[
  {
    "path": ".gitignore",
    "content": "praw.ini\n*.json\n*.pyc\n*.ttf\n*.otf"
  },
  {
    "path": "README.md",
    "content": "makeswordclouds\n---------------\n\nA word cloud bot, currently running under /u/makeswordcloudsagain. The current version is v2.0.1."
  },
  {
    "path": "common/__main__.py",
    "content": "import os\nimport sys\nimport time\nimport traceback\n\nimport praw\n\nimport config\nimport reddit\nimport cloud\n\nclass Main:\n\tdef __init__(self):\n\t\tself.version = \"2.0.1\"\n\n\t\tself.c = config.Config(\"config.json\",\n\t\t\t{\n\t\t\t\t\"id\": \"<IMGUR_CLIENT_ID>\",\n\t\t\t\t\"min\": 100\n\t\t\t}\n\t\t)\n\n\t\tself.d = config.Config(\"database.json\",\n\t\t\t{\n\t\t\t\t\"banned\": [],\n\t\t\t\t\"replied\": []\n\t\t\t}\n\t\t)\n\n\t\tprint \"> Started makeswordclouds, version \" + self.version\n\t\tself.r = reddit.Reddit(self.c, self.d, praw.Reddit(\"makeswordclouds: running under version \" + self.version))\n\n\tdef legwork(self, submission, requester=None):\n\t\tprepend = \"\"\n\t\ttext = self.r.flatten(submission)\n\n\t\tcloud.generate(text)\n\t\tupload = cloud.upload(self.c.get()[\"id\"])\n\n\t\tif requester != None:\n\t\t\tprepend = \"**Summoned by /u/\" + requester + \".**  \\n\"\n\n\t\tcontent = (\n\t\t\tprepend +\n\t\t\t\"Here is a word cloud of every comment in this thread, as of this time: \" + upload\n\t\t)\n\n\t\treturn self.r.comment(submission, content)\n\n\tdef loop(self):\n\t\ttry:\n\t\t\twhile True:\n\t\t\t\tprint \"> Beginning mailbox check.\"\n\n\t\t\t\tfor mail in self.r.mailbox():\n\t\t\t\t\ttry:\n\t\t\t\t\t\turl = self.legwork(mail.submission.id, requester=mail.message.author.name)\n\n\t\t\t\t\t\tself.r.message(\n\t\t\t\t\t\t\tmail.message.author.name,\n\t\t\t\t\t\t\t\"Your word cloud has been created.\",\n\t\t\t\t\t\t\t\"Congratulations! Your word cloud can be found here: \" + url\n\t\t\t\t\t\t)\n\t\t\t\t\texcept reddit.BannedSubredditError as e:\n\t\t\t\t\t\ttry:\n\t\t\t\t\t\t\traise reddit.BannedSubredditError(\n\t\t\t\t\t\t\t\tresp=reddit.ErrorResponse(self.r, mail.message.author.name),\n\t\t\t\t\t\t\t\tlog=False\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\texcept:\n\t\t\t\t\t\t\tpass\n\t\t\t\t\texcept Exception as e:\n\t\t\t\t\t\tself.r.message(\n\t\t\t\t\t\t\tmail.message.author.name,\n\t\t\t\t\t\t\t\"A problem arose creating your word cloud.\",\n\t\t\t\t\t\t\t\"An internal error occured. I am unable to furthur explain the issue. Contact the developer if you want to know the full cause.\"\n\t\t\t\t\t\t)\n\n\t\t\t\t\t\tprint \"> An error occrred while creating the word cloud.\"\n\n\t\t\t\tprint \"> Beginning post check.\"\n\n\t\t\t\tfor post in self.r.posts():\n\t\t\t\t\ttry:\n\t\t\t\t\t\tself.legwork(post)\n\t\t\t\t\texcept reddit.BannedSubredditError:\n\t\t\t\t\t\tpass\n\n\t\t\t\tprint \"> Sleeping.\"\n\n\t\t\t\tself.d.save()\n\t\t\t\ttime.sleep(120)\n\t\texcept KeyboardInterrupt:\n\t\t\tprint \"> Terminated.\"\n\t\t\tself.d.save()\n\t\texcept:\n\t\t\tprint \"> An error occured. Restarting.\"\n\n\t\t\ttraceback.print_exc(file=sys.stdout)\n\t\t\tself.loop()\n\nif __name__ == \"__main__\":\n\tMain().loop()"
  },
  {
    "path": "common/cloud.py",
    "content": "import os\nimport random\n\nimport numpy\nimport pyimgur\n\nfrom PIL import Image\nfrom wordcloud import WordCloud, ImageColorGenerator\n\n\"\"\"\n\nmask = numpy.array(Image.open(path.join(path.dirname(path.dirname(__file__)), \"resources\") + \"/earth.png\"))\ncloud = 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)\n\ncloud.generate(r.flatten(\"4d1yv4\"))\n\nimage_colors = ImageColorGenerator(mask)\ncloud.recolor(color_func=image_colors)\n\ncloud.to_file(\"cloud.png\")\n\n\"\"\"\n\ndef generate(text):\n\tresources = os.path.join(os.path.dirname(os.path.dirname(__file__)), \"resources\")\n\tmasks = os.path.join(resources, \"masks\")\n\tfonts = os.path.join(resources, \"fonts\")\n\n\tmask = numpy.array(Image.open(os.path.join(masks, random.choice(os.listdir(masks)))))\n\n\tcloud = WordCloud(\n\t\tfont_path=os.path.join(fonts, random.choice(os.listdir(fonts))),\n\t\tbackground_color=\"#1A1A1A\",\n\t\tmask=mask,\n\t\tscale=2,\n\t\tmax_words=None,\n\t\trelative_scaling=0.5,\n\t\tprefer_horizontal=1.0\n\t)\n\n\tcloud.generate(text)\n\n\timage_colors = ImageColorGenerator(mask)\n\tcloud.recolor(color_func=image_colors)\n\n\tcloud.to_file(\"cloud.png\")\n\ndef upload(client):\n\timgur = pyimgur.Imgur(client)\n\tupload = imgur.upload_image(\"cloud.png\")\n\tos.remove(\"cloud.png\")\n\n\treturn upload.link"
  },
  {
    "path": "common/config.py",
    "content": "import json\nimport re\n\nfrom os import path\n\nclass Config:\n\tdef __init__(self, name, template):\n\t\tself.config_path = path.dirname(path.dirname(__file__)) + name\n\n\t\tif not path.isfile(self.config_path):\n\t\t\tself._write(self.config_path, template)\n\n\t\tself.config = json.loads(open(self.config_path).read())\n\n\tdef _write(self, filepath, template):\n\t\twith open(filepath, \"w\") as w:\n\t\t\tw.write(json.dumps(template, indent=4, sort_keys=True))\n\n\tdef get(self):\n\t\treturn self.config\n\n\tdef save(self):\n\t\tself._write(self.config_path, self.config)"
  },
  {
    "path": "common/reddit.py",
    "content": "import sys\nimport re\nimport traceback\n\nimport praw\n\nclass ErrorResponse:\n\tdef __init__(self, reddit, recipient):\n\t\tself.reddit = reddit\n\t\tself.recipient = recipient\n\nclass MakesWordCloudsErrorDummy(Exception):\n\tdef __init__(self, resp, message, log):\n\t\tException.__init__(self, message)\n\n\t\tif resp == None:\n\t\t\tself.makeswordclouds_cont = True\n\t\telse:\n\t\t\tresp.reddit.message(\n\t\t\t\tresp.recipient,\n\t\t\t\t\"A problem arose creating your word cloud.\",\n\t\t\t\tmessage\n\t\t\t)\n\n\t\tif log:\n\t\t\tprint \"> \" + message\n\nclass InvalidPermalinkError(MakesWordCloudsErrorDummy):\n\tdef __init__(self, resp=None, message=\"The permalink is invalid.\", log=True):\n\t\tMakesWordCloudsErrorDummy.__init__(self, resp, message, log)\n\nclass PreexistingCloudError(MakesWordCloudsErrorDummy):\n\tdef __init__(self, resp=None, message=\"The permalink already has a word cloud in its comments.\", log=True):\n\t\tMakesWordCloudsErrorDummy.__init__(self, resp, message, log)\n\nclass BannedSubredditError(MakesWordCloudsErrorDummy):\n\tdef __init__(self, resp=None, message=\"The subreddit is on the blacklist.\", log=True):\n\t\tMakesWordCloudsErrorDummy.__init__(self, resp, message, log)\n\nclass ValidMail:\n\tdef __init__(self, submission, message):\n\t\tself.submission = submission\n\t\tself.message = message\n\nclass Reddit:\n\tdef __init__(self, config, database, reddit):\n\t\tself.config = config\n\t\tself.database = database\n\n\t\tself.reddit = reddit\n\t\tself.reddit.refresh_access_information()\n\n\t\tself.footer = (\n\t\t\t\"---\\n\\n\"\n\t\t\t\"[^[source ^code]](https://github.com/Winneon/makeswordclouds) \"\n\t\t\t\"[^[contact ^developer]](https://reddit.com/user/WinneonSword) \"\n\t\t\t\"[^[request ^word ^cloud]](https://www.reddit.com/message/compose/?to=makeswordcloudsagain&subject=Requesting%20word%20cloud.&message=%2Bcreate%20REPLACE_THIS_WITH_A_REDDIT_POST_PERMALINK)\"\n\t\t)\n\n\t\tprint \"> Authenticated as /u/\" + self.reddit.get_me().name\n\n\tdef _format_comment(self, text):\n\t\treturn text + \"\\n\\n\" + self.footer\n\n\tdef flatten(self, submission):\n\t\tsubmission = self.reddit.get_submission(submission_id=submission, comment_limit=None)\n\t\tflattened = praw.helpers.flatten_tree(submission.comments)\n\t\ttext_mass = \"\"\n\n\t\tfor comment in flattened:\n\t\t\tif isinstance(comment, praw.objects.Comment):\n\t\t\t\t# i hate these 3 lines of code but i'm too lazy to redo them\n\t\t\t\tbody = re.sub(r\"https?://(?:www\\.)?[A-z0-9-]+\\.[A-z\\.]+[\\?A-z0-9&=/]*\", \"\", comment.body, flags=re.IGNORECASE)\n\t\t\t\tbody = re.sub(r\"<.*?>|&.*?;|/.+?(?= )|/.*\", \"\", body)\n\t\t\t\ttext_mass = text_mass + body + \"\\n\"\n\n\t\treturn text_mass\n\n\tdef mailbox(self):\n\t\tcollected = []\n\n\t\tfor message in self.reddit.get_unread(limit=None):\n\t\t\tif \"+create \" in message.body:\n\t\t\t\tsubmission = None\n\n\t\t\t\ttry:\n\t\t\t\t\tpermalink = message.body.replace(\"+create \", \"\")\n\n\t\t\t\t\tif \"redd.it\" in permalink:\n\t\t\t\t\t\tshort = permalink.replace(\"http://redd.it/\", \"\").replace(\"https://redd.it/\", \"\")\n\t\t\t\t\t\tsubmission = self.reddit.get_submission(submission_id=short)\n\t\t\t\t\telse:\n\t\t\t\t\t\tsubmission = self.reddit.get_submission(url=permalink)\n\t\t\t\texcept:\n\t\t\t\t\tpass\n\n\t\t\t\ttry:\n\t\t\t\t\tif submission == None:\n\t\t\t\t\t\traise InvalidPermalinkError(resp=ErrorResponse(self, message.author.name))\n\t\t\t\t\telif submission.id in self.database.get()[\"replied\"]:\n\t\t\t\t\t\traise PreexistingCloudError(resp=ErrorResponse(self, message.author.name))\n\t\t\t\t\telif submission.subreddit.display_name.lower() in self.database.get()[\"banned\"]:\n\t\t\t\t\t\traise BannedSubredditError(resp=ErrorResponse(self, message.author.name))\n\t\t\t\t\telse:\n\t\t\t\t\t\tcollected.append(ValidMail(submission, message))\n\t\t\t\texcept MakesWordCloudsErrorDummy:\n\t\t\t\t\tpass\n\n\t\t\tmessage.mark_as_read()\n\n\t\treturn collected\n\n\tdef posts(self):\n\t\tcollected = []\n\n\t\tfor post in self.reddit.get_subreddit(\"all\").get_hot(limit=200):\n\t\t\tsubreddit = post.subreddit.display_name\n\t\t\tlimit = int(self.config.get()[\"min\"])\n\n\t\t\tbanned = self.database.get()[\"banned\"]\n\t\t\treplied = self.database.get()[\"replied\"]\n\n\t\t\tif subreddit.lower() not in banned and post.id not in replied and post.num_comments >= limit:\n\t\t\t\tcollected.append(post.id)\n\n\t\treturn collected\n\n\tdef comment(self, submission, message):\n\t\tsubmission = self.reddit.get_submission(submission_id=submission)\n\n\t\ttry:\n\t\t\turl = submission.add_comment(self._format_comment(message)).permalink\n\t\t\tself.database.get()[\"replied\"].append(submission.id)\n\n\t\t\tprint \"> Comment posted. \"\n\t\t\tprint \"> \" + url\n\n\t\t\treturn url\n\t\texcept praw.errors.Forbidden as e:\n\t\t\tsubreddit = submission.subreddit.display_name.lower()\n\t\t\tbanned = self.database.get()[\"banned\"]\n\n\t\t\tif subreddit not in banned:\n\t\t\t\tbanned.append(subreddit)\n\t\t\t\traise BannedSubredditError()\n\t\texcept:\n\t\t\tprint \"> Failed to post comment.\"\n\n\t\t\tself.database.get()[\"replied\"].append(submission.id)\n\t\t\ttraceback.print_exc(file=sys.stdout)\n\n\tdef message(self, recipient, subject, message):\n\t\tself.reddit.send_message(recipient, subject, self._format_comment(message))"
  },
  {
    "path": "requirements.txt",
    "content": "image\nnumpy\npyimgur\npraw\nwordcloud"
  }
]