8.4. Howdy Email API
This document describes the lower level Plex emailing API, upon which the command line tol and the GUI tool are built. It lives in howdy.email.
8.4.1. howdy.email module
This contains the lowest level methods to send email using either the Google Contacts API or through Python’s SMTP functionality, and to find the Google contact names of friend emails on the Plex server. HowdyIMGClient and PNGPicObject allow one to add or remove images from one’s Imgur acount.
- class howdy.email.HowdyIMGClient(verify=True, data_imgurl=None)
This object contains and implements the collection of images located in a single main album in the Imgur account. This uses the Imgur API to peform all operations. This object is constructed using Imgur credentials – the client ID, secret, and refresh token – stored in the SQLite3 configuration database, and stores the following attributes: the client ID, secret, refresh token, and the access token used for API access to your Imgur album and images.
If the Imgur albums cannot be accessed, or there are no albums, then
self.albumID = None, theself.imgHashesis an emptydict.The main album ID is stored as a
stringin the Imgur configuration under themainALBUMIDkey, if it exists; otherwise the Imgur configuration dictionary does not have amainALBUMIDkey.If there is no main album ID defined, or if there is no album with that ID, then we choose the first album found, and reset the Imgur configuration data into the SQLite3 database with this album ID and name.
If the configured album exists in our Imgur library, then continue with this the main album.
Once the main album is found, populate
self.imghasheswith all the pictures in this album. The pictures in an album in our Imgur account are expected to be filled through methods in this object.The key is the MD5 hash of the image in that library.
The value is a four element
tuple: image name, image ID, the URL link to this image, and thedatetimeat which the image was uploaded.
- Parameters:
- Variables:
- Raises:
ValueError – if images in the new album cannot be accessed.
See also
- change_album_name(new_album_name)
Changes the main album name to a new name, only if the new name is different from the old name.
See also
- change_name(imgMD5, new_name)
Changes the name of an image in the main Imgur library.
- Parameters:
- Returns:
Trueif image could be found and its name changed. Otherwise returnsFalse.- Return type:
See also
- delete_candidate_album(candidate_album_name)
This deletes the candidate album from the Imgur account. This album with that name must exist in the Imgur account.
- Parameters:
candidate_album_name (str) – the name of the album to remove, with its underlying images.
See also
- delete_image(b64img, imgMD5=None)
Removes an image from the main Imgur library.
- Parameters:
- Returns:
Trueif image can be found and returned. Otherwise returnsFalse.- Return type:
See also
- get_candidate_album_names()
- Returns:
a
listof album names in the Imgur account.set_main_albumcan use this method to determine the valid album name to choose.
See also
get_candidate_albums.
- get_candidate_albums()
- classmethod get_image_md5(image)
- Returns:
the MD5 hash of the image.
- Parameters:
image (
PngImageFile) – the native Pillow PNG image object.
- get_main_album_name()
- refreshImages()
Refreshes the collection of images in the main Imgur album, by filling out
self.imghashes. The pictures in an album in our Imgur account are expected to be filled through methods in this object.
- set_main_album(new_album_name)
Sets or changes the main Imgur album used for storing and displaying images to a new album name. If
new_album_nameexists in the Imgur account, then sets that name. Ifnew_album_namedoes not exist, then creates this new Imgur album.Once this album is set or created,
sets the new Imgur credentials using
store_imgur_credentials.populates
self.imghasheswith all the images found in this library. Of course, if the album does not exist, thenself.imghashesis an emptydict.
- Parameters:
new_album_name (str) – the new name of the Imgur album to use for images.
- Raises:
ValueError – if images in the new album cannot be accessed.
See also
- upload_image(b64img, name, imgMD5=None)
Uploads a Base64 encoded file into the main Imgur album. If the image exists, then returns information (from
self.imghashes) about the file. If not, create it, put it intoself.imghashes, and then return its information.- Parameters:
- Returns:
a 4-element
tuple: image name, image ID, the URL link to this image, and thedatetimeat which the image was uploaded.- Return type:
See also
- class howdy.email.PNGPicObject(initdata, pImgClient)
This provides a GUI widget to the Imgur interface implemented in
PlexIMGClient. Initializaton of the image can either upload this image to the Imgur account, or retrieve the image from the main Imgur album. This object can also launch a GUI dialog window throughgetInfoGUI.- Parameters:
initdata (dict) –
the low-level dictionary that contains important information on the image, located in a file, that will either be uploaded into the main Imgur album or merely kept in memory. The main key that determines operation is
initialization. It can be one of"FILE"or"SERVER".If
initializationis"FILE", then upload the the image to the main album in the Imgur account. Here are the required keys ininitdata.filenameis the location of the image file on disk.actNameis the PNG filename to be used. It must end inpng.
If
initializationis"SERVER", then retrieve this image from the main album in the Imgur account. Here are the required keys ininitdata.pImgClient (PlexIMGClient) – the
PlexIMGClientused to access and manipulate (add, delete, rename) images in the main Imgur album.
- Variables:
actName (str) – the file name without full path, which must end in
png.img (QImage) – the
QImagerepresentation of this image.originalImage (Image) – the
Imagerepresentation of this image.originalWidth (float) – the inferred width in cm.
currentWidth (float) – the current image width in cm. It starts off as equal to
originalWidthb64string (str) – the Base64 encoded representation of this image as a PNG file.
imgurlLink (str) – the URL link to the image.
imgDateTime (datetime) – the
datetimeat which this image was first uploaded to the main album in the Imgur account.
- Raises:
ValueError – if
initdata['initialization']is neither"FILE"nor"SERVER".
- b64String()
- changeName(new_name, hImgClient)
changes the filename into a new name.
- Parameters:
new_name (str) – the new name of the image file to be changed in the main album on the Imgur account. This must end in
png.hImgClient (HowdyIMGClient) – the
HowdyIMGClientused to access and manipulate (add, delete, rename) images in the main Imgur album.
- classmethod createPNGPicObjects(pImgClient)
- Parameters:
pImgClient (PlexIMGClient) – the
PlexIMGClientused to access and manipulate (add, delete, rename) images in the main Imgur album.- Returns:
a
listofPNGPicObjectrepresenting the images in the main Imgur album.- Return type:
- getInfoGUI(parent)
Launches a
QDialogthat contains the underlying image and some other labels:ACTNAMEis the actual PNG file name,URLis the image’s Imgur link, andUPLOADED ATis the date and time at which the file was uploaded. An example image is shown below,
Fig. 8.36 An example PNG image that can be stored in the main Imgur library. Note the three rows above the image: the name of the PNG image; its URL; and the date and time it was uploaded.
- howdy.email.get_all_email_contacts_dict(verify=True, pagesize=4000)
Returns all the Google contacts using the Google Contacts API.
- howdy.email.get_email_contacts_dict(emailList, verify=True)
Returns the Google contacts given a set of emails, all using the Google Contacts API.
- Parameters:
- Returns:
a
listof two-elementtuple. The first element is the Google conatct name. The second element is a primary email associated with that contact.- Return type:
See also
- howdy.email.get_email_service(verify=True)
This returns a working
Resourcerepresenting the Google email service used to send and receive emails.- Parameters:
verify (bool) – optional argument, whether to verify SSL connections. Default is
True.- Returns:
the
Resourcerepresenting the Google email service used to send and receive emails. IfNone, then generated here.- Return type:
Resource
- howdy.email.send_email_lowlevel(msg, email_service=None, verify=True)
Sends out an email using the Google Contacts API. If process is unsuccessfull, prints out an error message,
"problem with <TO-EMAIL>", where<TO-EMAIL>is the recipient’s email address.- Parameters:
msg (
MIMEMultipart) – the email message object to send. At a high level, this is an email with body, sender, recipients, and optional attachments.email_service – optional argument, the
Resourcerepresenting the Google email service used to send and receive emails. IfNone, then generated here.verify (bool) – optional argument, whether to verify SSL connections. Default is
True.
See also
8.4.2. howdy.email.email module
This implements the following functionality: sending emails of torrent files and magnet links; sending MIMEMultiPart newsletter or more general style emails to friends of the Plex server; and sending general emails with attachments.
- howdy.email.email.get_summary_body(token, nameSection=False, fullURL='http://localhost:32400', verify=True)
Returns the summary body of the Plex newsletter email as a reStructuredText string document, for the Plex server.
- Parameters:
nameSection (bool) – if
True, then include this summary in its own section called"Summary". If not, then return as a stand-alone reStructuredText document.verify (bool) – optional argument, whether to verify SSL connections. Default is
True.
- Returns:
the reStructuredText document representing the summary of the media on the Plex server.
- Return type:
- howdy.email.email.get_summary_data_movies_remote(token, fullURL='http://localhost:32400', sinceDate=datetime.date(2020, 1, 1))
This returns summary information on movie media from all movie libraries on the Plex server, for use as part of the Plex newsletter sent out to one’s Plex server friends. The email first summarizes ALL the movie data, and then summarizes the movie data uploaded and processed since the last newsletter’s date. Unlike
get_summary_data_music_remoteandget_summary_data_television_remote, this returns alistof strings rather than a string.- Parameters:
- Returns:
a
stringdescription of TV media in all TV libraries on the Plex server. If there is no Plex server or TV library, returnsNone.- Return type:
See also
- howdy.email.email.get_summary_data_music_remote(token, fullURL='http://localhost:32400', sinceDate=datetime.date(2020, 1, 1))
This returns summary information on songs from all music libraries on the Plex server, for use as part of the Plex newsletter sent out to one’s Plex server friends. The email first summarizes ALL the music data, and then summarizes the music data uploaded and processed since a previous date. For example,
As of December 29, 2020, there are 17,853 songs made by 889 artists in 1,764 albums. The total size of music media is 306.979 GB. The total duration of music media is 7 months, 18 days, 15 hours, 8 minutes, and 15.785 seconds.
Since January 01, 2020, I have added 7,117 songs made by 700 artists in 1,180 albums. The total size of music media that I have added is 48.167 GB. The total duration of music media that I have added is 28 days, 15 hours, 25 minutes, and 37.580 seconds.
- Parameters:
- Returns:
a
stringdescription of music media in all music libraries on the Plex server. If there is no Plex server or music library, returnsNone.- Return type:
See also
- howdy.email.email.get_summary_data_television_remote(token, fullURL='http://localhost:32400', sinceDate=datetime.date(2020, 1, 1))
This returns summary information on TV media from all television libraries on the Plex server, for use as part of the Plex newsletter sent out to one’s Plex server friends. The email first summarizes ALL the TV data, and then summarizes the TV data uploaded and processed since a previous date. For example,
As of December 29, 2020, there are 25,195 TV episodes in 298 TV shows. The total size of TV media is 6.690 TB. The total duration of TV media is 1 year, 5 months, 19 days, 9 hours, 29 minutes, and 13.919 seconds.
Since January 01, 2020, I have added 5,005 TV epsisodes in 298 TV shows. The total size of TV media that I have added is 1.571 TB. The total duration of TV media that I have added is 3 months, 16 days, 4 hours, 52 minutes, and 15.406 seconds.
- Parameters:
- Returns:
a
stringdescription of TV media in all TV libraries on the Plex server. If there is no Plex server or TV library, returnsNone.- Return type:
See also
- howdy.email.email.get_summary_html(token, fullURL='http://localhost:32400', preambleText='', postambleText='', name=None)
Creates a Plex newsletter summary HTML email of the media on the Plex server. Used by the email GUI to send out summary emails.
- Parameters:
preambleText (str) – optional argument. The reStructuredText formatted preamble text (text section before summary), if non-empty. Default is
"".postambleText (str) – optional argument. The reStructuredText formatted text, in a section after the summary. if non-empty. Default is
"".name (str) – optional argument. If given, the recipient’s name.
- Returns:
a two-element
tuple. The first element is an HTMLstringdocument of the Plex newletter email. The second element is the full reStructuredTextstring.- Return type:
See also
- howdy.email.email.send_collective_email_full(mainHTML, subject, fromEmail, to_emails, cc_emails, bcc_emails, verify=True, email_service=None)
Sends the HTML email to the following
TOrecipients,CCrecipients, andBCCrecipients altogether. It uses the GMail API.
- howdy.email.email.send_email_movie_none(movieName, verify=True)
Request an individual movie from the Plex server’s administrator, using the GMail API.
- Parameters:
- Returns:
the string
"SUCCESS"if nothing goes wrong.- Return type:
- Raises:
AssertionError – if the current Plex account user’s email address does not exist.
- howdy.email.email.send_email_movie_torrent(movieName, data, isJackett=False, verify=True)
Sends an individual torrent file or magnet link to the Plex user’s email, using the GMail API.
- Parameters:
movieName (str) – the name of the movie.
data (str) – the Base64 encoded file, if torrent file. Otherwise the magnet URI link if magnet link.
isJackett (bool) –
booleanflag used to determine whetherdatais a torrent file or magnet link. IfFalse, then expects a torrent file. IfTrue, then expects a magnet link. Default isFalse.verify (bool) – optional argument, whether to verify SSL connections. Default is
True.
- Returns:
the string
"SUCCESS"if nothing goes wrong.- Return type:
- Raises:
AssertionError – if the current Plex account user’s email address does not exist.
- howdy.email.email.send_individual_email(mainHTML, email, name=None, mydate=datetime.date(2025, 11, 14), verify=True, email_service=None)
sends the HTML email to a single recipient email address using the GMail API. The subject is
"Plex Email Newsletter for <MONTH> <YEAR>".- Parameters:
email (str) – the recipient email address.
name (str) – optional argument. If given, the recipient’s name.
mydate (date) – optional argument. The
dateat which the email is sent. Default isnow( ).verify (bool) – optional argument, whether to verify SSL connections. Default is
True.email_service – optional argument, the
Resourcerepresenting the Google email service used to send and receive emails. IfNone, then generated here.
- Raises:
AssertionError – if the current Plex account user’s email address does not exist.
- howdy.email.email.send_individual_email_full(mainHTML, subject, emailAddress, name=None, attach=None, attachName=None, attachType='txt', verify=True, email_service=None)
Sends the HTML email, with optional single attachment, to a single recipient email address, using the GMail API. Unlike
send_individual_email_full_withsingleattach, the attachment type is also set.- Parameters:
subject (str) – the email subject.
emailAddress (str) – the recipient email address.
name (str) – optional argument. If given, the recipient’s name.
mydate (date) – optional argument. The
dateat which the email is sent. Default isnow( ).attach (str) – optional argument. If defined, the Base64 encoded attachment.
attachName (str) – optional argument. The
listof attachment names, if there is an attachment. If defined, thenattachDatamust also be defined.attachType (str) – the attachment type. Default is
txt.verify (bool) – optional argument, whether to verify SSL connections. Default is
True.email_service – optional argument, the
Resourcerepresenting the Google email service used to send and receive emails. IfNone, then generated here.
- Raises:
AssertionError – if the current Plex account user’s email address does not exist.
- howdy.email.email.send_individual_email_full_withattachs(mainHTML, subject, email, name=None, attachNames=None, attachDatas=None)
Sends the HTML email, with optional attachments, to a single recipient email address. This uses the
SMTPPython functionality to send through a local SMTP server (seesend_email_localsmtp).- Parameters:
subject (str) – the email subject.
email (str) – the recipient email address.
name (str) – optional argument. If given, the recipient’s name.
mydate (date) – optional argument. The
dateat which the email is sent. Default isnow( ).attachNames (list) – optional argument. The
listof attachment names, if attachments are used. If defined, thenattachDatasmust also be defined.attachDatas (list) – optional argument. If defined, the
listof attachments with corresponding name described inattachNames. Each entry is a Base64 encoded attachment.
- Raises:
AssertionError – if the current Plex account user’s email address does not exist.
- howdy.email.email.send_individual_email_full_withsingleattach(mainHTML, subject, email, name=None, attachData=None, attachName=None, verify=True, email_service=None)
Sends the HTML email, with optional single attachment, to a single recipient email address, using the GMail API.
- Parameters:
subject (str) – the email subject.
email (str) – the recipient email address.
name (str) – optional argument. If given, the recipient’s name.
mydate (date) – optional argument. The
dateat which the email is sent. Default isnow( ).attachData (str) – optional argument. If defined, the Base64 encoded attachment.
attachName (str) – optional argument. The
listof attachment names, if there is an attachment. If defined, thenattachDatamust also be defined.verify (bool) – optional argument, whether to verify SSL connections. Default is
True.email_service – optional argument, the
Resourcerepresenting the Google email service used to send and receive emails. IfNone, then generated here.
- Raises:
AssertionError – if the current Plex account user’s email address does not exist.
- howdy.email.email.send_individual_email_perproc(input_tuple)
A tuple-ized version of
send_individual_emailused by themultiprocessingmodule to send out emails.- Parameters:
input_tuple (tuple) – an expected four-element
tuple: the HTML email body, the recipient’s email, the recipient’s name, and theemail service resource.
See also
- howdy.email.email.test_email(subject=None, htmlstring=None, verify=True)
Sends a test email to the Plex user’s email address.
- Parameters:
subject (str) – optional argument. The email subject. If not defined, the subject is
"Plex Email Newsletter for <MONTH> <YEAR>".htmlstring (str) – optional argument. The email body as an HTML
strdocument. If not defined, the body is"This is a test.".verify (bool) – optional argument, whether to verify SSL connections. Default is
True.