Use the modern form for set literals

This commit is contained in:
Kovid Goyal 2018-09-10 19:35:20 +05:30
parent 1a928fc497
commit b789e4d81b
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
89 changed files with 307 additions and 315 deletions

View File

@ -277,8 +277,8 @@ class Plugin(object): # {{{
if self.plugin_path is not None:
from calibre.utils.zipfile import ZipFile
zf = ZipFile(self.plugin_path)
extensions = set([x.rpartition('.')[-1].lower() for x in
zf.namelist()])
extensions = {x.rpartition('.')[-1].lower() for x in
zf.namelist()}
zip_safe = True
for ext in ('pyd', 'so', 'dll', 'dylib'):
if ext in extensions:
@ -507,11 +507,10 @@ class CatalogPlugin(Plugin): # {{{
def get_output_fields(self, db, opts):
# Return a list of requested fields
all_std_fields = set(
['author_sort','authors','comments','cover','formats',
all_std_fields = {'author_sort','authors','comments','cover','formats',
'id','isbn','library_name','ondevice','pubdate','publisher',
'rating','series_index','series','size','tags','timestamp',
'title_sort','title','uuid','languages','identifiers'])
'title_sort','title','uuid','languages','identifiers'}
all_custom_fields = set(db.custom_field_keys())
for field in list(all_custom_fields):
fm = db.field_metadata[field]

View File

@ -24,7 +24,7 @@ class PML2PMLZ(FileTypePlugin):
'This plugin is run every time you add '
'a PML file to the library.')
version = numeric_version
file_types = set(['pml'])
file_types = {'pml'}
supported_platforms = ['windows', 'osx', 'linux']
on_import = True
@ -54,7 +54,7 @@ class TXT2TXTZ(FileTypePlugin):
'containing Markdown or Textile references to images. The referenced '
'images as well as the TXT file are added to the archive.')
version = numeric_version
file_types = set(['txt', 'text'])
file_types = {'txt', 'text'}
supported_platforms = ['windows', 'osx', 'linux']
on_import = True
@ -132,7 +132,7 @@ plugins += [HTML2ZIP, PML2PMLZ, TXT2TXTZ, ArchiveExtract,]
class ComicMetadataReader(MetadataReaderPlugin):
name = 'Read comic metadata'
file_types = set(['cbr', 'cbz'])
file_types = {'cbr', 'cbz'}
description = _('Extract cover from comic files')
def customization_help(self, gui=False):
@ -173,7 +173,7 @@ class ComicMetadataReader(MetadataReaderPlugin):
class CHMMetadataReader(MetadataReaderPlugin):
name = 'Read CHM metadata'
file_types = set(['chm'])
file_types = {'chm'}
description = _('Read metadata from %s files') % 'CHM'
def get_metadata(self, stream, ftype):
@ -184,7 +184,7 @@ class CHMMetadataReader(MetadataReaderPlugin):
class EPUBMetadataReader(MetadataReaderPlugin):
name = 'Read EPUB metadata'
file_types = set(['epub'])
file_types = {'epub'}
description = _('Read metadata from %s files')%'EPUB'
def get_metadata(self, stream, ftype):
@ -208,7 +208,7 @@ class FB2MetadataReader(MetadataReaderPlugin):
class HTMLMetadataReader(MetadataReaderPlugin):
name = 'Read HTML metadata'
file_types = set(['html'])
file_types = {'html'}
description = _('Read metadata from %s files')%'HTML'
def get_metadata(self, stream, ftype):
@ -219,7 +219,7 @@ class HTMLMetadataReader(MetadataReaderPlugin):
class HTMLZMetadataReader(MetadataReaderPlugin):
name = 'Read HTMLZ metadata'
file_types = set(['htmlz'])
file_types = {'htmlz'}
description = _('Read metadata from %s files') % 'HTMLZ'
author = 'John Schember'
@ -231,7 +231,7 @@ class HTMLZMetadataReader(MetadataReaderPlugin):
class IMPMetadataReader(MetadataReaderPlugin):
name = 'Read IMP metadata'
file_types = set(['imp'])
file_types = {'imp'}
description = _('Read metadata from %s files')%'IMP'
author = 'Ashish Kulkarni'
@ -243,7 +243,7 @@ class IMPMetadataReader(MetadataReaderPlugin):
class LITMetadataReader(MetadataReaderPlugin):
name = 'Read LIT metadata'
file_types = set(['lit'])
file_types = {'lit'}
description = _('Read metadata from %s files')%'LIT'
def get_metadata(self, stream, ftype):
@ -254,7 +254,7 @@ class LITMetadataReader(MetadataReaderPlugin):
class LRFMetadataReader(MetadataReaderPlugin):
name = 'Read LRF metadata'
file_types = set(['lrf'])
file_types = {'lrf'}
description = _('Read metadata from %s files')%'LRF'
def get_metadata(self, stream, ftype):
@ -265,7 +265,7 @@ class LRFMetadataReader(MetadataReaderPlugin):
class LRXMetadataReader(MetadataReaderPlugin):
name = 'Read LRX metadata'
file_types = set(['lrx'])
file_types = {'lrx'}
description = _('Read metadata from %s files')%'LRX'
def get_metadata(self, stream, ftype):
@ -276,7 +276,7 @@ class LRXMetadataReader(MetadataReaderPlugin):
class MOBIMetadataReader(MetadataReaderPlugin):
name = 'Read MOBI metadata'
file_types = set(['mobi', 'prc', 'azw', 'azw3', 'azw4', 'pobi'])
file_types = {'mobi', 'prc', 'azw', 'azw3', 'azw4', 'pobi'}
description = _('Read metadata from %s files')%'MOBI'
def get_metadata(self, stream, ftype):
@ -287,7 +287,7 @@ class MOBIMetadataReader(MetadataReaderPlugin):
class ODTMetadataReader(MetadataReaderPlugin):
name = 'Read ODT metadata'
file_types = set(['odt'])
file_types = {'odt'}
description = _('Read metadata from %s files')%'ODT'
def get_metadata(self, stream, ftype):
@ -298,7 +298,7 @@ class ODTMetadataReader(MetadataReaderPlugin):
class DocXMetadataReader(MetadataReaderPlugin):
name = 'Read DOCX metadata'
file_types = set(['docx'])
file_types = {'docx'}
description = _('Read metadata from %s files')%'DOCX'
def get_metadata(self, stream, ftype):
@ -320,7 +320,7 @@ class OPFMetadataReader(MetadataReaderPlugin):
class PDBMetadataReader(MetadataReaderPlugin):
name = 'Read PDB metadata'
file_types = set(['pdb', 'updb'])
file_types = {'pdb', 'updb'}
description = _('Read metadata from %s files') % 'PDB'
author = 'John Schember'
@ -332,7 +332,7 @@ class PDBMetadataReader(MetadataReaderPlugin):
class PDFMetadataReader(MetadataReaderPlugin):
name = 'Read PDF metadata'
file_types = set(['pdf'])
file_types = {'pdf'}
description = _('Read metadata from %s files')%'PDF'
def get_metadata(self, stream, ftype):
@ -345,7 +345,7 @@ class PDFMetadataReader(MetadataReaderPlugin):
class PMLMetadataReader(MetadataReaderPlugin):
name = 'Read PML metadata'
file_types = set(['pml', 'pmlz'])
file_types = {'pml', 'pmlz'}
description = _('Read metadata from %s files') % 'PML'
author = 'John Schember'
@ -357,7 +357,7 @@ class PMLMetadataReader(MetadataReaderPlugin):
class RARMetadataReader(MetadataReaderPlugin):
name = 'Read RAR metadata'
file_types = set(['rar'])
file_types = {'rar'}
description = _('Read metadata from e-books in RAR archives')
def get_metadata(self, stream, ftype):
@ -368,7 +368,7 @@ class RARMetadataReader(MetadataReaderPlugin):
class RBMetadataReader(MetadataReaderPlugin):
name = 'Read RB metadata'
file_types = set(['rb'])
file_types = {'rb'}
description = _('Read metadata from %s files')%'RB'
author = 'Ashish Kulkarni'
@ -380,7 +380,7 @@ class RBMetadataReader(MetadataReaderPlugin):
class RTFMetadataReader(MetadataReaderPlugin):
name = 'Read RTF metadata'
file_types = set(['rtf'])
file_types = {'rtf'}
description = _('Read metadata from %s files')%'RTF'
def get_metadata(self, stream, ftype):
@ -391,7 +391,7 @@ class RTFMetadataReader(MetadataReaderPlugin):
class SNBMetadataReader(MetadataReaderPlugin):
name = 'Read SNB metadata'
file_types = set(['snb'])
file_types = {'snb'}
description = _('Read metadata from %s files') % 'SNB'
author = 'Li Fanxi'
@ -403,7 +403,7 @@ class SNBMetadataReader(MetadataReaderPlugin):
class TOPAZMetadataReader(MetadataReaderPlugin):
name = 'Read Topaz metadata'
file_types = set(['tpz', 'azw1'])
file_types = {'tpz', 'azw1'}
description = _('Read metadata from %s files')%'MOBI'
def get_metadata(self, stream, ftype):
@ -414,7 +414,7 @@ class TOPAZMetadataReader(MetadataReaderPlugin):
class TXTMetadataReader(MetadataReaderPlugin):
name = 'Read TXT metadata'
file_types = set(['txt'])
file_types = {'txt'}
description = _('Read metadata from %s files') % 'TXT'
author = 'John Schember'
@ -426,7 +426,7 @@ class TXTMetadataReader(MetadataReaderPlugin):
class TXTZMetadataReader(MetadataReaderPlugin):
name = 'Read TXTZ metadata'
file_types = set(['txtz'])
file_types = {'txtz'}
description = _('Read metadata from %s files') % 'TXTZ'
author = 'John Schember'
@ -438,7 +438,7 @@ class TXTZMetadataReader(MetadataReaderPlugin):
class ZipMetadataReader(MetadataReaderPlugin):
name = 'Read ZIP metadata'
file_types = set(['zip', 'oebzip'])
file_types = {'zip', 'oebzip'}
description = _('Read metadata from e-books in ZIP archives')
def get_metadata(self, stream, ftype):
@ -457,7 +457,7 @@ plugins += [x for x in list(locals().values()) if isinstance(x, type) and
class EPUBMetadataWriter(MetadataWriterPlugin):
name = 'Set EPUB metadata'
file_types = set(['epub'])
file_types = {'epub'}
description = _('Set metadata in %s files')%'EPUB'
def set_metadata(self, stream, mi, type):
@ -487,7 +487,7 @@ class FB2MetadataWriter(MetadataWriterPlugin):
class HTMLZMetadataWriter(MetadataWriterPlugin):
name = 'Set HTMLZ metadata'
file_types = set(['htmlz'])
file_types = {'htmlz'}
description = _('Set metadata from %s files') % 'HTMLZ'
author = 'John Schember'
@ -499,7 +499,7 @@ class HTMLZMetadataWriter(MetadataWriterPlugin):
class LRFMetadataWriter(MetadataWriterPlugin):
name = 'Set LRF metadata'
file_types = set(['lrf'])
file_types = {'lrf'}
description = _('Set metadata in %s files')%'LRF'
def set_metadata(self, stream, mi, type):
@ -510,7 +510,7 @@ class LRFMetadataWriter(MetadataWriterPlugin):
class MOBIMetadataWriter(MetadataWriterPlugin):
name = 'Set MOBI metadata'
file_types = set(['mobi', 'prc', 'azw', 'azw3', 'azw4'])
file_types = {'mobi', 'prc', 'azw', 'azw3', 'azw4'}
description = _('Set metadata in %s files')%'MOBI'
author = 'Marshall T. Vandegrift'
@ -522,7 +522,7 @@ class MOBIMetadataWriter(MetadataWriterPlugin):
class PDBMetadataWriter(MetadataWriterPlugin):
name = 'Set PDB metadata'
file_types = set(['pdb'])
file_types = {'pdb'}
description = _('Set metadata from %s files') % 'PDB'
author = 'John Schember'
@ -534,7 +534,7 @@ class PDBMetadataWriter(MetadataWriterPlugin):
class PDFMetadataWriter(MetadataWriterPlugin):
name = 'Set PDF metadata'
file_types = set(['pdf'])
file_types = {'pdf'}
description = _('Set metadata in %s files') % 'PDF'
author = 'Kovid Goyal'
@ -546,7 +546,7 @@ class PDFMetadataWriter(MetadataWriterPlugin):
class RTFMetadataWriter(MetadataWriterPlugin):
name = 'Set RTF metadata'
file_types = set(['rtf'])
file_types = {'rtf'}
description = _('Set metadata in %s files')%'RTF'
def set_metadata(self, stream, mi, type):
@ -557,7 +557,7 @@ class RTFMetadataWriter(MetadataWriterPlugin):
class TOPAZMetadataWriter(MetadataWriterPlugin):
name = 'Set TOPAZ metadata'
file_types = set(['tpz', 'azw1'])
file_types = {'tpz', 'azw1'}
description = _('Set metadata in %s files')%'TOPAZ'
author = 'Greg Riker'
@ -569,7 +569,7 @@ class TOPAZMetadataWriter(MetadataWriterPlugin):
class TXTZMetadataWriter(MetadataWriterPlugin):
name = 'Set TXTZ metadata'
file_types = set(['txtz'])
file_types = {'txtz'}
description = _('Set metadata from %s files') % 'TXTZ'
author = 'John Schember'
@ -581,7 +581,7 @@ class TXTZMetadataWriter(MetadataWriterPlugin):
class DocXMetadataWriter(MetadataWriterPlugin):
name = 'Set DOCX metadata'
file_types = set(['docx'])
file_types = {'docx'}
description = _('Read metadata from %s files')%'DOCX'
def set_metadata(self, stream, mi, type):

View File

@ -166,7 +166,7 @@ class InputFormatPlugin(Plugin):
#: Options shared by all Input format plugins. Do not override
#: in sub-classes. Use :attr:`options` instead. Every option must be an
#: instance of :class:`OptionRecommendation`.
common_options = set([
common_options = {
OptionRecommendation(name='input_encoding',
recommended_value=None, level=OptionRecommendation.LOW,
help=_('Specify the character encoding of the input document. If '
@ -174,9 +174,7 @@ class InputFormatPlugin(Plugin):
'document itself. Particularly useful for documents that '
'do not declare an encoding or that have erroneous '
'encoding declarations.')
),
])
)}
#: Options to customize the behavior of this plugin. Every option must be an
#: instance of :class:`OptionRecommendation`.
@ -297,14 +295,13 @@ class OutputFormatPlugin(Plugin):
#: Options shared by all Input format plugins. Do not override
#: in sub-classes. Use :attr:`options` instead. Every option must be an
#: instance of :class:`OptionRecommendation`.
common_options = set([
common_options = {
OptionRecommendation(name='pretty_print',
recommended_value=False, level=OptionRecommendation.LOW,
help=_('If specified, the output plugin will try to create output '
'that is as human readable as possible. May not have any effect '
'for some output plugins.')
),
])
)}
#: Options to customize the behavior of this plugin. Every option must be an
#: instance of :class:`OptionRecommendation`.

