mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-07 10:14:46 -04:00
Sync to trunk
This commit is contained in:
commit
6f6fb1b1e8
@ -2,7 +2,7 @@ __license__ = 'GPL v3'
|
||||
__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
__appname__ = 'calibre'
|
||||
__version__ = '0.4.126'
|
||||
__version__ = '0.4.127'
|
||||
__author__ = "Kovid Goyal <kovid@kovidgoyal.net>"
|
||||
'''
|
||||
Various run time constants.
|
||||
|
@ -41,6 +41,20 @@ class Device(object):
|
||||
'''Return the FDI description of this device for HAL on linux.'''
|
||||
return ''
|
||||
|
||||
@classmethod
|
||||
def can_handle(cls, device_info):
|
||||
'''
|
||||
Optional method to perform further checks on a device to see if this driver
|
||||
is capable of handling it. If it is not it should return False. This method
|
||||
is only called after the vendor, product ids and the bcd have matched, so
|
||||
it can do some relatively time intensive checks. The default implementation
|
||||
returns True.
|
||||
|
||||
:param device_info: On windows a device ID string. On Unix a tuple of
|
||||
``(vendor_id, product_id, bcd)``.
|
||||
'''
|
||||
return True
|
||||
|
||||
def open(self):
|
||||
'''
|
||||
Perform any device specific initialization. Called after the device is
|
||||
|
@ -63,11 +63,13 @@ class DeviceScanner(object):
|
||||
for device_id in self.devices:
|
||||
if vid in device_id and pid in device_id:
|
||||
if self.test_bcd_windows(device_id, getattr(device, 'BCD', None)):
|
||||
if device.can_handle(device_id):
|
||||
return True
|
||||
else:
|
||||
for vendor, product, bcdDevice in self.devices:
|
||||
if device.VENDOR_ID == vendor and device.PRODUCT_ID == product:
|
||||
if self.test_bcd(bcdDevice, getattr(device, 'BCD', None)):
|
||||
if device.can_handle((vendor, product, bcdDevice)):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
@ -67,6 +67,7 @@ def txt2opf(path, tdir, opts):
|
||||
def pdf2opf(path, tdir, opts):
|
||||
from calibre.ebooks.lrf.pdf.convert_from import generate_html
|
||||
generate_html(path, tdir)
|
||||
opts.dont_split_on_page_breaks = True
|
||||
return os.path.join(tdir, 'metadata.opf')
|
||||
|
||||
def epub2opf(path, tdir, opts):
|
||||
|
@ -560,7 +560,7 @@ class Processor(Parser):
|
||||
hr = etree.Element('hr')
|
||||
if elem.getprevious() is None:
|
||||
elem.getparent()[:0] = [hr]
|
||||
else:
|
||||
elif elem.getparent() is not None:
|
||||
insert = None
|
||||
for i, c in enumerate(elem.getparent()):
|
||||
if c is elem:
|
||||
@ -796,7 +796,18 @@ class Processor(Parser):
|
||||
setting = ''
|
||||
face = font.attrib.pop('face', None)
|
||||
if face is not None:
|
||||
setting += 'font-face:%s;'%face
|
||||
faces = []
|
||||
for face in face.split(','):
|
||||
if ' ' in face:
|
||||
face = "%s" % face
|
||||
faces.append(face)
|
||||
for generic in ('serif', 'sans-serif', 'monospace'):
|
||||
if generic in faces:
|
||||
break
|
||||
else:
|
||||
faces.append('serif')
|
||||
family = ', '.join(faces)
|
||||
setting += 'font-family: %s;' % family
|
||||
color = font.attrib.pop('color', None)
|
||||
if color is not None:
|
||||
setting += 'color:%s'%color
|
||||
|
@ -425,7 +425,7 @@ def do_convert(path_to_file, opts, notification=lambda m, p: p, output_format='l
|
||||
thumbnail = None
|
||||
if not pages:
|
||||
raise ValueError('Could not find any pages in the comic: %s'%source)
|
||||
if not opts.no_process:
|
||||
if not getattr(opts, 'no_process', False):
|
||||
pages, failures, tdir2 = process_pages(pages, opts, notification)
|
||||
if not pages:
|
||||
raise ValueError('Could not find any valid pages in the comic: %s'%source)
|
||||
|
@ -29,7 +29,7 @@ def config(defaults=None):
|
||||
c.add_opt('top_right_y', [ '-w', '--righty'], default=default_crop,
|
||||
help=_('Number of pixels to crop from the right most y (default is %d)')%default_crop )
|
||||
c.add_opt('bounding', ['-b', '--bounding'],
|
||||
help=_('A file generated by ghostscript which allows each page to be individually cropped'))
|
||||
help=_('A file generated by ghostscript which allows each page to be individually cropped [gs -dSAFER -dNOPAUSE -dBATCH -sDEVICE=bbox > bounding] '))
|
||||
return c
|
||||
|
||||
|
||||
@ -38,14 +38,24 @@ def option_parser():
|
||||
return c.option_parser(usage=_('''\
|
||||
%prog [options] file.pdf
|
||||
|
||||
Crop a pdf.
|
||||
Crops a pdf.
|
||||
'''))
|
||||
|
||||
def main(args=sys.argv):
|
||||
parser = option_parser()
|
||||
opts, args = parser.parse_args(args)
|
||||
try:
|
||||
source = os.path.abspath(args[1])
|
||||
input_pdf = PdfFileReader(file(source, "rb"))
|
||||
except:
|
||||
print "Unable to read input"
|
||||
return 2
|
||||
info = input_pdf.getDocumentInfo()
|
||||
title = 'Unknown'
|
||||
author = 'Unknown'
|
||||
if info.title:
|
||||
title = info.title
|
||||
author = info.author
|
||||
if opts.bounding != None:
|
||||
try:
|
||||
bounding = open( opts.bounding , 'r' )
|
||||
@ -53,7 +63,7 @@ def main(args=sys.argv):
|
||||
except:
|
||||
print 'Error opening %s' % opts.bounding
|
||||
return 1
|
||||
output_pdf = PdfFileWriter()
|
||||
output_pdf = PdfFileWriter(title=title,author=author)
|
||||
for page_number in range (0, input_pdf.getNumPages() ):
|
||||
page = input_pdf.getPage(page_number)
|
||||
if opts.bounding != None:
|
||||
|
@ -75,7 +75,13 @@ def save_recipes(recipes):
|
||||
|
||||
def load_recipes():
|
||||
config.refresh()
|
||||
return [Recipe().unpickle(r) for r in config.get('scheduled_recipes', [])]
|
||||
recipes = []
|
||||
for r in config.get('scheduled_recipes', []):
|
||||
r = Recipe().unpickle(r)
|
||||
if r.builtin and not str(r.id).startswith('recipe_'):
|
||||
continue
|
||||
recipes.append(r)
|
||||
return recipes
|
||||
|
||||
class RecipeModel(QAbstractListModel, SearchQueryParser):
|
||||
|
||||
@ -438,7 +444,7 @@ class Scheduler(QObject):
|
||||
self.lock.unlock()
|
||||
|
||||
def main(args=sys.argv):
|
||||
app = QApplication([])
|
||||
QApplication([])
|
||||
from calibre.library.database2 import LibraryDatabase2
|
||||
d = SchedulerDialog(LibraryDatabase2('/home/kovid/documents/library'))
|
||||
d.exec_()
|
||||
|
BIN
src/calibre/gui2/images/news/telepolis.png
Normal file
BIN
src/calibre/gui2/images/news/telepolis.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 586 B |
@ -217,8 +217,7 @@ class Server(object):
|
||||
pos = pos.replace(month = 1)
|
||||
else:
|
||||
pos = pos.replace(month = pos.month + 1)
|
||||
|
||||
_months = list(months(self.earliest, self.latest))[:-1][:12]
|
||||
_months = list(months(self.earliest, self.latest))[:-1][-12:]
|
||||
_months = [range_for_month(*m) for m in _months]
|
||||
_months = [self.get_slice(*m) for m in _months]
|
||||
x = [m.min for m in _months]
|
||||
|
@ -35,7 +35,7 @@ class Distribution(object):
|
||||
('xdg-utils', '1.0.2', 'xdg-utils', 'xdg-utils', 'xdg-utils'),
|
||||
('dbus-python', '0.82.2', 'dbus-python', 'python-dbus', 'dbus-python'),
|
||||
('lxml', '2.0.5', 'lxml', 'python-lxml', 'python-lxml'),
|
||||
('BeautifulSoup', '3.0.5', 'beautifulsoup', 'python-beautifulsoup', 'python-beautifulsoup'),
|
||||
('BeautifulSoup', '3.0.5', 'beautifulsoup', 'python-beautifulsoup', 'python-BeautifulSoup'),
|
||||
('help2man', '1.36.4', 'help2man', 'help2man', 'help2man'),
|
||||
]
|
||||
|
||||
|
@ -765,6 +765,8 @@ class BasicNewsRecipe(object, LoggingInterface):
|
||||
self.log_debug(traceback.format_exc())
|
||||
if cu is not None:
|
||||
ext = cu.rpartition('.')[-1]
|
||||
if '?' in ext:
|
||||
ext = ''
|
||||
ext = ext.lower() if ext else 'jpg'
|
||||
self.report_progress(1, _('Downloading cover from %s')%cu)
|
||||
cpath = os.path.join(self.output_dir, 'cover.'+ext)
|
||||
|
@ -21,7 +21,7 @@ recipe_modules = ['recipe_' + r for r in (
|
||||
'linux_magazine', 'telegraph_uk', 'utne', 'sciencedaily', 'forbes',
|
||||
'time_magazine', 'endgadget', 'fudzilla', 'nspm_int', 'nspm', 'pescanik',
|
||||
'spiegel_int', 'themarketticker', 'tomshardware', 'xkcd', 'ftd', 'zdnet',
|
||||
'joelonsoftware',
|
||||
'joelonsoftware', 'telepolis', 'common_dreams',
|
||||
)]
|
||||
|
||||
import re, imp, inspect, time, os
|
||||
|
@ -42,3 +42,9 @@ class ChristianScienceMonitor(BasicNewsRecipe):
|
||||
feeds[-1][1].append(art)
|
||||
return feeds
|
||||
|
||||
def postprocess_html(self, soup, first_fetch):
|
||||
html = soup.find('html')
|
||||
if html is None:
|
||||
return soup
|
||||
html.extract()
|
||||
return html
|
||||
|
16
src/calibre/web/feeds/recipes/recipe_common_dreams.py
Normal file
16
src/calibre/web/feeds/recipes/recipe_common_dreams.py
Normal file
@ -0,0 +1,16 @@
|
||||
|
||||
from calibre.web.feeds.news import BasicNewsRecipe
|
||||
|
||||
class CommonDreams(BasicNewsRecipe):
|
||||
title = u'Common Dreams'
|
||||
description = u'Progressive news and views'
|
||||
__author__ = u'XanthanGum'
|
||||
oldest_article = 7
|
||||
max_articles_per_feed = 100
|
||||
|
||||
feeds = [
|
||||
(u'Common Dreams Headlines',
|
||||
u'http://www.commondreams.org/feed/headlines_rss'),
|
||||
(u'Common Dreams Views', u'http://www.commondreams.org/feed/views_rss'),
|
||||
(u'Common Dreams Newswire', u'http://www.commondreams.org/feed/newswire_rss')
|
||||
]
|
@ -49,7 +49,9 @@ class Economist(BasicNewsRecipe):
|
||||
if not index_started:
|
||||
continue
|
||||
text = string.capwords(text)
|
||||
if text not in feeds.keys():
|
||||
feeds[text] = []
|
||||
if text not in ans:
|
||||
ans.append(text)
|
||||
key = text
|
||||
continue
|
||||
|
34
src/calibre/web/feeds/recipes/recipe_telepolis.py
Normal file
34
src/calibre/web/feeds/recipes/recipe_telepolis.py
Normal file
@ -0,0 +1,34 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
__license__ = 'GPL v3'
|
||||
__copyright__ = '2008, Darko Miletic <darko.miletic at gmail.com>'
|
||||
'''
|
||||
www.heise.de/tp
|
||||
'''
|
||||
|
||||
from calibre.web.feeds.news import BasicNewsRecipe
|
||||
|
||||
class Telepolis(BasicNewsRecipe):
|
||||
title = 'Telepolis'
|
||||
__author__ = 'Darko Miletic'
|
||||
description = 'News from Germany in German'
|
||||
oldest_article = 2
|
||||
max_articles_per_feed = 100
|
||||
no_stylesheets = True
|
||||
use_embedded_content = False
|
||||
encoding = 'utf-8'
|
||||
|
||||
html2lrf_options = [ '--comment' , description
|
||||
, '--category' , 'blog,news'
|
||||
]
|
||||
|
||||
keep_only_tags = [
|
||||
dict(name='table', attrs={'class':'inhalt-table'})
|
||||
,dict(name='table', attrs={'class':'blogtable' })
|
||||
]
|
||||
remove_tags = [
|
||||
dict(name='table', attrs={'class':'img' })
|
||||
,dict(name='img' , attrs={'src':'/tp/r4/icons/inline/extlink.gif'})
|
||||
]
|
||||
|
||||
feeds = [(u'Telepolis Newsfeed', u'http://www.heise.de/tp/news.rdf')]
|
@ -33,6 +33,7 @@ class TimesOnline(BasicNewsRecipe):
|
||||
('Sports News', 'http://www.timesonline.co.uk/tol/feeds/rss/sport.xml'),
|
||||
('Film News', 'http://www.timesonline.co.uk/tol/feeds/rss/film.xml'),
|
||||
('Tech news', 'http://www.timesonline.co.uk/tol/feeds/rss/tech.xml'),
|
||||
('Literary Supplement', 'http://www.timesonline.co.uk/tol/feeds/rss/thetls.xml'),
|
||||
]
|
||||
|
||||
def print_version(self, url):
|
||||
|
@ -55,7 +55,7 @@ from utils import readNonWhitespace, readUntilWhitespace, ConvertFunctionsToVirt
|
||||
# This class supports writing PDF files out, given pages produced by another
|
||||
# class (typically {@link #PdfFileReader PdfFileReader}).
|
||||
class PdfFileWriter(object):
|
||||
def __init__(self):
|
||||
def __init__(self,title=u"Unknown",author=u"Unknown"):
|
||||
self._header = "%PDF-1.3"
|
||||
self._objects = [] # array of indirect objects
|
||||
|
||||
@ -71,7 +71,9 @@ class PdfFileWriter(object):
|
||||
# info object
|
||||
info = DictionaryObject()
|
||||
info.update({
|
||||
NameObject("/Producer"): createStringObject(u"Python PDF Library - http://pybrary.net/pyPdf/")
|
||||
NameObject("/Producer"): createStringObject(u"Python PDF Library - http://pybrary.net/pyPdf/"),
|
||||
NameObject("/Author"): createStringObject(author),
|
||||
NameObject("/Title"): createStringObject(title),
|
||||
})
|
||||
self._info = self._addObject(info)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user