Related
I have implement simple app in flask. I can get data and process it also but how can I get random created folder. In this app, I tried to input some data to text area. When export deck button clicked then the data post to flask. I can get data and generate deck also but unable send generated deck file or redirect to the random folder.
I get the following error.
raise TypeError(
TypeError: The view function did not return a valid response. The function either returned None or ended without a return statement.)
So, How can I implement this? Redirect to new random generated folder or send the generated file as download link.
Thanks
app.py
from flask import Flask, render_template, request, redirect, url_for, flash, send_file, send_from_directory
import image_occ_deck_export
import random, os
app = Flask(__name__)
app.config["CACHE_TYPE"] = "null"
#app.route("/", methods=["GET","POST"])
def home():
if request.method == "POST":
print(request.form['notes'])
notes = request.form['notes']
# random folder
data = request.form['notes']
print(data)
random_f = random.randrange(1 << 30, 1 << 31)
create_random_folder(random_f, data)
else:
return render_template("index.html")
def create_random_folder(random_f, data):
directory = str(random_f)
parent_dir = "static/uploads/"
path = os.path.join(parent_dir, directory)
if not os.path.exists(path):
os.mkdir(path)
random_file = directory + ".txt"
random_deck_name = directory + ".apkg"
file_loc = path + "/" + random_file
deck_loc = path + "/" + random_deck_name
with open(file_loc, 'w') as f:
f.write(str(data))
image_occ_deck_export.exportDeck(file_loc, deck_loc)
return redirect(url_for('uploaded', path=path))
#app.route('/uploaded/<path>', methods=['GET'])
def uploaded():
return render_template("upload.html")
if __name__ == "__main__":
app.run(debug=False)
index.js
function export() {
var textToExport = document.getElementById("noteData").value;
var formData = new FormData();
formData.append("notes", textToExport);
var request = new XMLHttpRequest();
request.open("POST", "/");
request.send(formData);
}
index.html
<html>
<textarea id="noteData"></textarea>
<button onclick="export()">Export Deck</button>
</html>
sample input
cordova-img-occ-note-1602529000819 <img src='art-1851483_640.jpg'></img> <img src='cordova-img-occ-ques-1602529000819.svg'></img> <img src='cordova-img-occ-ans-1602529000819.svg'></img> <img src='cordova-img-occ-orig-1602529000819.svg'></img>
cordova-img-occ-note-1602529001248 <img src='art-1851483_640.jpg'></img> <img src='cordova-img-occ-ques-1602529001248.svg'></img> <img src='cordova-img-occ-ans-1602529001248.svg'></img> <img src='cordova-img-occ-orig-1602529000819.svg'></img>
cordova-img-occ-note-1602529001673 <img src='art-1851483_640.jpg'></img> <img src='cordova-img-occ-ques-1602529001673.svg'></img> <img src='cordova-img-occ-ans-1602529001673.svg'></img> <img src='cordova-img-occ-orig-1602529000819.svg'></img>
image_occ_deck_export.py
The file use to generate anki deck from txt
import random
import genanki
import csv
import traceback
anki_deck_title = "learn"
anki_model_name = "image occ"
model_id = random.randrange(1 << 30, 1 << 31)
def exportDeck(data_filename, deck_filename):
try:
# front side
front = """
{{#Image}}
<div id="io-header">{{Header}}</div>
<div id="io-wrapper">
<div id="io-overlay">{{Question Mask}}</div>
<div id="io-original">{{Image}}</div>
</div>
<div id="io-footer">{{Footer}}</div>
<script>
// Prevent original image from loading before mask
aFade = 50, qFade = 0;
var mask = document.querySelector('#io-overlay>img');
function loaded() {
var original = document.querySelector('#io-original');
original.style.visibility = "visible";
}
if (mask === null || mask.complete) {
loaded();
} else {
mask.addEventListener('load', loaded);
}
</script>
{{/Image}}
"""
style = """
/* GENERAL CARD STYLE */
.card {
font-family: "Helvetica LT Std", Helvetica, Arial, Sans;
font-size: 150%;
text-align: center;
color: black;
background-color: white;
}
/* OCCLUSION CSS START - don't edit this */
#io-overlay {
position:absolute;
top:0;
width:100%;
z-index:3
}
#io-original {
position:relative;
top:0;
width:100%;
z-index:2;
visibility: hidden;
}
#io-wrapper {
position:relative;
width: 100%;
}
/* OCCLUSION CSS END */
/* OTHER STYLES */
#io-header{
font-size: 1.1em;
margin-bottom: 0.2em;
}
#io-footer{
max-width: 80%;
margin-left: auto;
margin-right: auto;
margin-top: 0.8em;
font-style: italic;
}
#io-extra-wrapper{
/* the wrapper is needed to center the
left-aligned blocks below it */
width: 80%;
margin-left: auto;
margin-right: auto;
margin-top: 0.5em;
}
#io-extra{
text-align:center;
display: inline-block;
}
.io-extra-entry{
margin-top: 0.8em;
font-size: 0.9em;
text-align:left;
}
.io-field-descr{
margin-bottom: 0.2em;
font-weight: bold;
font-size: 1em;
}
#io-revl-btn {
font-size: 0.5em;
}
/* ADJUSTMENTS FOR MOBILE DEVICES */
.mobile .card, .mobile #content {
font-size: 120%;
margin: 0;
}
.mobile #io-extra-wrapper {
width: 95%;
}
.mobile #io-revl-btn {
font-size: 0.8em;
}
"""
# back side
back = """
{{#Image}}
<div id="io-header">{{Header}}</div>
<div id="io-wrapper">
<div id="io-overlay">{{Answer Mask}}</div>
<div id="io-original">{{Image}}</div>
</div>
{{#Footer}}<div id="io-footer">{{Footer}}</div>{{/Footer}}
<button id="io-revl-btn" onclick="toggle();">Toggle Masks</button>
<div id="io-extra-wrapper">
<div id="io-extra">
{{#Remarks}}
<div class="io-extra-entry">
<div class="io-field-descr">Remarks</div>{{Remarks}}
</div>
{{/Remarks}}
{{#Sources}}
<div class="io-extra-entry">
<div class="io-field-descr">Sources</div>{{Sources}}
</div>
{{/Sources}}
{{#Extra 1}}
<div class="io-extra-entry">
<div class="io-field-descr">Extra 1</div>{{Extra 1}}
</div>
{{/Extra 1}}
{{#Extra 2}}
<div class="io-extra-entry">
<div class="io-field-descr">Extra 2</div>{{Extra 2}}
</div>
{{/Extra 2}}
</div>
</div>
<script>
// Toggle answer mask on clicking the image
var toggle = function() {
var amask = document.getElementById('io-overlay');
if (amask.style.display === 'block' || amask.style.display === '')
amask.style.display = 'none';
else
amask.style.display = 'block'
}
// Prevent original image from loading before mask
aFade = 50, qFade = 0;
var mask = document.querySelector('#io-overlay>img');
function loaded() {
var original = document.querySelector('#io-original');
original.style.visibility = "visible";
}
if (mask === null || mask.complete) {
loaded();
} else {
mask.addEventListener('load', loaded);
}
</script>
{{/Image}}
"""
# print(self.fields)
anki_model = genanki.Model(
model_id,
anki_model_name,
fields=[{"name": "id"},{"name": "Header"}, {"name": "Image"}, {"name": "Question Mask"}, {"name": "Footer"}, {"name": "Remarks"}, {"name": "Sources"}, {"name": "Extra 1"}, {"name": "Extra 2"}, {"name": "Answer Mask"}, {"name": "Original"}],
templates=[
{
"name": "Card 1",
"qfmt": front,
"afmt": back,
},
],
css=style,
)
anki_notes = []
with open(data_filename, "r", encoding="utf-8") as csv_file:
csv_reader = csv.reader(csv_file, delimiter="\t")
for row in csv_reader:
flds = []
for i in range(len(row)):
flds.append(row[i])
anki_note = genanki.Note(
model=anki_model,
fields=flds,
)
anki_notes.append(anki_note)
random.shuffle(anki_notes)
anki_deck = genanki.Deck(model_id, anki_deck_title)
anki_package = genanki.Package(anki_deck)
for anki_note in anki_notes:
anki_deck.add_note(anki_note)
anki_package.write_to_file(deck_filename)
print("Deck generated with {} flashcards".format(
len(anki_deck.notes)))
except Exception:
traceback.print_exc()
create_random_folder() returns a redirect, but when you call it from your home() request handler, you don’t do anything with the returned value and you don’t return a response in that code branch of your home() handler. It seems you intend to return that redirect from your home() handler like so:
return create_random_folder(random_f, data)
Remember, when you return a value from a function, you’re returning the value to the calling code, not to the browser. If you call a function from a request handler and receive a return value, that doesn’t automatically get sent back to the browser; you need to return it from the request handler.
I am reading an xlsx & creating a html while applying some style using jinja2
import pandas
import jinja2
df = pandas.read_excel('C:\\Users...\\2020.xlsx', 'TEST',
usecols = 'A:J')
pandas.set_option('precision', 2)
df_dropna = df.dropna(how = 'all')
df_fillna = df_dropna.fillna('')
#html = df_fillna.to_html(index=0,header=False,border=0)
def highlight(val):
if (val in ('USERID','Name')) :
return 'background-color: yellow'
else:
return 'background-color: white'
styler = (df_fillna.style.applymap(highlight))
# Template handling
env = jinja2.Environment(loader=jinja2.FileSystemLoader(searchpath=''))
template = env.get_template('template2.html')
outputText = template.render(my_table=styler.render())
html_file = open('trial.html', 'w')
html_file.write(outputText)
html_file.close()
Code works perfectly fine, except that I am not able to get rid of header & index. Anything that can help remove index & header? Please help!
See below image
Solution was not in Pyhton code, but I had to put it in my template for css
below is the code to hide index & header
table td.first { display: none;}
When calling render method overrid head parameter with empty list.
https://pandas.pydata.org/docs/reference/api/pandas.io.formats.style.Styler.render.html
Something like:
render(head=[]))
Adding this to the style.css in the Table settings worked for me.
th:nth-of-type(1){ display: none; }
table { margin-bottom: 0em; width:100%;}
th { font-weight: bold; text-align: center;}
thead th { background: #c3d9ff; }
th:nth-of-type(1){ display: none; }
th,td,caption { padding: 4px 5px 4px 5px; }
I can't change the size of the code at https://codepen.io/sinanelms/pen/MqdNNY. Would you like to help the map grow and shrink according to the size of the screen?
I worked on the following but could not do what I wanted.
<style type="text/css">
body{
background:#fff;}
#map{
width:1050px;
height:620px;
position:relative;}
#map svg {
position: relative;top:
-100px;
left: 0px;}
svg > a {cursor: pointer;display:block;}
#sehir{font-size:30px;text-align:center;margin-top:25px;color:#666;}
</style>
<div>
</div>
<div id="sehir"></div>
<div id="map"></div>
use Jquery window resize to set width and height with setViewBox and setSize. have a look into below code with window resize.
JS
var w = 1000, h=500;
var r = Raphael('map', w, h),
attributes = {
fill: '#666',
stroke: '#fff',
'stroke-width':.5,
'stroke-linejoin': 'round',
},
arr = new Array();
r.setViewBox(10, 100, w,h,true);
r.setSize('100%', '100%');
$(window).resize(function(){
r.setViewBox(10,100,w,h,true);
r.setSize('100%', '100%');
});
CSS
#map {
position: relative;
border: 1px solid red;
}
#map svg {
position: relative;
}
svg>a {
cursor: pointer;
display: block;
}
while you initiate Raphael with id map pass width in %.
Below its initiated with width 100% and height 800px.
var r = Raphael('map', '100%', '800'),
also remove width & height from inline css with #map
#map{
width:1050px;
height:620px;
position:relative;
}
I'm building a pyqt5 desktop interface where I'm using QWebEngineView to show a html file where I show a Leaflet map. This is working fine.
The next step is to export all features the user added to the map. When I click on "Export Features" on the map nothing happen, but when I open the same html file on my Chromium web browser, the "Export feature" opens the download dialog fine.
PyQt5 script:
self.MainWindow.webMapViewer = QtWebEngineWidgets.QWebEngineView()
self.MainWindow.webPageLayout.addWidget(self.MainWindow.webMapViewer)
self.html_path = os.path.split(os.path.abspath(__file__))[0] + r'/html/test.html'
self.MainWindow.webMapViewer.load(QtCore.QUrl().fromLocalFile(self.html_path))
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no' />
<title>FazMaraneyRGB_transparent_mosaic_group1</title>
<!-- Leaflet -->
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.5/leaflet.css" />
<script src="http://cdn.leafletjs.com/leaflet-0.7.5/leaflet.js"></script>
<!-- Leaflet.draw -->
<link rel="stylesheet" href="https://unpkg.com/leaflet-draw#0.4.1/dist/leaflet.draw.css" />
<script src="https://unpkg.com/leaflet-draw#0.4.1/dist/leaflet.draw.js"></script>
<!-- Leaflet Ajax -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet-ajax/2.1.0/leaflet.ajax.min.js"></script>
<!-- Leaflet Measument -->
<link rel="stylesheet" href="http://ljagis.github.io/leaflet-measure/leaflet-measure.css" />
<script src="http://ljagis.github.io/leaflet-measure/leaflet-measure.min.js"></script>
<style>
body { margin:0; padding:0; }
body, table, tr, td, th, div, h1, h2, input { font-family: "Calibri", "Trebuchet MS", "Ubuntu", Serif; font-size: 11pt; }
#map { position:absolute; top:0; bottom:0; width:100%; } /* full size */
.ctl {
padding: 2px 10px 2px 10px;
background: white;
background: rgba(255,255,255,0.9);
box-shadow: 0 0 15px rgba(0,0,0,0.2);
border-radius: 5px;
text-align: right;
}
.title {
font-size: 18pt;
font-weight: bold;
}
.src {
font-size: 10pt;
}
#delete, #export {
position: absolute;
top:100px;
right:10px;
z-index:100;
background:white;
color:black;
padding:6px;
border-radius:4px;
font-family: 'Helvetica Neue';
cursor: pointer;
font-size:12px;
text-decoration:none;
}
#export {
top:130px;
}
</style>
</head>
<body>
<div id='map'></div>
<div id='delete'>Delete Features</div>
<a href='#' id='export'>Export Features</a>
<script>
/* **** Leaflet **** */
// Base layers
// .. OpenStreetMap
var osm = L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {attribution: '© OpenStreetMap contributors'});
// .. White background
var white = L.tileLayer("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEAAQMAAABmvDolAAAAA1BMVEX///+nxBvIAAAAH0lEQVQYGe3BAQ0AAADCIPunfg43YAAAAAAAAAAA5wIhAAAB9aK9BAAAAABJRU5ErkJggg==");
// Overlay layers (TMS)
var lyr1 = L.tileLayer('./tiles/{z}/{x}/{y}.png', {tms: true, maxZoom: 22, opacity: 0.9, attribution: ""});
// Map
var map = L.map('map', {
measureControl: true,
center: [-18.3604868606589, -52.694255477616245],
zoom: 22,
minZoom: 0,
maxZoom: 22,
layers: [osm]
});
lyr1.addTo(map);
//Geojson Layers
var basemaps = {"OpenStreetMap": osm, "Without background": white}
var overlaymaps = {"Layer 1": lyr1}
// Title
var title = L.control();
title.onAdd = function(map) {
this._div = L.DomUtil.create('div', 'ctl title');
this.update();
return this._div;
};
title.update = function(props) {
this._div.innerHTML = "FazMaraneyRGB_transparent_mosaic_group1";
};
title.addTo(map);
// Note
var src = 'Generated by Hawkit';
var title = L.control({position: 'bottomleft'});
title.onAdd = function(map) {
this._div = L.DomUtil.create('div', 'ctl src');
this.update();
return this._div;
};
title.update = function(props) {
this._div.innerHTML = src;
};
title.addTo(map);
var featureGroup = L.featureGroup().addTo(map);
var drawControl = new L.Control.Draw({
edit: {
featureGroup: featureGroup
}
}).addTo(map);
map.on('draw:created', function(e) {
// Each time a feaute is created, it's added to the over arching feature group
featureGroup.addLayer(e.layer);
});
// on click, clear all layers
document.getElementById('delete').onclick = function(e) {
featureGroup.clearLayers();
}
document.getElementById('export').onclick = function(e) {
// Extract GeoJson from featureGroup
var data = featureGroup.toGeoJSON();
// Stringify the GeoJson
var convertedData = 'text/json;charset=utf-8,' + encodeURIComponent(JSON.stringify(data));
// Create export
document.getElementById('export').setAttribute('href', 'data:' + convertedData);
document.getElementById('export').setAttribute('download','data.geojson');
}
// Add base layers
L.control.layers(basemaps, overlaymaps, {collapsed: true}).addTo(map);
// Fit to overlay bounds (SW and NE points with (lat, lon))
map.fitBounds([[-18.36827062251916, -52.6871074784942], [-18.35270287637126, -52.7014028427423]]);
</script>
</body>
</html>
That popup window is generated by the browser, in the case of QWebEngine we must create it. To start, the signal indicating the download must be detected, and this signal is downloadRequested from the QWebEngineProfile. That signal sends us a QWebEngineDownloadItem object that handles the download, in it we create a dialog window with the help of QFileDialog. For this case we will create a custom QWebEnginePage as shown below:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no' />
<title>FazMaraneyRGB_transparent_mosaic_group1</title>
<!-- Leaflet -->
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.5/leaflet.css" />
<script src="http://cdn.leafletjs.com/leaflet-0.7.5/leaflet.js"></script>
<!-- Leaflet.draw -->
<link rel="stylesheet" href="https://unpkg.com/leaflet-draw#0.4.1/dist/leaflet.draw.css" />
<script src="https://unpkg.com/leaflet-draw#0.4.1/dist/leaflet.draw.js"></script>
<!-- Leaflet Ajax -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet-ajax/2.1.0/leaflet.ajax.min.js"></script>
<!-- Leaflet Measument -->
<link rel="stylesheet" href="http://ljagis.github.io/leaflet-measure/leaflet-measure.css" />
<script src="http://ljagis.github.io/leaflet-measure/leaflet-measure.min.js"></script>
<style>
body {
margin: 0;
padding: 0;
}
body,
table,
tr,
td,
th,
div,
h1,
h2,
input {
font-family: "Calibri", "Trebuchet MS", "Ubuntu", Serif;
font-size: 11pt;
}
#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
/* full size */
.ctl {
padding: 2px 10px 2px 10px;
background: white;
background: rgba(255, 255, 255, 0.9);
box-shadow: 0 0 15px rgba(0, 0, 0, 0.2);
border-radius: 5px;
text-align: right;
}
.title {
font-size: 18pt;
font-weight: bold;
}
.src {
font-size: 10pt;
}
#delete,
#export {
position: absolute;
top: 100px;
right: 10px;
z-index: 100;
background: white;
color: black;
padding: 6px;
border-radius: 4px;
font-family: 'Helvetica Neue';
cursor: pointer;
font-size: 12px;
text-decoration: none;
}
#export {
top: 130px;
}
</style>
</head>
<body>
<div id='map'></div>
<div id='delete'>Delete Features</div>
<a href='#' id='export'>Export Features</a>
<script>
/* **** Leaflet **** */
// Base layers
// .. OpenStreetMap
var osm = L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors'
});
// .. White background
var white = L.tileLayer("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEAAQMAAABmvDolAAAAA1BMVEX///+nxBvIAAAAH0lEQVQYGe3BAQ0AAADCIPunfg43YAAAAAAAAAAA5wIhAAAB9aK9BAAAAABJRU5ErkJggg==");
// Overlay layers (TMS)
var lyr1 = L.tileLayer('./tiles/{z}/{x}/{y}.png', {
tms: true,
maxZoom: 22,
opacity: 0.9,
attribution: ""
});
// Map
var map = L.map('map', {
measureControl: true,
center: [-18.3604868606589, -52.694255477616245],
zoom: 22,
minZoom: 0,
maxZoom: 22,
layers: [osm]
});
lyr1.addTo(map);
//Geojson Layers
var basemaps = {
"OpenStreetMap": osm,
"Without background": white
}
var overlaymaps = {
"Layer 1": lyr1
}
// Title
var title = L.control();
title.onAdd = function(map) {
this._div = L.DomUtil.create('div', 'ctl title');
this.update();
return this._div;
};
title.update = function(props) {
this._div.innerHTML = "FazMaraneyRGB_transparent_mosaic_group1";
};
title.addTo(map);
// Note
var src = 'Generated by Hawkit';
var title = L.control({
position: 'bottomleft'
});
title.onAdd = function(map) {
this._div = L.DomUtil.create('div', 'ctl src');
this.update();
return this._div;
};
title.update = function(props) {
this._div.innerHTML = src;
};
title.addTo(map);
var featureGroup = L.featureGroup().addTo(map);
var drawControl = new L.Control.Draw({
edit: {
featureGroup: featureGroup
}
}).addTo(map);
map.on('draw:created', function(e) {
// Each time a feaute is created, it's added to the over arching feature group
featureGroup.addLayer(e.layer);
});
// on click, clear all layers
document.getElementById('delete').onclick = function(e) {
featureGroup.clearLayers();
}
document.getElementById('export').onclick = function(e) {
// Extract GeoJson from featureGroup
var data = featureGroup.toGeoJSON();
// Stringify the GeoJson
var convertedData = 'text/json;charset=utf-8,' + encodeURIComponent(JSON.stringify(data));
// Create export
document.getElementById('export').setAttribute('href', 'data:' + convertedData);
document.getElementById('export').setAttribute('download', 'data.geojson');
}
// Add base layers
L.control.layers(basemaps, overlaymaps, {
collapsed: true
}).addTo(map);
// Fit to overlay bounds (SW and NE points with (lat, lon))
map.fitBounds([
[-18.36827062251916, -52.6871074784942],
[-18.35270287637126, -52.7014028427423]
]);
</script>
</body>
</html>
main.py
from PyQt5 import QtWebEngineWidgets, QtWidgets, QtCore
class WebEnginePage(QtWebEngineWidgets.QWebEnginePage):
def __init__(self, *args, **kwargs):
QtWebEngineWidgets.QWebEnginePage.__init__(self, *args, **kwargs)
self.profile().downloadRequested.connect(self.on_downloadRequested)
#QtCore.pyqtSlot(QtWebEngineWidgets.QWebEngineDownloadItem)
def on_downloadRequested(self, download):
old_path = download.path()
suffix = QtCore.QFileInfo(old_path).suffix()
path, _ = QtWidgets.QFileDialog.getSaveFileName(self.view(), "Save File", old_path, "*."+suffix)
if path:
download.setPath(path)
download.accept()
if __name__ == '__main__':
import sys
sys.argv.append("--remote-debugging-port=8000")
sys.argv.append("--disable-web-security")
app = QtWidgets.QApplication(sys.argv)
view = QtWebEngineWidgets.QWebEngineView()
page = WebEnginePage(view)
view.setPage(page)
path = QtCore.QDir.current().filePath("index.html")
view.load(QtCore.QUrl.fromLocalFile(path))
view.show()
sys.exit(app.exec_())
In your case:
self.MainWindow.webMapViewer = QtWebEngineWidgets.QWebEngineView()
self.MainWindow.webPageLayout.addWidget(self.MainWindow.webMapViewer)
page = WebEnginePage(self.MainWindow.webMapViewer) # create page
self.MainWindow.webMapViewer.setPage(page) # set page
self.html_path = os.path.split(os.path.abspath(__file__))[0] + r'/html/test.html'
self.MainWindow.webMapViewer.load(QtCore.QUrl().fromLocalFile(self.html_path))
Plus:
If you want to set a defined route use the following:
#QtCore.pyqtSlot(QtWebEngineWidgets.QWebEngineDownloadItem)
def on_downloadRequested(self, download):
directory = "/path/of/directory"
filename = QtCore.QFileInfo(download.path()).fileName()
download.setPath(QtCore.QDir(directory).filePath(filename))
download.accept()
I don't have any idea about html. Some how i got code to convert csv to html.
Below is code:
import sys
import csv
# Open the CSV file for reading
def populate_table(csv_fl):
reader = csv.reader(open(csv_fl))
# Create the HTML file for output
html_table = ''
# initialize rownum variable
rownum = 0
# write <table> tag
html_table= '<table>\n'
# generate table contents
for row in reader: # Read a single row from the CSV file
# write header row. assumes first row in csv contains header
if rownum == 0:
html_table += '<tr>\n' # write <tr> tag
for column in row:
html_table += '<th>' + column + '</th>\n'
html_table += '</tr>\n'
#write all other rows
else:
html_table += '<tr>\n'
for column in row:
if 'fail' in column or 'Fail' in column:
html_table += "<td style='color:red'>" + column + '</td>\n'
continue
html_table += '<td>' + column + '</td>\n'
html_table += '</tr>\n'
#increment row count
rownum += 1
# write </table> tag
html_table += '</table>\n'
return html_table
Above code if string contains Fail or fail it will make red color cell.
I need help here to make full line in red color (Not single cell).
Below is code to fill html (Indent is wrong. If need correct indent code i will share in link ).
I will excute below code like below:
python2.7 fil.py test.csv test.html
import csv2html
import sys
class Sketch:
def __init__(self):
"""
Returns html sketch for a defined scenario
Scenarios asccessible as functions.
supported ones are:
-fail
-pass
-status_update
-final
"""
def _style (self):
body = """
<style>
p {
font-family : Calibri;
font-size: 14px;
font-weight: bolder;
text-align : left;
}
p.fade {
color : #CCCCCC;
font-size: 14px;
}
em {
font-style : italic ;
font-size : 16px;
font-weight: lighter ;
}
em.pass {
font-style : italic ;
font-size : 16px;
color: green ;
}
em.fail {
font-style : italic ;
font-size : 16px;
color: red ;
}
a {
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
hr {
align: left ;
margin-left: 0px ;
width: 500px;
height:1px;
}
table {
border-collapse: collapse;
}
tr {
padding: 4px;
text-align: center;
border-right:2px solid #FFFFFF;
}
tr:nth-child(even){background-color: #f2f2f2}
th {
background-color: #cceeff;
color: black;
padding: 4px;
border-right:2px solid #FFFFFF;
}
</style>
"""
return body
def _start(self):
return """
<!DOCTYPE html>
<html>
"""
def _end(self):
body ="""
<hr/>
<p class="fade">Note: Link might be disabled,
please put me in safe sender list, by right
click on message.
This is a system generated mail, please don't
respond to it.</p>
</html>
"""
return body
def _fail (self):
body = """
<p>STATUS :
<em class="fail">failed</em>
</p>
"""
return body
def _critical_fail(self):
str_ = 'Failure is critical, terminating the run.'
body = """
<p>
<em class="fail">%s</em>
</p>
"""%str_
return body
def _pass (self):
body = """
<p>STATUS :
<em class="pass">passed</em>
</p>
"""
return body
def _type (self, title, val):
body = """
<p>%s :
<em>%s</em>
</p>
"""%(title.upper(), val)
return body
def _loglink(self, logs):
body = """ <p> LOGS :</p>
<a href=%s>%s</a>
"""%(logs,logs)
return body
def render (self, test_id, descr, platform=None, pass_=True, \
logs=None, critical=False):
body = self._start() +\
self._style() + \
self._type("test id", test_id) + \
self._type("description", descr) +\
self._type("platform", platform)
if pass_==True:
body += self._pass ()
else:
body += self._fail ()
if critical:
body += self._critical_fail()
body += self._loglink(logs)
body += self._end()
return body
def status_update (self, ):
pass
def final (self, logs):
body += self._end()
return body
def add_html_header (csv_fl, fname):
""" html data returned by sqlite needs to be enclosed in
some of the mandatory tags for the web to parse it
properly. ! """
sketch =Sketch()
content ="""
%s %s
<body>
%s
</body>
</html>
"""%(sketch._start(), sketch._style(), csv2html.populate_table(csv_fl))
open (fname, 'w').write (content)
if len(sys.argv) < 3:
print "Usage: csvToTable.py csv_file html_file"
exit(1)
csv_fl = sys.argv[1]
html_fl = sys.argv[2]
add_html_header(csv_fl, html_fl)
To color the whole row in red, simply
<tr style="color:red"> where <tr> is the row you want to color.
p {
font-family: Calibri;
font-size: 14px;
font-weight: bolder;
text-align: left;
}
p.fade {
color: #CCCCCC;
font-size: 14px;
}
em {
font-style: italic;
font-size: 16px;
font-weight: lighter;
}
em.pass {
font-style: italic;
font-size: 16px;
color: green;
}
em.fail {
font-style: italic;
font-size: 16px;
color: red;
}
a {
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
hr {
align: left;
margin-left: 0px;
width: 500px;
height: 1px;
}
table {
border-collapse: collapse;
}
tr {
padding: 4px;
text-align: center;
border-right: 2px solid #FFFFFF;
}
tr:nth-child(even) {
background-color: #f2f2f2
}
th {
background-color: #cceeff;
color: black;
padding: 4px;
border-right: 2px solid #FFFFFF;
}
<table>
<tr>
<th>AAA</th>
<th>BBB</th>
</tr>
<tr>
<td>CCC</td>
<td>DDD</td>
</tr>
<tr style="color:red"> <!-- Here -->
<td>EEE</td>
<td>FFF</td>
</tr>
<tr>
<td>GGG</td>
<td>HHH</td>
</tr>
</table>