Unit3Dup 0.9.12__tar.gz → 0.9.13__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.12 → unit3dup-0.9.13}/PKG-INFO +3 -3
  2. {unit3dup-0.9.12 → unit3dup-0.9.13}/README.rst +2 -2
  3. {unit3dup-0.9.12 → unit3dup-0.9.13}/Unit3Dup.egg-info/PKG-INFO +3 -3
  4. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/command.py +6 -9
  5. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/settings.py +95 -3
  6. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/tags.py +29 -95
  7. {unit3dup-0.9.12 → unit3dup-0.9.13}/pyproject.toml +1 -1
  8. {unit3dup-0.9.12 → unit3dup-0.9.13}/unit3dup/__main__.py +14 -3
  9. {unit3dup-0.9.12 → unit3dup-0.9.13}/unit3dup/bot.py +3 -2
  10. {unit3dup-0.9.12 → unit3dup-0.9.13}/unit3dup/media.py +0 -27
  11. {unit3dup-0.9.12 → unit3dup-0.9.13}/unit3dup/media_manager/DocuManager.py +3 -3
  12. {unit3dup-0.9.12 → unit3dup-0.9.13}/unit3dup/media_manager/GameManager.py +3 -3
  13. {unit3dup-0.9.12 → unit3dup-0.9.13}/unit3dup/media_manager/TorrentManager.py +3 -5
  14. {unit3dup-0.9.12 → unit3dup-0.9.13}/unit3dup/media_manager/VideoManager.py +6 -17
  15. {unit3dup-0.9.12 → unit3dup-0.9.13}/unit3dup/upload.py +3 -3
  16. {unit3dup-0.9.12 → unit3dup-0.9.13}/LICENSE +0 -0
  17. {unit3dup-0.9.12 → unit3dup-0.9.13}/Unit3Dup.egg-info/SOURCES.txt +0 -0
  18. {unit3dup-0.9.12 → unit3dup-0.9.13}/Unit3Dup.egg-info/dependency_links.txt +0 -0
  19. {unit3dup-0.9.12 → unit3dup-0.9.13}/Unit3Dup.egg-info/entry_points.txt +0 -0
  20. {unit3dup-0.9.12 → unit3dup-0.9.13}/Unit3Dup.egg-info/requires.txt +0 -0
  21. {unit3dup-0.9.12 → unit3dup-0.9.13}/Unit3Dup.egg-info/top_level.txt +0 -0
  22. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/__init__.py +0 -0
  23. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/bdinfo_string.py +0 -0
  24. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/bittorrent.py +0 -0
  25. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/constants.py +0 -0
  26. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/database.py +0 -0
  27. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/external_services/__init__.py +0 -0
  28. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/external_services/ftpx/__init__.py +0 -0
  29. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/external_services/ftpx/client.py +0 -0
  30. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/external_services/ftpx/core/__init__.py +0 -0
  31. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/external_services/ftpx/core/ftpx_service.py +0 -0
  32. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/external_services/ftpx/core/ftpx_session.py +0 -0
  33. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/external_services/ftpx/core/menu.py +0 -0
  34. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/external_services/ftpx/core/models/__init__.py +0 -0
  35. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/external_services/ftpx/core/models/list.py +0 -0
  36. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/external_services/igdb/__init__.py +0 -0
  37. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/external_services/igdb/client.py +0 -0
  38. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/external_services/igdb/core/__init__.py +0 -0
  39. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/external_services/igdb/core/api.py +0 -0
  40. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/external_services/igdb/core/models/__init__.py +0 -0
  41. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/external_services/igdb/core/models/search.py +0 -0
  42. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/external_services/igdb/core/platformid.py +0 -0
  43. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/external_services/igdb/core/tags.py +0 -0
  44. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/external_services/imageHost.py +0 -0
  45. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/external_services/mediaresult.py +0 -0
  46. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/external_services/sessions/__init__.py +0 -0
  47. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/external_services/sessions/agents.py +0 -0
  48. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/external_services/sessions/exceptions.py +0 -0
  49. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/external_services/sessions/session.py +0 -0
  50. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/external_services/theMovieDB/__init__.py +0 -0
  51. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/external_services/theMovieDB/core/__init__.py +0 -0
  52. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/external_services/theMovieDB/core/api.py +0 -0
  53. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/external_services/theMovieDB/core/keywords.py +0 -0
  54. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/external_services/theMovieDB/core/models/__init__.py +0 -0
  55. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/external_services/theMovieDB/core/models/movie/__init__.py +0 -0
  56. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/external_services/theMovieDB/core/models/movie/alternative_titles.py +0 -0
  57. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/external_services/theMovieDB/core/models/movie/details.py +0 -0
  58. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/external_services/theMovieDB/core/models/movie/movie.py +0 -0
  59. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/external_services/theMovieDB/core/models/movie/nowplaying.py +0 -0
  60. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/external_services/theMovieDB/core/models/movie/release_info.py +0 -0
  61. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/external_services/theMovieDB/core/models/tvshow/__init__.py +0 -0
  62. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/external_services/theMovieDB/core/models/tvshow/alternative.py +0 -0
  63. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/external_services/theMovieDB/core/models/tvshow/details.py +0 -0
  64. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/external_services/theMovieDB/core/models/tvshow/on_the_air.py +0 -0
  65. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/external_services/theMovieDB/core/models/tvshow/translations.py +0 -0
  66. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/external_services/theMovieDB/core/models/tvshow/tvshow.py +0 -0
  67. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/external_services/theMovieDB/core/videos.py +0 -0
  68. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/external_services/trailers/__init__.py +0 -0
  69. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/external_services/trailers/api.py +0 -0
  70. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/external_services/trailers/response.py +0 -0
  71. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/external_services/tvdb.py +0 -0
  72. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/extractor.py +0 -0
  73. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/frames.py +0 -0
  74. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/mediainfo.py +0 -0
  75. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/mediainfo_string.py +0 -0
  76. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/title.py +0 -0
  77. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/torrent_clients.py +0 -0
  78. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/trackers/__init__.py +0 -0
  79. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/trackers/data.py +0 -0
  80. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/trackers/itt.py +0 -0
  81. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/trackers/sis.py +0 -0
  82. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/trackers/trackers.py +0 -0
  83. {unit3dup-0.9.12 → unit3dup-0.9.13}/common/utility.py +0 -0
  84. {unit3dup-0.9.12 → unit3dup-0.9.13}/requirements.txt +0 -0
  85. {unit3dup-0.9.12 → unit3dup-0.9.13}/setup.cfg +0 -0
  86. {unit3dup-0.9.12 → unit3dup-0.9.13}/unit3dup/__init__.py +0 -0
  87. {unit3dup-0.9.12 → unit3dup-0.9.13}/unit3dup/automode.py +0 -0
  88. {unit3dup-0.9.12 → unit3dup-0.9.13}/unit3dup/duplicate.py +0 -0
  89. {unit3dup-0.9.12 → unit3dup-0.9.13}/unit3dup/exceptions.py +0 -0
  90. {unit3dup-0.9.12 → unit3dup-0.9.13}/unit3dup/media_manager/ContentManager.py +0 -0
  91. {unit3dup-0.9.12 → unit3dup-0.9.13}/unit3dup/media_manager/MediaInfoManager.py +0 -0
  92. {unit3dup-0.9.12 → unit3dup-0.9.13}/unit3dup/media_manager/SeedManager.py +0 -0
  93. {unit3dup-0.9.12 → unit3dup-0.9.13}/unit3dup/media_manager/__init__.py +0 -0
  94. {unit3dup-0.9.12 → unit3dup-0.9.13}/unit3dup/media_manager/common.py +0 -0
  95. {unit3dup-0.9.12 → unit3dup-0.9.13}/unit3dup/pvtDocu.py +0 -0
  96. {unit3dup-0.9.12 → unit3dup-0.9.13}/unit3dup/pvtTorrent.py +0 -0
  97. {unit3dup-0.9.12 → unit3dup-0.9.13}/unit3dup/pvtTracker.py +0 -0
  98. {unit3dup-0.9.12 → unit3dup-0.9.13}/unit3dup/pvtVideo.py +0 -0
  99. {unit3dup-0.9.12 → unit3dup-0.9.13}/unit3dup/torrent.py +0 -0
  100. {unit3dup-0.9.12 → unit3dup-0.9.13}/view/__init__.py +0 -0
  101. {unit3dup-0.9.12 → unit3dup-0.9.13}/view/custom_console.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: Unit3Dup
