Merge branch 'release-2.3.0'
This commit is contained in:
commit
c136534723
50 changed files with 1010 additions and 858 deletions
|
@ -26,7 +26,9 @@ FileETag None
|
||||||
</ifmodule>
|
</ifmodule>
|
||||||
|
|
||||||
<ifmodule mod_filter.c>
|
<ifmodule mod_filter.c>
|
||||||
AddOutputFilterByType DEFLATE text/css text/html application/javascript font/truetype
|
<IfModule mod_deflate.c>
|
||||||
|
AddOutputFilterByType DEFLATE text/css text/html application/javascript font/truetype
|
||||||
|
</IfModule>
|
||||||
</ifmodule>
|
</ifmodule>
|
||||||
|
|
||||||
<ifmodule mod_headers.c>
|
<ifmodule mod_headers.c>
|
||||||
|
|
10
.travis.yml
10
.travis.yml
|
@ -2,10 +2,10 @@
|
||||||
language: php
|
language: php
|
||||||
php: 7.3
|
php: 7.3
|
||||||
addons:
|
addons:
|
||||||
apt:
|
apt:
|
||||||
packages:
|
packages:
|
||||||
- language-pack-fr
|
- language-pack-fr
|
||||||
install: composer install --no-progress
|
install: composer install --no-progress
|
||||||
script:
|
script:
|
||||||
- composer lint
|
- composer lint
|
||||||
- composer test
|
- composer test
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
namespace Alltube;
|
namespace Alltube;
|
||||||
|
|
||||||
use Exception;
|
use Exception;
|
||||||
|
use Jawira\CaseConverter\CaseConverterException;
|
||||||
use Symfony\Component\Yaml\Yaml;
|
use Symfony\Component\Yaml\Yaml;
|
||||||
use Jawira\CaseConverter\Convert;
|
use Jawira\CaseConverter\Convert;
|
||||||
|
|
||||||
|
@ -39,7 +40,7 @@ class Config
|
||||||
/**
|
/**
|
||||||
* youtube-dl parameters.
|
* youtube-dl parameters.
|
||||||
*
|
*
|
||||||
* @var array
|
* @var string[]
|
||||||
*/
|
*/
|
||||||
public $params = ['--no-warnings', '--ignore-errors', '--flat-playlist', '--restrict-filenames', '--no-playlist'];
|
public $params = ['--no-warnings', '--ignore-errors', '--flat-playlist', '--restrict-filenames', '--no-playlist'];
|
||||||
|
|
||||||
|
@ -60,7 +61,7 @@ class Config
|
||||||
/**
|
/**
|
||||||
* List of formats available in advanced conversion mode.
|
* List of formats available in advanced conversion mode.
|
||||||
*
|
*
|
||||||
* @var array
|
* @var string[]
|
||||||
*/
|
*/
|
||||||
public $convertAdvancedFormats = ['mp3', 'avi', 'flv', 'wav'];
|
public $convertAdvancedFormats = ['mp3', 'avi', 'flv', 'wav'];
|
||||||
|
|
||||||
|
@ -121,17 +122,10 @@ class Config
|
||||||
*/
|
*/
|
||||||
public $appName = 'AllTube Download';
|
public $appName = 'AllTube Download';
|
||||||
|
|
||||||
/**
|
|
||||||
* YAML config file path.
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
private $file;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generic formats supported by youtube-dl.
|
* Generic formats supported by youtube-dl.
|
||||||
*
|
*
|
||||||
* @var array
|
* @var string[]
|
||||||
*/
|
*/
|
||||||
public $genericFormats = [];
|
public $genericFormats = [];
|
||||||
|
|
||||||
|
@ -145,7 +139,8 @@ class Config
|
||||||
/**
|
/**
|
||||||
* Config constructor.
|
* Config constructor.
|
||||||
*
|
*
|
||||||
* @param array $options Options
|
* @param mixed[] $options Options
|
||||||
|
* @throws CaseConverterException
|
||||||
*/
|
*/
|
||||||
private function __construct(array $options = [])
|
private function __construct(array $options = [])
|
||||||
{
|
{
|
||||||
|
@ -156,9 +151,9 @@ class Config
|
||||||
if (empty($this->genericFormats)) {
|
if (empty($this->genericFormats)) {
|
||||||
// We don't put this in the class definition so it can be detected by xgettext.
|
// We don't put this in the class definition so it can be detected by xgettext.
|
||||||
$this->genericFormats = [
|
$this->genericFormats = [
|
||||||
'best' => $localeManager->t('Best'),
|
'best' => $localeManager->t('Best'),
|
||||||
'bestvideo+bestaudio' => $localeManager->t('Remux best video with best audio'),
|
'bestvideo+bestaudio' => $localeManager->t('Remux best video with best audio'),
|
||||||
'worst' => $localeManager->t('Worst'),
|
'worst' => $localeManager->t('Worst'),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,10 +190,10 @@ class Config
|
||||||
/**
|
/**
|
||||||
* Throw an exception if some of the options are invalid.
|
* Throw an exception if some of the options are invalid.
|
||||||
*
|
*
|
||||||
* @throws Exception If youtube-dl is missing
|
* @return void
|
||||||
* @throws Exception If Python is missing
|
* @throws Exception If Python is missing
|
||||||
*
|
*
|
||||||
* @return void
|
* @throws Exception If youtube-dl is missing
|
||||||
*/
|
*/
|
||||||
private function validateOptions()
|
private function validateOptions()
|
||||||
{
|
{
|
||||||
|
@ -216,7 +211,7 @@ class Config
|
||||||
/**
|
/**
|
||||||
* Apply the provided options.
|
* Apply the provided options.
|
||||||
*
|
*
|
||||||
* @param array $options Options
|
* @param mixed[] $options Options
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
|
@ -235,6 +230,7 @@ class Config
|
||||||
* If the value is an array, you should use the YAML format: "CONVERT_ADVANCED_FORMATS='[foo, bar]'"
|
* If the value is an array, you should use the YAML format: "CONVERT_ADVANCED_FORMATS='[foo, bar]'"
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
|
* @throws CaseConverterException
|
||||||
*/
|
*/
|
||||||
private function getEnv()
|
private function getEnv()
|
||||||
{
|
{
|
||||||
|
@ -265,11 +261,13 @@ class Config
|
||||||
* Set options from a YAML file.
|
* Set options from a YAML file.
|
||||||
*
|
*
|
||||||
* @param string $file Path to the YAML file
|
* @param string $file Path to the YAML file
|
||||||
|
* @return void
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public static function setFile($file)
|
public static function setFile($file)
|
||||||
{
|
{
|
||||||
if (is_file($file)) {
|
if (is_file($file)) {
|
||||||
$options = Yaml::parse(file_get_contents($file));
|
$options = Yaml::parse(strval(file_get_contents($file)));
|
||||||
self::$instance = new self($options);
|
self::$instance = new self($options);
|
||||||
self::$instance->validateOptions();
|
self::$instance->validateOptions();
|
||||||
} else {
|
} else {
|
||||||
|
@ -280,8 +278,10 @@ class Config
|
||||||
/**
|
/**
|
||||||
* Manually set some options.
|
* Manually set some options.
|
||||||
*
|
*
|
||||||
* @param array $options Options (see `config/config.example.yml` for available options)
|
* @param mixed[] $options Options (see `config/config.example.yml` for available options)
|
||||||
* @param bool $update True to update an existing instance
|
* @param bool $update True to update an existing instance
|
||||||
|
* @return void
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public static function setOptions(array $options, $update = true)
|
public static function setOptions(array $options, $update = true)
|
||||||
{
|
{
|
||||||
|
|
|
@ -104,12 +104,14 @@ class Locale
|
||||||
/**
|
/**
|
||||||
* Get country information from locale.
|
* Get country information from locale.
|
||||||
*
|
*
|
||||||
* @return Country|array
|
* @return Country|Country[]|null
|
||||||
*/
|
*/
|
||||||
public function getCountry()
|
public function getCountry()
|
||||||
{
|
{
|
||||||
if (isset($this->region)) {
|
if (isset($this->region)) {
|
||||||
return country($this->getIso3166());
|
return country($this->getIso3166());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
namespace Alltube;
|
namespace Alltube;
|
||||||
|
|
||||||
use Aura\Session\Segment;
|
use Aura\Session\Segment;
|
||||||
use Symfony\Component\Process\Process;
|
|
||||||
use Symfony\Component\Translation\Translator;
|
use Symfony\Component\Translation\Translator;
|
||||||
use Symfony\Component\Translation\Loader\PoFileLoader;
|
use Symfony\Component\Translation\Loader\PoFileLoader;
|
||||||
|
|
||||||
|
@ -19,7 +18,7 @@ class LocaleManager
|
||||||
/**
|
/**
|
||||||
* Supported locales.
|
* Supported locales.
|
||||||
*
|
*
|
||||||
* @var array
|
* @var string[]
|
||||||
*/
|
*/
|
||||||
private $supportedLocales = ['en_US', 'fr_FR', 'zh_CN', 'es_ES', 'pt_BR', 'de_DE', 'ar', 'pl_PL', 'tr_TR'];
|
private $supportedLocales = ['en_US', 'fr_FR', 'zh_CN', 'es_ES', 'pt_BR', 'de_DE', 'ar', 'pl_PL', 'tr_TR'];
|
||||||
|
|
||||||
|
@ -112,6 +111,7 @@ class LocaleManager
|
||||||
* Set the current locale.
|
* Set the current locale.
|
||||||
*
|
*
|
||||||
* @param Locale $locale Locale
|
* @param Locale $locale Locale
|
||||||
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function setLocale(Locale $locale)
|
public function setLocale(Locale $locale)
|
||||||
{
|
{
|
||||||
|
@ -122,6 +122,7 @@ class LocaleManager
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unset the current locale.
|
* Unset the current locale.
|
||||||
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function unsetLocale()
|
public function unsetLocale()
|
||||||
{
|
{
|
||||||
|
@ -133,8 +134,8 @@ class LocaleManager
|
||||||
/**
|
/**
|
||||||
* Smarty "t" block.
|
* Smarty "t" block.
|
||||||
*
|
*
|
||||||
* @param array $params Block parameters
|
* @param mixed[] $params Block parameters
|
||||||
* @param string $text Block content
|
* @param string $text Block content
|
||||||
*
|
*
|
||||||
* @return string Translated string
|
* @return string Translated string
|
||||||
*/
|
*/
|
||||||
|
@ -152,6 +153,7 @@ class LocaleManager
|
||||||
*
|
*
|
||||||
* @param string $string String to translate
|
* @param string $string String to translate
|
||||||
*
|
*
|
||||||
|
* @param mixed[] $params
|
||||||
* @return string Translated string
|
* @return string Translated string
|
||||||
*/
|
*/
|
||||||
public function t($string, array $params = [])
|
public function t($string, array $params = [])
|
||||||
|
|
|
@ -36,9 +36,9 @@ class LocaleMiddleware
|
||||||
/**
|
/**
|
||||||
* Test if a locale can be used for the current user.
|
* Test if a locale can be used for the current user.
|
||||||
*
|
*
|
||||||
* @param array $proposedLocale Locale array created by AcceptLanguage::parse()
|
* @param mixed[] $proposedLocale Locale array created by AcceptLanguage::parse()
|
||||||
*
|
*
|
||||||
* @return Locale Locale if chosen, nothing otherwise
|
* @return Locale|null Locale if chosen, nothing otherwise
|
||||||
*/
|
*/
|
||||||
public function testLocale(array $proposedLocale)
|
public function testLocale(array $proposedLocale)
|
||||||
{
|
{
|
||||||
|
@ -52,14 +52,16 @@ class LocaleMiddleware
|
||||||
return new Locale($proposedLocale['language'] . '_' . $proposedLocale['region']);
|
return new Locale($proposedLocale['language'] . '_' . $proposedLocale['region']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main middleware function.
|
* Main middleware function.
|
||||||
*
|
*
|
||||||
* @param Request $request PSR request
|
* @param Request $request PSR request
|
||||||
* @param Response $response PSR response
|
* @param Response $response PSR response
|
||||||
* @param callable $next Next middleware
|
* @param callable $next Next middleware
|
||||||
*
|
*
|
||||||
* @return Response
|
* @return Response
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -21,7 +21,7 @@ class UglyRouter extends Router
|
||||||
*
|
*
|
||||||
* @param ServerRequestInterface $request The current HTTP request object
|
* @param ServerRequestInterface $request The current HTTP request object
|
||||||
*
|
*
|
||||||
* @return array
|
* @return mixed[]
|
||||||
*
|
*
|
||||||
* @link https://github.com/nikic/FastRoute/blob/master/src/Dispatcher.php
|
* @link https://github.com/nikic/FastRoute/blob/master/src/Dispatcher.php
|
||||||
*/
|
*/
|
||||||
|
@ -42,14 +42,14 @@ class UglyRouter extends Router
|
||||||
/**
|
/**
|
||||||
* Build the path for a named route including the base path.
|
* Build the path for a named route including the base path.
|
||||||
*
|
*
|
||||||
* @param string $name Route name
|
* @param string $name Route name
|
||||||
* @param array $data Named argument replacement data
|
* @param string[] $data Named argument replacement data
|
||||||
* @param array $queryParams Optional query string parameters
|
* @param string[] $queryParams Optional query string parameters
|
||||||
*
|
|
||||||
* @throws RuntimeException If named route does not exist
|
|
||||||
* @throws InvalidArgumentException If required data not provided
|
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
|
* @throws InvalidArgumentException If required data not provided
|
||||||
|
*
|
||||||
|
* @throws RuntimeException If named route does not exist
|
||||||
*/
|
*/
|
||||||
public function pathFor($name, array $data = [], array $queryParams = [])
|
public function pathFor($name, array $data = [], array $queryParams = [])
|
||||||
{
|
{
|
||||||
|
|
|
@ -10,7 +10,7 @@ use Alltube\Exception\EmptyUrlException;
|
||||||
use Alltube\Exception\PasswordException;
|
use Alltube\Exception\PasswordException;
|
||||||
use Exception;
|
use Exception;
|
||||||
use GuzzleHttp\Client;
|
use GuzzleHttp\Client;
|
||||||
use GuzzleHttp\Psr7\Response;
|
use Psr\Http\Message\ResponseInterface;
|
||||||
use stdClass;
|
use stdClass;
|
||||||
use Symfony\Component\Process\Process;
|
use Symfony\Component\Process\Process;
|
||||||
|
|
||||||
|
@ -19,16 +19,16 @@ use Symfony\Component\Process\Process;
|
||||||
*
|
*
|
||||||
* Due to the way youtube-dl behaves, this class can also contain information about a playlist.
|
* Due to the way youtube-dl behaves, this class can also contain information about a playlist.
|
||||||
*
|
*
|
||||||
* @property-read string $title Title
|
* @property-read string $title Title
|
||||||
* @property-read string $protocol Network protocol (HTTP, RTMP, etc.)
|
* @property-read string $protocol Network protocol (HTTP, RTMP, etc.)
|
||||||
* @property-read string $url File URL
|
* @property-read string $url File URL
|
||||||
* @property-read string $ext File extension
|
* @property-read string $ext File extension
|
||||||
* @property-read string $extractor_key youtube-dl extractor class used
|
* @property-read string $extractor_key youtube-dl extractor class used
|
||||||
* @property-read array $entries List of videos (if the object contains information about a playlist)
|
* @property-read array $entries List of videos (if the object contains information about a playlist)
|
||||||
* @property-read array $rtmp_conn
|
* @property-read array $rtmp_conn
|
||||||
* @property-read string|null $_type Object type (usually "playlist" or null)
|
* @property-read string|null $_type Object type (usually "playlist" or null)
|
||||||
* @property-read stdClass $downloader_options
|
* @property-read stdClass $downloader_options
|
||||||
* @property-read stdClass $http_headers
|
* @property-read stdClass $http_headers
|
||||||
*/
|
*/
|
||||||
class Video
|
class Video
|
||||||
{
|
{
|
||||||
|
@ -70,7 +70,7 @@ class Video
|
||||||
/**
|
/**
|
||||||
* URLs of the video files.
|
* URLs of the video files.
|
||||||
*
|
*
|
||||||
* @var array
|
* @var string[]
|
||||||
*/
|
*/
|
||||||
private $urls;
|
private $urls;
|
||||||
|
|
||||||
|
@ -84,11 +84,11 @@ class Video
|
||||||
/**
|
/**
|
||||||
* VideoDownload constructor.
|
* VideoDownload constructor.
|
||||||
*
|
*
|
||||||
* @param string $webpageUrl URL of the page containing the video
|
* @param string $webpageUrl URL of the page containing the video
|
||||||
* @param string $requestedFormat Requested video format
|
* @param string $requestedFormat Requested video format
|
||||||
* (can be any format string accepted by youtube-dl,
|
* (can be any format string accepted by youtube-dl,
|
||||||
* including selectors like "[height<=720]")
|
* including selectors like "[height<=720]")
|
||||||
* @param string $password Password
|
* @param string $password Password
|
||||||
*/
|
*/
|
||||||
public function __construct($webpageUrl, $requestedFormat = 'best', $password = null)
|
public function __construct($webpageUrl, $requestedFormat = 'best', $password = null)
|
||||||
{
|
{
|
||||||
|
@ -105,7 +105,7 @@ class Video
|
||||||
*
|
*
|
||||||
* @param string[] $arguments Arguments
|
* @param string[] $arguments Arguments
|
||||||
*
|
*
|
||||||
* @return Process
|
* @return Process<string>
|
||||||
*/
|
*/
|
||||||
private static function getProcess(array $arguments)
|
private static function getProcess(array $arguments)
|
||||||
{
|
{
|
||||||
|
@ -124,7 +124,9 @@ class Video
|
||||||
* List all extractors.
|
* List all extractors.
|
||||||
*
|
*
|
||||||
* @return string[] Extractors
|
* @return string[] Extractors
|
||||||
* */
|
*
|
||||||
|
* @throws PasswordException
|
||||||
|
*/
|
||||||
public static function getExtractors()
|
public static function getExtractors()
|
||||||
{
|
{
|
||||||
$video = new self('');
|
$video = new self('');
|
||||||
|
@ -135,13 +137,13 @@ class Video
|
||||||
/**
|
/**
|
||||||
* Call youtube-dl.
|
* Call youtube-dl.
|
||||||
*
|
*
|
||||||
* @param array $arguments Arguments
|
* @param string[] $arguments Arguments
|
||||||
*
|
*
|
||||||
* @throws PasswordException If the video is protected by a password and no password was specified
|
* @return string Result
|
||||||
* @throws Exception If the password is wrong
|
* @throws Exception If the password is wrong
|
||||||
* @throws Exception If youtube-dl returns an error
|
* @throws Exception If youtube-dl returns an error
|
||||||
*
|
*
|
||||||
* @return string Result
|
* @throws PasswordException If the video is protected by a password and no password was specified
|
||||||
*/
|
*/
|
||||||
private function callYoutubedl(array $arguments)
|
private function callYoutubedl(array $arguments)
|
||||||
{
|
{
|
||||||
|
@ -153,7 +155,7 @@ class Video
|
||||||
$process->run();
|
$process->run();
|
||||||
if (!$process->isSuccessful()) {
|
if (!$process->isSuccessful()) {
|
||||||
$errorOutput = trim($process->getErrorOutput());
|
$errorOutput = trim($process->getErrorOutput());
|
||||||
$exitCode = $process->getExitCode();
|
$exitCode = intval($process->getExitCode());
|
||||||
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') {
|
||||||
|
@ -172,6 +174,7 @@ class Video
|
||||||
* @param string $prop Property
|
* @param string $prop Property
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
|
* @throws PasswordException
|
||||||
*/
|
*/
|
||||||
private function getProp($prop = 'dump-json')
|
private function getProp($prop = 'dump-json')
|
||||||
{
|
{
|
||||||
|
@ -196,7 +199,9 @@ class Video
|
||||||
* Get all information about a video.
|
* Get all information about a video.
|
||||||
*
|
*
|
||||||
* @return stdClass Decoded JSON
|
* @return stdClass Decoded JSON
|
||||||
* */
|
*
|
||||||
|
* @throws PasswordException
|
||||||
|
*/
|
||||||
public function getJson()
|
public function getJson()
|
||||||
{
|
{
|
||||||
if (!isset($this->json)) {
|
if (!isset($this->json)) {
|
||||||
|
@ -212,12 +217,15 @@ class Video
|
||||||
* @param string $name Property
|
* @param string $name Property
|
||||||
*
|
*
|
||||||
* @return mixed
|
* @return mixed
|
||||||
|
* @throws PasswordException
|
||||||
*/
|
*/
|
||||||
public function __get($name)
|
public function __get($name)
|
||||||
{
|
{
|
||||||
if (isset($this->$name)) {
|
if (isset($this->$name)) {
|
||||||
return $this->getJson()->$name;
|
return $this->getJson()->$name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -226,6 +234,7 @@ class Video
|
||||||
* @param string $name Property
|
* @param string $name Property
|
||||||
*
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
|
* @throws PasswordException
|
||||||
*/
|
*/
|
||||||
public function __isset($name)
|
public function __isset($name)
|
||||||
{
|
{
|
||||||
|
@ -240,7 +249,9 @@ class Video
|
||||||
* (eg. bestvideo+bestaudio).
|
* (eg. bestvideo+bestaudio).
|
||||||
*
|
*
|
||||||
* @return string[] URLs of video
|
* @return string[] URLs of video
|
||||||
* */
|
* @throws EmptyUrlException
|
||||||
|
* @throws PasswordException
|
||||||
|
*/
|
||||||
public function getUrl()
|
public function getUrl()
|
||||||
{
|
{
|
||||||
// Cache the URLs.
|
// Cache the URLs.
|
||||||
|
@ -259,7 +270,9 @@ class Video
|
||||||
* Get filename of video file from URL of page.
|
* Get filename of video file from URL of page.
|
||||||
*
|
*
|
||||||
* @return string Filename of extracted video
|
* @return string Filename of extracted video
|
||||||
* */
|
*
|
||||||
|
* @throws PasswordException
|
||||||
|
*/
|
||||||
public function getFilename()
|
public function getFilename()
|
||||||
{
|
{
|
||||||
return trim($this->getProp('get-filename'));
|
return trim($this->getProp('get-filename'));
|
||||||
|
@ -271,23 +284,17 @@ class Video
|
||||||
* @param string $extension New file extension
|
* @param string $extension New file extension
|
||||||
*
|
*
|
||||||
* @return string Filename of extracted video with specified extension
|
* @return string Filename of extracted video with specified extension
|
||||||
|
* @throws PasswordException
|
||||||
*/
|
*/
|
||||||
public function getFileNameWithExtension($extension)
|
public function getFileNameWithExtension($extension)
|
||||||
{
|
{
|
||||||
return html_entity_decode(
|
return str_replace('.' . $this->ext, '.' . $extension, $this->getFilename());
|
||||||
pathinfo(
|
|
||||||
$this->getFilename(),
|
|
||||||
PATHINFO_FILENAME
|
|
||||||
) . '.' . $extension,
|
|
||||||
ENT_COMPAT,
|
|
||||||
'ISO-8859-1'
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return arguments used to run rtmp for a specific video.
|
* Return arguments used to run rtmp for a specific video.
|
||||||
*
|
*
|
||||||
* @return array Arguments
|
* @return string[] Arguments
|
||||||
*/
|
*/
|
||||||
private function getRtmpArguments()
|
private function getRtmpArguments()
|
||||||
{
|
{
|
||||||
|
@ -296,12 +303,12 @@ class Video
|
||||||
if ($this->protocol == 'rtmp') {
|
if ($this->protocol == 'rtmp') {
|
||||||
foreach (
|
foreach (
|
||||||
[
|
[
|
||||||
'url' => '-rtmp_tcurl',
|
'url' => '-rtmp_tcurl',
|
||||||
'webpage_url' => '-rtmp_pageurl',
|
'webpage_url' => '-rtmp_pageurl',
|
||||||
'player_url' => '-rtmp_swfverify',
|
'player_url' => '-rtmp_swfverify',
|
||||||
'flash_version' => '-rtmp_flashver',
|
'flash_version' => '-rtmp_flashver',
|
||||||
'play_path' => '-rtmp_playpath',
|
'play_path' => '-rtmp_playpath',
|
||||||
'app' => '-rtmp_app',
|
'app' => '-rtmp_app',
|
||||||
] as $property => $option
|
] as $property => $option
|
||||||
) {
|
) {
|
||||||
if (isset($this->{$property})) {
|
if (isset($this->{$property})) {
|
||||||
|
@ -324,7 +331,7 @@ class Video
|
||||||
/**
|
/**
|
||||||
* Check if a command runs successfully.
|
* Check if a command runs successfully.
|
||||||
*
|
*
|
||||||
* @param array $command Command and arguments
|
* @param string[] $command Command and arguments
|
||||||
*
|
*
|
||||||
* @return bool False if the command returns an error, true otherwise
|
* @return bool False if the command returns an error, true otherwise
|
||||||
*/
|
*/
|
||||||
|
@ -339,15 +346,15 @@ class Video
|
||||||
/**
|
/**
|
||||||
* Get a process that runs avconv in order to convert a video.
|
* Get a process that runs avconv in order to convert a video.
|
||||||
*
|
*
|
||||||
* @param int $audioBitrate Audio bitrate of the converted file
|
* @param int $audioBitrate Audio bitrate of the converted file
|
||||||
* @param string $filetype Filetype of the converted file
|
* @param string $filetype Filetype of the converted file
|
||||||
* @param bool $audioOnly True to return an audio-only file
|
* @param bool $audioOnly True to return an audio-only file
|
||||||
* @param string $from Start the conversion at this time
|
* @param string $from Start the conversion at this time
|
||||||
* @param string $to End the conversion at this time
|
* @param string $to End the conversion at this time
|
||||||
*
|
*
|
||||||
|
* @return Process<string> Process
|
||||||
* @throws Exception If avconv/ffmpeg is missing
|
* @throws Exception If avconv/ffmpeg is missing
|
||||||
*
|
*
|
||||||
* @return Process Process
|
|
||||||
*/
|
*/
|
||||||
private function getAvconvProcess(
|
private function getAvconvProcess(
|
||||||
$audioBitrate,
|
$audioBitrate,
|
||||||
|
@ -418,12 +425,12 @@ class Video
|
||||||
* Get audio stream of converted video.
|
* Get audio stream of converted video.
|
||||||
*
|
*
|
||||||
* @param string $from Start the conversion at this time
|
* @param string $from Start the conversion at this time
|
||||||
* @param string $to End the conversion at this time
|
* @param string $to End the conversion at this time
|
||||||
*
|
|
||||||
* @throws Exception If your try to convert an M3U8 video
|
|
||||||
* @throws Exception If the popen stream was not created correctly
|
|
||||||
*
|
*
|
||||||
* @return resource popen stream
|
* @return resource popen stream
|
||||||
|
* @throws Exception If the popen stream was not created correctly
|
||||||
|
*
|
||||||
|
* @throws Exception If your try to convert an M3U8 video
|
||||||
*/
|
*/
|
||||||
public function getAudioStream($from = null, $to = null)
|
public function getAudioStream($from = null, $to = null)
|
||||||
{
|
{
|
||||||
|
@ -453,10 +460,10 @@ class Video
|
||||||
/**
|
/**
|
||||||
* Get video stream from an M3U playlist.
|
* Get video stream from an M3U playlist.
|
||||||
*
|
*
|
||||||
* @throws Exception If avconv/ffmpeg is missing
|
* @return resource popen stream
|
||||||
* @throws Exception If the popen stream was not created correctly
|
* @throws Exception If the popen stream was not created correctly
|
||||||
*
|
*
|
||||||
* @return resource popen stream
|
* @throws Exception If avconv/ffmpeg is missing
|
||||||
*/
|
*/
|
||||||
public function getM3uStream()
|
public function getM3uStream()
|
||||||
{
|
{
|
||||||
|
@ -495,9 +502,9 @@ class Video
|
||||||
/**
|
/**
|
||||||
* Get an avconv stream to remux audio and video.
|
* Get an avconv stream to remux audio and video.
|
||||||
*
|
*
|
||||||
|
* @return resource popen stream
|
||||||
* @throws Exception If the popen stream was not created correctly
|
* @throws Exception If the popen stream was not created correctly
|
||||||
*
|
*
|
||||||
* @return resource popen stream
|
|
||||||
*/
|
*/
|
||||||
public function getRemuxStream()
|
public function getRemuxStream()
|
||||||
{
|
{
|
||||||
|
@ -532,9 +539,9 @@ class Video
|
||||||
/**
|
/**
|
||||||
* Get video stream from an RTMP video.
|
* Get video stream from an RTMP video.
|
||||||
*
|
*
|
||||||
|
* @return resource popen stream
|
||||||
* @throws Exception If the popen stream was not created correctly
|
* @throws Exception If the popen stream was not created correctly
|
||||||
*
|
*
|
||||||
* @return resource popen stream
|
|
||||||
*/
|
*/
|
||||||
public function getRtmpStream()
|
public function getRtmpStream()
|
||||||
{
|
{
|
||||||
|
@ -565,13 +572,13 @@ class Video
|
||||||
/**
|
/**
|
||||||
* Get the stream of a converted video.
|
* Get the stream of a converted video.
|
||||||
*
|
*
|
||||||
* @param int $audioBitrate Audio bitrate of the converted file
|
* @param int $audioBitrate Audio bitrate of the converted file
|
||||||
* @param string $filetype Filetype of the converted file
|
* @param string $filetype Filetype of the converted file
|
||||||
*
|
|
||||||
* @throws Exception If your try to convert and M3U8 video
|
|
||||||
* @throws Exception If the popen stream was not created correctly
|
|
||||||
*
|
*
|
||||||
* @return resource popen stream
|
* @return resource popen stream
|
||||||
|
* @throws Exception If the popen stream was not created correctly
|
||||||
|
*
|
||||||
|
* @throws Exception If your try to convert and M3U8 video
|
||||||
*/
|
*/
|
||||||
public function getConvertedStream($audioBitrate, $filetype)
|
public function getConvertedStream($audioBitrate, $filetype)
|
||||||
{
|
{
|
||||||
|
@ -605,21 +612,35 @@ class Video
|
||||||
/**
|
/**
|
||||||
* Get a HTTP response containing the video.
|
* Get a HTTP response containing the video.
|
||||||
*
|
*
|
||||||
* @param array $headers HTTP headers of the request
|
* @param mixed[] $headers HTTP headers of the request
|
||||||
*
|
*
|
||||||
* @return Response
|
* @return ResponseInterface
|
||||||
|
* @throws EmptyUrlException
|
||||||
|
* @throws PasswordException
|
||||||
|
* @link https://github.com/guzzle/guzzle/issues/2640
|
||||||
*/
|
*/
|
||||||
public function getHttpResponse(array $headers = [])
|
public function getHttpResponse(array $headers = [])
|
||||||
{
|
{
|
||||||
$client = new Client();
|
// IDN conversion breaks with Google hosts like https://r3---sn-25glene6.googlevideo.com/.
|
||||||
|
$client = new Client(['idn_conversion' => false]);
|
||||||
$urls = $this->getUrl();
|
$urls = $this->getUrl();
|
||||||
|
$stream_context_options = [];
|
||||||
|
|
||||||
|
if (array_key_exists('Referer', (array)$this->http_headers)) {
|
||||||
|
$stream_context_options = [
|
||||||
|
'http' => [
|
||||||
|
'header' => 'Referer: ' . $this->http_headers->Referer
|
||||||
|
]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
return $client->request(
|
return $client->request(
|
||||||
'GET',
|
'GET',
|
||||||
$urls[0],
|
$urls[0],
|
||||||
[
|
[
|
||||||
'stream' => true,
|
'stream' => true,
|
||||||
'headers' => array_merge((array) $this->http_headers, $headers)
|
'stream_context' => $stream_context_options,
|
||||||
|
'headers' => array_merge((array)$this->http_headers, $headers)
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ use Psr\Container\ContainerInterface;
|
||||||
use Slim\Http\Request;
|
use Slim\Http\Request;
|
||||||
use Slim\Views\Smarty;
|
use Slim\Views\Smarty;
|
||||||
use Slim\Views\SmartyPlugins;
|
use Slim\Views\SmartyPlugins;
|
||||||
|
use SmartyException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create Smarty view object.
|
* Create Smarty view object.
|
||||||
|
@ -20,14 +21,15 @@ class ViewFactory
|
||||||
* Create Smarty view object.
|
* Create Smarty view object.
|
||||||
*
|
*
|
||||||
* @param ContainerInterface $container Slim dependency container
|
* @param ContainerInterface $container Slim dependency container
|
||||||
* @param Request $request PSR-7 request
|
* @param Request $request PSR-7 request
|
||||||
*
|
*
|
||||||
* @return Smarty
|
* @return Smarty
|
||||||
|
* @throws SmartyException
|
||||||
*/
|
*/
|
||||||
public static function create(ContainerInterface $container, Request $request = null)
|
public static function create(ContainerInterface $container, Request $request = null)
|
||||||
{
|
{
|
||||||
if (!isset($request)) {
|
if (!isset($request)) {
|
||||||
$request = $container['request'];
|
$request = $container->get('request');
|
||||||
}
|
}
|
||||||
|
|
||||||
$view = new Smarty(__DIR__ . '/../templates/');
|
$view = new Smarty(__DIR__ . '/../templates/');
|
||||||
|
@ -35,9 +37,10 @@ class ViewFactory
|
||||||
$request = $request->withUri($request->getUri()->withScheme('https')->withPort(443));
|
$request = $request->withUri($request->getUri()->withScheme('https')->withPort(443));
|
||||||
}
|
}
|
||||||
|
|
||||||
$localeManager = $container['locale'];
|
/** @var LocaleManager $localeManager */
|
||||||
|
$localeManager = $container->get('locale');
|
||||||
|
|
||||||
$smartyPlugins = new SmartyPlugins($container['router'], $request->getUri()->withUserInfo(null));
|
$smartyPlugins = new SmartyPlugins($container->get('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']);
|
$view->registerPlugin('block', 't', [$localeManager, 'smartyTranslate']);
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
namespace Alltube\Stream;
|
namespace Alltube\Stream;
|
||||||
|
|
||||||
use Alltube\Video;
|
use Alltube\Video;
|
||||||
|
use Exception;
|
||||||
use Slim\Http\Stream;
|
use Slim\Http\Stream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -20,6 +21,7 @@ class ConvertedPlaylistArchiveStream extends PlaylistArchiveStream
|
||||||
* @param Video $video Video to stream
|
* @param Video $video Video to stream
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
protected function startVideoStream(Video $video)
|
protected function startVideoStream(Video $video)
|
||||||
{
|
{
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
|
|
||||||
namespace Alltube\Stream;
|
namespace Alltube\Stream;
|
||||||
|
|
||||||
|
use Alltube\Exception\EmptyUrlException;
|
||||||
|
use Alltube\Exception\PasswordException;
|
||||||
use Alltube\Video;
|
use Alltube\Video;
|
||||||
use Barracuda\ArchiveStream\ZipArchive;
|
use Barracuda\ArchiveStream\ZipArchive;
|
||||||
use Psr\Http\Message\StreamInterface;
|
use Psr\Http\Message\StreamInterface;
|
||||||
|
@ -48,7 +50,10 @@ class PlaylistArchiveStream extends ZipArchive implements StreamInterface
|
||||||
/**
|
/**
|
||||||
* PlaylistArchiveStream constructor.
|
* PlaylistArchiveStream constructor.
|
||||||
*
|
*
|
||||||
|
* We don't call the parent constructor because it messes up the output buffering.
|
||||||
|
*
|
||||||
* @param Video $video Video/playlist to download
|
* @param Video $video Video/playlist to download
|
||||||
|
* @noinspection PhpMissingParentConstructorInspection
|
||||||
*/
|
*/
|
||||||
public function __construct(Video $video)
|
public function __construct(Video $video)
|
||||||
{
|
{
|
||||||
|
@ -86,20 +91,21 @@ class PlaylistArchiveStream extends ZipArchive implements StreamInterface
|
||||||
*
|
*
|
||||||
* @param string $string The string that is to be written
|
* @param string $string The string that is to be written
|
||||||
*
|
*
|
||||||
* @return int
|
* @return int|false
|
||||||
*/
|
*/
|
||||||
public function write($string)
|
public function write($string)
|
||||||
{
|
{
|
||||||
fwrite($this->buffer, $string);
|
return fwrite($this->buffer, $string);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the size of the stream if known.
|
* Get the size of the stream if known.
|
||||||
*
|
*
|
||||||
* @return null
|
* @return int|null
|
||||||
*/
|
*/
|
||||||
public function getSize()
|
public function getSize()
|
||||||
{
|
{
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -145,7 +151,7 @@ class PlaylistArchiveStream extends ZipArchive implements StreamInterface
|
||||||
/**
|
/**
|
||||||
* Returns the remaining contents in a string.
|
* Returns the remaining contents in a string.
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string|false
|
||||||
*/
|
*/
|
||||||
public function getContents()
|
public function getContents()
|
||||||
{
|
{
|
||||||
|
@ -170,6 +176,8 @@ class PlaylistArchiveStream extends ZipArchive implements StreamInterface
|
||||||
if (isset($meta[$key])) {
|
if (isset($meta[$key])) {
|
||||||
return $meta[$key];
|
return $meta[$key];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -194,7 +202,7 @@ class PlaylistArchiveStream extends ZipArchive implements StreamInterface
|
||||||
{
|
{
|
||||||
$this->rewind();
|
$this->rewind();
|
||||||
|
|
||||||
return $this->getContents();
|
return strval($this->getContents());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -236,6 +244,8 @@ class PlaylistArchiveStream extends ZipArchive implements StreamInterface
|
||||||
* @param Video $video Video to stream
|
* @param Video $video Video to stream
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
|
* @throws PasswordException
|
||||||
|
* @throws EmptyUrlException
|
||||||
*/
|
*/
|
||||||
protected function startVideoStream(Video $video)
|
protected function startVideoStream(Video $video)
|
||||||
{
|
{
|
||||||
|
@ -246,7 +256,7 @@ class PlaylistArchiveStream extends ZipArchive implements StreamInterface
|
||||||
|
|
||||||
$this->init_file_stream_transfer(
|
$this->init_file_stream_transfer(
|
||||||
$video->getFilename(),
|
$video->getFilename(),
|
||||||
$contentLengthHeaders[0]
|
intval($contentLengthHeaders[0])
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,6 +266,8 @@ class PlaylistArchiveStream extends ZipArchive implements StreamInterface
|
||||||
* @param int $count Number of bytes to read
|
* @param int $count Number of bytes to read
|
||||||
*
|
*
|
||||||
* @return string|false
|
* @return string|false
|
||||||
|
* @throws EmptyUrlException
|
||||||
|
* @throws PasswordException
|
||||||
*/
|
*/
|
||||||
public function read($count)
|
public function read($count)
|
||||||
{
|
{
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
namespace Alltube\Stream;
|
namespace Alltube\Stream;
|
||||||
|
|
||||||
use GuzzleHttp\Psr7\Response;
|
use Psr\Http\Message\ResponseInterface;
|
||||||
use Psr\Http\Message\StreamInterface;
|
use Psr\Http\Message\StreamInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -18,16 +18,16 @@ class YoutubeChunkStream implements StreamInterface
|
||||||
/**
|
/**
|
||||||
* HTTP response containing the video chunk.
|
* HTTP response containing the video chunk.
|
||||||
*
|
*
|
||||||
* @var Response
|
* @var ResponseInterface
|
||||||
*/
|
*/
|
||||||
private $response;
|
private $response;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* YoutubeChunkStream constructor.
|
* YoutubeChunkStream constructor.
|
||||||
*
|
*
|
||||||
* @param Response $response HTTP response containing the video chunk
|
* @param ResponseInterface $response HTTP response containing the video chunk
|
||||||
*/
|
*/
|
||||||
public function __construct(Response $response)
|
public function __construct(ResponseInterface $response)
|
||||||
{
|
{
|
||||||
$this->response = $response;
|
$this->response = $response;
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ class YoutubeChunkStream implements StreamInterface
|
||||||
*/
|
*/
|
||||||
public function read($length)
|
public function read($length)
|
||||||
{
|
{
|
||||||
$size = $this->response->getHeader('Content-Length')[0];
|
$size = intval($this->response->getHeader('Content-Length')[0]);
|
||||||
if ($size - $this->tell() < $length) {
|
if ($size - $this->tell() < $length) {
|
||||||
// Don't try to read further than the end of the stream.
|
// Don't try to read further than the end of the stream.
|
||||||
$length = $size - $this->tell();
|
$length = $size - $this->tell();
|
||||||
|
@ -55,7 +55,7 @@ class YoutubeChunkStream implements StreamInterface
|
||||||
*/
|
*/
|
||||||
public function __toString()
|
public function __toString()
|
||||||
{
|
{
|
||||||
return (string) $this->response->getBody();
|
return (string)$this->response->getBody();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -124,21 +124,21 @@ class YoutubeChunkStream implements StreamInterface
|
||||||
* @param int $offset Stream offset
|
* @param int $offset Stream offset
|
||||||
* @param int $whence Specifies how the cursor position will be calculated
|
* @param int $whence Specifies how the cursor position will be calculated
|
||||||
*
|
*
|
||||||
* @return mixed
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function seek($offset, $whence = SEEK_SET)
|
public function seek($offset, $whence = SEEK_SET)
|
||||||
{
|
{
|
||||||
return $this->response->getBody()->seek($offset, $whence);
|
$this->response->getBody()->seek($offset, $whence);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Seek to the beginning of the stream.
|
* Seek to the beginning of the stream.
|
||||||
*
|
*
|
||||||
* @return mixed
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function rewind()
|
public function rewind()
|
||||||
{
|
{
|
||||||
return $this->response->getBody()->rewind();
|
$this->response->getBody()->rewind();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
|
|
||||||
namespace Alltube\Stream;
|
namespace Alltube\Stream;
|
||||||
|
|
||||||
|
use Alltube\Exception\EmptyUrlException;
|
||||||
|
use Alltube\Exception\PasswordException;
|
||||||
use Alltube\Video;
|
use Alltube\Video;
|
||||||
use GuzzleHttp\Psr7\AppendStream;
|
use GuzzleHttp\Psr7\AppendStream;
|
||||||
|
|
||||||
|
@ -19,6 +21,8 @@ class YoutubeStream extends AppendStream
|
||||||
* YoutubeStream constructor.
|
* YoutubeStream constructor.
|
||||||
*
|
*
|
||||||
* @param Video $video Video to stream
|
* @param Video $video Video to stream
|
||||||
|
* @throws EmptyUrlException
|
||||||
|
* @throws PasswordException
|
||||||
*/
|
*/
|
||||||
public function __construct(Video $video)
|
public function __construct(Video $video)
|
||||||
{
|
{
|
||||||
|
@ -31,7 +35,7 @@ class YoutubeStream extends AppendStream
|
||||||
while ($rangeStart < $contentLenghtHeader[0]) {
|
while ($rangeStart < $contentLenghtHeader[0]) {
|
||||||
$rangeEnd = $rangeStart + $video->downloader_options->http_chunk_size;
|
$rangeEnd = $rangeStart + $video->downloader_options->http_chunk_size;
|
||||||
if ($rangeEnd >= $contentLenghtHeader[0]) {
|
if ($rangeEnd >= $contentLenghtHeader[0]) {
|
||||||
$rangeEnd = $contentLenghtHeader[0] - 1;
|
$rangeEnd = intval($contentLenghtHeader[0]) - 1;
|
||||||
}
|
}
|
||||||
$response = $video->getHttpResponse(['Range' => 'bytes=' . $rangeStart . '-' . $rangeEnd]);
|
$response = $video->getHttpResponse(['Range' => 'bytes=' . $rangeStart . '-' . $rangeEnd]);
|
||||||
$this->addStream(new YoutubeChunkStream($response));
|
$this->addStream(new YoutubeChunkStream($response));
|
||||||
|
|
|
@ -5,34 +5,35 @@
|
||||||
"homepage": "http://alltubedownload.net/",
|
"homepage": "http://alltubedownload.net/",
|
||||||
"type": "project",
|
"type": "project",
|
||||||
"require": {
|
"require": {
|
||||||
"aura/session": "~2.1.0",
|
"ext-intl": "*",
|
||||||
"barracudanetworks/archivestream-php": "~1.0.5",
|
"ext-json": "*",
|
||||||
"guzzlehttp/guzzle": "~6.3.0",
|
"aura/session": "^2.1",
|
||||||
|
"barracudanetworks/archivestream-php": "^1.0",
|
||||||
|
"guzzlehttp/guzzle": "^6.5",
|
||||||
"jawira/case-converter": "^3.4",
|
"jawira/case-converter": "^3.4",
|
||||||
"mathmarques/smarty-view": "~1.1.0",
|
"mathmarques/smarty-view": "^1.1",
|
||||||
"npm-asset/open-sans-fontface": "^1.4",
|
"npm-asset/open-sans-fontface": "^1.4",
|
||||||
"rinvex/countries": "~3.1.0",
|
"rinvex/countries": "^6.1",
|
||||||
"slim/slim": "~3.12.1",
|
|
||||||
"symfony/process": "^4.0",
|
"symfony/process": "^4.0",
|
||||||
"symfony/translation": "^4.0",
|
"symfony/translation": "^4.0",
|
||||||
"symfony/yaml": "^4.0",
|
"symfony/yaml": "^4.0",
|
||||||
"zonuexe/http-accept-language": "~0.4.1"
|
"zonuexe/http-accept-language": "^0.4.1"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"anam/phantomjs-linux-x86-binary": "~2.1.1",
|
"anam/phantomjs-linux-x86-binary": "^2.1",
|
||||||
"consolidation/robo": "^2.0",
|
"consolidation/robo": "^2.0",
|
||||||
"ffmpeg/ffmpeg": "^4.1",
|
"ffmpeg/ffmpeg": "^4.1",
|
||||||
"heroku/heroku-buildpack-php": "^162.0",
|
"heroku/heroku-buildpack-php": "^162.0",
|
||||||
"php-mock/php-mock-mockery": "^1.3",
|
"php-mock/php-mock-mockery": "^1.3",
|
||||||
"phpro/grumphp": "^0.17.0",
|
"phpro/grumphp": "^0.18.0",
|
||||||
"phpstan/phpstan": "~0.9.2",
|
"phpstan/phpstan": "^0.12.25",
|
||||||
"phpunit/phpunit": "^8.4",
|
"phpunit/phpunit": "^8.4",
|
||||||
"roave/security-advisories": "dev-master",
|
"roave/security-advisories": "dev-master",
|
||||||
"smarty-gettext/smarty-gettext": "^1.6",
|
"smarty-gettext/smarty-gettext": "^1.6",
|
||||||
"squizlabs/php_codesniffer": "^3.5",
|
"squizlabs/php_codesniffer": "^3.5",
|
||||||
"symfony/debug": "^4.0",
|
"symfony/error-handler": "^5.0",
|
||||||
"symfony/var-dumper": "^4.0",
|
"symfony/var-dumper": "^5.0",
|
||||||
"ytdl-org/youtube-dl": "^2020.02"
|
"ytdl-org/youtube-dl": "^2020.05"
|
||||||
},
|
},
|
||||||
"extra": {
|
"extra": {
|
||||||
"paas": {
|
"paas": {
|
||||||
|
@ -50,10 +51,10 @@
|
||||||
"type": "package",
|
"type": "package",
|
||||||
"package": {
|
"package": {
|
||||||
"name": "ytdl-org/youtube-dl",
|
"name": "ytdl-org/youtube-dl",
|
||||||
"version": "2020.02.16",
|
"version": "2020.05.08",
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://github.com/ytdl-org/youtube-dl/archive/2020.02.16.zip"
|
"url": "https://github.com/ytdl-org/youtube-dl/archive/2020.05.08.zip"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
778
composer.lock
generated
778
composer.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -66,10 +66,12 @@ class DownloadController extends BaseController
|
||||||
/**
|
/**
|
||||||
* Return a converted MP3 file.
|
* Return a converted MP3 file.
|
||||||
*
|
*
|
||||||
* @param Request $request PSR-7 request
|
* @param Request $request PSR-7 request
|
||||||
* @param Response $response PSR-7 response
|
* @param Response $response PSR-7 response
|
||||||
*
|
*
|
||||||
* @return Response HTTP response
|
* @return Response HTTP response
|
||||||
|
* @throws PasswordException
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
private function getConvertedAudioResponse(Request $request, Response $response)
|
private function getConvertedAudioResponse(Request $request, Response $response)
|
||||||
{
|
{
|
||||||
|
@ -100,10 +102,11 @@ class DownloadController extends BaseController
|
||||||
/**
|
/**
|
||||||
* Return the MP3 file.
|
* Return the MP3 file.
|
||||||
*
|
*
|
||||||
* @param Request $request PSR-7 request
|
* @param Request $request PSR-7 request
|
||||||
* @param Response $response PSR-7 response
|
* @param Response $response PSR-7 response
|
||||||
*
|
*
|
||||||
* @return Response HTTP response
|
* @return Response HTTP response
|
||||||
|
* @throws PasswordException
|
||||||
*/
|
*/
|
||||||
private function getAudioResponse(Request $request, Response $response)
|
private function getAudioResponse(Request $request, Response $response)
|
||||||
{
|
{
|
||||||
|
@ -130,7 +133,7 @@ class DownloadController extends BaseController
|
||||||
return $frontController->password($request, $response);
|
return $frontController->password($request, $response);
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
// If MP3 is not available, we convert it.
|
// If MP3 is not available, we convert it.
|
||||||
$this->video = $this->video->withFormat('bestaudio');
|
$this->video = $this->video->withFormat('bestaudio/best');
|
||||||
|
|
||||||
return $this->getConvertedAudioResponse($request, $response);
|
return $this->getConvertedAudioResponse($request, $response);
|
||||||
}
|
}
|
||||||
|
@ -139,10 +142,13 @@ class DownloadController extends BaseController
|
||||||
/**
|
/**
|
||||||
* Get a video/audio stream piped through the server.
|
* Get a video/audio stream piped through the server.
|
||||||
*
|
*
|
||||||
* @param Response $response PSR-7 response
|
* @param Request $request PSR-7 request
|
||||||
* @param Request $request PSR-7 request
|
|
||||||
*
|
*
|
||||||
|
* @param Response $response PSR-7 response
|
||||||
* @return Response HTTP response
|
* @return Response HTTP response
|
||||||
|
* @throws EmptyUrlException
|
||||||
|
* @throws PasswordException
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
private function getStream(Request $request, Response $response)
|
private function getStream(Request $request, Response $response)
|
||||||
{
|
{
|
||||||
|
@ -205,9 +211,11 @@ class DownloadController extends BaseController
|
||||||
* Get a remuxed stream piped through the server.
|
* Get a remuxed stream piped through the server.
|
||||||
*
|
*
|
||||||
* @param Response $response PSR-7 response
|
* @param Response $response PSR-7 response
|
||||||
* @param Request $request PSR-7 request
|
* @param Request $request PSR-7 request
|
||||||
*
|
*
|
||||||
* @return Response HTTP response
|
* @return Response HTTP response
|
||||||
|
* @throws PasswordException
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
private function getRemuxStream(Request $request, Response $response)
|
private function getRemuxStream(Request $request, Response $response)
|
||||||
{
|
{
|
||||||
|
@ -230,10 +238,13 @@ class DownloadController extends BaseController
|
||||||
* Get approriate HTTP response to download query.
|
* Get approriate HTTP response to download query.
|
||||||
* Depends on whether we want to stream, remux or simply redirect.
|
* Depends on whether we want to stream, remux or simply redirect.
|
||||||
*
|
*
|
||||||
* @param Response $response PSR-7 response
|
* @param Request $request PSR-7 request
|
||||||
* @param Request $request PSR-7 request
|
|
||||||
*
|
*
|
||||||
|
* @param Response $response PSR-7 response
|
||||||
* @return Response HTTP response
|
* @return Response HTTP response
|
||||||
|
* @throws EmptyUrlException
|
||||||
|
* @throws PasswordException
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
private function getDownloadResponse(Request $request, Response $response)
|
private function getDownloadResponse(Request $request, Response $response)
|
||||||
{
|
{
|
||||||
|
@ -262,10 +273,12 @@ class DownloadController extends BaseController
|
||||||
/**
|
/**
|
||||||
* Return a converted video file.
|
* Return a converted video file.
|
||||||
*
|
*
|
||||||
* @param Request $request PSR-7 request
|
* @param Request $request PSR-7 request
|
||||||
* @param Response $response PSR-7 response
|
* @param Response $response PSR-7 response
|
||||||
*
|
*
|
||||||
* @return Response HTTP response
|
* @return Response HTTP response
|
||||||
|
* @throws PasswordException
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
private function getConvertedResponse(Request $request, Response $response)
|
private function getConvertedResponse(Request $request, Response $response)
|
||||||
{
|
{
|
||||||
|
|
|
@ -9,15 +9,15 @@ namespace Alltube\Controller;
|
||||||
use Alltube\Exception\PasswordException;
|
use Alltube\Exception\PasswordException;
|
||||||
use Alltube\Locale;
|
use Alltube\Locale;
|
||||||
use Alltube\Video;
|
use Alltube\Video;
|
||||||
|
use Symfony\Component\ErrorHandler\ErrorHandler;
|
||||||
|
use Symfony\Component\ErrorHandler\ErrorRenderer\HtmlErrorRenderer;
|
||||||
|
use Symfony\Component\ErrorHandler\Exception\FlattenException;
|
||||||
use Throwable;
|
use Throwable;
|
||||||
use Exception;
|
use Exception;
|
||||||
use Psr\Container\ContainerInterface;
|
use Psr\Container\ContainerInterface;
|
||||||
use Slim\Container;
|
|
||||||
use Slim\Http\Request;
|
use Slim\Http\Request;
|
||||||
use Slim\Http\Response;
|
use Slim\Http\Response;
|
||||||
use Slim\Views\Smarty;
|
use Slim\Views\Smarty;
|
||||||
use Symfony\Component\Debug\ExceptionHandler;
|
|
||||||
use Symfony\Component\Debug\Exception\FlattenException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main controller.
|
* Main controller.
|
||||||
|
@ -46,7 +46,7 @@ class FrontController extends BaseController
|
||||||
/**
|
/**
|
||||||
* Display index page.
|
* Display index page.
|
||||||
*
|
*
|
||||||
* @param Request $request PSR-7 request
|
* @param Request $request PSR-7 request
|
||||||
* @param Response $response PSR-7 response
|
* @param Response $response PSR-7 response
|
||||||
*
|
*
|
||||||
* @return Response HTTP response
|
* @return Response HTTP response
|
||||||
|
@ -58,15 +58,15 @@ class FrontController extends BaseController
|
||||||
$response,
|
$response,
|
||||||
'index.tpl',
|
'index.tpl',
|
||||||
[
|
[
|
||||||
'config' => $this->config,
|
'config' => $this->config,
|
||||||
'class' => 'index',
|
'class' => 'index',
|
||||||
'description' => $this->localeManager->t(
|
'description' => $this->localeManager->t(
|
||||||
'Easily download videos from Youtube, Dailymotion, Vimeo and other websites.'
|
'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(),
|
||||||
'locale' => $this->localeManager->getLocale(),
|
'locale' => $this->localeManager->getLocale(),
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -76,9 +76,9 @@ class FrontController extends BaseController
|
||||||
/**
|
/**
|
||||||
* Switch locale.
|
* Switch locale.
|
||||||
*
|
*
|
||||||
* @param Request $request PSR-7 request
|
* @param Request $request PSR-7 request
|
||||||
* @param Response $response PSR-7 response
|
* @param Response $response PSR-7 response
|
||||||
* @param array $data Query parameters
|
* @param string[] $data Query parameters
|
||||||
*
|
*
|
||||||
* @return Response
|
* @return Response
|
||||||
*/
|
*/
|
||||||
|
@ -92,10 +92,11 @@ class FrontController extends BaseController
|
||||||
/**
|
/**
|
||||||
* Display a list of extractors.
|
* Display a list of extractors.
|
||||||
*
|
*
|
||||||
* @param Request $request PSR-7 request
|
* @param Request $request PSR-7 request
|
||||||
* @param Response $response PSR-7 response
|
* @param Response $response PSR-7 response
|
||||||
*
|
*
|
||||||
* @return Response HTTP response
|
* @return Response HTTP response
|
||||||
|
* @throws PasswordException
|
||||||
*/
|
*/
|
||||||
public function extractors(Request $request, Response $response)
|
public function extractors(Request $request, Response $response)
|
||||||
{
|
{
|
||||||
|
@ -103,14 +104,14 @@ class FrontController extends BaseController
|
||||||
$response,
|
$response,
|
||||||
'extractors.tpl',
|
'extractors.tpl',
|
||||||
[
|
[
|
||||||
'config' => $this->config,
|
'config' => $this->config,
|
||||||
'extractors' => Video::getExtractors(),
|
'extractors' => Video::getExtractors(),
|
||||||
'class' => 'extractors',
|
'class' => 'extractors',
|
||||||
'title' => $this->localeManager->t('Supported websites'),
|
'title' => $this->localeManager->t('Supported websites'),
|
||||||
'description' => $this->localeManager->t('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(),
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -120,7 +121,7 @@ class FrontController extends BaseController
|
||||||
/**
|
/**
|
||||||
* Display a password prompt.
|
* Display a password prompt.
|
||||||
*
|
*
|
||||||
* @param Request $request PSR-7 request
|
* @param Request $request PSR-7 request
|
||||||
* @param Response $response PSR-7 response
|
* @param Response $response PSR-7 response
|
||||||
*
|
*
|
||||||
* @return Response HTTP response
|
* @return Response HTTP response
|
||||||
|
@ -131,14 +132,14 @@ class FrontController extends BaseController
|
||||||
$response,
|
$response,
|
||||||
'password.tpl',
|
'password.tpl',
|
||||||
[
|
[
|
||||||
'config' => $this->config,
|
'config' => $this->config,
|
||||||
'class' => 'password',
|
'class' => 'password',
|
||||||
'title' => $this->localeManager->t('Password prompt'),
|
'title' => $this->localeManager->t('Password prompt'),
|
||||||
'description' => $this->localeManager->t(
|
'description' => $this->localeManager->t(
|
||||||
'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'
|
||||||
),
|
),
|
||||||
'canonical' => $this->getCanonicalUrl($request),
|
'canonical' => $this->getCanonicalUrl($request),
|
||||||
'locale' => $this->localeManager->getLocale(),
|
'locale' => $this->localeManager->getLocale(),
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -148,7 +149,7 @@ class FrontController extends BaseController
|
||||||
/**
|
/**
|
||||||
* Return the video description page.
|
* Return the video description page.
|
||||||
*
|
*
|
||||||
* @param Request $request PSR-7 request
|
* @param Request $request PSR-7 request
|
||||||
* @param Response $response PSR-7 response
|
* @param Response $response PSR-7 response
|
||||||
*
|
*
|
||||||
* @return Response HTTP response
|
* @return Response HTTP response
|
||||||
|
@ -185,13 +186,13 @@ class FrontController extends BaseController
|
||||||
$response,
|
$response,
|
||||||
$template,
|
$template,
|
||||||
[
|
[
|
||||||
'video' => $this->video,
|
'video' => $this->video,
|
||||||
'class' => 'info',
|
'class' => 'info',
|
||||||
'title' => $title,
|
'title' => $title,
|
||||||
'description' => $description,
|
'description' => $description,
|
||||||
'config' => $this->config,
|
'config' => $this->config,
|
||||||
'canonical' => $this->getCanonicalUrl($request),
|
'canonical' => $this->getCanonicalUrl($request),
|
||||||
'locale' => $this->localeManager->getLocale(),
|
'locale' => $this->localeManager->getLocale(),
|
||||||
'defaultFormat' => $this->defaultFormat,
|
'defaultFormat' => $this->defaultFormat,
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
@ -202,7 +203,7 @@ class FrontController extends BaseController
|
||||||
/**
|
/**
|
||||||
* Dislay information about the video.
|
* Dislay information about the video.
|
||||||
*
|
*
|
||||||
* @param Request $request PSR-7 request
|
* @param Request $request PSR-7 request
|
||||||
* @param Response $response PSR-7 response
|
* @param Response $response PSR-7 response
|
||||||
*
|
*
|
||||||
* @return Response HTTP response
|
* @return Response HTTP response
|
||||||
|
@ -231,18 +232,18 @@ class FrontController extends BaseController
|
||||||
/**
|
/**
|
||||||
* Display an error page.
|
* Display an error page.
|
||||||
*
|
*
|
||||||
* @param Request $request PSR-7 request
|
* @param Request $request PSR-7 request
|
||||||
* @param Response $response PSR-7 response
|
* @param Response $response PSR-7 response
|
||||||
* @param Throwable $error Error to display
|
* @param Throwable $error Error to display
|
||||||
*
|
*
|
||||||
* @return Response HTTP response
|
* @return Response HTTP response
|
||||||
*/
|
*/
|
||||||
public function error(Request $request, Response $response, Throwable $error)
|
public function error(Request $request, Response $response, Throwable $error)
|
||||||
{
|
{
|
||||||
if ($this->config->debug) {
|
if ($this->config->debug) {
|
||||||
$exception = FlattenException::createFromThrowable($error);
|
$renderer = new HtmlErrorRenderer(true);
|
||||||
$handler = new ExceptionHandler();
|
$exception = $renderer->render($error);
|
||||||
$response->getBody()->write($handler->getHtml($exception));
|
$response->getBody()->write($exception->getAsString());
|
||||||
|
|
||||||
return $response->withStatus($exception->getStatusCode());
|
return $response->withStatus($exception->getStatusCode());
|
||||||
} else {
|
} else {
|
||||||
|
@ -256,12 +257,12 @@ class FrontController extends BaseController
|
||||||
$response,
|
$response,
|
||||||
'error.tpl',
|
'error.tpl',
|
||||||
[
|
[
|
||||||
'config' => $this->config,
|
'config' => $this->config,
|
||||||
'error' => $message,
|
'error' => $message,
|
||||||
'class' => 'video',
|
'class' => 'video',
|
||||||
'title' => $this->localeManager->t('Error'),
|
'title' => $this->localeManager->t('Error'),
|
||||||
'canonical' => $this->getCanonicalUrl($request),
|
'canonical' => $this->getCanonicalUrl($request),
|
||||||
'locale' => $this->localeManager->getLocale(),
|
'locale' => $this->localeManager->getLocale(),
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
29
grumphp.yml
29
grumphp.yml
|
@ -1,17 +1,16 @@
|
||||||
---
|
---
|
||||||
parameters:
|
parameters:
|
||||||
ascii: ~
|
ascii: ~
|
||||||
tasks:
|
tasks:
|
||||||
jsonlint: ~
|
jsonlint: ~
|
||||||
xmllint: ~
|
xmllint: ~
|
||||||
yamllint: ~
|
yamllint: ~
|
||||||
composer: ~
|
composer: ~
|
||||||
phpcs:
|
phpcs:
|
||||||
standard: PSR12
|
standard: PSR12
|
||||||
ignore_patterns:
|
ignore_patterns:
|
||||||
- RoboFile.php
|
- RoboFile.php
|
||||||
phpstan:
|
phpstan:
|
||||||
level: max
|
level: max
|
||||||
configuration: phpstan.neon
|
ignore_patterns:
|
||||||
ignore_patterns:
|
- RoboFile.php
|
||||||
- RoboFile.php
|
|
||||||
|
|
21
index.php
21
index.php
|
@ -1,6 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
require_once __DIR__ . '/vendor/autoload.php';
|
require_once __DIR__ . '/vendor/autoload.php';
|
||||||
|
|
||||||
use Alltube\Config;
|
use Alltube\Config;
|
||||||
use Alltube\Controller\DownloadController;
|
use Alltube\Controller\DownloadController;
|
||||||
use Alltube\Controller\FrontController;
|
use Alltube\Controller\FrontController;
|
||||||
|
@ -10,7 +11,8 @@ use Alltube\LocaleMiddleware;
|
||||||
use Alltube\UglyRouter;
|
use Alltube\UglyRouter;
|
||||||
use Alltube\ViewFactory;
|
use Alltube\ViewFactory;
|
||||||
use Slim\App;
|
use Slim\App;
|
||||||
use Symfony\Component\Debug\Debug;
|
use Slim\Container;
|
||||||
|
use Symfony\Component\ErrorHandler\Debug;
|
||||||
|
|
||||||
if (isset($_SERVER['REQUEST_URI']) && strpos($_SERVER['REQUEST_URI'], '/index.php') !== false) {
|
if (isset($_SERVER['REQUEST_URI']) && strpos($_SERVER['REQUEST_URI'], '/index.php') !== false) {
|
||||||
header('Location: ' . str_ireplace('/index.php', '/', $_SERVER['REQUEST_URI']));
|
header('Location: ' . str_ireplace('/index.php', '/', $_SERVER['REQUEST_URI']));
|
||||||
|
@ -18,11 +20,17 @@ if (isset($_SERVER['REQUEST_URI']) && strpos($_SERVER['REQUEST_URI'], '/index.ph
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_file(__DIR__ . '/config/config.yml')) {
|
if (is_file(__DIR__ . '/config/config.yml')) {
|
||||||
Config::setFile(__DIR__ . '/config/config.yml');
|
try {
|
||||||
|
Config::setFile(__DIR__ . '/config/config.yml');
|
||||||
|
} catch (Exception $e) {
|
||||||
|
die('Could not load config file: ' . $e->getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create app.
|
// Create app.
|
||||||
$app = new App();
|
$app = new App();
|
||||||
|
|
||||||
|
/** @var Container $container */
|
||||||
$container = $app->getContainer();
|
$container = $app->getContainer();
|
||||||
|
|
||||||
// Load config.
|
// Load config.
|
||||||
|
@ -47,7 +55,11 @@ $container['locale'] = LocaleManager::getInstance();
|
||||||
$app->add(new LocaleMiddleware($container));
|
$app->add(new LocaleMiddleware($container));
|
||||||
|
|
||||||
// Smarty.
|
// Smarty.
|
||||||
$container['view'] = ViewFactory::create($container);
|
try {
|
||||||
|
$container['view'] = ViewFactory::create($container);
|
||||||
|
} catch (SmartyException $e) {
|
||||||
|
die('Could not load Smarty: ' . $e->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
// Controllers.
|
// Controllers.
|
||||||
$frontController = new FrontController($container);
|
$frontController = new FrontController($container);
|
||||||
|
@ -102,4 +114,7 @@ try {
|
||||||
$app->run();
|
$app->run();
|
||||||
} catch (SmartyException $e) {
|
} catch (SmartyException $e) {
|
||||||
die('Smarty could not compile the template file: ' . $e->getMessage());
|
die('Smarty could not compile the template file: ' . $e->getMessage());
|
||||||
|
} catch (Throwable $e) {
|
||||||
|
// Last resort if the error has not been caught by the error handler for some reason.
|
||||||
|
die('Error when starting the app: ' . $e->getMessage());
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
parameters:
|
|
||||||
ignoreErrors:
|
|
||||||
# The Archive constructor messes up the output buffering.
|
|
||||||
- '#Alltube\\Stream\\PlaylistArchiveStream::__construct\(\) does not call parent constructor from Barracuda\\ArchiveStream\\ZipArchive\.#'
|
|
30
phpunit.xml
30
phpunit.xml
|
@ -1,18 +1,18 @@
|
||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<phpunit bootstrap="tests/bootstrap.php">
|
<phpunit bootstrap="tests/bootstrap.php">
|
||||||
<filter>
|
<filter>
|
||||||
<whitelist>
|
<whitelist>
|
||||||
<directory>classes/</directory>
|
<directory>classes/</directory>
|
||||||
<directory>controllers/</directory>
|
<directory>controllers/</directory>
|
||||||
</whitelist>
|
</whitelist>
|
||||||
</filter>
|
</filter>
|
||||||
<testsuites>
|
<testsuites>
|
||||||
<testsuite name="Tests">
|
<testsuite name="Tests">
|
||||||
<directory>tests/</directory>
|
<directory>tests/</directory>
|
||||||
</testsuite>
|
</testsuite>
|
||||||
</testsuites>
|
</testsuites>
|
||||||
<logging>
|
<logging>
|
||||||
<log type="coverage-html" target="coverage/"/>
|
<log type="coverage-html" target="coverage/"/>
|
||||||
<log type="coverage-clover" target="clover.xml"/>
|
<log type="coverage-clover" target="clover.xml"/>
|
||||||
</logging>
|
</logging>
|
||||||
</phpunit>
|
</phpunit>
|
||||||
|
|
|
@ -1,21 +1,23 @@
|
||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<!DOCTYPE HTML>
|
<!DOCTYPE html>
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
|
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8"/>
|
<meta charset="UTF-8"/>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||||
<title>AllTube Download - Maintenance</title>
|
<title>AllTube Download - Maintenance</title>
|
||||||
<link rel="stylesheet" href="../dist/main.css"/>
|
<link rel="stylesheet" href="../dist/main.css"/>
|
||||||
<link rel="icon" href="../img/favicon.png"/>
|
<link rel="icon" href="../img/favicon.png"/>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
<div class="main">
|
<div class="main">
|
||||||
<h1>
|
<h1>
|
||||||
<img class="logo" src="../img/logo.png" alt="AllTube Download" width="328" height="284"/>
|
<img class="logo" src="../img/logo.png" alt="AllTube Download" width="328" height="284"/>
|
||||||
</h1>
|
</h1>
|
||||||
<div>An error occurred in the application and your page could not be served. Please try again in a few moments.</div>
|
<div>An error occurred in the application and your page could not be served. Please try again in a few
|
||||||
</div>
|
moments.
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</div>
|
||||||
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -1,21 +1,21 @@
|
||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<!DOCTYPE HTML>
|
<!DOCTYPE html>
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
|
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8"/>
|
<meta charset="UTF-8"/>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||||
<title>AllTube Download - Maintenance</title>
|
<title>AllTube Download - Maintenance</title>
|
||||||
<link rel="stylesheet" href="../dist/main.css"/>
|
<link rel="stylesheet" href="../dist/main.css"/>
|
||||||
<link rel="icon" href="../img/favicon.png"/>
|
<link rel="icon" href="../img/favicon.png"/>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
<div class="main">
|
<div class="main">
|
||||||
<h1>
|
<h1>
|
||||||
<img class="logo" src="../img/logo.png" alt="AllTube Download" width="328" height="284"/>
|
<img class="logo" src="../img/logo.png" alt="AllTube Download" width="328" height="284"/>
|
||||||
</h1>
|
</h1>
|
||||||
<div>This application is undergoing maintenance right now. Please check back later.</div>
|
<div>This application is undergoing maintenance right now. Please check back later.</div>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</div>
|
||||||
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||||
<url>
|
<url>
|
||||||
<loc>https://alltubedownload.net/</loc>
|
<loc>https://alltubedownload.net/</loc>
|
||||||
<changefreq>yearly</changefreq>
|
<changefreq>yearly</changefreq>
|
||||||
<priority>1</priority>
|
<priority>1</priority>
|
||||||
</url>
|
</url>
|
||||||
<url>
|
<url>
|
||||||
<loc>https://alltubedownload.net/extractors</loc>
|
<loc>https://alltubedownload.net/extractors</loc>
|
||||||
<changefreq>weekly</changefreq>
|
<changefreq>weekly</changefreq>
|
||||||
</url>
|
</url>
|
||||||
</urlset>
|
</urlset>
|
||||||
|
|
|
@ -6,4 +6,4 @@
|
||||||
{t}Please check the URL of your video.{/t}
|
{t}Please check the URL of your video.{/t}
|
||||||
<p><i>{$error|escape}</i></p>
|
<p><i>{$error|escape}</i></p>
|
||||||
</main>
|
</main>
|
||||||
{include file='inc/footer.tpl'}
|
{include file='inc/footer.tpl'}
|
||||||
|
|
|
@ -3,10 +3,10 @@
|
||||||
{include file='inc/logo.tpl'}
|
{include file='inc/logo.tpl'}
|
||||||
<h2 class="titre">{t}Supported websites{/t}</h2>
|
<h2 class="titre">{t}Supported websites{/t}</h2>
|
||||||
<div class="tripleliste">
|
<div class="tripleliste">
|
||||||
<ul>
|
<ul>
|
||||||
{foreach $extractors as $extractor}
|
{foreach $extractors as $extractor}
|
||||||
<li>{$extractor}</li>
|
<li>{$extractor}</li>
|
||||||
{/foreach}
|
{/foreach}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
{include file='inc/footer.tpl'}
|
{include file='inc/footer.tpl'}
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
·
|
·
|
||||||
|
|
||||||
<a rel="noopener" target="_blank" title="{t}Donate using Liberapay{/t}"
|
<a rel="noopener" target="_blank" title="{t}Donate using Liberapay{/t}"
|
||||||
href="https://liberapay.com/Rudloff/donate">
|
href="https://liberapay.com/Rudloff/donate">
|
||||||
{t}Donate{/t}
|
{t}Donate{/t}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,25 +1,25 @@
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html {if isset($locale)}lang="{$locale->getBcp47()}"{/if}>
|
<html {if isset($locale)}lang="{$locale->getBcp47()}"{/if}>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8"/>
|
||||||
<meta name=viewport content="width=device-width, initial-scale=1">
|
<meta name=viewport content="width=device-width, initial-scale=1">
|
||||||
{if isset($description)}
|
{if isset($description)}
|
||||||
<meta name="description" content="{$description|escape}" />
|
<meta name="description" content="{$description|escape}"/>
|
||||||
<meta name="twitter:description" content="{$description|escape}" />
|
<meta name="twitter:description" content="{$description|escape}"/>
|
||||||
<meta property="og:description" content="{$description|escape}" />
|
<meta property="og:description" content="{$description|escape}"/>
|
||||||
{/if}
|
{/if}
|
||||||
<link rel="stylesheet" href="{base_url}/css/fonts.css" />
|
<link rel="stylesheet" href="{base_url}/css/fonts.css"/>
|
||||||
<link rel="stylesheet" href="{base_url}/css/style.css" />
|
<link rel="stylesheet" href="{base_url}/css/style.css"/>
|
||||||
<title>{$config->appName}{if isset($title)} - {$title|escape}{/if}</title>
|
<title>{$config->appName}{if isset($title)} - {$title|escape}{/if}</title>
|
||||||
<link rel="canonical" href="{$canonical}" />
|
<link rel="canonical" href="{$canonical}"/>
|
||||||
<link rel="icon" href="{base_url}/img/favicon.png" />
|
<link rel="icon" href="{base_url}/img/favicon.png"/>
|
||||||
<meta property="og:title" content="{$config->appName}{if isset($title)} - {$title|escape}{/if}" />
|
<meta property="og:title" content="{$config->appName}{if isset($title)} - {$title|escape}{/if}"/>
|
||||||
<meta property="og:image" content="{base_url}/img/logo.png" />
|
<meta property="og:image" content="{base_url}/img/logo.png"/>
|
||||||
<meta name="twitter:card" content="summary" />
|
<meta name="twitter:card" content="summary"/>
|
||||||
<meta name="twitter:title" content="{$config->appName}{if isset($title)} - {$title|escape}{/if}" />
|
<meta name="twitter:title" content="{$config->appName}{if isset($title)} - {$title|escape}{/if}"/>
|
||||||
<meta name="twitter:image" content="{base_url}/img/logo.png" />
|
<meta name="twitter:image" content="{base_url}/img/logo.png"/>
|
||||||
<meta name="twitter:creator" content="@Tael67" />
|
<meta name="twitter:creator" content="@Tael67"/>
|
||||||
<meta name="theme-color" content="#4F4F4F">
|
<meta name="theme-color" content="#4F4F4F">
|
||||||
<link rel="manifest" href="{base_url}/resources/manifest.json" />
|
<link rel="manifest" href="{base_url}/resources/manifest.json"/>
|
||||||
</head>
|
</head>
|
||||||
<body class="{$class}">
|
<body class="{$class}">
|
||||||
|
|
|
@ -13,8 +13,8 @@
|
||||||
{if $supportedLocale != $locale}
|
{if $supportedLocale != $locale}
|
||||||
<li>
|
<li>
|
||||||
<a hreflang="{$supportedLocale->getBcp47()}"
|
<a hreflang="{$supportedLocale->getBcp47()}"
|
||||||
lang="{$supportedLocale->getBcp47()}"
|
lang="{$supportedLocale->getBcp47()}"
|
||||||
href="{path_for name='locale' data=['locale'=>$supportedLocale->getIso15897()]}">
|
href="{path_for name='locale' data=['locale'=>$supportedLocale->getIso15897()]}">
|
||||||
{if $supportedLocale->getCountry()}
|
{if $supportedLocale->getCountry()}
|
||||||
{$supportedLocale->getCountry()->getEmoji()}
|
{$supportedLocale->getCountry()->getEmoji()}
|
||||||
{/if}
|
{/if}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
<h1 class="logobis">
|
<h1 class="logobis">
|
||||||
<a class="logocompatible" href="{base_url}">
|
<a class="logocompatible" href="{base_url}">
|
||||||
<span class="logocompatiblemask"><img src="{base_url}/img/logocompatiblemask.png" width="447" height="107" alt="{$config->appName}" /></span>
|
<span class="logocompatiblemask"><img src="{base_url}/img/logocompatiblemask.png" width="447" height="107"
|
||||||
</a></h1>
|
alt="{$config->appName}"/></span>
|
||||||
|
</a></h1>
|
||||||
|
|
|
@ -2,41 +2,45 @@
|
||||||
{include file='inc/header.tpl'}
|
{include file='inc/header.tpl'}
|
||||||
<main class="main">
|
<main class="main">
|
||||||
<div><img class="logo" src="{base_url}/img/logo.png"
|
<div><img class="logo" src="{base_url}/img/logo.png"
|
||||||
alt="{$config->appName}" width="328" height="284"></div>
|
alt="{$config->appName}" width="328" height="284"></div>
|
||||||
<form action="{path_for name="info"}">
|
<form action="{path_for name="info"}">
|
||||||
<label class="labelurl" for="url">
|
<label class="labelurl" for="url">
|
||||||
{t}Copy here the URL of your video (Youtube, Dailymotion, etc.){/t}
|
{t}Copy here the URL of your video (Youtube, Dailymotion, etc.){/t}
|
||||||
</label>
|
</label>
|
||||||
<div class="champs">
|
<div class="champs">
|
||||||
<span class="URLinput_wrapper">
|
<span class="URLinput_wrapper">
|
||||||
<!-- We used to have an autofocus attribute on this field but it triggerd a very specific CSS bug: https://github.com/Rudloff/alltube/issues/117 -->
|
<!-- We used to have an autofocus attribute on this field but it triggerd a very specific CSS bug: https://github.com/Rudloff/alltube/issues/117 -->
|
||||||
<input class="URLinput large-font" type="url" name="url" id="url"
|
<input class="URLinput large-font" type="url" name="url" id="url"
|
||||||
required placeholder="http://example.com/video" />
|
required placeholder="http://example.com/video"/>
|
||||||
</span>
|
</span>
|
||||||
{if $config->uglyUrls}
|
{if $config->uglyUrls}
|
||||||
<input type="hidden" name="page" value="info" />
|
<input type="hidden" name="page" value="info"/>
|
||||||
{/if}
|
{/if}
|
||||||
<input class="downloadBtn large-font" type="submit" value="{t}Download{/t}" /><br/>
|
<input class="downloadBtn large-font" type="submit" value="{t}Download{/t}"/><br/>
|
||||||
{if $config->convert}
|
{if $config->convert}
|
||||||
<div class="mp3 small-font">
|
<div class="mp3 small-font">
|
||||||
<div class="mp3-inner">
|
<div class="mp3-inner">
|
||||||
<input type="checkbox" id="audio" class="audio" name="audio">
|
<input type="checkbox" id="audio" class="audio" name="audio">
|
||||||
<label for="audio"><span class="ui"></span>
|
<label for="audio"><span class="ui"></span>
|
||||||
{t}Audio only (MP3){/t}
|
{t}Audio only (MP3){/t}
|
||||||
</label>
|
</label>
|
||||||
<div class="seekOptions">
|
<div class="seekOptions">
|
||||||
<label for="from">{t}From{/t}</label> <input type="text" pattern="(\d+:)?(\d+:)?\d+(\.\d+)?" placeholder="HH:MM:SS" value="" name="from" id="from" />
|
<label for="from">{t}From{/t}</label> <input type="text" pattern="(\d+:)?(\d+:)?\d+(\.\d+)?"
|
||||||
<label for="to">{t}to{/t}</label> <input type="text" pattern="(\d+:)?(\d+:)?\d+(\.\d+)?" placeholder="HH:MM:SS" value="" name="to" id="to" />
|
placeholder="HH:MM:SS" value="" name="from"
|
||||||
|
id="from"/>
|
||||||
|
<label for="to">{t}to{/t}</label> <input type="text" pattern="(\d+:)?(\d+:)?\d+(\.\d+)?"
|
||||||
|
placeholder="HH:MM:SS" value="" name="to" id="to"/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{/if}
|
||||||
{/if}
|
</div>
|
||||||
</div>
|
|
||||||
</form>
|
</form>
|
||||||
<a class="combatiblelink small-font" href="{path_for name="extractors"}">{t}See all supported websites{/t}</a>
|
<a class="combatiblelink small-font" href="{path_for name="extractors"}">{t}See all supported websites{/t}</a>
|
||||||
<div id="bookmarklet" class="bookmarklet_wrapper">
|
<div id="bookmarklet" class="bookmarklet_wrapper">
|
||||||
<p> {t}Drag this to your bookmarks bar:{/t} </p>
|
<p> {t}Drag this to your bookmarks bar:{/t} </p>
|
||||||
<a class="bookmarklet small-font" href="javascript:window.location='{$domain}{path_for name='info'}?url='+encodeURIComponent(location.href);">{t}Bookmarklet{/t}</a>
|
<a class="bookmarklet small-font"
|
||||||
|
href="javascript:window.location='{$domain}{path_for name='info'}?url='+encodeURIComponent(location.href);">{t}Bookmarklet{/t}</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
|
@ -1,100 +1,105 @@
|
||||||
{include file="inc/head.tpl"}
|
{include file="inc/head.tpl"}
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
<div itemscope itemtype="http://schema.org/VideoObject">
|
<div itemscope itemtype="http://schema.org/VideoObject">
|
||||||
<main class="main">
|
<main class="main">
|
||||||
{include file="inc/logo.tpl"}
|
{include file="inc/logo.tpl"}
|
||||||
{$title="<i itemprop='name'>
|
{$title="<i itemprop='name'>
|
||||||
<a itemprop='url' id='video_link'
|
<a itemprop='url' id='video_link'
|
||||||
href='{$video->webpage_url}'>
|
href='{$video->webpage_url}'>
|
||||||
{$video->title}</a></i>"}
|
{$video->title}</a></i>"}
|
||||||
<p id="download_intro">
|
<p id="download_intro">
|
||||||
{t params=['@title' => $title]}You are going to download @title.{/t}
|
{t params=['@title' => $title]}You are going to download @title.{/t}
|
||||||
</p>
|
</p>
|
||||||
{if isset($video->thumbnail)}
|
{if isset($video->thumbnail)}
|
||||||
<img itemprop="thumbnailUrl" class="thumb" src="{$video->thumbnail}" alt="" />
|
<img itemprop="thumbnailUrl" class="thumb" src="{$video->thumbnail}" alt=""/>
|
||||||
{/if}
|
{/if}
|
||||||
{if isset($video->description)}
|
{if isset($video->description)}
|
||||||
<meta itemprop="description" content="{$video->description|escape}" />
|
<meta itemprop="description" content="{$video->description|escape}"/>
|
||||||
{/if}
|
{/if}
|
||||||
{if isset($video->upload_date)}
|
{if isset($video->upload_date)}
|
||||||
<meta itemprop="uploadDate" content="{$video->upload_date}" />
|
<meta itemprop="uploadDate" content="{$video->upload_date}"/>
|
||||||
{/if}
|
{/if}
|
||||||
<br/>
|
<br/>
|
||||||
<form action="{path_for name="download"}">
|
<form action="{path_for name="download"}">
|
||||||
<input type="hidden" name="url" value="{$video->webpage_url}" />
|
<input type="hidden" name="url" value="{$video->webpage_url}"/>
|
||||||
{if $config->uglyUrls}
|
{if $config->uglyUrls}
|
||||||
<input type="hidden" name="page" value="download" />
|
<input type="hidden" name="page" value="download"/>
|
||||||
{/if}
|
{/if}
|
||||||
{if isset($video->formats) && count($video->formats) > 1}
|
{if isset($video->formats) && count($video->formats) > 1}
|
||||||
<h3><label for="format">{t}Available formats:{/t}</label></h3>
|
<h3><label for="format">{t}Available formats:{/t}</label></h3>
|
||||||
<select name="format" id="format" class="formats monospace">
|
<select name="format" id="format" class="formats monospace">
|
||||||
<optgroup label="{t}Generic formats{/t}">
|
<optgroup label="{t}Generic formats{/t}">
|
||||||
{foreach $config->genericFormats as $format => $name}
|
{foreach $config->genericFormats as $format => $name}
|
||||||
<option value="{$format}">{t}{$name}{/t}</option>
|
<option value="{$format}">{t}{$name}{/t}</option>
|
||||||
{/foreach}
|
{/foreach}
|
||||||
</optgroup>
|
</optgroup>
|
||||||
<optgroup label="{t}Detailed formats{/t}" class="monospace">
|
<optgroup label="{t}Detailed formats{/t}" class="monospace">
|
||||||
{foreach $video->formats as $format}
|
{foreach $video->formats as $format}
|
||||||
{if $config->stream || $format->protocol|in_array:array('http', 'https')}
|
{if $config->stream || $format->protocol|in_array:array('http', 'https')}
|
||||||
{strip}
|
{strip}
|
||||||
<option value="{$format->format_id}">
|
<option value="{$format->format_id}">
|
||||||
{$format->ext}
|
{$format->ext}
|
||||||
{for $foo=1 to (5 - ($format->ext|strlen))}
|
{for $foo=1 to (5 - ($format->ext|strlen))}
|
||||||
|
|
||||||
{/for}
|
{/for}
|
||||||
{if isset($format->width)}
|
{if isset($format->width)}
|
||||||
{$format->width}x{$format->height}
|
{$format->width}x{$format->height}
|
||||||
{for $foo=1 to (10 - (("{$format->width}x{$format->height}")|strlen))}
|
{for $foo=1 to (10 - (("{$format->width}x{$format->height}")|strlen))}
|
||||||
|
|
||||||
{/for}
|
{/for}
|
||||||
{else}
|
{else}
|
||||||
{for $foo=1 to 10}
|
{for $foo=1 to 10}
|
||||||
|
|
||||||
{/for}
|
{/for}
|
||||||
{/if}
|
{/if}
|
||||||
{if isset($format->filesize)}
|
{if isset($format->filesize)}
|
||||||
{($format->filesize/1000000)|round:2} MB
|
{($format->filesize/1000000)|round:2} MB
|
||||||
{for $foo=1 to (7 - (($format->filesize/1000000)|round:2|strlen))}
|
{for $foo=1 to (7 - (($format->filesize/1000000)|round:2|strlen))}
|
||||||
|
|
||||||
{/for}
|
{/for}
|
||||||
{else}
|
{else}
|
||||||
{for $foo=1 to 10}
|
{for $foo=1 to 10}
|
||||||
|
|
||||||
{/for}
|
{/for}
|
||||||
{/if}
|
{/if}
|
||||||
{if isset($format->format_note)}
|
{if isset($format->format_note)}
|
||||||
{$format->format_note}
|
{$format->format_note}
|
||||||
{/if}
|
{/if}
|
||||||
({$format->format_id})
|
({$format->format_id})
|
||||||
</option>
|
</option>
|
||||||
{/strip}
|
{/strip}
|
||||||
{/if}
|
{/if}
|
||||||
{/foreach}
|
{/foreach}
|
||||||
</optgroup>
|
</optgroup>
|
||||||
</select><br/><br/>
|
</select>
|
||||||
{/if}
|
<br/>
|
||||||
{if $config->stream}
|
<br/>
|
||||||
<input type="checkbox" {if $config->stream != 'ask'}checked{/if} name="stream" id="stream"/>
|
{/if}
|
||||||
<label for="stream">{t}Stream the video through the server{/t}</label>
|
{if $config->stream}
|
||||||
<br/><br/>
|
<input type="checkbox" {if $config->stream != 'ask'}checked{/if} name="stream" id="stream"/>
|
||||||
{/if}
|
<label for="stream">{t}Stream the video through the server{/t}</label>
|
||||||
{if $config->convertAdvanced}
|
<br/>
|
||||||
<input type="checkbox" name="customConvert" id="customConvert"/>
|
<br/>
|
||||||
<label for="customConvert">{t}Convert into a custom format:{/t}</label>
|
{/if}
|
||||||
<select title="{t}Custom format{/t}" name="customFormat" aria-label="{t}Format to convert to{/t}">
|
{if $config->convertAdvanced}
|
||||||
{foreach $config->convertAdvancedFormats as $format}
|
<input type="checkbox" name="customConvert" id="customConvert"/>
|
||||||
<option>{$format}</option>
|
<label for="customConvert">{t}Convert into a custom format:{/t}</label>
|
||||||
{/foreach}
|
<select title="{t}Custom format{/t}" name="customFormat" aria-label="{t}Format to convert to{/t}">
|
||||||
</select>
|
{foreach $config->convertAdvancedFormats as $format}
|
||||||
{t}with{/t}
|
<option>{$format}</option>
|
||||||
<label for="customBitrate" class="sr-only">{t}Bit rate{/t}</label>
|
{/foreach}
|
||||||
<input type="number" value="{$config->audioBitrate}" title="{t}Custom bitrate{/t}" class="customBitrate"
|
</select>
|
||||||
name="customBitrate" id="customBitrate" aria-describedby="customBitrateUnit" />
|
{t}with{/t}
|
||||||
<span id="customBitrateUnit">{t}kbit/s audio{/t}</span>
|
<label for="customBitrate" class="sr-only">{t}Bit rate{/t}</label>
|
||||||
<br/><br/>
|
<input type="number" value="{$config->audioBitrate}" title="{t}Custom bitrate{/t}"
|
||||||
{/if}
|
class="customBitrate"
|
||||||
<input class="downloadBtn" type="submit" value="{t}Download{/t}" /><br/>
|
name="customBitrate" id="customBitrate" aria-describedby="customBitrateUnit"/>
|
||||||
</form>
|
<span id="customBitrateUnit">{t}kbit/s audio{/t}</span>
|
||||||
</main>
|
<br/>
|
||||||
</div>
|
<br/>
|
||||||
{include file="inc/footer.tpl"}
|
{/if}
|
||||||
|
<input class="downloadBtn" type="submit" value="{t}Download{/t}"/><br/>
|
||||||
|
</form>
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
{include file="inc/footer.tpl"}
|
||||||
|
|
|
@ -6,9 +6,9 @@
|
||||||
<p>{t}You need a password in order to download this video.{/t}</p>
|
<p>{t}You need a password in order to download this video.{/t}</p>
|
||||||
<form action="" method="POST">
|
<form action="" method="POST">
|
||||||
<label class="sr-only" for="password">{t}Video password{/t}</label>
|
<label class="sr-only" for="password">{t}Video password{/t}</label>
|
||||||
<input class="URLinput" type="password" name="password" id="password" />
|
<input class="URLinput" type="password" name="password" id="password"/>
|
||||||
<br/><br/>
|
<br/><br/>
|
||||||
<input class="downloadBtn" type="submit" value="{t}Download{/t}" />
|
<input class="downloadBtn" type="submit" value="{t}Download{/t}"/>
|
||||||
</form>
|
</form>
|
||||||
</main>
|
</main>
|
||||||
{include file='inc/footer.tpl'}
|
{include file='inc/footer.tpl'}
|
||||||
|
|
|
@ -1,43 +1,44 @@
|
||||||
{include file="inc/head.tpl"}
|
{include file="inc/head.tpl"}
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
<main class="main">
|
<main class="main">
|
||||||
{include file="inc/logo.tpl"}
|
{include file="inc/logo.tpl"}
|
||||||
|
|
||||||
{if isset($video->title)}
|
{if isset($video->title)}
|
||||||
{$title="<i>
|
{$title="<i>
|
||||||
<a href='{$video->webpage_url}'>
|
<a href='{$video->webpage_url}'>
|
||||||
{$video->title}</a>
|
{$video->title}</a>
|
||||||
</i>"}
|
</i>"}
|
||||||
<p>
|
<p>
|
||||||
{t params=['@title'=>$title]}Videos extracted from @title:{/t}
|
{t params=['@title'=>$title]}Videos extracted from @title:{/t}
|
||||||
</p>
|
</p>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{if $config->stream}
|
{if $config->stream}
|
||||||
<a href="{path_for name="download"}?url={$video->webpage_url}" class="downloadBtn">Download everything</a>
|
<a href="{path_for name="download"}?url={$video->webpage_url}" class="downloadBtn">Download everything</a>
|
||||||
{/if}
|
{/if}
|
||||||
{foreach $video->entries as $entry}
|
{foreach $video->entries as $entry}
|
||||||
<div class="playlist-entry">
|
<div class="playlist-entry">
|
||||||
<h3 class="playlist-entry-title"><a target="_blank" href="{strip}
|
<h3 class="playlist-entry-title"><a target="_blank" href="{strip}
|
||||||
{if isset($entry->ie_key) and $entry->ie_key == Youtube and !filter_var($entry->url, FILTER_VALIDATE_URL)}
|
{if isset($entry->ie_key) and $entry->ie_key == Youtube and !filter_var($entry->url, FILTER_VALIDATE_URL)}
|
||||||
https://www.youtube.com/watch?v=
|
https://www.youtube.com/watch?v=
|
||||||
{/if}
|
{/if}
|
||||||
{$entry->url}
|
{$entry->url}
|
||||||
{/strip}">
|
{/strip}">
|
||||||
{if !isset($entry->title)}
|
{if !isset($entry->title)}
|
||||||
{if $entry->ie_key == YoutubePlaylist}
|
{if $entry->ie_key == YoutubePlaylist}
|
||||||
Playlist
|
Playlist
|
||||||
{else}
|
{else}
|
||||||
Video
|
Video
|
||||||
{/if}
|
{/if}
|
||||||
{else}
|
{else}
|
||||||
{$entry->title}
|
{$entry->title}
|
||||||
{/if}
|
{/if}
|
||||||
</a></h3>
|
</a></h3>
|
||||||
<a target="_blank" class="downloadBtn" href="{path_for name="download"}?url={$entry->url}">{t}Download{/t}</a>
|
<a target="_blank" class="downloadBtn"
|
||||||
<a target="_blank" href="{path_for name="info"}?url={$entry->url}">{t}More options{/t}</a>
|
href="{path_for name="download"}?url={$entry->url}">{t}Download{/t}</a>
|
||||||
</div>
|
<a target="_blank" href="{path_for name="info"}?url={$entry->url}">{t}More options{/t}</a>
|
||||||
{/foreach}
|
</div>
|
||||||
|
{/foreach}
|
||||||
|
|
||||||
</main>
|
</main>
|
||||||
{include file="inc/footer.tpl"}
|
{include file="inc/footer.tpl"}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
namespace Alltube\Test;
|
namespace Alltube\Test;
|
||||||
|
|
||||||
use Alltube\Config;
|
use Alltube\Config;
|
||||||
|
use Exception;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -32,6 +33,7 @@ abstract class BaseTest extends TestCase
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepare tests.
|
* Prepare tests.
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
protected function setUp(): void
|
protected function setUp(): void
|
||||||
{
|
{
|
||||||
|
|
|
@ -23,6 +23,7 @@ class ConfigTest extends BaseTest
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepare tests.
|
* Prepare tests.
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
protected function setUp(): void
|
protected function setUp(): void
|
||||||
{
|
{
|
||||||
|
@ -39,7 +40,7 @@ class ConfigTest extends BaseTest
|
||||||
public function testGetInstance()
|
public function testGetInstance()
|
||||||
{
|
{
|
||||||
$config = Config::getInstance();
|
$config = Config::getInstance();
|
||||||
$this->assertEquals($config->convert, false);
|
$this->assertEquals(false, $config->convert);
|
||||||
$this->assertConfig($config);
|
$this->assertConfig($config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,7 +54,7 @@ class ConfigTest extends BaseTest
|
||||||
Config::destroyInstance();
|
Config::destroyInstance();
|
||||||
|
|
||||||
$config = Config::getInstance();
|
$config = Config::getInstance();
|
||||||
$this->assertEquals($config->convert, false);
|
$this->assertEquals(false, $config->convert);
|
||||||
$this->assertConfig($config);
|
$this->assertConfig($config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,6 +82,7 @@ class ConfigTest extends BaseTest
|
||||||
* Test the setFile function.
|
* Test the setFile function.
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function testSetFile()
|
public function testSetFile()
|
||||||
{
|
{
|
||||||
|
@ -103,24 +105,26 @@ class ConfigTest extends BaseTest
|
||||||
* Test the setOptions function.
|
* Test the setOptions function.
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function testSetOptions()
|
public function testSetOptions()
|
||||||
{
|
{
|
||||||
Config::setOptions(['appName' => 'foo']);
|
Config::setOptions(['appName' => 'foo']);
|
||||||
$config = Config::getInstance();
|
$config = Config::getInstance();
|
||||||
$this->assertEquals($config->appName, 'foo');
|
$this->assertEquals('foo', $config->appName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test the setOptions function.
|
* Test the setOptions function.
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function testSetOptionsWithoutUpdate()
|
public function testSetOptionsWithoutUpdate()
|
||||||
{
|
{
|
||||||
Config::setOptions(['appName' => 'foo'], false);
|
Config::setOptions(['appName' => 'foo'], false);
|
||||||
$config = Config::getInstance();
|
$config = Config::getInstance();
|
||||||
$this->assertEquals($config->appName, 'foo');
|
$this->assertEquals('foo', $config->appName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -149,6 +153,7 @@ class ConfigTest extends BaseTest
|
||||||
* Test the getInstance function with the CONVERT and PYTHON environment variables.
|
* Test the getInstance function with the CONVERT and PYTHON environment variables.
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function testGetInstanceWithEnv()
|
public function testGetInstanceWithEnv()
|
||||||
{
|
{
|
||||||
|
@ -156,7 +161,7 @@ class ConfigTest extends BaseTest
|
||||||
putenv('CONVERT=1');
|
putenv('CONVERT=1');
|
||||||
Config::setFile($this->getConfigFile());
|
Config::setFile($this->getConfigFile());
|
||||||
$config = Config::getInstance();
|
$config = Config::getInstance();
|
||||||
$this->assertEquals($config->convert, true);
|
$this->assertEquals(true, $config->convert);
|
||||||
putenv('CONVERT');
|
putenv('CONVERT');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,10 +6,12 @@
|
||||||
|
|
||||||
namespace Alltube\Test;
|
namespace Alltube\Test;
|
||||||
|
|
||||||
|
use Alltube\Controller\BaseController;
|
||||||
use Alltube\Controller\DownloadController;
|
use Alltube\Controller\DownloadController;
|
||||||
use Alltube\Controller\FrontController;
|
use Alltube\Controller\FrontController;
|
||||||
use Alltube\LocaleManager;
|
use Alltube\LocaleManager;
|
||||||
use Alltube\ViewFactory;
|
use Alltube\ViewFactory;
|
||||||
|
use Exception;
|
||||||
use Slim\Container;
|
use Slim\Container;
|
||||||
use Slim\Http\Environment;
|
use Slim\Http\Environment;
|
||||||
use Slim\Http\Request;
|
use Slim\Http\Request;
|
||||||
|
@ -43,11 +45,13 @@ abstract class ControllerTest extends BaseTest
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Controller instance used in tests.
|
* Controller instance used in tests.
|
||||||
|
* @var BaseController
|
||||||
*/
|
*/
|
||||||
protected $controller;
|
protected $controller;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepare tests.
|
* Prepare tests.
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
protected function setUp(): void
|
protected function setUp(): void
|
||||||
{
|
{
|
||||||
|
@ -78,7 +82,7 @@ abstract class ControllerTest extends BaseTest
|
||||||
* Run controller function with custom query parameters and return the result.
|
* Run controller function with custom query parameters and return the result.
|
||||||
*
|
*
|
||||||
* @param string $request Controller function to call
|
* @param string $request Controller function to call
|
||||||
* @param array $params Query parameters
|
* @param mixed[] $params Query parameters
|
||||||
*
|
*
|
||||||
* @return Response HTTP response
|
* @return Response HTTP response
|
||||||
*/
|
*/
|
||||||
|
@ -94,7 +98,7 @@ abstract class ControllerTest extends BaseTest
|
||||||
* Assert that calling controller function with these parameters returns a 200 HTTP response.
|
* Assert that calling controller function with these parameters returns a 200 HTTP response.
|
||||||
*
|
*
|
||||||
* @param string $request Controller function to call
|
* @param string $request Controller function to call
|
||||||
* @param array $params Query parameters
|
* @param mixed[] $params Query parameters
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
|
@ -107,7 +111,7 @@ abstract class ControllerTest extends BaseTest
|
||||||
* Assert that calling controller function with these parameters returns an HTTP redirect.
|
* Assert that calling controller function with these parameters returns an HTTP redirect.
|
||||||
*
|
*
|
||||||
* @param string $request Controller function to call
|
* @param string $request Controller function to call
|
||||||
* @param array $params Query parameters
|
* @param mixed[] $params Query parameters
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
|
@ -120,7 +124,7 @@ abstract class ControllerTest extends BaseTest
|
||||||
* Assert that calling controller function with these parameters returns an HTTP 500 error.
|
* Assert that calling controller function with these parameters returns an HTTP 500 error.
|
||||||
*
|
*
|
||||||
* @param string $request Controller function to call
|
* @param string $request Controller function to call
|
||||||
* @param array $params Query parameters
|
* @param mixed[] $params Query parameters
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
|
@ -133,7 +137,7 @@ abstract class ControllerTest extends BaseTest
|
||||||
* Assert that calling controller function with these parameters returns an HTTP 400 error.
|
* Assert that calling controller function with these parameters returns an HTTP 400 error.
|
||||||
*
|
*
|
||||||
* @param string $request Controller function to call
|
* @param string $request Controller function to call
|
||||||
* @param array $params Query parameters
|
* @param mixed[] $params Query parameters
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -8,6 +8,7 @@ namespace Alltube\Test;
|
||||||
|
|
||||||
use Alltube\Stream\ConvertedPlaylistArchiveStream;
|
use Alltube\Stream\ConvertedPlaylistArchiveStream;
|
||||||
use Alltube\Video;
|
use Alltube\Video;
|
||||||
|
use Exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unit tests for the ConvertedPlaylistArchiveStream class.
|
* Unit tests for the ConvertedPlaylistArchiveStream class.
|
||||||
|
@ -17,6 +18,7 @@ class ConvertedPlaylistArchiveStreamTest extends StreamTest
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Prepare tests.
|
* Prepare tests.
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
protected function setUp(): void
|
protected function setUp(): void
|
||||||
{
|
{
|
||||||
|
|
|
@ -8,6 +8,7 @@ namespace Alltube\Test;
|
||||||
|
|
||||||
use Alltube\Config;
|
use Alltube\Config;
|
||||||
use Alltube\Controller\DownloadController;
|
use Alltube\Controller\DownloadController;
|
||||||
|
use Exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unit tests for the FrontController class.
|
* Unit tests for the FrontController class.
|
||||||
|
@ -17,6 +18,7 @@ class DownloadControllerTest extends ControllerTest
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Prepare tests.
|
* Prepare tests.
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
protected function setUp(): void
|
protected function setUp(): void
|
||||||
{
|
{
|
||||||
|
@ -62,6 +64,7 @@ class DownloadControllerTest extends ControllerTest
|
||||||
* Test the download() function with streams enabled.
|
* Test the download() function with streams enabled.
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function testDownloadWithStream()
|
public function testDownloadWithStream()
|
||||||
{
|
{
|
||||||
|
@ -77,6 +80,7 @@ class DownloadControllerTest extends ControllerTest
|
||||||
* Test the download() function with an M3U stream.
|
* Test the download() function with an M3U stream.
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function testDownloadWithM3uStream()
|
public function testDownloadWithM3uStream()
|
||||||
{
|
{
|
||||||
|
@ -96,6 +100,7 @@ class DownloadControllerTest extends ControllerTest
|
||||||
* Test the download() function with an RTMP stream.
|
* Test the download() function with an RTMP stream.
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function testDownloadWithRtmpStream()
|
public function testDownloadWithRtmpStream()
|
||||||
{
|
{
|
||||||
|
@ -113,6 +118,7 @@ class DownloadControllerTest extends ControllerTest
|
||||||
* Test the download() function with a remuxed video.
|
* Test the download() function with a remuxed video.
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function testDownloadWithRemux()
|
public function testDownloadWithRemux()
|
||||||
{
|
{
|
||||||
|
@ -182,6 +188,7 @@ class DownloadControllerTest extends ControllerTest
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
* @requires OS Linux
|
* @requires OS Linux
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function testDownloadWithPlaylist()
|
public function testDownloadWithPlaylist()
|
||||||
{
|
{
|
||||||
|
@ -197,6 +204,7 @@ class DownloadControllerTest extends ControllerTest
|
||||||
* Test the download() function with an advanced conversion.
|
* Test the download() function with an advanced conversion.
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function testDownloadWithAdvancedConversion()
|
public function testDownloadWithAdvancedConversion()
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,8 +17,15 @@ use Slim\Http\Request;
|
||||||
*/
|
*/
|
||||||
class FrontControllerTest extends ControllerTest
|
class FrontControllerTest extends ControllerTest
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Controller instance used in tests.
|
||||||
|
* @var FrontController
|
||||||
|
*/
|
||||||
|
protected $controller;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepare tests.
|
* Prepare tests.
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
protected function setUp(): void
|
protected function setUp(): void
|
||||||
{
|
{
|
||||||
|
@ -41,6 +48,7 @@ class FrontControllerTest extends ControllerTest
|
||||||
* Test the constructor with streams enabled.
|
* Test the constructor with streams enabled.
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function testConstructorWithStream()
|
public function testConstructorWithStream()
|
||||||
{
|
{
|
||||||
|
@ -120,6 +128,7 @@ class FrontControllerTest extends ControllerTest
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
* @requires download
|
* @requires download
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function testInfoWithAudio()
|
public function testInfoWithAudio()
|
||||||
{
|
{
|
||||||
|
@ -136,6 +145,7 @@ class FrontControllerTest extends ControllerTest
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
* @requires download
|
* @requires download
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function testInfoWithVimeoAudio()
|
public function testInfoWithVimeoAudio()
|
||||||
{
|
{
|
||||||
|
@ -150,6 +160,7 @@ class FrontControllerTest extends ControllerTest
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
* @requires download
|
* @requires download
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function testInfoWithUnconvertedAudio()
|
public function testInfoWithUnconvertedAudio()
|
||||||
{
|
{
|
||||||
|
@ -197,6 +208,7 @@ class FrontControllerTest extends ControllerTest
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
* @requires download
|
* @requires download
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function testInfoWithStream()
|
public function testInfoWithStream()
|
||||||
{
|
{
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
namespace Alltube\Test;
|
namespace Alltube\Test;
|
||||||
|
|
||||||
use Alltube\Controller\JsonController;
|
use Alltube\Controller\JsonController;
|
||||||
|
use Exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unit tests for the FrontController class.
|
* Unit tests for the FrontController class.
|
||||||
|
@ -15,6 +16,7 @@ class JsonControllerTest extends ControllerTest
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Prepare tests.
|
* Prepare tests.
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
protected function setUp(): void
|
protected function setUp(): void
|
||||||
{
|
{
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
|
|
||||||
namespace Alltube\Test;
|
namespace Alltube\Test;
|
||||||
|
|
||||||
use Alltube\Locale;
|
|
||||||
use Alltube\LocaleManager;
|
use Alltube\LocaleManager;
|
||||||
use Alltube\LocaleMiddleware;
|
use Alltube\LocaleMiddleware;
|
||||||
use Slim\Container;
|
use Slim\Container;
|
||||||
|
|
|
@ -8,6 +8,7 @@ namespace Alltube\Test;
|
||||||
|
|
||||||
use Alltube\Stream\PlaylistArchiveStream;
|
use Alltube\Stream\PlaylistArchiveStream;
|
||||||
use Alltube\Video;
|
use Alltube\Video;
|
||||||
|
use Exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unit tests for the PlaylistArchiveStream class.
|
* Unit tests for the PlaylistArchiveStream class.
|
||||||
|
@ -17,6 +18,7 @@ class PlaylistArchiveStreamTest extends StreamTest
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Prepare tests.
|
* Prepare tests.
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
protected function setUp(): void
|
protected function setUp(): void
|
||||||
{
|
{
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
namespace Alltube\Test;
|
namespace Alltube\Test;
|
||||||
|
|
||||||
|
use Psr\Http\Message\StreamInterface;
|
||||||
use RuntimeException;
|
use RuntimeException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -15,6 +16,7 @@ abstract class StreamTest extends BaseTest
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Stream instance.
|
* Stream instance.
|
||||||
|
* @var StreamInterface
|
||||||
*/
|
*/
|
||||||
protected $stream;
|
protected $stream;
|
||||||
|
|
||||||
|
@ -36,7 +38,7 @@ abstract class StreamTest extends BaseTest
|
||||||
public function testWrite()
|
public function testWrite()
|
||||||
{
|
{
|
||||||
if ($this->stream->isWritable()) {
|
if ($this->stream->isWritable()) {
|
||||||
$this->assertNull($this->stream->write('foo'));
|
$this->assertIsInt($this->stream->write('foo'));
|
||||||
} else {
|
} else {
|
||||||
$this->expectException(RuntimeException::class);
|
$this->expectException(RuntimeException::class);
|
||||||
$this->stream->write('foo');
|
$this->stream->write('foo');
|
||||||
|
@ -103,7 +105,7 @@ abstract class StreamTest extends BaseTest
|
||||||
*/
|
*/
|
||||||
public function testEof()
|
public function testEof()
|
||||||
{
|
{
|
||||||
$this->assertFalse($this->stream->eof());
|
$this->assertIsBool($this->stream->eof());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -26,6 +26,7 @@ class VideoStubsTest extends BaseTest
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize properties used by test.
|
* Initialize properties used by test.
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
protected function setUp(): void
|
protected function setUp(): void
|
||||||
{
|
{
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
namespace Alltube\Test;
|
namespace Alltube\Test;
|
||||||
|
|
||||||
use Alltube\Config;
|
use Alltube\Config;
|
||||||
|
use Alltube\Exception\EmptyUrlException;
|
||||||
|
use Alltube\Exception\PasswordException;
|
||||||
use Alltube\Video;
|
use Alltube\Video;
|
||||||
use Exception;
|
use Exception;
|
||||||
|
|
||||||
|
@ -20,6 +22,7 @@ class VideoTest extends BaseTest
|
||||||
* Test getExtractors function.
|
* Test getExtractors function.
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
|
* @throws PasswordException
|
||||||
*/
|
*/
|
||||||
public function testGetExtractors()
|
public function testGetExtractors()
|
||||||
{
|
{
|
||||||
|
@ -29,13 +32,15 @@ class VideoTest extends BaseTest
|
||||||
/**
|
/**
|
||||||
* Test getUrl function.
|
* Test getUrl function.
|
||||||
*
|
*
|
||||||
* @param string $url URL
|
* @param string $url URL
|
||||||
* @param string $format Format
|
* @param string $format Format
|
||||||
* @param string $filename Filename
|
* @param string $filename Filename
|
||||||
* @param string $extension File extension
|
* @param string $extension File extension
|
||||||
* @param string $domain Domain
|
* @param string $domain Domain
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
|
* @throws PasswordException
|
||||||
|
* @throws EmptyUrlException
|
||||||
* @dataProvider urlProvider
|
* @dataProvider urlProvider
|
||||||
* @dataProvider m3uUrlProvider
|
* @dataProvider m3uUrlProvider
|
||||||
* @dataProvider remuxUrlProvider
|
* @dataProvider remuxUrlProvider
|
||||||
|
@ -57,6 +62,8 @@ class VideoTest extends BaseTest
|
||||||
* Test getUrl function with a protected video.
|
* Test getUrl function with a protected video.
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
|
* @throws EmptyUrlException
|
||||||
|
* @throws PasswordException
|
||||||
*/
|
*/
|
||||||
public function testgetUrlWithPassword()
|
public function testgetUrlWithPassword()
|
||||||
{
|
{
|
||||||
|
@ -70,6 +77,8 @@ class VideoTest extends BaseTest
|
||||||
* Test getUrl function with a protected video and no password.
|
* Test getUrl function with a protected video and no password.
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
|
* @throws EmptyUrlException
|
||||||
|
* @throws PasswordException
|
||||||
*/
|
*/
|
||||||
public function testgetUrlWithMissingPassword()
|
public function testgetUrlWithMissingPassword()
|
||||||
{
|
{
|
||||||
|
@ -82,6 +91,8 @@ class VideoTest extends BaseTest
|
||||||
* Test getUrl function with a protected video and a wrong password.
|
* Test getUrl function with a protected video and a wrong password.
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
|
* @throws EmptyUrlException
|
||||||
|
* @throws PasswordException
|
||||||
*/
|
*/
|
||||||
public function testgetUrlWithWrongPassword()
|
public function testgetUrlWithWrongPassword()
|
||||||
{
|
{
|
||||||
|
@ -96,6 +107,8 @@ class VideoTest extends BaseTest
|
||||||
* @param string $url URL
|
* @param string $url URL
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
|
* @throws EmptyUrlException
|
||||||
|
* @throws PasswordException
|
||||||
* @dataProvider ErrorUrlProvider
|
* @dataProvider ErrorUrlProvider
|
||||||
*/
|
*/
|
||||||
public function testgetUrlError($url)
|
public function testgetUrlError($url)
|
||||||
|
@ -112,7 +125,7 @@ class VideoTest extends BaseTest
|
||||||
*/
|
*/
|
||||||
public function urlProvider()
|
public function urlProvider()
|
||||||
{
|
{
|
||||||
$videos = [
|
return [
|
||||||
[
|
[
|
||||||
'https://www.youtube.com/watch?v=M7IpKCZ47pU', 'best[protocol^=http]',
|
'https://www.youtube.com/watch?v=M7IpKCZ47pU', 'best[protocol^=http]',
|
||||||
'It_s_Not_Me_It_s_You_-_Hearts_Under_Fire-M7IpKCZ47pU',
|
'It_s_Not_Me_It_s_You_-_Hearts_Under_Fire-M7IpKCZ47pU',
|
||||||
|
@ -136,11 +149,9 @@ class VideoTest extends BaseTest
|
||||||
'https://vimeo.com/24195442', 'http-720p',
|
'https://vimeo.com/24195442', 'http-720p',
|
||||||
'Carving_the_Mountains-24195442',
|
'Carving_the_Mountains-24195442',
|
||||||
'mp4',
|
'mp4',
|
||||||
'gcs-vimeo.akamaized.net',
|
'akamaized.net',
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
return $videos;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -167,7 +178,7 @@ class VideoTest extends BaseTest
|
||||||
*/
|
*/
|
||||||
public function m3uUrlProvider()
|
public function m3uUrlProvider()
|
||||||
{
|
{
|
||||||
$videos = [
|
return [
|
||||||
[
|
[
|
||||||
'https://twitter.com/verge/status/813055465324056576/video/1', 'hls-2176',
|
'https://twitter.com/verge/status/813055465324056576/video/1', 'hls-2176',
|
||||||
'The_Verge_-_This_tiny_origami_robot_can_self-fold_and_complete_tasks-813055465324056576',
|
'The_Verge_-_This_tiny_origami_robot_can_self-fold_and_complete_tasks-813055465324056576',
|
||||||
|
@ -175,8 +186,6 @@ class VideoTest extends BaseTest
|
||||||
'video.twimg.com',
|
'video.twimg.com',
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
return $videos;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -211,12 +220,13 @@ class VideoTest extends BaseTest
|
||||||
/**
|
/**
|
||||||
* Test getJSON function.
|
* Test getJSON function.
|
||||||
*
|
*
|
||||||
* @param string $url URL
|
* @param string $url URL
|
||||||
* @param string $format Format
|
* @param string $format Format
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
* @dataProvider urlProvider
|
* @dataProvider urlProvider
|
||||||
* @dataProvider m3uUrlProvider
|
* @dataProvider m3uUrlProvider
|
||||||
|
* @throws PasswordException
|
||||||
*/
|
*/
|
||||||
public function testGetJson($url, $format)
|
public function testGetJson($url, $format)
|
||||||
{
|
{
|
||||||
|
@ -237,6 +247,7 @@ class VideoTest extends BaseTest
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
* @dataProvider ErrorURLProvider
|
* @dataProvider ErrorURLProvider
|
||||||
|
* @throws PasswordException
|
||||||
*/
|
*/
|
||||||
public function testGetJsonError($url)
|
public function testGetJsonError($url)
|
||||||
{
|
{
|
||||||
|
@ -248,15 +259,16 @@ class VideoTest extends BaseTest
|
||||||
/**
|
/**
|
||||||
* Test getFilename function.
|
* Test getFilename function.
|
||||||
*
|
*
|
||||||
* @param string $url URL
|
* @param string $url URL
|
||||||
* @param string $format Format
|
* @param string $format Format
|
||||||
* @param string $filename Filename
|
* @param string $filename Filename
|
||||||
* @param string $extension File extension
|
* @param string $extension File extension
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
* @dataProvider urlProvider
|
* @dataProvider urlProvider
|
||||||
* @dataProvider m3uUrlProvider
|
* @dataProvider m3uUrlProvider
|
||||||
* @dataProvider remuxUrlProvider
|
* @dataProvider remuxUrlProvider
|
||||||
|
* @throws PasswordException
|
||||||
*/
|
*/
|
||||||
public function testGetFilename($url, $format, $filename, $extension)
|
public function testGetFilename($url, $format, $filename, $extension)
|
||||||
{
|
{
|
||||||
|
@ -271,6 +283,7 @@ class VideoTest extends BaseTest
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
* @dataProvider ErrorUrlProvider
|
* @dataProvider ErrorUrlProvider
|
||||||
|
* @throws PasswordException
|
||||||
*/
|
*/
|
||||||
public function testGetFilenameError($url)
|
public function testGetFilenameError($url)
|
||||||
{
|
{
|
||||||
|
@ -282,11 +295,12 @@ class VideoTest extends BaseTest
|
||||||
/**
|
/**
|
||||||
* Test getAudioStream function.
|
* Test getAudioStream function.
|
||||||
*
|
*
|
||||||
* @param string $url URL
|
* @param string $url URL
|
||||||
* @param string $format Format
|
* @param string $format Format
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
* @dataProvider urlProvider
|
* @dataProvider urlProvider
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function testGetAudioStream($url, $format)
|
public function testGetAudioStream($url, $format)
|
||||||
{
|
{
|
||||||
|
@ -371,11 +385,12 @@ class VideoTest extends BaseTest
|
||||||
/**
|
/**
|
||||||
* Test getM3uStream function.
|
* Test getM3uStream function.
|
||||||
*
|
*
|
||||||
* @param string $url URL
|
* @param string $url URL
|
||||||
* @param string $format Format
|
* @param string $format Format
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
* @dataProvider m3uUrlProvider
|
* @dataProvider m3uUrlProvider
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function testGetM3uStream($url, $format)
|
public function testGetM3uStream($url, $format)
|
||||||
{
|
{
|
||||||
|
@ -386,11 +401,12 @@ class VideoTest extends BaseTest
|
||||||
/**
|
/**
|
||||||
* Test getRemuxStream function.
|
* Test getRemuxStream function.
|
||||||
*
|
*
|
||||||
* @param string $url URL
|
* @param string $url URL
|
||||||
* @param string $format Format
|
* @param string $format Format
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
* @dataProvider remuxUrlProvider
|
* @dataProvider remuxUrlProvider
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function testGetRemuxStream($url, $format)
|
public function testGetRemuxStream($url, $format)
|
||||||
{
|
{
|
||||||
|
@ -417,11 +433,12 @@ class VideoTest extends BaseTest
|
||||||
/**
|
/**
|
||||||
* Test getRtmpStream function.
|
* Test getRtmpStream function.
|
||||||
*
|
*
|
||||||
* @param string $url URL
|
* @param string $url URL
|
||||||
* @param string $format Format
|
* @param string $format Format
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
* @dataProvider rtmpUrlProvider
|
* @dataProvider rtmpUrlProvider
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function testGetRtmpStream($url, $format)
|
public function testGetRtmpStream($url, $format)
|
||||||
{
|
{
|
||||||
|
@ -453,11 +470,12 @@ class VideoTest extends BaseTest
|
||||||
/**
|
/**
|
||||||
* Test getConvertedStream function without avconv.
|
* Test getConvertedStream function without avconv.
|
||||||
*
|
*
|
||||||
* @param string $url URL
|
* @param string $url URL
|
||||||
* @param string $format Format
|
* @param string $format Format
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
* @dataProvider urlProvider
|
* @dataProvider urlProvider
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function testGetConvertedStream($url, $format)
|
public function testGetConvertedStream($url, $format)
|
||||||
{
|
{
|
||||||
|
|
|
@ -12,6 +12,7 @@ use Slim\Container;
|
||||||
use Slim\Http\Environment;
|
use Slim\Http\Environment;
|
||||||
use Slim\Http\Request;
|
use Slim\Http\Request;
|
||||||
use Slim\Views\Smarty;
|
use Slim\Views\Smarty;
|
||||||
|
use SmartyException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unit tests for the ViewFactory class.
|
* Unit tests for the ViewFactory class.
|
||||||
|
@ -22,6 +23,7 @@ class ViewFactoryTest extends BaseTest
|
||||||
* Test the create() function.
|
* Test the create() function.
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
|
* @throws SmartyException
|
||||||
*/
|
*/
|
||||||
public function testCreate()
|
public function testCreate()
|
||||||
{
|
{
|
||||||
|
@ -35,6 +37,7 @@ class ViewFactoryTest extends BaseTest
|
||||||
* Test the create() function with a X-Forwarded-Proto header.
|
* Test the create() function with a X-Forwarded-Proto header.
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
|
* @throws SmartyException
|
||||||
*/
|
*/
|
||||||
public function testCreateWithXForwardedProto()
|
public function testCreateWithXForwardedProto()
|
||||||
{
|
{
|
||||||
|
|
|
@ -8,6 +8,7 @@ namespace Alltube\Test;
|
||||||
|
|
||||||
use Alltube\Stream\YoutubeChunkStream;
|
use Alltube\Stream\YoutubeChunkStream;
|
||||||
use Alltube\Video;
|
use Alltube\Video;
|
||||||
|
use Exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unit tests for the YoutubeChunkStream class.
|
* Unit tests for the YoutubeChunkStream class.
|
||||||
|
@ -17,6 +18,7 @@ class YoutubeChunkStreamTest extends StreamTest
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Prepare tests.
|
* Prepare tests.
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
protected function setUp(): void
|
protected function setUp(): void
|
||||||
{
|
{
|
||||||
|
|
|
@ -8,6 +8,7 @@ namespace Alltube\Test;
|
||||||
|
|
||||||
use Alltube\Stream\YoutubeStream;
|
use Alltube\Stream\YoutubeStream;
|
||||||
use Alltube\Video;
|
use Alltube\Video;
|
||||||
|
use Exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unit tests for the YoutubeStream class.
|
* Unit tests for the YoutubeStream class.
|
||||||
|
@ -17,6 +18,7 @@ class YoutubeStreamTest extends StreamTest
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Prepare tests.
|
* Prepare tests.
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
protected function setUp(): void
|
protected function setUp(): void
|
||||||
{
|
{
|
||||||
|
|
|
@ -9,7 +9,7 @@ use phpmock\mockery\PHPMockery;
|
||||||
// Composer autoload.
|
// Composer autoload.
|
||||||
require_once __DIR__ . '/../vendor/autoload.php';
|
require_once __DIR__ . '/../vendor/autoload.php';
|
||||||
|
|
||||||
ini_set('session.use_cookies', 0);
|
ini_set('session.use_cookies', '0');
|
||||||
session_cache_limiter('');
|
session_cache_limiter('');
|
||||||
session_start();
|
session_start();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue