Skip to content

Commit

Permalink
Merge branch 'master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
slapcat authored Dec 2, 2023
2 parents 1cdf47c + 8191d41 commit 781e47c
Show file tree
Hide file tree
Showing 20 changed files with 329 additions and 14 deletions.
59 changes: 59 additions & 0 deletions admin_manual/configuration_user/user_auth_ldap.rst
Original file line number Diff line number Diff line change
Expand Up @@ -659,6 +659,65 @@ The value can be modified by::

A value of 0 will update it on every of the named occasions.

Administrative Group mapping
^^^^^^^^^^^^^^^^^^^^^^^^^^^^

It is possible to promote **one** LDAP per connection as an admin group, so
that all its members also have administrative privileges in Nextcloud.

A group can either be promoted via a dedicated ``occ`` call providing a group
parameter that can be either a nextcloud group ID or a group name that will be
search against. When a search is executed an exact match is required.

Example usage::

$ php occ ldap:promote-group --help
Description:
declares the specified group as admin group (only one is possible per LDAP configuration)

Usage:
ldap:promote-group [options] [--] <group>

Arguments:
group the group ID in Nextcloud or a group name

Options:
-y, --yes do not ask for confirmation

# Example
$ php occ ldap:promote-group "Nextcloud Admins"
Promote Nextcloud Admins to the admin group (y|N)? y
Group Nextcloud Admins was promoted

$ php occ ldap:promote-group "Paramount Court"
Promote Nextcloud Admins to the admin group and demote Nextcloud Admins (Group ID: nextcloud_admins) (y|N)? y
Group Paramount Court was promoted

$ php occ ldap:promote-group "Paramount Court"
The specified group is already promoted

.. note:: Note the group ID will only be displayed when it differs from the
group's display name.

It is also possible to set the admin group mapping using
``occ ldap:set-config $configId ldapAdminGroup $groupId``, but as the Nextcloud
group ID might not be known (yet) it is recommended (especially for automatized
setups) to use the `promote-group` command, that would also pull in the group
and determine the group ID.

In order to demote or reset a promotion, an empty string should be set against
to the targeted config's ldapAdminGroup::

# Reset an admin group mapping via set-config
occ ldap:set-config $configId ldapAdminGroup ""
# Example
occ ldap:set-config s01 ldapAdminGroup ""

.. tip:: To have more than one administrative groups in a connection, create a
holding group in your LDAP directory that contains the single groups as
nested members, and promote this one.

Nextcloud avatar integration
----------------------------

Expand Down
1 change: 0 additions & 1 deletion admin_manual/release_notes/upgrade_to_28.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ System requirements

* PHP 8.3 is now supported, but 8.2 is recommended.

To be documented

Web server configuration
------------------------
Expand Down
14 changes: 14 additions & 0 deletions developer_manual/app_development/dependency_management.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,20 @@ Composer

You can add 3rd party php packages with `Composer`_. Composer will download the specified packages to a directory of your choice, typically to ``/vendor``. In order to benefit from Composer's autoloader, you'll want to add a ``require_once`` to the ``register`` method of your ``Application`` class in the :ref:`bootstrapping<Bootstrapping>` code of your app.

Remove unneeded files from packages
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

It is heavily recommended to remove files that are not required in production from the final packages.
This especially, but not exclusively, refers to:

* Developer files, e.g. ``/Makefile``
* CI workflows, e.g. ``/.github``
* Test assets, e.g. ``/tests``
* Configuration of development tools, e.g. ``/phpunit.xml``, ``/psalm.xml``
* Git or other version control code, e.g. ``/.git``

You can check the `Server's .gitignore <https://github.com/nextcloud/3rdparty/blob/master/.gitignore>`_ file for more inspiration.

.. _app-composer-dependency-hell:

Dependency hell
Expand Down
26 changes: 23 additions & 3 deletions developer_manual/digging_deeper/groupware/contacts_menu.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Contacts Menu

Nextcloud shows a *Contacts menu* in the right corner of the header. This menu lists a user's contacts. These contact entries can be extended by apps.

Apps that extend the contacts menu implement an IProvider. The providers ``process`` method is called for every entry show in the contacts menu.
Apps that extend the contacts menu implement an IProvider or IBulkProvider. The ``process`` method of IProvider is called for every entry show in the contacts menu. The ``process`` method of IBulkProvider is called for all entries at once. If it's cheaper to fetch data in one operation, use the IBulkProvider.

.. code-block:: php
:caption: lib/ContactsMenu/MyProvider.php
Expand All @@ -22,18 +22,38 @@ Apps that extend the contacts menu implement an IProvider. The providers ``proce
}
}
Alternatively, as a bulk provider:

