Repository: Winneon/makeswordclouds
Branch: master
Commit: 40baa8123258
Files: 7
Total size: 9.0 KB
Directory structure:
gitextract_trafy89f/
├── .gitignore
├── README.md
├── common/
│ ├── __main__.py
│ ├── cloud.py
│ ├── config.py
│ └── reddit.py
└── requirements.txt
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
praw.ini
*.json
*.pyc
*.ttf
*.otf
================================================
FILE: README.md
================================================
makeswordclouds
---------------
A word cloud bot, currently running under /u/makeswordcloudsagain. The current version is v2.0.1.
================================================
FILE: common/__main__.py
================================================
import os
import sys
import time
import traceback
import praw
import config
import reddit
import cloud
class Main:
def __init__(self):
self.version = "2.0.1"
self.c = config.Config("config.json",
{
"id": "<IMGUR_CLIENT_ID>",
"min": 100
}
)
self.d = config.Config("database.json",
{
"banned": [],
"replied": []
}
)
print "> Started makeswordclouds, version " + self.version
self.r = reddit.Reddit(self.c, self.d, praw.Reddit("makeswordclouds: running under version " + self.version))
def legwork(self, submission, requester=None):
prepend = ""
text = self.r.flatten(submission)
cloud.generate(text)
upload = cloud.upload(self.c.get()["id"])
if requester != None:
prepend = "**Summoned by /u/" + requester + ".** \n"
content = (
prepend +
"Here is a word cloud of every comment in this thread, as of this time: " + upload
)
return self.r.comment(submission, content)
def loop(self):
try:
while True:
print "> Beginning mailbox check."
for mail in self.r.mailbox():
try:
url = self.legwork(mail.submission.id, requester=mail.message.author.name)
self.r.message(
mail.message.author.name,
"Your word cloud has been created.",
"Congratulations! Your word cloud can be found here: " + url
)
except reddit.BannedSubredditError as e:
try:
raise reddit.BannedSubredditError(
resp=reddit.ErrorResponse(self.r, mail.message.author.name),
log=False
)
except:
pass
except Exception as e:
self.r.message(
mail.message.author.name,
"A problem arose creating your word cloud.",
"An internal error occured. I am unable to furthur explain the issue. Contact the developer if you want to know the full cause."
)
print "> An error occrred while creating the word cloud."
print "> Beginning post check."
for post in self.r.posts():
try:
self.legwork(post)
except reddit.BannedSubredditError:
pass
print "> Sleeping."
self.d.save()
time.sleep(120)
except KeyboardInterrupt:
print "> Terminated."
self.d.save()
except:
print "> An error occured. Restarting."
traceback.print_exc(file=sys.stdout)
self.loop()
if __name__ == "__main__":
Main().loop()
================================================
FILE: common/cloud.py
================================================
import os
import random
import numpy
import pyimgur
from PIL import Image
from wordcloud import WordCloud, ImageColorGenerator
"""
mask = numpy.array(Image.open(path.join(path.dirname(path.dirname(__file__)), "resources") + "/earth.png"))
cloud = WordCloud(font_path=path.join(path.dirname(path.dirname(__file__)), "resources") + "/fonts/quartzo.ttf", background_color="#1A1A1A", mask=mask, scale=2, max_words=None, relative_scaling=0.5, prefer_horizontal=1.0)
cloud.generate(r.flatten("4d1yv4"))
image_colors = ImageColorGenerator(mask)
cloud.recolor(color_func=image_colors)
cloud.to_file("cloud.png")
"""
def generate(text):
resources = os.path.join(os.path.dirname(os.path.dirname(__file__)), "resources")
masks = os.path.join(resources, "masks")
fonts = os.path.join(resources, "fonts")
mask = numpy.array(Image.open(os.path.join(masks, random.choice(os.listdir(masks)))))
cloud = WordCloud(
font_path=os.path.join(fonts, random.choice(os.listdir(fonts))),
background_color="#1A1A1A",
mask=mask,
scale=2,
max_words=None,
relative_scaling=0.5,
prefer_horizontal=1.0
)
cloud.generate(text)
image_colors = ImageColorGenerator(mask)
cloud.recolor(color_func=image_colors)
cloud.to_file("cloud.png")
def upload(client):
imgur = pyimgur.Imgur(client)
upload = imgur.upload_image("cloud.png")
os.remove("cloud.png")
return upload.link
================================================
FILE: common/config.py
================================================
import json
import re
from os import path
class Config:
def __init__(self, name, template):
self.config_path = path.dirname(path.dirname(__file__)) + name
if not path.isfile(self.config_path):
self._write(self.config_path, template)
self.config = json.loads(open(self.config_path).read())
def _write(self, filepath, template):
with open(filepath, "w") as w:
w.write(json.dumps(template, indent=4, sort_keys=True))
def get(self):
return self.config
def save(self):
self._write(self.config_path, self.config)
================================================
FILE: common/reddit.py
================================================
import sys
import re
import traceback
import praw
class ErrorResponse:
def __init__(self, reddit, recipient):
self.reddit = reddit
self.recipient = recipient
class MakesWordCloudsErrorDummy(Exception):
def __init__(self, resp, message, log):
Exception.__init__(self, message)
if resp == None:
self.makeswordclouds_cont = True
else:
resp.reddit.message(
resp.recipient,
"A problem arose creating your word cloud.",
message
)
if log:
print "> " + message
class InvalidPermalinkError(MakesWordCloudsErrorDummy):
def __init__(self, resp=None, message="The permalink is invalid.", log=True):
MakesWordCloudsErrorDummy.__init__(self, resp, message, log)
class PreexistingCloudError(MakesWordCloudsErrorDummy):
def __init__(self, resp=None, message="The permalink already has a word cloud in its comments.", log=True):
MakesWordCloudsErrorDummy.__init__(self, resp, message, log)
class BannedSubredditError(MakesWordCloudsErrorDummy):
def __init__(self, resp=None, message="The subreddit is on the blacklist.", log=True):
MakesWordCloudsErrorDummy.__init__(self, resp, message, log)
class ValidMail:
def __init__(self, submission, message):
self.submission = submission
self.message = message
class Reddit:
def __init__(self, config, database, reddit):
self.config = config
self.database = database
self.reddit = reddit
self.reddit.refresh_access_information()
self.footer = (
"---\n\n"
"[^[source ^code]](https://github.com/Winneon/makeswordclouds) "
"[^[contact ^developer]](https://reddit.com/user/WinneonSword) "
"[^[request ^word ^cloud]](https://www.reddit.com/message/compose/?to=makeswordcloudsagain&subject=Requesting%20word%20cloud.&message=%2Bcreate%20REPLACE_THIS_WITH_A_REDDIT_POST_PERMALINK)"
)
print "> Authenticated as /u/" + self.reddit.get_me().name
def _format_comment(self, text):
return text + "\n\n" + self.footer
def flatten(self, submission):
submission = self.reddit.get_submission(submission_id=submission, comment_limit=None)
flattened = praw.helpers.flatten_tree(submission.comments)
text_mass = ""
for comment in flattened:
if isinstance(comment, praw.objects.Comment):
# i hate these 3 lines of code but i'm too lazy to redo them
body = re.sub(r"https?://(?:www\.)?[A-z0-9-]+\.[A-z\.]+[\?A-z0-9&=/]*", "", comment.body, flags=re.IGNORECASE)
body = re.sub(r"<.*?>|&.*?;|/.+?(?= )|/.*", "", body)
text_mass = text_mass + body + "\n"
return text_mass
def mailbox(self):
collected = []
for message in self.reddit.get_unread(limit=None):
if "+create " in message.body:
submission = None
try:
permalink = message.body.replace("+create ", "")
if "redd.it" in permalink:
short = permalink.replace("http://redd.it/", "").replace("https://redd.it/", "")
submission = self.reddit.get_submission(submission_id=short)
else:
submission = self.reddit.get_submission(url=permalink)
except:
pass
try:
if submission == None:
raise InvalidPermalinkError(resp=ErrorResponse(self, message.author.name))
elif submission.id in self.database.get()["replied"]:
raise PreexistingCloudError(resp=ErrorResponse(self, message.author.name))
elif submission.subreddit.display_name.lower() in self.database.get()["banned"]:
raise BannedSubredditError(resp=ErrorResponse(self, message.author.name))
else:
collected.append(ValidMail(submission, message))
except MakesWordCloudsErrorDummy:
pass
message.mark_as_read()
return collected
def posts(self):
collected = []
for post in self.reddit.get_subreddit("all").get_hot(limit=200):
subreddit = post.subreddit.display_name
limit = int(self.config.get()["min"])
banned = self.database.get()["banned"]
replied = self.database.get()["replied"]
if subreddit.lower() not in banned and post.id not in replied and post.num_comments >= limit:
collected.append(post.id)
return collected
def comment(self, submission, message):
submission = self.reddit.get_submission(submission_id=submission)
try:
url = submission.add_comment(self._format_comment(message)).permalink
self.database.get()["replied"].append(submission.id)
print "> Comment posted. "
print "> " + url
return url
except praw.errors.Forbidden as e:
subreddit = submission.subreddit.display_name.lower()
banned = self.database.get()["banned"]
if subreddit not in banned:
banned.append(subreddit)
raise BannedSubredditError()
except:
print "> Failed to post comment."
self.database.get()["replied"].append(submission.id)
traceback.print_exc(file=sys.stdout)
def message(self, recipient, subject, message):
self.reddit.send_message(recipient, subject, self._format_comment(message))
================================================
FILE: requirements.txt
================================================
image
numpy
pyimgur
praw
wordcloud
gitextract_trafy89f/ ├── .gitignore ├── README.md ├── common/ │ ├── __main__.py │ ├── cloud.py │ ├── config.py │ └── reddit.py └── requirements.txt
SYMBOL INDEX (31 symbols across 4 files)
FILE: common/__main__.py
class Main (line 12) | class Main:
method __init__ (line 13) | def __init__(self):
method legwork (line 33) | def legwork(self, submission, requester=None):
method loop (line 50) | def loop(self):
FILE: common/cloud.py
function generate (line 24) | def generate(text):
function upload (line 48) | def upload(client):
FILE: common/config.py
class Config (line 6) | class Config:
method __init__ (line 7) | def __init__(self, name, template):
method _write (line 15) | def _write(self, filepath, template):
method get (line 19) | def get(self):
method save (line 22) | def save(self):
FILE: common/reddit.py
class ErrorResponse (line 7) | class ErrorResponse:
method __init__ (line 8) | def __init__(self, reddit, recipient):
class MakesWordCloudsErrorDummy (line 12) | class MakesWordCloudsErrorDummy(Exception):
method __init__ (line 13) | def __init__(self, resp, message, log):
class InvalidPermalinkError (line 28) | class InvalidPermalinkError(MakesWordCloudsErrorDummy):
method __init__ (line 29) | def __init__(self, resp=None, message="The permalink is invalid.", log...
class PreexistingCloudError (line 32) | class PreexistingCloudError(MakesWordCloudsErrorDummy):
method __init__ (line 33) | def __init__(self, resp=None, message="The permalink already has a wor...
class BannedSubredditError (line 36) | class BannedSubredditError(MakesWordCloudsErrorDummy):
method __init__ (line 37) | def __init__(self, resp=None, message="The subreddit is on the blackli...
class ValidMail (line 40) | class ValidMail:
method __init__ (line 41) | def __init__(self, submission, message):
class Reddit (line 45) | class Reddit:
method __init__ (line 46) | def __init__(self, config, database, reddit):
method _format_comment (line 62) | def _format_comment(self, text):
method flatten (line 65) | def flatten(self, submission):
method mailbox (line 79) | def mailbox(self):
method posts (line 113) | def posts(self):
method comment (line 128) | def comment(self, submission, message):
method message (line 152) | def message(self, recipient, subject, message):
Condensed preview — 7 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (11K chars).
[
{
"path": ".gitignore",
"chars": 33,
"preview": "praw.ini\n*.json\n*.pyc\n*.ttf\n*.otf"
},
{
"path": "README.md",
"chars": 130,
"preview": "makeswordclouds\n---------------\n\nA word cloud bot, currently running under /u/makeswordcloudsagain. The current version "
},
{
"path": "common/__main__.py",
"chars": 2334,
"preview": "import os\nimport sys\nimport time\nimport traceback\n\nimport praw\n\nimport config\nimport reddit\nimport cloud\n\nclass Main:\n\td"
},
{
"path": "common/cloud.py",
"chars": 1376,
"preview": "import os\nimport random\n\nimport numpy\nimport pyimgur\n\nfrom PIL import Image\nfrom wordcloud import WordCloud, ImageColorG"
},
{
"path": "common/config.py",
"chars": 535,
"preview": "import json\nimport re\n\nfrom os import path\n\nclass Config:\n\tdef __init__(self, name, template):\n\t\tself.config_path = path"
},
{
"path": "common/reddit.py",
"chars": 4816,
"preview": "import sys\nimport re\nimport traceback\n\nimport praw\n\nclass ErrorResponse:\n\tdef __init__(self, reddit, recipient):\n\t\tself."
},
{
"path": "requirements.txt",
"chars": 34,
"preview": "image\nnumpy\npyimgur\npraw\nwordcloud"
}
]
About this extraction
This page contains the full source code of the Winneon/makeswordclouds GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 7 files (9.0 KB), approximately 2.5k tokens, and a symbol index with 31 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.