Python Flask, redirect after rendering a template - python

I'm trying to redirect a user after a template has been rendered. Essentially, my code waits till a variable turns to False, and then redirects the user. The code renders a loading animation and tells the user to wait. The code renders the html and css template, but then when the wait is over doesn't redirect the user to a new url. My code:
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
global is_busy
is_busy = False
app = Flask(__name__, template_folder='template')
#app.route('/')
def main_menu():
return redirect(url_for('enteruserid'))
#app.route('/EnterID')
def enteruserid():
global is_busy
return render_template('enterid.html')
def waitUntil(condition, output):
time.sleep(1)
#app.route('/Scrape', methods=['POST', 'GET'])
def login():
global is_busy
if request.method == 'POST':
id = request.form['nm']
try:
int(id)
return render_template('waitingscreen.html')
waitUntil(is_busy, False)
return redirect(url_for('scrapingtheinternet', target_id=id))
except:
return redirect(url_for('notanint'))
else:
id = request.args.get('nm')
if __name__ == '__main__':
app.run(debug=True)
This code doesn't include the function where the "Scraping" occurs.
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>Reverse Image Search</h1>
<p>Enter User ID: </p>
<p><input type = "text" name = "nm" /></p>
<p><input type = "submit" value = "submit" /></p>
</body>
</html>
waitingscreen.html:
<!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 class="loader">
<div class="loading_1"></div>
<div class="loading_2">Please Wait...</div>
</div>
</body>
</html>
I'd appreciate any help. Thanks :)

Basically, the return statement ends the function in almost all languages.
say
def func():
print("hi")
return 0
print("after return")
func()
output:
hi
Whatever after return will not be executed (although see this answer about finally).
In your context, you can try to preview "waitingscreen.html" on the frontend when you click the login button
and avoid rendering it from the backend.
Some simple JS will help.
refer: Display a ‘loading’ message while a time consuming function is executed in Flask
Hope it will clear your query.

Related

Popup of my CircleMarker isn't shown, Folium - Python

