summaryrefslogtreecommitdiff
path: root/app/main.py
blob: fd1a8a09a7c63086d83472f8c8b669b634224e15 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# -*- mode: python; -*-

"""
"""

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(url_for("main.home"))
    flash(f"Couldn't download {title}.")
    return redirect(url_for("main.home"))


@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(url_for("main.home"))


@main.route("/download-local/<file>", 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/<file>", 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(url_for("main.home"))
Copyright 2019--2024 Marius PETER