This commit is contained in:
Cyberes 2024-06-09 21:30:13 -06:00
parent f7709fbe99
commit 039451b9cb
9 changed files with 681 additions and 1 deletions

View File

@ -2,4 +2,7 @@
*spam burner emails on /aicg/*
Old code I used to scrape and spam emails people posted on /aicg/. Funny how the burner posting dropped off after I industrialized the spam...
Old project I used to scrape and spam emails people posted on /aicg/. Funny how the burner posting dropped off after I industrialized the spam...
This code won't work without major modifications since it was part of the larger char-archive scraper project.

210
email-spammer.py Executable file
View File

@ -0,0 +1,210 @@
#!/usr/bin/env python3
import argparse
import itertools
import logging
import os
import random
import re
import sys
import warnings
from pathlib import Path
from queue import Queue
from bs4 import BeautifulSoup
from email_validator import EmailNotValidError, validate_email
from scraper import email_spammer, log
from scraper.email_spammer.phrases import SUBJECT_PHRASES_CYCLE
from scraper.email_spammer.scrape import EMAIL_PATTERN, search_4chan
from scraper.email_spammer.send import EmailWorker
from scraper.email_spammer.templates import FAKE_LGA, NORMAL_EMAIL
from scraper.helpers import resolve_path, select_random_file
DESU_EMAIL_DOMAINS = {
'proton.me': 0,
'protonmail.com': 14,
# 'gmail.com': 13
}
logger: logging.Logger
script_dir = os.path.dirname(os.path.realpath(__file__))
def clean_email(email: str):
email = re.sub(r'\[|\]', '', email)
if re.match(EMAIL_PATTERN, email):
email = email.lower()
email = email.replace('>', '').replace('<', '').replace('[spoiler:lit]', '')
return email
return None
def test_email(email: str):
try:
emailinfo = validate_email(email, check_deliverability=True)
return emailinfo.normalized
except EmailNotValidError as e:
return False
def search_for_proton_emails(text):
soup = BeautifulSoup(text, 'html.parser')
text = soup.find_all("div", {"class": "text"})
found = set()
for item in text:
m = re.findall(r'[^ \n]*?@proton\.me', item.text)
# return found
def main():
global logger
parser = argparse.ArgumentParser(description='')
parser.add_argument('--action', choices=['scrape', 'send', 'both'], help='What to do.')
parser.add_argument('-d', '--debug', action='store_true', help='Enable debug logging.')
parser.add_argument('--pages', default=165, type=int, help='How many pages to scrape on desuarchive.org')
parser.add_argument('--workers-per-email', default=1, type=int, help='How many workers to start per sender email address (Default: 1)')
parser.add_argument('--cache', default='found-emails.txt', help='Path to the cached email file.')
parser.add_argument('--image-dir', default=None, help='Path to the directory containing the images to send.')
# parser.add_argument('--cached-only', action='store_true', help="Only do cached emails, don't search for new ones.")
# parser.add_argument('--scrape-only', action='store_true', help="Only scrape and cache emails.")
parser.add_argument('--test', '-t', action='store_true', help="Send a test email to myself,")
parser.add_argument('--desu', action='store_true', help="Scrape desuarchive.org too.")
parser.add_argument('--send-lga', action='store_true', help="Send the fake LGA email.")
parser.add_argument('--sender', help="Send from this email address.")
parser.add_argument('--target', help="Send to only this email.")
parser.add_argument('--target-count', type=int, help="Send this many emails to the target.")
args = parser.parse_args()
if args.debug:
log_level = logging.DEBUG
else:
log_level = logging.INFO
log.root_logger.init(log_level)
logger = log.root_logger.logger
cached_emails_file = resolve_path(args.cache)
cached_emails_file.touch()
image_dir: Path = None
if args.action in ['send', 'both']:
if not args.image_dir:
logger.critical('Must supply --image-dir when sending emails')
sys.exit(1)
image_dir = resolve_path(args.image_dir)
if not image_dir.is_dir():
logger.critical(f'Image dir does not exist: {image_dir}')
cached_emails = set(cached_emails_file.read_text().splitlines())
found_emails = set()
found_4chan = set()
if not args.action:
logger.critical('Must specify what to do using --action')
sys.exit(1)
logger.info(f'Using cached emails file with {len(cached_emails)} emails: {cached_emails_file}')
if args.action in ['scrape', 'both']:
logger.info('Searching the current /aicg/ thread...')
found_emails_from_4chan = search_4chan()
for email in found_emails_from_4chan:
email = clean_email(email)
if email not in cached_emails:
logger.info(f'NEW: {email}')
found_4chan.add(email)
diff_4chan = found_4chan.difference(cached_emails)
logger.info(f'Found {len(found_emails_from_4chan)} emails from the latest thread(s), added {len(diff_4chan)} new emails.')
if args.desu:
logger.info('Scraping desuarchive.org')
# Have to use selenium since CloudFlare hides email addresses in the raw HTML.
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from webdriver_manager.chrome import ChromeDriverManager
# https://github.com/SeleniumHQ/selenium/issues/9995#issuecomment-987921515
options = Options()
options.binary_location = "/usr/bin/google-chrome"
# options.headless = True
options.add_argument('--headless')
options.add_argument("--window-size=1920,1200")
with warnings.catch_warnings():
# Silence selinium complaining about binary_location like a fucking nigger faggot
warnings.filterwarnings("ignore", category=DeprecationWarning)
driver = webdriver.Chrome(ChromeDriverManager().install(), options=options)
for query, query_max_page in DESU_EMAIL_DOMAINS.items():
if query_max_page > 0:
if args.pages < query_max_page:
max_page = args.pages
else:
max_page = query_max_page
else:
max_page = args.pages
logger.info(f'Searching {max_page} pages for {query}')
for i in range(1, max_page):
url = f'https://desuarchive.org/g/search/text/%22%40{query}%22/page/{i}/'
driver.get(url)
source = driver.page_source
soup = BeautifulSoup(source, 'html.parser')
text = soup.find_all("div", {"class": "text"})
for item in text:
matches = re.findall(rf"[^ \n>(]*?(?:@{'|'.join(DESU_EMAIL_DOMAINS)})", str(item))
for m in matches:
email = clean_email(m)
if email not in cached_emails:
logger.info(f'NEW: {email}')
found_emails.add(email)
driver.quit()
diff = len(found_emails.difference(cached_emails))
logger.info(f'Found {len(found_emails)} emails, added {diff} new emails.')
emails_file_content = found_emails | cached_emails | found_4chan
sorted_file_content = sorted(emails_file_content)
with open(cached_emails_file, 'w') as file:
for email in sorted_file_content:
cleaned = clean_email(email)
if cleaned:
file.write(cleaned + '\n')
logger.debug('Wrote to cache file.')
if args.action in ['send', 'both']:
emails_file_content = found_emails | cached_emails | found_4chan
email_list = [x for x in [*emails_file_content, *emails_file_content, *emails_file_content] if x != '']
random.shuffle(email_list)
if args.test:
if args.target:
args.target = 'yourtestemail@shit.fuck'
else:
# Used to load a million email addresses to send to, but the script was modified to troll LGA and Sam Cole.
email_list = ['youremailaddress@shit.fuck']
email_queue = Queue(maxsize=0)
logger.info(f'Starting {args.workers_per_email} workers and logging into SMTP...')
for i in range(args.workers_per_email):
worker = EmailWorker(email_queue, args.sender if not args.send_lga else 'sam.cole.404media@bestmail.us') # 'lgaburner@cluemail.com')
worker.start()
dir_list = list(Path(image_dir).rglob("*.*"))
if not args.target:
logger.info(f'Sending {len(email_list)} emails...')
for to_email in email_list:
if not args.send_lga:
d = (to_email, next(SUBJECT_PHRASES_CYCLE), NORMAL_EMAIL, select_random_file(image_dir, dir_list))
else:
d = (to_email, 'Chub.ai Interview Request', FAKE_LGA, None) # 'Invite to my discord and a token to our proxy'
email_queue.put(d)
else:
logger.info(f'Sending {args.target_count} emails...')
for i in range(args.target_count):
email_queue.put((args.target, next(SUBJECT_PHRASES_CYCLE), NORMAL_EMAIL, select_random_file(image_dir, dir_list)))
email_queue.join()
if __name__ == '__main__':
main()

View File

View File

@ -0,0 +1,5 @@
BLACKLISTED_DOMAINS = [
"anthropic.com",
"openai.com",
"sourcegraph.com",
]

291
email_spammer/phrases.py Normal file
View File

@ -0,0 +1,291 @@
import itertools
import random
EMAIL_PHRASES = [
'Quit broadcasting your email, ya moron! Revel in the smut, HA-HA-HA!',
'Quit plastering your email, ya moron! Have fun with the smut!',
'Stop sharing your email, you fool! Enjoy the filth!',
'Cease with the email, you nitwit! Revel in the erotica!',
'Halt the email nonsense, you imbecile! Delight in the obscenity!',
'Enough with the email, you dunce! Savor the lewdness!',
'Quit with the email, you simpleton! Relish the indecency!',
'Stop the email, you nincompoop! Enjoy the naughtiness!',
'Enough of your email, you buffoon! Indulge in the smut!',
'Quit the email, you dolt! Revel in the filth!',
'Halt the email, you dimwit! Delight in the erotica!',
'Cease the email, you numbskull! Savor the obscenity!',
'Stop with the email, you blockhead! Relish the lewdness!',
'Enough with the email, you bonehead! Enjoy the indecency!',
'Quit the email, you boob! Revel in the naughtiness!',
'Halt the email, you birdbrain! Delight in the smut!',
'Cease the email, you bozo! Savor the filth!',
'Stop the email, you chowderhead! Relish the erotica!',
'Enough of your email, you clod! Enjoy the obscenity!',
'Quit the email, you cluck! Revel in the lewdness!',
'Halt the email, you cretin! Delight in the indecency!',
'Cease the email, you dodo! Savor the naughtiness!',
'Stop with the email, you dope! Relish the smut!',
'Enough with the email, you dork! Enjoy the filth!',
'Quit the email, you doofus! Revel in the erotica!',
'Halt the email, you dweeb! Delight in the obscenity!',
'Cease the email, you ignoramus! Savor the lewdness!',
'Stop the email, you jackass! Relish the indecency!',
'Enough of your email, you jerk! Enjoy the naughtiness!',
'Quit the email, you knucklehead! Revel in the smut!',
'Halt the email, you lunkhead! Delight in the filth!',
'Cease the email, you meathead! Savor the erotica!',
'Stop with the email, you muttonhead! Relish the obscenity!',
'Enough with the email, you ninny! Enjoy the lewdness!',
'Quit the email, you noodle! Revel in the indecency!',
'Halt the email, you numpty! Delight in the naughtiness!',
'Cease the email, you oaf! Savor the smut!',
'Stop the email, you pillock! Relish the filth!',
'Enough of your email, you pinhead! Enjoy the erotica!',
'Quit the email, you prat! Revel in the obscenity!',
'Halt the email, you putz! Delight in the lewdness!',
'Cease the email, you schmuck! Savor the indecency!',
'Stop with the email, you twit! Relish the naughtiness!',
'Enough with the email, you twerp! Enjoy the smut!',
'Quit the email, you wally! Revel in the filth!',
'Halt the email, you wimp! Delight in the erotica!',
'Cease the email, you yutz! Savor the obscenity!',
'Stop the email, you zany! Relish the lewdness!',
'Enough of your email, you airhead! Enjoy the indecency!',
'Quit the email, you bungler! Revel in the naughtiness!',
'Halt the email, you dunderhead! Delight in the smut!',
'Cease the email, you klutz! Savor the filth!',
'Stop with the email, you muppet! Relish the erotica!',
'Enough with the email, you noddle! Enjoy the obscenity!',
'Quit the email, you pudding-head! Revel in the lewdness!',
'Halt the email, you sap! Delight in the indecency!',
'Cease the email, you scatterbrain! Savor the naughtiness!',
'Stop the email, you tomfool! Relish the smut!',
'Enough of your email, you turkey! Enjoy the filth!',
'Quit the email, you wazzock! Revel in the erotica!',
'Halt the email, you dingbat! Delight in the obscenity!',
'Cease the email, you goof! Savor the lewdness!',
'Stop with the email, you loon! Relish the indecency!',
'Enough with the email, you mooncalf! Enjoy the naughtiness!',
'Quit the email, you ninnyhammer! Revel in the smut!',
'Halt the email, you peabrain! Delight in the filth!',
'Cease the email, you simp! Savor the erotica!',
'Stop the email, you softhead! Relish the obscenity!',
'Enough of your email, you sop! Enjoy the lewdness!',
'Quit the email, you thickhead! Revel in the indecency!',
'Halt the email, you woodenhead! Delight in the naughtiness!',
'Cease the email, you yo-yo! Savor the smut!',
'Stop with the email, you zounderkite! Relish the filth!',
'Enough with the email, you addlepate! Enjoy the erotica!',
'Quit the email, you blunderbuss! Revel in the obscenity!',
'Halt the email, you chucklehead! Delight in the lewdness!',
'Cease the email, you dingleberry! Savor the indecency!',
'Stop the email, you flibbertigibbet! Relish the naughtiness!',
'Enough of your email, you gowk! Enjoy the smut!',
'Quit the email, you jobbernowl! Revel in the filth!',
'Halt the email, you mome! Delight in the erotica!',
'Cease the email, you mumpsimus! Savor the obscenity!',
'Stop with the email, you nabal! Relish the lewdness!',
'Enough with the email, you palooka! Enjoy the indecency!',
'Quit the email, you rattlebrain! Revel in the naughtiness!',
'Halt the email, you schlemiel! Delight in the smut!',
'Cease the email, you schnook! Savor the filth!',
'Stop the email, you shlub! Relish the erotica!',
'Enough of your email, you skelpie-limmer! Enjoy the obscenity!',
'Quit the email, you snollygoster! Revel in the lewdness!',
'Halt the email, you spatchcock! Delight in the indecency!',
'Cease the email, you spoony! Savor the naughtiness!',
'Stop with the email, you wallydraigle! Relish the smut!',
'Enough with the email, you wazzock! Enjoy the filth!',
'Quit the email, you weisenheimer! Revel in the erotica!',
'Halt the email, you whippersnapper! Delight in the obscenity!',
'Cease the email, you wittol! Savor the lewdness!',
'Stop the email, you zooterkins! Relish the indecency!',
'Enough of your email, you gudgeon! Enjoy the naughtiness!',
'Quit the email, you moonling! Revel in the smut!',
'Halt the email, you nidget! Delight in the filth!',
"Hello, just a little fun to brighten your day!",
"Ever seen a this alluring? Enjoy!",
"A little temptation for your eyes only!",
"Just a tantalizing tabby to tickle your fancy!",
"A purr-fectly provocative picture for your pleasure!",
"A little flirtation to spice up your inbox!",
"A captivating to charm your senses!",
"A seductive Siamese for your viewing pleasure!",
"A tantalizing tom to tease your imagination!",
"A bewitching Bengal to beguile your senses!",
"A risqué ragdoll to ruffle your feathers!",
"A provocative Persian to pique your interest!",
"A flirtatious to fire up your day!",
"A sultry Sphinx to stir your senses!",
"A titillating tabby to tantalize your taste!",
"A daring domestic shorthair to delight your day!",
"A coquettish to captivate your curiosity!",
"A seductive Scottish Fold to stimulate your senses!",
"A risqué Russian Blue to rouse your interest!",
"A provocative pussy to perk up your day!",
"A tantalizing Turkish Angora to tickle your fancy!",
"A flirtatious to fuel your fantasies!",
"A captivating Calico to catch your eye!",
"A beguiling Bombay to bewitch your senses!",
"A daring Devon Rex to dazzle your day!",
"An enticing Egyptian Mau to excite your senses!",
"A provocative puss to pique your interest!",
"A saucy Siamese to spice up your day!",
"A titillating Tonkinese to tease your senses!",
"A bewitching Burmese to beguile your imagination!",
"A risqué Ragamuffin to ruffle your routine!",
"A seductive Snowshoe to stir your senses!",
"A tantalizing Tuxedo to tickle your taste!",
"A flirtatious to fire up your fantasies!",
"A captivating Chartreux to charm your senses!",
"A provocative Pixie-bob to perk up your day!",
"A saucy Savannah to spice up your senses!",
"A titillating Turkish Van to tease your imagination!",
"A bewitching British Shorthair to beguile your senses!",
"A risqué Russian White to rouse your interest!",
"A seductive Selkirk Rex to stimulate your senses!",
"A tantalizing Toyger to tickle your fancy!",
"A flirtatious to fuel your day!",
"A captivating Cymric to catch your eye!",
"A provocative Peterbald to pique your interest!",
"A saucy Singapura to spice up your day!",
"A titillating Tabby to tease your senses!",
"A bewitching Bengal to beguile your imagination!",
"A risqué Ragdoll to ruffle your routine!",
"A seductive Sphynx to stir your senses!",
]
random.shuffle(EMAIL_PHRASES)
EMAIL_PHRASES_CYCLE = itertools.cycle(EMAIL_PHRASES)
SUBJECT_PHRASES = [
"YOUR LATEST AI PROXY KEY",
"YOUR UPDATED AI PROXY KEY",
"YOUR FRESH AI PROXY KEY",
"YOUR RECENT AI PROXY KEY",
"YOUR REVISED AI PROXY KEY",
"YOUR BRAND-NEW AI PROXY KEY",
"YOUR CURRENT AI PROXY KEY",
"YOUR MODERN AI PROXY KEY",
"YOUR LATEST GENERATION AI PROXY KEY",
"YOUR NEWLY ISSUED AI PROXY KEY",
"YOUR ADVANCED AI PROXY KEY",
"YOUR INNOVATIVE AI PROXY KEY",
"YOUR FRESHLY GENERATED AI PROXY KEY",
"YOUR JUST-RELEASED AI PROXY KEY",
"YOUR NEWEST AI PROXY KEY",
"YOUR STATE-OF-THE-ART AI PROXY KEY",
"YOUR JUST-UPDATED AI PROXY KEY",
"YOUR RECENTLY ACQUIRED AI PROXY KEY",
"YOUR LATEST EDITION AI PROXY KEY",
"YOUR NEWLY UPDATED AI PROXY KEY",
"Your Exclusive AI Proxy API Key is Here",
"Unlock the Power of AI with Your New API Key",
"Welcome to the Future: Your AI Proxy API Key",
"Start Your AI Journey with Your API Key",
"Your AI Proxy API Key: The Gateway to Innovation",
"Access Granted: Your AI Proxy API Key",
"Your AI Proxy API Key: Unleashing Potential",
"Get Started with Your AI Proxy API Key",
"Unleash Your Wild Side with This Fantasy",
"Purr-fectly Sensual Surprise Awaits You",
"Tease to Spice Up Your Day",
"Lover's Secret Desire Revealed",
"Unveiling the Sensual Side of Art",
"Image Like You've Never Seen Before",
"Purr-fectly Erotic Surprise for You",
"Fantasy to Ignite Your Senses",
"Image to Stir Your Wildest Dreams",
"Tease to Tickle Your Fancy",
"Lover's Erotic Dream Come True",
"Fantasy to Spice Up Your Inbox",
"Image to Ignite Your Passion",
"Tease to Set Your Heart Racing",
"Lover's Erotic Surprise",
"Fantasy to Stir Your Imagination",
"Image to Set Your Pulse Racing",
"Tease to Ignite Your Desire",
"Lover's Erotic Fantasy Revealed",
"Fantasy to Tickle Your Senses",
"Image to Stir Your Desire",
"Tease to Ignite Your Imagination",
"Lover's Erotic Dream Unveiled",
"Fantasy to Set Your Heart Aflutter",
"Image to Ignite Your Fantasy",
"Tease to Stir Your Passion",
"Lover's Erotic Surprise Awaits",
"Fantasy to Ignite Your Senses",
"Image to Stir Your Fantasy",
"Tease to Ignite Your Passion",
"Lover's Erotic Dream Awaits",
"Fantasy to Tickle Your Imagination",
"Image to Ignite Your Desire",
"Tease to Stir Your Senses",
"Lover's Erotic Surprise Unveiled",
"Fantasy to Set Your Pulse Racing",
"Image to Ignite Your Imagination",
"Tease to Stir Your Desire",
"Lover's Erotic Dream Revealed",
"Fantasy to Ignite Your Heart",
"Image to Stir Your Imagination",
"Tease to Ignite Your Senses",
"Lover's Erotic Surprise Revealed",
"Fantasy to Tickle Your Desire",
"Image to Ignite Your Dreams",
"Tease to Stir Your Heart",
"Lover's Erotic Dream Unveiled",
"Fantasy to Ignite Your Fantasy",
"Image to Stir Your Senses",
"Tease to Ignite Your Heart",
"Lover's Erotic Surprise Awaits",
"Fantasy to Tickle Your Heart",
"Image to Ignite Your Senses",
"Tease to Stir Your Fantasy",
"Lover's Erotic Dream Awaits",
"Fantasy to Ignite Your Desire",
"Image to Stir Your Heart",
"Tease to Ignite Your Fantasy",
"Lover's Erotic Surprise Unveiled",
"Fantasy to Tickle Your Senses",
"Image to Ignite Your Heart",
"Tease to Stir Your Imagination",
"Lover's Erotic Dream Revealed",
"Fantasy to Ignite Your Imagination",
"Image to Stir Your Desire",
"Tease to Ignite Your Imagination",
"Lover's Erotic Surprise Awaits",
"Fantasy to Tickle Your Fantasy",
"Image to Ignite Your Passion",
"Tease to Stir Your Senses",
"Lover's Erotic Dream Unveiled",
"Fantasy to Ignite Your Senses",
"Image to Stir Your Passion",
"Tease to Ignite Your Desire",
"Lover's Erotic Surprise Revealed",
"Fantasy to Tickle Your Imagination",
"Image to Ignite Your Desire",
"Tease to Stir Your Imagination",
"Lover's Erotic Dream Awaits",
"Fantasy to Ignite Your Passion",
"Image to Stir Your Fantasy",
"Tease to Ignite Your Senses",
"Lover's Erotic Surprise Unveiled",
"Fantasy to Tickle Your Desire",
"Image to Ignite Your Imagination",
"Tease to Stir Your Desire",
"Lover's Erotic Dream Revealed",
"Fantasy to Ignite Your Fantasy",
"Image to Stir Your Senses",
"Tease to Ignite Your Heart",
"Lover's Erotic Surprise Awaits",
"Fantasy to Tickle Your Senses",
"Image to Ignite Your Fantasy",
"Tease to Stir Your Passion",
"Lover's Erotic Dream Unveiled",
"Fantasy to Ignite Your Desire",
"Image to Stir Your Imagination",
"Tease to Ignite Your Passion",
"Lover's Erotic Surprise Revealed",
"Fantasy to Tickle Your Passion",
]
random.shuffle(SUBJECT_PHRASES)
SUBJECT_PHRASES_CYCLE = itertools.cycle(SUBJECT_PHRASES)

44
email_spammer/scrape.py Normal file
View File

@ -0,0 +1,44 @@
import re
import unicodedata
import requests
from scraper.email_spammer.blacklisted import BLACKLISTED_DOMAINS
EMAIL_PATTERN = re.compile(r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b')
def remove_strikethrough(s):
return ''.join(c for c in s if not unicodedata.combining(c))
def search_4chan():
url = "https://a.4cdn.org/g/catalog.json"
response = requests.get(url)
data = response.json()
email_addresses = []
for page in data:
for thread in page['threads']:
# Check if the thread has a subject and if '/aicg/' is in the subject
if 'sub' in thread and '/aicg/' in thread['sub']:
thread_id = thread['no']
thread_url = f"https://a.4cdn.org/g/thread/{thread_id}.json"
thread_response = requests.get(thread_url)
thread_data = thread_response.json()
# Loop through each post in the thread
for post in thread_data['posts']:
# Check if the post has a comment
if 'com' in post:
cleaned_comment = remove_strikethrough(post['com'])
# If so, find all email addresses in the comment
emails = re.findall(EMAIL_PATTERN, cleaned_comment)
for email in emails:
email = email.lower()
email_domain = email.split('@')[1]
# if email.endswith('proton.me') or email.endswith('protonmail.com') or email.endswith('cock.il'):
if email_domain not in BLACKLISTED_DOMAINS:
email_addresses.extend([email])
return email_addresses

82
email_spammer/send.py Normal file
View File

@ -0,0 +1,82 @@
import itertools
import random
import smtplib
import threading
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from scraper.log import root_logger
logger = root_logger.get_child('EMAIL_SENDER')
class EmailWorker(threading.Thread):
def __init__(self, queue, email_sender):
threading.Thread.__init__(self)
self.queue = queue
self.email_sender = email_sender
self.server = None
self.daemon = True
self.login()
def run(self):
while True:
to, subject, msg, img_path = self.queue.get()
try:
self.send_email(to, subject, msg, img_path)
finally:
self.queue.task_done()
def login(self):
try:
self.server = smtplib.SMTP_SSL('smtp.email.com', 465)
self.server.login("youremailaddress@shit.fuck", "password123")
logger.info(f'{self.email_sender} logged in to SMTP')
except smtplib.SMTPAuthenticationError as e:
logger.error(f'Failed to login - {e.__class__.__name__}. SMTP Code: {e.smtp_code}. Error: {e.smtp_error.decode()}')
return None
except Exception as e:
logger.error(f'Failed to login - {e.__class__.__name__}: {e}')
return None
def send_email(self, to, subject, msg, img_path):
msgRoot = MIMEMultipart('related')
msgRoot['Subject'] = subject
msgRoot['From'] = self.email_sender
msgRoot['To'] = to
msgRoot.preamble = 'This is a multi-part message in MIME format.'
msgAlternative = MIMEMultipart('alternative')
msgRoot.attach(msgAlternative)
msgText = MIMEText('This is the alternative plain text message.')
msgAlternative.attach(msgText)
if img_path:
img_html = '<br><img src="cid:image1"><br>'
else:
img_html = ''
msgText = MIMEText(f'{msg}{img_html}', 'html')
msgAlternative.attach(msgText)
if img_path:
with open(img_path, 'rb') as fp:
msgImage = MIMEImage(fp.read())
msgImage.add_header('Content-ID', '<image1>')
msgRoot.attach(msgImage)
logger.debug(f'Sending to {to} from {self.email_sender}')
try:
if not self.server.noop()[0] == 250:
self.login()
result = self.server.sendmail(self.email_sender, to, msgRoot.as_string())
self.server.ehlo() # reset the SMTP session
logger.info(f'Sent to {to} from {self.email_sender}')
return result
except smtplib.SMTPDataError as e:
if e.smtp_code != 250:
logger.error(f'Failed to send email to {to} - {e.__class__.__name__}. SMTP Code: {e.smtp_code}. Error: {e.smtp_error.decode()}')
except Exception as e:
logger.error(f'Failed to send email to {to} - {e.__class__.__name__}: {e}')
return

View File

@ -0,0 +1,43 @@
from uuid import uuid4
from scraper.email_spammer.phrases import EMAIL_PHRASES_CYCLE
NORMAL_EMAIL = f'<p>{next(EMAIL_PHRASES_CYCLE)}</p><br><p style="font-size: 9pt;font-style: italic;">If you are not associated with /aicg/ you can ignore this email.</p><br>'
# FAKE_LGA = f"""
# <p>
# Hello, this is Long Game Anon. I saw you posting on /aicg/ and want to invite you to my discord:<br>
# https://discord.com/invite/UkfGrsFe9D
# </p>
# <p>
# We are all very friendly here and love to see new faces, talk about chatbots and raiding /aicg/!<br>
# Have a cute gen of my newest LORA, you can download it here and become a sovlfull botmakie: https://civitai.com/models/124573?modelVersionId=136041
# </p>
#
# <p>
# Here is a private user_token for our discord proxy: {uuid4()}<br>
# You find the link there.
# </p>
#
# <p>Love Long Game Anon (funkytism) (yes I am jealous of wster)</p>"""
FAKE_LGA = f"""Hi there! I'm Sam, a journalist at 404 Media where I cover tech, AI, and sexuality. I'm working on a story about people who run LLMs locally to do erotic roleplay, and saw that you make ERP characters on Chub.ai. I've written often about companion chatbots, and recently wrote about the online communities that are using generative AI to make new kinds of porn.<br>
I'd love to ask you a few questions, if you're interested and available. If so, here's what I'm looking to learn:<br>
1) How did you first get started making characters? What was your first one, and do you have a favorite?<br>
2) Could you walk me through the process of creating a character, as if you were explaining to someone who knows nothing about these sites or how they work?<br>
3) Do you do commissions, or make any money on characters?<br>
4) Why do you think running your own LLM chatbot locally is more appealing to people, versus using something like an AI companion app (like Replika etc) that's easier but maybe more limited? Is there more freedom in the conversations, or customization, or privacy?<br>
5) Overall, what do people get out of interacting with erotic/NSFW/NSFL chat characters?<br>
6) How would you like to be cited, and what are your pronouns? (Anonymous is fine, or you can use a username)<br>
Thanks so much for your time, and any insights you might be able to provide! If you have thoughts on the above, feel free to send via email, or let me know if you prefer texting or a call. I'm aiming to write this story on Tuesday 9/19, if you have time to send thoughts in the next day or so.<br>
Best,<br>
-Sam"""

2
send-emails.sh Executable file
View File

@ -0,0 +1,2 @@
#!/bin/bash
./venv/bin/python email-spammer.py --cache found-emails.txt --image-dir ./catfox --action both