parent
35a3a2429e
commit
2f6a7a7717
@ -0,0 +1,21 @@ |
||||
package net.pokeranalytics.android.model.utils |
||||
|
||||
import io.realm.Realm |
||||
import net.pokeranalytics.android.model.realm.Session |
||||
import java.util.* |
||||
|
||||
class SessionUtils { |
||||
|
||||
companion object { |
||||
|
||||
/** |
||||
* Returns true if the provided parameters doesn't correspond to an existing session |
||||
*/ |
||||
fun unicityCheck(realm: Realm, startDate: Date, endDate: Date, net: Double) : Boolean { |
||||
val sessions = realm.where(Session::class.java).equalTo("startDate", startDate).equalTo("endDate", endDate).equalTo("result.net", net).findAll() |
||||
return sessions.isEmpty() |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,60 @@ |
||||
package net.pokeranalytics.android.util.csv |
||||
|
||||
import io.realm.Realm |
||||
import io.realm.RealmModel |
||||
import org.apache.commons.csv.CSVRecord |
||||
|
||||
|
||||
abstract class DataCSVDescriptor<T : RealmModel>(vararg elements: Field<*>) : CSVDescriptor(*elements) { |
||||
|
||||
val realmModels = mutableListOf<RealmModel>() |
||||
|
||||
abstract fun parseData(realm: Realm, record: CSVRecord) : T? |
||||
|
||||
override fun parse(realm: Realm, record: CSVRecord) { |
||||
|
||||
val data = this.parseData(realm, record) |
||||
data?.let { |
||||
this.realmModels.add(it) |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
||||
|
||||
open class CSVDescriptor(vararg elements: Field<*>) { |
||||
|
||||
protected var fields: List<Field<*>> = listOf() |
||||
|
||||
init { |
||||
if (elements.size > 0) { |
||||
this.fields = elements.toList() |
||||
} |
||||
} |
||||
|
||||
companion object { |
||||
val all: List<CSVDescriptor> = listOf(SessionCSVDescriptor.pokerIncomeCash) |
||||
} |
||||
|
||||
fun matches(headerMap: Map<String, Int>) : Boolean { |
||||
|
||||
var count = 0 |
||||
val headers = headerMap.keys |
||||
|
||||
this.fields.forEach { |
||||
|
||||
val index = headers.indexOf(it.header) |
||||
if (index >= 0) { |
||||
count++ |
||||
} |
||||
} |
||||
|
||||
return count == this.fields.size |
||||
} |
||||
|
||||
open fun parse(realm: Realm, record: CSVRecord) { |
||||
|
||||
|
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,55 @@ |
||||
package net.pokeranalytics.android.util.csv |
||||
|
||||
import io.realm.Realm |
||||
import org.apache.commons.csv.CSVFormat |
||||
import org.apache.commons.csv.CSVParser |
||||
import timber.log.Timber |
||||
import java.io.FileReader |
||||
|
||||
open class CSVImporter(var path: String) { |
||||
|
||||
private lateinit var descriptor: CSVDescriptor |
||||
|
||||
private fun start(realm: Realm) { |
||||
|
||||
val reader = FileReader(this.path) |
||||
|
||||
val parser = CSVFormat.RFC4180.withFirstRecordAsHeader().parse(reader) |
||||
|
||||
val descriptor = this.findDescriptor(parser.headerMap) |
||||
|
||||
if (descriptor != null) { |
||||
this.descriptor = descriptor |
||||
this.parse(realm, descriptor, parser) |
||||
} else { |
||||
Timber.d("No CSV descriptor found") |
||||
} |
||||
|
||||
} |
||||
|
||||
private fun findDescriptor(header: Map<String, Int>) : CSVDescriptor? { |
||||
CSVDescriptor.all.forEach { |
||||
if (it.matches(header)) { |
||||
return it |
||||
} |
||||
} |
||||
return null |
||||
} |
||||
|
||||
protected open fun parse(realm: Realm, descriptor: CSVDescriptor, parser : CSVParser) { |
||||
parser.records.forEach { record -> |
||||
descriptor.parse(realm, record) |
||||
} |
||||
} |
||||
|
||||
fun save(realm: Realm) { |
||||
|
||||
if (descriptor is DataCSVDescriptor<*>) { |
||||
realm.executeTransaction { |
||||
realm.copyToRealm((descriptor as DataCSVDescriptor<*>).realmModels) |
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,38 @@ |
||||
package net.pokeranalytics.android.util.csv |
||||
|
||||
import java.util.* |
||||
|
||||
|
||||
interface AmountField: NumberField { |
||||
|
||||
override fun parse(value: String) : Double? { |
||||
return null |
||||
} |
||||
|
||||
} |
||||
|
||||
interface NumberField: Field<Double> { |
||||
val numberFormat: String? |
||||
} |
||||
|
||||
interface DateField : Field<Date> { |
||||
val dateFormat: String? |
||||
|
||||
override fun parse(value: String) : Date? { |
||||
return null |
||||
} |
||||
} |
||||
|
||||
interface BlindField : Field<Double> { |
||||
override fun parse(value: String) : Double? { |
||||
return null |
||||
} |
||||
|
||||
} |
||||
|
||||
interface Field<T> { |
||||
val header: String |
||||
var callback: (() -> Unit)? |
||||
|
||||
fun parse(value: String) : T? |
||||
} |
||||
@ -0,0 +1,68 @@ |
||||
package net.pokeranalytics.android.util.csv |
||||
|
||||
import io.realm.Realm |
||||
import net.pokeranalytics.android.model.realm.Session |
||||
import net.pokeranalytics.android.model.utils.SessionUtils |
||||
import org.apache.commons.csv.CSVRecord |
||||
|
||||
sealed class SessionField { |
||||
|
||||
data class Start(override var header: String, override var callback: (() -> Unit)? = null, override val dateFormat: String? = null) : DateField |
||||
data class End(override var header: String, override var callback: (() -> Unit)? = null, override val dateFormat: String? = null) : DateField |
||||
|
||||
data class Buyin(override var header: String, override var callback: (() -> Unit)? = null, override val numberFormat: String? = null) : AmountField |
||||
data class CashedOut(override var header: String, override var callback: (() -> Unit)? = null, override val numberFormat: String? = null) : AmountField |
||||
|
||||
data class Blind(override var header: String, override var callback: (() -> Unit)? = null) : BlindField |
||||
|
||||
} |
||||
|
||||
class SessionCSVDescriptor(vararg elements: Field<*>) : DataCSVDescriptor<Session>(*elements) { |
||||
|
||||
companion object { |
||||
val pokerIncomeCash: CSVDescriptor = SessionCSVDescriptor(SessionField.Start("Start Time"), |
||||
SessionField.End("End Time"), |
||||
SessionField.Buyin("Buy In"), |
||||
SessionField.CashedOut("Cashed Out")) |
||||
|
||||
} |
||||
|
||||
override fun parseData(realm: Realm, record: CSVRecord): Session? { |
||||
|
||||
val session = Session() |
||||
|
||||
fields.forEach { |
||||
|
||||
val value = record.get(it.header) |
||||
when (it) { |
||||
is SessionField.Start -> { |
||||
session.startDate = it.parse(value) |
||||
} |
||||
is SessionField.End -> { |
||||
session.endDate = it.parse(value) |
||||
} |
||||
is SessionField.Buyin -> session.result?.buyin = it.parse(value) |
||||
is SessionField.CashedOut -> session.result?.cashout = it.parse(value) |
||||
is SessionField.Blind -> { |
||||
// session.cgSmallBlind = |
||||
} |
||||
else -> {} |
||||
} |
||||
|
||||
|
||||
} |
||||
|
||||
val startDate = session.startDate |
||||
val endDate = session.endDate |
||||
val net = session.result?.net |
||||
|
||||
if (startDate != null && endDate != null && net != null) { // valid session |
||||
val unique = SessionUtils.unicityCheck(realm, startDate, endDate, net) |
||||
return if (unique) session else null |
||||
} else { // invalid session |
||||
return null |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
||||
@ -1,4 +1,4 @@ |
||||
package net.pokeranalytics.android.util |
||||
package net.pokeranalytics.android.util.extensions |
||||
|
||||
import io.realm.Realm |
||||
import io.realm.RealmModel |
||||
Loading…
Reference in new issue