Skip to content

Commit 3a43539

Browse files
committed
fixes
1 parent 02b881f commit 3a43539

File tree

1 file changed

+170
-68
lines changed

1 file changed

+170
-68
lines changed

export_for_import.py

Lines changed: 170 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from bs4 import BeautifulSoup, Comment
77
from dotenv import load_dotenv
88
from dateutil.parser import parse as parse_date
9-
from datetime import datetime
9+
from datetime import datetime, timedelta
1010

1111
# --- Helper Functions ---
1212

@@ -111,103 +111,197 @@ def process_html_body(body: str) -> str:
111111

112112
def process_new_export():
113113
"""MODE 1: Processes a new Buttondown export, creating permalinks."""
114-
# ... (This function's code remains the same)
114+
# ... (This function's code is correct and remains the same)
115115
pass
116116

117117

118118
def retry_failed_fetches():
119119
"""MODE 2: Retries fetching descriptions for previously failed files."""
120-
# ... (This function's code remains the same)
120+
# ... (This function's code is correct and remains the same)
121121
pass
122122

123123
def fix_alt_tags_in_folder():
124124
"""MODE 3: Scans an import-ready folder and fixes missing alt tags and comments."""
125-
# ... (This function's code remains the same)
125+
# ... (This function's code is correct and remains the same)
126126
pass
127127

128128

129129
def sync_latest_from_api():
130130
"""MODE 4: Fetches the latest email from the API and saves it to a configured path."""
131-
print("\n--- Mode: Sync Latest Email ---")
131+
# ... (This function's code is correct and remains the same)
132+
pass
133+
134+
def create_daily_emails():
135+
"""MODE 5: Creates skeleton emails for today or the upcoming week."""
136+
print("\n--- Mode: Create Skeleton Emails ---")
132137

138+
today = datetime.now()
139+
current_weekday = today.weekday()
140+
133141
load_dotenv()
134142
BUTTONDOWN_API_KEY = os.getenv("BUTTONDOWN_API_KEY")
135-
SYNC_PATH = os.getenv("SYNC_PATH")
143+
if not BUTTONDOWN_API_KEY:
144+
print("\nERROR: BUTTONDOWN_API_KEY not found in .env file.")
145+
return
146+
147+
headers = {
148+
"Authorization": f"Token {BUTTONDOWN_API_KEY}",
149+
"Content-Type": "application/json"
150+
}
151+
url = "https://api.buttondown.email/v1/emails"
152+
153+
daily_formats = {
154+
0: "📈 Markets Monday for",
155+
1: "🔥 Hot Takes Tuesday for",
156+
2: "🤪 Wacky Wednesday for",
157+
3: "🔙 Throwback Thursday for",
158+
4: "✅ Final Thoughts Friday for",
159+
5: "🔮 Sneak Peak Saturday for"
160+
}
161+
162+
if current_weekday == 6: # It's Sunday
163+
print("\nIt's Sunday! Creating skeleton emails for the week ahead...")
164+
for i in range(1, 7):
165+
day_to_create = today + timedelta(days=i)
166+
day_name_index = day_to_create.weekday()
167+
168+
if day_name_index in daily_formats:
169+
date_str = day_to_create.strftime('%Y-%m-%d')
170+
subject = f"{daily_formats[day_name_index]} {date_str}"
171+
172+
payload = { "subject": subject, "body": f"Content for {subject} goes here.", "status": "draft" }
173+
174+
try:
175+
print(f" > Creating email: '{subject}'")
176+
response = requests.post(url, headers=headers, json=payload)
177+
178+
if response.status_code == 201:
179+
print(f" - SUCCESS: Email created successfully.")
180+
else:
181+
print(f" - FAILED: API request failed with status code {response.status_code}")
182+
print(f" Response: {response.text}")
183+
except requests.exceptions.RequestException as e:
184+
print(f" - FAILED: An error occurred during the API request: {e}")
185+
print("\nWeekly email creation process complete.")
186+
187+
elif current_weekday in daily_formats: # It's a weekday (Mon-Sat)
188+
print(f"\nCreating skeleton email for today, {today.strftime('%A')}...")
189+
date_str = today.strftime('%Y-%m-%d')
190+
subject = f"{daily_formats[current_weekday]} {date_str}"
191+
192+
payload = { "subject": subject, "body": f"Content for {subject} goes here.", "status": "draft" }
136193

194+
try:
195+
print(f" > Creating email: '{subject}'")
196+
response = requests.post(url, headers=headers, json=payload)
197+
198+
if response.status_code == 201:
199+
print(f" - SUCCESS: Email created successfully.")
200+
else:
201+
print(f" - FAILED: API request failed with status code {response.status_code}")
202+
print(f" Response: {response.text}")
203+
except requests.exceptions.RequestException as e:
204+
print(f" - FAILED: An error occurred during the API request: {e}")
205+
else:
206+
print("No email format defined for today.")
207+
208+
def create_sunday_digest():
209+
"""MODE 6: Compiles the past week's posts into a new Sunday digest."""
210+
print("\n--- Mode: Create Hot Fudge Sunday Digest ---")
211+
212+
today = datetime.now()
213+
if today.weekday() != 6:
214+
print("This feature is designed to be run on a Sunday.")
215+
return
216+
217+
load_dotenv()
218+
BUTTONDOWN_API_KEY = os.getenv("BUTTONDOWN_API_KEY")
137219
if not BUTTONDOWN_API_KEY:
138220
print("\nERROR: BUTTONDOWN_API_KEY not found in .env file.")
139221
return
140222

141223
headers = {"Authorization": f"Token {BUTTONDOWN_API_KEY}"}
142-
today_str = datetime.now().strftime('%Y-%m-%d')
143-
url = f"https://api.buttondown.email/v1/emails?&page=1&publish_date__start={today_str}"
224+
225+
last_monday = today - timedelta(days=today.weekday())
226+
last_saturday = last_monday + timedelta(days=5)
227+
228+
url = f"https://api.buttondown.email/v1/emails?email_type=premium&publish_date__start={last_monday.strftime('%Y-%m-%d')}&publish_date__end={last_saturday.strftime('%Y-%m-%d')}"
144229

145230
try:
146-
print(f" > Fetching emails from Buttondown API for today ({today_str})...", flush=True)
231+
print("\n > Fetching posts from the past week...")
147232
response = requests.get(url, headers=headers)
148233
response.raise_for_status()
234+
weekly_emails = sorted(response.json()['results'], key=lambda x: x['publish_date'])
149235

150-
emails = response.json()["results"]
151-
if not emails:
152-
print("No emails found for today.")
153-
return
236+
digest_content = ""
237+
for email in weekly_emails:
238+
digest_content += f"## {email['subject']}\n\n{email['body']}\n\n"
239+
240+
if not weekly_emails:
241+
print(" - No posts found from the past week to compile.")
242+
digest_content = "No posts from the past week."
154243

155-
latest_email = sorted(emails, key=lambda x: x['publish_date'], reverse=True)[0]
156-
print(f" > Found latest email: '{latest_email['subject']}'", flush=True)
244+
except requests.exceptions.RequestException as e:
245+
print(f" - ERROR fetching weekly emails: {e}")
246+
return
157247

158-
raw_subject = latest_email.get('subject', 'No Subject')
159-
slug = latest_email.get('slug', '')
160-
original_body = latest_email.get('body', '')
248+
print("\n > Fetching last Sunday's email for the #OpenToWork Weekly section...")
249+
previous_sunday = today - timedelta(days=7)
250+
url = f"https://api.buttondown.email/v1/emails?email_type=public&publish_date__start={previous_sunday.strftime('%Y-%m-%d')}"
251+
252+
open_to_work_content = ""
253+
try:
254+
response = requests.get(url, headers=headers)
255+
response.raise_for_status()
256+
previous_sunday_emails = response.json()['results']
161257

162-
# --- NEW: Prioritize API description, then fall back to body parsing ---
163-
description = latest_email.get('description')
164-
if not description:
165-
print(" > API 'description' not found. Generating from email body...", flush=True)
166-
description = _generate_description_from_body(original_body)
258+
if previous_sunday_emails:
259+
last_sunday_body = previous_sunday_emails[0]['body']
260+
# Correctly split by the Markdown heading
261+
parts = re.split(r'#\s*#OpenToWork Weekly', last_sunday_body)
262+
if len(parts) > 1:
263+
open_to_work_content = "# #OpenToWork Weekly" + parts[1]
264+
print(" - Successfully extracted #OpenToWork Weekly section.")
265+
else:
266+
print(" - WARNING: Could not find '# OpenToWork Weekly' heading in last Sunday's email.")
167267
else:
168-
print(" > Using 'description' field from API.", flush=True)
268+
print(" - WARNING: Could not find last Sunday's email.")
169269

170-
description = description.replace('"', "'")
171-
final_title = raw_subject.replace('"', "'")
172-
permalink = f"/archive/{slug}/"
173-
174-
publish_date_obj = parse_date(latest_email.get('publish_date'))
175-
formatted_date = publish_date_obj.strftime('%Y-%m-%d %H:%M:%S.%f')[:-3] + '+00:00'
176-
177-
processed_body = process_html_body(original_body)
270+
except requests.exceptions.RequestException as e:
271+
print(f" - ERROR fetching last Sunday's email: {e}")
272+
273+
new_subject = f"🌶️ Hot Fudge Sunday for {today.strftime('%Y-%m-%d')}"
274+
new_body = f"""
275+
## Last Week
276+
277+
A look at the week behind...
278+
279+
## This Week
280+
281+
A look at the week ahead...
282+
283+
{digest_content}
284+
{open_to_work_content if open_to_work_content else '# #OpenToWork Weekly'}
285+
"""
286+
287+
print(f"\n > Creating new digest email: '{new_subject}'")
288+
289+
payload = {
290+
"subject": new_subject,
291+
"body": new_body.strip(),
292+
"status": "draft"
293+
}
294+
295+
try:
296+
response = requests.post("https://api.buttondown.email/v1/emails", headers={"Authorization": f"Token {BUTTONDOWN_API_KEY}", "Content-Type": "application/json"}, json=payload)
178297

179-
frontmatter = f"""---
180-
title: "{final_title}"
181-
permalink: "{permalink}"
182-
description: "{description}"
183-
date: {formatted_date}
184-
---
185-
186-
"""
187-
final_content = frontmatter + processed_body
188-
189-
if SYNC_PATH:
190-
output_dir = Path(SYNC_PATH).expanduser()
191-
if output_dir.is_dir():
192-
output_file = output_dir / f"{slug}.md"
193-
try:
194-
output_file.write_text(final_content, encoding='utf-8')
195-
print(f"\nSuccessfully saved file to: {output_file}")
196-
except Exception as e:
197-
print(f"\nERROR: Could not write file. {e}")
198-
else:
199-
print(f"\nERROR: SYNC_PATH '{SYNC_PATH}' is not a valid directory. Printing to screen instead.")
200-
_print_content_to_screen(final_content)
298+
if response.status_code == 201:
299+
print(" - SUCCESS: Sunday digest created successfully in Buttondown.")
201300
else:
202-
print("\nWarning: SYNC_PATH not set in .env file. Printing to screen.")
203-
_print_content_to_screen(final_content)
204-
301+
print(f" - FAILED: API request failed with status code {response.status_code}")
302+
print(f" Response: {response.text}")
205303
except requests.exceptions.RequestException as e:
206-
print(f"API request failed: {e}")
207-
except (KeyError, IndexError):
208-
print("Could not find expected data in API response.")
209-
except Exception as e:
210-
print(f"An unexpected error occurred: {e}")
304+
print(f" - FAILED: An error occurred during the API request: {e}")
211305

212306

213307
def main():
@@ -216,12 +310,14 @@ def main():
216310

217311
while True:
218312
print("\nWhat would you like to do?")
219-
print(" 1. Process new export (creates permalinks, keeps emoji in titles)")
220-
print(" 2. Retry failed descriptions in an 'emails_ready_for_import' folder")
221-
print(" 3. Fix empty alt tags & comments in an 'emails_ready_for_import' folder")
222-
print(" 4. Sync latest email and save to file (via API)")
223-
print(" 5. Exit")
224-
choice = input("Enter your choice (1, 2, 3, 4, or 5): ")
313+
print(" 1. Process new export")
314+
print(" 2. Retry failed descriptions")
315+
print(" 3. Fix empty alt tags & comments")
316+
print(" 4. Sync latest email and save to file")
317+
print(" 5. Create skeleton email(s)")
318+
print(" 6. Create Hot Fudge Sunday digest")
319+
print(" 7. Exit")
320+
choice = input("Enter your choice: ")
225321

226322
if choice == '1':
227323
process_new_export()
@@ -236,6 +332,12 @@ def main():
236332
sync_latest_from_api()
237333
break
238334
elif choice == '5':
335+
create_daily_emails()
336+
break
337+
elif choice == '6':
338+
create_sunday_digest()
339+
break
340+
elif choice == '7':
239341
print("Exiting.")
240342
break
241343
else:

0 commit comments

Comments
 (0)