diff --git a/Makefile b/Makefile
index efe5ae6..ae9e224 100644
--- a/Makefile
+++ b/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
diff --git a/appinfo/application.php b/appinfo/application.php
index 40694a2..6cd7107 100644
--- a/appinfo/application.php
+++ b/appinfo/application.php
@@ -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;
- }
-
}
diff --git a/appinfo/info.xml b/appinfo/info.xml
index b592c1f..20a6df6 100644
--- a/appinfo/info.xml
+++ b/appinfo/info.xml
@@ -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
- 0.9.1
+ 0.9.16
agpl
jiaxinhuang
NCDownloader
diff --git a/appinfo/routes.php b/appinfo/routes.php
index 700fc17..c6a5ec2 100644
--- a/appinfo/routes.php
+++ b/appinfo/routes.php
@@ -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'],
diff --git a/lib/Controller/Aria2Controller.php b/lib/Controller/Aria2Controller.php
index 1951872..2fa121b 100644
--- a/lib/Controller/Aria2Controller.php
+++ b/lib/Controller/Aria2Controller.php
@@ -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('%s', $folderLink, $filename);
- $fileInfo = sprintf(' %s | %s', $extra ? $extra['link'] : 'nolink', $total, date("Y-m-d H:i:s", $timestamp));
+ $fileInfo = sprintf(' %s | %s', $extra["link"] ?? 'nolink', $total, date("Y-m-d H:i:s", $timestamp));
$tmp['filename'] = array($filename, $fileInfo);
if ($this->aria2->methodName === "tellStopped") {
diff --git a/lib/Controller/MainController.php b/lib/Controller/MainController.php
index 572447d..066926c 100644
--- a/lib/Controller/MainController.php
+++ b/lib/Controller/MainController.php
@@ -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);
+ }
+
}
diff --git a/lib/Controller/SettingsController.php b/lib/Controller/SettingsController.php
index 91f4a89..06c8af4 100644
--- a/lib/Controller/SettingsController.php
+++ b/lib/Controller/SettingsController.php
@@ -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));
diff --git a/lib/Controller/YoutubeController.php b/lib/Controller/YoutubeController.php
index a023525..ebc2cbd 100644
--- a/lib/Controller/YoutubeController.php
+++ b/lib/Controller/YoutubeController.php
@@ -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()];
diff --git a/lib/Search/Sites/TPB.php b/lib/Search/Sites/TPB.php
index d17b1bc..15b265b 100644
--- a/lib/Search/Sites/TPB.php
+++ b/lib/Search/Sites/TPB.php
@@ -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();
diff --git a/lib/Search/Sites/bitSearch.php b/lib/Search/Sites/bitSearch.php
index a275f32..8e18002 100644
--- a/lib/Search/Sites/bitSearch.php
+++ b/lib/Search/Sites/bitSearch.php
@@ -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();
diff --git a/lib/Settings/Personal.php b/lib/Settings/Personal.php
index c289834..3293be5 100644
--- a/lib/Settings/Personal.php
+++ b/lib/Settings/Personal.php
@@ -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"),
diff --git a/lib/Tools/Aria2.php b/lib/Tools/Aria2.php
index 14dda87..af730d7 100644
--- a/lib/Tools/Aria2.php
+++ b/lib/Tools/Aria2.php
@@ -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;
}
diff --git a/lib/Tools/DbHelper.php b/lib/Tools/DbHelper.php
index 6019864..143f452 100644
--- a/lib/Tools/DbHelper.php
+++ b/lib/Tools/DbHelper.php
@@ -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)) {
- $extra = pg_unescape_bytea(stream_get_contents($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);
diff --git a/lib/Tools/Helper.php b/lib/Tools/Helper.php
index fd6641a..dfb7af3 100644
--- a/lib/Tools/Helper.php
+++ b/lib/Tools/Helper.php
@@ -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");
+ }
}
diff --git a/lib/Tools/Settings.php b/lib/Tools/Settings.php
index 631f499..18e9578 100644
--- a/lib/Tools/Settings.php
+++ b/lib/Tools/Settings.php
@@ -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));
-
- }
}
diff --git a/lib/Tools/Youtube.php b/lib/Tools/Youtube.php
index 912df4e..cedfae1 100644
--- a/lib/Tools/Youtube.php
+++ b/lib/Tools/Youtube.php
@@ -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)
diff --git a/lib/Tools/YoutubeHelper.php b/lib/Tools/YoutubeHelper.php
index 5ffaadd..6f94801 100644
--- a/lib/Tools/YoutubeHelper.php
+++ b/lib/Tools/YoutubeHelper.php
@@ -66,7 +66,9 @@ class YoutubeHelper
if ($file) {
$extra = serialize($extra);
if($this->dbconn->getDBType() == "pgsql"){
- $extra = pg_escape_bytea($extra);
+ if (function_exists("pg_escape_bytea")) {
+ $extra = pg_escape_bytea($extra);
+ }
}
$data = [
'uid' => $this->user,
diff --git a/lib/Tools/folderScan.php b/lib/Tools/folderScan.php
index b347855..98c2d4a 100644
--- a/lib/Tools/folderScan.php
+++ b/lib/Tools/folderScan.php
@@ -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
diff --git a/src/App.vue b/src/App.vue
index 2e5080e..0514638 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -56,19 +56,25 @@ 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 (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;
}
+ 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!");
+ 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");
diff --git a/src/actions/updatePage.js b/src/actions/updatePage.js
index 4aea671..3b584ec 100644
--- a/src/actions/updatePage.js
+++ b/src/actions/updatePage.js
@@ -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");
}
}
\ No newline at end of file
diff --git a/src/lib/eventHandler.ts b/src/lib/eventHandler.ts
index bebabcd..81ad419 100644
--- a/src/lib/eventHandler.ts
+++ b/src/lib/eventHandler.ts
@@ -14,23 +14,26 @@ const eventHandler = {
});
return;
}
- let el = document.querySelector(target);
- if (!el) {
+ let items = document.querySelectorAll(target);
+ if (!items) {
return;
}
- el.addEventListener(eventType, function (e) {
- let element = e.target as HTMLElement;
- if (element === this && selector === target) {
- callback.call(element, e);
- return;
- }
- for (; element && element != this; element = element.parentElement) {
- if (typeof selector === "string" && element.matches(selector)) {
+ items.forEach(el => {
+ el.addEventListener(eventType, function (e) {
+ let element = e.target as HTMLElement;
+ if (element === this && selector === target) {
callback.call(element, e);
- break;
+ return;
}
- }
- });
+ for (; element && element != this; element = element.parentElement) {
+ if (typeof selector === "string" && element.matches(selector)) {
+ callback.call(element, e);
+ break;
+ }
+ }
+ });
+ })
+
},
remove: function (element: target, eventType: string, callback: callback) {
diff --git a/src/lib/polling.ts b/src/lib/polling.ts
new file mode 100644
index 0000000..0b4dedf
--- /dev/null
+++ b/src/lib/polling.ts
@@ -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;
\ No newline at end of file
diff --git a/src/utils/helper.js b/src/utils/helper.js
index aba3181..f343a21 100644
--- a/src/utils/helper.js
+++ b/src/utils/helper.js
@@ -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 = '
' + data[key] + '
';
}
},
- 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;
}
}
diff --git a/templates/Navigation.php b/templates/Navigation.php
index 643b931..e23ef4d 100644
--- a/templates/Navigation.php
+++ b/templates/Navigation.php
@@ -1,5 +1,12 @@
"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"],
+];
?>
@@ -33,71 +40,21 @@ extract($_);