How to remove margins from PDF? (Generated using WeasyPrint) - python

I am trying to render a PDF document within my Flask application. For this, I am using the following HTML template:
<!DOCTYPE html>
<html>
<head>
<style>
#page {
margin:0
}
h1 {
color:white;
}
.header{
background: #0a0045;
height: 250px;
}
.center {
position: relative;
top: 50%;
left: 50%;
-ms-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
text-align:center;
}
</style>
</head>
<body>
<div class="header">
<div class="center">
<h1>Name</h1>
</div>
</div>
</body>
</html>
I keep getting white margins at the top and right/left of my header section:
Is there a way to remove them?
Edit:
Below is the code used to generate the PDF file using WeasyPrint in my Flask app:
def generate_pdf(id):
element = Element.query.filter_by(id=id).first()
attri_dict = get_element_attri_dict_for_tpl(element)
html = render_template('element.html', attri_dict=attri_dict)
pdf = HTML(string=html).write_pdf()
destin_loc = app.config['ELEMENTS_FOLDER']
timestamp = dt.datetime.now().strftime('%Y%m%d%H%M%S')
file_name = '_'.join(['new_element', timestamp])
path_to_new_file = destin_loc + '/%s.pdf' % file_name
f = open(path_to_new_file, 'wb')
f.write(pdf)
filename = return_latest_element_path()
return send_from_directory(directory=app.config['ELEMENTS_FOLDER'],
filename=filename,
as_attachment=True)

Maybe you forgot " ; " or/and " mm ",
it works:
#page {
size: A4; /* Change from the default size of A4 */
margin: 0mm; /* Set margin on each page */
}

