Prevent duplicated scans in a single QR code scan in DJango - python

The current camera scans the QR code and posts the same value to view_nurse.py multiple times till the QR code is moved away from the camera. This causes my database to have many repeated values shown in the image below. How do I prevent this from happening?
In situations where I scan another QR code without relaunching the camera, the program should be able to detect that it is a new QR code and POST the results into the views_nurse.py.
<nurse_home.html>
{% load static %}
{% block mainbody %}
<title>Django Online Barcode Reader</title>
<meta charset="utf-8">
{% csrf_token %}
<script src={% static "js/html5-qrcode.min.js" %}></script>
<style>
.result{
background-color: green;
color:#fff;
padding:20px;
}
.row{
display:flex;
}
</style>
<!--<form action="" method="POST">-->
{% csrf_token %}
<div class="row">
<div class="col">
<div style="width:500px;" id="reader"></div>
</div>
<div class="col" style="padding:30px;">
<h4>Scanned Result</h4>
<!--<div id="result" name="result">Result Here</div>-->
<output type="POST" id="result" name="result" placeholder="qrCodeMessage">
{% csrf_token %}
</div>
</div>
<script type="text/javascript">
// 1) Create a function to get the CSRF token
function getCookie(name) {
let cookie = document.cookie.match("(^|;) ?" + name + "=([^;]*)(;|$)");
return cookie ? cookie[2] : null;
}
// 2) After generating the qrcode in the onScanSuccess callback, you invoke sendQrCode function with the qr code as argument
function onScanSuccess(qrCodeMessage) {
document.getElementById("result").innerHTML = '<span class="result">' + qrCodeMessage + "</span>";
// Call the function here
sendQrCode(qrCodeMessage);
}
//3) Fetch to send a POST request to nurse_qrscan route:
async function sendQrCode(qrCode) {
console.log(qrCode)
const response = await fetch("/nurse_qrscan", {
method: "POST",
headers: {
"X-CSRFToken": getCookie("csrftoken"),
},
body: JSON.stringify({
result: qrCode,
}),
})
.then((response) => response.json())
.then((data) => {
console.log(data)
}
);
}
function onScanError(errorMessage) {
//handle scan error
}
var html5QrcodeScanner = new Html5QrcodeScanner("reader", {
fps: 10,
qrbox: 250,
});
html5QrcodeScanner.render(onScanSuccess, onScanError);
</script>
{% endblock %}
<view_nurse.py>
#api_view(['GET',"POST"])
# Nurse scans QR
def nurse_qrscan(request):
if request.method == 'POST':
# parse the JSON data
data = json.load(request)
result = data.get("result")
if result != None:
c = connection.cursor()
# Saving the result to database, nurse_QR
c.execute("INSERT INTO nurse_QR (output) VALUES ('{0}');".format(result))
return Action.success()
<Image: Output shown in database - Values of the single QR code is repeated multiple times from the POSTS>

Related

Why the fields of card payment are empty?

