From 67249034f9aeafb77db41fa567d3962a57845174 Mon Sep 17 00:00:00 2001 From: Gideon Okuro Date: Wed, 13 Nov 2024 20:30:15 +0300 Subject: [PATCH 01/38] update realm in build gradle and start models migration --- app/build.gradle | 6 +- .../ole/planet/myplanet/MainApplication.kt | 2 +- .../myplanet/base/BaseRecyclerFragment.kt | 2 +- .../myplanet/base/BaseResourceFragment.kt | 4 +- .../myplanet/datamanager/DatabaseService.kt | 68 +++++++++---- .../myplanet/datamanager/ManagerSync.kt | 2 +- .../myplanet/datamanager/MyDownloadService.kt | 3 +- .../planet/myplanet/model/RealmAchievement.kt | 96 ++++++++++--------- .../ole/planet/myplanet/model/RealmAnswer.kt | 64 ++++++------- .../ole/planet/myplanet/model/RealmApkLog.kt | 58 +++++------ .../myplanet/model/RealmCertification.kt | 64 +++++++------ .../planet/myplanet/service/SyncManager.kt | 2 +- .../service/TaskNotificationWorker.kt | 2 +- .../planet/myplanet/service/UploadManager.kt | 10 +- .../myplanet/service/UploadToShelfService.kt | 2 +- .../myplanet/service/UserProfileDbHandler.kt | 2 +- .../ole/planet/myplanet/ui/SettingActivity.kt | 2 +- .../myplanet/ui/chat/ChatDetailFragment.kt | 2 +- .../ui/chat/ChatHistoryListAdapter.kt | 2 +- .../ui/chat/ChatHistoryListFragment.kt | 2 +- .../myplanet/ui/community/AddLinkFragment.kt | 2 +- .../ui/community/CommunityFragment.kt | 2 +- .../myplanet/ui/community/ServicesFragment.kt | 2 +- .../ui/courses/CourseDetailFragment.kt | 2 +- .../ui/courses/CourseProgressActivity.kt | 2 +- .../myplanet/ui/courses/CourseStepFragment.kt | 2 +- .../myplanet/ui/courses/MyProgressFragment.kt | 2 +- .../myplanet/ui/courses/TakeCourseFragment.kt | 4 +- .../ui/dashboard/BaseDashboardFragment.kt | 6 +- .../ui/dashboard/DashboardFragment.kt | 2 +- .../ui/dashboard/MyActivityFragment.kt | 2 +- .../notification/NotificationsFragment.kt | 2 +- .../ui/dictionary/DictionaryActivity.kt | 2 +- .../ui/enterprises/FinanceFragment.kt | 2 +- .../ui/enterprises/ReportsFragment.kt | 2 +- .../myplanet/ui/exam/BaseExamFragment.kt | 2 +- .../ui/exam/UserInformationFragment.kt | 2 +- .../ui/feedback/FeedbackDetailActivity.kt | 2 +- .../myplanet/ui/feedback/FeedbackFragment.kt | 2 +- .../ui/feedback/FeedbackListFragment.kt | 2 +- .../ui/myPersonals/MyPersonalsFragment.kt | 2 +- .../ui/myhealth/AddExaminationActivity.kt | 2 +- .../ui/myhealth/AddMyHealthActivity.kt | 2 +- .../myplanet/ui/myhealth/MyHealthFragment.kt | 2 +- .../ui/mymeetup/MyMeetupDetailFragment.kt | 2 +- .../myplanet/ui/news/NewsDetailActivity.kt | 2 +- .../planet/myplanet/ui/news/NewsFragment.kt | 2 +- .../planet/myplanet/ui/news/ReplyActivity.kt | 2 +- .../myplanet/ui/rating/RatingFragment.kt | 2 +- .../ui/resources/AddResourceActivity.kt | 2 +- .../ui/resources/AddResourceFragment.kt | 2 +- .../ui/resources/CollectionsFragment.kt | 2 +- .../ui/resources/ResourceDetailFragment.kt | 2 +- .../ui/submission/MySubmissionFragment.kt | 2 +- .../myplanet/ui/survey/SendSurveyFragment.kt | 4 +- .../planet/myplanet/ui/sync/SyncActivity.kt | 6 +- .../myplanet/ui/team/BaseTeamFragment.kt | 2 +- .../myplanet/ui/team/MyTeamsDetailFragment.kt | 2 +- .../myplanet/ui/team/TeamDetailFragment.kt | 2 +- .../planet/myplanet/ui/team/TeamFragment.kt | 2 +- .../ui/userprofile/AchievementFragment.kt | 2 +- .../ui/userprofile/BecomeMemberActivity.kt | 2 +- .../ui/userprofile/EditAchievementFragment.kt | 2 +- .../ui/userprofile/UserDetailFragment.kt | 2 +- .../ui/userprofile/UserProfileFragment.kt | 2 +- .../myplanet/ui/viewer/PDFReaderActivity.kt | 2 +- build.gradle | 1 - 67 files changed, 263 insertions(+), 237 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index ce75940730..c77f0490ac 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -3,7 +3,7 @@ apply plugin: 'kotlin-android' apply plugin: 'kotlin-kapt' apply plugin: 'kotlinx-serialization' apply plugin: 'dagger.hilt.android.plugin' -apply plugin: 'realm-android' + android { compileSdk 35 defaultConfig { @@ -233,9 +233,7 @@ dependencies { implementation(platform("org.jetbrains.kotlin:kotlin-bom:2.0.21")) implementation 'com.github.chrisbanes:PhotoView:2.3.0' -} -realm { - syncEnabled = true + implementation "io.realm.kotlin:library-base:1.11.0" } kapt{ correctErrorTypes true diff --git a/app/src/main/java/org/ole/planet/myplanet/MainApplication.kt b/app/src/main/java/org/ole/planet/myplanet/MainApplication.kt index b0939e1ce0..4fa85b8425 100644 --- a/app/src/main/java/org/ole/planet/myplanet/MainApplication.kt +++ b/app/src/main/java/org/ole/planet/myplanet/MainApplication.kt @@ -152,7 +152,7 @@ class MainApplication : Application(), Application.ActivityLifecycleCallbacks { startListenNetworkState() preferences = getSharedPreferences(PREFS_NAME, MODE_PRIVATE) - service = DatabaseService(context) + service = DatabaseService() mRealm = service.realmInstance defaultPref = PreferenceManager.getDefaultSharedPreferences(this) diff --git a/app/src/main/java/org/ole/planet/myplanet/base/BaseRecyclerFragment.kt b/app/src/main/java/org/ole/planet/myplanet/base/BaseRecyclerFragment.kt index 35746787be..cb051e576f 100644 --- a/app/src/main/java/org/ole/planet/myplanet/base/BaseRecyclerFragment.kt +++ b/app/src/main/java/org/ole/planet/myplanet/base/BaseRecyclerFragment.kt @@ -89,7 +89,7 @@ abstract class BaseRecyclerFragment
  • : BaseRecyclerParentFragment(), On tvMessage = v.findViewById(R.id.tv_message) selectedItems = mutableListOf() list = mutableListOf() - realmService = DatabaseService(requireActivity()) + realmService = DatabaseService() mRealm = realmService.realmInstance profileDbHandler = UserProfileDbHandler(requireActivity()) model = profileDbHandler.userModel!! diff --git a/app/src/main/java/org/ole/planet/myplanet/base/BaseResourceFragment.kt b/app/src/main/java/org/ole/planet/myplanet/base/BaseResourceFragment.kt index d1684d5e79..070810f0d4 100644 --- a/app/src/main/java/org/ole/planet/myplanet/base/BaseResourceFragment.kt +++ b/app/src/main/java/org/ole/planet/myplanet/base/BaseResourceFragment.kt @@ -65,7 +65,7 @@ abstract class BaseResourceFragment : Fragment() { private var receiver: BroadcastReceiver = object : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { - showDownloadDialog(getLibraryList(DatabaseService(context).realmInstance)) + showDownloadDialog(getLibraryList(DatabaseService().realmInstance)) } } @@ -245,7 +245,7 @@ abstract class BaseResourceFragment : Fragment() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - mRealm = DatabaseService(requireActivity()).realmInstance + mRealm = DatabaseService().realmInstance prgDialog = getProgressDialog(requireActivity()) settings = requireActivity().getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE) editor = settings?.edit() diff --git a/app/src/main/java/org/ole/planet/myplanet/datamanager/DatabaseService.kt b/app/src/main/java/org/ole/planet/myplanet/datamanager/DatabaseService.kt index 42f8623faf..16530a9653 100644 --- a/app/src/main/java/org/ole/planet/myplanet/datamanager/DatabaseService.kt +++ b/app/src/main/java/org/ole/planet/myplanet/datamanager/DatabaseService.kt @@ -1,24 +1,56 @@ package org.ole.planet.myplanet.datamanager -import android.content.Context -import io.realm.* -import io.realm.log.* +import io.realm.kotlin.Realm +import io.realm.kotlin.RealmConfiguration +import io.realm.kotlin.log.RealmLog +import io.realm.kotlin.log.LogLevel +import org.ole.planet.myplanet.model.* + +class DatabaseService() { + private val config: RealmConfiguration -class DatabaseService(context: Context) { init { - Realm.init(context) - RealmLog.setLevel(LogLevel.DEBUG) - val config = RealmConfiguration.Builder() - .name(Realm.DEFAULT_REALM_NAME) - .deleteRealmIfMigrationNeeded() - .schemaVersion(4) - .allowWritesOnUiThread(true) - .build() - Realm.setDefaultConfiguration(config) + RealmLog.level = LogLevel.DEBUG // Set log level + // Define the Realm configuration + config = RealmConfiguration.create( + schema = setOf( + RealmAchievement::class, RealmAnswer::class, RealmApkLog::class, + RealmCertification::class, RealmChatHistory::class, RealmCommunity::class, + RealmCourseActivity::class, RealmCourseProgress::class, RealmCourseStep::class, + RealmDictionary::class, RealmExamQuestion::class, RealmFeedback::class, + RealmMeetup::class, RealmMessage::class, RealmMyCourse::class, RealmMyHealth::class, + RealmMyHealthPojo::class, RealmMyLibrary::class, RealmMyLife::class, + RealmMyPersonal::class, RealmMyTeam::class, RealmNews::class, RealmNewsLog::class, + RealmNotification::class, RealmOfflineActivity::class, RealmRating::class, + RealmRemovedLog::class, RealmResourceActivity::class, RealmSearchActivity::class, + RealmStepExam::class, RealmSubmission::class, RealmSubmitPhotos::class, RealmTag::class, RealmTeamLog::class, RealmTeamNotification::class, RealmTeamTask::class, + RealmUserChallengeActions::class, RealmUserModel::class), + name = "default.realm", + schemaVersion = 4 + ) + } + + // Lazily open a Realm instance with the configuration + val realmInstance: Realm by lazy { + Realm.open(config) } +} - val realmInstance: Realm - get() { - return Realm.getDefaultInstance() - } -} \ No newline at end of file +//class DatabaseService(context: Context) { +// init { +// Realm.init(context) +// RealmLog.setLevel(LogLevel.DEBUG) +// val config = RealmConfiguration.Builder() +// .name(Realm.DEFAULT_REALM_NAME) +// .deleteRealmIfMigrationNeeded() +// .schemaVersion(4) +// .allowWritesOnUiThread(true) +// .build() +// Realm.setDefaultConfiguration(config) +// } +// +// val realmInstance: Realm +// get() { +// return Realm.getDefaultInstance() +// } +//} \ No newline at end of file diff --git a/app/src/main/java/org/ole/planet/myplanet/datamanager/ManagerSync.kt b/app/src/main/java/org/ole/planet/myplanet/datamanager/ManagerSync.kt index e1793e8562..d74b18039e 100644 --- a/app/src/main/java/org/ole/planet/myplanet/datamanager/ManagerSync.kt +++ b/app/src/main/java/org/ole/planet/myplanet/datamanager/ManagerSync.kt @@ -20,7 +20,7 @@ import java.util.Locale class ManagerSync private constructor(context: Context) { private val settings: SharedPreferences = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE) - private val dbService: DatabaseService = DatabaseService(context) + private val dbService: DatabaseService = DatabaseService() private val mRealm: Realm = dbService.realmInstance fun login(userName: String?, password: String?, listener: SyncListener) { diff --git a/app/src/main/java/org/ole/planet/myplanet/datamanager/MyDownloadService.kt b/app/src/main/java/org/ole/planet/myplanet/datamanager/MyDownloadService.kt index 46383c558e..655c609bcb 100644 --- a/app/src/main/java/org/ole/planet/myplanet/datamanager/MyDownloadService.kt +++ b/app/src/main/java/org/ole/planet/myplanet/datamanager/MyDownloadService.kt @@ -23,7 +23,6 @@ import org.ole.planet.myplanet.utilities.FileUtils.getSDPathFromUrl import org.ole.planet.myplanet.utilities.Utilities.header import retrofit2.Call import java.io.* -import kotlin.math.pow import kotlin.math.roundToInt class MyDownloadService : Service() { @@ -40,7 +39,7 @@ class MyDownloadService : Service() { private var completeAll = false private var fromSync = false - private val databaseService: DatabaseService by lazy { DatabaseService(this) } + private val databaseService: DatabaseService by lazy { DatabaseService() } private val mRealm: Realm by lazy { databaseService.realmInstance } override fun onBind(intent: Intent?): IBinder? = null diff --git a/app/src/main/java/org/ole/planet/myplanet/model/RealmAchievement.kt b/app/src/main/java/org/ole/planet/myplanet/model/RealmAchievement.kt index 143846a491..6ed326aea3 100644 --- a/app/src/main/java/org/ole/planet/myplanet/model/RealmAchievement.kt +++ b/app/src/main/java/org/ole/planet/myplanet/model/RealmAchievement.kt @@ -7,31 +7,34 @@ import com.google.gson.JsonArray import com.google.gson.JsonElement import com.google.gson.JsonObject import com.opencsv.CSVWriter -import io.realm.Realm -import io.realm.RealmList -import io.realm.RealmObject -import io.realm.annotations.PrimaryKey +import io.realm.kotlin.Realm +import io.realm.kotlin.ext.query +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.runBlocking import org.ole.planet.myplanet.MainApplication.Companion.context import org.ole.planet.myplanet.utilities.JsonUtils import java.io.File import java.io.FileWriter import java.io.IOException -open class RealmAchievement : RealmObject() { - var achievements: RealmList? = null - var references: RealmList? = null +class RealmAchievement : RealmObject { + @PrimaryKey + var _id: String = "" + var _rev: String? = null + var achievements: RealmList = realmListOf() + var references: RealmList = realmListOf() var purpose: String? = null var achievementsHeader: String? = null var sendToNation: String? = null - var _rev: String? = null - @PrimaryKey - var _id: String? = null var goals: String? = null val achievementsArray: JsonArray get() { val array = JsonArray() - for (s in achievements ?: emptyList()) { + for (s in achievements) { val ob = Gson().fromJson(s, JsonElement::class.java) array.add(ob) } @@ -40,7 +43,7 @@ open class RealmAchievement : RealmObject() { fun getReferencesArray(): JsonArray { val array = JsonArray() - for (s in references ?: emptyList()) { + for (s in references) { val ob = Gson().fromJson(s, JsonElement::class.java) array.add(ob) } @@ -48,22 +51,22 @@ open class RealmAchievement : RealmObject() { } fun setAchievements(ac: JsonArray) { - achievements = RealmList() + achievements.clear() for (el in ac) { val achievement = Gson().toJson(el) - if (!achievements?.contains(achievement)!!) { - achievements?.add(achievement) + if (!achievements.contains(achievement)) { + achievements.add(achievement) } } } fun setReferences(of: JsonArray?) { - references = RealmList() + references.clear() if (of == null) return for (el in of) { val e = Gson().toJson(el) - if (!references?.contains(e)!!) { - references?.add(e) + if (!references.contains(e)) { + references.add(e) } } } @@ -95,35 +98,39 @@ open class RealmAchievement : RealmObject() { } @JvmStatic - fun insert(mRealm: Realm, act: JsonObject?) { - if (!mRealm.isInTransaction) { - mRealm.beginTransaction() + fun insert(mRealm: Realm, act: JsonObject?) = runBlocking { + mRealm.write { + val achievementId = JsonUtils.getString("_id", act) + var achievement = this.query("_id == $0", achievementId).first().find() + + if (achievement == null) { + achievement = RealmAchievement().apply { + _id = achievementId + } + achievement = this.copyToRealm(achievement) + } + + achievement._rev = JsonUtils.getString("_rev", act) + achievement.purpose = JsonUtils.getString("purpose", act) + achievement.goals = JsonUtils.getString("goals", act) + achievement.achievementsHeader = JsonUtils.getString("achievementsHeader", act) + achievement.setReferences(JsonUtils.getJsonArray("references", act)) + achievement.setAchievements(JsonUtils.getJsonArray("achievements", act)) + + val csvRow = arrayOf( + JsonUtils.getString("_id", act), + JsonUtils.getString("_rev", act), + JsonUtils.getString("purpose", act), + JsonUtils.getString("goals", act), + JsonUtils.getString("achievementsHeader", act), + JsonUtils.getJsonArray("references", act).toString(), + JsonUtils.getJsonArray("achievements", act).toString() + ) + achievementDataList.add(csvRow) } - var achievement = mRealm.where(RealmAchievement::class.java) - .equalTo("_id", JsonUtils.getString("_id", act)).findFirst() - if (achievement == null) achievement = mRealm.createObject( - RealmAchievement::class.java, JsonUtils.getString("_id", act) - ) - achievement?._rev = JsonUtils.getString("_rev", act) - achievement?.purpose = JsonUtils.getString("purpose", act) - achievement?.goals = JsonUtils.getString("goals", act) - achievement?.achievementsHeader = JsonUtils.getString("achievementsHeader", act) - achievement?.setReferences(JsonUtils.getJsonArray("references", act)) - achievement?.setAchievements(JsonUtils.getJsonArray("achievements", act)) - mRealm.commitTransaction() - - val csvRow = arrayOf( - JsonUtils.getString("_id", act), - JsonUtils.getString("_rev", act), - JsonUtils.getString("purpose", act), - JsonUtils.getString("goals", act), - JsonUtils.getString("achievementsHeader", act), - JsonUtils.getJsonArray("references", act).toString(), - JsonUtils.getJsonArray("achievements", act).toString() - ) - achievementDataList.add(csvRow) } + @JvmStatic fun writeCsv(filePath: String, data: List>) { try { @@ -146,3 +153,4 @@ open class RealmAchievement : RealmObject() { } } } + diff --git a/app/src/main/java/org/ole/planet/myplanet/model/RealmAnswer.kt b/app/src/main/java/org/ole/planet/myplanet/model/RealmAnswer.kt index 7e9f95bc80..2651fc54bb 100644 --- a/app/src/main/java/org/ole/planet/myplanet/model/RealmAnswer.kt +++ b/app/src/main/java/org/ole/planet/myplanet/model/RealmAnswer.kt @@ -1,47 +1,43 @@ package org.ole.planet.myplanet.model - import android.text.TextUtils import com.google.gson.Gson import com.google.gson.JsonArray import com.google.gson.JsonObject -import io.realm.RealmList -import io.realm.RealmObject -import io.realm.annotations.PrimaryKey +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 -open class RealmAnswer : RealmObject() { +class RealmAnswer : RealmObject { @PrimaryKey var id: String? = null var value: String? = null - var valueChoices: RealmList? = null - var mistakes = 0 - var isPassed = false - var grade = 0 + var valueChoices: RealmList = realmListOf() + var mistakes: Int = 0 + var isPassed: Boolean = false + var grade: Int = 0 var examId: String? = null var questionId: String? = null var submissionId: String? = null - val valueChoicesArray: JsonArray - get() { - val array = JsonArray() - if (valueChoices == null) { - return array - } - for (choice in valueChoices ?: emptyList()) { - array.add(Gson().fromJson(choice, JsonObject::class.java)) - } - return array + + val valueChoicesArray: JsonArray get() { + val array = JsonArray() + for (choice in valueChoices) { + array.add(Gson().fromJson(choice, JsonObject::class.java)) } + return array + } fun setValueChoices(map: HashMap?, isLastAnsValid: Boolean) { if (!isLastAnsValid) { - valueChoices?.clear() + valueChoices.clear() } - if (map != null) { - for (key in map.keys) { - val ob = JsonObject() - ob.addProperty("id", map[key]) - ob.addProperty("text", key) - valueChoices?.add(Gson().toJson(ob)) + map?.forEach { (key, value) -> + val ob = JsonObject().apply { + addProperty("id", value) + addProperty("text", key) } + valueChoices.add(Gson().toJson(ob)) } } @@ -49,22 +45,22 @@ open class RealmAnswer : RealmObject() { @JvmStatic fun serializeRealmAnswer(answers: RealmList): JsonArray { val array = JsonArray() - for (ans in answers) { + answers.forEach { ans -> array.add(createObject(ans)) } return array } private fun createObject(ans: RealmAnswer): JsonObject { - val `object` = JsonObject() + val jsonObject = JsonObject() if (!TextUtils.isEmpty(ans.value)) { - `object`.addProperty("value", ans.value) + jsonObject.addProperty("value", ans.value) } else { - `object`.add("value", ans.valueChoicesArray) + jsonObject.add("value", ans.valueChoicesArray) } - `object`.addProperty("mistakes", ans.mistakes) - `object`.addProperty("passed", ans.isPassed) - return `object` + jsonObject.addProperty("mistakes", ans.mistakes) + jsonObject.addProperty("passed", ans.isPassed) + return jsonObject } } -} \ No newline at end of file +} diff --git a/app/src/main/java/org/ole/planet/myplanet/model/RealmApkLog.kt b/app/src/main/java/org/ole/planet/myplanet/model/RealmApkLog.kt index bf4c28615e..f9cd86c041 100644 --- a/app/src/main/java/org/ole/planet/myplanet/model/RealmApkLog.kt +++ b/app/src/main/java/org/ole/planet/myplanet/model/RealmApkLog.kt @@ -2,12 +2,12 @@ package org.ole.planet.myplanet.model import android.content.Context import com.google.gson.JsonObject -import io.realm.RealmObject -import io.realm.annotations.Ignore -import io.realm.annotations.PrimaryKey +import io.realm.kotlin.types.RealmObject +import io.realm.kotlin.types.annotations.Ignore +import io.realm.kotlin.types.annotations.PrimaryKey import org.ole.planet.myplanet.utilities.NetworkUtils -open class RealmApkLog : RealmObject() { +class RealmApkLog : RealmObject { @PrimaryKey var id: String? = null var userId: String? = null @@ -21,24 +21,17 @@ open class RealmApkLog : RealmObject() { var time: String? = null fun setError(e: Throwable) { - error += "--------- Stack trace ---------\n\n" + error = (error ?: "") + "--------- Stack trace ---------\n\n" appendReport(e) error += "--------- Cause ---------\n\n" - val cause = e.cause - appendReport(cause) + appendReport(e.cause) } private fun appendReport(cause: Throwable?) { - if (cause != null) { - error += """ - $cause - - - """.trimIndent() - val arr = cause.stackTrace - for (i in arr.indices) { - error += """ ${arr[i]} -""" + cause?.let { + error += "$it\n\n" + for (element in it.stackTrace) { + error += " $element\n" } } error += "-------------------------------\n\n" @@ -50,21 +43,20 @@ open class RealmApkLog : RealmObject() { @JvmStatic fun serialize(log: RealmApkLog, context: Context): JsonObject { - val `object` = JsonObject() - `object`.addProperty("type", log.type) - `object`.addProperty("error", log.error) - `object`.addProperty("page", log.page) - `object`.addProperty("time", log.time) - `object`.addProperty("userId", log.userId) - `object`.addProperty("version", log.version) - `object`.addProperty("createdOn", log.createdOn) - `object`.addProperty("androidId", log.createdOn) - `object`.addProperty("createdOn", log.createdOn) - `object`.addProperty("androidId", NetworkUtils.getUniqueIdentifier()) - `object`.addProperty("deviceName", NetworkUtils.getDeviceName()) - `object`.addProperty("customDeviceName", NetworkUtils.getCustomDeviceName(context)) - `object`.addProperty("parentCode", log.parentCode) - return `object` + val jsonObject = JsonObject().apply { + addProperty("type", log.type) + addProperty("error", log.error) + addProperty("page", log.page) + addProperty("time", log.time) + addProperty("userId", log.userId) + addProperty("version", log.version) + addProperty("createdOn", log.createdOn) + addProperty("androidId", NetworkUtils.getUniqueIdentifier()) + addProperty("deviceName", NetworkUtils.getDeviceName()) + addProperty("customDeviceName", NetworkUtils.getCustomDeviceName(context)) + addProperty("parentCode", log.parentCode) + } + return jsonObject } } -} \ No newline at end of file +} diff --git a/app/src/main/java/org/ole/planet/myplanet/model/RealmCertification.kt b/app/src/main/java/org/ole/planet/myplanet/model/RealmCertification.kt index 0e258dfb8c..0d6c5e8806 100644 --- a/app/src/main/java/org/ole/planet/myplanet/model/RealmCertification.kt +++ b/app/src/main/java/org/ole/planet/myplanet/model/RealmCertification.kt @@ -1,45 +1,54 @@ package org.ole.planet.myplanet.model -import com.google.gson.Gson import com.google.gson.JsonArray import com.google.gson.JsonObject import com.opencsv.CSVWriter -import io.realm.Realm -import io.realm.RealmObject -import io.realm.annotations.PrimaryKey +import io.realm.kotlin.Realm +import io.realm.kotlin.ext.query +import io.realm.kotlin.types.RealmList +import io.realm.kotlin.types.RealmObject +import io.realm.kotlin.types.annotations.PrimaryKey +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext import org.ole.planet.myplanet.MainApplication.Companion.context import org.ole.planet.myplanet.utilities.JsonUtils import java.io.File import java.io.FileWriter import java.io.IOException -open class RealmCertification : RealmObject() { +class RealmCertification : RealmObject { @PrimaryKey var _id: String? = null var _rev: String? = null var name: String? = null - private var courseIds: String? = null + var courseIds: RealmList? = null fun setCourseIds(courseIds: JsonArray?) { - this.courseIds = Gson().toJson(courseIds) + this.courseIds?.clear() + courseIds?.forEach { courseId -> + this.courseIds?.add(courseId.asString) + } } companion object { private val certificationDataList: MutableList> = mutableListOf() @JvmStatic - fun insert(mRealm: Realm, `object`: JsonObject?) { - if (!mRealm.isInTransaction) { - mRealm.beginTransaction() - } + suspend fun insert(realm: Realm, `object`: JsonObject?) { val id = JsonUtils.getString("_id", `object`) - var certification = mRealm.where(RealmCertification::class.java).equalTo("_id", id).findFirst() - if (certification == null) { - certification = mRealm.createObject(RealmCertification::class.java, id) + withContext(Dispatchers.IO) { + realm.write { + var certification = query("_id == $0", id).first().find() + if (certification == null) { + certification = RealmCertification().apply { _id = id } + copyToRealm(certification) + } + certification.apply { + name = JsonUtils.getString("name", `object`) + setCourseIds(JsonUtils.getJsonArray("courseIds", `object`)) + } + } } - certification?.name = JsonUtils.getString("name", `object`) - certification?.setCourseIds(JsonUtils.getJsonArray("courseIds", `object`)) - mRealm.commitTransaction() val csvRow = arrayOf( JsonUtils.getString("_id", `object`), JsonUtils.getString("name", `object`), @@ -50,13 +59,9 @@ open class RealmCertification : RealmObject() { @JvmStatic fun isCourseCertified(realm: Realm, courseId: String?): Boolean { - // FIXME - if (courseId == null) { - return false - } - val c = - realm.where(RealmCertification::class.java).contains("courseIds", courseId).count() - return c > 0 + if (courseId == null) return false + val count = realm.query("courseIds CONTAINS $0", courseId).count().find() + return count > 0 } @JvmStatic @@ -64,12 +69,12 @@ open class RealmCertification : RealmObject() { try { val file = File(filePath) file.parentFile?.mkdirs() - val writer = CSVWriter(FileWriter(file)) - writer.writeNext(arrayOf("certificationId", "name", "courseIds")) - for (row in data) { - writer.writeNext(row) + CSVWriter(FileWriter(file)).use { writer -> + writer.writeNext(arrayOf("certificationId", "name", "courseIds")) + data.forEach { row -> + writer.writeNext(row) + } } - writer.close() } catch (e: IOException) { e.printStackTrace() } @@ -81,3 +86,4 @@ open class RealmCertification : RealmObject() { } } } + diff --git a/app/src/main/java/org/ole/planet/myplanet/service/SyncManager.kt b/app/src/main/java/org/ole/planet/myplanet/service/SyncManager.kt index 4766a88e3f..48f53cfc79 100644 --- a/app/src/main/java/org/ole/planet/myplanet/service/SyncManager.kt +++ b/app/src/main/java/org/ole/planet/myplanet/service/SyncManager.kt @@ -45,7 +45,7 @@ class SyncManager private constructor(private val context: Context) { private val stringArray = arrayOfNulls(4) private var shelfDoc: Rows? = null private var listener: SyncListener? = null - private val dbService: DatabaseService = DatabaseService(context) + private val dbService: DatabaseService = DatabaseService() fun start(listener: SyncListener?) { this.listener = listener diff --git a/app/src/main/java/org/ole/planet/myplanet/service/TaskNotificationWorker.kt b/app/src/main/java/org/ole/planet/myplanet/service/TaskNotificationWorker.kt index 8b3d3440d6..5610ebf71b 100644 --- a/app/src/main/java/org/ole/planet/myplanet/service/TaskNotificationWorker.kt +++ b/app/src/main/java/org/ole/planet/myplanet/service/TaskNotificationWorker.kt @@ -12,7 +12,7 @@ import java.util.Calendar class TaskNotificationWorker(private val context: Context, workerParams: WorkerParameters) : Worker(context, workerParams) { override fun doWork(): Result { - val mRealm = DatabaseService(context).realmInstance + val mRealm = DatabaseService().realmInstance val current = Calendar.getInstance().timeInMillis val tomorrow = Calendar.getInstance() tomorrow.add(Calendar.DAY_OF_YEAR, 1) diff --git a/app/src/main/java/org/ole/planet/myplanet/service/UploadManager.kt b/app/src/main/java/org/ole/planet/myplanet/service/UploadManager.kt index f0c4bd6abb..d96da79c6e 100644 --- a/app/src/main/java/org/ole/planet/myplanet/service/UploadManager.kt +++ b/app/src/main/java/org/ole/planet/myplanet/service/UploadManager.kt @@ -71,7 +71,7 @@ import java.util.Date class UploadManager(var context: Context) : FileUploadService() { var pref: SharedPreferences = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE) - private val dbService: DatabaseService = DatabaseService(context) + private val dbService: DatabaseService = DatabaseService() lateinit var mRealm: Realm private fun uploadNewsActivities() { @@ -236,7 +236,7 @@ class UploadManager(var context: Context) : FileUploadService() { } fun uploadSubmitPhotos(listener: SuccessListener?) { - mRealm = DatabaseService(context).realmInstance + mRealm = DatabaseService().realmInstance val apiInterface = client?.create(ApiInterface::class.java) mRealm.executeTransactionAsync { realm: Realm -> val data: List = realm.where(RealmSubmitPhotos::class.java).equalTo("uploaded", false).findAll() @@ -259,7 +259,7 @@ class UploadManager(var context: Context) : FileUploadService() { } fun uploadResource(listener: SuccessListener?) { - mRealm = DatabaseService(context).realmInstance + mRealm = DatabaseService().realmInstance val apiInterface = client?.create(ApiInterface::class.java) mRealm.executeTransactionAsync { realm: Realm -> val user = realm.where(RealmUserModel::class.java).equalTo("id", pref.getString("userId", "")).findFirst() @@ -282,7 +282,7 @@ class UploadManager(var context: Context) : FileUploadService() { } fun uploadMyPersonal(personal: RealmMyPersonal, listener: SuccessListener) { - mRealm = DatabaseService(context).realmInstance + mRealm = DatabaseService().realmInstance val apiInterface = client?.create(ApiInterface::class.java) if (!personal.isUploaded) { apiInterface?.postDoc(Utilities.header, "application/json", Utilities.getUrl() + "/resources", serialize(personal, context))?.enqueue(object : Callback { @@ -310,7 +310,7 @@ class UploadManager(var context: Context) : FileUploadService() { } fun uploadTeamTask() { - mRealm = DatabaseService(context).realmInstance + mRealm = DatabaseService().realmInstance val apiInterface = client?.create(ApiInterface::class.java) mRealm.executeTransactionAsync { realm: Realm -> val list: List = realm.where(RealmTeamTask::class.java).findAll() diff --git a/app/src/main/java/org/ole/planet/myplanet/service/UploadToShelfService.kt b/app/src/main/java/org/ole/planet/myplanet/service/UploadToShelfService.kt index 652c0e1531..c13bd053b4 100644 --- a/app/src/main/java/org/ole/planet/myplanet/service/UploadToShelfService.kt +++ b/app/src/main/java/org/ole/planet/myplanet/service/UploadToShelfService.kt @@ -31,7 +31,7 @@ import java.io.IOException import java.util.Date class UploadToShelfService(context: Context) { - private val dbService: DatabaseService = DatabaseService(context) + private val dbService: DatabaseService = DatabaseService() private val sharedPreferences: SharedPreferences = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE) lateinit var mRealm: Realm diff --git a/app/src/main/java/org/ole/planet/myplanet/service/UserProfileDbHandler.kt b/app/src/main/java/org/ole/planet/myplanet/service/UserProfileDbHandler.kt index 71a46e768f..ec52dc7f97 100644 --- a/app/src/main/java/org/ole/planet/myplanet/service/UserProfileDbHandler.kt +++ b/app/src/main/java/org/ole/planet/myplanet/service/UserProfileDbHandler.kt @@ -27,7 +27,7 @@ class UserProfileDbHandler(context: Context) { init { try { val validContext = context.applicationContext ?: throw IllegalArgumentException("Invalid context provided") - realmService = DatabaseService(validContext) + realmService = DatabaseService() settings = validContext.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE) fullName = Utilities.getUserName(settings) mRealm = realmService.realmInstance diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/SettingActivity.kt b/app/src/main/java/org/ole/planet/myplanet/ui/SettingActivity.kt index 5a7f192220..d1ff4a965f 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/SettingActivity.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/SettingActivity.kt @@ -132,7 +132,7 @@ class SettingActivity : AppCompatActivity() { } private fun clearDataButtonInit() { - val mRealm = DatabaseService(requireActivity()).realmInstance + val mRealm = DatabaseService().realmInstance val preference = findPreference("reset_app") if (preference != null) { preference.onPreferenceClickListener = OnPreferenceClickListener { diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/chat/ChatDetailFragment.kt b/app/src/main/java/org/ole/planet/myplanet/ui/chat/ChatDetailFragment.kt index a1b1696a1b..bcee911611 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/chat/ChatDetailFragment.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/chat/ChatDetailFragment.kt @@ -47,7 +47,7 @@ class ChatDetailFragment : Fragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - mRealm = DatabaseService(requireContext()).realmInstance + mRealm = DatabaseService().realmInstance user = UserProfileDbHandler(requireContext()).userModel mAdapter = ChatAdapter(ArrayList(), requireContext(), fragmentChatDetailBinding.recyclerGchat) fragmentChatDetailBinding.recyclerGchat.adapter = mAdapter diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/chat/ChatHistoryListAdapter.kt b/app/src/main/java/org/ole/planet/myplanet/ui/chat/ChatHistoryListAdapter.kt index 91e0646a3b..f4823f8c8c 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/chat/ChatHistoryListAdapter.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/chat/ChatHistoryListAdapter.kt @@ -69,7 +69,7 @@ class ChatHistoryListAdapter(var context: Context, private var chatHistory: List override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { rowChatHistoryBinding = RowChatHistoryBinding.inflate(LayoutInflater.from(parent.context), parent, false) - mRealm = DatabaseService(context).realmInstance + mRealm = DatabaseService().realmInstance user = UserProfileDbHandler(context).userModel newsList = mRealm.where(RealmNews::class.java) .equalTo("docType", "message", Case.INSENSITIVE) diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/chat/ChatHistoryListFragment.kt b/app/src/main/java/org/ole/planet/myplanet/ui/chat/ChatHistoryListFragment.kt index 70dad54f61..bb8012ec49 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/chat/ChatHistoryListFragment.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/chat/ChatHistoryListFragment.kt @@ -69,7 +69,7 @@ class ChatHistoryListFragment : Fragment() { } fun refreshChatHistoryList() { - val mRealm = DatabaseService(requireActivity()).realmInstance + val mRealm = DatabaseService().realmInstance val list = mRealm.where(RealmChatHistory::class.java).equalTo("user", user?.name) .sort("id", Sort.DESCENDING) .findAll() diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/community/AddLinkFragment.kt b/app/src/main/java/org/ole/planet/myplanet/ui/community/AddLinkFragment.kt index cbc32cde15..5a978173cd 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/community/AddLinkFragment.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/community/AddLinkFragment.kt @@ -66,7 +66,7 @@ class AddLinkFragment : BottomSheetDialogFragment(), AdapterView.OnItemSelectedL override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - mRealm = DatabaseService(requireActivity()).realmInstance + mRealm = DatabaseService().realmInstance fragmentAddLinkBinding.spnLink.onItemSelectedListener = this fragmentAddLinkBinding.btnSave.setOnClickListener { val type = fragmentAddLinkBinding.spnLink.selectedItem.toString() diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/community/CommunityFragment.kt b/app/src/main/java/org/ole/planet/myplanet/ui/community/CommunityFragment.kt index dac4e44a56..5923c0ff36 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/community/CommunityFragment.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/community/CommunityFragment.kt @@ -51,7 +51,7 @@ class CommunityFragment : BaseContainerFragment(), AdapterNews.OnNewsItemClickLi override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - mRealm = DatabaseService(requireActivity()).realmInstance + mRealm = DatabaseService().realmInstance user = UserProfileDbHandler(requireActivity()).userModel fragmentCommunityBinding.btnLibrary.setOnClickListener { homeItemClickListener?.openCallFragment(ResourcesFragment()) diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/community/ServicesFragment.kt b/app/src/main/java/org/ole/planet/myplanet/ui/community/ServicesFragment.kt index 1eb4515e97..6dbe239f3f 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/community/ServicesFragment.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/community/ServicesFragment.kt @@ -33,7 +33,7 @@ class ServicesFragment : BaseTeamFragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - mRealm = DatabaseService(requireActivity()).realmInstance + mRealm = DatabaseService().realmInstance user = UserProfileDbHandler(requireActivity()).userModel val links = mRealm.where(RealmMyTeam::class.java)?.equalTo("docType", "link")?.findAll() diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/courses/CourseDetailFragment.kt b/app/src/main/java/org/ole/planet/myplanet/ui/courses/CourseDetailFragment.kt index a2f6b1ccb2..96d7cc530f 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/courses/CourseDetailFragment.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/courses/CourseDetailFragment.kt @@ -38,7 +38,7 @@ class CourseDetailFragment : BaseContainerFragment(), OnRatingChangeListener { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { fragmentCourseDetailBinding = FragmentCourseDetailBinding.inflate(inflater, container, false) - dbService = DatabaseService(requireActivity()) + dbService = DatabaseService() cRealm = dbService.realmInstance courses = cRealm.where(RealmMyCourse::class.java).equalTo("courseId", id).findFirst() user = UserProfileDbHandler(requireContext()).userModel diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/courses/CourseProgressActivity.kt b/app/src/main/java/org/ole/planet/myplanet/ui/courses/CourseProgressActivity.kt index 55f1445646..f6edffc313 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/courses/CourseProgressActivity.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/courses/CourseProgressActivity.kt @@ -31,7 +31,7 @@ class CourseProgressActivity : BaseActivity() { setContentView(activityCourseProgressBinding.root) initActionBar() courseId = intent.getStringExtra("courseId").toString() - realm = DatabaseService(this).realmInstance + realm = DatabaseService().realmInstance user = UserProfileDbHandler(this).userModel val courseProgress = RealmCourseProgress.getCourseProgress(realm, user?.id) val progress = courseProgress[courseId] diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/courses/CourseStepFragment.kt b/app/src/main/java/org/ole/planet/myplanet/ui/courses/CourseStepFragment.kt index 2bd0edf5e2..b50e11cc43 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/courses/CourseStepFragment.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/courses/CourseStepFragment.kt @@ -54,7 +54,7 @@ class CourseStepFragment : BaseContainerFragment(), ImageCaptureCallback { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { fragmentCourseStepBinding = FragmentCourseStepBinding.inflate(inflater, container, false) - dbService = DatabaseService(requireActivity()) + dbService = DatabaseService() cRealm = dbService.realmInstance user = UserProfileDbHandler(requireContext()).userModel fragmentCourseStepBinding.btnTakeTest.visibility = View.VISIBLE diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/courses/MyProgressFragment.kt b/app/src/main/java/org/ole/planet/myplanet/ui/courses/MyProgressFragment.kt index 83f0a3c3bd..5762e2e476 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/courses/MyProgressFragment.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/courses/MyProgressFragment.kt @@ -35,7 +35,7 @@ class MyProgressFragment : Fragment() { } private fun initializeData() { - val realm = DatabaseService(requireActivity()).realmInstance + val realm = DatabaseService().realmInstance val user = UserProfileDbHandler(requireActivity()).userModel val courseData = fetchCourseData(realm, user?.id) fragmentMyProgressBinding.rvMyprogress.layoutManager = LinearLayoutManager(requireActivity()) diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/courses/TakeCourseFragment.kt b/app/src/main/java/org/ole/planet/myplanet/ui/courses/TakeCourseFragment.kt index 79e64139e7..bf2ce68cd7 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/courses/TakeCourseFragment.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/courses/TakeCourseFragment.kt @@ -57,7 +57,7 @@ class TakeCourseFragment : Fragment(), ViewPager.OnPageChangeListener, View.OnCl override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { fragmentTakeCourseBinding = FragmentTakeCourseBinding.inflate(inflater, container, false) - dbService = DatabaseService(requireActivity()) + dbService = DatabaseService() mRealm = dbService.realmInstance userModel = UserProfileDbHandler(requireContext()).userModel currentCourse = mRealm.where(RealmMyCourse::class.java).equalTo("courseId", courseId).findFirst() @@ -239,7 +239,7 @@ class TakeCourseFragment : Fragment(), ViewPager.OnPageChangeListener, View.OnCl } private fun getCourseProgress(): Int { - val realm = DatabaseService(requireActivity()).realmInstance + val realm = DatabaseService().realmInstance val user = UserProfileDbHandler(requireActivity()).userModel val courseProgressMap = RealmCourseProgress.getCourseProgress(realm, user?.id) val courseProgress = courseProgressMap[courseId]?.asJsonObject?.get("current")?.asInt diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/dashboard/BaseDashboardFragment.kt b/app/src/main/java/org/ole/planet/myplanet/ui/dashboard/BaseDashboardFragment.kt index 342d201de8..ad8ef8d9f1 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/dashboard/BaseDashboardFragment.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/dashboard/BaseDashboardFragment.kt @@ -106,7 +106,7 @@ open class BaseDashboardFragment : BaseDashboardFragmentPlugin(), NotificationCa } override fun forceDownloadNewsImages() { - mRealm = DatabaseService(requireContext()).realmInstance + mRealm = DatabaseService().realmInstance Utilities.toast(activity, getString(R.string.please_select_starting_date)) val now = Calendar.getInstance() val dpd = DatePickerDialog(requireActivity(), { _: DatePicker?, i: Int, i1: Int, i2: Int -> @@ -249,7 +249,7 @@ open class BaseDashboardFragment : BaseDashboardFragmentPlugin(), NotificationCa } private fun setUpMyLife(userId: String?) { - val realm = DatabaseService(requireContext()).realmInstance + val realm = DatabaseService().realmInstance val realmObjects = RealmMyLife.getMyLifeByUserId(mRealm, settings) if (realmObjects.isEmpty()) { if (!realm.isInTransaction) { @@ -321,7 +321,7 @@ open class BaseDashboardFragment : BaseDashboardFragmentPlugin(), NotificationCa view.findViewById(R.id.txtFullName).setOnClickListener { homeItemClickListener?.openCallFragment(UserProfileFragment()) } - dbService = DatabaseService(requireContext()) + dbService = DatabaseService() mRealm = dbService.realmInstance myLibraryDiv(view) initializeFlexBoxView(view, R.id.flexboxLayoutCourse, RealmMyCourse::class.java) diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/dashboard/DashboardFragment.kt b/app/src/main/java/org/ole/planet/myplanet/ui/dashboard/DashboardFragment.kt index 0e087c85f7..93b48205d9 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/dashboard/DashboardFragment.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/dashboard/DashboardFragment.kt @@ -41,7 +41,7 @@ class DashboardFragment : BaseDashboardFragment() { fragmentHomeBinding.cardProfile.tvAchievement.setOnClickListener { homeItemClickListener?.openCallFragment(AchievementFragment()) } - databaseService = DatabaseService(requireActivity()) + databaseService = DatabaseService() dRealm = databaseService.realmInstance user = UserProfileDbHandler(requireContext()).userModel onLoaded(view) diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/dashboard/MyActivityFragment.kt b/app/src/main/java/org/ole/planet/myplanet/ui/dashboard/MyActivityFragment.kt index 78e8fe346d..c12694f864 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/dashboard/MyActivityFragment.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/dashboard/MyActivityFragment.kt @@ -32,7 +32,7 @@ class MyActivityFragment : Fragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) val userModel = UserProfileDbHandler(requireActivity()).userModel - realm = DatabaseService(requireActivity()).realmInstance + realm = DatabaseService().realmInstance val calendar = Calendar.getInstance() val daynight_textColor = ResourcesCompat.getColor(getResources(), R.color.daynight_textColor, null); diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/dashboard/notification/NotificationsFragment.kt b/app/src/main/java/org/ole/planet/myplanet/ui/dashboard/notification/NotificationsFragment.kt index b642cd3b88..8fef0959c5 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/dashboard/notification/NotificationsFragment.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/dashboard/notification/NotificationsFragment.kt @@ -50,7 +50,7 @@ class NotificationsFragment : Fragment() { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { fragmentNotificationsBinding = FragmentNotificationsBinding.inflate(inflater, container, false) - databaseService = DatabaseService(requireActivity()) + databaseService = DatabaseService() mRealm = databaseService.realmInstance userId = arguments?.getString("userId") ?: "" diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/dictionary/DictionaryActivity.kt b/app/src/main/java/org/ole/planet/myplanet/ui/dictionary/DictionaryActivity.kt index d815b2f77e..8ed33d3fd7 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/dictionary/DictionaryActivity.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/dictionary/DictionaryActivity.kt @@ -26,7 +26,7 @@ class DictionaryActivity : BaseActivity() { setContentView(fragmentDictionaryBinding.root) initActionBar() title = getString(R.string.dictionary) - mRealm = DatabaseService(this).realmInstance + mRealm = DatabaseService().realmInstance list = mRealm.where(RealmDictionary::class.java)?.findAll() fragmentDictionaryBinding.tvResult.text = getString(R.string.list_size, list?.size) if (FileUtils.checkFileExist(Constants.DICTIONARY_URL)) { diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/enterprises/FinanceFragment.kt b/app/src/main/java/org/ole/planet/myplanet/ui/enterprises/FinanceFragment.kt index e2be64e8bc..994157deaa 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/enterprises/FinanceFragment.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/enterprises/FinanceFragment.kt @@ -47,7 +47,7 @@ class FinanceFragment : BaseTeamFragment() { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { fragmentFinanceBinding = FragmentFinanceBinding.inflate(inflater, container, false) - fRealm = DatabaseService(requireActivity()).realmInstance + fRealm = DatabaseService().realmInstance date = Calendar.getInstance() fragmentFinanceBinding.btnFilter.setOnClickListener { showDatePickerDialog() } list = fRealm.where(RealmMyTeam::class.java).notEqualTo("status", "archived") diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/enterprises/ReportsFragment.kt b/app/src/main/java/org/ole/planet/myplanet/ui/enterprises/ReportsFragment.kt index 5d2026f437..cd67fd87ae 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/enterprises/ReportsFragment.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/enterprises/ReportsFragment.kt @@ -40,7 +40,7 @@ class ReportsFragment : BaseTeamFragment() { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { fragmentReportsBinding = FragmentReportsBinding.inflate(inflater, container, false) - mRealm = DatabaseService(requireActivity()).realmInstance + mRealm = DatabaseService().realmInstance prefData = SharedPrefManager(requireContext()) if (!isMember()) { fragmentReportsBinding.addReports.visibility = View.GONE diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/exam/BaseExamFragment.kt b/app/src/main/java/org/ole/planet/myplanet/ui/exam/BaseExamFragment.kt index 5a7a0402be..3e359c7e2b 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/exam/BaseExamFragment.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/exam/BaseExamFragment.kt @@ -54,7 +54,7 @@ abstract class BaseExamFragment : Fragment(), ImageCaptureCallback { var submitId = "" override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - db = DatabaseService(requireActivity()) + db = DatabaseService() mRealm = db.realmInstance if (arguments != null) { stepId = requireArguments().getString("stepId") diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/exam/UserInformationFragment.kt b/app/src/main/java/org/ole/planet/myplanet/ui/exam/UserInformationFragment.kt index 6fa96ca8b4..5bed268fff 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/exam/UserInformationFragment.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/exam/UserInformationFragment.kt @@ -33,7 +33,7 @@ class UserInformationFragment : BaseDialogFragment(), View.OnClickListener { var userModel: RealmUserModel? = null override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { fragmentUserInformationBinding = FragmentUserInformationBinding.inflate(inflater, container, false) - mRealm = DatabaseService(requireActivity()).realmInstance + mRealm = DatabaseService().realmInstance userModel = UserProfileDbHandler(requireContext()).userModel if (!TextUtils.isEmpty(id)) { submissions = mRealm.where(RealmSubmission::class.java).equalTo("id", id).findFirst() diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/feedback/FeedbackDetailActivity.kt b/app/src/main/java/org/ole/planet/myplanet/ui/feedback/FeedbackDetailActivity.kt index de398b80d7..67f51c53b1 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/feedback/FeedbackDetailActivity.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/feedback/FeedbackDetailActivity.kt @@ -45,7 +45,7 @@ class FeedbackDetailActivity : AppCompatActivity() { supportActionBar?.setHomeButtonEnabled(true) supportActionBar?.setDisplayHomeAsUpEnabled(true) setTitle(R.string.feedback) - realm = DatabaseService(this).realmInstance + realm = DatabaseService().realmInstance feedback = realm.where(RealmFeedback::class.java).equalTo("id", intent.getStringExtra("id")).findFirst()!! activityFeedbackDetailBinding.tvDate.text = getFormatedDateWithTime(feedback.openTime) activityFeedbackDetailBinding.tvMessage.text = if (TextUtils.isEmpty(feedback.message)) diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/feedback/FeedbackFragment.kt b/app/src/main/java/org/ole/planet/myplanet/ui/feedback/FeedbackFragment.kt index 6b9ae244a9..75059c8f80 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/feedback/FeedbackFragment.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/feedback/FeedbackFragment.kt @@ -43,7 +43,7 @@ class FeedbackFragment : DialogFragment(), View.OnClickListener { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { fragmentFeedbackBinding = FragmentFeedbackBinding.inflate(inflater, container, false) - databaseService = DatabaseService(requireActivity()) + databaseService = DatabaseService() mRealm = databaseService.realmInstance model = UserProfileDbHandler(requireContext()).userModel user = model?.name diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/feedback/FeedbackListFragment.kt b/app/src/main/java/org/ole/planet/myplanet/ui/feedback/FeedbackListFragment.kt index bf49250c18..0420dd8a09 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/feedback/FeedbackListFragment.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/feedback/FeedbackListFragment.kt @@ -24,7 +24,7 @@ class FeedbackListFragment : Fragment(), OnFeedbackSubmittedListener { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { fragmentFeedbackListBinding = FragmentFeedbackListBinding.inflate(inflater, container, false) - mRealm = DatabaseService(requireActivity()).realmInstance + mRealm = DatabaseService().realmInstance userModel = UserProfileDbHandler(requireContext()).userModel fragmentFeedbackListBinding.fab.setOnClickListener { diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/myPersonals/MyPersonalsFragment.kt b/app/src/main/java/org/ole/planet/myplanet/ui/myPersonals/MyPersonalsFragment.kt index eb2e624d7b..ffae749acf 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/myPersonals/MyPersonalsFragment.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/myPersonals/MyPersonalsFragment.kt @@ -35,7 +35,7 @@ class MyPersonalsFragment : Fragment(), OnSelectedMyPersonal { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { fragmentMyPersonalsBinding = FragmentMyPersonalsBinding.inflate(inflater, container, false) pg = DialogUtils.getCustomProgressDialog(requireContext()) - mRealm = DatabaseService(requireActivity()).realmInstance + mRealm = DatabaseService().realmInstance fragmentMyPersonalsBinding.rvMypersonal.layoutManager = LinearLayoutManager(activity) fragmentMyPersonalsBinding.addMyPersonal.setOnClickListener { addResourceFragment = AddResourceFragment() diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/myhealth/AddExaminationActivity.kt b/app/src/main/java/org/ole/planet/myplanet/ui/myhealth/AddExaminationActivity.kt index 9d150df6d7..fadc52aa2f 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/myhealth/AddExaminationActivity.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/myhealth/AddExaminationActivity.kt @@ -70,7 +70,7 @@ class AddExaminationActivity : AppCompatActivity(), CompoundButton.OnCheckedChan initViews() currentUser = UserProfileDbHandler(this).userModel mapConditions = HashMap() - mRealm = DatabaseService(this).realmInstance + mRealm = DatabaseService().realmInstance userId = intent.getStringExtra("userId") pojo = mRealm.where(RealmMyHealthPojo::class.java).equalTo("_id", userId).findFirst() if (pojo == null) { diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/myhealth/AddMyHealthActivity.kt b/app/src/main/java/org/ole/planet/myplanet/ui/myhealth/AddMyHealthActivity.kt index a5fabaf095..5649a5b11a 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/myhealth/AddMyHealthActivity.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/myhealth/AddMyHealthActivity.kt @@ -39,7 +39,7 @@ class AddMyHealthActivity : AppCompatActivity() { setContentView(activityAddMyHealthBinding.root) supportActionBar?.setDisplayHomeAsUpEnabled(true) supportActionBar?.setHomeButtonEnabled(true) - realm = DatabaseService(this).realmInstance + realm = DatabaseService().realmInstance userId = intent.getStringExtra("userId") healthPojo = realm.where(RealmMyHealthPojo::class.java).equalTo("_id", userId).findFirst() if (healthPojo == null) { diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/myhealth/MyHealthFragment.kt b/app/src/main/java/org/ole/planet/myplanet/ui/myhealth/MyHealthFragment.kt index 41928e10ca..66396ceb55 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/myhealth/MyHealthFragment.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/myhealth/MyHealthFragment.kt @@ -51,7 +51,7 @@ class MyHealthFragment : Fragment() { var dialog: AlertDialog? = null override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { fragmentVitalSignBinding = FragmentVitalSignBinding.inflate(inflater, container, false) - mRealm = DatabaseService(requireContext()).realmInstance + mRealm = DatabaseService().realmInstance return fragmentVitalSignBinding.root } diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/mymeetup/MyMeetupDetailFragment.kt b/app/src/main/java/org/ole/planet/myplanet/ui/mymeetup/MyMeetupDetailFragment.kt index 93718d35f4..e0ff97c323 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/mymeetup/MyMeetupDetailFragment.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/mymeetup/MyMeetupDetailFragment.kt @@ -45,7 +45,7 @@ class MyMeetupDetailFragment : Fragment(), View.OnClickListener { fragmentMyMeetupDetailBinding.btnInvite.visibility = if (showBetaFeature(Constants.KEY_MEETUPS, requireContext())) View.VISIBLE else View.GONE fragmentMyMeetupDetailBinding.btnLeave.visibility = if (showBetaFeature(Constants.KEY_MEETUPS, requireContext())) View.VISIBLE else View.GONE fragmentMyMeetupDetailBinding.btnLeave.setOnClickListener(this) - mRealm = DatabaseService(requireActivity()).realmInstance + mRealm = DatabaseService().realmInstance profileDbHandler = UserProfileDbHandler(requireContext()) user = profileDbHandler?.userModel?.let { mRealm.copyFromRealm(it) } return fragmentMyMeetupDetailBinding.root diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/news/NewsDetailActivity.kt b/app/src/main/java/org/ole/planet/myplanet/ui/news/NewsDetailActivity.kt index 1cf872f573..5cbc83072f 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/news/NewsDetailActivity.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/news/NewsDetailActivity.kt @@ -32,7 +32,7 @@ class NewsDetailActivity : BaseActivity() { setContentView(activityNewsDetailBinding.root) setSupportActionBar(activityNewsDetailBinding.toolbar) initActionBar() - realm = DatabaseService(this).realmInstance + realm = DatabaseService().realmInstance val id = intent.getStringExtra("newsId") news = realm.where(RealmNews::class.java).equalTo("id", id).findFirst() if (news == null) { diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/news/NewsFragment.kt b/app/src/main/java/org/ole/planet/myplanet/ui/news/NewsFragment.kt index 51e4bb5567..01f23334ce 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/news/NewsFragment.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/news/NewsFragment.kt @@ -38,7 +38,7 @@ class NewsFragment : BaseNewsFragment() { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { fragmentNewsBinding = FragmentNewsBinding.inflate(inflater, container, false) llImage = fragmentNewsBinding.llImages - mRealm = DatabaseService(requireActivity()).realmInstance + mRealm = DatabaseService().realmInstance user = UserProfileDbHandler(requireContext()).userModel setupUI(fragmentNewsBinding.newsFragmentParentLayout, requireActivity()) if (user?.id?.startsWith("guest") == true) { diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/news/ReplyActivity.kt b/app/src/main/java/org/ole/planet/myplanet/ui/news/ReplyActivity.kt index 8175e4ce21..58db187cb3 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/news/ReplyActivity.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/news/ReplyActivity.kt @@ -51,7 +51,7 @@ open class ReplyActivity : AppCompatActivity(), OnNewsItemClickListener { setContentView(activityReplyBinding.root) supportActionBar?.setDisplayHomeAsUpEnabled(true) supportActionBar?.setHomeButtonEnabled(true) - mRealm = DatabaseService(this).realmInstance + mRealm = DatabaseService().realmInstance title = "Reply" imageList = RealmList() id = intent.getStringExtra("id") diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/rating/RatingFragment.kt b/app/src/main/java/org/ole/planet/myplanet/ui/rating/RatingFragment.kt index 641e98c6e9..491ca281b8 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/rating/RatingFragment.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/rating/RatingFragment.kt @@ -49,7 +49,7 @@ class RatingFragment : DialogFragment() { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { fragmentRatingBinding = FragmentRatingBinding.inflate(inflater, container, false) - databaseService = DatabaseService(requireActivity()) + databaseService = DatabaseService() mRealm = databaseService.realmInstance settings = requireActivity().getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE) return fragmentRatingBinding.root diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/resources/AddResourceActivity.kt b/app/src/main/java/org/ole/planet/myplanet/ui/resources/AddResourceActivity.kt index 3879394fc9..837bc0ba52 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/resources/AddResourceActivity.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/resources/AddResourceActivity.kt @@ -50,7 +50,7 @@ class AddResourceActivity : AppCompatActivity() { levels = RealmList() subjects = RealmList() resourceFor = RealmList() - mRealm = DatabaseService(this).realmInstance + mRealm = DatabaseService().realmInstance initializeViews() } diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/resources/AddResourceFragment.kt b/app/src/main/java/org/ole/planet/myplanet/ui/resources/AddResourceFragment.kt index e001fa0396..b577d97665 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/resources/AddResourceFragment.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/resources/AddResourceFragment.kt @@ -293,7 +293,7 @@ class AddResourceFragment : BottomSheetDialogFragment() { return@setPositiveButton } val desc = etDesc.text.toString().trim { it <= ' ' } - val realm = DatabaseService(context).realmInstance + val realm = DatabaseService().realmInstance realm.executeTransactionAsync( Realm.Transaction { realm1: Realm -> val myPersonal = realm1.createObject(RealmMyPersonal::class.java, UUID.randomUUID().toString()) myPersonal.title = title diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/resources/CollectionsFragment.kt b/app/src/main/java/org/ole/planet/myplanet/ui/resources/CollectionsFragment.kt index a3e9648c9e..798620b714 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/resources/CollectionsFragment.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/resources/CollectionsFragment.kt @@ -39,7 +39,7 @@ class CollectionsFragment : DialogFragment(), TagExpandableAdapter.OnClickTagIte override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { fragmentCollectionsBinding = FragmentCollectionsBinding.inflate(inflater, container, false) - mRealm = DatabaseService(requireActivity()).realmInstance + mRealm = DatabaseService().realmInstance KeyboardUtils.hideSoftKeyboard(requireActivity()) return fragmentCollectionsBinding.root } diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/resources/ResourceDetailFragment.kt b/app/src/main/java/org/ole/planet/myplanet/ui/resources/ResourceDetailFragment.kt index 6a6f5fc0d4..1632cac728 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/resources/ResourceDetailFragment.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/resources/ResourceDetailFragment.kt @@ -52,7 +52,7 @@ class ResourceDetailFragment : BaseContainerFragment(), OnRatingChangeListener { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { super.onCreateView(inflater, container, savedInstanceState) fragmentLibraryDetailBinding = FragmentLibraryDetailBinding.inflate(inflater, container, false) - dbService = DatabaseService(requireActivity()) + dbService = DatabaseService() lRealm = dbService.realmInstance userModel = UserProfileDbHandler(requireContext()).userModel!! library = lRealm.where(RealmMyLibrary::class.java).equalTo("resourceId", libraryId).findFirst()!! diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/submission/MySubmissionFragment.kt b/app/src/main/java/org/ole/planet/myplanet/ui/submission/MySubmissionFragment.kt index 27816a1fb3..7c7f429d5c 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/submission/MySubmissionFragment.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/submission/MySubmissionFragment.kt @@ -45,7 +45,7 @@ class MySubmissionFragment : Fragment(), CompoundButton.OnCheckedChangeListener override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - mRealm = DatabaseService(requireActivity()).realmInstance + mRealm = DatabaseService().realmInstance fragmentMySubmissionBinding.rvMysurvey.layoutManager = LinearLayoutManager(activity) fragmentMySubmissionBinding.rvMysurvey.addItemDecoration( DividerItemDecoration(activity, DividerItemDecoration.VERTICAL) diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/survey/SendSurveyFragment.kt b/app/src/main/java/org/ole/planet/myplanet/ui/survey/SendSurveyFragment.kt index 0610e68751..d5925a2d14 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/survey/SendSurveyFragment.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/survey/SendSurveyFragment.kt @@ -29,7 +29,7 @@ class SendSurveyFragment : BaseDialogFragment() { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { fragmentSendSurveyBinding = FragmentSendSurveyBinding.inflate(inflater, container, false) - dbService = DatabaseService(requireActivity()) + dbService = DatabaseService() mRealm = dbService.realmInstance if (TextUtils.isEmpty(id)) { dismiss() @@ -40,7 +40,7 @@ class SendSurveyFragment : BaseDialogFragment() { } private fun createSurveySubmission(userId: String?) { - val mRealm = DatabaseService(requireActivity()).realmInstance + val mRealm = DatabaseService().realmInstance val exam = mRealm.where(RealmStepExam::class.java).equalTo("id", id).findFirst() mRealm.beginTransaction() var sub = mRealm.where(RealmSubmission::class.java).equalTo("userId", userId) diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/sync/SyncActivity.kt b/app/src/main/java/org/ole/planet/myplanet/ui/sync/SyncActivity.kt index 3a48b00344..33f4a2ce23 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/sync/SyncActivity.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/sync/SyncActivity.kt @@ -25,7 +25,6 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import kotlinx.serialization.json.Json -import okhttp3.ResponseBody import org.ole.planet.myplanet.BuildConfig import org.ole.planet.myplanet.MainApplication.Companion.applicationScope import org.ole.planet.myplanet.MainApplication.Companion.context @@ -57,9 +56,6 @@ import org.ole.planet.myplanet.utilities.NetworkUtils.getCustomDeviceName import org.ole.planet.myplanet.utilities.NotificationUtil.cancelAll import org.ole.planet.myplanet.utilities.Utilities.getRelativeTime import org.ole.planet.myplanet.utilities.Utilities.openDownloadService -import retrofit2.Call -import retrofit2.Callback -import retrofit2.Response import java.io.File import java.util.* import java.util.concurrent.TimeUnit @@ -107,7 +103,7 @@ abstract class SyncActivity : ProcessUserDataActivity(), SyncListener, CheckVers super.onCreate(savedInstanceState) settings = getSharedPreferences(PREFS_NAME, MODE_PRIVATE) editor = settings.edit() - mRealm = DatabaseService(this).realmInstance + mRealm = DatabaseService().realmInstance mRealm = Realm.getDefaultInstance() requestAllPermissions() customProgressDialog = DialogUtils.getCustomProgressDialog(this) diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/team/BaseTeamFragment.kt b/app/src/main/java/org/ole/planet/myplanet/ui/team/BaseTeamFragment.kt index cff58141dd..8d1e63be11 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/team/BaseTeamFragment.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/team/BaseTeamFragment.kt @@ -22,7 +22,7 @@ abstract class BaseTeamFragment : BaseNewsFragment() { val sParentCode = settings?.getString("parentCode", "") val communityName = settings?.getString("communityName", "") teamId = requireArguments().getString("id", "") ?: "$communityName@$sParentCode" - dbService = DatabaseService(requireActivity()) + dbService = DatabaseService() mRealm = dbService.realmInstance user = profileDbHandler.userModel?.let { mRealm.copyFromRealm(it) } team = try { diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/team/MyTeamsDetailFragment.kt b/app/src/main/java/org/ole/planet/myplanet/ui/team/MyTeamsDetailFragment.kt index 5aa8a1a7a9..bc4d260d62 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/team/MyTeamsDetailFragment.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/team/MyTeamsDetailFragment.kt @@ -69,7 +69,7 @@ class MyTeamsDetailFragment : BaseNewsFragment() { fragmentMyTeamsDetailBinding = FragmentMyTeamsDetailBinding.inflate(inflater, container, false) val v: View = fragmentMyTeamsDetailBinding.root initializeViews(v) - dbService = DatabaseService(requireActivity()) + dbService = DatabaseService() mRealm = dbService.realmInstance user = profileDbHandler.userModel?.let { mRealm.copyFromRealm(it) } team = mRealm.where(RealmMyTeam::class.java).equalTo("_id", teamId).findFirst() diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/team/TeamDetailFragment.kt b/app/src/main/java/org/ole/planet/myplanet/ui/team/TeamDetailFragment.kt index 13bc105782..6b2c0d1144 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/team/TeamDetailFragment.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/team/TeamDetailFragment.kt @@ -26,7 +26,7 @@ class TeamDetailFragment : BaseTeamFragment() { fragmentTeamDetailBinding = FragmentTeamDetailBinding.inflate(inflater, container, false) val isMyTeam = requireArguments().getBoolean("isMyTeam", false) val user = UserProfileDbHandler(requireContext()).userModel - mRealm = DatabaseService(requireActivity()).realmInstance + mRealm = DatabaseService().realmInstance team = mRealm.where(RealmMyTeam::class.java).equalTo("_id", teamId).findFirst() ?: throw IllegalArgumentException("Team not found for ID: $teamId") fragmentTeamDetailBinding.viewPager2.adapter = TeamPagerAdapter(requireActivity(), team, isMyTeam) TabLayoutMediator(fragmentTeamDetailBinding.tabLayout, fragmentTeamDetailBinding.viewPager2) { tab, position -> diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/team/TeamFragment.kt b/app/src/main/java/org/ole/planet/myplanet/ui/team/TeamFragment.kt index 62bb743394..43ee9e29f3 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/team/TeamFragment.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/team/TeamFragment.kt @@ -48,7 +48,7 @@ class TeamFragment : Fragment(), AdapterTeamList.OnClickTeamItem { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { fragmentTeamBinding = FragmentTeamBinding.inflate(inflater, container, false) - mRealm = DatabaseService(requireContext()).realmInstance + mRealm = DatabaseService().realmInstance user = UserProfileDbHandler(requireActivity()).userModel if (user?.isGuest() == true) { diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/userprofile/AchievementFragment.kt b/app/src/main/java/org/ole/planet/myplanet/ui/userprofile/AchievementFragment.kt index 4b10b224f0..a60daf22cd 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/userprofile/AchievementFragment.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/userprofile/AchievementFragment.kt @@ -42,7 +42,7 @@ class AchievementFragment : BaseContainerFragment() { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { fragmentAchievementBinding = FragmentAchievementBinding.inflate(inflater, container, false) - aRealm = DatabaseService(MainApplication.context).realmInstance + aRealm = DatabaseService().realmInstance user = UserProfileDbHandler(MainApplication.context).userModel fragmentAchievementBinding.btnEdit.setOnClickListener { if (listener != null) listener?.openCallFragment(EditAchievementFragment()) diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/userprofile/BecomeMemberActivity.kt b/app/src/main/java/org/ole/planet/myplanet/ui/userprofile/BecomeMemberActivity.kt index 31c89f6747..180e92af96 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/userprofile/BecomeMemberActivity.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/userprofile/BecomeMemberActivity.kt @@ -51,7 +51,7 @@ class BecomeMemberActivity : BaseActivity() { setContentView(activityBecomeMemberBinding.root) supportActionBar?.setHomeButtonEnabled(true) supportActionBar?.setDisplayHomeAsUpEnabled(true) - val mRealm: Realm = DatabaseService(this).realmInstance + val mRealm: Realm = DatabaseService().realmInstance val languages = resources.getStringArray(R.array.language) val lnAadapter = ArrayAdapter(this, R.layout.become_a_member_spinner_layout, languages) activityBecomeMemberBinding.spnLang.adapter = lnAadapter diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/userprofile/EditAchievementFragment.kt b/app/src/main/java/org/ole/planet/myplanet/ui/userprofile/EditAchievementFragment.kt index f34853948e..071d35f8b8 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/userprofile/EditAchievementFragment.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/userprofile/EditAchievementFragment.kt @@ -62,7 +62,7 @@ class EditAchievementFragment : BaseContainerFragment(), DatePickerDialog.OnDate override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { fragmentEditAchievementBinding = FragmentEditAchievementBinding.inflate(inflater, container, false) - aRealm = DatabaseService(requireActivity()).realmInstance + aRealm = DatabaseService().realmInstance user = UserProfileDbHandler(requireContext()).userModel achievementArray = JsonArray() achievement = aRealm.where(RealmAchievement::class.java).equalTo("_id", user?.id + "@" + user?.planetCode).findFirst() diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/userprofile/UserDetailFragment.kt b/app/src/main/java/org/ole/planet/myplanet/ui/userprofile/UserDetailFragment.kt index 44a9898fa5..9ac5764094 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/userprofile/UserDetailFragment.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/userprofile/UserDetailFragment.kt @@ -33,7 +33,7 @@ class UserDetailFragment : Fragment() { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { fragmentUserDetailBinding = FragmentUserDetailBinding.inflate(inflater, container, false) fragmentUserDetailBinding.rvUserDetail.layoutManager = GridLayoutManager(activity, 2) - val mRealm = DatabaseService(requireActivity()).realmInstance + val mRealm = DatabaseService().realmInstance db = UserProfileDbHandler(requireActivity()) user = mRealm.where(RealmUserModel::class.java).equalTo("id", userId).findFirst() return fragmentUserDetailBinding.root diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/userprofile/UserProfileFragment.kt b/app/src/main/java/org/ole/planet/myplanet/ui/userprofile/UserProfileFragment.kt index 4782e89ee9..faebb463ff 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/userprofile/UserProfileFragment.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/userprofile/UserProfileFragment.kt @@ -91,7 +91,7 @@ class UserProfileFragment : Fragment() { fragmentUserProfileBinding = FragmentUserProfileBinding.inflate(inflater, container, false) settings = requireContext().getSharedPreferences(PREFS_NAME, MODE_PRIVATE) handler = UserProfileDbHandler(requireContext()) - realmService = DatabaseService(requireContext()) + realmService = DatabaseService() mRealm = realmService.realmInstance fragmentUserProfileBinding.rvStat.layoutManager = LinearLayoutManager(activity) fragmentUserProfileBinding.rvStat.isNestedScrollingEnabled = false diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/viewer/PDFReaderActivity.kt b/app/src/main/java/org/ole/planet/myplanet/ui/viewer/PDFReaderActivity.kt index 267dc9b9a9..3f6a65f3fd 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/viewer/PDFReaderActivity.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/viewer/PDFReaderActivity.kt @@ -35,7 +35,7 @@ class PDFReaderActivity : AppCompatActivity(), OnPageChangeListener, OnLoadCompl activityPdfReaderBinding = ActivityPdfreaderBinding.inflate(layoutInflater) setContentView(activityPdfReaderBinding.root) audioRecorderService = AudioRecorderService().setAudioRecordListener(this) - mRealm = DatabaseService(this).realmInstance + mRealm = DatabaseService().realmInstance if (intent.hasExtra("resourceId")) { val resourceID = intent.getStringExtra("resourceId") library = mRealm.where(RealmMyLibrary::class.java).equalTo("id", resourceID).findFirst()!! diff --git a/build.gradle b/build.gradle index da7baf0208..466e0e06a7 100644 --- a/build.gradle +++ b/build.gradle @@ -18,7 +18,6 @@ buildscript { } dependencies { classpath 'com.android.tools.build:gradle:8.7.2' - classpath "io.realm:realm-gradle-plugin:10.19.0" classpath "com.google.dagger:hilt-android-gradle-plugin:2.52" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version" From 2db88dba7b04647b6897b44c684668ad252c2a56 Mon Sep 17 00:00:00 2001 From: Gideon Okuro Date: Wed, 20 Nov 2024 19:16:51 +0300 Subject: [PATCH 02/38] more models migrated to kotlin --- .../planet/myplanet/model/RealmCommunity.kt | 10 ++-- .../myplanet/model/RealmCourseActivity.kt | 55 +++++++++---------- .../planet/myplanet/model/RealmCourseStep.kt | 6 +- .../planet/myplanet/model/RealmDictionary.kt | 27 ++++----- .../ole/planet/myplanet/model/RealmMessage.kt | 28 +++++----- .../myplanet/model/RealmNotification.kt | 8 +-- .../myplanet/model/RealmTeamNotification.kt | 6 +- 7 files changed, 68 insertions(+), 72 deletions(-) diff --git a/app/src/main/java/org/ole/planet/myplanet/model/RealmCommunity.kt b/app/src/main/java/org/ole/planet/myplanet/model/RealmCommunity.kt index 7623c881c9..552933d425 100644 --- a/app/src/main/java/org/ole/planet/myplanet/model/RealmCommunity.kt +++ b/app/src/main/java/org/ole/planet/myplanet/model/RealmCommunity.kt @@ -1,9 +1,9 @@ package org.ole.planet.myplanet.model -import io.realm.RealmObject -import io.realm.annotations.PrimaryKey +import io.realm.kotlin.types.RealmObject +import io.realm.kotlin.types.annotations.PrimaryKey -open class RealmCommunity : RealmObject() { +class RealmCommunity : RealmObject { @PrimaryKey var id: String = "" var weight: Int = 10 @@ -12,7 +12,5 @@ open class RealmCommunity : RealmObject() { var name: String = "" var parentDomain: String = "" - override fun toString(): String { - return name - } + override fun toString(): String = name } \ No newline at end of file diff --git a/app/src/main/java/org/ole/planet/myplanet/model/RealmCourseActivity.kt b/app/src/main/java/org/ole/planet/myplanet/model/RealmCourseActivity.kt index 3352ec6a59..10aa37d840 100644 --- a/app/src/main/java/org/ole/planet/myplanet/model/RealmCourseActivity.kt +++ b/app/src/main/java/org/ole/planet/myplanet/model/RealmCourseActivity.kt @@ -1,14 +1,14 @@ package org.ole.planet.myplanet.model import com.google.gson.JsonObject -import io.realm.Realm -import io.realm.RealmObject -import io.realm.annotations.PrimaryKey +import io.realm.kotlin.Realm +import io.realm.kotlin.types.RealmObject +import io.realm.kotlin.types.annotations.PrimaryKey import org.ole.planet.myplanet.utilities.NetworkUtils import java.util.Date import java.util.UUID -open class RealmCourseActivity : RealmObject() { +class RealmCourseActivity : RealmObject { @PrimaryKey var id: String? = null var _id: String? = null @@ -22,35 +22,34 @@ open class RealmCourseActivity : RealmObject() { var user: String? = null companion object { - @JvmStatic fun createActivity(realm: Realm, userModel: RealmUserModel?, course: RealmMyCourse?) { - if (!realm.isInTransaction) { - realm.executeTransaction { - val activity = it.createObject(RealmCourseActivity::class.java, UUID.randomUUID().toString()) - activity.type = "visit" - activity.title = course?.courseTitle - activity.courseId = course?.courseId - activity.time = Date().time - activity.parentCode = userModel?.parentCode - activity.createdOn = userModel?.planetCode - activity.user = userModel?.name + realm.writeBlocking { + val activity = RealmCourseActivity().apply { + id = UUID.randomUUID().toString() + type = "visit" + title = course?.courseTitle + courseId = course?.courseId + time = Date().time + parentCode = userModel?.parentCode + createdOn = userModel?.planetCode + user = userModel?.name } + copyToRealm(activity) } } - @JvmStatic - fun serializeSerialize(realmCourseActivities: RealmCourseActivity): JsonObject { - val ob = JsonObject() - ob.addProperty("user", realmCourseActivities.user) - ob.addProperty("courseId", realmCourseActivities.courseId) - ob.addProperty("type", realmCourseActivities.type) - ob.addProperty("title", realmCourseActivities.title) - ob.addProperty("time", realmCourseActivities.time) - ob.addProperty("createdOn", realmCourseActivities.createdOn) - ob.addProperty("parentCode", realmCourseActivities.parentCode) - ob.addProperty("androidId", NetworkUtils.getUniqueIdentifier()) - ob.addProperty("deviceName", NetworkUtils.getDeviceName()) - return ob + fun serializeSerialize(realmCourseActivity: RealmCourseActivity): JsonObject { + return JsonObject().apply { + addProperty("user", realmCourseActivity.user) + addProperty("courseId", realmCourseActivity.courseId) + addProperty("type", realmCourseActivity.type) + addProperty("title", realmCourseActivity.title) + addProperty("time", realmCourseActivity.time) + addProperty("createdOn", realmCourseActivity.createdOn) + addProperty("parentCode", realmCourseActivity.parentCode) + addProperty("androidId", NetworkUtils.getUniqueIdentifier()) + addProperty("deviceName", NetworkUtils.getDeviceName()) + } } } } diff --git a/app/src/main/java/org/ole/planet/myplanet/model/RealmCourseStep.kt b/app/src/main/java/org/ole/planet/myplanet/model/RealmCourseStep.kt index 697889b801..af07aa162a 100644 --- a/app/src/main/java/org/ole/planet/myplanet/model/RealmCourseStep.kt +++ b/app/src/main/java/org/ole/planet/myplanet/model/RealmCourseStep.kt @@ -1,9 +1,9 @@ package org.ole.planet.myplanet.model -import io.realm.RealmObject -import io.realm.annotations.PrimaryKey +import io.realm.kotlin.types.RealmObject +import io.realm.kotlin.types.annotations.PrimaryKey -open class RealmCourseStep : RealmObject() { +class RealmCourseStep : RealmObject { @PrimaryKey var id: String? = null var courseId: String? = null diff --git a/app/src/main/java/org/ole/planet/myplanet/model/RealmDictionary.kt b/app/src/main/java/org/ole/planet/myplanet/model/RealmDictionary.kt index 0121efcc5b..de5fc188ba 100644 --- a/app/src/main/java/org/ole/planet/myplanet/model/RealmDictionary.kt +++ b/app/src/main/java/org/ole/planet/myplanet/model/RealmDictionary.kt @@ -1,16 +1,17 @@ package org.ole.planet.myplanet.model -import io.realm.RealmObject -import io.realm.annotations.PrimaryKey +import io.realm.kotlin.types.RealmObject +import io.realm.kotlin.types.annotations.PrimaryKey -open class RealmDictionary( - @PrimaryKey var id: String = "", - var word: String = "", - var meaning: String = "", - var synonym: String = "", - var advanceCode: String = "", - var code: String = "", - var definition: String = "", - var language: String = "", - var antonym: String = "" -) : RealmObject() +class RealmCourseStep : RealmObject { + @PrimaryKey + var id: String? = null + var word: String? = null + var meaning: String? = null + var synonym: String? = null + var advanceCode: String? = null + var code: String? = null + var definition: String? = null + var language: String? = null + var antonym: String? = null +} diff --git a/app/src/main/java/org/ole/planet/myplanet/model/RealmMessage.kt b/app/src/main/java/org/ole/planet/myplanet/model/RealmMessage.kt index e4ac63593d..a831141e56 100644 --- a/app/src/main/java/org/ole/planet/myplanet/model/RealmMessage.kt +++ b/app/src/main/java/org/ole/planet/myplanet/model/RealmMessage.kt @@ -3,11 +3,10 @@ package org.ole.planet.myplanet.model import com.google.gson.JsonArray import com.google.gson.JsonElement import com.google.gson.JsonObject -import io.realm.RealmList -import io.realm.RealmObject -import io.realm.annotations.PrimaryKey +import io.realm.kotlin.types.RealmObject +import io.realm.kotlin.types.annotations.PrimaryKey -open class RealmMessage : RealmObject() { +class RealmMessage : RealmObject { @PrimaryKey var id: String? = null var message: String? = null @@ -15,18 +14,17 @@ open class RealmMessage : RealmObject() { var user: String? = null companion object { - fun serialize(messages: RealmList): JsonElement { - val array = JsonArray() - for (ms in messages) { - val `object` = JsonObject() - `object`.addProperty("user", ms.user) - `object`.addProperty("time", ms.time) - `object`.addProperty("message", ms.message) - array.add(`object`) + fun serialize(messages: List): JsonElement { + return JsonArray().apply { + messages.forEach { ms -> + val `object` = JsonObject().apply { + addProperty("user", ms.user) + addProperty("time", ms.time) + addProperty("message", ms.message) + } + add(`object`) + } } - return array } - -// fun insertFeedback(mRealm: Realm?) {} } } \ No newline at end of file diff --git a/app/src/main/java/org/ole/planet/myplanet/model/RealmNotification.kt b/app/src/main/java/org/ole/planet/myplanet/model/RealmNotification.kt index bb061b6ad4..56c85a3668 100644 --- a/app/src/main/java/org/ole/planet/myplanet/model/RealmNotification.kt +++ b/app/src/main/java/org/ole/planet/myplanet/model/RealmNotification.kt @@ -1,13 +1,13 @@ package org.ole.planet.myplanet.model -import io.realm.RealmObject -import io.realm.annotations.PrimaryKey +import io.realm.kotlin.types.RealmObject +import io.realm.kotlin.types.annotations.PrimaryKey import java.util.Date import java.util.UUID -open class RealmNotification : RealmObject() { +class RealmNotification : RealmObject { @PrimaryKey - var id: String = UUID.randomUUID().toString() + var id: String = "${UUID.randomUUID()}" var userId: String = "" var message: String = "" var isRead: Boolean = false diff --git a/app/src/main/java/org/ole/planet/myplanet/model/RealmTeamNotification.kt b/app/src/main/java/org/ole/planet/myplanet/model/RealmTeamNotification.kt index 4e041ac810..db371ffecc 100644 --- a/app/src/main/java/org/ole/planet/myplanet/model/RealmTeamNotification.kt +++ b/app/src/main/java/org/ole/planet/myplanet/model/RealmTeamNotification.kt @@ -1,9 +1,9 @@ package org.ole.planet.myplanet.model -import io.realm.RealmObject -import io.realm.annotations.PrimaryKey +import io.realm.kotlin.types.RealmObject +import io.realm.kotlin.types.annotations.PrimaryKey -open class RealmTeamNotification : RealmObject() { +class RealmTeamNotification : RealmObject { @PrimaryKey var id: String? = null var type: String? = null From da5e81401dd0fefa56d2a369a1bd58addb0ca5b5 Mon Sep 17 00:00:00 2001 From: Gideon Okuro Date: Fri, 22 Nov 2024 17:42:11 +0300 Subject: [PATCH 03/38] migrate more realm models to the kotlin sdk --- .../myplanet/model/RealmSearchActivity.kt | 74 ++-- .../myplanet/model/RealmSubmitPhotos.kt | 45 +- .../org/ole/planet/myplanet/model/RealmTag.kt | 96 +++-- .../ole/planet/myplanet/model/RealmTeamLog.kt | 111 ++--- .../planet/myplanet/model/RealmTeamTask.kt | 149 +++---- .../model/RealmUserChallengeActions.kt | 30 +- .../planet/myplanet/model/RealmUserModel.kt | 390 +++++++++--------- 7 files changed, 436 insertions(+), 459 deletions(-) diff --git a/app/src/main/java/org/ole/planet/myplanet/model/RealmSearchActivity.kt b/app/src/main/java/org/ole/planet/myplanet/model/RealmSearchActivity.kt index 2d4ea838e1..02b8d0b70a 100644 --- a/app/src/main/java/org/ole/planet/myplanet/model/RealmSearchActivity.kt +++ b/app/src/main/java/org/ole/planet/myplanet/model/RealmSearchActivity.kt @@ -1,54 +1,48 @@ package org.ole.planet.myplanet.model -import com.google.gson.Gson -import com.google.gson.JsonObject -import io.realm.RealmObject -import io.realm.annotations.PrimaryKey +import io.realm.kotlin.types.RealmObject +import io.realm.kotlin.types.annotations.PrimaryKey +import kotlinx.serialization.json.JsonObject +import kotlinx.serialization.json.JsonPrimitive +import kotlinx.serialization.json.buildJsonObject import org.ole.planet.myplanet.MainApplication import org.ole.planet.myplanet.utilities.NetworkUtils import org.ole.planet.myplanet.utilities.VersionUtils -open class RealmSearchActivity( +class RealmSearchActivity : RealmObject { @PrimaryKey - var id: String = "", - var _id: String = "", - var _rev: String = "", - var text: String = "", - var type: String = "", - var time: Long = 0, - var user: String = "", - var filter: String = "", - var createdOn: String = "", + var id: String = "" + var _id: String = "" + var _rev: String = "" + var text: String = "" + var type: String = "" + var time: Long = 0 + var user: String = "" + var filter: String = "" + var createdOn: String = "" var parentCode: String = "" -) : RealmObject() { - fun serialize(): JsonObject { - val obj = JsonObject() - obj.addProperty("text", text) - obj.addProperty("type", type) - obj.addProperty("time", time) - obj.addProperty("user", user) - obj.addProperty("androidId", VersionUtils.getAndroidId(MainApplication.context)) - obj.addProperty( - "customDeviceName", NetworkUtils.getCustomDeviceName(MainApplication.context) - ) - obj.addProperty("deviceName", NetworkUtils.getDeviceName()) - obj.addProperty("createdOn", createdOn) - obj.addProperty("parentCode", parentCode) - obj.add("filter", Gson().fromJson(filter, JsonObject::class.java)) - return obj + + fun serialize(): JsonObject = buildJsonObject { + put("text", JsonPrimitive(text)) + put("type", JsonPrimitive(type)) + put("time", JsonPrimitive(time)) + put("user", JsonPrimitive(user)) + put("androidId", JsonPrimitive(VersionUtils.getAndroidId(MainApplication.context))) + put("customDeviceName", JsonPrimitive(NetworkUtils.getCustomDeviceName(MainApplication.context))) + put("deviceName", JsonPrimitive(NetworkUtils.getDeviceName())) + put("createdOn", JsonPrimitive(createdOn)) + put("parentCode", JsonPrimitive(parentCode)) + put("filter", kotlinx.serialization.json.Json.parseToJsonElement(filter)) } companion object { - @JvmStatic - fun insert(log: RealmNewsLog): JsonObject { - val ob = JsonObject() - ob.addProperty("user", log.userId) - ob.addProperty("type", log.type) - ob.addProperty("time", log.time) - ob.addProperty("androidId", NetworkUtils.getUniqueIdentifier()) - ob.addProperty("deviceName", NetworkUtils.getDeviceName()) - ob.addProperty("customDeviceName", NetworkUtils.getCustomDeviceName(MainApplication.context)) - return ob + fun insert(log: RealmNewsLog): JsonObject = buildJsonObject { + put("user", JsonPrimitive(log.userId)) + put("type", JsonPrimitive(log.type)) + put("time", JsonPrimitive(log.time)) + put("androidId", JsonPrimitive(NetworkUtils.getUniqueIdentifier())) + put("deviceName", JsonPrimitive(NetworkUtils.getDeviceName())) + put("customDeviceName", JsonPrimitive(NetworkUtils.getCustomDeviceName(MainApplication.context))) } } } \ No newline at end of file diff --git a/app/src/main/java/org/ole/planet/myplanet/model/RealmSubmitPhotos.kt b/app/src/main/java/org/ole/planet/myplanet/model/RealmSubmitPhotos.kt index 1f9b4c0b7f..5d44566711 100644 --- a/app/src/main/java/org/ole/planet/myplanet/model/RealmSubmitPhotos.kt +++ b/app/src/main/java/org/ole/planet/myplanet/model/RealmSubmitPhotos.kt @@ -1,10 +1,10 @@ package org.ole.planet.myplanet.model import com.google.gson.JsonObject -import io.realm.RealmObject -import io.realm.annotations.PrimaryKey +import io.realm.kotlin.types.RealmObject +import io.realm.kotlin.types.annotations.PrimaryKey -open class RealmSubmitPhotos : RealmObject() { +class RealmSubmitPhotos : RealmObject { @PrimaryKey var id: String? = null var _id: String? = null @@ -16,35 +16,22 @@ open class RealmSubmitPhotos : RealmObject() { var date: String? = null var uniqueId: String? = null var photoLocation: String? = null - var uploaded = false + var uploaded: Boolean = false companion object { - /** - * public static JsonArray serializeRealmSubmitPhotos(RealmList submitPhotos) - * { - * JsonArray arr = new JsonArray(); - * for(RealmSubmitPhotos sub: submitPhotos) - * { - * arr.add(createObject(sub)); - * } - * - * - * return arr; - * } - */ - @JvmStatic fun serializeRealmSubmitPhotos(submit: RealmSubmitPhotos): JsonObject { - val obj = JsonObject() - obj.addProperty("id", submit.id) - obj.addProperty("submissionId", submit.submissionId) - obj.addProperty("type", "photo") - obj.addProperty("courseId", submit.courseId) - obj.addProperty("examId", submit.examId) - obj.addProperty("memberId", submit.memberId) - obj.addProperty("date", submit.date) - obj.addProperty("macAddress", submit.uniqueId) - obj.addProperty("photoLocation", submit.photoLocation) - return obj + return JsonObject().apply { + addProperty("id", submit.id) + addProperty("submissionId", submit.submissionId) + addProperty("type", "photo") + addProperty("courseId", submit.courseId) + addProperty("examId", submit.examId) + addProperty("memberId", submit.memberId) + addProperty("date", submit.date) + addProperty("macAddress", submit.uniqueId) + addProperty("photoLocation", submit.photoLocation) + } } } } + diff --git a/app/src/main/java/org/ole/planet/myplanet/model/RealmTag.kt b/app/src/main/java/org/ole/planet/myplanet/model/RealmTag.kt index 03187d38ed..ce1e90b1c2 100644 --- a/app/src/main/java/org/ole/planet/myplanet/model/RealmTag.kt +++ b/app/src/main/java/org/ole/planet/myplanet/model/RealmTag.kt @@ -3,17 +3,17 @@ package org.ole.planet.myplanet.model import com.google.gson.JsonArray import com.google.gson.JsonObject import com.opencsv.CSVWriter -import io.realm.Realm -import io.realm.RealmList -import io.realm.RealmObject -import io.realm.annotations.PrimaryKey -import org.ole.planet.myplanet.MainApplication.Companion.context +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 org.ole.planet.myplanet.MainApplication import org.ole.planet.myplanet.utilities.JsonUtils import java.io.File import java.io.FileWriter import java.io.IOException -open class RealmTag : RealmObject() { +class RealmTag : RealmObject { @PrimaryKey var id: String? = null var _id: String? = null @@ -21,51 +21,55 @@ open class RealmTag : RealmObject() { var name: String? = null var linkId: String? = null var tagId: String? = null - var attachedTo: RealmList? = null + var attachedTo: RealmList = realmListOf() var docType: String? = null var db: String? = null - var isAttached = false - private fun setAttachedTo(attachedTo: JsonArray) { - this.attachedTo = RealmList() + var isAttached: Boolean = false + + fun setAttachedTo(attachedTo: JsonArray) { + this.attachedTo.clear() for (i in 0 until attachedTo.size()) { - this.attachedTo?.add(JsonUtils.getString(attachedTo, i)) + this.attachedTo.add(JsonUtils.getString(attachedTo, i)) } - isAttached = (this.attachedTo?.size ?: 0) > 0 + isAttached = this.attachedTo.isNotEmpty() } override fun toString(): String { - return name!! + return name ?: super.toString() } companion object { private val tagDataList: MutableList> = mutableListOf() - @JvmStatic - fun insert(mRealm: Realm, act: JsonObject) { - if (!mRealm.isInTransaction) { - mRealm.beginTransaction() - } - var tag = mRealm.where(RealmTag::class.java).equalTo("_id", JsonUtils.getString("_id", act)).findFirst() - if (tag == null) { - tag = mRealm.createObject(RealmTag::class.java, JsonUtils.getString("_id", act)) - } - if (tag != null) { - tag._rev = JsonUtils.getString("_rev", act) - tag._id = JsonUtils.getString("_id", act) - tag.name = JsonUtils.getString("name", act) - tag.db = JsonUtils.getString("db", act) - tag.docType = JsonUtils.getString("docType", act) - tag.tagId = JsonUtils.getString("tagId", act) - tag.linkId = JsonUtils.getString("linkId", act) - val el = act["attachedTo"] - if (el != null && el.isJsonArray) { - tag.setAttachedTo(JsonUtils.getJsonArray("attachedTo", act)) - } else { - tag.attachedTo?.add(JsonUtils.getString("attachedTo", act)) + suspend fun insert(realm: io.realm.kotlin.Realm, act: JsonObject?) { + if (act == null) return + + realm.write { + val id = JsonUtils.getString("_id", act) + + val existingTag = query(RealmTag::class, "id == $0", id).first().find() + + val tag = existingTag ?: copyToRealm(RealmTag().apply { + this._id = id + }) + + tag.apply { + _rev = JsonUtils.getString("_rev", act) + name = JsonUtils.getString("name", act) + db = JsonUtils.getString("db", act) + docType = JsonUtils.getString("docType", act) + tagId = JsonUtils.getString("tagId", act) + linkId = JsonUtils.getString("linkId", act) + + val el = act["attachedTo"] + if (el != null && el.isJsonArray) { + setAttachedTo(JsonUtils.getJsonArray("attachedTo", act)) + } else { + attachedTo.add(JsonUtils.getString("attachedTo", act)) + } + isAttached = attachedTo.isNotEmpty() } - tag.isAttached = (tag.attachedTo?.size ?: 0) > 0 } - mRealm.commitTransaction() val csvRow = arrayOf( JsonUtils.getString("_id", act), @@ -77,7 +81,6 @@ open class RealmTag : RealmObject() { JsonUtils.getString("linkId", act), JsonUtils.getString("attachedTo", act) ) - tagDataList.add(csvRow) } @@ -85,28 +88,23 @@ open class RealmTag : RealmObject() { try { val file = File(filePath) file.parentFile?.mkdirs() - val writer = CSVWriter(FileWriter(file)) - writer.writeNext(arrayOf("_id", "_rev", "name", "db", "docType", "tagId", "linkId", "attachedTo")) - for (row in data) { - writer.writeNext(row) + CSVWriter(FileWriter(file)).use { writer -> + writer.writeNext(arrayOf("_id", "_rev", "name", "db", "docType", "tagId", "linkId", "attachedTo")) + data.forEach { writer.writeNext(it) } } - writer.close() } catch (e: IOException) { e.printStackTrace() } } fun tagWriteCsv() { - writeCsv("${context.getExternalFilesDir(null)}/ole/tags.csv", tagDataList) + writeCsv("${MainApplication.context.getExternalFilesDir(null)}/ole/tags.csv", tagDataList) } - @JvmStatic fun getTagsArray(list: List): JsonArray { - val array = JsonArray() - for (t in list) { - array.add(t._id) + return JsonArray().apply { + list.forEach { add(it._id) } } - return array } } } \ No newline at end of file diff --git a/app/src/main/java/org/ole/planet/myplanet/model/RealmTeamLog.kt b/app/src/main/java/org/ole/planet/myplanet/model/RealmTeamLog.kt index b9c9b13f2d..25d3d40b9c 100644 --- a/app/src/main/java/org/ole/planet/myplanet/model/RealmTeamLog.kt +++ b/app/src/main/java/org/ole/planet/myplanet/model/RealmTeamLog.kt @@ -1,13 +1,12 @@ package org.ole.planet.myplanet.model import android.content.Context -import android.text.TextUtils import com.google.gson.JsonObject import com.opencsv.CSVWriter -import io.realm.Realm -import io.realm.RealmObject -import io.realm.annotations.PrimaryKey -import org.ole.planet.myplanet.MainApplication.Companion.context +import io.realm.kotlin.Realm +import io.realm.kotlin.types.RealmObject +import io.realm.kotlin.types.annotations.PrimaryKey +import org.ole.planet.myplanet.MainApplication import org.ole.planet.myplanet.utilities.JsonUtils import org.ole.planet.myplanet.utilities.NetworkUtils import java.io.File @@ -15,7 +14,7 @@ import java.io.FileWriter import java.io.IOException import java.util.Calendar -open class RealmTeamLog : RealmObject() { +class RealmTeamLog : RealmObject { @PrimaryKey var id: String? = null var _id: String? = null @@ -27,63 +26,68 @@ open class RealmTeamLog : RealmObject() { var createdOn: String? = null var parentCode: String? = null var time: Long? = null - var uploaded = false + var uploaded: Boolean = false + companion object { private val teamLogDataList: MutableList> = mutableListOf() - @JvmStatic fun getVisitCount(realm: Realm, userName: String?, teamId: String?): Long { - return realm.where(RealmTeamLog::class.java).equalTo("type", "teamVisit").equalTo("user", userName).equalTo("teamId", teamId).count() + return realm.query(RealmTeamLog::class, "type == $0 AND user == $1 AND teamId == $2", "teamVisit", userName, teamId).count().find() } - @JvmStatic fun getVisitByTeam(realm: Realm, teamId: String?): Long { val calendar = Calendar.getInstance() calendar.add(Calendar.DAY_OF_YEAR, -30) - return realm.where(RealmTeamLog::class.java).equalTo("type", "teamVisit").equalTo("teamId", teamId).greaterThan("time", calendar.timeInMillis).count() + return realm.query(RealmTeamLog::class, "type == 'teamVisit' AND teamId == $0 AND time > $1", teamId ?: "", calendar.timeInMillis).count().find() } - @JvmStatic fun serializeTeamActivities(log: RealmTeamLog, context: Context): JsonObject { - val ob = JsonObject() - ob.addProperty("user", log.user) - ob.addProperty("type", log.type) - ob.addProperty("createdOn", log.createdOn) - ob.addProperty("parentCode", log.parentCode) - ob.addProperty("teamType", log.teamType) - ob.addProperty("time", log.time) - ob.addProperty("teamId", log.teamId) - ob.addProperty("androidId", NetworkUtils.getUniqueIdentifier()) - ob.addProperty("deviceName", NetworkUtils.getDeviceName()) - ob.addProperty("customDeviceName", NetworkUtils.getCustomDeviceName(context)) - if (!TextUtils.isEmpty(log._rev)) { - ob.addProperty("_rev", log._rev) - ob.addProperty("_id", log._id) + return JsonObject().apply { + addProperty("user", log.user) + addProperty("type", log.type) + addProperty("createdOn", log.createdOn) + addProperty("parentCode", log.parentCode) + addProperty("teamType", log.teamType) + addProperty("time", log.time) + addProperty("teamId", log.teamId) + addProperty("androidId", NetworkUtils.getUniqueIdentifier()) + addProperty("deviceName", NetworkUtils.getDeviceName()) + addProperty("customDeviceName", NetworkUtils.getCustomDeviceName(context)) + if (!log._rev.isNullOrEmpty()) { + addProperty("_rev", log._rev) + addProperty("_id", log._id) + } } - return ob } - @JvmStatic - fun insert(mRealm: Realm, act: JsonObject?) { - if (!mRealm.isInTransaction) { - mRealm.beginTransaction() - } - var tag = mRealm.where(RealmTeamLog::class.java).equalTo("id", JsonUtils.getString("_id", act)).findFirst() - if (tag == null) { - tag = mRealm.createObject(RealmTeamLog::class.java, JsonUtils.getString("_id", act)) - } - if (tag != null) { - tag._rev = JsonUtils.getString("_rev", act) - tag._id = JsonUtils.getString("_id", act) - tag.type = JsonUtils.getString("type", act) - tag.user = JsonUtils.getString("user", act) - tag.createdOn = JsonUtils.getString("createdOn", act) - tag.parentCode = JsonUtils.getString("parentCode", act) - tag.time = JsonUtils.getLong("time", act) - tag.teamId = JsonUtils.getString("teamId", act) - tag.teamType = JsonUtils.getString("teamType", act) + suspend fun insert(realm: Realm, act: JsonObject?) { + if (act == null) return + + realm.write { + val id = JsonUtils.getString("_id", act) + + val existingLog = query(RealmTeamLog::class, "id == $0", id).first().find() + + val tag = existingLog ?: copyToRealm(RealmTeamLog().apply { + this.id = id + }) + + tag.apply { + _rev = JsonUtils.getString("_rev", act) + _id = JsonUtils.getString("_id", act) + type = JsonUtils.getString("type", act) + user = JsonUtils.getString("user", act) + createdOn = JsonUtils.getString("createdOn", act) + parentCode = JsonUtils.getString("parentCode", act) + time = JsonUtils.getLong("time", act) + teamId = JsonUtils.getString("teamId", act) + teamType = JsonUtils.getString("teamType", act) + } + + if (existingLog == null) { + copyToRealm(tag) + } } - mRealm.commitTransaction() val csvRow = arrayOf( JsonUtils.getString("_id", act), @@ -103,20 +107,19 @@ open class RealmTeamLog : RealmObject() { try { val file = File(filePath) file.parentFile?.mkdirs() - val writer = CSVWriter(FileWriter(file)) - writer.writeNext(arrayOf("_id", "_rev", "user", "type", "createdOn", "parentCode", "time", "teamId", "teamType")) - for (row in data) { - writer.writeNext(row) + CSVWriter(FileWriter(file)).use { writer -> + writer.writeNext(arrayOf("_id", "_rev", "user", "type", "createdOn", "parentCode", "time", "teamId", "teamType")) + data.forEach { row -> + writer.writeNext(row) + } } - writer.close() } catch (e: IOException) { e.printStackTrace() } } fun teamLogWriteCsv() { - writeCsv("${context.getExternalFilesDir(null)}/ole/teamLog.csv", teamLogDataList) + writeCsv("${MainApplication.context.getExternalFilesDir(null)}/ole/teamLog.csv", teamLogDataList) } - } } diff --git a/app/src/main/java/org/ole/planet/myplanet/model/RealmTeamTask.kt b/app/src/main/java/org/ole/planet/myplanet/model/RealmTeamTask.kt index 82181db617..4095d1d8ef 100644 --- a/app/src/main/java/org/ole/planet/myplanet/model/RealmTeamTask.kt +++ b/app/src/main/java/org/ole/planet/myplanet/model/RealmTeamTask.kt @@ -1,19 +1,19 @@ package org.ole.planet.myplanet.model -import android.text.TextUtils import com.google.gson.Gson import com.google.gson.JsonObject import com.opencsv.CSVWriter -import io.realm.Realm -import io.realm.RealmObject -import io.realm.annotations.PrimaryKey -import org.ole.planet.myplanet.MainApplication.Companion.context +import io.realm.kotlin.Realm +import io.realm.kotlin.ext.query +import io.realm.kotlin.types.RealmObject +import io.realm.kotlin.types.annotations.PrimaryKey +import org.ole.planet.myplanet.MainApplication import org.ole.planet.myplanet.utilities.JsonUtils import java.io.File import java.io.FileWriter import java.io.IOException -open class RealmTeamTask : RealmObject() { +class RealmTeamTask : RealmObject { @PrimaryKey var id: String? = null var _id: String? = null @@ -23,62 +23,65 @@ open class RealmTeamTask : RealmObject() { var link: String? = null var sync: String? = null var teamId: String? = null - var isUpdated = false + var isUpdated: Boolean = false var assignee: String? = null var deadline: Long = 0 var completedTime: Long = 0 var status: String? = null - var completed = false - var isNotified = false + var completed: Boolean = false + var isNotified: Boolean = false override fun toString(): String { - return title!! + return title ?: "" } companion object { - val taskDataList: MutableList> = mutableListOf() + private val taskDataList: MutableList> = mutableListOf() - @JvmStatic - fun insert(mRealm: Realm, obj: JsonObject?) { - if (!mRealm.isInTransaction) { - mRealm.beginTransaction() - } - var task = mRealm.where(RealmTeamTask::class.java).equalTo("_id", JsonUtils.getString("_id", obj)).findFirst() - if (task == null) { - task = mRealm.createObject(RealmTeamTask::class.java, JsonUtils.getString("_id", obj)) - } - if (task != null) { - task._id = JsonUtils.getString("_id", obj) - task._rev = JsonUtils.getString("_rev", obj) - task.title = JsonUtils.getString("title", obj) - task.status = JsonUtils.getString("status", obj) - task.deadline = JsonUtils.getLong("deadline", obj) - task.completedTime = JsonUtils.getLong("completedTime", obj) - task.description = JsonUtils.getString("description", obj) - task.link = Gson().toJson(JsonUtils.getJsonObject("link", obj)) - task.sync = Gson().toJson(JsonUtils.getJsonObject("sync", obj)) - task.teamId = JsonUtils.getString("teams", JsonUtils.getJsonObject("link", obj)) - val user = JsonUtils.getJsonObject("assignee", obj) - if (user.has("_id")) task.assignee = JsonUtils.getString("_id", user) - task.completed = JsonUtils.getBoolean("completed", obj) + suspend fun insert(realm: Realm, obj: JsonObject?) { + obj?.let { jsonObj -> + val taskId = JsonUtils.getString("_id", jsonObj) + + realm.write { + val existingTask = query("_id == $0", taskId).first().find() + + val task = existingTask ?: RealmTeamTask().apply { _id = taskId } + + copyToRealm(task.apply { + _rev = JsonUtils.getString("_rev", jsonObj) + title = JsonUtils.getString("title", jsonObj) + status = JsonUtils.getString("status", jsonObj) + deadline = JsonUtils.getLong("deadline", jsonObj) + completedTime = JsonUtils.getLong("completedTime", jsonObj) + description = JsonUtils.getString("description", jsonObj) + link = Gson().toJson(JsonUtils.getJsonObject("link", jsonObj)) + sync = Gson().toJson(JsonUtils.getJsonObject("sync", jsonObj)) + teamId = JsonUtils.getString("teams", JsonUtils.getJsonObject("link", jsonObj)) + + val user = JsonUtils.getJsonObject("assignee", jsonObj) + if (user.has("_id")) { + assignee = JsonUtils.getString("_id", user) + } + completed = JsonUtils.getBoolean("completed", jsonObj) + }) + } + + val csvRow = arrayOf( + JsonUtils.getString("_id", jsonObj), + JsonUtils.getString("_rev", jsonObj), + JsonUtils.getString("title", jsonObj), + JsonUtils.getString("status", jsonObj), + JsonUtils.getLong("deadline", jsonObj).toString(), + JsonUtils.getLong("completedTime", jsonObj).toString(), + JsonUtils.getString("description", jsonObj), + JsonUtils.getString("link", jsonObj), + JsonUtils.getString("sync", jsonObj), + JsonUtils.getString("teams", JsonUtils.getJsonObject("link", jsonObj)), + JsonUtils.getString("assignee", JsonUtils.getJsonObject("assignee", jsonObj)), + JsonUtils.getBoolean("completed", jsonObj).toString() + ) + taskDataList.add(csvRow) } - mRealm.commitTransaction() - - val csvRow = arrayOf( - JsonUtils.getString("_id", obj), - JsonUtils.getString("_rev", obj), - JsonUtils.getString("title", obj), - JsonUtils.getString("status", obj), - JsonUtils.getLong("deadline", obj).toString(), - JsonUtils.getLong("completedTime", obj).toString(), - JsonUtils.getString("description", obj), - JsonUtils.getString("link", obj), - JsonUtils.getString("sync", obj), - JsonUtils.getString("teams", JsonUtils.getJsonObject("link", obj)), - JsonUtils.getString("assignee", JsonUtils.getJsonObject("assignee", obj)), - JsonUtils.getBoolean("completed", obj).toString() - ) - taskDataList.add(csvRow) } fun writeCsv(filePath: String, data: List>) { @@ -86,7 +89,10 @@ open class RealmTeamTask : RealmObject() { val file = File(filePath) file.parentFile?.mkdirs() val writer = CSVWriter(FileWriter(file)) - writer.writeNext(arrayOf("_id", "_rev", "title", "status", "deadline", "completedTime", "description", "link", "sync", "teams", "assignee", "completed")) + writer.writeNext(arrayOf( + "_id", "_rev", "title", "status", "deadline", "completedTime", + "description", "link", "sync", "teams", "assignee", "completed" + )) for (row in data) { writer.writeNext(row) } @@ -97,27 +103,32 @@ open class RealmTeamTask : RealmObject() { } fun teamTaskWriteCsv() { - writeCsv("${context.getExternalFilesDir(null)}/ole/teamTask.csv", taskDataList) + writeCsv("${MainApplication.context.getExternalFilesDir(null)}/ole/teamTask.csv", taskDataList) } - @JvmStatic fun serialize(realm: Realm, task: RealmTeamTask): JsonObject { - val `object` = JsonObject() - if (!TextUtils.isEmpty(task._id)) { - `object`.addProperty("_id", task._id) - `object`.addProperty("_rev", task._rev) + return JsonObject().apply { + task._id?.let { + addProperty("_id", it) + addProperty("_rev", task._rev) + } + addProperty("title", task.title) + addProperty("deadline", task.deadline) + addProperty("description", task.description) + addProperty("completed", task.completed) + addProperty("completedTime", task.completedTime) + + val user = realm.query("id == $0", task.assignee).first().find() + + if (user != null) { + add("assignee", user.serialize()) + } else { + addProperty("assignee", "") + } + + add("sync", Gson().fromJson(task.sync, JsonObject::class.java)) + add("link", Gson().fromJson(task.link, JsonObject::class.java)) } - `object`.addProperty("title", task.title) - `object`.addProperty("deadline", task.deadline) - `object`.addProperty("description", task.description) - `object`.addProperty("completed", task.completed) - `object`.addProperty("completedTime", task.completedTime) - val user = realm.where(RealmUserModel::class.java).equalTo("id", task.assignee).findFirst() - if (user != null) `object`.add("assignee", user.serialize()) - else `object`.addProperty("assignee", "") - `object`.add("sync", Gson().fromJson(task.sync, JsonObject::class.java)) - `object`.add("link", Gson().fromJson(task.link, JsonObject::class.java)) - return `object` } } } diff --git a/app/src/main/java/org/ole/planet/myplanet/model/RealmUserChallengeActions.kt b/app/src/main/java/org/ole/planet/myplanet/model/RealmUserChallengeActions.kt index 7cadbbfc00..262b007a75 100644 --- a/app/src/main/java/org/ole/planet/myplanet/model/RealmUserChallengeActions.kt +++ b/app/src/main/java/org/ole/planet/myplanet/model/RealmUserChallengeActions.kt @@ -1,28 +1,28 @@ package org.ole.planet.myplanet.model -import io.realm.Realm -import io.realm.RealmObject -import io.realm.annotations.PrimaryKey -import java.util.UUID +import io.realm.kotlin.Realm +import io.realm.kotlin.types.RealmObject +import io.realm.kotlin.types.RealmUUID +import io.realm.kotlin.types.annotations.PrimaryKey -open class RealmUserChallengeActions : RealmObject() { +class RealmUserChallengeActions : RealmObject { @PrimaryKey - var id: String = UUID.randomUUID().toString() + var id: String = RealmUUID.random().toString() var userId: String? = null var actionType: String? = null var resourceId: String? = null var time: Long = 0 companion object { - fun createAction(realm: Realm, userId: String, resourceId: String?, actionType: String) { - realm.executeTransaction { transactionRealm -> - val action = transactionRealm.createObject( - RealmUserChallengeActions::class.java, UUID.randomUUID().toString() - ) - action.userId = userId - action.actionType = actionType - action.resourceId = resourceId - action.time = System.currentTimeMillis() + suspend fun createAction(realm: Realm, userId: String, resourceId: String?, actionType: String) { + realm.write { + copyToRealm(RealmUserChallengeActions().apply { + this.id = RealmUUID.random().toString() + this.userId = userId + this.actionType = actionType + this.resourceId = resourceId + this.time = System.currentTimeMillis() + }) } } } diff --git a/app/src/main/java/org/ole/planet/myplanet/model/RealmUserModel.kt b/app/src/main/java/org/ole/planet/myplanet/model/RealmUserModel.kt index abba9b236d..637ce9084d 100644 --- a/app/src/main/java/org/ole/planet/myplanet/model/RealmUserModel.kt +++ b/app/src/main/java/org/ole/planet/myplanet/model/RealmUserModel.kt @@ -1,17 +1,16 @@ package org.ole.planet.myplanet.model import android.content.SharedPreferences -import android.text.TextUtils import com.google.gson.JsonArray import com.google.gson.JsonObject -import com.google.gson.JsonParser import com.opencsv.CSVWriter -import io.realm.Realm -import io.realm.RealmList -import io.realm.RealmObject -import io.realm.annotations.PrimaryKey -import org.apache.commons.lang3.StringUtils -import org.ole.planet.myplanet.MainApplication.Companion.context +import io.realm.kotlin.Realm +import io.realm.kotlin.ext.query +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 org.ole.planet.myplanet.MainApplication import org.ole.planet.myplanet.utilities.JsonUtils import org.ole.planet.myplanet.utilities.NetworkUtils import org.ole.planet.myplanet.utilities.Utilities @@ -22,14 +21,14 @@ import java.io.IOException import java.util.Locale import java.util.UUID -open class RealmUserModel : RealmObject() { +class RealmUserModel : RealmObject { @PrimaryKey - var id: String? = null + var id: String = UUID.randomUUID().toString() var _id: String? = null var _rev: String? = null var name: String? = null - var rolesList: RealmList? = null - var userAdmin: Boolean? = null + var rolesList: RealmList = realmListOf() + var userAdmin: Boolean = false var joinDate: Long = 0 var firstName: String? = null var lastName: String? = null @@ -51,207 +50,216 @@ open class RealmUserModel : RealmObject() { var key: String? = null var iv: String? = null var password: String? = null - var isUpdated = false - var isShowTopbar = false - var isArchived = false + var isUpdated: Boolean = false + var isShowTopbar: Boolean = false + var isArchived: Boolean = false fun serialize(): JsonObject { - val `object` = JsonObject() - if (_id?.isNotEmpty() == true) { - `object`.addProperty("_id", _id) - `object`.addProperty("_rev", _rev) - } - `object`.addProperty("name", name) - `object`.add("roles", getRoles()) - if (_id?.isEmpty() == true) { - `object`.addProperty("password", password) - `object`.addProperty("androidId", NetworkUtils.getUniqueIdentifier()) - `object`.addProperty("uniqueAndroidId", VersionUtils.getAndroidId(context)) - `object`.addProperty("customDeviceName", NetworkUtils.getCustomDeviceName(context)) - } else { - `object`.addProperty("derived_key", derived_key) - `object`.addProperty("salt", salt) - `object`.addProperty("password_scheme", password_scheme) - } - `object`.addProperty("isUserAdmin", userAdmin) - `object`.addProperty("joinDate", joinDate) - `object`.addProperty("firstName", firstName) - `object`.addProperty("lastName", lastName) - `object`.addProperty("middleName", middleName) - `object`.addProperty("email", email) - `object`.addProperty("language", language) - `object`.addProperty("level", level) - `object`.addProperty("type", "user") - `object`.addProperty("gender", gender) - `object`.addProperty("phoneNumber", phoneNumber) - `object`.addProperty("birthDate", dob) - try { - `object`.addProperty("iterations", iterations?.toInt()) - } catch (e: Exception) { - `object`.addProperty("iterations", 10) + return JsonObject().apply { + if (!_id.isNullOrEmpty()) { + addProperty("_id", _id) + addProperty("_rev", _rev) + } + addProperty("name", name) + add("roles", getRoles()) + if (_id.isNullOrEmpty()) { + addProperty("password", password) + addProperty("androidId", NetworkUtils.getUniqueIdentifier()) + addProperty("uniqueAndroidId", VersionUtils.getAndroidId(MainApplication.context)) + addProperty("customDeviceName", NetworkUtils.getCustomDeviceName(MainApplication.context)) + } else { + addProperty("derived_key", derived_key) + addProperty("salt", salt) + addProperty("password_scheme", password_scheme) + } + addProperty("isUserAdmin", userAdmin) + addProperty("joinDate", joinDate) + addProperty("firstName", firstName) + addProperty("lastName", lastName) + addProperty("middleName", middleName) + addProperty("email", email) + addProperty("language", language) + addProperty("level", level) + addProperty("type", "user") + addProperty("gender", gender) + addProperty("phoneNumber", phoneNumber) + addProperty("birthDate", dob) + try { + addProperty("iterations", iterations?.toInt()) + } catch (e: Exception) { + e.printStackTrace() + addProperty("iterations", 10) + } + addProperty("parentCode", parentCode) + addProperty("planetCode", planetCode) + addProperty("birthPlace", birthPlace) + addProperty("isArchived", isArchived) } - `object`.addProperty("parentCode", parentCode) - `object`.addProperty("planetCode", planetCode) - `object`.addProperty("birthPlace", birthPlace) - `object`.addProperty("isArchived", isArchived) - return `object` } private fun getRoles(): JsonArray { - val ar = JsonArray() - for (s in rolesList ?: emptyList()) { - ar.add(s) + return JsonArray().apply { + rolesList.forEach { add(it) } } - return ar } - fun setRoles(roles: RealmList?) { - rolesList = roles + fun setRoles(roles: List) { + rolesList.clear() + rolesList.addAll(roles) } - fun getRoleAsString(): String { - return StringUtils.join(rolesList, ",") - } + fun getRoleAsString(): String = rolesList.joinToString(",") - fun getFullName(): String { - return "$firstName $lastName" - } + fun getFullName(): String = "$firstName $lastName" fun addImageUrl(jsonDoc: JsonObject?) { - if (jsonDoc?.has("_attachments") == true) { - val element = JsonParser.parseString(jsonDoc["_attachments"].asJsonObject.toString()) - val obj = element.asJsonObject - val entries = obj.entrySet() - for ((key1) in entries) { - userImage = Utilities.getUserImageUrl(id, key1) - break + jsonDoc?.get("_attachments")?.asJsonObject?.let { attachments -> + attachments.entrySet().firstOrNull()?.let { (key) -> + userImage = Utilities.getUserImageUrl(id, key) } } } - fun isManager(): Boolean { - val roles = getRoles() - val isManager = roles.toString().lowercase(Locale.ROOT).contains("manager") || userAdmin ?: false - return isManager - } + fun isManager(): Boolean = getRoles().toString().lowercase(Locale.ROOT).contains("manager") || userAdmin - fun isLeader(): Boolean { - val roles = getRoles() - return roles.toString().lowercase(Locale.ROOT).contains("leader") - } + fun isLeader(): Boolean = getRoles().toString().lowercase(Locale.ROOT).contains("leader") - fun isGuest(): Boolean { - return _id?.startsWith("guest_") == true - } + fun isGuest(): Boolean = _id?.startsWith("guest_") == true - override fun toString(): String { - return "$name" - } + override fun toString(): String = name ?: "" companion object { private val userDataList: MutableList> = mutableListOf() - @JvmStatic - fun createGuestUser(username: String?, mRealm: Realm, settings: SharedPreferences): RealmUserModel? { - val `object` = JsonObject() - `object`.addProperty("_id", "guest_$username") - `object`.addProperty("name", username) - `object`.addProperty("firstName", username) - val rolesArray = JsonArray() - rolesArray.add("guest") - `object`.add("roles", rolesArray) - if (!mRealm.isInTransaction) mRealm.beginTransaction() - return populateUsersTable(`object`, mRealm, settings) + suspend fun createGuestUser(username: String?, realm: Realm, settings: SharedPreferences): RealmUserModel? { + val jsonObject = JsonObject().apply { + addProperty("_id", "guest_$username") + addProperty("name", username) + addProperty("firstName", username) + add("roles", JsonArray().apply { add("guest") }) + } + + return populateUsersTable(jsonObject, realm, settings) } - @JvmStatic - fun populateUsersTable(jsonDoc: JsonObject?, mRealm: Realm?, settings: SharedPreferences): RealmUserModel? { - try { - var id = JsonUtils.getString("_id", jsonDoc) - if (id.isEmpty()) id = UUID.randomUUID().toString() - var user = mRealm?.where(RealmUserModel::class.java)?.equalTo("_id", id)?.findFirst() - if (user == null) { - user = mRealm?.createObject(RealmUserModel::class.java, id) + suspend fun populateUsersTable(jsonDoc: JsonObject?, realm: Realm, settings: SharedPreferences): RealmUserModel? { + return try { + val id = JsonUtils.getString("_id", jsonDoc).ifEmpty { UUID.randomUUID().toString() } + + realm.write { + val user = query("_id == $0", id).first().find() + ?: RealmUserModel().apply { this._id = id } + + copyToRealm(user.apply { + insertIntoUsers(jsonDoc, this, settings) + }) } - insertIntoUsers(jsonDoc, user, settings) - return user } catch (err: Exception) { err.printStackTrace() + null } - return null } - @JvmStatic fun isUserExists(realm: Realm, name: String?): Boolean { - return realm.where(RealmUserModel::class.java).equalTo("name", name).count() > 0 + return realm.query("name == $0", name ?: "").count().find() > 0 } - private fun insertIntoUsers(jsonDoc: JsonObject?, user: RealmUserModel?, settings: SharedPreferences) { - if (user != null) { - user._rev = JsonUtils.getString("_rev", jsonDoc) - user._id = JsonUtils.getString("_id", jsonDoc) - user.name = JsonUtils.getString("name", jsonDoc) - val array = JsonUtils.getJsonArray("roles", jsonDoc) - val roles = RealmList() - for (i in 0 until array.size()) { - roles.add(JsonUtils.getString(array, i)) + private fun insertIntoUsers(jsonDoc: JsonObject?, user: RealmUserModel, settings: SharedPreferences) { + user.apply { + _rev = JsonUtils.getString("_rev", jsonDoc) + name = JsonUtils.getString("name", jsonDoc) + + val rolesArray = JsonUtils.getJsonArray("roles", jsonDoc) + val roles = mutableListOf() + for (i in 0 until rolesArray.size()) { + JsonUtils.getString(rolesArray, i).let { roles.add(it) } } - user.setRoles(roles) - user.userAdmin = JsonUtils.getBoolean("isUserAdmin", jsonDoc) - user.joinDate = JsonUtils.getLong("joinDate", jsonDoc) - user.firstName = JsonUtils.getString("firstName", jsonDoc) - user.lastName = JsonUtils.getString("lastName", jsonDoc) - user.middleName = JsonUtils.getString("middleName", jsonDoc) - user.planetCode = JsonUtils.getString("planetCode", jsonDoc) - user.parentCode = JsonUtils.getString("parentCode", jsonDoc) - user.email = JsonUtils.getString("email", jsonDoc) - if (user._id?.isEmpty() == true) { - user.password = JsonUtils.getString("password", jsonDoc) + setRoles(roles) + + userAdmin = JsonUtils.getBoolean("isUserAdmin", jsonDoc) + joinDate = JsonUtils.getLong("joinDate", jsonDoc) + firstName = JsonUtils.getString("firstName", jsonDoc) + lastName = JsonUtils.getString("lastName", jsonDoc) + middleName = JsonUtils.getString("middleName", jsonDoc) + planetCode = JsonUtils.getString("planetCode", jsonDoc) + parentCode = JsonUtils.getString("parentCode", jsonDoc) + email = JsonUtils.getString("email", jsonDoc) + if (_id.isNullOrEmpty()) { + password = JsonUtils.getString("password", jsonDoc) } - user.phoneNumber = JsonUtils.getString("phoneNumber", jsonDoc) - user.password_scheme = JsonUtils.getString("password_scheme", jsonDoc) - user.iterations = JsonUtils.getString("iterations", jsonDoc) - user.derived_key = JsonUtils.getString("derived_key", jsonDoc) - user.salt = JsonUtils.getString("salt", jsonDoc) - user.dob = JsonUtils.getString("birthDate", jsonDoc) - user.birthPlace = JsonUtils.getString("birthPlace", jsonDoc) - user.gender = JsonUtils.getString("gender", jsonDoc) - user.language = JsonUtils.getString("language", jsonDoc) - user.level = JsonUtils.getString("level", jsonDoc) - user.isShowTopbar = true - user.addImageUrl(jsonDoc) - user.isArchived = JsonUtils.getBoolean("isArchived", jsonDoc) - if (!TextUtils.isEmpty(JsonUtils.getString("planetCode", jsonDoc))) { - settings.edit().putString("planetCode", JsonUtils.getString("planetCode", jsonDoc)).apply() + phoneNumber = JsonUtils.getString("phoneNumber", jsonDoc) + password_scheme = JsonUtils.getString("password_scheme", jsonDoc) + iterations = JsonUtils.getString("iterations", jsonDoc) + derived_key = JsonUtils.getString("derived_key", jsonDoc) + salt = JsonUtils.getString("salt", jsonDoc) + dob = JsonUtils.getString("birthDate", jsonDoc) + birthPlace = JsonUtils.getString("birthPlace", jsonDoc) + gender = JsonUtils.getString("gender", jsonDoc) + language = JsonUtils.getString("language", jsonDoc) + level = JsonUtils.getString("level", jsonDoc) + isShowTopbar = true + addImageUrl(jsonDoc) + isArchived = JsonUtils.getBoolean("isArchived", jsonDoc) + + JsonUtils.getString("planetCode", jsonDoc).let { + settings.edit().putString("planetCode", it).apply() } - if (!TextUtils.isEmpty(JsonUtils.getString("parentCode", jsonDoc))) { - settings.edit().putString("parentCode", JsonUtils.getString("parentCode", jsonDoc)).apply() + JsonUtils.getString("parentCode", jsonDoc).let { + settings.edit().putString("parentCode", it).apply() } + } - val csvRow = arrayOf( - user.userAdmin.toString(), - user._id.toString(), - user.name.toString(), - user.firstName.toString(), - user.lastName.toString(), - user.email.toString(), - user.phoneNumber.toString(), - user.planetCode.toString(), - user.parentCode.toString(), - user.password_scheme.toString(), - user.iterations.toString(), - user.derived_key.toString(), - user.salt.toString(), - user.level.toString(), - user.language.toString(), - user.gender.toString(), - user.dob.toString(), - user.birthPlace.toString(), - user.userImage.toString(), - user.isArchived.toString() - ) + val csvRow = arrayOf( + user.userAdmin.toString(), + user._id.toString(), + user.name.toString(), + user.firstName.toString(), + user.lastName.toString(), + user.email.toString(), + user.phoneNumber.toString(), + user.planetCode.toString(), + user.parentCode.toString(), + user.password_scheme.toString(), + user.iterations.toString(), + user.derived_key.toString(), + user.salt.toString(), + user.level.toString(), + user.language.toString(), + user.gender.toString(), + user.dob.toString(), + user.birthPlace.toString(), + user.userImage.toString(), + user.isArchived.toString() + ) + userDataList.add(csvRow) + } - userDataList.add(csvRow) + suspend fun updateUserDetails(realm: Realm, userId: String?, firstName: String?, lastName: String?, + middleName: String?, email: String?, phoneNumber: String?, level: String?, language: String?, + gender: String?, dob: String?, onSuccess: () -> Unit + ) { + try { + realm.write { + query("id == $0", userId ?: "").first().find()?.apply { + this.firstName = firstName + this.lastName = lastName + this.middleName = middleName + this.email = email + this.phoneNumber = phoneNumber + this.level = level + this.language = language + this.gender = gender + this.dob = dob + this.isUpdated = true + }?.also { + copyToRealm(it) + onSuccess() + Utilities.toast(MainApplication.context, "User details updated successfully") + } + } + } catch (e: Exception) { + e.printStackTrace() + Utilities.toast(MainApplication.context, "User details update failed") } } @@ -259,45 +267,21 @@ open class RealmUserModel : RealmObject() { try { val file = File(filePath) file.parentFile?.mkdirs() - val writer = CSVWriter(FileWriter(file)) - writer.writeNext(arrayOf("userAdmin", "_id", "name", "firstName", "lastName", "email", "phoneNumber", "planetCode", "parentCode", "password_scheme", "iterations", "derived_key", "salt", "level")) - for (row in data) { - writer.writeNext(row) + CSVWriter(FileWriter(file)).use { writer -> + writer.writeNext(arrayOf( + "userAdmin", "_id", "name", "firstName", "lastName", + "email", "phoneNumber", "planetCode", "parentCode", + "password_scheme", "iterations", "derived_key", "salt", "level" + )) + data.forEach { writer.writeNext(it) } } - writer.close() } catch (e: IOException) { e.printStackTrace() } } fun userWriteCsv() { - writeCsv("${context.getExternalFilesDir(null)}/ole/userData.csv", userDataList) - } - - - fun updateUserDetails(realm: Realm, userId: String?, firstName: String?, lastName: String?, - middleName: String?, email: String?, phoneNumber: String?, level: String?, language: String?, - gender: String?, dob: String?, onSuccess: () -> Unit) { - realm.executeTransactionAsync({ mRealm -> - val user = mRealm.where(RealmUserModel::class.java).equalTo("id", userId).findFirst() - if (user != null) { - user.firstName = firstName - user.lastName = lastName - user.middleName = middleName - user.email = email - user.phoneNumber = phoneNumber - user.level = level - user.language = language - user.gender = gender - user.dob = dob - user.isUpdated = true - } - }, { - onSuccess.invoke() - Utilities.toast(context, "User details updated successfully") - }) { - Utilities.toast(context, "User details update failed") - } + writeCsv("${MainApplication.context.getExternalFilesDir(null)}/ole/userData.csv", userDataList) } } } From 4accf1a12621288c8ad6348ea59252bd8e756d2c Mon Sep 17 00:00:00 2001 From: Gideon Okuro Date: Fri, 22 Nov 2024 17:52:59 +0300 Subject: [PATCH 04/38] Update DatabaseService.kt --- .../myplanet/datamanager/DatabaseService.kt | 25 ++----------------- 1 file changed, 2 insertions(+), 23 deletions(-) diff --git a/app/src/main/java/org/ole/planet/myplanet/datamanager/DatabaseService.kt b/app/src/main/java/org/ole/planet/myplanet/datamanager/DatabaseService.kt index 16530a9653..d62ea7e0c4 100644 --- a/app/src/main/java/org/ole/planet/myplanet/datamanager/DatabaseService.kt +++ b/app/src/main/java/org/ole/planet/myplanet/datamanager/DatabaseService.kt @@ -10,8 +10,7 @@ class DatabaseService() { private val config: RealmConfiguration init { - RealmLog.level = LogLevel.DEBUG // Set log level - // Define the Realm configuration + RealmLog.level = LogLevel.DEBUG config = RealmConfiguration.create( schema = setOf( RealmAchievement::class, RealmAnswer::class, RealmApkLog::class, @@ -29,28 +28,8 @@ class DatabaseService() { schemaVersion = 4 ) } - - // Lazily open a Realm instance with the configuration + val realmInstance: Realm by lazy { Realm.open(config) } } - -//class DatabaseService(context: Context) { -// init { -// Realm.init(context) -// RealmLog.setLevel(LogLevel.DEBUG) -// val config = RealmConfiguration.Builder() -// .name(Realm.DEFAULT_REALM_NAME) -// .deleteRealmIfMigrationNeeded() -// .schemaVersion(4) -// .allowWritesOnUiThread(true) -// .build() -// Realm.setDefaultConfiguration(config) -// } -// -// val realmInstance: Realm -// get() { -// return Realm.getDefaultInstance() -// } -//} \ No newline at end of file From bd69e86d10c48d883323ea8545d1f84c822cc1c8 Mon Sep 17 00:00:00 2001 From: Gideon Okuro Date: Mon, 25 Nov 2024 14:30:56 +0300 Subject: [PATCH 05/38] update file class name --- .../main/java/org/ole/planet/myplanet/model/RealmDictionary.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/org/ole/planet/myplanet/model/RealmDictionary.kt b/app/src/main/java/org/ole/planet/myplanet/model/RealmDictionary.kt index de5fc188ba..066bd365d6 100644 --- a/app/src/main/java/org/ole/planet/myplanet/model/RealmDictionary.kt +++ b/app/src/main/java/org/ole/planet/myplanet/model/RealmDictionary.kt @@ -3,7 +3,7 @@ package org.ole.planet.myplanet.model import io.realm.kotlin.types.RealmObject import io.realm.kotlin.types.annotations.PrimaryKey -class RealmCourseStep : RealmObject { +class RealmDictionary : RealmObject { @PrimaryKey var id: String? = null var word: String? = null From 94135c340db0e0a8b15f5bedbd8aa5af3c5abe5f Mon Sep 17 00:00:00 2001 From: Gideon Okuro Date: Tue, 26 Nov 2024 15:07:38 +0300 Subject: [PATCH 06/38] migrate more file to kotlin realm sdk --- .../planet/myplanet/model/ChatViewModel.kt | 2 +- .../ole/planet/myplanet/model/Conversation.kt | 6 +- .../planet/myplanet/model/RealmChatHistory.kt | 155 ++++++++++-------- .../ole/planet/myplanet/model/RealmMeetup.kt | 139 +++++++--------- .../ole/planet/myplanet/model/RealmMessage.kt | 20 +-- .../planet/myplanet/model/RealmMyPersonal.kt | 21 ++- .../ole/planet/myplanet/model/RealmNewsLog.kt | 15 +- .../myplanet/model/RealmOfflineActivity.kt | 128 ++++++++------- .../planet/myplanet/model/RealmRemovedLog.kt | 67 ++++---- .../myplanet/model/RealmResourceActivity.kt | 48 +++--- 10 files changed, 299 insertions(+), 302 deletions(-) diff --git a/app/src/main/java/org/ole/planet/myplanet/model/ChatViewModel.kt b/app/src/main/java/org/ole/planet/myplanet/model/ChatViewModel.kt index 60f4823745..42a11f4094 100644 --- a/app/src/main/java/org/ole/planet/myplanet/model/ChatViewModel.kt +++ b/app/src/main/java/org/ole/planet/myplanet/model/ChatViewModel.kt @@ -3,7 +3,7 @@ package org.ole.planet.myplanet.model import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel -import io.realm.RealmList +import io.realm.kotlin.types.RealmList class ChatViewModel : ViewModel() { private val selectedChatHistoryLiveData = MutableLiveData>() diff --git a/app/src/main/java/org/ole/planet/myplanet/model/Conversation.kt b/app/src/main/java/org/ole/planet/myplanet/model/Conversation.kt index f9ba0fe17d..efb593e992 100644 --- a/app/src/main/java/org/ole/planet/myplanet/model/Conversation.kt +++ b/app/src/main/java/org/ole/planet/myplanet/model/Conversation.kt @@ -1,8 +1,8 @@ package org.ole.planet.myplanet.model -import io.realm.RealmObject +import io.realm.kotlin.types.RealmObject -open class Conversation : RealmObject() { +class Conversation : RealmObject { var query: String? = null var response: String? = null -} +} \ No newline at end of file diff --git a/app/src/main/java/org/ole/planet/myplanet/model/RealmChatHistory.kt b/app/src/main/java/org/ole/planet/myplanet/model/RealmChatHistory.kt index 91834c4abb..823cb2519b 100644 --- a/app/src/main/java/org/ole/planet/myplanet/model/RealmChatHistory.kt +++ b/app/src/main/java/org/ole/planet/myplanet/model/RealmChatHistory.kt @@ -1,21 +1,22 @@ package org.ole.planet.myplanet.model import com.google.gson.Gson -import com.google.gson.JsonArray import com.google.gson.JsonObject import com.opencsv.CSVWriter -import io.realm.Realm -import io.realm.RealmList -import io.realm.RealmObject -import io.realm.annotations.PrimaryKey -import org.ole.planet.myplanet.MainApplication.Companion.context +import io.realm.kotlin.Realm +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 org.ole.planet.myplanet.MainApplication import org.ole.planet.myplanet.utilities.JsonUtils -import java.util.Date import java.io.File import java.io.FileWriter import java.io.IOException +import java.util.Date -open class RealmChatHistory : RealmObject() { + +class RealmChatHistory : RealmObject { @PrimaryKey var id: String? = null var _id: String? = null @@ -27,71 +28,87 @@ open class RealmChatHistory : RealmObject() { var updatedDate: String? = null var lastUsed: Long = 0 var conversations: RealmList? = null + + constructor() + companion object { private val chatDataList: MutableList> = mutableListOf() - @JvmStatic - fun insert(mRealm: Realm, act: JsonObject?) { - if (!mRealm.isInTransaction) { - mRealm.beginTransaction() + suspend fun insert(realm: Realm, act: JsonObject?) { + realm.write { + val chatHistoryId = JsonUtils.getString("_id", act) + + query(RealmChatHistory::class) + .query("_id == $0", chatHistoryId) + .first() + .find() + ?.let { findLatest(it)?.let { obj -> delete(obj) } } + + val chatHistory = RealmChatHistory().apply { + id = chatHistoryId + _rev = JsonUtils.getString("_rev", act) + _id = JsonUtils.getString("_id", act) + title = JsonUtils.getString("title", act) + createdDate = JsonUtils.getString("createdDate", act) + updatedDate = JsonUtils.getString("updatedDate", act) + user = JsonUtils.getString("user", act) + aiProvider = JsonUtils.getString("aiProvider", act) + conversations = parseConversations(act) + lastUsed = Date().time + } + + this.copyToRealm(chatHistory) + + val csvRow = arrayOf( + JsonUtils.getString("_id", act), + JsonUtils.getString("_rev", act), + JsonUtils.getString("title", act), + JsonUtils.getString("createdDate", act), + JsonUtils.getString("updatedDate", act), + JsonUtils.getString("user", act), + JsonUtils.getString("aiProvider", act), + JsonUtils.getJsonArray("conversations", act).toString() + ) + chatDataList.add(csvRow) } - val chatHistoryId = JsonUtils.getString("_id", act) - val existingChatHistory = mRealm.where(RealmChatHistory::class.java).equalTo("_id", chatHistoryId).findFirst() - existingChatHistory?.deleteFromRealm() - val chatHistory = mRealm.createObject(RealmChatHistory::class.java, chatHistoryId) - chatHistory._rev = JsonUtils.getString("_rev", act) - chatHistory._id = JsonUtils.getString("_id", act) - chatHistory.title = JsonUtils.getString("title", act) - chatHistory.createdDate = JsonUtils.getString("createdDate", act) - chatHistory.updatedDate = JsonUtils.getString("updatedDate", act) - chatHistory.user = JsonUtils.getString("user", act) - chatHistory.aiProvider = JsonUtils.getString("aiProvider", act) - chatHistory.conversations = parseConversations(mRealm, JsonUtils.getJsonArray("conversations", act)) - chatHistory.lastUsed = Date().time - mRealm.commitTransaction() - - val csvRow = arrayOf( - JsonUtils.getString("_id", act), - JsonUtils.getString("_rev", act), - JsonUtils.getString("title", act), - JsonUtils.getString("createdDate", act), - JsonUtils.getString("updatedDate", act), - JsonUtils.getString("user", act), - JsonUtils.getString("aiProvider", act), - JsonUtils.getJsonArray("conversations", act).toString() - ) - chatDataList.add(csvRow) } - private fun parseConversations(realm: Realm, jsonArray: JsonArray): RealmList { - val conversations = RealmList() - for (element in jsonArray) { - val conversation = Gson().fromJson(element, Conversation::class.java) - val realmConversation = realm.copyToRealm(conversation) - conversations.add(realmConversation) + private fun parseConversations(act: JsonObject?): RealmList? { + val jsonArray = JsonUtils.getJsonArray("conversations", act) + return if (jsonArray.isEmpty) null else realmListOf().apply { + jsonArray.forEach { element -> + add(Gson().fromJson(element, Conversation::class.java)) + } } - return conversations } - fun addConversationToChatHistory(mRealm: Realm, chatHistoryId: String?, query: String?, response: String?) { - val chatHistory = mRealm.where(RealmChatHistory::class.java).equalTo("_id", chatHistoryId).findFirst() - if (chatHistory != null) { - if (!mRealm.isInTransaction) { - mRealm.beginTransaction() - } - try { - val conversation = Conversation() - conversation.query = query - conversation.response = response - if (chatHistory.conversations == null) { - chatHistory.conversations = RealmList() + suspend fun addConversationToChatHistory(realm: Realm, chatHistoryId: String?, query: String?, response: String?) { + realm.write { + val chatHistory = query(RealmChatHistory::class) + .query("_id == $0", chatHistoryId) + .first() + .find() + + if (chatHistory != null) { + try { + val conversation = Conversation().apply { + this.query = query + this.response = response + } + + if (chatHistory.conversations == null) { + chatHistory.conversations = realmListOf() + } + chatHistory.conversations?.add(conversation) + chatHistory.lastUsed = Date().time + + findLatest(chatHistory)?.let { latest -> + latest.conversations = chatHistory.conversations + latest.lastUsed = chatHistory.lastUsed + } + } catch (e: Exception) { + e.printStackTrace() } - chatHistory.conversations?.add(conversation) - chatHistory.lastUsed = Date().time - mRealm.copyToRealmOrUpdate(chatHistory) - } catch (e: Exception) { - mRealm.cancelTransaction() - e.printStackTrace() } } } @@ -100,19 +117,19 @@ open class RealmChatHistory : RealmObject() { try { val file = File(filePath) file.parentFile?.mkdirs() - val writer = CSVWriter(FileWriter(file)) - writer.writeNext(arrayOf("chatHistoryId", "chatHistory_rev", "title", "createdDate", "updatedDate", "user", "aiProvider", "conversations")) - for (row in data) { - writer.writeNext(row) + CSVWriter(FileWriter(file)).use { writer -> + writer.writeNext(arrayOf("chatHistoryId", "chatHistory_rev", "title", "createdDate", "updatedDate", "user", "aiProvider", "conversations")) + for (row in data) { + writer.writeNext(row) + } } - writer.close() } catch (e: IOException) { e.printStackTrace() } } fun chatWriteCsv() { - writeCsv("${context.getExternalFilesDir(null)}/ole/chatHistory.csv", chatDataList) + writeCsv("${MainApplication.context.getExternalFilesDir(null)}/ole/chatHistory.csv", chatDataList) } } } diff --git a/app/src/main/java/org/ole/planet/myplanet/model/RealmMeetup.kt b/app/src/main/java/org/ole/planet/myplanet/model/RealmMeetup.kt index 2498ba9919..5f9df0a3d5 100644 --- a/app/src/main/java/org/ole/planet/myplanet/model/RealmMeetup.kt +++ b/app/src/main/java/org/ole/planet/myplanet/model/RealmMeetup.kt @@ -1,20 +1,20 @@ package org.ole.planet.myplanet.model -import android.text.TextUtils import com.google.gson.* import com.opencsv.CSVWriter -import io.realm.* -import io.realm.annotations.PrimaryKey +import io.realm.kotlin.Realm +import io.realm.kotlin.types.RealmObject +import io.realm.kotlin.types.annotations.PrimaryKey import org.json.JSONArray -import org.ole.planet.myplanet.MainApplication.Companion.context +import org.ole.planet.myplanet.MainApplication import org.ole.planet.myplanet.utilities.* import java.io.File import java.io.FileWriter import java.io.IOException -open class RealmMeetup : RealmObject() { +class RealmMeetup : RealmObject { @PrimaryKey - var id: String? = null + var id: String = "" var userId: String? = null var meetupId: String? = null var meetupIdRev: String? = null @@ -35,60 +35,55 @@ open class RealmMeetup : RealmObject() { companion object { private val meetupDataList: MutableList> = mutableListOf() - @JvmStatic - fun insert(mRealm: Realm, meetupDoc: JsonObject) { - insert("", meetupDoc, mRealm) - } + fun insert(realm: Realm, meetupDoc: JsonObject, userId: String? = null) { + realm.writeBlocking { + val myMeetupsDB = query(RealmMeetup::class, "id == $0", JsonUtils.getString("_id", meetupDoc)) + .first() + .find() ?: copyToRealm(RealmMeetup().apply { + id = JsonUtils.getString("_id", meetupDoc) + }) - fun insert(userId: String?, meetupDoc: JsonObject, mRealm: Realm) { - if (!mRealm.isInTransaction) { - mRealm.beginTransaction() - } - var myMeetupsDB = mRealm.where(RealmMeetup::class.java) - .equalTo("id", JsonUtils.getString("_id", meetupDoc)).findFirst() - if (myMeetupsDB == null) { - myMeetupsDB = mRealm.createObject(RealmMeetup::class.java, JsonUtils.getString("_id", meetupDoc)) - } - myMeetupsDB?.meetupId = JsonUtils.getString("_id", meetupDoc) - myMeetupsDB?.userId = userId - myMeetupsDB?.meetupIdRev = JsonUtils.getString("_rev", meetupDoc) - myMeetupsDB?.title = JsonUtils.getString("title", meetupDoc) - myMeetupsDB?.description = JsonUtils.getString("description", meetupDoc) - myMeetupsDB?.startDate = JsonUtils.getLong("startDate", meetupDoc) - myMeetupsDB?.endDate = JsonUtils.getLong("endDate", meetupDoc) - myMeetupsDB?.recurring = JsonUtils.getString("recurring", meetupDoc) - myMeetupsDB?.startTime = JsonUtils.getString("startTime", meetupDoc) - myMeetupsDB?.endTime = JsonUtils.getString("endTime", meetupDoc) - myMeetupsDB?.category = JsonUtils.getString("category", meetupDoc) - myMeetupsDB?.meetupLocation = JsonUtils.getString("meetupLocation", meetupDoc) - myMeetupsDB?.creator = JsonUtils.getString("createdBy", meetupDoc) - myMeetupsDB?.day = JsonUtils.getJsonArray("day", meetupDoc).toString() - myMeetupsDB?.links = JsonUtils.getJsonObject("link", meetupDoc).toString() - myMeetupsDB?.teamId = JsonUtils.getString("teams", JsonUtils.getJsonObject("link", meetupDoc)) - mRealm.commitTransaction() + myMeetupsDB.apply { + this.userId = userId + meetupId = JsonUtils.getString("_id", meetupDoc) + meetupIdRev = JsonUtils.getString("_rev", meetupDoc) + title = JsonUtils.getString("title", meetupDoc) + description = JsonUtils.getString("description", meetupDoc) + startDate = JsonUtils.getLong("startDate", meetupDoc) + endDate = JsonUtils.getLong("endDate", meetupDoc) + recurring = JsonUtils.getString("recurring", meetupDoc) + startTime = JsonUtils.getString("startTime", meetupDoc) + endTime = JsonUtils.getString("endTime", meetupDoc) + category = JsonUtils.getString("category", meetupDoc) + meetupLocation = JsonUtils.getString("meetupLocation", meetupDoc) + creator = JsonUtils.getString("createdBy", meetupDoc) + day = JsonUtils.getJsonArray("day", meetupDoc).toString() + links = JsonUtils.getJsonObject("link", meetupDoc).toString() + teamId = JsonUtils.getString("teams", JsonUtils.getJsonObject("link", meetupDoc)) + } - val csvRow = arrayOf( - JsonUtils.getString("_id", meetupDoc), - userId ?: "", - JsonUtils.getString("_rev", meetupDoc), - JsonUtils.getString("title", meetupDoc), - JsonUtils.getString("description", meetupDoc), - JsonUtils.getLong("startDate", meetupDoc).toString(), - JsonUtils.getLong("endDate", meetupDoc).toString(), - JsonUtils.getString("recurring", meetupDoc), - JsonUtils.getString("startTime", meetupDoc), - JsonUtils.getString("endTime", meetupDoc), - JsonUtils.getString("category", meetupDoc), - JsonUtils.getString("meetupLocation", meetupDoc), - JsonUtils.getString("createdBy", meetupDoc), - JsonUtils.getJsonArray("day", meetupDoc).toString(), - JsonUtils.getJsonObject("link", meetupDoc).toString(), - JsonUtils.getString("teams", JsonUtils.getJsonObject("link", meetupDoc)) - ) - meetupDataList.add(csvRow) + val csvRow = arrayOf( + JsonUtils.getString("_id", meetupDoc), + userId ?: "", + JsonUtils.getString("_rev", meetupDoc), + JsonUtils.getString("title", meetupDoc), + JsonUtils.getString("description", meetupDoc), + JsonUtils.getLong("startDate", meetupDoc).toString(), + JsonUtils.getLong("endDate", meetupDoc).toString(), + JsonUtils.getString("recurring", meetupDoc), + JsonUtils.getString("startTime", meetupDoc), + JsonUtils.getString("endTime", meetupDoc), + JsonUtils.getString("category", meetupDoc), + JsonUtils.getString("meetupLocation", meetupDoc), + JsonUtils.getString("createdBy", meetupDoc), + JsonUtils.getJsonArray("day", meetupDoc).toString(), + JsonUtils.getJsonObject("link", meetupDoc).toString(), + JsonUtils.getString("teams", JsonUtils.getJsonObject("link", meetupDoc)) + ) + meetupDataList.add(csvRow) + } } - @JvmStatic fun writeCsv(filePath: String, data: List>) { try { val file = File(filePath) @@ -104,19 +99,15 @@ open class RealmMeetup : RealmObject() { } } - - @JvmStatic - fun getMyMeetUpIds(realm: Realm?, userId: String?): JsonArray { - val meetups = realm?.where(RealmMeetup::class.java)?.isNotEmpty("userId") - ?.equalTo("userId", userId, Case.INSENSITIVE)?.findAll() + fun getMyMeetUpIds(realm: Realm, userId: String): JsonArray { + val meetups = realm.query(RealmMeetup::class, "userId == $0", userId).find() val ids = JsonArray() - for (lib in meetups ?: emptyList()) { - ids.add(lib.meetupId) + for (lib in meetups) { + lib.meetupId?.let { ids.add(it) } } return ids } - @JvmStatic fun getHashMap(meetups: RealmMeetup): HashMap { val map = HashMap() map["Meetup Title"] = checkNull(meetups.title) @@ -128,13 +119,13 @@ open class RealmMeetup : RealmObject() { } catch (e: Exception) { e.printStackTrace() } - map["Meetup Time"] = checkNull(meetups.startTime) + " - " + checkNull(meetups.endTime) + map["Meetup Time"] = "${checkNull(meetups.startTime)} - ${checkNull(meetups.endTime)}" map["Recurring"] = checkNull(meetups.recurring) var recurringDays = "" try { val ar = JSONArray(meetups.day) for (i in 0 until ar.length()) { - recurringDays += ar[i].toString() + ", " + recurringDays += "${ar[i]}, " } } catch (e: Exception) { e.printStackTrace() @@ -145,23 +136,17 @@ open class RealmMeetup : RealmObject() { return map } - @JvmStatic - fun getJoinedUserIds(mRealm: Realm): Array { - val list: List = mRealm.where(RealmMeetup::class.java).isNotEmpty("userId").findAll() - val myIds = arrayOfNulls(list.size) - for (i in list.indices) { - myIds[i] = list[i].userId - } - return myIds + fun getJoinedUserIds(realm: Realm): Array { + val list = realm.query(RealmMeetup::class, "userId != null").find() + return list.mapNotNull { it.userId }.toTypedArray() } private fun checkNull(s: String?): String { - return if (TextUtils.isEmpty(s)) "" else s!! + return s ?: "" } - @JvmStatic fun meetupWriteCsv() { - writeCsv("${context.getExternalFilesDir(null)}/ole/meetups.csv", meetupDataList) + writeCsv("${MainApplication.context.getExternalFilesDir(null)}/ole/meetups.csv", meetupDataList) } } } diff --git a/app/src/main/java/org/ole/planet/myplanet/model/RealmMessage.kt b/app/src/main/java/org/ole/planet/myplanet/model/RealmMessage.kt index a831141e56..bea2fc95e3 100644 --- a/app/src/main/java/org/ole/planet/myplanet/model/RealmMessage.kt +++ b/app/src/main/java/org/ole/planet/myplanet/model/RealmMessage.kt @@ -1,10 +1,11 @@ package org.ole.planet.myplanet.model -import com.google.gson.JsonArray -import com.google.gson.JsonElement -import com.google.gson.JsonObject import io.realm.kotlin.types.RealmObject import io.realm.kotlin.types.annotations.PrimaryKey +import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.buildJsonArray +import kotlinx.serialization.json.buildJsonObject +import kotlinx.serialization.json.put class RealmMessage : RealmObject { @PrimaryKey @@ -15,14 +16,13 @@ class RealmMessage : RealmObject { companion object { fun serialize(messages: List): JsonElement { - return JsonArray().apply { + return buildJsonArray { messages.forEach { ms -> - val `object` = JsonObject().apply { - addProperty("user", ms.user) - addProperty("time", ms.time) - addProperty("message", ms.message) - } - add(`object`) + add(buildJsonObject { + put("user", ms.user) + put("time", ms.time) + put("message", ms.message) + }) } } } diff --git a/app/src/main/java/org/ole/planet/myplanet/model/RealmMyPersonal.kt b/app/src/main/java/org/ole/planet/myplanet/model/RealmMyPersonal.kt index 184f33bc7b..41cc433b9f 100644 --- a/app/src/main/java/org/ole/planet/myplanet/model/RealmMyPersonal.kt +++ b/app/src/main/java/org/ole/planet/myplanet/model/RealmMyPersonal.kt @@ -1,19 +1,19 @@ package org.ole.planet.myplanet.model +import io.realm.kotlin.types.RealmObject +import io.realm.kotlin.types.annotations.PrimaryKey import android.content.Context import com.google.gson.JsonObject -import io.realm.RealmObject -import io.realm.annotations.PrimaryKey import org.ole.planet.myplanet.utilities.FileUtils import org.ole.planet.myplanet.utilities.NetworkUtils import java.util.Date -open class RealmMyPersonal : RealmObject() { +class RealmMyPersonal : RealmObject { @PrimaryKey var id: String? = null var _id: String? = null var _rev: String? = null - var isUploaded = false + var isUploaded: Boolean = false var title: String? = null var description: String? = null var date: Long = 0 @@ -21,8 +21,9 @@ open class RealmMyPersonal : RealmObject() { var userName: String? = null var path: String? = null + constructor() + companion object { - @JvmStatic fun serialize(personal: RealmMyPersonal, context: Context): JsonObject { val `object` = JsonObject() `object`.addProperty("title", personal.title) @@ -34,13 +35,15 @@ open class RealmMyPersonal : RealmObject() { `object`.addProperty("description", personal.description) `object`.addProperty("resourceType", "Activities") `object`.addProperty("private", true) - val object1 = JsonObject() + + val privateForObject = JsonObject() `object`.addProperty("androidId", NetworkUtils.getUniqueIdentifier()) `object`.addProperty("deviceName", NetworkUtils.getDeviceName()) `object`.addProperty("customDeviceName", NetworkUtils.getCustomDeviceName(context)) - object1.addProperty("users", personal.userId) - `object`.add("privateFor", object1) + privateForObject.addProperty("users", personal.userId) + `object`.add("privateFor", privateForObject) + return `object` } } -} +} \ No newline at end of file diff --git a/app/src/main/java/org/ole/planet/myplanet/model/RealmNewsLog.kt b/app/src/main/java/org/ole/planet/myplanet/model/RealmNewsLog.kt index 4fbc3a5e71..5cd0403475 100644 --- a/app/src/main/java/org/ole/planet/myplanet/model/RealmNewsLog.kt +++ b/app/src/main/java/org/ole/planet/myplanet/model/RealmNewsLog.kt @@ -1,12 +1,12 @@ package org.ole.planet.myplanet.model import com.google.gson.JsonObject -import io.realm.RealmObject -import io.realm.annotations.PrimaryKey +import io.realm.kotlin.types.RealmObject +import io.realm.kotlin.types.annotations.PrimaryKey import org.ole.planet.myplanet.MainApplication import org.ole.planet.myplanet.utilities.NetworkUtils -open class RealmNewsLog : RealmObject() { +class RealmNewsLog : RealmObject { @PrimaryKey var id: String? = null var _id: String? = null @@ -16,8 +16,9 @@ open class RealmNewsLog : RealmObject() { var userId: String? = null var androidId: String? = null + constructor() + companion object { - @JvmStatic fun serialize(log: RealmNewsLog): JsonObject { val ob = JsonObject() ob.addProperty("user", log.userId) @@ -25,10 +26,8 @@ open class RealmNewsLog : RealmObject() { ob.addProperty("time", log.time) ob.addProperty("androidId", NetworkUtils.getUniqueIdentifier()) ob.addProperty("deviceName", NetworkUtils.getDeviceName()) - ob.addProperty( - "customDeviceName", NetworkUtils.getCustomDeviceName(MainApplication.context) - ) + ob.addProperty("customDeviceName", NetworkUtils.getCustomDeviceName(MainApplication.context)) return ob } } -} +} \ No newline at end of file diff --git a/app/src/main/java/org/ole/planet/myplanet/model/RealmOfflineActivity.kt b/app/src/main/java/org/ole/planet/myplanet/model/RealmOfflineActivity.kt index 26a5f5c731..804715feaa 100644 --- a/app/src/main/java/org/ole/planet/myplanet/model/RealmOfflineActivity.kt +++ b/app/src/main/java/org/ole/planet/myplanet/model/RealmOfflineActivity.kt @@ -1,21 +1,21 @@ package org.ole.planet.myplanet.model -import android.content.Context +import io.realm.kotlin.types.RealmObject +import io.realm.kotlin.types.annotations.PrimaryKey +import io.realm.kotlin.Realm import com.google.gson.JsonObject -import com.opencsv.CSVWriter -import io.realm.Realm -import io.realm.RealmObject -import io.realm.Sort -import io.realm.annotations.PrimaryKey -import org.ole.planet.myplanet.MainApplication.Companion.context -import org.ole.planet.myplanet.service.UserProfileDbHandler -import org.ole.planet.myplanet.utilities.JsonUtils -import org.ole.planet.myplanet.utilities.NetworkUtils import java.io.File import java.io.FileWriter import java.io.IOException +import com.opencsv.CSVWriter +import android.content.Context +import io.realm.kotlin.query.Sort +import org.ole.planet.myplanet.MainApplication +import org.ole.planet.myplanet.utilities.JsonUtils +import org.ole.planet.myplanet.utilities.NetworkUtils +import org.ole.planet.myplanet.service.UserProfileDbHandler -open class RealmOfflineActivity : RealmObject() { +class RealmOfflineActivity : RealmObject { @PrimaryKey var id: String? = null var _id: String? = null @@ -29,6 +29,9 @@ open class RealmOfflineActivity : RealmObject() { var loginTime: Long? = null var logoutTime: Long? = null var androidId: String? = null + + constructor() + fun changeRev(r: JsonObject?) { if (r != null) { _rev = JsonUtils.getString("_rev", r) @@ -38,7 +41,7 @@ open class RealmOfflineActivity : RealmObject() { companion object { private val offlineDataList: MutableList> = mutableListOf() - @JvmStatic + fun serializeLoginActivities(realmOfflineActivities: RealmOfflineActivity, context: Context): JsonObject { val ob = JsonObject() ob.addProperty("user", realmOfflineActivities.userName) @@ -50,78 +53,79 @@ open class RealmOfflineActivity : RealmObject() { ob.addProperty("androidId", NetworkUtils.getUniqueIdentifier()) ob.addProperty("deviceName", NetworkUtils.getDeviceName()) ob.addProperty("customDeviceName", NetworkUtils.getCustomDeviceName(context)) - if (realmOfflineActivities._id != null) { + + realmOfflineActivities._id?.let { ob.addProperty("_id", realmOfflineActivities.logoutTime) } - if (realmOfflineActivities._rev != null) { + realmOfflineActivities._rev?.let { ob.addProperty("_rev", realmOfflineActivities._rev) } return ob } - @JvmStatic - fun getRecentLogin(mRealm: Realm): RealmOfflineActivity? { - return mRealm.where(RealmOfflineActivity::class.java) - .equalTo("type", UserProfileDbHandler.KEY_LOGIN).sort("loginTime", Sort.DESCENDING) - .findFirst() + fun getRecentLogin(realm: Realm): RealmOfflineActivity? { + return realm.query(RealmOfflineActivity::class) + .query("type == $0", UserProfileDbHandler.KEY_LOGIN) + .sort("loginTime", Sort.DESCENDING) + .first() + .find() } - @JvmStatic - fun insert(mRealm: Realm, act: JsonObject?) { - if (!mRealm.isInTransaction) { - mRealm.beginTransaction() - } - var activities = mRealm.where(RealmOfflineActivity::class.java) - .equalTo("_id", JsonUtils.getString("_id", act)) - .findFirst() - if (activities == null) { - activities = mRealm.createObject(RealmOfflineActivity::class.java, JsonUtils.getString("_id", act)) - } - if (activities != null) { - activities._rev = JsonUtils.getString("_rev", act) - activities._id = JsonUtils.getString("_id", act) - activities.loginTime = JsonUtils.getLong("loginTime", act) - activities.type = JsonUtils.getString("type", act) - activities.userName = JsonUtils.getString("user", act) - activities.parentCode = JsonUtils.getString("parentCode", act) - activities.createdOn = JsonUtils.getString("createdOn", act) - activities.userName = JsonUtils.getString("user", act) - activities.logoutTime = JsonUtils.getLong("logoutTime", act) - activities.androidId = JsonUtils.getString("androidId", act) - } - mRealm.commitTransaction() + suspend fun insert(realm: Realm, act: JsonObject?) { + realm.write { + val _id = JsonUtils.getString("_id", act) + + val activities = query(RealmOfflineActivity::class) + .query("_id == $0", _id) + .first() + .find() ?: copyToRealm(RealmOfflineActivity().apply { + id = _id + this._id = _id + }) - val csvRow = arrayOf( - JsonUtils.getString("_id", act), - JsonUtils.getString("_rev", act), - JsonUtils.getString("user", act), - JsonUtils.getString("type", act), - JsonUtils.getString("createdOn", act), - JsonUtils.getString("parentCode", act), - JsonUtils.getLong("loginTime", act).toString(), - JsonUtils.getLong("logoutTime", act).toString(), - JsonUtils.getString("androidId", act) - ) - offlineDataList.add(csvRow) + activities.apply { + _rev = JsonUtils.getString("_rev", act) + loginTime = JsonUtils.getLong("loginTime", act) + type = JsonUtils.getString("type", act) + userName = JsonUtils.getString("user", act) + parentCode = JsonUtils.getString("parentCode", act) + createdOn = JsonUtils.getString("createdOn", act) + logoutTime = JsonUtils.getLong("logoutTime", act) + androidId = JsonUtils.getString("androidId", act) + } + + val csvRow = arrayOf( + JsonUtils.getString("_id", act), + JsonUtils.getString("_rev", act), + JsonUtils.getString("user", act), + JsonUtils.getString("type", act), + JsonUtils.getString("createdOn", act), + JsonUtils.getString("parentCode", act), + JsonUtils.getLong("loginTime", act).toString(), + JsonUtils.getLong("logoutTime", act).toString(), + JsonUtils.getString("androidId", act) + ) + offlineDataList.add(csvRow) + } } fun writeCsv(filePath: String, data: List>) { try { val file = File(filePath) file.parentFile?.mkdirs() - val writer = CSVWriter(FileWriter(file)) - writer.writeNext(arrayOf("id", "_rev", "userName", "type", "createdOn", "parentCode", "loginTime", "logoutTime", "androidId")) - for (row in data) { - writer.writeNext(row) + CSVWriter(FileWriter(file)).use { writer -> + writer.writeNext(arrayOf("id", "_rev", "userName", "type", "createdOn", "parentCode", "loginTime", "logoutTime", "androidId")) + for (row in data) { + writer.writeNext(row) + } } - writer.close() } catch (e: IOException) { e.printStackTrace() } } fun offlineWriteCsv() { - writeCsv("${context.getExternalFilesDir(null)}/ole/offlineActivity.csv", offlineDataList) + writeCsv("${MainApplication.context.getExternalFilesDir(null)}/ole/offlineActivity.csv", offlineDataList) } } -} +} \ No newline at end of file diff --git a/app/src/main/java/org/ole/planet/myplanet/model/RealmRemovedLog.kt b/app/src/main/java/org/ole/planet/myplanet/model/RealmRemovedLog.kt index e92910d345..d96698b723 100644 --- a/app/src/main/java/org/ole/planet/myplanet/model/RealmRemovedLog.kt +++ b/app/src/main/java/org/ole/planet/myplanet/model/RealmRemovedLog.kt @@ -1,54 +1,43 @@ package org.ole.planet.myplanet.model -import io.realm.Realm -import io.realm.RealmObject -import io.realm.annotations.PrimaryKey -import java.util.UUID +import io.realm.kotlin.Realm +import io.realm.kotlin.types.RealmObject +import io.realm.kotlin.types.annotations.PrimaryKey +import io.realm.kotlin.ext.query -open class RealmRemovedLog : RealmObject() { +class RealmRemovedLog : RealmObject { @PrimaryKey var id: String? = null - private var userId: String? = null - private var type: String? = null - private var docId: String? = null + var userId: String? = null + var type: String? = null + var docId: String? = null companion object { - @JvmStatic - fun onAdd(mRealm: Realm, type: String?, userId: String?, docId: String?) { - if (!mRealm.isInTransaction) mRealm.beginTransaction() - mRealm.where(RealmRemovedLog::class.java) - .equalTo("type", type) - .equalTo("userId", userId) - .equalTo("docId", docId) - .findAll().deleteAllFromRealm() - mRealm.commitTransaction() + fun onAdd(realm: Realm, type: String?, userId: String?, docId: String?) { + realm.writeBlocking { + query("type == $0 AND userId == $1 AND docId == $2", + type ?: "", + userId ?: "", + docId ?: "" + ).find() + .forEach { delete(it) } + } } - @JvmStatic - fun onRemove(mRealm: Realm, type: String, userId: String?, docId: String?) { - if (!mRealm.isInTransaction) mRealm.beginTransaction() - val log = mRealm.createObject(RealmRemovedLog::class.java, UUID.randomUUID().toString()) - log.docId = docId - log.userId = userId - log.type = type - mRealm.commitTransaction() + fun onRemove(realm: Realm, type: String, userId: String?, docId: String?) { + realm.writeBlocking { + copyToRealm(RealmRemovedLog().apply { + this.docId = docId + this.userId = userId + this.type = type + }) + } } - @JvmStatic - fun removedIds(realm: Realm?, type: String, userId: String?): Array { - val removedLibs = realm?.where(RealmRemovedLog::class.java) - ?.equalTo("userId", userId) - ?.equalTo("type", type) - ?.findAll() + fun removedIds(realm: Realm, type: String, userId: String?): Array { + val removedLibs = realm.query("userId == $0 AND type == $1", userId, type).find() - if (removedLibs != null) { - val ids = Array(removedLibs.size) { "" } - for ((i, removed) in removedLibs.withIndex()) { - ids[i] = removed.docId ?: "" - } - return ids - } - return arrayOf() + return removedLibs.mapNotNull { it.docId }.toTypedArray() } } } diff --git a/app/src/main/java/org/ole/planet/myplanet/model/RealmResourceActivity.kt b/app/src/main/java/org/ole/planet/myplanet/model/RealmResourceActivity.kt index 2e76ebe9ae..956225de11 100644 --- a/app/src/main/java/org/ole/planet/myplanet/model/RealmResourceActivity.kt +++ b/app/src/main/java/org/ole/planet/myplanet/model/RealmResourceActivity.kt @@ -1,15 +1,15 @@ package org.ole.planet.myplanet.model import android.content.SharedPreferences +import io.realm.kotlin.types.RealmObject +import io.realm.kotlin.types.annotations.PrimaryKey +import io.realm.kotlin.Realm import com.google.gson.JsonObject -import io.realm.Realm -import io.realm.RealmObject -import io.realm.annotations.PrimaryKey import org.ole.planet.myplanet.utilities.NetworkUtils import java.util.Date import java.util.UUID -open class RealmResourceActivity : RealmObject() { +class RealmResourceActivity : RealmObject { @PrimaryKey var id: String? = null var _id: String? = null @@ -23,8 +23,9 @@ open class RealmResourceActivity : RealmObject() { var user: String? = null var androidId: String? = null + constructor() + companion object { - @JvmStatic fun serializeResourceActivities(realmResourceActivities: RealmResourceActivity): JsonObject { val ob = JsonObject() ob.addProperty("user", realmResourceActivities.user) @@ -39,25 +40,24 @@ open class RealmResourceActivity : RealmObject() { return ob } - @JvmStatic - fun onSynced(mRealm: Realm, settings: SharedPreferences) { - if (!mRealm.isInTransaction) { - mRealm.beginTransaction() - } - val user = mRealm.where(RealmUserModel::class.java).equalTo("id", settings.getString("userId", "")).findFirst() - ?: return - if (user.id?.startsWith("guest") == true) { - return + suspend fun onSynced(realm: Realm, settings: SharedPreferences) { + realm.write { + val userId = settings.getString("userId", "") ?: "" + val user = query(RealmUserModel::class).query("id == $0", userId).first().find() ?: return@write + + if (user.id.startsWith("guest") == true) return@write + + copyToRealm(RealmResourceActivity().apply { + id = UUID.randomUUID().toString() + this.user = user.name + _rev = null + _id = null + parentCode = user.parentCode + createdOn = user.planetCode + type = "sync" + time = Date().time + }) } - val activities = mRealm.createObject(RealmResourceActivity::class.java, UUID.randomUUID().toString()) - activities.user = user.name - activities._rev = null - activities._id = null - activities.parentCode = user.parentCode - activities.createdOn = user.planetCode - activities.type = "sync" - activities.time = Date().time - mRealm.commitTransaction() } } -} +} \ No newline at end of file From 254dd48cafd27b571f7fa587695db45b2bfbf1ca Mon Sep 17 00:00:00 2001 From: Gideon Okuro Date: Tue, 3 Dec 2024 13:35:05 +0300 Subject: [PATCH 07/38] migrate realmMylife --- .../ole/planet/myplanet/model/RealmMyLife.kt | 58 ++++++++----------- 1 file changed, 24 insertions(+), 34 deletions(-) diff --git a/app/src/main/java/org/ole/planet/myplanet/model/RealmMyLife.kt b/app/src/main/java/org/ole/planet/myplanet/model/RealmMyLife.kt index ff602979b3..107407e7fc 100644 --- a/app/src/main/java/org/ole/planet/myplanet/model/RealmMyLife.kt +++ b/app/src/main/java/org/ole/planet/myplanet/model/RealmMyLife.kt @@ -1,18 +1,18 @@ package org.ole.planet.myplanet.model +import io.realm.kotlin.types.RealmObject +import io.realm.kotlin.types.annotations.PrimaryKey +import io.realm.kotlin.Realm import android.content.SharedPreferences -import io.realm.Realm -import io.realm.RealmObject -import io.realm.annotations.PrimaryKey -open class RealmMyLife : RealmObject { +class RealmMyLife : RealmObject { @PrimaryKey var _id: String? = null var imageId: String? = null var userId: String? = null var title: String? = null - var isVisible = false - var weight = 0 + var isVisible: Boolean = false + var weight: Int = 0 constructor(imageId: String?, userId: String?, title: String?) { this.imageId = imageId @@ -24,46 +24,36 @@ open class RealmMyLife : RealmObject { constructor() companion object { - fun getMyLifeByUserId(mRealm: Realm, settings: SharedPreferences?): List { + fun getMyLifeByUserId(realm: Realm, settings: SharedPreferences?): List { val userId = settings?.getString("userId", "--") - return getMyLifeByUserId(mRealm, userId) + return getMyLifeByUserId(realm, userId) } - @JvmStatic - fun getMyLifeByUserId(mRealm: Realm, userId: String?): List { - return mRealm.where(RealmMyLife::class.java).equalTo("userId", userId).findAll() - .sort("weight") + fun getMyLifeByUserId(realm: Realm, userId: String?): List { + return realm.query(RealmMyLife::class, "userId == $0", userId).find().sortedBy { it.weight } } - @JvmStatic fun updateWeight(weight: Int, id: String?, realm: Realm, userId: String?) { - realm.executeTransaction { mRealm -> - var currentWeight = -1 - val myLifeList = getMyLifeByUserId(mRealm, userId) - for (item in myLifeList) { - if (id?.let { item._id?.contains(it) } == true) { - currentWeight = item.weight - item.weight = weight - } - } - for (item in myLifeList) { - if (currentWeight != -1 && item.weight == weight && !id?.let { item._id?.contains(it) }!!) { - item.weight = currentWeight + realm.writeBlocking { + val myLifeList = getMyLifeByUserId(realm, userId) + val targetItem = myLifeList.find { it._id?.contains(id ?: "") == true } + + targetItem?.let { current -> + val currentWeight = current.weight + current.weight = weight + + myLifeList.filter { it._id != current._id && it.weight == weight }.forEach { + it.weight = currentWeight } } } } - @JvmStatic fun updateVisibility(isVisible: Boolean, id: String?, realm: Realm, userId: String?) { - realm.executeTransaction { mRealm -> - val myLifeList = getMyLifeByUserId(mRealm, userId) - for (item in myLifeList) { - if (id?.let { item._id?.contains(it) } == true) { - item.isVisible = isVisible - } - } + realm.writeBlocking { + val myLifeList = getMyLifeByUserId(realm, userId) + myLifeList.find { it._id?.contains(id ?: "") == true }?.isVisible = isVisible } } } -} +} \ No newline at end of file From f5f95ce06cb05599ab3516377d79c128e782f5da Mon Sep 17 00:00:00 2001 From: Gideon Okuro Date: Fri, 6 Dec 2024 17:17:48 +0300 Subject: [PATCH 08/38] migrate realm rating --- .../ole/planet/myplanet/model/RealmRating.kt | 199 +++++++++--------- 1 file changed, 96 insertions(+), 103 deletions(-) diff --git a/app/src/main/java/org/ole/planet/myplanet/model/RealmRating.kt b/app/src/main/java/org/ole/planet/myplanet/model/RealmRating.kt index b37dbef458..781a7d6008 100644 --- a/app/src/main/java/org/ole/planet/myplanet/model/RealmRating.kt +++ b/app/src/main/java/org/ole/planet/myplanet/model/RealmRating.kt @@ -3,28 +3,25 @@ package org.ole.planet.myplanet.model import com.google.gson.Gson import com.google.gson.JsonObject import com.opencsv.CSVWriter -import io.realm.Realm -import io.realm.RealmObject -import io.realm.annotations.PrimaryKey -import org.ole.planet.myplanet.MainApplication.Companion.context -import org.ole.planet.myplanet.utilities.JsonUtils -import org.ole.planet.myplanet.utilities.NetworkUtils +import io.realm.kotlin.Realm +import io.realm.kotlin.ext.query +import io.realm.kotlin.types.RealmObject +import io.realm.kotlin.types.annotations.PrimaryKey import java.io.File import java.io.FileWriter import java.io.IOException -open class RealmRating : RealmObject() { +class RealmRating : RealmObject { @PrimaryKey - var id: String? = null + var id: String = "" var createdOn: String? = null - var _rev: String? = null + var rev: String? = null var time: Long = 0 var title: String? = null var userId: String? = null - var isUpdated = false - var rate = 0 - var _id: String? = null - var item: String? = null + var isUpdated: Boolean = false + var rate: Int = 0 + var itemId: String? = null var comment: String? = null var parentCode: String? = null var planetCode: String? = null @@ -33,102 +30,93 @@ open class RealmRating : RealmObject() { companion object { private val ratingDataList: MutableList> = mutableListOf() - @JvmStatic - fun getRatings(mRealm: Realm, type: String?, userId: String?): HashMap { - val r = mRealm.where(RealmRating::class.java).equalTo("type", type).findAll() - val map = HashMap() - for (rating in r) { - val `object` = getRatingsById(mRealm, rating.type, rating.item, userId) - if (`object` != null) map[rating.item] = `object` + + suspend fun getRatings(realm: Realm, type: String?, userId: String?): Map { + val results = realm.query("type == $0", type).find() + val map = mutableMapOf() + + for (rating in results) { + val ratingObject = getRatingsById(realm, rating.type, rating.itemId, userId) + if (ratingObject != null) map[rating.itemId] = ratingObject } + return map } - @JvmStatic - fun getRatingsById(mRealm: Realm, type: String?, id: String?, userid: String?): JsonObject? { - val r = mRealm.where(RealmRating::class.java).equalTo("type", type).equalTo("item", id).findAll() - if (r.size == 0) { - return null - } - val `object` = JsonObject() - var totalRating = 0 - for (rating in r) { - totalRating += rating.rate - } - val ratingObject = mRealm.where(RealmRating::class.java).equalTo("type", type) - .equalTo("userId", userid).equalTo("item", id).findFirst() - if (ratingObject != null) { - `object`.addProperty("ratingByUser", ratingObject.rate) - } - `object`.addProperty("averageRating", totalRating.toFloat() / r.size) - `object`.addProperty("total", r.size) - return `object` + suspend fun getRatingsById(realm: Realm, type: String?, id: String?, userId: String?): JsonObject? { + val results = realm.query("type == $0 && itemId == $1", type, id).find() + if (results.isEmpty()) return null + + val totalRating = results.sumOf { it.rate } + val avgRating = totalRating.toFloat() / results.size + + val userRating = results.firstOrNull { it.userId == userId } + val jsonObject = JsonObject() + jsonObject.addProperty("ratingByUser", userRating?.rate ?: 0) + jsonObject.addProperty("averageRating", avgRating) + jsonObject.addProperty("total", results.size) + + return jsonObject } - @JvmStatic fun serializeRating(realmRating: RealmRating): JsonObject { - val ob = JsonObject() - if (realmRating._id != null) ob.addProperty("_id", realmRating._id) - if (realmRating._rev != null) ob.addProperty("_rev", realmRating._rev) - ob.add("user", Gson().fromJson(realmRating.user, JsonObject::class.java)) - ob.addProperty("item", realmRating.item) - ob.addProperty("type", realmRating.type) - ob.addProperty("title", realmRating.title) - ob.addProperty("time", realmRating.time) - ob.addProperty("comment", realmRating.comment) - ob.addProperty("rate", realmRating.rate) - ob.addProperty("createdOn", realmRating.createdOn) - ob.addProperty("parentCode", realmRating.parentCode) - ob.addProperty("planetCode", realmRating.planetCode) - ob.addProperty("customDeviceName", NetworkUtils.getCustomDeviceName(context)) - ob.addProperty("deviceName", NetworkUtils.getDeviceName()) - ob.addProperty("androidId", NetworkUtils.getUniqueIdentifier()) - return ob + val jsonObject = JsonObject() + jsonObject.addProperty("_id", realmRating.id) + jsonObject.addProperty("_rev", realmRating.rev) + jsonObject.add("user", Gson().fromJson(realmRating.user, JsonObject::class.java)) + jsonObject.addProperty("item", realmRating.itemId) + jsonObject.addProperty("type", realmRating.type) + jsonObject.addProperty("title", realmRating.title) + jsonObject.addProperty("time", realmRating.time) + jsonObject.addProperty("comment", realmRating.comment) + jsonObject.addProperty("rate", realmRating.rate) + jsonObject.addProperty("createdOn", realmRating.createdOn) + jsonObject.addProperty("parentCode", realmRating.parentCode) + jsonObject.addProperty("planetCode", realmRating.planetCode) + return jsonObject } - @JvmStatic - fun insert(mRealm: Realm, act: JsonObject) { - if (!mRealm.isInTransaction) { - mRealm.beginTransaction() - } - var rating = mRealm.where(RealmRating::class.java).equalTo("_id", JsonUtils.getString("_id", act)).findFirst() - if (rating == null) { - rating = mRealm.createObject(RealmRating::class.java, JsonUtils.getString("_id", act)) - } - if (rating != null) { - rating._rev = JsonUtils.getString("_rev", act) - rating._id = JsonUtils.getString("_id", act) - rating.time = JsonUtils.getLong("time", act) - rating.title = JsonUtils.getString("title", act) - rating.type = JsonUtils.getString("type", act) - rating.item = JsonUtils.getString("item", act) - rating.rate = JsonUtils.getInt("rate", act) - rating.isUpdated = false - rating.comment = JsonUtils.getString("comment", act) - rating.user = Gson().toJson(JsonUtils.getJsonObject("user", act)) - rating.userId = JsonUtils.getString("_id", JsonUtils.getJsonObject("user", act)) - rating.parentCode = JsonUtils.getString("parentCode", act) - rating.parentCode = JsonUtils.getString("planetCode", act) - rating.createdOn = JsonUtils.getString("createdOn", act) + + suspend fun insert(realm: Realm, act: JsonObject) { + realm.writeBlocking { + val rating = query("id == $0", act.get("_id").asString).first().find() + ?: RealmRating().apply { + id = act.get("_id").asString + }.also { copyToRealm(it) } + + rating.apply { + rev = act.get("_rev").asString + time = act.get("time").asLong + title = act.get("title").asString + type = act.get("type").asString + itemId = act.get("item").asString + rate = act.get("rate").asInt + isUpdated = false + comment = act.get("comment").asString + user = Gson().toJson(act.getAsJsonObject("user")) + userId = act.getAsJsonObject("user").get("_id").asString + parentCode = act.get("parentCode").asString + planetCode = act.get("planetCode").asString + createdOn = act.get("createdOn").asString + } + + ratingDataList.add( + arrayOf( + act.get("_id").asString, + act.get("_rev").asString, + act.get("user").toString(), + act.get("item").asString, + act.get("type").asString, + act.get("title").asString, + act.get("time").asString, + act.get("comment").asString, + act.get("rate").asString, + act.get("createdOn").asString, + act.get("parentCode").asString, + act.get("planetCode").asString + ) + ) } - mRealm.commitTransaction() - - val csvRow = arrayOf( - JsonUtils.getString("_id", act), - JsonUtils.getString("_rev", act), - JsonUtils.getString("user", act), - JsonUtils.getString("item", act), - JsonUtils.getString("type", act), - JsonUtils.getString("title", act), - JsonUtils.getLong("time", act).toString(), - JsonUtils.getString("comment", act), - JsonUtils.getInt("rate", act).toString(), - JsonUtils.getString("createdOn", act), - JsonUtils.getString("parentCode", act), - JsonUtils.getString("planetCode", act) - ) - - ratingDataList.add(csvRow) } fun writeCsv(filePath: String, data: List>) { @@ -136,7 +124,12 @@ open class RealmRating : RealmObject() { val file = File(filePath) file.parentFile?.mkdirs() val writer = CSVWriter(FileWriter(file)) - writer.writeNext(arrayOf("_id", "_rev", "user", "item", "type", "title", "time", "comment", "rate", "createdOn", "parentCode", "planetCode")) + writer.writeNext( + arrayOf( + "_id", "_rev", "user", "item", "type", "title", + "time", "comment", "rate", "createdOn", "parentCode", "planetCode" + ) + ) for (row in data) { writer.writeNext(row) } @@ -146,8 +139,8 @@ open class RealmRating : RealmObject() { } } - fun ratingWriteCsv() { - writeCsv("${context.getExternalFilesDir(null)}/ole/ratings.csv", ratingDataList) + fun ratingWriteCsv(filePath: String) { + writeCsv(filePath, ratingDataList) } } -} +} \ No newline at end of file From dcee5de56e5f310210aed5d76a789a7ed27e3de9 Mon Sep 17 00:00:00 2001 From: Gideon Okuro Date: Fri, 6 Dec 2024 17:22:46 +0300 Subject: [PATCH 09/38] migrate realm feedback --- .../planet/myplanet/model/RealmFeedback.kt | 228 ++++++++---------- 1 file changed, 107 insertions(+), 121 deletions(-) diff --git a/app/src/main/java/org/ole/planet/myplanet/model/RealmFeedback.kt b/app/src/main/java/org/ole/planet/myplanet/model/RealmFeedback.kt index c3f3e8c37e..72bfef4c4d 100644 --- a/app/src/main/java/org/ole/planet/myplanet/model/RealmFeedback.kt +++ b/app/src/main/java/org/ole/planet/myplanet/model/RealmFeedback.kt @@ -1,23 +1,16 @@ package org.ole.planet.myplanet.model -import android.text.TextUtils -import com.google.gson.Gson -import com.google.gson.JsonArray -import com.google.gson.JsonObject -import com.google.gson.JsonParser -import com.google.gson.stream.JsonReader -import com.opencsv.CSVWriter -import io.realm.Realm -import io.realm.RealmObject -import io.realm.annotations.PrimaryKey -import org.ole.planet.myplanet.MainApplication.Companion.context -import org.ole.planet.myplanet.utilities.JsonUtils +import com.google.gson.* +import io.realm.kotlin.Realm +import io.realm.kotlin.ext.query +import io.realm.kotlin.types.RealmObject +import io.realm.kotlin.types.annotations.PrimaryKey import java.io.File import java.io.FileWriter import java.io.IOException -import java.io.StringReader +import kotlin.collections.MutableList -open class RealmFeedback : RealmObject() { +class RealmFeedback : RealmObject { @PrimaryKey var id: String? = null var _id: String? = null @@ -31,139 +24,132 @@ open class RealmFeedback : RealmObject() { var url: String? = null var isUploaded = false var _rev: String? = null - var messages: String? = null - private set + private var messages: String? = null var item: String? = null var parentCode: String? = null var state: String? = null + fun setMessages(messages: JsonArray?) { this.messages = Gson().toJson(messages) } val messageList: List? - get() { - if (TextUtils.isEmpty(messages)) return null - val feedbackReplies: MutableList = ArrayList() - - val stringReader = StringReader(messages) - val jsonReader = JsonReader(stringReader) - - val e = JsonParser.parseReader(jsonReader) - val ar = e.asJsonArray - if (ar.size() > 0) { - for (i in 1 until ar.size()) { - val ob = ar[i].asJsonObject - feedbackReplies.add( - FeedbackReply( - ob["message"].asString, - ob["user"].asString, - ob["time"].asString - ) + get() = if (messages.isNullOrEmpty()) { + null + } else { + try { + val jsonArray = JsonParser.parseString(messages).asJsonArray + jsonArray.map { + val jsonObject = it.asJsonObject + FeedbackReply( + jsonObject["message"].asString, + jsonObject["user"].asString, + jsonObject["time"].asString ) } + } catch (e: Exception) { + null } - return feedbackReplies } val message: String - get() { - if (TextUtils.isEmpty(messages)) return "" - - val stringReader = StringReader(messages) - val jsonReader = JsonReader(stringReader) - - val e = JsonParser.parseReader(jsonReader) - val ar = e.asJsonArray - if (ar.size() > 0) { - val ob = ar[0].asJsonObject - return ob["message"].asString + get() = if (messages.isNullOrEmpty()) { + "" + } else { + try { + val jsonArray = JsonParser.parseString(messages).asJsonArray + if (jsonArray.size() > 0) { + jsonArray[0].asJsonObject["message"].asString + } else { + "" + } + } catch (e: Exception) { + "" } - return "" } - fun setMessages(messages: String?) { - this.messages = messages - } - companion object { - val feedbacksDataList: MutableList> = mutableListOf() - @JvmStatic - fun serializeFeedback(feedback: RealmFeedback): JsonObject { - val `object` = JsonObject() - `object`.addProperty("title", feedback.title) - `object`.addProperty("source", feedback.source) - `object`.addProperty("status", feedback.status) - `object`.addProperty("priority", feedback.priority) - `object`.addProperty("owner", feedback.owner) - `object`.addProperty("openTime", feedback.openTime) - `object`.addProperty("type", feedback.type) - `object`.addProperty("url", feedback.url) - `object`.addProperty("parentCode", feedback.parentCode) - `object`.addProperty("state", feedback.state) - `object`.addProperty("item", feedback.item) - if (feedback._id != null) `object`.addProperty("_id", feedback._id) - if (feedback._rev != null) `object`.addProperty("_rev", feedback._rev) + private val feedbacksDataList: MutableList> = mutableListOf() - try { - `object`.add("messages", JsonParser.parseString(feedback.messages)) - } catch (err: Exception) { - err.printStackTrace() + suspend fun insert(realm: Realm, act: JsonObject) { + realm.writeBlocking { + val feedback = query("_id == $0", act["_id"].asString).first().find() + ?: RealmFeedback().apply { + _id = act["_id"].asString + }.also { copyToRealm(it) } + + feedback.apply { + title = act["title"].asString + source = act["source"].asString + status = act["status"].asString + priority = act["priority"].asString + owner = act["owner"].asString + openTime = act["openTime"].asLong + type = act["type"].asString + url = act["url"].asString + parentCode = act["parentCode"].asString + setMessages(act["messages"].asJsonArray) + isUploaded = true + item = act["item"].asString + state = act["state"].asString + _rev = act["_rev"].asString + } + + feedbacksDataList.add( + arrayOf( + act["_id"].asString, + act["title"].asString, + act["source"].asString, + act["status"].asString, + act["priority"].asString, + act["owner"].asString, + act["openTime"].asString, + act["type"].asString, + act["url"].asString, + act["parentCode"].asString, + act["state"].asString, + act["item"].asString, + act["messages"].asJsonArray.toString() + ) + ) } - return `object` } - @JvmStatic - fun insert(mRealm: Realm, act: JsonObject?) { - if (!mRealm.isInTransaction) { - mRealm.beginTransaction() - } - var feedback = mRealm.where(RealmFeedback::class.java).equalTo("_id", JsonUtils.getString("_id", act)).findFirst() - if (feedback == null) { - feedback = mRealm.createObject(RealmFeedback::class.java, JsonUtils.getString("_id", act)) - } - feedback?._id = JsonUtils.getString("_id", act) - feedback?.title = JsonUtils.getString("title", act) - feedback?.source = JsonUtils.getString("source", act) - feedback?.status = JsonUtils.getString("status", act) - feedback?.priority = JsonUtils.getString("priority", act) - feedback?.owner = JsonUtils.getString("owner", act) - feedback?.openTime = JsonUtils.getLong("openTime", act) - feedback?.type = JsonUtils.getString("type", act) - feedback?.url = JsonUtils.getString("url", act) - feedback?.parentCode = JsonUtils.getString("parentCode", act) - feedback?.setMessages(Gson().toJson(JsonUtils.getJsonArray("messages", act))) - feedback?.isUploaded = true - feedback?.item = JsonUtils.getString("item", act) - feedback?.state = JsonUtils.getString("state", act) - feedback?._rev = JsonUtils.getString("_rev", act) - mRealm.commitTransaction() + fun serializeFeedback(feedback: RealmFeedback): JsonObject { + val jsonObject = JsonObject() + jsonObject.addProperty("title", feedback.title) + jsonObject.addProperty("source", feedback.source) + jsonObject.addProperty("status", feedback.status) + jsonObject.addProperty("priority", feedback.priority) + jsonObject.addProperty("owner", feedback.owner) + jsonObject.addProperty("openTime", feedback.openTime) + jsonObject.addProperty("type", feedback.type) + jsonObject.addProperty("url", feedback.url) + jsonObject.addProperty("parentCode", feedback.parentCode) + jsonObject.addProperty("state", feedback.state) + jsonObject.addProperty("item", feedback.item) + feedback._id?.let { jsonObject.addProperty("_id", it) } + feedback._rev?.let { jsonObject.addProperty("_rev", it) } - val csvRow = arrayOf( - JsonUtils.getString("_id", act), - JsonUtils.getString("title", act), - JsonUtils.getString("source", act), - JsonUtils.getString("status", act), - JsonUtils.getString("priority", act), - JsonUtils.getString("owner", act), - JsonUtils.getLong("openTime", act).toString(), - JsonUtils.getString("type", act), - JsonUtils.getString("url", act), - JsonUtils.getString("parentCode", act), - JsonUtils.getString("state", act), - JsonUtils.getString("item", act), - JsonUtils.getJsonArray("messages", act).toString() - ) - feedbacksDataList.add(csvRow) + try { + feedback.messages?.let { + jsonObject.add("messages", JsonParser.parseString(it)) + } + } catch (e: Exception) { + e.printStackTrace() + } + return jsonObject } fun writeCsv(filePath: String, data: List>) { try { val file = File(filePath) file.parentFile?.mkdirs() - val writer = CSVWriter(FileWriter(file)) - writer.writeNext(arrayOf("feedbackId", "title", "source", "status", "priority", "owner", "openTime", "type", "url", "parentCode", "state", "item", "messages")) - for (row in data) { - writer.writeNext(row) + val writer = FileWriter(file) + writer.write("feedbackId,title,source,status,priority,owner,openTime,type,url,parentCode,state,item,messages\n") + data.forEach { row -> + writer.write(row.joinToString(",")) + writer.write("\n") } writer.close() } catch (e: IOException) { @@ -171,8 +157,8 @@ open class RealmFeedback : RealmObject() { } } - fun feedbackWriteCsv() { - writeCsv("${context.getExternalFilesDir(null)}/ole/feedback.csv", feedbacksDataList) + fun feedbackWriteCsv(filePath: String) { + writeCsv(filePath, feedbacksDataList) } } -} +} \ No newline at end of file From 8064d8533020df82f2395c2471fbd67f6728247b Mon Sep 17 00:00:00 2001 From: Gideon Okuro Date: Fri, 6 Dec 2024 18:10:09 +0300 Subject: [PATCH 10/38] migrate realm myhealthpojo --- .../myplanet/model/RealmMyHealthPojo.kt | 207 +++++++++--------- 1 file changed, 101 insertions(+), 106 deletions(-) diff --git a/app/src/main/java/org/ole/planet/myplanet/model/RealmMyHealthPojo.kt b/app/src/main/java/org/ole/planet/myplanet/model/RealmMyHealthPojo.kt index d125e6b961..2a9a42ccd4 100644 --- a/app/src/main/java/org/ole/planet/myplanet/model/RealmMyHealthPojo.kt +++ b/app/src/main/java/org/ole/planet/myplanet/model/RealmMyHealthPojo.kt @@ -1,113 +1,104 @@ package org.ole.planet.myplanet.model -import android.text.TextUtils -import com.google.gson.Gson -import com.google.gson.JsonObject +import com.google.gson.* import com.opencsv.CSVWriter -import io.realm.Realm -import io.realm.RealmObject -import io.realm.annotations.PrimaryKey +import io.realm.kotlin.Realm +import io.realm.kotlin.types.RealmObject +import io.realm.kotlin.types.annotations.PrimaryKey import org.ole.planet.myplanet.MainApplication.Companion.context import org.ole.planet.myplanet.utilities.AndroidDecrypter import org.ole.planet.myplanet.utilities.JsonUtils -import java.io.File -import java.io.FileWriter -import java.io.IOException +import java.io.* -open class RealmMyHealthPojo : RealmObject() { +class RealmMyHealthPojo : RealmObject { @PrimaryKey var _id: String? = null var userId: String? = null - var isUpdated = false + var isUpdated: Boolean = false var _rev: String? = null var data: String? = null - var temperature = 0f - private set - var pulse = 0 + var temperature: Float = 0f + var pulse: Int = 0 var bp: String? = null - var height = 0f - var weight = 0f - private set + var height: Float = 0f + var weight: Float = 0f var vision: String? = null var date: Long = 0 var hearing: String? = null var conditions: String? = null - var isSelfExamination = false + var isSelfExamination: Boolean = false var planetCode: String? = null - var isHasInfo = false + var isHasInfo: Boolean = false var profileId: String? = null var creatorId: String? = null var gender: String? = null - var age = 0 - fun getEncryptedDataAsJson(model: RealmUserModel): JsonObject { - return if (!TextUtils.isEmpty(data)) Gson().fromJson( - AndroidDecrypter.decrypt(data, model.key, model.iv), JsonObject::class.java - ) else JsonObject() - } - - fun setTemperature(temperature: Float) { - this.temperature = temperature - } + var age: Int = 0 - fun setWeight(weight: Float) { - this.weight = weight + fun getEncryptedDataAsJson(key: String, iv: String): JsonObject { + return if (!data.isNullOrEmpty()) { + Gson().fromJson(AndroidDecrypter.decrypt(data!!, key, iv), JsonObject::class.java) + } else { + JsonObject() + } } companion object { val healthDataList: MutableList> = mutableListOf() - @JvmStatic - fun insert(mRealm: Realm, act: JsonObject?) { - if (!mRealm.isInTransaction) { - mRealm.beginTransaction() - } - var myHealth = mRealm.where(RealmMyHealthPojo::class.java).equalTo("_id", JsonUtils.getString("_id", act)).findFirst() - if (myHealth == null) { - myHealth = mRealm.createObject(RealmMyHealthPojo::class.java, JsonUtils.getString("_id", act)) + suspend fun insert(realm: Realm, act: JsonObject?) { + realm.write { + var myHealth = this.query(RealmMyHealthPojo::class, "id == $0", act?.get("_id")?.asString).first().find() + if (myHealth == null) { + myHealth = RealmMyHealthPojo().apply { + _id = act?.get("_id")?.asString ?: "" + } + copyToRealm(myHealth) + } + myHealth.apply { + data = act?.get("data")?.asString + userId = act?.get("_id")?.asString + _rev = act?.get("_rev")?.asString + temperature = act?.get("temperature")?.asFloat ?: 0f + isUpdated = false + pulse = act?.get("pulse")?.asInt ?: 0 + height = act?.get("height")?.asFloat ?: 0f + weight = act?.get("weight")?.asFloat ?: 0f + vision = act?.get("vision")?.asString + hearing = act?.get("hearing")?.asString + bp = act?.get("bp")?.asString + isSelfExamination = act?.get("selfExamination")?.asBoolean ?: false + isHasInfo = act?.get("hasInfo")?.asBoolean ?: false + date = act?.get("date")?.asLong ?: 0L + profileId = act?.get("profileId")?.asString + creatorId = act?.get("creatorId")?.asString + age = act?.get("age")?.asInt ?: 0 + gender = act?.get("gender")?.asString + conditions = Gson().toJson(act?.get("conditions")?.asJsonObject) + } + + val csvRow = arrayOf( + JsonUtils.getString("_id", act), + JsonUtils.getString("_rev", act), + JsonUtils.getString("data", act), + JsonUtils.getFloat("temperature", act).toString(), + JsonUtils.getInt("pulse", act).toString(), + JsonUtils.getString("bp", act), + JsonUtils.getFloat("height", act).toString(), + JsonUtils.getFloat("weight", act).toString(), + JsonUtils.getString("vision", act), + JsonUtils.getString("hearing", act), + JsonUtils.getLong("date", act).toString(), + JsonUtils.getBoolean("selfExamination", act).toString(), + JsonUtils.getString("planetCode", act), + JsonUtils.getBoolean("hasInfo", act).toString(), + JsonUtils.getString("profileId", act), + JsonUtils.getString("creatorId", act), + JsonUtils.getInt("age", act).toString(), + JsonUtils.getString("gender", act), + JsonUtils.getJsonObject("conditions", act).toString() + ) + healthDataList.add(csvRow) } - myHealth?.data = JsonUtils.getString("data", act) - myHealth?.userId = JsonUtils.getString("_id", act) - myHealth?._rev = JsonUtils.getString("_rev", act) - myHealth?.setTemperature(JsonUtils.getFloat("temperature", act)) - myHealth?.isUpdated = false - myHealth?.pulse = JsonUtils.getInt("pulse", act) - myHealth?.height = JsonUtils.getFloat("height", act) - myHealth?.setWeight(JsonUtils.getFloat("weight", act)) - myHealth?.vision = JsonUtils.getString("vision", act) - myHealth?.hearing = JsonUtils.getString("hearing", act) - myHealth?.bp = JsonUtils.getString("bp", act) - myHealth?.isSelfExamination = JsonUtils.getBoolean("selfExamination", act) - myHealth?.isHasInfo = JsonUtils.getBoolean("hasInfo", act) - myHealth?.date = JsonUtils.getLong("date", act) - myHealth?.profileId = JsonUtils.getString("profileId", act) - myHealth?.creatorId = JsonUtils.getString("creatorId", act) - myHealth?.age = JsonUtils.getInt("age", act) - myHealth?.gender = JsonUtils.getString("gender", act) - myHealth?.planetCode = JsonUtils.getString("planetCode", act) - myHealth?.conditions = Gson().toJson(JsonUtils.getJsonObject("conditions", act)) - mRealm.commitTransaction() - val csvRow = arrayOf( - JsonUtils.getString("_id", act), - JsonUtils.getString("_rev", act), - JsonUtils.getString("data", act), - JsonUtils.getFloat("temperature", act).toString(), - JsonUtils.getInt("pulse", act).toString(), - JsonUtils.getString("bp", act), - JsonUtils.getFloat("height", act).toString(), - JsonUtils.getFloat("weight", act).toString(), - JsonUtils.getString("vision", act), - JsonUtils.getString("hearing", act), - JsonUtils.getLong("date", act).toString(), - JsonUtils.getBoolean("selfExamination", act).toString(), - JsonUtils.getString("planetCode", act), - JsonUtils.getBoolean("hasInfo", act).toString(), - JsonUtils.getString("profileId", act), - JsonUtils.getString("creatorId", act), - JsonUtils.getInt("age", act).toString(), - JsonUtils.getString("gender", act), - JsonUtils.getJsonObject("conditions", act).toString() - ) - healthDataList.add(csvRow) } fun writeCsv(filePath: String, data: List>) { @@ -115,7 +106,13 @@ open class RealmMyHealthPojo : RealmObject() { val file = File(filePath) file.parentFile?.mkdirs() val writer = CSVWriter(FileWriter(file)) - writer.writeNext(arrayOf("healthId", "health_rev", "data", "temperature", "pulse", "bp", "height", "weight", "vision", "hearing", "date", "selfExamination", "planetCode", "hasInfo", "profileId", "creator", "age", "gender", "conditions")) + writer.writeNext( + arrayOf( + "healthId", "health_rev", "data", "temperature", "pulse", "bp", "height", + "weight", "vision", "hearing", "date", "selfExamination", "planetCode", + "hasInfo", "profileId", "creator", "age", "gender", "conditions" + ) + ) for (row in data) { writer.writeNext(row) } @@ -129,30 +126,28 @@ open class RealmMyHealthPojo : RealmObject() { writeCsv("${context.getExternalFilesDir(null)}/ole/health.csv", healthDataList) } - @JvmStatic fun serialize(health: RealmMyHealthPojo): JsonObject { - val `object` = JsonObject() - if (!TextUtils.isEmpty(health.userId)) `object`.addProperty("_id", health.userId) - if (!TextUtils.isEmpty(health._rev)) `object`.addProperty("_rev", health._rev) - `object`.addProperty("data", health.data) - JsonUtils.addFloat(`object`, "temperature", health.temperature) - JsonUtils.addInteger(`object`, "pulse", health.pulse) - JsonUtils.addString(`object`, "bp", health.bp) - JsonUtils.addFloat(`object`, "height", health.height) - JsonUtils.addFloat(`object`, "weight", health.weight) - JsonUtils.addString(`object`, "vision", health.vision) - JsonUtils.addString(`object`, "hearing", health.hearing) - JsonUtils.addLong(`object`, "date", health.date) - `object`.addProperty("selfExamination", health.isSelfExamination) - JsonUtils.addString(`object`, "planetCode", health.planetCode) - `object`.addProperty("hasInfo", health.isHasInfo) - JsonUtils.addString(`object`, "profileId", health.profileId) - JsonUtils.addString(`object`, "creatorId", health.profileId) - JsonUtils.addString(`object`, "gender", health.gender) - `object`.addProperty("age", health.age) - JsonUtils.addJson(`object`, "conditions", Gson().fromJson(health.conditions, JsonObject::class.java) - ) - return `object` + return JsonObject().apply { + addProperty("_id", health.userId) + addProperty("_rev", health._rev) + addProperty("data", health.data) + addProperty("temperature", health.temperature) + addProperty("pulse", health.pulse) + addProperty("bp", health.bp) + addProperty("height", health.height) + addProperty("weight", health.weight) + addProperty("vision", health.vision) + addProperty("hearing", health.hearing) + addProperty("date", health.date) + addProperty("selfExamination", health.isSelfExamination) + addProperty("planetCode", health.planetCode) + addProperty("hasInfo", health.isHasInfo) + addProperty("profileId", health.profileId) + addProperty("creatorId", health.creatorId) + addProperty("gender", health.gender) + addProperty("age", health.age) + add("conditions", Gson().fromJson(health.conditions, JsonObject::class.java)) + } } } } \ No newline at end of file From ae8c36464f04ffa421ec4c4e2a9f7ab4b3f2427b Mon Sep 17 00:00:00 2001 From: Gideon Okuro Date: Fri, 6 Dec 2024 18:44:13 +0300 Subject: [PATCH 11/38] migrate realm realmStepExam and realmExamQuestion --- .../myplanet/model/RealmExamQuestion.kt | 211 +++++++++++++----- .../planet/myplanet/model/RealmStepExam.kt | 191 +++++++--------- 2 files changed, 245 insertions(+), 157 deletions(-) diff --git a/app/src/main/java/org/ole/planet/myplanet/model/RealmExamQuestion.kt b/app/src/main/java/org/ole/planet/myplanet/model/RealmExamQuestion.kt index 045bfae66a..723b4d12be 100644 --- a/app/src/main/java/org/ole/planet/myplanet/model/RealmExamQuestion.kt +++ b/app/src/main/java/org/ole/planet/myplanet/model/RealmExamQuestion.kt @@ -1,97 +1,204 @@ package org.ole.planet.myplanet.model -import android.util.Base64 -import com.google.gson.Gson +import io.realm.kotlin.ext.realmListOf +import io.realm.kotlin.types.RealmObject +import io.realm.kotlin.types.RealmList +import io.realm.kotlin.types.annotations.PrimaryKey import com.google.gson.JsonArray import com.google.gson.JsonObject -import io.realm.Realm -import io.realm.RealmList -import io.realm.RealmObject -import io.realm.RealmResults -import io.realm.annotations.PrimaryKey -import org.ole.planet.myplanet.utilities.JsonParserUtils +import io.realm.kotlin.Realm import org.ole.planet.myplanet.utilities.JsonUtils import java.util.Locale -open class RealmExamQuestion : RealmObject() { +class RealmExamQuestion : RealmObject { @PrimaryKey var id: String? = null var header: String? = null var body: String? = null var type: String? = null var examId: String? = null - private var correctChoice: RealmList? = null + var correctChoice: RealmList = realmListOf() var marks: String? = null var choices: String? = null - private fun setCorrectChoiceArray(array: JsonArray, question: RealmExamQuestion?) { + + private fun setCorrectChoiceArray(array: JsonArray) { + correctChoice.clear() for (i in 0 until array.size()) { - question?.correctChoice?.add(JsonUtils.getString(array, i).lowercase(Locale.getDefault())) + correctChoice.add(array[i].asString.lowercase(Locale.getDefault())) } } - fun getCorrectChoice(): RealmList? { - return correctChoice - } - val correctChoiceArray: JsonArray get() { val array = JsonArray() - for (s in correctChoice ?: emptyList()){ + for (s in correctChoice) { array.add(s) } return array } companion object { - @JvmStatic - fun insertExamQuestions(questions: JsonArray, examId: String?, mRealm: Realm) { - for (i in 0 until questions.size()) { - val question = questions[i].asJsonObject - val questionId = Base64.encodeToString(question.toString().toByteArray(), Base64.NO_WRAP) - var myQuestion = mRealm.where(RealmExamQuestion::class.java).equalTo("id", questionId).findFirst() - if (myQuestion == null) { - myQuestion = mRealm.createObject(RealmExamQuestion::class.java, questionId) - } - myQuestion?.examId = examId - myQuestion?.body = JsonUtils.getString("body", question) - myQuestion?.type = JsonUtils.getString("type", question) - myQuestion?.header = JsonUtils.getString("title", question) - myQuestion?.marks = JsonUtils.getString("marks", question) - myQuestion?.choices = Gson().toJson(JsonUtils.getJsonArray("choices", question)) - val isMultipleChoice = question.has("correctChoice") && JsonUtils.getString("type", question).startsWith("select") - if (isMultipleChoice) { - insertCorrectChoice(question["choices"].asJsonArray, question, myQuestion) + suspend fun insertExamQuestions(questions: JsonArray, examId: String?, realm: Realm) { + realm.write { + for (i in 0 until questions.size()) { + val question = questions[i].asJsonObject + val questionId = question.toString().hashCode().toString() // Generate a unique ID + var myQuestion = query(RealmExamQuestion::class, "id == $0", questionId).first().find() + if (myQuestion == null) { + myQuestion = RealmExamQuestion().apply { id = questionId } + copyToRealm(myQuestion) + } + myQuestion.examId = examId + myQuestion.body = question["body"]?.asString + myQuestion.type = question["type"]?.asString + myQuestion.header = question["title"]?.asString + myQuestion.marks = question["marks"]?.asString + myQuestion.choices = question["choices"]?.asJsonArray?.toString() + + val isMultipleChoice = question.has("correctChoice") && (myQuestion.type?.startsWith("select") == true) + if (isMultipleChoice) { + val choicesArray = question["correctChoice"]?.asJsonArray + if (choicesArray != null) { + insertCorrectChoice(choicesArray, question, myQuestion) + } else { + val correctChoice = question["correctChoice"]?.asString + if (correctChoice != null) { + myQuestion.correctChoice.clear() + myQuestion.correctChoice.add(correctChoice) + } + } + } } } } private fun insertCorrectChoice(array: JsonArray, question: JsonObject, myQuestion: RealmExamQuestion?) { + myQuestion?.correctChoice = realmListOf() + for (a in 0 until array.size()) { val res = array[a].asJsonObject if (question["correctChoice"].isJsonArray) { - myQuestion?.correctChoice = RealmList() - myQuestion?.setCorrectChoiceArray(JsonUtils.getJsonArray("correctChoice", question), myQuestion) - } else if (JsonUtils.getString("correctChoice", question) == JsonUtils.getString("id", res)) { - myQuestion?.correctChoice = RealmList() - myQuestion?.correctChoice?.add(JsonUtils.getString("res", res)) + myQuestion?.setCorrectChoiceArray(JsonUtils.getJsonArray("correctChoice", question)) + } else { + val correctChoice = JsonUtils.getString("correctChoice", question) + if (correctChoice == JsonUtils.getString("id", res)) { + myQuestion?.correctChoice?.add(JsonUtils.getString("res", res)) + } } } } - @JvmStatic - fun serializeQuestions(question: RealmResults): JsonArray { + fun serializeQuestions(questions: List): JsonArray { val array = JsonArray() - for (que in question) { - val `object` = JsonObject() - `object`.addProperty("header", que.header) - `object`.addProperty("body", que.body) - `object`.addProperty("type", que.type) - `object`.addProperty("marks", que.marks) - `object`.add("choices", JsonParserUtils.getStringAsJsonArray(que.choices)) - `object`.add("correctChoice", que.correctChoiceArray) - array.add(`object`) + for (question in questions) { + val jsonObject = JsonObject() + jsonObject.addProperty("header", question.header) + jsonObject.addProperty("body", question.body) + jsonObject.addProperty("type", question.type) + jsonObject.addProperty("marks", question.marks) + jsonObject.add("choices", JsonArray().apply { + question.choices?.let { add(it) } + }) + jsonObject.add("correctChoice", question.correctChoiceArray) + array.add(jsonObject) } return array } } -} \ No newline at end of file +} + +//import android.util.Base64 +//import com.google.gson.Gson +//import com.google.gson.JsonArray +//import com.google.gson.JsonObject +//import io.realm.Realm +//import io.realm.RealmList +//import io.realm.RealmObject +//import io.realm.RealmResults +//import io.realm.annotations.PrimaryKey +//import org.ole.planet.myplanet.utilities.JsonParserUtils +//import org.ole.planet.myplanet.utilities.JsonUtils +//import java.util.Locale +// +//open class RealmExamQuestion : RealmObject() { +// @PrimaryKey +// var id: String? = null +// var header: String? = null +// var body: String? = null +// var type: String? = null +// var examId: String? = null +// private var correctChoice: RealmList? = null +// var marks: String? = null +// var choices: String? = null +// private fun setCorrectChoiceArray(array: JsonArray, question: RealmExamQuestion?) { +// for (i in 0 until array.size()) { +// question?.correctChoice?.add(JsonUtils.getString(array, i).lowercase(Locale.getDefault())) +// } +// } +// +// fun getCorrectChoice(): RealmList? { +// return correctChoice +// } +// +// val correctChoiceArray: JsonArray +// get() { +// val array = JsonArray() +// for (s in correctChoice ?: emptyList()){ +// array.add(s) +// } +// return array +// } +// +// companion object { +// @JvmStatic +// fun insertExamQuestions(questions: JsonArray, examId: String?, mRealm: Realm) { +// for (i in 0 until questions.size()) { +// val question = questions[i].asJsonObject +// val questionId = Base64.encodeToString(question.toString().toByteArray(), Base64.NO_WRAP) +// var myQuestion = mRealm.where(RealmExamQuestion::class.java).equalTo("id", questionId).findFirst() +// if (myQuestion == null) { +// myQuestion = mRealm.createObject(RealmExamQuestion::class.java, questionId) +// } +// myQuestion?.examId = examId +// myQuestion?.body = JsonUtils.getString("body", question) +// myQuestion?.type = JsonUtils.getString("type", question) +// myQuestion?.header = JsonUtils.getString("title", question) +// myQuestion?.marks = JsonUtils.getString("marks", question) +// myQuestion?.choices = Gson().toJson(JsonUtils.getJsonArray("choices", question)) +// val isMultipleChoice = question.has("correctChoice") && JsonUtils.getString("type", question).startsWith("select") +// if (isMultipleChoice) { +// insertCorrectChoice(question["choices"].asJsonArray, question, myQuestion) +// } +// } +// } +// +// private fun insertCorrectChoice(array: JsonArray, question: JsonObject, myQuestion: RealmExamQuestion?) { +// for (a in 0 until array.size()) { +// val res = array[a].asJsonObject +// if (question["correctChoice"].isJsonArray) { +// myQuestion?.correctChoice = RealmList() +// myQuestion?.setCorrectChoiceArray(JsonUtils.getJsonArray("correctChoice", question), myQuestion) +// } else if (JsonUtils.getString("correctChoice", question) == JsonUtils.getString("id", res)) { +// myQuestion?.correctChoice = RealmList() +// myQuestion?.correctChoice?.add(JsonUtils.getString("res", res)) +// } +// } +// } +// +// @JvmStatic +// fun serializeQuestions(question: RealmResults): JsonArray { +// val array = JsonArray() +// for (que in question) { +// val `object` = JsonObject() +// `object`.addProperty("header", que.header) +// `object`.addProperty("body", que.body) +// `object`.addProperty("type", que.type) +// `object`.addProperty("marks", que.marks) +// `object`.add("choices", JsonParserUtils.getStringAsJsonArray(que.choices)) +// `object`.add("correctChoice", que.correctChoiceArray) +// array.add(`object`) +// } +// return array +// } +// } +//} \ No newline at end of file diff --git a/app/src/main/java/org/ole/planet/myplanet/model/RealmStepExam.kt b/app/src/main/java/org/ole/planet/myplanet/model/RealmStepExam.kt index 54bf32ae29..6f6419d91c 100644 --- a/app/src/main/java/org/ole/planet/myplanet/model/RealmStepExam.kt +++ b/app/src/main/java/org/ole/planet/myplanet/model/RealmStepExam.kt @@ -1,92 +1,83 @@ package org.ole.planet.myplanet.model -import android.text.TextUtils import com.google.gson.JsonObject import com.opencsv.CSVWriter -import io.realm.Realm -import io.realm.RealmObject -import io.realm.RealmResults -import io.realm.annotations.PrimaryKey -import org.ole.planet.myplanet.MainApplication.Companion.context -import org.ole.planet.myplanet.utilities.JsonUtils +import io.realm.kotlin.Realm +import io.realm.kotlin.types.RealmObject +import io.realm.kotlin.types.annotations.PrimaryKey +import org.ole.planet.myplanet.MainApplication import java.io.File import java.io.FileWriter import java.io.IOException -open class RealmStepExam : RealmObject() { +class RealmStepExam : RealmObject { @PrimaryKey var id: String? = null var _rev: String? = null var createdDate: Long = 0 var updatedDate: Long = 0 var createdBy: String? = null - var totalMarks = 0 + var totalMarks: Int = 0 var name: String? = null var type: String? = null var stepId: String? = null var courseId: String? = null var sourcePlanet: String? = null var passingPercentage: String? = null - var noOfQuestions = 0 - var isFromNation = false + var noOfQuestions: Int = 0 + var isFromNation: Boolean = false companion object { val examDataList: MutableList> = mutableListOf() - @JvmStatic - fun insertCourseStepsExams(myCoursesID: String?, stepId: String?, exam: JsonObject, mRealm: Realm) { - insertCourseStepsExams(myCoursesID, stepId, exam, "", mRealm) - } - - @JvmStatic - fun insertCourseStepsExams(myCoursesID: String?, stepId: String?, exam: JsonObject, parentId: String?, mRealm: Realm) { - if (!mRealm.isInTransaction) { - mRealm.beginTransaction() - } - var myExam = mRealm.where(RealmStepExam::class.java).equalTo("id", JsonUtils.getString("_id", exam)).findFirst() - if (myExam == null) { - val id = JsonUtils.getString("_id", exam) - myExam = mRealm.createObject(RealmStepExam::class.java, - if (TextUtils.isEmpty(id)) { - parentId - } else { - id + suspend fun insertCourseStepsExams(myCoursesID: String?, stepId: String?, exam: JsonObject, realm: Realm, parentId: String? = "") { + realm.write { + var myExam = this.query(RealmStepExam::class, "id == $0", exam["_id"]?.asString).first().find() + if (myExam == null) { + myExam = RealmStepExam().apply { + id = exam["_id"]?.asString ?: parentId.orEmpty() } + copyToRealm(myExam) + } + + checkIdsAndInsert(myCoursesID, stepId, myExam) + myExam.type = exam["type"]?.asString ?: "exam" + myExam.name = exam["name"]?.asString + myExam.passingPercentage = exam["passingPercentage"]?.asString + myExam._rev = exam["_rev"]?.asString + myExam.createdBy = exam["createdBy"]?.asString + myExam.sourcePlanet = exam["sourcePlanet"]?.asString + myExam.createdDate = exam["createdDate"]?.asLong ?: 0 + myExam.updatedDate = exam["updatedDate"]?.asLong ?: 0 + myExam.totalMarks = exam["totalMarks"]?.asInt ?: 0 + myExam.noOfQuestions = exam["questions"]?.asJsonArray?.size() ?: 0 + myExam.isFromNation = !parentId.isNullOrEmpty() + + val csvRow = arrayOf( + exam["_id"]?.asString.orEmpty(), + exam["_rev"]?.asString.orEmpty(), + exam["name"]?.asString.orEmpty(), + exam["passingPercentage"]?.asString.orEmpty(), + exam["type"]?.asString.orEmpty(), + exam["createdBy"]?.asString.orEmpty(), + exam["sourcePlanet"]?.asString.orEmpty(), + exam["createdDate"]?.asString.orEmpty(), + exam["updatedDate"]?.asString.orEmpty(), + exam["totalMarks"]?.asString.orEmpty(), + exam["noOfQuestions"]?.asString.orEmpty(), + myExam.isFromNation.toString() ) + examDataList.add(csvRow) } - checkIdsAndInsert(myCoursesID, stepId, myExam) - myExam?.type = if (exam.has("type")) JsonUtils.getString("type", exam) else "exam" - myExam?.name = JsonUtils.getString("name", exam) - myExam?.passingPercentage = JsonUtils.getString("passingPercentage", exam) - myExam?._rev = JsonUtils.getString("_rev", exam) - myExam?.createdBy = JsonUtils.getString("createdBy", exam) - myExam?.sourcePlanet = JsonUtils.getString("sourcePlanet", exam) - myExam?.createdDate = JsonUtils.getLong("createdDate", exam) - myExam?.updatedDate = JsonUtils.getLong("updatedDate", exam) - myExam?.totalMarks = JsonUtils.getInt("totalMarks", exam) - myExam?.noOfQuestions = JsonUtils.getJsonArray("questions", exam).size() - myExam?.isFromNation = !TextUtils.isEmpty(parentId) - val oldQuestions: RealmResults<*>? = mRealm.where(RealmExamQuestion::class.java).equalTo("examId", JsonUtils.getString("_id", exam)).findAll() - if (oldQuestions == null || oldQuestions.isEmpty()) { - RealmExamQuestion.insertExamQuestions(JsonUtils.getJsonArray("questions", exam), JsonUtils.getString("_id", exam), mRealm) - } - mRealm.commitTransaction() + } - val csvRow = arrayOf( - JsonUtils.getString("_id", exam), - JsonUtils.getString("_rev", exam), - JsonUtils.getString("name", exam), - JsonUtils.getString("passingPercentage", exam), - JsonUtils.getString("type", exam), - JsonUtils.getString("createdBy", exam), - JsonUtils.getString("sourcePlanet", exam), - JsonUtils.getString("createdDate", exam), - JsonUtils.getString("updatedDate", exam), - JsonUtils.getString("totalMarks", exam), - JsonUtils.getString("noOfQuestions", exam), - JsonUtils.getString("isFromNation", exam) - ) - examDataList.add(csvRow) + private fun checkIdsAndInsert(myCoursesID: String?, stepId: String?, myExam: RealmStepExam?) { + if (!myCoursesID.isNullOrEmpty()) { + myExam?.courseId = myCoursesID + } + if (!stepId.isNullOrEmpty()) { + myExam?.stepId = stepId + } } fun writeCsv(filePath: String, data: List>) { @@ -94,7 +85,13 @@ open class RealmStepExam : RealmObject() { val file = File(filePath) file.parentFile?.mkdirs() val writer = CSVWriter(FileWriter(file)) - writer.writeNext(arrayOf("_id", "_rev", "name", "passingPercentage", "type", "createdBy", "sourcePlanet", "createdDate", "updatedDate", "totalMarks", "noOfQuestions", "isFromNation")) + writer.writeNext( + arrayOf( + "_id", "_rev", "name", "passingPercentage", "type", "createdBy", + "sourcePlanet", "createdDate", "updatedDate", "totalMarks", + "noOfQuestions", "isFromNation" + ) + ) for (row in data) { writer.writeNext(row) } @@ -105,59 +102,43 @@ open class RealmStepExam : RealmObject() { } fun stepExamWriteCsv() { - writeCsv("${context.getExternalFilesDir(null)}/ole/stepExam.csv", examDataList) + writeCsv("${MainApplication.context.getExternalFilesDir(null)}/ole/stepExam.csv", examDataList) } - private fun checkIdsAndInsert(myCoursesID: String?, stepId: String?, myExam: RealmStepExam?) { - if (!TextUtils.isEmpty(myCoursesID)) { - myExam?.courseId = myCoursesID - } - if (!TextUtils.isEmpty(stepId)) { - myExam?.stepId = stepId - } + suspend fun getNoOfExam(realm: Realm, courseId: String?): Int { + return realm.query(RealmStepExam::class, "courseId == $0", courseId) + .count() + .find() + .toInt() } - @JvmStatic - fun getNoOfExam(mRealm: Realm, courseId: String?): Int { - val res: RealmResults<*>? = mRealm.where(RealmStepExam::class.java).equalTo("courseId", courseId).findAll() - return res?.size ?: 0 - } + fun serializeExam(realm: Realm, exam: RealmStepExam): JsonObject { + val jsonObject = JsonObject() + jsonObject.addProperty("_id", exam.id) + jsonObject.addProperty("_rev", exam._rev) + jsonObject.addProperty("name", exam.name) + jsonObject.addProperty("passingPercentage", exam.passingPercentage) + jsonObject.addProperty("type", exam.type) + jsonObject.addProperty("updatedDate", exam.updatedDate) + jsonObject.addProperty("createdDate", exam.createdDate) + jsonObject.addProperty("sourcePlanet", exam.sourcePlanet) + jsonObject.addProperty("totalMarks", exam.totalMarks) + jsonObject.addProperty("createdBy", exam.createdBy) - @JvmStatic - fun serializeExam(mRealm: Realm, exam: RealmStepExam): JsonObject { - val `object` = JsonObject() - `object`.addProperty("_id", exam.id) - `object`.addProperty("_rev", exam._rev) - `object`.addProperty("name", exam.name) - `object`.addProperty("passingPercentage", exam.passingPercentage) - `object`.addProperty("type", exam.type) - `object`.addProperty("updatedDate", exam.updatedDate) - `object`.addProperty("createdDate", exam.createdDate) - `object`.addProperty("sourcePlanet", exam.sourcePlanet) - `object`.addProperty("totalMarks", exam.createdDate) - `object`.addProperty("createdBy", exam.createdBy) - val question = mRealm.where(RealmExamQuestion::class.java).equalTo("examId", exam.id).findAll() - `object`.add("questions", RealmExamQuestion.serializeQuestions(question)) - return `object` + val questions = realm.query(RealmExamQuestion::class, "examId == $0", exam.id).find() + jsonObject.add("questions", RealmExamQuestion.serializeQuestions(questions)) + return jsonObject } - @JvmStatic fun getIds(list: List): Array { - val ids = arrayOfNulls(list.size) - for ((i, e) in list.withIndex()) { - if (e.type?.startsWith("survey") == true) { - ids[i] = e.id - } else { - ids[i] = e.id + "@" + e.courseId - } - } - return ids + return list.map { + if (it.type?.startsWith("survey") == true) it.id else "${it.id}@${it.courseId}" + }.toTypedArray() } - @JvmStatic - fun getSurveyCreationTime(surveyId: String, mRealm: Realm): Long? { - val survey = mRealm.where(RealmStepExam::class.java).equalTo("id", surveyId).findFirst() + suspend fun getSurveyCreationTime(realm: Realm, surveyId: String): Long? { + val survey = realm.query(RealmStepExam::class, "id == $0", surveyId).first().find() return survey?.createdDate } } -} +} \ No newline at end of file From 27389ba5ac9ef113d4debf7ff15009f1a2ff52f8 Mon Sep 17 00:00:00 2001 From: Gideon Okuro Date: Fri, 6 Dec 2024 18:45:16 +0300 Subject: [PATCH 12/38] delete commented code --- .../myplanet/model/RealmExamQuestion.kt | 96 ------------------- 1 file changed, 96 deletions(-) diff --git a/app/src/main/java/org/ole/planet/myplanet/model/RealmExamQuestion.kt b/app/src/main/java/org/ole/planet/myplanet/model/RealmExamQuestion.kt index 723b4d12be..01030a6766 100644 --- a/app/src/main/java/org/ole/planet/myplanet/model/RealmExamQuestion.kt +++ b/app/src/main/java/org/ole/planet/myplanet/model/RealmExamQuestion.kt @@ -106,99 +106,3 @@ class RealmExamQuestion : RealmObject { } } } - -//import android.util.Base64 -//import com.google.gson.Gson -//import com.google.gson.JsonArray -//import com.google.gson.JsonObject -//import io.realm.Realm -//import io.realm.RealmList -//import io.realm.RealmObject -//import io.realm.RealmResults -//import io.realm.annotations.PrimaryKey -//import org.ole.planet.myplanet.utilities.JsonParserUtils -//import org.ole.planet.myplanet.utilities.JsonUtils -//import java.util.Locale -// -//open class RealmExamQuestion : RealmObject() { -// @PrimaryKey -// var id: String? = null -// var header: String? = null -// var body: String? = null -// var type: String? = null -// var examId: String? = null -// private var correctChoice: RealmList? = null -// var marks: String? = null -// var choices: String? = null -// private fun setCorrectChoiceArray(array: JsonArray, question: RealmExamQuestion?) { -// for (i in 0 until array.size()) { -// question?.correctChoice?.add(JsonUtils.getString(array, i).lowercase(Locale.getDefault())) -// } -// } -// -// fun getCorrectChoice(): RealmList? { -// return correctChoice -// } -// -// val correctChoiceArray: JsonArray -// get() { -// val array = JsonArray() -// for (s in correctChoice ?: emptyList()){ -// array.add(s) -// } -// return array -// } -// -// companion object { -// @JvmStatic -// fun insertExamQuestions(questions: JsonArray, examId: String?, mRealm: Realm) { -// for (i in 0 until questions.size()) { -// val question = questions[i].asJsonObject -// val questionId = Base64.encodeToString(question.toString().toByteArray(), Base64.NO_WRAP) -// var myQuestion = mRealm.where(RealmExamQuestion::class.java).equalTo("id", questionId).findFirst() -// if (myQuestion == null) { -// myQuestion = mRealm.createObject(RealmExamQuestion::class.java, questionId) -// } -// myQuestion?.examId = examId -// myQuestion?.body = JsonUtils.getString("body", question) -// myQuestion?.type = JsonUtils.getString("type", question) -// myQuestion?.header = JsonUtils.getString("title", question) -// myQuestion?.marks = JsonUtils.getString("marks", question) -// myQuestion?.choices = Gson().toJson(JsonUtils.getJsonArray("choices", question)) -// val isMultipleChoice = question.has("correctChoice") && JsonUtils.getString("type", question).startsWith("select") -// if (isMultipleChoice) { -// insertCorrectChoice(question["choices"].asJsonArray, question, myQuestion) -// } -// } -// } -// -// private fun insertCorrectChoice(array: JsonArray, question: JsonObject, myQuestion: RealmExamQuestion?) { -// for (a in 0 until array.size()) { -// val res = array[a].asJsonObject -// if (question["correctChoice"].isJsonArray) { -// myQuestion?.correctChoice = RealmList() -// myQuestion?.setCorrectChoiceArray(JsonUtils.getJsonArray("correctChoice", question), myQuestion) -// } else if (JsonUtils.getString("correctChoice", question) == JsonUtils.getString("id", res)) { -// myQuestion?.correctChoice = RealmList() -// myQuestion?.correctChoice?.add(JsonUtils.getString("res", res)) -// } -// } -// } -// -// @JvmStatic -// fun serializeQuestions(question: RealmResults): JsonArray { -// val array = JsonArray() -// for (que in question) { -// val `object` = JsonObject() -// `object`.addProperty("header", que.header) -// `object`.addProperty("body", que.body) -// `object`.addProperty("type", que.type) -// `object`.addProperty("marks", que.marks) -// `object`.add("choices", JsonParserUtils.getStringAsJsonArray(que.choices)) -// `object`.add("correctChoice", que.correctChoiceArray) -// array.add(`object`) -// } -// return array -// } -// } -//} \ No newline at end of file From 3d6fa7f79c5fb87bc639763936acd87ae7de5d1e Mon Sep 17 00:00:00 2001 From: Gideon Okuro Date: Mon, 9 Dec 2024 18:46:06 +0300 Subject: [PATCH 13/38] migrate more classes to kotlin realm --- .../ole/planet/myplanet/model/RealmAnswer.kt | 1 + .../ole/planet/myplanet/model/RealmNews.kt | 423 ++++++++---------- .../planet/myplanet/model/RealmSubmission.kt | 326 ++++++-------- 3 files changed, 339 insertions(+), 411 deletions(-) diff --git a/app/src/main/java/org/ole/planet/myplanet/model/RealmAnswer.kt b/app/src/main/java/org/ole/planet/myplanet/model/RealmAnswer.kt index 2651fc54bb..32f29b54d5 100644 --- a/app/src/main/java/org/ole/planet/myplanet/model/RealmAnswer.kt +++ b/app/src/main/java/org/ole/planet/myplanet/model/RealmAnswer.kt @@ -1,4 +1,5 @@ package org.ole.planet.myplanet.model + import android.text.TextUtils import com.google.gson.Gson import com.google.gson.JsonArray diff --git a/app/src/main/java/org/ole/planet/myplanet/model/RealmNews.kt b/app/src/main/java/org/ole/planet/myplanet/model/RealmNews.kt index 4be46018e9..60c280c8fa 100644 --- a/app/src/main/java/org/ole/planet/myplanet/model/RealmNews.kt +++ b/app/src/main/java/org/ole/planet/myplanet/model/RealmNews.kt @@ -1,26 +1,21 @@ package org.ole.planet.myplanet.model -import android.text.TextUtils import com.google.gson.Gson import com.google.gson.JsonArray import com.google.gson.JsonObject -import com.google.gson.JsonSyntaxException import com.opencsv.CSVWriter -import io.realm.Realm -import io.realm.RealmList -import io.realm.RealmObject -import io.realm.annotations.PrimaryKey +import io.realm.kotlin.Realm +import io.realm.kotlin.types.RealmList +import io.realm.kotlin.types.RealmObject +import io.realm.kotlin.types.annotations.PrimaryKey import org.ole.planet.myplanet.MainApplication.Companion.context import org.ole.planet.myplanet.utilities.JsonUtils import java.io.File -import java.io.FileWriter import java.io.IOException -import java.util.Date -import java.util.UUID -open class RealmNews : RealmObject() { +class RealmNews : RealmObject { @PrimaryKey - var id: String? = null + var id: String = "" var _id: String? = null var _rev: String? = null var userId: String? = null @@ -52,138 +47,127 @@ open class RealmNews : RealmObject() { var newsUpdatedDate: Long = 0 var chat: Boolean = false - val imagesArray: JsonArray - get() = if (images == null) JsonArray() else Gson().fromJson(images, JsonArray::class.java) + val imagesArray: List + get() = images?.let { Gson().fromJson(it, List::class.java) as List } ?: emptyList() - val labelsArray: JsonArray - get() { - val array = JsonArray() - labels?.forEach{ s -> - array.add(s) - } - return array - } + val labelsArray: List? + get() = labels?.toList() - fun addLabel(label: String?) { - if (label != null && !labels?.contains(label)!!) { + fun addLabel(label: String) { + if (label.isNotBlank() && labels?.contains(label) == false) { labels?.add(label) } } - fun setLabels(images: JsonArray) { - labels = RealmList() - for (ob in images) { - labels?.add(ob.asString) - } + fun setLabels(labelsJson: JsonArray) { + val labelsList = labelsJson.map { it.asString } + labels?.clear() + labels?.addAll(labelsList) } - val messageWithoutMarkdown: String? - get() { - var ms = message - for (ob in imagesArray) { - ms = ms?.replace(JsonUtils.getString("markdown", ob.asJsonObject), "") - } - return ms + val messageWithoutMarkdown: String? get() { + var ms = message + imagesArray.forEach { markdown -> + ms = ms?.replace(markdown, "") } + return ms + } - val isCommunityNews: Boolean - get() { - val array = Gson().fromJson(viewIn, JsonArray::class.java) - var isCommunity = false - for (e in array) { - val `object` = e.asJsonObject - if (`object`.has("section") && `object`["section"].asString.equals("community", ignoreCase = true)) { - isCommunity = true - break - } - } - return isCommunity - } + val isCommunityNews: Boolean get() { + val viewInArray = Gson().fromJson(viewIn, List::class.java) as? List> ?: return false + return viewInArray.any { it["section"].equals("community", ignoreCase = true) } + } companion object { val newsDataList: MutableList> = mutableListOf() - @JvmStatic - fun insert(mRealm: Realm, doc: JsonObject?) { - if (!mRealm.isInTransaction) mRealm.beginTransaction() - var news = mRealm.where(RealmNews::class.java) - .equalTo("_id", JsonUtils.getString("_id", doc)) - .findFirst() - if (news == null) { - news = mRealm.createObject(RealmNews::class.java, JsonUtils.getString("_id", doc)) - } - news?._rev = JsonUtils.getString("_rev", doc) - news?._id = JsonUtils.getString("_id", doc) - news?.viewableBy = JsonUtils.getString("viewableBy", doc) - news?.docType = JsonUtils.getString("docType", doc) - news?.avatar = JsonUtils.getString("avatar", doc) - news?.updatedDate = JsonUtils.getLong("updatedDate", doc) - news?.viewableId = JsonUtils.getString("viewableId", doc) - news?.createdOn = JsonUtils.getString("createdOn", doc) - news?.messageType = JsonUtils.getString("messageType", doc) - news?.messagePlanetCode = JsonUtils.getString("messagePlanetCode", doc) - news?.replyTo = JsonUtils.getString("replyTo", doc) - news?.parentCode = JsonUtils.getString("parentCode", doc) - val user = JsonUtils.getJsonObject("user", doc) - news?.user = Gson().toJson(JsonUtils.getJsonObject("user", doc)) - news?.userId = JsonUtils.getString("_id", user) - news?.userName = JsonUtils.getString("name", user) - news?.time = JsonUtils.getLong("time", doc) - val images = JsonUtils.getJsonArray("images", doc) - val message = JsonUtils.getString("message", doc) - news?.message = message - news?.images = Gson().toJson(images) - val labels = JsonUtils.getJsonArray("labels", doc) - news?.viewIn = Gson().toJson(JsonUtils.getJsonArray("viewIn", doc)) - news?.setLabels(labels) - news?.chat = JsonUtils.getBoolean("chat", doc) + suspend fun insert(realm: Realm, doc: JsonObject?) { + realm.write { + val existingNews = query(RealmNews::class, "_id == $0", JsonUtils.getString("_id", doc)).first().find() + + val news = existingNews ?: copyToRealm(RealmNews().apply { _id = JsonUtils.getString("_id", doc) }) + + news.apply { + _rev = JsonUtils.getString("_rev", doc) + viewableBy = JsonUtils.getString("viewableBy", doc) + docType = JsonUtils.getString("docType", doc) + avatar = JsonUtils.getString("avatar", doc) + updatedDate = JsonUtils.getLong("updatedDate", doc) + viewableId = JsonUtils.getString("viewableId", doc) + createdOn = JsonUtils.getString("createdOn", doc) + messageType = JsonUtils.getString("messageType", doc) + messagePlanetCode = JsonUtils.getString("messagePlanetCode", doc) + replyTo = JsonUtils.getString("replyTo", doc) + parentCode = JsonUtils.getString("parentCode", doc) - val newsObj = JsonUtils.getJsonObject("news", doc) - news?.newsId = JsonUtils.getString("_id", newsObj) - news?.newsRev = JsonUtils.getString("_rev", newsObj) - news?.newsUser = JsonUtils.getString("user", newsObj) - news?.aiProvider = JsonUtils.getString("aiProvider", newsObj) - news?.newsTitle = JsonUtils.getString("title", newsObj) - news?.conversations = Gson().toJson(JsonUtils.getJsonArray("conversations", newsObj)) - news?.newsCreatedDate = JsonUtils.getLong("createdDate", newsObj) - news?.newsUpdatedDate = JsonUtils.getLong("updatedDate", newsObj) - mRealm.commitTransaction() + val user = JsonUtils.getJsonObject("user", doc) + this.user = Gson().toJson(user) + userId = JsonUtils.getString("_id", user) + userName = JsonUtils.getString("name", user) - val csvRow = arrayOf( - JsonUtils.getString("_id", doc), - JsonUtils.getString("_rev", doc), - JsonUtils.getString("viewableBy", doc), - JsonUtils.getString("docType", doc), - JsonUtils.getString("avatar", doc), - JsonUtils.getLong("updatedDate", doc).toString(), - JsonUtils.getString("viewableId", doc), - JsonUtils.getString("createdOn", doc), - JsonUtils.getString("messageType", doc), - JsonUtils.getString("messagePlanetCode", doc), - JsonUtils.getString("replyTo", doc), - JsonUtils.getString("parentCode", doc), - JsonUtils.getString("user", doc), - JsonUtils.getString("time", doc), - JsonUtils.getString("message", doc), - JsonUtils.getString("images", doc), - JsonUtils.getString("labels", doc), - JsonUtils.getString("viewIn", doc), - JsonUtils.getBoolean("chat", doc).toString(), - JsonUtils.getString("news", doc) - ) - newsDataList.add(csvRow) + time = JsonUtils.getLong("time", doc) + message = JsonUtils.getString("message", doc) + images = Gson().toJson(JsonUtils.getJsonArray("images", doc)) + setLabels(JsonUtils.getJsonArray("labels", doc)) + viewIn = Gson().toJson(JsonUtils.getJsonArray("viewIn", doc)) + chat = JsonUtils.getBoolean("chat", doc) + + val newsObj = JsonUtils.getJsonObject("news", doc) + newsId = JsonUtils.getString("_id", newsObj) + newsRev = JsonUtils.getString("_rev", newsObj) + newsUser = JsonUtils.getString("user", newsObj) + aiProvider = JsonUtils.getString("aiProvider", newsObj) + newsTitle = JsonUtils.getString("title", newsObj) + conversations = Gson().toJson(JsonUtils.getJsonArray("conversations", newsObj)) + newsCreatedDate = JsonUtils.getLong("createdDate", newsObj) + newsUpdatedDate = JsonUtils.getLong("updatedDate", newsObj) + } + + val csvRow = arrayOf( + JsonUtils.getString("_id", doc), + JsonUtils.getString("_rev", doc), + JsonUtils.getString("viewableBy", doc), + JsonUtils.getString("docType", doc), + JsonUtils.getString("avatar", doc), + JsonUtils.getLong("updatedDate", doc).toString(), + JsonUtils.getString("viewableId", doc), + JsonUtils.getString("createdOn", doc), + JsonUtils.getString("messageType", doc), + JsonUtils.getString("messagePlanetCode", doc), + JsonUtils.getString("replyTo", doc), + JsonUtils.getString("parentCode", doc), + JsonUtils.getString("user", doc), + JsonUtils.getString("time", doc), + JsonUtils.getString("message", doc), + JsonUtils.getString("images", doc), + JsonUtils.getString("labels", doc), + JsonUtils.getString("viewIn", doc), + JsonUtils.getBoolean("chat", doc).toString(), + JsonUtils.getString("news", doc) + ) + newsDataList.add(csvRow) + } } fun writeCsv(filePath: String, data: List>) { try { val file = File(filePath) file.parentFile?.mkdirs() - val writer = CSVWriter(FileWriter(file)) - writer.writeNext(arrayOf("_id", "_rev", "viewableBy", "docType", "avatar", "updatedDate", "viewableId", "createdOn", "messageType", "messagePlanetCode", "replyTo", "parentCode", "user", "time", "message", "images", "labels", "viewIn", "chat", "news")) - for (row in data) { - writer.writeNext(row) + file.bufferedWriter().use { writer -> + val csvWriter = CSVWriter(writer) + csvWriter.writeNext( + arrayOf( + "_id", "_rev", "viewableBy", "docType", "avatar", "updatedDate", + "viewableId", "createdOn", "messageType", "messagePlanetCode", + "replyTo", "parentCode", "user", "time", "message", + "images", "labels", "viewIn", "chat", "news" + ) + ) + for (row in data) { + csvWriter.writeNext(row) + } + csvWriter.close() } - writer.close() } catch (e: IOException) { e.printStackTrace() } @@ -193,134 +177,119 @@ open class RealmNews : RealmObject() { writeCsv("${context.getExternalFilesDir(null)}/ole/news.csv", newsDataList) } - @JvmStatic fun serializeNews(news: RealmNews): JsonObject { - val `object` = JsonObject() - `object`.addProperty("chat", news.chat) - `object`.addProperty("message", news.message) - if (news._id != null) `object`.addProperty("_id", news._id) - if (news._rev != null) `object`.addProperty("_rev", news._rev) - `object`.addProperty("time", news.time) - `object`.addProperty("createdOn", news.createdOn) - `object`.addProperty("docType", news.docType) - addViewIn(`object`, news) - `object`.addProperty("avatar", news.avatar) - `object`.addProperty("messageType", news.messageType) - `object`.addProperty("messagePlanetCode", news.messagePlanetCode) - `object`.addProperty("createdOn", news.createdOn) - `object`.addProperty("replyTo", news.replyTo) - `object`.addProperty("parentCode", news.parentCode) - `object`.add("images", news.imagesArray) - `object`.add("labels", news.labelsArray) - `object`.add("user", Gson().fromJson(news.user, JsonObject::class.java)) - val newsObject = JsonObject() - newsObject.addProperty("_id", news.newsId) - newsObject.addProperty("_rev", news.newsRev) - newsObject.addProperty("user", news.newsUser) - newsObject.addProperty("aiProvider", news.aiProvider) - newsObject.addProperty("title", news.newsTitle) - newsObject.add("conversations", Gson().fromJson(news.conversations, JsonArray::class.java)) - newsObject.addProperty("createdDate", news.newsCreatedDate) - newsObject.addProperty("updatedDate", news.newsUpdatedDate) - `object`.add("news", newsObject) - return `object` - } + val `object` = JsonObject().apply { + addProperty("chat", news.chat) + addProperty("message", news.message) + if (news._id != null) addProperty("_id", news._id) + if (news._rev != null) addProperty("_rev", news._rev) + addProperty("time", news.time) + addProperty("createdOn", news.createdOn) + addProperty("docType", news.docType) + addViewIn(this, news) + addProperty("avatar", news.avatar) + addProperty("messageType", news.messageType) + addProperty("messagePlanetCode", news.messagePlanetCode) + addProperty("createdOn", news.createdOn) + addProperty("replyTo", news.replyTo) + addProperty("parentCode", news.parentCode) + add("images", Gson().toJsonTree(news.imagesArray)) + add("labels", Gson().toJsonTree(news.labelsArray)) + add("user", Gson().fromJson(news.user, JsonObject::class.java)) - private fun addViewIn(`object`: JsonObject, news: RealmNews) { - if (!TextUtils.isEmpty(news.viewableId)) { - `object`.addProperty("viewableId", news.viewableId) - `object`.addProperty("viewableBy", news.viewableBy) - } - if (!TextUtils.isEmpty(news.viewIn)) { - val ar = Gson().fromJson(news.viewIn, JsonArray::class.java) - if (ar.size() > 0) `object`.add("viewIn", ar) + val newsObject = JsonObject().apply { + addProperty("_id", news.newsId) + addProperty("_rev", news.newsRev) + addProperty("user", news.newsUser) + addProperty("aiProvider", news.aiProvider) + addProperty("title", news.newsTitle) + add("conversations", Gson().fromJson(news.conversations, JsonArray::class.java)) + addProperty("createdDate", news.newsCreatedDate) + addProperty("updatedDate", news.newsUpdatedDate) + } + add("news", newsObject) } + return `object` } - @JvmStatic - fun createNews(map: HashMap, mRealm: Realm, user: RealmUserModel?, imageUrls: RealmList?): RealmNews { - if (!mRealm.isInTransaction) { - mRealm.beginTransaction() + private fun addViewIn(jsonObject: JsonObject, news: RealmNews) { + if (!news.viewableId.isNullOrEmpty()) { + jsonObject.addProperty("viewableId", news.viewableId) + jsonObject.addProperty("viewableBy", news.viewableBy) } - val news = mRealm.createObject(RealmNews::class.java, "${UUID.randomUUID()}") - news.message = map["message"] - news.time = Date().time - news.createdOn = user?.planetCode - news.avatar = "" - news.docType = "message" - news.userName = user?.name - news.parentCode = user?.parentCode - news.messagePlanetCode = map["messagePlanetCode"] - news.messageType = map["messageType"] - news.viewIn = getViewInJson(map) - news.chat = map["chat"]?.toBoolean() ?: false - - try { - news.updatedDate = map["updatedDate"]?.toLong() ?: 0 - } catch (e: Exception) { - e.printStackTrace() + if (!news.viewIn.isNullOrEmpty()) { + val viewInArray = Gson().fromJson(news.viewIn, JsonArray::class.java) + if (viewInArray.size() > 0) { + jsonObject.add("viewIn", viewInArray) + } } + } + + suspend fun createNews(realm: Realm, map: Map, realmUserModel: RealmUserModel?, imageUrl: RealmList?): RealmNews { + return realm.write { + val news = copyToRealm(RealmNews()) + news.apply { + message = map["message"] + time = System.currentTimeMillis() + createdOn = realmUserModel?.planetCode + avatar = "" + docType = "message" + userName = realmUserModel?.name + parentCode = realmUserModel?.parentCode + messagePlanetCode = map["messagePlanetCode"] + messageType = map["messageType"] + viewIn = getViewInJson(map) + chat = map["chat"]?.toBoolean() == true + updatedDate = map["updatedDate"]?.toLongOrNull() ?: 0 + userId = realmUserModel?.id + replyTo = map["replyTo"] ?: "" + user = Gson().toJson(realmUserModel?.serialize()) + imageUrls = imageUrl - news.userId = user?.id - news.replyTo = map["replyTo"] ?: "" - news.user = Gson().toJson(user?.serialize()) - news.imageUrls = imageUrls + map["news"]?.let { newsStr -> + val newsJson = Gson().fromJson(newsStr.replace("=", ":"), JsonObject::class.java) + newsId = JsonUtils.getString("_id", newsJson) + newsRev = JsonUtils.getString("_rev", newsJson) + newsUser = JsonUtils.getString("user", newsJson) + aiProvider = JsonUtils.getString("aiProvider", newsJson) + newsTitle = JsonUtils.getString("title", newsJson) - if (map.containsKey("news")) { - val newsObj = map["news"] - val gson = Gson() - try { - val newsJsonString = newsObj?.replace("=", ":") - val newsJson = gson.fromJson(newsJsonString, JsonObject::class.java) - news.newsId = JsonUtils.getString("_id", newsJson) - news.newsRev = JsonUtils.getString("_rev", newsJson) - news.newsUser = JsonUtils.getString("user", newsJson) - news.aiProvider = JsonUtils.getString("aiProvider", newsJson) - news.newsTitle = JsonUtils.getString("title", newsJson) - if (newsJson.has("conversations")) { - val conversationsElement = newsJson.get("conversations") - if (conversationsElement.isJsonPrimitive && conversationsElement.asJsonPrimitive.isString) { - val conversationsString = conversationsElement.asString - try { - val conversationsArray = gson.fromJson(conversationsString, JsonArray::class.java) - if (conversationsArray.size() > 0) { - val conversationsList = ArrayList>() - conversationsArray.forEach { conversationElement -> - val conversationObj = conversationElement.asJsonObject - val conversationMap = HashMap() - conversationMap["query"] = conversationObj.get("query").asString - conversationMap["response"] = conversationObj.get("response").asString - conversationsList.add(conversationMap) + newsJson.get("conversations")?.let { conversationsElement -> + if (conversationsElement.isJsonPrimitive && conversationsElement.asJsonPrimitive.isString) { + val conversationsArray = Gson().fromJson( + conversationsElement.asString, + JsonArray::class.java + ) + conversations = Gson().toJson( + conversationsArray.map { conv -> + mapOf( + "query" to conv.asJsonObject["query"].asString, + "response" to conv.asJsonObject["response"].asString + ) } - news.conversations = Gson().toJson(conversationsList) - } - } catch (e: JsonSyntaxException) { - e.printStackTrace() + ) } } + + newsCreatedDate = JsonUtils.getLong("createdDate", newsJson) + newsUpdatedDate = JsonUtils.getLong("updatedDate", newsJson) } - news.newsCreatedDate = JsonUtils.getLong("createdDate", newsJson) - news.newsUpdatedDate = JsonUtils.getLong("updatedDate", newsJson) - } catch (e: JsonSyntaxException) { - e.printStackTrace() } + news } - - mRealm.commitTransaction() - return news } - @JvmStatic - fun getViewInJson(map: HashMap): String { + fun getViewInJson(map: Map): String { val viewInArray = JsonArray() - if (!TextUtils.isEmpty(map["viewInId"])) { - val `object` = JsonObject() - `object`.addProperty("_id", map["viewInId"]) - `object`.addProperty("section", map["viewInSection"]) + map["viewInId"]?.let { id -> + val `object` = JsonObject().apply { + addProperty("_id", id) + addProperty("section", map["viewInSection"]) + } viewInArray.add(`object`) } return Gson().toJson(viewInArray) } } -} +} \ No newline at end of file diff --git a/app/src/main/java/org/ole/planet/myplanet/model/RealmSubmission.kt b/app/src/main/java/org/ole/planet/myplanet/model/RealmSubmission.kt index ba34e3b34b..90effb59f4 100644 --- a/app/src/main/java/org/ole/planet/myplanet/model/RealmSubmission.kt +++ b/app/src/main/java/org/ole/planet/myplanet/model/RealmSubmission.kt @@ -1,19 +1,17 @@ package org.ole.planet.myplanet.model -import android.content.Context -import android.text.TextUtils import com.google.gson.Gson import com.google.gson.JsonObject import com.google.gson.JsonParser import com.opencsv.CSVWriter -import io.realm.Case -import io.realm.Realm -import io.realm.RealmList -import io.realm.RealmObject -import io.realm.Sort -import io.realm.annotations.PrimaryKey -import org.ole.planet.myplanet.MainApplication.Companion.context -import org.ole.planet.myplanet.R +import io.realm.kotlin.Realm +import io.realm.kotlin.ext.query +import io.realm.kotlin.ext.realmListOf +import io.realm.kotlin.query.Sort +import io.realm.kotlin.types.RealmList +import io.realm.kotlin.types.RealmObject +import io.realm.kotlin.types.annotations.PrimaryKey +import org.ole.planet.myplanet.MainApplication import org.ole.planet.myplanet.datamanager.ApiInterface import org.ole.planet.myplanet.utilities.JsonUtils import org.ole.planet.myplanet.utilities.NetworkUtils @@ -22,10 +20,9 @@ import org.ole.planet.myplanet.utilities.Utilities import java.io.File import java.io.FileWriter import java.io.IOException -import java.util.Date -import java.util.UUID +import java.util.* -open class RealmSubmission : RealmObject() { +class RealmSubmission : RealmObject { @PrimaryKey var id: String? = null var _id: String? = null @@ -36,10 +33,10 @@ open class RealmSubmission : RealmObject() { var user: String? = null var startTime: Long = 0 var lastUpdateTime: Long = 0 - var answers: RealmList? = null + var answers: RealmList = realmListOf() var grade: Long = 0 var status: String? = null - var uploaded = false + var uploaded: Boolean = false var sender: String? = null var source: String? = null var parentCode: String? = null @@ -48,218 +45,179 @@ open class RealmSubmission : RealmObject() { companion object { private val submissionDataList: MutableList> = mutableListOf() - @JvmStatic - fun insert(mRealm: Realm, submission: JsonObject) { - if (!mRealm.isInTransaction) { - mRealm.executeTransaction { realm -> - if (submission.has("_attachments")) { - return@executeTransaction - } - val id = JsonUtils.getString("_id", submission) - var sub = realm.where(RealmSubmission::class.java).equalTo("_id", id).findFirst() - if (sub == null) { - sub = realm.createObject(RealmSubmission::class.java, id) - } - if (sub != null) { - sub._id = JsonUtils.getString("_id", submission) - sub.status = JsonUtils.getString("status", submission) - sub._rev = JsonUtils.getString("_rev", submission) - sub.grade = JsonUtils.getLong("grade", submission) - sub.type = JsonUtils.getString("type", submission) - sub.uploaded = JsonUtils.getString("status", submission) == "graded" - sub.startTime = JsonUtils.getLong("startTime", submission) - sub.lastUpdateTime = JsonUtils.getLong("lastUpdateTime", submission) - sub.parentId = JsonUtils.getString("parentId", submission) - sub.sender = JsonUtils.getString("sender", submission) - sub.source = JsonUtils.getString("source", submission) - sub.parentCode = JsonUtils.getString("parentCode", submission) - sub.parent = Gson().toJson(JsonUtils.getJsonObject("parent", submission)) - sub.user = Gson().toJson(JsonUtils.getJsonObject("user", submission)) - } - - val csvRow = arrayOf( - JsonUtils.getString("_id", submission), - JsonUtils.getString("parentId", submission), - JsonUtils.getString("type", submission), - JsonUtils.getString("status", submission), - JsonUtils.getString("grade", submission), - JsonUtils.getString("startTime", submission), - JsonUtils.getString("lastUpdateTime", submission), - JsonUtils.getString("sender", submission), - JsonUtils.getString("source", submission), - JsonUtils.getString("parentCode", submission), - JsonUtils.getString("user", submission) - ) - submissionDataList.add(csvRow) + suspend fun insert(realm: Realm, submission: JsonObject) { + if (submission.has("_attachments")) { + return + } - RealmStepExam.insertCourseStepsExams("", "", JsonUtils.getJsonObject("parent", submission), JsonUtils.getString("parentId", submission), realm) - val userId = JsonUtils.getString("_id", JsonUtils.getJsonObject("user", submission)) - if (userId.contains("@")) { - val us = userId.split("@".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() - if (us[0].startsWith("org.couchdb.user:")) { - if (sub != null) { - sub.userId = us[0] - } - } else { - if (sub != null) { - sub.userId = "org.couchdb.user:" + us[0] - } - } + val id = JsonUtils.getString("_id", submission) + var parent: JsonObject? = null + var parentId: String? = null + + realm.write { + val existingSubmission = query("_id == $0", id).first().find() + val sub = existingSubmission ?: copyToRealm(RealmSubmission().apply { _id = id }) + + sub._id = JsonUtils.getString("_id", submission) + sub.status = JsonUtils.getString("status", submission) + sub._rev = JsonUtils.getString("_rev", submission) + sub.grade = JsonUtils.getLong("grade", submission) + sub.type = JsonUtils.getString("type", submission) + sub.uploaded = JsonUtils.getString("status", submission) == "graded" + sub.startTime = JsonUtils.getLong("startTime", submission) + sub.lastUpdateTime = JsonUtils.getLong("lastUpdateTime", submission) + sub.parentId = JsonUtils.getString("parentId", submission) + sub.sender = JsonUtils.getString("sender", submission) + sub.source = JsonUtils.getString("source", submission) + sub.parentCode = JsonUtils.getString("parentCode", submission) + sub.parent = Gson().toJson(JsonUtils.getJsonObject("parent", submission)) + sub.user = Gson().toJson(JsonUtils.getJsonObject("user", submission)) + + parent = JsonUtils.getJsonObject("parent", submission) + parentId = JsonUtils.getString("parentId", submission) + + val csvRow = arrayOf( + JsonUtils.getString("_id", submission), + JsonUtils.getString("parentId", submission), + JsonUtils.getString("type", submission), + JsonUtils.getString("status", submission), + JsonUtils.getString("grade", submission), + JsonUtils.getString("startTime", submission), + JsonUtils.getString("lastUpdateTime", submission), + JsonUtils.getString("sender", submission), + JsonUtils.getString("source", submission), + JsonUtils.getString("parentCode", submission), + JsonUtils.getString("user", submission) + ) + submissionDataList.add(csvRow) + + val userId = JsonUtils.getString("_id", JsonUtils.getJsonObject("user", submission)) + sub.userId = if (userId.contains("@")) { + val us = userId.split("@".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() + if (us[0].startsWith("org.couchdb.user:")) { + us[0] } else { - if (sub != null) { - sub.userId = userId - } + "org.couchdb.user:${us[0]}" } + } else { + userId } } + + if (parent != null && parentId != null) { + RealmStepExam.insertCourseStepsExams("", "", parent, realm, parentId) + } } fun writeCsv(filePath: String, data: List>) { try { val file = File(filePath) file.parentFile?.mkdirs() - val writer = CSVWriter(FileWriter(file)) - writer.writeNext(arrayOf("_id", "parentId", "type", "status", "grade", "startTime", "lastUpdateTime", "sender", "source", "parentCode", "user")) - for (row in data) { - writer.writeNext(row) + CSVWriter(FileWriter(file)).use { writer -> + writer.writeNext(arrayOf("_id", "parentId", "type", "status", "grade", + "startTime", "lastUpdateTime", "sender", "source", "parentCode", "user") + ) + data.forEach { writer.writeNext(it) } } - writer.close() } catch (e: IOException) { e.printStackTrace() } } fun submissionWriteCsv() { - writeCsv("${context.getExternalFilesDir(null)}/ole/submission.csv", submissionDataList) + val filePath = "${MainApplication.context.getExternalFilesDir(null)}/ole/submission.csv" + writeCsv(filePath, submissionDataList) } - private fun serializeExamResult(mRealm: Realm, sub: RealmSubmission, context: Context): JsonObject { - val `object` = JsonObject() - val user = mRealm.where(RealmUserModel::class.java).equalTo("id", sub.userId).findFirst() - var examId = sub.parentId - if (sub.parentId?.contains("@") == true) { - examId = sub.parentId!!.split("@".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()[0] - } - val exam = mRealm.where(RealmStepExam::class.java).equalTo("id", examId).findFirst() - if (!TextUtils.isEmpty(sub._id)) { - `object`.addProperty("_id", sub._id) - } - if (!TextUtils.isEmpty(sub._rev)) { - `object`.addProperty("_rev", sub._rev) + private fun serializeExamResult(realm: Realm, sub: RealmSubmission): JsonObject { + val jsonObject = JsonObject() + val user = realm.query("id == $0", sub.userId).first().find() + val parentId = sub.parentId + val examId = if (parentId?.contains("@") == true) parentId.split("@")[0] else parentId + val exam = realm.query("id == $0", examId).first().find() + + jsonObject.addProperty("_id", sub._id) + jsonObject.addProperty("_rev", sub._rev) + jsonObject.addProperty("parentId", sub.parentId) + jsonObject.addProperty("type", sub.type) + jsonObject.addProperty("grade", sub.grade) + jsonObject.addProperty("startTime", sub.startTime) + jsonObject.addProperty("lastUpdateTime", sub.lastUpdateTime) + jsonObject.addProperty("status", sub.status) + jsonObject.addProperty("androidId", NetworkUtils.getUniqueIdentifier()) + jsonObject.addProperty("deviceName", NetworkUtils.getDeviceName()) + jsonObject.addProperty("customDeviceName", NetworkUtils.getCustomDeviceName(MainApplication.context)) + jsonObject.addProperty("sender", sub.sender) + jsonObject.addProperty("source", sub.source) + jsonObject.addProperty("parentCode", sub.parentCode) + jsonObject.add("parent", sub.parent?.let { Gson().fromJson(it, JsonObject::class.java) }) + jsonObject.add("answers", RealmAnswer.serializeRealmAnswer(sub.answers)) + + if (exam != null && sub.parent.isNullOrEmpty()) { + jsonObject.add("parent", RealmStepExam.serializeExam(realm, exam)) } - `object`.addProperty("parentId", sub.parentId) - `object`.addProperty("type", sub.type) - `object`.addProperty("grade", sub.grade) - `object`.addProperty("startTime", sub.startTime) - `object`.addProperty("lastUpdateTime", sub.lastUpdateTime) - `object`.addProperty("status", sub.status) - `object`.addProperty("androidId", NetworkUtils.getUniqueIdentifier()) - `object`.addProperty("deviceName", NetworkUtils.getDeviceName()) - `object`.addProperty("customDeviceName", NetworkUtils.getCustomDeviceName(context)) - `object`.addProperty("sender", sub.sender) - `object`.addProperty("source", sub.source) - `object`.addProperty("parentCode", sub.parentCode) - val parent = Gson().fromJson(sub.parent, JsonObject::class.java) - `object`.add("parent", parent) - `object`.add("answers", RealmAnswer.serializeRealmAnswer(sub.answers!!)) - if (exam != null && parent == null) `object`.add("parent", RealmStepExam.serializeExam(mRealm, exam)) - if (TextUtils.isEmpty(sub.user)) { - `object`.add("user", user?.serialize()) + + if (sub.user.isNullOrEmpty()) { + jsonObject.add("user", user?.serialize()) } else { - `object`.add("user", JsonParser.parseString(sub.user)) + jsonObject.add("user", JsonParser.parseString(sub.user)) } - return `object` - } - @JvmStatic - fun isStepCompleted(realm: Realm, id: String?, userId: String?): Boolean { - val exam = realm.where(RealmStepExam::class.java).equalTo("stepId", id).findFirst() ?: return true - return exam.id?.let { - realm.where(RealmSubmission::class.java).equalTo("userId", userId) - .contains("parentId", it).notEqualTo("status", "pending").findFirst() - } != null + return jsonObject } - @JvmStatic - fun createSubmission(sub: RealmSubmission?, mRealm: Realm): RealmSubmission { - var submission = sub - if (submission == null || submission.status == "complete" && (submission.type == "exam" || submission.type == "survey")) - submission = mRealm.createObject(RealmSubmission::class.java, UUID.randomUUID().toString()) - submission!!.lastUpdateTime = Date().time - return submission + fun isStepCompleted(realm: Realm, id: String?, userId: String?): Boolean { + val stepExam = realm.query("stepId == $0", id).first().find() ?: return true + return realm.query("userId == $0 AND parentId == $1 AND status != 'pending'", userId, stepExam.id).first().find() != null } - @JvmStatic - @Throws(IOException::class) - fun continueResultUpload(sub: RealmSubmission, apiInterface: ApiInterface?, realm: Realm, context: Context) { - if (!TextUtils.isEmpty(sub.userId) && sub.userId?.startsWith("guest") == true) return - val `object`: JsonObject? = if (TextUtils.isEmpty(sub._id)) { - apiInterface?.postDoc(Utilities.header, "application/json", Utilities.getUrl() + "/submissions", serializeExamResult(realm, sub, context))?.execute()?.body() - } else { - apiInterface?.putDoc(Utilities.header, "application/json", Utilities.getUrl() + "/submissions/" + sub._id, serializeExamResult(realm, sub, context))?.execute()?.body() - } - if (`object` != null) { - sub._id = JsonUtils.getString("id", `object`) - sub._rev = JsonUtils.getString("rev", `object`) + suspend fun createSubmission(sub: RealmSubmission?, realm: Realm): RealmSubmission { + return realm.write { + val newSub = sub ?: RealmSubmission().apply { id = UUID.randomUUID().toString() } + findLatest(newSub) ?: copyToRealm(newSub) } } - @JvmStatic - fun getNoOfSubmissionByUser(id: String?, userId: String?, mRealm: Realm): String { - if (id == null || userId == null) return "No Submissions Found" + suspend fun continueResultUpload(sub: RealmSubmission, apiInterface: ApiInterface?, realm: Realm) { + if (sub.userId.isNullOrEmpty() || sub.userId?.startsWith("guest") == true) return - val submissionCount = mRealm.where(RealmSubmission::class.java) - .equalTo("parentId", id) - .equalTo("userId", userId) - .equalTo("status", "complete") - .count().toInt() + val serializedResult = serializeExamResult(realm, sub) + val response: JsonObject? = if (sub._id.isNullOrEmpty()) { + apiInterface?.postDoc(Utilities.header, "application/json", "${Utilities.getUrl()}/submissions", serializedResult)?.execute()?.body() + } else { + apiInterface?.putDoc(Utilities.header, "application/json", "${Utilities.getUrl()}/submissions/${sub._id}", serializedResult)?.execute()?.body() + } - val pluralizedString = if (submissionCount == 1) "time" else "times" - return context.getString(R.string.survey_taken) + " " + submissionCount + " " + pluralizedString + if (response != null) { + realm.write { + findLatest(sub)?.apply { + _id = JsonUtils.getString("id", response) + _rev = JsonUtils.getString("rev", response) + } + } + } } - @JvmStatic - fun getNoOfSurveySubmissionByUser(userId: String?, mRealm: Realm): Int { - if (userId == null) return 0 - - return mRealm.where(RealmSubmission::class.java) - .equalTo("userId", userId) - .equalTo("type", "survey") - .equalTo("status", "pending", Case.INSENSITIVE) - .count().toInt() + fun getNoOfSubmissionByUser(realm: Realm, id: String?, userId: String?): Int { + return if (id == null || userId == null) 0 else realm.query("parentId == $0 AND userId == $1 AND status == 'complete'", id, userId).count().find().toInt() } - @JvmStatic - fun getRecentSubmissionDate(id: String?, userId: String?, mRealm: Realm): String { - if (id == null || userId == null) return "" - - val recentSubmission = mRealm.where(RealmSubmission::class.java) - .equalTo("parentId", id) - .equalTo("userId", userId) - .sort("startTime", Sort.DESCENDING) - .findFirst() - - return recentSubmission?.startTime?.let { TimeUtils.getFormatedDateWithTime(it) } ?: "" + fun getRecentSubmissionDate(realm: Realm, id: String?, userId: String?): String { + val submission = realm.query("parentId == $0 AND userId == $1", id, userId).sort("startTime", Sort.DESCENDING).first().find() + return submission?.startTime?.let { TimeUtils.getFormatedDateWithTime(it) } ?: "" } - @JvmStatic - fun getExamMap(mRealm: Realm, submissions: List?): HashMap { - val exams = HashMap() - for (sub in submissions ?: emptyList()){ - var id = sub.parentId - if (checkParentId(sub.parentId)) { - id = sub.parentId!!.split("@".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()[0] - } - val survey = mRealm.where(RealmStepExam::class.java).equalTo("id", id).findFirst() - if (survey != null) { - exams[sub.parentId] = survey - } + fun getExamMap(realm: Realm, submissions: List): Map { + return submissions.associate { submission -> + val parentId = submission.parentId + val examId = if (checkParentId(parentId)) parentId?.split("@")?.firstOrNull() else parentId + val exam = realm.query("id == $0", examId).first().find() + submission.parentId to exam } - return exams } private fun checkParentId(parentId: String?): Boolean { - return parentId != null && parentId.contains("@") + return parentId?.contains("@") == true } } } From 443631ad2cb673261da24129b2b5ad097fa0e82c Mon Sep 17 00:00:00 2001 From: Gideon Okuro Date: Tue, 10 Dec 2024 20:52:59 +0300 Subject: [PATCH 14/38] migrate realmMyTeam --- .../ole/planet/myplanet/model/RealmMyTeam.kt | 638 ++++++++---------- 1 file changed, 288 insertions(+), 350 deletions(-) diff --git a/app/src/main/java/org/ole/planet/myplanet/model/RealmMyTeam.kt b/app/src/main/java/org/ole/planet/myplanet/model/RealmMyTeam.kt index b11de626d1..25f3ab893e 100644 --- a/app/src/main/java/org/ole/planet/myplanet/model/RealmMyTeam.kt +++ b/app/src/main/java/org/ole/planet/myplanet/model/RealmMyTeam.kt @@ -5,11 +5,12 @@ import com.google.gson.Gson import com.google.gson.JsonObject import com.google.gson.JsonParser import com.opencsv.CSVWriter -import io.realm.Realm -import io.realm.RealmList -import io.realm.RealmObject -import io.realm.RealmResults -import io.realm.annotations.PrimaryKey +import io.realm.kotlin.Realm +import io.realm.kotlin.ext.query +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 org.ole.planet.myplanet.MainApplication.Companion.context import org.ole.planet.myplanet.utilities.AndroidDecrypter import org.ole.planet.myplanet.utilities.DownloadUtils.extractLinks @@ -21,42 +22,43 @@ import java.io.FileWriter import java.io.IOException import java.util.Date -open class RealmMyTeam : RealmObject() { +//import org.ole.planet.myplanet.utilities.JsonUtils +class RealmMyTeam : RealmObject { @PrimaryKey - var _id: String? = null - var _rev: String? = null - var courses: RealmList? = null - var teamId: String? = null - var name: String? = null - var userId: String? = null - var description: String? = null - var requests: String? = null - var sourcePlanet: String? = null - var limit = 0 + var _id: String = "" + var _rev: String = "" + var courses: RealmList = realmListOf() + var teamId: String = "" + var name: String = "" + var userId: String = "" + var description: String = "" + var requests: String = "" + var sourcePlanet: String = "" + var limit: Int = 0 var createdDate: Long = 0 - var resourceId: String? = null - var status: String? = null - var teamType: String? = null - var teamPlanetCode: String? = null - var userPlanetCode: String? = null - var parentCode: String? = null - var docType: String? = null - var title: String? = null - var route: String? = null - var services: String? = null - var createdBy: String? = null - var rules: String? = null - var isLeader = false - var type: String? = null - var amount = 0 + var resourceId: String = "" + var status: String = "" + var teamType: String = "" + var teamPlanetCode: String = "" + var userPlanetCode: String = "" + var parentCode: String = "" + var docType: String = "" + var title: String = "" + var route: String = "" + var services: String = "" + var createdBy: String = "" + var rules: String = "" + var isLeader: Boolean = false + var type: String = "" + var amount: Int = 0 var date: Long = 0 - var isPublic = false - var updated = false - var beginningBalance = 0 - var sales = 0 - var otherIncome = 0 - var wages = 0 - var otherExpenses = 0 + var isPublic: Boolean = false + var updated: Boolean = false + var beginningBalance: Int = 0 + var sales: Int = 0 + var otherIncome: Int = 0 + var wages: Int = 0 + var otherExpenses: Int = 0 var startDate: Long = 0 var endDate: Long = 0 var updatedDate: Long = 0 @@ -66,112 +68,122 @@ open class RealmMyTeam : RealmObject() { val reportsDataList: MutableList> = mutableListOf() private val concatenatedLinks = ArrayList() - @JvmStatic - fun insertMyTeams(doc: JsonObject, mRealm: Realm) { - val teamId = JsonUtils.getString("_id", doc) - var myTeams = mRealm.where(RealmMyTeam::class.java).equalTo("_id", teamId).findFirst() - if (myTeams == null) { - myTeams = mRealm.createObject(RealmMyTeam::class.java, teamId) - } - if (myTeams != null) { - myTeams.userId = JsonUtils.getString("userId", doc) - myTeams.teamId = JsonUtils.getString("teamId", doc) - myTeams._rev = JsonUtils.getString("_rev", doc) - myTeams.name = JsonUtils.getString("name", doc) - myTeams.sourcePlanet = JsonUtils.getString("sourcePlanet", doc) - myTeams.title = JsonUtils.getString("title", doc) - myTeams.description = JsonUtils.getString("description", doc) - val links = extractLinks(JsonUtils.getString("description", doc)) - val baseUrl = getUrl() - for (link in links) { - val concatenatedLink = "$baseUrl/$link" - concatenatedLinks.add(concatenatedLink) - } - openDownloadService(context, concatenatedLinks, true) - myTeams.limit = JsonUtils.getInt("limit", doc) - myTeams.status = JsonUtils.getString("status", doc) - myTeams.teamPlanetCode = JsonUtils.getString("teamPlanetCode", doc) - myTeams.createdDate = JsonUtils.getLong("createdDate", doc) - myTeams.resourceId = JsonUtils.getString("resourceId", doc) - myTeams.teamType = JsonUtils.getString("teamType", doc) - myTeams.route = JsonUtils.getString("route", doc) - myTeams.type = JsonUtils.getString("type", doc) - myTeams.services = JsonUtils.getString("services", doc) - myTeams.rules = JsonUtils.getString("rules", doc) - myTeams.parentCode = JsonUtils.getString("parentCode", doc) - myTeams.createdBy = JsonUtils.getString("createdBy", doc) - myTeams.userPlanetCode = JsonUtils.getString("userPlanetCode", doc) - myTeams.isLeader = JsonUtils.getBoolean("isLeader", doc) - myTeams.amount = JsonUtils.getInt("amount", doc) - myTeams.date = JsonUtils.getLong("date", doc) - myTeams.docType = JsonUtils.getString("docType", doc) - myTeams.isPublic = JsonUtils.getBoolean("public", doc) - myTeams.beginningBalance = JsonUtils.getInt("beginningBalance", doc) - myTeams.sales = JsonUtils.getInt("sales", doc) - myTeams.otherIncome = JsonUtils.getInt("otherIncome", doc) - myTeams.wages = JsonUtils.getInt("wages", doc) - myTeams.otherExpenses = JsonUtils.getInt("otherExpenses", doc) - myTeams.startDate = JsonUtils.getLong("startDate", doc) - myTeams.endDate = JsonUtils.getLong("endDate", doc) - myTeams.updatedDate = JsonUtils.getLong("updatedDate", doc) - val coursesArray = JsonUtils.getJsonArray("courses", doc) - myTeams.courses = RealmList() - for (e in coursesArray) { - val id = e.asJsonObject["_id"].asString - if (!myTeams.courses?.contains(id)!!) { - myTeams.courses?.add(id) + fun insertMyTeams(doc: JsonObject, realm: Realm) { + val teamID = JsonUtils.getString("_id", doc) + realm.writeBlocking { + val myTeams = query("_id == $0", teamID).first().find() + ?: RealmMyTeam().apply { this._id = teamID } + + myTeams.apply { + userId = JsonUtils.getString("userId", doc) + teamId = JsonUtils.getString("teamId", doc) + _rev = JsonUtils.getString("_rev", doc) + name = JsonUtils.getString("name", doc) + sourcePlanet = JsonUtils.getString("sourcePlanet", doc) + title = JsonUtils.getString("title", doc) + description = JsonUtils.getString("description", doc) + + val links = extractLinks(JsonUtils.getString("description", doc)) + val baseUrl = getUrl() + concatenatedLinks.clear() + concatenatedLinks.addAll(links.map { "$baseUrl/$it" }) + openDownloadService(context, concatenatedLinks, true) + + limit = JsonUtils.getInt("limit", doc) + status = JsonUtils.getString("status", doc) + teamPlanetCode = JsonUtils.getString("teamPlanetCode", doc) + createdDate = JsonUtils.getLong("createdDate", doc) + resourceId = JsonUtils.getString("resourceId", doc) + teamType = JsonUtils.getString("teamType", doc) + route = JsonUtils.getString("route", doc) + type = JsonUtils.getString("type", doc) + services = JsonUtils.getString("services", doc) + rules = JsonUtils.getString("rules", doc) + parentCode = JsonUtils.getString("parentCode", doc) + createdBy = JsonUtils.getString("createdBy", doc) + userPlanetCode = JsonUtils.getString("userPlanetCode", doc) + isLeader = JsonUtils.getBoolean("isLeader", doc) + amount = JsonUtils.getInt("amount", doc) + date = JsonUtils.getLong("date", doc) + docType = JsonUtils.getString("docType", doc) + isPublic = JsonUtils.getBoolean("public", doc) + beginningBalance = JsonUtils.getInt("beginningBalance", doc) + sales = JsonUtils.getInt("sales", doc) + otherIncome = JsonUtils.getInt("otherIncome", doc) + wages = JsonUtils.getInt("wages", doc) + otherExpenses = JsonUtils.getInt("otherExpenses", doc) + startDate = JsonUtils.getLong("startDate", doc) + endDate = JsonUtils.getLong("endDate", doc) + updatedDate = JsonUtils.getLong("updatedDate", doc) + + val coursesArray = JsonUtils.getJsonArray("courses", doc) + courses.clear() + coursesArray.forEach { element -> + val id = element.asJsonObject["_id"].asString + if (!courses.contains(id)) { + courses.add(id) + } } } + + val csvRow = arrayOf( + JsonUtils.getString("userId", doc), + JsonUtils.getString("teamId", doc), + JsonUtils.getString("_rev", doc), + JsonUtils.getString("name", doc), + JsonUtils.getString("sourcePlanet", doc), + JsonUtils.getString("title", doc), + JsonUtils.getString("description", doc), + JsonUtils.getInt("limit", doc).toString(), + JsonUtils.getString("status", doc), + JsonUtils.getString("teamPlanetCode", doc), + JsonUtils.getLong("createdDate", doc).toString(), + JsonUtils.getString("resourceId", doc), + JsonUtils.getString("teamType", doc), + JsonUtils.getString("route", doc), + JsonUtils.getString("type", doc), + JsonUtils.getString("services", doc), + JsonUtils.getString("rules", doc), + JsonUtils.getString("parentCode", doc), + JsonUtils.getString("createdBy", doc), + JsonUtils.getString("userPlanetCode", doc), + JsonUtils.getBoolean("isLeader", doc).toString(), + JsonUtils.getInt("amount", doc).toString(), + JsonUtils.getLong("date", doc).toString(), + JsonUtils.getString("docType", doc), + JsonUtils.getBoolean("public", doc).toString(), + JsonUtils.getInt("beginningBalance", doc).toString(), + JsonUtils.getInt("sales", doc).toString(), + JsonUtils.getInt("otherIncome", doc).toString(), + JsonUtils.getInt("wages", doc).toString(), + JsonUtils.getInt("otherExpenses", doc).toString(), + JsonUtils.getLong("startDate", doc).toString(), + JsonUtils.getLong("endDate", doc).toString(), + JsonUtils.getLong("updatedDate", doc).toString(), + JsonUtils.getJsonArray("courses", doc).toString() + ) + teamDataList.add(csvRow) } - val csvRow = arrayOf( - JsonUtils.getString("userId", doc), - JsonUtils.getString("teamId", doc), - JsonUtils.getString("_rev", doc), - JsonUtils.getString("name", doc), - JsonUtils.getString("sourcePlanet", doc), - JsonUtils.getString("title", doc), - JsonUtils.getString("description", doc), - JsonUtils.getInt("limit", doc).toString(), - JsonUtils.getString("status", doc), - JsonUtils.getString("teamPlanetCode", doc), - JsonUtils.getLong("createdDate", doc).toString(), - JsonUtils.getString("resourceId", doc), - JsonUtils.getString("teamType", doc), - JsonUtils.getString("route", doc), - JsonUtils.getString("type", doc), - JsonUtils.getString("services", doc), - JsonUtils.getString("rules", doc), - JsonUtils.getString("parentCode", doc), - JsonUtils.getString("createdBy", doc), - JsonUtils.getString("userPlanetCode", doc), - JsonUtils.getBoolean("isLeader", doc).toString(), - JsonUtils.getInt("amount", doc).toString(), - JsonUtils.getLong("date", doc).toString(), - JsonUtils.getString("docType", doc), - JsonUtils.getBoolean("public", doc).toString(), - JsonUtils.getInt("beginningBalance", doc).toString(), - JsonUtils.getInt("sales", doc).toString(), - JsonUtils.getInt("otherIncome", doc).toString(), - JsonUtils.getInt("wages", doc).toString(), - JsonUtils.getInt("otherExpenses", doc).toString(), - JsonUtils.getLong("startDate", doc).toString(), - JsonUtils.getLong("endDate", doc).toString(), - JsonUtils.getLong("updatedDate", doc).toString(), - JsonUtils.getJsonArray("courses", doc).toString() - ) - teamDataList.add(csvRow) } fun writeCsv(filePath: String, data: List>) { try { val file = File(filePath) file.parentFile?.mkdirs() - val writer = CSVWriter(FileWriter(file)) - writer.writeNext(arrayOf("userId", "teamId", "teamId_rev", "name", "sourcePlanet", "title", "description", "limit", "status", "teamPlanetCode", "createdDate", "resourceId", "teamType", "route", "type", "services", "rules", "parentCode", "createdBy", "userPlanetCode", "isLeader", "amount", "date", "docType", "public", "beginningBalance", "sales", "otherIncome", "wages", "otherExpenses", "startDate", "endDate", "updatedDate", "courses")) - for (row in data) { - writer.writeNext(row) + CSVWriter(FileWriter(file)).use { writer -> + writer.writeNext( + arrayOf("userId", "teamId", "teamId_rev", "name", "sourcePlanet", "title", + "description", "limit", "status", "teamPlanetCode", "createdDate", + "resourceId", "teamType", "route", "type", "services", "rules", "parentCode", + "createdBy", "userPlanetCode", "isLeader", "amount", "date", "docType", + "public", "beginningBalance", "sales", "otherIncome", "wages", + "otherExpenses", "startDate", "endDate", "updatedDate", "courses" + ) + ) + for (row in data) { + writer.writeNext(row) + } } - writer.close() } catch (e: IOException) { e.printStackTrace() } @@ -181,34 +193,30 @@ open class RealmMyTeam : RealmObject() { writeCsv("${context.getExternalFilesDir(null)}/ole/team.csv", teamDataList) } - @JvmStatic - fun insertReports(doc: JsonObject, mRealm: Realm) { - if (!mRealm.isInTransaction) { - mRealm.beginTransaction() - } - val teamId = JsonUtils.getString("_id", doc) - var myTeams = mRealm.where(RealmMyTeam::class.java).equalTo("_id", teamId).findFirst() - if (myTeams == null) { - myTeams = mRealm.createObject(RealmMyTeam::class.java, teamId) - } - if (myTeams != null) { - myTeams.teamId = JsonUtils.getString("teamId", doc) - myTeams.description = JsonUtils.getString("description", doc) - myTeams.teamPlanetCode = JsonUtils.getString("teamPlanetCode", doc) - myTeams.createdDate = JsonUtils.getLong("createdDate", doc) - myTeams.teamType = JsonUtils.getString("teamType", doc) - myTeams.docType = JsonUtils.getString("docType", doc) - myTeams.beginningBalance = JsonUtils.getInt("beginningBalance", doc) - myTeams.sales = JsonUtils.getInt("sales", doc) - myTeams.otherIncome = JsonUtils.getInt("otherIncome", doc) - myTeams.wages = JsonUtils.getInt("wages", doc) - myTeams.otherExpenses = JsonUtils.getInt("otherExpenses", doc) - myTeams.startDate = JsonUtils.getLong("startDate", doc) - myTeams.endDate = JsonUtils.getLong("endDate", doc) - myTeams.updatedDate = JsonUtils.getLong("updatedDate", doc) - myTeams.updated = JsonUtils.getBoolean("updated", doc) + fun insertReports(doc: JsonObject, realm: Realm) { + realm.writeBlocking { + val teamId = JsonUtils.getString("_id", doc) + val myTeams = query("_id == $0", teamId).first().find() + ?: RealmMyTeam().apply { this._id = teamId } + + myTeams.apply { + this.teamId = JsonUtils.getString("teamId", doc) + description = JsonUtils.getString("description", doc) + teamPlanetCode = JsonUtils.getString("teamPlanetCode", doc) + createdDate = JsonUtils.getLong("createdDate", doc) + teamType = JsonUtils.getString("teamType", doc) + docType = JsonUtils.getString("docType", doc) + beginningBalance = JsonUtils.getInt("beginningBalance", doc) + sales = JsonUtils.getInt("sales", doc) + otherIncome = JsonUtils.getInt("otherIncome", doc) + wages = JsonUtils.getInt("wages", doc) + otherExpenses = JsonUtils.getInt("otherExpenses", doc) + startDate = JsonUtils.getLong("startDate", doc) + endDate = JsonUtils.getLong("endDate", doc) + updatedDate = JsonUtils.getLong("updatedDate", doc) + updated = JsonUtils.getBoolean("updated", doc) + } } - mRealm.commitTransaction() val csvRow = arrayOf( JsonUtils.getString("teamId", doc), @@ -230,11 +238,10 @@ open class RealmMyTeam : RealmObject() { reportsDataList.add(csvRow) } - @JvmStatic - fun updateReports(doc: JsonObject, mRealm: Realm) { - mRealm.executeTransactionAsync { realm -> + fun updateReports(doc: JsonObject, realm: Realm) { + realm.writeBlocking { val reportId = JsonUtils.getString("_id", doc) - val report = realm.where(RealmMyTeam::class.java).equalTo("_id", reportId).findFirst() + val report = query("_id == $0", reportId).first().find() report?.apply { description = JsonUtils.getString("description", doc) beginningBalance = JsonUtils.getInt("beginningBalance", doc) @@ -250,236 +257,167 @@ open class RealmMyTeam : RealmObject() { } } - @JvmStatic fun deleteReport(reportId: String, realm: Realm) { - realm.executeTransactionAsync { transactionRealm -> - val report = transactionRealm.where(RealmMyTeam::class.java).equalTo("_id", reportId).findFirst() - report?.deleteFromRealm() + realm.writeBlocking { + query("_id == $0", reportId).first().find()?.let { delete(it) } } } - @JvmStatic - fun getResourceIds(teamId: String?, realm: Realm): MutableList { - val teams = realm.where(RealmMyTeam::class.java).equalTo("teamId", teamId).findAll() - val ids = mutableListOf() - for (team in teams) { - if (!team.resourceId.isNullOrBlank()) { - ids.add(team.resourceId!!) - } - } - return ids + fun getResourceIds(teamId: String, realm: Realm): List { + return realm.query("teamId == $0", teamId).find().map { + it.resourceId + }.filter { it.isNotBlank() } } - @JvmStatic - fun getResourceIdsByUser(userId: String?, realm: Realm): MutableList { - val list = realm.where(RealmMyTeam::class.java) - .equalTo("userId", userId) - .equalTo("docType", "membership") - .findAll() - val teamIds = mutableListOf() - for (team in list) { - if (!team.teamId.isNullOrBlank()) { - teamIds.add(team.teamId!!) - } - } - val l2 = realm.where(RealmMyTeam::class.java) - .`in`("teamId", teamIds.toTypedArray()) - .equalTo("docType", "resourceLink") - .findAll() - val ids = mutableListOf() - for (team in l2) { - if (!team.resourceId.isNullOrBlank()) { - ids.add(team.resourceId!!) - } - } - return ids + fun getResourceIdsByUser(userId: String, realm: Realm): List { + val teamIds = realm.query("userId == $0 AND docType == 'membership'", userId).find().map { it.teamId } + + return realm.query("teamId IN $0 AND docType == 'resourceLink'", teamIds).find().map { + it.resourceId + }.filter { it.isNotBlank() } } - @JvmStatic - fun getTeamCreator(teamId: String?, realm: Realm?): String { - val teams = realm?.where(RealmMyTeam::class.java)?.equalTo("teamId", teamId)?.findFirst() - return teams?.userId ?: "" + fun getTeamCreator(teamId: String, realm: Realm): String { + return realm.query("teamId == $0", teamId).first().find()?.userId ?: "" } - @JvmStatic - fun getTeamLeader(teamId: String?, realm: Realm): String { - val team = realm.where(RealmMyTeam::class.java) - .equalTo("teamId", teamId) - .equalTo("isLeader", true) - .findFirst() - return team?.userId ?: "" + fun getTeamLeader(teamId: String, realm: Realm): String { + return realm.query("teamId == $0 AND isLeader == true", teamId).first().find()?.userId ?: "" } - @JvmStatic - fun insert(mRealm: Realm, doc: JsonObject) { - insertMyTeams(doc, mRealm) + fun insert(realm: Realm, doc: JsonObject) { + insertMyTeams(doc, realm) } - @JvmStatic - fun requestToJoin(teamId: String?, userModel: RealmUserModel?, mRealm: Realm) { - if (!mRealm.isInTransaction) mRealm.beginTransaction() - val team = mRealm.createObject(RealmMyTeam::class.java, AndroidDecrypter.generateIv()) - team.docType = "request" - team.createdDate = Date().time - team.teamType = "sync" - team.userId = userModel?.id - team.teamId = teamId - team.updated = true - team.teamPlanetCode = userModel?.planetCode - mRealm.commitTransaction() + fun requestToJoin(teamId: String, userModel: RealmUserModel, realm: Realm) { + realm.writeBlocking { + copyToRealm(RealmMyTeam().apply { + this._id = AndroidDecrypter.generateIv() + this.docType = "request" + this.createdDate = Date().time + this.teamType = "sync" + this.userId = userModel.id + this.teamId = teamId + this.updated = true + this.teamPlanetCode = userModel.planetCode ?: "" + }) + } } - @JvmStatic - fun getRequestedMember(teamId: String, realm: Realm): MutableList { + fun getRequestedMember(teamId: String, realm: Realm): List { return getUsers(teamId, realm, "request") } - @JvmStatic - fun getJoinedMember(teamId: String, realm: Realm): MutableList { + fun getJoinedMember(teamId: String, realm: Realm): List { return getUsers(teamId, realm, "membership") } - @JvmStatic - fun isTeamLeader(teamId: String?, userId: String?, realm: Realm): Boolean { - val team = realm.where(RealmMyTeam::class.java) - .equalTo("teamId", teamId) - .equalTo("docType", "membership") - .equalTo("userId", userId) - .equalTo("isLeader", true) - .findFirst() - return team != null + fun isTeamLeader(teamId: String, userId: String, realm: Realm): Boolean { + val count = realm.query("teamId == $0 AND docType == 'membership' AND userId == $1 AND isLeader == true", teamId, userId).first().find() + return count != null } - @JvmStatic - fun getUsers(teamId: String?, mRealm: Realm, docType: String): MutableList { - var query = mRealm.where(RealmMyTeam::class.java).equalTo("teamId", teamId) - if (docType.isNotEmpty()) { - query = query.equalTo("docType", docType) + fun getUsers(teamId: String, realm: Realm, docType: String = ""): List { + val queryStr = if (docType.isNotEmpty()) { + "teamId == $0 AND docType == $1" + } else { + "teamId == $0" } - val myTeam = query.findAll() - val list = mutableListOf() - for (team in myTeam) { - val model = mRealm.where(RealmUserModel::class.java) - .equalTo("id", team.userId) - .findFirst() - if (model != null && !list.contains(model)) list.add(model) + + val teams = if (docType.isNotEmpty()) { + realm.query(queryStr, teamId, docType).find() + } else { + realm.query(queryStr, teamId).find() } - return list + + return teams.mapNotNull { + team -> realm.query("id == $0", team.userId).first().find() + }.distinct() } - @JvmStatic - fun filterUsers(teamId: String?, user: String, mRealm: Realm): MutableList { - val myTeam = mRealm.where(RealmMyTeam::class.java).equalTo("teamId", teamId).findAll() - val list = mutableListOf() - for (team in myTeam) { - val model = mRealm.where(RealmUserModel::class.java) - .equalTo("id", team.userId) - .findFirst() - if (model != null && model.name?.contains(user) == true) { - list.add(model) + fun filterUsers(teamId: String, user: String, realm: Realm): List { + val teams = realm.query("teamId == $0", teamId).find() + + return teams.mapNotNull { team -> + realm.query("id == $0", team.userId).first().find()?.takeIf { + it.name?.contains(user) == true } } - return list } - @JvmStatic fun serialize(team: RealmMyTeam): JsonObject { val gson = Gson() - val `object` = JsonObject() - - JsonUtils.addString(`object`, "_id", team._id) - JsonUtils.addString(`object`, "_rev", team._rev) - `object`.addProperty("name", team.name) - `object`.addProperty("userId", team.userId) - if (team.docType != "report") { - `object`.addProperty("limit", team.limit) - `object`.addProperty("amount", team.amount) - `object`.addProperty("date", team.date) - `object`.addProperty("public", team.isPublic) - `object`.addProperty("isLeader", team.isLeader) - } - `object`.addProperty("createdDate", team.createdDate) - `object`.addProperty("description", team.description) - `object`.addProperty("beginningBalance", team.beginningBalance) - `object`.addProperty("sales", team.sales) - `object`.addProperty("otherIncome", team.otherIncome) - `object`.addProperty("wages", team.wages) - `object`.addProperty("otherExpenses", team.otherExpenses) - `object`.addProperty("startDate", team.startDate) - `object`.addProperty("endDate", team.endDate) - `object`.addProperty("updatedDate", team.updatedDate) - JsonUtils.addString(`object`, "teamId", team.teamId) - `object`.addProperty("teamType", team.teamType) - `object`.addProperty("teamPlanetCode", team.teamPlanetCode) - `object`.addProperty("docType", team.docType) - `object`.addProperty("status", team.status) - `object`.addProperty("userPlanetCode", team.userPlanetCode) - `object`.addProperty("parentCode", team.parentCode) - - `object`.addProperty("type", team.type) - `object`.addProperty("route", team.route) - `object`.addProperty("sourcePlanet", team.sourcePlanet) - `object`.addProperty("services", team.services) - `object`.addProperty("createdBy", team.createdBy) - `object`.addProperty("resourceId", team.resourceId) - `object`.addProperty("rules", team.rules) - - if (team.teamType == "debit" || team.teamType == "credit") { - `object`.addProperty("type", team.teamType) + val obj = JsonObject().apply { + JsonUtils.addString(this, "_id", team._id) + JsonUtils.addString(this, "_rev", team._rev) + addProperty("name", team.name) + addProperty("userId", team.userId) + + if (team.docType != "report") { + addProperty("limit", team.limit) + addProperty("amount", team.amount) + addProperty("date", team.date) + addProperty("public", team.isPublic) + addProperty("isLeader", team.isLeader) + } + + addProperty("createdDate", team.createdDate) + addProperty("description", team.description) + addProperty("beginningBalance", team.beginningBalance) + addProperty("sales", team.sales) + addProperty("otherIncome", team.otherIncome) + addProperty("wages", team.wages) + addProperty("otherExpenses", team.otherExpenses) + addProperty("startDate", team.startDate) + addProperty("endDate", team.endDate) + addProperty("updatedDate", team.updatedDate) + JsonUtils.addString(this, "teamId", team.teamId) + addProperty("teamType", team.teamType) + addProperty("teamPlanetCode", team.teamPlanetCode) + addProperty("docType", team.docType) + addProperty("status", team.status) + addProperty("userPlanetCode", team.userPlanetCode) + addProperty("parentCode", team.parentCode) + addProperty("type", team.type) + addProperty("route", team.route) + addProperty("sourcePlanet", team.sourcePlanet) + addProperty("services", team.services) + addProperty("createdBy", team.createdBy) + addProperty("resourceId", team.resourceId) + addProperty("rules", team.rules) + + if (team.teamType == "debit" || team.teamType == "credit") { + addProperty("type", team.teamType) + } } - return JsonParser.parseString(gson.toJson(`object`)).asJsonObject + return JsonParser.parseString(gson.toJson(obj)).asJsonObject } - fun getMyTeamsByUserId(mRealm: Realm, settings: SharedPreferences?): RealmResults { + fun getMyTeamsByUserId(realm: Realm, settings: SharedPreferences?): List { val userId = settings?.getString("userId", "--") ?: "--" - val list = mRealm.where(RealmMyTeam::class.java) - .equalTo("userId", userId) - .equalTo("docType", "membership") - .findAll() - - val teamIds = list.map { it.teamId }.toTypedArray() - return mRealm.where(RealmMyTeam::class.java) - .`in`("_id", teamIds) - .findAll() + val teamIds = realm.query("userId == $0 AND docType == 'membership'", userId).find().map { it._id } + + return realm.query("_id IN $0", teamIds).find() } } - fun requested(userId: String?, mRealm: Realm): Boolean { - val m = mRealm.where(RealmMyTeam::class.java) - .equalTo("docType", "request") - .equalTo("teamId", _id) - .equalTo("userId", userId) - .findAll() - - return m.size > 0 + fun requested(userId: String, realm: Realm): Boolean { + val count = realm.query("docType == 'request' AND teamId == $0 AND userId == $1", _id, userId).first().find() + return count != null } - fun isMyTeam(userID: String?, mRealm: Realm): Boolean { - return mRealm.where(RealmMyTeam::class.java) - .equalTo("userId", userID) - .equalTo("teamId", _id) - .equalTo("docType", "membership") - .count() > 0 + fun isMyTeam(userId: String, realm: Realm): Boolean { + val count = realm.query("userId == $0 AND teamId == $1 AND docType == 'membership'", userId, _id).first().find() + return count != null } - fun leave(user: RealmUserModel?, mRealm: Realm) { - val teams = mRealm.where(RealmMyTeam::class.java) - .equalTo("userId", user?.id) - .equalTo("teamId", this._id) - .equalTo("docType", "membership") - .findAll() - - for (team in teams) { - if (team != null) { - removeTeam(team, mRealm) - } + fun leave(user: RealmUserModel, realm: Realm) { + realm.writeBlocking { + query("userId == $0 AND teamId == $1 AND docType == 'membership'", user.id, this@RealmMyTeam._id) + .find().forEach { + delete(it) + } } } - - private fun removeTeam(team: RealmMyTeam, mRealm: Realm) { - if (!mRealm.isInTransaction) mRealm.beginTransaction() - team.deleteFromRealm() - mRealm.commitTransaction() - } -} +} \ No newline at end of file From 3f4ff4aba4f0e1dec915f81b1dbb5055d0e12fcc Mon Sep 17 00:00:00 2001 From: Gideon Okuro Date: Tue, 10 Dec 2024 23:13:12 +0300 Subject: [PATCH 15/38] migrate realmMyCourse and course progress --- .../myplanet/model/RealmCourseProgress.kt | 203 +++--- .../planet/myplanet/model/RealmMyCourse.kt | 641 ++++++++++++------ 2 files changed, 559 insertions(+), 285 deletions(-) diff --git a/app/src/main/java/org/ole/planet/myplanet/model/RealmCourseProgress.kt b/app/src/main/java/org/ole/planet/myplanet/model/RealmCourseProgress.kt index a4f6884757..3c85633474 100644 --- a/app/src/main/java/org/ole/planet/myplanet/model/RealmCourseProgress.kt +++ b/app/src/main/java/org/ole/planet/myplanet/model/RealmCourseProgress.kt @@ -2,9 +2,20 @@ package org.ole.planet.myplanet.model import com.google.gson.JsonObject import com.opencsv.CSVWriter -import io.realm.Realm -import io.realm.RealmObject -import io.realm.annotations.PrimaryKey +import io.realm.kotlin.Realm +import io.realm.kotlin.RealmConfiguration +import io.realm.kotlin.ext.query +import io.realm.kotlin.ext.realmListOf +import io.realm.kotlin.query.Sort +import io.realm.kotlin.types.RealmObject +import io.realm.kotlin.types.annotations.PrimaryKey +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.asFlow +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.flow.flatMapLatest +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.toList import org.ole.planet.myplanet.MainApplication.Companion.context import org.ole.planet.myplanet.model.RealmMyCourse.Companion.getCourseSteps import org.ole.planet.myplanet.model.RealmMyCourse.Companion.getMyCourseByUserId @@ -14,124 +25,124 @@ import java.io.File import java.io.FileWriter import java.io.IOException -open class RealmCourseProgress : RealmObject() { +class RealmCourseProgress : RealmObject { @PrimaryKey - var id: String? = null - var _id: String? = null - var createdOn: String? = null + var id: String = "" + var _id: String = "" + var createdOn: String = "" var createdDate: Long = 0 var updatedDate: Long = 0 - var _rev: String? = null - var stepNum = 0 - var passed = false - var userId: String? = null - var courseId: String? = null - var parentCode: String? = null + var _rev: String = "" + var stepNum: Int = 0 + var passed: Boolean = false + var userId: String = "" + var courseId: String = "" + var parentCode: String = "" companion object { - val progressDataList: MutableList> = mutableListOf() - @JvmStatic + private val progressDataList = mutableListOf>() + fun serializeProgress(progress: RealmCourseProgress): JsonObject { - val `object` = JsonObject() - `object`.addProperty("userId", progress.userId) - `object`.addProperty("parentCode", progress.parentCode) - `object`.addProperty("courseId", progress.courseId) - `object`.addProperty("passed", progress.passed) - `object`.addProperty("stepNum", progress.stepNum) - `object`.addProperty("createdOn", progress.createdOn) - `object`.addProperty("createdDate", progress.createdDate) - `object`.addProperty("updatedDate", progress.updatedDate) - return `object` + return JsonObject().apply { + addProperty("userId", progress.userId) + addProperty("parentCode", progress.parentCode) + addProperty("courseId", progress.courseId) + addProperty("passed", progress.passed) + addProperty("stepNum", progress.stepNum) + addProperty("createdOn", progress.createdOn) + addProperty("createdDate", progress.createdDate) + addProperty("updatedDate", progress.updatedDate) + } } - @JvmStatic - fun getCourseProgress(mRealm: Realm, userId: String?): HashMap { - val r = getMyCourseByUserId(userId, mRealm.where(RealmMyCourse::class.java).findAll()) - val map = HashMap() - for (course in r) { - val `object` = JsonObject() - val steps = getCourseSteps(mRealm, course.courseId) - `object`.addProperty("max", steps.size) - `object`.addProperty("current", getCurrentProgress(steps, mRealm, userId, course.courseId)) - if (isMyCourse(userId, course.courseId, mRealm)) map[course.courseId] = `object` + suspend fun getCourseProgress(realm: Realm, userId: String): Flow> { + return getMyCourseByUserId(userId).map { courses -> + courses.map { course -> + getCourseSteps(course.courseId).first().let { steps -> + if (isMyCourse(userId, course.courseId)) { + course.courseId to JsonObject().apply { + addProperty("max", steps.size) + addProperty("current", getCurrentProgress(steps, realm, userId, course.courseId)) + } + } else null + } + }.filterNotNull().toMap() } - return map } -// @JvmStatic -// fun getPassedCourses(mRealm: Realm, userId: String?): List { -// val progresses = mRealm.where(RealmCourseProgress::class.java).equalTo("userId", userId).equalTo("passed", true).findAll() -// val list: MutableList = ArrayList() -// for (progress in progresses) { -// Utilities.log("Course id certified " + progress.courseId) -// val sub = progress.courseId?.let { -// mRealm.where(RealmSubmission::class.java) -// .contains("parentId", it).equalTo("userId", userId) -// .sort("lastUpdateTime", Sort.DESCENDING).findFirst() +// fun getPassedCourses(realm: Realm, userId: String): Flow> { +// return realm.query("userId == $0 AND passed == true", userId) +// .asFlow() +// .map { progresses -> +// progresses.list.mapNotNull { progress -> +// realm.query("parentId CONTAINS $0 AND userId == $1", +// progress.courseId, userId).sort("lastUpdateTime", Sort.DESCENDING) +// .first().find() +// } // } -// if (sub != null) list.add(sub) -// } -// return list // } - @JvmStatic - fun getCurrentProgress(steps: List?, mRealm: Realm, userId: String?, courseId: String?): Int { - var i = 0 - while (i < (steps?.size ?: 0)) { - mRealm.where(RealmCourseProgress::class.java).equalTo("stepNum", i + 1).equalTo("userId", userId).equalTo("courseId", courseId) - .findFirst() - ?: break - i++ + fun getCurrentProgress(steps: List, realm: Realm, userId: String, courseId: String): Int { + var currentStep = 0 + while (currentStep < steps.size) { + val progress = realm.query( + "stepNum == $0 AND userId == $1 AND courseId == $2", currentStep + 1, userId, courseId + ).first().find() ?: break + currentStep++ } - return i + return currentStep } - @JvmStatic - fun insert(mRealm: Realm, act: JsonObject?) { - if (!mRealm.isInTransaction) { - mRealm.beginTransaction() - } - var courseProgress = mRealm.where(RealmCourseProgress::class.java).equalTo("_id", JsonUtils.getString("_id", act)).findFirst() - if (courseProgress == null) { - courseProgress = mRealm.createObject(RealmCourseProgress::class.java, JsonUtils.getString("_id", act)) - } - courseProgress?._rev = JsonUtils.getString("_rev", act) - courseProgress?._id = JsonUtils.getString("_id", act) - courseProgress?.passed = JsonUtils.getBoolean("passed", act) - courseProgress?.stepNum = JsonUtils.getInt("stepNum", act) - courseProgress?.userId = JsonUtils.getString("userId", act) - courseProgress?.parentCode = JsonUtils.getString("parentCode", act) - courseProgress?.courseId = JsonUtils.getString("courseId", act) - courseProgress?.createdOn = JsonUtils.getString("createdOn", act) - courseProgress?.createdDate = JsonUtils.getLong("createdDate", act) - courseProgress?.updatedDate = JsonUtils.getLong("updatedDate", act) - mRealm.commitTransaction() + suspend fun insert(realm: Realm, act: JsonObject) { + realm.write { + val courseProgress = query("_id == $0", + JsonUtils.getString("_id", act)).first().find() + ?: RealmCourseProgress().apply { + id = JsonUtils.getString("_id", act) + } + + copyToRealm(courseProgress.apply { + _rev = JsonUtils.getString("_rev", act) + _id = JsonUtils.getString("_id", act) + passed = JsonUtils.getBoolean("passed", act) + stepNum = JsonUtils.getInt("stepNum", act) + userId = JsonUtils.getString("userId", act) + parentCode = JsonUtils.getString("parentCode", act) + courseId = JsonUtils.getString("courseId", act) + createdOn = JsonUtils.getString("createdOn", act) + createdDate = JsonUtils.getLong("createdDate", act) + updatedDate = JsonUtils.getLong("updatedDate", act) + }) - val csvRow = arrayOf( - JsonUtils.getString("_id", act), - JsonUtils.getString("_rev", act), - JsonUtils.getBoolean("passed", act).toString(), - JsonUtils.getInt("stepNum", act).toString(), - JsonUtils.getString("userId", act), - JsonUtils.getString("parentCode", act), - JsonUtils.getString("courseId", act), - JsonUtils.getString("createdOn", act), - JsonUtils.getLong("createdDate", act).toString(), - JsonUtils.getLong("updatedDate", act).toString() - ) - progressDataList.add(csvRow) + val csvRow = arrayOf( + JsonUtils.getString("_id", act), + JsonUtils.getString("_rev", act), + JsonUtils.getBoolean("passed", act).toString(), + JsonUtils.getInt("stepNum", act).toString(), + JsonUtils.getString("userId", act), + JsonUtils.getString("parentCode", act), + JsonUtils.getString("courseId", act), + JsonUtils.getString("createdOn", act), + JsonUtils.getLong("createdDate", act).toString(), + JsonUtils.getLong("updatedDate", act).toString() + ) + progressDataList.add(csvRow) + } } fun writeCsv(filePath: String, data: List>) { try { val file = File(filePath) file.parentFile?.mkdirs() - val writer = CSVWriter(FileWriter(file)) - writer.writeNext(arrayOf("progressId", "progress_rev", "passed", "stepNum", "userId", "parentCode", "courseId", "createdOn", "createdDate", "updatedDate")) - for (row in data) { - writer.writeNext(row) + CSVWriter(FileWriter(file)).use { writer -> + writer.writeNext(arrayOf( + "progressId", "progress_rev", "passed", "stepNum", "userId", "parentCode", + "courseId", "createdOn", "createdDate", "updatedDate" + )) + data.forEach { row -> + writer.writeNext(row) + } } - writer.close() } catch (e: IOException) { e.printStackTrace() } diff --git a/app/src/main/java/org/ole/planet/myplanet/model/RealmMyCourse.kt b/app/src/main/java/org/ole/planet/myplanet/model/RealmMyCourse.kt index ca760df965..73a4df6de3 100644 --- a/app/src/main/java/org/ole/planet/myplanet/model/RealmMyCourse.kt +++ b/app/src/main/java/org/ole/planet/myplanet/model/RealmMyCourse.kt @@ -8,136 +8,118 @@ import com.google.gson.Gson import com.google.gson.JsonArray import com.google.gson.JsonObject import com.opencsv.CSVWriter -import io.realm.Realm -import io.realm.RealmList -import io.realm.RealmObject -import io.realm.RealmResults -import io.realm.annotations.PrimaryKey -import io.realm.kotlin.where +import io.realm.kotlin.Realm +import io.realm.kotlin.ext.query +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.launch import org.ole.planet.myplanet.MainApplication.Companion.context import org.ole.planet.myplanet.model.RealmMyLibrary.Companion.createStepResource import org.ole.planet.myplanet.model.RealmStepExam.Companion.insertCourseStepsExams import org.ole.planet.myplanet.utilities.Constants.PREFS_NAME -import org.ole.planet.myplanet.utilities.DownloadUtils.extractLinks import org.ole.planet.myplanet.utilities.JsonUtils -import org.ole.planet.myplanet.utilities.Utilities import java.io.File import java.io.FileWriter import java.io.IOException -open class RealmMyCourse : RealmObject() { +class RealmMyCourse : RealmObject { @PrimaryKey - var id: String? = null - var userId: RealmList? = null - private set - var courseId: String? = null - var courseRev: String? = null - var languageOfInstruction: String? = null - var courseTitle: String? = null - var memberLimit: Int? = null - var description: String? = null - var method: String? = null - var gradeLevel: String? = null - var subjectLevel: String? = null + var id: String = "" + var userId: RealmList = realmListOf() + var courseId: String = "" + var courseRev: String = "" + var languageOfInstruction: String = "" + var courseTitle: String = "" + var memberLimit: Int = 0 + var description: String = "" + var method: String = "" + var gradeLevel: String = "" + var subjectLevel: String = "" var createdDate: Long = 0 - private var numberOfSteps: Int? = null - var courseSteps: RealmList? = null + private var numberOfSteps: Int = 0 + var courseSteps: RealmList = realmListOf() + @Transient var isMyCourse: Boolean = false - fun setUserId(userId: String?) { - if (this.userId == null) { - this.userId = RealmList() - } - if (!this.userId?.contains(userId)!! && !TextUtils.isEmpty(userId)) { - this.userId?.add(userId) + + fun addUserId(userId: String) { + if (!TextUtils.isEmpty(userId) && !this.userId.contains(userId)) { + this.userId.add(userId) } } - fun removeUserId(userId: String?) { - this.userId?.remove(userId) + fun removeUserId(userId: String) { + this.userId.remove(userId) } - fun getNumberOfSteps(): Int { - return numberOfSteps ?: 0 - } + fun getNumberOfSteps(): Int = numberOfSteps - fun setNumberOfSteps(numberOfSteps: Int?) { - this.numberOfSteps = numberOfSteps + fun setNumberOfSteps(steps: Int) { + numberOfSteps = steps } - override fun toString(): String { - return courseTitle ?: "" - } + override fun toString(): String = courseTitle companion object { private val gson = Gson() private val concatenatedLinks = ArrayList() val courseDataList: MutableList> = mutableListOf() - @JvmStatic - fun insertMyCourses(userId: String?, myCoursesDoc: JsonObject?, mRealm: Realm) { - context.getSharedPreferences(PREFS_NAME, MODE_PRIVATE) - if (!mRealm.isInTransaction) { - mRealm.beginTransaction() - } - val id = JsonUtils.getString("_id", myCoursesDoc) - var myMyCoursesDB = mRealm.where(RealmMyCourse::class.java).equalTo("id", id).findFirst() - if (myMyCoursesDB == null) { - myMyCoursesDB = mRealm.createObject(RealmMyCourse::class.java, id) - } - myMyCoursesDB?.setUserId(userId) - myMyCoursesDB?.courseId = JsonUtils.getString("_id", myCoursesDoc) - myMyCoursesDB?.courseRev = JsonUtils.getString("_rev", myCoursesDoc) - myMyCoursesDB?.languageOfInstruction = JsonUtils.getString("languageOfInstruction", myCoursesDoc) - myMyCoursesDB?.courseTitle = JsonUtils.getString("courseTitle", myCoursesDoc) - myMyCoursesDB?.memberLimit = JsonUtils.getInt("memberLimit", myCoursesDoc) - myMyCoursesDB?.description = JsonUtils.getString("description", myCoursesDoc) - val description = JsonUtils.getString("description", myCoursesDoc) - val links = extractLinks(description) - val baseUrl = Utilities.getUrl() - for (link in links) { - val concatenatedLink = "$baseUrl/$link" - concatenatedLinks.add(concatenatedLink) - } - myMyCoursesDB?.method = JsonUtils.getString("method", myCoursesDoc) - myMyCoursesDB?.gradeLevel = JsonUtils.getString("gradeLevel", myCoursesDoc) - myMyCoursesDB?.subjectLevel = JsonUtils.getString("subjectLevel", myCoursesDoc) - myMyCoursesDB?.createdDate = JsonUtils.getLong("createdDate", myCoursesDoc) - myMyCoursesDB?.setNumberOfSteps(JsonUtils.getJsonArray("steps", myCoursesDoc).size()) - val courseStepsJsonArray = JsonUtils.getJsonArray("steps", myCoursesDoc) - val courseStepsList = mutableListOf() - - for (i in 0 until courseStepsJsonArray.size()) { - val stepId = Base64.encodeToString(courseStepsJsonArray[i].toString().toByteArray(), Base64.NO_WRAP) - val stepJson = courseStepsJsonArray[i].asJsonObject - val step = RealmCourseStep() - step.id = stepId - step.stepTitle = JsonUtils.getString("stepTitle", stepJson) - step.description = JsonUtils.getString("description", stepJson) - val stepDescription = JsonUtils.getString("description", stepJson) - val stepLinks = extractLinks(stepDescription) - for (stepLink in stepLinks) { - val concatenatedLink = "$baseUrl/$stepLink" - concatenatedLinks.add(concatenatedLink) + fun insertMyCourses(userId: String, myCoursesDoc: JsonObject, realm: Realm) { + CoroutineScope(Dispatchers.IO).launch { + val ID = JsonUtils.getString("_id", myCoursesDoc) + realm.writeBlocking { + var myMyCourseDB = this.query("id == $0", ID).first().find() + + if (myMyCourseDB == null) { + myMyCourseDB = RealmMyCourse().apply { this.id = ID } + copyToRealm(myMyCourseDB) + } + + myMyCourseDB.apply { + addUserId(userId) + courseId = JsonUtils.getString("_id", myCoursesDoc) + courseRev = JsonUtils.getString("_rev", myCoursesDoc) + languageOfInstruction = JsonUtils.getString("languageOfInstruction", myCoursesDoc) + courseTitle = JsonUtils.getString("courseTitle", myCoursesDoc) + memberLimit = JsonUtils.getInt("memberLimit", myCoursesDoc) + description = JsonUtils.getString("description", myCoursesDoc) + method = JsonUtils.getString("method", myCoursesDoc) + gradeLevel = JsonUtils.getString("gradeLevel", myCoursesDoc) + subjectLevel = JsonUtils.getString("subjectLevel", myCoursesDoc) + createdDate = JsonUtils.getLong("createdDate", myCoursesDoc) + setNumberOfSteps(JsonUtils.getJsonArray("steps", myCoursesDoc).size()) + + courseSteps.clear() + } } - insertCourseStepsAttachments(myMyCoursesDB?.courseId, stepId, JsonUtils.getJsonArray("resources", stepJson), mRealm) - insertExam(stepJson, mRealm, stepId, i + 1, myMyCoursesDB?.courseId) - insertSurvey(stepJson, mRealm, stepId, i + 1, myMyCoursesDB?.courseId, myMyCoursesDB?.createdDate) - step.noOfResources = JsonUtils.getJsonArray("resources", stepJson).size() - step.courseId = myMyCoursesDB?.courseId - courseStepsList.add(step) - } - if (mRealm.isInTransaction) { - mRealm.commitTransaction() - } + val courseStepsJsonArray = JsonUtils.getJsonArray("steps", myCoursesDoc) + + for (i in 0 until courseStepsJsonArray.size()) { + val stepJson = courseStepsJsonArray[i].asJsonObject + val stepId = Base64.encodeToString(stepJson.toString().toByteArray(), Base64.NO_WRAP) - if (!mRealm.isInTransaction) { - mRealm.beginTransaction() + realm.writeBlocking { + val step = RealmCourseStep().apply { + id = stepId + stepTitle = JsonUtils.getString("stepTitle", stepJson) + description = JsonUtils.getString("description", stepJson) + courseId = ID + noOfResources = JsonUtils.getJsonArray("resources", stepJson).size() + } + copyToRealm(step) + } + + // Safely call suspend functions + insertExam(stepJson, realm, stepId, i + 1, ID) + insertSurvey(stepJson, realm, stepId, i + 1, ID, JsonUtils.getLong("createdDate", myCoursesDoc)) + } } - myMyCoursesDB?.courseSteps = RealmList() - myMyCoursesDB?.courseSteps?.addAll(courseStepsList) - mRealm.commitTransaction() val csvRow = arrayOf( JsonUtils.getString("_id", myCoursesDoc), @@ -159,12 +141,14 @@ open class RealmMyCourse : RealmObject() { try { val file = File(filePath) file.parentFile?.mkdirs() - val writer = CSVWriter(FileWriter(file)) - writer.writeNext(arrayOf("courseId", "course_rev", "languageOfInstruction", "courseTitle", "memberLimit", "description", "method", "gradeLevel", "subjectLevel", "createdDate", "steps")) - for (row in data) { - writer.writeNext(row) + CSVWriter(FileWriter(file)).use { writer -> + writer.writeNext(arrayOf( + "courseId", "course_rev", "languageOfInstruction", + "courseTitle", "memberLimit", "description", "method", + "gradeLevel", "subjectLevel", "createdDate", "steps" + )) + data.forEach { writer.writeNext(it) } } - writer.close() } catch (e: IOException) { e.printStackTrace() } @@ -174,132 +158,411 @@ open class RealmMyCourse : RealmObject() { writeCsv("${context.getExternalFilesDir(null)}/ole/course.csv", courseDataList) } - @JvmStatic fun saveConcatenatedLinksToPrefs() { val settings: SharedPreferences = context.getSharedPreferences(PREFS_NAME, MODE_PRIVATE) val existingJsonLinks = settings.getString("concatenated_links", null) - val existingConcatenatedLinks = if (existingJsonLinks != null) { - gson.fromJson(existingJsonLinks, Array::class.java).toMutableList() - } else { - mutableListOf() - } - val linksToProcess: List + val existingConcatenatedLinks = existingJsonLinks?.let { + gson.fromJson(it, Array::class.java).toMutableList() + } ?: mutableListOf() + synchronized(concatenatedLinks) { - linksToProcess = concatenatedLinks.toList() - } - for (link in linksToProcess) { - if (!existingConcatenatedLinks.contains(link)) { - existingConcatenatedLinks.add(link) + concatenatedLinks.forEach { link -> + if (!existingConcatenatedLinks.contains(link)) { + existingConcatenatedLinks.add(link) + } } } - val jsonConcatenatedLinks = gson.toJson(existingConcatenatedLinks) - settings.edit().putString("concatenated_links", jsonConcatenatedLinks).apply() + + settings.edit().putString("concatenated_links", gson.toJson(existingConcatenatedLinks)).apply() } - fun getCourseSteps(mRealm: Realm, courseId: String?): List { - val myCourse = mRealm.where().equalTo("id", courseId).findFirst() - val courseSteps = myCourse?.courseSteps ?: emptyList() - return courseSteps + fun getCourseSteps(realm: Realm, courseId: String): List { + return realm.query("id == $0", courseId).first().find()?.courseSteps?.toList() + ?: emptyList() } - fun getCourseStepIds(mRealm: Realm, courseId: String?): Array { - val course = mRealm.where().equalTo("courseId", courseId).findFirst() - val stepIds = course?.courseSteps?.map { it.id }?.toTypedArray() ?: emptyArray() - return stepIds + fun getCourseStepIds(realm: Realm, courseId: String): Array { + return realm.query("courseId == $0", courseId).first().find()?.courseSteps?.map { it.id }?.toTypedArray() ?: emptyArray() } - private fun insertExam(stepContainer: JsonObject, mRealm: Realm, stepId: String, i: Int, myCoursesID: String?) { + private suspend fun insertExam(stepContainer: JsonObject, realm: Realm, stepId: String, stepNumber: Int, courseId: String) { if (stepContainer.has("exam")) { - val `object` = stepContainer.getAsJsonObject("exam") - `object`.addProperty("stepNumber", i) - insertCourseStepsExams(myCoursesID, stepId, `object`, mRealm) + val examObject = stepContainer.getAsJsonObject("exam").apply { + addProperty("stepNumber", stepNumber) + } + insertCourseStepsExams(courseId, stepId, examObject, realm) } } - private fun insertSurvey(stepContainer: JsonObject, mRealm: Realm, stepId: String, i: Int, myCoursesID: String?, createdDate: Long?) { + private suspend fun insertSurvey(stepContainer: JsonObject, realm: Realm, stepId: String, stepNumber: Int, courseId: String, createdDate: Long) { if (stepContainer.has("survey")) { - val `object` = stepContainer.getAsJsonObject("survey") - `object`.addProperty("stepNumber", i) - `object`.addProperty("createdDate", createdDate) - insertCourseStepsExams(myCoursesID, stepId, `object`, mRealm) + val surveyObject = stepContainer.getAsJsonObject("survey").apply { + addProperty("stepNumber", stepNumber) + addProperty("createdDate", createdDate) + } + insertCourseStepsExams(courseId, stepId, surveyObject, realm) } } - private fun insertCourseStepsAttachments(myCoursesID: String?, stepId: String?, resources: JsonArray, mRealm: Realm?) { + private fun insertCourseStepsAttachments(courseId: String, stepId: String, resources: JsonArray, realm: Realm) { resources.forEach { resource -> - if (mRealm != null) { - createStepResource(mRealm, resource.asJsonObject, myCoursesID, stepId) - } + createStepResource(realm, resource.asJsonObject, courseId, stepId) } } - @JvmStatic - fun getMyByUserId(mRealm: Realm, settings: SharedPreferences?): RealmResults { - val userId = settings?.getString("userId", "--") - return mRealm.where(RealmMyCourse::class.java) - .equalTo("userId", userId) - .findAll() + fun getMyByUserId(realm: Realm, settings: SharedPreferences?): List { + val userId = settings?.getString("userId", "--") ?: return emptyList() + return realm.query("userId == $0", userId).find() } - @JvmStatic - fun getMyCourseByUserId(userId: String?, libs: List?): List { - val libraries: MutableList = ArrayList() - for (item in libs ?: emptyList()) { - if (item.userId?.contains(userId) == true) { - libraries.add(item) - } - } - return libraries + fun getMyCourseByUserId(userId: String, courses: List): List { + return courses.filter { course -> course.userId.contains(userId) } } - @JvmStatic - fun getOurCourse(userId: String?, libs: List): List { - val libraries: MutableList = ArrayList() - for (item in libs) { - if (!item.userId?.contains(userId)!!) { - libraries.add(item) - } - } - return libraries + fun getOurCourse(userId: String, courses: List): List { + return courses.filter { course -> !course.userId.contains(userId) } } - @JvmStatic - fun isMyCourse(userId: String?, courseId: String?, realm: Realm): Boolean { - return getMyCourseByUserId(userId, realm.where(RealmMyCourse::class.java).equalTo("courseId", courseId).findAll()).isNotEmpty() + fun isMyCourse(userId: String, courseId: String, realm: Realm): Boolean { + val courses = realm.query("courseId == $0", courseId).find() + return getMyCourseByUserId(userId, courses).isNotEmpty() } - @JvmStatic - fun getCourseByCourseId(courseId: String, mRealm: Realm): RealmMyCourse? { - return mRealm.where(RealmMyCourse::class.java).equalTo("courseId", courseId).findFirst() + fun getCourseByCourseId(courseId: String, realm: Realm): RealmMyCourse? { + return realm.query("courseId == $0", courseId).first().find() } - @JvmStatic - fun insert(mRealm: Realm, myCoursesDoc: JsonObject?) { - insertMyCourses("", myCoursesDoc, mRealm) + fun insert(realm: Realm, myCoursesDoc: JsonObject) { + insertMyCourses("", myCoursesDoc, realm) } - @JvmStatic - fun getMyCourse(mRealm: Realm, id: String?): RealmMyCourse? { - return mRealm.where(RealmMyCourse::class.java).equalTo("courseId", id).findFirst() + fun getMyCourse(realm: Realm, id: String): RealmMyCourse? { + return realm.query("courseId == $0", id).first().find() } - @JvmStatic - fun createMyCourse(course: RealmMyCourse?, mRealm: Realm, id: String?) { - if (!mRealm.isInTransaction) { - mRealm.beginTransaction() + fun createMyCourse(course: RealmMyCourse?, realm: Realm, id: String) { + realm.writeBlocking { + course?.addUserId(id) } - course?.setUserId(id) - mRealm.commitTransaction() } - @JvmStatic - fun getMyCourseIds(realm: Realm?, userId: String?): JsonArray { - val myCourses = getMyCourseByUserId(userId, realm?.where(RealmMyCourse::class.java)?.findAll()) - val ids = JsonArray() - for (lib in myCourses) { - ids.add(lib.courseId) + fun getMyCourseIds(realm: Realm?, userId: String): JsonArray { + val myCourses = realm?.let { + getMyCourseByUserId(userId, it.query().find()) + } ?: emptyList() + + return JsonArray().apply { + myCourses.forEach { course -> + add(course.courseId) + } } - return ids } } -} \ No newline at end of file +} + + +//package org.ole.planet.myplanet.model +// +//import android.content.Context.MODE_PRIVATE +//import android.content.SharedPreferences +//import android.text.TextUtils +//import android.util.Base64 +//import com.google.gson.Gson +//import com.google.gson.JsonArray +//import com.google.gson.JsonObject +//import com.opencsv.CSVWriter +//import io.realm.Realm +//import io.realm.RealmList +//import io.realm.RealmObject +//import io.realm.RealmResults +//import io.realm.annotations.PrimaryKey +//import io.realm.kotlin.where +//import org.ole.planet.myplanet.MainApplication.Companion.context +//import org.ole.planet.myplanet.model.RealmMyLibrary.Companion.createStepResource +//import org.ole.planet.myplanet.model.RealmStepExam.Companion.insertCourseStepsExams +//import org.ole.planet.myplanet.utilities.Constants.PREFS_NAME +//import org.ole.planet.myplanet.utilities.DownloadUtils.extractLinks +//import org.ole.planet.myplanet.utilities.JsonUtils +//import org.ole.planet.myplanet.utilities.Utilities +//import java.io.File +//import java.io.FileWriter +//import java.io.IOException +// +//open class RealmMyCourse : RealmObject() { +// @PrimaryKey +// var id: String? = null +// var userId: RealmList? = null +// private set +// var courseId: String? = null +// var courseRev: String? = null +// var languageOfInstruction: String? = null +// var courseTitle: String? = null +// var memberLimit: Int? = null +// var description: String? = null +// var method: String? = null +// var gradeLevel: String? = null +// var subjectLevel: String? = null +// var createdDate: Long = 0 +// private var numberOfSteps: Int? = null +// var courseSteps: RealmList? = null +// @Transient +// var isMyCourse: Boolean = false +// fun setUserId(userId: String?) { +// if (this.userId == null) { +// this.userId = RealmList() +// } +// if (!this.userId?.contains(userId)!! && !TextUtils.isEmpty(userId)) { +// this.userId?.add(userId) +// } +// } +// +// fun removeUserId(userId: String?) { +// this.userId?.remove(userId) +// } +// +// fun getNumberOfSteps(): Int { +// return numberOfSteps ?: 0 +// } +// +// fun setNumberOfSteps(numberOfSteps: Int?) { +// this.numberOfSteps = numberOfSteps +// } +// +// override fun toString(): String { +// return courseTitle ?: "" +// } +// +// companion object { +// private val gson = Gson() +// private val concatenatedLinks = ArrayList() +// val courseDataList: MutableList> = mutableListOf() +// +// @JvmStatic +// fun insertMyCourses(userId: String?, myCoursesDoc: JsonObject?, mRealm: Realm) { +// context.getSharedPreferences(PREFS_NAME, MODE_PRIVATE) +// if (!mRealm.isInTransaction) { +// mRealm.beginTransaction() +// } +// val id = JsonUtils.getString("_id", myCoursesDoc) +// var myMyCoursesDB = mRealm.where(RealmMyCourse::class.java).equalTo("id", id).findFirst() +// if (myMyCoursesDB == null) { +// myMyCoursesDB = mRealm.createObject(RealmMyCourse::class.java, id) +// } +// myMyCoursesDB?.setUserId(userId) +// myMyCoursesDB?.courseId = JsonUtils.getString("_id", myCoursesDoc) +// myMyCoursesDB?.courseRev = JsonUtils.getString("_rev", myCoursesDoc) +// myMyCoursesDB?.languageOfInstruction = JsonUtils.getString("languageOfInstruction", myCoursesDoc) +// myMyCoursesDB?.courseTitle = JsonUtils.getString("courseTitle", myCoursesDoc) +// myMyCoursesDB?.memberLimit = JsonUtils.getInt("memberLimit", myCoursesDoc) +// myMyCoursesDB?.description = JsonUtils.getString("description", myCoursesDoc) +// val description = JsonUtils.getString("description", myCoursesDoc) +// val links = extractLinks(description) +// val baseUrl = Utilities.getUrl() +// for (link in links) { +// val concatenatedLink = "$baseUrl/$link" +// concatenatedLinks.add(concatenatedLink) +// } +// myMyCoursesDB?.method = JsonUtils.getString("method", myCoursesDoc) +// myMyCoursesDB?.gradeLevel = JsonUtils.getString("gradeLevel", myCoursesDoc) +// myMyCoursesDB?.subjectLevel = JsonUtils.getString("subjectLevel", myCoursesDoc) +// myMyCoursesDB?.createdDate = JsonUtils.getLong("createdDate", myCoursesDoc) +// myMyCoursesDB?.setNumberOfSteps(JsonUtils.getJsonArray("steps", myCoursesDoc).size()) +// val courseStepsJsonArray = JsonUtils.getJsonArray("steps", myCoursesDoc) +// val courseStepsList = mutableListOf() +// +// for (i in 0 until courseStepsJsonArray.size()) { +// val stepId = Base64.encodeToString(courseStepsJsonArray[i].toString().toByteArray(), Base64.NO_WRAP) +// val stepJson = courseStepsJsonArray[i].asJsonObject +// val step = RealmCourseStep() +// step.id = stepId +// step.stepTitle = JsonUtils.getString("stepTitle", stepJson) +// step.description = JsonUtils.getString("description", stepJson) +// val stepDescription = JsonUtils.getString("description", stepJson) +// val stepLinks = extractLinks(stepDescription) +// for (stepLink in stepLinks) { +// val concatenatedLink = "$baseUrl/$stepLink" +// concatenatedLinks.add(concatenatedLink) +// } +// insertCourseStepsAttachments(myMyCoursesDB?.courseId, stepId, JsonUtils.getJsonArray("resources", stepJson), mRealm) +// insertExam(stepJson, mRealm, stepId, i + 1, myMyCoursesDB?.courseId) +// insertSurvey(stepJson, mRealm, stepId, i + 1, myMyCoursesDB?.courseId, myMyCoursesDB?.createdDate) +// step.noOfResources = JsonUtils.getJsonArray("resources", stepJson).size() +// step.courseId = myMyCoursesDB?.courseId +// courseStepsList.add(step) +// } +// +// if (mRealm.isInTransaction) { +// mRealm.commitTransaction() +// } +// +// if (!mRealm.isInTransaction) { +// mRealm.beginTransaction() +// } +// myMyCoursesDB?.courseSteps = RealmList() +// myMyCoursesDB?.courseSteps?.addAll(courseStepsList) +// mRealm.commitTransaction() +// +// val csvRow = arrayOf( +// JsonUtils.getString("_id", myCoursesDoc), +// JsonUtils.getString("_rev", myCoursesDoc), +// JsonUtils.getString("languageOfInstruction", myCoursesDoc), +// JsonUtils.getString("courseTitle", myCoursesDoc), +// JsonUtils.getInt("memberLimit", myCoursesDoc).toString(), +// JsonUtils.getString("description", myCoursesDoc), +// JsonUtils.getString("method", myCoursesDoc), +// JsonUtils.getString("gradeLevel", myCoursesDoc), +// JsonUtils.getString("subjectLevel", myCoursesDoc), +// JsonUtils.getLong("createdDate", myCoursesDoc).toString(), +// JsonUtils.getJsonArray("steps", myCoursesDoc).toString() +// ) +// courseDataList.add(csvRow) +// } +// +// fun writeCsv(filePath: String, data: List>) { +// try { +// val file = File(filePath) +// file.parentFile?.mkdirs() +// val writer = CSVWriter(FileWriter(file)) +// writer.writeNext(arrayOf("courseId", "course_rev", "languageOfInstruction", "courseTitle", "memberLimit", "description", "method", "gradeLevel", "subjectLevel", "createdDate", "steps")) +// for (row in data) { +// writer.writeNext(row) +// } +// writer.close() +// } catch (e: IOException) { +// e.printStackTrace() +// } +// } +// +// fun courseWriteCsv() { +// writeCsv("${context.getExternalFilesDir(null)}/ole/course.csv", courseDataList) +// } +// +// @JvmStatic +// fun saveConcatenatedLinksToPrefs() { +// val settings: SharedPreferences = context.getSharedPreferences(PREFS_NAME, MODE_PRIVATE) +// val existingJsonLinks = settings.getString("concatenated_links", null) +// val existingConcatenatedLinks = if (existingJsonLinks != null) { +// gson.fromJson(existingJsonLinks, Array::class.java).toMutableList() +// } else { +// mutableListOf() +// } +// val linksToProcess: List +// synchronized(concatenatedLinks) { +// linksToProcess = concatenatedLinks.toList() +// } +// for (link in linksToProcess) { +// if (!existingConcatenatedLinks.contains(link)) { +// existingConcatenatedLinks.add(link) +// } +// } +// val jsonConcatenatedLinks = gson.toJson(existingConcatenatedLinks) +// settings.edit().putString("concatenated_links", jsonConcatenatedLinks).apply() +// } +// +// fun getCourseSteps(mRealm: Realm, courseId: String?): List { +// val myCourse = mRealm.where().equalTo("id", courseId).findFirst() +// val courseSteps = myCourse?.courseSteps ?: emptyList() +// return courseSteps +// } +// +// fun getCourseStepIds(mRealm: Realm, courseId: String?): Array { +// val course = mRealm.where().equalTo("courseId", courseId).findFirst() +// val stepIds = course?.courseSteps?.map { it.id }?.toTypedArray() ?: emptyArray() +// return stepIds +// } +// +// private fun insertExam(stepContainer: JsonObject, mRealm: Realm, stepId: String, i: Int, myCoursesID: String?) { +// if (stepContainer.has("exam")) { +// val `object` = stepContainer.getAsJsonObject("exam") +// `object`.addProperty("stepNumber", i) +// insertCourseStepsExams(myCoursesID, stepId, `object`, mRealm) +// } +// } +// +// private fun insertSurvey(stepContainer: JsonObject, mRealm: Realm, stepId: String, i: Int, myCoursesID: String?, createdDate: Long?) { +// if (stepContainer.has("survey")) { +// val `object` = stepContainer.getAsJsonObject("survey") +// `object`.addProperty("stepNumber", i) +// `object`.addProperty("createdDate", createdDate) +// insertCourseStepsExams(myCoursesID, stepId, `object`, mRealm) +// } +// } +// +// private fun insertCourseStepsAttachments(myCoursesID: String?, stepId: String?, resources: JsonArray, mRealm: Realm?) { +// resources.forEach { resource -> +// if (mRealm != null) { +// createStepResource(mRealm, resource.asJsonObject, myCoursesID, stepId) +// } +// } +// } +// +// @JvmStatic +// fun getMyByUserId(mRealm: Realm, settings: SharedPreferences?): RealmResults { +// val userId = settings?.getString("userId", "--") +// return mRealm.where(RealmMyCourse::class.java) +// .equalTo("userId", userId) +// .findAll() +// } +// +// @JvmStatic +// fun getMyCourseByUserId(userId: String?, libs: List?): List { +// val libraries: MutableList = ArrayList() +// for (item in libs ?: emptyList()) { +// if (item.userId?.contains(userId) == true) { +// libraries.add(item) +// } +// } +// return libraries +// } +// +// @JvmStatic +// fun getOurCourse(userId: String?, libs: List): List { +// val libraries: MutableList = ArrayList() +// for (item in libs) { +// if (!item.userId?.contains(userId)!!) { +// libraries.add(item) +// } +// } +// return libraries +// } +// +// @JvmStatic +// fun isMyCourse(userId: String?, courseId: String?, realm: Realm): Boolean { +// return getMyCourseByUserId(userId, realm.where(RealmMyCourse::class.java).equalTo("courseId", courseId).findAll()).isNotEmpty() +// } +// +// @JvmStatic +// fun getCourseByCourseId(courseId: String, mRealm: Realm): RealmMyCourse? { +// return mRealm.where(RealmMyCourse::class.java).equalTo("courseId", courseId).findFirst() +// } +// +// @JvmStatic +// fun insert(mRealm: Realm, myCoursesDoc: JsonObject?) { +// insertMyCourses("", myCoursesDoc, mRealm) +// } +// +// @JvmStatic +// fun getMyCourse(mRealm: Realm, id: String?): RealmMyCourse? { +// return mRealm.where(RealmMyCourse::class.java).equalTo("courseId", id).findFirst() +// } +// +// @JvmStatic +// fun createMyCourse(course: RealmMyCourse?, mRealm: Realm, id: String?) { +// if (!mRealm.isInTransaction) { +// mRealm.beginTransaction() +// } +// course?.setUserId(id) +// mRealm.commitTransaction() +// } +// +// @JvmStatic +// fun getMyCourseIds(realm: Realm?, userId: String?): JsonArray { +// val myCourses = getMyCourseByUserId(userId, realm?.where(RealmMyCourse::class.java)?.findAll()) +// val ids = JsonArray() +// for (lib in myCourses) { +// ids.add(lib.courseId) +// } +// return ids +// } +// } +//} \ No newline at end of file From bf5931f3860877ff4ed23e4b86a28b8a9bd86ae5 Mon Sep 17 00:00:00 2001 From: Gideon Okuro Date: Wed, 11 Dec 2024 14:07:17 +0300 Subject: [PATCH 16/38] migrate realmMyLibrary --- ...kotlin-compiler-1469149011553098994.salive | 0 .../planet/myplanet/model/RealmMyLibrary.kt | 348 +++++++++--------- 2 files changed, 179 insertions(+), 169 deletions(-) create mode 100644 .kotlin/sessions/kotlin-compiler-1469149011553098994.salive diff --git a/.kotlin/sessions/kotlin-compiler-1469149011553098994.salive b/.kotlin/sessions/kotlin-compiler-1469149011553098994.salive new file mode 100644 index 0000000000..e69de29bb2 diff --git a/app/src/main/java/org/ole/planet/myplanet/model/RealmMyLibrary.kt b/app/src/main/java/org/ole/planet/myplanet/model/RealmMyLibrary.kt index b360c194d3..8229e6d1a3 100644 --- a/app/src/main/java/org/ole/planet/myplanet/model/RealmMyLibrary.kt +++ b/app/src/main/java/org/ole/planet/myplanet/model/RealmMyLibrary.kt @@ -6,10 +6,12 @@ import com.google.gson.JsonArray import com.google.gson.JsonNull import com.google.gson.JsonObject import com.opencsv.CSVWriter -import io.realm.Realm -import io.realm.RealmList -import io.realm.RealmObject -import io.realm.annotations.PrimaryKey +import io.realm.kotlin.Realm +import io.realm.kotlin.ext.query +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 org.ole.planet.myplanet.MainApplication.Companion.context import org.ole.planet.myplanet.utilities.Constants.PREFS_NAME import org.ole.planet.myplanet.utilities.FileUtils @@ -21,48 +23,54 @@ import java.io.IOException import java.util.Calendar import java.util.Date -open class RealmMyLibrary : RealmObject() { +class RealmMyLibrary : RealmObject { @PrimaryKey - var id: String? = null - var _id: String? = null - var userId: RealmList? = null - private set - var resourceRemoteAddress: String? = null - var resourceLocalAddress: String? = null + var id: String = "" + var _id: String = "" + private var _userId: RealmList = realmListOf() + var resourceRemoteAddress: String = "" + var resourceLocalAddress: String = "" var resourceOffline: Boolean = false - var resourceId: String? = null - var _rev: String? = null - var downloadedRev: String? = null + var resourceId: String = "" + var _rev: String = "" + var downloadedRev: String = "" var needsOptimization: Boolean = false - var publisher: String? = null - var linkToLicense: String? = null - var addedBy: String? = null - var uploadDate: String? = null + var publisher: String = "" + var linkToLicense: String = "" + var addedBy: String = "" + var uploadDate: String = "" var createdDate: Long = 0 - var openWith: String? = null - var articleDate: String? = null - var kind: String? = null - var language: String? = null - var author: String? = null - var year: String? = null - var medium: String? = null - var title: String? = null - var averageRating: String? = null - var filename: String? = null - var mediaType: String? = null - var resourceType: String? = null - var description: String? = null - var translationAudioPath: String? = null + var openWith: String = "" + var articleDate: String = "" + var kind: String = "" + var language: String = "" + var author: String = "" + var year: String = "" + var medium: String = "" + var title: String = "" + var averageRating: String = "" + var filename: String = "" + var mediaType: String = "" + var resourceType: String = "" + var description: String = "" + var translationAudioPath: String = "" var sum: Int = 0 var timesRated: Int = 0 - var resourceFor: RealmList? = null - var subject: RealmList? = null - var level: RealmList? = null - var tag: RealmList? = null - var languages: RealmList? = null - var courseId: String? = null - var stepId: String? = null + var resourceFor: RealmList = realmListOf() + var subject: RealmList = realmListOf() + var level: RealmList = realmListOf() + var tag: RealmList = realmListOf() + var languages: RealmList = realmListOf() + var courseId: String = "" + var stepId: String = "" var isPrivate: Boolean = false + + var userId: RealmList + get() = _userId + private set(value) { + _userId = value + } + fun serializeResource(): JsonObject { return JsonObject().apply { addProperty("_id", _id) @@ -96,111 +104,107 @@ open class RealmMyLibrary : RealmObject() { add("_attachments", ob) } } - private fun RealmList?.toJsonArray(): JsonArray { + + private fun RealmList.toJsonArray(): JsonArray { return JsonArray().apply { - this@toJsonArray?.forEach { add(it) } + forEach { add(it) } } } - fun setUserId(userId: String?) { - if (userId.isNullOrBlank()) return - if (this.userId == null) { - this.userId = RealmList() - } - if (!this.userId!!.contains(userId)) { - this.userId?.add(userId) + fun setUserId(newUserId: String?) { + if (newUserId.isNullOrBlank()) return + + if (!_userId.contains(newUserId)) { + _userId.add(newUserId) } } + fun isResourceOffline(): Boolean { return resourceOffline && _rev == downloadedRev } - private fun JsonArray?.setListIfNotNull(targetList: RealmList?, setter: (String) -> Unit) { + + private fun JsonArray?.setListIfNotNull(targetList: RealmList, setter: (String) -> Unit) { this?.forEach { jsonElement -> val value = jsonElement.takeIf { it !is JsonNull }?.asString ?: return@forEach - if (value !in targetList.orEmpty()) { + if (value !in targetList) { setter(value) } } } - fun setResourceFor(array: JsonArray, resource: RealmMyLibrary?) { - array.setListIfNotNull(resource?.resourceFor) { resource?.resourceFor?.add(it) } + fun setResourceFor(array: JsonArray) { + array.setListIfNotNull(resourceFor) { resourceFor.add(it) } } - fun setSubject(array: JsonArray, resource: RealmMyLibrary?) { - array.setListIfNotNull(resource?.subject) { resource?.subject?.add(it) } + fun setSubject(array: JsonArray) { + array.setListIfNotNull(subject) { subject.add(it) } } - fun setLevel(array: JsonArray, resource: RealmMyLibrary?) { - array.setListIfNotNull(resource?.level) { resource?.level?.add(it) } + fun setLevel(array: JsonArray) { + array.setListIfNotNull(level) { level.add(it) } } - fun setTag(array: JsonArray, resource: RealmMyLibrary?) { - array.setListIfNotNull(resource?.tag) { resource?.tag?.add(it) } + fun setTag(array: JsonArray) { + array.setListIfNotNull(tag) { tag.add(it) } } - fun setLanguages(array: JsonArray, resource: RealmMyLibrary?) { - array.setListIfNotNull(resource?.languages) { resource?.languages?.add(it) } + fun setLanguages(array: JsonArray) { + array.setListIfNotNull(languages) { languages.add(it) } } - fun setUserId(userId: RealmList?) { - this.userId = userId + fun setUserId(userId: RealmList) { + this._userId = userId } val subjectsAsString: String - get() = subject?.joinToString(", ") ?: "" + get() = subject.joinToString(", ") override fun toString(): String { - return title ?: "" + return title } fun removeUserId(id: String?) { - userId?.remove(id) + _userId.remove(id) } fun needToUpdate(): Boolean { - return !resourceOffline || resourceLocalAddress != null && _rev != downloadedRev + return !resourceOffline || (resourceLocalAddress.isNotBlank() && _rev != downloadedRev) } companion object { val libraryDataList: MutableList> = mutableListOf() - fun getMyLibraryByUserId(mRealm: Realm, settings: SharedPreferences?): List { - val libs = mRealm.where(RealmMyLibrary::class.java).findAll() - return getMyLibraryByUserId(settings?.getString("userId", "--"), libs, mRealm) + fun getMyLibraryByUserId(realm: Realm, settings: SharedPreferences?): List { + val libs = realm.query().find() + return getMyLibraryByUserId(settings?.getString("userId", "--"), libs) } - fun getMyLibraryByUserId(userId: String?, libs: List, mRealm: Realm): List { - val ids = RealmMyTeam.getResourceIdsByUser(userId, mRealm) - return libs.filter { it.userId?.contains(userId) == true || it.resourceId in ids } + fun getMyLibraryByUserId(userId: String, libs: List, realm: Realm): List { + val ids = RealmMyTeam.getResourceIdsByUser(userId, realm) + return libs.filter { it.userId.contains(userId) || it.resourceId in ids } } - @JvmStatic fun getMyLibraryByUserId(userId: String?, libs: List): List { - return libs.filter { it.userId?.contains(userId) == true } + return libs.filter { it.userId.contains(userId) } } - @JvmStatic fun getOurLibrary(userId: String?, libs: List): List { - return libs.filter { it.userId?.contains(userId) == false } + return libs.filter { !it.userId.contains(userId) } } - private fun getIds(mRealm: Realm): Array { - val list = mRealm.where(RealmMyLibrary::class.java).findAll() - return list.map { it.resourceId }.toTypedArray() + private fun getIds(realm: Realm): Array { + return realm.query().find().map { it.resourceId }.toTypedArray() } - @JvmStatic - fun removeDeletedResource(newIds: List, mRealm: Realm) { - val ids = getIds(mRealm) + suspend fun removeDeletedResource(newIds: List, realm: Realm) { + val ids = getIds(realm) ids.filterNot { it in newIds }.forEach { id -> - mRealm.executeTransaction { realm -> - realm.where(RealmMyLibrary::class.java).equalTo("resourceId", id).findAll().deleteAllFromRealm() + realm.write { + query("resourceId == $0", id).find().forEach { delete(it) } } } } - @JvmStatic fun serialize(personal: RealmMyLibrary, user: RealmUserModel?): JsonObject { return JsonObject().apply { addProperty("title", personal.title) @@ -230,88 +234,83 @@ open class RealmMyLibrary : RealmObject() { } } - private fun insertResources(doc: JsonObject, mRealm: Realm) { - insertMyLibrary("", doc, mRealm) + private suspend fun insertResources(doc: JsonObject, realm: Realm) { + insertMyLibrary("", doc, realm) } - @JvmStatic - fun createStepResource(mRealm: Realm, res: JsonObject, myCoursesID: String?, stepId: String?) { - insertMyLibrary("", stepId, myCoursesID, res, mRealm) + suspend fun createStepResource(realm: Realm, res: JsonObject, myCoursesID: String?, stepId: String?) { + insertMyLibrary("", stepId, myCoursesID, res, realm) } - @JvmStatic - fun insertMyLibrary(userId: String?, doc: JsonObject, mRealm: Realm) { - insertMyLibrary(userId, "", "", doc, mRealm) + suspend fun insertMyLibrary(userId: String?, doc: JsonObject, realm: Realm) { + insertMyLibrary(userId, "", "", doc, realm) } - @JvmStatic - fun createFromResource(resource: RealmMyLibrary?, mRealm: Realm, userId: String?) { - if (!mRealm.isInTransaction) { - mRealm.beginTransaction() + suspend fun createFromResource(resource: RealmMyLibrary?, realm: Realm, userId: String?) { + realm.write { + resource?.setUserId(userId) } - resource?.setUserId(userId) - mRealm.commitTransaction() } - @JvmStatic - fun insertMyLibrary(userId: String?, stepId: String?, courseId: String?, doc: JsonObject, mRealm: Realm) { - if (!mRealm.isInTransaction) { - mRealm.beginTransaction() - } + suspend fun insertMyLibrary(userId: String?, stepId: String?, courseId: String?, doc: JsonObject, realm: Realm) { val resourceId = JsonUtils.getString("_id", doc) val settings = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE) - var resource = mRealm.where(RealmMyLibrary::class.java).equalTo("id", resourceId).findFirst() - if (resource == null) { - resource = mRealm.createObject(RealmMyLibrary::class.java, resourceId) - } - resource?.apply { - setUserId(userId) - _id = resourceId - if (!stepId.isNullOrBlank()) { - this.stepId = stepId - } - if (!courseId.isNullOrBlank()) { - this.courseId = courseId + + realm.write { + var resource = query("id == $0", resourceId).first().find() + if (resource == null) { + resource = RealmMyLibrary().apply { id = resourceId } + copyToRealm(resource) } - _rev = JsonUtils.getString("_rev", doc) - this.resourceId = resourceId - title = JsonUtils.getString("title", doc) - description = JsonUtils.getString("description", doc) - if (doc.has("_attachments")) { - val attachments = doc["_attachments"].asJsonObject - attachments.entrySet().forEach { (key, _) -> - if (key.indexOf("/") < 0) { - resourceRemoteAddress = "${settings.getString("couchdbURL", "http://")}/resources/$resourceId/$key" - resourceLocalAddress = key - resourceOffline = FileUtils.checkFileExist(resourceRemoteAddress) + + resource.apply { + setUserId(userId) + _id = resourceId + if (!stepId.isNullOrBlank()) { + this.stepId = stepId + } + if (!courseId.isNullOrBlank()) { + this.courseId = courseId + } + _rev = JsonUtils.getString("_rev", doc) + this.resourceId = resourceId + title = JsonUtils.getString("title", doc) + description = JsonUtils.getString("description", doc) + if (doc.has("_attachments")) { + val attachments = doc["_attachments"].asJsonObject + attachments.entrySet().forEach { (key, _) -> + if (key.indexOf("/") < 0) { + resourceRemoteAddress = "${settings.getString("couchdbURL", "http://")}/resources/$resourceId/$key" + resourceLocalAddress = key + resourceOffline = FileUtils.checkFileExist(resourceRemoteAddress) + } } } + filename = JsonUtils.getString("filename", doc) + averageRating = JsonUtils.getString("averageRating", doc) + uploadDate = JsonUtils.getString("uploadDate", doc) + year = JsonUtils.getString("year", doc) + addedBy = JsonUtils.getString("addedBy", doc) + publisher = JsonUtils.getString("publisher", doc) + linkToLicense = JsonUtils.getString("linkToLicense", doc) + openWith = JsonUtils.getString("openWith", doc) + articleDate = JsonUtils.getString("articleDate", doc) + kind = JsonUtils.getString("kind", doc) + createdDate = JsonUtils.getLong("createdDate", doc) + language = JsonUtils.getString("language", doc) + author = JsonUtils.getString("author", doc) + mediaType = JsonUtils.getString("mediaType", doc) + resourceType = JsonUtils.getString("resourceType", doc) + timesRated = JsonUtils.getInt("timesRated", doc) + medium = JsonUtils.getString("medium", doc) + setResourceFor(JsonUtils.getJsonArray("resourceFor", doc)) + setSubject(JsonUtils.getJsonArray("subject", doc)) + setLevel(JsonUtils.getJsonArray("level", doc)) + setTag(JsonUtils.getJsonArray("tags", doc)) + isPrivate = JsonUtils.getBoolean("private", doc) + setLanguages(JsonUtils.getJsonArray("languages", doc)) } - filename = JsonUtils.getString("filename", doc) - averageRating = JsonUtils.getString("averageRating", doc) - uploadDate = JsonUtils.getString("uploadDate", doc) - year = JsonUtils.getString("year", doc) - addedBy = JsonUtils.getString("addedBy", doc) - publisher = JsonUtils.getString("publisher", doc) - linkToLicense = JsonUtils.getString("linkToLicense", doc) - openWith = JsonUtils.getString("openWith", doc) - articleDate = JsonUtils.getString("articleDate", doc) - kind = JsonUtils.getString("kind", doc) - createdDate = JsonUtils.getLong("createdDate", doc) - language = JsonUtils.getString("language", doc) - author = JsonUtils.getString("author", doc) - mediaType = JsonUtils.getString("mediaType", doc) - resourceType = JsonUtils.getString("resourceType", doc) - timesRated = JsonUtils.getInt("timesRated", doc) - medium = JsonUtils.getString("medium", doc) - setResourceFor(JsonUtils.getJsonArray("resourceFor", doc), this) - setSubject(JsonUtils.getJsonArray("subject", doc), this) - setLevel(JsonUtils.getJsonArray("level", doc), this) - setTag(JsonUtils.getJsonArray("tags", doc), this) - isPrivate = JsonUtils.getBoolean("private", doc) - setLanguages(JsonUtils.getJsonArray("languages", doc), this) } - mRealm.commitTransaction() val csvRow = arrayOf( JsonUtils.getString("_id", doc), @@ -356,7 +355,14 @@ open class RealmMyLibrary : RealmObject() { val file = File(filePath) file.parentFile?.mkdirs() CSVWriter(FileWriter(file)).use { writer -> - writer.writeNext(arrayOf("libraryId", "library_rev", "title", "description", "resourceRemoteAddress", "resourceLocalAddress", "resourceOffline", "resourceId", "addedBy", "uploadDate", "createdDate", "openWith", "articleDate", "kind", "language", "author", "year", "medium", "filename", "mediaType", "resourceType", "timesRated", "averageRating", "publisher", "linkToLicense", "subject", "level", "tags", "languages", "courseId", "stepId", "downloaded", "private")) + writer.writeNext(arrayOf("libraryId", "library_rev", "title", "description", + "resourceRemoteAddress", "resourceLocalAddress", "resourceOffline", + "resourceId", "addedBy", "uploadDate", "createdDate", "openWith", + "articleDate", "kind", "language", "author", "year", "medium", "filename", + "mediaType", "resourceType", "timesRated", "averageRating", "publisher", + "linkToLicense", "subject", "level", "tags", "languages", "courseId", + "stepId", "downloaded", "private" + )) data.forEach { row -> writer.writeNext(row) } @@ -370,44 +376,48 @@ open class RealmMyLibrary : RealmObject() { writeCsv("${context.getExternalFilesDir(null)}/ole/library.csv", libraryDataList) } - @JvmStatic - fun listToString(list: RealmList?): String { - return list?.joinToString(", ") ?: "" + fun listToString(list: RealmList): String { + return list.joinToString(", ") } - @JvmStatic - fun save(allDocs: JsonArray, mRealm: Realm): List { - val list: MutableList = ArrayList() + suspend fun save(allDocs: JsonArray, realm: Realm): List { + val list = mutableListOf() allDocs.forEach { doc -> val document = JsonUtils.getJsonObject("doc", doc.asJsonObject) val id = JsonUtils.getString("_id", document) if (!id.startsWith("_design")) { list.add(id) - insertResources(document, mRealm) + insertResources(document, realm) } } return list } - @JvmStatic fun getMyLibIds(realm: Realm?, userId: String?): JsonArray { - val myLibraries = userId?.let { realm?.where(RealmMyLibrary::class.java)?.contains("userId", it)?.findAll() } - return JsonArray().apply { myLibraries?.forEach { lib -> add(lib.id) } + return JsonArray().apply { + userId?.let { + realm?.query("userId CONTAINS $0", it)?.find()?.forEach { lib -> + add(lib.id) + } + } } } - @JvmStatic + fun getLevels(libraries: List): Set { - return libraries.flatMap { it.level ?: emptyList() }.toSet() + return libraries.flatMap { it.level }.toSet() } - @JvmStatic - fun getArrayList(libraries: List, type: String): Set { - return libraries.mapNotNull { if (type == "mediums") it.mediaType else it.language }.filterNot { it.isNullOrBlank() }.toSet() + fun getArrayList(libraries: List, type: String): Set { + return libraries.map { + when (type) { + "mediums" -> it.mediaType + else -> it.language + } + }.filterNot { it.isBlank() }.toSet() } - @JvmStatic fun getSubjects(libraries: List): Set { - return libraries.flatMap { it.subject ?: emptyList() }.toSet() + return libraries.flatMap { it.subject }.toSet() } } } \ No newline at end of file From 1a85145d0da26c26a1d203cc11c2402fde905651 Mon Sep 17 00:00:00 2001 From: Gideon Okuro Date: Wed, 11 Dec 2024 14:26:37 +0300 Subject: [PATCH 17/38] migrate mainapplication --- ...kotlin-compiler-1469149011553098994.salive | 0 .../ole/planet/myplanet/MainApplication.kt | 75 +++++++++---------- 2 files changed, 36 insertions(+), 39 deletions(-) delete mode 100644 .kotlin/sessions/kotlin-compiler-1469149011553098994.salive diff --git a/.kotlin/sessions/kotlin-compiler-1469149011553098994.salive b/.kotlin/sessions/kotlin-compiler-1469149011553098994.salive deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/app/src/main/java/org/ole/planet/myplanet/MainApplication.kt b/app/src/main/java/org/ole/planet/myplanet/MainApplication.kt index 884ade4183..f9ad7e17ad 100644 --- a/app/src/main/java/org/ole/planet/myplanet/MainApplication.kt +++ b/app/src/main/java/org/ole/planet/myplanet/MainApplication.kt @@ -14,7 +14,7 @@ import androidx.preference.PreferenceManager import androidx.work.ExistingPeriodicWorkPolicy import androidx.work.PeriodicWorkRequest import androidx.work.WorkManager -import io.realm.Realm +import io.realm.kotlin.Realm import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob @@ -22,9 +22,7 @@ import kotlinx.coroutines.cancel import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch -import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withContext -import org.ole.planet.myplanet.MainApplication import org.ole.planet.myplanet.base.BaseResourceFragment.Companion.backgroundDownload import org.ole.planet.myplanet.base.BaseResourceFragment.Companion.getAllLibraryList import org.ole.planet.myplanet.callback.TeamPageListener @@ -56,7 +54,7 @@ class MainApplication : Application(), Application.ActivityLifecycleCallbacks { private const val STAY_ONLINE_WORK_TAG = "stayOnlineWork" private const val TASK_NOTIFICATION_WORK_TAG = "taskNotificationWork" lateinit var context: Context - lateinit var mRealm: Realm + lateinit var realm: Realm lateinit var service: DatabaseService var preferences: SharedPreferences? = null var syncFailedCount = 0 @@ -75,29 +73,27 @@ class MainApplication : Application(), Application.ActivityLifecycleCallbacks { val applicationScope = CoroutineScope(SupervisorJob() + Dispatchers.Default) lateinit var defaultPref: SharedPreferences - fun createLog(type: String) { - runBlocking { - withContext(Dispatchers.IO) { - val realm = Realm.getDefaultInstance() - try { - realm.executeTransaction { r -> - val log = r.createObject(RealmApkLog::class.java, "${UUID.randomUUID()}") + suspend fun createLog(type: String) { + withContext(Dispatchers.IO) { + try { + realm.write { + val log = RealmApkLog().apply { + id = UUID.randomUUID().toString() val model = UserProfileDbHandler(context).userModel if (model != null) { - log.parentCode = model.parentCode - log.createdOn = model.planetCode - log.userId = model.id + parentCode = model.parentCode + createdOn = model.planetCode + userId = model.id } - log.time = "${Date().time}" - log.page = "" - log.version = getVersionName(context) - log.type = type + time = Date().time.toString() + page = "" + version = getVersionName(context) + this.type = type } - } catch (e: Exception) { - e.printStackTrace() - } finally { - realm.close() + copyToRealm(log) } + } catch (e: Exception) { + e.printStackTrace() } } } @@ -145,24 +141,22 @@ class MainApplication : Application(), Application.ActivityLifecycleCallbacks { e.printStackTrace() applicationScope.launch(Dispatchers.IO) { try { - val realm = Realm.getDefaultInstance() - try { - realm.executeTransaction { r -> - val log = r.createObject(RealmApkLog::class.java, "${UUID.randomUUID()}") + realm.write { + val log = RealmApkLog().apply { + id = UUID.randomUUID().toString() val model = UserProfileDbHandler(context).userModel if (model != null) { - log.parentCode = model.parentCode - log.createdOn = model.planetCode - log.userId = model.id + parentCode = model.parentCode + createdOn = model.planetCode + userId = model.id } - log.time = "${Date().time}" - log.page = "" - log.version = getVersionName(context) - log.type = RealmApkLog.ERROR_TYPE_CRASH - log.setError(e) + time = Date().time.toString() + page = "" + version = getVersionName(context) + type = RealmApkLog.ERROR_TYPE_CRASH + setError(e) } - } finally { - realm.close() + copyToRealm(log) } } catch (ex: Exception) { ex.printStackTrace() @@ -188,7 +182,7 @@ class MainApplication : Application(), Application.ActivityLifecycleCallbacks { preferences = getSharedPreferences(PREFS_NAME, MODE_PRIVATE) service = DatabaseService() - mRealm = service.realmInstance + realm = service.realmInstance defaultPref = PreferenceManager.getDefaultSharedPreferences(this) val builder = VmPolicy.Builder() @@ -205,7 +199,9 @@ class MainApplication : Application(), Application.ActivityLifecycleCallbacks { scheduleTaskNotificationWork() Thread.setDefaultUncaughtExceptionHandler { _: Thread?, e: Throwable -> - handleUncaughtException(e) + applicationScope.launch { + handleUncaughtException(e) + } } registerActivityLifecycleCallbacks(this) onAppStarted() @@ -225,7 +221,7 @@ class MainApplication : Application(), Application.ActivityLifecycleCallbacks { } if (canReachServer) { if (defaultPref.getBoolean("beta_auto_download", false)) { - backgroundDownload(downloadAllFiles(getAllLibraryList(mRealm))) + backgroundDownload(downloadAllFiles(getAllLibraryList(realm))) } } } @@ -326,6 +322,7 @@ class MainApplication : Application(), Application.ActivityLifecycleCallbacks { override fun onTerminate() { super.onTerminate() onAppClosed() + realm.close() applicationScope.cancel() } } From 28b82d081c56651c1ce16f0ae53ffc0b586cdbfc Mon Sep 17 00:00:00 2001 From: Gideon Okuro Date: Wed, 11 Dec 2024 16:06:11 +0300 Subject: [PATCH 18/38] cleanup --- .../myplanet/base/BaseContainerFragment.kt | 4 +- .../planet/myplanet/model/RealmMyCourse.kt | 312 +----------------- 2 files changed, 4 insertions(+), 312 deletions(-) diff --git a/app/src/main/java/org/ole/planet/myplanet/base/BaseContainerFragment.kt b/app/src/main/java/org/ole/planet/myplanet/base/BaseContainerFragment.kt index 83545b2d85..26a7a0ee10 100644 --- a/app/src/main/java/org/ole/planet/myplanet/base/BaseContainerFragment.kt +++ b/app/src/main/java/org/ole/planet/myplanet/base/BaseContainerFragment.kt @@ -225,8 +225,8 @@ abstract class BaseContainerFragment : BaseResourceFragment() { throw RuntimeException("Failed to create directory: " + directory.absolutePath) } } - val apkFile = items.resourceLocalAddress?.let { File(directory, it) } - if (apkFile != null) { + val apkFile = File(directory, items.resourceLocalAddress) + if (true) { if (!apkFile.exists()) { Utilities.toast(activity,"APK file not found") return diff --git a/app/src/main/java/org/ole/planet/myplanet/model/RealmMyCourse.kt b/app/src/main/java/org/ole/planet/myplanet/model/RealmMyCourse.kt index 73a4df6de3..22b5b1f5d5 100644 --- a/app/src/main/java/org/ole/planet/myplanet/model/RealmMyCourse.kt +++ b/app/src/main/java/org/ole/planet/myplanet/model/RealmMyCourse.kt @@ -115,7 +115,6 @@ class RealmMyCourse : RealmObject { copyToRealm(step) } - // Safely call suspend functions insertExam(stepJson, realm, stepId, i + 1, ID) insertSurvey(stepJson, realm, stepId, i + 1, ID, JsonUtils.getLong("createdDate", myCoursesDoc)) } @@ -204,7 +203,7 @@ class RealmMyCourse : RealmObject { } } - private fun insertCourseStepsAttachments(courseId: String, stepId: String, resources: JsonArray, realm: Realm) { + private suspend fun insertCourseStepsAttachments(courseId: String, stepId: String, resources: JsonArray, realm: Realm) { resources.forEach { resource -> createStepResource(realm, resource.asJsonObject, courseId, stepId) } @@ -258,311 +257,4 @@ class RealmMyCourse : RealmObject { } } } -} - - -//package org.ole.planet.myplanet.model -// -//import android.content.Context.MODE_PRIVATE -//import android.content.SharedPreferences -//import android.text.TextUtils -//import android.util.Base64 -//import com.google.gson.Gson -//import com.google.gson.JsonArray -//import com.google.gson.JsonObject -//import com.opencsv.CSVWriter -//import io.realm.Realm -//import io.realm.RealmList -//import io.realm.RealmObject -//import io.realm.RealmResults -//import io.realm.annotations.PrimaryKey -//import io.realm.kotlin.where -//import org.ole.planet.myplanet.MainApplication.Companion.context -//import org.ole.planet.myplanet.model.RealmMyLibrary.Companion.createStepResource -//import org.ole.planet.myplanet.model.RealmStepExam.Companion.insertCourseStepsExams -//import org.ole.planet.myplanet.utilities.Constants.PREFS_NAME -//import org.ole.planet.myplanet.utilities.DownloadUtils.extractLinks -//import org.ole.planet.myplanet.utilities.JsonUtils -//import org.ole.planet.myplanet.utilities.Utilities -//import java.io.File -//import java.io.FileWriter -//import java.io.IOException -// -//open class RealmMyCourse : RealmObject() { -// @PrimaryKey -// var id: String? = null -// var userId: RealmList? = null -// private set -// var courseId: String? = null -// var courseRev: String? = null -// var languageOfInstruction: String? = null -// var courseTitle: String? = null -// var memberLimit: Int? = null -// var description: String? = null -// var method: String? = null -// var gradeLevel: String? = null -// var subjectLevel: String? = null -// var createdDate: Long = 0 -// private var numberOfSteps: Int? = null -// var courseSteps: RealmList? = null -// @Transient -// var isMyCourse: Boolean = false -// fun setUserId(userId: String?) { -// if (this.userId == null) { -// this.userId = RealmList() -// } -// if (!this.userId?.contains(userId)!! && !TextUtils.isEmpty(userId)) { -// this.userId?.add(userId) -// } -// } -// -// fun removeUserId(userId: String?) { -// this.userId?.remove(userId) -// } -// -// fun getNumberOfSteps(): Int { -// return numberOfSteps ?: 0 -// } -// -// fun setNumberOfSteps(numberOfSteps: Int?) { -// this.numberOfSteps = numberOfSteps -// } -// -// override fun toString(): String { -// return courseTitle ?: "" -// } -// -// companion object { -// private val gson = Gson() -// private val concatenatedLinks = ArrayList() -// val courseDataList: MutableList> = mutableListOf() -// -// @JvmStatic -// fun insertMyCourses(userId: String?, myCoursesDoc: JsonObject?, mRealm: Realm) { -// context.getSharedPreferences(PREFS_NAME, MODE_PRIVATE) -// if (!mRealm.isInTransaction) { -// mRealm.beginTransaction() -// } -// val id = JsonUtils.getString("_id", myCoursesDoc) -// var myMyCoursesDB = mRealm.where(RealmMyCourse::class.java).equalTo("id", id).findFirst() -// if (myMyCoursesDB == null) { -// myMyCoursesDB = mRealm.createObject(RealmMyCourse::class.java, id) -// } -// myMyCoursesDB?.setUserId(userId) -// myMyCoursesDB?.courseId = JsonUtils.getString("_id", myCoursesDoc) -// myMyCoursesDB?.courseRev = JsonUtils.getString("_rev", myCoursesDoc) -// myMyCoursesDB?.languageOfInstruction = JsonUtils.getString("languageOfInstruction", myCoursesDoc) -// myMyCoursesDB?.courseTitle = JsonUtils.getString("courseTitle", myCoursesDoc) -// myMyCoursesDB?.memberLimit = JsonUtils.getInt("memberLimit", myCoursesDoc) -// myMyCoursesDB?.description = JsonUtils.getString("description", myCoursesDoc) -// val description = JsonUtils.getString("description", myCoursesDoc) -// val links = extractLinks(description) -// val baseUrl = Utilities.getUrl() -// for (link in links) { -// val concatenatedLink = "$baseUrl/$link" -// concatenatedLinks.add(concatenatedLink) -// } -// myMyCoursesDB?.method = JsonUtils.getString("method", myCoursesDoc) -// myMyCoursesDB?.gradeLevel = JsonUtils.getString("gradeLevel", myCoursesDoc) -// myMyCoursesDB?.subjectLevel = JsonUtils.getString("subjectLevel", myCoursesDoc) -// myMyCoursesDB?.createdDate = JsonUtils.getLong("createdDate", myCoursesDoc) -// myMyCoursesDB?.setNumberOfSteps(JsonUtils.getJsonArray("steps", myCoursesDoc).size()) -// val courseStepsJsonArray = JsonUtils.getJsonArray("steps", myCoursesDoc) -// val courseStepsList = mutableListOf() -// -// for (i in 0 until courseStepsJsonArray.size()) { -// val stepId = Base64.encodeToString(courseStepsJsonArray[i].toString().toByteArray(), Base64.NO_WRAP) -// val stepJson = courseStepsJsonArray[i].asJsonObject -// val step = RealmCourseStep() -// step.id = stepId -// step.stepTitle = JsonUtils.getString("stepTitle", stepJson) -// step.description = JsonUtils.getString("description", stepJson) -// val stepDescription = JsonUtils.getString("description", stepJson) -// val stepLinks = extractLinks(stepDescription) -// for (stepLink in stepLinks) { -// val concatenatedLink = "$baseUrl/$stepLink" -// concatenatedLinks.add(concatenatedLink) -// } -// insertCourseStepsAttachments(myMyCoursesDB?.courseId, stepId, JsonUtils.getJsonArray("resources", stepJson), mRealm) -// insertExam(stepJson, mRealm, stepId, i + 1, myMyCoursesDB?.courseId) -// insertSurvey(stepJson, mRealm, stepId, i + 1, myMyCoursesDB?.courseId, myMyCoursesDB?.createdDate) -// step.noOfResources = JsonUtils.getJsonArray("resources", stepJson).size() -// step.courseId = myMyCoursesDB?.courseId -// courseStepsList.add(step) -// } -// -// if (mRealm.isInTransaction) { -// mRealm.commitTransaction() -// } -// -// if (!mRealm.isInTransaction) { -// mRealm.beginTransaction() -// } -// myMyCoursesDB?.courseSteps = RealmList() -// myMyCoursesDB?.courseSteps?.addAll(courseStepsList) -// mRealm.commitTransaction() -// -// val csvRow = arrayOf( -// JsonUtils.getString("_id", myCoursesDoc), -// JsonUtils.getString("_rev", myCoursesDoc), -// JsonUtils.getString("languageOfInstruction", myCoursesDoc), -// JsonUtils.getString("courseTitle", myCoursesDoc), -// JsonUtils.getInt("memberLimit", myCoursesDoc).toString(), -// JsonUtils.getString("description", myCoursesDoc), -// JsonUtils.getString("method", myCoursesDoc), -// JsonUtils.getString("gradeLevel", myCoursesDoc), -// JsonUtils.getString("subjectLevel", myCoursesDoc), -// JsonUtils.getLong("createdDate", myCoursesDoc).toString(), -// JsonUtils.getJsonArray("steps", myCoursesDoc).toString() -// ) -// courseDataList.add(csvRow) -// } -// -// fun writeCsv(filePath: String, data: List>) { -// try { -// val file = File(filePath) -// file.parentFile?.mkdirs() -// val writer = CSVWriter(FileWriter(file)) -// writer.writeNext(arrayOf("courseId", "course_rev", "languageOfInstruction", "courseTitle", "memberLimit", "description", "method", "gradeLevel", "subjectLevel", "createdDate", "steps")) -// for (row in data) { -// writer.writeNext(row) -// } -// writer.close() -// } catch (e: IOException) { -// e.printStackTrace() -// } -// } -// -// fun courseWriteCsv() { -// writeCsv("${context.getExternalFilesDir(null)}/ole/course.csv", courseDataList) -// } -// -// @JvmStatic -// fun saveConcatenatedLinksToPrefs() { -// val settings: SharedPreferences = context.getSharedPreferences(PREFS_NAME, MODE_PRIVATE) -// val existingJsonLinks = settings.getString("concatenated_links", null) -// val existingConcatenatedLinks = if (existingJsonLinks != null) { -// gson.fromJson(existingJsonLinks, Array::class.java).toMutableList() -// } else { -// mutableListOf() -// } -// val linksToProcess: List -// synchronized(concatenatedLinks) { -// linksToProcess = concatenatedLinks.toList() -// } -// for (link in linksToProcess) { -// if (!existingConcatenatedLinks.contains(link)) { -// existingConcatenatedLinks.add(link) -// } -// } -// val jsonConcatenatedLinks = gson.toJson(existingConcatenatedLinks) -// settings.edit().putString("concatenated_links", jsonConcatenatedLinks).apply() -// } -// -// fun getCourseSteps(mRealm: Realm, courseId: String?): List { -// val myCourse = mRealm.where().equalTo("id", courseId).findFirst() -// val courseSteps = myCourse?.courseSteps ?: emptyList() -// return courseSteps -// } -// -// fun getCourseStepIds(mRealm: Realm, courseId: String?): Array { -// val course = mRealm.where().equalTo("courseId", courseId).findFirst() -// val stepIds = course?.courseSteps?.map { it.id }?.toTypedArray() ?: emptyArray() -// return stepIds -// } -// -// private fun insertExam(stepContainer: JsonObject, mRealm: Realm, stepId: String, i: Int, myCoursesID: String?) { -// if (stepContainer.has("exam")) { -// val `object` = stepContainer.getAsJsonObject("exam") -// `object`.addProperty("stepNumber", i) -// insertCourseStepsExams(myCoursesID, stepId, `object`, mRealm) -// } -// } -// -// private fun insertSurvey(stepContainer: JsonObject, mRealm: Realm, stepId: String, i: Int, myCoursesID: String?, createdDate: Long?) { -// if (stepContainer.has("survey")) { -// val `object` = stepContainer.getAsJsonObject("survey") -// `object`.addProperty("stepNumber", i) -// `object`.addProperty("createdDate", createdDate) -// insertCourseStepsExams(myCoursesID, stepId, `object`, mRealm) -// } -// } -// -// private fun insertCourseStepsAttachments(myCoursesID: String?, stepId: String?, resources: JsonArray, mRealm: Realm?) { -// resources.forEach { resource -> -// if (mRealm != null) { -// createStepResource(mRealm, resource.asJsonObject, myCoursesID, stepId) -// } -// } -// } -// -// @JvmStatic -// fun getMyByUserId(mRealm: Realm, settings: SharedPreferences?): RealmResults { -// val userId = settings?.getString("userId", "--") -// return mRealm.where(RealmMyCourse::class.java) -// .equalTo("userId", userId) -// .findAll() -// } -// -// @JvmStatic -// fun getMyCourseByUserId(userId: String?, libs: List?): List { -// val libraries: MutableList = ArrayList() -// for (item in libs ?: emptyList()) { -// if (item.userId?.contains(userId) == true) { -// libraries.add(item) -// } -// } -// return libraries -// } -// -// @JvmStatic -// fun getOurCourse(userId: String?, libs: List): List { -// val libraries: MutableList = ArrayList() -// for (item in libs) { -// if (!item.userId?.contains(userId)!!) { -// libraries.add(item) -// } -// } -// return libraries -// } -// -// @JvmStatic -// fun isMyCourse(userId: String?, courseId: String?, realm: Realm): Boolean { -// return getMyCourseByUserId(userId, realm.where(RealmMyCourse::class.java).equalTo("courseId", courseId).findAll()).isNotEmpty() -// } -// -// @JvmStatic -// fun getCourseByCourseId(courseId: String, mRealm: Realm): RealmMyCourse? { -// return mRealm.where(RealmMyCourse::class.java).equalTo("courseId", courseId).findFirst() -// } -// -// @JvmStatic -// fun insert(mRealm: Realm, myCoursesDoc: JsonObject?) { -// insertMyCourses("", myCoursesDoc, mRealm) -// } -// -// @JvmStatic -// fun getMyCourse(mRealm: Realm, id: String?): RealmMyCourse? { -// return mRealm.where(RealmMyCourse::class.java).equalTo("courseId", id).findFirst() -// } -// -// @JvmStatic -// fun createMyCourse(course: RealmMyCourse?, mRealm: Realm, id: String?) { -// if (!mRealm.isInTransaction) { -// mRealm.beginTransaction() -// } -// course?.setUserId(id) -// mRealm.commitTransaction() -// } -// -// @JvmStatic -// fun getMyCourseIds(realm: Realm?, userId: String?): JsonArray { -// val myCourses = getMyCourseByUserId(userId, realm?.where(RealmMyCourse::class.java)?.findAll()) -// val ids = JsonArray() -// for (lib in myCourses) { -// ids.add(lib.courseId) -// } -// return ids -// } -// } -//} \ No newline at end of file +} \ No newline at end of file From 6de988b110c440145955a567375bd41c3ee17dc3 Mon Sep 17 00:00:00 2001 From: Gideon Okuro Date: Wed, 11 Dec 2024 16:28:28 +0300 Subject: [PATCH 19/38] migrate baseContainer fragment --- .../myplanet/base/BaseContainerFragment.kt | 117 ++++++++-------- .../base/BaseContainerFragment.kt.lite | 129 +++++++++--------- 2 files changed, 124 insertions(+), 122 deletions(-) diff --git a/app/src/main/java/org/ole/planet/myplanet/base/BaseContainerFragment.kt b/app/src/main/java/org/ole/planet/myplanet/base/BaseContainerFragment.kt index 26a7a0ee10..142fce3fdd 100644 --- a/app/src/main/java/org/ole/planet/myplanet/base/BaseContainerFragment.kt +++ b/app/src/main/java/org/ole/planet/myplanet/base/BaseContainerFragment.kt @@ -22,7 +22,9 @@ import androidx.appcompat.app.AlertDialog import androidx.appcompat.view.ContextThemeWrapper import androidx.appcompat.widget.AppCompatRatingBar import androidx.core.content.FileProvider +import androidx.lifecycle.lifecycleScope import com.google.gson.JsonObject +import kotlinx.coroutines.launch import org.ole.planet.myplanet.MainApplication import org.ole.planet.myplanet.R import org.ole.planet.myplanet.base.PermissionActivity.Companion.hasInstallPermission @@ -110,35 +112,33 @@ abstract class BaseContainerFragment : BaseResourceFragment() { } private fun openIntent(items: RealmMyLibrary, typeClass: Class<*>?) { val fileOpenIntent = Intent(activity, typeClass) - if (items.resourceLocalAddress?.contains("ole/audio") == true || items.resourceLocalAddress?.contains("ole/video") == true) { + if (items.resourceLocalAddress.contains("ole/audio") == true || items.resourceLocalAddress.contains("ole/video") == true) { fileOpenIntent.putExtra("TOUCHED_FILE", items.resourceLocalAddress) fileOpenIntent.putExtra("RESOURCE_TITLE", items.title) } else { - fileOpenIntent.putExtra("TOUCHED_FILE", items.id + "/" + items.resourceLocalAddress) + fileOpenIntent.putExtra("TOUCHED_FILE", "${items.id}/${items.resourceLocalAddress}") fileOpenIntent.putExtra("RESOURCE_TITLE", items.title) } startActivity(fileOpenIntent) } private fun openPdf(item: RealmMyLibrary) { val fileOpenIntent = Intent(activity, PDFReaderActivity::class.java) - fileOpenIntent.putExtra("TOUCHED_FILE", item.id + "/" + item.resourceLocalAddress) + fileOpenIntent.putExtra("TOUCHED_FILE", "${item.id}/${item.resourceLocalAddress}") fileOpenIntent.putExtra("resourceId", item.id) startActivity(fileOpenIntent) } fun openResource(items: RealmMyLibrary) { - val matchingItems = mRealm.where(RealmMyLibrary::class.java) - .equalTo("resourceLocalAddress", items.resourceLocalAddress) - .findAll() + val matchingItems = MainApplication.realm.query(RealmMyLibrary::class, "resourceLocalAddress == $0", items.resourceLocalAddress).find() val anyOffline = matchingItems.any { it.isResourceOffline() } if (anyOffline) { - val offlineItem = matchingItems.first { it.isResourceOffline()} + val offlineItem = matchingItems.first { it.isResourceOffline() } openFileType(offlineItem, "offline") } else { if (items.isResourceOffline()) { openFileType(items, "offline") } else if (FileUtils.getFileExtension(items.resourceLocalAddress) == "mp4") { - openFileType(items, "online") + openFileType(items, "online") } else { val arrayList = ArrayList() arrayList.add(Utilities.getUrl(items)) @@ -149,71 +149,72 @@ abstract class BaseContainerFragment : BaseResourceFragment() { } private fun checkFileExtension(items: RealmMyLibrary) { - val filenameArray = items.resourceLocalAddress?.split("\\.".toRegex())?.toTypedArray() - val extension = filenameArray?.get(filenameArray.size - 1) + val filenameArray = items.resourceLocalAddress.split("\\.".toRegex()).toTypedArray() + val extension = filenameArray[filenameArray.size - 1] val mimetype = Utilities.getMimeType(items.resourceLocalAddress) val userId = "${model?.id}" - val existingAction = mRealm.where(RealmUserChallengeActions::class.java) - .equalTo("userId", userId) - .equalTo("resourceId", items.resourceId) - .findFirst() + val existingAction = MainApplication.realm.query(RealmUserChallengeActions::class, "userId == $0 AND resourceId == $1", userId, items.resourceId).first().find() - if (mimetype != null) { - if (mimetype.contains("image")) { - openIntent(items, ImageViewerActivity::class.java) - if (existingAction == null) { - createAction(mRealm, userId, items.resourceId, "resourceOpen") + lifecycleScope.launch { + if (mimetype != null) { + when { + mimetype.contains("image") -> { + openIntent(items, ImageViewerActivity::class.java) + if (existingAction == null) { + createAction(MainApplication.realm, userId, items.resourceId, "resourceOpen") + } + } + mimetype.contains("pdf") -> { + openPdf(items) + if (existingAction == null) { + createAction(MainApplication.realm, userId, items.resourceId, "resourceOpen") + } + } + mimetype.contains("audio") -> { + openIntent(items, AudioPlayerActivity::class.java) + if (existingAction == null) { + createAction(MainApplication.realm, userId, items.resourceId, "resourceOpen") + } + } + else -> checkMoreFileExtensions(extension, items) } - } else if (mimetype.contains("pdf")) { - openPdf(items) - if (existingAction == null) { - createAction(mRealm, userId, items.resourceId, "resourceOpen") - } - } else if (mimetype.contains("audio")) { - openIntent(items, AudioPlayerActivity::class.java) - if (existingAction == null) { - createAction(mRealm, userId, items.resourceId, "resourceOpen") - } - } else { - checkMoreFileExtensions(extension, items) } } } private fun checkMoreFileExtensions(extension: String?, items: RealmMyLibrary) { val userId = "${model?.id}" - val existingAction = mRealm.where(RealmUserChallengeActions::class.java) - .equalTo("userId", userId) - .equalTo("resourceId", items.resourceId) - .findFirst() + val existingAction = MainApplication.realm.query(RealmUserChallengeActions::class, "userId == $0 AND resourceId == $1", userId, items.resourceId).first().find() - when (extension) { - "txt" -> { - if (existingAction == null) { - createAction(mRealm, userId, items.resourceId, "resourceOpen") + lifecycleScope.launch { + when (extension) { + "txt" -> { + if (existingAction == null) { + createAction(MainApplication.realm, userId, items.resourceId, "resourceOpen") + } + openIntent(items, TextFileViewerActivity::class.java) } - openIntent(items, TextFileViewerActivity::class.java) - } - "md" -> { - if (existingAction == null) { - createAction(mRealm, userId, items.resourceId, "resourceOpen") + "md" -> { + if (existingAction == null) { + createAction(MainApplication.realm, userId, items.resourceId, "resourceOpen") + } + openIntent(items, MarkdownViewerActivity::class.java) } - openIntent(items, MarkdownViewerActivity::class.java) - } - "csv" -> { - if (existingAction == null) { - createAction(mRealm, userId, items.resourceId, "resourceOpen") + "csv" -> { + if (existingAction == null) { + createAction(MainApplication.realm, userId, items.resourceId, "resourceOpen") + } + openIntent(items, CSVViewerActivity::class.java) } - openIntent(items, CSVViewerActivity::class.java) - } - "apk" -> { - if (existingAction == null) { - createAction(mRealm, userId, items.resourceId, "resourceOpen") + "apk" -> { + if (existingAction == null) { + createAction(MainApplication.realm, userId, items.resourceId, "resourceOpen") + } + installApk(items) } - installApk(items) + else -> Toast.makeText(activity, getString(R.string.this_file_type_is_currently_unsupported), Toast.LENGTH_LONG).show() } - else -> Toast.makeText(activity, getString(R.string.this_file_type_is_currently_unsupported), Toast.LENGTH_LONG).show() } } @@ -232,7 +233,7 @@ abstract class BaseContainerFragment : BaseResourceFragment() { return } } - val uri = apkFile?.let { + val uri = apkFile.let { FileProvider.getUriForFile(MainApplication.context, "${MainApplication.context.packageName}.fileprovider", it) } val intent = Intent(Intent.ACTION_VIEW).apply { @@ -278,7 +279,7 @@ abstract class BaseContainerFragment : BaseResourceFragment() { bundle.putString("videoURL", "" + Utilities.getUrl(items)) bundle.putString("Auth", "" + auth) } else if (videoType == "offline") { - if (items.resourceRemoteAddress == null && items.resourceLocalAddress != null) { + if (false) { bundle.putString("videoURL", items.resourceLocalAddress) } else { bundle.putString("videoURL", "" + Uri.fromFile(File("" + FileUtils.getSDPathFromUrl(items.resourceRemoteAddress)))) diff --git a/app/src/main/java/org/ole/planet/myplanet/base/BaseContainerFragment.kt.lite b/app/src/main/java/org/ole/planet/myplanet/base/BaseContainerFragment.kt.lite index 8a64f08109..66dfe37379 100644 --- a/app/src/main/java/org/ole/planet/myplanet/base/BaseContainerFragment.kt.lite +++ b/app/src/main/java/org/ole/planet/myplanet/base/BaseContainerFragment.kt.lite @@ -16,14 +16,16 @@ import android.widget.ArrayAdapter import android.widget.Button import android.widget.TextView import android.widget.Toast -import androidx.activity.result.ActivityResultLauncher -import androidx.activity.result.contract.ActivityResultContracts +//import androidx.activity.result.ActivityResultLauncher +//import androidx.activity.result.contract.ActivityResultContracts import androidx.appcompat.app.AlertDialog import androidx.appcompat.view.ContextThemeWrapper import androidx.appcompat.widget.AppCompatRatingBar //import androidx.core.content.FileProvider +import androidx.lifecycle.lifecycleScope import com.google.gson.JsonObject -//import org.ole.planet.myplanet.MainApplication +import kotlinx.coroutines.launch +import org.ole.planet.myplanet.MainApplication import org.ole.planet.myplanet.R //import org.ole.planet.myplanet.base.PermissionActivity.Companion.hasInstallPermission import org.ole.planet.myplanet.callback.OnHomeItemClickListener @@ -110,35 +112,33 @@ abstract class BaseContainerFragment : BaseResourceFragment() { } private fun openIntent(items: RealmMyLibrary, typeClass: Class<*>?) { val fileOpenIntent = Intent(activity, typeClass) - if (items.resourceLocalAddress?.contains("ole/audio") == true || items.resourceLocalAddress?.contains("ole/video") == true) { + if (items.resourceLocalAddress.contains("ole/audio") == true || items.resourceLocalAddress.contains("ole/video") == true) { fileOpenIntent.putExtra("TOUCHED_FILE", items.resourceLocalAddress) fileOpenIntent.putExtra("RESOURCE_TITLE", items.title) } else { - fileOpenIntent.putExtra("TOUCHED_FILE", items.id + "/" + items.resourceLocalAddress) + fileOpenIntent.putExtra("TOUCHED_FILE", "${items.id}/${items.resourceLocalAddress}") fileOpenIntent.putExtra("RESOURCE_TITLE", items.title) } startActivity(fileOpenIntent) } private fun openPdf(item: RealmMyLibrary) { val fileOpenIntent = Intent(activity, PDFReaderActivity::class.java) - fileOpenIntent.putExtra("TOUCHED_FILE", item.id + "/" + item.resourceLocalAddress) + fileOpenIntent.putExtra("TOUCHED_FILE", "${item.id}/${item.resourceLocalAddress}") fileOpenIntent.putExtra("resourceId", item.id) startActivity(fileOpenIntent) } fun openResource(items: RealmMyLibrary) { - val matchingItems = mRealm.where(RealmMyLibrary::class.java) - .equalTo("resourceLocalAddress", items.resourceLocalAddress) - .findAll() + val matchingItems = MainApplication.realm.query(RealmMyLibrary::class, "resourceLocalAddress == $0", items.resourceLocalAddress).find() val anyOffline = matchingItems.any { it.isResourceOffline() } if (anyOffline) { - val offlineItem = matchingItems.first { it.isResourceOffline()} + val offlineItem = matchingItems.first { it.isResourceOffline() } openFileType(offlineItem, "offline") } else { if (items.isResourceOffline()) { openFileType(items, "offline") } else if (FileUtils.getFileExtension(items.resourceLocalAddress) == "mp4") { - openFileType(items, "online") + openFileType(items, "online") } else { val arrayList = ArrayList() arrayList.add(Utilities.getUrl(items)) @@ -149,71 +149,72 @@ abstract class BaseContainerFragment : BaseResourceFragment() { } private fun checkFileExtension(items: RealmMyLibrary) { - val filenameArray = items.resourceLocalAddress?.split("\\.".toRegex())?.toTypedArray() - val extension = filenameArray?.get(filenameArray.size - 1) + val filenameArray = items.resourceLocalAddress.split("\\.".toRegex()).toTypedArray() + val extension = filenameArray[filenameArray.size - 1] val mimetype = Utilities.getMimeType(items.resourceLocalAddress) val userId = "${model?.id}" - val existingAction = mRealm.where(RealmUserChallengeActions::class.java) - .equalTo("userId", userId) - .equalTo("resourceId", items.resourceId) - .findFirst() + val existingAction = MainApplication.realm.query(RealmUserChallengeActions::class, "userId == $0 AND resourceId == $1", userId, items.resourceId).first().find() - if (mimetype != null) { - if (mimetype.contains("image")) { - openIntent(items, ImageViewerActivity::class.java) - if (existingAction == null) { - createAction(mRealm, userId, items.resourceId, "resourceOpen") + lifecycleScope.launch { + if (mimetype != null) { + when { + mimetype.contains("image") -> { + openIntent(items, ImageViewerActivity::class.java) + if (existingAction == null) { + createAction(MainApplication.realm, userId, items.resourceId, "resourceOpen") + } + } + mimetype.contains("pdf") -> { + openPdf(items) + if (existingAction == null) { + createAction(MainApplication.realm, userId, items.resourceId, "resourceOpen") + } + } + mimetype.contains("audio") -> { + openIntent(items, AudioPlayerActivity::class.java) + if (existingAction == null) { + createAction(MainApplication.realm, userId, items.resourceId, "resourceOpen") + } + } + else -> checkMoreFileExtensions(extension, items) } - } else if (mimetype.contains("pdf")) { - openPdf(items) - if (existingAction == null) { - createAction(mRealm, userId, items.resourceId, "resourceOpen") - } - } else if (mimetype.contains("audio")) { - openIntent(items, AudioPlayerActivity::class.java) - if (existingAction == null) { - createAction(mRealm, userId, items.resourceId, "resourceOpen") - } - } else { - checkMoreFileExtensions(extension, items) } } } private fun checkMoreFileExtensions(extension: String?, items: RealmMyLibrary) { val userId = "${model?.id}" - val existingAction = mRealm.where(RealmUserChallengeActions::class.java) - .equalTo("userId", userId) - .equalTo("resourceId", items.resourceId) - .findFirst() + val existingAction = MainApplication.realm.query(RealmUserChallengeActions::class, "userId == $0 AND resourceId == $1", userId, items.resourceId).first().find() - when (extension) { - "txt" -> { - if (existingAction == null) { - createAction(mRealm, userId, items.resourceId, "resourceOpen") + lifecycleScope.launch { + when (extension) { + "txt" -> { + if (existingAction == null) { + createAction(MainApplication.realm, userId, items.resourceId, "resourceOpen") + } + openIntent(items, TextFileViewerActivity::class.java) } - openIntent(items, TextFileViewerActivity::class.java) - } - "md" -> { - if (existingAction == null) { - createAction(mRealm, userId, items.resourceId, "resourceOpen") + "md" -> { + if (existingAction == null) { + createAction(MainApplication.realm, userId, items.resourceId, "resourceOpen") + } + openIntent(items, MarkdownViewerActivity::class.java) } - openIntent(items, MarkdownViewerActivity::class.java) - } - "csv" -> { - if (existingAction == null) { - createAction(mRealm, userId, items.resourceId, "resourceOpen") + "csv" -> { + if (existingAction == null) { + createAction(MainApplication.realm, userId, items.resourceId, "resourceOpen") + } + openIntent(items, CSVViewerActivity::class.java) } - openIntent(items, CSVViewerActivity::class.java) - } -// "apk" -> { -// if (existingAction == null) { -// createAction(mRealm, userId, items.resourceId, "resourceOpen") +// "apk" -> { +// if (existingAction == null) { +// createAction(MainApplication.realm, userId, items.resourceId, "resourceOpen") +// } +// installApk(items) // } -// installApk(items) -// } - else -> Toast.makeText(activity, getString(R.string.this_file_type_is_currently_unsupported), Toast.LENGTH_LONG).show() + else -> Toast.makeText(activity, getString(R.string.this_file_type_is_currently_unsupported), Toast.LENGTH_LONG).show() + } } } @@ -225,14 +226,14 @@ abstract class BaseContainerFragment : BaseResourceFragment() { // throw RuntimeException("Failed to create directory: " + directory.absolutePath) // } // } -// val apkFile = items.resourceLocalAddress?.let { File(directory, it) } -// if (apkFile != null) { +// val apkFile = File(directory, items.resourceLocalAddress) +// if (true) { // if (!apkFile.exists()) { // Utilities.toast(activity,"APK file not found") // return // } // } -// val uri = apkFile?.let { +// val uri = apkFile.let { // FileProvider.getUriForFile(MainApplication.context, "${MainApplication.context.packageName}.fileprovider", it) // } // val intent = Intent(Intent.ACTION_VIEW).apply { @@ -278,7 +279,7 @@ abstract class BaseContainerFragment : BaseResourceFragment() { bundle.putString("videoURL", "" + Utilities.getUrl(items)) bundle.putString("Auth", "" + auth) } else if (videoType == "offline") { - if (items.resourceRemoteAddress == null && items.resourceLocalAddress != null) { + if (false) { bundle.putString("videoURL", items.resourceLocalAddress) } else { bundle.putString("videoURL", "" + Uri.fromFile(File("" + FileUtils.getSDPathFromUrl(items.resourceRemoteAddress)))) From b8fcf7c0c32f30580c730020a476fb054b753564 Mon Sep 17 00:00:00 2001 From: Gideon Okuro Date: Wed, 11 Dec 2024 16:32:09 +0300 Subject: [PATCH 20/38] migrate baseNewsFragment --- .../org/ole/planet/myplanet/base/BaseNewsFragment.kt | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/org/ole/planet/myplanet/base/BaseNewsFragment.kt b/app/src/main/java/org/ole/planet/myplanet/base/BaseNewsFragment.kt index 7dbd5e7858..5e0392a788 100644 --- a/app/src/main/java/org/ole/planet/myplanet/base/BaseNewsFragment.kt +++ b/app/src/main/java/org/ole/planet/myplanet/base/BaseNewsFragment.kt @@ -6,7 +6,6 @@ import android.content.Intent import android.content.res.Configuration import android.database.Cursor import android.net.Uri -import android.os.Build import android.os.Bundle import android.provider.MediaStore import android.text.TextUtils @@ -17,14 +16,14 @@ import android.widget.LinearLayout import androidx.activity.result.ActivityResult import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.contract.ActivityResultContracts -import androidx.annotation.RequiresApi import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.bumptech.glide.Glide import com.google.gson.Gson import com.google.gson.JsonObject -import io.realm.RealmList +import io.realm.kotlin.ext.realmListOf +import io.realm.kotlin.types.RealmList import org.ole.planet.myplanet.R import org.ole.planet.myplanet.callback.OnHomeItemClickListener import org.ole.planet.myplanet.model.RealmNews @@ -39,7 +38,6 @@ import org.ole.planet.myplanet.utilities.JsonUtils.getString import java.io.File import java.io.FileOutputStream -@RequiresApi(api = Build.VERSION_CODES.O) abstract class BaseNewsFragment : BaseContainerFragment(), OnNewsItemClickListener { lateinit var imageList: RealmList @JvmField @@ -51,7 +49,7 @@ abstract class BaseNewsFragment : BaseContainerFragment(), OnNewsItemClickListen override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - imageList = RealmList() + imageList = realmListOf() profileDbHandler = UserProfileDbHandler(requireContext()) openFolderLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result: ActivityResult -> if (result.resultCode == Activity.RESULT_OK) { @@ -109,7 +107,7 @@ abstract class BaseNewsFragment : BaseContainerFragment(), OnNewsItemClickListen } } - abstract fun setData(list: List?) + abstract fun setData(list: List?) fun showNoData(v: View?, count: Int?, source: String) { count?.let { BaseRecyclerFragment.showNoData(v, it, source) } } From b62f96c26b1cd8895ba0733ed70591e1a8352449 Mon Sep 17 00:00:00 2001 From: Gideon Okuro Date: Wed, 11 Dec 2024 16:58:55 +0300 Subject: [PATCH 21/38] migrate baseRecyclerFragment --- .../myplanet/base/BaseRecyclerFragment.kt | 188 ++++++++---------- .../planet/myplanet/model/RealmMyCourse.kt | 4 +- 2 files changed, 90 insertions(+), 102 deletions(-) diff --git a/app/src/main/java/org/ole/planet/myplanet/base/BaseRecyclerFragment.kt b/app/src/main/java/org/ole/planet/myplanet/base/BaseRecyclerFragment.kt index cb051e576f..ae5208b5f1 100644 --- a/app/src/main/java/org/ole/planet/myplanet/base/BaseRecyclerFragment.kt +++ b/app/src/main/java/org/ole/planet/myplanet/base/BaseRecyclerFragment.kt @@ -2,40 +2,37 @@ package org.ole.planet.myplanet.base import android.content.Context.MODE_PRIVATE import android.content.SharedPreferences -import android.os.Build import android.os.Bundle import android.text.TextUtils import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.TextView -import androidx.annotation.RequiresApi +import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.google.common.reflect.TypeToken import com.google.gson.Gson -import io.realm.Case -import io.realm.RealmList -import io.realm.RealmModel -import io.realm.RealmObject -import io.realm.RealmResults +import io.realm.kotlin.ext.query +import io.realm.kotlin.types.RealmObject +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import org.ole.planet.myplanet.MainApplication.Companion.realm import org.ole.planet.myplanet.R import org.ole.planet.myplanet.callback.OnRatingChangeListener import org.ole.planet.myplanet.datamanager.DatabaseService +import org.ole.planet.myplanet.model.* import org.ole.planet.myplanet.model.RealmCourseProgress import org.ole.planet.myplanet.model.RealmMyCourse import org.ole.planet.myplanet.model.RealmMyCourse.Companion.createMyCourse import org.ole.planet.myplanet.model.RealmMyCourse.Companion.getMyCourse import org.ole.planet.myplanet.model.RealmMyCourse.Companion.getMyCourseByUserId import org.ole.planet.myplanet.model.RealmMyCourse.Companion.getOurCourse -import org.ole.planet.myplanet.model.RealmMyLibrary import org.ole.planet.myplanet.model.RealmMyLibrary.Companion.createFromResource import org.ole.planet.myplanet.model.RealmMyLibrary.Companion.getMyLibraryByUserId import org.ole.planet.myplanet.model.RealmMyLibrary.Companion.getOurLibrary import org.ole.planet.myplanet.model.RealmRemovedLog.Companion.onAdd -import org.ole.planet.myplanet.model.RealmStepExam -import org.ole.planet.myplanet.model.RealmSubmission -import org.ole.planet.myplanet.model.RealmTag import org.ole.planet.myplanet.service.UserProfileDbHandler import org.ole.planet.myplanet.utilities.Constants.PREFS_NAME import org.ole.planet.myplanet.utilities.Utilities.toast @@ -59,20 +56,18 @@ abstract class BaseRecyclerFragment
  • : BaseRecyclerParentFragment(), On var courseLib: String? = null abstract fun getLayout(): Int - abstract fun getAdapter(): RecyclerView.Adapter<*> - @RequiresApi(Build.VERSION_CODES.TIRAMISU) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) arguments?.let { isMyCourseLib = it.getBoolean("isMyCourseLib") courseLib = it.getString("courseLib") val json = it.getString("resources") - resources = (json?.let { + resources = json?.let { val type = object : TypeToken>() {}.type Gson().fromJson>(json, type) - } ?: arrayListOf()) + } ?: arrayListOf() } } @@ -90,7 +85,7 @@ abstract class BaseRecyclerFragment
  • : BaseRecyclerParentFragment(), On selectedItems = mutableListOf() list = mutableListOf() realmService = DatabaseService() - mRealm = realmService.realmInstance + realm = realmService.realmInstance profileDbHandler = UserProfileDbHandler(requireActivity()) model = profileDbHandler.userModel!! val adapter = getAdapter() @@ -98,7 +93,7 @@ abstract class BaseRecyclerFragment
  • : BaseRecyclerParentFragment(), On if (isMyCourseLib && adapter.itemCount != 0 && courseLib == "courses") { resources?.let { showDownloadDialog(it) } } else if (isMyCourseLib && courseLib == null && !isSurvey) { - showDownloadDialog(getLibraryList(mRealm)) + showDownloadDialog(getLibraryList(realm)) } return v } @@ -106,7 +101,11 @@ abstract class BaseRecyclerFragment
  • : BaseRecyclerParentFragment(), On private fun initDeleteButton() { tvDelete?.let { it.visibility = View.VISIBLE - it.setOnClickListener { deleteSelected(false) } + it.setOnClickListener { + lifecycleScope.launch { + deleteSelected(false) + } + } } } @@ -114,19 +113,18 @@ abstract class BaseRecyclerFragment
  • : BaseRecyclerParentFragment(), On recyclerView.adapter = getAdapter() } - fun addToMyList() { + suspend fun addToMyList() { for (i in selectedItems?.indices!!) { val `object` = selectedItems?.get(i) as RealmObject if (`object` is RealmMyLibrary) { - val myObject = mRealm.where(RealmMyLibrary::class.java) - .equalTo("resourceId", `object`.resourceId).findFirst() - createFromResource(myObject, mRealm, model?.id) - onAdd(mRealm, "resources", profileDbHandler.userModel?.id, myObject?.resourceId) + val myObject = realm.query("resourceId == $0", `object`.resourceId).first().find() + createFromResource(myObject, realm, model?.id) + onAdd(realm, "resources", profileDbHandler.userModel?.id, myObject?.resourceId) toast(activity, getString(R.string.added_to_my_library)) } else { - val myObject = getMyCourse(mRealm, (`object` as RealmMyCourse).courseId) - createMyCourse(myObject, mRealm, model?.id) - onAdd(mRealm, "courses", profileDbHandler.userModel?.id, myObject?.courseId) + val myObject = getMyCourse(realm, (`object` as RealmMyCourse).courseId) + createMyCourse(myObject, realm, model?.id) + onAdd(realm, "courses", profileDbHandler.userModel?.id, myObject?.courseId) toast(activity, getString(R.string.added_to_my_courses)) } } @@ -134,12 +132,30 @@ abstract class BaseRecyclerFragment
  • : BaseRecyclerParentFragment(), On showNoData(tvMessage, getAdapter().itemCount, "") } - fun deleteSelected(deleteProgress: Boolean) { - for (i in selectedItems?.indices!!) { - if (!mRealm.isInTransaction()) mRealm.beginTransaction() - val `object` = selectedItems?.get(i) as RealmObject - deleteCourseProgress(deleteProgress, `object`) - removeFromShelf(`object`) + suspend fun deleteSelected(deleteProgress: Boolean) { + withContext(Dispatchers.IO) { + for (i in selectedItems?.indices!!) { + val `object` = selectedItems?.get(i) as RealmObject + if (deleteProgress && `object` is RealmMyCourse) { + val courseProgress = realm.query("courseId == $0", `object`.courseId).find() + val examList = realm.query("courseId == $0", `object`.courseId).find() + val submissionsToDelete = examList.flatMap { exam -> + realm.query("parentId == $0 AND type != $1 AND uploaded == $2", exam.id, "survey", false).find() + } + + realm.write { + courseProgress.forEach { delete(it) } + submissionsToDelete.forEach { delete(it) } + } + } + + realm.write { + removeFromShelf(`object`) + } + } + } + + withContext(Dispatchers.Main) { recyclerView.adapter = getAdapter() showNoData(tvMessage, getAdapter().itemCount, "") } @@ -149,50 +165,38 @@ abstract class BaseRecyclerFragment
  • : BaseRecyclerParentFragment(), On return selectedItems?.size ?: 0 } - private fun deleteCourseProgress(deleteProgress: Boolean, `object`: RealmObject) { - if (deleteProgress && `object` is RealmMyCourse) { - mRealm.where(RealmCourseProgress::class.java).equalTo("courseId", `object`.courseId).findAll().deleteAllFromRealm() - val examList: List = mRealm.where(RealmStepExam::class.java).equalTo("courseId", `object`.courseId).findAll() - for (exam in examList) { - mRealm.where(RealmSubmission::class.java).equalTo("parentId", exam.id) - .notEqualTo("type", "survey").equalTo("uploaded", false).findAll() - .deleteAllFromRealm() - } - } - } - override fun onDestroy() { super.onDestroy() - mRealm.close() + realm.close() } private fun checkAndAddToList(course: RealmMyCourse?, courses: MutableList, tags: List) { for (tg in tags) { - val count = mRealm.where(RealmTag::class.java).equalTo("db", "courses").equalTo("tagId", tg.id) - .equalTo("linkId", course?.courseId).count() + val count = realm.query("db == $0 AND tagId == $1 AND linkId == $2", "courses", tg.id, course?.courseId).count().find() if (count > 0 && !courses.contains(course)) { course?.let { courses.add(it) } } } } - private fun
  • getData(s: String, c: Class
  • ): List
  • { + private inline fun getData(s: String, c: Class
  • ): List
  • { val queryParts = s.split(" ").filterNot { it.isEmpty() } return if (s.contains(" ")) { - val data: RealmResults
  • = mRealm.where(c).findAll() + val data = realm.query
  • ().find() data.filter { item -> - searchAndMatch(item, c, queryParts) + searchAndMatch(item, queryParts) } } else { - mRealm.where(c).contains(if (c == RealmMyLibrary::class.java) "title" else "courseTitle", s, Case.INSENSITIVE).findAll() + val field = if (c == RealmMyLibrary::class.java) "title" else "courseTitle" + realm.query
  • ("$field CONTAINS[c] $0", s).find() } } - private fun
  • searchAndMatch(item: LI, c: Class, queryParts: List): Boolean { - val title = if (c.isAssignableFrom(RealmMyLibrary::class.java)) { - (item as RealmMyLibrary).title - } else { - (item as RealmMyCourse).courseTitle + private fun
  • searchAndMatch(item: LI, queryParts: List): Boolean { + val title = when (item) { + is RealmMyLibrary -> item.title + is RealmMyCourse -> item.courseTitle + else -> null } return queryParts.all { queryPart -> title?.lowercase(Locale.getDefault())?.contains(queryPart.lowercase(Locale.getDefault())) == true @@ -222,14 +226,14 @@ abstract class BaseRecyclerFragment
  • : BaseRecyclerParentFragment(), On } var list = getData(s, RealmMyCourse::class.java) list = if (isMyCourseLib) { - getMyCourseByUserId(model?.id, list) + getMyCourseByUserId(model?.id ?: "", list) } else { - getOurCourse(model?.id, list) + getOurCourse(model?.id ?: "", list) } if (tags.isEmpty()) { return list } - val courses = RealmList() + val courses = mutableListOf() list.forEach { course -> checkAndAddToList(course, courses, tags) } @@ -242,8 +246,7 @@ abstract class BaseRecyclerFragment
  • : BaseRecyclerParentFragment(), On private fun filter(tags: List, library: RealmMyLibrary?, libraries: MutableList) { for (tg in tags) { - val count = mRealm.where(RealmTag::class.java).equalTo("db", "resources") - .equalTo("tagId", tg.id).equalTo("linkId", library?.id).count() + val count = realm.query("db == $0 AND tagId == $1 AND linkId == $2", "resources", tg.id, library?.id).count().find() if (count > 0 && !libraries.contains(library)) { library?.let { libraries.add(it) } } @@ -251,30 +254,19 @@ abstract class BaseRecyclerFragment
  • : BaseRecyclerParentFragment(), On } fun applyFilter(libraries: List): List { - val newList: MutableList = ArrayList() - for (l in libraries) { - if (isValidFilter(l)) newList.add(l) - } - return newList + return libraries.filter { isValidFilter(it) } } private fun applyCourseFilter(courses: List): List { if (TextUtils.isEmpty(subjectLevel) && TextUtils.isEmpty(gradeLevel)) return courses - val newList: MutableList = ArrayList() - for (l in courses) { - if (TextUtils.equals(l.gradeLevel, gradeLevel) || TextUtils.equals( - l.subjectLevel, subjectLevel - ) - ) { - newList.add(l) - } + return courses.filter { course -> + TextUtils.equals(course.gradeLevel, gradeLevel) || TextUtils.equals(course.subjectLevel, subjectLevel) } - return newList } private fun isValidFilter(l: RealmMyLibrary): Boolean { - val sub = subjects.isEmpty() || subjects.let { l.subject?.containsAll(it) } == true - val lev = levels.isEmpty() || l.level!!.containsAll(levels) + val sub = subjects.isEmpty() || subjects.let { l.subject.containsAll(it) } == true + val lev = levels.isEmpty() || l.level.containsAll(levels) val lan = languages.isEmpty() || languages.contains(l.language) val med = mediums.isEmpty() || mediums.contains(l.mediaType) return sub && lev && lan && med @@ -285,28 +277,24 @@ abstract class BaseRecyclerFragment
  • : BaseRecyclerParentFragment(), On fun showNoData(v: View?, count: Int?, source: String) { v ?: return - v.visibility = if (count == 0) { - View.VISIBLE - } else { - View.GONE - } - when (source) { - "courses" -> (v as TextView).setText(R.string.no_courses) - "resources" -> (v as TextView).setText(R.string.no_resources) - "finances" -> (v as TextView).setText(R.string.no_finance_record) - "news" -> (v as TextView).setText(R.string.no_voices_available) - "teamCourses" -> (v as TextView).setText(R.string.no_team_courses) - "teamResources" -> (v as TextView).setText(R.string.no_team_resources) - "tasks" -> (v as TextView).setText(R.string.no_tasks) - "members" -> (v as TextView).setText(R.string.no_join_request_available) - "discussions" -> (v as TextView).setText(R.string.no_news) - "survey" -> (v as TextView).setText(R.string.no_surveys) - "submission" -> (v as TextView).setText(R.string.no_submissions) - "teams" -> (v as TextView).setText(R.string.no_teams) - "chatHistory" -> (v as TextView).setText(R.string.no_chats) - "feedback" -> (v as TextView).setText(R.string.no_feedback) - else -> (v as TextView).setText(R.string.no_data_available_please_check_and_try_again) - } + v.visibility = if (count == 0) View.VISIBLE else View.GONE + (v as TextView).setText(when (source) { + "courses" -> R.string.no_courses + "resources" -> R.string.no_resources + "finances" -> R.string.no_finance_record + "news" -> R.string.no_voices_available + "teamCourses" -> R.string.no_team_courses + "teamResources" -> R.string.no_team_resources + "tasks" -> R.string.no_tasks + "members" -> R.string.no_join_request_available + "discussions" -> R.string.no_news + "survey" -> R.string.no_surveys + "submission" -> R.string.no_submissions + "teams" -> R.string.no_teams + "chatHistory" -> R.string.no_chats + "feedback" -> R.string.no_feedback + else -> R.string.no_data_available_please_check_and_try_again + }) } fun showNoFilter(v: View?, count: Int) { @@ -315,4 +303,4 @@ abstract class BaseRecyclerFragment
  • : BaseRecyclerParentFragment(), On (v as TextView).setText(R.string.no_course_matched_filter) } } -} +} \ No newline at end of file diff --git a/app/src/main/java/org/ole/planet/myplanet/model/RealmMyCourse.kt b/app/src/main/java/org/ole/planet/myplanet/model/RealmMyCourse.kt index 22b5b1f5d5..35481598c1 100644 --- a/app/src/main/java/org/ole/planet/myplanet/model/RealmMyCourse.kt +++ b/app/src/main/java/org/ole/planet/myplanet/model/RealmMyCourse.kt @@ -239,9 +239,9 @@ class RealmMyCourse : RealmObject { return realm.query("courseId == $0", id).first().find() } - fun createMyCourse(course: RealmMyCourse?, realm: Realm, id: String) { + fun createMyCourse(course: RealmMyCourse?, realm: Realm, id: String?) { realm.writeBlocking { - course?.addUserId(id) + course?.addUserId(id ?: "") } } From 381b3ab094cb7f7cf518791e50ec1e2eab5bc904 Mon Sep 17 00:00:00 2001 From: Gideon Okuro Date: Wed, 11 Dec 2024 17:11:37 +0300 Subject: [PATCH 22/38] migrate baseRecyclerParentFragment --- .../base/BaseRecyclerParentFragment.kt | 68 +++++++++++-------- 1 file changed, 38 insertions(+), 30 deletions(-) diff --git a/app/src/main/java/org/ole/planet/myplanet/base/BaseRecyclerParentFragment.kt b/app/src/main/java/org/ole/planet/myplanet/base/BaseRecyclerParentFragment.kt index dacdd24bc1..f7fd5a3993 100644 --- a/app/src/main/java/org/ole/planet/myplanet/base/BaseRecyclerParentFragment.kt +++ b/app/src/main/java/org/ole/planet/myplanet/base/BaseRecyclerParentFragment.kt @@ -1,8 +1,9 @@ package org.ole.planet.myplanet.base import com.google.gson.JsonArray -import io.realm.RealmModel -import io.realm.Sort +import io.realm.kotlin.ext.query +import io.realm.kotlin.query.Sort +import org.ole.planet.myplanet.MainApplication.Companion.realm import org.ole.planet.myplanet.model.RealmMyCourse import org.ole.planet.myplanet.model.RealmMyLibrary import org.ole.planet.myplanet.model.RealmStepExam @@ -14,21 +15,21 @@ abstract class BaseRecyclerParentFragment
  • : BaseResourceFragment() { fun getList(c: Class<*>): List
  • { return when { c == RealmStepExam::class.java -> { - mRealm.where(c).equalTo("type", "surveys").findAll().toList() as List
  • + realm.query("type == $0", "surveys").find() as List
  • } isMyCourseLib -> { - getMyLibItems(c as Class) + getMyLibItems(c) } c == RealmMyLibrary::class.java -> { - RealmMyLibrary.getOurLibrary(model?.id, mRealm.where(c).equalTo("isPrivate", false).findAll().toList()) as List
  • + val results = realm.query("isPrivate == $0", false).find() + RealmMyLibrary.getOurLibrary(model?.id, results) as List
  • } else -> { - val myLibItems = getMyLibItems(c as Class) - val results: List = mRealm.where(RealmMyCourse::class.java) - .isNotEmpty("courseTitle") - .findAll() - .toList() - val ourCourseItems = RealmMyCourse.getOurCourse(model?.id, results) + val myLibItems = getMyLibItems(c) + val results = realm.query() + .query("courseTitle != $0", "") + .find() + val ourCourseItems = RealmMyCourse.getOurCourse(model?.id ?: "", results) when (c) { RealmMyCourse::class.java -> { @@ -57,47 +58,54 @@ abstract class BaseRecyclerParentFragment
  • : BaseResourceFragment() { fun getList(c: Class<*>, orderBy: String? = null, sort: Sort = Sort.ASCENDING): List
  • { return when { c == RealmStepExam::class.java -> { - mRealm.where(c).equalTo("type", "surveys").sort(orderBy ?: "", sort).findAll().toList() as List
  • + realm.query("type == $0", "surveys").apply { + orderBy?.let { sort(it, sort) } + }.find() as List
  • } isMyCourseLib -> { - getMyLibItems(c as Class, orderBy) + getMyLibItems(c, orderBy) } c == RealmMyLibrary::class.java -> { - RealmMyLibrary.getOurLibrary(model?.id, mRealm.where(c).equalTo("isPrivate", false).sort(orderBy ?: "", sort).findAll().toList()) as List
  • + val results = realm.query("isPrivate == $0", false).apply { + orderBy?.let { sort(it, sort) } + }.find() + RealmMyLibrary.getOurLibrary(model?.id, results) as List
  • } else -> { - val results = mRealm.where(RealmMyCourse::class.java).sort(orderBy ?: "", sort).findAll().toList() as List - RealmMyCourse.getOurCourse(model?.id, results) as List
  • + val results = realm.query().apply { + orderBy?.let { sort(it, sort) } + }.find() + RealmMyCourse.getOurCourse(model?.id ?: "", results) as List
  • } } } + @Suppress("UNCHECKED_CAST") - private fun getMyLibItems(c: Class, orderBy: String? = null): List
  • { - val query = mRealm.where(c) - val realmResults = if (orderBy != null) { - query.sort(orderBy).findAll() - } else { - query.findAll() - } - val results: List = realmResults.toList() + private fun getMyLibItems(c: Class<*>, orderBy: String? = null): List
  • { return when (c) { RealmMyLibrary::class.java -> { - RealmMyLibrary.getMyLibraryByUserId(model?.id, results as? List ?: emptyList()) as List
  • + val results = realm.query().apply { + orderBy?.let { sort(it) } + }.find() + RealmMyLibrary.getMyLibraryByUserId(model?.id, results) as List
  • } RealmMyCourse::class.java -> { - RealmMyCourse.getMyCourseByUserId(model?.id, results as? List ?: emptyList()) as List
  • + val results = realm.query().apply { + orderBy?.let { sort(it) } + }.find() + RealmMyCourse.getMyCourseByUserId(model?.id ?: "", results) as List
  • } else -> throw IllegalArgumentException("Unsupported class: ${c.simpleName}") } } fun getJsonArrayFromList(list: Set): JsonArray { - val array = JsonArray() - list.forEach { array.add(it) } - return array + return JsonArray().apply { + list.forEach { add(it) } + } } companion object { var isSurvey: Boolean = false } -} +} \ No newline at end of file From 158d240afd4b44a908943e029a192ca0084aea72 Mon Sep 17 00:00:00 2001 From: Gideon Okuro Date: Fri, 13 Dec 2024 16:12:51 +0300 Subject: [PATCH 23/38] migrate baseRecyclerFragment --- .../myplanet/base/BaseRecyclerFragment.kt | 30 ++-- .../myplanet/base/BaseResourceFragment.kt | 128 +++++++++++------- .../myplanet/ui/courses/CoursesFragment.kt | 35 +++-- .../ui/resources/ResourcesFragment.kt | 10 +- 4 files changed, 117 insertions(+), 86 deletions(-) diff --git a/app/src/main/java/org/ole/planet/myplanet/base/BaseRecyclerFragment.kt b/app/src/main/java/org/ole/planet/myplanet/base/BaseRecyclerFragment.kt index ae5208b5f1..4ee85180e9 100644 --- a/app/src/main/java/org/ole/planet/myplanet/base/BaseRecyclerFragment.kt +++ b/app/src/main/java/org/ole/planet/myplanet/base/BaseRecyclerFragment.kt @@ -23,16 +23,6 @@ import org.ole.planet.myplanet.R import org.ole.planet.myplanet.callback.OnRatingChangeListener import org.ole.planet.myplanet.datamanager.DatabaseService import org.ole.planet.myplanet.model.* -import org.ole.planet.myplanet.model.RealmCourseProgress -import org.ole.planet.myplanet.model.RealmMyCourse -import org.ole.planet.myplanet.model.RealmMyCourse.Companion.createMyCourse -import org.ole.planet.myplanet.model.RealmMyCourse.Companion.getMyCourse -import org.ole.planet.myplanet.model.RealmMyCourse.Companion.getMyCourseByUserId -import org.ole.planet.myplanet.model.RealmMyCourse.Companion.getOurCourse -import org.ole.planet.myplanet.model.RealmMyLibrary.Companion.createFromResource -import org.ole.planet.myplanet.model.RealmMyLibrary.Companion.getMyLibraryByUserId -import org.ole.planet.myplanet.model.RealmMyLibrary.Companion.getOurLibrary -import org.ole.planet.myplanet.model.RealmRemovedLog.Companion.onAdd import org.ole.planet.myplanet.service.UserProfileDbHandler import org.ole.planet.myplanet.utilities.Constants.PREFS_NAME import org.ole.planet.myplanet.utilities.Utilities.toast @@ -118,13 +108,13 @@ abstract class BaseRecyclerFragment
  • : BaseRecyclerParentFragment(), On val `object` = selectedItems?.get(i) as RealmObject if (`object` is RealmMyLibrary) { val myObject = realm.query("resourceId == $0", `object`.resourceId).first().find() - createFromResource(myObject, realm, model?.id) - onAdd(realm, "resources", profileDbHandler.userModel?.id, myObject?.resourceId) + RealmMyLibrary.createFromResource(myObject, realm, model?.id) + RealmRemovedLog.onAdd(realm, "resources", profileDbHandler.userModel?.id, myObject?.resourceId) toast(activity, getString(R.string.added_to_my_library)) } else { - val myObject = getMyCourse(realm, (`object` as RealmMyCourse).courseId) - createMyCourse(myObject, realm, model?.id) - onAdd(realm, "courses", profileDbHandler.userModel?.id, myObject?.courseId) + val myObject = RealmMyCourse.getMyCourse(realm, (`object` as RealmMyCourse).courseId) + RealmMyCourse.createMyCourse(myObject, realm, model?.id) + RealmRemovedLog.onAdd(realm, "courses", profileDbHandler.userModel?.id, myObject?.courseId) toast(activity, getString(R.string.added_to_my_courses)) } } @@ -149,7 +139,7 @@ abstract class BaseRecyclerFragment
  • : BaseRecyclerParentFragment(), On } } - realm.write { + lifecycleScope.launch { removeFromShelf(`object`) } } @@ -206,9 +196,9 @@ abstract class BaseRecyclerFragment
  • : BaseRecyclerParentFragment(), On fun filterLibraryByTag(s: String, tags: List): List { var list = getData(s, RealmMyLibrary::class.java) list = if (isMyCourseLib) { - getMyLibraryByUserId(model?.id, list) + RealmMyLibrary.getMyLibraryByUserId(model?.id, list) } else { - getOurLibrary(model?.id, list) + RealmMyLibrary.getOurLibrary(model?.id, list) } if (tags.isEmpty()) { return list @@ -226,9 +216,9 @@ abstract class BaseRecyclerFragment
  • : BaseRecyclerParentFragment(), On } var list = getData(s, RealmMyCourse::class.java) list = if (isMyCourseLib) { - getMyCourseByUserId(model?.id ?: "", list) + RealmMyCourse.getMyCourseByUserId(model?.id ?: "", list) } else { - getOurCourse(model?.id ?: "", list) + RealmMyCourse.getOurCourse(model?.id ?: "", list) } if (tags.isEmpty()) { return list diff --git a/app/src/main/java/org/ole/planet/myplanet/base/BaseResourceFragment.kt b/app/src/main/java/org/ole/planet/myplanet/base/BaseResourceFragment.kt index 070810f0d4..a4138187c8 100644 --- a/app/src/main/java/org/ole/planet/myplanet/base/BaseResourceFragment.kt +++ b/app/src/main/java/org/ole/planet/myplanet/base/BaseResourceFragment.kt @@ -21,11 +21,13 @@ import android.widget.TextView import androidx.appcompat.app.AlertDialog import androidx.fragment.app.Fragment import androidx.localbroadcastmanager.content.LocalBroadcastManager -import io.realm.Realm -import io.realm.RealmObject -import io.realm.RealmResults +import io.realm.kotlin.Realm +import io.realm.kotlin.types.RealmObject +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext import org.ole.planet.myplanet.MainApplication import org.ole.planet.myplanet.MainApplication.Companion.context +import org.ole.planet.myplanet.MainApplication.Companion.realm import org.ole.planet.myplanet.R import org.ole.planet.myplanet.callback.OnHomeItemClickListener import org.ole.planet.myplanet.datamanager.DatabaseService @@ -142,14 +144,16 @@ abstract class BaseResourceFragment : Fragment() { fun showPendingSurveyDialog() { model = UserProfileDbHandler(requireContext()).userModel - val list: List = mRealm.where(RealmSubmission::class.java) - .equalTo("userId", model?.id) - .equalTo("status", "pending").equalTo("type", "survey") - .findAll() + val list = realm.query(RealmSubmission::class, + "userId == $0 AND status == $1 AND type == $2", + model?.id, "pending", "survey" + ).find() + if (list.isEmpty()) { return } - val exams = getExamMap(mRealm, list) + + val exams = getExamMap(realm, list) val arrayAdapter: ArrayAdapter<*> = object : ArrayAdapter(requireActivity(), android.R.layout.simple_list_item_1, list) { override fun getView(position: Int, convertView: View?, parent: ViewGroup): View { var convertedView = convertView @@ -164,6 +168,7 @@ abstract class BaseResourceFragment : Fragment() { return convertedView!! } } + AlertDialog.Builder(requireActivity()).setTitle("Pending Surveys") .setAdapter(arrayAdapter) { _: DialogInterface?, i: Int -> AdapterMySubmission.openSurvey(homeItemClickListener, list[i].id, true) @@ -239,13 +244,13 @@ abstract class BaseResourceFragment : Fragment() { LocalBroadcastManager.getInstance(MainApplication.context).registerReceiver(stateReceiver, intentFilter3) } - fun getLibraryList(mRealm: Realm): List { - return getLibraryList(mRealm, settings?.getString("userId", "--")) + fun getLibraryList(realm: Realm): List { + return getLibraryList(realm, settings?.getString("userId", "--")) } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - mRealm = DatabaseService().realmInstance + realm = DatabaseService().realmInstance prgDialog = getProgressDialog(requireActivity()) settings = requireActivity().getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE) editor = settings?.edit() @@ -258,19 +263,37 @@ abstract class BaseResourceFragment : Fragment() { LocalBroadcastManager.getInstance(requireActivity()).unregisterReceiver(stateReceiver) } - fun removeFromShelf(`object`: RealmObject) { - if (`object` is RealmMyLibrary) { - val myObject = mRealm.where(RealmMyLibrary::class.java).equalTo("resourceId", `object`.resourceId).findFirst() - myObject?.removeUserId(model?.id) - model?.id?.let { `object`.resourceId?.let { it1 -> - onRemove(mRealm, "resources", it, it1) - } } - Utilities.toast(activity, getString(R.string.removed_from_mylibrary)) - } else { - val myObject = getMyCourse(mRealm, (`object` as RealmMyCourse).courseId) - myObject?.removeUserId(model?.id) - model?.id?.let { `object`.courseId?.let { it1 -> onRemove(mRealm, "courses", it, it1) } } - Utilities.toast(activity, getString(R.string.removed_from_mycourse)) + suspend fun removeFromShelf(`object`: RealmObject) { + when (`object`) { + is RealmMyLibrary -> { + val myObject = realm.query( + RealmMyLibrary::class, + "resourceId == $0", `object`.resourceId + ).first().find() + + realm.write { + myObject?.removeUserId(model?.id) + } + + model?.id?.let { userId -> + `object`.resourceId?.let { resourceId -> + onRemove(realm, "resources", userId, resourceId) + } + } + withContext(Dispatchers.Main) { + Utilities.toast(activity, getString(R.string.removed_from_mylibrary)) + } + } + is RealmMyCourse -> { + val myObject = getMyCourse(realm, `object`.courseId) + realm.write { + myObject?.removeUserId(model?.id ?: "") + } + model?.id?.let { userId -> + onRemove(realm, "courses", userId, `object`.courseId) + } + Utilities.toast(activity, getString(R.string.removed_from_mycourse)) + } } } @@ -287,25 +310,32 @@ abstract class BaseResourceFragment : Fragment() { tvSelected?.text = selected.subSequence(0, selected.length - 1) } - fun addToLibrary(libraryItems: List, selectedItems: ArrayList) { - for (i in selectedItems.indices) { - if (!libraryItems[selectedItems[i]]?.userId?.contains(profileDbHandler.userModel?.id)!!) { - if (!mRealm.isInTransaction) mRealm.beginTransaction() - libraryItems[selectedItems[i]]?.setUserId(profileDbHandler.userModel?.id) - RealmRemovedLog.onAdd(mRealm, "resources", profileDbHandler.userModel?.id, libraryItems[selectedItems[i]]?.resourceId) + suspend fun addToLibrary(libraryItems: List, selectedItems: ArrayList) { + realm.write { + for (i in selectedItems.indices) { + if (!libraryItems[selectedItems[i]].userId.contains(profileDbHandler.userModel?.id)) { + libraryItems[selectedItems[i]].setUserId(profileDbHandler.userModel?.id) + RealmRemovedLog.onAdd( + realm, + "resources", + profileDbHandler.userModel?.id, + libraryItems[selectedItems[i]].resourceId + ) + } } } Utilities.toast(activity, getString(R.string.added_to_my_library)) } - fun addAllToLibrary(libraryItems: List) { - for (libraryItem in libraryItems) { - if (!libraryItem?.userId?.contains(profileDbHandler.userModel?.id)!!) { - if (!mRealm.isInTransaction) { - mRealm.beginTransaction() + suspend fun addAllToLibrary(libraryItems: List) { + realm.write { + for (libraryItem in libraryItems) { + if (!libraryItem.userId.contains(profileDbHandler.userModel?.id)) { + libraryItem.setUserId(profileDbHandler.userModel?.id) + RealmRemovedLog.onAdd( + realm, "resources", profileDbHandler.userModel?.id, libraryItem.resourceId + ) } - libraryItem.setUserId(profileDbHandler.userModel?.id) - RealmRemovedLog.onAdd(mRealm, "resources", profileDbHandler.userModel?.id, libraryItem.resourceId) } } Utilities.toast(activity, getString(R.string.added_to_my_library)) @@ -315,9 +345,9 @@ abstract class BaseResourceFragment : Fragment() { var settings: SharedPreferences? = null var auth = "" - fun getAllLibraryList(mRealm: Realm): List { - val l = mRealm.where(RealmMyLibrary::class.java).equalTo("resourceOffline", false).findAll() - val libList: MutableList = ArrayList() + fun getAllLibraryList(realm: Realm): List { + val l = realm.query(RealmMyLibrary::class, "resourceOffline == $0", false).find() + val libList = mutableListOf() val libraries = getLibraries(l) libList.addAll(libraries) return libList @@ -335,26 +365,20 @@ abstract class BaseResourceFragment : Fragment() { }) } - fun getLibraryList(mRealm: Realm, userId: String?): List { - val l = mRealm.where(RealmMyLibrary::class.java).equalTo("isPrivate", false).findAll() - val libList: MutableList = ArrayList() + fun getLibraryList(realm: Realm, userId: String?): List { + val l = realm.query(RealmMyLibrary::class, "isPrivate == $0", false).find() + val libList = mutableListOf() val libraries = getLibraries(l) for (item in libraries) { - if (item.userId?.contains(userId) == true) { + if (item.userId.contains(userId)) { libList.add(item) } } return libList } - private fun getLibraries(l: RealmResults): List { - val libraries: MutableList = ArrayList() - for (lib in l) { - if (lib.needToUpdate()) { - libraries.add(lib) - } - } - return libraries + private fun getLibraries(l: List): List { + return l.filter { it.needToUpdate() } } } } diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/courses/CoursesFragment.kt b/app/src/main/java/org/ole/planet/myplanet/ui/courses/CoursesFragment.kt index 8d0cfebeb0..6eef0b2979 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/courses/CoursesFragment.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/courses/CoursesFragment.kt @@ -15,9 +15,11 @@ import android.widget.Spinner import android.widget.TextView import androidx.appcompat.view.ContextThemeWrapper import androidx.fragment.app.Fragment +import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.RecyclerView import com.google.gson.Gson import com.google.gson.JsonObject +import kotlinx.coroutines.launch import org.ole.planet.myplanet.R import org.ole.planet.myplanet.base.BaseRecyclerFragment import org.ole.planet.myplanet.callback.OnCourseItemSelected @@ -68,15 +70,18 @@ class CoursesFragment : BaseRecyclerFragment(), OnCourseItemSele } override fun getAdapter(): RecyclerView.Adapter<*> { - val map = getRatings(mRealm, "course", model?.id) - val progressMap = getCourseProgress(mRealm, model?.id) - val courseList: List = getList(RealmMyCourse::class.java).filterIsInstance() - val sortedCourseList = courseList.sortedWith(compareBy({ it?.isMyCourse }, { it?.courseTitle })) - adapterCourses = AdapterCourses(requireActivity(), sortedCourseList, map) - adapterCourses.setProgressMap(progressMap) - adapterCourses.setmRealm(mRealm) - adapterCourses.setListener(this) - adapterCourses.setRatingChangeListener(this) + lifecycleScope.launch { + val map = getRatings(mRealm, "course", model?.id) + val progressMap = getCourseProgress(mRealm, model?.id ?: "") + val courseList: List = getList(RealmMyCourse::class.java).filterIsInstance() + val sortedCourseList = courseList.sortedWith(compareBy({ it?.isMyCourse }, { it?.courseTitle })) + adapterCourses = AdapterCourses(requireActivity(), sortedCourseList, map) + adapterCourses.setProgressMap(progressMap) + adapterCourses.setmRealm(mRealm) + adapterCourses.setListener(this) + adapterCourses.setRatingChangeListener(this) + } + if (isMyCourseLib) { val courseIds = courseList.mapNotNull { it?.id } @@ -123,7 +128,9 @@ class CoursesFragment : BaseRecyclerFragment(), OnCourseItemSele } alertDialogBuilder.setMessage(message) .setPositiveButton(R.string.yes) { _: DialogInterface?, _: Int -> - deleteSelected(true) + lifecycleScope.launch { + deleteSelected(true) + } val newFragment = CoursesFragment() recreateFragment(newFragment) checkList() @@ -139,7 +146,9 @@ class CoursesFragment : BaseRecyclerFragment(), OnCourseItemSele } alertDialogBuilder.setMessage(message) .setPositiveButton(R.string.yes) { _: DialogInterface?, _: Int -> - deleteSelected(true) + lifecycleScope.launch { + deleteSelected(true) + } val newFragment = CoursesFragment() recreateFragment(newFragment) checkList() @@ -196,7 +205,9 @@ class CoursesFragment : BaseRecyclerFragment(), OnCourseItemSele if ((selectedItems?.size ?: 0) > 0) { confirmation = createAlertDialog() confirmation.show() - addToMyList() + lifecycleScope.launch { + addToMyList() + } selectedItems?.clear() tvAddToLib.isEnabled = false checkList() diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/resources/ResourcesFragment.kt b/app/src/main/java/org/ole/planet/myplanet/ui/resources/ResourcesFragment.kt index bf9727a5e9..3703d57a9f 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/resources/ResourcesFragment.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/resources/ResourcesFragment.kt @@ -12,6 +12,7 @@ import android.widget.EditText import android.widget.ImageButton import android.widget.TextView import androidx.fragment.app.Fragment +import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.RecyclerView import com.github.clans.fab.FloatingActionButton import com.google.android.flexbox.FlexboxLayout @@ -20,6 +21,7 @@ import com.google.gson.JsonObject import fisk.chipcloud.ChipCloud import fisk.chipcloud.ChipCloudConfig import fisk.chipcloud.ChipDeletedListener +import kotlinx.coroutines.launch import org.ole.planet.myplanet.R import org.ole.planet.myplanet.base.BaseRecyclerFragment import org.ole.planet.myplanet.callback.OnFilterListener @@ -101,7 +103,9 @@ class ResourcesFragment : BaseRecyclerFragment(), OnLibraryItem if ((selectedItems?.size ?: 0) > 0) { confirmation = createAlertDialog() confirmation?.show() - addToMyList() + lifecycleScope.launch { + addToMyList() + } selectedItems?.clear() tvAddToLib.isEnabled = false checkList() @@ -112,7 +116,9 @@ class ResourcesFragment : BaseRecyclerFragment(), OnLibraryItem AlertDialog.Builder(this.context, R.style.AlertDialogTheme) .setMessage(R.string.confirm_removal) .setPositiveButton(R.string.yes) { _, _ -> - deleteSelected(true) + lifecycleScope.launch { + deleteSelected(true) + } val newFragment = ResourcesFragment() recreateFragment(newFragment) } From 588bc996c678fd1a56bc40a38d9e3a0efe3064a5 Mon Sep 17 00:00:00 2001 From: Gideon Okuro Date: Fri, 13 Dec 2024 16:31:36 +0300 Subject: [PATCH 24/38] migrate manager sync --- .../myplanet/base/BaseResourceFragment.kt | 12 +++++-- .../myplanet/datamanager/DatabaseService.kt | 36 ++++++++++--------- .../myplanet/datamanager/ManagerSync.kt | 12 +++++-- 3 files changed, 38 insertions(+), 22 deletions(-) diff --git a/app/src/main/java/org/ole/planet/myplanet/base/BaseResourceFragment.kt b/app/src/main/java/org/ole/planet/myplanet/base/BaseResourceFragment.kt index a4138187c8..1043c62226 100644 --- a/app/src/main/java/org/ole/planet/myplanet/base/BaseResourceFragment.kt +++ b/app/src/main/java/org/ole/planet/myplanet/base/BaseResourceFragment.kt @@ -20,10 +20,12 @@ import android.widget.ListView import android.widget.TextView import androidx.appcompat.app.AlertDialog import androidx.fragment.app.Fragment +import androidx.lifecycle.lifecycleScope import androidx.localbroadcastmanager.content.LocalBroadcastManager import io.realm.kotlin.Realm import io.realm.kotlin.types.RealmObject import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import org.ole.planet.myplanet.MainApplication import org.ole.planet.myplanet.MainApplication.Companion.context @@ -99,7 +101,7 @@ abstract class BaseResourceFragment : Fragment() { } } - protected fun showDownloadDialog(dbMyLibrary: List) { + protected fun showDownloadDialog(dbMyLibrary: List) { if (isAdded) { Service(MainApplication.context).isPlanetAvailable(object : PlanetAvailableListener { override fun isAvailable() { @@ -114,12 +116,16 @@ abstract class BaseResourceFragment : Fragment() { alertDialogBuilder.setView(convertView).setTitle(R.string.download_suggestion) alertDialogBuilder.setPositiveButton(R.string.download_selected) { _: DialogInterface?, _: Int -> lv?.selectedItemsList?.let { - addToLibrary(dbMyLibrary, it) + lifecycleScope.launch { + addToLibrary(dbMyLibrary, it) + } downloadFiles(dbMyLibrary, it) }?.let { startDownload(it) } }.setNeutralButton(R.string.download_all) { _: DialogInterface?, _: Int -> lv?.selectedItemsList?.let { - addAllToLibrary(dbMyLibrary) + lifecycleScope.launch { + addAllToLibrary(dbMyLibrary) + } } startDownload(downloadAllFiles(dbMyLibrary)) }.setNegativeButton(R.string.txt_cancel, null) diff --git a/app/src/main/java/org/ole/planet/myplanet/datamanager/DatabaseService.kt b/app/src/main/java/org/ole/planet/myplanet/datamanager/DatabaseService.kt index d62ea7e0c4..4d806300d1 100644 --- a/app/src/main/java/org/ole/planet/myplanet/datamanager/DatabaseService.kt +++ b/app/src/main/java/org/ole/planet/myplanet/datamanager/DatabaseService.kt @@ -4,31 +4,35 @@ import io.realm.kotlin.Realm import io.realm.kotlin.RealmConfiguration import io.realm.kotlin.log.RealmLog import io.realm.kotlin.log.LogLevel +import io.realm.kotlin.types.RealmObject import org.ole.planet.myplanet.model.* +import kotlin.reflect.KClass class DatabaseService() { private val config: RealmConfiguration init { - RealmLog.level = LogLevel.DEBUG - config = RealmConfiguration.create( + RealmLog.level = LogLevel.DEBUG + config = RealmConfiguration.Builder( schema = setOf( - RealmAchievement::class, RealmAnswer::class, RealmApkLog::class, - RealmCertification::class, RealmChatHistory::class, RealmCommunity::class, - RealmCourseActivity::class, RealmCourseProgress::class, RealmCourseStep::class, - RealmDictionary::class, RealmExamQuestion::class, RealmFeedback::class, - RealmMeetup::class, RealmMessage::class, RealmMyCourse::class, RealmMyHealth::class, - RealmMyHealthPojo::class, RealmMyLibrary::class, RealmMyLife::class, - RealmMyPersonal::class, RealmMyTeam::class, RealmNews::class, RealmNewsLog::class, - RealmNotification::class, RealmOfflineActivity::class, RealmRating::class, - RealmRemovedLog::class, RealmResourceActivity::class, RealmSearchActivity::class, - RealmStepExam::class, RealmSubmission::class, RealmSubmitPhotos::class, RealmTag::class, RealmTeamLog::class, RealmTeamNotification::class, RealmTeamTask::class, - RealmUserChallengeActions::class, RealmUserModel::class), - name = "default.realm", - schemaVersion = 4 + RealmAchievement::class, RealmAnswer::class, RealmApkLog::class, RealmCertification::class, + RealmChatHistory::class, RealmCommunity::class, RealmCourseActivity::class, + RealmCourseProgress::class, RealmCourseStep::class, RealmDictionary::class, + RealmExamQuestion::class, RealmFeedback::class, RealmMeetup::class, RealmMessage::class, + RealmMyCourse::class, RealmMyHealth::class, RealmMyHealthPojo::class, RealmMyLibrary::class, + RealmMyLife::class, RealmMyPersonal::class, RealmMyTeam::class, RealmNews::class, + RealmNewsLog::class, RealmNotification::class, RealmOfflineActivity::class, + RealmRating::class, RealmRemovedLog::class, RealmResourceActivity::class, + RealmSearchActivity::class, RealmStepExam::class, RealmSubmission::class, + RealmSubmitPhotos::class, RealmTag::class, RealmTeamLog::class, RealmTeamNotification::class, + RealmTeamTask::class, RealmUserChallengeActions::class, RealmUserModel::class + ) as Set> ) + .directory("default.realm") + .schemaVersion(4) + .build() } - + val realmInstance: Realm by lazy { Realm.open(config) } diff --git a/app/src/main/java/org/ole/planet/myplanet/datamanager/ManagerSync.kt b/app/src/main/java/org/ole/planet/myplanet/datamanager/ManagerSync.kt index d74b18039e..6f49830bdf 100644 --- a/app/src/main/java/org/ole/planet/myplanet/datamanager/ManagerSync.kt +++ b/app/src/main/java/org/ole/planet/myplanet/datamanager/ManagerSync.kt @@ -5,7 +5,10 @@ import android.content.SharedPreferences import android.util.Base64 import com.google.gson.Gson import com.google.gson.JsonObject -import io.realm.Realm +import io.realm.kotlin.Realm +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch import org.ole.planet.myplanet.MainApplication import org.ole.planet.myplanet.callback.SyncListener import org.ole.planet.myplanet.model.RealmUserModel.Companion.populateUsersTable @@ -22,6 +25,7 @@ class ManagerSync private constructor(context: Context) { private val settings: SharedPreferences = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE) private val dbService: DatabaseService = DatabaseService() private val mRealm: Realm = dbService.realmInstance + private val scope = CoroutineScope(Dispatchers.Main) fun login(userName: String?, password: String?, listener: SyncListener) { listener.onSyncStarted() @@ -36,7 +40,9 @@ class ManagerSync private constructor(context: Context) { val derivedKey = jsonDoc["derived_key"].asString val salt = jsonDoc["salt"].asString if (androidDecrypter(userName, password, derivedKey, salt)) { - checkManagerAndInsert(jsonDoc, mRealm, listener) + scope.launch(Dispatchers.IO) { + checkManagerAndInsert(jsonDoc, mRealm, listener) + } } else { listener.onSyncFailed("Name or password is incorrect.") } @@ -77,7 +83,7 @@ class ManagerSync private constructor(context: Context) { }) } - private fun checkManagerAndInsert(jsonDoc: JsonObject?, realm: Realm, listener: SyncListener) { + private suspend fun checkManagerAndInsert(jsonDoc: JsonObject?, realm: Realm, listener: SyncListener) { if (isManager(jsonDoc)) { populateUsersTable(jsonDoc, realm, settings) listener.onSyncComplete() From 74f6229976388103075c88b4ff907c1f7ac28bd9 Mon Sep 17 00:00:00 2001 From: Gideon Okuro Date: Fri, 13 Dec 2024 16:36:19 +0300 Subject: [PATCH 25/38] migrate myDownload service --- .../myplanet/datamanager/MyDownloadService.kt | 28 ++++++++----------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/app/src/main/java/org/ole/planet/myplanet/datamanager/MyDownloadService.kt b/app/src/main/java/org/ole/planet/myplanet/datamanager/MyDownloadService.kt index 11ed49d7b4..53d4b6b0cc 100644 --- a/app/src/main/java/org/ole/planet/myplanet/datamanager/MyDownloadService.kt +++ b/app/src/main/java/org/ole/planet/myplanet/datamanager/MyDownloadService.kt @@ -8,11 +8,11 @@ import android.content.SharedPreferences import android.os.IBinder import androidx.core.app.NotificationCompat import androidx.localbroadcastmanager.content.LocalBroadcastManager -import io.realm.Realm +import io.realm.kotlin.Realm import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext import okhttp3.ResponseBody import org.ole.planet.myplanet.model.Download import org.ole.planet.myplanet.model.RealmMyLibrary @@ -26,7 +26,6 @@ import java.io.* import kotlin.math.roundToInt class MyDownloadService : Service() { - private var count = 0 private var data = ByteArray(1024 * 4) private var outputFile: File? = null private var notificationBuilder: NotificationCompat.Builder? = null @@ -36,9 +35,8 @@ class MyDownloadService : Service() { private lateinit var urls: Array private var currentIndex = 0 private var request: Call? = null - private var completeAll = false private var fromSync = false - + private val serviceScope = CoroutineScope(Dispatchers.IO + Job()) private val databaseService: DatabaseService by lazy { DatabaseService() } private val mRealm: Realm by lazy { databaseService.realmInstance } @@ -59,7 +57,7 @@ class MyDownloadService : Service() { urls = urlSet.toTypedArray() fromSync = intent?.getBooleanExtra("fromSync", false) == true - CoroutineScope(Dispatchers.IO).launch { + serviceScope.launch { urls.forEachIndexed { index, url -> currentIndex = index initDownload(url, fromSync) @@ -209,19 +207,17 @@ class MyDownloadService : Service() { } private fun changeOfflineStatus() { - CoroutineScope(Dispatchers.IO).launch { + serviceScope.launch { if (urls.isNotEmpty() && currentIndex >= 0 && currentIndex < urls.size) { val currentFileName = getFileNameFromUrl(urls[currentIndex]) - withContext(Dispatchers.Main) { - mRealm.executeTransaction { realm -> - realm.where(RealmMyLibrary::class.java) - .equalTo("resourceLocalAddress", currentFileName) - .findAll() - ?.forEach { - it.resourceOffline = true - it.downloadedRev = it._rev + mRealm.write { + query(RealmMyLibrary::class, "resourceLocalAddress == $0", currentFileName) + .find().forEach { + findLatest(it)?.apply { + resourceOffline = true + downloadedRev = _rev } - } + } } } } From 60b1a5152509e4a49c75b422f53d548991c9e36c Mon Sep 17 00:00:00 2001 From: Gideon Okuro Date: Fri, 13 Dec 2024 16:53:50 +0300 Subject: [PATCH 26/38] migrate service class to the kotlin realmsdk --- .../planet/myplanet/datamanager/Service.kt | 141 +++++++++--------- 1 file changed, 72 insertions(+), 69 deletions(-) diff --git a/app/src/main/java/org/ole/planet/myplanet/datamanager/Service.kt b/app/src/main/java/org/ole/planet/myplanet/datamanager/Service.kt index de64caf55d..5c25ffc82c 100644 --- a/app/src/main/java/org/ole/planet/myplanet/datamanager/Service.kt +++ b/app/src/main/java/org/ole/planet/myplanet/datamanager/Service.kt @@ -8,7 +8,7 @@ import android.net.Uri import android.text.TextUtils import com.google.gson.Gson import com.google.gson.JsonObject -import io.realm.Realm +import io.realm.kotlin.Realm import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob @@ -190,7 +190,9 @@ class Service(private val context: Context) { override fun onResponse(call: Call, response: Response) { if (response.body() != null && response.body()!!.has("id")) { uploadToShelf(obj) - saveUserToDb(realm, response.body()!!.get("id").asString, obj, callback) + serviceScope.launch { + saveUserToDb(realm, response.body()!!.get("id").asString, obj, callback) + } } else { callback.onSuccess("Unable to create user") } @@ -211,21 +213,27 @@ class Service(private val context: Context) { override fun notAvailable() { val settings = MainApplication.context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE) - if (isUserExists(realm, obj["name"].asString)) { - callback.onSuccess("User already exists") - return - } - realm.beginTransaction() - val model = populateUsersTable(obj, realm, settings) - val keyString = generateKey() - val iv = generateIv() - if (model != null) { - model.key = keyString - model.iv = iv + serviceScope.launch { + if (isUserExists(realm, obj["name"].asString)) { + callback.onSuccess("User already exists") + return@launch + } + + val model = populateUsersTable(obj, realm, settings) + realm.write { + val keyString = generateKey() + val iv = generateIv() + if (model != null) { + findLatest(model)?.apply { + key = keyString + this.iv = iv + } + } + } + + Utilities.toast(MainApplication.context, "Not connected to planet, created user offline.") + callback.onSuccess("Not connected to planet, created user offline.") } - realm.commitTransaction() - Utilities.toast(MainApplication.context, "Not connected to planet, created user offline.") - callback.onSuccess("Not connected to planet, created user offline.") } }) } @@ -238,86 +246,81 @@ class Service(private val context: Context) { }) } - private fun saveUserToDb(realm: Realm, id: String, obj: JsonObject, callback: CreateUserCallback) { + private suspend fun saveUserToDb(realm: Realm, id: String, obj: JsonObject, callback: CreateUserCallback) { val settings = MainApplication.context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE) - realm.executeTransactionAsync({ realm1: Realm? -> - try { + try { + withContext(Dispatchers.IO) { val res = retrofitInterface?.getJsonObject(Utilities.header, Utilities.getUrl() + "/_users/" + id)?.execute() if (res?.body() != null) { - val model = populateUsersTable(res.body(), realm1, settings) - if (model != null) { - UploadToShelfService(MainApplication.context).saveKeyIv(retrofitInterface, model, obj) + val model = populateUsersTable(res.body(), realm, settings) + realm.write { + if (model != null) { + UploadToShelfService(MainApplication.context).saveKeyIv(retrofitInterface, model, obj) + } } } - } catch (e: IOException) { - e.printStackTrace() } - }, { callback.onSuccess("User created successfully") isNetworkConnectedFlow.onEach { isConnected -> if (isConnected) { val serverUrl = settings.getString("serverURL", "") if (!serverUrl.isNullOrEmpty()) { - serviceScope.launch { - val canReachServer = withContext(Dispatchers.IO) { - isServerReachable(serverUrl) - } - if (canReachServer) { - if (context is ProcessUserDataActivity) { - context.runOnUiThread { - context.startUpload("becomeMember") - } + val canReachServer = withContext(Dispatchers.IO) { + isServerReachable(serverUrl) + } + if (canReachServer) { + if (context is ProcessUserDataActivity) { + withContext(Dispatchers.Main) { + context.startUpload("becomeMember") } - TransactionSyncManager.syncDb(realm, "tablet_users") } + TransactionSyncManager.syncDb(realm, "tablet_users") } } } }.launchIn(serviceScope) - }) { error: Throwable -> + } catch (error: Exception) { error.printStackTrace() callback.onSuccess("Unable to save user please sync") } } - fun syncPlanetServers(realm: Realm, callback: SuccessListener) { - retrofitInterface?.getJsonObject("", "https://planet.earth.ole.org/db/communityregistrationrequests/_all_docs?include_docs=true")?.enqueue(object : Callback { - override fun onResponse(call: Call, response: Response) { - if (response.body() != null) { - val arr = JsonUtils.getJsonArray("rows", response.body()) - if (!realm.isClosed) { - realm.executeTransactionAsync({ realm1: Realm -> - realm1.delete(RealmCommunity::class.java) - for (j in arr) { - var jsonDoc = j.asJsonObject - jsonDoc = JsonUtils.getJsonObject("doc", jsonDoc) - val id = JsonUtils.getString("_id", jsonDoc) - val community = realm1.createObject(RealmCommunity::class.java, id) - if (JsonUtils.getString("name", jsonDoc) == "learning") { - community.weight = 0 - } - community.localDomain = JsonUtils.getString("localDomain", jsonDoc) - community.name = JsonUtils.getString("name", jsonDoc) - community.parentDomain = JsonUtils.getString("parentDomain", jsonDoc) - community.registrationRequest = JsonUtils.getString("registrationRequest", jsonDoc) + suspend fun syncPlanetServers(realm: Realm, callback: SuccessListener) { + try { + val response = withContext(Dispatchers.IO) { + retrofitInterface?.getJsonObject("", "https://planet.earth.ole.org/db/communityregistrationrequests/_all_docs?include_docs=true")?.execute() + } + + if (response?.body() != null) { + val arr = JsonUtils.getJsonArray("rows", response.body()) + realm.write { + // Delete existing communities + query(RealmCommunity::class).find().forEach { delete(it) } + // Add new communities + arr.forEach { j -> + var jsonDoc = j.asJsonObject + jsonDoc = JsonUtils.getJsonObject("doc", jsonDoc) + val id = JsonUtils.getString("_id", jsonDoc) + + val community = RealmCommunity().apply { + this.id = id + if (JsonUtils.getString("name", jsonDoc) == "learning") { + weight = 0 } - }, { - realm.close() - callback.onSuccess("Server sync successfully") - }) { error: Throwable -> - realm.close() - error.printStackTrace() - callback.onSuccess("Unable to connect to planet earth") + localDomain = JsonUtils.getString("localDomain", jsonDoc) + name = JsonUtils.getString("name", jsonDoc) + parentDomain = JsonUtils.getString("parentDomain", jsonDoc) + registrationRequest = JsonUtils.getString("registrationRequest", jsonDoc) } + copyToRealm(community) } } + callback.onSuccess("Server sync successfully") } - - override fun onFailure(call: Call, t: Throwable) { - realm.close() - callback.onSuccess("Unable to connect to planet earth") - } - }) + } catch (error: Exception) { + error.printStackTrace() + callback.onSuccess("Unable to connect to planet earth") + } } fun getMinApk(listener: ConfigurationIdListener?, url: String, pin: String, activity: SyncActivity) { From 4dbe86580f333e759669f90c52470b159e7a0595 Mon Sep 17 00:00:00 2001 From: Gideon Okuro Date: Tue, 17 Dec 2024 13:35:57 +0300 Subject: [PATCH 27/38] resolve realmCourseProgress error --- .../myplanet/model/RealmCourseProgress.kt | 56 ++++++++----------- 1 file changed, 23 insertions(+), 33 deletions(-) diff --git a/app/src/main/java/org/ole/planet/myplanet/model/RealmCourseProgress.kt b/app/src/main/java/org/ole/planet/myplanet/model/RealmCourseProgress.kt index 3c85633474..6a31fd1337 100644 --- a/app/src/main/java/org/ole/planet/myplanet/model/RealmCourseProgress.kt +++ b/app/src/main/java/org/ole/planet/myplanet/model/RealmCourseProgress.kt @@ -3,27 +3,13 @@ package org.ole.planet.myplanet.model import com.google.gson.JsonObject import com.opencsv.CSVWriter import io.realm.kotlin.Realm -import io.realm.kotlin.RealmConfiguration import io.realm.kotlin.ext.query -import io.realm.kotlin.ext.realmListOf -import io.realm.kotlin.query.Sort import io.realm.kotlin.types.RealmObject import io.realm.kotlin.types.annotations.PrimaryKey -import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.asFlow -import kotlinx.coroutines.flow.first -import kotlinx.coroutines.flow.flatMapLatest -import kotlinx.coroutines.flow.map -import kotlinx.coroutines.flow.toList -import org.ole.planet.myplanet.MainApplication.Companion.context -import org.ole.planet.myplanet.model.RealmMyCourse.Companion.getCourseSteps -import org.ole.planet.myplanet.model.RealmMyCourse.Companion.getMyCourseByUserId -import org.ole.planet.myplanet.model.RealmMyCourse.Companion.isMyCourse +import kotlinx.coroutines.flow.* +import org.ole.planet.myplanet.MainApplication import org.ole.planet.myplanet.utilities.JsonUtils -import java.io.File -import java.io.FileWriter -import java.io.IOException +import java.io.* class RealmCourseProgress : RealmObject { @PrimaryKey @@ -55,18 +41,23 @@ class RealmCourseProgress : RealmObject { } } - suspend fun getCourseProgress(realm: Realm, userId: String): Flow> { - return getMyCourseByUserId(userId).map { courses -> - courses.map { course -> - getCourseSteps(course.courseId).first().let { steps -> - if (isMyCourse(userId, course.courseId)) { - course.courseId to JsonObject().apply { - addProperty("max", steps.size) - addProperty("current", getCurrentProgress(steps, realm, userId, course.courseId)) - } - } else null - } - }.filterNotNull().toMap() + fun getCourseProgress(realm: Realm, userId: String): Flow> { + return flow { + val courses = realm.query().find() + val myCourses = RealmMyCourse.getMyCourseByUserId(userId, courses) + + val progressMap = myCourses.mapNotNull { course -> + val steps = RealmMyCourse.getCourseSteps(realm, course.courseId) + + if (RealmMyCourse.isMyCourse(userId, course.courseId, realm)) { + course.courseId to JsonObject().apply { + addProperty("max", steps.size) + addProperty("current", getCurrentProgress(steps, realm, userId, course.courseId)) + } + } else null + }.toMap() + + emit(progressMap) } } @@ -135,9 +126,8 @@ class RealmCourseProgress : RealmObject { val file = File(filePath) file.parentFile?.mkdirs() CSVWriter(FileWriter(file)).use { writer -> - writer.writeNext(arrayOf( - "progressId", "progress_rev", "passed", "stepNum", "userId", "parentCode", - "courseId", "createdOn", "createdDate", "updatedDate" + writer.writeNext(arrayOf("progressId", "progress_rev", "passed", "stepNum", + "userId", "parentCode", "courseId", "createdOn", "createdDate", "updatedDate" )) data.forEach { row -> writer.writeNext(row) @@ -149,7 +139,7 @@ class RealmCourseProgress : RealmObject { } fun progressWriteCsv() { - writeCsv("${context.getExternalFilesDir(null)}/ole/chatHistory.csv", progressDataList) + writeCsv("${MainApplication.context.getExternalFilesDir(null)}/ole/chatHistory.csv", progressDataList) } } } From 70630681cddd880306c345e4422d04d12e8e086c Mon Sep 17 00:00:00 2001 From: Gideon Okuro Date: Wed, 18 Dec 2024 16:01:40 +0300 Subject: [PATCH 28/38] migrate syncManager and task notification worker --- .../planet/myplanet/model/RealmMyCourse.kt | 4 +- .../planet/myplanet/model/RealmMyLibrary.kt | 10 +- .../planet/myplanet/service/SyncManager.kt | 236 ++++++++---------- .../service/TaskNotificationWorker.kt | 41 +-- 4 files changed, 145 insertions(+), 146 deletions(-) diff --git a/app/src/main/java/org/ole/planet/myplanet/model/RealmMyCourse.kt b/app/src/main/java/org/ole/planet/myplanet/model/RealmMyCourse.kt index 35481598c1..98cf0979a5 100644 --- a/app/src/main/java/org/ole/planet/myplanet/model/RealmMyCourse.kt +++ b/app/src/main/java/org/ole/planet/myplanet/model/RealmMyCourse.kt @@ -69,7 +69,7 @@ class RealmMyCourse : RealmObject { private val concatenatedLinks = ArrayList() val courseDataList: MutableList> = 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 { @@ -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) diff --git a/app/src/main/java/org/ole/planet/myplanet/model/RealmMyLibrary.kt b/app/src/main/java/org/ole/planet/myplanet/model/RealmMyLibrary.kt index 8229e6d1a3..9b4edfdfee 100644 --- a/app/src/main/java/org/ole/planet/myplanet/model/RealmMyLibrary.kt +++ b/app/src/main/java/org/ole/planet/myplanet/model/RealmMyLibrary.kt @@ -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 @@ -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?) { diff --git a/app/src/main/java/org/ole/planet/myplanet/service/SyncManager.kt b/app/src/main/java/org/ole/planet/myplanet/service/SyncManager.kt index 48f53cfc79..5dd7e16413 100644 --- a/app/src/main/java/org/ole/planet/myplanet/service/SyncManager.kt +++ b/app/src/main/java/org/ole/planet/myplanet/service/SyncManager.kt @@ -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 @@ -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 @@ -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() { @@ -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() } } @@ -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) @@ -144,36 +120,48 @@ class SyncManager private constructor(private val context: Context) { } } - @Throws(IOException::class) - private fun syncResource(dbClient: ApiInterface?) { - val newIds: MutableList = 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 = 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 = save(getJsonArray("rows", response.body()), mRealm) - newIds.addAll(ids) + private suspend fun syncResource(dbClient: ApiInterface?) { + val newIds = mutableListOf() + + 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() + + 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) { @@ -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) { @@ -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, 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, 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? diff --git a/app/src/main/java/org/ole/planet/myplanet/service/TaskNotificationWorker.kt b/app/src/main/java/org/ole/planet/myplanet/service/TaskNotificationWorker.kt index 5610ebf71b..fc4e610ffe 100644 --- a/app/src/main/java/org/ole/planet/myplanet/service/TaskNotificationWorker.kt +++ b/app/src/main/java/org/ole/planet/myplanet/service/TaskNotificationWorker.kt @@ -3,6 +3,7 @@ package org.ole.planet.myplanet.service import android.content.Context import androidx.work.Worker import androidx.work.WorkerParameters +import io.realm.kotlin.ext.query import org.ole.planet.myplanet.R import org.ole.planet.myplanet.datamanager.DatabaseService import org.ole.planet.myplanet.model.RealmTeamTask @@ -14,23 +15,31 @@ class TaskNotificationWorker(private val context: Context, workerParams: WorkerP override fun doWork(): Result { val mRealm = DatabaseService().realmInstance val current = Calendar.getInstance().timeInMillis - val tomorrow = Calendar.getInstance() - tomorrow.add(Calendar.DAY_OF_YEAR, 1) - val user = UserProfileDbHandler(context).userModel - if (user != null) { - val tasks: List = mRealm.where(RealmTeamTask::class.java) - .equalTo("completed", false) - .equalTo("assignee", user.id) - .equalTo("isNotified", false) - .between("deadline", current, tomorrow.timeInMillis) - .findAll() - mRealm.beginTransaction() - for (`in` in tasks) { - create(context, R.drawable.ole_logo, `in`.title, "Task expires on " + formatDate(`in`.deadline, "")) - `in`.isNotified = true + val tomorrow = Calendar.getInstance().apply { + add(Calendar.DAY_OF_YEAR, 1) + } + + UserProfileDbHandler(context).userModel?.let { user -> + try { + val tasks = mRealm.query("completed == false AND assignee == $0 AND isNotified == false AND deadline BETWEEN {$1, $2}", user.id, current, tomorrow.timeInMillis).find() + + mRealm.writeBlocking { + tasks.forEach { task -> + create(context, R.drawable.ole_logo, task.title, "Task expires on ${formatDate(task.deadline, "")}") + findLatest(task)?.let { latestTask -> + latestTask.isNotified = true + } + } + } + return Result.success() + } catch (e: Exception) { + e.printStackTrace() + return Result.failure() + } finally { + mRealm.close() } - mRealm.commitTransaction() } - return Result.success() + + return Result.failure() } } From 3f94d5fe3b2af385da64baa58cafd0baac13f9a3 Mon Sep 17 00:00:00 2001 From: Gideon Okuro Date: Wed, 18 Dec 2024 16:46:45 +0300 Subject: [PATCH 29/38] migrate transaction syncManager --- .../planet/myplanet/model/RealmFeedback.kt | 19 +- .../ole/planet/myplanet/model/RealmRating.kt | 11 +- .../service/TransactionSyncManager.kt | 280 ++++++++---------- 3 files changed, 139 insertions(+), 171 deletions(-) diff --git a/app/src/main/java/org/ole/planet/myplanet/model/RealmFeedback.kt b/app/src/main/java/org/ole/planet/myplanet/model/RealmFeedback.kt index 72bfef4c4d..5ec7217343 100644 --- a/app/src/main/java/org/ole/planet/myplanet/model/RealmFeedback.kt +++ b/app/src/main/java/org/ole/planet/myplanet/model/RealmFeedback.kt @@ -1,10 +1,12 @@ package org.ole.planet.myplanet.model import com.google.gson.* +import com.opencsv.CSVWriter import io.realm.kotlin.Realm import io.realm.kotlin.ext.query import io.realm.kotlin.types.RealmObject import io.realm.kotlin.types.annotations.PrimaryKey +import org.ole.planet.myplanet.MainApplication import java.io.File import java.io.FileWriter import java.io.IOException @@ -145,20 +147,21 @@ class RealmFeedback : RealmObject { try { val file = File(filePath) file.parentFile?.mkdirs() - val writer = FileWriter(file) - writer.write("feedbackId,title,source,status,priority,owner,openTime,type,url,parentCode,state,item,messages\n") - data.forEach { row -> - writer.write(row.joinToString(",")) - writer.write("\n") + CSVWriter(FileWriter(file)).use { writer -> + writer.writeNext(arrayOf( + "feedbackId","title","source","status","priority","owner","openTime","type","url","parentCode","state","item","messages" + )) + data.forEach { row -> + writer.writeNext(row) + } } - writer.close() } catch (e: IOException) { e.printStackTrace() } } - fun feedbackWriteCsv(filePath: String) { - writeCsv(filePath, feedbacksDataList) + fun feedbackWriteCsv() { + writeCsv("${MainApplication.context.getExternalFilesDir(null)}/ole/feedback.csv", feedbacksDataList) } } } \ No newline at end of file diff --git a/app/src/main/java/org/ole/planet/myplanet/model/RealmRating.kt b/app/src/main/java/org/ole/planet/myplanet/model/RealmRating.kt index 781a7d6008..065a78577e 100644 --- a/app/src/main/java/org/ole/planet/myplanet/model/RealmRating.kt +++ b/app/src/main/java/org/ole/planet/myplanet/model/RealmRating.kt @@ -7,6 +7,7 @@ import io.realm.kotlin.Realm import io.realm.kotlin.ext.query import io.realm.kotlin.types.RealmObject import io.realm.kotlin.types.annotations.PrimaryKey +import org.ole.planet.myplanet.MainApplication import java.io.File import java.io.FileWriter import java.io.IOException @@ -31,7 +32,7 @@ class RealmRating : RealmObject { companion object { private val ratingDataList: MutableList> = mutableListOf() - suspend fun getRatings(realm: Realm, type: String?, userId: String?): Map { + fun getRatings(realm: Realm, type: String?, userId: String?): Map { val results = realm.query("type == $0", type).find() val map = mutableMapOf() @@ -43,7 +44,7 @@ class RealmRating : RealmObject { return map } - suspend fun getRatingsById(realm: Realm, type: String?, id: String?, userId: String?): JsonObject? { + fun getRatingsById(realm: Realm, type: String?, id: String?, userId: String?): JsonObject? { val results = realm.query("type == $0 && itemId == $1", type, id).find() if (results.isEmpty()) return null @@ -77,7 +78,7 @@ class RealmRating : RealmObject { } - suspend fun insert(realm: Realm, act: JsonObject) { + fun insert(realm: Realm, act: JsonObject) { realm.writeBlocking { val rating = query("id == $0", act.get("_id").asString).first().find() ?: RealmRating().apply { @@ -139,8 +140,8 @@ class RealmRating : RealmObject { } } - fun ratingWriteCsv(filePath: String) { - writeCsv(filePath, ratingDataList) + fun ratingWriteCsv() { + writeCsv("${MainApplication.context.getExternalFilesDir(null)}/ole/rating.csv", ratingDataList) } } } \ No newline at end of file diff --git a/app/src/main/java/org/ole/planet/myplanet/service/TransactionSyncManager.kt b/app/src/main/java/org/ole/planet/myplanet/service/TransactionSyncManager.kt index b7284adc50..f291cc7f1e 100644 --- a/app/src/main/java/org/ole/planet/myplanet/service/TransactionSyncManager.kt +++ b/app/src/main/java/org/ole/planet/myplanet/service/TransactionSyncManager.kt @@ -1,63 +1,29 @@ package org.ole.planet.myplanet.service -import android.content.Context -import android.content.SharedPreferences -import android.text.TextUtils +import android.content.* import android.util.Base64 -import com.google.gson.Gson -import com.google.gson.JsonArray -import com.google.gson.JsonObject -import io.realm.Realm +import com.google.gson.* +import io.realm.kotlin.Realm +import kotlinx.coroutines.* import org.ole.planet.myplanet.MainApplication import org.ole.planet.myplanet.callback.SyncListener -import org.ole.planet.myplanet.datamanager.ApiClient.client -import org.ole.planet.myplanet.datamanager.ApiInterface -import org.ole.planet.myplanet.model.DocumentResponse -import org.ole.planet.myplanet.model.RealmAchievement.Companion.achievementWriteCsv -import org.ole.planet.myplanet.model.RealmCertification.Companion.certificationWriteCsv -import org.ole.planet.myplanet.model.RealmChatHistory.Companion.chatWriteCsv -import org.ole.planet.myplanet.model.RealmChatHistory.Companion.insert -import org.ole.planet.myplanet.model.RealmCourseProgress.Companion.progressWriteCsv -import org.ole.planet.myplanet.model.RealmFeedback.Companion.feedbackWriteCsv -import org.ole.planet.myplanet.model.RealmMeetup.Companion.meetupWriteCsv -import org.ole.planet.myplanet.model.RealmMyCourse.Companion.courseWriteCsv -import org.ole.planet.myplanet.model.RealmMyCourse.Companion.saveConcatenatedLinksToPrefs -import org.ole.planet.myplanet.model.RealmMyHealthPojo.Companion.healthWriteCsv -import org.ole.planet.myplanet.model.RealmMyLibrary.Companion.libraryWriteCsv -import org.ole.planet.myplanet.model.RealmMyTeam.Companion.teamWriteCsv -import org.ole.planet.myplanet.model.RealmNews.Companion.newsWriteCsv -import org.ole.planet.myplanet.model.RealmOfflineActivity.Companion.offlineWriteCsv -import org.ole.planet.myplanet.model.RealmRating.Companion.ratingWriteCsv -import org.ole.planet.myplanet.model.RealmStepExam.Companion.insertCourseStepsExams -import org.ole.planet.myplanet.model.RealmStepExam.Companion.stepExamWriteCsv -import org.ole.planet.myplanet.model.RealmSubmission.Companion.submissionWriteCsv -import org.ole.planet.myplanet.model.RealmTag.Companion.tagWriteCsv -import org.ole.planet.myplanet.model.RealmTeamLog.Companion.teamLogWriteCsv -import org.ole.planet.myplanet.model.RealmTeamTask.Companion.teamTaskWriteCsv -import org.ole.planet.myplanet.model.RealmUserModel -import org.ole.planet.myplanet.model.RealmUserModel.Companion.populateUsersTable -import org.ole.planet.myplanet.model.RealmUserModel.Companion.userWriteCsv -import org.ole.planet.myplanet.utilities.Constants -import org.ole.planet.myplanet.utilities.Constants.PREFS_NAME -import org.ole.planet.myplanet.utilities.JsonUtils.getJsonArray -import org.ole.planet.myplanet.utilities.JsonUtils.getJsonObject -import org.ole.planet.myplanet.utilities.JsonUtils.getString -import org.ole.planet.myplanet.utilities.Utilities +import org.ole.planet.myplanet.datamanager.* +import org.ole.planet.myplanet.model.* +import org.ole.planet.myplanet.utilities.* import retrofit2.Response import java.io.IOException object TransactionSyncManager { + private val coroutineScope = CoroutineScope(Dispatchers.IO) fun authenticate(): Boolean { - val apiInterface = client?.create(ApiInterface::class.java) - try { - val response: Response? = apiInterface?.getDocuments(Utilities.header, Utilities.getUrl() + "/tablet_users/_all_docs")?.execute() - if (response != null) { - return response.code() == 200 - } + val apiInterface = ApiClient.client?.create(ApiInterface::class.java) + return try { + val response: Response? = apiInterface?.getDocuments(Utilities.header, "${Utilities.getUrl()}/tablet_users/_all_docs")?.execute() + response?.code() == 200 } catch (e: IOException) { e.printStackTrace() + false } - return false } fun syncAllHealthData(mRealm: Realm, settings: SharedPreferences, listener: SyncListener) { @@ -65,28 +31,32 @@ object TransactionSyncManager { val userName = settings.getString("loginUserName", "") val password = settings.getString("loginUserPassword", "") val header = "Basic " + Base64.encodeToString("$userName:$password".toByteArray(), Base64.NO_WRAP) - mRealm.executeTransactionAsync({ realm: Realm -> - val users = realm.where(RealmUserModel::class.java).isNotEmpty("_id").findAll() - for (userModel in users) { - syncHealthData(userModel, header) + + coroutineScope.launch { + try { + mRealm.write { + val users = query(RealmUserModel::class).find() + users.forEach { userModel -> + syncHealthData(userModel, header) + } + } + listener.onSyncComplete() + } catch (error: Throwable) { + error.message?.let { listener.onSyncFailed(it) } } - }, { listener.onSyncComplete() }) { error: Throwable -> - error.message?.let { listener.onSyncFailed(it) } } } private fun syncHealthData(userModel: RealmUserModel?, header: String) { - val table = "userdb-" + userModel?.planetCode?.let { Utilities.toHex(it) } + "-" + userModel?.name?.let { Utilities.toHex(it) } - val apiInterface = client?.create(ApiInterface::class.java) - val response: Response? + val table = "userdb-${userModel?.planetCode?.let { Utilities.toHex(it) }}-${userModel?.name?.let { Utilities.toHex(it) }}" + val apiInterface = ApiClient.client?.create(ApiInterface::class.java) try { - response = apiInterface?.getDocuments(header, Utilities.getUrl() + "/" + table + "/_all_docs")?.execute() - val ob = response?.body() - if (ob != null && ob.rows?.isNotEmpty() == true) { - val r = ob.rows!![0] - val jsonDoc = apiInterface?.getJsonObject(header, Utilities.getUrl() + "/" + table + "/" + r.id)?.execute()?.body() - userModel?.key = getString("key", jsonDoc) - userModel?.iv = getString("iv", jsonDoc) + val response = apiInterface?.getDocuments(header, "${Utilities.getUrl()}/$table/_all_docs")?.execute() + + response?.body()?.rows?.firstOrNull()?.let { r -> + val jsonDoc = apiInterface.getJsonObject(header, "${Utilities.getUrl()}/$table/${r.id}").execute().body() + userModel?.key = JsonUtils.getString("key", jsonDoc) + userModel?.iv = JsonUtils.getString("iv", jsonDoc) } } catch (e: IOException) { e.printStackTrace() @@ -98,40 +68,61 @@ object TransactionSyncManager { val model = UserProfileDbHandler(MainApplication.context).userModel val userName = settings.getString("loginUserName", "") val password = settings.getString("loginUserPassword", "") -// val table = "userdb-" + model?.planetCode?.let { Utilities.toHex(it) } + "-" + model?.name?.let { Utilities.toHex(it) } - val header = "Basic " + Base64.encodeToString("$userName:$password".toByteArray(), Base64.NO_WRAP) - val id = model?.id - mRealm.executeTransactionAsync({ realm: Realm -> - val userModel = realm.where(RealmUserModel::class.java).equalTo("id", id).findFirst() - syncHealthData(userModel, header) - }, { listener.onSyncComplete() }) { error: Throwable -> - error.message?.let { listener.onSyncFailed(it) } + val header = "Basic " + Base64.encodeToString( + "$userName:$password".toByteArray(), + Base64.NO_WRAP + ) + + coroutineScope.launch { + try { + mRealm.write { + query(RealmUserModel::class, "id == $0", model?.id) + .first().find()?.let { userModel -> + syncHealthData(userModel, header) + } + } + listener.onSyncComplete() + } catch (error: Throwable) { + error.message?.let { listener.onSyncFailed(it) } + } } } fun syncDb(realm: Realm, table: String) { - realm.executeTransactionAsync { mRealm: Realm -> - val apiInterface = client?.create(ApiInterface::class.java) - val allDocs = apiInterface?.getJsonObject(Utilities.header, Utilities.getUrl() + "/" + table + "/_all_docs?include_doc=false") + coroutineScope.launch { try { - val all = allDocs?.execute() - val rows = getJsonArray("rows", all?.body()) - val keys: MutableList = 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 = apiInterface?.findDocs(Utilities.header, "application/json", Utilities.getUrl() + "/" + table + "/_all_docs?include_docs=true", obj)?.execute() - if (response?.body() != null) { - val arr = getJsonArray("rows", response.body()) - if (table == "chat_history") { - insertToChat(arr, mRealm) + realm.write { + val apiInterface = ApiClient.client?.create(ApiInterface::class.java) + val allDocs = apiInterface?.getJsonObject(Utilities.header, "${Utilities.getUrl()}/$table/_all_docs?include_doc=false") + + val all = allDocs?.execute() + val rows = JsonUtils.getJsonArray("rows", all?.body()) + val keys = mutableListOf() + + rows.forEachIndexed { index, element -> + val obj = element.asJsonObject + JsonUtils.getString("id", obj).takeIf { it.isNotEmpty() }?.let { + keys.add(JsonUtils.getString("key", obj)) + } + + if (index == rows.size() - 1 || keys.size == 1000) { + val requestObj = JsonObject().apply { + add("keys", Gson().fromJson(Gson().toJson(keys), JsonArray::class.java)) + } + + val response = apiInterface?.findDocs(Utilities.header, "application/json", "${Utilities.getUrl()}/$table/_all_docs?include_docs=true", requestObj)?.execute() + + response?.body()?.let { body -> + val arr = JsonUtils.getJsonArray("rows", body) + coroutineScope.launch { + when (table) { + "chat_history" -> insertToChat(arr, realm) + else -> insertDocs(arr, realm, table) + } + } } - insertDocs(arr, mRealm, table) + keys.clear() } - keys.clear() } } } catch (e: IOException) { @@ -140,92 +131,65 @@ object TransactionSyncManager { } } - private fun insertToChat(arr: JsonArray, mRealm: Realm) { - val chatHistoryList = mutableListOf() - for (j in arr) { - var jsonDoc = j.asJsonObject - jsonDoc = getJsonObject("doc", jsonDoc) - chatHistoryList.add(jsonDoc) - } - - mRealm.executeTransactionAsync { bgRealm -> - chatHistoryList.forEach { jsonDoc -> - insert(bgRealm, jsonDoc) - } + private suspend fun insertToChat(arr: JsonArray, realm: Realm) { + arr.forEach { element -> + RealmChatHistory.insert(realm, JsonUtils.getJsonObject("doc", element.asJsonObject)) } } - private fun insertDocs(arr: JsonArray, mRealm: Realm, table: String) { - val documentList = mutableListOf() - - for (j in arr) { - var jsonDoc = j.asJsonObject - jsonDoc = getJsonObject("doc", jsonDoc) - val id = getString("_id", jsonDoc) - if (!id.startsWith("_design")) { - documentList.add(jsonDoc) - } - } - mRealm.executeTransactionAsync { bgRealm -> - documentList.forEach { jsonDoc -> - continueInsert(bgRealm, table, jsonDoc) + private suspend fun insertDocs(arr: JsonArray, realm: Realm, table: String) { + arr.forEach { element -> + element.asJsonObject.let { jsonDoc -> + JsonUtils.getJsonObject("doc", jsonDoc).let { doc -> + JsonUtils.getString("_id", doc).takeIf { !it.startsWith("_design") }?.let { + continueInsert(realm, table, doc) + } + } } } } - private fun continueInsert(mRealm: Realm, table: String, jsonDoc: JsonObject) { - val settings = MainApplication.context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE) + private suspend fun continueInsert(realm: Realm, table: String, jsonDoc: JsonObject) { + val settings = MainApplication.context.getSharedPreferences(Constants.PREFS_NAME, Context.MODE_PRIVATE) + when (table) { - "exams" -> { - insertCourseStepsExams("", "", jsonDoc, mRealm) - } - "tablet_users" -> { - populateUsersTable(jsonDoc, mRealm, settings) - } - else -> { - callMethod(mRealm, jsonDoc, table) - } + "exams" -> RealmStepExam.insertCourseStepsExams("", "", jsonDoc, realm) + "tablet_users" -> RealmUserModel.populateUsersTable(jsonDoc, realm, settings) + else -> callMethod(realm, jsonDoc, table) } - saveConcatenatedLinksToPrefs() + + RealmMyCourse.saveConcatenatedLinksToPrefs() val syncFiles = settings.getBoolean("download_sync_files", false) if (syncFiles) { - meetupWriteCsv() - achievementWriteCsv() - certificationWriteCsv() - chatWriteCsv() - progressWriteCsv() - feedbackWriteCsv() - courseWriteCsv() - healthWriteCsv() - libraryWriteCsv() - teamLogWriteCsv() - teamWriteCsv() - newsWriteCsv() - offlineWriteCsv() - ratingWriteCsv() - stepExamWriteCsv() - submissionWriteCsv() - tagWriteCsv() - teamTaskWriteCsv() - userWriteCsv() + RealmMeetup.meetupWriteCsv() + RealmAchievement.achievementWriteCsv() + RealmCertification.certificationWriteCsv() + RealmChatHistory.chatWriteCsv() + RealmCourseProgress.progressWriteCsv() + RealmFeedback.feedbackWriteCsv() + RealmMyCourse.courseWriteCsv() + RealmMyHealthPojo.healthWriteCsv() + RealmMyLibrary.libraryWriteCsv() + RealmTeamLog.teamLogWriteCsv() + RealmMyTeam.teamWriteCsv() + RealmNews.newsWriteCsv() + RealmOfflineActivity.offlineWriteCsv() + RealmRating.ratingWriteCsv() + RealmStepExam.stepExamWriteCsv() + RealmSubmission.submissionWriteCsv() + RealmTag.tagWriteCsv() + RealmTeamTask.teamTaskWriteCsv() + RealmUserModel.userWriteCsv() } } - private fun callMethod(mRealm: Realm, jsonDoc: JsonObject, type: String) { + private fun callMethod(realm: Realm, jsonDoc: JsonObject, type: String) { try { - val methods = Constants.classList[type]?.methods - methods?.let { - for (m in it) { - if ("insert" == m.name) { - m.invoke(null, mRealm, jsonDoc) - break - } - } - } + Constants.classList[type]?.methods?.find { it.name == "insert" }?.invoke(null, realm, jsonDoc) } catch (e: Exception) { e.printStackTrace() } } -} +} \ No newline at end of file From 56c88fbe647d94deac5c90336b934046c523deef Mon Sep 17 00:00:00 2001 From: Gideon Okuro Date: Fri, 20 Dec 2024 15:49:07 +0300 Subject: [PATCH 30/38] migrate service to realm kotlin sdk --- .../planet/myplanet/datamanager/Service.kt | 157 +++++++++--------- 1 file changed, 77 insertions(+), 80 deletions(-) diff --git a/app/src/main/java/org/ole/planet/myplanet/datamanager/Service.kt b/app/src/main/java/org/ole/planet/myplanet/datamanager/Service.kt index 0343e2bf4f..bdd53546e6 100644 --- a/app/src/main/java/org/ole/planet/myplanet/datamanager/Service.kt +++ b/app/src/main/java/org/ole/planet/myplanet/datamanager/Service.kt @@ -52,7 +52,6 @@ import kotlin.math.min class Service(private val context: Context) { private val preferences: SharedPreferences = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE) private val retrofitInterface: ApiInterface? = ApiClient.client?.create(ApiInterface::class.java) - private val serviceScope = CoroutineScope(SupervisorJob() + Dispatchers.Main) fun healthAccess(listener: SuccessListener) { @@ -190,9 +189,7 @@ class Service(private val context: Context) { override fun onResponse(call: Call, response: Response) { if (response.body() != null && response.body()!!.has("id")) { uploadToShelf(obj) - serviceScope.launch { - saveUserToDb(realm, response.body()!!.get("id").asString, obj, callback) - } + saveUserToDb(realm, response.body()!!.get("id").asString, obj, callback) } else { callback.onSuccess("Unable to create user") } @@ -213,9 +210,11 @@ class Service(private val context: Context) { override fun notAvailable() { val settings = MainApplication.context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE) - serviceScope.launch { + serviceScope.launch(Dispatchers.IO) { if (isUserExists(realm, obj["name"].asString)) { - callback.onSuccess("User already exists") + withContext(Dispatchers.Main) { + callback.onSuccess("User already exists") + } return@launch } @@ -223,16 +222,17 @@ class Service(private val context: Context) { realm.write { val keyString = generateKey() val iv = generateIv() - if (model != null) { - findLatest(model)?.apply { - key = keyString - this.iv = iv - } + model?.let { + it.key = keyString + it.iv = iv + copyToRealm(it) } } - Utilities.toast(MainApplication.context, "Not connected to planet, created user offline.") - callback.onSuccess("Not connected to planet, created user offline.") + withContext(Dispatchers.Main) { + Utilities.toast(MainApplication.context, "Not connected to planet, created user offline.") + callback.onSuccess("Not connected to planet, created user offline.") + } } } }) @@ -246,92 +246,89 @@ class Service(private val context: Context) { }) } - private suspend fun saveUserToDb(realm: Realm, id: String, obj: JsonObject, callback: CreateUserCallback) { + private fun saveUserToDb(realm: Realm, id: String, obj: JsonObject, callback: CreateUserCallback) { val settings = MainApplication.context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE) - try { - withContext(Dispatchers.IO) { - val res = retrofitInterface?.getJsonObject(Utilities.header, Utilities.getUrl() + "/_users/" + id)?.execute() + serviceScope.launch(Dispatchers.IO) { + try { + val res = retrofitInterface?.getJsonObject(Utilities.header, "${Utilities.getUrl()}/_users/$id")?.execute() if (res?.body() != null) { val model = populateUsersTable(res.body(), realm, settings) realm.write { - if (model != null) { - UploadToShelfService(MainApplication.context).saveKeyIv(retrofitInterface, model, obj) + model?.let { + copyToRealm(it) + UploadToShelfService(MainApplication.context).saveKeyIv(retrofitInterface, it, obj) } } - } - } - callback.onSuccess("User created successfully") - isNetworkConnectedFlow.onEach { isConnected -> - if (isConnected) { - val serverUrl = settings.getString("serverURL", "") - if (!serverUrl.isNullOrEmpty()) { - val canReachServer = withContext(Dispatchers.IO) { - isServerReachable(serverUrl) - } - if (canReachServer) { - if (context is ProcessUserDataActivity) { - withContext(Dispatchers.Main) { - context.startUpload("becomeMember") + withContext(Dispatchers.Main) { + callback.onSuccess("User created successfully") + } + + isNetworkConnectedFlow.onEach { isConnected -> + if (isConnected) { + val serverUrl = settings.getString("serverURL", "") + if (!serverUrl.isNullOrEmpty()) { + val canReachServer = withContext(Dispatchers.IO) { + isServerReachable(serverUrl) + } + if (canReachServer) { + if (context is ProcessUserDataActivity) { + withContext(Dispatchers.Main) { + context.startUpload("becomeMember") + } + } + TransactionSyncManager.syncDb(realm, "tablet_users") } } - TransactionSyncManager.syncDb(realm, "tablet_users") } - } + }.launchIn(serviceScope) + } + } catch (e: IOException) { + e.printStackTrace() + withContext(Dispatchers.Main) { + callback.onSuccess("Unable to save user please sync") } - }.launchIn(serviceScope) - } catch (error: Exception) { - error.printStackTrace() - callback.onSuccess("Unable to save user please sync") + } } } - suspend fun syncPlanetServers(realm: Realm, callback: SuccessListener) { - try { - val response = withContext(Dispatchers.IO) { - retrofitInterface?.getJsonObject("", "https://planet.earth.ole.org/db/communityregistrationrequests/_all_docs?include_docs=true")?.execute() - } - - if (response?.body() != null) { - val arr = JsonUtils.getJsonArray("rows", response.body()) - realm.write { - // Delete existing communities - query(RealmCommunity::class).find().forEach { delete(it) } - // Add new communities - arr.forEach { j -> - var jsonDoc = j.asJsonObject - jsonDoc = JsonUtils.getJsonObject("doc", jsonDoc) - val id = JsonUtils.getString("_id", jsonDoc) - - val community = RealmCommunity().apply { - this.id = id - if (JsonUtils.getString("name", jsonDoc) == "learning") { - weight = 0 + fun syncPlanetServers(realm: Realm, callback: SuccessListener) { + retrofitInterface?.getJsonObject("", "https://planet.earth.ole.org/db/communityregistrationrequests/_all_docs?include_docs=true")?.enqueue(object : Callback { + override fun onResponse(call: Call, response: Response) { + if (response.body() != null) { + val arr = JsonUtils.getJsonArray("rows", response.body()) + serviceScope.launch(Dispatchers.IO) { + realm.write { + // Delete existing communities + query(RealmCommunity::class).find().forEach { delete(it) } + + // Add new communities + arr.forEach { j -> + var jsonDoc = j.asJsonObject + jsonDoc = JsonUtils.getJsonObject("doc", jsonDoc) + val id = JsonUtils.getString("_id", jsonDoc) + + val community = RealmCommunity().apply { + this.id = id + if (JsonUtils.getString("name", jsonDoc) == "learning") { + this.weight = 0 + } + this.localDomain = JsonUtils.getString("localDomain", jsonDoc) + this.name = JsonUtils.getString("name", jsonDoc) + this.parentDomain = JsonUtils.getString("parentDomain", jsonDoc) + this.registrationRequest = JsonUtils.getString("registrationRequest", jsonDoc) + } + copyToRealm(community) } - localDomain = JsonUtils.getString("localDomain", jsonDoc) - name = JsonUtils.getString("name", jsonDoc) - parentDomain = JsonUtils.getString("parentDomain", jsonDoc) - registrationRequest = JsonUtils.getString("registrationRequest", jsonDoc) - }, { - realm.close() + } + + withContext(Dispatchers.Main) { callback.onSuccess("Server sync successfully") - }) { error: Throwable -> - realm.close() - error.printStackTrace() } - copyToRealm(community) } } - callback.onSuccess("Server sync successfully") } - } catch (error: Exception) { - error.printStackTrace() - callback.onSuccess("Unable to connect to planet earth") - } - - override fun onFailure(call: Call, t: Throwable) { - realm.close() - } + override fun onFailure(call: Call, t: Throwable) {} }) } @@ -489,4 +486,4 @@ class Service(private val context: Context) { interface ConfigurationIdListener { fun onConfigurationIdReceived(id: String, code: String) } -} +} \ No newline at end of file From 65d7834be5a8c93d4a0ce124254e325210864ac8 Mon Sep 17 00:00:00 2001 From: Gideon Okuro Date: Fri, 20 Dec 2024 17:08:39 +0300 Subject: [PATCH 31/38] migrate uploadManager to realm kotlin sdk --- .../ole/planet/myplanet/model/RealmRating.kt | 21 +- .../planet/myplanet/service/UploadManager.kt | 692 ++++++++++-------- 2 files changed, 389 insertions(+), 324 deletions(-) diff --git a/app/src/main/java/org/ole/planet/myplanet/model/RealmRating.kt b/app/src/main/java/org/ole/planet/myplanet/model/RealmRating.kt index 065a78577e..f576ac74a4 100644 --- a/app/src/main/java/org/ole/planet/myplanet/model/RealmRating.kt +++ b/app/src/main/java/org/ole/planet/myplanet/model/RealmRating.kt @@ -16,13 +16,14 @@ class RealmRating : RealmObject { @PrimaryKey var id: String = "" var createdOn: String? = null - var rev: String? = null + var _rev: String? = null var time: Long = 0 var title: String? = null var userId: String? = null var isUpdated: Boolean = false var rate: Int = 0 - var itemId: String? = null + var _id: String? = null + var item: String? = null var comment: String? = null var parentCode: String? = null var planetCode: String? = null @@ -37,8 +38,8 @@ class RealmRating : RealmObject { val map = mutableMapOf() for (rating in results) { - val ratingObject = getRatingsById(realm, rating.type, rating.itemId, userId) - if (ratingObject != null) map[rating.itemId] = ratingObject + val ratingObject = getRatingsById(realm, rating.type, rating.item, userId) + if (ratingObject != null) map[rating.item] = ratingObject } return map @@ -62,10 +63,10 @@ class RealmRating : RealmObject { fun serializeRating(realmRating: RealmRating): JsonObject { val jsonObject = JsonObject() - jsonObject.addProperty("_id", realmRating.id) - jsonObject.addProperty("_rev", realmRating.rev) + jsonObject.addProperty("_id", realmRating._id) + jsonObject.addProperty("_rev", realmRating._rev) jsonObject.add("user", Gson().fromJson(realmRating.user, JsonObject::class.java)) - jsonObject.addProperty("item", realmRating.itemId) + jsonObject.addProperty("item", realmRating.item) jsonObject.addProperty("type", realmRating.type) jsonObject.addProperty("title", realmRating.title) jsonObject.addProperty("time", realmRating.time) @@ -82,15 +83,15 @@ class RealmRating : RealmObject { realm.writeBlocking { val rating = query("id == $0", act.get("_id").asString).first().find() ?: RealmRating().apply { - id = act.get("_id").asString + _id = act.get("_id").asString }.also { copyToRealm(it) } rating.apply { - rev = act.get("_rev").asString + _rev = act.get("_rev").asString time = act.get("time").asLong title = act.get("title").asString type = act.get("type").asString - itemId = act.get("item").asString + item = act.get("item").asString rate = act.get("rate").asInt isUpdated = false comment = act.get("comment").asString diff --git a/app/src/main/java/org/ole/planet/myplanet/service/UploadManager.kt b/app/src/main/java/org/ole/planet/myplanet/service/UploadManager.kt index d96da79c6e..587ad825b2 100644 --- a/app/src/main/java/org/ole/planet/myplanet/service/UploadManager.kt +++ b/app/src/main/java/org/ole/planet/myplanet/service/UploadManager.kt @@ -4,9 +4,14 @@ import android.content.Context import android.content.SharedPreferences import android.text.TextUtils import com.google.gson.Gson +import com.google.gson.JsonArray import com.google.gson.JsonObject -import io.realm.Realm -import io.realm.RealmResults +import io.realm.kotlin.Realm +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import okhttp3.MediaType import okhttp3.RequestBody import org.ole.planet.myplanet.MainApplication @@ -72,37 +77,40 @@ import java.util.Date class UploadManager(var context: Context) : FileUploadService() { var pref: SharedPreferences = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE) private val dbService: DatabaseService = DatabaseService() - lateinit var mRealm: Realm + private val realm: Realm by lazy { dbService.realmInstance } + private val scope = CoroutineScope(Dispatchers.IO + SupervisorJob()) + private val apiInterface = client?.create(ApiInterface::class.java) private fun uploadNewsActivities() { - val apiInterface = client?.create(ApiInterface::class.java) - mRealm = dbService.realmInstance - mRealm.executeTransactionAsync { realm: Realm -> - val newsLog: List = realm.where(RealmNewsLog::class.java).isNull("_id").or().isEmpty("_id").findAll() - for (news in newsLog) { - try { - val `object` = apiInterface?.postDoc(Utilities.header, "application/json", Utilities.getUrl() + "/myplanet_activities", serialize(news))?.execute()?.body() - if (`object` != null) { - news._id = getString("id", `object`) - news._rev = getString("rev", `object`) + scope.launch { + realm.write { + val newsLog = query(RealmNewsLog::class).query("_id == null || _id == ''").find() + for (news in newsLog) { + try { + val `object` = apiInterface?.postDoc(Utilities.header, "application/json", "${Utilities.getUrl()}/myplanet_activities", serialize(news))?.execute()?.body() + if (`object` != null) { + findLatest(news)?.apply { + _id = getString("id", `object`) + _rev = getString("rev", `object`) + } + } + } catch (e: IOException) { + e.printStackTrace() } - } catch (e: IOException) { - e.printStackTrace() } } } } fun uploadActivities(listener: SuccessListener?) { - val apiInterface = client?.create(ApiInterface::class.java) val model = UserProfileDbHandler(MainApplication.context).userModel ?: return if (model.isManager()) return try { - apiInterface?.postDoc(Utilities.header, "application/json", Utilities.getUrl() + "/myplanet_activities", getNormalMyPlanetActivities(MainApplication.context, pref, model))?.enqueue(object : Callback { + apiInterface?.postDoc(Utilities.header, "application/json", "${Utilities.getUrl()}/myplanet_activities", getNormalMyPlanetActivities(MainApplication.context, pref, model))?.enqueue(object : Callback { override fun onResponse(call: Call, response: Response) {} override fun onFailure(call: Call, t: Throwable) {} }) - apiInterface?.getJsonObject(Utilities.header, Utilities.getUrl() + "/myplanet_activities/" + getAndroidId(MainApplication.context) + "@" + getUniqueIdentifier())?.enqueue(object : Callback { + apiInterface?.getJsonObject(Utilities.header, "${Utilities.getUrl()}/myplanet_activities/${getAndroidId(MainApplication.context)}@${getUniqueIdentifier()}")?.enqueue(object : Callback { override fun onResponse(call: Call, response: Response) { var `object` = response.body() if (`object` != null) { @@ -112,7 +120,7 @@ class UploadManager(var context: Context) : FileUploadService() { } else { `object` = getMyPlanetActivities(context, pref, model) } - apiInterface.postDoc(Utilities.header, "application/json", Utilities.getUrl() + "/myplanet_activities", `object`).enqueue(object : Callback { + apiInterface.postDoc(Utilities.header, "application/json", "${Utilities.getUrl()}/myplanet_activities", `object`).enqueue(object : Callback { override fun onResponse(call: Call, response: Response) { listener?.onSuccess("My planet activities uploaded successfully") } @@ -129,25 +137,29 @@ class UploadManager(var context: Context) : FileUploadService() { } fun uploadExamResult(listener: SuccessListener) { - mRealm = dbService.realmInstance - val apiInterface = client?.create(ApiInterface::class.java) - mRealm.executeTransactionAsync( - { realm: Realm -> - val submissions: List = realm.where( - RealmSubmission::class.java - ).findAll() - for (sub in submissions) { + val submissions = realm.query(RealmSubmission::class).find() + scope.launch { + try { + submissions.forEach { sub -> try { - if ((sub.answers?.size ?: 0) > 0) { - continueResultUpload(sub, apiInterface, realm, context) + if (sub.answers.isNotEmpty()) { + withContext(Dispatchers.IO) { + continueResultUpload(sub, apiInterface, realm) + } } } catch (e: Exception) { e.printStackTrace() } } - }, - { listener.onSuccess("Result sync completed successfully") }) { e: Throwable -> e.printStackTrace() } - uploadCourseProgress() + + withContext(Dispatchers.Main) { + listener.onSuccess("Result sync completed successfully") + } + } catch (e: Exception) { + e.printStackTrace() + } + uploadCourseProgress() + } } private fun createImage(user: RealmUserModel?, imgObject: JsonObject?): JsonObject { @@ -155,10 +167,10 @@ class UploadManager(var context: Context) : FileUploadService() { `object`.addProperty("title", getString("fileName", imgObject)) `object`.addProperty("createdDate", Date().time) `object`.addProperty("filename", getString("fileName", imgObject)) - `object`.addProperty("addedBy", user!!.id) + `object`.addProperty("addedBy", user?.id) `object`.addProperty("private", true) - `object`.addProperty("resideOn", user.parentCode) - `object`.addProperty("sourcePlanet", user.planetCode) + `object`.addProperty("resideOn", user?.parentCode) + `object`.addProperty("sourcePlanet", user?.planetCode) val object1 = JsonObject() `object`.addProperty("androidId", getUniqueIdentifier()) `object`.addProperty("deviceName", getDeviceName()) @@ -169,136 +181,148 @@ class UploadManager(var context: Context) : FileUploadService() { } fun uploadAchievement() { - mRealm = dbService.realmInstance -// val apiInterface = client?.create(ApiInterface::class.java) - mRealm.executeTransactionAsync { realm: Realm -> - val list: List = realm.where(RealmAchievement::class.java).findAll() - for (sub in list) { - try { - if (sub._id?.startsWith("guest") == true) { - continue + scope.launch { + realm.write { + val list = query(RealmAchievement::class).find() + for (sub in list) { + try { + if (sub._id.startsWith("guest") == true) { + continue + } + } catch (e: IOException) { + e.printStackTrace() } -// val ob = apiInterface?.putDoc(Utilities.header, "application/json", Utilities.getUrl() + "/achievements/" + sub.get_id(), serialize(sub))?.execute()?.body() -// if (ob == null) { -// val re = apiInterface?.postDoc(Utilities.header, "application/json", Utilities.getUrl() + "/achievements", serialize(sub))?.execute()?.errorBody() -// } - } catch (e: IOException) { - e.printStackTrace() } } } } private fun uploadCourseProgress() { - val apiInterface = client?.create(ApiInterface::class.java) - mRealm = dbService.realmInstance - mRealm.executeTransactionAsync { realm: Realm -> - val data: List = realm.where(RealmCourseProgress::class.java).isNull("_id").findAll() - for (sub in data) { - try { - if (sub.userId?.startsWith("guest") == true) { - continue - } - val `object` = apiInterface?.postDoc(Utilities.header, "application/json", Utilities.getUrl() + "/courses_progress", serializeProgress(sub))?.execute()?.body() - if (`object` != null) { - sub._id = getString("id", `object`) - sub._rev = getString("rev", `object`) + scope.launch { + realm.write { + val data = query(RealmCourseProgress::class).query("_id == null").find() + for (sub in data) { + try { + if (sub.userId.startsWith("guest") == true) { + continue + } + val `object` = apiInterface?.postDoc(Utilities.header, "application/json", "${Utilities.getUrl()}/courses_progress", serializeProgress(sub))?.execute()?.body() + if (`object` != null) { + findLatest(sub)?.apply { + _id = getString("id", `object`) + _rev = getString("rev", `object`) + } + } + } catch (e: IOException) { + e.printStackTrace() } - } catch (e: IOException) { - e.printStackTrace() } } } } fun uploadFeedback(listener: SuccessListener) { - val apiInterface = client?.create(ApiInterface::class.java) - mRealm = dbService.realmInstance - mRealm.executeTransactionAsync(Realm.Transaction { realm: Realm -> - val feedbacks: List = realm.where(RealmFeedback::class.java).findAll() - for (feedback in feedbacks) { - try { - val res: Response? = apiInterface?.postDoc(Utilities.header, "application/json", Utilities.getUrl() + "/feedback", serializeFeedback(feedback))?.execute() - val r = res?.body() - if (r != null) { - val revElement = r["rev"] - val idElement = r["id"] - if (revElement != null && idElement != null) { - feedback._rev = revElement.asString - feedback._id = idElement.asString + scope.launch { + try { + realm.write { + val feedbacks = query(RealmFeedback::class).find() + for (feedback in feedbacks) { + try { + val res = apiInterface?.postDoc(Utilities.header, "application/json", "${Utilities.getUrl()}/feedback", serializeFeedback(feedback))?.execute() + val r = res?.body() + if (r != null) { + val revElement = r["rev"] + val idElement = r["id"] + if (revElement != null && idElement != null) { + findLatest(feedback)?.apply { + _rev = revElement.asString + _id = idElement.asString + } + } + } + } catch (e: IOException) { + e.printStackTrace() } } - } catch (e: IOException) { - e.printStackTrace() } - } }, - Realm.Transaction.OnSuccess { listener.onSuccess("Feedback sync completed successfully") }) + withContext(Dispatchers.Main) { + listener.onSuccess("Feedback sync completed successfully") + } + } catch (e: Exception) { + e.printStackTrace() + } + } } fun uploadSubmitPhotos(listener: SuccessListener?) { - mRealm = DatabaseService().realmInstance - val apiInterface = client?.create(ApiInterface::class.java) - mRealm.executeTransactionAsync { realm: Realm -> - val data: List = realm.where(RealmSubmitPhotos::class.java).equalTo("uploaded", false).findAll() - for (sub in data) { - try { - val `object` = apiInterface?.postDoc(Utilities.header, "application/json", Utilities.getUrl() + "/submissions", serializeRealmSubmitPhotos(sub))?.execute()?.body() - if (`object` != null) { - val rev = getString("rev", `object`) - val id = getString("id", `object`) - sub.uploaded = true - sub._rev = rev - sub._id = id - uploadAttachment(id, rev, sub, listener!!) + scope.launch { + realm.write { + val data = query(RealmSubmitPhotos::class).query("uploaded == false").find() + for (sub in data) { + try { + val `object` = apiInterface?.postDoc(Utilities.header, "application/json", "${Utilities.getUrl()}/submissions", serializeRealmSubmitPhotos(sub))?.execute()?.body() + + if (`object` != null) { + findLatest(sub)?.apply { + val rev = getString("rev", `object`) + val id = getString("id", `object`) + uploaded = true + _rev = rev + _id = id + } + uploadAttachment(getString("id", `object`), getString("rev", `object`), sub, listener!!) + } + } catch (e: Exception) { + e.printStackTrace() } - } catch (e: Exception) { - e.printStackTrace() } } } } fun uploadResource(listener: SuccessListener?) { - mRealm = DatabaseService().realmInstance - val apiInterface = client?.create(ApiInterface::class.java) - mRealm.executeTransactionAsync { realm: Realm -> - val user = realm.where(RealmUserModel::class.java).equalTo("id", pref.getString("userId", "")).findFirst() - val data: List = realm.where(RealmMyLibrary::class.java).isNull("_rev").findAll() - for (sub in data) { - try { - val `object` = apiInterface?.postDoc(Utilities.header, "application/json", Utilities.getUrl() + "/resources", serialize(sub, user))?.execute()?.body() - if (`object` != null) { - val rev = getString("rev", `object`) - val id = getString("id", `object`) - sub._rev = rev - sub._id = id - uploadAttachment(id, rev, sub, listener!!) + scope.launch { + realm.write { + val user = query(RealmUserModel::class).query("id == $0", pref.getString("userId", "")).first().find() + val data = query(RealmMyLibrary::class).query("_rev == null").find() + + for (sub in data) { + try { + val `object` = apiInterface?.postDoc(Utilities.header, "application/json", "${Utilities.getUrl()}/resources", serialize(sub, user))?.execute()?.body() + + if (`object` != null) { + findLatest(sub)?.apply { + _rev = getString("rev", `object`) + _id = getString("id", `object`) + } + uploadAttachment(getString("id", `object`), getString("rev", `object`), sub, listener!!) + } + } catch (e: Exception) { + e.printStackTrace() } - } catch (e: Exception) { - e.printStackTrace() } } } } fun uploadMyPersonal(personal: RealmMyPersonal, listener: SuccessListener) { - mRealm = DatabaseService().realmInstance - val apiInterface = client?.create(ApiInterface::class.java) if (!personal.isUploaded) { - apiInterface?.postDoc(Utilities.header, "application/json", Utilities.getUrl() + "/resources", serialize(personal, context))?.enqueue(object : Callback { + apiInterface?.postDoc(Utilities.header, "application/json", "${Utilities.getUrl()}/resources", serialize(personal, context))?.enqueue(object : Callback { override fun onResponse(call: Call, response: Response) { val `object` = response.body() if (`object` != null) { - if (!mRealm.isInTransaction) { - mRealm.beginTransaction() + scope.launch { + realm.write { + findLatest(personal)?.apply { + val rev = getString("rev", `object`) + val id = getString("id", `object`) + isUploaded = true + _rev = rev + _id = id + } + } + uploadAttachment(getString("id", `object`), getString("rev", `object`), personal, listener) } - val rev = getString("rev", `object`) - val id = getString("id", `object`) - personal.isUploaded = true - personal._rev = rev - personal._id = id - mRealm.commitTransaction() - uploadAttachment(id, rev, personal, listener) } } @@ -310,23 +334,23 @@ class UploadManager(var context: Context) : FileUploadService() { } fun uploadTeamTask() { - mRealm = DatabaseService().realmInstance - val apiInterface = client?.create(ApiInterface::class.java) - mRealm.executeTransactionAsync { realm: Realm -> - val list: List = realm.where(RealmTeamTask::class.java).findAll() - for (task in list) { - if (TextUtils.isEmpty(task._id) || task.isUpdated) { - var `object`: JsonObject? - try { - `object` = apiInterface?.postDoc(Utilities.header, "application/json", Utilities.getUrl() + "/tasks", serialize(realm, task))?.execute()?.body() - if (`object` != null) { - val rev = getString("rev", `object`) - val id = getString("id", `object`) - task._rev = rev - task._id = id + scope.launch { + realm.write { + val list = query(RealmTeamTask::class).find() + for (task in list) { + if (TextUtils.isEmpty(task._id) || task.isUpdated) { + try { + val `object` = apiInterface?.postDoc(Utilities.header, "application/json", "${Utilities.getUrl()}/tasks", serialize(realm, task))?.execute()?.body() + + if (`object` != null) { + findLatest(task)?.apply { + _rev = getString("rev", `object`) + _id = getString("id", `object`) + } + } + } catch (e: IOException) { + e.printStackTrace() } - } catch (e: IOException) { - e.printStackTrace() } } } @@ -334,152 +358,179 @@ class UploadManager(var context: Context) : FileUploadService() { } fun uploadTeams() { - val apiInterface = client?.create(ApiInterface::class.java) - mRealm = dbService.realmInstance - mRealm.executeTransactionAsync { realm: Realm -> - val teams: List = realm.where(RealmMyTeam::class.java).equalTo("updated", true).findAll() - for (team in teams) { - try { - val `object` = apiInterface?.postDoc(Utilities.header, "application/json", Utilities.getUrl() + "/teams", serialize(team))?.execute()?.body() - if (`object` != null) { - team._rev = getString("rev", `object`) - team.updated = false + scope.launch { + realm.write { + val teams = query(RealmMyTeam::class).query("updated == true").find() + for (team in teams) { + try { + val `object` = apiInterface?.postDoc(Utilities.header, "application/json", "${Utilities.getUrl()}/teams", serialize(team))?.execute()?.body() + + if (`object` != null) { + findLatest(team)?.apply { + _rev = getString("rev", `object`) + updated = false + } + } + } catch (e: IOException) { + e.printStackTrace() } - } catch (e: IOException) { - e.printStackTrace() } } } } fun uploadUserActivities(listener: SuccessListener) { - val apiInterface = client?.create(ApiInterface::class.java) - mRealm = dbService.realmInstance val model = UserProfileDbHandler(MainApplication.context).userModel ?: return - if (model.isManager()) { - return - } - mRealm.executeTransactionAsync({ realm: Realm -> - val activities = realm.where(RealmOfflineActivity::class.java).isNull("_rev").equalTo("type", "login").findAll() - for (act in activities) { - try { - if (act.userId?.startsWith("guest") == true) { - continue + if (model.isManager()) return + + scope.launch { + try { + realm.write { + val activities = query(RealmOfflineActivity::class).query("_rev == null AND type == 'login'").find() + + for (act in activities) { + try { + if (act.userId?.startsWith("guest") == true) continue + val `object` = apiInterface?.postDoc(Utilities.header, "application/json", "${Utilities.getUrl()}/login_activities", serializeLoginActivities(act, context))?.execute()?.body() + findLatest(act)?.changeRev(`object`) + } catch (e: IOException) { + e.printStackTrace() + } } - val `object` = apiInterface?.postDoc(Utilities.header, "application/json", Utilities.getUrl() + "/login_activities", serializeLoginActivities(act, context))?.execute()?.body() - act.changeRev(`object`) - } catch (e: IOException) { - e.printStackTrace() + + uploadTeamActivities() + } + + withContext(Dispatchers.Main) { + listener.onSuccess("Sync with server completed successfully") + } + } catch (e: Throwable) { + withContext(Dispatchers.Main) { + listener.onSuccess(e.message) } } - uploadTeamActivities(realm, apiInterface) }, - { listener.onSuccess("Sync with server completed successfully") }) { e: Throwable -> - listener.onSuccess(e.message) } } - private fun uploadTeamActivities(realm: Realm, apiInterface: ApiInterface?) { - val logs = realm.where(RealmTeamLog::class.java).isNull("_rev").findAll() - for (log in logs) { - try { - val `object` = apiInterface?.postDoc(Utilities.header, "application/json", Utilities.getUrl() + "/team_activities", serializeTeamActivities(log, context))?.execute()?.body() - if (`object` != null) { - log._id = getString("id", `object`) - log._rev = getString("rev", `object`) + private fun uploadTeamActivities() { + scope.launch { + realm.write { + val logs = query(RealmTeamLog::class).query("_rev == null").find() + for (log in logs) { + try { + val `object` = apiInterface?.postDoc(Utilities.header, "application/json", "${Utilities.getUrl()}/team_activities", serializeTeamActivities(log, context))?.execute()?.body() + + if (`object` != null) { + val latest = findLatest(log) + if (latest != null) { + latest._id = getString("id", `object`) + latest._rev = getString("rev", `object`) + } + } + } catch (e: IOException) { + e.printStackTrace() + } } - } catch (e: IOException) { - e.printStackTrace() } } } fun uploadRating() { - mRealm = dbService.realmInstance - val apiInterface = client?.create(ApiInterface::class.java) - mRealm.executeTransactionAsync { realm: Realm -> - val activities = realm.where(RealmRating::class.java).equalTo("isUpdated", true).findAll() - for (act in activities) { - try { - if (act.userId?.startsWith("guest") == true) { - continue - } - val `object`: Response? = - if (TextUtils.isEmpty(act._id)) { - apiInterface?.postDoc(Utilities.header, "application/json", Utilities.getUrl() + "/ratings", serializeRating(act))?.execute() + scope.launch { + realm.write { + val activities = query(RealmRating::class).query("isUpdated == true").find() + for (act in activities) { + try { + if (act.userId?.startsWith("guest") == true) continue + val `object`: Response? = if (TextUtils.isEmpty(act._id)) { + apiInterface?.postDoc(Utilities.header, "application/json", "${Utilities.getUrl()}/ratings", serializeRating(act))?.execute() } else { - apiInterface?.putDoc(Utilities.header, "application/json", Utilities.getUrl() + "/ratings/" + act._id, serializeRating(act))?.execute() - } - if (`object`?.body() != null) { - act._id = getString("id", `object`.body()) - act._rev = getString("rev", `object`.body()) - act.isUpdated = false + apiInterface?.putDoc(Utilities.header, "application/json", "${Utilities.getUrl()}/ratings/${act._id}", serializeRating(act))?.execute() + } + + if (`object`?.body() != null) { + findLatest(act)?.apply { + _id = getString("id", `object`.body()) + _rev = getString("rev", `object`.body()) + isUpdated = false + } + } + } catch (e: Exception) { + e.printStackTrace() } - } catch (e: Exception) { - e.printStackTrace() } } } } fun uploadNews() { - mRealm = dbService.realmInstance - val apiInterface = client?.create(ApiInterface::class.java) -// val userModel = UserProfileDbHandler(context).userModel - mRealm.executeTransactionAsync { realm: Realm -> - val activities = realm.where(RealmNews::class.java).findAll() - for (act in activities) { - try { - if (act.userId?.startsWith("guest") == true) { - continue - } - val `object` = serializeNews(act) - val image = act.imagesArray - val user = realm.where(RealmUserModel::class.java).equalTo("id", pref.getString("userId", "")).findFirst() - if (act.imageUrls != null) { - for (imageObject in act.imageUrls ?: emptyList()) { - val imgObject = Gson().fromJson(imageObject, JsonObject::class.java) - val ob = createImage(user, imgObject) - val response = apiInterface?.postDoc(Utilities.header, "application/json", Utilities.getUrl() + "/resources", ob)?.execute()?.body() - val rev = getString("rev", response) - val id = getString("id", response) - val f = File(getString("imageUrl", imgObject)) - val name = getFileNameFromUrl(getString("imageUrl", imgObject)) - val format = "%s/resources/%s/%s" - val connection = f.toURI().toURL().openConnection() - val mimeType = connection.contentType - val body = RequestBody.create(MediaType.parse("application/octet"), fullyReadFileToBytes(f)) - val url = String.format(format, Utilities.getUrl(), id, name) - val res = apiInterface?.uploadResource(getHeaderMap(mimeType, rev), url, body)?.execute() - val attachment = res?.body() - val resourceObject = JsonObject() - resourceObject.addProperty("resourceId", getString("id", attachment)) - resourceObject.addProperty("filename", getString("fileName", imgObject)) - val markdown = "![](resources/" + getString("id", attachment) + "/" + getString("fileName", imgObject) + ")" - resourceObject.addProperty("markdown", markdown) - var msg = getString("message", `object`) - msg += """ - - $markdown - """.trimIndent() - `object`.addProperty("message", msg) - image.add(resourceObject) + scope.launch { + realm.write { + val activities = query(RealmNews::class).find() + for (act in activities) { + try { + if (act.userId?.startsWith("guest") == true) { + continue } - } - act.images = Gson().toJson(image) - `object`.add("images", image) - val newsUploadResponse: Response? = - if (TextUtils.isEmpty(act._id)) { - apiInterface?.postDoc(Utilities.header, "application/json", Utilities.getUrl() + "/news", `object`)?.execute() - } else { - apiInterface?.putDoc(Utilities.header, "application/json", Utilities.getUrl() + "/news/" + act._id, `object`)?.execute() + val `object` = serializeNews(act) + val image = JsonArray() + val user = query(RealmUserModel::class).query("id == $0", pref.getString("userId", "")).first().find() + + act.imageUrls?.let { urls -> + for (imageObject in urls) { + val imgObject = Gson().fromJson(imageObject, JsonObject::class.java) + val ob = createImage(user, imgObject) + val response = apiInterface?.postDoc(Utilities.header, "application/json", "${Utilities.getUrl()}/resources", ob)?.execute()?.body() + + val rev = getString("rev", response) + val id = getString("id", response) + val f = File(getString("imageUrl", imgObject)) + val name = getFileNameFromUrl(getString("imageUrl", imgObject)) + val format = "%s/resources/%s/%s" + val connection = f.toURI().toURL().openConnection() + val mimeType = connection.contentType + val body = RequestBody.create(MediaType.parse("application/octet"), fullyReadFileToBytes(f)) + val url = String.format(format, Utilities.getUrl(), id, name) + val res = apiInterface?.uploadResource(getHeaderMap(mimeType, rev), url, body)?.execute() + val attachment = res?.body() + + val resourceObject = JsonObject() + resourceObject.addProperty("resourceId", getString("id", attachment)) + resourceObject.addProperty("filename", getString("fileName", imgObject)) + val markdown = "![](resources/${getString("id", attachment)}/${getString("fileName", imgObject)})" + resourceObject.addProperty("markdown", markdown) + var msg = getString("message", `object`) + msg += """ + + $markdown + """.trimIndent() + `object`.addProperty("message", msg) + image.add(resourceObject) + } + } + + findLatest(act)?.apply { + images = Gson().toJson(image) } - if (newsUploadResponse?.body() != null) { - act.imageUrls?.clear() - act._id = getString("id", newsUploadResponse.body()) - act._rev = getString("rev", newsUploadResponse.body()) + `object`.add("images", image) + + val newsUploadResponse: Response? = + if (TextUtils.isEmpty(act._id)) { + apiInterface?.postDoc(Utilities.header, "application/json", "${Utilities.getUrl()}/news", `object`)?.execute() + } else { + apiInterface?.putDoc(Utilities.header, "application/json", "${Utilities.getUrl()}/news/${act._id}", `object`)?.execute() + } + + if (newsUploadResponse?.body() != null) { + findLatest(act)?.apply { + imageUrls?.clear() + _id = getString("id", newsUploadResponse.body()) + _rev = getString("rev", newsUploadResponse.body()) + } + } + } catch (e: Exception) { + e.printStackTrace() } - } catch (e: Exception) { - e.printStackTrace() } } } @@ -487,86 +538,99 @@ class UploadManager(var context: Context) : FileUploadService() { } fun uploadCrashLog() { - mRealm = dbService.realmInstance - val apiInterface = client?.create(ApiInterface::class.java) - mRealm.executeTransactionAsync(Realm.Transaction { realm: Realm -> - val logs: RealmResults = realm.where(RealmApkLog::class.java).isNull("_rev").findAll() - for (act in logs) { - try { - val o = apiInterface?.postDoc(Utilities.header, "application/json", Utilities.getUrl() + "/apk_logs", serialize(act, context))?.execute()?.body() - if (o != null) { - act._rev = getString("rev", o) + scope.launch { + try { + realm.write { + val logs = query(RealmApkLog::class).query("_rev == null").find() + for (act in logs) { + try { + val o = apiInterface?.postDoc(Utilities.header, "application/json", "${Utilities.getUrl()}/apk_logs", serialize(act, context))?.execute()?.body() + if (o != null) { + findLatest(act)?.apply { + _rev = getString("rev", o) + } + } + } catch (e: IOException) { + e.printStackTrace() + } } - } catch (e: IOException) { - e.printStackTrace() } + } catch (e: Exception) { + e.printStackTrace() } - }, Realm.Transaction.OnSuccess {}) + } } fun uploadSearchActivity() { - mRealm = dbService.realmInstance - val apiInterface = client?.create(ApiInterface::class.java) - mRealm.executeTransactionAsync { realm: Realm -> - val logs: RealmResults = realm.where(RealmSearchActivity::class.java).isEmpty("_rev").findAll() - for (act in logs) { - try { - val o = apiInterface?.postDoc(Utilities.header, "application/json", Utilities.getUrl() + "/search_activities", act.serialize())?.execute()?.body() - if (o != null) { - act._rev = getString("rev", o) + scope.launch { + realm.write { + val logs = query(RealmSearchActivity::class).query("_rev == ''").find() + for (act in logs) { + try { + val serializedData = act.serialize().let { kotlinxJson -> + Gson().fromJson(kotlinxJson.toString(), JsonObject::class.java) + } + + val o = apiInterface?.postDoc(Utilities.header, "application/json", "${Utilities.getUrl()}/search_activities", serializedData)?.execute()?.body() + + if (o != null) { + findLatest(act)?.apply { + _rev = getString("rev", o) + } + } + } catch (e: IOException) { + e.printStackTrace() } - } catch (e: IOException) { - e.printStackTrace() } } } } fun uploadResourceActivities(type: String) { - mRealm = dbService.realmInstance - val apiInterface = client?.create(ApiInterface::class.java) - val db = if (type == "sync") { - "admin_activities" - } else { - "resource_activities" - } - mRealm.executeTransactionAsync { realm: Realm -> - val activities: RealmResults = - if (type == "sync") { - realm.where(RealmResourceActivity::class.java).isNull("_rev").equalTo("type", "sync").findAll() + val db = if (type == "sync") "admin_activities" else "resource_activities" + scope.launch { + realm.write { + val activities = if (type == "sync") { + query(RealmResourceActivity::class) + .query("_rev == null && type == 'sync'").find() } else { - realm.where(RealmResourceActivity::class.java).isNull("_rev").notEqualTo("type", "sync").findAll() + query(RealmResourceActivity::class) + .query("_rev == null && type != 'sync'").find() } - for (act in activities) { - try { - val `object` = apiInterface?.postDoc(Utilities.header, "application/json", Utilities.getUrl() + "/" + db, serializeResourceActivities(act))?.execute()?.body() - if (`object` != null) { - act._rev = getString("rev", `object`) - act._id = getString("id", `object`) + + for (act in activities) { + try { + val `object` = apiInterface?.postDoc(Utilities.header, "application/json", "${Utilities.getUrl()}/$db", serializeResourceActivities(act))?.execute()?.body() + if (`object` != null) { + findLatest(act)?.apply { + _rev = getString("rev", `object`) + _id = getString("id", `object`) + } + } + } catch (e: IOException) { + e.printStackTrace() } - } catch (e: IOException) { - e.printStackTrace() } } } } fun uploadCourseActivities() { - mRealm = dbService.realmInstance - val apiInterface = client?.create(ApiInterface::class.java) - mRealm.executeTransactionAsync { realm: Realm -> - val activities: RealmResults = - realm.where(RealmCourseActivity::class.java).isNull("_rev") - .notEqualTo("type", "sync").findAll() - for (act in activities) { - try { - val `object` = apiInterface?.postDoc(Utilities.header, "application/json", Utilities.getUrl() + "/course_activities", serializeSerialize(act))?.execute()?.body() - if (`object` != null) { - act._rev = getString("rev", `object`) - act._id = getString("id", `object`) + scope.launch { + realm.write { + val activities = query(RealmCourseActivity::class).query("_rev == null && type != 'sync'").find() + for (act in activities) { + try { + val `object` = apiInterface?.postDoc(Utilities.header, "application/json", "${Utilities.getUrl()}/course_activities", serializeSerialize(act))?.execute()?.body() + if (`object` != null) { + findLatest(act)?.apply { + _rev = getString("rev", `object`) + _id = getString("id", `object`) + } + } + } catch (e: IOException) { + e.printStackTrace() } - } catch (e: IOException) { - e.printStackTrace() } } } From 9f115010ec3a3f870e7b8c09855bc5bc8fc74dd6 Mon Sep 17 00:00:00 2001 From: Gideon Okuro Date: Fri, 20 Dec 2024 17:36:43 +0300 Subject: [PATCH 32/38] migrate uploadToShelfService to realm kotlin sdk --- .../myplanet/service/UploadToShelfService.kt | 280 ++++++++++-------- 1 file changed, 154 insertions(+), 126 deletions(-) diff --git a/app/src/main/java/org/ole/planet/myplanet/service/UploadToShelfService.kt b/app/src/main/java/org/ole/planet/myplanet/service/UploadToShelfService.kt index c13bd053b4..411f0af793 100644 --- a/app/src/main/java/org/ole/planet/myplanet/service/UploadToShelfService.kt +++ b/app/src/main/java/org/ole/planet/myplanet/service/UploadToShelfService.kt @@ -1,31 +1,19 @@ package org.ole.planet.myplanet.service -import android.content.Context -import android.content.SharedPreferences +import android.content.* import android.text.TextUtils import android.util.Base64 -import com.google.gson.Gson -import com.google.gson.JsonArray -import com.google.gson.JsonObject -import io.realm.Realm +import com.google.gson.* +import io.realm.kotlin.Realm +import kotlinx.coroutines.* import org.ole.planet.myplanet.MainApplication import org.ole.planet.myplanet.callback.SuccessListener 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.model.RealmMeetup.Companion.getMyMeetUpIds -import org.ole.planet.myplanet.model.RealmMyCourse.Companion.getMyCourseIds -import org.ole.planet.myplanet.model.RealmMyHealthPojo -import org.ole.planet.myplanet.model.RealmMyHealthPojo.Companion.serialize -import org.ole.planet.myplanet.model.RealmMyLibrary.Companion.getMyLibIds -import org.ole.planet.myplanet.model.RealmRemovedLog.Companion.removedIds -import org.ole.planet.myplanet.model.RealmUserModel -import org.ole.planet.myplanet.utilities.AndroidDecrypter.Companion.generateIv -import org.ole.planet.myplanet.utilities.AndroidDecrypter.Companion.generateKey +import org.ole.planet.myplanet.datamanager.* +import org.ole.planet.myplanet.model.* +import org.ole.planet.myplanet.utilities.AndroidDecrypter import org.ole.planet.myplanet.utilities.Constants.PREFS_NAME -import org.ole.planet.myplanet.utilities.JsonUtils.getJsonArray -import org.ole.planet.myplanet.utilities.JsonUtils.getString -import org.ole.planet.myplanet.utilities.Utilities +import org.ole.planet.myplanet.utilities.* import retrofit2.Response import java.io.IOException import java.util.Date @@ -33,68 +21,86 @@ import java.util.Date class UploadToShelfService(context: Context) { private val dbService: DatabaseService = DatabaseService() private val sharedPreferences: SharedPreferences = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE) - lateinit var mRealm: Realm + private val realm: Realm by lazy { dbService.realmInstance } + private val scope = CoroutineScope(Dispatchers.IO + SupervisorJob()) + private val apiInterface = client?.create(ApiInterface::class.java) fun uploadUserData(listener: SuccessListener) { - val apiInterface = client?.create(ApiInterface::class.java) - mRealm = dbService.realmInstance - mRealm.executeTransactionAsync({ realm: Realm -> - val userModels: List = realm.where(RealmUserModel::class.java).isEmpty("_id").or().equalTo("isUpdated", true).findAll() - for (model in userModels) { - try { - val password = sharedPreferences.getString("loginUserPassword", "") - val header = "Basic " + Base64.encodeToString(("${model.name}:${password}").toByteArray(), Base64.NO_WRAP) - val res = apiInterface?.getJsonObject(header, "${replacedUrl(model)}/_users/org.couchdb.user:${model.name}")?.execute() - if (res?.body() == null) { - val obj = model.serialize() - val createResponse = apiInterface?.putDoc(null, "application/json", "${replacedUrl(model)}/_users/org.couchdb.user:${model.name}", obj)?.execute() - if (createResponse?.isSuccessful == true) { - val id = createResponse.body()?.get("id")?.asString - val rev = createResponse.body()?.get("rev")?.asString - model._id = id - model._rev = rev - val fetchDataResponse = apiInterface.getJsonObject(header, "${replacedUrl(model)}/_users/$id").execute() - if (fetchDataResponse.isSuccessful) { - model.password_scheme = getString("password_scheme", fetchDataResponse.body()) - model.derived_key = getString("derived_key", fetchDataResponse.body()) - model.salt = getString("salt", fetchDataResponse.body()) - model.iterations = getString("iterations", fetchDataResponse.body()) - if (saveKeyIv(apiInterface, model, obj)) { - updateHealthData(realm, model) - } - } - } - } else if (model.isUpdated) { + scope.launch { + try { + realm.write { + val userModels = query(RealmUserModel::class).query("_id == '' OR isUpdated == true").find() + for (model in userModels) { try { - val latestDocResponse = apiInterface.getJsonObject(header, "${replacedUrl(model)}/_users/org.couchdb.user:${model.name}").execute() - if (latestDocResponse.isSuccessful) { - val latestRev = latestDocResponse.body()?.get("_rev")?.asString + val password = sharedPreferences.getString("loginUserPassword", "") + val header = "Basic ${Base64.encodeToString(("${ model.name }:${ password }").toByteArray(), Base64.NO_WRAP)}" + val res = apiInterface?.getJsonObject(header, "${replacedUrl(model)}/_users/org.couchdb.user:${model.name}")?.execute() + + if (res?.body() == null) { val obj = model.serialize() - val objMap = obj.entrySet().associate { (key, value) -> key to value } - val mutableObj = mutableMapOf().apply { putAll(objMap) } - latestRev?.let { rev -> mutableObj["_rev"] = rev as Any } - val gson = Gson() - val jsonElement = gson.toJsonTree(mutableObj) - val jsonObject = jsonElement.asJsonObject - - val updateResponse = apiInterface.putDoc(header, "application/json", "${replacedUrl(model)}/_users/org.couchdb.user:${model.name}", jsonObject).execute() - if (updateResponse.isSuccessful) { - val updatedRev = updateResponse.body()?.get("rev")?.asString - model._rev = updatedRev - model.isUpdated = false + val createResponse = apiInterface?.putDoc(null, "application/json", "${replacedUrl(model)}/_users/org.couchdb.user:${model.name}", obj)?.execute() + + if (createResponse?.isSuccessful == true) { + val id = createResponse.body()?.get("id")?.asString + val rev = createResponse.body()?.get("rev")?.asString + findLatest(model)?.apply { + _id = id + _rev = rev + } + + val fetchDataResponse = apiInterface.getJsonObject(header, "${replacedUrl(model)}/_users/$id").execute() + if (fetchDataResponse.isSuccessful) { + findLatest(model)?.apply { + password_scheme = JsonUtils.getString("password_scheme", fetchDataResponse.body()) + derived_key = JsonUtils.getString("derived_key", fetchDataResponse.body()) + salt = JsonUtils.getString("salt", fetchDataResponse.body()) + iterations = JsonUtils.getString("iterations", fetchDataResponse.body()) + } + if (saveKeyIv(apiInterface, model, obj)) { + updateHealthData(model) + } + } + } + } else if (model.isUpdated) { + try { + val latestDocResponse = apiInterface.getJsonObject(header, "${replacedUrl(model)}/_users/org.couchdb.user:${model.name}").execute() + + if (latestDocResponse.isSuccessful) { + val latestRev = latestDocResponse.body()?.get("_rev")?.asString + val obj = model.serialize() + val objMap = obj.entrySet().associate { (key, value) -> key to value } + val mutableObj = mutableMapOf().apply { putAll(objMap) } + latestRev?.let { rev -> mutableObj["_rev"] = rev as Any } + val gson = Gson() + val jsonElement = gson.toJsonTree(mutableObj) + val jsonObject = jsonElement.asJsonObject + + val updateResponse = apiInterface.putDoc(header, "application/json", "${replacedUrl(model)}/_users/org.couchdb.user:${model.name}", jsonObject).execute() + + if (updateResponse.isSuccessful) { + findLatest(model)?.apply { + _rev = updateResponse.body()?.get("rev")?.asString + isUpdated = false + } + } + } + } catch (e: IOException) { + e.printStackTrace() } + } else { + Utilities.toast(MainApplication.context, "User ${model.name} already exists") } } catch (e: IOException) { e.printStackTrace() } - } else { - Utilities.toast(MainApplication.context, "User ${model.name} already exists") } - } catch (e: IOException) { - e.printStackTrace() } + uploadToShelf(listener) + } catch (e: Exception) { + e.printStackTrace() + uploadToShelf(listener) } - }, { uploadToShelf(listener) }) { uploadToShelf(listener) } + } } private fun replacedUrl(model: RealmUserModel): String { @@ -106,20 +112,26 @@ class UploadToShelfService(context: Context) { return "$protocol://$replacedUrl" // Append the protocol to the modified URL } - private fun updateHealthData(realm: Realm, model: RealmUserModel) { - val list: List = realm.where(RealmMyHealthPojo::class.java).equalTo("_id", model.id).findAll() - for (p in list) { - p.userId = model._id + private fun updateHealthData(model: RealmUserModel) { + scope.launch { + realm.write { + query(RealmMyHealthPojo::class) + .query("_id == $0", model.id).find().forEach { healthPojo -> + findLatest(healthPojo)?.apply { + userId = model._id + } + } + } } } @Throws(IOException::class) fun saveKeyIv(apiInterface: ApiInterface?, model: RealmUserModel, obj: JsonObject): Boolean { - val table = "userdb-" + Utilities.toHex(model.planetCode) + "-" + Utilities.toHex(model.name) - val header = "Basic " + Base64.encodeToString((obj["name"].asString + ":" + obj["password"].asString).toByteArray(), Base64.NO_WRAP) + val table = "userdb-${Utilities.toHex(model.planetCode)}-${Utilities.toHex(model.name)}" + val header = "Basic ${Base64.encodeToString(("${ obj["name"].asString }:${ obj["password"].asString }").toByteArray(), Base64.NO_WRAP)}" val ob = JsonObject() - var keyString = generateKey() - var iv: String? = generateIv() + var keyString = AndroidDecrypter.generateKey() + var iv: String? = AndroidDecrypter.generateIv() if (!TextUtils.isEmpty(model.iv)) { iv = model.iv } @@ -145,62 +157,78 @@ class UploadToShelfService(context: Context) { } fun uploadHealth() { - val apiInterface = client?.create(ApiInterface::class.java) - mRealm = dbService.realmInstance - mRealm.executeTransactionAsync { realm: Realm -> - val myHealths: List = realm.where(RealmMyHealthPojo::class.java).equalTo("isUpdated", true).notEqualTo("userId", "").findAll() - for (pojo in myHealths) { - try { - val res = apiInterface?.postDoc(Utilities.header, "application/json", Utilities.getUrl() + "/health", serialize(pojo))?.execute() - if (res?.body() != null && res.body()?.has("id") == true) { - pojo._rev = res.body()!!["rev"].asString - pojo.isUpdated = false + scope.launch { + realm.write { + val myHealths = query(RealmMyHealthPojo::class).query("isUpdated == true AND userId != ''").find() + + for (pojo in myHealths) { + try { + val res = apiInterface?.postDoc(Utilities.header, "application/json", "${Utilities.getUrl()}/health", RealmMyHealthPojo.serialize(pojo))?.execute() + + if (res?.body() != null && res.body()?.has("id") == true) { + findLatest(pojo)?.apply { + _rev = res.body()!!["rev"].asString + isUpdated = false + } + } + } catch (e: Exception) { + e.printStackTrace() } - } catch (e: Exception) { - e.printStackTrace() } } } } private fun uploadToShelf(listener: SuccessListener) { - val apiInterface = client?.create(ApiInterface::class.java) - mRealm = dbService.realmInstance - mRealm.executeTransactionAsync({ realm: Realm -> - val users = realm.where(RealmUserModel::class.java).isNotEmpty("_id").findAll() - for (model in users) { - try { - if (model.id?.startsWith("guest") == true) { - continue + scope.launch { + try { + realm.write { + val users = query(RealmUserModel::class).query("_id != ''").find() + for (model in users) { + try { + if (model.id.startsWith("guest") == true) { + continue + } + + val jsonDoc = apiInterface?.getJsonObject(Utilities.header, "${Utilities.getUrl()}/shelf/${model._id}")?.execute()?.body() + + val `object` = getShelfData(model.id, jsonDoc) + val d = apiInterface?.getJsonObject(Utilities.header, "${Utilities.getUrl()}/shelf/${model.id}")?.execute()?.body() + + `object`.addProperty("_rev", JsonUtils.getString("_rev", d)) + apiInterface?.putDoc(Utilities.header, "application/json", "${Utilities.getUrl()}/shelf/${sharedPreferences.getString("userId", "")}", `object`)?.execute()?.body() + } catch (e: Exception) { + e.printStackTrace() + } } - val jsonDoc = apiInterface?.getJsonObject(Utilities.header, Utilities.getUrl() + "/shelf/" + model._id)?.execute()?.body() - val `object` = getShelfData(realm, model.id, jsonDoc) - val d = apiInterface?.getJsonObject(Utilities.header, Utilities.getUrl() + "/shelf/" + model.id)?.execute()?.body() - `object`.addProperty("_rev", getString("_rev", d)) - apiInterface?.putDoc(Utilities.header, "application/json", Utilities.getUrl() + "/shelf/" + sharedPreferences.getString("userId", ""), `object`)?.execute()?.body() - } catch (e: Exception) { - e.printStackTrace() } - } }, - { listener.onSuccess("Sync with server completed successfully") }) { - listener.onSuccess("Unable to update documents.") + withContext(Dispatchers.Main) { + listener.onSuccess("Sync with server completed successfully") + } + } catch (e: Exception) { + e.printStackTrace() + withContext(Dispatchers.Main) { + listener.onSuccess("Unable to update documents.") + } + } } } - private fun getShelfData(realm: Realm?, userId: String?, jsonDoc: JsonObject?): JsonObject { - val myLibs = getMyLibIds(realm, userId) - val myCourses = getMyCourseIds(realm, userId) - val myMeetups = getMyMeetUpIds(realm, userId) - val removedResources = listOf(*removedIds(realm, "resources", userId)) - val removedCourses = listOf(*removedIds(realm, "courses", userId)) - val mergedResourceIds = mergeJsonArray(myLibs, getJsonArray("resourceIds", jsonDoc), removedResources) - val mergedCourseIds = mergeJsonArray(myCourses, getJsonArray("courseIds", jsonDoc), removedCourses) - val `object` = JsonObject() - `object`.addProperty("_id", sharedPreferences.getString("userId", "")) - `object`.add("meetupIds", mergeJsonArray(myMeetups, getJsonArray("meetupIds", jsonDoc), removedResources)) - `object`.add("resourceIds", mergedResourceIds) - `object`.add("courseIds", mergedCourseIds) - return `object` + private fun getShelfData(userId: String, jsonDoc: JsonObject?): JsonObject { + val myLibs = RealmMyLibrary.getMyLibIds(realm, userId) + val myCourses = RealmMyCourse.getMyCourseIds(realm, userId) + val myMeetups = RealmMeetup.getMyMeetUpIds(realm, userId) + val removedResources = listOf(*RealmRemovedLog.removedIds(realm, "resources", userId)) + val removedCourses = listOf(*RealmRemovedLog.removedIds(realm, "courses", userId)) + val mergedResourceIds = mergeJsonArray(myLibs, JsonUtils.getJsonArray("resourceIds", jsonDoc), removedResources) + val mergedCourseIds = mergeJsonArray(myCourses, JsonUtils.getJsonArray("courseIds", jsonDoc), removedCourses) + + return JsonObject().apply { + addProperty("_id", sharedPreferences.getString("userId", "")) + add("meetupIds", mergeJsonArray(myMeetups, JsonUtils.getJsonArray("meetupIds", jsonDoc), removedResources)) + add("resourceIds", mergedResourceIds) + add("courseIds", mergedCourseIds) + } } private fun mergeJsonArray(array1: JsonArray?, array2: JsonArray, removedIds: List): JsonArray { @@ -225,12 +253,12 @@ class UploadToShelfService(context: Context) { private set private fun changeUserSecurity(model: RealmUserModel, obj: JsonObject) { - val table = "userdb-" + Utilities.toHex(model.planetCode) + "-" + Utilities.toHex(model.name) - val header = "Basic " + Base64.encodeToString((obj["name"].asString + ":" + obj["password"].asString).toByteArray(), Base64.NO_WRAP) + val table = "userdb-${Utilities.toHex(model.planetCode)}-${Utilities.toHex(model.name)}" + val header = "Basic ${Base64.encodeToString(("${ obj["name"].asString }:" + "${ obj["password"].asString }").toByteArray(), Base64.NO_WRAP)}" val apiInterface = client?.create(ApiInterface::class.java) val response: Response? try { - response = apiInterface?.getJsonObject(header, Utilities.getUrl() + "/" + table + "/_security")?.execute() + response = apiInterface?.getJsonObject(header, "${Utilities.getUrl()}/$table/_security")?.execute() if (response?.body() != null) { val jsonObject = response.body() val members = jsonObject?.getAsJsonObject("members") @@ -242,7 +270,7 @@ class UploadToShelfService(context: Context) { rolesArray.add("health") members?.add("roles", rolesArray) jsonObject?.add("members", members) - apiInterface?.putDoc(header, "application/json", Utilities.getUrl() + "/" + table + "/_security", jsonObject)?.execute() + apiInterface.putDoc(header, "application/json", "${Utilities.getUrl()}/$table/_security", jsonObject).execute() } } catch (e: IOException) { e.printStackTrace() From 0afd5328aab17f7091179749025744528ef09c3f Mon Sep 17 00:00:00 2001 From: Gideon Okuro Date: Fri, 20 Dec 2024 18:36:49 +0300 Subject: [PATCH 33/38] migrate UserProfileDbHandler to realm kotlin sdk --- .../myplanet/model/RealmOfflineActivity.kt | 2 +- .../myplanet/service/UserProfileDbHandler.kt | 180 ++++++++++-------- .../ole/planet/myplanet/ui/SettingActivity.kt | 2 +- 3 files changed, 98 insertions(+), 86 deletions(-) diff --git a/app/src/main/java/org/ole/planet/myplanet/model/RealmOfflineActivity.kt b/app/src/main/java/org/ole/planet/myplanet/model/RealmOfflineActivity.kt index 804715feaa..6697611336 100644 --- a/app/src/main/java/org/ole/planet/myplanet/model/RealmOfflineActivity.kt +++ b/app/src/main/java/org/ole/planet/myplanet/model/RealmOfflineActivity.kt @@ -26,7 +26,7 @@ class RealmOfflineActivity : RealmObject { var description: String? = null var createdOn: String? = null var parentCode: String? = null - var loginTime: Long? = null + var loginTime: Long = 0L var logoutTime: Long? = null var androidId: String? = null diff --git a/app/src/main/java/org/ole/planet/myplanet/service/UserProfileDbHandler.kt b/app/src/main/java/org/ole/planet/myplanet/service/UserProfileDbHandler.kt index ec52dc7f97..ef9aeee20b 100644 --- a/app/src/main/java/org/ole/planet/myplanet/service/UserProfileDbHandler.kt +++ b/app/src/main/java/org/ole/planet/myplanet/service/UserProfileDbHandler.kt @@ -2,8 +2,13 @@ package org.ole.planet.myplanet.service import android.content.Context import android.content.SharedPreferences -import io.realm.Realm +import io.realm.kotlin.Realm +import io.realm.kotlin.query.Sort +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.launch +import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withContext import org.ole.planet.myplanet.datamanager.DatabaseService import org.ole.planet.myplanet.model.RealmMyLibrary @@ -23,6 +28,7 @@ class UserProfileDbHandler(context: Context) { var mRealm: Realm private val realmService: DatabaseService private val fullName: String + private val scope = CoroutineScope(Dispatchers.IO + SupervisorJob()) init { try { @@ -36,80 +42,79 @@ class UserProfileDbHandler(context: Context) { } } - val userModel: RealmUserModel? get() { - if (mRealm.isClosed) { - mRealm = realmService.realmInstance + val userModel: RealmUserModel? + get() { + if (mRealm.isClosed()) { + return realmService.realmInstance.query(RealmUserModel::class).query("id == $0", settings.getString("userId", "")).first().find() + } + return mRealm.query(RealmUserModel::class).query("id == $0", settings.getString("userId", "")).first().find() } - return mRealm.where(RealmUserModel::class.java) - .equalTo("id", settings.getString("userId", "")) - .findFirst() - } fun onLogin() { - if (!mRealm.isInTransaction) { - mRealm.beginTransaction() + scope.launch { + mRealm.write { + val offlineActivities = createUser() + copyToRealm(offlineActivities).apply { + type = KEY_LOGIN + _rev = null + _id = null + description = "Member login on offline application" + loginTime = Date().time + } + } } - val offlineActivities = mRealm.copyToRealm(createUser()) - offlineActivities.type = KEY_LOGIN - offlineActivities._rev = null - offlineActivities._id = null - offlineActivities.description = "Member login on offline application" - offlineActivities.loginTime = Date().time - mRealm.commitTransaction() } suspend fun onLogout() { withContext(Dispatchers.IO) { - val realm = realmService.realmInstance - try { - realm.executeTransaction { - val offlineActivities = getRecentLogin(it) - offlineActivities?.logoutTime = Date().time + mRealm.write { + val offlineActivities = getRecentLogin(mRealm) + offlineActivities?.let { activity -> + findLatest(activity)?.apply { + logoutTime = Date().time + } } - } finally { - realm.close() } } } fun onDestroy() { - if (!mRealm.isClosed) { + if (!mRealm.isClosed()) { mRealm.close() } } private fun createUser(): RealmOfflineActivity { - val offlineActivities = mRealm.createObject(RealmOfflineActivity::class.java, UUID.randomUUID().toString()) - val model = userModel - offlineActivities.userId = model?.id - offlineActivities.userName = model?.name - offlineActivities.parentCode = model?.parentCode - offlineActivities.createdOn = model?.planetCode - return offlineActivities + return RealmOfflineActivity().apply { + this._id = UUID.randomUUID().toString() + this.userId = userModel?.id + this.userName = userModel?.name + this.parentCode = userModel?.parentCode + this.createdOn = userModel?.planetCode + } } - val lastVisit: Long? get() = mRealm.where(RealmOfflineActivity::class.java).max("loginTime") as Long? + val lastVisit: Long? + get() = mRealm.query(RealmOfflineActivity::class).sort("loginTime", Sort.DESCENDING).first().find()?.loginTime val offlineVisits: Int get() = getOfflineVisits(userModel) - fun getOfflineVisits(m: RealmUserModel?): Int { val dbUsers = mRealm.where(RealmOfflineActivity::class.java).equalTo("userName", m?.name).equalTo("type", KEY_LOGIN).findAll() - return if (!dbUsers.isEmpty()) { - dbUsers.size - } else { - 0 - } + fun getOfflineVisits(m: RealmUserModel?): Int { + return mRealm.query(RealmOfflineActivity::class, "userName == $0 AND type == $1", m?.name, KEY_LOGIN).count().find().toInt() } - fun getLastVisit(m: RealmUserModel): String { - val realm = Realm.getDefaultInstance() - realm.beginTransaction() - val lastLogoutTimestamp = realm.where(RealmOfflineActivity::class.java) - .equalTo("userName", m.name) - .max("loginTime") as Long? - realm.commitTransaction() - return if (lastLogoutTimestamp != null) { - val date = Date(lastLogoutTimestamp) - SimpleDateFormat("MMMM dd, yyyy hh:mm a", Locale.getDefault()).format(date) - } else { + fun getLastVisit(user: RealmUserModel): String { + return try { + val lastLogoutTimestamp = mRealm.query(RealmOfflineActivity::class, "userName == $0", user.name) + .sort("loginTime", Sort.DESCENDING).first().find()?.loginTime + + if (lastLogoutTimestamp != null) { + val date = Date(lastLogoutTimestamp) + SimpleDateFormat("MMMM dd, yyyy hh:mm a", Locale.getDefault()).format(date) + } else { + "No logout record found" + } + } catch (e: Exception) { + e.printStackTrace() "No logout record found" } } @@ -124,48 +129,55 @@ class UserProfileDbHandler(context: Context) { return } - if (!mRealm.isInTransaction) mRealm.beginTransaction() - val offlineActivities = mRealm.copyToRealm(createResourceUser(model)) - offlineActivities.type = type - offlineActivities.title = item.title - offlineActivities.resourceId = item.resourceId - offlineActivities.time = Date().time - mRealm.commitTransaction() + scope.launch { + mRealm.write { + val offlineActivities = createResourceUser(model) + copyToRealm(offlineActivities).apply { + this.type = type + this.title = item.title + this.resourceId = item.resourceId + this.time = Date().time + } + } + } } private fun createResourceUser(model: RealmUserModel?): RealmResourceActivity { - val offlineActivities = mRealm.createObject(RealmResourceActivity::class.java, "${UUID.randomUUID()}") - offlineActivities.user = model?.name - offlineActivities.parentCode = model?.parentCode - offlineActivities.createdOn = model?.planetCode - return offlineActivities + return RealmResourceActivity().apply { + this._id = UUID.randomUUID().toString() + this.user = model?.name + this.parentCode = model?.parentCode + this.createdOn = model?.planetCode + } } - val numberOfResourceOpen: String get() { - val count = mRealm.where(RealmResourceActivity::class.java).equalTo("user", fullName) - .equalTo("type", KEY_RESOURCE_OPEN).count() - return if (count == 0L) "" else "Resource opened $count times." - } + val numberOfResourceOpen: String + get() { + val count = runBlocking { + mRealm.query(RealmResourceActivity::class, "user == $0 AND type == $1", fullName, KEY_RESOURCE_OPEN).count().find() + } + return if (count == 0L) "" else "Resource opened $count times." + } - val maxOpenedResource: String get() { - val result = mRealm.where(RealmResourceActivity::class.java) - .equalTo("user", fullName).equalTo("type", KEY_RESOURCE_OPEN) - .findAll().where().distinct("resourceId").findAll() - var maxCount = 0L - var maxOpenedResource = "" - for (realmResourceActivities in result) { - val count = mRealm.where(RealmResourceActivity::class.java) - .equalTo("user", fullName) - .equalTo("type", KEY_RESOURCE_OPEN) - .equalTo("resourceId", realmResourceActivities.resourceId).count() - - if (count > maxCount) { - maxCount = count - maxOpenedResource = "${realmResourceActivities.title}" + val maxOpenedResource: String + get() { + var maxCount = 0L + var maxOpenedResource = "" + + runBlocking { + val result = mRealm.query(RealmResourceActivity::class, "user == $0 AND type == $1", fullName, KEY_RESOURCE_OPEN).distinct("resourceId").find() + + for (realmResourceActivities in result) { + val count = mRealm.query(RealmResourceActivity::class, "user == $0 AND type == $1 AND resourceId == $2", fullName, KEY_RESOURCE_OPEN, realmResourceActivities.resourceId).count().find() + + if (count > maxCount) { + maxCount = count + maxOpenedResource = "${realmResourceActivities.title}" + } + } } + return if (maxCount == 0L) "" else "$maxOpenedResource opened $maxCount times" } - return if (maxCount == 0L) "" else "$maxOpenedResource opened $maxCount times" - } companion object { const val KEY_LOGIN = "login" diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/SettingActivity.kt b/app/src/main/java/org/ole/planet/myplanet/ui/SettingActivity.kt index 085c918c0b..b0646f6419 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/SettingActivity.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/SettingActivity.kt @@ -21,7 +21,7 @@ import androidx.preference.Preference.OnPreferenceClickListener import androidx.preference.PreferenceFragmentCompat import androidx.preference.PreferenceManager import androidx.preference.SwitchPreference -import io.realm.Realm +import io.realRealm import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch From 5512adb6b9ac9eef41214a1fc9f5d739c554d1e7 Mon Sep 17 00:00:00 2001 From: Gideon Okuro Date: Mon, 23 Dec 2024 15:59:14 +0300 Subject: [PATCH 34/38] migrate settingsActivity --- .../ole/planet/myplanet/MainApplication.kt | 12 +++---- .../myplanet/base/BaseContainerFragment.kt | 2 +- .../myplanet/base/BaseRecyclerFragment.kt | 35 +++++++++--------- .../base/BaseRecyclerParentFragment.kt | 17 +++++---- .../myplanet/base/BaseResourceFragment.kt | 36 +++++++------------ .../ole/planet/myplanet/ui/SettingActivity.kt | 26 +++++++------- 6 files changed, 58 insertions(+), 70 deletions(-) diff --git a/app/src/main/java/org/ole/planet/myplanet/MainApplication.kt b/app/src/main/java/org/ole/planet/myplanet/MainApplication.kt index a9eb86f480..0da0b1e1d7 100644 --- a/app/src/main/java/org/ole/planet/myplanet/MainApplication.kt +++ b/app/src/main/java/org/ole/planet/myplanet/MainApplication.kt @@ -54,7 +54,7 @@ class MainApplication : Application(), Application.ActivityLifecycleCallbacks { private const val STAY_ONLINE_WORK_TAG = "stayOnlineWork" private const val TASK_NOTIFICATION_WORK_TAG = "taskNotificationWork" lateinit var context: Context - lateinit var realm: Realm + lateinit var mRealm: Realm lateinit var service: DatabaseService var preferences: SharedPreferences? = null var syncFailedCount = 0 @@ -76,7 +76,7 @@ class MainApplication : Application(), Application.ActivityLifecycleCallbacks { suspend fun createLog(type: String) { withContext(Dispatchers.IO) { try { - realm.write { + mRealm.write { val log = RealmApkLog().apply { id = UUID.randomUUID().toString() val model = UserProfileDbHandler(context).userModel @@ -149,7 +149,7 @@ class MainApplication : Application(), Application.ActivityLifecycleCallbacks { e.printStackTrace() applicationScope.launch(Dispatchers.IO) { try { - realm.write { + mRealm.write { val log = RealmApkLog().apply { id = UUID.randomUUID().toString() val model = UserProfileDbHandler(context).userModel @@ -190,7 +190,7 @@ class MainApplication : Application(), Application.ActivityLifecycleCallbacks { preferences = getSharedPreferences(PREFS_NAME, MODE_PRIVATE) service = DatabaseService() - realm = service.realmInstance + mRealm = service.realmInstance defaultPref = PreferenceManager.getDefaultSharedPreferences(this) val builder = VmPolicy.Builder() @@ -229,7 +229,7 @@ class MainApplication : Application(), Application.ActivityLifecycleCallbacks { } if (canReachServer) { if (defaultPref.getBoolean("beta_auto_download", false)) { - backgroundDownload(downloadAllFiles(getAllLibraryList(realm))) + backgroundDownload(downloadAllFiles(getAllLibraryList(mRealm))) } } } @@ -330,7 +330,7 @@ class MainApplication : Application(), Application.ActivityLifecycleCallbacks { override fun onTerminate() { super.onTerminate() onAppClosed() - realm.close() + mRealm.close() applicationScope.cancel() } } diff --git a/app/src/main/java/org/ole/planet/myplanet/base/BaseContainerFragment.kt b/app/src/main/java/org/ole/planet/myplanet/base/BaseContainerFragment.kt index 716fb4d104..15adaef4b9 100644 --- a/app/src/main/java/org/ole/planet/myplanet/base/BaseContainerFragment.kt +++ b/app/src/main/java/org/ole/planet/myplanet/base/BaseContainerFragment.kt @@ -124,7 +124,7 @@ abstract class BaseContainerFragment : BaseResourceFragment() { } fun openResource(items: RealmMyLibrary) { - val matchingItems = MainApplication.realm.query(RealmMyLibrary::class, "resourceLocalAddress == $0", items.resourceLocalAddress).find() + val matchingItems = MainApplication.mRealm.query(RealmMyLibrary::class, "resourceLocalAddress == $0", items.resourceLocalAddress).find() val anyOffline = matchingItems.any { it.isResourceOffline() } if (anyOffline) { val offlineItem = matchingItems.first { it.isResourceOffline() } diff --git a/app/src/main/java/org/ole/planet/myplanet/base/BaseRecyclerFragment.kt b/app/src/main/java/org/ole/planet/myplanet/base/BaseRecyclerFragment.kt index 4ee85180e9..9da5c5de3f 100644 --- a/app/src/main/java/org/ole/planet/myplanet/base/BaseRecyclerFragment.kt +++ b/app/src/main/java/org/ole/planet/myplanet/base/BaseRecyclerFragment.kt @@ -18,7 +18,6 @@ import io.realm.kotlin.types.RealmObject import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext -import org.ole.planet.myplanet.MainApplication.Companion.realm import org.ole.planet.myplanet.R import org.ole.planet.myplanet.callback.OnRatingChangeListener import org.ole.planet.myplanet.datamanager.DatabaseService @@ -75,7 +74,7 @@ abstract class BaseRecyclerFragment
  • : BaseRecyclerParentFragment(), On selectedItems = mutableListOf() list = mutableListOf() realmService = DatabaseService() - realm = realmService.realmInstance + mRealm = realmService.realmInstance profileDbHandler = UserProfileDbHandler(requireActivity()) model = profileDbHandler.userModel!! val adapter = getAdapter() @@ -83,7 +82,7 @@ abstract class BaseRecyclerFragment
  • : BaseRecyclerParentFragment(), On if (isMyCourseLib && adapter.itemCount != 0 && courseLib == "courses") { resources?.let { showDownloadDialog(it) } } else if (isMyCourseLib && courseLib == null && !isSurvey) { - showDownloadDialog(getLibraryList(realm)) + showDownloadDialog(getLibraryList(mRealm)) } return v } @@ -107,14 +106,14 @@ abstract class BaseRecyclerFragment
  • : BaseRecyclerParentFragment(), On for (i in selectedItems?.indices!!) { val `object` = selectedItems?.get(i) as RealmObject if (`object` is RealmMyLibrary) { - val myObject = realm.query("resourceId == $0", `object`.resourceId).first().find() - RealmMyLibrary.createFromResource(myObject, realm, model?.id) - RealmRemovedLog.onAdd(realm, "resources", profileDbHandler.userModel?.id, myObject?.resourceId) + val myObject = mRealm.query("resourceId == $0", `object`.resourceId).first().find() + RealmMyLibrary.createFromResource(myObject, mRealm, model?.id) + RealmRemovedLog.onAdd(mRealm, "resources", profileDbHandler.userModel?.id, myObject?.resourceId) toast(activity, getString(R.string.added_to_my_library)) } else { - val myObject = RealmMyCourse.getMyCourse(realm, (`object` as RealmMyCourse).courseId) - RealmMyCourse.createMyCourse(myObject, realm, model?.id) - RealmRemovedLog.onAdd(realm, "courses", profileDbHandler.userModel?.id, myObject?.courseId) + val myObject = RealmMyCourse.getMyCourse(mRealm, (`object` as RealmMyCourse).courseId) + RealmMyCourse.createMyCourse(myObject, mRealm, model?.id) + RealmRemovedLog.onAdd(mRealm, "courses", profileDbHandler.userModel?.id, myObject?.courseId) toast(activity, getString(R.string.added_to_my_courses)) } } @@ -127,13 +126,13 @@ abstract class BaseRecyclerFragment
  • : BaseRecyclerParentFragment(), On for (i in selectedItems?.indices!!) { val `object` = selectedItems?.get(i) as RealmObject if (deleteProgress && `object` is RealmMyCourse) { - val courseProgress = realm.query("courseId == $0", `object`.courseId).find() - val examList = realm.query("courseId == $0", `object`.courseId).find() + val courseProgress = mRealm.query("courseId == $0", `object`.courseId).find() + val examList = mRealm.query("courseId == $0", `object`.courseId).find() val submissionsToDelete = examList.flatMap { exam -> - realm.query("parentId == $0 AND type != $1 AND uploaded == $2", exam.id, "survey", false).find() + mRealm.query("parentId == $0 AND type != $1 AND uploaded == $2", exam.id, "survey", false).find() } - realm.write { + mRealm.write { courseProgress.forEach { delete(it) } submissionsToDelete.forEach { delete(it) } } @@ -157,12 +156,12 @@ abstract class BaseRecyclerFragment
  • : BaseRecyclerParentFragment(), On override fun onDestroy() { super.onDestroy() - realm.close() + mRealm.close() } private fun checkAndAddToList(course: RealmMyCourse?, courses: MutableList, tags: List) { for (tg in tags) { - val count = realm.query("db == $0 AND tagId == $1 AND linkId == $2", "courses", tg.id, course?.courseId).count().find() + val count = mRealm.query("db == $0 AND tagId == $1 AND linkId == $2", "courses", tg.id, course?.courseId).count().find() if (count > 0 && !courses.contains(course)) { course?.let { courses.add(it) } } @@ -172,13 +171,13 @@ abstract class BaseRecyclerFragment
  • : BaseRecyclerParentFragment(), On private inline fun getData(s: String, c: Class
  • ): List
  • { val queryParts = s.split(" ").filterNot { it.isEmpty() } return if (s.contains(" ")) { - val data = realm.query
  • ().find() + val data = mRealm.query
  • ().find() data.filter { item -> searchAndMatch(item, queryParts) } } else { val field = if (c == RealmMyLibrary::class.java) "title" else "courseTitle" - realm.query
  • ("$field CONTAINS[c] $0", s).find() + mRealm.query
  • ("$field CONTAINS[c] $0", s).find() } } @@ -236,7 +235,7 @@ abstract class BaseRecyclerFragment
  • : BaseRecyclerParentFragment(), On private fun filter(tags: List, library: RealmMyLibrary?, libraries: MutableList) { for (tg in tags) { - val count = realm.query("db == $0 AND tagId == $1 AND linkId == $2", "resources", tg.id, library?.id).count().find() + val count = mRealm.query("db == $0 AND tagId == $1 AND linkId == $2", "resources", tg.id, library?.id).count().find() if (count > 0 && !libraries.contains(library)) { library?.let { libraries.add(it) } } diff --git a/app/src/main/java/org/ole/planet/myplanet/base/BaseRecyclerParentFragment.kt b/app/src/main/java/org/ole/planet/myplanet/base/BaseRecyclerParentFragment.kt index f7fd5a3993..55cea470b4 100644 --- a/app/src/main/java/org/ole/planet/myplanet/base/BaseRecyclerParentFragment.kt +++ b/app/src/main/java/org/ole/planet/myplanet/base/BaseRecyclerParentFragment.kt @@ -3,7 +3,6 @@ package org.ole.planet.myplanet.base import com.google.gson.JsonArray import io.realm.kotlin.ext.query import io.realm.kotlin.query.Sort -import org.ole.planet.myplanet.MainApplication.Companion.realm import org.ole.planet.myplanet.model.RealmMyCourse import org.ole.planet.myplanet.model.RealmMyLibrary import org.ole.planet.myplanet.model.RealmStepExam @@ -15,18 +14,18 @@ abstract class BaseRecyclerParentFragment
  • : BaseResourceFragment() { fun getList(c: Class<*>): List
  • { return when { c == RealmStepExam::class.java -> { - realm.query("type == $0", "surveys").find() as List
  • + mRealm.query("type == $0", "surveys").find() as List
  • } isMyCourseLib -> { getMyLibItems(c) } c == RealmMyLibrary::class.java -> { - val results = realm.query("isPrivate == $0", false).find() + val results = mRealm.query("isPrivate == $0", false).find() RealmMyLibrary.getOurLibrary(model?.id, results) as List
  • } else -> { val myLibItems = getMyLibItems(c) - val results = realm.query() + val results = mRealm.query() .query("courseTitle != $0", "") .find() val ourCourseItems = RealmMyCourse.getOurCourse(model?.id ?: "", results) @@ -58,7 +57,7 @@ abstract class BaseRecyclerParentFragment
  • : BaseResourceFragment() { fun getList(c: Class<*>, orderBy: String? = null, sort: Sort = Sort.ASCENDING): List
  • { return when { c == RealmStepExam::class.java -> { - realm.query("type == $0", "surveys").apply { + mRealm.query("type == $0", "surveys").apply { orderBy?.let { sort(it, sort) } }.find() as List
  • } @@ -66,13 +65,13 @@ abstract class BaseRecyclerParentFragment
  • : BaseResourceFragment() { getMyLibItems(c, orderBy) } c == RealmMyLibrary::class.java -> { - val results = realm.query("isPrivate == $0", false).apply { + val results = mRealm.query("isPrivate == $0", false).apply { orderBy?.let { sort(it, sort) } }.find() RealmMyLibrary.getOurLibrary(model?.id, results) as List
  • } else -> { - val results = realm.query().apply { + val results = mRealm.query().apply { orderBy?.let { sort(it, sort) } }.find() RealmMyCourse.getOurCourse(model?.id ?: "", results) as List
  • @@ -84,13 +83,13 @@ abstract class BaseRecyclerParentFragment
  • : BaseResourceFragment() { private fun getMyLibItems(c: Class<*>, orderBy: String? = null): List
  • { return when (c) { RealmMyLibrary::class.java -> { - val results = realm.query().apply { + val results = mRealm.query().apply { orderBy?.let { sort(it) } }.find() RealmMyLibrary.getMyLibraryByUserId(model?.id, results) as List
  • } RealmMyCourse::class.java -> { - val results = realm.query().apply { + val results = mRealm.query().apply { orderBy?.let { sort(it) } }.find() RealmMyCourse.getMyCourseByUserId(model?.id ?: "", results) as List
  • diff --git a/app/src/main/java/org/ole/planet/myplanet/base/BaseResourceFragment.kt b/app/src/main/java/org/ole/planet/myplanet/base/BaseResourceFragment.kt index 95eb7e6e73..be13ad3665 100644 --- a/app/src/main/java/org/ole/planet/myplanet/base/BaseResourceFragment.kt +++ b/app/src/main/java/org/ole/planet/myplanet/base/BaseResourceFragment.kt @@ -27,7 +27,6 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import org.ole.planet.myplanet.MainApplication import org.ole.planet.myplanet.MainApplication.Companion.context -import org.ole.planet.myplanet.MainApplication.Companion.realm import org.ole.planet.myplanet.R import org.ole.planet.myplanet.callback.OnHomeItemClickListener import org.ole.planet.myplanet.datamanager.DatabaseService @@ -148,7 +147,7 @@ abstract class BaseResourceFragment : Fragment() { fun showPendingSurveyDialog() { model = UserProfileDbHandler(requireContext()).userModel - val list = realm.query(RealmSubmission::class, + val list = mRealm.query(RealmSubmission::class, "userId == $0 AND status == $1 AND type == $2", model?.id, "pending", "survey" ).find() @@ -157,7 +156,7 @@ abstract class BaseResourceFragment : Fragment() { return } - val exams = getExamMap(realm, list) + val exams = getExamMap(mRealm, list) val arrayAdapter: ArrayAdapter<*> = object : ArrayAdapter(requireActivity(), android.R.layout.simple_list_item_1, list) { override fun getView(position: Int, convertView: View?, parent: ViewGroup): View { var convertedView = convertView @@ -251,7 +250,7 @@ abstract class BaseResourceFragment : Fragment() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - realm = DatabaseService().realmInstance + mRealm = DatabaseService().realmInstance prgDialog = getProgressDialog(requireActivity()) settings = requireActivity().getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE) editor = settings?.edit() @@ -267,31 +266,29 @@ abstract class BaseResourceFragment : Fragment() { suspend fun removeFromShelf(`object`: RealmObject) { when (`object`) { is RealmMyLibrary -> { - val myObject = realm.query( + val myObject = mRealm.query( RealmMyLibrary::class, "resourceId == $0", `object`.resourceId ).first().find() - realm.write { + mRealm.write { myObject?.removeUserId(model?.id) } model?.id?.let { userId -> - `object`.resourceId?.let { resourceId -> - onRemove(realm, "resources", userId, resourceId) - } + onRemove(mRealm, "resources", userId, `object`.resourceId) } withContext(Dispatchers.Main) { Utilities.toast(activity, getString(R.string.removed_from_mylibrary)) } } is RealmMyCourse -> { - val myObject = getMyCourse(realm, `object`.courseId) - realm.write { + val myObject = getMyCourse(mRealm, `object`.courseId) + mRealm.write { myObject?.removeUserId(model?.id ?: "") } model?.id?.let { userId -> - onRemove(realm, "courses", userId, `object`.courseId) + onRemove(mRealm, "courses", userId, `object`.courseId) } Utilities.toast(activity, getString(R.string.removed_from_mycourse)) } @@ -312,16 +309,11 @@ abstract class BaseResourceFragment : Fragment() { } suspend fun addToLibrary(libraryItems: List, selectedItems: ArrayList) { - realm.write { + mRealm.write { for (i in selectedItems.indices) { if (!libraryItems[selectedItems[i]].userId.contains(profileDbHandler.userModel?.id)) { libraryItems[selectedItems[i]].setUserId(profileDbHandler.userModel?.id) - RealmRemovedLog.onAdd( - realm, - "resources", - profileDbHandler.userModel?.id, - libraryItems[selectedItems[i]].resourceId - ) + RealmRemovedLog.onAdd(mRealm, "resources", profileDbHandler.userModel?.id, libraryItems[selectedItems[i]].resourceId) } } } @@ -329,13 +321,11 @@ abstract class BaseResourceFragment : Fragment() { } suspend fun addAllToLibrary(libraryItems: List) { - realm.write { + mRealm.write { for (libraryItem in libraryItems) { if (!libraryItem.userId.contains(profileDbHandler.userModel?.id)) { libraryItem.setUserId(profileDbHandler.userModel?.id) - RealmRemovedLog.onAdd( - realm, "resources", profileDbHandler.userModel?.id, libraryItem.resourceId - ) + RealmRemovedLog.onAdd(mRealm, "resources", profileDbHandler.userModel?.id, libraryItem.resourceId) } } } diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/SettingActivity.kt b/app/src/main/java/org/ole/planet/myplanet/ui/SettingActivity.kt index b0646f6419..cc26f9229b 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/SettingActivity.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/SettingActivity.kt @@ -10,7 +10,6 @@ import android.view.MenuItem import android.view.View import android.view.ViewGroup import android.widget.ArrayAdapter -import android.widget.ListView import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatDelegate @@ -21,13 +20,10 @@ import androidx.preference.Preference.OnPreferenceClickListener import androidx.preference.PreferenceFragmentCompat import androidx.preference.PreferenceManager import androidx.preference.SwitchPreference -import io.realRealm import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch -import org.ole.planet.myplanet.MainApplication.Companion.context import org.ole.planet.myplanet.MainApplication.Companion.mRealm -import org.ole.planet.myplanet.MainApplication.Companion.setThemeMode import org.ole.planet.myplanet.R import org.ole.planet.myplanet.base.BaseResourceFragment.Companion.backgroundDownload import org.ole.planet.myplanet.base.BaseResourceFragment.Companion.getAllLibraryList @@ -122,7 +118,7 @@ class SettingActivity : AppCompatActivity() { val autoDownload = findPreference("beta_auto_download") autoDownload?.onPreferenceChangeListener = OnPreferenceChangeListener { _: Preference?, _: Any? -> - if (autoDownload?.isChecked == true) { + if (autoDownload.isChecked == true) { defaultPref.edit().putBoolean("beta_auto_download", true).apply() backgroundDownload(downloadAllFiles(getAllLibraryList(mRealm))) } else { @@ -153,17 +149,21 @@ class SettingActivity : AppCompatActivity() { val prefFreeUp = findPreference("freeup_space") if (prefFreeUp != null) { prefFreeUp.onPreferenceClickListener = OnPreferenceClickListener { - AlertDialog.Builder(requireActivity()).setTitle(R.string.are_you_sure_want_to_delete_all_the_files) - .setPositiveButton(R.string.yes) { _: DialogInterface?, _: Int -> - mRealm.executeTransactionAsync({ realm: Realm -> - val libraries = realm.where(RealmMyLibrary::class.java).findAll() - for (library in libraries) library.resourceOffline = false }, { + AlertDialog.Builder(requireActivity()) + .setTitle(R.string.are_you_sure_want_to_delete_all_the_files) + .setPositiveButton(R.string.yes) { _, _ -> + CoroutineScope(Dispatchers.Main).launch { + mRealm.write { + val libraries = this.query(RealmMyLibrary::class).find() + libraries.forEach { it.resourceOffline = false } + } val f = File(Utilities.SD_PATH) deleteRecursive(f) - Utilities.toast(requireActivity(), R.string.data_cleared.toString()) }) { - Utilities.toast(requireActivity(), R.string.unable_to_clear_files.toString()) + Utilities.toast(requireActivity(), getString(R.string.data_cleared)) } - }.setNegativeButton("No", null).show() + } + .setNegativeButton(R.string.no, null) + .show() false } } From ad0920f0a732492689d37884ae63b3feb3b2dc76 Mon Sep 17 00:00:00 2001 From: Gideon Okuro Date: Mon, 23 Dec 2024 16:19:16 +0300 Subject: [PATCH 35/38] migrate chatDetailFragment --- .../planet/myplanet/model/RealmChatHistory.kt | 36 ++++++--------- .../myplanet/ui/chat/ChatDetailFragment.kt | 44 +++++++++++-------- 2 files changed, 39 insertions(+), 41 deletions(-) diff --git a/app/src/main/java/org/ole/planet/myplanet/model/RealmChatHistory.kt b/app/src/main/java/org/ole/planet/myplanet/model/RealmChatHistory.kt index 823cb2519b..7ede278d99 100644 --- a/app/src/main/java/org/ole/planet/myplanet/model/RealmChatHistory.kt +++ b/app/src/main/java/org/ole/planet/myplanet/model/RealmChatHistory.kt @@ -83,32 +83,24 @@ class RealmChatHistory : RealmObject { } suspend fun addConversationToChatHistory(realm: Realm, chatHistoryId: String?, query: String?, response: String?) { - realm.write { - val chatHistory = query(RealmChatHistory::class) - .query("_id == $0", chatHistoryId) - .first() - .find() + val chatHistory = realm.query(RealmChatHistory::class).query("_id == $0", chatHistoryId).first().find() - if (chatHistory != null) { - try { - val conversation = Conversation().apply { - this.query = query - this.response = response - } - - if (chatHistory.conversations == null) { - chatHistory.conversations = realmListOf() - } - chatHistory.conversations?.add(conversation) - chatHistory.lastUsed = Date().time + if (chatHistory != null) { + try { + val conversation = Conversation().apply { + this.query = query + this.response = response + } - findLatest(chatHistory)?.let { latest -> - latest.conversations = chatHistory.conversations - latest.lastUsed = chatHistory.lastUsed + realm.write { + if (findLatest(chatHistory)?.conversations == null) { + findLatest(chatHistory)?.conversations = realmListOf() } - } catch (e: Exception) { - e.printStackTrace() + findLatest(chatHistory)?.conversations?.add(conversation) + findLatest(chatHistory)?.lastUsed = Date().time } + } catch (e: Exception) { + e.printStackTrace() } } } diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/chat/ChatDetailFragment.kt b/app/src/main/java/org/ole/planet/myplanet/ui/chat/ChatDetailFragment.kt index 5abe2c603d..46663e4e6a 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/chat/ChatDetailFragment.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/chat/ChatDetailFragment.kt @@ -6,9 +6,12 @@ import android.view.* import androidx.core.content.ContextCompat import androidx.fragment.app.Fragment import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.* import com.google.gson.* -import io.realm.Realm +import io.realm.kotlin.Realm +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch import okhttp3.* import org.ole.planet.myplanet.R import org.ole.planet.myplanet.databinding.FragmentChatDetailBinding @@ -129,7 +132,7 @@ class ChatDetailFragment : Fragment() { mAdapter.clearData() fragmentChatDetailBinding.editGchatMessage.text.clear() fragmentChatDetailBinding.textGchatIndicator.visibility = View.GONE - if (conversations.isValid) { + if (conversations != null && conversations.isNotEmpty()) { for (conversation in conversations) { val query = conversation.query val response = conversation.response @@ -260,6 +263,7 @@ class ChatDetailFragment : Fragment() { fragmentChatDetailBinding.tvGemini.visibility = View.GONE } } catch (e: JsonSyntaxException) { + e.printStackTrace() onFailError() } } @@ -313,10 +317,10 @@ class ChatDetailFragment : Fragment() { jsonObject.add("conversations", conversationsArray) - requireActivity().runOnUiThread { + lifecycleScope.launch { RealmChatHistory.insert(mRealm, jsonObject) + (requireActivity() as? DashboardActivity)?.refreshChatHistoryList() } - (requireActivity() as? DashboardActivity)?.refreshChatHistoryList() } } else { fragmentChatDetailBinding.textGchatIndicator.visibility = View.VISIBLE @@ -336,10 +340,10 @@ class ChatDetailFragment : Fragment() { conversationsArray.add(conversationObject) jsonObject.add("conversations", conversationsArray) - requireActivity().runOnUiThread { + lifecycleScope.launch { RealmChatHistory.insert(mRealm, jsonObject) + (requireActivity() as? DashboardActivity)?.refreshChatHistoryList() } - (requireActivity() as? DashboardActivity)?.refreshChatHistoryList() } } else { fragmentChatDetailBinding.textGchatIndicator.visibility = View.VISIBLE @@ -381,7 +385,9 @@ class ChatDetailFragment : Fragment() { mAdapter.responseSource = ChatAdapter.RESPONSE_SOURCE_NETWORK mAdapter.addResponse(chatResponse) _rev = "${response.body()?.couchDBResponse?.rev}" - continueConversationRealm(id, query, chatResponse) + lifecycleScope.launch { + continueConversationRealm(id, query, chatResponse) + } } } else { fragmentChatDetailBinding.textGchatIndicator.visibility = View.VISIBLE @@ -390,7 +396,9 @@ class ChatDetailFragment : Fragment() { } else { fragmentChatDetailBinding.textGchatIndicator.visibility = View.VISIBLE fragmentChatDetailBinding.textGchatIndicator.text = getString(R.string.request_failed_please_retry) - continueConversationRealm(id, query, "") + lifecycleScope.launch { + continueConversationRealm(id, query, "") + } } fragmentChatDetailBinding.buttonGchatSend.isEnabled = true @@ -399,7 +407,9 @@ class ChatDetailFragment : Fragment() { } override fun onFailure(call: Call, t: Throwable) { - continueConversationRealm(id, query, "") + lifecycleScope.launch { + continueConversationRealm(id, query, "") + } fragmentChatDetailBinding.textGchatIndicator.visibility = View.VISIBLE fragmentChatDetailBinding.textGchatIndicator.text = context?.getString(R.string.message_placeholder, t.message) fragmentChatDetailBinding.buttonGchatSend.isEnabled = true @@ -409,17 +419,13 @@ class ChatDetailFragment : Fragment() { }) } - private fun continueConversationRealm(id:String, query:String, chatResponse:String) { - try { - addConversationToChatHistory(mRealm, id, query, chatResponse) - mRealm.commitTransaction() - } catch (e: Exception) { - e.printStackTrace() - if (mRealm.isInTransaction) { - mRealm.cancelTransaction() + private fun continueConversationRealm(id: String, query: String, chatResponse: String) { + lifecycleScope.launch(Dispatchers.Main) { + try { + addConversationToChatHistory(mRealm, id, query, chatResponse) + } catch (e: Exception) { + e.printStackTrace() } - } finally { - mRealm.close() } } From 15af9d0c4c303f9af09e85b50c2b672a9f6ccc1c Mon Sep 17 00:00:00 2001 From: Gideon Okuro Date: Mon, 23 Dec 2024 17:20:14 +0300 Subject: [PATCH 36/38] migrate chatHistoryListAdapter --- .../ole/planet/myplanet/model/RealmNews.kt | 2 +- .../ui/chat/ChatHistoryListAdapter.kt | 31 +++++++++---------- 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/org/ole/planet/myplanet/model/RealmNews.kt b/app/src/main/java/org/ole/planet/myplanet/model/RealmNews.kt index 60c280c8fa..7375725d97 100644 --- a/app/src/main/java/org/ole/planet/myplanet/model/RealmNews.kt +++ b/app/src/main/java/org/ole/planet/myplanet/model/RealmNews.kt @@ -226,7 +226,7 @@ class RealmNews : RealmObject { } } - suspend fun createNews(realm: Realm, map: Map, realmUserModel: RealmUserModel?, imageUrl: RealmList?): RealmNews { + suspend fun createNews(map: Map, realm: Realm, realmUserModel: RealmUserModel?, imageUrl: RealmList?): RealmNews { return realm.write { val news = copyToRealm(RealmNews()) news.apply { diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/chat/ChatHistoryListAdapter.kt b/app/src/main/java/org/ole/planet/myplanet/ui/chat/ChatHistoryListAdapter.kt index 643f39f96b..91cf035fe2 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/chat/ChatHistoryListAdapter.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/chat/ChatHistoryListAdapter.kt @@ -7,10 +7,13 @@ import android.view.ViewGroup import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.google.gson.Gson -import io.realm.Case -import io.realm.Realm -import io.realm.RealmList -import io.realm.RealmResults +import io.realm.kotlin.Realm +import io.realm.kotlin.ext.query +import io.realm.kotlin.query.RealmResults +import io.realm.kotlin.types.RealmList +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch import org.ole.planet.myplanet.R import org.ole.planet.myplanet.databinding.AddNoteDialogBinding import org.ole.planet.myplanet.databinding.ChatShareDialogBinding @@ -70,10 +73,7 @@ class ChatHistoryListAdapter(var context: Context, private var chatHistory: List rowChatHistoryBinding = RowChatHistoryBinding.inflate(LayoutInflater.from(parent.context), parent, false) mRealm = DatabaseService().realmInstance user = UserProfileDbHandler(context).userModel - newsList = mRealm.where(RealmNews::class.java) - .equalTo("docType", "message", Case.INSENSITIVE) - .equalTo("createdOn", user?.planetCode, Case.INSENSITIVE) - .findAll() + newsList = mRealm.query("docType CONTAINS[c] $0 AND createdOn CONTAINS[c] $1", "message", user?.planetCode ?: "").find() return ViewHolderChat(rowChatHistoryBinding) } @@ -127,13 +127,8 @@ class ChatHistoryListAdapter(var context: Context, private var chatHistory: List chatShareDialogBinding.listView.setOnChildClickListener { _, _, groupPosition, childPosition, _ -> if (expandableTitleList[groupPosition] == context.getString(R.string.share_with_team_enterprise)) { - val teamList = mRealm.where(RealmMyTeam::class.java) - .isEmpty("teamId").notEqualTo("status", "archived") - .equalTo("type", "team").findAll() - - val enterpriseList = mRealm.where(RealmMyTeam::class.java) - .isEmpty("teamId").notEqualTo("status", "archived") - .equalTo("type", "enterprise").findAll() + val teamList = mRealm.query("teamId == null AND status != $0 AND type == $1", "archived", "team").find() + val enterpriseList = mRealm.query("teamId == null AND status != $0 AND type == $1", "archived", "enterprise").find() if (expandableDetailList[expandableTitleList[groupPosition]]?.get(childPosition) == context.getString(R.string.teams)) { showGrandChildRecyclerView(teamList, context.getString(R.string.teams), filteredChatHistory[position]) @@ -145,7 +140,7 @@ class ChatHistoryListAdapter(var context: Context, private var chatHistory: List val sParentcode = settings?.getString("parentCode", "") val communityName = settings?.getString("communityName", "") val teamId = "$communityName@$sParentcode" - val community = mRealm.where(RealmMyTeam::class.java).equalTo("_id", teamId).findFirst() + val community = mRealm.query("_id == $0", teamId).first().find() showEditTextAndShareButton(community, context.getString(R.string.community), filteredChatHistory[position]) } dialog?.dismiss() @@ -213,7 +208,9 @@ class ChatHistoryListAdapter(var context: Context, private var chatHistory: List map["chat"] = "true" map["news"] = Gson().toJson(serializedMap) - createNews(map, mRealm, user, null) + CoroutineScope(Dispatchers.Main).launch { + createNews(map, mRealm, user, null) + } fragment.refreshChatHistoryList() dialog.dismiss() From 76298265352d723a24957abd3ffef890aea718d6 Mon Sep 17 00:00:00 2001 From: Gideon Okuro Date: Mon, 23 Dec 2024 17:32:14 +0300 Subject: [PATCH 37/38] migrate chatHistoryListFragment --- .../myplanet/ui/chat/ChatHistoryListAdapter.kt | 4 ++-- .../myplanet/ui/chat/ChatHistoryListFragment.kt | 12 ++++++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/chat/ChatHistoryListAdapter.kt b/app/src/main/java/org/ole/planet/myplanet/ui/chat/ChatHistoryListAdapter.kt index 91cf035fe2..9c15b04b57 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/chat/ChatHistoryListAdapter.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/chat/ChatHistoryListAdapter.kt @@ -131,9 +131,9 @@ class ChatHistoryListAdapter(var context: Context, private var chatHistory: List val enterpriseList = mRealm.query("teamId == null AND status != $0 AND type == $1", "archived", "enterprise").find() if (expandableDetailList[expandableTitleList[groupPosition]]?.get(childPosition) == context.getString(R.string.teams)) { - showGrandChildRecyclerView(teamList, context.getString(R.string.teams), filteredChatHistory[position]) + showGrandChildRecyclerView(teamList.toList(), context.getString(R.string.teams), filteredChatHistory[position]) } else { - showGrandChildRecyclerView(enterpriseList, context.getString(R.string.enterprises), filteredChatHistory[position]) + showGrandChildRecyclerView(enterpriseList.toList(), context.getString(R.string.enterprises), filteredChatHistory[position]) } } else { settings = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE) diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/chat/ChatHistoryListFragment.kt b/app/src/main/java/org/ole/planet/myplanet/ui/chat/ChatHistoryListFragment.kt index bb8012ec49..3cca550b68 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/chat/ChatHistoryListFragment.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/chat/ChatHistoryListFragment.kt @@ -7,7 +7,9 @@ import androidx.activity.OnBackPressedCallback import androidx.fragment.app.Fragment import androidx.lifecycle.ViewModelProvider import androidx.slidingpanelayout.widget.SlidingPaneLayout -import io.realm.* +import io.realm.kotlin.Realm +import io.realm.kotlin.query.Sort +import io.realm.kotlin.types.RealmList import org.ole.planet.myplanet.R import org.ole.planet.myplanet.base.BaseRecyclerFragment.Companion.showNoData import org.ole.planet.myplanet.databinding.FragmentChatHistoryListBinding @@ -19,6 +21,7 @@ class ChatHistoryListFragment : Fragment() { private lateinit var fragmentChatHistoryListBinding: FragmentChatHistoryListBinding private lateinit var sharedViewModel: ChatViewModel var user: RealmUserModel? = null + private lateinit var mRealm: Realm override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -28,6 +31,7 @@ class ChatHistoryListFragment : Fragment() { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { fragmentChatHistoryListBinding = FragmentChatHistoryListBinding.inflate(inflater, container, false) user = UserProfileDbHandler(requireContext()).userModel + mRealm = DatabaseService().realmInstance return fragmentChatHistoryListBinding.root } @@ -69,10 +73,10 @@ class ChatHistoryListFragment : Fragment() { } fun refreshChatHistoryList() { - val mRealm = DatabaseService().realmInstance - val list = mRealm.where(RealmChatHistory::class.java).equalTo("user", user?.name) + val list = mRealm.query(RealmChatHistory::class, "user == $0", user?.name ?: "") .sort("id", Sort.DESCENDING) - .findAll() + .find() + .toList() val adapter = fragmentChatHistoryListBinding.recyclerView.adapter as? ChatHistoryListAdapter if (adapter == null) { From 6155cb25cb06cad7bd2c17d31333e256b3944ed0 Mon Sep 17 00:00:00 2001 From: Gideon Okuro Date: Mon, 23 Dec 2024 17:48:08 +0300 Subject: [PATCH 38/38] migrate AddLinkFragment --- .../myplanet/ui/community/AddLinkFragment.kt | 48 +++++++++++-------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/community/AddLinkFragment.kt b/app/src/main/java/org/ole/planet/myplanet/ui/community/AddLinkFragment.kt index 5a978173cd..5490b78218 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/community/AddLinkFragment.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/community/AddLinkFragment.kt @@ -11,7 +11,10 @@ import androidx.recyclerview.widget.LinearLayoutManager import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.bottomsheet.BottomSheetDialog import com.google.android.material.bottomsheet.BottomSheetDialogFragment -import io.realm.Realm +import io.realm.kotlin.Realm +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch import org.ole.planet.myplanet.R import org.ole.planet.myplanet.databinding.FragmentAddLinkBinding import org.ole.planet.myplanet.datamanager.DatabaseService @@ -23,17 +26,16 @@ import java.util.UUID class AddLinkFragment : BottomSheetDialogFragment(), AdapterView.OnItemSelectedListener { private lateinit var fragmentAddLinkBinding: FragmentAddLinkBinding - override fun onNothingSelected(p0: AdapterView<*>?) { - } - lateinit var mRealm: Realm var selectedTeam: RealmMyTeam? = null + override fun onNothingSelected(p0: AdapterView<*>?) { + } + override fun onItemSelected(p0: AdapterView<*>?, p1: View?, p2: Int, p3: Long) { - val query = mRealm.where(RealmMyTeam::class.java).isEmpty("teamId").isNotEmpty("name").equalTo( "type", - if (fragmentAddLinkBinding.spnLink.selectedItem.toString() == "Enterprises") "enterprise" - else "" - ).notEqualTo("status", "archived").findAll() + val query = mRealm.query(RealmMyTeam::class, "teamId == null AND name != null AND type == $0 AND status != $1", + if (fragmentAddLinkBinding.spnLink.selectedItem.toString() == "Enterprises") "enterprise" else "", + "archived").find() fragmentAddLinkBinding.rvList.layoutManager = LinearLayoutManager(requireActivity()) val adapter = AdapterTeam(requireActivity(), query, mRealm) adapter.setTeamSelectedListener(object : AdapterTeam.OnTeamSelectedListener { @@ -54,7 +56,7 @@ class AddLinkFragment : BottomSheetDialogFragment(), AdapterView.OnItemSelectedL dialog.findViewById(com.google.android.material.R.id.design_bottom_sheet) BottomSheetBehavior.from(bottomSheet!!).state = BottomSheetBehavior.STATE_EXPANDED BottomSheetBehavior.from(bottomSheet).skipCollapsed = true - BottomSheetBehavior.from(bottomSheet).setHideable(true) + BottomSheetBehavior.from(bottomSheet).isHideable = true } return bottomSheetDialog } @@ -70,8 +72,8 @@ class AddLinkFragment : BottomSheetDialogFragment(), AdapterView.OnItemSelectedL fragmentAddLinkBinding.spnLink.onItemSelectedListener = this fragmentAddLinkBinding.btnSave.setOnClickListener { val type = fragmentAddLinkBinding.spnLink.selectedItem.toString() - val title = fragmentAddLinkBinding.etName.text.toString() - if (title.isEmpty()) { + var titles = fragmentAddLinkBinding.etName.text.toString() + if (titles.isEmpty()) { Utilities.toast(requireActivity(), getString(R.string.title_is_required)) return@setOnClickListener } @@ -80,14 +82,22 @@ class AddLinkFragment : BottomSheetDialogFragment(), AdapterView.OnItemSelectedL return@setOnClickListener } - mRealm.executeTransaction { - val team = it.createObject(RealmMyTeam::class.java, UUID.randomUUID().toString()) - team.docType = "link" - team.updated = true - team.title = title - team.route = """/${type.lowercase(Locale.ROOT)}/view/${selectedTeam!!._id}""" - dismiss() - + CoroutineScope(Dispatchers.Main).launch { + try { + mRealm.write { + val team = RealmMyTeam().apply { + _id = UUID.randomUUID().toString() + docType = "link" + updated = true + title = titles + route = """/${type.lowercase(Locale.ROOT)}/view/${selectedTeam?._id}""" + } + copyToRealm(team) + } + dismiss() + } catch (e: Exception) { + e.printStackTrace() + } } } }