[MVP] Working as expected

refactor_total
Brett Spaulding 3 years ago
parent fd62c0977d
commit a6d5f6d309

5
.gitignore vendored

@ -1,3 +1,4 @@
./navidrome/
./music/ navidrome/
music/
.idea/ .idea/

@ -1,6 +1,9 @@
import json
from apscheduler.schedulers.background import BackgroundScheduler
from database import Model from database import Model
from flask import Flask, render_template from flask import Flask, render_template
from redis import Redis from redis import Redis
from utils.download import download_album
from utils.processor import process_download from utils.processor import process_download
@ -9,6 +12,27 @@ redis = Redis(host='redis', port=6379)
Album = Model('album') Album = Model('album')
def process_downloads():
print('Processing Downloads..')
pending_downloads = Album.search([('downloaded', '=', False), ('downloading', '=', False)])
if pending_downloads:
ready_album = pending_downloads[:1]
if ready_album:
album = ready_album[0]
print('...................')
print('Downloading Album..')
print(album)
Album.write(album['id'], {'downloading': True})
download_album(album)
else:
return
cron = BackgroundScheduler({'apscheduler.job_defaults.max_instances': 3}, daemon=True)
cron.add_job(process_downloads, 'interval', minutes=1)
cron.start()
@app.route('/') @app.route('/')
def index(): def index():
# redis.incr('hits') # redis.incr('hits')
@ -35,9 +59,9 @@ def get_artist(path):
@app.route('/api/v1/get/queue') @app.route('/api/v1/get/queue')
def get_queue(): def get_queue():
album_ids = Album.search([('downloaded', '=', False)]) album_ids = Album.search([('downloaded', '=', False)])
data = {'album_ids': album_ids} data = {}
print('======================') if album_ids:
print(data) data.update({'album_ids': album_ids})
return render_template('download_queue.html', **data) return render_template('download_queue.html', **data)

@ -1,3 +1,4 @@
import json
import operator as oprtr import operator as oprtr
from pysondb import PysonDB from pysondb import PysonDB
@ -37,8 +38,6 @@ class Model:
filtered_record_ids =[] filtered_record_ids =[]
for record in records: for record in records:
record_id = self.env.get_by_id(record) record_id = self.env.get_by_id(record)
print('===')
print(record_id)
checklist = [] checklist = []
for param in params: for param in params:
field = param[0] field = param[0]
@ -48,6 +47,7 @@ class Model:
passed = all(x for x in checklist) passed = all(x for x in checklist)
if passed: if passed:
record_id.update({'id': record})
filtered_record_ids.append(record_id) filtered_record_ids.append(record_id)
return filtered_record_ids return filtered_record_ids
@ -77,7 +77,8 @@ class Model:
return record_ids return record_ids
def write(self, record_id, vals): def write(self, record_id, vals):
self.env.update_by_id(record_id, vals) record = self.env.update_by_id(record_id, vals)
return record
def unlink(self, record_id): def unlink(self, record_id):
self.env.delete_by_id(record_id) self.env.delete_by_id(record_id)

