hydroxide-push/protonmail/events.go

183 lines
3.6 KiB
Go
Raw Permalink Normal View History

2017-09-09 19:23:14 +03:00
package protonmail
import (
2018-01-11 15:40:05 +02:00
"encoding/json"
2017-09-09 19:23:14 +03:00
"net/http"
)
2018-01-11 13:39:32 +02:00
type EventRefresh int
const (
EventRefreshMail EventRefresh = 1 << iota
EventRefreshContacts
)
2017-09-09 19:23:14 +03:00
type Event struct {
2018-10-21 13:15:20 +03:00
ID string `json:"EventID"`
Refresh EventRefresh
2018-01-11 13:39:32 +02:00
Messages []*EventMessage
2017-09-09 19:23:14 +03:00
Contacts []*EventContact
//ContactEmails
//Labels
//User
//Members
//Domains
//Organization
2018-01-11 13:39:32 +02:00
MessageCounts []*MessageCount
2017-09-09 19:23:14 +03:00
//ConversationCounts
//UsedSpace
Notices []string
}
type EventAction int
const (
EventDelete EventAction = iota
EventCreate
EventUpdate
2018-01-11 13:39:32 +02:00
// For messages
EventUpdateFlags
2017-09-09 19:23:14 +03:00
)
2018-01-11 13:39:32 +02:00
type EventMessage struct {
2018-10-21 13:15:20 +03:00
ID string
Action EventAction
2018-01-11 15:40:05 +02:00
// Only populated for EventCreate
Created *Message
// Only populated for EventUpdate or EventUpdateFlags
Updated *EventMessageUpdate
}
type EventMessageUpdate struct {
Unread *int
2018-01-11 15:40:05 +02:00
Type *MessageType
2020-09-14 13:09:50 +03:00
Time Timestamp
2018-01-11 15:40:05 +02:00
IsReplied *int
IsRepliedAll *int
IsForwarded *int
// Only populated for EventUpdateFlags
LabelIDs []string
LabelIDsAdded []string
LabelIDsRemoved []string
}
func buildLabelsSet(labelIDs []string) map[string]struct{} {
set := make(map[string]struct{}, len(labelIDs))
for _, labelID := range labelIDs {
set[labelID] = struct{}{}
}
return set
}
func (update *EventMessageUpdate) DiffLabelIDs(current []string) (added, removed []string) {
if update.LabelIDsAdded != nil && update.LabelIDsRemoved != nil {
return update.LabelIDsAdded, update.LabelIDsRemoved
}
if update.LabelIDs == nil {
return
}
currentSet := buildLabelsSet(current)
updateSet := buildLabelsSet(update.LabelIDs)
for labelID := range currentSet {
if _, ok := updateSet[labelID]; !ok {
removed = append(removed, labelID)
}
}
for labelID := range updateSet {
if _, ok := currentSet[labelID]; !ok {
added = append(added, labelID)
}
}
return
}
func (update *EventMessageUpdate) Patch(msg *Message) {
msg.Time = update.Time
if update.Unread != nil {
msg.Unread = *update.Unread
2018-01-11 15:40:05 +02:00
}
if update.Type != nil {
msg.Type = *update.Type
}
if update.IsReplied != nil {
msg.IsReplied = *update.IsReplied
}
if update.IsRepliedAll != nil {
msg.IsRepliedAll = *update.IsRepliedAll
}
if update.IsForwarded != nil {
msg.IsForwarded = *update.IsForwarded
}
if update.LabelIDs != nil {
msg.LabelIDs = update.LabelIDs
} else if update.LabelIDsAdded != nil && update.LabelIDsRemoved != nil {
set := buildLabelsSet(msg.LabelIDs)
for _, labelID := range update.LabelIDsAdded {
set[labelID] = struct{}{}
}
for _, labelID := range update.LabelIDsRemoved {
delete(set, labelID)
}
msg.LabelIDs = make([]string, 0, len(set))
for labelID := range set {
msg.LabelIDs = append(msg.LabelIDs, labelID)
}
}
}
type rawEventMessage struct {
ID string
Action EventAction
Message json.RawMessage `json:",omitempty"`
}
func (em *EventMessage) UnmarshalJSON(b []byte) error {
var raw rawEventMessage
if err := json.Unmarshal(b, &raw); err != nil {
return err
}
em.ID = raw.ID
em.Action = raw.Action
switch raw.Action {
case EventCreate:
2018-01-12 14:20:17 +02:00
em.Created = new(Message)
2018-01-11 15:40:05 +02:00
return json.Unmarshal(raw.Message, em.Created)
case EventUpdate, EventUpdateFlags:
2018-01-12 14:20:17 +02:00
em.Updated = new(EventMessageUpdate)
2018-01-11 15:40:05 +02:00
return json.Unmarshal(raw.Message, em.Updated)
}
return nil
2018-01-11 13:39:32 +02:00
}
2017-09-09 19:23:14 +03:00
type EventContact struct {
2017-09-13 12:43:12 +03:00
ID string
Action EventAction
2017-09-09 19:23:14 +03:00
Contact *Contact
}
func (c *Client) GetEvent(last string) (*Event, error) {
if last == "" {
last = "latest"
}
req, err := c.newRequest(http.MethodGet, "/events/"+last, nil)
if err != nil {
return nil, err
}
var respData struct {
resp
*Event
}
if err := c.doJSON(req, &respData); err != nil {
return nil, err
}
return respData.Event, nil
}