From a95df5ec4200490381f866b230c7cbe4dd56c3aa Mon Sep 17 00:00:00 2001 From: Liam Date: Sun, 2 Jun 2024 01:04:42 -0400 Subject: [PATCH 1/3] Add OpenSearch XML description for browsers --- assets/static/opensearch.xml | 10 ++++++++++ lib/philomena_web.ex | 2 +- lib/philomena_web/templates/layout/app.html.slime | 1 + 3 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 assets/static/opensearch.xml diff --git a/assets/static/opensearch.xml b/assets/static/opensearch.xml new file mode 100644 index 000000000..48909d2ff --- /dev/null +++ b/assets/static/opensearch.xml @@ -0,0 +1,10 @@ + + Derpibooru + Derpibooru image search + UTF-8 + https://derpibooru.org/favicon.ico + https://derpibooru.org/favicon.svg + + + + diff --git a/lib/philomena_web.ex b/lib/philomena_web.ex index a4bccdf2e..fd16f8ce9 100644 --- a/lib/philomena_web.ex +++ b/lib/philomena_web.ex @@ -17,7 +17,7 @@ defmodule PhilomenaWeb do and import those modules here. """ - def static_paths, do: ~w(assets favicon.ico favicon.svg robots.txt) + def static_paths, do: ~w(assets favicon.ico favicon.svg robots.txt opensearch.xml) def controller do quote do diff --git a/lib/philomena_web/templates/layout/app.html.slime b/lib/philomena_web/templates/layout/app.html.slime index 29013972b..d78423697 100644 --- a/lib/philomena_web/templates/layout/app.html.slime +++ b/lib/philomena_web/templates/layout/app.html.slime @@ -15,6 +15,7 @@ html lang="en" link rel="stylesheet" href=dark_stylesheet_path() media="(prefers-color-scheme: dark)" link rel="icon" href=~p"/favicon.ico" type="image/x-icon" link rel="icon" href=~p"/favicon.svg" type="image/svg+xml" + link rel="search" type="application/opensearchdescription+xml" title="Derpibooru" href=~p"/opensearch.xml" meta name="generator" content="philomena" meta name="theme-color" content="#618fc3" meta name="format-detection" content="telephone=no" From ed34dea36f84ab70e9e7217949b193c52a1ac0e9 Mon Sep 17 00:00:00 2001 From: Liam Date: Sun, 2 Jun 2024 00:49:01 -0400 Subject: [PATCH 2/3] Swap Bamboo for Swoosh email delivery --- config/config.exs | 1 - config/runtime.exs | 22 +++++++++------------- lib/philomena/application.ex | 3 +++ lib/philomena/mailer.ex | 8 +++++++- lib/philomena/users/user_notifier.ex | 4 ++-- mix.exs | 9 +++------ mix.lock | 6 +++--- 7 files changed, 27 insertions(+), 26 deletions(-) diff --git a/config/config.exs b/config/config.exs index 2c797a1ae..9d9435871 100644 --- a/config/config.exs +++ b/config/config.exs @@ -58,7 +58,6 @@ config :logger, :console, # Use Jason for JSON parsing in Phoenix config :phoenix, :json_library, Jason -config :bamboo, :json_library, Jason # Import environment specific config. This must remain at the bottom # of this file so it overrides the configuration defined above. diff --git a/config/runtime.exs b/config/runtime.exs index 4257ed9e8..935ba1244 100644 --- a/config/runtime.exs +++ b/config/runtime.exs @@ -6,7 +6,6 @@ import Config # by calling `mix release`. # # See `mix help release` for more information. -{:ok, _} = Application.ensure_all_started(:tls_certificate_check) config :bcrypt_elixir, log_rounds: String.to_integer(System.get_env("BCRYPT_ROUNDS", "12")) @@ -118,17 +117,14 @@ end if config_env() == :prod do # Production mailer config config :philomena, Philomena.Mailer, - adapter: Bamboo.SMTPAdapter, - server: System.fetch_env!("SMTP_RELAY"), - hostname: System.fetch_env!("SMTP_DOMAIN"), - port: System.get_env("SMTP_PORT") || 587, - username: System.fetch_env!("SMTP_USERNAME"), - password: System.fetch_env!("SMTP_PASSWORD"), - tls: :always, - auth: :always, - tls_options: - [middlebox_comp_mode: false] ++ - :tls_certificate_check.options(System.fetch_env!("SMTP_RELAY")) + adapter: Swoosh.Adapters.Mua, + relay: System.fetch_env!("SMTP_RELAY"), + port: String.to_integer(System.get_env("SMTP_PORT", "587")), + auth: [ + username: System.fetch_env!("SMTP_USERNAME"), + password: System.fetch_env!("SMTP_PASSWORD") + ], + ssl: [middlebox_comp_mode: false] # Production endpoint config {:ok, ip} = :inet.parse_address(System.get_env("APP_IP", "127.0.0.1") |> String.to_charlist()) @@ -140,7 +136,7 @@ if config_env() == :prod do server: not is_nil(System.get_env("START_ENDPOINT")) else # Don't send email in development - config :philomena, Philomena.Mailer, adapter: Bamboo.LocalAdapter + config :philomena, Philomena.Mailer, adapter: Swoosh.Adapters.Local # Use this to debug slime templates # config :slime, :keep_lines, true diff --git a/lib/philomena/application.ex b/lib/philomena/application.ex index 28d7d6453..4d1a7a4b3 100644 --- a/lib/philomena/application.ex +++ b/lib/philomena/application.ex @@ -14,6 +14,9 @@ defmodule Philomena.Application do # Background queueing system Philomena.ExqSupervisor, + # Mailer + {Task.Supervisor, name: Philomena.AsyncEmailSupervisor}, + # Starts a worker by calling: Philomena.Worker.start_link(arg) # {Philomena.Worker, arg}, {Redix, name: :redix, host: Application.get_env(:philomena, :redis_host)}, diff --git a/lib/philomena/mailer.ex b/lib/philomena/mailer.ex index 93bed3bae..642f329ee 100644 --- a/lib/philomena/mailer.ex +++ b/lib/philomena/mailer.ex @@ -1,3 +1,9 @@ defmodule Philomena.Mailer do - use Bamboo.Mailer, otp_app: :philomena + use Swoosh.Mailer, otp_app: :philomena + + @spec deliver_later(Swoosh.Email.t()) :: {:ok, Swoosh.Email.t()} + def deliver_later(mail) do + Task.Supervisor.start_child(Philomena.AsyncEmailSupervisor, fn -> deliver(mail) end) + {:ok, mail} + end end diff --git a/lib/philomena/users/user_notifier.ex b/lib/philomena/users/user_notifier.ex index bc8b71db9..480833211 100644 --- a/lib/philomena/users/user_notifier.ex +++ b/lib/philomena/users/user_notifier.ex @@ -1,9 +1,9 @@ defmodule Philomena.Users.UserNotifier do - alias Bamboo.Email + alias Swoosh.Email alias Philomena.Mailer defp deliver(to, subject, body) do - Email.new_email( + Email.new( to: to, from: mailer_address(), subject: subject, diff --git a/mix.exs b/mix.exs index 85d5c270e..130f1ccc1 100644 --- a/mix.exs +++ b/mix.exs @@ -62,7 +62,6 @@ defmodule Philomena.MixProject do github: "basho/erlang-pbkdf2", ref: "7e9bd5fcd3cc3062159e4c9214bb628aa6feb5ca"}, {:qrcode, "~> 0.1"}, {:redix, "~> 1.2"}, - {:bamboo, "~> 2.2"}, {:remote_ip, "~> 1.1"}, {:briefly, "~> 0.4"}, {:tesla, "~> 1.5"}, @@ -76,11 +75,9 @@ defmodule Philomena.MixProject do {:inet_cidr, "~> 1.0"}, # SMTP - {:tls_certificate_check, "~> 1.21"}, - {:bamboo_smtp, "~> 4.2", - github: "botsquad/bamboo_smtp", - ref: "c630ccde40070deffc7d78ee6e4a08c9199f145b", - override: true}, + {:swoosh, "~> 1.16"}, + {:mua, "~> 0.2.0"}, + {:mail, "~> 0.3.0"}, # Markdown {:rustler, "~> 0.27"}, diff --git a/mix.lock b/mix.lock index 522e76766..73184f5a9 100644 --- a/mix.lock +++ b/mix.lock @@ -1,6 +1,4 @@ %{ - "bamboo": {:hex, :bamboo, "2.2.0", "f10a406d2b7f5123eb1f02edfa043c259db04b47ab956041f279eaac776ef5ce", [:mix], [{:hackney, ">= 1.15.2", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:mime, "~> 1.4", [hex: :mime, repo: "hexpm", optional: false]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "8c3b14ba7d2f40cb4be04128ed1e2aff06d91d9413d38bafb4afccffa3ade4fc"}, - "bamboo_smtp": {:git, "https://github.com/botsquad/bamboo_smtp.git", "c630ccde40070deffc7d78ee6e4a08c9199f145b", [ref: "c630ccde40070deffc7d78ee6e4a08c9199f145b"]}, "bcrypt_elixir": {:hex, :bcrypt_elixir, "3.1.0", "0b110a9a6c619b19a7f73fa3004aa11d6e719a67e672d1633dc36b6b2290a0f7", [:make, :mix], [{:comeonin, "~> 5.3", [hex: :comeonin, repo: "hexpm", optional: false]}, {:elixir_make, "~> 0.6", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "2ad2acb5a8bc049e8d5aa267802631912bb80d5f4110a178ae7999e69dca1bf7"}, "briefly": {:hex, :briefly, "0.5.1", "ee10d48da7f79ed2aebdc3e536d5f9a0c3e36ff76c0ad0d4254653a152b13a8a", [:mix], [], "hexpm", "bd684aa92ad8b7b4e0d92c31200993c4bc1469fc68cd6d5f15144041bd15cb57"}, "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, @@ -40,11 +38,13 @@ "idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~> 0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"}, "inet_cidr": {:hex, :inet_cidr, "1.0.8", "d26bb7bdbdf21ae401ead2092bf2bb4bf57fe44a62f5eaa5025280720ace8a40", [:mix], [], "hexpm", "d5b26da66603bb56c933c65214c72152f0de9a6ea53618b56d63302a68f6a90e"}, "jason": {:hex, :jason, "1.4.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"}, + "mail": {:hex, :mail, "0.3.1", "cb0a14e4ed8904e4e5a08214e686ccf6f9099346885db17d8c309381f865cc5c", [:mix], [], "hexpm", "1db701e89865c1d5fa296b2b57b1cd587587cca8d8a1a22892b35ef5a8e352a6"}, "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"}, "mime": {:hex, :mime, "1.6.0", "dabde576a497cef4bbdd60aceee8160e02a6c89250d6c0b29e56c0dfb00db3d2", [:mix], [], "hexpm", "31a1a8613f8321143dde1dafc36006a17d28d02bdfecb9e95a880fa7aabd19a7"}, "mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"}, "mint": {:hex, :mint, "1.5.2", "4805e059f96028948870d23d7783613b7e6b0e2fb4e98d720383852a760067fd", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "d77d9e9ce4eb35941907f1d3df38d8f750c357865353e21d335bdcdf6d892a02"}, "mix_audit": {:hex, :mix_audit, "2.1.2", "6cd5c5e2edbc9298629c85347b39fb3210656e541153826efd0b2a63767f3395", [:make, :mix], [{:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:yaml_elixir, "~> 2.9", [hex: :yaml_elixir, repo: "hexpm", optional: false]}], "hexpm", "68d2f06f96b9c445a23434c9d5f09682866a5b4e90f631829db1c64f140e795b"}, + "mua": {:hex, :mua, "0.2.1", "7f1c20dbe7266d514a07bf5b7a3946413d70150be41cb5475b5a95bb517a378f", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}], "hexpm", "0bc556803a1d09dfb69bfebecb838cf33a2d123de84f700c41b6b8134027c11f"}, "neotoma": {:hex, :neotoma, "1.7.3", "d8bd5404b73273989946e4f4f6d529e5c2088f5fa1ca790b4dbe81f4be408e61", [:rebar], [], "hexpm", "2da322b9b1567ffa0706a7f30f6bbbde70835ae44a1050615f4b4a3d436e0f28"}, "nimble_options": {:hex, :nimble_options, "1.1.0", "3b31a57ede9cb1502071fade751ab0c7b8dbe75a9a4c2b5bbb0943a690b63172", [:mix], [], "hexpm", "8bbbb3941af3ca9acc7835f5655ea062111c9c27bcac53e004460dfd19008a99"}, "nimble_parsec": {:hex, :nimble_parsec, "1.4.0", "51f9b613ea62cfa97b25ccc2c1b4216e81df970acd8e16e8d1bdc58fef21370d", [:mix], [], "hexpm", "9c565862810fb383e9838c1dd2d7d2c437b3d13b267414ba6af33e50d2d1cf28"}, @@ -78,9 +78,9 @@ "sobelow": {:hex, :sobelow, "0.13.0", "218afe9075904793f5c64b8837cc356e493d88fddde126a463839351870b8d1e", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "cd6e9026b85fc35d7529da14f95e85a078d9dd1907a9097b3ba6ac7ebbe34a0d"}, "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.7", "354c321cf377240c7b8716899e182ce4890c5938111a1296add3ec74cf1715df", [:make, :mix, :rebar3], [], "hexpm", "fe4c190e8f37401d30167c8c405eda19469f34577987c76dde613e838bbc67f8"}, "sweet_xml": {:hex, :sweet_xml, "0.7.4", "a8b7e1ce7ecd775c7e8a65d501bc2cd933bff3a9c41ab763f5105688ef485d08", [:mix], [], "hexpm", "e7c4b0bdbf460c928234951def54fe87edf1a170f6896675443279e2dbeba167"}, + "swoosh": {:hex, :swoosh, "1.16.9", "20c6a32ea49136a4c19f538e27739bb5070558c0fa76b8a95f4d5d5ca7d319a1", [:mix], [{:bandit, ">= 1.0.0", [hex: :bandit, repo: "hexpm", optional: true]}, {:cowboy, "~> 1.1 or ~> 2.4", [hex: :cowboy, repo: "hexpm", optional: true]}, {:ex_aws, "~> 2.1", [hex: :ex_aws, repo: "hexpm", optional: true]}, {:finch, "~> 0.6", [hex: :finch, repo: "hexpm", optional: true]}, {:gen_smtp, "~> 0.13 or ~> 1.0", [hex: :gen_smtp, repo: "hexpm", optional: true]}, {:hackney, "~> 1.9", [hex: :hackney, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mail, "~> 0.2", [hex: :mail, repo: "hexpm", optional: true]}, {:mime, "~> 1.1 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mua, "~> 0.2.0", [hex: :mua, repo: "hexpm", optional: true]}, {:multipart, "~> 0.4", [hex: :multipart, repo: "hexpm", optional: true]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: true]}, {:plug_cowboy, ">= 1.0.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:req, "~> 0.5 or ~> 1.0", [hex: :req, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "878b1a7a6c10ebbf725a3349363f48f79c5e3d792eb621643b0d276a38acc0a6"}, "telemetry": {:hex, :telemetry, "1.2.1", "68fdfe8d8f05a8428483a97d7aab2f268aaff24b49e0f599faa091f1d4e7f61c", [:rebar3], [], "hexpm", "dad9ce9d8effc621708f99eac538ef1cbe05d6a874dd741de2e689c47feafed5"}, "tesla": {:hex, :tesla, "1.8.0", "d511a4f5c5e42538d97eef7c40ec4f3e44effdc5068206f42ed859e09e51d1fd", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: true]}, {:finch, "~> 0.13", [hex: :finch, repo: "hexpm", optional: true]}, {:fuse, "~> 2.4", [hex: :fuse, repo: "hexpm", optional: true]}, {:gun, ">= 1.0.0", [hex: :gun, repo: "hexpm", optional: true]}, {:hackney, "~> 1.6", [hex: :hackney, repo: "hexpm", optional: true]}, {:ibrowse, "4.4.2", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: true]}, {:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.0", [hex: :mint, repo: "hexpm", optional: true]}, {:msgpax, "~> 2.3", [hex: :msgpax, repo: "hexpm", optional: true]}, {:poison, ">= 1.0.0", [hex: :poison, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "10501f360cd926a309501287470372af1a6e1cbed0f43949203a4c13300bc79f"}, - "tls_certificate_check": {:hex, :tls_certificate_check, "1.21.0", "042ab2c0c860652bc5cf69c94e3a31f96676d14682e22ec7813bd173ceff1788", [:rebar3], [{:ssl_verify_fun, "~> 1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm", "6cee6cffc35a390840d48d463541d50746a7b0e421acaadb833cfc7961e490e7"}, "toml": {:hex, :toml, "0.7.0", "fbcd773caa937d0c7a02c301a1feea25612720ac3fa1ccb8bfd9d30d822911de", [:mix], [], "hexpm", "0690246a2478c1defd100b0c9b89b4ea280a22be9a7b313a8a058a2408a2fa70"}, "unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"}, "websock": {:hex, :websock, "0.5.3", "2f69a6ebe810328555b6fe5c831a851f485e303a7c8ce6c5f675abeb20ebdadc", [:mix], [], "hexpm", "6105453d7fac22c712ad66fab1d45abdf049868f253cf719b625151460b8b453"}, From c63bc41d8b15947e1b1d86d650f99b30eb97aaeb Mon Sep 17 00:00:00 2001 From: Liam Date: Fri, 24 May 2024 21:15:05 -0400 Subject: [PATCH 3/3] Split out HTTP client interaction into PhilomenaProxy namespace --- lib/camo/image.ex | 8 -- .../artist_links/automatic_verifier.ex | 2 +- lib/philomena/channels/picarto_channel.ex | 2 +- lib/philomena/channels/piczel_channel.ex | 2 +- lib/philomena/http.ex | 46 -------- lib/philomena/scrapers.ex | 25 ---- lib/philomena_proxy/camo.ex | 24 ++++ lib/philomena_proxy/http.ex | 107 ++++++++++++++++++ lib/philomena_proxy/scrapers.ex | 71 ++++++++++++ .../scrapers/deviantart.ex | 21 +++- .../scrapers/pillowfort.ex | 14 ++- .../scrapers/raw.ex | 18 ++- lib/philomena_proxy/scrapers/scraper.ex | 11 ++ .../scrapers/tumblr.ex | 18 ++- .../scrapers/twitter.ex | 16 ++- .../controllers/image/scrape_controller.ex | 2 +- lib/philomena_web/plugs/check_captcha_plug.ex | 2 +- .../plugs/compromised_password_check_plug.ex | 2 +- lib/philomena_web/plugs/scraper_plug.ex | 2 +- lib/philomena_web/views/channel_view.ex | 12 +- priv/repo/seeds_development.exs | 2 +- 21 files changed, 294 insertions(+), 113 deletions(-) delete mode 100644 lib/camo/image.ex delete mode 100644 lib/philomena/http.ex delete mode 100644 lib/philomena/scrapers.ex create mode 100644 lib/philomena_proxy/camo.ex create mode 100644 lib/philomena_proxy/http.ex create mode 100644 lib/philomena_proxy/scrapers.ex rename lib/{philomena => philomena_proxy}/scrapers/deviantart.ex (89%) rename lib/{philomena => philomena_proxy}/scrapers/pillowfort.ex (78%) rename lib/{philomena => philomena_proxy}/scrapers/raw.ex (56%) create mode 100644 lib/philomena_proxy/scrapers/scraper.ex rename lib/{philomena => philomena_proxy}/scrapers/tumblr.ex (84%) rename lib/{philomena => philomena_proxy}/scrapers/twitter.ex (61%) diff --git a/lib/camo/image.ex b/lib/camo/image.ex deleted file mode 100644 index e77f99e61..000000000 --- a/lib/camo/image.ex +++ /dev/null @@ -1,8 +0,0 @@ -defmodule Camo.Image do - @doc """ - Convert a potentially untrusted external image URL into a trusted one - loaded through a gocamo proxy (specified by the environment). - """ - @spec image_url(String.t()) :: String.t() - def image_url(input), do: Philomena.Native.camo_image_url(input) -end diff --git a/lib/philomena/artist_links/automatic_verifier.ex b/lib/philomena/artist_links/automatic_verifier.ex index 1fd303a44..57fd8fd2e 100644 --- a/lib/philomena/artist_links/automatic_verifier.ex +++ b/lib/philomena/artist_links/automatic_verifier.ex @@ -1,7 +1,7 @@ defmodule Philomena.ArtistLinks.AutomaticVerifier do def check_link(artist_link, recheck_time) do artist_link.uri - |> Philomena.Http.get() + |> PhilomenaProxy.Http.get() |> contains_verification_code?(artist_link.verification_code) |> case do true -> diff --git a/lib/philomena/channels/picarto_channel.ex b/lib/philomena/channels/picarto_channel.ex index cc54cdd6b..a27a3615e 100644 --- a/lib/philomena/channels/picarto_channel.ex +++ b/lib/philomena/channels/picarto_channel.ex @@ -4,7 +4,7 @@ defmodule Philomena.Channels.PicartoChannel do @spec live_channels(DateTime.t()) :: map() def live_channels(now) do @api_online - |> Philomena.Http.get() + |> PhilomenaProxy.Http.get() |> case do {:ok, %Tesla.Env{body: body, status: 200}} -> body diff --git a/lib/philomena/channels/piczel_channel.ex b/lib/philomena/channels/piczel_channel.ex index 23ce8a0db..56da9e34e 100644 --- a/lib/philomena/channels/piczel_channel.ex +++ b/lib/philomena/channels/piczel_channel.ex @@ -4,7 +4,7 @@ defmodule Philomena.Channels.PiczelChannel do @spec live_channels(DateTime.t()) :: map() def live_channels(now) do @api_online - |> Philomena.Http.get() + |> PhilomenaProxy.Http.get() |> case do {:ok, %Tesla.Env{body: body, status: 200}} -> body diff --git a/lib/philomena/http.ex b/lib/philomena/http.ex deleted file mode 100644 index 738d8a110..000000000 --- a/lib/philomena/http.ex +++ /dev/null @@ -1,46 +0,0 @@ -defmodule Philomena.Http do - def get(url, headers \\ [], options \\ []) do - Tesla.get(client(headers), url, opts: [adapter: adapter_opts(options)]) - end - - def head(url, headers \\ [], options \\ []) do - Tesla.head(client(headers), url, opts: [adapter: adapter_opts(options)]) - end - - def post(url, body, headers \\ [], options \\ []) do - Tesla.post(client(headers), url, body, opts: [adapter: adapter_opts(options)]) - end - - defp adapter_opts(opts) do - opts = Keyword.merge(opts, max_body: 125_000_000, inet6: true) - - case Application.get_env(:philomena, :proxy_host) do - nil -> - opts - - url -> - Keyword.merge(opts, proxy: proxy_opts(URI.parse(url))) - end - end - - defp proxy_opts(%{host: host, port: port, scheme: "https"}), - do: {:https, host, port, [transport_opts: [inet6: true]]} - - defp proxy_opts(%{host: host, port: port, scheme: "http"}), - do: {:http, host, port, [transport_opts: [inet6: true]]} - - defp client(headers) do - Tesla.client( - [ - {Tesla.Middleware.FollowRedirects, max_redirects: 1}, - {Tesla.Middleware.Headers, - [ - {"User-Agent", - "Mozilla/5.0 (X11; Philomena; Linux x86_64; rv:86.0) Gecko/20100101 Firefox/86.0"} - | headers - ]} - ], - Tesla.Adapter.Mint - ) - end -end diff --git a/lib/philomena/scrapers.ex b/lib/philomena/scrapers.ex deleted file mode 100644 index da5fd381d..000000000 --- a/lib/philomena/scrapers.ex +++ /dev/null @@ -1,25 +0,0 @@ -defmodule Philomena.Scrapers do - @scrapers [ - Philomena.Scrapers.Deviantart, - Philomena.Scrapers.Pillowfort, - Philomena.Scrapers.Twitter, - Philomena.Scrapers.Tumblr, - Philomena.Scrapers.Raw - ] - - def scrape!(url) do - uri = URI.parse(url) - - @scrapers - |> Enum.find(& &1.can_handle?(uri, url)) - |> wrap() - |> Enum.map(& &1.scrape(uri, url)) - |> unwrap() - end - - defp wrap(nil), do: [] - defp wrap(res), do: [res] - - defp unwrap([result]), do: result - defp unwrap(_result), do: nil -end diff --git a/lib/philomena_proxy/camo.ex b/lib/philomena_proxy/camo.ex new file mode 100644 index 000000000..881b1c395 --- /dev/null +++ b/lib/philomena_proxy/camo.ex @@ -0,0 +1,24 @@ +defmodule PhilomenaProxy.Camo do + @moduledoc """ + Image proxying utilities. + """ + + @doc """ + Convert a potentially untrusted external image URL into a trusted one + loaded through a gocamo proxy (specified by the environment). + + Configuration is read from environment variables at runtime by Philomena. + + config :philomena, + camo_host: System.get_env("CAMO_HOST"), + camo_key: System.get_env("CAMO_KEY"), + + ## Example + + iex> PhilomenaProxy.Camo.image_url("https://example.org/img/view/2024/1/1/1.png") + "https://example.net/L5MqSmYq1ZEqiBGGvsvSDpILyJI/aHR0cHM6Ly9leGFtcGxlLm9yZy9pbWcvdmlldy8yMDI0LzEvMS8xLnBuZwo" + + """ + @spec image_url(String.t()) :: String.t() + def image_url(input), do: Philomena.Native.camo_image_url(input) +end diff --git a/lib/philomena_proxy/http.ex b/lib/philomena_proxy/http.ex new file mode 100644 index 000000000..9a5af4ec0 --- /dev/null +++ b/lib/philomena_proxy/http.ex @@ -0,0 +1,107 @@ +defmodule PhilomenaProxy.Http do + @moduledoc """ + HTTP client implementation. + + This applies the Philomena User-Agent header, and optionally proxies traffic through a SOCKS5 + HTTP proxy to allow the application to connect when the local network is restricted. + + If a proxy host is not specified in the configuration, then a proxy is not used and external + traffic is originated from the same network as application. + + Proxy options are read from environment variables at runtime by Philomena. + + config :philomena, + proxy_host: System.get_env("PROXY_HOST"), + + """ + + @type url :: String.t() + @type header_list :: [{String.t(), String.t()}] + @type body :: binary() + + @type client_options :: keyword() + + @doc ~S""" + Perform a HTTP GET request. + + ## Example + + iex> PhilomenaProxy.Http.get("http://example.com", [{"authorization", "Bearer #{token}"}]) + {:ok, %Tesla.Env{...}} + + iex> PhilomenaProxy.Http.get("http://nonexistent.example.com") + {:error, %Mint.TransportError{reason: :nxdomain}} + + """ + @spec get(url(), header_list(), client_options()) :: Tesla.Env.result() + def get(url, headers \\ [], options \\ []) do + Tesla.get(client(headers), url, opts: [adapter: adapter_opts(options)]) + end + + @doc ~S""" + Perform a HTTP HEAD request. + + ## Example + + iex> PhilomenaProxy.Http.head("http://example.com", [{"authorization", "Bearer #{token}"}]) + {:ok, %Tesla.Env{...}} + + iex> PhilomenaProxy.Http.head("http://nonexistent.example.com") + {:error, %Mint.TransportError{reason: :nxdomain}} + + """ + @spec head(url(), header_list(), client_options()) :: Tesla.Env.result() + def head(url, headers \\ [], options \\ []) do + Tesla.head(client(headers), url, opts: [adapter: adapter_opts(options)]) + end + + @doc ~S""" + Perform a HTTP POST request. + + ## Example + + iex> PhilomenaProxy.Http.post("http://example.com", "", [{"authorization", "Bearer #{token}"}]) + {:ok, %Tesla.Env{...}} + + iex> PhilomenaProxy.Http.post("http://nonexistent.example.com", "") + {:error, %Mint.TransportError{reason: :nxdomain}} + + """ + @spec post(url(), body(), header_list(), client_options()) :: Tesla.Env.result() + def post(url, body, headers \\ [], options \\ []) do + Tesla.post(client(headers), url, body, opts: [adapter: adapter_opts(options)]) + end + + defp adapter_opts(opts) do + opts = Keyword.merge(opts, max_body: 125_000_000, inet6: true) + + case Application.get_env(:philomena, :proxy_host) do + nil -> + opts + + url -> + Keyword.merge(opts, proxy: proxy_opts(URI.parse(url))) + end + end + + defp proxy_opts(%{host: host, port: port, scheme: "https"}), + do: {:https, host, port, [transport_opts: [inet6: true]]} + + defp proxy_opts(%{host: host, port: port, scheme: "http"}), + do: {:http, host, port, [transport_opts: [inet6: true]]} + + defp client(headers) do + Tesla.client( + [ + {Tesla.Middleware.FollowRedirects, max_redirects: 1}, + {Tesla.Middleware.Headers, + [ + {"User-Agent", + "Mozilla/5.0 (X11; Philomena; Linux x86_64; rv:86.0) Gecko/20100101 Firefox/86.0"} + | headers + ]} + ], + Tesla.Adapter.Mint + ) + end +end diff --git a/lib/philomena_proxy/scrapers.ex b/lib/philomena_proxy/scrapers.ex new file mode 100644 index 000000000..9a1668872 --- /dev/null +++ b/lib/philomena_proxy/scrapers.ex @@ -0,0 +1,71 @@ +defmodule PhilomenaProxy.Scrapers do + @moduledoc """ + Scrape utilities to facilitate uploading media from other websites. + """ + + # The URL to fetch, as a string. + @type url :: String.t() + + # An individual image in a list associated with a scrape result. + @type image_result :: %{ + url: url(), + camo_url: url() + } + + # Result of a successful scrape. + @type scrape_result :: %{ + source_url: url(), + description: String.t() | nil, + author_name: String.t() | nil, + images: [image_result()] + } + + @scrapers [ + PhilomenaProxy.Scrapers.Deviantart, + PhilomenaProxy.Scrapers.Pillowfort, + PhilomenaProxy.Scrapers.Twitter, + PhilomenaProxy.Scrapers.Tumblr, + PhilomenaProxy.Scrapers.Raw + ] + + @doc """ + Scrape a URL for content. + + The scrape result is intended for serialization to JSON. + + ## Examples + + iex> PhilomenaProxy.Scrapers.scrape!("http://example.org/image-page") + %{ + source_url: "http://example.org/image-page", + description: "Test", + author_name: "myself", + images: [ + %{ + url: "http://example.org/image.png" + camo_url: "http://example.net/UT2YIjkWDas6CQBmQcYlcNGmKfQ/aHR0cDovL2V4YW1wbGUub3JnL2ltY" + } + ] + } + + iex> PhilomenaProxy.Scrapers.scrape!("http://example.org/nonexistent-path") + nil + + """ + @spec scrape!(url()) :: scrape_result() | nil + def scrape!(url) do + uri = URI.parse(url) + + @scrapers + |> Enum.find(& &1.can_handle?(uri, url)) + |> wrap() + |> Enum.map(& &1.scrape(uri, url)) + |> unwrap() + end + + defp wrap(nil), do: [] + defp wrap(res), do: [res] + + defp unwrap([result]), do: result + defp unwrap(_result), do: nil +end diff --git a/lib/philomena/scrapers/deviantart.ex b/lib/philomena_proxy/scrapers/deviantart.ex similarity index 89% rename from lib/philomena/scrapers/deviantart.ex rename to lib/philomena_proxy/scrapers/deviantart.ex index 4bc8fdd92..109851335 100644 --- a/lib/philomena/scrapers/deviantart.ex +++ b/lib/philomena_proxy/scrapers/deviantart.ex @@ -1,4 +1,11 @@ -defmodule Philomena.Scrapers.Deviantart do +defmodule PhilomenaProxy.Scrapers.Deviantart do + @moduledoc false + + alias PhilomenaProxy.Scrapers.Scraper + alias PhilomenaProxy.Scrapers + + @behaviour Scraper + @image_regex ~r|data-rh="true" rel="preload" href="([^"]*)" as="image"| @source_regex ~r|rel="canonical" href="([^"]*)"| @artist_regex ~r|https://www.deviantart.com/([^/]*)/art| @@ -7,7 +14,7 @@ defmodule Philomena.Scrapers.Deviantart do @png_regex ~r|(https://[0-9a-z\-\.]+(?:/intermediary)?/f/[0-9a-f\-]+/[0-9a-z\-]+\.png/v1/fill/[0-9a-z_,]+/[0-9a-z_\-]+)(\.png)(.*)| @jpg_regex ~r|(https://[0-9a-z\-\.]+(?:/intermediary)?/f/[0-9a-f\-]+/[0-9a-z\-]+\.jpg/v1/fill/w_[0-9]+,h_[0-9]+,q_)([0-9]+)(,[a-z]+\/[a-z0-6_\-]+\.jpe?g.*)| - @spec can_handle?(URI.t(), String.t()) :: true | false + @spec can_handle?(URI.t(), String.t()) :: boolean() def can_handle?(uri, _url) do String.ends_with?(uri.host, "deviantart.com") end @@ -21,6 +28,7 @@ defmodule Philomena.Scrapers.Deviantart do # # So, regex it is. Eat dirt, deviantart. You don't deserve the respect # artists give you. + @spec scrape(URI.t(), Scrapers.url()) :: Scrapers.scrape_result() def scrape(_uri, url) do url |> follow_redirect(2) @@ -38,10 +46,11 @@ defmodule Philomena.Scrapers.Deviantart do %{ source_url: source, author_name: artist, + description: "", images: [ %{ url: image, - camo_url: Camo.Image.image_url(image) + camo_url: PhilomenaProxy.Camo.image_url(image) } ] } @@ -51,7 +60,7 @@ defmodule Philomena.Scrapers.Deviantart do with [domain, object_uuid, object_name] <- Regex.run(@cdnint_regex, image.url, capture: :all_but_first), built_url <- "#{domain}/intermediary/f/#{object_uuid}/#{object_name}", - {:ok, %Tesla.Env{status: 200}} <- Philomena.Http.head(built_url) do + {:ok, %Tesla.Env{status: 200}} <- PhilomenaProxy.Http.head(built_url) do # This is the high resolution URL. %{ data @@ -110,7 +119,7 @@ defmodule Philomena.Scrapers.Deviantart do built_url = "http://orig01.deviantart.net/x_by_x-d#{base36}.png" - case Philomena.Http.get(built_url) do + case PhilomenaProxy.Http.get(built_url) do {:ok, %Tesla.Env{status: 301, headers: headers}} -> # Location header provides URL of high res image. {_location, link} = Enum.find(headers, fn {header, _val} -> header == "location" end) @@ -135,7 +144,7 @@ defmodule Philomena.Scrapers.Deviantart do defp follow_redirect(_url, 0), do: nil defp follow_redirect(url, max_times) do - case Philomena.Http.get(url) do + case PhilomenaProxy.Http.get(url) do {:ok, %Tesla.Env{headers: headers, status: code}} when code in [301, 302] -> location = Enum.find_value(headers, &location_header/1) follow_redirect(location, max_times - 1) diff --git a/lib/philomena/scrapers/pillowfort.ex b/lib/philomena_proxy/scrapers/pillowfort.ex similarity index 78% rename from lib/philomena/scrapers/pillowfort.ex rename to lib/philomena_proxy/scrapers/pillowfort.ex index b577c8190..6e083c9c4 100755 --- a/lib/philomena/scrapers/pillowfort.ex +++ b/lib/philomena_proxy/scrapers/pillowfort.ex @@ -1,4 +1,11 @@ -defmodule Philomena.Scrapers.Pillowfort do +defmodule PhilomenaProxy.Scrapers.Pillowfort do + @moduledoc false + + alias PhilomenaProxy.Scrapers.Scraper + alias PhilomenaProxy.Scrapers + + @behaviour Scraper + @url_regex ~r|\Ahttps?://www\.pillowfort\.social/posts/([0-9]+)| @spec can_handle?(URI.t(), String.t()) :: boolean() @@ -6,12 +13,13 @@ defmodule Philomena.Scrapers.Pillowfort do String.match?(url, @url_regex) end + @spec scrape(URI.t(), Scrapers.url()) :: Scrapers.scrape_result() def scrape(_uri, url) do [post_id] = Regex.run(@url_regex, url, capture: :all_but_first) api_url = "https://www.pillowfort.social/posts/#{post_id}/json" - Philomena.Http.get(api_url) + PhilomenaProxy.Http.get(api_url) |> json!() |> process_response!(url) end @@ -25,7 +33,7 @@ defmodule Philomena.Scrapers.Pillowfort do |> Enum.map( &%{ url: &1["url"], - camo_url: Camo.Image.image_url(&1["small_image_url"]) + camo_url: PhilomenaProxy.Camo.image_url(&1["small_image_url"]) } ) diff --git a/lib/philomena/scrapers/raw.ex b/lib/philomena_proxy/scrapers/raw.ex similarity index 56% rename from lib/philomena/scrapers/raw.ex rename to lib/philomena_proxy/scrapers/raw.ex index 0085f54c8..ed31d10ba 100644 --- a/lib/philomena/scrapers/raw.ex +++ b/lib/philomena_proxy/scrapers/raw.ex @@ -1,9 +1,16 @@ -defmodule Philomena.Scrapers.Raw do +defmodule PhilomenaProxy.Scrapers.Raw do + @moduledoc false + + alias PhilomenaProxy.Scrapers.Scraper + alias PhilomenaProxy.Scrapers + + @behaviour Scraper + @mime_types ["image/gif", "image/jpeg", "image/png", "image/svg", "image/svg+xml", "video/webm"] - @spec can_handle?(URI.t(), String.t()) :: true | false + @spec can_handle?(URI.t(), String.t()) :: boolean() def can_handle?(_uri, url) do - Philomena.Http.head(url) + PhilomenaProxy.Http.head(url) |> case do {:ok, %Tesla.Env{status: 200, headers: headers}} -> headers @@ -16,13 +23,16 @@ defmodule Philomena.Scrapers.Raw do end end + @spec scrape(URI.t(), Scrapers.url()) :: Scrapers.scrape_result() def scrape(_uri, url) do %{ source_url: url, + author_name: "", + description: "", images: [ %{ url: url, - camo_url: Camo.Image.image_url(url) + camo_url: PhilomenaProxy.Camo.image_url(url) } ] } diff --git a/lib/philomena_proxy/scrapers/scraper.ex b/lib/philomena_proxy/scrapers/scraper.ex new file mode 100644 index 000000000..15cedcea8 --- /dev/null +++ b/lib/philomena_proxy/scrapers/scraper.ex @@ -0,0 +1,11 @@ +defmodule PhilomenaProxy.Scrapers.Scraper do + @moduledoc false + + alias PhilomenaProxy.Scrapers + + # Return whether the given URL can be parsed by the scraper + @callback can_handle?(URI.t(), Scrapers.url()) :: boolean() + + # Collect upload information from the URL + @callback scrape(URI.t(), Scrapers.url()) :: Scrapers.scrape_result() +end diff --git a/lib/philomena/scrapers/tumblr.ex b/lib/philomena_proxy/scrapers/tumblr.ex similarity index 84% rename from lib/philomena/scrapers/tumblr.ex rename to lib/philomena_proxy/scrapers/tumblr.ex index 61ec1def1..fe648e66a 100644 --- a/lib/philomena/scrapers/tumblr.ex +++ b/lib/philomena_proxy/scrapers/tumblr.ex @@ -1,4 +1,11 @@ -defmodule Philomena.Scrapers.Tumblr do +defmodule PhilomenaProxy.Scrapers.Tumblr do + @moduledoc false + + alias PhilomenaProxy.Scrapers.Scraper + alias PhilomenaProxy.Scrapers + + @behaviour Scraper + @url_regex ~r|\Ahttps?://(?:.*)/(?:image\|post)/(\d+)(?:\z\|[/?#])| @media_regex ~r|https?://(?:\d+\.)?media\.tumblr\.com/[a-f\d]+/[a-f\d]+-[a-f\d]+/s\d+x\d+/[a-f\d]+\.(?:png\|jpe?g\|gif)|i @size_regex ~r|_(\d+)(\..+)\z| @@ -18,13 +25,14 @@ defmodule Philomena.Scrapers.Tumblr do String.match?(url, @url_regex) and tumblr_domain?(uri.host) end + @spec scrape(URI.t(), Scrapers.url()) :: Scrapers.scrape_result() def scrape(uri, url) do [post_id] = Regex.run(@url_regex, url, capture: :all_but_first) api_url = "https://api.tumblr.com/v2/blog/#{uri.host}/posts/photo?id=#{post_id}&api_key=#{tumblr_api_key()}" - Philomena.Http.get(api_url) + PhilomenaProxy.Http.get(api_url) |> json!() |> process_response!() end @@ -44,7 +52,7 @@ defmodule Philomena.Scrapers.Tumblr do %{"url" => preview} = Enum.find(photo["alt_sizes"], &(&1["width"] == 400)) || %{"url" => image} - %{url: image, camo_url: Camo.Image.image_url(preview)} + %{url: image, camo_url: PhilomenaProxy.Camo.image_url(preview)} end) add_meta(post, images) @@ -55,7 +63,7 @@ defmodule Philomena.Scrapers.Tumblr do @media_regex |> Regex.scan(post["body"]) |> Enum.map(fn [url | _captures] -> - %{url: url, camo_url: Camo.Image.image_url(url)} + %{url: url, camo_url: PhilomenaProxy.Camo.image_url(url)} end) add_meta(post, images) @@ -68,7 +76,7 @@ defmodule Philomena.Scrapers.Tumblr do end defp url_ok?(url) do - match?({:ok, %Tesla.Env{status: 200}}, Philomena.Http.head(url)) + match?({:ok, %Tesla.Env{status: 200}}, PhilomenaProxy.Http.head(url)) end defp add_meta(post, images) do diff --git a/lib/philomena/scrapers/twitter.ex b/lib/philomena_proxy/scrapers/twitter.ex similarity index 61% rename from lib/philomena/scrapers/twitter.ex rename to lib/philomena_proxy/scrapers/twitter.ex index 0ba64180e..def1a3748 100644 --- a/lib/philomena/scrapers/twitter.ex +++ b/lib/philomena_proxy/scrapers/twitter.ex @@ -1,16 +1,24 @@ -defmodule Philomena.Scrapers.Twitter do +defmodule PhilomenaProxy.Scrapers.Twitter do + @moduledoc false + + alias PhilomenaProxy.Scrapers.Scraper + alias PhilomenaProxy.Scrapers + + @behaviour Scraper + @url_regex ~r|\Ahttps?://(?:mobile\.)?(?:twitter\|x).com/([A-Za-z\d_]+)/status/([\d]+)/?| - @spec can_handle?(URI.t(), String.t()) :: true | false + @spec can_handle?(URI.t(), String.t()) :: boolean() def can_handle?(_uri, url) do String.match?(url, @url_regex) end + @spec scrape(URI.t(), Scrapers.url()) :: Scrapers.scrape_result() def scrape(_uri, url) do [user, status_id] = Regex.run(@url_regex, url, capture: :all_but_first) api_url = "https://api.fxtwitter.com/#{user}/status/#{status_id}" - {:ok, %Tesla.Env{status: 200, body: body}} = Philomena.Http.get(api_url) + {:ok, %Tesla.Env{status: 200, body: body}} = PhilomenaProxy.Http.get(api_url) json = Jason.decode!(body) tweet = json["tweet"] @@ -19,7 +27,7 @@ defmodule Philomena.Scrapers.Twitter do Enum.map(tweet["media"]["photos"], fn p -> %{ url: "#{p["url"]}:orig", - camo_url: Camo.Image.image_url(p["url"]) + camo_url: PhilomenaProxy.Camo.image_url(p["url"]) } end) diff --git a/lib/philomena_web/controllers/image/scrape_controller.ex b/lib/philomena_web/controllers/image/scrape_controller.ex index a46c87333..56e602e93 100644 --- a/lib/philomena_web/controllers/image/scrape_controller.ex +++ b/lib/philomena_web/controllers/image/scrape_controller.ex @@ -1,7 +1,7 @@ defmodule PhilomenaWeb.Image.ScrapeController do use PhilomenaWeb, :controller - alias Philomena.Scrapers + alias PhilomenaProxy.Scrapers def create(conn, params) do result = diff --git a/lib/philomena_web/plugs/check_captcha_plug.ex b/lib/philomena_web/plugs/check_captcha_plug.ex index d411d4052..607309ad1 100644 --- a/lib/philomena_web/plugs/check_captcha_plug.ex +++ b/lib/philomena_web/plugs/check_captcha_plug.ex @@ -31,7 +31,7 @@ defmodule PhilomenaWeb.CheckCaptchaPlug do defp valid_solution?(%{"h-captcha-response" => captcha_token}) do {:ok, %{body: body, status: 200}} = - Philomena.Http.post( + PhilomenaProxy.Http.post( "https://hcaptcha.com/siteverify", URI.encode_query(%{"response" => captcha_token, "secret" => hcaptcha_secret_key()}), [{"Content-Type", "application/x-www-form-urlencoded"}] diff --git a/lib/philomena_web/plugs/compromised_password_check_plug.ex b/lib/philomena_web/plugs/compromised_password_check_plug.ex index eaeecd2aa..b46e597f4 100644 --- a/lib/philomena_web/plugs/compromised_password_check_plug.ex +++ b/lib/philomena_web/plugs/compromised_password_check_plug.ex @@ -35,7 +35,7 @@ defmodule PhilomenaWeb.CompromisedPasswordCheckPlug do :crypto.hash(:sha, password) |> Base.encode16() - case Philomena.Http.get(make_api_url(prefix)) do + case PhilomenaProxy.Http.get(make_api_url(prefix)) do {:ok, %Tesla.Env{body: body, status: 200}} -> String.contains?(body, rest) _ -> false end diff --git a/lib/philomena_web/plugs/scraper_plug.ex b/lib/philomena_web/plugs/scraper_plug.ex index 1fcd0db17..2e4e1769a 100644 --- a/lib/philomena_web/plugs/scraper_plug.ex +++ b/lib/philomena_web/plugs/scraper_plug.ex @@ -15,7 +15,7 @@ defmodule PhilomenaWeb.ScraperPlug do %{"scraper_cache" => url} when not is_nil(url) and url != "" -> url - |> Philomena.Http.get() + |> PhilomenaProxy.Http.get() |> maybe_fixup_params(url, opts, conn) _ -> diff --git a/lib/philomena_web/views/channel_view.ex b/lib/philomena_web/views/channel_view.ex index b4dc532ea..acb4880aa 100644 --- a/lib/philomena_web/views/channel_view.ex +++ b/lib/philomena_web/views/channel_view.ex @@ -4,20 +4,24 @@ defmodule PhilomenaWeb.ChannelView do def channel_image(%{type: "LivestreamChannel", short_name: short_name}) do now = DateTime.utc_now() |> DateTime.to_unix(:microsecond) - Camo.Image.image_url( + PhilomenaProxy.Camo.image_url( "https://thumbnail.api.livestream.com/thumbnail?name=#{short_name}&rand=#{now}" ) end def channel_image(%{type: "PicartoChannel", thumbnail_url: thumbnail_url}), - do: Camo.Image.image_url(thumbnail_url || "https://picarto.tv/images/missingthumb.jpg") + do: + PhilomenaProxy.Camo.image_url(thumbnail_url || "https://picarto.tv/images/missingthumb.jpg") def channel_image(%{type: "PiczelChannel", remote_stream_id: remote_stream_id}), - do: Camo.Image.image_url("https://piczel.tv/api/thumbnail/stream_#{remote_stream_id}.jpg") + do: + PhilomenaProxy.Camo.image_url( + "https://piczel.tv/api/thumbnail/stream_#{remote_stream_id}.jpg" + ) def channel_image(%{type: "TwitchChannel", short_name: short_name}), do: - Camo.Image.image_url( + PhilomenaProxy.Camo.image_url( "https://static-cdn.jtvnw.net/previews-ttv/live_user_#{String.downcase(short_name)}-320x180.jpg" ) end diff --git a/priv/repo/seeds_development.exs b/priv/repo/seeds_development.exs index 466b31118..cde0302af 100644 --- a/priv/repo/seeds_development.exs +++ b/priv/repo/seeds_development.exs @@ -52,7 +52,7 @@ for image_def <- resources["remote_images"] do now = DateTime.utc_now() |> DateTime.to_unix(:microsecond) IO.puts "Fetching #{image_def["url"]} ..." - {:ok, %{body: body}} = Philomena.Http.get(image_def["url"]) + {:ok, %{body: body}} = PhilomenaProxy.Http.get(image_def["url"]) File.write!(file, body)