Unit3Dup 0.9.3__tar.gz → 0.9.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.
Files changed (101) hide show
  1. {unit3dup-0.9.3 → unit3dup-0.9.5}/PKG-INFO +1 -1
  2. {unit3dup-0.9.3 → unit3dup-0.9.5}/Unit3Dup.egg-info/PKG-INFO +1 -1
  3. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/p2p_tags.py +79 -17
  4. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/settings.py +4 -4
  5. {unit3dup-0.9.3 → unit3dup-0.9.5}/pyproject.toml +1 -1
  6. {unit3dup-0.9.3 → unit3dup-0.9.5}/unit3dup/bot.py +8 -0
  7. {unit3dup-0.9.3 → unit3dup-0.9.5}/LICENSE +0 -0
  8. {unit3dup-0.9.3 → unit3dup-0.9.5}/README.rst +0 -0
  9. {unit3dup-0.9.3 → unit3dup-0.9.5}/Unit3Dup.egg-info/SOURCES.txt +0 -0
  10. {unit3dup-0.9.3 → unit3dup-0.9.5}/Unit3Dup.egg-info/dependency_links.txt +0 -0
  11. {unit3dup-0.9.3 → unit3dup-0.9.5}/Unit3Dup.egg-info/entry_points.txt +0 -0
  12. {unit3dup-0.9.3 → unit3dup-0.9.5}/Unit3Dup.egg-info/requires.txt +0 -0
  13. {unit3dup-0.9.3 → unit3dup-0.9.5}/Unit3Dup.egg-info/top_level.txt +0 -0
  14. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/__init__.py +0 -0
  15. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/bdinfo_string.py +0 -0
  16. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/bittorrent.py +0 -0
  17. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/command.py +0 -0
  18. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/constants.py +0 -0
  19. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/database.py +0 -0
  20. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/external_services/__init__.py +0 -0
  21. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/external_services/ftpx/__init__.py +0 -0
  22. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/external_services/ftpx/client.py +0 -0
  23. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/external_services/ftpx/core/__init__.py +0 -0
  24. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/external_services/ftpx/core/ftpx_service.py +0 -0
  25. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/external_services/ftpx/core/ftpx_session.py +0 -0
  26. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/external_services/ftpx/core/menu.py +0 -0
  27. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/external_services/ftpx/core/models/__init__.py +0 -0
  28. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/external_services/ftpx/core/models/list.py +0 -0
  29. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/external_services/igdb/__init__.py +0 -0
  30. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/external_services/igdb/client.py +0 -0
  31. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/external_services/igdb/core/__init__.py +0 -0
  32. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/external_services/igdb/core/api.py +0 -0
  33. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/external_services/igdb/core/models/__init__.py +0 -0
  34. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/external_services/igdb/core/models/search.py +0 -0
  35. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/external_services/igdb/core/platformid.py +0 -0
  36. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/external_services/igdb/core/tags.py +0 -0
  37. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/external_services/imageHost.py +0 -0
  38. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/external_services/mediaresult.py +0 -0
  39. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/external_services/sessions/__init__.py +0 -0
  40. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/external_services/sessions/agents.py +0 -0
  41. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/external_services/sessions/exceptions.py +0 -0
  42. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/external_services/sessions/session.py +0 -0
  43. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/external_services/theMovieDB/__init__.py +0 -0
  44. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/external_services/theMovieDB/core/__init__.py +0 -0
  45. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/external_services/theMovieDB/core/api.py +0 -0
  46. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/external_services/theMovieDB/core/keywords.py +0 -0
  47. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/external_services/theMovieDB/core/models/__init__.py +0 -0
  48. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/external_services/theMovieDB/core/models/movie/__init__.py +0 -0
  49. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/external_services/theMovieDB/core/models/movie/alternative_titles.py +0 -0
  50. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/external_services/theMovieDB/core/models/movie/details.py +0 -0
  51. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/external_services/theMovieDB/core/models/movie/movie.py +0 -0
  52. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/external_services/theMovieDB/core/models/movie/nowplaying.py +0 -0
  53. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/external_services/theMovieDB/core/models/movie/release_info.py +0 -0
  54. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/external_services/theMovieDB/core/models/tvshow/__init__.py +0 -0
  55. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/external_services/theMovieDB/core/models/tvshow/alternative.py +0 -0
  56. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/external_services/theMovieDB/core/models/tvshow/details.py +0 -0
  57. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/external_services/theMovieDB/core/models/tvshow/on_the_air.py +0 -0
  58. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/external_services/theMovieDB/core/models/tvshow/translations.py +0 -0
  59. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/external_services/theMovieDB/core/models/tvshow/tvshow.py +0 -0
  60. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/external_services/theMovieDB/core/videos.py +0 -0
  61. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/external_services/trailers/__init__.py +0 -0
  62. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/external_services/trailers/api.py +0 -0
  63. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/external_services/trailers/response.py +0 -0
  64. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/external_services/tvdb.py +0 -0
  65. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/extractor.py +0 -0
  66. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/frames.py +0 -0
  67. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/mediainfo.py +0 -0
  68. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/mediainfo_string.py +0 -0
  69. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/title.py +0 -0
  70. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/torrent_clients.py +0 -0
  71. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/trackers/__init__.py +0 -0
  72. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/trackers/data.py +0 -0
  73. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/trackers/itt.py +0 -0
  74. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/trackers/sis.py +0 -0
  75. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/trackers/trackers.py +0 -0
  76. {unit3dup-0.9.3 → unit3dup-0.9.5}/common/utility.py +0 -0
  77. {unit3dup-0.9.3 → unit3dup-0.9.5}/requirements.txt +0 -0
  78. {unit3dup-0.9.3 → unit3dup-0.9.5}/setup.cfg +0 -0
  79. {unit3dup-0.9.3 → unit3dup-0.9.5}/unit3dup/__init__.py +0 -0
  80. {unit3dup-0.9.3 → unit3dup-0.9.5}/unit3dup/__main__.py +0 -0
  81. {unit3dup-0.9.3 → unit3dup-0.9.5}/unit3dup/automode.py +0 -0
  82. {unit3dup-0.9.3 → unit3dup-0.9.5}/unit3dup/duplicate.py +0 -0
  83. {unit3dup-0.9.3 → unit3dup-0.9.5}/unit3dup/exceptions.py +0 -0
  84. {unit3dup-0.9.3 → unit3dup-0.9.5}/unit3dup/media.py +0 -0
  85. {unit3dup-0.9.3 → unit3dup-0.9.5}/unit3dup/media_manager/ContentManager.py +0 -0
  86. {unit3dup-0.9.3 → unit3dup-0.9.5}/unit3dup/media_manager/DocuManager.py +0 -0
  87. {unit3dup-0.9.3 → unit3dup-0.9.5}/unit3dup/media_manager/GameManager.py +0 -0
  88. {unit3dup-0.9.3 → unit3dup-0.9.5}/unit3dup/media_manager/MediaInfoManager.py +0 -0
  89. {unit3dup-0.9.3 → unit3dup-0.9.5}/unit3dup/media_manager/SeedManager.py +0 -0
  90. {unit3dup-0.9.3 → unit3dup-0.9.5}/unit3dup/media_manager/TorrentManager.py +0 -0
  91. {unit3dup-0.9.3 → unit3dup-0.9.5}/unit3dup/media_manager/VideoManager.py +0 -0
  92. {unit3dup-0.9.3 → unit3dup-0.9.5}/unit3dup/media_manager/__init__.py +0 -0
  93. {unit3dup-0.9.3 → unit3dup-0.9.5}/unit3dup/media_manager/common.py +0 -0
  94. {unit3dup-0.9.3 → unit3dup-0.9.5}/unit3dup/pvtDocu.py +0 -0
  95. {unit3dup-0.9.3 → unit3dup-0.9.5}/unit3dup/pvtTorrent.py +0 -0
  96. {unit3dup-0.9.3 → unit3dup-0.9.5}/unit3dup/pvtTracker.py +0 -0
  97. {unit3dup-0.9.3 → unit3dup-0.9.5}/unit3dup/pvtVideo.py +0 -0
  98. {unit3dup-0.9.3 → unit3dup-0.9.5}/unit3dup/torrent.py +0 -0
  99. {unit3dup-0.9.3 → unit3dup-0.9.5}/unit3dup/upload.py +0 -0
  100. {unit3dup-0.9.3 → unit3dup-0.9.5}/view/__init__.py +0 -0
  101. {unit3dup-0.9.3 → unit3dup-0.9.5}/view/custom_console.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: Unit3Dup
