def can_delete_paper(paperid): ## currently anonymous cannot delete any comments userid = get_user_id() if (userid == ANONYMOUS): return False else: return is_super_admin(userid) or is_author_of_paper(userid, paperid)
def add_comment(paperid): con = get_db() error = None with con: con.execute('insert into comments \ (comment,userid,paperid) \ values (?,?,?)', [ # here we do not escape, because we will # do it in jinja request.form['comment'], get_user_id(), paperid ]) con.execute('update papers set lastcommentat=datetime() \ where paperid = ?', [paperid]) if user_authenticated(): flash('You successfully commented the paper') else: flash('You anonymously commented the paper') last_c_id=query_db("SELECT last_insert_rowid() as lid", one=True)['lid'] # notify user about new comment comment_was_added(paperid, last_c_id) return redirect(url_for('onepaper',paperid=paperid, title = None, error=error) + "#comment-" + str(last_c_id))
def onepaper(paperid, title = None): paper = get_paper_w_uploader(paperid) liked = query_db( "select count(*) as c \ from likes \ where paperid=? and userid=?", [paperid,get_user_id()], one=True)['c'] if paper['edited_at'] is not None: paper['edituser'] = query_db( "select username \ from users \ where userid = ?", [paper['edited_by']], one=True)['username'] authors=get_authors(paperid) domains=get_domains(paperid) keywords=get_keywords(paperid) comments=get_comments(paperid) return render_template('paper/onepaper.html', entry=paper, comments=comments, authors=authors, domains=domains, keywords=keywords, liked=liked, liked_by=liked_by(paperid))
def like_paper(paperid,title): if not user_authenticated(): return "<h1>Forbidden (anonymous cannot like)</h1>", 403 con = get_db() with con: con.execute('insert into likes (paperid,userid) values (?,?)', [paperid, get_user_id()]) return str(likes(paperid))
def unlike_paper(paperid,title): if not user_authenticated(): return "<h1>Forbidden (anonymous cannot unlike)</h1>", 403 con = get_db() with con: con.execute('delete from likes where \ paperid = ? and userid=?', [paperid, get_user_id()]) return str(likes(paperid))
def can_meta_edit_paper(paperid): ## currently any registered user can edit meta information of any paper. ## should we make a moderation system or ## the system for local git-like views of PG? Smth like that: ## 1) User changes meta information. It affects only her own view. ## 2) User submits changes to global view. ## 3) Other members approve it. userid = get_user_id() if (userid == ANONYMOUS): return False return True
def users_to_notify(paperid): who_like = who_likes(paperid) who_comment = commentators(paperid) users = who_like + who_comment ## We notify union of all these users ## but not the current_user (who make the action) ## and ANONYMOUS current_user_id = get_user_id() users = list( {v['userid']:v for v in users if v['userid'] != current_user_id and v['userid'] != ANONYMOUS}.values()) return users
def edit_comment(commentid): if not can_edit_comment(commentid): return "<h1>It's forbidden, my dear</h1>", 403 error = None oldcomment = get_comment(commentid) if request.method == 'GET': return render_template('comment/editcomment.html', error=error, comment=oldcomment, ) if request.method == 'POST': con = get_db() # soft delete old comment delete_comment(oldcomment['commentid']) # create a new comment with same creation date # but add edited_by and edited_at info with con: con.execute('insert into comments \ (comment, userid, paperid, createtime, edited_at, edited_by) \ values (?, ?, ?, ?, datetime(), ?)', [ request.form['comment'], oldcomment['userid'], oldcomment['paperid'], oldcomment['createtime'], get_user_id(), ]) # TODO: should we notify someone about comment edition ? if user_authenticated(): flash('You successfully updated the comment') # TODO: allows anonymous to update comments last_c_id=query_db("SELECT last_insert_rowid() as lid", one=True)['lid'] return redirect(url_for('onepaper', paperid=oldcomment['paperid'], error=error) + "#comment-" + str(last_c_id))
def users_to_notify_about_new_paper(paperid): users = query_db( "select distinct users.* \ from users as users, \ likes as likes, \ papers as papers_by_uploader, \ papers as newpapers, \ users as uploaders \ where \ likes.userid = users.userid and \ likes.paperid = papers_by_uploader.paperid and \ papers_by_uploader.userid = uploaders.userid and \ uploaders.userid = newpapers.userid and \ newpapers.paperid = ?", [paperid]) ## We notify union of all these users ## but not the current_user (who make the action) ## and ANONYMOUS current_user_id = get_user_id() users = list({ v['userid']: v for v in users if v['userid'] != current_user_id and v['userid'] != ANONYMOUS }.values()) return users
def can_delete_tag(tagname): userid = get_user_id() if (userid == ANONYMOUS): return False else: return is_super_admin(userid)
def can_delete_author(fullname): userid = get_user_id() if (userid == ANONYMOUS): return False else: return is_super_admin(userid)
def previews(seq): """ for a sequence of papers, i.e. 'select * from papers', we extract additional info about comments, authors, etc. In order to render the list of previews <paper|comments>. We use this at main page and also at sites of users """ liked_by_l = {} liked = {} commentsHead = {} commentsTail = {} for paper in seq: liked_by_l[paper['paperid']] = liked_by(paper['paperid']) liked[paper['paperid']] = query_db( "select * \ from likes \ where paperid=? and userid=?", [paper['paperid'], get_user_id()], one=True) commentsHead[paper['paperid']] = query_db( " \ select \ c.commentid, c.comment, c.userid, \ c.createtime, \ u.username \ from comments as c, users as u \ where \ c.userid = u.userid and \ c.deleted_at is null and \ c.paperid = ? \ order by c.createtime \ limit 2 \ ", [paper['paperid']]) # construct a list of comments ids ids_in_head = [ str(c['commentid']) for c in commentsHead[paper['paperid']] ] good_injection = '(' + ','.join(ids_in_head) + ')' # donot cosider a comments with id from the list head # we cannot bind into 'in (?)', therefore we inject! commentsTail[paper['paperid']] = query_db( "select * from \ ( \ select \ c.commentid, c.comment, c.userid, \ c.createtime, \ u.username \ from comments as c, users as u \ where \ c.deleted_at is null and \ c.userid = u.userid and \ c.commentid not in " + good_injection + " and \ c.paperid = ? \ order by c.createtime desc \ limit 2) \ order by createtime \ ", [paper['paperid']]) return (commentsTail, commentsHead, liked_by_l, liked)
def edit_paper(paperid): if not can_edit_paper(paperid): return "<h1>It's forbidden, my dear</h1>", 403 error = None paper = query_db("select * \ from papers \ where paperid = ?", [paperid], one=True) if request.method == 'GET': request.form.title = paper['title'] request.form.authors = ", ".join([x['fullname'] for x in get_authors(paperid)]) request.form.domains = ", ".join([x['domainname'] for x in get_domains(paperid)]) request.form.keywords= ", ".join([x['keyword'] for x in get_keywords(paperid)]) if not is_internal_pdf (paper['getlink']): request.form.url = paper['getlink'] if request.method == 'POST': histore_paper_info(paper) paper_file = request.files['pdf'] if paper_file and not allowed_file(paper_file.filename): error = 'Please choose a pdf file' elif request.form['title'] == "": error = 'Please add a title' elif request.form['domains'] == "": error = 'Please specify at least one domain' elif request.form['authors'] == "": error = 'Please add some authors' elif request.form['keywords'] == "": error = 'Please add some keywords' else: con = get_db() with con: con.execute('update papers set title = ?, edited_by = ?, \ edited_at = datetime() \ where paperid = ?', [request.form['title'], get_user_id(), paperid]) authors_ids = map(get_insert_author, parse_list(request.form['authors'])) con.execute('delete from papers_authors where paperid = ?', [paperid]) for authorid in authors_ids: con.execute('insert into papers_authors \ (paperid, authorid) \ values(?,?)',[paperid, authorid]) domains_ids = map(get_insert_domain, parse_list(request.form['domains'])) con.execute('delete from papers_domains where paperid = ?', [paperid]) for domainid in domains_ids: con.execute('insert into papers_domains \ (paperid, domainid) \ values(?,?)',[paperid, domainid]) keywords_ids = map(get_insert_keyword, parse_list(request.form['keywords'])) con.execute('delete from papers_keywords where paperid = ?', [paperid]) for keywordid in keywords_ids: con.execute('insert into papers_keywords \ (paperid, keywordid) \ values(?,?)',[paperid, keywordid]) if paper_file: filename_pdf = str(paperid) + "-" + \ secure_filename(paper_file.filename) ppdf = os.path.join(app.config['UPLOAD_FOLDER'],filename_pdf) paper_file.save(ppdf) ## this is just a hack. ## In order to generate first page filename_png = str(paperid) + ".png" ppng = os.path.join(app.config['PREVIEW_FOLDER'],filename_png) os.system('papersite/gen.sh ' + ppdf + ' ' + ppng) # end of hack ## Sometimes authors provide a url to their paper ## in this case we don't store a full paper, we use the url instead if request.form['url'] != "": if paper_file: # a file was just uploaded, we already took the first page. It is a fair use. # We delete the file os.remove(ppdf) else: # The following magick will happens... # we test if a link is to un existing papers, link = paper['getlink'] if (is_internal_pdf(link)): filename_pdf = link.replace('/static/memory/pdfs/', '') ppdf = os.path.join(app.config['UPLOAD_FOLDER'],filename_pdf) os.remove(ppdf) # here we will delete file that was already uploaded some time ago # but now was remplaced by un URL. con.execute("update papers set getlink = ? \ where paperid=?", [request.form['url'], paperid]) elif paper_file: con.execute("update papers set getlink = ? \ where paperid=?", ['/static/memory/pdfs/'+filename_pdf, paperid]) ## TODO: notify some users by email about changes flash('You successfully modified the paper') return redirect(url_for('onepaper', paperid=paperid, title=request.form['title'])) return render_template('paper/edit.html', error=error, paperid=paperid, domains=query_db ("select * from domains"), keywords=query_db ("select * from keywords"), authors=query_db ("select * from authors"))
def edit_paper_meta_information(paperid): ### edit Title, authors, tags and domains lists if not can_meta_edit_paper(paperid): return "<h1>It's forbidden fro you, my sweetie.</h1>", 403 error = None paper = query_db("select * \ from papers \ where paperid = ?", [paperid], one=True) if request.method == 'GET': request.form.title = paper['title'] request.form.authors = ", ".join([x['fullname'] for x in get_authors(paperid)]) request.form.domains = ", ".join([x['domainname'] for x in get_domains(paperid)]) request.form.keywords= ", ".join([x['keyword'] for x in get_keywords(paperid)]) if request.method == 'POST': histore_paper_info(paper) if request.form['title'] == "": error = 'Please add a title' elif request.form['domains'] == "": error = 'Please specify at least one domain' elif request.form['authors'] == "": error = 'Please add some authors' elif request.form['keywords'] == "": error = 'Please add some keywords' else: con = get_db() with con: con.execute('update papers set title = ?, edited_by = ?, \ edited_at = datetime() \ where paperid = ?', [request.form['title'], get_user_id(), paperid]) authors_ids = map(get_insert_author, parse_list(request.form['authors'])) con.execute('delete from papers_authors where paperid = ?', [paperid]) for authorid in authors_ids: con.execute('insert into papers_authors \ (paperid, authorid) \ values(?,?)',[paperid, authorid]) domains_ids = map(get_insert_domain, parse_list(request.form['domains'])) con.execute('delete from papers_domains where paperid = ?', [paperid]) for domainid in domains_ids: con.execute('insert into papers_domains \ (paperid, domainid) \ values(?,?)',[paperid, domainid]) keywords_ids = map(get_insert_keyword, parse_list(request.form['keywords'])) con.execute('delete from papers_keywords where paperid = ?', [paperid]) for keywordid in keywords_ids: con.execute('insert into papers_keywords \ (paperid, keywordid) \ values(?,?)',[paperid, keywordid]) ## TODO: notify some users by email about changes flash('You successfully modified the paper') return redirect(url_for('onepaper', paperid=paperid, title=request.form['title'])) return render_template('paper/meta-edit.html', error=error, paperid=paperid, domains=query_db ("select * from domains"), keywords=query_db ("select * from keywords"), authors=query_db ("select * from authors"))
def add_paper(): error = None if request.method == 'POST': paper_file = request.files['pdf'] if not paper_file or not allowed_file(paper_file.filename): error = 'Please choose a pdf file' elif request.form['title'] == "": error = 'Please add a title' elif request.form['domains'] == "": error = 'Please specify at least one domain' elif request.form['authors'] == "": error = 'Please add some authors' elif request.form['keywords'] == "": error = 'Please add some keywords' else: con = get_db() with con: con.execute('insert into papers(title,userid) \ values (?,?)', [request.form['title'], get_user_id()]) paperid = con.execute("SELECT last_insert_rowid() as lid" ).fetchone()['lid'] authors_ids = map(get_insert_author, parse_list(request.form['authors'])) for authorid in authors_ids: con.execute('insert into papers_authors \ (paperid, authorid) \ values(?,?)',[paperid, authorid]) domains_ids = map(get_insert_domain, parse_list(request.form['domains'])) for domainid in domains_ids: con.execute('insert into papers_domains \ (paperid, domainid) \ values(?,?)',[paperid, domainid]) keywords_ids = map(get_insert_keyword, parse_list(request.form['keywords'])) for keywordid in keywords_ids: con.execute('insert into papers_keywords \ (paperid, keywordid) \ values(?,?)',[paperid, keywordid]) filename_pdf = str(paperid) + "-" + \ secure_filename(paper_file.filename) ppdf = os.path.join(app.config['UPLOAD_FOLDER'],filename_pdf) paper_file.save(ppdf) ## this is just a hack. ## In order to generate first page filename_png = str(paperid) + ".png" ppng = os.path.join(app.config['PREVIEW_FOLDER'],filename_png) os.system('papersite/gen.sh ' + ppdf + ' ' + ppng) # end of hack ## Sometimes authors provide a url to their paper ## in this case we don't store a full paper, we use the url instead if request.form['url'] != "": os.remove(ppdf) con.execute("update papers set getlink = ? \ where paperid=?", [request.form['url'], paperid]) else: con.execute("update papers set getlink = ? \ where paperid=?", ['/static/memory/pdfs/'+filename_pdf, paperid]) ## notify some users by email about this paper new_paper_was_added(paperid) flash('You successfully upload the paper') return redirect(url_for('onepaper', paperid=paperid, title=request.form['title'])) return render_template('paper/add.html', error=error, domains=query_db ("select * from domains"), keywords=query_db ("select * from keywords"), authors=query_db ("select * from authors"))