Bazel structure and bin to convert HallOfBeorn dump to CSV for ALEP pipeline

This commit is contained in:
Christian Nieves committed 2023-07-19 00:38:38 -05:00
commit 0359a73df0
20 files changed
+615

No files matched your search

+26
View File
@@ -0,0 +1,26 @@
load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
package(
default_visibility = ["//visibility:public"],
)
go_library(
name = "beornextract_lib",
srcs = ["main.go"],
data = [
"//cmd/beornextract/data:Bot.Cards.json",
"//cmd/beornextract/data:Export.Cards.json",
],
importpath = "github.com/squk/lotr/cmd/beornextract",
deps = [
"//cmd/beornextract/types",
"@com_github_grokify_html_strip_tags_go//:html-strip-tags-go",
"@com_github_jessevdk_go_flags//:go_default_library",
"@io_bazel_rules_go//go/tools/bazel:go_default_library",
],
)
go_binary(
name = "beornextract",
embed = [":beornextract_lib"],
)
+2
View File
@@ -0,0 +1,2 @@
exports_files(glob(["*.json"]))
# exports_files(["Export.Cards.json"])
+1
View File
@@ -0,0 +1 @@
[{"pack_code":"Core","pack_name":"Core Set","is_official":true,"type_code":"hero","type_name":"Hero","sphere_code":"leadership","sphere_name":"Leadership","position":1,"code":"01001","name":"Aragorn","traits":"Dúnedain. Noble. Ranger.","keywords":"Sentinel.","text":"Sentinel.<b>Response:</b> After Aragorn commits to a quest, spend 1 resource from his resource pool to ready him.\n","flavor":"\"I am Aragorn son of Arathorn; and if by life or death I can save you, I will.\"\r\n-The Fellowship of the Ring","is_unique":true,"threat":12,"willpower":2,"attack":3,"defense":2,"health":5,"quantity":1,"deck_limit":1,"illustrator":"John Stanko","octgnid":"51223bd0-ffd1-11df-a976-0801200c9001","has_errata":false,"url":"https://hallofbeorn.com/LotR/Details/Aragorn-Core","imagesrc":"https://s3.amazonaws.com/hallofbeorn-resources/Images/Cards/Core-Set/Aragorn.jpg","versions":[{"set_name":"Core Set","year":"2011","url":"https://hallofbeorn.com/LotR/Details/Aragorn-Core"},{"set_name":"The Old Forest","year":"2014","url":"https://hallofbeorn.com/LotR/Details/Aragorn-TOF"},{"set_name":"Fog on the Barrow-downs","year":"2015","url":"https://hallofbeorn.com/LotR/Details/Aragorn-FotBD"},{"set_name":"Two-Player Limited Edition Starter","year":"2018","url":"https://hallofbeorn.com/LotR/Details/Aragorn-TPLES"},{"set_name":"Revised Core Set","year":"2022","url":"https://hallofbeorn.com/LotR/Details/Aragorn-RevCore"}]},{"pack_code":"Core","pack_name":"Core Set","is_official":true,"type_code":"hero","type_name":"Hero","sphere_code":"leadership","sphere_name":"Leadership","position":2,"code":"01002","name":"Théodred","traits":"Noble. Rohan. Warrior.","text":"<b>Response:</b> After Théodred commits to a quest, choose a hero committed to that quest. Add 1 resource to that hero's resource pool.","flavor":"\"Not all is dark. Take courage, Lord of the Mark...\"\r\n-Gandalf, The Two Towers","is_unique":true,"threat":8,"willpower":1,"attack":2,"defense":1,"health":4,"quantity":1,"deck_limit":1,"illustrator":"Jeff Himmelman","octgnid":"51223bd0-ffd1-11df-a976-0801200c9002","has_errata":false,"url":"https://hallofbeorn.com/LotR/Details/Theodred-Core","imagesrc":"https://s3.amazonaws.com/hallofbeorn-resources/Images/Cards/Core-Set/Theodred.jpg","versions":[{"set_name":"Core Set","year":"2011","url":"https://hallofbeorn.com/LotR/Details/Theodred-Core"},{"set_name":"Revised Core Set","year":"2022","url":"https://hallofbeorn.com/LotR/Details/Theodred-RevCore"}]},{"pack_code":"Core","pack_name":"Core Set","is_official":true,"type_code":"hero","type_name":"Hero","sphere_code":"leadership","sphere_name":"Leadership","position":3,"code":"01003","name":"Glóin","traits":"Dwarf. Noble.","text":"<b>Response:</b> After Glóin suffers damage, add 1 resource to his resource pool for each point of damage he just suffered.\n","flavor":"His beard, very long and forked, was white, nearly as white as the snow-white cloth of his garments.\r\n-The Fellowship of the Ring","is_unique":true,"threat":9,"willpower":2,"attack":2,"defense":1,"health":4,"quantity":1,"deck_limit":1,"illustrator":"Tom Garden","octgnid":"51223bd0-ffd1-11df-a976-0801200c9003","has_errata":false,"url":"https://hallofbeorn.com/LotR/Details/Gloin-Core","imagesrc":"https://s3.amazonaws.com/hallofbeorn-resources/Images/Cards/Core-Set/Gloin.jpg","versions":[{"set_name":"Core Set","year":"2011","url":"https://hallofbeorn.com/LotR/Details/Gloin-Core"},{"set_name":"Revised Core Set","year":"2022","url":"https://hallofbeorn.com/LotR/Details/Gloin-RevCore"}]},{"pack_code":"Core","pack_name":"Core Set","is_official":true,"type_code":"hero","type_name":"Hero","sphere_code":"tactics","sphere_name":"Tactics","position":4,"code":"01004","name":"Gimli","traits":"Dwarf. Noble. Warrior.","text":"Gimli gets +1 [attack] for each damage token on him.\n","flavor":"\"Men need many words before deeds. My axe is restless in my hands\"\r\n-The Two Towers","is_unique":true,"threat":11,"willpower":2,"attack":2,"defense":2,"health":5,"quantity":1,"deck_limit":1,"illustrator":"Tony Foti","octgnid":"51223bd0-ffd1-11df-a976-0801200c9004","has_errata":false,"url":"https://hallofbeorn.com/LotR/Details/Gimli-Core","imagesrc":"https://s3.amazonaws.com/hallofbeorn-resources/Images/Cards/Core-Set/Gimli.jpg","versions":[{"set_name":"Core Set","year":"2011","url":"https://hallofbeorn.com/LotR/Details/Gimli-Core"},{"set_name":"The Ruins of Belegost","year":"2015","url":"https://hallofbeorn.com/LotR/Details/Gimli-TRoB"},{"set_name":"Revised Core Set","year":"2022","url":"https://hallofbeorn.com/LotR/Details/Gimli-RevCore"}]},{"pack_code":"Core","pack_name":"Core Set","is_official":true,"type_code":"hero","type_name":"Hero","sphere_code":"tactics","sphere_name":"Tactics","position":5,"code":"01005","name":"Legolas","traits":"Noble. Silvan. Warrior.","keywords":"Ranged.","text":"Ranged.\n<b>Response:</b> After Legolas participates in an attack that destroys an enemy, place 2 progress tokens on the current quest.\n","flavor":"\"I can waLine truncated
+1
View File
@@ -0,0 +1 @@
[{"pack_code":"Core","pack_name":"Core Set","is_official":true,"type_code":"hero","type_name":"Hero","sphere_code":"leadership","sphere_name":"Leadership","position":1,"code":"01001","name":"Aragorn","traits":"Dúnedain. Noble. Ranger.","keywords":"Sentinel.","text":"Sentinel.\r\n<b>Response:</b> After Aragorn commits to a quest, spend 1 resource from his resource pool to ready him.","flavor":"\"I am Aragorn son of Arathorn; and if by life or death I can save you, I will.\"\r\n-The Fellowship of the Ring","is_unique":true,"threat":12,"willpower":2,"attack":3,"defense":2,"health":5,"quantity":1,"deck_limit":1,"illustrator":"John Stanko","octgnid":"51223bd0-ffd1-11df-a976-0801200c9001","has_errata":false,"url":"https://hallofbeorn.com/LotR/Details/Aragorn-Core","imagesrc":"https://s3.amazonaws.com/hallofbeorn-resources/Images/Cards/Core-Set/Aragorn.jpg"},{"pack_code":"Core","pack_name":"Core Set","is_official":true,"type_code":"hero","type_name":"Hero","sphere_code":"leadership","sphere_name":"Leadership","position":2,"code":"01002","name":"Théodred","traits":"Noble. Rohan. Warrior.","text":"<b>Response:</b> After Théodred commits to a quest, choose a hero committed to that quest. Add 1 resource to that hero's resource pool.","flavor":"\"Not all is dark. Take courage, Lord of the Mark...\"\r\n-Gandalf, The Two Towers","is_unique":true,"threat":8,"willpower":1,"attack":2,"defense":1,"health":4,"quantity":1,"deck_limit":1,"illustrator":"Jeff Himmelman","octgnid":"51223bd0-ffd1-11df-a976-0801200c9002","has_errata":false,"url":"https://hallofbeorn.com/LotR/Details/Theodred-Core","imagesrc":"https://s3.amazonaws.com/hallofbeorn-resources/Images/Cards/Core-Set/Theodred.jpg"},{"pack_code":"Core","pack_name":"Core Set","is_official":true,"type_code":"hero","type_name":"Hero","sphere_code":"leadership","sphere_name":"Leadership","position":3,"code":"01003","name":"Glóin","traits":"Dwarf. Noble.","text":"<b>Response:</b> After Glóin suffers damage, add 1 resource to his resource pool for each point of damage he just suffered.","flavor":"His beard, very long and forked, was white, nearly as white as the snow-white cloth of his garments.\r\n-The Fellowship of the Ring","is_unique":true,"threat":9,"willpower":2,"attack":2,"defense":1,"health":4,"quantity":1,"deck_limit":1,"illustrator":"Tom Garden","octgnid":"51223bd0-ffd1-11df-a976-0801200c9003","has_errata":false,"url":"https://hallofbeorn.com/LotR/Details/Gloin-Core","imagesrc":"https://s3.amazonaws.com/hallofbeorn-resources/Images/Cards/Core-Set/Gloin.jpg"},{"pack_code":"Core","pack_name":"Core Set","is_official":true,"type_code":"hero","type_name":"Hero","sphere_code":"tactics","sphere_name":"Tactics","position":4,"code":"01004","name":"Gimli","traits":"Dwarf. Noble. Warrior.","text":"Gimli gets +1 [attack] for each damage token on him.","flavor":"\"Men need many words before deeds. My axe is restless in my hands\"\r\n-The Two Towers","is_unique":true,"threat":11,"willpower":2,"attack":2,"defense":2,"health":5,"quantity":1,"deck_limit":1,"illustrator":"Tony Foti","octgnid":"51223bd0-ffd1-11df-a976-0801200c9004","has_errata":false,"url":"https://hallofbeorn.com/LotR/Details/Gimli-Core","imagesrc":"https://s3.amazonaws.com/hallofbeorn-resources/Images/Cards/Core-Set/Gimli.jpg"},{"pack_code":"Core","pack_name":"Core Set","is_official":true,"type_code":"hero","type_name":"Hero","sphere_code":"tactics","sphere_name":"Tactics","position":5,"code":"01005","name":"Legolas","traits":"Noble. Silvan. Warrior.","keywords":"Ranged.","text":"Ranged.\r\n<b>Response:</b> After Legolas participates in an attack that destroys an enemy, place 2 progress tokens on the current quest.","flavor":"\"I can walk this path, but others have not this skill.\"\r\n-The Fellowship of the Ring","is_unique":true,"threat":9,"willpower":1,"attack":3,"defense":1,"health":4,"quantity":1,"deck_limit":1,"illustrator":"Magali Villeneuve","octgnid":"51223bd0-ffd1-11df-a976-0801200c9005","has_errata":false,"url":"https://hallofbeorn.com/LotR/Details/Legolas-Core","imagesrc":"https://s3.amazonaws.com/hallofbeorn-resources/Images/Cards/Core-Set/Legolas.jpg"},{"pack_code":"Core","pack_name":"Core Set","is_official":true,"type_code":"hero","type_name":"Hero","sphere_code":"tactics","sphere_name":"Tactics","position":6,"code":"01006","name":"Thalin","traits":"Dwarf. Warrior.","text":"While Thalin is committed to a quest, deal 1 damage to each enemy as it is revealed by the encounter deck.","flavor":"There hammer on the anvil smote,\r\nThere chisel clove, and graver wrote;\r\nThere forged was blade, and bound was hilt;\r\nThe delver mined, the mason built.\r\n-The Fellowship of the Ring","is_unique":true,"threat":9,"willpower":1,"attack":2,"defense":2,"health":4,"quantity":1,"deck_limit":1,"illustrator":"Jen Zee","octgnid":"51223bd0-ffd1-11df-a976-0801200c9006","has_errata":true,"url":"https://hallofbeorn.com/LotR/Details/Thalin-Core","imagesrc":"https://s3.amazonaws.com/hallofbeorn-resources/Images/Cards/CoreLine truncated
+1
View File
@@ -0,0 +1 @@
[{"pack_code":"Core","pack_name":"Core Set","type_code":"hero","type_name":"Hero","sphere_code":"leadership","sphere_name":"Leadership","position":1,"code":"01001","name":"Aragorn","traits":"D\u00fanedain. Noble. Ranger.","text":"Sentinel.\n<b>Response:<\/b> After Aragorn commits to a quest, spend 1 resource from his resource pool to ready him.","flavor":"\"I am Aragorn son of Arathorn; and if by life or death I can save you, I will.\"\n<cite>The Fellowship of the Ring<\/cite>","is_unique":true,"threat":12,"willpower":2,"attack":3,"defense":2,"health":5,"quantity":1,"deck_limit":1,"illustrator":"John Stanko","octgnid":"51223bd0-ffd1-11df-a976-0801200c9001","has_errata":false,"url":"https:\/\/ringsdb.com\/card\/01001","imagesrc":"\/bundles\/cards\/01001.png"},{"pack_code":"Core","pack_name":"Core Set","type_code":"hero","type_name":"Hero","sphere_code":"leadership","sphere_name":"Leadership","position":2,"code":"01002","name":"Th\u00e9odred","traits":"Noble. Rohan. Warrior.","text":"<b>Response:<\/b> After Th\u00e9odred commits to a quest, choose a hero committed to that quest. Add 1 resource to that hero's resource pool.","flavor":"\"Not all is dark. Take courage, Lord of the Mark...\"\n<cite>Gandalf, The Two Towers<\/cite>","is_unique":true,"threat":8,"willpower":1,"attack":2,"defense":1,"health":4,"quantity":1,"deck_limit":1,"illustrator":"Jeff Himmelman","octgnid":"51223bd0-ffd1-11df-a976-0801200c9002","has_errata":false,"url":"https:\/\/ringsdb.com\/card\/01002","imagesrc":"\/bundles\/cards\/01002.png"},{"pack_code":"Core","pack_name":"Core Set","type_code":"hero","type_name":"Hero","sphere_code":"leadership","sphere_name":"Leadership","position":3,"code":"01003","name":"Gl\u00f3in","traits":"Dwarf. Noble.","text":"<b>Response:<\/b> After Gl\u00f3in suffers damage, add 1 resource to his resource pool for each point of damage he just suffered.","flavor":"His beard, very long and forked, was white, nearly as white as the snow-white cloth of his garments.\n<cite>The Fellowship of the Ring<\/cite>","is_unique":true,"threat":9,"willpower":2,"attack":2,"defense":1,"health":4,"quantity":1,"deck_limit":1,"illustrator":"Tom Garden","octgnid":"51223bd0-ffd1-11df-a976-0801200c9003","has_errata":false,"url":"https:\/\/ringsdb.com\/card\/01003","imagesrc":"\/bundles\/cards\/01003.png"},{"pack_code":"Core","pack_name":"Core Set","type_code":"hero","type_name":"Hero","sphere_code":"tactics","sphere_name":"Tactics","position":4,"code":"01004","name":"Gimli","traits":"Dwarf. Noble. Warrior.","text":"Gimli gets +1 [attack] for each damage token on him.","flavor":"\"Men need many words before deeds. My axe is restless in my hands.\" <cite>The Two Towers<\/cite>","is_unique":true,"threat":11,"willpower":2,"attack":2,"defense":2,"health":5,"quantity":1,"deck_limit":1,"illustrator":"Tony Foti","octgnid":"51223bd0-ffd1-11df-a976-0801200c9004","has_errata":false,"url":"https:\/\/ringsdb.com\/card\/01004","imagesrc":"\/bundles\/cards\/01004.png"},{"pack_code":"Core","pack_name":"Core Set","type_code":"hero","type_name":"Hero","sphere_code":"tactics","sphere_name":"Tactics","position":5,"code":"01005","name":"Legolas","traits":"Noble. Silvan. Warrior.","text":"Ranged.\r\n<b>Response:<\/b> After Legolas participates in an attack that destroys an enemy, place 2 progress tokens on the current quest.","flavor":"\"I can walk this path, but others have not this skill.\"\r\n<cite>The Fellowship of the Ring<\/cite>","is_unique":true,"threat":9,"willpower":1,"attack":3,"defense":1,"health":4,"quantity":1,"deck_limit":1,"illustrator":"Magali Villeneuve","octgnid":"51223bd0-ffd1-11df-a976-0801200c9005","has_errata":false,"url":"https:\/\/ringsdb.com\/card\/01005","imagesrc":"\/bundles\/cards\/01005.png"},{"pack_code":"Core","pack_name":"Core Set","type_code":"hero","type_name":"Hero","sphere_code":"tactics","sphere_name":"Tactics","position":6,"code":"01006","name":"Thalin","traits":"Dwarf. Warrior.","text":"While Thalin is committed to a quest, deal 1 damage to each enemy as it is revealed by the encounter deck.","flavor":"There hammer on the anvil smote,\nThere chisel clove, and graver wrote;\nThere forged was blade, and bound was hilt;\nThe delver mined, the mason built.\n<cite>The Fellowship of the Ring<\/cite>","is_unique":true,"threat":9,"willpower":1,"attack":2,"defense":2,"health":4,"quantity":1,"deck_limit":1,"illustrator":"Jen Zee","octgnid":"51223bd0-ffd1-11df-a976-0801200c9006","has_errata":false,"url":"https:\/\/ringsdb.com\/card\/01006","imagesrc":"\/bundles\/cards\/01006.png"},{"pack_code":"Core","pack_name":"Core Set","type_code":"hero","type_name":"Hero","sphere_code":"spirit","sphere_name":"Spirit","position":7,"code":"01007","name":"\u00c9owyn","traits":"Noble. Rohan.","text":"<b>Action:<\/b> Discard 1 card from your hand to give \u00c9owyn +1 [willpower] until the end of the phase. This effect may be triggered by each player once each round.","flavor":"Slender and tall she was in her white robe girt with silver; but stLine truncated
+136
View File
@@ -0,0 +1,136 @@
package main
import (
"encoding/csv"
"encoding/json"
"fmt"
"io/ioutil"
"log"
"os"
"path/filepath"
"regexp"
"strconv"
"strings"
"github.com/bazelbuild/rules_go/go/tools/bazel"
strip "github.com/grokify/html-strip-tags-go"
"github.com/jessevdk/go-flags"
"github.com/squk/lotr/cmd/beornextract/types"
)
type Options struct {
RawConversion bool `short:"r" long:"raw" description:"Enable to keep the original text from HallOfBeorn dump. Enable to prep for ALEP pipeline."`
}
var opts = Options{
RawConversion: false,
}
func main() {
_, err := flags.ParseArgs(&opts, os.Args)
if err != nil {
panic(err)
}
fmt.Println("LOTR CARD PARSE")
f, err := bazel.Runfile(".")
if err != nil {
panic(err)
}
err = filepath.Walk(f,
func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
fmt.Println(path, info.Size())
return nil
})
if err != nil {
log.Println(err)
}
// Open our jsonFile
// jsonFile, err := os.Open("cmd/beornextract/data/Bot.Cards.json")
jsonFile, err := os.Open("cmd/beornextract/data/Export.Cards.json")
// if we os.Open returns an error then handle it
if err != nil {
fmt.Println(err)
return
}
// defer the closing of our jsonFile so that we can parse it later on
defer jsonFile.Close()
byteValue, _ := ioutil.ReadAll(jsonFile)
cards := []types.HallOfBeornCard{}
json.Unmarshal(byteValue, &cards)
// Open a file for writing
csvFile, err := os.Create("/Users/christian/Downloads/lotr-lcg-set-generator.csv")
defer csvFile.Close()
if err != nil {
// Handle error
}
// Create a writer
w := csv.NewWriter(csvFile)
// Write some rows
for _, card := range cards {
if card.EncounterSet != "" {
continue // skip non=player cards
}
w.Write(
[]string{
card.Octgnid,
"", // hidden
"", // hidden
card.EncounterSet,
strconv.Itoa(card.Position),
strconv.Itoa(card.Quantity),
card.Name,
fmt.Sprintf(
"%t",
card.IsUnique,
),
card.TypeName,
card.SphereName,
card.Traits,
findKeywords(card.Text),
card.Cost,
card.EngagementCost,
strconv.Itoa(card.Threat),
strconv.Itoa(card.Willpower),
strconv.Itoa(card.Attack),
strconv.Itoa(card.Defense),
strconv.Itoa(card.Health),
card.QuestPoints,
strconv.Itoa(card.VictoryPoints),
"", // Special Icon
transformText(card.Name, card.Text),
card.Flavor,
},
)
}
// Close the writer
w.Flush()
// spew.Dump(c)
}
func transformText(name, text string) string {
if opts.RawConversion {
return text
}
out := strings.ReplaceAll(text, name, "[name]") // insert name tag
out = strip.StripTags(out)
out = keywordPattern.ReplaceAllLiteralString(out, "")
return strings.TrimSpace(out)
}
var keywordPattern = regexp.MustCompile(`((?:(?:[A-Z][a-z]+(\.|\s[0-9]+\.)\s*)+))`)
func findKeywords(text string) string {
return strings.TrimSpace(keywordPattern.FindString(text))
}
+8
View File
@@ -0,0 +1,8 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "types",
srcs = ["card.go"],
importpath = "github.com/squk/lotr/cmd/beornextract/types",
visibility = ["//visibility:public"],
)
+27
View File
@@ -0,0 +1,27 @@
package types
type HallOfBeornCard struct {
PackCode string `json:"pack_code,omitempty"`
PackName string `json:"pack_name,omitempty"`
IsOfficial bool `json:"is_official,omitempty"`
TypeCode string `json:"type_code,omitempty"`
TypeName string `json:"type_name,omitempty"`
SphereCode string `json:"sphere_code,omitempty"`
SphereName string `json:"sphere_name,omitempty"`
Position int `json:"position,omitempty"`
Threat int `json:"threat,omitempty"`
Willpower int `json:"willpower,omitempty"`
Attack int `json:"attack,omitempty"`
Defense int `json:"defense,omitempty"`
Health int `json:"health,omitempty"`
Octgnid string `json:"octgnid,omitempty"`
HasErrata bool `json:"has_errata,omitempty"`
URL string `json:"url,omitempty"`
QuestPoints string `json:"quest,omitempty"`
VictoryPoints int `json:"victory,omitempty"`
Imagesrc string `json:"imagesrc,omitempty"`
EncounterSet string `json:"encounter_set,omitempty"`
EngagementCost string `json:"engagement_cost,omitempty"`
ThreatStrength int `json:"threat_strength,omitempty"`
}