diff --git a/lib/philomena_web/controllers/api/json/oembed_controller.ex b/lib/philomena_web/controllers/api/json/oembed_controller.ex new file mode 100644 index 00000000..a10e7244 --- /dev/null +++ b/lib/philomena_web/controllers/api/json/oembed_controller.ex @@ -0,0 +1,72 @@ +defmodule PhilomenaWeb.Api.Json.OembedController do + use PhilomenaWeb, :controller + + alias Philomena.Images.Image + alias Philomena.Repo + import Ecto.Query + + @cdn_regex ~r/\/img\/.*\/(\d+)(\.|[\/_][_\w])/ + @img_regex ~r/\/(\d+)/ + + def index(conn, %{"url" => url}) do + parsed = URI.parse(url) + + try_oembed(conn, parsed) + end + def index(conn, _params), do: oembed_error(conn) + + defp try_oembed(conn, %{path: path}) do + cdn = Regex.run(@cdn_regex, path, capture: :all_but_first) + img = Regex.run(@img_regex, path, capture: :all_but_first) + + image_id = + cond do + cdn -> hd(cdn) + img -> hd(img) + true -> nil + end + + load_image(image_id) + |> oembed_image(conn) + end + + defp load_image(nil), do: nil + defp load_image(id) do + Image + |> where(id: ^id, hidden_from_users: false) + |> preload([:tags, :user]) + |> Repo.one() + end + + defp oembed_image(nil, conn), do: oembed_error(conn) + defp oembed_image(image, conn), do: json(conn, oembed_json(image, conn)) + + defp oembed_error(conn) do + conn + |> Plug.Conn.put_status(:not_found) + |> json(%{error: "couldn't find an image"}) + end + + defp oembed_json(image, conn) do + %{ + version: "1.0", + type: "photo", + title: "##{image.id} - #{image.tag_list_cache} - Derpibooru", + author_url: image.source_url, + author_name: artist_tags(image.tags), + provider_name: "Derpibooru", + provider_url: Routes.image_url(conn, :show, image), + cache_age: 7200, + derpibooru_id: image.id, + derpibooru_score: image.score, + derpibooru_comments: image.comments_count, + derpibooru_tags: Enum.map(image.tags, & &1.name) + } + end + + defp artist_tags(tags) do + tags + |> Enum.filter(& &1.namespace == "artist") + |> Enum.map_join(", ", & &1.name) + end +end \ No newline at end of file diff --git a/lib/philomena_web/plugs/filter_id_plug.ex b/lib/philomena_web/plugs/filter_id_plug.ex index 1c8f9ef1..8e1851dd 100644 --- a/lib/philomena_web/plugs/filter_id_plug.ex +++ b/lib/philomena_web/plugs/filter_id_plug.ex @@ -9,7 +9,7 @@ defmodule PhilomenaWeb.FilterIdPlug do filter = load_filter(conn.params) user = conn.assigns.current_user - case Canada.Can.can?(user, :show, filter) do + case not is_nil(filter) and Canada.Can.can?(user, :show, filter) do true -> Plug.Conn.assign(conn, :current_filter, filter) false -> conn end diff --git a/lib/philomena_web/router.ex b/lib/philomena_web/router.ex index 2128ee9e..90a20713 100644 --- a/lib/philomena_web/router.ex +++ b/lib/philomena_web/router.ex @@ -80,6 +80,7 @@ defmodule PhilomenaWeb.Router do resources "/reverse", ReverseController, only: [:create] end resources "/search", SearchController, only: [:index] + resources "/oembed", OembedController, only: [:index] end scope "/", PhilomenaWeb do