diff --git a/.htaccess b/.htaccess index 7cac6a1..eba3ddb 100644 --- a/.htaccess +++ b/.htaccess @@ -34,5 +34,5 @@ FileETag None Header set X-Content-Type-Options nosniff Header set X-XSS-Protection "1; mode=block" Header set Referrer-Policy no-referrer - Header set Content-Security-Policy "default-src 'self'; object-src 'none'; script-src 'none'; img-src http:" + Header set Content-Security-Policy "default-src 'self'; object-src 'none'; script-src 'none'; style-src 'self' 'unsafe-inline'; img-src http:" diff --git a/Gruntfile.js b/Gruntfile.js index b198735..1238148 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -101,7 +101,7 @@ module.exports = function (grunt) { 'i18n/es_ES/LC_MESSAGES/Alltube.mo': 'i18n/es_ES/LC_MESSAGES/Alltube.po', 'i18n/de_DE/LC_MESSAGES/Alltube.mo': 'i18n/de_DE/LC_MESSAGES/Alltube.po', 'i18n/pt_BR/LC_MESSAGES/Alltube.mo': 'i18n/pt_BR/LC_MESSAGES/Alltube.po', - 'i18n/ar_001/LC_MESSAGES/Alltube.mo': 'i18n/ar_001/LC_MESSAGES/Alltube.po' + 'i18n/ar/LC_MESSAGES/Alltube.mo': 'i18n/ar/LC_MESSAGES/Alltube.po' } } }, diff --git a/app.json b/app.json index 848962c..edc1929 100644 --- a/app.json +++ b/app.json @@ -17,14 +17,14 @@ { "url": "https://github.com/piotras/heroku-buildpack-gettext.git" }, + { + "url": "heroku/php" + }, { "url": "heroku/nodejs" }, { "url": "heroku/python" - }, - { - "url": "heroku/php" } ], "env": { diff --git a/classes/Config.php b/classes/Config.php index ea98a85..e4454dc 100644 --- a/classes/Config.php +++ b/classes/Config.php @@ -8,6 +8,7 @@ namespace Alltube; use Exception; use Symfony\Component\Yaml\Yaml; +use Jawira\CaseConverter\Convert; /** * Manage config parameters. @@ -134,6 +135,13 @@ class Config */ public $genericFormats = []; + /** + * Enable debug mode. + * + * @var bool + */ + public $debug = false; + /** * Config constructor. * @@ -222,17 +230,18 @@ class Config /** * Override options from environement variables. - * Supported environment variables: CONVERT, PYTHON, AUDIO_BITRATE. + * Environment variables should use screaming snake case: CONVERT, PYTHON, AUDIO_BITRATE, etc. + * If the value is an array, you should use the YAML format: "CONVERT_ADVANCED_FORMATS='[foo, bar]'" * * @return void */ private function getEnv() { - foreach (['CONVERT', 'PYTHON', 'AUDIO_BITRATE', 'STREAM'] as $var) { - $env = getenv($var); + foreach (get_object_vars($this) as $prop => $value) { + $convert = new Convert($prop); + $env = getenv($convert->toSnake(true)); if ($env) { - $prop = lcfirst(str_replace('_', '', ucwords(strtolower($var), '_'))); - $this->$prop = $env; + $this->$prop = Yaml::parse($env); } } } diff --git a/classes/Locale.php b/classes/Locale.php index 6418df7..50e9055 100644 --- a/classes/Locale.php +++ b/classes/Locale.php @@ -38,7 +38,9 @@ class Locale { $parse = AcceptLanguage::parse($locale); $this->language = $parse[1]['language']; - $this->region = $parse[1]['region']; + if (!empty($parse[1]['region'])) { + $this->region = $parse[1]['region']; + } } /** @@ -68,7 +70,11 @@ class Locale */ public function getIso15897() { - return $this->language . '_' . $this->region; + if (isset($this->region)) { + return $this->language . '_' . $this->region; + } else { + return $this->language; + } } /** @@ -78,7 +84,11 @@ class Locale */ public function getBcp47() { - return $this->language . '-' . $this->region; + if (isset($this->region)) { + return $this->language . '-' . $this->region; + } else { + return $this->language; + } } /** @@ -98,6 +108,8 @@ class Locale */ public function getCountry() { - return country($this->getIso3166()); + if (isset($this->region)) { + return country($this->getIso3166()); + } } } diff --git a/classes/LocaleManager.php b/classes/LocaleManager.php index 81ed684..2f42d3a 100644 --- a/classes/LocaleManager.php +++ b/classes/LocaleManager.php @@ -8,6 +8,8 @@ namespace Alltube; use Aura\Session\Segment; use Symfony\Component\Process\Process; +use Symfony\Component\Translation\Translator; +use Symfony\Component\Translation\Loader\MoFileLoader; /** * Class used to manage locales. @@ -19,7 +21,7 @@ class LocaleManager * * @var array */ - private $supportedLocales = ['en_US', 'fr_FR', 'zh_CN', 'es_ES', 'pt_BR', 'de_DE', 'ar_001']; + private $supportedLocales = ['en_US', 'fr_FR', 'zh_CN', 'es_ES', 'pt_BR', 'de_DE', 'ar']; /** * Current locale. @@ -35,19 +37,49 @@ class LocaleManager */ private $sessionSegment; + /** + * Default locale. + * + * @var string + */ + private const DEFAULT_LOCALE = 'en'; + + /** + * Symfony Translator instance. + * + * @var Translator + */ + private $translator; + + /** + * Singleton instance. + * + * @var LocaleManager|null + */ + private static $instance; + /** * LocaleManager constructor. */ - public function __construct() + private function __construct() { $session = SessionManager::getSession(); $this->sessionSegment = $session->getSegment(self::class); $cookieLocale = $this->sessionSegment->get('locale'); + + $this->translator = new Translator(self::DEFAULT_LOCALE); if (isset($cookieLocale)) { $this->setLocale(new Locale($cookieLocale)); } - bindtextdomain('Alltube', __DIR__ . '/../i18n/'); - textdomain('Alltube'); + + $this->translator->addLoader('gettext', new MoFileLoader()); + foreach ($this->getSupportedLocales() as $locale) { + $this->translator->addResource( + 'gettext', + __DIR__ . '/../i18n/' . $locale->getIso15897() . '/LC_MESSAGES/Alltube.mo', + $locale->getIso15897() + ); + } } /** @@ -58,16 +90,9 @@ class LocaleManager public function getSupportedLocales() { $return = []; - $process = new Process(['locale', '-a']); - $process->run(); - $installedLocales = explode(PHP_EOL, trim($process->getOutput())); + foreach ($this->supportedLocales as $supportedLocale) { - if ( - in_array($supportedLocale, $installedLocales) - || in_array($supportedLocale . '.utf8', $installedLocales) - ) { - $return[] = new Locale($supportedLocale); - } + $return[] = new Locale($supportedLocale); } return $return; @@ -90,8 +115,7 @@ class LocaleManager */ public function setLocale(Locale $locale) { - putenv('LANG=' . $locale); - setlocale(LC_ALL, [$locale . '.utf8', $locale]); + $this->translator->setLocale($locale->getIso15897()); $this->curLocale = $locale; $this->sessionSegment->set('locale', $locale); } @@ -101,7 +125,61 @@ class LocaleManager */ public function unsetLocale() { + $this->translator->setLocale(self::DEFAULT_LOCALE); $this->curLocale = null; $this->sessionSegment->clear(); } + + /** + * Smarty "t" block. + * + * @param array $params Block parameters + * @param string $text Block content + * + * @return string Translated string + */ + public function smartyTranslate(array $params, $text) + { + if (isset($params['params'])) { + return $this->t($text, $params['params']); + } else { + return $this->t($text); + } + } + + /** + * Translate a string. + * + * @param string $string String to translate + * + * @return string Translated string + */ + public function t($string, array $params = []) + { + return $this->translator->trans($string, $params); + } + + /** + * Get LocaleManager singleton instance. + * + * @return LocaleManager + */ + public static function getInstance() + { + if (!isset(self::$instance)) { + self::$instance = new self(); + } + + return self::$instance; + } + + /** + * Destroy singleton instance. + * + * @return void + */ + public static function destroyInstance() + { + self::$instance = null; + } } diff --git a/classes/Video.php b/classes/Video.php index f368385..a50983f 100644 --- a/classes/Video.php +++ b/classes/Video.php @@ -74,6 +74,13 @@ class Video */ private $urls; + /** + * LocaleManager instance. + * + * @var LocaleManager + */ + protected $localeManager; + /** * VideoDownload constructor. * @@ -87,6 +94,8 @@ class Video $this->requestedFormat = $requestedFormat; $this->password = $password; $this->config = Config::getInstance(); + + $this->localeManager = LocaleManager::getInstance(); } /** @@ -116,7 +125,9 @@ class Video * */ public static function getExtractors() { - return explode("\n", trim(self::callYoutubedl(['--list-extractors']))); + $video = new self(''); + + return explode("\n", trim($video->callYoutubedl(['--list-extractors']))); } /** @@ -130,7 +141,7 @@ class Video * * @return string Result */ - private static function callYoutubedl(array $arguments) + private function callYoutubedl(array $arguments) { $config = Config::getInstance(); @@ -145,7 +156,7 @@ class Video if ($errorOutput == 'ERROR: This video is protected by a password, use the --video-password option') { throw new PasswordException($errorOutput, $exitCode); } elseif (substr($errorOutput, 0, 21) == 'ERROR: Wrong password') { - throw new Exception(_('Wrong password'), $exitCode); + throw new Exception($this->localeManager->t('Wrong password'), $exitCode); } else { throw new Exception($errorOutput, $exitCode); } @@ -177,7 +188,7 @@ class Video $arguments[] = $this->password; } - return $this::callYoutubedl($arguments); + return $this->callYoutubedl($arguments); } /** @@ -236,7 +247,7 @@ class Video $this->urls = explode("\n", $this->getProp('get-url')); if (empty($this->urls[0])) { - throw new EmptyUrlException(_('youtube-dl returned an empty URL.')); + throw new EmptyUrlException($this->localeManager->t('youtube-dl returned an empty URL.')); } } @@ -345,7 +356,12 @@ class Video $to = null ) { if (!$this->checkCommand([$this->config->avconv, '-version'])) { - throw new Exception(_('Can\'t find avconv or ffmpeg at ') . $this->config->avconv . '.'); + throw new Exception( + $this->localeManager->t( + "Can't find avconv or ffmpeg at @path.", + ['@path' => $this->config->avconv] + ) + ); } $durationRegex = '/(\d+:)?(\d+:)?(\d+)/'; @@ -358,14 +374,14 @@ class Video if (!empty($from)) { if (!preg_match($durationRegex, $from)) { - throw new Exception(_('Invalid start time: ') . $from . '.'); + throw new Exception($this->localeManager->t('Invalid start time: @from.', ['@from' => $from])); } $afterArguments[] = '-ss'; $afterArguments[] = $from; } if (!empty($to)) { if (!preg_match($durationRegex, $to)) { - throw new Exception(_('Invalid end time: ') . $to . '.'); + throw new Exception($this->localeManager->t('Invalid end time: @to.', ['@to' => $to])); } $afterArguments[] = '-to'; $afterArguments[] = $to; @@ -411,14 +427,14 @@ class Video public function getAudioStream($from = null, $to = null) { if (isset($this->_type) && $this->_type == 'playlist') { - throw new Exception(_('Conversion of playlists is not supported.')); + throw new Exception($this->localeManager->t('Conversion of playlists is not supported.')); } if (isset($this->protocol)) { if (in_array($this->protocol, ['m3u8', 'm3u8_native'])) { - throw new Exception(_('Conversion of M3U8 files is not supported.')); + throw new Exception($this->localeManager->t('Conversion of M3U8 files is not supported.')); } elseif ($this->protocol == 'http_dash_segments') { - throw new Exception(_('Conversion of DASH segments is not supported.')); + throw new Exception($this->localeManager->t('Conversion of DASH segments is not supported.')); } } @@ -427,7 +443,7 @@ class Video $stream = popen($avconvProc->getCommandLine(), 'r'); if (!is_resource($stream)) { - throw new Exception(_('Could not open popen stream.')); + throw new Exception($this->localeManager->t('Could not open popen stream.')); } return $stream; @@ -444,7 +460,12 @@ class Video public function getM3uStream() { if (!$this->checkCommand([$this->config->avconv, '-version'])) { - throw new Exception(_('Can\'t find avconv or ffmpeg at ') . $this->config->avconv . '.'); + throw new Exception( + $this->localeManager->t( + "Can't find avconv or ffmpeg at @path.", + ['@path' => $this->config->avconv] + ) + ); } $urls = $this->getUrl(); @@ -464,7 +485,7 @@ class Video $stream = popen($process->getCommandLine(), 'r'); if (!is_resource($stream)) { - throw new Exception(_('Could not open popen stream.')); + throw new Exception($this->localeManager->t('Could not open popen stream.')); } return $stream; @@ -482,7 +503,7 @@ class Video $urls = $this->getUrl(); if (!isset($urls[0]) || !isset($urls[1])) { - throw new Exception(_('This video does not have two URLs.')); + throw new Exception($this->localeManager->t('This video does not have two URLs.')); } $process = new Process( @@ -501,7 +522,7 @@ class Video $stream = popen($process->getCommandLine(), 'r'); if (!is_resource($stream)) { - throw new Exception(_('Could not open popen stream.')); + throw new Exception($this->localeManager->t('Could not open popen stream.')); } return $stream; @@ -534,7 +555,7 @@ class Video ); $stream = popen($process->getCommandLine(), 'r'); if (!is_resource($stream)) { - throw new Exception(_('Could not open popen stream.')); + throw new Exception($this->localeManager->t('Could not open popen stream.')); } return $stream; @@ -554,7 +575,7 @@ class Video public function getConvertedStream($audioBitrate, $filetype) { if (in_array($this->protocol, ['m3u8', 'm3u8_native'])) { - throw new Exception(_('Conversion of M3U8 files is not supported.')); + throw new Exception($this->localeManager->t('Conversion of M3U8 files is not supported.')); } $avconvProc = $this->getAvconvProcess($audioBitrate, $filetype, false); @@ -562,7 +583,7 @@ class Video $stream = popen($avconvProc->getCommandLine(), 'r'); if (!is_resource($stream)) { - throw new Exception(_('Could not open popen stream.')); + throw new Exception($this->localeManager->t('Could not open popen stream.')); } return $stream; @@ -592,6 +613,13 @@ class Video $client = new Client(); $urls = $this->getUrl(); - return $client->request('GET', $urls[0], ['stream' => true, 'headers' => $headers]); + return $client->request( + 'GET', + $urls[0], + [ + 'stream' => true, + 'headers' => array_merge((array) $this->http_headers, $headers) + ] + ); } } diff --git a/classes/ViewFactory.php b/classes/ViewFactory.php index a78efd7..835b471 100644 --- a/classes/ViewFactory.php +++ b/classes/ViewFactory.php @@ -35,9 +35,12 @@ class ViewFactory $request = $request->withUri($request->getUri()->withScheme('https')->withPort(443)); } + $localeManager = $container['locale']; + $smartyPlugins = new SmartyPlugins($container['router'], $request->getUri()->withUserInfo(null)); $view->registerPlugin('function', 'path_for', [$smartyPlugins, 'pathFor']); $view->registerPlugin('function', 'base_url', [$smartyPlugins, 'baseUrl']); + $view->registerPlugin('block', 't', [$localeManager, 'smartyTranslate']); return $view; } diff --git a/composer.json b/composer.json index 5d2c0fc..c7065b3 100644 --- a/composer.json +++ b/composer.json @@ -12,11 +12,12 @@ "guzzlehttp/guzzle": "~6.3.0", "aura/session": "~2.1.0", "barracudanetworks/archivestream-php": "~1.0.5", - "smarty-gettext/smarty-gettext": "~1.6.0", "zonuexe/http-accept-language": "~0.4.1", "rinvex/countries": "~3.1.0", "php-mock/php-mock-mockery": "~1.3.0", - "ext-xsl": "*" + "ext-xsl": "*", + "jawira/case-converter": "^1.2", + "symfony/translation": "^3.4" }, "require-dev": { "symfony/var-dumper": "~3.4.1", @@ -27,7 +28,8 @@ "heroku/heroku-buildpack-php": "^162.0", "anam/phantomjs-linux-x86-binary": "~2.1.1", "phpstan/phpstan": "~0.9.2", - "roave/security-advisories": "dev-master" + "roave/security-advisories": "dev-master", + "smarty-gettext/smarty-gettext": "^1.6" }, "extra": { "paas": { @@ -90,7 +92,7 @@ "compile": "composer install --ignore-platform-reqs", "update-locales": [ "tsmarty2c.php templates > i18n/template.pot", - "xgettext --omit-header -j -o i18n/template.pot classes/* controllers/*" + "xgettext --omit-header -kt -j -o i18n/template.pot classes/*.php classes/*/*.php controllers/*" ], "youtube-dl": "vendor/rg3/youtube-dl/youtube_dl/__main__.py" }, diff --git a/composer.lock b/composer.lock index 2b960a4..0cdbc1b 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "07b922cb69b4f4dbd5e537656d559c8d", + "content-hash": "c773a24c670cb4c431217ea94f03b942", "packages": [ { "name": "aura/session", @@ -137,6 +137,7 @@ ], "description": "Promoting the interoperability of container objects (DIC, SL, etc.)", "homepage": "https://github.com/container-interop/container-interop", + "abandoned": "psr/container", "time": "2017-02-14T19:40:03+00:00" }, { @@ -374,6 +375,50 @@ ], "time": "2016-01-20T08:20:44+00:00" }, + { + "name": "jawira/case-converter", + "version": "v1.2.0", + "source": { + "type": "git", + "url": "https://github.com/jawira/case-converter.git", + "reference": "79716629a298e44507a8eed9b997968f39367abc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/jawira/case-converter/zipball/79716629a298e44507a8eed9b997968f39367abc", + "reference": "79716629a298e44507a8eed9b997968f39367abc", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": ">=5.4" + }, + "suggest": { + "pds/skeleton": "PHP Package Development Standards" + }, + "type": "library", + "autoload": { + "psr-4": { + "Jawira\\CaseConverter\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jawira Portugal" + } + ], + "description": "Convert string between **Camel Case** ?, **Snake Case** ?and **Kebab Case** ?.", + "keywords": [ + "camel case", + "kebab case", + "snake case" + ], + "time": "2019-03-18T05:59:08+00:00" + }, { "name": "mathmarques/smarty-view", "version": "1.1.2", @@ -1078,61 +1123,6 @@ ], "time": "2019-04-16T16:47:29+00:00" }, - { - "name": "smarty-gettext/smarty-gettext", - "version": "1.6.1", - "source": { - "type": "git", - "url": "https://github.com/smarty-gettext/smarty-gettext.git", - "reference": "9a7d9284b5374caeae5eb226cf486efb4bc748b4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/smarty-gettext/smarty-gettext/zipball/9a7d9284b5374caeae5eb226cf486efb4bc748b4", - "reference": "9a7d9284b5374caeae5eb226cf486efb4bc748b4", - "shasum": "" - }, - "require": { - "ext-gettext": "*", - "ext-pcre": "*", - "php": "~5.3|~7.0" - }, - "require-dev": { - "azatoth/php-pgettext": "~1.0", - "phpunit/phpunit": ">=4.8.36", - "smarty/smarty": "3.1.*" - }, - "suggest": { - "azatoth/php-pgettext": "Support msgctxt for {t} via context parameter" - }, - "bin": [ - "tsmarty2c.php" - ], - "type": "library", - "autoload": { - "files": [ - "block.t.php", - "function.locale.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-2.1" - ], - "authors": [ - { - "name": "Sagi Bashari", - "email": "sagi@boom.org.il" - }, - { - "name": "Elan Ruusamäe", - "email": "glen@delfi.ee" - } - ], - "description": "Gettext plugin enabling internationalization in Smarty Package files", - "homepage": "https://github.com/smarty-gettext/smarty-gettext", - "time": "2019-01-17T23:06:53+00:00" - }, { "name": "smarty/smarty", "version": "v3.1.33", @@ -1244,6 +1234,65 @@ ], "time": "2019-02-06T07:57:58+00:00" }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.11.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "fe5e94c604826c35a32fa832f35bd036b6799609" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/fe5e94c604826c35a32fa832f35bd036b6799609", + "reference": "fe5e94c604826c35a32fa832f35bd036b6799609", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.11-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "time": "2019-02-06T07:57:58+00:00" + }, { "name": "symfony/process", "version": "v3.4.29", @@ -1293,6 +1342,76 @@ "homepage": "https://symfony.com", "time": "2019-05-30T15:47:52+00:00" }, + { + "name": "symfony/translation", + "version": "v3.4.35", + "source": { + "type": "git", + "url": "https://github.com/symfony/translation.git", + "reference": "2031c895bc97ac1787d418d90bd1ed7d299f2772" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/translation/zipball/2031c895bc97ac1787d418d90bd1ed7d299f2772", + "reference": "2031c895bc97ac1787d418d90bd1ed7d299f2772", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/config": "<2.8", + "symfony/dependency-injection": "<3.4", + "symfony/yaml": "<3.4" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "~2.8|~3.0|~4.0", + "symfony/dependency-injection": "~3.4|~4.0", + "symfony/finder": "~2.8|~3.0|~4.0", + "symfony/http-kernel": "~3.4|~4.0", + "symfony/intl": "^2.8.18|^3.2.5|~4.0", + "symfony/var-dumper": "~3.4|~4.0", + "symfony/yaml": "~3.4|~4.0" + }, + "suggest": { + "psr/log-implementation": "To use logging capability in translator", + "symfony/config": "", + "symfony/yaml": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Translation\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Translation Component", + "homepage": "https://symfony.com", + "time": "2019-10-30T12:43:22+00:00" + }, { "name": "symfony/yaml", "version": "v3.4.29", @@ -3829,6 +3948,61 @@ "homepage": "https://github.com/sebastianbergmann/version", "time": "2016-10-03T07:35:21+00:00" }, + { + "name": "smarty-gettext/smarty-gettext", + "version": "1.6.1", + "source": { + "type": "git", + "url": "https://github.com/smarty-gettext/smarty-gettext.git", + "reference": "9a7d9284b5374caeae5eb226cf486efb4bc748b4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/smarty-gettext/smarty-gettext/zipball/9a7d9284b5374caeae5eb226cf486efb4bc748b4", + "reference": "9a7d9284b5374caeae5eb226cf486efb4bc748b4", + "shasum": "" + }, + "require": { + "ext-gettext": "*", + "ext-pcre": "*", + "php": "~5.3|~7.0" + }, + "require-dev": { + "azatoth/php-pgettext": "~1.0", + "phpunit/phpunit": ">=4.8.36", + "smarty/smarty": "3.1.*" + }, + "suggest": { + "azatoth/php-pgettext": "Support msgctxt for {t} via context parameter" + }, + "bin": [ + "tsmarty2c.php" + ], + "type": "library", + "autoload": { + "files": [ + "block.t.php", + "function.locale.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-2.1" + ], + "authors": [ + { + "name": "Sagi Bashari", + "email": "sagi@boom.org.il" + }, + { + "name": "Elan Ruusamäe", + "email": "glen@delfi.ee" + } + ], + "description": "Gettext plugin enabling internationalization in Smarty Package files", + "homepage": "https://github.com/smarty-gettext/smarty-gettext", + "time": "2019-01-17T23:06:53+00:00" + }, { "name": "squizlabs/php_codesniffer", "version": "3.5.0", @@ -4057,65 +4231,6 @@ "homepage": "https://symfony.com", "time": "2019-05-30T15:47:52+00:00" }, - { - "name": "symfony/polyfill-mbstring", - "version": "v1.11.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "fe5e94c604826c35a32fa832f35bd036b6799609" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/fe5e94c604826c35a32fa832f35bd036b6799609", - "reference": "fe5e94c604826c35a32fa832f35bd036b6799609", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "suggest": { - "ext-mbstring": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.11-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" - }, - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for the Mbstring extension", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "mbstring", - "polyfill", - "portable", - "shim" - ], - "time": "2019-02-06T07:57:58+00:00" - }, { "name": "symfony/var-dumper", "version": "v3.4.29", diff --git a/config/config.example.yml b/config/config.example.yml index 3cd1fe0..022e612 100644 --- a/config/config.example.yml +++ b/config/config.example.yml @@ -51,3 +51,6 @@ genericFormats: best: Best bestvideo+bestaudio: Remux best video with best audio worst: Worst + +# Enable debug mode. +debug: false diff --git a/controllers/BaseController.php b/controllers/BaseController.php index e555a6f..59e9862 100644 --- a/controllers/BaseController.php +++ b/controllers/BaseController.php @@ -7,6 +7,7 @@ namespace Alltube\Controller; use Alltube\Config; +use Alltube\LocaleManager; use Alltube\SessionManager; use Alltube\Video; use Aura\Session\Segment; @@ -53,6 +54,13 @@ abstract class BaseController */ protected $sessionSegment; + /** + * LocaleManager instance. + * + * @var LocaleManager + */ + protected $localeManager; + /** * BaseController constructor. * @@ -64,6 +72,7 @@ abstract class BaseController $this->container = $container; $session = SessionManager::getSession(); $this->sessionSegment = $session->getSegment(self::class); + $this->localeManager = $this->container->get('locale'); if ($this->config->stream) { $this->defaultFormat = 'best'; diff --git a/controllers/DownloadController.php b/controllers/DownloadController.php index b3f3f3c..7862b6c 100644 --- a/controllers/DownloadController.php +++ b/controllers/DownloadController.php @@ -166,7 +166,7 @@ class DownloadController extends BaseController $response = $response->withHeader('Content-Type', 'video/' . $this->video->ext); $body = new Stream($this->video->getM3uStream()); } else { - $headers = (array) $this->video->http_headers; + $headers = []; $range = $request->getHeader('Range'); if (!empty($range)) { @@ -212,7 +212,7 @@ class DownloadController extends BaseController private function getRemuxStream(Request $request, Response $response) { if (!$this->config->remux) { - throw new Exception(_('You need to enable remux mode to merge two formats.')); + throw new Exception($this->localeManager->t('You need to enable remux mode to merge two formats.')); } $stream = $this->video->getRemuxStream(); $response = $response->withHeader('Content-Type', 'video/x-matroska'); @@ -222,7 +222,7 @@ class DownloadController extends BaseController return $response->withHeader( 'Content-Disposition', - 'attachment; filename="' . $this->video->getFileNameWithExtension('mkv') + 'attachment; filename="' . $this->video->getFileNameWithExtension('mkv') . '"' ); } @@ -252,7 +252,7 @@ class DownloadController extends BaseController return $this->getStream($request, $response); } else { if (empty($videoUrls[0])) { - throw new Exception(_("Can't find URL of video.")); + throw new Exception($this->localeManager->t("Can't find URL of video.")); } return $response->withRedirect($videoUrls[0]); diff --git a/controllers/FrontController.php b/controllers/FrontController.php index 733bbd5..a56af7e 100644 --- a/controllers/FrontController.php +++ b/controllers/FrontController.php @@ -8,14 +8,16 @@ namespace Alltube\Controller; use Alltube\Exception\PasswordException; use Alltube\Locale; -use Alltube\LocaleManager; use Alltube\Video; +use Throwable; use Exception; use Psr\Container\ContainerInterface; use Slim\Container; use Slim\Http\Request; use Slim\Http\Response; use Slim\Views\Smarty; +use Symfony\Component\Debug\ExceptionHandler; +use Symfony\Component\Debug\Exception\FatalThrowableError; /** * Main controller. @@ -29,13 +31,6 @@ class FrontController extends BaseController */ private $view; - /** - * LocaleManager instance. - * - * @var LocaleManager - */ - private $localeManager; - /** * BaseController constructor. * @@ -45,7 +40,6 @@ class FrontController extends BaseController { parent::__construct($container); - $this->localeManager = $this->container->get('locale'); $this->view = $this->container->get('view'); } @@ -66,7 +60,9 @@ class FrontController extends BaseController [ 'config' => $this->config, 'class' => 'index', - 'description' => _('Easily download videos from Youtube, Dailymotion, Vimeo and other websites.'), + 'description' => $this->localeManager->t( + 'Easily download videos from Youtube, Dailymotion, Vimeo and other websites.' + ), 'domain' => $uri->getScheme() . '://' . $uri->getAuthority(), 'canonical' => $this->getCanonicalUrl($request), 'supportedLocales' => $this->localeManager->getSupportedLocales(), @@ -110,8 +106,8 @@ class FrontController extends BaseController 'config' => $this->config, 'extractors' => Video::getExtractors(), 'class' => 'extractors', - 'title' => _('Supported websites'), - 'description' => _('List of all supported websites from which Alltube Download ' . + 'title' => $this->localeManager->t('Supported websites'), + 'description' => $this->localeManager->t('List of all supported websites from which Alltube Download ' . 'can extract video or audio files'), 'canonical' => $this->getCanonicalUrl($request), 'locale' => $this->localeManager->getLocale(), @@ -137,8 +133,10 @@ class FrontController extends BaseController [ 'config' => $this->config, 'class' => 'password', - 'title' => _('Password prompt'), - 'description' => _('You need a password in order to download this video with Alltube Download'), + 'title' => $this->localeManager->t('Password prompt'), + 'description' => $this->localeManager->t( + 'You need a password in order to download this video with Alltube Download' + ), 'canonical' => $this->getCanonicalUrl($request), 'locale' => $this->localeManager->getLocale(), ] @@ -168,12 +166,20 @@ class FrontController extends BaseController } else { $template = 'info.tpl'; } - $title = _('Video download'); - $description = _('Download video from ') . $this->video->extractor_key; + $title = $this->localeManager->t('Video download'); + $description = $this->localeManager->t( + 'Download video from @extractor', + ['@extractor' => $this->video->extractor_key] + ); if (isset($this->video->title)) { $title = $this->video->title; - $description = _('Download') . ' "' . $this->video->title . '" ' . - _('from') . ' ' . $this->video->extractor_key; + $description = $this->localeManager->t( + 'Download @title from @extractor', + [ + '@title' => $this->video->title, + '@extractor' => $this->video->extractor_key + ] + ); } $this->view->render( $response, @@ -233,18 +239,54 @@ class FrontController extends BaseController */ public function error(Request $request, Response $response, Exception $exception) { - $this->view->render( - $response, - 'error.tpl', - [ - 'config' => $this->config, - 'errors' => $exception->getMessage(), - 'class' => 'video', - 'title' => _('Error'), - 'canonical' => $this->getCanonicalUrl($request), - 'locale' => $this->localeManager->getLocale(), - ] - ); + if ($this->config->debug) { + $handler = new ExceptionHandler(); + $handler->handle($exception); + } else { + $this->view->render( + $response, + 'error.tpl', + [ + 'config' => $this->config, + 'errors' => $exception->getMessage(), + 'class' => 'video', + 'title' => $this->localeManager->t('Error'), + 'canonical' => $this->getCanonicalUrl($request), + 'locale' => $this->localeManager->getLocale(), + ] + ); + } + + return $response->withStatus(500); + } + + /** + * Display an error page for fatal errors. + * + * @param Request $request PSR-7 request + * @param Response $response PSR-7 response + * @param Throwable $error Error to display + * + * @return Response HTTP response + */ + public function fatalError(Request $request, Response $response, Throwable $error) + { + if ($this->config->debug) { + $handler = new ExceptionHandler(); + $handler->handle(new FatalThrowableError($error)); + } else { + $this->view->render( + $response, + 'error.tpl', + [ + 'config' => $this->config, + 'class' => 'video', + 'title' => $this->localeManager->t('Error'), + 'canonical' => $this->getCanonicalUrl($request), + 'locale' => $this->localeManager->getLocale(), + ] + ); + } return $response->withStatus(500); } diff --git a/i18n/ar_001/LC_MESSAGES/Alltube.po b/i18n/ar/LC_MESSAGES/Alltube.po similarity index 100% rename from i18n/ar_001/LC_MESSAGES/Alltube.po rename to i18n/ar/LC_MESSAGES/Alltube.po diff --git a/i18n/es_ES/LC_MESSAGES/Alltube.po b/i18n/es_ES/LC_MESSAGES/Alltube.po index 3562254..a6914ec 100644 --- a/i18n/es_ES/LC_MESSAGES/Alltube.po +++ b/i18n/es_ES/LC_MESSAGES/Alltube.po @@ -9,15 +9,15 @@ msgstr "" #: templates/error.tpl:6 msgid "Please check the URL of your video." -msgstr "Porfavor, revise la URL de su video." +msgstr "Por favor, revise la URL de su vídeo." #: templates/playlist.tpl:5 msgid "Videos extracted from" -msgstr "Videos extraidos desde" +msgstr "Vídeos extraídos desde" #: templates/playlist.tpl:7 msgid ":" -msgstr "" +msgstr ":" #: templates/playlist.tpl:26 templates/password.tpl:10 templates/video.tpl:83 #: templates/video.tpl:86 templates/index.tpl:18 @@ -55,23 +55,23 @@ msgstr "Formatos disponibles:" #: templates/video.tpl:29 msgid "Generic formats" -msgstr "Formatos genericos" +msgstr "Formatos genéricos" #: templates/video.tpl:32 msgid "Best" -msgstr "Mejor" +msgstr "El mejor" #: templates/video.tpl:37 msgid "Remux best video with best audio" -msgstr "" +msgstr "Usar la mejor calidad de vídeo y audio" #: templates/video.tpl:41 msgid "Worst" -msgstr "Peor" +msgstr "El peor" #: templates/video.tpl:44 msgid "Detailed formats" -msgstr "" +msgstr "Formatos detallados" #: templates/inc/footer.tpl:4 msgid "Code by" @@ -107,11 +107,11 @@ msgstr "Compartir en Facebook" #: templates/index.tpl:8 msgid "Copy here the URL of your video (Youtube, Dailymotion, etc.)" -msgstr "Copia aqui la URL de tu video (Youtube, Dailymotion, etc.)" +msgstr "Copia aquí la URL de tu vídeo (Youtube, Dailymotion, etc.)" #: templates/index.tpl:23 msgid "Audio only (MP3)" -msgstr "Solo audio (MP3)" +msgstr "Sólo audio (MP3)" #: templates/index.tpl:28 msgid "See all supported websites" @@ -123,7 +123,7 @@ msgstr "Arrastra esto a tu barra de marcadores" #: templates/index.tpl:31 msgid "Bookmarklet" -msgstr "" +msgstr "Marcador" #: templates/inc/header.tpl:4 msgid "Switch language" diff --git a/i18n/fr_FR/LC_MESSAGES/Alltube.po b/i18n/fr_FR/LC_MESSAGES/Alltube.po index fa25dd4..c249db6 100644 --- a/i18n/fr_FR/LC_MESSAGES/Alltube.po +++ b/i18n/fr_FR/LC_MESSAGES/Alltube.po @@ -1,34 +1,61 @@ msgid "" msgstr "" +"Project-Id-Version: AllTube Download\n" +"POT-Creation-Date: \n" +"PO-Revision-Date: \n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: POEditor.com\n" -"Project-Id-Version: AllTube Download\n" -"Language: fr\n" +"X-Generator: Poedit 2.2.4\n" -#: templates/error.tpl:6 -msgid "Please check the URL of your video." -msgstr "Veuillez vérifier l'URL de votre vidéo" +#: templates/playlist.tpl:13 +msgid "Videos extracted from @title:" +msgstr "Vidéos extraites depuis @title :" -#: templates/playlist.tpl:5 -msgid "Videos extracted from" -msgstr "Vidéos extraites depuis" - -#: templates/playlist.tpl:7 -msgid ":" -msgstr " :" - -#: templates/playlist.tpl:26 templates/video.tpl:96 templates/video.tpl:99 -#: templates/password.tpl:10 templates/index.tpl:19 -#: controllers/FrontController.php:315 +#: templates/playlist.tpl:38 templates/password.tpl:11 templates/index.tpl:19 +#: templates/info.tpl:98 msgid "Download" msgstr "Télécharger" -#: templates/playlist.tpl:27 +#: templates/playlist.tpl:39 msgid "More options" msgstr "Plus d'options" +#: templates/inc/header.tpl:4 +msgid "Switch language" +msgstr "Changer de langue" + +#: templates/inc/header.tpl:8 +msgid "Set language" +msgstr "Choisir la langue" + +#: templates/inc/footer.tpl:8 +msgid "Code by @dev" +msgstr "Développé par @dev" + +#: templates/inc/footer.tpl:16 +msgid "Design by @designer" +msgstr "Designé par @designer" + +#: templates/inc/footer.tpl:21 +msgid "Get the code" +msgstr "Obtenir le code" + +#: templates/inc/footer.tpl:29 +msgid "Based on @youtubedl" +msgstr "Basé sur @youtubedl" + +#: templates/inc/footer.tpl:33 +msgid "Donate using Liberapay" +msgstr "Faire un don avec Liberapay" + +#: templates/inc/footer.tpl:35 +msgid "Donate" +msgstr "Faire un don" + #: templates/password.tpl:5 msgid "This video is protected" msgstr "Cette vidéo est protégée" @@ -41,62 +68,6 @@ msgstr "L'accès à cette vidéo nécessite un mot de passe." msgid "Video password" msgstr "Mot de passe de la vidéo" -#: templates/extractors.tpl:4 controllers/FrontController.php:167 -msgid "Supported websites" -msgstr "Sites web supportés" - -#: templates/video.tpl:6 -msgid "You are going to download" -msgstr "Vous allez télécharger" - -#: templates/video.tpl:24 -msgid "Available formats:" -msgstr "Formats disponibles :" - -#: templates/video.tpl:29 -msgid "Generic formats" -msgstr "Formats génériques" - -#: templates/video.tpl:32 -msgid "Best" -msgstr "Meilleure qualité" - -#: templates/video.tpl:37 -msgid "Remux best video with best audio" -msgstr "Combiner la meilleure vidéo avec le meilleur audio" - -#: templates/video.tpl:41 -msgid "Worst" -msgstr "Pire qualité" - -#: templates/video.tpl:44 -msgid "Detailed formats" -msgstr "Formats détaillés" - -#: templates/inc/footer.tpl:4 -msgid "Code by" -msgstr "Développé par" - -#: templates/inc/footer.tpl:6 -msgid "Design by" -msgstr "Designé par" - -#: templates/inc/footer.tpl:10 -msgid "Get the code" -msgstr "Obtenir le code" - -#: templates/inc/footer.tpl:12 -msgid "Based on" -msgstr "Basé sur" - -#: templates/inc/header.tpl:21 -msgid "Share on Twitter" -msgstr "Partager sur Twitter" - -#: templates/inc/header.tpl:23 -msgid "Share on Facebook" -msgstr "Partager sur Facebook" - #: templates/index.tpl:8 msgid "Copy here the URL of your video (Youtube, Dailymotion, etc.)" msgstr "Copiez ici l'URL de votre vidéo (Youtube, Dailymotion, etc.)" @@ -105,6 +76,14 @@ msgstr "Copiez ici l'URL de votre vidéo (Youtube, Dailymotion, etc.)" msgid "Audio only (MP3)" msgstr "Audio uniquement (MP3)" +#: templates/index.tpl:28 +msgid "From" +msgstr "À partir de" + +#: templates/index.tpl:29 +msgid "to" +msgstr "jusqu'à" + #: templates/index.tpl:36 msgid "See all supported websites" msgstr "Voir tous les sites supportés" @@ -117,121 +96,183 @@ msgstr "Glissez ce lien dans votre barre de favoris :" msgid "Bookmarklet" msgstr "Bookmarklet" -#: templates/inc/header.tpl:4 -msgid "Switch language" -msgstr "Changer de langue" +#: templates/info.tpl:13 +msgid "You are going to download @title." +msgstr "Vous allez télécharger @title." + +#: templates/info.tpl:31 +msgid "Available formats:" +msgstr "Formats disponibles :" + +#: templates/info.tpl:33 +msgid "Generic formats" +msgstr "Formats génériques" + +#: templates/info.tpl:38 +msgid "Detailed formats" +msgstr "Formats détaillés" + +#: templates/info.tpl:80 +msgid "Stream the video through the server" +msgstr "Transférer la vidéo à travers le serveur" + +#: templates/info.tpl:85 +msgid "Convert into a custom format:" +msgstr "Convertir dans un format personnalisé :" + +#: templates/info.tpl:86 +msgid "Custom format" +msgstr "Format personnalisé" + +#: templates/info.tpl:86 +msgid "Format to convert to" +msgstr "Format vers lequel convertir" + +#: templates/info.tpl:91 +msgid "with" +msgstr "avec de l'audio à" + +#: templates/info.tpl:92 +msgid "Bit rate" +msgstr "Débit binaire" + +#: templates/info.tpl:93 +msgid "Custom bitrate" +msgstr "Débit binaire personnalisé" + +#: templates/info.tpl:95 +msgid "kbit/s audio" +msgstr "kbit/s" #: templates/error.tpl:5 msgid "An error occurred" msgstr "Une erreur est survenue" -#: templates/video.tpl:85 -msgid "Convert into a custom format:" -msgstr "Convertir dans un format personnalisé :" +#: templates/error.tpl:6 +msgid "Please check the URL of your video." +msgstr "Veuillez vérifier l'URL de votre vidéo." -#: templates/video.tpl:93 -msgid "kbit/s audio" -msgstr "kbit/s" +#: templates/extractors.tpl:4 controllers/FrontController.php:109 +msgid "Supported websites" +msgstr "Sites web supportés" -#: templates/video.tpl:91 -msgid "with" -msgstr "avec de l'audio à" +#: classes/Config.php:158 +msgid "Best" +msgstr "Meilleure qualité" -#: classes/VideoDownload.php:117 +#: classes/Config.php:159 +msgid "Remux best video with best audio" +msgstr "Combiner la meilleure vidéo avec le meilleur audio" + +#: classes/Config.php:160 +msgid "Worst" +msgstr "Pire qualité" + +#: classes/Video.php:159 msgid "Wrong password" msgstr "Mauvais mot de passe" -#: classes/VideoDownload.php:364 classes/VideoDownload.php:526 -msgid "Conversion of M3U8 files is not supported." -msgstr "La conversion des fichiers M3U8 n'est pas possible." - -#: classes/VideoDownload.php:375 classes/VideoDownload.php:412 -#: classes/VideoDownload.php:445 classes/VideoDownload.php:478 -#: classes/VideoDownload.php:534 -msgid "Could not open popen stream." -msgstr "Impossible d'ouvrir le flux popen." - -#: classes/VideoDownload.php:502 -msgid "Could not open fopen stream." -msgstr "Impossible d'ouvrir le flux fopen." - -#: controllers/FrontController.php:124 -msgid "Easily download videos from Youtube, Dailymotion, Vimeo and other websites." -msgstr "Téléchargez facilement des vidéos depuis Youtube, Dailymotion, Vimeo et d'autres sites web." - -#: controllers/FrontController.php:168 -msgid "List of all supported websites from which Alltube Download can extract video or audio files" -msgstr "Liste de tous les sites web depuis lesquels Alltube Download peut extraire des fichiers vidéo ou audio" - -#: controllers/FrontController.php:193 -msgid "Password prompt" -msgstr "Demande de mot de passe" - -#: controllers/FrontController.php:194 -msgid "You need a password in order to download this video with Alltube Download" -msgstr "Vous avez besoin d'un mot de passe pour télécharger cette vidéo avec Alltube Download" - -#: controllers/FrontController.php:311 -msgid "Video download" -msgstr "Téléchargement d'une vidéo" - -#: controllers/FrontController.php:312 -msgid "Download video from " -msgstr "Téléchargement d'une vidéo depuis " - -#: controllers/FrontController.php:315 -msgid "from" -msgstr "depuis" - -#: controllers/FrontController.php:378 -msgid "Error" -msgstr "Erreur" - -#: controllers/FrontController.php:450 -msgid "You need to enable remux mode to merge two formats." -msgstr "Vous devez activer le mode remux pour fusionner deux formats." - -#: controllers/FrontController.php:525 -msgid "Can't find URL of video." -msgstr "Impossible de trouver l'URL de la vidéo." - -#: classes/VideoDownload.php:289 classes/VideoDownload.php:394 -msgid "Can't find avconv or ffmpeg at " -msgstr "Impossible de trouver avconv ou ffmpeg à " - -#: templates/inc/footer.tpl:14 -msgid "Donate" -msgstr "Faire un don" - -#: classes/VideoDownload.php:158 +#: classes/Video.php:250 msgid "youtube-dl returned an empty URL." msgstr "youtube-dl a retourné une URL vide." -#: classes/VideoDownload.php:359 +#: classes/Video.php:361 classes/Video.php:465 +msgid "Can't find avconv or ffmpeg at @path." +msgstr "Impossible de trouver avconv ou ffmpeg à @path." + +#: classes/Video.php:377 +msgid "Invalid start time: @from." +msgstr "Horodatage de début non-valide : @from." + +#: classes/Video.php:384 +msgid "Invalid end time: @to." +msgstr "Horodatage de fin non-valide : @to." + +#: classes/Video.php:430 msgid "Conversion of playlists is not supported." msgstr "Impossible de convertir une playlist." -#: classes/VideoDownload.php:366 +#: classes/Video.php:435 classes/Video.php:578 +msgid "Conversion of M3U8 files is not supported." +msgstr "La conversion des fichiers M3U8 n'est pas possible." + +#: classes/Video.php:437 msgid "Conversion of DASH segments is not supported." msgstr "Impossible de convertir des segments DASH." -#: templates/inc/footer.tpl:14 -msgid "Donate using Liberapay" -msgstr "Faire un don avec Liberapay" +#: classes/Video.php:446 classes/Video.php:488 classes/Video.php:525 +#: classes/Video.php:558 classes/Video.php:586 +msgid "Could not open popen stream." +msgstr "Impossible d'ouvrir le flux popen." -#: classes/VideoDownload.php:302 -msgid "Invalid start time: " -msgstr "Horodatage de début non-valide :␣" +#: classes/Video.php:506 +msgid "This video does not have two URLs." +msgstr "Cette vidéo n'a pas deux URL." -#: classes/VideoDownload.php:309 -msgid "Invalid end time: " -msgstr "Horodatage de fin non-valide :␣" +#: controllers/DownloadController.php:215 +msgid "You need to enable remux mode to merge two formats." +msgstr "Vous devez activer le mode remux pour fusionner deux formats." -#: templates/index.tpl:28 -msgid "From" -msgstr "À partir de" +#: controllers/DownloadController.php:255 +msgid "Can't find URL of video." +msgstr "Impossible de trouver l'URL de la vidéo." -#: templates/index.tpl:29 -msgid "to" -msgstr "jusqu'à" +#: controllers/FrontController.php:64 +msgid "" +"Easily download videos from Youtube, Dailymotion, Vimeo and other websites." +msgstr "" +"Téléchargez facilement des vidéos depuis Youtube, Dailymotion, Vimeo et " +"d'autres sites web." +#: controllers/FrontController.php:110 +msgid "" +"List of all supported websites from which Alltube Download can extract video " +"or audio files" +msgstr "" +"Liste de tous les sites web depuis lesquels Alltube Download peut extraire " +"des fichiers vidéo ou audio" + +#: controllers/FrontController.php:136 +msgid "Password prompt" +msgstr "Demande de mot de passe" + +#: controllers/FrontController.php:138 +msgid "" +"You need a password in order to download this video with Alltube Download" +msgstr "" +"Vous avez besoin d'un mot de passe pour télécharger cette vidéo avec Alltube " +"Download" + +#: controllers/FrontController.php:169 +msgid "Video download" +msgstr "Téléchargement d'une vidéo" + +#: controllers/FrontController.php:171 +msgid "Download video from @extractor" +msgstr "Téléchargement d'une vidéo depuis @extractor" + +#: controllers/FrontController.php:177 +msgid "Download @title from @extractor" +msgstr "Téléchargement de @title depuis @extractor" + +#: controllers/FrontController.php:253 controllers/FrontController.php:284 +msgid "Error" +msgstr "Erreur" + +#~ msgid ":" +#~ msgstr " :" + +#~ msgid "Based on" +#~ msgstr "Basé sur" + +#~ msgid "Share on Twitter" +#~ msgstr "Partager sur Twitter" + +#~ msgid "Share on Facebook" +#~ msgstr "Partager sur Facebook" + +#~ msgid "Could not open fopen stream." +#~ msgstr "Impossible d'ouvrir le flux fopen." + +#~ msgid "from" +#~ msgstr "depuis" diff --git a/i18n/template.pot b/i18n/template.pot index 6bc0c01..a7d5402 100644 --- a/i18n/template.pot +++ b/i18n/template.pot @@ -1,110 +1,49 @@ msgid "" msgstr "Content-Type: text/plain; charset=UTF-8\n" -#: templates/inc/footer.tpl:4 -msgid "Code by" +#: templates/playlist.tpl:13 +msgid "Videos extracted from @title:" msgstr "" -#: templates/inc/footer.tpl:6 -msgid "Design by" +#: templates/playlist.tpl:38 templates/password.tpl:11 templates/index.tpl:19 +#: templates/info.tpl:98 +msgid "Download" msgstr "" -#: templates/inc/footer.tpl:10 -msgid "Get the code" -msgstr "" - -#: templates/inc/footer.tpl:12 -msgid "Based on" -msgstr "" - -#: templates/inc/footer.tpl:14 -msgid "Donate using Liberapay" -msgstr "" - -#: templates/inc/footer.tpl:14 -msgid "Donate" +#: templates/playlist.tpl:39 +msgid "More options" msgstr "" #: templates/inc/header.tpl:4 msgid "Switch language" msgstr "" -#: templates/inc/header.tpl:21 -msgid "Share on Twitter" +#: templates/inc/header.tpl:8 +msgid "Set language" msgstr "" -#: templates/inc/header.tpl:23 -msgid "Share on Facebook" +#: templates/inc/footer.tpl:8 +msgid "Code by @dev" msgstr "" -#: templates/playlist.tpl:5 -msgid "Videos extracted from" +#: templates/inc/footer.tpl:16 +msgid "Design by @designer" msgstr "" -#: templates/playlist.tpl:7 -msgid ":" +#: templates/inc/footer.tpl:21 +msgid "Get the code" msgstr "" -#: templates/playlist.tpl:26 templates/video.tpl:96 templates/video.tpl:99 -#: templates/password.tpl:10 templates/index.tpl:19 -#: controllers/FrontController.php:315 -msgid "Download" +#: templates/inc/footer.tpl:29 +msgid "Based on @youtubedl" msgstr "" -#: templates/playlist.tpl:27 -msgid "More options" +#: templates/inc/footer.tpl:33 +msgid "Donate using Liberapay" msgstr "" -#: templates/extractors.tpl:4 controllers/FrontController.php:167 -msgid "Supported websites" -msgstr "" - -#: templates/video.tpl:6 -msgid "You are going to download" -msgstr "" - -#: templates/video.tpl:24 -msgid "Available formats:" -msgstr "" - -#: templates/video.tpl:29 -msgid "Generic formats" -msgstr "" - -#: templates/video.tpl:32 -msgid "Best" -msgstr "" - -#: templates/video.tpl:37 -msgid "Remux best video with best audio" -msgstr "" - -#: templates/video.tpl:41 -msgid "Worst" -msgstr "" - -#: templates/video.tpl:44 -msgid "Detailed formats" -msgstr "" - -#: templates/video.tpl:85 -msgid "Convert into a custom format:" -msgstr "" - -#: templates/video.tpl:91 -msgid "with" -msgstr "" - -#: templates/video.tpl:93 -msgid "kbit/s audio" -msgstr "" - -#: templates/error.tpl:5 -msgid "An error occurred" -msgstr "" - -#: templates/error.tpl:6 -msgid "Please check the URL of your video." +#: templates/inc/footer.tpl:35 +msgid "Donate" msgstr "" #: templates/password.tpl:5 @@ -147,88 +86,159 @@ msgstr "" msgid "Bookmarklet" msgstr "" -#: classes/VideoDownload.php:117 +#: templates/info.tpl:13 +msgid "You are going to download @title." +msgstr "" + +#: templates/info.tpl:31 +msgid "Available formats:" +msgstr "" + +#: templates/info.tpl:33 +msgid "Generic formats" +msgstr "" + +#: templates/info.tpl:38 +msgid "Detailed formats" +msgstr "" + +#: templates/info.tpl:80 +msgid "Stream the video through the server" +msgstr "" + +#: templates/info.tpl:85 +msgid "Convert into a custom format:" +msgstr "" + +#: templates/info.tpl:86 +msgid "Custom format" +msgstr "" + +#: templates/info.tpl:86 +msgid "Format to convert to" +msgstr "" + +#: templates/info.tpl:91 +msgid "with" +msgstr "" + +#: templates/info.tpl:92 +msgid "Bit rate" +msgstr "" + +#: templates/info.tpl:93 +msgid "Custom bitrate" +msgstr "" + +#: templates/info.tpl:95 +msgid "kbit/s audio" +msgstr "" + +#: templates/error.tpl:5 +msgid "An error occurred" +msgstr "" + +#: templates/error.tpl:6 +msgid "Please check the URL of your video." +msgstr "" + +#: templates/extractors.tpl:4 controllers/FrontController.php:109 +msgid "Supported websites" +msgstr "" + +#: classes/Config.php:158 +msgid "Best" +msgstr "" + +#: classes/Config.php:159 +msgid "Remux best video with best audio" +msgstr "" + +#: classes/Config.php:160 +msgid "Worst" +msgstr "" + +#: classes/Video.php:159 msgid "Wrong password" msgstr "" -#: classes/VideoDownload.php:158 +#: classes/Video.php:250 msgid "youtube-dl returned an empty URL." msgstr "" -#: classes/VideoDownload.php:289 classes/VideoDownload.php:394 -msgid "Can't find avconv or ffmpeg at " +#: classes/Video.php:361 classes/Video.php:465 +msgid "Can't find avconv or ffmpeg at @path." msgstr "" -#: classes/VideoDownload.php:302 -msgid "Invalid start time: " +#: classes/Video.php:377 +msgid "Invalid start time: @from." msgstr "" -#: classes/VideoDownload.php:309 -msgid "Invalid end time: " +#: classes/Video.php:384 +msgid "Invalid end time: @to." msgstr "" -#: classes/VideoDownload.php:359 +#: classes/Video.php:430 msgid "Conversion of playlists is not supported." msgstr "" -#: classes/VideoDownload.php:364 classes/VideoDownload.php:526 +#: classes/Video.php:435 classes/Video.php:578 msgid "Conversion of M3U8 files is not supported." msgstr "" -#: classes/VideoDownload.php:366 +#: classes/Video.php:437 msgid "Conversion of DASH segments is not supported." msgstr "" -#: classes/VideoDownload.php:375 classes/VideoDownload.php:412 -#: classes/VideoDownload.php:445 classes/VideoDownload.php:478 -#: classes/VideoDownload.php:534 +#: classes/Video.php:446 classes/Video.php:488 classes/Video.php:525 +#: classes/Video.php:558 classes/Video.php:586 msgid "Could not open popen stream." msgstr "" -#: classes/VideoDownload.php:502 -msgid "Could not open fopen stream." +#: classes/Video.php:506 +msgid "This video does not have two URLs." msgstr "" -#: controllers/FrontController.php:124 +#: controllers/DownloadController.php:215 +msgid "You need to enable remux mode to merge two formats." +msgstr "" + +#: controllers/DownloadController.php:255 +msgid "Can't find URL of video." +msgstr "" + +#: controllers/FrontController.php:64 msgid "" "Easily download videos from Youtube, Dailymotion, Vimeo and other websites." msgstr "" -#: controllers/FrontController.php:168 +#: controllers/FrontController.php:110 msgid "" "List of all supported websites from which Alltube Download can extract video " "or audio files" msgstr "" -#: controllers/FrontController.php:193 +#: controllers/FrontController.php:136 msgid "Password prompt" msgstr "" -#: controllers/FrontController.php:194 +#: controllers/FrontController.php:138 msgid "" "You need a password in order to download this video with Alltube Download" msgstr "" -#: controllers/FrontController.php:311 +#: controllers/FrontController.php:169 msgid "Video download" msgstr "" -#: controllers/FrontController.php:312 -msgid "Download video from " +#: controllers/FrontController.php:171 +msgid "Download video from @extractor" msgstr "" -#: controllers/FrontController.php:315 -msgid "from" +#: controllers/FrontController.php:177 +msgid "Download @title from @extractor" msgstr "" -#: controllers/FrontController.php:378 +#: controllers/FrontController.php:253 controllers/FrontController.php:284 msgid "Error" msgstr "" - -#: controllers/FrontController.php:450 -msgid "You need to enable remux mode to merge two formats." -msgstr "" - -#: controllers/FrontController.php:525 -msgid "Can't find URL of video." -msgstr "" diff --git a/index.php b/index.php index 3da84a0..b69d13d 100644 --- a/index.php +++ b/index.php @@ -10,6 +10,7 @@ use Alltube\LocaleMiddleware; use Alltube\UglyRouter; use Alltube\ViewFactory; use Slim\App; +use Symfony\Component\Debug\Debug; if (isset($_SERVER['REQUEST_URI']) && strpos($_SERVER['REQUEST_URI'], '/index.php') !== false) { header('Location: ' . str_ireplace('/index.php', '/', $_SERVER['REQUEST_URI'])); @@ -20,26 +21,44 @@ if (is_file(__DIR__ . '/config/config.yml')) { Config::setFile(__DIR__ . '/config/config.yml'); } +// Create app. $app = new App(); $container = $app->getContainer(); + +// Load config. $config = Config::getInstance(); if ($config->uglyUrls) { $container['router'] = new UglyRouter(); } -$container['view'] = ViewFactory::create($container); +if ($config->debug) { + /* + We want to enable this as soon as possible, + in order to catch errors that are thrown + before the Slim error handler is ready. + */ + Debug::enable(); +} +// Locales. if (!class_exists('Locale')) { die('You need to install the intl extension for PHP.'); } -$container['locale'] = new LocaleManager(); +$container['locale'] = LocaleManager::getInstance(); $app->add(new LocaleMiddleware($container)); +// Smarty. +$container['view'] = ViewFactory::create($container); + +// Controllers. $frontController = new FrontController($container); $jsonController = new JsonController($container); $downloadController = new DownloadController($container); +// Error handling. $container['errorHandler'] = [$frontController, 'error']; +$container['phpErrorHandler'] = [$frontController, 'fatalError']; +// Routes. $app->get( '/', [$frontController, 'index'] @@ -59,7 +78,7 @@ $app->any('/video', [$frontController, 'info']); $app->any( '/watch', - [$frontController, 'video'] + [$frontController, 'info'] ); $app->any( diff --git a/package.json b/package.json index ab98e92..77fc381 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "alltube", "description": "HTML GUI for youtube-dl", - "version": "2.0.5", + "version": "2.1.0", "author": "Pierre Rudloff", "bugs": "https://github.com/Rudloff/alltube/issues", "dependencies": { diff --git a/resources/manifest.json b/resources/manifest.json index 25aae7f..6f5e6f1 100644 --- a/resources/manifest.json +++ b/resources/manifest.json @@ -5,27 +5,27 @@ "display": "standalone", "icons": [ { - "src": "img/favicon.png", + "src": "../img/favicon.png", "sizes": "32x32", "type": "image/png" }, { - "src": "img/logo_60.png", + "src": "../img/logo_60.png", "sizes": "60x60", "type": "image/png" }, { - "src": "img/logo_90.png", + "src": "../img/logo_90.png", "sizes": "90x60", "type": "image/png" }, { - "src": "img/logo_app.png", + "src": "../img/logo_app.png", "sizes": "243x243", "type": "image/png" }, { - "src": "img/logo_250.png", + "src": "../img/logo_250.png", "sizes": "250x250", "type": "image/png" } diff --git a/templates/inc/footer.tpl b/templates/inc/footer.tpl index 88a3ece..dd4ec6f 100644 --- a/templates/inc/footer.tpl +++ b/templates/inc/footer.tpl @@ -1,18 +1,40 @@ diff --git a/templates/inc/head.tpl b/templates/inc/head.tpl index c3ee074..ce5febf 100644 --- a/templates/inc/head.tpl +++ b/templates/inc/head.tpl @@ -1,4 +1,3 @@ -{locale path="../i18n" domain="Alltube"} diff --git a/templates/inc/header.tpl b/templates/inc/header.tpl index 844757e..8a9c569 100644 --- a/templates/inc/header.tpl +++ b/templates/inc/header.tpl @@ -2,28 +2,29 @@ {if isset($supportedLocales) AND count($supportedLocales) > 1}
{/if} -
- -
-
- -
-
-
diff --git a/templates/info.tpl b/templates/info.tpl index 5d1fa68..6a2d5f9 100644 --- a/templates/info.tpl +++ b/templates/info.tpl @@ -3,10 +3,12 @@
{include file="inc/logo.tpl"} -