I am creating an online shopping and the users should pay their orders by using a credit card payment. So, I created a sandbox account to test the Braintree API, install the Braintree and make the all configuration as it is shown the python files below. But, as you can notice in figure 3, the card information framework is displayed with only the card lables but there are the fields of the Card number, the Cvv and the expiration date of the card.
Payment/views.py:
import braintree
from django.shortcuts import render, redirect, get_object_or_404
from orders.models import Order
def payment_process(request):
order_id = request.session.get('order_id')
order = get_object_or_404(Order, id=order_id)
if request.method == 'POST':
# retrieve nonce
nonce = request.POST.get('payment_method_nonce', None)
# create and submit transaction
result = braintree.Transaction.sale({
'amount': '{:.2f}'.format(order.get_total_cost()),
'payment_method_nonce': nonce,
'options': {
'submit_for_settlement': True
}
})
if result.is_success:
# mark the order as paid
order.paid = True
# store the unique transaction id
order.braintree_id = result.transaction.id
order.save()
return redirect('payment:done')
else:
return redirect('payment:canceled')
else:
# generate token
client_token = braintree.ClientToken.generate()
return render(request,
'payment/process.html',
{'order': order,
'client_token': client_token})
def payment_done(request):
return render(request, 'payment/done.html')
def payment_canceled(request):
return render(request, 'payment/canceled.html')
After clicking on the Place order button, I was expecting to get a form like the one below but unfortunately, I've got a form without fields.
This is the template that displays the payment form and processes:
{% extends "base.html" %}
{% block title %}Pay by credit card{% endblock %}
{% block content %}
<h1>Pay by credit card</h1>
<form action="." id="payment" method="post">
<label for="card-number">Card Number</label>
<div id="card-number" class="field"></div>
<label for="cvv">CVV</label>
<div id="cvv" class="field"></div>
<label for="expiration-date">Expiration Date</label>
<div id="expiration-date" class="field"></div>
<input type="hidden" id="nonce" name="payment_method_nonce" value="">
{% csrf_token %}
<input type="submit" value="Pay">
</form>
<!-- Load the required client component. -->
<script src="https://js.braintreegateway.com/web/3.29.0/js/client.min.js">
</script>
<!-- Load Hosted Fields component. -->
<script src="https://js.braintreegateway.com/web/3.29.0/js/hostedfields.min.js"></script>
<script>
var form = document.querySelector('#payment');
var submit = document.querySelector('input[type="submit"]');
braintree.client.create({
authorization: '{{ client_token }}'
}, function (clientErr, clientInstance) {
if (clientErr) {
console.error(clientErr);
return;
}
braintree.hostedFields.create({
client: clientInstance,
styles: {
'input': {'font-size': '13px'},
'input.invalid': {'color': 'red'},
'input.valid': {'color': 'green'}
},
fields: {
number: {selector: '#card-number'},
cvv: {selector: '#cvv'},
expirationDate: {selector: '#expiration-date'}
}
}, function (hostedFieldsErr, hostedFieldsInstance) {
if (hostedFieldsErr) {
console.error(hostedFieldsErr);
return;
}
submit.removeAttribute('disabled');
form.addEventListener('submit', function (event) {
event.preventDefault();
hostedFieldsInstance.tokenize(function (tokenizeErr, payload) {
if (tokenizeErr) {
console.error(tokenizeErr);
return;
}
// set nonce to send to the server
document.getElementById('nonce').value = payload.nonce;
// submit form
document.getElementById('payment').submit();
});
}, false);
});
});
</script>
{% endblock %}
How can I get an "empty cart information" and not even have the cards fields while I have placed an order?
Thanks

update sqlite database in python after the item from dropdown suggestions selected

My program must update table "idlist" in python after the item was selected from drop down suggestions in js. User selects the item, after that POST request in python adds it to the "idlist" table.
As I run the program I get the following error message:
I am grateful for your ideas and suggestions:
Here is my python code:
def search():
"""Search for books that match query"""
if request.method == "GET":
if not request.args.get("q"):
return render_template("adjust.html")
else:
q = request.args.get("q") + "%"
books = db.execute("SELECT Title, Author FROM book WHERE Title LIKE :q OR Author LIKE :q", q=q)
return jsonify(books)
if request.method == "POST" and request.form.get("title"):
Title = request.form.get("title")
insert_book = db.execute("INSERT INTO idlist (id,Title1, Status) VALUES (:id, :Title1, :Status)", id=session["user_id"], Title1=Title, Status="Not started")
return redirect("/")
return render_template("adjust.html")
Here is html:
{% extends "layout.html" %}
{% block title %}
Add your Book
{% endblock %}
{% block main %}
<form action="/adjust" method="POST">
<div class="form-group">
<p>Choose your Book</p>
<label class="sr-only" for="q">Title, Author</label>
<input class="form-control" id="q" placeholder="Title, Author" name="title" type="text" autocomplete="off" />
</div>
<button class="btn btn-primary" type="submit">Add</button>
</form>
{% endblock %}
Here is js:
function configure()
{
// Configure typeahead
$("#q").typeahead({
highlight: false,
minLength: 1
},
{
display: function(suggestion) { return suggestion.Title; },
limit: 10,
source: search,
templates: {
suggestion: Handlebars.compile(
"<div>"+
"{{Title}}, {{Author}}" +
"</div>"
)
}
});
// Give focus to text box
$("#q").focus();
}
// Search database for typeahead's suggestions
function search(query, syncResults, asyncResults)
{
// Get places matching query (asynchronously)
let parameters = {
q: query
};
$.getJSON("/adjust", parameters, function(data, textStatus, jqXHR) {
// Call typeahead's callback with search results (Author Title)
asyncResults(data);
});
}
$(document).ready(function() {
configure();
});
Don't use Ajax to Add new book it will make user confused because he don't know if it was added to the idlist or not, use the Form POST instead.
in script.js remove the following block
$("#q").on('typeahead:selected', function a(eventObject, suggestion, name) {
...
...
});
and to add selected item to the input form, replace
display: function(suggestion) { return null; },
with
display: function(suggestion) { return suggestion.Title; },
to make form POST, in adjust.html replace
<form action="/adjust">
....
<input class="form-control" id="q" placeholder="Title, Author" type="text"/>
with
<form action="/addbook" method="POST">
....
<input class="form-control" id="q" placeholder="Title, Author" name="title" type="text" autocomplete="off" />
And the addBook() method
#app.route("/addbook", methods=["GET", "POST"])
def addbook():
"""Add selected book"""
if request.method == "POST" and request.form.get("title"):
Title = request.form.get("title")
insert_book = db.execute("INSERT INTO idlist (id,Title1, Status) VALUES (:id, :Title1, :Status)", id=session["user_id"], Title1=Title, Status="Not started")
return redirect("/")
# no "title" in the form, return to Add new book page
return redirect("/adjust")

