This commit is contained in:
Kovid Goyal 2024-12-15 19:07:08 +05:30
commit 5c9d3386ee
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
118 changed files with 657 additions and 594 deletions

View File

@ -23,8 +23,9 @@ from setup import __appname__, __version__
sys.path.append(base) sys.path.append(base)
import calibre.utils.img as cimg
import custom import custom
import calibre.utils.img as cimg
from calibre.utils.localization import localize_website_link from calibre.utils.localization import localize_website_link
del sys.path[0] del sys.path[0]

View File

@ -299,7 +299,7 @@ def render_options(cmd, groups, options_header=True, add_program=True, header_le
def mark_options(raw): def mark_options(raw):
raw = re.sub(r'(\s+)--(\s+)', u'\\1``--``\\2', raw) raw = re.sub(r'(\s+)--(\s+)', r'\1``--``\2', raw)
def sub(m): def sub(m):
opt = m.group() opt = m.group()

View File

@ -8,13 +8,13 @@ __docformat__ = 'restructuredtext en'
import os import os
from sphinx.builders.epub3 import Epub3Builder as EpubBuilder
from calibre.ebooks.oeb.base import OPF from calibre.ebooks.oeb.base import OPF
from calibre.ebooks.oeb.polish.check.links import UnreferencedResource, check_links from calibre.ebooks.oeb.polish.check.links import UnreferencedResource, check_links
from calibre.ebooks.oeb.polish.container import OEB_DOCS, get_container from calibre.ebooks.oeb.polish.container import OEB_DOCS, get_container
from calibre.ebooks.oeb.polish.pretty import pretty_html_tree, pretty_opf from calibre.ebooks.oeb.polish.pretty import pretty_html_tree, pretty_opf
from calibre.utils.imghdr import identify from calibre.utils.imghdr import identify
from sphinx.builders.epub3 import Epub3Builder as EpubBuilder
from polyglot.builtins import iteritems from polyglot.builtins import iteritems

View File

@ -7,14 +7,15 @@ __copyright__ = '2014, Kovid Goyal <kovid at kovidgoyal.net>'
import re import re
from css_parser.css import CSSRule
from qt.core import QAction, QInputDialog
from calibre import force_unicode from calibre import force_unicode
from calibre.ebooks.oeb.polish.container import OEB_DOCS, OEB_STYLES, serialize from calibre.ebooks.oeb.polish.container import OEB_DOCS, OEB_STYLES, serialize
from calibre.gui2 import error_dialog from calibre.gui2 import error_dialog
# The base class that all tools must inherit from # The base class that all tools must inherit from
from calibre.gui2.tweak_book.plugin import Tool from calibre.gui2.tweak_book.plugin import Tool
from css_parser.css import CSSRule
from qt.core import QAction, QInputDialog
class DemoTool(Tool): class DemoTool(Tool):

View File

@ -6,9 +6,10 @@ __license__ = 'GPL v3'
__copyright__ = '2011, Kovid Goyal <kovid@kovidgoyal.net>' __copyright__ = '2011, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'
from calibre.utils.config import JSONConfig
from qt.core import QHBoxLayout, QLabel, QLineEdit, QWidget from qt.core import QHBoxLayout, QLabel, QLineEdit, QWidget
from calibre.utils.config import JSONConfig
# This is where all preferences for this plugin will be stored # This is where all preferences for this plugin will be stored
# Remember that this name (i.e. plugins/interface_demo) is also # Remember that this name (i.e. plugins/interface_demo) is also
# in a global namespace, so make it as unique as possible. # in a global namespace, so make it as unique as possible.

View File

@ -12,9 +12,10 @@ if False:
# You do not need this code in your plugins # You do not need this code in your plugins
get_icons = get_resources = None get_icons = get_resources = None
from calibre_plugins.interface_demo.config import prefs
from qt.core import QDialog, QLabel, QMessageBox, QPushButton, QVBoxLayout from qt.core import QDialog, QLabel, QMessageBox, QPushButton, QVBoxLayout
from calibre_plugins.interface_demo.config import prefs
class DemoDialog(QDialog): class DemoDialog(QDialog):

View File

@ -4,24 +4,35 @@ requires-python = ">=3.8"
[tool.ruff] [tool.ruff]
line-length = 160 line-length = 160
target-version = 'py38' target-version = 'py38'
builtins = ['_'] builtins = ['_', 'I', 'P']
include = ['*.py', '*.recipe']
[tool.ruff.lint] exclude = [
ignore = ['E741', 'E402', 'E722', 'E401'] "*_ui.py",
select = ['E', 'F', 'I'] "bypy/*",
"setup/*",
[tool.ruff.lint.per-file-ignores] "src/css_selectors/*",
"src/calibre/ebooks/unihandecode/unicodepoints.py" = ["E501"] "src/polyglot/*",
"src/qt/__init__.py" = ["E501"] "src/templite/*",
"src/tinycss/*",
]
[tool.ruff.format] [tool.ruff.format]
quote-style = 'single' quote-style = 'single'
[tool.ruff.lint]
ignore = ['E402', 'E722', 'E741', 'E401']
select = ['E', 'F', 'I', 'W']
[tool.ruff.lint.per-file-ignores]
"src/calibre/ebooks/unihandecode/*codepoints.py" = ['E501', 'W191']
"src/qt/*.py" = ['I']
"src/qt/*.pyi" = ['I']
[tool.ruff.lint.isort] [tool.ruff.lint.isort]
detect-same-package = true detect-same-package = true
extra-standard-library = ['aes', 'elementmaker', 'encodings'] extra-standard-library = ["aes", "elementmaker", "encodings"]
known-first-party = ["calibre_extensions", 'polyglot'] known-first-party = ["calibre_extensions", "calibre_plugins", "polyglot"]
known-third-party = ["qt"] known-third-party = ["odf", "qt", "templite", "tinycss", "css_selectors"]
relative-imports-order = "closest-to-furthest" relative-imports-order = "closest-to-furthest"
split-on-trailing-comma = false split-on-trailing-comma = false
section-order = ['__python__', "future", "standard-library", "third-party", "first-party", "local-folder"] section-order = ['__python__', "future", "standard-library", "third-party", "first-party", "local-folder"]

View File

@ -7,12 +7,13 @@ from collections import defaultdict
from datetime import datetime, timedelta from datetime import datetime, timedelta
from urllib.parse import quote, urlencode from urllib.parse import quote, urlencode
from html5_parser import parse
from lxml import etree
from calibre import replace_entities from calibre import replace_entities
from calibre.ebooks.BeautifulSoup import NavigableString, Tag from calibre.ebooks.BeautifulSoup import NavigableString, Tag
from calibre.ptempfile import PersistentTemporaryFile from calibre.ptempfile import PersistentTemporaryFile
from calibre.web.feeds.news import BasicNewsRecipe from calibre.web.feeds.news import BasicNewsRecipe
from html5_parser import parse
from lxml import etree
use_archive = True use_archive = True

View File

@ -4,9 +4,10 @@ __copyright__ = '2010, Walt Anthony <workshop.northpole at gmail.com>'
www.americanthinker.com www.americanthinker.com
''' '''
import html5lib import html5lib
from lxml import etree
from calibre.utils.cleantext import clean_xml_chars from calibre.utils.cleantext import clean_xml_chars
from calibre.web.feeds.news import BasicNewsRecipe from calibre.web.feeds.news import BasicNewsRecipe
from lxml import etree
class AmericanThinker(BasicNewsRecipe): class AmericanThinker(BasicNewsRecipe):

View File

@ -4,9 +4,10 @@ __copyright__ = '2009-2010, Darko Miletic <darko.miletic at gmail.com>'
spectator.org spectator.org
''' '''
from calibre.web.feeds.news import BasicNewsRecipe
from css_selectors import Select from css_selectors import Select
from calibre.web.feeds.news import BasicNewsRecipe
class TheAmericanSpectator(BasicNewsRecipe): class TheAmericanSpectator(BasicNewsRecipe):
title = 'The American Spectator' title = 'The American Spectator'

View File

@ -7,7 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
class BeforeWeGo(BasicNewsRecipe): class BeforeWeGo(BasicNewsRecipe):
title = 'Before We Go' title = 'Before We Go'
__author__ = 'bugmen00t' __author__ = 'bugmen00t'
description = 'Before We Go Blog is a collective of Fantasy, Sci-Fi and Graphic Novel fans from around the world, passionate about providing awesome, enjoyable reviews for anyone who loves a good book!' # noqa description = 'Before We Go Blog is a collective of Fantasy, Sci-Fi and Graphic Novel fans from around the world, passionate about providing awesome, enjoyable reviews for anyone who loves a good book!' # noqa
publisher = 'BEFOREWEGOBLOG' publisher = 'BEFOREWEGOBLOG'

View File

@ -3,9 +3,10 @@
import json import json
from datetime import datetime from datetime import datetime
from calibre.web.feeds.news import BasicNewsRecipe
from html5_parser import parse from html5_parser import parse
from calibre.web.feeds.news import BasicNewsRecipe
class BusinessStandard(BasicNewsRecipe): class BusinessStandard(BasicNewsRecipe):
title = 'Business Standard' title = 'Business Standard'

View File

@ -3,9 +3,10 @@
import json import json
from urllib.parse import quote, urlparse from urllib.parse import quote, urlparse
from calibre.web.feeds.news import BasicNewsRecipe
from mechanize import Request from mechanize import Request
from calibre.web.feeds.news import BasicNewsRecipe
def absurl(x): def absurl(x):
if x.startswith('//'): if x.startswith('//'):

View File

@ -5,7 +5,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
class CATOInstitute(BasicNewsRecipe): class CATOInstitute(BasicNewsRecipe):
title = u'The CATO Institute' title = u'The CATO Institute'
description = "The Cato Institute is a public policy research organization — a think tank — \ description = "The Cato Institute is a public policy research organization — a think tank — \
dedicated to the principles of individual liberty, limited government, free markets and peace.\ dedicated to the principles of individual liberty, limited government, free markets and peace.\
Its scholars and analysts conduct independent, nonpartisan research on a wide range of policy issues." Its scholars and analysts conduct independent, nonpartisan research on a wide range of policy issues."
__author__ = '_reader' __author__ = '_reader'

View File

@ -5,7 +5,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
class Cherta(BasicNewsRecipe): class Cherta(BasicNewsRecipe):
title = '\u0427\u0435\u0440\u0442\u0430' title = '\u0427\u0435\u0440\u0442\u0430'
__author__ = 'bugmen00t' __author__ = 'bugmen00t'
description = ' \u0418\u043D\u0442\u0435\u0440\u0435\u0441\u043D\u044B\u0435, \u0432\u0430\u0436\u043D\u044B\u0435 \u0438 \u0433\u043B\u0443\u0431\u043E\u043A\u0438\u0435 \u0442\u0435\u043A\u0441\u0442\u044B \u043F\u0440\u043E \u043D\u0430\u0441\u0438\u043B\u0438\u0435 \u0438 \u043D\u0435\u0440\u0430\u0432\u0435\u043D\u0441\u0442\u0432\u043E \u0432 \u0420\u043E\u0441\u0441\u0438\u0438.' # noqa description = ' \u0418\u043D\u0442\u0435\u0440\u0435\u0441\u043D\u044B\u0435, \u0432\u0430\u0436\u043D\u044B\u0435 \u0438 \u0433\u043B\u0443\u0431\u043E\u043A\u0438\u0435 \u0442\u0435\u043A\u0441\u0442\u044B \u043F\u0440\u043E \u043D\u0430\u0441\u0438\u043B\u0438\u0435 \u0438 \u043D\u0435\u0440\u0430\u0432\u0435\u043D\u0441\u0442\u0432\u043E \u0432 \u0420\u043E\u0441\u0441\u0438\u0438.' # noqa
publisher = 'cherta.media' publisher = 'cherta.media'

View File

@ -18,7 +18,6 @@ class herald(BasicNewsRecipe):
keep_only_tags = [ keep_only_tags = [
classes('article-title article-author__name'), classes('article-title article-author__name'),
dict(name='div', attrs={'id':'main-content'}) dict(name='div', attrs={'id':'main-content'})
] ]
remove_tags = [ remove_tags = [

View File

@ -7,7 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
class WiComix(BasicNewsRecipe): class WiComix(BasicNewsRecipe):
title = 'dev.ua' title = 'dev.ua'
__author__ = 'bugmen00t' __author__ = 'bugmen00t'
publisher = '\u0422\u041E\u0412 \u00AB\u0414\u0435\u0432 \u0423\u043A\u0440\u0430\u0457\u043D\u0430\u00BB' publisher = '\u0422\u041E\u0412 \u00AB\u0414\u0435\u0432 \u0423\u043A\u0440\u0430\u0457\u043D\u0430\u00BB'
category = 'news' category = 'news'

View File

@ -16,6 +16,7 @@ try:
except ImportError: except ImportError:
from cookielib import Cookie from cookielib import Cookie
import mechanize import mechanize
from calibre.web.feeds.news import BasicNewsRecipe from calibre.web.feeds.news import BasicNewsRecipe

View File

@ -39,7 +39,7 @@ class DRNyheder(BasicNewsRecipe):
publisher = 'DR Nyheder' publisher = 'DR Nyheder'
description = 'Her finder du nyheder fra DR.' description = 'Her finder du nyheder fra DR.'
category = 'news, politics, money, culture, sport, science, Denmark' category = 'news, politics, money, culture, sport, science, Denmark'
publication_type = 'newspaper' publication_type = 'newspaper'
encoding = 'utf8' encoding = 'utf8'
language = 'da' language = 'da'
oldest_article = 4 # 2 might be best oldest_article = 4 # 2 might be best
@ -47,7 +47,7 @@ class DRNyheder(BasicNewsRecipe):
no_stylesheets = True no_stylesheets = True
use_embedded_content = False use_embedded_content = False
auto_cleanup = False auto_cleanup = False
remove_empty_feeds = True remove_empty_feeds = True
ignore_duplicate_articles = {'title', 'url'} ignore_duplicate_articles = {'title', 'url'}
simultaneous_downloads = 20 simultaneous_downloads = 20
compress_news_images = True compress_news_images = True

View File

@ -4,7 +4,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
class EchoMsk(BasicNewsRecipe): class EchoMsk(BasicNewsRecipe):
title = '\u042D\u0425\u041E' title = '\u042D\u0425\u041E'
__author__ = 'bugmen00t' __author__ = 'bugmen00t'
description = ('\u042D\u0425\u041E - \u043A\u0430\u043A \u043D\u0430 \u0441\u0442\u0430\u0440\u043E\u043C' description = ('\u042D\u0425\u041E - \u043A\u0430\u043A \u043D\u0430 \u0441\u0442\u0430\u0440\u043E\u043C'
' \u0434\u043E\u0431\u0440\u043E\u043C \u0440\u0430\u0434\u0438\u043E') ' \u0434\u043E\u0431\u0440\u043E\u043C \u0440\u0430\u0434\u0438\u043E')

View File

@ -53,7 +53,7 @@ class JSONHasNoContent(ValueError):
def load_article_from_json(raw, root): def load_article_from_json(raw, root):
# open('/t/raw.json', 'w').write(raw) # open('/t/raw.json', 'w').write(raw)
data = json.loads(raw) data = json.loads(raw)
body = root.xpath('//body')[0] body = root.xpath('//body')[0]
article = E(body, 'article') article = E(body, 'article')

View File

@ -42,7 +42,7 @@ class EpochTimes(BasicNewsRecipe):
dict(name='img', attrs={'src':lambda x: x and x.endswith('svg')}) dict(name='img', attrs={'src':lambda x: x and x.endswith('svg')})
] ]
# feeds can be found at https://www.theepochtimes.com/rssfeeds # feeds can be found at https://www.theepochtimes.com/rssfeeds
feeds = [ feeds = [
('Special Series', 'https://feed.theepochtimes.com/health/special-series/feed'), ('Special Series', 'https://feed.theepochtimes.com/health/special-series/feed'),
('US', 'https://feed.theepochtimes.com/us/feed'), ('US', 'https://feed.theepochtimes.com/us/feed'),

View File

@ -5,9 +5,10 @@ www.esquire.com
''' '''
from collections import defaultdict from collections import defaultdict
from calibre.web.feeds.news import BasicNewsRecipe
from css_selectors import Select from css_selectors import Select
from calibre.web.feeds.news import BasicNewsRecipe
def absolutize(url): def absolutize(url):
if url.startswith('/'): if url.startswith('/'):

View File

@ -4,9 +4,10 @@ import json
import re import re
from urllib.parse import quote from urllib.parse import quote
from html5_parser import parse
from calibre import browser from calibre import browser
from calibre.web.feeds.news import BasicNewsRecipe, classes from calibre.web.feeds.news import BasicNewsRecipe, classes
from html5_parser import parse
class ft(BasicNewsRecipe): class ft(BasicNewsRecipe):

View File

@ -7,9 +7,10 @@ __copyright__ = '2017, John Hutson <jfhutson at gmail.com>'
firstthings.com firstthings.com
''' '''
import html5lib import html5lib
from calibre.web.feeds.news import BasicNewsRecipe
from lxml import html from lxml import html
from calibre.web.feeds.news import BasicNewsRecipe
class FirstThings(BasicNewsRecipe): class FirstThings(BasicNewsRecipe):

View File

@ -4,9 +4,10 @@ import re
import html5lib import html5lib
import mechanize import mechanize
from calibre.web.feeds.news import BasicNewsRecipe, classes
from lxml import html from lxml import html
from calibre.web.feeds.news import BasicNewsRecipe, classes
def as_article(source, log): def as_article(source, log):
url = source['url'] url = source['url']

View File

@ -20,9 +20,9 @@ class google_news_de(BasicNewsRecipe):
cover_url = 'https://upload.wikimedia.org/wikipedia/commons/thumb/d/da/Google_News_icon.svg/500px-Google_News_icon.svg.png' cover_url = 'https://upload.wikimedia.org/wikipedia/commons/thumb/d/da/Google_News_icon.svg/500px-Google_News_icon.svg.png'
# Author # Author
__author__ = 'Volker Heggemann, VoHe, unkn0wn' __author__ = 'Volker Heggemann, VoHe, unkn0wn'
# oldest article to download (in days) ---- can be edit by user # oldest article to download (in days) ---- can be edit by user
oldest_article = 1.25 oldest_article = 1.25
# describes itself, ---- can be edit by user # describes itself, ---- can be edit by user
max_articles_per_feed = 200 max_articles_per_feed = 200
# speed up the download on fast computers be careful (I test max.20) # speed up the download on fast computers be careful (I test max.20)
# ---- can be edit by user # ---- can be edit by user
@ -31,7 +31,7 @@ class google_news_de(BasicNewsRecipe):
description = u'Google News filter by your own recipe. Please read it in calibre software!' description = u'Google News filter by your own recipe. Please read it in calibre software!'
# What is the content of? # What is the content of?
category = u'NEWS' category = u'NEWS'
# describes itself, ---- can be edit by user # describes itself, ---- can be edit by user
use_embedded_content = False use_embedded_content = False
remove_javascript = True remove_javascript = True
# Removes empty feeds - why keep them!? # Removes empty feeds - why keep them!?
@ -65,7 +65,7 @@ class google_news_de(BasicNewsRecipe):
return pt.name return pt.name
# now the content description and URL follows # now the content description and URL follows
# feel free to add, wipe out what you need ---- can be edit by user # feel free to add, wipe out what you need ---- can be edit by user
# #
def get_feeds(self): def get_feeds(self):
url = "https://geolocation-db.com/json" url = "https://geolocation-db.com/json"

View File

@ -5,7 +5,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
class Gorky(BasicNewsRecipe): class Gorky(BasicNewsRecipe):
title = '\u0413\u043E\u0440\u044C\u043A\u0438\u0439' title = '\u0413\u043E\u0440\u044C\u043A\u0438\u0439'
__author__ = 'bugmen00t' __author__ = 'bugmen00t'
description = '\u041D\u0435\u043A\u043E\u043C\u043C\u0435\u0440\u0447\u0435\u0441\u043A\u0438\u0439 \u043F\u0440\u043E\u0435\u043A\u0442 \u043E \u043A\u043D\u0438\u0433\u0430\u0445 \u0438 \u0447\u0442\u0435\u043D\u0438\u0438.' # noqa description = '\u041D\u0435\u043A\u043E\u043C\u043C\u0435\u0440\u0447\u0435\u0441\u043A\u0438\u0439 \u043F\u0440\u043E\u0435\u043A\u0442 \u043E \u043A\u043D\u0438\u0433\u0430\u0445 \u0438 \u0447\u0442\u0435\u043D\u0438\u0438.' # noqa
publisher = '\u0410\u041D\u041E "\u0426\u0435\u043D\u0442\u0440 \u043F\u043E \u0441\u043E\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044E \u0440\u0430\u0437\u0432\u0438\u0442\u0438\u044F \u043A\u0443\u043B\u044C\u0442\u0443\u0440\u044B \u0447\u0442\u0435\u043D\u0438\u044F \u0438 \u043A\u043D\u0438\u0433\u043E\u0438\u0437\u0434\u0430\u043D\u0438\u044F \u00AB\u0413\u043E\u0440\u044C\u043A\u0438\u0439 \u041C\u0435\u0434\u0438\u0430\u00BB"' # noqa publisher = '\u0410\u041D\u041E "\u0426\u0435\u043D\u0442\u0440 \u043F\u043E \u0441\u043E\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044E \u0440\u0430\u0437\u0432\u0438\u0442\u0438\u044F \u043A\u0443\u043B\u044C\u0442\u0443\u0440\u044B \u0447\u0442\u0435\u043D\u0438\u044F \u0438 \u043A\u043D\u0438\u0433\u043E\u0438\u0437\u0434\u0430\u043D\u0438\u044F \u00AB\u0413\u043E\u0440\u044C\u043A\u0438\u0439 \u041C\u0435\u0434\u0438\u0430\u00BB"' # noqa

View File

@ -8,9 +8,10 @@ __copyright__ = '2011, Piotr Kontek, piotr.kontek@gmail.com \
import re import re
import time import time
from calibre.web.feeds.news import BasicNewsRecipe
from lxml import html from lxml import html
from calibre.web.feeds.news import BasicNewsRecipe
class GN(BasicNewsRecipe): class GN(BasicNewsRecipe):
__author__ = 'Piotr Kontek, Tomasz Długosz' __author__ = 'Piotr Kontek, Tomasz Długosz'

View File

@ -7,9 +7,10 @@ __copyright__ = '2011, Piotr Kontek, piotr.kontek@gmail.com \
import re import re
from calibre.web.feeds.news import BasicNewsRecipe
from lxml import html from lxml import html
from calibre.web.feeds.news import BasicNewsRecipe
class GN(BasicNewsRecipe): class GN(BasicNewsRecipe):
__author__ = 'Piotr Kontek, Tomasz Długosz' __author__ = 'Piotr Kontek, Tomasz Długosz'

View File

@ -5,9 +5,10 @@ import re
from collections import OrderedDict from collections import OrderedDict
from urllib.parse import urlencode, urljoin from urllib.parse import urlencode, urljoin
from mechanize import Request
from calibre import browser, random_user_agent from calibre import browser, random_user_agent
from calibre.web.feeds.news import BasicNewsRecipe, classes from calibre.web.feeds.news import BasicNewsRecipe, classes
from mechanize import Request
class HBR(BasicNewsRecipe): class HBR(BasicNewsRecipe):

View File

@ -2,9 +2,10 @@
# vim:fileencoding=utf-8 # vim:fileencoding=utf-8
import json import json
from calibre.web.feeds.news import BasicNewsRecipe
from html5_parser import parse from html5_parser import parse
from calibre.web.feeds.news import BasicNewsRecipe
def get_story(story): def get_story(story):
str_type = story.get('type', '') str_type = story.get('type', '')

View File

@ -1,7 +1,7 @@
########################################################################## ##########################################################################
# Description: http://hvg.hu/ RSS channel # Description: http://hvg.hu/ RSS channel
# Author: Bigpapa (bigpapabig@hotmail.com) # Author: Bigpapa (bigpapabig@hotmail.com)
# Date: 2011.12.20. - V1.1 # Date: 2011.12.20. - V1.1
########################################################################## ##########################################################################
from calibre.web.feeds.news import BasicNewsRecipe from calibre.web.feeds.news import BasicNewsRecipe
@ -11,7 +11,7 @@ class hvg(BasicNewsRecipe):
title = u'HVG' title = u'HVG'
__author__ = 'Bigpapa' __author__ = 'Bigpapa'
language = 'hu' language = 'hu'
oldest_article = 5 # Hany napos legyen a legregebbi cikk amit leszedjen. oldest_article = 5 # Hany napos legyen a legregebbi cikk amit leszedjen.
# Az adott e-bookban tarolt cikkek feedenkenti maximalis szamat adja meg. # Az adott e-bookban tarolt cikkek feedenkenti maximalis szamat adja meg.
max_articles_per_feed = 5 max_articles_per_feed = 5
no_stylesheets = True no_stylesheets = True

View File

@ -8,9 +8,10 @@ import json
from contextlib import closing from contextlib import closing
from time import sleep from time import sleep
from calibre.web.feeds.news import BasicNewsRecipe
from mechanize import Request from mechanize import Request
from calibre.web.feeds.news import BasicNewsRecipe
def absolutize(url): def absolutize(url):
if url.startswith('/'): if url.startswith('/'):

View File

@ -129,11 +129,11 @@ class LeMonde(BasicNewsRecipe):
dict(name=['footer', 'link', 'meta', 'svg', 'button', 'source']), dict(name=['footer', 'link', 'meta', 'svg', 'button', 'source']),
dict(name='img', attrs={'class': ['article__author-picture']}), dict(name='img', attrs={'class': ['article__author-picture']}),
dict(name='section', attrs={'class': dict(name='section', attrs={'class':
[ [
'inread js-services-inread', 'catcher catcher--inline', 'inread inread--NL js-services-inread', 'inread js-services-inread', 'catcher catcher--inline', 'inread inread--NL js-services-inread',
'article__reactions', 'author', 'catcher', 'portfolio', 'services-inread' 'article__reactions', 'author', 'catcher', 'portfolio', 'services-inread'
] ]
}) })
] ]
remove_attributes = [ remove_attributes = [

View File

@ -30,7 +30,7 @@ class AdvancedUserRecipe1591780224(BasicNewsRecipe):
# remove the rubbish (in ebook) # remove the rubbish (in ebook)
auto_cleanup = True auto_cleanup = True
# now the content description and URL follows # now the content description and URL follows
# feel free to add, wipe out what you need ---- can be edit by user # feel free to add, wipe out what you need ---- can be edit by user
# #
# some of this are double # some of this are double
# #

View File

@ -118,9 +118,10 @@ class Mediapart(BasicNewsRecipe):
''' '''
Create a generic cover for recipes that don't have a cover Create a generic cover for recipes that don't have a cover
''' '''
from calibre.gui2 import ensure_app, load_builtin_fonts, pixmap_to_data
from qt.core import QFont, QImage, QPainter, QPen, QRect, Qt from qt.core import QFont, QImage, QPainter, QPen, QRect, Qt
from calibre.gui2 import ensure_app, load_builtin_fonts, pixmap_to_data
def init_environment(): def init_environment():
ensure_app() ensure_app()
load_builtin_fonts() load_builtin_fonts()

View File

@ -5,7 +5,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
class MoscowTimes(BasicNewsRecipe): class MoscowTimes(BasicNewsRecipe):
title = 'The Moscow Times' title = 'The Moscow Times'
__author__ = 'bugmen00t' __author__ = 'bugmen00t'
description = 'The Moscow Times is Russias leading, independent English-language media outlet. Our team of Russian and English journalists provide readers across the world with breaking news, engaging stories and balanced reporting about the largest country on Earth.' # noqa description = 'The Moscow Times is Russias leading, independent English-language media outlet. Our team of Russian and English journalists provide readers across the world with breaking news, engaging stories and balanced reporting about the largest country on Earth.' # noqa
publisher = 'Tiamti LLC' publisher = 'Tiamti LLC'

View File

@ -9,9 +9,9 @@ class MyDealzDE(BasicNewsRecipe):
title = 'MyDealz' title = 'MyDealz'
# Author # Author
__author__ = 'Volker Heggemann, VoHe' __author__ = 'Volker Heggemann, VoHe'
# oldest article to download (in days) ---- can be edit by user # oldest article to download (in days) ---- can be edit by user
oldest_article = 5 oldest_article = 5
# describes itself, ---- can be edit by user # describes itself, ---- can be edit by user
max_articles_per_feed = 100 max_articles_per_feed = 100
# Cover Picture # Cover Picture
cover_url = 'https://pbs.twimg.com/profile_images/817053687545741313/0wFqvfqC_400x400.jpg' cover_url = 'https://pbs.twimg.com/profile_images/817053687545741313/0wFqvfqC_400x400.jpg'
@ -24,9 +24,9 @@ class MyDealzDE(BasicNewsRecipe):
publisher = u'https://www.mydealz.de' publisher = u'https://www.mydealz.de'
# What is the content of? # What is the content of?
category = u'Shopping' category = u'Shopping'
# describes itself, ---- can be edit by user # describes itself, ---- can be edit by user
use_embedded_content = False use_embedded_content = False
# describes itself, ---- can be edit by user # describes itself, ---- can be edit by user
language = 'de' language = 'de'
# encoding of content. e.g. utf-8, None, ... # encoding of content. e.g. utf-8, None, ...
# ---- can be edit by user # ---- can be edit by user
@ -39,7 +39,7 @@ class MyDealzDE(BasicNewsRecipe):
# remove the rubbish (in ebook) # remove the rubbish (in ebook)
auto_cleanup = True auto_cleanup = True
# now the content description and URL follows # now the content description and URL follows
# feel free to add, wipe out what you need ---- can be edit by user # feel free to add, wipe out what you need ---- can be edit by user
# #
# some of this are double # some of this are double
# #

View File

@ -1,7 +1,7 @@
########################################################################## ##########################################################################
# Description: http://nol.hu/ RSS channel # Description: http://nol.hu/ RSS channel
# Author: Bigpapa (bigpapabig@hotmail.com) # Author: Bigpapa (bigpapabig@hotmail.com)
# Date: 2011.12.18. - V1.1 # Date: 2011.12.18. - V1.1
########################################################################## ##########################################################################
from calibre.web.feeds.recipes import BasicNewsRecipe from calibre.web.feeds.recipes import BasicNewsRecipe

View File

@ -4,9 +4,10 @@ import json
import re import re
from contextlib import closing from contextlib import closing
from calibre.web.feeds.recipes import BasicNewsRecipe
from mechanize import Request from mechanize import Request
from calibre.web.feeds.recipes import BasicNewsRecipe
class NRC(BasicNewsRecipe): class NRC(BasicNewsRecipe):
title = 'NRC' title = 'NRC'

View File

@ -1,9 +1,10 @@
import json import json
from datetime import datetime from datetime import datetime
from calibre.web.feeds.recipes import BasicNewsRecipe
from mechanize import Request from mechanize import Request
from calibre.web.feeds.recipes import BasicNewsRecipe
class Nzz(BasicNewsRecipe): class Nzz(BasicNewsRecipe):
title = 'NZZ' title = 'NZZ'

View File

@ -7,9 +7,10 @@ odb.org
import uuid import uuid
from calibre.web.feeds.news import BasicNewsRecipe
from lxml import html from lxml import html
from calibre.web.feeds.news import BasicNewsRecipe
class OurDailyBread(BasicNewsRecipe): class OurDailyBread(BasicNewsRecipe):
title = 'Our Daily Bread' title = 'Our Daily Bread'

View File

@ -7,7 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
class PaperPaper(BasicNewsRecipe): class PaperPaper(BasicNewsRecipe):
title = '\u0411\u0443\u043C\u0430\u0433\u0430' title = '\u0411\u0443\u043C\u0430\u0433\u0430'
__author__ = 'bugmen00t' __author__ = 'bugmen00t'
description = '\u0418\u0437\u0434\u0430\u043D\u0438\u0435 \u043E \u043F\u0440\u0435\u043A\u0440\u0430\u0441\u043D\u043E\u043C \u0433\u043E\u0440\u043E\u0434\u0435 \u0421\u0430\u043D\u043A\u0442-\u041F\u0435\u0442\u0435\u0440\u0431\u0443\u0440\u0433\u0435, \u0432 \u043A\u043E\u0442\u043E\u0440\u043E\u043C, \u043A\u043E\u043D\u0435\u0447\u043D\u043E, \u0434\u0430\u043B\u0435\u043A\u043E \u043D\u0435 \u0432\u0441\u0451 \u0438\u0434\u0435\u0430\u043B\u044C\u043D\u043E, \u2014 \u0438 \u043F\u043E\u044D\u0442\u043E\u043C\u0443 \u043C\u044B \u0437\u0430\u043D\u0438\u043C\u0430\u0435\u043C\u0441\u044F \u0436\u0443\u0440\u043D\u0430\u043B\u0438\u0441\u0442\u0438\u043A\u043E\u0439, \u0447\u0442\u043E\u0431\u044B \u043F\u0440\u0438\u0432\u043B\u0435\u043A\u0430\u0442\u044C \u0432\u043D\u0438\u043C\u0430\u043D\u0438\u0435 \u043A \u0432\u0430\u0436\u043D\u044B\u043C \u0434\u043B\u044F \u0432\u0441\u0435\u0445 \u043F\u0440\u043E\u0431\u043B\u0435\u043C\u0430\u043C \u0438 \u0432\u043B\u0438\u044F\u0442\u044C \u043D\u0430 \u0438\u0445 \u0440\u0435\u0448\u0435\u043D\u0438\u0435.' # noqa description = '\u0418\u0437\u0434\u0430\u043D\u0438\u0435 \u043E \u043F\u0440\u0435\u043A\u0440\u0430\u0441\u043D\u043E\u043C \u0433\u043E\u0440\u043E\u0434\u0435 \u0421\u0430\u043D\u043A\u0442-\u041F\u0435\u0442\u0435\u0440\u0431\u0443\u0440\u0433\u0435, \u0432 \u043A\u043E\u0442\u043E\u0440\u043E\u043C, \u043A\u043E\u043D\u0435\u0447\u043D\u043E, \u0434\u0430\u043B\u0435\u043A\u043E \u043D\u0435 \u0432\u0441\u0451 \u0438\u0434\u0435\u0430\u043B\u044C\u043D\u043E, \u2014 \u0438 \u043F\u043E\u044D\u0442\u043E\u043C\u0443 \u043C\u044B \u0437\u0430\u043D\u0438\u043C\u0430\u0435\u043C\u0441\u044F \u0436\u0443\u0440\u043D\u0430\u043B\u0438\u0441\u0442\u0438\u043A\u043E\u0439, \u0447\u0442\u043E\u0431\u044B \u043F\u0440\u0438\u0432\u043B\u0435\u043A\u0430\u0442\u044C \u0432\u043D\u0438\u043C\u0430\u043D\u0438\u0435 \u043A \u0432\u0430\u0436\u043D\u044B\u043C \u0434\u043B\u044F \u0432\u0441\u0435\u0445 \u043F\u0440\u043E\u0431\u043B\u0435\u043C\u0430\u043C \u0438 \u0432\u043B\u0438\u044F\u0442\u044C \u043D\u0430 \u0438\u0445 \u0440\u0435\u0448\u0435\u043D\u0438\u0435.' # noqa
publisher = '\u041A\u0438\u0440\u0438\u043B\u043B \u0410\u0440\u0442\u0451\u043C\u0435\u043D\u043A\u043E, \u0422\u0430\u0442\u044C\u044F\u043D\u0430 \u0418\u0432\u0430\u043D\u043E\u0432\u0430' # noqa publisher = '\u041A\u0438\u0440\u0438\u043B\u043B \u0410\u0440\u0442\u0451\u043C\u0435\u043D\u043A\u043E, \u0422\u0430\u0442\u044C\u044F\u043D\u0430 \u0418\u0432\u0430\u043D\u043E\u0432\u0430' # noqa

View File

@ -3,9 +3,10 @@ import json
import uuid import uuid
from contextlib import closing from contextlib import closing
from calibre.web.feeds.recipes import BasicNewsRecipe
from mechanize import Request from mechanize import Request
from calibre.web.feeds.recipes import BasicNewsRecipe
class Parool(BasicNewsRecipe): class Parool(BasicNewsRecipe):
title = 'Het Parool' title = 'Het Parool'

View File

@ -7,7 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
class Poligon(BasicNewsRecipe): class Poligon(BasicNewsRecipe):
title = '\u041F\u043E\u043B\u0438\u0433\u043E\u043D' title = '\u041F\u043E\u043B\u0438\u0433\u043E\u043D'
__author__ = 'bugmen00t' __author__ = 'bugmen00t'
description = '\u041D\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043C\u043E\u0435 \u0438\u043D\u0442\u0435\u0440\u043D\u0435\u0442-\u0438\u0437\u0434\u0430\u043D\u0438\u0435, \u0432\u044B\u043F\u0443\u0441\u043A\u0430\u0435\u043C\u043E\u0435 \u0436\u0443\u0440\u043D\u0430\u043B\u0438\u0441\u0442\u0430\u043C\u0438 \u043D\u0435\u0441\u043A\u043E\u043B\u044C\u043A\u0438\u0445 \u0440\u043E\u0441\u0441\u0438\u0439\u0441\u043A\u0438\u0445 \u0438\u0437\u0434\u0430\u043D\u0438\u0439, \u043F\u043E\u0434\u0432\u0435\u0440\u0433\u0448\u0438\u0445\u0441\u044F \u0434\u0430\u0432\u043B\u0435\u043D\u0438\u044E \u0441\u043E \u0441\u0442\u043E\u0440\u043E\u043D\u044B \u0433\u043E\u0441\u0443\u0434\u0430\u0440\u0441\u0442\u0432\u0430. \u041F\u0438\u0448\u0435\u043C \u043E \u0420\u043E\u0441\u0441\u0438\u0438 \u0438 \u043D\u0435 \u0442\u043E\u043B\u044C\u043A\u043E.' # noqa description = '\u041D\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043C\u043E\u0435 \u0438\u043D\u0442\u0435\u0440\u043D\u0435\u0442-\u0438\u0437\u0434\u0430\u043D\u0438\u0435, \u0432\u044B\u043F\u0443\u0441\u043A\u0430\u0435\u043C\u043E\u0435 \u0436\u0443\u0440\u043D\u0430\u043B\u0438\u0441\u0442\u0430\u043C\u0438 \u043D\u0435\u0441\u043A\u043E\u043B\u044C\u043A\u0438\u0445 \u0440\u043E\u0441\u0441\u0438\u0439\u0441\u043A\u0438\u0445 \u0438\u0437\u0434\u0430\u043D\u0438\u0439, \u043F\u043E\u0434\u0432\u0435\u0440\u0433\u0448\u0438\u0445\u0441\u044F \u0434\u0430\u0432\u043B\u0435\u043D\u0438\u044E \u0441\u043E \u0441\u0442\u043E\u0440\u043E\u043D\u044B \u0433\u043E\u0441\u0443\u0434\u0430\u0440\u0441\u0442\u0432\u0430. \u041F\u0438\u0448\u0435\u043C \u043E \u0420\u043E\u0441\u0441\u0438\u0438 \u0438 \u043D\u0435 \u0442\u043E\u043B\u044C\u043A\u043E.' # noqa
publisher = 'poligon.media' publisher = 'poligon.media'

View File

@ -12,9 +12,9 @@ class PressePortalDE(BasicNewsRecipe):
title = 'Presseportal DE' title = 'Presseportal DE'
# Author # Author
__author__ = 'Volker Heggemann, VoHe' __author__ = 'Volker Heggemann, VoHe'
# oldest article to download (in days) ---- can be edit by user # oldest article to download (in days) ---- can be edit by user
oldest_article = 1 oldest_article = 1
# describes itself, ---- can be edit by user # describes itself, ---- can be edit by user
max_articles_per_feed = 100 max_articles_per_feed = 100
# speed up the download on fast computers be careful (I test max.20) # speed up the download on fast computers be careful (I test max.20)
# ---- can be edit by user # ---- can be edit by user
@ -29,9 +29,9 @@ class PressePortalDE(BasicNewsRecipe):
publisher = u'Presseportal.de' publisher = u'Presseportal.de'
# What is the content of? # What is the content of?
category = u'latest news, national Police, Germany' category = u'latest news, national Police, Germany'
# describes itself, ---- can be edit by user # describes itself, ---- can be edit by user
use_embedded_content = False use_embedded_content = False
# describes itself, ---- can be edit by user # describes itself, ---- can be edit by user
language = 'de' language = 'de'
# encoding of content. e.g. utf-8, None, ... # encoding of content. e.g. utf-8, None, ...
# ---- can be edit by user # ---- can be edit by user
@ -44,7 +44,7 @@ class PressePortalDE(BasicNewsRecipe):
# remove the rubbish (in ebook) # remove the rubbish (in ebook)
auto_cleanup = True auto_cleanup = True
# now the content description and URL follows # now the content description and URL follows
# feel free to add, wipe out what you need ---- can be edit by user # feel free to add, wipe out what you need ---- can be edit by user
# #
# some of this are double # some of this are double
# so if you load "Alle Ressort" you don't need "Wirtschaft, Finanzen, Politik, Vermischtes..." at all. # so if you load "Alle Ressort" you don't need "Wirtschaft, Finanzen, Politik, Vermischtes..." at all.

View File

@ -7,7 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
class ProSleduet(BasicNewsRecipe): class ProSleduet(BasicNewsRecipe):
title = '\u041F\u0440\u043E\u0434\u043E\u043B\u0436\u0435\u043D\u0438\u0435 \u0441\u043B\u0435\u0434\u0443\u0435\u0442' title = '\u041F\u0440\u043E\u0434\u043E\u043B\u0436\u0435\u043D\u0438\u0435 \u0441\u043B\u0435\u0434\u0443\u0435\u0442'
__author__ = 'bugmen00t' __author__ = 'bugmen00t'
description = ('\u0414\u0438\u0434\u0436\u0438\u0442\u0430\u043B-\u043F\u0440\u043E\u0435\u043A\u0442' description = ('\u0414\u0438\u0434\u0436\u0438\u0442\u0430\u043B-\u043F\u0440\u043E\u0435\u043A\u0442'
' \u0436\u0443\u0440\u043D\u0430\u043B\u0438\u0441\u0442\u043E\u0432' ' \u0436\u0443\u0440\u043D\u0430\u043B\u0438\u0441\u0442\u043E\u0432'

View File

@ -9,7 +9,6 @@ publico.pt
''' '''
from calibre.web.feeds.news import BasicNewsRecipe from calibre.web.feeds.news import BasicNewsRecipe
from polyglot.urllib import urlencode from polyglot.urllib import urlencode

View File

@ -82,70 +82,70 @@ class RadioCanada(BasicNewsRecipe):
# From the list situated at https://ici.radio-canada.ca/rss # From the list situated at https://ici.radio-canada.ca/rss
feeds = [ feeds = [
# Information # Information
('Grands titres', 'https://ici.radio-canada.ca/rss/4159'), ('Grands titres', 'https://ici.radio-canada.ca/rss/4159'),
('En continu', 'https://ici.radio-canada.ca/rss/1000524'), ('En continu', 'https://ici.radio-canada.ca/rss/1000524'),
# Thématiques # Thématiques
('Alimentation', 'https://ici.radio-canada.ca/rss/7239'), ('Alimentation', 'https://ici.radio-canada.ca/rss/7239'),
('Art de vivre', 'https://ici.radio-canada.ca/rss/4163'), ('Art de vivre', 'https://ici.radio-canada.ca/rss/4163'),
('Économie', 'https://ici.radio-canada.ca/rss/5717'), ('Économie', 'https://ici.radio-canada.ca/rss/5717'),
('Environnement', 'https://ici.radio-canada.ca/rss/92408'), ('Environnement', 'https://ici.radio-canada.ca/rss/92408'),
('International', 'https://ici.radio-canada.ca/rss/96'), ('International', 'https://ici.radio-canada.ca/rss/96'),
('Justice et faits divers', 'https://ici.radio-canada.ca/rss/92411'), ('Justice et faits divers', 'https://ici.radio-canada.ca/rss/92411'),
('Politique', 'https://ici.radio-canada.ca/rss/4175'), ('Politique', 'https://ici.radio-canada.ca/rss/4175'),
('Santé', 'https://ici.radio-canada.ca/rss/4171'), ('Santé', 'https://ici.radio-canada.ca/rss/4171'),
('Science', 'https://ici.radio-canada.ca/rss/4165'), ('Science', 'https://ici.radio-canada.ca/rss/4165'),
('Société', 'https://ici.radio-canada.ca/rss/7110'), ('Société', 'https://ici.radio-canada.ca/rss/7110'),
('Techno', 'https://ici.radio-canada.ca/rss/4169'), ('Techno', 'https://ici.radio-canada.ca/rss/4169'),
# Sports # Sports
('Grands titres', 'https://ici.radio-canada.ca/rss/771'), ('Grands titres', 'https://ici.radio-canada.ca/rss/771'),
('Football', 'https://ici.radio-canada.ca/rss/1000057'), ('Football', 'https://ici.radio-canada.ca/rss/1000057'),
('Hockey', 'https://ici.radio-canada.ca/rss/1000056'), ('Hockey', 'https://ici.radio-canada.ca/rss/1000056'),
('Olympiques', 'https://ici.radio-canada.ca/rss/64852'), ('Olympiques', 'https://ici.radio-canada.ca/rss/64852'),
('Podium', 'https://ici.radio-canada.ca/rss/555082'), ('Podium', 'https://ici.radio-canada.ca/rss/555082'),
('Soccer', 'https://ici.radio-canada.ca/rss/1000058'), ('Soccer', 'https://ici.radio-canada.ca/rss/1000058'),
('Tennis', 'https://ici.radio-canada.ca/rss/1000059'), ('Tennis', 'https://ici.radio-canada.ca/rss/1000059'),
# Arts # Arts
('Grands Titres', 'https://ici.radio-canada.ca/rss/4167'), ('Grands Titres', 'https://ici.radio-canada.ca/rss/4167'),
('Célébrités', 'https://ici.radio-canada.ca/rss/1000232'), ('Célébrités', 'https://ici.radio-canada.ca/rss/1000232'),
('Cinéma', 'https://ici.radio-canada.ca/rss/1000229'), ('Cinéma', 'https://ici.radio-canada.ca/rss/1000229'),
('Humour', 'https://ici.radio-canada.ca/rss/1000231'), ('Humour', 'https://ici.radio-canada.ca/rss/1000231'),
('Livres', 'https://ici.radio-canada.ca/rss/1000083'), ('Livres', 'https://ici.radio-canada.ca/rss/1000083'),
('Musique', 'https://ici.radio-canada.ca/rss/1000230'), ('Musique', 'https://ici.radio-canada.ca/rss/1000230'),
('Télé', 'https://ici.radio-canada.ca/rss/1000233'), ('Télé', 'https://ici.radio-canada.ca/rss/1000233'),
# Régions # Régions
('Abitibi-Témiscamingue', 'https://ici.radio-canada.ca/rss/5763'), ('Abitibi-Témiscamingue', 'https://ici.radio-canada.ca/rss/5763'),
('Alberta', 'https://ici.radio-canada.ca/rss/5767'), ('Alberta', 'https://ici.radio-canada.ca/rss/5767'),
('Bas-Saint-Laurent', 'https://ici.radio-canada.ca/rss/35004'), ('Bas-Saint-Laurent', 'https://ici.radio-canada.ca/rss/35004'),
('Colombie-Brittanique', 'https://ici.radio-canada.ca/rss/5769'), ('Colombie-Brittanique', 'https://ici.radio-canada.ca/rss/5769'),
('Côte-Nord', 'https://ici.radio-canada.ca/rss/35019'), ('Côte-Nord', 'https://ici.radio-canada.ca/rss/35019'),
('Estrie', 'https://ici.radio-canada.ca/rss/5773'), ('Estrie', 'https://ici.radio-canada.ca/rss/5773'),
('Gaspésie-Îles-de-la-Madeleine', 'https://ici.radio-canada.ca/rss/35015'), ('Gaspésie-Îles-de-la-Madeleine', 'https://ici.radio-canada.ca/rss/35015'),
('Grand Montréal', 'https://ici.radio-canada.ca/rss/4201'), ('Grand Montréal', 'https://ici.radio-canada.ca/rss/4201'),
('Grand Nord', 'https://ici.radio-canada.ca/rss/1001049'), ('Grand Nord', 'https://ici.radio-canada.ca/rss/1001049'),
('Île-du-Prince-Édouard', 'https://ici.radio-canada.ca/rss/1000814'), ('Île-du-Prince-Édouard', 'https://ici.radio-canada.ca/rss/1000814'),
('Manitoba', 'https://ici.radio-canada.ca/rss/5775'), ('Manitoba', 'https://ici.radio-canada.ca/rss/5775'),
('MauricieCentre-du-Québec', 'https://ici.radio-canada.ca/rss/5777'), ('MauricieCentre-du-Québec', 'https://ici.radio-canada.ca/rss/5777'),
('Nord de lOntario', 'https://ici.radio-canada.ca/rss/36518'), ('Nord de lOntario', 'https://ici.radio-canada.ca/rss/36518'),
('Nouveau-Brunswick', 'https://ici.radio-canada.ca/rss/5765'), ('Nouveau-Brunswick', 'https://ici.radio-canada.ca/rss/5765'),
('Nouvelle-Écosse', 'https://ici.radio-canada.ca/rss/1000813'), ('Nouvelle-Écosse', 'https://ici.radio-canada.ca/rss/1000813'),
('Ottawa-Gatineau', 'https://ici.radio-canada.ca/rss/6102'), ('Ottawa-Gatineau', 'https://ici.radio-canada.ca/rss/6102'),
('Québec', 'https://ici.radio-canada.ca/rss/6104'), ('Québec', 'https://ici.radio-canada.ca/rss/6104'),
('Saguenay-Lac-St-Jean', 'https://ici.radio-canada.ca/rss/6106'), ('Saguenay-Lac-St-Jean', 'https://ici.radio-canada.ca/rss/6106'),
('Saskatchewan', 'https://ici.radio-canada.ca/rss/6108'), ('Saskatchewan', 'https://ici.radio-canada.ca/rss/6108'),
('Terre-Neuve-et-Labrador', 'https://ici.radio-canada.ca/rss/1000815'), ('Terre-Neuve-et-Labrador', 'https://ici.radio-canada.ca/rss/1000815'),
('Toronto', 'https://ici.radio-canada.ca/rss/5779'), ('Toronto', 'https://ici.radio-canada.ca/rss/5779'),
('Windsor', 'https://ici.radio-canada.ca/rss/475289'), ('Windsor', 'https://ici.radio-canada.ca/rss/475289'),
# Autres # Autres
('Archives', 'https://ici.radio-canada.ca/rss/1000548'), ('Archives', 'https://ici.radio-canada.ca/rss/1000548'),
('Dossiers', 'https://ici.radio-canada.ca/rss/6735'), ('Dossiers', 'https://ici.radio-canada.ca/rss/6735'),
('Espaces autochtones', 'https://ici.radio-canada.ca/rss/116435'), ('Espaces autochtones', 'https://ici.radio-canada.ca/rss/116435'),
('RCI', 'http://www.rcinet.ca/fr/feed/rss/') ('RCI', 'http://www.rcinet.ca/fr/feed/rss/')
] ]
# The following was copied and adapted as per the following post: # The following was copied and adapted as per the following post:

View File

@ -10,9 +10,10 @@ import re
# This imports the version bundled with Calibre # This imports the version bundled with Calibre
import lxml import lxml
from lxml.builder import E
from calibre.ebooks.BeautifulSoup import BeautifulSoup from calibre.ebooks.BeautifulSoup import BeautifulSoup
from calibre.web.feeds.recipes import BasicNewsRecipe from calibre.web.feeds.recipes import BasicNewsRecipe
from lxml.builder import E
respekt_url = 'https://www.respekt.cz' respekt_url = 'https://www.respekt.cz'

View File

@ -5,7 +5,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
class Sobaka(BasicNewsRecipe): class Sobaka(BasicNewsRecipe):
title = '\u0421\u043E\u0431\u0430\u043A\u0430.ru' title = '\u0421\u043E\u0431\u0430\u043A\u0430.ru'
__author__ = 'bugmen00t' __author__ = 'bugmen00t'
description = '\u0416\u0443\u0440\u043D\u0430\u043B \u043E \u043B\u044E\u0434\u044F\u0445 \u0432 \u041F\u0435\u0442\u0435\u0440\u0431\u0443\u0440\u0433\u0435' # noqa description = '\u0416\u0443\u0440\u043D\u0430\u043B \u043E \u043B\u044E\u0434\u044F\u0445 \u0432 \u041F\u0435\u0442\u0435\u0440\u0431\u0443\u0440\u0433\u0435' # noqa
publisher = '\u041E\u041E\u041E \u00AB\u0416\u0443\u0440\u043D\u0430\u043B\u044B \u0438 \u0441\u0430\u0439\u0442\u044B "\u0424\u0430\u0431\u0440\u0438\u043A\u0430 \u043A\u043E\u043D\u0442\u0435\u043D\u0442\u0430 "\u0422\u043E\u0447\u043A\u0430 \u0420\u0443"\u00BB' # noqa publisher = '\u041E\u041E\u041E \u00AB\u0416\u0443\u0440\u043D\u0430\u043B\u044B \u0438 \u0441\u0430\u0439\u0442\u044B "\u0424\u0430\u0431\u0440\u0438\u043A\u0430 \u043A\u043E\u043D\u0442\u0435\u043D\u0442\u0430 "\u0422\u043E\u0447\u043A\u0430 \u0420\u0443"\u00BB' # noqa

View File

@ -19,10 +19,10 @@ class Spiegel_DE_all(BasicNewsRecipe):
title = u'Spiegel Online RSS - German alle Themen' title = u'Spiegel Online RSS - German alle Themen'
# Author # Author
__author__ = u'Volker Heggemann, VoHe' __author__ = u'Volker Heggemann, VoHe'
# oldest article to download (in days) ---- can be edit by user # oldest article to download (in days) ---- can be edit by user
# be careful, if there is a lot of news, the file size exceeds! # be careful, if there is a lot of news, the file size exceeds!
oldest_article = 7 oldest_article = 7
# describes itself, ---- can be edit by user # describes itself, ---- can be edit by user
max_articles_per_feed = 100 max_articles_per_feed = 100
# speed up the download on fast computers be careful (I test max.20) # speed up the download on fast computers be careful (I test max.20)
# ---- can be edit by user # ---- can be edit by user
@ -40,11 +40,11 @@ class Spiegel_DE_all(BasicNewsRecipe):
cover_url = 'https://de.m.wikipedia.org/wiki/Datei:Spiegel_Online_logo.svg' cover_url = 'https://de.m.wikipedia.org/wiki/Datei:Spiegel_Online_logo.svg'
# What is the content of? # What is the content of?
category = 'SPIEGEL ONLINE RSS' category = 'SPIEGEL ONLINE RSS'
# describes itself, ---- can be edit by user # describes itself, ---- can be edit by user
language = 'de' language = 'de'
lang = 'de-DE' lang = 'de-DE'
no_stylesheets = True no_stylesheets = True
# describes itself, ---- can be edit by user # describes itself, ---- can be edit by user
use_embedded_content = False use_embedded_content = False
# encoding of content. e.g. utf-8, None, ... # encoding of content. e.g. utf-8, None, ...
# ---- can be edit by user # ---- can be edit by user
@ -57,7 +57,7 @@ class Spiegel_DE_all(BasicNewsRecipe):
# remove the rubbish (in ebook) # remove the rubbish (in ebook)
auto_cleanup = True auto_cleanup = True
# now the content description and URL follows # now the content description and URL follows
# feel free to add, wipe out what you need ---- can be edit by user # feel free to add, wipe out what you need ---- can be edit by user
# #
# Make some tests, may you first comment all of them out, and step by step you add what you'll need? # Make some tests, may you first comment all of them out, and step by step you add what you'll need?
# #

View File

@ -46,7 +46,7 @@ class StraitsTimes(BasicNewsRecipe):
,(u'Opinion' , u'https://www.straitstimes.com/news/opinion/rss.xml') ,(u'Opinion' , u'https://www.straitstimes.com/news/opinion/rss.xml')
,(u'Life' , u'https://www.straitstimes.com/news/life/rss.xml') ,(u'Life' , u'https://www.straitstimes.com/news/life/rss.xml')
,(u'Singapore' , u'https://www.straitstimes.com/news/singapore/rss.xml') ,(u'Singapore' , u'https://www.straitstimes.com/news/singapore/rss.xml')
,(u'Asia' , u'https://www.straitstimes.com/news/asia/rss.xml') ,(u'Asia' , u'https://www.straitstimes.com/news/asia/rss.xml')
,(u'Multimedia' , u'https://www.straitstimes.com/news/multimedia/rss.xml') ,(u'Multimedia' , u'https://www.straitstimes.com/news/multimedia/rss.xml')
,(u'Sport' , u'https://www.straitstimes.com/news/sport/rss.xml') ,(u'Sport' , u'https://www.straitstimes.com/news/sport/rss.xml')
] ]

View File

@ -22,7 +22,7 @@ class germant3n(BasicNewsRecipe):
# remove the rubbish (in ebook) # remove the rubbish (in ebook)
auto_cleanup = True auto_cleanup = True
# now the content description and URL follows # now the content description and URL follows
# feel free to add, wipe out what you need ---- can be edit by user # feel free to add, wipe out what you need ---- can be edit by user
# #
# some of this are double # some of this are double
# #

View File

@ -7,7 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
class TInvariant(BasicNewsRecipe): class TInvariant(BasicNewsRecipe):
title = 'T-Invariant' title = 'T-Invariant'
__author__ = 'bugmen00t' __author__ = 'bugmen00t'
description = 'T-Invariant is a multimedia project of scientists and science journalists. Our task is to be a bridge between the academic community in Russia and outside Russia. Lets keep in touch!' # noqa description = 'T-Invariant is a multimedia project of scientists and science journalists. Our task is to be a bridge between the academic community in Russia and outside Russia. Lets keep in touch!' # noqa
publisher = '\u0422-\u0438\u043D\u0432\u0430\u0440\u0438\u0430\u043D\u0442 / T-invariant' publisher = '\u0422-\u0438\u043D\u0432\u0430\u0440\u0438\u0430\u043D\u0442 / T-invariant'

View File

@ -7,7 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
class TInvariant(BasicNewsRecipe): class TInvariant(BasicNewsRecipe):
title = 'T-Invariant' title = 'T-Invariant'
__author__ = 'bugmen00t' __author__ = 'bugmen00t'
description = '\u041C\u0443\u043B\u044C\u0442\u0438\u043C\u0435\u0434\u0438\u0439\u043D\u044B\u0439 \u043F\u0440\u043E\u0435\u043A\u0442 \u0443\u0447\u0435\u043D\u044B\u0445 \u0438 \u043D\u0430\u0443\u0447\u043D\u044B\u0445 \u0436\u0443\u0440\u043D\u0430\u043B\u0438\u0441\u0442\u043E\u0432.' # noqa description = '\u041C\u0443\u043B\u044C\u0442\u0438\u043C\u0435\u0434\u0438\u0439\u043D\u044B\u0439 \u043F\u0440\u043E\u0435\u043A\u0442 \u0443\u0447\u0435\u043D\u044B\u0445 \u0438 \u043D\u0430\u0443\u0447\u043D\u044B\u0445 \u0436\u0443\u0440\u043D\u0430\u043B\u0438\u0441\u0442\u043E\u0432.' # noqa
publisher = '\u0422-\u0438\u043D\u0432\u0430\u0440\u0438\u0430\u043D\u0442 / T-invariant' publisher = '\u0422-\u0438\u043D\u0432\u0430\u0440\u0438\u0430\u043D\u0442 / T-invariant'

View File

@ -7,7 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
class TInvariant(BasicNewsRecipe): class TInvariant(BasicNewsRecipe):
title = 'T-Invariant' title = 'T-Invariant'
__author__ = 'bugmen00t' __author__ = 'bugmen00t'
description = 'T-Invariant is a multimedia project of scientists and science journalists. Our task is to be a bridge between the academic community in Russia and outside Russia. Lets keep in touch!' # noqa description = 'T-Invariant is a multimedia project of scientists and science journalists. Our task is to be a bridge between the academic community in Russia and outside Russia. Lets keep in touch!' # noqa
publisher = '\u0422-\u0438\u043D\u0432\u0430\u0440\u0438\u0430\u043D\u0442 / T-invariant' publisher = '\u0422-\u0438\u043D\u0432\u0430\u0440\u0438\u0430\u043D\u0442 / T-invariant'

View File

@ -51,73 +51,73 @@ class PhilippineDailyInquirer(BasicNewsRecipe):
feeds = [ feeds = [
('Headlines' , 'http://newsinfo.inquirer.net/category/inquirer-headlines/feed'), ('Headlines', 'http://newsinfo.inquirer.net/category/inquirer-headlines/feed'),
('Latest Stories' , 'http://newsinfo.inquirer.net/category/latest-stories/feed'), ('Latest Stories' , 'http://newsinfo.inquirer.net/category/latest-stories/feed'),
('Nation' , 'http://newsinfo.inquirer.net/category/nation/feed'), ('Nation' , 'http://newsinfo.inquirer.net/category/nation/feed'),
('Nation - Latest Stories' , 'http://newsinfo.inquirer.net/category/latest-stories/nation-latest-stories/feed'), ('Nation - Latest Stories' , 'http://newsinfo.inquirer.net/category/latest-stories/nation-latest-stories/feed'),
('Metro' , 'http://newsinfo.inquirer.net/category/metro/feed'), ('Metro' , 'http://newsinfo.inquirer.net/category/metro/feed'),
('Metro - Latest Stories' , 'http://newsinfo.inquirer.net/category/latest-stories/metro-latest-stories/feed'), ('Metro - Latest Stories' , 'http://newsinfo.inquirer.net/category/latest-stories/metro-latest-stories/feed'),
('Regions' , 'http://newsinfo.inquirer.net/category/regions/feed'), ('Regions' , 'http://newsinfo.inquirer.net/category/regions/feed'),
('Regions - Latest Stories' , 'http://newsinfo.inquirer.net/category/latest-stories/regions-latest-stories/feed'), ('Regions - Latest Stories' , 'http://newsinfo.inquirer.net/category/latest-stories/regions-latest-stories/feed'),
('News' , 'http://www.inquirer.net/fullfeed'), ('News' , 'http://www.inquirer.net/fullfeed'),
('More News' , 'http://newsinfo.inquirer.net/feed') ('More News' , 'http://newsinfo.inquirer.net/feed')
, ,
('Global Nation' , 'http://globalnation.inquirer.net/feed'), ('Global Nation' , 'http://globalnation.inquirer.net/feed'),
('Global Nation - Latest Stories', 'http://globalnation.inquirer.net/category/latest-stories/feed'), ('Global Nation - Latest Stories', 'http://globalnation.inquirer.net/category/latest-stories/feed'),
('Global Nation - Philippines', 'http://globalnation.inquirer.net/category/news/philippines/feed'), ('Global Nation - Philippines', 'http://globalnation.inquirer.net/category/news/philippines/feed'),
('Global Nation - Asia & Pacific', 'http://globalnation.inquirer.net/category/news/asiaaustralia/feed'), ('Global Nation - Asia & Pacific', 'http://globalnation.inquirer.net/category/news/asiaaustralia/feed'),
('Global Nation - Americas', 'http://globalnation.inquirer.net/category/news/uscanada/feed'), ('Global Nation - Americas', 'http://globalnation.inquirer.net/category/news/uscanada/feed'),
('Global Nation - Middle East & Africa', 'http://globalnation.inquirer.net/category/news/middle-eastafrica/feed'), ('Global Nation - Middle East & Africa', 'http://globalnation.inquirer.net/category/news/middle-eastafrica/feed'),
('Global Nation - Europe' , 'http://globalnation.inquirer.net/category/news/europe/feed'), ('Global Nation - Europe' , 'http://globalnation.inquirer.net/category/news/europe/feed'),
('Global Nation - Global Pinoy', 'http://globalnation.inquirer.net/category/global-pinoy/feed'), ('Global Nation - Global Pinoy', 'http://globalnation.inquirer.net/category/global-pinoy/feed'),
('Global Nation - Events' , 'http://globalnation.inquirer.net/category/events/feed'), ('Global Nation - Events' , 'http://globalnation.inquirer.net/category/events/feed'),
('Business' , 'http://business.inquirer.net/feed'), ('Business' , 'http://business.inquirer.net/feed'),
('Business - Latest Stories' , 'http://business.inquirer.net/category/latest-stories/feed'), ('Business - Latest Stories' , 'http://business.inquirer.net/category/latest-stories/feed'),
('Business - Money' , 'http://business.inquirer.net/category/money/feed'), ('Business - Money' , 'http://business.inquirer.net/category/money/feed'),
('Business - Science & Health', 'http://business.inquirer.net/category/science-and-health/feed'), ('Business - Science & Health', 'http://business.inquirer.net/category/science-and-health/feed'),
('Business - Motoring' , 'http://business.inquirer.net/category/motoring/feed'), ('Business - Motoring' , 'http://business.inquirer.net/category/motoring/feed'),
('Business - Property Guide' , 'http://business.inquirer.net/category/property-guide/feed'), ('Business - Property Guide' , 'http://business.inquirer.net/category/property-guide/feed'),
('Business - Columnists' , 'http://business.inquirer.net/category/columnists/feed'), ('Business - Columnists' , 'http://business.inquirer.net/category/columnists/feed'),
('Sports' , 'http://sports.inquirer.net/feed'), ('Sports' , 'http://sports.inquirer.net/feed'),
('Sports - Latest Stories' , 'http://sports.inquirer.net/category/latest-stories/feed'), ('Sports - Latest Stories' , 'http://sports.inquirer.net/category/latest-stories/feed'),
('Sports - Basketball' , 'http://sports.inquirer.net/category/section/basketball/feed'), ('Sports - Basketball' , 'http://sports.inquirer.net/category/section/basketball/feed'),
('Sports - Boxing & MMA', 'http://sports.inquirer.net/category/section/boxing-mma/feed'), ('Sports - Boxing & MMA', 'http://sports.inquirer.net/category/section/boxing-mma/feed'),
('Sports - Golf' , 'http://sports.inquirer.net/category/section/golf/feed'), ('Sports - Golf' , 'http://sports.inquirer.net/category/section/golf/feed'),
('Sports - Football' , 'http://sports.inquirer.net/category/section/other-sports/football/feed'), ('Sports - Football' , 'http://sports.inquirer.net/category/section/other-sports/football/feed'),
('Sports - Other Sports' , 'http://sports.inquirer.net/category/section/other-sports/feed'), ('Sports - Other Sports' , 'http://sports.inquirer.net/category/section/other-sports/feed'),
('Technology' , 'http://technology.inquirer.net/feed'), ('Technology' , 'http://technology.inquirer.net/feed'),
('Technology Latest Stories', 'http://technology.inquirer.net/category/latest-stories/feed'), ('Technology Latest Stories', 'http://technology.inquirer.net/category/latest-stories/feed'),
('Entertainment' , 'http://entertainment.inquirer.net/feed'), ('Entertainment' , 'http://entertainment.inquirer.net/feed'),
('Entertainment - Headlines', 'http://entertainment.inquirer.net/category/headlines/feed'), ('Entertainment - Headlines', 'http://entertainment.inquirer.net/category/headlines/feed'),
('Entertainment - Latest Stories', 'http://entertainment.inquirer.net/category/latest-stories/feed'), ('Entertainment - Latest Stories', 'http://entertainment.inquirer.net/category/latest-stories/feed'),
('Entertainment - Movies' , 'http://movies.inquirer.net/feed'), ('Entertainment - Movies' , 'http://movies.inquirer.net/feed'),
('Lifestyle' , 'http://lifestyle.inquirer.net/feed'), ('Lifestyle' , 'http://lifestyle.inquirer.net/feed'),
('Lifestyle - Latest Stories', 'http://lifestyle.inquirer.net/category/latest-stories/feed'), ('Lifestyle - Latest Stories', 'http://lifestyle.inquirer.net/category/latest-stories/feed'),
('Lifestyle - Arts & Books' , 'http://lifestyle.inquirer.net/category/arts-and-books/feed'), ('Lifestyle - Arts & Books' , 'http://lifestyle.inquirer.net/category/arts-and-books/feed'),
('Lifestyle - Wellness' , 'http://lifestyle.inquirer.net/category/wellness/feed'), ('Lifestyle - Wellness' , 'http://lifestyle.inquirer.net/category/wellness/feed'),
('Lifestyle - Home & Entertaining', 'http://lifestyle.inquirer.net/category/home-and-entertaining/feed'), ('Lifestyle - Home & Entertaining', 'http://lifestyle.inquirer.net/category/home-and-entertaining/feed'),
('Lifestyle - Parenting' , 'http://lifestyle.inquirer.net/category/parenting/feed'), ('Lifestyle - Parenting' , 'http://lifestyle.inquirer.net/category/parenting/feed'),
('Lifestyle - Food' , 'http://lifestyle.inquirer.net/category/food/feed'), ('Lifestyle - Food' , 'http://lifestyle.inquirer.net/category/food/feed'),
('Lifestyle - Fashion & Beauty', 'http://lifestyle.inquirer.net/category/fashion-and-beauty/feed'), ('Lifestyle - Fashion & Beauty', 'http://lifestyle.inquirer.net/category/fashion-and-beauty/feed'),
('Lifestyle - Super' , 'http://lifestyle.inquirer.net/category/super/feed'), ('Lifestyle - Super' , 'http://lifestyle.inquirer.net/category/super/feed'),
('Lifestyle - 2BU' , 'http://lifestyle.inquirer.net/category/2bu/feed'), ('Lifestyle - 2BU' , 'http://lifestyle.inquirer.net/category/2bu/feed'),
('Lifestyle - Sunday Lifestyle', 'http://lifestyle.inquirer.net/category/sunday-lifestyle/feed'), ('Lifestyle - Sunday Lifestyle', 'http://lifestyle.inquirer.net/category/sunday-lifestyle/feed'),
('Lifestyle - Wedding' , 'http://lifestyle.inquirer.net/category/sunday-lifestyle/wedding/feed'), ('Lifestyle - Wedding' , 'http://lifestyle.inquirer.net/category/sunday-lifestyle/wedding/feed'),
('Lifestyle - Travel' , 'http://lifestyle.inquirer.net/category/sunday-lifestyle/travel/feed'), ('Lifestyle - Travel' , 'http://lifestyle.inquirer.net/category/sunday-lifestyle/travel/feed'),
('Lifestyle - Relationship' , 'http://lifestyle.inquirer.net/category/sunday-lifestyle/relationship/feed'), ('Lifestyle - Relationship' , 'http://lifestyle.inquirer.net/category/sunday-lifestyle/relationship/feed'),
('Opinion' , 'http://opinion.inquirer.net/feed'), ('Opinion' , 'http://opinion.inquirer.net/feed'),
('Opinion - Viewpoints' , 'http://opinion.inquirer.net/category/viewpoints/feed'), ('Opinion - Viewpoints' , 'http://opinion.inquirer.net/category/viewpoints/feed'),
('Opinion - Talk of the Town', 'http://opinion.inquirer.net/category/inquirer-opinion/talk-of-the-town/feed'), ('Opinion - Talk of the Town', 'http://opinion.inquirer.net/category/inquirer-opinion/talk-of-the-town/feed'),
('Editorial' , 'http://opinion.inquirer.net/category/editorial/feed'), ('Editorial' , 'http://opinion.inquirer.net/category/editorial/feed'),
('Letters to the Editor' , 'http://opinion.inquirer.net/category/letters-to-the-editor/feed'), ('Letters to the Editor' , 'http://opinion.inquirer.net/category/letters-to-the-editor/feed'),
('Columns' , 'http://opinion.inquirer.net/category/columns/feed'), ('Columns' , 'http://opinion.inquirer.net/category/columns/feed'),
('Citizens Journalism' , 'http://newsinfo.inquirer.net/category/citizens-journalism/feed'), ('Citizens Journalism' , 'http://newsinfo.inquirer.net/category/citizens-journalism/feed'),
('Cebu - Daily News' , 'http://newsinfo.inquirer.net/category/cdn/feed'), ('Cebu - Daily News' , 'http://newsinfo.inquirer.net/category/cdn/feed'),
('Cebu - More News' , 'http://newsinfo.inquirer.net/category/cdn/cdn-news/feed'), ('Cebu - More News' , 'http://newsinfo.inquirer.net/category/cdn/cdn-news/feed'),
('Cebu - Community' , 'http://newsinfo.inquirer.net/category/cdn/cdn-community/feed'), ('Cebu - Community' , 'http://newsinfo.inquirer.net/category/cdn/cdn-community/feed'),
('Cebu - Metro' , 'http://newsinfo.inquirer.net/category/cdn/cdn-metro/feed'), ('Cebu - Metro' , 'http://newsinfo.inquirer.net/category/cdn/cdn-metro/feed'),
('Cebu - Business' , 'http://newsinfo.inquirer.net/category/cdn/cdn-enterprise/feed'), ('Cebu - Business' , 'http://newsinfo.inquirer.net/category/cdn/cdn-enterprise/feed'),
('Cebu - Sports' , 'http://newsinfo.inquirer.net/category/cdn/cdn-sports/feed'), ('Cebu - Sports' , 'http://newsinfo.inquirer.net/category/cdn/cdn-sports/feed'),
('Cebu - Visayas' , 'http://newsinfo.inquirer.net/category/cdn/cdn-visayas/feed'), ('Cebu - Visayas' , 'http://newsinfo.inquirer.net/category/cdn/cdn-visayas/feed'),
('Cebu - Opinion' , 'http://newsinfo.inquirer.net/category/cdn/cdn-opinion/feed') ('Cebu - Opinion' , 'http://newsinfo.inquirer.net/category/cdn/cdn-opinion/feed')
] ]

View File

@ -15,10 +15,11 @@ except ImportError:
from urllib import urlencode from urllib import urlencode
import re import re
from mechanize import Request
from calibre import strftime from calibre import strftime
from calibre.ptempfile import PersistentTemporaryFile from calibre.ptempfile import PersistentTemporaryFile
from calibre.web.feeds.news import BasicNewsRecipe from calibre.web.feeds.news import BasicNewsRecipe
from mechanize import Request
class TheNewCriterion(BasicNewsRecipe): class TheNewCriterion(BasicNewsRecipe):

View File

@ -69,7 +69,7 @@ class PrivateEyeRecipe(BasicNewsRecipe):
article['author'] = author article['author'] = author
return article return article
edition_re = re.compile('(?:-front-cover-)(\d+)-') edition_re = re.compile(r'(?:-front-cover-)(\d+)-')
# Identify the cover image and extract the edition# from the url # Identify the cover image and extract the edition# from the url
def get_cover_url(self): def get_cover_url(self):
@ -242,8 +242,8 @@ class PrivateEyeRecipe(BasicNewsRecipe):
{'name': 'a', 'class': "view-full-screen"}, {'name': 'a', 'class': "view-full-screen"},
{'name': 'div', 'class': "image-counter"}, {'name': 'div', 'class': "image-counter"},
{'name': 'h2', 'string': "Find out more about The Oldie"}, {'name': 'h2', 'string': "Find out more about The Oldie"},
{'name': 'a', 'href': re.compile("^https?:\/\/issuu.com\/")}, {'name': 'a', 'href': re.compile(r"^https?:\/\/issuu.com\/")},
{'name': 'img', 'src': re.compile("\/assets\/images\/icons\/icon-")}, {'name': 'img', 'src': re.compile(r"\/assets\/images\/icons\/icon-")},
] ]
# The following extra css is to tweak the formatting of various elements of various article pages. # The following extra css is to tweak the formatting of various elements of various article pages.

View File

@ -16,7 +16,7 @@ def re_html(y):
def get_id(url): def get_id(url):
rq = browser().open(url) rq = browser().open(url)
return re.search('\?p=(\S+)>', str(rq.info())).group(1) return re.search(r'\?p=(\S+)>', str(rq.info())).group(1)
class TLS(BasicNewsRecipe): class TLS(BasicNewsRecipe):

View File

@ -29,9 +29,8 @@ class Ugeskriftet(BasicNewsRecipe):
h2{font-weight: bold; font-size: large;} h2{font-weight: bold; font-size: large;}
h3{font-weight: bold; font-size: large;} h3{font-weight: bold; font-size: large;}
h4{font-weight: bold; font-size: large;} h4{font-weight: bold; font-size: large;}
""" """
feeds = [ feeds = [
('Ugeskriftet for læger', 'https://ugeskriftet.dk/rss/forside'), ('Ugeskriftet for læger', 'https://ugeskriftet.dk/rss/forside'),
] ]

View File

@ -5,7 +5,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
class UkrInform(BasicNewsRecipe): class UkrInform(BasicNewsRecipe):
title = 'UkrInform (Espa\u00F1ol)' title = 'UkrInform (Espa\u00F1ol)'
__author__ = 'bugmen00t' __author__ = 'bugmen00t'
description = 'Agencia de noticias nacional de Ucrania, fuente de informaci\u00F3n sobre la vida pol\u00EDtica, econ\u00F3mica, social, cient\u00EDfica, cultural y p\u00FAblica en Ucrania y en el extranjero.' # noqa description = 'Agencia de noticias nacional de Ucrania, fuente de informaci\u00F3n sobre la vida pol\u00EDtica, econ\u00F3mica, social, cient\u00EDfica, cultural y p\u00FAblica en Ucrania y en el extranjero.' # noqa
publisher = 'Ministerio de Cultura y Pol\u00EDtica de Informaci\u00F3n de Ucrania' publisher = 'Ministerio de Cultura y Pol\u00EDtica de Informaci\u00F3n de Ucrania'

View File

@ -88,7 +88,6 @@ class USAToday(BasicNewsRecipe):
feeds.append((section, articles)) feeds.append((section, articles))
return feeds return feeds
def preprocess_html(self, soup): def preprocess_html(self, soup):
for img in soup.findAll('img', src=True): for img in soup.findAll('img', src=True):
img['src'] = 'https://www.usatoday.com' + img['src'] img['src'] = 'https://www.usatoday.com' + img['src']

View File

@ -3,9 +3,10 @@ import json
import uuid import uuid
from contextlib import closing from contextlib import closing
from calibre.web.feeds.recipes import BasicNewsRecipe
from mechanize import Request from mechanize import Request
from calibre.web.feeds.recipes import BasicNewsRecipe
class Volkskrant(BasicNewsRecipe): class Volkskrant(BasicNewsRecipe):
title = 'Volkskrant' title = 'Volkskrant'

View File

@ -7,7 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
class WiComix(BasicNewsRecipe): class WiComix(BasicNewsRecipe):
title = 'Wicomix' title = 'Wicomix'
__author__ = 'bugmen00t' __author__ = 'bugmen00t'
description = '\u0418\u043D\u0442\u0435\u0440\u0435\u0441\u043D\u043E \u043F\u0438\u0448\u0435\u043C \u043F\u0440\u043E \u043A\u043E\u043C\u0438\u043A\u0441\u044B \u0438 \u043C\u0430\u043D\u0433\u0443 \u0432 \u0420\u043E\u0441\u0441\u0438\u0438.' # noqa description = '\u0418\u043D\u0442\u0435\u0440\u0435\u0441\u043D\u043E \u043F\u0438\u0448\u0435\u043C \u043F\u0440\u043E \u043A\u043E\u043C\u0438\u043A\u0441\u044B \u0438 \u043C\u0430\u043D\u0433\u0443 \u0432 \u0420\u043E\u0441\u0441\u0438\u0438.' # noqa
publisher = '\u0421\u0435\u0440\u0433\u0435\u0439 \u041E\u0440\u0435\u0448\u043A\u0438\u043D' publisher = '\u0421\u0435\u0440\u0433\u0435\u0439 \u041E\u0440\u0435\u0448\u043A\u0438\u043D'

View File

@ -10,11 +10,12 @@ import time
from base64 import standard_b64encode from base64 import standard_b64encode
from datetime import date, timedelta from datetime import date, timedelta
from calibre.ptempfile import PersistentTemporaryFile
from calibre.web.feeds.news import BasicNewsRecipe
from css_selectors import Select from css_selectors import Select
from mechanize import Request from mechanize import Request
from calibre.ptempfile import PersistentTemporaryFile
from calibre.web.feeds.news import BasicNewsRecipe
try: try:
import urllib.parse as urlparse import urllib.parse as urlparse
except ImportError: except ImportError:

View File

@ -216,14 +216,14 @@ save_template_title_series_sorting = 'library_order'
# (present only for legacy reasons). # (present only for legacy reasons).
per_language_title_sort_articles = { per_language_title_sort_articles = {
# English # English
'eng' : (r'A\s+', r'The\s+', r'An\s+'), 'eng': (r'A\s+', r'The\s+', r'An\s+'),
# Esperanto # Esperanto
'epo': (r'La\s+', r"L'", 'L´'), 'epo': (r'La\s+', r"L'", 'L´'),
# Spanish # Spanish
'spa' : (r'El\s+', r'La\s+', r'Lo\s+', r'Los\s+', r'Las\s+', r'Un\s+', 'spa': (r'El\s+', r'La\s+', r'Lo\s+', r'Los\s+', r'Las\s+', r'Un\s+',
r'Una\s+', r'Unos\s+', r'Unas\s+'), r'Una\s+', r'Unos\s+', r'Unas\s+'),
# French # French
'fra' : (r'Le\s+', r'La\s+', r"L'", u'L´', u'L', r'Les\s+', r'Un\s+', r'Une\s+', 'fra': (r'Le\s+', r'La\s+', r"L'", r'L´', r'L', r'Les\s+', r'Un\s+', r'Une\s+',
r'Des\s+', r'De\s+La\s+', r'De\s+', r"D'", r'D´', r'D'), r'Des\s+', r'De\s+La\s+', r'De\s+', r"D'", r'D´', r'D'),
# Polish # Polish
'pol': (), 'pol': (),
@ -233,32 +233,32 @@ per_language_title_sort_articles = {
'Un´', 'Dei\\s+', 'Degli\\s+', 'Delle\\s+', 'Del\\s+', 'Un´', 'Dei\\s+', 'Degli\\s+', 'Delle\\s+', 'Del\\s+',
'Della\\s+', 'Dello\\s+', "Dell'", 'Dell´'), 'Della\\s+', 'Dello\\s+', "Dell'", 'Dell´'),
# Portuguese # Portuguese
'por' : (r'A\s+', r'O\s+', r'Os\s+', r'As\s+', r'Um\s+', r'Uns\s+', 'por': (r'A\s+', r'O\s+', r'Os\s+', r'As\s+', r'Um\s+', r'Uns\s+',
r'Uma\s+', r'Umas\s+', ), r'Uma\s+', r'Umas\s+', ),
# Romanian # Romanian
'ron' : (r'Un\s+', r'O\s+', r'Nişte\s+', ), 'ron': (r'Un\s+', r'O\s+', r'Nişte\s+', ),
# German # German
'deu' : (r'Der\s+', r'Die\s+', r'Das\s+', r'Den\s+', r'Ein\s+', 'deu': (r'Der\s+', r'Die\s+', r'Das\s+', r'Den\s+', r'Ein\s+',
r'Eine\s+', r'Einen\s+', r'Dem\s+', r'Des\s+', r'Einem\s+', r'Eine\s+', r'Einen\s+', r'Dem\s+', r'Des\s+', r'Einem\s+',
r'Eines\s+'), r'Eines\s+'),
# Dutch # Dutch
'nld' : (r'De\s+', r'Het\s+', r'Een\s+', r"'n\s+", r"'s\s+", r'Ene\s+', 'nld': (r'De\s+', r'Het\s+', r'Een\s+', r"'n\s+", r"'s\s+", r'Ene\s+',
r'Ener\s+', r'Enes\s+', r'Den\s+', r'Der\s+', r'Des\s+', r'Ener\s+', r'Enes\s+', r'Den\s+', r'Der\s+', r'Des\s+',
r"'t\s+"), r"'t\s+"),
# Swedish # Swedish
'swe' : (r'En\s+', r'Ett\s+', r'Det\s+', r'Den\s+', r'De\s+', ), 'swe': (r'En\s+', r'Ett\s+', r'Det\s+', r'Den\s+', r'De\s+', ),
# Turkish # Turkish
'tur' : (r'Bir\s+', ), 'tur': (r'Bir\s+', ),
# Afrikaans # Afrikaans
'afr' : (r"'n\s+", r'Die\s+', ), 'afr': (r"'n\s+", r'Die\s+', ),
# Greek # Greek
'ell' : (r'O\s+', r'I\s+', r'To\s+', r'Ta\s+', r'Tus\s+', r'Tis\s+', 'ell': (r'O\s+', r'I\s+', r'To\s+', r'Ta\s+', r'Tus\s+', r'Tis\s+',
r"'Enas\s+", r"'Mia\s+", r"'Ena\s+", r"'Enan\s+", ), r"'Enas\s+", r"'Mia\s+", r"'Ena\s+", r"'Enan\s+", ),
# Hungarian # Hungarian
'hun' : (r'A\s+', r'Az\s+', r'Egy\s+',), 'hun': (r'A\s+', r'Az\s+', r'Egy\s+',),
} }
default_language_for_title_sort = None default_language_for_title_sort = None
title_sort_articles=r'^(A|The|An)\s+' title_sort_articles = r'^(A|The|An)\s+'
#: Specify a folder calibre should connect to at startup #: Specify a folder calibre should connect to at startup
# Specify a folder that calibre should connect to at startup using # Specify a folder that calibre should connect to at startup using
@ -331,8 +331,8 @@ auto_connect_to_folder = ''
# The resulting two tweaks are: # The resulting two tweaks are:
# sony_collection_renaming_rules={'series':'Series', 'tags':'Tag'} # sony_collection_renaming_rules={'series':'Series', 'tags':'Tag'}
# sony_collection_name_template='{category:||: }{value}' # sony_collection_name_template='{category:||: }{value}'
sony_collection_renaming_rules={} sony_collection_renaming_rules = {}
sony_collection_name_template='{value}{category:| (|)}' sony_collection_name_template = '{value}{category:| (|)}'
#: Specify how SONY collections are sorted #: Specify how SONY collections are sorted
# Specify how SONY collections are sorted. This tweak is only applicable if # Specify how SONY collections are sorted. This tweak is only applicable if
@ -402,7 +402,7 @@ vertical_scrolling_per_row = False
# Default: locale_for_sorting = '' -- use the language calibre displays in # Default: locale_for_sorting = '' -- use the language calibre displays in
# Example: locale_for_sorting = 'fr' -- sort using French rules. # Example: locale_for_sorting = 'fr' -- sort using French rules.
# Example: locale_for_sorting = 'nb' -- sort using Norwegian rules. # Example: locale_for_sorting = 'nb' -- sort using Norwegian rules.
locale_for_sorting = '' locale_for_sorting = ''
#: The number of seconds to wait before sending emails #: The number of seconds to wait before sending emails
# The number of seconds to wait before sending emails when using a # The number of seconds to wait before sending emails when using a

