Merge branch 'dev' of gitlab.com:stax-river/poker-analytics into dev

dev
Aurelien Hubert 7 years ago
commit ed9da94302
  1. 40
      app/src/main/java/net/pokeranalytics/android/calculus/Report.kt
  2. 1
      app/src/main/java/net/pokeranalytics/android/calculus/Stat.kt
  3. 2
      app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt
  4. 2
      app/src/main/java/net/pokeranalytics/android/model/realm/SessionSet.kt
  5. 2
      app/src/main/java/net/pokeranalytics/android/model/realm/Transaction.kt
  6. 12
      app/src/main/java/net/pokeranalytics/android/ui/adapter/RowRepresentableDataSource.kt
  7. 2
      app/src/main/java/net/pokeranalytics/android/ui/extensions/UIExtensions.kt
  8. 2
      app/src/main/java/net/pokeranalytics/android/ui/fragment/data/CustomFieldDataFragment.kt
  9. 1
      app/src/main/java/net/pokeranalytics/android/ui/fragment/report/ComposableTableReportFragment.kt
  10. 2
      app/src/main/java/net/pokeranalytics/android/ui/graph/GraphUnderlyingEntry.kt
  11. 2
      app/src/main/java/net/pokeranalytics/android/ui/view/LegendView.kt
  12. 2
      app/src/main/java/net/pokeranalytics/android/ui/view/MultiLineLegendView.kt
  13. 2
      app/src/main/java/net/pokeranalytics/android/util/TextFormat.kt
  14. 38
      app/src/main/java/net/pokeranalytics/android/util/csv/CSVDescriptor.kt
  15. 95
      app/src/main/java/net/pokeranalytics/android/util/csv/CSVImporter.kt
  16. 71
      app/src/main/java/net/pokeranalytics/android/util/csv/SessionCSVDescriptor.kt
  17. 14
      app/src/main/java/net/pokeranalytics/android/util/csv/TypedCSVField.kt