How to send selected data from a datatable?

I take some user input that results in a table which I can display. Now I want to allow the user to select some data and then send these data back to another function where it is further processed. For the toy example I use for demonstration purposes, it might look like this:
Unfortunately, I fail to do so. The critical parts are probably thisjquery part (the entire code can be found below):
$('#send_data').bind('click', function() {
$.getJSON('/_selected_data', {
sel_data: table.rows().data().toArray()
}, function(data) {
alert('This worked')
});
return false;
});
and this part of my Python code:
#app.route('/_selected_data')
def get_selected_data():
sel_data = request.args.get('sel_data')
When I print sel_data it prints None, when I use requests.json it does not work either; ideally it would be possible to get the results again as a pandas dataframe with the same columns headers.
How would I do this correctly? Also, if the user does not select any data, then of course the entire table should be returned.
This is the entire code:
from flask import Flask, render_template, request, jsonify
import pandas as pd
import numpy as np
import json
# just for reproducibility
np.random.seed(0)
# Initialize the Flask application
app = Flask(__name__)
#app.route('/')
def index():
return render_template('index.html')
#app.route('/_get_table')
def get_table():
a = request.args.get('a', type=int)
b = request.args.get('b', type=int)
df = pd.DataFrame(np.random.randint(0, 100, size=(a, b)), columns=['C1', 'C2'])
return jsonify(number_elements=a * b,
my_table=json.loads(df.to_json(orient="split"))["data"],
columns=[{"title": str(col)} for col in json.loads(df.to_json(orient="split"))["columns"]])
#app.route('/_selected_data')
def get_selected_data():
sel_data = request.args.get('sel_data')
print(sel_data)
return jsonify(dummy_data=1)
if __name__ == '__main__':
app.run(debug=True)
and my index.html
<!DOCTYPE html>
<html lang="en">
<head>
<link href="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdn.datatables.net/1.10.16/css/jquery.dataTables.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
<div class="header">
<h3 class="text-muted">Create a pretty table</h3>
</div>
<div>
<p>Number of rows</p>
<input type="text" size="5" id="a" value="10">
<p>Number of columns</p>
<input type="text" size="5" id="b" value="2">
<p>get a pretty table</p>
<p>send selected data</p>
<p>Result</p>
<p>Number of elements:</p>
<span id="elements">Hallo</span><br>
<table id="a_nice_table" class="table table-striped">Here should be a table</table>
</div>
</div>
<script src="https://code.jquery.com/jquery-1.12.4.js" type="text/javascript"></script>
<script src="https://cdn.datatables.net/1.10.16/js/jquery.dataTables.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function() {
var table = null;
$('#calculate').bind('click', function() {
$.getJSON('/_get_table', {
a: $('#a').val(),
b: $('#b').val()
}, function(data) {
$("#elements").text(data.number_elements);
if (table !== null) {
table.destroy();
table = null;
$("#a_nice_table").empty();
}
table = $("#a_nice_table").DataTable({
data: data.my_table,
columns: data.columns
});
});
return false;
});
$('#send_data').bind('click', function() {
$.getJSON('/_selected_data', {
sel_data: table.rows().data().toArray()
}, function(data) {
alert('This worked')
});
return false;
});
});
</script>
</body>
</html>
Here is my attempted solution to your problem. I'm making the assumption that the user can only select one row at a time.
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<link href="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdn.datatables.net/1.10.16/css/jquery.dataTables.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
<div class="header">
<h3 class="text-muted">Create a pretty table</h3>
</div>
<div>
<p>Number of rows</p>
<input type="text" size="5" id="a" value="10">
<p>Number of columns</p>
<input type="text" size="5" id="b" value="2">
<p>get a pretty table</p>
<p>send selected data</p>
<p>Result</p>
<p>Number of elements:</p>
<span id="elements">Hallo</span><br>
<table id="a_nice_table" class="table table-striped">Here should be a table</table>
</div>
</div>
<script src="https://code.jquery.com/jquery-1.12.4.js" type="text/javascript"></script>
<script src="https://cdn.datatables.net/1.10.16/js/jquery.dataTables.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function() {
var table = null;
var selected = null;
$('#calculate').bind('click', function() {
$.getJSON('/_get_table', {
a: $('#a').val(),
b: $('#b').val()
}, function(data) {
$("#elements").text(data.number_elements);
if (table !== null) {
table.destroy();
table = null;
$("#a_nice_table").empty();
}
table = $("#a_nice_table").DataTable({
data: data.my_table,
columns: data.columns
});
var drawn_table = document.getElementById('a_nice_table'),
selected = drawn_table.getElementsByClassName('selected');
drawn_table.onclick = highlight;
function highlight(e) {
if (selected[0]) selected[0].className = '';
e.target.parentNode.className = 'selected';
}
});
return false;
});
$('#send_data').bind('click', function() {
var selected = $("tr.selected").html();
if (selected != null) {
console.log("<thead>" + $("#a_nice_table thead").html() + "</thead><tbody><tr>" + selected + "</tr></tbody>");
$.getJSON('/_selected_data', {
sel_data: "<thead>" + $("#a_nice_table thead").html() + "</thead><tbody><tr>" + selected + "</tr></tbody>"
}, function(data) {
alert('This worked');
});
} else {
console.log($("#a_nice_table").html());
$.getJSON('/_selected_data', {
sel_data: $("#a_nice_table").html()
}, function(data) {
alert('This worked');
});
}
return false;
});
});
</script>
</body>
</html>
app.py
from flask import Flask, render_template, request, jsonify
import pandas as pd
import numpy as np
import json
# just for reproducibility
np.random.seed(0)
# Initialize the Flask application
app = Flask(__name__)
#app.route('/')
def index():
return render_template('index.html')
#app.route('/_get_table')
def get_table():
a = request.args.get('a', type=int)
b = request.args.get('b', type=int)
df = pd.DataFrame(np.random.randint(0, 100, size=(a, b)), columns=['C1', 'C2'])
return jsonify(number_elements=a * b,
my_table=json.loads(df.to_json(orient="split"))["data"],
columns=[{"title": str(col)} for col in json.loads(df.to_json(orient="split"))["columns"]])
#app.route('/_selected_data')
def get_selected_data():
sel_data = request.args.get('sel_data')
df_list = pd.read_html("<table>" + sel_data + "</table>")
df = pd.concat(df_list)
print(df)
return jsonify(dummy_data=1)
if __name__ == '__main__':
app.run(debug=True)
So basically what happens is that after a table is randomly generated, I have to create a couple of variables (drawn_table and selected) to track the table and its selected row. As of now, there's no visual change to when a row is selected but it's up to you if you want to make any CSS modifications to denote when a row is selected. When a user does click a row, the row gets a class assignment of "selected", and any other row gets deselected. This is so that JQuery will know what row is selected when sending it back to the server.
Then in the send_data link, I'll find the tr (table row) element that has the "selected" class (tr.selected) and grab the html code inside this element. If the element exists, then I will send the html along with the table header info as JSON to flask. If there is no tr.selected element, then the html code is obviously undefined, so the code will run the else part of the block and send the entire table.
In app.py, I read the JSON value, which is a string of HTML code. Since Pandas has a read_html method, I can pass the HTML string to the method to create a list of dataframes. Then I concat the list of dataframes to make my final df.
You can see the result of the dataframe in Python's console log (print(df)). You can also see the html code result in your browsers inspector because I added some console.log statements.

