diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/l10n/be.js | 44 | ||||
-rw-r--r-- | lib/l10n/be.json | 44 | ||||
-rw-r--r-- | lib/l10n/sw.js | 20 | ||||
-rw-r--r-- | lib/l10n/sw.json | 20 | ||||
-rw-r--r-- | lib/private/AppFramework/App.php | 15 | ||||
-rw-r--r-- | lib/private/DB/QueryBuilder/FunctionBuilder/OCIFunctionBuilder.php | 4 | ||||
-rw-r--r-- | lib/private/DB/QueryBuilder/QueryBuilder.php | 2 | ||||
-rw-r--r-- | lib/private/Files/ObjectStore/ObjectStoreStorage.php | 42 | ||||
-rw-r--r-- | lib/private/Files/ObjectStore/S3ObjectTrait.php | 33 | ||||
-rw-r--r-- | lib/private/Files/Type/Detection.php | 33 | ||||
-rw-r--r-- | lib/private/Security/IdentityProof/Manager.php | 26 | ||||
-rw-r--r-- | lib/private/TaskProcessing/Manager.php | 19 | ||||
-rw-r--r-- | lib/public/TaskProcessing/IManager.php | 1 |
13 files changed, 232 insertions, 71 deletions
diff --git a/lib/l10n/be.js b/lib/l10n/be.js index eb38c0ed05e..4d73f079394 100644 --- a/lib/l10n/be.js +++ b/lib/l10n/be.js @@ -1,11 +1,39 @@ OC.L10N.register( "lib", { + "%1$s and %2$s" : "%1$s і %2$s", + "%1$s, %2$s and %3$s" : "%1$s, %2$s і %3$s", + "%1$s, %2$s, %3$s and %4$s" : "%1$s, %2$s, %3$s і %4$s", + "%1$s, %2$s, %3$s, %4$s and %5$s" : "%1$s, %2$s, %3$s, %4$s і %5$s", "Authentication" : "Аўтэнтыфікацыя", "Unknown filetype" : "Невядомы тып файла", + "Avatar image is not square" : "Відарыс аватара не квадратны", "Files" : "Файлы", + "_%nh_::_%nh_" : ["%n г","%n г","%n г","%n г"], + "_%nm_::_%nm_" : ["%n хв","%n хв","%n хв","%n хв"], + "Local time: %s" : "Мясцовы час: %s", + "today" : "сёння", + "tomorrow" : "заўтра", + "yesterday" : "учора", + "_in %n day_::_in %n days_" : ["праз %n дзень","праз %n дні","праз %n дзён","праз %n дзён"], + "_%n day ago_::_%n days ago_" : ["%n дзень таму","%n дні таму","%n дзён таму","%n дзён таму"], + "next month" : "у наступным месяцы", + "last month" : "у мінулым месяцы", + "_in %n month_::_in %n months_" : ["праз %n месяц","праз %n месяцы","праз %n месяцаў","праз %n месяцаў"], + "_%n month ago_::_%n months ago_" : ["%n месяц таму","%n месяцы таму","%n месяцаў таму","%n месяцаў таму"], + "next year" : "у наступным годзе", + "last year" : "у мінулым годзе", + "_in %n year_::_in %n years_" : ["праз %n год","праз %n гады","праз %n гадоў","праз %n гадоў"], "_%n year ago_::_%n years ago_" : ["%n год таму","%n гады таму","%n гадоў таму","%n гадоў таму"], + "_in %n hour_::_in %n hours_" : ["праз %n гадзіну","праз %n гадзіны","праз %n гадзін","праз %n гадзін"], + "_%n hour ago_::_%n hours ago_" : ["%n гадзіну таму","%n гадзіны таму","%n гадзін таму","%n гадзін таму"], + "_in %n minute_::_in %n minutes_" : ["праз %n хвіліну","праз %n хвіліны","праз %n хвілін","праз %n хвілін"], + "_%n minute ago_::_%n minutes ago_" : ["%n хвіліну таму","%n хвіліны таму","%n хвілін таму","%n хвілін таму"], + "in a few seconds" : "праз некалькі секунд", "seconds ago" : "с таму", + "Empty file" : "Пусты файл", + "Could not convert file" : "Не атрымалася канвертаваць файл", + "%1$s (renamed)" : "%1$s (перайменаваны)", "Templates" : "Шаблоны", "__language_name__" : "Беларуская", "Apps" : "Праграмы", @@ -15,6 +43,7 @@ OC.L10N.register( "Twitter" : "Twitter", "Role" : "Роля", "Pronouns" : "Займеннікі", + "Could not find category \"%s\"" : "Не ўдалося знайсці катэгорыю \"%s\"", "Sunday" : "Нядзеля", "Monday" : "Панядзелак", "Tuesday" : "Аўторак", @@ -41,7 +70,20 @@ OC.L10N.register( "October" : "Кастрычнік", "November" : "Лістапад", "December" : "Снежань", + "Account disabled" : "Уліковы запіс адключаны", + "Application is not enabled" : "Праграма не ўключана", + "Authentication error" : "Памылка аўтэнтыфікацыі", + "Images" : "Відарысы", + "Question" : "Пытанне", + "Number of images" : "Колькасць відарысаў", + "Chat" : "Чат", + "Chat with the assistant" : "Чат з памочнікам", "Text" : "Тэкст", - "Translate" : "Перакласці" + "Translate" : "Перакласці", + "Result" : "Вынік", + "The translated text" : "Перакладзены тэкст", + "Organisation" : "Арганізацыя", + "Cannot download file" : "Немагчыма спампаваць файл", + "Login is too long" : "Лагін занадта доўгі" }, "nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);"); diff --git a/lib/l10n/be.json b/lib/l10n/be.json index d944caed749..9a410c17f7d 100644 --- a/lib/l10n/be.json +++ b/lib/l10n/be.json @@ -1,9 +1,37 @@ { "translations": { + "%1$s and %2$s" : "%1$s і %2$s", + "%1$s, %2$s and %3$s" : "%1$s, %2$s і %3$s", + "%1$s, %2$s, %3$s and %4$s" : "%1$s, %2$s, %3$s і %4$s", + "%1$s, %2$s, %3$s, %4$s and %5$s" : "%1$s, %2$s, %3$s, %4$s і %5$s", "Authentication" : "Аўтэнтыфікацыя", "Unknown filetype" : "Невядомы тып файла", + "Avatar image is not square" : "Відарыс аватара не квадратны", "Files" : "Файлы", + "_%nh_::_%nh_" : ["%n г","%n г","%n г","%n г"], + "_%nm_::_%nm_" : ["%n хв","%n хв","%n хв","%n хв"], + "Local time: %s" : "Мясцовы час: %s", + "today" : "сёння", + "tomorrow" : "заўтра", + "yesterday" : "учора", + "_in %n day_::_in %n days_" : ["праз %n дзень","праз %n дні","праз %n дзён","праз %n дзён"], + "_%n day ago_::_%n days ago_" : ["%n дзень таму","%n дні таму","%n дзён таму","%n дзён таму"], + "next month" : "у наступным месяцы", + "last month" : "у мінулым месяцы", + "_in %n month_::_in %n months_" : ["праз %n месяц","праз %n месяцы","праз %n месяцаў","праз %n месяцаў"], + "_%n month ago_::_%n months ago_" : ["%n месяц таму","%n месяцы таму","%n месяцаў таму","%n месяцаў таму"], + "next year" : "у наступным годзе", + "last year" : "у мінулым годзе", + "_in %n year_::_in %n years_" : ["праз %n год","праз %n гады","праз %n гадоў","праз %n гадоў"], "_%n year ago_::_%n years ago_" : ["%n год таму","%n гады таму","%n гадоў таму","%n гадоў таму"], + "_in %n hour_::_in %n hours_" : ["праз %n гадзіну","праз %n гадзіны","праз %n гадзін","праз %n гадзін"], + "_%n hour ago_::_%n hours ago_" : ["%n гадзіну таму","%n гадзіны таму","%n гадзін таму","%n гадзін таму"], + "_in %n minute_::_in %n minutes_" : ["праз %n хвіліну","праз %n хвіліны","праз %n хвілін","праз %n хвілін"], + "_%n minute ago_::_%n minutes ago_" : ["%n хвіліну таму","%n хвіліны таму","%n хвілін таму","%n хвілін таму"], + "in a few seconds" : "праз некалькі секунд", "seconds ago" : "с таму", + "Empty file" : "Пусты файл", + "Could not convert file" : "Не атрымалася канвертаваць файл", + "%1$s (renamed)" : "%1$s (перайменаваны)", "Templates" : "Шаблоны", "__language_name__" : "Беларуская", "Apps" : "Праграмы", @@ -13,6 +41,7 @@ "Twitter" : "Twitter", "Role" : "Роля", "Pronouns" : "Займеннікі", + "Could not find category \"%s\"" : "Не ўдалося знайсці катэгорыю \"%s\"", "Sunday" : "Нядзеля", "Monday" : "Панядзелак", "Tuesday" : "Аўторак", @@ -39,7 +68,20 @@ "October" : "Кастрычнік", "November" : "Лістапад", "December" : "Снежань", + "Account disabled" : "Уліковы запіс адключаны", + "Application is not enabled" : "Праграма не ўключана", + "Authentication error" : "Памылка аўтэнтыфікацыі", + "Images" : "Відарысы", + "Question" : "Пытанне", + "Number of images" : "Колькасць відарысаў", + "Chat" : "Чат", + "Chat with the assistant" : "Чат з памочнікам", "Text" : "Тэкст", - "Translate" : "Перакласці" + "Translate" : "Перакласці", + "Result" : "Вынік", + "The translated text" : "Перакладзены тэкст", + "Organisation" : "Арганізацыя", + "Cannot download file" : "Немагчыма спампаваць файл", + "Login is too long" : "Лагін занадта доўгі" },"pluralForm" :"nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);" }
\ No newline at end of file diff --git a/lib/l10n/sw.js b/lib/l10n/sw.js index 9e10b43b403..0eca41da17e 100644 --- a/lib/l10n/sw.js +++ b/lib/l10n/sw.js @@ -45,9 +45,27 @@ OC.L10N.register( "Storage is temporarily not available" : "Uhifadhi haupo kwa muda", "Images" : "Picha", "Question" : "Swali", + "Voice chat with the assistant" : "Voice chat with the assistant", + "System prompt" : "System prompt", + "Define rules and assumptions that the assistant should follow during the conversation." : "Define rules and assumptions that the assistant should follow during the conversation.", + "Chat voice message" : "Chat voice message", + "Chat history" : "Chat history", + "Input transcript" : "Input transcript", + "Transcription of the audio input" : "Transcription of the audio input", + "Response voice message" : "Response voice message", + "The generated voice response as part of the conversation" : "The generated voice response as part of the conversation", + "Output transcript" : "Output transcript", + "Transcription of the audio output" : "Transcription of the audio output", + "Transcribe audio" : "Transcribe audio", + "Audio input" : "Audio input", "Confirmation" : "Uthibitisho", + "Prompt" : "Prompt", + "Describe a task that you want the assistant to do or ask a question" : "Describe a task that you want the assistant to do or ask a question", + "The history of chat messages before the current message, starting with a message by the user" : "The history of chat messages before the current message, starting with a message by the user", "Text" : "Maandishi", + "Summarize" : "Summarize", "Summary" : "Muhtasari", - "Translate" : "Tafsiri" + "Translate" : "Tafsiri", + "Result" : "Result" }, "nplurals=2; plural=(n != 1);"); diff --git a/lib/l10n/sw.json b/lib/l10n/sw.json index a645af4e6a8..5759a8f07f4 100644 --- a/lib/l10n/sw.json +++ b/lib/l10n/sw.json @@ -43,9 +43,27 @@ "Storage is temporarily not available" : "Uhifadhi haupo kwa muda", "Images" : "Picha", "Question" : "Swali", + "Voice chat with the assistant" : "Voice chat with the assistant", + "System prompt" : "System prompt", + "Define rules and assumptions that the assistant should follow during the conversation." : "Define rules and assumptions that the assistant should follow during the conversation.", + "Chat voice message" : "Chat voice message", + "Chat history" : "Chat history", + "Input transcript" : "Input transcript", + "Transcription of the audio input" : "Transcription of the audio input", + "Response voice message" : "Response voice message", + "The generated voice response as part of the conversation" : "The generated voice response as part of the conversation", + "Output transcript" : "Output transcript", + "Transcription of the audio output" : "Transcription of the audio output", + "Transcribe audio" : "Transcribe audio", + "Audio input" : "Audio input", "Confirmation" : "Uthibitisho", + "Prompt" : "Prompt", + "Describe a task that you want the assistant to do or ask a question" : "Describe a task that you want the assistant to do or ask a question", + "The history of chat messages before the current message, starting with a message by the user" : "The history of chat messages before the current message, starting with a message by the user", "Text" : "Maandishi", + "Summarize" : "Summarize", "Summary" : "Muhtasari", - "Translate" : "Tafsiri" + "Translate" : "Tafsiri", + "Result" : "Result" },"pluralForm" :"nplurals=2; plural=(n != 1);" }
\ No newline at end of file diff --git a/lib/private/AppFramework/App.php b/lib/private/AppFramework/App.php index e719ea19f90..77135986d5f 100644 --- a/lib/private/AppFramework/App.php +++ b/lib/private/AppFramework/App.php @@ -50,19 +50,8 @@ class App { if (isset($appInfo['namespace'])) { self::$nameSpaceCache[$appId] = trim($appInfo['namespace']); } else { - if ($appId !== 'spreed') { - // if the tag is not found, fall back to uppercasing the first letter - self::$nameSpaceCache[$appId] = ucfirst($appId); - } else { - // For the Talk app (appid spreed) the above fallback doesn't work. - // This leads to a problem when trying to install it freshly, - // because the apps namespace is already registered before the - // app is downloaded from the appstore, because of the hackish - // global route index.php/call/{token} which is registered via - // the core/routes.php so it does not have the app namespace. - // @ref https://github.com/nextcloud/server/pull/19433 - self::$nameSpaceCache[$appId] = 'Talk'; - } + // if the tag is not found, fall back to uppercasing the first letter + self::$nameSpaceCache[$appId] = ucfirst($appId); } return $topNamespace . self::$nameSpaceCache[$appId]; diff --git a/lib/private/DB/QueryBuilder/FunctionBuilder/OCIFunctionBuilder.php b/lib/private/DB/QueryBuilder/FunctionBuilder/OCIFunctionBuilder.php index 8fae6275916..47a8eaa6fd0 100644 --- a/lib/private/DB/QueryBuilder/FunctionBuilder/OCIFunctionBuilder.php +++ b/lib/private/DB/QueryBuilder/FunctionBuilder/OCIFunctionBuilder.php @@ -81,12 +81,12 @@ class OCIFunctionBuilder extends FunctionBuilder { public function octetLength($field, $alias = ''): IQueryFunction { $alias = $alias ? (' AS ' . $this->helper->quoteColumnName($alias)) : ''; $quotedName = $this->helper->quoteColumnName($field); - return new QueryFunction('LENGTHB(' . $quotedName . ')' . $alias); + return new QueryFunction('COALESCE(LENGTHB(' . $quotedName . '), 0)' . $alias); } public function charLength($field, $alias = ''): IQueryFunction { $alias = $alias ? (' AS ' . $this->helper->quoteColumnName($alias)) : ''; $quotedName = $this->helper->quoteColumnName($field); - return new QueryFunction('LENGTH(' . $quotedName . ')' . $alias); + return new QueryFunction('COALESCE(LENGTH(' . $quotedName . '), 0)' . $alias); } } diff --git a/lib/private/DB/QueryBuilder/QueryBuilder.php b/lib/private/DB/QueryBuilder/QueryBuilder.php index 8b224c28dfe..1d1ccd29bf7 100644 --- a/lib/private/DB/QueryBuilder/QueryBuilder.php +++ b/lib/private/DB/QueryBuilder/QueryBuilder.php @@ -161,7 +161,7 @@ class QueryBuilder implements IQueryBuilder { try { $params = []; foreach ($this->getParameters() as $placeholder => $value) { - if ($value instanceof \DateTime) { + if ($value instanceof \DateTimeInterface) { $params[] = $placeholder . ' => DateTime:\'' . $value->format('c') . '\''; } elseif (is_array($value)) { $params[] = $placeholder . ' => (\'' . implode('\', \'', $value) . '\')'; diff --git a/lib/private/Files/ObjectStore/ObjectStoreStorage.php b/lib/private/Files/ObjectStore/ObjectStoreStorage.php index 10ee6aec167..9ab11f8a3df 100644 --- a/lib/private/Files/ObjectStore/ObjectStoreStorage.php +++ b/lib/private/Files/ObjectStore/ObjectStoreStorage.php @@ -475,6 +475,9 @@ class ObjectStoreStorage extends \OC\Files\Storage\Common implements IChunkedFil 'original-storage' => $this->getId(), 'original-path' => $path, ]; + if ($size) { + $metadata['size'] = $size; + } $stat['mimetype'] = $mimetype; $stat['etag'] = $this->getETag($path); @@ -496,32 +499,27 @@ class ObjectStoreStorage extends \OC\Files\Storage\Common implements IChunkedFil $urn = $this->getURN($fileId); try { //upload to object storage - if ($size === null) { - $countStream = CountWrapper::wrap($stream, function ($writtenSize) use ($fileId, &$size) { + + $totalWritten = 0; + $countStream = CountWrapper::wrap($stream, function ($writtenSize) use ($fileId, $size, $exists, &$totalWritten) { + if (is_null($size) && !$exists) { $this->getCache()->update($fileId, [ 'size' => $writtenSize, ]); - $size = $writtenSize; - }); - if ($this->objectStore instanceof IObjectStoreMetaData) { - $this->objectStore->writeObjectWithMetaData($urn, $countStream, $metadata); - } else { - $this->objectStore->writeObject($urn, $countStream, $metadata['mimetype']); } - if (is_resource($countStream)) { - fclose($countStream); - } - $stat['size'] = $size; + $totalWritten = $writtenSize; + }); + + if ($this->objectStore instanceof IObjectStoreMetaData) { + $this->objectStore->writeObjectWithMetaData($urn, $countStream, $metadata); } else { - if ($this->objectStore instanceof IObjectStoreMetaData) { - $this->objectStore->writeObjectWithMetaData($urn, $stream, $metadata); - } else { - $this->objectStore->writeObject($urn, $stream, $metadata['mimetype']); - } - if (is_resource($stream)) { - fclose($stream); - } + $this->objectStore->writeObject($urn, $countStream, $metadata['mimetype']); } + if (is_resource($countStream)) { + fclose($countStream); + } + + $stat['size'] = $totalWritten; } catch (\Exception $ex) { if (!$exists) { /* @@ -545,7 +543,7 @@ class ObjectStoreStorage extends \OC\Files\Storage\Common implements IChunkedFil ] ); } - throw $ex; // make this bubble up + throw new GenericFileException('Error while writing stream to object store', 0, $ex); } if ($exists) { @@ -561,7 +559,7 @@ class ObjectStoreStorage extends \OC\Files\Storage\Common implements IChunkedFil } } - return $size; + return $totalWritten; } public function getObjectStore(): IObjectStore { diff --git a/lib/private/Files/ObjectStore/S3ObjectTrait.php b/lib/private/Files/ObjectStore/S3ObjectTrait.php index 5e6dcf88a42..89405de2e8e 100644 --- a/lib/private/Files/ObjectStore/S3ObjectTrait.php +++ b/lib/private/Files/ObjectStore/S3ObjectTrait.php @@ -6,6 +6,8 @@ */ namespace OC\Files\ObjectStore; +use Aws\Command; +use Aws\Exception\MultipartUploadException; use Aws\S3\Exception\S3MultipartUploadException; use Aws\S3\MultipartCopy; use Aws\S3\MultipartUploader; @@ -96,7 +98,9 @@ trait S3ObjectTrait { protected function writeSingle(string $urn, StreamInterface $stream, array $metaData): void { $mimetype = $metaData['mimetype'] ?? null; unset($metaData['mimetype']); - $this->getConnection()->putObject([ + unset($metaData['size']); + + $args = [ 'Bucket' => $this->bucket, 'Key' => $urn, 'Body' => $stream, @@ -104,7 +108,13 @@ trait S3ObjectTrait { 'ContentType' => $mimetype, 'Metadata' => $this->buildS3Metadata($metaData), 'StorageClass' => $this->storageClass, - ] + $this->getSSECParameters()); + ] + $this->getSSECParameters(); + + if ($size = $stream->getSize()) { + $args['ContentLength'] = $size; + } + + $this->getConnection()->putObject($args); } @@ -119,12 +129,15 @@ trait S3ObjectTrait { protected function writeMultiPart(string $urn, StreamInterface $stream, array $metaData): void { $mimetype = $metaData['mimetype'] ?? null; unset($metaData['mimetype']); + unset($metaData['size']); $attempts = 0; $uploaded = false; $concurrency = $this->concurrency; $exception = null; $state = null; + $size = $stream->getSize(); + $totalWritten = 0; // retry multipart upload once with concurrency at half on failure while (!$uploaded && $attempts <= 1) { @@ -139,6 +152,15 @@ trait S3ObjectTrait { 'Metadata' => $this->buildS3Metadata($metaData), 'StorageClass' => $this->storageClass, ] + $this->getSSECParameters(), + 'before_upload' => function (Command $command) use (&$totalWritten) { + $totalWritten += $command['ContentLength']; + }, + 'before_complete' => function ($_command) use (&$totalWritten, $size, &$uploader, &$attempts) { + if ($size !== null && $totalWritten != $size) { + $e = new \Exception('Incomplete multi part upload, expected ' . $size . ' bytes, wrote ' . $totalWritten); + throw new MultipartUploadException($uploader->getState(), $e); + } + }, ]); try { @@ -155,6 +177,9 @@ trait S3ObjectTrait { if ($stream->isSeekable()) { $stream->rewind(); } + } catch (MultipartUploadException $e) { + $exception = $e; + break; } } @@ -180,7 +205,9 @@ trait S3ObjectTrait { public function writeObjectWithMetaData(string $urn, $stream, array $metaData): void { $canSeek = fseek($stream, 0, SEEK_CUR) === 0; - $psrStream = Utils::streamFor($stream); + $psrStream = Utils::streamFor($stream, [ + 'size' => $metaData['size'] ?? null, + ]); $size = $psrStream->getSize(); diff --git a/lib/private/Files/Type/Detection.php b/lib/private/Files/Type/Detection.php index d5810a90868..6af6ce1a0b1 100644 --- a/lib/private/Files/Type/Detection.php +++ b/lib/private/Files/Type/Detection.php @@ -55,7 +55,8 @@ class Detection implements IMimeTypeDetector { * @param string $mimeType * @param string|null $secureMimeType */ - public function registerType(string $extension, + public function registerType( + string $extension, string $mimeType, ?string $secureMimeType = null): void { // Make sure the extension is a string @@ -217,14 +218,10 @@ class Detection implements IMimeTypeDetector { return 'httpd/unix-directory'; } - if (function_exists('finfo_open') - && function_exists('finfo_file') - && $finfo = finfo_open(FILEINFO_MIME)) { - $info = @finfo_file($finfo, $path); - finfo_close($finfo); - if ($info) { - $info = strtolower($info); - $mimeType = str_contains($info, ';') ? substr($info, 0, strpos($info, ';')) : $info; + if (class_exists(finfo::class)) { + $finfo = new finfo(FILEINFO_MIME_TYPE); + $mimeType = @$finfo->file($path); + if ($mimeType) { $mimeType = $this->getSecureMimeType($mimeType); if ($mimeType !== 'application/octet-stream') { return $mimeType; @@ -240,7 +237,7 @@ class Detection implements IMimeTypeDetector { if (function_exists('mime_content_type')) { // use mime magic extension if available $mimeType = mime_content_type($path); - if ($mimeType !== false) { + if ($mimeType) { $mimeType = $this->getSecureMimeType($mimeType); if ($mimeType !== 'application/octet-stream') { return $mimeType; @@ -258,7 +255,7 @@ class Detection implements IMimeTypeDetector { if ($fp !== false) { $mimeType = fgets($fp); pclose($fp); - if ($mimeType !== false) { + if ($mimeType) { //trim the newline $mimeType = trim($mimeType); $mimeType = $this->getSecureMimeType($mimeType); @@ -293,19 +290,21 @@ class Detection implements IMimeTypeDetector { * @return string */ public function detectString($data): string { - if (function_exists('finfo_open') && function_exists('finfo_file')) { - $finfo = finfo_open(FILEINFO_MIME); - $info = finfo_buffer($finfo, $data); - return str_contains($info, ';') ? substr($info, 0, strpos($info, ';')) : $info; + if (class_exists(finfo::class)) { + $finfo = new finfo(FILEINFO_MIME_TYPE); + $mimeType = $finfo->buffer($data); + if ($mimeType) { + return $mimeType; + } } $tmpFile = \OCP\Server::get(ITempManager::class)->getTemporaryFile(); $fh = fopen($tmpFile, 'wb'); fwrite($fh, $data, 8024); fclose($fh); - $mime = $this->detect($tmpFile); + $mimeType = $this->detect($tmpFile); unset($tmpFile); - return $mime; + return $mimeType; } /** diff --git a/lib/private/Security/IdentityProof/Manager.php b/lib/private/Security/IdentityProof/Manager.php index 935c18bb81d..c16b8314beb 100644 --- a/lib/private/Security/IdentityProof/Manager.php +++ b/lib/private/Security/IdentityProof/Manager.php @@ -11,6 +11,8 @@ namespace OC\Security\IdentityProof; use OC\Files\AppData\Factory; use OCP\Files\IAppData; use OCP\Files\NotFoundException; +use OCP\ICache; +use OCP\ICacheFactory; use OCP\IConfig; use OCP\IUser; use OCP\Security\ICrypto; @@ -19,13 +21,17 @@ use Psr\Log\LoggerInterface; class Manager { private IAppData $appData; + protected ICache $cache; + public function __construct( Factory $appDataFactory, private ICrypto $crypto, private IConfig $config, private LoggerInterface $logger, + private ICacheFactory $cacheFactory, ) { $this->appData = $appDataFactory->get('identityproof'); + $this->cache = $this->cacheFactory->createDistributed('identityproof::'); } /** @@ -96,12 +102,24 @@ class Manager { */ protected function retrieveKey(string $id): Key { try { + $cachedPublicKey = $this->cache->get($id . '-public'); + $cachedPrivateKey = $this->cache->get($id . '-private'); + + if ($cachedPublicKey !== null && $cachedPrivateKey !== null) { + $decryptedPrivateKey = $this->crypto->decrypt($cachedPrivateKey); + + return new Key($cachedPublicKey, $decryptedPrivateKey); + } + $folder = $this->appData->getFolder($id); - $privateKey = $this->crypto->decrypt( - $folder->getFile('private')->getContent() - ); + $privateKey = $folder->getFile('private')->getContent(); $publicKey = $folder->getFile('public')->getContent(); - return new Key($publicKey, $privateKey); + + $this->cache->set($id . '-public', $publicKey); + $this->cache->set($id . '-private', $privateKey); + + $decryptedPrivateKey = $this->crypto->decrypt($privateKey); + return new Key($publicKey, $decryptedPrivateKey); } catch (\Exception $e) { return $this->generateKey($id); } diff --git a/lib/private/TaskProcessing/Manager.php b/lib/private/TaskProcessing/Manager.php index a9c9f1e1ca2..11fb2bed559 100644 --- a/lib/private/TaskProcessing/Manager.php +++ b/lib/private/TaskProcessing/Manager.php @@ -31,9 +31,9 @@ use OCP\Files\Node; use OCP\Files\NotPermittedException; use OCP\Files\SimpleFS\ISimpleFile; use OCP\Http\Client\IClientService; +use OCP\IAppConfig; use OCP\ICache; use OCP\ICacheFactory; -use OCP\IConfig; use OCP\IL10N; use OCP\IServerContainer; use OCP\IUserManager; @@ -73,6 +73,11 @@ class Manager implements IManager { public const LEGACY_PREFIX_TEXTTOIMAGE = 'legacy:TextToImage:'; public const LEGACY_PREFIX_SPEECHTOTEXT = 'legacy:SpeechToText:'; + public const LAZY_CONFIG_KEYS = [ + 'ai.taskprocessing_type_preferences', + 'ai.taskprocessing_provider_preferences', + ]; + /** @var list<IProvider>|null */ private ?array $providers = null; @@ -92,7 +97,7 @@ class Manager implements IManager { private ?GetTaskProcessingProvidersEvent $eventResult = null; public function __construct( - private IConfig $config, + private IAppConfig $appConfig, private Coordinator $coordinator, private IServerContainer $serverContainer, private LoggerInterface $logger, @@ -630,7 +635,7 @@ class Manager implements IManager { */ private function _getTaskTypeSettings(): array { try { - $json = $this->config->getAppValue('core', 'ai.taskprocessing_type_preferences', ''); + $json = $this->appConfig->getValueString('core', 'ai.taskprocessing_type_preferences', '', lazy: true); if ($json === '') { return []; } @@ -788,7 +793,11 @@ class Manager implements IManager { if ($this->preferences === null) { $this->preferences = $this->distributedCache->get('ai.taskprocessing_provider_preferences'); if ($this->preferences === null) { - $this->preferences = json_decode($this->config->getAppValue('core', 'ai.taskprocessing_provider_preferences', 'null'), associative: true, flags: JSON_THROW_ON_ERROR); + $this->preferences = json_decode( + $this->appConfig->getValueString('core', 'ai.taskprocessing_provider_preferences', 'null', lazy: true), + associative: true, + flags: JSON_THROW_ON_ERROR, + ); $this->distributedCache->set('ai.taskprocessing_provider_preferences', $this->preferences, 60 * 3); } } @@ -889,7 +898,7 @@ class Manager implements IManager { $user = $this->userManager->get($userId); } - $guestsAllowed = $this->config->getAppValue('core', 'ai.taskprocessing_guests', 'false'); + $guestsAllowed = $this->appConfig->getValueString('core', 'ai.taskprocessing_guests', 'false'); if ($guestsAllowed == 'true' || !class_exists(\OCA\Guests\UserBackend::class) || !($user->getBackend() instanceof \OCA\Guests\UserBackend)) { return true; } diff --git a/lib/public/TaskProcessing/IManager.php b/lib/public/TaskProcessing/IManager.php index f161030f5f4..723eca8f615 100644 --- a/lib/public/TaskProcessing/IManager.php +++ b/lib/public/TaskProcessing/IManager.php @@ -26,6 +26,7 @@ use OCP\TaskProcessing\Exception\ValidationException; * @since 30.0.0 */ interface IManager { + /** * @since 30.0.0 */ |