Upgrade python error checker to use pyflakes 0.4 and fix te new errors found by it

This commit is contained in:
Kovid Goyal 2009-12-01 17:57:49 +00:00
parent c1bad65f7f
commit 1327e15337
53 changed files with 163 additions and 901 deletions

View File

@ -11,7 +11,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
class ChicagoBreakingNews(BasicNewsRecipe):
title = 'Chicago Breaking News'
__author__ = 'Darko Miletic'
description = 'Breaking News from Chicago'
description = 'Breaking News from Chicago'
oldest_article = 1
max_articles_per_feed = 100
no_stylesheets = True
@ -21,19 +21,18 @@ class ChicagoBreakingNews(BasicNewsRecipe):
encoding = 'utf8'
language = 'en'
html2lrf_options = [
'--comment', description
, '--category', category
, '--publisher', publisher
]
html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"'
html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"'
feeds = [(u'Breaking news', u'http://feeds2.feedburner.com/ChicagoBreakingNews/')]
def preprocess_html(self, soup):
links = soup.findAll('a')
for item in soup.findAll('a'):
if item['href'].find('http://feedads.googleadservices.com') > -1:
item.extract()

View File

@ -80,7 +80,6 @@ class GlasSrpske(BasicNewsRecipe):
for item in soup.findAll('div', attrs={'class':'gl_rub'}):
atag = item.find('a')
ptag = item.find('p')
datetag = item.find('span')
url = self.INDEX + atag['href']
title = self.tag_to_string(atag)
description = self.tag_to_string(ptag)

View File

@ -147,7 +147,6 @@ class NYTimes(BasicNewsRecipe):
# Fetch the outer table
table = soup.find('table')
previousTable = table
contentTable = None
# Find the deepest table containing the stories
while True :

View File

@ -53,8 +53,8 @@ class NYTimes(BasicNewsRecipe):
articles = {}
key = None
ans = []
allSectionKeywords = ['The Front Page', 'International','National','Obituaries','Editorials',
'New York','Business Day','Sports','Dining','Arts','Home','Styles']
#allSectionKeywords = ['The Front Page', 'International','National','Obituaries','Editorials',
#'New York','Business Day','Sports','Dining','Arts','Home','Styles']
excludeSectionKeywords = ['Dining','Styles']

View File

@ -71,7 +71,6 @@ class ScientificAmerican(BasicNewsRecipe):
feeds.append(('Features', features))
section = []
found = []
title = None
for x in soup.find(id='magazine-main_col1').findAll(['div', 'a']):

View File

@ -72,7 +72,6 @@ class Time(BasicNewsRecipe):
return feeds
def find_articles(self, seched):
articles = []
for a in seched.findNextSiblings( attrs={'class':['toc_hed','rule2']}):
if a.name in "div":
break

View File

@ -1,76 +1,76 @@
from calibre.web.feeds.news import BasicNewsRecipe
from calibre.ebooks.BeautifulSoup import Tag
class VrijNederlandRecipe(BasicNewsRecipe) :
__license__ = 'GPL v3'
__author__ = 'kwetal'
language = 'nl_NL'
locale = 'nl_NL'
version = 1
title = u'Vrij Nederland'
publisher = u'Weekbladpers Tijdschriften'
category = u'News, Opinion'
description = u'Weekly opinion magazine from the Netherlands'
oldest_article = 7
max_articles_per_feed = 100
use_embedded_content = False
no_stylesheets = True
remove_javascript = True
# Does not seem to work
#extra_css = '''li.calibre2 {padding-bottom: 40px}'''
conversion_options = {'publisher': publisher, 'tags': category, 'comments': description}
feeds = []
feeds.append((u'Politiek', u'http://www.vn.nl/politiek.rss'))
feeds.append((u'Buitenland', u'http://www.vn.nl/buitenland.rss'))
feeds.append((u'Economie', u'http://www.vn.nl/economie.rss'))
feeds.append((u'Justitie', u'http://www.vn.nl/justitie.rss'))
feeds.append((u'Samenleving', u'http://www.vn.nl/samenleving.rss'))
feeds.append((u'Crime', u'http://www.vn.nl/crime.rss'))
feeds.append((u'Media', u'http://www.vn.nl/media.rss'))
feeds.append((u'De Republiek der Letteren', u'http://www.vn.nl/republiek.rss'))
feeds.append((u'Max van Weezel', u'http://www.vn.nl/vanweezel.rss'))
feeds.append((u'Ko Colijn', u'http://www.vn.nl/colijn.rss'))
feeds.append((u'Kees Kraaijeveld', u'http://www.vn.nl/kraaijeveld.rss'))
feeds.append((u'Frank Kalshoven', u'http://www.vn.nl/kalshoven.rss'))
feeds.append((u'Stephan Sanders', u'http://www.vn.nl/sanders.rss'))
feeds.append((u'Micha Wertheim', u'http://www.vn.nl/wertheim.rss'))
feeds.append((u'Arnon Grunberg', u'http://www.vn.nl/grunberg.rss'))
feeds.append((u'Carel Peeters', u'http://www.vn.nl/carelpeeters.rss'))
keep_only_tags = [dict(name = 'div', attrs = {'class' : 'cl-column column-one'})]
remove_tags = []
remove_tags.append(dict(name = 'div', attrs = {'class' : 'wpg-element guest-book-overview'}))
remove_tags.append(dict(name = 'div', attrs = {'class' : 'wpg-element forum-message-form'}))
remove_tags.append(dict(name = 'div', attrs = {'class' : 'mediaterms'}))
remove_tags.append(dict(name = 'div', attrs = {'class': 'label-term'}))
remove_tags.append(dict(name = 'div', attrs = {'class': 'wpg-element Media-Collection-Element-Artikel-Lijst'}))
remove_tags.append(dict(name = 'object'))
remove_tags.append(dict(name = 'link'))
remove_tags.append(dict(name = 'meta'))
def preprocess_html(self, soup):
# Just clean up the result a little
meta = soup.find('div', attrs = {'class': 'meta'})
if meta:
link = meta.find('span', attrs = {'class': 'link'})
if link:
link.extract()
for seperator in meta.findAll('span', attrs = {'class': 'seperator'}):
seperator.extract()
# Their header is full of 'if IE6/7/8' tags. Just get rid of it altogether
theirHead = soup.head
theirHead.extract()
myHead = Tag(soup, 'head')
soup.insert(0, myHead)
return soup
from calibre.web.feeds.news import BasicNewsRecipe
from calibre.ebooks.BeautifulSoup import Tag
class VrijNederlandRecipe(BasicNewsRecipe) :
__license__ = 'GPL v3'
__author__ = 'kwetal'
language = 'nl_NL'
locale = 'nl_NL'
version = 1
title = u'Vrij Nederland'
publisher = u'Weekbladpers Tijdschriften'
category = u'News, Opinion'
description = u'Weekly opinion magazine from the Netherlands'
oldest_article = 7
max_articles_per_feed = 100
use_embedded_content = False
no_stylesheets = True
remove_javascript = True
# Does not seem to work
#extra_css = '''li.calibre2 {padding-bottom: 40px}'''
conversion_options = {'publisher': publisher, 'tags': category, 'comments': description}
feeds = []
feeds.append((u'Politiek', u'http://www.vn.nl/politiek.rss'))
feeds.append((u'Buitenland', u'http://www.vn.nl/buitenland.rss'))
feeds.append((u'Economie', u'http://www.vn.nl/economie.rss'))
feeds.append((u'Justitie', u'http://www.vn.nl/justitie.rss'))
feeds.append((u'Samenleving', u'http://www.vn.nl/samenleving.rss'))
feeds.append((u'Crime', u'http://www.vn.nl/crime.rss'))
feeds.append((u'Media', u'http://www.vn.nl/media.rss'))
feeds.append((u'De Republiek der Letteren', u'http://www.vn.nl/republiek.rss'))
feeds.append((u'Max van Weezel', u'http://www.vn.nl/vanweezel.rss'))
feeds.append((u'Ko Colijn', u'http://www.vn.nl/colijn.rss'))
feeds.append((u'Kees Kraaijeveld', u'http://www.vn.nl/kraaijeveld.rss'))
feeds.append((u'Frank Kalshoven', u'http://www.vn.nl/kalshoven.rss'))
feeds.append((u'Stephan Sanders', u'http://www.vn.nl/sanders.rss'))
feeds.append((u'Micha Wertheim', u'http://www.vn.nl/wertheim.rss'))
feeds.append((u'Arnon Grunberg', u'http://www.vn.nl/grunberg.rss'))
feeds.append((u'Carel Peeters', u'http://www.vn.nl/carelpeeters.rss'))
keep_only_tags = [dict(name = 'div', attrs = {'class' : 'cl-column column-one'})]
remove_tags = []
remove_tags.append(dict(name = 'div', attrs = {'class' : 'wpg-element guest-book-overview'}))
remove_tags.append(dict(name = 'div', attrs = {'class' : 'wpg-element forum-message-form'}))
remove_tags.append(dict(name = 'div', attrs = {'class' : 'mediaterms'}))
remove_tags.append(dict(name = 'div', attrs = {'class': 'label-term'}))
remove_tags.append(dict(name = 'div', attrs = {'class': 'wpg-element Media-Collection-Element-Artikel-Lijst'}))
remove_tags.append(dict(name = 'object'))
remove_tags.append(dict(name = 'link'))
remove_tags.append(dict(name = 'meta'))
def preprocess_html(self, soup):
# Just clean up the result a little
meta = soup.find('div', attrs = {'class': 'meta'})
if meta:
link = meta.find('span', attrs = {'class': 'link'})
if link:
link.extract()
for seperator in meta.findAll('span', attrs = {'class': 'seperator'}):
seperator.extract()
# Their header is full of 'if IE6/7/8' tags. Just get rid of it altogether
theirHead = soup.head
theirHead.extract()
myHead = Tag(soup, 'head')
soup.insert(0, myHead)
return soup