google-charts not getting displayed on the server

My code:
<html>
<head>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['FileName', 'Frequency'],
{% for l in list1 %}
[{{l.file_name}},{{l.frequency_count}}],
{% endfor %}
]);
var options = {
title: 'Search Performance',
hAxis: {title: 'FileName', titleTextStyle: {color: 'red'}}
};
var chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
</script>
</head>
<body>
<div id="chart_div" style="width: 900px; height: 500px;"></div>
</body>
</html>
On running my app (created in Django) on the server this chart is not getting displayed, why? This page is "results.html" which is directed from my views.py file. Here "list1" contains the data stored in the table namely "file_name" and "frequency_count". Why is this happening?
I'm new to Django, google-charts and JavaScript.
You may have a problem in the loop that prints the javacript array of values for the chart. I guess the filenames are strings, and as such they need to be delimited with ' or ", like this:
{% for l in list1 %}
['{{ l.file_name }}', {{ l.frequency_count }}],
{% endfor %}
To test this, I just got rid of the loop and put a couple of rows of sample static data, like this:
var data = google.visualization.arrayToDataTable([
['FileName', 'Frequency'],
['this', 100],
['that', 200]
]);
And I got the chart working:

Facing problem in returning the ongoing upload status back to the HTML using AJAX in Django