3
- Version: 0.9.12
3
+ Version: 0.9.13
4
4
  Summary: An uploader for the Unit3D torrent tracker
5
5
  Author: Parzival
6
6
  License-Expression: MIT
@@ -60,8 +60,8 @@ It performs the following tasks:
60
60
  - Seeding in qBittorrent, Transmission or rTorrent
61
61
  - Reseeding one or more torrents at a time
62
62
  - Seed your torrents across different OS
63
- - Add a custom title to your seasons
64
- - Generate info for a title using MediaInfo
63
+ - Generate various tags for titles: ``version``, ``resolution``, ``uhd``, ``platform``, ``source``, ``remux``, ``multi``, ``acodec``, ``channels``, ``flag``, ``subtitle``, ``vcodec``, ``hdr``, ``video_encoder``
64
+
65
65
 
66
66
  unit3dup can grab the first page, convert it to an image (using xpdf),
67
67
  and then the bot can upload it to an image host, then add the link to the torrent page description.
@@ -29,8 +29,8 @@ It performs the following tasks:
29
29
  - Seeding in qBittorrent, Transmission or rTorrent
30
30
  - Reseeding one or more torrents at a time
31
31
  - Seed your torrents across different OS
32
- - Add a custom title to your seasons
33
- - Generate info for a title using MediaInfo
32
+ - Generate various tags for titles: ``version``, ``resolution``, ``uhd``, ``platform``, ``source``, ``remux``, ``multi``, ``acodec``, ``channels``, ``flag``, ``subtitle``, ``vcodec``, ``hdr``, ``video_encoder``
33
+
34
34
 
35
35
  unit3dup can grab the first page, convert it to an image (using xpdf),
36
36
  and then the bot can upload it to an image host, then add the link to the torrent page description.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: Unit3Dup
3
- Version: 0.9.12
3
+ Version: 0.9.13
4
4
  Summary: An uploader for the Unit3D torrent tracker
5
5
  Author: Parzival
6
6
  License-Expression: MIT
