Skip to content

Commit

Permalink
Nextcloud 20 compatibility (#28)
Browse files Browse the repository at this point in the history
* NC20 IBootStrap, LoggerInterface,
* Cover RegisterFlowOperationsListener
* Add tests
* Use PSR-3 ContainerInterface
* Include autoload.php inside of Application
* Lint fix
* Exception serialization (see nextcloud/server#21875)
  • Loading branch information
R0Wi authored Oct 10, 2020
1 parent da2542f commit 796222c
Show file tree
Hide file tree
Showing 22 changed files with 473 additions and 140 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
matrix:
php-versions: ['7.4']
databases: ['sqlite']
server-versions: ['stable19']
server-versions: ['stable20']

name: php${{ matrix.php-versions }}-${{ matrix.databases }}-${{ matrix.server-versions }}

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ jobs:
matrix:
php-versions: ['7.4']
databases: ['sqlite']
server-versions: ['stable19']
server-versions: ['stable20']

steps:
- name: Checkout server
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/phpunit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
matrix:
php-versions: ['7.4']
databases: ['sqlite']
server-versions: ['stable19']
server-versions: ['stable20']

name: php${{ matrix.php-versions }}-${{ matrix.databases }}-${{ matrix.server-versions }}

Expand Down Expand Up @@ -79,7 +79,7 @@ jobs:
matrix:
php-versions: ['7.2', '7.3', '7.4']
databases: ['mysql']
server-versions: ['stable19']
server-versions: ['stable20']

name: php${{ matrix.php-versions }}-${{ matrix.databases }}-${{ matrix.server-versions }}

Expand Down Expand Up @@ -147,7 +147,7 @@ jobs:
matrix:
php-versions: ['7.4']
databases: ['pgsql']
server-versions: ['stable19']
server-versions: ['stable20']

name: php${{ matrix.php-versions }}-${{ matrix.databases }}-${{ matrix.server-versions }}

Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ vendor
.php_cs.cache
coverage*.xml
coverage*.html
coverage_html
build
.phpunit.result.cache
*.cov
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ integrationtest: composer
html-coverage: composer
$(CURDIR)/vendor/phpunit/phpunit/phpunit -c phpunit.xml --coverage-php coverage_unittests.cov
$(CURDIR)/vendor/phpunit/phpunit/phpunit -c phpunit.integration.xml --coverage-php coverage_integrationtests.cov
$(CURDIR)/vendor/phpunit/phpcov/phpcov merge --html coverage.html .
$(CURDIR)/vendor/phpunit/phpcov/phpcov merge --html coverage_html .

.PHONY: coverage
coverage: composer
Expand Down
24 changes: 23 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
[![codecov](https://codecov.io/gh/R0Wi/workflow_ocr/branch/master/graph/badge.svg)](https://codecov.io/gh/R0Wi/workflow_ocr)
![Lint](https://github.com/R0Wi/workflow_ocr/workflows/Lint/badge.svg)
[![Generic badge](https://img.shields.io/github/v/release/R0Wi/workflow_ocr)](https://github.com/R0Wi/workflow_ocr/releases)
[![Generic badge](https://img.shields.io/badge/Nextcloud-19-orange)](https://github.com/nextcloud/server)
[![Generic badge](https://img.shields.io/badge/Nextcloud-20-orange)](https://github.com/nextcloud/server)

## Table of contents
* [Setup](#setup)
Expand All @@ -20,6 +20,7 @@
* [Development](#development)
+ [Dev setup](#dev-setup)
+ [Debugging](#debugging)
+ [Executing tests](#executing-tests)
+ [Adding a new `OcrProcessor`](#adding-a-new--ocrprocessor-)
* [Limitations](#limitations)
* [Used libraries & components](#used-libraries---components)
Expand Down Expand Up @@ -181,6 +182,27 @@ If you're looking for some good sources on how to setup `VSCode` + `XDebug` we c
* https://tighten.co/blog/configure-vscode-to-debug-phpunit-tests-with-xdebug/
* https://code.visualstudio.com/docs/languages/php

### Executing tests
To execute the implemented PHPUnit tests you can use one of the following commands:

```bash
# Only run unittests
make unittest

# Only run integrationtests
make integrationtest

# Run all tests
make test

# Run all tests and create HTML coverage report
make html-coverage

# Run all tests and create XML coverage report
make coverage
```
> :warning: Make sure you activated the app before you run any tests (`php occ app:enable workflow_ocr`). Otherwise the initialization will fail.
### Adding a new `OcrProcessor`
To support a new mimetype for being processed with OCR you have to follow a few easy steps:
1. Create a new class in `lib/OcrProcessors` and let the class implement the interface `IOcrProcessor`.
Expand Down
28 changes: 0 additions & 28 deletions appinfo/app.php

This file was deleted.

32 changes: 0 additions & 32 deletions appinfo/autoload.php

This file was deleted.

4 changes: 2 additions & 2 deletions appinfo/info.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<summary>OCR processing via workflow</summary>
<description>This app makes it possible to process various files via OCR algorithms.
The processing is done via workflow-engine and can therefore easily be customized.</description>
<version>1.19.1</version>
<version>1.20.0</version>
<licence>agpl</licence>
<author mail="[email protected]">Robin Windey</author>
<namespace>WorkflowOcr</namespace>
Expand All @@ -22,6 +22,6 @@
<repository type="git">https://github.com/R0Wi/workflow_ocr.git</repository>
<screenshot>https://github.com/R0Wi/workflow_ocr/blob/eb2d65e9610406bbab22c4c8dda1cea015b5c791/doc/img/usage_1.jpg?raw=true</screenshot>
<dependencies>
<nextcloud min-version="19" max-version="19" />
<nextcloud min-version="20" max-version="20" />
</dependencies>
</info>
66 changes: 37 additions & 29 deletions lib/AppInfo/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@

namespace OCA\WorkflowOcr\AppInfo;

use OCA\WorkflowOcr\Listener\RegisterFlowOperationsListener;
use OCA\WorkflowOcr\OcrProcessors\IOcrProcessorFactory;
use OCA\WorkflowOcr\OcrProcessors\OcrProcessorFactory;
use OCA\WorkflowOcr\Operation;
use OCA\WorkflowOcr\Service\IOcrService;
use OCA\WorkflowOcr\Service\OcrService;
use OCA\WorkflowOcr\Wrapper\Filesystem;
Expand All @@ -46,44 +46,52 @@
use OCA\WorkflowOcr\Wrapper\TesseractOcrWrapper;
use OCA\WorkflowOcr\Wrapper\ViewFactory;
use OCA\WorkflowOcr\Wrapper\WrapperFactory;
use OCP\WorkflowEngine\IManager;
use Symfony\Component\EventDispatcher\GenericEvent;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\AppFramework\App;
use OCP\AppFramework\Bootstrap\IBootContext;
use OCP\AppFramework\Bootstrap\IBootstrap;
use OCP\AppFramework\Bootstrap\IRegistrationContext;
use OCP\WorkflowEngine\Events\RegisterOperationsEvent;

class Application extends \OCP\AppFramework\App {
class Application extends App implements IBootstrap {
public const COMPOSER_DIR = __DIR__ . '/../../vendor/';
public const APP_NAME = "workflow_ocr";

/**
* Application constructor.
*/
public function __construct() {
parent::__construct(Application::APP_NAME);

$this->registerWorkflow();
$this->registerDependencies();
public function __construct(array $urlParams = []) {
parent::__construct(Application::APP_NAME, $urlParams);
}

private function registerWorkflow() :void {
/* @var IEventDispatcher $eventDispatcher */
$eventDispatcher = $this->getContainer()->query(IEventDispatcher::class);
$eventDispatcher->addListener(IManager::EVENT_NAME_REG_OPERATION, function (GenericEvent $event) {
$operation = $this->getContainer()->query(Operation::class);
$event->getSubject()->registerOperation($operation);
script(Application::APP_NAME, 'admin');
});
/**
* @inheritdoc
*/
public function register(IRegistrationContext $context): void {
$context->registerServiceAlias(IOcrService::class, OcrService::class);
$context->registerServiceAlias(IOcrProcessorFactory::class, OcrProcessorFactory::class);
$context->registerServiceAlias(IPdfParser::class, PdfParserWrapper::class);
$context->registerServiceAlias(IImagick::class, ImagickWrapper::class);
$context->registerServiceAlias(ITesseractOcr::class, TesseractOcrWrapper::class);
$context->registerServiceAlias(IViewFactory::class, ViewFactory::class);
$context->registerServiceAlias(IFpdi::class, FpdiWrapper::class);
$context->registerServiceAlias(IWrapperFactory::class, WrapperFactory::class);
$context->registerServiceAlias(IFilesystem::class, Filesystem::class);

$context->registerEventListener(RegisterOperationsEvent::class, RegisterFlowOperationsListener::class);
}

private function registerDependencies() : void {
$container = $this->getContainer();
/**
* @inheritdoc
*/
public function boot(IBootContext $context): void {
$this->requireAutoload();
}

$container->registerAlias(IOcrService::class, OcrService::class);
$container->registerAlias(IOcrProcessorFactory::class, OcrProcessorFactory::class);
$container->registerAlias(IPdfParser::class, PdfParserWrapper::class);
$container->registerAlias(IImagick::class, ImagickWrapper::class);
$container->registerAlias(ITesseractOcr::class, TesseractOcrWrapper::class);
$container->registerAlias(IViewFactory::class, ViewFactory::class);
$container->registerAlias(IFpdi::class, FpdiWrapper::class);
$container->registerAlias(IWrapperFactory::class, WrapperFactory::class);
$container->registerAlias(IFilesystem::class, Filesystem::class);
private function requireAutoload() {
if (is_dir(self::COMPOSER_DIR) && file_exists(self::COMPOSER_DIR . 'autoload.php')) {
require_once self::COMPOSER_DIR . 'autoload.php';
} else {
throw new \Exception('Cannot include autoload. Did you run install dependencies using composer?');
}
}
}
8 changes: 4 additions & 4 deletions lib/BackgroundJobs/ProcessFileJob.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
use OC\User\NoUserException;
use OCP\Files\IRootFolder;
use OCP\Files\NotFoundException;
use OCP\ILogger;
use \OCP\Files\File;
use OCA\WorkflowOcr\Exception\OcrNotPossibleException;
use OCA\WorkflowOcr\Exception\OcrProcessorNotFoundException;
Expand All @@ -41,14 +40,15 @@
use OCP\IUserManager;
use OCP\IUser;
use OCP\IUserSession;
use Psr\Log\LoggerInterface;

/**
* Represents a QuedJob which processes
* a OCR on a single file.
*/
class ProcessFileJob extends \OC\BackgroundJob\QueuedJob {

/** @var ILogger */
/** @var LoggerInterface */
protected $logger;
/** @var IRootFolder */
private $rootFolder;
Expand All @@ -64,7 +64,7 @@ class ProcessFileJob extends \OC\BackgroundJob\QueuedJob {
private $userSession;

public function __construct(
ILogger $logger,
LoggerInterface $logger,
IRootFolder $rootFolder,
IOcrService $ocrService,
IViewFactory $viewFactory,
Expand Down Expand Up @@ -95,7 +95,7 @@ protected function run($argument) : void {
$this->initUserEnvironment($uid);
$this->processFile($filePath);
} catch (\Throwable $ex) {
$this->logger->logException($ex);
$this->logger->error($ex->getMessage(), ['exception' => $ex]);
} finally {
$this->shutdownUserEnvironment();
}
Expand Down
50 changes: 50 additions & 0 deletions lib/Listener/RegisterFlowOperationsListener.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

declare(strict_types=1);

/**
* @copyright Copyright (c) 2020 Robin Windey <[email protected]>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

namespace OCA\WorkflowOcr\Listener;

use OCA\WorkflowOcr\AppInfo\Application;
use OCA\WorkflowOcr\Operation;
use OCP\EventDispatcher\Event;
use OCP\EventDispatcher\IEventListener;
use OCP\Util;
use OCP\WorkflowEngine\Events\RegisterOperationsEvent;
use Psr\Container\ContainerInterface;

class RegisterFlowOperationsListener implements IEventListener {

/** @var ContainerInterface */
private $container;

public function __construct(ContainerInterface $container) {
$this->container = $container;
}

public function handle(Event $event): void {
if (!$event instanceof RegisterOperationsEvent) {
return;
}
$event->registerOperation($this->container->get(Operation::class));
Util::addScript(Application::APP_NAME, 'admin');
}
}
Loading

0 comments on commit 796222c

Please sign in to comment.