media-downloader 2.1.2__tar.gz → 2.1.4__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.
Potentially problematic release.
This version of media-downloader might be problematic. Click here for more details.
- {media_downloader-2.1.2/media_downloader.egg-info → media_downloader-2.1.4}/PKG-INFO +3 -3
- {media_downloader-2.1.2 → media_downloader-2.1.4}/README.md +1 -1
- media_downloader-2.1.4/media_downloader/__init__.py +31 -0
- {media_downloader-2.1.2 → media_downloader-2.1.4}/media_downloader/media_downloader_mcp.py +57 -17
- {media_downloader-2.1.2 → media_downloader-2.1.4/media_downloader.egg-info}/PKG-INFO +3 -3
- media_downloader-2.1.4/media_downloader.egg-info/requires.txt +2 -0
- {media_downloader-2.1.2 → media_downloader-2.1.4}/pyproject.toml +2 -2
- media_downloader-2.1.4/requirements.txt +2 -0
- media_downloader-2.1.2/media_downloader/__init__.py +0 -24
- media_downloader-2.1.2/media_downloader.egg-info/requires.txt +0 -2
- media_downloader-2.1.2/requirements.txt +0 -2
- {media_downloader-2.1.2 → media_downloader-2.1.4}/LICENSE +0 -0
- {media_downloader-2.1.2 → media_downloader-2.1.4}/MANIFEST.in +0 -0
- {media_downloader-2.1.2 → media_downloader-2.1.4}/media_downloader/__main__.py +0 -0
- {media_downloader-2.1.2 → media_downloader-2.1.4}/media_downloader/media_downloader.py +0 -0
- {media_downloader-2.1.2 → media_downloader-2.1.4}/media_downloader.egg-info/SOURCES.txt +0 -0
- {media_downloader-2.1.2 → media_downloader-2.1.4}/media_downloader.egg-info/dependency_links.txt +0 -0
- {media_downloader-2.1.2 → media_downloader-2.1.4}/media_downloader.egg-info/entry_points.txt +0 -0
- {media_downloader-2.1.2 → media_downloader-2.1.4}/media_downloader.egg-info/top_level.txt +0 -0
- {media_downloader-2.1.2 → media_downloader-2.1.4}/setup.cfg +0 -0
- {media_downloader-2.1.2 → media_downloader-2.1.4}/tests/test_mcp.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: media-downloader
|
|
3
|
-
Version: 2.1.
|
|
3
|
+
Version: 2.1.4
|
|
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.
|
|
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
|

|
|
39
39
|

