Skip to content
This repository was archived by the owner on Jun 3, 2024. It is now read-only.

Commit 1574dd3

Browse files
Merge pull request #5 from techboy-coder/add_punctuation_from_thomasaarholt_fork
Cleaned cli bit and allow more file extentions
2 parents 40bda50 + 1a9a3ab commit 1574dd3

File tree

9 files changed

+77
-168
lines changed

9 files changed

+77
-168
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66

77
## What is mmdl ❓
88

9-
MMDL is a cli app which allows you to quickly and efficiently download one or multiple songs from YouTube.
9+
**TLDR**: MMDL is a cli app which allows you to quickly and efficiently download one or multiple songs from YouTube.
10+
11+
I wanted a tool to quickly and efficiently download songs/audios from YouTube based on the name of the song. I also wanted the songs to be tagged with metadata. This is why I created this simple to use tool.
1012

1113
### Why
1214

images/mmdl_go.png

90.5 KB
Loading

images/mmdl_help.png

84.3 KB
Loading

mmdl.egg-info/PKG-INFO

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ License-File: LICENSE
2424

2525
## What is mmdl ❓
2626

27-
MMDL is a cli app which allows you to quickly and efficiently download one or multiple songs from YouTube.
27+
**TLDR**: MMDL is a cli app which allows you to quickly and efficiently download one or multiple songs from YouTube.
28+
29+
I wanted a tool to quickly and efficiently download songs/audios from YouTube based on the name of the song. I also wanted the songs to be tagged with metadata. This is why I created this simple to use tool.
2830

2931
### Why
3032

mmdl.egg-info/SOURCES.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ mmdl/__init__.py
66
mmdl/ask.py
77
mmdl/cli.py
88
mmdl/globals.py
9-
mmdl/mdl.py
109
mmdl/utils.py
1110
mmdl/yt_utils.py
1211
mmdl.egg-info/PKG-INFO

mmdl/cli.py

