commit bd0a7a32b23a7e444718301d28e5ff6b28d40654 Author: CakesTwix Date: Fri Aug 23 17:05:31 2024 +0300 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f241265 --- /dev/null +++ b/.gitignore @@ -0,0 +1,16 @@ +.venv/ + +*.pyc +__pycache__/ + +instance/ + +.pytest_cache/ +.coverage +htmlcov/ + +dist/ +build/ +*.egg-info/ + +cookie.txt \ No newline at end of file diff --git a/app/app.py b/app/app.py new file mode 100644 index 0000000..85fb286 --- /dev/null +++ b/app/app.py @@ -0,0 +1,122 @@ +from flask import Flask, render_template, request, jsonify, redirect, url_for +import time +from services.torrents import initiate_config, serialize_operation_result + +from models.request_data import RequestData +from flask_caching import Cache +from flask_sqlalchemy import SQLAlchemy + + +from toloka2MediaServer.main_logic import ( + add_release_by_url, update_release_by_name, update_releases, + search_torrents, get_torrent as get_torrent_external, + add_torrent as add_torrent_external +) + +cache = Cache(config={'CACHE_TYPE': 'SimpleCache'}) +app = Flask(__name__) +app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///t2w.db" +cache.init_app(app) + +from sqlalchemy.orm import DeclarativeBase, MappedAsDataclass + +class Base(DeclarativeBase, MappedAsDataclass): + pass + +db = SQLAlchemy(app, model_class=Base) + +from models.db import ImagesCache + +with app.app_context(): + db.create_all() + +@app.route("/") +@cache.cached(timeout=1) +def root_route(): + sections = [] + config = initiate_config() + titles = config.titles_config + new_torrent = 0 + for title in titles.sections(): + if request.args.get('query', '') in title: + image_cache = db.session.execute(db.select(ImagesCache).filter_by(codename=title)).scalar_one_or_none() + if image_cache: + titles[title]["image"] = image_cache.image + else: + toloka_torrent = config.toloka.get_torrent(f"https://toloka.to/{titles[title]["guid"]}") + toloka_img = f"https:{toloka_torrent.img}" if toloka_torrent.img.startswith("//") else toloka_torrent.img + db.session.add(ImagesCache(title, toloka_img)) + db.session.commit() + + titles[title]["image"] = toloka_img + + # Config data + titles[title]["codename"] = title + titles[title]["torrent_name"] = titles[title]["torrent_name"].replace("\"", "") + sections.append(titles[title]) + + return render_template('index.html', titles = sections, new_torrent = new_torrent) + +# First stage +@app.route("/add") +def add_route(): + config = initiate_config() + if request.args.get('query'): + torrent = config.toloka.get_torrent(request.args.get('query')) + return render_template('add.html', torrent = torrent, episode_integers = [i for i in ''.join((ch if ch.isdigit() else ' ') for ch in f"{torrent.files[0].folder_name}/{torrent.files[0].file_name}").split()], default_dir = config.app_config.get("Toloka", "default_download_dir")) + + if len(request.args) == 6: + requestData = RequestData( + url = request.args["toloka_url"], + season = request.args["season-index"], + index = int(request.args["episode-index"]), + correction = int(request.args['adjusted-episode-number']), + title = request.args["dirname"], + ) + + config.args = requestData + operation_result = add_release_by_url(config) + output = serialize_operation_result(operation_result) + return redirect(url_for('root_route')) + + return render_template('add.html') + +@app.route("/about") +def about_route(): + return render_template('about.html') + +@app.route("/settings") +def settings_route(): + return render_template('settings.html') + +@app.route("/delete/") +def delete_route(codename): + config = initiate_config() + titles = config.titles_config + titles.remove_section(codename) + with open("data/titles.ini", "w") as f: + titles.write(f) + + return f"{codename} успішно видалений." + +@app.route("/update/", defaults={'codename': None}) +@app.route("/update/") +def update_route(codename): + # Process the name to update release + try: + config = initiate_config() + requestData = RequestData( + codename = codename + ) + if codename: + config.args = requestData + operation_result = update_release_by_name(config) + else: + config.args = RequestData() + operation_result = update_releases(config) + + output = serialize_operation_result(operation_result) + return output + except Exception as e: + message = f'Error: {str(e)}' + return {"error": message} diff --git a/app/data/app.ini b/app/data/app.ini new file mode 100644 index 0000000..19b48f1 --- /dev/null +++ b/app/data/app.ini @@ -0,0 +1,26 @@ +[Python] +# NOTSET +# DEBUG +# INFO +# WARNING +# ERROR +# CRITICAL +logging = DEBUG + +[transmission] +username = +password = +port = 9091 +host = +protocol = http +rpc = /transmission/rpc +category = sonarr +tag = tolokaAnime + +[Toloka] +username = +password = +client = +default_download_dir = +wait_time = 10 +client_wait_time = 2 diff --git a/app/data/titles.ini b/app/data/titles.ini new file mode 100644 index 0000000..e664665 --- /dev/null +++ b/app/data/titles.ini @@ -0,0 +1,52 @@ +[TenseishitaraSlimeDattaKen] +episode_index = 2 +season_number = 03 +ext_name = .mkv +torrent_name = "Tensei shitara Slime Datta Ken" +download_dir = /media/HDD/Jellyfin/Anime +publish_date = 24-08-16 21:57 +release_group = FanVoxUA +meta = +hash = 18a83050fa77ae155d0df927c6142824c35094bb +adjusted_episode_number = 0 +guid = t678039 + +[DEADDEADDEMONSDEDEDEDEDESTRUCTION] +episode_index = 0 +season_number = 01 +ext_name = .mkv +torrent_name = "DEAD DEAD DEMONS DEDEDEDE DESTRUCTION" +download_dir = /media/HDD/Jellyfin/Anime +publish_date = 24-08-18 12:01 +release_group = FanVoxUA +meta = +hash = 40c5fbeed2f1c4c11fb7247eb81e72b70255f871 +adjusted_episode_number = 0 +guid = t679732 + +[ScottPilgrimTakesOff] +episode_index = 4 +season_number = 01 +ext_name = .mkv +torrent_name = "Scott Pilgrim Takes Off" +download_dir = /media/HDD/Jellyfin/Anime +publish_date = 24-06-29 19:41 +release_group = Altron320 +meta = +hash = 25946318d080809e65f32249bd3184d265af2146 +adjusted_episode_number = 0 +guid = t679822 + +[VinlandSaga] +episode_index = 2 +season_number = 01 +ext_name = .mkv +torrent_name = "Vinland Saga" +download_dir = /media/HDD/Jellyfin/Anime +publish_date = 20-06-29 20:08 +release_group = 11FrYkT +meta = +hash = 2d1c961f8899156ff4ef995b1ad9b03bc75442d6 +adjusted_episode_number = 0 +guid = t111251 + diff --git a/app/models/db.py b/app/models/db.py new file mode 100644 index 0000000..1e230e0 --- /dev/null +++ b/app/models/db.py @@ -0,0 +1,8 @@ +from app import db +from sqlalchemy.orm import Mapped, mapped_column + +class ImagesCache(db.Model): + __tablename__ = "image_cache" + + codename: Mapped[str] = mapped_column(primary_key=True) + image: Mapped[str] = mapped_column() \ No newline at end of file diff --git a/app/models/request_data.py b/app/models/request_data.py new file mode 100644 index 0000000..17d8aae --- /dev/null +++ b/app/models/request_data.py @@ -0,0 +1,16 @@ +class RequestData: + url: str = "" + season: int = 0 + index: int = 0 + correction: int = 0 + title: str = "" + codename: str = "" + force: bool = False + def __init__(self, url = "", season = 0, index = 0, correction = 0, title = "", codename = "", force=False): + self.url = url + self.season = season + self.index = index + self.correction = correction + self.title = title + self.codename = codename + self.force = force \ No newline at end of file diff --git a/app/services/torrents.py b/app/services/torrents.py new file mode 100644 index 0000000..dbe9141 --- /dev/null +++ b/app/services/torrents.py @@ -0,0 +1,38 @@ +from toloka2MediaServer.config_parser import load_configurations, get_toloka_client +from toloka2MediaServer.logger_setup import setup_logging +from toloka2MediaServer.models.config import Config +from toloka2MediaServer.clients.dynamic import dynamic_client_init + +def initiate_config(): + app_config_path='data/app.ini' + title_config_path='data/titles.ini' + logger_path = 'data/app_web.log' + + app_config, titles_config, application_config = load_configurations(app_config_path,title_config_path) + toloka=get_toloka_client(application_config) + logger=setup_logging(logger_path) + + config = Config( + logger=logger, + toloka=toloka, + app_config=app_config, + titles_config=titles_config, + application_config=application_config + ) + + client = dynamic_client_init(config) + config.client = client + + return config + +def serialize_operation_result(operation_result): + return { + "operation_type": operation_result.operation_type.name if operation_result.operation_type else None, + "torrent_references": [str(torrent) for torrent in operation_result.torrent_references], + "titles_references": [str(titles) for titles in operation_result.titles_references], + "status_message": operation_result.status_message, + "response_code": operation_result.response_code.name if operation_result.response_code else None, + "operation_logs": operation_result.operation_logs, + "start_time": operation_result.start_time.isoformat() if operation_result.start_time else None, + "end_time": operation_result.end_time.isoformat() if operation_result.end_time else None + } \ No newline at end of file diff --git a/app/templates/about.html b/app/templates/about.html new file mode 100644 index 0000000..a289707 --- /dev/null +++ b/app/templates/about.html @@ -0,0 +1,90 @@ +{% extends "base.html" %} {% block nav %} + + + + + +{% endblock %} {% block content %} + + +
+
+
+ cloud +
Toloka2Web v2
+

