From 56b9c52528d1e514d4ec15f1da7517cd83bcf5ff Mon Sep 17 00:00:00 2001 From: Ben Busby Date: Mon, 8 Nov 2021 17:08:19 -0700 Subject: [PATCH] Display list of available instances on home page This introduces a number of new changes: - Services are now inserted into redis with a prefix prepended to the key name. This allows for easier filtering to get only live instances. - The home page now uses an eex template for displaying all live instances for every service, determined by the last update - A "last_updated" field was added - farside.ex was added to contain all functionality related to querying for instances (WIP) - Other improvements --- config/config.exs | 4 +++- index.eex | 50 +++++++++++++++++++++++++++++++++++++++++++ lib/farside.ex | 45 ++++++++++++++++++++++++++++++++++++++ lib/farside/router.ex | 18 ++++++++++++++-- mix.lock | 2 ++ services.json | 10 ++++----- update.exs | 14 ++++++++---- 7 files changed, 131 insertions(+), 12 deletions(-) create mode 100644 index.eex create mode 100644 lib/farside.ex diff --git a/config/config.exs b/config/config.exs index 11fa98f..3b9dfe6 100644 --- a/config/config.exs +++ b/config/config.exs @@ -4,4 +4,6 @@ config :farside, redis_conn: "redis://localhost:6379", fallback_str: "-fallback", update_file: ".update-results", - services_json: "services.json" + service_prefix: "service-", + services_json: "services.json", + index: "index.eex" diff --git a/index.eex b/index.eex new file mode 100644 index 0000000..c55e587 --- /dev/null +++ b/index.eex @@ -0,0 +1,50 @@ + + Farside + + + +
+
+

Farside | View on GitHub

+
+

Last synced <%= last_updated %> UTC

+
+
    + <%= for {service, instance_list} <- services do %> +
  • <%= service %>
  • +
      + <%= for url <- instance_list do %> +
    • <%= url %>
    • + <% end%> +
    + <% end %> +
