From 1e76572990de896f3e3a49c74cd4c86a05b05c7c Mon Sep 17 00:00:00 2001 From: Simon Vieille Date: Fri, 20 Nov 2020 13:39:12 +0100 Subject: [PATCH 1/8] add products types edition --- lib/Controller/PrinterController.php | 98 +++++++++++++++------------- 1 file changed, 54 insertions(+), 44 deletions(-) diff --git a/lib/Controller/PrinterController.php b/lib/Controller/PrinterController.php index e390408..70b7de0 100644 --- a/lib/Controller/PrinterController.php +++ b/lib/Controller/PrinterController.php @@ -1,59 +1,69 @@ language = \OC::$server->getL10N('printer'); + } - public function __construct($appName, IRequest $request) { + /** + * callback function to get md5 hash of a file. + * + * @NoAdminRequired + * + * @param (string) $sourcefile - filename + * @param (string) $orientation - Orientation of printed file + */ + public function printfile($sourcefile, $orientation) + { + $filefullpath = \OC\Files\Filesystem::getLocalFile($sourcefile); - parent::__construct($appName, $request); + $options = [ + 'landscape' => [ + 'lpr', + $filefullpath, + ], + 'portrait' => [ + 'lpr', + '-o', + 'orientation-requested=4', + $filefullpath, + ], + ]; - // get i10n - $this->language = \OC::$server->getL10N('printer'); + $success = [ + 'response' => 'success', + 'msg' => $this->language->t('Print succeeded!'), + ]; - } + $error = [ + 'response' => 'error', + 'msg' => $this->language->t('Print failed'), + ]; - /** - * callback function to get md5 hash of a file - * @NoAdminRequired - * @param (string) $sourcefile - filename - * @param (string) $orientation - Orientation of printed file - */ - public function printfile($sourcefile, $orientation) { - if($orientation === "landscape") { - $filefullpath = \OC\Files\Filesystem::getLocalFile($sourcefile); - exec('lpr "' . $filefullpath . '"'); - return new JSONResponse( - array( - 'response' => 'success', - 'msg' => $this->language->t('Print succeeded!') - ) - ); - } + if (!isset($options[$orientation])) { + return new JSONResponse($error); + } - if($orientation === "portrait"){ - $filefullpath = \OC\Files\Filesystem::getLocalFile($sourcefile); - exec('lpr -o orientation-requested=4 "' . $filefullpath . '"'); - return new JSONResponse( - array( - 'response' => 'success', - 'msg' => $this->language->t('Print succeeded!') - ) - ); - } else { - return new JSONResponse( - array( - 'response' => 'error', - 'msg' => $this->language->t('Print failed') - ) - ); - }; - } + $process = new Process($options[$orientation]); + $process->run(); + + if ($process->isSuccessful()) { + return new JSONResponse($success); + } + + return new JSONResponse($error); + } } From 18e0c134642c4f59759b2930750da7b8ff7c6c8d Mon Sep 17 00:00:00 2001 From: Simon Vieille Date: Fri, 20 Nov 2020 14:00:31 +0100 Subject: [PATCH 2/8] add dependency to symfony/process --- composer.json | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 composer.json diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..5075602 --- /dev/null +++ b/composer.json @@ -0,0 +1,5 @@ +{ + "require": { + "symfony/process": "^4.4" + } +} From 11b873df02d2c2c2419f45bc4d4b828ce5ff0bc6 Mon Sep 17 00:00:00 2001 From: Simon Vieille Date: Fri, 20 Nov 2020 14:01:44 +0100 Subject: [PATCH 3/8] add service to manage printer --- lib/Controller/PrinterController.php | 46 ++++++++++++---------------- lib/Service/Printer.php | 44 ++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 27 deletions(-) create mode 100644 lib/Service/Printer.php diff --git a/lib/Controller/PrinterController.php b/lib/Controller/PrinterController.php index 70b7de0..4bfd574 100644 --- a/lib/Controller/PrinterController.php +++ b/lib/Controller/PrinterController.php @@ -6,42 +6,35 @@ use OCP\AppFramework\Controller; use OCP\AppFramework\Http\JSONResponse; use OCP\IRequest; use Symfony\Component\Process\Process; +use OCA\Printer\Service\Printer; +use Symfony\Component\Process\Exception\ProcessFailedException; class PrinterController extends Controller { + /** + * @var OC\L10N\LazyL10N + */ protected $language; - public function __construct($appName, IRequest $request) + /** + * @var Printer + */ + protected $printer; + + public function __construct(string $appName, IRequest $request, Printer $printer) { parent::__construct($appName, $request); $this->language = \OC::$server->getL10N('printer'); + $this->printer = $printer; } /** - * callback function to get md5 hash of a file. - * * @NoAdminRequired - * - * @param (string) $sourcefile - filename - * @param (string) $orientation - Orientation of printed file */ - public function printfile($sourcefile, $orientation) + public function printfile(string $sourcefile, string $orientation): JSONResponse { - $filefullpath = \OC\Files\Filesystem::getLocalFile($sourcefile); - - $options = [ - 'landscape' => [ - 'lpr', - $filefullpath, - ], - 'portrait' => [ - 'lpr', - '-o', - 'orientation-requested=4', - $filefullpath, - ], - ]; + $file = \OC\Files\Filesystem::getLocalFile($sourcefile); $success = [ 'response' => 'success', @@ -53,17 +46,16 @@ class PrinterController extends Controller 'msg' => $this->language->t('Print failed'), ]; - if (!isset($options[$orientation])) { + if (!$this->printer->isValidOrirentation($orientation)) { return new JSONResponse($error); } - $process = new Process($options[$orientation]); - $process->run(); + try { + $this->printer->print($file, $orientation); - if ($process->isSuccessful()) { return new JSONResponse($success); + } catch (ProcessFailedException $exception) { + return new JSONResponse($error); } - - return new JSONResponse($error); } } diff --git a/lib/Service/Printer.php b/lib/Service/Printer.php new file mode 100644 index 0000000..3150e11 --- /dev/null +++ b/lib/Service/Printer.php @@ -0,0 +1,44 @@ + + */ +class Printer +{ + public function print(string $file, string $orientation) + { + $options = [ + 'landscape' => [ + 'lpr', + $file, + ], + 'portrait' => [ + 'lpr', + '-o', + 'orientation-requested=4', + $file, + ], + ]; + + $process = new Process($options[$orientation]); + $process->mustRun(); + } + + /** + * Validates an orientation. + */ + public function isValidOrirentation(string $orientation): bool + { + return in_array($orientation, [ + 'landscape', + 'portrait', + ]); + } +} From f854accbcc5c54d38b1efe5369a1e2952a3b2ea1 Mon Sep 17 00:00:00 2001 From: Simon Vieille Date: Fri, 20 Nov 2020 14:02:06 +0100 Subject: [PATCH 4/8] add ignored files (git) --- .gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..61ead86 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/vendor From 497a9f48928a0998cfb861aab5afed48a668d64b Mon Sep 17 00:00:00 2001 From: Simon Vieille Date: Fri, 20 Nov 2020 15:45:11 +0100 Subject: [PATCH 5/8] add admin section to select groups allowed to print --- appinfo/info.xml | 6 +- css/admin.css | 3 + js/admin.js | 65 ++++++++++++++++++++ lib/Config.php | 66 +++++++++++++++++++++ lib/Controller/PrinterController.php | 24 +++++++- lib/Settings/Admin/AllowedGroups.php | 63 ++++++++++++++++++++ lib/Settings/Admin/Section.php | 48 +++++++++++++++ templates/settings/admin/allowed-groups.php | 38 ++++++++++++ 8 files changed, 309 insertions(+), 4 deletions(-) create mode 100644 css/admin.css create mode 100644 js/admin.js create mode 100644 lib/Config.php create mode 100644 lib/Settings/Admin/AllowedGroups.php create mode 100644 lib/Settings/Admin/Section.php create mode 100644 templates/settings/admin/allowed-groups.php diff --git a/appinfo/info.xml b/appinfo/info.xml index c576f0e..95a29f3 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -28,6 +28,10 @@ https://github.com/e-alfred/nextcloud-printer/issues https://github.com/e-alfred/nextcloud-printer/raw/master/screenshots/printer.gif - + + + OCA\Printer\Settings\Admin\AllowedGroups + OCA\Printer\Settings\Admin\Section + diff --git a/css/admin.css b/css/admin.css new file mode 100644 index 0000000..d77db4d --- /dev/null +++ b/css/admin.css @@ -0,0 +1,3 @@ +#printer_admin input { + vertical-align: middle; +} diff --git a/js/admin.js b/js/admin.js new file mode 100644 index 0000000..901d7de --- /dev/null +++ b/js/admin.js @@ -0,0 +1,65 @@ +let elements = [] + +const selector = '#printer-message'; + +const appConfig = (name, value, callbacks) => { + OCP.AppConfig.setValue('printer', name, value, callbacks) +} + +const saveSettings = (key) => { + const element = elements.get(key) + let value + let name + + if (jQuery(element).is('[data-checkbox]')) { + name = jQuery(element).attr('data-name') + const inputs = jQuery('input[name="' + name + '[]"]:checked') + value = [] + + inputs.each((i, v) => { + value.push(v.value) + }) + + value = JSON.stringify(value) + } else { + name = jQuery(element).attr('name') + value = jQuery(element).val() + } + + const size = elements.length + + if (name === 'cache') { + ++value + } + + const callbacks = { + success: () => { + OC.msg.finishedSuccess( + selector, + t('printer', (key + 1) + '/' + size) + ) + + if (key < size - 1) { + saveSettings(++key) + } else { + OC.msg.finishedSuccess(selector, t('printer', 'Saved')) + } + }, + error: () => { + OC.msg.finishedError(selector, t('printer', 'Error while saving "' + element + '"')) + } + } + + appConfig(name, value, callbacks) +} + +jQuery(document).ready(() => { + elements = jQuery('.printer-setting') + + jQuery('#printer-save').on('click', (event) => { + event.preventDefault() + OC.msg.startSaving(selector) + + saveSettings(0) + }); +}); diff --git a/lib/Config.php b/lib/Config.php new file mode 100644 index 0000000..d103c92 --- /dev/null +++ b/lib/Config.php @@ -0,0 +1,66 @@ +config = $config; + $this->secureRandom = $secureRandom; + $this->groupManager = $groupManager; + $this->timeFactory = $timeFactory; + } + + /** + * @return string[] + */ + public function getAllowedGroupIds(): array + { + $groups = $this->config->getAppValue('printer', 'allowed_groups', '[]'); + $groups = json_decode($groups, true); + + return \is_array($groups) ? $groups : []; + } + + public function isDisabledForUser(IUser $user): bool + { + $allowedGroups = $this->getAllowedGroupIds(); + + if (empty($allowedGroups)) { + return false; + } + + $userGroups = $this->groupManager->getUserGroupIds($user); + + return empty(array_intersect($allowedGroups, $userGroups)); + } +} diff --git a/lib/Controller/PrinterController.php b/lib/Controller/PrinterController.php index 4bfd574..f827d27 100644 --- a/lib/Controller/PrinterController.php +++ b/lib/Controller/PrinterController.php @@ -2,11 +2,12 @@ namespace OCA\Printer\Controller; +use OCA\Printer\Config; +use OCA\Printer\Service\Printer; use OCP\AppFramework\Controller; use OCP\AppFramework\Http\JSONResponse; use OCP\IRequest; -use Symfony\Component\Process\Process; -use OCA\Printer\Service\Printer; +use OCP\IUserSession; use Symfony\Component\Process\Exception\ProcessFailedException; class PrinterController extends Controller @@ -21,12 +22,18 @@ class PrinterController extends Controller */ protected $printer; - public function __construct(string $appName, IRequest $request, Printer $printer) + /** + * @var Config + */ + protected $config; + + public function __construct(string $appName, IRequest $request, Printer $printer, Config $config) { parent::__construct($appName, $request); $this->language = \OC::$server->getL10N('printer'); $this->printer = $printer; + $this->config = $config; } /** @@ -46,6 +53,17 @@ class PrinterController extends Controller 'msg' => $this->language->t('Print failed'), ]; + $notAllowed = [ + 'response' => 'error', + 'msg' => $this->language->t('User not allowed'), + ]; + + $user = \OC::$server[IUserSession::class]->getUser(); + + if (!$user || $this->config->isDisabledForUser($user)) { + return new JSONResponse($notAllowed); + } + if (!$this->printer->isValidOrirentation($orientation)) { return new JSONResponse($error); } diff --git a/lib/Settings/Admin/AllowedGroups.php b/lib/Settings/Admin/AllowedGroups.php new file mode 100644 index 0000000..406f979 --- /dev/null +++ b/lib/Settings/Admin/AllowedGroups.php @@ -0,0 +1,63 @@ +config = $config; + $this->initialStateService = $initialStateService; + $this->groupManager = $groupManager; + } + + public function getForm(): TemplateResponse + { + $this->initialStateService->provideInitialState( + 'printer', + 'allowed_groups', + $this->config->getAllowedGroupIds() + ); + + $groups = $this->groupManager->search('', 100); + $allowedGroups = $this->config->getAllowedGroupIds(); + + return new TemplateResponse('printer', 'settings/admin/allowed-groups', [ + 'groups' => $groups, + 'allowedGroups' => $allowedGroups, + ], ''); + } + + public function getSection(): string + { + return 'printer'; + } + + public function getPriority(): int + { + return 10; + } +} diff --git a/lib/Settings/Admin/Section.php b/lib/Settings/Admin/Section.php new file mode 100644 index 0000000..ed5cb07 --- /dev/null +++ b/lib/Settings/Admin/Section.php @@ -0,0 +1,48 @@ +url = $url; + $this->l = $l; + } + + public function getIcon(): string + { + return $this->url->imagePath('spreed', 'app-dark.svg'); + } + + public function getID(): string + { + return 'printer'; + } + + public function getName(): string + { + return $this->l->t('Printer'); + } + + public function getPriority(): int + { + return 70; + } +} diff --git a/templates/settings/admin/allowed-groups.php b/templates/settings/admin/allowed-groups.php new file mode 100644 index 0000000..2553000 --- /dev/null +++ b/templates/settings/admin/allowed-groups.php @@ -0,0 +1,38 @@ + +
+
+

t('Limit to groups')) ?>

+

+ t('When at least one group is selected, only people of the listed groups can print.')); ?> +

