Remove v1 upload api and update notice

This commit is contained in:
TheAMM 2017-05-22 22:54:33 +03:00
parent b241dd5508
commit f04c3e1cf3
5 changed files with 10 additions and 231 deletions

View File

@ -6,6 +6,9 @@ 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 import routes
import functools import functools
import json import json
import os.path import os.path
@ -42,87 +45,7 @@ def api_require_user(f):
return decorator return decorator
def validate_user(upload_request):
auth_info = None
try:
if 'auth_info' in upload_request.files:
auth_info = json.loads(upload_request.files['auth_info'].read().decode('utf-8'))
if 'username' not in auth_info.keys() or 'password' not in auth_info.keys():
return False, None, None
username = auth_info['username']
password = auth_info['password']
user = models.User.by_username(username)
if not user:
user = models.User.by_email(username)
if not user or password != user.password_hash or \
user.status == models.UserStatusType.INACTIVE:
return False, None, None
return True, user, None
else:
return False, None, None
except Exception as e:
return False, None, e
def _create_upload_category_choices():
''' Turns categories in the database into a list of (id, name)s '''
choices = [('', '[Select a category]')]
for main_cat in models.MainCategory.query.order_by(models.MainCategory.id):
choices.append((main_cat.id_as_string, main_cat.name, True))
for sub_cat in main_cat.sub_categories:
choices.append((sub_cat.id_as_string, ' - ' + sub_cat.name))
return choices
# #################################### API ROUTES #################################### # #################################### API ROUTES ####################################
def api_upload(upload_request, user):
form_info = None
try:
form_info = json.loads(upload_request.files['torrent_info'].read().decode('utf-8'))
form_info_as_dict = []
for k, v in form_info.items():
if k in ['is_anonymous', 'is_hidden', 'is_remake', 'is_complete', 'is_trusted']:
if v:
form_info_as_dict.append((k, v))
else:
form_info_as_dict.append((k, v))
# Hack for while v1 is still being used: default trusted to true
if not [x for x in form_info_as_dict if x[0] == 'is_trusted']:
form_info_as_dict.append(('is_trusted', True))
form_info = ImmutableMultiDict(form_info_as_dict)
except Exception as e:
return flask.make_response(flask.jsonify(
{'Failure': ['Invalid data. See HELP in api_uploader.py']}), 400)
try:
torrent_file = upload_request.files['torrent_file']
torrent_file = ImmutableMultiDict([('torrent_file', torrent_file)])
except Exception as e:
return flask.make_response(flask.jsonify(
{'Failure': ['No torrent file was attached.']}), 400)
form = forms.UploadForm(CombinedMultiDict((torrent_file, form_info)), meta={'csrf': False})
form.category.choices = _create_upload_category_choices()
if upload_request.method == 'POST' and form.validate():
torrent = backend.handle_torrent_upload(form, user, True)
return flask.make_response(flask.jsonify({'Success': int('{0}'.format(torrent.id))}), 200)
else:
return_error_messages = []
for error_name, error_messages in form.errors.items():
return_error_messages.extend(error_messages)
return flask.make_response(flask.jsonify({'Failure': return_error_messages}), 400)
# V2 below
# Map UploadForm fields to API keys # Map UploadForm fields to API keys
UPLOAD_API_FORM_KEYMAP = { UPLOAD_API_FORM_KEYMAP = {
@ -150,6 +73,7 @@ UPLOAD_API_DEFAULTS = {
} }
@api_blueprint.route('/upload', methods=['POST'])
@api_blueprint.route('/v2/upload', methods=['POST']) @api_blueprint.route('/v2/upload', methods=['POST'])
@basic_auth_user @basic_auth_user
@api_require_user @api_require_user
@ -170,7 +94,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 = _create_upload_category_choices() upload_form.category.choices = routes._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

@ -133,9 +133,6 @@ def get_category_id_map():
# Routes start here # # Routes start here #
app.register_blueprint(api_handler.api_blueprint, url_prefix='/api')
def chain_get(source, *args): def chain_get(source, *args):
''' Tries to return values from source by the given keys. ''' Tries to return values from source by the given keys.
Returns None if none match. Returns None if none match.
@ -767,10 +764,5 @@ def site_help():
# #################################### API ROUTES #################################### # #################################### API ROUTES ####################################
@app.route('/api/upload', methods=['POST'])
def api_upload(): app.register_blueprint(api_handler.api_blueprint, url_prefix='/api')
is_valid_user, user, debug = api_handler.validate_user(flask.request)
if not is_valid_user:
return flask.make_response(flask.jsonify({"Failure": "Invalid username or password."}), 400)
api_response = api_handler.api_upload(flask.request, user)
return api_response

View File

@ -3,8 +3,8 @@
{% block body %} {% block body %}
<div class="alert alert-info"> <div class="alert alert-info">
<p><strong>5/21 Update:</strong> We've updated our upload API to v2 (v1 still works). See documentation <b><a href="https://github.com/nyaadevs/nyaa/blob/master/utils/api_uploader_v2.py">here</a></b>.</p> <p><strong>2017-05-22 Update:</strong> We've updated our upload API to v2 (v1 <b>is now disabled!</b>). See documentation <b><a href="https://github.com/nyaadevs/nyaa/blob/master/utils/api_uploader_v2.py">here</a></b>.</p>
<p><strong>5/17 Update:</strong> We've added faster and more accurate search! In addition to your typical keyword search in both English and other languages, you can also now use powerful operators <p><strong>2017-05-17 Update:</strong> We've added faster and more accurate search! In addition to your typical keyword search in both English and other languages, you can also now use powerful operators
like <kbd>clockwork planet -horrible</kbd> or <kbd>commie|horrible|cartel yowamushi</kbd> to search. For all supported operators, please click <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-simple-query-string-query.html#_simple_query_string_syntax">here</a>. More features are coming soon!</p><br> like <kbd>clockwork planet -horrible</kbd> or <kbd>commie|horrible|cartel yowamushi</kbd> to search. For all supported operators, please click <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-simple-query-string-query.html#_simple_query_string_syntax">here</a>. More features are coming soon!</p><br>
<p>We welcome you to provide feedback at <a href="irc://irc.rizon.net/nyaa-dev">#nyaa-dev@irc.rizon.net</a></p> <p>We welcome you to provide feedback at <a href="irc://irc.rizon.net/nyaa-dev">#nyaa-dev@irc.rizon.net</a></p>
<p>Our GitHub: <a href="https://github.com/nyaadevs" target="_blank">https://github.com/nyaadevs</a> - creating <a href="https://github.com/nyaadevs/nyaa/issues">issues</a> for features and faults is recommendable!</p> <p>Our GitHub: <a href="https://github.com/nyaadevs" target="_blank">https://github.com/nyaadevs</a> - creating <a href="https://github.com/nyaadevs/nyaa/issues">issues</a> for features and faults is recommendable!</p>

View File

@ -1,137 +0,0 @@
# Uploads a single torrent file
# Works on nyaa.si and sukebei.nyaa.si
# Consider using api_uploader_v2.py instead
# It has a nice command line interface
import json
import requests
'''
The POST payload to the api endpoint (/api/upload) should be multipart/form-data containing three fields
'auth_info': file containing "{
'username': str,
'password': str
}",
'torrent_info': {
'category': str, # see below
'display_name': str, # optional
'information': str,
'description': str,
'is_anonymous': boolean,
'is_hidden': boolean,
'is_remake': boolean,
'is_complete': boolean,
'is_trusted': boolean #optional
},
'torrent_file': multi part file format
A successful request should return {'Success': int(torrent_id)}
A failed request should return {'Failure': ["Failure 1", "Failure 2"...]]}
'''
# ########################################### HELP ############################################
# ################################# CATEGORIES MUST BE EXACT ##################################
'''
# Nyaa categories only for now, but api still works for sukebei
Anime
Anime - AMV : '1_1'
Anime - English : '1_2'
Anime - Non-English : '1_3'
Anime - Raw : '1_4'
Audio
Lossless : '2_1'
Lossy : '2_2'
Literature
Literature - English-translated : '3_1'
Literature - Non-English : '3_2'
Literature - Non-English-Translated : '3_3'
Literature - Raw : '3_4'
Live Action
Live Action - English-translated : '4_1'
Live Action - Idol/Promotional Video : '4_2'
Live Action - Non-English-translated : '4_3'
Live Action - Raw : '4_4'
Pictures
Pictures - Graphics : '5_1'
Pictures - Photos : '5_2'
Software
Software - Applications : '6_1'
Software - Games : '6_2'
'''
# ################################# CATEGORIES MUST BE EXACT ##################################
# ###################################### EXAMPLE REQUEST ######################################
'''
# Required
username = ''
password = ''
torrent_file = '/path/to/my.torrent'
category = '1_2'
#Optional
display_name = ''
information = 'API HOWTO'
description = 'Visit #nyaa-dev@irc.rizon.net'
# Defaults to False, change to True to set
is_anonymous : False,
is_hidden : False,
is_remake : False,
is_complete : False
'''
# ######################################## CHANGE HERE ########################################
url = 'https://nyaa.si/api/upload' # or 'https://sukebei.nyaa.si/api/upload' or 'http://127.0.0.1:5500/api/upload'
# Required
username = ''
password = ''
torrent_file = ''
category = ''
# Optional
display_name = ''
information = ''
description = ''
is_anonymous = False
is_hidden = False
is_remake = False
is_complete = False
is_trusted = True # This will only work if a user is trusted, otherwise the option is ignored
auth_info = {
'username' : username,
'password' : password
}
metadata={
'category' : category,
'display_name' : display_name,
'information' : information,
'description' : description,
'is_anonymous' : is_anonymous,
'is_hidden' : is_hidden,
'is_remake' : is_remake,
'is_complete' : is_complete,
'is_trusted' : is_trusted
}
files = {
'auth_info' : (json.dumps(auth_info)),
'torrent_info' : (json.dumps(metadata)),
'torrent_file' : ('{0}'.format(torrent_file), open(torrent_file, 'rb'), 'application/octet-stream')
}
response = requests.post(url, files=files)
json_response = response.json()
print(json_response)
# A successful request should print {'Success': int(torrent_id)}

View File

@ -9,7 +9,7 @@ NYAA_HOST = 'https://nyaa.si'
SUKEBEI_HOST = 'https://sukebei.nyaa.si' SUKEBEI_HOST = 'https://sukebei.nyaa.si'
API_BASE = '/api' API_BASE = '/api'
API_UPLOAD = API_BASE + '/v2/upload' API_UPLOAD = API_BASE + '/upload'
NYAA_CATS = '''1_1 - Anime - AMV NYAA_CATS = '''1_1 - Anime - AMV
1_2 - Anime - English 1_2 - Anime - English