Skip to content

Commit

Permalink
Added database models and saving
Browse files Browse the repository at this point in the history
  • Loading branch information
aanorbel committed Dec 13, 2023
1 parent d9ca5df commit 21bd846
Show file tree
Hide file tree
Showing 5 changed files with 150 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.google.android.material.checkbox.MaterialCheckBox
import io.noties.markwon.Markwon
import org.openobservatory.engine.BaseNettest
import org.openobservatory.engine.OONIRunDescriptor
import org.openobservatory.engine.OONIRunNettest
import org.openobservatory.ooniprobe.R
import org.openobservatory.ooniprobe.activity.AbstractActivity
import org.openobservatory.ooniprobe.activity.add_descriptor.adapter.AddDescriptorExpandableListAdapter
Expand All @@ -26,14 +28,16 @@ import org.openobservatory.ooniprobe.common.PreferenceManager
import org.openobservatory.ooniprobe.common.ReadMorePlugin
import org.openobservatory.ooniprobe.common.TestDescriptorManager
import org.openobservatory.ooniprobe.databinding.ActivityAddDescriptorBinding
import org.openobservatory.ooniprobe.model.database.TestDescriptor
import org.openobservatory.ooniprobe.model.database.getNettests
import javax.inject.Inject

class AddDescriptorActivity : AbstractActivity() {
companion object {
private const val DESCRIPTOR = "descriptor"

@JvmStatic
fun newIntent(context: Context, descriptor: OONIRunDescriptor): Intent {
fun newIntent(context: Context, descriptor: TestDescriptor): Intent {
return Intent(context, AddDescriptorActivity::class.java).putExtra(
DESCRIPTOR,
descriptor
Expand Down Expand Up @@ -96,9 +100,9 @@ class AddDescriptorActivity : AbstractActivity() {
supportActionBar?.setDisplayShowHomeEnabled(false)
supportActionBar?.title = "Add New Link"
val descriptorExtra = if (VERSION.SDK_INT >= VERSION_CODES.TIRAMISU) {
intent.getParcelableExtra(DESCRIPTOR, OONIRunDescriptor::class.java)
intent.getParcelableExtra(DESCRIPTOR, TestDescriptor::class.java)
} else {
intent.getSerializableExtra(DESCRIPTOR) as OONIRunDescriptor?
intent.getSerializableExtra(DESCRIPTOR) as TestDescriptor?
}
val viewModel: AddDescriptorViewModel by viewModels {
object : ViewModelProvider.Factory {
Expand All @@ -113,7 +117,7 @@ class AddDescriptorActivity : AbstractActivity() {
descriptorExtra?.let { descriptor ->
viewModel.onDescriptorChanged(descriptor)
val adapter = AddDescriptorExpandableListAdapter(
nettests = descriptor.nettests.map { nettest ->
nettests = descriptor.getNettests().map { nettest ->
GroupedItem(
name = nettest.name,
inputs = nettest.inputs,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,42 +2,43 @@ package org.openobservatory.ooniprobe.activity.add_descriptor

import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewmodel.ViewModelFactoryDsl
import com.google.android.material.checkbox.MaterialCheckBox
import com.google.android.material.checkbox.MaterialCheckBox.CheckedState
import org.openobservatory.engine.OONIRunDescriptor
import org.openobservatory.engine.OONIRunNettest
import org.openobservatory.ooniprobe.activity.add_descriptor.adapter.GroupedItem
import org.openobservatory.ooniprobe.common.LocaleUtils
import org.openobservatory.ooniprobe.common.TestDescriptorManager
import javax.inject.Inject
import org.openobservatory.ooniprobe.model.database.TestDescriptor
import org.openobservatory.ooniprobe.model.database.getValueForKey

class AddDescriptorViewModel constructor(
class AddDescriptorViewModel(
var descriptorManager: TestDescriptorManager
) : ViewModel() {
@CheckedState
val selectedAllBtnStatus: MutableLiveData<Int> =
MutableLiveData(MaterialCheckBox.STATE_CHECKED)
var descriptor: MutableLiveData<OONIRunDescriptor> = MutableLiveData()
var descriptor: MutableLiveData<TestDescriptor> = MutableLiveData()
val finishActivity: MutableLiveData<Boolean> = MutableLiveData()
fun onDescriptorChanged(descriptor: OONIRunDescriptor) {
fun onDescriptorChanged(descriptor: TestDescriptor) {
this.descriptor.value = descriptor
}

fun getName(): String {
return descriptor.value?.let { descriptor ->
descriptor.nameIntl[LocaleUtils.sLocale.language] ?: descriptor.name
descriptor.nameIntl.getValueForKey(LocaleUtils.sLocale.language) ?: descriptor.name
} ?: ""
}

fun getDescription(): String {
return descriptor.value?.let { descriptor ->
descriptor.descriptionIntl[LocaleUtils.sLocale.language] ?: descriptor.description
descriptor.descriptionIntl.getValueForKey(LocaleUtils.sLocale.language)
?: descriptor.description
} ?: ""
}

fun getShortDescription(): String {
return descriptor.value?.let { descriptor ->
descriptor.shortDescriptionIntl[LocaleUtils.sLocale.language]
descriptor.shortDescriptionIntl.getValueForKey(LocaleUtils.sLocale.language)
?: descriptor.shortDescription
} ?: ""
}
Expand All @@ -50,9 +51,14 @@ class AddDescriptorViewModel constructor(
descriptor.value?.let { descriptor ->
descriptorManager.addDescriptor(
descriptor = descriptor.apply {
nettests = selectedNettest.filter { it.selected }
isAutoUpdate = automatedUpdates
nettests = selectedNettest.filter { it.selected }.map { nettest ->
OONIRunNettest(
name = nettest.name,
inputs = nettest.inputs
)
}
},
automatedUpdates = automatedUpdates
).also {
finishActivity()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
@Database(name = AppDatabase.NAME, version = AppDatabase.VERSION, foreignKeyConstraintsEnforced = true)
public class AppDatabase {
public static final String NAME = "v2";
public static final int VERSION = 3;
public static final int VERSION = 3 + 1;

@Migration(version = 2, database = AppDatabase.class)
public static class Migration2 extends AlterTableMigration<Result> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ package org.openobservatory.ooniprobe.common
import android.content.Context
import org.openobservatory.engine.BaseNettest
import org.openobservatory.engine.LoggerArray
import org.openobservatory.engine.OONIRunDescriptor
import org.openobservatory.engine.OONIRunFetchResponse
import org.openobservatory.ooniprobe.BuildConfig
import org.openobservatory.ooniprobe.model.database.TestDescriptor
import org.openobservatory.ooniprobe.test.EngineProvider
import org.openobservatory.ooniprobe.test.suite.DynamicTestSuite
import javax.inject.Inject
Expand All @@ -27,7 +27,7 @@ class TestDescriptorManager @Inject constructor(private val context: Context) {
return getDescriptorByName(name)?.getTest(context)
}

fun fetchDescriptorFromRunId(runId: Long, context: Context): OONIRunDescriptor {
fun fetchDescriptorFromRunId(runId: Long, context: Context): TestDescriptor {
val session = EngineProvider.get().newSession(
EngineProvider.get().getDefaultSessionConfig(
context,
Expand All @@ -40,11 +40,26 @@ class TestDescriptorManager @Inject constructor(private val context: Context) {
val ooniContext = session.newContextWithTimeout(300)

val response: OONIRunFetchResponse = session.ooniRunFetch(ooniContext, runId)
return response.descriptor
return TestDescriptor(
runId = runId,
name = response.descriptor.name,
nameIntl = response.descriptor.nameIntl,
author = response.descriptor.author,
shortDescription = response.descriptor.shortDescription,
shortDescriptionIntl = response.descriptor.shortDescriptionIntl,
description = response.descriptor.description,
descriptionIntl = response.descriptor.descriptionIntl,
icon = response.descriptor.icon,
color = response.descriptor.color,
animation = response.descriptor.animation,
isArchived = response.archived,
descriptorCreationTime = response.creationTime,
translationCreationTime = response.translationCreationTime,
nettests = response.descriptor.nettests
)
}

fun addDescriptor(descriptor: OONIRunDescriptor, automatedUpdates: Boolean): Boolean {
// persist to database
return false
fun addDescriptor(descriptor: TestDescriptor): Boolean {
return descriptor.save()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package org.openobservatory.ooniprobe.model.database

import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.raizlabs.android.dbflow.annotation.Column
import com.raizlabs.android.dbflow.annotation.PrimaryKey
import com.raizlabs.android.dbflow.annotation.Table
import com.raizlabs.android.dbflow.converter.TypeConverter
import com.raizlabs.android.dbflow.structure.BaseModel
import org.openobservatory.engine.OONIRunNettest
import org.openobservatory.ooniprobe.activity.add_descriptor.adapter.GroupedItem
import org.openobservatory.ooniprobe.common.AppDatabase
import java.io.Serializable
import java.util.Date
import com.raizlabs.android.dbflow.annotation.TypeConverter as TypeConverterAnnotation

@Table(database = AppDatabase::class)
class TestDescriptor(
@PrimaryKey
var runId: Long = 0,
@Column
var name: String = "",
@Column(name = "name_intl", typeConverter = MapConverter::class)
var nameIntl: Any? = null,
@Column
var author: String = "",
@Column(name = "short_description")
var shortDescription: String = "",
@Column(name = "short_description_intl", typeConverter = MapConverter::class)
var shortDescriptionIntl: Any? = null,
@Column
var description: String = "",
@Column(name = "description_intl", typeConverter = MapConverter::class)
var descriptionIntl: Any? = null,
@Column
var icon: String? = null,
@Column
var color: String? = null,
@Column
var animation: String? = null,
@Column
var isArchived: Boolean = false,
@Column(name = "auto_run")
var isAutoRun: Boolean = true,
@Column(name = "auto_update")
var isAutoUpdate: Boolean = false,
@Column(name = "descriptor_creation_time")
var descriptorCreationTime: Date? = null,
@Column(name = "translation_creation_time")
var translationCreationTime: Date? = null,
@Column(typeConverter = NettestConverter::class)
var nettests: Any = emptyList<OONIRunNettest>()
) : BaseModel(), Serializable

fun TestDescriptor.getNettests(): List<OONIRunNettest> {
return when (nettests is List<*>) {
true -> (nettests as List<*>)
.filterIsInstance<OONIRunNettest>()
.map { nettest: OONIRunNettest ->
return@map GroupedItem(
name = nettest.name,
inputs = nettest.inputs,
selected = true
)
}

false -> emptyList()
}
}

fun Any?.getValueForKey(language: String): String? {
return if (this is Map<*, *>) {
this[language] as String?
} else {
null
}
}



@TypeConverterAnnotation
class MapConverter : TypeConverter<String, Any>() {
override fun getDBValue(model: Any?): String? {
return Gson().toJson(model)
}

override fun getModelValue(json: String): HashMap<String, String> {
val gson = Gson()
val type = object : TypeToken<HashMap<String, String>>() {}.type
return gson.fromJson(json, type)
}
}


@TypeConverterAnnotation
class NettestConverter : TypeConverter<String, Any>() {
override fun getDBValue(model: Any): String = Gson().toJson(model)

override fun getModelValue(data: String): List<*> = Gson().fromJson(
data, Array<OONIRunNettest>::class.java
).toList()
}

0 comments on commit 21bd846

Please sign in to comment.