Merge branch 'master' into master
This commit is contained in:
7
Makefile
7
Makefile
@@ -113,20 +113,21 @@ dist:
|
||||
source:
|
||||
rm -rf $(source_build_directory)
|
||||
mkdir -p $(source_build_directory)
|
||||
tar cvzf $(source_package_name).tar.gz ../$(app_name) \
|
||||
tar cvzf $(source_package_name).tar.gz \
|
||||
--exclude-vcs \
|
||||
--exclude="../$(app_name)/build" \
|
||||
--exclude="../$(app_name)/js/node_modules" \
|
||||
--exclude="../$(app_name)/node_modules" \
|
||||
--exclude="../$(app_name)/*.log" \
|
||||
--exclude="../$(app_name)/js/*.log" \
|
||||
../$(app_name)
|
||||
|
||||
# Builds the source package for the app store, ignores php and js tests
|
||||
.PHONY: appstore
|
||||
appstore:
|
||||
rm -rf $(appstore_build_directory)
|
||||
mkdir -p $(appstore_build_directory)
|
||||
tar cvzf $(appstore_package_name).tar.gz ../$(app_name) \
|
||||
tar cvzf $(appstore_package_name).tar.gz \
|
||||
--exclude-vcs \
|
||||
--exclude="../$(app_name)/build" \
|
||||
--exclude="../$(app_name)/tests" \
|
||||
@@ -142,12 +143,14 @@ appstore:
|
||||
--exclude="../$(app_name)/js/bower.json" \
|
||||
--exclude="../$(app_name)/js/karma.*" \
|
||||
--exclude="../$(app_name)/js/protractor.*" \
|
||||
--exclude="../$(app_name)/node_modules" \
|
||||
--exclude="../$(app_name)/package.json" \
|
||||
--exclude="../$(app_name)/bower.json" \
|
||||
--exclude="../$(app_name)/karma.*" \
|
||||
--exclude="../$(app_name)/protractor\.*" \
|
||||
--exclude="../$(app_name)/.*" \
|
||||
--exclude="../$(app_name)/js/.*" \
|
||||
../$(app_name)
|
||||
|
||||
.PHONY: test
|
||||
test: composer
|
||||
|
||||
@@ -19,11 +19,9 @@ class Application extends App
|
||||
public function __construct(array $urlParams = array())
|
||||
{
|
||||
parent::__construct('ncdownloader', $urlParams);
|
||||
$user = \OC::$server->getUserSession()->getUser();
|
||||
$user = Helper::getUser();
|
||||
$this->uid = ($user) ? $user->getUID() : '';
|
||||
$this->settings = new Settings($this->uid);
|
||||
$this->dataDir = \OC::$server->getSystemConfig()->getValue('datadirectory');
|
||||
$this->appPath = \OC::$server->getAppManager()->getAppPath('ncdownloader');
|
||||
$this->userFolder = Helper::getUserFolder($this->uid);
|
||||
$container = $this->getContainer();
|
||||
$container->registerService('UserId', function (IContainer $container) {
|
||||
@@ -31,15 +29,11 @@ class Application extends App
|
||||
});
|
||||
|
||||
$container->registerService('Aria2', function (IContainer $container) {
|
||||
return new Aria2($this->getConfig());
|
||||
return new Aria2(Helper::getAria2Config($this->uid));
|
||||
});
|
||||
|
||||
$container->registerService('Youtube', function (IContainer $container) {
|
||||
$config = [
|
||||
'binary' => $this->settings->setType(Settings::TYPE['SYSTEM'])->get("ncd_yt_binary"),
|
||||
'downloadDir' => $this->getRealDownloadDir(),
|
||||
'settings' => $this->settings->setType(Settings::TYPE['USER'])->getYoutube(),
|
||||
];
|
||||
$config = Helper::getYoutubeConfig($this->uid);
|
||||
return new Youtube($config);
|
||||
});
|
||||
|
||||
@@ -100,42 +94,4 @@ class Application extends App
|
||||
}
|
||||
}
|
||||
|
||||
private function getRealDownloadDir()
|
||||
{
|
||||
|
||||
//relative nextcloud user path
|
||||
$dir = $this->settings->get('ncd_downloader_dir') ?? "/Downloads";
|
||||
return $this->dataDir . $this->userFolder . $dir;
|
||||
}
|
||||
private function getRealTorrentsDir()
|
||||
{
|
||||
$dir = $this->settings->get('ncd_torrents_dir') ?? "/Torrents";
|
||||
return $this->dataDir . $this->userFolder . $dir;
|
||||
}
|
||||
|
||||
private function getConfig()
|
||||
{
|
||||
//$this->config = \OC::$server->getAppConfig();
|
||||
$realDownloadDir = $this->getRealDownloadDir();
|
||||
$torrentsDir = $this->getRealTorrentsDir();
|
||||
$aria2_dir = $this->dataDir . "/aria2";
|
||||
$settings['seed_time'] = $this->settings->get("ncd_seed_time");
|
||||
$settings['seed_ratio'] = $this->settings->get("ncd_seed_ratio");
|
||||
if (is_array($customSettings = $this->settings->getAria2())) {
|
||||
$settings = array_merge($customSettings, $settings);
|
||||
}
|
||||
$token = $this->settings->setType(Settings::TYPE['SYSTEM'])->get('ncd_rpctoken');
|
||||
$config = [
|
||||
'dir' => $realDownloadDir,
|
||||
'torrents_dir' => $torrentsDir,
|
||||
'conf_dir' => $aria2_dir,
|
||||
'token' => $token,
|
||||
'settings' => $settings,
|
||||
'binary' => $this->settings->setType(Settings::TYPE['SYSTEM'])->get('ncd_aria2_binary'),
|
||||
'startHook' => $this->appPath . "/hooks/startHook.sh",
|
||||
'completeHook' => $this->appPath . "/hooks/completeHook.sh",
|
||||
];
|
||||
return $config;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ Search for torrents within the app from mutiple BT sites;
|
||||
Control Aria2 and manage download tasks from the web;
|
||||
download videos from 700+ video sites(youtube,youku,vimo,dailymotion,twitter,facebook and the likes
|
||||
</description>
|
||||
<version>0.9.1</version>
|
||||
<version>0.9.16</version>
|
||||
<licence>agpl</licence>
|
||||
<author mail="freefallbenson@gmail.com" homepage="https://github.com/shiningw">jiaxinhuang</author>
|
||||
<namespace>NCDownloader</namespace>
|
||||
|
||||
@@ -7,7 +7,7 @@ return [
|
||||
['name' => 'main#Download', 'url' => '/new', 'verb' => 'POST'],
|
||||
['name' => 'Aria2#Action', 'url' => '/aria2/{path}', 'verb' => 'POST'],
|
||||
['name' => 'Aria2#getStatus', 'url' => '/status/{path}', 'verb' => 'POST'],
|
||||
['name' => 'Aria2#Update', 'url' => '/update', 'verb' => 'GET'],
|
||||
['name' => 'Main#scanFolder', 'url' => '/scanfolder', 'verb' => 'GET'],
|
||||
['name' => 'Youtube#Index', 'url' => '/youtube/get', 'verb' => 'POST'],
|
||||
['name' => 'Youtube#Download', 'url' => '/youtube/new', 'verb' => 'POST'],
|
||||
['name' => 'Youtube#Delete', 'url' => '/youtube/delete', 'verb' => 'POST'],
|
||||
|
||||
@@ -6,7 +6,6 @@ use OCA\NCDownloader\Tools\Counters;
|
||||
use OCA\NCDownloader\Tools\DbHelper;
|
||||
use OCA\NCDownloader\Tools\folderScan;
|
||||
use OCA\NCDownloader\Tools\Helper;
|
||||
use OCA\NCDownloader\Tools\Settings;
|
||||
use OCP\AppFramework\Controller;
|
||||
use OCP\AppFramework\Http\JSONResponse;
|
||||
use OCP\Files\IRootFolder;
|
||||
@@ -32,8 +31,7 @@ class Aria2Controller extends Controller
|
||||
$this->l10n = $IL10N;
|
||||
$this->rootFolder = $rootFolder;
|
||||
$this->urlGenerator = \OC::$server->getURLGenerator();
|
||||
$this->settings = new Settings($UserId);
|
||||
$this->downloadDir = $this->settings->get('ncd_downloader_dir') ?? "/Downloads";
|
||||
$this->downloadDir = Helper::getDownloadDir();
|
||||
OC_Util::setupFS();
|
||||
//$this->config = \OC::$server->getAppConfig();
|
||||
$this->aria2 = $aria2;
|
||||
@@ -122,15 +120,6 @@ class Aria2Controller extends Controller
|
||||
$data = $this->aria2->start();
|
||||
return $data;
|
||||
}
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
* @NoCSRFRequired
|
||||
*/
|
||||
public function Update()
|
||||
{
|
||||
$resp = folderScan::create()->scan();
|
||||
return new JSONResponse($resp);
|
||||
}
|
||||
|
||||
private function createActionItem($name, $path)
|
||||
{
|
||||
@@ -235,7 +224,7 @@ class Aria2Controller extends Controller
|
||||
$tmp = [];
|
||||
$actions = [];
|
||||
$filename = sprintf('<a class="download-file-folder" href="%s">%s</a>', $folderLink, $filename);
|
||||
$fileInfo = sprintf('<button id="icon-clipboard" class="icon-clipboard" data-text="%s"></button> %s | %s', $extra ? $extra['link'] : 'nolink', $total, date("Y-m-d H:i:s", $timestamp));
|
||||
$fileInfo = sprintf('<button id="icon-clipboard" class="icon-clipboard" data-text="%s"></button> %s | %s', $extra["link"] ?? 'nolink', $total, date("Y-m-d H:i:s", $timestamp));
|
||||
$tmp['filename'] = array($filename, $fileInfo);
|
||||
|
||||
if ($this->aria2->methodName === "tellStopped") {
|
||||
|
||||
@@ -11,10 +11,11 @@ use OCA\NCDownloader\Tools\Youtube;
|
||||
use OCP\AppFramework\Controller;
|
||||
use OCP\AppFramework\Http\JSONResponse;
|
||||
use OCP\AppFramework\Http\TemplateResponse;
|
||||
//use OCP\Files\IRootFolder;
|
||||
use OCP\IL10N;
|
||||
//use OCP\Files\IRootFolder;
|
||||
use OCP\IRequest;
|
||||
use OC_Util;
|
||||
use OCA\NCDownloader\Tools\folderScan;
|
||||
|
||||
class MainController extends Controller
|
||||
{
|
||||
@@ -27,6 +28,7 @@ class MainController extends Controller
|
||||
|
||||
public function __construct($appName, IRequest $request, $UserId, IL10N $IL10N, Aria2 $aria2, Youtube $youtube)
|
||||
{
|
||||
|
||||
parent::__construct($appName, $request);
|
||||
$this->appName = $appName;
|
||||
$this->uid = $UserId;
|
||||
@@ -38,10 +40,9 @@ class MainController extends Controller
|
||||
$this->dbconn = new DbHelper();
|
||||
$this->counters = new Counters($aria2, $this->dbconn, $UserId);
|
||||
$this->youtube = $youtube;
|
||||
$this->settings = new Settings($this->uid);
|
||||
$this->isAdmin = \OC_User::isAdminUser($this->uid);
|
||||
$this->hideError = $this->settings->get("ncd_hide_errors", false);
|
||||
$this->disable_bt_nonadmin = $this->settings->setType($this->settings::TYPE['SYSTEM'])->get("ncd_disable_bt", false);
|
||||
$this->hideError = Helper::getSettings("ncd_hide_errors", false);
|
||||
$this->disable_bt_nonadmin = Helper::getSettings("ncd_disable_bt", false, Settings::TYPE["SYSTEM"]);
|
||||
$this->accessDenied = $this->l10n->t("Sorry,only admin users can download files via BT!");
|
||||
}
|
||||
/**
|
||||
@@ -56,7 +57,6 @@ class MainController extends Controller
|
||||
// OC_Util::addStyle($this->appName, 'table');
|
||||
$params = $this->buildParams();
|
||||
$response = new TemplateResponse($this->appName, 'Index', $params);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
@@ -124,6 +124,10 @@ class MainController extends Controller
|
||||
*/
|
||||
public function Download()
|
||||
{
|
||||
$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'));
|
||||
if (Helper::isMagnet($url)) {
|
||||
if ($this->disable_bt_nonadmin && !($this->isAdmin)) {
|
||||
@@ -192,4 +196,14 @@ class MainController extends Controller
|
||||
return new JSONResponse($resp);
|
||||
}
|
||||
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
* @NoCSRFRequired
|
||||
*/
|
||||
public function scanFolder()
|
||||
{
|
||||
$resp = folderScan::create()->scan();
|
||||
return new JSONResponse($resp);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -111,7 +111,7 @@ class SettingsController extends Controller
|
||||
{
|
||||
$saved = json_decode($this->settings->get("custom_youtube_dl_settings"), 1);
|
||||
$params = $this->request->getParams();
|
||||
foreach ($data as $key => $value) {
|
||||
foreach ($params as $key => $value) {
|
||||
unset($saved[$key]);
|
||||
}
|
||||
$resp = $this->settings->save("custom_youtube_dl_settings", json_encode($saved));
|
||||
|
||||
@@ -5,7 +5,6 @@ use OCA\NCDownloader\Tools\Aria2;
|
||||
use OCA\NCDownloader\Tools\DbHelper;
|
||||
use OCA\NCDownloader\Tools\folderScan;
|
||||
use OCA\NCDownloader\Tools\Helper;
|
||||
use OCA\NCDownloader\Tools\Settings;
|
||||
use OCA\NCDownloader\Tools\Youtube;
|
||||
use OCP\AppFramework\Controller;
|
||||
use OCP\AppFramework\Http\JSONResponse;
|
||||
@@ -27,8 +26,7 @@ class YoutubeController extends Controller
|
||||
$this->uid = $UserId;
|
||||
$this->urlGenerator = \OC::$server->getURLGenerator();
|
||||
$this->l10n = $IL10N;
|
||||
$this->settings = new Settings($UserId);
|
||||
$this->downloadDir = $this->settings->get('ncd_downloader_dir') ?? "/Downloads";
|
||||
$this->downloadDir = Helper::getDownloadDir();
|
||||
$this->dbconn = new DbHelper();
|
||||
$this->youtube = $youtube;
|
||||
$this->aria2 = $aria2;
|
||||
@@ -77,7 +75,10 @@ class YoutubeController extends Controller
|
||||
*/
|
||||
public function Download()
|
||||
{
|
||||
$params = array();
|
||||
$dlDir = $this->youtube->getDownloadDir();
|
||||
if (!is_writable($dlDir)) {
|
||||
return new JSONResponse(['error' => sprintf("%s is not writable", $dlDir)]);
|
||||
}
|
||||
$url = trim($this->request->getParam('text-input-value'));
|
||||
$yt = $this->youtube;
|
||||
if (in_array($this->request->getParam('extension'), $this->audio_extensions)) {
|
||||
@@ -119,7 +120,7 @@ class YoutubeController extends Controller
|
||||
}
|
||||
|
||||
$row = $this->dbconn->getByGid($gid);
|
||||
$data = $this->dbconn->getExtra($value["data"]);;
|
||||
$data = $this->dbconn->getExtra($row["data"]);
|
||||
if (!isset($data['pid'])) {
|
||||
if ($this->dbconn->deleteByGid($gid)) {
|
||||
$msg = sprintf("%s is deleted from database!", $gid);
|
||||
@@ -204,9 +205,9 @@ class YoutubeController extends Controller
|
||||
private function installYTD()
|
||||
{
|
||||
try {
|
||||
$filename = Helper::getFileName($yt->installUrl());
|
||||
$yt->setDownloadDir($this->dataDir . "/bin");
|
||||
$resp = $this->Save($yt->installUrl(), $filename);
|
||||
$filename = Helper::getFileName($this->installUrl());
|
||||
$this->setDownloadDir($this->dataDir . "/bin");
|
||||
$resp = $this->Save($this->installUrl(), $filename);
|
||||
return $resp;
|
||||
} catch (\Exception $e) {
|
||||
return ['error' => $e->getMessage()];
|
||||
|
||||
@@ -33,7 +33,6 @@ class TPB extends searchBase implements searchInterface
|
||||
if ($this->content) {
|
||||
return $this->content;
|
||||
}
|
||||
$content;
|
||||
try {
|
||||
$response = $this->client->request('GET', $this->searchUrl);
|
||||
$content = $response->getContent();
|
||||
|
||||
@@ -37,7 +37,6 @@ class bitSearch extends searchBase implements searchInterface
|
||||
if ($this->content) {
|
||||
return $this->content;
|
||||
}
|
||||
$content;
|
||||
try {
|
||||
$response = $this->client->request('GET', $this->searchUrl, ['query' => $this->query]);
|
||||
$content = $response->getContent();
|
||||
|
||||
@@ -34,7 +34,7 @@ class Personal implements ISettings {
|
||||
*/
|
||||
public function getForm() {
|
||||
$parameters = [
|
||||
"ncd_downloader_dir" => $this->settings->get("ncd_downloader_dir"),
|
||||
"ncd_downloader_dir" => Helper::getDownloadDir(),
|
||||
"ncd_torrents_dir" => $this->settings->get("ncd_torrents_dir"),
|
||||
"ncd_seed_ratio" => $this->settings->get("ncd_seed_ratio"),
|
||||
'ncd_seed_time_unit' => $this->settings->get("ncd_seed_time_unit"),
|
||||
|
||||
@@ -97,10 +97,14 @@ class Aria2
|
||||
|
||||
private function configure()
|
||||
{
|
||||
if (!is_dir($this->confDir)) {
|
||||
if ($this->confDir && !is_dir($this->confDir)) {
|
||||
mkdir($this->confDir, 0755, true);
|
||||
}
|
||||
if (!is_dir($dir = $this->getDownloadDir())) {
|
||||
$dir = "";
|
||||
if (($dir = $this->getDownloadDir()) && !is_dir($dir)) {
|
||||
mkdir($dir, 0755, true);
|
||||
}
|
||||
if (($dir = $this->getTorrentsDir()) && !is_dir($dir)) {
|
||||
mkdir($dir, 0755, true);
|
||||
}
|
||||
$this->followTorrent(true);
|
||||
@@ -123,12 +127,9 @@ class Aria2
|
||||
public function setTorrentsDir($dir)
|
||||
{
|
||||
$this->torrentsDir = $dir;
|
||||
if (!is_dir($dir)) {
|
||||
mkdir($dir, 0755, true);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
public function getTorrentsDir()
|
||||
public function getTorrentsDir(): string
|
||||
{
|
||||
return $this->torrentsDir;
|
||||
}
|
||||
@@ -136,12 +137,9 @@ class Aria2
|
||||
{
|
||||
$this->setOption('dir', $dir);
|
||||
$this->downloadDir = $dir;
|
||||
if (!is_dir($dir)) {
|
||||
mkdir($dir, 0755, true);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
public function getDownloadDir()
|
||||
public function getDownloadDir(): string
|
||||
{
|
||||
return $this->downloadDir;
|
||||
}
|
||||
|
||||
@@ -67,6 +67,7 @@ class DbHelper
|
||||
->andWhere('type = :type')
|
||||
->setParameter('uid', $uid)
|
||||
->setParameter('type', Helper::DOWNLOADTYPE['YOUTUBE-DL'])
|
||||
->orderBy('id', 'DESC')
|
||||
->execute();
|
||||
return $qb->fetchAll();
|
||||
}
|
||||
@@ -132,7 +133,12 @@ class DbHelper
|
||||
public function getExtra($data)
|
||||
{
|
||||
if ($this->getDBType() == "pgsql" && is_resource($data)) {
|
||||
if (function_exists("pg_unescape_bytea")) {
|
||||
$extra = pg_unescape_bytea(stream_get_contents($data));
|
||||
}
|
||||
else {
|
||||
$extra = stream_get_contents($data);
|
||||
}
|
||||
return unserialize($extra);
|
||||
}
|
||||
return unserialize($data);
|
||||
|
||||
@@ -2,15 +2,19 @@
|
||||
|
||||
namespace OCA\NCDownloader\Tools;
|
||||
|
||||
use Exception;
|
||||
use OCA\NCDownloader\Search\Sites\searchInterface;
|
||||
use OCA\NCDownloader\Tools\aria2Options;
|
||||
use OCA\NCDownloader\Tools\Settings;
|
||||
use OCP\IUser;
|
||||
use OC\Files\Filesystem;
|
||||
use OC_Util;
|
||||
|
||||
class Helper
|
||||
{
|
||||
public const DOWNLOADTYPE = ['ARIA2' => 1, 'YOUTUBE-DL' => 2, 'OTHERS' => 3];
|
||||
public const STATUS = ['ACTIVE' => 1, 'PAUSED' => 2, 'COMPLETE' => 3, 'WAITING' => 4, 'ERROR' => 5];
|
||||
const MAXLEN = 255;
|
||||
const MAXFILELEN = 255;
|
||||
|
||||
public static function isUrl($URL)
|
||||
{
|
||||
@@ -61,8 +65,8 @@ class Helper
|
||||
}
|
||||
public static function clipFilename($filename)
|
||||
{
|
||||
if (($len = strlen($filename)) > 64) {
|
||||
return substr($filename, $len - 64);
|
||||
if (($len = strlen($filename)) > self::MAXFILELEN) {
|
||||
return substr($filename, $len - self::MAXFILELEN);
|
||||
}
|
||||
return $filename;
|
||||
}
|
||||
@@ -73,7 +77,7 @@ class Helper
|
||||
} else {
|
||||
$filename = self::getUrlPath($url);
|
||||
}
|
||||
return substr($filename, 0, self::MAXLEN);
|
||||
return substr($filename, 0, self::MAXFILELEN);
|
||||
}
|
||||
public static function formatBytes($size, $precision = 2)
|
||||
{
|
||||
@@ -135,6 +139,9 @@ class Helper
|
||||
|
||||
public static function debug($msg)
|
||||
{
|
||||
if (is_array($msg)) {
|
||||
$msg = implode(",", $msg);
|
||||
}
|
||||
$logger = \OC::$server->getLogger();
|
||||
$logger->error($msg, ['app' => 'ncdownloader']);
|
||||
}
|
||||
@@ -279,14 +286,13 @@ class Helper
|
||||
];
|
||||
return $titles[$type];
|
||||
}
|
||||
// the relative home folder of a nextcloud user
|
||||
public static function getUserFolder($uid = null)
|
||||
// the relative home folder of a nextcloud user,e.g. /admin/files
|
||||
public static function getUserFolder($uid = null): string
|
||||
{
|
||||
if (!empty($rootFolder = Filesystem::getRoot())) {
|
||||
return $rootFolder;
|
||||
} else if (isset($uid)) {
|
||||
return "/" . $uid . "/files";
|
||||
|
||||
}
|
||||
return '';
|
||||
}
|
||||
@@ -374,4 +380,124 @@ class Helper
|
||||
return $sites;
|
||||
}
|
||||
|
||||
public static function getMountPoints(): ?array
|
||||
{
|
||||
return Filesystem::getMountPoints("/");
|
||||
}
|
||||
|
||||
public static function getDataDir(): string
|
||||
{
|
||||
return \OC::$server->getSystemConfig()->getValue('datadirectory');
|
||||
}
|
||||
|
||||
public static function getLocalFolder(string $path): string
|
||||
{
|
||||
if (self::getUID()) {
|
||||
OC_Util::setupFS();
|
||||
return Filesystem::getLocalFolder($path);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public static function getRealDownloadDir($uid = null): string
|
||||
{
|
||||
$dlDir = self::getDownloadDir();
|
||||
return self::getLocalFolder($dlDir);
|
||||
}
|
||||
public static function getRealTorrentsDir($uid = null): string
|
||||
{
|
||||
$dir = self::getSettings('ncd_torrents_dir', "/Torrents");
|
||||
return self::getLocalFolder($dir);
|
||||
}
|
||||
|
||||
public static function getUser(): ?IUser
|
||||
{
|
||||
return \OC::$server->getUserSession()->getUser();
|
||||
}
|
||||
|
||||
public static function getUID(): string
|
||||
{
|
||||
$user = self::getUser();
|
||||
$uid = $user ? $user->getUID() : "";
|
||||
return $uid;
|
||||
}
|
||||
|
||||
public static function getSettings($key, $default = null, int $type = Settings::TYPE['USER'])
|
||||
{
|
||||
$settings = self::newSettings();
|
||||
return $settings->setType($type)->get($key, $default);
|
||||
}
|
||||
|
||||
public static function newSettings($uid = null)
|
||||
{
|
||||
$uid = $uid ?? self::getUID();
|
||||
return Settings::create($uid);
|
||||
}
|
||||
|
||||
public static function getYoutubeConfig($uid = null): array
|
||||
{
|
||||
$config = [
|
||||
'binary' => self::getSettings("ncd_yt_binary", null, Settings::TYPE['SYSTEM']),
|
||||
'downloadDir' => Helper::getRealDownloadDir(),
|
||||
'settings' => self::newSettings()->getYoutube(),
|
||||
];
|
||||
return $config;
|
||||
}
|
||||
|
||||
public static function getAria2Config($uid = null): array
|
||||
{
|
||||
$options = [];
|
||||
$uid = $uid ?? self::getUID();
|
||||
$settings = self::newSettings($uid);
|
||||
$realDownloadDir = Helper::getRealDownloadDir($uid);
|
||||
$torrentsDir = Helper::getRealTorrentsDir($uid);
|
||||
$appPath = self::getAppPath();
|
||||
$dataDir = self::getDataDir();
|
||||
$aria2_dir = $dataDir . "/aria2";
|
||||
$options['seed_time'] = $settings->get("ncd_seed_time");
|
||||
$options['seed_ratio'] = $settings->get("ncd_seed_ratio");
|
||||
if (is_array($customSettings = $settings->getAria2())) {
|
||||
$options = array_merge($customSettings, $options);
|
||||
}
|
||||
$token = $settings->setType(Settings::TYPE['SYSTEM'])->get('ncd_rpctoken');
|
||||
$config = [
|
||||
'dir' => $realDownloadDir,
|
||||
'torrents_dir' => $torrentsDir,
|
||||
'conf_dir' => $aria2_dir,
|
||||
'token' => $token,
|
||||
'settings' => $options,
|
||||
'binary' => $settings->setType(Settings::TYPE['SYSTEM'])->get('ncd_aria2_binary'),
|
||||
'startHook' => $appPath . "/hooks/startHook.sh",
|
||||
'completeHook' => $appPath . "/hooks/completeHook.sh",
|
||||
];
|
||||
return $config;
|
||||
}
|
||||
|
||||
public static function getAppPath(): string
|
||||
{
|
||||
return \OC::$server->getAppManager()->getAppPath('ncdownloader');
|
||||
}
|
||||
public static function folderUpdated(string $dir): bool
|
||||
{
|
||||
if (!file_exists($dir)) {
|
||||
return false;
|
||||
}
|
||||
$checkFile = $dir . "/.lastmodified";
|
||||
if (!file_exists($checkFile)) {
|
||||
$time = \filemtime($dir);
|
||||
file_put_contents($checkFile, $time);
|
||||
return false;
|
||||
}
|
||||
$lastModified = (int) file_get_contents($checkFile);
|
||||
$time = \filemtime($dir);
|
||||
if ($time > $lastModified) {
|
||||
file_put_contents($checkFile, $time);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public static function getDownloadDir(): string
|
||||
{
|
||||
return self::getSettings('ncd_downloader_dir', "/Downloads");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,17 +7,19 @@ use OC\AllConfig;
|
||||
class Settings extends AllConfig
|
||||
{
|
||||
//@config OC\AppConfig
|
||||
private $config;
|
||||
private $appConfig;
|
||||
|
||||
//@OC\SystemConfig
|
||||
private $sysConfig;
|
||||
|
||||
//@OC\AllConfig
|
||||
private $allConfig;
|
||||
|
||||
private $user;
|
||||
private $appName;
|
||||
//type of settings (system = 1 or app =2)
|
||||
private $type;
|
||||
public const TYPE = ['SYSTEM' => 0x001, 'USER' => 0x010, 'APP' => 0x100];
|
||||
private static $instance = null;
|
||||
public const TYPE = ['SYSTEM' => 1, 'USER' => 2, 'APP' => 3];
|
||||
public function __construct($user = null)
|
||||
{
|
||||
$this->appConfig = \OC::$server->getAppConfig();
|
||||
@@ -29,6 +31,14 @@ class Settings extends AllConfig
|
||||
//$this->connAdapter = \OC::$server->getDatabaseConnection();
|
||||
//$this->conn = $this->connAdapter->getInner();
|
||||
}
|
||||
public static function create($user = null)
|
||||
{
|
||||
|
||||
if (!self::$instance) {
|
||||
self::$instance = new static($user);
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
public function setType($type)
|
||||
{
|
||||
$this->type = $type;
|
||||
@@ -104,141 +114,4 @@ class Settings extends AllConfig
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class customSettings
|
||||
{
|
||||
private $name = null;
|
||||
private $dbType = 0;
|
||||
private $table = 'ncdownloader_settings';
|
||||
private $uid = null;
|
||||
const PGSQL = 1, MYSQL = 2, SQL = 3;
|
||||
/* @var OC\DB\ConnectionAdapter */
|
||||
private $connAdapter;
|
||||
/* @var OC\DB\Connection */
|
||||
private $conn;
|
||||
private $type = 2; //personal = 2,admin =1
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
if (\OC::$server->getConfig()->getSystemValue('dbtype') == 'pgsql') {
|
||||
$this->dbType = PGSQL;
|
||||
}
|
||||
$this->connAdapter = \OC::$server->getDatabaseConnection();
|
||||
$this->conn = $this->connAdapter->getInner();
|
||||
|
||||
$this->prefixTable();
|
||||
}
|
||||
|
||||
private function prefixTable()
|
||||
{
|
||||
$this->table = '*PREFIX*' . $this->table;
|
||||
return $this->table;
|
||||
}
|
||||
|
||||
public function set($name, $value)
|
||||
{
|
||||
if ($this->have($name)) {
|
||||
$this->update($name, $value);
|
||||
} else {
|
||||
$this->insert($name, $value);
|
||||
}
|
||||
}
|
||||
public function setType($type)
|
||||
{
|
||||
$this->type = $type;
|
||||
}
|
||||
|
||||
public function get($name)
|
||||
{
|
||||
|
||||
if (isset($this->uid)) {
|
||||
$sql = sprintf("SELECT value FROM %s WHERE uid = ? AND name = ? LIMIT 1", $this->table);
|
||||
$query = \OC_DB::prepare($sql);
|
||||
$result = $query->execute(array($this->uid, $name));
|
||||
} else {
|
||||
$sql = sprintf("SELECT value FROM %s WHERE name = ? LIMIT 1", $this->table);
|
||||
$query = \OC_DB::prepare($sql);
|
||||
$result = $query->execute(array($name));
|
||||
}
|
||||
if ($query->rowCount() == 1) {
|
||||
return $result->fetchOne();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function setUID($uid)
|
||||
{
|
||||
$this->uid = $uid;
|
||||
}
|
||||
|
||||
public function setTable($table)
|
||||
{
|
||||
$this->table = $table;
|
||||
}
|
||||
public function getTable()
|
||||
{
|
||||
return $this->table;
|
||||
}
|
||||
|
||||
public function have($name)
|
||||
{
|
||||
if (isset($this->uid)) {
|
||||
$sql = sprintf("SELECT value FROM %s WHERE uid = ? AND name = ? AND type = ? LIMIT 1", $this->table);
|
||||
$query = \OC_DB::prepare($sql);
|
||||
$query->execute(array($name, $this->uid, $this->type));
|
||||
} else {
|
||||
$sql = sprintf("SELECT value FROM %s WHERE name = ? AND type = ? LIMIT 1", $this->table);
|
||||
$query = \OC_DB::prepare($sql);
|
||||
$query->execute(array($name, $this->type));
|
||||
}
|
||||
|
||||
if ($query->rowCount() == 1) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getAll()
|
||||
{
|
||||
$sql = 'SELECT `name`, `value` FROM `*PREFIX*' . $this->table . '`'
|
||||
. (!is_null($this->uid) ? ' WHERE `UID` = ?' : '');
|
||||
if ($this->DbType == 1) {
|
||||
$sql = 'SELECT "name", "value" FROM *PREFIX*' . $this->table . ''
|
||||
. (!is_null($this->uid) ? ' WHERE "uid" = ?' : '');
|
||||
}
|
||||
$query = \OC_DB::prepare($sql);
|
||||
|
||||
if (!is_null($this->uid)) {
|
||||
return $query->execute(array($this->uid));
|
||||
} else {
|
||||
return $query->execute();
|
||||
}
|
||||
}
|
||||
|
||||
public function update($value)
|
||||
{
|
||||
if (isset($this->uid)) {
|
||||
$sql = sprintf("UPDATE %s SET value = ? WHERE name = ? AND type = ? AND uid = ?", $this->table);
|
||||
//OCP\DB\IPreparedStatement
|
||||
$query = \OC_DB::prepare($sql);
|
||||
$query->execute(array($value, $name, $this->type, $this->uid));
|
||||
} else {
|
||||
$sql = sprintf("UPDATE %s SET value = ? WHERE name = ? AND type = ?", $this->table);
|
||||
//OCP\DB\IPreparedStatement
|
||||
$query = \OC_DB::prepare($sql);
|
||||
$query->execute(array($value, $name, $this->type));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function insert($name, $value)
|
||||
{
|
||||
$sql = sprintf("INSERT INTO %s (name,value,type,uid) VALUES(?,?,?,?)", $this->table);
|
||||
//OCP\DB\IPreparedStatement
|
||||
$query = \OC_DB::prepare($sql);
|
||||
$query->execute(array($name, $value, $this->type, $this->uid));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,9 +104,9 @@ class Youtube
|
||||
return $this;
|
||||
}
|
||||
|
||||
public static function create()
|
||||
public static function create($options)
|
||||
{
|
||||
return new self();
|
||||
return new self($options);
|
||||
}
|
||||
|
||||
public function setDownloadDir($dir)
|
||||
@@ -116,7 +116,7 @@ class Youtube
|
||||
|
||||
public function getDownloadDir()
|
||||
{
|
||||
return $this->getDownloadDir;
|
||||
return $this->downloadDir;
|
||||
}
|
||||
|
||||
public function prependOption(string $option)
|
||||
|
||||
@@ -66,8 +66,10 @@ class YoutubeHelper
|
||||
if ($file) {
|
||||
$extra = serialize($extra);
|
||||
if($this->dbconn->getDBType() == "pgsql"){
|
||||
if (function_exists("pg_escape_bytea")) {
|
||||
$extra = pg_escape_bytea($extra);
|
||||
}
|
||||
}
|
||||
$data = [
|
||||
'uid' => $this->user,
|
||||
'gid' => $this->gid,
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
namespace OCA\NCDownloader\Tools;
|
||||
|
||||
use OCA\NCDownloader\Tools\Helper;
|
||||
use OCA\NCDownloader\Tools\Settings;
|
||||
use OC\Files\Utils\Scanner;
|
||||
use \OCP\EventDispatcher\IEventDispatcher;
|
||||
|
||||
@@ -10,19 +9,17 @@ class folderScan
|
||||
{
|
||||
private $user;
|
||||
private $path;
|
||||
private $realDir;
|
||||
public function __construct($path = null, $user = null)
|
||||
{
|
||||
$this->user = $user ?? \OC::$server->getUserSession()->getUser()->getUID();
|
||||
$this->user = $user ?? Helper::getUID();
|
||||
$this->path = $path ?? $this->getDefaultPath();
|
||||
$this->realDir = \OC::$server->getSystemConfig()->getValue('datadirectory') . "/" . $this->path;
|
||||
$this->realDir = $realDir ?? Helper::getLocalFolder($this->path);
|
||||
}
|
||||
|
||||
public function getDefaultPath()
|
||||
{
|
||||
$settings = new Settings($this->user);
|
||||
$rootFolder = Helper::getUserFolder($this->user);
|
||||
$downloadDir = $settings->get('ncd_downloader_dir') ?? "/Downloads";
|
||||
return $rootFolder . "/" . ltrim($downloadDir, '/\\');
|
||||
return Helper::getUserFolder() . Helper::getDownloadDir();
|
||||
}
|
||||
public static function create($path = null, $user = null)
|
||||
{
|
||||
@@ -42,7 +39,7 @@ class folderScan
|
||||
|
||||
private function update()
|
||||
{
|
||||
if (!(self::folderUpdated($this->realDir))) {
|
||||
if (!(Helper::folderUpdated($this->realDir))) {
|
||||
return ['message' => "no change"];
|
||||
}
|
||||
$this->scan();
|
||||
@@ -55,34 +52,15 @@ class folderScan
|
||||
$this->scanner = new Scanner($this->user, \OC::$server->getDatabaseConnection(), \OC::$server->query(IEventDispatcher::class), $this->logger);
|
||||
try {
|
||||
$this->scanner->scan($this->path);
|
||||
return ['status' => 'OK', 'path' => $this->path];
|
||||
} catch (ForbiddenException $e) {
|
||||
return ['status' => true, 'path' => $this->path];
|
||||
} catch (\OCP\Files\ForbiddenException $e) {
|
||||
$this->logger->warning("Make sure you're running the scan command only as the user the web server runs as");
|
||||
} catch (\OCP\Files\NotFoundException $e) {
|
||||
$this->logger->warning("Path for the scan command not found: " . $e->getMessage());
|
||||
} catch (\Exception $e) {
|
||||
|
||||
$this->logger->warning("Exception during scan: " . $e->getMessage() . $e->getTraceAsString());
|
||||
}
|
||||
return ['status' => $e->getMessage(), 'path' => $this->path];
|
||||
|
||||
}
|
||||
public static function folderUpdated($dir)
|
||||
{
|
||||
if (!file_exists($dir)) {
|
||||
return false;
|
||||
}
|
||||
$checkFile = $dir . "/.lastmodified";
|
||||
if (!file_exists($checkFile)) {
|
||||
$time = \filemtime($dir);
|
||||
file_put_contents($checkFile, $time);
|
||||
return false;
|
||||
}
|
||||
$lastModified = (int) file_get_contents($checkFile);
|
||||
$time = \filemtime($dir);
|
||||
if ($time > $lastModified) {
|
||||
file_put_contents($checkFile, $time);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return ['status' => false, 'path' => $this->path];
|
||||
}
|
||||
|
||||
//update only folder is modified
|
||||
|
||||
18
src/App.vue
18
src/App.vue
@@ -56,18 +56,24 @@ export default {
|
||||
let element = event.target;
|
||||
let formWrapper = element.closest("form");
|
||||
let formData = helper.getData(formWrapper);
|
||||
let inputValue = formData["text-input-value"];
|
||||
let inputValue = formData["text-input-value"].trim();
|
||||
let message;
|
||||
if (!helper.isURL(inputValue) && !helper.isMagnetURI(inputValue)) {
|
||||
helper.error(t("ncdownloader", inputValue + " is Invalid"));
|
||||
return;
|
||||
}
|
||||
if (formData.type === "youtube-dl") {
|
||||
formData["extension"] = "";
|
||||
|
||||
if (formData["select-value-extension"] !== "defaultext") {
|
||||
formData["extension"] = formData["select-value-extension"];
|
||||
}
|
||||
message = helper.t("Download task started!");
|
||||
}
|
||||
if (!helper.isURL(inputValue) && !helper.isMagnetURI(inputValue)) {
|
||||
helper.error(t("ncdownloader", inputValue + " is Invalid"));
|
||||
return;
|
||||
helper.pollingYoutube();
|
||||
helper.setContentTableType("youtube-dl-downloads");
|
||||
} else {
|
||||
helper.polling();
|
||||
helper.setContentTableType("active-downloads");
|
||||
}
|
||||
if (message) {
|
||||
helper.info(message);
|
||||
@@ -90,7 +96,7 @@ export default {
|
||||
vm.$data.loading = 0;
|
||||
return;
|
||||
}
|
||||
helper.enabledPolling = 0;
|
||||
helper.disablePolling();
|
||||
contentTable.getInstance().loading();
|
||||
|
||||
let url = formWrapper.getAttribute("action");
|
||||
|
||||
@@ -1,50 +1,40 @@
|
||||
import helper from '../utils/helper'
|
||||
import eventHandler from '../lib/eventHandler';
|
||||
import Http from '../lib/http'
|
||||
|
||||
const basePath = "/apps/ncdownloader/status/";
|
||||
const tableContainer = ".table";
|
||||
export default {
|
||||
run: function () {
|
||||
|
||||
const clickHandler = (event, type) => {
|
||||
const clickHandler = (event) => {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
helper.hideDownload();
|
||||
let container = document.querySelector(tableContainer);
|
||||
let currentType = container.getAttribute("type");
|
||||
let path = basePath + type;
|
||||
if (type === "youtube-dl") {
|
||||
path = "/apps/ncdownloader/youtube/get";
|
||||
}
|
||||
let name = type + "-downloads";
|
||||
let element = event.target;
|
||||
//helper.hideDownload();
|
||||
let currentType = helper.getContentTableType();
|
||||
let path = element.getAttribute("path");
|
||||
let name = element.getAttribute("id");
|
||||
//avoid repeated click
|
||||
if (currentType === name && helper.enabledPolling) {
|
||||
if (currentType === name && helper.isPolling()) {
|
||||
return;
|
||||
}
|
||||
helper.enabledPolling = 1;
|
||||
//$(tableContainer).removeClass().addClass("table " + name);
|
||||
container.setAttribute("type", name);
|
||||
container.className = "table " + name;
|
||||
let delay = 15000;
|
||||
if (['active', 'youtube-dl'].includes(type)) {
|
||||
delay = 1500;
|
||||
helper.setContentTableType(name);
|
||||
let delay;
|
||||
if (!['active-downloads', 'youtube-dl-downloads'].includes(name)) {
|
||||
delay = 15000;
|
||||
}
|
||||
if (name === "youtube-dl-downloads") {
|
||||
helper.pollingYoutube();
|
||||
} else {
|
||||
helper.polling(delay, path);
|
||||
}
|
||||
helper.loop(helper.refresh, delay, ...[path])
|
||||
};
|
||||
eventHandler.add("click",".waiting-downloads a",event => clickHandler(event, 'waiting'));
|
||||
eventHandler.add("click",".complete-downloads a",event => clickHandler(event, 'complete'));
|
||||
eventHandler.add("click",".active-downloads a",event => clickHandler(event, 'active'));
|
||||
eventHandler.add("click",".fail-downloads a",event => clickHandler(event, 'fail'));
|
||||
eventHandler.add("click",".youtube-dl-downloads a",event => clickHandler(event, 'youtube-dl'));
|
||||
eventHandler.add("click", "#ncdownloader-table-wrapper",".download-file-folder", function (event) {
|
||||
eventHandler.add("click", ".download-queue a", event => clickHandler(event));
|
||||
eventHandler.add("click", "#ncdownloader-table-wrapper", ".download-file-folder", function (event) {
|
||||
event.stopPropagation();
|
||||
const path = "/apps/ncdownloader/update";
|
||||
let url = helper.generateUrl(path);
|
||||
Http.getInstance(url).setMethod('GET').send();
|
||||
event.preventDefault();
|
||||
let ele = event.target;
|
||||
let url = ele.getAttribute("href");
|
||||
helper.scanFolder().then(() => {
|
||||
helper.redirect(url);
|
||||
});
|
||||
});
|
||||
helper.polling(function (url) {
|
||||
url = helper.generateUrl(url);
|
||||
Http.getInstance(url).setMethod('GET').send();
|
||||
}, 60000, "/apps/ncdownloader/update");
|
||||
}
|
||||
}
|
||||
@@ -14,10 +14,11 @@ const eventHandler = {
|
||||
});
|
||||
return;
|
||||
}
|
||||
let el = document.querySelector(target);
|
||||
if (!el) {
|
||||
let items = document.querySelectorAll(target);
|
||||
if (!items) {
|
||||
return;
|
||||
}
|
||||
items.forEach(el => {
|
||||
el.addEventListener(eventType, function (e) {
|
||||
let element = e.target as HTMLElement;
|
||||
if (element === this && selector === target) {
|
||||
@@ -31,6 +32,8 @@ const eventHandler = {
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
},
|
||||
remove: function (element: target, eventType: string, callback: callback) {
|
||||
|
||||
|
||||
49
src/lib/polling.ts
Normal file
49
src/lib/polling.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
type callback = (...args: any[]) => void
|
||||
|
||||
class Polling {
|
||||
private static instance: Polling;
|
||||
private timeoutID: number;
|
||||
private delay: number = 1500;
|
||||
private enabled: boolean = false;
|
||||
constructor() {
|
||||
this.enabled = false;
|
||||
}
|
||||
static create(): Polling {
|
||||
this.instance = this.instance || new Polling();
|
||||
return this.instance;
|
||||
}
|
||||
|
||||
enable() {
|
||||
this.enabled = true;
|
||||
return this;
|
||||
}
|
||||
disable() {
|
||||
this.enabled = false;
|
||||
return this;
|
||||
}
|
||||
isEnabled() {
|
||||
return this.enabled;
|
||||
}
|
||||
setDelay(time: number = 1500): Polling {
|
||||
this.delay = time;
|
||||
return this;
|
||||
}
|
||||
|
||||
run(callback: callback, ...args: any[]) {
|
||||
this.clear().enable()
|
||||
callback(...args);
|
||||
let timeoutHandler = () => {
|
||||
if (this.enabled) {
|
||||
this.run(callback, ...args);
|
||||
}
|
||||
}
|
||||
this.timeoutID = window.setTimeout(timeoutHandler, this.delay);
|
||||
}
|
||||
clear() {
|
||||
if (this.timeoutID)
|
||||
window.clearTimeout(this.timeoutID);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
export default Polling;
|
||||
@@ -6,7 +6,7 @@ import "toastify-js/src/toastify.css"
|
||||
import { translate as t, translatePlural as n } from '@nextcloud/l10n'
|
||||
import contentTable from '../lib/contentTable';
|
||||
import Http from '../lib/http'
|
||||
|
||||
import Polling from "../lib/polling";
|
||||
const helper = {
|
||||
vue: {},
|
||||
addVue(name, object) {
|
||||
@@ -16,12 +16,45 @@ const helper = {
|
||||
return helper.vue[name];
|
||||
},
|
||||
generateUrl: generateUrl,
|
||||
loop(callback, delay, ...args) {
|
||||
callback(...args);
|
||||
clearTimeout(helper.timeoutID);
|
||||
this.polling(callback, delay, ...args);
|
||||
isPolling() {
|
||||
return Polling.create().isEnabled();
|
||||
},
|
||||
enabePolling() {
|
||||
Polling.create().enable();
|
||||
},
|
||||
disablePolling() {
|
||||
Polling.create().disable().clear();
|
||||
},
|
||||
polling(delay = 1500, path) {
|
||||
Polling.create().setDelay(delay).run(helper.refresh, path);
|
||||
},
|
||||
scanFolder(path = "/apps/ncdownloader/scanfolder") {
|
||||
let url = helper.generateUrl(path);
|
||||
return new Promise((resolve) => {
|
||||
Http.getInstance(url).setMethod('GET').setHandler(function (data) {
|
||||
resolve(data.status);
|
||||
}).send();
|
||||
});
|
||||
},
|
||||
pollingFolder(delay = 1500) {
|
||||
Polling.create().setDelay(delay).run(helper.scanFolder);
|
||||
},
|
||||
pollingYoutube(delay = 1500) {
|
||||
Polling.create().setDelay(delay).run(helper.refresh, "/apps/ncdownloader/youtube/get");
|
||||
},
|
||||
refresh(path) {
|
||||
path = path || "/apps/ncdownloader/status/active";
|
||||
let url = helper.generateUrl(path);
|
||||
Http.getInstance(url).setHandler(function (data) {
|
||||
if (data && data.row) {
|
||||
contentTable.getInstance(data.title, data.row).create();
|
||||
} else {
|
||||
contentTable.getInstance().noData();
|
||||
}
|
||||
if (data.counter)
|
||||
helper.updateCounter(data.counter);
|
||||
}).send();
|
||||
},
|
||||
enabledPolling: 0,
|
||||
trim(string, char) {
|
||||
return string.split(char).filter(Boolean).join(char)
|
||||
},
|
||||
@@ -32,15 +65,6 @@ const helper = {
|
||||
ucfirst(string) {
|
||||
return string.charAt(0).toUpperCase() + string.slice(1)
|
||||
},
|
||||
polling(callback, delay, ...args) {
|
||||
self = this;
|
||||
helper.timeoutID = setTimeout(function () {
|
||||
if (self.enabledPolling) {
|
||||
callback(...args);
|
||||
self.polling(callback, delay, ...args);
|
||||
}
|
||||
}, delay);
|
||||
},
|
||||
isURL(url) {
|
||||
let regex = '^((https?|ftp)://)([a-z0-9-]+\.)?(?:[-a-zA-Z0-9()@:%_\+.~#?&/=]+)$';
|
||||
const pattern = new RegExp(regex, 'i');
|
||||
@@ -115,19 +139,6 @@ const helper = {
|
||||
counter.innerHTML = '<div class="number">' + data[key] + '</div>';
|
||||
}
|
||||
},
|
||||
refresh(path) {
|
||||
path = path || "/apps/ncdownloader/status/active";
|
||||
let url = helper.generateUrl(path);
|
||||
Http.getInstance(url).setHandler(function (data) {
|
||||
if (data && data.row) {
|
||||
contentTable.getInstance(data.title, data.row).create();
|
||||
} else {
|
||||
contentTable.getInstance().noData();
|
||||
}
|
||||
if (data.counter)
|
||||
helper.updateCounter(data.counter);
|
||||
}).send();
|
||||
},
|
||||
html2DOM: function (htmlString) {
|
||||
const parser = new window.DOMParser();
|
||||
let doc = parser.parseFromString(htmlString, "text/html")
|
||||
@@ -253,6 +264,18 @@ const helper = {
|
||||
resetSearch: function (vm) {
|
||||
vm.$data.loading = 0;
|
||||
contentTable.getInstance([], []).clear();
|
||||
},
|
||||
redirect(url) {
|
||||
window.location.href = url;
|
||||
},
|
||||
getContentTableType() {
|
||||
let container = document.getElementById("ncdownloader-table-wrapper");
|
||||
return container.getAttribute("type");
|
||||
},
|
||||
setContentTableType(name) {
|
||||
let container = document.getElementById("ncdownloader-table-wrapper");
|
||||
container.setAttribute("type", name);
|
||||
container.className = "table " + name;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
<?php
|
||||
extract($_);
|
||||
$downloadsList = [
|
||||
["name" => "active", "label" => "Active Downloads", "id" => "active-downloads", "path" => "/apps/ncdownloader/status/active"],
|
||||
["name" => "waiting", "label" => "Waiting Downloads", "id" => "waiting-downloads", "path" => "/apps/ncdownloader/status/waiting"],
|
||||
["name" => "fail", "label" => "Failed Downloads", "id" => "failed-downloads", "path" => "/apps/ncdownloader/status/fail"],
|
||||
["name" => "complete", "label" => "Complete Downloads", "id" => "complete-downloads", "path" => "/apps/ncdownloader/status/complete"],
|
||||
["name" => "youtube-dl", "label" => "Youtube-dl Downloads", "id" => "youtube-dl-downloads", "path" => "/apps/ncdownloader/youtube/get"],
|
||||
];
|
||||
?>
|
||||
<div id="app-navigation">
|
||||
<?php if (!$ncd_hide_errors): ?>
|
||||
@@ -33,71 +40,21 @@ extract($_);
|
||||
</div>
|
||||
<?php endif;?>
|
||||
<ul>
|
||||
<li class="active-downloads">
|
||||
<?php foreach ($downloadsList as $value): ?>
|
||||
<li class="download-queue <?php print $value["id"];?>">
|
||||
<div class="app-navigation-entry-bullet"></div>
|
||||
<a role="button" tabindex="0" path="/apps/ncdownloader/dl/active">
|
||||
<?php print($l->t('Active Downloads'));?>
|
||||
<a role="button" tabindex="0" path="<?php print $value["path"];?>" id="<?php print $value["id"];?>">
|
||||
<?php print($l->t($value["label"]));?>
|
||||
</a>
|
||||
<div class="app-navigation-entry-utils">
|
||||
<ul>
|
||||
<li class="app-navigation-entry-utils-counter" id="active-downloads-counter">
|
||||
<div class="number"><?php print($_['counter']['active']);?></div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
<li class="waiting-downloads">
|
||||
<div class="app-navigation-entry-bullet"></div>
|
||||
<a role="button" tabindex="0" path="/apps/ncdownloader/dl/waiting">
|
||||
<?php print($l->t('Waiting Downloads'));?>
|
||||
</a>
|
||||
<div class="app-navigation-entry-utils">
|
||||
<ul>
|
||||
<li class="app-navigation-entry-utils-counter" id="waiting-downloads-counter">
|
||||
<div class="number"><?php print($_['counter']['waiting']);?></div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
<li class="complete-downloads">
|
||||
<div class="app-navigation-entry-bullet"></div>
|
||||
<a role="button" tabindex="0" path="/apps/ncdownloader/dl/complete">
|
||||
<?php print($l->t('Complete Downloads'));?>
|
||||
</a>
|
||||
<div class="app-navigation-entry-utils">
|
||||
<ul>
|
||||
<li class="app-navigation-entry-utils-counter" id="complete-downloads-counter">
|
||||
<div class="number"><?php print($_['counter']['complete']);?></div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
<li class="fail-downloads">
|
||||
<div class="app-navigation-entry-bullet"></div>
|
||||
<a role="button" tabindex="0" path="/apps/ncdownloader/dl/fail">
|
||||
<?php print($l->t('Failed Downloads'));?>
|
||||
</a>
|
||||
<div class="app-navigation-entry-utils">
|
||||
<ul>
|
||||
<li class="app-navigation-entry-utils-counter" id="fail-downloads-counter">
|
||||
<div class="number"><?php print($_['counter']['fail']);?></div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
<li class="youtube-dl-downloads">
|
||||
<div class="app-navigation-entry-bullet"></div>
|
||||
<a role="button" tabindex="0">
|
||||
<?php print($l->t('Youtube-dl Downloads'));?>
|
||||
</a>
|
||||
<div class="app-navigation-entry-utils">
|
||||
<ul>
|
||||
<li class="app-navigation-entry-utils-counter" id="youtube-dl-downloads-counter">
|
||||
<div class="number"><?php print($_['counter']['youtube-dl']);?></div>
|
||||
<li class="app-navigation-entry-utils-counter" id="<?php print $value["name"] . "-downloads-counter";?>">
|
||||
<div class="number"><?php print($_['counter'][$value["name"]]);?></div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
<?php endforeach;?>
|
||||
</ul>
|
||||
<div id="app-settings">
|
||||
<div id="app-settings-header">
|
||||
|
||||
Reference in New Issue
Block a user