forked from 0x2620/pandora
use json_response
This commit is contained in:
parent
f606ee998d
commit
f2b97de2b1
2 changed files with 55 additions and 59 deletions
|
@ -22,7 +22,7 @@ except ImportError:
|
||||||
from django.utils import simplejson as json
|
from django.utils import simplejson as json
|
||||||
|
|
||||||
from oxdjango.decorators import login_required_json
|
from oxdjango.decorators import login_required_json
|
||||||
from oxdjango.shortcuts import render_to_json_response, get_object_or_404_json
|
from oxdjango.shortcuts import render_to_json_response, get_object_or_404_json, json_response
|
||||||
|
|
||||||
import models
|
import models
|
||||||
import utils
|
import utils
|
||||||
|
@ -49,8 +49,8 @@ def api(request):
|
||||||
if f:
|
if f:
|
||||||
response = f(request)
|
response = f(request)
|
||||||
else:
|
else:
|
||||||
response = render_to_json_response(
|
response = render_to_json_response(json_response(status=400,
|
||||||
{'status': {'code': 400, 'text': 'Unknown function %s' % function}})
|
text='Unknown function %s' % function))
|
||||||
#response['Access-Control-Allow-Origin'] = '*'
|
#response['Access-Control-Allow-Origin'] = '*'
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ def api_hello(request):
|
||||||
return {'status': {'code': int, 'text': string},
|
return {'status': {'code': int, 'text': string},
|
||||||
'data': {user: object}}
|
'data': {user: object}}
|
||||||
'''
|
'''
|
||||||
response = {'status': {'code': 200, 'text': 'ok'}, 'data': {}}
|
response = json_response({})
|
||||||
if request.user.is_authenticated():
|
if request.user.is_authenticated():
|
||||||
response['data']['user'] = getUserJSON(request.user)
|
response['data']['user'] = getUserJSON(request.user)
|
||||||
else:
|
else:
|
||||||
|
@ -146,7 +146,7 @@ def api_find(request):
|
||||||
'data': {items=int, files=int, pixels=int, size=int, duration=int}}
|
'data': {items=int, files=int, pixels=int, size=int, duration=int}}
|
||||||
'''
|
'''
|
||||||
query = _parse_query(request)
|
query = _parse_query(request)
|
||||||
response = {'status': {'code': 200, 'text':'ok'}, 'data':{}}
|
response = json_response({})
|
||||||
if 'p' in query:
|
if 'p' in query:
|
||||||
response['data']['items'] = []
|
response['data']['items'] = []
|
||||||
qs = _order_query(query['q'], query['s'])
|
qs = _order_query(query['q'], query['s'])
|
||||||
|
@ -219,7 +219,7 @@ def api_getItem(request):
|
||||||
|
|
||||||
return item array
|
return item array
|
||||||
'''
|
'''
|
||||||
response = {'status': {'code': 200, 'text': 'ok'}}
|
response = json_response({})
|
||||||
itemId = json.loads(request.POST['data'])
|
itemId = json.loads(request.POST['data'])
|
||||||
item = get_object_or_404_json(models.Movie, movieId=itemId)
|
item = get_object_or_404_json(models.Movie, movieId=itemId)
|
||||||
#FIXME: check permissions
|
#FIXME: check permissions
|
||||||
|
@ -237,10 +237,10 @@ def api_editItem(request):
|
||||||
data = json.loads(request.POST['data'])
|
data = json.loads(request.POST['data'])
|
||||||
item = get_object_or_404_json(models.Movie, movieId=data['id'])
|
item = get_object_or_404_json(models.Movie, movieId=data['id'])
|
||||||
if item.editable(request.user):
|
if item.editable(request.user):
|
||||||
response = {'status': {'code': 501, 'text': 'not implemented'}}
|
response = json_response(status=501, text='not implemented')
|
||||||
item.edit(data)
|
item.edit(data)
|
||||||
else:
|
else:
|
||||||
response = {'status': {'code': 403, 'text': 'permission denied'}}
|
response = json_response(status=403, text='permissino denied')
|
||||||
return render_to_json_response(response)
|
return render_to_json_response(response)
|
||||||
|
|
||||||
@login_required_json
|
@login_required_json
|
||||||
|
@ -251,13 +251,13 @@ def api_removeItem(request):
|
||||||
|
|
||||||
return {'status': {'code': int, 'text': string}}
|
return {'status': {'code': int, 'text': string}}
|
||||||
'''
|
'''
|
||||||
response = {'status': {'code': 200, 'text': 'ok'}}
|
response = json_response({})
|
||||||
itemId = json.loads(request.POST['data'])
|
itemId = json.loads(request.POST['data'])
|
||||||
item = get_object_or_404_json(models.Movie, movieId=itemId)
|
item = get_object_or_404_json(models.Movie, movieId=itemId)
|
||||||
if item.editable(request.user):
|
if item.editable(request.user):
|
||||||
response = {'status': {'code': 501, 'text': 'not implemented'}}
|
response = json_response(status=501, text='not implemented')
|
||||||
else:
|
else:
|
||||||
response = {'status': {'code': 403, 'text': 'permission denied'}}
|
response = json_response(status=403, text='permissino denied')
|
||||||
return render_to_json_response(response)
|
return render_to_json_response(response)
|
||||||
|
|
||||||
@login_required_json
|
@login_required_json
|
||||||
|
@ -290,16 +290,16 @@ def api_editLayer(request):
|
||||||
return {'status': {'code': int, 'text': string},
|
return {'status': {'code': int, 'text': string},
|
||||||
'data': {}}
|
'data': {}}
|
||||||
'''
|
'''
|
||||||
response = {'status': {'code': 200, 'text': 'ok'}}
|
response = json_response({})
|
||||||
data = json.loads(request.POST['data'])
|
data = json.loads(request.POST['data'])
|
||||||
layer = get_object_or_404_json(models.Layer, pk=data['id'])
|
layer = get_object_or_404_json(models.Layer, pk=data['id'])
|
||||||
if layer.editable(request.user):
|
if layer.editable(request.user):
|
||||||
response = {'status': {'code': 501, 'text': 'not implemented'}}
|
response = json_response(status=501, text='not implemented')
|
||||||
else:
|
else:
|
||||||
response = {'status': {'code': 403, 'text': 'permission denied'}}
|
response = json_response(status=403, text='permission denied')
|
||||||
return render_to_json_response(response)
|
return render_to_json_response(response)
|
||||||
|
|
||||||
response = {'status': {'code': 501, 'text': 'not implemented'}}
|
response = json_response(status=501, text='not implemented')
|
||||||
return render_to_json_response(response)
|
return render_to_json_response(response)
|
||||||
|
|
||||||
@login_required_json
|
@login_required_json
|
||||||
|
@ -310,7 +310,7 @@ def api_addListItem(request):
|
||||||
return {'status': {'code': int, 'text': string},
|
return {'status': {'code': int, 'text': string},
|
||||||
'data': {}}
|
'data': {}}
|
||||||
'''
|
'''
|
||||||
response = {'status': {'code': 501, 'text': 'not implemented'}}
|
response = json_response(status=501, text='not implemented')
|
||||||
return render_to_json_response(response)
|
return render_to_json_response(response)
|
||||||
|
|
||||||
@login_required_json
|
@login_required_json
|
||||||
|
@ -321,7 +321,7 @@ def api_removeListItem(request):
|
||||||
return {'status': {'code': int, 'text': string},
|
return {'status': {'code': int, 'text': string},
|
||||||
'data': {}}
|
'data': {}}
|
||||||
'''
|
'''
|
||||||
response = {'status': {'code': 501, 'text': 'not implemented'}}
|
response = json_response(status=501, text='not implemented')
|
||||||
return render_to_json_response(response)
|
return render_to_json_response(response)
|
||||||
|
|
||||||
@login_required_json
|
@login_required_json
|
||||||
|
@ -332,7 +332,7 @@ def api_addList(request):
|
||||||
return {'status': {'code': int, 'text': string},
|
return {'status': {'code': int, 'text': string},
|
||||||
'data': {}}
|
'data': {}}
|
||||||
'''
|
'''
|
||||||
response = {'status': {'code': 501, 'text': 'not implemented'}}
|
response = json_response(status=501, text='not implemented')
|
||||||
return render_to_json_response(response)
|
return render_to_json_response(response)
|
||||||
|
|
||||||
@login_required_json
|
@login_required_json
|
||||||
|
@ -343,7 +343,7 @@ def api_editList(request):
|
||||||
return {'status': {'code': int, 'text': string},
|
return {'status': {'code': int, 'text': string},
|
||||||
'data': {}}
|
'data': {}}
|
||||||
'''
|
'''
|
||||||
response = {'status': {'code': 501, 'text': 'not implemented'}}
|
response = json_response(status=501, text='not implemented')
|
||||||
return render_to_json_response(response)
|
return render_to_json_response(response)
|
||||||
|
|
||||||
def api_removeList(request):
|
def api_removeList(request):
|
||||||
|
@ -353,7 +353,7 @@ def api_removeList(request):
|
||||||
return {'status': {'code': int, 'text': string},
|
return {'status': {'code': int, 'text': string},
|
||||||
'data': {}}
|
'data': {}}
|
||||||
'''
|
'''
|
||||||
response = {'status': {'code': 501, 'text': 'not implemented'}}
|
response = json_response(status=501, text='not implemented')
|
||||||
return render_to_json_response(response)
|
return render_to_json_response(response)
|
||||||
|
|
||||||
@login_required_json
|
@login_required_json
|
||||||
|
@ -373,7 +373,8 @@ def api_addArchive(request):
|
||||||
archive = models.Archive(name=data['name'])
|
archive = models.Archive(name=data['name'])
|
||||||
archive.save()
|
archive.save()
|
||||||
archive.users.add(request.user)
|
archive.users.add(request.user)
|
||||||
response = {'status': {'code': 200, 'text': 'archive created'}}
|
response = json_response({})
|
||||||
|
response['status']['text'] = 'archive created'
|
||||||
return render_to_json_response(response)
|
return render_to_json_response(response)
|
||||||
|
|
||||||
@login_required_json
|
@login_required_json
|
||||||
|
@ -388,10 +389,10 @@ def api_editArchive(request):
|
||||||
data = json.loads(request.POST['data'])
|
data = json.loads(request.POST['data'])
|
||||||
item = get_object_or_404_json(models.Archive, name=data['name'])
|
item = get_object_or_404_json(models.Archive, name=data['name'])
|
||||||
if item.editable(request.user):
|
if item.editable(request.user):
|
||||||
response = {'status': {'code': 501, 'text': 'not implemented'}}
|
response = json_response(status=501, text='not implemented')
|
||||||
item.edit(data)
|
item.edit(data)
|
||||||
else:
|
else:
|
||||||
response = {'status': {'code': 403, 'text': 'permission denied'}}
|
response = json_response(status=403, text='permission denied')
|
||||||
return render_to_json_response(response)
|
return render_to_json_response(response)
|
||||||
|
|
||||||
@login_required_json
|
@login_required_json
|
||||||
|
@ -403,13 +404,13 @@ def api_removeArchive(request):
|
||||||
|
|
||||||
return {'status': {'code': int, 'text': string}}
|
return {'status': {'code': int, 'text': string}}
|
||||||
'''
|
'''
|
||||||
response = {'status': {'code': 200, 'text': 'ok'}}
|
response = json_response({})
|
||||||
itemId = json.loads(request.POST['data'])
|
itemId = json.loads(request.POST['data'])
|
||||||
item = get_object_or_404_json(models.Archive, movieId=itemId)
|
item = get_object_or_404_json(models.Archive, movieId=itemId)
|
||||||
if item.editable(request.user):
|
if item.editable(request.user):
|
||||||
response = {'status': {'code': 501, 'text': 'not implemented'}}
|
response = json_response(status=501, text='not implemented')
|
||||||
else:
|
else:
|
||||||
response = {'status': {'code': 403, 'text': 'permission denied'}}
|
response = json_response(status=403, text='permission denied')
|
||||||
return render_to_json_response(response)
|
return render_to_json_response(response)
|
||||||
|
|
||||||
|
|
||||||
|
@ -450,11 +451,9 @@ def api_update(request):
|
||||||
rename[oshash] = f.file.path
|
rename[oshash] = f.file.path
|
||||||
#print "processed files for", archive.name
|
#print "processed files for", archive.name
|
||||||
#remove all files not in files.keys() from ArchiveFile
|
#remove all files not in files.keys() from ArchiveFile
|
||||||
response = {'status': {'code': 200, 'text': 'ok'}, 'data': {}}
|
response = json_response({'info': needs_data, 'rename': rename})
|
||||||
response['data']['info'] = needs_data
|
|
||||||
response['data']['rename'] = rename
|
|
||||||
else:
|
else:
|
||||||
response = {'status': {'code': 403, 'text': 'permission denied'}}
|
response = json_response(status=403, text='permission denied')
|
||||||
return render_to_json_response(response)
|
return render_to_json_response(response)
|
||||||
|
|
||||||
def api_encodingSettings(request):
|
def api_encodingSettings(request):
|
||||||
|
@ -463,8 +462,7 @@ def api_encodingSettings(request):
|
||||||
return {'status': {'code': int, 'text': string},
|
return {'status': {'code': int, 'text': string},
|
||||||
'data': {'options': {'videoQuality':...}}}
|
'data': {'options': {'videoQuality':...}}}
|
||||||
'''
|
'''
|
||||||
response = {'status': {'code': 200, 'text': 'ok'}}
|
response = json_response({'options': settings.VIDEO_ENCODING[settings.VIDEO_PROFILE]})
|
||||||
response['data'] = {'options': settings.VIDEO_ENCODING[settings.VIDEO_PROFILE]}
|
|
||||||
return render_to_json_response(response)
|
return render_to_json_response(response)
|
||||||
|
|
||||||
class UploadForm(forms.Form):
|
class UploadForm(forms.Form):
|
||||||
|
@ -497,14 +495,13 @@ def api_upload(request): #video, timeline, frame
|
||||||
frame.frame.delete()
|
frame.frame.delete()
|
||||||
frame.frame.save(ff.name, ff)
|
frame.frame.save(ff.name, ff)
|
||||||
frame.save()
|
frame.save()
|
||||||
response = {'status': {'code': 200, 'text': 'ok'}}
|
response = json_response({'url': frame.frame.url})
|
||||||
response['url'] = frame.frame.url
|
|
||||||
return render_to_json_response(response)
|
return render_to_json_response(response)
|
||||||
if data['item'] == 'timeline':
|
if data['item'] == 'timeline':
|
||||||
pass
|
pass
|
||||||
#print "not implemented"
|
#print "not implemented"
|
||||||
|
|
||||||
response = {'status': {'code': 501, 'text': 'not implemented'}}
|
response = json_response(status=501, text='not implemented')
|
||||||
return render_to_json_response(response)
|
return render_to_json_response(response)
|
||||||
|
|
||||||
@login_required_json
|
@login_required_json
|
||||||
|
@ -548,7 +545,7 @@ def firefogg_upload(request):
|
||||||
response['done'] = 1
|
response['done'] = 1
|
||||||
return render_to_json_response(response)
|
return render_to_json_response(response)
|
||||||
print request.GET, request.POST
|
print request.GET, request.POST
|
||||||
response = {'status': {'code': 400, 'text': 'this request requires POST'}}
|
response = json_response(status=400, text='this request requires POST')
|
||||||
return render_to_json_response(response)
|
return render_to_json_response(response)
|
||||||
|
|
||||||
@login_required_json
|
@login_required_json
|
||||||
|
@ -556,7 +553,7 @@ def api_editFile(request): #FIXME: should this be file.files. or part of update
|
||||||
'''
|
'''
|
||||||
change file / imdb link
|
change file / imdb link
|
||||||
'''
|
'''
|
||||||
response = {'status': {'code': 501, 'text': 'not implemented'}}
|
response = json_response(status=501, text='not implemented')
|
||||||
return render_to_json_response(response)
|
return render_to_json_response(response)
|
||||||
|
|
||||||
def api_parse(request): #parse path and return info
|
def api_parse(request): #parse path and return info
|
||||||
|
@ -567,8 +564,7 @@ def api_parse(request): #parse path and return info
|
||||||
data: {imdb: string}}
|
data: {imdb: string}}
|
||||||
'''
|
'''
|
||||||
path = json.loads(request.POST['data'])['path']
|
path = json.loads(request.POST['data'])['path']
|
||||||
response = utils.parsePath(path)
|
response = json_response(utils.parsePath(path))
|
||||||
response = {'status': {'code': 200, 'text': 'ok'}, data: response}
|
|
||||||
return render_to_json_response(response)
|
return render_to_json_response(response)
|
||||||
|
|
||||||
def api_getImdbId(request):
|
def api_getImdbId(request):
|
||||||
|
@ -580,10 +576,9 @@ def api_getImdbId(request):
|
||||||
'''
|
'''
|
||||||
imdbId = oxweb.imdb.guess(search_title, r['director'], timeout=-1)
|
imdbId = oxweb.imdb.guess(search_title, r['director'], timeout=-1)
|
||||||
if imdbId:
|
if imdbId:
|
||||||
response = {'status': {'code': 200, 'text': 'ok'},
|
response = json_response({'imdbId': imdbId})
|
||||||
'data': {'imdbId': imdbId}}
|
|
||||||
else:
|
else:
|
||||||
response = {'status': {'code': 404, 'text': 'not found'}}
|
response = json_response(status=404, text='not found')
|
||||||
return render_to_json_response(response)
|
return render_to_json_response(response)
|
||||||
|
|
||||||
def api_fileInfo(request):
|
def api_fileInfo(request):
|
||||||
|
@ -626,7 +621,7 @@ def api_subtitles(request):
|
||||||
sub.srt = srt
|
sub.srt = srt
|
||||||
sub.save()
|
sub.save()
|
||||||
else:
|
else:
|
||||||
response = {'status': {'code': 200, 'text': 'ok'}, 'data':{}}
|
response = json_response({})
|
||||||
if language:
|
if language:
|
||||||
q = models.Subtitles.objects.filter(movie_file__oshash=oshash, language=language)
|
q = models.Subtitles.objects.filter(movie_file__oshash=oshash, language=language)
|
||||||
if q.count() > 0:
|
if q.count() > 0:
|
||||||
|
|
|
@ -11,7 +11,7 @@ from django.template import RequestContext, loader, Context
|
||||||
from django.utils import simplejson as json
|
from django.utils import simplejson as json
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
|
||||||
from oxdjango.shortcuts import render_to_json_response
|
from oxdjango.shortcuts import render_to_json_response, json_response
|
||||||
from oxdjango.decorators import login_required_json
|
from oxdjango.decorators import login_required_json
|
||||||
|
|
||||||
import models
|
import models
|
||||||
|
@ -27,7 +27,7 @@ def api_login(request):
|
||||||
|
|
||||||
return {'status': {'code': int, 'text': string}}
|
return {'status': {'code': int, 'text': string}}
|
||||||
'''
|
'''
|
||||||
response = {'status': {'code': 403, 'text': 'login failed'}}
|
response = json_response(status=403, text='login failed')
|
||||||
data = json.loads(request.POST['data'])
|
data = json.loads(request.POST['data'])
|
||||||
form = LoginForm(data, request.FILES)
|
form = LoginForm(data, request.FILES)
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
|
@ -36,13 +36,15 @@ def api_login(request):
|
||||||
if user.is_active:
|
if user.is_active:
|
||||||
login(request, user)
|
login(request, user)
|
||||||
user_json = models.getUserJSON(user)
|
user_json = models.getUserJSON(user)
|
||||||
response = {'status': {'code': 200, 'message': 'You are logged in.', 'user': user_json}}
|
response = json_response({'user': user_json}, text='You are logged in.')
|
||||||
else:
|
else:
|
||||||
response = {'status': {'code': 401, 'text': 'Your account is disabled.'}}
|
response = json_response(status=401,
|
||||||
|
text='Your account is disabled.')
|
||||||
else:
|
else:
|
||||||
response = {'status': {'code': 401, 'text': 'Your username and password were incorrect.'}}
|
response = json_response(status=401,
|
||||||
|
text='Your username and password were incorrect.')
|
||||||
else:
|
else:
|
||||||
response = {'status': {'code': 400, 'text': 'invalid data'}}
|
response = json_response(status=400, text='invalid data')
|
||||||
|
|
||||||
return render_to_json_response(response)
|
return render_to_json_response(response)
|
||||||
|
|
||||||
|
@ -53,7 +55,7 @@ def api_logout(request):
|
||||||
|
|
||||||
return {'status': {'code': int, 'text': string}}
|
return {'status': {'code': int, 'text': string}}
|
||||||
'''
|
'''
|
||||||
response = {'status': {'code': 200, 'text': 'logged out'}}
|
response = json_response(text='logged out')
|
||||||
if request.user.is_authenticated():
|
if request.user.is_authenticated():
|
||||||
logout(request)
|
logout(request)
|
||||||
return render_to_json_response(response)
|
return render_to_json_response(response)
|
||||||
|
@ -74,9 +76,9 @@ def api_register(request):
|
||||||
form = RegisterForm(data, request.FILES)
|
form = RegisterForm(data, request.FILES)
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
if models.User.objects.filter(username=form.data['username']).count() > 0:
|
if models.User.objects.filter(username=form.data['username']).count() > 0:
|
||||||
response = {'status': {'code': 400, 'text': 'username or email exists'}}
|
response = json_response(status=400, text='username or email exists')
|
||||||
elif models.User.objects.filter(email=form.data['email']).count() > 0:
|
elif models.User.objects.filter(email=form.data['email']).count() > 0:
|
||||||
response = {'status': {'code': 400, 'text': 'username or email exists'}}
|
response = json_response(status=400, text='username or email exists')
|
||||||
else:
|
else:
|
||||||
user = models.User(username=form.data['username'], email=form.data['email'])
|
user = models.User(username=form.data['username'], email=form.data['email'])
|
||||||
user.set_password(form.data['password'])
|
user.set_password(form.data['password'])
|
||||||
|
@ -84,9 +86,9 @@ def api_register(request):
|
||||||
user = authenticate(username=form.data['username'],
|
user = authenticate(username=form.data['username'],
|
||||||
password=form.data['password'])
|
password=form.data['password'])
|
||||||
login(request, user)
|
login(request, user)
|
||||||
response = {'status': {'code':200, 'text': 'account created'}}
|
response = json_response(text='account created')
|
||||||
else:
|
else:
|
||||||
response = {'status': {'code': 400, 'text': 'username exists'}}
|
response = json_response(status=400, text='username exists')
|
||||||
return render_to_json_response(response)
|
return render_to_json_response(response)
|
||||||
|
|
||||||
class RecoverForm(forms.Form):
|
class RecoverForm(forms.Form):
|
||||||
|
@ -125,11 +127,11 @@ def api_recover(request):
|
||||||
message = template.render(context)
|
message = template.render(context)
|
||||||
subject = '%s account recovery' % settings.SITENAME
|
subject = '%s account recovery' % settings.SITENAME
|
||||||
user.email_user(subject, message)
|
user.email_user(subject, message)
|
||||||
response = {'status': {'code': 200, 'text': 'recover email sent.'}}
|
response = json_response(text='recover email sent')
|
||||||
else:
|
else:
|
||||||
response = {'status': {'code': 404, 'text': 'user or email not found.'}}
|
response = json_response(status=404, text='username or email not found')
|
||||||
else:
|
else:
|
||||||
response = {'status': {'code': 400, 'text': 'username exists'}}
|
response = json_response(status=400, text='invalid data')
|
||||||
return render_to_json_response(response)
|
return render_to_json_response(response)
|
||||||
|
|
||||||
def recover(request, key):
|
def recover(request, key):
|
||||||
|
@ -165,7 +167,7 @@ def api_preferences(request):
|
||||||
if data is object:
|
if data is object:
|
||||||
set key values in dict as preferences
|
set key values in dict as preferences
|
||||||
'''
|
'''
|
||||||
response = {'status': {'code': 200, 'text': 'ok'}, 'data':{}}
|
response = json_response()
|
||||||
if 'data' not in request.POST:
|
if 'data' not in request.POST:
|
||||||
response['data']['preferences'] = models.getPreferences(request.user)
|
response['data']['preferences'] = models.getPreferences(request.user)
|
||||||
else:
|
else:
|
||||||
|
@ -185,4 +187,3 @@ def api_preferences(request):
|
||||||
for key in data:
|
for key in data:
|
||||||
models.setPreference(request.user, key, data[key])
|
models.setPreference(request.user, key, data[key])
|
||||||
return render_to_json_response(response)
|
return render_to_json_response(response)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue