Merge branch 'pleroma-conversations' into 'develop'
authorlain <lain@soykaf.club>
Fri, 16 Aug 2019 12:55:33 +0000 (12:55 +0000)
committerlain <lain@soykaf.club>
Fri, 16 Aug 2019 12:55:33 +0000 (12:55 +0000)
Extended Pleroma Conversations

See merge request pleroma/pleroma!1535

1  2 
CHANGELOG.md
lib/pleroma/user.ex
lib/pleroma/web/mastodon_api/views/status_view.ex
lib/pleroma/web/streamer.ex

diff --combined CHANGELOG.md
index 5f071b7e2d8593221bd4ddfdd0e4eb6e967f9b4f,2d6eac4c5d6e235767cf35fd84756c4660d75c5f..fa7818137bda45947f70e0524863b7e280e32d63
@@@ -37,15 -37,14 +37,16 @@@ The format is based on [Keep a Changelo
  - Rich Media: The crawled URL is now spliced into the rich media data.
  - ActivityPub S2S: sharedInbox usage has been mostly aligned with the rules in the AP specification.
  - ActivityPub S2S: remote user deletions now work the same as local user deletions.
 +- ActivityPub S2S: POST requests are now signed with `(request-target)` pseudo-header.
  - Not being able to access the Mastodon FE login page on private instances
  - Invalid SemVer version generation, when the current branch does not have commits ahead of tag/checked out on a tag
  - Pleroma.Upload base_url was not automatically whitelisted by MediaProxy. Now your custom CDN or file hosting will be accessed directly as expected.
  - Report email not being sent to admins when the reporter is a remote user
  - MRF: ensure that subdomain_match calls are case-insensitive
 +- MRF: fix use of unserializable keyword lists in describe() implementations
  
  ### Added
+ - Conversations: Add Pleroma-specific conversation endpoints and status posting extensions. Run the `bump_all_conversations` task again to create the necessary data.
  - **Breaking:** MRF describe API, which adds support for exposing configuration information about MRF policies to NodeInfo.
    Custom modules will need to be updated by adding, at the very least, `def describe, do: {:ok, %{}}` to the MRF policy modules.
  - MRF: Support for priming the mediaproxy cache (`Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy`)
diff --combined lib/pleroma/user.ex
index a1040fe7165d2c2384d524adff923aa58dcc2689,29712f25761fa4f7a9ca54349a2da3e65ce84420..5c3c8a8a270a42956b5d290bf5d389ecd81af461
@@@ -132,28 -132,6 +132,28 @@@ defmodule Pleroma.User d
      |> Map.put(:follower_count, follower_count)
    end
  
 +  def follow_state(%User{} = user, %User{} = target) do
 +    follow_activity = Utils.fetch_latest_follow(user, target)
 +
 +    if follow_activity,
 +      do: follow_activity.data["state"],
 +      # Ideally this would be nil, but then Cachex does not commit the value
 +      else: false
 +  end
 +
 +  def get_cached_follow_state(user, target) do
 +    key = "follow_state:#{user.ap_id}|#{target.ap_id}"
 +    Cachex.fetch!(:user_cache, key, fn _ -> {:commit, follow_state(user, target)} end)
 +  end
 +
 +  def set_follow_state_cache(user_ap_id, target_ap_id, state) do
 +    Cachex.put(
 +      :user_cache,
 +      "follow_state:#{user_ap_id}|#{target_ap_id}",
 +      state
 +    )
 +  end
 +
    def set_info_cache(user, args) do
      Cachex.put(:user_cache, "user_info:#{user.id}", user_info(user, args))
    end
      Repo.get_by(User, ap_id: ap_id)
    end
  
+   def get_all_by_ap_id(ap_ids) do
+     from(u in __MODULE__,
+       where: u.ap_id in ^ap_ids
+     )
+     |> Repo.all()
+   end
    # This is mostly an SPC migration fix. This guesses the user nickname by taking the last part
    # of the ap_id and the domain and tries to get that user
    def get_by_guessed_nickname(ap_id) do
index 7e4e992801a8508eea62a666877857fdfad9242a,d3aea2aaf8861c243fe302ec8f6b326cb78c3ed4..42fbdf51b4f645af0e20f36761840201549022b2
@@@ -8,6 -8,8 +8,8 @@@ defmodule Pleroma.Web.MastodonAPI.Statu
    require Pleroma.Constants
  
    alias Pleroma.Activity
+   alias Pleroma.Conversation
+   alias Pleroma.Conversation.Participation
    alias Pleroma.HTML
    alias Pleroma.Object
    alias Pleroma.Repo
  
    def render("index.json", opts) do
      replied_to_activities = get_replied_to_activities(opts.activities)
 +    parallel = unless is_nil(opts[:parallel]), do: opts[:parallel], else: true
  
      opts.activities
      |> safe_render_many(
        StatusView,
        "status.json",
 -      Map.put(opts, :replied_to_activities, replied_to_activities)
 +      Map.put(opts, :replied_to_activities, replied_to_activities),
 +      parallel
      )
    end
  
          object.data["url"] || object.data["external_url"] || object.data["id"]
        end
  
+     direct_conversation_id =
+       with {_, true} <- {:include_id, opts[:with_direct_conversation_id]},
+            {_, %User{} = for_user} <- {:for_user, opts[:for]},
+            %{data: %{"context" => context}} when is_binary(context) <- activity,
+            %Conversation{} = conversation <- Conversation.get_for_ap_id(context),
+            %Participation{id: participation_id} <-
+              Participation.for_user_and_conversation(for_user, conversation) do
+         participation_id
+       else
+         _e ->
+           nil
+       end
      %{
        id: to_string(activity.id),
        uri: object.data["id"],
          conversation_id: get_context_id(activity),
          in_reply_to_account_acct: reply_to_user && reply_to_user.nickname,
          content: %{"text/plain" => content_plaintext},
-         spoiler_text: %{"text/plain" => summary_plaintext}
+         spoiler_text: %{"text/plain" => summary_plaintext},
+         direct_conversation_id: direct_conversation_id
        }
      }
    end
