ittup 1.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ittup/__init__.py +1 -0
- ittup/__main__.py +5 -0
- ittup/common/__init__.py +4 -0
- ittup/common/about.py +15 -0
- ittup/common/bdinfo_string.py +98 -0
- ittup/common/bittorrent.py +14 -0
- ittup/common/command.py +162 -0
- ittup/common/constants.py +18 -0
- ittup/common/database.py +78 -0
- ittup/common/external_services/__init__.py +9 -0
- ittup/common/external_services/ftpx/__init__.py +0 -0
- ittup/common/external_services/ftpx/client.py +305 -0
- ittup/common/external_services/ftpx/core/__init__.py +0 -0
- ittup/common/external_services/ftpx/core/ftpx_service.py +76 -0
- ittup/common/external_services/ftpx/core/ftpx_session.py +159 -0
- ittup/common/external_services/ftpx/core/menu.py +17 -0
- ittup/common/external_services/ftpx/core/models/__init__.py +0 -0
- ittup/common/external_services/ftpx/core/models/list.py +17 -0
- ittup/common/external_services/igdb/__init__.py +0 -0
- ittup/common/external_services/igdb/client.py +262 -0
- ittup/common/external_services/igdb/core/__init__.py +0 -0
- ittup/common/external_services/igdb/core/api.py +70 -0
- ittup/common/external_services/igdb/core/models/__init__.py +0 -0
- ittup/common/external_services/igdb/core/models/search.py +13 -0
- ittup/common/external_services/igdb/core/platformid.py +24 -0
- ittup/common/external_services/igdb/core/tags.py +13 -0
- ittup/common/external_services/imageHost.py +324 -0
- ittup/common/external_services/mediaresult.py +25 -0
- ittup/common/external_services/sessions/__init__.py +0 -0
- ittup/common/external_services/sessions/agents.py +212 -0
- ittup/common/external_services/sessions/exceptions.py +100 -0
- ittup/common/external_services/sessions/session.py +149 -0
- ittup/common/external_services/theMovieDB/__init__.py +4 -0
- ittup/common/external_services/theMovieDB/core/__init__.py +8 -0
- ittup/common/external_services/theMovieDB/core/api.py +574 -0
- ittup/common/external_services/theMovieDB/core/keywords.py +7 -0
- ittup/common/external_services/theMovieDB/core/models/__init__.py +0 -0
- ittup/common/external_services/theMovieDB/core/models/movie/__init__.py +0 -0
- ittup/common/external_services/theMovieDB/core/models/movie/alternative.py +2 -0
- ittup/common/external_services/theMovieDB/core/models/movie/details.py +82 -0
- ittup/common/external_services/theMovieDB/core/models/movie/movie.py +48 -0
- ittup/common/external_services/theMovieDB/core/models/movie/nowplaying.py +69 -0
- ittup/common/external_services/theMovieDB/core/models/movie/release_info.py +49 -0
- ittup/common/external_services/theMovieDB/core/models/movie/translations.py +33 -0
- ittup/common/external_services/theMovieDB/core/models/tvshow/__init__.py +0 -0
- ittup/common/external_services/theMovieDB/core/models/tvshow/alternative.py +14 -0
- ittup/common/external_services/theMovieDB/core/models/tvshow/details.py +139 -0
- ittup/common/external_services/theMovieDB/core/models/tvshow/on_the_air.py +27 -0
- ittup/common/external_services/theMovieDB/core/models/tvshow/translations.py +45 -0
- ittup/common/external_services/theMovieDB/core/models/tvshow/tvshow.py +50 -0
- ittup/common/external_services/theMovieDB/core/videos.py +21 -0
- ittup/common/external_services/trailers/__init__.py +3 -0
- ittup/common/external_services/trailers/api.py +120 -0
- ittup/common/external_services/trailers/response.py +51 -0
- ittup/common/external_services/tvdb.py +45 -0
- ittup/common/extractor.py +124 -0
- ittup/common/frames.py +221 -0
- ittup/common/mediainfo.py +206 -0
- ittup/common/mediainfo_string.py +103 -0
- ittup/common/settings.py +952 -0
- ittup/common/tags.py +415 -0
- ittup/common/title.py +127 -0
- ittup/common/torrent_clients.py +280 -0
- ittup/common/trackers/__init__.py +8 -0
- ittup/common/trackers/ban_list.py +5 -0
- ittup/common/trackers/data.py +22 -0
- ittup/common/trackers/itt.py +153 -0
- ittup/common/trackers/signs_list.py +293 -0
- ittup/common/trackers/tags_list.py +118 -0
- ittup/common/trackers/trackers.py +46 -0
- ittup/common/utility.py +394 -0
- ittup/core/__init__.py +5 -0
- ittup/core/__main__.py +289 -0
- ittup/core/automode.py +122 -0
- ittup/core/bot.py +294 -0
- ittup/core/duplicate.py +270 -0
- ittup/core/exceptions.py +122 -0
- ittup/core/media.py +378 -0
- ittup/core/media_manager/ContentManager.py +199 -0
- ittup/core/media_manager/DocuManager.py +76 -0
- ittup/core/media_manager/GameManager.py +107 -0
- ittup/core/media_manager/MediaInfoManager.py +26 -0
- ittup/core/media_manager/SeedManager.py +49 -0
- ittup/core/media_manager/TorrentManager.py +153 -0
- ittup/core/media_manager/VideoManager.py +145 -0
- ittup/core/media_manager/__init__.py +0 -0
- ittup/core/media_manager/common.py +265 -0
- ittup/core/pvtDocu.py +123 -0
- ittup/core/pvtTorrent.py +78 -0
- ittup/core/pvtTracker.py +481 -0
- ittup/core/pvtVideo.py +104 -0
- ittup/core/torrent.py +467 -0
- ittup/core/upload.py +168 -0
- ittup/view/__init__.py +3 -0
- ittup/view/custom_console.py +148 -0
- ittup-1.1.0.dist-info/METADATA +182 -0
- ittup-1.1.0.dist-info/RECORD +101 -0
- ittup-1.1.0.dist-info/WHEEL +5 -0
- ittup-1.1.0.dist-info/entry_points.txt +2 -0
- ittup-1.1.0.dist-info/licenses/LICENSE +22 -0
- ittup-1.1.0.dist-info/top_level.txt +1 -0
ittup/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
ittup/__main__.py
ADDED
ittup/common/__init__.py
ADDED
ittup/common/about.py
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
from importlib.metadata import PackageNotFoundError, version as _package_version
|
|
3
|
+
|
|
4
|
+
APP_NAME = "ittup"
|
|
5
|
+
APP_DESCRIPTION = "ItaTorrents uploader"
|
|
6
|
+
REPO_URL = "https://github.com/TehMaat/ittup"
|
|
7
|
+
|
|
8
|
+
# The version is defined only in pyproject.toml and read from the installed package metadata
|
|
9
|
+
try:
|
|
10
|
+
__version__ = _package_version(APP_NAME)
|
|
11
|
+
except PackageNotFoundError:
|
|
12
|
+
# Running from a source checkout without installing the package
|
|
13
|
+
__version__ = "0.0.0+unknown"
|
|
14
|
+
|
|
15
|
+
USER_AGENT = f"{APP_NAME}/{__version__} (+{REPO_URL})"
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
class BDInfo:
|
|
4
|
+
"""
|
|
5
|
+
A class to represent information about a Blu-ray disc.
|
|
6
|
+
|
|
7
|
+
Attributes:
|
|
8
|
+
disc_label (str): The label or name of the disc.
|
|
9
|
+
disc_size (str): The size of the disc.
|
|
10
|
+
protection (str): The type of protection applied to the disc.
|
|
11
|
+
playlist (str): The playlist information.
|
|
12
|
+
size (str): The size of the content on the disc.
|
|
13
|
+
length (str): The length of the content on the disc.
|
|
14
|
+
total_bitrate (str): The total bitrate of the disc content.
|
|
15
|
+
video (str): The video specifications.
|
|
16
|
+
audio (list[str]): A list of audio specifications.
|
|
17
|
+
languages (list[str]): A list of languages extracted from audio specifications.
|
|
18
|
+
subtitles (list[str]): A list of subtitle specifications.
|
|
19
|
+
|
|
20
|
+
Methods:
|
|
21
|
+
from_bdinfo_string(bd_info_string: str) -> 'BDInfo':
|
|
22
|
+
Creates an instance of BDInfo from a formatted string.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
def __init__(
|
|
26
|
+
self,
|
|
27
|
+
disc_label: str,
|
|
28
|
+
disc_size: str,
|
|
29
|
+
protection: str,
|
|
30
|
+
playlist: str,
|
|
31
|
+
size: str,
|
|
32
|
+
length: str,
|
|
33
|
+
total_bitrate: str,
|
|
34
|
+
video: str,
|
|
35
|
+
audio: list[str],
|
|
36
|
+
languages: list[str],
|
|
37
|
+
subtitles: list[str],
|
|
38
|
+
):
|
|
39
|
+
self.disc_label = disc_label
|
|
40
|
+
self.disc_size = disc_size
|
|
41
|
+
self.protection = protection
|
|
42
|
+
self.playlist = playlist
|
|
43
|
+
self.size = size
|
|
44
|
+
self.length = length
|
|
45
|
+
self.total_bitrate = total_bitrate
|
|
46
|
+
self.video = video
|
|
47
|
+
self.audio = audio
|
|
48
|
+
self.languages = languages
|
|
49
|
+
self.subtitles = subtitles
|
|
50
|
+
|
|
51
|
+
@classmethod
|
|
52
|
+
def from_bdinfo_string(cls, bd_info_string: str) -> 'BDInfo':
|
|
53
|
+
"""
|
|
54
|
+
Creates an instance of BDInfo from a formatted string.
|
|
55
|
+
|
|
56
|
+
Args:
|
|
57
|
+
bd_info_string (str): A string containing Blu-ray disc information formatted with labels and values.
|
|
58
|
+
|
|
59
|
+
Returns:
|
|
60
|
+
BDInfo: An instance of the BDInfo class with attributes populated from the input string.
|
|
61
|
+
"""
|
|
62
|
+
lines = bd_info_string.strip().split("\n")
|
|
63
|
+
data = {"audio": [], "subtitles": []}
|
|
64
|
+
|
|
65
|
+
for line in lines:
|
|
66
|
+
# Parsing Audio
|
|
67
|
+
if ": " in line:
|
|
68
|
+
key, value = line.split(": ", 1)
|
|
69
|
+
key = key.strip().replace(" ", "_").lower()
|
|
70
|
+
|
|
71
|
+
if key == "audio":
|
|
72
|
+
data["audio"].append(value.strip().lower())
|
|
73
|
+
elif key == "subtitle":
|
|
74
|
+
data["subtitles"].append(value.strip().lower())
|
|
75
|
+
else:
|
|
76
|
+
data[key] = value.strip()
|
|
77
|
+
|
|
78
|
+
# Parsing Languages
|
|
79
|
+
languages_parsed = []
|
|
80
|
+
for item in data["audio"]:
|
|
81
|
+
item = item.replace("(", " ")
|
|
82
|
+
item = item.replace(")", " ")
|
|
83
|
+
item = item.split("/")
|
|
84
|
+
languages_parsed.append(item[0].strip())
|
|
85
|
+
|
|
86
|
+
return cls(
|
|
87
|
+
disc_label=data.get("disc_label"),
|
|
88
|
+
disc_size=data.get("disc_size"),
|
|
89
|
+
protection=data.get("protection"),
|
|
90
|
+
playlist=data.get("playlist"),
|
|
91
|
+
size=data.get("size"),
|
|
92
|
+
length=data.get("length"),
|
|
93
|
+
total_bitrate=data.get("total_bitrate"),
|
|
94
|
+
video=data.get("video"),
|
|
95
|
+
audio=data["audio"],
|
|
96
|
+
languages=languages_parsed,
|
|
97
|
+
subtitles=data["subtitles"],
|
|
98
|
+
)
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from ittup.core.pvtTorrent import Mytorrent
|
|
5
|
+
from ittup.core.media import Media
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@dataclass
|
|
9
|
+
class BittorrentData:
|
|
10
|
+
tracker_response: str
|
|
11
|
+
torrent_response: Mytorrent | None
|
|
12
|
+
content: Media
|
|
13
|
+
tracker_message: dict
|
|
14
|
+
archive_path: str
|
ittup/common/command.py
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
import os
|
|
3
|
+
import argparse
|
|
4
|
+
|
|
5
|
+
from ittup.common.utility import System
|
|
6
|
+
from ittup.common.about import APP_DESCRIPTION, APP_NAME
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class RemovedFlag(argparse.Action):
|
|
10
|
+
def __call__(self, parser, namespace, values, option_string=None):
|
|
11
|
+
parser.error(f"'{option_string}' has been removed: {APP_NAME} uploads only to ItaTorrents")
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class CommandLine:
|
|
15
|
+
"""
|
|
16
|
+
Handle command line arguments
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
def __init__(self):
|
|
20
|
+
|
|
21
|
+
# /////////////////////////
|
|
22
|
+
# Main parser
|
|
23
|
+
# /////////////////////////
|
|
24
|
+
parser = argparse.ArgumentParser(
|
|
25
|
+
prog=APP_NAME,
|
|
26
|
+
description=f"{APP_DESCRIPTION}: manage torrents, uploads, searches and config checks",
|
|
27
|
+
formatter_class=argparse.ArgumentDefaultsHelpFormatter
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
# /////////////////////////
|
|
31
|
+
# Groups
|
|
32
|
+
# /////////////////////////
|
|
33
|
+
cfg_group = parser.add_argument_group("Config Commands")
|
|
34
|
+
upload_group = parser.add_argument_group("Upload Commands")
|
|
35
|
+
search_group = parser.add_argument_group("Search Commands")
|
|
36
|
+
filter_group = parser.add_argument_group("Filter Options")
|
|
37
|
+
special_group = parser.add_argument_group("Special Flags")
|
|
38
|
+
|
|
39
|
+
# /////////////////////////
|
|
40
|
+
# Config Commands
|
|
41
|
+
# /////////////////////////
|
|
42
|
+
cfg_group.add_argument(
|
|
43
|
+
"-check", "--check",
|
|
44
|
+
action="store_true",
|
|
45
|
+
help="Check config files"
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
# /////////////////////////
|
|
49
|
+
# Upload Commands
|
|
50
|
+
# /////////////////////////
|
|
51
|
+
upload_group.add_argument("-u", "--upload", type=str, help="Upload path")
|
|
52
|
+
upload_group.add_argument("-f", "--folder", type=str, help="Upload folder")
|
|
53
|
+
upload_group.add_argument("-scan", "--scan", type=str, help="Scan folder")
|
|
54
|
+
upload_group.add_argument("-reseed", "--reseed", action="store_true", help="Reseed folder")
|
|
55
|
+
upload_group.add_argument("-watcher", "--watcher", action="store_true", help="Start watcher")
|
|
56
|
+
upload_group.add_argument("-notitle", "--notitle", type=str, help="Manual title")
|
|
57
|
+
|
|
58
|
+
upload_group.add_argument(
|
|
59
|
+
"-force",
|
|
60
|
+
nargs='?',
|
|
61
|
+
const="movie",
|
|
62
|
+
type=str,
|
|
63
|
+
default=None,
|
|
64
|
+
help="Force category"
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
upload_group.add_argument("-noseed", "--noseed", action="store_true", help="Disable seeding")
|
|
68
|
+
upload_group.add_argument("-noup", "--noup", action="store_true", help="Torrent only")
|
|
69
|
+
upload_group.add_argument("-dup", "--duplicate", action="store_true", help="Check duplicates")
|
|
70
|
+
upload_group.add_argument("-personal", "--personal", action="store_true", help="Personal release")
|
|
71
|
+
upload_group.add_argument("-ftp", "--ftp", action="store_true", help="Connect FTP")
|
|
72
|
+
|
|
73
|
+
# Removed flags: ittup uploads only to ItaTorrents. Without this '-mt' would be parsed as '-m t'
|
|
74
|
+
upload_group.add_argument("-mt", "--mt", "-tracker", "--tracker", nargs='?', action=RemovedFlag,
|
|
75
|
+
help=argparse.SUPPRESS)
|
|
76
|
+
|
|
77
|
+
# /////////////////////////
|
|
78
|
+
# Search Commands
|
|
79
|
+
# /////////////////////////
|
|
80
|
+
search_group.add_argument("-dmp", "--dump", action="store_true", help="Dump titles")
|
|
81
|
+
search_group.add_argument("-sch", "--search", type=str, help="Search torrent")
|
|
82
|
+
search_group.add_argument("-db", "--dbsave", action="store_true", help="Save results")
|
|
83
|
+
search_group.add_argument("-i", "--info", type=str, help="Torrent info")
|
|
84
|
+
search_group.add_argument("-up", "--uploader", type=str, help="By uploader")
|
|
85
|
+
search_group.add_argument("-d", "--description", type=str, help="By description")
|
|
86
|
+
search_group.add_argument("-bd", "--bdinfo", type=str, help="Show BDInfo")
|
|
87
|
+
search_group.add_argument("-m", "--mediainfo", type=str, help="Show MediaInfo")
|
|
88
|
+
search_group.add_argument("-int", "--internal", action="store_true", help="Internal Release")
|
|
89
|
+
search_group.add_argument("-mod", "--moderation", action="store_true", help="In moderation")
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
# /////////////////////////
|
|
93
|
+
# Filter Options
|
|
94
|
+
# /////////////////////////
|
|
95
|
+
filter_group.add_argument("-st", "--startyear", type=str, help="Start year")
|
|
96
|
+
filter_group.add_argument("-en", "--endyear", type=str, help="End year")
|
|
97
|
+
filter_group.add_argument("-type", "--type", type=str, help="Type")
|
|
98
|
+
filter_group.add_argument("-res", "--resolution", type=str, help="Resolution")
|
|
99
|
+
filter_group.add_argument("-file", "--filename", type=str, help="Filename")
|
|
100
|
+
filter_group.add_argument("-se", "--season", type=str, help="Season")
|
|
101
|
+
filter_group.add_argument("-ep", "--episode", type=str, help="Episode")
|
|
102
|
+
|
|
103
|
+
# IDs
|
|
104
|
+
filter_group.add_argument("-tmdb", "--tmdb_id", type=str, help="TMDB ID")
|
|
105
|
+
filter_group.add_argument("-imdb", "--imdb_id", type=str, help="IMDB ID")
|
|
106
|
+
filter_group.add_argument("-tvdb", "--tvdb_id", type=int, help="TVDB ID")
|
|
107
|
+
filter_group.add_argument("-mal", "--mal_id", type=str, help="MAL ID")
|
|
108
|
+
filter_group.add_argument("-playid", "--playlist_id", type=str, help="Playlist ID")
|
|
109
|
+
filter_group.add_argument("-coll", "--collection_id", type=str, help="Collection ID")
|
|
110
|
+
|
|
111
|
+
# Status
|
|
112
|
+
filter_group.add_argument("-free", "--freelech", type=str, help="Freeleech")
|
|
113
|
+
filter_group.add_argument("-al", "--alive", action="store_true", help="Alive")
|
|
114
|
+
filter_group.add_argument("-dd", "--dead", action="store_true", help="Dead")
|
|
115
|
+
filter_group.add_argument("-dy", "--dying", action="store_true", help="Dying")
|
|
116
|
+
|
|
117
|
+
# /////////////////////////
|
|
118
|
+
# Special Flags
|
|
119
|
+
# /////////////////////////
|
|
120
|
+
special_group.add_argument("-du", "--doubleup", action="store_true", help="DoubleUp")
|
|
121
|
+
special_group.add_argument("-fe", "--featured", action="store_true", help="Featured")
|
|
122
|
+
special_group.add_argument("-re", "--refundable", action="store_true", help="Refundable")
|
|
123
|
+
special_group.add_argument("-str", "--stream", action="store_true", help="Stream")
|
|
124
|
+
special_group.add_argument("-sd", "--standard", action="store_true", help="SD")
|
|
125
|
+
special_group.add_argument("-hs", "--highspeed", action="store_true", help="Highspeed")
|
|
126
|
+
special_group.add_argument("-inter", "--intern_r", action="store_true", help="Internal Release")
|
|
127
|
+
special_group.add_argument("-pr", "--prelease", action="store_true", help="Personal")
|
|
128
|
+
|
|
129
|
+
# /////////////////////////
|
|
130
|
+
# Parse args
|
|
131
|
+
# /////////////////////////
|
|
132
|
+
self.args = parser.parse_args()
|
|
133
|
+
|
|
134
|
+
# /////////////////////////
|
|
135
|
+
# Check scan path
|
|
136
|
+
# /////////////////////////
|
|
137
|
+
self.is_dir = os.path.isdir(self.args.scan) if self.args.scan else None
|
|
138
|
+
|
|
139
|
+
# /////////////////////////
|
|
140
|
+
# Expand upload path
|
|
141
|
+
# /////////////////////////
|
|
142
|
+
if self.args.upload:
|
|
143
|
+
self.args.upload = os.path.expanduser(self.args.upload)
|
|
144
|
+
|
|
145
|
+
# /////////////////////////
|
|
146
|
+
# Validate force category
|
|
147
|
+
# /////////////////////////
|
|
148
|
+
if self.args.force:
|
|
149
|
+
|
|
150
|
+
self.args.force = self.args.force[:10]
|
|
151
|
+
|
|
152
|
+
valid_categories = [
|
|
153
|
+
System.category_list[System.MOVIE],
|
|
154
|
+
System.category_list[System.GAME],
|
|
155
|
+
System.category_list[System.TV_SHOW],
|
|
156
|
+
System.category_list[System.DOCUMENTARY]
|
|
157
|
+
]
|
|
158
|
+
|
|
159
|
+
if self.args.force.lower() not in valid_categories:
|
|
160
|
+
self.args.force = None
|
|
161
|
+
print("Invalid -force category")
|
|
162
|
+
exit()
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
language_dict = {
|
|
4
|
+
"IT": "Italian",
|
|
5
|
+
"ES": "Spanish",
|
|
6
|
+
"DE": "German",
|
|
7
|
+
"FR": "French",
|
|
8
|
+
"EN": "English",
|
|
9
|
+
"TR": "Turkish",
|
|
10
|
+
"PT": "Portuguese",
|
|
11
|
+
"JA": "Japanese",
|
|
12
|
+
"BG": "Bulgarian",
|
|
13
|
+
"PL": "Polish"
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def my_language(iso639_1: str)-> str | None:
|
|
18
|
+
return language_dict.get(iso639_1.upper(), '')
|
ittup/common/database.py
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import os
|
|
3
|
+
import sqlite3
|
|
4
|
+
from ittup.core import config_settings
|
|
5
|
+
|
|
6
|
+
# Torrent attributes
|
|
7
|
+
create_table_sql = ('\n'
|
|
8
|
+
'CREATE TABLE IF NOT EXISTS torrents (\n'
|
|
9
|
+
' id INTEGER PRIMARY KEY AUTOINCREMENT,\n'
|
|
10
|
+
' name TEXT,\n'
|
|
11
|
+
' category TEXT,\n'
|
|
12
|
+
' category_id INTEGER,\n'
|
|
13
|
+
' created_at TEXT,\n'
|
|
14
|
+
' description TEXT,\n'
|
|
15
|
+
' details_link TEXT,\n'
|
|
16
|
+
' download_link TEXT,\n'
|
|
17
|
+
' double_upload BOOLEAN,\n'
|
|
18
|
+
' featured BOOLEAN,\n'
|
|
19
|
+
' freeleech TEXT,\n'
|
|
20
|
+
' igdb_id INTEGER,\n'
|
|
21
|
+
' imdb_id TEXT,\n'
|
|
22
|
+
' info_hash TEXT,\n'
|
|
23
|
+
' internal BOOLEAN,\n'
|
|
24
|
+
' leechers INTEGER,\n'
|
|
25
|
+
' magnet_link TEXT,\n'
|
|
26
|
+
' mal_id INTEGER,\n'
|
|
27
|
+
' media_info TEXT,\n'
|
|
28
|
+
' release_year INTEGER,\n'
|
|
29
|
+
' resolution TEXT,\n'
|
|
30
|
+
' resolution_id INTEGER,\n'
|
|
31
|
+
' seeders INTEGER,\n'
|
|
32
|
+
' size INTEGER,\n'
|
|
33
|
+
' times_completed INTEGER,\n'
|
|
34
|
+
' tmdb_id INTEGER,\n'
|
|
35
|
+
' tvdb_id INTEGER,\n'
|
|
36
|
+
' type TEXT,\n'
|
|
37
|
+
' type_id INTEGER,\n'
|
|
38
|
+
' uploader TEXT,\n'
|
|
39
|
+
' personal_release BOOLEAN,\n'
|
|
40
|
+
' refundable BOOLEAN,\n'
|
|
41
|
+
' num_file INTEGER,\n'
|
|
42
|
+
' bd_info TEXT,\n'
|
|
43
|
+
' genres TEXT,\n'
|
|
44
|
+
' poster TEXT,\n'
|
|
45
|
+
' meta TEXT,\n'
|
|
46
|
+
' files TEXT\n'
|
|
47
|
+
')\n')
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class Database:
|
|
51
|
+
"""
|
|
52
|
+
Create a new database and populate it with torrents attributes
|
|
53
|
+
Search torrents based on attributes
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
def __init__(self, db_file):
|
|
57
|
+
self.filename = db_file
|
|
58
|
+
self.CACHE_PATH = config_settings.user_preferences.CACHE_PATH
|
|
59
|
+
self.database = sqlite3.connect(os.path.join(self.CACHE_PATH, f"{db_file}.db"))
|
|
60
|
+
self.cursor = self.database.cursor()
|
|
61
|
+
self.build()
|
|
62
|
+
|
|
63
|
+
def build(self):
|
|
64
|
+
self.cursor.execute("DROP TABLE IF EXISTS torrents")
|
|
65
|
+
self.cursor.execute(create_table_sql)
|
|
66
|
+
self.database.commit()
|
|
67
|
+
|
|
68
|
+
def write(self, data: dict):
|
|
69
|
+
for key, value in data.items():
|
|
70
|
+
if isinstance(value, (dict, list)):
|
|
71
|
+
data[key] = json.dumps(value)
|
|
72
|
+
|
|
73
|
+
keys = ', '.join(data.keys())
|
|
74
|
+
placeholders = ', '.join(['?'] * len(data))
|
|
75
|
+
values = tuple(data.values())
|
|
76
|
+
sql = f'''INSERT INTO torrents ({keys}) VALUES ({placeholders})'''
|
|
77
|
+
self.cursor.execute(sql, values)
|
|
78
|
+
self.database.commit()
|
|
File without changes
|