Send SVG image content to email as HTML using boto3
I want to send SVG content (without saved file) as HTML to Outlook email address. This SVG content works fine in browser showing a circle image, however sending it via boto3.client to Outlook email results in empty mail. Why? Any suggestions appreciated.
import io
import json
import boto3
from botocore.exceptions import ClientError
SENDER = "Name1 LastName1 <Name1.LastName1@mail.com>"
RECIPIENT = "Name2 LastName2 <Name2.LastName2@mail.com>"
AWS_REGION = "us-east-1"
SUBJECT = "something"
svg = """
<svg width="100" height="100">
<circle cx="50" cy="50" r="40" stroke="green" stroke-width="4" fill="yellow" />
</svg>
"""
BODY_HTML = f"""<html>
<body>
{svg}
</body>
</html>
"""
CHARSET = "UTF-8"
client = boto3.client('ses',region_name=AWS_REGION)
try:
response = client.send_email(
Destination={
'ToAddresses': [
RECIPIENT
],
},
Message={
'Body': {
'Html': {
'Charset': CHARSET,
'Data': BODY_HTML
}
},
'Subject': {
'Charset': CHARSET,
'Data': SUBJECT
},
},
Source=SENDER
)
except ClientError as e:
print(e.response['Error']['Message'])
else:
print("Email sent! Message ID:"),
print(response['MessageId'])
1 answer
-
answered 2022-05-07 19:32
Eugene Astafiev
SVG graphics are widely supported in web browsers but not all email programs know what to do with these new images. In case of Outlook you need to export the file to any image file format like PNG or JPEG and then attach it to the mail item. Then in the message body you can refer to use using a special syntax with a
cid:
prefix. Also you need to set thePR_ATTACH_CONTENT_ID
MAPI property (DASL name "http://schemas.microsoft.com/mapi/proptag/0x3712001F") using theAttachment.PropertyAccessor.SetProperty
method and refer that attachment through thesrc
attribute that matches the value ofPR_ATTACH_CONTENT_ID
set on the attachment.PR_ATTACH_CONTENT_ID
corresponds to theContent-ID
MIME header when the message is sent.attachment = MailItem.Attachments.Add("c:\temp\MyPicture.jpg") attachment.PropertyAccessor.SetProperty("http://schemas.microsoft.com/mapi/proptag/0x3712001F", "YourImageId") MailItem.HTMLBody = "<html><body>Test image <img src=""cid:YourImageId""></body></html>"
do you know?
how many words do you know
See also questions close to this topic
-
Python File Tagging System does not retrieve nested dictionaries in dictionary
I am building a file tagging system using Python. The idea is simple. Given a directory of files (and files within subdirectories), I want to filter them out using a filter input and tag those files with a word or a phrase.
If I got the following contents in my current directory:
data/ budget.xls world_building_budget.txt a.txt b.exe hello_world.dat world_builder.spec
and I execute the following command in the shell:
py -3 tag_tool.py -filter=world -tag="World-Building Tool"
My output will be:
These files were tagged with "World-Building Tool": data/ world_building_budget.txt hello_world.dat world_builder.spec
My current output isn't exactly like this but basically, I am converting all files and files within subdirectories into a single dictionary like this:
def fs_tree_to_dict(path_): file_token = '' for root, dirs, files in os.walk(path_): tree = {d: fs_tree_to_dict(os.path.join(root, d)) for d in dirs} tree.update({f: file_token for f in files}) return tree
Right now, my dictionary looks like this:
key:''
.In the following function, I am turning the empty values
''
into empty lists (to hold my tags):def empty_str_to_list(d): for k,v in d.items(): if v == '': d[k] = [] elif isinstance(v, dict): empty_str_to_list(v)
When I run my entire code, this is my output:
hello_world.dat ['World-Building Tool'] world_builder.spec ['World-Building Tool']
But it does not see
data/world_building_budget.txt
. This is the full dictionary:{'data': {'world_building_budget.txt': []}, 'a.txt': [], 'hello_world.dat': [], 'b.exe': [], 'world_builder.spec': []}
This is my full code:
import os, argparse def fs_tree_to_dict(path_): file_token = '' for root, dirs, files in os.walk(path_): tree = {d: fs_tree_to_dict(os.path.join(root, d)) for d in dirs} tree.update({f: file_token for f in files}) return tree def empty_str_to_list(d): for k, v in d.items(): if v == '': d[k] = [] elif isinstance(v, dict): empty_str_to_list(v) parser = argparse.ArgumentParser(description="Just an example", formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument("--filter", action="store", help="keyword to filter files") parser.add_argument("--tag", action="store", help="a tag phrase to attach to a file") parser.add_argument("--get_tagged", action="store", help="retrieve files matching an existing tag") args = parser.parse_args() filter = args.filter tag = args.tag get_tagged = args.get_tagged current_dir = os.getcwd() files_dict = fs_tree_to_dict(current_dir) empty_str_to_list(files_dict) for k, v in files_dict.items(): if filter in k: if v == []: v.append(tag) print(k, v) elif isinstance(v, dict): empty_str_to_list(v) if get_tagged in v: print(k, v)
-
Actaully i am working on a project and in it, it is showing no module name pip_internal plz help me for the same. I am using pycharm(conda interpreter
File "C:\Users\pjain\AppData\Local\Programs\Python\Python310\lib\runpy.py", line 196, in _run_module_as_main return _run_code(code, main_globals, None, File "C:\Users\pjain\AppData\Local\Programs\Python\Python310\lib\runpy.py", line 86, in _run_code exec(code, run_globals) File "C:\Users\pjain\AppData\Local\Programs\Python\Python310\Scripts\pip.exe\__main__.py", line 4, in <module> File "C:\Users\pjain\AppData\Local\Programs\Python\Python310\lib\site-packages\pip\_internal\__init__.py", line 4, in <module> from pip_internal.utils import _log
I am using pycharm with conda interpreter.
-
Looping the function if the input is not string
I'm new to python (first of all) I have a homework to do a function about checking if an item exists in a dictionary or not.
inventory = {"apple" : 50, "orange" : 50, "pineapple" : 70, "strawberry" : 30} def check_item(): x = input("Enter the fruit's name: ") if not x.isalpha(): print("Error! You need to type the name of the fruit") elif x in inventory: print("Fruit found:", x) print("Inventory available:", inventory[x],"KG") else: print("Fruit not found") check_item()
I want the function to loop again only if the input written is not string. I've tried to type return Under print("Error! You need to type the name of the fruit") but didn't work. Help
-
Creating Sticky Navbar with Drop Down Menu HTML
I am creating a HTML web page which contains a sticky navbar with drop down menu. However, when I created one, the dropdown menu does not works in the sticky navbar and so goes vise versa. below is the screenshot of both the result of the two codes.
*image with dropdown menu but without sticky navbar
*image with sticky navbar but without dropdown menu
below is the code for "image with dropdown menu but without sticky navbar"
<!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font- awesome/4.7.0/css/font-awesome.min.css"> <style> body {margin:0;font-family:Arial} .topnav { overflow: hidden; background-color: #333; } .topnav a { list-style-type: none; float: left; display: block; color: #f2f2f2; text-align: center; padding: 14px 16px; text-decoration: none; font-size: 17px; position: sticky; } .active { background-color: #04AA6D; color: white; } .topnav .icon { display: none; } .dropdown { float: left; overflow: hidden; } .dropdown .dropbtn { font-size: 17px; border: none; outline: none; color: white; padding: 14px 16px; background-color: inherit; font-family: inherit; margin: 0; } .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 { float: none; color: black; padding: 12px 16px; text-decoration: none; display: block; text-align: left; } .topnav a:hover, .dropdown:hover .dropbtn { background-color: #555; color: white; } .dropdown-content a:hover { background-color: #ddd; color: black; } .dropdown:hover .dropdown-content { display: block; } @media screen and (max-width: 600px) { .topnav a:not(:first-child), .dropdown .dropbtn { display: none; } .topnav a.icon { float: right; display: block; } } @media screen and (max-width: 600px) { .topnav.responsive {position: relative;} .topnav.responsive .icon { position: absolute; right: 0; top: 0; } .topnav.responsive a { float: none; display: block; text-align: left; } .topnav.responsive .dropdown {float: none;} .topnav.responsive .dropdown-content {position: relative;} .topnav.responsive .dropdown .dropbtn { display: block; width: 100%; text-align: left; } } </style> </head> <body> <div class="header"> <h2>Scroll Down</h2> <p>Scroll down to see the sticky effect.</p> </div> <div class="topnav" id="myTopnav"> <a href="#home" class="active">Home</a> <a href="#news">News</a> <a href="#contact">Contact</a> <div class="dropdown"> <button class="dropbtn">Dropdown <i class="fa fa-caret-down"></i> </button> <div class="dropdown-content"> <a href="#">Link 1</a> <a href="#">Link 2</a> <a href="#">Link 3</a> </div> </div> <a href="#about">About</a> <a href="javascript:void(0);" style="font-size:15px;" class="icon" onclick="myFunction()">☰</a> </div> <div style="padding-left:16px"> <h2>Responsive Topnav with Dropdown</h2> <p>Resize the browser window to see how it works.</p> <p>Hover over the dropdown button to open the dropdown menu.</p> </div> <h3>Sticky Navigation Bar Example</h3> <p>The navbar will <strong>stick</strong> to the top when you reach its scroll position.</p> <p><strong>Note:</strong> Internet Explorer do not support sticky positioning and Safari requires a -webkit- prefix.</p> <p>Some text to enable scrolling. </p> <p>Some text to enable scrolling. </p> <p>Some text to enable scrolling. </p> <p>Some text to enable scrolling. </p> <p>Some text to enable scrolling. </p> <p>Some text to enable scrolling. </p> <p>Some text to enable scrolling. </p> <p>Some text to enable scrolling. </p> <p>Some text to enable scrolling. </p> <p>Some text to enable scrolling. </p> <p>Some text to enable scrolling. </p> <p>Some text to enable scrolling. </p> <p>Some text to enable scrolling. </p> <p>Some text to enable scrolling. </p> <p>Some text to enable scrolling. </p> <script> function myFunction() { var x = document.getElementById("myTopnav"); if (x.className === "topnav") { x.className += " responsive"; } else { x.className = "topnav"; } } </script> </body> </html>
below is the code for "image with sticky navbar but without dropdown menu"
<!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font- awesome/4.7.0/css/font-awesome.min.css"> <style> body { font-size: 20px; } body {margin:0;} ul { list-style-type: none; margin: 0; padding: 0; overflow: hidden; background-color: #333; position: -webkit-sticky; /* Safari */ position: sticky; top: 0; } li { float: left; } li a { display: block; color: white; text-align: center; padding: 16px 20px; text-decoration: none; } li a:hover { background-color: #111; } /*======================================================================*/ body { background-color:white; } ul { list-style-type: none; margin: 0; padding: 0; overflow: hidden; background-color: #38444d; } 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; } footer { text-align: center; padding: 3px; background-color: DarkSalmon; color: white; } </style> </head> <body> <div class="header"> <h2>Scroll Down</h2> <p>Scroll down to see the sticky effect.</p> </div> <ul> <li><a href="#home">Home</a></li> <li><a href="#news">News</a></li> <li class="dropdown"> <a href="javascript:void(1)" class="dropbtn">Dropdown</a> <div class="dropdown-content"> <a href="#">Link 1</a> <a href="#">Link 2</a> <a href="#">Link 3</a> </div> </li> </ul> <h3>Sticky Navigation Bar Example</h3> <p>The navbar will <strong>stick</strong> to the top when you reach its scroll position.</p> <p><strong>Note:</strong> Internet Explorer do not support sticky positioning and Safari requires a -webkit- prefix.</p> <p>Some text to enable scrolling. </p> <p>Some text to enable scrolling. </p> <p>Some text to enable scrolling. </p> <p>Some text to enable scrolling. </p> <p>Some text to enable scrolling. </p> <p>Some text to enable scrolling. </p> <p>Some text to enable scrolling. </p> <p>Some text to enable scrolling. </p> <p>Some text to enable scrolling. </p> <p>Some text to enable scrolling. </p> <p>Some text to enable scrolling. </p> <p>Some text to enable scrolling. </p> <p>Some text to enable scrolling. </p> <p>Some text to enable scrolling. </p> <p>Some text to enable scrolling. </p> <footer> <p>Author: Hege Refsnes<br> <a href="mailto:hege@example.com">hege@example.com</a></p> </footer> </body> </html>
Please i need some help with this as i am new to html and css.
-
Javascript: Change element class if button has a certain value
<div class="main-div main-div2"> <!-- IF up to date, main-div3 --> <button id="update-btn" class="btn update-btn"> Up to date </button> </div>
I want to make it so if update-btn has a value of "Up to date", change the div class from "main-div main-div2" to "main-div main-div3". Otherwise, if it's any other value, change it to "main-div main-div2"
What kind of loop would be good for this Javascript function too if I want it to be checking constantly?
Thank you.
-
Boostrap vertical sizing with different style width and height
I am trying to set verticaly icon on profile photo card inside div to be in the middle in white box(div), but dont know why it doesnt works. When I use
style="width: 300px; height: 300px;
for div square I can center it on horizontaly, but not verticaly :/ Can someone explain me what I am doing wrong?Anyway is there any way how to resize bootstrap icons except display-1???
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.8.1/font/bootstrap-icons.css"> <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/popper.js@1.12.9/dist/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script> <div class="container-sm offset-md"> <h1 class="p-4 m-4">Nastavení profilu</h1> <div class="row"> <div class="col"> <div class="card p-4 m-4"> Osobní údaje <input type="text" name="name" class="form-control" placeholder="Jméno"> <input type="text" name="surname" class="form-control" placeholder="Příjmení"> <input type="email" name="email" class="form-control" placeholder="E-Mail"> <input type="date" name="name" class="form-control"> </div> </div> <div class="col-4"> <div class="card p-4 m-4 bg-light"> Profilová fotografie <div class=" square text-center border display-1 m-3 bg-white mx-auto"> <i class="bi bi-person-fill align-middle justify-content-center text-secondary"></i> </div> <input type="file" id="customFile" name="file" hidden=""> <div class="text-center"> <button class="btn btn-success" for="customFile">Nahrát</button> <button type="button" class="btn btn-danger">Smazat</button> <p class="text-muted mt-3 mb-0">Poznámka: Minimální velikost 300px x 300px</p> </div> </div> </div> </div> <div class="row"> <div class="col"> <div class="card p-4 m-4"> Změna hesla </div> </div> <div class="col"> <div class="card p-4 m-4"> Zobrazit/skrýt podrobnosti </div> </div> </div> </div>
-
Just 1 icon out of several from my sprite will not show up
Hey guys fairly new to coding so forgive me. I took logos and made a sprite and inserted into my header. Everything works fine except the #chevron, it is the only one not showing up. If I use #quotes instead, the quotes icon shows up fine. I'm assuming it's a file issue but I checked the file and its fine.
Solutions I've tried;
- Remaking the sprite file etc
- Checking the original chevron.svg file (Its completely fine)
-
How do I use an animated SVG for navbar link hover, and position it properly?
I’m building my portfolio and it has a theme as if it's been drawn on paper.
When you hover over a link on my navbar, the SVG animates from underneath, it's an arrow that points to the link and it looks like it's been drawn with a sharpie. I would also like to animation to reverse on mouse out, instead of just disappearing.
The animation works awesomely on hover (by itself), exactly as I want, however I cannot figure out how to make it appear on a navbar link hover instead. Also, I'm unsure how to position it. Currently I have the SVG placed after my
<a>
tags.Here's the code:
div { border: 1px black solid; width: 120px; height: 150px; text-align: center; } #arrowSVG:hover path { animation: nav_arrow 800ms linear 1 normal forwards; } @keyframes nav_arrow { 0%, 100% { stroke-dashoffset: 228.816432; } 60% { stroke-dashoffset: 0; } 100% { stroke-dashoffset: 0; } }
<div> <p> Hover me! </> <svg id="arrowSVG" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 128 128" shape-rendering="geometricPrecision" text-rendering="geometricPrecision"> <path id="eZuEQXWsHpA2" d="M81.33906,95.61239c-2.04913-2.92733-15.33188-23.55344-18.27718-23.9216-2.1176-.2647-6.39806,6.74064-9.13859, 5.64442-1.72253-.68901-.23957-19.37568,1.07513-20.42744.35406-.28324,17.10175,10.91579,16.93327,12.09519-.24773,1.73411-10.42713, 4.21185-12.09519,4.56929-2.16723.46441-8.43321,2.60391-6.45077,1.61269c3.20375-1.60188,6.85172-2.25839,9.67615-4.56929.39226-.32094, 1.55594-1.2354,1.07513-1.07513-.88133.29378-11.28885,4.35372-11.28885,4.30051c0-2.22645,10.47757-5.91321,12.36397-5.91321c1.02153, 0-1.18114-1.93573-2.15025-1.61269-2.93453.97818-11.8009,6.50634-9.94494,4.03173c2.11065-2.81419,10.07996-2.15151,11.02006-4.03173.26335-.5267-10.04599, 1.11958-10.4825.53757-2.04355-2.72474,8.60103-2.59902,8.60103-3.76295c0-1.26705-8.19827,1.07445-8.86981,0-.76572-1.22515,1.75021-2.86552, 2.15026-3.49417.30422-.47805.18968-1.16541.53756-1.61269c1.16554-1.49856,2.42055,6.98982,3.76296,8.33224c4.42514,4.42514,10.96031-4.00183,9.40736,3.76295" fill="none" stroke="#000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" stroke-dashoffset="228.816432" stroke-dasharray="228.816432" /> </div>
- Outlook VSTO - Get all items in a group calendar
-
How to set outlook addins pinned right away?
I set the SupportsPinning to true for outlook addins by modifying the manifest file as shown below. This allows the pin icon available. By default, the Pin is not selected. So is there a way to have the addins PINNED right away?
<!-- Task pane button --> <Control xsi:type="Button" id="msgReadOpenPaneButton"> ...... <Action xsi:type="ShowTaskpane"> <SourceLocation resid="readTaskPaneUrl" /> <SupportsPinning>true</SupportsPinning> </Action> </Control>
-
Load and cache images from AWS S3 into flutter
I want to fetch and cache user profile pictures from S3 into my flutter app.
First, when a user uploads a picture, my flask backend generates a random file name, stores the file in an S3 bucket (using boto3) and the name in the database.
To retrieve the picture I use presigned_urls:
s3client = boto3.client('s3', config=Config(signature_version='s3v4', region_name='eu-west-2')) s3client.generate_presigned_url('get_object',Params={'Bucket': BUCKET,'Key': file_name_retrieved_from_db_for_user},ExpiresIn=120)
In Flutter I have a Future which calls the API and gets the image's generated presigned url (i.e. https://xx.s3.amazonaws.com/FILENAME.jpg?signature).And then using a FutureBuilder I do the following:
FutureBuilder( future: get_picture_url(user_id), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.done) { if (snapshot.data==0) { return Icon(Icons.account_circle, size: 110.0); } print(user_id); print('this is the data fetched'); print(snapshot.data); return CachedNetworkImage( imageUrl: snapshot.data, imageBuilder: (context, imageProvider) => Container( width: 180.0, height: 180.0, decoration: BoxDecoration( shape: BoxShape.circle, image: DecorationImage( image: imageProvider, fit: BoxFit.cover), ), ), placeholder: (context, url) => ProfPicPlaceHolder(), errorWidget: (context, url, error) => Icon(Icons.error), ); } else { return ProfPicPlaceHolder(); } } ),
The problem is that each time the FutureBuilder calls the API to get the image's url, the URL is different due to different signature following the filename in the url, so the same image is loaded and cached again and again.
How can I access an image that is stored in S3 in flask using boto3 and then pass that url to cached network image in flutter? Is there any other way to cache an image in flutter from aws S3?
-
How to download files from S3 to a custom folder or a network path using boto3
Below is the function to download the files from a S3 Bucket. But the problem is I can't find how to direct those files into a network path instead of downloading into the project folder without having any control over where the files must be downloaded.
import boto3 import config import os import win32api def download_all_objects_in_folder(): #= boto3.resource('s3') s3_resource = boto3.resource('s3', aws_access_key_id=config.AWS_BUCKET_KEY, aws_secret_access_key=config.AWS_BUCKET_SECRET_KEY) my_bucket = s3_resource.Bucket(config.BUCKET) # Create the folder logic here objects = my_bucket.objects.filter(Prefix='Export_20181104/') for obj in objects: path, filename = os.path.split(obj.key) my_bucket.download_file(obj.key, filename,"C:\Other") #win32api.MessageBox(0, obj.key, 'title') print("imports completed")
Update: This is the error I am getting when I pass the custom path.
ValueError: Invalid extra_args key 'C', must be one of: ChecksumMode, VersionId, SSECustomerAlgorithm, SSECustomerKey, SSECustomerKeyMD5, RequestPayer, ExpectedBucketOwner