From 44810e5df2cb4fcf743c3a6fc8d3f44acbd585a3 Mon Sep 17 00:00:00 2001 From: benson Date: Fri, 23 Dec 2022 17:25:06 +0800 Subject: [PATCH] added basic api for 3rd-party clients --- appinfo/application.php | 2 +- appinfo/routes.php | 3 ++ lib/Controller/ApiController.php | 57 +++++++++++++++++++++++++++++ lib/Controller/MainController.php | 4 +- lib/Controller/SearchController.php | 10 ++--- lib/Controller/YtdlController.php | 21 ++++++----- src/App.vue | 7 ++++ src/actions/buttonActions.js | 2 + src/utils/helper.js | 4 +- 9 files changed, 90 insertions(+), 20 deletions(-) create mode 100644 lib/Controller/ApiController.php diff --git a/appinfo/application.php b/appinfo/application.php index 115f90c..ea49bbf 100644 --- a/appinfo/application.php +++ b/appinfo/application.php @@ -63,7 +63,7 @@ class Application extends App implements IBootstrap $context->registerService(Settings::class, function (ContainerInterface $c) use ($uid){ return new Settings($uid); }); - + //$context->injectFn([$this, 'registerSearchProviders']); } } diff --git a/appinfo/routes.php b/appinfo/routes.php index def087a..adbf1a9 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -27,5 +27,8 @@ return [ ['name' => 'Settings#saveYtdl', 'url' => '/personal/ytdl/save', 'verb' => 'POST'], ['name' => 'Settings#deleteYtdl', 'url' => '/personal/ytdl/delete', 'verb' => 'POST'], ['name' => 'Settings#getSettings', 'url' => '/getsettings', 'verb' => 'POST'], + //api routes + ['name' => 'Api#download', 'url' => '/api/v1/download', 'verb' => 'POST'], + ['name' => 'Api#search', 'url' => '/api/v1/search', 'verb' => 'POST'], ], ]; diff --git a/lib/Controller/ApiController.php b/lib/Controller/ApiController.php new file mode 100644 index 0000000..0b8dbab --- /dev/null +++ b/lib/Controller/ApiController.php @@ -0,0 +1,57 @@ +IL10N = $IL10N; + $this->main = $main; + $this->search = $search; + $this->ytdl = $ytdl; + parent::__construct($appName, $request); + } + + /** + * @CORS + * @NoAdminRequired + * @NoCSRFRequired + */ + public function download(string $url, string $type = "aria2", array $options = []): JSONResponse + { + if ($type == "aria2") { + return $this->main->Download($url); + } else if ($type == "ytdl") { + $extension = $options["extension"] ?? "mp4"; + return $this->ytdl->Download($url, $extension); + } else if ($type == "bt") { + return $this->main->Upload(); + } + return new JSONResponse(["error" => "Invalid download type"]); + } + + /** + * @CORS + * @NoAdminRequired + * @NoCSRFRequired + */ + public function search(string $keyword, string $site = "TPB"): JSONResponse + { + return $this->search->execute($keyword, $site); + } +} diff --git a/lib/Controller/MainController.php b/lib/Controller/MainController.php index f9178f4..88d7dbb 100644 --- a/lib/Controller/MainController.php +++ b/lib/Controller/MainController.php @@ -126,13 +126,13 @@ class MainController extends Controller /** * @NoAdminRequired */ - public function Download() + public function Download(string $url) { $dlDir = $this->aria2->getDownloadDir(); if (!is_writable($dlDir)) { return new JSONResponse(['error' => sprintf("%s is not writable", $dlDir)]); } - $url = trim($this->request->getParam('text-input-value')); + //$url = trim($this->request->getParam('text-input-value')); if (Helper::isMagnet($url)) { if ($this->disable_bt_nonadmin && !($this->isAdmin)) { return new JSONResponse(['error' => $this->accessDenied]); diff --git a/lib/Controller/SearchController.php b/lib/Controller/SearchController.php index 09dd091..b5186a4 100644 --- a/lib/Controller/SearchController.php +++ b/lib/Controller/SearchController.php @@ -1,4 +1,5 @@ urlGenerator = \OC::$server->getURLGenerator(); $this->search = new siteSearch(); } - /** + /** * @NoAdminRequired */ - public function execute() + public function execute(string $keyword,string $site = "TPB") { - $keyword = Helper::sanitize($this->request->getParam('text-input-value')); - $site = Helper::sanitize($this->request->getParam('select-value-search')); + $keyword = Helper::sanitize($keyword); + $site = Helper::sanitize($site); $this->search->setSite($site); $data = $this->search->go($keyword); return new JSONResponse($data); } - } diff --git a/lib/Controller/YtdlController.php b/lib/Controller/YtdlController.php index 8555a34..a4cd241 100644 --- a/lib/Controller/YtdlController.php +++ b/lib/Controller/YtdlController.php @@ -1,4 +1,5 @@ ytdl->getDownloadDir(); if (!is_writable($dlDir)) { return new JSONResponse(['error' => sprintf("%s is not writable", $dlDir)]); } - $url = trim($this->request->getParam('text-input-value')); + //$url = trim($this->request->getParam('text-input-value')); + $url = trim($url); $yt = $this->ytdl; - if (in_array($this->request->getParam('extension'), $this->audio_extensions)) { + if (in_array($extension, $this->audio_extensions)) { $yt->audioOnly = true; - $yt->audioFormat = $this->request->getParam('extension'); + $yt->audioFormat = $extension; } else { - $yt->videoFormat = $this->request->getParam('extension'); + $yt->videoFormat = $extension; } if (!$yt->isInstalled()) { return new JSONResponse(["error" => "Please install the latest yt-dlp or make the bundled binary file executable in ncdownloader/bin"]); @@ -108,9 +110,9 @@ class YtdlController extends Controller /** * @NoAdminRequired */ - public function Delete() + public function Delete(string $gid) { - $gid = $this->request->getParam('gid'); + //$gid = $this->request->getParam('gid'); if (!$gid) { return new JSONResponse(['error' => "no gid value is received!"]); } @@ -143,9 +145,9 @@ class YtdlController extends Controller /** * @NoAdminRequired */ - public function Redownload() + public function Redownload(string $gid) { - $gid = $this->request->getParam('gid'); + //$gid = $this->request->getParam('gid'); if (!$gid) { return new JSONResponse(['error' => "no gid value is received!"]); } @@ -211,5 +213,4 @@ class YtdlController extends Controller return ['error' => $this->l10n->t("Youtube-dl NOT installed!")]; } - } diff --git a/src/App.vue b/src/App.vue index 1fa2d7f..761e39f 100644 --- a/src/App.vue +++ b/src/App.vue @@ -79,6 +79,8 @@ export default { helper.info(message); } let url = formWrapper.getAttribute("action"); + formData['url'] = formData["text-input-value"] + delete formData["text-input-value"] helper.httpClient(url) .setData(formData) .setHandler(function (data) { @@ -100,6 +102,11 @@ export default { contentTable.getInstance().loading(); let url = formWrapper.getAttribute("action"); + formData['keyword'] = formData["text-input-value"] + formData['site'] = formData["select-value-search"] + delete formData["text-input-value"] + delete formData['select-value-search'] + helper.httpClient(url) .setData(formData) .setHandler(function (data) { diff --git a/src/actions/buttonActions.js b/src/actions/buttonActions.js index 7d588cd..d2e8709 100644 --- a/src/actions/buttonActions.js +++ b/src/actions/buttonActions.js @@ -29,6 +29,8 @@ const buttonHandler = (event, type) => { console.log("gid is not set!"); } } + data['url'] = data["text-input-value"] + delete data["text-input-value"] helper.httpClient(url).setErrorHandler(function (xhr, textStatus, error) { console.log(error); }).setHandler(function (data) { diff --git a/src/utils/helper.js b/src/utils/helper.js index 8d4bd90..4b173ba 100644 --- a/src/utils/helper.js +++ b/src/utils/helper.js @@ -173,7 +173,7 @@ const helper = { if (element.hasAttribute('type') && element.getAttribute('type') === 'button') { continue } - const key = element.getAttribute('id') + const key = element.getAttribute('id') || element.getAttribute('name') data[key] = element.value for (let prop in element.dataset) { if (prop == "rel") { @@ -189,7 +189,7 @@ const helper = { } data[prop] = element.dataset[prop]; } - const key = element.getAttribute('id') + const key = element.getAttribute('id') || element.getAttribute('name') data[key] = element.value } return data;