@ -9,85 +9,61 @@
"link" "link"
], ],
"data": { "data": {
"199074445401889600": { "277061953508566187": {
"artist": "Inteus", "artist": "System Of A Down",
"downloaded": false, "downloaded": true,
"downloading": false, "downloading": false,
"link": "/playlist?list=OLAK5uy_nr-vlAyokNEb25RLBNe1XHsFo9gkvu2Pg&playnext=1&index=1", "link": "/playlist?list=OLAK5uy_lvT9kmNao6-ZoqeO4Vs_dA5Ol80SXk3Ig&playnext=1&index=1",
"cover": "https://i9.ytimg.com/s_p/OLAK5uy_nr-vlAyokNEb25RLBNe1XHsFo9gkvu2Pg/mqdefault.jpg?sqp=CJT0pKQGir7X7AMGCN-N_qMG&rs=AOn4CLBo8tjoBHrUytlN1kfqTHYVMaVA4Q&v=1686079199", "cover": "https://i9.ytimg.com/s_p/OLAK5uy_lvT9kmNao6-ZoqeO4Vs_dA5Ol80SXk3Ig/mqdefault.jpg?sqp=CMzWpaQGir7X7AMGCLH-l6QG&rs=AOn4CLAvH1W4KrlwCiNjnkCP0Od959EmRQ&v=1686503217",
"album": "Quick Revive" "album": "Protect The Land - Genocidal Humanoidz"
}, },
"187732915376923467": { "944002510455338759": {
"artist": "Inteus", "artist": "System Of A Down",
"downloaded": false, "downloaded": true,
"downloading": false, "downloading": false,
"link": "/playlist?list=OLAK5uy_lS0tCQXZ-1ppWJOMhaMel8GKGtnUzsvnU&playnext=1&index=1", "link": "/playlist?list=OLAK5uy_k0JS7wXMiLcvCNgcbZunGaPiTt1KX3rY4&playnext=1&index=1",
"cover": "https://i9.ytimg.com/s_p/OLAK5uy_lS0tCQXZ-1ppWJOMhaMel8GKGtnUzsvnU/mqdefault.jpg?sqp=CJT0pKQGir7X7AMGCPDOhaQG&rs=AOn4CLBa8Mmhg8B0A7ljEpCsig_bzTju0A&v=1686202224", "cover": "https://i9.ytimg.com/s_p/OLAK5uy_k0JS7wXMiLcvCNgcbZunGaPiTt1KX3rY4/mqdefault.jpg?sqp=CMzWpaQGir7X7AMGCMPCoKQG&rs=AOn4CLAXHNH_ikaut2-Lf_ZMvtbEw2QsJw&v=1686643011",
"album": "Winds of Paradise" "album": "Hypnotize"
}, },
"206562046422345861": { "408685349006703299": {
"artist": "Inteus", "artist": "System Of A Down",
"downloaded": false, "downloaded": true,
"downloading": false, "downloading": false,
"link": "/playlist?list=OLAK5uy_movr4fRkYisvKvX92G_D6fWfV1umrn3hs&playnext=1&index=1", "link": "/playlist?list=OLAK5uy_kTJeZXfriqNa_00DjGWvAIICYRRiOISGs&playnext=1&index=1",
"cover": "https://i9.ytimg.com/s_p/OLAK5uy_movr4fRkYisvKvX92G_D6fWfV1umrn3hs/mqdefault.jpg?sqp=CJT0pKQGir7X7AMGCIKr_6MG&rs=AOn4CLDiszLRoh4cueTcK9h20CQ3KNpeXQ&v=1686099330", "cover": "https://i9.ytimg.com/s_p/OLAK5uy_kTJeZXfriqNa_00DjGWvAIICYRRiOISGs/mqdefault.jpg?sqp=CMzWpaQGir7X7AMGCOD8kKQG&rs=AOn4CLDilmmezso7Uga6UtwFkyZwWoajnQ&v=1686388320",
"album": "Selection:3" "album": "Mezmerize"
}, },
"321688139888393359": { "294169533529189046": {
"artist": "Inteus", "artist": "System Of A Down",
"downloaded": false, "downloaded": true,
"downloading": false, "downloading": false,
"link": "/playlist?list=OLAK5uy_kW87DzVan7NyJ7j06XBmOHlg1WaFm38LA&playnext=1&index=1", "link": "/playlist?list=OLAK5uy_nTgNbKalmllvDQkCl1AnGtl6qYlqHOV04&playnext=1&index=1",
"cover": "https://i9.ytimg.com/s_p/OLAK5uy_kW87DzVan7NyJ7j06XBmOHlg1WaFm38LA/mqdefault.jpg?sqp=CJT0pKQGir7X7AMGCIDi_aMG&rs=AOn4CLA4dE1oa2TYSqb0pvfNTdK7ZSgERw&v=1686073600", "cover": "https://i9.ytimg.com/s_p/OLAK5uy_nTgNbKalmllvDQkCl1AnGtl6qYlqHOV04/mqdefault.jpg?sqp=CMzWpaQGir7X7AMGCLKGlKQG&rs=AOn4CLDLmCArMfYuSemTqvhr7ZFjgNRzdA&v=1686438706",
"album": "Bruh Moment (2020 Scraps)" "album": "Steal This Album!"
}, },
"633598784099856320": { "211435660709717567": {
"artist": "Inteus", "artist": "System Of A Down",
"downloaded": false, "downloaded": true,
"downloading": false, "downloading": false,
"link": "/playlist?list=OLAK5uy_n1DHIq4LZlVVBvyilCzrjxAyCmsBSRfY0&playnext=1&index=1", "link": "/playlist?list=OLAK5uy_kb1yvg1bLW2yKdKxO1qvzGK7pFl9TuFBw&playnext=1&index=1",
"cover": "https://i9.ytimg.com/s_p/OLAK5uy_n1DHIq4LZlVVBvyilCzrjxAyCmsBSRfY0/mqdefault.jpg?sqp=CJT0pKQGir7X7AMGCJGzn6QG&rs=AOn4CLD_qLcb-Z1EabBDe3449f3d0mh3Cg&v=1686624657", "cover": "https://i9.ytimg.com/s_p/OLAK5uy_kb1yvg1bLW2yKdKxO1qvzGK7pFl9TuFBw/mqdefault.jpg?sqp=CMzWpaQGir7X7AMGCOuEkaQG&rs=AOn4CLCiDAqW94eyFczMp1Lou8IRPhVNYw&v=1686389355",
"album": "Yent Szn 3" "album": "Toxicity"
}, },
"131921253377227610": { "661582160567415371": {
"artist": "Inteus", "artist": "System Of A Down",
"downloaded": false, "downloaded": true,
"downloading": false, "downloading": false,
"link": "/playlist?list=OLAK5uy_nm2zfpc5MDyzOp2ftFqdlHBQ-L3tE2BQM&playnext=1&index=1", "link": "/playlist?list=OLAK5uy_ld_QngiUfBzcKb1CnnoBS-b7xauS6N2Us&playnext=1&index=1",
"cover": "https://i9.ytimg.com/s_p/OLAK5uy_nm2zfpc5MDyzOp2ftFqdlHBQ-L3tE2BQM/mqdefault.jpg?sqp=CJT0pKQGir7X7AMGCIPhgaQG&rs=AOn4CLBM_1qrbE_tAOEp51oGRYQMeTkRsw&v=1686139011", "cover": "https://i9.ytimg.com/s_p/OLAK5uy_ld_QngiUfBzcKb1CnnoBS-b7xauS6N2Us/mqdefault.jpg?sqp=CMzWpaQGir7X7AMGCKCjjaQG&rs=AOn4CLCtH2z6aR7u9EemiwZEda7-S3ADuw&v=1686327712",
"album": "Voyager" "album": "System Of A Down"
}, },
"271867710382714948": { "157682831582935241": {
"artist": "Inteus", "artist": "System Of A Down",
"downloaded": false, "downloaded": true,
"downloading": false, "downloading": false,
"link": "/playlist?list=OLAK5uy_kEzRY57fWs2iqQv7mg9jA8XEwdctH3vdk&playnext=1&index=1", "link": "/playlist?list=OLAK5uy_nFkNOoOmhDf_bWKkazOrMDEqqh_Z7bVlU&playnext=1&index=1",
"cover": "https://i9.ytimg.com/s_p/OLAK5uy_kEzRY57fWs2iqQv7mg9jA8XEwdctH3vdk/mqdefault.jpg?sqp=CJT0pKQGir7X7AMGCLKkkaQG&rs=AOn4CLCsG_4SxEMgAp96U-dAiavg1BZggQ&v=1686393394", "cover": "https://i9.ytimg.com/s_p/OLAK5uy_nFkNOoOmhDf_bWKkazOrMDEqqh_Z7bVlU/mqdefault.jpg?sqp=CMzWpaQGir7X7AMGCPO9gKQG&rs=AOn4CLC7VbkYuPc5LGoGOU1G6SNc9lcoWA&v=1686118131",
"album": "Chapter III" "album": "B.Y.O.B."
},
"322585091946466973": {
"artist": "Inteus",
"downloaded": false,
"downloading": false,
"link": "/playlist?list=OLAK5uy_nWWfDckTPSOY4nN_5bXMz1y83Qrc160sM&playnext=1&index=1",
"cover": "https://i9.ytimg.com/s_p/OLAK5uy_nWWfDckTPSOY4nN_5bXMz1y83Qrc160sM/mqdefault.jpg?sqp=CJT0pKQGir7X7AMGCILUmaQG&rs=AOn4CLBW1i3Fi_0G31s8k81YFjUNM6ui_w&v=1686530562",
"album": "Chapter II"
},
"219693029017574393": {
"artist": "Inteus",
"downloaded": false,
"downloading": false,
"link": "/playlist?list=OLAK5uy_kwpt9qeeS577nxNUo8kh2S4R_3gFFf5Ys&playnext=1&index=1",
"cover": "https://i9.ytimg.com/s_p/OLAK5uy_kwpt9qeeS577nxNUo8kh2S4R_3gFFf5Ys/mqdefault.jpg?sqp=CJT0pKQGir7X7AMGCJeClqQG&rs=AOn4CLD82PHRl_xq8BKF2EtuLOC2d-WStg&v=1686470935",
"album": "Chapter 1"
},
"106299219586508927": {
"artist": "Inteus",
"downloaded": false,
"downloading": false,
"link": "/playlist?list=OLAK5uy_kA-xQTNx8Az1t4HAFQ9vB1oTWG4A5cAIQ&playnext=1&index=1",
"cover": "https://i9.ytimg.com/s_p/OLAK5uy_kA-xQTNx8Az1t4HAFQ9vB1oTWG4A5cAIQ/mqdefault.jpg?sqp=CJT0pKQGir7X7AMGCNaakaQG&rs=AOn4CLDN92pGYYBFP0Vwi5c28qE7L43K_w&v=1686392150",
"album": "Selection: 2"
} }
} }
} }

