-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: OCC and OCS Calendar Import/Export #49995
base: master
Are you sure you want to change the base?
Conversation
b0ee614
to
5198d6b
Compare
c69a4fb
to
8a6dd83
Compare
Hi @tcitworld I was wondering if you would be willing to test this out with some of your larger live data calendars? |
59a2223
to
67dc029
Compare
67dc029
to
8ad0991
Compare
8ad0991
to
213c1aa
Compare
Signed-off-by: SebastianKrupinski <[email protected]>
a2f9ff4
to
8eff6e4
Compare
Signed-off-by: SebastianKrupinski <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First round of feedback
apps/dav/lib/CalDAV/CalendarImpl.php
Outdated
* | ||
* @since 32.0.0 | ||
* | ||
* @return array |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can this be typed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, as long a pslam plays nice.
apps/dav/lib/CalDAV/CalendarImpl.php
Outdated
* @return array | ||
*/ | ||
public function import(CalendarImportOptions $options, callable $generator): array { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the blank lines at a method start are strange. please try to avoid them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
/** | ||
* Calendar Export Service | ||
* | ||
* @since 32.0.0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI the @since
annotations are used for public API. You don't have to add this for internal structures, because they won't be used in apps.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TBH, I add these as a way of tracking when something was added, so when I look though our code I can see how new or old something is, and if there are fixes to back port is easy to see how far back you can go.
Do you want me to remove them?
public function __construct() { | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔥
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this mean fire as in, this is great or burn it? Lol
// construct options object | ||
$options = new CalendarExportOptions(); | ||
// evaluate if provided format is supported | ||
if ($format !== null && !in_array($format, $this->exportService::FORMATS)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
always use in_array in strict mode
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
#[ApiRoute(verb: 'GET', url: '/export', root: '/calendar')] | ||
#[ApiRoute(verb: 'POST', url: '/export', root: '/calendar')] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't get why it is GET and POST
return new DataResponse(['error' => 'user not found'], Http::STATUS_BAD_REQUEST); | ||
} | ||
} else { | ||
$userId = $this->userSession->getUser()->getUID(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
opening the route unauthenticated with no userId
passed will lead to a NPE when calling getUID
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tested this with Insomnia, by sending a request without authentication or cookies.
Requests that are NOT authenticated get rejected by the initial check as expected.
if (!$this->userSession->isLoggedIn()) {
return new DataResponse([], Http::STATUS_UNAUTHORIZED);
}
Is this sufficient or am I missing something?
}; | ||
|
||
return new StreamGeneratorResponse($this->exportService->export($calendar, $options), $contentType); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unnecessary blank line
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
#[ApiRoute(verb: 'POST', url: '/import', root: '/calendar')] | ||
#[UserRateLimit(limit: 1, period: 60)] | ||
#[NoAdminRequired] | ||
public function index(string $id, array $options, string $data, ?string $user = null) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
missing return type hint
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
missing types for options
return new DataResponse(['error' => 'user not found'], Http::STATUS_BAD_REQUEST); | ||
} | ||
} else { | ||
$userId = $this->userSession->getUser()->getUID(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NPE
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See comments on the CalendarExportController.
When adding a new controller for HTTP routes I'm wondering if we shouldn't got for OCS and openapi specs right away. Could you please check how doable that is with the different input/output formats you want to support? |
Found a new internal use for this, this morning, calendar subscriptions can use the same import code to reduce redundant code, complexity and increase performance. |
Signed-off-by: SebastianKrupinski <[email protected]>
Signed-off-by: SebastianKrupinski <[email protected]>
Signed-off-by: SebastianKrupinski <[email protected]>
Signed-off-by: SebastianKrupinski <[email protected]>
Signed-off-by: SebastianKrupinski <[email protected]>
I think we can make it work, Import is good already, just struggling getting a proper phpdoc export |
Summary
This adds the ability to export calendars via the OCS and OCC.
OCC Export
Command: calendar:export
Arguments: userId calendarId format filepath
OCC Import
Command: calendar:import
Arguments: userId calendarId format filepath
Options: errors, validation, supersede, show-created, show-updated, show-skipped, show-errors
OCS Export
Endpoint: /ocs/v2.php/calendar/export
Request GET
Request: POST
OCS Import
Endpoint: /ocs/v2.php/calendar/import
Request: POST
Performance
Checklist