Last active
May 5, 2022 07:53
-
-
Save mworrell/08a9f2115c2df7a3f3068b500564314d to your computer and use it in GitHub Desktop.
Zotonic 1.0 - Template model for the OMDB movie database - source code to accompany the documentation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-module(m_omdb). | |
-behaviour(zotonic_model). | |
-export([ | |
m_get/3 | |
]). | |
-include_lib("zotonic_core/include/zotonic.hrl"). | |
-define(API_URL, "http://www.omdbapi.com/?"). | |
-spec m_get(Keys, Msg, Context) -> Return when | |
Keys :: list(), | |
Msg :: zotonic_model:opt_msg(), | |
Return :: zotonic_model:return(), | |
Context:: z:context(). | |
% Syntax: m.omdb.api_url | |
m_get([ <<"api_url">> | Rest ], _Msg, _Context) -> | |
{ok, {z_convert:to_binary(?API_URL), Rest}}; | |
% Syntax: m.omdb["tt0123456789"] | |
m_get([ <<"tt", _/binary>> = Id | Rest ], _Msg, _Context) -> | |
{ok, {fetch_data([ {id, Id} ]), Rest}}; | |
% Syntax: m.omdb["some title"] | |
m_get([ Title | Rest ], _Msg, _Context) when is_binary(Title) -> | |
{ok, {fetch_data([ {id, Id} ]), Rest}}; | |
% Syntax: m.omdb.sometype["tt0123456789"] | |
m_get([ Type, <<"tt", _/binary>> = Id | Rest ], _Msg, _Context) | |
when Type =:= <<"movies">>; | |
Type =:= <<"series">>; | |
Type =:= <<"episode">> -> | |
{ok, {fetch_data([ {type, Type}, {id, Id} ]), _Msg, Rest}}; | |
% Syntax: m.omdb.sometype[QueryString] | |
m_get([ Type, QueryString | Rest ], _Msg, _Context) | |
when Type =:= <<"movies">>; | |
Type =:= <<"series">>; | |
Type =:= <<"episode">> -> | |
{ok, {fetch_data([ {type, Type}, {title, QueryString} ]), Rest}}; | |
% Syntax: m.omdb[{query QueryParams}] | |
% For m.omdb[{query title="Dollhouse"}], Query is: [{title,"Dollhouse"}] | |
m_get([ {query, Query} | Rest ], _Msg, _Context) -> | |
{ok {fetch_data(Query), Rest}}; | |
% Syntax: m.omdb.sometype[{query QueryParams}] | |
% For m.omdb.series[{query title="Dollhouse"}], Query is: [{title,"Dollhouse"}] and Q is: [{type,"series"}] | |
m_get([ Type, {query, Query} | Rest ], _Msg, _Context) | |
when Type =:= <<"movies">>; | |
Type =:= <<"series">>; | |
Type =:= <<"episode">> -> | |
{ok, {fetch_data([ {type, Type} | Query ]), Rest}}. | |
-spec fetch_data(Query) -> list() when Query:: list(). | |
fetch_data([]) -> | |
[{error, "Params missing"}]; | |
fetch_data(Query) -> | |
case proplists:is_defined(title, Query) or proplists:is_defined(id, Query) of | |
false -> [{error, "Param id or title missing"}]; | |
true -> | |
QueryParts = lists:map(fun(Q) -> | |
make_query_string(Q) | |
end, Query), | |
Url = ?API_URL ++ string:join(QueryParts, "&"), | |
case get_page_body(Url) of | |
{error, Error} -> | |
[{error, Error}]; | |
Json -> | |
{struct, JsonData} = mochijson2:decode(Json), | |
lists:map(fun(D) -> | |
convert_data_prop(D) | |
end, JsonData) | |
end | |
end. | |
%% Translate query params id, title and type into parameters that OMDB wants | |
-spec make_query_string({Key, Value}) -> string() when | |
Key:: atom(), | |
Value:: binary() | string() | atom(). | |
make_query_string({id, Id}) -> | |
"i=" ++ z_url:url_encode(Id); | |
make_query_string({title, Title}) -> | |
"t=" ++ z_url:url_encode(Title); | |
make_query_string({type, Type}) -> | |
"type=" ++ z_url:url_encode(Type); | |
make_query_string(_) -> | |
"". | |
%% Translate binary keys to atoms | |
-spec convert_data_prop({Key, Value}) -> {atom(), string()} when | |
Key:: binary(), | |
Value:: binary(). | |
convert_data_prop({Key, Value}) -> | |
{z_convert:to_atom(string:to_lower(z_convert:to_list(Key))), Value}. | |
get_page_body(Url) -> | |
case httpc:request(get, {Url, []}, [], []) of | |
{ok, {_, Headers, Body}} -> | |
case content_length(Headers) of | |
0 -> {error, "No content"}; | |
_ -> Body | |
end; | |
Error -> | |
{error, Error} | |
end. | |
content_length(Headers) -> | |
list_to_integer(proplists:get_value("content-length", Headers, "0")). |
@williamthome Thanks!
@williamthome Ok if I copy your version over to this gist?
@williamthome Ok if I copy your version over to this gist?
Of course! o/
Thanks, copied it!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Revised according to 1.0.0-rc.5/zotonic_model