Зручний сайт для завантаження аніме до медіасерверу Jellyfin

+
+ +
+
+
+ + +{% endblock %} \ No newline at end of file diff --git a/app/templates/add.html b/app/templates/add.html new file mode 100644 index 0000000..0ce5977 --- /dev/null +++ b/app/templates/add.html @@ -0,0 +1,202 @@ +{% extends "base.html" %} {% block nav %} + + + + + +{% endblock %} {% block content %} + +

+

add Додати новий контент
+

+ + + +
+
+ search + + +
+
+ +{% if torrent %} + + + +{% endif %} + + + +{% endblock %} \ No newline at end of file diff --git a/app/templates/base.html b/app/templates/base.html new file mode 100644 index 0000000..da0870b --- /dev/null +++ b/app/templates/base.html @@ -0,0 +1,44 @@ + + + + + + + + Toloka2Web + + + + + + + + + {% block nav %}{% endblock %} +
+ +
+ +
+ {% block content %}{% endblock %} +
+ + + + + \ No newline at end of file diff --git a/app/templates/index.html b/app/templates/index.html new file mode 100644 index 0000000..106ce08 --- /dev/null +++ b/app/templates/index.html @@ -0,0 +1,191 @@ +{% extends "base.html" %} +{% block nav %} + + + +{% endblock %} + +{% block content %} +

+

hub Торенти
+

+ + +

+

work Дії
+

+ + done_all + Оновити + + +
+
+ search + + +
+
+{%for item in titles%} + + +{%endfor%} + +
Інформація
+
+ +
+ +{% endblock %} \ No newline at end of file diff --git a/app/templates/settings.html b/app/templates/settings.html new file mode 100644 index 0000000..ee5dafd --- /dev/null +++ b/app/templates/settings.html @@ -0,0 +1,98 @@ +{% extends "base.html" %} {% block nav %} + + + + + +{% endblock %} {% block content %} + +

+

settings Налаштування WIP
+

+ +
+ + + + + + + + + +{% endblock %} \ No newline at end of file