tgalal / yowsup

The WhatsApp lib
GNU General Public License v3.0
7.09k stars 2.23k forks source link

Yowsup 2.0 - Sending images from desktop #413

Closed vsarinho closed 9 years ago

vsarinho commented 10 years ago

Do you have an example??

According to cli example:

#@clicmd("Send and image")
def image_send(self, jid, path):
    pass
mediumwell commented 10 years ago

I also wonder how to send media. The legacy branch used to have a MediaDownloader and a MediaUploader, whereas in yowsup-2.0, I can only find a MediaDownloader but no uploader. How can I send an image?

tgalal commented 10 years ago

Still it's not implemented I'm working on it. I expect it to be ready in a day or 2

guyschlider commented 9 years ago

Any news? :) can we help some how? maybe taking the old code and adjust it?

tgalal commented 9 years ago

sorry I got too busy working on much higher priority stuff in yowsup, sending media still needs some work to integrate in yowsup v2, I promise I'll look into it asap, or feel free to try port it if anyone is interested if in a hurry It goes like this: We send this to WhatsApp to request upload

    <iq to="s.whatsapp.net" type="set" xmlns="w:m">
        <media hash="{{b64_hash}}" type="{{type}}" size="{{size_bytes}}" orighash={{b64_orighash?}}></media>
    </iq>

We get an iq result stanza containing media child with an attribute called Url. Then we use this Url to upload the file to using MediaUploader (which has to be moved to yowsup2 as well)

chirikchik commented 9 years ago

Hi! Could you clarify the status of image sending in v 2.0? I extended demo echo client with image echo and it works OK including thumbnail. It also works if I try to send image by myself (I tried only already uploaded images). But they arrive to device without thumbnail. Something is wrong with encoding of preview data. Could you please check?

def sendImageMessages (): 
    layer = stack.getLayer(5)
    imgUtils = ImageUtils("C:\dev\wsPython\ImageSender\IMG-20141219-WA0009.jpg")

    thumbData = imgUtils.createThumb()

    outImage = ImageDownloadableMediaMessageProtocolEntity(
    "image/jpeg", imgUtils.getHash(), 
    "https://mmi601.whatsapp.net/d/G3Q3JSArdaAt3ADulYzqllSTyvYABQqMI7oBmg/AgoHeH7ZefFXUzEGzE3UCOwKPcOk-Yssdxr03P8BkW1z.jpg", 
    "111.111.111.11",
    imgUtils.imageInfo.__getattribute__("st_size"), "AgoHeH7ZefFXUzEGzE3UCOwKPcOk-Yssdxr03P8BkW1z.jpg", 
    "raw", 
    825, 825,
    "Test image",
    to = "xxxxxxxxxxx@s.whatsapp.net", 
    preview = thumbData);

    layer.send(outImage);

def createThumb(self):
    THUMBNAIL_SIZE = 64, 64
    thumbnailFile = "thumb.jpg"

    im = Image.open(self.imagePath)
    im.thumbnail(THUMBNAIL_SIZE, Image.ANTIALIAS)
    im.save(thumbnailFile, "JPEG")

    with open(thumbnailFile, "rb") as imageFile:
        raw = base64.b64encode(imageFile.read())
    return raw
debianitram commented 9 years ago

Try this,

def createThumb(self, size=100, raw=False):
        img = Image.open(self.path_image)  
        width, height = img.size
        img_thumbnail = self.path_image + '_thumbnail'

        if width > height:
            nheight = float(height) / width * size
            nwidth = size
        else:
            nwidth = float(width) / height * size
            nheight = size

        img.thumbnail((nwidth, nheight), Image.ANTIALIAS)
        img.save(img_thumbnail, 'JPEG')

        with open(img_thumbnail, 'rb') as imageFile:
            raw = base64.b64encode(imageFile.read())

        return raw
nautical commented 9 years ago

Is there a proper example of sending image in the client ?

ivanbaldo commented 9 years ago

Warning, I am having problems uploading images with YowSup legacy, I wonder if I am doing something wrong or something changed in the protocol. I will reply back if I get more info.

ivanbaldo commented 9 years ago