|
|
40
40
|
|
|
41
|
-
*Version: 2.1.
|
|
41
|
+
*Version: 2.1.4*
|
|
42
42
|
|
|
43
43
|
Download videos and audio from the internet!
|
|
44
44
|
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# coding: utf-8
|
|
3
|
+
|
|
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
|
+
"_"
|
|
23
|
+
):
|
|
24
|
+
globals()[name] = obj
|
|
25
|
+
__all__.append(name)
|
|
26
|
+
|
|
27
|
+
"""
|
|
28
|
+
media-downloader
|
|
29
|
+
|
|
30
|
+
Download videos and audio from the internet!
|
|
31
|
+
"""
|
|
@@ -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
|
-
|
|
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:
|
|
@@ -54,10 +54,10 @@ async def download_media(
|
|
|
54
54
|
ctx: Context = Field(
|
|
55
55
|
description="MCP context for progress reporting.", default=None
|
|
56
56
|
),
|
|
57
|
-
) -> str:
|
|
57
|
+
) -> Dict[str, Any]:
|
|
58
58
|
"""
|
|
59
|
-
Downloads media from a given URL to the specified directory. Download as a video or audio file
|
|
60
|
-
Returns
|
|
59
|
+
Downloads media from a given URL to the specified directory. Download as a video or audio file.
|
|
60
|
+
Returns a Dictionary response with status, download directory, audio only, and other details.
|
|
61
61
|
"""
|
|
62
62
|
logger = logging.getLogger("MediaDownloader")
|
|
63
63
|
logger.debug(
|
|
@@ -66,9 +66,21 @@ async def download_media(
|
|
|
66
66
|
|
|
67
67
|
try:
|
|
68
68
|
if not video_url:
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
69
|
+
return {
|
|
70
|
+
"status": 400,
|
|
71
|
+
"message": "Invalid input: video_url must not be empty",
|
|
72
|
+
"data": {
|
|
73
|
+
"video_url": video_url,
|
|
74
|
+
"download_directory": download_directory,
|
|
75
|
+
"audio_only": audio_only,
|
|
76
|
+
},
|
|
77
|
+
"error": "video_url must not be empty",
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if download_directory:
|
|
81
|
+
download_directory = os.path.expanduser(download_directory)
|
|
82
|
+
else:
|
|
83
|
+
download_directory = f'{os.path.expanduser("~")}/Downloads'
|
|
72
84
|
os.makedirs(download_directory, exist_ok=True)
|
|
73
85
|
|
|
74
86
|
downloader = MediaDownloader(
|
|
@@ -92,7 +104,16 @@ async def download_media(
|
|
|
92
104
|
file_path = downloader.download_video(link=video_url)
|
|
93
105
|
|
|
94
106
|
if not file_path or not os.path.exists(file_path):
|
|
95
|
-
|
|
107
|
+
return {
|
|
108
|
+
"status": 500,
|
|
109
|
+
"message": "Download failed: file not found",
|
|
110
|
+
"data": {
|
|
111
|
+
"video_url": video_url,
|
|
112
|
+
"download_directory": download_directory,
|
|
113
|
+
"audio_only": audio_only,
|
|
114
|
+
},
|
|
115
|
+
"error": "Download failed or file not found",
|
|
116
|
+
}
|
|
96
117
|
|
|
97
118
|
# Report completion
|
|
98
119
|
if ctx:
|
|
@@ -100,15 +121,34 @@ async def download_media(
|
|
|
100
121
|
logger.debug("Reported final progress: 100/100")
|
|
101
122
|
|
|
102
123
|
logger.debug(f"Download completed, file path: {file_path}")
|
|
103
|
-
return
|
|
124
|
+
return {
|
|
125
|
+
"status": 200,
|
|
126
|
+
"message": "Media downloaded successfully",
|
|
127
|
+
"data": {
|
|
128
|
+
"file_path": file_path,
|
|
129
|
+
"download_directory": download_directory,
|
|
130
|
+
"audio_only": audio_only,
|
|
131
|
+
"video_url": video_url,
|
|
132
|
+
},
|
|
133
|
+
}
|
|
104
134
|
except Exception as e:
|
|
105
|
-
logger.error(
|
|
106
|
-
|
|
135
|
+
logger.error(
|
|
136
|
+
f"Failed to download media: {str(e)}\nParams: video_url: {video_url}, download directory: {download_directory}, audio only: {audio_only}"
|
|
137
|
+
)
|
|
138
|
+
return {
|
|
139
|
+
"status": 500,
|
|
140
|
+
"message": "Failed to download media",
|
|
141
|
+
"data": {
|
|
142
|
+
"video_url": video_url,
|
|
143
|
+
"download_directory": download_directory,
|
|
144
|
+
"audio_only": audio_only,
|
|
145
|
+
},
|
|
146
|
+
"error": str(e),
|
|
147
|
+
}
|
|
107
148
|
|
|
108
149
|
|
|
109
150
|
def media_downloader_mcp():
|
|
110
151
|
parser = argparse.ArgumentParser(description="Run media downloader MCP server.")
|
|
111
|
-
|
|
112
152
|
parser.add_argument(
|
|
113
153
|
"-t",
|
|
114
154
|
"--transport",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: media-downloader
|
|
3
|
-
Version: 2.1.
|
|
3
|
+
Version: 2.1.4
|
|
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.
|
|
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
|

|
|
39
39
|

|
|
40
40
|
|
|
41
|
-
*Version: 2.1.
|
|
41
|
+
*Version: 2.1.4*
|
|
42
42
|
|
|
43
43
|
Download videos and audio from the internet!
|
|
44
44
|
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "media-downloader"
|
|
7
|
-
version = "2.1.
|
|
7
|
+
version = "2.1.4"
|
|
8
8
|
description = "Download audio/videos from the internet!\nHost an MCP Server for Agentic AI to download videos!"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
authors = [{ name = "Audel Rouhi", email = "knucklessg1@gmail.com" }]
|
|
@@ -18,7 +18,7 @@ classifiers = [
|
|
|
18
18
|
]
|
|
19
19
|
requires-python = ">=3.8"
|
|
20
20
|
dependencies = [
|
|
21
|
-
"yt-dlp>=2025.
|
|
21
|
+
"yt-dlp>=2025.9.26",
|
|
22
22
|
"fastmcp>=2.11.3"
|
|
23
23
|
]
|
|
24
24
|
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python
|
|
2
|
-
# coding: utf-8
|
|
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
|
-
)
|
|
12
|
-
|
|
13
|
-
"""
|
|
14
|
-
media-downloader
|
|
15
|
-
|
|
16
|
-
Download videos and audio from the internet!
|
|
17
|
-
"""
|
|
18
|
-
|
|
19
|
-
__all__ = [
|
|
20
|
-
"media_downloader",
|
|
21
|
-
"media_downloader_mcp",
|
|
22
|
-
"setup_logging",
|
|
23
|
-
"MediaDownloader",
|
|
24
|
-
]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{media_downloader-2.1.2 → media_downloader-2.1.4}/media_downloader.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{media_downloader-2.1.2 → media_downloader-2.1.4}/media_downloader.egg-info/entry_points.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|