From 320f56c652b9b3c219f96e10ec83504a66a27a30 Mon Sep 17 00:00:00 2001 From: Laurent Date: Mon, 26 Aug 2019 10:27:27 +0200 Subject: [PATCH] Integrating poker analytics iOS CSV import --- .../android/util/csv/CSVDescriptor.kt | 12 - .../android/util/csv/CSVField.kt | 19 + .../android/util/csv/CSVImporter.kt | 2 +- .../android/util/csv/ProductCSVDescriptors.kt | 399 ++++++++++-------- .../android/util/csv/SessionField.kt | 12 +- 5 files changed, 251 insertions(+), 193 deletions(-) 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 90e610df..a4e915f9 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 @@ -97,18 +97,6 @@ abstract class CSVDescriptor(var source: DataSource, vararg elements: CSVField) } } - companion object { - /** - * The list of all managed CSVDescriptors - */ - val all: List = - listOf(ProductCSVDescriptors.pokerIncomeCash, - ProductCSVDescriptors.pokerBankrollTracker, - ProductCSVDescriptors.runGoodCashGames, - ProductCSVDescriptors.runGoodTournaments, - ProductCSVDescriptors.pokerAgent) - } - /** * Method called when iterating on a CSVRecord */ 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 ce2b1f66..52032742 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 @@ -14,6 +14,25 @@ interface NumberCSVField: TypedCSVField { val numberFormat: String? + companion object { + + fun defaultParse(value: String) : Double? { + + if (value.isEmpty()) { + return null + } + + val formatter = NumberFormat.getInstance() + + return try { + formatter.parse(value).toDouble() + } catch (e: ParseException) { + Timber.d("Field > Unparseable number: $value") + null + } + } + } + override fun parse(value: String) : Double? { if (value.isEmpty()) { diff --git a/app/src/main/java/net/pokeranalytics/android/util/csv/CSVImporter.kt b/app/src/main/java/net/pokeranalytics/android/util/csv/CSVImporter.kt index 4ffb6ca9..05b37957 100644 --- a/app/src/main/java/net/pokeranalytics/android/util/csv/CSVImporter.kt +++ b/app/src/main/java/net/pokeranalytics/android/util/csv/CSVImporter.kt @@ -176,7 +176,7 @@ open class CSVImporter(istream: InputStream) { */ private fun findDescriptor(record: CSVRecord): CSVDescriptor? { - CSVDescriptor.all.forEach { descriptor -> + ProductCSVDescriptors.all.forEach { descriptor -> if (descriptor.matches(record)) { this.currentDescriptor = descriptor Timber.d("Identified source: ${descriptor.source}") 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 28be015e..34b9bf2e 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 @@ -2,182 +2,227 @@ package net.pokeranalytics.android.util.csv class ProductCSVDescriptors { - companion object { - - val pokerAgent: CSVDescriptor = SessionCSVDescriptor( - DataSource.POKER_AGENT, - false, - SessionField.Start("Date ", dateFormat = "MM-dd-yyyy"), - SessionField.Location("Location"), - SessionField.SmallBlind("SB"), - SessionField.BigBlind("BB"), - SessionField.NetResult("P/L"), - SessionField.Duration("Hrs", randomTime = true), - SessionField.LimitAndGame("Type") - ) - - val pokerIncomeCash: CSVDescriptor = SessionCSVDescriptor( - DataSource.POKER_INCOME, - false, - SessionField.Start("Start Time"), - SessionField.End("End Time"), - SessionField.Buyin("Buy In"), - SessionField.CashedOut("Cashed Out"), - SessionField.Break("Break Minutes"), - SessionField.LimitType("Limit Type"), - SessionField.Game("Game"), - SessionField.Bankroll("Bankroll"), - SessionField.Location("Location"), - SessionField.Location("Location Type"), - SessionField.Comment("Note"), - SessionField.Tips("Tips"), - SessionField.Blind("Stake") - ) - - val pokerBankrollTracker: CSVDescriptor = SessionCSVDescriptor( - DataSource.POKER_BANKROLL_TRACKER, - true, - SessionField.Start("starttime", dateFormat = "MM/dd/yy HH:mm"), - SessionField.End("endtime", dateFormat = "MM/dd/yy HH:mm"), - SessionField.SessionType("variant"), - SessionField.Buyin("buyin"), - SessionField.CashedOut("cashout"), - SessionField.Rebuy("rebuycosts"), - SessionField.Addon("addoncosts"), - SessionField.Break("breakminutes"), - SessionField.LimitType("limit"), - SessionField.Game("game"), - SessionField.Bankroll("currency"), // same as currency code - SessionField.Location("type"), - SessionField.Comment("comment", true), - SessionField.Tips("expensesfromstack"), - SessionField.SmallBlind("smallblind"), - SessionField.BigBlind("bigblind"), - SessionField.TournamentNumberOfPlayers("player"), - SessionField.TournamentPosition("place"), - SessionField.TournamentName("mttname"), - SessionField.CurrencyCode("currency"), - SessionField.StackingIn("sharesincomings"), - SessionField.StackingOut("sharesoutgoings"), - SessionField.CurrencyRate("exchangerate"), - SessionField.TableSize("tablesize") - ) - - val runGoodTournaments: CSVDescriptor = SessionCSVDescriptor( - DataSource.RUNGOOD, - true, - SessionField.Start("Start Date", dateFormat = "dd/MM/yyyy"), - SessionField.StartTime("Start Time"), - SessionField.End("End Date"), - SessionField.EndTime("End Time"), - SessionField.Buyin("Total Buy-In"), - SessionField.CashedOut("Winnings"), - SessionField.NetResult("Profit"), - SessionField.Break("Break"), - SessionField.LimitType("Limit Type"), - SessionField.Game("Game"), - SessionField.Bankroll("Bankroll"), - SessionField.TableSize("Table Type"), - SessionField.Location("Location"), - SessionField.LocationType("Location Type"), - SessionField.Comment("Notes"), - SessionField.CurrencyCode("Currency"), - SessionField.TournamentName("Event Name"), - SessionField.TournamentNumberOfPlayers("Total Players"), - SessionField.TournamentPosition("Finished Place"), - SessionField.TournamentType("Single-Table/Multi-Table") - - ) - - val runGoodCashGames: CSVDescriptor = SessionCSVDescriptor( - DataSource.RUNGOOD, - false, - SessionField.Start("Start Date", dateFormat = "dd/MM/yyyy"), - SessionField.StartTime("Start Time", dateFormat = "HH:mm"), - SessionField.End("End Date", dateFormat = "dd/MM/yyyy"), - SessionField.EndTime("End Time", dateFormat = "HH:mm"), - SessionField.Buyin("Total Buy-In"), - SessionField.CashedOut("Cashed Out"), - SessionField.NetResult("Profit"), - SessionField.Break("Break"), - SessionField.LimitType("Limit Type"), - SessionField.Game("Game"), - SessionField.Bankroll("Bankroll"), - SessionField.TableSize("Table Type"), - SessionField.Location("Location"), - SessionField.LocationType("Location Type"), - SessionField.Comment("Notes"), - SessionField.CurrencyCode("Currency"), - SessionField.Blind("Stakes", callback = { value -> - // $10/20 - value.drop(1) - val blinds = value.split("/") - if (blinds.size == 2) { - return@Blind Pair(blinds.first().toDouble(), blinds.last().toDouble()) - } else { - return@Blind null - } - }) - ) - - /* - headers.append("\"Start Date\"") - headers.append("\"End Date\"") - headers.append("\"Break\"") - headers.append("\"Type\"") - headers.append("\"Live\"") - headers.append("\"Tables\"") - headers.append("\"Buyin\"") - headers.append("\"Cashed Out\"") - headers.append("\"Online Net\"") - headers.append("\"Tips\"") - headers.append("\"Limit\"") - headers.append("\"Game\"") - headers.append("\"Table Size\"") - headers.append("\"Location\"") - headers.append("\"Bankroll\"") - headers.append("\"Currency Code\"") - headers.append("\"Currency Rate\"") - headers.append("\"Small Blind\"") - headers.append("\"Big Blind\"") - headers.append("\"Tournament Type\"") - headers.append("\"Entry fee\"") - headers.append("\"Number of players\"") - headers.append("\"Prize Pool\"") - headers.append("\"Position\"") - headers.append("\"Comment\"") - - */ - - val pokerAnalyticsiOS: CSVDescriptor = SessionCSVDescriptor( - DataSource.POKER_ANALYTICS, - null, - SessionField.Start("Start Date"), - SessionField.End("End Date"), - SessionField.Break("Break"), - SessionField.SessionType("Type"), - SessionField.Live("Live"), - SessionField.NumberOfTables("Tables"), - SessionField.Buyin("Buy In"), - SessionField.CashedOut("Cashed Out"), - SessionField.NetResult("Online Net"), - SessionField.Tips("Tips"), - SessionField.LimitType("Limit"), - SessionField.Game("Game"), - SessionField.TableSize("Table Size"), - SessionField.Location("Location"), - SessionField.Bankroll("Bankroll"), - SessionField.CurrencyCode("Currency Code"), - SessionField.CurrencyRate("Currency Rate"), - SessionField.SmallBlind("Small Blind"), - SessionField.BigBlind("Big Blind"), - SessionField.TournamentType("Tournament Type"), - SessionField.TournamentEntryFee("Entry fee"), - SessionField.TournamentNumberOfPlayers("Number of players"), - SessionField.TournamentPosition("Position"), - SessionField.Comment("Note") - ) - - } + companion object { + + /** + * The list of all managed CSVDescriptors + */ + val all: List = + listOf( + pokerAgent, + pokerIncomeCash, + pokerBankrollTracker, + runGoodCashGames, + runGoodTournaments, + iOSPokerAnalytics + ) + + private val pokerAgent: CSVDescriptor + get() { + return SessionCSVDescriptor( + DataSource.POKER_AGENT, + false, + SessionField.Start("Date ", dateFormat = "MM-dd-yyyy"), + SessionField.Location("Location"), + SessionField.SmallBlind("SB"), + SessionField.BigBlind("BB"), + SessionField.NetResult("P/L"), + SessionField.Duration("Hrs", randomTime = true), + SessionField.LimitAndGame("Type") + ) + } + + private val pokerIncomeCash: CSVDescriptor + get() { + return SessionCSVDescriptor( + DataSource.POKER_INCOME, + false, + SessionField.Start("Start Time"), + SessionField.End("End Time"), + SessionField.Buyin("Buy In"), + SessionField.CashedOut("Cashed Out"), + SessionField.Break("Break Minutes"), + SessionField.LimitType("Limit Type"), + SessionField.Game("Game"), + SessionField.Bankroll("Bankroll"), + SessionField.Location("Location"), + SessionField.Location("Location Type"), + SessionField.Comment("Note"), + SessionField.Tips("Tips"), + SessionField.Blind("Stake") + ) + } + + private val pokerBankrollTracker: CSVDescriptor + get() { + return SessionCSVDescriptor( + DataSource.POKER_BANKROLL_TRACKER, + true, + SessionField.Start("starttime", dateFormat = "MM/dd/yy HH:mm"), + SessionField.End("endtime", dateFormat = "MM/dd/yy HH:mm"), + SessionField.SessionType("variant"), + SessionField.Buyin("buyin"), + SessionField.CashedOut("cashout"), + SessionField.Rebuy("rebuycosts"), + SessionField.Addon("addoncosts"), + SessionField.Break("breakminutes"), + SessionField.LimitType("limit"), + SessionField.Game("game"), + SessionField.Bankroll("currency"), // same as currency code + SessionField.Location("type"), + SessionField.Comment("comment", true), + SessionField.Tips("expensesfromstack"), + SessionField.SmallBlind("smallblind"), + SessionField.BigBlind("bigblind"), + SessionField.TournamentNumberOfPlayers("player"), + SessionField.TournamentPosition("place"), + SessionField.TournamentName("mttname"), + SessionField.CurrencyCode("currency"), + SessionField.StackingIn("sharesincomings"), + SessionField.StackingOut("sharesoutgoings"), + SessionField.CurrencyRate("exchangerate"), + SessionField.TableSize("tablesize") + ) + } + + private val runGoodTournaments: CSVDescriptor + get() { + return SessionCSVDescriptor( + DataSource.RUNGOOD, + true, + SessionField.Start("Start Date", dateFormat = "dd/MM/yyyy"), + SessionField.StartTime("Start Time"), + SessionField.End("End Date"), + SessionField.EndTime("End Time"), + SessionField.Buyin("Total Buy-In"), + SessionField.CashedOut("Winnings"), + SessionField.NetResult("Profit"), + SessionField.Break("Break"), + SessionField.LimitType("Limit Type"), + SessionField.Game("Game"), + SessionField.Bankroll("Bankroll"), + SessionField.TableSize("Table Type"), + SessionField.Location("Location"), + SessionField.LocationType("Location Type"), + SessionField.Comment("Notes"), + SessionField.CurrencyCode("Currency"), + SessionField.TournamentName("Event Name"), + SessionField.TournamentNumberOfPlayers("Total Players"), + SessionField.TournamentPosition("Finished Place"), + SessionField.TournamentType("Single-Table/Multi-Table") + + ) + } + + + private val runGoodCashGames: CSVDescriptor + get() { + + return SessionCSVDescriptor( + DataSource.RUNGOOD, + false, + SessionField.Start("Start Date", dateFormat = "dd/MM/yyyy"), + SessionField.StartTime("Start Time", dateFormat = "HH:mm"), + SessionField.End("End Date", dateFormat = "dd/MM/yyyy"), + SessionField.EndTime("End Time", dateFormat = "HH:mm"), + SessionField.Buyin("Total Buy-In"), + SessionField.CashedOut("Cashed Out"), + SessionField.NetResult("Profit"), + SessionField.Break("Break"), + SessionField.LimitType("Limit Type"), + SessionField.Game("Game"), + SessionField.Bankroll("Bankroll"), + SessionField.TableSize("Table Type"), + SessionField.Location("Location"), + SessionField.LocationType("Location Type"), + SessionField.Comment("Notes"), + SessionField.CurrencyCode("Currency"), + SessionField.Blind("Stakes", callback = { value -> + // $10/20 + value.drop(1) + val blinds = value.split("/") + if (blinds.size == 2) { + return@Blind Pair( + blinds.first().toDouble(), + blinds.last().toDouble() + ) + } else { + return@Blind null + } + }) + ) + } + +// val pokerAnalyticsiOS: CSVDescriptor +// get() { +// +// return SessionCSVDescriptor( +// DataSource.POKER_ANALYTICS, +// null, +// SessionField.Start("Start Date"), +// SessionField.End("End Date"), +// SessionField.Break("Break"), +// SessionField.SessionType("Type"), +// SessionField.Live("Live"), +// SessionField.NumberOfTables("Tables"), +// SessionField.Buyin("Buy In"), +// SessionField.CashedOut("Cashed Out"), +// SessionField.NetResult("Online Net"), +// SessionField.Tips("Tips"), +// SessionField.LimitType("Limit"), +// SessionField.Game("Game"), +// SessionField.TableSize("Table Size"), +// SessionField.Location("Location"), +// SessionField.Bankroll("Bankroll"), +// SessionField.CurrencyCode("Currency Code"), +// SessionField.CurrencyRate("Currency Rate"), +// SessionField.SmallBlind("Small Blind"), +// SessionField.BigBlind("Big Blind"), +// SessionField.TournamentType("Tournament Type"), +// SessionField.TournamentEntryFee("Entry fee"), +// SessionField.TournamentNumberOfPlayers("Number of players"), +// SessionField.TournamentPosition("Position"), +// SessionField.Comment("Note") +// ) +// } + + + private val pokerAnalyticsiOS: CSVDescriptor + get() { + return SessionCSVDescriptor( + DataSource.POKER_ANALYTICS, + true, + 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.Live("Live"), + SessionField.NumberOfTables("Tables"), + SessionField.Buyin("Buyin"), + SessionField.CashedOut("Cashed Out"), + SessionField.NetResult("Online Net"), + SessionField.Tips("Tips"), + SessionField.LimitType("Limit"), + SessionField.Game("Game"), + SessionField.TableSize("Table Size"), + SessionField.Location("Location"), + SessionField.Bankroll("Bankroll"), + SessionField.CurrencyCode("Currency Code"), + SessionField.CurrencyRate("Currency Rate"), + 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") + ) + } + + } } \ No newline at end of file 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 fb8a3f38..78755fd8 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 @@ -121,6 +121,11 @@ sealed class SessionField { override var callback: ((String) -> Boolean?)? = null ) : BooleanCSVField + data class NumberOfTables( + override var header: String, + override var callback: ((String) -> Int?)? = null + ) : IntCSVField + data class Game(override var header: String) : CSVField data class LimitAndGame(override var header: String) : CSVField data class Location(override var header: String) : CSVField @@ -158,9 +163,10 @@ sealed class SessionField { override val numberFormat: String? = null ) : NumberCSVField - data class NumberOfTables( + data class TournamentPrizePool( override var header: String, - override var callback: ((String) -> Int?)? = null - ) : IntCSVField + override var callback: ((String) -> Double?)? = null, + override val numberFormat: String? = null + ) : NumberCSVField }