+ +
    + +
  • + getGid(), $_['allowedGroups'])): ?> + checked + + > + + +
  • + +
+ + + + +
+
From ae6f7552dc1ca95bdd8a357fbaad1c8b76abcf2f Mon Sep 17 00:00:00 2001 From: Simon Vieille Date: Fri, 20 Nov 2020 15:52:23 +0100 Subject: [PATCH 6/8] add app icon --- img/app-dark.svg | 1 + lib/Settings/Admin/Section.php | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 img/app-dark.svg diff --git a/img/app-dark.svg b/img/app-dark.svg new file mode 100644 index 0000000..627af08 --- /dev/null +++ b/img/app-dark.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/lib/Settings/Admin/Section.php b/lib/Settings/Admin/Section.php index ed5cb07..e9791b3 100644 --- a/lib/Settings/Admin/Section.php +++ b/lib/Settings/Admin/Section.php @@ -28,7 +28,7 @@ class Section implements IIconSection public function getIcon(): string { - return $this->url->imagePath('spreed', 'app-dark.svg'); + return $this->url->imagePath('printer', 'app-dark.svg'); } public function getID(): string From 44c27053cbd27518d2ab009a901b91e40d443532 Mon Sep 17 00:00:00 2001 From: Simon Vieille Date: Fri, 20 Nov 2020 16:08:24 +0100 Subject: [PATCH 7/8] remove useless code --- lib/Config.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/Config.php b/lib/Config.php index d103c92..08fc703 100644 --- a/lib/Config.php +++ b/lib/Config.php @@ -32,12 +32,10 @@ class Config */ private $secureRandom; - public function __construct(IConfig $config, ISecureRandom $secureRandom, IGroupManager $groupManager, ITimeFactory $timeFactory) + public function __construct(IConfig $config, IGroupManager $groupManager) { $this->config = $config; - $this->secureRandom = $secureRandom; $this->groupManager = $groupManager; - $this->timeFactory = $timeFactory; } /** From 79d1958e9b4bdb73786b1aa735f56cd3fd2d53c0 Mon Sep 17 00:00:00 2001 From: Simon Vieille Date: Fri, 20 Nov 2020 16:13:45 +0100 Subject: [PATCH 8/8] fix typo --- lib/Controller/PrinterController.php | 2 +- lib/Service/Printer.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Controller/PrinterController.php b/lib/Controller/PrinterController.php index f827d27..8999a13 100644 --- a/lib/Controller/PrinterController.php +++ b/lib/Controller/PrinterController.php @@ -64,7 +64,7 @@ class PrinterController extends Controller return new JSONResponse($notAllowed); } - if (!$this->printer->isValidOrirentation($orientation)) { + if (!$this->printer->isValidOrientation($orientation)) { return new JSONResponse($error); } diff --git a/lib/Service/Printer.php b/lib/Service/Printer.php index 3150e11..6f20930 100644 --- a/lib/Service/Printer.php +++ b/lib/Service/Printer.php @@ -34,7 +34,7 @@ class Printer /** * Validates an orientation. */ - public function isValidOrirentation(string $orientation): bool + public function isValidOrientation(string $orientation): bool { return in_array($orientation, [ 'landscape',