Popup of my CircleMarker object can't be accessed(it doesnt show when clicked on), the popups can be accessed by clicking at a certain CircleMarker object when two layers are active at the beginning but when I turn both layers off, and then turn on the volcano layer and then the population layer the volcano popup of a CircleMarker object isn't showing. Is there any way to solve this?
~
import folium
import pandas as ps
from branca.element import Template, MacroElement
data = ps.read_csv("Volcanoes.txt")
lat = list(data["LAT"])
lon = list(data["LON"])
elev = list(data["ELEV"])
name = list(data["NAME"])
html = """<h4>Volcano information:</h4>
<pre>
Height: %s m
Name: %s
</pre>
"""
template = """
{% macro html(this, kwargs) %}
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script>
$( function() {
$( "#maplegend" ).draggable({
start: function (event, ui) {
$(this).css({
right: "auto",
top: "auto",
bottom: "auto"
});
}
});
});
</script>
</head>
<body>
<div id='maplegend' class='maplegend'
style='position: absolute; z-index:9999; border:2px solid grey; background-color:rgba(255, 255, 255, 0.8);
border-radius:6px; padding: 10px; font-size:14px; right: 20px; bottom: 20px;'>
<div class='legend-title'>Legenda </div>
<div class='legend-scale'>
<ul class='legend-labels'>
<li><span style='background:red;opacity:0.7;'></span>Više od 20 mil stanovnika</li>
<li><span style='background:orange;opacity:0.7;'></span>Više od 10 mil i manje od 20 mil stanovnika</li>
<li><span style='background:green;opacity:0.7;'></span>Manje od 10 mil stanovnika</li>
<li><span style='background:red;opacity:0.7;'></span>Vulkani višlji od 3000m</li>
<li><span style='background:orange;opacity:0.7;'></span>Vulkani višlji od 1000m i manji od 30000m</li>
<li><span style='background:green;opacity:0.7;'></span>Vulkani niži od 1000m</li>
</ul>
</div>
</div>
</body>
</html>
<style type='text/css'>
.maplegend .legend-title {
text-align: left;
margin-bottom: 5px;
font-weight: bold;
font-size: 90%;
}
.maplegend .legend-scale ul {
margin: 0;
margin-bottom: 5px;
padding: 0;
float: left;
list-style: none;
}
.maplegend .legend-scale ul li {
font-size: 80%;
list-style: none;
margin-left: 0;
line-height: 18px;
margin-bottom: 2px;
}
.maplegend ul.legend-labels li span {
display: block;
float: left;
height: 16px;
width: 30px;
margin-right: 5px;
margin-left: 0;
border: 1px solid #999;
}
.maplegend .legend-source {
font-size: 80%;
color: #777;
clear: both;
}
.maplegend a {
color: #777;
}
</style>
{% endmacro %}"""
def color_producer(elevation):
if elevation<1000:
return 'green'
elif 1000 <= elevation <3000:
return 'orange'
else: return 'red'
map = folium.Map(location=[38.58,-99.09], zoom_start=6, tiles = "Stamen Terrain")
fgv = folium.FeatureGroup(name="Vulkani")
fgp = folium.FeatureGroup(name="Populacija")
fgp.add_child(folium.GeoJson(data=open('world.json','r',encoding='utf-8-sig').read(),
style_function=lambda x:{'fillColor':'green' if x['properties']['POP2005']<10000000 else 'orange' if 10000000 <= x['properties']['POP2005'] < 20000000 else 'red'}))
for lt, ln, el,nm in zip(lat, lon, elev,name):
iframe = folium.IFrame(html=html % (str(el),nm), width=200, height=100)
fgv.add_child(folium.CircleMarker(location=[lt, ln],radius = 10, popup=folium.Popup(iframe), fill_color=color_producer(el),color='grey',fill = True,fill_opacity=0.7 ))
macro = MacroElement()
macro._template = Template(template)
map.add_child(fgp)
map.add_child(fgv)
map.get_root().add_child(macro)
map.add_child(folium.LayerControl(autoZIndex=False))
map.save("Map1.html")
~
I tried map.add_child(fgv) after map.add_child(fgp) but to no avail.

Refreshing GPIO Pin Status Automatically On a Flask Server

