media-downloader 2.1.2__py3-none-any.whl → 2.1.3__py3-none-any.whl

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.

Potentially problematic release.


This version of media-downloader might be problematic. Click here for more details.

@@ -1,24 +1,29 @@
1
1
  #!/usr/bin/env python
2
2
  # coding: utf-8
3
3
 
4
- from media_downloader.media_downloader import (
5
- media_downloader,
6
- setup_logging,
7
- MediaDownloader,
8
- )
9
- from media_downloader.media_downloader_mcp import (
10
- media_downloader_mcp,
11
- )
4
+ import importlib
5
+ import inspect
6
+
7
+ # List of modules to import from
8
+ MODULES = [
9
+ 'media_downloader.media_downloader',
10
+ 'media_downloader.media_downloader_mcp',
11
+ ]
12
+
13
+ # Initialize __all__ to expose all public classes and functions
14
+ __all__ = []
15
+
16
+ # Dynamically import all classes and functions from the specified modules
17
+ for module_name in MODULES:
18
+ module = importlib.import_module(module_name)
19
+ for name, obj in inspect.getmembers(module):
20
+ # Include only classes and functions, excluding private (starting with '_')
21
+ if (inspect.isclass(obj) or inspect.isfunction(obj)) and not name.startswith('_'):
22
+ globals()[name] = obj
23
+ __all__.append(name)
12
24
 
13
25
  """
14
26
  media-downloader
15
27
 
16
28
  Download videos and audio from the internet!
17
- """
18
-
19
- __all__ = [
20
- "media_downloader",
21
- "media_downloader_mcp",
22
- "setup_logging",
23
- "MediaDownloader",
24
- ]
29
+ """
@@ -4,7 +4,7 @@ import argparse
4
4
  import os
5
5
  import sys
6
6
  import logging
7
- from typing import Optional
7
+ from typing import Optional, Union, Dict, Any
8
8
  from media_downloader import MediaDownloader, setup_logging
9
9
  from fastmcp import FastMCP, Context
10
10
  from pydantic import Field
@@ -15,14 +15,14 @@ setup_logging(is_mcp_server=True, log_file="media_downloader_mcp.log")
15
15
  mcp = FastMCP(name="MediaDownloaderServer")
16
16
 
17
17
 
18
- def to_boolean(string):
19
- # Normalize the string: strip whitespace and convert to lowercase
18
+ def to_boolean(string: Union[str, bool] = None) -> bool:
19
+ if isinstance(string, bool):
20
+ return string
21
+ if not string:
22
+ return False
20
23
  normalized = str(string).strip().lower()
21
-
22
- # Define valid true/false values
23
24
  true_values = {"t", "true", "y", "yes", "1"}
24
25
  false_values = {"f", "false", "n", "no", "0"}
25
-
26
26
  if normalized in true_values:
27
27
  return True
28
28
  elif normalized in false_values:
@@ -31,6 +31,7 @@ def to_boolean(string):
31
31
  raise ValueError(f"Cannot convert '{string}' to boolean")
32
32
 
33
33
 
34
+
34
35
  @mcp.tool(
35
36
  annotations={
36
37
  "title": "Download Media",
@@ -42,22 +43,22 @@ def to_boolean(string):
42
43
  tags={"collection_management"},
43
44
  )
44
45
  async def download_media(
45
- video_url: str = Field(description="Video URL to Download", default=None),
46
- download_directory: Optional[str] = Field(
47
- description="The directory where the media will be saved. If None, uses default directory.",
48
- default=os.environ.get("DOWNLOAD_DIRECTORY", None),
49
- ),
50
- audio_only: Optional[bool] = Field(
51
- description="Downloads only the audio",
52
- default=to_boolean(os.environ.get("AUDIO_ONLY", False)),
53
- ),
54
- ctx: Context = Field(
55
- description="MCP context for progress reporting.", default=None
56
- ),
57
- ) -> str:
46
+ video_url: str = Field(description="Video URL to Download", default=None),
47
+ download_directory: Optional[str] = Field(
48
+ description="The directory where the media will be saved. If None, uses default directory.",
49
+ default=os.environ.get("DOWNLOAD_DIRECTORY", None),
50
+ ),
51
+ audio_only: Optional[bool] = Field(
52
+ description="Downloads only the audio",
53
+ default=to_boolean(os.environ.get("AUDIO_ONLY", False)),
54
+ ),
55
+ ctx: Context = Field(
56
+ description="MCP context for progress reporting.", default=None
57
+ ),
58
+ ) -> Dict[str, Any]:
58
59
  """
