I'm trying to make an automated task that (1) collects CSV data about wildfires from the internet, (2) reads its contents to see where wildfires in the CSV have occurred in the past 3 days, (3) visualizes them on a map, (4) and sends an email to a specific alias, with text and a map about where they have occurred.
In the email (4), I want to mention the locations of wildfires, which are in the form of a string:
print(provinces_on_fire_str)
Out[0]: "Province1, Province2"
I used Content-ID to add an image to the e-mail body, using the following code:
# set the plaintext body
msg.set_content('This is a plain text body.')
# create content-ID for the image
image_cid = make_msgid()
# alternative HTML body
msg.add_alternative("""\
<html>
<body>
<p>This e-mail contains information about fires reported in the past 3 days.<br>
The VIIRS sensor has reported wildfires in the following provinces: {provinces_on_fire_str}
This e-mail was sent automatically.
</p>
<img src="cid:{image_cid}">
</body>
</html>
""".format(image_cid=image_cid[1:-1]), subtype="html")
# attach image to mail
with open(f"path/toimage/{today}.png", 'rb') as img:
maintype, subtype = mimetypes.guess_type(img.name)[0].split("/")
msg.get_payload()[1].add_related(img.read(),
maintype=maintype,
subtype=subtype,
cid=image_cid)
This returns an error, implying no such object as "provinces_on_fire_str" exists for the HTML code. Without the "provinces_on_fire_str" variable in the HTML body, the expected output email is the following (albeit this lacks the text explanation of where they occurred):
Now, the obvious thing that came to my mind is to convert the HTML body part to an f-string, so I can add the "Province1, Province2" values to the e-mail text. But adding f before the e-mail string breaks the image_cid (though the Province1, Province2 values are included in the ultimate e-mail).
.add_alternative with f-string input:
# alternative HTML body
msg.add_alternative(f"""\
<html>
<body>
<p>This e-mail contains information about fires reported in the past 3 days.<br>
The VIIRS sensor has reported wildfires in the following provinces: {provinces_on_fire_str}
This e-mail was sent automatically.
</p>
<img src="cid:{image_cid}">
</body>
</html>
""".format(image_cid=image_cid[1:-1]), subtype="html")
Output email:
How do I pass the string values of provinces_on_fire_str into the HTML code without breaking the image_cid?
Consider a simpler example:
foo = 1
bar = 2
print('{foo} == {bar}'.format(foo=foo+1))
It does not work, because bar is not looked up automatically. The .format method of strings is just a method; it does not do any magic. It does not know about the caller's local variables foo and bar; it must be passed all the information that should be used. Of course, because we are passing it information explicitly, we can make modifications.
We can solve the error by simply including the missing argument:
foo = 1
bar = 2
print('{foo} == {bar}'.format(foo=foo+1, bar=bar))
f-strings are magic, or rather, syntactic sugar. They are translated into an equivalent .format call at compile time. They are not a different kind of string; after the compile-time translation, a perfectly ordinary string has a perfectly ordinary .format method called upon it.
If we do
foo = 1
bar = 2
print(f'{foo+1} == {bar}')
then that is already equivalent to the fixed .format version. We can use expressions in the {} placeholders, not just variable names. Notice that this already does the work; we should not have an explicit .format call on the result.
If we have just
foo = 1
bar = 2
print(f'{foo} == {bar}')
then of course we lose the modification of the foo value. If you want to use a modified foo in the formatted output, then either describe the modification in the f-string, or else modify the variable beforehand.
Translating that to the original code, we can either do:
msg.add_alternative(f"""\
<html>
<body>
<p>This e-mail contains information about fires reported in the past 3 days.<br>
The VIIRS sensor has reported wildfires in the following provinces: {provinces_on_fire_str}
This e-mail was sent automatically.
</p>
<img src="cid:{image_cid[1:-1]}">
</body>
</html>
""")
or:
image_cid = image_cid[1:-1]
msg.add_alternative(f"""\
<html>
<body>
<p>This e-mail contains information about fires reported in the past 3 days.<br>
The VIIRS sensor has reported wildfires in the following provinces: {provinces_on_fire_str}
This e-mail was sent automatically.
</p>
<img src="cid:{image_cid}">
</body>
</html>
""")
Related
I have a Python variable whose value is a string of text and would like to edit that value via Javascript.
I have no idea how to go about doing this.
Attempts:
function changeValue(val) {
val = 'new text';
}
<textarea placeholder="some text">{{ changeValue({{ result }}) }}</textarea>
<textarea placeholder="some text">
{{ result }}
</textarea>
What I want: I have some text (result) being added and would like to check if the text is empty. If so, I want to show the placeholder text.
The issue: Although I can check if the value is empty, when I try to print that result out it reads none
Thanks to all!
You do not need to call the JavaScript function from the HTML file. There are several approaches you can take:
1. Store the variable in HTML metadata:
<meta id="result_var" data-result={{result}}>
And then get the data in JavaScript:
result = document.getElementById("result_var").value;
2. Keep the variable in the tag where it's supposed to be and get it from there in JavaScript:
<textarea placeholder="some text" id="result-var"> {{result}} </textarea>
And then get it in JavaScript:
let result = document.getElementById("result-var");
3. Query it from your API: You can create a route in your Flask app that returns JSON data with the variable you need and then get that data to your JavaScript file by sending a request to your API.
4. Jinja format: I've seen solutions that involve just using the variable as if it was a jinja variable in JavaScript like this: let result = JSON.parse('{{ result | tojson }}');. But I haven't been able to get this working properly, not sure why.
I hope this helps!
I am trying to make a basic outlook email template for one of my tasks at work. The goal is to be able to run a script and provide a number to the program such that I can generate repetitive blocks of code for releasing materials in our warehouse. I have figured out how to draft the email (need manual inputs so using mail.save to make a draft), but I am struggling to come up with a way to populate x blocks of code for the name/tracking/item/lot/containers potion of the HTML body (used // to denote the repetitive block). I think I will probably need to remove the r""" """ bit and use quotes so that a function can be used in the middle of the HTMLbody, but I'm not sure. Here is the current code I have:
import win32com.client as win32
import os
outlook = win32.Dispatch('outlook.application')
mail = outlook.CreateItem(0)
# SEND TO
mail.To = 'Email here'
# SUBJECT
mail.Subject = 'Subject here'
# MESSAGE BODY
mail.HTMLBody = r"""
The following stuff is ready: <br><br>
<b>Name</b><br> //This is the block of code I want to repeat X times.
Tracking #/ WO #: <br>
Item #: <br>
Lot #: <br>
X containers <br><br> //This is the end of the repeatable block
Best regards, <br><br>
<p style="font-family: Arial; font-size: 10pt"><b>My Name</b><br>
Title<br>
Company<br>
D: phone number here<br>
fakeEmail#somedomain.com<br>
www.fakesite.com<br></p>
"""
mail.Save()
I originally tried to do something like this with the body portion, which I imagine is closer to what I will need:
mail.HTMLBody = (
"text here"
class call here for repetitive block
"text here to finish signature"
)
Would this approach work better for my goal?
Sounds like you need to build an HTML string based on the data from an external source. The MailItem.HTMLBody property returns or sets a string representing the HTML body of the specified item. The HTMLBody property should be an HTML syntax string, that means the string should represent a well formed HTML document.
I am trying to design and implement a basic calculator in HTML and Python(using CGI). Below given is a static HTML web page and it is being redirected to a python script (calci.py) where, I am able to calculate the sum but unable to append the resultant to the 'output' textbox.
calculator.html
<html>
<head>
<title>Calculator</title>
</head>
<body>
<form action="python_scripts/calci.py" method="post">
Input 1 : <input type="text" name="input1"/><br>
Input 2 : <input type="text" name="input2"/><br>
<input type="submit" value="+" title="add" /><br>
output : <input type="text" name="output"/><br>
</form>
</body>
</html>
calci.py
import cgi
form = cgi.FieldStorage()
input1 = form.getvalue('input1')
input2 = form.getvalue('input2')
output = str(int(input1)+int(input2))
#how to return the response to the html
#and append it to the textbox
Thanks
This is not the way Web applications work - not hat simply, at least.
If you want to rely only on the browser, and plain HTML for your application, each request has to send the whole html page as a string. You have to use Python's string formatting capabilities to put the resulting number in the correct place in the HTML form.
This way of working is typical of "Web 1.0" applications (as opposed to the "Web 2.0" term used about ten years ago).
Modern web applications use logic that runs on the client side, in Javascript code, to make an HTTP request to retrieve only the needed data - and them, this client-side logic would place your result in the proper place in the page, without reloading the page. This is what isgenerally known as "ajax". It is not that complex, but the html + javascript side of the application become much more complex.
I think one should really understand the "Web 1.0" way before doing it the "Ajax way". in your case, let's suppose your HTML containing the calculator form is in a file called "calc.html". Inside it, where the result should lie, put a markup that can be understood by Python's built-in native string formatting methods, like {result} -
<html>
<body>
...
calculator body
...
Answer: <input type="text" readonly="true" value={result} />
</body>
</html>
And rewrite your code like:
import cgi
form = cgi.FieldStorage()
input1 = form.getvalue('input1')
input2 = form.getvalue('input2')
result = int(input1)+int(input2)
html = open("calc.html".read())
header = "Content-Type: text/html; charset=UTF-8\n\n"
output = header + html.format(result=result)
print (output)
The CGI way is outdated, but is nice for learning: it relies on your whole program being run, and whatever it prints to the standard output to be redirected to the HTTP request as a response. That includes the HTTP Headers, which are included, in a minimal form, above.
(I will leave the complete implementation of a way for the raw '{result}' string not to show up in the inital calculator form as an exercise from where you are 0- the path is to get the initial calculator html template through a CGI script as well, instead of statically, (maybe the same) as well - and just populate "result" with "0" or an empty string)
you can transfer response with the help of java script.
use under print("window.location=url")
I am trying to create a corpus of data from a set of .html pages I have stored in a directory.
These HTML pages have lots of info I don't need.
This info is all stored before the line
<div class="channel">
How can I programmatically remove all of the text before
<div class="channel">
in every HTML file in a folder?
Bonus question for a 50point bounty :
How do I programmatically remove everything AFTER, for example,
<div class="footer">
?
So if my index.html was previously :
<head>
<title>This is bad HTML</title>
</head>
<body>
<h1> Remove me</h1>
<div class="channel">
<h1> This is the good data, keep me</h1>
<p> Keep this text </p>
</div>
<div class="footer">
<h1> Remove me, I am pointless</h1>
</div>
</body>
After my script runs, I want it to be :
<div class="channel">
<h1> This is the good data, keep me</h1>
<p> Keep this text </p>
</div>
This is a bit heavy on memory usage, but it works. Basically you open up the directory, get all ".html" files, read them into a variable, find the split point, store the before or after in a variable, and then overwrite the file.
There are probably better ways to do this, nonetheless, but it works.
import os
dir = os.listdir(".")
files = []
for file in dir:
if file[-5:] == '.html':
files.insert(0, file)
for fileName in files:
file = open(fileName)
content = file.read()
file.close()
loc = content.find('<div class="channel">')
newContent = content[loc:]
file = open(fileName, 'w')
file.write(newContent)
file.close()
If you wanted to just keep up to a point:
newContent = content[0:loc - 1] # I think the -1 is needed, not sure
Note that the things you're searching should be kept in a variable, and not hardcoded.
Also, this won't work recursively for file/folder structures, but you can find out how to modify it to do that very easily.
to remove everything above and everything below
that means the only thing left should be this section:
<div class="channel">
<h1> This is the good data, keep me</h1>
<p> Keep this text </p>
</div>
rather than thinking to remove the unwanted, it would be easier to just extract the wanted.
you can easily extract channel div using XML parser such as DOM
You've not mentioned a language in the question - the post is tagged with python so this answer might still be out of context, but I'll give a php solution that could likely easily be rewritten in another language.
$html='....'; // your page
$search='<div class="channel">';
$components = explode($search,$html); // [0 => before the string, 1 => after the string]
$result = $search.$components[1];
return $result;
To do the reverse is fairly easy too; simply take the value of $components[0] after altering $search to your <div class="footer"> value.
If you happen to have the $search string cropping up multiple times:
$html='....'; // your page
$search='<div class="channel">';
$components = explode($search,$html); // [0 => before the string, 1 => after the string]
unset($components[0]);
$result = $search.implode($search,$components);
return $result;
Someone who knows python better than I do feel free to rewrite and take the answer!
How do I insert a variable into an HTML email I'm sending with python? The variable I'm trying to send is code. Below is what I have so far.
text = "We Says Thanks!"
html = """\
<html>
<head></head>
<body>
<p>Thank you for being a loyal customer.<br>
Here is your unique code to unlock exclusive content:<br>
<br><br><h1><% print code %></h1><br>
<img src="http://example.com/footer.jpg">
</p>
</body>
</html>
"""
Use "formatstring".format:
code = "We Says Thanks!"
html = """\
<html>
<head></head>
<body>
<p>Thank you for being a loyal customer.<br>
Here is your unique code to unlock exclusive content:<br>
<br><br><h1>{code}</h1><br>
<img src="http://example.com/footer.jpg">
</p>
</body>
</html>
""".format(code=code)
If you find yourself substituting a large number of variables, you can use
.format(**locals())
Another way is to use Templates:
>>> from string import Template
>>> html = '''\
<html>
<head></head>
<body>
<p>Thank you for being a loyal customer.<br>
Here is your unique code to unlock exclusive content:<br>
<br><br><h1>$code</h1><br>
<img src="http://example.com/footer.jpg">
</p>
</body>
</html>
'''
>>> s = Template(html).safe_substitute(code="We Says Thanks!")
>>> print(s)
<html>
<head></head>
<body>
<p>Thank you for being a loyal customer.<br>
Here is your unique code to unlock exclusive content:<br>
<br><br><h1>We Says Thanks!</h1><br>
<img src="http://example.com/footer.jpg">
</p>
</body>
</html>
Note, that I used safe_substitute, not substitute, as if there is a placeholder which is not in the dictionary provided, substitute will raise ValueError: Invalid placeholder in string. The same problem is with string formatting.
use pythons string manipulation:
http://docs.python.org/2/library/stdtypes.html#string-formatting
generally the % operator is used to put a variable into a string, %i for integers, %s for strings and %f for floats,
NB: there is also another formatting type (.format) which is also described in the above link, that allows you to pass in a dict or list slightly more elegant than what I show below, this may be what you should go for in the long run as the % operator gets confusing if you have 100 variables you want to put into a string, though the use of dicts (my last example) kinda negates this.
code_str = "super duper heading"
html = "<h1>%s</h1>" % code_str
# <h1>super duper heading</h1>
code_nr = 42
html = "<h1>%i</h1>" % code_nr
# <h1>42</h1>
html = "<h1>%s %i</h1>" % (code_str, code_nr)
# <h1>super duper heading 42</h1>
html = "%(my_str)s %(my_nr)d" % {"my_str": code_str, "my_nr": code_nr}
# <h1>super duper heading 42</h1>
this is very basic and only work with primitive types, if you want to be able to store dicts, lists and possible objects I suggest you use cobvert them to jsons http://docs.python.org/2/library/json.html and https://stackoverflow.com/questions/4759634/python-json-tutorial are good sources of inspiration
Hope this helps