mfget 0.1.1__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.
mfget-0.1.1/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Mediafire-DL contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
mfget-0.1.1/PKG-INFO ADDED
@@ -0,0 +1,235 @@
1
+ Metadata-Version: 2.4
2
+ Name: mfget
3
+ Version: 0.1.1
4
+ Summary: A clean MediaFire file and folder downloader with a Rich-powered CLI.
5
+ License-Expression: MIT
6
+ Project-URL: Homepage, https://github.com/worstgirlinamerica/mediafire-dl
7
+ Project-URL: Repository, https://github.com/worstgirlinamerica/mediafire-dl
8
+ Project-URL: Issues, https://github.com/worstgirlinamerica/mediafire-dl/issues
9
+ Keywords: mediafire,downloader,cli,rich
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Environment :: Console
12
+ Classifier: Intended Audience :: End Users/Desktop
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.9
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Topic :: Internet :: WWW/HTTP
19
+ Classifier: Topic :: Utilities
20
+ Requires-Python: >=3.9
21
+ Description-Content-Type: text/markdown
22
+ License-File: LICENSE
23
+ Requires-Dist: rich>=13.7.0
24
+ Dynamic: license-file
25
+
26
+ # Mediafire-DL
27
+
28
+ Mediafire-DL is a small command-line downloader for MediaFire links.
29
+
30
+ It handles single files and folders, keeps nested folder structure intact, and shows a clean progress display while it downloads. Public links work without any login details. Links that require an account can be tried with an optional local cookies file.
31
+
32
+ ## What It Does
33
+
34
+ - Downloads public MediaFire file links
35
+ - Downloads public MediaFire folder links
36
+ - Walks nested folders automatically
37
+ - Saves folders using the same folder layout MediaFire reports
38
+ - Shows a file preview before downloading
39
+ - Supports a dry-run mode so you can check what would be saved first
40
+ - Defaults to your system `Downloads` folder
41
+ - Can read a local `cookies.txt` file for links your own browser account can access
42
+
43
+ ## Install
44
+
45
+ You need Python 3.9 or newer.
46
+
47
+ ### From GitHub
48
+
49
+ This works without cloning the repo first:
50
+
51
+ ```bash
52
+ python3 -m pip install --user git+https://github.com/worstgirlinamerica/mediafire-dl.git
53
+ ```
54
+
55
+ Then run:
56
+
57
+ ```bash
58
+ mediafire-dl
59
+ ```
60
+
61
+ On Windows, use `py` instead of `python3`:
62
+
63
+ ```powershell
64
+ py -m pip install --user git+https://github.com/worstgirlinamerica/mediafire-dl.git
65
+ ```
66
+
67
+ ### From PyPI
68
+
69
+ Once Mediafire-DL is published to PyPI as `mfget`, it can be installed like this:
70
+
71
+ ```bash
72
+ python3 -m pip install --user mfget
73
+ ```
74
+
75
+ On Windows:
76
+
77
+ ```powershell
78
+ py -m pip install --user mfget
79
+ ```
80
+
81
+ ### macOS
82
+
83
+ If you installed with Python 3:
84
+
85
+ ```bash
86
+ mediafire-dl
87
+ ```
88
+
89
+ If your terminal says `mediafire-dl` was not found, use the module form:
90
+
91
+ ```bash
92
+ python3 -m mediafire_dl
93
+ ```
94
+
95
+ If the command is installed but your shell cannot find it, add Python's user script folder to your PATH. The version number may be different on your machine:
96
+
97
+ ```bash
98
+ echo 'export PATH="$HOME/Library/Python/3.12/bin:$PATH"' >> ~/.zshrc
99
+ source ~/.zshrc
100
+ ```
101
+
102
+ ### Windows
103
+
104
+ Run:
105
+
106
+ ```powershell
107
+ mediafire-dl
108
+ ```
109
+
110
+ If PowerShell says `mediafire-dl` was not found, use:
111
+
112
+ ```powershell
113
+ py -m mediafire_dl
114
+ ```
115
+
116
+ If you want the `mediafire-dl` command to work directly, add Python's user Scripts folder to PATH. It usually looks like this, with the Python version adjusted for your install:
117
+
118
+ ```text
119
+ %APPDATA%\Python\Python312\Scripts
120
+ ```
121
+
122
+ ### Linux
123
+
124
+ Run:
125
+
126
+ ```bash
127
+ mediafire-dl
128
+ ```
129
+
130
+ If your shell says `mediafire-dl` was not found, use:
131
+
132
+ ```bash
133
+ python3 -m mediafire_dl
134
+ ```
135
+
136
+ Or add Python's user script folder to your PATH:
137
+
138
+ ```bash
139
+ echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
140
+ source ~/.bashrc
141
+ ```
142
+
143
+ ### Local Development
144
+
145
+ If you cloned the repo and want to install from the project folder:
146
+
147
+ ```bash
148
+ python3 -m pip install --user .
149
+ ```
150
+
151
+ ## Usage
152
+
153
+ Run the command and paste a MediaFire link when it asks:
154
+
155
+ ```bash
156
+ mediafire-dl
157
+ ```
158
+
159
+ Or pass the link directly:
160
+
161
+ ```bash
162
+ mediafire-dl "https://www.mediafire.com/file/example/file.zip/file"
163
+ ```
164
+
165
+ Choose a save folder:
166
+
167
+ ```bash
168
+ mediafire-dl "https://www.mediafire.com/folder/example/My+Folder" --output ~/Downloads/MediaFire
169
+ ```
170
+
171
+ Preview a folder without downloading anything:
172
+
173
+ ```bash
174
+ mediafire-dl --dry-run "https://www.mediafire.com/folder/example/My+Folder"
175
+ ```
176
+
177
+ Show more technical error details:
178
+
179
+ ```bash
180
+ mediafire-dl --verbose "https://www.mediafire.com/file/example/file.zip/file"
181
+ ```
182
+
183
+ Use a local cookies file for a link that your browser account can already access:
184
+
185
+ ```bash
186
+ mediafire-dl --cookies ~/Downloads/cookies.txt "https://www.mediafire.com/file/example/file.zip/file"
187
+ ```
188
+
189
+ The cookies file must be in Netscape/Mozilla `cookies.txt` format. Mediafire-DL only reads the file from your computer for that run.
190
+
191
+ ## Supported Links
192
+
193
+ Supported:
194
+
195
+ - Public MediaFire file links
196
+ - Public MediaFire folder links
197
+ - Public folders with nested subfolders
198
+ - MediaFire file or folder links that work with a user-provided `cookies.txt` file
199
+
200
+ Not supported:
201
+
202
+ - Asking for or storing MediaFire usernames and passwords
203
+ - Automatically reading cookies from your browser
204
+ - Password-protected downloads that require an extra password prompt
205
+ - Captcha-gated or blocked downloads
206
+
207
+ ## Privacy And Safety
208
+
209
+ Mediafire-DL does not ask for MediaFire login details and does not read browser cookies automatically. If you use `--cookies`, the cookie file stays on your machine and is only read by the current command.
210
+
211
+ This repo already ignores common private and generated files in `.gitignore`, including `.env`, cookies, logs, caches, virtual environments, `.DS_Store`, partial downloads, and local media/download folders.
212
+
213
+ ## Development
214
+
215
+ For an editable install while working on the code:
216
+
217
+ ```bash
218
+ python3 -m pip install --user -e .
219
+ ```
220
+
221
+ Run the CLI from source:
222
+
223
+ ```bash
224
+ python3 -m mediafire_dl
225
+ ```
226
+
227
+ The package entry point is:
228
+
229
+ ```bash
230
+ mediafire-dl
231
+ ```
232
+
233
+ ## License
234
+
235
+ MIT License. See [LICENSE](LICENSE).
mfget-0.1.1/README.md ADDED
@@ -0,0 +1,210 @@
1
+ # Mediafire-DL
2
+
3
+ Mediafire-DL is a small command-line downloader for MediaFire links.
4
+
5
+ It handles single files and folders, keeps nested folder structure intact, and shows a clean progress display while it downloads. Public links work without any login details. Links that require an account can be tried with an optional local cookies file.
6
+
7
+ ## What It Does
8
+
9
+ - Downloads public MediaFire file links
10
+ - Downloads public MediaFire folder links
11
+ - Walks nested folders automatically
12
+ - Saves folders using the same folder layout MediaFire reports
13
+ - Shows a file preview before downloading
14
+ - Supports a dry-run mode so you can check what would be saved first
15
+ - Defaults to your system `Downloads` folder
16
+ - Can read a local `cookies.txt` file for links your own browser account can access
17
+
18
+ ## Install
19
+
20
+ You need Python 3.9 or newer.
21
+
22
+ ### From GitHub
23
+
24
+ This works without cloning the repo first:
25
+
26
+ ```bash
27
+ python3 -m pip install --user git+https://github.com/worstgirlinamerica/mediafire-dl.git
28
+ ```
29
+
30
+ Then run:
31
+
32
+ ```bash
33
+ mediafire-dl
34
+ ```
35
+
36
+ On Windows, use `py` instead of `python3`:
37
+
38
+ ```powershell
39
+ py -m pip install --user git+https://github.com/worstgirlinamerica/mediafire-dl.git
40
+ ```
41
+
42
+ ### From PyPI
43
+
44
+ Once Mediafire-DL is published to PyPI as `mfget`, it can be installed like this:
45
+
46
+ ```bash
47
+ python3 -m pip install --user mfget
48
+ ```
49
+
50
+ On Windows:
51
+
52
+ ```powershell
53
+ py -m pip install --user mfget
54
+ ```
55
+
56
+ ### macOS
57
+
58
+ If you installed with Python 3:
59
+
60
+ ```bash
61
+ mediafire-dl
62
+ ```
63
+
64
+ If your terminal says `mediafire-dl` was not found, use the module form:
65
+
66
+ ```bash
67
+ python3 -m mediafire_dl
68
+ ```
69
+
70
+ If the command is installed but your shell cannot find it, add Python's user script folder to your PATH. The version number may be different on your machine:
71
+
72
+ ```bash
73
+ echo 'export PATH="$HOME/Library/Python/3.12/bin:$PATH"' >> ~/.zshrc
74
+ source ~/.zshrc
75
+ ```
76
+
77
+ ### Windows
78
+
79
+ Run:
80
+
81
+ ```powershell
82
+ mediafire-dl
83
+ ```
84
+
85
+ If PowerShell says `mediafire-dl` was not found, use:
86
+
87
+ ```powershell
88
+ py -m mediafire_dl
89
+ ```
90
+
91
+ If you want the `mediafire-dl` command to work directly, add Python's user Scripts folder to PATH. It usually looks like this, with the Python version adjusted for your install:
92
+
93
+ ```text
94
+ %APPDATA%\Python\Python312\Scripts
95
+ ```
96
+
97
+ ### Linux
98
+
99
+ Run:
100
+
101
+ ```bash
102
+ mediafire-dl
103
+ ```
104
+
105
+ If your shell says `mediafire-dl` was not found, use:
106
+
107
+ ```bash
108
+ python3 -m mediafire_dl
109
+ ```
110
+
111
+ Or add Python's user script folder to your PATH:
112
+
113
+ ```bash
114
+ echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
115
+ source ~/.bashrc
116
+ ```
117
+
118
+ ### Local Development
119
+
120
+ If you cloned the repo and want to install from the project folder:
121
+
122
+ ```bash
123
+ python3 -m pip install --user .
124
+ ```
125
+
126
+ ## Usage
127
+
128
+ Run the command and paste a MediaFire link when it asks:
129
+
130
+ ```bash
131
+ mediafire-dl
132
+ ```
133
+
134
+ Or pass the link directly:
135
+
136
+ ```bash
137
+ mediafire-dl "https://www.mediafire.com/file/example/file.zip/file"
138
+ ```
139
+
140
+ Choose a save folder:
141
+
142
+ ```bash
143
+ mediafire-dl "https://www.mediafire.com/folder/example/My+Folder" --output ~/Downloads/MediaFire
144
+ ```
145
+
146
+ Preview a folder without downloading anything:
147
+
148
+ ```bash
149
+ mediafire-dl --dry-run "https://www.mediafire.com/folder/example/My+Folder"
150
+ ```
151
+
152
+ Show more technical error details:
153
+
154
+ ```bash
155
+ mediafire-dl --verbose "https://www.mediafire.com/file/example/file.zip/file"
156
+ ```
157
+
158
+ Use a local cookies file for a link that your browser account can already access:
159
+
160
+ ```bash
161
+ mediafire-dl --cookies ~/Downloads/cookies.txt "https://www.mediafire.com/file/example/file.zip/file"
162
+ ```
163
+
164
+ The cookies file must be in Netscape/Mozilla `cookies.txt` format. Mediafire-DL only reads the file from your computer for that run.
165
+
166
+ ## Supported Links
167
+
168
+ Supported:
169
+
170
+ - Public MediaFire file links
171
+ - Public MediaFire folder links
172
+ - Public folders with nested subfolders
173
+ - MediaFire file or folder links that work with a user-provided `cookies.txt` file
174
+
175
+ Not supported:
176
+
177
+ - Asking for or storing MediaFire usernames and passwords
178
+ - Automatically reading cookies from your browser
179
+ - Password-protected downloads that require an extra password prompt
180
+ - Captcha-gated or blocked downloads
181
+
182
+ ## Privacy And Safety
183
+
184
+ Mediafire-DL does not ask for MediaFire login details and does not read browser cookies automatically. If you use `--cookies`, the cookie file stays on your machine and is only read by the current command.
185
+
186
+ This repo already ignores common private and generated files in `.gitignore`, including `.env`, cookies, logs, caches, virtual environments, `.DS_Store`, partial downloads, and local media/download folders.
187
+
188
+ ## Development
189
+
190
+ For an editable install while working on the code:
191
+
192
+ ```bash
193
+ python3 -m pip install --user -e .
194
+ ```
195
+
196
+ Run the CLI from source:
197
+
198
+ ```bash
199
+ python3 -m mediafire_dl
200
+ ```
201
+
202
+ The package entry point is:
203
+
204
+ ```bash
205
+ mediafire-dl
206
+ ```
207
+
208
+ ## License
209
+
210
+ MIT License. See [LICENSE](LICENSE).
@@ -0,0 +1,3 @@
1
+ """Mediafire-DL package."""
2
+
3
+ __version__ = "0.1.0"
@@ -0,0 +1,9 @@
1
+ from __future__ import annotations
2
+
3
+ import sys
4
+
5
+ from .cli import main
6
+
7
+
8
+ if __name__ == "__main__":
9
+ sys.exit(main())
@@ -0,0 +1,112 @@
1
+ from __future__ import annotations
2
+
3
+ import argparse
4
+ import logging
5
+ import sys
6
+ from pathlib import Path
7
+
8
+ from rich.console import Console
9
+
10
+ from .downloader import Downloader
11
+ from .errors import MediafireDLError
12
+ from .http import HttpClient
13
+ from .mediafire import MediafireClient
14
+ from .output import RichUI
15
+
16
+
17
+ def main(argv: list[str] | None = None) -> int:
18
+ args = parse_args(argv)
19
+ configure_logging(args.verbose)
20
+
21
+ ui = RichUI(Console())
22
+ link = args.link or ui.ask_link()
23
+ if not link.strip():
24
+ ui.error("Please paste a MediaFire file or folder link.")
25
+ return 1
26
+ destination = Path(args.output or ui.ask_save_dir(str(default_downloads_dir()))).expanduser()
27
+
28
+ try:
29
+ cookie_file = Path(args.cookies).expanduser() if args.cookies else None
30
+ http = HttpClient(cookie_file=cookie_file)
31
+ client = MediafireClient(http)
32
+ downloader = Downloader(http)
33
+
34
+ ui.status("Finding files...")
35
+ plan = client.build_plan(link)
36
+ if not plan.files:
37
+ ui.warning("No downloadable files were found.")
38
+ return 1
39
+
40
+ ui.show_plan(plan)
41
+ ui.status("Preparing downloads...")
42
+
43
+ if args.dry_run:
44
+ ui.warning("Dry run: nothing was downloaded.")
45
+ return 0
46
+
47
+ ui.status("Downloading...")
48
+ saved_to = downloader.download_plan(plan, destination, ui)
49
+ ui.finished(str(saved_to))
50
+ return 0
51
+ except KeyboardInterrupt:
52
+ ui.error("Download cancelled.")
53
+ return 130
54
+ except MediafireDLError as exc:
55
+ if args.verbose:
56
+ logging.getLogger(__name__).exception("Mediafire-DL failed")
57
+ ui.error(str(exc))
58
+ return 1
59
+ except Exception as exc:
60
+ if args.verbose:
61
+ logging.getLogger(__name__).exception("Unexpected failure")
62
+ ui.error(str(exc))
63
+ else:
64
+ ui.error("Something went wrong. Run again with --verbose for details.")
65
+ return 1
66
+
67
+
68
+ def parse_args(argv: list[str] | None = None) -> argparse.Namespace:
69
+ parser = argparse.ArgumentParser(
70
+ prog="mediafire-dl",
71
+ description="Download MediaFire files and folders with a clean progress UI.",
72
+ )
73
+ parser.add_argument("link", nargs="?", help="MediaFire file or folder link")
74
+ parser.add_argument(
75
+ "-o",
76
+ "--output",
77
+ help="Folder to save downloads into. Defaults to your Downloads folder.",
78
+ )
79
+ parser.add_argument(
80
+ "--dry-run",
81
+ action="store_true",
82
+ help="List files without downloading them.",
83
+ )
84
+ parser.add_argument(
85
+ "--cookies",
86
+ help=(
87
+ "Path to a Netscape/Mozilla cookies.txt file to use for links your browser can access. "
88
+ "Cookies are read locally and are not saved by Mediafire-DL."
89
+ ),
90
+ )
91
+ parser.add_argument(
92
+ "--verbose",
93
+ action="store_true",
94
+ help="Show technical logs and tracebacks for troubleshooting.",
95
+ )
96
+ return parser.parse_args(argv)
97
+
98
+
99
+ def configure_logging(verbose: bool) -> None:
100
+ logging.basicConfig(
101
+ level=logging.DEBUG if verbose else logging.CRITICAL,
102
+ format="%(levelname)s: %(name)s: %(message)s",
103
+ )
104
+
105
+
106
+ def default_downloads_dir() -> Path:
107
+ downloads = Path.home() / "Downloads"
108
+ return downloads if downloads.exists() else Path.home()
109
+
110
+
111
+ if __name__ == "__main__":
112
+ sys.exit(main())
@@ -0,0 +1,61 @@
1
+ from __future__ import annotations
2
+
3
+ import logging
4
+ from pathlib import Path
5
+
6
+ from .errors import DownloadLinkError, MediafireDLError
7
+ from .http import HttpClient
8
+ from .mediafire import safe_name
9
+ from .models import DownloadPlan, MediafireItem
10
+ from .output import UserInterface
11
+
12
+ LOGGER = logging.getLogger(__name__)
13
+
14
+
15
+ class Downloader:
16
+ def __init__(self, http: HttpClient | None = None, chunk_size: int = 1024 * 128) -> None:
17
+ self.http = http or HttpClient()
18
+ self.chunk_size = chunk_size
19
+
20
+ def download_plan(self, plan: DownloadPlan, destination: Path, ui: UserInterface) -> Path:
21
+ root = destination / safe_name(plan.display_name) if plan.is_folder else destination
22
+ root.mkdir(parents=True, exist_ok=True)
23
+
24
+ total = len(plan.files)
25
+ for index, item in enumerate(plan.files, start=1):
26
+ self._download_item(item, root, ui, index, total)
27
+ return root
28
+
29
+ def _download_item(
30
+ self,
31
+ item: MediafireItem,
32
+ root: Path,
33
+ ui: UserInterface,
34
+ index: int,
35
+ total: int,
36
+ ) -> None:
37
+ target = root / Path(*item.relative_folder.parts) / safe_name(item.name)
38
+ target.parent.mkdir(parents=True, exist_ok=True)
39
+ partial = target.with_name(f"{target.name}.part")
40
+
41
+ try:
42
+ direct_url = self.http.find_public_download_url(item.page_url)
43
+ except MediafireDLError:
44
+ raise
45
+ except Exception as exc:
46
+ LOGGER.debug("Unexpected error while finding download URL", exc_info=exc)
47
+ raise DownloadLinkError(f"Could not prepare {item.name} for download.") from exc
48
+
49
+ with self.http.open_download(direct_url) as response:
50
+ length = response.headers.get("Content-Length")
51
+ total_size = int(length) if length and length.isdigit() else item.size
52
+ progress = ui.start_file(index, total, item, total_size)
53
+ with partial.open("wb") as file:
54
+ while True:
55
+ chunk = response.read(self.chunk_size)
56
+ if not chunk:
57
+ break
58
+ file.write(chunk)
59
+ progress.update(len(chunk))
60
+ progress.finish()
61
+ partial.replace(target)
@@ -0,0 +1,18 @@
1
+ class MediafireDLError(Exception):
2
+ """Base exception for user-facing downloader errors."""
3
+
4
+
5
+ class UnsupportedLinkError(MediafireDLError):
6
+ """Raised when a link is not a supported MediaFire file or folder URL."""
7
+
8
+
9
+ class MediafireAPIError(MediafireDLError):
10
+ """Raised when MediaFire's public API returns an error."""
11
+
12
+
13
+ class DownloadLinkError(MediafireDLError):
14
+ """Raised when a public download URL cannot be extracted."""
15
+
16
+
17
+ class CookieFileError(MediafireDLError):
18
+ """Raised when a user-provided cookie file cannot be loaded."""