package com.hdweiss.morgand.synchronizer.calendar; import android.content.Context; import android.content.SharedPreferences; import android.database.Cursor; import android.preference.PreferenceManager; import android.text.TextUtils; import android.util.Log; import com.hdweiss.morgand.Application; import com.hdweiss.morgand.data.OrgCalendarEntry; import com.hdweiss.morgand.data.dao.OrgNode; import com.hdweiss.morgand.data.dao.OrgNodeRepository; import com.hdweiss.morgand.events.DataUpdatedEvent; import com.hdweiss.morgand.settings.PreferenceUtils; import com.hdweiss.morgand.utils.MultiMap; import com.hdweiss.morgand.utils.SafeAsyncTask; import java.util.HashSet; import java.util.List; public class SyncCalendarTask extends SafeAsyncTask<String, DataUpdatedEvent, Void> { private CalendarWrapper calendarWrapper; private HashSet<String> inactiveTodoKeywords = new HashSet<String>(); private boolean showDone = true; private boolean showPast = true; private boolean showHabits = true; private boolean pullEnabled = false; private boolean pullDelete = false; private int inserted = 0; private int deleted = 0; private int unchanged = 0; public SyncCalendarTask(Context context) { super(context, ReportMode.Log); this.calendarWrapper = new CalendarWrapper(context); refreshPreferences(); } @Override protected Void safeDoInBackground(String... files) throws Exception { Log.d("Calendar", "Started synchronization"); if (files.length == 0) { Log.d("Calendar", "No modified files"); } for(String file: files) syncFileSchedule(file); if (pullEnabled) // TODO complete assimilate Calendar (implement function that delivers default capture node) ;//assimilateCalendar(); Log.d("Calendar", "Ended synchronization"); return null; } @Override protected void onProgressUpdate(DataUpdatedEvent... events) { for(DataUpdatedEvent event: events) Application.getBus().post(event); } private void syncFileSchedule(String filename) { inserted = 0; deleted = 0; unchanged = 0; MultiMap<CalendarEntry> entries = getCalendarEntries(filename); List<OrgNode> nodes = OrgNodeRepository.getScheduledNodes(filename, showHabits); Log.d("Calendar", filename + " has " + nodes.size() + " calendar entries"); for(OrgNode node: nodes) { for(OrgCalendarEntry date: node.getOrgNodeDates()) { if (shouldInsertEntry(date, node)) createOrUpdateEntry(entries, date, filename, node); } } removeCalendarEntries(entries); Log.d("Calendar", "Calendar (" + filename + ") Inserted: " + inserted + " and deleted: " + deleted + ", unchanged: " + unchanged); } private void createOrUpdateEntry(MultiMap<CalendarEntry> entries, OrgCalendarEntry date, String filename, OrgNode node) { CalendarEntry insertedEntry = entries.findValue(date.beginTime, date); if (insertedEntry != null && insertedEntry.title.equals(date.getCalendarTitle())) { entries.remove(date.beginTime, insertedEntry); unchanged++; } else { calendarWrapper.insertEntry(date, node.getBody(), filename, node.getProperty("LOCATION"), node.getProperty("BUSY")); inserted++; } } private boolean shouldInsertEntry(OrgCalendarEntry date, OrgNode node) { String todo = node.getTodo(); if (this.showDone == false && TextUtils.isEmpty(todo) == false && inactiveTodoKeywords.contains(todo)) return false; if (this.showPast == false && date.isInPast()) return false; if (this.showHabits == false && "habit".equals(node.getProperty("STYLE"))) return false; return true; } private MultiMap<CalendarEntry> getCalendarEntries(String filename) { Cursor query = calendarWrapper.getCalendarCursor(filename); CalendarEntriesParser entriesParser = new CalendarEntriesParser(query); MultiMap<CalendarEntry> map = new MultiMap<CalendarEntry>(); while (query.isAfterLast() == false) { CalendarEntry entry = entriesParser.getEntryFromCursor(query); map.put(entry.dtStart, entry); query.moveToNext(); } query.close(); return map; } private void removeCalendarEntries(MultiMap<CalendarEntry> entries) { for (Long entryKey : entries.keySet()) { for (CalendarEntry entry : entries.get(entryKey)) { calendarWrapper.deleteEntry(entry); deleted++; } } } private void assimilateCalendar() { Cursor query = calendarWrapper.getUnassimilatedCalendarCursor(); CalendarEntriesParser entriesParser = new CalendarEntriesParser(query); while(query.isAfterLast() == false) { CalendarEntry entry = entriesParser.getEntryFromCursor(query); OrgNode captureNode = OrgNodeRepository.getDefaultCaptureNode(); entry.writeToOrgNodes(captureNode); if (this.pullDelete) calendarWrapper.deleteEntry(entry); query.moveToNext(); } query.close(); publishProgress(new DataUpdatedEvent()); } private void refreshPreferences() { SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context); this.pullEnabled = sharedPreferences.getBoolean("calendar_pull", false); this.pullDelete = sharedPreferences.getBoolean("calendar_pull_delete", false); this.showDone = sharedPreferences.getBoolean("calendar_show_done", true); this.showPast = sharedPreferences.getBoolean("calendar_show_past", true); this.showHabits = sharedPreferences.getBoolean("calendar_habits", true); this.inactiveTodoKeywords = PreferenceUtils.getInactiveTodoKeywords(); this.calendarWrapper.refreshPreferences(); } }