diff --git a/resources/recipes/gizmodo.recipe b/resources/recipes/gizmodo.recipe
index 6f6e6ae0cf..4233ef66b7 100644
--- a/resources/recipes/gizmodo.recipe
+++ b/resources/recipes/gizmodo.recipe
@@ -17,7 +17,7 @@ class Gizmodo(BasicNewsRecipe):
max_articles_per_feed = 100
no_stylesheets = True
encoding = 'utf-8'
- use_embedded_content = True
+ use_embedded_content = False
language = 'en'
masthead_url = 'http://cache.gawkerassets.com/assets/gizmodo.com/img/logo.png'
extra_css = ' body{font-family: "Lucida Grande",Helvetica,Arial,sans-serif} img{margin-bottom: 1em} '
@@ -29,9 +29,11 @@ class Gizmodo(BasicNewsRecipe):
, 'language' : language
}
- remove_attributes = ['width','height']
- remove_tags = [dict(name='div',attrs={'class':'feedflare'})]
- remove_tags_after = dict(name='div',attrs={'class':'feedflare'})
+ remove_attributes = ['width','height']
+ keep_only_tags = [dict(attrs={'class':'content permalink'})]
+ remove_tags_before = dict(name='h1')
+ remove_tags = [dict(attrs={'class':'contactinfo'})]
+ remove_tags_after = dict(attrs={'class':'contactinfo'})
feeds = [(u'Articles', u'http://feeds.gawker.com/gizmodo/full')]
diff --git a/resources/recipes/vreme.recipe b/resources/recipes/vreme.recipe
index a54353b78c..197c20f108 100644
--- a/resources/recipes/vreme.recipe
+++ b/resources/recipes/vreme.recipe
@@ -52,10 +52,12 @@ class Vreme(BasicNewsRecipe):
def parse_index(self):
articles = []
soup = self.index_to_soup(self.INDEX)
-
+ cover_item = soup.find('div',attrs={'id':'najava'})
+ if cover_item:
+ self.cover_url = self.INDEX + cover_item.img['src']
for item in soup.findAll(['h3','h4']):
- description = ''
- title_prefix = ''
+ description = u''
+ title_prefix = u''
feed_link = item.find('a')
if feed_link and feed_link.has_key('href') and feed_link['href'].startswith('/cms/view.php'):
url = self.INDEX + feed_link['href']
@@ -67,7 +69,7 @@ class Vreme(BasicNewsRecipe):
,'url' :url
,'description':description
})
- return [(soup.head.title.string, articles)]
+ return [('Nedeljnik Vreme', articles)]
remove_tags = [
dict(name=['object','link'])
@@ -76,11 +78,3 @@ class Vreme(BasicNewsRecipe):
def print_version(self, url):
return url + '&print=yes'
-
- def get_cover_url(self):
- cover_url = None
- soup = self.index_to_soup(self.INDEX)
- cover_item = soup.find('div',attrs={'id':'najava'})
- if cover_item:
- cover_url = self.INDEX + cover_item.img['src']
- return cover_url
diff --git a/src/calibre/devices/prs505/driver.py b/src/calibre/devices/prs505/driver.py
index bd06d2d7e1..5a820b3ed8 100644
--- a/src/calibre/devices/prs505/driver.py
+++ b/src/calibre/devices/prs505/driver.py
@@ -6,8 +6,7 @@ __docformat__ = 'restructuredtext en'
Device driver for the SONY devices
'''
-import os
-import re
+import os, time, re
from calibre.devices.usbms.driver import USBMS
from calibre.devices.prs505 import MEDIA_XML
@@ -66,6 +65,41 @@ class PRS505(USBMS):
def windows_filter_pnp_id(self, pnp_id):
return '_LAUNCHER' in pnp_id
+ def post_open_callback(self):
+
+ def write_cache(prefix):
+ try:
+ cachep = os.path.join(prefix, *(CACHE_XML.split('/')))
+ if not os.path.exists(cachep):
+ dname = os.path.dirname(cachep)
+ if not os.path.exists(dname):
+ try:
+ os.makedirs(dname, mode=0777)
+ except:
+ time.sleep(5)
+ os.makedirs(dname, mode=0777)
+ with open(cachep, 'wb') as f:
+ f.write(u'''
+
+
+ '''.encode('utf8'))
+ return True
+ except:
+ import traceback
+ traceback.print_exc()
+ return False
+
+ # Make sure we don't have the launcher partition
+ # as one of the cards
+
+ if self._card_a_prefix is not None:
+ if not write_cache(self._card_a_prefix):
+ self._card_a_prefix = None
+ if self._card_b_prefix is not None:
+ if not write_cache(self._card_b_prefix):
+ self._card_b_prefix = None
+
+
def get_device_information(self, end_session=True):
return (self.gui_name, '', '', '')
diff --git a/src/calibre/devices/prs505/sony_cache.py b/src/calibre/devices/prs505/sony_cache.py
index 177a741e0d..0292a275d7 100644
--- a/src/calibre/devices/prs505/sony_cache.py
+++ b/src/calibre/devices/prs505/sony_cache.py
@@ -415,10 +415,11 @@ class XMLCache(object):
prints('\tmtime', strftime(os.path.getmtime(path)))
record.set('date', date)
record.set('size', str(os.stat(path).st_size))
- record.set('title', book.title)
+ title = book.title if book.title else _('Unknown')
+ record.set('title', title)
ts = book.title_sort
if not ts:
- ts = title_sort(book.title)
+ ts = title_sort(title)
record.set('titleSorter', ts)
record.set('author', authors_to_string(book.authors))
ext = os.path.splitext(path)[1]
diff --git a/src/calibre/gui2/main.py b/src/calibre/gui2/main.py
index 29ae1875c8..ba40c0c92b 100644
--- a/src/calibre/gui2/main.py
+++ b/src/calibre/gui2/main.py
@@ -226,7 +226,7 @@ class GuiRunner(QObject):
self.splash_pixmap = QPixmap()
self.splash_pixmap.load(I('library.png'))
self.splash_screen = QSplashScreen(self.splash_pixmap,
- Qt.SplashScreen|Qt.WindowStaysOnTopHint)
+ Qt.SplashScreen)
self.splash_screen.showMessage(_('Starting %s: Loading books...') %
__appname__)
self.splash_screen.show()
diff --git a/src/calibre/gui2/main.ui b/src/calibre/gui2/main.ui
index 8c1d1bf787..1abaf53d3c 100644
--- a/src/calibre/gui2/main.ui
+++ b/src/calibre/gui2/main.ui
@@ -28,7 +28,7 @@
:/images/library.png:/images/library.png
-
+
-
-
@@ -305,78 +305,79 @@
-
-
-
-
-
-
-
- 0
- 100
-
-
-
- Qt::Vertical
-
-
-
-
- 100
- 100
-
-
-
- 0
-
-
-
-
-
-
-
- Qt::Horizontal
-
-
-
-
-
-
-
- true
-
-
- true
-
-
- true
-
-
- true
-
-
-
- -
+
+
+
+ 0
+ 100
+
+
+
+ Qt::Vertical
+
+
+
+
-
+
+
+
+ 100
+ 100
+
+
+
+ 0
+
+
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+
-
+
+
+ true
+
+
+ true
+
+
+ true
+
+
+ true
+
+
+
+ -
Sort by &popularity
-
- -
-
-
- 0
-
-
-
-
- Match any
+
+ -
+
+
+ 0
-
- -
-
- Match all
-
-
-
-
- -
+
-
+
+ Match any
+
+
+ -
+
+ Match all
+
+
+
+
+ -
Create, edit, and delete user categories
@@ -385,10 +386,49 @@
Manage &user categories
-
-
+
+
+
+
+
+
+ 100
+ 10
+
+
+
+ true
+
+
+ true
+
+
+ false
+
+
+ QAbstractItemView::DragDrop
+
+
+ true
+
+
+ QAbstractItemView::SelectRows
+
+
+ false
+
+
+ false
+
+
-
+
+
+
+
+
+ -
+
100
@@ -420,139 +460,107 @@
false
-
-
-
+
+
+
+
+
+ -
+
+
+
+ 10
+ 10
+
+
+
+ true
+
+
+ true
+
+
+ false
+
+
+ QAbstractItemView::DragDrop
+
+
+ true
+
+
+ QAbstractItemView::SelectRows
+
+
+ false
+
+
+ false
+
+
+
+
+
+
+
+ -
+
+
+
+ 10
+ 10
+
+
+
+ true
+
+
+ true
+
+
+ false
+
+
+ QAbstractItemView::DragDrop
+
+
+ true
+
+
+ QAbstractItemView::SelectRows
+
+
+ false
+
+
+ false
+
+
+
+
+
-
-
- -
-
-
-
- 100
- 10
-
-
-
- true
-
-
- true
-
-
- false
-
-
- QAbstractItemView::DragDrop
-
-
- true
-
-
- QAbstractItemView::SelectRows
-
-
- false
-
-
- false
-
-
-
-
+
+ -
+
-
-
-
-
-
-
-
- 10
- 10
-
-
-
- true
-
-
- true
-
-
- false
-
-
- QAbstractItemView::DragDrop
-
-
- true
-
-
- QAbstractItemView::SelectRows
-
-
- false
-
-
- false
-
-
-
-
-
-
-
- -
-
-
-
- 10
- 10
-
-
-
- true
-
-
- true
-
-
- false
-
-
- QAbstractItemView::DragDrop
-
-
- true
-
-
- QAbstractItemView::SelectRows
-
-
- false
-
-
- false
-
-
-
-
-
-
-
-
-
- -
-
-
-
+
+
+
+
+
diff --git a/src/calibre/library/database2.py b/src/calibre/library/database2.py
index 29e1901ce2..f1eeb23643 100644
--- a/src/calibre/library/database2.py
+++ b/src/calibre/library/database2.py
@@ -9,12 +9,6 @@ The database used to store ebook metadata
import os, sys, shutil, cStringIO, glob,functools, traceback
from itertools import repeat
from math import floor
-try:
- from PIL import Image as PILImage
- PILImage
-except ImportError:
- import Image as PILImage
-
from PyQt4.QtGui import QImage
@@ -37,7 +31,7 @@ from calibre.utils.date import utcnow, now as nowf, utcfromtimestamp
from calibre.utils.config import prefs
from calibre.utils.search_query_parser import saved_searches
from calibre.ebooks import BOOK_EXTENSIONS, check_ebook_format
-
+from calibre.utils.magick_draw import save_cover_data_to
if iswindows:
import calibre.utils.winshell as winshell
@@ -475,11 +469,9 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
if callable(getattr(data, 'save', None)):
data.save(path)
else:
- f = data
- if not callable(getattr(data, 'read', None)):
- f = cStringIO.StringIO(data)
- im = PILImage.open(f)
- im.convert('RGB').save(path, 'JPEG')
+ if callable(getattr(data, 'read', None)):
+ data = data.read()
+ save_cover_data_to(data, path)
def book_on_device(self, id):
if callable(self.book_on_device_func):
diff --git a/src/calibre/library/server/content.py b/src/calibre/library/server/content.py
index 12bd786322..4dd32eb284 100644
--- a/src/calibre/library/server/content.py
+++ b/src/calibre/library/server/content.py
@@ -127,10 +127,7 @@ class ContentServer(object):
cherrypy.log('User agent: '+ua)
if want_opds:
- return self.stanza(search=kwargs.get('search', None), sortby=kwargs.get('sortby',None), authorid=kwargs.get('authorid',None),
- tagid=kwargs.get('tagid',None),
- seriesid=kwargs.get('seriesid',None),
- offset=kwargs.get('offset', 0))
+ return self.opds(version=0)
if want_mobile:
return self.mobile()
diff --git a/src/calibre/manual/faq.rst b/src/calibre/manual/faq.rst
index 99afc32b18..833d99f28e 100644
--- a/src/calibre/manual/faq.rst
+++ b/src/calibre/manual/faq.rst
@@ -157,7 +157,9 @@ If you get timeout errors while browsing the calibre catalog in Stanza, try incr
Alternative for the iPad
^^^^^^^^^^^^^^^^^^^^^^^^^^^
-As of |app| version 0.7.0, on windows and OS X you can plugin your iPad into the computer using its charging cable, and |app| will detect it and show you a list of books on the iPad. You can then use the Send to device button to send books directly to iBooks on the iPad.
+As of |app| version 0.7.0, you can plugin your iPad into the computer using its charging cable, and |app| will detect it and show you a list of books on the iPad. You can then use the Send to device button to send books directly to iBooks on the iPad.
+
+This method only works on Windows XP and higher and OS X 10.5 and higher. Linux is not supported (iTunes is not available in linux) and OS X 10.4 is not supported.
How do I use |app| with my Android phone?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/src/calibre/utils/magick_draw.py b/src/calibre/utils/magick_draw.py
index aeb5bb2268..c4a6c1d76e 100644
--- a/src/calibre/utils/magick_draw.py
+++ b/src/calibre/utils/magick_draw.py
@@ -212,6 +212,23 @@ def create_cover_page(top_lines, logo_path, width=590, height=750,
p.DestroyMagickWand(canvas)
return ans
+def save_cover_data_to(data, path, bgcolor='white'):
+ '''
+ Saves image in data to path, in the format specified by the path
+ extension. Composes the image onto a blank cancas so as to
+ properly convert transparent images.
+ '''
+ with open(path, 'wb') as f:
+ f.write(data)
+ with p.ImageMagick():
+ img = load_image(path)
+ canvas = create_canvas(p.MagickGetImageWidth(img),
+ p.MagickGetImageHeight(img), bgcolor)
+ compose_image(canvas, img, 0, 0)
+ p.MagickWriteImage(canvas, path)
+ p.DestroyMagickWand(img)
+ p.DestroyMagickWand(canvas)
+
def test():
import subprocess
with TemporaryFile('.png') as f:
diff --git a/src/calibre/web/feeds/__init__.py b/src/calibre/web/feeds/__init__.py
index bcb8c2d74f..da7122c491 100644
--- a/src/calibre/web/feeds/__init__.py
+++ b/src/calibre/web/feeds/__init__.py
@@ -11,7 +11,7 @@ from lxml import html
from calibre.web.feeds.feedparser import parse
from calibre.utils.logging import default_log
-from calibre import entity_to_unicode
+from calibre import entity_to_unicode, strftime
from calibre.utils.date import dt_factory, utcnow, local_tz
class Article(object):
@@ -53,12 +53,17 @@ class Article(object):
@dynamic_property
def formatted_date(self):
+
def fget(self):
if self._formatted_date is None:
- self._formatted_date = self.localtime.strftime(" [%a, %d %b %H:%M]")
+ self._formatted_date = strftime(" [%a, %d %b %H:%M]",
+ t=self.localtime.timetuple())
return self._formatted_date
+
def fset(self, val):
- self._formatted_date = val
+ if isinstance(val, unicode):
+ self._formatted_date = val
+
return property(fget=fget, fset=fset)
@dynamic_property