Unit3Dup 0.9.4__tar.gz → 0.9.6__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.4 → unit3dup-0.9.6}/PKG-INFO +1 -1
  2. {unit3dup-0.9.4 → unit3dup-0.9.6}/Unit3Dup.egg-info/PKG-INFO +1 -1
  3. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/p2p_tags.py +92 -15
  4. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/settings.py +4 -4
  5. {unit3dup-0.9.4 → unit3dup-0.9.6}/pyproject.toml +1 -1
  6. {unit3dup-0.9.4 → unit3dup-0.9.6}/unit3dup/bot.py +8 -0
  7. {unit3dup-0.9.4 → unit3dup-0.9.6}/unit3dup/media.py +1 -2
  8. {unit3dup-0.9.4 → unit3dup-0.9.6}/LICENSE +0 -0
  9. {unit3dup-0.9.4 → unit3dup-0.9.6}/README.rst +0 -0
  10. {unit3dup-0.9.4 → unit3dup-0.9.6}/Unit3Dup.egg-info/SOURCES.txt +0 -0
  11. {unit3dup-0.9.4 → unit3dup-0.9.6}/Unit3Dup.egg-info/dependency_links.txt +0 -0
  12. {unit3dup-0.9.4 → unit3dup-0.9.6}/Unit3Dup.egg-info/entry_points.txt +0 -0
  13. {unit3dup-0.9.4 → unit3dup-0.9.6}/Unit3Dup.egg-info/requires.txt +0 -0
  14. {unit3dup-0.9.4 → unit3dup-0.9.6}/Unit3Dup.egg-info/top_level.txt +0 -0
  15. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/__init__.py +0 -0
  16. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/bdinfo_string.py +0 -0
  17. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/bittorrent.py +0 -0
  18. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/command.py +0 -0
  19. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/constants.py +0 -0
  20. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/database.py +0 -0
  21. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/external_services/__init__.py +0 -0
  22. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/external_services/ftpx/__init__.py +0 -0
  23. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/external_services/ftpx/client.py +0 -0
  24. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/external_services/ftpx/core/__init__.py +0 -0
  25. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/external_services/ftpx/core/ftpx_service.py +0 -0
  26. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/external_services/ftpx/core/ftpx_session.py +0 -0
  27. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/external_services/ftpx/core/menu.py +0 -0
  28. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/external_services/ftpx/core/models/__init__.py +0 -0
  29. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/external_services/ftpx/core/models/list.py +0 -0
  30. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/external_services/igdb/__init__.py +0 -0
  31. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/external_services/igdb/client.py +0 -0
  32. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/external_services/igdb/core/__init__.py +0 -0
  33. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/external_services/igdb/core/api.py +0 -0
  34. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/external_services/igdb/core/models/__init__.py +0 -0
  35. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/external_services/igdb/core/models/search.py +0 -0
  36. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/external_services/igdb/core/platformid.py +0 -0
  37. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/external_services/igdb/core/tags.py +0 -0
  38. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/external_services/imageHost.py +0 -0
  39. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/external_services/mediaresult.py +0 -0
  40. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/external_services/sessions/__init__.py +0 -0
  41. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/external_services/sessions/agents.py +0 -0
  42. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/external_services/sessions/exceptions.py +0 -0
  43. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/external_services/sessions/session.py +0 -0
  44. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/external_services/theMovieDB/__init__.py +0 -0
  45. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/external_services/theMovieDB/core/__init__.py +0 -0
  46. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/external_services/theMovieDB/core/api.py +0 -0
  47. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/external_services/theMovieDB/core/keywords.py +0 -0
  48. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/external_services/theMovieDB/core/models/__init__.py +0 -0
  49. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/external_services/theMovieDB/core/models/movie/__init__.py +0 -0
  50. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/external_services/theMovieDB/core/models/movie/alternative_titles.py +0 -0
  51. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/external_services/theMovieDB/core/models/movie/details.py +0 -0
  52. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/external_services/theMovieDB/core/models/movie/movie.py +0 -0
  53. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/external_services/theMovieDB/core/models/movie/nowplaying.py +0 -0
  54. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/external_services/theMovieDB/core/models/movie/release_info.py +0 -0
  55. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/external_services/theMovieDB/core/models/tvshow/__init__.py +0 -0
  56. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/external_services/theMovieDB/core/models/tvshow/alternative.py +0 -0
  57. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/external_services/theMovieDB/core/models/tvshow/details.py +0 -0
  58. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/external_services/theMovieDB/core/models/tvshow/on_the_air.py +0 -0
  59. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/external_services/theMovieDB/core/models/tvshow/translations.py +0 -0
  60. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/external_services/theMovieDB/core/models/tvshow/tvshow.py +0 -0
  61. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/external_services/theMovieDB/core/videos.py +0 -0
  62. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/external_services/trailers/__init__.py +0 -0
  63. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/external_services/trailers/api.py +0 -0
  64. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/external_services/trailers/response.py +0 -0
  65. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/external_services/tvdb.py +0 -0
  66. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/extractor.py +0 -0
  67. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/frames.py +0 -0
  68. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/mediainfo.py +0 -0
  69. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/mediainfo_string.py +0 -0
  70. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/title.py +0 -0
  71. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/torrent_clients.py +0 -0
  72. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/trackers/__init__.py +0 -0
  73. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/trackers/data.py +0 -0
  74. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/trackers/itt.py +0 -0
  75. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/trackers/sis.py +0 -0
  76. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/trackers/trackers.py +0 -0
  77. {unit3dup-0.9.4 → unit3dup-0.9.6}/common/utility.py +0 -0
  78. {unit3dup-0.9.4 → unit3dup-0.9.6}/requirements.txt +0 -0
  79. {unit3dup-0.9.4 → unit3dup-0.9.6}/setup.cfg +0 -0
  80. {unit3dup-0.9.4 → unit3dup-0.9.6}/unit3dup/__init__.py +0 -0
  81. {unit3dup-0.9.4 → unit3dup-0.9.6}/unit3dup/__main__.py +0 -0
  82. {unit3dup-0.9.4 → unit3dup-0.9.6}/unit3dup/automode.py +0 -0
  83. {unit3dup-0.9.4 → unit3dup-0.9.6}/unit3dup/duplicate.py +0 -0
  84. {unit3dup-0.9.4 → unit3dup-0.9.6}/unit3dup/exceptions.py +0 -0
  85. {unit3dup-0.9.4 → unit3dup-0.9.6}/unit3dup/media_manager/ContentManager.py +0 -0
  86. {unit3dup-0.9.4 → unit3dup-0.9.6}/unit3dup/media_manager/DocuManager.py +0 -0
  87. {unit3dup-0.9.4 → unit3dup-0.9.6}/unit3dup/media_manager/GameManager.py +0 -0
  88. {unit3dup-0.9.4 → unit3dup-0.9.6}/unit3dup/media_manager/MediaInfoManager.py +0 -0
  89. {unit3dup-0.9.4 → unit3dup-0.9.6}/unit3dup/media_manager/SeedManager.py +0 -0
  90. {unit3dup-0.9.4 → unit3dup-0.9.6}/unit3dup/media_manager/TorrentManager.py +0 -0
  91. {unit3dup-0.9.4 → unit3dup-0.9.6}/unit3dup/media_manager/VideoManager.py +0 -0
  92. {unit3dup-0.9.4 → unit3dup-0.9.6}/unit3dup/media_manager/__init__.py +0 -0
  93. {unit3dup-0.9.4 → unit3dup-0.9.6}/unit3dup/media_manager/common.py +0 -0
  94. {unit3dup-0.9.4 → unit3dup-0.9.6}/unit3dup/pvtDocu.py +0 -0
  95. {unit3dup-0.9.4 → unit3dup-0.9.6}/unit3dup/pvtTorrent.py +0 -0
  96. {unit3dup-0.9.4 → unit3dup-0.9.6}/unit3dup/pvtTracker.py +0 -0
  97. {unit3dup-0.9.4 → unit3dup-0.9.6}/unit3dup/pvtVideo.py +0 -0
  98. {unit3dup-0.9.4 → unit3dup-0.9.6}/unit3dup/torrent.py +0 -0
  99. {unit3dup-0.9.4 → unit3dup-0.9.6}/unit3dup/upload.py +0 -0
  100. {unit3dup-0.9.4 → unit3dup-0.9.6}/view/__init__.py +0 -0
  101. {unit3dup-0.9.4 → unit3dup-0.9.6}/view/custom_console.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: Unit3Dup