@ -1,3 +1,4 @@
apscheduler==3.10.1
async-timeout==4.0.2 async-timeout==4.0.2
beautifulsoup4==4.12.2 beautifulsoup4==4.12.2
Brotli==1.0.9 Brotli==1.0.9
@ -20,6 +21,7 @@ requests==2.31.0
requests-file==1.5.1 requests-file==1.5.1
selenium==3.14.1 selenium==3.14.1
selenium-requests==1.3 selenium-requests==1.3
schedule==1.2.0
six==1.16.0 six==1.16.0
soupsieve==2.4.1 soupsieve==2.4.1
tldextract==3.4.4 tldextract==3.4.4

Binary file not shown.

Before

Width:  |  Height:  |  Size: 77 KiB

After

Width:  |  Height:  |  Size: 77 KiB

@ -1,5 +1,6 @@
const appModal = $('#modalDownloadQueue'); const appModal = $('#modalDownloadQueue');
const appModalContent = $('#modal_content'); const appModalContent = $('#modal_content');
let modalPolling = false;
function proc_notification(icon, title, text) { function proc_notification(icon, title, text) {
Swal.fire({ Swal.fire({
@ -9,15 +10,22 @@ function proc_notification(icon, title, text) {
}) })
} }
$('.queue_btn').on('click', () => { function fill_download_queue() {
console.log('Get Queue!');
$.ajax({ $.ajax({
url: '/api/v1/get/queue' url: '/api/v1/get/queue'
}).done((res) => { }).done((res) => {
console.log(res);
appModalContent.html(res); appModalContent.html(res);
appModal.modal('toggle');
}) })
}
$('.queue_btn').on('click', () => {
console.log('Get Queue!');
if (modalPolling) {
clearInterval(modalPolling);
}
fill_download_queue();
modalPolling = setInterval(fill_download_queue, 4000);
appModal.modal('toggle');
}) })
$('#download_btn').on('click', () => { $('#download_btn').on('click', () => {

@ -1,38 +1,42 @@
import os import os
from database import Model
from const import * from const import *
from .yt_dlp_logger import * from .yt_dlp_logger import *
import wget import wget
import yt_dlp import yt_dlp
Album = Model('album')
def download_process_list(artist, processed_albums_data_list):
def download_album(album):
""" """
Take a list of dictionaries that have the values needed to create a file-structure and save the downloaded files Take a list of albums and process the downloads
:param artist: :param album: Dict of album data
:param processed_albums_data_list:
:return: :return:
""" """
print('------')
print('Album Data')
print(album)
artist = album.get('artist')
artist_path = MEDIA_FOLDER + '/%s' % artist artist_path = MEDIA_FOLDER + '/%s' % artist
if not os.path.exists(artist_path): if not os.path.exists(artist_path):
os.mkdir(artist_path) os.mkdir(artist_path)
for item in processed_albums_data_list:
print('---') print('---')
# Create album folder # Create album folder
album = item.get('album') album_title = album.get('album')
album_path = artist_path + '/%s' % album album_path = artist_path + '/%s' % album_title
if not os.path.exists(album_path): if not os.path.exists(album_path):
os.mkdir(album_path) os.mkdir(album_path)
# Save album cover # Save album cover
if item.get('cover'): if album.get('cover'):
try: try:
download_file(item.get('cover'), album_path) download_file(album.get('cover'), album_path)
except Exception as e: except Exception as e:
print("Warning: %s" % e) print("Warning: %s" % e)
# Download album # Download album
print(item)
ydl_opts = { ydl_opts = {
'logger': YtDlpLogger(), 'logger': YtDlpLogger(),
'progress_hooks': [yt_dlp_log_hook], 'progress_hooks': [yt_dlp_log_hook],
@ -47,11 +51,13 @@ def download_process_list(artist, processed_albums_data_list):
with yt_dlp.YoutubeDL(ydl_opts) as ydl: with yt_dlp.YoutubeDL(ydl_opts) as ydl:
try: try:
error_code = ydl.download('https://youtube.com' + item.get('link')) error_code = ydl.download('https://youtube.com' + album.get('link'))
except Exception as e: except Exception as e:
print('!!!!!!!!!') print('!!!!!!!!!')
print(e) print(e)
Album.write(album['id'], {'downloaded': True, 'downloading': False})
def download_file(url, output): def download_file(url, output):
filename = wget.download(url, out=output) filename = wget.download(url, out=output)

Loading…
Cancel
Save