mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Merge branch 'ruff-pep8' of https://github.com/un-pogaz/calibre
This commit is contained in:
commit
5c9d3386ee
@ -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]
|
||||||
|
@ -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()
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
@ -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):
|
||||||
|
@ -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.
|
||||||
|
@ -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):
|
||||||
|
|
||||||
|
@ -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"]
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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):
|
||||||
|
@ -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'
|
||||||
|
@ -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'
|
||||||
|
@ -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'
|
||||||
|
@ -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('//'):
|
||||||
|
@ -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'
|
||||||
|
@ -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'
|
||||||
|
@ -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 = [
|
||||||
|
@ -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'
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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')
|
||||||
|
@ -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')
|
||||||
|
@ -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'),
|
||||||
|
@ -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('/'):
|
||||||
|
@ -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):
|
||||||
|
@ -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):
|
||||||
|
|
||||||
|
@ -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']
|
||||||
|
@ -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"
|
||||||
|
@ -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
|
||||||
|
@ -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'
|
||||||
|
@ -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'
|
||||||
|
@ -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):
|
||||||
|
@ -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', '')
|
||||||
|
@ -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
|
||||||
|
@ -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('/'):
|
||||||
|
@ -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 = [
|
||||||
|
@ -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
|
||||||
#
|
#
|
||||||
|
@ -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()
|
||||||
|
@ -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 Russia’s 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 Russia’s 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'
|
||||||
|
@ -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
|
||||||
#
|
#
|
||||||
|
@ -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
|
||||||
|
@ -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'
|
||||||
|
@ -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'
|
||||||
|
@ -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'
|
||||||
|
@ -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
|
||||||
|
@ -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'
|
||||||
|
@ -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'
|
||||||
|
@ -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.
|
||||||
|
@ -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'
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
@ -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'),
|
||||||
('Mauricie–Centre-du-Québec', 'https://ici.radio-canada.ca/rss/5777'),
|
('Mauricie–Centre-du-Québec', 'https://ici.radio-canada.ca/rss/5777'),
|
||||||
('Nord de l’Ontario', 'https://ici.radio-canada.ca/rss/36518'),
|
('Nord de l’Ontario', '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:
|
||||||
|
@ -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'
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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?
|
||||||
#
|
#
|
||||||
|
@ -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')
|
||||||
]
|
]
|
||||||
|
@ -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
|
||||||
#
|
#
|
||||||
|
@ -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. Let’s 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. Let’s 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'
|
||||||
|
@ -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'
|
||||||
|
@ -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. Let’s 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. Let’s 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'
|
||||||
|
@ -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')
|
||||||
]
|
]
|
||||||
|
@ -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):
|
||||||
|
@ -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.
|
||||||
|
@ -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):
|
||||||
|
@ -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'),
|
||||||
]
|
]
|
||||||
|
|
@ -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'
|
||||||
|
@ -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']
|
||||||
|
@ -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'
|
||||||
|
@ -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'
|
||||||
|
@ -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:
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
@ -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'
|
||||||
|
@ -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:
|
||||||
|
@ -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] = []
|
||||||
|
@ -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:
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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):
|
||||||
|
@ -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')
|
||||||
|
@ -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):
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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'),
|
||||||
|
@ -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',
|
||||||
|
@ -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),
|
||||||
|
@ -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',
|
||||||
|
@ -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\
|
||||||
|
@ -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):
|
||||||
|
@ -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")
|
||||||
|
@ -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)
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user