/ucengine/src/models/uce_presence.erl
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 20% public api 21-export([add/2, 22 get/2, 23 delete/2, 24 assert/3, 25 add_stream/2, 26 remove_stream/2, 27 join/3, 28 leave/3]). 29 30-include("uce.hrl"). 31-include_lib("stdlib/include/qlc.hrl"). 32 33% 34% Add presence 35% Attach a presence to the user 36% 37-spec add(domain(), presence()) -> {ok, sid()}. 38add(Domain, #uce_presence{id=none}=Presence) -> 39 add(Domain, Presence#uce_presence{id=utils:random()}); 40add(Domain, #uce_presence{last_activity=0}=Presence) -> 41 add(Domain, Presence#uce_presence{last_activity=utils:now()}); 42add(Domain, #uce_presence{timeout=0}=Presence) -> 43 add(Domain, Presence#uce_presence{timeout=config:get(presence_timeout)}); 44add(Domain, #uce_presence{id=Sid, user=Uid}=Presence) -> 45 UPid = case gproc:lookup_local_name({Domain, uid, Uid}) of 46 undefined -> 47 {ok, NewPid} = uce_vhost:add_user(Domain, Uid), 48 NewPid; 49 Pid -> 50 Pid 51 end, 52 ok = gen_server:call(UPid, {add_presence, Presence}), 53 {ok, Sid}. 54 55% 56% Get presence 57% 58-spec get(domain(), sid()) -> {ok, presence()} | {error, not_found}. 59get(Domain, Sid) -> 60 call_if_proc_found(Domain, Sid, {get_presence, Sid}). 61 62% 63% Delete presence 64% 65-spec delete(domain(), sid()) -> {ok, deleted} | {error, not_found}. 66delete(Domain, Sid) -> 67 cast_if_proc_found(Domain, Sid, {delete_presence, Sid}), 68 {ok, deleted}. 69 70-spec assert(domain(), uid(), sid()) -> {ok, true} | erlang:throw({error, unauthorized}). 71assert(Domain, Uid, Sid) -> 72 case check(Domain, Uid, Sid) of 73 {ok, true} -> 74 {ok, true}; 75 {ok, false} -> 76 throw({error, unauthorized}) 77 end. 78 79-spec join(domain(), sid(), meeting_id()) -> {ok, updated}. 80join(Domain, Sid, Meeting) -> 81 {ok, Presence} = get(Domain, Sid), 82 case lists:member(Meeting, Presence#uce_presence.meetings) of 83 true -> 84 {ok, updated}; 85 false -> 86 Meetings = [Meeting|Presence#uce_presence.meetings], 87 update(Domain, Presence#uce_presence{meetings=Meetings}) 88 end. 89 90-spec leave(domain(), sid(), meeting_id()) -> {ok, updated}. 91leave(Domain, Sid, Meeting) -> 92 {ok, Record} = get(Domain, Sid), 93 Meetings = lists:delete(Meeting, Record#uce_presence.meetings), 94 update(Domain, Record#uce_presence{meetings=Meetings}). 95 96% 97% Add active stream connection to prevent timeout 98% 99-spec add_stream(domain(), sid()) -> ok. 100add_stream(Domain, Sid) -> 101 cast_if_proc_found(Domain, Sid, {add_stream, Sid}). 102 103-spec remove_stream(domain(), sid()) -> ok. 104remove_stream(Domain, Sid) -> 105 cast_if_proc_found(Domain, Sid, {remove_stream, Sid}). 106 107% 108% Private function 109% 110 111% 112% Update presence 113% 114-spec update(domain(), presence()) -> {ok, presence()} | {error, not_found}. 115update(Domain, #uce_presence{id=Sid} = Presence) -> 116 call_if_proc_found(Domain, Sid, {update_presence, Presence}). 117 118check(Domain, Uid, Sid) -> 119 case get(Domain, Sid) of 120 {ok, #uce_presence{user=Uid} = Presence} -> 121 {ok, _Presence} = update(Domain, Presence#uce_presence{last_activity=utils:now()}), 122 {ok, true}; 123 {error, not_found} -> 124 {ok, false} 125 end. 126 127call_if_proc_found(Domain, Sid, Call) -> 128 case gproc:lookup_local_name({Domain, sid, Sid}) of 129 undefined -> 130 {error, not_found}; 131 Pid -> 132 gen_server:call(Pid, Call) 133 end. 134 135cast_if_proc_found(Domain, Sid, Call) -> 136 case gproc:lookup_local_name({Domain, sid, Sid}) of 137 undefined -> 138 {error, not_found}; 139 Pid -> 140 ok = gen_server:cast(Pid, Call) 141 end.