View File

@ -41,6 +41,10 @@ class Check(Command):
CACHE = 'check.json' CACHE = 'check.json'
def add_options(self, parser):
parser.add_option('--fix', '--auto-fix', default=False, action='store_true',
help='Try to automatically fix some of the smallest errors')
def get_files(self): def get_files(self):
yield from checkable_python_files(self.SRC) yield from checkable_python_files(self.SRC)
@ -91,6 +95,10 @@ class Check(Command):
p = subprocess.Popen(['python', self.j(self.wn_path, 'whats_new.py'), f]) p = subprocess.Popen(['python', self.j(self.wn_path, 'whats_new.py'), f])
return p.wait() != 0 return p.wait() != 0
def perform_auto_fix(self):
p = subprocess.Popen(['ruff', 'check', '--fix-only'], text=True, stdout=subprocess.PIPE)
return p.stdout.read()
def run(self, opts): def run(self, opts):
self.fhash_cache = {} self.fhash_cache = {}
cache = {} cache = {}
@ -102,13 +110,20 @@ class Check(Command):
except OSError as err: except OSError as err:
if err.errno != errno.ENOENT: if err.errno != errno.ENOENT:
raise raise
if opts.fix:
self.info('\tAuto-fixing')
msg = self.perform_auto_fix()
self.info(msg)
dirty_files = tuple(f for f in self.get_files() if not self.is_cache_valid(f, cache)) dirty_files = tuple(f for f in self.get_files() if not self.is_cache_valid(f, cache))
try: try:
for i, f in enumerate(dirty_files): for i, f in enumerate(dirty_files):
self.info('\tChecking', f) self.info('\tChecking', f)
if self.file_has_errors(f): if self.file_has_errors(f):
self.info('%d files left to check' % (len(dirty_files) - i - 1)) self.info('%d files left to check' % (len(dirty_files) - i - 1))
edit_file(f) try:
edit_file(f)
except FileNotFoundError:
pass # continue if the configured editor fail to be open
if self.file_has_errors(f): if self.file_has_errors(f):
raise SystemExit(1) raise SystemExit(1)
cache[f] = self.file_hash(f) cache[f] = self.file_hash(f)