I am building a garage controller using Raspberry Pi with a Flask Server on it. Everything is working as expected except the fact that I still need to figure out how to automatically update the GPIO pin status and refresh the html page to open/close automatically.
I have attached my code below, any help would be appreciated.
The refresh status button you see right now is a workaround I created to refresh the page. But I am looking for something to refresh the page automatically per PIN status change.
Flask Code
import time
from datetime import datetime
from flask import Flask, render_template, request
import RPi.GPIO as GPIO
import logging
app = Flask(__name__)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(16, GPIO.IN, GPIO.PUD_UP)
GPIO.setup(7, GPIO.OUT)
#app.route("/", methods=['GET', 'POST'])
def Status():
if GPIO.input(16) == GPIO.LOW:
app.logger.info('Gate is Closed')
return render_template('Closed.html')
elif GPIO.input(16) == GPIO.HIGH:
app.logger.info('Gate is Open')
return render_template('Open.html')
#app.route("/Open", methods=['GET', 'POST'])
def Open():
GPIO.output(7, True)
app.logger.info('Gate is Opening')
return render_template('Open.html')
#app.route("/Closed", methods=['GET', 'POST'])
def Closed():
GPIO.output(7, False)
app.logger.info('Gate is Closing')
return render_template('Closed.html')
if __name__ == "__main__":
app.run()
HTML Code for Closed
<html>
<head>
<meta name="viewport" content="width=device-width">
<!--<meta http-equiv="refresh"
content="1; url = /" />-->
<!--<link rel="stylesheet" type="text/css" href="stylesheet.css">-->
<style>
.switch {
vertical-align: middle;
position: relative;
display: inline-block;
width: 60px;
height: 34px;
}
.switch input {
opacity: 0;
width: 0;
height: 0;
}
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: .4s;
transition: .4s;
}
.slider:before {
position: absolute;
content: "";
height: 26px;
width: 26px;
left: 4px;
bottom: 4px;
background-color: white;
-webkit-transition: .4s;
transition: .4s;
}
input:checked + .slider {
background-color: #2196F3;
}
input:focus + .slider {
box-shadow: 0 0 1px #2196F3;
}
input:checked + .slider:before {
-webkit-transform: translateX(26px);
-ms-transform: translateX(26px);
transform: translateX(26px);
}
/* Rounded sliders */
.slider.round {
border-radius: 34px;
}
.slider.round:before {
border-radius: 50%;
}
.button {
color: #fff !important;
text-transform: uppercase;
text-decoration: none;
background: #000;
padding: 10px;
border-radius: 5px;
display: inline-block;
border: none;
transition: all 0.4s ease 0s;
}
.sliderWrapper{display: inline-block;margin:24px 24px 24px 24px;position:relative;}
.sliderWrapper div{display: inline-block;line-height:60px;}
</style>
<script type="text/javascript">
setTimeout (
function() { window.location.reload(); },
500
)
</script>
</head>
<body bgcolor="#ff5c33">
<center>
<br>
<h1>Gate Control</h1>
<br><br> <br> <br>
<h3>Use the toggle to Open/Close the Relay!</h3>
<form action="/Open">
<div class="sliderWrapper">
<div>Close </div>
<label class="switch">
<input type="checkbox" onclick="submit();">
<span class="slider round"></span>
</label>
<div> Open </div>
</div>
</form>
<div class="refresh">
<br><br>
<h3>Use the button to Refresh the Page/Status!</h3>
Refresh
</div>
</center>
</body>
</html>
HTML Code for Open
<html>
<head>
<meta name="viewport" content="width=device-width">
<!--<meta http-equiv="refresh"
content="1; url = /" />-->
<!--<link rel="stylesheet" type="text/css" href="stylesheet.css">-->
<style>
.switch {
vertical-align: middle;
position: relative;
display: inline-block;
width: 60px;
height: 34px;
}
.switch input {
opacity: 0;
width: 0;
height: 0;
}
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: .4s;
transition: .4s;
}
.slider:before {
position: absolute;
content: "";
height: 26px;
width: 26px;
left: 4px;
bottom: 4px;
background-color: white;
-webkit-transition: .4s;
transition: .4s;
}
input:checked + .slider {
background-color: #2196F3;
}
input:focus + .slider {
box-shadow: 0 0 1px #2196F3;
}
input:checked + .slider:before {
-webkit-transform: translateX(26px);
-ms-transform: translateX(26px);
transform: translateX(26px);
}
/* Rounded sliders */
.slider.round {
border-radius: 34px;
}
.slider.round:before {
border-radius: 50%;
}
.button {
color: #fff !important;
text-transform: uppercase;
text-decoration: none;
background: #000;
padding: 10px;
border-radius: 5px;
display: inline-block;
border: none;
transition: all 0.4s ease 0s;
}
.sliderWrapper{display: inline-block;margin:24px 24px 24px 24px;position:relative;}
.sliderWrapper div{display: inline-block;line-height:60px;}
</style>
<script type="text/javascript">
setTimeout (
function() { window.location.reload(); },
500
)
</script>
</head>
<body bgcolor="lightgreen">
<center>
<br>
<h1>Gate Control</h1>
<br><br> <br> <br>
<h3>Use the toggle to Open/Close the Relay!</h3>
<form action="/Closed">
<div class="sliderWrapper">
<div>Close </div>
<label class="switch">
<input type="checkbox" checked onclick="submit();">
<span class="slider round"></span>
</label>
<div> Open </div>
</div>
</form>
<div class="refresh">
<br><br>
<h3>Use the button to Refresh the Page/Status!</h3>
Refresh
</div>
</center>
</body>
</html>
You are running into how HTTP works in the classic client server way.
Your client in the front end request something from your server
if the requested resource/page is available the server responds. and sends it back to client.
Done
The above request/response cycle explains why your refresh button is needed.
In the past one way to work around this was to run some javascript/JQuery in the front end and periodically refresh the page (AJAX/long polling) And that will still work.
By now there are other ways too, for example use a (web)sockets to create a bi directional channel in which the server can push data to the client. Working around the problem you have with classic request/response. (Flask Socket IO for example)
Both ways are worth researching, but javascript to periodically poll will probably be the quickest if not the prettiest fix.

