Skip to content

Commit 62a0c36

Browse files
author
Eric Sartre
committed
implement notify on called.
1 parent 19d5c94 commit 62a0c36

File tree

8 files changed

+170
-16
lines changed

8 files changed

+170
-16
lines changed

Makefile

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
all:
2-
erlc -o ebin src/*.erl
2+
./rebar compile
33
run:
4-
erl -boot start_sasl -pa ebin -config ebin/remotter_error
4+
erl -boot start_sasl -pa ebin -sname remotter@local -detached -config ebin/remotter_error -s application start remotter
55
clean:
66
$(RM) ebin/*.beam
7+
$(RM) error_logs/*
78

priv/jiffy.so

50 KB
Binary file not shown.

rebar

128 KB
Binary file not shown.

rebar.config

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{erl_opts, [debug_info, fail_on_warning]}.
2+
{require_otp_vsn, "R15"}.
3+

src/direct_msg.erl

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
-module(direct_msg).
2+
-compile(export_all).
3+
-define(CONSUMER_KEY, "tdPkd4z4lvANKT22xqIzng").
4+
-define(CONSUMER_SECRET, "oZjO8LxzGSq4jvWcgRNOFzlJsiMLCiZOVMWJdIKPCsk").
5+
-define(ACCESS_TOKEN, "547781917-jNire46819xGXASVB4FBvlVDvIJWIz6XmvNFs3U8").
6+
-define(TOKEN_SECRET, "vWvZDu80doIoA8yIOeKkQ98t5fMErYgFMvimE7YeMU").
7+
8+
send(Msg) ->
9+
application:start(inets),
10+
ssl:start(),
11+
Consumer = {?CONSUMER_KEY, ?CONSUMER_SECRET, hmac_sha1},
12+
URL = "https://api.twitter.com/1/direct_messages/new.json",
13+
Query = [{"screen_name", "siritori"}, {"text", Msg}],
14+
oauth:post(URL, Query, Consumer, ?ACCESS_TOKEN, ?TOKEN_SECRET, []).
15+

src/jiffy.erl

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
% This file is part of Jiffy released under the MIT license.
2+
% See the LICENSE file for more information.
3+
4+
-module(jiffy).
5+
-export([decode/1, encode/1, encode/2]).
6+
-define(NOT_LOADED, not_loaded(?LINE)).
7+
8+
-on_load(init/0).
9+
10+
decode(Data) when is_binary(Data) ->
11+
case nif_decode(Data) of
12+
{error, _} = Error ->
13+
throw(Error);
14+
{partial, EJson} ->
15+
finish_decode(EJson);
16+
EJson ->
17+
EJson
18+
end;
19+
decode(Data) when is_list(Data) ->
20+
decode(iolist_to_binary(Data)).
21+
22+
23+
encode(Data) ->
24+
encode(Data, []).
25+
26+
27+
encode(Data, Options) ->
28+
case nif_encode(Data, Options) of
29+
{error, _} = Error ->
30+
throw(Error);
31+
{partial, IOData} ->
32+
finish_encode(IOData, []);
33+
IOData ->
34+
IOData
35+
end.
36+
37+
38+
finish_decode({bignum, Value}) ->
39+
list_to_integer(binary_to_list(Value));
40+
finish_decode({bignum_e, Value}) ->
41+
{IVal, EVal} = case string:to_integer(binary_to_list(Value)) of
42+
{I, [$e | ExpStr]} ->
43+
{E, []} = string:to_integer(ExpStr),
44+
{I, E};
45+
{I, [$E | ExpStr]} ->
46+
{E, []} = string:to_integer(ExpStr),
47+
{I, E}
48+
end,
49+
IVal * math:pow(10, EVal);
50+
finish_decode({bigdbl, Value}) ->
51+
list_to_float(binary_to_list(Value));
52+
finish_decode({Pairs}) when is_list(Pairs) ->
53+
finish_decode_obj(Pairs, []);
54+
finish_decode(Vals) when is_list(Vals) ->
55+
finish_decode_arr(Vals, []);
56+
finish_decode(Val) ->
57+
Val.
58+
59+
finish_decode_obj([], Acc) ->
60+
{lists:reverse(Acc)};
61+
finish_decode_obj([{K, V} | Pairs], Acc) ->
62+
finish_decode_obj(Pairs, [{K, finish_decode(V)} | Acc]).
63+
64+
finish_decode_arr([], Acc) ->
65+
lists:reverse(Acc);
66+
finish_decode_arr([V | Vals], Acc) ->
67+
finish_decode_arr(Vals, [finish_decode(V) | Acc]).
68+
69+
70+
finish_encode([], Acc) ->
71+
%% No reverse! The NIF returned us
72+
%% the pieces in reverse order.
73+
Acc;
74+
finish_encode([<<_/binary>>=B | Rest], Acc) ->
75+
finish_encode(Rest, [B | Acc]);
76+
finish_encode([Val | Rest], Acc) when is_integer(Val) ->
77+
Bin = list_to_binary(integer_to_list(Val)),
78+
finish_encode(Rest, [Bin | Acc]);
79+
finish_encode(_, _) ->
80+
throw({error, invalid_ejson}).
81+
82+
83+
init() ->
84+
PrivDir = case code:priv_dir(?MODULE) of
85+
{error, _} ->
86+
EbinDir = filename:dirname(code:which(?MODULE)),
87+
AppPath = filename:dirname(EbinDir),
88+
filename:join(AppPath, "priv");
89+
Path ->
90+
Path
91+
end,
92+
erlang:load_nif(filename:join(PrivDir, "jiffy"), 0).
93+
94+
95+
not_loaded(Line) ->
96+
erlang:nif_error({not_loaded, [{module, ?MODULE}, {line, Line}]}).
97+
98+
nif_decode(_Data) ->
99+
?NOT_LOADED.
100+
101+
nif_encode(_Data, _Options) ->
102+
?NOT_LOADED.
103+

ebin/remotter.app renamed to src/remotter.app.src

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,6 @@
11
{application, remotter,
22
[{description, "Remote interface for Twitter"},
3-
{vsn, "0.1.1"},
4-
{modules, [
5-
remotter_app,
6-
remotter_sup,
7-
remotter_server,
8-
oauth,
9-
userstream_server
10-
]},
3+
{vsn, git},
114
{registered, [remotter_sup]},
125
{applications, [kernel, stdlib]},
136
{mod, {remotter_app, []}}

src/remotter_server.erl

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,42 @@ handle_part(Part) ->
1313

1414
init([]) ->
1515
process_flag(trap_exit, true),
16-
{ok, void}.
16+
{ok, false}.
1717

18-
handle_call(Msg, _From, void) ->
19-
{reply, Msg, void}.
18+
handle_call(Msg, _From, State) ->
19+
{reply, Msg, State}.
2020

21-
handle_cast({part, Part}, void) ->
22-
io:format("receive: ~p~n", [Part]),
23-
{noreply, void}.
21+
handle_cast({part, Part}, State) ->
22+
Decoded = jiffy:decode(Part),
23+
case dig([<<"user">>, <<"screen_name">>], Decoded) of
24+
{ok, <<"siritori">>} ->
25+
{ok, Text} = dig([<<"text">>], Decoded),
26+
case binary:split(Text, <<"cmd&gt;">>) of
27+
[<<>>, <<"disable notify">>] ->
28+
direct_msg:send("notify disabled."),
29+
{noreply, false};
30+
[<<>>, <<"enable notify">>] ->
31+
direct_msg:send("notify enabled."),
32+
{noreply, true};
33+
[<<>>, _] ->
34+
direct_msg:send("error: undefined command."),
35+
{noreply, State};
36+
_ ->
37+
{noreply, State}
38+
end;
39+
{ok, NameBin} ->
40+
{ok, Text} = dig([<<"text">>], Decoded),
41+
case binary:match(Text, <<"えりっく">>) of
42+
{_, _} ->
43+
io:format("~s called you!!~n~p~n", [NameBin, Text]),
44+
direct_msg:send(binary_to_list(NameBin) ++ " called you!"),
45+
{noreply, State};
46+
nomatch ->
47+
{noreply, State}
48+
end;
49+
{error, _} ->
50+
{noreply, State}
51+
end.
2452

2553
handle_info(_Info, void) ->
2654
{noreply, void}.
@@ -32,3 +60,14 @@ terminate(_Reason, void) ->
3260
code_change(_OldVsn, void, _Extra) ->
3361
{ok, void}.
3462

63+
%% internal functions
64+
65+
dig([], Val) ->
66+
{ok, Val};
67+
dig([Key|Rest], {Data}) ->
68+
case lists:keyfind(Key, 1, Data) of
69+
{Key, Val} ->
70+
dig(Rest, Val);
71+
false ->
72+
{error, not_found}
73+
end.

0 commit comments

Comments
 (0)