* added server path to account name to allow Baïkal CalDAV+CardDAV setup as two accounts
* enabled relaxed iCal parsing/unfolding for better compatibility
* fixed crash bug for .ics files that don't contain events
* fixed bug where all events where deleted locally when using multiple calendars
pull/2/head
rfc2822 11 years ago
parent 62ed38ee4f
commit 5d3ef61b77

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="at.bitfire.davdroid"
android:versionCode="3"
android:versionName="0.3-alpha" >
android:versionCode="4"
android:versionName="0.3.1-alpha" >
<uses-sdk
android:minSdkVersion="14"

@ -16,10 +16,12 @@ import java.util.SimpleTimeZone;
import java.util.TimeZone;
import lombok.Getter;
import lombok.NonNull;
import lombok.Setter;
import net.fortuna.ical4j.data.CalendarBuilder;
import net.fortuna.ical4j.data.ParserException;
import net.fortuna.ical4j.model.Component;
import net.fortuna.ical4j.model.ComponentList;
import net.fortuna.ical4j.model.Date;
import net.fortuna.ical4j.model.DateTime;
import net.fortuna.ical4j.model.DefaultTimeZoneRegistryFactory;
@ -90,19 +92,17 @@ public class Event extends Resource {
@Override
public void parseEntity(InputStream entity) throws IOException, ParserException {
if (entity == null)
return;
public void parseEntity(@NonNull InputStream entity) throws IOException, ParserException {
CalendarBuilder builder = new CalendarBuilder();
net.fortuna.ical4j.model.Calendar ical = builder.build(entity);
if (ical == null)
return;
// event
VEvent event = (VEvent) ical.getComponents(Component.VEVENT).get(0);
if (event == null)
ComponentList events = ical.getComponents(Component.VEVENT);
if (events == null || events.isEmpty())
return;
VEvent event = (VEvent)events.get(0);
if (event.getUid() != null)
uid = event.getUid().toString();

@ -15,6 +15,9 @@ import java.util.List;
import net.fortuna.ical4j.vcard.Parameter.Id;
import net.fortuna.ical4j.vcard.parameter.Type;
import net.fortuna.ical4j.vcard.property.Telephone;
import org.apache.commons.lang.StringUtils;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.content.ContentProviderClient;
@ -22,6 +25,7 @@ import android.content.ContentProviderOperation;
import android.content.ContentProviderOperation.Builder;
import android.content.ContentUris;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.net.Uri;
import android.os.RemoteException;
import android.provider.ContactsContract.CommonDataKinds.Email;
@ -232,6 +236,24 @@ public class LocalAddressBook extends LocalCollection<Contact> {
c.populated = true;
return;
}
public void deleteAllExceptRemoteNames(Resource[] remoteResources) {
String where;
if (remoteResources.length != 0) {
List<String> terms = new LinkedList<String>();
for (Resource res : remoteResources)
terms.add(entryColumnRemoteName() + "<>" + DatabaseUtils.sqlEscapeString(res.getName()));
where = StringUtils.join(terms, " AND ");
} else
where = entryColumnRemoteName() + " IS NOT NULL";
Builder builder = ContentProviderOperation.newDelete(entriesURI()).withSelection(where, null);
pendingOperations.add(builder
.withYieldAllowed(true)
.build());
}
/* private helper methods */

@ -10,6 +10,9 @@ package at.bitfire.davdroid.resource;
import java.net.URISyntaxException;
import java.text.ParseException;
import java.util.LinkedList;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import lombok.Getter;
import net.fortuna.ical4j.model.Parameter;
@ -34,6 +37,7 @@ import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.net.Uri;
import android.os.RemoteException;
import android.provider.CalendarContract;
@ -82,7 +86,7 @@ public class LocalCalendar extends LocalCollection<Event> {
values.put(Calendars.ACCOUNT_TYPE, account.type);
values.put(Calendars.NAME, info.getPath());
values.put(Calendars.CALENDAR_DISPLAY_NAME, info.getTitle());
values.put(Calendars.CALENDAR_COLOR, 0xC3EA6E);
values.put(Calendars.CALENDAR_COLOR, 0xFFC3EA6E);
values.put(Calendars.CALENDAR_ACCESS_LEVEL, Calendars.CAL_ACCESS_OWNER);
values.put(Calendars.ALLOWED_AVAILABILITY, Events.AVAILABILITY_BUSY + "," + Events.AVAILABILITY_FREE + "," + Events.AVAILABILITY_TENTATIVE);
values.put(Calendars.ALLOWED_ATTENDEE_TYPES, Attendees.TYPE_NONE + "," + Attendees.TYPE_REQUIRED + "," + Attendees.TYPE_OPTIONAL + "," + Attendees.TYPE_RESOURCE);
@ -307,6 +311,25 @@ public class LocalCalendar extends LocalCollection<Event> {
}
public void deleteAllExceptRemoteNames(Resource[] remoteResources) {
String where;
if (remoteResources.length != 0) {
List<String> terms = new LinkedList<String>();
for (Resource res : remoteResources)
terms.add(entryColumnRemoteName() + "<>" + DatabaseUtils.sqlEscapeString(res.getName()));
where = StringUtils.join(terms, " AND ");
} else
where = entryColumnRemoteName() + " IS NOT NULL";
Builder builder = ContentProviderOperation.newDelete(entriesURI())
.withSelection(Events.CALENDAR_ID + "=? AND (" + where + ")", new String[] { String.valueOf(id) });
pendingOperations.add(builder
.withYieldAllowed(true)
.build());
}
/* private helper methods */
@Override

@ -29,6 +29,8 @@ import android.os.RemoteException;
import android.provider.CalendarContract;
public abstract class LocalCollection<ResourceType extends Resource> {
//private static final String TAG = "davdroid.LocalCollection";
protected Account account;
protected ContentProviderClient providerClient;
protected ArrayList<ContentProviderOperation> pendingOperations = new ArrayList<ContentProviderOperation>();
@ -147,22 +149,7 @@ public abstract class LocalCollection<ResourceType extends Resource> {
.build());
}
public void deleteAllExceptRemoteNames(Resource[] remoteResources) {
Builder builder = ContentProviderOperation.newDelete(entriesURI());
if (remoteResources.length != 0) {
List<String> terms = new LinkedList<String>();
for (Resource res : remoteResources)
terms.add(entryColumnRemoteName() + "<>" + DatabaseUtils.sqlEscapeString(res.getName()));
String where = StringUtils.join(terms, " AND ");
builder = builder.withSelection(where, new String[] {});
} else
builder = builder.withSelection(entryColumnRemoteName() + " IS NOT NULL", null);
pendingOperations.add(builder
.withYieldAllowed(true)
.build());
}
public abstract void deleteAllExceptRemoteNames(Resource[] remoteResources);
public void clearDirty(Resource resource) {
pendingOperations.add(ContentProviderOperation

@ -132,7 +132,7 @@ public class SelectCollectionsFragment extends ListFragment {
ServerInfo serverInfo = (ServerInfo)getArguments().getSerializable(KEY_SERVER_INFO);
try {
URI baseURI = new URI(serverInfo.getBaseURL());
String accountName = serverInfo.getUserName() + "@" + baseURI.getHost();
String accountName = serverInfo.getUserName() + "@" + baseURI.getHost() + baseURI.getPath();
AccountManager accountManager = AccountManager.get(getActivity());
Account account = new Account(accountName, Constants.ACCOUNT_TYPE);

@ -1 +1,4 @@
ical4j.unfolding.relaxed=true
ical4j.parsing.relaxed=true
ical4j.compatibility.outlook=true

Loading…
Cancel
Save