Permalink
Browse files

KAZOO-587: support multiple users hotdesking via a single endpoint

  • Loading branch information...
1 parent ec04d2b commit 56bc64800c158a5a3c546f1322fd0aef3e00b18c @k-anderson k-anderson committed Feb 25, 2013
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -2,35 +2,17 @@
"_id": "_design/cf_attributes",
"language": "javascript",
"views": {
- "caller_id": {
- "map": "function(doc) { if (!doc.caller_id || doc.pvt_deleted) return; emit(doc._id, doc.caller_id); }"
- },
- "caller_id_options": {
- "map": "function(doc) { if (!doc.caller_id_options || doc.pvt_deleted) return; emit(doc._id, doc.caller_id_options); }"
- },
- "media_options": {
- "map": "function(doc) { if (!doc.media || doc.pvt_deleted) return; emit(doc._id, doc.media); }"
- },
- "moh_options": {
- "map": "function(doc) { if (!doc.music_on_hold || doc.pvt_deleted) return; emit(doc._id, doc.music_on_hold); }"
- },
- "call_forward": {
- "map": "function(doc) { if (!doc.call_forward || !doc.call_forward.enabled || doc.pvt_deleted) return; emit(doc._id, doc.call_forward); }"
- },
- "owner": {
- "map": "function(doc) { if (!doc.owner_id || doc.pvt_deleted) return; emit(doc._id, doc.owner_id); }"
+ "temporal_rules": {
+ "map": "function(doc) { if (doc.pvt_type != 'temporal_rule' || doc.pvt_deleted) return; emit(doc._id, null); }"
},
"owned": {
- "map": "function(doc) { if (!doc.owner_id || doc.pvt_deleted) return; emit([doc.owner_id, doc.pvt_type], doc._id); }"
+ "map": "function(doc) {if (doc.pvt_deleted) return; if (doc.pvt_type == 'user' && doc.hotdesk && doc.hotdesk.enabled && doc.hotdesk.endpoint_ids) {doc.hotdesk.endpoint_ids.forEach(function (endpoint_id) {emit([doc._id, 'device'], endpoint_id)});} else if (doc.owner_id) {emit([doc.owner_id, doc.pvt_type], doc._id);}}"
},
- "friendly_name": {
- "map": "function(doc) { if ((doc.pvt_type != 'user' && doc.pvt_type != 'device') || doc.pvt_deleted) return; if (doc.pvt_type == 'user') emit(doc._id, {'friendly_name': doc.first_name + ' ' + doc.last_name}); else emit(doc._id, {'friendly_name': doc.name}); }"
+ "owner": {
+ "map": "function(doc) {if (doc.pvt_deleted) return;if (doc.pvt_type == 'user' && doc.hotdesk && doc.hotdesk.enabled && doc.hotdesk.endpoint_ids) {doc.hotdesk.endpoint_ids.forEach(function (endpoint_id) {emit(endpoint_id, doc._id)});} else if (doc.owner_id) {emit(doc._id, doc.owner_id);}}"
},
"hotdesk_id": {
- "map": "function(doc) { if (!doc.hotdesk || doc.pvt_deleted) return; emit(doc.hotdesk.id, {'owner_id':doc._id, 'hotdesk':doc.hotdesk}); }"
- },
- "temporal_rules": {
- "map": "function(doc) { if (doc.pvt_type != 'temporal_rule' || doc.pvt_deleted) return; emit(doc._id, null); }"
+ "map": "function(doc) { if (!doc.hotdesk || doc.pvt_deleted) return; emit(doc.hotdesk.id, null); }"
},
"mailbox_number": {
"map": "function(doc) { if (doc.pvt_type != 'vmbox' || doc.pvt_deleted) return; emit(doc.mailbox, null); }"
@@ -42,8 +24,8 @@
"map": "function(doc) { if (doc.pvt_type != 'vmbox' || !doc.owner_id || doc.pvt_deleted) return; doc.messages.forEach(function (message) { if (message.folder != 'deleted') emit([doc.owner_id, message.folder], 1); }); }",
"reduce": "function (key, values, rereduce) { return sum(values) }"
},
- "sip_credentials": {
- "map": "function(doc) { if (typeof doc.sip !== 'undefined' && ! doc.pvt_deleted) { var sip = JSON.parse(JSON.stringify(doc.sip)); sip.authorizing_id = doc._id; sip.authorizing_type = doc.pvt_type; emit(sip.username, sip); } else if (doc.pvt_type === 'sys_info' && ! doc.pvt_deleted) { for (i in doc.servers) {var auth = doc.servers[i].auth; var sip = {'password': auth.auth_password, 'username': auth.auth_user, 'method': auth.auth_method || 'password', 'invite_format': doc.servers[i].options.inbound_format || 'e164'}; sip.authorizing_id = doc._id; sip.authorizing_type = doc.pvt_type; emit(sip.username, sip);}}}"
+ "sip_username": {
+ "map": "function(doc) {if (doc.sip && doc.sip.username && doc.sip.method == 'password' && !doc.pvt_deleted) {emit(doc.sip.username, null);} else if (doc.pvt_type === 'sys_info' && !doc.pvt_deleted) {for (i in doc.servers) {var auth = doc.servers[i].auth; if (auth.auth_user && auth.auth_method == 'password') {emit(auth.auth_user, null);}}}}"
}
}
}
@@ -16,11 +16,7 @@
-export([moh_attributes/2, moh_attributes/3]).
-export([owner_id/1, owner_id/2]).
-export([presence_id/1, presence_id/2]).
-
--export([owned_by/2, owned_by/3, fetch_owned_by/2, fetch_owned_by/3]).
-
-
--export([flush_attributes/1]).
+-export([owned_by/2, owned_by/3]).
%%-----------------------------------------------------------------------------
%% @public
@@ -330,36 +326,32 @@ presence_id(Endpoint, Call) ->
%% @doc
%% @end
%%-----------------------------------------------------------------------------
--spec owned_by(api_binary(), whapps_call:call()) -> list().
--spec owned_by(api_binary(), atom() | string() | ne_binary(), whapps_call:call()) -> list().
+-spec owned_by(api_binary(), whapps_call:call()) -> api_binaries().
+-spec owned_by(api_binary(), ne_binary(), whapps_call:call()) -> api_binaries().
--spec fetch_owned_by(api_binary(), whapps_call:call()) ->
- list().
--spec fetch_owned_by(api_binary(), atom() | string() | ne_binary(), whapps_call:call()) ->
- list().
-
-owned_by(undefined, _) -> [];
+owned_by('undefined', _) -> [];
owned_by(OwnerId, Call) ->
- Attributes = fetch_attributes(owned, Call),
- [V || {[I, _], V} <- Attributes, I =:= OwnerId].
-
-owned_by(undefined, _, _) -> [];
-owned_by(OwnerId, false, Call) ->
- wh_cache:erase_local(?CALLFLOW_CACHE, {?MODULE, whapps_call:account_db(Call), owned}),
- owned_by(OwnerId, Call);
-owned_by(OwnerId, Attribute, Call) when not is_binary(Attribute) ->
- owned_by(OwnerId, wh_util:to_binary(Attribute), Call);
-owned_by(OwnerId, Attribute, Call) ->
- Attributes = fetch_attributes(owned, Call),
- [V || {[I, T], V} <- Attributes, I =:= OwnerId, T =:= Attribute].
-
-fetch_owned_by(OwnerId, Call) ->
- wh_cache:erase_local(?CALLFLOW_CACHE, {?MODULE, whapps_call:account_db(Call), owned}),
- owned_by(OwnerId, Call).
-
-fetch_owned_by(OwnerId, Attribute, Call) ->
- wh_cache:erase_local(?CALLFLOW_CACHE, {?MODULE, whapps_call:account_db(Call), owned}),
- owned_by(OwnerId, Attribute, Call).
+ AccountDb = whapps_call:account_db(Call),
+ ViewOptions = [{'startkey', [OwnerId]}
+ ,{'endkey', [OwnerId, wh_json:new()]}
+ ],
+ case couch_mgr:get_results(AccountDb, <<"cf_attributes/owned">>, ViewOptions) of
+ {'ok', JObjs} -> [wh_json:get_value(<<"value">>, JObj) || JObj <- JObjs];
+ {'error', _R} ->
+ lager:warning("unable to find documents owned by ~s: ~p", [OwnerId, _R]),
+ []
+ end.
+
+owned_by('undefined', _, _) -> [];
+owned_by(OwnerId, Type, Call) ->
+ AccountDb = whapps_call:account_db(Call),
+ ViewOptions = [{'key', [OwnerId, Type]}],
+ case couch_mgr:get_results(AccountDb, <<"cf_attributes/owned">>, ViewOptions) of
+ {'ok', JObjs} -> [wh_json:get_value(<<"value">>, JObj) || JObj <- JObjs];
+ {'error', _R} ->
+ lager:warning("unable to find ~s documents owned by ~s: ~p", [Type, OwnerId, _R]),
+ []
+ end.
%%-----------------------------------------------------------------------------
%% @private
@@ -383,39 +375,3 @@ get_cid_or_default(Attribute, Property, Endpoint) ->
undefined -> wh_json:get_ne_value([<<"default">>, Property], Endpoint);
Value -> Value
end.
-
-%%-----------------------------------------------------------------------------
-%% @private
-%% @doc
-%% @end
-%%-----------------------------------------------------------------------------
--spec fetch_attributes(atom(), whapps_call:call() | api_binary()) -> wh_proplist().
-fetch_attributes(_Attribute, undefined) -> [];
-fetch_attributes(Attribute, ?NE_BINARY = AccountDb) ->
- case wh_cache:peek_local(?CALLFLOW_CACHE, {?MODULE, AccountDb, Attribute}) of
- {ok, Attributes} -> Attributes;
- {error, not_found} ->
- case couch_mgr:get_all_results(AccountDb, <<"cf_attributes/", (wh_util:to_binary(Attribute))/binary>>) of
- {ok, JObjs} ->
- Props = [{wh_json:get_value(<<"key">>, JObj), wh_json:get_value(<<"value">>, JObj)}
- || JObj <- JObjs],
- %% TODO: figure out a way to include the origin of the attributes...
- CacheProps = [{expires, 900}],
- wh_cache:store_local(?CALLFLOW_CACHE, {?MODULE, AccountDb, Attribute}, Props, CacheProps),
- Props;
- {error, _R} ->
- lager:warning("unable to fetch attribute ~s: ~p", [Attribute, _R]),
- []
- end
- end;
-fetch_attributes(Attribute, Call) ->
- fetch_attributes(Attribute, whapps_call:account_db(Call)).
-
--spec flush_attributes(ne_binary()) -> any().
-flush_attributes(AccountDb) ->
- Keys = wh_cache:filter_local(?CALLFLOW_CACHE
- ,fun({?MODULE, AcctDb, _}, _) when AcctDb =:= AccountDb -> true;
- (_,_) -> false
- end
- ),
- [wh_cache:erase_local(?CALLFLOW_CACHE, Key) || Key <- Keys].
@@ -129,7 +129,7 @@ merge_attributes([?CF_ATTR_LOWER_KEY|Keys], Account, Endpoint, Owner) ->
true ->
merge_attributes(Keys, Account, Endpoint, Owner);
false ->
- Update = wh_json:set_value(FullKey, OwnerAttr, Endpoint),
+ Update = wh_json:set_value(FullKey, OwnerAttr, Endpoint),
merge_attributes(Keys, Account, Update, Owner)
end;
merge_attributes([<<"name">> = Key|Keys], Account, Endpoint, Owner) ->
@@ -164,7 +164,7 @@ merge_call_restrictions([Key|Keys], Account, Endpoint, Owner) ->
case wh_json:get_value([<<"call_restriction">>, Key, <<"action">>], Account) =:= <<"deny">>
orelse wh_json:get_value([<<"call_restriction">>, Key, <<"action">>], Owner) =:= <<"deny">>
of
- true ->
+ true ->
Update = wh_json:set_value([<<"call_restriction">>, Key, <<"action">>], <<"deny">>, Endpoint),
merge_call_restrictions(Keys, Account, Update, Owner);
false ->
Oops, something went wrong.

0 comments on commit 56bc648

Please sign in to comment.