diff --git a/lib/kolab_wopi/chwala.ex b/lib/kolab_wopi/chwala.ex index ea77aef..e5f0461 100644 --- a/lib/kolab_wopi/chwala.ex +++ b/lib/kolab_wopi/chwala.ex @@ -1,205 +1,206 @@ defmodule KolabWopi.Chwala do @moduledoc """ A Chwala web service client. See https://docs.kolab.org/about/chwala/ """ use HTTPoison.Base require Logger def start_link do GenServer.start_link(__MODULE__, []) end @doc """ Fetches document metadata from Chwala Args: * `token` - Chwala access token * `file_id` - File identifier Returns {:ok, result} if the request is successful, {:error, code, reason} otherwise """ def document_info(token, file_id) do # Method: GET # Params: # method: "document_info" # id: file_id # token: token # # In case of an error response body will be: # [code: 403, reason: "Invalid session", status: "ERROR"] # on success it will be: # [status: "OK", result: []] # TODO: this request is not yet implemented in Chwala params = %{ method: "document_info", token: token, id: file_id, } response_handler(get(base_url, [], params: params)) end @doc """ Fetches document content from Chwala Args: * `token` - Chwala access token * `file_id` - File identifier * `pid` - The process that will process the data stream Returns {:ok, HTTPoison.AsyncResponse} if the request is successful, {:error, reason} otherwise """ def document_get(token, file_id, pid) do # Method: GET # Params: # method: "document" # id: file_id # token: token # # In case of an error http code will be 500 # On success response body will contain file content params = %{ method: "document", token: token, id: file_id, } get(base_url, [], [params: params, stream_to: pid]) end @doc """ Updates document content in Chwala Args: * `token` - Chwala access token * `file_id` - File identifier * `body` - File content * `resource` - Optional request object returned by this function * in streaming mode * `close` - Closes connection (end streaming) Returns {:ok, result} if the request is successful, {:error, code, reason} on error or {:continue, resource} when streaming body """ def document_put(token, file_id, body, resource, close) when is_nil(resource) do # Method: PUT # Params: # method: "document" # id: file_id # token: token # # In case of an error response body will be e.g.: # [code: 403, reason: "Invalid session", status: "ERROR"] # On success it will be: # [status: "OK", result: []] params = %{ method: "document", token: token, id: file_id, } # Unfortunately HTTPoison does not have a way to stream requests # https://github.com/edgurgel/httpoison/issues/97 if close do response_handler(put(base_url, body, [], params: params)) else url = base_url <> "?" <> URI.encode_query(params) case :hackney.request(:put, base_url, [], :stream, []) do {:error, reason} -> {:error, 500, reason} {:ok, resource} -> document_put(token, file_id, body, resource, false) {:ok, status, _headers} -> {:error, status, "Unknown error"} {:ok, _status, _headers, resource} -> {:ok, body} = :hackney.body(resource) response_handler({:ok, process_response_body(body)}) end end end # continue sending document body started with "initial" document_put() def document_put(_token, _file_id, body, resource, close) when not is_nil(resource) do case :hackney.send_body(resource, body) do {:error, reason} -> {:error, 500, reason} _ -> if close do case :hackney.start_response(resource) do {:error, reason} -> {:error, 500, reason} {:ok, _status, _headers, resource} -> {:ok, body} = :hackney.body(resource) response_handler({:ok, process_response_body(body)}) end else {:continue, resource} end end end @doc """ Renames the document Args: * `token` - Chwala access token * `file_id` - File identifier * `name` - New file name Returns ??? """ def document_rename(token, file_id, name) do # Method: POST # Params: # method: "document_rename" # id: file_id # token: token # name: name # # In case of an error response body will be e.g.: # [code: 403, reason: "Invalid session", status: "ERROR"] # On success it will be: # [status: "OK", result: []] # TODO: not implemented in Chwala yet end # Decodes JSON response defp process_response_body(body) do + Logger.debug body body |> Poison.decode! |> Enum.map(fn({k, v}) -> {String.to_atom(k), v} end) end # Returns the base URL for the chwala implementation defp base_url() do Application.get_env(:kolab_wopi, :chwala_base_url) end # Chwala response handler, catches error responses defp response_handler({:error, reason}) do {:error, 500, reason} end defp response_handler({:ok, %{:status_code => 200} = response}) do # get response body, it's already JSON-decoded response = response.body if response[:status] != "OK" do {:error, response[:code], response[:reason]} else {:ok, response[:result]} end end defp response_handler({:ok, response}) do {:error, response.status_code, ""} end end