Skip to content

Commit

Permalink
Merge pull request #199 from ConductionNL/development
Browse files Browse the repository at this point in the history
Development to main
  • Loading branch information
remko48 authored Jan 30, 2025
2 parents 2aa83ea + d0f73f6 commit 80f3292
Show file tree
Hide file tree
Showing 31 changed files with 2,026 additions and 135 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"@context": {
"schema": "http:\/\/schema.org",
"register": "501"
},
"@type": "mapping",
"@id": "http:\/\/nextcloud.local\/index.php\/apps\/openconnector\/api\/mappings\/1",
"name": "Xxllnc Zaak to Publicatie",
"description": "",
"version": "0.0.3",
"reference": "http:\/\/nextcloud.local\/index.php\/apps\/openconnector\/api\/mappings\/1",
"mapping": {
"title": "{{ values['case.subject'] }}",
"summary": "{{ values['attribute.woo_samenvatting'] }}",
"description": "{{ values['attribute.woo_beschrijving'] }}",
"category": "{{ values['attribute.woo_categorie'] }}",
"featured": false,
"status": "Published",
"attachmentCount": 0,
"published": "{{ values['attribute.woo_publicatiedatum'] }}",
"modified": "{{ \"now\"|date(\"Y-m-d\\\\TH:i:s.v\\\\Z\") }}",
"license": "eupl2",
"catalog": "1bcb99cd-7e47-4242-b7a7-ac7d36fe5d5e",
"attachments": "[{% set fileCount = 0 %}{% for file in values['attribute.woo_publicatie'] %}{% if fileCount > 0 %}, {% endif %}\"\/api\/v1\/case\/{{id}}\/document\/{{file.uuid}}\/download\"{% set fileCount = fileCount + 1 %}{% endfor %}{% for file in values['attribute.woo_inventarisatielijst'] %}{% if fileCount > 0 %}, {% endif %}\"\/api\/v1\/case\/{{id}}\/document\/{{file.uuid}}\/download\"{% set fileCount = fileCount + 1 %}{% endfor %}{% for file in values['attribute.woo_informatieverzoek'] %}{% if fileCount > 0 %}, {% endif %}\"\/api\/v1\/case\/{{id}}\/document\/{{file.uuid}}\/download\"{% set fileCount = fileCount + 1 %}{% endfor %}{% for file in values['attribute.woo_besluit'] %}{% if fileCount > 0 %}, {% endif %}\"\/api\/v1\/case\/{{id}}\/document\/{{file.uuid}}\/download\"{% set fileCount = fileCount + 1 %}{% endfor %}]"
},
"unset": [
""
],
"cast": {
"title": "unsetIfValue==",
"summary": "unsetIfValue==",
"description": "unsetIfValue==",
"category": "unsetIfValue==",
"published": "unsetIfValue==",
"modified": "unsetIfValue==",
"attachments": "jsonToArray"
},
"passThrough": false
}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"@context": {
"schema": "http:\/\/schema.org",
"register": "501"
},
"@type": "rule",
"@id": "http:\/\/nextcloud.local\/index.php\/apps\/openconnector\/api\/rules\/4",
"name": "Fetch Xxllnc files",
"description": null,
"reference": "http:\/\/nextcloud.local\/index.php\/apps\/openconnector\/api\/rules\/4",
"version": "0.0.1",
"action": "post",
"timing": "after",
"conditions": {
"==": [
1,
1
]
},
"type": "fetch_file",
"configuration": {
"fetch_file": {
"source": 3,
"filePath": "attachments",
"method": "GET",
"sourceConfiguration": []
}
},
"order": 0
}
3 changes: 0 additions & 3 deletions css/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,6 @@
--OC-color-status-emergency: #ffffff;
}




