DDownloader 0.4.1__tar.gz → 0.4.2__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 (57) hide show
  1. {ddownloader-0.4.1 → ddownloader-0.4.2}/DDownloader/main.py +14 -1
  2. ddownloader-0.4.2/DDownloader/modules/__init__.py +1 -0
  3. {ddownloader-0.4.1 → ddownloader-0.4.2}/DDownloader/modules/args_parser.py +1 -0
  4. {ddownloader-0.4.1 → ddownloader-0.4.2}/DDownloader/modules/banners.py +2 -1
  5. {ddownloader-0.4.1 → ddownloader-0.4.2}/DDownloader/modules/downloader.py +72 -0
  6. {ddownloader-0.4.1 → ddownloader-0.4.2}/PKG-INFO +3 -2
  7. {ddownloader-0.4.1 → ddownloader-0.4.2}/pyproject.toml +2 -2
  8. ddownloader-0.4.1/DDownloader/bin/Logs/2025-02-22_06-23-57-591.log +0 -10996
  9. ddownloader-0.4.1/DDownloader/bin/Logs/2025-02-22_10-40-22-275.log +0 -10979
  10. ddownloader-0.4.1/DDownloader/bin/Logs/2025-02-22_10-47-26-730.log +0 -108
  11. ddownloader-0.4.1/DDownloader/bin/Logs/2025-02-22_11-10-51-275.log +0 -11317
  12. ddownloader-0.4.1/DDownloader/bin/Logs/2025-02-22_11-38-34-609.log +0 -82
  13. ddownloader-0.4.1/DDownloader/bin/Logs/2025-02-22_11-40-04-799.log +0 -10978
  14. ddownloader-0.4.1/DDownloader/bin/Logs/2025-02-22_12-20-28-623.log +0 -115
  15. ddownloader-0.4.1/DDownloader/bin/Logs/2025-02-28_01-38-30-721.log +0 -19
  16. ddownloader-0.4.1/DDownloader/bin/Logs/2025-02-28_01-38-52-028.log +0 -19
  17. ddownloader-0.4.1/DDownloader/bin/Logs/2025-02-28_01-39-01-077.log +0 -17
  18. ddownloader-0.4.1/DDownloader/bin/Logs/2025-02-28_01-39-17-503.log +0 -20
  19. ddownloader-0.4.1/DDownloader/bin/Logs/2025-02-28_01-39-34-955.log +0 -29
  20. ddownloader-0.4.1/DDownloader/bin/Logs/2025-02-28_01-39-55-379.log +0 -18
  21. ddownloader-0.4.1/DDownloader/bin/Logs/2025-02-28_01-40-41-293.log +0 -74
  22. ddownloader-0.4.1/DDownloader/bin/Logs/2025-02-28_01-42-15-463.log +0 -60
  23. ddownloader-0.4.1/DDownloader/bin/Logs/2025-03-04_07-09-17-079.log +0 -119
  24. ddownloader-0.4.1/DDownloader/bin/Logs/2025-03-06_02-58-30-968.log +0 -99
  25. ddownloader-0.4.1/DDownloader/bin/Logs/2025-03-06_03-05-58-847.log +0 -25
  26. ddownloader-0.4.1/DDownloader/bin/Logs/2025-03-08_00-06-25-965.log +0 -98
  27. ddownloader-0.4.1/DDownloader/bin/Logs/2025-03-09_08-25-37-490.log +0 -73
  28. ddownloader-0.4.1/DDownloader/bin/Logs/2025-03-09_08-30-17-945.log +0 -83
  29. ddownloader-0.4.1/DDownloader/bin/Logs/2025-03-09_08-30-46-741.log +0 -85
  30. ddownloader-0.4.1/DDownloader/bin/Logs/2025-03-09_08-35-00-461.log +0 -77
  31. ddownloader-0.4.1/DDownloader/bin/Logs/2025-03-09_08-47-42-424.log +0 -81
  32. ddownloader-0.4.1/DDownloader/bin/Logs/2025-03-12_07-53-39-189.log +0 -61
  33. ddownloader-0.4.1/DDownloader/bin/Logs/2025-03-14_18-55-10-031.log +0 -100
  34. ddownloader-0.4.1/DDownloader/bin/Logs/2025-03-17_02-16-55-723.log +0 -10
  35. ddownloader-0.4.1/DDownloader/bin/Logs/2025-03-17_02-18-48-738.log +0 -9
  36. ddownloader-0.4.1/DDownloader/bin/Logs/2025-03-17_02-55-02-627.log +0 -29
  37. ddownloader-0.4.1/DDownloader/bin/Logs/2025-03-17_02-56-50-289.log +0 -31
  38. ddownloader-0.4.1/DDownloader/bin/Logs/2025-03-22_03-09-50-038.log +0 -31
  39. ddownloader-0.4.1/DDownloader/bin/Logs/2025-03-22_03-10-15-122.log +0 -15
  40. ddownloader-0.4.1/DDownloader/bin/Logs/2025-03-22_03-10-32-099.log +0 -15
  41. ddownloader-0.4.1/DDownloader/bin/Logs/2025-03-22_03-12-53-637.log +0 -16
  42. ddownloader-0.4.1/DDownloader/bin/Logs/2025-03-22_03-13-21-065.log +0 -53
  43. ddownloader-0.4.1/DDownloader/bin/Logs/2025-03-22_03-14-51-221.log +0 -843
  44. ddownloader-0.4.1/DDownloader/bin/Logs/2025-04-15_00-26-16-899.log +0 -85
  45. ddownloader-0.4.1/DDownloader/modules/__init__.py +0 -1
  46. {ddownloader-0.4.1 → ddownloader-0.4.2}/DDownloader/__init__.py +0 -0
  47. {ddownloader-0.4.1 → ddownloader-0.4.2}/DDownloader/bin/N_m3u8DL-RE.exe +0 -0
  48. {ddownloader-0.4.1 → ddownloader-0.4.2}/DDownloader/bin/aria2c.exe +0 -0
  49. {ddownloader-0.4.1 → ddownloader-0.4.2}/DDownloader/bin/ffmpeg.exe +0 -0
  50. {ddownloader-0.4.1 → ddownloader-0.4.2}/DDownloader/bin/mkvmerge.exe +0 -0
  51. {ddownloader-0.4.1 → ddownloader-0.4.2}/DDownloader/bin/mp4decrypt.exe +0 -0
  52. {ddownloader-0.4.1 → ddownloader-0.4.2}/DDownloader/bin/shaka-packager.exe +0 -0
  53. {ddownloader-0.4.1 → ddownloader-0.4.2}/DDownloader/bin/yt-dlp.exe +0 -0
  54. {ddownloader-0.4.1 → ddownloader-0.4.2}/DDownloader/modules/helper.py +0 -0
  55. {ddownloader-0.4.1 → ddownloader-0.4.2}/DDownloader/modules/streamlink.py +0 -0
  56. {ddownloader-0.4.1 → ddownloader-0.4.2}/LICENSE +0 -0
  57. {ddownloader-0.4.1 → ddownloader-0.4.2}/README.md +0 -0
