Skip to content

Commit

Permalink
Duplicate detection in calendar export, hidden "delete local calendar…
Browse files Browse the repository at this point in the history
…" function
  • Loading branch information
m-i-n-a-r committed Aug 15, 2024
1 parent 6808bb0 commit 58bc70b
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,22 @@ import com.minar.birday.activities.MainActivity
import com.minar.birday.model.EventResult
import com.minar.birday.utilities.addEvent
import com.minar.birday.utilities.createOrGetCalendar
import com.minar.birday.utilities.deleteLocalCalendar
import com.minar.birday.utilities.formatName
import com.minar.birday.utilities.getStringForTypeCodename
import java.time.ZoneId
import java.time.ZoneOffset
import kotlin.concurrent.thread


class CalendarExporter(context: Context, attrs: AttributeSet?) : Preference(context, attrs),
View.OnClickListener {
View.OnClickListener, View.OnLongClickListener {

override fun onBindViewHolder(holder: PreferenceViewHolder) {
super.onBindViewHolder(holder)
val v = holder.itemView
v.setOnClickListener(this)
v.setOnLongClickListener(this)
}

override fun onClick(v: View) {
Expand Down Expand Up @@ -88,7 +91,9 @@ class CalendarExporter(context: Context, attrs: AttributeSet?) : Preference(cont
try {
// Always first name first, to simplify a bit, plus the event type
for (event in events) {
val eventName = formatName(event, false) + "- ${
val startDate =
event.originalDate.atStartOfDay().toInstant(ZoneOffset.UTC).toEpochMilli()
val eventName = formatName(event, false) + " - ${
getStringForTypeCodename(
context,
event.type!!
Expand All @@ -99,8 +104,7 @@ class CalendarExporter(context: Context, attrs: AttributeSet?) : Preference(cont
calendarId,
eventName,
event.notes,
event.originalDate.atStartOfDay(ZoneId.systemDefault()).toInstant()
.toEpochMilli()
startDate
)
}
return true
Expand All @@ -109,4 +113,13 @@ class CalendarExporter(context: Context, attrs: AttributeSet?) : Preference(cont
return false
}
}

// Delete the local calendar on long click
override fun onLongClick(p0: View?): Boolean {
val act = context as MainActivity
act.vibrate()
deleteLocalCalendar(context, context.getString(R.string.events_notification_channel))
act.showSnackbar(context.getString(R.string.deleted))
return true
}
}
52 changes: 52 additions & 0 deletions app/src/main/java/com/minar/birday/utilities/CalendarUtils.kt
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
package com.minar.birday.utilities

import android.content.ContentResolver
import android.content.ContentUris
import android.content.ContentValues
import android.content.Context
import android.database.Cursor
import android.net.Uri
import android.provider.CalendarContract
import android.util.Log
import com.minar.birday.R
import java.time.LocalDate
import java.util.TimeZone
import java.util.concurrent.TimeUnit

Expand Down Expand Up @@ -80,6 +86,7 @@ fun addEvent(
description: String? = "",
startTime: Long
): Long {
Log.d("export", "Exporting to calendar: $title with start time $startTime")
val values = ContentValues().apply {
put(CalendarContract.Events.DTSTART, startTime)
put(CalendarContract.Events.DTEND, startTime + TimeUnit.DAYS.toMillis(1))
Expand All @@ -91,11 +98,56 @@ fun addEvent(
put(CalendarContract.Events.ALL_DAY, 1)
put(CalendarContract.Events.RRULE, "FREQ=YEARLY") // Yearly, of course
}
// Stop if the event already exists
if (isEventDuplicate(context, title, startTime)) {
Log.d("export", "Duplicate found in calendar: $title")
return -1
}

// Else insert it and return its ID
val uri = context.contentResolver.insert(CalendarContract.Events.CONTENT_URI, values)
return uri?.lastPathSegment?.toLong() ?: -1
}

// Check if an event is already in the calendar by name and date. Naive, but whatever
fun isEventDuplicate(
context: Context,
title: String,
eventStartTime: Long
): Boolean {
val resolver: ContentResolver = context.contentResolver
val uri: Uri = CalendarContract.Events.CONTENT_URI
val selection =
"((${CalendarContract.Events.TITLE} = ?))"
val selectionArgs = arrayOf(title)

val cursor: Cursor? = resolver.query(uri, null, selection, selectionArgs, null)
return cursor?.use { it.count > 0 } ?: false
}

// Fucking nuke the local calendar and send it directly to hell
fun deleteLocalCalendar(context: Context, calendarName: String) {
val cr: ContentResolver = context.contentResolver
val uri: Uri = CalendarContract.Calendars.CONTENT_URI
val selection = "${CalendarContract.Calendars.CALENDAR_DISPLAY_NAME} = ?"
val selectionArgs = arrayOf(calendarName)

// Obtain the calendar ID
val cursor = cr.query(uri, arrayOf(CalendarContract.Calendars._ID), selection, selectionArgs, null)
cursor?.use {
if (it.moveToFirst()) {
val calendarId = it.getLong(0)
val deleteUri = ContentUris.withAppendedId(uri, calendarId)
val rowsDeleted = cr.delete(deleteUri, null, null)
if (rowsDeleted > 0) {
Log.d("calendar","Calendar nuked, get rekt")
} else {
Log.d("calendar", "Can't find the local calendar")
}
}
}
}

// Add a reminder for an event, probably unused, but could have sense in certain cases
fun addReminder(context: Context, eventId: Long, minutesBefore: Int) {
val values = ContentValues().apply {
Expand Down

0 comments on commit 58bc70b

Please sign in to comment.