Added Dockerfile and sources

This commit is contained in:
0xFEEDC0DE64
2018-05-06 01:27:39 +02:00
parent a983389815
commit db9dd88759
5 changed files with 327 additions and 0 deletions

3
.dockerignore Normal file
View File

@ -0,0 +1,3 @@
/Dockerfile
/LICENSE
/README.md

9
Dockerfile Normal file
View File

@ -0,0 +1,9 @@
FROM php:7.0-apache
RUN apt update \
&& apt install youtube-dl -y \
&& rm /var/lib/apt/lists/* /var/log/* -Rf
ADD . /var/www/html
VOLUME ["/var/www/html/files"]

132
index.php Executable file
View File

@ -0,0 +1,132 @@
<?php
$options = [
"audio_mp3" => [
'name' => 'Audio Only (MP3)',
'group' => 'Audio Only',
'option' => '-k -x --audio-format mp3 --audio-quality 0',
'cache' => '*-%youtubeid%.mp3'
],
"audio_flac" => [
'name' => 'Audio Only (FLAC)',
'group' => 'Audio Only',
'option' => '-k -x --audio-format flac --audio-quality 0',
'cache' => '*-%youtubeid%.flac'
],
"best_video_audio" => [
'name' => 'Combine best Video+Audio',
'group' => NULL,
'option' => '-k',
'cache' => NULL
]
];
if(!chdir('files')) {
die('could not enter files folder');
}
if($_SERVER['REQUEST_METHOD'] == 'POST') {
if(!isset($_POST['option'], $_POST['url'])) {
http_response_code(400);
die('not all required values set!');
}
if(empty($option = trim($_POST['option'])) ||
empty($url = trim($_POST['url']))) {
http_response_code(400);
die('url empty!');
}
if(!filter_var($url, FILTER_VALIDATE_URL)) {
http_response_code(400);
die('invalid url!');
}
if(!isset($options[$option])) {
http_response_code(400);
die('invalid option!');
}
$option = $options[$option];
preg_match("#(?<=v=)[a-zA-Z0-9-]+(?=&)|(?<=v\/)[^&\n]+(?=\?)|(?<=v=)[^&\n]+|(?<=youtu.be/)[^&\n]+#", $url, $matches);
if(count($matches) != 1) {
http_response_code(400);
die('invalid youtube url!' . count($matches));
}
$cached = false;
if(!is_null($option['cache'])) {
foreach(glob(str_replace("%youtubeid%", $matches[0], $option['cache'])) as $file) {
echo '[cache] Destination: ' . $file . "\n";
$cached = true;
}
}
if($cached) {
die('exit code: 0');
}
ini_set('output_buffering', 'off');
ini_set('zlib.output_compression', false);
ini_set('implicit_flush', true);
ob_implicit_flush(true);
while (ob_get_level() > 0) {
$level = ob_get_level();
ob_end_clean();
if (ob_get_level() == $level) break;
}
if (function_exists('apache_setenv')) {
apache_setenv('no-gzip', '1');
apache_setenv('dont-vary', '1');
}
set_time_limit(0);
system('youtube-dl ' . $option['option']. ' ' . $url . ' 2>&1', $exitCode);
die('exit code: ' . $exitCode);
}
?>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<title>Daniel's YouTube Downloader</title>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous" />
<style>
pre {
max-height: 100px;
}
</style>
</head>
<body>
<div class="container">
<form method="POST" class="form-inline">
<select name="option" class="form-control">
<?php $lastGroup = NULL; ?>
<?php foreach($options as $index => $option) { ?>
<?php if($option['group'] != $lastGroup) { ?>
<?php if(!is_null($lastGroup)) { ?></optgroup><?php } ?>
<?php if(!is_null($option['group'])) { ?><optgroup label="<?php echo htmlentities($option['group']); ?>"><?php } ?>
<?php $lastGroup = $option['group']; ?>
<?php } ?>
<option value="<?php echo $index; ?>"><?php echo htmlentities($option['name']); ?></option>
<?php } ?>
</select>
<input type="url" name="url" <?php if(isset($url)) { echo 'value="' . htmlentities($url) . '"'; } ?> required="required" class="form-control" />
<button type="submit" class="btn btn-primary">Los</button>
<a href="info.php">Service Status</a>
</form>
</div>
<div class="row" id="results"></div>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script src="script.js"></script>
</body>
</html>

61
info.php Executable file
View File

@ -0,0 +1,61 @@
<html>
<head>
<title>Daniel's YouTube Downloader</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous" />
</head>
<body>
<div class="container">
<a href="index.php">Back</a>
<table class="table table-striped">
<thead>
<tr>
<?php
$output = shell_exec('ps aux');
$lines = explode("\n", $output);
$regExpr = "^";
foreach($lines as $i=>$line) {
if($i == 0) {
$columns = preg_split('/ +/', $line);
foreach($columns as $column) {
echo ' <th>' . htmlentities($column) . "</th>\n";
}
echo " </tr>\n";
echo " </thead>\n";
echo " <tbody>\n";
for($i = 1; $i < count($columns); $i++) {
$regExpr .= '([^ ]+) +';
}
$regExpr .= '(.*)$';
} else {
//if(strpos($line, "youtube-dl") === FALSE) {
// continue;
//}
if(!preg_match('/' . $regExpr . '/', $line, $matches)) {
continue;
}
array_shift($matches);
if($matches[0] != 'www-data') {
continue;
}
echo " <tr>\n";
foreach($matches as $match) {
echo ' <td>' . htmlentities($match) . "</td>\n";
}
echo " </tr>\n";
}
}
?>
</tbody>
</table>
</div>
</body>
</html>

122
script.js Normal file
View File

@ -0,0 +1,122 @@
jQuery(document).ready(function($){
$('form').submit(function(e) {
e.preventDefault();
var resultWrapper, result, resultHeader, resultBody, resultContent;
$('#results').append(resultWrapper = $('<div>')
.addClass('col-xl-3 col-md-4 col-sm-6 col-12')
.append(result = $('<div>')
.addClass('card text-white bg-secondary')
.append(resultHeader = $('<div>')
.addClass('card-header')
.text($("input[name=url]").val() + ' ')
.append($('<small>')
.text($('select[name=option] option:selected').text())
)
)
.append(resultBody = $('<div>')
.addClass('card-body')
.append(resultContent = $('<pre>')
)
)
)
);
function formatText(text) {
var result = "";
for(var line of text.split("\n")) {
var parts = line.split("\r");
result += parts[parts.length - 1] + "\n";
}
return result;
}
$.ajax({
'url': $('form').attr('action'),
'method': $('form').attr('method'),
'data': (function() {
var data = {};
$('form input, form select').each(function(){
data[$(this).attr('name')] = $(this).val();
});
return data;
})(),
'processData': true,
'contentType': 'application/x-www-form-urlencoded; charset=UTF-8',
'xhr': function() {
var xhr = new XMLHttpRequest();
xhr.addEventListener('progress', function(e) {
resultContent.text(formatText(e.target.response));
}, false);
return xhr;
},
'success': function(data) {
resultContent.text(formatText(data));
result
.removeClass('bg-warning')
if(data.indexOf('exit code: 0') == -1) {
result
.addClass('bg-danger')
.append($('<p>').text('There was an error while processing your request!'));
return;
}
var anyLink = false;
for(regex of [
/Destination: ([^\n\r$]*)/g,
/ ([^ ]+) has already been downloaded and merged/g
]) {
var match;
while (match = regex.exec(data)) {
if(anyLink) {
resultBody.append($('<br/>'));
}
resultBody.append($('<a>')
.addClass('btn btn-sm btn-primary')
.attr('href', 'files/' + match[1])
.text(match[1])
);
anyLink = true;
}
}
if(anyLink) {
result
.addClass('bg-success');
} else {
result
.addClass('bg-danger')
.append($('<p>').text('Did not find any downloadable file!'));
}
},
'error': function(jqXHR, textStatus, errorThrown) {
resultContent.text(formatText(jqXHR.responseText));
result
.removeClass('alert-warning')
.addClass('alert-danger')
.append($('<p>').text('Request failed!'));
},
'complete': function() {
resultHeader.prepend($('<a>')
.html('&times;')
.addClass('float-right btn btn-sm btn-danger')
.attr('href', '#')
.click(function(e) {
e.preventDefault();
resultWrapper.remove();
})
)
}
});
})
});