View File

@ -10,49 +10,49 @@ from calibre.devices.usbms.driver import USBMS
class BOEYE_BEX(USBMS): class BOEYE_BEX(USBMS):
name = 'BOEYE BEX reader driver' name = 'BOEYE BEX reader driver'
gui_name = 'BOEYE BEX' gui_name = 'BOEYE BEX'
description = _('Communicate with BOEYE BEX Serial e-book readers.') description = _('Communicate with BOEYE BEX Serial e-book readers.')
author = 'szboeye' author = 'szboeye'
supported_platforms = ['windows', 'osx', 'linux'] supported_platforms = ['windows', 'osx', 'linux']
FORMATS = ['epub', 'mobi', 'fb2', 'lit', 'prc', 'pdf', 'rtf', 'txt', 'djvu', 'doc', 'chm', 'html', 'zip', 'pdb'] FORMATS = ['epub', 'mobi', 'fb2', 'lit', 'prc', 'pdf', 'rtf', 'txt', 'djvu', 'doc', 'chm', 'html', 'zip', 'pdb']
VENDOR_ID = [0x0085] VENDOR_ID = [0x0085]
PRODUCT_ID = [0x600] PRODUCT_ID = [0x600]
VENDOR_NAME = 'LINUX' VENDOR_NAME = 'LINUX'
WINDOWS_MAIN_MEM = 'FILE-STOR_GADGET' WINDOWS_MAIN_MEM = 'FILE-STOR_GADGET'
OSX_MAIN_MEM = 'Linux File-Stor Gadget Media' OSX_MAIN_MEM = 'Linux File-Stor Gadget Media'
MAIN_MEMORY_VOLUME_LABEL = 'BOEYE BEX Storage Card' MAIN_MEMORY_VOLUME_LABEL = 'BOEYE BEX Storage Card'
EBOOK_DIR_MAIN = 'Documents' EBOOK_DIR_MAIN = 'Documents'
SUPPORTS_SUB_DIRS = True SUPPORTS_SUB_DIRS = True
class BOEYE_BDX(USBMS): class BOEYE_BDX(USBMS):
name = 'BOEYE BDX reader driver' name = 'BOEYE BDX reader driver'
gui_name = 'BOEYE BDX' gui_name = 'BOEYE BDX'
description = _('Communicate with BOEYE BDX serial e-book readers.') description = _('Communicate with BOEYE BDX serial e-book readers.')
author = 'szboeye' author = 'szboeye'
supported_platforms = ['windows', 'osx', 'linux'] supported_platforms = ['windows', 'osx', 'linux']
FORMATS = ['epub', 'mobi', 'fb2', 'lit', 'prc', 'pdf', 'rtf', 'txt', 'djvu', 'doc', 'chm', 'html', 'zip', 'pdb'] FORMATS = ['epub', 'mobi', 'fb2', 'lit', 'prc', 'pdf', 'rtf', 'txt', 'djvu', 'doc', 'chm', 'html', 'zip', 'pdb']
VENDOR_ID = [0x0085] VENDOR_ID = [0x0085]
PRODUCT_ID = [0x800] PRODUCT_ID = [0x800]
VENDOR_NAME = 'LINUX' VENDOR_NAME = 'LINUX'
WINDOWS_MAIN_MEM = 'FILE-STOR_GADGET' WINDOWS_MAIN_MEM = 'FILE-STOR_GADGET'
WINDOWS_CARD_A_MEM = 'FILE-STOR_GADGET' WINDOWS_CARD_A_MEM = 'FILE-STOR_GADGET'
OSX_MAIN_MEM = 'Linux File-Stor Gadget Media' OSX_MAIN_MEM = 'Linux File-Stor Gadget Media'
OSX_CARD_A_MEM = 'Linux File-Stor Gadget Media' OSX_CARD_A_MEM = 'Linux File-Stor Gadget Media'
MAIN_MEMORY_VOLUME_LABEL = 'BOEYE BDX Internal Memory' MAIN_MEMORY_VOLUME_LABEL = 'BOEYE BDX Internal Memory'
STORAGE_CARD_VOLUME_LABEL = 'BOEYE BDX Storage Card' STORAGE_CARD_VOLUME_LABEL = 'BOEYE BDX Storage Card'
EBOOK_DIR_MAIN = 'Documents' EBOOK_DIR_MAIN = 'Documents'
EBOOK_DIR_CARD_A = 'Documents' EBOOK_DIR_CARD_A = 'Documents'
SUPPORTS_SUB_DIRS = True SUPPORTS_SUB_DIRS = True