Lines changed: 33 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
from mmdl import MusicDownloader
1818
from .ask import asker
1919
from rich.console import Console
20+
from .utils import *
2021
import questionary
2122
console = Console()
2223
from click_help_colors import HelpColorsGroup, HelpColorsCommand
@@ -50,23 +51,15 @@ def go(verbose, debug):
5051
# Go Command
5152
> Easy way to download songs. Uses inputs/inquirer. (Simply run 'mmdl go')
5253
"""
54+
print_logo()
5355

5456
if debug:
5557
console.log("Verbose: ", verbose)
5658
console.log("Debug: ", debug)
5759

58-
console.print("""\b[red]
59-
_ _
60-
| | |
61-
_ __ ___ _ __ ___ __| | |
62-
| '_ ` _ \| '_ ` _ \ / _` | |
63-
| | | | | | | | | | | (_| | | [/]by techboy-coder[red]
64-
|_| |_| |_|_| |_| |_|\__,_|_| [/]find me on https://github.com/techboy-coder
65-
66-
[green]mmdl [Mega Music Downloader] - A tool to easily download music.[/green]
67-
""")
60+
6861
song_names=asker()
69-
console.print("\n[cyan]> [/] Total number of songs: %s. \n" % (len(song_names)))
62+
num_of_songs_printer(len(song_names))
7063
# List, verbose, debug
7164
MusicDownloader(song_names, verbose, debug).download_songs()
7265

@@ -114,19 +107,11 @@ def file(file, seperator, verbose, debug):
114107
console.log("Verbose: ", verbose)
115108
console.log("Debug: ", debug)
116109

117-
console.print("""\b[red]
118-
_ _
119-
| | |
120-
_ __ ___ _ __ ___ __| | |
121-
| '_ ` _ \| '_ ` _ \ / _` | |
122-
| | | | | | | | | | | (_| | | [/]by techboy-coder[red]
123-
|_| |_| |_|_| |_| |_|\__,_|_| [/]find me on https://github.com/techboy-coder
124-
125-
[green]mmdl [Mega Music Downloader] - A tool to easily download music.[/green]
126-
""")
127-
console.print("\n[cyan]> [/] Total number of songs: %s. \n" % (len(songs)))
128-
if not questionary.confirm("Do you want to continue").ask():
129-
quit()
110+
print_logo()
111+
112+
num_of_songs_printer(len(songs))
113+
114+
wanna_continue()
130115
# file, verbose, debug
131116
MusicDownloader(songs, verbose, debug).download_songs()
132117
return
@@ -174,17 +159,8 @@ def list(songs, verbose, debug, ask):
174159
console.log("Verbose: ", verbose)
175160
console.log("Debug: ", debug)
176161

177-
console.print("""\b[red]
178-
_ _
179-
| | |
180-
_ __ ___ _ __ ___ __| | |
181-
| '_ ` _ \| '_ ` _ \ / _` | |
182-
| | | | | | | | | | | (_| | | [/]by techboy-coder[red]
183-
|_| |_| |_|_| |_| |_|\__,_|_| [/]find me on https://github.com/techboy-coder
184-
185-
[green]mmdl [Mega Music Downloader] - A tool to easily download music.[/green]
186-
""")
187-
console.print("\n[cyan]> [/] Total number of songs: %s. \n" % (len(songs_list)))
162+
print_logo()
163+
num_of_songs_printer(len(songs_list))
188164
# file, verbose, debug
189165
MusicDownloader(songs_list, verbose, debug).download_songs()
190166
return
@@ -209,66 +185,48 @@ def ytmusic(file, verbose, debug, ask):
209185
"""
210186
if not ask and not file:
211187
ask = True
212-
if ask:
213-
console.print("[cyan][>][/] We'll be manually asking you for the file location.")
214-
console.print("""
188+
189+
guide = """
215190
[bold red]YT-Music[/bold red].
216191
- Go to your YTMusic liked songs playlist (https://music.youtube.com/playlist?list=LM)
217192
- Make sure you are logged in
218193
- Press Ctrl/Cmd + Shift + i and open the dev tools
219194
- Keep scrolling down until you reach the end of your playlist (Songs will stop loading)
220195
- Copy the all the html markup
221196
- Create a text file and paste the html into it.
222-
""")
223-
if not questionary.confirm("Only continue if you have done the task.").ask():
224-
quit()
197+
"""
198+
199+
if ask:
200+
console.print("[cyan][>][/] We'll be manually asking you for the file location.")
201+
console.print(guide)
202+
wanna_continue("Only continue if you have done the task.")
203+
225204
file = questionary.path("Where is that file located?").ask()
226205
with open(file, "r", encoding="utf-8") as f:
227206
data = f.read()
228-
h = fromstring(data)
229-
sel = CSSSelector("yt-formatted-string.title.style-scope.ytmusic-responsive-list-item-renderer.complex-string > a.yt-simple-endpoint.style-scope.yt-formatted-string")
230-
songs_list=[e.text for e in sel(h)]
231-
if not songs_list[0]:
232-
console.log("[red][-] Hmm. No songs could be parsed from html. Did you select the correct HTML? If you see a error please make a bug report. Thanks!")
233-
quit()
207+
234208
if not ask:
235209
if not file:
236210
console.log("[red][-] You need to enter the file location or add the -a flag.")
237211
quit()
238212
data = file.read()
239-
h = fromstring(data)
240-
sel = CSSSelector("yt-formatted-string.title.style-scope.ytmusic-responsive-list-item-renderer.complex-string > a.yt-simple-endpoint.style-scope.yt-formatted-string")
241-
songs_list=[e.text for e in sel(h)]
242-
if not songs_list[0]:
243-
console.log("[red][-] Hmm. No songs could be parsed from html. Did you select the correct HTML? If you see a error please make a bug report. Thanks!")
244-
console.print("""
245-
[bold red]YT-Music[/bold red].
246-
- Go to your YTMusic liked songs playlist (https://music.youtube.com/playlist?list=LM)
247-
- Make sure you are logged in
248-
- Press Ctrl/Cmd + Shift + i and open the dev tools
249-
- Keep scrolling down until you reach the end of your playlist (Songs will stop loading)
250-
- Copy the all the html markup
251-
- Create a text file and paste the html into it.
252-
""")
213+
214+
215+
h = fromstring(data)
216+
sel = CSSSelector("yt-formatted-string.title.style-scope.ytmusic-responsive-list-item-renderer.complex-string > a.yt-simple-endpoint.style-scope.yt-formatted-string")
217+
songs_list=[e.text for e in sel(h)]
218+
if not songs_list[0]:
219+
console.log("[red][-] Hmm. No songs could be parsed from html. Did you select the correct HTML? If you see a error please make a bug report. Thanks!")
220+
console.print(guide)
253221

254222

255223
if debug:
256224
console.log("Songs: ", str(songs_list))
257225
console.log("Verbose: ", verbose)
258226
console.log("Debug: ", debug)
259-
console.print("""\b[red]
260-
_ _
261-
| | |
262-
_ __ ___ _ __ ___ __| | |
263-
| '_ ` _ \| '_ ` _ \ / _` | |
264-
| | | | | | | | | | | (_| | | [/]by techboy-coder[red]
265-
|_| |_| |_|_| |_| |_|\__,_|_| [/]find me on https://github.com/techboy-coder
266-
267-
[green]mmdl [Mega Music Downloader] - A tool to easily download music.[/green]
268-
""")
269-
console.print("\n[cyan]> [/] Total number of songs: %s. \n" % (len(songs_list)))
270-
if not questionary.confirm("Do you want to continue").ask():
271-
quit()
227+
print_logo()
228+
num_of_songs_printer(len(songs_list))
229+
wanna_continue()
272230
# file, verbose, debug
273231
MusicDownloader(songs_list, verbose, debug).download_songs()
274232
return
@@ -300,16 +258,7 @@ def single(song, verbose, debug):
300258
console.log("Verbose: ", verbose)
301259
console.log("Debug: ", debug)
302260

303-
console.print("""\b[red]
304-
_ _
305-
| | |
306-
_ __ ___ _ __ ___ __| | |
307-
| '_ ` _ \| '_ ` _ \ / _` | |
308-
| | | | | | | | | | | (_| | | [/]by techboy-coder[red]
309-
|_| |_| |_|_| |_| |_|\__,_|_| [/]find me on https://github.com/techboy-coder
310-
311-
[green]mmdl [Mega Music Downloader] - A tool to easily download music.[/green]
312-
""")
261+
print_logo()
313262
songs = [song]
314263
console.print("\n[cyan]> [/] Song: %s. \n" % (song))
315264
# file, verbose, debug

mmdl/mdl.py

Lines changed: 1 addition & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -36,81 +36,6 @@
3636
##Dev Dep
3737
import shutil
3838

39-
class DisplayablePath(object):
40-
display_filename_prefix_middle = '├──'
41-
display_filename_prefix_last = '└──'
42-
display_parent_prefix_middle = ' '
43-
display_parent_prefix_last = '│ '
44-
45-
def __init__(self, path, parent_path, is_last):
46-
self.path = Path(str(path))
47-
self.parent = parent_path
48-
self.is_last = is_last
49-
if self.parent:
50-
self.depth = self.parent.depth + 1
51-
else:
52-
self.depth = 0
53-
54-
@property
55-
def displayname(self):
56-
if self.path.is_dir():
57-
return self.path.name + '/'
58-
return self.path.name
59-
60-
@classmethod
61-
def make_tree(cls, root, parent=None, is_last=False, criteria=None):
62-
root = Path(str(root))
63-
criteria = criteria or cls._default_criteria
64-
65-
displayable_root = cls(root, parent, is_last)
66-
yield displayable_root
67-
68-
children = sorted(list(path
69-
for path in root.iterdir()
70-
if criteria(path)),
71-
key=lambda s: str(s).lower())
72-
count = 1
73-
for path in children:
74-
is_last = count == len(children)
75-
if path.is_dir():
76-
yield from cls.make_tree(path,
77-
parent=displayable_root,
78-
is_last=is_last,
79-
criteria=criteria)
80-
else:
81-
yield cls(path, displayable_root, is_last)
82-
count += 1
83-
84-
@classmethod
85-
def _default_criteria(cls, path):
86-
return True
87-
88-
@property
89-
def displayname(self):
90-
if self.path.is_dir():
91-
return self.path.name + '/'
92-
return self.path.name
93-
94-
def displayable(self):
95-
if self.parent is None:
96-
return self.displayname
97-
98-
_filename_prefix = (self.display_filename_prefix_last
99-
if self.is_last
100-
else self.display_filename_prefix_middle)
101-
102-
parts = ['{!s} {!s}'.format(_filename_prefix,
103-
self.displayname)]
104-
105-
parent = self.parent
106-
while parent and parent.parent is not None:
107-
parts.append(self.display_parent_prefix_middle
108-
if parent.is_last
109-
else self.display_parent_prefix_last)
110-
parent = parent.parent
111-
112-
return ''.join(reversed(parts))
113-
11439
class MusicDownloader():
11540
def __init__(self, song_names: list[str], verbose: int, debug: bool):
11641
"""Music Downloader Class. This is the main class :/
@@ -171,6 +96,7 @@ def download_songs(self): # sourcery no-metrics
17196
]
17297
temp = []
17398
cwd = Utils.get_cwd()
99+
174100
for f in filenames:
175101
# print(f["filename"])
176102
does_exist = executor.submit(Utils.check_file_exists, f["filename"], f)

mmdl/utils.py

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
from pathlib import Path
33
from rich.logging import RichHandler
44
import concurrent.futures
5+
from rich.console import Console
6+
import questionary
7+
console = Console()
58

69
# log=logging
710

@@ -58,4 +61,36 @@ def check_file_exists(filepath: str, rest):
5861
# print("lkj")
5962
# print(path, filepath)
6063
# print(Path(path+"/"+filepath).is_file())
61-
return [Path(filepath).is_file(), rest]
64+
# if any(File.endswith(".mp3") or File.endswith(".mp3") for File in os.listdir(".")):
65+
# return True
66+
# return False
67+
exists=Path(os.path.splitext(filepath)[0]+".mp3").is_file() or Path(os.path.splitext(filepath)[0]+".m4a").is_file() or Path(os.path.splitext(filepath)[0]+".opus").is_file()
68+
return [exists, rest]
69+
70+
71+
def print_logo():
72+
console.print("""\b[red]
73+
_ _
74+
| | |
75+
_ __ ___ _ __ ___ __| | |
76+
| '_ ` _ \| '_ ` _ \ / _` | |
77+
| | | | | | | | | | | (_| | | [/]by techboy-coder[red]
78+
|_| |_| |_|_| |_| |_|\__,_|_| [/]find me on https://github.com/techboy-coder
79+
80+
[green]mmdl [Mega Music Downloader] - A tool to easily download music.[/green]
81+
""")
82+
83+
def num_of_songs_printer(num):
84+
console.print("\n[cyan]> [/] Total number of songs: %s. \n" % (num))
85+
86+
def wanna_continue(msg="Do you want to continue"):
87+
if not questionary.confirm(msg).ask():
88+
quit()
89+
90+
def check_file(filename):
91+
possible_extensions = ('', '.txt', '.dat')
92+
for e in possible_extensions:
93+
if os.path.isfile(filename + e):
94+
return filename + e
95+
else:
96+
return None

mmdl/yt_utils.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ def __init__(self, mmdl: bool):
2323
{
2424
'key': 'FFmpegExtractAudio',
2525
'preferredcodec': 'mp3',
26-
'preferredquality': '192',
26+
# 'preferredquality': '192',
2727
}
2828
],
2929
'outtmpl': str(self.output_dir)+'/%(title)s.%(ext)s',
@@ -40,15 +40,11 @@ def download(self, url: str, do_download: bool, rest: None):
4040
with youtube_dl.YoutubeDL(self.ytdl_opts) as ydl:
4141
info = ydl.extract_info(url, download=True)
4242
filename = ydl.prepare_filename(info)
43-
filename = filename.replace("webm","mp3")
44-
filename = filename.replace("m4a", "mp3")
4543
return {"filename": filename, "url": url, "rest":rest}
4644
else:
4745
with youtube_dl.YoutubeDL(self.ytdl_opts) as ydl:
4846
info = ydl.extract_info(url, download=False)
4947
filename = ydl.prepare_filename(info)
50-
filename = filename.replace("webm","mp3")
51-
filename = filename.replace("m4a", "mp3")
5248
return {"filename": filename, "url": url, "rest":rest}
5349

5450
def logger(self):

0 commit comments

Comments
 (0)