View File

@ -7,33 +7,57 @@ __copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en'
import sys, os, cPickle, subprocess
from operator import attrgetter
from setup import Command
import __builtin__
def check_for_python_errors(filename, builtins):
from pyflakes import checker, ast
def set_builtins(builtins):
for x in builtins:
if not hasattr(__builtin__, x):
setattr(__builtin__, x, True)
yield x
contents = open(filename, 'rb').read()
class Message:
def __init__(self, filename, lineno, msg):
self.filename, self.lineno, self.msg = filename, lineno, msg
def __str__(self):
return '%s:%s: %s'%(self.filename, self.lineno, self.msg)
def check_for_python_errors(code_string, filename):
# Since compiler.parse does not reliably report syntax errors, use the
# built in compiler first to detect those.
try:
tree = ast.parse(contents, filename)
except:
import traceback
traceback.print_exc()
try:
value = sys.exc_info()[1]
lineno, offset, line = value[1][1:]
except IndexError:
lineno, offset, line = 1, 0, ''
if line.endswith("\n"):
line = line[:-1]
compile(code_string, filename, "exec")
except MemoryError:
# Python 2.4 will raise MemoryError if the source can't be
# decoded.
if sys.version_info[:2] == (2, 4):
raise SyntaxError(None)
raise
except (SyntaxError, IndentationError), value:
msg = value.args[0]
return [SyntaxError(filename, lineno, offset, str(value))]
(lineno, offset, text) = value.lineno, value.offset, value.text
# If there's an encoding problem with the file, the text is None.
if text is None:
# Avoid using msg, since for the only known case, it contains a
# bogus message that claims the encoding the file declared was
# unknown.
msg = "%s: problem decoding source" % filename
return [Message(filename, lineno, msg)]
else:
w = checker.Checker(tree, filename, builtins = builtins)
w.messages.sort(key = attrgetter('lineno'))
return w.messages
# Okay, it's syntactically valid. Now parse it into an ast and check
# it.
import compiler
checker = __import__('pyflakes.checker').checker
tree = compiler.parse(code_string)
w = checker.Checker(tree, filename)
w.messages.sort(lambda a, b: cmp(a.lineno, b.lineno))
return [Message(x.filename, x.lineno, x.message%x.message_args) for x in
w.messages]
class Check(Command):
@ -65,15 +89,18 @@ class Check(Command):
cache = {}
if os.path.exists(self.CACHE):
cache = cPickle.load(open(self.CACHE, 'rb'))
builtins = list(set_builtins(self.BUILTINS))
for f, mtime in self.get_files(cache):
self.info('\tChecking', f)
w = check_for_python_errors(f, self.BUILTINS)
w = check_for_python_errors(open(f, 'rb').read(), f)
if w:
self.report_errors(w)
cPickle.dump(cache, open(self.CACHE, 'wb'), -1)
subprocess.call(['gvim', '-f', f])
raise SystemExit(1)
cache[f] = mtime
for x in builtins:
delattr(__builtin__, x)
cPickle.dump(cache, open(self.CACHE, 'wb'), -1)
wn_path = os.path.expanduser('~/work/servers/src/calibre_servers/main')
if os.path.exists(wn_path):
@ -85,11 +112,5 @@ class Check(Command):
def report_errors(self, errors):
for err in errors:
if isinstance(err, SyntaxError):
print '\t\tSyntax Error'
else:
col = getattr(err, 'col', 0) if getattr(err, 'col', 0) else 0
lineno = err.lineno if err.lineno else 0
self.info('\t\t%d:%d:'%(lineno, col),
err.message%err.message_args)
self.info('\t\t', str(err))

View File