View File

@ -97,8 +97,8 @@ class HANLINV5(HANLINV3):
gui_name = 'Hanlin V5' gui_name = 'Hanlin V5'
description = _('Communicate with Hanlin V5 e-book readers.') description = _('Communicate with Hanlin V5 e-book readers.')
VENDOR_ID = [0x0492] VENDOR_ID = [0x0492]
PRODUCT_ID = [0x8813] PRODUCT_ID = [0x8813]
BCD = [0x319] BCD = [0x319]
OSX_MAIN_MEM = 'Hanlin V5 Internal Memory' OSX_MAIN_MEM = 'Hanlin V5 Internal Memory'

View File

@ -11,7 +11,7 @@ class PageGroup:
"""Simulate constructor overloading""" """Simulate constructor overloading"""
def __init__(self, page_locations: Union[int, List[int]], page_number_type: PageNumberTypes, first_value: int, def __init__(self, page_locations: Union[int, List[int]], page_number_type: PageNumberTypes, first_value: int,
page_labels: Union[str, List[str], None] = None): page_labels: Union[str, List[str], None] = None):
if page_locations.__class__ == int: if page_locations.__class__ is int:
self.page_locations: List[int] = [page_locations] self.page_locations: List[int] = [page_locations]
else: else:
self.page_locations: List[int] = page_locations self.page_locations: List[int] = page_locations
@ -19,7 +19,7 @@ class PageGroup:
self.__first_value = first_value self.__first_value = first_value
if page_number_type == PageNumberTypes.Custom: if page_number_type == PageNumberTypes.Custom:
assert page_labels is not None assert page_labels is not None
if page_labels.__class__ == str: if page_labels.__class__ is str:
assert 1 == len(self.page_locations) and len(page_labels) > 0 assert 1 == len(self.page_locations) and len(page_labels) > 0
self.__page_number_labels: List[str] = [page_labels] self.__page_number_labels: List[str] = [page_labels]
else: else:
@ -28,7 +28,7 @@ class PageGroup:
self.__page_number_labels: List[str] = page_labels self.__page_number_labels: List[str] = page_labels
def append(self, page_location: Union[int, Tuple[int, str]]) -> None: def append(self, page_location: Union[int, Tuple[int, str]]) -> None:
if page_location.__class__ == int: if page_location.__class__ is int:
assert self.__page_number_type != PageNumberTypes.Custom assert self.__page_number_type != PageNumberTypes.Custom
self.page_locations.append(page_location) self.page_locations.append(page_location)
else: else:

