diff --git a/appinfo/application.php b/appinfo/application.php index a3fe2c2..40694a2 100644 --- a/appinfo/application.php +++ b/appinfo/application.php @@ -5,9 +5,6 @@ namespace OCA\NCDownloader\AppInfo; use OCA\NCDownloader\Controller\Aria2Controller; use OCA\NCDownloader\Controller\MainController; use OCA\NCDownloader\Controller\YoutubeController; -use OCA\NCDownloader\Search\Sites\bitSearch; -use OCA\NCDownloader\Search\Sites\sliderkz; -use OCA\NCDownloader\Search\Sites\TPB; use OCA\NCDownloader\Tools\Aria2; use OCA\NCDownloader\Tools\Client; use OCA\NCDownloader\Tools\Helper; @@ -91,20 +88,16 @@ class Application extends App $container->registerService('crawler', function () { return new Crawler(); }); - $container->registerService(TPB::class, function (IContainer $container) { - $crawler = $container->query('crawler'); - $client = $container->query('httpClient'); - return new TPB($crawler, $client); - }); - $container->registerService(bitSearch::class, function (IContainer $container) { - $crawler = $container->query('crawler'); - $client = $container->query('httpClient'); - return new bitSearch($crawler, $client); - }); - $container->registerService(sliderkz::class, function (IContainer $container) { - $client = $container->query('httpClient'); - return new sliderkz($client); - }); + $sites = Helper::getSearchSites(); + foreach ($sites as $site) { + //fully qualified class name + $className = $site['class']; + $container->registerService($className, function (IContainer $container) use ($className) { + $crawler = $container->query('crawler'); + $client = $container->query('httpClient'); + return $className::create($crawler, $client); + }); + } } private function getRealDownloadDir() diff --git a/lib/Controller/MainController.php b/lib/Controller/MainController.php index 50f020e..3e3e89d 100644 --- a/lib/Controller/MainController.php +++ b/lib/Controller/MainController.php @@ -72,6 +72,12 @@ class MainController extends Controller $params['counter'] = $this->counters->getCounters(); $params['python_installed'] = Helper::pythonInstalled(); $params['ffmpeg_installed'] = Helper::ffmpegInstalled(); + $sites = []; + foreach (Helper::getSearchSites() as $site) { + $label = $site['class']::getLabel(); + $sites[] = ['name' => $site['name'], 'label' => strtoupper($label)]; + } + $params['search_sites'] = json_encode($sites); $errors = []; if ($aria2_installed) { diff --git a/lib/Search/Sites/TPB.php b/lib/Search/Sites/TPB.php index a1756c8..d17b1bc 100644 --- a/lib/Search/Sites/TPB.php +++ b/lib/Search/Sites/TPB.php @@ -69,4 +69,8 @@ class TPB extends searchBase implements searchInterface $this->rows = $this->parse(); return $this; } + public static function getLabel(): string + { + return 'thepiratebay'; + } } diff --git a/lib/Search/Sites/bitSearch.php b/lib/Search/Sites/bitSearch.php index 03e1817..a275f32 100644 --- a/lib/Search/Sites/bitSearch.php +++ b/lib/Search/Sites/bitSearch.php @@ -80,4 +80,8 @@ class bitSearch extends searchBase implements searchInterface $this->rows = $this->parse(); return $this; } + public static function getLabel(): string + { + return 'bitsearch'; + } } diff --git a/lib/Search/Sites/searchBase.php b/lib/Search/Sites/searchBase.php index 0a3b65a..b9c8874 100644 --- a/lib/Search/Sites/searchBase.php +++ b/lib/Search/Sites/searchBase.php @@ -9,6 +9,7 @@ abstract class searchBase protected $rows = []; protected $errors = []; protected $actionLinks = [["name" => 'download', 'path' => '/index.php/apps/ncdownloader/new'], ['name' => 'clipboard']]; + private static $instance = null; public function getTableTitles(): array { @@ -18,6 +19,16 @@ abstract class searchBase return $this->tableTitles; } + public static function create($crawler,$client) + { + + if (!self::$instance) { + self::$instance = new static($crawler,$client); + } + + return self::$instance; + } + public function setTableTitles(array $titles) { $this->tableTitles = $titles; diff --git a/lib/Search/Sites/sliderkz.php b/lib/Search/Sites/sliderkz.php index 612dfe2..d4c5c96 100644 --- a/lib/Search/Sites/sliderkz.php +++ b/lib/Search/Sites/sliderkz.php @@ -10,10 +10,12 @@ class sliderkz extends searchBase implements searchInterface public $baseUrl = "https://slider.kz/vk_auth.php"; protected $query = null; protected $tableTitles = []; - public function __construct($client) + + public function __construct($crawler,$client) { $this->client = $client; } + public function search(string $keyword): array { $this->query = ['q' => trim($keyword)]; @@ -69,4 +71,9 @@ class sliderkz extends searchBase implements searchInterface return []; } + + public static function getLabel(): string + { + return 'music'; + } } diff --git a/lib/Tools/File.php b/lib/Tools/File.php new file mode 100644 index 0000000..a763243 --- /dev/null +++ b/lib/Tools/File.php @@ -0,0 +1,59 @@ +dirName = $dirname; + $this->suffix = $suffix; + + if (!is_dir($dirname)) { + throw new \Exception("directory ${dirname} doesn't exit"); + } + + } + + public static function create($dir, $suffix) + { + return new static($dir, $suffix); + } + + public function scandir($recursive = false) + { + if ($recursive) { + return $this->scandirRecursive(); + } + + $files = \glob($this->dirName . DIRECTORY_SEPARATOR . "*.{$this->suffix}"); + $this->Files = $files; + return $files; + } + + protected function scandirRecursive() + { + + $directory = new \RecursiveDirectoryIterator($this->dirName); + $iterator = new \RecursiveIteratorIterator($directory); + $iterators = new \RegexIterator($iterator, '/.*\.' . $this->suffix . '$/', \RegexIterator::GET_MATCH); + + $files = array(); + foreach ($iterators as $info) { + if ($info) { + $files[] = reset($info); + } + } + $this->Files = $files; + return $files; + } + public function getBasename($file){ + return basename($file,".".$this->suffix); + } +} diff --git a/lib/Tools/Helper.php b/lib/Tools/Helper.php index c19158e..b81a43c 100644 --- a/lib/Tools/Helper.php +++ b/lib/Tools/Helper.php @@ -2,6 +2,7 @@ namespace OCA\NCDownloader\Tools; +use OCA\NCDownloader\Search\Sites\searchInterface; use OCA\NCDownloader\Tools\aria2Options; use OC\Files\Filesystem; @@ -331,4 +332,37 @@ class Helper return (bool) self::findBinaryPath('python'); } + public static function findSearchSites($dir, $suffix = 'php'): array + { + $filetool = File::create($dir, $suffix); + $files = $filetool->scandir(); + $sites = []; + foreach ($files as $file) { + $basename = $filetool->getBasename($file); + $namespace = 'OCA\\NCDownloader\\Search\\Sites\\'; + $className = $namespace . $basename; + if (in_array(searchInterface::class, class_implements($className))) { + $sites[] = ['class' => $className, 'name' => $basename]; + } + } + return $sites; + } + + public static function getSearchSites(): array + { + $key = 'searchSites'; + $memcache = \OC::$server->getMemCacheFactory()->createDistributed($key); + if ($memcache->hasKey($key)) { + $sites = $memcache->get($key); + } else { + try { + $sites = Helper::findSearchSites(__DIR__ . "/../Search/Sites/"); + $memcache->set($key, $sites, 300); + } catch (\Exception $e) { + self::debug($e->getMessage()); + } + } + return $sites; + } + } diff --git a/src/App.vue b/src/App.vue index 76c99c6..4a6c685 100644 --- a/src/App.vue +++ b/src/App.vue @@ -33,6 +33,12 @@ const successCallback = (data, element) => { export default { name: "mainApp", + inject: ["settings"], + provide() { + return { + search_sites: this.settings.search_sites, + }; + }, data() { return { display: { download: true, search: false }, diff --git a/src/components/mainForm.vue b/src/components/mainForm.vue index 386835b..9aaa246 100644 --- a/src/components/mainForm.vue +++ b/src/components/mainForm.vue @@ -43,7 +43,12 @@ > - + @@ -55,6 +60,7 @@ import uploadFile from "./uploadFile"; import { translate as t } from "@nextcloud/l10n"; export default { + inject: ["settings", "search_sites"], data() { return { checkedValue: false, @@ -64,6 +70,7 @@ export default { downloadType: "aria2", placeholder: t("ncdownloader", "Paste your http/magnet link here"), searchLabel: t("ncdownloader", "Search Torrents"), + searchOptions: this.search_sites ? this.search_sites : this.noOptions(), }; }, components: { @@ -72,6 +79,7 @@ export default { searchInput, uploadFile, }, + created() {}, computed: {}, methods: { whichType(type, event) { @@ -105,10 +113,13 @@ export default { optionCallback(option) { if (option.label.toLowerCase() == "music") { this.searchLabel = t("ncdownloader", "Search Music"); - }else{ + } else { this.searchLabel = t("ncdownloader", "Search Torrents"); } }, + noOptions() { + return [{ name: "nooptions", label: "No Options" }]; + }, }, mounted() {}, name: "mainForm", diff --git a/src/components/searchInput.vue b/src/components/searchInput.vue index 5e65860..dae9213 100644 --- a/src/components/searchInput.vue +++ b/src/components/searchInput.vue @@ -29,11 +29,6 @@ export default { return { placeholder: t("ncdownloader", "Enter keyword to search"), selected: "TPB", - selectOptions: [ - { name: "TPB", label: "THEPIRATEBAY" }, - { name: "bitSearch", label: "BITSEARCH" }, - { name: "sliderkz", label: "MUSIC" }, - ], }; }, components: { @@ -53,7 +48,9 @@ export default { }, }, name: "searchInput", - props: [], + props: { + selectOptions: Object, + }, };