From efe1a34a9f24d78574dd9109e098c1492b238401 Mon Sep 17 00:00:00 2001 From: Pierre Rudloff Date: Wed, 27 Jul 2016 13:36:31 +0200 Subject: [PATCH 01/29] More questions in FAQ --- FAQ.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/FAQ.md b/FAQ.md index 59c4b04..362e23a 100644 --- a/FAQ.md +++ b/FAQ.md @@ -3,3 +3,26 @@ ## My browser plays the video. How do I download it? Most recent browsers automatically play a video if it is a format they know how to play. You can ususally download the video by doing *File > Save to* or *ctrl + S*. + +## How do I change config parameters? +You need to create a YAML file called `config.yml` at the root of your project. +Here are the parameters that you can set: +* youtubedl: path to youtube-dl's binary of `__main__.py` file +* python: path to your python binary +* params: an array of parameters to pass to youtube-dl +* curl_params: an array of parameters to pass to curl +* convert: true to enable audio conversion +* avconv: path to your avconv or ffmpeg binary +* rtmpdump: path to your rtmpdump binary + +See [config.example.yml](config.example.yml) for default values. + +## How do I enable audio conversion? +In order to enable audio conversion, you need to add this to your `config.yml` file: +```yaml +convert: true +``` +You will also need to install `avconv` and `curl` on your server: +```bash +sudo apt-get install libav-tools curl +``` From bd02236ca522ccf656472cd862c9dcf89dd8f4d4 Mon Sep 17 00:00:00 2001 From: Pierre Rudloff Date: Wed, 27 Jul 2016 13:40:18 +0200 Subject: [PATCH 02/29] Syntax highlighting in README --- README.md | 95 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 49 insertions(+), 46 deletions(-) diff --git a/README.md b/README.md index bf2ff3e..483b269 100644 --- a/README.md +++ b/README.md @@ -14,25 +14,28 @@ You just have to unzip it on your server and it should be ready to use. ### From Git In order to get AllTube working, you need to use [npm](https://www.npmjs.com/) and [Composer](https://getcomposer.org/): - - npm install - composer install +```bash +npm install +composer install +``` This will download all the required dependencies. (Note that it will download the ffmpeg binary for 64-bits Linux. If you are on another platform, you might want to specify the path to avconv/ffmpeg in your config file.) You should also ensure that the *templates_c* folder has the right permissions: - - chmod 777 templates_c/ +```bash +chmod 777 templates_c/ +``` If your web server is Apache, you need to set the `AllowOverride` setting to `All` or `FileInfo`. ## Config If you want to use a custom config, you need to create a config file: - - cp config.example.yml config.yml +```bash +cp config.example.yml config.yml +``` ## Web server configuration ### Apache @@ -43,52 +46,52 @@ You will need the following modules: ### Nginx Here is an exemple Nginx configuration: +```nginx +server { + server_name localhost; + listen 443 ssl; - server { - server_name localhost; - listen 443 ssl; + root /var/www/path/to/alltube; + index index.php; - root /var/www/path/to/alltube; - index index.php; + access_log /var/log/nginx/alltube.access.log; + error_log /var/log/nginx/alltube.error.log; - access_log /var/log/nginx/alltube.access.log; - error_log /var/log/nginx/alltube.error.log; + types { + text/html html htm shtml; + text/css css; + text/xml xml; + application/x-web-app-manifest+json webapp; + } - types { - text/html html htm shtml; - text/css css; - text/xml xml; - application/x-web-app-manifest+json webapp; - } + # Deny access to dotfiles + location ~ /\. { + deny all; + } - # Deny access to dotfiles - location ~ /\. { - deny all; - } + location / { + try_files $uri /index.php?$args; + } - location / { - try_files $uri /index.php?$args; - } + location ~ \.php$ { + try_files $uri /index.php?$args; - location ~ \.php$ { - try_files $uri /index.php?$args; + fastcgi_param PATH_INFO $fastcgi_path_info; + fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; - fastcgi_param PATH_INFO $fastcgi_path_info; - fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info; - fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_pass unix:/var/run/php5-fpm.sock; + fastcgi_index index.php; + fastcgi_split_path_info ^(.+\.php)(/.+)$; + fastcgi_intercept_errors off; - fastcgi_pass unix:/var/run/php5-fpm.sock; - fastcgi_index index.php; - fastcgi_split_path_info ^(.+\.php)(/.+)$; - fastcgi_intercept_errors off; - - fastcgi_buffer_size 16k; - fastcgi_buffers 4 16k; - - include fastcgi_params; - } - } + fastcgi_buffer_size 16k; + fastcgi_buffers 4 16k; + include fastcgi_params; + } +} +``` ## License This software is available under the [GNU General Public License](http://www.gnu.org/licenses/gpl.html). @@ -100,7 +103,7 @@ You need [avconv](https://libav.org/avconv.html), [rtmpdump](http://rtmpdump.mpl If you don't want to enable conversions, you can disable it in *config.yml*. On Debian-based systems: - - sudo apt-get install libav-tools rtmpdump curl - +```bash +sudo apt-get install libav-tools rtmpdump curl +``` You also probably need to edit the *avconv* variable in *config.yml* so that it points to your ffmpeg/avconv binary (*/usr/bin/avconv* on Debian/Ubuntu). From 76360f8ce07be1effe270ed2adf362095fbeb678 Mon Sep 17 00:00:00 2001 From: Pierre Rudloff Date: Thu, 28 Jul 2016 02:07:40 +0200 Subject: [PATCH 03/29] avconv path in FAQ --- FAQ.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/FAQ.md b/FAQ.md index 362e23a..52c7ed6 100644 --- a/FAQ.md +++ b/FAQ.md @@ -7,7 +7,7 @@ You can ususally download the video by doing *File > Save to* or *ctrl + S*. ## How do I change config parameters? You need to create a YAML file called `config.yml` at the root of your project. Here are the parameters that you can set: -* youtubedl: path to youtube-dl's binary of `__main__.py` file +* youtubedl: path to your youtube-dl binary * python: path to your python binary * params: an array of parameters to pass to youtube-dl * curl_params: an array of parameters to pass to curl @@ -21,6 +21,7 @@ See [config.example.yml](config.example.yml) for default values. In order to enable audio conversion, you need to add this to your `config.yml` file: ```yaml convert: true +avconv: path/to/avconv ``` You will also need to install `avconv` and `curl` on your server: ```bash From 26388ea1b45ff6f5cb354153d028057755732ac8 Mon Sep 17 00:00:00 2001 From: Pierre Rudloff Date: Sat, 30 Jul 2016 00:15:17 +0200 Subject: [PATCH 04/29] Move all logic to the VideoDownload class --- classes/VideoDownload.php | 111 ++++++++++++++++++++++++++++++++ controllers/FrontController.php | 87 +------------------------ 2 files changed, 114 insertions(+), 84 deletions(-) diff --git a/classes/VideoDownload.php b/classes/VideoDownload.php index 22033cc..67ebd9b 100644 --- a/classes/VideoDownload.php +++ b/classes/VideoDownload.php @@ -14,6 +14,7 @@ namespace Alltube; use Symfony\Component\Process\Process; use Symfony\Component\Process\ProcessBuilder; +use Chain\Chain; /** * Main class @@ -113,4 +114,114 @@ class VideoDownload } } + + public function getFilename($url, $format = null) + { + $this->procBuilder->setArguments( + array( + '--get-filename', + $url + ) + ); + if (isset($format)) { + $this->procBuilder->add('-f '.$format); + } + $process = $this->procBuilder->getProcess(); + $process->run(); + if (!$process->isSuccessful()) { + throw new \Exception($process->getErrorOutput()); + } else { + return $process->getOutput(); + } + } + + public function getAudioFilename($url, $format = null) + { + return html_entity_decode( + pathinfo( + $this->getFilename($url, $format), + PATHINFO_FILENAME + ).'.mp3', + ENT_COMPAT, + 'ISO-8859-1' + ); + } + + public function getConversionProcess($url, $format) + { + if (!shell_exec('which '.$this->config->avconv)) { + throw(new \Exception('Can\'t find avconv or ffmpeg')); + } + + $video = $this->getJSON($url, $format); + + //Vimeo needs a correct user-agent + ini_set( + 'user_agent', + $video->http_headers->{'User-Agent'} + ); + $avconvProc = ProcessBuilder::create( + array( + $this->config->avconv, + '-v', 'quiet', + '-i', '-', + '-f', 'mp3', + '-vn', + 'pipe:1' + ) + ); + + if (parse_url($video->url, PHP_URL_SCHEME) == 'rtmp') { + if (!shell_exec('which '.$this->config->rtmpdump)) { + throw(new \Exception('Can\'t find rtmpdump')); + } + $builder = new ProcessBuilder( + array( + $this->config->rtmpdump, + '-q', + '-r', + $video->url, + '--pageUrl', $video->webpage_url + ) + ); + if (isset($video->player_url)) { + $builder->add('--swfVfy'); + $builder->add($video->player_url); + } + if (isset($video->flash_version)) { + $builder->add('--flashVer'); + $builder->add($video->flash_version); + } + if (isset($video->play_path)) { + $builder->add('--playpath'); + $builder->add($video->play_path); + } + foreach ($video->rtmp_conn as $conn) { + $builder->add('--conn'); + $builder->add($conn); + } + $chain = new Chain($builder->getProcess()); + $chain->add('|', $avconvProc); + } else { + if (!shell_exec('which curl')) { + throw(new \Exception('Can\'t find curl')); + } + $chain = new Chain( + ProcessBuilder::create( + array_merge( + array( + 'curl', + '--silent', + '--location', + '--user-agent', $video->http_headers->{'User-Agent'}, + $video->url + ), + $this->config->curl_params + ) + ) + ); + $chain->add('|', $avconvProc); + } + return popen($chain->getProcess()->getCommandLine(), 'r'); + } } diff --git a/controllers/FrontController.php b/controllers/FrontController.php index 3087529..ea9dbd5 100644 --- a/controllers/FrontController.php +++ b/controllers/FrontController.php @@ -14,8 +14,6 @@ namespace Alltube\Controller; use Alltube\VideoDownload; use Alltube\Config; -use Symfony\Component\Process\ProcessBuilder; -use Chain\Chain; use Slim\Http\Stream; use Slim\Http\Request; use Slim\Http\Response; @@ -122,96 +120,17 @@ class FrontController $url = $this->download->getURL($params["url"], 'mp3[protocol^=http]'); return $response->withRedirect($url); } catch (\Exception $e) { - $video = $this->download->getJSON($params["url"], 'bestaudio/best'); - - if (!shell_exec('which '.$this->config->avconv)) { - throw(new \Exception('Can\'t find avconv or ffmpeg')); - } - - $avconvProc = ProcessBuilder::create( - array( - $this->config->avconv, - '-v', 'quiet', - '-i', '-', - '-f', 'mp3', - '-vn', - 'pipe:1' - ) - ); - - //Vimeo needs a correct user-agent - ini_set( - 'user_agent', - $video->http_headers->{'User-Agent'} - ); $response = $response->withHeader( 'Content-Disposition', 'attachment; filename="'. - html_entity_decode( - pathinfo( - $video->_filename, - PATHINFO_FILENAME - ).'.mp3', - ENT_COMPAT, - 'ISO-8859-1' - ).'"' + $this->download->getAudioFilename($params["url"], 'bestaudio/best').'"' ); $response = $response->withHeader('Content-Type', 'audio/mpeg'); - if (parse_url($video->url, PHP_URL_SCHEME) == 'rtmp') { - if (!shell_exec('which '.$this->config->rtmpdump)) { - throw(new \Exception('Can\'t find rtmpdump')); - } - $builder = new ProcessBuilder( - array( - $this->config->rtmpdump, - '-q', - '-r', - $video->url, - '--pageUrl', $video->webpage_url - ) - ); - if (isset($video->player_url)) { - $builder->add('--swfVfy'); - $builder->add($video->player_url); - } - if (isset($video->flash_version)) { - $builder->add('--flashVer'); - $builder->add($video->flash_version); - } - if (isset($video->play_path)) { - $builder->add('--playpath'); - $builder->add($video->play_path); - } - foreach ($video->rtmp_conn as $conn) { - $builder->add('--conn'); - $builder->add($conn); - } - $chain = new Chain($builder->getProcess()); - $chain->add('|', $avconvProc); - } else { - if (!shell_exec('which curl')) { - throw(new \Exception('Can\'t find curl')); - } - $chain = new Chain( - ProcessBuilder::create( - array_merge( - array( - 'curl', - '--silent', - '--location', - '--user-agent', $video->http_headers->{'User-Agent'}, - $video->url - ), - $this->config->curl_params - ) - ) - ); - $chain->add('|', $avconvProc); - } if ($request->isGet()) { - $response = $response->withBody(new Stream(popen($chain->getProcess()->getCommandLine(), 'r'))); + $process = $this->download->getConversionProcess($params["url"], 'bestaudio/best'); + $response = $response->withBody(new Stream($process)); } return $response; } From e3cec201eebabdd51c812c4c3869b5bf15760f2c Mon Sep 17 00:00:00 2001 From: Pierre Rudloff Date: Sat, 30 Jul 2016 00:47:46 +0200 Subject: [PATCH 05/29] New tests --- classes/VideoDownload.php | 4 +- controllers/FrontController.php | 2 +- tests/ConfigTest.php | 6 +++ tests/VideoDownloadTest.php | 86 +++++++++++++++++++++++++++++++-- 4 files changed, 92 insertions(+), 6 deletions(-) diff --git a/classes/VideoDownload.php b/classes/VideoDownload.php index 67ebd9b..c252697 100644 --- a/classes/VideoDownload.php +++ b/classes/VideoDownload.php @@ -131,7 +131,7 @@ class VideoDownload if (!$process->isSuccessful()) { throw new \Exception($process->getErrorOutput()); } else { - return $process->getOutput(); + return trim($process->getOutput()); } } @@ -147,7 +147,7 @@ class VideoDownload ); } - public function getConversionProcess($url, $format) + public function getAudioStream($url, $format) { if (!shell_exec('which '.$this->config->avconv)) { throw(new \Exception('Can\'t find avconv or ffmpeg')); diff --git a/controllers/FrontController.php b/controllers/FrontController.php index ea9dbd5..f4098b8 100644 --- a/controllers/FrontController.php +++ b/controllers/FrontController.php @@ -129,7 +129,7 @@ class FrontController $response = $response->withHeader('Content-Type', 'audio/mpeg'); if ($request->isGet()) { - $process = $this->download->getConversionProcess($params["url"], 'bestaudio/best'); + $process = $this->download->getAudioStream($params["url"], 'bestaudio/best'); $response = $response->withBody(new Stream($process)); } return $response; diff --git a/tests/ConfigTest.php b/tests/ConfigTest.php index c4fde67..a103010 100644 --- a/tests/ConfigTest.php +++ b/tests/ConfigTest.php @@ -38,5 +38,11 @@ class ConfigTest extends \PHPUnit_Framework_TestCase putenv('CONVERT=1'); $config = Config::getInstance(); $this->assertEquals($config->convert, true); + $this->assertInternalType('array', $config->curl_params); + $this->assertInternalType('array', $config->params); + $this->assertInternalType('string', $config->youtubedl); + $this->assertInternalType('string', $config->python); + $this->assertInternalType('string', $config->avconv); + $this->assertInternalType('string', $config->rtmpdump); } } diff --git a/tests/VideoDownloadTest.php b/tests/VideoDownloadTest.php index ce9e9b2..4855d74 100644 --- a/tests/VideoDownloadTest.php +++ b/tests/VideoDownloadTest.php @@ -83,18 +83,22 @@ class VideoDownloadTest extends \PHPUnit_Framework_TestCase array( 'https://www.youtube.com/watch?v=M7IpKCZ47pU', null, "It's Not Me, It's You - Hearts Under Fire-M7IpKCZ47pU.mp4", - 'googlevideo.com' + 'googlevideo.com', + "It's Not Me, It's You - Hearts Under Fire-M7IpKCZ47pU.mp3" ), array( 'https://www.youtube.com/watch?v=RJJ6FCAXvKg', 22, "'Heart Attack' - Demi Lovato ". "(Sam Tsui & Against The Current)-RJJ6FCAXvKg.mp4", - 'googlevideo.com' + 'googlevideo.com', + "'Heart Attack' - Demi Lovato ". + "(Sam Tsui & Against The Current)-RJJ6FCAXvKg.mp3" ), array( 'https://vimeo.com/24195442', null, "Carving the Mountains-24195442.mp4", - 'vimeocdn.com' + 'vimeocdn.com', + "Carving the Mountains-24195442.mp3" ), ); } @@ -144,4 +148,80 @@ class VideoDownloadTest extends \PHPUnit_Framework_TestCase { $videoURL = $this->download->getJSON($url); } + + /** + * Test getFilename function + * + * @param string $url URL + * @param string $format Format + * + * @return void + * @dataProvider urlProvider + */ + public function testGetFilename($url, $format, $filename) + { + $videoFilename = $this->download->getFilename($url, $format); + $this->assertEquals($videoFilename, $filename); + } + + /** + * Test getFilename function errors + * + * @param string $url URL + * + * @return void + * @expectedException Exception + * @dataProvider ErrorUrlProvider + */ + public function testGetFilenameError($url) + { + $this->download->getFilename($url); + } + + /** + * Test getAudioFilename function + * + * @param string $url URL + * @param string $format Format + * + * @return void + * @dataProvider urlProvider + */ + public function testGetAudioFilename($url, $format, $filename, $domain, $audioFilename) + { + $videoFilename = $this->download->getAudioFilename($url, $format); + $this->assertEquals($videoFilename, $audioFilename); + } + + /** + * Test getAudioStream function + * + * @param string $url URL + * @param string $format Format + * + * @return void + * @dataProvider urlProvider + */ + public function testGetAudioStream($url, $format) + { + $process = $this->download->getAudioStream($url, $format); + $this->assertInternalType('resource', $process); + } + + /** + * Test getAudioStream function + * + * @param string $url URL + * @param string $format Format + * + * @return void + * @expectedException Exception + * @dataProvider urlProvider + */ + public function testGetAudioStreamAvconvError($url, $format) + { + $config = \Alltube\Config::getInstance(); + $config->avconv = 'foobar'; + $this->download->getAudioStream($url, $format); + } } From 782d4e124e644009f4f4e29e3392aaf527638faa Mon Sep 17 00:00:00 2001 From: Pierre Rudloff Date: Sat, 30 Jul 2016 12:40:49 +0200 Subject: [PATCH 06/29] Destroy Config instance after each test --- classes/Config.php | 5 +++++ tests/VideoDownloadTest.php | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/classes/Config.php b/classes/Config.php index c7befdf..cc13c3c 100644 --- a/classes/Config.php +++ b/classes/Config.php @@ -70,4 +70,9 @@ class Config } return self::$instance; } + + public static function destroyInstance() + { + self::$instance = null; + } } diff --git a/tests/VideoDownloadTest.php b/tests/VideoDownloadTest.php index 4855d74..bfe4e4d 100644 --- a/tests/VideoDownloadTest.php +++ b/tests/VideoDownloadTest.php @@ -32,6 +32,11 @@ class VideoDownloadTest extends \PHPUnit_Framework_TestCase $this->download = new VideoDownload(); } + protected function tearDown() + { + \Alltube\Config::destroyInstance(); + } + /** * Test listExtractors function * From ef65cb502b22667d2d85eadc74c8b68743137859 Mon Sep 17 00:00:00 2001 From: Pierre Rudloff Date: Sat, 30 Jul 2016 12:41:20 +0200 Subject: [PATCH 07/29] Lint --- controllers/FrontController.php | 1 - 1 file changed, 1 deletion(-) diff --git a/controllers/FrontController.php b/controllers/FrontController.php index f4098b8..17f28ac 100644 --- a/controllers/FrontController.php +++ b/controllers/FrontController.php @@ -120,7 +120,6 @@ class FrontController $url = $this->download->getURL($params["url"], 'mp3[protocol^=http]'); return $response->withRedirect($url); } catch (\Exception $e) { - $response = $response->withHeader( 'Content-Disposition', 'attachment; filename="'. From 37c223638d8bb8875aad0dbb33a8d9feb84fd135 Mon Sep 17 00:00:00 2001 From: Pierre Rudloff Date: Sat, 30 Jul 2016 14:01:00 +0200 Subject: [PATCH 08/29] Add rtmp tests --- classes/Config.php | 1 + classes/VideoDownload.php | 16 +++++++++----- config.example.yml | 1 + tests/VideoDownloadTest.php | 43 ++++++++++++++++++++++++++++++++++--- 4 files changed, 53 insertions(+), 8 deletions(-) diff --git a/classes/Config.php b/classes/Config.php index cc13c3c..96e5ca5 100644 --- a/classes/Config.php +++ b/classes/Config.php @@ -35,6 +35,7 @@ class Config public $convert = false; public $avconv = 'vendor/bin/ffmpeg'; public $rtmpdump = 'vendor/bin/rtmpdump'; + public $curl = '/usr/bin/curl'; public $curl_params = array(); /** diff --git a/classes/VideoDownload.php b/classes/VideoDownload.php index c252697..c22733b 100644 --- a/classes/VideoDownload.php +++ b/classes/VideoDownload.php @@ -196,21 +196,27 @@ class VideoDownload $builder->add('--playpath'); $builder->add($video->play_path); } - foreach ($video->rtmp_conn as $conn) { - $builder->add('--conn'); - $builder->add($conn); + if (isset($video->rtmp_conn)) { + foreach ($video->rtmp_conn as $conn) { + $builder->add('--conn'); + $builder->add($conn); + } + } + if (isset($video->app)) { + $builder->add('--app'); + $builder->add($video->app); } $chain = new Chain($builder->getProcess()); $chain->add('|', $avconvProc); } else { - if (!shell_exec('which curl')) { + if (!shell_exec('which '.$this->config->curl)) { throw(new \Exception('Can\'t find curl')); } $chain = new Chain( ProcessBuilder::create( array_merge( array( - 'curl', + $this->config->curl, '--silent', '--location', '--user-agent', $video->http_headers->{'User-Agent'}, diff --git a/config.example.yml b/config.example.yml index 9f66ab7..ca03f0b 100644 --- a/config.example.yml +++ b/config.example.yml @@ -10,3 +10,4 @@ curl_params: convert: false avconv: vendor/bin/ffmpeg rtmpdump: vendor/bin/rtmpdump +curl: /usr/bin/curl diff --git a/tests/VideoDownloadTest.php b/tests/VideoDownloadTest.php index bfe4e4d..7faada5 100644 --- a/tests/VideoDownloadTest.php +++ b/tests/VideoDownloadTest.php @@ -105,6 +105,24 @@ class VideoDownloadTest extends \PHPUnit_Framework_TestCase 'vimeocdn.com', "Carving the Mountains-24195442.mp3" ), + array( + 'http://www.bbc.co.uk/programmes/b039g8p7', 'bestaudio/best', + "Leonard Cohen, Kaleidoscope - BBC Radio 4-b039d07m.flv", + 'bbcodspdns.fcod.llnwd.net', + "Leonard Cohen, Kaleidoscope - BBC Radio 4-b039d07m.mp3" + ), + array( + 'http://www.arte.tv/guide/de/sendungen/XEN/xenius/?vid=055918-015_PLUS7-D', 'RTMP_MQ_1', + "Xenius-063945-044-A.flv", + 'edgefcs.net', + "Xenius-063945-044-A.mp3" + ), + array( + 'http://www.rtl2.de/sendung/grip-das-motormagazin/folge/folge-203-0', 'bestaudio/best', + "GRIP sucht den Sommerkönig-folge-203-0.f4v", + 'edgefcs.net', + "GRIP sucht den Sommerkönig-folge-203-0.mp3" + ) ); } @@ -209,12 +227,13 @@ class VideoDownloadTest extends \PHPUnit_Framework_TestCase */ public function testGetAudioStream($url, $format) { - $process = $this->download->getAudioStream($url, $format); - $this->assertInternalType('resource', $process); + $stream = $this->download->getAudioStream($url, $format); + $this->assertInternalType('resource', $stream); + $this->assertNotEmpty(fread($stream, 100)); } /** - * Test getAudioStream function + * Test getAudioStream function without avconv * * @param string $url URL * @param string $format Format @@ -229,4 +248,22 @@ class VideoDownloadTest extends \PHPUnit_Framework_TestCase $config->avconv = 'foobar'; $this->download->getAudioStream($url, $format); } + + /** + * Test getAudioStream function without curl or rtmpdump + * + * @param string $url URL + * @param string $format Format + * + * @return void + * @expectedException Exception + * @dataProvider urlProvider + */ + public function testGetAudioStreamCurlError($url, $format) + { + $config = \Alltube\Config::getInstance(); + $config->curl = 'foobar'; + $config->rtmpdump = 'foobar'; + $this->download->getAudioStream($url, $format); + } } From fc73459731969c52d808080a9dd607902e35eb34 Mon Sep 17 00:00:00 2001 From: Pierre Rudloff Date: Mon, 1 Aug 2016 01:01:10 +0200 Subject: [PATCH 09/29] Use template includes --- controllers/FrontController.php | 50 ++++++--------------------------- templates/error.tpl | 6 ++-- templates/extractors.tpl | 6 +++- templates/{ => inc}/footer.tpl | 0 templates/{ => inc}/head.tpl | 0 templates/{ => inc}/header.tpl | 0 templates/{ => inc}/logo.tpl | 0 templates/index.tpl | 5 +++- templates/video.tpl | 4 ++- 9 files changed, 24 insertions(+), 47 deletions(-) rename templates/{ => inc}/footer.tpl (100%) rename templates/{ => inc}/head.tpl (100%) rename templates/{ => inc}/header.tpl (100%) rename templates/{ => inc}/logo.tpl (100%) diff --git a/controllers/FrontController.php b/controllers/FrontController.php index 17f28ac..cbedd12 100644 --- a/controllers/FrontController.php +++ b/controllers/FrontController.php @@ -50,24 +50,13 @@ class FrontController { $this->container->view->render( $response, - 'head.tpl', + 'index.tpl', array( + 'convert'=>$this->config->convert, 'class'=>'index', 'description'=>'Easily download videos from Youtube, Dailymotion, Vimeo and other websites.' ) ); - $this->container->view->render( - $response, - 'header.tpl' - ); - $this->container->view->render( - $response, - 'index.tpl', - array( - 'convert'=>$this->config->convert - ) - ); - $this->container->view->render($response, 'footer.tpl'); } /** @@ -82,24 +71,15 @@ class FrontController { $this->container->view->render( $response, - 'head.tpl', + 'extractors.tpl', array( + 'extractors'=>$this->download->listExtractors(), 'class'=>'extractors', 'title'=>'Supported websites', 'description' =>'List of all supported websites from which Alltube Download can extract video or audio files' ) ); - $this->container->view->render($response, 'header.tpl'); - $this->container->view->render($response, 'logo.tpl'); - $this->container->view->render( - $response, - 'extractors.tpl', - array( - 'extractors'=>$this->download->listExtractors() - ) - ); - $this->container->view->render($response, 'footer.tpl'); } /** @@ -137,21 +117,14 @@ class FrontController $video = $this->download->getJSON($params["url"]); $this->container->view->render( $response, - 'head.tpl', + 'video.tpl', array( + 'video'=>$video, 'class'=>'video', 'title'=>$video->title, 'description'=>'Download "'.$video->title.'" from '.$video->extractor_key ) ); - $this->container->view->render( - $response, - 'video.tpl', - array( - 'video'=>$video - ) - ); - $this->container->view->render($response, 'footer.tpl'); } } else { return $response->withRedirect($this->container->get('router')->pathFor('index')); @@ -162,20 +135,13 @@ class FrontController { $this->container->view->render( $response, - 'head.tpl', + 'error.tpl', array( + 'errors'=>$exception->getMessage(), 'class'=>'video', 'title'=>'Error' ) ); - $this->container->view->render( - $response, - 'error.tpl', - array( - 'errors'=>$exception->getMessage() - ) - ); - $this->container->view->render($response, 'footer.tpl'); return $response->withStatus(500); } diff --git a/templates/error.tpl b/templates/error.tpl index d000ab3..67a0fae 100644 --- a/templates/error.tpl +++ b/templates/error.tpl @@ -1,6 +1,7 @@ +{include file='inc/head.tpl'}
- {include file="logo.tpl"} + {include file="inc/logo.tpl"}

