Move torrent edit and upload into 'torrents' blueprint

Move supporting functions and variables into other files
* nyaa.views.torrents:
  - _create_upload_category_choices
* nyaa.backend:
  - get_category_id_map
This commit is contained in:
Kfir Hadas 2017-07-24 23:10:36 +03:00
parent 9acdd14e81
commit 9fef343c1b
6 changed files with 127 additions and 127 deletions

View File

@ -6,8 +6,7 @@ from nyaa import models, forms
from nyaa import bencode, backend, utils from nyaa import bencode, backend, utils
from nyaa import torrents from nyaa import torrents
# For _create_upload_category_choices from nyaa.views.torrents import _create_upload_category_choices
from nyaa import routes
import functools import functools
import json import json
@ -102,7 +101,7 @@ def v2_api_upload():
# Flask-WTF (very helpfully!!) automatically grabs the request form, so force a None formdata # Flask-WTF (very helpfully!!) automatically grabs the request form, so force a None formdata
upload_form = forms.UploadForm(None, data=mapped_dict, meta={'csrf': False}) upload_form = forms.UploadForm(None, data=mapped_dict, meta={'csrf': False})
upload_form.category.choices = routes._create_upload_category_choices() upload_form.category.choices = _create_upload_category_choices()
if upload_form.validate(): if upload_form.validate():
torrent = backend.handle_torrent_upload(upload_form, flask.g.user) torrent = backend.handle_torrent_upload(upload_form, flask.g.user)

View File

@ -12,6 +12,19 @@ from orderedset import OrderedSet
from ipaddress import ip_address from ipaddress import ip_address
@utils.cached_function
def get_category_id_map():
''' Reads database for categories and turns them into a dict with
ids as keys and name list as the value, ala
{'1_0': ['Anime'], '1_2': ['Anime', 'English-translated'], ...} '''
cat_id_map = {}
for main_cat in models.MainCategory.query:
cat_id_map[main_cat.id_as_string] = [main_cat.name]
for sub_cat in main_cat.sub_categories:
cat_id_map[sub_cat.id_as_string] = [main_cat.name, sub_cat.name]
return cat_id_map
def _replace_utf8_values(dict_or_list): def _replace_utf8_values(dict_or_list):
''' Will replace 'property' with 'property.utf-8' and remove latter if it exists. ''' Will replace 'property' with 'property.utf-8' and remove latter if it exists.
Thanks, bitcomet! :/ ''' Thanks, bitcomet! :/ '''

View File

