Everythings working
This commit is contained in:
@@ -13,3 +13,5 @@ build/
|
|||||||
*.swp
|
*.swp
|
||||||
*~
|
*~
|
||||||
tmp
|
tmp
|
||||||
|
Music
|
||||||
|
cookies.txt
|
||||||
|
|||||||
+69
-3
@@ -1,6 +1,7 @@
|
|||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
import pathlib
|
import pathlib
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
import shutil
|
import shutil
|
||||||
import urllib.request
|
import urllib.request
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
@@ -16,6 +17,8 @@ from mutagen.mp3 import MP3
|
|||||||
from mutagen.id3 import ID3, APIC
|
from mutagen.id3 import ID3, APIC
|
||||||
from flask import Flask, render_template, request, jsonify
|
from flask import Flask, render_template, request, jsonify
|
||||||
|
|
||||||
|
MUSIC_FOLDER = "Music"
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class ReleaseInfo:
|
class ReleaseInfo:
|
||||||
@@ -39,10 +42,11 @@ class RipError(Exception):
|
|||||||
|
|
||||||
|
|
||||||
class MetadataPostProcessor(PostProcessor):
|
class MetadataPostProcessor(PostProcessor):
|
||||||
def __init__(self, info: ReleaseInfo, art_path: str):
|
def __init__(self, info: ReleaseInfo, art_path: str, on_finish: Callable):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.info = info
|
self.info = info
|
||||||
self.art_path = art_path
|
self.art_path = art_path
|
||||||
|
self.on_finish = on_finish
|
||||||
|
|
||||||
def run(self, information):
|
def run(self, information):
|
||||||
file = pathlib.Path(information["filepath"])
|
file = pathlib.Path(information["filepath"])
|
||||||
@@ -77,6 +81,7 @@ class MetadataPostProcessor(PostProcessor):
|
|||||||
)
|
)
|
||||||
id3audio.save()
|
id3audio.save()
|
||||||
|
|
||||||
|
self.on_finish()
|
||||||
return [], information
|
return [], information
|
||||||
|
|
||||||
|
|
||||||
@@ -101,6 +106,7 @@ def download_content(path: str, url: str, post_processor: PostProcessor) -> None
|
|||||||
{
|
{
|
||||||
"format": "bestaudio/best",
|
"format": "bestaudio/best",
|
||||||
"ignoreerrors": True,
|
"ignoreerrors": True,
|
||||||
|
"restrictfilenames": True,
|
||||||
"postprocessors": [
|
"postprocessors": [
|
||||||
{
|
{
|
||||||
"key": "FFmpegExtractAudio",
|
"key": "FFmpegExtractAudio",
|
||||||
@@ -172,6 +178,50 @@ def find_tmp_path() -> str:
|
|||||||
return f"{project_root_path}/tmp"
|
return f"{project_root_path}/tmp"
|
||||||
|
|
||||||
|
|
||||||
|
def sort_into_music(path: str, info: ReleaseInfo) -> None:
|
||||||
|
try:
|
||||||
|
for file_name in os.listdir(path):
|
||||||
|
if file_name == "cover.jpg":
|
||||||
|
continue
|
||||||
|
|
||||||
|
audio = EasyID3(os.path.join(path, file_name))
|
||||||
|
artist_list = audio.get("artist")
|
||||||
|
if artist_list is None:
|
||||||
|
raise RipError("Artist tag was None")
|
||||||
|
|
||||||
|
artist = artist_list[0]
|
||||||
|
re.sub(r"[^\w_. -]", "_", artist)
|
||||||
|
title = info.title
|
||||||
|
re.sub(r"[^\w_. -]", "_", title)
|
||||||
|
|
||||||
|
artist_path = os.path.join(MUSIC_FOLDER, artist)
|
||||||
|
release_path = os.path.join(MUSIC_FOLDER, artist, title)
|
||||||
|
|
||||||
|
if not os.path.exists(artist_path):
|
||||||
|
os.makedirs(artist_path)
|
||||||
|
|
||||||
|
if not os.path.exists(release_path):
|
||||||
|
os.mkdir(release_path)
|
||||||
|
|
||||||
|
dst_file_path = os.path.join(release_path, file_name)
|
||||||
|
dst_file_path_cover = os.path.join(release_path, "cover.jpg")
|
||||||
|
|
||||||
|
if os.path.exists(dst_file_path):
|
||||||
|
os.remove(dst_file_path)
|
||||||
|
|
||||||
|
if os.path.exists(dst_file_path_cover):
|
||||||
|
os.remove(dst_file_path_cover)
|
||||||
|
|
||||||
|
source_file_path = os.path.join(path, file_name)
|
||||||
|
shutil.move(source_file_path, release_path)
|
||||||
|
|
||||||
|
source_file_path_cover = os.path.join(path, "cover.jpg")
|
||||||
|
shutil.copy(source_file_path_cover, release_path)
|
||||||
|
|
||||||
|
except Exception:
|
||||||
|
raise RipError("Filesystem error")
|
||||||
|
|
||||||
|
|
||||||
def rip_worker(rip_queue: list[str], status_callback: Callable[[ReleaseInfo | str, bool],]):
|
def rip_worker(rip_queue: list[str], status_callback: Callable[[ReleaseInfo | str, bool],]):
|
||||||
tmp_path = find_tmp_path()
|
tmp_path = find_tmp_path()
|
||||||
|
|
||||||
@@ -195,12 +245,28 @@ def rip_worker(rip_queue: list[str], status_callback: Callable[[ReleaseInfo | st
|
|||||||
if not os.path.exists(art_path):
|
if not os.path.exists(art_path):
|
||||||
raise RipError("Art download failed")
|
raise RipError("Art download failed")
|
||||||
|
|
||||||
status_callback("Downloading content", False)
|
status_callback("Downloading content (0)", False)
|
||||||
download_content(tmp_path, url, MetadataPostProcessor(info, art_path))
|
|
||||||
|
on_index = 0
|
||||||
|
|
||||||
|
def on_download_finish() -> None:
|
||||||
|
nonlocal on_index
|
||||||
|
on_index += 1
|
||||||
|
status_callback(f"Downloading content ({on_index})", False)
|
||||||
|
|
||||||
|
download_content(tmp_path, url, MetadataPostProcessor(info, art_path, on_download_finish))
|
||||||
|
if len(os.listdir(tmp_path)) == 0:
|
||||||
|
raise RipError("No content was downloaded")
|
||||||
|
|
||||||
|
status_callback("Sorting content", False)
|
||||||
|
sort_into_music(tmp_path, info)
|
||||||
|
|
||||||
except RipError as e:
|
except RipError as e:
|
||||||
status_callback(e.msg, True)
|
status_callback(e.msg, True)
|
||||||
|
|
||||||
|
except Exception:
|
||||||
|
status_callback("Unknown Error", True)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
status_callback("Finished sucessfully", True)
|
status_callback("Finished sucessfully", True)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user