I'm building a simple image navigator application in Python using Flask. I want to have forward and backward buttons to navigate through all the images in the static folder. So far, I've a single button which displays the image without refreshing the page. How can I navigate through the directory using buttons?
app.py
from flask import Flask, render_template
app = Flask(__name__)
#app.route("/")
def hello():
return render_template('upload.html')
#app.route("/getimage")
def get_img():
return "00621.jpg"
if __name__ == '__main__':
app.run()
upload.html
<!DOCTYPE html>
<html lang="en">
<style>
img {
max-width: 100%;
max-height: 100%;
}
</style>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
$(document).ready(function() {
$('#retrieve').click(function(){
$.ajax({
url: "{{ url_for ('get_img') }}",
type : 'POST',
contentType: 'application/json;charset=UTF-8',
data : {'data':{{}}}
success: function(response) {
$("#myimg").attr('src', 'static/' + response);
},
error: function(xhr) {
//Do Something to handle error
}
});
});
});
</script>
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"
integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
</head>
<body>
<div class="container">
<div class="row">
<div class="col-lg-12">
<h1 class="page-header">Image Annotator</h1>
</div>
<button type='button' id ='retrieve'>Submit</button>
<img src="" id="myimg" />
</div>
</div>
</body>
</html>
I have reconstructed some of your code to achieve the answer. Please be aware that I've switched things from Jquery to JS.
New HTML Page:
<!DOCTYPE html>
<html lang="en">
<style>
img {
max-width: 100%;
max-height: 100%;
}
</style>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"
integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
</head>
<body>
<div class="container">
<div class="row">
<div class="col-lg-12">
<h1 class="page-header">Image Annotator</h1>
</div>
<button type='button' onclick="oclick()" id='retrieve'>Submit</button>
<button onclick="action(2)" type="button">Backward</button><button onclick="action(1)" type="button">Forward</button>
<image src="" id="myimg"></image>
</div>
</div>
<script>
var imgap = 0
function oclick(){
var getInitialImage = new XMLHttpRequest();
getInitialImage.open("GET", "/getimage");
getInitialImage.onreadystatechange = function (){
if (this.readyState == 4 && this.status == 200){
document.getElementById("myimg").setAttribute("src", "/image/" + this.responseText);
}
}
getInitialImage.send();
}
function action(ac){
if (ac == 1){
imgap += 1
var getnextimagedetails = new XMLHttpRequest();
getnextimagedetails.open("GET", "/getimage?num=" + imgap.toString());
getnextimagedetails.onreadystatechange = function (){
if (this.readyState == 4 && this.status == 200){
document.getElementById("myimg").setAttribute("src", "/image/" + this.responseText);
}
}
getnextimagedetails.send();
}
if (ac == 2){
imgap += -1
var getlastimagedetails = new XMLHttpRequest();
getlastimagedetails.open("GET", "/getimage?num=" + imgap.toString());
getlastimagedetails.onreadystatechange = function (){
if (this.readyState == 4 && this.status == 200){
document.getElementById("myimg").setAttribute("src", "/image/" + this.responseText);
}
}
getlastimagedetails.send();
}
}
</script>
</body>
</html>
New Flask Document:
from flask import Flask, send_from_directory, request
import os
app = Flask(__name__)
#app.route("/")
def hello():
return send_from_directory('', 'upload.html')
#app.route("/image/<path:path>")
def image(path):
print(path)
if (path.endswith(".jpg") or path.endswith(".png") or path.endswith(".bmp") or path.endswith(".jpeg")):
return send_from_directory("", path)
return "", 500
#app.route("/getimage")
def get_img():
print(request.args.get("num"))
if (request.args.get("num") != None):
dirfiles = os.listdir()
presentedstr = []
for string in dirfiles:
if (string.endswith(".jpg") or string.endswith(".svg") or string.endswith(".bmp") or string.endswith(".jpeg") or string.endswith(".png")):
presentedstr.append(string)
presentedstr.index("00621.jpg")
return presentedstr[presentedstr.index("00621.jpg") + int(request.args.get("num"))]
else:
return "00621.jpg"
if __name__ == '__main__':
app.run()
How this implementation works, is the button will send out a request to the server for what the next image or item is, before making another request for the actual next image itself. It will search the same directory.
Related
I'm working in a personal project and in one section I'm showing cards on the screen, but the card only show one at time. I needed to do a Ajax call and it's working good, but the only thing that I can't get is the response from my view.
This is my Ajax call:
$('#accept').on('click', function() {
var accept_value = $('#accept').val();
$.ajax({
url: '/cards/',
type: 'POST',
data: {'duo_status': accept_value},
headers: { "X-CSRFToken": "{{ csrf_token }}" },
success: function(data) {
console.log('Accepted: success')
console.log(data)
}
})
})
And I'm sending this from my view, that is a list of objects:
return render(request, 'cards.html', {'duo_filter': shuffled_list})
When I click the button, the data is sent to the views.py normally, but when I try to show this data in the console, it shows me this:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-KyZXEAg3QhqLMpG8r+8fhAXLRk2vvoC2f3B09zVXn8CA5QIVfZOJ3BCsw2P0p/We" crossorigin="anonymous">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<title>Cards</title>
</head>
<body>
<div style="display: flex;">
<strong style="padding: 0 5px;"></strong>
<p id="card_username"></p>
</div>
<!--BOTÕES (ACEITAR/RECUSAR)-->
<div style="display: flex;">
<button style="margin: 10px 20px; background-color: red;"
id="refuse"
value="refuse,">
Recusar
</button>
<button style="margin: 10px 20px; background-color: green;"
id="accept"
value="accept,">
Aceitar
</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.1.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-U1DAWAznBHeqEIlVSCgzq+c9gqGAJn5c/t99JyeKa9xxaYpSvHU5awsuZVVFIhvj" crossorigin="anonymous"></script>
<script type="text/javascript">
$(document).ready(function() {
$('#refuse').on('click', function() {
var refuse_value = $('#refuse').val();
$.ajax({
url: '/cards/',
type: 'post',
data: {'duo_status': refuse_value},
headers: { "X-CSRFToken": "mfMSEGkKK22vPYy9Ut2DnrVjonr5oPerERO0q6CHrQrUiqpIeK9xuYUb8Ob2cz7y" },
success: function(data) {
console.log('Refused -> success')
}
})
})
$('#accept').on('click', function() {
var accept_value = $('#accept').val();
$.ajax({
url: '/cards/',
type: 'POST',
data: {'duo_status': accept_value},
headers: { "X-CSRFToken": "mfMSEGkKK22vPYy9Ut2DnrVjonr5oPerERO0q6CHrQrUiqpIeK9xuYUb8Ob2cz7y" },
success: function(data) {
console.log('Accepted -> success')
console.log(data)
}
})
})
})
</script>
</body>
</html>
This is literally the response I get in my console and it is my HTML page, I have no idea why, anyone knows what am I doing wrong?
Thanks!!
you are returning render of cards.html in the view snippet you show:
return render(request, 'cards.html', {'duo_filter': shuffled_list})
Render generates an html page.
Do you just want to return json?
from django.http import JsonResponse
return JsonResponse({'duo_filter': shuffled_list})
What is the simplest way to change class name form .black to .white in the example below using python and flask framework? For example: after mouse click on div #area ?
CSS file:
#area {position:absolute;width:100px;height:100px;}
.black {background-color:#000;}
.white {background-color:#fff;}
HTML file:
<!doctype html>
<html>
<head>
<title>Title</title>
<link rel="stylesheet" href="{{ url_for('static',filename='style.css')}}">
</head>
<body>
<div id="area" class="black"></div>
</body>
</html>
This need JavaScript and it has nothing to do with Flask
Example using querySelector()
<div id="area" class="black" onclick="change();"></div>
<script>
area = document.querySelector('#area');
function change(){
area.classList.replace('black', 'white');
}
</script>
or using special variable this
<div id="area" class="black" onclick="change(this);"></div>
<script>
function change(item){
item.classList.replace('black', 'white');
}
</script>
Eventually you could use addEventListener instead of onclick
<div id="area" class="black"></div>
<script>
function change(){
this.classList.replace('black', 'white');
}
area = document.querySelector('#area');
area.addEventListener('click', change);
</script>
or shorter
<div id="area" class="black"></div>
<script>
area = document.querySelector('#area');
area.addEventListener('click', function(){
this.classList.replace('black', 'white');
});
</script>
or even little shorter
<div id="area" class="black"></div>
<script>
document.querySelector('#area').addEventListener('click', function(){
this.classList.replace('black', 'white');
});
</script>
Minimal working code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Title</title>
<style>
#area1 {width:100px;height:100px;}
#area2 {width:100px;height:100px;}
#area3 {width:100px;height:100px;}
#area4 {width:100px;height:100px;}
.black {background-color:#000;}
.white {background-color:#fff;}
</style>
</head>
<body>
<div id="area1" class="black" onclick="change1();"></div>
<br>
<div id="area2" class="black" onclick="change2(this);"></div>
<br>
<div id="area3" class="black"></div>
<br>
<div id="area4" class="black"></div>
<script>
area1 = document.querySelector('#area1');
function change1(){
area1.classList.replace('black', 'white');
console.log('change1');
}
function change2(item){
item.classList.replace('black', 'white');
console.log('change2');
}
function change3(){
this.classList.replace('black', 'white');
console.log('change3');
}
area3 = document.querySelector('#area3');
area3.addEventListener('click', change3);
area4 = document.querySelector('#area4');
area4.addEventListener('click', function(){
this.classList.replace('black', 'white');
console.log('change4');
});
</script>
</body>
</html>
Using Python you would have to use <a></a> which would send information to server when you click it. And server would use Python to generate HTML with new class and send it back to browser. But it means to reload all page and it needs time.
Minimal working code:
I put black area in <a></a> which ?color=white and when server gets it then it sends back HTML with white area and with ?color=black, etc.
from flask import Flask, request, render_template_string
app = Flask(__name__)
#app.route('/')
def index():
color = request.args.get('color', 'black')
if color == 'black':
other = 'white'
else:
other = 'black'
return render_template_string('''
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Title</title>
<style>
#area {width:100px;height:100px;}
.black {background-color:#000;}
.white {background-color:#fff;}
</style>
</head>
<body>
<div id="area" class="{{ color }}"></div>
</body>
</html>''', color=color, other=other)
if __name__ == '__main__':
app.run()
It is not popular but you can load JavaScript module Brython to run some Python code in web browser. But you can uses only modules converted to JavaScript
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Title</title>
<style>
#area {width:100px;height:100px;}
.black {background-color:#000;}
.white {background-color:#fff;}
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/brython/3.9.1/brython.min.js"></script>
</head>
<body onload="brython()">
<div id="area" class="black"></div>
<script type="text/python">
from browser import document
def change(ev):
if document['area'].attrs['class'] == 'black':
document['area'].attrs['class'] = 'white'
else:
document['area'].attrs['class'] = 'black'
document["area"].bind("click", change)
</script>
</body>
</html>
There is also transcrypt which can convert some Python code to JavaScript code and run in web browser.
Similar module RapydScript
Thanks, but it must be Python. I have found solution for printing a list, for example:
If I create a list called 'content'=['white','black'] the code below will print: white black and it works fine.
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="{{ url_for('static',filename='style.css')}}">
</head>
<body>
{% for x in content %}
{{x}}
{% endfor %}
</body>
</html>
So according to my question the code below should also work:
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="{{ url_for('static',filename='style.css')}}">
</head>
<body>
{% if x==1 %}
<div id="area" class="white"></div>
{% else %}
<div id="area" class="black"></div>
{% endif %}
</body>
</html>
But it doesn't, any ideas?
There is a python script for face recognition that i want to modify and run it in my laravel application to give access to the users to a page using face recognition. But i have no idea how to do that.
Here is the original html ( not the one of my application) :
you take a snapshot and compare the image with images you have in a folder
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="css/bootstrap.min.css">
<link rel="stylesheet" href="css/style.css">
<title>Login</title>
</head>
<body onload="init()">
<nav class="navbar text-white navbar-dark bg-dark">
<a href="#" class="navbar-brand">
Login
</a>
</nav>
<p>
</p>
<div class="container text-center bordered" style="width:280px">
<form action="login.py" method="post" enctype="multipart/form-data">
<video onclick="snapshot(this);" width=250 height=250 id="video" controls autoplay></video>
<br>
<input type="email" placeholder="Email" name="email" class="form-control form-control-sm text-left">
<br>
<input type="text" accept="image/png" hidden name="current_image" id="current_image">
<button onclick="login()" class="btn-dark" value="login">Login </button>
<br>
<br>
</form>
</div>
<canvas id="myCanvas" width="400" height="350" hidden></canvas>
</body>
<script>
//--------------------
// GET USER MEDIA CODE
//--------------------
navigator.mediaDevices.getUserMedia = ( navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.msGetUserMedia);
var video;
var webcamStream;
if (navigator.getUserMedia) {
navigator.getUserMedia (
// constraints
{
video: true,
audio: false
},
// successCallback
function(localMediaStream) {
video = document.querySelector('video');
video.srcObject = localMediaStream;
webcamStream = localMediaStream;
},
// errorCallback
function(err) {
console.log("The following error occured: " + err);
}
);
} else {
console.log("getUserMedia not supported");
}
var canvas, ctx;
function init() {
// Get the canvas and obtain a context for
// drawing in it
mcanvas = document.getElementById("myCanvas");
ctx = mcanvas.getContext('2d');
}
function login() {
// Draws current image from the video element into the canvas
ctx.drawImage(video,0,0,mcanvas.width,mcanvas.height);
var dataURL = mcanvas.toDataURL('image/png');
document.getElementById("current_image").value=dataURL;
}
</script>
</html>
and the python :
#!"C:\Users\aya-i\AppData\Local\Programs\Python\Python38\python.exe"
import cgi
from base64 import b64decode
import face_recognition
formData = cgi.FieldStorage()
face_match=0
image=formData.getvalue("current_image")
email=formData.getvalue("email")
data_uri = image
header, encoded = data_uri.split(",", 1)
data = b64decode(encoded)
with open("image.png", "wb") as f:
f.write(data)
got_image = face_recognition.load_image_file("image.png")
existing_image = face_recognition.load_image_file("students/"+email+".jpg")
got_image_facialfeatures = face_recognition.face_encodings(got_image)[0]
existing_image_facialfeatures = face_recognition.face_encodings(existing_image)[0]
results= face_recognition.compare_faces([existing_image_facialfeatures],got_image_facialfeatures)
if(results[0]):
face_match=1
else:
face_match=0
print("Content-Type: text/html")
print()
if(face_match==1):
print("<script>alert('welcome ",email," ')</script>")
else:
print("<script>alert('face not recognized')</script>")
Any external commands such as unix terminal commands, python command and ... should be run with PHP's exec() function. This function runs your commands and has an option to get the output of your command, you have to handle the error and success output yourself.
This question already has answers here:
Flask App: Update progress bar while function runs
(3 answers)
Closed 1 year ago.
Just want to insert a progress bar in my html page. It should load from a for in my app.py. That's what I did so far...
app.py
from flask import Flask, render_template
app = Flask(__name__)
#app.route('/')
def index():
return render_template('index.html')
#app.route('/progress')
def ajax_index():
for i in range(500):
print("%d" % i)
# I want to load this in a progress bar
if __name__ == "__main__":
app.run(debug=True)
I'm using a bootstrap progress-bar from w3schools in my code
index.html
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script>
$(function () {
$("#content").load("/progress");
});
</script>
</head>
<body>
<div class="container">
<h2>Progress Bar With Label</h2>
<div class="progress">
<div class="progress-bar" role="progressbar" aria-valuenow="70" aria-valuemin="0" aria-valuemax="100" style="width:0%"></div>
</div>
</div>
</body>
</html>
Any help, please?
this is pretty simple: poll your api and update the progress bar width and valuenow until finished:
var interval = setInterval(update_progress, 1000);
function update_progress() {
$.get('/progress').done(function(n){
n = n / 5; // percent value
if (n == 100) {
clearInterval(interval);
callback(); // user defined
}
$('.progress-bar').animate({'width': n +'%'}).attr('aria-valuenow', n);
}).fail(function() {
clearInterval(interval);
displayerror(); // user defined
});
}
I am trying to implement the same stack overflow text-area with syntax highlighting in Python and have come this far but i am not able to get it working.
app.py
from flask import Flask, render_template, request
import preview
app = Flask(__name__)
#app.route('/',methods=['GET','POST'])
def index():
if request.method == 'POST':
markdown_content = request.args.get['wdd-input']
post_preview = preview.markdown(markdown_content['data'])
return render_template('test.html', result=post_preview)
if request.method == 'GET':
return render_template('demo.html')
if __name__ == '__main__':
app.run()
preview is something which does syntax highlighting and its based upon Pygments.
test.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>PageDown Demo Page</title>
<link rel="stylesheet" type="text/css" href="/static/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="/static/css/highlighting.css">
<link rel="stylesheet" type="text/css" href="/static/css/demo.css" />
<script type="text/javascript" src="/static/js/jquery-1.9.1.min.js"></script>
<script type="text/javascript" src="/static/js/bootstrap.min.js"></script>
<script type="text/javascript" src="/static/js/hycus-textarea.js"></script>
<script type="text/javascript" src="/static/js/Markdown.Editor.js"></script>
<script type="text/javascript">
(function (m) {
m(document).ready(function () {
m('textarea.wmd-input').TextAreaResizer();
});
})(jQuery);
</script>
</head>
<body>
<div class="container">
<div id="pagedwon">
<div id="tabnav">
<ul class="nav nav-tabs" id="markdown_tab" style="padding: 0 10px; margin-bottom: 10px;">
<li class="active">Edit</li>
<li>Preview</li>
</ul>
</div>
<div class="tab-content">
<div class="tab-pane active" id="edit">
<div class="wmd-panel">
<div id="wmd-button-bar"></div>
<textarea class="wmd-input" id="wmd-input" rows="10" name="text-input">
This is the *pagedown* editor.
------------------------------
**Note**: Just plain **Markdown**, except that the input is sanitized: **HTML** is not allowed.
</textarea>
</div>
<script type="text/javascript">
(function () {
var pagedown_editor = new Markdown.Editor();
pagedown_editor.run();
})();
</script>
<script type="text/javascript">
(function (m) {
m("#markdown_tab a").click(function () {
if (m(this).html() == "Preview"){
var markdown_content = m("#wmd-input").val();
if (!markdown_content) {
m("div#markdownpreview").html("Empty Markdown Content.");
} else {
content_to_preview = {
"data": markdown_content
}
m.post("/", content_to_preview)
.success( function(preview_content){
if (preview_content == 'None'){
m("div#markdownpreview").html("No content received.");
} else {
m("div#markdownpreview").html(preview_content);
}
})
.error( function () {
m("div#markdownpreview").html("Sorry, error occurred. Please retry.");
});
}
}
});
})(jQuery);
</script>
</div>
<div class="tab-pane markdown-body" id="markdownpreview">
Loding preview content ...
</div>
</div>
</div>
</div>
</body>
</html>
This is log from the console:
127.0.0.1 - - [26/Jun/2014 20:25:01] "POST / HTTP/1.1" 500 -
How to get it working, please help. I am new to Flask.
First, request.args is for query string parameters, but you are sending over data via POST. You should be using request.form instead.
Second, MultiDict.get is a function, and does not support the __getitem__ protocol (which is the cause of your 500 error).
Third, as #Doobeh points out in the comments, you are sending the data over under the key data, but you are trying to access it via the key "wdd-input" - this will result in a BadRequest error.
Finally, the value extracted from request.form will be a string (which does not support strings as __getitem__ values) - and you don't need it anyway, as you already have the entire string.
A re-worked version of your POST portion:
if request.method == 'POST':
markdown_content = request.form.get('data', 'No content yet ...')
post_preview = preview.markdown(markdown_content)
return render_template('test.html', result=post_preview)