mobilizon/lib/service/site_map.ex

71 lines
2.0 KiB
Elixir

defmodule Mobilizon.Service.SiteMap do
@moduledoc """
Generates a sitemap
"""
alias Mobilizon.{Actors, Events, Posts}
alias Mobilizon.Storage.Repo
alias Mobilizon.Web.Endpoint
use Mobilizon.Web, :verified_routes
@default_static_frequency :monthly
@spec generate_sitemap :: {:ok, :ok}
def generate_sitemap do
static_routes = [
{url(~p"/*path"), :daily},
"#{Endpoint.url()}/search",
"#{Endpoint.url()}/about/instance",
"#{Endpoint.url()}/terms",
"#{Endpoint.url()}/privacy",
"#{Endpoint.url()}/rules",
"#{Endpoint.url()}/glossary"
]
config = [
store: Sitemapper.FileStore,
store_config: [path: Application.get_env(:mobilizon, __MODULE__) |> get_in([:path])],
sitemap_url: Endpoint.url(),
gzip: false
]
Repo.transaction(
fn ->
Events.stream_events_for_sitemap()
|> Stream.concat(Actors.list_groups_for_stream())
|> Stream.concat(Posts.list_posts_for_stream())
|> Stream.concat(
Enum.map(static_routes, fn route ->
{url, frequency} =
case route do
{url, frequency} -> {url, frequency}
url when is_binary(url) -> {url, @default_static_frequency}
end
%{url: url, updated_at: nil, frequence: frequency}
end)
)
|> Stream.map(fn %{url: url, updated_at: updated_at} = args ->
frequence = Map.get(args, :frequence, :weekly)
%Sitemapper.URL{
loc: url,
changefreq: frequence,
lastmod: check_date_time(updated_at)
}
end)
|> Sitemapper.generate(config)
|> Sitemapper.persist(config)
|> Stream.run()
end,
timeout: :infinity
)
end
# Sometimes we use naive datetimes
@spec check_date_time(any()) :: DateTime.t() | nil
defp check_date_time(%NaiveDateTime{} = datetime), do: DateTime.from_naive!(datetime, "Etc/UTC")
defp check_date_time(%DateTime{} = datetime), do: datetime
defp check_date_time(_), do: nil
end