You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2555 lines
73 KiB
2555 lines
73 KiB
#!/usr/bin/env python
|
|
# -*- coding: utf-8 -*-
|
|
|
|
"""
|
|
Stashr - Flask API Routing Definitions
|
|
"""
|
|
|
|
"""
|
|
MIT License
|
|
|
|
Copyright (c) 2020 Andrew Vanderbye
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
in the Software without restriction, including without limitation the rights
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
furnished to do so, subject to the following conditions:
|
|
|
|
The above copyright notice and this permission notice shall be included in all
|
|
copies or substantial portions of the Software.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
SOFTWARE.
|
|
"""
|
|
|
|
"""-------------------------------------------------------------------------------------------
|
|
-- IMPORTS
|
|
-------------------------------------------------------------------------------------------"""
|
|
|
|
import os, json, pathlib, io, urllib, datetime, signal
|
|
from zipfile import ZipFile
|
|
|
|
try:
|
|
from rarfile import RarFile
|
|
use_rar = True
|
|
except ImportError:
|
|
# print('RarFile not imported')
|
|
use_rar = False
|
|
|
|
try:
|
|
from tarfile import TarFile
|
|
use_tar = True
|
|
except ImportError:
|
|
# print('TarFile not imported')
|
|
use_tar = False
|
|
|
|
from natsort import natsorted
|
|
from operator import itemgetter, attrgetter
|
|
|
|
from validate import Validator
|
|
|
|
""" --- STASHR CORE IMPORTS --- """
|
|
from stashr import log, database, utils, paths, folders, naming, forms, tasks
|
|
|
|
from stashr.config import stashrconfig
|
|
from stashr.comicvine import cv
|
|
|
|
""" --- FLASK IMPORTS --- """
|
|
from flask import Blueprint, jsonify, request, redirect, url_for, send_file
|
|
|
|
""" --- FLASK EXTENSION IMPORTS --- """
|
|
from flask_login import current_user
|
|
|
|
""" --- SQL ALCHEMY OPERATORS --- """
|
|
from sqlalchemy import or_, and_
|
|
from sqlalchemy.orm import contains_eager
|
|
|
|
""" --- WERKZEUG --- """
|
|
from werkzeug.utils import secure_filename
|
|
from werkzeug.datastructures import ImmutableMultiDict
|
|
|
|
""" --- CREATE LOGGER --- """
|
|
logger = log.stashr_logger(__name__)
|
|
|
|
"""-------------------------------------------------------------------------------------------
|
|
-- API ROUTES
|
|
-------------------------------------------------------------------------------------------"""
|
|
|
|
api = Blueprint('api', __name__, template_folder='templates')
|
|
|
|
""" --- API CALLS PER METHOD --- """
|
|
# GET - api_key = request.args.get('api_key')
|
|
# POST - api_key = request.json['api_key']
|
|
# PUT - api_key = request.json['api_key']
|
|
# DELETE - api_key = request.json['api_key']
|
|
|
|
""" --- DEFINE CODE MESSAGES --- """
|
|
|
|
return_codes = {
|
|
'100': "Invalid API Key",
|
|
'200': "OK",
|
|
'201': "Created",
|
|
'400': "Bad Request",
|
|
'401': "Unauthorized",
|
|
'403': "Forbidden",
|
|
'404': "Not Found",
|
|
'405': "Method Not Allowed",
|
|
'406': "Not Acceptable",
|
|
'409': "Item Exists",
|
|
'500': "Server Error",
|
|
}
|
|
|
|
""" --- ALL VOLUMES --- """
|
|
|
|
# GET
|
|
@api.route('/volumes', methods=['GET'])
|
|
def api_get_all_volumes():
|
|
"""To Update Later
|
|
This is using docstrings for specifications.
|
|
---
|
|
tags:
|
|
- volumes
|
|
"""
|
|
|
|
user = current_user
|
|
|
|
if not user.is_authenticated:
|
|
api_key = request.args.get('api_key')
|
|
if api_key == "":
|
|
logger.debug('API Key not provided')
|
|
return jsonify(create_json_return('100'))
|
|
user = database.session \
|
|
.query(database.Users) \
|
|
.filter(database.Users.api_key == api_key) \
|
|
.first()
|
|
|
|
if user is None:
|
|
logger.debug('API Key not in database')
|
|
return jsonify(create_json_return('100'))
|
|
|
|
offset = request.args.get('offset') if request.args.get('offset') is not None else 0
|
|
limit = request.args.get('limit') if request.args.get('limit') is not None else 100
|
|
|
|
total_results = database.session \
|
|
.query(database.Volumes.volume_id) \
|
|
.count()
|
|
|
|
volumes = database.session \
|
|
.query(database.Volumes) \
|
|
.filter(database.Volumes.volume_age_rating <= user.rating_allowed) \
|
|
.order_by(database.Volumes.volume_sort_title) \
|
|
.offset(offset) \
|
|
.limit(limit) \
|
|
.distinct() \
|
|
.all()
|
|
|
|
data = database.VolumesSchema(many=True).dump(volumes)
|
|
return create_json_return('200', total_results=total_results, results=data)
|
|
|
|
# POST
|
|
|
|
""" --- SINGLE VOLUME --- """
|
|
|
|
# GET
|
|
@api.route('/volumes/<volume_id>', methods=['GET'])
|
|
def api_get_single_volume(volume_id):
|
|
"""To Update Later
|
|
This is using docstrings for specifications.
|
|
---
|
|
tags:
|
|
- volumes
|
|
"""
|
|
|
|
user = current_user
|
|
|
|
if not user.is_authenticated:
|
|
if "api_key" not in request.args:
|
|
return jsonify(create_json_return('100'))
|
|
api_key = request.args.get('api_key')
|
|
if api_key == "":
|
|
return jsonify(create_json_return('100'))
|
|
user = database.session \
|
|
.query(database.Users) \
|
|
.filter(database.Users.api_key == api_key) \
|
|
.first()
|
|
|
|
if user is None:
|
|
return jsonify(create_json_return('100'))
|
|
|
|
volume = database.session \
|
|
.query(database.Volumes) \
|
|
.filter(or_(database.Volumes.volume_id == volume_id,
|
|
database.Volumes.volume_slug == volume_id)) \
|
|
.filter(database.Volumes.volume_age_rating <= user.rating_allowed) \
|
|
.first()
|
|
|
|
if volume is None:
|
|
return jsonify(create_json_return('404'))
|
|
|
|
total_results = database.session \
|
|
.query(database.Volumes) \
|
|
.filter(or_(database.Volumes.volume_id == volume_id,
|
|
database.Volumes.volume_slug == volume_id)) \
|
|
.count()
|
|
|
|
data = database.VolumesSchema().dump(volume)
|
|
return create_json_return('200', results=data, total_results=total_results)
|
|
|
|
# POST
|
|
@api.route('/volumes/<volume_id>', methods=["POST"])
|
|
def api_post_single_volume(volume_id):
|
|
"""To Update Later
|
|
This is using docstrings for specifications.
|
|
---
|
|
tags:
|
|
- volumes
|
|
"""
|
|
|
|
user = current_user
|
|
|
|
if not user.is_authenticated:
|
|
if not request.json:
|
|
return jsonify(create_json_return('400'))
|
|
if "api_key" not in request.json:
|
|
return jsonify(create_json_return('400'))
|
|
if request.json['api_key'] == "":
|
|
return jsonify(create_json_return('100'))
|
|
|
|
user = database.session \
|
|
.query(database.Users) \
|
|
.filter(database.Users.api_key == request.json['api_key']) \
|
|
.first()
|
|
|
|
if user is None:
|
|
return jsonify(create_json_return('100'))
|
|
|
|
if not user.role == 'admin':
|
|
return jsonify(create_json_return('401'))
|
|
|
|
resource = database.session \
|
|
.query(database.Volumes) \
|
|
.filter(or_(database.Volumes.volume_id == volume_id,
|
|
database.Volumes.volume_slug == volume_id)) \
|
|
.first()
|
|
|
|
if resource is None:
|
|
utils.add_volume_to_library(volume_id)
|
|
return jsonify(create_json_return('200'))
|
|
|
|
utils.scrape_volume_issues(volume_id)
|
|
utils.refresh_single_volume(resource.volume_id)
|
|
|
|
return jsonify(create_json_return('200'))
|
|
|
|
# PUT
|
|
@api.route('/volumes/<volume_id>', methods=["PUT"])
|
|
def api_put_single_volume(volume_id):
|
|
"""To Update Later
|
|
This is using docstrings for specifications.
|
|
---
|
|
tags:
|
|
- volumes
|
|
"""
|
|
|
|
user = current_user
|
|
|
|
if not user.is_authenticated:
|
|
if not request.json:
|
|
return jsonify(create_json_return('400'))
|
|
if "api_key" not in request.json:
|
|
return jsonify(create_json_return('400'))
|
|
if request.json['api_key'] == "":
|
|
return jsonify(create_json_return('100'))
|
|
|
|
user = database.session \
|
|
.query(database.Users) \
|
|
.filter(database.Users.api_key == request.json['api_key']) \
|
|
.first()
|
|
|
|
if user is None:
|
|
return jsonify(create_json_return('100'))
|
|
|
|
volume = database.session \
|
|
.query(database.Volumes) \
|
|
.filter(or_(database.Volumes.volume_id == volume_id,
|
|
database.Volumes.volume_slug == volume_id),
|
|
database.Users.id == user.id) \
|
|
.first()
|
|
|
|
if volume is None:
|
|
return jsonify(create_json_return('404'))
|
|
|
|
"""
|
|
if len(volume.notes) == 0:
|
|
# utils.populate_user_notes(user.id, volume.volume_id)
|
|
pass
|
|
"""
|
|
|
|
allowed_keys = [
|
|
'volume_status',
|
|
'volume_age_rating',
|
|
'volume_note'
|
|
]
|
|
|
|
error = False
|
|
|
|
for key, value in request.json['data'].items():
|
|
if key not in allowed_keys:
|
|
error = True
|
|
break
|
|
"""
|
|
if key == 'volume_note':
|
|
print('updating note')
|
|
volume.notes[0].volume_note = value
|
|
"""
|
|
if user.role == 'admin':
|
|
setattr(volume, key, value)
|
|
|
|
if error:
|
|
return jsonify(create_json_return('400'))
|
|
|
|
database.session.merge(volume)
|
|
database.session.commit()
|
|
|
|
return jsonify(create_json_return('200'))
|
|
|
|
# DELETE
|
|
@api.route('/volumes/<volume_id>', methods=["DELETE"])
|
|
def api_delete_single_volume(volume_id):
|
|
"""To Update Later
|
|
This is using docstrings for specifications.
|
|
---
|
|
tags:
|
|
- volumes
|
|
"""
|
|
|
|
user = current_user
|
|
|
|
if not user.is_authenticated:
|
|
if not request.json:
|
|
return jsonify(create_json_return('400'))
|
|
if "api_key" not in request.json:
|
|
return jsonify(create_json_return('400'))
|
|
if request.json['api_key'] == "":
|
|
return jsonify(create_json_return('100'))
|
|
|
|
user = database.session \
|
|
.query(database.Users) \
|
|
.filter(database.Users.api_key == request.json['api_key']) \
|
|
.first()
|
|
|
|
if user is None:
|
|
return jsonify(create_json_return('100'))
|
|
|
|
if not user.role == 'admin':
|
|
return jsonify(create_json_return('100'))
|
|
|
|
resource = database.session \
|
|
.query(database.Volumes) \
|
|
.filter(or_(database.Volumes.volume_slug == volume_id,
|
|
database.Volumes.volume_id == volume_id)) \
|
|
.first()
|
|
|
|
if resource is None:
|
|
return jsonify(create_json_return('404'))
|
|
|
|
utils.delete_volume(resource.volume_id)
|
|
|
|
return jsonify(create_json_return('200'))
|
|
|
|
""" --- SINGLE VOLUME ALL ISSUES --- """
|
|
|
|
# GET
|
|
@api.route('/volumes/<volume_id>/issues', methods=['GET'])
|
|
def api_get_single_volume_all_issues(volume_id):
|
|
"""To Update Later
|
|
This is using docstrings for specifications.
|
|
---
|
|
tags:
|
|
- volumes
|
|
"""
|
|
|
|
user = current_user
|
|
|
|
if not user.is_authenticated:
|
|
if "api_key" not in request.args:
|
|
return jsonify(create_json_return('100'))
|
|
api_key = request.args.get('api_key')
|
|
if api_key == "":
|
|
return jsonify(create_json_return('100'))
|
|
user = database.session \
|
|
.query(database.Users) \
|
|
.filter(database.Users.api_key == api_key) \
|
|
.first()
|
|
|
|
if user is None:
|
|
return jsonify(create_json_return('100'))
|
|
|
|
offset = request.args.get('offset') if request.args.get('offset') is not None else 0
|
|
limit = request.args.get('limit') if request.args.get('limit') is not None else 100
|
|
|
|
volume = database.session \
|
|
.query(database.Volumes) \
|
|
.filter(or_(database.Volumes.volume_slug == volume_id,
|
|
database.Volumes.volume_id == volume_id)) \
|
|
.filter(database.Volumes.volume_age_rating <= user.rating_allowed) \
|
|
.first()
|
|
|
|
if volume is None:
|
|
return jsonify(create_json_return('409'))
|
|
|
|
total_issues = database.session \
|
|
.query(database.Issues.issue_id) \
|
|
.filter(database.Issues.issue_volume_id == volume.volume_id) \
|
|
.count()
|
|
|
|
if total_issues == 0:
|
|
utils.scrape_volume_issues(volume.volume_id)
|
|
# Return redirect
|
|
return redirect(url_for('api.api_get_single_volume_all_issues', volume_id=volume_id))
|
|
|
|
ret_issues = (
|
|
database.session.query(database.Issues)
|
|
.join(database.Issues.read_status)
|
|
.options(contains_eager(database.Issues.read_status))
|
|
.join(database.Issues.owned_status)
|
|
.options(contains_eager(database.Issues.owned_status))
|
|
.filter(database.Issues.issue_volume_id == volume_id)
|
|
.filter(database.ReadIssues.read_user_id == user.id)
|
|
.filter(database.OwnedIssues.owned_user_id == user.id)
|
|
).all()
|
|
|
|
if len(ret_issues) != total_issues:
|
|
logger.debug('NEED TO ADD A DAMN READ STATUS')
|
|
utils.populate_statuses(user.id, volume_id, ret_issues)
|
|
# utils.populate_read_status(user.id, volume_id, ret_issues)
|
|
# utils.populate_owned_status(user.id, volume, ret_issues)
|
|
return redirect(url_for('api.api_get_single_volume_all_issues', volume_id=volume_id))
|
|
|
|
issues = (
|
|
database.session.query(database.Issues)
|
|
.join(database.Issues.read_status)
|
|
.options(contains_eager(database.Issues.read_status))
|
|
.join(database.Issues.owned_status)
|
|
.options(contains_eager(database.Issues.owned_status))
|
|
.filter(database.Issues.issue_volume_id == volume_id)
|
|
.filter(database.ReadIssues.read_user_id == user.id)
|
|
.filter(database.OwnedIssues.owned_user_id == user.id)
|
|
).order_by(database.Issues.issue_id.asc()).distinct().offset(offset).limit(limit).all()
|
|
|
|
data = database.IssuesSchema(many=True).dump(issues)
|
|
|
|
return create_json_return('200', results=data, total_results=total_issues)
|
|
|
|
""" --- SINGLE VOLUME SINGLE ISSUE --- """
|
|
|
|
# GET
|
|
|
|
# POST
|
|
|
|
# PUT
|
|
|
|
# DELETE
|
|
|
|
""" --- SINGLE VOLUME SINGLE ISSUE IMAGE --- """
|
|
|
|
# GET
|
|
|
|
""" --- ALL ISSUES --- """
|
|
|
|
# GET
|
|
|
|
""" --- SINGLE ISSUE --- """
|
|
|
|
# GET
|
|
@api.route('/issues/<issue_id>', methods=["GET"])
|
|
def api_get_single_issue(issue_id):
|
|
"""To Update Later
|
|
This is using docstrings for specifications.
|
|
---
|
|
tags:
|
|
- issues
|
|
"""
|
|
|
|
user = current_user
|
|
|
|
if not user.is_authenticated:
|
|
api_key = request.args.get('api_key')
|
|
if api_key == "":
|
|
return jsonify(create_json_return('100'))
|
|
user = database.session \
|
|
.query(database.Users) \
|
|
.filter(database.Users.api_key == api_key) \
|
|
.first()
|
|
|
|
if user is None:
|
|
return jsonify(create_json_return('100'))
|
|
|
|
issue = database.session \
|
|
.query(database.Issues) \
|
|
.filter(database.Issues.issue_id == issue_id) \
|
|
.first()
|
|
|
|
volumes_folder = stashrconfig['DIRECTORY']['comics']
|
|
volume_folder = issue.volume.directory.directory_path
|
|
issue_file = issue.issue_file_path
|
|
|
|
issue_file = os.path.join(
|
|
paths.base_path,
|
|
volumes_folder,
|
|
volume_folder,
|
|
issue_file
|
|
)
|
|
|
|
if not os.path.isfile(issue_file):
|
|
return jsonify(create_json_return('404'))
|
|
|
|
filetype = pathlib.Path(issue_file).suffix
|
|
|
|
if filetype == '.cbz':
|
|
issue_file = ZipFile(issue_file)
|
|
elif filetype == '.cbr' and use_rar:
|
|
issue_file = RarFile(issue_file)
|
|
else:
|
|
return(jsonify(create_json_return('500')))
|
|
|
|
images = []
|
|
|
|
for name in issue_file.namelist():
|
|
if pathlib.Path(name).suffix == '.jpg':
|
|
image = {}
|
|
image['id'] = issue_file.namelist().index(name)
|
|
image['path'] = urllib.parse.quote(name)
|
|
images.append(image)
|
|
|
|
return jsonify(create_json_return('200', results=natsorted(images, key=lambda image: image['path'])))
|
|
|
|
# POST
|
|
@api.route('/issues/<issue_id>', methods=["POST"])
|
|
def api_post_single_issue(issue_id):
|
|
"""To Update Later
|
|
This is using docstrings for specifications.
|
|
---
|
|
tags:
|
|
- issues
|
|
"""
|
|
|
|
user = current_user
|
|
|
|
if not user.is_authenticated:
|
|
if not request.json:
|
|
return jsonify(create_json_return('400'))
|
|
if "api_key" not in request.json:
|
|
return jsonify(create_json_return('400'))
|
|
if request.json['api_key'] == "":
|
|
return jsonify(create_json_return('100'))
|
|
|
|
user = database.session \
|
|
.query(database.Users) \
|
|
.filter(database.Users.api_key == request.json['api_key']) \
|
|
.first()
|
|
|
|
if user is None:
|
|
return jsonify(create_json_return('100'))
|
|
|
|
if user.role != 'admin':
|
|
return jsonify(create_json_return('401'))
|
|
|
|
if 'file' not in request.files:
|
|
return jsonify(create_json_return('400'))
|
|
|
|
issue = database.session \
|
|
.query(database.Issues) \
|
|
.filter(database.Issues.issue_id == issue_id) \
|
|
.first()
|
|
|
|
if issue is None:
|
|
return jsonify(create_json_return('404'))
|
|
|
|
if issue.issue_file_path is not None:
|
|
existing_file = os.path.join(
|
|
folders.StashrFolders().comic_folder(),
|
|
issue.volume.directory.directory_path,
|
|
issue.issue_file_path
|
|
)
|
|
if os.path.isfile(existing_file):
|
|
return jsonify(create_json_return('409'))
|
|
|
|
file = request.files['file']
|
|
|
|
file_path = os.path.join(
|
|
folders.StashrFolders().comic_folder(),
|
|
issue.volume.directory.directory_path,
|
|
f'{naming.file_name_by_db(issue)}{pathlib.Path(file.filename).suffix}'
|
|
)
|
|
|
|
volume_path = os.path.join(
|
|
folders.StashrFolders().comic_folder(),
|
|
issue.volume.volume_path,
|
|
)
|
|
|
|
if not os.path.exists(volume_path):
|
|
os.makedirs(volume_path)
|
|
|
|
file.save(file_path)
|
|
|
|
issue.issue_file_path = pathlib.Path(file_path).name
|
|
issue.issue_file_status = True
|
|
issue.issue_file_date = datetime.date.today()
|
|
|
|
database.session.commit()
|
|
|
|
utils.refresh_single_volume(issue.volume.volume_id)
|
|
|
|
return jsonify(create_json_return('200'))
|
|
|
|
# PUT
|
|
@api.route('/issues/<issue_id>', methods=["PUT"])
|
|
def api_put_single_issue(issue_id):
|
|
"""To Update Later
|
|
This is using docstrings for specifications.
|
|
---
|
|
tags:
|
|
- issues
|
|
"""
|
|
|
|
user = current_user
|
|
|
|
if not user.is_authenticated:
|
|
if not request.json:
|
|
return jsonify(create_json_return('400'))
|
|
if "api_key" not in request.json:
|
|
return jsonify(create_json_return('400'))
|
|
if request.json['api_key'] == "":
|
|
return jsonify(create_json_return('100'))
|
|
|
|
user = database.session \
|
|
.query(database.Users) \
|
|
.filter(database.Users.api_key == request.json['api_key']) \
|
|
.first()
|
|
|
|
if user is None:
|
|
return jsonify(create_json_return('100'))
|
|
|
|
issue = (
|
|
database.session.query(database.Issues)
|
|
.join(database.Issues.read_status)
|
|
.options(contains_eager(database.Issues.read_status))
|
|
.join(database.Issues.owned_status)
|
|
.options(contains_eager(database.Issues.owned_status))
|
|
.filter(database.Issues.issue_id == issue_id)
|
|
.filter(database.ReadIssues.read_user_id == user.id)
|
|
.filter(database.OwnedIssues.owned_user_id == user.id)
|
|
).first()
|
|
|
|
if issue is None:
|
|
return jsonify(create_json_return('404'))
|
|
|
|
allowed_keys = [
|
|
'read_status',
|
|
'owned_status'
|
|
]
|
|
|
|
error = False
|
|
|
|
for key, value in request.json['data'].items():
|
|
if key not in allowed_keys:
|
|
error = True
|
|
break
|
|
if key == 'read_status':
|
|
issue.read_status[0].read_status = value
|
|
continue
|
|
if key == 'owned_status':
|
|
issue.owned_status[0].owned_status = value
|
|
continue
|
|
setattr(issue, key, value)
|
|
|
|
if error:
|
|
return jsonify(create_json_return('400'))
|
|
|
|
database.session.merge(issue)
|
|
database.session.commit()
|
|
return jsonify(create_json_return('200'))
|
|
|
|
# DELETE
|
|
@api.route('/issues/<issue_id>', methods=["DELETE"])
|
|
def api_delete_single_issue(issue_id):
|
|
"""To Update Later
|
|
This is using docstrings for specifications.
|
|
---
|
|
tags:
|
|
- issues
|
|
"""
|
|
|
|
user = current_user
|
|
|
|
if not user.is_authenticated:
|
|
if not request.json:
|
|
return jsonify(create_json_return('400'))
|
|
if "api_key" not in request.json:
|
|
return jsonify(create_json_return('400'))
|
|
if request.json['api_key'] == "":
|
|
return jsonify(create_json_return('100'))
|
|
|
|
user = database.session \
|
|
.query(database.Users) \
|
|
.filter(database.Users.api_key == request.json['api_key']) \
|
|
.first()
|
|
|
|
if user is None:
|
|
return jsonify(create_json_return('100'))
|
|
|
|
if user.role != 'admin':
|
|
return jsonify(create_json_return('401'))
|
|
|
|
issue = database.session \
|
|
.query(database.Issues) \
|
|
.filter(database.Issues.issue_id == issue_id) \
|
|
.first()
|
|
|
|
if issue is None:
|
|
return jsonify(create_json_return('404'))
|
|
|
|
utils.delete_comic_file(issue_id)
|
|
|
|
utils.refresh_single_volume(issue.volume.volume_id)
|
|
|
|
return create_json_return('200')
|
|
|
|
""" --- SINGLE ISSUE IMAGE --- """
|
|
|
|
# GET
|
|
@api.route('/issues/<issue_id>/<path:image_file>', methods=["GET"])
|
|
def api_single_issue_image(issue_id, image_file):
|
|
"""To Update Later
|
|
This is using docstrings for specifications.
|
|
---
|
|
tags:
|
|
- issues
|
|
"""
|
|
|
|
user = current_user
|
|
|
|
if not user.is_authenticated:
|
|
api_key = request.args.get('api_key')
|
|
if api_key == "":
|
|
return jsonify(create_json_return('100'))
|
|
user = database.session \
|
|
.query(database.Users) \
|
|
.filter(database.Users.api_key == api_key) \
|
|
.first()
|
|
|
|
if user is None:
|
|
return jsonify(create_json_return('100'))
|
|
|
|
issue = database.session \
|
|
.query(database.Issues) \
|
|
.filter(database.Issues.issue_id == issue_id) \
|
|
.first()
|
|
|
|
volumes_folder = volume_folder = stashrconfig['DIRECTORY']['comics']
|
|
volume_folder = issue.volume.directory.directory_path
|
|
issue_file = issue.issue_file_path
|
|
|
|
issue_file = os.path.join(
|
|
paths.base_path,
|
|
volumes_folder,
|
|
volume_folder,
|
|
issue_file
|
|
)
|
|
|
|
if not os.path.isfile(issue_file):
|
|
return jsonify(create_json_return('404'))
|
|
|
|
print(issue_file)
|
|
|
|
filetype = pathlib.Path(issue_file).suffix
|
|
|
|
if filetype == '.cbz':
|
|
issue_file = ZipFile(issue_file)
|
|
elif filetype == '.cbr' and use_rar:
|
|
issue_file = RarFile(issue_file)
|
|
else:
|
|
return(jsonify(create_json_return('500')))
|
|
|
|
image_data = issue_file.read(image_file)
|
|
issue_file.close()
|
|
|
|
return send_file(
|
|
io.BytesIO(image_data),
|
|
attachment_filename=image_file,
|
|
mimetype='image/jpg'
|
|
)
|
|
|
|
""" --- ALL PUBLISHERS --- """
|
|
|
|
# GET
|
|
@api.route('/publishers', methods=["GET"])
|
|
def api_get_all_publishers():
|
|
"""To Update Later
|
|
This is using docstrings for specifications.
|
|
---
|
|
tags:
|
|
- publishers
|
|
"""
|
|
|
|
user = current_user
|
|
|
|
if not user.is_authenticated:
|
|
if "api_key" not in request.args:
|
|
return jsonify(create_json_return('100'))
|
|
api_key = request.args.get('api_key')
|
|
if api_key == "":
|
|
return jsonify(create_json_return('100'))
|
|
|
|
user = database.session \
|
|
.query(database.Users) \
|
|
.filter(database.Users.api_key == api_key) \
|
|
.first()
|
|
|
|
if user is None:
|
|
return jsonify(create_json_return('100'))
|
|
|
|
offset = request.args.get('offset') if request.args.get('offset') is not None else 0
|
|
limit = request.args.get('limit') if request.args.get('limit') is not None else 100
|
|
|
|
total_results = database.session \
|
|
.query(database.Publishers) \
|
|
.count()
|
|
|
|
publishers = database.session \
|
|
.query(database.Publishers) \
|
|
.order_by() \
|
|
.offset(offset) \
|
|
.limit(limit) \
|
|
.distinct() \
|
|
.all()
|
|
|
|
data = database.PublishersSchema(many=True).dump(publishers)
|
|
return create_json_return('200', results=data, total_results=total_results)
|
|
|
|
# POST
|
|
@api.route('/publishers', methods=["POST"])
|
|
def api_post_all_publishers():
|
|
"""To Update Later
|
|
This is using docstrings for specifications.
|
|
---
|
|
tags:
|
|
- publishers
|
|
"""
|
|
|
|
user = current_user
|
|
|
|
if not user.is_authenticated:
|
|
if not request.json:
|
|
return jsonify(create_json_return('400'))
|
|
if "api_key" not in request.json:
|
|
return jsonify(create_json_return('400'))
|
|
if request.json['api_key'] == "":
|
|
return jsonify(create_json_return('100'))
|
|
|
|
user = database.session \
|
|
.query(database.Users) \
|
|
.filter(database.Users.api_key == request.json['api_key']) \
|
|
.first()
|
|
|
|
if user is None:
|
|
return jsonify(create_json_return('100'))
|
|
|
|
allowed_keys = [
|
|
'publisher_id',
|
|
]
|
|
|
|
for key, value in request.json['data'].items():
|
|
if key not in allowed_keys:
|
|
return jsonify(create_json_return('400'))
|
|
if key == 'publisher_id':
|
|
utils.add_publisher(value)
|
|
return jsonify(create_json_return('201'))
|
|
|
|
""" --- SINGLE PUBLISHER --- """
|
|
|
|
# GET
|
|
@api.route('/publishers/<publisher_id>', methods=["GET"])
|
|
def api_get_single_publisher(publisher_id):
|
|
"""To Update Later
|
|
This is using docstrings for specifications.
|
|
---
|
|
tags:
|
|
- publishers
|
|
"""
|
|
|
|
user = current_user
|
|
|
|
if not user.is_authenticated:
|
|
api_key = request.args.get('api_key')
|
|
if api_key == "":
|
|
return jsonify(create_json_return('100'))
|
|
user = database.session \
|
|
.query(database.Users) \
|
|
.filter(database.Users.api_key == api_key) \
|
|
.first()
|
|
|
|
if user is None:
|
|
return jsonify(create_json_return('100'))
|
|
|
|
total_results = database.session \
|
|
.query(database.Publishers) \
|
|
.filter(database.Publishers.publisher_id == publisher_id) \
|
|
.count()
|
|
|
|
publisher = database.session \
|
|
.query(database.Publishers) \
|
|
.filter(database.Publishers.publisher_id == publisher_id) \
|
|
.first()
|
|
|
|
data = database.PublishersSchema().dump(publisher)
|
|
return create_json_return('200', total_results=total_results, results=data)
|
|
|
|
# POST
|
|
|
|
""" --- SINGLE PUBLISHER ALL VOLUMES --- """
|
|
|
|
# GET
|
|
@api.route('/publishers/<publisher_id>/volumes', methods=["GET"])
|
|
def api_get_single_publisher_volumes(publisher_id):
|
|
"""To Update Later
|
|
This is using docstrings for specifications.
|
|
---
|
|
tags:
|
|
- publishers
|
|
"""
|
|
|
|
user = current_user
|
|
|
|
if not user.is_authenticated:
|
|
api_key = request.args.get('api_key')
|
|
if api_key == "":
|
|
return jsonify(create_json_return('100'))
|
|
user = database.session \
|
|
.query(database.Users) \
|
|
.filter(database.Users.api_key == api_key) \
|
|
.first()
|
|
|
|
if user is None:
|
|
return jsonify(create_json_return('100'))
|
|
|
|
offset = request.args.get('offset') if request.args.get('offset') is not None else 0
|
|
limit = request.args.get('limit') if request.args.get('limit') is not None else 100
|
|
|
|
total_results = database.session \
|
|
.query(database.Volumes) \
|
|
.filter(database.Volumes.volume_publisher_id == publisher_id) \
|
|
.filter(database.Volumes.volume_age_rating <= user.rating_allowed) \
|
|
.count()
|
|
|
|
publisher_volumes = database.session \
|
|
.query(database.Volumes) \
|
|
.filter(database.Volumes.volume_publisher_id == publisher_id) \
|
|
.filter(database.Volumes.volume_age_rating <= user.rating_allowed) \
|
|
.order_by(database.Volumes.volume_sort_title) \
|
|
.offset(offset) \
|
|
.limit(limit) \
|
|
.distinct() \
|
|
.all()
|
|
|
|
data = database.VolumesSchema(many=True).dump(publisher_volumes)
|
|
return create_json_return('200', total_results=total_results, results=data)
|
|
|
|
""" --- NEW RELEASES --- """
|
|
|
|
# GET
|
|
@api.route('/newreleases', methods=["GET"])
|
|
def api_get_new_releases():
|
|
"""To Update Later
|
|
This is using docstrings for specifications.
|
|
---
|
|
tags:
|
|
- newreleases
|
|
"""
|
|
|
|
user = current_user
|
|
|
|
if not user.is_authenticated:
|
|
api_key = request.args.get('api_key')
|
|
if api_key == "":
|
|
return jsonify(create_json_return('100'))
|
|
user = database.session \
|
|
.query(database.Users) \
|
|
.filter(database.Users.api_key == api_key) \
|
|
.first()
|
|
|
|
if user is None:
|
|
return jsonify(create_json_return('100'))
|
|
|
|
offset = request.args.get('offset') if request.args.get('offset') is not None else 0
|
|
limit = request.args.get('limit') if request.args.get('limit') is not None else 100
|
|
|
|
total_results = database.session \
|
|
.query(database.NewReleases) \
|
|
.count()
|
|
|
|
releases = database.session \
|
|
.query(database.NewReleases) \
|
|
.order_by(database.NewReleases.new_release_id) \
|
|
.offset(offset) \
|
|
.limit(limit) \
|
|
.distinct() \
|
|
.all()
|
|
|
|
data = database.NewReleasesSchema(many=True).dump(releases)
|
|
return create_json_return('200', results=data, total_results=total_results)
|
|
|
|
# POST
|
|
@api.route('/newreleases', methods=["POST"])
|
|
def api_post_new_releases():
|
|
"""To Update Later
|
|
This is using docstrings for specifications.
|
|
---
|
|
tags:
|
|
- newreleases
|
|
"""
|
|
|
|
user = current_user
|
|
|
|
if not user.is_authenticated:
|
|
if not request.json:
|
|
return jsonify(create_json_return('400'))
|
|
if "api_key" not in request.json:
|
|
return jsonify(create_json_return('400'))
|
|
if request.json['api_key'] == "":
|
|
return jsonify(create_json_return('100'))
|
|
user = database.session \
|
|
.query(database.Users) \
|
|
.filter(database.Users.api_key == request.json['api_key']) \
|
|
.first()
|
|
|
|
if user is None:
|
|
return jsonify(create_json_return('100'))
|
|
|
|
utils.update_release_list()
|
|
|
|
return jsonify(create_json_return('200'))
|
|
|
|
""" --- READING LIST --- """
|
|
|
|
# GET
|
|
@api.route('/readinglist', methods=["GET"])
|
|
def api_get_reading_list():
|
|
"""To Update Later
|
|
This is using docstrings for specifications.
|
|
---
|
|
tags:
|
|
- readinglist
|
|
"""
|
|
|
|
user = current_user
|
|
|
|
if not user.is_authenticated:
|
|
if "api_key" not in request.args:
|
|
return jsonify(create_json_return('100'))
|
|
api_key = request.args.get('api_key')
|
|
if api_key == "":
|
|
return jsonify(create_json_return('100'))
|
|
user = database.session \
|
|
.query(database.Users) \
|
|
.filter(database.Users.api_key == api_key) \
|
|
.first()
|
|
|
|
if user is None:
|
|
return jsonify(create_json_return('100'))
|
|
|
|
offset = request.args.get('offset') if request.args.get('offset') is not None else 0
|
|
limit = request.args.get('limit') if request.args.get('limit') is not None else 100
|
|
|
|
total_results = database.session \
|
|
.query(database.ReadingLists) \
|
|
.filter(database.ReadingLists.reading_list_user_id == user.id) \
|
|
.count()
|
|
|
|
issues = (
|
|
database.session.query(database.Issues)
|
|
.join(database.Issues.readinglist)
|
|
.options(contains_eager(database.Issues.readinglist))
|
|
.filter(database.ReadingLists.reading_list_user_id == user.id)
|
|
.join(database.Issues.read_status)
|
|
.options(contains_eager(database.Issues.read_status))
|
|
.filter(database.ReadIssues.read_user_id == user.id)
|
|
.join(database.Issues.owned_status)
|
|
.options(contains_eager(database.Issues.owned_status))
|
|
.filter(database.OwnedIssues.owned_user_id == user.id)
|
|
).order_by(database.ReadingLists.reading_list_position.asc()).distinct().offset(offset).limit(limit).all()
|
|
|
|
# data = database.ReadingListsSchema(many=True).dump(readinglist)
|
|
data = database.IssuesSchema(many=True).dump(issues)
|
|
|
|
return create_json_return('200', results=data, total_results=total_results)
|
|
|
|
# POST
|
|
@api.route('/readinglist', methods=["POST"])
|
|
def api_post_reading_list():
|
|
"""To Update Later
|
|
This is using docstrings for specifications.
|
|
---
|
|
tags:
|
|
- readinglist
|
|
"""
|
|
|
|
user = current_user
|
|
|
|
if not user.is_authenticated:
|
|
if not request.json:
|
|
return jsonify(create_json_return('400'))
|
|
if "api_key" not in request.json:
|
|
return jsonify(create_json_return('400'))
|
|
if request.json['api_key'] == "":
|
|
return jsonify(create_json_return('100'))
|
|
|
|
user = database.session \
|
|
.query(database.Users) \
|
|
.filter(database.Users.api_key == request.json['api_key']) \
|
|
.first()
|
|
|
|
if user is None:
|
|
return jsonify(create_json_return('100'))
|
|
|
|
issue_id = request.json['issue_id']
|
|
|
|
current_list = database.session \
|
|
.query(database.ReadingLists) \
|
|
.filter(database.ReadingLists.reading_list_user_id == user.id) \
|
|
.all()
|
|
|
|
existing_issue = database.session \
|
|
.query(database.ReadingLists) \
|
|
.filter(database.ReadingLists.reading_list_user_id == user.id,
|
|
database.ReadingLists.reading_list_issue_id == issue_id) \
|
|
.first()
|
|
|
|
if existing_issue is not None:
|
|
return jsonify(create_json_return('409'))
|
|
|
|
new_entry = database.ReadingLists(
|
|
reading_list_user_id = user.id,
|
|
reading_list_issue_id = issue_id,
|
|
reading_list_position = len(current_list)+1
|
|
)
|
|
|
|
database.session.add(new_entry)
|
|
database.session.commit()
|
|
|
|
return jsonify(create_json_return('200'))
|
|
|
|
# PUT
|
|
@api.route('/readinglist', methods=["PUT"])
|
|
def api_put_reading_list():
|
|
"""To Update Later
|
|
This is using docstrings for specifications.
|
|
---
|
|
tags:
|
|
- readinglist
|
|
"""
|
|
|
|
user = current_user
|
|
|
|
if not user.is_authenticated:
|
|
if not request.json:
|
|
return jsonify(create_json_return('400'))
|
|
if "api_key" not in request.json:
|
|
return jsonify(create_json_return('400'))
|
|
if request.json['api_key'] == "":
|
|
return jsonify(create_json_return('100'))
|
|
|
|
user = database.session \
|
|
.query(database.Users) \
|
|
.filter(database.Users.api_key == request.json['api_key']) \
|
|
.first()
|
|
|
|
if user is None:
|
|
return jsonify(create_json_return('100'))
|
|
|
|
allowed_keys = [
|
|
'old_index',
|
|
'new_index'
|
|
]
|
|
|
|
for key, value in request.json['data'].items():
|
|
if key not in allowed_keys:
|
|
return jsonify(create_json_return('400'))
|
|
|
|
|
|
reading_list = database.session \
|
|
.query(database.ReadingLists) \
|
|
.filter(database.ReadingLists.reading_list_user_id == user.id) \
|
|
.order_by(database.ReadingLists.reading_list_position) \
|
|
.all()
|
|
|
|
reading_list.insert(request.json['data']['new_index'], reading_list.pop(request.json['data']['old_index']))
|
|
|
|
for item in reading_list:
|
|
item.reading_list_position = reading_list.index(item)
|
|
|
|
database.session.commit()
|
|
|
|
return jsonify(create_json_return('200'))
|
|
|
|
# DELETE
|
|
@api.route('/readinglist', methods=["DELETE"])
|
|
def api_delete_reading_list():
|
|
"""To Update Later
|
|
This is using docstrings for specifications.
|
|
---
|
|
tags:
|
|
- readinglist
|
|
"""
|
|
|
|
user = current_user
|
|
|
|
if not user.is_authenticated:
|
|
if not request.json:
|
|
return jsonify(create_json_return('400'))
|
|
if "api_key" not in request.json:
|
|
return jsonify(create_json_return('400'))
|
|
if request.json['api_key'] == "":
|
|
return jsonify(create_json_return('100'))
|
|
|
|
user = database.session \
|
|
.query(database.Users) \
|
|
.filter(database.Users.api_key == request.json['api_key']) \
|
|
.first()
|
|
|
|
if user is None:
|
|
return jsonify(create_json_return('100'))
|
|
|
|
database.session \
|
|
.query(database.ReadingLists) \
|
|
.filter(database.ReadingLists.reading_list_user_id == user.id) \
|
|
.delete()
|
|
|
|
return jsonify(create_json_return('200'))
|
|
|
|
""" --- READING LIST SINGLE ISSUE --- """
|
|
|
|
# DELETE
|
|
@api.route('/readinglist/<issue_id>', methods=["DELETE"])
|
|
def api_delete_reading_list_single(issue_id):
|
|
"""To Update Later
|
|
This is using docstrings for specifications.
|
|
---
|
|
tags:
|
|
- readinglist
|
|
"""
|
|
|
|
user = current_user
|
|
|
|
if not user.is_authenticated:
|
|
if not request.json:
|
|
return jsonify(create_json_return('400'))
|
|
if "api_key" not in request.json:
|
|
return jsonify(create_json_return('400'))
|
|
if request.json['api_key'] == "":
|
|
return jsonify(create_json_return('100'))
|
|
|
|
user = database.session \
|
|
.query(database.Users) \
|
|
.filter(database.Users.api_key == request.json['api_key']) \
|
|
.first()
|
|
|
|
if user is None:
|
|
return jsonify(create_json_return('100'))
|
|
|
|
check_issue = database.session \
|
|
.query(database.ReadingLists) \
|
|
.filter(database.ReadingLists.reading_list_user_id == user.id,
|
|
database.ReadingLists.reading_list_issue_id == issue_id) \
|
|
.first()
|
|
|
|
if check_issue is None:
|
|
return jsonify(create_json_return('404'))
|
|
|
|
database.session \
|
|
.query(database.ReadingLists) \
|
|
.filter(database.ReadingLists.reading_list_user_id == user.id,
|
|
database.ReadingLists.reading_list_issue_id == issue_id) \
|
|
.delete()
|
|
|
|
database.session.commit()
|
|
|
|
# TODO: Update order numbers on reading list after the removal of an issue
|
|
|
|
return jsonify(create_json_return('200'))
|
|
|
|
""" --- ALL COLLECTIONS --- """
|
|
|
|
# GET
|
|
@api.route('/collections', methods=["GET"])
|
|
def api_get_all_collections():
|
|
"""To Update Later
|
|
This is using docstrings for specifications.
|
|
---
|
|
tags:
|
|
- collections
|
|
"""
|
|
|
|
user = current_user
|
|
|
|
if not user.is_authenticated:
|
|
if "api_key" not in request.args:
|
|
return jsonify(create_json_return('100'))
|
|
api_key = request.args.get('api_key')
|
|
if api_key == "":
|
|
return jsonify(create_json_return('100'))
|
|
user = database.session \
|
|
.query(database.Users) \
|
|
.filter(database.Users.api_key == api_key) \
|
|
.first()
|
|
|
|
if user is None:
|
|
return jsonify(create_json_return('100'))
|
|
|
|
offset = request.args.get('offset') if request.args.get('offset') is not None else 0
|
|
limit = request.args.get('limit') if request.args.get('limit') is not None else 100
|
|
|
|
total_results = database.session \
|
|
.query(database.Collections) \
|
|
.filter(database.Collections.collection_user_id == user.id) \
|
|
.count()
|
|
|
|
collections = database.session \
|
|
.query(database.Collections) \
|
|
.filter(or_(database.Collections.collection_user_id == user.id,
|
|
database.Collections.collection_public == 1)) \
|
|
.order_by(database.Collections.collection_id) \
|
|
.offset(offset) \
|
|
.limit(limit) \
|
|
.distinct() \
|
|
.all()
|
|
|
|
data = database.CollectionsSchema(many=True).dump(collections)
|
|
return create_json_return('200', results=data, total_results=total_results)
|
|
|
|
# POST
|
|
@api.route('/collections', methods=["POST"])
|
|
def api_post_all_collections():
|
|
"""To Update Later
|
|
This is using docstrings for specifications.
|
|
---
|
|
tags:
|
|
- collections
|
|
"""
|
|
|
|
user = current_user
|
|
|
|
if not user.is_authenticated:
|
|
if not request.json:
|
|
return jsonify(create_json_return('400'))
|
|
if "api_key" not in request.json:
|
|
return jsonify(create_json_return('400'))
|
|
if request.json['api_key'] == "":
|
|
return jsonify(create_json_return('100'))
|
|
|
|
user = database.session \
|
|
.query(database.Users) \
|
|
.filter(database.Users.api_key == request.json['api_key']) \
|
|
.first()
|
|
|
|
if user is None:
|
|
return jsonify(create_json_return('100'))
|
|
|
|
collection_id = utils.create_new_collection(user.id, request.json['data']['collection_name'])
|
|
if request.json['data']['issue_id']:
|
|
utils.add_issue_to_collection(collection_id, request.json['data']['issue_id'])
|
|
|
|
return jsonify(create_json_return('200'))
|
|
|
|
""" --- SINGLE COLLECTION --- """
|
|
|
|
# GET
|
|
@api.route('/collections/<collection_slug>', methods=["GET"])
|
|
def api_get_single_collection(collection_slug):
|
|
"""To Update Later
|
|
This is using docstrings for specifications.
|
|
---
|
|
tags:
|
|
- collections
|
|
"""
|
|
|
|
user = current_user
|
|
|
|
if not user.is_authenticated:
|
|
api_key = request.args.get('api_key')
|
|
if api_key == "":
|
|
return jsonify(create_json_return('100'))
|
|
user = database.session \
|
|
.query(database.Users) \
|
|
.filter(database.Users.api_key == api_key) \
|
|
.first()
|
|
|
|
if user is None:
|
|
return jsonify(create_json_return('100'))
|
|
|
|
collection = database.session \
|
|
.query(database.Collections) \
|
|
.filter(database.Collections.collection_slug == collection_slug) \
|
|
.first()
|
|
|
|
if collection.collection_user_id != user.id and collection.collection_public == 'false':
|
|
return create_json_return('409')
|
|
|
|
total_results = database.session \
|
|
.query(database.Collections) \
|
|
.filter(database.Collections.collection_slug == collection_slug) \
|
|
.count()
|
|
|
|
data = database.CollectionsSchema().dump(collection)
|
|
return create_json_return('200', results=data, total_results=total_results)
|
|
|
|
# POST
|
|
@api.route('/collections/<collection_slug>', methods=["POST"])
|
|
def api_post_single_collection(collection_slug):
|
|
"""To Update Later
|
|
This is using docstrings for specifications.
|
|
---
|
|
tags:
|
|
- collections
|
|
"""
|
|
|
|
user = current_user
|
|
|
|
if not user.is_authenticated:
|
|
if not request.json:
|
|
return jsonify(create_json_return('400'))
|
|
if "api_key" not in request.json:
|
|
return jsonify(create_json_return('400'))
|
|
if request.json['api_key'] == "":
|
|
return jsonify(create_json_return('100'))
|
|
|
|
user = database.session \
|
|
.query(database.Users) \
|
|
.filter(database.Users.api_key == request.json['api_key']) \
|
|
.first()
|
|
|
|
if user is None:
|
|
return jsonify(create_json_return('100'))
|
|
|
|
collection = database.session \
|
|
.query(database.Collections) \
|
|
.filter(or_(database.Collections.collection_id == collection_slug,
|
|
database.Collections.collection_slug == collection_slug)) \
|
|
.first()
|
|
|
|
if collection is None:
|
|
return jsonify(create_json_return('404'))
|
|
|
|
if collection.collection_user_id != user.id:
|
|
return jsonify(create_json_return('401'))
|
|
|
|
try:
|
|
issue_id = request.json['data']['issue_id']
|
|
|
|
check_issue = database.session \
|
|
.query(database.CollectionLinks) \
|
|
.filter(database.CollectionLinks.collection_link_collection_id == collection_slug,
|
|
database.CollectionLinks.collection_link_issue_id == issue_id) \
|
|
.first()
|
|
|
|
if check_issue is not None:
|
|
return jsonify(create_json_return('409'))
|
|
|
|
utils.add_issue_to_collection(collection_slug, issue_id)
|
|
except:
|
|
return jsonify(create_json_return('400'))
|
|
finally:
|
|
return jsonify(create_json_return('200'))
|
|
|
|
# PUT
|
|
@api.route('/collections/<collection_slug>', methods=["PUT"])
|
|
def api_put_single_collection(collection_slug):
|
|
"""To Update Later
|
|
This is using docstrings for specifications.
|
|
---
|
|
tags:
|
|
- collections
|
|
"""
|
|
|
|
user = current_user
|
|
|
|
if not user.is_authenticated:
|
|
if not request.json:
|
|
return jsonify(create_json_return('400'))
|
|
if "api_key" not in request.json:
|
|
return jsonify(create_json_return('400'))
|
|
if request.json['api_key'] == "":
|
|
return jsonify(create_json_return('100'))
|
|
|
|
user = database.session \
|
|
.query(database.Users) \
|
|
.filter(database.Users.api_key == request.json['api_key']) \
|
|
.first()
|
|
|
|
if user is None:
|
|
return jsonify(create_json_return('100'))
|
|
|
|
collection = database.session \
|
|
.query(database.Collections) \
|
|
.filter(or_(database.Collections.collection_id == collection_slug,
|
|
database.Collections.collection_slug == collection_slug)) \
|
|
.first()
|
|
|
|
if collection is None:
|
|
return jsonify(create_json_return('404'))
|
|
|
|
if collection.collection_user_id != user.id:
|
|
return jsonify(create_json_return('401'))
|
|
|
|
allowed_keys = [
|
|
'old_index',
|
|
'new_index',
|
|
'collection_name',
|
|
'collection_public',
|
|
'collection_age_rating',
|
|
'collection_description',
|
|
'collection_cover_image'
|
|
]
|
|
|
|
for key, value in request.json['data'].items():
|
|
# print(f'{key} - {value}')
|
|
if key not in allowed_keys:
|
|
return jsonify(create_json_return('400'))
|
|
if key == 'old_index' or key == 'new_index':
|
|
continue
|
|
setattr(collection, key, value)
|
|
# database.session.commit()
|
|
|
|
database.session.commit()
|
|
|
|
# print('just before update order')
|
|
if 'old_index' in request.json['data'] and 'new_index' in request.json['data']:
|
|
# print('updating order')
|
|
collection_items = database.session \
|
|
.query(database.CollectionLinks) \
|
|
.filter(database.CollectionLinks.collection_link_collection_id == collection.collection_id) \
|
|
.order_by(database.CollectionLinks.collection_link_issue_position) \
|
|
.all()
|
|
|
|
collection_items.insert(request.json['data']['new_index'], collection_items.pop(request.json['data']['old_index']))
|
|
|
|
for item in collection_items:
|
|
# print(item)
|
|
item.collection_link_issue_position = collection_items.index(item)
|
|
|
|
database.session.commit()
|
|
|
|
return jsonify(create_json_return('200'))
|
|
|
|
# DELETE
|
|
@api.route('/collections/<collection_slug>', methods=["DELETE"])
|
|
def api_delete_single_collection(collection_slug):
|
|
"""To Update Later
|
|
This is using docstrings for specifications.
|
|
---
|
|
tags:
|
|
- collections
|
|
"""
|
|
|
|
user = current_user
|
|
|
|
if not user.is_authenticated:
|
|
if not request.json:
|
|
return jsonify(create_json_return('400'))
|
|
if "api_key" not in request.json:
|
|
return jsonify(create_json_return('400'))
|
|
if request.json['api_key'] == "":
|
|
return jsonify(create_json_return('100'))
|
|
|
|
user = database.session \
|
|
.query(database.Users) \
|
|
.filter(database.Users.api_key == request.json['api_key']) \
|
|
.first()
|
|
|
|
if user is None:
|
|
return jsonify(create_json_return('100'))
|
|
|
|
collection = database.session \
|
|
.query(database.Collections) \
|
|
.filter(or_(database.Collections.collection_id == collection_slug,
|
|
database.Collections.collection_slug == collection_slug)) \
|
|
.first()
|
|
|
|
if user.id != collection.collection_user_id:
|
|
return jsonify(create_json_return('403'))
|
|
|
|
database.session \
|
|
.query(database.Collections) \
|
|
.filter(or_(database.Collections.collection_id == collection_slug,
|
|
database.Collections.collection_slug == collection_slug)) \
|
|
.delete()
|
|
|
|
database.session \
|
|
.query(database.CollectionLinks) \
|
|
.filter(database.CollectionLinks.collection_link_collection_id == collection.collection_id) \
|
|
.delete()
|
|
|
|
database.session.commit()
|
|
|
|
return jsonify(create_json_return('200'))
|
|
|
|
""" --- SINGLE COLLECTION ALL ISSUES --- """
|
|
|
|
# GET
|
|
@api.route('/collections/<collection_slug>/issues', methods=["GET"])
|
|
def api_get_collection_all_issues(collection_slug):
|
|
"""To Update Later
|
|
This is using docstrings for specifications.
|
|
---
|
|
tags:
|
|
- collections
|
|
"""
|
|
|
|
user = current_user
|
|
|
|
if not user.is_authenticated:
|
|
api_key = request.args.get('api_key')
|
|
if api_key == "":
|
|
return jsonify(create_json_return('100'))
|
|
user = database.session \
|
|
.query(database.Users) \
|
|
.filter(database.Users.api_key == api_key) \
|
|
.first()
|
|
|
|
if user is None:
|
|
return jsonify(create_json_return('100'))
|
|
|
|
offset = request.args.get('offset') if request.args.get('offset') is not None else 0
|
|
limit = request.args.get('limit') if request.args.get('limit') is not None else 100
|
|
|
|
collection = database.session \
|
|
.query(database.Collections) \
|
|
.filter(database.Collections.collection_slug == collection_slug) \
|
|
.first()
|
|
|
|
if collection.collection_user_id != user.id and collection.collection_public == 'false':
|
|
return create_json_return('409')
|
|
|
|
total_results = database.session \
|
|
.query(database.CollectionLinks) \
|
|
.filter(database.CollectionLinks.collection_link_collection_id == collection.collection_id) \
|
|
.count()
|
|
|
|
issues = (
|
|
database.session.query(database.Issues)
|
|
.join(database.Issues.collections)
|
|
.options(contains_eager(database.Issues.collections))
|
|
.filter(database.CollectionLinks.collection_link_collection_id == collection.collection_id)
|
|
.join(database.Issues.read_status)
|
|
.options(contains_eager(database.Issues.read_status))
|
|
.filter(database.ReadIssues.read_user_id == user.id)
|
|
.join(database.Issues.owned_status)
|
|
.options(contains_eager(database.Issues.owned_status))
|
|
.filter(database.OwnedIssues.owned_user_id == user.id)
|
|
).order_by(database.CollectionLinks.collection_link_issue_position.asc()).distinct().offset(offset).limit(limit).all()
|
|
|
|
data = database.IssuesSchema(many=True).dump(issues)
|
|
|
|
# print(data)
|
|
|
|
return create_json_return('200', results=data, total_results=total_results)
|
|
|
|
""" --- SINGLE COLECTION SINGLE ISSUE --- """
|
|
|
|
# GET
|
|
|
|
# POST
|
|
@api.route('/collections/<collection_slug>/issues/<issue_id>', methods=["POST"])
|
|
def api_post_collection_issue(collection_slug, issue_id):
|
|
pass
|
|
|
|
# DELETE
|
|
@api.route('/collections/<collection_slug>/issues/<issue_id>', methods=["DELETE"])
|
|
def api_delete_collection_issue(collection_slug, issue_id):
|
|
"""To Update Later
|
|
This is using docstrings for specifications.
|
|
---
|
|
tags:
|
|
- collections
|
|
"""
|
|
|
|
user = current_user
|
|
|
|
if not user.is_authenticated:
|
|
if not request.json:
|
|
return jsonify(create_json_return('400'))
|
|
if "api_key" not in request.json:
|
|
return jsonify(create_json_return('400'))
|
|
if request.json['api_key'] == "":
|
|
return jsonify(create_json_return('100'))
|
|
|
|
user = database.session \
|
|
.query(database.Users) \
|
|
.filter(database.Users.api_key == request.json['api_key']) \
|
|
.first()
|
|
|
|
if user is None:
|
|
return jsonify(create_json_return('100'))
|
|
|
|
collection = database.session \
|
|
.query(database.Collections) \
|
|
.filter(or_(database.Collections.collection_id == collection_slug,
|
|
database.Collections.collection_slug == collection_slug)) \
|
|
.first()
|
|
|
|
if user.id != collection.collection_user_id:
|
|
return jsonify(create_json_return('403'))
|
|
|
|
database.session \
|
|
.query(database.CollectionLinks) \
|
|
.filter(database.CollectionLinks.collection_link_collection_id == collection.collection_id,
|
|
database.CollectionLinks.collection_link_issue_id == issue_id) \
|
|
.delete()
|
|
|
|
database.session.commit()
|
|
|
|
return jsonify(create_json_return('200'))
|
|
|
|
""" --- SEARCH --- """
|
|
|
|
# GET
|
|
@api.route('/search', methods=["GET"])
|
|
def api_get_search():
|
|
"""To Update Later
|
|
This is using docstrings for specifications.
|
|
---
|
|
tags:
|
|
- search
|
|
"""
|
|
|
|
offset = request.args.get('offset') if request.args.get('offset') is not None else 0
|
|
limit = request.args.get('limit') if request.args.get('limit') is not None else 100
|
|
|
|
search_results = cv.search(request.args.get('query'), resources=['volume'], offset=offset, limit=limit)
|
|
total_results = len(search_results.results)
|
|
|
|
return jsonify(create_json_return('200', results=search_results.results, total_results=total_results))
|
|
|
|
""" --- SCRAPE --- """
|
|
|
|
|
|
""" --- SCRAPE DIRECTORIES --- """
|
|
|
|
|
|
""" --- DOWNLOADS --- """
|
|
|
|
# GET
|
|
@api.route('/downloads/<issue_id>', methods=['GET'])
|
|
def api_get_download_issue(issue_id):
|
|
"""To Update Later
|
|
This is using docstrings for specifications.
|
|
---
|
|
tags:
|
|
- downloads
|
|
"""
|
|
|
|
user = current_user
|
|
|
|
if not user.is_authenticated:
|
|
if not request.json:
|
|
return jsonify(create_json_return('400'))
|
|
if "api_key" not in request.json:
|
|
return jsonify(create_json_return('400'))
|
|
if request.json['api_key'] == "":
|
|
return jsonify(create_json_return('100'))
|
|
|
|
user = database.session \
|
|
.query(database.Users) \
|
|
.filter(database.Users.api_key == request.json['api_key']) \
|
|
.first()
|
|
|
|
if user is None:
|
|
return jsonify(create_json_return('100'))
|
|
|
|
issue = database.session \
|
|
.query(database.Issues) \
|
|
.filter(database.Issues.issue_id == issue_id) \
|
|
.first()
|
|
|
|
if issue is None:
|
|
return jsonify(create_json_return('404'))
|
|
|
|
issue_file = os.path.join(
|
|
folders.StashrFolders().comic_folder(),
|
|
issue.volume.directory.directory_path,
|
|
issue.issue_file_path
|
|
)
|
|
|
|
logger.debug(f'DOWNLOAD PATH: {issue_file}')
|
|
|
|
if not os.path.isfile(issue_file):
|
|
return jsonify(create_json_return('404'))
|
|
|
|
return send_file(issue_file, as_attachment=True, attachment_filename=pathlib.Path(issue_file).name)
|
|
|
|
""" --- ALL RATINGS --- """
|
|
|
|
# GET
|
|
@api.route('/ratings', methods=["GET"])
|
|
def api_get_all_ratings():
|
|
"""To Update Later
|
|
This is using docstrings for specifications.
|
|
---
|
|
tags:
|
|
- ratings
|
|
"""
|
|
|
|
user = current_user
|
|
|
|
if not user.is_authenticated:
|
|
api_key = request.args.get('api_key')
|
|
if api_key == "":
|
|
return jsonify(create_json_return('100'))
|
|
user = database.session \
|
|
.query(database.Users) \
|
|
.filter(database.Users.api_key == api_key) \
|
|
.first()
|
|
|
|
if user is None:
|
|
return jsonify(create_json_return('100'))
|
|
|
|
offset = request.args.get('offset') if request.args.get('offset') is not None else 0
|
|
limit = request.args.get('limit') if request.args.get('limit') is not None else 100
|
|
|
|
total_results = database.session \
|
|
.query(database.AgeRatings) \
|
|
.count()
|
|
|
|
ratings = database.session \
|
|
.query(database.AgeRatings) \
|
|
.all()
|
|
|
|
data = database.AgeRatingsSchema(many=True).dump(ratings)
|
|
return create_json_return('200', total_results=total_results, results=data)
|
|
|
|
|
|
""" --- SETTINGS --- """
|
|
|
|
|
|
@api.route('/settings', methods=["GET"])
|
|
def api_get_settings():
|
|
"""To Update Later
|
|
This is using docstrings for specifications.
|
|
---
|
|
tags:
|
|
- settings
|
|
"""
|
|
|
|
user = current_user
|
|
|
|
if not user.is_authenticated:
|
|
api_key = request.args.get('api_key')
|
|
if api_key == "":
|
|
return jsonify(create_json_return('100'))
|
|
user = database.session \
|
|
.query(database.Users) \
|
|
.filter(database.Users.api_key == api_key) \
|
|
.first()
|
|
|
|
if user is None:
|
|
return jsonify(create_json_return('100'))
|
|
|
|
settings = stashrconfig
|
|
|
|
if "SECURITY" in settings:
|
|
settings.pop("SECURITY")
|
|
|
|
for section in settings:
|
|
if "mail_password" in settings[section]:
|
|
settings[section].pop('mail_password')
|
|
|
|
return create_json_return('200', results=settings)
|
|
|
|
|
|
@api.route('/settings/<section>', methods=["GET"])
|
|
def api_get_settings_single_section(section):
|
|
"""To Update Later
|
|
This is using docstrings for specifications.
|
|
---
|
|
tags:
|
|
- settings
|
|
"""
|
|
|
|
user = current_user
|
|
|
|
if not user.is_authenticated:
|
|
api_key = request.args.get('api_key')
|
|
if api_key == "":
|
|
return jsonify(create_json_return('100'))
|
|
user = database.session \
|
|
.query(database.Users) \
|
|
.filter(database.Users.api_key == api_key) \
|
|
.first()
|
|
|
|
if user is None:
|
|
return jsonify(create_json_return('100'))
|
|
|
|
disallowed_sections = [
|
|
'security'
|
|
]
|
|
|
|
if section.lower() in disallowed_sections:
|
|
return create_json_return('405')
|
|
|
|
try:
|
|
settings = stashrconfig[section.upper()]
|
|
|
|
if 'mail_password' in settings:
|
|
settings.pop('mail_password')
|
|
|
|
except:
|
|
return create_json_return('404')
|
|
|
|
return create_json_return('200', results=settings)
|
|
|
|
|
|
@api.route('/settings/<section>/<setting>', methods=["GET"])
|
|
def api_get_settings_single_section_single_settings(section, setting):
|
|
"""To Update Later
|
|
This is using docstrings for specifications.
|
|
---
|
|
tags:
|
|
- settings
|
|
"""
|
|
|
|
user = current_user
|
|
|
|
if not user.is_authenticated:
|
|
api_key = request.args.get('api_key')
|
|
if api_key == "":
|
|
return jsonify(create_json_return('100'))
|
|
user = database.session \
|
|
.query(database.Users) \
|
|
.filter(database.Users.api_key == api_key) \
|
|
.first()
|
|
|
|
if user is None:
|
|
return jsonify(create_json_return('100'))
|
|
|
|
disallowed_sections = [
|
|
'security'
|
|
]
|
|
|
|
if section.lower() in disallowed_sections:
|
|
return create_json_return('405')
|
|
|
|
try:
|
|
settings = stashrconfig[section.upper()][setting]
|
|
except:
|
|
return create_json_return('404')
|
|
|
|
return create_json_return('200', results=settings)
|
|
|
|
|
|
""" --- API CALLS TO PLACE --- """
|
|
|
|
@api.route('/users', methods=["GET"])
|
|
def api_get_users():
|
|
"""To Update Later
|
|
This is using docstrings for specifications.
|
|
---
|
|
tags:
|
|
- users
|
|
"""
|
|
|
|
user = current_user
|
|
|
|
if not user.is_authenticated:
|
|
api_key = request.args.get('api_key')
|
|
if api_key == "":
|
|
return jsonify(create_json_return('100'))
|
|
user = database.session \
|
|
.query(database.Users) \
|
|
.filter(database.Users.api_key == api_key) \
|
|
.first()
|
|
|
|
if user is None:
|
|
return jsonify(create_json_return('100'))
|
|
|
|
if user.role != 'admin':
|
|
return jsonify(create_json_return('401'))
|
|
|
|
offset = request.args.get('offset') if request.args.get('offset') is not None else 0
|
|
limit = request.args.get('limit') if request.args.get('limit') is not None else 100
|
|
|
|
total_results = database.session \
|
|
.query(database.Users) \
|
|
.count()
|
|
|
|
users = database.session \
|
|
.query(database.Users) \
|
|
.order_by(database.Users.id) \
|
|
.offset(offset) \
|
|
.limit(limit) \
|
|
.all()
|
|
|
|
data = database.UsersSchema(many=True).dump(users)
|
|
return create_json_return('200', results=data, total_results=total_results)
|
|
|
|
|
|
@api.route('/users/<user_id>', methods=["GET"])
|
|
def api_get_single_user(user_id):
|
|
"""To Update Later
|
|
This is using docstrings for specifications.
|
|
---
|
|
tags:
|
|
- users
|
|
"""
|
|
|
|
user = current_user
|
|
|
|
if not user.is_authenticated:
|
|
api_key = request.args.get('api_key')
|
|
if api_key == "":
|
|
return jsonify(create_json_return('100'))
|
|
user = database.session \
|
|
.query(database.Users) \
|
|
.filter(database.Users.api_key == api_key) \
|
|
.first()
|
|
|
|
if user is None:
|
|
return jsonify(create_json_return('100'))
|
|
|
|
if user.role == 'admin' or user.id == int(user_id):
|
|
total_results = database.session \
|
|
.query(database.Users) \
|
|
.filter(database.Users.id == user_id) \
|
|
.count()
|
|
|
|
get_user = database.session \
|
|
.query(database.Users) \
|
|
.filter(database.Users.id == user_id) \
|
|
.first()
|
|
|
|
data = database.UsersSchema().dump(get_user)
|
|
# print(type(data))
|
|
return create_json_return('200', results=data, total_results=total_results)
|
|
else:
|
|
return jsonify(create_json_return('401'))
|
|
|
|
|
|
@api.route('/plugins', methods=["GET"])
|
|
def api_get_plugins():
|
|
"""To Update Later
|
|
This is using docstrings for specifications.
|
|
---
|
|
tags:
|
|
- plugins
|
|
"""
|
|
from stashr.stashr import pm
|
|
|
|
data = []
|
|
|
|
plugins = pm.get_all_plugins
|
|
|
|
for item in plugins:
|
|
list_item = {}
|
|
list_item['plugin_name'] = item.plugin_name
|
|
list_item['plugin_description'] = item.plugin_description
|
|
list_item['plugin_version'] = item.plugin_version
|
|
list_item['plugin_author'] = item.plugin_author
|
|
list_item['plugin_url'] = item.plugin_url
|
|
list_item['plugin_license'] = item.plugin_license
|
|
list_item['plugin_state'] = item.plugin_state
|
|
list_item['plugin_package_name'] = item.plugin_package_name
|
|
# list_item[]
|
|
data.append(list_item)
|
|
|
|
total_results = len(data)
|
|
|
|
return create_json_return('200', results=data, total_results=total_results)
|
|
|
|
|
|
""" --- NEW SCRAPE --- """
|
|
|
|
|
|
@api.route('/scrape/directories', methods=['GET'])
|
|
def api_get_directories():
|
|
"""To Update Later
|
|
This is using docstrings for specifications.
|
|
---
|
|
tags:
|
|
- scrape
|
|
"""
|
|
|
|
user = current_user
|
|
|
|
if not user.is_authenticated:
|
|
api_key = request.args.get('api_key')
|
|
if api_key == "":
|
|
return jsonify(create_json_return('100'))
|
|
user = database.session \
|
|
.query(database.Users) \
|
|
.filter(database.Users.api_key == api_key) \
|
|
.first()
|
|
|
|
if user is None:
|
|
return jsonify(create_json_return('100'))
|
|
|
|
if user.role != 'admin':
|
|
return jsonify(create_json_return('401'))
|
|
|
|
offset = request.args.get('offset') if request.args.get('offset') is not None else 0
|
|
limit = request.args.get('limit') if request.args.get('limit') is not None else 100
|
|
|
|
total_results = database.session \
|
|
.query(database.ScrapeItems) \
|
|
.count()
|
|
|
|
directories = database.session \
|
|
.query(database.ScrapeItems) \
|
|
.order_by(database.ScrapeItems.scrape_directory.asc()) \
|
|
.offset(offset) \
|
|
.limit(limit) \
|
|
.distinct() \
|
|
.all()
|
|
|
|
data = database.ScrapeItemsSchema(many=True).dump(directories)
|
|
|
|
return create_json_return('200', results=data, total_results=total_results)
|
|
|
|
|
|
@api.route('/scrape/directories/scan', methods=['POST'])
|
|
def api_post_directories_scan():
|
|
"""To Update Later
|
|
This is using docstrings for specifications.
|
|
---
|
|
tags:
|
|
- scrape
|
|
"""
|
|
|
|
user = current_user
|
|
|
|
if not user.is_authenticated:
|
|
if not request.json:
|
|
return jsonify(create_json_return('400'))
|
|
if "api_key" not in request.json:
|
|
return jsonify(create_json_return('400'))
|
|
if request.json['api_key'] == "":
|
|
return jsonify(create_json_return('100'))
|
|
|
|
user = database.session \
|
|
.query(database.Users) \
|
|
.filter(database.Users.api_key == request.json['api_key']) \
|
|
.first()
|
|
|
|
if user is None:
|
|
return jsonify(create_json_return('100'))
|
|
|
|
if user.role != 'admin':
|
|
return jsonify(create_json_return('401'))
|
|
|
|
# CALL TASK HERE
|
|
# utils.scan_directories()
|
|
tasks.scan_directories()
|
|
|
|
return jsonify(create_json_return('200'))
|
|
|
|
|
|
@api.route('/scrape/directories/add', methods=['POST'])
|
|
def api_post_directories_add():
|
|
"""To Update Later
|
|
This is using docstrings for specifications.
|
|
---
|
|
tags:
|
|
- scrape
|
|
"""
|
|
|
|
user = current_user
|
|
|
|
if not user.is_authenticated:
|
|
if not request.json:
|
|
return jsonify(create_json_return('400'))
|
|
if "api_key" not in request.json:
|
|
return jsonify(create_json_return('400'))
|
|
if request.json['api_key'] == "":
|
|
return jsonify(create_json_return('100'))
|
|
|
|
user = database.session \
|
|
.query(database.Users) \
|
|
.filter(database.Users.api_key == request.json['api_key']) \
|
|
.first()
|
|
|
|
if user is None:
|
|
return jsonify(create_json_return('100'))
|
|
|
|
if user.role != 'admin':
|
|
return jsonify(create_json_return('401'))
|
|
|
|
"""
|
|
matched_directories = database.session \
|
|
.query(database.ScrapeItems) \
|
|
.filter(database.ScrapeItems.scrape_add == 1) \
|
|
.all()
|
|
|
|
print(len(matched_directories))
|
|
|
|
for item in matched_directories:
|
|
utils.add_scrape_match(item)
|
|
"""
|
|
|
|
tasks.add_scraped_directories()
|
|
|
|
return jsonify(create_json_return('200'))
|
|
|
|
|
|
@api.route('/scrape/directories/edit/<scrape_id>', methods=['PUT'])
|
|
def api_put_directories_edit(scrape_id):
|
|
"""To Update Later
|
|
This is using docstrings for specifications.
|
|
---
|
|
tags:
|
|
- scrape
|
|
"""
|
|
|
|
user = current_user
|
|
|
|
if not user.is_authenticated:
|
|
if not request.json:
|
|
return jsonify(create_json_return('400'))
|
|
if "api_key" not in request.json:
|
|
return jsonify(create_json_return('400'))
|
|
if request.json['api_key'] == "":
|
|
return jsonify(create_json_return('100'))
|
|
|
|
user = database.session \
|
|
.query(database.Users) \
|
|
.filter(database.Users.api_key == request.json['api_key']) \
|
|
.first()
|
|
|
|
if user is None:
|
|
return jsonify(create_json_return('100'))
|
|
|
|
if user.role != 'admin':
|
|
return jsonify(create_json_return('401'))
|
|
|
|
allowed_keys = [
|
|
'scrape_add',
|
|
'scrape_candidate'
|
|
]
|
|
|
|
check_directory = database.session \
|
|
.query(database.ScrapeItems) \
|
|
.filter(database.ScrapeItems.scrape_id == scrape_id) \
|
|
.first()
|
|
|
|
if check_directory is None:
|
|
return jsonify(create_json_return('404'))
|
|
|
|
for key, value in request.json['data'].items():
|
|
if key not in allowed_keys:
|
|
database.session.rollbak()
|
|
return jsonify(create_json_return('400'))
|
|
setattr(check_directory, key, value)
|
|
|
|
database.session.merge(check_directory)
|
|
database.session.commit()
|
|
# print(check_directory.scrape_id)
|
|
|
|
return jsonify(create_json_return('200'))
|
|
|
|
|
|
@api.route('/scrape/directories/extend/<scrape_id>', methods=['POST'])
|
|
def api_post_directories_extend(scrape_id):
|
|
"""To Update Later
|
|
This is using docstrings for specifications.
|
|
---
|
|
tags:
|
|
- scrape
|
|
"""
|
|
|
|
user = current_user
|
|
|
|
if not user.is_authenticated:
|
|
if not request.json:
|
|
return jsonify(create_json_return('400'))
|
|
if "api_key" not in request.json:
|
|
return jsonify(create_json_return('400'))
|
|
if request.json['api_key'] == "":
|
|
return jsonify(create_json_return('100'))
|
|
|
|
user = database.session \
|
|
.query(database.Users) \
|
|
.filter(database.Users.api_key == request.json['api_key']) \
|
|
.first()
|
|
|
|
if user is None:
|
|
return jsonify(create_json_return('100'))
|
|
|
|
if user.role != 'admin':
|
|
return jsonify(create_json_return('401'))
|
|
|
|
allowed_keys = [
|
|
'search_terms'
|
|
]
|
|
|
|
for key, value in request.json['data'].items():
|
|
if key not in allowed_keys:
|
|
return jsonify(create_json_return('400'))
|
|
|
|
if "data" not in request.json:
|
|
return jsonify(create_json_return('400'))
|
|
if "search_terms" not in request.json['data']:
|
|
return jsonify(create_json_return('400'))
|
|
|
|
search_terms = request.json['data']['search_terms']
|
|
|
|
# DO THINGS HERE
|
|
utils.new_scrape_extend_matches(scrape_id, search_terms)
|
|
# tasks.extend_scrape(scrape_id)
|
|
|
|
return jsonify(create_json_return('200'))
|
|
|
|
|
|
""" --- PLUGIN UPLOAD/INSTALL --- """
|
|
|
|
|
|
@api.route('/plugins/upload', methods=['POST'])
|
|
def api_post_upload_plugin():
|
|
"""To Update Later
|
|
This is using docstrings for specifications.
|
|
---
|
|
tags:
|
|
- plugins
|
|
"""
|
|
|
|
user = current_user
|
|
|
|
if not user.is_authenticated:
|
|
if not request.json:
|
|
return jsonify(create_json_return('400'))
|
|
if "api_key" not in request.json:
|
|
return jsonify(create_json_return('400'))
|
|
if request.json['api_key'] == "":
|
|
return jsonify(create_json_return('100'))
|
|
|
|
user = database.session \
|
|
.query(database.Users) \
|
|
.filter(database.Users.api_key == request.json['api_key']) \
|
|
.first()
|
|
|
|
if user is None:
|
|
return jsonify(create_json_return('100'))
|
|
|
|
if user.role != 'admin':
|
|
return jsonify(create_json_return('401'))
|
|
|
|
if 'file' not in request.files:
|
|
return jsonify(create_json_return('400'))
|
|
|
|
# DO THINGS HERE
|
|
file = request.files['file']
|
|
|
|
file_path =os.path.join(
|
|
folders.StashrFolders().temp_folder(),
|
|
file.filename
|
|
)
|
|
|
|
file.save(file_path)
|
|
|
|
utils.install_plugin(file_path)
|
|
|
|
return jsonify(create_json_return('200'))
|
|
|
|
|
|
@api.route('/plugins/enable/<plugin>', methods=['POST'])
|
|
def api_post_plugin_enable(plugin):
|
|
"""To Update Later
|
|
This is using docstrings for specifications.
|
|
---
|
|
tags:
|
|
- plugins
|
|
"""
|
|
|
|
user = current_user
|
|
|
|
if not user.is_authenticated:
|
|
if not request.json:
|
|
return jsonify(create_json_return('400'))
|
|
if "api_key" not in request.json:
|
|
return jsonify(create_json_return('400'))
|
|
if request.json['api_key'] == "":
|
|
return jsonify(create_json_return('100'))
|
|
|
|
user = database.session \
|
|
.query(database.Users) \
|
|
.filter(database.Users.api_key == request.json['api_key']) \
|
|
.first()
|
|
|
|
if user is None:
|
|
return jsonify(create_json_return('100'))
|
|
|
|
if user.role != 'admin':
|
|
return jsonify(create_json_return('401'))
|
|
|
|
utils.enable_plugin(plugin)
|
|
|
|
return jsonify(create_json_return('200'))
|
|
|
|
|
|
@api.route('/plugins/disable/<plugin>', methods=['POST'])
|
|
def api_post_plugin_disable(plugin):
|
|
"""To Update Later
|
|
This is using docstrings for specifications.
|
|
---
|
|
tags:
|
|
- plugins
|
|
"""
|
|
|
|
user = current_user
|
|
|
|
if not user.is_authenticated:
|
|
if not request.json:
|
|
return jsonify(create_json_return('400'))
|
|
if "api_key" not in request.json:
|
|
return jsonify(create_json_return('400'))
|
|
if request.json['api_key'] == "":
|
|
return jsonify(create_json_return('100'))
|
|
|
|
user = database.session \
|
|
.query(database.Users) \
|
|
.filter(database.Users.api_key == request.json['api_key']) \
|
|
.first()
|
|
|
|
if user is None:
|
|
return jsonify(create_json_return('100'))
|
|
|
|
if user.role != 'admin':
|
|
return jsonify(create_json_return('401'))
|
|
|
|
utils.disable_plugin(plugin)
|
|
|
|
return jsonify(create_json_return('200'))
|
|
|
|
@api.route('/plugins/remove/<plugin>', methods=['POST'])
|
|
def api_post_plugin_remove(plugin):
|
|
"""To Update Later
|
|
This is using docstrings for specifications.
|
|
---
|
|
tags:
|
|
- plugins
|
|
"""
|
|
|
|
user = current_user
|
|
|
|
if not user.is_authenticated:
|
|
if not request.json:
|
|
return jsonify(create_json_return('400'))
|
|
if "api_key" not in request.json:
|
|
return jsonify(create_json_return('400'))
|
|
if request.json['api_key'] == "":
|
|
return jsonify(create_json_return('100'))
|
|
|
|
user = database.session \
|
|
.query(database.Users) \
|
|
.filter(database.Users.api_key == request.json['api_key']) \
|
|
.first()
|
|
|
|
if user is None:
|
|
return jsonify(create_json_return('100'))
|
|
|
|
if user.role != 'admin':
|
|
return jsonify(create_json_return('401'))
|
|
|
|
utils.uninstall_plugin(plugin)
|
|
|
|
return jsonify(create_json_return('200'))
|
|
|
|
""" --- RESTART SERVER --- """
|
|
|
|
@api.route('/restart', methods=['POST'])
|
|
def restart_server():
|
|
"""To Update Later
|
|
This is using docstrings for specifications.
|
|
---
|
|
tags:
|
|
- server
|
|
"""
|
|
|
|
user = current_user
|
|
|
|
if not user.is_authenticated:
|
|
if not request.json:
|
|
return jsonify(create_json_return('400'))
|
|
if "api_key" not in request.json:
|
|
return jsonify(create_json_return('400'))
|
|
if request.json['api_key'] == "":
|
|
return jsonify(create_json_return('100'))
|
|
|
|
user = database.session \
|
|
.query(database.Users) \
|
|
.filter(database.Users.api_key == request.json['api_key']) \
|
|
.first()
|
|
|
|
if user is None:
|
|
return jsonify(create_json_return('100'))
|
|
|
|
if user.role != 'admin':
|
|
return jsonify(create_json_return('401'))
|
|
|
|
if hasattr(signal, 'SIGHUP'):
|
|
os.kill(os.getpid(), signal.SIGHUP)
|
|
else:
|
|
print('no sighup')
|
|
import ctypes
|
|
ucrtbase = ctypes.CDLL('ucrtbase')
|
|
c_raise = ucrtbase['raise']
|
|
c_raise(signal.SIGINT)
|
|
|
|
return create_json_return('200')
|
|
|
|
|
|
""" --- API WRAPPER --- """
|
|
|
|
"""---------------------
|
|
|
|
data = {
|
|
status_code: <code>,
|
|
message: <error_message>,
|
|
number_of_total_results: <number>,
|
|
limit: <number>,
|
|
offset: <offset>,
|
|
results: <results>,
|
|
}
|
|
|
|
possible codes
|
|
200: OK
|
|
201: Created
|
|
405: Method Not Allowed
|
|
409: Conflict (item exists)
|
|
404: Not Found
|
|
406: Not Acceptable
|
|
|
|
---------------------"""
|
|
|
|
def create_json_return(status_code, total_results=None, results=None, message=None):
|
|
|
|
json = {}
|
|
|
|
json['status_code'] = status_code
|
|
|
|
if message is None:
|
|
json['message'] = return_codes[status_code]
|
|
else:
|
|
json['message'] = message
|
|
|
|
if results is not None:
|
|
if total_results is not None:
|
|
json['number_of_total_results'] = total_results
|
|
json['number_of_page_results'] = len(results)
|
|
json['results'] = results
|
|
|
|
return json |