.. code-block:: php
:caption: lib/ContactsMenu/MyBulkProvider.php
<?php
namespace OCA\MyApp\ContactsMenu;
use OCP\Contacts\ContactsMenu\IEntry;
use OCP\Contacts\ContactsMenu\IProvider;
class MyBulkProvider implements IBulkProvider {
public function process(array $entries): void {
// todo: something useful in bulk
}
}
.. code-block:: xml
:caption: appinfo/info.xml
:emphasize-lines: 6-8
:emphasize-lines: 6-10
<?xml version="1.0"?>
<info xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://apps.nextcloud.com/schema/apps/info.xsd">
<id>my_app</id>
<name>My App</name>
<contactsmenu>
<provider>OCA\MyApp\ContactsMenu\LinkActionProvider</provider>
<provider>OCA\MyApp\ContactsMenu\MyProvider</provider>
<!-- or -->
<provider>OCA\MyApp\ContactsMenu\MyBulkProvider</provider>
</contactsmenu>
</info>
Expand Down
8 changes: 4 additions & 4 deletions developer_manual/digging_deeper/speech-to-text.rst
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,13 @@ The corresponding ``MyReferenceListener`` class can look like:
}
if ($event instanceof TranscriptionSuccessfulEvent) {
$transcript = $event->getTranscript()
$transcript = $event->getTranscript();
// store $transcript somewhere
}
if ($event instanceof TranscriptionSuccessfulEvent) {
$error = $event->getErrorMessage()
$userId = $event->getUserId()
if ($event instanceof TranscriptionFailedEvent) {
$error = $event->getErrorMessage();
$userId = $event->getUserId();
// Notify relevant user about failure
}
}
Expand Down
158 changes: 155 additions & 3 deletions developer_manual/digging_deeper/text_processing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ To consume the Language Model API, you will need to :ref:`inject<dependency-inj
* ``scheduleTask(Task $task)`` This method provides the actual prompt functionality. The task is defined using the Task class. This method runs the task asynchronously in a background job.
* ``getTask(int $id)`` This method fetches a task specified by its id.

.. versionadded:: 28.0.0

* ``runOrScheduleTask(Task $task)`` This method also runs a task, but fist checks the expected runtime of the provider to be used. If the runtime fits inside the available processing time for the current request the task is run synchronously, otherwise it is scheduled as a background job. The task is defined using the Task class.


If you would like to use the text processing functionality in a client, there are also OCS endpoints available for this: :ref:`OCS Text Processing API<ocs-textprocessing-api>`

Expand All @@ -37,9 +41,8 @@ To create a task we use the ``\OCP\TextProcessing\Task`` class. Its constructor

.. code-block:: php
if (in_array(SummaryTaskType::class, $languageModelManager->getAvailableTaskTypes()) {
if (in_array(SummaryTaskType::class, $textprocessingManager->getAvailableTaskTypes()) {
$summaryTask = new Task(SummaryTaskType::class, $emailText, "my_app", $userId, (string) $emailId);
$languageModelManager->scheduleTask($summaryTask);
} else {
// cannot use summarization
}
Expand All @@ -55,6 +58,59 @@ The task class objects have the following methods available:
* ``getIdentifier()`` This returns the original scheduler-defined identifier for the task
* ``getUserId()`` This returns the originating user ID of the task.

You could now run the task directly as follows. However, this will block the current PHP process until the task is done, which can sometimes take dozens of minutes, depending on which provider is used.

.. code-block:: php
try {
$textprocessingManager->runTask($summaryTask);
} catch (\OCP\PreConditionNotMetException|\OCP\TextProcessing\Exception\TaskFailureException $e) {
// task failed
// return error
}
// task was successful
The wiser choice, when you are in the context of a HTTP controller, is to schedule the task for execution in a background job, as follows:

.. code-block:: php
try {
$textprocessingManager->scheduleTask($summaryTask);
} catch (\OCP\PreConditionNotMetException|\OCP\DB\Exception $e) {
// scheduling task failed
}
// task was scheduled successfully
Conditional scheduling of tasks
###############################

.. versionadded:: 28.0.0

Of course, you might want to schedule the task in a background job **only** if it takes longer than the request timeout. This is what ``runOrScheduleTask`` does.

.. code-block:: php
try {
$textprocessingManager->runOrScheduleTask($summaryTask);
} catch (\OCP\PreConditionNotMetException|\OCP\DB\Exception $e) {
// scheduling task failed
// return error
} catch (\OCP\TextProcessing\Exception\TaskFailureException $e) {
// task was run but failed
// status will be STATUS_FAILED
// return error
}
switch ($summaryTask->getStatus()) {
case \OCP\TextProcessing\Task::STATUS_SUCCESSFUL:
// task was run directly and was successful
case \OCP\TextProcessing\Task::STATUS_RUNNING:
case \OCP\TextProcessing\Task::STATUS_SCHEDULED:
// task was deferred to background job
default:
// something went wrong
}
Task statuses
^^^^^^^^^^^^^

Expand Down Expand Up @@ -164,6 +220,102 @@ The method ``process`` implements the text processing step, e.g. it passes the p

The class would typically be saved into a file in ``lib/TextProcessing`` of your app but you are free to put it elsewhere as long as it's loadable by Nextcloud's :ref:`dependency injection container<dependency-injection>`.

Processing tasks in the context of a user
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. versionadded:: 28.0.0

Sometimes the processing of a text processing task may depend upon which user requested the task. You can now obtain this information in your provider by additionally implementing the ``OCP\TextProcessing\IProviderWithUserId`` interface:

.. code-block:: php
:emphasize-lines: 10,14,16,31,32,33
<?php
declare(strict_types=1);
namespace OCA\MyApp\TextProcessing;
use OCA\MyApp\AppInfo\Application;
use OCP\Files\File;
use OCP\TextProcessing\IProvider;
use OCP\TextProcessing\IProviderWithUserId;
use OCP\TextProcessing\SummaryTaskType;
use OCP\IL10N;
class Provider implements IProvider, IProviderWithUserId {
private ?string $userId = null;
public function __construct(
private IL10N $l,
) {
}
public function getName(): string {
return $this->l->t('My awesome text processing provider');
}
public function getTaskType(): string {
return SummaryTaskType::class;
}
public function setUserId(?string $userId): void {
$this->userId = $userId;
}
public function process(string $input): string {
// Return the output here, making use of $this->userId
}
}
Streamlining processing for fast providers
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. versionadded:: 28.0.0

Downstream consumers of the TextProcessing API can optimize execution of tasks if they know how long a task will run with your provider. To allow this kind of optimization you can provide an estimate of how much time your provider typically takes. To do this you simply implement the additional ``OCP\TextProcessing\IProviderWithExpectedRuntime`` interface

.. code-block:: php
:emphasize-lines: 10,14,29,30,31
<?php
declare(strict_types=1);
namespace OCA\MyApp\TextProcessing;
use OCA\MyApp\AppInfo\Application;
use OCP\Files\File;
use OCP\TextProcessing\IProvider;
use OCP\TextProcessing\IProviderWithExpectedRuntime;
use OCP\TextProcessing\SummaryTaskType;
use OCP\IL10N;
class Provider implements IProvider, IProviderWithExpectedRuntime {
public function __construct(
private IL10N $l,
) {
}
public function getName(): string {
return $this->l->t('My awesome text processing provider');
}
public function getTaskType(): string {
return SummaryTaskType::class;
}
public function getExpectedRuntime(): int {
return 10; // expected runtime of a task is 10s
}
public function process(string $input): string {
// Return the output here
}
}
Providing more task types
^^^^^^^^^^^^^^^^^^^^^^^^^

Expand Down Expand Up @@ -227,4 +379,4 @@ The provider class is registered via the :ref:`bootstrap mechanism<Bootstrapping
public function boot(IBootContext $context): void {}
}
}
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,5 @@ sphinxcontrib-qthelp==1.0.6
sphinxcontrib-serializinghtml==1.1.9
sphinx-toolbox==3.5.0
sphinx-reredirects==0.1.3
urllib3==2.0.6
urllib3==2.0.7
zipp==3.16.2
Binary file added user_manual/groupware/images/change-tag-color.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added user_manual/groupware/images/delete-tag.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
23 changes: 23 additions & 0 deletions user_manual/groupware/mail.rst
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,29 @@ Edit tags
2. Click *Edit tags*
3. On the tags modal, set/unset tags

Change color for tags
~~~~~~~~~~~~~~~~~~~~~

.. versionadded:: 3.5

.. figure:: images/change-tag-color.png

Upon creating a tag, a randomly assigned color is automatically chosen. Once the tag is saved, you have the flexibility to customize its color according to your preferences. This feature can be found on the Tag modal action menu.

Delete tags
~~~~~~~~~~~

.. versionadded:: 3.5

.. figure:: images/delete-tag.png

You now have the ability to delete tags that you have previously created. To access this feature:

1. Open the action menu of an envelope/thread.
2. Select Edit tags.
3. Within the tags modal, open the action menu for the specific tag you wish to delete.

.. note:: Please note that default tags such as Work, To do, Personal, and Later cannot be deleted, they can only be renamed.

Message actions
---------------
Expand Down
Loading

0 comments on commit 781e47c

Please sign in to comment.