View File

@ -44,7 +44,7 @@ class Plugin(_Plugin):
class InputProfile(Plugin):
author = 'Kovid Goyal'
supported_platforms = set(['windows', 'osx', 'linux'])
supported_platforms = {'windows', 'osx', 'linux'}
can_be_disabled = False
type = _('Input profile')
@ -242,7 +242,7 @@ input_profiles.sort(cmp=lambda x,y:cmp(x.name.lower(), y.name.lower()))
class OutputProfile(Plugin):
author = 'Kovid Goyal'
supported_platforms = set(['windows', 'osx', 'linux'])
supported_platforms = {'windows', 'osx', 'linux'}
can_be_disabled = False
type = _('Output profile')

View File

@ -102,9 +102,9 @@ def restore_plugin_state_to_default(plugin_or_name):
config['enabled_plugins'] = ep
default_disabled_plugins = set([
default_disabled_plugins = {
'Overdrive', 'Douban Books', 'OZON.ru', 'Edelweiss', 'Google Images', 'Big Book Search',
])
}
def is_disabled(plugin):

View File

@ -1215,9 +1215,9 @@ class DB(object):
@property
def custom_tables(self):
return set([x[0] for x in self.conn.get(
return {x[0] for x in self.conn.get(
'SELECT name FROM sqlite_master WHERE type="table" AND '
'(name GLOB "custom_column_*" OR name GLOB "books_custom_column_*")')])
'(name GLOB "custom_column_*" OR name GLOB "books_custom_column_*")')}
@classmethod
def exists_at(cls, path):

View File

@ -36,20 +36,20 @@ class FilesystemTest(BaseTest):
ae, af, sf = self.assertEqual, self.assertFalse, cache.set_field
# Test that changing metadata on a book with no formats/cover works
ae(sf('title', {3:'moved1'}), set([3]))
ae(sf('authors', {3:'moved1'}), set([3]))
ae(sf('title', {3:'Moved1'}), set([3]))
ae(sf('authors', {3:'Moved1'}), set([3]))
ae(sf('title', {3:'moved1'}), {3})
ae(sf('authors', {3:'moved1'}), {3})
ae(sf('title', {3:'Moved1'}), {3})
ae(sf('authors', {3:'Moved1'}), {3})
ae(cache.field_for('title', 3), 'Moved1')
ae(cache.field_for('authors', 3), ('Moved1',))
# Now try with a book that has covers and formats
orig_data = self.get_filesystem_data(cache, 1)
orig_fpath = cache.format_abspath(1, 'FMT1')
ae(sf('title', {1:'moved'}), set([1]))
ae(sf('authors', {1:'moved'}), set([1]))
ae(sf('title', {1:'Moved'}), set([1]))
ae(sf('authors', {1:'Moved'}), set([1]))
ae(sf('title', {1:'moved'}), {1})
ae(sf('authors', {1:'moved'}), {1})
ae(sf('title', {1:'Moved'}), {1})
ae(sf('authors', {1:'Moved'}), {1})
ae(cache.field_for('title', 1), 'Moved')
ae(cache.field_for('authors', 1), ('Moved',))
cache2 = self.init_cache(cl)

View File

@ -146,7 +146,7 @@ class LegacyTest(BaseTest):
# Ensure that the following change will actually update the timestamp
# on filesystems with one second resolution (OS X)
time.sleep(1)
self.assertEqual(db2.data.cache.set_field('title', {1:'xxx'}), set([1]))
self.assertEqual(db2.data.cache.set_field('title', {1:'xxx'}), {1})
db2.close()
del db2
self.assertNotEqual(db.title(1, index_is_id=True), 'xxx')

View File

@ -152,8 +152,8 @@ class WritingTest(BaseTest):
del cache2
self.assertEqual(cache.set_field('publisher', {1:'one', 2:'two',
3:'three'}), {1, 2, 3})
self.assertEqual(cache.set_field('publisher', {1:''}), set([1]))
self.assertEqual(cache.set_field('publisher', {1:'two'}), set([1]))
self.assertEqual(cache.set_field('publisher', {1:''}), {1})
self.assertEqual(cache.set_field('publisher', {1:'two'}), {1})
self.assertEqual(tuple(map(f.for_book, (1,2,3))), ('two', 'two', 'three'))
self.assertEqual(cache.set_field('publisher', {1:'Two'}), {1, 2})
cache2 = self.init_cache(cl)
@ -163,7 +163,7 @@ class WritingTest(BaseTest):
# Enum
self.assertFalse(cache.set_field('#enum', {1:'Not allowed'}))
self.assertEqual(cache.set_field('#enum', {1:'One', 2:'One', 3:'Three'}), {1, 3})
self.assertEqual(cache.set_field('#enum', {1:None}), set([1]))
self.assertEqual(cache.set_field('#enum', {1:None}), {1})
cache2 = self.init_cache(cl)
for c in (cache, cache2):
for i, val in {1:None, 2:'One', 3:'Three'}.iteritems():
@ -185,10 +185,10 @@ class WritingTest(BaseTest):
# Series
self.assertFalse(cache.set_field('series',
{1:'a series one', 2:'a series one'}, allow_case_change=False))
self.assertEqual(cache.set_field('series', {3:'Series [3]'}), set([3]))
self.assertEqual(cache.set_field('series', {3:'Series [3]'}), {3})
self.assertEqual(cache.set_field('#series', {1:'Series', 3:'Series'}),
{1, 3})
self.assertEqual(cache.set_field('#series', {2:'Series [0]'}), set([2]))
self.assertEqual(cache.set_field('#series', {2:'Series [0]'}), {2})
cache2 = self.init_cache(cl)
for c in (cache, cache2):
for i, val in {1:'A Series One', 2:'A Series One', 3:'Series'}.iteritems():
@ -219,7 +219,7 @@ class WritingTest(BaseTest):
ae(sf(name, {1:'tag one, News'}), {1, 2})
ae(sf(name, {3:('tag two', 'sep,sep2')}), {2, 3})
ae(len(f.table.id_map), 4)
ae(sf(name, {1:None}), set([1]))
ae(sf(name, {1:None}), {1})
cache2 = self.init_cache(cl)
for c in (cache, cache2):
ae(c.field_for(name, 3), ('tag two', 'sep;sep2'))
@ -237,7 +237,7 @@ class WritingTest(BaseTest):
f = cache.fields[name]
ae(len(f.table.id_map), 3)
af(cache.set_field(name, {3:None if name == 'authors' else 'Unknown'}))
ae(cache.set_field(name, {3:'Kovid Goyal & Divok Layog'}), set([3]))
ae(cache.set_field(name, {3:'Kovid Goyal & Divok Layog'}), {3})
ae(cache.set_field(name, {1:'', 2:'An, Author'}), {1,2})
cache2 = self.init_cache(cl)
for c in (cache, cache2):
@ -257,18 +257,18 @@ class WritingTest(BaseTest):
# Languages
f = cache.fields['languages']
ae(f.table.id_map, {1: 'eng', 2: 'deu'})
ae(sf('languages', {1:''}), set([1]))
ae(sf('languages', {1:''}), {1})
ae(cache.field_for('languages', 1), ())
ae(sf('languages', {2:('und',)}), set([2]))
ae(sf('languages', {2:('und',)}), {2})
af(f.table.id_map)
ae(sf('languages', {1:'eng,fra,deu', 2:'es,Dutch', 3:'English'}), {1, 2, 3})
ae(cache.field_for('languages', 1), ('eng', 'fra', 'deu'))
ae(cache.field_for('languages', 2), ('spa', 'nld'))
ae(cache.field_for('languages', 3), ('eng',))
ae(sf('languages', {3:None}), set([3]))
ae(sf('languages', {3:None}), {3})
ae(cache.field_for('languages', 3), ())
ae(sf('languages', {1:'deu,fra,eng'}), set([1]), 'Changing order failed')
ae(sf('languages', {2:'deu,eng,eng'}), set([2]))
ae(sf('languages', {1:'deu,fra,eng'}), {1}, 'Changing order failed')
ae(sf('languages', {2:'deu,eng,eng'}), {2})
cache2 = self.init_cache(cl)
for c in (cache, cache2):
ae(cache.field_for('languages', 1), ('deu', 'fra', 'eng'))
@ -277,9 +277,9 @@ class WritingTest(BaseTest):
# Identifiers
f = cache.fields['identifiers']
ae(sf('identifiers', {3: 'one:1,two:2'}), set([3]))
ae(sf('identifiers', {2:None}), set([2]))
ae(sf('identifiers', {1: {'test':'1', 'two':'2'}}), set([1]))
ae(sf('identifiers', {3: 'one:1,two:2'}), {3})
ae(sf('identifiers', {2:None}), {2})
ae(sf('identifiers', {1: {'test':'1', 'two':'2'}}), {1})
cache2 = self.init_cache(cl)
for c in (cache, cache2):
ae(c.field_for('identifiers', 3), {'one':'1', 'two':'2'})
@ -323,7 +323,7 @@ class WritingTest(BaseTest):
onowf = c.nowf
c.nowf = lambda: utime
try:
ae(sf('title', {3:'xxx'}), set([3]))
ae(sf('title', {3:'xxx'}), {3})
self.assertTrue(3 in cache.dirtied_cache)
ae(cache.field_for('last_modified', 3), utime)
cache.dump_metadata()
@ -374,7 +374,7 @@ class WritingTest(BaseTest):
# Test removing a cover
ae(cache.field_for('cover', 1), 1)
ae(cache.set_cover({1:None}), set([1]))
ae(cache.set_cover({1:None}), {1})
ae(cache.field_for('cover', 1), 0)
img = IMG
@ -645,7 +645,7 @@ class WritingTest(BaseTest):
uv = int(cache.backend.user_version)
all_ids = cache.all_book_ids()
cache.dump_and_restore()
self.assertEqual(cache.set_field('title', {1:'nt'}), set([1]), 'database connection broken')
self.assertEqual(cache.set_field('title', {1:'nt'}), {1}, 'database connection broken')
cache = self.init_cache()
self.assertEqual(cache.all_book_ids(), all_ids, 'dump and restore broke database')
self.assertEqual(int(cache.backend.user_version), uv)

