From 25945b8fead989cca09a23983623b63ce36dcc0c Mon Sep 17 00:00:00 2001 From: Christian Cleberg Date: Mon, 8 Jan 2024 20:11:17 -0600 Subject: feat: total re-write from Emacs org-mode to Zola markdown --- blog/2022-06-22-daily-poetry.org | 239 --------------------------------------- 1 file changed, 239 deletions(-) delete mode 100644 blog/2022-06-22-daily-poetry.org (limited to 'blog/2022-06-22-daily-poetry.org') diff --git a/blog/2022-06-22-daily-poetry.org b/blog/2022-06-22-daily-poetry.org deleted file mode 100644 index dd1e249..0000000 --- a/blog/2022-06-22-daily-poetry.org +++ /dev/null @@ -1,239 +0,0 @@ -#+title: Daily Plaintext Poetry via Email -#+date: 2022-06-22 - -** Source Code -:PROPERTIES: -:CUSTOM_ID: source-code -:END: -I don't want to bury the lede here, so if you'd like to see the full -source code I use to email myself plaintext poems daily, visit the -repository: [[https://git.sr.ht/~cmc/daily-poem/][daily-poem]]. - -** My Daily Dose of Poetry -:PROPERTIES: -:CUSTOM_ID: my-daily-dose-of-poetry -:END: -Most of my programming projects are small, random projects that are made -strictly to fix some small problem I have or enhance my quality of life. - -In this case, I was looking for a simply and easy way to get a daily -dose of literature or poetry to read in the mornings. - -However, I don't want to sign up for a random mailing list on just any -website. I also don't want to have to work to find the reading content -each morning, as I know I would simply give up and stop reading daily. - -Thus, I found a way to deliver poetry to myself in plain-text format, on -a daily basis, and scheduled to deliver automatically. - -** Prerequisites -:PROPERTIES: -:CUSTOM_ID: prerequisites -:END: -This solution uses Python and email, so the following process requires -the following to be installed: - -1. An SMTP server, which can be as easy as installing =mailutils= if - you're on a Debian-based distro. -2. Python (& pip!) -3. The following Python packages: =email=, =smtplib=, =json=, and - =requests= - -** Breaking Down the Logic -:PROPERTIES: -:CUSTOM_ID: breaking-down-the-logic -:END: -I want to break down the logic for this program, as it's quite simple -and informational. - -*** Required Packages -:PROPERTIES: -:CUSTOM_ID: required-packages -:END: -This program starts with a simple import of the required packages, so I -wanted to explain why each package is used: - -#+begin_src py -from email.mime.text import MIMEText # Required for translating MIMEText -import smtplib # Required to process the SMTP mail delivery -import json # Required to parse the poetry API results -import requests # Required to send out a request to the API -#+end_src - -*** Sending the API Request -:PROPERTIES: -:CUSTOM_ID: sending-the-api-request -:END: -Next, we need to actually send the API request. In my case, I'm calling -a random poem from the entire API. If you want, you can call specific -poems or authors from this API. - -#+begin_src py -json_data = requests.get('https://poetrydb.org/random').json() -#+end_src - -This gives us the following result in JSON: - -#+begin_src json -[ - { - "title": "Sonnet XXII: With Fools and Children", - "author": "Michael Drayton", - "lines": [ - "To Folly", - "", - "With fools and children, good discretion bears;", - "Then, honest people, bear with Love and me,", - "Nor older yet, nor wiser made by years,", - "Amongst the rest of fools and children be;", - "Love, still a baby, plays with gauds and toys,", - "And, like a wanton, sports with every feather,", - "And idiots still are running after boys,", - "Then fools and children fitt'st to go together.", - "He still as young as when he first was born,", - "No wiser I than when as young as he;", - "You that behold us, laugh us not to scorn;", - "Give Nature thanks you are not such as we.", - "Yet fools and children sometimes tell in play", - "Some, wise in show, more fools indeed than they." - ], - "linecount": "15" - } -] -#+end_src - -*** Parsing the API Results -:PROPERTIES: -:CUSTOM_ID: parsing-the-api-results -:END: -In order to parse this into a readable format, we need to use the =json= -package and extract the fields we want. In the example below, I am -grabbing every field presented by the API. - -For the actual poem content, we need to loop over each line in the -=lines= variable since each line is a separate string by default. - -#+begin_quote -You /could/ also extract the title or author and make another call out -to the API to avoid having to build the plaintext poem with a loop, but -it just doesn't make sense to me to send multiple requests when we can -create a simple loop on our local machine to work with the data we -already have. - -For -[[https://poetrydb.org/title/Sonnet%20XXII:%20With%20Fools%20and%20Children/lines.text][example]], -look at the raw data response of this link to see the poem's lines -returned in plaintext. - -#+end_quote - -#+begin_src py -title = json_data[0]['title'] -author = json_data[0]['author'] -line_count = json_data[0]['linecount'] -lines = '' -for line in json_data[0]['lines']: - lines = lines + line + "\n" -#+end_src - -*** Composing the Email -:PROPERTIES: -:CUSTOM_ID: composing-the-email -:END: -Now that I have all the data I need, I just need to compose it into a -message and prepare the message metadata. - -For my daily email, I want to see the title of the poem first, followed -by the author, then a blank line, and finally the full poem. This code -snippet combines that data and packages it into a MIMEText container, -ready to be emailed. - -#+begin_src py -msg_body = title + "\n" + author + "\n\n" + lines -msg = MIMEText(msg_body) -#+end_src - -Before we send the email, we need to prepare the metadata (subject, -from, to, etc.): - -#+begin_src py -sender_email = 'example@server.local' -recipient_emails = ['user@example.com'] -msg['Subject'] = 'Your Daily Poem (' + line_count + ' lines)' -msg['From'] = sender_email -msg['To'] = recipient_email -#+end_src - -*** Sending the Email -:PROPERTIES: -:CUSTOM_ID: sending-the-email -:END: -Now that I have everything ready to be emailed, the last step is to -simply connect to an SMTP server and send the email out to the -recipients. In my case, I installed =mailutils= on Ubuntu and let my -SMTP server be =localhost=. - -#+begin_src py -smtp_server = 'localhost' -s = smtplib.SMTP(smtp_server) -s.sendmail(sender_email, recipient_emails, msg.as_string()) -s.quit() -#+end_src - -** The Result! -:PROPERTIES: -:CUSTOM_ID: the-result -:END: -Instead of including a screenshot, I've copied the contents of the email -that was delivered to my inbox below since I set this process up in -plaintext format. - -#+begin_src txt -Date: Wed, 22 Jun 2022 14:37:19 +0000 (UTC) -From: REDACTED -To: REDACTED -Subject: Your Daily Poem (36 lines) -MIME-Version: 1.0 -Content-Transfer-Encoding: 8bit -Content-Type: text/plain; charset=utf-8 - -Sonnet XXII: With Fools and Children -Michael Drayton - -With fools and children, good discretion bears; -Then, honest people, bear with Love and me, -Nor older yet, nor wiser made by years, -Amongst the rest of fools and children be; -Love, still a baby, plays with gauds and toys, -And, like a wanton, sports with every feather, -And idiots still are running after boys, -Then fools and children fitt'st to go together. -He still as young as when he first was born, -No wiser I than when as young as he; -You that behold us, laugh us not to scorn; -Give Nature thanks you are not such as we. -Yet fools and children sometimes tell in play -Some, wise in show, more fools indeed than they. -#+end_src - -** Scheduling the Daily Email -:PROPERTIES: -:CUSTOM_ID: scheduling-the-daily-email -:END: -Last, but not least, is scheduling this Python script with =crontab=. To -schedule a script to run daily, you can add it to the =crontab= file. To -do this, open =crontab= in editing mode: - -#+begin_src sh -crontab -e -#+end_src - -In the file, simply paste the following snippet at the bottom of the -file and ensure that the file path is correctly pointing to wherever you -saved your Python script: - -#+begin_src config -0 8 * * * python3 /home//dailypoem/main.py -#+end_src - -We have now set up the script and scheduled it to run daily at 08:00! -- cgit v1.2.3-70-g09d2