From 18234cc44e6bc989e3e3cf15714c54b4fa05b9dd Mon Sep 17 00:00:00 2001 From: Sachin Joshi Date: Tue, 16 Jul 2019 22:37:36 +0545 Subject: add the rich media ttl based on image exp time --- lib/pleroma/web/rich_media/parser.ex | 41 ++++++++++++++++ .../web/rich_media/parsers/ttl/aws_signed_url.ex | 54 ++++++++++++++++++++++ 2 files changed, 95 insertions(+) create mode 100644 lib/pleroma/web/rich_media/parsers/ttl/aws_signed_url.ex (limited to 'lib') diff --git a/lib/pleroma/web/rich_media/parser.ex b/lib/pleroma/web/rich_media/parser.ex index 0d2523338..ba8dc6f2a 100644 --- a/lib/pleroma/web/rich_media/parser.ex +++ b/lib/pleroma/web/rich_media/parser.ex @@ -24,6 +24,7 @@ defmodule Pleroma.Web.RichMedia.Parser do Cachex.fetch!(:rich_media_cache, url, fn _ -> {:commit, parse_url(url)} end) + |> set_ttl_based_on_image(url) rescue e -> {:error, "Cachex error: #{inspect(e)}"} @@ -31,6 +32,46 @@ defmodule Pleroma.Web.RichMedia.Parser do end end + @doc """ + Set the rich media cache based on the expiration time of image. + + Define a module that has `run` function + + ## Example + + defmodule MyModule do + def run(data, url) do + image_url = Map.get(data, :image) + # do some parsing in the url and get the ttl of the image + # ttl is unix time + ttl = parse_ttl_from_url(image_url) + Cachex.expire_at(:rich_media_cache, url, ttl * 1000) + end + end + + Define the module in the config + + config :pleroma, :rich_media, + ttl_setters: [MyModule] + """ + def set_ttl_based_on_image({:ok, data}, url) do + case Cachex.ttl(:rich_media_cache, url) do + {:ok, nil} -> + modules = Pleroma.Config.get([:rich_media, :ttl_setters]) + + if Enum.count(modules) > 0 do + Enum.each(modules, & &1.run(data, url)) + end + + {:ok, data} + + _ -> + {:ok, data} + end + end + + def set_ttl_based_on_image(data, _url), do: data + defp parse_url(url) do try do {:ok, %Tesla.Env{body: html}} = Pleroma.HTTP.get(url, [], adapter: @hackney_options) diff --git a/lib/pleroma/web/rich_media/parsers/ttl/aws_signed_url.ex b/lib/pleroma/web/rich_media/parsers/ttl/aws_signed_url.ex new file mode 100644 index 000000000..d57107939 --- /dev/null +++ b/lib/pleroma/web/rich_media/parsers/ttl/aws_signed_url.ex @@ -0,0 +1,54 @@ +defmodule Pleroma.Web.RichMedia.Parser.TTL.AwsSignedUrl do + def run(data, url) do + image = Map.get(data, :image) + + if is_aws_signed_url(image) do + image + |> parse_query_params() + |> format_query_params() + |> get_expiration_timestamp() + |> set_ttl(url) + end + end + + defp is_aws_signed_url(""), do: nil + defp is_aws_signed_url(nil), do: nil + + defp is_aws_signed_url(image) when is_binary(image) do + %URI{host: host, query: query} = URI.parse(image) + + if String.contains?(host, "amazonaws.com") and + String.contains?(query, "X-Amz-Expires") do + image + else + nil + end + end + + defp is_aws_signed_url(_), do: nil + + defp parse_query_params(image) do + %URI{query: query} = URI.parse(image) + query + end + + defp format_query_params(query) do + query + |> String.split(~r/&|=/) + |> Enum.chunk_every(2) + |> Map.new(fn [k, v] -> {k, v} end) + end + + defp get_expiration_timestamp(params) when is_map(params) do + {:ok, date} = + params + |> Map.get("X-Amz-Date") + |> Timex.parse("{ISO:Basic:Z}") + + Timex.to_unix(date) + String.to_integer(Map.get(params, "X-Amz-Expires")) + end + + defp set_ttl(ttl, url) do + Cachex.expire_at(:rich_media_cache, url, ttl * 1000) + end +end -- cgit v1.2.3 From de9906ad56bd25d6c8c38bef1307192df2e95445 Mon Sep 17 00:00:00 2001 From: Sachin Joshi Date: Fri, 19 Jul 2019 11:43:42 +0545 Subject: change the structure of image ttl parsar --- lib/pleroma/web/rich_media/parser.ex | 36 ++++++++++++---------- .../web/rich_media/parsers/ttl/aws_signed_url.ex | 10 +++--- lib/pleroma/web/rich_media/parsers/ttl/ttl.ex | 3 ++ 3 files changed, 27 insertions(+), 22 deletions(-) create mode 100644 lib/pleroma/web/rich_media/parsers/ttl/ttl.ex (limited to 'lib') diff --git a/lib/pleroma/web/rich_media/parser.ex b/lib/pleroma/web/rich_media/parser.ex index ba8dc6f2a..b69b2be61 100644 --- a/lib/pleroma/web/rich_media/parser.ex +++ b/lib/pleroma/web/rich_media/parser.ex @@ -35,17 +35,17 @@ defmodule Pleroma.Web.RichMedia.Parser do @doc """ Set the rich media cache based on the expiration time of image. - Define a module that has `run` function + Adopt behaviour `Pleroma.Web.RichMedia.Parser.TTL` ## Example defmodule MyModule do - def run(data, url) do + @behaviour Pleroma.Web.RichMedia.Parser.TTL + def ttl(data, url) do image_url = Map.get(data, :image) # do some parsing in the url and get the ttl of the image - # ttl is unix time - ttl = parse_ttl_from_url(image_url) - Cachex.expire_at(:rich_media_cache, url, ttl * 1000) + # and return ttl is unix time + parse_ttl_from_url(image_url) end end @@ -55,22 +55,26 @@ defmodule Pleroma.Web.RichMedia.Parser do ttl_setters: [MyModule] """ def set_ttl_based_on_image({:ok, data}, url) do - case Cachex.ttl(:rich_media_cache, url) do - {:ok, nil} -> - modules = Pleroma.Config.get([:rich_media, :ttl_setters]) - - if Enum.count(modules) > 0 do - Enum.each(modules, & &1.run(data, url)) - end - - {:ok, data} - + with {:ok, nil} <- Cachex.ttl(:rich_media_cache, url) do + ttl = get_ttl_from_image(data, url) + Cachex.expire_at(:rich_media_cache, url, ttl * 1000) + {:ok, data} + else _ -> {:ok, data} end end - def set_ttl_based_on_image(data, _url), do: data + defp get_ttl_from_image(data, url) do + Pleroma.Config.get([:rich_media, :ttl_setters]) + |> Enum.reduce({:ok, nil}, fn + module, {:ok, _ttl} -> + module.ttl(data, url) + + _, error -> + error + end) + end defp parse_url(url) do try do diff --git a/lib/pleroma/web/rich_media/parsers/ttl/aws_signed_url.ex b/lib/pleroma/web/rich_media/parsers/ttl/aws_signed_url.ex index d57107939..014c0935f 100644 --- a/lib/pleroma/web/rich_media/parsers/ttl/aws_signed_url.ex +++ b/lib/pleroma/web/rich_media/parsers/ttl/aws_signed_url.ex @@ -1,5 +1,8 @@ defmodule Pleroma.Web.RichMedia.Parser.TTL.AwsSignedUrl do - def run(data, url) do + @behaviour Pleroma.Web.RichMedia.Parser.TTL + + @impl Pleroma.Web.RichMedia.Parser.TTL + def ttl(data, _url) do image = Map.get(data, :image) if is_aws_signed_url(image) do @@ -7,7 +10,6 @@ defmodule Pleroma.Web.RichMedia.Parser.TTL.AwsSignedUrl do |> parse_query_params() |> format_query_params() |> get_expiration_timestamp() - |> set_ttl(url) end end @@ -47,8 +49,4 @@ defmodule Pleroma.Web.RichMedia.Parser.TTL.AwsSignedUrl do Timex.to_unix(date) + String.to_integer(Map.get(params, "X-Amz-Expires")) end - - defp set_ttl(ttl, url) do - Cachex.expire_at(:rich_media_cache, url, ttl * 1000) - end end diff --git a/lib/pleroma/web/rich_media/parsers/ttl/ttl.ex b/lib/pleroma/web/rich_media/parsers/ttl/ttl.ex new file mode 100644 index 000000000..6b3ec6d30 --- /dev/null +++ b/lib/pleroma/web/rich_media/parsers/ttl/ttl.ex @@ -0,0 +1,3 @@ +defmodule Pleroma.Web.RichMedia.Parser.TTL do + @callback ttl(Map.t(), String.t()) :: {:ok, Integer.t()} | {:error, String.t()} +end -- cgit v1.2.3