Switch to symfony/translation for translations (#250)

This commit is contained in:
Pierre Rudloff 2019-11-27 23:15:49 +01:00
parent 0b1ce90f47
commit a5bd827d21
16 changed files with 399 additions and 212 deletions

View file

@ -101,7 +101,7 @@ module.exports = function (grunt) {
'i18n/es_ES/LC_MESSAGES/Alltube.mo': 'i18n/es_ES/LC_MESSAGES/Alltube.po', '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/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/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'
} }
} }
}, },

View file

@ -135,6 +135,11 @@ class Config
*/ */
public $genericFormats = []; public $genericFormats = [];
/**
* Enable debug mode.
*
* @var bool
*/
public $debug = false; public $debug = false;
/** /**

View file

@ -38,8 +38,10 @@ class Locale
{ {
$parse = AcceptLanguage::parse($locale); $parse = AcceptLanguage::parse($locale);
$this->language = $parse[1]['language']; $this->language = $parse[1]['language'];
if (!empty($parse[1]['region'])) {
$this->region = $parse[1]['region']; $this->region = $parse[1]['region'];
} }
}
/** /**
* Convert the locale to a string. * Convert the locale to a string.
@ -68,7 +70,11 @@ class Locale
*/ */
public function getIso15897() public function getIso15897()
{ {
if (isset($this->region)) {
return $this->language . '_' . $this->region; return $this->language . '_' . $this->region;
} else {
return $this->language;
}
} }
/** /**
@ -78,7 +84,11 @@ class Locale
*/ */
public function getBcp47() public function getBcp47()
{ {
if (isset($this->region)) {
return $this->language . '-' . $this->region; return $this->language . '-' . $this->region;
} else {
return $this->language;
}
} }
/** /**
@ -98,6 +108,8 @@ class Locale
*/ */
public function getCountry() public function getCountry()
{ {
if (isset($this->region)) {
return country($this->getIso3166()); return country($this->getIso3166());
} }
}
} }

View file