View File

@ -271,7 +271,7 @@ class KINDLE(USBMS):
from calibre.ebooks.metadata import MetaInformation
bm = annotation
ignore_tags = set(['Catalog', 'Clippings'])
ignore_tags = {'Catalog', 'Clippings'}
if bm.type == 'kindle_bookmark':
mi = db.get_metadata(db_id, index_is_id=True)

View File

@ -1280,7 +1280,7 @@ class KOBO(USBMS):
def add_annotation_to_library(self, db, db_id, annotation):
from calibre.ebooks.BeautifulSoup import Tag
bm = annotation
ignore_tags = set(['Catalog', 'Clippings'])
ignore_tags = {'Catalog', 'Clippings'}
if bm.type == 'kobo_bookmark' and bm.value.last_read:
mi = db.get_metadata(db_id, index_is_id=True)

View File

@ -14,7 +14,7 @@ class AZW4Input(InputFormatPlugin):
name = 'AZW4 Input'
author = 'John Schember'
description = 'Convert AZW4 to HTML'
file_types = set(['azw4'])
file_types = {'azw4'}
commit_name = 'azw4_input'
def convert(self, stream, options, file_ext, log,

View File

@ -15,7 +15,7 @@ class CHMInput(InputFormatPlugin):
name = 'CHM Input'
author = 'Kovid Goyal and Alex Bramley'
description = 'Convert CHM files to OEB'
file_types = set(['chm'])
file_types = {'chm'}
commit_name = 'chm_input'
def _chmtohtml(self, output_dir, chm_path, no_images, log, debug_dump=False):

View File

@ -19,12 +19,12 @@ class ComicInput(InputFormatPlugin):
name = 'Comic Input'
author = 'Kovid Goyal'
description = 'Optimize comic files (.cbz, .cbr, .cbc) for viewing on portable devices'
file_types = set(['cbz', 'cbr', 'cbc'])
file_types = {'cbz', 'cbr', 'cbc'}
is_image_collection = True
commit_name = 'comic_input'
core_usage = -1
options = set([
options = {
OptionRecommendation(name='colors', recommended_value=0,
help=_('Reduce the number of colors used in the image. This works only'
' if you choose the PNG output format. It is useful to reduce file sizes.'
@ -71,9 +71,9 @@ class ComicInput(InputFormatPlugin):
help=_('When converting a CBC do not add links to each page to'
' the TOC. Note this only applies if the TOC has more than one'
' section')),
])
}
recommendations = set([
recommendations = {
('margin_left', 0, OptionRecommendation.HIGH),
('margin_top', 0, OptionRecommendation.HIGH),
('margin_right', 0, OptionRecommendation.HIGH),
@ -88,7 +88,7 @@ class ComicInput(InputFormatPlugin):
('page_breaks_before', None, OptionRecommendation.HIGH),
('disable_font_rescaling', True, OptionRecommendation.HIGH),
('linearize_tables', False, OptionRecommendation.HIGH),
])
}
def get_comics_from_collection(self, stream):
from calibre.libunzip import extract as zipextract

View File

@ -18,7 +18,7 @@ class DJVUInput(InputFormatPlugin):
name = 'DJVU Input'
author = 'Anthon van der Neut'
description = 'Convert OCR-ed DJVU files (.djvu) to HTML'
file_types = set(['djvu', 'djv'])
file_types = {'djvu', 'djv'}
commit_name = 'djvu_input'
def convert(self, stream, options, file_ext, log, accelerators):

View File

@ -27,7 +27,7 @@ class DOCXInput(InputFormatPlugin):
help=_('Render superscripts and subscripts so that they do not affect the line height.')),
}
recommendations = set([('page_breaks_before', '/', OptionRecommendation.MED)])
recommendations = {('page_breaks_before', '/', OptionRecommendation.MED)}
def convert(self, stream, options, file_ext, log, accelerators):
from calibre.ebooks.docx.to_html import Convert

View File

@ -32,11 +32,11 @@ class EPUBInput(InputFormatPlugin):
name = 'EPUB Input'
author = 'Kovid Goyal'
description = 'Convert EPUB files (.epub) to HTML'
file_types = set(['epub'])
file_types = {'epub'}
output_encoding = None
commit_name = 'epub_input'
recommendations = set([('page_breaks_before', '/', OptionRecommendation.MED)])
recommendations = {('page_breaks_before', '/', OptionRecommendation.MED)}
def process_encryption(self, encfile, opf, log):
from lxml import etree

View File

@ -51,7 +51,7 @@ class EPUBOutput(OutputFormatPlugin):
commit_name = 'epub_output'
ui_data = {'versions': ('2', '3')}
options = set([
options = {
OptionRecommendation(name='extract_to',
help=_('Extract the contents of the generated %s file to the '
'specified directory. The contents of the directory are first '
@ -125,9 +125,9 @@ class EPUBOutput(OutputFormatPlugin):
' actually need it.')
),
])
}
recommendations = set([('pretty_print', True, OptionRecommendation.HIGH)])
recommendations = {('pretty_print', True, OptionRecommendation.HIGH)}
def workaround_webkit_quirks(self): # {{{
from calibre.ebooks.oeb.base import XPath

View File

@ -21,19 +21,18 @@ class FB2Input(InputFormatPlugin):
file_types = {'fb2', 'fbz'}
commit_name = 'fb2_input'
recommendations = set([
recommendations = {
('level1_toc', '//h:h1', OptionRecommendation.MED),
('level2_toc', '//h:h2', OptionRecommendation.MED),
('level3_toc', '//h:h3', OptionRecommendation.MED),
])
}
options = set([
options = {
OptionRecommendation(name='no_inline_fb2_toc',
recommended_value=False, level=OptionRecommendation.LOW,
help=_('Do not insert a Table of Contents at the beginning of the book.'
)
),
])
)}
def convert(self, stream, options, file_ext, log,
accelerators):

View File

@ -151,7 +151,7 @@ class FB2Output(OutputFormatPlugin):
'genres': FB2_GENRES,
}
options = set([
options = {
OptionRecommendation(name='sectionize',
recommended_value='files', level=OptionRecommendation.LOW,
choices=list(ui_data['sectionize']),
@ -167,7 +167,7 @@ class FB2Output(OutputFormatPlugin):
choices=FB2_GENRES,
help=(_('Genre for the book. Choices: %s\n\n See: ') % ', '.join(FB2_GENRES)
) + 'http://www.fictionbook.org/index.php/Eng:FictionBook_2.1_genres ' + _('for a complete list with descriptions.')),
])
}
def convert(self, oeb_book, output_path, input_plugin, opts, log):
from calibre.ebooks.oeb.transforms.jacket import linearize_jacket

View File

@ -30,10 +30,10 @@ class HTMLInput(InputFormatPlugin):
name = 'HTML Input'
author = 'Kovid Goyal'
description = 'Convert HTML and OPF files to an OEB'
file_types = set(['opf', 'html', 'htm', 'xhtml', 'xhtm', 'shtm', 'shtml'])
file_types = {'opf', 'html', 'htm', 'xhtml', 'xhtm', 'shtm', 'shtml'}
commit_name = 'html_input'
options = set([
options = {
OptionRecommendation(name='breadth_first',
recommended_value=False, level=OptionRecommendation.LOW,
help=_('Traverse links in HTML files breadth first. Normally, '
@ -59,7 +59,7 @@ class HTMLInput(InputFormatPlugin):
)
),
])
}
def convert(self, stream, opts, file_ext, log,
accelerators):

View File