The image upload works correctly in YowSup Legacy, the part that doesn't work is when sending the image to the recipients. I made it work outside YowSup with this: MediaNode = ProtocolTreeNode("media", {"mimetype":"image/jpeg", "filehash":Hash, "encoding":"raw", "url":URL, "height":str(ImgSize[1]), "width":str(ImgSize[0]), "file":Name, "type":"image", "size":str(os.path.getsize(FilePath)), "caption":Caption}, None, Thumbnail) MessageNode = ProtocolTreeNode("message", {"type":"media", "to":Mobile+"@s.whatsapp.net", "id":str(time.time()), "t":str(long(time.time()))}, [MediaNode]) YowMgr._writeNode(MessageNode) Should be fixed in YowSup Legacy and ported to V2. Hope this helps!!!

nautical commented 9 years ago

is it fixed in legacy branch ? Where is the fix ?

ivanbaldo commented 9 years ago

Sending images is not yet supported in V2. In the Legacy branch, you can upload the image correctly (except if you use Python 2.6 in which case you need to remove some bytearray() calls) but the sending is outdated and doesn't work. You can send the image with the example code I posted earlier. Maybe Tarek or someone else can adapt the code I posted to YowSup Legacy, I don't know if I will be able to do it myself since that part of the code is a bit confusing for me. And also the code I posted could be useful if someone wants to adapt it to YowSup V2. Remember, first you need to upload the image to WhatsApp servers, after that you can send that uploaded image to whatever recipients you want (groups included). Have a good year!!!

nautical commented 9 years ago

I was able to upload the image successfully , the sending part is not working , will try your code and update.

morfeokmg commented 9 years ago

Let me if understand your change, we need two steps for send the image to the smartphone.

  1. Upload the image to the wattsapp server.
  2. Send the message to the group or participant, as the image uploaded.

My question is: what kind of message we need for send the image in step 2. (text, url, image) What I need implement for end the module??

I implement the legacy version for my server and I have reports on image format, my idea is send these one's to my wattsapp. Only I need the second step for complete this one.

I review the code but I don't the implementation for the command, I know how can with xml, only need the information for the command of send the image (that I understand the the command for upload is very different for the step 2nd)

morfeokmg commented 9 years ago

This is my test. I executed in debug mode.

.... YowsupConnectionManager: starting reader YowsupConnectionManager: started Sending picture /home/morfeokmg/watts/Caso1.jpg of size 42781 with name Caso1.jpg Sending media_requestUpload BinTreeNodeWriter: Outgoing BinTreeNodeWriter:

......

BinTreeNodeReader:  Incoming
BinTreeNodeReader:  
<iq type="result" from="s.whatsapp.net" id="upload_1">
    <duplicate mimetype="image/jpeg"     filehash="hsjVxrz8M1Z0J8nNmQAcBph3NIsuU6SDiNl6xiGp6OM="     url="https://mmi631.whatsapp.net/d/AubJPvfWLCHP69u3qvJxNxoTVl1N0wNkjuC0mnt4B5t0.jpg"     height="434" width="700" type="image" size="42781">
    </duplicate>
</iq>

Request Dublicate: hash: hsjVxrz8M1Z0J8nNmQAcBph3NIsuU6SDiNl6xiGp6OM= url:     https://mmi631.whatsapp.net/d/AubJPvfWLCHP69u3qvJxNxoTVl1N0wNkjuC0mnt4B5t0.jpg 
Sending message_image
BinTreeNodeWriter:  Outgoing
BinTreeNodeWriter:  
<message to="XXXXXXX-XXXXX@g.us" type="text" id="1420751496-0">
    <media     url="https://mmi631.whatsapp.net/d/AubJPvfWLCHP69u3qvJxNxoTVl1N0wNkjuC0mnt4B5t0.jpg"     type="image" file="Caso1.jpg" size="42781">
    796573
    </media>
    <x xmlns="jabber:x:event">
        <server>
        </server>
    </x>
</message>

BinTreeNodeReader:  Incoming
BinTreeNodeReader:  
<ack count="5" t="1420751480" from="XXXXXXXXXXX@g.us" id="XXXXXXX-0" class="message">
</ack>

Got request MediaReceipt

Please, I need know what I need modify or implement in the code!!!!.

Best Regards.

nautical commented 9 years ago

@ivanbaldo can u give a gist of example that you wrote worked ?

morfeokmg commented 9 years ago

I review the code on connectionmanager.py I think that the incomplete code is:

  @mediaNode
def sendImage(self, jid, url, name, size, preview):
    return "image"

If this is correct, i Need implement some return as

    return ProtocolTreeNode("media", {"type":"location","latitude":latitude,"longitude":longitude},None,preview)

