Ill try to explain it here but this is gonna require a video tutorial:
First there are several ways to achieve it. Although Anthony's suggestion
(cache.ram) is optimal it didnt work on production, I dont know why
cache.ram doesnt work on pythonanywhere.
I got the progress bar working on production using the scheduler, which i
dont like cos its db intensive and more complex to setup, but i had no
choice since the processes where too long to finish (10 minutes) and the
http conection times out before its done.
Cache.ram
Create 2 controllers, one for your view and another one to get the progress.
def getprogress():
return cache.ram('message', lambda: None, None)
def progress():
# when a form is submitted, change progress each second
if request.post_vars:
n = 20 #simulate 20 iterations
for i in range(n):
msg = "Inserting records"
percent = 100*(i+1) / n
#update the percent each 5%
if percent % 5 == 0:
#store the array in ram [percent, text msg]
message = cache.ram('message', lambda: ";".join([percent,
msg]), time_expire=0)
print "main:", percent, message
sleep(1)
#we are calling this controller through ajax so return a string
when done
return "done"
else:
message = cache.ram('message', lambda: -1, time_expire=0)
return locals()
The view:
<div class="well">
<div id="pbar">
<div class="row">
<div class="col-md-12">
<h3>Processing...</h3>
</div>
<div class="col-md-12">
<div class="progress progress-bar-xl"
style="margin-top: 3px">
<div class="progress-bar progress-bar-warning"
role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100"
style="width: 0%;">0%</div>
</div>
</div>
</div>
<div class="row">
<!-- <div class="col-md-1">
<input id="start" value="Pause" class="input-sm btn
btn-primary btn-gradient btn-block dark" style="line-height: 0.8em;padding:
0" type="submit">
</div>
<div class="col-md-1">
<input id="abort" value="Abort" class="input-sm btn
btn-danger btn-gradient btn-block dark" style="line-height: 0.8em;padding:
0" type="submit">
</div> -->
</div>
</div>
</div>
js:
create a progress bar "class" jquery ui required if i recall.
<script type="text/javascript">
function ProgressBar (selector) {
var self = this;
self.el = $(selector)
self.text = self.el.find("h3");
self.progress = self.el.find(".progress-bar");
self.btnstart = self.el.find("#start");
self.btnabort = self.el.find("#abort");
self.value = 0;
self.min = 0;
self.max = 100;
self.interval = 5000;
self.running = false;
self.timer = null;
self.offset = 0;
self.set_progress = function (value) {
value = value || 0;
var done = false;
if (value>=self.max) {
value = self.max
done = true;
};
value = parseInt(value) + "%";
self.progress.css("width", value);
self.progress.text(value);
if (done) self.done();
};
self.done = function (msg) {
var msg = msg || "Process Completed"
self.text.text(msg)
console.log("done", self.timer);
clearInterval(self.timer);
self.running = false;
};
self.abort = function (e) {
if (self.running) {
self.value = 0;
self.set_progress(0);
self.text.text("Aborted");
if (self.timer) {
clearInterval(self.timer);
};
self.running = false;
};
}
#ask the server for the progress
self.ask = function () {
var ask = $.ajax({
url: window.location.origin + "/default/getprogress"
, type: "get"
});
ask.done(function (res, msg, xhr) {
console.log(res);
if (res=="-1") {
console.log("not running...?");
self.done();
return
}
// var data = res.split(";");
var percent = parseInt(res[0]);
var msg = res[1];
// if (msg == "Error") {
// return self.done(msg);
// };
self.text.text(msg);
// console.log("resp", res);
self.value = percent + self.offset;
if (percent == 80 && self.offset < 10) {
self.offset +=0.5;
}
if (percent == 80 && self.offset >= 10 && self.offset < 15)
{
self.offset +=0.1;
}
self.set_progress(self.value);
});
ask.fail(function (xhr, status, error) {
var resp = xhr.responseText;
self.done("Error (see browser's console for details)");
if (console) {
console.log(resp);
};
// console.log(resp);
// console.log(status);
// console.log(error);
// clearInterval(self.timer);
// self.running = false;
})
};
self.start = function (e) {
self.text.text("Processing...");
if (!self.running) {
console.log("running");
self.value = 0;
self.set_progress();
self.ask();
self.timer = setInterval(self.ask, self.interval);
self.running = true
} else {
console.log("already runing");
}
}
self.set_progress(self.value);
// self.btnstart.on("click", self.start);
// self.btnabort.on("click", self.abort);
}
var pbar = new ProgressBar("#pbar");
pbar.start();
Note: this ProgressBar function is expecting a json response from the
server with an array like [50, "Processing"]
The scheduler is more complex to setup i might need to do a video tutorial
to exaplain it.
--
Resources:
- http://web2py.com
- http://web2py.com/book (Documentation)
- http://github.com/web2py/web2py (Source code)
- https://code.google.com/p/web2py/issues/list (Report Issues)
---
You received this message because you are subscribed to the Google Groups
"web2py-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.