View File

@ -11,7 +11,7 @@ from calibre.devices.kindle.apnx_page_generator.page_number_type import PageNumb
class Pages: class Pages:
def __init__(self, page_locations: Optional[List[int]] = None): def __init__(self, page_locations: Optional[List[int]] = None):
if page_locations.__class__ == list: if page_locations.__class__ is list:
self.__pages_groups: List[PageGroup] = [PageGroup(page_locations, PageNumberTypes.Arabic, 1)] self.__pages_groups: List[PageGroup] = [PageGroup(page_locations, PageNumberTypes.Arabic, 1)]
else: else:
self.__pages_groups: List[PageGroup] = [] self.__pages_groups: List[PageGroup] = []

View File

@ -673,7 +673,7 @@ class Device(DeviceConfig, DevicePlugin):
hal = get_hal() hal = get_hal()
vols = hal.get_volumes(d) vols = hal.get_volumes(d)
if verbose: if verbose:
print("FBSD: ", vols) print("FBSD:\t", vols)
ok, mv = hal.mount_volumes(vols) ok, mv = hal.mount_volumes(vols)
if not ok: if not ok:

View File

@ -106,19 +106,19 @@ class HAL:
# Mount Point becomes Mount Path # Mount Point becomes Mount Path
mp += '/' mp += '/'
if DEBUG: if DEBUG:
print("FBSD: mounted", vol['label'], "on", mp) print("FBSD:\tmounted", vol['label'], "on", mp)
if mtd == 0: if mtd == 0:
ans['_main_prefix'], ans['_main_vol'] = mp, vol['vol'] ans['_main_prefix'], ans['_main_vol'] = mp, vol['vol']
if DEBUG: if DEBUG:
print("FBSD: main = ", mp) print("FBSD:\tmain = ", mp)
elif mtd == 1: elif mtd == 1:
ans['_card_a_prefix'], ans['_card_a_vol'] = mp, vol['vol'] ans['_card_a_prefix'], ans['_card_a_vol'] = mp, vol['vol']
if DEBUG: if DEBUG:
print("FBSD: card a = ", mp) print("FBSD:\tcard a = ", mp)
elif mtd == 2: elif mtd == 2:
ans['_card_b_prefix'], ans['_card_b_vol'] = mp, vol['vol'] ans['_card_b_prefix'], ans['_card_b_vol'] = mp, vol['vol']
if DEBUG: if DEBUG:
print("FBSD: card b = ", mp) print("FBSD:\tcard b = ", mp)
break break
mtd += 1 mtd += 1