/* Pages */
.pageHeader {
margin-block-start: var(--app-navigation-padding);
Expand Down
40 changes: 40 additions & 0 deletions docs/rules/rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,46 @@ Upload rules manage file upload functionality and restrictions. Configuration in
- allowedTypes: Comma-separated list of allowed file extensions (e.g., jpg,png,pdf)
- maxSize: Maximum allowed file size in megabytes

#### Partial upload rules

Partial upload rules manage file uploads in multiple parts, allowing for uploads of larger files.
Partial uploads require the created object to contain the file size of the file to be created.

The functionality is split into two rule types:

- `fileparts_create`
- `filepart_upload`

The `fileparts_create` type creates the partial file upload from the endpoint. These partial files will be nested into
the response object, and will be stored with their ids in the saved object. The fileparts will be stored in objects according to a separate schema.

The default schema of these fileparts is:

```json
{
"id": "baed4312-c6b8-48bc-a1b3-c3536d9653be", // The id of the file part object.
"order": 1, // The order number of the file part, starting at 1
"size": 297809, // The size in bytes of the file part that is/will be uploaded
"data": "..." // The data uploaded. This will only exist after uploading, until the data is written into a partial file.
}
```

The `fileparts_create` rule takes the following configuration:

- `sizeLocation` (required): The location in the created object containing the size of the complete file.
- `schemaId` (required): The schema to store the file part in.
- `filenameLocation` (optional): The location in the created object that contains the filename of the file to be created. This defaults to `filename` if it is not set.
- `filePartLocation` (optional): The location in the created object the created fileparts will be written to. Defaults to `fileParts`
- `mappingId` (optional): If the resulting filePart objects have to be mapped to a specific format, the id of the mapping that will map the file parts to the desired format.

The `filepart_upload` type will upload the data in the file part that is uploaded into a temporary file, and
once all fileparts have been uploaded, it will reconcile the partial uploads into one file (deleting the temporary files,
and if no additional data has been put into the folder where the parts are stored, the folder).

The `filepart_upload` rule takes the following configuration:

- `mappingId` (optional): If the file parts are in a specific format, the mapping to map the fileparts to the default format. (Usually this means that this is the inverse mapping of `mappingId` in the corresponding `fileparts_create` rule).

### Locking Rules

Locking rules provide exclusive access control for resources. Configuration includes:
Expand Down
39 changes: 39 additions & 0 deletions docs/synchronization.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Synchronization Actions

## Concept

Just as with Endpoints, synchronizations can trigger additional actions (at this moment called rules).
These can change the content of an object, but also trigger additional synchronizations.

These actions can be created by creating a rule (an action) and adding it by id to the property
actions in the Synchronization.

## Synchronizing files
In order to fetch a file from an external source and store it in the Nextcloud Filesystem in a way that OpenRegister can
connect it to an object, there are two predefined actions:

- `fetch_file`: This action downloads the file and substitutes the base encoded content into the variable that contained the file url
- `write_file`: This action takes a file's content in base encoding and the filename (otherwise it will use a default filename), and writes it to the filesystem.

### Fetch file

This action should be run on timing `after` (when the object has been stored).
The action takes the following parameters in the `configuration` property:

- `source` (required): The id of the source where the file can be downloaded
- `filePath` (required): The dot path of the location in the input object that contains the file url or file path.
- `method` (optional): The HTTP method that should be used to fetch the file. Defaults to GET
- `sourceConfiguration` (optional): Additional configuration for the source that only holds for fetching files.

When properly configured this action will download the file from the given source and substitute the base64 encoded content in the returned object.
It is preferred to run this action in combination with `write_file` immediately after, so the file contents are properly stored in the Nextcloud file system instead of written to a database.

### Write file

This action should be run on timing `after`, and if combined with `fetch_file` it should be run in order after `fetch_file`.
The action takes the followin parameters in the `configuration` property:

- `filePath` (required): The dot path of the location in the input object that contains the base64 encoded content of the file.
- `fileNamePath` (required): The dot path of the location in the input object that contains the filename

This will write the file to the nextcloud filesystem in the folder that belongs to the written object, and substitutes the file content in the returned data with the path of the object in the Nextcloud File System.
2 changes: 1 addition & 1 deletion lib/Db/EndpointMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public function findAll(?int $limit = null, ?int $offset = null, ?array $filters

private function createEndpointRegex(string $endpoint) {
$regex = '#'.preg_replace(pattern: ['#\/{{([^}}]+)}}\/#', '#\/{{([^}}]+)}}$#'], replacement: ['/([^/]+)/', '(/([^/]+))?'], subject: $endpoint).'#';
if(str_ends_with(haystack: $regex, needle: '?#') === false && str_ends_with(haystack: $regex, needle: '$#') === false) {
if (str_ends_with(haystack: $regex, needle: '?#') === false && str_ends_with(haystack: $regex, needle: '$#') === false) {
$regex = substr($regex, 0, -1). '$#';
}

Expand Down
11 changes: 5 additions & 6 deletions lib/Db/Mapping.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,6 @@ public function __construct() {
$this->addType('dateModified', 'datetime');
}

// todo: This is a hotfix for a bug in the datamodel. Update the data model and remove this.
public function getUpdated(): DateTime
{
return $this->dateModified ?? $this->dateCreated;
}

public function getJsonFields(): array
{
return array_keys(
Expand All @@ -49,6 +43,11 @@ public function getJsonFields(): array
);
}

public function getUpdated(): ?DateTime
{
return $this->dateModified;
}

public function hydrate(array $object): self
{
$jsonFields = $this->getJsonFields();
Expand Down
3 changes: 3 additions & 0 deletions lib/Db/Synchronization.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class Synchronization extends Entity implements JsonSerializable

protected array $conditions = [];
protected array $followUps = [];
protected array $actions = [];


public function __construct() {
Expand Down Expand Up @@ -69,6 +70,7 @@ public function __construct() {
$this->addType('updated', 'datetime');
$this->addType(fieldName:'conditions', type: 'json');
$this->addType(fieldName:'followUps', type: 'json');
$this->addType(fieldName: 'actions', type: 'json');
}

/**
Expand Down Expand Up @@ -147,6 +149,7 @@ public function jsonSerialize(): array
'updated' => isset($this->updated) === true ? $this->updated->format('c') : null,
'conditions' => $this->conditions,
'followUps' => $this->followUps,
'actions' => $this->actions,
];
}
}
60 changes: 60 additions & 0 deletions lib/Migration/Version1Date20250123100521.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php

declare(strict_types=1);

/**
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

namespace OCA\OpenConnector\Migration;

use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;

/**
* FIXME Auto-generated migration step: Please modify to your needs!
*/
class Version1Date20250123100521 extends SimpleMigrationStep {

/**
* @param IOutput $output
* @param Closure(): ISchemaWrapper $schemaClosure
* @param array $options
*/
public function preSchemaChange(IOutput $output, Closure $schemaClosure, array $options): void {
}

/**
* @param IOutput $output
* @param Closure(): ISchemaWrapper $schemaClosure
* @param array $options
* @return null|ISchemaWrapper
*/
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/**
* @var ISchemaWrapper $schema
*/
$schema = $schemaClosure();

if ($schema->hasTable(tableName: 'openconnector_synchronizations') === true) {
$table = $schema->getTable(tableName: 'openconnector_synchronizations');
if ($table->hasColumn('actions') === false){
$table->addColumn(name: 'actions', typeName: Types::JSON)->setNotnull(false)->setDefault('[]');
}
}

return $schema;
}

/**
* @param IOutput $output
* @param Closure(): ISchemaWrapper $schemaClosure
* @param array $options
*/
public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options): void {
}
}
Loading

0 comments on commit 80f3292

Please sign in to comment.