migrate therinaldos.com data
Build & Deploy to DigitalOcean Space / build (push) Failing after 2m38s

This commit is contained in:
2024-05-05 15:50:45 -04:00
commit ef1ff240d4
23182 changed files with 3801898 additions and 0 deletions
@@ -0,0 +1,42 @@
<?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>files_reminders</id>
<name>File reminders</name>
<summary>Set file reminders</summary>
<description><![CDATA[**📣 File reminders**
Set file reminders.
]]></description>
<version>1.1.0</version>
<licence>agpl</licence>
<author>Christopher Ng</author>
<namespace>FilesReminders</namespace>
<types>
<dav />
</types>
<category>files</category>
<bugs>https://github.com/nextcloud/server/issues</bugs>
<dependencies>
<nextcloud min-version="28" max-version="28" />
</dependencies>
<background-jobs>
<job>OCA\FilesReminders\BackgroundJob\CleanUpReminders</job>
<job>OCA\FilesReminders\BackgroundJob\ScheduledNotifications</job>
</background-jobs>
<commands>
<command>OCA\FilesReminders\Command\ListCommand</command>
</commands>
<sabre>
<plugins>
<plugin>OCA\FilesReminders\Dav\PropFindPlugin</plugin>
</plugins>
</sabre>
</info>
@@ -0,0 +1,37 @@
<?php
declare(strict_types=1);
/**
* @copyright 2023 Christopher Ng <chrng8@gmail.com>
*
* @author Christopher Ng <chrng8@gmail.com>
*
* @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/>.
*
*/
$requirements = [
'version' => '1',
];
return [
'ocs' => [
['name' => 'Api#get', 'url' => '/api/v{version}/{fileId}', 'verb' => 'GET', 'requirements' => $requirements],
['name' => 'Api#set', 'url' => '/api/v{version}/{fileId}', 'verb' => 'PUT', 'requirements' => $requirements],
['name' => 'Api#remove', 'url' => '/api/v{version}/{fileId}', 'verb' => 'DELETE', 'requirements' => $requirements],
],
];
@@ -0,0 +1,84 @@
{
"hashes": {
"appinfo\/info.xml": "7d96210d8250e1151a0cd26fea11c03dedf8213e7516806e398a599cf1411a77791c110a90f2b7f281241523882e6b19887762e6691b691a740f7f486c627557",
"appinfo\/routes.php": "3b5ac24a126c95a8afa5c46d5ce9048e1e92ed6b9d6d60d7c89869a471de6f937c7efbbffa7467c3ac30cf2b8eafc3db28e9809f2a1f8a5d35c588091f7752a8",
"composer\/autoload.php": "1456985137382ef7e86c3cc9beae06523606ad9c03855c5ba541f63ec5602713399504355dd337861c755c1ecab6aaa2b8f0c5706fa8dc914aff08ed30de47c4",
"composer\/composer.json": "c2d89543261c872dfc82dca29ca4d8d458c1b0783481bb79b5598c92387efef4186c426a604fd35e4a0f45638aace7da35dc94d9ac7c402df00ddc50b153957c",
"composer\/composer.lock": "ff05b13233ad4e3365c2bdfd64abe5c05883d227b20303d35b50ae0f6415fb36a3f2c7d047b130bcafaeedb4a9231cdbafb81bdfc1a2f51746e008a7a68ad0b1",
"composer\/composer\/ClassLoader.php": "f73af132ef1159370f4da75d1477541c8fd55e82d64e1a29b199e8963597b3558853edd48f703118bb139680e80bbae5cd601580c9f62355f3e749214b40e162",
"composer\/composer\/InstalledVersions.php": "733e68c171cb9e44868bb0f105850fbd0e4f225c67235bf30fb2ac5c3443c6edfb722d4b33aa91c82bb600e937cb6392eb1883694d41616e66969d7d42e23b4f",
"composer\/composer\/LICENSE": "f3bb64009f41a425df5a9bbab53490f0eb9b74fa8d6aaa2f57efb928edc4ffff330260666edeaa04a91fed708c3663371cf01b284f3a08d6698aaef7a23f355a",
"composer\/composer\/autoload_classmap.php": "91d12bb559b1345c84a15b51b43cdd278988cfa37dcce2c7691f35c5ed16b56a81587d2c9817450d7eaee27d4cb04e3e018bf063d8dcceba1d741e13dd25dbaf",
"composer\/composer\/autoload_namespaces.php": "5b2571f3b573a778d362b8c7412787b4084c7f27d3f5bba1585243f3ccbb0b9054e68522a22a1ad59ec11097b03a0e343865c0188c65b25f0a97e24e120339d1",
"composer\/composer\/autoload_psr4.php": "51fa466422560704aae58c023e897733d321e14a5c98c8735e9cfa6ca10b74a33d30206cf4729678868b5b3c2cfbc1a5b050d77cc266ef174dd6b9ccb474b4c7",
"composer\/composer\/autoload_real.php": "0b073423b6e5c633e8898121c9366940f58ec4f5663695616d87e764beeadc1cfce62f4adcc46c5aa7c23e58d396d4f17bb5c33937a486e7860b27523621152c",
"composer\/composer\/autoload_static.php": "10e21b61bfd8a7fffa084e0fcb5d0553735c9c33db9a709f79c49251982f38b3aa9f03f061efb302c196acec33e7d51772e84e0b2a70f908105c93413b27198b",
"composer\/composer\/installed.json": "0a3ed51f953eb945b970a8eb21957ca2beee4669c7d0d9be97b8259c391b60688f8abb78d4b1fae5e4e2ea5e3d8747f4d35f066a2605e9a76f5b45ec3f1da357",
"composer\/composer\/installed.php": "8701a728a2e5608dae8c47ba4b92b3f473d3f23fb6665823890235b32c36a320d646fc7bbbc27bc42f05248d245ccafe694ea49ff58bbdb7f4452ded7c643d22",
"img\/alarm.svg": "e2f8b9952cc7e23583c1cbcd7bf3438de3080f41635bd9c010de2e8c989b017a5b98b11f65e592506c6b99f206f6c175b2cc690ca2ab680c2f7c1929d0e06eef",
"l10n\/ar.js": "d90f4a918583acce9c1bd8ba5bfcfba01a3aa0f69277510dbf4f7b99c4144bb837ef8b47e94e2282a67dfbce5d43c827177aa437ad4743d4acf29d4884110e2b",
"l10n\/ar.json": "ea4a53241410d293c361720def40c72b220e753a7c33486b824d82d53afe480a2abce5a50e5f09d9394e007607b034b95a0764388dc2882d016bb69a078907d2",
"l10n\/cs.js": "21aa5bcbd793ba9a3fd43e7198113daa90bc404136f5d7e5ecf640375910d8ce4447156b4d647eb1d6e48cd0b33f6013908987f1e01720c1b3dd00c2c0ba984e",
"l10n\/cs.json": "3bef9d27482d9b0bd92f9b222568ab89a98ac696057148489452c5675ae01b9afd4644136730e9dadd7520da372ebc21a3b89f26a1594754a1c48942421cd513",
"l10n\/de_DE.js": "2d5e7810aa9495be41c537befc757dd8bba74dd450016cbfab5275f208c35e7b909563ee23624936693787f4038097a51543fd7184f552b0c9531c8fa98ddc97",
"l10n\/de_DE.json": "10468890a2c626e41a179179457debe189b870ce04d5e964b6297705aa3e6cd50909986154f062eb212c89f3dbf8da27f54bd019cad37f0390c2b4ba43358e03",
"l10n\/el.js": "14d32bfa8dcacb10ba6b3ca4a5d34803ec565557e4e48e3866c4c9b5d35aa1b5e13f9025a03f9b3b81c44b8ee255ed6a9583fb13c78785ea23dc1d91e86fd308",
"l10n\/el.json": "b88adea26c436b9597c1ff5f9c93c41d741dec88d2603bf6594502843247e6936b798d01ff267276fcd09db58b7fe194a8f2ea46f9668ef7fdf26ee11af89ab2",
"l10n\/en_GB.js": "e78f9acfe82ae50cd004ff66dd35873179b5a05d7387c4e34a1f8e91e31eb6e71616b47e7843fa0845332e055cd05231222dcf16cc7245dcc494f547b5a91614",
"l10n\/en_GB.json": "ed0eb165e584b067435d92dc1e9e41404b78edcae11a47f822f17e9e275982bcd4eecf60b235070a7c9e83ee152e4ce5a995bbd917630c68c1229065fa6de2a2",
"l10n\/es.js": "552a248d18f743651fd0477cdae6665fae3522b0d11eff98e004728326f34556acf6c767f86560fcceca91c587520ac6e6780e221c841601176b3c632572bc90",
"l10n\/es.json": "748715b311ded21cbe81da893b418e71f419b5bc4b439bcb4d4177092032e21c15a4362ac98f6c795e24b28792d551c6d15a17f310423fef40f7f6d84b07b638",
"l10n\/fi.js": "4cc6555baacd4f8328cd75f3f26230a607f9946b5796e6f0274dc3f1bde48068faac1a793129d9a68eca61d56d53f26662f987ff25019dfd30c39b0c4f70246e",
"l10n\/fi.json": "ab9cbc2d55a345d92baa4c4840c6b4ba7823935f428829d59dad3e7bc8f9796513bfe47563178b65ca4eb60b5b5cabcd1e5e5eb199f4fb4a8b44815d0c4aa68e",
"l10n\/fr.js": "300e2dd5e1337b666d8e8abd2fff0ae24bdadf8db47e55a18fe619e48cf719d146c63e8fc566a5ceab33e062b018cd8aa374b08199fde44e5e2c822318c36da8",
"l10n\/fr.json": "9dd6f6b9185273820979f8e3f46ea301c8ac33bba225ce855bb16fe4b1e9030d66a7134ed248274a9f1a2afdd7157b6ac3c2d5b83f1005e928609325e7b5b220",
"l10n\/gl.js": "cac19f473c734a911c0a9fcbf7a68c917e34da049577b394759d7b9538b3104b873f7ad57a4ae349fdce551e19e79b45290aaf0a0138bc35e48d62a92a7352cf",
"l10n\/gl.json": "0fda6d29917f89b18dd6f54eac2f639a8990275151323bdb53a65bf89e69d1b8c5eb10d8039090e3e95128aa2eff4f4aa3630e934711ebd862d0fb866261bf56",
"l10n\/hu.js": "6580f000753b736d863f9e4757e8f37f89b6e01b5418e07e3d70807e7885119cc3b0ff2af95e44f6ca17c8819a58bf15620819bfde87578045beaf3e740b7648",
"l10n\/hu.json": "e41c7a12046710e21be13355e66350f91057c19ab65e0fd792d4942c7f6bb812d28ba0943c2776e6a19bf31332f694a93fb824a0bf7f90e01490fde17241c635",
"l10n\/lt_LT.js": "db2877b64f8bd64eec8fc16ad688506319406f4af84029b5d5d389d4922ba7d96c4fc58bbc496f4e8b8bcbfe77912784ba34b7826adf02dc2594a0ea12898281",
"l10n\/lt_LT.json": "26f3231cc11d1986aa6afbebc2fe0e97e7e70f42a516caeda61cd6e1fb2ed6e6744bfde60fb7971af04b1822faac3b706daaaa23c8bc0b917e028587e6a6ee92",
"l10n\/mk.js": "79c701af6e2e68312260542e9cf5f60db6a54345ae2d7cd0331704a029f449f98a96571654ee46c18da7785e60b0452c0de4d54d72c07b372cdbcd5b0a13dcb8",
"l10n\/mk.json": "78d624c0d0a0e09505f5838288d5eb693904bb06867cbc9a0063b9c7a9176054916a08210a29a908d5eaf4eb8598f087ac1c25ce0d0cd0809a0e3e73b0680f7b",
"l10n\/nb.js": "dbc67bc80ef3474c98e90f45928f9d30080987326175ba40af220b1837207f1b7cc5f7a6ddaa11ab70de65073f11db50e9bd5b8f9cbd4f6ad302dcb70a1092c4",
"l10n\/nb.json": "40a41cf63acead353337a6cd49f8dd694f42864496f991c04cefafc2330650e988c4be4b7ab15ba62946cf14ebbdb6116ddc2151211be32b792f392562e4225d",
"l10n\/pl.js": "2b798ae6ccf250e6b2033205a57dca7a816b84d81e2ee6597bb4e2fc993056fcf0c770cf358e16a0292734ad958d4f88ea4589f4bfd85e419dbb93b1629f4cce",
"l10n\/pl.json": "bd181022a75c714f080dc8eff96fe2f35279cae6b2a0930861edac4a5efd408baddf3fb21363baa73f93f61838ce6b5f22e65816aceb80ee04b5c4e1bc6cc43a",
"l10n\/pt_BR.js": "2360db8048e2abef36697acf0bba98d70c8186ef3dec93338ddda32cae37f47e3a1980aa9817ecf4fa724a0f9d27c480d86beda5be8627fe7190c7b1f1fd9ac3",
"l10n\/pt_BR.json": "92b1ec049858f85a3187fa4ce413878c7c5ae00b8363589ab4a6c1be88491925beaf4a865da9246a04b5ddcc5ffc50f90f1c43e7186d3c44cff34c3366a6cda2",
"l10n\/ru.js": "3e77ce8a0e98167b122047d2062661fe095aca1abe36010eae43cff6975b84f7ba3cd2bc2821d05c0ddbbaa025c753075b7912a9d92a755878ff106aef6dd687",
"l10n\/ru.json": "04d3768680fa02e957104a2151d00d8466acc143a8ed807f25cac5ebc2a7d890004fa5cc29f491dae834bd67430d219ddde718b57171cc38b0d2356f5a39e9b6",
"l10n\/sr.js": "1494167ced33fa664ed4ec1263e9873ff84a27b0874b4f2d7729cab640e968fd0367f3b2946f1f732b214f83a476972e23483f6f3efeb9833d7c5b113e19dfd7",
"l10n\/sr.json": "6c3986dd0667a74b03296d8b86f2f7dd74621f5d515c754a2a02c30faefa6fd77f8cb4e00daaddf670d6138cb8d42dda611526d437d08fac01c9030d3287e812",
"l10n\/sv.js": "e9fea4160483ac28d7c02b87dd8c866ad15483d80b900d50fb255711b4f576985a5dbe39a8805f10dc5d95600f2c98dc3488432c9db8bc7ba8dcc4b85817faaa",
"l10n\/sv.json": "10751c49e1e73e8fc187bc9d8b29ec1a7d3f239c56202457096e3d83bcd6d4131ecb3b7b38b234dcca486dd79df94a8d425a7530ef3aed4e3e33eb4404ae12bc",
"l10n\/tr.js": "4d8a5b3091952d377b4445df828703bead5e029654da66a07c113c467f62acef9d697cdced9a68506ca9ec2e452522fd4094ecf33a3c79b621ce4849758f2755",
"l10n\/tr.json": "1a1a400cf3a3625c586de94beafd3202ff84d73b7a0e3a16f53e46de50ce8a4fcad78911e496020795c6e8f62cd69263b2836c4baa6fb7f220f9d180079ce0b1",
"l10n\/uk.js": "af2b0a82daf373751d8a6846775f630589f9fd505107d3b5cfb05e92f4db6097f5115243421a57cd1a2c1b31529fbf063e3270cc1a0d647807a054d410fd450d",
"l10n\/uk.json": "a55a1b7939fd489959d33f0f3a207259e1aa01252e310c18b144ffe24e579d33c644d37b131db15783ae984c35bee5e449e4814a67954c86ac689faca2974f7e",
"l10n\/zh_HK.js": "38a8c4578fd3181f9186add0eb519f98a77b4759f4ee690c84d09f9b08d842d23beb1c9fabc3b162b81f2575b1927e9eb022bcb2f1277a9c45ad0da0de8836cd",
"l10n\/zh_HK.json": "5471feb77da9212933dbd5cc8cfc06fa164c2967ae6e4d3bacdb6bbf9669616cc21a5d22f54c5f7e1ba2092579bfc4172938af9cbedba15127d3a1b2ed4b9885",
"l10n\/zh_TW.js": "7764dbc5ca07ea8bcea17a0835bd27e1c09ce2e9a719758cabed075d4c3366556b44e2d4ee7ec1bf96732e5805318b8e5ab401ac0376a58e0f6facf44512e1f1",
"l10n\/zh_TW.json": "064f5cbf3caacb6dcb7ba9c69d13da6f8ec10fffaa31526cfe05a3bd64601d13a63ebdb915760c28b3fa006487bd4ca65ad28e21d9b1b36a8b99eb6313a17d33",
"lib\/AppInfo\/Application.php": "32d5a2437019220a5e25712185ebb4b3929231b6eb6b586085d417dbce8c2a8bb1e4f383580e2a4196183f98457d38d4d2e97e757222b27d926c24d33dfab46c",
"lib\/BackgroundJob\/CleanUpReminders.php": "e60c404faec9081cb20400cca201c13dad135309c835b7d632ceb18291ab2da3ed18030ae560cc2691f4b82f8fc49e558a9d8e23eceaf06782e28acb44d8b371",
"lib\/BackgroundJob\/ScheduledNotifications.php": "ed0cc57c34a1fc89d6b2264dffd14603a3b85191d07acc077a417e4936b2f3dec9361c89bbcb39de600b01a3cf67d759990274dcc3746eddb8edea41edad727d",
"lib\/Command\/ListCommand.php": "acf563b0dc9f9db64ee28fff92bf61755ada55e142526987543f67db227a8b849064f42dd86a0612e1c5d67c755373a82f1d2ea843d0ce48e0df1173c9406b5f",
"lib\/Controller\/ApiController.php": "0edefab0316266875b034319bab028ac5e16fa3d12975be101c0090c183a21e2cb04f050c2fde270cfba018b95653f0ffa0a2271d9f1d4483214a77fd0c65f41",
"lib\/Dav\/PropFindPlugin.php": "763a3d4b41654cf0e4b0c650b307e5ce5519d10b13561933be0979d9c7537989cbfb61d2ad94e6f5b65902f594519f3520f26715d48203cc0c1e748c7f6e701a",
"lib\/Db\/Reminder.php": "2350e6ac76002400785ad483c6a2650b56435c11a44361d5735c743e44bc8298fb473d21a1032b28a6685ce995225ef86809b8c80336d15fa6c024db0264f35c",
"lib\/Db\/ReminderMapper.php": "d5909900be6c0379e07bb3a1a2796588bcf30671cc228991f2a5b0654b4dbea888b15023252d66f00ec9f56a183ba086cae90fbc3939721d0963bed16d00645c",
"lib\/Exception\/NodeNotFoundException.php": "c07ac6a7fa1bc71bedc76666426024f16f75c14c3cbba5853616ec360af01133255466c1258564509b2240b4a5d91d5cef5da9bef2fc94060c8d82c8137a14ce",
"lib\/Exception\/UserNotFoundException.php": "88318ad3ec0763b895f0b96b813006e55469a779f34ae693cdeaf0fdd7065ba771f480f77fa3ecb1c890bb05356b0bb541fdbed4edaa886e12c7ecba03541c5e",
"lib\/Listener\/LoadAdditionalScriptsListener.php": "b79395298f485f50b6d150a074f00a5d299a8067f66c9cb307d9bcc4895612c974e168441782dce6480fb56466b1b99b18c3b8a2eb09ad780c5741375f0a404a",
"lib\/Listener\/NodeDeletedListener.php": "92d086ebf118f6de4dfeb3dc505ee9a1dd9e41f052b737fca43184aa20a773c22a792e286e3b36848eee722cea606351105fcca3d66d32df7f490e448692f8ae",
"lib\/Listener\/UserDeletedListener.php": "b620b410d62231b5b478126c16d047c959caa08595f295cc67bcc33e47f1d9e34439e6fffa4a1b7c6321754157e9c1f8a395bcd03f1efd3f2c0f36563f79e6dd",
"lib\/Migration\/Version10000Date20230725162149.php": "58b1e432db9f624799ad8029de7fb46c9b344de9c90d03ae678542d7d238ee46227dfd57d2b5c518276379053fd6fd418171e4567d3591127cd5c42fd4461895",
"lib\/Model\/RichReminder.php": "1cced55cfd620a3937bd866739cae26814d898e32e86b136c9d535193e84b8c5cb361179f5158b9c4dde30be0f869468f4baae31c9f7121ddae4ffa935ecdd16",
"lib\/Notification\/Notifier.php": "fb5e6c4c840ae071b8d9afc1d4ceb669bd6068883ad5081518be0fbc67c3c33cca3ab390158d79b64686488d227b6961c956d108d51637133daf39db5e8659cf",
"lib\/Service\/ReminderService.php": "90ffb5a35240e16d37b042c0e3ab046679e57d6be950aa0210d4d23257d6ec22552fa7831eadb83baf34e169857b62b2a023bc9e44bdd9dadeef91f0be4af67e",
"openapi.json": "fd40d3e7f2d114013c009f06de2f3d5d8928e7369e2b52ca9b4334df87b9973d698472514d0dcb5440e192d05f06301fa42673668737c8d322f92bfae6be7ba7"
},
"signature": "Duc\/S4+cevAJi5Hvw1je3Mtct8aZxcHZeEl2pfATbN8wi9Ir+J8rwW+zlVZ1ZDlXKK3RrgXZQ8gFYaLdGoR7v7I1mxHNW\/Dc\/703IRmVueXy6BeOP3CUeKM9aQTw3mJl3A72HyWlFhZud55XIkf2i9rkZRCcxQGXEDU3qxCGcDROhgEsNgnyj7se\/CPIqwjvlrqqhRCHqLMJbV4ml4SSZrTYYroXhaBu\/K5KAvdBEj8v\/zwrLlomK3jyKFUsC3Umozebsf57zG\/xu5OTOB2434RiD4IToHNj4i1q6hrpEUaVmVy6VT8GmUTidhEtAq5HcrTrrv7UKywMGXD1gwvzpw==",
"certificate": "-----BEGIN CERTIFICATE-----\r\nMIIEojCCA4qgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwezELMAkGA1UEBhMCREUx\r\nGzAZBgNVBAgMEkJhZGVuLVd1ZXJ0dGVtYmVyZzEXMBUGA1UECgwOTmV4dGNsb3Vk\r\nIEdtYkgxNjA0BgNVBAMMLU5leHRjbG91ZCBDb2RlIFNpZ25pbmcgSW50ZXJtZWRp\r\nYXRlIEF1dGhvcml0eTAeFw0xNjA2MTIyMTA1MDZaFw00MTA2MDYyMTA1MDZaMGYx\r\nCzAJBgNVBAYTAkRFMRswGQYDVQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxEjAQBgNV\r\nBAcMCVN0dXR0Z2FydDEXMBUGA1UECgwOTmV4dGNsb3VkIEdtYkgxDTALBgNVBAMM\r\nBGNvcmUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDUxcrn2DC892IX\r\n8+dJjZVh9YeHF65n2ha886oeAizOuHBdWBfzqt+GoUYTOjqZF93HZMcwy0P+xyCf\r\nQqak5Ke9dybN06RXUuGP45k9UYBp03qzlUzCDalrkj+Jd30LqcSC1sjRTsfuhc+u\r\nvH1IBuBnf7SMUJUcoEffbmmpAPlEcLHxlUGlGnz0q1e8UFzjbEFj3JucMO4ys35F\r\nqZS4dhvCngQhRW3DaMlQLXEUL9k3kFV+BzlkPzVZEtSmk4HJujFCnZj1vMcjQBg\/\r\nBqq1HCmUB6tulnGcxUzt\/Z\/oSIgnuGyENeke077W3EyryINL7EIyD4Xp7sxLizTM\r\nFCFCjjH1AgMBAAGjggFDMIIBPzAJBgNVHRMEAjAAMBEGCWCGSAGG+EIBAQQEAwIG\r\nQDAzBglghkgBhvhCAQ0EJhYkT3BlblNTTCBHZW5lcmF0ZWQgU2VydmVyIENlcnRp\r\nZmljYXRlMB0GA1UdDgQWBBQwc1H9AL8pRlW2e5SLCfPPqtqc0DCBpQYDVR0jBIGd\r\nMIGagBRt6m6qqTcsPIktFz79Ru7DnnjtdKF+pHwwejELMAkGA1UEBhMCREUxGzAZ\r\nBgNVBAgMEkJhZGVuLVd1ZXJ0dGVtYmVyZzESMBAGA1UEBwwJU3R1dHRnYXJ0MRcw\r\nFQYDVQQKDA5OZXh0Y2xvdWQgR21iSDEhMB8GA1UEAwwYTmV4dGNsb3VkIFJvb3Qg\r\nQXV0aG9yaXR5ggIQADAOBgNVHQ8BAf8EBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUH\r\nAwEwDQYJKoZIhvcNAQELBQADggEBADZ6+HV\/+0NEH3nahTBFxO6nKyR\/VWigACH0\r\nnaV0ecTcoQwDjKDNNFr+4S1WlHdwITlnNabC7v9rZ\/6QvbkrOTuO9fOR6azp1EwW\r\n2pixWqj0Sb9\/dSIVRpSq+jpBE6JAiX44dSR7zoBxRB8DgVO2Afy0s80xEpr5JAzb\r\nNYuPS7M5UHdAv2dr16fDcDIvn+vk92KpNh1NTeZFjBbRVQ9DXrgkRGW34TK8uSLI\r\nYG6jnfJ6eJgTaO431ywWPXNg1mUMaT\/+QBOgB299QVCKQU+lcZWptQt+RdsJUm46\r\nNY\/nARy4Oi4uOe88SuWITj9KhrFmEvrUlgM8FvoXA1ldrR7KiEg=\r\n-----END CERTIFICATE-----"
}
@@ -0,0 +1,25 @@
<?php
// autoload.php @generated by Composer
if (PHP_VERSION_ID < 50600) {
if (!headers_sent()) {
header('HTTP/1.1 500 Internal Server Error');
}
$err = 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL;
if (!ini_get('display_errors')) {
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
fwrite(STDERR, $err);
} elseif (!headers_sent()) {
echo $err;
}
}
trigger_error(
$err,
E_USER_ERROR
);
}
require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInitFilesReminders::getLoader();
@@ -0,0 +1,13 @@
{
"config" : {
"vendor-dir": ".",
"optimize-autoloader": true,
"classmap-authoritative": true,
"autoloader-suffix": "FilesReminders"
},
"autoload" : {
"psr-4": {
"OCA\\FilesReminders\\": "../lib/"
}
}
}
+18
View File
@@ -0,0 +1,18 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "d751713988987e9331980363e24189ce",
"packages": [],
"packages-dev": [],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": [],
"prefer-stable": false,
"prefer-lowest": false,
"platform": [],
"platform-dev": [],
"plugin-api-version": "2.3.0"
}
@@ -0,0 +1,579 @@
<?php
/*
* This file is part of Composer.
*
* (c) Nils Adermann <naderman@naderman.de>
* Jordi Boggiano <j.boggiano@seld.be>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Composer\Autoload;
/**
* ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
*
* $loader = new \Composer\Autoload\ClassLoader();
*
* // register classes with namespaces
* $loader->add('Symfony\Component', __DIR__.'/component');
* $loader->add('Symfony', __DIR__.'/framework');
*
* // activate the autoloader
* $loader->register();
*
* // to enable searching the include path (eg. for PEAR packages)
* $loader->setUseIncludePath(true);
*
* In this example, if you try to use a class in the Symfony\Component
* namespace or one of its children (Symfony\Component\Console for instance),
* the autoloader will first look for the class under the component/
* directory, and it will then fallback to the framework/ directory if not
* found before giving up.
*
* This class is loosely based on the Symfony UniversalClassLoader.
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Jordi Boggiano <j.boggiano@seld.be>
* @see https://www.php-fig.org/psr/psr-0/
* @see https://www.php-fig.org/psr/psr-4/
*/
class ClassLoader
{
/** @var \Closure(string):void */
private static $includeFile;
/** @var string|null */
private $vendorDir;
// PSR-4
/**
* @var array<string, array<string, int>>
*/
private $prefixLengthsPsr4 = array();
/**
* @var array<string, list<string>>
*/
private $prefixDirsPsr4 = array();
/**
* @var list<string>
*/
private $fallbackDirsPsr4 = array();
// PSR-0
/**
* List of PSR-0 prefixes
*
* Structured as array('F (first letter)' => array('Foo\Bar (full prefix)' => array('path', 'path2')))
*
* @var array<string, array<string, list<string>>>
*/
private $prefixesPsr0 = array();
/**
* @var list<string>
*/
private $fallbackDirsPsr0 = array();
/** @var bool */
private $useIncludePath = false;
/**
* @var array<string, string>
*/
private $classMap = array();
/** @var bool */
private $classMapAuthoritative = false;
/**
* @var array<string, bool>
*/
private $missingClasses = array();
/** @var string|null */
private $apcuPrefix;
/**
* @var array<string, self>
*/
private static $registeredLoaders = array();
/**
* @param string|null $vendorDir
*/
public function __construct($vendorDir = null)
{
$this->vendorDir = $vendorDir;
self::initializeIncludeClosure();
}
/**
* @return array<string, list<string>>
*/
public function getPrefixes()
{
if (!empty($this->prefixesPsr0)) {
return call_user_func_array('array_merge', array_values($this->prefixesPsr0));
}
return array();
}
/**
* @return array<string, list<string>>
*/
public function getPrefixesPsr4()
{
return $this->prefixDirsPsr4;
}
/**
* @return list<string>
*/
public function getFallbackDirs()
{
return $this->fallbackDirsPsr0;
}
/**
* @return list<string>
*/
public function getFallbackDirsPsr4()
{
return $this->fallbackDirsPsr4;
}
/**
* @return array<string, string> Array of classname => path
*/
public function getClassMap()
{
return $this->classMap;
}
/**
* @param array<string, string> $classMap Class to filename map
*
* @return void
*/
public function addClassMap(array $classMap)
{
if ($this->classMap) {
$this->classMap = array_merge($this->classMap, $classMap);
} else {
$this->classMap = $classMap;
}
}
/**
* Registers a set of PSR-0 directories for a given prefix, either
* appending or prepending to the ones previously set for this prefix.
*
* @param string $prefix The prefix
* @param list<string>|string $paths The PSR-0 root directories
* @param bool $prepend Whether to prepend the directories
*
* @return void
*/
public function add($prefix, $paths, $prepend = false)
{
$paths = (array) $paths;
if (!$prefix) {
if ($prepend) {
$this->fallbackDirsPsr0 = array_merge(
$paths,
$this->fallbackDirsPsr0
);
} else {
$this->fallbackDirsPsr0 = array_merge(
$this->fallbackDirsPsr0,
$paths
);
}
return;
}
$first = $prefix[0];
if (!isset($this->prefixesPsr0[$first][$prefix])) {
$this->prefixesPsr0[$first][$prefix] = $paths;
return;
}
if ($prepend) {
$this->prefixesPsr0[$first][$prefix] = array_merge(
$paths,
$this->prefixesPsr0[$first][$prefix]
);
} else {
$this->prefixesPsr0[$first][$prefix] = array_merge(
$this->prefixesPsr0[$first][$prefix],
$paths
);
}
}
/**
* Registers a set of PSR-4 directories for a given namespace, either
* appending or prepending to the ones previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param list<string>|string $paths The PSR-4 base directories
* @param bool $prepend Whether to prepend the directories
*
* @throws \InvalidArgumentException
*
* @return void
*/
public function addPsr4($prefix, $paths, $prepend = false)
{
$paths = (array) $paths;
if (!$prefix) {
// Register directories for the root namespace.
if ($prepend) {
$this->fallbackDirsPsr4 = array_merge(
$paths,
$this->fallbackDirsPsr4
);
} else {
$this->fallbackDirsPsr4 = array_merge(
$this->fallbackDirsPsr4,
$paths
);
}
} elseif (!isset($this->prefixDirsPsr4[$prefix])) {
// Register directories for a new namespace.
$length = strlen($prefix);
if ('\\' !== $prefix[$length - 1]) {
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
}
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
$this->prefixDirsPsr4[$prefix] = $paths;
} elseif ($prepend) {
// Prepend directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
$paths,
$this->prefixDirsPsr4[$prefix]
);
} else {
// Append directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
$this->prefixDirsPsr4[$prefix],
$paths
);
}
}
/**
* Registers a set of PSR-0 directories for a given prefix,
* replacing any others previously set for this prefix.
*
* @param string $prefix The prefix
* @param list<string>|string $paths The PSR-0 base directories
*
* @return void
*/
public function set($prefix, $paths)
{
if (!$prefix) {
$this->fallbackDirsPsr0 = (array) $paths;
} else {
$this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
}
}
/**
* Registers a set of PSR-4 directories for a given namespace,
* replacing any others previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param list<string>|string $paths The PSR-4 base directories
*
* @throws \InvalidArgumentException
*
* @return void
*/
public function setPsr4($prefix, $paths)
{
if (!$prefix) {
$this->fallbackDirsPsr4 = (array) $paths;
} else {
$length = strlen($prefix);
if ('\\' !== $prefix[$length - 1]) {
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
}
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
$this->prefixDirsPsr4[$prefix] = (array) $paths;
}
}
/**
* Turns on searching the include path for class files.
*
* @param bool $useIncludePath
*
* @return void
*/
public function setUseIncludePath($useIncludePath)
{
$this->useIncludePath = $useIncludePath;
}
/**
* Can be used to check if the autoloader uses the include path to check
* for classes.
*
* @return bool
*/
public function getUseIncludePath()
{
return $this->useIncludePath;
}
/**
* Turns off searching the prefix and fallback directories for classes
* that have not been registered with the class map.
*
* @param bool $classMapAuthoritative
*
* @return void
*/
public function setClassMapAuthoritative($classMapAuthoritative)
{
$this->classMapAuthoritative = $classMapAuthoritative;
}
/**
* Should class lookup fail if not found in the current class map?
*
* @return bool
*/
public function isClassMapAuthoritative()
{
return $this->classMapAuthoritative;
}
/**
* APCu prefix to use to cache found/not-found classes, if the extension is enabled.
*
* @param string|null $apcuPrefix
*
* @return void
*/
public function setApcuPrefix($apcuPrefix)
{
$this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
}
/**
* The APCu prefix in use, or null if APCu caching is not enabled.
*
* @return string|null
*/
public function getApcuPrefix()
{
return $this->apcuPrefix;
}
/**
* Registers this instance as an autoloader.
*
* @param bool $prepend Whether to prepend the autoloader or not
*
* @return void
*/
public function register($prepend = false)
{
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
if (null === $this->vendorDir) {
return;
}
if ($prepend) {
self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
} else {
unset(self::$registeredLoaders[$this->vendorDir]);
self::$registeredLoaders[$this->vendorDir] = $this;
}
}
/**
* Unregisters this instance as an autoloader.
*
* @return void
*/
public function unregister()
{
spl_autoload_unregister(array($this, 'loadClass'));
if (null !== $this->vendorDir) {
unset(self::$registeredLoaders[$this->vendorDir]);
}
}
/**
* Loads the given class or interface.
*
* @param string $class The name of the class
* @return true|null True if loaded, null otherwise
*/
public function loadClass($class)
{
if ($file = $this->findFile($class)) {
$includeFile = self::$includeFile;
$includeFile($file);
return true;
}
return null;
}
/**
* Finds the path to the file where the class is defined.
*
* @param string $class The name of the class
*
* @return string|false The path if found, false otherwise
*/
public function findFile($class)
{
// class map lookup
if (isset($this->classMap[$class])) {
return $this->classMap[$class];
}
if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
return false;
}
if (null !== $this->apcuPrefix) {
$file = apcu_fetch($this->apcuPrefix.$class, $hit);
if ($hit) {
return $file;
}
}
$file = $this->findFileWithExtension($class, '.php');
// Search for Hack files if we are running on HHVM
if (false === $file && defined('HHVM_VERSION')) {
$file = $this->findFileWithExtension($class, '.hh');
}
if (null !== $this->apcuPrefix) {
apcu_add($this->apcuPrefix.$class, $file);
}
if (false === $file) {
// Remember that this class does not exist.
$this->missingClasses[$class] = true;
}
return $file;
}
/**
* Returns the currently registered loaders keyed by their corresponding vendor directories.
*
* @return array<string, self>
*/
public static function getRegisteredLoaders()
{
return self::$registeredLoaders;
}
/**
* @param string $class
* @param string $ext
* @return string|false
*/
private function findFileWithExtension($class, $ext)
{
// PSR-4 lookup
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
$first = $class[0];
if (isset($this->prefixLengthsPsr4[$first])) {
$subPath = $class;
while (false !== $lastPos = strrpos($subPath, '\\')) {
$subPath = substr($subPath, 0, $lastPos);
$search = $subPath . '\\';
if (isset($this->prefixDirsPsr4[$search])) {
$pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
foreach ($this->prefixDirsPsr4[$search] as $dir) {
if (file_exists($file = $dir . $pathEnd)) {
return $file;
}
}
}
}
}
// PSR-4 fallback dirs
foreach ($this->fallbackDirsPsr4 as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
return $file;
}
}
// PSR-0 lookup
if (false !== $pos = strrpos($class, '\\')) {
// namespaced class name
$logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
. strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
} else {
// PEAR-like class name
$logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
}
if (isset($this->prefixesPsr0[$first])) {
foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
if (0 === strpos($class, $prefix)) {
foreach ($dirs as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
return $file;
}
}
}
}
}
// PSR-0 fallback dirs
foreach ($this->fallbackDirsPsr0 as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
return $file;
}
}
// PSR-0 include paths.
if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
return $file;
}
return false;
}
/**
* @return void
*/
private static function initializeIncludeClosure()
{
if (self::$includeFile !== null) {
return;
}
/**
* Scope isolated include.
*
* Prevents access to $this/self from included files.
*
* @param string $file
* @return void
*/
self::$includeFile = \Closure::bind(static function($file) {
include $file;
}, null, null);
}
}
@@ -0,0 +1,359 @@
<?php
/*
* This file is part of Composer.
*
* (c) Nils Adermann <naderman@naderman.de>
* Jordi Boggiano <j.boggiano@seld.be>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Composer;
use Composer\Autoload\ClassLoader;
use Composer\Semver\VersionParser;
/**
* This class is copied in every Composer installed project and available to all
*
* See also https://getcomposer.org/doc/07-runtime.md#installed-versions
*
* To require its presence, you can require `composer-runtime-api ^2.0`
*
* @final
*/
class InstalledVersions
{
/**
* @var mixed[]|null
* @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}|array{}|null
*/
private static $installed;
/**
* @var bool|null
*/
private static $canGetVendors;
/**
* @var array[]
* @psalm-var array<string, array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
*/
private static $installedByVendor = array();
/**
* Returns a list of all package names which are present, either by being installed, replaced or provided
*
* @return string[]
* @psalm-return list<string>
*/
public static function getInstalledPackages()
{
$packages = array();
foreach (self::getInstalled() as $installed) {
$packages[] = array_keys($installed['versions']);
}
if (1 === \count($packages)) {
return $packages[0];
}
return array_keys(array_flip(\call_user_func_array('array_merge', $packages)));
}
/**
* Returns a list of all package names with a specific type e.g. 'library'
*
* @param string $type
* @return string[]
* @psalm-return list<string>
*/
public static function getInstalledPackagesByType($type)
{
$packagesByType = array();
foreach (self::getInstalled() as $installed) {
foreach ($installed['versions'] as $name => $package) {
if (isset($package['type']) && $package['type'] === $type) {
$packagesByType[] = $name;
}
}
}
return $packagesByType;
}
/**
* Checks whether the given package is installed
*
* This also returns true if the package name is provided or replaced by another package
*
* @param string $packageName
* @param bool $includeDevRequirements
* @return bool
*/
public static function isInstalled($packageName, $includeDevRequirements = true)
{
foreach (self::getInstalled() as $installed) {
if (isset($installed['versions'][$packageName])) {
return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false;
}
}
return false;
}
/**
* Checks whether the given package satisfies a version constraint
*
* e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call:
*
* Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3')
*
* @param VersionParser $parser Install composer/semver to have access to this class and functionality
* @param string $packageName
* @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package
* @return bool
*/
public static function satisfies(VersionParser $parser, $packageName, $constraint)
{
$constraint = $parser->parseConstraints((string) $constraint);
$provided = $parser->parseConstraints(self::getVersionRanges($packageName));
return $provided->matches($constraint);
}
/**
* Returns a version constraint representing all the range(s) which are installed for a given package
*
* It is easier to use this via isInstalled() with the $constraint argument if you need to check
* whether a given version of a package is installed, and not just whether it exists
*
* @param string $packageName
* @return string Version constraint usable with composer/semver
*/
public static function getVersionRanges($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
$ranges = array();
if (isset($installed['versions'][$packageName]['pretty_version'])) {
$ranges[] = $installed['versions'][$packageName]['pretty_version'];
}
if (array_key_exists('aliases', $installed['versions'][$packageName])) {
$ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']);
}
if (array_key_exists('replaced', $installed['versions'][$packageName])) {
$ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']);
}
if (array_key_exists('provided', $installed['versions'][$packageName])) {
$ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']);
}
return implode(' || ', $ranges);
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @param string $packageName
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
*/
public static function getVersion($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
if (!isset($installed['versions'][$packageName]['version'])) {
return null;
}
return $installed['versions'][$packageName]['version'];
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @param string $packageName
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
*/
public static function getPrettyVersion($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
if (!isset($installed['versions'][$packageName]['pretty_version'])) {
return null;
}
return $installed['versions'][$packageName]['pretty_version'];
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @param string $packageName
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference
*/
public static function getReference($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
if (!isset($installed['versions'][$packageName]['reference'])) {
return null;
}
return $installed['versions'][$packageName]['reference'];
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @param string $packageName
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path.
*/
public static function getInstallPath($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null;
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @return array
* @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}
*/
public static function getRootPackage()
{
$installed = self::getInstalled();
return $installed[0]['root'];
}
/**
* Returns the raw installed.php data for custom implementations
*
* @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect.
* @return array[]
* @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}
*/
public static function getRawData()
{
@trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED);
if (null === self::$installed) {
// only require the installed.php file if this file is loaded from its dumped location,
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
if (substr(__DIR__, -8, 1) !== 'C') {
self::$installed = include __DIR__ . '/installed.php';
} else {
self::$installed = array();
}
}
return self::$installed;
}
/**
* Returns the raw data of all installed.php which are currently loaded for custom implementations
*
* @return array[]
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
*/
public static function getAllRawData()
{
return self::getInstalled();
}
/**
* Lets you reload the static array from another file
*
* This is only useful for complex integrations in which a project needs to use
* this class but then also needs to execute another project's autoloader in process,
* and wants to ensure both projects have access to their version of installed.php.
*
* A typical case would be PHPUnit, where it would need to make sure it reads all
* the data it needs from this class, then call reload() with
* `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure
* the project in which it runs can then also use this class safely, without
* interference between PHPUnit's dependencies and the project's dependencies.
*
* @param array[] $data A vendor/composer/installed.php data set
* @return void
*
* @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $data
*/
public static function reload($data)
{
self::$installed = $data;
self::$installedByVendor = array();
}
/**
* @return array[]
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
*/
private static function getInstalled()
{
if (null === self::$canGetVendors) {
self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders');
}
$installed = array();
if (self::$canGetVendors) {
foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
if (isset(self::$installedByVendor[$vendorDir])) {
$installed[] = self::$installedByVendor[$vendorDir];
} elseif (is_file($vendorDir.'/composer/installed.php')) {
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
$required = require $vendorDir.'/composer/installed.php';
$installed[] = self::$installedByVendor[$vendorDir] = $required;
if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
self::$installed = $installed[count($installed) - 1];
}
}
}
}
if (null === self::$installed) {
// only require the installed.php file if this file is loaded from its dumped location,
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
if (substr(__DIR__, -8, 1) !== 'C') {
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
$required = require __DIR__ . '/installed.php';
self::$installed = $required;
} else {
self::$installed = array();
}
}
if (self::$installed !== array()) {
$installed[] = self::$installed;
}
return $installed;
}
}
@@ -0,0 +1,21 @@
Copyright (c) Nils Adermann, Jordi Boggiano
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
@@ -0,0 +1,27 @@
<?php
// autoload_classmap.php @generated by Composer
$vendorDir = dirname(__DIR__);
$baseDir = $vendorDir;
return array(
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
'OCA\\FilesReminders\\AppInfo\\Application' => $baseDir . '/../lib/AppInfo/Application.php',
'OCA\\FilesReminders\\BackgroundJob\\CleanUpReminders' => $baseDir . '/../lib/BackgroundJob/CleanUpReminders.php',
'OCA\\FilesReminders\\BackgroundJob\\ScheduledNotifications' => $baseDir . '/../lib/BackgroundJob/ScheduledNotifications.php',
'OCA\\FilesReminders\\Command\\ListCommand' => $baseDir . '/../lib/Command/ListCommand.php',
'OCA\\FilesReminders\\Controller\\ApiController' => $baseDir . '/../lib/Controller/ApiController.php',
'OCA\\FilesReminders\\Dav\\PropFindPlugin' => $baseDir . '/../lib/Dav/PropFindPlugin.php',
'OCA\\FilesReminders\\Db\\Reminder' => $baseDir . '/../lib/Db/Reminder.php',
'OCA\\FilesReminders\\Db\\ReminderMapper' => $baseDir . '/../lib/Db/ReminderMapper.php',
'OCA\\FilesReminders\\Exception\\NodeNotFoundException' => $baseDir . '/../lib/Exception/NodeNotFoundException.php',
'OCA\\FilesReminders\\Exception\\UserNotFoundException' => $baseDir . '/../lib/Exception/UserNotFoundException.php',
'OCA\\FilesReminders\\Listener\\LoadAdditionalScriptsListener' => $baseDir . '/../lib/Listener/LoadAdditionalScriptsListener.php',
'OCA\\FilesReminders\\Listener\\NodeDeletedListener' => $baseDir . '/../lib/Listener/NodeDeletedListener.php',
'OCA\\FilesReminders\\Listener\\UserDeletedListener' => $baseDir . '/../lib/Listener/UserDeletedListener.php',
'OCA\\FilesReminders\\Migration\\Version10000Date20230725162149' => $baseDir . '/../lib/Migration/Version10000Date20230725162149.php',
'OCA\\FilesReminders\\Model\\RichReminder' => $baseDir . '/../lib/Model/RichReminder.php',
'OCA\\FilesReminders\\Notification\\Notifier' => $baseDir . '/../lib/Notification/Notifier.php',
'OCA\\FilesReminders\\Service\\ReminderService' => $baseDir . '/../lib/Service/ReminderService.php',
);
@@ -0,0 +1,9 @@
<?php
// autoload_namespaces.php @generated by Composer
$vendorDir = dirname(__DIR__);
$baseDir = $vendorDir;
return array(
);
@@ -0,0 +1,10 @@
<?php
// autoload_psr4.php @generated by Composer
$vendorDir = dirname(__DIR__);
$baseDir = $vendorDir;
return array(
'OCA\\FilesReminders\\' => array($baseDir . '/../lib'),
);
@@ -0,0 +1,37 @@
<?php
// autoload_real.php @generated by Composer
class ComposerAutoloaderInitFilesReminders
{
private static $loader;
public static function loadClassLoader($class)
{
if ('Composer\Autoload\ClassLoader' === $class) {
require __DIR__ . '/ClassLoader.php';
}
}
/**
* @return \Composer\Autoload\ClassLoader
*/
public static function getLoader()
{
if (null !== self::$loader) {
return self::$loader;
}
spl_autoload_register(array('ComposerAutoloaderInitFilesReminders', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
spl_autoload_unregister(array('ComposerAutoloaderInitFilesReminders', 'loadClassLoader'));
require __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInitFilesReminders::getInitializer($loader));
$loader->setClassMapAuthoritative(true);
$loader->register(true);
return $loader;
}
}
@@ -0,0 +1,53 @@
<?php
// autoload_static.php @generated by Composer
namespace Composer\Autoload;
class ComposerStaticInitFilesReminders
{
public static $prefixLengthsPsr4 = array (
'O' =>
array (
'OCA\\FilesReminders\\' => 19,
),
);
public static $prefixDirsPsr4 = array (
'OCA\\FilesReminders\\' =>
array (
0 => __DIR__ . '/..' . '/../lib',
),
);
public static $classMap = array (
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
'OCA\\FilesReminders\\AppInfo\\Application' => __DIR__ . '/..' . '/../lib/AppInfo/Application.php',
'OCA\\FilesReminders\\BackgroundJob\\CleanUpReminders' => __DIR__ . '/..' . '/../lib/BackgroundJob/CleanUpReminders.php',
'OCA\\FilesReminders\\BackgroundJob\\ScheduledNotifications' => __DIR__ . '/..' . '/../lib/BackgroundJob/ScheduledNotifications.php',
'OCA\\FilesReminders\\Command\\ListCommand' => __DIR__ . '/..' . '/../lib/Command/ListCommand.php',
'OCA\\FilesReminders\\Controller\\ApiController' => __DIR__ . '/..' . '/../lib/Controller/ApiController.php',
'OCA\\FilesReminders\\Dav\\PropFindPlugin' => __DIR__ . '/..' . '/../lib/Dav/PropFindPlugin.php',
'OCA\\FilesReminders\\Db\\Reminder' => __DIR__ . '/..' . '/../lib/Db/Reminder.php',
'OCA\\FilesReminders\\Db\\ReminderMapper' => __DIR__ . '/..' . '/../lib/Db/ReminderMapper.php',
'OCA\\FilesReminders\\Exception\\NodeNotFoundException' => __DIR__ . '/..' . '/../lib/Exception/NodeNotFoundException.php',
'OCA\\FilesReminders\\Exception\\UserNotFoundException' => __DIR__ . '/..' . '/../lib/Exception/UserNotFoundException.php',
'OCA\\FilesReminders\\Listener\\LoadAdditionalScriptsListener' => __DIR__ . '/..' . '/../lib/Listener/LoadAdditionalScriptsListener.php',
'OCA\\FilesReminders\\Listener\\NodeDeletedListener' => __DIR__ . '/..' . '/../lib/Listener/NodeDeletedListener.php',
'OCA\\FilesReminders\\Listener\\UserDeletedListener' => __DIR__ . '/..' . '/../lib/Listener/UserDeletedListener.php',
'OCA\\FilesReminders\\Migration\\Version10000Date20230725162149' => __DIR__ . '/..' . '/../lib/Migration/Version10000Date20230725162149.php',
'OCA\\FilesReminders\\Model\\RichReminder' => __DIR__ . '/..' . '/../lib/Model/RichReminder.php',
'OCA\\FilesReminders\\Notification\\Notifier' => __DIR__ . '/..' . '/../lib/Notification/Notifier.php',
'OCA\\FilesReminders\\Service\\ReminderService' => __DIR__ . '/..' . '/../lib/Service/ReminderService.php',
);
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInitFilesReminders::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInitFilesReminders::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInitFilesReminders::$classMap;
}, null, ClassLoader::class);
}
}
@@ -0,0 +1,5 @@
{
"packages": [],
"dev": false,
"dev-package-names": []
}
@@ -0,0 +1,23 @@
<?php return array(
'root' => array(
'name' => '__root__',
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'reference' => '9685b49f0d8f9e7d34f299e51628748a04d0e175',
'type' => 'library',
'install_path' => __DIR__ . '/../',
'aliases' => array(),
'dev' => false,
),
'versions' => array(
'__root__' => array(
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'reference' => '9685b49f0d8f9e7d34f299e51628748a04d0e175',
'type' => 'library',
'install_path' => __DIR__ . '/../',
'aliases' => array(),
'dev_requirement' => false,
),
),
);
@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000">
<path d="M0 0h24v24H0V0z" fill="none" />
<path
d="M12.5 8H11v6l4.75 2.85.75-1.23-4-2.37zm4.837-6.19l4.607 3.845-1.28 1.535-4.61-3.843zm-10.674 0l1.282 1.536L3.337 7.19l-1.28-1.536zM12 4c-4.97 0-9 4.03-9 9s4.03 9 9 9 9-4.03 9-9-4.03-9-9-9zm0 16c-3.86 0-7-3.14-7-7s3.14-7 7-7 7 3.14 7 7-3.14 7-7 7z" />
</svg>

