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

/ucengine/src/controllers/file_controller.erl

http://github.com/AF83/ucengine
Erlang | 129 lines | 90 code | 14 blank | 25 comment | 0 complexity | a76f6be0e8976f983affceb2b16c3ad7 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(file_controller).
  19. -export([init/0, add/4, list/4, get/4, delete/4]).
  20. -include("uce.hrl").
  21. -include_lib("kernel/include/file.hrl").
  22. init() ->
  23. [#uce_route{method='POST',
  24. path=["file", meeting],
  25. callback={?MODULE, add,
  26. [{"uid", required, string},
  27. {"sid", required, string},
  28. {"content", required, file},
  29. {"metadata", [], dictionary},
  30. {"forceContentType", "application/json", string}]}},
  31. #uce_route{method='GET',
  32. path=["file", meeting],
  33. callback={?MODULE, list,
  34. [{"uid", required, string},
  35. {"sid", required, string},
  36. {"order", asc, atom}]}},
  37. #uce_route{method='GET',
  38. path=["file", meeting, id],
  39. callback={?MODULE, get,
  40. [{"uid", required, string},
  41. {"sid", required, string}]}},
  42. #uce_route{method='DELETE',
  43. path=["file", meeting, id],
  44. callback={?MODULE, delete,
  45. [{"uid", required, string},
  46. {"sid", required, string}]}}].
  47. add(Domain, [{meeting, Meeting}], [Uid, Sid, FileUploaded, Metadata, ForceContentType], _) ->
  48. {ok, true} = uce_presence:assert(Domain, Uid, Sid),
  49. {ok, true} = uce_access:assert(Domain, Uid, Meeting, "file", "add"),
  50. {ok, Id} = uce_file:add(Domain, #uce_file{location=Meeting,
  51. name=FileUploaded#file_upload.filename,
  52. uri=FileUploaded#file_upload.uri,
  53. datetime=utils:now(),
  54. metadata={struct, Metadata}}),
  55. {ok, File} = uce_file:get(Domain, Id),
  56. {ok, FileInfo} = file:read_file_info(get_path(File#uce_file.uri)),
  57. EventMetadata = utils:proplist_merge([{"id", Id},
  58. {"domain", Domain},
  59. {"name", File#uce_file.name},
  60. {"size", integer_to_list(FileInfo#file_info.size)},
  61. {"mime", File#uce_file.mime}], Metadata),
  62. uce_event:add(Domain,
  63. #uce_event{id=none,
  64. location=Meeting,
  65. from=Uid,
  66. type="internal.file.add",
  67. metadata={struct, EventMetadata}}),
  68. %% In old webbrowser we cannot send file with xmlhttprequest, so we send a
  69. %% file via an iframe, and if we reply with a content-type
  70. %% 'application/json', browser show a popup allowing users to select the
  71. %% correct programm to show it. This is very annoying.
  72. case ForceContentType of
  73. "application/json" ->
  74. json_helpers:created(Domain, Id);
  75. ContentType ->
  76. json_helpers:format_response(201, ContentType, cors_helpers:format_cors_headers(Domain), {struct, [{result, Id}]})
  77. end.
  78. list(Domain, [{meeting, Meeting}], [Uid, Sid, Order], _) ->
  79. {ok, true} = uce_presence:assert(Domain, Uid, Sid),
  80. {ok, true} = uce_access:assert(Domain, Uid, Meeting, "file", "list"),
  81. {ok, Files} = uce_file:list(Domain, Meeting, Order),
  82. json_helpers:json(Domain, Files).
  83. %%
  84. %% @doc Get real path from encoded uri of record uce_file
  85. %% @spec (Uri::list) -> list
  86. %%
  87. get_path(Uri) ->
  88. re:replace(Uri, "file\:\/\/", "", [{return, list}]).
  89. get(Domain, [{meeting, Meeting}, {id, Id}], [Uid, Sid], _) ->
  90. NormalizedId = unicode_helpers:normalize_unicode(Id),
  91. {ok, true} = uce_presence:assert(Domain, Uid, Sid),
  92. {ok, true} = uce_access:assert(Domain, Uid, Meeting, "file", "get", [{"id", Id}]),
  93. {ok, File} = uce_file:get(Domain, NormalizedId),
  94. Path = get_path(File#uce_file.uri),
  95. case file:read_file(Path) of
  96. {error, Reason} ->
  97. throw({error, Reason});
  98. {ok, Content} ->
  99. http_helpers:download(File#uce_file.name, Content)
  100. end.
  101. delete(Domain, [{meeting, Meeting}, {id, Id}], [Uid, Sid], _) ->
  102. NormalizedId = unicode_helpers:normalize_unicode(Id),
  103. {ok, true} = uce_presence:assert(Domain, Uid, Sid),
  104. {ok, true} = uce_access:assert(Domain, Uid, Meeting, "file", "delete", [{"id", Id}]),
  105. {ok, File} = uce_file:get(Domain, NormalizedId),
  106. {ok, deleted} = uce_file:delete(Domain, NormalizedId),
  107. uce_event:add(Domain,
  108. #uce_event{id=none,
  109. location=Meeting,
  110. from=Uid,
  111. type="internal.file.delete",
  112. metadata=[
  113. {"id", Id},
  114. {"name", File#uce_file.name}]}),
  115. json_helpers:ok(Domain).