The weasyprint uses 3 sources of css, one of them is default user agent stylesheet
(https://doc.courtbouillon.org/weasyprint/stable/api_reference.html#supported-features)
That defines:
body {
display: block;
margin: 8px;
}
make sure to override that margin on tag and you will loose the margin.

Related

Importing SVG into HTML

I'm very new to HTML...just started yesterday. The problem I'm having is that when I'm importing an SVG into my HTML script, the text gets all gargled. For example, Peak Metagene Plot becomes 2eak MetaCene 2lot. It's almost like certain letters are changed.
I have made a python script to read in an SVG file like such (I'm calling in two SVGs here, violin and metagene_reads):
# violin
if args['--violin']:
violin_file = open(args['--violin'], 'r')
violin_txt = violin_file.read()
violin_hide = ''
else:
violin_txt = ''
violin_hide = 'hidden'
# metagene reads
if args['--metagene_reads']:
metagene_reads_file = open(args['--metagene_reads'], 'r')
metagene_reads_txt = metagene_reads_file.read()
metagene_reads_hide = ''
else:
metagene_reads_txt = ''
metagene_reads_hide = 'hidden'
I then use this code to feed into an HTML template. Without pasting the entire code, I'll only list the contents that are giving me the weird text:
Specify font type...
<!DOCTYPE html>
<html>
<h1><link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.18/css/jquery.dataTables.css">
<style>
td {
text-align: center;
vertical-align: middle;
}
h1 {
font-size: 36px;
font-weight: bold;
font-family: Georgia, Times, "Times New Roman", serif;
}
h2 {
font-size: 24px;
font-family: Georgia, Times, "Times New Roman", serif;
}
h3 {
margin-bottom: 0px;
padding: 0px;
margin-left: 300px;
font-size: 24px;
font-family: Georgia, Times, "Times New Roman", serif;
}
.initiallyHidden { display: none; }
.toggle {
background-color: #4CAF50;
border: none;
color: white;
padding: 8px 20px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 12px;
margin-bottom: 20px;
}
....other contents like tables, etc.
Below is where I'm importing the SVGs called in from the python script (code shown above). This is where I'm getting the weird formatting issues.
<br>
{{metagene_reads_txt}}
<br>
<h2 {{metagene_peaks_hide}}><center>MultipleMetagene Peaks Plot</center></h2>
<p {{metagene_peaks_hide}}>
<br>
<button class="toggle" onclick="metagenePeaks()">Click to learn more</button>
<div id="metagenePeaksID" class="initiallyHidden">
The multiple metagene peaks plot illustrates the average peak coverage of 5' UTR, CDS, and 3' UTR features.
</div>
<script>
function metagenePeaks() {
var x = document.getElementById("metagenePeaksID");
display = x.style.display;
x.style.display = (display && display !== 'none') ? 'none' : 'block';
}
</script>
<br>
{{metagene_peaks_txt}}
<br>
<h2 {{violin_hide}}><center>Gene Count Violin Plot</center></h2>
<p {{violin_hide}}>
<br>
<button class="toggle" onclick="violinFunction()">Click to learn more</button>
<div id="violinDIV" class="initiallyHidden">
The violin plot illustrates the distribution of gene counts for each sample. The gene counts were normalized for differences in library depth and log transformed.
</div>
<script>
function violinFunction() {
var x = document.getElementById("violinDIV");
display = x.style.display;
x.style.display = (display && display !== 'none') ? 'none' : 'block';
}
</script>
<br>
{{violin_txt}}
<br>
</p>
</body>
</html>
Any help would be greatly appreciated.
What you are doing right now is taking SVG content, something like this:
<svg version="1.1"
baseProfile="full"
width="300" height="200"
xmlns="http://www.w3.org/2000/svg">
<rect width="100%" height="100%" fill="black" />
<circle cx="150" cy="100" r="90" fill="blue" />
</svg>
And just copy+pasting that into the HTML, which the browser does not understand.
Instead, you should be linking to the SVG file using something like this (although depending on how this is hosted the relative path may need to be adjusted):
<img src="{{violin_file}}">
If you really want to embed it within the code (which I generally do not recommend), you can Base64 Encode it and embed that, something like this:
import base64
with open(violin_file, "rb") as image_file:
violin_base64 = str(base64.b64encode(image_file.read()),'utf-8')
And then instead of {{violin_txt}} you would do:
<img src="data:image/svg+xml;base64,{{violin_base64}}" />

Rendering multiple pandas html tables side-by-side

I have produced individual html tables showing work orders from multiple departments , and a running count rendered in the header of how many are orders are 'Completed' out of the 'Total' number of orders in that department. This all works fine, but I cannot find a way, clever or otherwise, to render these tables side by side on an html page. I can't have the tables on top of one another because the page will be appear static on a large monitor through a raspberry pi, so scrolling isn't an option.
pd.set_option('colheader_justify', 'center') # FOR TABLE <th>
table1 = CNC.to_html(classes='mystyle', na_rep='', index = False)
status1 = f"{C10} of {Total10} Completed"
html_string = f'''
<html>
<head><title>HTML Pandas Dataframe with CSS</title></head>
<link rel="stylesheet" type="text/css" href="df_style.css"/>
<body>
<h1 style="border:2px solid DodgerBlue;font-size:35px;text-align:center"> C N C </h1>
<h1 style="background-color:MediumSeaGreen;font-family:verdana;font-size:40px;text-align:center"> {status1} </h1>
{table1}
<script>setInterval(() => location.reload(), 60000);</script>
</body>
</html>.
'''
with open("CNC.html", mode = 'w') as f:
f.write(html_string.format(table=CNC.to_html(classes='mystyle', na_rep='', index = False)))
CSS
.mystyle {
font-size: 15pt;
font-family: Arial;
border-collapse: collapse;
border: 1px solid silver;
}
.mystyle td, th {
padding: 10px;
}
.mystyle tr:nth-child(even) {
background: #E0E0E0;
}
.mystyle tr:hover {
background: silver;
cursor: pointer;
}
.mystyle {
margin: auto;
padding: 0;
}
.mystyle {
text-align: center;
width: 100%;
}
Rendered CNC html table
This obviously creates and renders only a single table on an html page
It would be great if there was some CSS magic I could use so that I could just apply that stylesheet to each department's html.

Django filter local folders

I have a templatetag function that returns a Collapse menu with all folders, subfolders and images in a root directory but now I want to be able to filter which folders I get, the templatetag function recives one parameter, the root directory, and I know it should recibe a second parameter with the folder I want to get but I'm confused in this part.
in my settings.py I have this:
STATICFILES_DIRS = [
BASE_DIR / 'static',
'D:/Users/my_user/Documents/Luis/results',
]
in my templatetag.py I have this:
from django import template
from django.utils.safestring import mark_safe
import os
register = template.Library()
#register.simple_tag
def my_tag(path):
html=''
for file in os.listdir(path):
rel = os.path.join(path, file)
if os.path.isdir(rel):
html += f"""<button type="button" class="collapsible">{file}</button>"""
html +='<div class="content"><div class="row mt-2">'
html += my_tag(rel)
html += '</div></div>'
else:
html +=f'<div class="col-md-6 d-flex align-items-stretch"><picture>'
x=str(rel)[43:]
print(x)
html += """<img src="/static"""+"""/%s" """%(x)
html += """ class="lazy card-img-top" width="500" height="400" """
html += """alt="/static"""+"""/%s" """%(x)
html +='></picture></div>'
return mark_safe(html)
and in my template.html I have this:
{% load static files %}
<style>
.collapsible {
background-color: #F8F8F8;
color: #858E9B;
cursor: pointer;
padding: 18px;
width: 100%;
border: none;
text-align: left;
outline: none;
font-size: 15px;
}
/* .active, .collapsible:hover {
background-color: #555;
}*/
.content {
padding: 0 18px;
display: none;
overflow: hidden;
background-color: #F8F8F8;
}.card-img-top {
height: 90vh !important;
object-fit: contain;
}
</style>
{% my_tag 'D:/Users/my_user/Documents/Luis/results' %}
<script>
var coll = document.getElementsByClassName("collapsible");
var i;
for (i = 0; i < coll.length; i++) {
coll[i].addEventListener("click", function() {
this.classList.toggle("active");
var content = this.nextElementSibling;
if (content.style.display === "block") {
content.style.display = "none";
} else {
content.style.display = "block";
}
});
}
</script>
This is an example of the final result:
So the idea is to get a specific day, can anyone give me an idea?

use textarea for python input() to Skulpt

i want to use a textarea whenever the Python input() function is run in Skulpt. The default is to use an alert box - i want to use a textarea instead.
i've tried to get this working, but nothing happens when i try this example:
https://github.com/skulpt/skulpt/issues/685
everything else works fine as i want it. please help! :D
<!DOCTYPE html>
<html lang="en">
<head>
<script src="js/jquery-3.2.1.min.js" type="text/javascript"></script>
<script src="js/debugger.js" type="text/javascript"></script>
<script src="js/skulpt.min.js" type="text/javascript"></script>
<script src="js/skulpt-stdlib.js" type="text/javascript"></script>
<title>i dont like the alert boxes</title>
<style type="text/css" media="screen">
#source{
position: relative;
width: 500px;
height: 300px;
}
#console{
position: relative;
width: 500px;
height: 100px;
overflow: scroll;
}
body{
background-color: whitesmoke;
}
#turtleCanvas{
position: relative;
border: 1px;
border-color: firebrick;
border-collapse: collapse;
border-style: solid;
width: 500px;
}
</style>
<script src="js/brython/brython.js" type="text/javascript"></script>
</head>
<body onload="brython()">
<script type="text/javascript">
function outf(text) {
var mypre = document.getElementById("console");
mypre.innerHTML = mypre.innerHTML + text;
}
function builtinRead(x) {
if (Sk.builtinFiles === undefined || Sk.builtinFiles["files"][x] === undefined)
throw "File not found: '" + x + "'";
return Sk.builtinFiles["files"][x];
}
function runit() {
var editor = ace.edit("source");
var code = editor.getValue();
document.getElementById("hiddenCode").innerHTML = code;
var prog = document.getElementById("hiddenCode").value;
var mypre = document.getElementById("console");
mypre.innerHTML = '';
Sk.pre = "console";
Sk.configure({output:outf, read:builtinRead});
(Sk.TurtleGraphics || (Sk.TurtleGraphics = {})).target = 'turtleCanvas';
var myPromise = Sk.misceval.asyncToPromise(function() {
return Sk.importMainWithBody("<stdin>", false, prog, true);
});
myPromise.then(function(mod) {
console.log('success');
},
function(err) {
console.log(err.toString());
});
}
</script>
<textarea id="hiddenCode" style="display:none;"></textarea><br />
<div id="source">import turtle
myName = input("who r u?")
print(myName)
t = turtle.Turtle()
t.forward(100)</div>
<button type="button" onclick="runit()">Run</button>
<textarea id="programInputField">some input lines</textarea>
<pre id="console">output</pre>
<div id="turtleCanvas"></div>
<script src="js/ace/src-noconflict/ace.js" type="text/javascript" charset="utf-8"></script>
<script>
var window1 = ace.edit("source");
var window2 = ace.edit("console");
window1.setTheme("ace/theme/textmate");
window2.setTheme("ace/theme/twilight");
window1.getSession().setMode("ace/mode/python");
</script>
</body>
Never mind!!!! This worked perfectly, just had to change the id of my text area, otherwise i just copied and pasted it and commented out my own sk.configure line..... brilliant, thankyou whoever you are!!!!!!! :D :D :D :D
Wait for an event to occur within a function in Javascript for Skulpt