@ -22,7 +22,7 @@ class HTMLOutput(OutputFormatPlugin):
file_type = 'zip'
commit_name = 'html_output'
options = set([
options = {
OptionRecommendation(name='template_css',
help=_('CSS file used for the output instead of the default file')),
@ -37,9 +37,9 @@ class HTMLOutput(OutputFormatPlugin):
'specified directory. WARNING: The contents of the directory '
'will be deleted.')
),
])
}
recommendations = set([('pretty_print', True, OptionRecommendation.HIGH)])
recommendations = {('pretty_print', True, OptionRecommendation.HIGH)}
def generate_toc(self, oeb_book, ref_url, output_dir):
'''

View File

@ -17,7 +17,7 @@ class HTMLZInput(InputFormatPlugin):
name = 'HTLZ Input'
author = 'John Schember'
description = 'Convert HTML files to HTML'
file_types = set(['htmlz'])
file_types = {'htmlz'}
commit_name = 'htmlz_input'
def convert(self, stream, options, file_ext, log,

View File

@ -14,7 +14,7 @@ class LITInput(InputFormatPlugin):
name = 'LIT Input'
author = 'Marshall T. Vandegrift'
description = 'Convert LIT files to HTML'
file_types = set(['lit'])
file_types = {'lit'}
commit_name = 'lit_input'
def convert(self, stream, options, file_ext, log,

View File

@ -15,7 +15,7 @@ class LRFInput(InputFormatPlugin):
name = 'LRF Input'
author = 'Kovid Goyal'
description = 'Convert LRF files to HTML'
file_types = set(['lrf'])
file_types = {'lrf'}
commit_name = 'lrf_input'
def convert(self, stream, options, file_ext, log,

View File

@ -92,7 +92,7 @@ class LRFOutput(OutputFormatPlugin):
file_type = 'lrf'
commit_name = 'lrf_output'
options = set([
options = {
OptionRecommendation(name='enable_autorotation', recommended_value=False,
help=_('Enable auto-rotation of images that are wider than the screen width.')
),
@ -134,11 +134,10 @@ class LRFOutput(OutputFormatPlugin):
help=_('The monospace family of fonts to embed')
),
])
}
recommendations = set([
('change_justification', 'original', OptionRecommendation.HIGH),
])
recommendations = {
('change_justification', 'original', OptionRecommendation.HIGH)}
def convert_images(self, pages, opts, wide):
from calibre.ebooks.lrf.pylrs.pylrs import Book, BookSetting, ImageStream, ImageBlock

View File

@ -13,7 +13,7 @@ class MOBIInput(InputFormatPlugin):
name = 'MOBI Input'
author = 'Kovid Goyal'
description = 'Convert MOBI files (.mobi, .prc, .azw) to HTML'
file_types = set(['mobi', 'prc', 'azw', 'azw3', 'pobi'])
file_types = {'mobi', 'prc', 'azw', 'azw3', 'pobi'}
commit_name = 'mobi_input'
def convert(self, stream, options, file_ext, log,

View File

@ -44,7 +44,7 @@ class MOBIOutput(OutputFormatPlugin):
commit_name = 'mobi_output'
ui_data = {'file_types': ['old', 'both', 'new']}
options = set([
options = {
OptionRecommendation(name='prefer_author_sort',
recommended_value=False, level=OptionRecommendation.LOW,
help=_('When present, use author sort field as author.')
@ -106,7 +106,7 @@ class MOBIOutput(OutputFormatPlugin):
'more features than MOBI 6, but only works with newer Kindles. '
'Allowed values: {}').format('old, both, new')),
])
}
def check_for_periodical(self):
if self.is_periodical:
@ -274,7 +274,7 @@ class AZW3Output(OutputFormatPlugin):
file_type = 'azw3'
commit_name = 'azw3_output'
options = set([
options = {
OptionRecommendation(name='prefer_author_sort',
recommended_value=False, level=OptionRecommendation.LOW,
help=_('When present, use author sort field as author.')
@ -305,7 +305,7 @@ class AZW3Output(OutputFormatPlugin):
' the book will not auto sync its last read position '
' on multiple devices. Complain to Amazon.')
),
])
}
def convert(self, oeb, output_path, input_plugin, opts, log):
from calibre.ebooks.mobi.writer2.resources import Resources

View File

@ -15,7 +15,7 @@ class ODTInput(InputFormatPlugin):
name = 'ODT Input'
author = 'Kovid Goyal'
description = 'Convert ODT (OpenOffice) files to HTML'
file_types = set(['odt'])
file_types = {'odt'}
commit_name = 'odt_input'
def convert(self, stream, options, file_ext, log,

View File

@ -18,7 +18,7 @@ class OEBOutput(OutputFormatPlugin):
file_type = 'oeb'
commit_name = 'oeb_output'
recommendations = set([('pretty_print', True, OptionRecommendation.HIGH)])
recommendations = {('pretty_print', True, OptionRecommendation.HIGH)}
def convert(self, oeb_book, output_path, input_plugin, opts, log):
from urllib import unquote

View File

@ -14,7 +14,7 @@ class PDBInput(InputFormatPlugin):
name = 'PDB Input'
author = 'John Schember'
description = 'Convert PDB to HTML'
file_types = set(['pdb', 'updb'])
file_types = {'pdb', 'updb'}
commit_name = 'pdb_input'
def convert(self, stream, options, file_ext, log,

View File

@ -19,7 +19,7 @@ class PDBOutput(OutputFormatPlugin):
commit_name = 'pdb_output'
ui_data = {'formats': tuple(ALL_FORMAT_WRITERS)}
options = set([
options = {
OptionRecommendation(name='format', recommended_value='doc',
level=OptionRecommendation.LOW,
short_switch='f', choices=list(ALL_FORMAT_WRITERS),
@ -32,7 +32,7 @@ class PDBOutput(OutputFormatPlugin):
OptionRecommendation(name='inline_toc',
recommended_value=False, level=OptionRecommendation.LOW,
help=_('Add Table of Contents to beginning of the book.')),
])
}
def convert(self, oeb_book, output_path, input_plugin, opts, log):
close = False

View File

@ -14,10 +14,10 @@ class PDFInput(InputFormatPlugin):
name = 'PDF Input'
author = 'Kovid Goyal and John Schember'
description = 'Convert PDF files to HTML'
file_types = set(['pdf'])
file_types = {'pdf'}
commit_name = 'pdf_input'
options = set([
options = {
OptionRecommendation(name='no_images', recommended_value=False,
help=_('Do not extract images from the document')),
OptionRecommendation(name='unwrap_factor', recommended_value=0.45,
@ -26,7 +26,7 @@ class PDFInput(InputFormatPlugin):
'default is 0.45, just below the median line length.')),
OptionRecommendation(name='new_pdf_engine', recommended_value=False,
help=_('Use the new PDF conversion engine. Currently not operational.'))
])
}
def convert_new(self, stream, accelerators):
from calibre.ebooks.pdf.pdftohtml import pdftohtml

View File

@ -18,7 +18,7 @@ class PMLInput(InputFormatPlugin):
author = 'John Schember'
description = 'Convert PML to OEB'
# pmlz is a zip file containing pml files and png images.
file_types = set(['pml', 'pmlz'])
file_types = {'pml', 'pmlz'}
commit_name = 'pml_input'
def process_pml(self, pml_path, html_path, close_all=False):

View File

@ -18,7 +18,7 @@ class PMLOutput(OutputFormatPlugin):
file_type = 'pmlz'
commit_name = 'pml_output'
options = set([
options = {
OptionRecommendation(name='pml_output_encoding', recommended_value='cp1252',
level=OptionRecommendation.LOW,
help=_('Specify the character encoding of the output document. '
@ -32,7 +32,7 @@ class PMLOutput(OutputFormatPlugin):
'have their size and depth reduced by default to accommodate '
'applications that can not convert images on their '
'own such as Dropbook.')),
])
}
def convert(self, oeb_book, output_path, input_plugin, opts, log):
from calibre.ebooks.pml.pmlml import PMLMLizer

View File

@ -14,7 +14,7 @@ class RBInput(InputFormatPlugin):
name = 'RB Input'
author = 'John Schember'
description = 'Convert RB files to HTML'
file_types = set(['rb'])
file_types = {'rb'}
commit_name = 'rb_input'
def convert(self, stream, options, file_ext, log,

View File

@ -16,11 +16,10 @@ class RBOutput(OutputFormatPlugin):
file_type = 'rb'
commit_name = 'rb_output'
options = set([
options = {
OptionRecommendation(name='inline_toc',
recommended_value=False, level=OptionRecommendation.LOW,
help=_('Add Table of Contents to beginning of the book.')),
])
help=_('Add Table of Contents to beginning of the book.'))}
def convert(self, oeb_book, output_path, input_plugin, opts, log):
from calibre.ebooks.rb.writer import RBWriter

View File

@ -22,10 +22,10 @@ class RecipeInput(InputFormatPlugin):
name = 'Recipe Input'
author = 'Kovid Goyal'
description = _('Download periodical content from the internet')
file_types = set(['recipe', 'downloaded_recipe'])
file_types = {'recipe', 'downloaded_recipe'}
commit_name = 'recipe_input'
recommendations = set([
recommendations = {
('chapter', None, OptionRecommendation.HIGH),
('dont_split_on_page_breaks', True, OptionRecommendation.HIGH),
('use_auto_toc', False, OptionRecommendation.HIGH),
@ -33,9 +33,9 @@ class RecipeInput(InputFormatPlugin):
('input_profile', 'default', OptionRecommendation.HIGH),
('page_breaks_before', None, OptionRecommendation.HIGH),
('insert_metadata', False, OptionRecommendation.HIGH),
])
}
options = set([
options = {
OptionRecommendation(name='test', recommended_value=False,
help=_(
'Useful for recipe development. Forces'
@ -53,7 +53,7 @@ class RecipeInput(InputFormatPlugin):
help=_('Do not download latest version of builtin recipes from the calibre server')),
OptionRecommendation(name='lrf', recommended_value=False,
help='Optimize fetching for subsequent conversion to LRF.'),
])
}
def convert(self, recipe_or_file, opts, file_ext, log,
accelerators):

View File

@ -43,7 +43,7 @@ class RTFInput(InputFormatPlugin):
name = 'RTF Input'
author = 'Kovid Goyal'
description = 'Convert RTF files to HTML'
file_types = set(['rtf'])
file_types = {'rtf'}
commit_name = 'rtf_input'
options = {

View File

@ -22,7 +22,7 @@ class SNBInput(InputFormatPlugin):
name = 'SNB Input'
author = 'Li Fanxi'
description = 'Convert SNB files to OEB'
file_types = set(['snb'])
file_types = {'snb'}
commit_name = 'snb_input'
options = set([

View File

@ -18,7 +18,7 @@ class SNBOutput(OutputFormatPlugin):
file_type = 'snb'
commit_name = 'snb_output'
options = set([
options = {
OptionRecommendation(name='snb_output_encoding', recommended_value='utf-8',
level=OptionRecommendation.LOW,
help=_('Specify the character encoding of the output document. '
@ -45,7 +45,7 @@ class SNBOutput(OutputFormatPlugin):
OptionRecommendation(name='snb_full_screen',
recommended_value=False, level=OptionRecommendation.LOW,
help=_('Resize all the images for full screen view. ')),
])
}
def convert(self, oeb_book, output_path, input_plugin, opts, log):
from lxml import etree

View File

@ -14,7 +14,7 @@ class TCRInput(InputFormatPlugin):
name = 'TCR Input'
author = 'John Schember'
description = 'Convert TCR files to HTML'
file_types = set(['tcr'])
file_types = {'tcr'}
commit_name = 'tcr_input'
def convert(self, stream, options, file_ext, log, accelerators):

View File

@ -17,12 +17,11 @@ class TCROutput(OutputFormatPlugin):
file_type = 'tcr'
commit_name = 'tcr_output'
options = set([
options = {
OptionRecommendation(name='tcr_output_encoding', recommended_value='utf-8',
level=OptionRecommendation.LOW,
help=_('Specify the character encoding of the output document. '
'The default is utf-8.')),
])
'The default is utf-8.'))}
def convert(self, oeb_book, output_path, input_plugin, opts, log):
from calibre.ebooks.txt.txtml import TXTMLizer

View File

@ -52,7 +52,7 @@ class TXTInput(InputFormatPlugin):
},
}
options = set([
options = {
OptionRecommendation(name='formatting_type', recommended_value='auto',
choices=list(ui_data['formatting_types']),
help=_('Formatting used within the document.\n'
@ -87,7 +87,7 @@ class TXTInput(InputFormatPlugin):
'To learn more about markdown extensions, see {}\n'
'This should be a comma separated list of extensions to enable:\n'
).format('https://python-markdown.github.io/extensions/') + '\n'.join('* %s: %s' % (k, MD_EXTENSIONS[k]) for k in sorted(MD_EXTENSIONS))),
])
}
def shift_file(self, base_dir, fname, data):
name, ext = os.path.splitext(fname)

View File

@ -30,7 +30,7 @@ class TXTOutput(OutputFormatPlugin):
},
}
options = set([
options = {
OptionRecommendation(name='newline', recommended_value='system',
level=OptionRecommendation.LOW,
short_switch='n', choices=NEWLINE_TYPES,
@ -80,7 +80,7 @@ class TXTOutput(OutputFormatPlugin):
'formatting that supports setting font color. If this option is '
'not specified font color will not be set and default to the '
'color displayed by the reader (generally this is black).')),
])
}
def convert(self, oeb_book, output_path, input_plugin, opts, log):
from calibre.ebooks.txt.txtml import TXTMLizer

View File

@ -22,7 +22,7 @@ file containing all linked files. This plugin is run \
every time you add an HTML file to the library.\
'''))
version = numeric_version
file_types = set(['html', 'htm', 'xhtml', 'xhtm', 'shtm', 'shtml'])
file_types = {'html', 'htm', 'xhtml', 'xhtm', 'shtm', 'shtml'}
supported_platforms = ['windows', 'osx', 'linux']
on_import = True

View File

@ -34,7 +34,7 @@ import calibre.ebooks.lit.mssha1 as mssha1
__all__ = ['LitWriter']
LIT_IMAGES = set(['image/png', 'image/jpeg', 'image/gif'])
LIT_IMAGES = {'image/png', 'image/jpeg', 'image/gif'}
LIT_MIMES = OEB_DOCS | OEB_STYLES | LIT_IMAGES
MS_COVER_TYPE = 'other.ms-coverimage-standard'
@ -115,7 +115,7 @@ LZXC_CONTROL = \
COLLAPSE = re.compile(r'[ \t\r\n\v]+')
PAGE_BREAKS = set(['always', 'left', 'right'])
PAGE_BREAKS = {'always', 'left', 'right'}
def decint(value):