@ -8,6 +8,8 @@ namespace Alltube;
use Aura\Session\Segment; use Aura\Session\Segment;
use Symfony\Component\Process\Process; use Symfony\Component\Process\Process;
use Symfony\Component\Translation\Translator;
use Symfony\Component\Translation\Loader\MoFileLoader;
/** /**
* Class used to manage locales. * Class used to manage locales.
@ -19,7 +21,7 @@ class LocaleManager
* *
* @var array * @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. * Current locale.
@ -35,19 +37,49 @@ class LocaleManager
*/ */
private $sessionSegment; 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. * LocaleManager constructor.
*/ */
public function __construct() private function __construct()
{ {
$session = SessionManager::getSession(); $session = SessionManager::getSession();
$this->sessionSegment = $session->getSegment(self::class); $this->sessionSegment = $session->getSegment(self::class);
$cookieLocale = $this->sessionSegment->get('locale'); $cookieLocale = $this->sessionSegment->get('locale');
$this->translator = new Translator(self::DEFAULT_LOCALE);
if (isset($cookieLocale)) { if (isset($cookieLocale)) {
$this->setLocale(new Locale($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,17 +90,10 @@ class LocaleManager
public function getSupportedLocales() public function getSupportedLocales()
{ {
$return = []; $return = [];
$process = new Process(['locale', '-a']);
$process->run();
$installedLocales = explode(PHP_EOL, trim($process->getOutput()));
foreach ($this->supportedLocales as $supportedLocale) { 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; return $return;
} }
@ -90,8 +115,7 @@ class LocaleManager
*/ */
public function setLocale(Locale $locale) public function setLocale(Locale $locale)
{ {
putenv('LANG=' . $locale); $this->translator->setLocale($locale->getIso15897());
setlocale(LC_ALL, [$locale . '.utf8', $locale]);
$this->curLocale = $locale; $this->curLocale = $locale;
$this->sessionSegment->set('locale', $locale); $this->sessionSegment->set('locale', $locale);
} }
@ -101,7 +125,47 @@ class LocaleManager
*/ */
public function unsetLocale() public function unsetLocale()
{ {
$this->translator->setLocale(self::DEFAULT_LOCALE);
$this->curLocale = null; $this->curLocale = null;
$this->sessionSegment->clear(); $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)
{
return $this->t($text);
}
/**
* Translate a string.
*
* @param string $string String to translate
*
* @return string Translated string
*/
public function t($string)
{
return $this->translator->trans($string);
}
/**
* Get LocaleManager singleton instance.
*
* @return LocaleManager
*/
public static function getInstance()
{
if (!isset(self::$instance)) {
self::$instance = new self();
}
return self::$instance;
}
} }

View file

@ -74,6 +74,13 @@ class Video
*/ */
private $urls; private $urls;
/**
* LocaleManager instance.
*
* @var LocaleManager
*/
protected $localeManager;
/** /**
* VideoDownload constructor. * VideoDownload constructor.
* *
@ -87,6 +94,8 @@ class Video
$this->requestedFormat = $requestedFormat; $this->requestedFormat = $requestedFormat;
$this->password = $password; $this->password = $password;
$this->config = Config::getInstance(); $this->config = Config::getInstance();
$this->localeManager = LocaleManager::getInstance();
} }
/** /**
@ -116,7 +125,9 @@ class Video
* */ * */
public static function getExtractors() 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 * @return string Result
*/ */
private static function callYoutubedl(array $arguments) private function callYoutubedl(array $arguments)
{ {
$config = Config::getInstance(); $config = Config::getInstance();
@ -145,7 +156,7 @@ class Video
if ($errorOutput == 'ERROR: This video is protected by a password, use the --video-password option') { if ($errorOutput == 'ERROR: This video is protected by a password, use the --video-password option') {
throw new PasswordException($errorOutput, $exitCode); throw new PasswordException($errorOutput, $exitCode);
} elseif (substr($errorOutput, 0, 21) == 'ERROR: Wrong password') { } elseif (substr($errorOutput, 0, 21) == 'ERROR: Wrong password') {
throw new Exception(_('Wrong password'), $exitCode); throw new Exception($this->localeManager->t('Wrong password'), $exitCode);
} else { } else {
throw new Exception($errorOutput, $exitCode); throw new Exception($errorOutput, $exitCode);
} }
@ -177,7 +188,7 @@ class Video
$arguments[] = $this->password; $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')); $this->urls = explode("\n", $this->getProp('get-url'));
if (empty($this->urls[0])) { 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,11 @@ class Video
$to = null $to = null
) { ) {
if (!$this->checkCommand([$this->config->avconv, '-version'])) { 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 '
) . $this->config->avconv . '.'
);
} }
$durationRegex = '/(\d+:)?(\d+:)?(\d+)/'; $durationRegex = '/(\d+:)?(\d+:)?(\d+)/';
@ -358,14 +373,14 @@ class Video
if (!empty($from)) { if (!empty($from)) {
if (!preg_match($durationRegex, $from)) { if (!preg_match($durationRegex, $from)) {
throw new Exception(_('Invalid start time: ') . $from . '.'); throw new Exception($this->localeManager->t('Invalid start time: ') . $from . '.');
} }
$afterArguments[] = '-ss'; $afterArguments[] = '-ss';
$afterArguments[] = $from; $afterArguments[] = $from;
} }
if (!empty($to)) { if (!empty($to)) {
if (!preg_match($durationRegex, $to)) { if (!preg_match($durationRegex, $to)) {
throw new Exception(_('Invalid end time: ') . $to . '.'); throw new Exception($this->localeManager->t('Invalid end time: ') . $to . '.');
} }
$afterArguments[] = '-to'; $afterArguments[] = '-to';
$afterArguments[] = $to; $afterArguments[] = $to;
@ -411,14 +426,14 @@ class Video
public function getAudioStream($from = null, $to = null) public function getAudioStream($from = null, $to = null)
{ {
if (isset($this->_type) && $this->_type == 'playlist') { 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 (isset($this->protocol)) {
if (in_array($this->protocol, ['m3u8', 'm3u8_native'])) { 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') { } 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 +442,7 @@ class Video
$stream = popen($avconvProc->getCommandLine(), 'r'); $stream = popen($avconvProc->getCommandLine(), 'r');
if (!is_resource($stream)) { 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; return $stream;
@ -444,7 +459,11 @@ class Video
public function getM3uStream() public function getM3uStream()
{ {
if (!$this->checkCommand([$this->config->avconv, '-version'])) { 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 '
) . $this->config->avconv . '.'
);
} }
$urls = $this->getUrl(); $urls = $this->getUrl();
@ -464,7 +483,7 @@ class Video
$stream = popen($process->getCommandLine(), 'r'); $stream = popen($process->getCommandLine(), 'r');
if (!is_resource($stream)) { 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; return $stream;
@ -482,7 +501,7 @@ class Video
$urls = $this->getUrl(); $urls = $this->getUrl();
if (!isset($urls[0]) || !isset($urls[1])) { 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( $process = new Process(
@ -501,7 +520,7 @@ class Video
$stream = popen($process->getCommandLine(), 'r'); $stream = popen($process->getCommandLine(), 'r');
if (!is_resource($stream)) { 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; return $stream;
@ -534,7 +553,7 @@ class Video
); );
$stream = popen($process->getCommandLine(), 'r'); $stream = popen($process->getCommandLine(), 'r');
if (!is_resource($stream)) { 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; return $stream;
@ -554,7 +573,7 @@ class Video
public function getConvertedStream($audioBitrate, $filetype) public function getConvertedStream($audioBitrate, $filetype)
{ {
if (in_array($this->protocol, ['m3u8', 'm3u8_native'])) { 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); $avconvProc = $this->getAvconvProcess($audioBitrate, $filetype, false);
@ -562,7 +581,7 @@ class Video
$stream = popen($avconvProc->getCommandLine(), 'r'); $stream = popen($avconvProc->getCommandLine(), 'r');
if (!is_resource($stream)) { 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; return $stream;

View file

@ -35,9 +35,12 @@ class ViewFactory
$request = $request->withUri($request->getUri()->withScheme('https')->withPort(443)); $request = $request->withUri($request->getUri()->withScheme('https')->withPort(443));
} }
$localeManager = $container['locale'];
$smartyPlugins = new SmartyPlugins($container['router'], $request->getUri()->withUserInfo(null)); $smartyPlugins = new SmartyPlugins($container['router'], $request->getUri()->withUserInfo(null));
$view->registerPlugin('function', 'path_for', [$smartyPlugins, 'pathFor']); $view->registerPlugin('function', 'path_for', [$smartyPlugins, 'pathFor']);
$view->registerPlugin('function', 'base_url', [$smartyPlugins, 'baseUrl']); $view->registerPlugin('function', 'base_url', [$smartyPlugins, 'baseUrl']);
$view->registerPlugin('block', 't', [$localeManager, 'smartyTranslate']);
return $view; return $view;
} }

View file

@ -12,12 +12,12 @@
"guzzlehttp/guzzle": "~6.3.0", "guzzlehttp/guzzle": "~6.3.0",
"aura/session": "~2.1.0", "aura/session": "~2.1.0",
"barracudanetworks/archivestream-php": "~1.0.5", "barracudanetworks/archivestream-php": "~1.0.5",
"smarty-gettext/smarty-gettext": "~1.6.0",
"zonuexe/http-accept-language": "~0.4.1", "zonuexe/http-accept-language": "~0.4.1",
"rinvex/countries": "~3.1.0", "rinvex/countries": "~3.1.0",
"php-mock/php-mock-mockery": "~1.3.0", "php-mock/php-mock-mockery": "~1.3.0",
"ext-xsl": "*", "ext-xsl": "*",
"jawira/case-converter": "^1.2" "jawira/case-converter": "^1.2",
"symfony/translation": "^3.4"
}, },
"require-dev": { "require-dev": {
"symfony/var-dumper": "~3.4.1", "symfony/var-dumper": "~3.4.1",
@ -28,7 +28,8 @@
"heroku/heroku-buildpack-php": "^162.0", "heroku/heroku-buildpack-php": "^162.0",
"anam/phantomjs-linux-x86-binary": "~2.1.1", "anam/phantomjs-linux-x86-binary": "~2.1.1",
"phpstan/phpstan": "~0.9.2", "phpstan/phpstan": "~0.9.2",
"roave/security-advisories": "dev-master" "roave/security-advisories": "dev-master",
"smarty-gettext/smarty-gettext": "^1.6"
}, },
"extra": { "extra": {
"paas": { "paas": {
@ -91,7 +92,7 @@
"compile": "composer install --ignore-platform-reqs", "compile": "composer install --ignore-platform-reqs",
"update-locales": [ "update-locales": [
"tsmarty2c.php templates > i18n/template.pot", "tsmarty2c.php templates > i18n/template.pot",
"xgettext --omit-header -j -o i18n/template.pot classes/*.php classes/*/*.php 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" "youtube-dl": "vendor/rg3/youtube-dl/youtube_dl/__main__.py"
}, },

301
composer.lock generated
View file

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "c92febd7767c29a4160d24a434ba0d4a", "content-hash": "c773a24c670cb4c431217ea94f03b942",
"packages": [ "packages": [
{ {
"name": "aura/session", "name": "aura/session",
@ -137,6 +137,7 @@
], ],
"description": "Promoting the interoperability of container objects (DIC, SL, etc.)", "description": "Promoting the interoperability of container objects (DIC, SL, etc.)",
"homepage": "https://github.com/container-interop/container-interop", "homepage": "https://github.com/container-interop/container-interop",
"abandoned": "psr/container",
"time": "2017-02-14T19:40:03+00:00" "time": "2017-02-14T19:40:03+00:00"
}, },
{ {
@ -1122,61 +1123,6 @@
], ],
"time": "2019-04-16T16:47:29+00:00" "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", "name": "smarty/smarty",
"version": "v3.1.33", "version": "v3.1.33",
@ -1288,6 +1234,65 @@
], ],
"time": "2019-02-06T07:57:58+00:00" "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", "name": "symfony/process",
"version": "v3.4.29", "version": "v3.4.29",
@ -1337,6 +1342,76 @@
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2019-05-30T15:47:52+00:00" "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", "name": "symfony/yaml",
"version": "v3.4.29", "version": "v3.4.29",
@ -3873,6 +3948,61 @@
"homepage": "https://github.com/sebastianbergmann/version", "homepage": "https://github.com/sebastianbergmann/version",
"time": "2016-10-03T07:35:21+00:00" "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", "name": "squizlabs/php_codesniffer",
"version": "3.5.0", "version": "3.5.0",
@ -4101,65 +4231,6 @@
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2019-05-30T15:47:52+00:00" "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", "name": "symfony/var-dumper",
"version": "v3.4.29", "version": "v3.4.29",

View file

@ -7,6 +7,7 @@
namespace Alltube\Controller; namespace Alltube\Controller;
use Alltube\Config; use Alltube\Config;
use Alltube\LocaleManager;
use Alltube\SessionManager; use Alltube\SessionManager;
use Alltube\Video; use Alltube\Video;
use Aura\Session\Segment; use Aura\Session\Segment;
@ -53,6 +54,13 @@ abstract class BaseController
*/ */
protected $sessionSegment; protected $sessionSegment;
/**
* LocaleManager instance.
*
* @var LocaleManager
*/
protected $localeManager;
/** /**
* BaseController constructor. * BaseController constructor.
* *
@ -64,6 +72,7 @@ abstract class BaseController
$this->container = $container; $this->container = $container;
$session = SessionManager::getSession(); $session = SessionManager::getSession();
$this->sessionSegment = $session->getSegment(self::class); $this->sessionSegment = $session->getSegment(self::class);
$this->localeManager = $this->container->get('locale');
if ($this->config->stream) { if ($this->config->stream) {
$this->defaultFormat = 'best'; $this->defaultFormat = 'best';

View file

@ -212,7 +212,7 @@ class DownloadController extends BaseController
private function getRemuxStream(Request $request, Response $response) private function getRemuxStream(Request $request, Response $response)
{ {
if (!$this->config->remux) { 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(); $stream = $this->video->getRemuxStream();
$response = $response->withHeader('Content-Type', 'video/x-matroska'); $response = $response->withHeader('Content-Type', 'video/x-matroska');
@ -252,7 +252,7 @@ class DownloadController extends BaseController
return $this->getStream($request, $response); return $this->getStream($request, $response);
} else { } else {
if (empty($videoUrls[0])) { 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]); return $response->withRedirect($videoUrls[0]);

View file

@ -8,7 +8,6 @@ namespace Alltube\Controller;
use Alltube\Exception\PasswordException; use Alltube\Exception\PasswordException;
use Alltube\Locale; use Alltube\Locale;
use Alltube\LocaleManager;
use Alltube\Video; use Alltube\Video;
use Exception; use Exception;
use Psr\Container\ContainerInterface; use Psr\Container\ContainerInterface;
@ -30,13 +29,6 @@ class FrontController extends BaseController
*/ */
private $view; private $view;
/**
* LocaleManager instance.
*
* @var LocaleManager
*/
private $localeManager;
/** /**
* BaseController constructor. * BaseController constructor.
* *
@ -46,7 +38,6 @@ class FrontController extends BaseController
{ {
parent::__construct($container); parent::__construct($container);
$this->localeManager = $this->container->get('locale');
$this->view = $this->container->get('view'); $this->view = $this->container->get('view');
} }
@ -67,7 +58,9 @@ class FrontController extends BaseController
[ [
'config' => $this->config, 'config' => $this->config,
'class' => 'index', '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(), 'domain' => $uri->getScheme() . '://' . $uri->getAuthority(),
'canonical' => $this->getCanonicalUrl($request), 'canonical' => $this->getCanonicalUrl($request),
'supportedLocales' => $this->localeManager->getSupportedLocales(), 'supportedLocales' => $this->localeManager->getSupportedLocales(),
@ -111,8 +104,8 @@ class FrontController extends BaseController
'config' => $this->config, 'config' => $this->config,
'extractors' => Video::getExtractors(), 'extractors' => Video::getExtractors(),
'class' => 'extractors', 'class' => 'extractors',
'title' => _('Supported websites'), 'title' => $this->localeManager->t('Supported websites'),
'description' => _('List of all supported websites from which Alltube Download ' . 'description' => $this->localeManager->t('List of all supported websites from which Alltube Download ' .
'can extract video or audio files'), 'can extract video or audio files'),
'canonical' => $this->getCanonicalUrl($request), 'canonical' => $this->getCanonicalUrl($request),
'locale' => $this->localeManager->getLocale(), 'locale' => $this->localeManager->getLocale(),
@ -138,8 +131,10 @@ class FrontController extends BaseController
[ [
'config' => $this->config, 'config' => $this->config,
'class' => 'password', 'class' => 'password',
'title' => _('Password prompt'), 'title' => $this->localeManager->t('Password prompt'),
'description' => _('You need a password in order to download this video with Alltube Download'), 'description' => $this->localeManager->t(
'You need a password in order to download this video with Alltube Download'
),
'canonical' => $this->getCanonicalUrl($request), 'canonical' => $this->getCanonicalUrl($request),
'locale' => $this->localeManager->getLocale(), 'locale' => $this->localeManager->getLocale(),
] ]
@ -169,12 +164,12 @@ class FrontController extends BaseController
} else { } else {
$template = 'info.tpl'; $template = 'info.tpl';
} }
$title = _('Video download'); $title = $this->localeManager->t('Video download');
$description = _('Download video from ') . $this->video->extractor_key; $description = $this->localeManager->t('Download video from ') . $this->video->extractor_key;
if (isset($this->video->title)) { if (isset($this->video->title)) {
$title = $this->video->title; $title = $this->video->title;
$description = _('Download') . ' "' . $this->video->title . '" ' . $description = $this->localeManager->t('Download') . ' "' . $this->video->title . '" ' .
_('from') . ' ' . $this->video->extractor_key; $this->localeManager->t('from') . ' ' . $this->video->extractor_key;
} }
$this->view->render( $this->view->render(
$response, $response,
@ -245,7 +240,7 @@ class FrontController extends BaseController
'config' => $this->config, 'config' => $this->config,
'errors' => $exception->getMessage(), 'errors' => $exception->getMessage(),
'class' => 'video', 'class' => 'video',
'title' => _('Error'), 'title' => $this->localeManager->t('Error'),
'canonical' => $this->getCanonicalUrl($request), 'canonical' => $this->getCanonicalUrl($request),
'locale' => $this->localeManager->getLocale(), 'locale' => $this->localeManager->getLocale(),
] ]

View file

@ -10,7 +10,7 @@ msgid ":"
msgstr "" msgstr ""
#: templates/playlist.tpl:30 templates/password.tpl:11 templates/index.tpl:19 #: templates/playlist.tpl:30 templates/password.tpl:11 templates/index.tpl:19
#: templates/info.tpl:94 controllers/FrontController.php:175 #: templates/info.tpl:94 controllers/FrontController.php:176
msgid "Download" msgid "Download"
msgstr "" msgstr ""
@ -22,15 +22,15 @@ msgstr ""
msgid "Switch language" msgid "Switch language"
msgstr "" msgstr ""
#: templates/inc/header.tpl:21 #: templates/inc/header.tpl:30
msgid "Share on Twitter" msgid "Share on Twitter"
msgstr "" msgstr ""
#: templates/inc/header.tpl:21 templates/inc/header.tpl:24 #: templates/inc/header.tpl:30 templates/inc/header.tpl:33
msgid "(opens a new window)" msgid "(opens a new window)"
msgstr "" msgstr ""
#: templates/inc/header.tpl:24 #: templates/inc/header.tpl:33
msgid "Share on Facebook" msgid "Share on Facebook"
msgstr "" msgstr ""
@ -146,60 +146,60 @@ msgstr ""
msgid "Please check the URL of your video." msgid "Please check the URL of your video."
msgstr "" msgstr ""
#: templates/extractors.tpl:4 controllers/FrontController.php:113 #: templates/extractors.tpl:4 controllers/FrontController.php:114
msgid "Supported websites" msgid "Supported websites"
msgstr "" msgstr ""
#: classes/Config.php:150 #: classes/Config.php:153
msgid "Best" msgid "Best"
msgstr "" msgstr ""
#: classes/Config.php:151 #: classes/Config.php:154
msgid "Remux best video with best audio" msgid "Remux best video with best audio"
msgstr "" msgstr ""
#: classes/Config.php:152 #: classes/Config.php:155
msgid "Worst" msgid "Worst"
msgstr "" msgstr ""
#: classes/Video.php:148 #: classes/Video.php:156
msgid "Wrong password" msgid "Wrong password"
msgstr "" msgstr ""
#: classes/Video.php:239 #: classes/Video.php:247
msgid "youtube-dl returned an empty URL." msgid "youtube-dl returned an empty URL."
msgstr "" msgstr ""
#: classes/Video.php:348 classes/Video.php:447 #: classes/Video.php:356 classes/Video.php:455
msgid "Can't find avconv or ffmpeg at " msgid "Can't find avconv or ffmpeg at "
msgstr "" msgstr ""
#: classes/Video.php:361 #: classes/Video.php:369
msgid "Invalid start time: " msgid "Invalid start time: "
msgstr "" msgstr ""
#: classes/Video.php:368 #: classes/Video.php:376
msgid "Invalid end time: " msgid "Invalid end time: "
msgstr "" msgstr ""
#: classes/Video.php:414 #: classes/Video.php:422
msgid "Conversion of playlists is not supported." msgid "Conversion of playlists is not supported."
msgstr "" msgstr ""
#: classes/Video.php:419 classes/Video.php:557 #: classes/Video.php:427 classes/Video.php:565
msgid "Conversion of M3U8 files is not supported." msgid "Conversion of M3U8 files is not supported."
msgstr "" msgstr ""
#: classes/Video.php:421 #: classes/Video.php:429
msgid "Conversion of DASH segments is not supported." msgid "Conversion of DASH segments is not supported."
msgstr "" msgstr ""
#: classes/Video.php:430 classes/Video.php:467 classes/Video.php:504 #: classes/Video.php:438 classes/Video.php:475 classes/Video.php:512
#: classes/Video.php:537 classes/Video.php:565 #: classes/Video.php:545 classes/Video.php:573
msgid "Could not open popen stream." msgid "Could not open popen stream."
msgstr "" msgstr ""
#: classes/Video.php:485 #: classes/Video.php:493
msgid "This video does not have two URLs." msgid "This video does not have two URLs."
msgstr "" msgstr ""
@ -211,38 +211,38 @@ msgstr ""
msgid "Can't find URL of video." msgid "Can't find URL of video."
msgstr "" msgstr ""
#: controllers/FrontController.php:69 #: controllers/FrontController.php:70
msgid "" msgid ""
"Easily download videos from Youtube, Dailymotion, Vimeo and other websites." "Easily download videos from Youtube, Dailymotion, Vimeo and other websites."
msgstr "" msgstr ""
#: controllers/FrontController.php:114 #: controllers/FrontController.php:115
msgid "" msgid ""
"List of all supported websites from which Alltube Download can extract video " "List of all supported websites from which Alltube Download can extract video "
"or audio files" "or audio files"
msgstr "" msgstr ""
#: controllers/FrontController.php:140 #: controllers/FrontController.php:141
msgid "Password prompt" msgid "Password prompt"
msgstr "" msgstr ""
#: controllers/FrontController.php:141 #: controllers/FrontController.php:142
msgid "" msgid ""
"You need a password in order to download this video with Alltube Download" "You need a password in order to download this video with Alltube Download"
msgstr "" msgstr ""
#: controllers/FrontController.php:171 #: controllers/FrontController.php:172
msgid "Video download" msgid "Video download"
msgstr "" msgstr ""
#: controllers/FrontController.php:172 #: controllers/FrontController.php:173
msgid "Download video from " msgid "Download video from "
msgstr "" msgstr ""
#: controllers/FrontController.php:176 #: controllers/FrontController.php:177
msgid "from" msgid "from"
msgstr "" msgstr ""
#: controllers/FrontController.php:243 #: controllers/FrontController.php:248
msgid "Error" msgid "Error"
msgstr "" msgstr ""

View file

@ -32,14 +32,14 @@ if ($config->debug) {
Debug::enable(); Debug::enable();
} }
$container['view'] = ViewFactory::create($container);
if (!class_exists('Locale')) { if (!class_exists('Locale')) {
die('You need to install the intl extension for PHP.'); die('You need to install the intl extension for PHP.');
} }
$container['locale'] = new LocaleManager(); $container['locale'] = LocaleManager::getInstance();
$app->add(new LocaleMiddleware($container)); $app->add(new LocaleMiddleware($container));
$container['view'] = ViewFactory::create($container);
$frontController = new FrontController($container); $frontController = new FrontController($container);
$jsonController = new JsonController($container); $jsonController = new JsonController($container);
$downloadController = new DownloadController($container); $downloadController = new DownloadController($container);

View file

@ -1,4 +1,3 @@
{locale path="../i18n" domain="Alltube"}
<!doctype html> <!doctype html>
<html {if isset($locale)}lang="{$locale->getBcp47()}"{/if}> <html {if isset($locale)}lang="{$locale->getBcp47()}"{/if}>
<head> <head>

View file

@ -2,7 +2,7 @@
{if isset($supportedLocales) AND count($supportedLocales) > 1} {if isset($supportedLocales) AND count($supportedLocales) > 1}
<div class="locales small-font"> <div class="locales small-font">
<button class="localesBtn small-font" title="{t}Switch language{/t}"> <button class="localesBtn small-font" title="{t}Switch language{/t}">
{if isset($locale)} {if isset($locale) AND $locale->getCountry()}
{$locale->getCountry()->getEmoji()} {$locale->getCountry()->getEmoji()}
{else} {else}
Set language Set language
@ -11,7 +11,16 @@
<ul class="supportedLocales"> <ul class="supportedLocales">
{foreach $supportedLocales as $supportedLocale} {foreach $supportedLocales as $supportedLocale}
{if $supportedLocale != $locale} {if $supportedLocale != $locale}
<li><a hreflang="{$supportedLocale->getBcp47()}" lang="{$supportedLocale->getBcp47()}" href="{path_for name='locale' data=['locale'=>$supportedLocale->getIso15897()]}">{$supportedLocale->getCountry()->getEmoji()} {$supportedLocale->getFullName()|ucfirst}</a></li> <li>
<a hreflang="{$supportedLocale->getBcp47()}"
lang="{$supportedLocale->getBcp47()}"
href="{path_for name='locale' data=['locale'=>$supportedLocale->getIso15897()]}">
{if $supportedLocale->getCountry()}
{$supportedLocale->getCountry()->getEmoji()}
{/if}
{$supportedLocale->getFullName()|ucfirst}
</a>
</li>
{/if} {/if}
{/foreach} {/foreach}
</ul> </ul>