1

Erlang をいじり始めたばかりで、Twitter のタイムラインを表示するためだけの非常に単純なテスト Web アプリケーションを作成しています。

アプリの作成には webmachine を使用し、テンプレートのレンダリングには erlyDTL を使用しています。

私の質問は、mochiweb のmochijson2:decode/1関数によって返される構造に関連しています。

次の例のように、タイムラインを正常に取得してデコードできます。

1> Url = "http://api.twitter.com/1/statuses/user_timeline.json?screen_name=<TWITTER_SCREEN_NAME_HERE>".
2> inets:start().
3> {ok, {_, _, Response}} = httpc:request(Url).
4> DecodedJson = mochijson2:decode(Response).

このmochijson2:decode/1関数は、次の形式のタプルのリストを返します。

[{struct, proplist()}, {struct, proplist()}, ...]

ただし、タイムラインを erlyDTL に渡すには、structatom タグを取り除き、単純に proplist のリストを webmachine リソース (erlyDTL によってレンダリング) に渡す必要があります。パターン マッチングにまったく慣れていないので、次のリスト内包表記でこれを実現できると考えました。

Timeline = [Tweet || {struct, Tweet} <- DecodedJson].

<<"user">>実際、これは、値自体{struct, proplist()}タプルである, を除いて、各 Tweet proplist 内のすべてのアイテムに対して完全に機能します。私は一生、この入れ子になったタプルからアトムを削除する方法を理解できず、外部ツイートと各ツイートに含まれるユーザーのstruct両方にパターン マッチする Erlang コードの例を誰かが提供できるかどうか疑問に思っていました。{struct, Tweet}{struct, User}

最終的な目標は、次の例のように、Django テンプレート言語で各ツイートにアクセスできるようにすることです。

{{ tweet.text }}  <- works
{{ tweet.created_at }}  <- works
{{ tweet.user.profile_image_url }}  <- ???

どんな助けでも大歓迎です!

4

3 に答える 3

2

最近取り組んだプロジェクトでは、EXT JSフロントエンド アプリからの大きな JSON データ構造を扱っていました。JSON オブジェクトの一例を以下に示します (これは単なる JSON のスケルトンです)。

{
        "presence_token":"734737328233HDHSBSHSYEYEYWYWGWE",
        "presence_time":"HH:分:秒",
        "friend_requests":
        [
            {
                "from":"ユーザー名",
                "タイプ":"バディ",
                "日付":"DD/MM/YY",
                "時間":"HH:分:秒",
                "name":"あなたのフルネーム",
                "メール":"user@example.com"
            }
        ]、
        "group_status":
        [
            {
                "group_name":"ecampus",
                "ステータス":"実行中",
                "メンバー":["フィル","ジョシュ","シャズ"],
                "開始日":"DD/MM/YY",
                "start_time":"HH:分:秒"             
            }、
            {
                "group_name":"ブガンダ",
                「ステータス」:「オフ」
            }
        ]、
        "friend_status":
        [
            {
                "friend":"Friend_username",
                "ステータス":"オンライン",
                "log_on_time":"HH:分:秒",
                "状態":"利用可能",
                "name":"Friend_Fullname",
                "メール":"user@example.com"              
            }、
            {
                "friend":"Friend_username",
                "ステータス":"オフライン",                 
                "name":"Friend_Fullname",
                "メール":"user@example.com"              
            }           
        ]           
    }

の後mochijson2:decode/1、私が持っていた構造体オブジェクトは次のように表示されます:

        {struct,[{<<"presence_token">>,
                  <<"734737328233HDHSBSHSYEYEYWYWGWE">>}、
                 {<<"存在時間">>、<<"HH:分:秒">>}、
                 {<<"friend_requests">>、
                  [{struct,[{<<"from">>,<<"ユーザー名">>},
                            {<<"タイプ">>、<<"バディ">>}、
                            {<<"日付">>,<<"DD/MM/YY">>},
                            {<<"時間">>,<<"HH:分:秒">>},
                            {<<"名前">>、<<"あなたのフルネーム">>}、
                            {<<"email">>,<<"user@example.com">>}]}]},
                 {<<"group_status">>、
                  [{struct,[{<<"group_name">>,<<"ecampus">>},
                            {<<"ステータス">>、<<"実行中">>}、
                            {<<"メンバー">>,[<<"フィル">>,<<"ジョシュ">>,<<"シャズ">>]},
                            {<<"開始日">>,<<"DD/MM/YY">>},
                            {<<"start_time">>,<<"HH:分:秒">>}]},
                   {struct,[{<<"group_name">>,<<"buganda">>},
                            {<<"ステータス">>,<<"オフ">>}]}]},
                 {<<"friend_status">>、
                  [{struct,[{<<"friend">>,<<"Friend_username">>},
                            {<<"状態">>,<<"オンライン">>},
                            {<<"ログオン時間">>,<<"HH:分:秒">>},
                            {<<"状態">>、<<"利用可能">>}、
                            {<<"name">>,<<"Friend_Fullname">>},
                            {<<"email">>,<<"user@example.com">>}]},
                   {struct,[{<<"friend">>,<<"Friend_username">>},
                            {<<"状態">>,<<"オフライン">>},
                            {<<"name">>,<<"Friend_Fullname">>},
                            {<<"email">>,<<"user@example.com">>}]}]}]}