View File

@ -820,7 +820,7 @@ class Text(LRFStream):
text_tags = set(list(TextAttr.tag_map.keys()) +
list(Text.text_tags.keys()) +
list(ruby_tags.keys()))
text_tags -= set([0xf500+i for i in range(10)])
text_tags -= {0xf500+i for i in range(10)}
text_tags.add(0xf5cc)
while stream.tell() < length:

View File

@ -13,9 +13,9 @@ from calibre.customize import FileTypePlugin
def is_comic(list_of_names):
extensions = set([x.rpartition('.')[-1].lower() for x in list_of_names
if '.' in x and x.lower().rpartition('/')[-1] != 'thumbs.db'])
comic_extensions = set(['jpg', 'jpeg', 'png'])
extensions = {x.rpartition('.')[-1].lower() for x in list_of_names
if '.' in x and x.lower().rpartition('/')[-1] != 'thumbs.db'}
comic_extensions = {'jpg', 'jpeg', 'png'}
return len(extensions - comic_extensions) == 0
@ -44,7 +44,7 @@ class ArchiveExtract(FileTypePlugin):
description = _('Extract common e-book formats from archive files '
'(ZIP/RAR). Also try to autodetect if they are actually '
'CBZ/CBR files.')
file_types = set(['zip', 'rar'])
file_types = {'zip', 'rar'}
supported_platforms = ['windows', 'osx', 'linux']
on_import = True

View File

@ -81,7 +81,7 @@ class Ozon(Source):
ozonid = identifiers.get('ozon', None)
qItems = set([ozonid, isbn])
qItems = {ozonid, isbn}
# Added Russian variant of 'Unknown'
unk = [_('Unknown').upper(), 'Неизв.'.upper(), icu_upper('Неизв.')]

View File

@ -47,10 +47,10 @@ def title_test(title, exact=False):
def authors_test(authors):
authors = set([x.lower() for x in authors])
authors = {x.lower() for x in authors}
def test(mi):
au = set([x.lower() for x in mi.authors])
au = {x.lower() for x in mi.authors}
if msprefs['swap_author_names']:
def revert_to_fn_ln(a):
if ',' not in a:
@ -61,7 +61,7 @@ def authors_test(authors):
parts.insert(0, t)
return ' '.join(parts)
au = set([revert_to_fn_ln(x) for x in au])
au = {revert_to_fn_ln(x) for x in au}
if au == authors:
return True
@ -72,10 +72,10 @@ def authors_test(authors):
def tags_test(tags):
tags = set([x.lower() for x in tags])
tags = {x.lower() for x in tags}
def test(mi):
t = set([x.lower() for x in mi.tags])
t = {x.lower() for x in mi.tags}
if t == tags:
return True
prints('Tags test failed. Expected: \'%s\' found \'%s\''%(tags, t))

View File

@ -26,19 +26,19 @@ def MBP(name):
MOBI_NSMAP = {None: XHTML_NS, 'mbp': MBP_NS}
INLINE_TAGS = {'span', 'a', 'code', 'u', 's', 'big', 'strike', 'tt', 'font', 'q', 'i', 'b', 'em', 'strong', 'sup', 'sub'}
HEADER_TAGS = set(['h1', 'h2', 'h3', 'h4', 'h5', 'h6'])
HEADER_TAGS = {'h1', 'h2', 'h3', 'h4', 'h5', 'h6'}
# GR: Added 'caption' to both sets
NESTABLE_TAGS = set(['ol', 'ul', 'li', 'table', 'tr', 'td', 'th', 'caption'])
TABLE_TAGS = set(['table', 'tr', 'td', 'th', 'caption'])
NESTABLE_TAGS = {'ol', 'ul', 'li', 'table', 'tr', 'td', 'th', 'caption'}
TABLE_TAGS = {'table', 'tr', 'td', 'th', 'caption'}
SPECIAL_TAGS = set(['hr', 'br'])
CONTENT_TAGS = set(['img', 'hr', 'br'])
SPECIAL_TAGS = {'hr', 'br'}
CONTENT_TAGS = {'img', 'hr', 'br'}
NOT_VTAGS = HEADER_TAGS | NESTABLE_TAGS | TABLE_TAGS | SPECIAL_TAGS | \
CONTENT_TAGS
LEAF_TAGS = set(['base', 'basefont', 'frame', 'link', 'meta', 'area', 'br',
'col', 'hr', 'img', 'input', 'param'])
PAGE_BREAKS = set(['always', 'left', 'right'])
LEAF_TAGS = {'base', 'basefont', 'frame', 'link', 'meta', 'area', 'br',
'col', 'hr', 'img', 'input', 'param'}
PAGE_BREAKS = {'always', 'left', 'right'}
COLLAPSE = re.compile(r'[ \t\r\n\v]+')

View File

@ -354,8 +354,8 @@ class TBS(object): # {{{
if spanner is None:
articles = depth_map[2]
sections = set([self.section_map[a.parent_index] for a in
articles])
sections = {self.section_map[a.parent_index] for a in
articles}
sections = sorted(sections, key=lambda x:x.offset)
section_map = {s:[a for a in articles if a.parent_index ==
s.index] for s in sections}

View File

@ -27,11 +27,11 @@ XML_NS = 'http://www.w3.org/XML/1998/namespace'
OEB_DOC_NS = 'http://openebook.org/namespaces/oeb-document/1.0/'
OPF1_NS = 'http://openebook.org/namespaces/oeb-package/1.0/'
OPF2_NS = 'http://www.idpf.org/2007/opf'
OPF_NSES = set([OPF1_NS, OPF2_NS])
OPF_NSES = {OPF1_NS, OPF2_NS}
DC09_NS = 'http://purl.org/metadata/dublin_core'
DC10_NS = 'http://purl.org/dc/elements/1.0/'
DC11_NS = 'http://purl.org/dc/elements/1.1/'
DC_NSES = set([DC09_NS, DC10_NS, DC11_NS])
DC_NSES = {DC09_NS, DC10_NS, DC11_NS}
XSI_NS = 'http://www.w3.org/2001/XMLSchema-instance'
DCTERMS_NS = 'http://purl.org/dc/terms/'
NCX_NS = 'http://www.daisy.org/z3986/2005/ncx/'
@ -297,11 +297,11 @@ BINARY_MIME = 'application/octet-stream'
XHTML_CSS_NAMESPACE = u'@namespace "%s";\n' % XHTML_NS
OEB_STYLES = set([CSS_MIME, OEB_CSS_MIME, 'text/x-oeb-css', 'xhtml/css'])
OEB_DOCS = set([XHTML_MIME, 'text/html', OEB_DOC_MIME,
'text/x-oeb-document'])
OEB_RASTER_IMAGES = set([GIF_MIME, JPEG_MIME, PNG_MIME])
OEB_IMAGES = set([GIF_MIME, JPEG_MIME, PNG_MIME, SVG_MIME])
OEB_STYLES = {CSS_MIME, OEB_CSS_MIME, 'text/x-oeb-css', 'xhtml/css'}
OEB_DOCS = {XHTML_MIME, 'text/html', OEB_DOC_MIME,
'text/x-oeb-document'}
OEB_RASTER_IMAGES = {GIF_MIME, JPEG_MIME, PNG_MIME}
OEB_IMAGES = {GIF_MIME, JPEG_MIME, PNG_MIME, SVG_MIME}
MS_COVER_TYPE = 'other.ms-coverimage-standard'
@ -617,12 +617,12 @@ class Metadata(object):
metadata items.
"""
DC_TERMS = set(['contributor', 'coverage', 'creator', 'date',
DC_TERMS = {'contributor', 'coverage', 'creator', 'date',
'description', 'format', 'identifier', 'language',
'publisher', 'relation', 'rights', 'source',
'subject', 'title', 'type'])
CALIBRE_TERMS = set(['series', 'series_index', 'rating', 'timestamp',
'publication_type', 'title_sort'])
'subject', 'title', 'type'}
CALIBRE_TERMS = {'series', 'series_index', 'rating', 'timestamp',
'publication_type', 'title_sort'}
OPF_ATTRS = {'role': OPF('role'), 'file-as': OPF('file-as'),
'scheme': OPF('scheme'), 'event': OPF('event'),
'type': XSI('type'), 'lang': XML('lang'), 'id': 'id'}
@ -1199,7 +1199,7 @@ class Manifest(object):
href = urlnormalize(href)
base, ext = os.path.splitext(href)
index = 1
lhrefs = set([x.lower() for x in self.hrefs])
lhrefs = {x.lower() for x in self.hrefs}
while href.lower() in lhrefs:
href = base + str(index) + ext
index += 1
@ -1704,7 +1704,7 @@ class PageList(object):
:attr:`klass`: Optional semantic class of this page.
:attr:`id`: Optional unique identifier for this page.
"""
TYPES = set(['front', 'normal', 'special'])
TYPES = {'front', 'normal', 'special'}
def __init__(self, name, href, type='normal', klass=None, id=None):
self.name = unicode(name)

View File

@ -19,7 +19,7 @@ CASE_MANGLER_CSS = """
}
"""
TEXT_TRANSFORMS = set(['capitalize', 'uppercase', 'lowercase'])
TEXT_TRANSFORMS = {'capitalize', 'uppercase', 'lowercase'}
class CaseMangler(object):

View File

@ -19,8 +19,8 @@ from calibre.ebooks.oeb.stylizer import Stylizer
from calibre.ptempfile import PersistentTemporaryFile
from calibre.utils.imghdr import what
IMAGE_TAGS = set([XHTML('img'), XHTML('object')])
KEEP_ATTRS = set(['class', 'style', 'width', 'height', 'align'])
IMAGE_TAGS = {XHTML('img'), XHTML('object')}
KEEP_ATTRS = {'class', 'style', 'width', 'height', 'align'}
class Unavailable(Exception):

View File

@ -514,7 +514,7 @@ class AddAction(InterfaceAction):
ans = os.path.splitext(x)[1]
ans = ans[1:] if len(ans) > 1 else ans
return ans.lower()
remove = set([p for p in paths if ext(p) in ve])
remove = {p for p in paths if ext(p) in ve}
if remove:
paths = [p for p in paths if p not in remove]
vmsg = getattr(self.gui.device_manager.device, 'VIRTUAL_BOOK_EXTENSION_MESSAGE', None) or _(

View File

@ -90,7 +90,7 @@ class FetchAnnotationsAction(InterfaceAction):
paths = []
for x in ('memory', 'card_a', 'card_b'):
x = getattr(self.gui, x+'_view').model()
paths += x.paths_for_db_ids(set([id_]), as_map=True)[id_]
paths += x.paths_for_db_ids({id_}, as_map=True)[id_]
return paths[0].path if paths else None
def generate_annotation_paths(ids, db, device):

View File

@ -250,8 +250,8 @@ class Worker(Thread): # {{{
if gprefs['automerge'] == 'new record':
incoming_fmts = \
set([os.path.splitext(path)[-1].replace('.',
'').upper() for path in paths])
{os.path.splitext(path)[-1].replace('.',
'').upper() for path in paths}
if incoming_fmts.intersection(seen_fmts):
# There was at least one duplicate format

View File

@ -222,7 +222,7 @@ class DeleteAction(InterfaceAction):
bfmts = m.db.formats(id, index_is_id=True)
if bfmts is None:
continue
bfmts = set([x.lower() for x in bfmts.split(',')])
bfmts = {x.lower() for x in bfmts.split(',')}
rfmts = bfmts - set(fmts)
if bfmts - rfmts:
# Do not delete if it will leave the book with no

View File

@ -259,7 +259,7 @@ class ViewAction(InterfaceAction):
except:
error_dialog(self.gui, _('Cannot view'),
_('This book no longer exists in your library'), show=True)
self.update_history([], remove=set([id_]))
self.update_history([], remove={id_})
continue
title = db.title(id_, index_is_id=True)

View File

@ -25,7 +25,7 @@ class PluginWidget(QWidget, Ui_Form):
]
sync_enabled = False
formats = set(['bib'])
formats = {'bib'}
def __init__(self, parent=None):
QWidget.__init__(self, parent)

