View raw

1 # -*- mode: python; -*- 2 3 """ 4 """ 5 6 import os 7 import time 8 import glob 9 from datetime import datetime 10 from concurrent.futures import ThreadPoolExecutor 11 12 from flask import ( 13 Blueprint, 14 render_template, 15 send_from_directory, 16 request, 17 redirect, 18 flash, 19 url_for, 20 jsonify, 21 abort, 22 ) 23 from flask_login import login_required, current_user 24 import youtube_dl 25 26 from .models import db, Download 27 from .forms import DownloadToRemote, ManageRemote 28 29 main = Blueprint("main", __name__) 30 executor = ThreadPoolExecutor(4) 31 32 33 @main.route("/") 34 @main.route("/index") 35 @login_required 36 def home(): 37 """Prompt for video URL.""" 38 # https://www.youtube.com/watch?v=86khmc6y1yE&list=RDGMEMYH9CUrFO7CfLJpaD7UR85w&index=13 39 download_history = Download.query.order_by(Download.primary_key.desc()).all() 40 downloaded_files = [ 41 file for file in os.listdir("downloads") if file.endswith((".mp3", ".m4a")) 42 ] 43 pending_files = [file for file in os.listdir("downloads") if file.endswith(".part")] 44 return render_template( 45 "home.html", 46 user=current_user, 47 form_download_remote=DownloadToRemote(), 48 form_manage_remote=ManageRemote(), 49 downloaded_files=downloaded_files, 50 pending_files=pending_files, 51 download_history=download_history, 52 ) 53 54 55 @main.route("/download-remote", methods=["POST"]) 56 @login_required 57 def download_remote(): 58 """Download audio from URL onto server.""" 59 form = DownloadToRemote() 60 if form.validate_on_submit(): 61 url = request.form["url"] 62 ydl_opts = { 63 "format": "bestaudio/best", 64 "outtmpl": os.path.join( 65 os.getcwd(), 66 "downloads", 67 "%(title)s.%(ext)s", 68 ), 69 "noplaylist": True, 70 "postprocessors": [ 71 { 72 "key": "FFmpegExtractAudio", 73 "preferredcodec": "mp3", 74 "preferredquality": "192", 75 } 76 ], 77 } 78 executor.submit(youtube_dl.YoutubeDL(ydl_opts).download, [url]) 79 with youtube_dl.YoutubeDL(ydl_opts) as ydl: 80 # time.sleep(1) 81 info = ydl.extract_info(url, download=False) 82 title = info.get("title") 83 new_download = Download( 84 title=title, 85 url=url, 86 user_id=current_user.primary_key, 87 ) 88 db.session.add(new_download) 89 db.session.commit() 90 flash(f"Successfully started downloading {title}.") 91 return redirect(url_for("main.home")) 92 flash(f"Couldn't download {title}.") 93 return redirect(url_for("main.home")) 94 95 96 @main.route("/manage-remote/", methods=["POST"]) 97 @login_required 98 def manage_remote(): 99 """Manage all files downloaded on remote device. 100 101 The value of the submit button pressed is checked, then the 102 appropriate redirection is performed. 103 104 """ 105 form = ManageRemote() 106 if form.validate_on_submit(): 107 file_name = request.form.get("file_name") 108 if form.download_local.data: 109 return redirect(url_for("main.download_local", file=file_name)) 110 elif form.remove_remote.data: 111 return redirect(url_for("main.remove_remote", file=file_name)) 112 flash("Couldn't manage remote file.", "error") 113 return redirect(url_for("main.home")) 114 115 116 @main.route("/download-local/<file>", methods=["GET", "POST"]) 117 @login_required 118 def download_local(file): 119 """Download file from remote to local device.""" 120 downloads = os.path.join(os.getcwd(), "downloads") 121 return send_from_directory(downloads, file, as_attachment=True) 122 123 124 @main.route("/remove-remote/<file>", methods=["GET", "POST"]) 125 @login_required 126 def remove_remote(file): 127 """Remove file from remote device.""" 128 file_to_remove = os.path.join(os.getcwd(), "downloads", file) 129 os.remove(file_to_remove) 130 flash(f"Successfully removed file {file}.") 131 return redirect(url_for("main.home")) 132