sourcing/sourcing/view.py
2017-02-15 14:59:18 +00:00

254 lines
7.8 KiB
Python

from flask import (Blueprint, render_template, request, redirect, flash,
url_for, abort, jsonify)
from flask_login import (login_user, current_user, logout_user,
login_required, LoginManager)
from .forms import (LoginForm, SignupForm, AccountSettingsForm,
UploadSourceDocForm, SourceDocForm, ItemForm)
from .model import User, SourceDoc, Item, XanaDoc, XanaLink
from .url import get_url
from .edl import fulfil_edl_with_sources
from .database import session
from .text import iter_lines
from werkzeug.debug.tbtools import get_current_traceback
from jinja2 import evalcontextfilter, Markup
from functools import wraps
import re
login_manager = LoginManager()
login_manager.login_view = '.login'
re_paragraph = re.compile(r'(?:\r\n|\r|\n){2,}')
bp = Blueprint('view', __name__)
def init_app(app):
login_manager.init_app(app)
app.register_blueprint(bp)
@app.template_filter()
@evalcontextfilter
def newline_html(eval_ctx, value):
return u'\n\n'.join(Markup(u'<p>') + p.replace('\n', Markup('<br>')) + Markup(u'</p>')
for p in re_paragraph.split(value))
@login_manager.user_loader
def load_user(user_id):
return User.query.get(user_id)
# where do we redirect after signup is complete
view_after_signup = '.home'
@bp.context_processor
def inject_user():
return dict(current_user=current_user)
def show_errors(f):
@wraps(f)
def wrapper(*args, **kwargs):
try:
return f(*args, **kwargs)
except Exception:
traceback = get_current_traceback(skip=1, show_hidden_frames=False,
ignore_system_exceptions=True)
return traceback.render_full().encode('utf-8', 'replace')
return wrapper
@bp.route('/')
def home():
titles = XanaLink.get_all_titles()
docs = Item.query.order_by(Item.created)
return render_template('home.html', docs=docs)
@bp.route('/source_doc_upload', methods=["POST"])
@show_errors
def source_doc_upload():
f = request.files['sourcedoc_file']
text = f.read()
doc = SourceDoc(text=text, user=current_user, filename=f.filename)
session.add(doc)
session.commit()
flash('new source document uploaded')
return redirect(doc.url)
@bp.route('/about')
def about():
return render_template('about.html')
@bp.route('/contact')
def contact():
return render_template('contact.html')
def redirect_to_home():
return redirect(url_for('.home'))
@bp.route('/login', methods=['GET', 'POST'])
def login():
form = LoginForm(next=request.args.get('next'))
if form.validate_on_submit():
login_user(form.user, remember=form.remember.data)
flash('Logged in successfully.')
return redirect(request.form.get('next') or url_for('.home'))
return render_template('login.html', form=form)
@bp.route('/logout')
def logout():
logout_user()
flash('You have been logged out.')
return redirect_to_home()
@bp.route('/signup', methods=['GET', 'POST'])
def signup():
form = SignupForm()
if not form.validate_on_submit():
return render_template('signup.html', form=form)
user = User(**form.data)
session.add(user)
session.commit()
flash('New account created.')
login_user(user)
return redirect(url_for(view_after_signup))
def redirect_to_doc(doc):
return redirect(url_for('.view_document', hashid=doc.hashid))
def get_source_doc(username, hashid):
doc = Item.get_by_hashid(hashid)
if doc and doc.user.username != username:
doc = None
return doc if doc else abort(404)
def get_item(username, hashid):
doc = Item.get_by_hashid(hashid)
if doc and doc.user.username != username:
doc = None
return doc if doc else abort(404)
def view_xanadoc(item):
return render_template('view/xanadoc.html',
item=item,
doc=fulfil_edl_with_sources(item.text))
@bp.route('/<username>/<hashid>/edl')
def view_edl(username, hashid):
item = get_item(username, hashid)
if item.type != 'xanadoc':
return abort(404)
return render_template('view.html', doc=item, iter_lines=iter_lines)
@bp.route('/<username>/<hashid>')
def view_item(username, hashid):
item = get_item(username, hashid)
if item.type == 'xanadoc':
return view_xanadoc(item)
return render_template('view.html',
doc=item,
iter_lines=iter_lines)
@bp.route('/<username>/<hashid>/edit', methods=['GET', 'POST'])
def edit_item(username, hashid):
obj = get_item(current_user.username, hashid)
form = SourceDocForm(obj=obj)
if form.validate_on_submit():
form.populate_obj(obj)
session.add(obj)
session.commit()
flash('Changes to {} saved.'.format(obj.type))
return redirect(obj.url)
return render_template('edit.html', form=form, doc=obj)
@bp.route('/source_doc_text/<int:source_doc_id>')
def source_doc_text(source_doc_id):
doc = SourceDoc.query.get(source_doc_id)
return render_template('source_doc_text.html', doc=doc, iter_lines=iter_lines)
@bp.route('/settings/account', methods=['GET', 'POST'])
@login_required
def account_settings():
form = AccountSettingsForm(obj=current_user)
if form.validate_on_submit():
form.populate_obj(current_user)
session.add(current_user)
session.commit()
flash('Account details updated.')
return redirect(url_for(request.endpoint))
return render_template('user/account.html', form=form)
@bp.route('/new/sourcedoc', methods=['GET', 'POST'])
@login_required
def new_sourcedoc():
form = SourceDocForm()
if form.validate_on_submit():
doc = SourceDoc(user=current_user)
form.populate_obj(doc)
session.add(doc)
session.commit()
flash('New document saved.')
return redirect(doc.url)
return render_template('new.html', form=form, title='source document')
@bp.route('/new/xanalink', methods=['GET', 'POST'])
@login_required
def new_xanalink():
form = ItemForm()
if form.validate_on_submit():
obj = XanaLink(user=current_user)
form.populate_obj(obj)
session.add(obj)
session.commit()
flash('New xanalink saved.')
return redirect(obj.url)
return render_template('new.html', form=form, title='xanalink')
@bp.route('/new/xanadoc', methods=['GET', 'POST'])
@login_required
def new_xanadoc():
form = ItemForm()
if form.validate_on_submit():
obj = XanaDoc(user=current_user)
form.populate_obj(obj)
session.add(obj)
session.commit()
flash('New xanadoc saved.')
return redirect(obj.url)
return render_template('new.html', form=form, title='xanadoc')
@bp.route('/edit/<filename>', methods=['GET', 'POST'])
@login_required
def edit_source_document(filename):
doc = get_source_doc(current_user.username, filename)
form = SourceDocForm(obj=doc)
if form.validate_on_submit():
form.populate_obj(doc)
session.add(doc)
session.commit()
flash('Changes to document saved.')
return redirect(doc.url)
return render_template('edit.html', form=form, doc=doc)
@bp.route('/api/1/get/<username>/<filename>')
def api_get_document(username, filename):
doc = get_source_doc(username, filename)
if not doc:
return abort(404)
ret = {
'username': username,
'filename': filename,
'character_count': len(doc.text),
'document_price': str(doc.document_price),
'price_per_character': str(doc.price_per_character),
}
return jsonify(ret)
@bp.route('/get_span.json')
def get_span():
url = request.args['url']
start = int(request.args['start'])
length = int(request.args['length'])
spanid = request.args['spanid']
text = get_url(url)
return jsonify(text=text[start:start + length], spanid=spanid)