improved user experience for novice user(including support for standalone aria2c and ytdl binaries);support for snap installation;close #19

This commit is contained in:
huangjx
2022-02-21 15:50:42 +08:00
parent 20b3e25369
commit 8e5ebdd8e7
11 changed files with 88 additions and 18 deletions

1
.gitignore vendored
View File

@@ -5,3 +5,4 @@ build.sh
test.php test.php
js/app* js/app*
exclude exclude
bin

View File

@@ -56,7 +56,8 @@ class Application extends App
$container->query('UserId'), $container->query('UserId'),
\OC::$server->getL10N('ncdownloader'), \OC::$server->getL10N('ncdownloader'),
//\OC::$server->getRootFolder(), //\OC::$server->getRootFolder(),
$container->query('Aria2') $container->query('Aria2'),
$container->query('Youtube')
); );
}); });

View File

@@ -6,6 +6,8 @@ use OCA\NCDownloader\Tools\Aria2;
use OCA\NCDownloader\Tools\Counters; use OCA\NCDownloader\Tools\Counters;
use OCA\NCDownloader\Tools\DbHelper; use OCA\NCDownloader\Tools\DbHelper;
use OCA\NCDownloader\Tools\Helper; use OCA\NCDownloader\Tools\Helper;
use OCA\NCDownloader\Tools\Settings;
use OCA\NCDownloader\Tools\Youtube;
use OCP\AppFramework\Controller; use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\JSONResponse; use OCP\AppFramework\Http\JSONResponse;
use OCP\AppFramework\Http\TemplateResponse; use OCP\AppFramework\Http\TemplateResponse;
@@ -23,7 +25,7 @@ class MainController extends Controller
private $aria2Opts; private $aria2Opts;
private $l10n; private $l10n;
public function __construct($appName, IRequest $request, $UserId, IL10N $IL10N, Aria2 $aria2) public function __construct($appName, IRequest $request, $UserId, IL10N $IL10N, Aria2 $aria2, Youtube $youtube)
{ {
parent::__construct($appName, $request); parent::__construct($appName, $request);
$this->appName = $appName; $this->appName = $appName;
@@ -36,6 +38,9 @@ class MainController extends Controller
$this->urlGenerator = \OC::$server->getURLGenerator(); $this->urlGenerator = \OC::$server->getURLGenerator();
$this->dbconn = new DbHelper(); $this->dbconn = new DbHelper();
$this->counters = new Counters($aria2, $this->dbconn, $UserId); $this->counters = new Counters($aria2, $this->dbconn, $UserId);
$this->youtube = $youtube;
$this->settings = new Settings($UserId);
} }
/** /**
* @NoAdminRequired * @NoAdminRequired
@@ -50,7 +55,13 @@ class MainController extends Controller
$params = array(); $params = array();
$params['aria2_running'] = $this->aria2->isRunning(); $params['aria2_running'] = $this->aria2->isRunning();
$params['aria2_installed'] = $this->aria2->isInstalled(); $params['aria2_installed'] = $this->aria2->isInstalled();
$params['youtube_installed'] = (bool) Helper::findBinaryPath('youtube-dl'); $params['aria2_bin'] = $this->aria2->getBin();
$params['aria2_executable'] = $this->aria2->isExecutable();
$params['youtube_installed'] = $this->youtube->isInstalled();
$params['youtube_bin'] = $this->youtube->getBin();
$params['youtube_executable'] = $this->youtube->isExecutable();
$params['ncd_hide_errors'] = $this->settings->get("ncd_hide_errors");
$params['counter'] = $this->counters->getCounters(); $params['counter'] = $this->counters->getCounters();
$params['settings_url'] = $this->urlGenerator->linkToRoute("settings.PersonalSettings.index", ['section' => 'ncdownloader']); $params['settings_url'] = $this->urlGenerator->linkToRoute("settings.PersonalSettings.index", ['section' => 'ncdownloader']);
$params['admin_settings_url'] = $this->urlGenerator->linkToRoute("settings.AdminSettings.index", ['section' => 'ncdownloader']); $params['admin_settings_url'] = $this->urlGenerator->linkToRoute("settings.AdminSettings.index", ['section' => 'ncdownloader']);

View File

@@ -132,5 +132,4 @@ class SettingsController extends Controller
} }
return ['message' => "Saved!"]; return ['message' => "Saved!"];
} }
} }

View File

@@ -38,10 +38,10 @@ class Aria2
); );
//turn keys in $options into variables //turn keys in $options into variables
extract($options); extract($options);
if (isset($binary) && @is_executable($binary)) { if (isset($binary) && $this->isExecutable($binary)) {
$this->bin = $binary; $this->bin = $binary;
} else { } else {
$this->bin = Helper::findBinaryPath('aria2c'); $this->bin = Helper::findBinaryPath('aria2c', __DIR__ . "/../../bin/aria2c");
} }
$this->setDownloadDir($dir); $this->setDownloadDir($dir);
$this->setTorrentsDir($torrents_dir); $this->setTorrentsDir($torrents_dir);
@@ -379,17 +379,27 @@ class Aria2
} }
public function isInstalled() public function isInstalled()
{ {
return (bool) (isset($this->bin) && @is_executable($this->bin)); return @is_file($this->bin);
} }
public function isExecutable()
{
return @is_executable($this->bin);
}
public function isRunning() public function isRunning()
{ {
$resp = $this->getSessionInfo(); $resp = $this->getSessionInfo();
return (bool) $resp; return (bool) $resp;
} }
public function getBin()
{
return $this->bin;
}
public function stop() public function stop()
{ {
$resp = $this->shutdown(); $resp = $this->shutdown();
sleep(1); sleep(3);
return $resp ?? null; return $resp ?? null;
} }
private function confTemplate() private function confTemplate()

View File

@@ -202,6 +202,7 @@ class Helper
if ($memcache->hasKey($program)) { if ($memcache->hasKey($program)) {
return $memcache->get($program); return $memcache->get($program);
} }
$dataPath = \OC::$server->getSystemConfig()->getValue('datadirectory'); $dataPath = \OC::$server->getSystemConfig()->getValue('datadirectory');
$paths = ['/usr/local/sbin', '/usr/local/bin', '/usr/sbin', '/usr/bin', '/sbin', '/bin', '/opt/bin', $dataPath . "/bin"]; $paths = ['/usr/local/sbin', '/usr/local/bin', '/usr/sbin', '/usr/bin', '/sbin', '/bin', '/opt/bin', $dataPath . "/bin"];
$result = $default; $result = $default;

View File

@@ -18,6 +18,7 @@ class Youtube
private $outTpl = "%(id)s-%(title).64s.%(ext)s"; private $outTpl = "%(id)s-%(title).64s.%(ext)s";
private $defaultDir = "/tmp/downloads"; private $defaultDir = "/tmp/downloads";
private $env = []; private $env = [];
private $bin;
public function __construct(array $options) public function __construct(array $options)
{ {
@@ -27,7 +28,7 @@ class Youtube
public function init(array $options) public function init(array $options)
{ {
extract($options); extract($options);
if (isset($binary) && @is_executable($binary)) { if (isset($binary) && $this->isExecutable($binary)) {
$this->bin = $binary; $this->bin = $binary;
} else { } else {
$this->bin = Helper::findBinaryPath('youtube-dl', __DIR__ . "/../../bin/youtube-dl"); $this->bin = Helper::findBinaryPath('youtube-dl', __DIR__ . "/../../bin/youtube-dl");
@@ -157,7 +158,7 @@ class Youtube
$data = ['link' => $url]; $data = ['link' => $url];
$process->run(function ($type, $buffer) use ($data, $process) { $process->run(function ($type, $buffer) use ($data, $process) {
if (Process::ERR === $type) { if (Process::ERR === $type) {
// $this->onError($buffer); // $this->onError($buffer);
} else { } else {
$data['pid'] = $process->getPid(); $data['pid'] = $process->getPid();
$this->onOutput($buffer, $data); $this->onOutput($buffer, $data);
@@ -235,7 +236,16 @@ class Youtube
} }
public function isInstalled() public function isInstalled()
{ {
return (bool) (isset($this->bin) && @is_executable($this->bin)); return @is_file($this->bin);
}
public function isExecutable()
{
return @is_executable($this->bin);
}
public function getBin()
{
return $this->bin;
} }
public static function install() public static function install()
{ {

View File

@@ -16,6 +16,7 @@ const basePath = "/apps/ncdownloader";
window.addEventListener('DOMContentLoaded', function () { window.addEventListener('DOMContentLoaded', function () {
helper.showErrors('[data-error-message]');
// inputAction.run(); // inputAction.run();
updatePage.run(); updatePage.run();
buttonActions.run(); buttonActions.run();
@@ -60,10 +61,20 @@ window.addEventListener('DOMContentLoaded', function () {
}).send(); }).send();
}) })
eventHandler.add("click", "#app-navigation", "#search-download", helper.showDownload); eventHandler.add("click", "#app-navigation", "#search-download", helper.showDownload);
delegate('#ncdownloader-table-wrapper', eventHandler.add("change", "#app-navigation", "#ncd-hide-errors", e => {
let data = {};
data["ncd_hide_errors"] = e.target.checked === "true";
console.log(data)
const url = helper.generateUrl(basePath + "/personal/save");
Http.getInstance(url).setData(data).setHandler(data => {
console.log(data);
}).send();
})
delegate('#app-ncdownloader-wrapper',
{ target: '[data-tippy-content]' } { target: '[data-tippy-content]' }
); );
}); });

View File

@@ -178,6 +178,12 @@ const helper = {
}, },
getScrollTop() { getScrollTop() {
return window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0; return window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;
},
showErrors(target) {
let errors = document.querySelectorAll(target);
errors.forEach(element => {
helper.message(element.getAttribute('data-error-message'), 20000);
})
} }
} }

View File

@@ -1,25 +1,38 @@
<?php <?php
$aria2_running = $_['aria2_running']; extract($_);
$youtube_installed = $_['youtube_installed']; $permission_error = sprintf("aria2 is installed but not executable.Please execute command sudo chmod 755 %s", $aria2_bin);
$aria2_installed = $_['aria2_installed']; if ($youtube_installed && !$youtube_executable) {
$ytb_error = sprintf("youtube-dl is installed but not executable.Please execute command sudo chmod 755 %s", $youtube_bin);
} else if (!$youtube_installed && !$youtube_executable) {
$ytb_error = "youtube-dl is not installed!";
}
?> ?>
<div id="app-navigation"> <div id="app-navigation">
<?php if ($ncd_hide_errors): ?>
<?php if (isset($ytb_error)): ?>
<div data-error-message="<?php print $l->t($ytb_error);?>"></div>
<?php endif;?>
<?php endif;?>
<div class="app-navigation-new" id="search-download" data-inputbox="form-input-wrapper"> <div class="app-navigation-new" id="search-download" data-inputbox="form-input-wrapper">
<button type="button" class="icon-add"> <button type="button" class="icon-add">
<?php print($l->t('Download & Search'));?> <?php print($l->t('Download & Search'));?>
</button> </button>
</div> </div>
<div class="app-navigation-new" id="start-aria2"> <div class="app-navigation-new" id="start-aria2">
<?php if ($aria2_installed): ?> <?php if ($aria2_installed && $aria2_executable): ?>
<button type="button" class="icon-power" <button type="button" class="icon-power"
data-aria2="<?php $aria2_running ? print $l->t('on') : print $l->t('off');?>"> data-aria2="<?php $aria2_running ? print $l->t('on') : print $l->t('off');?>">
<?php $aria2_running ? print $l->t('Stop Aria2') : print $l->t('Start Aria2');?> <?php $aria2_running ? print $l->t('Stop Aria2') : print $l->t('Start Aria2');?>
</button> </button>
</button> </button>
<?php elseif ($aria2_installed && !$aria2_executable): ?>
<button type="button" class="icon-power notinstalled" data-error-message="<?php print $l->t($permission_error);?>">
<?php print $l->t("aria2c is installed but not executable");?>
</button>
<?php else: ?> <?php else: ?>
<button type="button" class="icon-power notinstalled"> <button type="button" class="icon-power notinstalled">
<?php print $l->t('Aria2 is not installed!');?> <?php print $l->t("aria2c is not installed!");?>
</button> </button>
<?php endif;?> <?php endif;?>
</div> </div>

View File

@@ -1,5 +1,9 @@
<?php <?php
extract($_); extract($_);
$checked = '';
if ($ncd_hide_errors) {
$checked = "checked";
}
?> ?>
<div id="app-settings"> <div id="app-settings">
<div id="app-settings-header"> <div id="app-settings-header">
@@ -11,6 +15,9 @@ extract($_);
</div> </div>
<div id="app-settings-content"> <div id="app-settings-content">
<ul id="ncdownloader-settings-collapsible-container"> <ul id="ncdownloader-settings-collapsible-container">
<li class="ncdownloader-settings-item" data-tippy-content="check this to show or suppress errors">
<input class="checkbox" type="checkbox" value="<?php print($ncd_hide_errors);?>" <?php print($checked);?> id="ncd-hide-errors"><label for="ncd-hide-errors"><?php p($l->t('Hide Errors'));?></label>
</li>
<li class="ncdownloader-settings-item"> <li class="ncdownloader-settings-item">
<a href="<?php p($l->t($settings_url));?>" title="<?php p($l->t('Personal Settings'));?>" > <a href="<?php p($l->t($settings_url));?>" title="<?php p($l->t('Personal Settings'));?>" >
<?php p($l->t('Personal Settings'));?> <?php p($l->t('Personal Settings'));?>