PageRenderTime 33ms CodeModel.GetById 22ms app.highlight 8ms RepoModel.GetById 1ms app.codeStats 1ms

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