Merge branch 'master' into enh/text-processing-provider-with-id

pull/41088/head
Marcel Klehr 5 months ago committed by GitHub
commit 53be798a70
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -36,11 +36,14 @@ use OCA\DAV\CalDAV\CalendarHome;
use OCP\IConfig;
use Psr\Log\LoggerInterface;
use Sabre\CalDAV\ICalendar;
use Sabre\CalDAV\ICalendarObject;
use Sabre\CalDAV\Schedule\ISchedulingObject;
use Sabre\DAV\INode;
use Sabre\DAV\IProperties;
use Sabre\DAV\PropFind;
use Sabre\DAV\Server;
use Sabre\DAV\Xml\Property\LocalHref;
use Sabre\DAVACL\IACL;
use Sabre\DAVACL\IPrincipal;
use Sabre\HTTP\RequestInterface;
use Sabre\HTTP\ResponseInterface;
@ -50,6 +53,7 @@ use Sabre\VObject\Component\VEvent;
use Sabre\VObject\DateTimeParser;
use Sabre\VObject\FreeBusyGenerator;
use Sabre\VObject\ITip;
use Sabre\VObject\ITip\SameOrganizerForAllComponentsException;
use Sabre\VObject\Parameter;
use Sabre\VObject\Property;
use Sabre\VObject\Reader;
@ -161,7 +165,29 @@ class Plugin extends \Sabre\CalDAV\Schedule\Plugin {
$this->pathOfCalendarObjectChange = $request->getPath();
}
parent::calendarObjectChange($request, $response, $vCal, $calendarPath, $modified, $isNew);
try {
parent::calendarObjectChange($request, $response, $vCal, $calendarPath, $modified, $isNew);
} catch (SameOrganizerForAllComponentsException $e) {
$this->handleSameOrganizerException($e, $vCal, $calendarPath);
}
}
/**
* @inheritDoc
*/
public function beforeUnbind($path): void {
try {
parent::beforeUnbind($path);
} catch (SameOrganizerForAllComponentsException $e) {
$node = $this->server->tree->getNodeForPath($path);
if (!$node instanceof ICalendarObject || $node instanceof ISchedulingObject) {
throw $e;
}
/** @var VCalendar $vCal */
$vCal = Reader::read($node->get());
$this->handleSameOrganizerException($e, $vCal, $path);
}
}
/**
@ -630,4 +656,44 @@ EOF;
'{DAV:}displayname' => $displayName,
]);
}
/**
* Try to handle the given exception gracefully or throw it if necessary.
*
* @throws SameOrganizerForAllComponentsException If the exception should not be ignored
*/
private function handleSameOrganizerException(
SameOrganizerForAllComponentsException $e,
VCalendar $vCal,
string $calendarPath,
): void {
// This is very hacky! However, we want to allow saving events with multiple
// organizers. Those events are not RFC compliant, but sometimes imported from major
// external calendar services (e.g. Google). If the current user is not an organizer of
// the event we ignore the exception as no scheduling messages will be sent anyway.
// It would be cleaner to patch Sabre to validate organizers *after* checking if
// scheduling messages are necessary. Currently, organizers are validated first and
// afterwards the broker checks if messages should be scheduled. So the code will throw
// even if the organizers are not relevant. This is to ensure compliance with RFCs but
// a bit too strict for real world usage.
if (!isset($vCal->VEVENT)) {
throw $e;
}
$calendarNode = $this->server->tree->getNodeForPath($calendarPath);
if (!($calendarNode instanceof IACL)) {
// Should always be an instance of IACL but just to be sure
throw $e;
}
$addresses = $this->getAddressesForPrincipal($calendarNode->getOwner());
foreach ($vCal->VEVENT as $vevent) {
if (in_array($vevent->ORGANIZER->getNormalizedValue(), $addresses, true)) {
// User is an organizer => throw the exception
throw $e;
}
}
}
}