but i don't know the variables, @tgalal, @chirikchik, @debianitram do you know what parameters i need???

Thanks in advance!

morfeokmg commented 9 years ago

I analize the debug, and this is my unique conclusion

From UploaderClient.py the correct execution is:

            ReaderThread:   Read thread startedX
             YowsupConnectionManager:   started
            Sending picture /home/morfeokmg/watts/CasoMau.jpg of size 42781 with name CasoMau.jpg
            Sending media_requestUpload
            BinTreeNodeWriter:  Outgoing
            BinTreeNodeWriter:  
            <iq to="s.whatsapp.net" xmlns="w:m" type="set" id="upload_1">
                <media type="image" hash="hsjVxrz8M1Z0J8nNmQAcBph3NIsuU6SDiNl6xiGp6OM=" size="42781">
                </media>
            </iq>

This part doesn't work or is incomplete (I think that is the second option) (from UploaderClient.py Interface : message_imageSend)

            def doSendImage(self, url):
                        print("Sending message_image")
                        statinfo = os.stat(self.path)
                        name=os.path.basename(self.path)

                        #im = Image.open("c:\\users\\poot\\desktop\\icon.png")                                                                                               
                #im.thumbnail(size, Image.ANTIALIAS)                                                                                                                 

                    msgId = self.methodsInterface.call("message_imageSend", (self.jid, url, name,str(statinfo.st_size), "yes"))
                #msgId = self.methodsInterface.call("message_imageSend", (self.jid, url, name,str(statinfo.st_size), self.createThumb()))                            
                self.sentCache[msgId] = [int(time.time()), self.path]

            Request Dublicate: hash: hsjVxrz8M1Z0J8nNmQAcBph3NIsuU6SDiNl6xiGp6OM= url: https://mmi631.whatsapp.net/d/AubJPvfWLCHP69u3qvJxNxoTVl1N0wNkjuC0mnt4B5t0.jpg 
            Sending message_image
            BinTreeNodeWriter:  Outgoing
            BinTreeNodeWriter:  
            <message to="XXXXXXXXXXX-XXXXXXX@g.us" type="text" id="XXXXXXXXX-0">
                <media url="https://mmi631.whatsapp.net/d/AubJPvfWLCHP69u3qvJxNxoTVl1N0wNkjuC0mnt4B5t0.jpg" type="image" file="CasoMau.jpg" size="42781">
                    796573
                </media>
                <x xmlns="jabber:x:event">
                    <server>
                    </server>
                </x>
            </message>

But message_imageSend Is
self.methodInterface.registerCallback("message_imageSend",self.sendImage)

and sendImage is not implemented

            @sendMessage
                @mediaNode
            def sendImage(self, jid, url, name, size, preview):
                return "image"              

what I Need for implement the missing code?

Thanks!

tgalal commented 9 years ago

Hi all! I appreciate your efforts a lot! I've finished building this into yowsup and yowsup-cli and will publish it with documentation in a few a hours.

morfeokmg commented 9 years ago

If we can contribute something, we will be very pleased !!!!

morfeokmg commented 9 years ago

Sorry @tgalal, do you have the update or only the documentation?

BR

nautical commented 9 years ago

Thanks working well now ..

morfeokmg commented 9 years ago

hi!, some update????

BR

morfeokmg commented 9 years ago

Sorry, some update????

morfeokmg commented 9 years ago

@tgalal, i search in the documents, but doesn't have more about this one:

         def sendImage(self, jid, url, name, size, preview):
            #return "image"
            self._d("sending image (" + name + ":" + str(size) + ")")

            return ProtocolTreeNode("media",     {"type":"image","name":name,"size":size,"url":url,"to":jid},None,preview)

I review your code, but, i don't understand in what part is implemented the types for ProtocolTreeNode.

Please, help me to understand this one!

BR

tgalal commented 9 years ago

I'm sorry there is not going to be an update/support for legacy (unless someone wants to send a pull a request). This issue was opened for yowsup2 though and sending images is working there so I'll need to close it

morfeokmg commented 9 years ago

OK, thanks!, let me open some request for legacy.

jigarrdesai commented 9 years ago

how to sent image from path using yowsup-cli demos command?

niravtrivedi commented 9 years ago

I have tried below steps

pip uninstall PIL sudo apt-get install libjpeg-dev pip install -I pillow

Thanks