index bbaddd8529f530e22b1fea21103541a27e7e50fb,a0bb108953286826537c6bdef9e0d5524ee37399..66c8cd2c4fa6b6657b14d0587f0c8284c6252057
@@@ -18,7 -18,7 +18,7 @@@ defmodule Pleroma.Web.Streamer d
  
    @keepalive_interval :timer.seconds(30)
  
 -  def start_link do
 +  def start_link(_) do
      GenServer.start_link(__MODULE__, %{}, name: __MODULE__)
    end
  
    end
  
    def init(args) do
 -    spawn(fn ->
 -      # 30 seconds
 -      Process.sleep(@keepalive_interval)
 -      GenServer.cast(__MODULE__, %{action: :ping})
 -    end)
 +    Process.send_after(self(), %{action: :ping}, @keepalive_interval)
  
      {:ok, args}
    end
  
 -  def handle_cast(%{action: :ping}, topics) do
 -    Map.values(topics)
 +  def handle_info(%{action: :ping}, topics) do
 +    topics
 +    |> Map.values()
      |> List.flatten()
      |> Enum.each(fn socket ->
        Logger.debug("Sending keepalive ping")
        send(socket.transport_pid, {:text, ""})
      end)
  
 -    spawn(fn ->
 -      # 30 seconds
 -      Process.sleep(@keepalive_interval)
 -      GenServer.cast(__MODULE__, %{action: :ping})
 -    end)
 +    Process.send_after(self(), %{action: :ping}, @keepalive_interval)
  
      {:noreply, topics}
    end
        payload:
          Pleroma.Web.MastodonAPI.ConversationView.render("participation.json", %{
            participation: participation,
-           user: participation.user
+           for: participation.user
          })
          |> Jason.encode!()
      }