View File

@ -38,7 +38,7 @@ class PluginWidget(QWidget,Ui_Form):
sync_enabled = True
# Formats supported by this plugin
formats = set(['azw3','epub','mobi'])
formats = {'azw3','epub','mobi'}
def __init__(self, parent=None):
QWidget.__init__(self, parent)

View File

@ -62,8 +62,8 @@ class LookAndFeelWidget(Widget, Ui_Form):
w = getattr(self, 'filter_css_%s'%key)
if w.isChecked():
ans = ans.union(item)
ans = ans.union(set([x.strip().lower() for x in
unicode(self.filter_css_others.text()).split(',')]))
ans = ans.union({x.strip().lower() for x in
unicode(self.filter_css_others.text()).split(',')})
return ','.join(ans) if ans else None
if g is self.opt_font_size_mapping:
val = unicode(g.text()).strip()

View File

@ -1334,10 +1334,10 @@ class BulkText(BulkBase):
else:
txt = rtext
if txt:
remove = set([v.strip() for v in txt.split(ism['ui_to_list'])])
remove = {v.strip() for v in txt.split(ism['ui_to_list'])}
txt = adding
if txt:
add = set([v.strip() for v in txt.split(ism['ui_to_list'])])
add = {v.strip() for v in txt.split(ism['ui_to_list'])}
else:
add = set()
self.db.set_custom_bulk_multiple(book_ids, add=add,

View File

@ -353,9 +353,9 @@ class CheckLibraryDialog(QDialog):
item = tl.child(i)
id = int(item.data(0, Qt.UserRole))
all = self.db.formats(id, index_is_id=True, verify_formats=False)
all = set([f.strip() for f in all.split(',')]) if all else set()
all = {f.strip() for f in all.split(',')} if all else set()
valid = self.db.formats(id, index_is_id=True, verify_formats=True)
valid = set([f.strip() for f in valid.split(',')]) if valid else set()
valid = {f.strip() for f in valid.split(',')} if valid else set()
for fmt in all-valid:
self.db.remove_format(id, fmt, index_is_id=True, db_only=True)

View File

@ -351,8 +351,8 @@ class JobManager(QAbstractTableModel, AdaptSQP): # {{{
self._kill_job(job)
def universal_set(self):
return set([i for i, j in enumerate(self.jobs) if not getattr(j,
'hidden_in_gui', False)])
return {i for i, j in enumerate(self.jobs) if not getattr(j,
'hidden_in_gui', False)}
def get_matches(self, location, query, candidates=None):
if candidates is None:

View File

@ -641,7 +641,7 @@ class BooksModel(QAbstractTableModel): # {{{
if not fmts:
fmts = ''
db_formats = set(fmts.lower().split(','))
available_formats = set([f.lower() for f in formats])
available_formats = {f.lower() for f in formats}
u = available_formats.intersection(db_formats)
for f in formats:
if f.lower() in u:
@ -697,7 +697,7 @@ class BooksModel(QAbstractTableModel): # {{{
if not fmts:
fmts = ''
db_formats = set(fmts.lower().split(','))
available_formats = set([f.lower() for f in formats])
available_formats = {f.lower() for f in formats}
u = available_formats.intersection(db_formats)
for f in formats:
if f.lower() in u:
@ -1104,7 +1104,7 @@ class BooksModel(QAbstractTableModel): # {{{
return True
id = self.db.id(row)
books_to_refresh = set([id])
books_to_refresh = {id}
books_to_refresh |= self.db.set_custom(id, val, extra=s_index,
label=label, num=None, append=False, notify=True,
allow_case_change=True)
@ -1153,7 +1153,7 @@ class BooksModel(QAbstractTableModel): # {{{
value if column in ('timestamp', 'pubdate')
else re.sub(u'\\s', u' ', unicode(value or '').strip()))
id = self.db.id(row)
books_to_refresh = set([id])
books_to_refresh = {id}
if column == 'rating':
val = max(0, min(int(val or 0), 10))
self.db.set_rating(id, val)
@ -1243,7 +1243,7 @@ class OnDeviceSearch(SearchQueryParser): # {{{
if location not in self.USABLE_LOCATIONS:
return set([])
matches = set([])
all_locs = set(self.USABLE_LOCATIONS) - set(['all', 'tags'])
all_locs = set(self.USABLE_LOCATIONS) - {'all', 'tags'}
locations = all_locs if location == 'all' else [location]
q = {
'title' : lambda x : getattr(x, 'title').lower(),

View File

@ -1114,8 +1114,8 @@ class BooksView(QTableView): # {{{
Select rows identified by identifiers. identifiers can be a set of ids,
row numbers or QModelIndexes.
'''
rows = set([x.row() if hasattr(x, 'row') else x for x in
identifiers])
rows = {x.row() if hasattr(x, 'row') else x for x in
identifiers}
if using_ids:
rows = set([])
identifiers = set(identifiers)

View File

@ -911,8 +911,8 @@ class FormatsManager(QWidget):
db.add_format(id_, ext, spool, notify=False,
index_is_id=True)
dbfmts = db.formats(id_, index_is_id=True)
db_extensions = set([fl.lower() for fl in (dbfmts.split(',') if dbfmts
else [])])
db_extensions = {fl.lower() for fl in (dbfmts.split(',') if dbfmts
else [])}
extensions = new_extensions.union(old_extensions)
for ext in db_extensions:
if ext not in extensions and ext in self.original_val:

View File

@ -45,10 +45,10 @@ class FieldsModel(FM): # {{{
self.endResetModel()
def commit(self):
ignored_fields = set([x for x in self.prefs['ignore_fields'] if x not in
self.overrides])
changed = set([k for k, v in self.overrides.iteritems() if v ==
Qt.Unchecked])
ignored_fields = {x for x in self.prefs['ignore_fields'] if x not in
self.overrides}
changed = {k for k, v in self.overrides.iteritems() if v ==
Qt.Unchecked}
self.prefs['ignore_fields'] = list(ignored_fields.union(changed))
# }}}

View File

@ -140,7 +140,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
input_map = prefs['input_format_order']
all_formats = set()
self.opt_input_order.clear()
for fmt in all_input_formats().union(set(['ZIP', 'RAR'])):
for fmt in all_input_formats().union({'ZIP', 'RAR'}):
all_formats.add(fmt.upper())
for format in input_map + list(all_formats.difference(input_map)):
item = QListWidgetItem(format, self.opt_input_order)

View File

@ -239,9 +239,9 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
if not config_cols:
config_cols = ['title']
removed_cols = set(model.column_map) - set(config_cols)
hidden_cols = set([unicode(self.opt_columns.item(i, 0).data(Qt.UserRole) or '')
hidden_cols = {unicode(self.opt_columns.item(i, 0).data(Qt.UserRole) or '')
for i in range(self.opt_columns.rowCount())
if self.opt_columns.item(i, 0).checkState()==Qt.Unchecked])
if self.opt_columns.item(i, 0).checkState()==Qt.Unchecked}
hidden_cols = hidden_cols.union(removed_cols) # Hide removed cols
hidden_cols = list(hidden_cols.intersection(set(model.column_map)))
if 'ondevice' in hidden_cols:

View File

@ -479,14 +479,14 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
r('tags_browser_collapse_at', gprefs)
r('tag_browser_dont_collapse', gprefs, setting=CommaSeparatedList)
choices = set([k for k in db.field_metadata.all_field_keys()
choices = {k for k in db.field_metadata.all_field_keys()
if (db.field_metadata[k]['is_category'] and (
db.field_metadata[k]['datatype'] in ['text', 'series', 'enumeration'
]) and not db.field_metadata[k]['display'].get('is_names', False)) or (
db.field_metadata[k]['datatype'] in ['composite'
] and db.field_metadata[k]['display'].get('make_category', False))])
choices -= set(['authors', 'publisher', 'formats', 'news', 'identifiers'])
choices |= set(['search'])
] and db.field_metadata[k]['display'].get('make_category', False))}
choices -= {'authors', 'publisher', 'formats', 'news', 'identifiers'}
choices |= {'search'}
self.opt_categories_using_hierarchy.update_items_cache(choices)
r('categories_using_hierarchy', db.prefs, setting=CommaSeparatedList,
choices=sorted(list(choices), key=sort_key))

View File

@ -233,10 +233,10 @@ class FieldsModel(QAbstractListModel): # {{{
return ret
def commit(self):
ignored_fields = set([x for x in msprefs['ignore_fields'] if x not in
self.overrides])
changed = set([k for k, v in self.overrides.iteritems() if v ==
Qt.Unchecked])
ignored_fields = {x for x in msprefs['ignore_fields'] if x not in
self.overrides}
changed = {k for k, v in self.overrides.iteritems() if v ==
Qt.Unchecked}
msprefs['ignore_fields'] = list(ignored_fields.union(changed))
def user_default_state(self, field):
@ -249,10 +249,10 @@ class FieldsModel(QAbstractListModel): # {{{
self.endResetModel()
def commit_user_defaults(self):
default_ignored_fields = set([x for x in msprefs['user_default_ignore_fields'] if x not in
self.overrides])
changed = set([k for k, v in self.overrides.iteritems() if v ==
Qt.Unchecked])
default_ignored_fields = {x for x in msprefs['user_default_ignore_fields'] if x not in
self.overrides}
changed = {k for k, v in self.overrides.iteritems() if v ==
Qt.Unchecked}
msprefs['user_default_ignore_fields'] = list(default_ignored_fields.union(changed))
# }}}

View File

@ -292,7 +292,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
names = self.all_actions.model().names(x)
if names:
not_added = self.current_actions.model().add(names)
ns = set([y.name for y in not_added])
ns = {y.name for y in not_added}
added = set(names) - ns
self.all_actions.model().remove(x, added)
if not_added:
@ -311,7 +311,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
names = self.current_actions.model().names(x)
if names:
not_removed = self.current_actions.model().remove(x)
ns = set([y.name for y in not_removed])
ns = {y.name for y in not_removed}
removed = set(names) - ns
self.all_actions.model().add(removed)
if not_removed:

View File

@ -230,7 +230,7 @@ class SearchFilter(SearchQueryParser):
if location not in self.USABLE_LOCATIONS:
return set([])
matches = set([])
all_locs = set(self.USABLE_LOCATIONS) - set(['all'])
all_locs = set(self.USABLE_LOCATIONS) - {'all'}
locations = all_locs if location == 'all' else [location]
q = {
'affiliate': lambda x: x.affiliate,

View File

@ -392,7 +392,7 @@ class SearchFilter(SearchQueryParser):
if location not in self.USABLE_LOCATIONS:
return set([])
matches = set([])
all_locs = set(self.USABLE_LOCATIONS) - set(['all'])
all_locs = set(self.USABLE_LOCATIONS) - {'all'}
locations = all_locs if location == 'all' else [location]
q = {
'affiliate': attrgetter('affiliate'),

View File

@ -152,7 +152,7 @@ class SearchFilter(SearchQueryParser):
if location not in self.USABLE_LOCATIONS:
return set([])
matches = set([])
all_locs = set(self.USABLE_LOCATIONS) - set(['all'])
all_locs = set(self.USABLE_LOCATIONS) - {'all'}
locations = all_locs if location == 'all' else [location]
q = {
'author': lambda x: x.author.lower(),

View File

@ -745,7 +745,7 @@ class TagsModel(QAbstractItemModel): # {{{
return ans
def dropMimeData(self, md, action, row, column, parent):
fmts = set([unicode(x) for x in md.formats()])
fmts = {unicode(x) for x in md.formats()}
if not fmts.intersection(set(self.mimeTypes())):
return False
if "application/calibre+from_library" in fmts:
@ -880,7 +880,7 @@ class TagsModel(QAbstractItemModel): # {{{
cat_contents = categories.get(on_node.category_key[1:], None)
if cat_contents is None:
return
cat_contents = set([(v, c) for v,c,ign in cat_contents])
cat_contents = {(v, c) for v,c,ign in cat_contents}
fm_src = self.db.metadata_for_field(column)
label = fm_src['label']
@ -903,7 +903,7 @@ class TagsModel(QAbstractItemModel): # {{{
if value:
if not isinstance(value, list):
value = [value]
cat_contents |= set([(v, column) for v in value])
cat_contents |= {(v, column) for v in value}
categories[on_node.category_key[1:]] = [[v, c, 0] for v,c in cat_contents]
self.db.new_api.set_pref('user_categories', categories)

View File

@ -264,7 +264,7 @@ class ResultCache(SearchQueryParser): # {{{
# Search functions {{{
def universal_set(self):
return set([i[0] for i in self._data if i is not None])
return {i[0] for i in self._data if i is not None}
def change_search_locations(self, locations):
self.sqp_change_locations(locations)

View File

@ -27,7 +27,7 @@ class BIBTEX(CatalogPlugin):
supported_platforms = ['windows', 'osx', 'linux']
author = 'Sengian'
version = (1, 0, 0)
file_types = set(['bib'])
file_types = {'bib'}
cli_options = [
Option('--fields',

View File

@ -24,7 +24,7 @@ class CSV_XML(CatalogPlugin):
supported_platforms = ['windows', 'osx', 'linux']
author = 'Greg Riker'
version = (1, 0, 0)
file_types = set(['csv', 'xml'])
file_types = {'csv', 'xml'}
cli_options = [
Option('--fields',

View File

@ -31,7 +31,7 @@ class EPUB_MOBI(CatalogPlugin):
minimum_calibre_version = (0, 7, 40)
author = 'Greg Riker'
version = (1, 0, 0)
file_types = set(['azw3', 'epub', 'mobi'])
file_types = {'azw3', 'epub', 'mobi'}
THUMB_SMALLEST = "1.0"
THUMB_LARGEST = "2.0"

View File

@ -26,9 +26,9 @@ class CustomColumns(object):
@property
def custom_tables(self):
return set([x[0] for x in self.conn.get(
return {x[0] for x in self.conn.get(
'SELECT name FROM sqlite_master WHERE type="table" AND '
'(name GLOB "custom_column_*" OR name GLOB "books_custom_column_*")')])
'(name GLOB "custom_column_*" OR name GLOB "books_custom_column_*")')}
def __init__(self):
# Verify that CUSTOM_DATA_TYPES is a (possibly improper) subset of
@ -361,7 +361,7 @@ class CustomColumns(object):
ans = self.conn.get('SELECT value FROM %s'%table)
else:
ans = self.conn.get('SELECT DISTINCT value FROM %s'%table)
ans = set([x[0] for x in ans])
ans = {x[0] for x in ans}
return ans
def delete_custom_column(self, label=None, num=None):
@ -509,7 +509,7 @@ class CustomColumns(object):
rv = self._set_custom(id, val, label=label, num=num, append=append,
notify=notify, extra=extra,
allow_case_change=allow_case_change)
self.dirtied(set([id])|rv, commit=False)
self.dirtied({id}|rv, commit=False)
if commit:
self.conn.commit()
return rv
@ -590,7 +590,7 @@ class CustomColumns(object):
if case_change:
bks = self.conn.get('SELECT book FROM %s WHERE value=?'%lt,
(xid,))
books_to_refresh |= set([bk[0] for bk in bks])
books_to_refresh |= {bk[0] for bk in bks}
nval = self.conn.get(
'SELECT custom_%s FROM meta2 WHERE id=?'%data['num'],
(id_,), all=False)

View File

@ -1255,7 +1255,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
formats = self.conn.get('SELECT DISTINCT format from data')
if not formats:
return set([])
return set([f[0] for f in formats])
return {f[0] for f in formats}
def format_files(self, index, index_is_id=False):
id = index if index_is_id else self.id(index)
@ -2494,7 +2494,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
if case_change:
bks = self.conn.get('''SELECT book FROM books_authors_link
WHERE author=?''', (aid,))
books_to_refresh |= set([bk[0] for bk in bks])
books_to_refresh |= {bk[0] for bk in bks}
for bk in books_to_refresh:
ss = self.author_sort_from_book(id, index_is_id=True)
aus = self.author_sort(bk, index_is_id=True)
@ -2534,7 +2534,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
self.windows_check_if_files_in_use(id)
books_to_refresh = self._set_authors(id, authors,
allow_case_change=allow_case_change)
self.dirtied(set([id])|books_to_refresh, commit=False)
self.dirtied({id}|books_to_refresh, commit=False)
if commit:
self.conn.commit()
self.set_path(id, index_is_id=True)
@ -2599,7 +2599,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
FROM books_languages_link WHERE
books_languages_link.lang_code=languages.id) < 1''')
books_to_refresh = set([book_id])
books_to_refresh = {book_id}
final_languages = []
for l in languages:
lc = canonicalize_lang(l)
@ -2676,12 +2676,12 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
if case_change:
bks = self.conn.get('''SELECT book FROM books_publishers_link
WHERE publisher=?''', (aid,))
books_to_refresh |= set([bk[0] for bk in bks])
books_to_refresh |= {bk[0] for bk in bks}
self.conn.execute('''DELETE FROM publishers WHERE (SELECT COUNT(id)
FROM books_publishers_link
WHERE publisher=publishers.id) < 1''')
self.dirtied(set([id])|books_to_refresh, commit=False)
self.dirtied({id}|books_to_refresh, commit=False)
if commit:
self.conn.commit()
self.data.set(id, self.FIELD_MAP['publisher'], publisher, row_is_id=True)
@ -2990,7 +2990,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
(id,), all=True)
if not result:
return set([])
return set([r[0] for r in result])
return {r[0] for r in result}
@classmethod
def cleanup_tags(cls, tags):
@ -3123,10 +3123,10 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
if case_changed:
bks = self.conn.get('SELECT book FROM books_tags_link WHERE tag=?',
(tid,))
books_to_refresh |= set([bk[0] for bk in bks])
books_to_refresh |= {bk[0] for bk in bks}
self.conn.execute('''DELETE FROM tags WHERE (SELECT COUNT(id)
FROM books_tags_link WHERE tag=tags.id) < 1''')
self.dirtied(set([id])|books_to_refresh, commit=False)
self.dirtied({id}|books_to_refresh, commit=False)
if commit:
self.conn.commit()
tags = u','.join(self.get_tags(id))
@ -3202,7 +3202,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
if case_change:
bks = self.conn.get('SELECT book FROM books_series_link WHERE series=?',
(aid,))
books_to_refresh |= set([bk[0] for bk in bks])
books_to_refresh |= {bk[0] for bk in bks}
self.conn.execute('''DELETE FROM series
WHERE (SELECT COUNT(id) FROM books_series_link
WHERE series=series.id) < 1''')
@ -3598,7 +3598,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
for x in items:
path_map[x.lower()] = x
items = set(path_map)
paths = set([x.lower() for x in paths])
paths = {x.lower() for x in paths}
items = items.intersection(paths)
return items, path_map

