LoginSignup
1
0

More than 5 years have passed since last update.

Google Spread Sheetで複数列を取得してElmのモデルに入れたメモ

Last updated at Posted at 2019-04-27

概要

Google Sheet APIが使えるようになった
ElmでSheet APIを使えるようになった
もう少し大きなシートを使ってページを更新できるようにしてみる。

出来上がったのがこちら。google spread sheetでカードの文言などを編集できる。

ユーザカードページ
※ 現在、ソースの状態とは実装がずれております。完成品の大まかなイメージは変わっていません。

この時点のソース

デコーダの書き方が課題点となっている。

  • ~でなければのときの書き方が冗長になっている。
  • 現在の書き方だと、スプレッドシートとの相性が悪い? 列を追加したときに、そこから先の番号を手作業で1つずつ更新が必要。

開発環境

  • Windows 10
  • Vagrant 2.2.4
  • Virtualbox 6.0.6r130049
  • Ubuntu 18.04.2 LTS (Bionic Beaver)
  • Docker version 18.09.5, build e8ff056
  • docker-compose version 1.24.0, build 0aa59064

ソース

モデル定義

type alias CardData =
    { cardId : String
    , cardName : String
    , cardType : String
    , kind : String
    , exp : Int
    , timing : String
    , cost : Int
    , range : Int
    , maxRange : Int
    , target : String
    , maxLevel : Int
    , effect : String
    , description : String
    , tags : List Tag
    , imgMain : String
    , illustedByName : String
    , illustedByUrl : String
    , imgFrame : String
    , frameByName : String
    , frameByUrl : String
    , deleteFlag : Int
    }
type alias Tag =
    { name : String
    , level : Int
    }


initCard =
    CardData "" "" "" "" 0 "" 0 0 0 "" 0 "" "" [] "" "" "" "" "" "" 0

タグを複数持ったカード。タグについてはスプレッドシートでは1つのセルに"タグ,タグ:Lv,タグ..."という形で記述する。
:Lvがないときは0として扱う。

タグのデコード

tagsDecoder : Decoder (List Tag)
tagsDecoder =
    D.map tagsParser string


tagsParser : String -> List Tag
tagsParser s =
    let
        list =
            String.split "," s
    in
    List.map (\str -> tagParser str) list


tagDecoder : Decoder Tag
tagDecoder =
    D.map tagParser string


tagParser : String -> Tag
tagParser s =
    let
        list =
            String.split ":" s

        name =
            case List.head list of
                Just a ->
                    a

                _ ->
                    s

        value =
            case List.tail list of
                Just t ->
                    case List.head t of
                        Just a ->
                            case String.toInt a of
                                Just n ->
                                    n

                                _ ->
                                    0

                        _ ->
                            0

                _ ->
                    0
    in
    Tag name value

「:Lvがないときは0として扱う。」の場合分けがかなりの力技になっている。
何か、もっといいやり方がありそうだけれど、今後の課題。

カードのデコード

import Json.Decode as D exposing (..)
import Json.Decode.Pipeline exposing (custom, hardcoded, optional, required)
import Json.Encode as E

-- 省略

cardDataListDecodeFromJson : String -> Result Error (List CardData)
cardDataListDecodeFromJson s =
    decodeString (field "values" (D.list cardDecoder)) s


cardDecodeFromString : String -> Result Error CardData
cardDecodeFromString s =
    decodeString cardDecoder s


cardDecoder : Decoder CardData
cardDecoder =
    D.succeed CardData
        |> Json.Decode.Pipeline.custom (D.index 0 D.string)
        |> Json.Decode.Pipeline.custom (D.index 1 D.string)
        |> Json.Decode.Pipeline.custom (D.index 2 D.string)
        |> Json.Decode.Pipeline.custom (D.index 3 D.string)
        |> Json.Decode.Pipeline.custom (D.index 4 GSAPI.decoderIntFromString)
        |> Json.Decode.Pipeline.custom (D.index 5 D.string)
        |> Json.Decode.Pipeline.custom (D.index 6 GSAPI.decoderIntFromString)
        |> Json.Decode.Pipeline.custom (D.index 7 GSAPI.decoderIntFromString)
        |> Json.Decode.Pipeline.custom (D.index 8 GSAPI.decoderIntFromString)
        |> Json.Decode.Pipeline.custom (D.index 9 D.string)
        |> Json.Decode.Pipeline.custom (D.index 10 GSAPI.decoderIntFromString)
        |> Json.Decode.Pipeline.custom (D.index 11 D.string)
        |> Json.Decode.Pipeline.custom (D.index 12 D.string)
        |> Json.Decode.Pipeline.custom (D.index 13 tagsDecoder)
        |> Json.Decode.Pipeline.custom (D.index 14 D.string)
        |> Json.Decode.Pipeline.custom (D.index 15 D.string)
        |> Json.Decode.Pipeline.custom (D.index 16 D.string)
        |> Json.Decode.Pipeline.custom (D.index 17 D.string)
        |> Json.Decode.Pipeline.custom (D.index 18 D.string)
        |> Json.Decode.Pipeline.custom (D.index 19 D.string)
        |> Json.Decode.Pipeline.custom (D.index 20 GSAPI.decoderIntFromString)

作り方が悪い気がする。

  • 列を追加したときに、そこから先の番号を手作業で1つずつ更新が必要。
  • 今、どのプロパティを取得しているのかがぱっと見でわからない。

json

今回解析した、GooogleAPIが返してくるjsonは以下のようなもの。
数値も文字列として返してくるのが注意かも。

{
  "range": "cardList!A2:U3",
  "majorDimension": "ROWS",
  "values": [
    [
      "B000",
      "走る",
      "能力",
      "基本能力",
      "0",
      "アクション",
      "4",
      "0",
      "0",
      "自身",
      "1",
      "移動1",
      "逃げてもいいし、向かってもいい。\n君たちは何処にだっていける。\n一歩ずつではあるけれど。",
      "移動,基本能力:0",
      "/assets/images/card/main/run.png",
      "ヒューマンピクトグラム2.0",
      "http://pictogram2.com/",
      "/assets/images/card/frame/report.gif",
      "",
      "",
      "0"
    ],
    [
      "C000",
      "未定",
      "能力",
      "てすと",
      "",
      "",
      "0",
      "0",
      "0",
      "自身",
      "1",
      "",
      "",
      "",
      "",
      "",
      "",
      "",
      "",
      "",
      "0"
    ]
  ]
}

参考

Google Sheet APIを試したメモ
ElmでGoogle Spread Sheetの値を読み込んだメモ
Elmの歩き方(入門者向けブックマーク集)
Decoder a からいろいろ理解ってしまおう
elm json pipline

1
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0