@@ -89,6 +89,7 @@ def main():
89
89
  logger.info("YouTube URL detected. Initializing YouTube downloader...")
90
90
  print(Fore.RED + "═" * 100 + Fore.RESET)
91
91
  is_playlist = "list=" in args.url
92
+ downloader.cookies = args.cookies
92
93
  downloader.youtube_downloader(
93
94
  url=args.url,
94
95
  output_file=os.path.join(downloads_dir, args.output),
@@ -96,8 +97,20 @@ def main():
96
97
  playlist=is_playlist
97
98
  )
98
99
  exit(0)
100
+ elif re.search(r"iq\.com", args.url, re.IGNORECASE):
101
+ logger.info("IQ.com URL detected. Initializing IQ.com downloader...")
102
+ print(Fore.RED + "═" * 100 + Fore.RESET)
103
+ # Set default output name if not provided
104
+ output_name = args.output if args.output else "iq_video"
105
+ downloader.cookies = args.cookies
106
+ downloader.iq_downloader(
107
+ url=args.url,
108
+ output_file=os.path.join(downloads_dir, output_name),
109
+ download_type="mp4"
110
+ )
111
+ exit(0)
99
112
  else:
100
- logger.error("Unsupported URL format. Please provide a valid DASH (.mpd), HLS (.m3u8), ISM (.ism), or YouTube URL.")
113
+ logger.error("Unsupported URL format. Please provide a valid DASH (.mpd), HLS (.m3u8), ISM (.ism), YouTube, or IQ.com URL.")
101
114
  exit(1)
