Integrating poker analytics iOS CSV import

od
Laurent 6 years ago
parent b969039597
commit 320f56c652
  1. 12
      app/src/main/java/net/pokeranalytics/android/util/csv/CSVDescriptor.kt
  2. 19
      app/src/main/java/net/pokeranalytics/android/util/csv/CSVField.kt
  3. 2
      app/src/main/java/net/pokeranalytics/android/util/csv/CSVImporter.kt
  4. 399
      app/src/main/java/net/pokeranalytics/android/util/csv/ProductCSVDescriptors.kt
  5. 12
      app/src/main/java/net/pokeranalytics/android/util/csv/SessionField.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<CSVDescriptor> =
listOf(ProductCSVDescriptors.pokerIncomeCash,
ProductCSVDescriptors.pokerBankrollTracker,
ProductCSVDescriptors.runGoodCashGames,
ProductCSVDescriptors.runGoodTournaments,
ProductCSVDescriptors.pokerAgent)
}
/** /**
* Method called when iterating on a CSVRecord * Method called when iterating on a CSVRecord
*/ */

@ -14,6 +14,25 @@ interface NumberCSVField: TypedCSVField<Double> {
val numberFormat: String? 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? { override fun parse(value: String) : Double? {
if (value.isEmpty()) { if (value.isEmpty()) {

@ -176,7 +176,7 @@ open class CSVImporter(istream: InputStream) {
*/ */
private fun findDescriptor(record: CSVRecord): CSVDescriptor? { private fun findDescriptor(record: CSVRecord): CSVDescriptor? {
CSVDescriptor.all.forEach { descriptor -> ProductCSVDescriptors.all.forEach { descriptor ->
if (descriptor.matches(record)) { if (descriptor.matches(record)) {
this.currentDescriptor = descriptor this.currentDescriptor = descriptor
Timber.d("Identified source: ${descriptor.source}") Timber.d("Identified source: ${descriptor.source}")

@ -2,182 +2,227 @@ package net.pokeranalytics.android.util.csv
class ProductCSVDescriptors { class ProductCSVDescriptors {
companion object { companion object {
val pokerAgent: CSVDescriptor = SessionCSVDescriptor( /**
DataSource.POKER_AGENT, * The list of all managed CSVDescriptors
false, */
SessionField.Start("Date ", dateFormat = "MM-dd-yyyy"), val all: List<CSVDescriptor> =
SessionField.Location("Location"), listOf(
SessionField.SmallBlind("SB"), pokerAgent,
SessionField.BigBlind("BB"), pokerIncomeCash,
SessionField.NetResult("P/L"), pokerBankrollTracker,
SessionField.Duration("Hrs", randomTime = true), runGoodCashGames,
SessionField.LimitAndGame("Type") runGoodTournaments,
) iOSPokerAnalytics
)
val pokerIncomeCash: CSVDescriptor = SessionCSVDescriptor(
DataSource.POKER_INCOME, private val pokerAgent: CSVDescriptor
false, get() {
SessionField.Start("Start Time"), return SessionCSVDescriptor(
SessionField.End("End Time"), DataSource.POKER_AGENT,
SessionField.Buyin("Buy In"), false,
SessionField.CashedOut("Cashed Out"), SessionField.Start("Date ", dateFormat = "MM-dd-yyyy"),
SessionField.Break("Break Minutes"), SessionField.Location("Location"),
SessionField.LimitType("Limit Type"), SessionField.SmallBlind("SB"),
SessionField.Game("Game"), SessionField.BigBlind("BB"),
SessionField.Bankroll("Bankroll"), SessionField.NetResult("P/L"),
SessionField.Location("Location"), SessionField.Duration("Hrs", randomTime = true),
SessionField.Location("Location Type"), SessionField.LimitAndGame("Type")
SessionField.Comment("Note"), )
SessionField.Tips("Tips"), }
SessionField.Blind("Stake")
) private val pokerIncomeCash: CSVDescriptor
get() {
val pokerBankrollTracker: CSVDescriptor = SessionCSVDescriptor( return SessionCSVDescriptor(
DataSource.POKER_BANKROLL_TRACKER, DataSource.POKER_INCOME,
true, false,
SessionField.Start("starttime", dateFormat = "MM/dd/yy HH:mm"), SessionField.Start("Start Time"),
SessionField.End("endtime", dateFormat = "MM/dd/yy HH:mm"), SessionField.End("End Time"),
SessionField.SessionType("variant"), SessionField.Buyin("Buy In"),
SessionField.Buyin("buyin"), SessionField.CashedOut("Cashed Out"),
SessionField.CashedOut("cashout"), SessionField.Break("Break Minutes"),
SessionField.Rebuy("rebuycosts"), SessionField.LimitType("Limit Type"),
SessionField.Addon("addoncosts"), SessionField.Game("Game"),
SessionField.Break("breakminutes"), SessionField.Bankroll("Bankroll"),
SessionField.LimitType("limit"), SessionField.Location("Location"),
SessionField.Game("game"), SessionField.Location("Location Type"),
SessionField.Bankroll("currency"), // same as currency code SessionField.Comment("Note"),
SessionField.Location("type"), SessionField.Tips("Tips"),
SessionField.Comment("comment", true), SessionField.Blind("Stake")
SessionField.Tips("expensesfromstack"), )
SessionField.SmallBlind("smallblind"), }
SessionField.BigBlind("bigblind"),
SessionField.TournamentNumberOfPlayers("player"), private val pokerBankrollTracker: CSVDescriptor
SessionField.TournamentPosition("place"), get() {
SessionField.TournamentName("mttname"), return SessionCSVDescriptor(
SessionField.CurrencyCode("currency"), DataSource.POKER_BANKROLL_TRACKER,
SessionField.StackingIn("sharesincomings"), true,
SessionField.StackingOut("sharesoutgoings"), SessionField.Start("starttime", dateFormat = "MM/dd/yy HH:mm"),
SessionField.CurrencyRate("exchangerate"), SessionField.End("endtime", dateFormat = "MM/dd/yy HH:mm"),
SessionField.TableSize("tablesize") SessionField.SessionType("variant"),
) SessionField.Buyin("buyin"),
SessionField.CashedOut("cashout"),
val runGoodTournaments: CSVDescriptor = SessionCSVDescriptor( SessionField.Rebuy("rebuycosts"),
DataSource.RUNGOOD, SessionField.Addon("addoncosts"),
true, SessionField.Break("breakminutes"),
SessionField.Start("Start Date", dateFormat = "dd/MM/yyyy"), SessionField.LimitType("limit"),
SessionField.StartTime("Start Time"), SessionField.Game("game"),
SessionField.End("End Date"), SessionField.Bankroll("currency"), // same as currency code
SessionField.EndTime("End Time"), SessionField.Location("type"),
SessionField.Buyin("Total Buy-In"), SessionField.Comment("comment", true),
SessionField.CashedOut("Winnings"), SessionField.Tips("expensesfromstack"),
SessionField.NetResult("Profit"), SessionField.SmallBlind("smallblind"),
SessionField.Break("Break"), SessionField.BigBlind("bigblind"),
SessionField.LimitType("Limit Type"), SessionField.TournamentNumberOfPlayers("player"),
SessionField.Game("Game"), SessionField.TournamentPosition("place"),
SessionField.Bankroll("Bankroll"), SessionField.TournamentName("mttname"),
SessionField.TableSize("Table Type"), SessionField.CurrencyCode("currency"),
SessionField.Location("Location"), SessionField.StackingIn("sharesincomings"),
SessionField.LocationType("Location Type"), SessionField.StackingOut("sharesoutgoings"),
SessionField.Comment("Notes"), SessionField.CurrencyRate("exchangerate"),
SessionField.CurrencyCode("Currency"), SessionField.TableSize("tablesize")
SessionField.TournamentName("Event Name"), )
SessionField.TournamentNumberOfPlayers("Total Players"), }
SessionField.TournamentPosition("Finished Place"),
SessionField.TournamentType("Single-Table/Multi-Table") private val runGoodTournaments: CSVDescriptor
get() {
) return SessionCSVDescriptor(
DataSource.RUNGOOD,
val runGoodCashGames: CSVDescriptor = SessionCSVDescriptor( true,
DataSource.RUNGOOD, SessionField.Start("Start Date", dateFormat = "dd/MM/yyyy"),
false, SessionField.StartTime("Start Time"),
SessionField.Start("Start Date", dateFormat = "dd/MM/yyyy"), SessionField.End("End Date"),
SessionField.StartTime("Start Time", dateFormat = "HH:mm"), SessionField.EndTime("End Time"),
SessionField.End("End Date", dateFormat = "dd/MM/yyyy"), SessionField.Buyin("Total Buy-In"),
SessionField.EndTime("End Time", dateFormat = "HH:mm"), SessionField.CashedOut("Winnings"),
SessionField.Buyin("Total Buy-In"), SessionField.NetResult("Profit"),
SessionField.CashedOut("Cashed Out"), SessionField.Break("Break"),
SessionField.NetResult("Profit"), SessionField.LimitType("Limit Type"),
SessionField.Break("Break"), SessionField.Game("Game"),
SessionField.LimitType("Limit Type"), SessionField.Bankroll("Bankroll"),
SessionField.Game("Game"), SessionField.TableSize("Table Type"),
SessionField.Bankroll("Bankroll"), SessionField.Location("Location"),
SessionField.TableSize("Table Type"), SessionField.LocationType("Location Type"),
SessionField.Location("Location"), SessionField.Comment("Notes"),
SessionField.LocationType("Location Type"), SessionField.CurrencyCode("Currency"),
SessionField.Comment("Notes"), SessionField.TournamentName("Event Name"),
SessionField.CurrencyCode("Currency"), SessionField.TournamentNumberOfPlayers("Total Players"),
SessionField.Blind("Stakes", callback = { value -> SessionField.TournamentPosition("Finished Place"),
// $10/20 SessionField.TournamentType("Single-Table/Multi-Table")
value.drop(1)
val blinds = value.split("/") )
if (blinds.size == 2) { }
return@Blind Pair(blinds.first().toDouble(), blinds.last().toDouble())
} else {
return@Blind null private val runGoodCashGames: CSVDescriptor
} get() {
})
) return SessionCSVDescriptor(
DataSource.RUNGOOD,
/* false,
headers.append("\"Start Date\"") SessionField.Start("Start Date", dateFormat = "dd/MM/yyyy"),
headers.append("\"End Date\"") SessionField.StartTime("Start Time", dateFormat = "HH:mm"),
headers.append("\"Break\"") SessionField.End("End Date", dateFormat = "dd/MM/yyyy"),
headers.append("\"Type\"") SessionField.EndTime("End Time", dateFormat = "HH:mm"),
headers.append("\"Live\"") SessionField.Buyin("Total Buy-In"),
headers.append("\"Tables\"") SessionField.CashedOut("Cashed Out"),
headers.append("\"Buyin\"") SessionField.NetResult("Profit"),
headers.append("\"Cashed Out\"") SessionField.Break("Break"),
headers.append("\"Online Net\"") SessionField.LimitType("Limit Type"),
headers.append("\"Tips\"") SessionField.Game("Game"),
headers.append("\"Limit\"") SessionField.Bankroll("Bankroll"),
headers.append("\"Game\"") SessionField.TableSize("Table Type"),
headers.append("\"Table Size\"") SessionField.Location("Location"),
headers.append("\"Location\"") SessionField.LocationType("Location Type"),
headers.append("\"Bankroll\"") SessionField.Comment("Notes"),
headers.append("\"Currency Code\"") SessionField.CurrencyCode("Currency"),
headers.append("\"Currency Rate\"") SessionField.Blind("Stakes", callback = { value ->
headers.append("\"Small Blind\"") // $10/20
headers.append("\"Big Blind\"") value.drop(1)
headers.append("\"Tournament Type\"") val blinds = value.split("/")
headers.append("\"Entry fee\"") if (blinds.size == 2) {
headers.append("\"Number of players\"") return@Blind Pair(
headers.append("\"Prize Pool\"") blinds.first().toDouble(),
headers.append("\"Position\"") blinds.last().toDouble()
headers.append("\"Comment\"") )
} else {
*/ return@Blind null
}
val pokerAnalyticsiOS: CSVDescriptor = SessionCSVDescriptor( })
DataSource.POKER_ANALYTICS, )
null, }
SessionField.Start("Start Date"),
SessionField.End("End Date"), // val pokerAnalyticsiOS: CSVDescriptor
SessionField.Break("Break"), // get() {
SessionField.SessionType("Type"), //
SessionField.Live("Live"), // return SessionCSVDescriptor(
SessionField.NumberOfTables("Tables"), // DataSource.POKER_ANALYTICS,
SessionField.Buyin("Buy In"), // null,
SessionField.CashedOut("Cashed Out"), // SessionField.Start("Start Date"),
SessionField.NetResult("Online Net"), // SessionField.End("End Date"),
SessionField.Tips("Tips"), // SessionField.Break("Break"),
SessionField.LimitType("Limit"), // SessionField.SessionType("Type"),
SessionField.Game("Game"), // SessionField.Live("Live"),
SessionField.TableSize("Table Size"), // SessionField.NumberOfTables("Tables"),
SessionField.Location("Location"), // SessionField.Buyin("Buy In"),
SessionField.Bankroll("Bankroll"), // SessionField.CashedOut("Cashed Out"),
SessionField.CurrencyCode("Currency Code"), // SessionField.NetResult("Online Net"),
SessionField.CurrencyRate("Currency Rate"), // SessionField.Tips("Tips"),
SessionField.SmallBlind("Small Blind"), // SessionField.LimitType("Limit"),
SessionField.BigBlind("Big Blind"), // SessionField.Game("Game"),
SessionField.TournamentType("Tournament Type"), // SessionField.TableSize("Table Size"),
SessionField.TournamentEntryFee("Entry fee"), // SessionField.Location("Location"),
SessionField.TournamentNumberOfPlayers("Number of players"), // SessionField.Bankroll("Bankroll"),
SessionField.TournamentPosition("Position"), // SessionField.CurrencyCode("Currency Code"),
SessionField.Comment("Note") // 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")
)
}
}
} }

@ -121,6 +121,11 @@ sealed class SessionField {
override var callback: ((String) -> Boolean?)? = null override var callback: ((String) -> Boolean?)? = null
) : BooleanCSVField ) : 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 Game(override var header: String) : CSVField
data class LimitAndGame(override var header: String) : CSVField data class LimitAndGame(override var header: String) : CSVField
data class Location(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 override val numberFormat: String? = null
) : NumberCSVField ) : NumberCSVField
data class NumberOfTables( data class TournamentPrizePool(
override var header: String, override var header: String,
override var callback: ((String) -> Int?)? = null override var callback: ((String) -> Double?)? = null,
) : IntCSVField override val numberFormat: String? = null
) : NumberCSVField
} }

Loading…
Cancel
Save