Unit3Dup 0.9.8__tar.gz → 0.9.10__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.
- {unit3dup-0.9.8 → unit3dup-0.9.10}/PKG-INFO +1 -1
- {unit3dup-0.9.8 → unit3dup-0.9.10}/Unit3Dup.egg-info/PKG-INFO +1 -1
- unit3dup-0.9.10/common/p2p_tags.py +328 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/settings.py +4 -4
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/utility.py +17 -1
- {unit3dup-0.9.8 → unit3dup-0.9.10}/pyproject.toml +1 -1
- unit3dup-0.9.8/common/p2p_tags.py +0 -371
- {unit3dup-0.9.8 → unit3dup-0.9.10}/LICENSE +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/README.rst +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/Unit3Dup.egg-info/SOURCES.txt +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/Unit3Dup.egg-info/dependency_links.txt +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/Unit3Dup.egg-info/entry_points.txt +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/Unit3Dup.egg-info/requires.txt +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/Unit3Dup.egg-info/top_level.txt +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/__init__.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/bdinfo_string.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/bittorrent.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/command.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/constants.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/database.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/external_services/__init__.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/external_services/ftpx/__init__.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/external_services/ftpx/client.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/external_services/ftpx/core/__init__.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/external_services/ftpx/core/ftpx_service.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/external_services/ftpx/core/ftpx_session.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/external_services/ftpx/core/menu.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/external_services/ftpx/core/models/__init__.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/external_services/ftpx/core/models/list.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/external_services/igdb/__init__.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/external_services/igdb/client.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/external_services/igdb/core/__init__.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/external_services/igdb/core/api.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/external_services/igdb/core/models/__init__.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/external_services/igdb/core/models/search.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/external_services/igdb/core/platformid.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/external_services/igdb/core/tags.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/external_services/imageHost.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/external_services/mediaresult.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/external_services/sessions/__init__.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/external_services/sessions/agents.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/external_services/sessions/exceptions.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/external_services/sessions/session.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/external_services/theMovieDB/__init__.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/external_services/theMovieDB/core/__init__.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/external_services/theMovieDB/core/api.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/external_services/theMovieDB/core/keywords.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/external_services/theMovieDB/core/models/__init__.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/external_services/theMovieDB/core/models/movie/__init__.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/external_services/theMovieDB/core/models/movie/alternative_titles.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/external_services/theMovieDB/core/models/movie/details.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/external_services/theMovieDB/core/models/movie/movie.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/external_services/theMovieDB/core/models/movie/nowplaying.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/external_services/theMovieDB/core/models/movie/release_info.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/external_services/theMovieDB/core/models/tvshow/__init__.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/external_services/theMovieDB/core/models/tvshow/alternative.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/external_services/theMovieDB/core/models/tvshow/details.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/external_services/theMovieDB/core/models/tvshow/on_the_air.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/external_services/theMovieDB/core/models/tvshow/translations.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/external_services/theMovieDB/core/models/tvshow/tvshow.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/external_services/theMovieDB/core/videos.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/external_services/trailers/__init__.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/external_services/trailers/api.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/external_services/trailers/response.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/external_services/tvdb.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/extractor.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/frames.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/mediainfo.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/mediainfo_string.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/title.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/torrent_clients.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/trackers/__init__.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/trackers/data.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/trackers/itt.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/trackers/sis.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/common/trackers/trackers.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/requirements.txt +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/setup.cfg +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/unit3dup/__init__.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/unit3dup/__main__.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/unit3dup/automode.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/unit3dup/bot.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/unit3dup/duplicate.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/unit3dup/exceptions.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/unit3dup/media.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/unit3dup/media_manager/ContentManager.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/unit3dup/media_manager/DocuManager.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/unit3dup/media_manager/GameManager.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/unit3dup/media_manager/MediaInfoManager.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/unit3dup/media_manager/SeedManager.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/unit3dup/media_manager/TorrentManager.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/unit3dup/media_manager/VideoManager.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/unit3dup/media_manager/__init__.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/unit3dup/media_manager/common.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/unit3dup/pvtDocu.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/unit3dup/pvtTorrent.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/unit3dup/pvtTracker.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/unit3dup/pvtVideo.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/unit3dup/torrent.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/unit3dup/upload.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/view/__init__.py +0 -0
- {unit3dup-0.9.8 → unit3dup-0.9.10}/view/custom_console.py +0 -0
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
import os
|
|
3
|
+
import re
|
|
4
|
+
from collections import deque
|
|
5
|
+
from common.utility import ManageTitles
|
|
6
|
+
from common.mediainfo import MediaFile
|
|
7
|
+
|
|
8
|
+
TAG_TYPES = {
|
|
9
|
+
"WEB-DL": "source",
|
|
10
|
+
"WEBDL": "source",
|
|
11
|
+
"WEB-DLMUX": "source",
|
|
12
|
+
"WEBDLMUX": "source",
|
|
13
|
+
"WEBMUX": "source",
|
|
14
|
+
"WEBRIP": "source",
|
|
15
|
+
"BD-UNTOUCHED": "source",
|
|
16
|
+
"REMUX": "source",
|
|
17
|
+
"VU": "source",
|
|
18
|
+
"UHD": "source",
|
|
19
|
+
"UHDRIP": "source",
|
|
20
|
+
"BLURAY": "source",
|
|
21
|
+
|
|
22
|
+
"AMZN": "platform",
|
|
23
|
+
"AMC": "platform",
|
|
24
|
+
"CN": "platform",
|
|
25
|
+
"CR": "platform",
|
|
26
|
+
"DCU": "platform",
|
|
27
|
+
"DISC": "platform",
|
|
28
|
+
"DSCP": "platform",
|
|
29
|
+
"DSNY": "platform",
|
|
30
|
+
"DSNP": "platform",
|
|
31
|
+
"DPLY": "platform",
|
|
32
|
+
"ESPN": "platform",
|
|
33
|
+
"FOOD": "platform",
|
|
34
|
+
"FOX": "platform",
|
|
35
|
+
"PLAY": "platform",
|
|
36
|
+
"HBO": "platform",
|
|
37
|
+
"HMAX": "platform",
|
|
38
|
+
"HGTV": "platform",
|
|
39
|
+
"HIST": "platform",
|
|
40
|
+
"HULU": "platform",
|
|
41
|
+
"MTOD": "platform",
|
|
42
|
+
"NATG": "platform",
|
|
43
|
+
"NF": "platform",
|
|
44
|
+
"NICK": "platform",
|
|
45
|
+
"NOW": "platform",
|
|
46
|
+
"PMNT": "platform",
|
|
47
|
+
"PMTP": "platform",
|
|
48
|
+
"PCOK": "platform",
|
|
49
|
+
"RKTN": "platform",
|
|
50
|
+
"SHO": "platform",
|
|
51
|
+
"SKST": "platform",
|
|
52
|
+
"STAN": "platform",
|
|
53
|
+
"STRP": "platform",
|
|
54
|
+
"STZ": "platform",
|
|
55
|
+
"TIMV": "platform",
|
|
56
|
+
|
|
57
|
+
"ITA": "flag",
|
|
58
|
+
"ENG": "flag",
|
|
59
|
+
"FRA": "flag",
|
|
60
|
+
"GER": "flag",
|
|
61
|
+
"ESP": "flag",
|
|
62
|
+
"JPN": "flag",
|
|
63
|
+
"JAP": "flag",
|
|
64
|
+
"POR": "flag",
|
|
65
|
+
"PRT": "flag",
|
|
66
|
+
|
|
67
|
+
"SUB": "subtitle",
|
|
68
|
+
"SUBS": "subtitle",
|
|
69
|
+
|
|
70
|
+
"ATMOS": "audio",
|
|
71
|
+
"TRUEHD": "audio",
|
|
72
|
+
"DTSHD": "audio",
|
|
73
|
+
"DTS-HD": "audio",
|
|
74
|
+
"DTS-HD MA": "audio",
|
|
75
|
+
"DDP7.1": "audio",
|
|
76
|
+
"DDP5.1": "audio",
|
|
77
|
+
"DDP2.0": "audio",
|
|
78
|
+
"DTS": "audio",
|
|
79
|
+
"XLL": "audio",
|
|
80
|
+
"DD7.1": "audio",
|
|
81
|
+
"DD5.1": "audio",
|
|
82
|
+
"DD2.0": "audio",
|
|
83
|
+
"DD+ 7.1": "audio",
|
|
84
|
+
"DD+ 5.1": "audio",
|
|
85
|
+
"DD+ 2.0": "audio",
|
|
86
|
+
"DTS-HD MA 7.1": "audio",
|
|
87
|
+
"DTS-HD MA 5.1": "audio",
|
|
88
|
+
"DTS-HD MA 2.0": "audio",
|
|
89
|
+
"DD 7.1": "audio",
|
|
90
|
+
"DD 5.1": "audio",
|
|
91
|
+
"DD 2.0": "audio",
|
|
92
|
+
"AAC2.0": "audio",
|
|
93
|
+
"AAC5.1": "audio",
|
|
94
|
+
"AC3": "audio",
|
|
95
|
+
"DD": "audio",
|
|
96
|
+
"DD+": "audio",
|
|
97
|
+
"DDP": "audio",
|
|
98
|
+
"E-AC3": "audio",
|
|
99
|
+
"EAC3": "audio",
|
|
100
|
+
"AC-3": "audio",
|
|
101
|
+
"AAC": "audio",
|
|
102
|
+
"AVC": "audio",
|
|
103
|
+
|
|
104
|
+
"7.1": "channels",
|
|
105
|
+
"5.1": "channels",
|
|
106
|
+
"2.0": "channels",
|
|
107
|
+
|
|
108
|
+
"H.264": "video",
|
|
109
|
+
"X.264": "video",
|
|
110
|
+
"X264": "video",
|
|
111
|
+
"H264": "video",
|
|
112
|
+
"H.265": "video",
|
|
113
|
+
"X.265": "video",
|
|
114
|
+
"X265": "video",
|
|
115
|
+
"H265": "video",
|
|
116
|
+
"HEVC": "video",
|
|
117
|
+
"DV": "video",
|
|
118
|
+
"HDR10": "video",
|
|
119
|
+
"DVHDR10": "video",
|
|
120
|
+
"DVHDR": "video",
|
|
121
|
+
"HDRPLUS+": "video",
|
|
122
|
+
"HDR10PLUS": "video",
|
|
123
|
+
"HDR": "video",
|
|
124
|
+
"HDR10+": "video",
|
|
125
|
+
"FHDRIP": "video",
|
|
126
|
+
"FULL HD": "video",
|
|
127
|
+
"FULLHD": "video",
|
|
128
|
+
"HD": "video",
|
|
129
|
+
"UHD 4K": "video",
|
|
130
|
+
|
|
131
|
+
"REPACK": "version",
|
|
132
|
+
"EXTENDED": "version",
|
|
133
|
+
|
|
134
|
+
"4320P": "resolution",
|
|
135
|
+
"2160P": "resolution",
|
|
136
|
+
"1080P": "resolution",
|
|
137
|
+
"720P": "resolution",
|
|
138
|
+
"576P": "resolution",
|
|
139
|
+
"480P": "resolution",
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
class P2pTags:
|
|
144
|
+
def __init__(
|
|
145
|
+
self, filename: str, title: str, year: str, mediafile_resolution: str,
|
|
146
|
+
season: int, episode: int, episode_title: str, releaser_sign: str,
|
|
147
|
+
tags_position: list, mediafile: MediaFile
|
|
148
|
+
):
|
|
149
|
+
self.filename = filename
|
|
150
|
+
self.title = title
|
|
151
|
+
self.year = year
|
|
152
|
+
self.mediafile_resolution = mediafile_resolution
|
|
153
|
+
self.season = season
|
|
154
|
+
self.episode = episode
|
|
155
|
+
self.episode_title = episode_title
|
|
156
|
+
self.releaser_sign = releaser_sign
|
|
157
|
+
self.mediafile = mediafile
|
|
158
|
+
self.tags_position = tags_position
|
|
159
|
+
self.sign_in_title: str | None = None
|
|
160
|
+
|
|
161
|
+
self.tags_sorted = self._extract_tags()
|
|
162
|
+
|
|
163
|
+
def _extract_tags(self) -> list:
|
|
164
|
+
search_tags = sorted(TAG_TYPES.keys(), key=len, reverse=True)
|
|
165
|
+
pattern = re.compile(r'\b(?:' + '|'.join(map(re.escape, search_tags)) + r')\b', re.IGNORECASE)
|
|
166
|
+
|
|
167
|
+
# Search for tags in the title
|
|
168
|
+
tags_match = list(dict.fromkeys(pattern.findall(self.filename)))
|
|
169
|
+
# Search for channels
|
|
170
|
+
ch = ''
|
|
171
|
+
if self.mediafile.audio_track:
|
|
172
|
+
channel_s = self.mediafile.audio_track[0].get('channel_s', 0)
|
|
173
|
+
ch = {2: "2.0", 6: "5.1", 8: "7.1"}.get(channel_s, "")
|
|
174
|
+
|
|
175
|
+
# Categories of found tags
|
|
176
|
+
categories = [TAG_TYPES.get(tag.upper()) for tag in tags_match]
|
|
177
|
+
# Add video codec only if there is no video categories
|
|
178
|
+
if 'video' not in categories and self.mediafile.video_track:
|
|
179
|
+
video_codec = self.mediafile.video_track[0].get('format', "")
|
|
180
|
+
if video_codec:
|
|
181
|
+
tags_match.append(video_codec)
|
|
182
|
+
|
|
183
|
+
# Add audio codec only if there is no video categories
|
|
184
|
+
if 'audio' not in categories and self.mediafile.audio_track:
|
|
185
|
+
for audio in self.mediafile.audio_track:
|
|
186
|
+
# Other_format https://github.com/sbraz/pymediainfo/discussions/119#discussioncomment-2330673
|
|
187
|
+
# con format mi restituisce solo DTS
|
|
188
|
+
# Use other_format per format che hanno uno o piu tag
|
|
189
|
+
other_format = audio.get('other_format', [])
|
|
190
|
+
if other_format:
|
|
191
|
+
tags_match.append(other_format[0])
|
|
192
|
+
|
|
193
|
+
# Add tag language if there is no tag
|
|
194
|
+
flags = self._audio_lang()
|
|
195
|
+
missing_flags = [tag for tag in flags if tag not in tags_match]
|
|
196
|
+
tags_match.extend(missing_flags)
|
|
197
|
+
|
|
198
|
+
# Add subtitle tag if subtitle_track exist and there is no 'sub' in the title
|
|
199
|
+
if 'subtitle' not in categories and self.mediafile.subtitle_track:
|
|
200
|
+
tags_match.append("SUBS" if len(self.mediafile.subtitle_track) > 1 else "SUB")
|
|
201
|
+
|
|
202
|
+
return self._normalize_tags(tags_match, ch)
|
|
203
|
+
|
|
204
|
+
def _audio_lang(self) -> set:
|
|
205
|
+
if not self.mediafile:
|
|
206
|
+
return set()
|
|
207
|
+
langs = set()
|
|
208
|
+
for track in self.mediafile.audio_track:
|
|
209
|
+
for l in track.get('other_language', []):
|
|
210
|
+
c = ManageTitles.convert_iso(l)
|
|
211
|
+
if c:
|
|
212
|
+
if isinstance(c, list):
|
|
213
|
+
langs.update(c)
|
|
214
|
+
else:
|
|
215
|
+
langs.update(c)
|
|
216
|
+
break
|
|
217
|
+
return langs
|
|
218
|
+
|
|
219
|
+
def _normalize_tags(self, tags_match: list, channel_tag: str) -> list:
|
|
220
|
+
audio_translate = {
|
|
221
|
+
"AC3": "DD",
|
|
222
|
+
"AC-3": "DD",
|
|
223
|
+
"EAC3": "DD+",
|
|
224
|
+
"E-AC3": "DD+",
|
|
225
|
+
"DDP2.0": "DD+",
|
|
226
|
+
"DDP5.1": "DD+",
|
|
227
|
+
"DDP7.1": "DD+",
|
|
228
|
+
"DDP": "DD+",
|
|
229
|
+
"DTS XLL": "DTS-HD MA",
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
video_translate = {
|
|
233
|
+
"x264": "H.264",
|
|
234
|
+
"X.264": "H.264",
|
|
235
|
+
"X264": "H.264",
|
|
236
|
+
"AVC": "H.264",
|
|
237
|
+
"HEVC": "H.265",
|
|
238
|
+
"H265": "H.265",
|
|
239
|
+
"X.265": "H.265",
|
|
240
|
+
"X265": "H.265",
|
|
241
|
+
"x265": "H.265",
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
resolution_lower = {"4320P", "2160P", "1080P", "720P", "576P", "480P"}
|
|
245
|
+
codec_lower = {"X.264", "X265", "X.265", "X264"}
|
|
246
|
+
|
|
247
|
+
# verify the tags found in the title
|
|
248
|
+
normalized = []
|
|
249
|
+
for tag in tags_match:
|
|
250
|
+
t = tag.upper()
|
|
251
|
+
if t in audio_translate:
|
|
252
|
+
codec = audio_translate[t]
|
|
253
|
+
tag = f"{codec} {channel_tag}" if channel_tag else codec
|
|
254
|
+
elif t in video_translate:
|
|
255
|
+
tag = video_translate[t]
|
|
256
|
+
elif t in resolution_lower or t in codec_lower:
|
|
257
|
+
tag = t.lower()
|
|
258
|
+
elif t == "SUB":
|
|
259
|
+
tag = "SUBS" if len(self.mediafile.subtitle_track) > 1 else "SUB"
|
|
260
|
+
normalized.append(tag)
|
|
261
|
+
|
|
262
|
+
# Check if a 'resolution' tag exists and add mediafile resolution if it doesn't
|
|
263
|
+
if not any(TAG_TYPES.get(tag.upper()) == "resolution" for tag in normalized):
|
|
264
|
+
normalized.append(self.mediafile_resolution)
|
|
265
|
+
|
|
266
|
+
# Sort and alternate audio/flag tags
|
|
267
|
+
return self._sort_tags(normalized, channel_tag)
|
|
268
|
+
|
|
269
|
+
def _sort_tags(self, tags: list, channel_tag: str) -> list:
|
|
270
|
+
# /// Sort tags based on 2 rules:
|
|
271
|
+
# 1) Order by tag_positions
|
|
272
|
+
# 2) For audio and flag categories alternate them (audio/flag/audio/flag)
|
|
273
|
+
# We can't sort each tags so we create dedicated list
|
|
274
|
+
audio_q, flag_q, channel_q = deque(), deque(), deque()
|
|
275
|
+
other_groups = {}
|
|
276
|
+
|
|
277
|
+
for tag in tags:
|
|
278
|
+
cat = TAG_TYPES.get(tag.upper(), "unknown")
|
|
279
|
+
if cat == "audio":
|
|
280
|
+
audio_q.append(tag.upper())
|
|
281
|
+
elif cat == "channels":
|
|
282
|
+
channel_q.append(tag)
|
|
283
|
+
elif cat == "flag":
|
|
284
|
+
flag_q.append(tag.upper())
|
|
285
|
+
elif cat == "video":
|
|
286
|
+
other_groups.setdefault(cat, []).append(tag.upper())
|
|
287
|
+
else:
|
|
288
|
+
other_groups.setdefault(cat, []).append(tag)
|
|
289
|
+
|
|
290
|
+
# Alternate only if we have at least 2 audio and 2 flag tags
|
|
291
|
+
mixed = []
|
|
292
|
+
if len(audio_q) >= 2 and len(flag_q) >= 2:
|
|
293
|
+
while audio_q or flag_q:
|
|
294
|
+
if audio_q: mixed.append(audio_q.popleft())
|
|
295
|
+
if channel_q: mixed.append(channel_q.popleft())
|
|
296
|
+
if flag_q: mixed.append(flag_q.popleft())
|
|
297
|
+
else:
|
|
298
|
+
mixed = list(audio_q) + list(channel_q) + list(flag_q)
|
|
299
|
+
|
|
300
|
+
result = []
|
|
301
|
+
for cat in self.tags_position:
|
|
302
|
+
if cat in ("audio", "channels", "flag") and mixed:
|
|
303
|
+
result.extend(mixed)
|
|
304
|
+
mixed = []
|
|
305
|
+
elif cat in other_groups:
|
|
306
|
+
result.extend(other_groups[cat])
|
|
307
|
+
return result
|
|
308
|
+
|
|
309
|
+
def process(self) -> str:
|
|
310
|
+
se_str = ''
|
|
311
|
+
if self.season is not None and self.episode is not None:
|
|
312
|
+
se_str = f"S{self.season:02d}E{self.episode:02d}"
|
|
313
|
+
elif self.season is not None:
|
|
314
|
+
se_str = f"S{self.season:02d}"
|
|
315
|
+
elif self.episode is not None:
|
|
316
|
+
se_str = f"E{self.episode:02d}"
|
|
317
|
+
|
|
318
|
+
# Detect releaser sign in filename if not provided
|
|
319
|
+
if not self.releaser_sign:
|
|
320
|
+
filename, _ = os.path.splitext(os.path.basename(self.filename))
|
|
321
|
+
m = re.search(r'-([A-Za-z0-9]+)$', filename)
|
|
322
|
+
self.sign_in_title = f"-{m.group(1)}" if m and m.group(1) not in TAG_TYPES else ""
|
|
323
|
+
else:
|
|
324
|
+
self.sign_in_title = f"-{self.releaser_sign}"
|
|
325
|
+
|
|
326
|
+
parts = [self.title, str(self.year), se_str]
|
|
327
|
+
filtered_parts = [p for p in parts if p]
|
|
328
|
+
return f"{' '.join(filtered_parts)} {' '.join(self.tags_sorted)}{self.sign_in_title}"
|
|
@@ -15,7 +15,7 @@ from common.utility import ManageTitles
|
|
|
15
15
|
from common import trackers
|
|
16
16
|
|
|
17
17
|
config_file = "Unit3Dbot.json"
|
|
18
|
-
version = "0.9.
|
|
18
|
+
version = "0.9.10"
|
|
19
19
|
|
|
20
20
|
if os.name == "nt":
|
|
21
21
|
WATCHER_DESTINATION_PATH: Path = Path(os.getenv("LOCALAPPDATA", ".")) / "Unit3Dup_config" / "watcher_destination_path"
|
|
@@ -250,12 +250,12 @@ class Validate:
|
|
|
250
250
|
print(f"-> Invalid TAG position. The list is empty !")
|
|
251
251
|
exit(1)
|
|
252
252
|
|
|
253
|
-
if len(position_list) !=
|
|
253
|
+
if len(position_list) != 9:
|
|
254
254
|
print(f"-> Invalid TAG position list. Wrong number of elements !")
|
|
255
255
|
exit(1)
|
|
256
256
|
|
|
257
257
|
for tag in position_list:
|
|
258
|
-
if tag.lower() not in ["resolution", "source", "audio", "channels", "flag", "subtitle", "video"]:
|
|
258
|
+
if tag.lower() not in ["version","resolution", "platform","source", "audio", "channels", "flag", "subtitle", "video"]:
|
|
259
259
|
print(f"-> Invalid TAG position '{tag}'. Please fix your configuration file")
|
|
260
260
|
exit(1)
|
|
261
261
|
|
|
@@ -578,7 +578,7 @@ class Load:
|
|
|
578
578
|
"PASSIMA_PRIORITY": 5,
|
|
579
579
|
"IMARIDE_PRIORITY": 6,
|
|
580
580
|
"NUMBER_OF_SCREENSHOTS": 4,
|
|
581
|
-
"TAGS_POSITION": ["resolution", "source", "audio", "channels", "flag", "subtitle", "video"],
|
|
581
|
+
"TAGS_POSITION": ["version","resolution", "platform", "source", "audio", "channels", "flag", "subtitle", "video"],
|
|
582
582
|
"YOUTUBE_FAV_CHANNEL_ID": "UCGCbxpnt25hWPFLSbvwfg_w",
|
|
583
583
|
"YOUTUBE_CHANNEL_ENABLE": "False",
|
|
584
584
|
"DUPLICATE_ON": "true",
|
|
@@ -43,17 +43,33 @@ class ManageTitles:
|
|
|
43
43
|
"ES-MX": "ESP"
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
# From mediainfo
|
|
47
|
+
long_name = {
|
|
48
|
+
"ENGLISH": "ENG",
|
|
49
|
+
"ITALIAN": "ITA",
|
|
50
|
+
"GERMAN": "DEU",
|
|
51
|
+
"FRENCH": "FRA",
|
|
52
|
+
"SPANISH": "ESP",
|
|
53
|
+
"JAPANESE": "JPN",
|
|
54
|
+
"BRAZILIAN": "BRA",
|
|
55
|
+
"RUSSIAN": "RUS",
|
|
56
|
+
"CHINESE": "CHN",
|
|
57
|
+
"AMERICAN": "USA",
|
|
58
|
+
"BRITISH": "GBR"
|
|
59
|
+
}
|
|
46
60
|
@staticmethod
|
|
47
61
|
def convert_iso(code) -> list | str | None:
|
|
48
62
|
""" Convert iso 2 to 3 """
|
|
49
63
|
code = code.upper()
|
|
50
|
-
|
|
51
64
|
# if it's 'multilang'
|
|
52
65
|
if '-' in code:
|
|
53
66
|
codes = code.split('-')
|
|
54
67
|
else:
|
|
55
68
|
codes = [code]
|
|
56
69
|
|
|
70
|
+
if code in ManageTitles.long_name:
|
|
71
|
+
codes = [ManageTitles.long_name[code]]
|
|
72
|
+
|
|
57
73
|
result = []
|
|
58
74
|
for part in codes:
|
|
59
75
|
# Capture the 2 or 3 letter code followed by '-' or end string
|
|
@@ -1,371 +0,0 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
import os
|
|
3
|
-
import re
|
|
4
|
-
from common.utility import ManageTitles
|
|
5
|
-
from common.mediainfo import MediaFile
|
|
6
|
-
from collections import deque
|
|
7
|
-
|
|
8
|
-
TAG_TYPES = {
|
|
9
|
-
"WEB-DL": "source",
|
|
10
|
-
"WEBDL": "source",
|
|
11
|
-
"WEB-DLMUX": "source",
|
|
12
|
-
"WEBDLMUX": "source",
|
|
13
|
-
"WEBMUX": "source",
|
|
14
|
-
"WEBRIP": "source",
|
|
15
|
-
"BD-UNTOUCHED": "source",
|
|
16
|
-
"REMUX": "source",
|
|
17
|
-
"VU": "source",
|
|
18
|
-
"UHD": "source",
|
|
19
|
-
"BLURAY": "source",
|
|
20
|
-
"AMZN": "source",
|
|
21
|
-
"AMC": "source",
|
|
22
|
-
"CN": "source",
|
|
23
|
-
"CR": "source",
|
|
24
|
-
"DCU": "source",
|
|
25
|
-
"DISC": "source",
|
|
26
|
-
"DSCP": "source",
|
|
27
|
-
"DSNY": "source",
|
|
28
|
-
"DSNP": "source",
|
|
29
|
-
"DPLY": "source",
|
|
30
|
-
"ESPN": "source",
|
|
31
|
-
"FOOD": "source",
|
|
32
|
-
"FOX": "source",
|
|
33
|
-
"PLAY": "source",
|
|
34
|
-
"HBO": "source",
|
|
35
|
-
"HMAX": "source",
|
|
36
|
-
"HGTV": "source",
|
|
37
|
-
"HIST": "source",
|
|
38
|
-
"HULU": "source",
|
|
39
|
-
"MTOD": "source",
|
|
40
|
-
"NATG": "source",
|
|
41
|
-
"NF": "source",
|
|
42
|
-
"NICK": "source",
|
|
43
|
-
"NOW": "source",
|
|
44
|
-
"PMNT": "source",
|
|
45
|
-
"PMTP": "source",
|
|
46
|
-
"PCOK": "source",
|
|
47
|
-
"RKTN": "source",
|
|
48
|
-
"SHO": "source",
|
|
49
|
-
"SKST": "source",
|
|
50
|
-
"STAN": "source",
|
|
51
|
-
"STRP": "source",
|
|
52
|
-
"STZ": "source",
|
|
53
|
-
"TIMV": "source",
|
|
54
|
-
|
|
55
|
-
"SUB": "subtitle",
|
|
56
|
-
"SUBS": "subtitle",
|
|
57
|
-
"ITA": "flag",
|
|
58
|
-
"ENG": "flag",
|
|
59
|
-
"FRA": "flag",
|
|
60
|
-
"GER": "flag",
|
|
61
|
-
"ESP": "flag",
|
|
62
|
-
"JPN": "flag",
|
|
63
|
-
"JAP": "flag",
|
|
64
|
-
"POR": "flag",
|
|
65
|
-
"PRT": "flag",
|
|
66
|
-
|
|
67
|
-
"ATMOS": "audio",
|
|
68
|
-
"TRUEHD": "audio",
|
|
69
|
-
"DTSHD": "audio",
|
|
70
|
-
"DTS-HD": "audio",
|
|
71
|
-
"DTS-HD MA": "audio",
|
|
72
|
-
"DDP7.1": "audio",
|
|
73
|
-
"DDP5.1": "audio",
|
|
74
|
-
"DDP2.0": "audio",
|
|
75
|
-
"DTS": "audio",
|
|
76
|
-
|
|
77
|
-
"DD7.1": "audio",
|
|
78
|
-
"DD5.1": "audio",
|
|
79
|
-
"DD2.0": "audio",
|
|
80
|
-
|
|
81
|
-
"DD+ 7.1": "audio",
|
|
82
|
-
"DD+ 5.1": "audio",
|
|
83
|
-
"DD+ 2.0": "audio",
|
|
84
|
-
|
|
85
|
-
"DD 7.1": "audio",
|
|
86
|
-
"DD 5.1": "audio",
|
|
87
|
-
"DD 2.0": "audio",
|
|
88
|
-
|
|
89
|
-
"AAC2.0": "audio",
|
|
90
|
-
"AAC5.1": "audio",
|
|
91
|
-
"AC3": "audio",
|
|
92
|
-
"DD": "audio",
|
|
93
|
-
"DD+": "audio",
|
|
94
|
-
"DDP": "audio",
|
|
95
|
-
"E-AC3": "audio",
|
|
96
|
-
"EAC3": "audio",
|
|
97
|
-
"AC-3": "audio",
|
|
98
|
-
"AAC": "audio",
|
|
99
|
-
"AVC": "audio",
|
|
100
|
-
|
|
101
|
-
"7.1": "channels",
|
|
102
|
-
"5.1": "channels",
|
|
103
|
-
"2.0": "channels",
|
|
104
|
-
|
|
105
|
-
"H.264": "video",
|
|
106
|
-
"X.264": "video",
|
|
107
|
-
"X264": "video",
|
|
108
|
-
"H264": "video",
|
|
109
|
-
"H.265": "video",
|
|
110
|
-
"X.265": "video",
|
|
111
|
-
"X265": "video",
|
|
112
|
-
"H265": "video",
|
|
113
|
-
"HEVC": "video",
|
|
114
|
-
"DV": "video",
|
|
115
|
-
"HDR10": "video",
|
|
116
|
-
"DVHDR10": "video",
|
|
117
|
-
"DVHDR": "video",
|
|
118
|
-
"HDRPLUS+": "video",
|
|
119
|
-
"HDR10PLUS": "video",
|
|
120
|
-
"HDR": "video",
|
|
121
|
-
"HDR10+": "video",
|
|
122
|
-
"FHDRIP": "video",
|
|
123
|
-
"UHDRIP": "video",
|
|
124
|
-
"FULL HD": "video",
|
|
125
|
-
"FULLHD": "video",
|
|
126
|
-
"HD": "video",
|
|
127
|
-
"UHD 4K": "video",
|
|
128
|
-
|
|
129
|
-
"4320P": "resolution",
|
|
130
|
-
"2160P": "resolution",
|
|
131
|
-
"1080P": "resolution",
|
|
132
|
-
"720P": "resolution",
|
|
133
|
-
"576P": "resolution",
|
|
134
|
-
"480P": "resolution",
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
class P2pTags:
|
|
139
|
-
def __init__(self, filename: str, title: str, year: str, mediafile_resolution: str, season: int, episode: int,
|
|
140
|
-
episode_title: str, releaser_sign: str, tags_position: list, mediafile: MediaFile):
|
|
141
|
-
|
|
142
|
-
self.filename = filename
|
|
143
|
-
self.title = title
|
|
144
|
-
self.year = year
|
|
145
|
-
self.mediafile_resolution = mediafile_resolution
|
|
146
|
-
self.season = season
|
|
147
|
-
self.episode = episode
|
|
148
|
-
self.episode_title = episode_title
|
|
149
|
-
self.releaser_sign = releaser_sign
|
|
150
|
-
self.mediafile = mediafile
|
|
151
|
-
self.tags_position = tags_position
|
|
152
|
-
self.sign_in_title: str | None = None
|
|
153
|
-
|
|
154
|
-
search_tags = sorted(TAG_TYPES.keys(), key=len, reverse=True)
|
|
155
|
-
pattern = re.compile(
|
|
156
|
-
r'\b(?:' + '|'.join(map(re.escape, search_tags)) + r')\b',
|
|
157
|
-
re.IGNORECASE
|
|
158
|
-
)
|
|
159
|
-
|
|
160
|
-
# Search for tags in the title
|
|
161
|
-
tags_match = pattern.findall(filename.upper())
|
|
162
|
-
# remove dope
|
|
163
|
-
tags_match = list(dict.fromkeys(tags_match))
|
|
164
|
-
|
|
165
|
-
# Search for channels
|
|
166
|
-
channel_s = self.mediafile.audio_track[0].get('channel_s', None)
|
|
167
|
-
ch: str = ''
|
|
168
|
-
# map channels
|
|
169
|
-
if channel_s == 6:
|
|
170
|
-
ch = "5.1"
|
|
171
|
-
elif channel_s == 8:
|
|
172
|
-
ch = "7.1"
|
|
173
|
-
elif channel_s == 2:
|
|
174
|
-
ch = "2.0"
|
|
175
|
-
|
|
176
|
-
# extract categories results
|
|
177
|
-
categories = [TAG_TYPES.get(tag) for tag in tags_match]
|
|
178
|
-
|
|
179
|
-
# Add video codec only if there is no video categories
|
|
180
|
-
if 'video' not in categories:
|
|
181
|
-
video_codec = self.mediafile.video_track[0].get('format', "") if self.mediafile.video_track else ""
|
|
182
|
-
tags_match.append(video_codec)
|
|
183
|
-
|
|
184
|
-
# Add audio codec only if there is no audio categories
|
|
185
|
-
if 'audio' not in categories:
|
|
186
|
-
audio_format = self.mediafile.audio_track[0].get('format', "") if self.mediafile.audio_track else ""
|
|
187
|
-
tags_match.append(audio_format)
|
|
188
|
-
|
|
189
|
-
# Add tag language if there is no tag
|
|
190
|
-
flags = self._audio_lang()
|
|
191
|
-
# are all the language tags from mediaInfo available in the title?
|
|
192
|
-
if len(flags) != tags_match.count('flag'):
|
|
193
|
-
missing_flags = [tag for tag in flags if tag not in tags_match]
|
|
194
|
-
tags_match.extend(missing_flags)
|
|
195
|
-
|
|
196
|
-
# Add subtitle tag if subtitle_track exist and there is no 'sub' in the title
|
|
197
|
-
if 'subtitle' not in categories:
|
|
198
|
-
sub_tag = "SUBS" if len(self.mediafile.subtitle_track) > 1 else "SUB"
|
|
199
|
-
if self.mediafile.subtitle_track:
|
|
200
|
-
tags_match.append(sub_tag)
|
|
201
|
-
|
|
202
|
-
# Translate audio codec
|
|
203
|
-
audio_translate = {
|
|
204
|
-
"AC3": "DD",
|
|
205
|
-
"AC-3": "DD",
|
|
206
|
-
"EAC3": "DD+",
|
|
207
|
-
"E-AC3": "DD+",
|
|
208
|
-
"DDP2.0": "DD+",
|
|
209
|
-
"DDP5.1": "DD+",
|
|
210
|
-
"DDP7.1": "DD+",
|
|
211
|
-
"DDP": "DD+",
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
# Translate video codec
|
|
215
|
-
video_translate = {
|
|
216
|
-
"H.264": "x264",
|
|
217
|
-
"X.264": "x264",
|
|
218
|
-
"X264": "x264",
|
|
219
|
-
"AVC": "x264",
|
|
220
|
-
"H.265": "x265",
|
|
221
|
-
"H265": "x265",
|
|
222
|
-
"X.265": "x265",
|
|
223
|
-
"X265": "x265",
|
|
224
|
-
"HEVC": "x265",
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
# lower the res..
|
|
228
|
-
resolution_lower = {"4320P", "2160P", "1080P", "720P", "576P", "480P"}
|
|
229
|
-
codec_lower = {'X.264', 'X265', 'X.265', 'X264'}
|
|
230
|
-
|
|
231
|
-
has_channel_tag = ch in tags_match
|
|
232
|
-
new_tags = []
|
|
233
|
-
|
|
234
|
-
# verify the tags found in the title
|
|
235
|
-
for tag in tags_match:
|
|
236
|
-
t = tag.upper()
|
|
237
|
-
if t in audio_translate:
|
|
238
|
-
codec = audio_translate[t]
|
|
239
|
-
# Add channels only if it does not exist
|
|
240
|
-
if ch and not has_channel_tag:
|
|
241
|
-
tag = f"{codec} {ch}"
|
|
242
|
-
else:
|
|
243
|
-
tag = codec
|
|
244
|
-
|
|
245
|
-
elif t in video_translate:
|
|
246
|
-
tag = video_translate[t]
|
|
247
|
-
|
|
248
|
-
# Lower the res
|
|
249
|
-
elif t in resolution_lower:
|
|
250
|
-
tag = t.lower()
|
|
251
|
-
|
|
252
|
-
# Fix the 'sub' word
|
|
253
|
-
elif t == "SUB":
|
|
254
|
-
sub_tag = "SUBS" if len(self.mediafile.subtitle_track) > 1 else "SUB"
|
|
255
|
-
tag = sub_tag
|
|
256
|
-
|
|
257
|
-
elif t in codec_lower:
|
|
258
|
-
tag = t.lower()
|
|
259
|
-
|
|
260
|
-
new_tags.append(tag)
|
|
261
|
-
|
|
262
|
-
tags_match = new_tags
|
|
263
|
-
|
|
264
|
-
# Check if a 'resolution' tag exists and add mediafile resolution if it doesn't
|
|
265
|
-
if not any(TAG_TYPES.get(tag.upper()) == "resolution" for tag in tags_match):
|
|
266
|
-
tags_match.append(self.mediafile_resolution)
|
|
267
|
-
|
|
268
|
-
# /// Sort tags based on 2 rules:
|
|
269
|
-
# 1) Order by tag_positions
|
|
270
|
-
# 2) For audio and flag categories alternate them (audio/flag/audio/flag)
|
|
271
|
-
# We can't sort each tags so we create dedicated list
|
|
272
|
-
audio_q = deque()
|
|
273
|
-
flag_q = deque()
|
|
274
|
-
channel_q = deque()
|
|
275
|
-
|
|
276
|
-
# This dict is for other categories
|
|
277
|
-
other_groups = {}
|
|
278
|
-
|
|
279
|
-
# Isolate audio and flag tags
|
|
280
|
-
# All other tags will follow the normal precedence order
|
|
281
|
-
for tag in tags_match:
|
|
282
|
-
cat = TAG_TYPES.get(tag.upper(), "unknown")
|
|
283
|
-
if cat == "audio":
|
|
284
|
-
# Add audio tag to its queue
|
|
285
|
-
audio_q.append(tag)
|
|
286
|
-
elif cat == "channels":
|
|
287
|
-
channel_q.append(tag)
|
|
288
|
-
elif cat == "flag":
|
|
289
|
-
# Add flag tag to its queue
|
|
290
|
-
flag_q.append(tag)
|
|
291
|
-
else:
|
|
292
|
-
# Add the other tags to other_groups
|
|
293
|
-
other_groups.setdefault(cat, []).append(tag)
|
|
294
|
-
|
|
295
|
-
# Alternate only if we have at least 2 audio and 2 flag tags
|
|
296
|
-
if len(audio_q) >= 2 and len(flag_q) >= 2:
|
|
297
|
-
mixed_audio_ch_flag = []
|
|
298
|
-
# Alternate
|
|
299
|
-
while audio_q or flag_q:
|
|
300
|
-
if audio_q:
|
|
301
|
-
# get the first left audio and append to new list
|
|
302
|
-
mixed_audio_ch_flag.append(audio_q.popleft())
|
|
303
|
-
if channel_q:
|
|
304
|
-
mixed_audio_ch_flag.append(channel_q.popleft())
|
|
305
|
-
if flag_q:
|
|
306
|
-
# get the first right flag and append to new list
|
|
307
|
-
mixed_audio_ch_flag.append(flag_q.popleft())
|
|
308
|
-
else:
|
|
309
|
-
# otherwise goes for normal precedence
|
|
310
|
-
mixed_audio_ch_flag = list(audio_q) + list(channel_q) + list(flag_q)
|
|
311
|
-
|
|
312
|
-
# Rebuild the title ordering each tag+ audio/flag by tag_position
|
|
313
|
-
result = []
|
|
314
|
-
for cat in self.tags_position:
|
|
315
|
-
if cat in ("audio", "channels", "flag"):
|
|
316
|
-
# Insert the audio/flag processed tags
|
|
317
|
-
if mixed_audio_ch_flag:
|
|
318
|
-
result.extend(mixed_audio_ch_flag)
|
|
319
|
-
# clear
|
|
320
|
-
mixed_audio_ch_flag = []
|
|
321
|
-
elif cat in other_groups:
|
|
322
|
-
result.extend(other_groups[cat])
|
|
323
|
-
self.tags_sorted = result
|
|
324
|
-
|
|
325
|
-
def _audio_lang(self) -> list:
|
|
326
|
-
|
|
327
|
-
if not self.mediafile:
|
|
328
|
-
return []
|
|
329
|
-
|
|
330
|
-
lang: list = []
|
|
331
|
-
for track in self.mediafile.audio_track:
|
|
332
|
-
l = track.get('other_language', None)
|
|
333
|
-
if l:
|
|
334
|
-
for t in l:
|
|
335
|
-
c = ManageTitles.convert_iso(t)
|
|
336
|
-
if c:
|
|
337
|
-
if isinstance(c,list):
|
|
338
|
-
lang.extend(c)
|
|
339
|
-
break
|
|
340
|
-
else:
|
|
341
|
-
lang.append(c)
|
|
342
|
-
break
|
|
343
|
-
return lang
|
|
344
|
-
|
|
345
|
-
def process(self) -> str:
|
|
346
|
-
se_str = ''
|
|
347
|
-
if self.season is not None and self.episode is not None:
|
|
348
|
-
se_str = f"S{self.season:02d}E{self.episode:02d}"
|
|
349
|
-
elif self.season is not None:
|
|
350
|
-
se_str = f"S{self.season:02d}"
|
|
351
|
-
elif self.episode is not None:
|
|
352
|
-
se_str = f"E{self.episode:02d}"
|
|
353
|
-
|
|
354
|
-
if not self.releaser_sign:
|
|
355
|
-
# Search for a sign in the title
|
|
356
|
-
base_name = os.path.basename(self.filename)
|
|
357
|
-
filename, file_ext = os.path.splitext(base_name)
|
|
358
|
-
m = re.search(r'-([A-Za-z0-9]+)$', filename)
|
|
359
|
-
|
|
360
|
-
if m and m.group(1) not in TAG_TYPES:
|
|
361
|
-
self.sign_in_title = f"-{m.group(1)}"
|
|
362
|
-
else:
|
|
363
|
-
self.sign_in_title = ""
|
|
364
|
-
else:
|
|
365
|
-
self.sign_in_title = f"-{self.releaser_sign}"
|
|
366
|
-
|
|
367
|
-
parts = [self.title, str(self.year), se_str, self.episode_title]
|
|
368
|
-
filtered_parts = [part for part in parts if part]
|
|
369
|
-
title = ' '.join(filtered_parts)
|
|
370
|
-
|
|
371
|
-
return f"{title} {' '.join(self.tags_sorted)}{self.sign_in_title}"
|
|
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
|
|
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
|
{unit3dup-0.9.8 → unit3dup-0.9.10}/common/external_services/theMovieDB/core/models/__init__.py
RENAMED
|
File without changes
|
{unit3dup-0.9.8 → unit3dup-0.9.10}/common/external_services/theMovieDB/core/models/movie/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{unit3dup-0.9.8 → unit3dup-0.9.10}/common/external_services/theMovieDB/core/models/movie/details.py
RENAMED
|
File without changes
|
{unit3dup-0.9.8 → unit3dup-0.9.10}/common/external_services/theMovieDB/core/models/movie/movie.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{unit3dup-0.9.8 → unit3dup-0.9.10}/common/external_services/theMovieDB/core/models/tvshow/details.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{unit3dup-0.9.8 → unit3dup-0.9.10}/common/external_services/theMovieDB/core/models/tvshow/tvshow.py
RENAMED
|
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
|
|
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
|