1 |
|
%%%------------------------------------------------------------------- |
2 |
|
%%% @author Ludwik Bukowski <ludwik.bukowski@erlang-solutions.com> |
3 |
|
%%% @copyright (C) 2015, Ludwik Bukowski |
4 |
|
%%% @doc XEP-0202: Entity Time |
5 |
|
%%% @end |
6 |
|
%%%------------------------------------------------------------------- |
7 |
|
-module(mod_time). |
8 |
|
-author('ludwik.bukowski@erlang-solutions.com'). |
9 |
|
|
10 |
|
-behaviour(gen_mod). |
11 |
|
-behaviour(mongoose_module_metrics). |
12 |
|
|
13 |
|
-export([start/2]). |
14 |
|
-export([stop/1]). |
15 |
|
-export([supported_features/0]). |
16 |
|
-export([config_spec/0]). |
17 |
|
-export([process_local_iq/5]). |
18 |
|
|
19 |
|
-ignore_xref([process_local_iq/5]). |
20 |
|
|
21 |
|
-include("jlib.hrl"). |
22 |
|
-include("mongoose_config_spec.hrl"). |
23 |
|
|
24 |
|
-xep([{xep, 202}, {version, "2.0"}]). |
25 |
|
-xep([{xep, 82}, {version, "1.1.1"}]). |
26 |
|
|
27 |
|
-spec start(HostType :: mongooseim:host_type(), gen_mod:module_opts()) -> ok | {error, atom()}. |
28 |
|
start(HostType, #{iqdisc := IQDisc}) -> |
29 |
1 |
gen_iq_handler:add_iq_handler_for_domain(HostType, ?NS_TIME, ejabberd_local, |
30 |
|
fun ?MODULE:process_local_iq/5, #{}, IQDisc). |
31 |
|
|
32 |
|
-spec stop(HostType :: mongooseim:host_type()) -> ok | {error, not_registered}. |
33 |
|
stop(HostType) -> |
34 |
1 |
gen_iq_handler:remove_iq_handler_for_domain(HostType, ?NS_TIME, ejabberd_local). |
35 |
|
|
36 |
|
-spec supported_features() -> [atom()]. |
37 |
|
supported_features() -> |
38 |
1 |
[dynamic_domains]. |
39 |
|
|
40 |
|
-spec config_spec() -> mongoose_config_spec:config_section(). |
41 |
|
config_spec() -> |
42 |
186 |
#section{ |
43 |
|
items = #{<<"iqdisc">> => mongoose_config_spec:iqdisc()}, |
44 |
|
defaults = #{<<"iqdisc">> => one_queue} |
45 |
|
}. |
46 |
|
|
47 |
|
process_local_iq(Acc, _From, _To, #iq{type = set, sub_el = SubEl} = IQ, _Extra) -> |
48 |
:-( |
{Acc, IQ#iq{type = error, sub_el = [SubEl, mongoose_xmpp_errors:not_allowed()]}}; |
49 |
|
|
50 |
|
process_local_iq(Acc, _From, _To, #iq{type = get} = IQ, _Extra) -> |
51 |
1 |
{UTC, TZODiff} = calculate_time(), |
52 |
1 |
R = IQ#iq{type = result, |
53 |
|
sub_el = |
54 |
|
[#xmlel{name = <<"time">>, |
55 |
|
attrs = [{<<"xmlns">>, ?NS_TIME}], |
56 |
|
children = |
57 |
|
[#xmlel{name = <<"tzo">>, attrs = [], |
58 |
|
children = [#xmlcdata{content = list_to_binary(TZODiff)}]}, |
59 |
|
#xmlel{name = <<"utc">>, attrs = [], |
60 |
|
children = |
61 |
|
[#xmlcdata{content = list_to_binary(UTC)}]}]}]}, |
62 |
1 |
{Acc, R}. |
63 |
|
|
64 |
|
%% Internals |
65 |
|
calculate_time() -> |
66 |
1 |
SystemTime = erlang:system_time(second), |
67 |
1 |
UTCString = calendar:system_time_to_rfc3339(SystemTime, [{offset, "Z"}]), |
68 |
1 |
LocalString = calendar:system_time_to_rfc3339(SystemTime), |
69 |
1 |
DateTimeLength = length(UTCString) - 1, |
70 |
1 |
{UTCString, string:slice(LocalString, DateTimeLength)}. |