#!/usr/bin/env python # -*- coding: utf-8 -*- import praw import sys import logging import requests import time import sqlite3 from logging.handlers import TimedRotatingFileHandler from prawcore.exceptions import RequestException, ResponseException from PIL import Image, ImageDraw, ImageFont from io import BytesIO import re reddit = praw.Reddit(‘bot1’) subreddit = reddit.subreddit(“earthporn”) class Database: def __init__(self): self._sql_conn = sqlite3.connect(‘database.db’) self._sql = self._sql_conn.cursor() self._sql.execute(“CREATE TABLE IF NOT EXISTS submissions (id text PRIMARY KEY);”) def has_submission_been_checked(self, submission_id): self._sql.execute(‘SELECT EXISTS(SELECT 1 FROM submissions WHERE id=? LIMIT 1)’, (submission_id,)) if self._sql.fetchone()[0]: return True return False def submission_checked(self, submission_id): self._sql.execute(‘INSERT INTO submissions (id) VALUES (?)’, (submission_id,)) self._sql_conn.commit() class ImageResolutionBot: def __init__(self): self._db = Database() logging.debug(‘Initializing bot’) def run(self): for submission in subreddit.new(limit=10): if not self._db.has_submission_been_checked(submission.id): self.process_submission(submission) self._db.submission_checked(submission.id) def process_submission(self, submission): try: regex_results = re.search(‘([0-9]{3,5}) ?[xX’ + u’×’ + ‘*] ?([0-9]{3,5})’, submission.title) claimed_width = regex_results.group(1) claimed_height = regex_results.group(2) try: response = requests.get(submission.url) img = Image.open(BytesIO(response.content)) except Exception as error: response = requests.get(submission.url + ‘.jpg’) img = Image.open(BytesIO(response.content)) width, height = img.size if str(width) != claimed_width or str(height) != claimed_height: reply_template = ‘The actual resolution of this image is {}, not {}.’ reply_text = reply_template.format(str(width) + “x” + str(height), claimed_width + “x” + claimed_height) submission.reply(reply_text) logging.info(‘%s\n%s’, submission.title, reply_text) #print(submission.title) #print(reply_text) #print(“”) except Exception as error: logging.error(‘Failed submission with title %s, skipping it | %s’, submission.title, error) return def _setup_logging(level): console_handler = logging.StreamHandler() file_handler = TimedRotatingFileHandler(‘./log/imageresolutionbot.log’, when=’midnight’, interval=1) file_handler.suffix = ‘%Y-%m-%d’ module_loggers = [‘requests’, ‘urllib3’, ‘prawcore’, ‘PIL.Image’, ‘PIL.PngImagePlugin’] for logger in module_loggers: logging.getLogger(logger).setLevel(logging.ERROR) logging.basicConfig(format=’%(asctime)s %(levelname)s %(message)s’, datefmt=’%Y-%m-%d %H:%M:%S’, level=level, handlers=[console_handler, file_handler]) def _handle_exception(exc_type, exc_value, exc_traceback): # Don’t log ctrl+c if issubclass(exc_type, KeyboardInterrupt): sys.__excepthook__(exc_type, exc_value, exc_traceback) return logging.critical(‘Unhandled exception:\n’, exc_info=(exc_type, exc_value, exc_traceback)) def main(): _setup_logging(logging.INFO) sys.excepthook = _handle_exception bot = ImageResolutionBot() while True: try: logging.debug(‘Running bot’) bot.run() logging.debug(‘Bot finished, restarting in 60 seconds’) except (requests.exceptions.ReadTimeout, requests.exceptions.ConnectionError, ResponseException, RequestException): logging.error(‘Reddit api timed out, restarting’) continue time.sleep(60) if __name__ == ‘__main__’: main()