mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Merge from trunk
This commit is contained in:
commit
284bbb58df
90
recipes/nzz_webpaper.recipe
Normal file
90
recipes/nzz_webpaper.recipe
Normal file
@ -0,0 +1,90 @@
|
||||
from calibre import strftime
|
||||
|
||||
__license__ = 'GPL v3'
|
||||
__copyright__ = '2012, Bernd Leinfelder <skoll1975 at gmail.com> '
|
||||
|
||||
'''
|
||||
webpaper.nzz.ch
|
||||
'''
|
||||
|
||||
from calibre.web.feeds.recipes import BasicNewsRecipe
|
||||
|
||||
class Nzz(BasicNewsRecipe):
|
||||
title = 'NZZ Webpaper'
|
||||
__author__ = 'Bernd Leinfelder'
|
||||
description = 'Neue Zuercher Zeitung Webpaper - Erfordert NZZ Digital Abonnement'
|
||||
timefmt = ' [%a, %d %b, %Y]'
|
||||
publisher = 'NZZ AG'
|
||||
needs_subscription = True
|
||||
category = 'news, politics, nachrichten, Switzerland'
|
||||
oldest_article = 2
|
||||
max_articles_per_feed = 100
|
||||
no_stylesheets = True
|
||||
encoding = 'utf-8'
|
||||
use_embedded_content = False
|
||||
language = 'de'
|
||||
extra_css = 'h1 {font: sans-serif large;}\n.byline {font:monospace;}'
|
||||
|
||||
conversion_options = {
|
||||
'comments' : description
|
||||
,'tags' : category
|
||||
,'language' : language
|
||||
,'publisher' : publisher
|
||||
}
|
||||
|
||||
remove_tags = [dict(name='footer')]
|
||||
|
||||
remove_tags_before = dict(name='article')
|
||||
remove_tags_after= dict(name='footer')
|
||||
|
||||
def parse_index(self):
|
||||
baseref = 'https://webpaper.nzz.ch'
|
||||
soup = self.index_to_soup(baseref)
|
||||
|
||||
articles = {}
|
||||
key = None
|
||||
ans = []
|
||||
|
||||
issuelist = soup.find(id="issueSelectorList")
|
||||
|
||||
feeds = issuelist.findAll("a")
|
||||
for f in feeds:
|
||||
section = f.string
|
||||
sectionref = baseref + f['href']
|
||||
|
||||
# print "section is "+section +" and ref is "+sectionref
|
||||
ans.append(section)
|
||||
|
||||
articlesoup = self.index_to_soup(sectionref)
|
||||
|
||||
articlesoup = articlesoup.findAll('article','article')
|
||||
for a in articlesoup:
|
||||
artlink = a.find('a')
|
||||
|
||||
arthref = baseref + artlink['href']
|
||||
arthead = a.find('h2')
|
||||
artcaption = arthead.string
|
||||
|
||||
pubdate = strftime('%a, %d %b')
|
||||
|
||||
if not artcaption is None:
|
||||
# print " found article named "+artcaption+" at "+arthref
|
||||
if not articles.has_key(section):
|
||||
articles[section] = []
|
||||
articles[section].append(
|
||||
dict(title=artcaption, url=arthref, date=pubdate, description='', content=''))
|
||||
|
||||
ans = [(key, articles[key]) for key in ans if articles.has_key(key)]
|
||||
return ans
|
||||
|
||||
def get_browser(self):
|
||||
br = BasicNewsRecipe.get_browser()
|
||||
if self.username is not None and self.password is not None:
|
||||
br.open('https://webpaper.nzz.ch/login')
|
||||
br.select_form(nr=0)
|
||||
br['_username'] = self.username
|
||||
br['_password'] = self.password
|
||||
br.submit()
|
||||
return br
|
||||
|
||||
|
@ -482,6 +482,10 @@ class Py2App(object):
|
||||
shutil.rmtree(tdir)
|
||||
shutil.rmtree(os.path.join(self.site_packages, 'calibre', 'plugins'))
|
||||
self.remove_bytecode(join(self.resources_dir, 'Python', 'site-packages'))
|
||||
# Create dummy IPython README_STARTUP
|
||||
with open(join(self.site_packages,
|
||||
'IPython/config/profile/README_STARTUP'), 'wb') as f:
|
||||
f.write('\n')
|
||||
|
||||
@flush
|
||||
def add_modules_from_dir(self, src):
|
||||
@ -551,6 +555,15 @@ class Py2App(object):
|
||||
if dest2.endswith('.so'):
|
||||
self.fix_dependencies_in_lib(dest2)
|
||||
self.remove_bytecode(join(self.resources_dir, 'Python', 'lib'))
|
||||
confdir = join(self.resources_dir, 'Python',
|
||||
'lib/python%s/config'%self.version_info)
|
||||
os.makedirs(confdir)
|
||||
shutil.copy2(join(src, 'config/Makefile'), confdir)
|
||||
incdir = join(self.resources_dir, 'Python',
|
||||
'include/python'+self.version_info)
|
||||
os.makedirs(incdir)
|
||||
shutil.copy2(join(src.replace('/lib/', '/include/'), 'pyconfig.h'),
|
||||
incdir)
|
||||
|
||||
@flush
|
||||
def remove_bytecode(self, dest):
|
||||
|
@ -14,7 +14,7 @@ from setup.build_environment import msvc, MT, RC
|
||||
from setup.installer.windows.wix import WixMixIn
|
||||
|
||||
OPENSSL_DIR = r'Q:\openssl'
|
||||
QT_DIR = 'Q:\\Qt\\4.8.1'
|
||||
QT_DIR = 'Q:\\Qt\\4.8.2'
|
||||
QT_DLLS = ['Core', 'Gui', 'Network', 'Svg', 'WebKit', 'Xml', 'XmlPatterns']
|
||||
QTCURVE = r'C:\plugins\styles'
|
||||
LIBUNRAR = 'C:\\Program Files\\UnrarDLL\\unrar.dll'
|
||||
|
@ -97,7 +97,7 @@ Now, run configure and make::
|
||||
|
||||
-no-plugin-manifests is needed so that loading the plugins does not fail looking for the CRT assembly
|
||||
|
||||
configure -opensource -release -qt-zlib -qt-libmng -qt-libpng -qt-libtiff -qt-libjpeg -release -platform win32-msvc2008 -no-qt3support -webkit -xmlpatterns -no-phonon -no-style-plastique -no-style-cleanlooks -no-style-motif -no-style-cde -no-declarative -no-scripttools -no-audio-backend -no-multimedia -no-dbus -no-openvg -no-opengl -no-qt3support -confirm-license -nomake examples -nomake demos -nomake docs -no-plugin-manifests -openssl -I Q:\openssl\include -L Q:\openssl\lib && nmake
|
||||
configure -opensource -release -ltcg -qt-zlib -qt-libmng -qt-libpng -qt-libtiff -qt-libjpeg -release -platform win32-msvc2008 -no-qt3support -webkit -xmlpatterns -no-phonon -no-style-plastique -no-style-cleanlooks -no-style-motif -no-style-cde -no-declarative -no-scripttools -no-audio-backend -no-multimedia -no-dbus -no-openvg -no-opengl -no-qt3support -confirm-license -nomake examples -nomake demos -nomake docs -no-plugin-manifests -openssl -I Q:\openssl\include -L Q:\openssl\lib && nmake
|
||||
|
||||
Add the path to the bin folder inside the Qt dir to your system PATH.
|
||||
|
||||
|
@ -372,6 +372,11 @@ class Chunker(object):
|
||||
# the chunk immediately after
|
||||
pos_fid = (chunk.sequence_number, 0, offset)
|
||||
break
|
||||
if chunk is self.chunk_table[-1]:
|
||||
# This can happen for aids very close to the end of the the
|
||||
# end of the text (https://bugs.launchpad.net/bugs/1011330)
|
||||
pos_fid = (chunk.sequence_number, offset-chunk.insert_pos,
|
||||
offset)
|
||||
if pos_fid is None:
|
||||
raise ValueError('Could not find chunk for aid: %r'%
|
||||
match.group(1))
|
||||
|
@ -22,10 +22,10 @@ from calibre.gui2.store.search_result import SearchResult
|
||||
from calibre.gui2.store.web_store_dialog import WebStoreDialog
|
||||
|
||||
class GutenbergStore(BasicStoreConfig, StorePlugin):
|
||||
|
||||
|
||||
def open(self, parent=None, detail_item=None, external=False):
|
||||
url = 'http://gutenberg.org/'
|
||||
|
||||
|
||||
if detail_item:
|
||||
detail_item = url_slash_cleaner(url + detail_item)
|
||||
|
||||
@ -39,46 +39,46 @@ class GutenbergStore(BasicStoreConfig, StorePlugin):
|
||||
|
||||
def search(self, query, max_results=10, timeout=60):
|
||||
url = 'http://m.gutenberg.org/ebooks/search.mobile/?default_prefix=all&sort_order=title&query=' + urllib.quote_plus(query)
|
||||
|
||||
|
||||
br = browser()
|
||||
|
||||
|
||||
counter = max_results
|
||||
with closing(br.open(url, timeout=timeout)) as f:
|
||||
doc = html.fromstring(f.read())
|
||||
for data in doc.xpath('//ol[@class="results"]//li[contains(@class, "icon_title") and not(contains(@class, "toplink"))]'):
|
||||
for data in doc.xpath('//ol[@class="results"]/li[@class="booklink"]'):
|
||||
if counter <= 0:
|
||||
break
|
||||
|
||||
id = ''.join(data.xpath('./a/@href'))
|
||||
id = id.split('.mobile')[0]
|
||||
|
||||
|
||||
title = ''.join(data.xpath('.//span[@class="title"]/text()'))
|
||||
author = ''.join(data.xpath('.//span[@class="subtitle"]/text()'))
|
||||
|
||||
|
||||
counter -= 1
|
||||
|
||||
|
||||
s = SearchResult()
|
||||
s.cover_url = ''
|
||||
|
||||
|
||||
s.detail_item = id.strip()
|
||||
s.title = title.strip()
|
||||
s.author = author.strip()
|
||||
s.price = '$0.00'
|
||||
s.drm = SearchResult.DRM_UNLOCKED
|
||||
|
||||
|
||||
yield s
|
||||
|
||||
def get_details(self, search_result, timeout):
|
||||
url = url_slash_cleaner('http://m.gutenberg.org/' + search_result.detail_item)
|
||||
|
||||
|
||||
br = browser()
|
||||
with closing(br.open(url, timeout=timeout)) as nf:
|
||||
doc = html.fromstring(nf.read())
|
||||
|
||||
|
||||
for save_item in doc.xpath('//li[contains(@class, "icon_save")]/a'):
|
||||
type = save_item.get('type')
|
||||
href = save_item.get('href')
|
||||
|
||||
|
||||
if type:
|
||||
ext = mimetypes.guess_extension(type)
|
||||
if ext:
|
||||
|
@ -976,6 +976,7 @@ class QtCConfig
|
||||
|
||||
QtCConfig::QtCConfig(const QString &filename)
|
||||
{
|
||||
if (filename.isEmpty()) return; // Changed by Kovid to ensure config files are never read
|
||||
QFile f(filename);
|
||||
|
||||
#if QT_VERSION >= 0x040000
|
||||
@ -1748,17 +1749,13 @@ bool qtcReadConfig(const char *file, Options *opts, Options *defOpts)
|
||||
#endif
|
||||
else
|
||||
{
|
||||
// Changed by Kovid to ensure config files are never read
|
||||
#ifdef __cplusplus
|
||||
QtCConfig cfg(file);
|
||||
|
||||
if(cfg.ok())
|
||||
{
|
||||
QtCConfig cfg(QString(""));
|
||||
#else
|
||||
GHashTable *cfg=loadConfig(file);
|
||||
|
||||
if(cfg)
|
||||
{
|
||||
GHashTable *cfg=NULL;
|
||||
#endif
|
||||
if (0) {
|
||||
int i;
|
||||
|
||||
opts->version=readVersionEntry(cfg, VERSION_KEY);
|
||||
|
@ -209,6 +209,9 @@ namespace QtCurve
|
||||
// force update
|
||||
if( widget->isVisible() )
|
||||
{ widget->update(); }
|
||||
|
||||
#else
|
||||
Q_UNUSED(widget);
|
||||
|
||||
#endif
|
||||
|
||||
@ -220,6 +223,8 @@ namespace QtCurve
|
||||
{
|
||||
#ifdef Q_WS_X11
|
||||
XChangeProperty( QX11Info::display(), widget->winId(), _atom, XA_CARDINAL, 32, PropModeReplace, 0, 0 );
|
||||
#else
|
||||
Q_UNUSED(widget);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
@ -731,6 +731,7 @@ inline int numButtons(EScrollbar type)
|
||||
case SCROLLBAR_NONE:
|
||||
return 0;
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
|
||||
static inline void drawRect(QPainter *p, const QRect &r)
|
||||
@ -963,6 +964,7 @@ Style::Style()
|
||||
itsAnimateStep(0),
|
||||
itsTitlebarHeight(0),
|
||||
calibre_icon_map(QHash<int,QString>()),
|
||||
is_kde_session(0),
|
||||
itsPos(-1, -1),
|
||||
itsHoverWidget(0L),
|
||||
#ifdef Q_WS_X11
|
||||
@ -977,6 +979,9 @@ Style::Style()
|
||||
, itsName(name)
|
||||
#endif
|
||||
{
|
||||
#if !defined(_WIN32) && !defined(__APPLE__)
|
||||
is_kde_session = (getenv("KDE_FULL_SESSION") != NULL);
|
||||
#endif
|
||||
const char *env=getenv(QTCURVE_PREVIEW_CONFIG);
|
||||
if(env && 0==strcmp(env, QTCURVE_PREVIEW_CONFIG))
|
||||
{
|
||||
@ -3602,7 +3607,14 @@ int Style::styleHint(StyleHint hint, const QStyleOption *option, const QWidget *
|
||||
#endif
|
||||
return 0;
|
||||
case SH_DialogButtonLayout:
|
||||
return opts.gtkButtonOrder ? QDialogButtonBox::GnomeLayout : QDialogButtonBox::KdeLayout;
|
||||
// Changed by Kovid to use platform specific button orders.
|
||||
#ifdef _WIN32
|
||||
return QDialogButtonBox::WinLayout;
|
||||
#elif defined(__APPLE__)
|
||||
return QDialogButtonBox::MacLayout;
|
||||
#else
|
||||
return is_kde_session ? QDialogButtonBox::KdeLayout : QDialogButtonBox::GnomeLayout;
|
||||
#endif
|
||||
case SH_MessageBox_TextInteractionFlags:
|
||||
return Qt::TextSelectableByMouse | Qt::LinksAccessibleByMouse;
|
||||
case SH_LineEdit_PasswordCharacter:
|
||||
|
@ -355,6 +355,7 @@ class Style : public QCommonStyle
|
||||
mutable QList<int> itsMdiButtons[2]; // 0=left, 1=right
|
||||
mutable int itsTitlebarHeight;
|
||||
QHash<int,QString> calibre_icon_map;
|
||||
bool is_kde_session;
|
||||
|
||||
// Required for Q3Header hover...
|
||||
QPoint itsPos;
|
||||
|
@ -74,6 +74,7 @@ namespace QtCurve
|
||||
else
|
||||
return false;
|
||||
#else
|
||||
Q_UNUSED(widget);
|
||||
return compositingActive();
|
||||
#endif
|
||||
}
|
||||
|
@ -680,6 +680,8 @@ namespace QtCurve
|
||||
NETRootInfo rootInfo(QX11Info::display(), NET::WMMoveResize);
|
||||
rootInfo.moveResizeRequest( widget->window()->winId(), position.x(), position.y(), NET::Move);
|
||||
#endif // QTC_QT_ONLY
|
||||
#else
|
||||
Q_UNUSED(position);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user