@@ -60,8 +60,8 @@ It performs the following tasks:
60
60
  - Seeding in qBittorrent, Transmission or rTorrent
61
61
  - Reseeding one or more torrents at a time
62
62
  - Seed your torrents across different OS
63
- - Add a custom title to your seasons
64
- - Generate info for a title using MediaInfo
63
+ - Generate various tags for titles: ``version``, ``resolution``, ``uhd``, ``platform``, ``source``, ``remux``, ``multi``, ``acodec``, ``channels``, ``flag``, ``subtitle``, ``vcodec``, ``hdr``, ``video_encoder``
64
+
65
65
 
66
66
  unit3dup can grab the first page, convert it to an image (using xpdf),
67
67
  and then the bot can upload it to an image host, then add the link to the torrent page description.
@@ -1,10 +1,10 @@
1
1
  # -*- coding: utf-8 -*-
2
-
3
2
  import os
4
3
  import argparse
5
4
  from common.utility import System
6
5
  from common.settings import Load
7
6
 
7
+
8
8
  class CommandLine:
9
9
  """
10
10
  Class to handle user input from the command line
@@ -30,7 +30,6 @@ class CommandLine:
30
30
  parser.add_argument("-b", "--buildtags", action="store_true", help="Auto build torrent name")
31
31
 
32
32
  parser.add_argument("-reseed", "--reseed", action="store_true", help="reseed folder")
33
- parser.add_argument("-gentitle", "--gentitle", action="store_true", help="")
34
33
  parser.add_argument("-watcher", "--watcher", action="store_true", help="Start watcher")
35
34
 
36
35
  parser.add_argument("-notitle", "--notitle", type=str, help="")
@@ -99,8 +98,6 @@ class CommandLine:
99
98
  "-pr", "--prelease", action="store_true", help="Personal release torrent"
100
99
  )
101
100
 
102
-
103
-
104
101
  # Parsing the User cli
105
102
  self.args: parser = parser.parse_args()
106
103
 
@@ -114,10 +111,10 @@ class CommandLine:
114
111
  # Test -force flag
115
112
  if self.args.force:
116
113
  self.args.force = self.args.force[:10]
117
- if self.args.force.lower() not in [ System.category_list[System.MOVIE],
118
- System.category_list[System.GAME],
119
- System.category_list[System.TV_SHOW],
120
- System.category_list[System.DOCUMENTARY]]:
114
+ if self.args.force.lower() not in [System.category_list[System.MOVIE],
115
+ System.category_list[System.GAME],
116
+ System.category_list[System.TV_SHOW],
117
+ System.category_list[System.DOCUMENTARY]]:
121
118
  self.args.force = None
122
119
  print("Invalid -force category")
123
- exit()
120
+ exit()
@@ -15,7 +15,8 @@ from common.utility import ManageTitles
15
15
  from common import trackers
16
16
 
17
17
  config_file = "Unit3Dbot.json"
18
- version = "0.9.12"
18
+ user_tags_file = "tags_list.json"
19
+ version = "0.9.13"
19
20
 
20
21
  if os.name == "nt":
21
22
  WATCHER_DESTINATION_PATH: Path = Path(os.getenv("LOCALAPPDATA", ".")) / "Unit3Dup_config" / "watcher_destination_path"
@@ -23,6 +24,7 @@ if os.name == "nt":
23
24
  CACHE_PATH: Path = Path(os.getenv("LOCALAPPDATA", ".")) / "Unit3Dup_config" / "cache_path"
24
25
  TORRENT_ARCHIVE_PATH: Path = Path(os.getenv("LOCALAPPDATA", ".")) / "Unit3Dup_config" / "torrent_archive_path"
25
26
  DEFAULT_JSON_PATH: Path = Path(os.getenv("LOCALAPPDATA", ".")) / "Unit3Dup_config" / f"{config_file}"
27
+ USER_TAGS_PATH: Path = Path(os.getenv("LOCALAPPDATA", ".")) / "Unit3Dup_config" / f"{user_tags_file}"
26
28
 
27
29
  else:
28
30
  WATCHER_DESTINATION_PATH: Path = Path.home() / "Unit3Dup_config" / "watcher_destination_path"
@@ -30,7 +32,7 @@ else:
30
32
  CACHE_PATH: Path = Path.home() / "Unit3Dup_config" / "cache_path"
31
33
  TORRENT_ARCHIVE_PATH: Path = Path.home() / "Unit3Dup_config" / "torrent_archive_path"
32
34
  DEFAULT_JSON_PATH: Path = Path.home() / "Unit3Dup_config" / f"{config_file}"
33
-
35
+ USER_TAGS_PATH: Path = Path.home() / "Unit3Dup_config" / f"{user_tags_file}"
34
36
 
35
37
  def get_default_path(field: str)-> str:
36
38
  default_paths = {
@@ -522,6 +524,92 @@ class Load:
522
524
  def _load_config(self):
523
525
  self.config = self.load_config()
524
526
 
527
+ @staticmethod
528
+ def create_tags_list_file(path: Path):
529
+ """
530
+ Creates a tags list file
531
+ """
532
+ TAG_TYPES = {
533
+ "REMUX": "remux",
534
+ "WEB-DL": "source",
535
+ "WEB-DLMUX": "source",
536
+ "WEBMUX": "source",
537
+ "WEBRIP": "source",
538
+ "BD-UNTOUCHED": "source",
539
+ "TS": "source",
540
+ "CAM": "source",
541
+ "HDTS": "source",
542
+ "MD": "source",
543
+ "UHDRIP": "source",
544
+ "BLURAY": "source",
545
+ "BRRIP": "source",
546
+ "BDRIP": "source",
547
+ "FHDRIP": "source",
548
+
549
+ "ATVP": "platform",
550
+ "AMZN": "platform",
551
+ "AMC": "platform",
552
+ "CN": "platform",
553
+ "CR": "platform",
554
+ "DCU": "platform",
555
+ "DISC": "platform",
556
+ "DSCP": "platform",
557
+ "DSNY": "platform",
558
+ "DSNP": "platform",
559
+ "DPLY": "platform",
560
+ "ESPN": "platform",
561
+ "FOOD": "platform",
562
+ "FOX": "platform",
563
+ "PLAY": "platform",
564
+ "HBO": "platform",
565
+ "HMAX": "platform",
566
+ "HGTV": "platform",
567
+ "HIST": "platform",
568
+ "HULU": "platform",
569
+ "MTOD": "platform",
570
+ "NATG": "platform",
571
+ "NF": "platform",
572
+ "NICK": "platform",
573
+ "NOW": "platform",
574
+ "PMNT": "platform",
575
+ "PMTP": "platform",
576
+ "PCOK": "platform",
577
+ "RKTN": "platform",
578
+ "SHO": "platform",
579
+ "SKST": "platform",
580
+ "STAN": "platform",
581
+ "STRP": "platform",
582
+ "STZ": "platform",
583
+ "TIMV": "platform",
584
+
585
+ "REPACK": "version",
586
+ "EXTENDED": "version",
587
+ "SUBBED": "version",
588
+ "MUX": "version",
589
+ "REMASTERED": "version",
590
+ "READNFO": "version",
591
+ "UNRATED": "version",
592
+ "LIMITED": "version",
593
+ "VU": "version",
594
+ "STV": "version",
595
+ "RECODE": "version",
596
+ "INTERNAL": "version",
597
+ "PROPER": "version",
598
+ "DUAL": "version",
599
+ "UNTOUCHED": "version",
600
+ "COMPLETE": "version",
601
+ "COMPLETA": "version",
602
+
603
+ "X264": "video_encoder",
604
+ "X265": "video_encoder",
605
+ }
606
+
607
+ path.parent.mkdir(parents=True, exist_ok=True)
608
+ with open(path, "w", encoding="utf-8") as tags_list_file:
609
+ json.dump(TAG_TYPES, tags_list_file, ensure_ascii=False, indent=4)
610
+
611
+
612
+
525
613
 
526
614
  @staticmethod
527
615
  def create_default_json_file(path: Path):
@@ -580,7 +668,7 @@ class Load:
580
668
  "IMARIDE_PRIORITY": 6,
581
669
  "NUMBER_OF_SCREENSHOTS": 4,
582
670
  "TAGS_POSITION": ["title", "year", "season", "version", "resolution", "uhd", "platform", "source", "remux",
583
- "multi", "acodec", "channels", "flag", "subtitle", "vcodec", "hdr", "video_encoder"],
671
+ "multi", "acodec", "channels", "flag", "subtitle", "hdr", "vcodec", "video_encoder"],
584
672
  "YOUTUBE_FAV_CHANNEL_ID": "UCGCbxpnt25hWPFLSbvwfg_w",
585
673
  "YOUTUBE_CHANNEL_ENABLE": "False",
586
674
  "DUPLICATE_ON": "true",
@@ -655,6 +743,10 @@ class Load:
655
743
  print(f"Create default configuration file: {DEFAULT_JSON_PATH}")
656
744
  Load.create_default_json_file(DEFAULT_JSON_PATH)
657
745
 
746
+ if not USER_TAGS_PATH.exists():
747
+ print(f"Create default Tags_list file: {USER_TAGS_PATH}")
748
+ Load.create_tags_list_file(USER_TAGS_PATH)
749
+
658
750
  # Since the last bot version there might are new attributes
659
751
  # Load the json file, find the difference between json file and the code. Update the user's json file
660
752
  update_config = JsonConfig(default_json_path=DEFAULT_JSON_PATH)
@@ -4,81 +4,6 @@ import re
4
4
  from common.mediainfo import MediaFile
5
5
  from common.utility import ManageTitles
6
6
 
7
- TAG_TYPES = {
8
- "REMUX": "remux",
9
- "WEB-DL": "source",
10
- "WEB-DLMUX": "source",
11
- "WEBMUX": "source",
12
- "WEBRIP": "source",
13
- "BD-UNTOUCHED": "source",
14
- "TS": "source",
15
- "CAM": "source",
16
- "HDTS": "source",
17
- "MD": "source",
18
- "UHDRIP": "source",
19
- "BLURAY": "source",
20
- "BRRIP": "source",
21
- "BDRIP": "source",
22
- "FHDRIP": "source",
23
-
24
- "ATVP": "platform",
25
- "AMZN": "platform",
26
- "AMC": "platform",
27
- "CN": "platform",
28
- "CR": "platform",
29
- "DCU": "platform",
30
- "DISC": "platform",
31
- "DSCP": "platform",
32
- "DSNY": "platform",
33
- "DSNP": "platform",
34
- "DPLY": "platform",
35
- "ESPN": "platform",
36
- "FOOD": "platform",
37
- "FOX": "platform",
38
- "PLAY": "platform",
39
- "HBO": "platform",
40
- "HMAX": "platform",
41
- "HGTV": "platform",
42
- "HIST": "platform",
43
- "HULU": "platform",
44
- "MTOD": "platform",
45
- "NATG": "platform",
46
- "NF": "platform",
47
- "NICK": "platform",
48
- "NOW": "platform",
49
- "PMNT": "platform",
50
- "PMTP": "platform",
51
- "PCOK": "platform",
52
- "RKTN": "platform",
53
- "SHO": "platform",
54
- "SKST": "platform",
55
- "STAN": "platform",
56
- "STRP": "platform",
57
- "STZ": "platform",
58
- "TIMV": "platform",
59
-
60
- "REPACK": "version",
61
- "EXTENDED": "version",
62
- "SUBBED": "version",
63
- "MUX": "version",
64
- "REMASTERED": "version",
65
- "READNFO": "version",
66
- "UNRATED": "version",
67
- "LIMITED": "version",
68
- "VU": "version",
69
- "STV": "version",
70
- "RECODE": "version",
71
- "INTERNAL": "version",
72
- "PROPER": "version",
73
- "DUAL": "version",
74
- "UNTOUCHED": "version",
75
- "COMPLETE": "version",
76
- "COMPLETA": "version",
77
-
78
- "X264": "video_encoder",
79
- "X265": "video_encoder",
80
- }
81
-
82
7
  # From hdr format
83
8
  hdr_map = {
84
9
  "DOLBY VISION": "DV",
@@ -124,7 +49,7 @@ video_encoder_translate = {
124
49
 
125
50
  class SearchTags(object):
126
51
  def __init__(self, filename, title: str, year: str, season: int, episode: int,
127
- mediafile: MediaFile, tags_position: list, releaser_sign: str):
52
+ mediafile: MediaFile, tags_position: list, tags_list: dict, releaser_sign: str):
128
53
 
129
54
  self.tags_position = tags_position
130
55
  self.releaser_sign = releaser_sign
@@ -136,25 +61,30 @@ class SearchTags(object):
136
61
  self.year = year
137
62
  self.tags_dict = {}
138
63
  self.tags_position = tags_position
64
+ self.TAG_TYPES = tags_list
139
65
 
140
- def normalize_version_tag(self, tag: str) -> str:
66
+ @staticmethod
67
+ def normalize_version_tag(tag: str) -> str:
141
68
  tag_esc = re.escape(tag)
142
69
  # Filter hyphenated,space compounds
143
70
  tag_esc = tag_esc.replace(r'\ ', r'[.\s_-]*')
144
71
  return tag_esc
145
72
 
146
- def normalize_platform_tag(self, tag: str) -> str:
73
+ @staticmethod
74
+ def normalize_platform_tag(tag: str) -> str:
147
75
  # escape
148
76
  tag_esc = re.escape(tag)
149
77
  return tag_esc
150
78
 
151
- def normalize_sources(self, tag: str) -> str:
79
+ @staticmethod
80
+ def normalize_sources(tag: str) -> str:
152
81
  tag_esc = re.escape(tag)
153
82
  # Filter hyphenated,space compounds
154
83
  tag_esc = tag_esc.replace(r'\ ', r'[.\s_-]*')
155
84
  return tag_esc
156
85
 
157
- def normalize_video_encoder(self, tag: str) -> str:
86
+ @staticmethod
87
+ def normalize_video_encoder(tag: str) -> str:
158
88
  tag_esc = re.escape(tag)
159
89
  tag_esc = re.sub(r'([A-Z])(\d+)', r'\1[._-]?\2', tag_esc)
160
90
  return tag_esc
@@ -164,7 +94,7 @@ class SearchTags(object):
164
94
 
165
95
  # loop sorted TAG_TYPES dictionary
166
96
  for i, (tag, category) in enumerate(
167
- sorted(TAG_TYPES.items(), key=lambda x: len(x[0]), reverse=True)
97
+ sorted(self.TAG_TYPES.items(), key=lambda x: len(x[0]), reverse=True)
168
98
  ):
169
99
  if category == "version":
170
100
  norm = self.normalize_version_tag(tag)
@@ -202,7 +132,8 @@ class SearchTags(object):
202
132
  updated_category = self.mediainfo_uhd(category=category)
203
133
 
204
134
  elif category == "subtitle":
205
- updated_category = {'subtitle': "SUBS" if len(self.mediafile.subtitle_track) > 1 else "SUB"}
135
+ if self.mediafile.subtitle_track:
136
+ updated_category = {'subtitle': "SUBS" if len(self.mediafile.subtitle_track) > 1 else "SUB"}
206
137
 
207
138
  if updated_category:
208
139
  self.tags_dict.update(updated_category)
@@ -226,7 +157,7 @@ class SearchTags(object):
226
157
  if not self.releaser_sign:
227
158
  filename, _ = os.path.splitext(os.path.basename(self.filename))
228
159
  m = re.search(r'-([A-Za-z0-9]+)$', filename)
229
- self.releaser_sign = f"-{m.group(1)}" if m and m.group(1) not in TAG_TYPES else ""
160
+ self.releaser_sign = f"-{m.group(1)}" if m and m.group(1) not in self.TAG_TYPES else ""
230
161
  else:
231
162
  self.releaser_sign = f"-{self.releaser_sign}"
232
163
 
@@ -249,7 +180,7 @@ class SearchTags(object):
249
180
  return refactored
250
181
 
251
182
  def mediainfo_audio(self, category: str) -> dict:
252
- langs = set()
183
+ languages = []
253
184
  audio_codecs = []
254
185
  if self.mediafile.audio_track:
255
186
  for audio in self.mediafile.audio_track:
@@ -267,22 +198,23 @@ class SearchTags(object):
267
198
  ch = {2: "2.0", 6: "5.1", 8: "7.1"}.get(channel_s, "")
268
199
  if f"{codec_translated} {ch} {atmos}".strip() not in audio_codecs:
269
200
  audio_codecs.append(f"{codec_translated} {ch} {atmos}".strip())
270
- print(f"Mediainfo {other_format} -> {codec_translated} {ch} {atmos}")
201
+ # print(f"Mediainfo {other_format} -> {codec_translated} {ch} {atmos}")
271
202
 
272
203
  # Add flags
273
204
  for l in audio.get('other_language', []):
274
205
  c = ManageTitles.convert_iso(l)
275
206
  if c:
276
207
  if isinstance(c, list):
277
- langs.update(c)
208
+ languages.append(c[0])
278
209
  else:
279
- langs.add(c)
210
+ languages.append(c)
280
211
  break
212
+ languages = list(dict.fromkeys(languages))
281
213
  # Add multilanguage tag when languages > 2
282
- if len(langs) > 2:
214
+ if len(languages) > 2:
283
215
  self.tags_dict.update({'multi': 'MULTI'})
284
216
 
285
- audio_codecs.extend(list(langs))
217
+ audio_codecs.extend(languages)
286
218
  return {category: audio_codecs}
287
219
 
288
220
  def mediainfo_video(self, category: str) -> dict:
@@ -302,16 +234,17 @@ class SearchTags(object):
302
234
  hdr_format = video.get('hdr_format', "")
303
235
  # Check hdr
304
236
  if hdr_format_commercial:
305
- print(f"hdr_format_commercial: {hdr_format_commercial}")
306
- print(f"hdr_format: {hdr_format}")
237
+ # print(f"hdr_format_commercial: {hdr_format_commercial}")
238
+ # print(f"hdr_format: {hdr_format}")
307
239
  hdr = ''
308
240
  if hdr_format_commercial in hdr_map:
309
- print(f"hdr_format_commercial: {hdr_format_commercial} -> Tag: {hdr_map[hdr_format_commercial]}")
241
+ # print(
242
+ # f"hdr_format_commercial: {hdr_format_commercial} -> Tag: {hdr_map[hdr_format_commercial]}")
310
243
  hdr = hdr_map[hdr_format_commercial]
311
244
  # Check dolby vision
312
245
  if 'DOLBY VISION' in hdr_format_commercial.upper() or 'DOLBY VISION' in hdr_format.upper():
313
246
  hdr = f"DOLBY VISION {hdr}"
314
- print(hdr)
247
+ # print(hdr)
315
248
  return {category: hdr_map[hdr]}
316
249
  return {}
317
250
 
@@ -323,7 +256,8 @@ class SearchTags(object):
323
256
  if self.mediafile.video_track:
324
257
  video_height = int(self.mediafile.video_track[0].get('height', 0))
325
258
  video_width = int(self.mediafile.video_track[0].get('width', 0))
326
- print(f"VideoTrack : W{video_width} x H{video_height}")
259
+
260
+ # print(f"VideoTrack : W{video_width} x H{video_height}")
327
261
 
328
262
  # Calculate range 5%
329
263
  def in_range(value, standard):
@@ -354,4 +288,4 @@ class SearchTags(object):
354
288
  result[category] = 'unknown'
355
289
  result['resolution'] = f'{video_width}x{video_height}'
356
290
 
357
- return result
291
+ return result
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
5
5
  [project]
6
6
  dynamic = ["dependencies"]
7
7
  name = "Unit3Dup"
8
- version = "0.9.12"
8
+ version = "0.9.13"
9
9
  description = "An uploader for the Unit3D torrent tracker"
10
10
  readme = "README.rst"
11
11
  requires-python = ">=3.10"
@@ -1,8 +1,9 @@
1
1
  # -*- coding: utf-8 -*-
2
+ import json
2
3
 
3
4
  from common.torrent_clients import TransmissionClient, QbittorrentClient, RTorrentClient
4
5
  from common.command import CommandLine
5
- from common.settings import Load,DEFAULT_JSON_PATH
6
+ from common.settings import Load,DEFAULT_JSON_PATH, USER_TAGS_PATH
6
7
 
7
8
  from unit3dup.torrent import View
8
9
  from unit3dup import pvtTracker
@@ -94,10 +95,19 @@ def main():
94
95
  if cli.args.mt:
95
96
  tracker_name_list = config.tracker_config.MULTI_TRACKER
96
97
 
98
+ # Load User Tags list
99
+ tags_list = None
100
+ if cli.args.buildtags:
101
+ try:
102
+ with open(USER_TAGS_PATH, "r", encoding="utf-8") as f:
103
+ tags_list = json.load(f)
104
+ except FileNotFoundError:
105
+ custom_console.bot_error_log(f"User tags file {USER_TAGS_PATH} not found. Please update your configuration file")
106
+
97
107
  # Manual upload mode
98
108
  if cli.args.upload:
99
109
  bot = Bot(path=cli.args.upload, cli=cli.args, trackers_name_list=tracker_name_list,
100
- torrent_archive_path=tracker_archive)
110
+ torrent_archive_path=tracker_archive, tags_list=tags_list)
101
111
  bot.run()
102
112
 
103
113
  # Manual folder mode
@@ -108,13 +118,14 @@ def main():
108
118
  mode="folder",
109
119
  trackers_name_list=tracker_name_list,
110
120
  torrent_archive_path=tracker_archive,
121
+ tags_list=tags_list
111
122
  )
112
123
  bot.run()
113
124
 
114
125
  # Auto mode
115
126
  if cli.args.scan and not cli.args.ftp:
116
127
  bot = Bot(path=cli.args.scan, cli=cli.args, mode="auto", trackers_name_list=tracker_name_list,
117
- torrent_archive_path=tracker_archive)
128
+ torrent_archive_path=tracker_archive, tags_list=tags_list)
118
129
  bot.run()
119
130
 
120
131
  # Watcher
@@ -29,7 +29,7 @@ class Bot:
29
29
  """