trouble retrieving an email from an username from a text document

so I have this website that allows me to get the email from a user that has signed up to the website, so when you sign up it adds your discord username and your email after it in a text file like this
Discorduser#0182 Test#example.com
Discordusernumber_one#0182 Testboi#example.co.uk
However, it retrieves the email from the first line when i put in the first option, but if i do the 2nd user, it cant seem to find it, here is the code to the website... the code is part of a bottle.py script but here is the main parts of this page
#get('/get_confirm')
def confirm():
return CONFIRM_PAGE
#post('/get_confirm')
def confirm():
name = request.forms.get('name')
for line in open('Confirmations.txt', 'r').readlines():
login_info = line.replace('\n', '').split()
if name == login_info[0]:
return CONFIRM_PAGE.replace('''<h1 id='emailbox'></h1>''', '<h1>' + login_info[1] + '</h1>')
else:
return CONFIRM_PAGE.replace('''<h1 id='emailbox'></h1>''', '<h1>' + 'That user is not valid' + '</h1>')
CONFIRM_PAGE = '''
<!DOCTYPE html>
<html>
<head>
<link rel="icon" href="/static/icon.ico">
<title>TylerR - get_confirms</title>
<style>
.content {
background: white;
padding: 15px;
border-radius: 3px;
}
ul {
list-style-type: none;
margin: 0;
padding: 0;
overflow: hidden;
background-color: #333;
}
li {
float: left;
}
li a, .dropbtn {
display: inline-block;
color: white;
text-align: center;
padding: 14px 16px;
text-decoration: none;
}
li a:hover, .dropdown:hover .dropbtn {
background-color: red;
}
li.dropdown {
display: inline-block;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #f9f9f9;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
}
.dropdown-content a {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
text-align: left;
}
.dropdown-content a:hover {background-color: #f1f1f1}
.dropdown:hover .dropdown-content {
display: block;
}
</style>
</head>
<body style='background-size: cover; background-image: url(\"/static/WebisteBackground.png\"); background-attachment: fixed;'>
<ul>
<li><a href='/'>Home</a></li>
<li><a href='/commands'>Commands</a></li>
<li><a href='/youtube'>Youtube</a></li>
<li><a href='/downloads'>Downloads</a></li>
<a href='https://www.youtube.com/channel/UCTHnGh3DpDXMyuL03ove1tQ'>
<img align='right' src='/static/youtubelogo.png' style="width:40px;height:40px;">
</a>
<a href='https://www.instagram.com/drumsnaps/'>
<img align='right' src='/static/Insta.png' style="width:40px;height:40px;">
</a>
</ul>
</div>
<center>
<h1 style="font-family:Cooper Black; font-size: 7em;"><b>Confirmations<b></h1>
<br>
<h1>Please enter an username to retrieve email</h1>
<h3>When entering name, replace any spaces with _</h3>
<form method='POST' action='/get_confirm'>
<h2>Discord Username:</h2>
<input name='name' type='text' placeholder='User#0000'>
<br>
<input type='submit'>
</form>
<div class='content'>
<h1 id='emailbox'></h1>
</div>
</center>
</body>
</html>
'''
I am using bottle.py
so if anyone could let me know why this is happening that would be great
In your check it returns immediately - with success (if user is on the first line) or no success (if user is not on first line). You want to return no success, only after you checked all lines.
#post('/get_confirm')
def confirm():
name = request.forms.get('name')
with open('Confirmations.txt', 'r') as f:
for line in f:
user, email = line.strip().split()
if name == user:
return CONFIRM_PAGE.replace('''<h1 id='emailbox'></h1>''', '<h1>' + email + '</h1>')
return CONFIRM_PAGE.replace('''<h1 id='emailbox'></h1>''', '<h1>' + 'That user is not valid' + '</h1>')
Also, better use template engine like jinja2 to construct the HTML page.

