Skip to content

Commit

Permalink
migrate syncManager and task notification worker
Browse files Browse the repository at this point in the history
  • Loading branch information
Okuro3499 committed Dec 18, 2024
1 parent 4dbe865 commit 7063068
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 146 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ class RealmMyCourse : RealmObject {
private val concatenatedLinks = ArrayList<String>()
val courseDataList: MutableList<Array<String>> = mutableListOf()

fun insertMyCourses(userId: String, myCoursesDoc: JsonObject, realm: Realm) {
fun insertMyCourses(userId: String?, myCoursesDoc: JsonObject, realm: Realm) {
CoroutineScope(Dispatchers.IO).launch {
val ID = JsonUtils.getString("_id", myCoursesDoc)
realm.writeBlocking {
Expand All @@ -81,7 +81,7 @@ class RealmMyCourse : RealmObject {
}

myMyCourseDB.apply {
addUserId(userId)
addUserId(userId ?: "")
courseId = JsonUtils.getString("_id", myCoursesDoc)
courseRev = JsonUtils.getString("_rev", myCoursesDoc)
languageOfInstruction = JsonUtils.getString("languageOfInstruction", myCoursesDoc)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ import io.realm.kotlin.ext.realmListOf
import io.realm.kotlin.types.RealmList
import io.realm.kotlin.types.RealmObject
import io.realm.kotlin.types.annotations.PrimaryKey
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.launch
import org.ole.planet.myplanet.MainApplication.Companion.context
import org.ole.planet.myplanet.utilities.Constants.PREFS_NAME
import org.ole.planet.myplanet.utilities.FileUtils
Expand Down Expand Up @@ -242,8 +246,10 @@ class RealmMyLibrary : RealmObject {
insertMyLibrary("", stepId, myCoursesID, res, realm)
}

suspend fun insertMyLibrary(userId: String?, doc: JsonObject, realm: Realm) {
insertMyLibrary(userId, "", "", doc, realm)
fun insertMyLibrary(userId: String?, doc: JsonObject, realm: Realm) {
CoroutineScope(SupervisorJob() + Dispatchers.IO).launch{
insertMyLibrary(userId, "", "", doc, realm)
}
}

suspend fun createFromResource(resource: RealmMyLibrary?, realm: Realm, userId: String?) {
Expand Down
236 changes: 110 additions & 126 deletions app/src/main/java/org/ole/planet/myplanet/service/SyncManager.kt
Original file line number Diff line number Diff line change
@@ -1,39 +1,18 @@
package org.ole.planet.myplanet.service

import android.content.Context
import android.content.SharedPreferences
import android.net.wifi.SupplicantState
import android.net.wifi.WifiManager
import android.text.TextUtils
import com.google.gson.Gson
import com.google.gson.JsonArray
import com.google.gson.JsonNull
import com.google.gson.JsonObject
import io.realm.Realm
import org.ole.planet.myplanet.MainApplication
import org.ole.planet.myplanet.R
import android.content.*
import android.net.wifi.*
import com.google.gson.*
import io.realm.kotlin.Realm
import kotlinx.coroutines.*
import org.ole.planet.myplanet.*
import org.ole.planet.myplanet.callback.SyncListener
import org.ole.planet.myplanet.datamanager.*
import org.ole.planet.myplanet.datamanager.ApiClient.client
import org.ole.planet.myplanet.datamanager.ApiInterface
import org.ole.planet.myplanet.datamanager.DatabaseService
import org.ole.planet.myplanet.datamanager.ManagerSync
import org.ole.planet.myplanet.model.RealmMeetup.Companion.insert
import org.ole.planet.myplanet.model.RealmMyCourse.Companion.insertMyCourses
import org.ole.planet.myplanet.model.RealmMyCourse.Companion.saveConcatenatedLinksToPrefs
import org.ole.planet.myplanet.model.RealmMyLibrary.Companion.insertMyLibrary
import org.ole.planet.myplanet.model.RealmMyLibrary.Companion.removeDeletedResource
import org.ole.planet.myplanet.model.RealmMyLibrary.Companion.save
import org.ole.planet.myplanet.model.RealmMyTeam.Companion.insertMyTeams
import org.ole.planet.myplanet.model.RealmResourceActivity.Companion.onSynced
import org.ole.planet.myplanet.model.Rows
import org.ole.planet.myplanet.utilities.Constants
import org.ole.planet.myplanet.model.*
import org.ole.planet.myplanet.utilities.Constants.PREFS_NAME
import org.ole.planet.myplanet.utilities.Constants.ShelfData
import org.ole.planet.myplanet.utilities.JsonUtils.getJsonArray
import org.ole.planet.myplanet.utilities.JsonUtils.getString
import org.ole.planet.myplanet.utilities.NotificationUtil.cancel
import org.ole.planet.myplanet.utilities.NotificationUtil.create
import org.ole.planet.myplanet.utilities.Utilities
import org.ole.planet.myplanet.utilities.*
import java.io.IOException
import java.util.Date

Expand All @@ -46,6 +25,7 @@ class SyncManager private constructor(private val context: Context) {
private var shelfDoc: Rows? = null
private var listener: SyncListener? = null
private val dbService: DatabaseService = DatabaseService()
private val coroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)

fun start(listener: SyncListener?) {
this.listener = listener
Expand All @@ -57,21 +37,12 @@ class SyncManager private constructor(private val context: Context) {
}

private fun destroy() {
cancel(context, 111)
NotificationUtil.cancel(context, 111)
isSyncing = false
ourInstance = null
settings.edit().putLong("LastSync", Date().time).apply()
if (listener != null) {
listener?.onSyncComplete()
}
try {
if (::mRealm.isInitialized && !mRealm.isClosed) {
mRealm.close()
td?.interrupt()
}
} catch (e: Exception) {
e.printStackTrace()
}
listener?.onSyncComplete()
td?.interrupt()
}

private fun authenticateAndSync() {
Expand All @@ -87,43 +58,48 @@ class SyncManager private constructor(private val context: Context) {
}

private fun startSync() {
try {
val wifiManager = context.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
val wifiInfo = wifiManager.connectionInfo
if (wifiInfo.supplicantState == SupplicantState.COMPLETED) {
settings.edit().putString("LastWifiSSID", wifiInfo.ssid).apply()
CoroutineScope(Dispatchers.IO).launch {
try {
val wifiManager =
context.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
val wifiInfo = wifiManager.connectionInfo
if (wifiInfo.supplicantState == SupplicantState.COMPLETED) {
settings.edit().putString("LastWifiSSID", wifiInfo.ssid).apply()
}
isSyncing = true
NotificationUtil.create(context, R.mipmap.ic_launcher, " Syncing data", "Please wait...")

mRealm = dbService.realmInstance

TransactionSyncManager.syncDb(mRealm, "tablet_users")
myLibraryTransactionSync()
TransactionSyncManager.syncDb(mRealm, "courses")
TransactionSyncManager.syncDb(mRealm, "exams")
TransactionSyncManager.syncDb(mRealm, "ratings")
TransactionSyncManager.syncDb(mRealm, "courses_progress")
TransactionSyncManager.syncDb(mRealm, "achievements")
TransactionSyncManager.syncDb(mRealm, "tags")
TransactionSyncManager.syncDb(mRealm, "submissions")
TransactionSyncManager.syncDb(mRealm, "news")
TransactionSyncManager.syncDb(mRealm, "feedback")
TransactionSyncManager.syncDb(mRealm, "teams")
TransactionSyncManager.syncDb(mRealm, "tasks")
TransactionSyncManager.syncDb(mRealm, "login_activities")
TransactionSyncManager.syncDb(mRealm, "meetups")
TransactionSyncManager.syncDb(mRealm, "health")
TransactionSyncManager.syncDb(mRealm, "certifications")
TransactionSyncManager.syncDb(mRealm, "team_activities")
TransactionSyncManager.syncDb(mRealm, "chat_history")

ManagerSync.instance?.syncAdmin()
resourceTransactionSync()
RealmResourceActivity.onSynced(mRealm, settings)
} catch (err: Exception) {
err.printStackTrace()
handleException(err.message)
} finally {
destroy()
}
isSyncing = true
create(context, R.mipmap.ic_launcher, " Syncing data", "Please wait...")
mRealm = dbService.realmInstance
TransactionSyncManager.syncDb(mRealm, "tablet_users")
myLibraryTransactionSync()
TransactionSyncManager.syncDb(mRealm, "courses")
TransactionSyncManager.syncDb(mRealm, "exams")
TransactionSyncManager.syncDb(mRealm, "ratings")
TransactionSyncManager.syncDb(mRealm, "courses_progress")
TransactionSyncManager.syncDb(mRealm, "achievements")
TransactionSyncManager.syncDb(mRealm, "tags")
TransactionSyncManager.syncDb(mRealm, "submissions")
TransactionSyncManager.syncDb(mRealm, "news")
TransactionSyncManager.syncDb(mRealm, "feedback")
TransactionSyncManager.syncDb(mRealm, "teams")
TransactionSyncManager.syncDb(mRealm, "tasks")
TransactionSyncManager.syncDb(mRealm, "login_activities")
TransactionSyncManager.syncDb(mRealm, "meetups")
TransactionSyncManager.syncDb(mRealm, "health")
TransactionSyncManager.syncDb(mRealm, "certifications")
TransactionSyncManager.syncDb(mRealm, "team_activities")
TransactionSyncManager.syncDb(mRealm, "chat_history")
ManagerSync.instance?.syncAdmin()
resourceTransactionSync()
onSynced(mRealm, settings)
mRealm.close()
} catch (err: Exception) {
err.printStackTrace()
handleException(err.message)
} finally {
destroy()
}
}

Expand All @@ -135,7 +111,7 @@ class SyncManager private constructor(private val context: Context) {
}
}

private fun resourceTransactionSync() {
private suspend fun resourceTransactionSync() {
val apiInterface = client?.create(ApiInterface::class.java)
try {
syncResource(apiInterface)
Expand All @@ -144,36 +120,48 @@ class SyncManager private constructor(private val context: Context) {
}
}

@Throws(IOException::class)
private fun syncResource(dbClient: ApiInterface?) {
val newIds: MutableList<String?> = ArrayList()
val allDocs = dbClient?.getJsonObject(Utilities.header, Utilities.getUrl() + "/resources/_all_docs?include_doc=false")
val all = allDocs?.execute()
val rows = getJsonArray("rows", all?.body())
val keys: MutableList<String> = ArrayList()
for (i in 0 until rows.size()) {
val `object` = rows[i].asJsonObject
if (!TextUtils.isEmpty(getString("id", `object`))) keys.add(getString("key", `object`))
if (i == rows.size() - 1 || keys.size == 1000) {
val obj = JsonObject()
obj.add("keys", Gson().fromJson(Gson().toJson(keys), JsonArray::class.java))
val response = dbClient?.findDocs(Utilities.header, "application/json", Utilities.getUrl() + "/resources/_all_docs?include_docs=true", obj)?.execute()
if (response?.body() != null) {
val ids: List<String?> = save(getJsonArray("rows", response.body()), mRealm)
newIds.addAll(ids)
private suspend fun syncResource(dbClient: ApiInterface?) {
val newIds = mutableListOf<String?>()

try {
// Fetch all document keys
val allDocs = dbClient?.getJsonObject(Utilities.header, "${Utilities.getUrl()}/resources/_all_docs?include_doc=false")?.execute()
val rows = JsonUtils.getJsonArray("rows", allDocs?.body())
val keys = mutableListOf<String>()

for (i in 0 until rows.size()) {
val rowObject = rows[i].asJsonObject
val id = JsonUtils.getString("id", rowObject)
if (id.isNotEmpty()) {
keys.add(JsonUtils.getString("key", rowObject))
// Process in batches of 1000 keys
if (keys.size == 1000 || i == rows.size() - 1) {
val keysJson = JsonObject().apply {
add("keys", Gson().fromJson(Gson().toJson(keys), JsonArray::class.java))
}
val batchedDocsResponse = dbClient?.findDocs(Utilities.header, "application/json", "${Utilities.getUrl()}/resources/_all_docs?include_docs=true", keysJson)?.execute()
val batchedRows = JsonUtils.getJsonArray("rows", batchedDocsResponse?.body())
val ids = withContext(Dispatchers.IO) { RealmMyLibrary.save(batchedRows, mRealm) }
newIds.addAll(ids)
keys.clear()
}
}
keys.clear()
}

withContext(Dispatchers.IO) {
RealmMyLibrary.removeDeletedResource(newIds.filterNotNull(), mRealm)
}
} catch (e: IOException) {
e.printStackTrace()
}
removeDeletedResource(newIds, mRealm)
}

private fun myLibraryTransactionSync() {
val apiInterface = client?.create(ApiInterface::class.java)
try {
val res = apiInterface?.getDocuments(Utilities.header, Utilities.getUrl() + "/shelf/_all_docs")?.execute()?.body()
for (i in res?.rows!!.indices) {
shelfDoc = res.rows!![i]
res?.rows?.forEach { row ->
shelfDoc = row
populateShelfItems(apiInterface)
}
} catch (e: IOException) {
Expand All @@ -184,9 +172,8 @@ class SyncManager private constructor(private val context: Context) {
private fun populateShelfItems(apiInterface: ApiInterface) {
try {
val jsonDoc = apiInterface.getJsonObject(Utilities.header, Utilities.getUrl() + "/shelf/" + shelfDoc?.id).execute().body()
for (i in Constants.shelfDataList.indices) {
val shelfData = Constants.shelfDataList[i]
val array = getJsonArray(shelfData.key, jsonDoc)
Constants.shelfDataList.forEach { shelfData ->
val array = JsonUtils.getJsonArray(shelfData.key, jsonDoc)
memberShelfData(array, shelfData)
}
} catch (err: Exception) {
Expand All @@ -208,42 +195,39 @@ class SyncManager private constructor(private val context: Context) {
}

private fun check(arrayCategoryIds: JsonArray) {
for (x in 0 until arrayCategoryIds.size()) {
if (arrayCategoryIds[x] is JsonNull) {
continue
arrayCategoryIds.forEach { element ->
if (element !is JsonNull) {
validateDocument(arrayCategoryIds, element.asString)
}
validateDocument(arrayCategoryIds, x)
}
}

private fun validateDocument(arrayCategoryIds: JsonArray, x: Int) {
val apiInterface = client!!.create(ApiInterface::class.java)
private fun validateDocument(arrayCategoryIds: JsonArray, id: String) {
val apiInterface = client?.create(ApiInterface::class.java)
try {
val resourceDoc = apiInterface.getJsonObject(Utilities.header, Utilities.getUrl() + "/" + stringArray[2] + "/" + arrayCategoryIds[x].asString).execute().body()
resourceDoc?.let { triggerInsert(stringArray, it) }
val resourceDoc = apiInterface?.getJsonObject(Utilities.header, Utilities.getUrl() + "/" + stringArray[2] + "/" + id)?.execute()?.body()
resourceDoc?.let {
coroutineScope.launch {
triggerInsert(stringArray, it)
}
}
} catch (e: IOException) {
e.printStackTrace()
}
}

private fun triggerInsert(stringArray: Array<String?>, resourceDoc: JsonObject) {
when (stringArray[2]) {
"resources" -> insertMyLibrary(stringArray[0], resourceDoc, mRealm)
"meetups" -> insert(mRealm, resourceDoc)
"courses" -> {
if (!mRealm.isInTransaction){
mRealm.beginTransaction()
}
insertMyCourses(stringArray[0], resourceDoc, mRealm)
if (mRealm.isInTransaction){
mRealm.commitTransaction()
private suspend fun triggerInsert(stringArray: Array<String?>, resourceDoc: JsonObject) {
mRealm.write {
when (stringArray[2]) {
"resources" -> RealmMyLibrary.insertMyLibrary(stringArray[0], resourceDoc, mRealm)
"meetups" -> RealmMeetup.insert(mRealm, resourceDoc)
"courses" -> RealmMyCourse.insertMyCourses(stringArray[0], resourceDoc, mRealm)
"teams" -> RealmMyTeam.insertMyTeams(resourceDoc, mRealm)
}
}
"teams" -> insertMyTeams(resourceDoc, mRealm)
}
saveConcatenatedLinksToPrefs()
}

RealmMyCourse.saveConcatenatedLinksToPrefs()
}
companion object {
private var ourInstance: SyncManager? = null
val instance: SyncManager?
Expand Down
Loading

0 comments on commit 7063068

Please sign in to comment.