{t}You are going to download{/t} - . +{$title=" + "} +

+ {t params=['@title' => $title]}You are going to download @title.{/t}

{if isset($video->thumbnail)} @@ -20,11 +22,11 @@
+ {if $config->uglyUrls} + + {/if} {if isset($video->formats) && count($video->formats) > 1}

- {if $config->uglyUrls} - - {/if}

- {if $config->stream} - - -

- {/if} - {if $config->convertAdvanced} - - - - {t}with{/t} - - - {t}kbit/s audio{/t} -

- {/if} + {/if} + {if $config->stream} + + +

+ {/if} + {if $config->convertAdvanced} + + + + {t}with{/t} + + + {t}kbit/s audio{/t} +

{/if}
diff --git a/templates/playlist.tpl b/templates/playlist.tpl index 4afa662..5804e4b 100644 --- a/templates/playlist.tpl +++ b/templates/playlist.tpl @@ -2,10 +2,17 @@
{include file="inc/logo.tpl"} -

{t}Videos extracted from{/t} {if isset($video->title)} - -{$video->title}{/if}{t}:{/t} -

+ +{if isset($video->title)} + {$title=" + + {$video->title} + "} +

+ {t params=['@title'=>$title]}Videos extracted from @title:{/t} +

+{/if} + {if $config->stream} webpage_url}" class="downloadBtn">Download everything {/if} diff --git a/tests/BaseTest.php b/tests/BaseTest.php index 136a553..9a98f50 100644 --- a/tests/BaseTest.php +++ b/tests/BaseTest.php @@ -45,4 +45,29 @@ abstract class BaseTest extends TestCase { Config::destroyInstance(); } + + /** + * Check tests requirements. + * @return void + */ + protected function checkRequirements() + { + parent::checkRequirements(); + + $annotations = $this->getAnnotations(); + $requires = []; + + if (isset($annotations['class']['requires'])) { + $requires += $annotations['class']['requires']; + } + if (isset($annotations['method']['requires'])) { + $requires += $annotations['method']['requires']; + } + + foreach ($requires as $require) { + if ($require == 'download' && getenv('CI')) { + $this->markTestSkipped('Do not run tests that download videos on CI.'); + } + } + } } diff --git a/tests/ControllerTest.php b/tests/ControllerTest.php index fa6b02c..c703a7d 100644 --- a/tests/ControllerTest.php +++ b/tests/ControllerTest.php @@ -56,8 +56,8 @@ abstract class ControllerTest extends BaseTest $this->container = new Container(); $this->request = Request::createFromEnvironment(Environment::mock()); $this->response = new Response(); + $this->container['locale'] = LocaleManager::getInstance(); $this->container['view'] = ViewFactory::create($this->container, $this->request); - $this->container['locale'] = new LocaleManager(); $frontController = new FrontController($this->container); $downloadController = new DownloadController($this->container); diff --git a/tests/ConvertedPlaylistArchiveStreamTest.php b/tests/ConvertedPlaylistArchiveStreamTest.php index 0c7b3c5..58b826e 100644 --- a/tests/ConvertedPlaylistArchiveStreamTest.php +++ b/tests/ConvertedPlaylistArchiveStreamTest.php @@ -11,6 +11,7 @@ use Alltube\Video; /** * Unit tests for the ConvertedPlaylistArchiveStream class. + * @requires download */ class ConvertedPlaylistArchiveStreamTest extends StreamTest { diff --git a/tests/DownloadControllerTest.php b/tests/DownloadControllerTest.php index ada74f7..7bc4d93 100644 --- a/tests/DownloadControllerTest.php +++ b/tests/DownloadControllerTest.php @@ -11,6 +11,7 @@ use Alltube\Controller\DownloadController; /** * Unit tests for the FrontController class. + * @requires download */ class DownloadControllerTest extends ControllerTest { @@ -79,10 +80,6 @@ class DownloadControllerTest extends ControllerTest */ public function testDownloadWithM3uStream() { - if (getenv('CI')) { - $this->markTestSkipped('Twitter returns a 429 error when the test is ran too many times.'); - } - Config::setOptions(['stream' => true]); $this->assertRequestIsOk( @@ -153,9 +150,6 @@ class DownloadControllerTest extends ControllerTest */ public function testDownloadWithMissingPassword() { - if (getenv('CI')) { - $this->markTestSkipped('Travis is blacklisted by Vimeo.'); - } $this->assertRequestIsRedirect('download', ['url' => 'http://vimeo.com/68375962']); } diff --git a/tests/FrontControllerTest.php b/tests/FrontControllerTest.php index 0d9248b..2904d47 100644 --- a/tests/FrontControllerTest.php +++ b/tests/FrontControllerTest.php @@ -108,6 +108,7 @@ class FrontControllerTest extends ControllerTest * Test the info() function. * * @return void + * @requires download */ public function testInfo() { @@ -118,6 +119,7 @@ class FrontControllerTest extends ControllerTest * Test the info() function with audio conversion. * * @return void + * @requires download */ public function testInfoWithAudio() { @@ -133,12 +135,10 @@ class FrontControllerTest extends ControllerTest * Test the info() function with audio conversion from a Vimeo video. * * @return void + * @requires download */ public function testInfoWithVimeoAudio() { - if (getenv('CI')) { - $this->markTestSkipped('Travis is blacklisted by Vimeo.'); - } Config::setOptions(['convert' => true]); // So we can test the fallback to default format @@ -149,6 +149,7 @@ class FrontControllerTest extends ControllerTest * Test the info() function with audio enabled and an URL that doesn't need to be converted. * * @return void + * @requires download */ public function testInfoWithUnconvertedAudio() { @@ -167,12 +168,10 @@ class FrontControllerTest extends ControllerTest * Test the info() function with a password. * * @return void + * @requires download */ public function testInfoWithPassword() { - if (getenv('CI')) { - $this->markTestSkipped('Travis is blacklisted by Vimeo.'); - } $result = $this->controller->info( $this->request->withQueryParams(['url' => 'http://vimeo.com/68375962']) ->withParsedBody(['password' => 'youtube-dl']), @@ -185,12 +184,10 @@ class FrontControllerTest extends ControllerTest * Test the info() function with a missing password. * * @return void + * @requires download */ public function testInfoWithMissingPassword() { - if (getenv('CI')) { - $this->markTestSkipped('Travis is blacklisted by Vimeo.'); - } $this->assertRequestIsOk('info', ['url' => 'http://vimeo.com/68375962']); $this->assertRequestIsOk('info', ['url' => 'http://vimeo.com/68375962', 'audio' => true]); } @@ -199,6 +196,7 @@ class FrontControllerTest extends ControllerTest * Test the info() function with streams enabled. * * @return void + * @requires download */ public function testInfoWithStream() { @@ -215,6 +213,7 @@ class FrontControllerTest extends ControllerTest * Test the info() function with a playlist. * * @return void + * @requires download */ public function testInfoWithPlaylist() { diff --git a/tests/JsonControllerTest.php b/tests/JsonControllerTest.php index 3b5de08..d25f3e6 100644 --- a/tests/JsonControllerTest.php +++ b/tests/JsonControllerTest.php @@ -27,6 +27,7 @@ class JsonControllerTest extends ControllerTest * Test the json() function. * * @return void + * @requires download */ public function testJson() { @@ -37,6 +38,7 @@ class JsonControllerTest extends ControllerTest * Test the json() function with an error. * * @return void + * @requires download */ public function testJsonWithError() { diff --git a/tests/LocaleManagerTest.php b/tests/LocaleManagerTest.php index 1bbc8a1..1ceb5d8 100644 --- a/tests/LocaleManagerTest.php +++ b/tests/LocaleManagerTest.php @@ -27,7 +27,7 @@ class LocaleManagerTest extends BaseTest protected function setUp() { $_SESSION[LocaleManager::class]['locale'] = 'foo_BAR'; - $this->localeManager = new LocaleManager(); + $this->localeManager = LocaleManager::getInstance(); } /** @@ -38,6 +38,7 @@ class LocaleManagerTest extends BaseTest protected function tearDown() { $this->localeManager->unsetLocale(); + LocaleManager::destroyInstance(); } /** @@ -93,6 +94,7 @@ class LocaleManagerTest extends BaseTest */ public function testEnv() { + putenv('LANG=foo_BAR'); $this->localeManager->setLocale(new Locale('foo_BAR')); $this->assertEquals('foo_BAR', getenv('LANG')); } diff --git a/tests/LocaleMiddlewareTest.php b/tests/LocaleMiddlewareTest.php index 299e8ca..005e87e 100644 --- a/tests/LocaleMiddlewareTest.php +++ b/tests/LocaleMiddlewareTest.php @@ -39,7 +39,7 @@ class LocaleMiddlewareTest extends BaseTest protected function setUp() { $this->container = new Container(); - $this->container['locale'] = new LocaleManager(); + $this->container['locale'] = LocaleManager::getInstance(); $this->middleware = new LocaleMiddleware($this->container); } @@ -51,6 +51,7 @@ class LocaleMiddlewareTest extends BaseTest protected function tearDown() { $this->container['locale']->unsetLocale(); + LocaleManager::destroyInstance(); } /** diff --git a/tests/PlaylistArchiveStreamTest.php b/tests/PlaylistArchiveStreamTest.php index afefcb2..9c301a3 100644 --- a/tests/PlaylistArchiveStreamTest.php +++ b/tests/PlaylistArchiveStreamTest.php @@ -11,6 +11,7 @@ use Alltube\Video; /** * Unit tests for the PlaylistArchiveStream class. + * @requires download */ class PlaylistArchiveStreamTest extends StreamTest { diff --git a/tests/VideoTest.php b/tests/VideoTest.php index bb47062..b19b538 100644 --- a/tests/VideoTest.php +++ b/tests/VideoTest.php @@ -11,6 +11,7 @@ use Alltube\Video; /** * Unit tests for the Video class. + * @requires download */ class VideoTest extends BaseTest { @@ -58,10 +59,6 @@ class VideoTest extends BaseTest */ public function testgetUrlWithPassword() { - if (getenv('CI')) { - $this->markTestSkipped('Travis is blacklisted by Vimeo.'); - } - $video = new Video('http://vimeo.com/68375962', 'best', 'youtube-dl'); foreach ($video->getUrl() as $videoURL) { $this->assertContains('vimeocdn.com', $videoURL); @@ -76,10 +73,6 @@ class VideoTest extends BaseTest */ public function testgetUrlWithMissingPassword() { - if (getenv('CI')) { - $this->markTestSkipped('Travis is blacklisted by Vimeo.'); - } - $video = new Video('http://vimeo.com/68375962'); $video->getUrl(); } @@ -92,10 +85,6 @@ class VideoTest extends BaseTest */ public function testgetUrlWithWrongPassword() { - if (getenv('CI')) { - $this->markTestSkipped('Travis is blacklisted by Vimeo.'); - } - $video = new Video('http://vimeo.com/68375962', 'best', 'foo'); $video->getUrl(); } @@ -142,29 +131,19 @@ class VideoTest extends BaseTest 'flv', 'bbcodspdns.fcod.llnwd.net', ], - [ - 'http://www.rtl2.de/sendung/grip-das-motormagazin/folge/folge-203-0', 'bestaudio/best', - 'GRIP_sucht_den_Sommerkonig-folge-203-0', - 'f4v', - 'edgefcs.net', - ], [ 'https://openload.co/f/kUEfGclsU9o', 'best[protocol^=http]', 'skyrim_no-audio_1080.mp4-kUEfGclsU9o', 'mp4', 'openload.co', ], - ]; - - if (!getenv('CI')) { - // Travis is blacklisted by Vimeo. - $videos[] = [ + [ 'https://vimeo.com/24195442', 'best[protocol^=http]', 'Carving_the_Mountains-24195442', 'mp4', 'vimeocdn.com', - ]; - } + ] + ]; return $videos; } @@ -193,17 +172,14 @@ class VideoTest extends BaseTest */ public function m3uUrlProvider() { - $videos = []; - - if (!getenv('CI')) { - // Twitter returns a 429 error when the test is ran too many times. - $videos[] = [ + $videos = [ + [ 'https://twitter.com/verge/status/813055465324056576/video/1', 'hls-2176', 'The_Verge_-_This_tiny_origami_robot_can_self-fold_and_complete_tasks-813055465324056576', 'mp4', 'video.twimg.com', - ]; - } + ] + ]; return $videos; } @@ -365,10 +341,6 @@ class VideoTest extends BaseTest */ public function testGetAudioStreamDashError() { - if (getenv('CI')) { - $this->markTestSkipped('Travis is blacklisted by Vimeo.'); - } - $video = new Video('https://vimeo.com/251997032', 'bestaudio/best'); $video->getAudioStream(); } diff --git a/tests/ViewFactoryTest.php b/tests/ViewFactoryTest.php index 163eeb1..45286c9 100644 --- a/tests/ViewFactoryTest.php +++ b/tests/ViewFactoryTest.php @@ -6,6 +6,7 @@ namespace Alltube\Test; +use Alltube\LocaleManager; use Alltube\ViewFactory; use Slim\Container; use Slim\Http\Environment; @@ -24,7 +25,9 @@ class ViewFactoryTest extends BaseTest */ public function testCreate() { - $view = ViewFactory::create(new Container()); + $container = new Container(); + $container['locale'] = LocaleManager::getInstance(); + $view = ViewFactory::create($container); $this->assertInstanceOf(Smarty::class, $view); } @@ -35,8 +38,10 @@ class ViewFactoryTest extends BaseTest */ public function testCreateWithXForwardedProto() { + $container = new Container(); + $container['locale'] = LocaleManager::getInstance(); $request = Request::createFromEnvironment(Environment::mock()); - $view = ViewFactory::create(new Container(), $request->withHeader('X-Forwarded-Proto', 'https')); + $view = ViewFactory::create($container, $request->withHeader('X-Forwarded-Proto', 'https')); $this->assertInstanceOf(Smarty::class, $view); } } diff --git a/tests/YoutubeChunkStreamTest.php b/tests/YoutubeChunkStreamTest.php index cae27c0..a817119 100644 --- a/tests/YoutubeChunkStreamTest.php +++ b/tests/YoutubeChunkStreamTest.php @@ -11,6 +11,7 @@ use Alltube\Video; /** * Unit tests for the YoutubeChunkStream class. + * @requires download */ class YoutubeChunkStreamTest extends StreamTest { diff --git a/tests/YoutubeStreamTest.php b/tests/YoutubeStreamTest.php index f855aa8..3bbd325 100644 --- a/tests/YoutubeStreamTest.php +++ b/tests/YoutubeStreamTest.php @@ -11,6 +11,7 @@ use Alltube\Video; /** * Unit tests for the YoutubeStream class. + * @requires download */ class YoutubeStreamTest extends StreamTest {