After

Width:  |  Height:  |  Size: 415 B

@@ -0,0 +1,33 @@
OC.L10N.register(
"files_reminders",
{
"File reminders" : "تذكيرات الملفات",
"Reminder for {name}" : "تذكير لـ {name}",
"View file" : "أعرُض الملف",
"View folder" : "أعرُض المجلد",
"Set file reminders" : "تعيين تذكيرات للملفات",
"**📣 File reminders**\n\nSet file reminders." : "**📣 تذكيرات الملفات File reminders**\n\nتعيين تذكيرات الملفات.",
"We will remind you of this file" : "سوف يتم تذكيرك بهذا الملف",
"Please choose a valid date & time" : "من فضلك، إختَر وقتاً و تاريخاً صحيحين",
"Cancel" : "إلغاء",
"Set reminder" : "ضبط التذكير",
"Set reminder for \"{fileName}\"" : "تعيين تنبيه للملف \"{fileName}\"",
"Set reminder at custom date & time" : "حدّد التذكير في وقت و تاريخ مخصص",
"Clear reminder" : "إمحُ التذكير",
"Reminder set for \"{fileName}\"" : "تمّ تعيين تذكير لـ \"{fileName}\"",
"Failed to set reminder" : "تعذّر تعيين التذكير",
"Set custom reminder" : "تعيين تذكير مُخصّص",
"Later today" : "في وقت لاحقٍ اليوم",
"Set reminder for later today" : "عيّن التذكير لوقت لاحقٍ اليوم",
"Tomorrow" : "غدا",
"Set reminder for tomorrow" : "عيّن التذكير للغد",
"This weekend" : "نهاية هذا الأسبوع",
"Set reminder for this weekend" : "عيّن التذكير لنهاية هذا الأسبوع",
"Next week" : "الأسبوع القادم",
"Set reminder for next week" : "عيّن التذكير للأسبوع القادم",
"Back" : "عودة",
"Reminder cleared" : "تمّت إزالة التذكير",
"Failed to clear reminder" : "تعذّرت إزالة التذكير",
"Failed to load reminder" : "تعذّر تحميل التذكير"
},
"nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;");
@@ -0,0 +1,31 @@
{ "translations": {
"File reminders" : "تذكيرات الملفات",
"Reminder for {name}" : "تذكير لـ {name}",
"View file" : "أعرُض الملف",
"View folder" : "أعرُض المجلد",
"Set file reminders" : "تعيين تذكيرات للملفات",
"**📣 File reminders**\n\nSet file reminders." : "**📣 تذكيرات الملفات File reminders**\n\nتعيين تذكيرات الملفات.",
"We will remind you of this file" : "سوف يتم تذكيرك بهذا الملف",
"Please choose a valid date & time" : "من فضلك، إختَر وقتاً و تاريخاً صحيحين",
"Cancel" : "إلغاء",
"Set reminder" : "ضبط التذكير",
"Set reminder for \"{fileName}\"" : "تعيين تنبيه للملف \"{fileName}\"",
"Set reminder at custom date & time" : "حدّد التذكير في وقت و تاريخ مخصص",
"Clear reminder" : "إمحُ التذكير",
"Reminder set for \"{fileName}\"" : "تمّ تعيين تذكير لـ \"{fileName}\"",
"Failed to set reminder" : "تعذّر تعيين التذكير",
"Set custom reminder" : "تعيين تذكير مُخصّص",
"Later today" : "في وقت لاحقٍ اليوم",
"Set reminder for later today" : "عيّن التذكير لوقت لاحقٍ اليوم",
"Tomorrow" : "غدا",
"Set reminder for tomorrow" : "عيّن التذكير للغد",
"This weekend" : "نهاية هذا الأسبوع",
"Set reminder for this weekend" : "عيّن التذكير لنهاية هذا الأسبوع",
"Next week" : "الأسبوع القادم",
"Set reminder for next week" : "عيّن التذكير للأسبوع القادم",
"Back" : "عودة",
"Reminder cleared" : "تمّت إزالة التذكير",
"Failed to clear reminder" : "تعذّرت إزالة التذكير",
"Failed to load reminder" : "تعذّر تحميل التذكير"
},"pluralForm" :"nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;"
}
@@ -0,0 +1,33 @@
OC.L10N.register(
"files_reminders",
{
"File reminders" : "Připomínky souborů",
"Reminder for {name}" : "Připomínka ohledně {name}",
"View file" : "Zobrazit soubor",
"View folder" : "Zobrazit složku",
"Set file reminders" : "Nastavit připomínky souborů",
"**📣 File reminders**\n\nSet file reminders." : "**📣 Připomínky souborů**\n\nNastavte připomínky souborů.",
"We will remind you of this file" : "Připomeneme vám tento soubor",
"Please choose a valid date & time" : "Zvolte platný datum a čas",
"Cancel" : "Storno",
"Set reminder" : "Nastavit připomínku",
"Set reminder for \"{fileName}\"" : "Nastavit připomínku pro „{fileName}",
"Set reminder at custom date & time" : "Nastavit připomínku na uživatelsky určené datum a čas",
"Clear reminder" : "Vyčistit připomínku",
"Reminder set for \"{fileName}\"" : "Nastavena připomínka ohledně „{fileName}“",
"Failed to set reminder" : "Připomínku se nepodařilo nastavit",
"Set custom reminder" : "Nastavit uživatelsky určenou připomínku",
"Later today" : "Později dnes",
"Set reminder for later today" : "Nastavit připomínku na později dnes",
"Tomorrow" : "Zítra",
"Set reminder for tomorrow" : "Nastavit připomínku na zítra",
"This weekend" : "Tento víkend",
"Set reminder for this weekend" : "Nastavit připomínku na tento víkend",
"Next week" : "Příští týden",
"Set reminder for next week" : "Nastavit připomínku pro příští týden",
"Back" : "Zpět",
"Reminder cleared" : "Připomínka vyčištěna",
"Failed to clear reminder" : "Připomínku se nepodařilo vyčistit",
"Failed to load reminder" : "Připomínku se nepodařilo načíst"
},
"nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n >= 2 && n <= 4 && n % 1 == 0) ? 1: (n % 1 != 0 ) ? 2 : 3;");
@@ -0,0 +1,31 @@
{ "translations": {
"File reminders" : "Připomínky souborů",
"Reminder for {name}" : "Připomínka ohledně {name}",
"View file" : "Zobrazit soubor",
"View folder" : "Zobrazit složku",
"Set file reminders" : "Nastavit připomínky souborů",
"**📣 File reminders**\n\nSet file reminders." : "**📣 Připomínky souborů**\n\nNastavte připomínky souborů.",
"We will remind you of this file" : "Připomeneme vám tento soubor",
"Please choose a valid date & time" : "Zvolte platný datum a čas",
"Cancel" : "Storno",
"Set reminder" : "Nastavit připomínku",
"Set reminder for \"{fileName}\"" : "Nastavit připomínku pro „{fileName}",
"Set reminder at custom date & time" : "Nastavit připomínku na uživatelsky určené datum a čas",
"Clear reminder" : "Vyčistit připomínku",
"Reminder set for \"{fileName}\"" : "Nastavena připomínka ohledně „{fileName}“",
"Failed to set reminder" : "Připomínku se nepodařilo nastavit",
"Set custom reminder" : "Nastavit uživatelsky určenou připomínku",
"Later today" : "Později dnes",
"Set reminder for later today" : "Nastavit připomínku na později dnes",
"Tomorrow" : "Zítra",
"Set reminder for tomorrow" : "Nastavit připomínku na zítra",
"This weekend" : "Tento víkend",
"Set reminder for this weekend" : "Nastavit připomínku na tento víkend",
"Next week" : "Příští týden",
"Set reminder for next week" : "Nastavit připomínku pro příští týden",
"Back" : "Zpět",
"Reminder cleared" : "Připomínka vyčištěna",
"Failed to clear reminder" : "Připomínku se nepodařilo vyčistit",
"Failed to load reminder" : "Připomínku se nepodařilo načíst"
},"pluralForm" :"nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n >= 2 && n <= 4 && n % 1 == 0) ? 1: (n % 1 != 0 ) ? 2 : 3;"
}
@@ -0,0 +1,33 @@
OC.L10N.register(
"files_reminders",
{
"File reminders" : "Dateierinnerungen",
"Reminder for {name}" : "Erinnerung für {name}",
"View file" : "Datei anzeigen",
"View folder" : "Ordner anzeigen",
"Set file reminders" : "Dateierinnerungen setzen",
"**📣 File reminders**\n\nSet file reminders." : "**📣 Dateierinnerungen**\n\nSetze Dateierinnerungen.",
"We will remind you of this file" : "Sie werden an diese Datei erinnert werden",
"Please choose a valid date & time" : "Bitte gültiges Datum und Uhrzeit wählen",
"Cancel" : "Abbrechen",
"Set reminder" : "Erinnerung erstellen",
"Set reminder for \"{fileName}\"" : "Erinnerung für \"{fileName}\" setzen",
"Set reminder at custom date & time" : "Erinnerung für benutzerdefinierten Zeitpunkt und Tag erstellen",
"Clear reminder" : "Erinnerung löschen",
"Reminder set for \"{fileName}\"" : "Erinnerung für \"{filename}\" gesetzt",
"Failed to set reminder" : "Fehler beim Setzen der Erinnerung",
"Set custom reminder" : "Benutzerdefinierte Erinnerung erstellen",
"Later today" : "Später heute",
"Set reminder for later today" : "Erinnerung für später heute erstellen",
"Tomorrow" : "Morgen",
"Set reminder for tomorrow" : "Erinnerung für morgen erstellen",
"This weekend" : "Dieses Wochenende",
"Set reminder for this weekend" : "Erinnerung für kommendes Wochenende erstellen",
"Next week" : "Nächste Woche",
"Set reminder for next week" : "Erinnerung für nächste Woche erstellen",
"Back" : "Zurück",
"Reminder cleared" : "Erinnerung gelöscht",
"Failed to clear reminder" : "Fehler beim Löschen der Erinnerung",
"Failed to load reminder" : "Fehler beim Laden der Erinnerung"
},
"nplurals=2; plural=(n != 1);");
@@ -0,0 +1,31 @@
{ "translations": {
"File reminders" : "Dateierinnerungen",
"Reminder for {name}" : "Erinnerung für {name}",
"View file" : "Datei anzeigen",
"View folder" : "Ordner anzeigen",
"Set file reminders" : "Dateierinnerungen setzen",
"**📣 File reminders**\n\nSet file reminders." : "**📣 Dateierinnerungen**\n\nSetze Dateierinnerungen.",
"We will remind you of this file" : "Sie werden an diese Datei erinnert werden",
"Please choose a valid date & time" : "Bitte gültiges Datum und Uhrzeit wählen",
"Cancel" : "Abbrechen",
"Set reminder" : "Erinnerung erstellen",
"Set reminder for \"{fileName}\"" : "Erinnerung für \"{fileName}\" setzen",
"Set reminder at custom date & time" : "Erinnerung für benutzerdefinierten Zeitpunkt und Tag erstellen",
"Clear reminder" : "Erinnerung löschen",
"Reminder set for \"{fileName}\"" : "Erinnerung für \"{filename}\" gesetzt",
"Failed to set reminder" : "Fehler beim Setzen der Erinnerung",
"Set custom reminder" : "Benutzerdefinierte Erinnerung erstellen",
"Later today" : "Später heute",
"Set reminder for later today" : "Erinnerung für später heute erstellen",
"Tomorrow" : "Morgen",
"Set reminder for tomorrow" : "Erinnerung für morgen erstellen",
"This weekend" : "Dieses Wochenende",
"Set reminder for this weekend" : "Erinnerung für kommendes Wochenende erstellen",
"Next week" : "Nächste Woche",
"Set reminder for next week" : "Erinnerung für nächste Woche erstellen",
"Back" : "Zurück",
"Reminder cleared" : "Erinnerung gelöscht",
"Failed to clear reminder" : "Fehler beim Löschen der Erinnerung",
"Failed to load reminder" : "Fehler beim Laden der Erinnerung"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}
@@ -0,0 +1,31 @@
OC.L10N.register(
"files_reminders",
{
"File reminders" : "Υπενθυμίσεις αρχείων",
"Reminder for {name}" : "Υπενθύμιση για {name}",
"View file" : "Προβολή αρχείου",
"View folder" : "Προβολή φακέλου",
"Set file reminders" : "Ορίστε υπενθυμίσεις αρχείων",
"**📣 File reminders**\n\nSet file reminders." : "**📣 Υπενθυμίσεις αρχείων**\n\nΟρίστε υπενθυμίσεις αρχείων.",
"Please choose a valid date & time" : "Επιλέξτε μια έγκυρη ημερομηνία και ώρα",
"Cancel" : "Ακύρωση",
"Set reminder" : "Προσθήκη υπενθύμισης",
"Set reminder at custom date & time" : "Ορίστε την υπενθύμιση σε προσαρμοσμένη ημερομηνία και ώρα",
"Clear reminder" : "Εκκαθάριση υπενθύμισης",
"Reminder set for \"{fileName}\"" : "Ορίστηκε υπενθύμιση για \"{fileName}\"",
"Failed to set reminder" : "Αποτυχία ορισμού υπενθύμισης",
"Set custom reminder" : "Ορισμός προσαρμοσμένης υπενθύμισης",
"Later today" : "Αργότερα σήμερα",
"Set reminder for later today" : "Ορισμός υπενθύμισης για αργότερα σήμερα",
"Tomorrow" : "Αύριο",
"Set reminder for tomorrow" : "Ορισμός υπενθύμισης για αύριο",
"This weekend" : "Αυτό το Σαββατοκύριακο",
"Set reminder for this weekend" : "Ορίστε υπενθύμιση για αυτό το Σαββατοκύριακο",
"Next week" : "Επόμενη εβδομάδα",
"Set reminder for next week" : "Ορίστε υπενθύμιση για την επόμενη εβδομάδα",
"Back" : "Επιστροφή",
"Reminder cleared" : "Η υπενθύμιση διαγράφηκε",
"Failed to clear reminder" : "Αποτυχία εκκαθάρισης της υπενθύμισης",
"Failed to load reminder" : "Η φόρτωση της υπενθύμισης απέτυχε"
},
"nplurals=2; plural=(n != 1);");
@@ -0,0 +1,29 @@
{ "translations": {
"File reminders" : "Υπενθυμίσεις αρχείων",
"Reminder for {name}" : "Υπενθύμιση για {name}",
"View file" : "Προβολή αρχείου",
"View folder" : "Προβολή φακέλου",
"Set file reminders" : "Ορίστε υπενθυμίσεις αρχείων",
"**📣 File reminders**\n\nSet file reminders." : "**📣 Υπενθυμίσεις αρχείων**\n\nΟρίστε υπενθυμίσεις αρχείων.",
"Please choose a valid date & time" : "Επιλέξτε μια έγκυρη ημερομηνία και ώρα",
"Cancel" : "Ακύρωση",
"Set reminder" : "Προσθήκη υπενθύμισης",
"Set reminder at custom date & time" : "Ορίστε την υπενθύμιση σε προσαρμοσμένη ημερομηνία και ώρα",
"Clear reminder" : "Εκκαθάριση υπενθύμισης",
"Reminder set for \"{fileName}\"" : "Ορίστηκε υπενθύμιση για \"{fileName}\"",
"Failed to set reminder" : "Αποτυχία ορισμού υπενθύμισης",
"Set custom reminder" : "Ορισμός προσαρμοσμένης υπενθύμισης",
"Later today" : "Αργότερα σήμερα",
"Set reminder for later today" : "Ορισμός υπενθύμισης για αργότερα σήμερα",
"Tomorrow" : "Αύριο",
"Set reminder for tomorrow" : "Ορισμός υπενθύμισης για αύριο",
"This weekend" : "Αυτό το Σαββατοκύριακο",
"Set reminder for this weekend" : "Ορίστε υπενθύμιση για αυτό το Σαββατοκύριακο",
"Next week" : "Επόμενη εβδομάδα",
"Set reminder for next week" : "Ορίστε υπενθύμιση για την επόμενη εβδομάδα",
"Back" : "Επιστροφή",
"Reminder cleared" : "Η υπενθύμιση διαγράφηκε",
"Failed to clear reminder" : "Αποτυχία εκκαθάρισης της υπενθύμισης",
"Failed to load reminder" : "Η φόρτωση της υπενθύμισης απέτυχε"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}
@@ -0,0 +1,31 @@
OC.L10N.register(
"files_reminders",
{
"File reminders" : "File reminders",
"Reminder for {name}" : "Reminder for {name}",
"View file" : "View file",
"View folder" : "View folder",
"Set file reminders" : "Set file reminders",
"**📣 File reminders**\n\nSet file reminders." : "**📣 File reminders**\n\nSet file reminders.",
"Please choose a valid date & time" : "Please choose a valid date & time",
"Cancel" : "Cancel",
"Set reminder" : "Set reminder",
"Set reminder at custom date & time" : "Set reminder at custom date & time",
"Clear reminder" : "Clear reminder",
"Reminder set for \"{fileName}\"" : "Reminder set for \"{fileName}\"",
"Failed to set reminder" : "Failed to set reminder",
"Set custom reminder" : "Set custom reminder",
"Later today" : "Later today",
"Set reminder for later today" : "Set reminder for later today",
"Tomorrow" : "Tomorrow",
"Set reminder for tomorrow" : "Set reminder for tomorrow",
"This weekend" : "This weekend",
"Set reminder for this weekend" : "Set reminder for this weekend",
"Next week" : "Next week",
"Set reminder for next week" : "Set reminder for next week",
"Back" : "Back",
"Reminder cleared" : "Reminder cleared",
"Failed to clear reminder" : "Failed to clear reminder",
"Failed to load reminder" : "Failed to load reminder"
},
"nplurals=2; plural=(n != 1);");
@@ -0,0 +1,29 @@
{ "translations": {
"File reminders" : "File reminders",
"Reminder for {name}" : "Reminder for {name}",
"View file" : "View file",
"View folder" : "View folder",
"Set file reminders" : "Set file reminders",
"**📣 File reminders**\n\nSet file reminders." : "**📣 File reminders**\n\nSet file reminders.",
"Please choose a valid date & time" : "Please choose a valid date & time",
"Cancel" : "Cancel",
"Set reminder" : "Set reminder",
"Set reminder at custom date & time" : "Set reminder at custom date & time",
"Clear reminder" : "Clear reminder",
"Reminder set for \"{fileName}\"" : "Reminder set for \"{fileName}\"",
"Failed to set reminder" : "Failed to set reminder",
"Set custom reminder" : "Set custom reminder",
"Later today" : "Later today",
"Set reminder for later today" : "Set reminder for later today",
"Tomorrow" : "Tomorrow",
"Set reminder for tomorrow" : "Set reminder for tomorrow",
"This weekend" : "This weekend",
"Set reminder for this weekend" : "Set reminder for this weekend",
"Next week" : "Next week",
"Set reminder for next week" : "Set reminder for next week",
"Back" : "Back",
"Reminder cleared" : "Reminder cleared",
"Failed to clear reminder" : "Failed to clear reminder",
"Failed to load reminder" : "Failed to load reminder"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}
@@ -0,0 +1,31 @@
OC.L10N.register(
"files_reminders",
{
"File reminders" : "Recordatorios de archivo",
"Reminder for {name}" : "Recordatorio para {name}",
"View file" : "Ver archivo",
"View folder" : "Ver carpeta",
"Set file reminders" : "Establecer recordatorios de archivo",
"**📣 File reminders**\n\nSet file reminders." : "**📣 Recordatorios de archivo**\n\nEstablecer recordatorios de archivo.",
"Please choose a valid date & time" : "Por favor, escoja una fecha y hora válidas",
"Cancel" : "Cancelar",
"Set reminder" : "Enviar recordatorio",
"Set reminder at custom date & time" : "Establecer recordatorio a una fecha y hora personalizada",
"Clear reminder" : "Borrar recordatorio",
"Reminder set for \"{fileName}\"" : "Se estableció recordatorio para \"{fileName}\"",
"Failed to set reminder" : "No se pudo configurar el recordatorio",
"Set custom reminder" : "Configurar recordatorio personalizado",
"Later today" : "Más tarde hoy",
"Set reminder for later today" : "Configurar recordatorio para hoy, más tarde",
"Tomorrow" : "Mañana",
"Set reminder for tomorrow" : "Configurar recordatorio para mañana",
"This weekend" : "Este fin de semana",
"Set reminder for this weekend" : "Configurar recordatorio para este fin de semana",
"Next week" : "Semana siguiente",
"Set reminder for next week" : "Configurar recordatorio para la semana que viene",
"Back" : "Volver",
"Reminder cleared" : "Se quitó el recordatorio",
"Failed to clear reminder" : "Fallo al quitar el recordatorio",
"Failed to load reminder" : "Fallo al cargar el recordatorio"
},
"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
@@ -0,0 +1,29 @@
{ "translations": {
"File reminders" : "Recordatorios de archivo",
"Reminder for {name}" : "Recordatorio para {name}",
"View file" : "Ver archivo",
"View folder" : "Ver carpeta",
"Set file reminders" : "Establecer recordatorios de archivo",
"**📣 File reminders**\n\nSet file reminders." : "**📣 Recordatorios de archivo**\n\nEstablecer recordatorios de archivo.",
"Please choose a valid date & time" : "Por favor, escoja una fecha y hora válidas",
"Cancel" : "Cancelar",
"Set reminder" : "Enviar recordatorio",
"Set reminder at custom date & time" : "Establecer recordatorio a una fecha y hora personalizada",
"Clear reminder" : "Borrar recordatorio",
"Reminder set for \"{fileName}\"" : "Se estableció recordatorio para \"{fileName}\"",
"Failed to set reminder" : "No se pudo configurar el recordatorio",
"Set custom reminder" : "Configurar recordatorio personalizado",
"Later today" : "Más tarde hoy",
"Set reminder for later today" : "Configurar recordatorio para hoy, más tarde",
"Tomorrow" : "Mañana",
"Set reminder for tomorrow" : "Configurar recordatorio para mañana",
"This weekend" : "Este fin de semana",
"Set reminder for this weekend" : "Configurar recordatorio para este fin de semana",
"Next week" : "Semana siguiente",
"Set reminder for next week" : "Configurar recordatorio para la semana que viene",
"Back" : "Volver",
"Reminder cleared" : "Se quitó el recordatorio",
"Failed to clear reminder" : "Fallo al quitar el recordatorio",
"Failed to load reminder" : "Fallo al cargar el recordatorio"
},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
}
@@ -0,0 +1,31 @@
OC.L10N.register(
"files_reminders",
{
"File reminders" : "Tiedostomuistutukset",
"Reminder for {name}" : "Muistutus kohteesta {name}",
"View file" : "Näytä tiedosto",
"View folder" : "Näytä kansio",
"Set file reminders" : "Aseta tiedostomuistutuksia",
"**📣 File reminders**\n\nSet file reminders." : "**📣 Tiedostomuistutukset**\n\nAseta tiedostomuistutuksia.",
"Please choose a valid date & time" : "Valitse kelvollinen päivä ja aika",
"Cancel" : "Peruuta",
"Set reminder" : "Aseta muistutus",
"Set reminder at custom date & time" : "Aseta muistutus mukautetulle päivälle ja ajankohdalle",
"Clear reminder" : "Tyhjennä muistutus",
"Reminder set for \"{fileName}\"" : "Muistutus asetettu tiedostolle \"{fileName}\"",
"Failed to set reminder" : "Muistutuksen asettaminen epäonnistui",
"Set custom reminder" : "Aseta mukautettu muistutus",
"Later today" : "Myöhemmin tänään",
"Set reminder for later today" : "Aseta muistutus myöhemmälle ajankohdalle tälle päivälle",
"Tomorrow" : "Huomenna",
"Set reminder for tomorrow" : "Aseta muistutus huomiselle",
"This weekend" : "Tämä viikonloppu",
"Set reminder for this weekend" : "Aseta muistutus tälle viikonlopulle",
"Next week" : "Seuraava viikko",
"Set reminder for next week" : "Aseta muistutus seuraavalle viikolle",
"Back" : "Takaisin",
"Reminder cleared" : "Muistutus tyhjennetty",
"Failed to clear reminder" : "Muistutuksen tyhjentäminen epäonnistui",
"Failed to load reminder" : "Muistutuksen lataaminen epäonnistui"
},
"nplurals=2; plural=(n != 1);");
@@ -0,0 +1,29 @@
{ "translations": {
"File reminders" : "Tiedostomuistutukset",
"Reminder for {name}" : "Muistutus kohteesta {name}",
"View file" : "Näytä tiedosto",
"View folder" : "Näytä kansio",
"Set file reminders" : "Aseta tiedostomuistutuksia",
"**📣 File reminders**\n\nSet file reminders." : "**📣 Tiedostomuistutukset**\n\nAseta tiedostomuistutuksia.",
"Please choose a valid date & time" : "Valitse kelvollinen päivä ja aika",
"Cancel" : "Peruuta",
"Set reminder" : "Aseta muistutus",
"Set reminder at custom date & time" : "Aseta muistutus mukautetulle päivälle ja ajankohdalle",
"Clear reminder" : "Tyhjennä muistutus",
"Reminder set for \"{fileName}\"" : "Muistutus asetettu tiedostolle \"{fileName}\"",
"Failed to set reminder" : "Muistutuksen asettaminen epäonnistui",
"Set custom reminder" : "Aseta mukautettu muistutus",
"Later today" : "Myöhemmin tänään",
"Set reminder for later today" : "Aseta muistutus myöhemmälle ajankohdalle tälle päivälle",
"Tomorrow" : "Huomenna",
"Set reminder for tomorrow" : "Aseta muistutus huomiselle",
"This weekend" : "Tämä viikonloppu",
"Set reminder for this weekend" : "Aseta muistutus tälle viikonlopulle",
"Next week" : "Seuraava viikko",
"Set reminder for next week" : "Aseta muistutus seuraavalle viikolle",
"Back" : "Takaisin",
"Reminder cleared" : "Muistutus tyhjennetty",
"Failed to clear reminder" : "Muistutuksen tyhjentäminen epäonnistui",
"Failed to load reminder" : "Muistutuksen lataaminen epäonnistui"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}
@@ -0,0 +1,31 @@
OC.L10N.register(
"files_reminders",
{
"File reminders" : "Rappels de fichiers",
"Reminder for {name}" : "Rappel pour {name}",
"View file" : "Voir le fichier",
"View folder" : "Voir le dossier",
"Set file reminders" : "Définir des rappels pour des fichiers",
"**📣 File reminders**\n\nSet file reminders." : "**📣 Rappels de fichiers**\n\nDéfinissez des rappels de fichiers.",
"Please choose a valid date & time" : "Veuillez choisir une date et une heure valables",
"Cancel" : "Annuler",
"Set reminder" : "Définir un rappel",
"Set reminder at custom date & time" : "Définition d'un rappel à une date et une heure personnalisées",
"Clear reminder" : "Effacer le rappel",
"Reminder set for \"{fileName}\"" : "Définition d'un rappel pour \"{fileName}\"",
"Failed to set reminder" : "Échec de la définition du rappel",
"Set custom reminder" : "Définir un rappel personnalisé",
"Later today" : "Plus tard aujourd'hui",
"Set reminder for later today" : "Définir un rappel pour plus tard aujourd'hui",
"Tomorrow" : "Demain",
"Set reminder for tomorrow" : "Définir un rappel pour demain",
"This weekend" : "Ce week-end",
"Set reminder for this weekend" : "Définir un rappel pour ce week-end",
"Next week" : "Semaine suivante",
"Set reminder for next week" : "Définir un rappel pour la semaine prochaine",
"Back" : "Retour",
"Reminder cleared" : "Rappel effacé",
"Failed to clear reminder" : "Échec de l'effacement du rappel",
"Failed to load reminder" : "Échec du chargement du rappel"
},
"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
@@ -0,0 +1,29 @@
{ "translations": {
"File reminders" : "Rappels de fichiers",
"Reminder for {name}" : "Rappel pour {name}",
"View file" : "Voir le fichier",
"View folder" : "Voir le dossier",
"Set file reminders" : "Définir des rappels pour des fichiers",
"**📣 File reminders**\n\nSet file reminders." : "**📣 Rappels de fichiers**\n\nDéfinissez des rappels de fichiers.",
"Please choose a valid date & time" : "Veuillez choisir une date et une heure valables",
"Cancel" : "Annuler",
"Set reminder" : "Définir un rappel",
"Set reminder at custom date & time" : "Définition d'un rappel à une date et une heure personnalisées",
"Clear reminder" : "Effacer le rappel",
"Reminder set for \"{fileName}\"" : "Définition d'un rappel pour \"{fileName}\"",
"Failed to set reminder" : "Échec de la définition du rappel",
"Set custom reminder" : "Définir un rappel personnalisé",
"Later today" : "Plus tard aujourd'hui",
"Set reminder for later today" : "Définir un rappel pour plus tard aujourd'hui",
"Tomorrow" : "Demain",
"Set reminder for tomorrow" : "Définir un rappel pour demain",
"This weekend" : "Ce week-end",
"Set reminder for this weekend" : "Définir un rappel pour ce week-end",
"Next week" : "Semaine suivante",
"Set reminder for next week" : "Définir un rappel pour la semaine prochaine",
"Back" : "Retour",
"Reminder cleared" : "Rappel effacé",
"Failed to clear reminder" : "Échec de l'effacement du rappel",
"Failed to load reminder" : "Échec du chargement du rappel"
},"pluralForm" :"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
}
@@ -0,0 +1,33 @@
OC.L10N.register(
"files_reminders",
{
"File reminders" : "Lembretes de ficheiros",
"Reminder for {name}" : "Lembrete para {name}",
"View file" : "Ver ficheiro",
"View folder" : "Ver cartafol",
"Set file reminders" : "Definir lembretes de ficheiros",
"**📣 File reminders**\n\nSet file reminders." : "**📣 Lembretes de ficheiros**\n\nDefinir lembretes de ficheiros.",
"We will remind you of this file" : "Lembrarémoslle este ficheiro",
"Please choose a valid date & time" : "Escolla unha data e hora válidas",
"Cancel" : "Cancelar",
"Set reminder" : "Definir un lembrete",
"Set reminder for \"{fileName}\"" : "Definir un lembrete para «{fileName}»",
"Set reminder at custom date & time" : "Definir lembrete na data e hora personalizadas",
"Clear reminder" : "Limpar o lembrete",
"Reminder set for \"{fileName}\"" : "Lembrete definido para «{fileName}»",
"Failed to set reminder" : "Produciuse un fallo ao definir o lembrete",
"Set custom reminder" : "Definir un lembrete personalizado",
"Later today" : "Hoxe máis tarde",
"Set reminder for later today" : "Definir un lembrete para hoxe máis tarde",
"Tomorrow" : "Mañá",
"Set reminder for tomorrow" : "Definir un lembrete para mañá",
"This weekend" : "Este fin de semana",
"Set reminder for this weekend" : "Definir un lembrete para este fin de semana",
"Next week" : "Semana seguinte",
"Set reminder for next week" : "Definir un lembrete para a semana seguinte",
"Back" : "Atras",
"Reminder cleared" : "Limpouse o lembrete",
"Failed to clear reminder" : "Produciuse un fallo ao limpar o lembrete",
"Failed to load reminder" : "Produciuse un fallo ao cargar o lembrete"
},
"nplurals=2; plural=(n != 1);");
@@ -0,0 +1,31 @@
{ "translations": {
"File reminders" : "Lembretes de ficheiros",
"Reminder for {name}" : "Lembrete para {name}",
"View file" : "Ver ficheiro",
"View folder" : "Ver cartafol",
"Set file reminders" : "Definir lembretes de ficheiros",
"**📣 File reminders**\n\nSet file reminders." : "**📣 Lembretes de ficheiros**\n\nDefinir lembretes de ficheiros.",
"We will remind you of this file" : "Lembrarémoslle este ficheiro",
"Please choose a valid date & time" : "Escolla unha data e hora válidas",
"Cancel" : "Cancelar",
"Set reminder" : "Definir un lembrete",
"Set reminder for \"{fileName}\"" : "Definir un lembrete para «{fileName}»",
"Set reminder at custom date & time" : "Definir lembrete na data e hora personalizadas",
"Clear reminder" : "Limpar o lembrete",
"Reminder set for \"{fileName}\"" : "Lembrete definido para «{fileName}»",
"Failed to set reminder" : "Produciuse un fallo ao definir o lembrete",
"Set custom reminder" : "Definir un lembrete personalizado",
"Later today" : "Hoxe máis tarde",
"Set reminder for later today" : "Definir un lembrete para hoxe máis tarde",
"Tomorrow" : "Mañá",
"Set reminder for tomorrow" : "Definir un lembrete para mañá",
"This weekend" : "Este fin de semana",
"Set reminder for this weekend" : "Definir un lembrete para este fin de semana",
"Next week" : "Semana seguinte",
"Set reminder for next week" : "Definir un lembrete para a semana seguinte",
"Back" : "Atras",
"Reminder cleared" : "Limpouse o lembrete",
"Failed to clear reminder" : "Produciuse un fallo ao limpar o lembrete",
"Failed to load reminder" : "Produciuse un fallo ao cargar o lembrete"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}
@@ -0,0 +1,31 @@
OC.L10N.register(
"files_reminders",
{
"File reminders" : "Fájl emlékeztetők",
"Reminder for {name}" : "Emlékeztető a következőhöz: {name}",
"View file" : "Fájl megtekintése",
"View folder" : "Mappa megtekintése",
"Set file reminders" : "Fájl emlékeztetők beállítása",
"**📣 File reminders**\n\nSet file reminders." : "**📣 Fájl emlékeztetők**\n\nFájl emlékeztetők beállítása.",
"Please choose a valid date & time" : "Adjon meg egy érvényes dátumot és időt",
"Cancel" : "Mégse",
"Set reminder" : "Emlékeztető beállítása",
"Set reminder at custom date & time" : "Emlékeztető beállítása tetszőleges időpontra",
"Clear reminder" : "Emlékeztető törlése",
"Reminder set for \"{fileName}\"" : "Emlékeztető beállítva a következőhöz: {name}",
"Failed to set reminder" : "Nem sikerült beállítani az emlékeztetőt",
"Set custom reminder" : "Egyéni emlékeztető beállítása",
"Later today" : "Mai nap később",
"Set reminder for later today" : "Emlékeztető beállítása a mai napon későbbre",
"Tomorrow" : "Holnap",
"Set reminder for tomorrow" : "Emlékeztető beállítása holnapra",
"This weekend" : "Ezen a héten",
"Set reminder for this weekend" : "Emlékeztető beállítása erre a hétvégére",
"Next week" : "Következő hét",
"Set reminder for next week" : "Emlékeztető beállítása a következő hétre",
"Back" : "Vissza",
"Reminder cleared" : "Emlékeztető törölve",
"Failed to clear reminder" : "Nem sikerült törölni az emlékeztetőt",
"Failed to load reminder" : "Nem sikerült betölteni az emlékeztetőt"
},
"nplurals=2; plural=(n != 1);");
@@ -0,0 +1,29 @@
{ "translations": {
"File reminders" : "Fájl emlékeztetők",
"Reminder for {name}" : "Emlékeztető a következőhöz: {name}",
"View file" : "Fájl megtekintése",
"View folder" : "Mappa megtekintése",
"Set file reminders" : "Fájl emlékeztetők beállítása",
"**📣 File reminders**\n\nSet file reminders." : "**📣 Fájl emlékeztetők**\n\nFájl emlékeztetők beállítása.",
"Please choose a valid date & time" : "Adjon meg egy érvényes dátumot és időt",
"Cancel" : "Mégse",
"Set reminder" : "Emlékeztető beállítása",
"Set reminder at custom date & time" : "Emlékeztető beállítása tetszőleges időpontra",
"Clear reminder" : "Emlékeztető törlése",
"Reminder set for \"{fileName}\"" : "Emlékeztető beállítva a következőhöz: {name}",
"Failed to set reminder" : "Nem sikerült beállítani az emlékeztetőt",
"Set custom reminder" : "Egyéni emlékeztető beállítása",
"Later today" : "Mai nap később",
"Set reminder for later today" : "Emlékeztető beállítása a mai napon későbbre",
"Tomorrow" : "Holnap",
"Set reminder for tomorrow" : "Emlékeztető beállítása holnapra",
"This weekend" : "Ezen a héten",
"Set reminder for this weekend" : "Emlékeztető beállítása erre a hétvégére",
"Next week" : "Következő hét",
"Set reminder for next week" : "Emlékeztető beállítása a következő hétre",
"Back" : "Vissza",
"Reminder cleared" : "Emlékeztető törölve",
"Failed to clear reminder" : "Nem sikerült törölni az emlékeztetőt",
"Failed to load reminder" : "Nem sikerült betölteni az emlékeztetőt"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}
@@ -0,0 +1,31 @@
OC.L10N.register(
"files_reminders",
{
"File reminders" : "Priminimai apie failus",
"Reminder for {name}" : "Priminimas apie {name}",
"View file" : "Rodyti failą",
"View folder" : "Rodyti aplanką",
"Set file reminders" : "Nustatyti priminimus apie failus",
"**📣 File reminders**\n\nSet file reminders." : "**📣 Priminimai apie failus**\n\nNustatyti priminimus apie failus.",
"Please choose a valid date & time" : "Pasirinkite tinkamą datą ir laiką",
"Cancel" : "Atsisakyti",
"Set reminder" : "Nustatyti priminimą",
"Set reminder at custom date & time" : "Nustatyti priminimą tinkintą datą ir laiką",
"Clear reminder" : "Panaikinti priminimą",
"Reminder set for \"{fileName}\"" : "Nustatytas priminimas apie „{fileName}“",
"Failed to set reminder" : "Nepavyko nustatyti priminimo",
"Set custom reminder" : "Nustatyti tinkintą priminimą",
"Later today" : "Šiandien vėliau",
"Set reminder for later today" : "Nustatyti priminimą šiandien vėliau",
"Tomorrow" : "Rytoj",
"Set reminder for tomorrow" : "Nustatyti priminimą rytoj",
"This weekend" : "Šį savaitgalį",
"Set reminder for this weekend" : "Nustatyti priminimą šį savaitgalį",
"Next week" : "Kitą savaitę",
"Set reminder for next week" : "Nustatyti priminimą kitą savaitę",
"Back" : "Atgal",
"Reminder cleared" : "Priminimas panaikintas",
"Failed to clear reminder" : "Nepavyko panaikinti priminimo",
"Failed to load reminder" : "Nepavyko įkelti priminimo"
},
"nplurals=4; plural=(n % 10 == 1 && (n % 100 > 19 || n % 100 < 11) ? 0 : (n % 10 >= 2 && n % 10 <=9) && (n % 100 > 19 || n % 100 < 11) ? 1 : n % 1 != 0 ? 2: 3);");
@@ -0,0 +1,29 @@
{ "translations": {
"File reminders" : "Priminimai apie failus",
"Reminder for {name}" : "Priminimas apie {name}",
"View file" : "Rodyti failą",
"View folder" : "Rodyti aplanką",
"Set file reminders" : "Nustatyti priminimus apie failus",
"**📣 File reminders**\n\nSet file reminders." : "**📣 Priminimai apie failus**\n\nNustatyti priminimus apie failus.",
"Please choose a valid date & time" : "Pasirinkite tinkamą datą ir laiką",
"Cancel" : "Atsisakyti",
"Set reminder" : "Nustatyti priminimą",
"Set reminder at custom date & time" : "Nustatyti priminimą tinkintą datą ir laiką",
"Clear reminder" : "Panaikinti priminimą",
"Reminder set for \"{fileName}\"" : "Nustatytas priminimas apie „{fileName}“",
"Failed to set reminder" : "Nepavyko nustatyti priminimo",
"Set custom reminder" : "Nustatyti tinkintą priminimą",
"Later today" : "Šiandien vėliau",
"Set reminder for later today" : "Nustatyti priminimą šiandien vėliau",
"Tomorrow" : "Rytoj",
"Set reminder for tomorrow" : "Nustatyti priminimą rytoj",
"This weekend" : "Šį savaitgalį",
"Set reminder for this weekend" : "Nustatyti priminimą šį savaitgalį",
"Next week" : "Kitą savaitę",
"Set reminder for next week" : "Nustatyti priminimą kitą savaitę",
"Back" : "Atgal",
"Reminder cleared" : "Priminimas panaikintas",
"Failed to clear reminder" : "Nepavyko panaikinti priminimo",
"Failed to load reminder" : "Nepavyko įkelti priminimo"
},"pluralForm" :"nplurals=4; plural=(n % 10 == 1 && (n % 100 > 19 || n % 100 < 11) ? 0 : (n % 10 >= 2 && n % 10 <=9) && (n % 100 > 19 || n % 100 < 11) ? 1 : n % 1 != 0 ? 2: 3);"
}
@@ -0,0 +1,31 @@
OC.L10N.register(
"files_reminders",
{
"File reminders" : "Потсетник на датотеки",
"Reminder for {name}" : "Потсетник за {name}",
"View file" : "Види датотека",
"View folder" : "Види папка",
"Set file reminders" : "Постави потсетник на датотека",
"**📣 File reminders**\n\nSet file reminders." : "**📣 Потсетник на датотеки**\n\nПостави потсетник на датотека.",
"Please choose a valid date & time" : "Внесете валиден датум & време",
"Cancel" : "Откажи",
"Set reminder" : "Постави потсетник",
"Set reminder at custom date & time" : "Постави потсетник на прилагоден датум & време",
"Clear reminder" : "Острани потсетник",
"Reminder set for \"{fileName}\"" : "Поставен потсетник за \"{fileName}\"",
"Failed to set reminder" : "Неуспешно поставување на потсетник",
"Set custom reminder" : "Постави прилагоден потсетник",
"Later today" : "Денес покасно",
"Set reminder for later today" : "Постави потсетник за денес покасно",
"Tomorrow" : "Утре",
"Set reminder for tomorrow" : "Постави потсетник за утре",
"This weekend" : "Овој викенд",
"Set reminder for this weekend" : "Постави потсетник за овој викенд",
"Next week" : "Следна недела",
"Set reminder for next week" : "Постави потсетник за наредната недела",
"Back" : "Назад",
"Reminder cleared" : "Потсетникот е остранет",
"Failed to clear reminder" : "Неуспешно остранување на потсетник",
"Failed to load reminder" : "Неуспешно вчитување на потсетник"
},
"nplurals=2; plural=(n % 10 == 1 && n % 100 != 11) ? 0 : 1;");
@@ -0,0 +1,29 @@
{ "translations": {
"File reminders" : "Потсетник на датотеки",
"Reminder for {name}" : "Потсетник за {name}",
"View file" : "Види датотека",
"View folder" : "Види папка",
"Set file reminders" : "Постави потсетник на датотека",
"**📣 File reminders**\n\nSet file reminders." : "**📣 Потсетник на датотеки**\n\nПостави потсетник на датотека.",
"Please choose a valid date & time" : "Внесете валиден датум & време",
"Cancel" : "Откажи",
"Set reminder" : "Постави потсетник",
"Set reminder at custom date & time" : "Постави потсетник на прилагоден датум & време",
"Clear reminder" : "Острани потсетник",
"Reminder set for \"{fileName}\"" : "Поставен потсетник за \"{fileName}\"",
"Failed to set reminder" : "Неуспешно поставување на потсетник",
"Set custom reminder" : "Постави прилагоден потсетник",
"Later today" : "Денес покасно",
"Set reminder for later today" : "Постави потсетник за денес покасно",
"Tomorrow" : "Утре",
"Set reminder for tomorrow" : "Постави потсетник за утре",
"This weekend" : "Овој викенд",
"Set reminder for this weekend" : "Постави потсетник за овој викенд",
"Next week" : "Следна недела",
"Set reminder for next week" : "Постави потсетник за наредната недела",
"Back" : "Назад",
"Reminder cleared" : "Потсетникот е остранет",
"Failed to clear reminder" : "Неуспешно остранување на потсетник",
"Failed to load reminder" : "Неуспешно вчитување на потсетник"
},"pluralForm" :"nplurals=2; plural=(n % 10 == 1 && n % 100 != 11) ? 0 : 1;"
}
@@ -0,0 +1,30 @@
OC.L10N.register(
"files_reminders",
{
"File reminders" : "Filpåminnelser",
"Reminder for {name}" : "Påminnelse for {name}",
"View file" : "Vis fil",
"View folder" : "Vis mappe",
"Set file reminders" : "Angi filpåminnelser",
"**📣 File reminders**\n\nSet file reminders." : "**📣 Filpåminnelser**\n\nAngi filpåminnelser.",
"Please choose a valid date & time" : "Vennligst velg en gyldig dato og tid",
"Cancel" : "Avbryt",
"Set reminder at custom date & time" : "Still inn påminnelse til egendefinert dato og klokkeslett",
"Clear reminder" : "Tydelig påminnelse",
"Reminder set for \"{fileName}\"" : "Påminnelse satt for «{fileName}»",
"Failed to set reminder" : "Kunne ikke angi påminnelse",
"Set custom reminder" : "Angi egendefinert påminnelse",
"Later today" : "Senere i dag",
"Set reminder for later today" : "Sett påminnelse til senere i dag",
"Tomorrow" : "I morgen",
"Set reminder for tomorrow" : "Sett påminnelse for i morgen",
"This weekend" : "Denne helgen",
"Set reminder for this weekend" : "Sett påminnelse for denne helgen",
"Next week" : "Neste uke",
"Set reminder for next week" : "Sett påminnelse for neste uke",
"Back" : "Tilbake",
"Reminder cleared" : "Påminnelsen slettet",
"Failed to clear reminder" : "Kunne ikke fjerne påminnelsen",
"Failed to load reminder" : "Kunne ikke laste inn påminnelsen"
},
"nplurals=2; plural=(n != 1);");
@@ -0,0 +1,28 @@
{ "translations": {
"File reminders" : "Filpåminnelser",
"Reminder for {name}" : "Påminnelse for {name}",
"View file" : "Vis fil",
"View folder" : "Vis mappe",
"Set file reminders" : "Angi filpåminnelser",
"**📣 File reminders**\n\nSet file reminders." : "**📣 Filpåminnelser**\n\nAngi filpåminnelser.",
"Please choose a valid date & time" : "Vennligst velg en gyldig dato og tid",
"Cancel" : "Avbryt",
"Set reminder at custom date & time" : "Still inn påminnelse til egendefinert dato og klokkeslett",
"Clear reminder" : "Tydelig påminnelse",
"Reminder set for \"{fileName}\"" : "Påminnelse satt for «{fileName}»",
"Failed to set reminder" : "Kunne ikke angi påminnelse",
"Set custom reminder" : "Angi egendefinert påminnelse",
"Later today" : "Senere i dag",
"Set reminder for later today" : "Sett påminnelse til senere i dag",
"Tomorrow" : "I morgen",
"Set reminder for tomorrow" : "Sett påminnelse for i morgen",
"This weekend" : "Denne helgen",
"Set reminder for this weekend" : "Sett påminnelse for denne helgen",
"Next week" : "Neste uke",
"Set reminder for next week" : "Sett påminnelse for neste uke",
"Back" : "Tilbake",
"Reminder cleared" : "Påminnelsen slettet",
"Failed to clear reminder" : "Kunne ikke fjerne påminnelsen",
"Failed to load reminder" : "Kunne ikke laste inn påminnelsen"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}
@@ -0,0 +1,33 @@
OC.L10N.register(
"files_reminders",
{
"File reminders" : "Przypomnienia o plikach",
"Reminder for {name}" : "Przypomnienie dla {name}",
"View file" : "Zobacz plik",
"View folder" : "Wyświetl katalog",
"Set file reminders" : "Ustaw przypomnienia o plikach",
"**📣 File reminders**\n\nSet file reminders." : "**📣 Przypomnienia o plikach**\n\nUstaw przypomnienia o plikach.",
"We will remind you of this file" : "Przypomnimy Tobie o tym pliku",
"Please choose a valid date & time" : "Wybierz prawidłową datę i godzinę",
"Cancel" : "Anuluj",
"Set reminder" : "Ustaw przypomnienie",
"Set reminder for \"{fileName}\"" : "Ustaw przypomnienie dla \"{fileName}\"",
"Set reminder at custom date & time" : "Ustaw przypomnienie o własnej dacie i godzinie",
"Clear reminder" : "Wyczyść przypomnienie",
"Reminder set for \"{fileName}\"" : "Przypomnienie ustawione dla \"{fileName}\"",
"Failed to set reminder" : "Nie udało się ustawić przypomnienia",
"Set custom reminder" : "Ustaw niestandardowe przypomnienie",
"Later today" : "Później dzisiaj",
"Set reminder for later today" : "Ustaw przypomnienie na dzisiaj na późniejszy czas",
"Tomorrow" : "Jutro",
"Set reminder for tomorrow" : "Ustaw przypomnienie na jutro",
"This weekend" : "W ten weekend",
"Set reminder for this weekend" : "Ustaw przypomnienie na ten weekend",
"Next week" : "Następny tydzień",
"Set reminder for next week" : "Ustaw przypomnienie na przyszły tydzień",
"Back" : "Poprzednia",
"Reminder cleared" : "Przypomnienie zostało usunięte",
"Failed to clear reminder" : "Nie udało się wyczyścić przypomnienia",
"Failed to load reminder" : "Nie udało się wczytać przypomnienia"
},
"nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);");
@@ -0,0 +1,31 @@
{ "translations": {
"File reminders" : "Przypomnienia o plikach",
"Reminder for {name}" : "Przypomnienie dla {name}",
"View file" : "Zobacz plik",
"View folder" : "Wyświetl katalog",
"Set file reminders" : "Ustaw przypomnienia o plikach",
"**📣 File reminders**\n\nSet file reminders." : "**📣 Przypomnienia o plikach**\n\nUstaw przypomnienia o plikach.",
"We will remind you of this file" : "Przypomnimy Tobie o tym pliku",
"Please choose a valid date & time" : "Wybierz prawidłową datę i godzinę",
"Cancel" : "Anuluj",
"Set reminder" : "Ustaw przypomnienie",
"Set reminder for \"{fileName}\"" : "Ustaw przypomnienie dla \"{fileName}\"",
"Set reminder at custom date & time" : "Ustaw przypomnienie o własnej dacie i godzinie",
"Clear reminder" : "Wyczyść przypomnienie",
"Reminder set for \"{fileName}\"" : "Przypomnienie ustawione dla \"{fileName}\"",
"Failed to set reminder" : "Nie udało się ustawić przypomnienia",
"Set custom reminder" : "Ustaw niestandardowe przypomnienie",
"Later today" : "Później dzisiaj",
"Set reminder for later today" : "Ustaw przypomnienie na dzisiaj na późniejszy czas",
"Tomorrow" : "Jutro",
"Set reminder for tomorrow" : "Ustaw przypomnienie na jutro",
"This weekend" : "W ten weekend",
"Set reminder for this weekend" : "Ustaw przypomnienie na ten weekend",
"Next week" : "Następny tydzień",
"Set reminder for next week" : "Ustaw przypomnienie na przyszły tydzień",
"Back" : "Poprzednia",
"Reminder cleared" : "Przypomnienie zostało usunięte",
"Failed to clear reminder" : "Nie udało się wyczyścić przypomnienia",
"Failed to load reminder" : "Nie udało się wczytać przypomnienia"
},"pluralForm" :"nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);"
}
@@ -0,0 +1,31 @@
OC.L10N.register(
"files_reminders",
{
"File reminders" : "Lembretes em arquivo.",
"Reminder for {name}" : "Lembrete para {name}",
"View file" : "Ver arquivo",
"View folder" : "Ver pasta",
"Set file reminders" : "Define lembrete em arquivo",
"**📣 File reminders**\n\nSet file reminders." : "**📣 Lembrete em Arquivo**\n\nDefine lembrete em arquivo.",
"Please choose a valid date & time" : "Por favor escolha uma data e hora válida.",
"Cancel" : "Cancelar",
"Set reminder" : "Definir lembrete",
"Set reminder at custom date & time" : "Define lembrete em data e hora customizada",
"Clear reminder" : "Limpar lembrete",
"Reminder set for \"{fileName}\"" : "Lembrete definido para \"{fileName}\"",
"Failed to set reminder" : "Falha ao definir lembrete",
"Set custom reminder" : "Definir lembrete personalizado",
"Later today" : "Hoje mais tarde",
"Set reminder for later today" : "Definir lembrete para hoje mais tarde",
"Tomorrow" : "Amanhã",
"Set reminder for tomorrow" : "Definir lembrete para amanhã",
"This weekend" : "Este fim de semana",
"Set reminder for this weekend" : "Definir lembrete para este fim de semana",
"Next week" : "Próxima semana",
"Set reminder for next week" : "Definir lembrete para a próxima semana",
"Back" : "Voltar",
"Reminder cleared" : "Lembrete limpo",
"Failed to clear reminder" : "Falha ao limpar lembrete",
"Failed to load reminder" : "Falha ao carregar lembrete"
},
"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
@@ -0,0 +1,29 @@
{ "translations": {
"File reminders" : "Lembretes em arquivo.",
"Reminder for {name}" : "Lembrete para {name}",
"View file" : "Ver arquivo",
"View folder" : "Ver pasta",
"Set file reminders" : "Define lembrete em arquivo",
"**📣 File reminders**\n\nSet file reminders." : "**📣 Lembrete em Arquivo**\n\nDefine lembrete em arquivo.",
"Please choose a valid date & time" : "Por favor escolha uma data e hora válida.",
"Cancel" : "Cancelar",
"Set reminder" : "Definir lembrete",
"Set reminder at custom date & time" : "Define lembrete em data e hora customizada",
"Clear reminder" : "Limpar lembrete",
"Reminder set for \"{fileName}\"" : "Lembrete definido para \"{fileName}\"",
"Failed to set reminder" : "Falha ao definir lembrete",
"Set custom reminder" : "Definir lembrete personalizado",
"Later today" : "Hoje mais tarde",
"Set reminder for later today" : "Definir lembrete para hoje mais tarde",
"Tomorrow" : "Amanhã",
"Set reminder for tomorrow" : "Definir lembrete para amanhã",
"This weekend" : "Este fim de semana",
"Set reminder for this weekend" : "Definir lembrete para este fim de semana",
"Next week" : "Próxima semana",
"Set reminder for next week" : "Definir lembrete para a próxima semana",
"Back" : "Voltar",
"Reminder cleared" : "Lembrete limpo",
"Failed to clear reminder" : "Falha ao limpar lembrete",
"Failed to load reminder" : "Falha ao carregar lembrete"
},"pluralForm" :"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
}
@@ -0,0 +1,31 @@
OC.L10N.register(
"files_reminders",
{
"File reminders" : "Напоминания о файлах",
"Reminder for {name}" : "Напоминание для {name}",
"View file" : "Просмотреть файл",
"View folder" : "Просмотреть папку",
"Set file reminders" : "Установить напоминания о файлах",
"**📣 File reminders**\n\nSet file reminders." : "**📣 Напоминания о файлах**\n\nУстановить напоминания о файлах.",
"Please choose a valid date & time" : "Пожалуйста, выберите правильную дату и время",
"Cancel" : "Отмена",
"Set reminder" : "Установить напоминание",
"Set reminder at custom date & time" : "Установить напоминание на индивидуальную дату и время",
"Clear reminder" : "Очистить напоминание",
"Reminder set for \"{fileName}\"" : "Напоминание для \"{fileName}\"",
"Failed to set reminder" : "Не удалось установить напоминание",
"Set custom reminder" : "Установить особое напоминание",
"Later today" : "Позже сегодня",
"Set reminder for later today" : "Установить напоминание позднее сегодня",
"Tomorrow" : "Завтра",
"Set reminder for tomorrow" : "Установить напоминание на завтра",
"This weekend" : "Эта неделя",
"Set reminder for this weekend" : "Установить напоминание на эти выходные",
"Next week" : "Следующая неделя",
"Set reminder for next week" : "Установить напоминание на следующую неделю",
"Back" : "Назад",
"Reminder cleared" : "Напоминание удалено",
"Failed to clear reminder" : "Не удалось удалить напоминание",
"Failed to load reminder" : "Не удалось загрузить напоминание"
},
"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);");
@@ -0,0 +1,29 @@
{ "translations": {
"File reminders" : "Напоминания о файлах",
"Reminder for {name}" : "Напоминание для {name}",
"View file" : "Просмотреть файл",
"View folder" : "Просмотреть папку",
"Set file reminders" : "Установить напоминания о файлах",
"**📣 File reminders**\n\nSet file reminders." : "**📣 Напоминания о файлах**\n\nУстановить напоминания о файлах.",
"Please choose a valid date & time" : "Пожалуйста, выберите правильную дату и время",
"Cancel" : "Отмена",
"Set reminder" : "Установить напоминание",
"Set reminder at custom date & time" : "Установить напоминание на индивидуальную дату и время",
"Clear reminder" : "Очистить напоминание",
"Reminder set for \"{fileName}\"" : "Напоминание для \"{fileName}\"",
"Failed to set reminder" : "Не удалось установить напоминание",
"Set custom reminder" : "Установить особое напоминание",
"Later today" : "Позже сегодня",
"Set reminder for later today" : "Установить напоминание позднее сегодня",
"Tomorrow" : "Завтра",
"Set reminder for tomorrow" : "Установить напоминание на завтра",
"This weekend" : "Эта неделя",
"Set reminder for this weekend" : "Установить напоминание на эти выходные",
"Next week" : "Следующая неделя",
"Set reminder for next week" : "Установить напоминание на следующую неделю",
"Back" : "Назад",
"Reminder cleared" : "Напоминание удалено",
"Failed to clear reminder" : "Не удалось удалить напоминание",
"Failed to load reminder" : "Не удалось загрузить напоминание"
},"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);"
}
@@ -0,0 +1,33 @@
OC.L10N.register(
"files_reminders",
{
"File reminders" : "Подсетници о фајлу",
"Reminder for {name}" : "Подсетник за {name}",
"View file" : "Погледај фајл",
"View folder" : "Погледај фолдер",
"Set file reminders" : "Постави подсетнике о фајлу",
"**📣 File reminders**\n\nSet file reminders." : "**📣 Подсетници о фајлу**\n\nПостављање подсетника о фајлу.",
"We will remind you of this file" : "Подсетићемо вас на овај фајл",
"Please choose a valid date & time" : "Молимо вас да изаберете исправни датум и време",
"Cancel" : "Откажи",
"Set reminder" : "Постави подсетник",
"Set reminder for \"{fileName}\"" : "Постави подсетник за „{fileName}”",
"Set reminder at custom date & time" : "Постави подсетник за произвољни датум и време",
"Clear reminder" : "Обриши подсетник",
"Reminder set for \"{fileName}\"" : "Подсетник је постављен за „{fileName}”",
"Failed to set reminder" : "Није успело постављање подсетника",
"Set custom reminder" : "Постави произвољни подсетник",
"Later today" : "Касније данас",
"Set reminder for later today" : "Поставља подсетник за касније данас",
"Tomorrow" : "Сутра",
"Set reminder for tomorrow" : "Поставља подсетник за сутра",
"This weekend" : "Овог викенда",
"Set reminder for this weekend" : "Поставља подсетник за овај викенд",
"Next week" : "Наредне недеље",
"Set reminder for next week" : "Поставља подсетник за наредну недељу",
"Back" : "Назад",
"Reminder cleared" : "Подсетник је обрисан",
"Failed to clear reminder" : "Није успело брисање подсетника",
"Failed to load reminder" : "Није успело учитавање подсетника"
},
"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);");
@@ -0,0 +1,31 @@
{ "translations": {
"File reminders" : "Подсетници о фајлу",
"Reminder for {name}" : "Подсетник за {name}",
"View file" : "Погледај фајл",
"View folder" : "Погледај фолдер",
"Set file reminders" : "Постави подсетнике о фајлу",
"**📣 File reminders**\n\nSet file reminders." : "**📣 Подсетници о фајлу**\n\nПостављање подсетника о фајлу.",
"We will remind you of this file" : "Подсетићемо вас на овај фајл",
"Please choose a valid date & time" : "Молимо вас да изаберете исправни датум и време",
"Cancel" : "Откажи",
"Set reminder" : "Постави подсетник",
"Set reminder for \"{fileName}\"" : "Постави подсетник за „{fileName}”",
"Set reminder at custom date & time" : "Постави подсетник за произвољни датум и време",
"Clear reminder" : "Обриши подсетник",
"Reminder set for \"{fileName}\"" : "Подсетник је постављен за „{fileName}”",
"Failed to set reminder" : "Није успело постављање подсетника",
"Set custom reminder" : "Постави произвољни подсетник",
"Later today" : "Касније данас",
"Set reminder for later today" : "Поставља подсетник за касније данас",
"Tomorrow" : "Сутра",
"Set reminder for tomorrow" : "Поставља подсетник за сутра",
"This weekend" : "Овог викенда",
"Set reminder for this weekend" : "Поставља подсетник за овај викенд",
"Next week" : "Наредне недеље",
"Set reminder for next week" : "Поставља подсетник за наредну недељу",
"Back" : "Назад",
"Reminder cleared" : "Подсетник је обрисан",
"Failed to clear reminder" : "Није успело брисање подсетника",
"Failed to load reminder" : "Није успело учитавање подсетника"
},"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"
}
@@ -0,0 +1,33 @@
OC.L10N.register(
"files_reminders",
{
"File reminders" : "Filpåminnelser",
"Reminder for {name}" : "Påminnelse för {name}",
"View file" : "Visa fil",
"View folder" : "Visa mapp",
"Set file reminders" : "Ställ in filpåminnelser",
"**📣 File reminders**\n\nSet file reminders." : "**📣 Filpåminnelser**\n\nStäll in filpåminnelser.",
"We will remind you of this file" : "Vi kommer att påminna dig om denna fil",
"Please choose a valid date & time" : "Välj ett giltigt datum och tid",
"Cancel" : "Avbryt",
"Set reminder" : "Ställ in påminnelse",
"Set reminder for \"{fileName}\"" : "Ställ in påminnelse för \"{fileName}\"",
"Set reminder at custom date & time" : "Ställ in påminnelse vid anpassat datum och tid",
"Clear reminder" : "Rensa påminnelse",
"Reminder set for \"{fileName}\"" : "Påminnelse inställd för \"{fileName}\"",
"Failed to set reminder" : "Kunde inte ställa in påminnelsen",
"Set custom reminder" : "Ställ in anpassad påminnelse",
"Later today" : "Senare idag",
"Set reminder for later today" : "Ställ in påminnelse för senare idag",
"Tomorrow" : "I morgon",
"Set reminder for tomorrow" : "Ställ in påminnelse för imorgon",
"This weekend" : "Denna helgen",
"Set reminder for this weekend" : "Ställ in påminnelse för denna helg",
"Next week" : "Nästa vecka",
"Set reminder for next week" : "Ställ in påminnelse för nästa vecka",
"Back" : "Tillbaka",
"Reminder cleared" : "Påminnelsen rensad",
"Failed to clear reminder" : "Kunde inte rensa påminnelsen",
"Failed to load reminder" : "Kunde inte läsa in påminnelsen"
},
"nplurals=2; plural=(n != 1);");
@@ -0,0 +1,31 @@
{ "translations": {
"File reminders" : "Filpåminnelser",
"Reminder for {name}" : "Påminnelse för {name}",
"View file" : "Visa fil",
"View folder" : "Visa mapp",
"Set file reminders" : "Ställ in filpåminnelser",
"**📣 File reminders**\n\nSet file reminders." : "**📣 Filpåminnelser**\n\nStäll in filpåminnelser.",
"We will remind you of this file" : "Vi kommer att påminna dig om denna fil",
"Please choose a valid date & time" : "Välj ett giltigt datum och tid",
"Cancel" : "Avbryt",
"Set reminder" : "Ställ in påminnelse",
"Set reminder for \"{fileName}\"" : "Ställ in påminnelse för \"{fileName}\"",
"Set reminder at custom date & time" : "Ställ in påminnelse vid anpassat datum och tid",
"Clear reminder" : "Rensa påminnelse",
"Reminder set for \"{fileName}\"" : "Påminnelse inställd för \"{fileName}\"",
"Failed to set reminder" : "Kunde inte ställa in påminnelsen",
"Set custom reminder" : "Ställ in anpassad påminnelse",
"Later today" : "Senare idag",
"Set reminder for later today" : "Ställ in påminnelse för senare idag",
"Tomorrow" : "I morgon",
"Set reminder for tomorrow" : "Ställ in påminnelse för imorgon",
"This weekend" : "Denna helgen",
"Set reminder for this weekend" : "Ställ in påminnelse för denna helg",
"Next week" : "Nästa vecka",
"Set reminder for next week" : "Ställ in påminnelse för nästa vecka",
"Back" : "Tillbaka",
"Reminder cleared" : "Påminnelsen rensad",
"Failed to clear reminder" : "Kunde inte rensa påminnelsen",
"Failed to load reminder" : "Kunde inte läsa in påminnelsen"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}
@@ -0,0 +1,33 @@
OC.L10N.register(
"files_reminders",
{
"File reminders" : "Dosya anımsatıcıları",
"Reminder for {name}" : "{name} anımsatıcısı",
"View file" : "Dosyayı görüntüle",
"View folder" : "Klasörü görüntüle",
"Set file reminders" : "Dosya anımsatıcıları ayarla",
"**📣 File reminders**\n\nSet file reminders." : "**📣 Dosya anımsatıcıları**\n\nDosya anımsatıcıları ayarla.",
"We will remind you of this file" : "Size bu dosyayı anımsatacağız",
"Please choose a valid date & time" : "Lütfen geçerli bir tarih ve saat seçin",
"Cancel" : "İptal",
"Set reminder" : "Anımsatıcı ayarla",
"Set reminder for \"{fileName}\"" : "\"{fileName}\" için anımsatıcı ayarla",
"Set reminder at custom date & time" : "Özel bir tarih ve saat için anımsatıcı ayarla",
"Clear reminder" : "Anımsatıcıyı temizle",
"Reminder set for \"{fileName}\"" : "\"{fileName}\" için anımsatıcı ayarlandı",
"Failed to set reminder" : "Anımsatıcı ayarlanamadı",
"Set custom reminder" : "Özel anımsatıcı ayarla",
"Later today" : "Bugün daha sonra",
"Set reminder for later today" : "Bugün daha sonrası için anımsatıcı ayarla",
"Tomorrow" : "Yarın",
"Set reminder for tomorrow" : "Yarın için anımsatıcı ayarla",
"This weekend" : "Bu hafta sonu",
"Set reminder for this weekend" : "Bu hafta sonu için anımsatıcı ayarla",
"Next week" : "Sonraki hafta",
"Set reminder for next week" : "Gelecek hafta için anımsatıcı ayarla",
"Back" : "Geri",
"Reminder cleared" : "Anımsatıcı temizlendi",
"Failed to clear reminder" : "Anımsatıcı temizlenemedi",
"Failed to load reminder" : "Anımsatıcı yüklenemedi"
},
"nplurals=2; plural=(n > 1);");
@@ -0,0 +1,31 @@
{ "translations": {
"File reminders" : "Dosya anımsatıcıları",
"Reminder for {name}" : "{name} anımsatıcısı",
"View file" : "Dosyayı görüntüle",
"View folder" : "Klasörü görüntüle",
"Set file reminders" : "Dosya anımsatıcıları ayarla",
"**📣 File reminders**\n\nSet file reminders." : "**📣 Dosya anımsatıcıları**\n\nDosya anımsatıcıları ayarla.",
"We will remind you of this file" : "Size bu dosyayı anımsatacağız",
"Please choose a valid date & time" : "Lütfen geçerli bir tarih ve saat seçin",
"Cancel" : "İptal",
"Set reminder" : "Anımsatıcı ayarla",
"Set reminder for \"{fileName}\"" : "\"{fileName}\" için anımsatıcı ayarla",
"Set reminder at custom date & time" : "Özel bir tarih ve saat için anımsatıcı ayarla",
"Clear reminder" : "Anımsatıcıyı temizle",
"Reminder set for \"{fileName}\"" : "\"{fileName}\" için anımsatıcı ayarlandı",
"Failed to set reminder" : "Anımsatıcı ayarlanamadı",
"Set custom reminder" : "Özel anımsatıcı ayarla",
"Later today" : "Bugün daha sonra",
"Set reminder for later today" : "Bugün daha sonrası için anımsatıcı ayarla",
"Tomorrow" : "Yarın",
"Set reminder for tomorrow" : "Yarın için anımsatıcı ayarla",
"This weekend" : "Bu hafta sonu",
"Set reminder for this weekend" : "Bu hafta sonu için anımsatıcı ayarla",
"Next week" : "Sonraki hafta",
"Set reminder for next week" : "Gelecek hafta için anımsatıcı ayarla",
"Back" : "Geri",
"Reminder cleared" : "Anımsatıcı temizlendi",
"Failed to clear reminder" : "Anımsatıcı temizlenemedi",
"Failed to load reminder" : "Anımsatıcı yüklenemedi"
},"pluralForm" :"nplurals=2; plural=(n > 1);"
}
@@ -0,0 +1,33 @@
OC.L10N.register(
"files_reminders",
{
"File reminders" : "Нагадування для файлів",
"Reminder for {name}" : "Нагадування для {name}",
"View file" : "Переглянути файл",
"View folder" : "Переглянути каталог",
"Set file reminders" : "Встановити нагадування для файлу",
"**📣 File reminders**\n\nSet file reminders." : "**📣 Нагадування для файлів**\n\nВстановити нагадування для файлу.",
"We will remind you of this file" : "Ми нагадаємо вам про цей файл.",
"Please choose a valid date & time" : "Виберіть дійсні дату та час",
"Cancel" : "Відміна",
"Set reminder" : "Встановити нагадування",
"Set reminder for \"{fileName}\"" : "Встановити нагадування для \"{fileName}\"",
"Set reminder at custom date & time" : "Встановити нагадування на власну дату та час",
"Clear reminder" : "Зняти нагадування",
"Reminder set for \"{fileName}\"" : "Встановлено нагадування для \"{fileName}\"",
"Failed to set reminder" : "Не вдалося встановити нагадування",
"Set custom reminder" : "Встановити власне нагадування",
"Later today" : "Пізніше сьогодні",
"Set reminder for later today" : "Встановити нагадування на сьогодні пізніше",
"Tomorrow" : "Завтра",
"Set reminder for tomorrow" : "Встановити нагадування на завтра",
"This weekend" : "Цими вихідними",
"Set reminder for this weekend" : "Встановити нагадування на ці вихідні",
"Next week" : "Наступний тиждень",
"Set reminder for next week" : "Встановити нагадування на наступний тиждень",
"Back" : "Назад",
"Reminder cleared" : "Нагадування знято",
"Failed to clear reminder" : "Не вдалося зняти нагадування",
"Failed to load reminder" : "Не вдалося отримати нагадування"
},
"nplurals=4; plural=(n % 1 == 0 && n % 10 == 1 && n % 100 != 11 ? 0 : n % 1 == 0 && n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14) ? 1 : n % 1 == 0 && (n % 10 ==0 || (n % 10 >=5 && n % 10 <=9) || (n % 100 >=11 && n % 100 <=14 )) ? 2: 3);");
@@ -0,0 +1,31 @@
{ "translations": {
"File reminders" : "Нагадування для файлів",
"Reminder for {name}" : "Нагадування для {name}",
"View file" : "Переглянути файл",
"View folder" : "Переглянути каталог",
"Set file reminders" : "Встановити нагадування для файлу",
"**📣 File reminders**\n\nSet file reminders." : "**📣 Нагадування для файлів**\n\nВстановити нагадування для файлу.",
"We will remind you of this file" : "Ми нагадаємо вам про цей файл.",
"Please choose a valid date & time" : "Виберіть дійсні дату та час",
"Cancel" : "Відміна",
"Set reminder" : "Встановити нагадування",
"Set reminder for \"{fileName}\"" : "Встановити нагадування для \"{fileName}\"",
"Set reminder at custom date & time" : "Встановити нагадування на власну дату та час",
"Clear reminder" : "Зняти нагадування",
"Reminder set for \"{fileName}\"" : "Встановлено нагадування для \"{fileName}\"",
"Failed to set reminder" : "Не вдалося встановити нагадування",
"Set custom reminder" : "Встановити власне нагадування",
"Later today" : "Пізніше сьогодні",
"Set reminder for later today" : "Встановити нагадування на сьогодні пізніше",
"Tomorrow" : "Завтра",
"Set reminder for tomorrow" : "Встановити нагадування на завтра",
"This weekend" : "Цими вихідними",
"Set reminder for this weekend" : "Встановити нагадування на ці вихідні",
"Next week" : "Наступний тиждень",
"Set reminder for next week" : "Встановити нагадування на наступний тиждень",
"Back" : "Назад",
"Reminder cleared" : "Нагадування знято",
"Failed to clear reminder" : "Не вдалося зняти нагадування",
"Failed to load reminder" : "Не вдалося отримати нагадування"
},"pluralForm" :"nplurals=4; plural=(n % 1 == 0 && n % 10 == 1 && n % 100 != 11 ? 0 : n % 1 == 0 && n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14) ? 1 : n % 1 == 0 && (n % 10 ==0 || (n % 10 >=5 && n % 10 <=9) || (n % 100 >=11 && n % 100 <=14 )) ? 2: 3);"
}
@@ -0,0 +1,31 @@
OC.L10N.register(
"files_reminders",
{
"File reminders" : "檔案提醒",
"Reminder for {name}" : "{name} 的提醒",
"View file" : "檢視檔案",
"View folder" : "檢視資料夾",
"Set file reminders" : "設定檔案提醒",
"**📣 File reminders**\n\nSet file reminders." : "**📣 檔案提醒**\n\n設定檔案提醒。",
"Please choose a valid date & time" : "請選擇有效的日期與時間",
"Cancel" : "取消",
"Set reminder" : "設定提醒",
"Set reminder at custom date & time" : "設定自訂日期與時間的提醒",
"Clear reminder" : "清除提醒",
"Reminder set for \"{fileName}\"" : "「{fileName}」的提醒設定",
"Failed to set reminder" : "設定提醒失敗",
"Set custom reminder" : "設定自訂提醒",
"Later today" : "今日稍後",
"Set reminder for later today" : "設定今天稍後的提醒",
"Tomorrow" : "明日",
"Set reminder for tomorrow" : "設定明天的提醒",
"This weekend" : "本週末",
"Set reminder for this weekend" : "設定本週末的提醒",
"Next week" : "下星期",
"Set reminder for next week" : "設定下星期的提醒",
"Back" : "上星期",
"Reminder cleared" : "提醒已清除",
"Failed to clear reminder" : "清除提醒失敗",
"Failed to load reminder" : "載入提醒失敗"
},
"nplurals=1; plural=0;");
@@ -0,0 +1,29 @@
{ "translations": {
"File reminders" : "檔案提醒",
"Reminder for {name}" : "{name} 的提醒",
"View file" : "檢視檔案",
"View folder" : "檢視資料夾",
"Set file reminders" : "設定檔案提醒",
"**📣 File reminders**\n\nSet file reminders." : "**📣 檔案提醒**\n\n設定檔案提醒。",
"Please choose a valid date & time" : "請選擇有效的日期與時間",
"Cancel" : "取消",
"Set reminder" : "設定提醒",
"Set reminder at custom date & time" : "設定自訂日期與時間的提醒",
"Clear reminder" : "清除提醒",
"Reminder set for \"{fileName}\"" : "「{fileName}」的提醒設定",
"Failed to set reminder" : "設定提醒失敗",
"Set custom reminder" : "設定自訂提醒",
"Later today" : "今日稍後",
"Set reminder for later today" : "設定今天稍後的提醒",
"Tomorrow" : "明日",
"Set reminder for tomorrow" : "設定明天的提醒",
"This weekend" : "本週末",
"Set reminder for this weekend" : "設定本週末的提醒",
"Next week" : "下星期",
"Set reminder for next week" : "設定下星期的提醒",
"Back" : "上星期",
"Reminder cleared" : "提醒已清除",
"Failed to clear reminder" : "清除提醒失敗",
"Failed to load reminder" : "載入提醒失敗"
},"pluralForm" :"nplurals=1; plural=0;"
}
@@ -0,0 +1,33 @@
OC.L10N.register(
"files_reminders",
{
"File reminders" : "檔案提醒",
"Reminder for {name}" : "{name} 的提醒",
"View file" : "檢視檔案",
"View folder" : "檢視資料夾",
"Set file reminders" : "設定檔案提醒",
"**📣 File reminders**\n\nSet file reminders." : "**📣 檔案提醒**\n\n設定檔案提醒。",
"We will remind you of this file" : "我們會提醒您該檔案",
"Please choose a valid date & time" : "請選擇有效的日期與時間",
"Cancel" : "取消",
"Set reminder" : "設定提醒",
"Set reminder for \"{fileName}\"" : "設定「{fileName}」的提醒",
"Set reminder at custom date & time" : "設定自訂日期與時間的提醒",
"Clear reminder" : "清除提醒",
"Reminder set for \"{fileName}\"" : "「{fileName}」的提醒設定",
"Failed to set reminder" : "設定提醒失敗",
"Set custom reminder" : "設定自訂提醒",
"Later today" : "今天稍後",
"Set reminder for later today" : "設定今天稍後的提醒",
"Tomorrow" : "明天",
"Set reminder for tomorrow" : "設定明天的提醒",
"This weekend" : "本週末",
"Set reminder for this weekend" : "設定本週末的提醒",
"Next week" : "下週",
"Set reminder for next week" : "設定下週的提醒",
"Back" : "返回",
"Reminder cleared" : "提醒已清除",
"Failed to clear reminder" : "清除提醒失敗",
"Failed to load reminder" : "載入提醒失敗"
},
"nplurals=1; plural=0;");
@@ -0,0 +1,31 @@
{ "translations": {
"File reminders" : "檔案提醒",
"Reminder for {name}" : "{name} 的提醒",
"View file" : "檢視檔案",
"View folder" : "檢視資料夾",
"Set file reminders" : "設定檔案提醒",
"**📣 File reminders**\n\nSet file reminders." : "**📣 檔案提醒**\n\n設定檔案提醒。",
"We will remind you of this file" : "我們會提醒您該檔案",
"Please choose a valid date & time" : "請選擇有效的日期與時間",
"Cancel" : "取消",
"Set reminder" : "設定提醒",
"Set reminder for \"{fileName}\"" : "設定「{fileName}」的提醒",
"Set reminder at custom date & time" : "設定自訂日期與時間的提醒",
"Clear reminder" : "清除提醒",
"Reminder set for \"{fileName}\"" : "「{fileName}」的提醒設定",
"Failed to set reminder" : "設定提醒失敗",
"Set custom reminder" : "設定自訂提醒",
"Later today" : "今天稍後",
"Set reminder for later today" : "設定今天稍後的提醒",
"Tomorrow" : "明天",
"Set reminder for tomorrow" : "設定明天的提醒",
"This weekend" : "本週末",
"Set reminder for this weekend" : "設定本週末的提醒",
"Next week" : "下週",
"Set reminder for next week" : "設定下週的提醒",
"Back" : "返回",
"Reminder cleared" : "提醒已清除",
"Failed to clear reminder" : "清除提醒失敗",
"Failed to load reminder" : "載入提醒失敗"
},"pluralForm" :"nplurals=1; plural=0;"
}
@@ -0,0 +1,59 @@
<?php
declare(strict_types=1);
/**
* @copyright 2023 Christopher Ng <chrng8@gmail.com>
*
* @author Christopher Ng <chrng8@gmail.com>
*
* @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\FilesReminders\AppInfo;
use OCA\Files\Event\LoadAdditionalScriptsEvent;
use OCA\FilesReminders\Listener\LoadAdditionalScriptsListener;
use OCA\FilesReminders\Listener\NodeDeletedListener;
use OCA\FilesReminders\Listener\UserDeletedListener;
use OCA\FilesReminders\Notification\Notifier;
use OCP\AppFramework\App;
use OCP\AppFramework\Bootstrap\IBootContext;
use OCP\AppFramework\Bootstrap\IBootstrap;
use OCP\AppFramework\Bootstrap\IRegistrationContext;
use OCP\Files\Events\Node\NodeDeletedEvent;
use OCP\User\Events\UserDeletedEvent;
class Application extends App implements IBootstrap {
public const APP_ID = 'files_reminders';
public function __construct() {
parent::__construct(static::APP_ID);
}
public function boot(IBootContext $context): void {
}
public function register(IRegistrationContext $context): void {
$context->registerNotifierService(Notifier::class);
$context->registerEventListener(NodeDeletedEvent::class, NodeDeletedListener::class);
$context->registerEventListener(UserDeletedEvent::class, UserDeletedListener::class);
$context->registerEventListener(LoadAdditionalScriptsEvent::class, LoadAdditionalScriptsListener::class);
}
}
@@ -0,0 +1,51 @@
<?php
declare(strict_types=1);
/**
* @copyright 2023 Christopher Ng <chrng8@gmail.com>
*
* @author Christopher Ng <chrng8@gmail.com>
*
* @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\FilesReminders\BackgroundJob;
use OCA\FilesReminders\Service\ReminderService;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\BackgroundJob\IJob;
use OCP\BackgroundJob\TimedJob;
class CleanUpReminders extends TimedJob {
public function __construct(
ITimeFactory $time,
private ReminderService $reminderService,
) {
parent::__construct($time);
$this->setInterval(24 * 60 * 60); // 1 day
$this->setTimeSensitivity(IJob::TIME_INSENSITIVE);
}
/**
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
protected function run($argument) {
$this->reminderService->cleanUp(500);
}
}
@@ -0,0 +1,59 @@
<?php
declare(strict_types=1);
/**
* @copyright 2023 Christopher Ng <chrng8@gmail.com>
*
* @author Christopher Ng <chrng8@gmail.com>
*
* @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\FilesReminders\BackgroundJob;
use OCA\FilesReminders\Db\ReminderMapper;
use OCA\FilesReminders\Service\ReminderService;
use OCP\AppFramework\Db\DoesNotExistException;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\BackgroundJob\Job;
use Psr\Log\LoggerInterface;
class ScheduledNotifications extends Job {
public function __construct(
ITimeFactory $time,
protected ReminderMapper $reminderMapper,
protected ReminderService $reminderService,
protected LoggerInterface $logger,
) {
parent::__construct($time);
}
/**
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function run($argument) {
$reminders = $this->reminderMapper->findOverdue();
foreach ($reminders as $reminder) {
try {
$this->reminderService->send($reminder);
} catch (DoesNotExistException $e) {
$this->logger->debug('Could not send notification for reminder with id ' . $reminder->getId());
}
}
}
}
@@ -0,0 +1,119 @@
<?php
declare(strict_types=1);
/**
* @copyright 2023 Christopher Ng <chrng8@gmail.com>
*
* @author Christopher Ng <chrng8@gmail.com>
*
* @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\FilesReminders\Command;
use DateTimeInterface;
use OC\Core\Command\Base;
use OCA\FilesReminders\Model\RichReminder;
use OCA\FilesReminders\Service\ReminderService;
use OCP\IUserManager;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
class ListCommand extends Base {
public function __construct(
private ReminderService $reminderService,
private IUserManager $userManager,
) {
parent::__construct();
}
protected function configure(): void {
$this
->setName('files:reminders')
->setDescription('List file reminders')
->addArgument(
'user',
InputArgument::OPTIONAL,
'list reminders for user',
)
->addOption(
'output',
null,
InputOption::VALUE_OPTIONAL,
'Output format (plain, json or json_pretty, default is plain)',
$this->defaultOutputFormat,
);
}
protected function execute(InputInterface $input, OutputInterface $output): int {
$io = new SymfonyStyle($input, $output);
$uid = $input->getArgument('user');
if ($uid !== null) {
/** @var string $uid */
$user = $this->userManager->get($uid);
if ($user === null) {
$io->error("Unknown user <$uid>");
return 1;
}
}
$reminders = $this->reminderService->getAll($user ?? null);
$outputOption = $input->getOption('output');
switch ($outputOption) {
case static::OUTPUT_FORMAT_JSON:
case static::OUTPUT_FORMAT_JSON_PRETTY:
$this->writeArrayInOutputFormat(
$input,
$io,
array_map(
fn (RichReminder $reminder) => $reminder->jsonSerialize(),
$reminders,
),
'',
);
return 0;
default:
if (empty($reminders)) {
$io->text('No reminders');
return 0;
}
$io->table(
['User Id', 'File Id', 'Path', 'Due Date', 'Updated At', 'Created At', 'Notified'],
array_map(
fn (RichReminder $reminder) => [
$reminder->getUserId(),
$reminder->getFileId(),
$reminder->getNode()->getPath(),
$reminder->getDueDate()->format(DateTimeInterface::ATOM), // ISO 8601
$reminder->getUpdatedAt()->format(DateTimeInterface::ATOM), // ISO 8601
$reminder->getCreatedAt()->format(DateTimeInterface::ATOM), // ISO 8601
$reminder->getNotified() ? 'true' : 'false',
],
$reminders,
),
);
return 0;
}
}
}
@@ -0,0 +1,149 @@
<?php
declare(strict_types=1);
/**
* @copyright 2023 Christopher Ng <chrng8@gmail.com>
*
* @author Christopher Ng <chrng8@gmail.com>
*
* @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\FilesReminders\Controller;
use DateTime;
use DateTimeInterface;
use DateTimeZone;
use Exception;
use OCA\FilesReminders\Exception\NodeNotFoundException;
use OCA\FilesReminders\Service\ReminderService;
use OCP\AppFramework\Db\DoesNotExistException;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\Attribute\NoAdminRequired;
use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\OCSController;
use OCP\IRequest;
use OCP\IUserSession;
use Psr\Log\LoggerInterface;
class ApiController extends OCSController {
public function __construct(
string $appName,
IRequest $request,
protected ReminderService $reminderService,
protected IUserSession $userSession,
protected LoggerInterface $logger,
) {
parent::__construct($appName, $request);
}
/**
* Get a reminder
*
* @param int $fileId ID of the file
* @return DataResponse<Http::STATUS_OK, array{dueDate: ?string}, array{}>|DataResponse<Http::STATUS_UNAUTHORIZED, array<empty>, array{}>
*
* 200: Reminder returned
* 401: User not found
*/
#[NoAdminRequired]
public function get(int $fileId): DataResponse {
$user = $this->userSession->getUser();
if ($user === null) {
return new DataResponse([], Http::STATUS_UNAUTHORIZED);
}
try {
$reminder = $this->reminderService->getDueForUser($user, $fileId);
$reminderData = [
'dueDate' => $reminder->getDueDate()->format(DateTimeInterface::ATOM), // ISO 8601
];
return new DataResponse($reminderData, Http::STATUS_OK);
} catch (DoesNotExistException $e) {
$reminderData = [
'dueDate' => null,
];
return new DataResponse($reminderData, Http::STATUS_OK);
}
}
/**
* Set a reminder
*
* @param int $fileId ID of the file
* @param string $dueDate ISO 8601 formatted date time string
*
* @return DataResponse<Http::STATUS_OK|Http::STATUS_CREATED|Http::STATUS_BAD_REQUEST|Http::STATUS_UNAUTHORIZED|Http::STATUS_NOT_FOUND, array<empty>, array{}>
*
* 200: Reminder updated
* 201: Reminder created successfully
* 400: Creating reminder is not possible
* 401: User not found
* 404: File not found
*/
#[NoAdminRequired]
public function set(int $fileId, string $dueDate): DataResponse {
try {
$dueDate = (new DateTime($dueDate))->setTimezone(new DateTimeZone('UTC'));
} catch (Exception $e) {
$this->logger->error($e->getMessage(), ['exception' => $e]);
return new DataResponse([], Http::STATUS_BAD_REQUEST);
}
$user = $this->userSession->getUser();
if ($user === null) {
return new DataResponse([], Http::STATUS_UNAUTHORIZED);
}
try {
$created = $this->reminderService->createOrUpdate($user, $fileId, $dueDate);
if ($created) {
return new DataResponse([], Http::STATUS_CREATED);
}
return new DataResponse([], Http::STATUS_OK);
} catch (NodeNotFoundException $e) {
return new DataResponse([], Http::STATUS_NOT_FOUND);
}
}
/**
* Remove a reminder
*
* @param int $fileId ID of the file
*
* @return DataResponse<Http::STATUS_OK|Http::STATUS_UNAUTHORIZED|Http::STATUS_NOT_FOUND, array<empty>, array{}>
*
* 200: Reminder deleted successfully
* 401: User not found
* 404: Reminder not found
*/
#[NoAdminRequired]
public function remove(int $fileId): DataResponse {
$user = $this->userSession->getUser();
if ($user === null) {
return new DataResponse([], Http::STATUS_UNAUTHORIZED);
}
try {
$this->reminderService->remove($user, $fileId);
return new DataResponse([], Http::STATUS_OK);
} catch (DoesNotExistException $e) {
return new DataResponse([], Http::STATUS_NOT_FOUND);
}
}
}
@@ -0,0 +1,82 @@
<?php
declare(strict_types=1);
/**
* @copyright 2024 Christopher Ng <chrng8@gmail.com>
*
* @author Christopher Ng <chrng8@gmail.com>
*
* @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\FilesReminders\Dav;
use DateTimeInterface;
use OCA\DAV\Connector\Sabre\Node;
use OCA\FilesReminders\Service\ReminderService;
use OCP\AppFramework\Db\DoesNotExistException;
use OCP\IUser;
use OCP\IUserSession;
use Sabre\DAV\INode;
use Sabre\DAV\PropFind;
use Sabre\DAV\Server;
use Sabre\DAV\ServerPlugin;
class PropFindPlugin extends ServerPlugin {
public const REMINDER_DUE_DATE_PROPERTY = '{http://nextcloud.org/ns}reminder-due-date';
public function __construct(
private ReminderService $reminderService,
private IUserSession $userSession,
) {
}
public function initialize(Server $server): void {
$server->on('propFind', [$this, 'propFind']);
}
public function propFind(PropFind $propFind, INode $node) {
if (!in_array(static::REMINDER_DUE_DATE_PROPERTY, $propFind->getRequestedProperties())) {
return;
}
if (!($node instanceof Node)) {
return;
}
$propFind->handle(
static::REMINDER_DUE_DATE_PROPERTY,
function () use ($node) {
$user = $this->userSession->getUser();
if (!($user instanceof IUser)) {
return '';
}
$fileId = $node->getId();
try {
$reminder = $this->reminderService->getDueForUser($user, $fileId);
} catch (DoesNotExistException $e) {
return '';
}
return $reminder->getDueDate()->format(DateTimeInterface::ATOM); // ISO 8601
},
);
}
}
@@ -0,0 +1,67 @@
<?php
declare(strict_types=1);
/**
* @copyright 2023 Christopher Ng <chrng8@gmail.com>
*
* @author Christopher Ng <chrng8@gmail.com>
*
* @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\FilesReminders\Db;
use DateTime;
use OCP\AppFramework\Db\Entity;
/**
* @method void setUserId(string $userId)
* @method string getUserId()
*
* @method void setFileId(int $fileId)
* @method int getFileId()
*
* @method void setDueDate(DateTime $dueDate)
* @method DateTime getDueDate()
*
* @method void setUpdatedAt(DateTime $updatedAt)
* @method DateTime getUpdatedAt()
*
* @method void setCreatedAt(DateTime $createdAt)
* @method DateTime getCreatedAt()
*
* @method void setNotified(bool $notified)
* @method bool getNotified()
*/
class Reminder extends Entity {
protected $userId;
protected $fileId;
protected $dueDate;
protected $updatedAt;
protected $createdAt;
protected $notified = false;
public function __construct() {
$this->addType('userId', 'string');
$this->addType('fileId', 'integer');
$this->addType('dueDate', 'datetime');
$this->addType('updatedAt', 'datetime');
$this->addType('createdAt', 'datetime');
$this->addType('notified', 'boolean');
}
}
@@ -0,0 +1,161 @@
<?php
declare(strict_types=1);
/**
* @copyright 2023 Christopher Ng <chrng8@gmail.com>
*
* @author Christopher Ng <chrng8@gmail.com>
*
* @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\FilesReminders\Db;
use DateTime;
use OCP\AppFramework\Db\DoesNotExistException;
use OCP\AppFramework\Db\QBMapper;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\Files\Node;
use OCP\Files\NotFoundException;
use OCP\IDBConnection;
use OCP\IUser;
/**
* @template-extends QBMapper<Reminder>
*/
class ReminderMapper extends QBMapper {
public const TABLE_NAME = 'files_reminders';
public function __construct(IDBConnection $db) {
parent::__construct(
$db,
static::TABLE_NAME,
Reminder::class,
);
}
public function markNotified(Reminder $reminder): Reminder {
$reminderUpdate = new Reminder();
$reminderUpdate->setId($reminder->getId());
$reminderUpdate->setNotified(true);
return $this->update($reminderUpdate);
}
public function find(int $id): Reminder {
$qb = $this->db->getQueryBuilder();
$qb->select('id', 'user_id', 'file_id', 'due_date', 'updated_at', 'created_at', 'notified')
->from($this->getTableName())
->where($qb->expr()->eq('id', $qb->createNamedParameter($id, IQueryBuilder::PARAM_INT)));
return $this->findEntity($qb);
}
/**
* @throws DoesNotExistException
*/
public function findDueForUser(IUser $user, int $fileId): Reminder {
$qb = $this->db->getQueryBuilder();
$qb->select('id', 'user_id', 'file_id', 'due_date', 'updated_at', 'created_at', 'notified')
->from($this->getTableName())
->where($qb->expr()->eq('user_id', $qb->createNamedParameter($user->getUID(), IQueryBuilder::PARAM_STR)))
->andWhere($qb->expr()->eq('file_id', $qb->createNamedParameter($fileId, IQueryBuilder::PARAM_INT)))
->andWhere($qb->expr()->eq('notified', $qb->createNamedParameter(false, IQueryBuilder::PARAM_BOOL)));
return $this->findEntity($qb);
}
/**
* @return Reminder[]
*/
public function findAll() {
$qb = $this->db->getQueryBuilder();
$qb->select('id', 'user_id', 'file_id', 'due_date', 'updated_at', 'created_at', 'notified')
->from($this->getTableName())
->orderBy('due_date', 'ASC');
return $this->findEntities($qb);
}
/**
* @return Reminder[]
*/
public function findAllForUser(IUser $user) {
$qb = $this->db->getQueryBuilder();
$qb->select('id', 'user_id', 'file_id', 'due_date', 'updated_at', 'created_at', 'notified')
->from($this->getTableName())
->where($qb->expr()->eq('user_id', $qb->createNamedParameter($user->getUID(), IQueryBuilder::PARAM_STR)))
->orderBy('due_date', 'ASC');
return $this->findEntities($qb);
}
/**
* @return Reminder[]
*/
public function findAllForNode(Node $node) {
try {
$nodeId = $node->getId();
} catch (NotFoundException $e) {
return [];
}
$qb = $this->db->getQueryBuilder();
$qb->select('id', 'user_id', 'file_id', 'due_date', 'updated_at', 'created_at', 'notified')
->from($this->getTableName())
->where($qb->expr()->eq('file_id', $qb->createNamedParameter($nodeId, IQueryBuilder::PARAM_INT)))
->orderBy('due_date', 'ASC');
return $this->findEntities($qb);
}
/**
* @return Reminder[]
*/
public function findOverdue() {
$qb = $this->db->getQueryBuilder();
$qb->select('id', 'user_id', 'file_id', 'due_date', 'updated_at', 'created_at', 'notified')
->from($this->getTableName())
->where($qb->expr()->lt('due_date', $qb->createFunction('NOW()')))
->andWhere($qb->expr()->eq('notified', $qb->createNamedParameter(false, IQueryBuilder::PARAM_BOOL)))
->orderBy('due_date', 'ASC');
return $this->findEntities($qb);
}
/**
* @return Reminder[]
*/
public function findNotified(DateTime $buffer, ?int $limit = null) {
$qb = $this->db->getQueryBuilder();
$qb->select('id', 'user_id', 'file_id', 'due_date', 'updated_at', 'created_at', 'notified')
->from($this->getTableName())
->where($qb->expr()->eq('notified', $qb->createNamedParameter(true, IQueryBuilder::PARAM_BOOL)))
->andWhere($qb->expr()->lt('due_date', $qb->createNamedParameter($buffer, IQueryBuilder::PARAM_DATE)))
->orderBy('due_date', 'ASC')
->setMaxResults($limit);
return $this->findEntities($qb);
}
}
@@ -0,0 +1,32 @@
<?php
declare(strict_types=1);
/**
* @copyright 2023 Christopher Ng <chrng8@gmail.com>
*
* @author Christopher Ng <chrng8@gmail.com>
*
* @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\FilesReminders\Exception;
use Exception;
class NodeNotFoundException extends Exception {
}
@@ -0,0 +1,32 @@
<?php
declare(strict_types=1);
/**
* @copyright 2023 Christopher Ng <chrng8@gmail.com>
*
* @author Christopher Ng <chrng8@gmail.com>
*
* @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\FilesReminders\Exception;
use Exception;
class UserNotFoundException extends Exception {
}
@@ -0,0 +1,53 @@
<?php
declare(strict_types=1);
/**
* @copyright 2023 Christopher Ng <chrng8@gmail.com>
*
* @author Christopher Ng <chrng8@gmail.com>
*
* @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\FilesReminders\Listener;
use OCA\Files\Event\LoadAdditionalScriptsEvent;
use OCA\FilesReminders\AppInfo\Application;
use OCP\App\IAppManager;
use OCP\EventDispatcher\Event;
use OCP\EventDispatcher\IEventListener;
use OCP\Util;
class LoadAdditionalScriptsListener implements IEventListener {
public function __construct(
private IAppManager $appManager,
) {
}
public function handle(Event $event): void {
if (!($event instanceof LoadAdditionalScriptsEvent)) {
return;
}
if (!$this->appManager->isEnabledForUser('notifications')) {
return;
}
Util::addInitScript(Application::APP_ID, 'init');
}
}
@@ -0,0 +1,48 @@
<?php
declare(strict_types=1);
/**
* @copyright 2023 Christopher Ng <chrng8@gmail.com>
*
* @author Christopher Ng <chrng8@gmail.com>
*
* @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\FilesReminders\Listener;
use OCA\FilesReminders\Service\ReminderService;
use OCP\EventDispatcher\Event;
use OCP\EventDispatcher\IEventListener;
use OCP\Files\Events\Node\NodeDeletedEvent;
class NodeDeletedListener implements IEventListener {
public function __construct(
private ReminderService $reminderService,
) {
}
public function handle(Event $event): void {
if (!($event instanceof NodeDeletedEvent)) {
return;
}
$node = $event->getNode();
$this->reminderService->removeAllForNode($node);
}
}
@@ -0,0 +1,48 @@
<?php
declare(strict_types=1);
/**
* @copyright 2023 Christopher Ng <chrng8@gmail.com>
*
* @author Christopher Ng <chrng8@gmail.com>
*
* @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\FilesReminders\Listener;
use OCA\FilesReminders\Service\ReminderService;
use OCP\EventDispatcher\Event;
use OCP\EventDispatcher\IEventListener;
use OCP\User\Events\UserDeletedEvent;
class UserDeletedListener implements IEventListener {
public function __construct(
private ReminderService $reminderService,
) {
}
public function handle(Event $event): void {
if (!($event instanceof UserDeletedEvent)) {
return;
}
$user = $event->getUser();
$this->reminderService->removeAllForUser($user);
}
}
@@ -0,0 +1,82 @@
<?php
declare(strict_types=1);
/**
* @copyright 2023 Christopher Ng <chrng8@gmail.com>
*
* @author Christopher Ng <chrng8@gmail.com>
*
* @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\FilesReminders\Migration;
use Closure;
use OCA\FilesReminders\Db\ReminderMapper;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version10000Date20230725162149 extends SimpleMigrationStep {
/**
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
*/
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
if ($schema->hasTable(ReminderMapper::TABLE_NAME)) {
return null;
}
$table = $schema->createTable(ReminderMapper::TABLE_NAME);
$table->addColumn('id', Types::BIGINT, [
'autoincrement' => true,
'notnull' => true,
'length' => 20,
'unsigned' => true,
]);
$table->addColumn('user_id', Types::STRING, [
'notnull' => true,
'length' => 64,
]);
$table->addColumn('file_id', Types::BIGINT, [
'notnull' => true,
'length' => 20,
'unsigned' => true,
]);
$table->addColumn('due_date', Types::DATETIME, [
'notnull' => true,
]);
$table->addColumn('updated_at', Types::DATETIME, [
'notnull' => true,
]);
$table->addColumn('created_at', Types::DATETIME, [
'notnull' => true,
]);
$table->addColumn('notified', Types::BOOLEAN, [
'notnull' => false,
'default' => false,
]);
$table->setPrimaryKey(['id']);
$table->addUniqueIndex(['user_id', 'file_id', 'due_date'], 'reminders_uniq_idx');
return $schema;
}
}
@@ -0,0 +1,75 @@
<?php
declare(strict_types=1);
/**
* @copyright 2023 Christopher Ng <chrng8@gmail.com>
*
* @author Christopher Ng <chrng8@gmail.com>
*
* @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\FilesReminders\Model;
use DateTimeInterface;
use JsonSerializable;
use OCA\FilesReminders\Db\Reminder;
use OCA\FilesReminders\Exception\NodeNotFoundException;
use OCP\Files\IRootFolder;
use OCP\Files\Node;
class RichReminder extends Reminder implements JsonSerializable {
public function __construct(
private Reminder $reminder,
private IRootFolder $root,
) {
parent::__construct();
}
/**
* @throws NodeNotFoundException
*/
public function getNode(): Node {
$nodes = $this->root->getUserFolder($this->getUserId())->getById($this->getFileId());
if (empty($nodes)) {
throw new NodeNotFoundException();
}
$node = reset($nodes);
return $node;
}
protected function getter(string $name): mixed {
return $this->reminder->getter($name);
}
public function __call(string $methodName, array $args) {
return $this->reminder->__call($methodName, $args);
}
public function jsonSerialize(): array {
return [
'userId' => $this->getUserId(),
'fileId' => $this->getFileId(),
'path' => $this->getNode()->getPath(),
'dueDate' => $this->getDueDate()->format(DateTimeInterface::ATOM), // ISO 8601
'updatedAt' => $this->getUpdatedAt()->format(DateTimeInterface::ATOM), // ISO 8601
'createdAt' => $this->getCreatedAt()->format(DateTimeInterface::ATOM), // ISO 8601
'notified' => $this->getNotified(),
];
}
}
@@ -0,0 +1,130 @@
<?php
declare(strict_types=1);
/**
* @copyright 2023 Christopher Ng <chrng8@gmail.com>
*
* @author Christopher Ng <chrng8@gmail.com>
*
* @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\FilesReminders\Notification;
use InvalidArgumentException;
use OCA\FilesReminders\AppInfo\Application;
use OCP\Files\FileInfo;
use OCP\Files\IRootFolder;
use OCP\IURLGenerator;
use OCP\L10N\IFactory;
use OCP\Notification\AlreadyProcessedException;
use OCP\Notification\IAction;
use OCP\Notification\INotification;
use OCP\Notification\INotifier;
class Notifier implements INotifier {
public function __construct(
protected IFactory $l10nFactory,
protected IURLGenerator $urlGenerator,
protected IRootFolder $root,
) {
}
public function getID(): string {
return Application::APP_ID;
}
public function getName(): string {
return $this->l10nFactory->get(Application::APP_ID)->t('File reminders');
}
/**
* @throws InvalidArgumentException
* @throws AlreadyProcessedException
*/
public function prepare(INotification $notification, string $languageCode): INotification {
$l = $this->l10nFactory->get(Application::APP_ID, $languageCode);
if ($notification->getApp() !== Application::APP_ID) {
throw new InvalidArgumentException();
}
switch ($notification->getSubject()) {
case 'reminder-due':
$params = $notification->getSubjectParameters();
$fileId = $params['fileId'];
$nodes = $this->root->getUserFolder($notification->getUser())->getById($fileId);
if (empty($nodes)) {
throw new InvalidArgumentException();
}
$node = reset($nodes);
$path = rtrim($node->getPath(), '/');
if (strpos($path, '/' . $notification->getUser() . '/files/') === 0) {
// Remove /user/files/...
$fullPath = $path;
[,,, $path] = explode('/', $fullPath, 4);
}
$link = $this->urlGenerator->linkToRouteAbsolute(
'files.viewcontroller.showFile',
['fileid' => $node->getId()],
);
// TRANSLATORS The name placeholder is for a file or folder name
$subject = $l->t('Reminder for {name}');
$notification
->setRichSubject(
$subject,
[
'name' => [
'type' => 'highlight',
'id' => $node->getId(),
'name' => $node->getName(),
],
],
)
->setLink($link);
$label = match ($node->getType()) {
FileInfo::TYPE_FILE => $l->t('View file'),
FileInfo::TYPE_FOLDER => $l->t('View folder'),
};
$this->addActionButton($notification, $label);
break;
default:
throw new InvalidArgumentException();
break;
}
return $notification;
}
protected function addActionButton(INotification $notification, string $label): void {
$action = $notification->createAction();
$action->setLabel($label)
->setParsedLabel($label)
->setLink($notification->getLink(), IAction::TYPE_WEB)
->setPrimary(true);
$notification->addParsedAction($action);
}
}
@@ -0,0 +1,181 @@
<?php
declare(strict_types=1);
/**
* @copyright 2023 Christopher Ng <chrng8@gmail.com>
*
* @author Christopher Ng <chrng8@gmail.com>
*
* @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\FilesReminders\Service;
use DateTime;
use DateTimeZone;
use OCA\FilesReminders\AppInfo\Application;
use OCA\FilesReminders\Db\Reminder;
use OCA\FilesReminders\Db\ReminderMapper;
use OCA\FilesReminders\Exception\NodeNotFoundException;
use OCA\FilesReminders\Exception\UserNotFoundException;
use OCA\FilesReminders\Model\RichReminder;
use OCP\AppFramework\Db\DoesNotExistException;
use OCP\Files\IRootFolder;
use OCP\Files\Node;
use OCP\IURLGenerator;
use OCP\IUser;
use OCP\IUserManager;
use OCP\Notification\IManager as INotificationManager;
use Psr\Log\LoggerInterface;
use Throwable;
class ReminderService {
public function __construct(
protected IUserManager $userManager,
protected IURLGenerator $urlGenerator,
protected INotificationManager $notificationManager,
protected ReminderMapper $reminderMapper,
protected IRootFolder $root,
protected LoggerInterface $logger,
) {
}
/**
* @throws DoesNotExistException
*/
public function get(int $id): RichReminder {
$reminder = $this->reminderMapper->find($id);
return new RichReminder($reminder, $this->root);
}
/**
* @throws DoesNotExistException
*/
public function getDueForUser(IUser $user, int $fileId): RichReminder {
$reminder = $this->reminderMapper->findDueForUser($user, $fileId);
return new RichReminder($reminder, $this->root);
}
/**
* @return RichReminder[]
*/
public function getAll(?IUser $user = null) {
$reminders = ($user !== null)
? $this->reminderMapper->findAllForUser($user)
: $this->reminderMapper->findAll();
return array_map(
fn (Reminder $reminder) => new RichReminder($reminder, $this->root),
$reminders,
);
}
/**
* @return bool true if created, false if updated
*
* @throws NodeNotFoundException
*/
public function createOrUpdate(IUser $user, int $fileId, DateTime $dueDate): bool {
$now = new DateTime('now', new DateTimeZone('UTC'));
try {
$reminder = $this->reminderMapper->findDueForUser($user, $fileId);
$reminder->setDueDate($dueDate);
$reminder->setUpdatedAt($now);
$this->reminderMapper->update($reminder);
return false;
} catch (DoesNotExistException $e) {
$nodes = $this->root->getUserFolder($user->getUID())->getById($fileId);
if (empty($nodes)) {
throw new NodeNotFoundException();
}
// Create new reminder if no reminder is found
$reminder = new Reminder();
$reminder->setUserId($user->getUID());
$reminder->setFileId($fileId);
$reminder->setDueDate($dueDate);
$reminder->setUpdatedAt($now);
$reminder->setCreatedAt($now);
$this->reminderMapper->insert($reminder);
return true;
}
}
/**
* @throws DoesNotExistException
*/
public function remove(IUser $user, int $fileId): void {
$reminder = $this->reminderMapper->findDueForUser($user, $fileId);
$this->reminderMapper->delete($reminder);
}
public function removeAllForNode(Node $node): void {
$reminders = $this->reminderMapper->findAllForNode($node);
foreach ($reminders as $reminder) {
$this->reminderMapper->delete($reminder);
}
}
public function removeAllForUser(IUser $user): void {
$reminders = $this->reminderMapper->findAllForUser($user);
foreach ($reminders as $reminder) {
$this->reminderMapper->delete($reminder);
}
}
/**
* @throws DoesNotExistException
* @throws UserNotFoundException
*/
public function send(Reminder $reminder): void {
if ($reminder->getNotified()) {
return;
}
$user = $this->userManager->get($reminder->getUserId());
if ($user === null) {
throw new UserNotFoundException();
}
$notification = $this->notificationManager->createNotification();
$notification
->setApp(Application::APP_ID)
->setIcon($this->urlGenerator->getAbsoluteURL($this->urlGenerator->imagePath('files', 'folder.svg')))
->setUser($user->getUID())
->setObject('reminder', (string)$reminder->getId())
->setSubject('reminder-due', [
'fileId' => $reminder->getFileId(),
])
->setDateTime($reminder->getDueDate());
try {
$this->notificationManager->notify($notification);
$this->reminderMapper->markNotified($reminder);
} catch (Throwable $th) {
$this->logger->error($th->getMessage(), $th->getTrace());
}
}
public function cleanUp(?int $limit = null): void {
$buffer = (new DateTime())
->setTimezone(new DateTimeZone('UTC'))
->modify('-1 day');
$reminders = $this->reminderMapper->findNotified($buffer, $limit);
foreach ($reminders as $reminder) {
$this->reminderMapper->delete($reminder);
}
}
}
@@ -0,0 +1,498 @@
{
"openapi": "3.0.3",
"info": {
"title": "files_reminders",
"version": "0.0.1",
"description": "Set file reminders",
"license": {
"name": "agpl"
}
},
"components": {
"securitySchemes": {
"basic_auth": {
"type": "http",
"scheme": "basic"
},
"bearer_auth": {
"type": "http",
"scheme": "bearer"
}
},
"schemas": {
"OCSMeta": {
"type": "object",
"required": [
"status",
"statuscode"
],
"properties": {
"status": {
"type": "string"
},
"statuscode": {
"type": "integer"
},
"message": {
"type": "string"
},
"totalitems": {
"type": "string"
},
"itemsperpage": {
"type": "string"
}
}
}
}
},
"paths": {
"/ocs/v2.php/apps/files_reminders/api/v{version}/{fileId}": {
"get": {
"operationId": "api-get",
"summary": "Get a reminder",
"tags": [
"api"
],
"security": [
{
"bearer_auth": []
},
{
"basic_auth": []
}
],
"parameters": [
{
"name": "version",
"in": "path",
"required": true,
"schema": {
"type": "string",
"pattern": "^1$"
}
},
{
"name": "fileId",
"in": "path",
"description": "ID of the file",
"required": true,
"schema": {
"type": "integer",
"format": "int64"
}
},
{
"name": "OCS-APIRequest",
"in": "header",
"description": "Required to be true for the API request to pass",
"required": true,
"schema": {
"type": "boolean",
"default": true
}
}
],
"responses": {
"200": {
"description": "Reminder returned",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {
"type": "object",
"required": [
"dueDate"
],
"properties": {
"dueDate": {
"type": "string",
"nullable": true
}
}
}
}
}
}
}
}
}
},
"401": {
"description": "User not found",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {}
}
}
}
}
}
}
}
}
},
"put": {
"operationId": "api-set",
"summary": "Set a reminder",
"tags": [
"api"
],
"security": [
{
"bearer_auth": []
},
{
"basic_auth": []
}
],
"parameters": [
{
"name": "dueDate",
"in": "query",
"description": "ISO 8601 formatted date time string",
"required": true,
"schema": {
"type": "string"
}
},
{
"name": "version",
"in": "path",
"required": true,
"schema": {
"type": "string",
"pattern": "^1$"
}
},
{
"name": "fileId",
"in": "path",
"description": "ID of the file",
"required": true,
"schema": {
"type": "integer",
"format": "int64"
}
},
{
"name": "OCS-APIRequest",
"in": "header",
"description": "Required to be true for the API request to pass",
"required": true,
"schema": {
"type": "boolean",
"default": true
}
}
],
"responses": {
"200": {
"description": "Reminder updated",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {}
}
}
}
}
}
}
},
"201": {
"description": "Reminder created successfully",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {}
}
}
}
}
}
}
},
"400": {
"description": "Creating reminder is not possible",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {}
}
}
}
}
}
}
},
"401": {
"description": "User not found",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {}
}
}
}
}
}
}
},
"404": {
"description": "File not found",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {}
}
}
}
}
}
}
}
}
},
"delete": {
"operationId": "api-remove",
"summary": "Remove a reminder",
"tags": [
"api"
],
"security": [
{
"bearer_auth": []
},
{
"basic_auth": []
}
],
"parameters": [
{
"name": "version",
"in": "path",
"required": true,
"schema": {
"type": "string",
"pattern": "^1$"
}
},
{
"name": "fileId",
"in": "path",
"description": "ID of the file",
"required": true,
"schema": {
"type": "integer",
"format": "int64"
}
},
{
"name": "OCS-APIRequest",
"in": "header",
"description": "Required to be true for the API request to pass",
"required": true,
"schema": {
"type": "boolean",
"default": true
}
}
],
"responses": {
"200": {
"description": "Reminder deleted successfully",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {}
}
}
}
}
}
}
},
"401": {
"description": "User not found",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {}
}
}
}
}
}
}
},
"404": {
"description": "Reminder not found",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {}
}
}
}
}
}
}
}
}
}
}
},
"tags": []
}