Flask send variable data to python through url_for() - javascript

I want to send a variable value to python from flask html/js through url_for().
Python Code :
#app.route('/video_feed/<device>')
def video_feed(device):
# return the response generated along with the specific media
# type (mime type)
print(device)
try:
return Response(gen(int(device)),mimetype = "multipart/x-mixed-replace; boundary=frame")
except Exception as e:
return Response(gen(device),mimetype = "multipart/x-mixed-replace; boundary=frame")
Desired in flask html file:
data.value = 0;
image.src = "{{ url_for('video_feed', device=data.value)}}";
But it does not work, I get the error:
jinja2.exceptions.UndefinedError: 'data' is undefined
This does work, however I can't use the variable data.value in url_for() :
image.src = "{{ url_for('video_feed', device=0)}}";
I have tried several different things like:
image.src = "{{ url_for('video_feed', device=${data.value})}}";
image.src = "{{ url_for('video_feed', device=$data.value)}}";
image.src = "{{ url_for('video_feed', device=%s)}}", data.value;
But nothing seems to work. My javascript is a bit rusty.
Any help would be appreciated!
Cheers!

url_for is expanded on the server side, before the page gets sent to the browser and well before JavaScript runs.
If you know the number (for device/data.value) at page generation time, pass it in to the template via render_template().
If, however, you don't know the value until after the page is rendered, you're going to need to construct the img element from JavaScript.

Related

Javascript: Temporarily store and display image received from backend as binary data?

I am currently trying to display an image, which I receive from a backend server in a particular way/format, on the screen of the browser.
My problem is acutally closely related to this issue, for which no real answer exists.
Here is a screenshot displaying what the backend server's response looks like:
payload.data contains the data of the image, which is a green cloud (also attached at the end of this post for reference).
My first, probably very stupid, question would be: What kind of format/encoding is that?
Anyway, here is what I then further tried to process the data:
const blob = new Blob([action.payload.data], { //contains the data
type: action.payload.headers["content-type"] // 'image/png'
})
console.log("blob: ", blob);
const url = URL.createObjectURL(blob);
console.log("url : ", url)
As a result, the blob is sucessfully created, as well as the url. However, when I open that link, no image gets displayed.
I am stuck here and would appreaciate any kind of helpful hint pointing out where I am doing a mistake here.
Thanks very much for your support in advance.
PS: As promised, here is the actual png image:
It seems like your data attribute is still in binary format. You need to convert the hex into base64 in order to display the image.
First, if the server you're fetching the image form is yours, I would recommend encoding the image on the server before sending it to the client.
If the server is not yours and you can't change the data that is being returned, try something like this:
function hexToBase64(str) {
return btoa(String.fromCharCode.apply(null, str.replace(/\r|\n/g, "").replace(/([\da-fA-F]{2}) ?/g, "0x$1 ").replace(/ +$/, "").split(" ")));
}
And then use it like this:
const img = document.createElement('img');
img.src = 'data:image/jpeg;base64,' + hexToBase64('your-binary-data');
document.body.appendChild(img);
reference: How to display binary data as image - extjs 4

How to add img elements with Javascript when using Django?

I am trying to dynamically insert img elements to the website I am building which uses Django for the back-end. The images change often so I pass the src from Python to Javascript like this:
views.py
path='{% static "../static/assets/'+image_name+'" %}'
response = render(request, 'main.html',{'image_path':path})
return response
Then I declare a global variable in the template so I can use this in the .js files.
main.html
var imagePath = {{image_path|safe}}
Then I use Javascript to pass this as src to new img elements. However, when I do it, Django cannot find images. When I put the string as src to a img element manually, it works.
Does anyone know how to solve this?
You need to use this:
from django.templatetags.static import static
path = static(f'assets/{image_name}')
response = render(request, 'main.html',{'image_path':path})
return response

Unable to load concatenated static file source

