mirror of
				https://github.com/sb745/NyaaV3.git
				synced 2025-10-31 07:55:46 +02:00 
			
		
		
		
	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:
		
							parent
							
								
									9acdd14e81
								
							
						
					
					
						commit
						9fef343c1b
					
				
					 6 changed files with 127 additions and 127 deletions
				
			
		|  | @ -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) | ||||||
|  |  | ||||||
|  | @ -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! :/ ''' | ||||||
|  |  | ||||||
							
								
								
									
										123
									
								
								nyaa/routes.py
									
										
									
									
									
								
							
							
						
						
									
										123
									
								
								nyaa/routes.py
									
										
									
									
									
								
							|  | @ -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) | ||||||
|  |  | ||||||
|  | @ -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 | ||||||
|  |  | ||||||
|  | @ -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> | ||||||
|  |  | ||||||
|  | @ -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 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Kfir Hadas
						Kfir Hadas