From 43c03b48815e7ddae39b5521212a8f2424a0403f Mon Sep 17 00:00:00 2001 From: Mark MacGillivray Date: Sat, 17 Mar 2012 12:30:38 +0000 Subject: [PATCH] more wiring in of functionality to facetview and jtedit. still a wee bit to go though. --- bibserver/dao.py | 6 +- bibserver/search.py | 42 +++++++---- .../static/vendor/jtedit/jquery.jtedit.js | 40 +++++------ bibserver/templates/account/register.html | 6 +- bibserver/templates/account/users.html | 17 +++++ bibserver/templates/account/view.html | 43 +++++------ bibserver/templates/base.html | 2 +- bibserver/templates/home/index.html | 18 +++-- bibserver/templates/record.html | 7 +- bibserver/templates/search/index.html | 71 +++++++++++++++---- bibserver/view/account.py | 14 ++-- bibserver/web.py | 23 +++++- config.json | 4 +- 13 files changed, 202 insertions(+), 91 deletions(-) create mode 100644 bibserver/templates/account/users.html diff --git a/bibserver/dao.py b/bibserver/dao.py index ac5a35e2..eee76abb 100644 --- a/bibserver/dao.py +++ b/bibserver/dao.py @@ -94,7 +94,7 @@ def delete(self): conn = httplib.HTTPConnection(url) conn.request('DELETE', loc) resp = conn.getresponse() - return True + return '' @classmethod def get(cls, id_): @@ -234,9 +234,11 @@ def get_by_owner_coll(cls,owner,coll): def delete(self): url = str(config['ELASTIC_SEARCH_HOST']) loc = config['ELASTIC_SEARCH_DB'] + "/" + self.__type__ + "/" + self.id + print loc conn = httplib.HTTPConnection(url) conn.request('DELETE', loc) resp = conn.getresponse() + print resp.read() for record in self.records: record.delete() @@ -267,6 +269,6 @@ def delete(self): conn = httplib.HTTPConnection(url) conn.request('DELETE', loc) resp = conn.getresponse() - for coll in self.collections(): + for coll in self.collections: coll.delete() diff --git a/bibserver/search.py b/bibserver/search.py index 7d462bea..c07b704b 100644 --- a/bibserver/search.py +++ b/bibserver/search.py @@ -102,7 +102,9 @@ def record(self): abort(401) record.data = request.json record.save() - return '' + resp = make_response( json.dumps(record.data, sort_keys=True, indent=4) ) + resp.mimetype = "application/json" + return resp else: admin = True if auth.collection.update(self.current_user, collection) else False return render_template('record.html', @@ -131,9 +133,20 @@ def account(self): elif request.method == 'POST': if not auth.user.update(self.current_user,acc): abort(401) - acc.data = request.json + info = request.json + if info.get('id',False): + if info['id'] != self.parts[0]: + acc = bibserver.dao.Account.get(info['id']) + else: + info['api_key'] = acc.data['api_key'] + info['_created'] = acc.data['_created'] + acc.data = info + if 'password' in info and not info['password'].startswith('sha1'): + acc.set_password(info['password']) acc.save() - return '' + resp = make_response( json.dumps(acc.data, sort_keys=True, indent=4) ) + resp.mimetype = "application/json" + return resp else: if util.request_wants_json(): if not auth.user.update(self.current_user,acc): @@ -165,14 +178,9 @@ def collection(self): # look for collection metadata metadata = bibserver.dao.Collection.get_by_owner_coll(self.parts[0],self.parts[1]) - if metadata: - if 'display_settings' in metadata: - # set display settings from collection info - #search_options = metadata['display_settings'] - pass if request.method == 'DELETE': - if metadata: + if metadata != None: if not auth.collection.update(self.current_user, metadata): abort(401) else: metadata.delete() @@ -186,9 +194,8 @@ def collection(self): record = bibserver.dao.Record.get(rid['_id']) if record: record.delete() return '' - elif request.method == 'POST': - if metadata: + if metadata != None: metadata.data = request.json metadata.save() return '' @@ -204,8 +211,17 @@ def collection(self): resp.mimetype = "application/json" return resp else: - admin = True if auth.collection.update(self.current_user, metadata) else False - return render_template('search/index.html', current_user=self.current_user, search_options=json.dumps(self.search_options), collection=metadata, admin=admin) + admin = True if metadata != None and auth.collection.update(self.current_user, metadata) else False + if metadata and 'display_settings' in metadata: + search_options = metadata['display_settings'] + return render_template('search/index.html', + current_user=self.current_user, + search_options=json.dumps(self.search_options), + collection=metadata.data, + record = json.dumps(metadata.data), + admin=admin + ) + def prettify(self,record): result = '' diff --git a/bibserver/static/vendor/jtedit/jquery.jtedit.js b/bibserver/static/vendor/jtedit/jquery.jtedit.js index 25b7bfc5..2409a110 100644 --- a/bibserver/static/vendor/jtedit/jquery.jtedit.js +++ b/bibserver/static/vendor/jtedit/jquery.jtedit.js @@ -20,12 +20,13 @@ // specify the defaults var defaults = { - "editable":true, // whether or not to make the table editable + "editable":true, // whether or not to make the table editable "source":undefined, // a source from which to GET the JSON data object "target":undefined, // a target to which updated JSON should be POSTed "noedit":[], // a list of keys that should not be editable, when edit is enabled "hide":[], // a list of keys that should be hidden from view "data":undefined, // a JSON object to render for editing + "delete_redirect":"#", // where to redirect to after deleting "tags": [] } @@ -85,23 +86,26 @@ } if (editable) { - if (data[key].constructor.toString().indexOf("Array") != -1) { // if this key points to a list - } else { - } if ( data.constructor.toString().indexOf("Array") == -1 ) { var addname = key } else { var addname = '' } - s += '
' - s += ' add ' + addname + '' + s += '
' + } s += ' ' s += '
' } s += '
' // close the listitems @@ -175,15 +179,11 @@ // save the record var jtedit_saveit = function(event,datain) { event.preventDefault() - if ($(this).attr('href') == "saveas") { - // trigger a save as new record instead of save over - alert("do saveas") - } !datain ? datain = $.parseJSON(jQuery('#jtedit_json').val()) : false - !options.source ? options.source = prompt('Please provide URL to save this record to:') : false - if (options.source) { + !options.target ? options.target = prompt('Please provide URL to save this record to:') : false + if (options.target) { $.ajax({ - url: options.source + url: options.target , type: 'POST' , data: JSON.stringify(datain) , contentType: "application/json; charset=utf-8" @@ -191,7 +191,7 @@ , processData: false , success: function(data, statusText, xhr) { alert("Changes saved") - //window.location = '#' + window.location = window.location } , error: function(xhr, message, error) { alert("Error... " + error) @@ -205,18 +205,17 @@ // delete the record var jtedit_deleteit = function(event) { event.preventDefault() - if (!options.source) { + if (!options.target) { alert('There is no available source URL to delete from') } else { var confirmed = confirm("You are about to irrevocably delete this. Are you sure you want to do so?") if (confirmed) { $.ajax({ - url: options.source + url: options.target , type: 'DELETE' , success: function(data, statusText, xhr) { alert("Record deleted.") - //window.location = '../' - //$('body').html('') + window.location = options.delete_redirect } , error: function(xhr, message, error) { alert("Error... " + error) @@ -323,10 +322,9 @@ '
  • JSON
  • ' + '' + ' save ' + - ' save as ' + ' reload ' + ' delete' - $('#jtedit').append(actions + '
    ' + actions) + $('#jtedit').append(actions + '
    ') // + actions) var testdata = '{"abstract": "Folien zu einem Vortrag auf der ODOK 2010 in Leoben zu Linked Data und Open Data, mit einer knappen Darstellung der Linked-Open-Data-Aktivit\u110e\u1162ten im hbz-Verbund.", "added-at": "2011-02-17T13:00:20.000+0100", "author": ["pretend",["list","inalist"],{"id": "PohlAdrian","name": "Pohl, Adrian"},{"id": "PohlAdrian","name": "Pohl, Adrian"}], "journal":{"id":"somejournal","name":"somename"}, "biburl": "http://www.bibsonomy.org/bibtex/229ff5da471fd9d2706f2fd08c17b43dc/acka47", "cid": "Pohl_2010_LOD", "collection": "pohl", "copyright": "http://creativecommons.org/licenses/by/2.5/", "howpublished": "published via slideshare.net", "id": "531e7aa806574787897314010f29d4cf", "interhash": "558af6397a6aad826d47925a12eda76c", "intrahash": "29ff5da471fd9d2706f2fd08c17b43dc", "keyword": ["ODOK hbz libraries linkeddata myown opendata presentation"], "link": [{"url": "http://www.slideshare.net/acka47/pohl-20100923-odoklod"}], "month": "September", "owner": "test", "timestamp": "2011-02-17T13:00:20.000+0100", "title": "Freie Katalogdaten und Linked Data", "type": "misc", "url": "http://localhost:5000/test/pohl/Pohl_2010_LOD", "year": "2010" }' diff --git a/bibserver/templates/account/register.html b/bibserver/templates/account/register.html index 2d049652..5d811656 100644 --- a/bibserver/templates/account/register.html +++ b/bibserver/templates/account/register.html @@ -11,7 +11,7 @@ {{ render_field(form.email, placeholder="hello@mywebsite.org") }} {{ render_field(form.password, placeholder="********") }} {{ render_field(form.confirm, placeholder="********") }} - {{ render_field(form.about, placeholder="just a bit") }} + {{ render_field(form.description, placeholder="just a bit") }}
    @@ -19,10 +19,10 @@

    It is necessary to register to use this service. This is only so that - your collections can be allocated to you. There is no cost. You will never be emailed.

    + your collections can be allocated to you. There is no cost. You will only be emailed about service issues.

    After registering and signing in, you can view your user information - by clicking your username on the top right menu. This includes your API-KEY, + by clicking your username on the top right menu. This includes your api_key, which you will need if you want to send data via the API.

    Don't get your username wrong! We can't change it! (If you do, just diff --git a/bibserver/templates/account/users.html b/bibserver/templates/account/users.html new file mode 100644 index 00000000..5c05f975 --- /dev/null +++ b/bibserver/templates/account/users.html @@ -0,0 +1,17 @@ +{% extends "base.html" %} + +{% block content %} + + {% for user in users %} + +

    +

    {{ user.id }}

    +

    {{ user.description}}

    +
    + + {% endfor %} + +
    + +{% endblock %} + diff --git a/bibserver/templates/account/view.html b/bibserver/templates/account/view.html index 9ecfb24f..cc998996 100644 --- a/bibserver/templates/account/view.html +++ b/bibserver/templates/account/view.html @@ -12,27 +12,34 @@
    -
    +

    Hi {{ current_user.id }}

    +

    {{ current_user.description }}

    +


    Your api_key is:

    +

    {{current_user['api_key']}}

    +

    You need to append this to your API calls if you want to make changes.

    {% if superuser %} -

    You are the superuser! -
    You can view and edit anything! +

    You are the superuser! You can view and edit anything!
    Be careful...

    {% endif %}
    -
    -

    Your api_key is {{current_user['api_key']}} -
    You need to append this to your API calls if you want to make changes.

    +
    +

    Edit your details

    -
    +

    Your collections

    Choose one to view, and your admin options will be available at the bottom of the result display page.

    @@ -45,33 +52,29 @@

    Your collections

    {% endfor %} {% endif %}
    -
    -

    Edit your user profile

    +
    +

    All your records

    {% else %} -
    -
    -

    {{ account.id }}

    -
    +
    +

    {{ account.id }}

    {{ account.description }}

    +
    +

    You are not logged in as this user. Use the login page if you want to change this

    +
    -
    -

    You are not logged in as this user. Use the login page if you want to change this

    +
    {% endif %} -
    -

    {{ account.id }} - all records

    -
    - {% endblock %} diff --git a/bibserver/templates/base.html b/bibserver/templates/base.html index 74f9329e..181ee081 100644 --- a/bibserver/templates/base.html +++ b/bibserver/templates/base.html @@ -104,7 +104,7 @@

    About

    diff --git a/bibserver/templates/home/index.html b/bibserver/templates/home/index.html index 730ee9b9..90302db4 100644 --- a/bibserver/templates/home/index.html +++ b/bibserver/templates/home/index.html @@ -14,7 +14,8 @@ "packageName": item, "value": indata[item]['records'], "owner": indata[item]['owner'], - "slug": indata[item]['slug'] + "slug": indata[item]['slug'], + "description": indata[item]['description'] } data["children"].push(arr); } @@ -35,14 +36,14 @@ .attr("class", "node") .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; }); node.append("svg:title") - .text(function(d) { return d.data.className + ": " + format(d.value); }) + .text(function(d) { return d.data.className + " : " + format(d.value) + " records : " + d.data.description; }) node.append("svg:circle") .attr("r", function(d) { return d.r; }) .style("fill", function(d) { return fill(d.data.packageName); }) node.append("svg:text") .attr("text-anchor", "middle") .attr("dy", ".3em") - .text(function(d) { return d.data.className.substr(0,12) + ".. (" + d.data.value + ")"; }) + .text(function(d) { return d.data.className.substr(0,12); }) node.on('click',function(d) { clickbubble(d.data.owner,d.data.slug) }) @@ -61,10 +62,10 @@

    Welcome to BibSoup!

    -


    BibSoup makes it easy to find, manage and share bibliographies. (now in beta)

    @@ -72,13 +73,18 @@

    Welcome to BibSoup!

    We have {{records}} records -

    across {{colls}} collections

    +

    across {{colls}} collections +

    shared by {{users}} users

    Search all records

    Search shared collections and records, find material relevant to your interests, make new collections.

    Search everything »

    +
    +

    What's this all about

    +

    Check out our FAQ for more links and info.

    +
    diff --git a/bibserver/templates/record.html b/bibserver/templates/record.html index f3b4d85c..4f86902d 100644 --- a/bibserver/templates/record.html +++ b/bibserver/templates/record.html @@ -31,7 +31,12 @@ {% if admin %} diff --git a/bibserver/templates/search/index.html b/bibserver/templates/search/index.html index 8f26bff3..7c972874 100644 --- a/bibserver/templates/search/index.html +++ b/bibserver/templates/search/index.html @@ -5,6 +5,7 @@
    + {% if collection.id %} + + Download as BibJSON + {% endif %} + + {% if admin %} + + + + + +
    +
    +
    +
    + {% endif %} + {% if implicit %}

    {{ implicit }}

    {% endif %} {% if collection.id %} -

    {{collection.owner}} / {{ collection.label }} +

    {{collection['owner']}} / {{ collection['label'] }} {{ collection['description'] }}

    {% endif %}
    + {% if collection.id %} + {% endif %} {% endblock %} diff --git a/bibserver/view/account.py b/bibserver/view/account.py index db9e2c57..9bbff88f 100644 --- a/bibserver/view/account.py +++ b/bibserver/view/account.py @@ -32,7 +32,7 @@ def login(): flash('Welcome back', 'success') return redirect('/'+user.id) else: - flash('Incorrect email/password', 'error') + flash('Incorrect username/password', 'error') if request.method == 'POST' and not form.validate(): flash('Invalid form', 'error') return render_template('account/login.html', form=form, upload=config['allow_upload']) @@ -58,7 +58,7 @@ class RegisterForm(Form): validators.EqualTo('confirm', message='Passwords must match') ]) confirm = PasswordField('Repeat Password') - about = TextAreaField('Describe yourself') + description = TextAreaField('Describe yourself') @blueprint.route('/register', methods=['GET', 'POST']) def register(): @@ -66,8 +66,12 @@ def register(): form = RegisterForm(request.form, csrf_enabled=False) if request.method == 'POST' and form.validate(): api_key = str(uuid.uuid4()) - account = dao.Account(id=form.username.data, email=form.email.data, - api_key=api_key) + account = dao.Account( + id=form.username.data, + email=form.email.data, + description = form.description.data, + api_key=api_key + ) account.set_password(form.password.data) account.save() login_user(account, remember=True) @@ -75,5 +79,5 @@ def register(): return redirect('/'+account.id) if request.method == 'POST' and not form.validate(): flash('Please correct the errors', 'error') - return render_template('account/register.html', form=form, upload=config['allow_upload']) + return render_template('account/register.html', form=form) diff --git a/bibserver/web.py b/bibserver/web.py index f476ed46..f1fe404f 100644 --- a/bibserver/web.py +++ b/bibserver/web.py @@ -75,7 +75,7 @@ def content(): def home(): data = [] try: - colldata = bibserver.dao.Collection.query(sort={"_created":{"order":"desc"}}) + colldata = bibserver.dao.Collection.query(sort={"_created":{"order":"desc"}},size=20) if colldata['hits']['total'] != 0: for coll in colldata['hits']['hits']: colln = bibserver.dao.Collection.get(coll['_id']) @@ -84,15 +84,32 @@ def home(): 'name': colln['label'], 'records': len(colln), 'owner': colln['owner'], - 'slug': colln['collection'] + 'slug': colln['collection'], + 'description': colln['description'] }) except: pass colls = bibserver.dao.Collection.query()['hits']['total'] records = bibserver.dao.Record.query()['hits']['total'] - return render_template('home/index.html', colldata=json.dumps(data), colls=colls, records=records) + users = bibserver.dao.Account.query()['hits']['total'] + return render_template('home/index.html', colldata=json.dumps(data), colls=colls, records=records, users=users) +@app.route('/users') +@app.route('/users.json') +def users(): + if current_user.is_anonymous(): + abort(401) + users = bibserver.dao.Account.query(sort={'id':{'order':'asc'}},size=1000000) + if users['hits']['total'] != 0: + users = [{'id':i['_source']['id'],'description':i['_source']['description']} for i in users['hits']['hits']] + if util.request_wants_json(): + resp = make_response( json.dumps(users, sort_keys=True, indent=4) ) + resp.mimetype = "application/json" + return resp + else: + return render_template('account/users.html',users=users) + # handle or disable uploads class UploadView(MethodView): def get(self): diff --git a/config.json b/config.json index fe261ade..e6fee69e 100644 --- a/config.json +++ b/config.json @@ -70,7 +70,7 @@ ], [ { - "pre":"" + "post":"" } ], [