How can I send both text and image? - python

In my chat application, only the text is can be sent right now. I'm trying to add a feature in which the images can also be sent. However, there is one point I'm stuck in. When receiving the data, how can I discriminate between photo and text? I'm asking this because these two are completely different procedures. In one of them, we encode it with UTF-8 and send, while in the other we send bytes. On the server side, how can I discriminate them?
I was able to add a send-photo feature on the client side as shown below. When I try it, it succesfully sends image bytes. The only thing I need to is to discriminate the text from bytes on the server side.
As my code is too long, I prefer not to add all of it here. You can access it through my github https://github.com/suleymanyaman/randomchatserver
Client
def sendphoto():
dlg = QFileDialog()
dlg.setFileMode(QFileDialog.AnyFile)
img_dir = QStringListModel()
if dlg.exec_():
img_dir = dlg.selectedFiles()[0]
data = open(r'{}'.format(img_dir),'rb').read()
s.send(data)
Server
while 1:
msg = client.recv(100000000).decode("utf-8")

Once it's on the network, everything is bytes. To add support for images, you just need to send some message that says "An image is coming next." Your protocol hopefully already has some "control messages" that you can use for this.
If you want to keep the protocol "readable" (i.e. you prefer all bytes to be sensible UTF-8), you could use base 64 encoding or similar to turn your images into "text" before sending them. But that probably isn't necessary.

Related

How to send encoded and decoded image over HTTP

I need to send an encoded and decoded image along with some metadata via HTTP.
I would like to send the images as binary data instead of encoding them as base64 as encoding & decoding adds unnecessary latency.
So for example, the encoded image may look like this:
img = open(img_file, 'rb').read()
and the decoded image may look like this:
img = cv2.imread(img_file)
Assume I also need to send some additional information in POST request, such as the image name for example.
What is the most efficient way to send these? What would the code look like in Python? What content-type or other headers would I need to use?
I've found some examples like this online, but they only send a single image and therefore set the content-type as image/jpeg, but I'm wondering what happens when you have additional fields to send.
If you want to send additional fields you have a few options:
Base64 encode the image data and embed it in a json string with all your extra data
Add custom HTTP headers with your fields in
Add your fields to the image metadata itself
I know you said you didn't want to do 1, but how do you know it is adding unnecessary latency if you've never tried it? I expect it's far less than the latency of an HTTP request. Option 2 is risky as the headers can get stripped or changed by network infrastructure and your users might not expect to find data in the headers. Option 3 depends a bit what the data is and whether it makes sense for it to be inside the image (and again whether your users know to look for it there)

decode bytes that are in string form with unkown encoding

