Skip to content

Commit

Permalink
Revert "Merge branch 'testing-both' into rich-link-fix"
Browse files Browse the repository at this point in the history
This reverts commit ee5cf0e, reversing
changes made to 4a4b4fb.
  • Loading branch information
joshuafhiggins committed Apr 14, 2024
1 parent ee5cf0e commit 253aaae
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 202 deletions.
227 changes: 47 additions & 180 deletions historysync.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,27 +145,29 @@ type messageIndex struct {
Index int
}

func (portal *Portal) convertBackfill(messages []*imessage.Message) ([]*event.Event, []messageWithIndex, map[messageIndex]int, bool, *imessage.Message, error) {
func (portal *Portal) convertBackfill(messages []*imessage.Message) ([]*event.Event, []messageWithIndex, map[messageIndex]int, bool, error) {
events := make([]*event.Event, 0, len(messages))
metas := make([]messageWithIndex, 0, len(messages))
metaIndexes := make(map[messageIndex]int, len(messages))
unreadThreshold := time.Duration(portal.bridge.Config.Bridge.Backfill.UnreadHoursThreshold) * time.Hour
var isRead bool
var lastMessage *imessage.Message
for _, msg := range messages {
if msg.Tapback != nil {
portal.log.Debugln("Skipping tapback", msg.GUID, "in backfill, handling later")
if msg.ItemType != imessage.ItemTypeMessage && msg.Tapback == nil {
portal.log.Debugln("Skipping", msg.GUID, "in backfill (not a message)")
continue
}
intent := portal.getIntentForMessage(msg, nil)
if intent == nil {
portal.log.Debugln("Skipping", msg.GUID, "in backfill (didn't get an intent)")
continue
}

//Skip the last message in the array, we will add it later to correct inbox sorting
if msg == messages[len(messages)-1] && len(messages) > 1 /* we call this function again with one element in the array for the last message, so we'll want to process it */ {
portal.log.Errorln("Skipping message", msg.GUID, "in backfill, last one in the convo")
lastMessage = msg
if msg.Tapback != nil {
// TODO handle tapbacks
portal.log.Debugln("Skipping tapback", msg.GUID, "in backfill")
continue
}

intent := portal.getIntentForMessage(msg, nil)
converted := portal.convertiMessage(msg, intent)
for index, conv := range converted {
evt := &event.Event{
Expand All @@ -180,7 +182,7 @@ func (portal *Portal) convertBackfill(messages []*imessage.Message) ([]*event.Ev
var err error
evt.Type, err = portal.encrypt(intent, &evt.Content, evt.Type)
if err != nil {
return nil, nil, nil, false, nil, err
return nil, nil, nil, false, err
}
intent.AddDoublePuppetValue(&evt.Content)
if portal.bridge.Config.Homeserver.Software == bridgeconfig.SoftwareHungry {
Expand All @@ -193,70 +195,7 @@ func (portal *Portal) convertBackfill(messages []*imessage.Message) ([]*event.Ev
}
isRead = msg.IsRead || msg.IsFromMe || (unreadThreshold >= 0 && time.Since(msg.Time) > unreadThreshold)
}
return events, metas, metaIndexes, isRead, lastMessage, nil
}

func (portal *Portal) convertTapbacks(messages []*imessage.Message) ([]*event.Event, []messageWithIndex, map[messageIndex]int, bool, *imessage.Message, error) {
events := make([]*event.Event, 0, len(messages))
metas := make([]messageWithIndex, 0, len(messages))
metaIndexes := make(map[messageIndex]int, len(messages))
unreadThreshold := time.Duration(portal.bridge.Config.Bridge.Backfill.UnreadHoursThreshold) * time.Hour
var isRead bool
var lastMessage *imessage.Message
for _, msg := range messages {
//Only want tapbacks
if msg.Tapback == nil {
portal.log.Debugln("Skipping message", msg.GUID, "in backfill, should've already handled")
continue
}

//Skip the last message in the array, we will add it later to correct inbox sorting
if msg == messages[len(messages)-1] && len(messages) > 1 /* we call this function again with one element in the array for the last message, so we'll want to process it */ {
portal.log.Errorln("Skipping message", msg.GUID, "in backfill, last one in the convo")
lastMessage = msg
continue
}

intent := portal.getIntentForMessage(msg, nil)
dbMessage := portal.bridge.DB.Message.GetByGUID(portal.GUID, msg.Tapback.TargetGUID, msg.Tapback.TargetPart)
if dbMessage == nil {
//TODO BUG: This occurs when trying to find the target reaction for a rich link, related to #183
portal.log.Errorfln("Failed to get target message for tabpack, %+v", msg)
continue
}

evt := &event.Event{
Sender: intent.UserID,
Type: event.EventReaction,
Timestamp: msg.Time.UnixMilli(),
Content: event.Content{
Parsed: &event.ReactionEventContent{
RelatesTo: event.RelatesTo{
Type: event.RelAnnotation,
EventID: dbMessage.MXID,
Key: msg.Tapback.Type.Emoji(),
},
},
},
}

var err error
evt.Type, err = portal.encrypt(intent, &evt.Content, evt.Type)
if err != nil {
return nil, nil, nil, false, nil, err
}
intent.AddDoublePuppetValue(&evt.Content)
if portal.bridge.Config.Homeserver.Software == bridgeconfig.SoftwareHungry {
evt.ID = portal.deterministicEventID(msg.GUID, 0)
}

events = append(events, evt)
metas = append(metas, messageWithIndex{msg, intent, dbMessage, 0})
metaIndexes[messageIndex{msg.GUID, 0}] = len(metas)

isRead = msg.IsRead || msg.IsFromMe || (unreadThreshold >= 0 && time.Since(msg.Time) > unreadThreshold)
}
return events, metas, metaIndexes, isRead, lastMessage, nil
return events, metas, metaIndexes, isRead, nil
}

func (portal *Portal) sendBackfill(backfillID string, messages []*imessage.Message, forward, forwardIfNoMessages, markAsRead bool) (success bool) {
Expand All @@ -273,106 +212,16 @@ func (portal *Portal) sendBackfill(backfillID string, messages []*imessage.Messa
portal.bridge.IM.SendBackfillResult(portal.GUID, backfillID, success, idMap)
}()
batchSending := portal.bridge.SpecVersions.Supports(mautrix.BeeperFeatureBatchSending)

var validMessages []*imessage.Message
for _, msg := range messages {
if msg.ItemType != imessage.ItemTypeMessage && msg.Tapback == nil {
portal.log.Debugln("Skipping", msg.GUID, "in backfill (not a message)")
continue
}
intent := portal.getIntentForMessage(msg, nil)
if intent == nil {
portal.log.Debugln("Skipping", msg.GUID, "in backfill (didn't get an intent)")
continue
}
if msg.Tapback != nil && msg.Tapback.Remove {
//If we don't process it, there won't be a reaction; at least for BB, we never have to remove a reaction
if msg.Tapback.Remove {
portal.log.Debugln("Skipping", msg.GUID, "in backfill (it was a remove tapback)")
continue
}
}

validMessages = append(validMessages, msg)
}

events, metas, metaIndexes, isRead, lastMessage, err := portal.convertBackfill(validMessages)
events, metas, metaIndexes, isRead, err := portal.convertBackfill(messages)
if err != nil {
portal.log.Errorfln("Failed to convert messages for backfill: %v", err)
return false
}
portal.log.Debugfln("Converted %d messages into %d message events to backfill", len(messages), len(events))
if len(events) == 0 {
return true
}

eventIDs, sendErr := portal.sendBackfillToMatrixServer(batchSending, forward, forwardIfNoMessages, markAsRead, isRead, events, metas, metaIndexes)
if sendErr != nil {
return false
}
portal.addBackfillToDB(metas, eventIDs, idMap, backfillID)

//We have to process tapbacks after all other messages because we need texts in the DB in order to target them
events, metas, metaIndexes, isRead, lastTapback, err := portal.convertTapbacks(validMessages)
if err != nil {
portal.log.Errorfln("Failed to convert tapbacks for backfill: %v", err)
return false
}
portal.log.Debugfln("Converted %d messages into %d tapbacks events to backfill", len(messages), len(events))
portal.log.Debugfln("Converted %d messages into %d events to backfill", len(messages), len(events))
if len(events) == 0 {
return true
}

eventIDs, sendErr = portal.sendBackfillToMatrixServer(batchSending, forward, forwardIfNoMessages, markAsRead, isRead, events, metas, metaIndexes)
if sendErr != nil {
return false
}
portal.addBackfillToDB(metas, eventIDs, idMap, backfillID)

//Process the last message in the conversation that we skipped before in converting,
// this is dumb but Beeper sorts its inbox on when the event was recieved and not the timestamp
var lastMessageArray []*imessage.Message
if lastMessage != nil {
lastMessageArray = append(lastMessageArray, lastMessage)
events, metas, metaIndexes, isRead, _, err = portal.convertBackfill(lastMessageArray)
} else if lastTapback != nil {
lastMessageArray = append(lastMessageArray, lastTapback)
events, metas, metaIndexes, isRead, _, err = portal.convertTapbacks(lastMessageArray)
}
if err != nil {
portal.log.Errorfln("Failed to convert last message for backfill: %v", err)
return false
}

eventIDs, sendErr = portal.sendBackfillToMatrixServer(batchSending, forward, forwardIfNoMessages, markAsRead, isRead, events, metas, metaIndexes)
if sendErr != nil {
return false
}
portal.addBackfillToDB(metas, eventIDs, idMap, backfillID)

portal.log.Infofln("Finished backfill %s", backfillID)
return true
}

func (portal *Portal) addBackfillToDB(metas []messageWithIndex, eventIDs []id.EventID, idMap map[string][]id.EventID, backfillID string) {
for i, meta := range metas {
idMap[meta.GUID] = append(idMap[meta.GUID], eventIDs[i])
}
txn, err := portal.bridge.DB.Begin()
if err != nil {
portal.log.Errorln("Failed to start transaction to save batch messages:", err)
}
portal.log.Debugfln("Inserting %d event IDs to database to finish backfill %s", len(eventIDs), backfillID)
portal.finishBackfill(txn, eventIDs, metas)
portal.Update(txn)
err = txn.Commit()
if err != nil {
portal.log.Errorln("Failed to commit transaction to save batch messages:", err)
}
}

func (portal *Portal) sendBackfillToMatrixServer(batchSending, forward, forwardIfNoMessages, markAsRead, isRead bool, events []*event.Event, metas []messageWithIndex,
metaIndexes map[messageIndex]int) (eventIDs []id.EventID, err error) {
var eventIDs []id.EventID
if batchSending {
req := &mautrix.ReqBeeperBatchSend{
Events: events,
Expand All @@ -385,7 +234,7 @@ func (portal *Portal) sendBackfillToMatrixServer(batchSending, forward, forwardI
resp, err := portal.MainIntent().BeeperBatchSend(portal.MXID, req)
if err != nil {
portal.log.Errorln("Failed to batch send history:", err)
return nil, err
return false
}
eventIDs = resp.EventIDs
} else {
Expand All @@ -402,7 +251,7 @@ func (portal *Portal) sendBackfillToMatrixServer(batchSending, forward, forwardI
resp, err := meta.Intent.SendMassagedMessageEvent(portal.MXID, evt.Type, &evt.Content, evt.Timestamp)
if err != nil {
portal.log.Errorfln("Failed to send event #%d in history: %v", i, err)
return nil, err
return false
}
eventIDs[i] = resp.EventID
}
Expand All @@ -414,24 +263,42 @@ func (portal *Portal) sendBackfillToMatrixServer(batchSending, forward, forwardI
}
}
}
return eventIDs, nil
for i, meta := range metas {
idMap[meta.GUID] = append(idMap[meta.GUID], eventIDs[i])
}
txn, err := portal.bridge.DB.Begin()
if err != nil {
portal.log.Errorln("Failed to start transaction to save batch messages:", err)
return true
}
portal.log.Debugfln("Inserting %d event IDs to database to finish backfill %s", len(eventIDs), backfillID)
portal.finishBackfill(txn, eventIDs, metas)
portal.Update(txn)
err = txn.Commit()
if err != nil {
portal.log.Errorln("Failed to commit transaction to save batch messages:", err)
}
portal.log.Infofln("Finished backfill %s", backfillID)
return true
}

func (portal *Portal) finishBackfill(txn dbutil.Transaction, eventIDs []id.EventID, metas []messageWithIndex) {
for i, info := range metas {
if info.Tapback != nil {
if info.Tapback.Remove {
continue
// TODO handle removing tapbacks?
} else {
// TODO can existing tapbacks be modified in backfill?
dbTapback := portal.bridge.DB.Tapback.New()
dbTapback.PortalGUID = portal.GUID
dbTapback.SenderGUID = info.Sender.String()
dbTapback.MessageGUID = info.TapbackTarget.GUID
dbTapback.MessagePart = info.TapbackTarget.Part
dbTapback.GUID = info.GUID
dbTapback.Type = info.Tapback.Type
dbTapback.MXID = eventIDs[i]
dbTapback.Insert(txn)
}
dbTapback := portal.bridge.DB.Tapback.New()
dbTapback.PortalGUID = portal.GUID
dbTapback.SenderGUID = info.Sender.String()
dbTapback.MessageGUID = info.TapbackTarget.GUID
dbTapback.MessagePart = info.TapbackTarget.Part
dbTapback.GUID = info.GUID
dbTapback.Type = info.Tapback.Type
dbTapback.MXID = eventIDs[i]
dbTapback.Insert(txn)
} else {
dbMessage := portal.bridge.DB.Message.New()
dbMessage.PortalGUID = portal.GUID
Expand Down
23 changes: 1 addition & 22 deletions imessage/bluebubbles/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -1681,7 +1681,7 @@ func (bb *blueBubbles) convertBBMessageToiMessage(bbMessage Message) (*imessage.
bbMessage.AssociatedMessageType != "" {
message.Tapback = &imessage.Tapback{
TargetGUID: bbMessage.AssociatedMessageGUID,
Type: bb.convertBBTapbackToImessageTapback(bbMessage.AssociatedMessageType),
Type: imessage.TapbackFromName(bbMessage.AssociatedMessageType),
}
message.Tapback.Parse()
} else {
Expand Down Expand Up @@ -1819,27 +1819,6 @@ func IsUrl(str string) bool {
return true
}

func (bb *blueBubbles) convertBBTapbackToImessageTapback(associatedMessageType string) (tbType imessage.TapbackType) {
if strings.Contains(associatedMessageType, "love") {
tbType = imessage.TapbackLove
} else if strings.Contains(associatedMessageType, "like") {
tbType = imessage.TapbackLike
} else if strings.Contains(associatedMessageType, "dislike") {
tbType = imessage.TapbackDislike
} else if strings.Contains(associatedMessageType, "laugh") {
tbType = imessage.TapbackLaugh
} else if strings.Contains(associatedMessageType, "emphasize") {
tbType = imessage.TapbackEmphasis
} else if strings.Contains(associatedMessageType, "question") {
tbType = imessage.TapbackQuestion
}

if strings.Contains(associatedMessageType, "-") {
tbType += imessage.TapbackRemoveOffset
}
return tbType
}

func (bb *blueBubbles) convertBBChatToiMessageChat(bbChat Chat) (*imessage.ChatInfo, error) {
members := make([]string, len(bbChat.Participants))

Expand Down

0 comments on commit 253aaae

Please sign in to comment.