will produce an email with empty body and the image as an attachment.The better way, ie to have the image as part of the body of the email, requires to write an HTML body that refers to that image:import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.image import MIMEImage
msg = MIMEMultipart('alternative')
msg['Subject'] = "subject"
msg['From'] = from_addr
msg['To'] = to_addr
part = MIMEImage(open('/path/to/image', 'rb').read())
s = smtplib.SMTP('localhost')
s.sendmail(from_addr, to_addr, msg.as_string())
s.quit()
The trick is to define an image with a specific Content-ID and make that the only item in an HTML body: now you have an email with contains that specific image as the only content of the body, embedded in it.import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
msg = MIMEMultipart('alternative')
msg['Subject'] = "subject
msg['From'] = from_addr
msg['To'] = to_addr
text = MIMEText('<img src="cid:image1">', 'html')
msg.attach(text)
image = MIMEImage(open('/path/to/image', 'rb').read())
# Define the image's ID as referenced in the HTML body above
image.add_header('Content-ID', '<image1>')
msg.attach(image)
s = smtplib.SMTP('localhost')
s.sendmail(from_addr, to_addr, msg.as_string())
s.quit()
will produce an email with empty body and the image as an attachment.The better way, ie to have the image as part of the body of the email, requires to write an HTML body that refers to that image:import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.image import MIMEImage
msg = MIMEMultipart('alternative')
msg['Subject'] = "subject"
msg['From'] = from_addr
msg['To'] = to_addr
part = MIMEImage(open('/path/to/image', 'rb').read())
s = smtplib.SMTP('localhost')
s.sendmail(from_addr, to_addr, msg.as_string())
s.quit()
The trick is to define an image with a specific Content-ID and make that the only item in an HTML body: now you have an email with contains that specific image as the only content of the body, embedded in it.import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
msg = MIMEMultipart('alternative')
msg['Subject'] = "subject
msg['From'] = from_addr
msg['To'] = to_addr
text = MIMEText('<img src="cid:image1">', 'html')
msg.attach(text)
image = MIMEImage(open('/path/to/image', 'rb').read())
# Define the image's ID as referenced in the HTML body above
image.add_header('Content-ID', '<image1>')
msg.attach(image)
s = smtplib.SMTP('localhost')
s.sendmail(from_addr, to_addr, msg.as_string())
s.quit()
/sbin/lcd_toolbut sometimes it's a bit stubborn in executing the commands, so as mentioned here you may want to killall -9 lcdmond and then issue the command you want; this is the snippet i'm using:
# print a msg on the panelit ain't pretty, but it gets the job done.
killall -9 lcdmond
/sbin/lcd_tool -1 "$LINE1" -2 "$LINE2"
sleep 5
# turn off screen light
killall -9 lcdmond
/sbin/lcd_tool -f
/sbin/pic_raw 80 Beep shortbut they no longer work. So keep looking, i stumbled upon this post, mentioning hal_app, and that indeed works, but with a different syntax than the one presented at that link.In order to use hal_app to make a beep sound, the syntax that worked for me is:
/sbin/pic_raw 81 Beep long
/sbin/hal_app --se_buzzer enc_id=0,mode=XXXIf you remove entirely mode=XXX, it produces a short beep, but here is the list of all the modes available and their results (found out via exhaustive search):
code | output |
---|---|
0 | short beep (0.5 secs) |
1 | long beep (1 sec) |
2 | 3x short beeps (0.5 secs), long pause (1 sec) |
3-7, 10, 15, 16, 17, 18, 19, 20 | 2x long beeps (1 sec), very long pause (2 secs) |
8, 9 | 3x long beeps (1 sec), very long pauses (2 secs) |
12, 13 | long beep, 2x very short pause (0.25) very short beep (0.25) |
14 | 3x very short beep (0.25) very short pause (0.25) |
To create a new apps script, click "New project" from the scripts dashboard: this will open a code editor, so now cut and paste this code (change the label name to match the one you want to use, and the header too if you're going to use this for another team):
function tagPythonTeamEmails()
// search for all recent threads (hours is the smallest interval searchable)
var threads = GmailApp.search("newer_than:1h");
// this is the label i want to apply to the messages
var label = GmailApp.getUserLabelByName("Debian_Python_Pkgs"); // <-- EDIT THIS
for (var i = 0; i < threads.length; i++)
// get all messages in a given thread
var messages = threads[i].getMessages();
// for each message in the thread
for (var j = 0; j < messages.length; j++)
var message = messages[j];
// needed to have access to the full email: headers + body
var email = message.getRawContent();
// this is the header i want to check for: if present, add label and archive
if (email.indexOf("X-Distro-Tracker-Team: python") > -1) // <-- EDIT THIS
threads[i].addLabel(label);
threads[i].moveToArchive();
(This code is largely inspired by this StackOverflow answer.)
Given we're going to perform changes to the emails, we need to add extra permissions to the script; first we need to toggle the option "View > Show manifest file" which will show the appsscript.json file. Once done, edit it and update the scope of the script to include:
"oauthScopes": [
...
"https://www.googleapis.com/auth/gmail.readonly",
"https://www.googleapis.com/auth/gmail.modify"
],
These new permission will be granted when we deploy the script, which we can actually do right now: from the editor window click on "Publish > Deploy from manifest..." and then "Install add-on"; it will make the app script available to operate on Gmail by opening the usual Google grants authorization popup.
Unlike filters defined on the web UI, apps scripts are not triggered every time a mail is received (there's a pub-sub mechanism, but it doesn't look like it would work for this), so if we want to execute periodically the new script, we need to create a time-driven trigger.
The simplest way is probably from the script editor (but you can also follow this doc): "View > Current project's triggers" and then "Add trigger" from there. For my specific use-case i set:
Be aware of quotas and limitations for Apps scripts; in particular the "Triggers total runtime" set to "90 min / day" is what led me to set the trigger every 510 mins.
Use the scripts dashboard (doc) to monitor the script execution logs, in the "My Executions" section, and specifically the "Duration" column: the script execution time depends exclusively on the number of emails to process at every execution, so fine-tune the trigger time to stay within your quota.
The newer_than search operator doesn't allow a granularity smaller than hours (although that's not even documented), so that means we're going to scan multiple times the same emails.
UPDATE (2020-12-26): I've already had to bump from every 5 to every 10 minutes, as otherwise i'd get Exception: Service invoked too many times for one day: gmail. (remember the quota!)
[user]
name = Sandro Tosi
email = <personal.address>@gmail.com
[includeIf "gitdir:~/deb/"]
path = ~/.gitconfig-deb
Every time the git path is in ~/deb/ (which is where i have all Debian repos) the file ~/.gitconfig-deb will be included; its content:[user]That results in my personal address being used on all repos not part of Debian, where i use my Debian email address. This approach can be extended to every other git configuration values.
email = morph@debian.org
debrepro
script by Antonio Terceiro which is similar in purpose to reprotest
but more
lightweight; specific to Debian packages and without support for virtual servers
or configurable variations.
Packages reviewed and fixed, and bugs filed
The following updated packages have become reproducible in our testing framework
after being fixed:
61
was
uploaded to unstable by Chris
Lamb. It included
contributions
from:
--help
text and add an --output-empty
option.--status-fd
CLI option.0.3.2
was
uploaded to unstable by Ximin
Luo. It included
contributions
from:
--diffoscope-arg
CLI option to pass extra args to diffoscope.Week 1 | Week 2 | Week 3 | Week 4 | Week 5 | Week 6 | Week 7 | |
---|---|---|---|---|---|---|---|
# Packages | 10 | 15 | 10 | 14 | 10 | - | - |
Total | 10 | 25 | 35 | 49 | 59 | - | - |
dput-ng (1.4) unstable; urgency=low
[ Arno T ll ]
* Really fix #696659 by making sure the command line tool uses the most recent
version of the library.
* Mark several fields to be required in profiles (incoming, method)
* Fix broken tests.
* Do not run the check-debs hook in our mentors.d.n profile
* Fix "[dcut] dm bombed out" by using the profile key only when defined
(Closes: #698232)
* Parse the gecos field to obtain the user name / email address from the local
system when DEBFULLNAME and DEBEMAIL are not set.
* Fix "dcut reschedule sends "None-day" to ftp-master if the delay is
not specified" by forcing the corresponding parameter (Closes: #698719)
.
[ Luca Falavigna ]
* Implement default_keyid option. This is particularly useful with multiple
GPG keys, so dcut is aware of which one to use.
* Make scp uploader aware of "port" configuration option.
.
[ Paul Tagliamonte ]
* Hack around Launchpad's SFTP implementation. We musn't stat *anything*.
"Be vewy vewy quiet, I'm hunting wabbits" (Closes: #696558).
* Rewrote the test suite to actually test the majority of the codepaths we
take during an upload. Back up to 60%.
* Added a README for the twitter hook, Thanks to Sandro Tosi for the bug,
and Gergely Nagy for poking me about it. (Closes: #697768).
* Added a doc for helping folks install hooks into dput-ng (Closes: #697862).
* Properly remove DEFAULT from loadable config blocks. (Closes: #698157).
* Allow upload of more then one file. Thanks to Iain Lane for the
suggestion. (Closes: #698855).
.
[ Bernhard R. Link ]
* allow empty incoming dir to upload directly to the home directory
.
[ Sandro Tosi ]
* Install example hooks (Closes: #697767).
Thanks to all the contributors!
For anyone who doesn t know, you should check out the docs.
1.3:
* Avoid failing on upload if a pre/post upload hook is missing from the
Filesystem.
* Fix "dcut raises FtpUploadException" by correctly initializing the uploader
classes from dcut (Closes: #696467)
1.2:
* Add bash completions for dput-ng (Closes: #695412).
* Add in a script to set the default profile depending on the building
distro (Ubuntu support)
* Fix a bug where meta-class info won't be loaded if the config file has the
same name.
* Add an Ubuntu upload target.
* Added .udeb detection to the check debs hook.
* Catch the correct exception falling out of bin/dcut
* Fix the dput manpages to use --uid rather then the old --dm flag.
* Fix the CLI flag registration by setting required=True
in cancel and upload.
* Move make_delayed_upload above the logging call for sanity's sake.
* Fix "connects to the host even with -s" (Closes: #695347)
Thanks to everone who s contributed!
7 Bernhard R. Link
4 Ansgar Burchardt
3 Luca Falavigna
2 Michael Gilbert
2 Salvatore Bonaccorso
1 Benjamin Drung
1 Gergely Nagy
1 Jakub Wilk
1 Jimmy Kaplowitz
1 Luke Faraone
1 Sandro Tosi
This has been your every-once-in-a-while dput-ng update.
We re looking for more code contributions (to make sure everyone s happy), doc updates (etc) or ideas.
Next.