diff --git a/yowsup/common/tools.py b/yowsup/common/tools.py index e2a2f6301..7a3e258a4 100644 --- a/yowsup/common/tools.py +++ b/yowsup/common/tools.py @@ -212,38 +212,38 @@ def getExtension(mimetype): class VideoTools: - - @staticmethod - def getVideoProperties(videoFile): - if ModuleTools.INSTALLED_FFVIDEO(): - from ffvideo import VideoStream - s = VideoStream(videoFile) - return s.width, s.height, s.bitrate, s.duration #, s.codec_name - elif ModuleTools.INSTALLED_EXIFTOOL(): - try: - result = json.loads(check_output(["exiftool", "-j", "-n", videoFile]))[0] - except CalledProcessError: - logger.warn("exiftool returned non-zero status for video %s", videoFile) - except (IndexError, ValueError): - logger.warn("Failed reading exiftool result for video %s", videoFile) - else: - try: - return result["ImageWidth"], result["ImageHeight"], \ - result["AvgBitrate"], result["Duration"] - except KeyError: - logger.warn("Failed reading video properties from exiftool JSON") - else: - logger.warn("None of [Python ffvideo library, exiftool] installed") - - @staticmethod - def generatePreviewFromVideo(videoFile): - if ModuleTools.INSTALLED_FFVIDEO(): - from ffvideo import VideoStream - fd, path = tempfile.mkstemp('.jpg') - stream = VideoStream(videoFile) - stream.get_frame_at_sec(0).image().save(path) - preview = ImageTools.generatePreviewFromImage(path) - os.remove(path) - return preview - else: - logger.warn("Python ffvideo library not installed") + + @staticmethod + def getVideoProperties(videoFile): + if ModuleTools.INSTALLED_FFVIDEO(): + from ffvideo import VideoStream + s = VideoStream(videoFile) + return s.width, s.height, s.bitrate, s.duration #, s.codec_name + elif ModuleTools.INSTALLED_EXIFTOOL(): + try: + result = json.loads(check_output(["exiftool", "-j", "-n", videoFile]))[0] + except CalledProcessError: + logger.warn("exiftool returned non-zero status for video %s", videoFile) + except (IndexError, ValueError): + logger.warn("Failed reading exiftool result for video %s", videoFile) + else: + try: + return result["ImageWidth"], result["ImageHeight"], \ + result["AvgBitrate"], result["Duration"] + except KeyError: + logger.warn("Failed reading video properties from exiftool JSON") + else: + logger.warn("None of [Python ffvideo library, exiftool] installed") + + @staticmethod + def generatePreviewFromVideo(videoFile): + if ModuleTools.INSTALLED_FFVIDEO(): + from ffvideo import VideoStream + fd, path = tempfile.mkstemp('.jpg') + stream = VideoStream(videoFile) + stream.get_frame_at_sec(0).image().save(path) + preview = ImageTools.generatePreviewFromImage(path) + os.remove(path) + return preview + else: + logger.warn("Python ffvideo library not installed") diff --git a/yowsup/layers/axolotl/layer.py b/yowsup/layers/axolotl/layer.py index a5721ea75..50b0653d9 100644 --- a/yowsup/layers/axolotl/layer.py +++ b/yowsup/layers/axolotl/layer.py @@ -298,7 +298,10 @@ def handlePreKeyWhisperMessage(self, node): sessionCipher = self.getSessionCipher(pkMessageProtocolEntity.getAuthor(False)) plaintext = sessionCipher.decryptPkmsg(preKeyWhisperMessage) if enc.getVersion() == 2: - padding = ord(plaintext[-1]) & 0xFF + if isinstance(plaintext[-1], str): + padding = ord(plaintext[-1]) & 0xFF + else: + padding = plaintext[-1] & 0xFF self.parseAndHandleMessageProto(pkMessageProtocolEntity, plaintext[:-padding]) else: self.handleConversationMessage(node, plaintext) @@ -312,7 +315,10 @@ def handleWhisperMessage(self, node): plaintext = sessionCipher.decryptMsg(whisperMessage) if enc.getVersion() == 2: - padding = ord(plaintext[-1]) & 0xFF + if isinstance(plaintext[-1], str): + padding = ord(plaintext[-1]) & 0xFF + else: + padding = plaintext[-1] & 0xFF self.parseAndHandleMessageProto(encMessageProtocolEntity, plaintext[:-padding]) else: self.handleConversationMessage(encMessageProtocolEntity.toProtocolTreeNode(), plaintext) @@ -325,7 +331,10 @@ def handleSenderKeyMessage(self, node): groupCipher = GroupCipher(self.store, senderKeyName) try: plaintext = groupCipher.decrypt(enc.getData()) - padding = ord(plaintext[-1]) & 0xFF + if isinstance(plaintext[-1], str): + padding = ord(plaintext[-1]) & 0xFF + else: + padding = plaintext[-1] & 0xFF self.parseAndHandleMessageProto(encMessageProtocolEntity, plaintext[:-padding]) except NoSessionException as e: logger.error(e) @@ -343,7 +352,7 @@ def parseAndHandleMessageProto(self, encMessageProtocolEntity, serializedData): # f.write(serializedData) print(serializedData) print([s for s in serializedData]) - print([ord(s) for s in serializedData]) + #print([ord(s) for s in serializedData]) raise if not m or not serializedData: raise ValueError("Empty message") diff --git a/yowsup/layers/protocol_messages/proto/wa_pb2.py b/yowsup/layers/protocol_messages/proto/wa_pb2.py index 6fee329d7..5ef8b1529 100644 --- a/yowsup/layers/protocol_messages/proto/wa_pb2.py +++ b/yowsup/layers/protocol_messages/proto/wa_pb2.py @@ -1,22 +1,26 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: wa.proto -import sys +import sys _b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) - from google.protobuf import descriptor as _descriptor from google.protobuf import message as _message from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database from google.protobuf import descriptor_pb2 # @@protoc_insertion_point(imports) +_sym_db = _symbol_database.Default() + DESCRIPTOR = _descriptor.FileDescriptor( name='wa.proto', package='com.whatsapp.proto', - serialized_pb=_b('\n\x08wa.proto\x12\x12\x63om.whatsapp.proto\"\x95\x04\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\x12\x37\n\raudio_message\x18\x08 \x01(\x0b\x32 .com.whatsapp.proto.AudioMessage\x12\x37\n\rvideo_message\x18\t \x01(\x0b\x32 .com.whatsapp.proto.VideoMessage\"`\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\"\xa6\x01\n\x0cVideoMessage\x12\x0b\n\x03url\x18\x01 \x02(\x0c\x12\x11\n\tmime_type\x18\x02 \x02(\t\x12\x13\n\x0b\x66ile_sha256\x18\x03 \x02(\x0c\x12\x13\n\x0b\x66ile_length\x18\x04 \x02(\x04\x12\x10\n\x08\x64uration\x18\x05 \x02(\x04\x12\x11\n\tmedia_key\x18\x06 \x02(\x0c\x12\x0f\n\x07\x63\x61ption\x18\x07 \x02(\t\x12\x16\n\x0ejpeg_thumbnail\x18\x10 \x02(\x0c\"\x8a\x01\n\x0c\x41udioMessage\x12\x0b\n\x03url\x18\x01 \x02(\x0c\x12\x11\n\tmime_type\x18\x02 \x02(\t\x12\x13\n\x0b\x66ile_sha256\x18\x03 \x02(\x0c\x12\x13\n\x0b\x66ile_length\x18\x04 \x02(\x04\x12\x10\n\x08\x64uration\x18\x05 \x02(\x04\x12\x0b\n\x03unk\x18\x06 \x02(\r\x12\x11\n\tmedia_key\x18\x07 \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\"\xa9\x01\n\x0f\x44ocumentMessage\x12\x0b\n\x03url\x18\x01 \x02(\t\x12\x11\n\tmime_type\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(\x0c\"5\n\x0e\x43ontactMessage\x12\x14\n\x0c\x64isplay_name\x18\x01 \x02(\t\x12\r\n\x05vcard\x18\x10 \x02(\x0c')) + serialized_pb=_b('\n\x08wa.proto\x12\x12\x63om.whatsapp.proto\"\x95\x04\n\x07Message\x12\x14\n\x0c\x63onversation\x18\x01 \x01(\x0c\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\x12\x37\n\raudio_message\x18\x08 \x01(\x0b\x32 .com.whatsapp.proto.AudioMessage\x12\x37\n\rvideo_message\x18\t \x01(\x0b\x32 .com.whatsapp.proto.VideoMessage\"`\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\"\xa6\x01\n\x0cVideoMessage\x12\x0b\n\x03url\x18\x01 \x02(\x0c\x12\x11\n\tmime_type\x18\x02 \x02(\t\x12\x13\n\x0b\x66ile_sha256\x18\x03 \x02(\x0c\x12\x13\n\x0b\x66ile_length\x18\x04 \x02(\x04\x12\x10\n\x08\x64uration\x18\x05 \x02(\x04\x12\x11\n\tmedia_key\x18\x06 \x02(\x0c\x12\x0f\n\x07\x63\x61ption\x18\x07 \x02(\t\x12\x16\n\x0ejpeg_thumbnail\x18\x10 \x02(\x0c\"\x8a\x01\n\x0c\x41udioMessage\x12\x0b\n\x03url\x18\x01 \x02(\x0c\x12\x11\n\tmime_type\x18\x02 \x02(\t\x12\x13\n\x0b\x66ile_sha256\x18\x03 \x02(\x0c\x12\x13\n\x0b\x66ile_length\x18\x04 \x02(\x04\x12\x10\n\x08\x64uration\x18\x05 \x02(\x04\x12\x0b\n\x03unk\x18\x06 \x02(\r\x12\x11\n\tmedia_key\x18\x07 \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\"\xa9\x01\n\x0f\x44ocumentMessage\x12\x0b\n\x03url\x18\x01 \x02(\t\x12\x11\n\tmime_type\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(\x0c\"5\n\x0e\x43ontactMessage\x12\x14\n\x0c\x64isplay_name\x18\x01 \x02(\t\x12\r\n\x05vcard\x18\x10 \x02(\x0c') +) +_sym_db.RegisterFileDescriptor(DESCRIPTOR) @@ -31,7 +35,7 @@ _descriptor.FieldDescriptor( name='conversation', full_name='com.whatsapp.proto.Message.conversation', index=0, number=1, type=12, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), + has_default_value=False, default_value=_b(""), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), @@ -100,6 +104,8 @@ options=None, is_extendable=False, extension_ranges=[], + oneofs=[ + ], serialized_start=33, serialized_end=566, ) @@ -135,6 +141,8 @@ options=None, is_extendable=False, extension_ranges=[], + oneofs=[ + ], serialized_start=568, serialized_end=664, ) @@ -219,6 +227,8 @@ options=None, is_extendable=False, extension_ranges=[], + oneofs=[ + ], serialized_start=667, serialized_end=846, ) @@ -296,6 +306,8 @@ options=None, is_extendable=False, extension_ranges=[], + oneofs=[ + ], serialized_start=849, serialized_end=1015, ) @@ -366,6 +378,8 @@ options=None, is_extendable=False, extension_ranges=[], + oneofs=[ + ], serialized_start=1018, serialized_end=1156, ) @@ -429,6 +443,8 @@ options=None, is_extendable=False, extension_ranges=[], + oneofs=[ + ], serialized_start=1159, serialized_end=1297, ) @@ -506,6 +522,8 @@ options=None, is_extendable=False, extension_ranges=[], + oneofs=[ + ], serialized_start=1300, serialized_end=1469, ) @@ -569,6 +587,8 @@ options=None, is_extendable=False, extension_ranges=[], + oneofs=[ + ], serialized_start=1472, serialized_end=1603, ) @@ -604,6 +624,8 @@ options=None, is_extendable=False, extension_ranges=[], + oneofs=[ + ], serialized_start=1605, serialized_end=1658, ) @@ -626,59 +648,68 @@ DESCRIPTOR.message_types_by_name['UrlMessage'] = _URLMESSAGE DESCRIPTOR.message_types_by_name['ContactMessage'] = _CONTACTMESSAGE -class Message(_message.Message): - __metaclass__ = _reflection.GeneratedProtocolMessageType - DESCRIPTOR = _MESSAGE - +Message = _reflection.GeneratedProtocolMessageType('Message', (_message.Message,), dict( + DESCRIPTOR = _MESSAGE, + __module__ = 'wa_pb2' # @@protoc_insertion_point(class_scope:com.whatsapp.proto.Message) + )) +_sym_db.RegisterMessage(Message) -class SenderKeyDistributionMessage(_message.Message): - __metaclass__ = _reflection.GeneratedProtocolMessageType - DESCRIPTOR = _SENDERKEYDISTRIBUTIONMESSAGE - +SenderKeyDistributionMessage = _reflection.GeneratedProtocolMessageType('SenderKeyDistributionMessage', (_message.Message,), dict( + DESCRIPTOR = _SENDERKEYDISTRIBUTIONMESSAGE, + __module__ = 'wa_pb2' # @@protoc_insertion_point(class_scope:com.whatsapp.proto.SenderKeyDistributionMessage) + )) +_sym_db.RegisterMessage(SenderKeyDistributionMessage) -class ImageMessage(_message.Message): - __metaclass__ = _reflection.GeneratedProtocolMessageType - DESCRIPTOR = _IMAGEMESSAGE - +ImageMessage = _reflection.GeneratedProtocolMessageType('ImageMessage', (_message.Message,), dict( + DESCRIPTOR = _IMAGEMESSAGE, + __module__ = 'wa_pb2' # @@protoc_insertion_point(class_scope:com.whatsapp.proto.ImageMessage) + )) +_sym_db.RegisterMessage(ImageMessage) -class VideoMessage(_message.Message): - __metaclass__ = _reflection.GeneratedProtocolMessageType - DESCRIPTOR = _VIDEOMESSAGE - +VideoMessage = _reflection.GeneratedProtocolMessageType('VideoMessage', (_message.Message,), dict( + DESCRIPTOR = _VIDEOMESSAGE, + __module__ = 'wa_pb2' # @@protoc_insertion_point(class_scope:com.whatsapp.proto.VideoMessage) + )) +_sym_db.RegisterMessage(VideoMessage) -class AudioMessage(_message.Message): - __metaclass__ = _reflection.GeneratedProtocolMessageType - DESCRIPTOR = _AUDIOMESSAGE - +AudioMessage = _reflection.GeneratedProtocolMessageType('AudioMessage', (_message.Message,), dict( + DESCRIPTOR = _AUDIOMESSAGE, + __module__ = 'wa_pb2' # @@protoc_insertion_point(class_scope:com.whatsapp.proto.AudioMessage) + )) +_sym_db.RegisterMessage(AudioMessage) -class LocationMessage(_message.Message): - __metaclass__ = _reflection.GeneratedProtocolMessageType - DESCRIPTOR = _LOCATIONMESSAGE - +LocationMessage = _reflection.GeneratedProtocolMessageType('LocationMessage', (_message.Message,), dict( + DESCRIPTOR = _LOCATIONMESSAGE, + __module__ = 'wa_pb2' # @@protoc_insertion_point(class_scope:com.whatsapp.proto.LocationMessage) + )) +_sym_db.RegisterMessage(LocationMessage) -class DocumentMessage(_message.Message): - __metaclass__ = _reflection.GeneratedProtocolMessageType - DESCRIPTOR = _DOCUMENTMESSAGE - +DocumentMessage = _reflection.GeneratedProtocolMessageType('DocumentMessage', (_message.Message,), dict( + DESCRIPTOR = _DOCUMENTMESSAGE, + __module__ = 'wa_pb2' # @@protoc_insertion_point(class_scope:com.whatsapp.proto.DocumentMessage) + )) +_sym_db.RegisterMessage(DocumentMessage) -class UrlMessage(_message.Message): - __metaclass__ = _reflection.GeneratedProtocolMessageType - DESCRIPTOR = _URLMESSAGE - +UrlMessage = _reflection.GeneratedProtocolMessageType('UrlMessage', (_message.Message,), dict( + DESCRIPTOR = _URLMESSAGE, + __module__ = 'wa_pb2' # @@protoc_insertion_point(class_scope:com.whatsapp.proto.UrlMessage) + )) +_sym_db.RegisterMessage(UrlMessage) -class ContactMessage(_message.Message): - __metaclass__ = _reflection.GeneratedProtocolMessageType - DESCRIPTOR = _CONTACTMESSAGE - +ContactMessage = _reflection.GeneratedProtocolMessageType('ContactMessage', (_message.Message,), dict( + DESCRIPTOR = _CONTACTMESSAGE, + __module__ = 'wa_pb2' # @@protoc_insertion_point(class_scope:com.whatsapp.proto.ContactMessage) + )) +_sym_db.RegisterMessage(ContactMessage) # @@protoc_insertion_point(module_scope)