71 lines
2.0 KiB
Elixir
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
|