Skip to content

Instantly share code, notes, and snippets.

@hg
Created May 3, 2026 08:55
Show Gist options
  • Select an option

  • Save hg/50d9b3036c063e2dace414725b213756 to your computer and use it in GitHub Desktop.

Select an option

Save hg/50d9b3036c063e2dace414725b213756 to your computer and use it in GitHub Desktop.
mrakopedia.net Calibre recipe
#!/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