Skip to content

Commit 2cba151

Browse files
committed
cache webcal calendars on server
Signed-off-by: Georg Ehrke <developer@georgehrke.com>
1 parent 501ee33 commit 2cba151

File tree

13 files changed

+1062
-40
lines changed

13 files changed

+1062
-40
lines changed

apps/dav/appinfo/app.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,34 @@ function(GenericEvent $event) use ($app) {
4848
}
4949
);
5050

51+
$eventDispatcher->addListener('\OCA\DAV\CalDAV\CalDavBackend::createSubscription',
52+
function(GenericEvent $event) use ($app) {
53+
$jobList = $app->getContainer()->getServer()->getJobList();
54+
$subscriptionData = $event->getArgument('subscriptionData');
55+
56+
$jobList->add(\OCA\DAV\BackgroundJob\RefreshWebcalJob::class, [
57+
'principaluri' => $subscriptionData['principaluri'],
58+
'uri' => $subscriptionData['uri']
59+
]);
60+
}
61+
);
62+
63+
$eventDispatcher->addListener('\OCA\DAV\CalDAV\CalDavBackend::deleteSubscription',
64+
function(GenericEvent $event) use ($app) {
65+
$jobList = $app->getContainer()->getServer()->getJobList();
66+
$subscriptionData = $event->getArgument('subscriptionData');
67+
68+
$jobList->remove(\OCA\DAV\BackgroundJob\RefreshWebcalJob::class, [
69+
'principaluri' => $subscriptionData['principaluri'],
70+
'uri' => $subscriptionData['uri']
71+
]);
72+
73+
/** @var \OCA\DAV\CalDAV\CalDavBackend $calDavBackend */
74+
$calDavBackend = $app->getContainer()->query(\OCA\DAV\CalDAV\CalDavBackend::class);
75+
$calDavBackend->purgeAllCachedEventsForSubscription($subscriptionData['id']);
76+
}
77+
);
78+
5179
$eventHandler = function() use ($app) {
5280
try {
5381
$job = $app->getContainer()->query(\OCA\DAV\BackgroundJob\UpdateCalendarResourcesRoomsBackgroundJob::class);

apps/dav/appinfo/info.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<name>WebDAV</name>
66
<summary>WebDAV endpoint</summary>
77
<description>WebDAV endpoint</description>
8-
<version>1.5.4</version>
8+
<version>1.5.5</version>
99
<licence>agpl</licence>
1010
<author>owncloud.org</author>
1111
<namespace>DAV</namespace>
@@ -29,6 +29,7 @@
2929
<step>OCA\DAV\Migration\FixBirthdayCalendarComponent</step>
3030
<step>OCA\DAV\Migration\CalDAVRemoveEmptyValue</step>
3131
<step>OCA\DAV\Migration\BuildCalendarSearchIndex</step>
32+
<step>OCA\DAV\Migration\RefreshWebcalJobRegistrar</step>
3233
</post-migration>
3334
</repair-steps>
3435

apps/dav/composer/composer/autoload_classmap.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
'OCA\\DAV\\Avatars\\RootCollection' => $baseDir . '/../lib/Avatars/RootCollection.php',
1414
'OCA\\DAV\\BackgroundJob\\CleanupDirectLinksJob' => $baseDir . '/../lib/BackgroundJob/CleanupDirectLinksJob.php',
1515
'OCA\\DAV\\BackgroundJob\\GenerateBirthdayCalendarBackgroundJob' => $baseDir . '/../lib/BackgroundJob/GenerateBirthdayCalendarBackgroundJob.php',
16+
'OCA\\DAV\\BackgroundJob\\RefreshWebcalJob' => $baseDir . '/../lib/BackgroundJob/RefreshWebcalJob.php',
1617
'OCA\\DAV\\BackgroundJob\\UpdateCalendarResourcesRoomsBackgroundJob' => $baseDir . '/../lib/BackgroundJob/UpdateCalendarResourcesRoomsBackgroundJob.php',
1718
'OCA\\DAV\\CalDAV\\Activity\\Backend' => $baseDir . '/../lib/CalDAV/Activity/Backend.php',
1819
'OCA\\DAV\\CalDAV\\Activity\\Filter\\Calendar' => $baseDir . '/../lib/CalDAV/Activity/Filter/Calendar.php',
@@ -26,6 +27,8 @@
2627
'OCA\\DAV\\CalDAV\\Activity\\Setting\\Todo' => $baseDir . '/../lib/CalDAV/Activity/Setting/Todo.php',
2728
'OCA\\DAV\\CalDAV\\BirthdayCalendar\\EnablePlugin' => $baseDir . '/../lib/CalDAV/BirthdayCalendar/EnablePlugin.php',
2829
'OCA\\DAV\\CalDAV\\BirthdayService' => $baseDir . '/../lib/CalDAV/BirthdayService.php',
30+
'OCA\\DAV\\CalDAV\\CachedSubscription' => $baseDir . '/../lib/CalDAV/CachedSubscription.php',
31+
'OCA\\DAV\\CalDAV\\CachedSubscriptionObject' => $baseDir . '/../lib/CalDAV/CachedSubscriptionObject.php',
2932
'OCA\\DAV\\CalDAV\\CalDavBackend' => $baseDir . '/../lib/CalDAV/CalDavBackend.php',
3033
'OCA\\DAV\\CalDAV\\Calendar' => $baseDir . '/../lib/CalDAV/Calendar.php',
3134
'OCA\\DAV\\CalDAV\\CalendarHome' => $baseDir . '/../lib/CalDAV/CalendarHome.php',
@@ -54,6 +57,7 @@
5457
'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\PropFilter' => $baseDir . '/../lib/CalDAV/Search/Xml/Filter/PropFilter.php',
5558
'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\SearchTermFilter' => $baseDir . '/../lib/CalDAV/Search/Xml/Filter/SearchTermFilter.php',
5659
'OCA\\DAV\\CalDAV\\Search\\Xml\\Request\\CalendarSearchReport' => $baseDir . '/../lib/CalDAV/Search/Xml/Request/CalendarSearchReport.php',
60+
'OCA\\DAV\\CalDAV\\WebcalCaching\\Plugin' => $baseDir . '/../lib/CalDAV/WebcalCaching/Plugin.php',
5761
'OCA\\DAV\\Capabilities' => $baseDir . '/../lib/Capabilities.php',
5862
'OCA\\DAV\\CardDAV\\AddressBook' => $baseDir . '/../lib/CardDAV/AddressBook.php',
5963
'OCA\\DAV\\CardDAV\\AddressBookImpl' => $baseDir . '/../lib/CardDAV/AddressBookImpl.php',
@@ -144,12 +148,14 @@
144148
'OCA\\DAV\\Migration\\BuildCalendarSearchIndexBackgroundJob' => $baseDir . '/../lib/Migration/BuildCalendarSearchIndexBackgroundJob.php',
145149
'OCA\\DAV\\Migration\\CalDAVRemoveEmptyValue' => $baseDir . '/../lib/Migration/CalDAVRemoveEmptyValue.php',
146150
'OCA\\DAV\\Migration\\FixBirthdayCalendarComponent' => $baseDir . '/../lib/Migration/FixBirthdayCalendarComponent.php',
151+
'OCA\\DAV\\Migration\\RefreshWebcalJobRegistrar' => $baseDir . '/../lib/Migration/RefreshWebcalJobRegistrar.php',
147152
'OCA\\DAV\\Migration\\Version1004Date20170825134824' => $baseDir . '/../lib/Migration/Version1004Date20170825134824.php',
148153
'OCA\\DAV\\Migration\\Version1004Date20170919104507' => $baseDir . '/../lib/Migration/Version1004Date20170919104507.php',
149154
'OCA\\DAV\\Migration\\Version1004Date20170924124212' => $baseDir . '/../lib/Migration/Version1004Date20170924124212.php',
150155
'OCA\\DAV\\Migration\\Version1004Date20170926103422' => $baseDir . '/../lib/Migration/Version1004Date20170926103422.php',
151156
'OCA\\DAV\\Migration\\Version1005Date20180413093149' => $baseDir . '/../lib/Migration/Version1005Date20180413093149.php',
152157
'OCA\\DAV\\Migration\\Version1005Date20180530124431' => $baseDir . '/../lib/Migration/Version1005Date20180530124431.php',
158+
'OCA\\DAV\\Migration\\Version1006Date20180628111625' => $baseDir . '/../lib/Migration/Version1006Date20180628111625.php',
153159
'OCA\\DAV\\RootCollection' => $baseDir . '/../lib/RootCollection.php',
154160
'OCA\\DAV\\Server' => $baseDir . '/../lib/Server.php',
155161
'OCA\\DAV\\Settings\\CalDAVSettings' => $baseDir . '/../lib/Settings/CalDAVSettings.php',

apps/dav/composer/composer/autoload_static.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class ComposerStaticInitDAV
2828
'OCA\\DAV\\Avatars\\RootCollection' => __DIR__ . '/..' . '/../lib/Avatars/RootCollection.php',
2929
'OCA\\DAV\\BackgroundJob\\CleanupDirectLinksJob' => __DIR__ . '/..' . '/../lib/BackgroundJob/CleanupDirectLinksJob.php',
3030
'OCA\\DAV\\BackgroundJob\\GenerateBirthdayCalendarBackgroundJob' => __DIR__ . '/..' . '/../lib/BackgroundJob/GenerateBirthdayCalendarBackgroundJob.php',
31+
'OCA\\DAV\\BackgroundJob\\RefreshWebcalJob' => __DIR__ . '/..' . '/../lib/BackgroundJob/RefreshWebcalJob.php',
3132
'OCA\\DAV\\BackgroundJob\\UpdateCalendarResourcesRoomsBackgroundJob' => __DIR__ . '/..' . '/../lib/BackgroundJob/UpdateCalendarResourcesRoomsBackgroundJob.php',
3233
'OCA\\DAV\\CalDAV\\Activity\\Backend' => __DIR__ . '/..' . '/../lib/CalDAV/Activity/Backend.php',
3334
'OCA\\DAV\\CalDAV\\Activity\\Filter\\Calendar' => __DIR__ . '/..' . '/../lib/CalDAV/Activity/Filter/Calendar.php',
@@ -41,6 +42,8 @@ class ComposerStaticInitDAV
4142
'OCA\\DAV\\CalDAV\\Activity\\Setting\\Todo' => __DIR__ . '/..' . '/../lib/CalDAV/Activity/Setting/Todo.php',
4243
'OCA\\DAV\\CalDAV\\BirthdayCalendar\\EnablePlugin' => __DIR__ . '/..' . '/../lib/CalDAV/BirthdayCalendar/EnablePlugin.php',
4344
'OCA\\DAV\\CalDAV\\BirthdayService' => __DIR__ . '/..' . '/../lib/CalDAV/BirthdayService.php',
45+
'OCA\\DAV\\CalDAV\\CachedSubscription' => __DIR__ . '/..' . '/../lib/CalDAV/CachedSubscription.php',
46+
'OCA\\DAV\\CalDAV\\CachedSubscriptionObject' => __DIR__ . '/..' . '/../lib/CalDAV/CachedSubscriptionObject.php',
4447
'OCA\\DAV\\CalDAV\\CalDavBackend' => __DIR__ . '/..' . '/../lib/CalDAV/CalDavBackend.php',
4548
'OCA\\DAV\\CalDAV\\Calendar' => __DIR__ . '/..' . '/../lib/CalDAV/Calendar.php',
4649
'OCA\\DAV\\CalDAV\\CalendarHome' => __DIR__ . '/..' . '/../lib/CalDAV/CalendarHome.php',
@@ -69,6 +72,7 @@ class ComposerStaticInitDAV
6972
'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\PropFilter' => __DIR__ . '/..' . '/../lib/CalDAV/Search/Xml/Filter/PropFilter.php',
7073
'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\SearchTermFilter' => __DIR__ . '/..' . '/../lib/CalDAV/Search/Xml/Filter/SearchTermFilter.php',
7174
'OCA\\DAV\\CalDAV\\Search\\Xml\\Request\\CalendarSearchReport' => __DIR__ . '/..' . '/../lib/CalDAV/Search/Xml/Request/CalendarSearchReport.php',
75+
'OCA\\DAV\\CalDAV\\WebcalCaching\\Plugin' => __DIR__ . '/..' . '/../lib/CalDAV/WebcalCaching/Plugin.php',
7276
'OCA\\DAV\\Capabilities' => __DIR__ . '/..' . '/../lib/Capabilities.php',
7377
'OCA\\DAV\\CardDAV\\AddressBook' => __DIR__ . '/..' . '/../lib/CardDAV/AddressBook.php',
7478
'OCA\\DAV\\CardDAV\\AddressBookImpl' => __DIR__ . '/..' . '/../lib/CardDAV/AddressBookImpl.php',
@@ -159,12 +163,14 @@ class ComposerStaticInitDAV
159163
'OCA\\DAV\\Migration\\BuildCalendarSearchIndexBackgroundJob' => __DIR__ . '/..' . '/../lib/Migration/BuildCalendarSearchIndexBackgroundJob.php',
160164
'OCA\\DAV\\Migration\\CalDAVRemoveEmptyValue' => __DIR__ . '/..' . '/../lib/Migration/CalDAVRemoveEmptyValue.php',
161165
'OCA\\DAV\\Migration\\FixBirthdayCalendarComponent' => __DIR__ . '/..' . '/../lib/Migration/FixBirthdayCalendarComponent.php',
166+
'OCA\\DAV\\Migration\\RefreshWebcalJobRegistrar' => __DIR__ . '/..' . '/../lib/Migration/RefreshWebcalJobRegistrar.php',
162167
'OCA\\DAV\\Migration\\Version1004Date20170825134824' => __DIR__ . '/..' . '/../lib/Migration/Version1004Date20170825134824.php',
163168
'OCA\\DAV\\Migration\\Version1004Date20170919104507' => __DIR__ . '/..' . '/../lib/Migration/Version1004Date20170919104507.php',
164169
'OCA\\DAV\\Migration\\Version1004Date20170924124212' => __DIR__ . '/..' . '/../lib/Migration/Version1004Date20170924124212.php',
165170
'OCA\\DAV\\Migration\\Version1004Date20170926103422' => __DIR__ . '/..' . '/../lib/Migration/Version1004Date20170926103422.php',
166171
'OCA\\DAV\\Migration\\Version1005Date20180413093149' => __DIR__ . '/..' . '/../lib/Migration/Version1005Date20180413093149.php',
167172
'OCA\\DAV\\Migration\\Version1005Date20180530124431' => __DIR__ . '/..' . '/../lib/Migration/Version1005Date20180530124431.php',
173+
'OCA\\DAV\\Migration\\Version1006Date20180628111625' => __DIR__ . '/..' . '/../lib/Migration/Version1006Date20180628111625.php',
168174
'OCA\\DAV\\RootCollection' => __DIR__ . '/..' . '/../lib/RootCollection.php',
169175
'OCA\\DAV\\Server' => __DIR__ . '/..' . '/../lib/Server.php',
170176
'OCA\\DAV\\Settings\\CalDAVSettings' => __DIR__ . '/..' . '/../lib/Settings/CalDAVSettings.php',
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
<?php
2+
declare(strict_types=1);
3+
/**
4+
* @copyright 2018 Georg Ehrke <oc.list@georgehrke.com>
5+
*
6+
* @author Georg Ehrke <oc.list@georgehrke.com>
7+
*
8+
* @license GNU AGPL version 3 or any later version
9+
*
10+
* This program is free software: you can redistribute it and/or modify
11+
* it under the terms of the GNU Affero General Public License as
12+
* published by the Free Software Foundation, either version 3 of the
13+
* License, or (at your option) any later version.
14+
*
15+
* This program is distributed in the hope that it will be useful,
16+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
17+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18+
* GNU Affero General Public License for more details.
19+
*
20+
* You should have received a copy of the GNU Affero General Public License
21+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
22+
*
23+
*/
24+
namespace OCA\DAV\BackgroundJob;
25+
26+
use OC\BackgroundJob\TimedJob;
27+
use OCA\DAV\CalDAV\CalDavBackend;
28+
use OCP\Http\Client\IClientService;
29+
use OCP\ILogger;
30+
use Sabre\DAV\Exception\BadRequest;
31+
use Sabre\VObject\Component;
32+
use Sabre\VObject\ParseException;
33+
use Sabre\VObject\Splitter\ICalendar;
34+
35+
class RefreshWebcalJob extends TimedJob {
36+
37+
/** @var CalDavBackend */
38+
private $calDavBackend;
39+
40+
/** @var IClientService */
41+
private $clientService;
42+
43+
/** @var ILogger */
44+
private $logger;
45+
46+
/**
47+
* RefreshWebcalJob constructor.
48+
*
49+
* @param CalDavBackend $calDavBackend
50+
* @param IClientService $clientService
51+
* @param ILogger $logger
52+
*/
53+
public function __construct(CalDavBackend $calDavBackend, IClientService $clientService, ILogger $logger) {
54+
$this->calDavBackend = $calDavBackend;
55+
$this->clientService = $clientService;
56+
$this->logger = $logger;
57+
58+
$this->setInterval(60*60*24);
59+
}
60+
61+
/**
62+
* @param array $argument
63+
*/
64+
protected function run($argument) {
65+
$principalUri = $argument['principaluri'];
66+
$uri = $argument['uri'];
67+
68+
$subscriptions = array_filter(
69+
$this->calDavBackend->getSubscriptionsForUser($principalUri),
70+
function($sub) use ($uri) {
71+
return $sub['uri'] === $uri;
72+
}
73+
);
74+
75+
if (\count($subscriptions) === 0) {
76+
return;
77+
}
78+
/** @var array $subscription */
79+
$subscription = $subscriptions[0];
80+
81+
// if ($subscription['refreshrate'])
82+
83+
$webcalData = $this->queryWebcalFeed($subscription);
84+
if (!$webcalData) {
85+
return;
86+
}
87+
88+
$stripTodos = $subscription['striptodos'];
89+
$stripAlarms = $subscription['stripalarms'];
90+
$stripAttachments = $subscription['stripattachments'];
91+
92+
try {
93+
$splitter = new ICalendar($webcalData);
94+
95+
// we wait with deleting all purged events till we parsed the new ones
96+
// in case the new calendar is broken and new ICalendar throws a ParseException
97+
// the user will still see the old data
98+
$this->calDavBackend->purgeAllCachedEventsForSubscription($subscription['id']);
99+
100+
while ($vObject = $splitter->getNext()) {
101+
/** @var Component $vObject */
102+
$uid = null;
103+
$compName = null;
104+
105+
foreach ($vObject->getComponents() as $component) {
106+
if ($component->name === 'VTIMEZONE') {
107+
continue;
108+
}
109+
110+
$uid = $component->{'UID'}->getValue();
111+
$compName = $component->name;
112+
113+
if ($stripAlarms) {
114+
unset($component->{'VALARM'});
115+
}
116+
if ($stripAttachments) {
117+
unset($component->{'ATTACH'});
118+
}
119+
}
120+
121+
if ($stripTodos && $compName === 'VTODO') {
122+
continue;
123+
}
124+
125+
$uri = $uid . '.ics';
126+
$calendarData = $vObject->serialize();
127+
try {
128+
$this->calDavBackend->addCachedEvent($subscription['id'], $uri, $calendarData);
129+
} catch(BadRequest $ex) {
130+
$this->logger->logException($ex);
131+
}
132+
}
133+
134+
} catch(ParseException $ex) {
135+
$subscriptionId = $subscription['id'];
136+
137+
$this->logger->logException($ex);
138+
$this->logger->warning("Subscription $subscriptionId could not be refreshed due to a parsing error");
139+
}
140+
}
141+
142+
/**
143+
* @param array $subscription
144+
* @return null|resource
145+
*/
146+
private function queryWebcalFeed(array $subscription) {
147+
$client = $this->clientService->newClient();
148+
try {
149+
$response = $client->get($subscription['source'], [
150+
'stream' => true,
151+
'allow_redirects' => [
152+
'redirects' => 10
153+
]
154+
]);
155+
156+
return $response->getBody();
157+
} catch(\Exception $ex) {
158+
$subscriptionId = $subscription['id'];
159+
160+
$this->logger->logException($ex);
161+
$this->logger->warning("Subscription $subscriptionId could not be refreshed due to a network error");
162+
163+
return null;
164+
}
165+
}
166+
}

0 commit comments

Comments
 (0)