From 49b4008f204c409b9a40dc7dc17bd38239a09837 Mon Sep 17 00:00:00 2001 From: karl anderson Date: Wed, 11 Jul 2012 19:02:05 +0000 Subject: [PATCH] WHISTLE-1366: created API for downloading inbound faxes --- .../apps/crossbar/src/modules/cb_faxes.erl | 91 +++++++++++++++++-- 1 file changed, 85 insertions(+), 6 deletions(-) diff --git a/whistle_apps/apps/crossbar/src/modules/cb_faxes.erl b/whistle_apps/apps/crossbar/src/modules/cb_faxes.erl index af2c41fbdc7..2b1b57f2fcc 100644 --- a/whistle_apps/apps/crossbar/src/modules/cb_faxes.erl +++ b/whistle_apps/apps/crossbar/src/modules/cb_faxes.erl @@ -11,10 +11,11 @@ -module(cb_faxes). -export([init/0 - ,allowed_methods/0, allowed_methods/1, allowed_methods/2 - ,resource_exists/0, resource_exists/1, resource_exists/2 - ,validate/1, validate/2, validate/3 - ,get/1, get/2, get/3 + ,allowed_methods/0, allowed_methods/1, allowed_methods/2, allowed_methods/3 + ,resource_exists/0, resource_exists/1, resource_exists/2, resource_exists/3 + ,content_types_provided/4 + ,validate/1, validate/2, validate/3, validate/4 + ,get/1, get/2, get/3, get/4 ,put/1, put/2 ,post/1, post/2 ,delete/1, delete/2 @@ -22,6 +23,8 @@ -include_lib("crossbar/include/crossbar.hrl"). +-define(ATTACHMENT, <<"attachment">>). + -define(PVT_TYPE, <<"fax">>). -define(PVT_FUNS, [fun add_pvt_type/2 ,fun add_pvt_status/2 @@ -46,6 +49,7 @@ init() -> _ = crossbar_bindings:bind(<<"v1_resource.allowed_methods.faxes">>, ?MODULE, allowed_methods), _ = crossbar_bindings:bind(<<"v1_resource.resource_exists.faxes">>, ?MODULE, resource_exists), + _ = crossbar_bindings:bind(<<"v1_resource.content_types_provided.faxes">>, ?MODULE, content_types_provided), _ = crossbar_bindings:bind(<<"v1_resource.validate.faxes">>, ?MODULE, validate), _ = crossbar_bindings:bind(<<"v1_resource.execute.get.faxes">>, ?MODULE, get), _ = crossbar_bindings:bind(<<"v1_resource.execute.put.faxes">>, ?MODULE, put), @@ -62,6 +66,8 @@ init() -> -spec allowed_methods/0 :: () -> http_methods() | []. -spec allowed_methods/1 :: (path_token()) -> http_methods() | []. -spec allowed_methods/2 :: (path_token(), path_token()) -> http_methods() | []. +-spec allowed_methods/3 :: (path_token(), path_token(), path_token()) -> http_methods() | []. + allowed_methods() -> ['PUT']. @@ -70,11 +76,14 @@ allowed_methods(<<"incoming">>) -> allowed_methods(<<"outgoing">>) -> ['GET']. -allowed_methods(<<"incoming">>, _ID) -> +allowed_methods(<<"incoming">>, _Id) -> ['GET']; -allowed_methods(<<"outgoing">>, _ID) -> +allowed_methods(<<"outgoing">>, _Id) -> ['GET', 'POST', 'DELETE']. +allowed_methods(<<"incoming">>, _Id, ?ATTACHMENT) -> + ['GET']. + %%-------------------------------------------------------------------- %% @public %% @doc @@ -87,11 +96,36 @@ allowed_methods(<<"outgoing">>, _ID) -> -spec resource_exists/0 :: () -> 'true'. -spec resource_exists/1 :: (path_token()) -> 'true'. -spec resource_exists/2 :: (path_token(), path_token()) -> 'true'. +-spec resource_exists/3 :: (path_token(), path_token(), path_token()) -> 'true'. + resource_exists() -> true. resource_exists(<<"incoming">>) -> true; resource_exists(<<"outgoing">>) -> true. resource_exists(<<"incoming">>, _Id) -> true; resource_exists(<<"outgoing">>, _Id) -> true. +resource_exists(<<"incoming">>, _Id, ?ATTACHMENT) -> true. + +%%-------------------------------------------------------------------- +%% @private +%% @doc +%% Add content types accepted and provided by this module +%% +%% @end +%%-------------------------------------------------------------------- +-spec content_types_provided/4 :: (#cb_context{}, path_token(), path_token(), path_token()) -> #cb_context{}. +content_types_provided(#cb_context{req_verb = <<"get">>}=Context, <<"incoming">>, FaxId, ?ATTACHMENT) -> + case load_fax_meta(FaxId, Context) of + #cb_context{resp_status=success, doc=JObj} -> + case wh_json:get_keys(wh_json:get_value([<<"_attachments">>], JObj)) of + [] -> Context; + [Attachment|_] -> + CT = wh_json:get_value([<<"_attachments">>, Attachment, <<"content_type">>], JObj), + [Type, SubType] = binary:split(CT, <<"/">>), + Context#cb_context{content_types_provided=[{to_binary, [{Type, SubType}]}]} + end + end; +content_types_provided(Context, _, _, _) -> + Context. %%-------------------------------------------------------------------- %% @public @@ -105,6 +139,9 @@ resource_exists(<<"outgoing">>, _Id) -> true. %%-------------------------------------------------------------------- -spec validate/1 :: (#cb_context{}) -> #cb_context{}. -spec validate/2 :: (#cb_context{}, path_token()) -> #cb_context{}. +-spec validate/3 :: (#cb_context{}, path_token(), path_token()) -> #cb_context{}. +-spec validate/4 :: (#cb_context{}, path_token(), path_token(), path_token()) -> #cb_context{}. + validate(#cb_context{req_verb = <<"put">>}=Context) -> create(Context#cb_context{db_name=?WH_FAXES}). @@ -122,6 +159,9 @@ validate(#cb_context{req_verb = <<"post">>}=Context, <<"outgoing">>, Id) -> validate(#cb_context{req_verb = <<"delete">>}=Context, <<"outgoing">>, Id) -> read(Id, Context#cb_context{db_name=?WH_FAXES}). +validate(#cb_context{req_verb = <<"get">>}=Context, <<"inbound">>, Id, ?ATTACHMENT) -> + load_fax_binary(Id, Context). + %%-------------------------------------------------------------------- %% @public %% @doc @@ -133,12 +173,16 @@ validate(#cb_context{req_verb = <<"delete">>}=Context, <<"outgoing">>, Id) -> -spec get/1 :: (#cb_context{}) -> #cb_context{}. -spec get/2 :: (#cb_context{}, path_token()) -> #cb_context{}. -spec get/3 :: (#cb_context{}, path_token(), path_token()) -> #cb_context{}. +-spec get/4 :: (#cb_context{}, path_token(), path_token(), path_token()) -> #cb_context{}. + get(#cb_context{}=Context) -> Context. get(#cb_context{}=Context, _) -> Context. get(#cb_context{}=Context, _, _) -> Context. +get(#cb_context{}=Context, _, _, _) -> + Context. %%-------------------------------------------------------------------- %% @public @@ -208,6 +252,16 @@ create(#cb_context{req_data=Data}=Context) -> read(Id, Context) -> crossbar_doc:load(Id, Context). +%%-------------------------------------------------------------------- +%% @private +%% @doc +%% Load a fax document from the database +%% @end +%%-------------------------------------------------------------------- +-spec load_fax_meta/2 :: (ne_binary(), #cb_context{}) -> #cb_context{}. +load_fax_meta(FaxId, Context) -> + crossbar_doc:load(FaxId, Context). + %%-------------------------------------------------------------------- %% @private %% @doc @@ -245,6 +299,31 @@ incoming_summary(#cb_context{}=Context) -> ,fun normalize_incoming_view_results/2 ). +%%-------------------------------------------------------------------- +%% @private +%% @doc +%% Load the binary attachment of a fax doc +%% @end +%%-------------------------------------------------------------------- +-spec load_fax_binary/2 :: (path_token(), #cb_context{}) -> #cb_context{}. +load_fax_binary(FaxId, #cb_context{resp_headers=RespHeaders}=Context) -> + case load_fax_meta(FaxId, Context) of + #cb_context{resp_status=success, doc=JObj} -> + FaxMeta = wh_json:get_value([<<"_attachments">>], JObj), + case wh_json:get_keys(FaxMeta) of + [] -> crossbar_util:response_bad_identifier(FaxId, Context); + [Attachment|_] -> + Context1 = crossbar_doc:load_attachment(JObj, Attachment, Context), + Context1#cb_context{resp_headers = [{<<"Content-Disposition">>, <<"attachment; filename=", Attachment/binary>>} + ,{<<"Content-Type">>, wh_json:get_value([Attachment, <<"content_type">>], FaxMeta)} + ,{<<"Content-Length">>, wh_json:get_value([Attachment, <<"length">>], FaxMeta)} + | RespHeaders + ] + ,resp_etag=undefined} + end; + Context1 -> Context1 + end. + %%-------------------------------------------------------------------- %% @private %% @doc