Skip to content

Instantly share code, notes, and snippets.

@prikhi
Created June 19, 2019 03:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save prikhi/32b460c5b648ba12abc1d980fc9ce9c0 to your computer and use it in GitHub Desktop.
Save prikhi/32b460c5b648ba12abc1d980fc9ce9c0 to your computer and use it in GitHub Desktop.
Star Wars Galaxy of Heroes - Mods to CSV
module Main exposing (main)
import Browser
import Html exposing (..)
import Html.Attributes exposing (type_, value)
import Html.Events exposing (onInput, onClick)
import Http exposing (jsonBody, expectJson)
import Json.Encode as Encode
import Json.Decode as Decode
type alias Model =
{ allyCode : String
, characters : List Character
}
type alias Character =
{ name : String
, mods : List Mod
}
type alias Mod =
{ level : Int
, tier : Int
, slot: Int
, set : Int
, pips : Int
, primaryStat : (String, Float)
, secondaryStats : List (String, Float)
}
initialModel : Model
initialModel =
{ allyCode = ""
, characters = []
}
type Msg
= InputAllyCode String
| ClickSubmit
| FetchResult (Result Http.Error Profile)
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
case msg of
InputAllyCode str ->
({ model | allyCode = str }, Cmd.none)
ClickSubmit ->
(model, getProfile model.allyCode)
FetchResult (Err err) ->
(model, Cmd.none)
FetchResult (Ok prof) ->
({ model | characters = prof.roster }, Cmd.none)
getProfile : String -> Cmd Msg
getProfile allyCode =
Http.post
{ url = "https://api.mods-optimizer.swgoh.grandivory.com/playerprofile/"
, body = jsonBody <| Encode.object [ ("ally-code", Encode.string allyCode) ]
, expect = expectJson FetchResult decodeProfile
}
type alias Profile = { roster : List Character }
decodeProfile : Decode.Decoder Profile
decodeProfile = Decode.map Profile (Decode.field "roster" <| Decode.list decodeCharacter)
decodeCharacter : Decode.Decoder Character
decodeCharacter = Decode.map2 Character
(Decode.field "defId" Decode.string)
(Decode.field "mods" <| Decode.list decodeMod)
decodeMod : Decode.Decoder Mod
decodeMod = Decode.map7 Mod
(Decode.field "level" Decode.int)
(Decode.field "tier" Decode.int)
(Decode.field "slot" Decode.int)
(Decode.field "set" Decode.int)
(Decode.field "pips" Decode.int)
(Decode.field "primaryStat" decodeStat)
(Decode.field "secondaryStat" <| Decode.list decodeStat)
decodeStat : Decode.Decoder (String, Float)
decodeStat = Decode.map2 Tuple.pair
(Decode.field "unitStat" Decode.string)
(Decode.field "value" Decode.float)
view : Model -> Html Msg
view model =
div []
[ label []
[ text "Ally Code: "
, input
[ type_ "text"
, value model.allyCode
, onInput InputAllyCode
]
[]
]
, button [onClick ClickSubmit] [ text "Submit" ]
, label [] [ text "CSV:", br [] [], textarea [ value <| generateExport model.characters] [] ]
]
generateExport : List Character -> String
generateExport characters =
String.join "\n"
<| "character, level, tier, slot, set, pips, primary, secondary1, secondary2, secondary3, secondary4"
:: List.concatMap generateModLines characters
generateModLines : Character -> List String
generateModLines { name, mods } =
let
generateLine mod =
String.join "," <|
[ name
, String.fromInt mod.level
, String.fromInt mod.tier
, String.fromInt mod.slot
, String.fromInt mod.set
, String.fromInt mod.pips
, generateStat mod.primaryStat
]
++ List.map generateStat mod.secondaryStats
generateStat (description, val) =
description ++ ": " ++ String.fromFloat val
in
List.map generateLine mods
main : Program () Model Msg
main =
Browser.element
{ init = \_ -> (initialModel, Cmd.none)
, view = view
, update = update
, subscriptions = always Sub.none
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment