This repository has been archived by the owner on Feb 2, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
/
dispatcher.go
148 lines (141 loc) · 4.65 KB
/
dispatcher.go
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
package jobs
//
// GangGo Application Server
// Copyright (C) 2017 Lukas Matt <lukas@zauberstuhl.de>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
import (
"github.com/revel/revel"
"git.feneas.org/ganggo/ganggo/app/models"
"git.feneas.org/ganggo/federation"
)
type Dispatcher struct {
User models.User
Message interface{}
Retract bool
}
func (dispatcher Dispatcher) Run() {
switch entity := dispatcher.Message.(type) {
case models.AspectMembership:
revel.AppLog.Debug("Starting contact dispatcher")
dispatcher.Contact(entity)
case models.Post:
revel.AppLog.Debug("Starting post dispatcher")
dispatcher.StatusMessage(entity)
case models.Comment:
revel.AppLog.Debug("Starting comment dispatcher")
dispatcher.Comment(entity)
case models.Like:
revel.AppLog.Debug("Starting like dispatcher")
dispatcher.Like(entity)
// relaying entities
case federation.MessageComment:
revel.AppLog.Debug("Starting relay comment dispatcher")
dispatcher.RelayComment(entity)
case federation.MessageLike:
revel.AppLog.Debug("Starting relay like dispatcher")
dispatcher.RelayLike(entity)
case federation.MessageRetract:
revel.AppLog.Debug("Starting relay retraction dispatcher")
dispatcher.RelayRetraction(entity)
default:
revel.AppLog.Error("Unknown entity type in dispatcher!")
}
}
// findRecipients will return a list of users we should relay a post to
func (dispatcher *Dispatcher) findRecipients(parentPost *models.Post, parentUser *models.User) ([]models.Person, error) {
if parentPost != nil && parentUser != nil {
if parentPost.Public {
// everyone we are sharing with
return dispatcher.findPublicEndpoints()
} else {
// it is local we know all recipients
// lets relay the message to all remote servers
var visibility models.AspectVisibility
err := visibility.FindByPost(*parentPost)
if err != nil {
revel.AppLog.Error("Dispatcher findRecipients", err.Error(), err)
return []models.Person{}, err
}
var aspect models.Aspect
err = aspect.FindByID(visibility.AspectID)
if err != nil {
revel.AppLog.Error("Dispatcher findRecipients", err.Error(), err)
return []models.Person{}, err
}
var persons []models.Person
for _, member := range aspect.Memberships {
var person models.Person
err = person.FindByID(member.PersonID)
if err != nil {
revel.AppLog.Error("Dispatcher findRecipients", err.Error(), err)
continue
}
// skip if not reachable
if !person.Pod.Alive {
continue
}
persons = append(persons, person)
}
return persons, nil
}
} else if parentPost != nil {
// it is not local just send it to
// the remote server it should handle the rest
var persons = []models.Person{}
// skip if not reachable
if parentPost.Person.Pod.Alive {
persons = append(persons, parentPost.Person)
}
if !parentPost.Public {
// in case of AP we will fetch known visibilties as well
var visibilities models.Visibilities
err := visibilities.FindByPost(*parentPost)
if err == nil {
for _, visibility := range visibilities {
// skip if not reachable
if visibility.Person.Pod.Alive {
persons = append(persons, visibility.Person)
}
}
} else {
revel.AppLog.Error("Dispatcher findRecipients", err.Error(), err)
}
}
return persons, nil
}
return []models.Person{}, nil
}
// findPublicEndpoints will fetch all remote endpoints known to the server
// NOTE this can become a pretty heavy job needs some brain-storming
func (dispatcher *Dispatcher) findPublicEndpoints() (persons []models.Person, err error) {
var pods models.Pods
err = pods.FindAll()
if err != nil {
return
}
for _, pod := range pods {
var person models.Person
err = person.FindFirstByPodID(pod.ID)
if err != nil {
continue
}
// skip if not reachable
if person.Pod.Alive {
persons = append(persons, person)
}
}
return
}