How to remove padding inside QTabWidget tabs?

As you can see from the image there is a border around the text editor inside the QTabWidget.
I set the stylesheet like this:
tab.setStyleSheet("QTabWidget::pane { margin: 0px 0px 0px 0px; padding: 0px; border: 1px solid black; } QTabBar::tab { margin: 0px 0px 0px 0px; padding: 0px; border: 1px solid black; } QTabBar::tab:selected { background-color: #349117; }")
If I set margin negative, it helps but then things look a bit out of place and also I don't want to hard code values that might only work on my system but not others.
Here is the code:
import os, sys
from PySide2 import QtGui, QtCore, QtWidgets, QtWebEngineWidgets, QtWebChannel
# monaco editor index html file
file = "./index.html"
tab = QtWidgets.QTabWidget()
bgcolor = tab.palette().color(QtGui.QPalette.Background)
editor = QtWebEngineWidgets.QWebEngineView()
editor.load(QtCore.QUrl.fromLocalFile(file))
tab.setStyleSheet("QTabWidget::pane { margin: 0px 0px 0px 0px; padding: 0px; border: 1px solid black; } QTabBar::tab { margin: 0px 0px 0px 0px; padding: 0px; border: 1px solid black; } QTabBar::tab:selected { background-color: #349117; }")
tab.addTab(editor, "python1")
tab.show()
The border seems to come from the HTML page shown.
Here is the HTML code:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
</head>
<body>
<div id="container" style="min-height: calc(100vh - 40px); margin: 0; padding: 0; box-sizing: border-box; border: 0px"></div>
<script src="monaco-editor/min/vs/loader.js"></script>
<script>
require.config({ paths: { 'vs': 'monaco-editor/min/vs' }});
require(['vs/editor/editor.main'], function() {
var editor = monaco.editor.create(document.getElementById('container'), {
value: [
'function x() {',
'\tconsole.log("Hello world!");',
'}'
].join('\n'),
language: 'python',
fontFamily:"Verdana",
fontSize: "20px",
lineNumbers: "on",
roundedSelection: false,
scrollBeyondLastLine: true,
readOnly: false,
formatOnPaste: true,
insertSpaces: true,
automaticLayout: true,
theme: "vs-dark"
});
});
</script>
</body>
</html>
That padding is generated in HTML and can be removed using css:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
</head>
<style >
#container {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
</style>
<body>
<div id="container"></div>
<script src="monaco-editor/min/vs/loader.js"></script>
<script>
require.config({ paths: { 'vs': 'monaco-editor/min/vs' }});
require(['vs/editor/editor.main'], function() {
var editor = monaco.editor.create(document.getElementById('container'), {
value: [
'function x() {',
'\tconsole.log("Hello world!");',
'}'
].join('\n'),
language: 'python',
fontFamily:"Verdana",
fontSize: "20px",
lineNumbers: "on",
roundedSelection: false,
scrollBeyondLastLine: true,
readOnly: false,
formatOnPaste: true,
insertSpaces: true,
automaticLayout: true,
theme: "vs-dark"
});
});
</script>
</body>
</html>

Error getting web.py to render html page that calls a css file