59
- Downloads media from a given URL to the specified directory. Download as a video or audio file
60
- Returns the location of the Downloaded file
60
+ Downloads media from a given URL to the specified directory. Download as a video or audio file.
61
+ Returns a Dictionary response with status, download directory, audio only, and other details.
61
62
  """
62
63
  logger = logging.getLogger("MediaDownloader")
63
64
  logger.debug(
@@ -66,9 +67,21 @@ async def download_media(
66
67
 
67
68
  try:
68
69
  if not video_url:
69
- raise ValueError("video_url must not be empty")
70
-
71
- download_directory = f'{os.path.expanduser("~")}/Downloads'
70
+ return {
71
+ "status": 400,
72
+ "message": "Invalid input: video_url must not be empty",
73
+ "data": {
74
+ "video_url": video_url,
75
+ "download_directory": download_directory,
76
+ "audio_only": audio_only
77
+ },
78
+ "error": "video_url must not be empty"
79
+ }
80
+
81
+ if download_directory:
82
+ download_directory = os.path.expanduser(download_directory)
83
+ else:
84
+ download_directory = f'{os.path.expanduser("~")}/Downloads'
72
85
  os.makedirs(download_directory, exist_ok=True)
73
86
 
74
87
  downloader = MediaDownloader(
@@ -92,7 +105,16 @@ async def download_media(
92
105
  file_path = downloader.download_video(link=video_url)
93
106
 
94
107
  if not file_path or not os.path.exists(file_path):
95
- raise RuntimeError("Download failed or file not found")
108
+ return {
109
+ "status": 500,
110
+ "message": "Download failed: file not found",
111
+ "data": {
112
+ "video_url": video_url,
113
+ "download_directory": download_directory,
114
+ "audio_only": audio_only
115
+ },
116
+ "error": "Download failed or file not found"
117
+ }
96
118
 
97
119
  # Report completion
98
120
  if ctx:
@@ -100,15 +122,32 @@ async def download_media(
100
122
  logger.debug("Reported final progress: 100/100")
101
123
 
102
124
  logger.debug(f"Download completed, file path: {file_path}")
103
- return file_path
125
+ return {
126
+ "status": 200,
127
+ "message": "Media downloaded successfully",
128
+ "data": {
129
+ "file_path": file_path,
130
+ "download_directory": download_directory,
131
+ "audio_only": audio_only,
132
+ "video_url": video_url
133
+ }
134
+ }
104
135
  except Exception as e:
105
- logger.error(f"Failed to download media: {str(e)}")
106
- raise RuntimeError(f"Failed to download media: {str(e)}")
136
+ logger.error(f"Failed to download media: {str(e)}\nParams: video_url: {video_url}, download directory: {download_directory}, audio only: {audio_only}")
137
+ return {
138
+ "status": 500,
139
+ "message": "Failed to download media",
140
+ "data": {
141
+ "video_url": video_url,
142
+ "download_directory": download_directory,
143
+ "audio_only": audio_only
144
+ },
145
+ "error": str(e)
146
+ }
107
147
 
108
148
 
109
149
  def media_downloader_mcp():
110
150
  parser = argparse.ArgumentParser(description="Run media downloader MCP server.")
111
-
112
151
  parser.add_argument(
113
152
  "-t",
114
153
  "--transport",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: media-downloader
3
- Version: 2.1.2
3
+ Version: 2.1.3
4
4
  Summary: Download audio/videos from the internet!
5
5
  Author-email: Audel Rouhi <knucklessg1@gmail.com>
6
6
  License: MIT
@@ -12,7 +12,7 @@ Classifier: Programming Language :: Python :: 3
12
12
  Requires-Python: >=3.8
13
13
  Description-Content-Type: text/markdown
14
14
  License-File: LICENSE
15
- Requires-Dist: yt-dlp>=2025.8.20
15
+ Requires-Dist: yt-dlp>=2025.9.26
16
16
  Requires-Dist: fastmcp>=2.11.3
17
17
  Dynamic: license-file
18
18
 
@@ -38,7 +38,7 @@ Dynamic: license-file
38
38
  ![PyPI - Wheel](https://img.shields.io/pypi/wheel/media-downloader)
39
39
  ![PyPI - Implementation](https://img.shields.io/pypi/implementation/media-downloader)
40
40
 
41
- *Version: 2.1.2*
41
+ *Version: 2.1.3*
42
42
 
43
43
  Download videos and audio from the internet!
44
44
 
@@ -0,0 +1,11 @@
1
+ media_downloader/__init__.py,sha256=rnzjpKVjjq1kruHPnSoIdD_munB1olHMJA5onxM2dc0,798
2
+ media_downloader/__main__.py,sha256=5T-EOUX1ANJOd2ut4GoI9mvDpNCo25yZcOAZdnhzQI0,169
3
+ media_downloader/media_downloader.py,sha256=L20XUnnJ5UWq4ZZQIdmi7ZrOl2hXKSZkjNDH6l0eqKc,9097
4
+ media_downloader/media_downloader_mcp.py,sha256=8XPfTVOqjvkNY3V4stXDe5kGTA0OiWM-rOZLXQjIY0I,6378
5
+ media_downloader-2.1.3.dist-info/licenses/LICENSE,sha256=Z1xmcrPHBnGCETO_LLQJUeaSNBSnuptcDVTt4kaPUOE,1060
6
+ tests/test_mcp.py,sha256=mbe5O75w2SDr7-7nbzDSAHhMYx4qZKccU77h8Cp5LSo,1509
7
+ media_downloader-2.1.3.dist-info/METADATA,sha256=DDVpPSIvjd1Dj6fN-f_e6eg1Tl1cXsKW1bL5RL-fVFE,5979
8
+ media_downloader-2.1.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
9
+ media_downloader-2.1.3.dist-info/entry_points.txt,sha256=X_Ig7LdYJePZ9BQPMGyA2dSmBIQIYMHXCnTOeEbhgio,170
10
+ media_downloader-2.1.3.dist-info/top_level.txt,sha256=baD75VEFaytQEs4mmqyK1M0iZ5Y0HGF62vvtbSfbZCA,23
11
+ media_downloader-2.1.3.dist-info/RECORD,,
@@ -1,11 +0,0 @@
1
- media_downloader/__init__.py,sha256=kSGgs6_eniQMrwlOcvtjwNeq5xbFl93KUciQpdY2NDw,414
2
- media_downloader/__main__.py,sha256=5T-EOUX1ANJOd2ut4GoI9mvDpNCo25yZcOAZdnhzQI0,169
3
- media_downloader/media_downloader.py,sha256=L20XUnnJ5UWq4ZZQIdmi7ZrOl2hXKSZkjNDH6l0eqKc,9097
4
- media_downloader/media_downloader_mcp.py,sha256=IqfxtmIw12QTFwBtows4r7749baJfz8zoUZBRmhBarg,4820
5
- media_downloader-2.1.2.dist-info/licenses/LICENSE,sha256=Z1xmcrPHBnGCETO_LLQJUeaSNBSnuptcDVTt4kaPUOE,1060
6
- tests/test_mcp.py,sha256=mbe5O75w2SDr7-7nbzDSAHhMYx4qZKccU77h8Cp5LSo,1509
7
- media_downloader-2.1.2.dist-info/METADATA,sha256=wNKKHXAlomUmAKR3kwfdkLckgj50N6TRHxeRKkrfItU,5979
8
- media_downloader-2.1.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
9
- media_downloader-2.1.2.dist-info/entry_points.txt,sha256=X_Ig7LdYJePZ9BQPMGyA2dSmBIQIYMHXCnTOeEbhgio,170
10
- media_downloader-2.1.2.dist-info/top_level.txt,sha256=baD75VEFaytQEs4mmqyK1M0iZ5Y0HGF62vvtbSfbZCA,23
11
- media_downloader-2.1.2.dist-info/RECORD,,