Prevent double submits - python

I am using GAE for an app that has various submit href buttons, and use javascript to submit.
I am having a real tough time trying to figure out how to prevent multiple submits or doubl-clicking. I have tried various methods to disable or remove the href with javascript.
But I am thinking if there is maybe a method to prevent this in the backend.
What methods would you recommend I use?

Preventing it on the server side is not trivial - a second call may hit a different instance. So you need to deal with sessions. The code will get complex quickly.
I would recommend disabling the button before a call and reenabling it upon a response.

You can use a javascript to disable all submit buttons on your page when a form is submitted. Maybe something like this:
document.forms[0].addEventListener('submit', function() {
var btns = document.querySelectorAll('input[type="submit"]');
for (var i = 0; i < btns.length; i++) {
btns[i].disabled = 'disabled';
}
});
If you need to also disable other elements you can modify the querySelector.

Related

cannot return /user/docker when trying to route a function on Node js

I'm currently coding a website, on one of its pages there is a button that has to launch a python script taking 3 arguments (modif, id and type). My problem is that with the following code the web site returns me :
Cannot GET /users/docker
Here is the button in the html page :
<a class="btn yellow_btn" href="/users/docker?modif=modification&id=1&type=mysql">Valider</a>
Here is the route in my server.js :
app.get("/users/docker", function(req, res, modif, id, type){
console.log(modif);
console.log(id);
console.log(type);
const pythonInfo = spawn('python3', ['/home/flag-trader/script-python-site.py', modif, id, type]);
res.render("listCTF.ejs");
}
);
The python script is ok, I've tried it manually. What's more i've managed to launch it on the website by switching the button to a form that I've set hidden but it's kind of ugly and I wanna do it the proper way.
I'm kind of new with all the Nodejs stuff please try not to lose me, i'm pretty sure my code is missing just a few things to work. Thx a lot.

Django Views - Block Consecutive Quick Calls

A button click in my app calls a view which does a few database changes and then redirects to a new views which renders html. When the user typically clicks on the link, he accidentally clicks on in twice to thrice in a couple of seconds. I want to block the view call if the same call was made less than 10 seconds ago. Of course I can do it by checking in the database, but I was hoping to have a faster solution by using some decorator in django.
This should help. It's a JavaScript to disable the button on click, enable it after the operation completes.
$(document).ready(function () {
$("#btn").on("click", function() {
$(this).attr("disabled", "disabled");
doWork(); //this method contains your logic
});
});
function doWork() {
alert("doing work");
//actually this function will do something and when processing is done the button is enabled by removing the 'disabled' attribute
//I use setTimeout so you can see the button can only be clicked once, and can't be clicked again while work is being done
setTimeout('$("#btn").removeAttr("disabled")', 1500);
}
More info here.
You should disable the button with JavaScript after clicking on it.
This way the user is unable to trigger the view multiple times.
No, you can't use decorators in Django to do that.
The methods in your views file are supposed to be telling what to show on your screen. Whereas, the template files are created to tell Django how you want to show them.
You want Django to not count two consecutive calls on same view.
The problem is:
What do you mean by "consecutive"? How fast should I click to make it "non-consecutive"? What if I write a script that does the clicks? How would you define consecutive then?
Even if you did do that above part using some hack, the next problem would be to differentiate between the requests that come from different users (to that view). How would you differentiate between them to determine the "consecutiveness" of a particular user?
Why make unnecessary changes to do all this stuff?
Django is supposed to be used along with other things too. I have learned this the hard way. Using Javascript is the only way to do it, without any problems.
Client-side, one click and poof! disabled. Very fast and you have the request in pool.
Doing this part is easy. Refer to these links for more info:
How to disable html button using JavaScript?
Disable/enable an input with jQuery?

How to determine the size of html table in pixels given an html file

I have a html file that has various html tags in it. This html also has a bunch of tables in it. I am processing this file using python. How do I find out what the size (length x width in pixels) when it is rendered by a browser (preferably chrome or firefox)?
I am essentially looking for the information when you do "inspect element" on a browser, and you are able to see the size of the various elements. I want to access this size in my python code.
I am using lxml to parse my html and can use selenium if needed.
edit: added #node.js incase I can use it to spit out the size of all the tables in a shell script and I can grab it in python.
You're going to want to use Selenium WebDriver to open the HTML file in an actual browser installed on the computer that your Python code is running on.
I'm not sure how you'd use the Selenium WebDriver API to find out how tall a rendered table is, but the value_of_css_property method might do it.
If you can call out shellscript, and you can use Node.js, I'm assuming you could also install and use PhantomJS, which is a headless WebKit port. (I.e. an actual honest to goodness WebKit renderer that just doesn't require a window to work.) This will let you use Javascript and the familiar web libraries to manipulate the document. As an example, the following gets you the width of the logo element towards the upper left Stack Overflow site:
page = require('webpage').create(); // create a new "browser"
page.open('http://stackoverflow.com/', function() {
// callback when loading completes
var logoWidth = page.evaluate(function() {
// This runs in the rendered page and uses the version of jQuery that SO loads.
return $('#hlogo').width();
});
console.log(logoWidth); // prints 250, the same as Chrome.
phantom.exit(); // for some reason you need to exit manually
});
The documentation for PhantomJS will tell you more about what you can do with it and how.
One caveat however is that loading a page takes a while, since it needs to fetch CSS and scripts and generally do everything a browser does. I'm not sure if and how PhantomJS does any caching, if it does it might make sense to reuse the same process for multiple scrapes of the same site.

