Welcome to mirror list, hosted at ThFree Co, Russian Federation.

dispatcher.rb « federation « diaspora « lib - github.com/diaspora/diaspora.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 2ad441715dfb13659fb43af7ea671054b2f65f4b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# frozen_string_literal: true

module Diaspora
  module Federation
    class Dispatcher
      include Diaspora::Logging

      def initialize(sender, object, opts={})
        @sender = sender
        @object = object
        @opts = opts
      end

      def self.build(sender, object, opts={})
        sender = object.try(:sender_for_dispatch) || sender
        if object.try(:public?)
          Public.new(sender, object, opts)
        else
          Private.new(sender, object, opts)
        end
      end

      def self.defer_dispatch(sender, object, opts={})
        Workers::DeferredDispatch.perform_async(sender.id, object.class.to_s, object.id, opts.deep_stringify_keys)
      end

      def dispatch
        deliver_to_services
        deliver_to_subscribers
      end

      private

      attr_reader :sender, :object, :opts

      def entity
        @entity ||= Entities.build(object)
      end

      def magic_envelope
        @magic_envelope ||= DiasporaFederation::Salmon::MagicEnvelope.new(
          entity, sender.diaspora_handle
        ).envelop(sender.encryption_key)
      end

      def deliver_to_services
        deliver_to_user_services if opts[:service_types]
      end

      def deliver_to_subscribers
        local_people, remote_people = subscribers.uniq(&:id).partition(&:local?)

        deliver_to_local(local_people) unless local_people.empty?
        deliver_to_remote(remote_people)
      end

      def deliver_to_local(people)
        object_to_receive = object.object_to_receive
        return unless object_to_receive
        Workers::ReceiveLocal.perform_async(object_to_receive.class.to_s, object_to_receive.id, people.map(&:owner_id))
      end

      def deliver_to_remote(_people)
        raise NotImplementedError, "This is an abstract base method. Implement in your subclass."
      end

      def deliver_to_user_services
        case object
        when StatusMessage
          each_service {|service| Workers::PostToService.perform_async(service.id, object.id, opts[:url]) }
        when Retraction
          each_service {|service| Workers::DeletePostFromService.perform_async(service.id, opts.deep_stringify_keys) }
        end
      end

      def each_service
        sender.services.where(type: opts[:service_types]).each {|service| yield(service) }
      end

      def subscribers
        opts[:subscribers] || subscribers_from_ids || object.subscribers
      end

      def subscribers_from_ids
        Person.where(id: opts[:subscriber_ids]) if opts[:subscriber_ids]
      end
    end
  end
end

require "diaspora/federation/dispatcher/private"
require "diaspora/federation/dispatcher/public"