mirror of
https://gitlab.com/SIGBUS/nyaa.git
synced 2024-12-22 09:30:01 +00:00
c405f49eb6
This started out as a simple rebase, but then I rebased the wrong branches and it all got confusing, so here it is as a new dank commit. We now have an @admin_only decorator, and we ask for confirmation before we nuke. We can also see the nuke button when users are banned, and nuking is a separate endpoint with a separate form. Additionally, it now uses the new tracker API.
93 lines
2.6 KiB
Python
93 lines
2.6 KiB
Python
import functools
|
|
import hashlib
|
|
import random
|
|
import string
|
|
from collections import OrderedDict
|
|
|
|
import flask
|
|
|
|
|
|
def sha1_hash(input_bytes):
|
|
""" Hash given bytes with hashlib.sha1 and return the digest (as bytes) """
|
|
return hashlib.sha1(input_bytes).digest()
|
|
|
|
|
|
def sorted_pathdict(input_dict):
|
|
""" Sorts a parsed torrent filelist dict by alphabat, directories first """
|
|
directories = OrderedDict()
|
|
files = OrderedDict()
|
|
|
|
for key, value in input_dict.items():
|
|
if isinstance(value, dict):
|
|
directories[key] = sorted_pathdict(value)
|
|
else:
|
|
files[key] = value
|
|
|
|
return OrderedDict(sorted(directories.items()) + sorted(files.items()))
|
|
|
|
|
|
def random_string(length, charset=None):
|
|
if charset is None:
|
|
charset = string.ascii_letters + string.digits
|
|
return ''.join(random.choice(charset) for i in range(length))
|
|
|
|
|
|
def cached_function(f):
|
|
sentinel = object()
|
|
f._cached_value = sentinel
|
|
|
|
@functools.wraps(f)
|
|
def decorator(*args, **kwargs):
|
|
if f._cached_value is sentinel:
|
|
f._cached_value = f(*args, **kwargs)
|
|
return f._cached_value
|
|
return decorator
|
|
|
|
|
|
def flatten_dict(d, result=None):
|
|
if result is None:
|
|
result = {}
|
|
for key in d:
|
|
value = d[key]
|
|
if isinstance(value, dict):
|
|
value1 = {}
|
|
for keyIn in value:
|
|
value1["/".join([key, keyIn])] = value[keyIn]
|
|
flatten_dict(value1, result)
|
|
elif isinstance(value, (list, tuple)):
|
|
for indexB, element in enumerate(value):
|
|
if isinstance(element, dict):
|
|
value1 = {}
|
|
index = 0
|
|
for keyIn in element:
|
|
newkey = "/".join([key, keyIn])
|
|
value1[newkey] = value[indexB][keyIn]
|
|
index += 1
|
|
for keyA in value1:
|
|
flatten_dict(value1, result)
|
|
else:
|
|
result[key] = value
|
|
return result
|
|
|
|
|
|
def chain_get(source, *args):
|
|
''' Tries to return values from source by the given keys.
|
|
Returns None if none match.
|
|
Note: can return a None from the source. '''
|
|
sentinel = object()
|
|
for key in args:
|
|
value = source.get(key, sentinel)
|
|
if value is not sentinel:
|
|
return value
|
|
return None
|
|
|
|
|
|
def admin_only(f):
|
|
@functools.wraps(f)
|
|
def wrapper(*args, **kwargs):
|
|
if flask.g.user and flask.g.user.is_superadmin:
|
|
return f(*args, **kwargs)
|
|
else:
|
|
flask.abort(401)
|
|
return wrapper
|