-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 46315e8
Showing
10 changed files
with
381 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
download/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
from os import urandom, path | ||
|
||
|
||
# Web Server | ||
CSRF_ENABLED = True | ||
SECRET_KEY = urandom(30) | ||
PROPAGATE_EXCEPTIONS = True | ||
|
||
basedir = path.abspath(path.dirname(__file__)) | ||
VIDEO_DIR = path.join(basedir, 'download') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
ytdl | ||
==== | ||
|
||
A web application for downloading audio/video from YouTube. Basically just a web wrapper | ||
for [youtube-dl](https://ytdl-org.github.io/youtube-dl/) with a stripped-down feature set. | ||
|
||
Usage | ||
===== | ||
|
||
Installation | ||
------------ | ||
|
||
You'll need to install [youtube-dl](https://ytdl-org.github.io/youtube-dl/). It's | ||
recomended that you keep it updated (e.g., via a cron job). | ||
|
||
``` | ||
youtube-dl -U | ||
``` | ||
|
||
You'll also need to install ffmpeg/avconv. | ||
|
||
Requirements | ||
------------ | ||
|
||
* flask | ||
* flask-wtf | ||
* [youtube-dl](https://ytdl-org.github.io/youtube-dl/) | ||
* ffmpeg/avconv | ||
|
||
Starting the Server | ||
------------------- | ||
|
||
Start the server with `run.py`. By default it will be accessible at `localhost:9999`. To | ||
make the server world-accessible or for other options, see `run.py -h`. | ||
|
||
If you're having trouble configuring your sever, I wrote a | ||
[blog post](http://blog.spurll.com/2015/02/configuring-flask-uwsgi-and-nginx.html) | ||
explaining how you can get Flask, uWSGI, and Nginx working together. | ||
|
||
Bugs and Feature Requests | ||
========================= | ||
|
||
Feature Requests | ||
---------------- | ||
|
||
* TODO: Fix formatting | ||
* TODO: Delete downloads after a while | ||
* TODO: Include recommended cron lines for deleting old downloads and updating ytdl | ||
|
||
Known Bugs | ||
---------- | ||
|
||
None | ||
|
||
Thanks | ||
====== | ||
|
||
Thanks to the team behind [youtube-dl](https://ytdl-org.github.io/youtube-dl/)! | ||
|
||
License Information | ||
=================== | ||
|
||
Written by Gem Newman. [Website](http://spurll.com) | [GitHub](https://github.com/spurll/) | [Twitter](https://twitter.com/spurll) | ||
|
||
This work is licensed under Creative Commons [BY-SA 4.0](http://creativecommons.org/licenses/by-sa/4.0/). | ||
|
||
JQuery included under the [MIT "Expat" License](https://opensource.org/licenses/MIT). | ||
|
||
Remember: [GitHub is not my CV](https://blog.jcoglan.com/2013/11/15/why-github-is-not-your-cv/). | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
#!/usr/bin/env python3 | ||
|
||
|
||
from argparse import ArgumentParser | ||
|
||
from ytdl import app | ||
|
||
|
||
if __name__ == '__main__': | ||
description = "Runs the Flask server." | ||
parser = ArgumentParser(description=description) | ||
parser.add_argument("-0", "--public", help="Makes the server world-" | ||
"accessible by hosting at 0.0.0.0.", | ||
action="store_true") | ||
parser.add_argument("-p", "--port", help="Defines the port. Defaults to " | ||
"9999.", type=int, default=9999) | ||
parser.add_argument("-d", "--debug", help="Turns server debug mode on. " | ||
"(Not recommended for world-accesible servers!)", | ||
action="store_true") | ||
parser.add_argument("-r", "--reload", help="Turns the automatic realoder " | ||
"on. This setting restarts the server whenever a " | ||
"change in the source is detected.", | ||
action="store_true") | ||
args = parser.parse_args() | ||
|
||
app.run(host="0.0.0.0" if args.public else "localhost", port=args.port, | ||
use_debugger=args.debug, use_reloader=args.reload) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
from flask import Flask | ||
import os | ||
|
||
|
||
app = Flask(__name__) | ||
app.config.from_object('config') | ||
|
||
|
||
if not os.path.exists(app.config['VIDEO_DIR']): | ||
os.makedirs(app.config['VIDEO_DIR']) | ||
|
||
|
||
from ytdl import views |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
from flask_wtf import FlaskForm | ||
from wtforms import TextField, RadioField | ||
from wtforms.validators import Required | ||
|
||
|
||
class DownloadForm(FlaskForm): | ||
url = TextField('URL', validators=[Required()]) | ||
fmt = RadioField( | ||
'Format', | ||
choices=[ | ||
('mp3', 'Audio (MP3)'), | ||
('wav', 'Audio (WAV)'), | ||
('v', 'Video') | ||
], | ||
default='mp3' | ||
) | ||
|
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
body { | ||
font-family: serif; | ||
color: #ffffff; | ||
background-color: #222222; | ||
overflow-y: auto; | ||
margin: 0px; | ||
} | ||
|
||
p { | ||
margin: 5px; | ||
text-align: center; | ||
} | ||
|
||
table { | ||
width: 100%; | ||
margin-top: 5px; | ||
margin-bottom: 10px; | ||
border: 0px; | ||
border-spacing: 0px; | ||
} | ||
|
||
th { font-variant: small-caps; } | ||
td { font-size: 85%; padding: 3px; } | ||
tfoot { font-weight: bold; font-variant: small-caps; } | ||
|
||
#content { | ||
width: 100%; | ||
max-width: 500px; | ||
margin: auto; | ||
padding-top: 10px; | ||
} | ||
|
||
#title-buffer { | ||
width: 100%; | ||
height: 52px; | ||
top: 0px; | ||
position: static; | ||
} | ||
|
||
#title-bar { | ||
width: 100%; | ||
top: 0px; | ||
position: fixed; | ||
background-color: #111111; | ||
border-bottom: solid #444444; | ||
} | ||
|
||
#title { | ||
width: 60%; | ||
margin: auto; | ||
font-variant: small-caps; | ||
font-size: 200%; | ||
text-align: center; | ||
padding-top: 10px; | ||
padding-bottom: 10px; | ||
} | ||
|
||
#links { | ||
width: calc(20% - 20px); | ||
float: left; | ||
text-align: left; | ||
padding: 10px; | ||
} | ||
|
||
#user { | ||
width: calc(20% - 20px); | ||
float: right; | ||
text-align: right; | ||
padding: 10px; | ||
} | ||
|
||
.heading { | ||
font-variant: small-caps; | ||
text-align: center; | ||
font-size: 150%; | ||
padding-top: 5px; | ||
padding-bottom: 10px; | ||
} | ||
|
||
.small-screen { | ||
width: auto; | ||
margin: auto; | ||
float: none; | ||
text-align: center; | ||
padding: 2px; | ||
} | ||
|
||
.messages { font-style: italic; text-align: center; } | ||
.wide { width: 70%; top: 0px; } | ||
.narrow { width: 30%; top: 0px; } | ||
.right { float: right; text-align: right; } | ||
.section { padding-top: 5px; padding-bottom: 10px; } | ||
.login { max-width: 320px; margin: auto; } | ||
|
||
tr:nth-child(even) { background-color: #444444; border-color: #444444; } | ||
|
||
a:link { text-decoration: none; color: #888888; } | ||
a:visited { text-decoration: none; color: #888888; } | ||
a:hover { text-decoration: none; color: #ffffff; } | ||
a:active { text-decoration: none; color: #888888; } | ||
|
||
input { color: #ffffff; background-color: transparent; border: solid 1px #444444; } | ||
select { color: #ffffff; background-color: transparent; border: solid 1px #444444; } | ||
select option { background-color: #222222; } | ||
input[type="text"] { width: 100%; padding: 5px; margin: 5px; } | ||
input[type="password"] { width: 100%; } | ||
input[type="submit"] { width: 90%; padding: 5px; margin: 5px; } | ||
|
||
ul { padding: 0; text-align: center; } | ||
li { display: inline-block; margin: 10px; } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
<html> | ||
<head> | ||
<!-- Support for iOS device sizes. --> | ||
<meta name="viewport" content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, shrink-to-fit=no'> | ||
|
||
{% if title %} | ||
<title>{{title}}</title> | ||
{% endif %} | ||
|
||
<link rel="stylesheet" type="text/css" href="{{url_for('static', filename='style.css')}}"/> | ||
<link rel="shortcut icon" href="{{url_for('static', filename='icon.png')}}"/> | ||
|
||
<script> | ||
$(document).ready(function() { | ||
resizeContent(); | ||
resizeBuffer(); | ||
}); | ||
|
||
$(window).resize(function() { | ||
resizeContent(); | ||
resizeBuffer(); | ||
}); | ||
|
||
$(window).on('orientationchange', function() { | ||
resizeContent(); | ||
resizeBuffer(); | ||
}); | ||
|
||
function resizeBuffer() { | ||
// Resizes the title buffer which pushes content down below the floating title bar. | ||
$('#title-buffer').height($('#title-bar').outerHeight()); | ||
} | ||
|
||
function resizeContent() { | ||
if ($(window).width() < 700) { | ||
// Moves and resizes the links and login information information on a smaller screen. | ||
$('#links').addClass('small-screen'); | ||
$('#user').addClass('small-screen'); | ||
$('#title').addClass('small-screen'); | ||
} | ||
else { | ||
// Moves and resizes the links and login information information on a bigger (or horizontal) screen. | ||
$('#links').removeClass('small-screen'); | ||
$('#user').removeClass('small-screen'); | ||
$('#title').removeClass('small-screen'); | ||
} | ||
} | ||
</script> | ||
</head> | ||
|
||
<body> | ||
<div id="title-buffer"></div> | ||
<div id="title-bar"> | ||
<div id="title">ytdl</div> | ||
</div> | ||
|
||
{% with messages = get_flashed_messages() %} | ||
<div class="messages"> | ||
{% if messages %} | ||
{% for message in messages %} | ||
<p>{{ message }}</p> | ||
{% endfor %} | ||
{% endif %} | ||
</div> | ||
{% endwith %} | ||
|
||
<div id="content"> | ||
<form method="POST"> | ||
{{form.hidden_tag()}} | ||
|
||
<div class="narrow right"><input type="submit" value="Download" /></div> | ||
<div class="wide left">{{form.url(autofocus=True, placeholder="Video URL")}}</div> | ||
|
||
<div>{{form.fmt}}</div> | ||
</form> | ||
</div> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import os.path | ||
from tempfile import mkdtemp | ||
from subprocess import run | ||
from flask import render_template, flash, request, send_from_directory | ||
|
||
from ytdl import app | ||
from ytdl.forms import DownloadForm | ||
|
||
|
||
@app.route('/', methods=['GET', 'POST']) | ||
def index(): | ||
""" | ||
Download. | ||
""" | ||
form = DownloadForm() | ||
|
||
if request.method == 'GET': | ||
return render_template('index.html', form=form) | ||
|
||
if not form.validate_on_submit(): | ||
flash('Invalid form data. Please try again.') | ||
return render_template('index.html', form=form) | ||
|
||
# Create temporary directory | ||
directory = mkdtemp(dir=app.config['VIDEO_DIR']) | ||
|
||
fmt = form.fmt.data | ||
|
||
try: | ||
# Download the file | ||
process = run( | ||
[ | ||
'youtube-dl', | ||
form.url.data, | ||
'-o', os.path.join(directory, '%(title)s.%(ext)s'), | ||
'-x' if fmt != 'v' else '', | ||
f'--audio-format={fmt}' if fmt != 'v' else '' | ||
], | ||
check=True | ||
) | ||
|
||
except Exception as e: | ||
print(e) | ||
flash('Error: Could not download/convert the video as requested.') | ||
return render_template('index.html', form=form) | ||
|
||
files = os.listdir(directory) | ||
if not files: | ||
flash('Error: Could not find the file specified.') | ||
return render_template('index.html', form=form) | ||
|
||
# Send the file to the user | ||
return send_from_directory(directory, files[0], as_attachment=True) | ||
|