View File

@ -307,27 +307,27 @@ SPDRP_LOCATION_PATHS = DWORD(0x00000023)
CR_CODES, CR_CODE_NAMES = {}, {} CR_CODES, CR_CODE_NAMES = {}, {}
for line in '''\ for line in '''\
#define CR_SUCCESS 0x00000000 #define CR_SUCCESS 0x00000000
#define CR_DEFAULT 0x00000001 #define CR_DEFAULT 0x00000001
#define CR_OUT_OF_MEMORY 0x00000002 #define CR_OUT_OF_MEMORY 0x00000002
#define CR_INVALID_POINTER 0x00000003 #define CR_INVALID_POINTER 0x00000003
#define CR_INVALID_FLAG 0x00000004 #define CR_INVALID_FLAG 0x00000004
#define CR_INVALID_DEVNODE 0x00000005 #define CR_INVALID_DEVNODE 0x00000005
#define CR_INVALID_DEVINST CR_INVALID_DEVNODE #define CR_INVALID_DEVINST CR_INVALID_DEVNODE
#define CR_INVALID_RES_DES 0x00000006 #define CR_INVALID_RES_DES 0x00000006
#define CR_INVALID_LOG_CONF 0x00000007 #define CR_INVALID_LOG_CONF 0x00000007
#define CR_INVALID_ARBITRATOR 0x00000008 #define CR_INVALID_ARBITRATOR 0x00000008
#define CR_INVALID_NODELIST 0x00000009 #define CR_INVALID_NODELIST 0x00000009
#define CR_DEVNODE_HAS_REQS 0x0000000A #define CR_DEVNODE_HAS_REQS 0x0000000A
#define CR_DEVINST_HAS_REQS CR_DEVNODE_HAS_REQS #define CR_DEVINST_HAS_REQS CR_DEVNODE_HAS_REQS
#define CR_INVALID_RESOURCEID 0x0000000B #define CR_INVALID_RESOURCEID 0x0000000B
#define CR_DLVXD_NOT_FOUND 0x0000000C #define CR_DLVXD_NOT_FOUND 0x0000000C
#define CR_NO_SUCH_DEVNODE 0x0000000D #define CR_NO_SUCH_DEVNODE 0x0000000D
#define CR_NO_SUCH_DEVINST CR_NO_SUCH_DEVNODE #define CR_NO_SUCH_DEVINST CR_NO_SUCH_DEVNODE
#define CR_NO_MORE_LOG_CONF 0x0000000E #define CR_NO_MORE_LOG_CONF 0x0000000E
#define CR_NO_MORE_RES_DES 0x0000000F #define CR_NO_MORE_RES_DES 0x0000000F
#define CR_ALREADY_SUCH_DEVNODE 0x00000010 #define CR_ALREADY_SUCH_DEVNODE 0x00000010
#define CR_ALREADY_SUCH_DEVINST CR_ALREADY_SUCH_DEVNODE #define CR_ALREADY_SUCH_DEVINST CR_ALREADY_SUCH_DEVNODE
#define CR_INVALID_RANGE_LIST 0x00000011 #define CR_INVALID_RANGE_LIST 0x00000011
#define CR_INVALID_RANGE 0x00000012 #define CR_INVALID_RANGE 0x00000012
#define CR_FAILURE 0x00000013 #define CR_FAILURE 0x00000013

View File

@ -5,13 +5,13 @@
import re import re
from functools import partial from functools import partial
from css_selectors.select import Select, get_parsed_selector
from html5_parser import parse from html5_parser import parse
from lxml import etree from lxml import etree
from calibre.ebooks.metadata.tag_mapper import uniq from calibre.ebooks.metadata.tag_mapper import uniq
from calibre.ebooks.oeb.base import OEB_DOCS, XPath from calibre.ebooks.oeb.base import OEB_DOCS, XPath
from calibre.ebooks.oeb.parse_utils import XHTML from calibre.ebooks.oeb.parse_utils import XHTML
from css_selectors.select import Select, get_parsed_selector
def non_empty_validator(label, val): def non_empty_validator(label, val):

View File

@ -11,6 +11,8 @@ import types
from collections import defaultdict, namedtuple from collections import defaultdict, namedtuple
from itertools import chain from itertools import chain
from css_selectors import Select, SelectorError
from calibre import force_unicode, prepare_string_for_xml from calibre import force_unicode, prepare_string_for_xml
from calibre.ebooks.oeb.base import XPath, xml2text from calibre.ebooks.oeb.base import XPath, xml2text
from calibre.ebooks.oeb.polish.container import OEB_DOCS, OEB_STYLES from calibre.ebooks.oeb.polish.container import OEB_DOCS, OEB_STYLES
@ -18,7 +20,6 @@ from calibre.ebooks.oeb.polish.spell import count_all_chars, get_all_words
from calibre.ebooks.oeb.polish.utils import OEB_FONTS from calibre.ebooks.oeb.polish.utils import OEB_FONTS
from calibre.utils.icu import numeric_sort_key, safe_chr from calibre.utils.icu import numeric_sort_key, safe_chr
from calibre.utils.imghdr import identify from calibre.utils.imghdr import identify
from css_selectors import Select, SelectorError
from polyglot.builtins import iteritems from polyglot.builtins import iteritems
File = namedtuple('File', 'name dir basename size category word_count') File = namedtuple('File', 'name dir basename size category word_count')