View File

@ -1221,7 +1221,7 @@ class BuiltinListUnion(BuiltinFormatterFunction):
def evaluate(self, formatter, kwargs, mi, locals, list1, list2, separator):
res = [l.strip() for l in list1.split(separator) if l.strip()]
l2 = [l.strip() for l in list2.split(separator) if l.strip()]
lcl1 = set([icu_lower(l) for l in res])
lcl1 = {icu_lower(l) for l in res}
for i in l2:
if icu_lower(i) not in lcl1 and i not in res:
@ -1242,7 +1242,7 @@ class BuiltinListDifference(BuiltinFormatterFunction):
def evaluate(self, formatter, kwargs, mi, locals, list1, list2, separator):
l1 = [l.strip() for l in list1.split(separator) if l.strip()]
l2 = set([icu_lower(l.strip()) for l in list2.split(separator) if l.strip()])
l2 = {icu_lower(l.strip()) for l in list2.split(separator) if l.strip()}
res = []
for i in l1:
@ -1264,7 +1264,7 @@ class BuiltinListIntersection(BuiltinFormatterFunction):
def evaluate(self, formatter, kwargs, mi, locals, list1, list2, separator):
l1 = [l.strip() for l in list1.split(separator) if l.strip()]
l2 = set([icu_lower(l.strip()) for l in list2.split(separator) if l.strip()])
l2 = {icu_lower(l.strip()) for l in list2.split(separator) if l.strip()}
res = []
for i in l1:
@ -1303,8 +1303,8 @@ class BuiltinListEquals(BuiltinFormatterFunction):
'The comparison is case insensitive.')
def evaluate(self, formatter, kwargs, mi, locals, list1, sep1, list2, sep2, yes_val, no_val):
s1 = set([icu_lower(l.strip()) for l in list1.split(sep1) if l.strip()])
s2 = set([icu_lower(l.strip()) for l in list2.split(sep2) if l.strip()])
s1 = {icu_lower(l.strip()) for l in list1.split(sep1) if l.strip()}
s2 = {icu_lower(l.strip()) for l in list2.split(sep2) if l.strip()}
if s1 == s2:
return yes_val
return no_val

View File

@ -302,27 +302,27 @@ class Tester(SearchQueryParser):
}
tests = {
'Dysfunction' : set([348]),
'title:Dysfunction' : set([348]),
'Title:Dysfunction' : set([348]),
'title:Dysfunction OR author:Laurie': set([348, 444]),
'(tag:txt or tag:pdf)': set([33, 258, 354, 305, 242, 51, 55, 56, 154]),
'(tag:txt OR tag:pdf) and author:Tolstoy': set([55, 56]),
'Tolstoy txt': set([55, 56]),
'Dysfunction' : {348},
'title:Dysfunction' : {348},
'Title:Dysfunction' : {348},
'title:Dysfunction OR author:Laurie': {348, 444},
'(tag:txt or tag:pdf)': {33, 258, 354, 305, 242, 51, 55, 56, 154},
'(tag:txt OR tag:pdf) and author:Tolstoy': {55, 56},
'Tolstoy txt': {55, 56},
'Hamilton Amsterdam' : set([]),
u'Beär' : set([91]),
'dysfunc or tolstoy': set([348, 55, 56]),
'tag:txt AND NOT tolstoy': set([33, 258, 354, 305, 242, 154]),
'not tag:lrf' : set([305]),
'london:thames': set([13]),
'publisher:london:thames': set([13]),
'"(1977)"': set([13]),
'jack weatherford orc': set([30]),
u'Beär' : {91},
'dysfunc or tolstoy': {348, 55, 56},
'tag:txt AND NOT tolstoy': {33, 258, 354, 305, 242, 154},
'not tag:lrf' : {305},
'london:thames': {13},
'publisher:london:thames': {13},
'"(1977)"': {13},
'jack weatherford orc': {30},
'S\\"calzi': {343},
'author:S\\"calzi': {343},
'"S\\"calzi"': {343},
'M\\\\cMurtry': {427},
'author:Tolstoy (tag:txt OR tag:pdf)': set([55, 56]),
'author:Tolstoy (tag:txt OR tag:pdf)': {55, 56},
}
fields = {'title':0, 'author':1, 'publisher':2, 'tag':3}

