Parse open group attachments

This commit is contained in:
Niels Andriesse 2020-11-30 12:00:26 +11:00
parent b621bdc69a
commit 8564c650a5
4 changed files with 66 additions and 23 deletions

View File

@ -1,35 +1,74 @@
internal extension OpenGroupMessage {
static func from(_ message: VisibleMessage, for server: String) -> OpenGroupMessage? {
guard message.isValid else { preconditionFailure() } // Should be valid at this point
static func from(_ message: VisibleMessage, for server: String, using transaction: YapDatabaseReadWriteTransaction) -> OpenGroupMessage? {
let storage = Configuration.shared.storage
let displayName = storage.getUserDisplayName() ?? "Anonymous"
guard let userPublicKey = storage.getUserPublicKey() else { return nil }
// Validation
guard message.isValid else { return nil } // Should be valid at this point
// Quote
let quote: OpenGroupMessage.Quote? = {
if let quote = message.quote {
guard quote.isValid else { return nil }
return OpenGroupMessage.Quote(quotedMessageTimestamp: quote.timestamp!, quoteePublicKey: quote.publicKey!, quotedMessageBody: quote.text!, quotedMessageServerID: nil) // TODO: Server ID
let quotedMessageServerID = TSIncomingMessage.find(withAuthorId: quote.publicKey!, timestamp: quote.timestamp!, transaction: transaction)?.openGroupServerMessageID
return OpenGroupMessage.Quote(quotedMessageTimestamp: quote.timestamp!, quoteePublicKey: quote.publicKey!, quotedMessageBody: quote.text, quotedMessageServerID: quotedMessageServerID)
} else {
return nil
}
}()
let body = message.text!
// Message
let displayName = storage.getUserDisplayName() ?? "Anonymous"
let body = message.text ?? String(message.sentTimestamp!) // The back-end doesn't accept messages without a body so we use this as a workaround
let result = OpenGroupMessage(serverID: nil, senderPublicKey: userPublicKey, displayName: displayName, profilePicture: nil, body: body,
type: OpenGroupAPI.openGroupMessageType, timestamp: message.sentTimestamp!, quote: quote, attachments: [], signature: nil, serverTimestamp: 0)
if let linkPreview: OpenGroupMessage.Attachment = {
if let linkPreview = message.linkPreview {
guard linkPreview.isValid else { return nil }
// TODO: Implement
return OpenGroupMessage.Attachment(kind: .linkPreview, server: server, serverID: 0, contentType: "", size: 0, fileName: "",
flags: 0, width: 0, height: 0, caption: "", url: "", linkPreviewURL: "", linkPreviewTitle: "")
} else {
return nil
}
}() {
result.attachments.append(linkPreview)
// Link preview
if let linkPreview = message.linkPreview {
guard linkPreview.isValid, let attachmentID = linkPreview.attachmentID,
let attachment = TSAttachmentStream.fetch(uniqueId: attachmentID, transaction: transaction) else { return nil }
let fileName = attachment.sourceFilename ?? UUID().uuidString
let width = attachment.shouldHaveImageSize() ? attachment.imageSize().width : 0
let height = attachment.shouldHaveImageSize() ? attachment.imageSize().height : 0
let openGroupLinkPreview = OpenGroupMessage.Attachment(
kind: .linkPreview,
server: server,
serverID: 0,
contentType: attachment.contentType,
size: UInt(attachment.byteCount),
fileName: fileName,
flags: 0,
width: UInt(width),
height: UInt(height),
caption: attachment.caption,
url: attachment.downloadURL,
linkPreviewURL: linkPreview.url,
linkPreviewTitle: linkPreview.title
)
result.attachments.append(openGroupLinkPreview)
}
// TODO: Attachments
// Attachments
let attachments: [OpenGroupMessage.Attachment] = message.attachmentIDs.compactMap { attachmentID in
guard let attachment = TSAttachmentStream.fetch(uniqueId: attachmentID, transaction: transaction) else { return nil } // Should never occur
let fileName = attachment.sourceFilename ?? UUID().uuidString
let width = attachment.shouldHaveImageSize() ? attachment.imageSize().width : 0
let height = attachment.shouldHaveImageSize() ? attachment.imageSize().height : 0
return OpenGroupMessage.Attachment(
kind: .attachment,
server: server,
serverID: 0,
contentType: attachment.contentType,
size: UInt(attachment.byteCount),
fileName: fileName,
flags: 0,
width: UInt(width),
height: UInt(height),
caption: attachment.caption,
url: attachment.downloadURL,
linkPreviewURL: nil,
linkPreviewTitle: nil
)
}
result.attachments += attachments
// Return
return result
}
}

View File

@ -34,7 +34,7 @@ public final class OpenGroupMessage : NSObject {
public struct Quote {
public let quotedMessageTimestamp: UInt64
public let quoteePublicKey: String
public let quotedMessageBody: String
public let quotedMessageBody: String?
public let quotedMessageServerID: UInt64?
}
@ -96,7 +96,7 @@ public final class OpenGroupMessage : NSObject {
quotedMessageTimestamp: UInt64, quoteePublicKey: String?, quotedMessageBody: String?, quotedMessageServerID: UInt64,
signatureData: Data?, signatureVersion: UInt64, serverTimestamp: UInt64) {
let quote: Quote?
if quotedMessageTimestamp != 0, let quoteeHexEncodedPublicKey = quoteePublicKey, let quotedMessageBody = quotedMessageBody {
if quotedMessageTimestamp != 0, let quoteeHexEncodedPublicKey = quoteePublicKey {
let quotedMessageServerID = (quotedMessageServerID != 0) ? quotedMessageServerID : nil
quote = Quote(quotedMessageTimestamp: quotedMessageTimestamp, quoteePublicKey: quoteeHexEncodedPublicKey, quotedMessageBody: quotedMessageBody, quotedMessageServerID: quotedMessageServerID)
} else {
@ -137,7 +137,8 @@ public final class OpenGroupMessage : NSObject {
internal func toJSON() -> JSON {
var value: JSON = [ "timestamp" : timestamp ]
if let quote = quote {
value["quote"] = [ "id" : quote.quotedMessageTimestamp, "author" : quote.quoteePublicKey, "text" : quote.quotedMessageBody ]
value["quote"] = [ "id" : quote.quotedMessageTimestamp, "author" : quote.quoteePublicKey ]
if let quotedMessageBody = quote.quotedMessageBody { value["text"] = quotedMessageBody }
}
if let signature = signature {
value["sig"] = signature.data.toHexString()
@ -183,7 +184,10 @@ public final class OpenGroupMessage : NSObject {
private func getValidationData(for signatureVersion: UInt64) -> Data? {
var string = "\(body.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines))\(timestamp)"
if let quote = quote {
string += "\(quote.quotedMessageTimestamp)\(quote.quoteePublicKey)\(quote.quotedMessageBody.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines))"
string += "\(quote.quotedMessageTimestamp)\(quote.quoteePublicKey)"
if let quotedMessageBody = quote.quotedMessageBody {
string += "\(quotedMessageBody.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines))"
}
if let quotedMessageServerID = quote.quotedMessageServerID {
string += "\(quotedMessageServerID)"
}

View File

@ -231,7 +231,7 @@ public final class MessageSender : NSObject {
}
}()
guard let message = message as? VisibleMessage,
let openGroupMessage = OpenGroupMessage.from(message, for: server) else { seal.reject(Error.invalidMessage); return promise }
let openGroupMessage = OpenGroupMessage.from(message, for: server, using: transaction as! YapDatabaseReadWriteTransaction) else { seal.reject(Error.invalidMessage); return promise }
// Send the result
OpenGroupAPI.sendMessage(openGroupMessage, to: channel, on: server).done(on: DispatchQueue.global(qos: .userInitiated)) { openGroupMessage in
message.openGroupServerMessageID = openGroupMessage.serverID

View File

@ -119,7 +119,7 @@ public final class OpenGroupPoller : NSObject {
dataMessage.setGroup(try! groupContext.build())
if let quote = message.quote {
let signalQuote = SNProtoDataMessageQuote.builder(id: quote.quotedMessageTimestamp, author: quote.quoteePublicKey)
signalQuote.setText(quote.quotedMessageBody)
if let quotedMessageBody = quote.quotedMessageBody { signalQuote.setText(quotedMessageBody) }
dataMessage.setQuote(try! signalQuote.build())
}
let body = (message.body == message.timestamp.description) ? "" : message.body // Workaround for the fact that the back-end doesn't accept messages without a body