I'm trying to display a progress bar when a user presses a button.
How my code works:
- I'm using python flask to render a html template
- A user fills out a field and presses a button
- A process occurs and in the meantime a loading bar will appear under the Search button
I have been unable to achieve step 3. I have looked at many resources but none of them have an actual loading bar pop up.
enterid.html:
<!DOCTYPE html>
<html>
<head>
<title>DCF</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Reverse image search discord user id's">
<meta name="keywords" content="Discord">
<style>
h1 {
font-family: Arial, sans-serif;
color: #2f2d2d;
text-align: Center;
}
p {
font-family: Arial, sans-serif;
font-size: 14px;
text-align: Center;
color: #2f2d2d;
}
</style>
</head>
<body>
<form action = "http://localhost:5000/Scrape" method = "post">
<h1>Discord Catfish Finder</h1>
<p>Enter User ID: </p>
<p><input type = "text" name = "nm" /></p>
<p><input type = "submit" value = "submit" /></p>
</body>
</html>
A loading bar which i think looks cool and would like to use:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content=
"width=device-width, initial-scale=1.0">
<title>Loader Bar</title>
<style>
body {
background-color: #262626;
font-family: Lato, sans-serif;
}
.loader {
width: 150px;
margin: 150px auto 70px;
position: relative;
}
.loader .loading_1 {
position: relative;
width: 100%;
height: 10px;
border: 1px solid yellowgreen;
border-radius: 10px;
animation: turn 4s linear 1.75s infinite;
}
.loader .loading_1:before {
content: "";
display: block;
position: absolute;
width: 0;
height: 100%;
background-color: yellowgreen;
box-shadow: 10px 0px 15px 0px yellowgreen;
animation: load 2s linear infinite;
}
.loader .loading_2 {
position: absolute;
width: 100%;
top: 10px;
color: green;
font-size: 22px;
text-align: center;
animation: bounce 2s linear infinite;
}
@keyframes load {
0% {
width: 0%;
}
87.5% {
width: 100%;
}
}
@keyframes turn {
0% {
transform: rotateY(0deg);
}
6.25%,
50% {
transform: rotateY(180deg);
}
56.25%,
100% {
transform: rotateY(360deg);
}
}
@keyframes bounce {
0%,
100% {
top: 10px;
}
12.5% {
top: 30px;
}
}
</style>
</head>
<body>
<div >
<div ></div>
<div >Please Wait...</div>
</div>
</body>
</html>
My flask code if this affects anything:
from flask import Flask, redirect, url_for, request, render_template
import json
import requests
import webbrowser
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time
import psutil
import random
from os.path import exists
import os
import shutil
import threading
sem = threading.Semaphore()
app = Flask(__name__, template_folder='template')
@app.route('/')
def main_menu():
return redirect(url_for('enteruserid'))
@app.route('/EnterID')
def enteruserid():
return render_template('enterid.html')
@app.route('/notaninteger')
def notanint():
return "The value you entered wasn't an integer, please go back one page and change your input"
@app.route('/Failed')
def script_failed():
return "An unknown error occured, please try again"
@app.route('/Scraping/<target_id>')
def scrapingtheinternet(target_id):
sem.acquire()
try:
chrome_options = Options()
chrome_options.headless = True
chrome_options.add_argument("log-level=3")
chrome_options.add_experimental_option(
"excludeSwitches", ["enable-logging"])
driver = webdriver.Chrome(options=chrome_options)
begining_of_url = "https://lookup.guru/"
whole_url = begining_of_url str(target_id)
driver.get(whole_url)
wait = WebDriverWait(driver, 10)
wait.until(EC.visibility_of_element_located(
(By.XPATH, "//img")))
images = driver.find_elements_by_tag_name('img')
for image in images:
global pfp
pfp = (image.get_attribute('src'))
profileimageq = pfp.startswith(
"https://cdn.discordapp.com/avatars/")
if profileimageq == True:
break
img_data = requests.get(pfp).content
with open('pfpimage.png', 'wb') as handler:
handler.write(img_data)
handler.close()
filePath = 'pfpimage.png'
searchUrl = 'https://yandex.com/images/search'
files = {'upfile': ('blob', open(
filePath, 'rb'), 'image/jpeg')}
params = {'rpt': 'imageview', 'format': 'json',
'request': '{"blocks":[{"block":"b-page_type_search-by-image__link"}]}'}
response = requests.post(searchUrl, params=params, files=files)
query_string = json.loads(response.content)[
'blocks'][0]['params']['url']
img_search_url = searchUrl '?' query_string
webbrowser.open(whole_url)
webbrowser.open(img_search_url)
sem.release()
return "Opened results for id: %s" % target_id
except:
sem.release()
return redirect(url_for('script_failed'))
@app.route('/Overload/<cpu_load>')
def cpuoverload(cpu_load):
return 'CPU use too high, please try again later: %s' % cpu_load
@app.route('/Scrape', methods=['POST', 'GET'])
def login():
if request.method == 'POST':
id = request.form['nm']
try:
int(id)
except:
return redirect(url_for('notanint'))
cpu_load = psutil.cpu_percent(0.1)
if cpu_load >= 99.0:
return redirect(url_for('cpuoverload', cpu_load=cpu_load))
else:
return redirect(url_for('scrapingtheinternet', target_id=id))
else:
id = request.args.get('nm')
if __name__ == '__main__':
app.run(debug=True)
I'm a complete noob to html, css and java. Any help would be appreciated. From what I've seen, I believe that the loading bar should be possible in the html code by itself. Thanks in advance
CodePudding user response:
For long-running tasks in Flask, it is common to use a solution with Redis or Celery. This makes it possible to display a loading bar. You can find a detailed article on this here.
The following solution is very simpler and less professional. After submitting the form, an overlay is displayed, which contains the loading bar and animation.
<!DOCTYPE html>
<html>
<head>
<title>DCF</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Reverse image search discord user id's">
<meta name="keywords" content="Discord">
<style>
h1 {
font-family: Arial, sans-serif;
color: #2f2d2d;
text-align: Center;
}
p {
font-family: Arial, sans-serif;
font-size: 14px;
text-align: Center;
color: #2f2d2d;
}
.loader {
width: 150px;
margin: 150px auto 70px;
position: relative;
}
.loader .loading_1 {
position: relative;
width: 100%;
height: 10px;
border: 1px solid yellowgreen;
border-radius: 10px;
overflow: hidden;
animation: turn 4s linear infinite;
}
.loader .loading_1:before {
content: "";
display: block;
position: absolute;
width: 100%;
height: 100%;
background-color: yellowgreen;
box-shadow: 10px 0px 15px 0px yellowgreen;
animation: load 2s linear infinite;
}
.loader .loading_2 {
position: absolute;
width: 100%;
top: 10px;
color: green;
font-size: 22px;
text-align: center;
animation: bounce 2s linear infinite 0.0001s;
}
@keyframes load {
0% {
transform: translate(50%, 0px) scaleX(0);
}
87.5% {
transform: translate(0%, 0px) scaleX(1);
}
}
@keyframes turn {
0% {
transform: rotateY(0deg);
}
6.25%,
50% {
transform: rotateY(180deg);
}
56.25%,
100% {
transform: rotateY(360deg);
}
}
@keyframes bounce {
0%,
100% {
transform: translateY(10px);
}
12.5% {
transform: translateY(30px);
}
}
.overlay {
position: absolute;
display: none;
z-index: 9998;
width: 100vw;
height: 100vh;
top: 0;
left: 0;
background-color: #262626;
font-family: Lato, sans-serif;
}
.overlay.active {
display: block;
}
.loader.active {
display: block;
}
</style>
</head>
<body>
<form action="http://localhost:5000/Scrape" method="post">
<h1>Discord Catfish Finder</h1>
<p>Enter User ID: </p>
<p><input type = "text" name = "nm" /></p>
<p><input type = "submit" value = "submit" /></p>
</form>
<div >
<div >
<div ></div>
<div >Please Wait...</div>
</div>
</div>
<script type="text/javascript">
(() => {
document.querySelectorAll('form').forEach(elem => {
elem.addEventListener('submit', () => {
document.querySelector('div.overlay').classList.toggle('active');
})
});
})();
</script>
</body>
</html>