diff --git a/yowsup/layers/axolotl/layer.py b/yowsup/layers/axolotl/layer.py index f437e33a4..826e2f2e2 100644 --- a/yowsup/layers/axolotl/layer.py +++ b/yowsup/layers/axolotl/layer.py @@ -3,7 +3,7 @@ from yowsup.layers.network.layer import YowNetworkLayer from yowsup.layers.auth.layer_authentication import YowAuthenticationProtocolLayer from yowsup.layers.protocol_acks.protocolentities import OutgoingAckProtocolEntity -from yowsup.layers.axolotl.e2e_pb2 import * +from yowsup.layers.protocol_messages.proto.wa_pb2 import * from yowsup.layers.axolotl.store.sqlite.liteaxolotlstore import LiteAxolotlStore from yowsup.layers.axolotl.protocolentities import * from yowsup.structs import ProtocolTreeNode diff --git a/yowsup/layers/interface/interface.py b/yowsup/layers/interface/interface.py index 9674e37d1..763309e11 100644 --- a/yowsup/layers/interface/interface.py +++ b/yowsup/layers/interface/interface.py @@ -4,11 +4,12 @@ from yowsup.layers.auth import YowAuthenticationProtocolLayer from yowsup.layers.protocol_receipts.protocolentities import OutgoingReceiptProtocolEntity from yowsup.layers.protocol_acks.protocolentities import IncomingAckProtocolEntity -from yowsup.layers.network.layer import YowNetworkLayer -from yowsup.layers import EventCallback +from yowsup.layers.axolotl.layer import YowAxolotlLayer +from yowsup.layers.protocol_media.protocolentities.iq_requestupload import RequestUploadIqProtocolEntity +from yowsup.layers.protocol_media.protocolentities.iq_requestupload_result import ResultRequestUploadIqProtocolEntity +from yowsup.layers.protocol_media.mediauploader import MediaUploader +from yowsup.layers.axolotl.layer import YowAxolotlLayer import inspect -import logging -logger = logging.getLogger(__name__) class ProtocolEntityCallback(object): def __init__(self, entityType): @@ -17,15 +18,12 @@ def __init__(self, entityType): def __call__(self, fn): fn.entity_callback = self.entityType return fn - -class YowInterfaceLayer(YowLayer): - PROP_RECONNECT_ON_STREAM_ERR = "org.openwhatsapp.yowsup.prop.interface.reconnect_on_stream_error" +class YowInterfaceLayer(YowLayer): def __init__(self): super(YowInterfaceLayer, self).__init__() - self.reconnect = False self.entity_callbacks = {} self.iqRegistry = {} # self.receiptsRegistry = {} @@ -35,40 +33,13 @@ def __init__(self): fname = m[0] fn = m[1] self.entity_callbacks[fn.entity_callback] = getattr(self, fname) - + def _sendIq(self, iqEntity, onSuccess = None, onError = None): assert iqEntity.getTag() == "iq", "Expected *IqProtocolEntity in _sendIq, got %s" % iqEntity.getTag() self.iqRegistry[iqEntity.getId()] = (iqEntity, onSuccess, onError) self.toLower(iqEntity) - # def _sendReceipt(self, outgoingReceiptProtocolEntity, onAck = None): - # assert outgoingReceiptProtocolEntity.__class__ == OutgoingReceiptProtocolEntity,\ - # "Excepted OutgoingReceiptProtocolEntity in _sendReceipt, got %s" % outgoingReceiptProtocolEntity.__class__ - # self.receiptsRegistry[outgoingReceiptProtocolEntity.getId()] = (outgoingReceiptProtocolEntity, onAck) - # self.toLower(outgoingReceiptProtocolEntity) - - # def processReceiptsRegistry(self, incomingAckProtocolEntity): - # ''' - # entity: IncomingAckProtocolEntity - # ''' - # - # if incomingAckProtocolEntity.__class__ != IncomingAckProtocolEntity: - # return False - # - # receipt_id = incomingAckProtocolEntity.getId() - # if receipt_id in self.receiptsRegistry: - # originalReceiptEntity, ackClbk = self.receiptsRegistry[receipt_id] - # del self.receiptsRegistry[receipt_id] - # - # if ackClbk: - # ackClbk(incomingAckProtocolEntity, originalReceiptEntity) - # - # return True - # - # return False - - def processIqRegistry(self, entity): """ :type entity: IqProtocolEntity @@ -107,27 +78,41 @@ def receive(self, entity): self.entity_callbacks[entityType](entity) else: self.toUpper(entity) - - @ProtocolEntityCallback("stream:error") - def onStreamError(self, streamErrorEntity): - logger.error(streamErrorEntity) - if self.getProp(self.__class__.PROP_RECONNECT_ON_STREAM_ERR, True): - logger.info("Initiating reconnect") - self.reconnect = True - self.disconnect() + + def _sendMediaMessage(self, builder, success, error = None, progress = None): + # axolotlIface = self.getLayerInterface(YowAxolotlLayer) + # if axolotlIface: + # axolotlIface.encryptMedia(builder) + + iq = RequestUploadIqProtocolEntity(builder.mediaType, filePath = builder.getFilepath(), encrypted = builder.isEncrypted()) + successFn = lambda resultEntity, requestUploadEntity: self.__onRequestUploadSuccess(resultEntity, requestUploadEntity, builder, success, error, progress) + errorFn = lambda errorEntity, requestUploadEntity: self.__onRequestUploadError(errorEntity, requestUploadEntity, error) + self._sendIq(iq, successFn, errorFn) + + def __onRequestUploadSuccess(self, resultRequestUploadIqProtocolEntity, requestUploadEntity, builder, success, error = None, progress = None): + if(resultRequestUploadIqProtocolEntity.isDuplicate()): + return success(builder.build(resultRequestUploadIqProtocolEntity.getUrl(), resultRequestUploadIqProtocolEntity.getIp())) else: - logger.warn("No reconnecting because property %s is not set" % self.__class__.PROP_RECONNECT_ON_STREAM_ERR) - self.toUpper(streamErrorEntity) - - @EventCallback(YowNetworkLayer.EVENT_STATE_CONNECTED) - def onConnected(self, yowLayerEvent): - self.reconnect = False - - @EventCallback(YowNetworkLayer.EVENT_STATE_DISCONNECTED) - def onDisconnected(self, yowLayerEvent): - if self.reconnect: - self.reconnect = False - self.connect() + successFn = lambda path, jid, url: self.__onMediaUploadSuccess(builder, url, resultRequestUploadIqProtocolEntity.getIp(), success) + errorFn = lambda path, jid, errorText: self.__onMediaUploadError(builder, errorText, error) + + mediaUploader = MediaUploader(builder.jid, self.getOwnJid(), builder.getFilepath(), + resultRequestUploadIqProtocolEntity.getUrl(), + resultRequestUploadIqProtocolEntity.getResumeOffset(), + successFn, errorFn, progress, async=True) + mediaUploader.start() + + def __onRequestUploadError(self, errorEntity, requestUploadEntity, builder, error = None): + if error: + return error(errorEntity.code, errorEntity.text, errorEntity.backoff) + + def __onMediaUploadSuccess(self, builder, url, ip, successClbk): + messageNode = builder.build(url, ip) + return successClbk(messageNode) + + def __onMediaUploadError(self, builder, errorText, errorClbk = None): + if errorClbk: + return errorClbk(0, errorText, 0) def __str__(self): return "Interface Layer" diff --git a/yowsup/layers/protocol_media/protocolentities/builder_message_media_downloadable.py b/yowsup/layers/protocol_media/protocolentities/builder_message_media_downloadable.py new file mode 100644 index 000000000..458f7f25b --- /dev/null +++ b/yowsup/layers/protocol_media/protocolentities/builder_message_media_downloadable.py @@ -0,0 +1,61 @@ +# from yowsup.layers.protocol_media import mediacipher +import tempfile +import os +class DownloadableMediaMessageBuilder(object): + def __init__(self, downloadbleMediaMessageClass, jid, filepath): + self.jid = jid + self.filepath = filepath + self.encryptedFilepath = None + self.cls = downloadbleMediaMessageClass + self.mediaKey = None + self.attributes = {} + self.mediaType = self.cls.__name__.split("DownloadableMediaMessageProtocolEntity")[0].lower() #ugly ? + + # def encrypt(self): + # fd, encpath = tempfile.mkstemp() + # mediaKey = os.urandom(112) + # keys = mediacipher.getDerivedKeys(mediaKey) + # out = mediacipher.encryptImage(self.filepath, keys) + # with open(encImagePath, 'w') as outF: + # outF.write(out) + # + # self.mediaKey = mediaKey + # self.encryptedFilepath = encpath + + # def decrypt(self): + # self.mediaKey = None + # self.encryptedFilePath = None + + + def setEncryptionData(self, mediaKey, encryptedFilepath): + self.mediaKey = mediaKey + self.encryptedFilepath = encryptedFilepath + + def isEncrypted(self): + return self.encryptedFilepath is not None + + def getFilepath(self): + return self.encryptedFilepath or self.filepath + + def getOriginalFilepath(self): + return self.filepath + + def set(self, key, val): + self.attributes[key] = val + + def get(self, key, default = None): + if key in self.attributes: + return self.attributes[key] + + return default + + def getOrSet(self, key, func): + if not self.get(key): + self.set(key, func()) + + def build(self, url = None, ip = None): + if url: + self.set("url", url) + if ip: + self.set("ip", ip) + return self.cls.fromBuilder(self) diff --git a/yowsup/layers/protocol_media/protocolentities/message_media_downloadable.py b/yowsup/layers/protocol_media/protocolentities/message_media_downloadable.py index 0aaf4c64c..7286fdab9 100644 --- a/yowsup/layers/protocol_media/protocolentities/message_media_downloadable.py +++ b/yowsup/layers/protocol_media/protocolentities/message_media_downloadable.py @@ -4,27 +4,27 @@ import os class DownloadableMediaMessageProtocolEntity(MediaMessageProtocolEntity): ''' - {{THUMBNAIL_RAWDATA (JPEG?)}} ''' def __init__(self, mediaType, - mimeType, fileHash, url, ip, size, fileName, - _id = None, _from = None, to = None, notify = None, timestamp = None, + mimeType, fileHash, url, ip, size, fileName, mediaKey = None, + _id = None, _from = None, to = None, notify = None, timestamp = None, participant = None, preview = None, offline = None, retry = None): super(DownloadableMediaMessageProtocolEntity, self).__init__(mediaType, _id, _from, to, notify, timestamp, participant, preview, offline, retry) - self.setDownloadableMediaProps(mimeType, fileHash, url, ip, size, fileName) + self.setDownloadableMediaProps(mimeType, fileHash, url, ip, size, fileName, mediaKey) def __str__(self): out = super(DownloadableMediaMessageProtocolEntity, self).__str__() @@ -45,13 +45,14 @@ def getMediaUrl(self): def getMimeType(self): return self.mimeType - def setDownloadableMediaProps(self, mimeType, fileHash, url, ip, size, fileName): + def setDownloadableMediaProps(self, mimeType, fileHash, url, ip, size, fileName, mediaKey): self.mimeType = mimeType self.fileHash = fileHash self.url = url self.ip = ip self.size = int(size) self.fileName = fileName + self.mediaKey = mediaKey def toProtocolTreeNode(self): node = super(DownloadableMediaMessageProtocolEntity, self).toProtocolTreeNode() @@ -63,9 +64,14 @@ def toProtocolTreeNode(self): mediaNode.setAttribute("ip", self.ip) mediaNode.setAttribute("size", str(self.size)) mediaNode.setAttribute("file", self.fileName) + if self.mediaKey: + mediaNode.setAttribute("mediakey", self.mediaKey) return node + def isEncrypted(self): + return self.mediaKey is not None + @staticmethod def fromProtocolTreeNode(node): entity = MediaMessageProtocolEntity.fromProtocolTreeNode(node) @@ -77,17 +83,18 @@ def fromProtocolTreeNode(node): mediaNode.getAttributeValue("url"), mediaNode.getAttributeValue("ip"), mediaNode.getAttributeValue("size"), - mediaNode.getAttributeValue("file") + mediaNode.getAttributeValue("file"), + mediaNode.getAttributeValue("mediakey") ) return entity @staticmethod - def fromFilePath(fpath, url, mediaType, ip, to, mimeType = None, preview = None, filehash = None, filesize = None): - mimeType = mimeType or MimeTools.getMIME(fpath) - filehash = filehash or WATools.getFileHashForUpload(fpath) - size = filesize or os.path.getsize(fpath) - fileName = os.path.basename(fpath) - - return DownloadableMediaMessageProtocolEntity(mediaType, mimeType, filehash, url, ip, size, fileName, to = to, preview = preview) - - + def fromBuilder(builder): + url = builder.get("url") + ip = builder.get("ip") + assert url, "Url is required" + mimeType = builder.get("mimetype", MimeTools.getMIME(builder.getOriginalFilepath())[0]) + filehash = WATools.getFileHashForUpload(builder.getFilepath()) + size = os.path.getsize(builder.getFilepath()) + fileName = os.path.basename(builder.getFilepath()) + return DownloadableMediaMessageProtocolEntity(builder.mediaType, mimeType, filehash, url, ip, size, fileName, to = builder.jid, preview = builder.get("preview")) diff --git a/yowsup/layers/protocol_media/protocolentities/message_media_downloadable_audio.py b/yowsup/layers/protocol_media/protocolentities/message_media_downloadable_audio.py index f01aaf527..936681988 100644 --- a/yowsup/layers/protocol_media/protocolentities/message_media_downloadable_audio.py +++ b/yowsup/layers/protocol_media/protocolentities/message_media_downloadable_audio.py @@ -2,33 +2,33 @@ from .message_media_downloadable import DownloadableMediaMessageProtocolEntity class AudioDownloadableMediaMessageProtocolEntity(DownloadableMediaMessageProtocolEntity): ''' - {{THUMBNAIL_RAWDATA (JPEG?)}} ''' def __init__(self, - mimeType, fileHash, url, ip, size, fileName, + mimeType, fileHash, url, ip, size, fileName, abitrate, acodec, asampfreq, duration, encoding, origin, seconds, - _id = None, _from = None, to = None, notify = None, timestamp = None, + _id = None, _from = None, to = None, notify = None, timestamp = None, participant = None, preview = None, offline = None, retry = None): super(AudioDownloadableMediaMessageProtocolEntity, self).__init__("audio", - mimeType, fileHash, url, ip, size, fileName, + mimeType, fileHash, url, ip, size, fileName, None, _id, _from, to, notify, timestamp, participant, preview, offline, retry) self.setAudioProps(abitrate, acodec, asampfreq, duration, encoding, origin, seconds) diff --git a/yowsup/layers/protocol_media/protocolentities/message_media_downloadable_image.py b/yowsup/layers/protocol_media/protocolentities/message_media_downloadable_image.py index 5c29526aa..2f1365569 100644 --- a/yowsup/layers/protocol_media/protocolentities/message_media_downloadable_image.py +++ b/yowsup/layers/protocol_media/protocolentities/message_media_downloadable_image.py @@ -1,35 +1,38 @@ from yowsup.structs import ProtocolEntity, ProtocolTreeNode from .message_media_downloadable import DownloadableMediaMessageProtocolEntity +from .builder_message_media_downloadable import DownloadableMediaMessageBuilder +from yowsup.layers.protocol_messages.proto.wa_pb2 import ImageMessage from yowsup.common.tools import ImageTools + class ImageDownloadableMediaMessageProtocolEntity(DownloadableMediaMessageProtocolEntity): ''' - {{THUMBNAIL_RAWDATA (JPEG?)}} ''' def __init__(self, mimeType, fileHash, url, ip, size, fileName, - encoding, width, height, caption = None, - _id = None, _from = None, to = None, notify = None, timestamp = None, + encoding, width, height, caption = None, mediaKey = None, + _id = None, _from = None, to = None, notify = None, timestamp = None, participant = None, preview = None, offline = None, retry = None): super(ImageDownloadableMediaMessageProtocolEntity, self).__init__("image", - mimeType, fileHash, url, ip, size, fileName, + mimeType, fileHash, url, ip, size, fileName, mediaKey, _id, _from, to, notify, timestamp, participant, preview, offline, retry) self.setImageProps(encoding, width, height, caption) @@ -50,7 +53,7 @@ def setImageProps(self, encoding, width, height, caption): def getCaption(self): return self.caption - + def toProtocolTreeNode(self): node = super(ImageDownloadableMediaMessageProtocolEntity, self).toProtocolTreeNode() mediaNode = node.getChild("media") @@ -63,6 +66,20 @@ def toProtocolTreeNode(self): return node + def toProtobufMessage(self): + image_message = ImageMessage() + image_message.url = self.url + image_message.width = self.width + image_message.height = self.height + image_message.mime_type = self.mimeType + image_message.file_sha256 = self.fileHash + image_message.file_length = self.size + image_message.caption = self.caption + image_message.jpeg_thumbnail = self.preview + image_message.media_key = self.mediaKey + + return image_message + @staticmethod def fromProtocolTreeNode(node): entity = DownloadableMediaMessageProtocolEntity.fromProtocolTreeNode(node) @@ -78,17 +95,29 @@ def fromProtocolTreeNode(node): @staticmethod - def fromFilePath(path, url, ip, to, mimeType = None, caption = None, dimensions = None): - preview = ImageTools.generatePreviewFromImage(path) - entity = DownloadableMediaMessageProtocolEntity.fromFilePath(path, url, DownloadableMediaMessageProtocolEntity.MEDIA_TYPE_IMAGE, ip, to, mimeType, preview) - entity.__class__ = ImageDownloadableMediaMessageProtocolEntity - - if not dimensions: - dimensions = ImageTools.getImageDimensions(path) + def getBuilder(jid, filepath): + return DownloadableMediaMessageBuilder(ImageDownloadableMediaMessageProtocolEntity, jid, filepath) + @staticmethod + def fromBuilder(builder): + builder.getOrSet("preview", lambda: ImageTools.generatePreviewFromImage(builder.getOriginalFilepath())) + filepath = builder.getFilepath() + caption = builder.get("caption") + dimensions = builder.get("dimensions", ImageTools.getImageDimensions(builder.getOriginalFilepath())) assert dimensions, "Could not determine image dimensions" - width, height = dimensions + + entity = DownloadableMediaMessageProtocolEntity.fromBuilder(builder) + entity.__class__ = builder.cls entity.setImageProps("raw", width, height, caption) return entity + @staticmethod + def fromFilePath(path, url, ip, to, mimeType = None, caption = None, dimensions = None): + builder = ImageDownloadableMediaMessageProtocolEntity.getBuilder(to, path) + builder.set("url", url) + builder.set("ip", ip) + builder.set("caption", caption) + builder.set("mimetype", mimeType) + builder.set("dimensions", dimesions) + return ImageDownloadableMediaMessageProtocolEntity.fromBuilder(builder) diff --git a/yowsup/layers/protocol_media/protocolentities/message_media_downloadable_video.py b/yowsup/layers/protocol_media/protocolentities/message_media_downloadable_video.py index c6850739c..c6acb3bfc 100644 --- a/yowsup/layers/protocol_media/protocolentities/message_media_downloadable_video.py +++ b/yowsup/layers/protocol_media/protocolentities/message_media_downloadable_video.py @@ -32,7 +32,7 @@ def __init__(self, participant = None, preview = None, offline = None, retry = None): super(VideoDownloadableMediaMessageProtocolEntity, self).__init__("video", - mimeType, fileHash, url, ip, size, fileName, + mimeType, fileHash, url, ip, size, fileName, None, _id, _from, to, notify, timestamp, participant, preview, offline, retry) self.setVideoProps(encoding, width, height, vbitrate, abitrate, acodec, asampfmt, asampfreq, duration, fps, seconds, vcodec, caption) @@ -75,6 +75,11 @@ def toProtocolTreeNode(self): node = super(VideoDownloadableMediaMessageProtocolEntity, self).toProtocolTreeNode() mediaNode = node.getChild("media") + mediaNode.setAttribute("abitrate", self.abitrate) + mediaNode.setAttribute("acodec", self.acodec) + mediaNode.setAttribute("asampfmt", self.asampfmt) + mediaNode.setAttribute("asampfreq", self.asampfreq) + mediaNode.setAttribute("duration", self.duration) mediaNode.setAttribute("encoding", self.encoding) mediaNode.setAttribute("height", str(self.height)) mediaNode.setAttribute("width", str(self.width)) diff --git a/yowsup/layers/protocol_messages/proto/__init__.py b/yowsup/layers/protocol_messages/proto/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/yowsup/layers/axolotl/proto/e2e.proto b/yowsup/layers/protocol_messages/proto/wa.proto similarity index 100% rename from yowsup/layers/axolotl/proto/e2e.proto rename to yowsup/layers/protocol_messages/proto/wa.proto diff --git a/yowsup/layers/axolotl/e2e_pb2.py b/yowsup/layers/protocol_messages/proto/wa_pb2.py similarity index 88% rename from yowsup/layers/axolotl/e2e_pb2.py rename to yowsup/layers/protocol_messages/proto/wa_pb2.py index dbef983ba..528c1f77e 100644 --- a/yowsup/layers/axolotl/e2e_pb2.py +++ b/yowsup/layers/protocol_messages/proto/wa_pb2.py @@ -1,5 +1,5 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! -# source: e2e.proto +# source: wa.proto import sys _b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) @@ -16,9 +16,9 @@ DESCRIPTOR = _descriptor.FileDescriptor( - name='e2e.proto', + name='wa.proto', package='com.whatsapp.proto', - serialized_pb=_b('\n\te2e.proto\x12\x12\x63om.whatsapp.proto\"\xa3\x03\n\x07Message\x12\x14\n\x0c\x63onversation\x18\x01 \x01(\t\x12Y\n\x1fsender_key_distribution_message\x18\x02 \x01(\x0b\x32\x30.com.whatsapp.proto.SenderKeyDistributionMessage\x12\x37\n\rimage_message\x18\x03 \x01(\x0b\x32 .com.whatsapp.proto.ImageMessage\x12;\n\x0f\x63ontact_message\x18\x04 \x01(\x0b\x32\".com.whatsapp.proto.ContactMessage\x12=\n\x10location_message\x18\x05 \x01(\x0b\x32#.com.whatsapp.proto.LocationMessage\x12=\n\x10\x64ocument_message\x18\x07 \x01(\x0b\x32#.com.whatsapp.proto.DocumentMessage\x12\x33\n\x0burl_message\x18\x06 \x01(\x0b\x32\x1e.com.whatsapp.proto.UrlMessage\"`\n\x1cSenderKeyDistributionMessage\x12\x0f\n\x07groupId\x18\x01 \x02(\t\x12/\n\'axolotl_sender_key_distribution_message\x18\x02 \x02(\x0c\"\xb3\x01\n\x0cImageMessage\x12\x0b\n\x03url\x18\x01 \x02(\x0c\x12\x11\n\tmime_type\x18\x02 \x02(\t\x12\x0f\n\x07\x63\x61ption\x18\x03 \x02(\t\x12\x13\n\x0b\x66ile_sha256\x18\x04 \x02(\x0c\x12\x13\n\x0b\x66ile_length\x18\x05 \x02(\x04\x12\x0e\n\x06height\x18\x06 \x02(\r\x12\r\n\x05width\x18\x07 \x02(\r\x12\x11\n\tmedia_key\x18\x08 \x02(\x0c\x12\x16\n\x0ejpeg_thumbnail\x18\x10 \x02(\x0c\"\x8a\x01\n\x0fLocationMessage\x12\x18\n\x10\x64\x65grees_latitude\x18\x01 \x02(\x01\x12\x19\n\x11\x64\x65grees_longitude\x18\x02 \x02(\x01\x12\x0c\n\x04name\x18\x03 \x02(\t\x12\x0f\n\x07\x61\x64\x64ress\x18\x04 \x02(\t\x12\x0b\n\x03url\x18\x05 \x02(\t\x12\x16\n\x0ejpeg_thumbnail\x18\x10 \x02(\x0c\"\xa8\x01\n\x0f\x44ocumentMessage\x12\x0b\n\x03url\x18\x01 \x02(\t\x12\x10\n\x08mimeType\x18\x02 \x02(\t\x12\r\n\x05title\x18\x03 \x02(\t\x12\x13\n\x0b\x66ile_sha256\x18\x04 \x02(\x0c\x12\x13\n\x0b\x66ile_length\x18\x05 \x02(\x04\x12\x12\n\npage_count\x18\x06 \x02(\r\x12\x11\n\tmedia_key\x18\x07 \x02(\x0c\x12\x16\n\x0ejpeg_thumbnail\x18\x10 \x02(\x0c\"\x83\x01\n\nUrlMessage\x12\x0c\n\x04text\x18\x01 \x02(\t\x12\x14\n\x0cmatched_text\x18\x02 \x02(\t\x12\x15\n\rcanonical_url\x18\x04 \x02(\t\x12\x13\n\x0b\x64\x65scription\x18\x05 \x02(\t\x12\r\n\x05title\x18\x06 \x02(\t\x12\x16\n\x0ejpeg_thumbnail\x18\x10 \x02(\t\"5\n\x0e\x43ontactMessage\x12\x14\n\x0c\x64isplay_name\x18\x01 \x02(\t\x12\r\n\x05vcard\x18\x10 \x02(\t') + serialized_pb=_b('\n\x08wa.proto\x12\x12\x63om.whatsapp.proto\"\xa3\x03\n\x07Message\x12\x14\n\x0c\x63onversation\x18\x01 \x01(\t\x12Y\n\x1fsender_key_distribution_message\x18\x02 \x01(\x0b\x32\x30.com.whatsapp.proto.SenderKeyDistributionMessage\x12\x37\n\rimage_message\x18\x03 \x01(\x0b\x32 .com.whatsapp.proto.ImageMessage\x12;\n\x0f\x63ontact_message\x18\x04 \x01(\x0b\x32\".com.whatsapp.proto.ContactMessage\x12=\n\x10location_message\x18\x05 \x01(\x0b\x32#.com.whatsapp.proto.LocationMessage\x12=\n\x10\x64ocument_message\x18\x07 \x01(\x0b\x32#.com.whatsapp.proto.DocumentMessage\x12\x33\n\x0burl_message\x18\x06 \x01(\x0b\x32\x1e.com.whatsapp.proto.UrlMessage\"`\n\x1cSenderKeyDistributionMessage\x12\x0f\n\x07groupId\x18\x01 \x02(\t\x12/\n\'axolotl_sender_key_distribution_message\x18\x02 \x02(\x0c\"\xb3\x01\n\x0cImageMessage\x12\x0b\n\x03url\x18\x01 \x02(\x0c\x12\x11\n\tmime_type\x18\x02 \x02(\t\x12\x0f\n\x07\x63\x61ption\x18\x03 \x02(\t\x12\x13\n\x0b\x66ile_sha256\x18\x04 \x02(\x0c\x12\x13\n\x0b\x66ile_length\x18\x05 \x02(\x04\x12\x0e\n\x06height\x18\x06 \x02(\r\x12\r\n\x05width\x18\x07 \x02(\r\x12\x11\n\tmedia_key\x18\x08 \x02(\x0c\x12\x16\n\x0ejpeg_thumbnail\x18\x10 \x02(\x0c\"\x8a\x01\n\x0fLocationMessage\x12\x18\n\x10\x64\x65grees_latitude\x18\x01 \x02(\x01\x12\x19\n\x11\x64\x65grees_longitude\x18\x02 \x02(\x01\x12\x0c\n\x04name\x18\x03 \x02(\t\x12\x0f\n\x07\x61\x64\x64ress\x18\x04 \x02(\t\x12\x0b\n\x03url\x18\x05 \x02(\t\x12\x16\n\x0ejpeg_thumbnail\x18\x10 \x02(\x0c\"\xa8\x01\n\x0f\x44ocumentMessage\x12\x0b\n\x03url\x18\x01 \x02(\t\x12\x10\n\x08mimeType\x18\x02 \x02(\t\x12\r\n\x05title\x18\x03 \x02(\t\x12\x13\n\x0b\x66ile_sha256\x18\x04 \x02(\x0c\x12\x13\n\x0b\x66ile_length\x18\x05 \x02(\x04\x12\x12\n\npage_count\x18\x06 \x02(\r\x12\x11\n\tmedia_key\x18\x07 \x02(\x0c\x12\x16\n\x0ejpeg_thumbnail\x18\x10 \x02(\x0c\"\x83\x01\n\nUrlMessage\x12\x0c\n\x04text\x18\x01 \x02(\t\x12\x14\n\x0cmatched_text\x18\x02 \x02(\t\x12\x15\n\rcanonical_url\x18\x04 \x02(\t\x12\x13\n\x0b\x64\x65scription\x18\x05 \x02(\t\x12\r\n\x05title\x18\x06 \x02(\t\x12\x16\n\x0ejpeg_thumbnail\x18\x10 \x02(\t\"5\n\x0e\x43ontactMessage\x12\x14\n\x0c\x64isplay_name\x18\x01 \x02(\t\x12\r\n\x05vcard\x18\x10 \x02(\t') ) _sym_db.RegisterFileDescriptor(DESCRIPTOR) @@ -92,8 +92,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=34, - serialized_end=453, + serialized_start=33, + serialized_end=452, ) @@ -129,8 +129,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=455, - serialized_end=551, + serialized_start=454, + serialized_end=550, ) @@ -215,8 +215,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=554, - serialized_end=733, + serialized_start=553, + serialized_end=732, ) @@ -280,8 +280,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=736, - serialized_end=874, + serialized_start=735, + serialized_end=873, ) @@ -359,8 +359,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=877, - serialized_end=1045, + serialized_start=876, + serialized_end=1044, ) @@ -424,8 +424,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1048, - serialized_end=1179, + serialized_start=1047, + serialized_end=1178, ) @@ -461,8 +461,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1181, - serialized_end=1234, + serialized_start=1180, + serialized_end=1233, ) _MESSAGE.fields_by_name['sender_key_distribution_message'].message_type = _SENDERKEYDISTRIBUTIONMESSAGE @@ -481,49 +481,49 @@ Message = _reflection.GeneratedProtocolMessageType('Message', (_message.Message,), dict( DESCRIPTOR = _MESSAGE, - __module__ = 'e2e_pb2' + __module__ = 'wa_pb2' # @@protoc_insertion_point(class_scope:com.whatsapp.proto.Message) )) _sym_db.RegisterMessage(Message) SenderKeyDistributionMessage = _reflection.GeneratedProtocolMessageType('SenderKeyDistributionMessage', (_message.Message,), dict( DESCRIPTOR = _SENDERKEYDISTRIBUTIONMESSAGE, - __module__ = 'e2e_pb2' + __module__ = 'wa_pb2' # @@protoc_insertion_point(class_scope:com.whatsapp.proto.SenderKeyDistributionMessage) )) _sym_db.RegisterMessage(SenderKeyDistributionMessage) ImageMessage = _reflection.GeneratedProtocolMessageType('ImageMessage', (_message.Message,), dict( DESCRIPTOR = _IMAGEMESSAGE, - __module__ = 'e2e_pb2' + __module__ = 'wa_pb2' # @@protoc_insertion_point(class_scope:com.whatsapp.proto.ImageMessage) )) _sym_db.RegisterMessage(ImageMessage) LocationMessage = _reflection.GeneratedProtocolMessageType('LocationMessage', (_message.Message,), dict( DESCRIPTOR = _LOCATIONMESSAGE, - __module__ = 'e2e_pb2' + __module__ = 'wa_pb2' # @@protoc_insertion_point(class_scope:com.whatsapp.proto.LocationMessage) )) _sym_db.RegisterMessage(LocationMessage) DocumentMessage = _reflection.GeneratedProtocolMessageType('DocumentMessage', (_message.Message,), dict( DESCRIPTOR = _DOCUMENTMESSAGE, - __module__ = 'e2e_pb2' + __module__ = 'wa_pb2' # @@protoc_insertion_point(class_scope:com.whatsapp.proto.DocumentMessage) )) _sym_db.RegisterMessage(DocumentMessage) UrlMessage = _reflection.GeneratedProtocolMessageType('UrlMessage', (_message.Message,), dict( DESCRIPTOR = _URLMESSAGE, - __module__ = 'e2e_pb2' + __module__ = 'wa_pb2' # @@protoc_insertion_point(class_scope:com.whatsapp.proto.UrlMessage) )) _sym_db.RegisterMessage(UrlMessage) ContactMessage = _reflection.GeneratedProtocolMessageType('ContactMessage', (_message.Message,), dict( DESCRIPTOR = _CONTACTMESSAGE, - __module__ = 'e2e_pb2' + __module__ = 'wa_pb2' # @@protoc_insertion_point(class_scope:com.whatsapp.proto.ContactMessage) )) _sym_db.RegisterMessage(ContactMessage)