d4rktg 0.3.4__tar.gz → 0.3.5__tar.gz
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.
- {d4rktg-0.3.4 → d4rktg-0.3.5}/PKG-INFO +1 -1
- d4rktg-0.3.5/VERSION.txt +1 -0
- d4rktg-0.3.5/d4rk/Utils/_movie_parser.py +211 -0
- {d4rktg-0.3.4 → d4rktg-0.3.5}/d4rktg.egg-info/PKG-INFO +1 -1
- d4rktg-0.3.4/VERSION.txt +0 -1
- d4rktg-0.3.4/d4rk/Utils/_movie_parser.py +0 -92
- {d4rktg-0.3.4 → d4rktg-0.3.5}/MANIFEST.in +0 -0
- {d4rktg-0.3.4 → d4rktg-0.3.5}/README.rst +0 -0
- {d4rktg-0.3.4 → d4rktg-0.3.5}/d4rk/Database/__init__.py +0 -0
- {d4rktg-0.3.4 → d4rktg-0.3.5}/d4rk/Database/db.py +0 -0
- {d4rktg-0.3.4 → d4rktg-0.3.5}/d4rk/Handlers/__init__.py +0 -0
- {d4rktg-0.3.4 → d4rktg-0.3.5}/d4rk/Handlers/_bot.py +0 -0
- {d4rktg-0.3.4 → d4rktg-0.3.5}/d4rk/Handlers/_scheduler.py +0 -0
- {d4rktg-0.3.4 → d4rktg-0.3.5}/d4rk/Logs/__init__.py +0 -0
- {d4rktg-0.3.4 → d4rktg-0.3.5}/d4rk/Logs/_logger.py +0 -0
- {d4rktg-0.3.4 → d4rktg-0.3.5}/d4rk/Models/__init__.py +0 -0
- {d4rktg-0.3.4 → d4rktg-0.3.5}/d4rk/Models/_commands.py +0 -0
- {d4rktg-0.3.4 → d4rktg-0.3.5}/d4rk/Models/_movie_title.py +0 -0
- {d4rktg-0.3.4 → d4rktg-0.3.5}/d4rk/Utils/__init__.py +0 -0
- {d4rktg-0.3.4 → d4rktg-0.3.5}/d4rk/Utils/_decorators.py +0 -0
- {d4rktg-0.3.4 → d4rktg-0.3.5}/d4rk/Utils/_delete.py +0 -0
- {d4rktg-0.3.4 → d4rktg-0.3.5}/d4rk/Utils/_fonts.py +0 -0
- {d4rktg-0.3.4 → d4rktg-0.3.5}/d4rk/Utils/_ip.py +0 -0
- {d4rktg-0.3.4 → d4rktg-0.3.5}/d4rk/Utils/_ractions.py +0 -0
- {d4rktg-0.3.4 → d4rktg-0.3.5}/d4rk/Utils/_terminal.py +0 -0
- {d4rktg-0.3.4 → d4rktg-0.3.5}/d4rk/__init__.py +0 -0
- {d4rktg-0.3.4 → d4rktg-0.3.5}/d4rktg.egg-info/SOURCES.txt +0 -0
- {d4rktg-0.3.4 → d4rktg-0.3.5}/d4rktg.egg-info/dependency_links.txt +0 -0
- {d4rktg-0.3.4 → d4rktg-0.3.5}/d4rktg.egg-info/requires.txt +0 -0
- {d4rktg-0.3.4 → d4rktg-0.3.5}/d4rktg.egg-info/top_level.txt +0 -0
- {d4rktg-0.3.4 → d4rktg-0.3.5}/requirements.txt +0 -0
- {d4rktg-0.3.4 → d4rktg-0.3.5}/setup.cfg +0 -0
- {d4rktg-0.3.4 → d4rktg-0.3.5}/setup.py +0 -0
d4rktg-0.3.5/VERSION.txt
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.3.5
|
@@ -0,0 +1,211 @@
|
|
1
|
+
import re
|
2
|
+
import PTN
|
3
|
+
import unicodedata
|
4
|
+
|
5
|
+
from typing import List, Optional
|
6
|
+
from dataclasses import dataclass, field
|
7
|
+
|
8
|
+
@dataclass
|
9
|
+
class Movie:
|
10
|
+
title: str
|
11
|
+
normalized_title: str
|
12
|
+
year: Optional[int]
|
13
|
+
resolution: Optional[str]
|
14
|
+
quality: Optional[str]
|
15
|
+
codec: Optional[str]
|
16
|
+
extra: List[str] = field(default_factory=list)
|
17
|
+
split: bool = False
|
18
|
+
part: Optional[int] = None
|
19
|
+
|
20
|
+
class MovieParser:
|
21
|
+
def __parse_file_name(self, file_name: str):
|
22
|
+
file_name = re.sub(r'@[\w_]+', '', file_name.lower()).strip()
|
23
|
+
file_name = file_name.replace('_', ' ')
|
24
|
+
self.file_name = file_name
|
25
|
+
self.extension = self.file_name.split('.')[-1]
|
26
|
+
self.movie = PTN.parse(self.file_name)
|
27
|
+
self.tags = []
|
28
|
+
|
29
|
+
def fallback_title(self, file_name):
|
30
|
+
name = re.sub(r'\.\w{2,4}$', '', file_name)
|
31
|
+
name = name.replace('_', ' ').replace('.', ' ')
|
32
|
+
name = re.sub(r'@\w+', '', name)
|
33
|
+
name = unicodedata.normalize('NFKC', name)
|
34
|
+
tags_pattern = r'\b(480p|720p|1080p|2160p|BR_Rip|WEBRip|HDRip|x264|x265|HEVC|AAC|DD\+?5\.1|[0-9]+MB|1GB|2GB|Tamil|Telugu|Hindi|English|Dubbed|HDTV|WEB-DL|BluRay|Blu-ray|YTS|YIFY|fps)\b'
|
35
|
+
name = re.sub(tags_pattern, '', name, flags=re.IGNORECASE)
|
36
|
+
name = re.split(r'\b(S\d+|Ep\d+)\b', name, 1)[0]
|
37
|
+
name = re.sub(r'\s+', ' ', name).strip()
|
38
|
+
return name
|
39
|
+
|
40
|
+
def fallback_year(self, file_name):
|
41
|
+
years = re.findall(r'(?<!\d)(19\d{2}|20\d{2})(?!\d)', file_name)
|
42
|
+
return int(years[0]) if years else None
|
43
|
+
|
44
|
+
def _fix_roman_numerals(self, text: str) -> str:
|
45
|
+
roman_pattern = r'\b(i{1,3}|iv|v|vi{0,3}|ix|x{1,3}|xl|l|li{0,3}|lx|xc|c|ci{0,3}|cd|d|dc|cm|m|m{1,3})\b'
|
46
|
+
return re.sub(roman_pattern, lambda m: m.group(0).upper(), text, flags=re.IGNORECASE)
|
47
|
+
|
48
|
+
def extract(self, file_name: str) -> Movie:
|
49
|
+
self.__parse_file_name(file_name)
|
50
|
+
title = self.movie.get('title', '').replace('.', ' ').strip()
|
51
|
+
if not title:title = self.fallback_title(self.file_name)
|
52
|
+
else:title = title.replace('.', ' ').strip()
|
53
|
+
|
54
|
+
year = self.movie.get('year') or self.fallback_year(self.file_name)
|
55
|
+
if year and str(year) in title:title = title.replace(str(year), '').strip()
|
56
|
+
|
57
|
+
resolution = self.movie.get('resolution')
|
58
|
+
quality = self.movie.get('quality')
|
59
|
+
codec = self.movie.get('codec')
|
60
|
+
if codec:codec = codec.replace('H', 'x').replace('.', '')
|
61
|
+
|
62
|
+
extra = []
|
63
|
+
tag_keywords = {
|
64
|
+
# Release groups / encoders
|
65
|
+
'psa': 'PSA',
|
66
|
+
'pahe': 'Pahe',
|
67
|
+
'galaxyrg': 'GalaxyRG',
|
68
|
+
'yify': 'YIFY',
|
69
|
+
'yts': 'YTS',
|
70
|
+
'rarbg': 'RARBG',
|
71
|
+
'ettv': 'ETTV',
|
72
|
+
'evo': 'EVO',
|
73
|
+
'fgt': 'FGT',
|
74
|
+
'ntg': 'NTG',
|
75
|
+
'tigole': 'Tigole',
|
76
|
+
'qxr': 'QxR',
|
77
|
+
'vxt': 'VXT',
|
78
|
+
'cm8': 'CM8',
|
79
|
+
'naisu': 'NAISU',
|
80
|
+
'kog': 'KOGi',
|
81
|
+
'spark': 'SPARKS',
|
82
|
+
'don': 'DON',
|
83
|
+
'lama': 'LAMA',
|
84
|
+
'drone': 'DRONES',
|
85
|
+
'iht': 'IHT',
|
86
|
+
'amzn-rls': 'Amazon Release',
|
87
|
+
|
88
|
+
# Streaming platforms
|
89
|
+
'nf': 'Netflix',
|
90
|
+
'amzn': 'Amazon',
|
91
|
+
'hmax': 'HBO Max',
|
92
|
+
'dsnp': 'Disney+',
|
93
|
+
'hulu': 'Hulu',
|
94
|
+
'appletv': 'Apple TV+',
|
95
|
+
'paramount': 'Paramount+',
|
96
|
+
'peacock': 'Peacock',
|
97
|
+
'crave': 'Crave',
|
98
|
+
'zee5': 'ZEE5',
|
99
|
+
'sony': 'SonyLiv',
|
100
|
+
'atvp': 'Apple TV+',
|
101
|
+
'mbc': 'MBC',
|
102
|
+
|
103
|
+
# Video quality / features
|
104
|
+
'imax': 'IMAX',
|
105
|
+
'hdr': 'HDR',
|
106
|
+
'hdr10': 'HDR10',
|
107
|
+
'hdr10+': 'HDR10+',
|
108
|
+
'dolbyvision': 'Dolby Vision',
|
109
|
+
'dv': 'Dolby Vision',
|
110
|
+
'visionplus': 'Dolby Vision+',
|
111
|
+
'60fps': '60FPS',
|
112
|
+
'50fps': '50FPS',
|
113
|
+
'10bit': '10bit',
|
114
|
+
'8bit': '8bit',
|
115
|
+
'hevc': 'HEVC',
|
116
|
+
'x265': 'x265',
|
117
|
+
'h265': 'H.265',
|
118
|
+
'x264': 'x264',
|
119
|
+
'h264': 'H.264',
|
120
|
+
'av1': 'AV1',
|
121
|
+
|
122
|
+
# Audio formats
|
123
|
+
'aac': 'AAC',
|
124
|
+
'aac2': 'AAC2.0',
|
125
|
+
'aac5': 'AAC5.1',
|
126
|
+
'ac3': 'AC3',
|
127
|
+
'eac3': 'EAC3',
|
128
|
+
'dd': 'Dolby Digital',
|
129
|
+
'ddp': 'Dolby Digital Plus',
|
130
|
+
'ddp5': 'DDP5.1',
|
131
|
+
'truehd': 'TrueHD',
|
132
|
+
'dts': 'DTS',
|
133
|
+
'dtsma': 'DTS-HD MA',
|
134
|
+
'dtsx': 'DTS:X',
|
135
|
+
'atmos': 'Dolby Atmos',
|
136
|
+
'flac': 'FLAC',
|
137
|
+
'opus': 'Opus',
|
138
|
+
'mp3': 'MP3',
|
139
|
+
'lpcm': 'LPCM',
|
140
|
+
|
141
|
+
# Sources
|
142
|
+
'bluray': 'BluRay',
|
143
|
+
'brrip': 'BRRip',
|
144
|
+
'bdrip': 'BDRip',
|
145
|
+
'webrip': 'WEBRip',
|
146
|
+
'webdl': 'WEB-DL',
|
147
|
+
'hdtv': 'HDTV',
|
148
|
+
'dvdrip': 'DVDRip',
|
149
|
+
'dvdscr': 'DVDScr',
|
150
|
+
'r5': 'R5',
|
151
|
+
'cam': 'CAM',
|
152
|
+
'ts': 'TS',
|
153
|
+
'telesync': 'Telesync',
|
154
|
+
'telecine': 'Telecine',
|
155
|
+
'screener': 'Screener',
|
156
|
+
'vhsrip': 'VHSRip',
|
157
|
+
|
158
|
+
# Misc release tags
|
159
|
+
'remux': 'Remux',
|
160
|
+
'repack': 'Repack',
|
161
|
+
'rerip': 'ReRip',
|
162
|
+
'proper': 'Proper',
|
163
|
+
'uncut': 'Uncut',
|
164
|
+
'extended': 'Extended',
|
165
|
+
'directors': "Director's Cut",
|
166
|
+
'criterion': 'Criterion',
|
167
|
+
'uncensored': 'Uncensored',
|
168
|
+
'festival': 'Festival Cut',
|
169
|
+
'sample': 'Sample',
|
170
|
+
|
171
|
+
# Scene vanity / oddball
|
172
|
+
'1337x': '1337x',
|
173
|
+
'eztv': 'EZTV',
|
174
|
+
'torrentgalaxy': 'TorrentGalaxy',
|
175
|
+
'scene': 'Scene Release',
|
176
|
+
'internal': 'Internal',
|
177
|
+
'limited': 'Limited',
|
178
|
+
'complete': 'Complete Series',
|
179
|
+
'part': 'Part',
|
180
|
+
'dubbed': 'Dubbed',
|
181
|
+
'subbed': 'Subbed',
|
182
|
+
'multi': 'Multi Audio',
|
183
|
+
'dual': 'Dual Audio',
|
184
|
+
'retail': 'Retail Rip',
|
185
|
+
}
|
186
|
+
|
187
|
+
for k, v in tag_keywords.items():
|
188
|
+
if k in self.file_name:
|
189
|
+
extra.append(v)
|
190
|
+
|
191
|
+
if any(k in self.file_name for k in ['dolby', 'atmos']):
|
192
|
+
extra.append('DolbyAtmos')
|
193
|
+
|
194
|
+
match = re.search(r'\.(\d{3})$', file_name)
|
195
|
+
split = match is not None
|
196
|
+
part = int(match.group(1)) if split else None
|
197
|
+
|
198
|
+
return Movie(
|
199
|
+
title=self._fix_roman_numerals(title.title()),
|
200
|
+
normalized_title=re.sub(r'[^a-z0-9&\+]+', ' ', title.lower()).strip(),
|
201
|
+
year=year,
|
202
|
+
resolution=resolution,
|
203
|
+
quality=quality,
|
204
|
+
codec=codec,
|
205
|
+
extra=extra,
|
206
|
+
split=split,
|
207
|
+
part=part
|
208
|
+
)
|
209
|
+
|
210
|
+
parser = MovieParser()
|
211
|
+
|
d4rktg-0.3.4/VERSION.txt
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
0.3.4
|
@@ -1,92 +0,0 @@
|
|
1
|
-
import re
|
2
|
-
import PTN
|
3
|
-
import unicodedata
|
4
|
-
|
5
|
-
from typing import List, Optional
|
6
|
-
from dataclasses import dataclass, field
|
7
|
-
|
8
|
-
@dataclass
|
9
|
-
class Movie:
|
10
|
-
title: str
|
11
|
-
normalized_title: str
|
12
|
-
year: Optional[int]
|
13
|
-
resolution: Optional[str]
|
14
|
-
quality: Optional[str]
|
15
|
-
codec: Optional[str]
|
16
|
-
extra: List[str] = field(default_factory=list)
|
17
|
-
split: bool = False
|
18
|
-
part: Optional[int] = None
|
19
|
-
|
20
|
-
class MovieParser:
|
21
|
-
def __parse_file_name(self, file_name: str):
|
22
|
-
file_name = re.sub(r'@[\w_]+', '', file_name.lower()).strip()
|
23
|
-
file_name = file_name.replace('_', ' ')
|
24
|
-
self.file_name = file_name
|
25
|
-
self.extension = self.file_name.split('.')[-1]
|
26
|
-
self.movie = PTN.parse(self.file_name)
|
27
|
-
self.tags = []
|
28
|
-
|
29
|
-
def fallback_title(self, file_name):
|
30
|
-
name = re.sub(r'\.\w{2,4}$', '', file_name)
|
31
|
-
name = name.replace('_', ' ').replace('.', ' ')
|
32
|
-
name = re.sub(r'@\w+', '', name)
|
33
|
-
name = unicodedata.normalize('NFKC', name)
|
34
|
-
tags_pattern = r'\b(480p|720p|1080p|2160p|BR_Rip|WEBRip|HDRip|x264|x265|HEVC|AAC|DD\+?5\.1|[0-9]+MB|1GB|2GB|Tamil|Telugu|Hindi|English|Dubbed|HDTV|WEB-DL|BluRay|Blu-ray|YTS|YIFY|fps)\b'
|
35
|
-
name = re.sub(tags_pattern, '', name, flags=re.IGNORECASE)
|
36
|
-
name = re.split(r'\b(S\d+|Ep\d+)\b', name, 1)[0]
|
37
|
-
name = re.sub(r'\s+', ' ', name).strip()
|
38
|
-
return name
|
39
|
-
|
40
|
-
def fallback_year(self, file_name):
|
41
|
-
years = re.findall(r'(?<!\d)(19\d{2}|20\d{2})(?!\d)', file_name)
|
42
|
-
return int(years[0]) if years else None
|
43
|
-
|
44
|
-
def _fix_roman_numerals(self, text: str) -> str:
|
45
|
-
roman_pattern = r'\b(i{1,3}|iv|v|vi{0,3}|ix|x{1,3}|xl|l|li{0,3}|lx|xc|c|ci{0,3}|cd|d|dc|cm|m|m{1,3})\b'
|
46
|
-
return re.sub(roman_pattern, lambda m: m.group(0).upper(), text, flags=re.IGNORECASE)
|
47
|
-
|
48
|
-
def extract(self, file_name: str) -> Movie:
|
49
|
-
|
50
|
-
self.__parse_file_name(file_name)
|
51
|
-
title = self.movie.get('title', '').replace('.', ' ').strip()
|
52
|
-
if not title:title = self.fallback_title(self.file_name)
|
53
|
-
else:title = title.replace('.', ' ').strip()
|
54
|
-
|
55
|
-
year = self.movie.get('year') or self.fallback_year(self.file_name)
|
56
|
-
if year and str(year) in title:title = title.replace(str(year), '').strip()
|
57
|
-
|
58
|
-
resolution = self.movie.get('resolution')
|
59
|
-
quality = self.movie.get('quality')
|
60
|
-
codec = self.movie.get('codec')
|
61
|
-
if codec:codec = codec.replace('H', 'x').replace('.', '')
|
62
|
-
|
63
|
-
extra = []
|
64
|
-
tag_keywords = {
|
65
|
-
'psa': 'PSA', 'pahe': 'Pahe', 'galaxyrg': 'GalaxyRG',
|
66
|
-
'imax': 'IMAX', '60fps': '60FPS'
|
67
|
-
}
|
68
|
-
for k, v in tag_keywords.items():
|
69
|
-
if k in self.file_name:
|
70
|
-
extra.append(v)
|
71
|
-
|
72
|
-
if any(k in self.file_name for k in ['dolby', 'atmos']):
|
73
|
-
extra.append('DolbyAtmos')
|
74
|
-
|
75
|
-
match = re.search(r'\.(\d{3})$', file_name)
|
76
|
-
split = match is not None
|
77
|
-
part = int(match.group(1)) if split else None
|
78
|
-
|
79
|
-
return Movie(
|
80
|
-
title=self._fix_roman_numerals(title.title()),
|
81
|
-
normalized_title=re.sub(r'[^a-z0-9&\+]+', ' ', title.lower()).strip(),
|
82
|
-
year=year,
|
83
|
-
resolution=resolution,
|
84
|
-
quality=quality,
|
85
|
-
codec=codec,
|
86
|
-
extra=extra,
|
87
|
-
split=split,
|
88
|
-
part=part
|
89
|
-
)
|
90
|
-
|
91
|
-
parser = MovieParser()
|
92
|
-
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|