@ -2,10 +2,9 @@ import os.path
from urllib.parse import quote from urllib.parse import quote
import flask import flask
from werkzeug.datastructures import CombinedMultiDict
from nyaa import api_handler, app, backend, db, forms, models, template_utils, torrents, views from nyaa import api_handler, app, db, forms, models, template_utils, torrents, views
from nyaa.utils import cached_function from nyaa.backend import get_category_id_map
DEBUG_API = False DEBUG_API = False
@ -16,52 +15,8 @@ def category_name(cat_id):
return ' - '.join(get_category_id_map().get(cat_id, ['???'])) return ' - '.join(get_category_id_map().get(cat_id, ['???']))
@cached_function
def get_category_id_map():
''' Reads database for categories and turns them into a dict with
ids as keys and name list as the value, ala
{'1_0': ['Anime'], '1_2': ['Anime', 'English-translated'], ...} '''
cat_id_map = {}
for main_cat in models.MainCategory.query:
cat_id_map[main_cat.id_as_string] = [main_cat.name]
for sub_cat in main_cat.sub_categories:
cat_id_map[sub_cat.id_as_string] = [main_cat.name, sub_cat.name]
return cat_id_map
# Routes start here # # Routes start here #
@cached_function
def _create_upload_category_choices():
''' Turns categories in the database into a list of (id, name)s '''
choices = [('', '[Select a category]')]
id_map = get_category_id_map()
for key in sorted(id_map.keys()):
cat_names = id_map[key]
is_main_cat = key.endswith('_0')
# cat_name = is_main_cat and cat_names[0] or (' - ' + cat_names[1])
cat_name = ' - '.join(cat_names)
choices.append((key, cat_name, is_main_cat))
return choices
@app.route('/upload', methods=['GET', 'POST'])
def upload():
upload_form = forms.UploadForm(CombinedMultiDict((flask.request.files, flask.request.form)))
upload_form.category.choices = _create_upload_category_choices()
if flask.request.method == 'POST' and upload_form.validate():
torrent = backend.handle_torrent_upload(upload_form, flask.g.user)
return flask.redirect(flask.url_for('torrents.view', torrent_id=torrent.id))
else:
# If we get here with a POST, it means the form data was invalid: return a non-okay status
status_code = 400 if flask.request.method == 'POST' else 200
return flask.render_template('upload.html', upload_form=upload_form), status_code
@app.route('/view/<int:torrent_id>/comment/<int:comment_id>/delete', methods=['POST']) @app.route('/view/<int:torrent_id>/comment/<int:comment_id>/delete', methods=['POST'])
def delete_comment(torrent_id, comment_id): def delete_comment(torrent_id, comment_id):
if not flask.g.user: if not flask.g.user:
@ -93,80 +48,6 @@ def delete_comment(torrent_id, comment_id):
return flask.redirect(url) return flask.redirect(url)
@app.route('/view/<int:torrent_id>/edit', methods=['GET', 'POST'])
def edit_torrent(torrent_id):
torrent = models.Torrent.by_id(torrent_id)
form = forms.EditForm(flask.request.form)
form.category.choices = _create_upload_category_choices()
editor = flask.g.user
if not torrent:
flask.abort(404)
# Only allow admins edit deleted torrents
if torrent.deleted and not (editor and editor.is_moderator):
flask.abort(404)
# Only allow torrent owners or admins edit torrents
if not editor or not (editor is torrent.user or editor.is_moderator):
flask.abort(403)
if flask.request.method == 'POST' and form.validate():
# Form has been sent, edit torrent with data.
torrent.main_category_id, torrent.sub_category_id = \
form.category.parsed_data.get_category_ids()
torrent.display_name = (form.display_name.data or '').strip()
torrent.information = (form.information.data or '').strip()
torrent.description = (form.description.data or '').strip()
torrent.hidden = form.is_hidden.data
torrent.remake = form.is_remake.data
torrent.complete = form.is_complete.data
torrent.anonymous = form.is_anonymous.data
if editor.is_trusted:
torrent.trusted = form.is_trusted.data
deleted_changed = torrent.deleted != form.is_deleted.data
if editor.is_moderator:
torrent.deleted = form.is_deleted.data
url = flask.url_for('torrents.view', torrent_id=torrent.id)
if deleted_changed and editor.is_moderator:
log = "Torrent [#{0}]({1}) marked as {2}".format(
torrent.id, url, "deleted" if torrent.deleted else "undeleted")
adminlog = models.AdminLog(log=log, admin_id=editor.id)
db.session.add(adminlog)
db.session.commit()
flask.flash(flask.Markup(
'Torrent has been successfully edited! Changes might take a few minutes to show up.'),
'info')
return flask.redirect(url)
else:
if flask.request.method != 'POST':
# Fill form data only if the POST didn't fail
form.category.data = torrent.sub_category.id_as_string
form.display_name.data = torrent.display_name
form.information.data = torrent.information
form.description.data = torrent.description
form.is_hidden.data = torrent.hidden
form.is_remake.data = torrent.remake
form.is_complete.data = torrent.complete
form.is_anonymous.data = torrent.anonymous
form.is_trusted.data = torrent.trusted
form.is_deleted.data = torrent.deleted
return flask.render_template('edit.html',
form=form,
torrent=torrent)
@app.route('/view/<int:torrent_id>/magnet') @app.route('/view/<int:torrent_id>/magnet')
def redirect_magnet(torrent_id): def redirect_magnet(torrent_id):
torrent = models.Torrent.by_id(torrent_id) torrent = models.Torrent.by_id(torrent_id)

View File

@ -71,7 +71,7 @@
{% set search_placeholder = 'Search {} torrents...'.format(search_username) if user_page else 'Search...' %} {% set search_placeholder = 'Search {} torrents...'.format(search_username) if user_page else 'Search...' %}
<div id="navbar" class="navbar-collapse collapse"> <div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav"> <ul class="nav navbar-nav">
<li {% if request.path == url_for('upload') %}class="active"{% endif %}><a href="{{ url_for('upload') }}">Upload</a></li> <li {% if request.path == url_for('torrents.upload') %}class="active"{% endif %}><a href="{{ url_for('torrents.upload') }}">Upload</a></li>
<li class="dropdown"> <li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
About About

View File

@ -10,7 +10,7 @@
<div class="panel-heading"{% if torrent.hidden %} style="background-color: darkgray;"{% endif %}> <div class="panel-heading"{% if torrent.hidden %} style="background-color: darkgray;"{% endif %}>
<h3 class="panel-title"> <h3 class="panel-title">
{% if can_edit %} {% if can_edit %}
<a href="{{ url_for('edit_torrent', torrent_id=torrent.id) }}" title="Edit torrent"><i class="fa fa-fw fa-pencil"></i></a> <a href="{{ url_for('torrents.edit', torrent_id=torrent.id) }}" title="Edit torrent"><i class="fa fa-fw fa-pencil"></i></a>
{% endif %} {% endif %}
{{ torrent.display_name }} {{ torrent.display_name }}
</h3> </h3>

