PageRenderTime 191ms CodeModel.GetById 80ms app.highlight 17ms RepoModel.GetById 74ms 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
 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.