@ -388,9 +388,9 @@ class FilesPlugin extends ServerPlugin {
}
$propFind->handle(self::HIDDEN_PROPERTYNAME, function () use ($node) {
$filesMetadataManager = \OCP\Server::get(IFilesMetadataManager::class);
$metadata = $filesMetadataManager->getMetadata((int)$node->getFileId(), true);
return $metadata->hasKey('files-live-photo') && $node->getFileInfo()->getMimetype() === 'video/quicktime' ? 'true' : 'false';
$isLivePhoto = isset($node->getFileInfo()->getMetadata()['files-live-photo']);
$isMovFile = $node->getFileInfo()->getMimetype() === 'video/quicktime';
return ($isLivePhoto && $isMovFile) ? 'true' : 'false';
});
/**

@ -31,6 +31,7 @@ use OCP\IConfig;
use OCP\IL10N;
use OCP\Settings\IDelegatedSettings;
use OCP\SpeechToText\ISpeechToTextManager;
use OCP\SpeechToText\ISpeechToTextProviderWithId;
use OCP\TextProcessing\IManager;
use OCP\TextProcessing\IProvider;
use OCP\TextProcessing\IProviderWithId;
@ -70,7 +71,7 @@ class ArtificialIntelligence implements IDelegatedSettings {
$sttProviders = [];
foreach ($this->sttManager->getProviders() as $provider) {
$sttProviders[] = [
'class' => $provider::class,
'class' => $provider instanceof ISpeechToTextProviderWithId ? $provider->getId() : $provider::class,
'name' => $provider->getName(),
];
}

@ -658,6 +658,7 @@ return array(
'OCP\\SpeechToText\\Events\\TranscriptionSuccessfulEvent' => $baseDir . '/lib/public/SpeechToText/Events/TranscriptionSuccessfulEvent.php',
'OCP\\SpeechToText\\ISpeechToTextManager' => $baseDir . '/lib/public/SpeechToText/ISpeechToTextManager.php',
'OCP\\SpeechToText\\ISpeechToTextProvider' => $baseDir . '/lib/public/SpeechToText/ISpeechToTextProvider.php',
'OCP\\SpeechToText\\ISpeechToTextProviderWithId' => $baseDir . '/lib/public/SpeechToText/ISpeechToTextProviderWithId.php',
'OCP\\Support\\CrashReport\\ICollectBreadcrumbs' => $baseDir . '/lib/public/Support/CrashReport/ICollectBreadcrumbs.php',
'OCP\\Support\\CrashReport\\IMessageReporter' => $baseDir . '/lib/public/Support/CrashReport/IMessageReporter.php',
'OCP\\Support\\CrashReport\\IRegistry' => $baseDir . '/lib/public/Support/CrashReport/IRegistry.php',

@ -691,6 +691,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OCP\\SpeechToText\\Events\\TranscriptionSuccessfulEvent' => __DIR__ . '/../../..' . '/lib/public/SpeechToText/Events/TranscriptionSuccessfulEvent.php',
'OCP\\SpeechToText\\ISpeechToTextManager' => __DIR__ . '/../../..' . '/lib/public/SpeechToText/ISpeechToTextManager.php',
'OCP\\SpeechToText\\ISpeechToTextProvider' => __DIR__ . '/../../..' . '/lib/public/SpeechToText/ISpeechToTextProvider.php',
'OCP\\SpeechToText\\ISpeechToTextProviderWithId' => __DIR__ . '/../../..' . '/lib/public/SpeechToText/ISpeechToTextProviderWithId.php',
'OCP\\Support\\CrashReport\\ICollectBreadcrumbs' => __DIR__ . '/../../..' . '/lib/public/Support/CrashReport/ICollectBreadcrumbs.php',
'OCP\\Support\\CrashReport\\IMessageReporter' => __DIR__ . '/../../..' . '/lib/public/Support/CrashReport/IMessageReporter.php',
'OCP\\Support\\CrashReport\\IRegistry' => __DIR__ . '/../../..' . '/lib/public/Support/CrashReport/IRegistry.php',

@ -39,6 +39,7 @@ use OCP\IServerContainer;
use OCP\PreConditionNotMetException;
use OCP\SpeechToText\ISpeechToTextManager;
use OCP\SpeechToText\ISpeechToTextProvider;
use OCP\SpeechToText\ISpeechToTextProviderWithId;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Log\LoggerInterface;
@ -117,8 +118,13 @@ class SpeechToTextManager implements ISpeechToTextManager {
$json = $this->config->getAppValue('core', 'ai.stt_provider', '');
if ($json !== '') {
$className = json_decode($json, true);
$provider = current(array_filter($providers, fn ($provider) => $provider::class === $className));
$classNameOrId = json_decode($json, true);
$provider = current(array_filter($providers, function ($provider) use ($classNameOrId) {
if ($provider instanceof ISpeechToTextProviderWithId) {
return $provider->getId() === $classNameOrId;
}
return $provider::class === $classNameOrId;
}));
if ($provider !== false) {
$providers = [$provider];
}

@ -0,0 +1,14 @@
<?php
namespace OCP\SpeechToText;
/**
* @since 28.0.0
*/
interface ISpeechToTextProviderWithId extends ISpeechToTextProvider {
/**
* @since 28.0.0
*/
public function getId(): string;
}
Loading…
Cancel
Save