102
115
 
103
116
  downloader.manifest_url = args.url
@@ -0,0 +1 @@
1
+ __version__ = "0.4.2"
@@ -15,6 +15,7 @@ def parse_arguments():
15
15
  parser.add_argument("-o", "--output", help=argparse.SUPPRESS)
16
16
  parser.add_argument("-k", "--key", action="append", help=argparse.SUPPRESS)
17
17
  parser.add_argument("-H", "--header", action="append", help=argparse.SUPPRESS)
18
+ parser.add_argument("-c", "--cookies", help=argparse.SUPPRESS)
18
19
  parser.add_argument("-i", "--input", help=argparse.SUPPRESS)
19
20
  parser.add_argument("-q", "--quality", help=argparse.SUPPRESS)
20
21
  parser.add_argument("--auto-select",
@@ -23,7 +23,7 @@ def banners():
23
23
  stdout.write(""+Fore.YELLOW +"╔════════════════════════════════════════════════════════════════════════════╝\n")
24
24
  stdout.write(""+Fore.YELLOW +"║ \x1b[38;2;255;20;147m• "+Fore.GREEN+"GITHUB "+Fore.RED+" |"+Fore.LIGHTWHITE_EX+" GITHUB.COM/THATNOTEASY "+Fore.YELLOW+"║\n")
25
25
  stdout.write(""+Fore.YELLOW +"╚════════════════════════════════════════════════════════════════════════════╝\n")
26
- print(f"{Fore.YELLOW}[DDownloader] - {Fore.GREEN}A DRM-Protected & Non-Protected Content Downloader - {Fore.RED}[V0.4.1] \n{Fore.RESET}")
26
+ print(f"{Fore.YELLOW}[DDownloader] - {Fore.GREEN}A DRM-Protected & Non-Protected Content Downloader - {Fore.RED}[V0.4.2] \n{Fore.RESET}")
27
27
 
28
28
  # =========================================================================================================== #
29
29
 
@@ -45,6 +45,7 @@ def display_help():
45
45
  f" {Fore.GREEN}-o, --output{' ' * 19}{Style.RESET_ALL}Name of the output file 💾\n"
46
46
  f" {Fore.GREEN}-k, --key{' ' * 22}{Style.RESET_ALL}Decryption key in KID:KEY format 🔑\n"
47
47
  f" {Fore.GREEN}-H, --header{' ' * 19}{Style.RESET_ALL}Custom HTTP headers (e.g., User-Agent: value) 📋\n"
48
+ f" {Fore.GREEN}-c, --cookies{' ' * 19}{Style.RESET_ALL}Cookies file (e.g., netscape/json formatter) 📋\n"
48
49
  f"{Fore.RED}.++" + "═" * 100 + f"++.{Style.RESET_ALL}\n"
49
50
  f" {Fore.GREEN}-i, --input{' ' * 20}{Style.RESET_ALL}Input file for re-encoding. 📂\n"
50
51
  f" {Fore.GREEN}-q, --quality{' ' * 18}{Style.RESET_ALL}Target quality: HD, FHD, UHD. 🎥\n"
@@ -16,6 +16,7 @@ class DOWNLOADER:
16
16
  self.proxy = None
17
17
  self.decryption_keys = []
18
18
  self.headers = []
19
+ self.cookies = None
19
20
  self.binary_path = None
20
21
  self.auto_select = False
21
22
 
@@ -120,6 +121,73 @@ class DOWNLOADER:
120
121
  except Exception as e:
121
122
  logger.error(Fore.RED + f"An unexpected error occurred: {e}" + Fore.RESET)
122
123
 
124
+ # =========================================================================================================== #
125
+
126
+ def iq_downloader(self, url, output_file, download_type="mp4"):
127
+ """
128
+ Download a video from IQ.com using yt-dlp.
129
+
130
+ Args:
131
+ url (str): The IQ.com video URL.
132
+ output_file (str): The output file path to save the video.
133
+ download_type (str): The type of download ("mp4" for video, "mp3" for audio).
134
+ """
135
+ try:
136
+ # Get the yt-dlp binary path
137
+ yt_dlp_path = self._get_binary_path("yt-dlp")
138
+
139
+ # Determine the output file extension based on download type
140
+ if download_type == "mp3":
141
+ output_file = os.path.splitext(output_file)[0] + ".mp3"
142
+ elif download_type == "mp4":
143
+ output_file = os.path.splitext(output_file)[0] + ".mp4"
144
+ else:
145
+ logger.error(Fore.RED + f"Invalid download type: {download_type}. Use 'mp4' or 'mp3'." + Fore.RESET)
146
+ return
147
+
148
+ # Build the yt-dlp command for IQ.com
149
+ command = [
150
+ yt_dlp_path,
151
+ "-o", f"\"{output_file}\"", # Output file
152
+ "--no-check-certificate", # Bypass certificate verification
153
+ "--ignore-errors", # Ignore errors and continue downloading
154
+ ]
155
+
156
+ # Add cookies if provided
157
+ if self.cookies:
158
+ command.extend(["--cookies", f"\"{self.cookies}\""])
159
+
160
+ # Add audio extraction options if downloading MP3
161
+ if download_type == "mp3":
162
+ command.extend([
163
+ "--extract-audio", # Extract audio
164
+ "--audio-format", "mp3", # Convert to MP3
165
+ "--audio-quality", "0", # Best quality
166
+ ])
167
+ else:
168
+ # For MP4, download the best video and audio formats and merge them
169
+ command.extend([
170
+ "-f", "bv*+ba/b", # Download best video + best audio, or fallback to best combined format
171
+ "--merge-output-format", "mp4", # Merge into MP4
172
+ ])
173
+
174
+ # Add the IQ.com URL
175
+ command.append(url)
176
+
177
+ # Execute the command
178
+ self._execute_command(command)
179
+
180
+ # Check if output file exists to confirm success
181
+ if os.path.isfile(output_file):
182
+ logger.info(f"Download from IQ.com completed successfully. Output saved to: {output_file}")
183
+ return output_file
184
+ else:
185
+ logger.error(f"Download from IQ.com failed. Output file not created: {output_file}")
186
+ return None
187
+
188
+ except Exception as e:
189
+ logger.error(Fore.RED + f"An unexpected error occurred: {e}" + Fore.RESET)
190
+
123
191
  # =========================================================================================================== #
124
192
 
125
193
  def re_encode_content(self, input_file, quality, codec="libx265", crf=23, preset="superfast", audio_bitrate="256k", fps=60):
@@ -256,6 +324,10 @@ class DOWNLOADER:
256
324
  "--ignore-errors", # Ignore errors and continue downloading
257
325
  ]
