Merge branch 'extract-nodeinfo-metadata' into 'main'
feat(nodeinfo): extract and save NodeInfo information from instances to... Closes #1392 See merge request framasoft/mobilizon!1513
This commit is contained in:
39
lib/mobilizon/instances/instance_actor.ex
Normal file
39
lib/mobilizon/instances/instance_actor.ex
Normal file
@@ -0,0 +1,39 @@
|
||||
defmodule Mobilizon.Instances.InstanceActor do
|
||||
@moduledoc """
|
||||
An instance actor
|
||||
"""
|
||||
use Ecto.Schema
|
||||
import Ecto.Changeset
|
||||
alias Mobilizon.Actors.Actor
|
||||
|
||||
@type t :: %__MODULE__{
|
||||
domain: String.t(),
|
||||
actor: Actor.t(),
|
||||
instance_name: String.t(),
|
||||
instance_description: String.t(),
|
||||
software: String.t(),
|
||||
software_version: String.t()
|
||||
}
|
||||
|
||||
schema "instance_actors" do
|
||||
field(:domain, :string)
|
||||
field(:instance_name, :string)
|
||||
field(:instance_description, :string)
|
||||
field(:software, :string)
|
||||
field(:software_version, :string)
|
||||
belongs_to(:actor, Actor)
|
||||
|
||||
timestamps()
|
||||
end
|
||||
|
||||
@required_attrs [:domain]
|
||||
@optional_attrs [:actor_id, :instance_name, :instance_description, :software, :software_version]
|
||||
@attrs @required_attrs ++ @optional_attrs
|
||||
|
||||
def changeset(%__MODULE__{} = instance_actor, attrs) do
|
||||
instance_actor
|
||||
|> cast(attrs, @attrs)
|
||||
|> validate_required(@required_attrs)
|
||||
|> unique_constraint(:domain)
|
||||
end
|
||||
end
|
||||
@@ -4,7 +4,7 @@ defmodule Mobilizon.Instances do
|
||||
"""
|
||||
alias Ecto.Adapters.SQL
|
||||
alias Mobilizon.Actors.{Actor, Follower}
|
||||
alias Mobilizon.Instances.Instance
|
||||
alias Mobilizon.Instances.{Instance, InstanceActor}
|
||||
alias Mobilizon.Storage.{Page, Repo}
|
||||
import Ecto.Query
|
||||
|
||||
@@ -12,13 +12,13 @@ defmodule Mobilizon.Instances do
|
||||
|
||||
@spec instances(Keyword.t()) :: Page.t(Instance.t())
|
||||
def instances(options) do
|
||||
page = Keyword.get(options, :page)
|
||||
limit = Keyword.get(options, :limit)
|
||||
order_by = Keyword.get(options, :order_by)
|
||||
direction = Keyword.get(options, :direction)
|
||||
page = Keyword.get(options, :page, 1)
|
||||
limit = Keyword.get(options, :limit, 10)
|
||||
order_by = Keyword.get(options, :order_by, :event_count)
|
||||
direction = Keyword.get(options, :direction, :desc)
|
||||
filter_domain = Keyword.get(options, :filter_domain)
|
||||
# suspend_status = Keyword.get(options, :filter_suspend_status)
|
||||
follow_status = Keyword.get(options, :filter_follow_status)
|
||||
# suspend_status = Keyword.get(options, :filter_suspend_status, :all)
|
||||
follow_status = Keyword.get(options, :filter_follow_status, :all)
|
||||
|
||||
order_by_options = Keyword.new([{direction, order_by}])
|
||||
|
||||
@@ -42,7 +42,9 @@ defmodule Mobilizon.Instances do
|
||||
query =
|
||||
Instance
|
||||
|> join(:left, [i], s in subquery(subquery), on: i.domain == s.domain)
|
||||
|> select([i, s], {i, s})
|
||||
|> join(:left, [i], ia in InstanceActor, on: i.domain == ia.domain)
|
||||
|> join(:left, [_i, _s, ia], a in Actor, on: ia.actor_id == a.id)
|
||||
|> select([i, s, ia, a], {i, s, ia, a})
|
||||
|> order_by(^order_by_options)
|
||||
|
||||
query =
|
||||
@@ -100,16 +102,72 @@ defmodule Mobilizon.Instances do
|
||||
following: following,
|
||||
following_approved: following_approved,
|
||||
has_relay: has_relay
|
||||
}}
|
||||
}, instance_meta, instance_actor}
|
||||
) do
|
||||
instance
|
||||
|> Map.put(:follower_status, follow_status(following, following_approved))
|
||||
|> Map.put(:followed_status, follow_status(follower, follower_approved))
|
||||
|> Map.put(:has_relay, has_relay)
|
||||
|> Map.put(:instance_actor, instance_actor)
|
||||
|> add_metadata_details(instance_meta)
|
||||
end
|
||||
|
||||
@spec add_metadata_details(map(), InstanceActor.t() | nil) :: map()
|
||||
defp add_metadata_details(instance, nil), do: instance
|
||||
|
||||
defp add_metadata_details(instance, instance_meta) do
|
||||
instance
|
||||
|> Map.put(:instance_name, instance_meta.instance_name)
|
||||
|> Map.put(:instance_description, instance_meta.instance_description)
|
||||
|> Map.put(:software, instance_meta.software)
|
||||
|> Map.put(:software_version, instance_meta.software_version)
|
||||
end
|
||||
|
||||
defp follow_status(true, true), do: :approved
|
||||
defp follow_status(true, false), do: :pending
|
||||
defp follow_status(false, _), do: :none
|
||||
defp follow_status(nil, _), do: :none
|
||||
|
||||
@spec get_instance_actor(String.t()) :: InstanceActor.t() | nil
|
||||
def get_instance_actor(domain) do
|
||||
InstanceActor
|
||||
|> Repo.get_by(domain: domain)
|
||||
|> Repo.preload(:actor)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Creates an instance actor.
|
||||
"""
|
||||
@spec create_instance_actor(map) :: {:ok, InstanceActor.t()} | {:error, Ecto.Changeset.t()}
|
||||
def create_instance_actor(attrs \\ %{}) do
|
||||
with {:ok, %InstanceActor{} = instance_actor} <-
|
||||
%InstanceActor{}
|
||||
|> InstanceActor.changeset(attrs)
|
||||
|> Repo.insert(on_conflict: :replace_all, conflict_target: :domain) do
|
||||
{:ok, Repo.preload(instance_actor, :actor)}
|
||||
end
|
||||
end
|
||||
|
||||
@doc """
|
||||
Updates an instance actor.
|
||||
"""
|
||||
@spec update_instance_actor(InstanceActor.t(), map) ::
|
||||
{:ok, InstanceActor.t()} | {:error, Ecto.Changeset.t()}
|
||||
def update_instance_actor(%InstanceActor{} = instance_actor, attrs) do
|
||||
with {:ok, %InstanceActor{} = instance_actor} <-
|
||||
instance_actor
|
||||
|> Repo.preload(:actor)
|
||||
|> InstanceActor.changeset(attrs)
|
||||
|> Repo.update() do
|
||||
{:ok, Repo.preload(instance_actor, :actor)}
|
||||
end
|
||||
end
|
||||
|
||||
@doc """
|
||||
Deletes a post
|
||||
"""
|
||||
@spec delete_instance_actor(InstanceActor.t()) :: {:ok, Post.t()} | {:error, Ecto.Changeset.t()}
|
||||
def delete_instance_actor(%InstanceActor{} = instance_actor) do
|
||||
Repo.delete(instance_actor)
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user