View File

@ -16,8 +16,8 @@ from lxml import etree
#### Pages/lines #### Pages/lines
# How many pages/lines to scan when finding header/footer automatically # How many pages/lines to scan when finding header/footer automatically
PAGE_SCAN_COUNT = 20 # Arbitrary PAGE_SCAN_COUNT = 20 # Arbitrary
LINE_SCAN_COUNT = 2 # Arbitrary LINE_SCAN_COUNT = 2 # Arbitrary
# Number of character widths that two strings have to be apart, # Number of character widths that two strings have to be apart,
# for them to be considered part of the same text fragment # for them to be considered part of the same text fragment
@ -211,7 +211,7 @@ class Text(Element):
and abs(other.left - self.right) < 2.0: and abs(other.left - self.right) < 2.0:
#and abs(other.left - self.right) < self.average_character_width / 3.0: #and abs(other.left - self.right) < self.average_character_width / 3.0:
has_gap = 0 has_gap = 0
else: # Insert n spaces to fill gap. Use TAB? Columns? else: # Insert n spaces to fill gap. Use TAB? Columns?
if other.left < self.right: if other.left < self.right:
has_gap = 1 # Coalescing different lines. 1 space has_gap = 1 # Coalescing different lines. 1 space
else: # Multiple texts on same line else: # Multiple texts on same line
@ -275,7 +275,7 @@ class Text(Element):
self.font_size_em = max(self.font_size_em, other.font_size_em) self.font_size_em = max(self.font_size_em, other.font_size_em)
self.font = other.font if self.font_size == other.font_size else other.font self.font = other.font if self.font_size == other.font_size else other.font
if has_gap > 0: if has_gap > 0:
if has_gap < 3: # Small number of spaces = 1 space if has_gap < 3: # Small number of spaces = 1 space
if not (self.text_as_string.endswith(' ') \ if not (self.text_as_string.endswith(' ') \
or self.text_as_string.endswith('-') \ or self.text_as_string.endswith('-') \
or other.text_as_string.startswith(' ') \ or other.text_as_string.startswith(' ') \
@ -766,11 +766,11 @@ class Page:
while s < len(text.text_as_string) \ while s < len(text.text_as_string) \
and text.text_as_string[s] == ' ': and text.text_as_string[s] == ' ':
s += 1 s += 1
if s > 2: # Allow two leading spaces if s > 2: # Allow two leading spaces
# Assume this is a standard indent # Assume this is a standard indent
# Normally text.indented gets set later # Normally text.indented gets set later
text.indented = 1 text.indented = 1
w = round(s * text.average_character_width/2.0) # Spaces < avg width w = round(s * text.average_character_width/2.0) # Spaces < avg width
matchObj = re.match(r'^\s*(<[^>]+>)?\s*(.*)$', text.raw) matchObj = re.match(r'^\s*(<[^>]+>)?\s*(.*)$', text.raw)
t1 = matchObj.group(1) t1 = matchObj.group(1)
t2 = matchObj.group(2) t2 = matchObj.group(2)
@ -780,9 +780,9 @@ class Page:
t2 = '' t2 = ''
text.raw = t1 + t2 text.raw = t1 + t2
text.text_as_string = text.text_as_string[s:] text.text_as_string = text.text_as_string[s:]
text.left += w # Add indent text.left += w # Add indent
text.last_left += w text.last_left += w
text.width -= w # Reduce width text.width -= w # Reduce width
text.final_width -= w text.final_width -= w
self.left_margin = min(text.left, self.left_margin) self.left_margin = min(text.left, self.left_margin)
self.right_margin = max(text.right, self.right_margin) self.right_margin = max(text.right, self.right_margin)
@ -846,7 +846,7 @@ class Page:
or (frag.top < t.top and frag.bottom+BOTTOM_FACTOR > t.bottom) \ or (frag.top < t.top and frag.bottom+BOTTOM_FACTOR > t.bottom) \
or (t.top < frag.top and t.bottom > frag.top+BOTTOM_FACTOR) \ or (t.top < frag.top and t.bottom > frag.top+BOTTOM_FACTOR) \
or (t.top < frag.top and t.bottom+BOTTOM_FACTOR > frag.bottom)): or (t.top < frag.top and t.bottom+BOTTOM_FACTOR > frag.bottom)):
return t # Force match if same line return t # Force match if same line
# Sorting can put parts of a line in the wrong order if there are small chars # Sorting can put parts of a line in the wrong order if there are small chars
if t.left < frag.left: if t.left < frag.left:
hdelta = frag.left - t.right hdelta = frag.left - t.right
@ -916,7 +916,7 @@ class Page:
# NB Doesn't work where Contents goes to another page # NB Doesn't work where Contents goes to another page
if re.match(r'(?i)^\s*(table of )?contents\s*$', t.text_as_string) is not None: if re.match(r'(?i)^\s*(table of )?contents\s*$', t.text_as_string) is not None:
self.contents = True self.contents = True
t.tag = 'h2' # It won't get set later t.tag = 'h2' # It won't get set later
# Centered if left and right margins are within FACTOR% # Centered if left and right margins are within FACTOR%
# Because indents can waver a bit, use between indent and indent1 as == indent # Because indents can waver a bit, use between indent and indent1 as == indent
if (lmargin < indent or lmargin > indent1) \ if (lmargin < indent or lmargin > indent1) \
@ -1407,9 +1407,9 @@ class PDFDocument:
# Check for a testable value # Check for a testable value
if self.opts.pdf_header_regex is None: if self.opts.pdf_header_regex is None:
self.opts.pdf_header_regex = '' # Do nothing self.opts.pdf_header_regex = '' # Do nothing
if self.opts.pdf_footer_regex is None: if self.opts.pdf_footer_regex is None:
self.opts.pdf_footer_regex = '' # Do nothing self.opts.pdf_footer_regex = '' # Do nothing
parser = etree.XMLParser(recover=True) parser = etree.XMLParser(recover=True)
self.root = etree.fromstring(xml, parser=parser) self.root = etree.fromstring(xml, parser=parser)
@ -1863,11 +1863,11 @@ class PDFDocument:
if pages_to_scan > 0: if pages_to_scan > 0:
# Doc is shorter than scan_count # Doc is shorter than scan_count
pages_to_scan = scan_count - pages_to_scan # Number scanned pages_to_scan = scan_count - pages_to_scan # Number scanned
else: else:
# All required pages scanned # All required pages scanned
pages_to_scan = scan_count pages_to_scan = scan_count
pages_to_scan /= 2 # Are at least half matching? pages_to_scan /= 2 # Are at least half matching?
head_ind = 0 head_ind = 0
for i in range(LINE_SCAN_COUNT): for i in range(LINE_SCAN_COUNT):

View File

@ -6,54 +6,54 @@
''' '''
Codepages as to RTF 1.9.1: Codepages as to RTF 1.9.1:
437 United States IBM 437 United States IBM
708 Arabic (ASMO 708) 708 Arabic (ASMO 708)
709 Arabic (ASMO 449+, BCON V4) 709 Arabic (ASMO 449+, BCON V4)
710 Arabic (transparent Arabic) 710 Arabic (transparent Arabic)
711 Arabic (Nafitha Enhanced) 711 Arabic (Nafitha Enhanced)
720 Arabic (transparent ASMO) 720 Arabic (transparent ASMO)
819 Windows 3.1 (United States and Western Europe) 819 Windows 3.1 (United States and Western Europe)
850 IBM multilingual 850 IBM multilingual
852 Eastern European 852 Eastern European
860 Portuguese 860 Portuguese
862 Hebrew 862 Hebrew
863 French Canadian 863 French Canadian
864 Arabic 864 Arabic
865 Norwegian 865 Norwegian
866 Soviet Union 866 Soviet Union
874 Thai 874 Thai
932 Japanese 932 Japanese
936 Simplified Chinese 936 Simplified Chinese
949 Korean 949 Korean
950 Traditional Chinese 950 Traditional Chinese
1250 Eastern European 1250 Eastern European
1251 Cyrillic 1251 Cyrillic
1252 Western European 1252 Western European
1253 Greek 1253 Greek
1254 Turkish 1254 Turkish
1255 Hebrew 1255 Hebrew
1256 Arabic 1256 Arabic
1257 Baltic 1257 Baltic
1258 Vietnamese 1258 Vietnamese
1361 Johab 1361 Johab
10000 MAC Roman 10000 MAC Roman
10001 MAC Japan 10001 MAC Japan
10004 MAC Arabic 10004 MAC Arabic
10005 MAC Hebrew 10005 MAC Hebrew
10006 MAC Greek 10006 MAC Greek
10007 MAC Cyrillic 10007 MAC Cyrillic
10029 MAC Latin2 10029 MAC Latin2
10081 MAC Turkish 10081 MAC Turkish
57002 Devanagari 57002 Devanagari
57003 Bengali 57003 Bengali
57004 Tamil 57004 Tamil
57005 Telugu 57005 Telugu
57006 Assamese 57006 Assamese
57007 Oriya 57007 Oriya
57008 Kannada 57008 Kannada
57009 Malayalam 57009 Malayalam
57010 Gujarati 57010 Gujarati
57011 Punjabi 57011 Punjabi
''' '''
import re import re

View File

@ -81,7 +81,7 @@ class FieldStrings:
'INCLUDETEXT' : (self.__include_text_func, 'include-text-from-file'), 'INCLUDETEXT' : (self.__include_text_func, 'include-text-from-file'),
'INDEX' : (self.__index_func, 'index'), 'INDEX' : (self.__index_func, 'index'),
'NOTEREF' : (self.__note_ref_func, 'reference-to-note'), 'NOTEREF' : (self.__note_ref_func, 'reference-to-note'),
'PAGEREF' : (self.__page_ref_func, 'reference-to-page'), 'PAGEREF' : (self.__page_ref_func, 'reference-to-page'),
'REF' : (self.__ref_func, 'reference'), 'REF' : (self.__ref_func, 'reference'),
'ref' : (self.__ref_func, 'reference'), 'ref' : (self.__ref_func, 'reference'),
'SEQ' : (self.__sequence_func, 'numbering-sequence'), 'SEQ' : (self.__sequence_func, 'numbering-sequence'),

View File

@ -129,7 +129,7 @@ if another paragraph_def is found, the state changes to collect_tokens.
'list-simpi' : 'list-simple', 'list-simpi' : 'list-simple',
'list-conti' : 'list-continue', 'list-conti' : 'list-continue',
'list-hang_' : 'list-hang', 'list-hang_' : 'list-hang',
# 'list-tebef' : 'list-text-before', # 'list-tebef' : 'list-text-before',
# 'list-level' : 'level', # 'list-level' : 'level',
'list-id___' : 'list-id', 'list-id___' : 'list-id',
'list-start' : 'list-start', 'list-start' : 'list-start',

View File