I am new to django and eventually I learnt the use of static files in Django and to my relief I was finally able to load the files while hardcoding the file name in the {%static filename.jpg %}. However, when I tried to create a string by replacing the hardcoded filename.jpg with the dynamic file name, I wasn't getting the output.
Not working code snippet:
<script>
image_name = "1.png"
static_start = "{% static '"
static_end = "' %}"
image_src = static_start.concat(image_name, static_end)
window.alert(image_src)
var para = document.createElement("img");
{% load static %}
para.setAttribute("src", image_src)
var element = document.getElementById("div_test");
element.appendChild(para);
</script>
Working Code snippet:
<script>
var para = document.createElement("img");
{% load static %}
para.setAttribute("src", "{%static '1.png'%}")
var element = document.getElementById("div_test");
element.appendChild(para);
</script>
What I am trying to do is that, I have a bunch of image files that I am getting from somewhere through an API and I am storing them in the static folder. After downloading those image, I am trying to load them on my webpage, for that I am using the static file and getting the file name dynamically as I do not know what would the file name of the downloaded file.
The point is that string concatenation isn't working, while directly passing the string is.
Any help would really be appreciated.
P.S.: Apparently in the example shared above I am simply using 1.png which would eventually be replaced by the name of the file I wish to display.
Working code using get_static_prefix (the way I actually wanted)
<script>
image_name = "1.png"
var para = document.createElement("img");
{% load static %}
para.setAttribute("src", "{% get_static_prefix %}" + image_name)
var element = document.getElementById("div_test");
element.appendChild(para);
</script>
I think I understand what you are trying to do here, but I don't think it is possible. Django templates are rendered on the server, and JavaScript is rendered on the client-side. You are trying to create the template tag with JavaScript, but the template tags won't be evaluated on the client-side, they will just be strings.
So after referring to other posts, I realized what I was doing wrong. I believe there was something that wasn't right about string concatenation and the escape characters and therefore Django has an option for get_static_prefix and that is was I was supposed to use instead of that stupid string concatenation. I have edited my question with the correct working response, exactly the way I wanted it to.
References: Stackoverflow question,
Django tutorial

Ember cli replace image standard if image model is null in json

I want to display a standard image if the model in my json is null.
This is my function where first i successfully achieve to format the url in order to make it bigger (eg: https://i1.sndcdn.com/artworks-000121961221-bzjnxn-large.jpg to https://i1.sndcdn.com/artworks-000121961221-bzjnxn-t500x500.jpg) but then i can not assign a standard image when the model (artwork_url) is null.
formattedArtwork: Ember.computed('artwork_url', function() {
var splitURL, url;
if (this.get('artwork_url')) {
url = this.get('artwork_url');
splitURL = url.split('-large');
return splitURL[0] + '-t500x500' + splitURL[1];
} else {
url = this.get('https://mystandardimage.jpg');
return url;
}
}),
So if it gets the arwork_url i can format and display the img but if it does not get i would like to put a general image url i created, at the moment it says that my url is undefined although that url (https://i1.sndcdn.com/artworks-000121961221-bzjnxn-t500x500.jpg) really exists.
What am i doing wrong?
See the printscreen
After the debugger line, you should just return "https://i1.sndcdn.com/artworks-000121961221-bzjnxn-t500x500.jpg"

how to convert canvas to image to upload to flask?

Alright so I'm trying to upload a resized canvas image as a file to Flask.
First I tried to use the canvas.toDataURL() to convert it to a base64(?) string then tried to upload that as an image using formdata with AJAX, no luck.
Then I tried converting the base64 to a blob using this function:
function toblob(stuff) {
var g, type, bi, ab, ua, b, i;
g = stuff.split(',');
if (g[0].split('png')[1])
type = 'png';
else if (g[0].split('jpeg')[1])
type = 'jpeg';
else
return false;
bi = atob(g[1]);
ab = new ArrayBuffer(bi.length);
ua = new Uint8Array(ab);
for (i = 0; i < bi.length; i++) {
ua[i] = bi.charCodeAt(i);
}
b = new Blob([ua], {
type: "image/" + type
});
return b;
}
not image...
here's the ajax form I used:
s = new FormData();
s.append('image', toblob(d)); \\I believe I refer to this with request.files['image']?
var g = $.ajax({
url: 'url',
type: 'POST',
processData : false,
contentType : false,
data: s
}) //POSTDATA
Heres what I have so far serverside:
#app.route('/requests/<req>', methods=['POST'])
def requests(req=None):
if req == 'upload' and request.method == 'POST' and request.files['file']:
file = request.files['image'] \\referring to formdata() key
if file and allowed_file(file.filename):
n = secure_filename(file.filename)
file.save(os.path.join(app.config['UPLOAD_FOLDER'],n))
return redirect(url_for('index', p=n))
ALL THAT ASIDE AND MORE IMPORTANTLY
I feel pretty confident that the javascript is doing a good job of sending the data as many other stackoverflow questions use the same method for PHP servers and the server is indeed recieving the data.
My problem is that I don't know how to convert this data into a physical file to store into a directory?
I've tried using the upload tutorial but the data isn't a file so
that doesn't work.
I found one tutorial on how to upload blobs (I think?) but it doesn't work because it uses "files" which isn't defined.
Is there any way I can convert this data into physical image file through flask or js?
THANKYOU!
Found a work-around!
instead of using Flask's file.save(), I used werkzeug's FileStorage() Which (as far as I know) a raw version of the file.save() I used it by specifying the filename and stream(which is a blob FYI) like so:
FileStorage(stream=request.files['image']).save(os.path.join(app.config['AUTHOR_FOLDER'],'testpic.jpg')))
Plopped it down into the script, dodged around the error 400s and barely scrapped together a working function! haha.
It works but I have no idea how secure it is or how stable it is, just going to go with it for now. If any one has any experience please help me out. Thanks!
Life is awesome!

Categories