Initial commit
This commit is contained in:
commit
bd0a7a32b2
12 changed files with 903 additions and 0 deletions
16
.gitignore
vendored
Normal file
16
.gitignore
vendored
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
.venv/
|
||||||
|
|
||||||
|
*.pyc
|
||||||
|
__pycache__/
|
||||||
|
|
||||||
|
instance/
|
||||||
|
|
||||||
|
.pytest_cache/
|
||||||
|
.coverage
|
||||||
|
htmlcov/
|
||||||
|
|
||||||
|
dist/
|
||||||
|
build/
|
||||||
|
*.egg-info/
|
||||||
|
|
||||||
|
cookie.txt
|
122
app/app.py
Normal file
122
app/app.py
Normal file
|
@ -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/<codename>")
|
||||||
|
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/<codename>")
|
||||||
|
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}
|
26
app/data/app.ini
Normal file
26
app/data/app.ini
Normal file
|
@ -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
|
52
app/data/titles.ini
Normal file
52
app/data/titles.ini
Normal file
|
@ -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
|
||||||
|
|
8
app/models/db.py
Normal file
8
app/models/db.py
Normal file
|
@ -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()
|
16
app/models/request_data.py
Normal file
16
app/models/request_data.py
Normal file
|
@ -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
|
38
app/services/torrents.py
Normal file
38
app/services/torrents.py
Normal file
|
@ -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
|
||||||
|
}
|
90
app/templates/about.html
Normal file
90
app/templates/about.html
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
{% extends "base.html" %} {% block nav %}
|
||||||
|
<nav class="left drawer">
|
||||||
|
<header>
|
||||||
|
<nav>
|
||||||
|
<img src="https://www.beercss.com/favicon.png" class="circle">
|
||||||
|
<h6>Toloka2Web MD3</h6>
|
||||||
|
</nav>
|
||||||
|
</header>
|
||||||
|
<a href="/">
|
||||||
|
<i>home</i>
|
||||||
|
<div>Головна</div>
|
||||||
|
</a>
|
||||||
|
<a href="add">
|
||||||
|
<i>add</i>
|
||||||
|
<div>Додати</div>
|
||||||
|
</a>
|
||||||
|
<a href="settings">
|
||||||
|
<i>settings</i>
|
||||||
|
<div>Налаштування</div>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<div class="divider small-margin"></div>
|
||||||
|
<label>Інше</label>
|
||||||
|
<a class="active" href="about">
|
||||||
|
<i>person</i>
|
||||||
|
<div>Про застосунок</div>
|
||||||
|
</a>
|
||||||
|
<a href="help">
|
||||||
|
<i>help</i>
|
||||||
|
<div>Допомога</div>
|
||||||
|
</a>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<nav class="left m">
|
||||||
|
<header>
|
||||||
|
<img src="https://www.beercss.com/favicon.png" class="circle">
|
||||||
|
</header>
|
||||||
|
<a>
|
||||||
|
<i>home</i>
|
||||||
|
<div>Home</div>
|
||||||
|
</a>
|
||||||
|
<a>
|
||||||
|
<i>search</i>
|
||||||
|
<div>Search</div>
|
||||||
|
</a>
|
||||||
|
<a>
|
||||||
|
<i>settings</i>
|
||||||
|
<div>Settings</div>
|
||||||
|
</a>
|
||||||
|
<a>
|
||||||
|
<i>more_vert</i>
|
||||||
|
<div>More</div>
|
||||||
|
</a>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<nav class="bottom s">
|
||||||
|
<a>
|
||||||
|
<i>home</i>
|
||||||
|
</a>
|
||||||
|
<a>
|
||||||
|
<i>search</i>
|
||||||
|
</a>
|
||||||
|
<a>
|
||||||
|
<i>settings</i>
|
||||||
|
</a>
|
||||||
|
<a>
|
||||||
|
<i>more_vert</i>
|
||||||
|
</a>
|
||||||
|
</nav>
|
||||||
|
{% endblock %} {% block content %}
|
||||||
|
|
||||||
|
|
||||||
|
<div class="padding absolute center middle">
|
||||||
|
<article class="medium middle-align center-align">
|
||||||
|
<div>
|
||||||
|
<i class="extra">cloud</i>
|
||||||
|
<h5 class="primary-text">Toloka2Web v2</h5>
|
||||||
|
<p class="secondary-text">Зручний сайт для завантаження аніме до медіасерверу Jellyfin</p>
|
||||||
|
<div class="space"></div>
|
||||||
|
<nav class="center-align">
|
||||||
|
<a href="https://github.com"><i class="chip circle">code</i></a>
|
||||||
|
<a href="https://github.com"><i class="chip circle">bug_report</i></a>
|
||||||
|
<a href="https://mastodon.com"><i class="chip circle">diversity_3</i></a>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
{% endblock %}
|
202
app/templates/add.html
Normal file
202
app/templates/add.html
Normal file
|
@ -0,0 +1,202 @@
|
||||||
|
{% extends "base.html" %} {% block nav %}
|
||||||
|
<nav class="left drawer min">
|
||||||
|
<header>
|
||||||
|
<nav>
|
||||||
|
<img src="https://www.beercss.com/favicon.png" class="circle">
|
||||||
|
<h6>Toloka2Web MD3</h6>
|
||||||
|
</nav>
|
||||||
|
</header>
|
||||||
|
<a href="/">
|
||||||
|
<i>home</i>
|
||||||
|
<div>Головна</div>
|
||||||
|
</a>
|
||||||
|
<a class="active" href="add">
|
||||||
|
<i>add</i>
|
||||||
|
<div>Додати</div>
|
||||||
|
</a>
|
||||||
|
<a href="settings">
|
||||||
|
<i>settings</i>
|
||||||
|
<div>Налаштування</div>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<div class="divider small-margin"></div>
|
||||||
|
<label>Інше</label>
|
||||||
|
<a href="about">
|
||||||
|
<i>person</i>
|
||||||
|
<div>Про застосунок</div>
|
||||||
|
</a>
|
||||||
|
<a href="help">
|
||||||
|
<i>help</i>
|
||||||
|
<div>Допомога</div>
|
||||||
|
</a>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<nav class="left m">
|
||||||
|
<header>
|
||||||
|
<img src="https://www.beercss.com/favicon.png" class="circle">
|
||||||
|
</header>
|
||||||
|
<a>
|
||||||
|
<i>home</i>
|
||||||
|
<div>Home</div>
|
||||||
|
</a>
|
||||||
|
<a>
|
||||||
|
<i>search</i>
|
||||||
|
<div>Search</div>
|
||||||
|
</a>
|
||||||
|
<a>
|
||||||
|
<i>settings</i>
|
||||||
|
<div>Settings</div>
|
||||||
|
</a>
|
||||||
|
<a>
|
||||||
|
<i>more_vert</i>
|
||||||
|
<div>More</div>
|
||||||
|
</a>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<nav class="bottom s">
|
||||||
|
<a>
|
||||||
|
<i>home</i>
|
||||||
|
</a>
|
||||||
|
<a>
|
||||||
|
<i>search</i>
|
||||||
|
</a>
|
||||||
|
<a>
|
||||||
|
<i>settings</i>
|
||||||
|
</a>
|
||||||
|
<a>
|
||||||
|
<i>more_vert</i>
|
||||||
|
</a>
|
||||||
|
</nav>
|
||||||
|
{% endblock %} {% block content %}
|
||||||
|
|
||||||
|
<p class="large-text">
|
||||||
|
<h6><i>add</i> Додати новий контент</h6>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<nav class="scroll">
|
||||||
|
<div class="center-align">
|
||||||
|
<button class="circle small" id="step_1"><i>search</i></button>
|
||||||
|
<div class="small-margin">Знайти торрент</div>
|
||||||
|
</div>
|
||||||
|
<hr class="max">
|
||||||
|
<div class="center-align">
|
||||||
|
<button class="circle small" id="step_2"><i>info</i></button>
|
||||||
|
<div class="small-margin">Метадані</div>
|
||||||
|
</div>
|
||||||
|
<hr class="max">
|
||||||
|
<div class="center-align">
|
||||||
|
<button class="circle small" disabled id="step_3"><i>add</i></button>
|
||||||
|
<div class="small-margin">Додати WIP</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<form action="/add" id="search_form">
|
||||||
|
<div class="field large prefix round fill">
|
||||||
|
<i class="front">search</i>
|
||||||
|
<input id="search-box" name="query" type="text" placeholder="https://toloka.to/t680082">
|
||||||
|
</menu>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
{% if torrent %}
|
||||||
|
<article id="torrent_card" class="no-padding">
|
||||||
|
<div class="grid large-space">
|
||||||
|
<div class="s12 m6 l3">
|
||||||
|
<img class="responsive" src={{torrent.img}}>
|
||||||
|
</div>
|
||||||
|
<div class="s9">
|
||||||
|
<div class="padding">
|
||||||
|
<h5 class="primary-text">{{torrent.name}}</h5>
|
||||||
|
|
||||||
|
<hr class="medium">
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<a class="chip no-margin"><i>language_gb_english</i><span>{{torrent.size}}</span></a>
|
||||||
|
<a class="chip no-margin"><i>signature</i><span>{{torrent.author}}</span></a>
|
||||||
|
<a class="chip no-margin"><i>calendar_month</i><span>{{torrent.date}}</span></a>
|
||||||
|
<a class="chip no-margin"><i>star_rate</i><span>{{torrent.rating}}</span></a>
|
||||||
|
<a class="chip no-margin"><i>thumb_up</i><span>{{torrent.thanks}}</span></a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr class="large">
|
||||||
|
|
||||||
|
{{torrent.description}}
|
||||||
|
|
||||||
|
<hr class="large">
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<a class="green no-margin button" onclick="twoStage('{{torrent.url}}')">
|
||||||
|
<i>add</i>
|
||||||
|
<span>Додати</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
|
||||||
|
<article class="center-align" style="display: none;" id="two_stage">
|
||||||
|
<form action="/add">
|
||||||
|
<div class="grid">
|
||||||
|
|
||||||
|
<div class="field label prefix border s6">
|
||||||
|
<i>folder</i>
|
||||||
|
<input type="text" name="dirname" value="{{torrent.files[0].folder_name}}">
|
||||||
|
<label>Назва директорії</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="field label prefix border s6">
|
||||||
|
<i>numbers</i>
|
||||||
|
<select name="season-index">
|
||||||
|
{% for season in range(1, 10) %}
|
||||||
|
<option>{{season}}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
<label>Індекс сезону</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="field label prefix border s6">
|
||||||
|
<i>numbers</i>
|
||||||
|
<select name="episode-index">
|
||||||
|
{% for option_index in range(episode_integers|length) %}
|
||||||
|
<option value="{{option_index + 1}}">{{episode_integers[option_index]}}</option>
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
</select>
|
||||||
|
<label>Індекс епізоду</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="field label prefix border s6">
|
||||||
|
<i>route</i>
|
||||||
|
<input type="text" name="filepath" value="{{default_dir}}">
|
||||||
|
<label>Місце завантаження</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<input style="display: none;" type="text" name="toloka_url" value="{{torrent.url}}">
|
||||||
|
|
||||||
|
<div class="field label prefix border s6">
|
||||||
|
<i>numbers</i>
|
||||||
|
<input type="number" name="adjusted-episode-number" value="0">
|
||||||
|
<label>Скільки додати до епізоду</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button class="border small-round s12" type="submit">
|
||||||
|
<i>add</i>
|
||||||
|
<span>Додати</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</article>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function twoStage() {
|
||||||
|
document.getElementById("search_form").remove();
|
||||||
|
document.getElementById("torrent_card").remove();
|
||||||
|
document.getElementById("step_1").innerHTML = "<i>done</i>"
|
||||||
|
|
||||||
|
$("#two_stage").toggle();
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{% endblock %}
|
44
app/templates/base.html
Normal file
44
app/templates/base.html
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||||
|
<meta name="google" content="notranslate">
|
||||||
|
<title>Toloka2Web</title>
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/beercss@3.6.13/dist/cdn/beer.min.css" rel="stylesheet">
|
||||||
|
<script type="module" src="https://cdn.jsdelivr.net/npm/beercss@3.6.13/dist/cdn/beer.min.js"></script>
|
||||||
|
<script type="module"
|
||||||
|
src="https://cdn.jsdelivr.net/npm/material-dynamic-colors@1.1.2/dist/cdn/material-dynamic-colors.min.js"></script>
|
||||||
|
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-cookie/3.0.1/js.cookie.min.js"></script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="dark">
|
||||||
|
{% block nav %}{% endblock %}
|
||||||
|
<header class="surface-dim">
|
||||||
|
<nav>
|
||||||
|
<h5 class="max"></h5>
|
||||||
|
<a class="chip circle"><i>palette</i><input id="color-picker" type="color"></a>
|
||||||
|
<a class="chip circle" onclick="document.body.classList.toggle('dark');"><i>light_mode</i></a>
|
||||||
|
</nav>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<main class="responsive">
|
||||||
|
{% block content %}{% endblock %}
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
addEventListener("DOMContentLoaded", function startup() {
|
||||||
|
colorPicker = document.querySelector("#color-picker");
|
||||||
|
colorPicker.addEventListener("change", updateAll, false);
|
||||||
|
ui("theme", Cookies.get('my-color'));
|
||||||
|
})
|
||||||
|
function updateAll(event) {
|
||||||
|
ui("theme", event.target.value);
|
||||||
|
Cookies.set('my-color', event.target.value);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
191
app/templates/index.html
Normal file
191
app/templates/index.html
Normal file
|
@ -0,0 +1,191 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
{% block nav %}
|
||||||
|
<nav class="left drawer">
|
||||||
|
<header>
|
||||||
|
<nav>
|
||||||
|
<img src="https://www.beercss.com/favicon.png" class="circle">
|
||||||
|
<h6>Toloka2Web MD3</h6>
|
||||||
|
</nav>
|
||||||
|
</header>
|
||||||
|
<a class="active" href="/">
|
||||||
|
<i>home</i>
|
||||||
|
<div>Головна</div>
|
||||||
|
</a>
|
||||||
|
<a href="add">
|
||||||
|
<i>add</i>
|
||||||
|
<div>Додати</div>
|
||||||
|
</a>
|
||||||
|
<a href="settings">
|
||||||
|
<i>settings</i>
|
||||||
|
<div>Налаштування</div>
|
||||||
|
</a>
|
||||||
|
<div class="divider small-margin"></div>
|
||||||
|
<label>Інше</label>
|
||||||
|
<a href="about">
|
||||||
|
<i>person</i>
|
||||||
|
<div>Про застосунок</div>
|
||||||
|
</a>
|
||||||
|
<a href="help">
|
||||||
|
<i>help</i>
|
||||||
|
<div>Допомога</div>
|
||||||
|
</a>
|
||||||
|
</nav>
|
||||||
|
<nav class="left m">
|
||||||
|
<header>
|
||||||
|
<img src="https://www.beercss.com/favicon.png" class="circle">
|
||||||
|
</header>
|
||||||
|
<a>
|
||||||
|
<i>home</i>
|
||||||
|
<div>Home</div>
|
||||||
|
</a>
|
||||||
|
<a>
|
||||||
|
<i>search</i>
|
||||||
|
<div>Search</div>
|
||||||
|
</a>
|
||||||
|
<a>
|
||||||
|
<i>settings</i>
|
||||||
|
<div>Settings</div>
|
||||||
|
</a>
|
||||||
|
<a>
|
||||||
|
<i>more_vert</i>
|
||||||
|
<div>More</div>
|
||||||
|
</a>
|
||||||
|
</nav>
|
||||||
|
<nav class="bottom s">
|
||||||
|
<a>
|
||||||
|
<i>home</i>
|
||||||
|
</a>
|
||||||
|
<a>
|
||||||
|
<i>search</i>
|
||||||
|
</a>
|
||||||
|
<a>
|
||||||
|
<i>settings</i>
|
||||||
|
</a>
|
||||||
|
<a>
|
||||||
|
<i>more_vert</i>
|
||||||
|
</a>
|
||||||
|
</nav>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<p class="large-text">
|
||||||
|
<h6><i>hub</i> Торенти</h6>
|
||||||
|
</p>
|
||||||
|
<button class="round fill">
|
||||||
|
<span>Сортування</span>
|
||||||
|
<i>arrow_drop_down</i>
|
||||||
|
<menu>
|
||||||
|
<a href="search?query=&sort=name">За назвою</a>
|
||||||
|
<a href="search?query=&sort=date">За датою</a>
|
||||||
|
<a href="search?query=&sort=releasename">За релізером</a>
|
||||||
|
</menu>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<p class="large-text">
|
||||||
|
<h6><i>work</i> Дії</h6>
|
||||||
|
</p>
|
||||||
|
<a class="chip" onclick="updateByCodename('')">
|
||||||
|
<i id="update_all_icon">done_all</i>
|
||||||
|
<span>Оновити</span>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<form action="/">
|
||||||
|
<div class="field large prefix round fill">
|
||||||
|
<i class="front">search</i>
|
||||||
|
<input id="search-box" name="query" type="text">
|
||||||
|
</menu>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
{%for item in titles%}
|
||||||
|
<article class="no-padding" id="{{item.codename}}">
|
||||||
|
<div class="grid">
|
||||||
|
<div class="s12 m6 l3">
|
||||||
|
<img class="responsive " src={{item.image}}>
|
||||||
|
</div>
|
||||||
|
<div class="s9">
|
||||||
|
<div class="padding">
|
||||||
|
<h5 class="primary-text">{{item.torrent_name}} ({{item.codename}})</h5>
|
||||||
|
|
||||||
|
<hr class="medium">
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<a class="chip no-margin"><i>route</i><span>{{item.download_dir}}</span></a>
|
||||||
|
<a class="chip no-margin"><i>signature</i><span>{{item.release_group}}</span></a>
|
||||||
|
<a class="chip no-margin"><i>calendar_month</i><span>{{item.publish_date}}</span></a>
|
||||||
|
<a class="chip no-margin"><i>tag</i><span>{{item.hash}}</span></a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr class="large">
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<a class="chip primary-border no-margin" href="https://toloka.to/{{item.guid}}">
|
||||||
|
<i>link</i>
|
||||||
|
<span>Посилання</span>
|
||||||
|
</a>
|
||||||
|
<a class="chip green-border no-margin" onclick="updateByCodename('{{item.codename}}')">
|
||||||
|
<i>update</i>
|
||||||
|
<span>Оновити</span>
|
||||||
|
</a>
|
||||||
|
<a class="chip amber-border no-margin" onclick="editByCodename('{{item.codename}}')">
|
||||||
|
<i>edit</i>
|
||||||
|
<span>Редагувати</span>
|
||||||
|
</a>
|
||||||
|
<a class="chip red-border no-margin" onclick="deleteByCodename('{{item.codename}}')">
|
||||||
|
<i>delete</i>
|
||||||
|
<span>Видалити</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
|
||||||
|
{%endfor%}
|
||||||
|
<dialog id="dialog">
|
||||||
|
<h5 class="primary-text" id="torrent_title">Інформація</h5>
|
||||||
|
<div id="torrent_info"></div>
|
||||||
|
<nav class="right-align no-space">
|
||||||
|
<button class="transparent link" onclick="document.querySelector('#dialog').close();">Ок</button>
|
||||||
|
</nav>
|
||||||
|
</dialog>
|
||||||
|
<script>
|
||||||
|
function deleteByCodename(codename) {
|
||||||
|
fetch(`/delete/${codename}`);
|
||||||
|
document.getElementById(codename).remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
function editByCodename(codename) {
|
||||||
|
location.href = (`/edit/${codename}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateByCodename(codename) {
|
||||||
|
if (codename == "") {
|
||||||
|
$('#update_all_icon').html("update")
|
||||||
|
}
|
||||||
|
$.ajax({
|
||||||
|
url: `/update/${codename}`,
|
||||||
|
type: 'GET',
|
||||||
|
success: function (response) {
|
||||||
|
if (response.hasOwnProperty("error")) {
|
||||||
|
$('#torrent_title').html("Помилка")
|
||||||
|
$('#torrent_info').html(`${response.error}`)
|
||||||
|
document.querySelector('#dialog').showModal();
|
||||||
|
} else {
|
||||||
|
$('#update_all_icon').html("done_all")
|
||||||
|
|
||||||
|
var operation_html = ""
|
||||||
|
document.querySelector('#dialog').showModal();
|
||||||
|
for (var i = 0; i < response.operation_logs.length; i++) {
|
||||||
|
operation_html += `* ${response.operation_logs[i]}<br>`
|
||||||
|
}
|
||||||
|
$('#torrent_info').html(`${operation_html}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
error: function (result) {
|
||||||
|
document.querySelector('#dialog').showModal();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
98
app/templates/settings.html
Normal file
98
app/templates/settings.html
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
{% extends "base.html" %} {% block nav %}
|
||||||
|
<nav class="left drawer">
|
||||||
|
<header>
|
||||||
|
<nav>
|
||||||
|
<img src="https://www.beercss.com/favicon.png" class="circle">
|
||||||
|
<h6>Toloka2Web MD3</h6>
|
||||||
|
</nav>
|
||||||
|
</header>
|
||||||
|
<a href="/">
|
||||||
|
<i>home</i>
|
||||||
|
<div>Головна</div>
|
||||||
|
</a>
|
||||||
|
<a href="add">
|
||||||
|
<i>add</i>
|
||||||
|
<div>Додати</div>
|
||||||
|
</a>
|
||||||
|
<a class="active" href="settings">
|
||||||
|
<i>settings</i>
|
||||||
|
<div>Налаштування</div>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<div class="divider small-margin"></div>
|
||||||
|
<label>Інше</label>
|
||||||
|
<a href="about">
|
||||||
|
<i>person</i>
|
||||||
|
<div>Про застосунок</div>
|
||||||
|
</a>
|
||||||
|
<a href="help">
|
||||||
|
<i>help</i>
|
||||||
|
<div>Допомога</div>
|
||||||
|
</a>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<nav class="left m">
|
||||||
|
<header>
|
||||||
|
<img src="https://www.beercss.com/favicon.png" class="circle">
|
||||||
|
</header>
|
||||||
|
<a>
|
||||||
|
<i>home</i>
|
||||||
|
<div>Home</div>
|
||||||
|
</a>
|
||||||
|
<a>
|
||||||
|
<i>search</i>
|
||||||
|
<div>Search</div>
|
||||||
|
</a>
|
||||||
|
<a>
|
||||||
|
<i>settings</i>
|
||||||
|
<div>Settings</div>
|
||||||
|
</a>
|
||||||
|
<a>
|
||||||
|
<i>more_vert</i>
|
||||||
|
<div>More</div>
|
||||||
|
</a>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<nav class="bottom s">
|
||||||
|
<a>
|
||||||
|
<i>home</i>
|
||||||
|
</a>
|
||||||
|
<a>
|
||||||
|
<i>search</i>
|
||||||
|
</a>
|
||||||
|
<a>
|
||||||
|
<i>settings</i>
|
||||||
|
</a>
|
||||||
|
<a>
|
||||||
|
<i>more_vert</i>
|
||||||
|
</a>
|
||||||
|
</nav>
|
||||||
|
{% endblock %} {% block content %}
|
||||||
|
|
||||||
|
<p class="large-text">
|
||||||
|
<h6><i>settings</i> Налаштування WIP</h6>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="large-space"></div>
|
||||||
|
|
||||||
|
|
||||||
|
<article class="primary-text">
|
||||||
|
<a class="row wave"><i>person</i> Обліковий запис Tokoka.to</a>
|
||||||
|
<hr>
|
||||||
|
<a class="row wave"><i>hub</i> BitTorrent</a>
|
||||||
|
<hr>
|
||||||
|
<a class="row wave"><i>comic_bubble</i> Аніме</a>
|
||||||
|
<hr>
|
||||||
|
<a class="row wave"><i>bug_report</i> Дебагінг</a>
|
||||||
|
</article>
|
||||||
|
|
||||||
|
<article class="secondary-text">
|
||||||
|
<a class="row wave"><i>title</i> Toloka2Web v2</a>
|
||||||
|
<hr>
|
||||||
|
<a class="row wave"><i>conversion_path</i> v0.0.1</a>
|
||||||
|
</article>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{% endblock %}
|
Loading…
Reference in a new issue