summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorBen Busby <contact@benbusby.com>2022-06-09 13:08:01 -0600
committerBen Busby <contact@benbusby.com>2022-06-09 13:08:01 -0600
commit5006b97dfa42f9338bc2ee7080b79d37d4343cfa (patch)
treef479012e8e08a292201a822e14fbdea748982577 /lib
parentff8d220e900004671f9e52f56d4b47c3ca7a40d6 (diff)
downloadfarside-5006b97dfa42f9338bc2ee7080b79d37d4343cfa.tar.gz
Auto select frontend for links to "parent" service
Farside now supports redirecting based on a provided link to a "parent" service, if such a parent service is supported. For example, a link such as: farside.link/https://www.youtube.com/watch?v=dQw4w9WgXcQ will now redirect to any of the available YouTube related frontends. This works by matching against a mapping of "parent" service domains ("youtube.com", "reddit.com", etc) to a list of their respective frontend alternatives (["invidious", "piped"], ["libreddit", "teddit"], etc). A random element is chosen from this list, and the remainder of Farside's routing logic proceeds as if the user had chosen the service directly to begin with. Closes #37
Diffstat (limited to 'lib')
-rw-r--r--lib/farside.ex50
-rw-r--r--lib/farside/router.ex21
2 files changed, 68 insertions, 3 deletions
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 =