Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e0d3af2a4f |
@@ -1,12 +1,13 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
|
import glob
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import ClassVar
|
|
||||||
|
|
||||||
from pydantic_settings import CliImplicitFlag, CliPositionalArg
|
from pydantic_settings import CliImplicitFlag, CliPositionalArg
|
||||||
import structlog
|
import structlog
|
||||||
import yt_dlp
|
import yt_dlp
|
||||||
|
import yt_dlp.cookies
|
||||||
from mutagen.easyid3 import EasyID3
|
from mutagen.easyid3 import EasyID3
|
||||||
from pydantic import Field, computed_field
|
from pydantic import Field, computed_field
|
||||||
from shazamio import Shazam
|
from shazamio import Shazam
|
||||||
@@ -73,22 +74,24 @@ def current_quarter() -> Path:
|
|||||||
return Path().home() / "Music" / f"{date.quarter}_{date.year}"
|
return Path().home() / "Music" / f"{date.quarter}_{date.year}"
|
||||||
|
|
||||||
|
|
||||||
|
def _cookiesfrombrowser() -> tuple | None:
|
||||||
|
"""First available cookies source: firefox dev edition, firefox, then chrome."""
|
||||||
|
for root in yt_dlp.cookies._firefox_browser_dirs():
|
||||||
|
# dev edition lives in a randomly-prefixed dir, so pass an absolute path
|
||||||
|
matches = glob.glob(os.path.join(root, "*.dev-edition-default"))
|
||||||
|
if matches:
|
||||||
|
return ("firefox", matches[0], None, None)
|
||||||
|
if any(yt_dlp.cookies._firefox_cookie_dbs(yt_dlp.cookies._firefox_browser_dirs())):
|
||||||
|
return ("firefox", None, None, None)
|
||||||
|
return ("chrome", None, None, None)
|
||||||
|
|
||||||
|
|
||||||
class YtDownload(Command):
|
class YtDownload(Command):
|
||||||
"""
|
"""
|
||||||
download a youtube song from {URL} to current quarter dir.
|
download a youtube song from {URL} to current quarter dir.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
url: CliPositionalArg[str] = Field(description="youtube url to download")
|
url: CliPositionalArg[str] = Field(description="youtube url to download")
|
||||||
ydl_opts: ClassVar = {
|
|
||||||
"format": "mp3/bestaudio/best",
|
|
||||||
"postprocessors": [
|
|
||||||
{
|
|
||||||
"key": "FFmpegExtractAudio",
|
|
||||||
"preferredcodec": "mp3",
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"remote_components": ["ejs:github"],
|
|
||||||
}
|
|
||||||
parents: CliImplicitFlag[bool] = Field(
|
parents: CliImplicitFlag[bool] = Field(
|
||||||
default=True, description="create the parent dirs if not exists"
|
default=True, description="create the parent dirs if not exists"
|
||||||
)
|
)
|
||||||
@@ -99,6 +102,24 @@ class YtDownload(Command):
|
|||||||
date = DateParse()
|
date = DateParse()
|
||||||
return Path().home() / "Music" / f"{date.quarter}_{date.year}"
|
return Path().home() / "Music" / f"{date.quarter}_{date.year}"
|
||||||
|
|
||||||
|
@computed_field()
|
||||||
|
@property
|
||||||
|
def ydl_opts(self) -> dict:
|
||||||
|
opts = {
|
||||||
|
"format": "mp3/bestaudio/best",
|
||||||
|
"postprocessors": [
|
||||||
|
{
|
||||||
|
"key": "FFmpegExtractAudio",
|
||||||
|
"preferredcodec": "mp3",
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"remote_components": ["ejs:github"],
|
||||||
|
}
|
||||||
|
cookies = _cookiesfrombrowser()
|
||||||
|
if cookies is not None:
|
||||||
|
opts["cookiesfrombrowser"] = cookies
|
||||||
|
return opts
|
||||||
|
|
||||||
def run(self) -> None:
|
def run(self) -> None:
|
||||||
os.chdir(Path.home() / "Downloads")
|
os.chdir(Path.home() / "Downloads")
|
||||||
with yt_dlp.YoutubeDL(self.ydl_opts) as ydl:
|
with yt_dlp.YoutubeDL(self.ydl_opts) as ydl:
|
||||||
|
|||||||
Reference in New Issue
Block a user