Ok so I have the web.py file called app.py.
app.py references index.html and foo.html.
Both of these html files call just fine, what I mean is when I run app.py and go to http://localhost:8080/ and http://localhost:8080/Foo both of them display a webpage just fine, the issue is with the foo.html file tho. I have a large section in there that is supposed to use the rotate.css file and make the text in the section spin. The problem is the text doesn't even show up.
Files are below:
app.py
import web
urls = (
'/', 'Index',
'/Foo', 'Foo'
)
app = web.application(urls, globals())
render = web.template.render('templates/')
class Index(object):
def GET(self):
greeting_Index = "Hello World"
return render.index(greeting = greeting_Index)
class Foo(object):
def GET(self):
greeting_Foo = 'FooBAR'
return render.foo(greeting = greeting_Foo)
if __name__ == "__main__":
app.run()
foo.html
$def with (greeting)
$var cssfiles: static/rotate.css
<html>
<head>
<meta charset="UTF-8">
<title>Foobar</title>
</head>
<body>
$if greeting:
<em style="color: red; font-size: 5em;">Welcome to the Foo bar. $greeting.</em>
$else:
Herro world!
<section class="rw-wrapper">
<h2 class="rw-sentence">
<span>Real poetry is like</span>
<span>creating</span>
<div class="rw-words rw-words-1">
<span>breathtaking moments</span>
<span>lovely sounds</span>
<span>incredible magic</span>
<span>unseen experiences</span>
<span>happy feelings</span>
<span>beautiful butterflies</span>
</div>
<br />
<span>with a silent touch of</span>
<div class="rw-words rw-words-2">
<span>sugar</span>
<span>spice</span>
<span>colors</span>
<span>happiness</span>
<span>wonder</span>
<span>happiness</span>
</div>
</h2>
</section>
</body>
</html>
rotate.css
.rw-wrapper{
width: 80%;
position: relative;
margin: 110px auto 0 auto;
font-family: 'Bree Serif';
padding: 10px;
}
.rw-sentence{
margin: 0;
text-align: left;
text-shadow: 1px 1px 1px rgba(255,255,255,0.8);
}
.rw-sentence span{
color: #444;
white-space: nowrap;
font-size: 200%;
font-weight: normal;
}
.rw-words{
display: inline;
text-indent: 10px;
}
.rw-words span{
position: absolute;
opacity: 0;
overflow: hidden;
width: 100%;
color: #6b969d;
}
.rw-words-1 span{
animation: rotateWordsFirst 18s linear infinite 0s;
}
.rw-words-2 span{
animation: rotateWordsSecond 18s linear infinite 0s;
}
.rw-words span:nth-child(2){
animation-delay: 3s;
color: #6b889d;
}
.rw-words span:nth-child(3){
animation-delay: 6s;
color: #6b739d;
}
.rw-words span:nth-child(4){
animation-delay: 9s;
color: #7a6b9d;
}
.rw-words span:nth-child(5){
animation-delay: 12s;
color: #8d6b9d;
}
.rw-words span:nth-child(6){
animation-delay: 15s;
color: #9b6b9d;
}
#keyframes rotateWordsFirst {
0% { opacity: 1; animation-timing-function: ease-in; height: 0px; }
8% { opacity: 1; height: 60px; }
19% { opacity: 1; height: 60px; }
25% { opacity: 0; height: 60px; }
100% { opacity: 0; }
}
#keyframes rotateWordsSecond {
0% { opacity: 1; animation-timing-function: ease-in; width: 0px; }
10% { opacity: 0.3; width: 0px; }
20% { opacity: 1; width: 100%; }
27% { opacity: 0; width: 100%; }
100% { opacity: 0; }
}
According to http://webpy.org/cookbook/staticfiles you may have to alter your apache.conf file to allow apache to serve up those files.
And I did notice that nowhere in your html file do you actually link to the css file
<link rel="stylesheet" href="static/rotate.css" type="text/css">
somewhere in the head is missing or since your using it as a variable it should be
<link rel="stylesheet" href="$cssfiles" type="text/css">

Categories

Resources