mirror of
https://github.com/etesync/android
synced 2024-11-23 00:18:19 +00:00
Refactoring
* VEvent: don't set LAST-MODIFIED to sync time (should be last modification time which is not available) * ignore 403 Forbidden when uploading (can happen on certain scheduling conditions)
This commit is contained in:
parent
fc1874af85
commit
faeb3b7dd0
@ -293,8 +293,6 @@ public class Event extends iCalendar {
|
|||||||
event.getProperties().add(forPublic ? Clazz.PUBLIC : Clazz.PRIVATE);
|
event.getProperties().add(forPublic ? Clazz.PUBLIC : Clazz.PRIVATE);
|
||||||
|
|
||||||
event.getAlarms().addAll(alarms);
|
event.getAlarms().addAll(alarms);
|
||||||
|
|
||||||
props.add(new LastModified());
|
|
||||||
return event;
|
return event;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -425,7 +425,8 @@ public class LocalCalendar extends LocalCollection<Event> {
|
|||||||
// availability
|
// availability
|
||||||
e.opaque = values.getAsInteger(Events.AVAILABILITY) != Events.AVAILABILITY_FREE;
|
e.opaque = values.getAsInteger(Events.AVAILABILITY) != Events.AVAILABILITY_FREE;
|
||||||
|
|
||||||
// set ORGANIZER
|
// set ORGANIZER if there's attendee data
|
||||||
|
if (values.getAsInteger(Events.HAS_ATTENDEE_DATA) != 0)
|
||||||
try {
|
try {
|
||||||
e.organizer = new Organizer(new URI("mailto", values.getAsString(Events.ORGANIZER), null));
|
e.organizer = new Organizer(new URI("mailto", values.getAsString(Events.ORGANIZER), null));
|
||||||
} catch (URISyntaxException ex) {
|
} catch (URISyntaxException ex) {
|
||||||
@ -553,8 +554,8 @@ public class LocalCalendar extends LocalCollection<Event> {
|
|||||||
.withValue(entryColumnETag(), event.getETag())
|
.withValue(entryColumnETag(), event.getETag())
|
||||||
.withValue(entryColumnUID(), event.getUid());
|
.withValue(entryColumnUID(), event.getUid());
|
||||||
} else {
|
} else {
|
||||||
|
// event is an exception
|
||||||
builder.withValue(Events.ORIGINAL_SYNC_ID, event.getName());
|
builder.withValue(Events.ORIGINAL_SYNC_ID, event.getName());
|
||||||
|
|
||||||
// ORIGINAL_INSTANCE_TIME and ORIGINAL_ALL_DAY is set in buildExceptions.
|
// ORIGINAL_INSTANCE_TIME and ORIGINAL_ALL_DAY is set in buildExceptions.
|
||||||
// It's not possible to use only the RECURRENCE-ID to calculate
|
// It's not possible to use only the RECURRENCE-ID to calculate
|
||||||
// ORIGINAL_INSTANCE_TIME and ORIGINAL_ALL_DAY because iCloud sends DATE-TIME
|
// ORIGINAL_INSTANCE_TIME and ORIGINAL_ALL_DAY because iCloud sends DATE-TIME
|
||||||
@ -616,7 +617,6 @@ public class LocalCalendar extends LocalCollection<Event> {
|
|||||||
builder.withValue(Events.ORGANIZER, email != null ? email : uri.toString());
|
builder.withValue(Events.ORGANIZER, email != null ? email : uri.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
//Status status = event.getStatus();
|
|
||||||
if (event.status!= null) {
|
if (event.status!= null) {
|
||||||
int statusCode = Events.STATUS_TENTATIVE;
|
int statusCode = Events.STATUS_TENTATIVE;
|
||||||
if (event.status == Status.VEVENT_CONFIRMED)
|
if (event.status == Status.VEVENT_CONFIRMED)
|
||||||
@ -639,15 +639,15 @@ public class LocalCalendar extends LocalCollection<Event> {
|
|||||||
protected void addDataRows(Resource resource, long localID, int backrefIdx) {
|
protected void addDataRows(Resource resource, long localID, int backrefIdx) {
|
||||||
final Event event = (Event)resource;
|
final Event event = (Event)resource;
|
||||||
|
|
||||||
// add exceptions
|
|
||||||
for (Event exception : event.getExceptions())
|
|
||||||
pendingOperations.add(buildException(newDataInsertBuilder(Events.CONTENT_URI, Events.ORIGINAL_ID, localID, backrefIdx), event, exception).build());
|
|
||||||
// add attendees
|
// add attendees
|
||||||
for (Attendee attendee : event.getAttendees())
|
for (Attendee attendee : event.getAttendees())
|
||||||
pendingOperations.add(buildAttendee(newDataInsertBuilder(Attendees.CONTENT_URI, Attendees.EVENT_ID, localID, backrefIdx), attendee).build());
|
pendingOperations.add(buildAttendee(newDataInsertBuilder(Attendees.CONTENT_URI, Attendees.EVENT_ID, localID, backrefIdx), attendee).build());
|
||||||
// add reminders
|
// add reminders
|
||||||
for (VAlarm alarm : event.getAlarms())
|
for (VAlarm alarm : event.getAlarms())
|
||||||
pendingOperations.add(buildReminder(newDataInsertBuilder(Reminders.CONTENT_URI, Reminders.EVENT_ID, localID, backrefIdx), alarm).build());
|
pendingOperations.add(buildReminder(newDataInsertBuilder(Reminders.CONTENT_URI, Reminders.EVENT_ID, localID, backrefIdx), alarm).build());
|
||||||
|
// add exceptions
|
||||||
|
for (Event exception : event.getExceptions())
|
||||||
|
pendingOperations.add(buildException(newDataInsertBuilder(Events.CONTENT_URI, Events.ORIGINAL_ID, localID, backrefIdx), event, exception).build());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -668,7 +668,6 @@ public class LocalCalendar extends LocalCollection<Event> {
|
|||||||
|
|
||||||
protected Builder buildException(Builder builder, Event master, Event exception) {
|
protected Builder buildException(Builder builder, Event master, Event exception) {
|
||||||
buildEntry(builder, exception, false);
|
buildEntry(builder, exception, false);
|
||||||
builder.withValue(Events.ORIGINAL_SYNC_ID, exception.getName());
|
|
||||||
|
|
||||||
final boolean originalAllDay = master.isAllDay();
|
final boolean originalAllDay = master.isAllDay();
|
||||||
|
|
||||||
@ -685,12 +684,16 @@ public class LocalCalendar extends LocalCollection<Event> {
|
|||||||
|
|
||||||
builder.withValue(Events.ORIGINAL_INSTANCE_TIME, date.getTime());
|
builder.withValue(Events.ORIGINAL_INSTANCE_TIME, date.getTime());
|
||||||
builder.withValue(Events.ORIGINAL_ALL_DAY, originalAllDay ? 1 : 0);
|
builder.withValue(Events.ORIGINAL_ALL_DAY, originalAllDay ? 1 : 0);
|
||||||
|
|
||||||
|
/* TODO reminders and attendees for exceptions are currently not built because
|
||||||
|
* there's no backref index available */
|
||||||
|
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("InlinedApi")
|
@SuppressLint("InlinedApi")
|
||||||
protected Builder buildAttendee(Builder builder, Attendee attendee) {
|
protected Builder buildAttendee(Builder builder, Attendee attendee) {
|
||||||
final Uri member = Uri.parse(attendee.getValue());
|
final URI member = attendee.getCalAddress();
|
||||||
if ("mailto".equalsIgnoreCase(member.getScheme()))
|
if ("mailto".equalsIgnoreCase(member.getScheme()))
|
||||||
// attendee identified by email
|
// attendee identified by email
|
||||||
builder = builder.withValue(Attendees.ATTENDEE_EMAIL, member.getSchemeSpecificPart());
|
builder = builder.withValue(Attendees.ATTENDEE_EMAIL, member.getSchemeSpecificPart());
|
||||||
@ -760,7 +763,6 @@ public class LocalCalendar extends LocalCollection<Event> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Log.d(TAG, "Adding alarm " + minutes + " minutes before");
|
Log.d(TAG, "Adding alarm " + minutes + " minutes before");
|
||||||
|
|
||||||
return builder
|
return builder
|
||||||
.withValue(Reminders.METHOD, Reminders.METHOD_ALERT)
|
.withValue(Reminders.METHOD, Reminders.METHOD_ALERT)
|
||||||
.withValue(Reminders.MINUTES, minutes);
|
.withValue(Reminders.MINUTES, minutes);
|
||||||
|
@ -23,6 +23,7 @@ import at.bitfire.davdroid.resource.Resource;
|
|||||||
import at.bitfire.davdroid.resource.WebDavCollection;
|
import at.bitfire.davdroid.resource.WebDavCollection;
|
||||||
import at.bitfire.davdroid.webdav.ConflictException;
|
import at.bitfire.davdroid.webdav.ConflictException;
|
||||||
import at.bitfire.davdroid.webdav.DavException;
|
import at.bitfire.davdroid.webdav.DavException;
|
||||||
|
import at.bitfire.davdroid.webdav.ForbiddenException;
|
||||||
import at.bitfire.davdroid.webdav.HttpException;
|
import at.bitfire.davdroid.webdav.HttpException;
|
||||||
import at.bitfire.davdroid.webdav.NotFoundException;
|
import at.bitfire.davdroid.webdav.NotFoundException;
|
||||||
import at.bitfire.davdroid.webdav.PreconditionFailedException;
|
import at.bitfire.davdroid.webdav.PreconditionFailedException;
|
||||||
@ -119,11 +120,10 @@ public class SyncManager {
|
|||||||
remote.delete(res);
|
remote.delete(res);
|
||||||
} catch(NotFoundException e) {
|
} catch(NotFoundException e) {
|
||||||
Log.i(TAG, "Locally-deleted resource has already been removed from server");
|
Log.i(TAG, "Locally-deleted resource has already been removed from server");
|
||||||
} catch(PreconditionFailedException e) {
|
} catch(PreconditionFailedException|ConflictException e) {
|
||||||
Log.i(TAG, "Locally-deleted resource has been changed on the server in the meanwhile");
|
Log.i(TAG, "Locally-deleted resource has been changed on the server in the meanwhile");
|
||||||
}
|
}
|
||||||
|
|
||||||
// always delete locally so that the record with the DELETED flag doesn't cause another deletion attempt
|
|
||||||
local.delete(res);
|
local.delete(res);
|
||||||
|
|
||||||
count++;
|
count++;
|
||||||
@ -149,7 +149,7 @@ public class SyncManager {
|
|||||||
local.updateETag(res, eTag);
|
local.updateETag(res, eTag);
|
||||||
local.clearDirty(res);
|
local.clearDirty(res);
|
||||||
count++;
|
count++;
|
||||||
} catch (PreconditionFailedException|ConflictException e) {
|
} catch (ConflictException|PreconditionFailedException e) {
|
||||||
Log.i(TAG, "Didn't overwrite existing resource with other content");
|
Log.i(TAG, "Didn't overwrite existing resource with other content");
|
||||||
} catch (RecordNotFoundException e) {
|
} catch (RecordNotFoundException e) {
|
||||||
Log.wtf(TAG, "Couldn't read new record", e);
|
Log.wtf(TAG, "Couldn't read new record", e);
|
||||||
@ -173,8 +173,10 @@ public class SyncManager {
|
|||||||
local.updateETag(res, eTag);
|
local.updateETag(res, eTag);
|
||||||
local.clearDirty(res);
|
local.clearDirty(res);
|
||||||
count++;
|
count++;
|
||||||
} catch (PreconditionFailedException|ConflictException e) {
|
} catch (ForbiddenException e) {
|
||||||
Log.i(TAG, "Locally changed resource has been changed on the server in the meanwhile");
|
Log.w(TAG, "Server has rejected local changes, server wins", e);
|
||||||
|
} catch (ConflictException|PreconditionFailedException e) {
|
||||||
|
Log.i(TAG, "Locally changed resource has been changed on the server in the meanwhile", e);
|
||||||
} catch (RecordNotFoundException e) {
|
} catch (RecordNotFoundException e) {
|
||||||
Log.e(TAG, "Couldn't read dirty record", e);
|
Log.e(TAG, "Couldn't read dirty record", e);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2013 – 2015 Ricki Hirner (bitfire web engineering).
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the GNU Public License v3.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.gnu.org/licenses/gpl.html
|
||||||
|
*/
|
||||||
|
|
||||||
|
package at.bitfire.davdroid.webdav;
|
||||||
|
|
||||||
|
import org.apache.http.HttpStatus;
|
||||||
|
|
||||||
|
public class ForbiddenException extends HttpException {
|
||||||
|
private static final long serialVersionUID = 102282229174086113L;
|
||||||
|
|
||||||
|
public ForbiddenException(String reason) {
|
||||||
|
super(HttpStatus.SC_FORBIDDEN, reason);
|
||||||
|
}
|
||||||
|
}
|
@ -345,6 +345,8 @@ public class WebDavResource {
|
|||||||
switch (code) {
|
switch (code) {
|
||||||
case HttpStatus.SC_UNAUTHORIZED:
|
case HttpStatus.SC_UNAUTHORIZED:
|
||||||
throw new NotAuthorizedException(reason);
|
throw new NotAuthorizedException(reason);
|
||||||
|
case HttpStatus.SC_FORBIDDEN:
|
||||||
|
throw new ForbiddenException(reason);
|
||||||
case HttpStatus.SC_NOT_FOUND:
|
case HttpStatus.SC_NOT_FOUND:
|
||||||
throw new NotFoundException(reason);
|
throw new NotFoundException(reason);
|
||||||
case HttpStatus.SC_CONFLICT:
|
case HttpStatus.SC_CONFLICT:
|
||||||
|
@ -76,7 +76,7 @@
|
|||||||
<a href="http://davdroid.bitfire.at/donate?pk_campaign=davdroid-app&pk_kwd=main-activity">für DAVdroid spenden</a> oder die App kaufen.</p>
|
<a href="http://davdroid.bitfire.at/donate?pk_campaign=davdroid-app&pk_kwd=main-activity">für DAVdroid spenden</a> oder die App kaufen.</p>
|
||||||
|
|
||||||
<h1>Lizenz</h1>
|
<h1>Lizenz</h1>
|
||||||
<p>Copyright © 2013 – 2014 Ricki Hirner, Bernhard Stockmann (<a href="http://www.bitfire.at">bitfire web engineering</a>), alle Rechte
|
<p>Copyright © 2013 – 2015 Ricki Hirner, Bernhard Stockmann (<a href="http://www.bitfire.at">bitfire web engineering</a>), alle Rechte
|
||||||
vorbehalten. Dieses Programm ist freie Software. Sie können es unter den Bedingungen der <a href="http://www.gnu.org/licenses/gpl.html">GNU
|
vorbehalten. Dieses Programm ist freie Software. Sie können es unter den Bedingungen der <a href="http://www.gnu.org/licenses/gpl.html">GNU
|
||||||
General Public License Version 3</a>, wie von der Free Software Foundation veröffentlicht, weitergeben und/oder modifizieren.
|
General Public License Version 3</a>, wie von der Free Software Foundation veröffentlicht, weitergeben und/oder modifizieren.
|
||||||
Sofern Google Play oder Samsung Store andere Bedingungen benötigen, gelten für über den jeweiligen Markt heruntergeladene
|
Sofern Google Play oder Samsung Store andere Bedingungen benötigen, gelten für über den jeweiligen Markt heruntergeladene
|
||||||
|
Loading…
Reference in New Issue
Block a user