@ -182,8 +182,8 @@ class ProcessTokens:
'ixe' : ('in', 'index-ital', self.default_func), 'ixe' : ('in', 'index-ital', self.default_func),
'txe' : ('in', 'index-see_', self.default_func), 'txe' : ('in', 'index-see_', self.default_func),
# table of contents => tc # table of contents => tc
'tcl' : ('tc', 'toc-level_', self.default_func), 'tcl' : ('tc', 'toc-level_', self.default_func),
'tcn' : ('tc', 'toc-sup-nu', self.default_func), 'tcn' : ('tc', 'toc-sup-nu', self.default_func),
# field => fd # field => fd
'field' : ('fd', 'field_____', self.default_func), 'field' : ('fd', 'field_____', self.default_func),
'fldinst' : ('fd', 'field-inst', self.default_func), 'fldinst' : ('fd', 'field-inst', self.default_func),
@ -316,7 +316,7 @@ class ProcessTokens:
'brdrl' : ('bd', 'bor-par-le', self.default_func), 'brdrl' : ('bd', 'bor-par-le', self.default_func),
'brdrr' : ('bd', 'bor-par-ri', self.default_func), 'brdrr' : ('bd', 'bor-par-ri', self.default_func),
'box' : ('bd', 'bor-par-bx', self.default_func), 'box' : ('bd', 'bor-par-bx', self.default_func),
'chbrdr' : ('bd', 'bor-par-bo', self.default_func), 'chbrdr' : ('bd', 'bor-par-bo', self.default_func),
'brdrbtw' : ('bd', 'bor-for-ev', self.default_func), 'brdrbtw' : ('bd', 'bor-for-ev', self.default_func),
'brdrbar' : ('bd', 'bor-outsid', self.default_func), 'brdrbar' : ('bd', 'bor-outsid', self.default_func),
'brdrnone' : ('bd', 'bor-none__<false', self.two_part_func), 'brdrnone' : ('bd', 'bor-none__<false', self.two_part_func),
@ -349,10 +349,10 @@ class ProcessTokens:
'brdrengrave' : ('bt', 'bdr-engra_', self.default_func), 'brdrengrave' : ('bt', 'bdr-engra_', self.default_func),
'brdrframe' : ('bt', 'bdr-frame_', self.default_func), 'brdrframe' : ('bt', 'bdr-frame_', self.default_func),
'brdrw' : ('bt', 'bdr-li-wid', self.divide_by_20), 'brdrw' : ('bt', 'bdr-li-wid', self.divide_by_20),
'brsp' : ('bt', 'bdr-sp-wid', self.divide_by_20), 'brsp' : ('bt', 'bdr-sp-wid', self.divide_by_20),
'brdrcf' : ('bt', 'bdr-color_', self.default_func), 'brdrcf' : ('bt', 'bdr-color_', self.default_func),
# comments # comments
# 'comment' : ('cm', 'comment___', self.default_func), # 'comment' : ('cm', 'comment___', self.default_func),
} }
self.__number_type_dict = { self.__number_type_dict = {
0: 'Arabic', 0: 'Arabic',
@ -405,191 +405,191 @@ class ProcessTokens:
255: 'No number', 255: 'No number',
} }
self.__language_dict = { self.__language_dict = {
1078 : 'Afrikaans', 1078 : 'Afrikaans',
1052 : 'Albanian', 1052 : 'Albanian',
1025 : 'Arabic', 1025 : 'Arabic',
5121 : 'Arabic Algeria', 5121 : 'Arabic Algeria',
15361 : 'Arabic Bahrain', 15361 : 'Arabic Bahrain',
3073 : 'Arabic Egypt', 3073 : 'Arabic Egypt',
1 : 'Arabic General', 1 : 'Arabic General',
2049 : 'Arabic Iraq', 2049 : 'Arabic Iraq',
11265 : 'Arabic Jordan', 11265 : 'Arabic Jordan',
13313 : 'Arabic Kuwait', 13313 : 'Arabic Kuwait',
12289 : 'Arabic Lebanon', 12289 : 'Arabic Lebanon',
4097 : 'Arabic Libya', 4097 : 'Arabic Libya',
6145 : 'Arabic Morocco', 6145 : 'Arabic Morocco',
8193 : 'Arabic Oman', 8193 : 'Arabic Oman',
16385 : 'Arabic Qatar', 16385 : 'Arabic Qatar',
10241 : 'Arabic Syria', 10241 : 'Arabic Syria',
7169 : 'Arabic Tunisia', 7169 : 'Arabic Tunisia',
14337 : 'Arabic U.A.E.', 14337 : 'Arabic U.A.E.',
9217 : 'Arabic Yemen', 9217 : 'Arabic Yemen',
1067 : 'Armenian', 1067 : 'Armenian',
1101 : 'Assamese', 1101 : 'Assamese',
2092 : 'Azeri Cyrillic', 2092 : 'Azeri Cyrillic',
1068 : 'Azeri Latin', 1068 : 'Azeri Latin',
1069 : 'Basque', 1069 : 'Basque',
1093 : 'Bengali', 1093 : 'Bengali',
4122 : 'Bosnia Herzegovina', 4122 : 'Bosnia Herzegovina',
1026 : 'Bulgarian', 1026 : 'Bulgarian',
1109 : 'Burmese', 1109 : 'Burmese',
1059 : 'Byelorussian', 1059 : 'Byelorussian',
1027 : 'Catalan', 1027 : 'Catalan',
2052 : 'Chinese China', 2052 : 'Chinese China',
4 : 'Chinese General', 4 : 'Chinese General',
3076 : 'Chinese Hong Kong', 3076 : 'Chinese Hong Kong',
4100 : 'Chinese Singapore', 4100 : 'Chinese Singapore',
1028 : 'Chinese Taiwan', 1028 : 'Chinese Taiwan',
1050 : 'Croatian', 1050 : 'Croatian',
1029 : 'Czech', 1029 : 'Czech',
1030 : 'Danish', 1030 : 'Danish',
2067 : 'Dutch Belgium', 2067 : 'Dutch Belgium',
1043 : 'Dutch Standard', 1043 : 'Dutch Standard',
3081 : 'English Australia', 3081 : 'English Australia',
10249 : 'English Belize', 10249 : 'English Belize',
2057 : 'English British', 2057 : 'English British',
4105 : 'English Canada', 4105 : 'English Canada',
9225 : 'English Caribbean', 9225 : 'English Caribbean',
9 : 'English General', 9 : 'English General',
6153 : 'English Ireland', 6153 : 'English Ireland',
8201 : 'English Jamaica', 8201 : 'English Jamaica',
5129 : 'English New Zealand', 5129 : 'English New Zealand',
13321 : 'English Philippines', 13321 : 'English Philippines',
7177 : 'English South Africa', 7177 : 'English South Africa',
11273 : 'English Trinidad', 11273 : 'English Trinidad',
1033 : 'English United States', 1033 : 'English United States',
1061 : 'Estonian', 1061 : 'Estonian',
1080 : 'Faerose', 1080 : 'Faerose',
1065 : 'Farsi', 1065 : 'Farsi',
1035 : 'Finnish', 1035 : 'Finnish',
1036 : 'French', 1036 : 'French',
2060 : 'French Belgium', 2060 : 'French Belgium',
11276 : 'French Cameroon', 11276 : 'French Cameroon',
3084 : 'French Canada', 3084 : 'French Canada',
12300 : 'French Cote d\'Ivoire', 12300 : 'French Cote d\'Ivoire',
5132 : 'French Luxembourg', 5132 : 'French Luxembourg',
13324 : 'French Mali', 13324 : 'French Mali',
6156 : 'French Monaco', 6156 : 'French Monaco',
8204 : 'French Reunion', 8204 : 'French Reunion',
10252 : 'French Senegal', 10252 : 'French Senegal',
4108 : 'French Swiss', 4108 : 'French Swiss',
7180 : 'French West Indies', 7180 : 'French West Indies',
9228 : 'French Democratic Republic of the Congo', 9228 : 'French Democratic Republic of the Congo',
1122 : 'Frisian', 1122 : 'Frisian',
1084 : 'Gaelic', 1084 : 'Gaelic',
2108 : 'Gaelic Ireland', 2108 : 'Gaelic Ireland',
1110 : 'Galician', 1110 : 'Galician',
1079 : 'Georgian', 1079 : 'Georgian',
1031 : 'German', 1031 : 'German',
3079 : 'German Austrian', 3079 : 'German Austrian',
5127 : 'German Liechtenstein', 5127 : 'German Liechtenstein',
4103 : 'German Luxembourg', 4103 : 'German Luxembourg',
2055 : 'German Switzerland', 2055 : 'German Switzerland',
1032 : 'Greek', 1032 : 'Greek',
1095 : 'Gujarati', 1095 : 'Gujarati',
1037 : 'Hebrew', 1037 : 'Hebrew',
1081 : 'Hindi', 1081 : 'Hindi',
1038 : 'Hungarian', 1038 : 'Hungarian',
1039 : 'Icelandic', 1039 : 'Icelandic',
1057 : 'Indonesian', 1057 : 'Indonesian',
1040 : 'Italian', 1040 : 'Italian',
2064 : 'Italian Switzerland', 2064 : 'Italian Switzerland',
1041 : 'Japanese', 1041 : 'Japanese',
1099 : 'Kannada', 1099 : 'Kannada',
1120 : 'Kashmiri', 1120 : 'Kashmiri',
2144 : 'Kashmiri India', 2144 : 'Kashmiri India',
1087 : 'Kazakh', 1087 : 'Kazakh',
1107 : 'Khmer', 1107 : 'Khmer',
1088 : 'Kirghiz', 1088 : 'Kirghiz',
1111 : 'Konkani', 1111 : 'Konkani',
1042 : 'Korean', 1042 : 'Korean',
2066 : 'Korean Johab', 2066 : 'Korean Johab',
1108 : 'Lao', 1108 : 'Lao',
1062 : 'Latvian', 1062 : 'Latvian',
1063 : 'Lithuanian', 1063 : 'Lithuanian',
2087 : 'Lithuanian Classic', 2087 : 'Lithuanian Classic',
1086 : 'Malay', 1086 : 'Malay',
2110 : 'Malay Brunei Darussalam', 2110 : 'Malay Brunei Darussalam',
1100 : 'Malayalam', 1100 : 'Malayalam',
1082 : 'Maltese', 1082 : 'Maltese',
1112 : 'Manipuri', 1112 : 'Manipuri',
1102 : 'Marathi', 1102 : 'Marathi',
1104 : 'Mongolian', 1104 : 'Mongolian',
1121 : 'Nepali', 1121 : 'Nepali',
2145 : 'Nepali India', 2145 : 'Nepali India',
1044 : 'Norwegian Bokmal', 1044 : 'Norwegian Bokmal',
2068 : 'Norwegian Nynorsk', 2068 : 'Norwegian Nynorsk',
1096 : 'Oriya', 1096 : 'Oriya',
1045 : 'Polish', 1045 : 'Polish',
1046 : 'Portuguese (Brazil)', 1046 : 'Portuguese (Brazil)',
2070 : 'Portuguese (Portugal)', 2070 : 'Portuguese (Portugal)',
1094 : 'Punjabi', 1094 : 'Punjabi',
1047 : 'Rhaeto-Romanic', 1047 : 'Rhaeto-Romanic',
1048 : 'Romanian', 1048 : 'Romanian',
2072 : 'Romanian Moldova', 2072 : 'Romanian Moldova',
1049 : 'Russian', 1049 : 'Russian',
2073 : 'Russian Moldova', 2073 : 'Russian Moldova',
1083 : 'Sami Lappish', 1083 : 'Sami Lappish',
1103 : 'Sanskrit', 1103 : 'Sanskrit',
3098 : 'Serbian Cyrillic', 3098 : 'Serbian Cyrillic',
2074 : 'Serbian Latin', 2074 : 'Serbian Latin',
1113 : 'Sindhi', 1113 : 'Sindhi',
1051 : 'Slovak', 1051 : 'Slovak',
1060 : 'Slovenian', 1060 : 'Slovenian',
1070 : 'Sorbian', 1070 : 'Sorbian',
11274 : 'Spanish Argentina', 11274 : 'Spanish Argentina',
16394 : 'Spanish Bolivia', 16394 : 'Spanish Bolivia',
13322 : 'Spanish Chile', 13322 : 'Spanish Chile',
9226 : 'Spanish Colombia', 9226 : 'Spanish Colombia',
5130 : 'Spanish Costa Rica', 5130 : 'Spanish Costa Rica',
7178 : 'Spanish Dominican Republic', 7178 : 'Spanish Dominican Republic',
12298 : 'Spanish Ecuador', 12298 : 'Spanish Ecuador',
17418 : 'Spanish El Salvador', 17418 : 'Spanish El Salvador',
4106 : 'Spanish Guatemala', 4106 : 'Spanish Guatemala',
18442 : 'Spanish Honduras', 18442 : 'Spanish Honduras',
2058 : 'Spanish Mexico', 2058 : 'Spanish Mexico',
3082 : 'Spanish Modern', 3082 : 'Spanish Modern',
19466 : 'Spanish Nicaragua', 19466 : 'Spanish Nicaragua',
6154 : 'Spanish Panama', 6154 : 'Spanish Panama',
15370 : 'Spanish Paraguay', 15370 : 'Spanish Paraguay',
10250 : 'Spanish Peru', 10250 : 'Spanish Peru',
20490 : 'Spanish Puerto Rico', 20490 : 'Spanish Puerto Rico',
1034 : 'Spanish Traditional', 1034 : 'Spanish Traditional',
14346 : 'Spanish Uruguay', 14346 : 'Spanish Uruguay',
8202 : 'Spanish Venezuela', 8202 : 'Spanish Venezuela',
1072 : 'Sutu', 1072 : 'Sutu',
1089 : 'Swahili', 1089 : 'Swahili',
1053 : 'Swedish', 1053 : 'Swedish',
2077 : 'Swedish Finland', 2077 : 'Swedish Finland',
1064 : 'Tajik', 1064 : 'Tajik',
1097 : 'Tamil', 1097 : 'Tamil',
1092 : 'Tatar', 1092 : 'Tatar',
1098 : 'Telugu', 1098 : 'Telugu',
1054 : 'Thai', 1054 : 'Thai',
1105 : 'Tibetan', 1105 : 'Tibetan',
1073 : 'Tsonga', 1073 : 'Tsonga',
1074 : 'Tswana', 1074 : 'Tswana',
1055 : 'Turkish', 1055 : 'Turkish',
1090 : 'Turkmen', 1090 : 'Turkmen',
1058 : 'Ukranian', 1058 : 'Ukranian',
1056 : 'Urdu', 1056 : 'Urdu',
2080 : 'Urdu India', 2080 : 'Urdu India',
2115 : 'Uzbek Cyrillic', 2115 : 'Uzbek Cyrillic',
1091 : 'Uzbek Latin', 1091 : 'Uzbek Latin',
1075 : 'Venda', 1075 : 'Venda',
1066 : 'Vietnamese', 1066 : 'Vietnamese',
1106 : 'Welsh', 1106 : 'Welsh',
1076 : 'Xhosa', 1076 : 'Xhosa',
1085 : 'Yiddish', 1085 : 'Yiddish',
1077 : 'Zulu', 1077 : 'Zulu',
1024 : 'Unkown', 1024 : 'Unkown',
255 : 'Unkown', 255 : 'Unkown',
} }
""" """
# unknown # unknown
# These must get passed on because they occurred after \\* # These must get passed on because they occurred after \\*
'do' : ('un', 'unknown___', self.default_func), 'do' : ('un', 'unknown___', self.default_func),
'company' : ('un', 'company___', self.default_func), 'company' : ('un', 'company___', self.default_func),
'shpinst' : ('un', 'unknown___', self.default_func), 'shpinst' : ('un', 'unknown___', self.default_func),
'panose' : ('un', 'unknown___', self.default_func), 'panose' : ('un', 'unknown___', self.default_func),
'falt' : ('un', 'unknown___', self.default_func), 'falt' : ('un', 'unknown___', self.default_func),
@ -603,9 +603,9 @@ class ProcessTokens:
'generator' : ('un', 'unknown___', self.default_func), 'generator' : ('un', 'unknown___', self.default_func),
'ftnsep' : ('un', 'unknown___', self.default_func), 'ftnsep' : ('un', 'unknown___', self.default_func),
'aftnsep' : ('un', 'unknown___', self.default_func), 'aftnsep' : ('un', 'unknown___', self.default_func),
'aftnsepc' : ('un', 'unknown___', self.default_func), 'aftnsepc' : ('un', 'unknown___', self.default_func),
'aftncn' : ('un', 'unknown___', self.default_func), 'aftncn' : ('un', 'unknown___', self.default_func),
'objclass' : ('un', 'unknown___', self.default_func), 'objclass' : ('un', 'unknown___', self.default_func),
'objdata' : ('un', 'unknown___', self.default_func), 'objdata' : ('un', 'unknown___', self.default_func),
'picprop' : ('un', 'unknown___', self.default_func), 'picprop' : ('un', 'unknown___', self.default_func),
'blipuid' : ('un', 'unknown___', self.default_func), 'blipuid' : ('un', 'unknown___', self.default_func),

View File

@ -124,7 +124,7 @@ class Styles:
'list-simpi' : 'list-simple', 'list-simpi' : 'list-simple',
'list-conti' : 'list-continue', 'list-conti' : 'list-continue',
'list-hang_' : 'list-hang', 'list-hang_' : 'list-hang',
# 'list-tebef' : 'list-text-before', # 'list-tebef' : 'list-text-before',
# 'list-level' : 'level', # 'list-level' : 'level',
'list-id___' : 'list-id', 'list-id___' : 'list-id',
'list-start' : 'list-start', 'list-start' : 'list-start',

View File

@ -121,7 +121,7 @@ class Table:
Look for 'mi<mk<pard-start', which marks the beginning of a row. Start Look for 'mi<mk<pard-start', which marks the beginning of a row. Start
a row and start a cell. a row and start a cell.
""" """
# 'cell' : ('tb', 'cell______', self.default_func), # 'cell' : ('tb', 'cell______', self.default_func),
if self.__token_info == 'mi<mk<not-in-tbl' or\ if self.__token_info == 'mi<mk<not-in-tbl' or\
self.__token_info == 'mi<mk<sect-start' or\ self.__token_info == 'mi<mk<sect-start' or\
self.__token_info == 'mi<mk<sect-close' or\ self.__token_info == 'mi<mk<sect-close' or\

View File

@ -5,11 +5,11 @@ from contextlib import suppress
from typing import List, NamedTuple, Optional, Tuple from typing import List, NamedTuple, Optional, Tuple
from css_parser.css import CSSRule from css_parser.css import CSSRule
from css_selectors import Select, SelectorError
from calibre.ebooks.oeb.parse_utils import barename from calibre.ebooks.oeb.parse_utils import barename
from calibre.ebooks.oeb.polish.container import get_container from calibre.ebooks.oeb.polish.container import get_container
from calibre.ebooks.oeb.polish.parsing import parse from calibre.ebooks.oeb.polish.parsing import parse
from css_selectors import Select, SelectorError
class NoMatchingTagFound(KeyError): class NoMatchingTagFound(KeyError):

View File

@ -20,7 +20,7 @@ BANNER = ('Welcome to the interactive calibre shell!\n')
def setup_pyreadline(): def setup_pyreadline():
config = ''' config = '''
#Bind keys for exit (keys only work on empty lines #Bind keys for exit (keys only work on empty lines
#disable_readline(True) #Disable pyreadline completely. #disable_readline(True) #Disable pyreadline completely.
debug_output("off") #"on" saves log info to./pyreadline_debug_log.txt debug_output("off") #"on" saves log info to./pyreadline_debug_log.txt
#"on_nologfile" only enables print warning messages #"on_nologfile" only enables print warning messages
bind_exit_key("Control-d") bind_exit_key("Control-d")

View File

@ -1,5 +1,19 @@
# autogenerated by __main__.py do not edit # autogenerated by __main__.py do not edit
top_level_module_names=('QtCore', 'QtGui', 'QtWidgets', 'QtNetwork', 'QtSvg', 'QtPrintSupport', 'QtOpenGL', 'QtOpenGLWidgets', 'QtQuick', 'QtMultimedia', 'QtMultimediaWidgets', 'QtTextToSpeech', 'QtWebEngineCore', 'QtWebEngineWidgets', 'QtDBus') top_level_module_names = ('QtCore',
'QtGui',
'QtWidgets',
'QtNetwork',
'QtSvg',
'QtPrintSupport',
'QtOpenGL',
'QtOpenGLWidgets',
'QtQuick',
'QtMultimedia',
'QtMultimediaWidgets',
'QtTextToSpeech',
'QtWebEngineCore',
'QtWebEngineWidgets',
'QtDBus')
def __getattr__(name): def __getattr__(name):
@ -7,4 +21,3 @@ def __getattr__(name):
import importlib import importlib
return importlib.import_module("PyQt6." + name) return importlib.import_module("PyQt6." + name)
raise AttributeError(name) raise AttributeError(name)

View File

@ -1,5 +1,4 @@
#!/usr/bin/env python #!/usr/bin/env python
# vim:fileencoding=utf-8
# License: GPL v3 Copyright: 2021, Kovid Goyal <kovid at kovidgoyal.net> # License: GPL v3 Copyright: 2021, Kovid Goyal <kovid at kovidgoyal.net>
import importlib import importlib
@ -56,10 +55,10 @@ qt_modules = {}
def __getattr__(name): def __getattr__(name):
return dynamic_load(name, name_map, already_imported, qt_modules, module_names) return dynamic_load(name, name_map, already_imported, qt_modules, module_names)
''', file=f) ''', end='', file=f)
with open(f'{base}/{name}.pyi', 'w') as f: with open(f'{base}/{name}.pyi', 'w') as f:
print('# autogenerated by __main__.py do not edit', file=f) print('# autogenerated by __main__.py do not edit', file=f)
f.write('\n'.join(types)) print('\n'.join(types), file=f)
if name == 'core': if name == 'core':
module_names += ('sip',) module_names += ('sip',)
mod = importlib.import_module(f'{QT_WRAPPER}.sip') mod = importlib.import_module(f'{QT_WRAPPER}.sip')
@ -79,7 +78,8 @@ for name in module_lists.keys():
scan(name) scan(name)
with open(f'{base}/__init__.py', 'w') as f: with open(f'{base}/__init__.py', 'w') as f:
print('# autogenerated by __main__.py do not edit', file=f) print('# autogenerated by __main__.py do not edit', file=f)
print(f'{top_level_module_names=}', file=f) print('top_level_module_names = ', end='', file=f)
pprint(top_level_module_names, stream=f)
print(f''' print(f'''
def __getattr__(name): def __getattr__(name):
@ -87,4 +87,4 @@ def __getattr__(name):
import importlib import importlib
return importlib.import_module("{QT_WRAPPER}." + name) return importlib.import_module("{QT_WRAPPER}." + name)
raise AttributeError(name) raise AttributeError(name)
''', file=f) ''', end='', file=f)

View File

@ -1,5 +1,4 @@
#!/usr/bin/env python #!/usr/bin/env python
# vim:fileencoding=utf-8
# License: GPL v3 Copyright: 2021, Kovid Goyal <kovid at kovidgoyal.net> # License: GPL v3 Copyright: 2021, Kovid Goyal <kovid at kovidgoyal.net>
import sys import sys