move the CalDAV related functions away from context extensions

This commit is contained in:
tibbi 2017-08-16 21:38:41 +02:00
parent c0d6beb81f
commit 8f0c8f6018
4 changed files with 185 additions and 170 deletions

View File

@ -14,6 +14,7 @@ import com.simplemobiletools.calendar.dialogs.CustomEventReminderDialog
import com.simplemobiletools.calendar.dialogs.SelectCalendarsDialog import com.simplemobiletools.calendar.dialogs.SelectCalendarsDialog
import com.simplemobiletools.calendar.dialogs.SnoozePickerDialog import com.simplemobiletools.calendar.dialogs.SnoozePickerDialog
import com.simplemobiletools.calendar.extensions.* import com.simplemobiletools.calendar.extensions.*
import com.simplemobiletools.calendar.helpers.CalDAVEventsHandler
import com.simplemobiletools.calendar.helpers.FONT_SIZE_LARGE import com.simplemobiletools.calendar.helpers.FONT_SIZE_LARGE
import com.simplemobiletools.calendar.helpers.FONT_SIZE_MEDIUM import com.simplemobiletools.calendar.helpers.FONT_SIZE_MEDIUM
import com.simplemobiletools.calendar.helpers.FONT_SIZE_SMALL import com.simplemobiletools.calendar.helpers.FONT_SIZE_SMALL
@ -137,7 +138,7 @@ class SettingsActivity : SimpleActivity() {
Thread({ Thread({
if (ids.isNotEmpty()) { if (ids.isNotEmpty()) {
val eventTypeNames = dbHelper.fetchEventTypes().map { it.title.toLowerCase() } as ArrayList<String> val eventTypeNames = dbHelper.fetchEventTypes().map { it.title.toLowerCase() } as ArrayList<String>
val calendars = getCalDAVCalendars(config.caldavSyncedCalendarIDs) val calendars = CalDAVEventsHandler(applicationContext).getCalDAVCalendars(config.caldavSyncedCalendarIDs)
calendars.forEach { calendars.forEach {
if (!eventTypeNames.contains(it.displayName.toLowerCase())) { if (!eventTypeNames.contains(it.displayName.toLowerCase())) {
val eventType = EventType(0, it.displayName, it.color) val eventType = EventType(0, it.displayName, it.color)
@ -148,7 +149,7 @@ class SettingsActivity : SimpleActivity() {
calendars.forEach { calendars.forEach {
val eventTypeId = dbHelper.getEventTypeIdWithTitle(it.displayName) val eventTypeId = dbHelper.getEventTypeIdWithTitle(it.displayName)
fetchCalDAVCalendarEvents(it.id, eventTypeId) CalDAVEventsHandler(applicationContext).fetchCalDAVCalendarEvents(it.id, eventTypeId)
} }
} }
}).start() }).start()

View File

@ -8,7 +8,7 @@ import android.view.ViewGroup
import android.widget.RelativeLayout import android.widget.RelativeLayout
import com.simplemobiletools.calendar.R import com.simplemobiletools.calendar.R
import com.simplemobiletools.calendar.extensions.config import com.simplemobiletools.calendar.extensions.config
import com.simplemobiletools.calendar.extensions.getCalDAVCalendars import com.simplemobiletools.calendar.helpers.CalDAVEventsHandler
import com.simplemobiletools.commons.extensions.setupDialogStuff import com.simplemobiletools.commons.extensions.setupDialogStuff
import kotlinx.android.synthetic.main.calendar_item_account.view.* import kotlinx.android.synthetic.main.calendar_item_account.view.*
import kotlinx.android.synthetic.main.calendar_item_calendar.view.* import kotlinx.android.synthetic.main.calendar_item_calendar.view.*
@ -21,7 +21,7 @@ class SelectCalendarsDialog(val activity: Activity, val callback: () -> Unit) :
init { init {
val ids = activity.config.caldavSyncedCalendarIDs.split(",").filter { it.trim().isNotEmpty() } as ArrayList<String> val ids = activity.config.caldavSyncedCalendarIDs.split(",").filter { it.trim().isNotEmpty() } as ArrayList<String>
val calendars = activity.getCalDAVCalendars() val calendars = CalDAVEventsHandler(activity).getCalDAVCalendars()
val sorted = calendars.sortedWith(compareBy({ it.accountName }, { it.displayName })) val sorted = calendars.sortedWith(compareBy({ it.accountName }, { it.displayName }))
sorted.forEach { sorted.forEach {
if (prevAccount != it.accountName) { if (prevAccount != it.accountName) {

View File

@ -8,26 +8,24 @@ import android.app.NotificationManager
import android.app.PendingIntent import android.app.PendingIntent
import android.appwidget.AppWidgetManager import android.appwidget.AppWidgetManager
import android.content.ComponentName import android.content.ComponentName
import android.content.ContentValues
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.database.Cursor
import android.graphics.Color import android.graphics.Color
import android.net.Uri import android.net.Uri
import android.os.Build import android.os.Build
import android.provider.CalendarContract
import android.support.v4.content.ContextCompat import android.support.v4.content.ContextCompat
import android.support.v7.app.NotificationCompat import android.support.v7.app.NotificationCompat
import com.simplemobiletools.calendar.R import com.simplemobiletools.calendar.R
import com.simplemobiletools.calendar.activities.EventActivity import com.simplemobiletools.calendar.activities.EventActivity
import com.simplemobiletools.calendar.helpers.* import com.simplemobiletools.calendar.helpers.*
import com.simplemobiletools.calendar.helpers.Formatter import com.simplemobiletools.calendar.helpers.Formatter
import com.simplemobiletools.calendar.models.CalDAVCalendar
import com.simplemobiletools.calendar.models.Event import com.simplemobiletools.calendar.models.Event
import com.simplemobiletools.calendar.receivers.NotificationReceiver import com.simplemobiletools.calendar.receivers.NotificationReceiver
import com.simplemobiletools.calendar.services.SnoozeService import com.simplemobiletools.calendar.services.SnoozeService
import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.extensions.getContrastColor
import com.simplemobiletools.commons.extensions.isKitkatPlus
import com.simplemobiletools.commons.extensions.isLollipopPlus
import org.joda.time.DateTime import org.joda.time.DateTime
import org.joda.time.DateTimeZone import org.joda.time.DateTimeZone
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
@ -232,167 +230,6 @@ fun Context.launchNewEventIntent(startNewTask: Boolean = false, today: Boolean =
} }
} }
fun Context.getCalDAVCalendars(ids: String = ""): List<CalDAVCalendar> {
val calendars = ArrayList<CalDAVCalendar>()
if (!hasCalendarPermission()) {
return calendars
}
dbHelper.fetchEventTypes()
val uri = CalendarContract.Calendars.CONTENT_URI
val projection = arrayOf(
CalendarContract.Calendars._ID,
CalendarContract.Calendars.CALENDAR_DISPLAY_NAME,
CalendarContract.Calendars.ACCOUNT_NAME,
CalendarContract.Calendars.OWNER_ACCOUNT,
CalendarContract.Calendars.CALENDAR_COLOR)
val selection = if (ids.trim().isNotEmpty()) "${CalendarContract.Calendars._ID} IN ($ids)" else null
var cursor: Cursor? = null
try {
cursor = contentResolver.query(uri, projection, selection, null, null)
if (cursor != null && cursor.moveToFirst()) {
do {
val id = cursor.getLongValue(CalendarContract.Calendars._ID)
val displayName = cursor.getStringValue(CalendarContract.Calendars.CALENDAR_DISPLAY_NAME)
val accountName = cursor.getStringValue(CalendarContract.Calendars.ACCOUNT_NAME)
val ownerName = cursor.getStringValue(CalendarContract.Calendars.OWNER_ACCOUNT)
val color = cursor.getIntValue(CalendarContract.Calendars.CALENDAR_COLOR)
val calendar = CalDAVCalendar(id, displayName, accountName, ownerName, color)
calendars.add(calendar)
} while (cursor.moveToNext())
}
} finally {
cursor?.close()
}
return calendars
}
fun Context.fetchCalDAVCalendarEvents(calendarId: Long, eventTypeId: Int) {
val importIdsMap = HashMap<String, Event>()
val existingEvents = dbHelper.getEventsFromCalDAVCalendar(calendarId)
existingEvents.forEach {
importIdsMap.put(it.importId, it)
}
val uri = CalendarContract.Events.CONTENT_URI
val projection = arrayOf(
CalendarContract.Events._ID,
CalendarContract.Events.TITLE,
CalendarContract.Events.DESCRIPTION,
CalendarContract.Events.DTSTART,
CalendarContract.Events.DTEND,
CalendarContract.Events.DURATION,
CalendarContract.Events.ALL_DAY,
CalendarContract.Events.RRULE)
val selection = "${CalendarContract.Events.CALENDAR_ID} = $calendarId"
var cursor: Cursor? = null
try {
cursor = contentResolver.query(uri, projection, selection, null, null)
if (cursor != null && cursor.moveToFirst()) {
do {
val id = cursor.getLongValue(CalendarContract.Events._ID)
val title = cursor.getStringValue(CalendarContract.Events.TITLE) ?: continue
val description = cursor.getStringValue(CalendarContract.Events.DESCRIPTION)
val startTS = (cursor.getLongValue(CalendarContract.Events.DTSTART) / 1000).toInt()
var endTS = (cursor.getLongValue(CalendarContract.Events.DTEND) / 1000).toInt()
val allDay = cursor.getIntValue(CalendarContract.Events.ALL_DAY)
val rrule = cursor.getStringValue(CalendarContract.Events.RRULE) ?: ""
val reminders = getCalDAVEventReminders(id)
if (endTS == 0) {
val duration = cursor.getStringValue(CalendarContract.Events.DURATION)
endTS = startTS + Parser().parseDuration(duration)
}
val importId = getCalDAVEventImportId(calendarId, id)
val repeatRule = Parser().parseRepeatInterval(rrule, startTS)
val event = Event(0, startTS, endTS, title, description, reminders.getOrElse(0, { -1 }),
reminders.getOrElse(1, { -1 }), reminders.getOrElse(2, { -1 }), repeatRule.repeatInterval,
importId, allDay, repeatRule.repeatLimit, repeatRule.repeatRule, eventTypeId, source = "$CALDAV-$calendarId")
if (event.getIsAllDay() && endTS > startTS) {
event.endTS -= DAY
}
if (importIdsMap.containsKey(event.importId)) {
val existingEvent = importIdsMap[importId]
val originalEventId = existingEvent!!.id
existingEvent.id = 0
if (existingEvent.hashCode() != event.hashCode()) {
event.id = originalEventId
dbHelper.update(event) {
}
}
} else {
dbHelper.insert(event, false) {
importIdsMap.put(event.importId, event)
}
}
} while (cursor.moveToNext())
}
} finally {
cursor?.close()
}
}
fun Context.addCalDAVEvent(event: Event, calendarId: Long) {
val durationMinutes = (event.endTS - event.startTS) / 1000 / 60
val uri = CalendarContract.Events.CONTENT_URI
val values = ContentValues().apply {
put(CalendarContract.Events.CALENDAR_ID, calendarId)
put(CalendarContract.Events.TITLE, event.title)
put(CalendarContract.Events.DESCRIPTION, event.description)
put(CalendarContract.Events.DTSTART, event.startTS * 1000L)
put(CalendarContract.Events.ALL_DAY, if (event.getIsAllDay()) 1 else 0)
put(CalendarContract.Events.RRULE, Parser().getShortRepeatInterval(event))
put(CalendarContract.Events.EVENT_TIMEZONE, TimeZone.getDefault().toString())
if (event.getIsAllDay() && event.endTS > event.startTS)
event.endTS += DAY
if (event.repeatInterval > 0) {
put(CalendarContract.Events.DURATION, Parser().getDurationString(durationMinutes))
} else {
put(CalendarContract.Events.DTEND, event.endTS * 1000L)
}
}
val newUri = contentResolver.insert(uri, values)
val eventRemoteID = java.lang.Long.parseLong(newUri.lastPathSegment)
val importId = getCalDAVEventImportId(calendarId, eventRemoteID)
dbHelper.updateEventImportIdAndSource(event.id, importId, "$CALDAV-$calendarId")
}
fun Context.getCalDAVEventReminders(eventId: Long): List<Int> {
val reminders = ArrayList<Int>()
val uri = CalendarContract.Reminders.CONTENT_URI
val projection = arrayOf(
CalendarContract.Reminders.MINUTES,
CalendarContract.Reminders.METHOD)
val selection = "${CalendarContract.Reminders.EVENT_ID} = $eventId"
var cursor: Cursor? = null
try {
cursor = contentResolver.query(uri, projection, selection, null, null)
if (cursor != null && cursor.moveToFirst()) {
do {
val minutes = cursor.getIntValue(CalendarContract.Reminders.MINUTES)
val method = cursor.getIntValue(CalendarContract.Reminders.METHOD)
if (method == CalendarContract.Reminders.METHOD_ALERT) {
reminders.add(minutes)
}
} while (cursor.moveToNext())
}
} finally {
cursor?.close()
}
return reminders
}
fun Context.getCalDAVEventImportId(calendarId: Long, eventId: Long) = "$CALDAV-$calendarId-$eventId"
fun Context.getNewEventTimestampFromCode(dayCode: String) = Formatter.getLocalDateTimeFromCode(dayCode).withTime(13, 0, 0, 0).seconds() fun Context.getNewEventTimestampFromCode(dayCode: String) = Formatter.getLocalDateTimeFromCode(dayCode).withTime(13, 0, 0, 0).seconds()
fun Context.getCurrentOffset() = SimpleDateFormat("Z", Locale.getDefault()).format(Date()) fun Context.getCurrentOffset() = SimpleDateFormat("Z", Locale.getDefault()).format(Date())

View File

@ -0,0 +1,177 @@
package com.simplemobiletools.calendar.helpers
import android.content.ContentValues
import android.content.Context
import android.database.Cursor
import android.provider.CalendarContract
import com.simplemobiletools.calendar.extensions.dbHelper
import com.simplemobiletools.calendar.extensions.hasCalendarPermission
import com.simplemobiletools.calendar.models.CalDAVCalendar
import com.simplemobiletools.calendar.models.Event
import com.simplemobiletools.commons.extensions.getIntValue
import com.simplemobiletools.commons.extensions.getLongValue
import com.simplemobiletools.commons.extensions.getStringValue
import java.util.*
class CalDAVEventsHandler(val context: Context) {
fun getCalDAVCalendars(ids: String = ""): List<CalDAVCalendar> {
val calendars = ArrayList<CalDAVCalendar>()
if (!context.hasCalendarPermission()) {
return calendars
}
context.dbHelper.fetchEventTypes()
val uri = CalendarContract.Calendars.CONTENT_URI
val projection = arrayOf(
CalendarContract.Calendars._ID,
CalendarContract.Calendars.CALENDAR_DISPLAY_NAME,
CalendarContract.Calendars.ACCOUNT_NAME,
CalendarContract.Calendars.OWNER_ACCOUNT,
CalendarContract.Calendars.CALENDAR_COLOR)
val selection = if (ids.trim().isNotEmpty()) "${CalendarContract.Calendars._ID} IN ($ids)" else null
var cursor: Cursor? = null
try {
cursor = context.contentResolver.query(uri, projection, selection, null, null)
if (cursor != null && cursor.moveToFirst()) {
do {
val id = cursor.getLongValue(CalendarContract.Calendars._ID)
val displayName = cursor.getStringValue(CalendarContract.Calendars.CALENDAR_DISPLAY_NAME)
val accountName = cursor.getStringValue(CalendarContract.Calendars.ACCOUNT_NAME)
val ownerName = cursor.getStringValue(CalendarContract.Calendars.OWNER_ACCOUNT)
val color = cursor.getIntValue(CalendarContract.Calendars.CALENDAR_COLOR)
val calendar = CalDAVCalendar(id, displayName, accountName, ownerName, color)
calendars.add(calendar)
} while (cursor.moveToNext())
}
} finally {
cursor?.close()
}
return calendars
}
fun fetchCalDAVCalendarEvents(calendarId: Long, eventTypeId: Int) {
val importIdsMap = HashMap<String, Event>()
val existingEvents = context.dbHelper.getEventsFromCalDAVCalendar(calendarId)
existingEvents.forEach {
importIdsMap.put(it.importId, it)
}
val uri = CalendarContract.Events.CONTENT_URI
val projection = arrayOf(
CalendarContract.Events._ID,
CalendarContract.Events.TITLE,
CalendarContract.Events.DESCRIPTION,
CalendarContract.Events.DTSTART,
CalendarContract.Events.DTEND,
CalendarContract.Events.DURATION,
CalendarContract.Events.ALL_DAY,
CalendarContract.Events.RRULE)
val selection = "${CalendarContract.Events.CALENDAR_ID} = $calendarId"
var cursor: Cursor? = null
try {
cursor = context.contentResolver.query(uri, projection, selection, null, null)
if (cursor != null && cursor.moveToFirst()) {
do {
val id = cursor.getLongValue(CalendarContract.Events._ID)
val title = cursor.getStringValue(CalendarContract.Events.TITLE) ?: continue
val description = cursor.getStringValue(CalendarContract.Events.DESCRIPTION)
val startTS = (cursor.getLongValue(CalendarContract.Events.DTSTART) / 1000).toInt()
var endTS = (cursor.getLongValue(CalendarContract.Events.DTEND) / 1000).toInt()
val allDay = cursor.getIntValue(CalendarContract.Events.ALL_DAY)
val rrule = cursor.getStringValue(CalendarContract.Events.RRULE) ?: ""
val reminders = getCalDAVEventReminders(id)
if (endTS == 0) {
val duration = cursor.getStringValue(CalendarContract.Events.DURATION)
endTS = startTS + Parser().parseDuration(duration)
}
val importId = getCalDAVEventImportId(calendarId, id)
val repeatRule = Parser().parseRepeatInterval(rrule, startTS)
val event = Event(0, startTS, endTS, title, description, reminders.getOrElse(0, { -1 }),
reminders.getOrElse(1, { -1 }), reminders.getOrElse(2, { -1 }), repeatRule.repeatInterval,
importId, allDay, repeatRule.repeatLimit, repeatRule.repeatRule, eventTypeId, source = "$CALDAV-$calendarId")
if (event.getIsAllDay() && endTS > startTS) {
event.endTS -= DAY
}
if (importIdsMap.containsKey(event.importId)) {
val existingEvent = importIdsMap[importId]
val originalEventId = existingEvent!!.id
existingEvent.id = 0
if (existingEvent.hashCode() != event.hashCode()) {
event.id = originalEventId
context.dbHelper.update(event) {
}
}
} else {
context.dbHelper.insert(event, false) {
importIdsMap.put(event.importId, event)
}
}
} while (cursor.moveToNext())
}
} finally {
cursor?.close()
}
}
fun addCalDAVEvent(event: Event, calendarId: Long) {
val durationMinutes = (event.endTS - event.startTS) / 1000 / 60
val uri = CalendarContract.Events.CONTENT_URI
val values = ContentValues().apply {
put(CalendarContract.Events.CALENDAR_ID, calendarId)
put(CalendarContract.Events.TITLE, event.title)
put(CalendarContract.Events.DESCRIPTION, event.description)
put(CalendarContract.Events.DTSTART, event.startTS * 1000L)
put(CalendarContract.Events.ALL_DAY, if (event.getIsAllDay()) 1 else 0)
put(CalendarContract.Events.RRULE, Parser().getShortRepeatInterval(event))
put(CalendarContract.Events.EVENT_TIMEZONE, TimeZone.getDefault().toString())
if (event.getIsAllDay() && event.endTS > event.startTS)
event.endTS += DAY
if (event.repeatInterval > 0) {
put(CalendarContract.Events.DURATION, Parser().getDurationString(durationMinutes))
} else {
put(CalendarContract.Events.DTEND, event.endTS * 1000L)
}
}
val newUri = context.contentResolver.insert(uri, values)
val eventRemoteID = java.lang.Long.parseLong(newUri.lastPathSegment)
val importId = getCalDAVEventImportId(calendarId, eventRemoteID)
context.dbHelper.updateEventImportIdAndSource(event.id, importId, "$CALDAV-$calendarId")
}
fun getCalDAVEventReminders(eventId: Long): List<Int> {
val reminders = ArrayList<Int>()
val uri = CalendarContract.Reminders.CONTENT_URI
val projection = arrayOf(
CalendarContract.Reminders.MINUTES,
CalendarContract.Reminders.METHOD)
val selection = "${CalendarContract.Reminders.EVENT_ID} = $eventId"
var cursor: Cursor? = null
try {
cursor = context.contentResolver.query(uri, projection, selection, null, null)
if (cursor != null && cursor.moveToFirst()) {
do {
val minutes = cursor.getIntValue(CalendarContract.Reminders.MINUTES)
val method = cursor.getIntValue(CalendarContract.Reminders.METHOD)
if (method == CalendarContract.Reminders.METHOD_ALERT) {
reminders.add(minutes)
}
} while (cursor.moveToNext())
}
} finally {
cursor?.close()
}
return reminders
}
fun getCalDAVEventImportId(calendarId: Long, eventId: Long) = "$CALDAV-$calendarId-$eventId"
}