View File

@ -1,10 +1,12 @@
import json import json
import flask import flask
from werkzeug.datastructures import CombinedMultiDict
from sqlalchemy.orm import joinedload from sqlalchemy.orm import joinedload
from nyaa import db, forms, models from nyaa import backend, db, forms, models
from nyaa.utils import cached_function
bp = flask.Blueprint('torrents', __name__) bp = flask.Blueprint('torrents', __name__)
@ -68,3 +70,108 @@ def view_torrent(torrent_id):
comments=torrent.comments, comments=torrent.comments,
can_edit=can_edit, can_edit=can_edit,
report_form=report_form) report_form=report_form)
@bp.route('/view/<int:torrent_id>/edit', endpoint='edit', methods=['GET', 'POST'])
def edit_torrent(torrent_id):
torrent = models.Torrent.by_id(torrent_id)
form = forms.EditForm(flask.request.form)
form.category.choices = _create_upload_category_choices()
editor = flask.g.user
if not torrent:
flask.abort(404)
# Only allow admins edit deleted torrents
if torrent.deleted and not (editor and editor.is_moderator):
flask.abort(404)
# Only allow torrent owners or admins edit torrents
if not editor or not (editor is torrent.user or editor.is_moderator):
flask.abort(403)
if flask.request.method == 'POST' and form.validate():
# Form has been sent, edit torrent with data.
torrent.main_category_id, torrent.sub_category_id = \
form.category.parsed_data.get_category_ids()
torrent.display_name = (form.display_name.data or '').strip()
torrent.information = (form.information.data or '').strip()
torrent.description = (form.description.data or '').strip()
torrent.hidden = form.is_hidden.data
torrent.remake = form.is_remake.data
torrent.complete = form.is_complete.data
torrent.anonymous = form.is_anonymous.data
if editor.is_trusted:
torrent.trusted = form.is_trusted.data
deleted_changed = torrent.deleted != form.is_deleted.data
if editor.is_moderator:
torrent.deleted = form.is_deleted.data
url = flask.url_for('torrents.view', torrent_id=torrent.id)
if deleted_changed and editor.is_moderator:
log = "Torrent [#{0}]({1}) marked as {2}".format(
torrent.id, url, "deleted" if torrent.deleted else "undeleted")
adminlog = models.AdminLog(log=log, admin_id=editor.id)
db.session.add(adminlog)
db.session.commit()
flask.flash(flask.Markup(
'Torrent has been successfully edited! Changes might take a few minutes to show up.'),
'info')
return flask.redirect(url)
else:
if flask.request.method != 'POST':
# Fill form data only if the POST didn't fail
form.category.data = torrent.sub_category.id_as_string
form.display_name.data = torrent.display_name
form.information.data = torrent.information
form.description.data = torrent.description
form.is_hidden.data = torrent.hidden
form.is_remake.data = torrent.remake
form.is_complete.data = torrent.complete
form.is_anonymous.data = torrent.anonymous
form.is_trusted.data = torrent.trusted
form.is_deleted.data = torrent.deleted
return flask.render_template('edit.html',
form=form,
torrent=torrent)
@bp.route('/upload', methods=['GET', 'POST'])
def upload():
upload_form = forms.UploadForm(CombinedMultiDict((flask.request.files, flask.request.form)))
upload_form.category.choices = _create_upload_category_choices()
if flask.request.method == 'POST' and upload_form.validate():
torrent = backend.handle_torrent_upload(upload_form, flask.g.user)
return flask.redirect(flask.url_for('torrents.view', torrent_id=torrent.id))
else:
# If we get here with a POST, it means the form data was invalid: return a non-okay status
status_code = 400 if flask.request.method == 'POST' else 200
return flask.render_template('upload.html', upload_form=upload_form), status_code
@cached_function
def _create_upload_category_choices():
''' Turns categories in the database into a list of (id, name)s '''
choices = [('', '[Select a category]')]
id_map = backend.get_category_id_map()
for key in sorted(id_map.keys()):
cat_names = id_map[key]
is_main_cat = key.endswith('_0')
# cat_name = is_main_cat and cat_names[0] or (' - ' + cat_names[1])
cat_name = ' - '.join(cat_names)
choices.append((key, cat_name, is_main_cat))
return choices