From 372159570b75e986c0320e55f403f994f4925241 Mon Sep 17 00:00:00 2001 From: Pancham Mehrunkar Date: Thu, 26 Mar 2020 01:53:38 -0700 Subject: [PATCH] create new UploadedVideo struct --- lib/cloudex/cloudinary_api.ex | 24 ++++++++--- lib/cloudex/uploaded_video.ex | 80 +++++++++++++++++++++++++++++++++++ test/cloudex/cloudex_test.exs | 37 +++++++++++++++- 3 files changed, 132 insertions(+), 9 deletions(-) create mode 100644 lib/cloudex/uploaded_video.ex diff --git a/lib/cloudex/cloudinary_api.ex b/lib/cloudex/cloudinary_api.ex index eb55962..c2076a9 100644 --- a/lib/cloudex/cloudinary_api.ex +++ b/lib/cloudex/cloudinary_api.ex @@ -20,7 +20,7 @@ defmodule Cloudex.CloudinaryApi do or {:error, "reason"} """ @spec upload(String.t() | {:ok, String.t()}, map) :: - {:ok, Cloudex.UploadedImage.t()} | {:error, any} + {:ok, Cloudex.UploadedImage.t()} | {:ok, %Cloudex.UploadedVideo{}} | {:error, any} def upload(item, opts \\ %{}) def upload({:ok, item}, opts) when is_binary(item), do: upload(item, opts) @@ -77,13 +77,20 @@ defmodule Cloudex.CloudinaryApi do @doc """ Converts the json result from cloudinary to a %UploadedImage{} struct """ - @spec json_result_to_struct(map, String.t()) :: %Cloudex.UploadedImage{} + @spec json_result_to_struct(map, String.t()) :: + %Cloudex.UploadedImage{} | %Cloudex.UploadedVideo{} def json_result_to_struct(result, source) do converted = Enum.map(result, fn {k, v} -> {String.to_atom(k), v} end) ++ [source: source] - struct(%Cloudex.UploadedImage{}, converted) + + if result["resource_type"] == "video" do + struct(%Cloudex.UploadedVideo{}, converted) + else + struct(%Cloudex.UploadedImage{}, converted) + end end - @spec upload_file(String.t(), map) :: {:ok, %Cloudex.UploadedImage{}} | {:error, any} + @spec upload_file(String.t(), map) :: + {:ok, %Cloudex.UploadedImage{}} | {:ok, %Cloudex.UploadedVideo{}} | {:error, any} defp upload_file(file_path, opts) do options = opts @@ -103,7 +110,8 @@ defmodule Cloudex.CloudinaryApi do Map.delete(opts, :resource_type) end - @spec upload_url(String.t(), map) :: {:ok, %Cloudex.UploadedImage{}} | {:error, any} + @spec upload_url(String.t(), map) :: + {:ok, %Cloudex.UploadedImage{}} | {:ok, %Cloudex.UploadedVideo{}} | {:error, any} defp upload_url(url, opts) do opts |> Map.merge(%{file: url}) @@ -153,7 +161,8 @@ defmodule Cloudex.CloudinaryApi do }" end - @spec post(tuple | String.t(), binary, map) :: {:ok, %Cloudex.UploadedImage{}} | {:error, any} + @spec post(tuple | String.t(), binary, map) :: + {:ok, %Cloudex.UploadedImage{}} | {:ok, %Cloudex.UploadedVideo{}} | {:error, any} defp post(body, source, opts) do with {:ok, raw_response} <- common_post(body, opts), {:ok, response} <- @json_library.decode(raw_response.body), @@ -187,7 +196,8 @@ defmodule Cloudex.CloudinaryApi do "#{@base_url}#{Cloudex.Settings.get(:cloud_name)}/#{resource_type}/upload" end - @spec handle_response(map, String.t()) :: {:error, any} | {:ok, %Cloudex.UploadedImage{}} + @spec handle_response(map, String.t()) :: + {:error, any} | {:ok, %Cloudex.UploadedImage{}} | {:ok, %Cloudex.UploadedVideo{}} defp handle_response( %{ "error" => %{ diff --git a/lib/cloudex/uploaded_video.ex b/lib/cloudex/uploaded_video.ex new file mode 100644 index 0000000..5c2e285 --- /dev/null +++ b/lib/cloudex/uploaded_video.ex @@ -0,0 +1,80 @@ +defmodule Cloudex.UploadedVideo do + @moduledoc """ + A simple struct containing all the information from cloudinary. + + * source + * public_id + * version + * signature + * width + * hieght + * format + * resource_type + * created_at + * tags + * bytes + * type + * etag + * url + * secure_url + * original_filename + * phash + * audio + * video + * frame_rate + * bit_rate + * duration + """ + + @type t :: %__MODULE__{ + audio: map() | %{}, + bit_rate: non_neg_integer | nil, + bytes: non_neg_integer | nil, + created_at: String.t() | nil, + duration: float() | nil, + etag: String.t() | nil, + format: String.t() | nil, + frame_rate: String.t() | nil, + height: non_neg_integer | nil, + moderation: [String.t()] | [] | nil, + original_filename: String.t() | nil, + phash: String.t() | nil, + public_id: String.t() | nil, + resource_type: String.t() | nil, + secure_url: String.t() | nil, + signature: String.t() | nil, + source: String.t() | nil, + tags: [String.t()] | [] | nil, + type: String.t() | nil, + url: String.t() | nil, + version: String.t() | nil, + video: map() | %{}, + width: non_neg_integer | nil, + context: struct | nil + } + + defstruct audio: %{}, + bit_rate: nil, + bytes: nil, + created_at: nil, + duration: nil, + etag: nil, + format: nil, + frame_rate: nil, + height: nil, + moderation: nil, + original_filename: nil, + phash: nil, + public_id: nil, + resource_type: nil, + secure_url: nil, + signature: nil, + source: nil, + tags: nil, + type: nil, + url: nil, + version: nil, + video: %{}, + width: nil, + context: nil +end diff --git a/test/cloudex/cloudex_test.exs b/test/cloudex/cloudex_test.exs index 7286e8b..a2b6b0e 100644 --- a/test/cloudex/cloudex_test.exs +++ b/test/cloudex/cloudex_test.exs @@ -24,8 +24,41 @@ defmodule CloudexTest do test "upload single video file" do use_cassette "test_upload_video" do - assert {:ok, %Cloudex.UploadedImage{}} = - Cloudex.upload("test/assets/teamwork.mp4", %{resource_type: "video"}) + result = Cloudex.upload("test/assets/teamwork.mp4", %{resource_type: "video"}) + + assert {:ok, + %Cloudex.UploadedVideo{ + audio: %{}, + bit_rate: 27217, + bytes: 299_396, + created_at: "2018-08-27T03:15:42Z", + duration: 88.0, + etag: "aaf7d25e2f37927b2be50e20c58304e3", + format: "mp4", + frame_rate: 25.0, + height: 400, + original_filename: "teamwork", + public_id: "bqzkffnaviwjafajqraf", + resource_type: "video", + secure_url: + "https://res.cloudinary.com/my_cloud_name/video/upload/v1535339742/bqzkffnaviwjafajqraf.mp4", + signature: "5b477564193de869ad6cf84e561dd74a091a2211", + source: "test/assets/teamwork.mp4", + tags: [], + type: "upload", + url: + "http://res.cloudinary.com/my_cloud_name/video/upload/v1535339742/bqzkffnaviwjafajqraf.mp4", + version: 1_535_339_742, + video: %{ + "bit_rate" => "26340", + "codec" => "h264", + "dar" => "8:5", + "level" => 31, + "pix_format" => "yuv420p", + "profile" => "Constrained Baseline" + }, + width: 640 + }} = result end end