PageRenderTime 32ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/ucengine/src/models/uce_presence.erl

http://github.com/AF83/ucengine
Erlang | 141 lines | 89 code | 15 blank | 37 comment | 0 complexity | b4801ed7cbdfa81e14a4c1c67a9b5a05 MD5 | raw file
  1. %%
  2. %% U.C.Engine - Unified Collaboration Engine
  3. %% Copyright (C) 2011 af83
  4. %%
  5. %% This program is free software: you can redistribute it and/or modify
  6. %% it under the terms of the GNU Affero General Public License as published by
  7. %% the Free Software Foundation, either version 3 of the License, or
  8. %% (at your option) any later version.
  9. %%
  10. %% This program is distributed in the hope that it will be useful,
  11. %% but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. %% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. %% GNU Affero General Public License for more details.
  14. %%
  15. %% You should have received a copy of the GNU Affero General Public License
  16. %% along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. %%
  18. -module(uce_presence).
  19. % public api
  20. -export([add/2,
  21. get/2,
  22. delete/2,
  23. assert/3,
  24. add_stream/2,
  25. remove_stream/2,
  26. join/3,
  27. leave/3]).
  28. -include("uce.hrl").
  29. -include_lib("stdlib/include/qlc.hrl").
  30. %
  31. % Add presence
  32. % Attach a presence to the user
  33. %
  34. -spec add(domain(), presence()) -> {ok, sid()}.
  35. add(Domain, #uce_presence{id=none}=Presence) ->
  36. add(Domain, Presence#uce_presence{id=utils:random()});
  37. add(Domain, #uce_presence{last_activity=0}=Presence) ->
  38. add(Domain, Presence#uce_presence{last_activity=utils:now()});
  39. add(Domain, #uce_presence{timeout=0}=Presence) ->
  40. add(Domain, Presence#uce_presence{timeout=config:get(presence_timeout)});
  41. add(Domain, #uce_presence{id=Sid, user=Uid}=Presence) ->
  42. UPid = case gproc:lookup_local_name({Domain, uid, Uid}) of
  43. undefined ->
  44. {ok, NewPid} = uce_vhost:add_user(Domain, Uid),
  45. NewPid;
  46. Pid ->
  47. Pid
  48. end,
  49. ok = gen_server:call(UPid, {add_presence, Presence}),
  50. {ok, Sid}.
  51. %
  52. % Get presence
  53. %
  54. -spec get(domain(), sid()) -> {ok, presence()} | {error, not_found}.
  55. get(Domain, Sid) ->
  56. call_if_proc_found(Domain, Sid, {get_presence, Sid}).
  57. %
  58. % Delete presence
  59. %
  60. -spec delete(domain(), sid()) -> {ok, deleted} | {error, not_found}.
  61. delete(Domain, Sid) ->
  62. cast_if_proc_found(Domain, Sid, {delete_presence, Sid}),
  63. {ok, deleted}.
  64. -spec assert(domain(), uid(), sid()) -> {ok, true} | erlang:throw({error, unauthorized}).
  65. assert(Domain, Uid, Sid) ->
  66. case check(Domain, Uid, Sid) of
  67. {ok, true} ->
  68. {ok, true};
  69. {ok, false} ->
  70. throw({error, unauthorized})
  71. end.
  72. -spec join(domain(), sid(), meeting_id()) -> {ok, updated}.
  73. join(Domain, Sid, Meeting) ->
  74. {ok, Presence} = get(Domain, Sid),
  75. case lists:member(Meeting, Presence#uce_presence.meetings) of
  76. true ->
  77. {ok, updated};
  78. false ->
  79. Meetings = [Meeting|Presence#uce_presence.meetings],
  80. update(Domain, Presence#uce_presence{meetings=Meetings})
  81. end.
  82. -spec leave(domain(), sid(), meeting_id()) -> {ok, updated}.
  83. leave(Domain, Sid, Meeting) ->
  84. {ok, Record} = get(Domain, Sid),
  85. Meetings = lists:delete(Meeting, Record#uce_presence.meetings),
  86. update(Domain, Record#uce_presence{meetings=Meetings}).
  87. %
  88. % Add active stream connection to prevent timeout
  89. %
  90. -spec add_stream(domain(), sid()) -> ok.
  91. add_stream(Domain, Sid) ->
  92. cast_if_proc_found(Domain, Sid, {add_stream, Sid}).
  93. -spec remove_stream(domain(), sid()) -> ok.
  94. remove_stream(Domain, Sid) ->
  95. cast_if_proc_found(Domain, Sid, {remove_stream, Sid}).
  96. %
  97. % Private function
  98. %
  99. %
  100. % Update presence
  101. %
  102. -spec update(domain(), presence()) -> {ok, presence()} | {error, not_found}.
  103. update(Domain, #uce_presence{id=Sid} = Presence) ->
  104. call_if_proc_found(Domain, Sid, {update_presence, Presence}).
  105. check(Domain, Uid, Sid) ->
  106. case get(Domain, Sid) of
  107. {ok, #uce_presence{user=Uid} = Presence} ->
  108. {ok, _Presence} = update(Domain, Presence#uce_presence{last_activity=utils:now()}),
  109. {ok, true};
  110. {error, not_found} ->
  111. {ok, false}
  112. end.
  113. call_if_proc_found(Domain, Sid, Call) ->
  114. case gproc:lookup_local_name({Domain, sid, Sid}) of
  115. undefined ->
  116. {error, not_found};
  117. Pid ->
  118. gen_server:call(Pid, Call)
  119. end.
  120. cast_if_proc_found(Domain, Sid, Call) ->
  121. case gproc:lookup_local_name({Domain, sid, Sid}) of
  122. undefined ->
  123. {error, not_found};
  124. Pid ->
  125. ok = gen_server:cast(Pid, Call)
  126. end.