From 604a1378b71e6ea0bc8e22019269c7ae511bff85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Ml=C3=A1dek?= Date: Tue, 14 Sep 2021 14:08:01 +0200 Subject: [PATCH] reformat w/ black --- delojza.py | 570 +++++++++++++++++++++++++++++++++++-------------- poetry.lock | 176 ++++++++++++++- pyproject.toml | 1 + 3 files changed, 581 insertions(+), 166 deletions(-) diff --git a/delojza.py b/delojza.py index 6dc76b9..934f457 100755 --- a/delojza.py +++ b/delojza.py @@ -64,40 +64,66 @@ class DelojzaDB: return [res[0] for res in results.fetchall()] def get_chat(self, id): - return self.db.execute("SELECT id, protected FROM chats WHERE id == ?", (id,)).fetchone() + return self.db.execute( + "SELECT id, protected FROM chats WHERE id == ?", (id,) + ).fetchone() def set_chat_protected(self, id, protected): chat_in_db = self.get_chat(id) if chat_in_db: - self.db.execute("UPDATE chats SET protected = ? WHERE id = ?", (protected, id)) + self.db.execute( + "UPDATE chats SET protected = ? WHERE id = ?", (protected, id) + ) else: - self.db.execute("INSERT INTO chats (id, protected) VALUES (?, ?)", (id, protected)) + self.db.execute( + "INSERT INTO chats (id, protected) VALUES (?, ?)", (id, protected) + ) self.db.commit() def get_tag(self, tag): - return self.db.execute("SELECT id, tag, protected FROM tags WHERE tag == ?", (tag,)).fetchone() + return self.db.execute( + "SELECT id, tag, protected FROM tags WHERE tag == ?", (tag,) + ).fetchone() def set_tag_protected(self, tag, protected): tag_in_db = self.get_tag(tag) if tag_in_db: - self.db.execute("UPDATE tags SET protected = ? WHERE tag = ?", (protected, tag)) + self.db.execute( + "UPDATE tags SET protected = ? WHERE tag = ?", (protected, tag) + ) else: - self.db.execute("INSERT INTO tags (tag, protected) VALUES (?, ?)", (tag, protected)) + self.db.execute( + "INSERT INTO tags (tag, protected) VALUES (?, ?)", (tag, protected) + ) self.db.commit() class DelojzaBot: - def __init__(self, tg_api_key, out_dir, redirects=None, tmp_dir=None, db_path=None, protected_password=None, - acoustid_key=None, tumblr_name=None, tumblr_keys=None, markov=None): + def __init__( + self, + tg_api_key, + out_dir, + redirects=None, + tmp_dir=None, + db_path=None, + protected_password=None, + acoustid_key=None, + tumblr_name=None, + tumblr_keys=None, + markov=None, + ): self._setup_logging(os.path.dirname(os.path.realpath(__file__))) - self.db = DelojzaDB(db_path or os.path.join(os.path.dirname(os.path.realpath(__file__)), "delojza.db")) + self.db = DelojzaDB( + db_path + or os.path.join(os.path.dirname(os.path.realpath(__file__)), "delojza.db") + ) self.out_dir = os.path.abspath(out_dir) self.out_dir = self.out_dir[:-1] if self.out_dir[-1] == "/" else self.out_dir - self.logger.debug('OUT_DIR: ' + out_dir) + self.logger.debug("OUT_DIR: " + out_dir) self.tmp_dir = tmp_dir if tmp_dir else tempfile.gettempdir() - self.logger.debug('TMP_DIR: ' + tmp_dir) + self.logger.debug("TMP_DIR: " + tmp_dir) self.markov = markov self.redirects = {} @@ -146,7 +172,9 @@ class DelojzaBot: dfh = logging.FileHandler(log_path + "/delojza.log") dfh.setLevel(logging.DEBUG) - formatter = logging.Formatter('%(asctime)s - %(name)s [%(levelname)s] %(message)s') + formatter = logging.Formatter( + "%(asctime)s - %(name)s [%(levelname)s] %(message)s" + ) ch.setFormatter(formatter) dfh.setFormatter(formatter) @@ -156,15 +184,16 @@ class DelojzaBot: def _log_msg(self, update): from_user = update.message.from_user - self.logger.debug(f"Received from {from_user.username or (from_user.first_name + from_user.last_name)}" - f" ({update.message.chat.id}): " + (update.message.text or "")) + self.logger.debug( + f"Received from {from_user.username or (from_user.first_name + from_user.last_name)}" + f" ({update.message.chat.id}): " + (update.message.text or "") + ) @staticmethod def ytdl_can(url): ies = youtube_dl.extractor.gen_extractors() for ie in ies: - if ie.suitable(url) and ie.IE_NAME != 'generic' \ - and '/channel/' not in url: + if ie.suitable(url) and ie.IE_NAME != "generic" and "/channel/" not in url: # Site has dedicated extractor return True return False @@ -174,14 +203,21 @@ class DelojzaBot: def sanitize(filepath): if filepath is None: return None - filepath = unicodedata.normalize('NFKD', filepath).encode('ascii', 'ignore').decode('ascii') - return re.sub(r'[^\w.()\[\]{}#-]', '_', filepath) + filepath = ( + unicodedata.normalize("NFKD", filepath) + .encode("ascii", "ignore") + .decode("ascii") + ) + return re.sub(r"[^\w.()\[\]{}#-]", "_", filepath) @staticmethod def _get_tags(filepath): try: audio = EasyID3(filepath) - return audio["artist"][0] if audio["artist"] else None, audio["title"][0] if audio["title"] else None + return ( + audio["artist"][0] if audio["artist"] else None, + audio["title"][0] if audio["title"] else None, + ) except mutagen.id3.ID3NoHeaderError: return None, None @@ -213,12 +249,16 @@ class DelojzaBot: if self.acoustid_key: try: self.logger.debug("Requesting AcoustID for {}".format(filepath)) - results = sorted(acoustid.match(self.acoustid_key, filepath), key=itemgetter(0), reverse=True) + results = sorted( + acoustid.match(self.acoustid_key, filepath), + key=itemgetter(0), + reverse=True, + ) if len(results) > 0: score, rid, aid_title, aid_artist = results[0] - if score > .4: + if score > 0.4: title = aid_title - artist = re.sub(r' *; +', ' & ', aid_artist) + artist = re.sub(r" *; +", " & ", aid_artist) best_acoustid_score = score source = "AcoustID ({}%)".format(round(score * 100)) except acoustid.NoBackendError: @@ -226,30 +266,32 @@ class DelojzaBot: except acoustid.FingerprintGenerationError: self.logger.warning("fingerprint could not be calculated") except acoustid.WebServiceError as exc: - self.logger.warning("web service request failed: {}".format(exc.message)) + self.logger.warning( + "web service request failed: {}".format(exc.message) + ) - if best_acoustid_score < .8: - if 'track' in info: - title = info['track'] - if 'artist' in info: - artist = info['artist'] + if best_acoustid_score < 0.8: + if "track" in info: + title = info["track"] + if "artist" in info: + artist = info["artist"] - if 'track' in info or 'artist' in info: + if "track" in info or "artist" in info: source = "supplied metadata" - if title is None and artist is None and '-' in info.get("title", ""): - split = info['title'].split("-") + if title is None and artist is None and "-" in info.get("title", ""): + split = info["title"].split("-") artist = split[0] title = split[1] source = "fallback (artist - title)" - if title is None and 'title' in info: - title = info['title'] + if title is None and "title" in info: + title = info["title"] source = "full title fallback" - if 'soundcloud' in info.get("extractor", "") and artist is None: - artist = info['uploader'] - source = "soundcloud \"fallback\"" + if "soundcloud" in info.get("extractor", "") and artist is None: + artist = info["uploader"] + source = 'soundcloud "fallback"' artist = artist.strip() if artist else None title = title.strip() if title else None @@ -258,14 +300,18 @@ class DelojzaBot: message.reply_text("Tried tagging, found nothing :(") return - message.reply_text("Tagging as \"{}\" by \"{}\"\nvia {}".format(title, artist, source)) - self.logger.info("Tagging {} w/ {} - {} [{}]...".format(filepath, title, artist, source)) + message.reply_text( + 'Tagging as "{}" by "{}"\nvia {}'.format(title, artist, source) + ) + self.logger.info( + "Tagging {} w/ {} - {} [{}]...".format(filepath, title, artist, source) + ) self._tag_file(filepath, artist, title) @staticmethod def _get_percent_filled(directory): output = subprocess.check_output(["df", directory]) - percents_re = re.search(r"[0-9]+%", output.decode('utf-8')) + percents_re = re.search(r"[0-9]+%", output.decode("utf-8")) if not percents_re: raise RuntimeError return int(percents_re.group(0)[:-1]) @@ -273,18 +319,22 @@ class DelojzaBot: # noinspection PyUnusedLocal def download_ytdl(self, urls, out_path, date, message, audio=False, filetitle=None): ytdl = { - 'noplaylist': True, - 'restrictfilenames': True, - 'outtmpl': os.path.join(self.tmp_dir, '{}__%(title)s__%(id)s.%(ext)s'.format(datestr(date))) + "noplaylist": True, + "restrictfilenames": True, + "outtmpl": os.path.join( + self.tmp_dir, "{}__%(title)s__%(id)s.%(ext)s".format(datestr(date)) + ), } if audio: - ytdl['format'] = 'bestaudio/best' - ytdl['postprocessors'] = [{ - 'key': 'FFmpegExtractAudio', - 'preferredcodec': 'mp3', - 'preferredquality': '256' - }] - ytdl['postprocessor_args'] = ['-ar', '44100'] + ytdl["format"] = "bestaudio/best" + ytdl["postprocessors"] = [ + { + "key": "FFmpegExtractAudio", + "preferredcodec": "mp3", + "preferredquality": "256", + } + ] + ytdl["postprocessor_args"] = ["-ar", "44100"] filenames = [] with youtube_dl.YoutubeDL(ytdl) as ytdl: attempts = 0 @@ -294,7 +344,7 @@ class DelojzaBot: break except DownloadError as exc: attempts += 1 - if '403' in str(exc) and attempts < 5: + if "403" in str(exc) and attempts < 5: self.logger.warning("Received a 403!") sleep(1.357) if self.markov: @@ -303,7 +353,7 @@ class DelojzaBot: raise exc for info in [ytdl.extract_info(url, download=False) for url in urls]: filename = ytdl.prepare_filename(info) - globbeds = glob(os.path.splitext(filename)[0] + '.*') + globbeds = glob(os.path.splitext(filename)[0] + ".*") for globbed in globbeds: if globbed.endswith("mp3"): self._autotag_file(globbed, message, info=info) @@ -315,24 +365,34 @@ class DelojzaBot: def download_raw(self, urls, out_path, date, message, audio=False, filetitle=None): filenames = [] for url in urls: - local_filename = os.path.join(out_path, "{}__{}".format(datestr(date), - self.sanitize(filetitle or url.split('/')[-1]))) + local_filename = os.path.join( + out_path, + "{}__{}".format( + datestr(date), self.sanitize(filetitle or url.split("/")[-1]) + ), + ) final_filename = local_filename is_mp3 = local_filename.endswith("mp3") r = requests.get(url, stream=True) - with open(local_filename, 'wb') as f: + with open(local_filename, "wb") as f: for chunk in r.iter_content(chunk_size=1024): if chunk: f.write(chunk) - if not re.match(r'.*\..{3,5}$', os.path.split(local_filename)[-1]): + if not re.match(r".*\..{3,5}$", os.path.split(local_filename)[-1]): kind = filetype.guess(local_filename) if kind is None: - self.logger.error("File has no extension and could not be determined!") + self.logger.error( + "File has no extension and could not be determined!" + ) else: - self.logger.info('Moving file without extension... %s?' % kind.extension) - final_filename = shutil.move(local_filename, local_filename + '.' + kind.extension) + self.logger.info( + "Moving file without extension... %s?" % kind.extension + ) + final_filename = shutil.move( + local_filename, local_filename + "." + kind.extension + ) is_mp3 = kind.extension == "mp3" filenames.append(final_filename) @@ -340,7 +400,7 @@ class DelojzaBot: if audio and is_mp3: try: id3 = mutagen.id3.ID3(final_filename) - untagged = 'TIT2' not in id3 + untagged = "TIT2" not in id3 except mutagen.id3.ID3NoHeaderError: untagged = True if untagged: @@ -350,10 +410,18 @@ class DelojzaBot: @staticmethod def extract_hashtags(message): - hashtags = list(map(message.parse_entity, - list(filter(lambda e: e.type == 'hashtag', message.entities)))) - hashtags += list(map(message.parse_caption_entity, - list(filter(lambda e: e.type == 'hashtag', message.caption_entities)))) + hashtags = list( + map( + message.parse_entity, + list(filter(lambda e: e.type == "hashtag", message.entities)), + ) + ) + hashtags += list( + map( + message.parse_caption_entity, + list(filter(lambda e: e.type == "hashtag", message.caption_entities)), + ) + ) if len(hashtags) > 0: hashtags = [hashtag[1:].upper() for hashtag in hashtags] for i, hashtag in enumerate(hashtags): @@ -370,24 +438,30 @@ class DelojzaBot: return hashtags def handle_text(self, message, hashtags): - if len(hashtags) == 0 or hashtags[0] not in ('TEXT', 'TXT'): + if len(hashtags) == 0 or hashtags[0] not in ("TEXT", "TXT"): return - info_line = self.sanitize("-".join(re.sub(r'#[\w]+', '', message.text).strip().split()[:7])) + info_line = self.sanitize( + "-".join(re.sub(r"#[\w]+", "", message.text).strip().split()[:7]) + ) if len(info_line) > 64: info_line = info_line[:64] - filename = '{}__{}.txt'.format(datestr(message.date), info_line) + filename = "{}__{}.txt".format(datestr(message.date), info_line) out_dir = self.redirects.get(hashtags[0], self.out_dir) - out_path = os.path.join(out_dir, *hashtags[1:] or ['TEXT']) + out_path = os.path.join(out_dir, *hashtags[1:] or ["TEXT"]) file_path = os.path.join(out_path, filename) mkdir_p(out_path) - with open(file_path, 'w') as out_file: + with open(file_path, "w") as out_file: out_file.write(message.text) - message.reply_text("Saved text to \"{}\"...".format(os.path.join(*hashtags[1:] or ['TEXT'], filename))) + message.reply_text( + 'Saved text to "{}"...'.format( + os.path.join(*hashtags[1:] or ["TEXT"], filename) + ) + ) # noinspection PyBroadException def handle(self, urls, message, hashtags, download_fn, filetitle=None): @@ -405,67 +479,104 @@ class DelojzaBot: else: out_dir = self.out_dir - if any(hashtag in self.db.get_protected_tags() for hashtag in original_hashtags): + if any( + hashtag in self.db.get_protected_tags() for hashtag in original_hashtags + ): if message.chat.id not in self.db.get_protected_chats(): - self.logger.info("Redirecting {} in chat {} due to protected hashtags: {}..." - .format(urls, message.chat.title, hashtags)) + self.logger.info( + "Redirecting {} in chat {} due to protected hashtags: {}...".format( + urls, message.chat.title, hashtags + ) + ) hashtags.insert(0, "PUBLIC") for i in range(len(hashtags)): - current_path = hashtags[:i + 1] + current_path = hashtags[: i + 1] if not os.path.isdir(os.path.join(out_dir, *current_path)): test_path = current_path test_path[-1] = "_" + test_path[-1] if os.path.isdir(os.path.join(out_dir, *test_path)): - self.logger.debug(f"Rerouting {current_path[-1]} to _{test_path[-1]}") + self.logger.debug( + f"Rerouting {current_path[-1]} to _{test_path[-1]}" + ) hashtags[i] = test_path[-1] self.last_hashtags[message.chat.id] = None - self.logger.info("Downloading %s into '%s' (%s)" % (urls, "/".join(original_hashtags), out_dir)) + self.logger.info( + "Downloading %s into '%s' (%s)" + % (urls, "/".join(original_hashtags), out_dir) + ) out_path = os.path.join(out_dir, *hashtags) mkdir_p(out_path) reply = 'Downloading to "{}"...'.format("/".join(original_hashtags)) - audio = any([any([tag in hashtag for tag in ('AUDIO', 'RADIO')]) for hashtag in original_hashtags]) + audio = any( + [ + any([tag in hashtag for tag in ("AUDIO", "RADIO")]) + for hashtag in original_hashtags + ] + ) if audio and download_fn != self.download_raw: - reply += ' (And also guessing you want to extract the audio)' + reply += " (And also guessing you want to extract the audio)" message.reply_text(reply) - filenames = download_fn(urls, out_path, message.date, message, audio=audio, filetitle=filetitle) + filenames = download_fn( + urls, out_path, message.date, message, audio=audio, filetitle=filetitle + ) cmd_hashtag = original_hashtags[0] tumblr_ids = [] - if cmd_hashtag in ('TUMBLR', 'TUMBLR_NOW') and self.tumblr_client: - now = cmd_hashtag == 'TUMBLR_NOW' - reply = '(btw, {})'.format("***FIRING TO TUMBLR RIGHT AWAY***" if now else "queueing to tumblr") + if cmd_hashtag in ("TUMBLR", "TUMBLR_NOW") and self.tumblr_client: + now = cmd_hashtag == "TUMBLR_NOW" + reply = "(btw, {})".format( + "***FIRING TO TUMBLR RIGHT AWAY***" if now else "queueing to tumblr" + ) message.reply_text(reply, parse_mode=telegram.ParseMode.MARKDOWN) for filename in filenames: if filename.endswith(".mp4"): try: - output_filename = filename[:-len(".mp4")] + ".gif" - subprocess.check_output(['ffmpeg', '-i', filename, output_filename]) + output_filename = filename[: -len(".mp4")] + ".gif" + subprocess.check_output( + ["ffmpeg", "-i", filename, output_filename] + ) filename = output_filename except subprocess.CalledProcessError: - message.reply_text("Conversion to gif failed, sorry! Check log...") + message.reply_text( + "Conversion to gif failed, sorry! Check log..." + ) continue - response = self.tumblr_client.create_photo(self.tumblr_name, data=filename, - state="published" if now else "queue") - if 'id' in response: - tumblr_ids.append(response['id']) + response = self.tumblr_client.create_photo( + self.tumblr_name, + data=filename, + state="published" if now else "queue", + ) + if "id" in response: + tumblr_ids.append(response["id"]) else: - self.logger.warning("Did not receive 'id' in tumblr response: \n" + pprint.pformat(response)) - message.reply_text('Something weird happened with the tumblrs, check it!') + self.logger.warning( + "Did not receive 'id' in tumblr response: \n" + + pprint.pformat(response) + ) + message.reply_text( + "Something weird happened with the tumblrs, check it!" + ) - self.last_downloaded[message.chat.id] = filenames, original_hashtags, tumblr_ids + self.last_downloaded[message.chat.id] = ( + filenames, + original_hashtags, + tumblr_ids, + ) return True except: exc_type, exc_value, __ = sys.exc_info() if "Timed out" not in str(exc_value): - message.reply_text("Something is FUCKED: [{}] {}".format(exc_type, exc_value)) + message.reply_text( + "Something is FUCKED: [{}] {}".format(exc_type, exc_value) + ) return False def handle_tg_message(self, message, bot, hashtag): @@ -488,13 +599,19 @@ class DelojzaBot: if file is not None: url = bot.getFile(file).file_path - return self.handle([url], message, hashtag, self.download_raw, filetitle=filetitle) + return self.handle( + [url], message, hashtag, self.download_raw, filetitle=filetitle + ) else: return False def handle_urls(self, message, hashtags): - urls = list(map(lambda e: message.parse_entity(e), - filter(lambda e: e.type == 'url', message.entities))) + urls = list( + map( + lambda e: message.parse_entity(e), + filter(lambda e: e.type == "url", message.entities), + ) + ) ytdl_res = False ytdl_urls = [url for url in urls if self.ytdl_can(url)] @@ -504,8 +621,11 @@ class DelojzaBot: raw_res = False normal_urls = [url for url in urls if not self.ytdl_can(url)] if len(normal_urls) > 0: - file_urls = [url for url in normal_urls if - "text" not in requests.head(url).headers.get("Content-Type", "text")] + file_urls = [ + url + for url in normal_urls + if "text" not in requests.head(url).headers.get("Content-Type", "text") + ] if len(file_urls) > 0: raw_res = self.handle(file_urls, message, hashtags, self.download_raw) @@ -515,64 +635,109 @@ class DelojzaBot: self._log_msg(update) hashtags = self._get_hashtags(update.message) if hashtags: - url_res = self.handle_urls(update.message, self._get_hashtags(update.message)) + url_res = self.handle_urls( + update.message, self._get_hashtags(update.message) + ) if url_res: return - msg_res = self.handle_tg_message(update.message, bot, self._get_hashtags(update.message)) + msg_res = self.handle_tg_message( + update.message, bot, self._get_hashtags(update.message) + ) if msg_res: return hashtags = self.extract_hashtags(update.message) if len(hashtags) > 0: - self.handle_text(update.message.reply_to_message or update.message, hashtags) + self.handle_text( + update.message.reply_to_message or update.message, hashtags + ) if update.message.reply_to_message: self.handle_tg_message(update.message.reply_to_message, bot, hashtags) self.handle_urls(update.message.reply_to_message, hashtags) else: - self.last_hashtags[update.message.chat.id] = update.message.from_user, datetime.now(), hashtags + self.last_hashtags[update.message.chat.id] = ( + update.message.from_user, + datetime.now(), + hashtags, + ) else: if self.markov and update.message.text: self.markov.add_to_corpus(update.message.text) def _get_tag_dirs(self): - return list(filter(lambda x: x.upper() == x, - filter(lambda directory: os.path.isdir(os.path.join(self.out_dir, directory)), - os.listdir(self.out_dir)))) + list(self.redirects.keys()) + return ( + list( + filter( + lambda x: x.upper() == x, + filter( + lambda directory: os.path.isdir( + os.path.join(self.out_dir, directory) + ), + os.listdir(self.out_dir), + ), + ) + ) + + list(self.redirects.keys()) + ) def tg_stats(self, _, update): self._log_msg(update) self.db.initialize() if update.message.chat.id not in self.db.get_protected_chats(): - update.message.reply_text((self.markov.make_sentence() + "!") if self.markov and random() > .7 else "nope.") + update.message.reply_text( + (self.markov.make_sentence() + "!") + if self.markov and random() > 0.7 + else "nope." + ) return tag_dirs = self._get_tag_dirs() reply = "Total number of tags: {}\n\n".format(len(tag_dirs)) - counts = [(directory, os.listdir(os.path.join(self.out_dir, directory))) for directory in - tag_dirs] # TODO REDIRECTS + counts = [ + (directory, os.listdir(os.path.join(self.out_dir, directory))) + for directory in tag_dirs + ] # TODO REDIRECTS counts.sort(key=itemgetter(0)) counts.sort(key=lambda x: len(x[1]), reverse=True) for directory, files in counts: if len(files) == 1: break - abs_paths = [os.path.join(self.out_dir, directory, file) for file in files] # TODO REDIRECTS + abs_paths = [ + os.path.join(self.out_dir, directory, file) for file in files + ] # TODO REDIRECTS abs_files = list(filter(os.path.isfile, abs_paths)) # mimes = [magic.from_file(path, mime=True).split("/")[0] for path in abs_files] # mime_counts = [(mime, mimes.count(mime)) for mime in set(mimes)] - exts = [ext[1:] for ext in [os.path.splitext(path)[1] for path in abs_files] if len(ext) > 0] + exts = [ + ext[1:] + for ext in [os.path.splitext(path)[1] for path in abs_files] + if len(ext) > 0 + ] ext_counts = [(ext, exts.count(ext)) for ext in set(exts)] dir_cnt = len(abs_paths) - len(abs_files) - type_counts = ext_counts + ([("directorie", dir_cnt)] if dir_cnt > 0 else []) - details = ", ".join(["{} {}s".format(cnt, mime) for mime, cnt in - sorted(type_counts, key=itemgetter(1), reverse=True)]) + type_counts = ext_counts + ( + [("directorie", dir_cnt)] if dir_cnt > 0 else [] + ) + details = ", ".join( + [ + "{} {}s".format(cnt, mime) + for mime, cnt in sorted( + type_counts, key=itemgetter(1), reverse=True + ) + ] + ) if len(type_counts) == 1: reply += "{}: {}\n".format(directory, details) else: - reply += "{}: {} files ({})\n".format(directory, len(files), details) + reply += "{}: {} files ({})\n".format( + directory, len(files), details + ) orphans = list(filter(lambda cnt: len(cnt[1]) <= 1, counts)) if len(orphans) > 0: - reply += "\nFollowing tags are orphans: " + ", ".join(map(itemgetter(0), orphans)) + reply += "\nFollowing tags are orphans: " + ", ".join( + map(itemgetter(0), orphans) + ) update.message.reply_text(reply, parse_mode=telegram.ParseMode.HTML) def _get_orphan_tags(self): @@ -589,20 +754,30 @@ class DelojzaBot: self._log_msg(update) self.db.initialize() if update.message.chat.id not in self.db.get_protected_chats(): - update.message.reply_text((self.markov.make_sentence() + "!") if self.markov and random() > .7 else "nope.") + update.message.reply_text( + (self.markov.make_sentence() + "!") + if self.markov and random() > 0.7 + else "nope." + ) return orphans = self._get_orphan_tags() if len(orphans) == 0: update.message.reply_text("Good job, no orphan tags!") else: - update.message.reply_text("The following tags only contain a single file:\n" + - ", ".join(map(itemgetter(0), orphans))) + update.message.reply_text( + "The following tags only contain a single file:\n" + + ", ".join(map(itemgetter(0), orphans)) + ) def tg_orphan_full(self, _, update): self._log_msg(update) self.db.initialize() if update.message.chat.id not in self.db.get_protected_chats(): - update.message.reply_text((self.markov.make_sentence() + "!") if self.markov and random() > .7 else "nope.") + update.message.reply_text( + (self.markov.make_sentence() + "!") + if self.markov and random() > 0.7 + else "nope." + ) return orphans = self._get_orphan_tags() if len(orphans) == 0: @@ -625,7 +800,7 @@ class DelojzaBot: out_dir = self.redirects.get(hashtags[0], self.out_dir) mp3s = [filename for filename in files if filename.endswith("mp3")] if len(mp3s) > 0: - arg_raw = re.sub(r'^/[@\w]+ ?', '', update.message.text).strip() + arg_raw = re.sub(r"^/[@\w]+ ?", "", update.message.text).strip() artist, title = None, None reverse = len(arg_raw) == 0 @@ -643,10 +818,16 @@ class DelojzaBot: title, artist = orig_artist, orig_title self._tag_file(mp3, artist, title) - update.message.reply_text("Tagging \"{}\" as \"{}\" by \"{}\"!" - .format(mp3[len(out_dir) + 1:], title, artist)) + update.message.reply_text( + 'Tagging "{}" as "{}" by "{}"!'.format( + mp3[len(out_dir) + 1 :], title, artist + ) + ) else: - update.message.reply_text((self.markov.make_sentence() if self.markov and random() > .7 else "") + "???") + update.message.reply_text( + (self.markov.make_sentence() if self.markov and random() > 0.7 else "") + + "???" + ) def tg_delete(self, _, update): self._log_msg(update) @@ -654,19 +835,28 @@ class DelojzaBot: files, hashtags, tumblr_ids = self.last_downloaded[update.message.chat.id] out_dir = self.redirects.get(hashtags[0], self.out_dir) for file in files: - update.message.reply_text("Removing \"{}\"!".format(file[len(out_dir) + 1:])) + update.message.reply_text( + 'Removing "{}"!'.format(file[len(out_dir) + 1 :]) + ) os.remove(file) parent_dir = os.path.dirname(file) while True: if len(os.listdir(parent_dir)) == 0: - update.message.reply_text("Removing directory \"{}\" as it's empty..." - .format(parent_dir[len(out_dir) + 1:])) + update.message.reply_text( + 'Removing directory "{}" as it\'s empty...'.format( + parent_dir[len(out_dir) + 1 :] + ) + ) os.rmdir(parent_dir) if parent_dir == out_dir: break parent_dir = os.path.dirname(parent_dir) if len(tumblr_ids) > 0: - plural = "s (all {} of them)".format(len(tumblr_ids)) if len(tumblr_ids) > 1 else "" + plural = ( + "s (all {} of them)".format(len(tumblr_ids)) + if len(tumblr_ids) > 1 + else "" + ) update.message.reply_text("Also deleting tumblr post{}!".format(plural)) for tumblr_id in tumblr_ids: if self.tumblr_client: @@ -681,13 +871,16 @@ class DelojzaBot: msg_split = update.message.text.split(" ") if len(msg_split) != 3: - update.message.reply_text((self.markov.make_sentence() if self.markov and random() > .7 else "") + "???") + update.message.reply_text( + (self.markov.make_sentence() if self.markov and random() > 0.7 else "") + + "???" + ) return chat_in_db = self.db.get_chat(update.message.chat.id) cmd = msg_split[1] - if cmd == 'tag': + if cmd == "tag": if chat_in_db and chat_in_db[1]: tag = msg_split[2].upper() tag_in_db = self.db.get_tag(tag) @@ -698,10 +891,18 @@ class DelojzaBot: end_protected = True self.db.set_tag_protected(tag, end_protected) - update.message.reply_text(f"got it, will {'NOT ' if not end_protected else ''}protect tag {tag}!") + update.message.reply_text( + f"got it, will {'NOT ' if not end_protected else ''}protect tag {tag}!" + ) else: - update.message.reply_text((self.markov.make_sentence() if self.markov and random() > .7 else "hublubl")) - elif cmd == 'chat': + update.message.reply_text( + ( + self.markov.make_sentence() + if self.markov and random() > 0.7 + else "hublubl" + ) + ) + elif cmd == "chat": password = msg_split[2] if password == self.protected_password: if chat_in_db: @@ -711,37 +912,63 @@ class DelojzaBot: end_protected = True self.db.set_chat_protected(update.message.chat.id, end_protected) - update.message.reply_text(f"got it, will {'NOT ' if not end_protected else ''}protect this chat!") + update.message.reply_text( + f"got it, will {'NOT ' if not end_protected else ''}protect this chat!" + ) else: - update.message.reply_text((self.markov.make_sentence() if self.markov and random() > .7 else "hublubl")) + update.message.reply_text( + ( + self.markov.make_sentence() + if self.markov and random() > 0.7 + else "hublubl" + ) + ) else: - update.message.reply_text((self.markov.make_sentence() if self.markov and random() > .7 else "") + "???") + update.message.reply_text( + (self.markov.make_sentence() if self.markov and random() > 0.7 else "") + + "???" + ) def tg_queue(self, _, update): if self.tumblr_client: blog_info = self.tumblr_client.blog_info(self.tumblr_name) - update.message.reply_text("Currently queued tumblr posts: " + str(blog_info['blog'].get('queue', "???"))) + update.message.reply_text( + "Currently queued tumblr posts: " + + str(blog_info["blog"].get("queue", "???")) + ) else: - update.message.reply_text((self.markov.make_sentence() if self.markov and random() > .7 else "") + "???") + update.message.reply_text( + (self.markov.make_sentence() if self.markov and random() > 0.7 else "") + + "???" + ) # noinspection PyMethodMayBeStatic def tg_version(self, _, update): self._log_msg(update) - delojza_date = datetime.fromtimestamp(os.path.getmtime(os.path.realpath(__file__))) \ - .strftime('%Y/%m/%d - %H:%M:%S') - update.message.reply_text("delojza modified date: {}\nyoutube-dl version: {}" - .format(delojza_date, YTDL_VERSION)) + delojza_date = datetime.fromtimestamp( + os.path.getmtime(os.path.realpath(__file__)) + ).strftime("%Y/%m/%d - %H:%M:%S") + update.message.reply_text( + "delojza modified date: {}\nyoutube-dl version: {}".format( + delojza_date, YTDL_VERSION + ) + ) def tg_start(self, _, update): self._log_msg(update) - update.message.reply_text(self.markov.make_sentence() if self.markov else "HELLO") + update.message.reply_text( + self.markov.make_sentence() if self.markov else "HELLO" + ) def tg_error(self, bot, update, error): self.logger.error(error) if "Timed out" in str(error): if update is not None: default = "Mmmm, I like it..." - update.message.reply_text((self.markov.make_sentence(tries=100) if self.markov else default) or default) + update.message.reply_text( + (self.markov.make_sentence(tries=100) if self.markov else default) + or default + ) self.tg_handle(bot, update) else: if update is not None: @@ -755,7 +982,7 @@ class DelojzaBot: class MarkovBlabberer: def __init__(self, filepath): - self.logger = logging.getLogger('markov') + self.logger = logging.getLogger("markov") self.filepath = filepath with open(filepath) as f: @@ -770,21 +997,28 @@ class MarkovBlabberer: text = text.lower() new_sentence = markovify.NewlineText(text) self.markov = markovify.combine([self.markov, new_sentence]) - with open(self.filepath, 'a') as f: - f.write(text + '\n') + with open(self.filepath, "a") as f: + f.write(text + "\n") -if __name__ == '__main__': - logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s') +if __name__ == "__main__": + logging.basicConfig( + level=logging.INFO, + format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", + ) _DIR_ = os.path.dirname(os.path.realpath(__file__)) - CONFIG_PATHS = ['/etc/delojza/delojza.ini', - os.path.join(os.getenv("HOME") or "", ".config/delojza/delojza.ini"), - os.path.join(_DIR_, "delojza.ini")] + CONFIG_PATHS = [ + "/etc/delojza/delojza.ini", + os.path.join(os.getenv("HOME") or "", ".config/delojza/delojza.ini"), + os.path.join(_DIR_, "delojza.ini"), + ] config = ConfigParser() try: - CONF_FILE = next(conf_path for conf_path in CONFIG_PATHS if os.path.isfile(conf_path)) + CONF_FILE = next( + conf_path for conf_path in CONFIG_PATHS if os.path.isfile(conf_path) + ) config.read(CONF_FILE) except StopIteration: logging.error("No config file found, stopping.") @@ -793,24 +1027,30 @@ if __name__ == '__main__': try: markov = MarkovBlabberer("initial.txt") except FileNotFoundError: - logging.warning("Didn't find `initial.txt`, continuing without markov blabbering!") + logging.warning( + "Didn't find `initial.txt`, continuing without markov blabbering!" + ) markov = None try: - redirects = config.items('redirects') + redirects = config.items("redirects") except NoSectionError: redirects = {} - delojza = DelojzaBot(config.get('delojza', 'tg_api_key'), - config.get('delojza', 'OUT_DIR', fallback=os.path.join(_DIR_, "out")), - tmp_dir=config.get('delojza', 'tmp_dir', fallback=tempfile.gettempdir()), - redirects=redirects, - protected_password=config.get('delojza', 'protected_password', fallback=None), - acoustid_key=config.get('delojza', 'acoustid_api_key', fallback=None), - tumblr_name=config.get('tumblr', 'blog_name', fallback=None), - tumblr_keys=(config.get('tumblr', 'consumer_key', fallback=None), - config.get('tumblr', 'consumer_secret', fallback=None), - config.get('tumblr', 'oauth_key', fallback=None), - config.get('tumblr', 'oauth_secret', fallback=None)), - markov=markov) + delojza = DelojzaBot( + config.get("delojza", "tg_api_key"), + config.get("delojza", "OUT_DIR", fallback=os.path.join(_DIR_, "out")), + tmp_dir=config.get("delojza", "tmp_dir", fallback=tempfile.gettempdir()), + redirects=redirects, + protected_password=config.get("delojza", "protected_password", fallback=None), + acoustid_key=config.get("delojza", "acoustid_api_key", fallback=None), + tumblr_name=config.get("tumblr", "blog_name", fallback=None), + tumblr_keys=( + config.get("tumblr", "consumer_key", fallback=None), + config.get("tumblr", "consumer_secret", fallback=None), + config.get("tumblr", "oauth_key", fallback=None), + config.get("tumblr", "oauth_secret", fallback=None), + ), + markov=markov, + ) delojza.run_idle() diff --git a/poetry.lock b/poetry.lock index 5b673df..bb4a66c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -6,6 +6,33 @@ category = "main" optional = false python-versions = "*" +[[package]] +name = "black" +version = "21.9b0" +description = "The uncompromising code formatter." +category = "dev" +optional = false +python-versions = ">=3.6.2" + +[package.dependencies] +click = ">=7.1.2" +mypy-extensions = ">=0.4.3" +pathspec = ">=0.9.0,<1" +platformdirs = ">=2" +regex = ">=2020.1.8" +tomli = ">=0.2.6,<2.0.0" +typing-extensions = [ + {version = ">=3.10.0.0", markers = "python_version < \"3.10\""}, + {version = "!=3.10.0.1", markers = "python_version >= \"3.10\""}, +] + +[package.extras] +colorama = ["colorama (>=0.4.3)"] +d = ["aiohttp (>=3.6.0)", "aiohttp-cors (>=0.4.0)"] +jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] +python2 = ["typed-ast (>=1.4.2)"] +uvloop = ["uvloop (>=0.15.2)"] + [[package]] name = "certifi" version = "2021.5.30" @@ -36,6 +63,25 @@ python-versions = ">=3.5.0" [package.extras] unicode_backport = ["unicodedata2"] +[[package]] +name = "click" +version = "8.0.1" +description = "Composable command line interface toolkit" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[[package]] +name = "colorama" +version = "0.4.4" +description = "Cross-platform colored terminal text." +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + [[package]] name = "cryptography" version = "3.4.8" @@ -98,6 +144,14 @@ category = "main" optional = false python-versions = ">=3.5, <4" +[[package]] +name = "mypy-extensions" +version = "0.4.3" +description = "Experimental type system extensions for programs checked with the mypy typechecker." +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "oauthlib" version = "3.1.1" @@ -111,6 +165,26 @@ rsa = ["cryptography (>=3.0.0,<4)"] signals = ["blinker (>=1.4.0)"] signedtoken = ["cryptography (>=3.0.0,<4)", "pyjwt (>=2.0.0,<3)"] +[[package]] +name = "pathspec" +version = "0.9.0" +description = "Utility library for gitignore style pattern matching of file paths." +category = "dev" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" + +[[package]] +name = "platformdirs" +version = "2.3.0" +description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.extras] +docs = ["Sphinx (>=4)", "furo (>=2021.7.5b38)", "proselint (>=0.10.2)", "sphinx-autodoc-typehints (>=1.12)"] +test = ["appdirs (==1.4.4)", "pytest (>=6)", "pytest-cov (>=2.7)", "pytest-mock (>=3.6)"] + [[package]] name = "pyacoustid" version = "1.2.2" @@ -160,6 +234,14 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" future = "*" requests-oauthlib = "*" +[[package]] +name = "regex" +version = "2021.8.28" +description = "Alternative regular expression module, to replace re." +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "requests" version = "2.26.0" @@ -193,6 +275,22 @@ requests = ">=2.0.0" [package.extras] rsa = ["oauthlib[signedtoken] (>=3.0.0)"] +[[package]] +name = "tomli" +version = "1.2.1" +description = "A lil' TOML parser" +category = "dev" +optional = false +python-versions = ">=3.6" + +[[package]] +name = "typing-extensions" +version = "3.10.0.2" +description = "Backported and Experimental Type Hints for Python 3.5+" +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "unidecode" version = "1.3.1" @@ -225,12 +323,16 @@ python-versions = "*" [metadata] lock-version = "1.1" python-versions = "^3.8" -content-hash = "01568add6ada6b27a0123da237bc38f136148cd1dad83399c994fb9991c906e7" +content-hash = "c6e54519de2d7d86694444f2c26f29af31da90a5df5dcd06c619d8d2dc7d2fd7" [metadata.files] audioread = [ {file = "audioread-2.1.9.tar.gz", hash = "sha256:a3480e42056c8e80a8192a54f6729a280ef66d27782ee11cbd63e9d4d1523089"}, ] +black = [ + {file = "black-21.9b0-py3-none-any.whl", hash = "sha256:380f1b5da05e5a1429225676655dddb96f5ae8c75bdf91e53d798871b902a115"}, + {file = "black-21.9b0.tar.gz", hash = "sha256:7de4cfc7eb6b710de325712d40125689101d21d25283eed7e9998722cf10eb91"}, +] certifi = [ {file = "certifi-2021.5.30-py2.py3-none-any.whl", hash = "sha256:50b1e4f8446b06f41be7dd6338db18e0990601dce795c2b1686458aa7e8fa7d8"}, {file = "certifi-2021.5.30.tar.gz", hash = "sha256:2bbf76fd432960138b3ef6dda3dde0544f27cbf8546c458e60baf371917ba9ee"}, @@ -286,6 +388,14 @@ charset-normalizer = [ {file = "charset-normalizer-2.0.4.tar.gz", hash = "sha256:f23667ebe1084be45f6ae0538e4a5a865206544097e4e8bbcacf42cd02a348f3"}, {file = "charset_normalizer-2.0.4-py3-none-any.whl", hash = "sha256:0c8911edd15d19223366a194a513099a302055a962bca2cec0f54b8b63175d8b"}, ] +click = [ + {file = "click-8.0.1-py3-none-any.whl", hash = "sha256:fba402a4a47334742d782209a7c79bc448911afe1149d07bdabdf480b3e2f4b6"}, + {file = "click-8.0.1.tar.gz", hash = "sha256:8c04c11192119b1ef78ea049e0a6f0463e4c48ef00a30160c704337586f3ad7a"}, +] +colorama = [ + {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, + {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, +] cryptography = [ {file = "cryptography-3.4.8-cp36-abi3-macosx_10_10_x86_64.whl", hash = "sha256:a00cf305f07b26c351d8d4e1af84ad7501eca8a342dedf24a7acb0e7b7406e14"}, {file = "cryptography-3.4.8-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:f44d141b8c4ea5eb4dbc9b3ad992d45580c1d22bf5e24363f2fbf50c2d7ae8a7"}, @@ -323,10 +433,22 @@ mutagen = [ {file = "mutagen-1.45.1-py3-none-any.whl", hash = "sha256:9c9f243fcec7f410f138cb12c21c84c64fde4195481a30c9bfb05b5f003adfed"}, {file = "mutagen-1.45.1.tar.gz", hash = "sha256:6397602efb3c2d7baebd2166ed85731ae1c1d475abca22090b7141ff5034b3e1"}, ] +mypy-extensions = [ + {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, + {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, +] oauthlib = [ {file = "oauthlib-3.1.1-py2.py3-none-any.whl", hash = "sha256:42bf6354c2ed8c6acb54d971fce6f88193d97297e18602a3a886603f9d7730cc"}, {file = "oauthlib-3.1.1.tar.gz", hash = "sha256:8f0215fcc533dd8dd1bee6f4c412d4f0cd7297307d43ac61666389e3bc3198a3"}, ] +pathspec = [ + {file = "pathspec-0.9.0-py2.py3-none-any.whl", hash = "sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a"}, + {file = "pathspec-0.9.0.tar.gz", hash = "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1"}, +] +platformdirs = [ + {file = "platformdirs-2.3.0-py3-none-any.whl", hash = "sha256:8003ac87717ae2c7ee1ea5a84a1a61e87f3fbd16eb5aadba194ea30a9019f648"}, + {file = "platformdirs-2.3.0.tar.gz", hash = "sha256:15b056538719b1c94bdaccb29e5f81879c7f7f0f4a153f46086d155dffcd4f0f"}, +] pyacoustid = [ {file = "pyacoustid-1.2.2.tar.gz", hash = "sha256:c279d9c30a7f481f1420fc37db65833b5f9816cd364dc2acaa93a11c482d4141"}, ] @@ -342,6 +464,49 @@ pytumblr = [ {file = "PyTumblr-0.1.0-py2.py3-none-any.whl", hash = "sha256:a3774d3978bcff2db98f36a2e5d17bb8496ac21157b1b518089adad86d0dca72"}, {file = "PyTumblr-0.1.0.tar.gz", hash = "sha256:eaa4d98217df7ab6392fa5d8801f4a2bdcba35bf0fd49328aa3c98e3b231b6f2"}, ] +regex = [ + {file = "regex-2021.8.28-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9d05ad5367c90814099000442b2125535e9d77581855b9bee8780f1b41f2b1a2"}, + {file = "regex-2021.8.28-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3bf1bc02bc421047bfec3343729c4bbbea42605bcfd6d6bfe2c07ade8b12d2a"}, + {file = "regex-2021.8.28-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f6a808044faae658f546dd5f525e921de9fa409de7a5570865467f03a626fc0"}, + {file = "regex-2021.8.28-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:a617593aeacc7a691cc4af4a4410031654f2909053bd8c8e7db837f179a630eb"}, + {file = "regex-2021.8.28-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:79aef6b5cd41feff359acaf98e040844613ff5298d0d19c455b3d9ae0bc8c35a"}, + {file = "regex-2021.8.28-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:0fc1f8f06977c2d4f5e3d3f0d4a08089be783973fc6b6e278bde01f0544ff308"}, + {file = "regex-2021.8.28-cp310-cp310-win32.whl", hash = "sha256:6eebf512aa90751d5ef6a7c2ac9d60113f32e86e5687326a50d7686e309f66ed"}, + {file = "regex-2021.8.28-cp310-cp310-win_amd64.whl", hash = "sha256:ac88856a8cbccfc14f1b2d0b829af354cc1743cb375e7f04251ae73b2af6adf8"}, + {file = "regex-2021.8.28-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:c206587c83e795d417ed3adc8453a791f6d36b67c81416676cad053b4104152c"}, + {file = "regex-2021.8.28-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8690ed94481f219a7a967c118abaf71ccc440f69acd583cab721b90eeedb77c"}, + {file = "regex-2021.8.28-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:328a1fad67445550b982caa2a2a850da5989fd6595e858f02d04636e7f8b0b13"}, + {file = "regex-2021.8.28-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:c7cb4c512d2d3b0870e00fbbac2f291d4b4bf2634d59a31176a87afe2777c6f0"}, + {file = "regex-2021.8.28-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:66256b6391c057305e5ae9209941ef63c33a476b73772ca967d4a2df70520ec1"}, + {file = "regex-2021.8.28-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:8e44769068d33e0ea6ccdf4b84d80c5afffe5207aa4d1881a629cf0ef3ec398f"}, + {file = "regex-2021.8.28-cp36-cp36m-win32.whl", hash = "sha256:08d74bfaa4c7731b8dac0a992c63673a2782758f7cfad34cf9c1b9184f911354"}, + {file = "regex-2021.8.28-cp36-cp36m-win_amd64.whl", hash = "sha256:abb48494d88e8a82601af905143e0de838c776c1241d92021e9256d5515b3645"}, + {file = "regex-2021.8.28-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b4c220a1fe0d2c622493b0a1fd48f8f991998fb447d3cd368033a4b86cf1127a"}, + {file = "regex-2021.8.28-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4a332404baa6665b54e5d283b4262f41f2103c255897084ec8f5487ce7b9e8e"}, + {file = "regex-2021.8.28-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c61dcc1cf9fd165127a2853e2c31eb4fb961a4f26b394ac9fe5669c7a6592892"}, + {file = "regex-2021.8.28-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:ee329d0387b5b41a5dddbb6243a21cb7896587a651bebb957e2d2bb8b63c0791"}, + {file = "regex-2021.8.28-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f60667673ff9c249709160529ab39667d1ae9fd38634e006bec95611f632e759"}, + {file = "regex-2021.8.28-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:b844fb09bd9936ed158ff9df0ab601e2045b316b17aa8b931857365ea8586906"}, + {file = "regex-2021.8.28-cp37-cp37m-win32.whl", hash = "sha256:4cde065ab33bcaab774d84096fae266d9301d1a2f5519d7bd58fc55274afbf7a"}, + {file = "regex-2021.8.28-cp37-cp37m-win_amd64.whl", hash = "sha256:1413b5022ed6ac0d504ba425ef02549a57d0f4276de58e3ab7e82437892704fc"}, + {file = "regex-2021.8.28-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ed4b50355b066796dacdd1cf538f2ce57275d001838f9b132fab80b75e8c84dd"}, + {file = "regex-2021.8.28-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28fc475f560d8f67cc8767b94db4c9440210f6958495aeae70fac8faec631797"}, + {file = "regex-2021.8.28-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bdc178caebd0f338d57ae445ef8e9b737ddf8fbc3ea187603f65aec5b041248f"}, + {file = "regex-2021.8.28-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:999ad08220467b6ad4bd3dd34e65329dd5d0df9b31e47106105e407954965256"}, + {file = "regex-2021.8.28-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:808ee5834e06f57978da3e003ad9d6292de69d2bf6263662a1a8ae30788e080b"}, + {file = "regex-2021.8.28-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:d5111d4c843d80202e62b4fdbb4920db1dcee4f9366d6b03294f45ed7b18b42e"}, + {file = "regex-2021.8.28-cp38-cp38-win32.whl", hash = "sha256:473858730ef6d6ff7f7d5f19452184cd0caa062a20047f6d6f3e135a4648865d"}, + {file = "regex-2021.8.28-cp38-cp38-win_amd64.whl", hash = "sha256:31a99a4796bf5aefc8351e98507b09e1b09115574f7c9dbb9cf2111f7220d2e2"}, + {file = "regex-2021.8.28-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:04f6b9749e335bb0d2f68c707f23bb1773c3fb6ecd10edf0f04df12a8920d468"}, + {file = "regex-2021.8.28-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b006628fe43aa69259ec04ca258d88ed19b64791693df59c422b607b6ece8bb"}, + {file = "regex-2021.8.28-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:121f4b3185feaade3f85f70294aef3f777199e9b5c0c0245c774ae884b110a2d"}, + {file = "regex-2021.8.28-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:a577a21de2ef8059b58f79ff76a4da81c45a75fe0bfb09bc8b7bb4293fa18983"}, + {file = "regex-2021.8.28-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1743345e30917e8c574f273f51679c294effba6ad372db1967852f12c76759d8"}, + {file = "regex-2021.8.28-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e1e8406b895aba6caa63d9fd1b6b1700d7e4825f78ccb1e5260551d168db38ed"}, + {file = "regex-2021.8.28-cp39-cp39-win32.whl", hash = "sha256:ed283ab3a01d8b53de3a05bfdf4473ae24e43caee7dcb5584e86f3f3e5ab4374"}, + {file = "regex-2021.8.28-cp39-cp39-win_amd64.whl", hash = "sha256:610b690b406653c84b7cb6091facb3033500ee81089867ee7d59e675f9ca2b73"}, + {file = "regex-2021.8.28.tar.gz", hash = "sha256:f585cbbeecb35f35609edccb95efd95a3e35824cd7752b586503f7e6087303f1"}, +] requests = [ {file = "requests-2.26.0-py2.py3-none-any.whl", hash = "sha256:6c1246513ecd5ecd4528a0906f910e8f0f9c6b8ec72030dc9fd154dc1a6efd24"}, {file = "requests-2.26.0.tar.gz", hash = "sha256:b8aa58f8cf793ffd8782d3d8cb19e66ef36f7aba4353eec859e74678b01b07a7"}, @@ -351,6 +516,15 @@ requests-oauthlib = [ {file = "requests_oauthlib-1.3.0-py2.py3-none-any.whl", hash = "sha256:7f71572defaecd16372f9006f33c2ec8c077c3cfa6f5911a9a90202beb513f3d"}, {file = "requests_oauthlib-1.3.0-py3.7.egg", hash = "sha256:fa6c47b933f01060936d87ae9327fead68768b69c6c9ea2109c48be30f2d4dbc"}, ] +tomli = [ + {file = "tomli-1.2.1-py3-none-any.whl", hash = "sha256:8dd0e9524d6f386271a36b41dbf6c57d8e32fd96fd22b6584679dc569d20899f"}, + {file = "tomli-1.2.1.tar.gz", hash = "sha256:a5b75cb6f3968abb47af1b40c1819dc519ea82bcc065776a866e8d74c5ca9442"}, +] +typing-extensions = [ + {file = "typing_extensions-3.10.0.2-py2-none-any.whl", hash = "sha256:d8226d10bc02a29bcc81df19a26e56a9647f8b0a6d4a83924139f4a8b01f17b7"}, + {file = "typing_extensions-3.10.0.2-py3-none-any.whl", hash = "sha256:f1d25edafde516b146ecd0613dabcc61409817af4766fbbcfb8d1ad4ec441a34"}, + {file = "typing_extensions-3.10.0.2.tar.gz", hash = "sha256:49f75d16ff11f1cd258e1b988ccff82a3ca5570217d7ad8c5f48205dd99a677e"}, +] unidecode = [ {file = "Unidecode-1.3.1-py3-none-any.whl", hash = "sha256:5f58926b9125b499f8ab6816828e737578fa3e31fa24d351a3ab7f4b7c064ab0"}, {file = "Unidecode-1.3.1.tar.gz", hash = "sha256:6efac090bf8f29970afc90caf4daae87b172709b786cb1b4da2d0c0624431ecc"}, diff --git a/pyproject.toml b/pyproject.toml index ce423bb..79ddef0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,6 +17,7 @@ PyTumblr = "^0.1.0" markovify = "^0.9.3" [tool.poetry.dev-dependencies] +black = {version = "^21.9b0", allow-prereleases = true} [build-system] requires = ["poetry-core>=1.0.0"]