+
+
+
+ diff --git a/lib/farside.ex b/lib/farside.ex new file mode 100644 index 0000000..9432406 --- /dev/null +++ b/lib/farside.ex @@ -0,0 +1,45 @@ +defmodule Farside do + @service_prefix Application.fetch_env!(:farside, :service_prefix) + + def get_services_map do + {:ok, redis_keys} = Redix.command(:redix, ["KEYS", "*"]) + + # Extract only service related keys + service_list = + Enum.filter( + redis_keys, + fn key -> + String.starts_with?(key, @service_prefix) + end + ) + + # Match service name to list of available instances + Enum.reduce(service_list, %{}, fn service, acc -> + {:ok, instance_list} = + Redix.command( + :redix, + ["LRANGE", service, "0", "-1"] + ) + + Map.put( + acc, + String.replace_prefix( + service, + @service_prefix, + "" + ), + instance_list + ) + end) + end + + def get_last_updated do + {:ok, last_updated} = + Redix.command( + :redix, + ["GET", "last_updated"] + ) + + last_updated + end +end diff --git a/lib/farside/router.ex b/lib/farside/router.ex index 95d9b41..82b3757 100644 --- a/lib/farside/router.ex +++ b/lib/farside/router.ex @@ -1,5 +1,7 @@ defmodule Farside.Router do + @index Application.fetch_env!(:farside, :index) @fallback_str Application.fetch_env!(:farside, :fallback_str) + @service_prefix Application.fetch_env!(:farside, :service_prefix) use Plug.Router @@ -7,7 +9,14 @@ defmodule Farside.Router do plug(:dispatch) get "/" do - send_resp(conn, 200, "") + resp = + EEx.eval_file( + @index, + last_updated: Farside.get_last_updated(), + services: Farside.get_services_map() + ) + + send_resp(conn, 200, resp) end get "/ping" do @@ -22,7 +31,12 @@ defmodule Farside.Router do {:ok, instances} = Redix.command( :redix, - ["LRANGE", service, "0", "-1"] + [ + "LRANGE", + "#{@service_prefix}#{service}", + "0", + "-1" + ] ) # Either pick a random available instance, diff --git a/mix.lock b/mix.lock index 1ada2e4..bb98ecc 100644 --- a/mix.lock +++ b/mix.lock @@ -10,7 +10,9 @@ "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"}, "mime": {:hex, :mime, "2.0.2", "0b9e1a4c840eafb68d820b0e2158ef5c49385d17fb36855ac6e7e087d4b1dcc5", [:mix], [], "hexpm", "e6a3f76b4c277739e36c2e21a2c640778ba4c3846189d5ab19f97f126df5f9b7"}, "mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"}, + "mustache": {:hex, :mustache, "0.3.1", "4c6ee79b13aae954035fe31b83c94480ddc7b536d09c44d4c65e61a9ead38d6b", [:mix], [], "hexpm", "8dc92b9b92a0d7449628f4fc981f8018a16a5b8c9907249e59db461482dac143"}, "parse_trans": {:hex, :parse_trans, "3.3.1", "16328ab840cc09919bd10dab29e431da3af9e9e7e7e6f0089dd5a2d2820011d8", [:rebar3], [], "hexpm", "07cd9577885f56362d414e8c4c4e6bdf10d43a8767abb92d24cbe8b24c54888b"}, + "phoenix_view": {:hex, :phoenix_view, "1.0.0", "fea71ecaaed71178b26dd65c401607de5ec22e2e9ef141389c721b3f3d4d8011", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}], "hexpm", "82be3e2516f5633220246e2e58181282c71640dab7afc04f70ad94253025db0c"}, "plug": {:hex, :plug, "1.12.1", "645678c800601d8d9f27ad1aebba1fdb9ce5b2623ddb961a074da0b96c35187d", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "d57e799a777bc20494b784966dc5fbda91eb4a09f571f76545b72a634ce0d30b"}, "plug_cowboy": {:hex, :plug_cowboy, "2.5.2", "62894ccd601cf9597e2c23911ff12798a8a18d237e9739f58a6b04e4988899fe", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:cowboy_telemetry, "~> 0.3", [hex: :cowboy_telemetry, repo: "hexpm", optional: false]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "ea6e87f774c8608d60c8d34022a7d073bd7680a0a013f049fc62bf35efea1044"}, "plug_crypto": {:hex, :plug_crypto, "1.2.2", "05654514ac717ff3a1843204b424477d9e60c143406aa94daf2274fdd280794d", [:mix], [], "hexpm", "87631c7ad914a5a445f0a3809f99b079113ae4ed4b867348dd9eec288cecb6db"}, diff --git a/services.json b/services.json index 1a938f4..cee766f 100644 --- a/services.json +++ b/services.json @@ -35,12 +35,12 @@ }, { "type": "bibliogram", - "test_url": "/taylorswift", - "fallback": "https://bibliogram.art/u", + "test_url": "/u/taylorswift", + "fallback": "https://bibliogram.art", "instances": [ - "https://bibliogram.art/u", - "https://bibliogram.snopyta.org/u", - "https://bibliogram.pussthecat.org/u", + "https://bibliogram.art", + "https://bibliogram.snopyta.org", + "https://bibliogram.pussthecat.org", "https://bibliogram.1d4.us", "https://insta.trom.tf", "https://bibliogram.hamster.dance", diff --git a/update.exs b/update.exs index fe1445b..4e95392 100644 --- a/update.exs +++ b/update.exs @@ -11,6 +11,7 @@ defmodule Instances do @fallback_str Application.fetch_env!(:farside, :fallback_str) @update_file Application.fetch_env!(:farside, :update_file) @services_json Application.fetch_env!(:farside, :services_json) + @service_prefix Application.fetch_env!(:farside, :service_prefix) def init() do File.rename(@update_file, "#{@update_file}-prev") @@ -45,18 +46,16 @@ defmodule Instances do end def add_to_redis(service, instances) do - IO.puts " --------" - IO.inspect "OK: " <> instances # Remove previous list of instances Redix.command(:redix, [ "DEL", - service.type + "#{@service_prefix}#{service.type}" ]) # Update with new list of available instances Redix.command(:redix, [ "LPUSH", - service.type + "#{@service_prefix}#{service.type}" ] ++ instances) # Set fallback to one of the available instances, @@ -84,3 +83,10 @@ defmodule Instances do end Instances.init() + +# Add UTC time of last update +Redix.command(:redix, [ + "SET", + "last_updated", + Calendar.strftime(DateTime.utc_now(), "%c") +])