I am trying to implement "Upload Progress Bar" in Django.
Following is my code in the template file:
{% extends "index_base.html" %}
{% block content %}
<script src="/media/js/functions.js" type="text/javascript"></script>
<script src="/media/js/jquery.js" type="text/javascript"> </script>
<script type="text/javascript">
var xhrObject1;
var xhrObject2;
function createXMLHttpObject()
{
var xhrObject; // The variable that makes Ajax possible!
try
{
xhrObject = new XMLHttpRequest();
}
catch (e)
{
try{
xhrObject = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e){
try {
xhrObject = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {
xhrObject = null;
}
}
}
return xhrObject;
}
function ajaxFunction()
{
xhrObject1 = createXMLHttpObject();
if (xhrObject1 == null)
{
alert("Your browser does not support ajax.");
return;
}
xhrObject1.onreadystatechange = function(){
if(xhrObject1.readyState == 4){
document.getElementById("targetDiv").innerHTML = xhrObject1.responseText;
}
else
{
xhrObject2 = createXMLHttpObject();
xhrObject2.onreadystatechange = function(){
if(xhrObject2.readyState == 4){
document.getElementById("targetDiv").innerHTML = xhrObject2.responseText;
}
else
{
document.getElementById("targetDiv").innerHTML = "getting progress...";
}
}
xhrObject2.open("GET", "/upload_progress.psp", true);
xhrObject2.send(null);
}
}
var arrFiles = document.getElementById('id_file');
var fileToUpload = arrFiles.files[0];
xhrObject1.open("POST", "/upload.psp/", true);
xhrObject1.send(fileToUpload);
}
function submitForm()
{
document.forms["myform"].submit();
ajaxFunction();
return false;
}
</script>
<div id="main_container">
{% include "includes/nav.html" %}
<!------- Main Contents ---------->
<div id="contents_holder">
<div id="contents">
<div id="c_banner">
<span class="main_title">Upload File</span>
</div>
<div id="targetDiv" > </div>
<div id="setting">
<form name="myform" id="myform" action="/upload.psp/" method="post" enctype="multipart/form-data">
<h2>Upload File</h2></br>
<p>{{ form.file.label_tag }} {{ form.file }}</p></br>
<input type="button" value="Upload" name="uploadButton" onclick="javascript:return submitForm();"/>
<input type="button" value="Cancel" name="cancelUploadButton" onclick ="cancelUploadClicked()"/>
<input type="hidden" value="title" name="title" id="title" />
</form>
</div>
</div>
</div>
</div>
{% endblock %}
Following are my two functions inside views.py:
#condition(etag_func=None)
def upload(request):
if request.method == 'POST':
form = UploadFileForm(request.POST, request.FILES)
if form.is_valid():
#handle_uploaded_file(request.FILES['file'])
f = request.FILES['file']
filename = "/host_lighttpd/var/www/htdocs/satellite/static/Data/" + f.name
destination = open(filename, 'wb+')
for chunk in f.chunks():
destination.write(chunk)
#yield chunk
request.session['uploaded'] += chunk
destination.close()
return render_to_response('uploadsuccess.html')
else:
form = UploadFileForm()
return render_to_response('upload.html', {'form': form})
def upload_progress(request):
#uploaded = request.session['uploaded']
return HttpResponse("Upload progress function...")
#return HttpResponse(uploaded)
My problem is how can I return the upload status back to the
second ajax call (GET method), so that it can be eventually updated
inside the html.
I don't know how can I return the ongoing uploading status.
Any help would be appreciated. Thanks in advance.
I recently had to do a bit of digging to find a solution for this myself.
Check out :-
http://fairviewcomputing.com/blog/2008/10/21/ajax-upload-progress-bars-jquery-django-nginx/
I have not tried the solution referenced yet, but it looks reasonable enough.
It involves registering a custom file upload class to expose the upload progress information.

Categories

Resources