Pass Returned Data From Python to JavaScript?

As I'm developing one chat bot for booking bus tickets I get request from user manually and returned response based on user request from API I did almost but I have doubt while passing returned data from Python to JavaScript using my IP address. Please anyone help me.
Here is my py:
import requests,json
import requests, json
from flask import render_template
import os
import time
from flask import render_template, Flask, request
from chatterbot.trainers import ListTrainer
from chatterbot import ChatBot
# # import win32api
#
# win32api.MessageBox(0, 'hello', 'title')
app = Flask(__name__)
#app.route('/',methods=['GET','POST'])
def map():
return render_template("sara.html")
#app.route('/run',methods=['GET','POST'])
def main():
print("run")
url = 'http://webapi.i2space.co.in/Buses/Sources'
payload = {'some': 'data'}
headers = {'consumerkey': 'D0106432CD19C98E0E8267EDFE9E3DF0', 'consumersecret': '43DEC493EBAE756BF7A2312F55FE5132'}
r = requests.get(url, data=json.dumps(payload), headers=headers)
print(r.text)
# response_data = r.json()
response_data = json.loads(r.text)
# print(type(response_data))
# s=(response_data[0]['Name'])
# print(s)
sorceid=request.args.get('sid')
print(sorceid)
l=''
for a in response_data:
print("hello")
print(a)
print(a['Name'])
if (sorceid==a['Name']):
l=a['Id']
print(l)
break
else:
print("no")
# list={"iden":l}
# print(list)
return render_template("sara.html",l=l)
if __name__ == '__main__':
app.run(host='192.168.1.80')
Here is my JavaScript:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="/static/style.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
</head>
<body>
<h1> HERE COMES!!!</h1>
{{ l }}
<div class="w3-container w3-teal" align="center" style="width: 50%">
<span>Bus-Bot</span>
</div>
<div class="w3-container" align="center" style="width: 50%">
<div id="chatbox">
<p class="botText"> Bus-Bot:<span>Hi! I'm Bus-Bot.</span></p>
</div>
<div id="userInput">
<input id="textInput" type="text" name="msg">
<input id="buttonInput" type="submit" value="submit" >
</div>
<script>
function getBotResponse() {
var rawText = $("#textInput").val();
var userHtml = '<div id="Chatid" class="container">'+
'<p class="userText" >ME:<span>' + rawText + '</span></p>'+'</div>';
$("#chatbox").append(userHtml);
document.getElementById('userInput').scrollIntoView({block: 'start', behavior: 'smooth'});
$.get("run", { msg: rawText }).done(function (data) {
alert(data);
var sou=data.l;
alert(sou);
alert(lol);
var botHtml = '<div id="botcon" class="container darker">'+'<p class="botText">Bus-Bot:<span>' + sou + '</span></p>'+'</div>';
console.log(botHtml);
$("#botcon").append(botHtml);
document.getElementById('userInput').scrollIntoView({block: 'start', behavior: 'smooth'});
});
}
$("#textInput").keypress(function(e) {
if(e.which == 13) {
getBotResponse();
}
});$("#lolInput").keypress(function(e) {
if(e.which == 13) {
alert('weldone');
getBotResponse();
}
});
$("#buttonInput").click(function() {
getBotResponse();
})
</script>
<style>
.container {
border: 2px solid #dedede;
background-color: #f1f1f1;
border-radius: 5px;
padding: 10px;
margin: 10px 0;
}
/* Darker chat container */
.darker {
border-color: #ccc;
background-color: #ddd;
}
/* Clear floats */
.container::after {
content: "";
clear: both;
display: table;
}
/* Style images */
.container img {
float: left;
max-width: 60px;
width: 100%;
margin-right: 20px;
border-radius: 50%;
}
/* Style the right image */
.container img.right {
float: right;
margin-left: 20px;
margin-right:0;
}
/* Style time text */
.time-right {
float: right;
color: #aaa;
}
/* Style time text */
.time-left {
float: left;
color: #999;
}
</style>
</div>
</div>
</body>
</html>
From Python I returned response using variable name "l" but I don't know how to pass this variable to JavaScript I want to get my response below to this line
var botHtml = '<div id="botcon" class="container darker">'+'<p class="botText">Bus-Bot:<span>' + sou + '</span></p>'+'</div>';
The render_template function from Flask doesn't pass any variable from one language to the other. It just replaces strings inside the html-template that it finds with a variable that you handover to it. With
return render_template("sara.html",l=l)
you are telling the program to take the sara.html template and insert your variable l anywhere where it finds {{ l }} in the template. You should see it in the actual HTML that you are sending to the client. because you are inserting it under your heading:
<h1> HERE COMES!!!</h1>
{{ l }}
It is really more helpful if you are using it to render pure HTML and not JavaScript. Of cause you can also replace things inside your JavaScript but that is really not a sensible way to do client-server communication. If you want communication between your client and server you should think about a different architecture.
Doing the get call
url = 'http://webapi.i2space.co.in/Buses/Sources'
payload = {'some': 'data'}
headers = {'consumerkey': 'D0106432CD19C98E0E8267EDFE9E3DF0', 'consumersecret': '43DEC493EBAE756BF7A2312F55FE5132'}
r = requests.get(url, data=json.dumps(payload), headers=headers)
inside your server is probably better kept in your client-side Javascript.

Categories

Resources