An error occured

Please check the URL of your video.

@@ -9,4 +10,5 @@
{/foreach}

-
+
+{include file='inc/footer.tpl'} diff --git a/templates/extractors.tpl b/templates/extractors.tpl index 076f99e..4944193 100644 --- a/templates/extractors.tpl +++ b/templates/extractors.tpl @@ -1,8 +1,12 @@ +{include file='inc/head.tpl'} +{include file='inc/header.tpl'} +{include file='inc/logo.tpl'}

Supported websites

-
    +
      {foreach $extractors as $extractor}
    • {$extractor}
    • {/foreach}
+{include file='inc/footer.tpl'} diff --git a/templates/footer.tpl b/templates/inc/footer.tpl similarity index 100% rename from templates/footer.tpl rename to templates/inc/footer.tpl diff --git a/templates/head.tpl b/templates/inc/head.tpl similarity index 100% rename from templates/head.tpl rename to templates/inc/head.tpl diff --git a/templates/header.tpl b/templates/inc/header.tpl similarity index 100% rename from templates/header.tpl rename to templates/inc/header.tpl diff --git a/templates/logo.tpl b/templates/inc/logo.tpl similarity index 100% rename from templates/logo.tpl rename to templates/inc/logo.tpl diff --git a/templates/index.tpl b/templates/index.tpl index 5d046e6..93f44eb 100644 --- a/templates/index.tpl +++ b/templates/index.tpl @@ -1,4 +1,6 @@ -
+{include file='inc/head.tpl'} +{include file='inc/header.tpl'} +
@@ -27,3 +29,4 @@
+{include file='inc/footer.tpl'} diff --git a/templates/video.tpl b/templates/video.tpl index daaf3cc..e3790b1 100644 --- a/templates/video.tpl +++ b/templates/video.tpl @@ -1,7 +1,8 @@ +{include file="inc/head.tpl"}
-{include file="logo.tpl"} +{include file="inc/logo.tpl"}

You are going to download