3
- Version: 0.9.4
3
+ Version: 0.9.6
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.4
3
+ Version: 0.9.6
4
4
  Summary: An uploader for the Unit3D torrent tracker
5
5
  Author: Parzival
6
6
  License-Expression: MIT
@@ -3,14 +3,17 @@ import os
3
3
  import re
4
4
  from common.utility import ManageTitles
5
5
  from common.mediainfo import MediaFile
6
+ from collections import 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",
16
+ "REMUX": "source",
14
17
  "VU": "source",
15
18
  "UHD": "source",
16
19
  "BLURAY": "source",
@@ -57,10 +60,15 @@ TAG_TYPES = {
57
60
  "GER": "flag",
58
61
  "ESP": "flag",
59
62
 
63
+ "ATMOS": "audio",
60
64
  "TRUEHD": "audio",
65
+ "DTSHD": "audio",
66
+ "DTS-HD": "audio",
67
+ "DTS-HD MA": "audio",
61
68
  "DDP7.1": "audio",
62
69
  "DDP5.1": "audio",
63
70
  "DDP2.0": "audio",
71
+ "DTS": "audio",
64
72
 
65
73
  "DD7.1": "audio",
66
74
  "DD5.1": "audio",
@@ -86,9 +94,9 @@ TAG_TYPES = {
86
94
  "AAC": "audio",
87
95
  "AVC": "audio",
88
96
 
89
- "7.1": "audio",
90
- "5.1": "audio",
91
- "2.0": "audio",
97
+ "7.1": "channels",
98
+ "5.1": "channels",
99
+ "2.0": "channels",
92
100
 
93
101
  "H.264": "video",
94
102
  "X.264": "video",
@@ -107,6 +115,7 @@ TAG_TYPES = {
107
115
  "HDR10PLUS": "video",
108
116
  "HDR": "video",
109
117
  "HDR10+": "video",
118
+ "FHDRIP": "video",
110
119
 
111
120
  "4320P": "resolution",
112
121
  "2160P": "resolution",
@@ -161,7 +170,7 @@ class P2pTags:
161
170
 
162
171
  # Add video codec only if there is no video categories
163
172
  if 'video' not in categories:
164
- video_codec = self.mediafile.video_track[0].get('encoded_library_name', "") if self.mediafile.video_track else ""
173
+ video_codec = self.mediafile.video_track[0].get('format', "") if self.mediafile.video_track else ""
165
174
  tags_match.append(video_codec)
166
175
 
167
176
  # Add audio codec only if there is no audio categories
@@ -191,6 +200,19 @@ class P2pTags:
191
200
  "DDP": "DD+",
192
201
  }
193
202
 
203
+ # Translate video codec
204
+ video_translate = {
205
+ "H.264": "x264",
206
+ "X.264": "x264",
207
+ "X264": "x264",
208
+ "AVC": "x264",
209
+ "H.265": "x265",
210
+ "H265": "x265",
211
+ "X.265": "x265",
212
+ "X265": "x265",
213
+ "HEVC": "x265",
214
+ }
215
+
194
216
  # lower the res..
195
217
  resolution_lower = {"4320P", "2160P", "1080P", "720P", "576P", "480P"}
196
218
  codec_lower = {'X.264', 'X265', 'X.265', 'X264'}
@@ -203,20 +225,23 @@ class P2pTags:
203
225
  t = tag.upper()
204
226
  if t in audio_translate:
205
227
  codec = audio_translate[t]
206
-
207
228
  # Add channels only if it does not exist
208
229
  if ch and not has_channel_tag:
209
230
  tag = f"{codec} {ch}"
210
231
  else:
211
232
  tag = codec
212
233
 
234
+ elif t in video_translate:
235
+ tag = video_translate[t]
236
+
213
237
  # Lower the res
214
238
  elif t in resolution_lower:
215
239
  tag = t.lower()
216
240
 
217
241
  # Fix the 'sub' word
218
242
  elif t == "SUB":
219
- tag = "SUBS"
243
+ sub_tag = "SUBS" if len(self.mediafile.subtitle_track) > 1 else "SUB"
244
+ tag = sub_tag
220
245
 
221
246
  elif t in codec_lower:
222
247
  tag = t.lower()
@@ -230,15 +255,67 @@ class P2pTags:
230
255
  tags_match.append(self.mediafile_resolution)
231
256
 
232
257
  # Assign an index to the 'precedence' keywords
233
- precedence_index = {}
234
- for i, v in enumerate(self.tags_position):
235
- precedence_index[v] = i
236
-
237
- # Started based on precedence
238
- self.tags_sorted = sorted(
239
- tags_match,
240
- key=lambda tag: precedence_index.get(TAG_TYPES[tag.upper()], 100)
241
- )
258
+ # precedence_index = {}
259
+ # for i, v in enumerate(self.tags_position):
260
+ # precedence_index[v] = i
261
+
262
+ # /// Sort tags based on 2 rules:
263
+ # 1) Order by tag_positions
264
+ # 2) For audio and flag categories alternate them (audio/flag/audio/flag)
265
+
266
+ # We can't sort each tags so we create dedicated list
267
+ audio_q = deque()
268
+ flag_q = deque()
269
+ channel_q = deque()
270
+
271
+ # This dict is for other categories
272
+ other_groups = {}
273
+
274
+ # Isolate audio and flag tags
275
+ # All other tags will follow the normal precedence order
276
+ for tag in tags_match:
277
+ cat = TAG_TYPES.get(tag.upper(), "unknown")
278
+ if cat == "audio":
279
+ # Add audio tag to its queue
280
+ audio_q.append(tag)
281
+ elif cat == "channels":
282
+ channel_q.append(tag)
283
+ elif cat == "flag":
284
+ # Add flag tag to its queue
285
+ flag_q.append(tag)
286
+ else:
287
+ # Add the other tags to other_groups
288
+ other_groups.setdefault(cat, []).append(tag)
289
+
290
+ # Alternate only if we have at least 2 audio and 2 flag tags
291
+ if len(audio_q) >= 2 and len(flag_q) >= 2:
292
+ mixed_audio_ch_flag = []
293
+ # Alternate
294
+ while audio_q or flag_q:
295
+ if audio_q:
296
+ # get the first left audio and append to new list
297
+ mixed_audio_ch_flag.append(audio_q.popleft())
298
+ if channel_q:
299
+ mixed_audio_ch_flag.append(channel_q.popleft())
300
+ if flag_q:
301
+ # get the first right flag and append to new list
302
+ mixed_audio_ch_flag.append(flag_q.popleft())
303
+ else:
304
+ # otherwise goes for normal precedence
305
+ mixed_audio_ch_flag = list(audio_q) + list(channel_q) + list(flag_q)
306
+
307
+ # Rebuild the title ordering each tag+ audio/flag by tag_position
308
+ result = []
309
+ for cat in self.tags_position:
310
+ if cat in ("audio", "channels", "flag"):
311
+ # Insert the audio/flag processed tags
312
+ if mixed_audio_ch_flag:
313
+ result.extend(mixed_audio_ch_flag)
314
+ # clear
315
+ mixed_audio_ch_flag = []
316
+ elif cat in other_groups:
317
+ result.extend(other_groups[cat])
318
+ self.tags_sorted = result
242
319
 
243
320
  def _audio_lang(self) -> list:
244
321
 
@@ -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.4"
18
+ version = "0.9.6"
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.4"
8
+ version = "0.9.6"
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
@@ -222,7 +222,7 @@ class Media:
222
222
  if not self._display_name:
223
223
  self._guess_filename = title.Guessit(self.title_sanitized)
224
224
  guess = self._guess_filename.guessit
225
- p2p_tags = P2pTags(filename=self.file_name,
225
+ p2p_tags = P2pTags(filename=self.title_sanitized,
226
226
  title=guess.get("title", None),
227
227
  year=guess.get("year", ""),
228
228
  episode_title=guess.get("episode_title", None),
@@ -350,7 +350,6 @@ class Media:
350
350
  }:
351
351
  # Read from the current video file the height field
352
352
  file_path = os.path.join(self.folder, self.file_name)
353
-
354
353
  # Media file
355
354
  self._media_file = MediaFile(file_path)
356
355
  return self._media_file
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