@ -606,7 +606,6 @@ class Device(DeviceConfig, DevicePlugin):
def eject_linux(self):
drives = self.find_device_nodes()
success = False
for drive in drives:
if drive:
cmd = 'calibre-mount-helper'

View File

@ -43,7 +43,6 @@ class FB2Input(InputFormatPlugin):
from calibre.ebooks.oeb.base import XLINK_NS
NAMESPACES = {'f':FB2NS, 'l':XLINK_NS}
log.debug('Parsing XML...')
parser = etree.XMLParser(recover=True, no_network=True)
doc = etree.fromstring(stream.read())
self.extract_embedded_content(doc)
log.debug('Converting XML to HTML...')

View File

@ -106,7 +106,7 @@ def process_file(lrfpath, opts, logger=None):
os.makedirs(opts.out)
document = LRFDocument(open(lrfpath, 'rb'))
conv = LRFConverter(document, opts, logger)
LRFConverter(document, opts, logger)
def main(args=sys.argv):

View File

@ -2207,7 +2207,7 @@ class JumpButton(LrsObject, LrsContainer):
def toElement(self, se):
b = self.lrsObjectElement("Button")
pb = SubElement(b, "PushButton")
jt = SubElement(pb, "JumpTo",
SubElement(pb, "JumpTo",
refpage=str(self.textBlock.parent.objId),
refobj=str(self.textBlock.objId))
return b

View File

@ -323,7 +323,7 @@ class MobiReader(object):
self.log.warning('Malformed markup, parsing using BeautifulSoup')
try:
root = soupparser.fromstring(self.processed_html)
except Exception, err:
except Exception:
self.log.warning('MOBI markup appears to contain random bytes. Stripping.')
self.processed_html = self.remove_random_bytes(self.processed_html)
root = soupparser.fromstring(self.processed_html)

View File

@ -510,7 +510,7 @@ class MobiWriter(object):
self._oeb.log.warning('_generate_flat_indexed_navpoints: Failed to generate index')
# Zero out self._HTMLRecords, return False
self._HTMLRecords = []
last_name = None
#last_name = None
return False
previousOffset = offset
@ -545,7 +545,7 @@ class MobiWriter(object):
if self.opts.verbose > 3 : self._oeb.logger.info(" node %03d: %-15.15s... spans HTML records %03d - %03d \t offset: 0x%06X length: 0x%06X" % \
(myIndex, child.title if child.title.strip() > "" else "(missing)", myStartingRecord, myStartingRecord, offset, length) )
last_name = "%04X" % myIndex
#last_name = "%04X" % myIndex
myIndex += 1
# Successfully parsed the entries
@ -625,7 +625,7 @@ class MobiWriter(object):
self._oeb.log.warning('_generate_indexed_navpoints: Failed to generate index')
# Zero out self._HTMLRecords, return False
self._HTMLRecords = []
last_name = None
#last_name = None
return False
previousOffset = offset
@ -659,7 +659,7 @@ class MobiWriter(object):
# *** This should check currentSectionNumber, because content could start late
if thisRecord > 0:
sectionChangesInThisRecord = True
sectionChangesInRecordNumber = thisRecord
#sectionChangesInRecordNumber = thisRecord
self._currentSectionIndex += 1
self._HTMLRecords[thisRecord].nextSectionNumber = self._currentSectionIndex
# The following node opens the nextSection
@ -717,7 +717,7 @@ class MobiWriter(object):
if self.opts.verbose > 3 : self._oeb.logger.info(" node: %03d %-10.10s %-15.15s... spans HTML records %03d-%03d \t offset: 0x%06X length: 0x%06X" % \
(myIndex, self._ctoc_map[i]['klass'], child.title if child.title.strip() > "" else "(missing)", thisRecord, thisRecord, offset, length) )
last_name = "%04X" % myIndex
#last_name = "%04X" % myIndex
myIndex += 1
# Successfully parsed the entries
@ -1999,7 +1999,7 @@ class MobiWriter(object):
self._articleCount = 0
self._chapterCount = 0
first = True
#first = True
if self._conforming_periodical_toc :
self._oeb.logger.info('Generating structured CTOC ...')
@ -2007,7 +2007,7 @@ class MobiWriter(object):
if self.opts.verbose > 2 :
self._oeb.logger.info(" %s" % child)
self._add_structured_ctoc_node(child, self._ctoc)
first = False
#first = False
else :
self._oeb.logger.info('Generating flat CTOC ...')
@ -2025,7 +2025,6 @@ class MobiWriter(object):
# Test to see if this child's offset is the same as the previous child's
# offset, skip it
h = child.href
first = False
if h is None:
self._oeb.logger.warn(' Ignoring TOC entry with no href:',
@ -2345,7 +2344,7 @@ class MobiWriter(object):
self._oeb.logger.info( "Writing NCXEntries for mobiType 0x%03X" % myDoc.mobiType)
sectionParent = myDoc.documentStructure.sectionParents[0]
articleCount = len(sectionParent.articles)
#articleCount = len(sectionParent.articles)
# Write opening periodical 0xDF entry
index = 0
@ -2361,7 +2360,7 @@ class MobiWriter(object):
while sectionCount <= lastSection :
# section
sectionParent = myDoc.documentStructure.sectionParents[sectionCount - 1]
articleCount = len(sectionParent.articles)
#articleCount = len(sectionParent.articles)
#index += 1
offset = sectionParent.startAddress
length = sectionParent.sectionLength

View File

@ -168,7 +168,6 @@ class OEBReader(object):
manifest = self.oeb.manifest
known = set(manifest.hrefs)
unchecked = set(manifest.values())
bad = []
while unchecked:
new = set()
for item in unchecked:

View File

@ -103,7 +103,7 @@ def run(opts, pathtopdf, log):
pdfreflow.reflow(data)
index = os.path.join(os.getcwdu(), 'index.xml')
xml = open(index, 'rb').read()
#pdfdoc = PDFDocument(xml, opts, log)
PDFDocument(xml, opts, log)
def option_parser():
from optparse import OptionParser

View File

@ -20,7 +20,7 @@ def is_valid_pdf(pdf_path):
try:
with open(os.path.abspath(pdf_path), 'rb') as pdf_file:
pdf = PdfFileReader(pdf_file)
PdfFileReader(pdf_file)
except:
return False
return True

View File

@ -610,7 +610,6 @@ class DeviceGUI(object):
def emails_sent(self, results, remove=[]):
errors, good = [], []
for jobname, exception, tb in results:
id = jobname.partition(':')[0]
title = jobname.partition(':')[-1]
if exception is not None:
errors.append([title, exception, tb])

View File

@ -135,7 +135,7 @@ class FetchMetadata(QDialog, Ui_FetchMetadata):
set_isbndb_key(key)
else:
key = None
title = author = publisher = isbn = pubdate = None
title = author = publisher = isbn = None
if self.isbn:
isbn = self.isbn
if self.title:

View File

@ -50,7 +50,7 @@ class TagEditor(QDialog, Ui_TagEditor):
confirms, deletes = [], []
items = self.available_tags.selectedItems() if item is None else [item]
if not items:
d = error_dialog(self, 'No tags selected', 'You must select at least one tag from the list of Available tags.').exec_()
error_dialog(self, 'No tags selected', 'You must select at least one tag from the list of Available tags.').exec_()
return
for item in items:
if self.db.is_tag_used(qstring_to_unicode(item.text())):

View File

@ -125,7 +125,6 @@ class JobManager(QAbstractTableModel):
def _update(self):
# Update running time
rows = set([])
for i, j in enumerate(self.jobs):
if j.run_state == j.RUNNING:
idx = self.index(i, 3)

View File

@ -186,7 +186,7 @@ class TextBlock(object):
try:
self.populate(tb.content)
self.end_line()
except TextBlock.HeightExceeded, err:
except TextBlock.HeightExceeded:
pass
#logger.warning('TextBlock height exceeded, skipping line:\n%s'%(err,))

View File

@ -440,7 +440,7 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI):
self.stack.setCurrentIndex(0)
try:
db = LibraryDatabase2(self.library_path)
except Exception, err:
except Exception:
import traceback
error_dialog(self, _('Bad database location'),
_('Bad database location')+':'+self.library_path,
@ -1033,7 +1033,6 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI):
def download_metadata(self, checked, covers=True, set_metadata=True,
set_social_metadata=None):
rows = self.library_view.selectionModel().selectedRows()
previous = self.library_view.currentIndex()
if not rows or len(rows) == 0:
d = error_dialog(self, _('Cannot download metadata'),
_('No books selected'))
@ -1071,7 +1070,7 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI):
x = self._download_book_metadata
self._download_book_metadata = None
if x.exception is None:
db = self.library_view.model().refresh_ids(
self.library_view.model().refresh_ids(
x.updated, cr)
if x.failures:
details = ['%s: %s'%(title, reason) for title,

View File

@ -141,6 +141,7 @@ class TagsModel(QAbstractItemModel):
data=self.categories[i], category_icon=self.cmap[i])
for tag in data[r]:
t = TagTreeItem(parent=c, data=tag, icon_map=self.icon_map)
t
self.db.add_listener(self.database_changed)
self.connect(self, SIGNAL('need_refresh()'), self.refresh,
@ -229,7 +230,6 @@ class TagsModel(QAbstractItemModel):
def reset_all_states(self):
for i in xrange(self.rowCount(QModelIndex())):
category_index = self.index(i, 0, QModelIndex())
category_item = category_index.internalPointer()
for j in xrange(self.rowCount(category_index)):
tag_index = self.index(j, 0, category_index)
tag_item = tag_index.internalPointer()

View File

@ -95,10 +95,6 @@ def convert_single_ebook(parent, db, book_ids, auto_conversion=False, out_format
return jobs, changed, bad
def convert_bulk_ebook(parent, queue, db, book_ids, out_format=None, args=[]):
changed = False
jobs = []
bad = []
total = len(book_ids)
if total == 0:
return None, None, None

View File

@ -437,7 +437,7 @@ def move_library(oldloc, newloc, parent, callback_on_complete):
# Try to load existing library at new location
try:
ndb = LibraryDatabase2(newloc)
LibraryDatabase2(newloc)
except Exception, err:
det = traceback.format_exc()
error_dialog(parent, _('Invalid database'),

View File

@ -889,10 +889,8 @@ class LibraryDatabase2(LibraryDatabase):
def formats(self, index, index_is_id=False):
''' Return available formats as a comma separated list or None if there are no available formats '''
id = index if index_is_id else self.id(index)
path = os.path.join(self.library_path, self.path(id, index_is_id=True))
try:
formats = self.conn.get('SELECT format FROM data WHERE book=?', (id,))
name = self.conn.get('SELECT name FROM data WHERE book=?', (id,), all=False)
formats = map(lambda x:x[0], formats)
except:
return None
@ -910,7 +908,10 @@ class LibraryDatabase2(LibraryDatabase):
def format_abspath(self, index, format, index_is_id=False):
'Return absolute path to the ebook file of format `format`'
id = index if index_is_id else self.id(index)
name = self.conn.get('SELECT name FROM data WHERE book=? AND format=?', (id, format), all=False)
try:
name = self.conn.get('SELECT name FROM data WHERE book=? AND format=?', (id, format), all=False)
except:
return None
if name:
path = os.path.join(self.library_path, self.path(id, index_is_id=True))
format = ('.' + format.lower()) if format else ''
@ -1813,11 +1814,9 @@ books_series_link feeds
else:
actual_formats = [x.lower() for x in actual_formats.split(',')]
mismatch = False
for fmt in formats:
if fmt in actual_formats:
continue
mismatch = True
if id not in bad:
bad[id] = []
bad[id].append(fmt)

View File

@ -636,10 +636,6 @@ class LibraryServer(object):
'type="application/atom+xml" href="/stanza/?%s"/>\n'
) % '&amp;'.join(q)
author_list=[]
tag_list=[]
series_list=[]
for record in nrecord_list:
r = record[FIELD_MAP['formats']]
r = r.upper() if r else ''

View File

@ -388,7 +388,7 @@ class PostInstall:
finally:
os.chdir(cwd)
shutil.rmtree(tdir)
except Exception, err:
except Exception:
if self.opts.fatal_errors:
raise
self.task_failed('Setting up desktop integration failed')

View File

@ -127,7 +127,6 @@ def generate_ebook_convert_help(preamble, info):
input and the output formats, the various combinations are listed below:
''')
sections = []
toc = {}
sec_templ = textwrap.dedent('''\
.. include:: ../global.rst
@ -141,7 +140,6 @@ def generate_ebook_convert_help(preamble, info):
''')
for i, ip in enumerate(input_format_plugins()):
path = os.path.join('cli', 'ebook-convert-%d.rst'%i)
sraw = sec_templ.format(ip.name)
toc[ip.name] = 'ebook-convert-%d'%i
for op in output_format_plugins():

View File

@ -262,7 +262,7 @@ class QtHelpBuilder(StandaloneHTMLBuilder):
shortname = shortname[:-2]
id = '%s.%s' % (id, shortname)
else:
id = descr = None
id = None
if id:
item = ' '*12 + '<keyword name="%s" id="%s" ref="%s"/>' % (

View File

@ -1,80 +0,0 @@
'''
Trac Macro to generate an end use Changelog from the svn logs.
'''
import re, collections, time, os
from bzrlib import log as blog, branch
from cStringIO import StringIO
from trac.wiki.formatter import Formatter
from trac.wiki.macros import WikiMacroBase
from trac.util import Markup
BZR_PATH = '/usr/local/calibre'
class ChangelogFormatter(blog.LogFormatter):
supports_tags = True
supports_merge_revisions = False
_show_advice = False
def __init__(self, num_of_versions=20):
self.num_of_versions = num_of_versions
self.messages = collections.deque()
self.entries = []
self.current_entry = None
def log_revision(self, r):
if len(self.entries) > self.num_of_versions-1:
return
msg = r.rev.message
match = re.match(r'version\s+(\d+\.\d+.\d+)', msg)
if match:
if self.current_entry is not None:
self.entries.append((self.current_entry, set(self.messages)))
timestamp = r.rev.timezone + r.rev.timestamp
self.current_entry = match.group(1) + time.strftime(' (%d %b, %Y)', time.gmtime(timestamp))
self.messages = collections.deque()
else:
if re.search(r'[a-zA-Z]', msg) and len(msg.strip()) > 5:
if 'translation' not in msg and not msg.startswith('IGN'):
self.messages.append(msg.strip())
def to_wiki_txt(self):
txt = ['= Changelog =\n[[PageOutline]]']
for entry in self.entries:
txt.append(u'----\n== Version '+entry[0]+' ==')
if entry[0].strip().startswith('0.6.0'):
txt.append(u'For a list of new features in 0.6.0 see http://calibre.kovidgoyal.net/new_in_6')
else:
for msg in entry[1]:
txt.append(u' * ' + msg)
return (u'\n'.join(txt)).encode('ascii', 'replace')
def bzr_log_to_txt():
path = BZR_PATH
if not os.path.exists(path):
path = '/home/kovid/work/calibre'
b = branch.Branch.open(path)
lf = ChangelogFormatter()
blog.show_log(b, lf)
return lf.to_wiki_txt()
class ChangeLogMacro(WikiMacroBase):
def expand_macro(self, formatter, name, args):
txt = bzr_log_to_txt().encode('ascii', 'xmlcharrefreplace')
out = StringIO()
Formatter(formatter.env, formatter.context).format(txt, out)
return Markup(out.getvalue().decode('utf8'))
if __name__ == '__main__':
print bzr_log_to_txt().encode('utf-8')

View File

@ -1,3 +0,0 @@
__license__ = 'GPL v3'
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'

View File

@ -1,405 +0,0 @@
__license__ = 'GPL v3'
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
__appname__ = 'calibre'
import re, textwrap
DEPENDENCIES = [
#(Generic, version, gentoo, ubuntu, fedora)
('python', '2.6', None, None, None),
('Python Imaging Library', '1.1.6', 'imaging', 'python-imaging', 'python-imaging'),
('libusb', '0.1.12', None, None, None),
('Qt', '4.5.1', 'qt', 'libqt4-core libqt4-gui', 'qt4'),
('PyQt', '4.6.1', 'PyQt4', 'python-qt4', 'PyQt4'),
('python-mechanize', '0.1.11', 'dev-python/mechanize', 'python-mechanize', 'python-mechanize'),
('ImageMagick', '6.3.5', 'imagemagick', 'imagemagick', 'ImageMagick'),
('xdg-utils', '1.0.2', 'xdg-utils', 'xdg-utils', 'xdg-utils'),
('lxml', '2.1.5', 'lxml', 'python-lxml', 'python-lxml'),
('python-dateutil', '1.4.1', 'python-dateutil', 'python-dateutil', 'python-dateutil'),
('BeautifulSoup', '3.0.5', 'beautifulsoup', 'python-beautifulsoup', 'python-BeautifulSoup'),
('dnspython', '1.6.0', 'dnspython', 'dnspython', 'dnspython', 'dnspython'),
('poppler', '0.12.0', 'poppler', 'poppler', 'poppler', 'poppler'),
('podofo', '0.7', 'podofo', 'podofo', 'podofo', 'podofo'),
('libwmf', '0.2.8', 'libwmf', 'libwmf', 'libwmf', 'libwmf'),
]
STATUS = 'http://status.calibre-ebook.com/dist'
class CoolDistro:
def __init__(self, name, title, prefix=''):
self.title = title
url = prefix + '/chrome/dl/images/%s_logo.png'
self.img = url%name
def get_linux_data(version='1.0.0'):
data = {'version':version, 'app':__appname__}
data['title'] = 'Download calibre for linux'
data['supported'] = []
for name, title in [
('debian', 'Debian Sid'),
('exherbo', 'Exherbo'),
('foresight', 'Foresight 2.1'),
('gentoo', 'Gentoo'),
('ubuntu', 'Ubuntu Jaunty Jackalope'),
('linux_mint', 'Linux Mint Gloria'),
]:
data['supported'].append(CoolDistro(name, title,
prefix='http://calibre.kovidgoyal.net'))
data['dependencies'] = DEPENDENCIES
return data
if __name__ == '__main__':
import os
from calibre.utils.genshi.template import MarkupTemplate
import cherrypy
class Test:
def index(self):
raw = open(os.path.dirname(os.path.abspath(__file__))+'/templates/linux.html').read()
return MarkupTemplate(raw).generate(**get_linux_data()).render('xhtml')
index.exposed = True
t = Test()
t.index()
cherrypy.quickstart(t)
else:
from pkg_resources import resource_filename
from trac.core import Component, implements
from trac.web.chrome import INavigationContributor, ITemplateProvider, add_stylesheet
from trac.web.main import IRequestHandler
from trac.util import Markup
DOWNLOAD_DIR = '/var/www/calibre.kovidgoyal.net/htdocs/downloads'
MOBILEREAD = 'https://dev.mobileread.com/dist/kovid/calibre/'
#MOBILEREAD = 'http://calibre.kovidgoyal.net/downloads/'
class OS(dict):
"""Dictionary with a default value for unknown keys."""
def __init__(self, dict):
self.update(dict)
if not dict.has_key('img'):
self['img'] = self['name']
class Download(Component):
implements(INavigationContributor, IRequestHandler, ITemplateProvider)
request_pat = re.compile(r'\/download$|\/download_\S+')
# INavigationContributor methods
def get_active_navigation_item(self, req):
return 'download'
def get_navigation_items(self, req):
yield 'mainnav', 'download', Markup('<a href="/download">Get %s</a>'%(__appname__,))
def get_templates_dirs(self):
return [resource_filename(__name__, 'templates')]
def get_htdocs_dirs(self):
return [('dl', resource_filename(__name__, 'htdocs'))]
# IRequestHandler methods
def match_request(self, req):
return self.__class__.request_pat.match(req.path_info)
def process_request(self, req):
add_stylesheet(req, 'dl/css/download.css')
if req.path_info == '/download':
return self.top_level(req)
elif req.path_info == '/download_linux_binary_installer':
req.send(LINUX_INSTALLER.replace('%version', self.version_from_filename()), 'text/x-python')
else:
match = re.match(r'\/download_(\S+)', req.path_info)
if match:
os = match.group(1)
if os == 'windows':
return self.windows(req)
elif os == 'osx':
return self.osx(req)
elif os == 'linux':
return self.linux(req)
def top_level(self, req):
operating_systems = [
OS({'name' : 'windows', 'title' : 'Windows'}),
OS({'name' : 'osx', 'title' : 'OS X'}),
OS({'name' : 'linux', 'title' : 'Linux'}),
]
data = dict(title='Get ' + __appname__,
operating_systems=operating_systems, width=200,
font_size='xx-large', top_level=True)
return 'download.html', data, None
def version_from_filename(self):
try:
return open(DOWNLOAD_DIR+'/latest_version', 'rb').read().strip()
except:
return '0.0.0'
def windows(self, req):
version = self.version_from_filename()
file = '%s-%s.msi'%(__appname__, version,)
data = dict(version = version, name='windows',
installer_name='Windows installer',
title='Download %s for windows'%(__appname__),
compatibility=('%(a)s works on Windows XP, Vista and 7.'
'If you are upgrading from a version older than 0.6.17, '
'please uninstall %(a)s first.')%dict(a=__appname__,),
path=STATUS+'/win32', app=__appname__,
note=Markup(\
'''
<p>If you are updating from a version of calibre older than 0.6.12 on
<b>Windows XP</b>, first uninstall calibre, then delete the C:\Program
Files\calibre folder (the location may be different if you previously
installed calibre elsewhere) and only then install the new version of
calibre.</p><p><br /></p>
<p>If you are using the <b>SONY PRS-500</b> and %(appname)s does not detect your reader, read on:</p>
<blockquote>
<p>
If you are using 64-bit windows, you're out of luck.
</p>
<p>
There may be a conflict with the USB driver from SONY. In windows, you cannot install two drivers
for one device. In order to resolve the conflict:
<ol>
<li>Start Device Manager by clicking Start->Run, typing devmgmt.msc and pressing enter.</li>
<li>Uninstall all PRS500 related drivers. You will find them in two locations:
<ul>
<li>Under "Libusb-Win32"</li>
<li>Under "Universal Serial ..." (... depends on the version of windows)</li>
</ul>
You can uninstall a driver by right clicking on it and selecting uninstall.
</li>
<li>Once the drivers have been uninstalled, find the file prs500.inf (it will be in the
driver folder in the folder in which you installed %(appname)s. Right click on it and
select Install.</li>
</ol>
</p>
</blockquote>
'''%dict(appname=__appname__)))
return 'binary.html', data, None
def osx(self, req):
version = self.version_from_filename()
file = 'calibre-%s.dmg'%(version,)
data = dict(version = version, name='osx',
installer_name='OS X universal dmg',
title='Download %s for OS X'%(__appname__),
compatibility='%s works on OS X Tiger, Leopard, and Snow Leopard.'%(__appname__,),
path=STATUS+'/osx32', app=__appname__,
note=Markup(\
u'''
<ol>
<li>To install the command line tools, go to Preferences-&gt;Advanced</li>
<li>The app cannot be run from within the dmg. You must drag it to a folder on your filesystem (The Desktop, Applications, wherever).</li>
<li>In order for localization of the user interface in your language, select your language in the preferences (by pressing u\2318+P) and select your language.</li>
</ol>
'''))
return 'binary.html', data, None
def linux(self, req):
data = get_linux_data(version=self.version_from_filename())
return 'linux.html', data, None
LINUX_INSTALLER = textwrap.dedent(r'''
import sys, os, shutil, tarfile, subprocess, tempfile, urllib2, re, stat
MOBILEREAD='https://dev.mobileread.com/dist/kovid/calibre/'
#MOBILEREAD='http://calibre.kovidgoyal.net/downloads/'
class TerminalController:
BOL = '' #: Move the cursor to the beginning of the line
UP = '' #: Move the cursor up one line
DOWN = '' #: Move the cursor down one line
LEFT = '' #: Move the cursor left one char
RIGHT = '' #: Move the cursor right one char
# Deletion:
CLEAR_SCREEN = '' #: Clear the screen and move to home position
CLEAR_EOL = '' #: Clear to the end of the line.
CLEAR_BOL = '' #: Clear to the beginning of the line.
CLEAR_EOS = '' #: Clear to the end of the screen
# Output modes:
BOLD = '' #: Turn on bold mode
BLINK = '' #: Turn on blink mode
DIM = '' #: Turn on half-bright mode
REVERSE = '' #: Turn on reverse-video mode
NORMAL = '' #: Turn off all modes
# Cursor display:
HIDE_CURSOR = '' #: Make the cursor invisible
SHOW_CURSOR = '' #: Make the cursor visible
# Terminal size:
COLS = None #: Width of the terminal (None for unknown)
LINES = None #: Height of the terminal (None for unknown)
# Foreground colors:
BLACK = BLUE = GREEN = CYAN = RED = MAGENTA = YELLOW = WHITE = ''
# Background colors:
BG_BLACK = BG_BLUE = BG_GREEN = BG_CYAN = ''
BG_RED = BG_MAGENTA = BG_YELLOW = BG_WHITE = ''
_STRING_CAPABILITIES = """
BOL=cr UP=cuu1 DOWN=cud1 LEFT=cub1 RIGHT=cuf1
CLEAR_SCREEN=clear CLEAR_EOL=el CLEAR_BOL=el1 CLEAR_EOS=ed BOLD=bold
BLINK=blink DIM=dim REVERSE=rev UNDERLINE=smul NORMAL=sgr0
HIDE_CURSOR=cinvis SHOW_CURSOR=cnorm""".split()
_COLORS = """BLACK BLUE GREEN CYAN RED MAGENTA YELLOW WHITE""".split()
_ANSICOLORS = "BLACK RED GREEN YELLOW BLUE MAGENTA CYAN WHITE".split()
def __init__(self, term_stream=sys.stdout):
# Curses isn't available on all platforms
try: import curses
except: return
# If the stream isn't a tty, then assume it has no capabilities.
if not hasattr(term_stream, 'isatty') or not term_stream.isatty(): return
# Check the terminal type. If we fail, then assume that the
# terminal has no capabilities.
try: curses.setupterm()
except: return
# Look up numeric capabilities.
self.COLS = curses.tigetnum('cols')
self.LINES = curses.tigetnum('lines')
# Look up string capabilities.
for capability in self._STRING_CAPABILITIES:
(attrib, cap_name) = capability.split('=')
setattr(self, attrib, self._tigetstr(cap_name) or '')
# Colors
set_fg = self._tigetstr('setf')
if set_fg:
for i,color in zip(range(len(self._COLORS)), self._COLORS):
setattr(self, color, curses.tparm(set_fg, i) or '')
set_fg_ansi = self._tigetstr('setaf')
if set_fg_ansi:
for i,color in zip(range(len(self._ANSICOLORS)), self._ANSICOLORS):
setattr(self, color, curses.tparm(set_fg_ansi, i) or '')
set_bg = self._tigetstr('setb')
if set_bg:
for i,color in zip(range(len(self._COLORS)), self._COLORS):
setattr(self, 'BG_'+color, curses.tparm(set_bg, i) or '')
set_bg_ansi = self._tigetstr('setab')
if set_bg_ansi:
for i,color in zip(range(len(self._ANSICOLORS)), self._ANSICOLORS):
setattr(self, 'BG_'+color, curses.tparm(set_bg_ansi, i) or '')
def _tigetstr(self, cap_name):
# String capabilities can include "delays" of the form "$<2>".
# For any modern terminal, we should be able to just ignore
# these, so strip them out.
import curses
cap = curses.tigetstr(cap_name) or ''
return re.sub(r'\$<\d+>[/*]?', '', cap)
def render(self, template):
return re.sub(r'\$\$|\${\w+}', self._render_sub, template)
def _render_sub(self, match):
s = match.group()
if s == '$$': return s
else: return getattr(self, s[2:-1])
class ProgressBar:
BAR = '%3d%% ${GREEN}[${BOLD}%s%s${NORMAL}${GREEN}]${NORMAL}\n'
HEADER = '${BOLD}${CYAN}%s${NORMAL}\n\n'
def __init__(self, term, header):
self.term = term
if not (self.term.CLEAR_EOL and self.term.UP and self.term.BOL):
raise ValueError("Terminal isn't capable enough -- you "
"should use a simpler progress dispaly.")
self.width = self.term.COLS or 75
self.bar = term.render(self.BAR)
self.header = self.term.render(self.HEADER % header.center(self.width))
self.cleared = 1 #: true if we haven't drawn the bar yet.
def update(self, percent, message=''):
if isinstance(message, unicode):
message = message.encode('utf-8', 'ignore')
if self.cleared:
sys.stdout.write(self.header)
self.cleared = 0
n = int((self.width-10)*percent)
msg = message.center(self.width)
sys.stdout.write(
self.term.BOL + self.term.UP + self.term.CLEAR_EOL +
(self.bar % (100*percent, '='*n, '-'*(self.width-10-n))) +
self.term.CLEAR_EOL + msg)
sys.stdout.flush()
def clear(self):
if not self.cleared:
sys.stdout.write(self.term.BOL + self.term.CLEAR_EOL +
self.term.UP + self.term.CLEAR_EOL +
self.term.UP + self.term.CLEAR_EOL)
self.cleared = 1
def download_tarball():
try:
pb = ProgressBar(TerminalController(sys.stdout), 'Downloading calibre...')
except ValueError:
print 'Downloading calibre...'
pb = None
local = 'calibre-test.tar.bz2'
src = open(local) if os.access(local, os.R_OK) else urllib2.urlopen(MOBILEREAD+'calibre-%version-i686.tar.bz2')
if hasattr(src, 'info'):
size = int(src.info()['content-length'])
else:
src.seek(0, 2)
size = src.tell()
src.seek(0)
f = tempfile.NamedTemporaryFile()
while f.tell() < size:
f.write(src.read(4*1024))
percent = f.tell()/float(size)
if pb is not None:
pb.update(percent)
else:
print '%d%%, '%int(percent*100),
f.seek(0)
return f
def extract_tarball(tar, destdir):
print 'Extracting application files...'
if hasattr(tar, 'read'):
subprocess.check_call(['tar', 'xjf', tar.name, '-C', destdir])
else:
subprocess.check_call(['tar', 'xjf', tar, '-C', destdir])
def main():
defdir = '/opt/calibre'
destdir = raw_input('Enter the installation directory for calibre (Its contents will be deleted!)[%s]: '%defdir).strip()
if not destdir:
destdir = defdir
destdir = os.path.abspath(destdir)
if os.path.exists(destdir):
shutil.rmtree(destdir)
os.makedirs(destdir)
f = download_tarball()
print 'Extracting files to %s ...'%destdir
extract_tarball(f, destdir)
mh = os.path.join(destdir, 'calibre-mount-helper')
if os.geteuid() == 0:
os.chown(mh, 0, 0)
os.chmod(mh,
stat.S_ISUID|stat.S_ISGID|stat.S_IRUSR|stat.S_IWUSR|stat.S_IXUSR|stat.S_IXGRP|stat.S_IXOTH)
else:
print 'WARNING: Not running as root. Cannot install mount helper.',
print 'Device automounting may not work.'
pi = os.path.join(destdir, 'calibre_postinstall')
subprocess.call(pi, shell=True)
return 0
''')

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 95 KiB

View File

@ -1,40 +0,0 @@
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:py="http://genshi.edgewall.org/"
xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include href="layout.html" />
<head>
<title>$title</title>
</head>
<body>
<div id="ctxtnav" class="nav"></div>
<div id="content" class="binary">
<h1>$title</h1>
<p>$compatibility</p>
<p>
<a style="border: 0px" href="$path">
<img width="50" height="50" style="border:1px red solid" src="${href.chrome('/dl/images/%s_logo.png'%(name,))}" /> $installer_name
</a> (Version: $version <a href="/wiki/Changelog">Changelog</a>)
</p>
While you wait for the download to complete, please consider donating to support the development
of ${app}. If the above link does not work, the files are also available from
<a href="https://sourceforge.net/projects/calibre/">sourceforge</a>.
<div>
<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
<input type="hidden" name="cmd" value="_s-xclick" />
<input type="hidden" name="hosted_button_id" value="3029289" />
<input type="image" src="https://www.paypal.com/en_US/i/btn/btn_donateCC_LG.gif" border="0" name="submit" alt="Donate to support calibre development" />
<img alt="" border="0" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1" />
</form>
<br />
</div>
<h2>Note</h2>
<div class="note">$note</div>
</div>
</body>
</html>

View File

@ -1,41 +0,0 @@
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:py="http://genshi.edgewall.org/"
xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include href="layout.html" />
<head>
<title>$title</title>
</head>
<body>
<div id="ctxtnav" class="nav"></div>
<p py:if="not top_level">If you have a 64bit computer, or an outdated operating system, the distribution
specific installation may not work for you. In that case, first try the binary installer.
If that also does not work, your only recourse is to try to install from source. In order
to do that you will have to install all the dependencies as well as the -dev package of PyQt4.
</p>
<div id="content" class="download">
<h1>$title</h1>
<center>
<table cellspacing="40px">
<tr>
<td style="text-align:center; font-size: ${font_size}" py:for="os in operating_systems">
<a href="download_${os['name']}" style="text-decoration:none; border:0;">
<img width="${width}" height="${width+20}" src="${href.chrome('/dl/images/%s_logo.png'%(os['img'],))}" />
</a>
<a href="download_${os['name']}" style="text-decoration:none; border:0">
<br />
${os['title']}
</a>
</td>
</tr>
</table>
<br />
</center>
</div>
</body>
</html>

View File

@ -1,165 +0,0 @@
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:py="http://genshi.edgewall.org/"
xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include href="layout.html" />
<head>
<title>${title}</title>
<style type="text/css">
table tr th.distro_type {
font-family: monospace;
font-weight: bold;
font-size: larger;
vertical-align:middle;
text-align: center;
border-bottom: solid 1pt black;
}
.right {
margin-left:2em;
border-left: solid 1pt black;
}
table#install_info {
border-collapse: collapse;
border-width: 1pt;
border-style: solid;
table-layout: fixed;
width: 95%;
background: #F7F7F0 none repeat scroll 0 0;
}
table#dependencies {
border-collapse: collapse;
border-width: 0pt;
font-family:monospace;
}
.tdata {vertical-align: top;}
</style>
</head>
<body>
<div id="ctxtnav" class="nav"></div>
<div id="content" class="download">
<h1>${title}</h1>
<p>
The latest release of ${app} is ${version}. See the
<a href="/wiki/Changelog">Changelog</a> for a list of new features.
</p>
<p>
${app} is available in the software repositories of the following
supported linux distributions:
<table id="install_info">
<col width="150" /><col width="*" />
<tr>
<th class="left distro_type">Supported<br/>distributions</th>
<th class="right distro_type">Unsupported distributions</th>
</tr>
<tr class="tdata">
<td class="left" style="overflow-y:scroll">
<div py:for="distro in supported"
style="text-align:center;margin-top:2ex;">
<div>
<img width="64px" height="64px"
src="${distro.img}" alt="${distro.title}" />
</div>
${distro.title}
</div>
</td>
<td class="right">
<div style="margin-left:2em">
<h3>Binary install</h3>
<p>
${app} has a binary installer that has been
tested on a number of distributions on both
32-bit and 64-bit x86 machines. To install,
copy paste the following command into a terminal
and press Enter:
</p>
<pre class="wiki">
sudo python -c "import urllib2; exec urllib2.urlopen('http://status.calibre-ebook.com/linux_installer').read(); main()"
</pre>
<h4>Note</h4>
<ul>
<li>
When running the command line utilities,
they will segfault after completion. This can
be ignored.
</li>
<li>
You must have xdg-utils installed
on your system before running the installer.
</li>
</ul>
<h3>Source install</h3>
<p>
<ol>
<li>
Make sure your system has python &ge; ${dependencies[0][1]}
</li>
<li>
Install the various dependencies listed below
</li>
<li>
Run the following commands in a terminal:
</li>
</ol>
<pre class="wiki">
wget -O- http://status.calibre-ebook.com/dist/src | tar xvz
cd calibre*
sudo python setup.py install
</pre>
Note that if your distribution does not have a
correctly compiled libunrar.so, ${app} will not
support rar files. In order to compile ${app} successfully
poppler headers must include XPdf headers. That is, poppler
must have been configured with --enable-xpdf-headers. Also,
some distributions have buggy libpng headers. See
<a href="https://bugs.launchpad.net/ubuntu/+source/libpng/+bug/218409">here</a>
for example.
</p>
</div>
</td>
</tr>
</table>
</p>
<p>
While you wait for the download to complete, please consider
donating to support the development of ${app}.
</p>
<div>
<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
<input type="hidden" name="cmd" value="_s-xclick" />
<input type="image" src="https://www.paypal.com/en_US/i/btn/btn_donateCC_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!" />
<img alt="" border="0" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1" />
<input type="hidden" name="encrypted" value="-----BEGIN PKCS7-----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-----END PKCS7-----" />
</form>
</div>
<hr/>
<h3>Note</h3>
<p>
If your kernel is compiled with CONFIG_SYSFS_DEPRECATED device detection may not work.
</p>
<hr/>
<h3>Dependencies</h3>
${app} has the following dependencies (the listed version is the minimum version)
<br/><br/>
<table id="dependencies">
<tr>
<th class="distro_type" style="margin-right:2em">Package</th>
<th class="distro_type">Version</th>
</tr>
<tr class="dependency" py:for="dep in dependencies">
<td style="margin-right:2em">${dep[0]}</td><td>${dep[1]}</td>
</tr>
</table>
<h3>Current calibre versions available in various distros</h3>
<div id="osw_calibre"></div>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js" type="text/javascript"></script>
<script src="http://static.oswatershed.org/js/package_badge.js" type="text/javascript"></script>
<script>$(document).ready(function(){ package_badge("calibre", "#osw_calibre"); });</script>
</div>
</body>
</html>

View File

@ -1544,7 +1544,7 @@ class Zeroconf(object):
# This is a quick test to see if we can parse the packets we generate
#temp = DNSIncoming(out.packet())
try:
bytes_sent = self.socket.sendto(out.packet(), 0, (addr, port))
self.socket.sendto(out.packet(), 0, (addr, port))
except:
# Ignore this, it may be a temporary loss of network connection
pass

View File

@ -65,7 +65,6 @@ def set_translators():
# CALIBRE_OVERRIDE_LANG=de_DE.utf8 program
lang = get_lang()
if lang:
translations = available_translations()
buf = iso639 = None
if os.access(lang+'.po', os.R_OK):
from calibre.translations.msgfmt import make

View File

@ -11,7 +11,7 @@ from calibre.constants import iswindows
def find_executable():
name = 'sigil' + ('.exe' if iswindows else '')
path = find_executable_in_path(name)
find_executable_in_path(name)
#if path is None and iswindows:
# path = search_program_files()

View File

@ -79,7 +79,6 @@ def save_soup(soup, target):
html = unicode(soup)
with open(target, 'wb') as f:
idx = html.find('hoping')
f.write(html.encode('utf-8'))
class response(str):
@ -259,7 +258,7 @@ class RecursiveFetcher(object):
continue
try:
data = self.fetch_url(iurl)
except Exception, err:
except Exception:
self.log.exception('Could not fetch stylesheet %s'% iurl)
continue
stylepath = os.path.join(diskpath, 'style'+str(c)+'.css')
@ -282,7 +281,7 @@ class RecursiveFetcher(object):
continue
try:
data = self.fetch_url(iurl)
except Exception, err:
except Exception:
self.log.exception('Could not fetch stylesheet %s'% iurl)
continue
c += 1
@ -314,7 +313,7 @@ class RecursiveFetcher(object):
continue
try:
data = self.fetch_url(iurl)
except Exception, err:
except Exception:
self.log.exception('Could not fetch image %s'% iurl)
continue
c += 1
@ -443,7 +442,7 @@ class RecursiveFetcher(object):
save_soup(soup, res)
self.localize_link(tag, 'href', res)
except Exception, err:
except Exception:
self.failed_links.append((iurl, traceback.format_exc()))
self.log.exception('Could not fetch link', iurl)
finally: