import smtplib from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart from email.mime.image import MIMEImage import os import markdown import logging import re # Setup logging logging.basicConfig(filename=r'c:\Users\a931627\Documents\QRMASTER\tmp\script_log.log', level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', force=True) def get_pitch_data(): return [ { "filename": "digitalGpoint-dynamic-vs-static-qr-codes.md", "subject": "Pitch: Solving the 'print gap' for small businesses (DigitalGpoint)", "to_email": "digitalgpoint.webmail@gmail.com", "intro": "Hi DigitalGpoint Team,

I’ve noticed DigitalGpoint covers a lot of practical tools for business growth—especially those that bridge the gap between offline operations and digital simplicity. My latest draft fits right into this space." }, { "filename": "techdee-5-qr-code-strategies.md", "subject": "Pitch: Offline-to-Online marketing workflows (Techdee)", "to_email": "Blayget@gmail.com", "intro": "Hi Techdee Team,

I’ve been following Techdee’s tech and marketing tutorials for a while. Your audience seems to really value actionable, tech-forward tactics that small businesses can actually execute. This piece on QR strategies was written with that utility in mind." }, { "filename": "seosandwitch-qr-codes-offline-attribution.md", "subject": "Pitch: Attribution blind spots in physical marketing (SEO Sandwitch)", "to_email": "joydeep@seosandwitch.com", "intro": "Hi Joydeep,

I’ve been working on a technical deep-dive into how QR codes can bridge the offline attribution gap in local SEO. Given your focus on technical search strategies, I thought this would be a perfect fit for SEO Sandwitch." } ] def send_premium_email(pitch_data): smtp_host = "smtp.qrmaster.net" smtp_port = 465 smtp_user = "timo@qrmaster.net" smtp_pass = "fiesta" bcc_email = "knuth.timo@gmail.com" articles_dir = r"c:\Users\a931627\Documents\QRMASTER\articles" images_dir = r"c:\Users\a931627\Documents\QRMASTER\assets\images" logging.info(f"Starting real email dispatch for the {len(pitch_data)} guest post pitches.") for item in pitch_data: to_email = item["to_email"] file_path = os.path.join(articles_dir, item["filename"]) if not os.path.exists(file_path): logging.error(f"File not found: {item['filename']}") continue with open(file_path, "r", encoding="utf-8") as f: article_content = f.read() article_html = markdown.markdown(article_content, extensions=['tables', 'fenced_code', 'nl2br']) # Find images and prepare attachments img_tags = re.findall(r']*src="([^"]+)"[^>]*>', article_html) attachments = [] for img_src in img_tags: img_filename = os.path.basename(img_src) img_path = os.path.join(images_dir, img_filename) if os.path.exists(img_path): cid = img_filename.replace(".", "_") article_html = article_html.replace(img_src, f"cid:{cid}") with open(img_path, "rb") as img_f: img_data = img_f.read() mime_img = MIMEImage(img_data) mime_img.add_header('Content-ID', f'<{cid}>') mime_img.add_header('Content-Disposition', 'inline', filename=img_filename) attachments.append(mime_img) else: logging.warning(f"Image not found: {img_path}") html_template = f"""
{item["intro"]}
{article_html}
""" message = MIMEMultipart("related") message["From"] = smtp_user message["To"] = to_email message["Bcc"] = bcc_email message["Subject"] = item["subject"] msg_alternative = MIMEMultipart("alternative") message.attach(msg_alternative) msg_alternative.attach(MIMEText(html_template, "html")) for att in attachments: message.attach(att) try: with smtplib.SMTP_SSL(smtp_host, smtp_port) as server: server.login(smtp_user, smtp_pass) # Send to To and Bcc recipients = [to_email, bcc_email] server.sendmail(smtp_user, recipients, message.as_string()) logging.info(f"Successfully sent: {item['filename']} to {to_email} (BCC'd {bcc_email})") print(f"SENT: {item['filename']} to {to_email}") except Exception as e: logging.error(f"Failed to send {item['filename']} to {to_email}: {e}") print(f"FAILED: {item['filename']} to {to_email}") if __name__ == "__main__": pitches = get_pitch_data() send_premium_email(pitches)