258
326
 
327
+ # Add cookies if provided
328
+ if self.cookies:
329
+ command.extend(["--cookies", f"\"{self.cookies}\""])
330
+
259
331
  # Add playlist-specific options if the URL is a playlist
260
332
  if playlist:
261
333
  command.extend([
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: DDownloader
3
- Version: 0.4.1
3
+ Version: 0.4.2
4
4
  Summary: A downloader for DRM-protected & Non DRM-protected content.
5
5
  License: MIT License
6
6
 
@@ -23,6 +23,7 @@ License: MIT License
23
23
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24
24
  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
25
25
  IN THE SOFTWARE.
26
+ License-File: LICENSE
26
27
  Author: ThatNotEasy
27
28
  Author-email: apidotmy@proton.me
28
29
  Requires-Python: >=3.7
@@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"
4
4
 
5
5
  [project]
6
6
  name = "DDownloader"
7
- version = "0.4.1"
7
+ version = "0.4.2"
8
8
  description = "A downloader for DRM-protected & Non DRM-protected content."
9
9
  readme = { file = "README.md", content-type = "text/markdown" }
10
10
  authors = [
@@ -25,7 +25,7 @@ classifiers = [
25
25
 
26
26
  [tool.poetry]
27
27
  name = "DDownloader"
28
- version = "0.4.1"
28
+ version = "0.4.2"
29
29
  description = "A downloader for DRM-protected & Non DRM-protected content."
30
30
  authors = ["ThatNotEasy <apidotmy@proton.me>"]
31
31
  license = "MIT"