From 51c9fed15381421c4b7e8ba95af60b5204483d50 Mon Sep 17 00:00:00 2001 From: Marius Peter Date: Sun, 5 Jun 2022 14:20:40 +0200 Subject: First commit :baby: --- app/main.py | 147 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 app/main.py (limited to 'app/main.py') diff --git a/app/main.py b/app/main.py new file mode 100644 index 0000000..149ef64 --- /dev/null +++ b/app/main.py @@ -0,0 +1,147 @@ +# -*- mode: python; -*- + +""" +routes.py module +---------------- + +This Python module contains the logic supporting: +1. Navigating between website pages +2. Interpreting user requests to the server +3. Dispatching requested content back to the user + +Python dependencies: +- flask: provides web application features +- forms: provides secure user form submission +- sqlalchemy: provides communication with database on server. + +Personal imports: +These are used to avoid cluttering this file with +placeholder data for posts' content. +""" + +import os +import time +import glob +from datetime import datetime +from concurrent.futures import ThreadPoolExecutor + +from flask import ( + Blueprint, + render_template, + send_from_directory, + request, + redirect, + flash, + url_for, + jsonify, + abort, +) +from flask_login import login_required, current_user +import youtube_dl + +from .models import db, Download +from .forms import DownloadToRemote, ManageRemote + +main = Blueprint("main", __name__) +executor = ThreadPoolExecutor(4) + + +@main.route("/") +@main.route("/index") +@login_required +def home(): + """Prompt for video URL.""" + # https://www.youtube.com/watch?v=86khmc6y1yE&list=RDGMEMYH9CUrFO7CfLJpaD7UR85w&index=13 + download_history = Download.query.order_by(Download.primary_key.desc()).all() + downloaded_files = [ + file for file in os.listdir("downloads") if file.endswith((".mp3", ".m4a")) + ] + pending_files = [file for file in os.listdir("downloads") if file.endswith(".part")] + return render_template( + "home.html", + user=current_user, + form_download_remote=DownloadToRemote(), + form_manage_remote=ManageRemote(), + downloaded_files=downloaded_files, + pending_files=pending_files, + download_history=download_history, + ) + + +@main.route("/download-remote", methods=["POST"]) +@login_required +def download_remote(): + """Download audio from URL onto server.""" + form = DownloadToRemote() + if form.validate_on_submit(): + url = request.form["url"] + ydl_opts = { + "format": "bestaudio/best", + "outtmpl": os.path.join( + os.getcwd(), + "downloads", + "%(title)s.%(ext)s", + ), + "noplaylist": True, + "postprocessors": [ + { + "key": "FFmpegExtractAudio", + "preferredcodec": "mp3", + "preferredquality": "192", + } + ], + } + executor.submit(youtube_dl.YoutubeDL(ydl_opts).download, [url]) + with youtube_dl.YoutubeDL(ydl_opts) as ydl: + # time.sleep(1) + info = ydl.extract_info(url, download=False) + title = info.get("title") + new_download = Download( + title=title, + url=url, + user_id=current_user.primary_key, + ) + db.session.add(new_download) + db.session.commit() + flash(f"Successfully started downloading {title}.") + return redirect("/index") + flash(f"Couldn't download {title}.") + return redirect("/index") + + +@main.route("/manage-remote/", methods=["POST"]) +@login_required +def manage_remote(): + """Manage all files downloaded on remote device. + + The value of the submit button pressed is checked, then the + appropriate redirection is performed. + + """ + form = ManageRemote() + if form.validate_on_submit(): + file_name = request.form.get("file_name") + if form.download_local.data: + return redirect(url_for("main.download_local", file=file_name)) + elif form.remove_remote.data: + return redirect(url_for("main.remove_remote", file=file_name)) + flash("Couldn't manage remote file.", "error") + return redirect("/index") + + +@main.route("/download-local/", methods=["GET", "POST"]) +@login_required +def download_local(file): + """Download file from remote to local device.""" + downloads = os.path.join(os.getcwd(), "downloads") + return send_from_directory(downloads, file, as_attachment=True) + + +@main.route("/remove-remote/", methods=["GET", "POST"]) +@login_required +def remove_remote(file): + """Remove file from remote device.""" + file_to_remove = os.path.join(os.getcwd(), "downloads", file) + os.remove(file_to_remove) + flash(f"Successfully removed file {file}.") + return redirect("/index") -- cgit v1.2.3