So I just started my own little project to create a bot for a game,
but only did little coding before, so I am definitely no expert, if I get something mixed up or forget to mention some information, I apologize in advance!
so basically my python bot will connect to the server (WebSocket connection 13, the header says "Accept-Encoding: gzip, deflate, br"), I use the WebSocket module and that works well. the game sends messages in JSON format. however, they are filled up with backslashes, I think internally a javascript clears those out / splits each message into multiple ones and removes the outermost layer. so far my solution is to just clear out the backslashes and from there on it's pretty straightforward.
problem is: map data is apparently encoded. so basically the message would look like this:
{"type":"pkg","data":"[\"{\\\"type\\\":\\\"pl\\\",\\\"data\\\":[\\\"{\\\\\\\"type\\\\\\\":\\\\\\\"p\\\\\\\",\\\\\\\"id\\\\\\\":227727,\\\\\\\"tpl\\\\\\\":227727,\\\\\\\"s\\\\\\\":458
.... and then at the end of the message (its a lot longer, i just didnt to post 30 lines of compressed data):
{\\\"type\\\":\\\"zip\\\",\\\"data\\\":\\\"{\\\\\\\"type\\\\\\\":\\\\\\\"map\\\\\\\",\\\\\\\"xî182îyî478îtilesî\\\\\\\"1:î¢î¤î£î¦526_21î¢254
which is obviously the encoded / compressed map data. firefox dev tools however shows it decompressed too, it then looks more like this:
\\\\\\\"map\\\\\\\",\\\\\\\"xî\u0080\u0086182î\u0080\u008dyî\u0080\u0086478î\u0080\u008dtilesî\u0080\u0086\\\\\\\"1:î\u0080¢î\u0080¤î\u0080£î\u0080¦526_21î\u0080¢254:36î\u0080²î\u0080´î\u0080³î\u0080µ:î\u0080¬î\u0080¸î\u0080ºî\u0080·î\u0080·î\u0080ºî\u0080¼î\u0080¶
I tried around with different commands and modules like zlib, but honestly, I m really lost. is that data already decoded and now in byte form or is that still compressed zip data? if so, how can I decode it, as I right now handle it as a raw string? or should I put it into a data file from the get-go? what does the xi, in the beginning, stand for, the encoding scheme?
any help is greatly appreciated, I would really like to know what the heck is going on here :D

Interfacing a QR code recognition to a django database

I'm coming to you with the following issue:
I have a bunch of physical boxes onto which I still stick QR codes generated using a python module named qrcode. In a nutshell, what I would like to do is everytime someone wants to take the object contained in a box, he scans the qr code with his phone, then takes it and put it back when he is done, not forgetting to scan the QR code again.
Pretty simple, isn't it?
I already have a django table containing all my objects.
Now my question is related to the design. I suspect the easiest way to achieve that is to have a POST request link in the QR code which will create a new entry in a table with the name of the object that has been picked or put back, the time (I would like to store this information).
If that's the correct way to do, how would you approach it? I'm not too sure I see how to make a POST request with a QR code. Would you have any idea?
Thanks.
PS: Another alternative I can think of would be to a link in the QR code to a form with a dummy button the user would click on. Once clicked the button would update the database. But I would fine a solution without any button more convenient...
The question boils down to a few choices: (a) what data do you want to encode into the QR code; (b) what app will you use to scan the QR code; and (c) how do you want the app to use / respond to the encoded data.
If you want your users to use off-the-shelf QR code readers (like free smartphone apps), then encoding a full URL to the appropriate API on your backend makes sense. Whether this should be a GET or POST depends on the QR code reader. I'd expect most to use GET, but you should verify that for your choice of app. That should be functionally fine, if you don't have any concerns about who should be able to scan the code.
If you want more control, e.g. you'd like to keep track of who scanned the code or other info not available to the server side just from a static URL request, you need a different approach. Something like, store the item ID (not URL) in the QR code; create your own simple QR code scanner app (many good examples exist) and add a little extra logic to that client, like requiring the user to log in with an ID + password, and build the URL dynamically from the item ID and the user ID. Many security variations possible (like JWT token) -- how you do that won't be dictated by the contents of the QR code. You could do a lot of other things in that QR code scanner / client, like add GPS location, ask the user to indicate why or where they're taking the item, etc.
So you can choose between a simple way with no controls, and a more complex way that would allow you to layer in whatever other controls and extra data you need.
If security is not a big concern: an API with a simple get method that takes as argument the object id and I will presume you have the code to make sure if the object is given as taken it will be switched to returned.
And why not post? POST needs headers that you can't include in qr unless you have a dedicated app, so GET and the ability to use example.com/api/leaseandret?id=12345 is a better alternative that allows for better usage with a QR.
A summary of the methods*
* A note here is that GET is not forbidden from being used to modify data and send data to a server GET is exclusively for getting data from a REST purist standpoint.

Determining if a MIME email part is a file or message text

As part of some email batch processing, we need to decode and clean up the messages. One critical part of that process is separating the mail bodies of a message and the mail attachments. The trickiest part is to determine when a Conent-Disposition: inline part is to be considered a message body alternative or a file.
So far, this code seems to handle most of the cases:
from email import message_from_string
def split_parts(raw):
msg = message_from_string(raw)
bodies = []
files = []
for sub in msg.walk():
if sub.is_multipart():
continue
cd = sub.get("Content-Disposition", "")
if cd.startswith("attachment") or (cd.startswith("inline") and
sub.get_filename()):
files.append(sub)
else:
bodies.append(sub)
return bodies, files
Note the reliance on the inline parts to have a filename specified in the headers, which Outlook seems to do for all its multipart/related messages. The Content-ID could also be used as a hint, but according to the RFC 2387 it is not such an indicator.
Therefore, if an embedded image is encoded as a message part that has Content-Disposition: inline, defines a Content-ID and doesn't have a filename then the above code can mistakenly classify it as a message body alternative.
From what I've read from the RFC's, there's not much hope on finding an easy check (specially since coding according to the RFCs is almost useless in the real world, because nobody does it); but I was wondering how big the chances are to hit the misclassification case.
Rationale
I could have a set of functions to treat each multipart/* case and let them indirectly recurse. However, we don't care so much about a faithful display; as a matter of fact, we filter all HTML messages through tidy. Instead, we are more interested in chosing one of the message body alternatives and saving as many attachments as possible, even if they are intended to be embedded.
Furthermore, some user agents do really weird things when composing multipart/alternative messages with embedded attachments that are not intended to be displayed inline (such as PDF files), as a result of the user dragging and dropping an arbitrary file into the composition window.
I'm not quite following you, but, if you want bodies, I would assume anything with a text/plain or text/html content type, with an inline content disposition, with no file name or no content-id, could be a body part.

How can I send in-body images in a mail using python?

how can i send in-body attached images in a mail using python?
I found this: http://docs.python.org/library/email-examples.html but it has not an example with images.
Thanks!
Take a look at the big example of "how to send the entire contents of a directory as an email message". The image in the file fp is converted into the message part msg here:
msg = MIMEImage(fp.read(), _subtype=subtype)
and then the message part is attached to the outer message here:
msg.add_header('Content-Disposition', 'attachment', filename=filename)
outer.attach(msg)
If you want the image to appear inline rather than as an attachment, you should set its Content-Disposition to inline instead of attachment.
(If you want to create HTML messages that display attached images, then you need to use the multipart/related MIME type defined in RFC 2387. Ask if you need help with this.)
Attach the image and use html to display it. See the MIME example from your link for how to attach it. An <img> tag will do for display in most clients. Make sure you use the appropriate MIME type for html. Your link tells you how to do that too.

Categories

Resources