ここで、この構造体を「深い」proplist に変換するモジュールを作成することにしました。このモジュールにはstruct:all_keys/1、構造体オブジェクトを渡すとリストとタプルを整理された方法で生成する関数が含まれます。コードは次のとおりです。

-モジュール(構造体)。
-export([all_keys/1])。

is_struct({struct,_}) -> true;
is_struct(_) -> false。

to_binary(S) when is_list(S)-> list_to_binary(S);
to_binary(S) when is_integer(S)-> S;
to_binary(S) when is_atom(S)-> to_binary(atom_to_list(S));
to_binary(S) -> S.

to_value(V) when is_binary(V)-> binary_to_list(V);
to_value(V) when is_integer(V)-> V;
to_value(V) の場合 is_list(V)->
    の list_to_integer(V) を試してください
        PP -> PP
    キャッチ
        _:_ ->
            list_to_float(V) を試す
                PP2 -> PP2
            キャッチ
                _:_ -> V
            終わり
    終わり;
to_value(A)-> A.

to_value2({struct,L})->
    all_keys({struct,L});
to_value2([{struct,_L}|_Rest] = LL)->
    [all_keys(XX) || XX <- LL];
to_value2(D) when is_binary(D)-> to_value(D);
to_value2(D) の場合 is_list(D)->
    [to_value2(任意) || 任意 <- D]。    

all_keys({struct,L})->
    [{to_value(Key),to_value2(Val)} || {キー、ヴァル} <- L];
all_keys(リスト)-> [all_keys(X) || X <-リスト]。

今、呼び出すと、次のstruct:all_keys(Struct_object)出力が得られます。

[{"presence_token",P_token},
 {"presence_time",P_time},
 {"friend_requests",
  [[{"差出人","ユーザー名"},
    {"タイプ","仲間"},
    {"日付","DD/MM/YY"},
    {"時間","HH:分:秒"},
    {"name","あなたのフルネーム"},
    {"email","user@example.com"}]]},
 {"group_status",
  [[{"group_name","ecampus"},
    {"ステータス","実行中"},
    {"メンバー",["フィル","ジョシュ","シャズ"]},
    {"開始日","DD/MM/YY"},
    {"start_time","HH:Mins:Secs"}],
   [{"group_name","buganda"},{"status","off"}]]},
 {"friend_status",
  [[{"フレンド","フレンド_ユーザー名"},
    {"ステータス","オンライン"},
    {"ログオン時間","HH:分:秒"},
    {"状態","利用可能"},
    {"name","Friend_Fullname"},
    {"email","user@example.com"}],
   [{"フレンド","フレンド_ユーザー名"},
    {"ステータス","オフライン"},
    {"name","Friend_Fullname"},
    {"email","user@example.com"}]]}]

上記の proplist は、struct オブジェクトよりも簡単に操作できます。ただし、構造体モジュールの別のバージョンが、特に有名な mochiweb の例 (Sticky Notes と呼ばれる) で見つかる場合があります。そのリンクは今のところありません。上に貼り付けた構造体モジュールは、mochijson2 の使用に役立つはずです。成功

于 2011-06-13T08:34:33.287 に答える
2

同様の目的で内部的に使用するものは次のとおりです。

%% @doc Flatten {struct, [term()]} to [term()] recursively.
destruct({struct, L}) ->
    destruct(L);
destruct([H | T]) ->
    [destruct(H) | destruct(T)];
destruct({K, V}) ->
    {K, destruct(V)};
destruct(Term) ->
    Term.

mochijson2 用語の他の用途については、KVC が役立つ場合があります: https://github.com/etrepum/kvc

于 2011-06-11T17:29:32.623 に答える
0

説明した構造に基づいて、次を試すことができます。

timeline(List) -> timeline(List, []).

timeline([], Result) -> lists:reverse(Result);
timeline([{struct, S}|T], Result) -> timeline(T, [S|Result]);
timeline([{<<"user">>, {struct, S}}|T], Result) -> timeline(T, [S|Result]);
timeline([_|T], Result) -> timeline(T, Result).

そのコードを というモジュールに入れましたtwitter

> twitter:timeline([{struct, 1}, {struct, 2}, {<<"user">>, {struct, 3}}, 5]).
[1,2,3]

<<"user">>特定のニーズに_応じて、に置き換えることができます。また、外部からの入力を処理しているため、何らかの例外処理も導入する必要があるでしょう。

于 2011-06-10T21:56:58.210 に答える