Merge from trunk

This commit is contained in:
Charles Haley 2012-06-12 09:43:39 +02:00
commit 284bbb58df
12 changed files with 150 additions and 24 deletions

View 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

View File

@ -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):

View File

@ -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'

View File

@ -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.

View File

@ -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))

View File

@ -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:

View File

@ -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);

View File

@ -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
}

View File

@ -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:

View File

@ -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;

View File

@ -74,6 +74,7 @@ namespace QtCurve
else
return false;
#else
Q_UNUSED(widget);
return compositingActive();
#endif
}

View File

@ -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
}