wxWidgets/wxPython: Migrating from htmlWindow to Webview

I have an app that uses htmlWindow and would like to migrate it to the new webview found in wx 2.9. However, I have learned there is no built-in method available to pass a JavaScript variable from the webpage back to the Python code. There is a RunScript method that allows one to send JavaScript to the page, but no method to retrieve an element id on a user click or any other user interaction.
My question is, is there any workaround to this? Is there any way to intercept, say, an alert call or anything else and get the data? The webview display is of not much value if one cannot receive data from user interaction.
As far as I'm aware the only way to get a return value from RunScript() is to use the page title hack.
e.g. somewhere in RunScript you set document.title to the value you wish to retrieve and get it into python with GetCurrentTitle(), if you wish you can reset the title after you have retrieved the data.
So if self.html is the webview
self.html.RunScript("""
//javascript goes here
// variable we wish to retrieve is called return_value
document.title = return_value
""")
r = self.html.GetCurrentTitle()
If you want to initiate it from within the webview it can be done (as suggested in the link Robin posted) by overriding the wxEVT_COMMAND_WEB_VIEW_NAVIGATING so that when it receives a custom url scheme, e.g. retrievedata://data/.... it retrieves the data from the url and does whatever you want with it, making sure you call evt.Veto() at some point. You can then pass any data you wish by simply calling a suitable url from within javascript.
Totally untested code below (just to give you an idea of how it can be done)
def OnPageNavigation(self, evt):
url = evt.GetUrl()
if url.startswith("retrievedata://data/"):
data = url[len("retrievedata://data/"):]
evt.Veto()
// Do whatever you want with the data
Alternatively you could use a combination of the two ideas and create a single url that when accessed calls GetPageTitle() and just make sure you set document.title before calling the page.
There was recently some discussion on the wx-users mail list and a suggestion for a workaround for things like this. I haven't tried it myself, but you may find it useful. See https://groups.google.com/d/topic/wx-users/Pdzl7AYPI4I/discussion

Finding rendered HTML element positions using WebKit (or Gecko)

I would like to get the dimensions (coordinates) for all the HTML elements of a webpage as they are rendered by a browser, that is the positions they are rendered at. For example, (top-left,top-right,bottom-left,bottom-right)
Could not find this in lxml. So, is there any library in Python that does this? I had also looked at Mechanize::Mozilla in Perl but, that seems difficult to configure/set-up.
I think the best way to do this for my requirement is to use a rendering engine - like WebKit or Gecko.
Are there any perl/python bindings available for the above two rendering engines? Google searches for tutorials on how to "plug-in" to the WebKit rendering engine is not very helpful.
lxml isn't going to help you at all. It isn't concerned about front-end rendering at all.
To accurately work out how something renders, you need to render it. For that you need to hook into a browser, spawn the page and run some JS on the page to find the DOM element and get its attributes.
It's totally possible but I think you should start by looking at how website screenshot factories work (as they'll share 90% of the code you need to get a browser launching and showing the right page).
You may want to still use lxml to inject your javascript into the page.
I agree with Oli, rendering the page in question and inspecting DOM via JavaScript is the most practical way IMHO.
You might find jQuery very useful here:
$(document).ready(function() {
var elem = $("div#some_container_id h1")
var elem_offset = elem.offset();
/* elem_offset is an object literal:
elem_offset = { x: 25, y: 140 }
*/
var elem_height = elem.height();
var elem_width = elem.width();
/* bottom_right is then
{ x: elem_offset.x + elem_width,
y: elem_offset.y + elem_height }
});
Related documentation is here.
Yes, Javascript is the way to go:
var allElements=document.getElementsByTagName("*"); will select all the elements in the page.
Then you can loop through this a extract the information you need from each element. Good documentation about getting the dimensions and positions of an element is here.
getElementsByTagName returns a nodelist not an array (so if your JS changes your HTML those changes will be reflected in the nodelist), so I'd be tempted to build the data into an AJAX post and send it to a server when it's done.
I was not able to find any easy solution (ie. Java/Perl/Python :) to hook onto Webkit/Gecko to solve the above rendering problem. The best I could find was the Lobo rendering engine written in Java which has a very clear API that does exactly what I want - access to both DOM and the rendering attributes of HTML elements.
JRex is a Java wrapper to Gecko rendering engine.
you have three main options:
1) http://www.gnu.org/software/pythonwebkit is webkit-based;
2) python-comtypes for accessing MSHTML (windows only)
3) hulahop (python-xpcom) which is xulrunner-based
you should get the pyjamas-desktop source code and look in the pyjd/ directory for "startup" code which will allow you to create a web browser application and begin, once the "page loaded" callback has been called by the engine, to manipulate the DOM.
you can perform node-walking, and can access the properties of the DOM elements that you require. you can look at the pyjamas/library/pyjamas/DOM.py module to see many of the things that you will need to be using in order to do what you want.
but if the three options above are not enough then you should read the page http://wiki.python.org/moin/WebBrowserProgramming for further options, many of which have been mentioned here by other people.
l.
You might consider looking at WWW::Selenium. With it (and selenium rc) you can puppet string IE, Firefox, or Safari from inside of Perl.
The problem is that current browsers don't render things quite the same. If you're looking for the standards compliant way of doing things, you could probably write something in Python to render the page, but that's going to be a hell of a lot of work.
You could use the wxHTML control from wxWidgets to render each part of a page individually to get an idea of it's size.
If you have a Mac you could try WebKit. That same article has some suggestions for solutions on other platforms too.

Categories

Resources