diff --git a/app/src/main/java/com/pixelized/rplexicon/repository/data/character/AlterationRepository.kt b/app/src/main/java/com/pixelized/rplexicon/repository/data/character/AlterationRepository.kt index 6fc5e0f..c4f6623 100644 --- a/app/src/main/java/com/pixelized/rplexicon/repository/data/character/AlterationRepository.kt +++ b/app/src/main/java/com/pixelized/rplexicon/repository/data/character/AlterationRepository.kt @@ -88,7 +88,7 @@ class AlterationRepository @Inject constructor( suspend fun fetchAlterationSheet(sheets: List) { googleRepository.fetch { sheet -> val request = sheet.get(CharacterBinder.ID, CharacterBinder.ALTERATION) - val data = alterationParser.parse(values = request.execute(), sheets = sheets) + val data = alterationParser.parse(sheet = request.execute(), characterSheets = sheets) _assignedAlterations.emit(data) lastSuccessFullUpdate = Update.currentTime() } diff --git a/app/src/main/java/com/pixelized/rplexicon/repository/data/character/DescriptionRepository.kt b/app/src/main/java/com/pixelized/rplexicon/repository/data/character/DescriptionRepository.kt index 73ffe6c..66d810c 100644 --- a/app/src/main/java/com/pixelized/rplexicon/repository/data/character/DescriptionRepository.kt +++ b/app/src/main/java/com/pixelized/rplexicon/repository/data/character/DescriptionRepository.kt @@ -28,7 +28,7 @@ class DescriptionRepository @Inject constructor( suspend fun fetchDescription() { googleRepository.fetch { sheet -> val request = sheet.get(CharacterBinder.ID, CharacterBinder.DESCRIPTION) - val data = parser.parse(data = request.execute()) + val data = parser.parse(sheet = request.execute()) _data.tryEmit(data) lastSuccessFullUpdate = Update.currentTime() diff --git a/app/src/main/java/com/pixelized/rplexicon/repository/data/character/InventoryRepository.kt b/app/src/main/java/com/pixelized/rplexicon/repository/data/character/InventoryRepository.kt index 35f1ba3..8991b2c 100644 --- a/app/src/main/java/com/pixelized/rplexicon/repository/data/character/InventoryRepository.kt +++ b/app/src/main/java/com/pixelized/rplexicon/repository/data/character/InventoryRepository.kt @@ -28,7 +28,7 @@ class InventoryRepository @Inject constructor( suspend fun fetchInventory() { googleRepository.fetch { sheet -> val request = sheet.get(CharacterBinder.ID, CharacterBinder.INVENTORY) - val data = inventoryParser.parse(data = request.execute()) + val data = inventoryParser.parse(sheet = request.execute()) _data.tryEmit(data) lastSuccessFullUpdate = Update.currentTime() } diff --git a/app/src/main/java/com/pixelized/rplexicon/repository/data/character/SkillRepository.kt b/app/src/main/java/com/pixelized/rplexicon/repository/data/character/SkillRepository.kt index 59af53a..e5bdec6 100644 --- a/app/src/main/java/com/pixelized/rplexicon/repository/data/character/SkillRepository.kt +++ b/app/src/main/java/com/pixelized/rplexicon/repository/data/character/SkillRepository.kt @@ -30,7 +30,7 @@ class SkillRepository @Inject constructor( suspend fun fetchSkills() { googleRepository.fetch { sheet -> val request = sheet.get(CharacterBinder.ID, CharacterBinder.SKILL) - val skills = skillParser.parse(data = request.execute()) + val skills = skillParser.parse(sheet = request.execute()) _skills.emit(skills) lastSuccessFullUpdate = Update.currentTime() diff --git a/app/src/main/java/com/pixelized/rplexicon/repository/data/character/SpellRepository.kt b/app/src/main/java/com/pixelized/rplexicon/repository/data/character/SpellRepository.kt index 0549fae..94fb7c1 100644 --- a/app/src/main/java/com/pixelized/rplexicon/repository/data/character/SpellRepository.kt +++ b/app/src/main/java/com/pixelized/rplexicon/repository/data/character/SpellRepository.kt @@ -43,8 +43,8 @@ class SpellRepository @Inject constructor( async { sheet.get(CharacterBinder.ID, CharacterBinder.MAGIC_LEXICON).execute() }, async { sheet.get(CharacterBinder.ID, CharacterBinder.MAGIC).execute() }, ) - val spellsBook = spellBookParser.parse(data = lexicon) - val assignedSpells = assignedSpellParser.parse(data = magic, spells = spellsBook) + val spellsBook = spellBookParser.parse(sheet = lexicon) + val assignedSpells = assignedSpellParser.parse(sheet = magic, spells = spellsBook) this@SpellRepository.spellsBook = spellsBook _spells.emit(assignedSpells) lastSuccessFullUpdate = Update.currentTime() diff --git a/app/src/main/java/com/pixelized/rplexicon/repository/data/lexicon/LexiconRepository.kt b/app/src/main/java/com/pixelized/rplexicon/repository/data/lexicon/LexiconRepository.kt index 140087f..13bcb91 100644 --- a/app/src/main/java/com/pixelized/rplexicon/repository/data/lexicon/LexiconRepository.kt +++ b/app/src/main/java/com/pixelized/rplexicon/repository/data/lexicon/LexiconRepository.kt @@ -30,7 +30,7 @@ class LexiconRepository @Inject constructor( suspend fun fetchLexicon() { googleRepository.fetch { sheet -> val request = sheet.get(LexiconBinder.ID, LexiconBinder.LEXICON) - val data = lexiconParser.parse(data = request.execute()) + val data = lexiconParser.parse(sheet = request.execute()) _data.tryEmit(data) lastSuccessFullUpdate = Update.currentTime() diff --git a/app/src/main/java/com/pixelized/rplexicon/repository/data/lexicon/LocationRepository.kt b/app/src/main/java/com/pixelized/rplexicon/repository/data/lexicon/LocationRepository.kt index 9db53c8..bc171e0 100644 --- a/app/src/main/java/com/pixelized/rplexicon/repository/data/lexicon/LocationRepository.kt +++ b/app/src/main/java/com/pixelized/rplexicon/repository/data/lexicon/LocationRepository.kt @@ -46,11 +46,11 @@ class LocationRepository @Inject constructor( @Throws(IncompatibleSheetStructure::class) private suspend fun updateData(map: ValueRange, marquee: ValueRange) { val marquees = marqueeParser - .parse(data = marquee) + .parse(sheet = marquee) .groupBy { it.map } val maps = locationParser - .parse(data = map) + .parse(sheet = map) .map { val associatedMarquees = marquees[it.name] if (associatedMarquees != null) { diff --git a/app/src/main/java/com/pixelized/rplexicon/repository/data/lexicon/QuestRepository.kt b/app/src/main/java/com/pixelized/rplexicon/repository/data/lexicon/QuestRepository.kt index 591d9cf..3e80950 100644 --- a/app/src/main/java/com/pixelized/rplexicon/repository/data/lexicon/QuestRepository.kt +++ b/app/src/main/java/com/pixelized/rplexicon/repository/data/lexicon/QuestRepository.kt @@ -35,7 +35,7 @@ class QuestRepository @Inject constructor( @Throws(IncompatibleSheetStructure::class, Exception::class) private suspend fun updateData(data: ValueRange) { - val questEntries = questParser.parse(value = data) + val questEntries = questParser.parse(sheet = data) val questMap = questEntries.groupBy { it.title } val quests = questMap.keys.mapIndexed { index, item -> Quest( diff --git a/app/src/main/java/com/pixelized/rplexicon/repository/parser/AttackParser.kt b/app/src/main/java/com/pixelized/rplexicon/repository/parser/AttackParser.kt index 9c5b3ff..34fead2 100644 --- a/app/src/main/java/com/pixelized/rplexicon/repository/parser/AttackParser.kt +++ b/app/src/main/java/com/pixelized/rplexicon/repository/parser/AttackParser.kt @@ -5,8 +5,6 @@ import com.google.api.services.sheets.v4.model.ValueRange import com.pixelized.rplexicon.model.Attack import com.pixelized.rplexicon.model.CharacterSheet import com.pixelized.rplexicon.utilitary.exceptions.IncompatibleSheetStructure -import com.pixelized.rplexicon.utilitary.extentions.local.checkSheetStructure -import com.pixelized.rplexicon.utilitary.extentions.sheet import javax.inject.Inject class AttackParser @Inject constructor( @@ -16,34 +14,24 @@ class AttackParser @Inject constructor( fun parse( value: ValueRange, charactersSheets: Map, - ): Map> { - val sheet = value.values.sheet() - - lateinit var structure: Map - + ): Map> = parserScope { // declare helper method to parse String - fun List<*>.parseString(key: String): String? = - (getOrNull(structure.getValue(key)) as? String)?.takeIf { it.isNotEmpty() } - val actions = hashMapOf>() - sheet?.forEachIndexed { index, row -> - when { - index == 0 -> { - structure = row.checkSheetStructure(model = COLUMNS) - } - - row is List<*> -> { + value.forEachRow { index, row -> + when (index) { + 0 -> updateStructure(row = row, columns = COLUMNS) + else -> { // Assume that the name is the first column. - val characterSheet = charactersSheets[row.getOrNull(0) as? String ?: ""] - val title = row.parseString(NAME) + val characterSheet = charactersSheets[row.parse(CHARACTER)] + val title = row.parse(column = NAME) if (characterSheet != null && title != null) { val attack = Attack( title = title, - type = parseType(value = row.parseString(TYPE)), - range = row.parseString(RANGE), - hit = throwParser.parse(value = row.parseString(HIT)), - damage = throwParser.parse(value = row.parseString(DAMAGE)), + type = parseType(value = row.parse(column = TYPE)), + range = row.parse(column = RANGE), + hit = throwParser.parse(value = row.parse(column = HIT)), + damage = throwParser.parse(value = row.parse(column = DAMAGE)), ) actions .getOrPut(characterSheet.name) { mutableListOf() } @@ -53,7 +41,7 @@ class AttackParser @Inject constructor( } } - return actions + actions } private fun parseType(value: String?): Attack.Type = try { @@ -64,12 +52,12 @@ class AttackParser @Inject constructor( } ?: Attack.Type.PHYSICAL_MELEE_ATTACK companion object { - const val NAME = "Nom" - const val TYPE = "Type" - const val RANGE = "Portée" - const val HIT = "Touché" - const val DAMAGE = "Dommage" - - val COLUMNS get() = listOf("", NAME, TYPE, RANGE, HIT, DAMAGE) + private val CHARACTER = column("") + private val NAME = column("Nom") + private val TYPE = column("Type") + private val RANGE = column("Portée") + private val HIT = column("Touché") + private val DAMAGE = column("Dommage") + private val COLUMNS get() = listOf(CHARACTER, NAME, TYPE, RANGE, HIT, DAMAGE) } } \ No newline at end of file diff --git a/app/src/main/java/com/pixelized/rplexicon/repository/parser/CharacterSheetParser.kt b/app/src/main/java/com/pixelized/rplexicon/repository/parser/CharacterSheetParser.kt index cf3ac34..28d61df 100644 --- a/app/src/main/java/com/pixelized/rplexicon/repository/parser/CharacterSheetParser.kt +++ b/app/src/main/java/com/pixelized/rplexicon/repository/parser/CharacterSheetParser.kt @@ -3,7 +3,6 @@ package com.pixelized.rplexicon.repository.parser import com.google.api.services.sheets.v4.model.ValueRange import com.pixelized.rplexicon.model.CharacterSheet import com.pixelized.rplexicon.utilitary.exceptions.IncompatibleSheetStructure -import com.pixelized.rplexicon.utilitary.extentions.local.checkSheetStructure import com.pixelized.rplexicon.utilitary.extentions.sheet import javax.inject.Inject @@ -11,8 +10,7 @@ import javax.inject.Inject class CharacterSheetParser @Inject constructor() { @Throws(IncompatibleSheetStructure::class) - fun parse(value: ValueRange): Map { - + fun parse(value: ValueRange): Map = parserScope { // fetch the character sheet val sheet = value.values.sheet() // fetch the List<*> ?.mapNotNull { it as? List<*> } // transform the List<*> to a List> @@ -20,79 +18,66 @@ class CharacterSheetParser @Inject constructor() { val entryCount = if (sheet.isNotEmpty()) sheet[0].size else 0 List(entryCount) { index -> sheet.map { it.getOrNull(index) } } } - - // prepare a hash on the structure & function to get index in it. - lateinit var structure: Map - - // declare helper method to parse String - fun List<*>.parseString(key: String): String? = - (getOrNull(structure.getValue(key)) as? String)?.takeIf { it.isNotEmpty() } - - // declare helper method to parse Int - fun List<*>.parseInt(key: String): Int? = parseString(key = key)?.toIntOrNull() - // parse the sheet - return sheet?.mapIndexedNotNull { index, item -> + sheet?.mapIndexedNotNull { index, item -> when (index) { 0 -> { - structure = item.checkSheetStructure(model = ROWS) - return@mapIndexedNotNull null + updateStructure(row = item, columns = ROWS) + null } else -> { - val name = item.parseString(NAME) + val name = item.parse(column = NAME) if (name != null) { CharacterSheet( name = name, - race = item.parseString(RACE), - proficiency = item.parseInt(MASTERY) ?: 2, - level = item.parseInt(LEVEL) ?: 2, - characterClass = item.parseString(CLASS) ?: "", - hitPoint = item.parseInt(MAX_HIT_POINT) ?: 1, - spell1 = item.parseInt(SPELL_LEVEL_1), - spell2 = item.parseInt(SPELL_LEVEL_2), - spell3 = item.parseInt(SPELL_LEVEL_3), - spell4 = item.parseInt(SPELL_LEVEL_4), - spell5 = item.parseInt(SPELL_LEVEL_5), - spell6 = item.parseInt(SPELL_LEVEL_6), - spell7 = item.parseInt(SPELL_LEVEL_7), - spell8 = item.parseInt(SPELL_LEVEL_8), - spell9 = item.parseInt(SPELL_LEVEL_9), - dC = item.parseInt(DD_SAVE_THROW), - armorClass = item.parseInt(ARMOR_CLASS) ?: 10, - speed = item.parseInt(SPEED) ?: 10, - strength = item.parseInt(STRENGTH) ?: 10, - dexterity = item.parseInt(DEXTERITY) ?: 10, - constitution = item.parseInt(CONSTITUTION) ?: 10, - intelligence = item.parseInt(INTELLIGENCE) ?: 10, - wisdom = item.parseInt(WISDOM) ?: 10, - charisma = item.parseInt(CHARISMA) ?: 10, - strengthSavingThrows = item.parseInt(STRENGTH_SAVING_THROW) ?: 0, - dexteritySavingThrows = item.parseInt(DEXTERITY_SAVING_THROW) ?: 0, - constitutionSavingThrows = item.parseInt(CONSTITUTION_SAVING_THROW) - ?: 0, - intelligenceSavingThrows = item.parseInt(INTELLIGENCE_SAVING_THROW) - ?: 0, - wisdomSavingThrows = item.parseInt(WISDOM_SAVING_THROW) ?: 0, - charismaSavingThrows = item.parseInt(CHARISMA_SAVING_THROW) ?: 0, - acrobatics = item.parseInt(ACROBATICS) ?: 0, - animalHandling = item.parseInt(ANIMAL_HANDLING) ?: 0, - arcana = item.parseInt(ARCANA) ?: 0, - athletics = item.parseInt(ATHLETICS) ?: 0, - deception = item.parseInt(DECEPTION) ?: 0, - history = item.parseInt(HISTORY) ?: 0, - insight = item.parseInt(INSIGHT) ?: 0, - intimidation = item.parseInt(INTIMIDATION) ?: 0, - investigation = item.parseInt(INVESTIGATION) ?: 0, - medicine = item.parseInt(MEDICINE) ?: 0, - nature = item.parseInt(NATURE) ?: 0, - perception = item.parseInt(PERCEPTION) ?: 0, - performance = item.parseInt(PERFORMANCE) ?: 0, - persuasion = item.parseInt(PERSUASION) ?: 0, - religion = item.parseInt(RELIGION) ?: 0, - sleightOfHand = item.parseInt(SLEIGHT_OF_HAND) ?: 0, - stealth = item.parseInt(STEALTH) ?: 0, - survival = item.parseInt(SURVIVAL) ?: 0, + race = item.parse(column = RACE), + proficiency = item.parseInt(column = MASTERY) ?: 2, + level = item.parseInt(column = LEVEL) ?: 2, + characterClass = item.parse(column = CLASS) ?: "", + hitPoint = item.parseInt(column = MAX_HIT_POINT) ?: 1, + spell1 = item.parseInt(column = SPELL_LEVEL_1), + spell2 = item.parseInt(column = SPELL_LEVEL_2), + spell3 = item.parseInt(column = SPELL_LEVEL_3), + spell4 = item.parseInt(column = SPELL_LEVEL_4), + spell5 = item.parseInt(column = SPELL_LEVEL_5), + spell6 = item.parseInt(column = SPELL_LEVEL_6), + spell7 = item.parseInt(column = SPELL_LEVEL_7), + spell8 = item.parseInt(column = SPELL_LEVEL_8), + spell9 = item.parseInt(column = SPELL_LEVEL_9), + dC = item.parseInt(column = DD_SAVE_THROW), + armorClass = item.parseInt(column = ARMOR_CLASS) ?: 10, + speed = item.parseInt(column = SPEED) ?: 10, + strength = item.parseInt(column = STRENGTH) ?: 10, + dexterity = item.parseInt(column = DEXTERITY) ?: 10, + constitution = item.parseInt(column = CONSTITUTION) ?: 10, + intelligence = item.parseInt(column = INTELLIGENCE) ?: 10, + wisdom = item.parseInt(column = WISDOM) ?: 10, + charisma = item.parseInt(column = CHARISMA) ?: 10, + strengthSavingThrows = item.parseInt(column = STRENGTH_SAVING_THROW) ?: 0, + dexteritySavingThrows = item.parseInt(column = DEXTERITY_SAVING_THROW) ?: 0, + constitutionSavingThrows = item.parseInt(column = CONSTITUTION_SAVING_THROW) ?: 0, + intelligenceSavingThrows = item.parseInt(column = INTELLIGENCE_SAVING_THROW) ?: 0, + wisdomSavingThrows = item.parseInt(column = WISDOM_SAVING_THROW) ?: 0, + charismaSavingThrows = item.parseInt(column = CHARISMA_SAVING_THROW) ?: 0, + acrobatics = item.parseInt(column = ACROBATICS) ?: 0, + animalHandling = item.parseInt(column = ANIMAL_HANDLING) ?: 0, + arcana = item.parseInt(column = ARCANA) ?: 0, + athletics = item.parseInt(column = ATHLETICS) ?: 0, + deception = item.parseInt(column = DECEPTION) ?: 0, + history = item.parseInt(column = HISTORY) ?: 0, + insight = item.parseInt(column = INSIGHT) ?: 0, + intimidation = item.parseInt(column = INTIMIDATION) ?: 0, + investigation = item.parseInt(column = INVESTIGATION) ?: 0, + medicine = item.parseInt(column = MEDICINE) ?: 0, + nature = item.parseInt(column = NATURE) ?: 0, + perception = item.parseInt(column = PERCEPTION) ?: 0, + performance = item.parseInt(column = PERFORMANCE) ?: 0, + persuasion = item.parseInt(column = PERSUASION) ?: 0, + religion = item.parseInt(column = RELIGION) ?: 0, + sleightOfHand = item.parseInt(column = SLEIGHT_OF_HAND) ?: 0, + stealth = item.parseInt(column = STEALTH) ?: 0, + survival = item.parseInt(column = SURVIVAL) ?: 0, ) } else { null @@ -103,54 +88,54 @@ class CharacterSheetParser @Inject constructor() { } companion object { - private const val NAME = "Nom" - private const val RACE = "Race" - private const val LEVEL = "Niveau" - private const val CLASS = "Classe" - private const val MAX_HIT_POINT = "Point de vie MAX" - private const val SPELL_LEVEL_1 = "Sort de niveau 1" - private const val SPELL_LEVEL_2 = "Sort de niveau 2" - private const val SPELL_LEVEL_3 = "Sort de niveau 3" - private const val SPELL_LEVEL_4 = "Sort de niveau 4" - private const val SPELL_LEVEL_5 = "Sort de niveau 5" - private const val SPELL_LEVEL_6 = "Sort de niveau 6" - private const val SPELL_LEVEL_7 = "Sort de niveau 7" - private const val SPELL_LEVEL_8 = "Sort de niveau 8" - private const val SPELL_LEVEL_9 = "Sort de niveau 9" - private const val DD_SAVE_THROW = "DD sauvergarde des sorts" - private const val ARMOR_CLASS = "Classe d'armure" - private const val SPEED = "Vitesse" - private const val MASTERY = "Bonus de maîtrise" - private const val STRENGTH = "Force" - private const val DEXTERITY = "Dextérité" - private const val CONSTITUTION = "Constitution" - private const val INTELLIGENCE = "Intelligence" - private const val WISDOM = "Sagesse" - private const val CHARISMA = "Charisme" - private const val STRENGTH_SAVING_THROW = "Jet de sauvegarde: Force" - private const val DEXTERITY_SAVING_THROW = "Jet de sauvegarde: Dextérité" - private const val CONSTITUTION_SAVING_THROW = "Jet de sauvegarde: Constitution" - private const val INTELLIGENCE_SAVING_THROW = "Jet de sauvegarde: Intelligence" - private const val WISDOM_SAVING_THROW = "Jet de sauvegarde: Sagesse" - private const val CHARISMA_SAVING_THROW = "Jet de sauvegarde: Charisme" - private const val ACROBATICS = "Acrobaties" - private const val ANIMAL_HANDLING = "Dressage" - private const val ARCANA = "Arcanes" - private const val ATHLETICS = "Athlétisme" - private const val DECEPTION = "Tromperie" - private const val HISTORY = "Histoire" - private const val INSIGHT = "Intuition" - private const val INTIMIDATION = "Intimidation" - private const val INVESTIGATION = "Investigation" - private const val MEDICINE = "Médecine" - private const val NATURE = "Nature" - private const val PERCEPTION = "Perception" - private const val PERFORMANCE = "Représentation" - private const val PERSUASION = "Persuasion" - private const val RELIGION = "Religion" - private const val SLEIGHT_OF_HAND = "Escamotage" - private const val STEALTH = "Discrétion" - private const val SURVIVAL = "Survie" + private val NAME = column("Nom") + private val RACE = column("Race") + private val LEVEL = column("Niveau") + private val CLASS = column("Classe") + private val MAX_HIT_POINT = column("Point de vie MAX") + private val SPELL_LEVEL_1 = column("Sort de niveau 1") + private val SPELL_LEVEL_2 = column("Sort de niveau 2") + private val SPELL_LEVEL_3 = column("Sort de niveau 3") + private val SPELL_LEVEL_4 = column("Sort de niveau 4") + private val SPELL_LEVEL_5 = column("Sort de niveau 5") + private val SPELL_LEVEL_6 = column("Sort de niveau 6") + private val SPELL_LEVEL_7 = column("Sort de niveau 7") + private val SPELL_LEVEL_8 = column("Sort de niveau 8") + private val SPELL_LEVEL_9 = column("Sort de niveau 9") + private val DD_SAVE_THROW = column("DD sauvergarde des sorts") + private val ARMOR_CLASS = column("Classe d'armure") + private val SPEED = column("Vitesse") + private val MASTERY = column("Bonus de maîtrise") + private val STRENGTH = column("Force") + private val DEXTERITY = column("Dextérité") + private val CONSTITUTION = column("Constitution") + private val INTELLIGENCE = column("Intelligence") + private val WISDOM = column("Sagesse") + private val CHARISMA = column("Charisme") + private val STRENGTH_SAVING_THROW = column("Jet de sauvegarde: Force") + private val DEXTERITY_SAVING_THROW = column("Jet de sauvegarde: Dextérité") + private val CONSTITUTION_SAVING_THROW = column("Jet de sauvegarde: Constitution") + private val INTELLIGENCE_SAVING_THROW = column("Jet de sauvegarde: Intelligence") + private val WISDOM_SAVING_THROW = column("Jet de sauvegarde: Sagesse") + private val CHARISMA_SAVING_THROW = column("Jet de sauvegarde: Charisme") + private val ACROBATICS = column("Acrobaties") + private val ANIMAL_HANDLING = column("Dressage") + private val ARCANA = column("Arcanes") + private val ATHLETICS = column("Athlétisme") + private val DECEPTION = column("Tromperie") + private val HISTORY = column("Histoire") + private val INSIGHT = column("Intuition") + private val INTIMIDATION = column("Intimidation") + private val INVESTIGATION = column("Investigation") + private val MEDICINE = column("Médecine") + private val NATURE = column("Nature") + private val PERCEPTION = column("Perception") + private val PERFORMANCE = column("Représentation") + private val PERSUASION = column("Persuasion") + private val RELIGION = column("Religion") + private val SLEIGHT_OF_HAND = column("Escamotage") + private val STEALTH = column("Discrétion") + private val SURVIVAL = column("Survie") private val ROWS get() = listOf( diff --git a/app/src/main/java/com/pixelized/rplexicon/repository/parser/Column.kt b/app/src/main/java/com/pixelized/rplexicon/repository/parser/Column.kt new file mode 100644 index 0000000..16bd761 --- /dev/null +++ b/app/src/main/java/com/pixelized/rplexicon/repository/parser/Column.kt @@ -0,0 +1,11 @@ +package com.pixelized.rplexicon.repository.parser + +data class Column( + val names: List, +) { + override fun toString(): String { + return names.toString() + } +} + +fun column(vararg names: String) = Column(names = names.toList()) \ No newline at end of file diff --git a/app/src/main/java/com/pixelized/rplexicon/repository/parser/DescriptionParser.kt b/app/src/main/java/com/pixelized/rplexicon/repository/parser/DescriptionParser.kt index db07a88..1dcfda0 100644 --- a/app/src/main/java/com/pixelized/rplexicon/repository/parser/DescriptionParser.kt +++ b/app/src/main/java/com/pixelized/rplexicon/repository/parser/DescriptionParser.kt @@ -3,32 +3,23 @@ package com.pixelized.rplexicon.repository.parser import com.google.api.services.sheets.v4.model.ValueRange import com.pixelized.rplexicon.model.Description import com.pixelized.rplexicon.utilitary.exceptions.IncompatibleSheetStructure -import com.pixelized.rplexicon.utilitary.extentions.local.checkSheetStructure -import com.pixelized.rplexicon.utilitary.extentions.sheet import javax.inject.Inject class DescriptionParser @Inject constructor() { @Throws(IncompatibleSheetStructure::class) - fun parse(data: ValueRange): Map { - val sheet = data.values.sheet() - val values = hashMapOf() - - lateinit var structure: Map - - sheet?.forEachIndexed { index, item -> - when { - index == 0 -> { - structure = item.checkSheetStructure(model = COLUMNS) - } - - item is List<*> -> { - val name = item.getOrNull(structure.getValue(NAME)) as? String - val translate = item.getOrNull(structure.getValue(TRANSLATE)) as? String - val description = item.getOrNull(structure.getValue(DESCRIPTION)) as? String + fun parse(sheet: ValueRange): Map = parserScope { + val descriptions = hashMapOf() + sheet.forEachRow { index, row -> + when (index) { + 0 -> updateStructure(row = row, columns = COLUMNS) + else -> { + val name = row.parse(column = NAME) + val translate = row.parse(column = TRANSLATE) + val description = row.parse(column = DESCRIPTION) if (name != null && translate != null && description != null) { - values[name] = Description( + descriptions[name] = Description( name = name, original = translate, description = description, @@ -38,13 +29,13 @@ class DescriptionParser @Inject constructor() { } } - return values + return@parserScope descriptions } companion object { - private const val NAME = "Nom" - private const val TRANSLATE = "Traduction" - private const val DESCRIPTION = "Description" + private val NAME = column("Nom") + private val TRANSLATE = column("Traduction") + private val DESCRIPTION = column("Description") private val COLUMNS = listOf( NAME, diff --git a/app/src/main/java/com/pixelized/rplexicon/repository/parser/LexiconParser.kt b/app/src/main/java/com/pixelized/rplexicon/repository/parser/LexiconParser.kt index e7c3dbd..995dae2 100644 --- a/app/src/main/java/com/pixelized/rplexicon/repository/parser/LexiconParser.kt +++ b/app/src/main/java/com/pixelized/rplexicon/repository/parser/LexiconParser.kt @@ -3,8 +3,6 @@ package com.pixelized.rplexicon.repository.parser import com.google.api.services.sheets.v4.model.ValueRange import com.pixelized.rplexicon.model.Lexicon import com.pixelized.rplexicon.utilitary.exceptions.IncompatibleSheetStructure -import com.pixelized.rplexicon.utilitary.extentions.local.checkSheetStructure -import com.pixelized.rplexicon.utilitary.extentions.sheet import javax.inject.Inject class LexiconParser @Inject constructor( @@ -12,80 +10,65 @@ class LexiconParser @Inject constructor( private val genderParser: GenderParser, private val raceParser: RaceParser, ) { - @Throws(IncompatibleSheetStructure::class) - fun parse(data: ValueRange): List { - val sheet = data.values.sheet() - lateinit var sheetStructure: Map + fun parse(sheet: ValueRange): List = parserScope { var id = 0 + val lexicons = mutableListOf() - return sheet?.mapIndexedNotNull { index, row -> - when { - index == 0 -> { - sheetStructure = row.checkSheetStructure(model = COLUMNS) - null - } - - row is List<*> -> { - val name = row.getOrNull(sheetStructure.name) as? String - val diminutive = row.getOrNull(sheetStructure.diminutive) as? String - val gender = row.getOrNull(sheetStructure.gender) as? String - val race = row.getOrNull(sheetStructure.race) as? String - val portrait = row.getOrNull(sheetStructure.portrait) as? String - val status = row.getOrNull(sheetStructure.status) as? String - val location = row.getOrNull(sheetStructure.location) as? String - val description = row.getOrNull(sheetStructure.description) as? String - val history = row.getOrNull(sheetStructure.history) as? String - val tags = row.getOrNull(sheetStructure.tags) as? String + sheet.forEachRow { index, row -> + when (index) { + 0 -> updateStructure(row = row, columns = COLUMNS) + else -> { + val name = row.parse(column = NAME) if (name != null) { - Lexicon( + val lexicon = Lexicon( id = id++, sheetIndex = index, name = name, - diminutive = diminutive?.takeIf { it.isNotBlank() }, - gender = genderParser.parse(gender), - race = raceParser.parser(race), - portrait = portraitParser.parse(portrait), - status = status?.takeIf { it.isNotBlank() }, - location = location?.takeIf { it.isNotBlank() }, - description = description?.takeIf { it.isNotBlank() }, - history = history?.takeIf { it.isNotBlank() }, - tags = tags?.takeIf { it.isNotBlank() }, + diminutive = row.parse(column = SHORT), + gender = genderParser.parse(row.parse(column = GENDER)), + race = raceParser.parser(row.parse(column = RACE)), + status = row.parse(column = STATUS), + location = row.parse(column = LOCATION), + portrait = portraitParser.parse(row.parse(column = PORTRAIT)), + description = row.parse(column = DESCRIPTION), + history = row.parse(column = HISTORY), + tags = row.parse(column = TAGS), ) - } else { - null + lexicons.add(lexicon) } } - - else -> null } - } ?: emptyList() - } + } - private val Map.name: Int get() = getValue(COLUMNS[0]) - private val Map.diminutive: Int get() = getValue(COLUMNS[1]) - private val Map.gender: Int get() = getValue(COLUMNS[2]) - private val Map.race: Int get() = getValue(COLUMNS[3]) - private val Map.status: Int get() = getValue(COLUMNS[4]) - private val Map.location: Int get() = getValue(COLUMNS[5]) - private val Map.portrait: Int get() = getValue(COLUMNS[6]) - private val Map.description: Int get() = getValue(COLUMNS[7]) - private val Map.history: Int get() = getValue(COLUMNS[8]) - private val Map.tags: Int get() = getValue(COLUMNS[9]) + return@parserScope lexicons + } companion object { - private val COLUMNS = listOf( - "Nom", - "Diminutif", - "Sexe", - "Race", - "Statut", - "Localisation", - "Portrait", - "Description", - "Histoire", - "Mots clés", - ) + private val NAME = column("Nom") + private val SHORT = column("Diminutif") + private val GENDER = column("Sexe") + private val RACE = column("Race") + private val STATUS = column("Statut") + private val LOCATION = column("Localisation") + private val PORTRAIT = column("Portrait") + private val DESCRIPTION = column("Description") + private val HISTORY = column("Histoire") + private val TAGS = column("Mots clés") + + private val COLUMNS + get() = listOf( + NAME, + SHORT, + GENDER, + RACE, + STATUS, + LOCATION, + PORTRAIT, + DESCRIPTION, + HISTORY, + TAGS, + ) } } \ No newline at end of file diff --git a/app/src/main/java/com/pixelized/rplexicon/repository/parser/LocationParser.kt b/app/src/main/java/com/pixelized/rplexicon/repository/parser/LocationParser.kt index 2536c1b..44b9a0e 100644 --- a/app/src/main/java/com/pixelized/rplexicon/repository/parser/LocationParser.kt +++ b/app/src/main/java/com/pixelized/rplexicon/repository/parser/LocationParser.kt @@ -1,55 +1,43 @@ package com.pixelized.rplexicon.repository.parser -import android.net.Uri import com.google.api.services.sheets.v4.model.ValueRange import com.pixelized.rplexicon.model.Location import com.pixelized.rplexicon.utilitary.exceptions.IncompatibleSheetStructure -import com.pixelized.rplexicon.utilitary.extentions.local.checkSheetStructure -import com.pixelized.rplexicon.utilitary.extentions.sheet import javax.inject.Inject class LocationParser @Inject constructor() { @Throws(IncompatibleSheetStructure::class) - fun parse(data: ValueRange): List { + fun parse(sheet: ValueRange): List = parserScope { + val locations = mutableListOf() var id = 0 - var sheetStructure: Map? = null - - return data.values.sheet()?.mapIndexedNotNull { index, item -> - when { - index == 0 -> { - sheetStructure = item.checkSheetStructure(COLUMNS) - null - } - - item is List<*> -> { - val name = item.getOrNull(sheetStructure.name) as? String - val uri = item.getOrNull(sheetStructure.uri)?.toString()?.let { Uri.parse(it) } + sheet.forEachRow { index, row -> + when (index) { + 0 -> updateStructure(row = row, columns = COLUMNS) + else -> { + val name = row.parse(column = NAME) + val uri = row.parseUri(column = MAP) if (name != null && uri != null) { - Location( + val location = Location( id = id++, sheetIndex = index, name = name, uri = uri, marquees = emptyList(), ) - } else { - null + locations.add(location) } } - - else -> null } - } ?: emptyList() - } + } - private val Map?.name: Int get() = this?.getValue(COLUMNS[0]) ?: 0 - private val Map?.uri: Int get() = this?.getValue(COLUMNS[1]) ?: 1 + return@parserScope locations + } companion object { - private val COLUMNS = listOf( - "Nom", "Carte" - ) + private val NAME = column("Nom") + private val MAP = column("Carte") + private val COLUMNS get() = listOf(NAME, MAP) } } \ No newline at end of file diff --git a/app/src/main/java/com/pixelized/rplexicon/repository/parser/MarqueeParser.kt b/app/src/main/java/com/pixelized/rplexicon/repository/parser/MarqueeParser.kt index 5ca6290..509a5a1 100644 --- a/app/src/main/java/com/pixelized/rplexicon/repository/parser/MarqueeParser.kt +++ b/app/src/main/java/com/pixelized/rplexicon/repository/parser/MarqueeParser.kt @@ -3,63 +3,52 @@ package com.pixelized.rplexicon.repository.parser import androidx.compose.ui.geometry.Offset import com.google.api.services.sheets.v4.model.ValueRange import com.pixelized.rplexicon.model.Location -import com.pixelized.rplexicon.utilitary.extentions.local.checkSheetStructure -import com.pixelized.rplexicon.utilitary.extentions.sheet +import com.pixelized.rplexicon.utilitary.exceptions.IncompatibleSheetStructure import javax.inject.Inject class MarqueeParser @Inject constructor() { - fun parse(data: ValueRange): List { - val sheet = data.values.sheet() - lateinit var structure: Map + @Throws(IncompatibleSheetStructure::class) + fun parse(sheet: ValueRange): List = parserScope { + val marquees = mutableListOf() - return sheet?.mapIndexedNotNull { index, item -> - when { - index == 0 -> { - structure = item.checkSheetStructure(model = COLUMNS) - null - } + sheet.forEachRow { index, item -> + when (index) { + 0 -> updateStructure(row = item, columns = COLUMNS) - item is List<*> -> { - val map = item.getOrNull(structure.map) as? String - val name = item.getOrNull(structure.name) as? String? - val x = (item.getOrNull(structure.x) as? String) + else -> { + val map = item.parse(column = MAP) + val x = item.parse(column = X) ?.replace(oldValue = ",", newValue = ".") ?.toFloatOrNull() - val y = (item.getOrNull(structure.y) as? String) + val y = item.parse(column = Y) ?.replace(oldValue = ",", newValue = ".") ?.toFloatOrNull() - val description = item.getOrNull(structure.description) as? String? - if (map != null) { - Location.Marquee( + val marquee = Location.Marquee( map = map, - name = name?.takeIf { it.isNotBlank() }, + name = item.parse(column = NAME), position = when { x != null && y != null -> Offset(x, y) else -> Offset.Unspecified }, - description = description?.takeIf { it.isNotBlank() }, + description = item.parse(column = DESCRIPTION), ) - } else { - null + marquees.add(marquee) } } - - else -> null } - } ?: emptyList() - } + } - private val Map.map: Int get() = getValue(COLUMNS[0]) - private val Map.name: Int get() = getValue(COLUMNS[1]) - private val Map.x: Int get() = getValue(COLUMNS[2]) - private val Map.y: Int get() = getValue(COLUMNS[3]) - private val Map.description: Int get() = getValue(COLUMNS[4]) + return@parserScope marquees + } companion object { - private val COLUMNS = listOf( - "Carte", "Nom", "X", "Y", "Description" - ) + private val MAP = column("Carte") + private val NAME = column("Nom") + private val X = column("X") + private val Y = column("Y") + private val DESCRIPTION = column("Description") + private val COLUMNS get() = listOf(MAP, NAME, X, Y, DESCRIPTION) } } \ No newline at end of file diff --git a/app/src/main/java/com/pixelized/rplexicon/repository/parser/ObjectActionParser.kt b/app/src/main/java/com/pixelized/rplexicon/repository/parser/ObjectActionParser.kt index b514acb..0ee7264 100644 --- a/app/src/main/java/com/pixelized/rplexicon/repository/parser/ObjectActionParser.kt +++ b/app/src/main/java/com/pixelized/rplexicon/repository/parser/ObjectActionParser.kt @@ -36,8 +36,8 @@ class ObjectActionParser @Inject constructor( } companion object { - private const val NAME = "Nom" - private const val EFFECT = "Effet" + private val NAME = column("Nom") + private val EFFECT = column("Effet") private val COLUMNS = listOf(NAME, EFFECT) } } \ No newline at end of file diff --git a/app/src/main/java/com/pixelized/rplexicon/repository/parser/QuestParser.kt b/app/src/main/java/com/pixelized/rplexicon/repository/parser/QuestParser.kt index e65dc7c..def793f 100644 --- a/app/src/main/java/com/pixelized/rplexicon/repository/parser/QuestParser.kt +++ b/app/src/main/java/com/pixelized/rplexicon/repository/parser/QuestParser.kt @@ -8,28 +8,28 @@ import javax.inject.Inject class QuestParser @Inject constructor( private val imageParser: PortraitParser ) { - fun parse(value: ValueRange): List = parserScope { + fun parse(sheet: ValueRange): List = parserScope { val quest = mutableListOf() - value.forEachRow { index, item -> + sheet.forEachRow { index, item -> when (index) { 0 -> updateStructure(row = item, columns = COLUMNS) else -> { - val title = item.parse(TITLE) - val description = item.parse(DESCRIPTION) + val title = item.parse(column = TITLE) + val description = item.parse(column = DESCRIPTION) if (title?.isNotEmpty() == true && description?.isNotEmpty() == true) { val entry = QuestEntry( sheetIndex = index, title = title, - subtitle = item.parse(SUB_TITLE), - complete = item.parseBool(COMPLETED) ?: false, - questGiver = item.parse(QUEST_GIVER), - area = item.parse(AREA), - groupReward = item.parse(GROUP_REWARD), - individualReward = item.parse(INDIVIDUAL_REWARD), + subtitle = item.parse(column = SUB_TITLE), + complete = item.parseBool(column = COMPLETED) ?: false, + questGiver = item.parse(column = QUEST_GIVER), + area = item.parse(column = AREA), + groupReward = item.parse(column = GROUP_REWARD), + individualReward = item.parse(column = INDIVIDUAL_REWARD), description = description, - images = imageParser.parse(item.parse(IMAGE)), - background = item.parseUri(BACKGROUND), + images = imageParser.parse(item.parse(column = IMAGE)), + background = item.parseUri(column = BACKGROUND), ) quest.add(entry) } @@ -37,32 +37,33 @@ class QuestParser @Inject constructor( } } - quest + return@parserScope quest } companion object { - private const val TITLE = "Titre" - private const val SUB_TITLE = "Sous Titre" - private const val COMPLETED = "Compléter" - private const val QUEST_GIVER = "Commanditaire" - private const val AREA = "Lieu" - private const val GROUP_REWARD = "Récompense de groupe" - private const val INDIVIDUAL_REWARD = "Récompense individuelle" - private const val DESCRIPTION = "Description" - private const val IMAGE = "Image" - private const val BACKGROUND = "fond" // TODO + private val TITLE = column("Titre") + private val SUB_TITLE = column("Sous Titre") + private val COMPLETED = column("Compléter") + private val QUEST_GIVER = column("Commanditaire") + private val AREA = column("Lieu") + private val GROUP_REWARD = column("Récompense de groupe") + private val INDIVIDUAL_REWARD = column("Récompense individuelle") + private val DESCRIPTION = column("Description") + private val IMAGE = column("Image") + private val BACKGROUND = column("fond", "Fond") // TODO remove "fond" after 0.7.0 release - private val COLUMNS = listOf( - TITLE, - SUB_TITLE, - COMPLETED, - QUEST_GIVER, - AREA, - GROUP_REWARD, - INDIVIDUAL_REWARD, - DESCRIPTION, - IMAGE, - BACKGROUND, - ) + private val COLUMNS + get() = listOf( + TITLE, + SUB_TITLE, + COMPLETED, + QUEST_GIVER, + AREA, + GROUP_REWARD, + INDIVIDUAL_REWARD, + DESCRIPTION, + IMAGE, + BACKGROUND, + ) } } \ No newline at end of file diff --git a/app/src/main/java/com/pixelized/rplexicon/repository/parser/SheetParserScope.kt b/app/src/main/java/com/pixelized/rplexicon/repository/parser/SheetParserScope.kt index 55230f3..97dc69a 100644 --- a/app/src/main/java/com/pixelized/rplexicon/repository/parser/SheetParserScope.kt +++ b/app/src/main/java/com/pixelized/rplexicon/repository/parser/SheetParserScope.kt @@ -13,9 +13,9 @@ inline fun parserScope( } class SheetParserScope { - private var structure: Map = hashMapOf() + private var structure: Map = hashMapOf() - fun updateStructure(row: Any, columns: List) { + fun updateStructure(row: Any, columns: List) { structure = row.checkSheetStructure(model = columns) } @@ -31,15 +31,15 @@ class SheetParserScope { fun Any?.toItem(): String? = this.toString().takeIf { it.isNotBlank() } - fun List<*>.parse(column: String): String? = + fun List<*>.parse(column: Column): String? = getOrNull(structure.getValue(column))?.toItem() - fun List<*>.parseInt(column: String): Int? = + fun List<*>.parseInt(column: Column): Int? = parse(column)?.toIntOrNull() - fun List<*>.parseBool(column: String): Boolean? = + fun List<*>.parseBool(column: Column): Boolean? = parse(column)?.equals("TRUE", ignoreCase = true) - fun List<*>.parseUri(column: String): Uri? = + fun List<*>.parseUri(column: Column): Uri? = parse(column)?.takeIf { it.isNotBlank() }?.toUri() } \ No newline at end of file diff --git a/app/src/main/java/com/pixelized/rplexicon/repository/parser/SkillParser.kt b/app/src/main/java/com/pixelized/rplexicon/repository/parser/SkillParser.kt index 9e37c90..89b0915 100644 --- a/app/src/main/java/com/pixelized/rplexicon/repository/parser/SkillParser.kt +++ b/app/src/main/java/com/pixelized/rplexicon/repository/parser/SkillParser.kt @@ -3,30 +3,19 @@ package com.pixelized.rplexicon.repository.parser import com.google.api.services.sheets.v4.model.ValueRange import com.pixelized.rplexicon.model.Skill import com.pixelized.rplexicon.utilitary.exceptions.IncompatibleSheetStructure -import com.pixelized.rplexicon.utilitary.extentions.local.checkSheetStructure -import com.pixelized.rplexicon.utilitary.extentions.sheet import javax.inject.Inject class SkillParser @Inject constructor( private val throwParser: ThrowParser, ) { - @Throws(IncompatibleSheetStructure::class) - fun parse(data: ValueRange): Map> { - val sheet = data.values.sheet() - val values = hashMapOf>() + fun parse(sheet: ValueRange): Map> = parserScope { + val skills = hashMapOf>() - lateinit var sheetStructure: Map - fun List<*>.parse(column: String): String? = - (getOrNull(sheetStructure.getValue(column)) as? String)?.takeIf { it.isNotBlank() } - - sheet?.forEachIndexed { index, row -> - when { - index == 0 -> { - sheetStructure = row.checkSheetStructure(model = COLUMNS) - } - - row is List<*> -> { + sheet.forEachRow { index, row -> + when (index) { + 0 -> updateStructure(row = row, columns = COLUMNS) + else -> { val character = row[0] as? String val name = row.parse(column = NAME) if (character?.isNotBlank() == true && name != null) { @@ -37,28 +26,22 @@ class SkillParser @Inject constructor( cost = row.parse(column = COST), effect = throwParser.parse(row.parse(column = EFFECT)), ) - values.getOrPut(character) { mutableListOf() }.add(skill) + skills.getOrPut(character) { mutableListOf() }.add(skill) } } } } - return values + return@parserScope skills } companion object { - private const val NAME = "Nom" - private const val AMOUNT = "Quantité" - private const val REST = "Récupération" - private const val COST = "Coût" - private const val EFFECT = "Effect" + private val NAME = column("Nom") + private val AMOUNT = column("Quantité") + private val REST = column("Récupération") + private val COST = column("Coût") + private val EFFECT = column("Effect") - private val COLUMNS = listOf( - NAME, - AMOUNT, - REST, - COST, - EFFECT, - ) + private val COLUMNS get() = listOf(NAME, AMOUNT, REST, COST, EFFECT) } } \ No newline at end of file diff --git a/app/src/main/java/com/pixelized/rplexicon/repository/parser/alteration/AlterationParser.kt b/app/src/main/java/com/pixelized/rplexicon/repository/parser/alteration/AlterationParser.kt index d230a1d..afa2073 100644 --- a/app/src/main/java/com/pixelized/rplexicon/repository/parser/alteration/AlterationParser.kt +++ b/app/src/main/java/com/pixelized/rplexicon/repository/parser/alteration/AlterationParser.kt @@ -4,11 +4,11 @@ import com.google.api.services.sheets.v4.model.ValueRange import com.pixelized.rplexicon.model.Alteration import com.pixelized.rplexicon.model.CharacterSheet import com.pixelized.rplexicon.model.Property +import com.pixelized.rplexicon.repository.parser.column +import com.pixelized.rplexicon.repository.parser.parserScope import com.pixelized.rplexicon.repository.parser.roll.DiceParser import com.pixelized.rplexicon.repository.parser.roll.FlatValueParser import com.pixelized.rplexicon.utilitary.exceptions.IncompatibleSheetStructure -import com.pixelized.rplexicon.utilitary.extentions.local.checkSheetStructure -import com.pixelized.rplexicon.utilitary.extentions.sheet import javax.inject.Inject class AlterationParser @Inject constructor( @@ -16,30 +16,22 @@ class AlterationParser @Inject constructor( private val flatParser: FlatValueParser, ) { @Throws(IncompatibleSheetStructure::class) - fun parse(values: ValueRange, sheets: List): Map> { - val sheet = values.values.sheet() - + fun parse( + sheet: ValueRange, + characterSheets: List, + ): Map> = parserScope { val properties = Property.values() - val data = hashMapOf>() + val alterations = hashMapOf>() - lateinit var alterationStructure: Map - lateinit var charactersStructure: Map + sheet.forEachRow { index, row -> + when (index) { + 0 -> updateStructure(row = row, columns = COLUMNS + characterSheets.map { column(it.name) }) - fun List<*>.parseString(key: String): String? = - (getOrNull(alterationStructure.getValue(key)) as? String)?.takeIf { it.isNotEmpty() } - - sheet?.forEachIndexed { index, row -> - when { - index == 0 -> { - alterationStructure = row.checkSheetStructure(model = COLUMNS) - charactersStructure = row.checkSheetStructure(model = sheets.map { it.name }) - } - - row is List<*> -> { + else -> { // Assume that the name is the first column. val name = row.getOrNull(0) as? String - val source = row.parseString(SOURCE) - val target = row.parseString(TARGET) + val source = row.parse(column = SOURCE) + val target = row.parse(column = TARGET) val alteration = if (name != null && source != null && target != null) { Alteration( name = name, @@ -48,8 +40,7 @@ class AlterationParser @Inject constructor( active = false, status = properties .mapNotNull { property -> - val column = alterationStructure.getValue(property.key) - val value = row.getOrNull(column) as? String + val value = row.parse(column = column(property.key)) if (value?.isNotEmpty() == true) { property to parseAlterationStatus(name, value) } else { @@ -62,26 +53,26 @@ class AlterationParser @Inject constructor( null } if (alteration != null) { - sheets + characterSheets .filter { // check if the alteration is applicable to the character alteration.target.let { target -> target == ALL || target == it.characterClass || target == it.race || target == it.name } } .forEach { // check the default alteration state for that character - val column = charactersStructure.getValue(it.name) - val default = (row.getOrNull(column) as? String)?.toBoolean() + val default = row.parseBool(column = column(it.name)) val assignedAlteration = alteration.copy( active = default ?: false ) - data.getOrPut(it.name) { mutableListOf() }.add(assignedAlteration) + alterations.getOrPut(it.name) { mutableListOf() } + .add(assignedAlteration) } } } } } - return data + return@parserScope alterations } private fun parseAlterationStatus(name: String, value: String): Alteration.Status = @@ -125,9 +116,9 @@ class AlterationParser @Inject constructor( private const val DISADVANTAGE = "dis" private const val FAIL = "fail" - private const val TARGET = "Cible" - private const val SOURCE = "Source" + private val TARGET = column("Cible") + private val SOURCE = column("Source") private val COLUMNS - get() = listOf(SOURCE, TARGET) + Property.values().map { it.key } + get() = listOf(SOURCE, TARGET) + Property.values().map { column(it.key) } } } \ No newline at end of file diff --git a/app/src/main/java/com/pixelized/rplexicon/repository/parser/alteration/AssignedAlterationParser.kt b/app/src/main/java/com/pixelized/rplexicon/repository/parser/alteration/AssignedAlterationParser.kt index fa08c54..9d2012e 100644 --- a/app/src/main/java/com/pixelized/rplexicon/repository/parser/alteration/AssignedAlterationParser.kt +++ b/app/src/main/java/com/pixelized/rplexicon/repository/parser/alteration/AssignedAlterationParser.kt @@ -1,33 +1,28 @@ package com.pixelized.rplexicon.repository.parser.alteration import com.google.api.services.sheets.v4.model.ValueRange +import com.pixelized.rplexicon.repository.parser.column +import com.pixelized.rplexicon.repository.parser.parserScope import com.pixelized.rplexicon.utilitary.exceptions.IncompatibleSheetStructure -import com.pixelized.rplexicon.utilitary.extentions.local.checkSheetStructure -import com.pixelized.rplexicon.utilitary.extentions.sheet import javax.inject.Inject class AssignedAlterationParser @Inject constructor() { @Throws(IncompatibleSheetStructure::class) - fun parse(value: ValueRange, characters: List): Map> { - val sheet = value.values.sheet() - + fun parse( + sheet: ValueRange, + characterNames: List + ): Map> = parserScope { val status = hashMapOf>() - lateinit var structure: Map - sheet?.mapNotNull { it as? List<*> }?.forEachIndexed { index, row -> + sheet.forEachRow { index, row -> when (index) { - 0 -> { - structure = row.checkSheetStructure(model = characters) - } - + 0 -> updateStructure(row = row, columns = characterNames.map { column(it) }) else -> { val alteration = row.getOrNull(0)?.toString() - if (alteration != null) { - characters.forEach { character -> - val value = row.getOrNull(structure.getValue(character)) - if (value == TRUE) { + characterNames.forEach { character -> + if (row.parseBool(column = column(character)) == true) { status .getOrPut(character) { mutableListOf() } .add(alteration) @@ -38,10 +33,6 @@ class AssignedAlterationParser @Inject constructor() { } } - return status - } - - companion object { - private const val TRUE = "TRUE" + return@parserScope status } } \ No newline at end of file diff --git a/app/src/main/java/com/pixelized/rplexicon/repository/parser/inventory/InventoryParser.kt b/app/src/main/java/com/pixelized/rplexicon/repository/parser/inventory/InventoryParser.kt index ef1ef6f..93fa004 100644 --- a/app/src/main/java/com/pixelized/rplexicon/repository/parser/inventory/InventoryParser.kt +++ b/app/src/main/java/com/pixelized/rplexicon/repository/parser/inventory/InventoryParser.kt @@ -2,6 +2,7 @@ package com.pixelized.rplexicon.repository.parser.inventory import com.google.api.services.sheets.v4.model.ValueRange import com.pixelized.rplexicon.model.Inventory +import com.pixelized.rplexicon.repository.parser.column import com.pixelized.rplexicon.repository.parser.parserScope import com.pixelized.rplexicon.utilitary.exceptions.IncompatibleSheetStructure import javax.inject.Inject @@ -9,10 +10,10 @@ import javax.inject.Inject class InventoryParser @Inject constructor() { @Throws(IncompatibleSheetStructure::class) - fun parse(data: ValueRange): Map = parserScope { + fun parse(sheet: ValueRange): Map = parserScope { val inventories = hashMapOf() - data.forEachRow { index, row -> + sheet.forEachRow { index, row -> when { index == 0 -> updateStructure(row = row, columns = COLUMNS) @@ -46,9 +47,9 @@ class InventoryParser @Inject constructor() { } companion object { - private const val CONTAINER = "Contenant" - private const val NAME = "Name" - private const val AMOUNT = "Quantité" + private val CONTAINER = column("Contenant") + private val NAME = column("Name") + private val AMOUNT = column("Quantité") private val COLUMNS = listOf(CONTAINER, NAME, AMOUNT) } } \ No newline at end of file diff --git a/app/src/main/java/com/pixelized/rplexicon/repository/parser/spell/AssignedSpellParser.kt b/app/src/main/java/com/pixelized/rplexicon/repository/parser/spell/AssignedSpellParser.kt index 25ffdbe..9c36af0 100644 --- a/app/src/main/java/com/pixelized/rplexicon/repository/parser/spell/AssignedSpellParser.kt +++ b/app/src/main/java/com/pixelized/rplexicon/repository/parser/spell/AssignedSpellParser.kt @@ -1,35 +1,28 @@ package com.pixelized.rplexicon.repository.parser.spell import com.google.api.services.sheets.v4.model.ValueRange -import com.pixelized.rplexicon.repository.parser.ThrowParser import com.pixelized.rplexicon.model.AssignedSpell import com.pixelized.rplexicon.model.Spell +import com.pixelized.rplexicon.repository.parser.ThrowParser +import com.pixelized.rplexicon.repository.parser.column +import com.pixelized.rplexicon.repository.parser.parserScope import com.pixelized.rplexicon.utilitary.exceptions.IncompatibleSheetStructure -import com.pixelized.rplexicon.utilitary.extentions.local.checkSheetStructure -import com.pixelized.rplexicon.utilitary.extentions.sheet import javax.inject.Inject class AssignedSpellParser @Inject constructor( private val throwParser: ThrowParser, ) { @Throws(IncompatibleSheetStructure::class) - fun parse(data: ValueRange, spells: List): Map> { - val sheet = data.values.sheet() + fun parse( + sheet: ValueRange, + spells: List, + ): Map> = parserScope { val spellsBook = spells.associateBy { it.name } - lateinit var structure: Map val assignedSpells = hashMapOf>() - - // declare helper method to parse String - fun List<*>.parse(key: String): String? = - (getOrNull(structure.getValue(key)) as? String)?.takeIf { it.isNotEmpty() } - - sheet?.forEachIndexed { index, row -> - when { - index == 0 -> { - structure = row.checkSheetStructure(model = COLUMNS) - } - - row is List<*> -> { + sheet.forEachRow { index, row -> + when (index) { + 0 -> updateStructure(row = row, columns = COLUMNS) + else -> { val character = row.getOrNull(0) as? String val spell = spellsBook[row.parse(NAME)] if (character != null && spell != null) { @@ -46,22 +39,15 @@ class AssignedSpellParser @Inject constructor( } } } - - return assignedSpells + return@parserScope assignedSpells } companion object { - private const val NAME = "Nom" - private const val HIT = "Touché" - private const val EFFECT = "Effet" - private const val LEVEL = "Par niveau" + private val NAME = column("Nom") + private val HIT = column("Touché") + private val EFFECT = column("Effet") + private val LEVEL = column("Par niveau") - private val COLUMNS - get() = listOf( - NAME, - HIT, - EFFECT, - LEVEL, - ) + private val COLUMNS get() = listOf(NAME, HIT, EFFECT, LEVEL) } } \ No newline at end of file diff --git a/app/src/main/java/com/pixelized/rplexicon/repository/parser/spell/SpellBookParser.kt b/app/src/main/java/com/pixelized/rplexicon/repository/parser/spell/SpellBookParser.kt index e9851cd..1649e3d 100644 --- a/app/src/main/java/com/pixelized/rplexicon/repository/parser/spell/SpellBookParser.kt +++ b/app/src/main/java/com/pixelized/rplexicon/repository/parser/spell/SpellBookParser.kt @@ -3,40 +3,27 @@ package com.pixelized.rplexicon.repository.parser.spell import android.util.Log import com.google.api.services.sheets.v4.model.ValueRange import com.pixelized.rplexicon.model.Spell +import com.pixelized.rplexicon.repository.parser.column +import com.pixelized.rplexicon.repository.parser.parserScope import com.pixelized.rplexicon.utilitary.exceptions.IncompatibleSheetStructure -import com.pixelized.rplexicon.utilitary.extentions.local.checkSheetStructure -import com.pixelized.rplexicon.utilitary.extentions.sheet import javax.inject.Inject class SpellBookParser @Inject constructor() { @Throws(IncompatibleSheetStructure::class) - fun parse(data: ValueRange): List { - - val sheet = data.values.sheet() - - lateinit var structure: Map - - // declare helper method to parse String - fun List<*>.parse(key: String): String? = - (getOrNull(structure.getValue(key)) as? String)?.takeIf { it.isNotEmpty() } - - return sheet?.mapIndexedNotNull { index, row -> + fun parse(sheet: ValueRange): List = parserScope { + val spells = mutableListOf() + sheet.forEachRow { index, row -> when { - index == 0 -> { - structure = row.checkSheetStructure(model = COLUMNS) - null - } - - row is List<*> -> { - val name = row.parse(NAME) - val level = row.parse(LEVEL)?.toIntOrNull() - val school = parseSchool(row.parse(SCHOOL)) - val castingTime = row.parse(CASTING_TIME) - val range = row.parse(RANGE) - val requirement = row.parse(REQUIREMENT) - val duration = row.parse(DURATION) - val ritual = row.parse(RITUAL)?.toBoolean() ?: false + index == 0 -> updateStructure(row = row, columns = COLUMNS) + else -> { + val name = row.parse(column = NAME) + val level = row.parseInt(column = LEVEL) + val school = parseSchool(row.parse(column = SCHOOL)) + val castingTime = row.parse(column = CASTING_TIME) + val range = row.parse(column = RANGE) + val requirement = row.parse(column = REQUIREMENT) + val duration = row.parse(column = DURATION) if (name != null && level != null && school != null @@ -45,7 +32,7 @@ class SpellBookParser @Inject constructor() { && requirement != null && duration != null ) { - Spell( + val spell = Spell( name = name, level = level, school = school, @@ -53,16 +40,14 @@ class SpellBookParser @Inject constructor() { range = range, requirement = requirement, duration = duration, - ritual = ritual, + ritual = row.parseBool(column = RITUAL) ?: false, ) - } else { - null + spells.add(spell) } } - - else -> null } - } ?: emptyList() + } + return@parserScope spells } private fun parseSchool(value: String?): Spell.School? = try { @@ -73,25 +58,16 @@ class SpellBookParser @Inject constructor() { } companion object { - private const val NAME = "Nom" - private const val SCHOOL = "École" - private const val LEVEL = "Niveau" - private const val CASTING_TIME = "Temps d'incantation" - private const val RANGE = "Portée" - private const val REQUIREMENT = "Composantes" - private const val DURATION = "Durée" - private const val RITUAL = "Rituel" + private val NAME = column("Nom") + private val SCHOOL = column("École") + private val LEVEL = column("Niveau") + private val CASTING_TIME = column("Temps d'incantation") + private val RANGE = column("Portée") + private val REQUIREMENT = column("Composantes") + private val DURATION = column("Durée") + private val RITUAL = column("Rituel") private val COLUMNS - get() = listOf( - NAME, - LEVEL, - SCHOOL, - CASTING_TIME, - RANGE, - REQUIREMENT, - DURATION, - RITUAL, - ) + get() = listOf(NAME, LEVEL, SCHOOL, CASTING_TIME, RANGE, REQUIREMENT, DURATION, RITUAL) } } \ No newline at end of file diff --git a/app/src/main/java/com/pixelized/rplexicon/utilitary/extentions/local/SheetEx.kt b/app/src/main/java/com/pixelized/rplexicon/utilitary/extentions/local/SheetEx.kt index 8c10979..39f87e1 100644 --- a/app/src/main/java/com/pixelized/rplexicon/utilitary/extentions/local/SheetEx.kt +++ b/app/src/main/java/com/pixelized/rplexicon/utilitary/extentions/local/SheetEx.kt @@ -1,30 +1,27 @@ package com.pixelized.rplexicon.utilitary.extentions.local +import com.pixelized.rplexicon.repository.parser.Column import com.pixelized.rplexicon.utilitary.exceptions.IncompatibleSheetStructure @Throws(IncompatibleSheetStructure::class) -fun Any?.checkSheetStructure(model: List): HashMap { +fun Any?.checkSheetStructure(model: List): Map { // check if the row is a list if (this !is ArrayList<*>) { throw IncompatibleSheetStructure("First row is not a List: $this") } // parse the first line to find element that we recognize. - val sheetStructure = hashMapOf() - forEachIndexed { index, cell -> - if (cell is String && model.contains(cell)) { - sheetStructure[cell] = index + val sheetStructure = model.associateWith { key -> + indexOfFirst { cell -> + key.names.contains(cell) } } // check if we found everything we need. when { - sheetStructure.size < model.size -> throw IncompatibleSheetStructure( - message = "Sheet header row does not have enough column: $size.\nstructure: $this\nheader: $sheetStructure" - ) - - sheetStructure.size > model.size -> throw IncompatibleSheetStructure( - message = "Sheet header row does have too mush columns: $size.\nstructure: $this\nheader: $sheetStructure" + sheetStructure.any { it.value < 0 } -> throw IncompatibleSheetStructure( + message = "Sheet header row does not have enough column !" + sheetStructure + .filter { it.value < 0 }.keys + .joinToString(prefix = "\n- Missing column: ") { it.toString() } ) } - return sheetStructure } \ No newline at end of file