From 1059d8a4bcfe9df74eec619e3febe18799cd1ed2 Mon Sep 17 00:00:00 2001 From: benson Date: Fri, 5 May 2023 21:56:16 +0800 Subject: [PATCH] added support for updating yt-dlp binary;moved version info display to admin section --- appinfo/application.php | 8 +- appinfo/routes.php | 3 + lib/Aria2/Aria2.php | 8 +- lib/Controller/MainController.php | 10 +++ lib/Http/Client.php | 9 +- lib/Settings/Admin.php | 3 +- lib/Settings/Personal.php | 2 - lib/Tools/Helper.php | 51 +++++++++++ lib/Ytdl/Ytdl.php | 25 +++++- src/adminSettings.vue | 8 ++ src/components/mainForm.vue | 12 ++- src/components/systemInfo.vue | 144 ++++++++++++++++++++++++++++++ src/css/bootstrap.scss | 1 + src/css/btn.scss | 1 + src/personalSettings.vue | 40 --------- 15 files changed, 264 insertions(+), 61 deletions(-) create mode 100644 src/components/systemInfo.vue create mode 100644 src/css/btn.scss diff --git a/appinfo/application.php b/appinfo/application.php index d28381a..450c8eb 100644 --- a/appinfo/application.php +++ b/appinfo/application.php @@ -22,13 +22,13 @@ class Application extends App implements IBootstrap } public function register(IRegistrationContext $context): void { - $context->registerService('httpClient', function () { + $context->registerService(Client::class, function () { $options = [ 'ipv4' => true, ]; return Client::create($options); }); - $context->registerService('crawler', function () { + $context->registerService(Crawler::class, function () { return new Crawler(); }); $sites = Helper::getSearchSites(); @@ -36,8 +36,8 @@ class Application extends App implements IBootstrap //fully qualified class name $className = $site['class']; $context->registerService($className, function (ContainerInterface $container) use ($className) { - $crawler = $container->get('crawler'); - $client = $container->get('httpClient'); + $crawler = $container->get(Crawler::class); + $client = $container->get(Client::class); return $className::create($crawler, $client); }); } diff --git a/appinfo/routes.php b/appinfo/routes.php index adbf1a9..c9bfecf 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -30,5 +30,8 @@ return [ //api routes ['name' => 'Api#download', 'url' => '/api/v1/download', 'verb' => 'POST'], ['name' => 'Api#search', 'url' => '/api/v1/search', 'verb' => 'POST'], + //binary updates + ['name' => 'Main#ytdlCheck', 'url' => '/ytdl/release/check', 'verb' => 'GET'], + ['name' => 'Main#ytdlUpdate', 'url' => '/ytdl/release/update', 'verb' => 'GET'], ], ]; diff --git a/lib/Aria2/Aria2.php b/lib/Aria2/Aria2.php index 4624ac5..7cb9e4b 100644 --- a/lib/Aria2/Aria2.php +++ b/lib/Aria2/Aria2.php @@ -412,8 +412,14 @@ class Aria2 { return $this->bin; } - public function version(){ + public function version() + { $resp = $this->getVersion(); return $resp['result']['version'] ?? null; } + public function install() + { + $url = "https://github.com/shiningw/ncdownloader-bin/raw/master/aria2c"; + Helper::Download($url, $this->bin); + } } diff --git a/lib/Controller/MainController.php b/lib/Controller/MainController.php index 121d11a..fae1add 100644 --- a/lib/Controller/MainController.php +++ b/lib/Controller/MainController.php @@ -226,4 +226,14 @@ class MainController extends Controller $counter = $this->counters->getCounters(); return new JSONResponse(['counter' => $counter]); } + + public function ytdlCheck() + { + $resp = $this->ytdl->check(); + return new JSONResponse($resp); + } + public function ytdlUPdate(){ + $resp = $this->ytdl->update(); + return new JSONResponse($resp); + } } diff --git a/lib/Http/Client.php b/lib/Http/Client.php index 9681dc5..58ed946 100644 --- a/lib/Http/Client.php +++ b/lib/Http/Client.php @@ -1,6 +1,6 @@ client = HttpClient::create($this->configure($options)); } - public static function create(?array $options = null) + public static function create(?array $options =[]) { return new self($options); } @@ -26,8 +26,7 @@ final class Client private function defaultOptions(): array { $settings = [ - 'headers' => [ - ], + 'headers' => [], 'extra' => ['curl' => null], ]; return $settings; diff --git a/lib/Settings/Admin.php b/lib/Settings/Admin.php index 91baeb6..42c5e53 100644 --- a/lib/Settings/Admin.php +++ b/lib/Settings/Admin.php @@ -39,7 +39,8 @@ class Admin implements ISettings $settings = Helper::getAllAdminSettings(); $settings += [ "path" => "/apps/ncdownloader/admin/save", - + "aria2_version" => Helper::getAria2Version(), + "ytdl_version" => Helper::getYtdlVersion(), ]; $parameters = [ 'settings' => $settings, diff --git a/lib/Settings/Personal.php b/lib/Settings/Personal.php index 9236c19..caaf971 100644 --- a/lib/Settings/Personal.php +++ b/lib/Settings/Personal.php @@ -50,8 +50,6 @@ class Personal implements ISettings "path" => $path, "disallow_aria2_settings" => Helper::getAdminSettings("disallow_aria2_settings"), "is_admin" => \OC_User::isAdminUser($this->uid), - "aria2_version" => Helper::getAria2Version(), - "ytdl_version" => Helper::getYtdlVersion(), ], "options" => [ [ diff --git a/lib/Tools/Helper.php b/lib/Tools/Helper.php index 10d0b5a..746d96c 100644 --- a/lib/Tools/Helper.php +++ b/lib/Tools/Helper.php @@ -12,6 +12,9 @@ use OC_Util; use Psr\Log\LoggerInterface; use OCA\NCDownloader\Aria2\Aria2; use OCA\NCDownloader\Ytdl\Ytdl; +use OCA\NCDownloader\Http\Client; + +require __DIR__ . "/../../vendor/autoload.php"; class Helper { @@ -592,4 +595,52 @@ class Helper ]; return $options; } + public static function getLatestRelease($owner, $repo) + { + $client = Client::create(); + $response = $client->request('GET', "https://api.github.com/repos/$owner/$repo/releases/latest", [ + 'headers' => [ + 'User-Agent' => 'PHP' + ] + ]); + $data = json_decode($response->getContent(), true); + if (isset($data['tag_name'])) { + return $data['tag_name']; + } + return null; + } + + public static function downloadLatestRelease($owner, $repo, $file) + { + $client = Client::create(['max_redirects' => 10]); + $response = $client->request('GET', "https://api.github.com/repos/$owner/$repo/releases/latest", [ + 'headers' => [ + 'User-Agent' => 'PHP' + ] + ]); + $data = json_decode($response->getContent(), true); + $downloadUrl = null; + foreach ($data['assets'] as $asset) { + if ($asset['name'] == $repo) { + $downloadUrl = $asset['browser_download_url']; + break; + } + } + if ($downloadUrl) { + if (!is_writable(dirname($file))) { + throw new \Exception(dirname($file) . " is not writable"); + } + $response = $client->request('GET', $downloadUrl); + if ($byte = file_put_contents($file, $response->getContent())) { + return $byte; + }else { + throw new \Exception("Failed to download $downloadUrl"); + } + } + return false; + } + public static function removeLetters($str) + { + return preg_replace('/[^0-9.]+/', '', $str); + } } diff --git a/lib/Ytdl/Ytdl.php b/lib/Ytdl/Ytdl.php index f142a87..7d8bb52 100644 --- a/lib/Ytdl/Ytdl.php +++ b/lib/Ytdl/Ytdl.php @@ -271,8 +271,31 @@ class Ytdl $process = new Process([$this->bin, '--version']); $process->run(); if ($process->isSuccessful()) { - return $process->getOutput(); + //remove any new line + return trim($process->getOutput()); } return false; } + public function check() + { + if ($tagName = Helper::getLatestRelease('yt-dlp', 'yt-dlp')) { + $tagName = Helper::removeLetters($tagName); + $version = $this->version(); + if ($version && version_compare($version, $tagName, '<')) { + return ['status' => true, 'message' => $tagName]; + } + } + return ['status' => false, 'message' => 'No update available']; + } + public function update() + { + $file = __DIR__ . "/../../bin/yt-dlp"; + try { + Helper::downloadLatestRelease('yt-dlp', 'yt-dlp', $file); + chmod($file, 0744); + } catch (\Exception $e) { + return ['status' => false,'message' => $e->getMessage()]; + } + return ['status' => true, 'message' => 'Updated to latest version','data' => $this->version()]; + } } diff --git a/src/adminSettings.vue b/src/adminSettings.vue index f8b0bc3..bf3098c 100644 --- a/src/adminSettings.vue +++ b/src/adminSettings.vue @@ -12,6 +12,7 @@ path="/apps/ncdownloader/admin/aria2/save" :validOptions="validOptions"> + diff --git a/src/components/mainForm.vue b/src/components/mainForm.vue index a383286..81f6ea0 100644 --- a/src/components/mainForm.vue +++ b/src/components/mainForm.vue @@ -199,18 +199,16 @@ export default { .checkboxes { border-radius: 0%; } - .download-button, - .search-button { - height: $column-height; - .btn-primary { + .download-button.btn-primary, + .search-button.btn-primary { color: #fff; background-color: #2d3f59; border-color: #1e324f; border-radius: 0%; - } - .btn-primary:hover { + } + .download-button.btn-primary:hover, + .search-button.btn-primary:hover { background-color: #191a16; - } } .magnet-link, diff --git a/src/components/systemInfo.vue b/src/components/systemInfo.vue new file mode 100644 index 0000000..6c02065 --- /dev/null +++ b/src/components/systemInfo.vue @@ -0,0 +1,144 @@ + + + \ No newline at end of file diff --git a/src/css/bootstrap.scss b/src/css/bootstrap.scss index 93386f7..0dc6e25 100644 --- a/src/css/bootstrap.scss +++ b/src/css/bootstrap.scss @@ -1,3 +1,4 @@ @import "../../node_modules/bootstrap/scss/functions"; @import "../../node_modules/bootstrap/scss/variables"; @import "../../node_modules/bootstrap/scss/mixins"; +@import "../../node_modules/bootstrap/scss/root"; diff --git a/src/css/btn.scss b/src/css/btn.scss new file mode 100644 index 0000000..89a62e7 --- /dev/null +++ b/src/css/btn.scss @@ -0,0 +1 @@ +@import "../../node_modules/bootstrap/scss/buttons"; diff --git a/src/personalSettings.vue b/src/personalSettings.vue index cd56780..6330542 100644 --- a/src/personalSettings.vue +++ b/src/personalSettings.vue @@ -12,19 +12,6 @@ path="/apps/ncdownloader/personal/ytdl/save" :validOptions="ytdlOptions"> -
-

System Info

-
-
-
Aria2 Version:
-
{{ aria2Version }}
-
-
-
yt-dlp Version:
-
{{ ytdVersion }}
-
-
-
- \ No newline at end of file