View File

@ -522,9 +522,9 @@ class _FeedParserMixin:
}
_matchnamespaces = {}
can_be_relative_uri = set(['link', 'id', 'wfw_comment', 'wfw_commentrss', 'docs', 'url', 'href', 'comments', 'icon', 'logo'])
can_contain_relative_uris = set(['content', 'title', 'summary', 'info', 'tagline', 'subtitle', 'copyright', 'rights', 'description'])
can_contain_dangerous_markup = set(['content', 'title', 'summary', 'info', 'tagline', 'subtitle', 'copyright', 'rights', 'description'])
can_be_relative_uri = {'link', 'id', 'wfw_comment', 'wfw_commentrss', 'docs', 'url', 'href', 'comments', 'icon', 'logo'}
can_contain_relative_uris = {'content', 'title', 'summary', 'info', 'tagline', 'subtitle', 'copyright', 'rights', 'description'}
can_contain_dangerous_markup = {'content', 'title', 'summary', 'info', 'tagline', 'subtitle', 'copyright', 'rights', 'description'}
html_types = [u'text/html', u'application/xhtml+xml']
def __init__(self, baseuri=None, baselang=None, encoding=u'utf-8'):
@ -1859,11 +1859,11 @@ if _XML_AVAILABLE:
class _BaseHTMLProcessor(sgmllib.SGMLParser):
special = re.compile('''[<>'"]''')
bare_ampersand = re.compile("&(?!#\d+;|#x[0-9a-fA-F]+;|\w+;)")
elements_no_end_tag = set([
elements_no_end_tag = {
'area', 'base', 'basefont', 'br', 'col', 'command', 'embed', 'frame',
'hr', 'img', 'input', 'isindex', 'keygen', 'link', 'meta', 'param',
'source', 'track', 'wbr'
])
}
def __init__(self, encoding, _type):
self.encoding = encoding
@ -2080,8 +2080,8 @@ class _MicroformatsParser:
NODE = 4
EMAIL = 5
known_xfn_relationships = set(['contact', 'acquaintance', 'friend', 'met', 'co-worker', 'coworker', 'colleague', 'co-resident', 'coresident', 'neighbor', 'child', 'parent', 'sibling', 'brother', 'sister', 'spouse', 'wife', 'husband', 'kin', 'relative', 'muse', 'crush', 'date', 'sweetheart', 'me'])
known_binary_extensions = set(['zip','rar','exe','gz','tar','tgz','tbz2','bz2','z','7z','dmg','img','sit','sitx','hqx','deb','rpm','bz2','jar','rar','iso','bin','msi','mp2','mp3','ogg','ogm','mp4','m4v','m4a','avi','wma','wmv'])
known_xfn_relationships = {'contact', 'acquaintance', 'friend', 'met', 'co-worker', 'coworker', 'colleague', 'co-resident', 'coresident', 'neighbor', 'child', 'parent', 'sibling', 'brother', 'sister', 'spouse', 'wife', 'husband', 'kin', 'relative', 'muse', 'crush', 'date', 'sweetheart', 'me'}
known_binary_extensions = {'zip','rar','exe','gz','tar','tgz','tbz2','bz2','z','7z','dmg','img','sit','sitx','hqx','deb','rpm','bz2','jar','rar','iso','bin','msi','mp2','mp3','ogg','ogm','mp4','m4v','m4a','avi','wma','wmv'}
def __init__(self, data, baseuri, encoding):
self.document = BeautifulSoup.BeautifulSoup(data)
@ -2514,7 +2514,7 @@ def _parseMicroformats(htmlSource, baseURI, encoding):
return {"tags": p.tags, "enclosures": p.enclosures, "xfn": p.xfn, "vcard": p.vcard}
class _RelativeURIResolver(_BaseHTMLProcessor):
relative_uris = set([('a', 'href'),
relative_uris = {('a', 'href'),
('applet', 'codebase'),
('area', 'href'),
('blockquote', 'cite'),
@ -2539,7 +2539,7 @@ class _RelativeURIResolver(_BaseHTMLProcessor):
('object', 'usemap'),
('q', 'cite'),
('script', 'src'),
('video', 'poster')])
('video', 'poster')}
def __init__(self, baseuri, encoding, _type):
_BaseHTMLProcessor.__init__(self, encoding, _type)
@ -2584,7 +2584,7 @@ def _makeSafeAbsoluteURI(base, rel=None):
return uri
class _HTMLSanitizer(_BaseHTMLProcessor):
acceptable_elements = set(['a', 'abbr', 'acronym', 'address', 'area',
acceptable_elements = {'a', 'abbr', 'acronym', 'address', 'area',
'article', 'aside', 'audio', 'b', 'big', 'blockquote', 'br', 'button',
'canvas', 'caption', 'center', 'cite', 'code', 'col', 'colgroup',
'command', 'datagrid', 'datalist', 'dd', 'del', 'details', 'dfn',
@ -2596,9 +2596,9 @@ class _HTMLSanitizer(_BaseHTMLProcessor):
'p', 'pre', 'progress', 'q', 's', 'samp', 'section', 'select',
'small', 'sound', 'source', 'spacer', 'span', 'strike', 'strong',
'sub', 'sup', 'table', 'tbody', 'td', 'textarea', 'time', 'tfoot',
'th', 'thead', 'tr', 'tt', 'u', 'ul', 'var', 'video', 'noscript'])
'th', 'thead', 'tr', 'tt', 'u', 'ul', 'var', 'video', 'noscript'}
acceptable_attributes = set(['abbr', 'accept', 'accept-charset', 'accesskey',
acceptable_attributes = {'abbr', 'accept', 'accept-charset', 'accesskey',
'action', 'align', 'alt', 'autocomplete', 'autofocus', 'axis',
'background', 'balance', 'bgcolor', 'bgproperties', 'border',
'bordercolor', 'bordercolordark', 'bordercolorlight', 'bottompadding',
@ -2619,11 +2619,11 @@ class _HTMLSanitizer(_BaseHTMLProcessor):
'src', 'start', 'step', 'summary', 'suppress', 'tabindex', 'target',
'template', 'title', 'toppadding', 'type', 'unselectable', 'usemap',
'urn', 'valign', 'value', 'variable', 'volume', 'vspace', 'vrml',
'width', 'wrap', 'xml:lang'])
'width', 'wrap', 'xml:lang'}
unacceptable_elements_with_end_tag = set(['script', 'applet', 'style'])
unacceptable_elements_with_end_tag = {'script', 'applet', 'style'}
acceptable_css_properties = set(['azimuth', 'background-color',
acceptable_css_properties = {'azimuth', 'background-color',
'border-bottom-color', 'border-collapse', 'border-color',
'border-left-color', 'border-right-color', 'border-top-color', 'clear',
'color', 'cursor', 'direction', 'display', 'elevation', 'float', 'font',
@ -2633,26 +2633,26 @@ class _HTMLSanitizer(_BaseHTMLProcessor):
'speak', 'speak-header', 'speak-numeral', 'speak-punctuation',
'speech-rate', 'stress', 'text-align', 'text-decoration', 'text-indent',
'unicode-bidi', 'vertical-align', 'voice-family', 'volume',
'white-space', 'width'])
'white-space', 'width'}
# survey of common keywords found in feeds
acceptable_css_keywords = set(['auto', 'aqua', 'black', 'block', 'blue',
acceptable_css_keywords = {'auto', 'aqua', 'black', 'block', 'blue',
'bold', 'both', 'bottom', 'brown', 'center', 'collapse', 'dashed',
'dotted', 'fuchsia', 'gray', 'green', '!important', 'italic', 'left',
'lime', 'maroon', 'medium', 'none', 'navy', 'normal', 'nowrap', 'olive',
'pointer', 'purple', 'red', 'right', 'solid', 'silver', 'teal', 'top',
'transparent', 'underline', 'white', 'yellow'])
'transparent', 'underline', 'white', 'yellow'}
valid_css_values = re.compile('^(#[0-9a-f]+|rgb\(\d+%?,\d*%?,?\d*%?\)?|' +
'\d{0,2}\.?\d{0,2}(cm|em|ex|in|mm|pc|pt|px|%|,|\))?)$')
mathml_elements = set(['annotation', 'annotation-xml', 'maction', 'math',
mathml_elements = {'annotation', 'annotation-xml', 'maction', 'math',
'merror', 'mfenced', 'mfrac', 'mi', 'mmultiscripts', 'mn', 'mo', 'mover', 'mpadded',
'mphantom', 'mprescripts', 'mroot', 'mrow', 'mspace', 'msqrt', 'mstyle',
'msub', 'msubsup', 'msup', 'mtable', 'mtd', 'mtext', 'mtr', 'munder',
'munderover', 'none', 'semantics'])
'munderover', 'none', 'semantics'}
mathml_attributes = set(['actiontype', 'align', 'columnalign', 'columnalign',
mathml_attributes = {'actiontype', 'align', 'columnalign', 'columnalign',
'columnalign', 'close', 'columnlines', 'columnspacing', 'columnspan', 'depth',
'display', 'displaystyle', 'encoding', 'equalcolumns', 'equalrows',
'fence', 'fontstyle', 'fontweight', 'frame', 'height', 'linethickness',
@ -2660,18 +2660,18 @@ class _HTMLSanitizer(_BaseHTMLProcessor):
'maxsize', 'minsize', 'open', 'other', 'rowalign', 'rowalign', 'rowalign',
'rowlines', 'rowspacing', 'rowspan', 'rspace', 'scriptlevel', 'selection',
'separator', 'separators', 'stretchy', 'width', 'width', 'xlink:href',
'xlink:show', 'xlink:type', 'xmlns', 'xmlns:xlink'])
'xlink:show', 'xlink:type', 'xmlns', 'xmlns:xlink'}
# svgtiny - foreignObject + linearGradient + radialGradient + stop
svg_elements = set(['a', 'animate', 'animateColor', 'animateMotion',
svg_elements = {'a', 'animate', 'animateColor', 'animateMotion',
'animateTransform', 'circle', 'defs', 'desc', 'ellipse', 'foreignObject',
'font-face', 'font-face-name', 'font-face-src', 'g', 'glyph', 'hkern',
'linearGradient', 'line', 'marker', 'metadata', 'missing-glyph', 'mpath',
'path', 'polygon', 'polyline', 'radialGradient', 'rect', 'set', 'stop',
'svg', 'switch', 'text', 'title', 'tspan', 'use'])
'svg', 'switch', 'text', 'title', 'tspan', 'use'}
# svgtiny + class + opacity + offset + xmlns + xmlns:xlink
svg_attributes = set(['accent-height', 'accumulate', 'additive', 'alphabetic',
svg_attributes = {'accent-height', 'accumulate', 'additive', 'alphabetic',
'arabic-form', 'ascent', 'attributeName', 'attributeType',
'baseProfile', 'bbox', 'begin', 'by', 'calcMode', 'cap-height',
'class', 'color', 'color-rendering', 'content', 'cx', 'cy', 'd', 'dx',
@ -2697,14 +2697,14 @@ class _HTMLSanitizer(_BaseHTMLProcessor):
'widths', 'x', 'x-height', 'x1', 'x2', 'xlink:actuate', 'xlink:arcrole',
'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type',
'xml:base', 'xml:lang', 'xml:space', 'xmlns', 'xmlns:xlink', 'y', 'y1',
'y2', 'zoomAndPan'])
'y2', 'zoomAndPan'}
svg_attr_map = None
svg_elem_map = None
acceptable_svg_properties = set([ 'fill', 'fill-opacity', 'fill-rule',
acceptable_svg_properties = { 'fill', 'fill-opacity', 'fill-rule',
'stroke', 'stroke-width', 'stroke-linecap', 'stroke-linejoin',
'stroke-opacity'])
'stroke-opacity'}
def reset(self):
_BaseHTMLProcessor.reset(self)