3
- Version: 0.9.3
3
+ Version: 0.9.5
4
4
  Summary: An uploader for the Unit3D torrent tracker
5
5
  Author: Parzival
6
6
  License-Expression: MIT
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: Unit3Dup
3
- Version: 0.9.3
3
+ Version: 0.9.5
4
4
  Summary: An uploader for the Unit3D torrent tracker
5
5
  Author: Parzival
6
6
  License-Expression: MIT
@@ -3,12 +3,14 @@ import os
3
3
  import re
4
4
  from common.utility import ManageTitles
5
5
  from common.mediainfo import MediaFile
6
+ from collections import defaultdict, deque
6
7
 
7
8
  TAG_TYPES = {
8
9
  "WEB-DL": "source",
9
10
  "WEBDL": "source",
10
11
  "WEB-DLMUX": "source",
11
12
  "WEBDLMUX": "source",
13
+ "WEBMUX": "source",
12
14
  "WEBRIP": "source",
13
15
  "BD-UNTOUCHED": "source",
14
16
  "VU": "source",
@@ -57,7 +59,10 @@ TAG_TYPES = {
57
59
  "GER": "flag",
58
60
  "ESP": "flag",
59
61
 
62
+ "ATMOS": "audio",
60
63
  "TRUEHD": "audio",
64
+ "DTSHD": "audio",
65
+ "DTS-HD": "audio",
61
66
  "DDP7.1": "audio",
62
67
  "DDP5.1": "audio",
63
68
  "DDP2.0": "audio",
@@ -86,9 +91,9 @@ TAG_TYPES = {
86
91
  "AAC": "audio",
87
92
  "AVC": "audio",
88
93
 
89
- "7.1": "audio",
90
- "5.1": "audio",
91
- "2.0": "audio",
94
+ "7.1": "channels",
95
+ "5.1": "channels",
96
+ "2.0": "channels",
92
97
 
93
98
  "H.264": "video",
94
99
  "X.264": "video",
@@ -161,8 +166,9 @@ class P2pTags:
161
166
 
162
167
  # Add video codec only if there is no video categories
163
168
  if 'video' not in categories:
164
- video_format = self.mediafile.video_track[0].get('format', "") if self.mediafile.video_track else ""
165
- tags_match.append(video_format)
169
+ video_codec = self.mediafile.video_track[0].get('encoded_library_name',
170
+ "") if self.mediafile.video_track else ""
171
+ tags_match.append(video_codec)
166
172
 
167
173
  # Add audio codec only if there is no audio categories
168
174
  if 'audio' not in categories:
@@ -175,8 +181,9 @@ class P2pTags:
175
181
 
176
182
  # Add subtitle tag if subtitle_track exist and there is no 'sub' in the title
177
183
  if 'subtitle' not in categories:
184
+ sub_tag = "SUBS" if len(self.mediafile.subtitle_track) > 1 else "SUB"
178
185
  if self.mediafile.subtitle_track:
179
- tags_match.append("SUBS")
186
+ tags_match.append(sub_tag)
180
187
 
181
188
  # Translate audio codec
182
189
  audio_translate = {
@@ -197,6 +204,7 @@ class P2pTags:
197
204
  has_channel_tag = ch in tags_match
198
205
  new_tags = []
199
206
 
207
+ # verify the tags found in the title
200
208
  for tag in tags_match:
201
209
  t = tag.upper()
202
210
  if t in audio_translate:
@@ -214,7 +222,8 @@ class P2pTags:
214
222
 
215
223
  # Fix the 'sub' word
216
224
  elif t == "SUB":
217
- tag = "SUBS"
225
+ sub_tag = "SUBS" if len(self.mediafile.subtitle_track) > 1 else "SUB"
226
+ tag = sub_tag
218
227
 
219
228
  elif t in codec_lower:
220
229
  tag = t.lower()
@@ -228,15 +237,67 @@ class P2pTags:
228
237
  tags_match.append(self.mediafile_resolution)
229
238
 
230
239
  # Assign an index to the 'precedence' keywords
231
- precedence_index = {}
232
- for i, v in enumerate(self.tags_position):
233
- precedence_index[v] = i
234
-
235
- # Started based on precedence
236
- self.tags_sorted = sorted(
237
- tags_match,
238
- key=lambda tag: precedence_index.get(TAG_TYPES[tag.upper()], 100)
239
- )
240
+ # precedence_index = {}
241
+ # for i, v in enumerate(self.tags_position):
242
+ # precedence_index[v] = i
243
+
244
+ # /// Sort tags based on 2 rules:
245
+ # 1) Order by tag_positions
246
+ # 2) For audio and flag categories alternate them (audio/flag/audio/flag)
247
+
248
+ # We can't sort each tags so we create dedicated list
249
+ audio_q = deque()
250
+ flag_q = deque()
251
+ channel_q = deque()
252
+
253
+ # This dict is for other categories
254
+ other_groups = {}
255
+
256
+ # Isolate audio and flag tags
257
+ # All other tags will follow the normal precedence order
258
+ for tag in tags_match:
259
+ cat = TAG_TYPES.get(tag.upper(), "unknown")
260
+ if cat == "audio":
261
+ # Add audio tag to its queue
262
+ audio_q.append(tag)
263
+ elif cat == "channels":
264
+ channel_q.append(tag)
265
+ elif cat == "flag":
266
+ # Add flag tag to its queue
267
+ flag_q.append(tag)
268
+ else:
269
+ # Add the other tags to other_groups
270
+ other_groups.setdefault(cat, []).append(tag)
271
+
272
+ # Alternate only if we have at least 2 audio and 2 flag tags
273
+ if len(audio_q) >= 2 and len(flag_q) >= 2:
274
+ mixed_audio_ch_flag = []
275
+ # Alternate
276
+ while audio_q or flag_q:
277
+ if audio_q:
278
+ # get the first left audio and append to new list
279
+ mixed_audio_ch_flag.append(audio_q.popleft())
280
+ if channel_q:
281
+ mixed_audio_ch_flag.append(channel_q.popleft())
282
+ if flag_q:
283
+ # get the first right flag and append to new list
284
+ mixed_audio_ch_flag.append(flag_q.popleft())
285
+ else:
286
+ # otherwise goes for normal precedence
287
+ mixed_audio_ch_flag = list(audio_q) + list(channel_q) + list(flag_q)
288
+
289
+ # Rebuild the title ordering each tag+ audio/flag by tag_position
290
+ result = []
291
+ for cat in self.tags_position:
292
+ if cat in ("audio", "channels", "flag"):
293
+ # Insert the audio/flag processed tags
294
+ if mixed_audio_ch_flag:
295
+ result.extend(mixed_audio_ch_flag)
296
+ # clear
297
+ mixed_audio_ch_flag = []
298
+ elif cat in other_groups:
299
+ result.extend(other_groups[cat])
300
+ self.tags_sorted = result
240
301
 
241
302
  def _audio_lang(self) -> list:
242
303
 
@@ -268,7 +329,8 @@ class P2pTags:
268
329
  base_name = os.path.basename(self.filename)
269
330
  filename, file_ext = os.path.splitext(base_name)
270
331
  m = re.search(r'-([A-Za-z0-9]+)$', filename)
271
- if m:
332
+
333
+ if m and m.group(1) not in TAG_TYPES:
272
334
  self.sign_in_title = f"-{m.group(1)}"
273
335
  else:
274
336
  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.3"
18
+ version = "0.9.5"
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) != 6:
253
+ if len(position_list) != 7:
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", "flag", "subtitle", "video"]:
258
+ if tag.lower() not in ["resolution", "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", "flag", "subtitle", "video"],
581
+ "TAGS_POSITION": ["resolution", "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",
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
5
5
  [project]
6
6
  dynamic = ["dependencies"]
7
7
  name = "Unit3Dup"
8
- version = "0.9.3"
8
+ version = "0.9.5"
9
9
  description = "An uploader for the Unit3D torrent tracker"
10
10
  readme = "README.rst"
11
11
  requires-python = ">=3.10"
@@ -54,6 +54,14 @@ class Bot:
54
54
  """
55
55
  custom_console.panel_message("Analyzing your media files... Please wait")
56
56
 
57
+ # Check permission
58
+ try:
59
+ os.stat(self.path)
60
+ except PermissionError:
61
+ custom_console.bot_error_log(f"Permission denied: {self.path}")
62
+ return False
63
+
64
+ # Exists
57
65
  if not os.path.exists(self.path):
58
66
  custom_console.bot_error_log("Path doesn't exist")
59
67
  return False
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