@ -17,6 +17,7 @@ import net.pokeranalytics.android.ui.graph.GraphUnderlyingEntry
import net.pokeranalytics.android.ui.view.DefaultLegendValues import net.pokeranalytics.android.ui.view.DefaultLegendValues
import net.pokeranalytics.android.ui.view.LegendContent import net.pokeranalytics.android.ui.view.LegendContent
import net.pokeranalytics.android.util.ColorUtils import net.pokeranalytics.android.util.ColorUtils
import net.pokeranalytics.android.util.TextFormat
import kotlin.math.abs import kotlin.math.abs
/** /**
@ -95,21 +96,17 @@ class Report(var options: Calculator.Options) {
/** /**
* A sessionGroup of computable items identified by a name * A sessionGroup of computable items identified by a name
*/ */
class ComputableGroup(query: Query, stats: List<Stat>? = null) { class ComputableGroup(var query: Query, var stats: List<Stat>? = null) {
// constructor(query: Query, statIds: List<Stat>? = null) : this(query.name, query.conditions) /**
// * A subgroup used to compute stat variation
// private constructor(name: String = "", conditions: List<QueryCondition> = listOf(), statIds: List<Stat>? = null) */
var comparedGroup: ComputableGroup? = null
var query: Query = query
/** /**
* The display name of the group * The computed statIds of the comparable sessionGroup
*/ */
// val name: String var comparedComputedResults: ComputedResults? = null
// get() {
// return this.query.name
// }
/** /**
* A list of _conditions to get * A list of _conditions to get
@ -164,21 +161,6 @@ class ComputableGroup(query: Query, stats: List<Stat>? = null) {
return sets return sets
} }
/**
* The list of statIds to display
*/
var stats: List<Stat>? = stats
/**
* A subgroup used to compute stat variation
*/
var comparedGroup: ComputableGroup? = null
/**
* The computed statIds of the comparable sessionGroup
*/
var comparedComputedResults: ComputedResults? = null
fun cleanup() { fun cleanup() {
this._computables = null this._computables = null
this._sessionSets = null this._sessionSets = null
@ -220,10 +202,10 @@ class ComputedResults(group: ComputableGroup, shouldManageMultiGroupProgressValu
} else { } else {
Point(value, data = data.objectIdentifier) Point(value, data = data.objectIdentifier)
} }
this._addEvolutionValue(point, stat = stat) this.addEvolutionValue(point, stat = stat)
} }
private fun _addEvolutionValue(point: Point, stat: Stat) { private fun addEvolutionValue(point: Point, stat: Stat) {
val evolutionValues = this._evolutionValues[stat] val evolutionValues = this._evolutionValues[stat]
if (evolutionValues != null) { if (evolutionValues != null) {
evolutionValues.add(point) evolutionValues.add(point)
@ -364,9 +346,7 @@ class ComputedResults(group: ComputableGroup, shouldManageMultiGroupProgressValu
} }
fun finalize() { fun finalize() {
this.consolidateProgressStats() this.consolidateProgressStats()
} }
// MPAndroidChart // MPAndroidChart

@ -6,6 +6,7 @@ import net.pokeranalytics.android.exceptions.FormattingException
import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.RowViewType import net.pokeranalytics.android.ui.view.RowViewType
import net.pokeranalytics.android.util.NULL_TEXT import net.pokeranalytics.android.util.NULL_TEXT
import net.pokeranalytics.android.util.TextFormat
import net.pokeranalytics.android.util.enumerations.IntIdentifiable import net.pokeranalytics.android.util.enumerations.IntIdentifiable
import net.pokeranalytics.android.util.enumerations.IntSearchable import net.pokeranalytics.android.util.enumerations.IntSearchable
import net.pokeranalytics.android.util.extensions.formatted import net.pokeranalytics.android.util.extensions.formatted

@ -15,7 +15,7 @@ import net.pokeranalytics.android.R
import net.pokeranalytics.android.calculus.ComputedStat import net.pokeranalytics.android.calculus.ComputedStat
import net.pokeranalytics.android.calculus.Stat import net.pokeranalytics.android.calculus.Stat
import net.pokeranalytics.android.calculus.StatFormattingException import net.pokeranalytics.android.calculus.StatFormattingException
import net.pokeranalytics.android.calculus.TextFormat import net.pokeranalytics.android.util.TextFormat
import net.pokeranalytics.android.exceptions.ModelException import net.pokeranalytics.android.exceptions.ModelException
import net.pokeranalytics.android.model.Limit import net.pokeranalytics.android.model.Limit
import net.pokeranalytics.android.model.TableSize import net.pokeranalytics.android.model.TableSize

@ -8,7 +8,7 @@ import io.realm.annotations.LinkingObjects
import io.realm.annotations.PrimaryKey import io.realm.annotations.PrimaryKey
import net.pokeranalytics.android.calculus.Stat import net.pokeranalytics.android.calculus.Stat
import net.pokeranalytics.android.calculus.StatFormattingException import net.pokeranalytics.android.calculus.StatFormattingException
import net.pokeranalytics.android.calculus.TextFormat import net.pokeranalytics.android.util.TextFormat
import net.pokeranalytics.android.model.filter.Filterable import net.pokeranalytics.android.model.filter.Filterable
import net.pokeranalytics.android.model.filter.QueryCondition import net.pokeranalytics.android.model.filter.QueryCondition
import net.pokeranalytics.android.model.interfaces.Timed import net.pokeranalytics.android.model.interfaces.Timed

@ -8,7 +8,7 @@ import io.realm.annotations.PrimaryKey
import io.realm.kotlin.where import io.realm.kotlin.where
import net.pokeranalytics.android.R import net.pokeranalytics.android.R
import net.pokeranalytics.android.calculus.Stat import net.pokeranalytics.android.calculus.Stat
import net.pokeranalytics.android.calculus.TextFormat import net.pokeranalytics.android.util.TextFormat
import net.pokeranalytics.android.model.filter.Filterable import net.pokeranalytics.android.model.filter.Filterable
import net.pokeranalytics.android.model.filter.QueryCondition import net.pokeranalytics.android.model.filter.QueryCondition
import net.pokeranalytics.android.model.interfaces.* import net.pokeranalytics.android.model.interfaces.*

@ -1,7 +1,7 @@
package net.pokeranalytics.android.ui.adapter package net.pokeranalytics.android.ui.adapter
import android.content.Context import android.content.Context
import net.pokeranalytics.android.calculus.TextFormat import net.pokeranalytics.android.util.TextFormat
import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.RowRepresentableEditDescriptor import net.pokeranalytics.android.ui.view.RowRepresentableEditDescriptor
@ -77,11 +77,11 @@ interface LiveRowRepresentableDataSource: RowRepresentableDataSource {
* Custom class providing the value to display and how to display them * Custom class providing the value to display and how to display them
*/ */
class DisplayDescriptor( class DisplayDescriptor(
var boolValue: Boolean? = null, var boolValue: Boolean? = null,
var stringValue: String? = null, var stringValue: String? = null,
var textFormat: TextFormat? = null, var textFormat: TextFormat? = null,
var actionIcon: Int? = null, var actionIcon: Int? = null,
var context: Context? = null) { var context: Context? = null) {
} }
class UnmanagedRowRepresentableException(message: String) : Exception(message) { class UnmanagedRowRepresentableException(message: String) : Exception(message) {

@ -16,7 +16,7 @@ import androidx.core.content.FileProvider
import androidx.core.view.isVisible import androidx.core.view.isVisible
import net.pokeranalytics.android.BuildConfig import net.pokeranalytics.android.BuildConfig
import net.pokeranalytics.android.R import net.pokeranalytics.android.R
import net.pokeranalytics.android.calculus.TextFormat import net.pokeranalytics.android.util.TextFormat
import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity
import net.pokeranalytics.android.ui.fragment.components.PokerAnalyticsFragment import net.pokeranalytics.android.ui.fragment.components.PokerAnalyticsFragment
import net.pokeranalytics.android.util.DeviceUtils import net.pokeranalytics.android.util.DeviceUtils

@ -30,7 +30,7 @@ import java.util.*
*/ */
class CustomFieldDataFragment : EditableDataFragment(), StaticRowRepresentableDataSource { class CustomFieldDataFragment : EditableDataFragment(), StaticRowRepresentableDataSource {
// Return the item as a Custom TypedField object // Return the item as a Custom TypedCSVField object
private val customField: CustomField private val customField: CustomField
get() { get() {
return this.item as CustomField return this.item as CustomField

@ -22,6 +22,7 @@ import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.rowrepresentable.CustomizableRowRepresentable import net.pokeranalytics.android.ui.view.rowrepresentable.CustomizableRowRepresentable
import net.pokeranalytics.android.ui.view.rowrepresentable.StatRow import net.pokeranalytics.android.ui.view.rowrepresentable.StatRow
import net.pokeranalytics.android.util.NULL_TEXT import net.pokeranalytics.android.util.NULL_TEXT
import net.pokeranalytics.android.util.TextFormat
import timber.log.Timber import timber.log.Timber
import java.util.* import java.util.*
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext

@ -3,7 +3,7 @@ package net.pokeranalytics.android.ui.graph
import android.content.Context import android.content.Context
import com.github.mikephil.charting.data.Entry import com.github.mikephil.charting.data.Entry
import net.pokeranalytics.android.calculus.Stat import net.pokeranalytics.android.calculus.Stat
import net.pokeranalytics.android.calculus.TextFormat import net.pokeranalytics.android.util.TextFormat
import net.pokeranalytics.android.model.interfaces.Timed import net.pokeranalytics.android.model.interfaces.Timed
import net.pokeranalytics.android.ui.fragment.GraphFragment import net.pokeranalytics.android.ui.fragment.GraphFragment
import net.pokeranalytics.android.ui.view.DefaultLegendValues import net.pokeranalytics.android.ui.view.DefaultLegendValues

@ -9,7 +9,7 @@ import androidx.core.view.isVisible
import kotlinx.android.synthetic.main.layout_legend_default.view.* import kotlinx.android.synthetic.main.layout_legend_default.view.*
import net.pokeranalytics.android.R import net.pokeranalytics.android.R
import net.pokeranalytics.android.calculus.Stat import net.pokeranalytics.android.calculus.Stat
import net.pokeranalytics.android.calculus.TextFormat import net.pokeranalytics.android.util.TextFormat
import net.pokeranalytics.android.ui.extensions.setTextFormat import net.pokeranalytics.android.ui.extensions.setTextFormat
import net.pokeranalytics.android.ui.fragment.GraphFragment import net.pokeranalytics.android.ui.fragment.GraphFragment

@ -9,7 +9,7 @@ import kotlinx.android.synthetic.main.layout_legend_default.view.stat2Name
import kotlinx.android.synthetic.main.layout_legend_default.view.stat2Value import kotlinx.android.synthetic.main.layout_legend_default.view.stat2Value
import net.pokeranalytics.android.R import net.pokeranalytics.android.R
import net.pokeranalytics.android.calculus.Stat import net.pokeranalytics.android.calculus.Stat
import net.pokeranalytics.android.calculus.TextFormat import net.pokeranalytics.android.util.TextFormat
import net.pokeranalytics.android.ui.extensions.setTextFormat import net.pokeranalytics.android.ui.extensions.setTextFormat
import net.pokeranalytics.android.ui.fragment.GraphFragment import net.pokeranalytics.android.ui.fragment.GraphFragment

@ -1,4 +1,4 @@
package net.pokeranalytics.android.calculus package net.pokeranalytics.android.util
import android.content.Context import android.content.Context
import android.graphics.Color import android.graphics.Color

@ -4,14 +4,19 @@ import io.realm.Realm
import io.realm.RealmModel import io.realm.RealmModel
import org.apache.commons.csv.CSVRecord import org.apache.commons.csv.CSVRecord
/**
* The various sources of CSV
*/
enum class DataSource { enum class DataSource {
POKER_INCOME, POKER_INCOME,
POKER_BANKROLL_TRACKER, POKER_BANKROLL_TRACKER,
RUNGOOD RUNGOOD
} }
abstract class DataCSVDescriptor<T : RealmModel>(source: DataSource, vararg elements: Field) : CSVDescriptor(source, *elements) { /**
* A DataCSVDescriptor produces RealmModel instances for each row
*/
abstract class DataCSVDescriptor<T : RealmModel>(source: DataSource, vararg elements: CSVField) : CSVDescriptor(source, *elements) {
val realmModels = mutableListOf<RealmModel>() val realmModels = mutableListOf<RealmModel>()
@ -28,10 +33,19 @@ abstract class DataCSVDescriptor<T : RealmModel>(source: DataSource, vararg elem
} }
open class CSVDescriptor(var source: DataSource, vararg elements: Field) { /**
* A CSVDescriptor describes a CSV format by a source and a list of Fields
*/
abstract class CSVDescriptor(var source: DataSource, vararg elements: CSVField) {
protected var fields: List<Field> = listOf() /**
protected var fieldMapping: MutableMap<Field, Int> = mutableMapOf() * The CSVField list describing the CSV header format
*/
protected var fields: List<CSVField> = listOf()
/**
* The mapping of CSVField with their index in the CSV file
*/
protected var fieldMapping: MutableMap<CSVField, Int> = mutableMapOf()
init { init {
if (elements.size > 0) { if (elements.size > 0) {
@ -40,10 +54,16 @@ open class CSVDescriptor(var source: DataSource, vararg elements: Field) {
} }
companion object { companion object {
/**
* The list of all managed CSVDescriptors
*/
val all: List<CSVDescriptor> = val all: List<CSVDescriptor> =
listOf(SessionCSVDescriptor.pokerIncomeCash, SessionCSVDescriptor.pokerBankrollTracker, SessionCSVDescriptor.runGoodCashGames, SessionCSVDescriptor.runGoodTournaments) listOf(SessionCSVDescriptor.pokerIncomeCash, SessionCSVDescriptor.pokerBankrollTracker, SessionCSVDescriptor.runGoodCashGames, SessionCSVDescriptor.runGoodTournaments)
} }
/**
* Returns whether the [record] matches the CSVDescriptor
*/
fun matches(record: CSVRecord): Boolean { fun matches(record: CSVRecord): Boolean {
var count = 0 var count = 0
@ -63,9 +83,9 @@ open class CSVDescriptor(var source: DataSource, vararg elements: Field) {
return count == this.fields.size return count == this.fields.size
} }
open fun parse(realm: Realm, record: CSVRecord) { /**
* Method called when iterating on a CSVRecord
*/
} abstract fun parse(realm: Realm, record: CSVRecord)
} }

@ -9,24 +9,56 @@ import java.io.InputStream
import java.io.InputStreamReader import java.io.InputStreamReader
import java.io.Reader import java.io.Reader
open class CSVImporter { class ImportException(message: String) : Exception(message)
/**
* A CSVImporter is a class in charge of parsing a CSV file and processing it
* When starting the parsing of a file, the instance will search for a CSVDescriptor, which describes
* the format of a CSV file.
* When finding a descriptor, the CSVImporter then continue to parse the file and delegates the parsing of each row
* to the CSVDescriptor
*/
open class CSVImporter(istream: InputStream) {
/**
* Number of commits required to commit a Realm transaction
*/
private val COMMIT_FREQUENCY = 100 private val COMMIT_FREQUENCY = 100
/**
var path: String? = null * The number of column indicating a valid record
var inputStream: InputStream? = null */
private val VALID_RECORD_COLUMNS = 4
constructor(istream: InputStream) { /**
inputStream = istream * The number of valid record to test for descriptor before throwing a File Format Exception
} */
private val VALID_RECORD_ATTEMPTS_BEFORE_THROWING_EXCEPTION = 5
constructor(filePath: String) {
path = filePath /**
} * The path of the CSV file
*/
private var path: String? = null
/**
* The InputStream containing a file content
*/
private var inputStream: InputStream? = istream
/**
* The current number of attempts at finding a valid CSVDescriptor
*/
private var descriptorFindingAttempts = 0
/**
* Stores the descriptors found
*/
private var usedDescriptors: MutableList<CSVDescriptor> = mutableListOf() private var usedDescriptors: MutableList<CSVDescriptor> = mutableListOf()
/**
* The currently used CSVDescriptor for parsing
*/
private var currentDescriptor: CSVDescriptor? = null private var currentDescriptor: CSVDescriptor? = null
/**
* Constructs a CSVParser object and starts parsing the CSV
*/
fun start() { fun start() {
val realm = Realm.getDefaultInstance() val realm = Realm.getDefaultInstance()
@ -49,21 +81,31 @@ open class CSVImporter {
Timber.d("line $index") Timber.d("line $index")
if (currentDescriptor == null) { // find descriptor if (this.currentDescriptor == null) { // find descriptor
this.findDescriptor(record) this.currentDescriptor = this.findDescriptor(record)
} else {
if ((index + 1) % COMMIT_FREQUENCY == 0) { if (this.currentDescriptor == null) {
Timber.d("****** committing at ${index} sessions...") this.descriptorFindingAttempts++
if (record.size() > VALID_RECORD_COLUMNS && this.descriptorFindingAttempts > VALID_RECORD_ATTEMPTS_BEFORE_THROWING_EXCEPTION) {
throw ImportException("This type of file is not supported")
}
}
} else { // parse
val parsingIndex = index + 1
if (parsingIndex % COMMIT_FREQUENCY == 0) {
Timber.d("****** committing at $parsingIndex sessions...")
realm.commitTransaction() realm.commitTransaction()
realm.beginTransaction() realm.beginTransaction()
} }
currentDescriptor?.let { this.currentDescriptor?.let {
if (record.size() == 0) { if (record.size() == 0) {
this.usedDescriptors.add(it) this.usedDescriptors.add(it)
this.currentDescriptor = this.currentDescriptor = null // reset descriptor when encountering an empty line (multiple descriptors can be found in a single file)
null // reset descriptor when encountering an empty line (multiple descriptors can be found in a single file) this.descriptorFindingAttempts = 0
} else { } else {
it.parse(realm, record) it.parse(realm, record)
} }
@ -81,16 +123,19 @@ open class CSVImporter {
realm.close() realm.close()
} }
private fun findDescriptor(record: CSVRecord) { /**
* Search for a descriptor in the list of managed formats
*/
private fun findDescriptor(record: CSVRecord) : CSVDescriptor? {
CSVDescriptor.all.forEach { descriptor -> CSVDescriptor.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}")
return return descriptor
} }
} }
return null
} }
fun save(realm: Realm) { fun save(realm: Realm) {

@ -12,107 +12,113 @@ import net.pokeranalytics.android.util.extensions.setHourMinutes
import org.apache.commons.csv.CSVRecord import org.apache.commons.csv.CSVRecord
import java.util.* import java.util.*
/**
* The enumeration of Session fields
*/
sealed class SessionField { sealed class SessionField {
data class Start( data class Start(
override var header: String, override var header: String,
override var callback: ((String) -> Date?)? = null, override var callback: ((String) -> Date?)? = null,
override val dateFormat: String? = null override val dateFormat: String? = null
) : DateField ) : DateCSVField
data class StartTime( data class StartTime(
override var header: String, override var header: String,
override var callback: ((String) -> Date?)? = null, override var callback: ((String) -> Date?)? = null,
override val dateFormat: String? = null override val dateFormat: String? = null
) : DateField ) : DateCSVField
data class End( data class End(
override var header: String, override var header: String,
override var callback: ((String) -> Date?)? = null, override var callback: ((String) -> Date?)? = null,
override val dateFormat: String? = null override val dateFormat: String? = null
) : DateField ) : DateCSVField
data class EndTime( data class EndTime(
override var header: String, override var header: String,
override var callback: ((String) -> Date?)? = null, override var callback: ((String) -> Date?)? = null,
override val dateFormat: String? = null override val dateFormat: String? = null
) : DateField ) : DateCSVField
data class Buyin( data class Buyin(
override var header: String, override var header: String,
override var callback: ((String) -> Double?)? = null, override var callback: ((String) -> Double?)? = null,
override val numberFormat: String? = null override val numberFormat: String? = null
) : NumberField ) : NumberCSVField
data class NetResult( data class NetResult(
override var header: String, override var header: String,
override var callback: ((String) -> Double?)? = null, override var callback: ((String) -> Double?)? = null,
override val numberFormat: String? = null override val numberFormat: String? = null
) : NumberField ) : NumberCSVField
data class CashedOut( data class CashedOut(
override var header: String, override var header: String,
override var callback: ((String) -> Double?)? = null, override var callback: ((String) -> Double?)? = null,
override val numberFormat: String? = null override val numberFormat: String? = null
) : NumberField ) : NumberCSVField
data class Break( data class Break(
override var header: String, override var header: String,
override var callback: ((String) -> Double?)? = null, override var callback: ((String) -> Double?)? = null,
override val numberFormat: String? = null override val numberFormat: String? = null
) : NumberField ) : NumberCSVField
data class Tips( data class Tips(
override var header: String, override var header: String,
override var callback: ((String) -> Double?)? = null, override var callback: ((String) -> Double?)? = null,
override val numberFormat: String? = null override val numberFormat: String? = null
) : NumberField ) : NumberCSVField
data class SmallBlind( data class SmallBlind(
override var header: String, override var header: String,
override var callback: ((String) -> Double?)? = null, override var callback: ((String) -> Double?)? = null,
override val numberFormat: String? = null override val numberFormat: String? = null
) : NumberField ) : NumberCSVField
data class BigBlind( data class BigBlind(
override var header: String, override var header: String,
override var callback: ((String) -> Double?)? = null, override var callback: ((String) -> Double?)? = null,
override val numberFormat: String? = null override val numberFormat: String? = null
) : NumberField ) : NumberCSVField
data class Blind(override var header: String, override var callback: ((String) -> Pair<Double, Double>?)? = null) : BlindField data class Blind(override var header: String, override var callback: ((String) -> Pair<Double, Double>?)? = null) : BlindCSVField
data class Game(override var header: String) : Field data class Game(override var header: String) : CSVField
data class Location(override var header: String) : Field data class Location(override var header: String) : CSVField
data class LocationType(override var header: String) : Field data class LocationType(override var header: String) : CSVField
data class Bankroll(override var header: String) : Field data class Bankroll(override var header: String) : CSVField
data class LimitType(override var header: String) : Field data class LimitType(override var header: String) : CSVField
data class Comment(override var header: String) : Field data class Comment(override var header: String) : CSVField
data class SessionType(override var header: String) : Field data class SessionType(override var header: String) : CSVField
data class TableSize(override var header: String) : Field data class TableSize(override var header: String) : CSVField
data class CurrencyCode(override var header: String) : Field data class CurrencyCode(override var header: String) : CSVField
data class TournamentName(override var header: String) : Field data class TournamentName(override var header: String) : CSVField
data class TournamentType(override var header: String) : Field data class TournamentType(override var header: String) : CSVField
data class CurrencyRate( data class CurrencyRate(
override var header: String, override var header: String,
override var callback: ((String) -> Double?)? = null, override var callback: ((String) -> Double?)? = null,
override val numberFormat: String? = null override val numberFormat: String? = null
) : NumberField ) : NumberCSVField
data class TournamentPosition( data class TournamentPosition(
override var header: String, override var header: String,
override var callback: ((String) -> Double?)? = null, override var callback: ((String) -> Double?)? = null,
override val numberFormat: String? = null override val numberFormat: String? = null
) : NumberField ) : NumberCSVField
data class TournamentNumberOfPlayers( data class TournamentNumberOfPlayers(
override var header: String, override var header: String,
override var callback: ((String) -> Double?)? = null, override var callback: ((String) -> Double?)? = null,
override val numberFormat: String? = null override val numberFormat: String? = null
) : NumberField ) : NumberCSVField
} }
class SessionCSVDescriptor(source: DataSource, private var isTournament: Boolean, vararg elements: Field) : DataCSVDescriptor<Session>(source, *elements) { /**
* A SessionCSVDescriptor is a CSVDescriptor specialized in parsing Session objects
*/
class SessionCSVDescriptor(source: DataSource, private var isTournament: Boolean, vararg elements: CSVField) : DataCSVDescriptor<Session>(source, *elements) {
companion object { companion object {
val pokerIncomeCash: CSVDescriptor = SessionCSVDescriptor( val pokerIncomeCash: CSVDescriptor = SessionCSVDescriptor(
@ -216,6 +222,9 @@ class SessionCSVDescriptor(source: DataSource, private var isTournament: Boolean
} }
/**
* Parses a [record] and return an optional Session
*/
override fun parseData(realm: Realm, record: CSVRecord): Session? { override fun parseData(realm: Realm, record: CSVRecord): Session? {
val session = Session.newInstance(realm, this.isTournament) val session = Session.newInstance(realm, this.isTournament)
@ -283,11 +292,11 @@ class SessionCSVDescriptor(source: DataSource, private var isTournament: Boolean
val endDate = session.endDate val endDate = session.endDate
val net = session.result?.net val net = session.result?.net
if (startDate != null && endDate != null && net != null) { // valid session return if (startDate != null && endDate != null && net != null) { // valid session
val unique = SessionUtils.unicityCheck(realm, startDate, endDate, net) val unique = SessionUtils.unicityCheck(realm, startDate, endDate, net)
return if (unique) session else null if (unique) session else null
} else { // invalid session } else { // invalid session
return null null
} }
} }

@ -7,8 +7,10 @@ import java.text.ParseException
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.* import java.util.*
/**
interface NumberField: TypedField<Double> { * An interface used to provide a Number flavour to a CSV field
*/
interface NumberCSVField: TypedCSVField<Double> {
val numberFormat: String? val numberFormat: String?
@ -29,7 +31,7 @@ interface NumberField: TypedField<Double> {
} }
} }
interface DateField : TypedField<Date> { interface DateCSVField : TypedCSVField<Date> {
val dateFormat: String? val dateFormat: String?
@ -46,7 +48,7 @@ interface DateField : TypedField<Date> {
} }
interface BlindField : TypedField<Pair<Double, Double>> { interface BlindCSVField : TypedCSVField<Pair<Double, Double>> {
override fun parse(value: String) : Pair<Double, Double>? { override fun parse(value: String) : Pair<Double, Double>? {
@ -68,11 +70,11 @@ interface BlindField : TypedField<Pair<Double, Double>> {
} }
interface TypedField<T> : Field { interface TypedCSVField<T> : CSVField {
fun parse(value: String) : T? fun parse(value: String) : T?
var callback: ((String) -> T?)? var callback: ((String) -> T?)?
} }
interface Field { interface CSVField {
val header: String val header: String
} }
Loading…
Cancel
Save