From 9dca2eb6477cec552db36c04b3c2c3879e286664 Mon Sep 17 00:00:00 2001 From: Laurent Date: Tue, 2 Jul 2019 17:57:26 +0200 Subject: [PATCH] Added iOS CSV import + custom field creation --- .../migrations/PokerAnalyticsMigration.kt | 2 + .../android/model/realm/CustomField.kt | 25 ++++++++++- .../android/model/realm/Session.kt | 5 +++ .../android/util/csv/CSVDescriptor.kt | 20 +++++++-- .../android/util/csv/CSVField.kt | 30 +++++++++---- .../android/util/csv/ProductCSVDescriptors.kt | 44 +++++++++++-------- .../android/util/csv/SessionCSVDescriptor.kt | 8 +++- .../android/util/csv/SessionField.kt | 19 +++++++- .../util/extensions/RealmExtensions.kt | 8 ++++ 9 files changed, 126 insertions(+), 35 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt b/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt index 5eec17e3..169fbc7b 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt @@ -167,6 +167,8 @@ class PokerAnalyticsMigration : RealmMigration { } } + schema.get("Session")?.addField("tournamentPrizepool", Double::class.java)?.setNullable("tournamentPrizepool", true) + currentVersion++ } } diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/CustomField.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/CustomField.kt index c9eb0dcf..096a9c6a 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/CustomField.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/CustomField.kt @@ -23,12 +23,29 @@ import net.pokeranalytics.android.ui.view.rowrepresentable.CustomFieldRow import net.pokeranalytics.android.ui.view.rowrepresentable.CustomizableRowRepresentable import net.pokeranalytics.android.ui.view.rowrepresentable.SimpleRow import net.pokeranalytics.android.util.enumerations.IntIdentifiable +import net.pokeranalytics.android.util.enumerations.IntSearchable +import net.pokeranalytics.android.util.extensions.findByName import java.util.* import kotlin.collections.ArrayList open class CustomField : RealmObject(), NameManageable, StaticRowRepresentableDataSource, RowRepresentable { + companion object { + + fun getOrCreate(realm: Realm, name: String, type: Type) : CustomField { + val cf = realm.findByName(CustomField::class.java, name) + cf?.let { + return it + } + val customField = CustomField() + customField.name = name + customField.type = type.uniqueIdentifier + return realm.copyToRealm(customField) + } + + } + @Ignore override val realmObjectClass: Class = CustomField::class.java @@ -39,7 +56,13 @@ open class CustomField : RealmObject(), NameManageable, StaticRowRepresentableDa IntIdentifiable { LIST(0, R.string.enum_custom_field_type), NUMBER(1, R.string.number), - AMOUNT(2, R.string.amount) + AMOUNT(2, R.string.amount); + + companion object : IntSearchable { + override fun valuesInternal(): Array { + return values() + } + } } /** diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt index 8944468e..9c91b6e0 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt @@ -314,6 +314,11 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat // The features of the tournament, like Knockout, Shootout, Turbo... var tournamentFeatures: RealmList = RealmList() + /** + * the prizepool of the tournament + */ + var tournamentPrizepool: Double? = null + // The custom fields values var customFieldEntries: RealmList = RealmList() diff --git a/app/src/main/java/net/pokeranalytics/android/util/csv/CSVDescriptor.kt b/app/src/main/java/net/pokeranalytics/android/util/csv/CSVDescriptor.kt index 68998913..6079cfcd 100644 --- a/app/src/main/java/net/pokeranalytics/android/util/csv/CSVDescriptor.kt +++ b/app/src/main/java/net/pokeranalytics/android/util/csv/CSVDescriptor.kt @@ -135,14 +135,28 @@ abstract class CSVDescriptor(var source: DataSource, vararg elements: CSVField) fun mapCustomField(record: CSVRecord, realm: Realm) { val customFields = realm.where(CustomField::class.java).findAll() val headers = record.toSet() - headers.forEach { header -> + headers.forEach { header -> + + // automatically creates custom field if necessary + if (source == DataSource.POKER_ANALYTICS) { + val splitter = "|" + if (header.contains(splitter)) { + val info = header.split(splitter) + val typeIdentifier = header.last().toInt() + val type = CustomField.Type.valueByIdentifier(typeIdentifier) + CustomField.getOrCreate(realm, info.first(), type) + } + } + + // maps header with custom fields val customField = customFields.firstOrNull { it.name == header } customField?.let { if (it.isListType) { - + val f = MappedCustomCSVField.List(header, null, it) + fields.add(f) } else { - val f = MappedCustomCVSField.Number(header, null, "", it) + val f = MappedCustomCSVField.Number(header, null, "", it) fields.add(f) } diff --git a/app/src/main/java/net/pokeranalytics/android/util/csv/CSVField.kt b/app/src/main/java/net/pokeranalytics/android/util/csv/CSVField.kt index a2597622..0862ac55 100644 --- a/app/src/main/java/net/pokeranalytics/android/util/csv/CSVField.kt +++ b/app/src/main/java/net/pokeranalytics/android/util/csv/CSVField.kt @@ -16,21 +16,33 @@ interface NumberCSVField: TypedCSVField { val numberFormat: String? - override fun parse(value: String) : Double? { + companion object { + + fun defaultParse(value: String) : Double? { + + if (value.isEmpty()) { + return null + } + + val formatter = NumberFormat.getInstance() - if (value.isEmpty()) { - return null + return try { + formatter.parse(value).toDouble() + } catch (e: ParseException) { + Timber.d("Field > Unparseable number: $value") + null + } } + } - val formatter = NumberFormat.getInstance() + override fun parse(value: String) : Double? { - return try { - formatter.parse(value).toDouble() - } catch (e: ParseException) { - Timber.d("Field ${header} > Unparseable number: $value") - null + this.callback?.let { cb -> + return cb(value) } + return defaultParse(value) } + } interface DataCSVField : TypedCSVField { diff --git a/app/src/main/java/net/pokeranalytics/android/util/csv/ProductCSVDescriptors.kt b/app/src/main/java/net/pokeranalytics/android/util/csv/ProductCSVDescriptors.kt index 293ee28f..baf3f3a5 100644 --- a/app/src/main/java/net/pokeranalytics/android/util/csv/ProductCSVDescriptors.kt +++ b/app/src/main/java/net/pokeranalytics/android/util/csv/ProductCSVDescriptors.kt @@ -12,7 +12,9 @@ class ProductCSVDescriptors { ProductCSVDescriptors.pokerIncomeCash, ProductCSVDescriptors.pokerBankrollTracker, ProductCSVDescriptors.runGoodCashGames, - ProductCSVDescriptors.runGoodTournaments + ProductCSVDescriptors.runGoodTournaments, + ProductCSVDescriptors.iOSPokerAnalytics + ) val pokerIncomeCash: CSVDescriptor = SessionCSVDescriptor( @@ -65,27 +67,33 @@ class ProductCSVDescriptors { val iOSPokerAnalytics: CSVDescriptor = SessionCSVDescriptor( DataSource.POKER_ANALYTICS, true, - SessionField.Start("Start date", dateFormat = "MM/dd/yy HH:mm"), - SessionField.End("End date", dateFormat = "MM/dd/yy HH:mm"), + SessionField.Start("Start date", dateFormat = "MM/dd/yy HH:mm:ss"), + SessionField.End("End date", dateFormat = "MM/dd/yy HH:mm:ss"), + SessionField.Break("Break", callback = { string -> + val number = NumberCSVField.defaultParse(string) + return@Break number?.times(1000.0) + }), SessionField.SessionType("Type"), - SessionField.Stakes("Stakes"), + SessionField.Live("Live"), + SessionField.Buyin("Buy-in"), + SessionField.CashedOut("Cashed Out"), + SessionField.NetResult("Net Result"), + SessionField.Tips("Tips"), + SessionField.LimitType("Limit"), SessionField.Game("Game"), - SessionField.Live("Live/Room"), - SessionField.Location("Location"), - SessionField.NumberOfTables("Number of tables"), SessionField.TableSize("Table size"), + SessionField.Location("Location"), + SessionField.NumberOfTables("Tables"), SessionField.Bankroll("Bankroll"), - SessionField.CurrencyCode("Currency"), - SessionField.CurrencyRate("Rate"), - SessionField.Comment("Comment"), - SessionField.Buyin("Buy-in"), - SessionField.CashedOut("Net result"), - - SessionField.Break("breakminutes"), - SessionField.LimitType("limit"), - SessionField.Tips("expensesfromstack"), - SessionField.TournamentNumberOfPlayers("player"), - SessionField.TournamentPosition("place") + SessionField.CurrencyCode("Currency Code"), + SessionField.SmallBlind("Small Blind"), + SessionField.BigBlind("Big Blind"), + SessionField.TournamentType("Tournament Type"), + SessionField.TournamentEntryFee("Entry fee"), + SessionField.TournamentNumberOfPlayers("Number of players"), + SessionField.TournamentPrizePool("Prize Pool"), + SessionField.TournamentPosition("Position"), + SessionField.Comment("Comment") ) val runGoodTournaments: CSVDescriptor = SessionCSVDescriptor( diff --git a/app/src/main/java/net/pokeranalytics/android/util/csv/SessionCSVDescriptor.kt b/app/src/main/java/net/pokeranalytics/android/util/csv/SessionCSVDescriptor.kt index a6dba2da..f5e5f4a0 100644 --- a/app/src/main/java/net/pokeranalytics/android/util/csv/SessionCSVDescriptor.kt +++ b/app/src/main/java/net/pokeranalytics/android/util/csv/SessionCSVDescriptor.kt @@ -155,6 +155,9 @@ class SessionCSVDescriptor(source: DataSource, private var isTournament: Boolean is SessionField.EndTime -> { endDate?.setHourMinutes(value) } + is SessionField.Live -> { + isLive = field.parse(value) ?: true + } is SessionField.Buyin -> { val buyin = field.parse(value) session.result?.buyin = buyin @@ -212,6 +215,7 @@ class SessionCSVDescriptor(source: DataSource, private var isTournament: Boolean TournamentType.getValueForLabel(value)?.ordinal is SessionField.TournamentNumberOfPlayers -> session.tournamentNumberOfPlayers = field.parse(value)?.toInt() + is SessionField.TournamentPrizePool -> session.tournamentPrizepool = field.parse(value) is SessionField.CurrencyCode -> currencyCode = value is SessionField.CurrencyRate -> currencyRate = field.parse(value) is SessionField.StackingIn -> { @@ -220,12 +224,12 @@ class SessionCSVDescriptor(source: DataSource, private var isTournament: Boolean is SessionField.StackingOut -> { stackingOut = field.parse(value) } - is MappedCustomCVSField.Number -> { + is MappedCustomCSVField.Number -> { field.parse(value)?.let { session.customFieldEntries.add(it) } } - is MappedCustomCVSField.List -> { + is MappedCustomCSVField.List -> { field.parse(value)?.let { session.customFieldEntries.add(it) } diff --git a/app/src/main/java/net/pokeranalytics/android/util/csv/SessionField.kt b/app/src/main/java/net/pokeranalytics/android/util/csv/SessionField.kt index 60c14c25..c4353635 100644 --- a/app/src/main/java/net/pokeranalytics/android/util/csv/SessionField.kt +++ b/app/src/main/java/net/pokeranalytics/android/util/csv/SessionField.kt @@ -4,7 +4,7 @@ import net.pokeranalytics.android.model.realm.CustomField import net.pokeranalytics.android.model.realm.CustomFieldEntry import java.util.* -sealed class MappedCustomCVSField { +sealed class MappedCustomCSVField { data class Number( override var header: String, @@ -149,7 +149,10 @@ sealed class SessionField { override var callback: ((String) -> Boolean?)? = null) : TypedCSVField { override fun parse(value: String): Boolean? { - return true + return when (value) { + "Live", "1" -> true + else -> false + } } } @@ -165,10 +168,22 @@ sealed class SessionField { override val numberFormat: String? = null ) : NumberCSVField + data class TournamentEntryFee( + override var header: String, + override var callback: ((String) -> Double?)? = null, + override val numberFormat: String? = null + ) : NumberCSVField + data class TournamentNumberOfPlayers( override var header: String, override var callback: ((String) -> Double?)? = null, override val numberFormat: String? = null ) : NumberCSVField + data class TournamentPrizePool( + override var header: String, + override var callback: ((String) -> Double?)? = null, + override val numberFormat: String? = null + ) : NumberCSVField + } diff --git a/app/src/main/java/net/pokeranalytics/android/util/extensions/RealmExtensions.kt b/app/src/main/java/net/pokeranalytics/android/util/extensions/RealmExtensions.kt index 7a2b5687..28634603 100644 --- a/app/src/main/java/net/pokeranalytics/android/util/extensions/RealmExtensions.kt +++ b/app/src/main/java/net/pokeranalytics/android/util/extensions/RealmExtensions.kt @@ -24,6 +24,14 @@ inline fun Realm.findById(id: String) : T? { return this.findById(T::class.java, id) } +fun Realm.findByName(clazz: Class, name: String) : T? { + return this.where(clazz).equalTo("name", name).findFirst() +} + +inline fun Realm.findByName(name: String) : T? { + return this.findByName(T::class.java, name) +} + fun Realm.getOrCreate(clazz: Class, name: String) : T { val instance = this.where(clazz).equalTo("name", name).findFirst() return if (instance != null) {