Created
May 3, 2026 08:55
-
-
Save hg/50d9b3036c063e2dace414725b213756 to your computer and use it in GitHub Desktop.
mrakopedia.net Calibre recipe
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env python3 | |
| # vim: ft=python sw=4 sts=4 et si | |
| __license__ = "GPL v3" | |
| __author__ = "hg" | |
| from calibre.web.feeds.recipes import BasicNewsRecipe | |
| base_url = "https://mrakopedia.net" | |
| logo_url = base_url + "/logos/default.gif" | |
| exclude = ["(манга)", "(комикс)", "Каталог"] | |
| class MrakopediaRecipe(BasicNewsRecipe): | |
| title = "Мракопедия" | |
| description = "Лучшие истории Мракопедии по голосам читателей" | |
| category = "copypasta, creepy, horror, fiction" | |
| masthead_url = logo_url | |
| cover_url = logo_url | |
| language = "ru" | |
| encoding = "utf-8" | |
| ignore_duplicate_articles = {'url'} | |
| no_stylesheets = True | |
| resolve_internal_links = True | |
| recipe_specific_options = { | |
| "save_large": { | |
| "short": "Сохранять большие НЕ текстовые документы", | |
| "long": ( | |
| "Возможные значения: yes/no. Текстовые истории сохраняются всегда, " | |
| "независимо от размера. Значение 'yes' дополнительно сохраняет " | |
| "массивные графические документы (комиксы, мангу) и второстепенные " | |
| "вещи вроде архивов ссылок. 'no' отбирает только текстовые посты." | |
| ), | |
| "default": "no" | |
| }, | |
| "sort_by": { | |
| "short": "Способ сортировки историй", | |
| "long": "rating — сортировать по оценке; votes — по количеству голосов.", | |
| "default": "rating" | |
| }, | |
| } | |
| keep_only_tags = [ | |
| {"name": "main", "class": "tl_article"}, | |
| ] | |
| remove_tags = [ | |
| {"name": "span", "class": "mw-editsection"}, | |
| {"name": "div", "class": "box"}, | |
| {"name": "div", "class": "rating_box"}, | |
| ] | |
| def parse_index(self): | |
| soup = self.index_to_soup(base_url + "/wiki/Категория:Рейтинг") | |
| links = soup.find_all("a", title=lambda t: t and "Рейтинг:" in t) | |
| index = [] | |
| def do_page(title, href): | |
| pages = self.load_rating(href) | |
| index.append((title, pages)) | |
| self.log("added {} pages from '{}'".format(len(pages), title)) | |
| do_page("Общий рейтинг", "/wiki/Рейтинг:Общий_рейтинг") | |
| for link in links: | |
| [_, title] = link["title"].split(":", maxsplit=1) | |
| do_page(title, link["href"]) | |
| return index | |
| def load_rating(self, url): | |
| doc = self.index_to_soup(base_url + url) | |
| content = doc.find(id="mw-content-text") | |
| table = content.find("table") | |
| index = [] | |
| skip_large = self.recipe_specific_options["save_large"] != "yes" | |
| for row in table.find_all("tr"): | |
| link = row.find("a", href=True) | |
| if not link: | |
| continue | |
| [title, rating, votes] = [cell.text for cell in row.find_all("td")] | |
| if skip_large and any([sub in title for sub in exclude]): | |
| self.log("skipped link", title) | |
| continue | |
| index.append({ | |
| "title": title, | |
| "url": base_url + link["href"] + "?reader", | |
| "description": "Рейтинг: {} ({} голосов)".format(rating, votes), | |
| "rating": int(rating.rstrip("%")), | |
| "votes": int(votes), | |
| }) | |
| sort = self.recipe_specific_options["sort_by"] | |
| return sorted(index, reverse=True, key=lambda i: i[sort]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment