summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--lib/farside.ex50
-rw-r--r--lib/farside/router.ex21
-rw-r--r--test/farside_test.exs18
4 files changed, 88 insertions, 3 deletions
diff --git a/.gitignore b/.gitignore
index 87fe868..e4f7466 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,3 +13,5 @@ erl_crash.dump
.update-result*
*.rdb
+.idea/
+*.iml
diff --git a/lib/farside.ex b/lib/farside.ex
index 16dc074..97a14bc 100644
--- a/lib/farside.ex
+++ b/lib/farside.ex
@@ -3,6 +3,21 @@ defmodule Farside do
@fallback_suffix Application.fetch_env!(:farside, :fallback_suffix)
@previous_suffix Application.fetch_env!(:farside, :previous_suffix)
+ # Define relation between available services and their parent service.
+ # This enables Farside to redirect with links such as:
+ # farside.link/https://www.youtube.com/watch?v=dQw4w9WgXcQ
+ @parent_services %{
+ "youtube.com" => ["invidious", "piped"],
+ "reddit.com" => ["libreddit", "teddit"],
+ "instagram.com" => ["bibliogram"],
+ "twitter.com" => ["nitter"],
+ "wikipedia.org" => ["wikiless"],
+ "medium.com" => ["scribe"],
+ "odysee.com" => ["librarian"],
+ "imgur.com" => ["rimgo"],
+ "translate.google.com" => ["lingva"]
+ }
+
def get_services_map do
{:ok, service_list} = Redix.command(:redix, ["KEYS", "#{@service_prefix}*"])
@@ -26,7 +41,42 @@ defmodule Farside do
end)
end
+ def get_service(service) do
+ # Check if service has an entry in Redis, otherwise try to
+ # match against available parent services
+ service_name = cond do
+ !check_service(service) ->
+ Enum.find_value(
+ @parent_services,
+ fn {k, v} ->
+ service =~ k && Enum.random(v)
+ end)
+ true ->
+ service
+ end
+
+ service_name
+ end
+
+ def check_service(service) do
+ # Checks to see if a specific service has instances available
+ # in redis
+ {:ok, instances} =
+ Redix.command(
+ :redix,
+ [
+ "LRANGE",
+ "#{@service_prefix}#{service}",
+ "0",
+ "-1"
+ ]
+ )
+
+ Enum.count(instances) > 0
+ end
+
def last_instance(service) do
+ # Fetches the last selected instance for a particular service
{:ok, previous} =
Redix.command(
:redix,
diff --git a/lib/farside/router.ex b/lib/farside/router.ex
index 2419055..e2902f6 100644
--- a/lib/farside/router.ex
+++ b/lib/farside/router.ex
@@ -39,12 +39,27 @@ defmodule Farside.Router do
end
get "/:service/*glob" do
- path = Enum.join(glob, "/")
+ service_name = cond do
+ service =~ "http" ->
+ List.first(glob)
+ true ->
+ service
+ end
+
+ path = cond do
+ service_name != service ->
+ Enum.join(Enum.slice(glob, 1..-1), "/")
+ true ->
+ Enum.join(glob, "/")
+ end
+
instance = cond do
conn.assigns[:throttle] != nil ->
- Farside.last_instance(service)
+ Farside.get_service(service_name)
+ |> Farside.last_instance
true ->
- Farside.pick_instance(service)
+ Farside.get_service(service_name)
+ |> Farside.pick_instance
end
params =
diff --git a/test/farside_test.exs b/test/farside_test.exs
index 05497f3..25828c6 100644
--- a/test/farside_test.exs
+++ b/test/farside_test.exs
@@ -77,4 +77,22 @@ defmodule FarsideTest do
assert first_redirect != second_redirect
end)
end
+
+ test "/https://..." do
+ parent_service = "https://www.youtube.com"
+ parent_path = "watch?v=dQw4w9WgXcQ"
+ conn = test_conn("/#{parent_service}/#{parent_path}")
+
+ redirect = elem(List.last(conn.resp_headers), 1)
+
+ IO.puts("")
+ IO.puts(" /#{parent_service}/#{parent_path}")
+ IO.puts(" redirected to")
+ IO.puts(" #{redirect}")
+
+ assert conn.state == :set
+ assert conn.status == 302
+ assert redirect =~ parent_path
+ assert !(redirect =~ parent_service)
+ end
end