def edit_paper(): """This is a temporary page, so that we can add papers to a series of topics. In reality we need a more sophisticated method for adding or editing papers, and for importing from ArXiV. If args(0) is specified, it is the id of the paper to edit. If the variable 'topic' is specified, it is taken to be the topic id of a paper to which the paper belongs by default. Note that I am assuming here that anyone can edit a paper. """ # TODO: verify permissions. paper = db(db.paper.paper_id == request.args(0)).select( orderby=~db.paper.start_date).first() is_create = paper is None # If there is no topic, # Creates the form. default_topic_id = paper.primary_topic if paper else request.vars.topic form = SQLFORM.factory( Field('title', default=None if is_create else paper.title), Field('authors', 'list:string', default=None if is_create else paper.authors), Field('abstract', 'text', default=None if is_create else text_store_read(paper.abstract)), Field('file', default=None if is_create else paper.file), Field('primary_topic', 'reference topic', default=default_topic_id, requires=IS_IN_DB(db, 'topic.id', '%(name)s')), Field('secondary_topics'), ) def validate_paper_edit_form(form): # Checks the names of the secondary topics. primary_topic_id = form.vars.primary_topic secondary_topic_ids = [] if form.vars.secondary_topics is not None: secondary_topics_raw_names = form.vars.secondary_topics.split(';') for n in secondary_topics_raw_names: nn = n.strip() if nn != '': t = db(db.topic.name == nn).select().first() if t is None: form.errors.secondary_topics = T( 'The topic %r does not exist') % nn return form else: secondary_topic_ids.append(t.id) form.vars.secondary_topic_ids = list( set(secondary_topic_ids) - {primary_topic_id}) return form if form.process(onvalidation=validate_paper_edit_form).accepted: # We have to carry out the requests in the form. now = datetime.utcnow() if is_create: # We have to come up with a new random id. random_paper_id = review_utils.get_random_id() abstract_id = text_store_write(form.vars.abstract) # We write the paper. db.paper.insert(paper_id=random_paper_id, title=form.vars.title, authors=form.vars.authors, abstract=abstract_id, file=form.vars.file, primary_topic=form.vars.primary_topic, start_date=datetime.utcnow(), end_date=None) else: random_paper_id = paper.paper_id # Checks if anything has changed about the paper, as opposed to the topics. is_abstract_different = False abstract_id = paper.abstract if form.vars.abstract != text_store_read(paper.abstract): abstract_id = text_store_write(form.vars.abstract) is_abstract_different = True if ((form.vars.title != paper.title) or (form.vars.authors != paper.authors) or is_abstract_different): logger.info( "The paper itself changed; moving to a new paper instance." ) # Closes the validity period of the previous instance of this paper. paper.update_record(end_date=now) # We write the paper. db.paper.insert(paper_id=random_paper_id, title=form.vars.title, authors=form.vars.authors, abstract=abstract_id, file=form.vars.file, primary_topic=form.vars.primary_topic, start_date=datetime.utcnow(), end_date=None) else: logger.info("The paper itself is unchanged.") # Then, we take care of the topics. new_topics = set({form.vars.primary_topic}) | set( form.vars.secondary_topic_ids) logger.info("new topics: %r" % new_topics) # First, we close the topics to which the paper no longer belongs. previous_occurrences = db( (db.paper_in_topic.paper_id == random_paper_id) & (db.paper_in_topic.end_date == None)).select() for t in previous_occurrences: if t.topic not in new_topics: logger.info("Removing paper from topic %r" % t.topic) t.update_record(end_date=now) # Second, for each new topic, searches. If the paper has never been in that topic before, # it adds the paper to that topic. Otherwise, it re-opens the previous tenure of the paper # in that topic. for tid in new_topics: last_occurrence = db( (db.paper_in_topic.paper_id == random_paper_id) & (db.paper_in_topic.topic == tid)).select( orderby=~db.paper_in_topic.start_date).first() if last_occurrence is None: # We need to insert. logger.info("Adding paper to new topic %r" % tid) db.paper_in_topic.insert( paper_id=random_paper_id, topic=tid, is_primary=tid == form.vars.primary_topic, start_date=now) elif last_occurrence.end_date is not None: # There was a previous occurrence, but it has now been closed. # We reopen it. logger.info("Reopening paper presence in topic %r" % tid) db.paper_in_topic.insert( paper_id=random_paper_id, topic=tid, is_primary=tid == form.vars.primary_topic, start_date=now, num_reviews=last_occurrence.num_reviews, score=last_occurrence.score, ) # The paper has been updated. session.flash = T('The paper has been updated.') # If we were looking at a specific topic, goes back to it. if request.vars.topic is not None: redirect(URL('default', 'topic_index', args=[request.vars.topic])) else: redirect(URL('default', 'index')) return dict(form=form, is_create=is_create)
def do_review(): """Shows to a user their review of a paper, allowing them to edit it or to enter it for the first time. The arguments are: - paper_id : the paper. - topic.id : the id of the topic, or the string "primary". - v / e: view, or edit. If there is a current review, then lets the user edit that instead, keeping track of the old review. """ (paper_id, topic_id) = get_paper_and_topic_ids() is_view = request.args(2) == 'v' paper = db((db.paper.paper_id == request.args(0)) & (db.paper.end_date == None)).select().first() topic = db.topic(topic_id) #logger.info("do_review paper.id %r topic.id %r is_view %r" % (paper,topic,is_view)) if paper is None or topic is None: component_fail(T('No such paper or topic.')) # Checks whether the paper is currently in the topic. paper_in_topic = db((db.paper_in_topic.paper_id == paper.paper_id) & (db.paper_in_topic.topic == topic.id) & (db.paper_in_topic.end_date == None)).select().first() if paper_in_topic is None: component_fail(T('The paper is not in the selected topic')) # Verify permissions. if not is_view and not can_review(topic.id): component_fail(T('You do not have the permission to perform reviews in this topic')) # Fishes out the current review, if any. current_review = db((db.review.user_email == get_user_email()) & (db.review.paper_id == paper.paper_id) & (db.review.topic == topic.id) & (db.review.end_date == None)).select().first() # Sets some defaults. logger.info("My user email: %r" % get_user_email()) db.review.paper.writable = False db.review.paper_id.readable = False db.review.user_email.default = get_user_email() db.review.paper_id.default = paper.paper_id db.review.paper.default = paper.id db.review.topic.default = topic.id db.review.start_date.label = T('Review date') db.review.end_date.readable = False db.review.useful_count.readable = is_view db.review.old_score.default = paper_in_topic.score # Creates the form for editing. form = SQLFORM(db.review, record=current_review, readonly=is_view) form.vars.user_email = get_user_email() form.vars.review_content = None if current_review is None else text_store_read(current_review.review_content) if form.validate(): # We must write the review as a new review. # First, we close the old review if any. now = datetime.utcnow() if current_review is not None: current_review.update_record(end_date=now) # Builds the correct review id. review_id = current_review.review_id if current_review is not None else None if review_id is None: review_id = review_utils.get_random_id() # Then, writes the current review. db.review.insert(user_email=get_user_email(), paper_id=paper.paper_id, review_id=review_id, paper=paper.id, topic=topic.id, start_date=now, end_date=None, review_content=str(text_store_write(form.vars.content)), old_score=paper_in_topic.score, grade=form.vars.grade, ) add_reviewer_to_topic(get_user_email(), topic.id) session.flash = T('Your review has been accepted.') redirect(URL('components', 'do_review', args=[paper.paper_id, topic_id, 'v'])) button_list = [] button_list.append(A(icon_reviews, T('All reviews'), cid=request.cid, _class='btn btn-success', _href=URL('components', 'paper_reviews', args=[paper.paper_id, topic_id]))) if is_view and can_review(topic.id): button_list.append(A(icon_edit, T('Edit review'), cid=request.cid, _class='btn btn-warning', _href=URL('components', 'do_review', args=[paper.paper_id, topic_id, 'e']))) # else: # button_list.append(A(icon_your_review, T('Your review'), cid=request.cid, # _class='btn btn-success', # _href=URL('components', 'do_review', args=[paper.paper_id, topic_id, 'v']))) return dict(button_list=button_list, form=form)
def edit_paper(): """This is a temporary page, so that we can add papers to a series of topics. In reality we need a more sophisticated method for adding or editing papers, and for importing from ArXiV. args(0) is the topic; one submits papers to specific topics for rating. If args(1) is specified, it is the id of the paper to edit. If the variable 'topic' is specified, it is taken to be the topic id of a paper to which the paper belongs by default. Note that I am assuming here that anyone can edit a paper. """ topic_id = int(request.args(0)) paper_id = request.args(1) user_id = auth.user paper = db(db.paper.paper_id == paper_id).select(orderby=~db.paper.start_date).first() is_create = paper is None # Checks permissions. if is_create: # Can the user submit? if not can_add_paper(topic_id): session.message = T('You cannot submit papers to this topic.') redirect(URL('default', 'view_topic', args=[topic_id])) else: # Can the user edit the paper? # ---qui--- form = SQLFORM.factory( Field('title', default=None if is_create else paper.title), Field('authors', 'list:string', default=None if is_create else paper.authors), Field('abstract', 'text', default=None if is_create else text_store_read(paper.abstract)), Field('paper_url', default=None if is_create else paper.paper_url, requires=IS_EMPTY_OR(IS_URL())), Field('primary_topic', 'reference topic', default=default_topic_id, requires=IS_IN_DB(db(), 'topic.id', '%(name)s')), Field('secondary_topics'), ) def validate_paper_edit_form(form): # Checks the names of the secondary topics. primary_topic_id = form.vars.primary_topic secondary_topic_ids = [] if form.vars.secondary_topics is not None: secondary_topics_raw_names = form.vars.secondary_topics.split(';') for n in secondary_topics_raw_names: nn = n.strip() if nn != '': t = db(db.topic.name == nn).select().first() if t is None: form.errors.secondary_topics = T('The topic %r does not exist') % nn return form if not can_add_paper(t.id): form.errors.secondary_topics = T('You do not have the permission to include topic %r') % nn return form secondary_topic_ids.append(t.id) form.vars.secondary_topic_ids = list(set(secondary_topic_ids) - {primary_topic_id}) return form if form.process(onvalidation=validate_paper_edit_form).accepted: # We have to carry out the requests in the form. now = datetime.utcnow() if is_create: # We have to come up with a new random id. random_paper_id = review_utils.get_random_id() abstract_id = text_store_write(form.vars.abstract) # We write the paper. db_paper_id = db.paper.insert(paper_id=random_paper_id, title=form.vars.title, authors=form.vars.authors, abstract=abstract_id, paper_url=form.vars.file, primary_topic=form.vars.primary_topic, start_date=datetime.utcnow(), end_date=None ) # Adds a permission line. db.paper_role.insert(paper_id=random_paper_id, can_edit=True, can_view=True, ) session.flash = T('The paper has been added') else: random_paper_id = paper.paper_id abstract_id = paper.abstract if form.vars.abstract != text_store_read(paper.abstract): abstract_id = text_store_write(form.vars.abstract) session.flash = T('The paper has been updated') # Closes the validity period of the previous instance of this paper. paper.update_record(end_date=now) # We write the paper. db_paper_id = db.paper.insert(paper_id=random_paper_id, title=form.vars.title, authors=form.vars.authors, abstract=abstract_id, file=form.vars.file, primary_topic=form.vars.primary_topic, start_date=datetime.utcnow(), end_date=None ) # Then, we take care of the topics. new_topics = set({form.vars.primary_topic}) | set(form.vars.secondary_topic_ids) logger.info("new topics: %r" % new_topics) for top in new_topics: db.paper_in_topic.insert( paper = db_paper_id, topic = top, is_primary = (top == form.vars.primary_topic), ) if request.vars.topic is not None: redirect(URL('default', 'topic_index', args=[request.vars.topic])) else: redirect(URL('default', 'index')) return dict(form=form, is_create=is_create) def view_paper(): """Views a paper, including the details of the paper, and all the reviews. Work in progress. Arguments: - paper_id """ return dict( signed_url=URL('api', 'paper_do', user_signature=True), unsigned_url=URL('api') ) def user(): """ exposes: http://..../[app]/default/user/login http://..../[app]/default/user/logout http://..../[app]/default/user/register http://..../[app]/default/user/profile http://..../[app]/default/user/retrieve_password http://..../[app]/default/user/change_password http://..../[app]/default/user/manage_users (requires membership in http://..../[app]/default/user/bulk_register use @auth.requires_login() @auth.requires_membership('group name') @auth.requires_permission('read','table name',record_id) to decorate functions that need access control """ return dict(form=auth()) @cache.action() def download(): """ allows downloading of uploaded files http://..../[app]/default/download/[filename] """ return response.download(request, db) def call(): """ exposes services. for example: http://..../[app]/default/call/jsonrpc decorate with @services.jsonrpc the functions to expose supports xml, json, xmlrpc, jsonrpc, amfrpc, rss, csv """ return service()
def do_review(): """Shows to a user their review of a paper, allowing them to edit it or to enter it for the first time. The arguments are: - paper_id : the paper. - topic.id : the id of the topic, or the string "primary". - v / e: view, or edit. If there is a current review, then lets the user edit that instead, keeping track of the old review. """ (paper_id, topic_id) = get_paper_and_topic_ids() is_view = request.args(2) == 'v' paper = db((db.paper.paper_id == request.args(0)) & (db.paper.end_date == None)).select().first() topic = db.topic(topic_id) #logger.info("do_review paper.id %r topic.id %r is_view %r" % (paper,topic,is_view)) if paper is None or topic is None: component_fail(T('No such paper or topic.')) # Checks whether the paper is currently in the topic. paper_in_topic = db((db.paper_in_topic.paper_id == paper.paper_id) & (db.paper_in_topic.topic == topic.id) & (db.paper_in_topic.end_date == None)).select().first() if paper_in_topic is None: component_fail(T('The paper is not in the selected topic')) # Verify permissions. if not is_view and not can_review(topic.id): component_fail( T('You do not have the permission to perform reviews in this topic' )) # Fishes out the current review, if any. current_review = db((db.review.user_email == get_user_email()) & (db.review.paper_id == paper.paper_id) & (db.review.topic == topic.id) & (db.review.end_date == None)).select().first() # Sets some defaults. logger.info("My user email: %r" % get_user_email()) db.review.paper.writable = False db.review.paper_id.readable = False db.review.user_email.default = get_user_email() db.review.paper_id.default = paper.paper_id db.review.paper.default = paper.id db.review.topic.default = topic.id db.review.start_date.label = T('Review date') db.review.end_date.readable = False db.review.useful_count.readable = is_view db.review.old_score.default = paper_in_topic.score # Creates the form for editing. form = SQLFORM(db.review, record=current_review, readonly=is_view) form.vars.user_email = get_user_email() form.vars.review_content = None if current_review is None else text_store_read( current_review.review_content) if form.validate(): # We must write the review as a new review. # First, we close the old review if any. now = datetime.utcnow() if current_review is not None: current_review.update_record(end_date=now) # Builds the correct review id. review_id = current_review.review_id if current_review is not None else None if review_id is None: review_id = review_utils.get_random_id() # Then, writes the current review. db.review.insert( user_email=get_user_email(), paper_id=paper.paper_id, review_id=review_id, paper=paper.id, topic=topic.id, start_date=now, end_date=None, review_content=str(text_store_write(form.vars.content)), old_score=paper_in_topic.score, grade=form.vars.grade, ) add_reviewer_to_topic(get_user_email(), topic.id) session.flash = T('Your review has been accepted.') redirect( URL('components', 'do_review', args=[paper.paper_id, topic_id, 'v'])) button_list = [] button_list.append( A(icon_reviews, T('All reviews'), cid=request.cid, _class='btn btn-success', _href=URL('components', 'paper_reviews', args=[paper.paper_id, topic_id]))) if is_view and can_review(topic.id): button_list.append( A(icon_edit, T('Edit review'), cid=request.cid, _class='btn btn-warning', _href=URL('components', 'do_review', args=[paper.paper_id, topic_id, 'e']))) # else: # button_list.append(A(icon_your_review, T('Your review'), cid=request.cid, # _class='btn btn-success', # _href=URL('components', 'do_review', args=[paper.paper_id, topic_id, 'v']))) return dict(button_list=button_list, form=form)
def do_review(): """Shows to a user their review of a paper, allowing them to edit it or to enter it for the first time. The arguments are: - paper_id : the paper. - v / e: view, or edit. - topic.id : the id of the topic. If there is a current review, then lets the user edit that instead, keeping track of the old review. """ # TODO: verify permissions. paper = db((db.paper.paper_id == request.args(0)) & (db.paper.end_date == None)).select().first() topic = db.topic(request.args(2)) is_view = request.args(1) == 'v' if topic is None: topic = db.topic(paper.primary_topic) if paper is None or topic is None: session.flash = T('No such paper') redirect(URL('default', 'index')) # Checks whether the paper is currently in the topic. paper_in_topic = db((db.paper_in_topic.paper_id == paper.paper_id) & (db.paper_in_topic.topic == topic.id) & (db.paper_in_topic.end_date == None)).select().first() if paper_in_topic is None: session.flash = T('The paper is not in the selected topic') redirect(URL('default', 'index')) # Fishes out the current review, if any. current_review = db((db.review.author == auth.user_id) & (db.review.paper_id == paper.paper_id) & (db.review.topic == topic.id) & (db.review.end_date == None)).select().first() # Sets some defaults. logger.info("My user id: %r" % auth.user_id) db.review.paper.writable = False db.review.paper_id.readable = False db.review.author.default = auth.user_id db.review.paper_id.default = paper.paper_id db.review.paper.default = paper.id db.review.topic.default = topic.id db.review.start_date.label = T('Review date') db.review.end_date.readable = False db.review.useful_count.readable = is_view db.review.old_score.default = paper_in_topic.score # Creates the form for editing. form = SQLFORM(db.review, record=current_review, readonly=is_view) form.vars.author = auth.user_id form.vars.content = None if current_review is None else text_store_read(current_review.content) if form.validate(): # We must write the review as a new review. # First, we close the old review if any. now = datetime.utcnow() if current_review is not None: current_review.update_record(end_date=now) # Builds the correct review id. review_id = current_review.review_id if current_review is not None else None if review_id is None: review_id = review_utils.get_random_id() # Then, writes the current review. db.review.insert(author=auth.user_id, paper_id=paper.paper_id, review_id=review_id, paper=paper.id, topic=topic.id, start_date=now, end_date=None, content=str(text_store_write(form.vars.content)), old_score=paper_in_topic.score, grade=form.vars.grade, ) # If the reviewer does not exist, adds it. reviewer = db((db.reviewer.user == auth.user_id) & (db.reviewer.topic == topic.id)).select().first() if reviewer is None: # Previously not existing. db.reviewer.insert(user=auth.user_id, topic=topic.id, is_reviewer=True) elif not reviewer.is_reviewer: reviewer.update_record(is_reviewer=True) session.flash = T('Your review has been accepted.') redirect(URL('components', 'do_review', args=[paper.paper_id, 'v'])) button_list = [] button_list.append(A(icon_reviews, T('All reviews'), cid=request.cid, _class='btn btn-success', _href=URL('components', 'paper_reviews', args=[paper.paper_id]))) if is_view: button_list.append(A(icon_edit, T('Edit review'), cid=request.cid, _class='btn btn-warning', _href=URL('components', 'do_review', args=[paper.paper_id, 'e']))) else: button_list.append(A(icon_your_review, T('Your review'), cid=request.cid, _class='btn btn-success', _href=URL('components', 'do_review', args=[paper.paper_id, 'v']))) return dict(button_list=button_list, form=form)