Unit3Dup 0.9.9__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.9 → unit3dup-0.9.10}/PKG-INFO +1 -1
- {unit3dup-0.9.9 → unit3dup-0.9.10}/Unit3Dup.egg-info/PKG-INFO +1 -1
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/p2p_tags.py +104 -153
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/settings.py +1 -1
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/utility.py +17 -1
- {unit3dup-0.9.9 → unit3dup-0.9.10}/pyproject.toml +1 -1
- {unit3dup-0.9.9 → unit3dup-0.9.10}/LICENSE +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/README.rst +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/Unit3Dup.egg-info/SOURCES.txt +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/Unit3Dup.egg-info/dependency_links.txt +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/Unit3Dup.egg-info/entry_points.txt +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/Unit3Dup.egg-info/requires.txt +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/Unit3Dup.egg-info/top_level.txt +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/__init__.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/bdinfo_string.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/bittorrent.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/command.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/constants.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/database.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/external_services/__init__.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/external_services/ftpx/__init__.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/external_services/ftpx/client.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/external_services/ftpx/core/__init__.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/external_services/ftpx/core/ftpx_service.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/external_services/ftpx/core/ftpx_session.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/external_services/ftpx/core/menu.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/external_services/ftpx/core/models/__init__.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/external_services/ftpx/core/models/list.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/external_services/igdb/__init__.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/external_services/igdb/client.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/external_services/igdb/core/__init__.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/external_services/igdb/core/api.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/external_services/igdb/core/models/__init__.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/external_services/igdb/core/models/search.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/external_services/igdb/core/platformid.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/external_services/igdb/core/tags.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/external_services/imageHost.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/external_services/mediaresult.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/external_services/sessions/__init__.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/external_services/sessions/agents.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/external_services/sessions/exceptions.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/external_services/sessions/session.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/external_services/theMovieDB/__init__.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/external_services/theMovieDB/core/__init__.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/external_services/theMovieDB/core/api.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/external_services/theMovieDB/core/keywords.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/external_services/theMovieDB/core/models/__init__.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/external_services/theMovieDB/core/models/movie/__init__.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/external_services/theMovieDB/core/models/movie/alternative_titles.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/external_services/theMovieDB/core/models/movie/details.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/external_services/theMovieDB/core/models/movie/movie.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/external_services/theMovieDB/core/models/movie/nowplaying.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/external_services/theMovieDB/core/models/movie/release_info.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/external_services/theMovieDB/core/models/tvshow/__init__.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/external_services/theMovieDB/core/models/tvshow/alternative.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/external_services/theMovieDB/core/models/tvshow/details.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/external_services/theMovieDB/core/models/tvshow/on_the_air.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/external_services/theMovieDB/core/models/tvshow/translations.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/external_services/theMovieDB/core/models/tvshow/tvshow.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/external_services/theMovieDB/core/videos.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/external_services/trailers/__init__.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/external_services/trailers/api.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/external_services/trailers/response.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/external_services/tvdb.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/extractor.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/frames.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/mediainfo.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/mediainfo_string.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/title.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/torrent_clients.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/trackers/__init__.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/trackers/data.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/trackers/itt.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/trackers/sis.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/common/trackers/trackers.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/requirements.txt +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/setup.cfg +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/unit3dup/__init__.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/unit3dup/__main__.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/unit3dup/automode.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/unit3dup/bot.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/unit3dup/duplicate.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/unit3dup/exceptions.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/unit3dup/media.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/unit3dup/media_manager/ContentManager.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/unit3dup/media_manager/DocuManager.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/unit3dup/media_manager/GameManager.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/unit3dup/media_manager/MediaInfoManager.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/unit3dup/media_manager/SeedManager.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/unit3dup/media_manager/TorrentManager.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/unit3dup/media_manager/VideoManager.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/unit3dup/media_manager/__init__.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/unit3dup/media_manager/common.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/unit3dup/pvtDocu.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/unit3dup/pvtTorrent.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/unit3dup/pvtTracker.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/unit3dup/pvtVideo.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/unit3dup/torrent.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/unit3dup/upload.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/view/__init__.py +0 -0
- {unit3dup-0.9.9 → unit3dup-0.9.10}/view/custom_console.py +0 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
import os
|
|
3
3
|
import re
|
|
4
|
+
from collections import deque
|
|
4
5
|
from common.utility import ManageTitles
|
|
5
6
|
from common.mediainfo import MediaFile
|
|
6
|
-
from collections import deque
|
|
7
7
|
|
|
8
8
|
TAG_TYPES = {
|
|
9
9
|
"WEB-DL": "source",
|
|
@@ -16,6 +16,7 @@ TAG_TYPES = {
|
|
|
16
16
|
"REMUX": "source",
|
|
17
17
|
"VU": "source",
|
|
18
18
|
"UHD": "source",
|
|
19
|
+
"UHDRIP": "source",
|
|
19
20
|
"BLURAY": "source",
|
|
20
21
|
|
|
21
22
|
"AMZN": "platform",
|
|
@@ -53,8 +54,6 @@ TAG_TYPES = {
|
|
|
53
54
|
"STZ": "platform",
|
|
54
55
|
"TIMV": "platform",
|
|
55
56
|
|
|
56
|
-
"SUB": "subtitle",
|
|
57
|
-
"SUBS": "subtitle",
|
|
58
57
|
"ITA": "flag",
|
|
59
58
|
"ENG": "flag",
|
|
60
59
|
"FRA": "flag",
|
|
@@ -65,6 +64,9 @@ TAG_TYPES = {
|
|
|
65
64
|
"POR": "flag",
|
|
66
65
|
"PRT": "flag",
|
|
67
66
|
|
|
67
|
+
"SUB": "subtitle",
|
|
68
|
+
"SUBS": "subtitle",
|
|
69
|
+
|
|
68
70
|
"ATMOS": "audio",
|
|
69
71
|
"TRUEHD": "audio",
|
|
70
72
|
"DTSHD": "audio",
|
|
@@ -74,19 +76,19 @@ TAG_TYPES = {
|
|
|
74
76
|
"DDP5.1": "audio",
|
|
75
77
|
"DDP2.0": "audio",
|
|
76
78
|
"DTS": "audio",
|
|
77
|
-
|
|
79
|
+
"XLL": "audio",
|
|
78
80
|
"DD7.1": "audio",
|
|
79
81
|
"DD5.1": "audio",
|
|
80
82
|
"DD2.0": "audio",
|
|
81
|
-
|
|
82
83
|
"DD+ 7.1": "audio",
|
|
83
84
|
"DD+ 5.1": "audio",
|
|
84
85
|
"DD+ 2.0": "audio",
|
|
85
|
-
|
|
86
|
+
"DTS-HD MA 7.1": "audio",
|
|
87
|
+
"DTS-HD MA 5.1": "audio",
|
|
88
|
+
"DTS-HD MA 2.0": "audio",
|
|
86
89
|
"DD 7.1": "audio",
|
|
87
90
|
"DD 5.1": "audio",
|
|
88
91
|
"DD 2.0": "audio",
|
|
89
|
-
|
|
90
92
|
"AAC2.0": "audio",
|
|
91
93
|
"AAC5.1": "audio",
|
|
92
94
|
"AC3": "audio",
|
|
@@ -121,7 +123,6 @@ TAG_TYPES = {
|
|
|
121
123
|
"HDR": "video",
|
|
122
124
|
"HDR10+": "video",
|
|
123
125
|
"FHDRIP": "video",
|
|
124
|
-
"UHDRIP": "video",
|
|
125
126
|
"FULL HD": "video",
|
|
126
127
|
"FULLHD": "video",
|
|
127
128
|
"HD": "video",
|
|
@@ -136,14 +137,15 @@ TAG_TYPES = {
|
|
|
136
137
|
"720P": "resolution",
|
|
137
138
|
"576P": "resolution",
|
|
138
139
|
"480P": "resolution",
|
|
139
|
-
|
|
140
140
|
}
|
|
141
141
|
|
|
142
142
|
|
|
143
143
|
class P2pTags:
|
|
144
|
-
def __init__(
|
|
145
|
-
|
|
146
|
-
|
|
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
|
+
):
|
|
147
149
|
self.filename = filename
|
|
148
150
|
self.title = title
|
|
149
151
|
self.year = year
|
|
@@ -156,55 +158,65 @@ class P2pTags:
|
|
|
156
158
|
self.tags_position = tags_position
|
|
157
159
|
self.sign_in_title: str | None = None
|
|
158
160
|
|
|
161
|
+
self.tags_sorted = self._extract_tags()
|
|
162
|
+
|
|
163
|
+
def _extract_tags(self) -> list:
|
|
159
164
|
search_tags = sorted(TAG_TYPES.keys(), key=len, reverse=True)
|
|
160
|
-
pattern = re.compile(
|
|
161
|
-
r'\b(?:' + '|'.join(map(re.escape, search_tags)) + r')\b',
|
|
162
|
-
re.IGNORECASE
|
|
163
|
-
)
|
|
165
|
+
pattern = re.compile(r'\b(?:' + '|'.join(map(re.escape, search_tags)) + r')\b', re.IGNORECASE)
|
|
164
166
|
|
|
165
167
|
# Search for tags in the title
|
|
166
|
-
tags_match = pattern.findall(filename
|
|
167
|
-
# remove dope
|
|
168
|
-
tags_match = list(dict.fromkeys(tags_match))
|
|
169
|
-
|
|
168
|
+
tags_match = list(dict.fromkeys(pattern.findall(self.filename)))
|
|
170
169
|
# Search for channels
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
ch = "5.1"
|
|
176
|
-
elif channel_s == 8:
|
|
177
|
-
ch = "7.1"
|
|
178
|
-
elif channel_s == 2:
|
|
179
|
-
ch = "2.0"
|
|
180
|
-
|
|
181
|
-
# extract categories results
|
|
182
|
-
categories = [TAG_TYPES.get(tag) for tag in tags_match]
|
|
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, "")
|
|
183
174
|
|
|
175
|
+
# Categories of found tags
|
|
176
|
+
categories = [TAG_TYPES.get(tag.upper()) for tag in tags_match]
|
|
184
177
|
# Add video codec only if there is no video categories
|
|
185
|
-
if 'video' not in categories:
|
|
186
|
-
video_codec = self.mediafile.video_track[0].get('format', "")
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
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])
|
|
193
192
|
|
|
194
193
|
# Add tag language if there is no tag
|
|
195
194
|
flags = self._audio_lang()
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
missing_flags = [tag for tag in flags if tag not in tags_match]
|
|
199
|
-
tags_match.extend(missing_flags)
|
|
195
|
+
missing_flags = [tag for tag in flags if tag not in tags_match]
|
|
196
|
+
tags_match.extend(missing_flags)
|
|
200
197
|
|
|
201
198
|
# Add subtitle tag if subtitle_track exist and there is no 'sub' in the title
|
|
202
|
-
if 'subtitle' not in categories:
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
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)
|
|
206
203
|
|
|
207
|
-
|
|
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:
|
|
208
220
|
audio_translate = {
|
|
209
221
|
"AC3": "DD",
|
|
210
222
|
"AC-3": "DD",
|
|
@@ -214,139 +226,85 @@ class P2pTags:
|
|
|
214
226
|
"DDP5.1": "DD+",
|
|
215
227
|
"DDP7.1": "DD+",
|
|
216
228
|
"DDP": "DD+",
|
|
229
|
+
"DTS XLL": "DTS-HD MA",
|
|
217
230
|
}
|
|
218
231
|
|
|
219
|
-
# Translate video codec
|
|
220
232
|
video_translate = {
|
|
221
|
-
"
|
|
222
|
-
"X.264": "
|
|
223
|
-
"X264": "
|
|
224
|
-
"AVC": "
|
|
225
|
-
"
|
|
226
|
-
"H265": "
|
|
227
|
-
"X.265": "
|
|
228
|
-
"X265": "
|
|
229
|
-
"
|
|
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",
|
|
230
242
|
}
|
|
231
243
|
|
|
232
|
-
# lower the res..
|
|
233
244
|
resolution_lower = {"4320P", "2160P", "1080P", "720P", "576P", "480P"}
|
|
234
|
-
codec_lower = {
|
|
235
|
-
|
|
236
|
-
has_channel_tag = ch in tags_match
|
|
237
|
-
new_tags = []
|
|
245
|
+
codec_lower = {"X.264", "X265", "X.265", "X264"}
|
|
238
246
|
|
|
239
247
|
# verify the tags found in the title
|
|
248
|
+
normalized = []
|
|
240
249
|
for tag in tags_match:
|
|
241
250
|
t = tag.upper()
|
|
242
251
|
if t in audio_translate:
|
|
243
252
|
codec = audio_translate[t]
|
|
244
|
-
|
|
245
|
-
if ch and not has_channel_tag:
|
|
246
|
-
tag = f"{codec} {ch}"
|
|
247
|
-
else:
|
|
248
|
-
tag = codec
|
|
249
|
-
|
|
253
|
+
tag = f"{codec} {channel_tag}" if channel_tag else codec
|
|
250
254
|
elif t in video_translate:
|
|
251
255
|
tag = video_translate[t]
|
|
252
|
-
|
|
253
|
-
# Lower the res
|
|
254
|
-
elif t in resolution_lower:
|
|
256
|
+
elif t in resolution_lower or t in codec_lower:
|
|
255
257
|
tag = t.lower()
|
|
256
|
-
|
|
257
|
-
# Fix the 'sub' word
|
|
258
258
|
elif t == "SUB":
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
elif t in codec_lower:
|
|
263
|
-
tag = t.lower()
|
|
264
|
-
|
|
265
|
-
new_tags.append(tag)
|
|
266
|
-
|
|
267
|
-
tags_match = new_tags
|
|
259
|
+
tag = "SUBS" if len(self.mediafile.subtitle_track) > 1 else "SUB"
|
|
260
|
+
normalized.append(tag)
|
|
268
261
|
|
|
269
262
|
# Check if a 'resolution' tag exists and add mediafile resolution if it doesn't
|
|
270
|
-
if not any(TAG_TYPES.get(tag.upper()) == "resolution" for tag in
|
|
271
|
-
|
|
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)
|
|
272
268
|
|
|
269
|
+
def _sort_tags(self, tags: list, channel_tag: str) -> list:
|
|
273
270
|
# /// Sort tags based on 2 rules:
|
|
274
271
|
# 1) Order by tag_positions
|
|
275
272
|
# 2) For audio and flag categories alternate them (audio/flag/audio/flag)
|
|
276
273
|
# We can't sort each tags so we create dedicated list
|
|
277
|
-
audio_q = deque()
|
|
278
|
-
flag_q = deque()
|
|
279
|
-
channel_q = deque()
|
|
280
|
-
|
|
281
|
-
# This dict is for other categories
|
|
274
|
+
audio_q, flag_q, channel_q = deque(), deque(), deque()
|
|
282
275
|
other_groups = {}
|
|
283
276
|
|
|
284
|
-
|
|
285
|
-
# All other tags will follow the normal precedence order
|
|
286
|
-
for tag in tags_match:
|
|
277
|
+
for tag in tags:
|
|
287
278
|
cat = TAG_TYPES.get(tag.upper(), "unknown")
|
|
288
279
|
if cat == "audio":
|
|
289
|
-
|
|
290
|
-
audio_q.append(tag)
|
|
280
|
+
audio_q.append(tag.upper())
|
|
291
281
|
elif cat == "channels":
|
|
292
282
|
channel_q.append(tag)
|
|
293
283
|
elif cat == "flag":
|
|
294
|
-
|
|
295
|
-
|
|
284
|
+
flag_q.append(tag.upper())
|
|
285
|
+
elif cat == "video":
|
|
286
|
+
other_groups.setdefault(cat, []).append(tag.upper())
|
|
296
287
|
else:
|
|
297
|
-
# Add the other tags to other_groups
|
|
298
288
|
other_groups.setdefault(cat, []).append(tag)
|
|
299
289
|
|
|
300
290
|
# Alternate only if we have at least 2 audio and 2 flag tags
|
|
291
|
+
mixed = []
|
|
301
292
|
if len(audio_q) >= 2 and len(flag_q) >= 2:
|
|
302
|
-
mixed_audio_ch_flag = []
|
|
303
|
-
# Alternate
|
|
304
293
|
while audio_q or flag_q:
|
|
305
|
-
if audio_q:
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
if channel_q:
|
|
309
|
-
mixed_audio_ch_flag.append(channel_q.popleft())
|
|
310
|
-
if flag_q:
|
|
311
|
-
# get the first right flag and append to new list
|
|
312
|
-
mixed_audio_ch_flag.append(flag_q.popleft())
|
|
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())
|
|
313
297
|
else:
|
|
314
|
-
|
|
315
|
-
mixed_audio_ch_flag = list(audio_q) + list(channel_q) + list(flag_q)
|
|
298
|
+
mixed = list(audio_q) + list(channel_q) + list(flag_q)
|
|
316
299
|
|
|
317
|
-
# Rebuild the title ordering each tag+ audio/flag by tag_position
|
|
318
300
|
result = []
|
|
319
|
-
|
|
320
301
|
for cat in self.tags_position:
|
|
321
|
-
if cat in ("audio", "channels", "flag"):
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
result.extend(mixed_audio_ch_flag)
|
|
325
|
-
# clear
|
|
326
|
-
mixed_audio_ch_flag = []
|
|
302
|
+
if cat in ("audio", "channels", "flag") and mixed:
|
|
303
|
+
result.extend(mixed)
|
|
304
|
+
mixed = []
|
|
327
305
|
elif cat in other_groups:
|
|
328
306
|
result.extend(other_groups[cat])
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
def _audio_lang(self) -> list:
|
|
332
|
-
|
|
333
|
-
if not self.mediafile:
|
|
334
|
-
return []
|
|
335
|
-
|
|
336
|
-
lang: list = []
|
|
337
|
-
for track in self.mediafile.audio_track:
|
|
338
|
-
l = track.get('other_language', None)
|
|
339
|
-
if l:
|
|
340
|
-
for t in l:
|
|
341
|
-
c = ManageTitles.convert_iso(t)
|
|
342
|
-
if c:
|
|
343
|
-
if isinstance(c, list):
|
|
344
|
-
lang.extend(c)
|
|
345
|
-
break
|
|
346
|
-
else:
|
|
347
|
-
lang.append(c)
|
|
348
|
-
break
|
|
349
|
-
return lang
|
|
307
|
+
return result
|
|
350
308
|
|
|
351
309
|
def process(self) -> str:
|
|
352
310
|
se_str = ''
|
|
@@ -357,21 +315,14 @@ class P2pTags:
|
|
|
357
315
|
elif self.episode is not None:
|
|
358
316
|
se_str = f"E{self.episode:02d}"
|
|
359
317
|
|
|
318
|
+
# Detect releaser sign in filename if not provided
|
|
360
319
|
if not self.releaser_sign:
|
|
361
|
-
|
|
362
|
-
base_name = os.path.basename(self.filename)
|
|
363
|
-
filename, file_ext = os.path.splitext(base_name)
|
|
320
|
+
filename, _ = os.path.splitext(os.path.basename(self.filename))
|
|
364
321
|
m = re.search(r'-([A-Za-z0-9]+)$', filename)
|
|
365
|
-
|
|
366
|
-
if m and m.group(1) not in TAG_TYPES:
|
|
367
|
-
self.sign_in_title = f"-{m.group(1)}"
|
|
368
|
-
else:
|
|
369
|
-
self.sign_in_title = ""
|
|
322
|
+
self.sign_in_title = f"-{m.group(1)}" if m and m.group(1) not in TAG_TYPES else ""
|
|
370
323
|
else:
|
|
371
324
|
self.sign_in_title = f"-{self.releaser_sign}"
|
|
372
325
|
|
|
373
|
-
parts = [self.title, str(self.year), se_str
|
|
374
|
-
filtered_parts = [
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
return f"{title} {' '.join(self.tags_sorted)}{self.sign_in_title}"
|
|
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"
|
|
@@ -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
|
|
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.9 → unit3dup-0.9.10}/common/external_services/theMovieDB/core/models/__init__.py
RENAMED
|
File without changes
|
{unit3dup-0.9.9 → unit3dup-0.9.10}/common/external_services/theMovieDB/core/models/movie/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{unit3dup-0.9.9 → unit3dup-0.9.10}/common/external_services/theMovieDB/core/models/movie/details.py
RENAMED
|
File without changes
|
{unit3dup-0.9.9 → 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.9 → 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.9 → 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
|