30
30
 
31
31
  # Bot Manager
32
- def __init__(self, path: str, cli: argparse.Namespace, trackers_name_list: list, mode="man",
32
+ def __init__(self, path: str, cli: argparse.Namespace, trackers_name_list: list, tags_list = None, mode="man",
33
33
  torrent_archive_path = None):
34
34
  """
35
35
  Initializes the Bot instance with path, command-line interface object, and mode
@@ -42,6 +42,7 @@ class Bot:
42
42
  self.trackers_name_list = trackers_name_list
43
43
  self.torrent_archive_path = torrent_archive_path
44
44
  self.content_manager = None
45
+ self.tags_list: dict = tags_list
45
46
  self.path = path.strip()
46
47
  self.cli = cli
47
48
  self.mode = mode
@@ -101,7 +102,7 @@ class Bot:
101
102
  return False
102
103
 
103
104
  # Instance a new run
104
- torrent_manager = TorrentManager(cli=self.cli, tracker_archive=self.torrent_archive_path)
105
+ torrent_manager = TorrentManager(cli=self.cli, tracker_archive=self.torrent_archive_path, tags_list=self.tags_list)
105
106
  # Process the torrents content (files)
106
107
  torrent_manager.process(contents=contents)
107
108
 
@@ -177,33 +177,6 @@ class Media:
177
177
  def igdb_id(self, value):
178
178
  self._igdb_id = value
179
179
 
180
- @property
181
- def generate_title(self) -> str:
182
-
183
- if not self._generate_title:
184
- # Read video and audio data from mediainfo
185
- video_f = self.mediafile.video_track[0]['format']
186
- audio_f = self.mediafile.audio_track[0]['format']
187
- audio_lang = self.mediafile.audio_track[0]['language']
188
- available_lang = ' '.join(lang for lang in self.mediafile.available_languages if lang is not None)
189
-
190
- # Search for Season and Episode o torrent_pack
191
- if 'tv' in self.category:
192
- serie = f"S{str(self.guess_season).zfill(2)}" if self.guess_season else ''
193
- if not self.torrent_pack:
194
- serie += f"E{str(self.guess_episode).zfill(2)}"
195
- else:
196
- serie = ''
197
-
198
- # Build the title
199
- self._generate_title = (f"{self.guess_title} {serie} {self.resolution} {video_f} "
200
- f"{available_lang} {audio_f} {audio_lang.upper()}")
201
- return self._generate_title
202
-
203
- @generate_title.setter
204
- def generate_title(self, value):
205
- self._generate_title = value
206
-
207
180
  @property
208
181
  def guess_filename(self):
209
182
  if not self._guess_filename:
@@ -1,5 +1,5 @@
1
1
  # -*- coding: utf-8 -*-
2
- import argparse
2
+ from argparse import Namespace
3
3
  import os
4
4
 
5
5
  from common.bittorrent import BittorrentData
@@ -14,10 +14,10 @@ from view import custom_console
14
14
 
15
15
  class DocuManager:
16
16
 
17
- def __init__(self, contents: list[Media], cli: argparse.Namespace):
17
+ def __init__(self, contents: list[Media], cli: Namespace):
18
18
  self._my_tmdb = None
19
19
  self.contents: list['Media'] = contents
20
- self.cli: argparse = cli
20
+ self.cli: Namespace = cli
21
21
 
22
22
  def process(self, selected_tracker: str, tracker_name_list: list, tracker_archive: str) -> list[BittorrentData]:
23
23
 
@@ -1,5 +1,5 @@
1
1
  # -*- coding: utf-8 -*-
2
- import argparse
2
+ from argparse import Namespace
3
3
  import os
4
4
 
5
5
  from common.external_services.igdb.client import IGDBClient
@@ -14,7 +14,7 @@ from view import custom_console
14
14
 
15
15
  class GameManager:
16
16
 
17
- def __init__(self, contents: list["Media"], cli: argparse.Namespace):
17
+ def __init__(self, contents: list["Media"], cli: Namespace):
18
18
  """
19
19
  Initialize the GameManager with the given contents
20
20
 
@@ -23,7 +23,7 @@ class GameManager:
23
23
  cli (argparse.Namespace): user flag Command line
24
24
  """
25
25
  self.contents: list[Media] = contents
26
- self.cli: argparse = cli
26
+ self.cli: Namespace = cli
27
27
  self.igdb = IGDBClient()
28
28
 
29
29
  def process(self, selected_tracker: str, tracker_name_list: list, tracker_archive: str) -> list[BittorrentData]:
@@ -1,9 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
3
  import argparse
4
-
5
- import requests
6
-
7
4
  from unit3dup.media_manager.VideoManager import VideoManager
8
5
  from unit3dup.media_manager.GameManager import GameManager
9
6
  from unit3dup.media_manager.DocuManager import DocuManager
@@ -21,10 +18,11 @@ from view import custom_console
21
18
 
22
19
 
23
20
  class TorrentManager:
24
- def __init__(self, cli: argparse.Namespace, tracker_archive: str):
21
+ def __init__(self, cli: argparse.Namespace, tracker_archive: str, tags_list: dict):
25
22
 
26
23
  self.preferred_lang = my_language(config_settings.user_preferences.PREFERRED_LANG)
27
24
  self.tracker_archive = tracker_archive
25
+ self.tags_list = tags_list
28
26
  self.videos: list[Media] = []
29
27
  self.games: list[Media] = []
30
28
  self.doc: list[Media] = []
@@ -93,7 +91,7 @@ class TorrentManager:
93
91
  # Build the torrent file and upload each VIDEO to the trackers
94
92
  if self.videos:
95
93
  video_manager = VideoManager(contents=self.videos[:self.fast_load],
96
- cli=self.cli)
94
+ cli=self.cli, tags_list= self.tags_list)
97
95
  video_process_results = video_manager.process(selected_tracker=selected_tracker,
98
96
  tracker_name_list=trackers_name_list,
99
97
  tracker_archive=self.tracker_archive)
@@ -1,5 +1,5 @@
1
1
  # -*- coding: utf-8 -*-
2
- import argparse
2
+ from argparse import Namespace
3
3
  import os
4
4
 
5
5
  from common.external_services.theMovieDB.core.api import DbOnline
@@ -18,7 +18,7 @@ from view import custom_console
18
18
 
19
19
  class VideoManager:
20
20
 
21
- def __init__(self, contents: list[Media], cli: argparse.Namespace):
21
+ def __init__(self, contents: list[Media], cli: Namespace, tags_list: dict):
22
22
  """
23
23
  Initialize the VideoManager with the given contents
24
24
 
@@ -29,7 +29,8 @@ class VideoManager:
29
29
 
30
30
  self.torrent_found: bool = False
31
31
  self.contents: list[Media] = contents
32
- self.cli: argparse.Namespace = cli
32
+ self.cli: Namespace = cli
33
+ self.tags_list: dict = tags_list
33
34
 
34
35
  def process(self, selected_tracker: str, tracker_name_list: list, tracker_archive: str) -> list[BittorrentData]:
35
36
  """
@@ -57,7 +58,8 @@ class VideoManager:
57
58
  episode=content.guess_episode,
58
59
  releaser_sign=config_settings.user_preferences.RELEASER_SIGN,
59
60
  tags_position=config_settings.user_preferences.TAGS_POSITION,
60
- mediafile=content.mediafile
61
+ tags_list=self.tags_list,
62
+ mediafile=content.mediafile,
61
63
  )
62
64
  content.display_name = search_tags.process()
63
65
 
@@ -91,19 +93,6 @@ class VideoManager:
91
93
  if not db:
92
94
  continue
93
95
 
94
- # Update display name with Serie Title when requested by the user (-notitle)
95
- if self.cli.notitle:
96
- # Add generated metadata to the display_title
97
- if self.cli.gentitle:
98
- content.display_name = (f"{db_online.media_result.result.get_title()} "
99
- f"{db_online.media_result.year} ")
100
- content.display_name += " " + content.generate_title
101
- else:
102
- # otherwise keep the old meta_data and add the new display_title to it
103
- print()
104
- content.display_name = (f"{db_online.media_result.result.get_title()}"
105
- f" {db_online.media_result.year} {content.guess_title}")
106
-
107
96
  # Get meta from the media video
108
97
  video_info = Video(media=content, tmdb_id=db.video_id, trailer_key=db.trailer_key)
109
98
  video_info.build_info()
@@ -1,6 +1,6 @@
1
- import argparse
2
- import json
1
+ from argparse import Namespace
3
2
  import requests
3
+ import json
4
4
 
5
5
  from common.external_services.igdb.core.models.search import Game
6
6
  from common.trackers.trackers import TRACKData
@@ -15,7 +15,7 @@ from view import custom_console
15
15
 
16
16
 
17
17
  class UploadBot:
18
- def __init__(self, content: Media, tracker_name: str, cli: argparse.ArgumentParser):
18
+ def __init__(self, content: Media, tracker_name: str, cli: Namespace):
19
19
  self.cli = cli
20
20
  self.content = content
21
21
  self.tracker_name = tracker_name
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