mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-08-11 09:13:57 -04:00
Apply the PEP8 blank line standards to the entire codebase
This commit is contained in:
parent
9306c28228
commit
e333001d31
@ -7,6 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
Lokalavisen Aabenraa
|
Lokalavisen Aabenraa
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class AabenraaLokalavisen_dk(BasicNewsRecipe):
|
class AabenraaLokalavisen_dk(BasicNewsRecipe):
|
||||||
__author__ = 'CoderAllan.github.com'
|
__author__ = 'CoderAllan.github.com'
|
||||||
title = 'Lokalavisen Aabenraa'
|
title = 'Lokalavisen Aabenraa'
|
||||||
|
@ -7,6 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
Lokalavisen Aarhus
|
Lokalavisen Aarhus
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class AarhusLokalavisen_dk(BasicNewsRecipe):
|
class AarhusLokalavisen_dk(BasicNewsRecipe):
|
||||||
__author__ = 'CoderAllan.github.com'
|
__author__ = 'CoderAllan.github.com'
|
||||||
title = 'Lokalavisen Aarhus'
|
title = 'Lokalavisen Aarhus'
|
||||||
|
@ -7,6 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
Lokalavisen Aarhus Midt
|
Lokalavisen Aarhus Midt
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class AarhusmidtLokalavisen_dk(BasicNewsRecipe):
|
class AarhusmidtLokalavisen_dk(BasicNewsRecipe):
|
||||||
__author__ = 'CoderAllan.github.com'
|
__author__ = 'CoderAllan.github.com'
|
||||||
title = 'Lokalavisen Aarhus Midt'
|
title = 'Lokalavisen Aarhus Midt'
|
||||||
|
@ -7,6 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
Lokalavisen Aarhus Nord
|
Lokalavisen Aarhus Nord
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class AarhusnordLokalavisen_dk(BasicNewsRecipe):
|
class AarhusnordLokalavisen_dk(BasicNewsRecipe):
|
||||||
__author__ = 'CoderAllan.github.com'
|
__author__ = 'CoderAllan.github.com'
|
||||||
title = 'Lokalavisen Aarhus Nord'
|
title = 'Lokalavisen Aarhus Nord'
|
||||||
|
@ -7,6 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
Lokalavisen Aarhus Syd
|
Lokalavisen Aarhus Syd
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class AarhussydLokalavisen_dk(BasicNewsRecipe):
|
class AarhussydLokalavisen_dk(BasicNewsRecipe):
|
||||||
__author__ = 'CoderAllan.github.com'
|
__author__ = 'CoderAllan.github.com'
|
||||||
title = 'Lokalavisen Aarhus Syd'
|
title = 'Lokalavisen Aarhus Syd'
|
||||||
|
@ -7,6 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
Lokalavisen Aarhus Ves
|
Lokalavisen Aarhus Ves
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class AarhusvestLokalavisen_dk(BasicNewsRecipe):
|
class AarhusvestLokalavisen_dk(BasicNewsRecipe):
|
||||||
__author__ = 'CoderAllan.github.com'
|
__author__ = 'CoderAllan.github.com'
|
||||||
title = 'Lokalavisen Aarhus Ves'
|
title = 'Lokalavisen Aarhus Ves'
|
||||||
|
@ -7,6 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
Albertslund Posten
|
Albertslund Posten
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class AlbertslundLokalavisen_dk(BasicNewsRecipe):
|
class AlbertslundLokalavisen_dk(BasicNewsRecipe):
|
||||||
__author__ = 'CoderAllan.github.com'
|
__author__ = 'CoderAllan.github.com'
|
||||||
title = 'Albertslund Posten'
|
title = 'Albertslund Posten'
|
||||||
|
@ -7,6 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
Allerød Nyt: RSS feed: Seneste nyt - alleroed.lokalavisen.dk
|
Allerød Nyt: RSS feed: Seneste nyt - alleroed.lokalavisen.dk
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class AlleroedLokalavisen_dk(BasicNewsRecipe):
|
class AlleroedLokalavisen_dk(BasicNewsRecipe):
|
||||||
__author__ = 'CoderAllan.github.com'
|
__author__ = 'CoderAllan.github.com'
|
||||||
title = 'Allerød Nyt - alleroed.lokalavisen.dk'
|
title = 'Allerød Nyt - alleroed.lokalavisen.dk'
|
||||||
|
@ -7,6 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
Alt om DATA, Datatid TechLife - Download, test, antivirus, netværk
|
Alt om DATA, Datatid TechLife - Download, test, antivirus, netværk
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class WwwAltomdata_dk(BasicNewsRecipe):
|
class WwwAltomdata_dk(BasicNewsRecipe):
|
||||||
__author__ = 'CoderAllan.github.com'
|
__author__ = 'CoderAllan.github.com'
|
||||||
title = 'Alt om DATA, Datatid TechLife - Download, test, antivirus, netværk'
|
title = 'Alt om DATA, Datatid TechLife - Download, test, antivirus, netværk'
|
||||||
|
@ -7,6 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
Amagerbladet
|
Amagerbladet
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class Amagerbladet_dk(BasicNewsRecipe):
|
class Amagerbladet_dk(BasicNewsRecipe):
|
||||||
__author__ = 'CoderAllan.github.com'
|
__author__ = 'CoderAllan.github.com'
|
||||||
title = 'Amagerbladet'
|
title = 'Amagerbladet'
|
||||||
|
@ -7,6 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
Avisen.dk
|
Avisen.dk
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class WwwAvisen_dk(BasicNewsRecipe):
|
class WwwAvisen_dk(BasicNewsRecipe):
|
||||||
__author__ = 'CoderAllan.github.com'
|
__author__ = 'CoderAllan.github.com'
|
||||||
title = 'Avisen.dk'
|
title = 'Avisen.dk'
|
||||||
|
@ -7,6 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
City Avisen
|
City Avisen
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class CityAvisen_dk(BasicNewsRecipe):
|
class CityAvisen_dk(BasicNewsRecipe):
|
||||||
__author__ = 'CoderAllan.github.com'
|
__author__ = 'CoderAllan.github.com'
|
||||||
title = 'City Avisen'
|
title = 'City Avisen'
|
||||||
|
@ -7,6 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
Computerworld.dk
|
Computerworld.dk
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class WwwComputerworld_dk(BasicNewsRecipe):
|
class WwwComputerworld_dk(BasicNewsRecipe):
|
||||||
__author__ = 'CoderAllan.github.com'
|
__author__ = 'CoderAllan.github.com'
|
||||||
title = 'Computerworld.dk'
|
title = 'Computerworld.dk'
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
from calibre.web.feeds.news import BasicNewsRecipe
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
|
|
||||||
class AdvancedUserRecipe(BasicNewsRecipe):
|
class AdvancedUserRecipe(BasicNewsRecipe):
|
||||||
title = u'Contropiano'
|
title = u'Contropiano'
|
||||||
oldest_article = 7
|
oldest_article = 7
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
from __future__ import unicode_literals, division, absolute_import, print_function
|
from __future__ import unicode_literals, division, absolute_import, print_function
|
||||||
from calibre.web.feeds.news import BasicNewsRecipe
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
|
|
||||||
class AdvancedUserRecipe1468055030(BasicNewsRecipe):
|
class AdvancedUserRecipe1468055030(BasicNewsRecipe):
|
||||||
title = 'DataNews'
|
title = 'DataNews'
|
||||||
__author__ = 'oCkz7bJ_'
|
__author__ = 'oCkz7bJ_'
|
||||||
|
@ -4,6 +4,7 @@ from __future__ import unicode_literals, division, absolute_import, print_functi
|
|||||||
import re
|
import re
|
||||||
from calibre.web.feeds.news import BasicNewsRecipe
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
|
|
||||||
class AdvancedUserRecipe1467571059(BasicNewsRecipe):
|
class AdvancedUserRecipe1467571059(BasicNewsRecipe):
|
||||||
title = 'De Standaard'
|
title = 'De Standaard'
|
||||||
__author__ = 'Darko Miletic, Aimylios, oCkz7bJ_'
|
__author__ = 'Darko Miletic, Aimylios, oCkz7bJ_'
|
||||||
|
@ -7,6 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
DjurslandsPosten
|
DjurslandsPosten
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class DjurslandsPosten_dk(BasicNewsRecipe):
|
class DjurslandsPosten_dk(BasicNewsRecipe):
|
||||||
__author__ = 'CoderAllan.github.com'
|
__author__ = 'CoderAllan.github.com'
|
||||||
title = 'DjurslandsPosten'
|
title = 'DjurslandsPosten'
|
||||||
|
@ -9,6 +9,7 @@ __copyright__ = '2010, Darko Miletic <darko.miletic at gmail.com>'
|
|||||||
DR.dk
|
DR.dk
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class DRNyheder(BasicNewsRecipe):
|
class DRNyheder(BasicNewsRecipe):
|
||||||
title = 'DR Nyheder'
|
title = 'DR Nyheder'
|
||||||
__author__ = 'Darko Miletic'
|
__author__ = 'Darko Miletic'
|
||||||
|
@ -7,6 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
Adresseavisen Ebeltoft
|
Adresseavisen Ebeltoft
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class EbeltoftLokalavisen_dk(BasicNewsRecipe):
|
class EbeltoftLokalavisen_dk(BasicNewsRecipe):
|
||||||
__author__ = 'CoderAllan.github.com'
|
__author__ = 'CoderAllan.github.com'
|
||||||
title = 'Adresseavisen Ebeltoft'
|
title = 'Adresseavisen Ebeltoft'
|
||||||
|
@ -7,6 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
Lokalavisen Egedal
|
Lokalavisen Egedal
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class EgedalLokalavisen_dk(BasicNewsRecipe):
|
class EgedalLokalavisen_dk(BasicNewsRecipe):
|
||||||
__author__ = 'CoderAllan.github.com'
|
__author__ = 'CoderAllan.github.com'
|
||||||
title = 'Lokalavisen Egedal'
|
title = 'Lokalavisen Egedal'
|
||||||
|
@ -6,6 +6,7 @@ eluniversal.com.mx
|
|||||||
|
|
||||||
from calibre.web.feeds.news import BasicNewsRecipe
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
|
|
||||||
class ElUniversal(BasicNewsRecipe):
|
class ElUniversal(BasicNewsRecipe):
|
||||||
title = 'El Universal'
|
title = 'El Universal'
|
||||||
__author__ = 'Darko Miletic'
|
__author__ = 'Darko Miletic'
|
||||||
|
@ -6,6 +6,7 @@ http://www.eltribuno.info/salta/edicion_impresa.aspx
|
|||||||
|
|
||||||
from calibre.web.feeds.news import BasicNewsRecipe
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
|
|
||||||
class ElTribunoSaltaImpreso(BasicNewsRecipe):
|
class ElTribunoSaltaImpreso(BasicNewsRecipe):
|
||||||
title = 'El Tribuno Salta'
|
title = 'El Tribuno Salta'
|
||||||
__author__ = 'Darko Miletic'
|
__author__ = 'Darko Miletic'
|
||||||
|
@ -7,6 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
Erhvervs•Avisen: RSS feed: Seneste nyt - erhvervsavisen.dk
|
Erhvervs•Avisen: RSS feed: Seneste nyt - erhvervsavisen.dk
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class Erhvervsavisen_dk(BasicNewsRecipe):
|
class Erhvervsavisen_dk(BasicNewsRecipe):
|
||||||
__author__ = 'CoderAllan.github.com'
|
__author__ = 'CoderAllan.github.com'
|
||||||
title = 'Erhvervs Avisen'
|
title = 'Erhvervs Avisen'
|
||||||
|
@ -7,6 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
Lokalavisen Esbjerg: RSS feed: Seneste nyt - esbjerg.lokalavisen.dk
|
Lokalavisen Esbjerg: RSS feed: Seneste nyt - esbjerg.lokalavisen.dk
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class EsbjergLokalavisen_dk(BasicNewsRecipe):
|
class EsbjergLokalavisen_dk(BasicNewsRecipe):
|
||||||
__author__ = 'CoderAllan.github.com'
|
__author__ = 'CoderAllan.github.com'
|
||||||
title = 'Lokalavisen Esbjerg'
|
title = 'Lokalavisen Esbjerg'
|
||||||
|
@ -7,6 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
Favrskov Avisen
|
Favrskov Avisen
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class FavrskovAvisen_dk(BasicNewsRecipe):
|
class FavrskovAvisen_dk(BasicNewsRecipe):
|
||||||
__author__ = 'CoderAllan.github.com'
|
__author__ = 'CoderAllan.github.com'
|
||||||
title = 'Favrskov Avisen'
|
title = 'Favrskov Avisen'
|
||||||
|
@ -7,6 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
Favrskovposten
|
Favrskovposten
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class FavrskovLokalavisen_dk(BasicNewsRecipe):
|
class FavrskovLokalavisen_dk(BasicNewsRecipe):
|
||||||
__author__ = 'CoderAllan.github.com'
|
__author__ = 'CoderAllan.github.com'
|
||||||
title = 'Favrskovposten'
|
title = 'Favrskovposten'
|
||||||
|
@ -7,6 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
Folkebladet
|
Folkebladet
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class Folkebladet_dk(BasicNewsRecipe):
|
class Folkebladet_dk(BasicNewsRecipe):
|
||||||
__author__ = 'CoderAllan.github.com'
|
__author__ = 'CoderAllan.github.com'
|
||||||
title = 'Folkebladet'
|
title = 'Folkebladet'
|
||||||
|
@ -7,6 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
Folkebladet Djursland
|
Folkebladet Djursland
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class FolkebladetDjursland_dk(BasicNewsRecipe):
|
class FolkebladetDjursland_dk(BasicNewsRecipe):
|
||||||
__author__ = 'CoderAllan.github.com'
|
__author__ = 'CoderAllan.github.com'
|
||||||
title = 'Folkebladet Djursland'
|
title = 'Folkebladet Djursland'
|
||||||
|
@ -7,6 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
folketidende.dk
|
folketidende.dk
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class Folketidende_dk(BasicNewsRecipe):
|
class Folketidende_dk(BasicNewsRecipe):
|
||||||
__author__ = 'CoderAllan.github.com'
|
__author__ = 'CoderAllan.github.com'
|
||||||
title = 'folketidende.dk'
|
title = 'folketidende.dk'
|
||||||
|
@ -7,6 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
Uge-Nyt
|
Uge-Nyt
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class FredensborgLokalavisen_dk(BasicNewsRecipe):
|
class FredensborgLokalavisen_dk(BasicNewsRecipe):
|
||||||
__author__ = 'CoderAllan.github.com'
|
__author__ = 'CoderAllan.github.com'
|
||||||
title = 'Uge-Nyt'
|
title = 'Uge-Nyt'
|
||||||
|
@ -7,6 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
Lokalavisen Fredericia
|
Lokalavisen Fredericia
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class FredericiaLokalavisen_dk(BasicNewsRecipe):
|
class FredericiaLokalavisen_dk(BasicNewsRecipe):
|
||||||
__author__ = 'CoderAllan.github.com'
|
__author__ = 'CoderAllan.github.com'
|
||||||
title = 'Lokalavisen Fredericia'
|
title = 'Lokalavisen Fredericia'
|
||||||
|
@ -7,6 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
Frederiksberg Bladet
|
Frederiksberg Bladet
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class FrederiksbergBladet_dk(BasicNewsRecipe):
|
class FrederiksbergBladet_dk(BasicNewsRecipe):
|
||||||
__author__ = 'CoderAllan.github.com'
|
__author__ = 'CoderAllan.github.com'
|
||||||
title = 'Frederiksberg Bladet'
|
title = 'Frederiksberg Bladet'
|
||||||
|
@ -7,6 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
Lokalavisen Frederikssund
|
Lokalavisen Frederikssund
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class FrederikssundLokalavisen_dk(BasicNewsRecipe):
|
class FrederikssundLokalavisen_dk(BasicNewsRecipe):
|
||||||
__author__ = 'CoderAllan.github.com'
|
__author__ = 'CoderAllan.github.com'
|
||||||
title = 'Lokalavisen Frederikssund'
|
title = 'Lokalavisen Frederikssund'
|
||||||
|
@ -7,6 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
Furesø Avis
|
Furesø Avis
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class FuresoeLokalavisen_dk(BasicNewsRecipe):
|
class FuresoeLokalavisen_dk(BasicNewsRecipe):
|
||||||
__author__ = 'CoderAllan.github.com'
|
__author__ = 'CoderAllan.github.com'
|
||||||
title = 'Furesø Avis'
|
title = 'Furesø Avis'
|
||||||
|
@ -7,6 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
Villabyerne
|
Villabyerne
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class GentofteLokalavisen_dk(BasicNewsRecipe):
|
class GentofteLokalavisen_dk(BasicNewsRecipe):
|
||||||
__author__ = 'CoderAllan.github.com'
|
__author__ = 'CoderAllan.github.com'
|
||||||
title = 'Villabyerne'
|
title = 'Villabyerne'
|
||||||
|
@ -7,6 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
Lokalavisen Grenaa
|
Lokalavisen Grenaa
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class GrenaaLokalavisen_dk(BasicNewsRecipe):
|
class GrenaaLokalavisen_dk(BasicNewsRecipe):
|
||||||
__author__ = 'CoderAllan.github.com'
|
__author__ = 'CoderAllan.github.com'
|
||||||
title = 'Lokalavisen Grenaa'
|
title = 'Lokalavisen Grenaa'
|
||||||
|
@ -7,6 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
Ugeposten Gribskov
|
Ugeposten Gribskov
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class GribskovLokalavisen_dk(BasicNewsRecipe):
|
class GribskovLokalavisen_dk(BasicNewsRecipe):
|
||||||
__author__ = 'CoderAllan.github.com'
|
__author__ = 'CoderAllan.github.com'
|
||||||
title = 'Ugeposten Gribskov'
|
title = 'Ugeposten Gribskov'
|
||||||
|
@ -7,6 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
Lokalavisen Haderslev
|
Lokalavisen Haderslev
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class HaderslevLokalavisen_dk(BasicNewsRecipe):
|
class HaderslevLokalavisen_dk(BasicNewsRecipe):
|
||||||
__author__ = 'CoderAllan.github.com'
|
__author__ = 'CoderAllan.github.com'
|
||||||
title = 'Lokalavisen Haderslev'
|
title = 'Lokalavisen Haderslev'
|
||||||
|
@ -7,6 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
Halsnæs Avis
|
Halsnæs Avis
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class HalsnaesLokalavisen_dk(BasicNewsRecipe):
|
class HalsnaesLokalavisen_dk(BasicNewsRecipe):
|
||||||
__author__ = 'CoderAllan.github.com'
|
__author__ = 'CoderAllan.github.com'
|
||||||
title = 'Halsnæs Avis'
|
title = 'Halsnæs Avis'
|
||||||
|
@ -7,6 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
Hillerød Posten
|
Hillerød Posten
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class HilleroedLokalavisen_dk(BasicNewsRecipe):
|
class HilleroedLokalavisen_dk(BasicNewsRecipe):
|
||||||
__author__ = 'CoderAllan.github.com'
|
__author__ = 'CoderAllan.github.com'
|
||||||
title = 'Hillerød Posten'
|
title = 'Hillerød Posten'
|
||||||
|
@ -7,6 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
Ugebladet
|
Ugebladet
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class HoersholmLokalavisen_dk(BasicNewsRecipe):
|
class HoersholmLokalavisen_dk(BasicNewsRecipe):
|
||||||
__author__ = 'CoderAllan.github.com'
|
__author__ = 'CoderAllan.github.com'
|
||||||
title = 'Ugebladet'
|
title = 'Ugebladet'
|
||||||
|
@ -7,6 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
Lokalavisen Hornsherred
|
Lokalavisen Hornsherred
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class HornsherredLokalavisen_dk(BasicNewsRecipe):
|
class HornsherredLokalavisen_dk(BasicNewsRecipe):
|
||||||
__author__ = 'CoderAllan.github.com'
|
__author__ = 'CoderAllan.github.com'
|
||||||
title = 'Lokalavisen Hornsherred'
|
title = 'Lokalavisen Hornsherred'
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
from __future__ import unicode_literals, division, absolute_import, print_function
|
from __future__ import unicode_literals, division, absolute_import, print_function
|
||||||
from calibre.web.feeds.news import BasicNewsRecipe
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
|
|
||||||
class Hvidovre_Avis_dk(BasicNewsRecipe):
|
class Hvidovre_Avis_dk(BasicNewsRecipe):
|
||||||
title = 'Hvidovre avis'
|
title = 'Hvidovre avis'
|
||||||
language = 'da'
|
language = 'da'
|
||||||
|
@ -7,6 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
Hvidovre Avis
|
Hvidovre Avis
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class HvidovreLokalavisen_dk(BasicNewsRecipe):
|
class HvidovreLokalavisen_dk(BasicNewsRecipe):
|
||||||
__author__ = 'CoderAllan.github.com'
|
__author__ = 'CoderAllan.github.com'
|
||||||
title = 'Hvidovre Avis'
|
title = 'Hvidovre Avis'
|
||||||
|
@ -6,6 +6,8 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
'''
|
'''
|
||||||
Ingeniøren.dk
|
Ingeniøren.dk
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class Ing_dk(BasicNewsRecipe):
|
class Ing_dk(BasicNewsRecipe):
|
||||||
__author__ = 'CoderAllan.github.com'
|
__author__ = 'CoderAllan.github.com'
|
||||||
title = 'Ingeniøren'
|
title = 'Ingeniøren'
|
||||||
|
@ -12,6 +12,7 @@ http://www.jotdown.es/
|
|||||||
import re
|
import re
|
||||||
from calibre.web.feeds.news import BasicNewsRecipe
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
|
|
||||||
class jotdown(BasicNewsRecipe):
|
class jotdown(BasicNewsRecipe):
|
||||||
author = 'desUBIKado'
|
author = 'desUBIKado'
|
||||||
description = 'Revista digital con magníficos y extensos artículos'
|
description = 'Revista digital con magníficos y extensos artículos'
|
||||||
|
@ -7,6 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
JydskeVestkysten | JV.dk | jv.dk
|
JydskeVestkysten | JV.dk | jv.dk
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class WwwJv_dk(BasicNewsRecipe):
|
class WwwJv_dk(BasicNewsRecipe):
|
||||||
__author__ = 'CoderAllan.github.com'
|
__author__ = 'CoderAllan.github.com'
|
||||||
title = 'JydskeVestkysten | JV.dk | jv.dk'
|
title = 'JydskeVestkysten | JV.dk | jv.dk'
|
||||||
|
@ -7,6 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
Lokalavisen Kalø Vig
|
Lokalavisen Kalø Vig
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class KaloevigLokalavisen_dk(BasicNewsRecipe):
|
class KaloevigLokalavisen_dk(BasicNewsRecipe):
|
||||||
__author__ = 'CoderAllan.github.com'
|
__author__ = 'CoderAllan.github.com'
|
||||||
title = 'Lokalavisen Kalø Vig'
|
title = 'Lokalavisen Kalø Vig'
|
||||||
|
@ -7,6 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
Kgs. Enghave Bladet
|
Kgs. Enghave Bladet
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class KgsEnghaveBladet_dk(BasicNewsRecipe):
|
class KgsEnghaveBladet_dk(BasicNewsRecipe):
|
||||||
__author__ = 'CoderAllan.github.com'
|
__author__ = 'CoderAllan.github.com'
|
||||||
title = 'Kgs. Enghave Bladet'
|
title = 'Kgs. Enghave Bladet'
|
||||||
|
@ -7,6 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
Lørdagsavisen
|
Lørdagsavisen
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class KoegeLokalavisen_dk(BasicNewsRecipe):
|
class KoegeLokalavisen_dk(BasicNewsRecipe):
|
||||||
__author__ = 'CoderAllan.github.com'
|
__author__ = 'CoderAllan.github.com'
|
||||||
title = 'Lørdagsavisen'
|
title = 'Lørdagsavisen'
|
||||||
|
@ -7,6 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
Lokalavisen Kolding
|
Lokalavisen Kolding
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class KoldingLokalavisen_dk(BasicNewsRecipe):
|
class KoldingLokalavisen_dk(BasicNewsRecipe):
|
||||||
__author__ = 'CoderAllan.github.com'
|
__author__ = 'CoderAllan.github.com'
|
||||||
title = 'Lokalavisen Kolding'
|
title = 'Lokalavisen Kolding'
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
from __future__ import unicode_literals, division, absolute_import, print_function
|
from __future__ import unicode_literals, division, absolute_import, print_function
|
||||||
from calibre.web.feeds.news import BasicNewsRecipe
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
|
|
||||||
class KristeligtDagblad(BasicNewsRecipe):
|
class KristeligtDagblad(BasicNewsRecipe):
|
||||||
title = 'Kristeligt Dagblad'
|
title = 'Kristeligt Dagblad'
|
||||||
language = 'da'
|
language = 'da'
|
||||||
|
@ -4,6 +4,7 @@ __author__ = 'Daniele Forsi'
|
|||||||
|
|
||||||
from calibre.web.feeds.recipes import BasicNewsRecipe
|
from calibre.web.feeds.recipes import BasicNewsRecipe
|
||||||
|
|
||||||
|
|
||||||
class LeScienze(BasicNewsRecipe):
|
class LeScienze(BasicNewsRecipe):
|
||||||
title = 'Le Scienze'
|
title = 'Le Scienze'
|
||||||
description = 'Edizione italiana di Scientific American'
|
description = 'Edizione italiana di Scientific American'
|
||||||
|
@ -7,6 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
Det grønne område
|
Det grønne område
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class Lyngby_taarbaekLokalavisen_dk(BasicNewsRecipe):
|
class Lyngby_taarbaekLokalavisen_dk(BasicNewsRecipe):
|
||||||
__author__ = 'CoderAllan.github.com'
|
__author__ = 'CoderAllan.github.com'
|
||||||
title = 'Det grønne område'
|
title = 'Det grønne område'
|
||||||
|
@ -7,6 +7,7 @@ www.nakedcapitalism.com
|
|||||||
|
|
||||||
from calibre.web.feeds.news import BasicNewsRecipe
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
|
|
||||||
class nakedcapitalism(BasicNewsRecipe):
|
class nakedcapitalism(BasicNewsRecipe):
|
||||||
title = 'Naked Capitalism'
|
title = 'Naked Capitalism'
|
||||||
__author__ = 'Darko Miletic'
|
__author__ = 'Darko Miletic'
|
||||||
|
@ -7,6 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
Nørrebro Nordvest bladet
|
Nørrebro Nordvest bladet
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class Minby_dk(BasicNewsRecipe):
|
class Minby_dk(BasicNewsRecipe):
|
||||||
__author__ = 'CoderAllan.github.com'
|
__author__ = 'CoderAllan.github.com'
|
||||||
title = 'Nørrebro Nordvest bladet'
|
title = 'Nørrebro Nordvest bladet'
|
||||||
|
@ -7,6 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
Lokalavisen Norddjurs
|
Lokalavisen Norddjurs
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class NorddjursLokalavisen_dk(BasicNewsRecipe):
|
class NorddjursLokalavisen_dk(BasicNewsRecipe):
|
||||||
__author__ = 'CoderAllan.github.com'
|
__author__ = 'CoderAllan.github.com'
|
||||||
title = 'Lokalavisen Norddjurs'
|
title = 'Lokalavisen Norddjurs'
|
||||||
|
@ -7,6 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
Nordjyske.dk
|
Nordjyske.dk
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class Nordjyske_dk(BasicNewsRecipe):
|
class Nordjyske_dk(BasicNewsRecipe):
|
||||||
__author__ = 'CoderAllan.github.com'
|
__author__ = 'CoderAllan.github.com'
|
||||||
title = 'Nordjyske.dk'
|
title = 'Nordjyske.dk'
|
||||||
|
@ -7,6 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
Lokalavisen Odense
|
Lokalavisen Odense
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class OdenseLokalavisen_dk(BasicNewsRecipe):
|
class OdenseLokalavisen_dk(BasicNewsRecipe):
|
||||||
__author__ = 'CoderAllan.github.com'
|
__author__ = 'CoderAllan.github.com'
|
||||||
title = 'Lokalavisen Odense'
|
title = 'Lokalavisen Odense'
|
||||||
|
@ -7,6 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
Østerbro Avis
|
Østerbro Avis
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class OesterbroAvis_dk(BasicNewsRecipe):
|
class OesterbroAvis_dk(BasicNewsRecipe):
|
||||||
__author__ = 'CoderAllan.github.com'
|
__author__ = 'CoderAllan.github.com'
|
||||||
title = 'Østerbro Avis'
|
title = 'Østerbro Avis'
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import re
|
import re
|
||||||
from calibre.web.feeds.news import BasicNewsRecipe
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
|
|
||||||
class AdvancedUserRecipe1359406781(BasicNewsRecipe):
|
class AdvancedUserRecipe1359406781(BasicNewsRecipe):
|
||||||
title = u'Private Eye'
|
title = u'Private Eye'
|
||||||
publication_type = 'magazine'
|
publication_type = 'magazine'
|
||||||
|
@ -7,6 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
Din avis Randers
|
Din avis Randers
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class RandersLokalavisen_dk(BasicNewsRecipe):
|
class RandersLokalavisen_dk(BasicNewsRecipe):
|
||||||
__author__ = 'CoderAllan.github.com'
|
__author__ = 'CoderAllan.github.com'
|
||||||
title = 'Din avis Randers'
|
title = 'Din avis Randers'
|
||||||
|
@ -14,6 +14,7 @@ import lxml
|
|||||||
from lxml.builder import E
|
from lxml.builder import E
|
||||||
respekt_url = 'http://www.respekt.cz'
|
respekt_url = 'http://www.respekt.cz'
|
||||||
|
|
||||||
|
|
||||||
class respektRecipe(BasicNewsRecipe):
|
class respektRecipe(BasicNewsRecipe):
|
||||||
__author__ = 'Tomáš Hnyk'
|
__author__ = 'Tomáš Hnyk'
|
||||||
publisher = u'Respekt Publishing a. s.'
|
publisher = u'Respekt Publishing a. s.'
|
||||||
|
@ -7,6 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
Roskilde Avis
|
Roskilde Avis
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class RoskildeLokalavisen_dk(BasicNewsRecipe):
|
class RoskildeLokalavisen_dk(BasicNewsRecipe):
|
||||||
__author__ = 'CoderAllan.github.com'
|
__author__ = 'CoderAllan.github.com'
|
||||||
title = 'Roskilde Avis'
|
title = 'Roskilde Avis'
|
||||||
|
@ -7,6 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
Rudersdal Avis
|
Rudersdal Avis
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class RudersdalLokalavisen_dk(BasicNewsRecipe):
|
class RudersdalLokalavisen_dk(BasicNewsRecipe):
|
||||||
__author__ = 'CoderAllan.github.com'
|
__author__ = 'CoderAllan.github.com'
|
||||||
title = 'Rudersdal Avis'
|
title = 'Rudersdal Avis'
|
||||||
|
@ -7,6 +7,7 @@ sciencedaily.com
|
|||||||
|
|
||||||
from calibre.web.feeds.news import BasicNewsRecipe
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
|
|
||||||
class ScienceDaily(BasicNewsRecipe):
|
class ScienceDaily(BasicNewsRecipe):
|
||||||
title = u'ScienceDaily'
|
title = u'ScienceDaily'
|
||||||
__author__ = u'Darko Miletic'
|
__author__ = u'Darko Miletic'
|
||||||
|
@ -7,6 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
Lokalavisen Skanderborg
|
Lokalavisen Skanderborg
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class SkanderborgLokalavisen_dk(BasicNewsRecipe):
|
class SkanderborgLokalavisen_dk(BasicNewsRecipe):
|
||||||
__author__ = 'CoderAllan.github.com'
|
__author__ = 'CoderAllan.github.com'
|
||||||
title = 'Lokalavisen Skanderborg'
|
title = 'Lokalavisen Skanderborg'
|
||||||
|
@ -7,6 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
sn.dk
|
sn.dk
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class Sn_dk(BasicNewsRecipe):
|
class Sn_dk(BasicNewsRecipe):
|
||||||
__author__ = 'CoderAllan.github.com'
|
__author__ = 'CoderAllan.github.com'
|
||||||
title = 'sn.dk'
|
title = 'sn.dk'
|
||||||
|
@ -7,6 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
Lokalavisen Sønderborg
|
Lokalavisen Sønderborg
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class SoenderborgLokalavisen_dk(BasicNewsRecipe):
|
class SoenderborgLokalavisen_dk(BasicNewsRecipe):
|
||||||
__author__ = 'CoderAllan.github.com'
|
__author__ = 'CoderAllan.github.com'
|
||||||
title = 'Lokalavisen Sønderborg'
|
title = 'Lokalavisen Sønderborg'
|
||||||
|
@ -7,6 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
Adresseavisen Syddjurs
|
Adresseavisen Syddjurs
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class SyddjursLokalavisen_dk(BasicNewsRecipe):
|
class SyddjursLokalavisen_dk(BasicNewsRecipe):
|
||||||
__author__ = 'CoderAllan.github.com'
|
__author__ = 'CoderAllan.github.com'
|
||||||
title = 'Adresseavisen Syddjurs'
|
title = 'Adresseavisen Syddjurs'
|
||||||
|
@ -9,11 +9,13 @@ http://www.theaustralian.news.com.au/
|
|||||||
|
|
||||||
from calibre.web.feeds.news import BasicNewsRecipe
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
|
|
||||||
def classes(classes):
|
def classes(classes):
|
||||||
q = frozenset(classes.split(' '))
|
q = frozenset(classes.split(' '))
|
||||||
return dict(attrs={
|
return dict(attrs={
|
||||||
'class': lambda x: x and frozenset(x.split()).intersection(q)})
|
'class': lambda x: x and frozenset(x.split()).intersection(q)})
|
||||||
|
|
||||||
|
|
||||||
class DailyTelegraph(BasicNewsRecipe):
|
class DailyTelegraph(BasicNewsRecipe):
|
||||||
title = u'The Australian'
|
title = u'The Australian'
|
||||||
__author__ = u'Kovid Goyal'
|
__author__ = u'Kovid Goyal'
|
||||||
|
@ -7,6 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
Valby Bladet
|
Valby Bladet
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class ValbyBladet_dk(BasicNewsRecipe):
|
class ValbyBladet_dk(BasicNewsRecipe):
|
||||||
__author__ = 'CoderAllan.github.com'
|
__author__ = 'CoderAllan.github.com'
|
||||||
title = 'Valby Bladet'
|
title = 'Valby Bladet'
|
||||||
|
@ -7,6 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
Vanløse Bladet
|
Vanløse Bladet
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class VanloeseBladet_dk(BasicNewsRecipe):
|
class VanloeseBladet_dk(BasicNewsRecipe):
|
||||||
__author__ = 'CoderAllan.github.com'
|
__author__ = 'CoderAllan.github.com'
|
||||||
title = 'Vanløse Bladet'
|
title = 'Vanløse Bladet'
|
||||||
|
@ -7,6 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
Lokalavisen Varde
|
Lokalavisen Varde
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class VardeLokalavisen_dk(BasicNewsRecipe):
|
class VardeLokalavisen_dk(BasicNewsRecipe):
|
||||||
__author__ = 'CoderAllan.github.com'
|
__author__ = 'CoderAllan.github.com'
|
||||||
title = 'Lokalavisen Varde'
|
title = 'Lokalavisen Varde'
|
||||||
|
@ -7,6 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
Lokalavisen Vejle
|
Lokalavisen Vejle
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class VejleLokalavisen_dk(BasicNewsRecipe):
|
class VejleLokalavisen_dk(BasicNewsRecipe):
|
||||||
__author__ = 'CoderAllan.github.com'
|
__author__ = 'CoderAllan.github.com'
|
||||||
title = 'Lokalavisen Vejle'
|
title = 'Lokalavisen Vejle'
|
||||||
|
@ -7,6 +7,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
Vesterbro Bladet
|
Vesterbro Bladet
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class VesterbroBladet_dk(BasicNewsRecipe):
|
class VesterbroBladet_dk(BasicNewsRecipe):
|
||||||
__author__ = 'CoderAllan.github.com'
|
__author__ = 'CoderAllan.github.com'
|
||||||
title = 'Vesterbro Bladet'
|
title = 'Vesterbro Bladet'
|
||||||
|
@ -11,6 +11,7 @@ http://www.weblogssl.com/
|
|||||||
import re
|
import re
|
||||||
from calibre.web.feeds.news import BasicNewsRecipe
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
|
|
||||||
class weblogssl(BasicNewsRecipe):
|
class weblogssl(BasicNewsRecipe):
|
||||||
__author__ = 'desUBIKado'
|
__author__ = 'desUBIKado'
|
||||||
description = u'Weblogs colectivos dedicados a seguir la actualidad sobre tecnologia, entretenimiento, estilos de vida, motor, deportes y economia.'
|
description = u'Weblogs colectivos dedicados a seguir la actualidad sobre tecnologia, entretenimiento, estilos de vida, motor, deportes y economia.'
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
[flake8]
|
[flake8]
|
||||||
max-line-length = 160
|
max-line-length = 160
|
||||||
builtins = _,dynamic_property,__,P,I,lopen,icu_lower,icu_upper,icu_title,ngettext
|
builtins = _,dynamic_property,__,P,I,lopen,icu_lower,icu_upper,icu_title,ngettext
|
||||||
ignore = E12,E203,E22,E231,E241,E301,E302,E304,E401,E402,E731,W391
|
ignore = E12,E203,E22,E231,E241,E401,E402,E731,W391
|
||||||
|
@ -10,12 +10,14 @@ import sys, os, json, subprocess, errno, hashlib
|
|||||||
from setup import Command, build_cache_dir
|
from setup import Command, build_cache_dir
|
||||||
import __builtin__
|
import __builtin__
|
||||||
|
|
||||||
|
|
||||||
def set_builtins(builtins):
|
def set_builtins(builtins):
|
||||||
for x in builtins:
|
for x in builtins:
|
||||||
if not hasattr(__builtin__, x):
|
if not hasattr(__builtin__, x):
|
||||||
setattr(__builtin__, x, True)
|
setattr(__builtin__, x, True)
|
||||||
yield x
|
yield x
|
||||||
|
|
||||||
|
|
||||||
class Message:
|
class Message:
|
||||||
|
|
||||||
def __init__(self, filename, lineno, msg):
|
def __init__(self, filename, lineno, msg):
|
||||||
@ -24,6 +26,7 @@ class Message:
|
|||||||
def __str__(self):
|
def __str__(self):
|
||||||
return '%s:%s: %s' % (self.filename, self.lineno, self.msg)
|
return '%s:%s: %s' % (self.filename, self.lineno, self.msg)
|
||||||
|
|
||||||
|
|
||||||
class Check(Command):
|
class Check(Command):
|
||||||
|
|
||||||
description = 'Check for errors in the calibre source code'
|
description = 'Check for errors in the calibre source code'
|
||||||
|
@ -29,18 +29,22 @@ if False:
|
|||||||
winerror, win32api, isbsd, config_dir
|
winerror, win32api, isbsd, config_dir
|
||||||
|
|
||||||
_mt_inited = False
|
_mt_inited = False
|
||||||
|
|
||||||
|
|
||||||
def _init_mimetypes():
|
def _init_mimetypes():
|
||||||
global _mt_inited
|
global _mt_inited
|
||||||
import mimetypes
|
import mimetypes
|
||||||
mimetypes.init([P('mime.types')])
|
mimetypes.init([P('mime.types')])
|
||||||
_mt_inited = True
|
_mt_inited = True
|
||||||
|
|
||||||
|
|
||||||
def guess_type(*args, **kwargs):
|
def guess_type(*args, **kwargs):
|
||||||
import mimetypes
|
import mimetypes
|
||||||
if not _mt_inited:
|
if not _mt_inited:
|
||||||
_init_mimetypes()
|
_init_mimetypes()
|
||||||
return mimetypes.guess_type(*args, **kwargs)
|
return mimetypes.guess_type(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
def guess_all_extensions(*args, **kwargs):
|
def guess_all_extensions(*args, **kwargs):
|
||||||
import mimetypes
|
import mimetypes
|
||||||
if not _mt_inited:
|
if not _mt_inited:
|
||||||
@ -57,17 +61,20 @@ def guess_extension(*args, **kwargs):
|
|||||||
ext = '.pdb'
|
ext = '.pdb'
|
||||||
return ext
|
return ext
|
||||||
|
|
||||||
|
|
||||||
def get_types_map():
|
def get_types_map():
|
||||||
import mimetypes
|
import mimetypes
|
||||||
if not _mt_inited:
|
if not _mt_inited:
|
||||||
_init_mimetypes()
|
_init_mimetypes()
|
||||||
return mimetypes.types_map
|
return mimetypes.types_map
|
||||||
|
|
||||||
|
|
||||||
def to_unicode(raw, encoding='utf-8', errors='strict'):
|
def to_unicode(raw, encoding='utf-8', errors='strict'):
|
||||||
if isinstance(raw, unicode):
|
if isinstance(raw, unicode):
|
||||||
return raw
|
return raw
|
||||||
return raw.decode(encoding, errors)
|
return raw.decode(encoding, errors)
|
||||||
|
|
||||||
|
|
||||||
def patheq(p1, p2):
|
def patheq(p1, p2):
|
||||||
p = os.path
|
p = os.path
|
||||||
d = lambda x : p.normcase(p.normpath(p.realpath(p.normpath(x))))
|
d = lambda x : p.normcase(p.normpath(p.realpath(p.normpath(x))))
|
||||||
@ -75,6 +82,7 @@ def patheq(p1, p2):
|
|||||||
return False
|
return False
|
||||||
return d(p1) == d(p2)
|
return d(p1) == d(p2)
|
||||||
|
|
||||||
|
|
||||||
def unicode_path(path, abs=False):
|
def unicode_path(path, abs=False):
|
||||||
if isinstance(path, bytes):
|
if isinstance(path, bytes):
|
||||||
path = path.decode(filesystem_encoding)
|
path = path.decode(filesystem_encoding)
|
||||||
@ -82,6 +90,7 @@ def unicode_path(path, abs=False):
|
|||||||
path = os.path.abspath(path)
|
path = os.path.abspath(path)
|
||||||
return path
|
return path
|
||||||
|
|
||||||
|
|
||||||
def osx_version():
|
def osx_version():
|
||||||
if isosx:
|
if isosx:
|
||||||
import platform
|
import platform
|
||||||
@ -90,6 +99,7 @@ def osx_version():
|
|||||||
if m:
|
if m:
|
||||||
return int(m.group(1)), int(m.group(2)), int(m.group(3))
|
return int(m.group(1)), int(m.group(2)), int(m.group(3))
|
||||||
|
|
||||||
|
|
||||||
def confirm_config_name(name):
|
def confirm_config_name(name):
|
||||||
return name + '_again'
|
return name + '_again'
|
||||||
|
|
||||||
@ -97,6 +107,7 @@ _filename_sanitize = re.compile(r'[\xae\0\\|\?\*<":>\+/]')
|
|||||||
_filename_sanitize_unicode = frozenset([u'\\', u'|', u'?', u'*', u'<',
|
_filename_sanitize_unicode = frozenset([u'\\', u'|', u'?', u'*', u'<',
|
||||||
u'"', u':', u'>', u'+', u'/'] + list(map(unichr, xrange(32))))
|
u'"', u':', u'>', u'+', u'/'] + list(map(unichr, xrange(32))))
|
||||||
|
|
||||||
|
|
||||||
def sanitize_file_name(name, substitute='_', as_unicode=False):
|
def sanitize_file_name(name, substitute='_', as_unicode=False):
|
||||||
'''
|
'''
|
||||||
Sanitize the filename `name`. All invalid characters are replaced by `substitute`.
|
Sanitize the filename `name`. All invalid characters are replaced by `substitute`.
|
||||||
@ -125,6 +136,7 @@ def sanitize_file_name(name, substitute='_', as_unicode=False):
|
|||||||
one = '_' + one[1:]
|
one = '_' + one[1:]
|
||||||
return one
|
return one
|
||||||
|
|
||||||
|
|
||||||
def sanitize_file_name_unicode(name, substitute='_'):
|
def sanitize_file_name_unicode(name, substitute='_'):
|
||||||
'''
|
'''
|
||||||
Sanitize the filename `name`. All invalid characters are replaced by `substitute`.
|
Sanitize the filename `name`. All invalid characters are replaced by `substitute`.
|
||||||
@ -151,6 +163,7 @@ def sanitize_file_name_unicode(name, substitute='_'):
|
|||||||
one = '_' + one[1:]
|
one = '_' + one[1:]
|
||||||
return one
|
return one
|
||||||
|
|
||||||
|
|
||||||
def sanitize_file_name2(name, substitute='_'):
|
def sanitize_file_name2(name, substitute='_'):
|
||||||
'''
|
'''
|
||||||
Sanitize filenames removing invalid chars. Keeps unicode names as unicode
|
Sanitize filenames removing invalid chars. Keeps unicode names as unicode
|
||||||
@ -160,6 +173,7 @@ def sanitize_file_name2(name, substitute='_'):
|
|||||||
return sanitize_file_name(name, substitute=substitute)
|
return sanitize_file_name(name, substitute=substitute)
|
||||||
return sanitize_file_name_unicode(name, substitute=substitute)
|
return sanitize_file_name_unicode(name, substitute=substitute)
|
||||||
|
|
||||||
|
|
||||||
def prints(*args, **kwargs):
|
def prints(*args, **kwargs):
|
||||||
'''
|
'''
|
||||||
Print unicode arguments safely by encoding them to preferred_encoding
|
Print unicode arguments safely by encoding them to preferred_encoding
|
||||||
@ -227,9 +241,11 @@ def prints(*args, **kwargs):
|
|||||||
count += len(sep)
|
count += len(sep)
|
||||||
return count
|
return count
|
||||||
|
|
||||||
|
|
||||||
class CommandLineError(Exception):
|
class CommandLineError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def setup_cli_handlers(logger, level):
|
def setup_cli_handlers(logger, level):
|
||||||
import logging
|
import logging
|
||||||
if os.environ.get('CALIBRE_WORKER', None) is not None and logger.handlers:
|
if os.environ.get('CALIBRE_WORKER', None) is not None and logger.handlers:
|
||||||
@ -261,6 +277,7 @@ def load_library(name, cdll):
|
|||||||
return cdll.LoadLibrary(name)
|
return cdll.LoadLibrary(name)
|
||||||
return cdll.LoadLibrary(name+'.so')
|
return cdll.LoadLibrary(name+'.so')
|
||||||
|
|
||||||
|
|
||||||
def filename_to_utf8(name):
|
def filename_to_utf8(name):
|
||||||
'''Return C{name} encoded in utf8. Unhandled characters are replaced. '''
|
'''Return C{name} encoded in utf8. Unhandled characters are replaced. '''
|
||||||
if isinstance(name, unicode):
|
if isinstance(name, unicode):
|
||||||
@ -268,6 +285,7 @@ def filename_to_utf8(name):
|
|||||||
codec = 'cp1252' if iswindows else 'utf8'
|
codec = 'cp1252' if iswindows else 'utf8'
|
||||||
return name.decode(codec, 'replace').encode('utf8')
|
return name.decode(codec, 'replace').encode('utf8')
|
||||||
|
|
||||||
|
|
||||||
def extract(path, dir):
|
def extract(path, dir):
|
||||||
extractor = None
|
extractor = None
|
||||||
# First use the file header to identify its type
|
# First use the file header to identify its type
|
||||||
@ -292,6 +310,7 @@ def extract(path, dir):
|
|||||||
raise Exception('Unknown archive type')
|
raise Exception('Unknown archive type')
|
||||||
extractor(path, dir)
|
extractor(path, dir)
|
||||||
|
|
||||||
|
|
||||||
def get_proxies(debug=True):
|
def get_proxies(debug=True):
|
||||||
from urllib import getproxies
|
from urllib import getproxies
|
||||||
proxies = getproxies()
|
proxies = getproxies()
|
||||||
@ -315,6 +334,7 @@ def get_proxies(debug=True):
|
|||||||
prints('Using proxies:', proxies)
|
prints('Using proxies:', proxies)
|
||||||
return proxies
|
return proxies
|
||||||
|
|
||||||
|
|
||||||
def get_parsed_proxy(typ='http', debug=True):
|
def get_parsed_proxy(typ='http', debug=True):
|
||||||
proxies = get_proxies(debug)
|
proxies = get_proxies(debug)
|
||||||
proxy = proxies.get(typ, None)
|
proxy = proxies.get(typ, None)
|
||||||
@ -346,6 +366,7 @@ def get_parsed_proxy(typ='http', debug=True):
|
|||||||
prints('Using http proxy', str(ans))
|
prints('Using http proxy', str(ans))
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
|
|
||||||
def get_proxy_info(proxy_scheme, proxy_string):
|
def get_proxy_info(proxy_scheme, proxy_string):
|
||||||
'''
|
'''
|
||||||
Parse all proxy information from a proxy string (as returned by
|
Parse all proxy information from a proxy string (as returned by
|
||||||
@ -372,6 +393,7 @@ def get_proxy_info(proxy_scheme, proxy_string):
|
|||||||
USER_AGENT = 'Mozilla/5.0 (Windows NT 6.1; Trident/7.0; rv:11.0) like Gecko'
|
USER_AGENT = 'Mozilla/5.0 (Windows NT 6.1; Trident/7.0; rv:11.0) like Gecko'
|
||||||
USER_AGENT_MOBILE = 'Mozilla/5.0 (Windows; U; Windows CE 5.1; rv:1.8.1a3) Gecko/20060610 Minimo/0.016'
|
USER_AGENT_MOBILE = 'Mozilla/5.0 (Windows; U; Windows CE 5.1; rv:1.8.1a3) Gecko/20060610 Minimo/0.016'
|
||||||
|
|
||||||
|
|
||||||
def random_user_agent(choose=None):
|
def random_user_agent(choose=None):
|
||||||
try:
|
try:
|
||||||
ua_list = random_user_agent.ua_list
|
ua_list = random_user_agent.ua_list
|
||||||
@ -398,6 +420,7 @@ def random_user_agent(choose=None):
|
|||||||
]
|
]
|
||||||
return random.choice(ua_list) if choose is None else ua_list[choose]
|
return random.choice(ua_list) if choose is None else ua_list[choose]
|
||||||
|
|
||||||
|
|
||||||
def browser(honor_time=True, max_time=2, mobile_browser=False, user_agent=None, use_robust_parser=False, verify_ssl_certificates=True):
|
def browser(honor_time=True, max_time=2, mobile_browser=False, user_agent=None, use_robust_parser=False, verify_ssl_certificates=True):
|
||||||
'''
|
'''
|
||||||
Create a mechanize browser for web scraping. The browser handles cookies,
|
Create a mechanize browser for web scraping. The browser handles cookies,
|
||||||
@ -431,6 +454,7 @@ def browser(honor_time=True, max_time=2, mobile_browser=False, user_agent=None,
|
|||||||
|
|
||||||
return opener
|
return opener
|
||||||
|
|
||||||
|
|
||||||
def fit_image(width, height, pwidth, pheight):
|
def fit_image(width, height, pwidth, pheight):
|
||||||
'''
|
'''
|
||||||
Fit image in box of width pwidth and height pheight.
|
Fit image in box of width pwidth and height pheight.
|
||||||
@ -453,6 +477,7 @@ def fit_image(width, height, pwidth, pheight):
|
|||||||
|
|
||||||
return scaled, int(width), int(height)
|
return scaled, int(width), int(height)
|
||||||
|
|
||||||
|
|
||||||
class CurrentDir(object):
|
class CurrentDir(object):
|
||||||
|
|
||||||
def __init__(self, path, workaround_temp_folder_permissions=False):
|
def __init__(self, path, workaround_temp_folder_permissions=False):
|
||||||
@ -481,6 +506,8 @@ class CurrentDir(object):
|
|||||||
|
|
||||||
|
|
||||||
_ncpus = None
|
_ncpus = None
|
||||||
|
|
||||||
|
|
||||||
def detect_ncpus():
|
def detect_ncpus():
|
||||||
"""Detects the number of effective CPUs in the system"""
|
"""Detects the number of effective CPUs in the system"""
|
||||||
global _ncpus
|
global _ncpus
|
||||||
@ -502,18 +529,22 @@ def detect_ncpus():
|
|||||||
|
|
||||||
relpath = os.path.relpath
|
relpath = os.path.relpath
|
||||||
_spat = re.compile(r'^the\s+|^a\s+|^an\s+', re.IGNORECASE)
|
_spat = re.compile(r'^the\s+|^a\s+|^an\s+', re.IGNORECASE)
|
||||||
|
|
||||||
|
|
||||||
def english_sort(x, y):
|
def english_sort(x, y):
|
||||||
'''
|
'''
|
||||||
Comapare two english phrases ignoring starting prepositions.
|
Comapare two english phrases ignoring starting prepositions.
|
||||||
'''
|
'''
|
||||||
return cmp(_spat.sub('', x), _spat.sub('', y))
|
return cmp(_spat.sub('', x), _spat.sub('', y))
|
||||||
|
|
||||||
|
|
||||||
def walk(dir):
|
def walk(dir):
|
||||||
''' A nice interface to os.walk '''
|
''' A nice interface to os.walk '''
|
||||||
for record in os.walk(dir):
|
for record in os.walk(dir):
|
||||||
for f in record[-1]:
|
for f in record[-1]:
|
||||||
yield os.path.join(record[0], f)
|
yield os.path.join(record[0], f)
|
||||||
|
|
||||||
|
|
||||||
def strftime(fmt, t=None):
|
def strftime(fmt, t=None):
|
||||||
''' A version of strftime that returns unicode strings and tries to handle dates
|
''' A version of strftime that returns unicode strings and tries to handle dates
|
||||||
before 1900 '''
|
before 1900 '''
|
||||||
@ -542,12 +573,14 @@ def strftime(fmt, t=None):
|
|||||||
ans = ans.replace('_early year hack##', str(orig_year))
|
ans = ans.replace('_early year hack##', str(orig_year))
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
|
|
||||||
def my_unichr(num):
|
def my_unichr(num):
|
||||||
try:
|
try:
|
||||||
return safe_chr(num)
|
return safe_chr(num)
|
||||||
except (ValueError, OverflowError):
|
except (ValueError, OverflowError):
|
||||||
return u'?'
|
return u'?'
|
||||||
|
|
||||||
|
|
||||||
def entity_to_unicode(match, exceptions=[], encoding='cp1252',
|
def entity_to_unicode(match, exceptions=[], encoding='cp1252',
|
||||||
result_exceptions={}):
|
result_exceptions={}):
|
||||||
'''
|
'''
|
||||||
@ -606,12 +639,15 @@ xml_entity_to_unicode = partial(entity_to_unicode, result_exceptions={
|
|||||||
'>' : '>',
|
'>' : '>',
|
||||||
'&' : '&'})
|
'&' : '&'})
|
||||||
|
|
||||||
|
|
||||||
def replace_entities(raw, encoding='cp1252'):
|
def replace_entities(raw, encoding='cp1252'):
|
||||||
return _ent_pat.sub(partial(entity_to_unicode, encoding=encoding), raw)
|
return _ent_pat.sub(partial(entity_to_unicode, encoding=encoding), raw)
|
||||||
|
|
||||||
|
|
||||||
def xml_replace_entities(raw, encoding='cp1252'):
|
def xml_replace_entities(raw, encoding='cp1252'):
|
||||||
return _ent_pat.sub(partial(xml_entity_to_unicode, encoding=encoding), raw)
|
return _ent_pat.sub(partial(xml_entity_to_unicode, encoding=encoding), raw)
|
||||||
|
|
||||||
|
|
||||||
def prepare_string_for_xml(raw, attribute=False):
|
def prepare_string_for_xml(raw, attribute=False):
|
||||||
raw = _ent_pat.sub(entity_to_unicode, raw)
|
raw = _ent_pat.sub(entity_to_unicode, raw)
|
||||||
raw = raw.replace('&', '&').replace('<', '<').replace('>', '>')
|
raw = raw.replace('&', '&').replace('<', '<').replace('>', '>')
|
||||||
@ -619,9 +655,11 @@ def prepare_string_for_xml(raw, attribute=False):
|
|||||||
raw = raw.replace('"', '"').replace("'", ''')
|
raw = raw.replace('"', '"').replace("'", ''')
|
||||||
return raw
|
return raw
|
||||||
|
|
||||||
|
|
||||||
def isbytestring(obj):
|
def isbytestring(obj):
|
||||||
return isinstance(obj, (str, bytes))
|
return isinstance(obj, (str, bytes))
|
||||||
|
|
||||||
|
|
||||||
def force_unicode(obj, enc=preferred_encoding):
|
def force_unicode(obj, enc=preferred_encoding):
|
||||||
if isbytestring(obj):
|
if isbytestring(obj):
|
||||||
try:
|
try:
|
||||||
@ -639,6 +677,7 @@ def force_unicode(obj, enc=preferred_encoding):
|
|||||||
obj = obj.decode('utf-8')
|
obj = obj.decode('utf-8')
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
|
|
||||||
def as_unicode(obj, enc=preferred_encoding):
|
def as_unicode(obj, enc=preferred_encoding):
|
||||||
if not isbytestring(obj):
|
if not isbytestring(obj):
|
||||||
try:
|
try:
|
||||||
@ -650,12 +689,14 @@ def as_unicode(obj, enc=preferred_encoding):
|
|||||||
obj = repr(obj)
|
obj = repr(obj)
|
||||||
return force_unicode(obj, enc=enc)
|
return force_unicode(obj, enc=enc)
|
||||||
|
|
||||||
|
|
||||||
def url_slash_cleaner(url):
|
def url_slash_cleaner(url):
|
||||||
'''
|
'''
|
||||||
Removes redundant /'s from url's.
|
Removes redundant /'s from url's.
|
||||||
'''
|
'''
|
||||||
return re.sub(r'(?<!:)/{2,}', '/', url)
|
return re.sub(r'(?<!:)/{2,}', '/', url)
|
||||||
|
|
||||||
|
|
||||||
def human_readable(size, sep=' '):
|
def human_readable(size, sep=' '):
|
||||||
""" Convert a size in bytes into a human readable form """
|
""" Convert a size in bytes into a human readable form """
|
||||||
divisor, suffix = 1, "B"
|
divisor, suffix = 1, "B"
|
||||||
@ -670,6 +711,7 @@ def human_readable(size, sep=' '):
|
|||||||
size = size[:-2]
|
size = size[:-2]
|
||||||
return size + sep + suffix
|
return size + sep + suffix
|
||||||
|
|
||||||
|
|
||||||
def remove_bracketed_text(src,
|
def remove_bracketed_text(src,
|
||||||
brackets={u'(':u')', u'[':u']', u'{':u'}'}):
|
brackets={u'(':u')', u'[':u']', u'{':u'}'}):
|
||||||
from collections import Counter
|
from collections import Counter
|
||||||
@ -688,10 +730,12 @@ def remove_bracketed_text(src,
|
|||||||
buf.append(char)
|
buf.append(char)
|
||||||
return u''.join(buf)
|
return u''.join(buf)
|
||||||
|
|
||||||
|
|
||||||
def ipython(user_ns=None):
|
def ipython(user_ns=None):
|
||||||
from calibre.utils.ipython import ipython
|
from calibre.utils.ipython import ipython
|
||||||
ipython(user_ns=user_ns)
|
ipython(user_ns=user_ns)
|
||||||
|
|
||||||
|
|
||||||
def fsync(fileobj):
|
def fsync(fileobj):
|
||||||
fileobj.flush()
|
fileobj.flush()
|
||||||
os.fsync(fileobj.fileno())
|
os.fsync(fileobj.fileno())
|
||||||
|
@ -45,6 +45,8 @@ win32api = importlib.import_module('win32api') if iswindows else None
|
|||||||
fcntl = None if iswindows else importlib.import_module('fcntl')
|
fcntl = None if iswindows else importlib.import_module('fcntl')
|
||||||
|
|
||||||
_osx_ver = None
|
_osx_ver = None
|
||||||
|
|
||||||
|
|
||||||
def get_osx_version():
|
def get_osx_version():
|
||||||
global _osx_ver
|
global _osx_ver
|
||||||
if _osx_ver is None:
|
if _osx_ver is None:
|
||||||
@ -77,12 +79,14 @@ else:
|
|||||||
|
|
||||||
DEBUG = False
|
DEBUG = False
|
||||||
|
|
||||||
|
|
||||||
def debug():
|
def debug():
|
||||||
global DEBUG
|
global DEBUG
|
||||||
DEBUG = True
|
DEBUG = True
|
||||||
|
|
||||||
_cache_dir = None
|
_cache_dir = None
|
||||||
|
|
||||||
|
|
||||||
def _get_cache_dir():
|
def _get_cache_dir():
|
||||||
confcache = os.path.join(config_dir, u'caches')
|
confcache = os.path.join(config_dir, u'caches')
|
||||||
if isportable:
|
if isportable:
|
||||||
@ -114,6 +118,7 @@ def _get_cache_dir():
|
|||||||
candidate = confcache
|
candidate = confcache
|
||||||
return candidate
|
return candidate
|
||||||
|
|
||||||
|
|
||||||
def cache_dir():
|
def cache_dir():
|
||||||
global _cache_dir
|
global _cache_dir
|
||||||
if _cache_dir is None:
|
if _cache_dir is None:
|
||||||
@ -122,6 +127,7 @@ def cache_dir():
|
|||||||
|
|
||||||
# plugins {{{
|
# plugins {{{
|
||||||
|
|
||||||
|
|
||||||
class Plugins(collections.Mapping):
|
class Plugins(collections.Mapping):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@ -231,6 +237,7 @@ else:
|
|||||||
print 'No write acces to', config_dir, 'using a temporary dir instead'
|
print 'No write acces to', config_dir, 'using a temporary dir instead'
|
||||||
import tempfile, atexit
|
import tempfile, atexit
|
||||||
config_dir = tempfile.mkdtemp(prefix='calibre-config-')
|
config_dir = tempfile.mkdtemp(prefix='calibre-config-')
|
||||||
|
|
||||||
def cleanup_cdir():
|
def cleanup_cdir():
|
||||||
try:
|
try:
|
||||||
import shutil
|
import shutil
|
||||||
@ -240,6 +247,7 @@ else:
|
|||||||
atexit.register(cleanup_cdir)
|
atexit.register(cleanup_cdir)
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
|
|
||||||
def get_version():
|
def get_version():
|
||||||
'''Return version string for display to user '''
|
'''Return version string for display to user '''
|
||||||
dv = os.environ.get('CALIBRE_DEVELOP_FROM', None)
|
dv = os.environ.get('CALIBRE_DEVELOP_FROM', None)
|
||||||
@ -253,11 +261,13 @@ def get_version():
|
|||||||
|
|
||||||
return v
|
return v
|
||||||
|
|
||||||
|
|
||||||
def get_portable_base():
|
def get_portable_base():
|
||||||
'Return path to the directory that contains calibre-portable.exe or None'
|
'Return path to the directory that contains calibre-portable.exe or None'
|
||||||
if isportable:
|
if isportable:
|
||||||
return os.path.dirname(os.path.dirname(os.environ['CALIBRE_PORTABLE_BUILD']))
|
return os.path.dirname(os.path.dirname(os.environ['CALIBRE_PORTABLE_BUILD']))
|
||||||
|
|
||||||
|
|
||||||
def get_unicode_windows_env_var(name):
|
def get_unicode_windows_env_var(name):
|
||||||
import ctypes
|
import ctypes
|
||||||
name = unicode(name)
|
name = unicode(name)
|
||||||
@ -268,6 +278,7 @@ def get_unicode_windows_env_var(name):
|
|||||||
ctypes.windll.kernel32.GetEnvironmentVariableW(name, buf, n)
|
ctypes.windll.kernel32.GetEnvironmentVariableW(name, buf, n)
|
||||||
return buf.value
|
return buf.value
|
||||||
|
|
||||||
|
|
||||||
def get_windows_username():
|
def get_windows_username():
|
||||||
'''
|
'''
|
||||||
Return the user name of the currently loggen in user as a unicode string.
|
Return the user name of the currently loggen in user as a unicode string.
|
||||||
@ -288,6 +299,7 @@ def get_windows_username():
|
|||||||
|
|
||||||
return get_unicode_windows_env_var(u'USERNAME')
|
return get_unicode_windows_env_var(u'USERNAME')
|
||||||
|
|
||||||
|
|
||||||
def get_windows_temp_path():
|
def get_windows_temp_path():
|
||||||
import ctypes
|
import ctypes
|
||||||
n = ctypes.windll.kernel32.GetTempPathW(0, None)
|
n = ctypes.windll.kernel32.GetTempPathW(0, None)
|
||||||
@ -298,6 +310,7 @@ def get_windows_temp_path():
|
|||||||
ans = buf.value
|
ans = buf.value
|
||||||
return ans if ans else None
|
return ans if ans else None
|
||||||
|
|
||||||
|
|
||||||
def get_windows_user_locale_name():
|
def get_windows_user_locale_name():
|
||||||
import ctypes
|
import ctypes
|
||||||
k32 = ctypes.windll.kernel32
|
k32 = ctypes.windll.kernel32
|
||||||
@ -310,6 +323,7 @@ def get_windows_user_locale_name():
|
|||||||
|
|
||||||
number_formats = None
|
number_formats = None
|
||||||
|
|
||||||
|
|
||||||
def get_windows_number_formats():
|
def get_windows_number_formats():
|
||||||
# This can be changed to use localeconv() once we switch to Visual Studio
|
# This can be changed to use localeconv() once we switch to Visual Studio
|
||||||
# 2015 as localeconv() in that version has unicode variants for all strings.
|
# 2015 as localeconv() in that version has unicode variants for all strings.
|
||||||
|
@ -17,6 +17,7 @@ elif isosx:
|
|||||||
class PluginNotFound(ValueError):
|
class PluginNotFound(ValueError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class InvalidPlugin(ValueError):
|
class InvalidPlugin(ValueError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@ -312,6 +313,7 @@ class Plugin(object): # {{{
|
|||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
|
|
||||||
class FileTypePlugin(Plugin): # {{{
|
class FileTypePlugin(Plugin): # {{{
|
||||||
'''
|
'''
|
||||||
A plugin that is associated with a particular set of file types.
|
A plugin that is associated with a particular set of file types.
|
||||||
@ -392,6 +394,7 @@ class FileTypePlugin(Plugin): # {{{
|
|||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
|
|
||||||
class MetadataReaderPlugin(Plugin): # {{{
|
class MetadataReaderPlugin(Plugin): # {{{
|
||||||
'''
|
'''
|
||||||
A plugin that implements reading metadata from a set of file types.
|
A plugin that implements reading metadata from a set of file types.
|
||||||
@ -422,6 +425,7 @@ class MetadataReaderPlugin(Plugin): # {{{
|
|||||||
return None
|
return None
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
|
|
||||||
class MetadataWriterPlugin(Plugin): # {{{
|
class MetadataWriterPlugin(Plugin): # {{{
|
||||||
'''
|
'''
|
||||||
A plugin that implements reading metadata from a set of file types.
|
A plugin that implements reading metadata from a set of file types.
|
||||||
@ -453,6 +457,7 @@ class MetadataWriterPlugin(Plugin): # {{{
|
|||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
|
|
||||||
class CatalogPlugin(Plugin): # {{{
|
class CatalogPlugin(Plugin): # {{{
|
||||||
'''
|
'''
|
||||||
A plugin that implements a catalog generator.
|
A plugin that implements a catalog generator.
|
||||||
@ -580,6 +585,7 @@ class CatalogPlugin(Plugin): # {{{
|
|||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
|
|
||||||
class InterfaceActionBase(Plugin): # {{{
|
class InterfaceActionBase(Plugin): # {{{
|
||||||
|
|
||||||
supported_platforms = ['windows', 'osx', 'linux']
|
supported_platforms = ['windows', 'osx', 'linux']
|
||||||
@ -607,6 +613,7 @@ class InterfaceActionBase(Plugin): # {{{
|
|||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
|
|
||||||
class PreferencesPlugin(Plugin): # {{{
|
class PreferencesPlugin(Plugin): # {{{
|
||||||
|
|
||||||
'''
|
'''
|
||||||
@ -666,6 +673,7 @@ class PreferencesPlugin(Plugin): # {{{
|
|||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
|
|
||||||
class StoreBase(Plugin): # {{{
|
class StoreBase(Plugin): # {{{
|
||||||
|
|
||||||
supported_platforms = ['windows', 'osx', 'linux']
|
supported_platforms = ['windows', 'osx', 'linux']
|
||||||
@ -715,6 +723,7 @@ class StoreBase(Plugin): # {{{
|
|||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
|
|
||||||
class ViewerPlugin(Plugin): # {{{
|
class ViewerPlugin(Plugin): # {{{
|
||||||
|
|
||||||
type = _('Viewer')
|
type = _('Viewer')
|
||||||
@ -774,6 +783,7 @@ class ViewerPlugin(Plugin): # {{{
|
|||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
|
|
||||||
class EditBookToolPlugin(Plugin): # {{{
|
class EditBookToolPlugin(Plugin): # {{{
|
||||||
|
|
||||||
type = _('Edit Book Tool')
|
type = _('Edit Book Tool')
|
||||||
@ -781,6 +791,7 @@ class EditBookToolPlugin(Plugin): # {{{
|
|||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
|
|
||||||
class LibraryClosedPlugin(Plugin): # {{{
|
class LibraryClosedPlugin(Plugin): # {{{
|
||||||
'''
|
'''
|
||||||
LibraryClosedPlugins are run when a library is closed, either at shutdown,
|
LibraryClosedPlugins are run when a library is closed, either at shutdown,
|
||||||
|
@ -15,6 +15,7 @@ plugins = []
|
|||||||
|
|
||||||
# To archive plugins {{{
|
# To archive plugins {{{
|
||||||
|
|
||||||
|
|
||||||
class PML2PMLZ(FileTypePlugin):
|
class PML2PMLZ(FileTypePlugin):
|
||||||
name = 'PML to PMLZ'
|
name = 'PML to PMLZ'
|
||||||
author = 'John Schember'
|
author = 'John Schember'
|
||||||
@ -45,6 +46,7 @@ class PML2PMLZ(FileTypePlugin):
|
|||||||
|
|
||||||
return of.name
|
return of.name
|
||||||
|
|
||||||
|
|
||||||
class TXT2TXTZ(FileTypePlugin):
|
class TXT2TXTZ(FileTypePlugin):
|
||||||
name = 'TXT to TXTZ'
|
name = 'TXT to TXTZ'
|
||||||
author = 'John Schember'
|
author = 'John Schember'
|
||||||
@ -124,6 +126,8 @@ plugins += [HTML2ZIP, PML2PMLZ, TXT2TXTZ, ArchiveExtract,]
|
|||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
# Metadata reader plugins {{{
|
# Metadata reader plugins {{{
|
||||||
|
|
||||||
|
|
||||||
class ComicMetadataReader(MetadataReaderPlugin):
|
class ComicMetadataReader(MetadataReaderPlugin):
|
||||||
|
|
||||||
name = 'Read comic metadata'
|
name = 'Read comic metadata'
|
||||||
@ -164,6 +168,7 @@ class ComicMetadataReader(MetadataReaderPlugin):
|
|||||||
mi.cover_data = (ext.lower(), data)
|
mi.cover_data = (ext.lower(), data)
|
||||||
return mi
|
return mi
|
||||||
|
|
||||||
|
|
||||||
class CHMMetadataReader(MetadataReaderPlugin):
|
class CHMMetadataReader(MetadataReaderPlugin):
|
||||||
|
|
||||||
name = 'Read CHM metadata'
|
name = 'Read CHM metadata'
|
||||||
@ -187,6 +192,7 @@ class EPUBMetadataReader(MetadataReaderPlugin):
|
|||||||
return get_quick_metadata(stream)
|
return get_quick_metadata(stream)
|
||||||
return get_metadata(stream)
|
return get_metadata(stream)
|
||||||
|
|
||||||
|
|
||||||
class FB2MetadataReader(MetadataReaderPlugin):
|
class FB2MetadataReader(MetadataReaderPlugin):
|
||||||
|
|
||||||
name = 'Read FB2 metadata'
|
name = 'Read FB2 metadata'
|
||||||
@ -197,6 +203,7 @@ class FB2MetadataReader(MetadataReaderPlugin):
|
|||||||
from calibre.ebooks.metadata.fb2 import get_metadata
|
from calibre.ebooks.metadata.fb2 import get_metadata
|
||||||
return get_metadata(stream)
|
return get_metadata(stream)
|
||||||
|
|
||||||
|
|
||||||
class HTMLMetadataReader(MetadataReaderPlugin):
|
class HTMLMetadataReader(MetadataReaderPlugin):
|
||||||
|
|
||||||
name = 'Read HTML metadata'
|
name = 'Read HTML metadata'
|
||||||
@ -207,6 +214,7 @@ class HTMLMetadataReader(MetadataReaderPlugin):
|
|||||||
from calibre.ebooks.metadata.html import get_metadata
|
from calibre.ebooks.metadata.html import get_metadata
|
||||||
return get_metadata(stream)
|
return get_metadata(stream)
|
||||||
|
|
||||||
|
|
||||||
class HTMLZMetadataReader(MetadataReaderPlugin):
|
class HTMLZMetadataReader(MetadataReaderPlugin):
|
||||||
|
|
||||||
name = 'Read HTMLZ metadata'
|
name = 'Read HTMLZ metadata'
|
||||||
@ -218,6 +226,7 @@ class HTMLZMetadataReader(MetadataReaderPlugin):
|
|||||||
from calibre.ebooks.metadata.extz import get_metadata
|
from calibre.ebooks.metadata.extz import get_metadata
|
||||||
return get_metadata(stream)
|
return get_metadata(stream)
|
||||||
|
|
||||||
|
|
||||||
class IMPMetadataReader(MetadataReaderPlugin):
|
class IMPMetadataReader(MetadataReaderPlugin):
|
||||||
|
|
||||||
name = 'Read IMP metadata'
|
name = 'Read IMP metadata'
|
||||||
@ -229,6 +238,7 @@ class IMPMetadataReader(MetadataReaderPlugin):
|
|||||||
from calibre.ebooks.metadata.imp import get_metadata
|
from calibre.ebooks.metadata.imp import get_metadata
|
||||||
return get_metadata(stream)
|
return get_metadata(stream)
|
||||||
|
|
||||||
|
|
||||||
class LITMetadataReader(MetadataReaderPlugin):
|
class LITMetadataReader(MetadataReaderPlugin):
|
||||||
|
|
||||||
name = 'Read LIT metadata'
|
name = 'Read LIT metadata'
|
||||||
@ -239,6 +249,7 @@ class LITMetadataReader(MetadataReaderPlugin):
|
|||||||
from calibre.ebooks.metadata.lit import get_metadata
|
from calibre.ebooks.metadata.lit import get_metadata
|
||||||
return get_metadata(stream)
|
return get_metadata(stream)
|
||||||
|
|
||||||
|
|
||||||
class LRFMetadataReader(MetadataReaderPlugin):
|
class LRFMetadataReader(MetadataReaderPlugin):
|
||||||
|
|
||||||
name = 'Read LRF metadata'
|
name = 'Read LRF metadata'
|
||||||
@ -249,6 +260,7 @@ class LRFMetadataReader(MetadataReaderPlugin):
|
|||||||
from calibre.ebooks.lrf.meta import get_metadata
|
from calibre.ebooks.lrf.meta import get_metadata
|
||||||
return get_metadata(stream)
|
return get_metadata(stream)
|
||||||
|
|
||||||
|
|
||||||
class LRXMetadataReader(MetadataReaderPlugin):
|
class LRXMetadataReader(MetadataReaderPlugin):
|
||||||
|
|
||||||
name = 'Read LRX metadata'
|
name = 'Read LRX metadata'
|
||||||
@ -259,6 +271,7 @@ class LRXMetadataReader(MetadataReaderPlugin):
|
|||||||
from calibre.ebooks.metadata.lrx import get_metadata
|
from calibre.ebooks.metadata.lrx import get_metadata
|
||||||
return get_metadata(stream)
|
return get_metadata(stream)
|
||||||
|
|
||||||
|
|
||||||
class MOBIMetadataReader(MetadataReaderPlugin):
|
class MOBIMetadataReader(MetadataReaderPlugin):
|
||||||
|
|
||||||
name = 'Read MOBI metadata'
|
name = 'Read MOBI metadata'
|
||||||
@ -269,6 +282,7 @@ class MOBIMetadataReader(MetadataReaderPlugin):
|
|||||||
from calibre.ebooks.metadata.mobi import get_metadata
|
from calibre.ebooks.metadata.mobi import get_metadata
|
||||||
return get_metadata(stream)
|
return get_metadata(stream)
|
||||||
|
|
||||||
|
|
||||||
class ODTMetadataReader(MetadataReaderPlugin):
|
class ODTMetadataReader(MetadataReaderPlugin):
|
||||||
|
|
||||||
name = 'Read ODT metadata'
|
name = 'Read ODT metadata'
|
||||||
@ -279,6 +293,7 @@ class ODTMetadataReader(MetadataReaderPlugin):
|
|||||||
from calibre.ebooks.metadata.odt import get_metadata
|
from calibre.ebooks.metadata.odt import get_metadata
|
||||||
return get_metadata(stream)
|
return get_metadata(stream)
|
||||||
|
|
||||||
|
|
||||||
class DocXMetadataReader(MetadataReaderPlugin):
|
class DocXMetadataReader(MetadataReaderPlugin):
|
||||||
|
|
||||||
name = 'Read DOCX metadata'
|
name = 'Read DOCX metadata'
|
||||||
@ -289,6 +304,7 @@ class DocXMetadataReader(MetadataReaderPlugin):
|
|||||||
from calibre.ebooks.metadata.docx import get_metadata
|
from calibre.ebooks.metadata.docx import get_metadata
|
||||||
return get_metadata(stream)
|
return get_metadata(stream)
|
||||||
|
|
||||||
|
|
||||||
class OPFMetadataReader(MetadataReaderPlugin):
|
class OPFMetadataReader(MetadataReaderPlugin):
|
||||||
|
|
||||||
name = 'Read OPF metadata'
|
name = 'Read OPF metadata'
|
||||||
@ -299,6 +315,7 @@ class OPFMetadataReader(MetadataReaderPlugin):
|
|||||||
from calibre.ebooks.metadata.opf import get_metadata
|
from calibre.ebooks.metadata.opf import get_metadata
|
||||||
return get_metadata(stream)[0]
|
return get_metadata(stream)[0]
|
||||||
|
|
||||||
|
|
||||||
class PDBMetadataReader(MetadataReaderPlugin):
|
class PDBMetadataReader(MetadataReaderPlugin):
|
||||||
|
|
||||||
name = 'Read PDB metadata'
|
name = 'Read PDB metadata'
|
||||||
@ -310,6 +327,7 @@ class PDBMetadataReader(MetadataReaderPlugin):
|
|||||||
from calibre.ebooks.metadata.pdb import get_metadata
|
from calibre.ebooks.metadata.pdb import get_metadata
|
||||||
return get_metadata(stream)
|
return get_metadata(stream)
|
||||||
|
|
||||||
|
|
||||||
class PDFMetadataReader(MetadataReaderPlugin):
|
class PDFMetadataReader(MetadataReaderPlugin):
|
||||||
|
|
||||||
name = 'Read PDF metadata'
|
name = 'Read PDF metadata'
|
||||||
@ -322,6 +340,7 @@ class PDFMetadataReader(MetadataReaderPlugin):
|
|||||||
return get_quick_metadata(stream)
|
return get_quick_metadata(stream)
|
||||||
return get_metadata(stream)
|
return get_metadata(stream)
|
||||||
|
|
||||||
|
|
||||||
class PMLMetadataReader(MetadataReaderPlugin):
|
class PMLMetadataReader(MetadataReaderPlugin):
|
||||||
|
|
||||||
name = 'Read PML metadata'
|
name = 'Read PML metadata'
|
||||||
@ -333,6 +352,7 @@ class PMLMetadataReader(MetadataReaderPlugin):
|
|||||||
from calibre.ebooks.metadata.pml import get_metadata
|
from calibre.ebooks.metadata.pml import get_metadata
|
||||||
return get_metadata(stream)
|
return get_metadata(stream)
|
||||||
|
|
||||||
|
|
||||||
class RARMetadataReader(MetadataReaderPlugin):
|
class RARMetadataReader(MetadataReaderPlugin):
|
||||||
|
|
||||||
name = 'Read RAR metadata'
|
name = 'Read RAR metadata'
|
||||||
@ -343,6 +363,7 @@ class RARMetadataReader(MetadataReaderPlugin):
|
|||||||
from calibre.ebooks.metadata.rar import get_metadata
|
from calibre.ebooks.metadata.rar import get_metadata
|
||||||
return get_metadata(stream)
|
return get_metadata(stream)
|
||||||
|
|
||||||
|
|
||||||
class RBMetadataReader(MetadataReaderPlugin):
|
class RBMetadataReader(MetadataReaderPlugin):
|
||||||
|
|
||||||
name = 'Read RB metadata'
|
name = 'Read RB metadata'
|
||||||
@ -354,6 +375,7 @@ class RBMetadataReader(MetadataReaderPlugin):
|
|||||||
from calibre.ebooks.metadata.rb import get_metadata
|
from calibre.ebooks.metadata.rb import get_metadata
|
||||||
return get_metadata(stream)
|
return get_metadata(stream)
|
||||||
|
|
||||||
|
|
||||||
class RTFMetadataReader(MetadataReaderPlugin):
|
class RTFMetadataReader(MetadataReaderPlugin):
|
||||||
|
|
||||||
name = 'Read RTF metadata'
|
name = 'Read RTF metadata'
|
||||||
@ -364,6 +386,7 @@ class RTFMetadataReader(MetadataReaderPlugin):
|
|||||||
from calibre.ebooks.metadata.rtf import get_metadata
|
from calibre.ebooks.metadata.rtf import get_metadata
|
||||||
return get_metadata(stream)
|
return get_metadata(stream)
|
||||||
|
|
||||||
|
|
||||||
class SNBMetadataReader(MetadataReaderPlugin):
|
class SNBMetadataReader(MetadataReaderPlugin):
|
||||||
|
|
||||||
name = 'Read SNB metadata'
|
name = 'Read SNB metadata'
|
||||||
@ -375,6 +398,7 @@ class SNBMetadataReader(MetadataReaderPlugin):
|
|||||||
from calibre.ebooks.metadata.snb import get_metadata
|
from calibre.ebooks.metadata.snb import get_metadata
|
||||||
return get_metadata(stream)
|
return get_metadata(stream)
|
||||||
|
|
||||||
|
|
||||||
class TOPAZMetadataReader(MetadataReaderPlugin):
|
class TOPAZMetadataReader(MetadataReaderPlugin):
|
||||||
|
|
||||||
name = 'Read Topaz metadata'
|
name = 'Read Topaz metadata'
|
||||||
@ -385,6 +409,7 @@ class TOPAZMetadataReader(MetadataReaderPlugin):
|
|||||||
from calibre.ebooks.metadata.topaz import get_metadata
|
from calibre.ebooks.metadata.topaz import get_metadata
|
||||||
return get_metadata(stream)
|
return get_metadata(stream)
|
||||||
|
|
||||||
|
|
||||||
class TXTMetadataReader(MetadataReaderPlugin):
|
class TXTMetadataReader(MetadataReaderPlugin):
|
||||||
|
|
||||||
name = 'Read TXT metadata'
|
name = 'Read TXT metadata'
|
||||||
@ -396,6 +421,7 @@ class TXTMetadataReader(MetadataReaderPlugin):
|
|||||||
from calibre.ebooks.metadata.txt import get_metadata
|
from calibre.ebooks.metadata.txt import get_metadata
|
||||||
return get_metadata(stream)
|
return get_metadata(stream)
|
||||||
|
|
||||||
|
|
||||||
class TXTZMetadataReader(MetadataReaderPlugin):
|
class TXTZMetadataReader(MetadataReaderPlugin):
|
||||||
|
|
||||||
name = 'Read TXTZ metadata'
|
name = 'Read TXTZ metadata'
|
||||||
@ -407,6 +433,7 @@ class TXTZMetadataReader(MetadataReaderPlugin):
|
|||||||
from calibre.ebooks.metadata.extz import get_metadata
|
from calibre.ebooks.metadata.extz import get_metadata
|
||||||
return get_metadata(stream)
|
return get_metadata(stream)
|
||||||
|
|
||||||
|
|
||||||
class ZipMetadataReader(MetadataReaderPlugin):
|
class ZipMetadataReader(MetadataReaderPlugin):
|
||||||
|
|
||||||
name = 'Read ZIP metadata'
|
name = 'Read ZIP metadata'
|
||||||
@ -424,6 +451,7 @@ plugins += [x for x in list(locals().values()) if isinstance(x, type) and
|
|||||||
|
|
||||||
# Metadata writer plugins {{{
|
# Metadata writer plugins {{{
|
||||||
|
|
||||||
|
|
||||||
class EPUBMetadataWriter(MetadataWriterPlugin):
|
class EPUBMetadataWriter(MetadataWriterPlugin):
|
||||||
|
|
||||||
name = 'Set EPUB metadata'
|
name = 'Set EPUB metadata'
|
||||||
@ -442,6 +470,7 @@ class EPUBMetadataWriter(MetadataWriterPlugin):
|
|||||||
return _('Enter {0} below to have the EPUB metadata writer plugin not'
|
return _('Enter {0} below to have the EPUB metadata writer plugin not'
|
||||||
' add cover images to EPUB files that have no existing cover image.').format(h)
|
' add cover images to EPUB files that have no existing cover image.').format(h)
|
||||||
|
|
||||||
|
|
||||||
class FB2MetadataWriter(MetadataWriterPlugin):
|
class FB2MetadataWriter(MetadataWriterPlugin):
|
||||||
|
|
||||||
name = 'Set FB2 metadata'
|
name = 'Set FB2 metadata'
|
||||||
@ -452,6 +481,7 @@ class FB2MetadataWriter(MetadataWriterPlugin):
|
|||||||
from calibre.ebooks.metadata.fb2 import set_metadata
|
from calibre.ebooks.metadata.fb2 import set_metadata
|
||||||
set_metadata(stream, mi, apply_null=self.apply_null)
|
set_metadata(stream, mi, apply_null=self.apply_null)
|
||||||
|
|
||||||
|
|
||||||
class HTMLZMetadataWriter(MetadataWriterPlugin):
|
class HTMLZMetadataWriter(MetadataWriterPlugin):
|
||||||
|
|
||||||
name = 'Set HTMLZ metadata'
|
name = 'Set HTMLZ metadata'
|
||||||
@ -463,6 +493,7 @@ class HTMLZMetadataWriter(MetadataWriterPlugin):
|
|||||||
from calibre.ebooks.metadata.extz import set_metadata
|
from calibre.ebooks.metadata.extz import set_metadata
|
||||||
set_metadata(stream, mi)
|
set_metadata(stream, mi)
|
||||||
|
|
||||||
|
|
||||||
class LRFMetadataWriter(MetadataWriterPlugin):
|
class LRFMetadataWriter(MetadataWriterPlugin):
|
||||||
|
|
||||||
name = 'Set LRF metadata'
|
name = 'Set LRF metadata'
|
||||||
@ -473,6 +504,7 @@ class LRFMetadataWriter(MetadataWriterPlugin):
|
|||||||
from calibre.ebooks.lrf.meta import set_metadata
|
from calibre.ebooks.lrf.meta import set_metadata
|
||||||
set_metadata(stream, mi)
|
set_metadata(stream, mi)
|
||||||
|
|
||||||
|
|
||||||
class MOBIMetadataWriter(MetadataWriterPlugin):
|
class MOBIMetadataWriter(MetadataWriterPlugin):
|
||||||
|
|
||||||
name = 'Set MOBI metadata'
|
name = 'Set MOBI metadata'
|
||||||
@ -484,6 +516,7 @@ class MOBIMetadataWriter(MetadataWriterPlugin):
|
|||||||
from calibre.ebooks.metadata.mobi import set_metadata
|
from calibre.ebooks.metadata.mobi import set_metadata
|
||||||
set_metadata(stream, mi)
|
set_metadata(stream, mi)
|
||||||
|
|
||||||
|
|
||||||
class PDBMetadataWriter(MetadataWriterPlugin):
|
class PDBMetadataWriter(MetadataWriterPlugin):
|
||||||
|
|
||||||
name = 'Set PDB metadata'
|
name = 'Set PDB metadata'
|
||||||
@ -495,6 +528,7 @@ class PDBMetadataWriter(MetadataWriterPlugin):
|
|||||||
from calibre.ebooks.metadata.pdb import set_metadata
|
from calibre.ebooks.metadata.pdb import set_metadata
|
||||||
set_metadata(stream, mi)
|
set_metadata(stream, mi)
|
||||||
|
|
||||||
|
|
||||||
class PDFMetadataWriter(MetadataWriterPlugin):
|
class PDFMetadataWriter(MetadataWriterPlugin):
|
||||||
|
|
||||||
name = 'Set PDF metadata'
|
name = 'Set PDF metadata'
|
||||||
@ -506,6 +540,7 @@ class PDFMetadataWriter(MetadataWriterPlugin):
|
|||||||
from calibre.ebooks.metadata.pdf import set_metadata
|
from calibre.ebooks.metadata.pdf import set_metadata
|
||||||
set_metadata(stream, mi)
|
set_metadata(stream, mi)
|
||||||
|
|
||||||
|
|
||||||
class RTFMetadataWriter(MetadataWriterPlugin):
|
class RTFMetadataWriter(MetadataWriterPlugin):
|
||||||
|
|
||||||
name = 'Set RTF metadata'
|
name = 'Set RTF metadata'
|
||||||
@ -516,6 +551,7 @@ class RTFMetadataWriter(MetadataWriterPlugin):
|
|||||||
from calibre.ebooks.metadata.rtf import set_metadata
|
from calibre.ebooks.metadata.rtf import set_metadata
|
||||||
set_metadata(stream, mi)
|
set_metadata(stream, mi)
|
||||||
|
|
||||||
|
|
||||||
class TOPAZMetadataWriter(MetadataWriterPlugin):
|
class TOPAZMetadataWriter(MetadataWriterPlugin):
|
||||||
|
|
||||||
name = 'Set TOPAZ metadata'
|
name = 'Set TOPAZ metadata'
|
||||||
@ -527,6 +563,7 @@ class TOPAZMetadataWriter(MetadataWriterPlugin):
|
|||||||
from calibre.ebooks.metadata.topaz import set_metadata
|
from calibre.ebooks.metadata.topaz import set_metadata
|
||||||
set_metadata(stream, mi)
|
set_metadata(stream, mi)
|
||||||
|
|
||||||
|
|
||||||
class TXTZMetadataWriter(MetadataWriterPlugin):
|
class TXTZMetadataWriter(MetadataWriterPlugin):
|
||||||
|
|
||||||
name = 'Set TXTZ metadata'
|
name = 'Set TXTZ metadata'
|
||||||
@ -538,6 +575,7 @@ class TXTZMetadataWriter(MetadataWriterPlugin):
|
|||||||
from calibre.ebooks.metadata.extz import set_metadata
|
from calibre.ebooks.metadata.extz import set_metadata
|
||||||
set_metadata(stream, mi)
|
set_metadata(stream, mi)
|
||||||
|
|
||||||
|
|
||||||
class DocXMetadataWriter(MetadataWriterPlugin):
|
class DocXMetadataWriter(MetadataWriterPlugin):
|
||||||
|
|
||||||
name = 'Set DOCX metadata'
|
name = 'Set DOCX metadata'
|
||||||
@ -790,180 +828,215 @@ plugins += [GoogleBooks, GoogleImages, Amazon, Edelweiss, OpenLibrary, ISBNDB, O
|
|||||||
|
|
||||||
# Interface Actions {{{
|
# Interface Actions {{{
|
||||||
|
|
||||||
|
|
||||||
class ActionAdd(InterfaceActionBase):
|
class ActionAdd(InterfaceActionBase):
|
||||||
name = 'Add Books'
|
name = 'Add Books'
|
||||||
actual_plugin = 'calibre.gui2.actions.add:AddAction'
|
actual_plugin = 'calibre.gui2.actions.add:AddAction'
|
||||||
description = _('Add books to calibre or the connected device')
|
description = _('Add books to calibre or the connected device')
|
||||||
|
|
||||||
|
|
||||||
class ActionFetchAnnotations(InterfaceActionBase):
|
class ActionFetchAnnotations(InterfaceActionBase):
|
||||||
name = 'Fetch Annotations'
|
name = 'Fetch Annotations'
|
||||||
actual_plugin = 'calibre.gui2.actions.annotate:FetchAnnotationsAction'
|
actual_plugin = 'calibre.gui2.actions.annotate:FetchAnnotationsAction'
|
||||||
description = _('Fetch annotations from a connected Kindle (experimental)')
|
description = _('Fetch annotations from a connected Kindle (experimental)')
|
||||||
|
|
||||||
|
|
||||||
class ActionGenerateCatalog(InterfaceActionBase):
|
class ActionGenerateCatalog(InterfaceActionBase):
|
||||||
name = 'Generate Catalog'
|
name = 'Generate Catalog'
|
||||||
actual_plugin = 'calibre.gui2.actions.catalog:GenerateCatalogAction'
|
actual_plugin = 'calibre.gui2.actions.catalog:GenerateCatalogAction'
|
||||||
description = _('Generate a catalog of the books in your calibre library')
|
description = _('Generate a catalog of the books in your calibre library')
|
||||||
|
|
||||||
|
|
||||||
class ActionConvert(InterfaceActionBase):
|
class ActionConvert(InterfaceActionBase):
|
||||||
name = 'Convert Books'
|
name = 'Convert Books'
|
||||||
actual_plugin = 'calibre.gui2.actions.convert:ConvertAction'
|
actual_plugin = 'calibre.gui2.actions.convert:ConvertAction'
|
||||||
description = _('Convert books to various ebook formats')
|
description = _('Convert books to various ebook formats')
|
||||||
|
|
||||||
|
|
||||||
class ActionPolish(InterfaceActionBase):
|
class ActionPolish(InterfaceActionBase):
|
||||||
name = 'Polish Books'
|
name = 'Polish Books'
|
||||||
actual_plugin = 'calibre.gui2.actions.polish:PolishAction'
|
actual_plugin = 'calibre.gui2.actions.polish:PolishAction'
|
||||||
description = _('Fine tune your ebooks')
|
description = _('Fine tune your ebooks')
|
||||||
|
|
||||||
|
|
||||||
class ActionEditToC(InterfaceActionBase):
|
class ActionEditToC(InterfaceActionBase):
|
||||||
name = 'Edit ToC'
|
name = 'Edit ToC'
|
||||||
actual_plugin = 'calibre.gui2.actions.toc_edit:ToCEditAction'
|
actual_plugin = 'calibre.gui2.actions.toc_edit:ToCEditAction'
|
||||||
description = _('Edit the Table of Contents in your books')
|
description = _('Edit the Table of Contents in your books')
|
||||||
|
|
||||||
|
|
||||||
class ActionDelete(InterfaceActionBase):
|
class ActionDelete(InterfaceActionBase):
|
||||||
name = 'Remove Books'
|
name = 'Remove Books'
|
||||||
actual_plugin = 'calibre.gui2.actions.delete:DeleteAction'
|
actual_plugin = 'calibre.gui2.actions.delete:DeleteAction'
|
||||||
description = _('Delete books from your calibre library or connected device')
|
description = _('Delete books from your calibre library or connected device')
|
||||||
|
|
||||||
|
|
||||||
class ActionEmbed(InterfaceActionBase):
|
class ActionEmbed(InterfaceActionBase):
|
||||||
name = 'Embed Metadata'
|
name = 'Embed Metadata'
|
||||||
actual_plugin = 'calibre.gui2.actions.embed:EmbedAction'
|
actual_plugin = 'calibre.gui2.actions.embed:EmbedAction'
|
||||||
description = _('Embed updated metadata into the actual book files in your calibre library')
|
description = _('Embed updated metadata into the actual book files in your calibre library')
|
||||||
|
|
||||||
|
|
||||||
class ActionEditMetadata(InterfaceActionBase):
|
class ActionEditMetadata(InterfaceActionBase):
|
||||||
name = 'Edit Metadata'
|
name = 'Edit Metadata'
|
||||||
actual_plugin = 'calibre.gui2.actions.edit_metadata:EditMetadataAction'
|
actual_plugin = 'calibre.gui2.actions.edit_metadata:EditMetadataAction'
|
||||||
description = _('Edit the metadata of books in your calibre library')
|
description = _('Edit the metadata of books in your calibre library')
|
||||||
|
|
||||||
|
|
||||||
class ActionView(InterfaceActionBase):
|
class ActionView(InterfaceActionBase):
|
||||||
name = 'View'
|
name = 'View'
|
||||||
actual_plugin = 'calibre.gui2.actions.view:ViewAction'
|
actual_plugin = 'calibre.gui2.actions.view:ViewAction'
|
||||||
description = _('Read books in your calibre library')
|
description = _('Read books in your calibre library')
|
||||||
|
|
||||||
|
|
||||||
class ActionFetchNews(InterfaceActionBase):
|
class ActionFetchNews(InterfaceActionBase):
|
||||||
name = 'Fetch News'
|
name = 'Fetch News'
|
||||||
actual_plugin = 'calibre.gui2.actions.fetch_news:FetchNewsAction'
|
actual_plugin = 'calibre.gui2.actions.fetch_news:FetchNewsAction'
|
||||||
description = _('Download news from the internet in ebook form')
|
description = _('Download news from the internet in ebook form')
|
||||||
|
|
||||||
|
|
||||||
class ActionQuickview(InterfaceActionBase):
|
class ActionQuickview(InterfaceActionBase):
|
||||||
name = 'Show Quickview'
|
name = 'Show Quickview'
|
||||||
actual_plugin = 'calibre.gui2.actions.show_quickview:ShowQuickviewAction'
|
actual_plugin = 'calibre.gui2.actions.show_quickview:ShowQuickviewAction'
|
||||||
description = _('Show a list of related books quickly')
|
description = _('Show a list of related books quickly')
|
||||||
|
|
||||||
|
|
||||||
class ActionTagMapper(InterfaceActionBase):
|
class ActionTagMapper(InterfaceActionBase):
|
||||||
name = 'Tag Mapper'
|
name = 'Tag Mapper'
|
||||||
actual_plugin = 'calibre.gui2.actions.tag_mapper:TagMapAction'
|
actual_plugin = 'calibre.gui2.actions.tag_mapper:TagMapAction'
|
||||||
description = _('Filter/transform the tags for books in the library')
|
description = _('Filter/transform the tags for books in the library')
|
||||||
|
|
||||||
|
|
||||||
class ActionTemplateTester(InterfaceActionBase):
|
class ActionTemplateTester(InterfaceActionBase):
|
||||||
name = 'Template Tester'
|
name = 'Template Tester'
|
||||||
actual_plugin = 'calibre.gui2.actions.show_template_tester:ShowTemplateTesterAction'
|
actual_plugin = 'calibre.gui2.actions.show_template_tester:ShowTemplateTesterAction'
|
||||||
description = _('Show an editor for testing templates')
|
description = _('Show an editor for testing templates')
|
||||||
|
|
||||||
|
|
||||||
class ActionSaveToDisk(InterfaceActionBase):
|
class ActionSaveToDisk(InterfaceActionBase):
|
||||||
name = 'Save To Disk'
|
name = 'Save To Disk'
|
||||||
actual_plugin = 'calibre.gui2.actions.save_to_disk:SaveToDiskAction'
|
actual_plugin = 'calibre.gui2.actions.save_to_disk:SaveToDiskAction'
|
||||||
description = _('Export books from your calibre library to the hard disk')
|
description = _('Export books from your calibre library to the hard disk')
|
||||||
|
|
||||||
|
|
||||||
class ActionShowBookDetails(InterfaceActionBase):
|
class ActionShowBookDetails(InterfaceActionBase):
|
||||||
name = 'Show Book Details'
|
name = 'Show Book Details'
|
||||||
actual_plugin = 'calibre.gui2.actions.show_book_details:ShowBookDetailsAction'
|
actual_plugin = 'calibre.gui2.actions.show_book_details:ShowBookDetailsAction'
|
||||||
description = _('Show book details in a separate popup')
|
description = _('Show book details in a separate popup')
|
||||||
|
|
||||||
|
|
||||||
class ActionRestart(InterfaceActionBase):
|
class ActionRestart(InterfaceActionBase):
|
||||||
name = 'Restart'
|
name = 'Restart'
|
||||||
actual_plugin = 'calibre.gui2.actions.restart:RestartAction'
|
actual_plugin = 'calibre.gui2.actions.restart:RestartAction'
|
||||||
description = _('Restart calibre')
|
description = _('Restart calibre')
|
||||||
|
|
||||||
|
|
||||||
class ActionOpenFolder(InterfaceActionBase):
|
class ActionOpenFolder(InterfaceActionBase):
|
||||||
name = 'Open Folder'
|
name = 'Open Folder'
|
||||||
actual_plugin = 'calibre.gui2.actions.open:OpenFolderAction'
|
actual_plugin = 'calibre.gui2.actions.open:OpenFolderAction'
|
||||||
description = _('Open the folder that contains the book files in your'
|
description = _('Open the folder that contains the book files in your'
|
||||||
' calibre library')
|
' calibre library')
|
||||||
|
|
||||||
|
|
||||||
class ActionSendToDevice(InterfaceActionBase):
|
class ActionSendToDevice(InterfaceActionBase):
|
||||||
name = 'Send To Device'
|
name = 'Send To Device'
|
||||||
actual_plugin = 'calibre.gui2.actions.device:SendToDeviceAction'
|
actual_plugin = 'calibre.gui2.actions.device:SendToDeviceAction'
|
||||||
description = _('Send books to the connected device')
|
description = _('Send books to the connected device')
|
||||||
|
|
||||||
|
|
||||||
class ActionConnectShare(InterfaceActionBase):
|
class ActionConnectShare(InterfaceActionBase):
|
||||||
name = 'Connect Share'
|
name = 'Connect Share'
|
||||||
actual_plugin = 'calibre.gui2.actions.device:ConnectShareAction'
|
actual_plugin = 'calibre.gui2.actions.device:ConnectShareAction'
|
||||||
description = _('Send books via email or the web also connect to iTunes or'
|
description = _('Send books via email or the web also connect to iTunes or'
|
||||||
' folders on your computer as if they are devices')
|
' folders on your computer as if they are devices')
|
||||||
|
|
||||||
|
|
||||||
class ActionHelp(InterfaceActionBase):
|
class ActionHelp(InterfaceActionBase):
|
||||||
name = 'Help'
|
name = 'Help'
|
||||||
actual_plugin = 'calibre.gui2.actions.help:HelpAction'
|
actual_plugin = 'calibre.gui2.actions.help:HelpAction'
|
||||||
description = _('Browse the calibre User Manual')
|
description = _('Browse the calibre User Manual')
|
||||||
|
|
||||||
|
|
||||||
class ActionPreferences(InterfaceActionBase):
|
class ActionPreferences(InterfaceActionBase):
|
||||||
name = 'Preferences'
|
name = 'Preferences'
|
||||||
actual_plugin = 'calibre.gui2.actions.preferences:PreferencesAction'
|
actual_plugin = 'calibre.gui2.actions.preferences:PreferencesAction'
|
||||||
description = _('Customize calibre')
|
description = _('Customize calibre')
|
||||||
|
|
||||||
|
|
||||||
class ActionSimilarBooks(InterfaceActionBase):
|
class ActionSimilarBooks(InterfaceActionBase):
|
||||||
name = 'Similar Books'
|
name = 'Similar Books'
|
||||||
actual_plugin = 'calibre.gui2.actions.similar_books:SimilarBooksAction'
|
actual_plugin = 'calibre.gui2.actions.similar_books:SimilarBooksAction'
|
||||||
description = _('Easily find books similar to the currently selected one')
|
description = _('Easily find books similar to the currently selected one')
|
||||||
|
|
||||||
|
|
||||||
class ActionChooseLibrary(InterfaceActionBase):
|
class ActionChooseLibrary(InterfaceActionBase):
|
||||||
name = 'Choose Library'
|
name = 'Choose Library'
|
||||||
actual_plugin = 'calibre.gui2.actions.choose_library:ChooseLibraryAction'
|
actual_plugin = 'calibre.gui2.actions.choose_library:ChooseLibraryAction'
|
||||||
description = _('Switch between different calibre libraries and perform'
|
description = _('Switch between different calibre libraries and perform'
|
||||||
' maintenance on them')
|
' maintenance on them')
|
||||||
|
|
||||||
|
|
||||||
class ActionAddToLibrary(InterfaceActionBase):
|
class ActionAddToLibrary(InterfaceActionBase):
|
||||||
name = 'Add To Library'
|
name = 'Add To Library'
|
||||||
actual_plugin = 'calibre.gui2.actions.add_to_library:AddToLibraryAction'
|
actual_plugin = 'calibre.gui2.actions.add_to_library:AddToLibraryAction'
|
||||||
description = _('Copy books from the device to your calibre library')
|
description = _('Copy books from the device to your calibre library')
|
||||||
|
|
||||||
|
|
||||||
class ActionEditCollections(InterfaceActionBase):
|
class ActionEditCollections(InterfaceActionBase):
|
||||||
name = 'Edit Collections'
|
name = 'Edit Collections'
|
||||||
actual_plugin = 'calibre.gui2.actions.edit_collections:EditCollectionsAction'
|
actual_plugin = 'calibre.gui2.actions.edit_collections:EditCollectionsAction'
|
||||||
description = _('Edit the collections in which books are placed on your device')
|
description = _('Edit the collections in which books are placed on your device')
|
||||||
|
|
||||||
|
|
||||||
class ActionMatchBooks(InterfaceActionBase):
|
class ActionMatchBooks(InterfaceActionBase):
|
||||||
name = 'Match Books'
|
name = 'Match Books'
|
||||||
actual_plugin = 'calibre.gui2.actions.match_books:MatchBookAction'
|
actual_plugin = 'calibre.gui2.actions.match_books:MatchBookAction'
|
||||||
description = _('Match book on the devices to books in the library')
|
description = _('Match book on the devices to books in the library')
|
||||||
|
|
||||||
|
|
||||||
class ActionCopyToLibrary(InterfaceActionBase):
|
class ActionCopyToLibrary(InterfaceActionBase):
|
||||||
name = 'Copy To Library'
|
name = 'Copy To Library'
|
||||||
actual_plugin = 'calibre.gui2.actions.copy_to_library:CopyToLibraryAction'
|
actual_plugin = 'calibre.gui2.actions.copy_to_library:CopyToLibraryAction'
|
||||||
description = _('Copy a book from one calibre library to another')
|
description = _('Copy a book from one calibre library to another')
|
||||||
|
|
||||||
|
|
||||||
class ActionTweakEpub(InterfaceActionBase):
|
class ActionTweakEpub(InterfaceActionBase):
|
||||||
name = 'Tweak ePub'
|
name = 'Tweak ePub'
|
||||||
actual_plugin = 'calibre.gui2.actions.tweak_epub:TweakEpubAction'
|
actual_plugin = 'calibre.gui2.actions.tweak_epub:TweakEpubAction'
|
||||||
description = _('Edit ebooks in the epub or azw3 formats')
|
description = _('Edit ebooks in the epub or azw3 formats')
|
||||||
|
|
||||||
|
|
||||||
class ActionUnpackBook(InterfaceActionBase):
|
class ActionUnpackBook(InterfaceActionBase):
|
||||||
name = 'Unpack Book'
|
name = 'Unpack Book'
|
||||||
actual_plugin = 'calibre.gui2.actions.unpack_book:UnpackBookAction'
|
actual_plugin = 'calibre.gui2.actions.unpack_book:UnpackBookAction'
|
||||||
description = _('Make small changes to epub or htmlz files in your calibre library')
|
description = _('Make small changes to epub or htmlz files in your calibre library')
|
||||||
|
|
||||||
|
|
||||||
class ActionNextMatch(InterfaceActionBase):
|
class ActionNextMatch(InterfaceActionBase):
|
||||||
name = 'Next Match'
|
name = 'Next Match'
|
||||||
actual_plugin = 'calibre.gui2.actions.next_match:NextMatchAction'
|
actual_plugin = 'calibre.gui2.actions.next_match:NextMatchAction'
|
||||||
description = _('Find the next or previous match when searching in '
|
description = _('Find the next or previous match when searching in '
|
||||||
'your calibre library in highlight mode')
|
'your calibre library in highlight mode')
|
||||||
|
|
||||||
|
|
||||||
class ActionPickRandom(InterfaceActionBase):
|
class ActionPickRandom(InterfaceActionBase):
|
||||||
name = 'Pick Random Book'
|
name = 'Pick Random Book'
|
||||||
actual_plugin = 'calibre.gui2.actions.random:PickRandomAction'
|
actual_plugin = 'calibre.gui2.actions.random:PickRandomAction'
|
||||||
description = _('Choose a random book from your calibre library')
|
description = _('Choose a random book from your calibre library')
|
||||||
|
|
||||||
|
|
||||||
class ActionSortBy(InterfaceActionBase):
|
class ActionSortBy(InterfaceActionBase):
|
||||||
name = 'Sort By'
|
name = 'Sort By'
|
||||||
actual_plugin = 'calibre.gui2.actions.sort:SortByAction'
|
actual_plugin = 'calibre.gui2.actions.sort:SortByAction'
|
||||||
description = _('Sort the list of books')
|
description = _('Sort the list of books')
|
||||||
|
|
||||||
|
|
||||||
class ActionMarkBooks(InterfaceActionBase):
|
class ActionMarkBooks(InterfaceActionBase):
|
||||||
name = 'Mark Books'
|
name = 'Mark Books'
|
||||||
actual_plugin = 'calibre.gui2.actions.mark_books:MarkBooksAction'
|
actual_plugin = 'calibre.gui2.actions.mark_books:MarkBooksAction'
|
||||||
description = _('Temporarily mark books')
|
description = _('Temporarily mark books')
|
||||||
|
|
||||||
|
|
||||||
class ActionStore(InterfaceActionBase):
|
class ActionStore(InterfaceActionBase):
|
||||||
name = 'Store'
|
name = 'Store'
|
||||||
author = 'John Schember'
|
author = 'John Schember'
|
||||||
@ -981,6 +1054,7 @@ class ActionStore(InterfaceActionBase):
|
|||||||
from calibre.gui2.store.config.store import save_settings as save
|
from calibre.gui2.store.config.store import save_settings as save
|
||||||
save(config_widget)
|
save(config_widget)
|
||||||
|
|
||||||
|
|
||||||
class ActionPluginUpdater(InterfaceActionBase):
|
class ActionPluginUpdater(InterfaceActionBase):
|
||||||
name = 'Plugin Updater'
|
name = 'Plugin Updater'
|
||||||
author = 'Grant Drake'
|
author = 'Grant Drake'
|
||||||
@ -1001,6 +1075,7 @@ plugins += [ActionAdd, ActionFetchAnnotations, ActionGenerateCatalog,
|
|||||||
|
|
||||||
# Preferences Plugins {{{
|
# Preferences Plugins {{{
|
||||||
|
|
||||||
|
|
||||||
class LookAndFeel(PreferencesPlugin):
|
class LookAndFeel(PreferencesPlugin):
|
||||||
name = 'Look & Feel'
|
name = 'Look & Feel'
|
||||||
icon = I('lookfeel.png')
|
icon = I('lookfeel.png')
|
||||||
@ -1013,6 +1088,7 @@ class LookAndFeel(PreferencesPlugin):
|
|||||||
description = _('Adjust the look and feel of the calibre interface'
|
description = _('Adjust the look and feel of the calibre interface'
|
||||||
' to suit your tastes')
|
' to suit your tastes')
|
||||||
|
|
||||||
|
|
||||||
class Behavior(PreferencesPlugin):
|
class Behavior(PreferencesPlugin):
|
||||||
name = 'Behavior'
|
name = 'Behavior'
|
||||||
icon = I('config.png')
|
icon = I('config.png')
|
||||||
@ -1024,6 +1100,7 @@ class Behavior(PreferencesPlugin):
|
|||||||
config_widget = 'calibre.gui2.preferences.behavior'
|
config_widget = 'calibre.gui2.preferences.behavior'
|
||||||
description = _('Change the way calibre behaves')
|
description = _('Change the way calibre behaves')
|
||||||
|
|
||||||
|
|
||||||
class Columns(PreferencesPlugin):
|
class Columns(PreferencesPlugin):
|
||||||
name = 'Custom Columns'
|
name = 'Custom Columns'
|
||||||
icon = I('column.png')
|
icon = I('column.png')
|
||||||
@ -1035,6 +1112,7 @@ class Columns(PreferencesPlugin):
|
|||||||
config_widget = 'calibre.gui2.preferences.columns'
|
config_widget = 'calibre.gui2.preferences.columns'
|
||||||
description = _('Add/remove your own columns to the calibre book list')
|
description = _('Add/remove your own columns to the calibre book list')
|
||||||
|
|
||||||
|
|
||||||
class Toolbar(PreferencesPlugin):
|
class Toolbar(PreferencesPlugin):
|
||||||
name = 'Toolbar'
|
name = 'Toolbar'
|
||||||
icon = I('wizard.png')
|
icon = I('wizard.png')
|
||||||
@ -1047,6 +1125,7 @@ class Toolbar(PreferencesPlugin):
|
|||||||
description = _('Customize the toolbars and context menus, changing which'
|
description = _('Customize the toolbars and context menus, changing which'
|
||||||
' actions are available in each')
|
' actions are available in each')
|
||||||
|
|
||||||
|
|
||||||
class Search(PreferencesPlugin):
|
class Search(PreferencesPlugin):
|
||||||
name = 'Search'
|
name = 'Search'
|
||||||
icon = I('search.png')
|
icon = I('search.png')
|
||||||
@ -1058,6 +1137,7 @@ class Search(PreferencesPlugin):
|
|||||||
config_widget = 'calibre.gui2.preferences.search'
|
config_widget = 'calibre.gui2.preferences.search'
|
||||||
description = _('Customize the way searching for books works in calibre')
|
description = _('Customize the way searching for books works in calibre')
|
||||||
|
|
||||||
|
|
||||||
class InputOptions(PreferencesPlugin):
|
class InputOptions(PreferencesPlugin):
|
||||||
name = 'Input Options'
|
name = 'Input Options'
|
||||||
icon = I('arrow-down.png')
|
icon = I('arrow-down.png')
|
||||||
@ -1074,6 +1154,7 @@ class InputOptions(PreferencesPlugin):
|
|||||||
self.config_widget = 'calibre.gui2.preferences.conversion:InputOptions'
|
self.config_widget = 'calibre.gui2.preferences.conversion:InputOptions'
|
||||||
return PreferencesPlugin.create_widget(self, *args, **kwargs)
|
return PreferencesPlugin.create_widget(self, *args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
class CommonOptions(PreferencesPlugin):
|
class CommonOptions(PreferencesPlugin):
|
||||||
name = 'Common Options'
|
name = 'Common Options'
|
||||||
icon = I('convert.png')
|
icon = I('convert.png')
|
||||||
@ -1085,6 +1166,7 @@ class CommonOptions(PreferencesPlugin):
|
|||||||
config_widget = 'calibre.gui2.preferences.conversion:CommonOptions'
|
config_widget = 'calibre.gui2.preferences.conversion:CommonOptions'
|
||||||
description = _('Set conversion options common to all formats')
|
description = _('Set conversion options common to all formats')
|
||||||
|
|
||||||
|
|
||||||
class OutputOptions(PreferencesPlugin):
|
class OutputOptions(PreferencesPlugin):
|
||||||
name = 'Output Options'
|
name = 'Output Options'
|
||||||
icon = I('arrow-up.png')
|
icon = I('arrow-up.png')
|
||||||
@ -1096,6 +1178,7 @@ class OutputOptions(PreferencesPlugin):
|
|||||||
config_widget = 'calibre.gui2.preferences.conversion:OutputOptions'
|
config_widget = 'calibre.gui2.preferences.conversion:OutputOptions'
|
||||||
description = _('Set conversion options specific to each output format')
|
description = _('Set conversion options specific to each output format')
|
||||||
|
|
||||||
|
|
||||||
class Adding(PreferencesPlugin):
|
class Adding(PreferencesPlugin):
|
||||||
name = 'Adding'
|
name = 'Adding'
|
||||||
icon = I('add_book.png')
|
icon = I('add_book.png')
|
||||||
@ -1108,6 +1191,7 @@ class Adding(PreferencesPlugin):
|
|||||||
description = _('Control how calibre reads metadata from files when '
|
description = _('Control how calibre reads metadata from files when '
|
||||||
'adding books')
|
'adding books')
|
||||||
|
|
||||||
|
|
||||||
class Saving(PreferencesPlugin):
|
class Saving(PreferencesPlugin):
|
||||||
name = 'Saving'
|
name = 'Saving'
|
||||||
icon = I('save.png')
|
icon = I('save.png')
|
||||||
@ -1120,6 +1204,7 @@ class Saving(PreferencesPlugin):
|
|||||||
description = _('Control how calibre exports files from its database '
|
description = _('Control how calibre exports files from its database '
|
||||||
'to disk when using Save to disk')
|
'to disk when using Save to disk')
|
||||||
|
|
||||||
|
|
||||||
class Sending(PreferencesPlugin):
|
class Sending(PreferencesPlugin):
|
||||||
name = 'Sending'
|
name = 'Sending'
|
||||||
icon = I('sync.png')
|
icon = I('sync.png')
|
||||||
@ -1132,6 +1217,7 @@ class Sending(PreferencesPlugin):
|
|||||||
description = _('Control how calibre transfers files to your '
|
description = _('Control how calibre transfers files to your '
|
||||||
'ebook reader')
|
'ebook reader')
|
||||||
|
|
||||||
|
|
||||||
class Plugboard(PreferencesPlugin):
|
class Plugboard(PreferencesPlugin):
|
||||||
name = 'Plugboard'
|
name = 'Plugboard'
|
||||||
icon = I('plugboard.png')
|
icon = I('plugboard.png')
|
||||||
@ -1143,6 +1229,7 @@ class Plugboard(PreferencesPlugin):
|
|||||||
config_widget = 'calibre.gui2.preferences.plugboard'
|
config_widget = 'calibre.gui2.preferences.plugboard'
|
||||||
description = _('Change metadata fields before saving/sending')
|
description = _('Change metadata fields before saving/sending')
|
||||||
|
|
||||||
|
|
||||||
class TemplateFunctions(PreferencesPlugin):
|
class TemplateFunctions(PreferencesPlugin):
|
||||||
name = 'TemplateFunctions'
|
name = 'TemplateFunctions'
|
||||||
icon = I('template_funcs.png')
|
icon = I('template_funcs.png')
|
||||||
@ -1154,6 +1241,7 @@ class TemplateFunctions(PreferencesPlugin):
|
|||||||
config_widget = 'calibre.gui2.preferences.template_functions'
|
config_widget = 'calibre.gui2.preferences.template_functions'
|
||||||
description = _('Create your own template functions')
|
description = _('Create your own template functions')
|
||||||
|
|
||||||
|
|
||||||
class Email(PreferencesPlugin):
|
class Email(PreferencesPlugin):
|
||||||
name = 'Email'
|
name = 'Email'
|
||||||
icon = I('mail.png')
|
icon = I('mail.png')
|
||||||
@ -1166,6 +1254,7 @@ class Email(PreferencesPlugin):
|
|||||||
description = _('Setup sharing of books via email. Can be used '
|
description = _('Setup sharing of books via email. Can be used '
|
||||||
'for automatic sending of downloaded news to your devices')
|
'for automatic sending of downloaded news to your devices')
|
||||||
|
|
||||||
|
|
||||||
class Server(PreferencesPlugin):
|
class Server(PreferencesPlugin):
|
||||||
name = 'Server'
|
name = 'Server'
|
||||||
icon = I('network-server.png')
|
icon = I('network-server.png')
|
||||||
@ -1179,6 +1268,7 @@ class Server(PreferencesPlugin):
|
|||||||
'give you access to your calibre library from anywhere, '
|
'give you access to your calibre library from anywhere, '
|
||||||
'on any device, over the internet')
|
'on any device, over the internet')
|
||||||
|
|
||||||
|
|
||||||
class MetadataSources(PreferencesPlugin):
|
class MetadataSources(PreferencesPlugin):
|
||||||
name = 'Metadata download'
|
name = 'Metadata download'
|
||||||
icon = I('download-metadata.png')
|
icon = I('download-metadata.png')
|
||||||
@ -1190,6 +1280,7 @@ class MetadataSources(PreferencesPlugin):
|
|||||||
config_widget = 'calibre.gui2.preferences.metadata_sources'
|
config_widget = 'calibre.gui2.preferences.metadata_sources'
|
||||||
description = _('Control how calibre downloads ebook metadata from the net')
|
description = _('Control how calibre downloads ebook metadata from the net')
|
||||||
|
|
||||||
|
|
||||||
class IgnoredDevices(PreferencesPlugin):
|
class IgnoredDevices(PreferencesPlugin):
|
||||||
name = 'Ignored Devices'
|
name = 'Ignored Devices'
|
||||||
icon = I('reader.png')
|
icon = I('reader.png')
|
||||||
@ -1215,6 +1306,7 @@ class Plugins(PreferencesPlugin):
|
|||||||
description = _('Add/remove/customize various bits of calibre '
|
description = _('Add/remove/customize various bits of calibre '
|
||||||
'functionality')
|
'functionality')
|
||||||
|
|
||||||
|
|
||||||
class Tweaks(PreferencesPlugin):
|
class Tweaks(PreferencesPlugin):
|
||||||
name = 'Tweaks'
|
name = 'Tweaks'
|
||||||
icon = I('tweaks.png')
|
icon = I('tweaks.png')
|
||||||
@ -1226,6 +1318,7 @@ class Tweaks(PreferencesPlugin):
|
|||||||
config_widget = 'calibre.gui2.preferences.tweaks'
|
config_widget = 'calibre.gui2.preferences.tweaks'
|
||||||
description = _('Fine tune how calibre behaves in various contexts')
|
description = _('Fine tune how calibre behaves in various contexts')
|
||||||
|
|
||||||
|
|
||||||
class Keyboard(PreferencesPlugin):
|
class Keyboard(PreferencesPlugin):
|
||||||
name = 'Keyboard'
|
name = 'Keyboard'
|
||||||
icon = I('keyboard-prefs.png')
|
icon = I('keyboard-prefs.png')
|
||||||
@ -1237,6 +1330,7 @@ class Keyboard(PreferencesPlugin):
|
|||||||
config_widget = 'calibre.gui2.preferences.keyboard'
|
config_widget = 'calibre.gui2.preferences.keyboard'
|
||||||
description = _('Customize the keyboard shortcuts used by calibre')
|
description = _('Customize the keyboard shortcuts used by calibre')
|
||||||
|
|
||||||
|
|
||||||
class Misc(PreferencesPlugin):
|
class Misc(PreferencesPlugin):
|
||||||
name = 'Misc'
|
name = 'Misc'
|
||||||
icon = I('exec.png')
|
icon = I('exec.png')
|
||||||
@ -1256,6 +1350,8 @@ plugins += [LookAndFeel, Behavior, Columns, Toolbar, Search, InputOptions,
|
|||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
# Store plugins {{{
|
# Store plugins {{{
|
||||||
|
|
||||||
|
|
||||||
class StoreAmazonKindleStore(StoreBase):
|
class StoreAmazonKindleStore(StoreBase):
|
||||||
name = 'Amazon Kindle'
|
name = 'Amazon Kindle'
|
||||||
description = u'Kindle books from Amazon.'
|
description = u'Kindle books from Amazon.'
|
||||||
@ -1265,6 +1361,7 @@ class StoreAmazonKindleStore(StoreBase):
|
|||||||
formats = ['KINDLE']
|
formats = ['KINDLE']
|
||||||
affiliate = False
|
affiliate = False
|
||||||
|
|
||||||
|
|
||||||
class StoreSonyStore(StoreBase):
|
class StoreSonyStore(StoreBase):
|
||||||
name = 'SONY Reader Store'
|
name = 'SONY Reader Store'
|
||||||
description = u'SONY Reader books.'
|
description = u'SONY Reader books.'
|
||||||
@ -1275,12 +1372,14 @@ class StoreSonyStore(StoreBase):
|
|||||||
formats = ['SONY']
|
formats = ['SONY']
|
||||||
affiliate = False
|
affiliate = False
|
||||||
|
|
||||||
|
|
||||||
class StoreSonyAUStore(StoreSonyStore):
|
class StoreSonyAUStore(StoreSonyStore):
|
||||||
name = 'SONY Reader (Australia) Store'
|
name = 'SONY Reader (Australia) Store'
|
||||||
description = u'SONY Reader books (Australia).'
|
description = u'SONY Reader books (Australia).'
|
||||||
actual_plugin = 'calibre.gui2.store.stores.sony_au_plugin:SonyStore'
|
actual_plugin = 'calibre.gui2.store.stores.sony_au_plugin:SonyStore'
|
||||||
headquarters = 'AU'
|
headquarters = 'AU'
|
||||||
|
|
||||||
|
|
||||||
class StoreAmazonAUKindleStore(StoreBase):
|
class StoreAmazonAUKindleStore(StoreBase):
|
||||||
name = 'Amazon AU Kindle'
|
name = 'Amazon AU Kindle'
|
||||||
author = u'Kovid Goyal'
|
author = u'Kovid Goyal'
|
||||||
@ -1290,6 +1389,7 @@ class StoreAmazonAUKindleStore(StoreBase):
|
|||||||
headquarters = 'AU'
|
headquarters = 'AU'
|
||||||
formats = ['KINDLE']
|
formats = ['KINDLE']
|
||||||
|
|
||||||
|
|
||||||
class StoreAmazonCAKindleStore(StoreBase):
|
class StoreAmazonCAKindleStore(StoreBase):
|
||||||
name = 'Amazon CA Kindle'
|
name = 'Amazon CA Kindle'
|
||||||
author = u'Kovid Goyal'
|
author = u'Kovid Goyal'
|
||||||
@ -1299,6 +1399,7 @@ class StoreAmazonCAKindleStore(StoreBase):
|
|||||||
headquarters = 'CA'
|
headquarters = 'CA'
|
||||||
formats = ['KINDLE']
|
formats = ['KINDLE']
|
||||||
|
|
||||||
|
|
||||||
class StoreAmazonINKindleStore(StoreBase):
|
class StoreAmazonINKindleStore(StoreBase):
|
||||||
name = 'Amazon IN Kindle'
|
name = 'Amazon IN Kindle'
|
||||||
author = u'Kovid Goyal'
|
author = u'Kovid Goyal'
|
||||||
@ -1308,6 +1409,7 @@ class StoreAmazonINKindleStore(StoreBase):
|
|||||||
headquarters = 'IN'
|
headquarters = 'IN'
|
||||||
formats = ['KINDLE']
|
formats = ['KINDLE']
|
||||||
|
|
||||||
|
|
||||||
class StoreAmazonDEKindleStore(StoreBase):
|
class StoreAmazonDEKindleStore(StoreBase):
|
||||||
name = 'Amazon DE Kindle'
|
name = 'Amazon DE Kindle'
|
||||||
author = 'Kovid Goyal'
|
author = 'Kovid Goyal'
|
||||||
@ -1317,6 +1419,7 @@ class StoreAmazonDEKindleStore(StoreBase):
|
|||||||
headquarters = 'DE'
|
headquarters = 'DE'
|
||||||
formats = ['KINDLE']
|
formats = ['KINDLE']
|
||||||
|
|
||||||
|
|
||||||
class StoreAmazonFRKindleStore(StoreBase):
|
class StoreAmazonFRKindleStore(StoreBase):
|
||||||
name = 'Amazon FR Kindle'
|
name = 'Amazon FR Kindle'
|
||||||
author = 'Kovid Goyal'
|
author = 'Kovid Goyal'
|
||||||
@ -1326,6 +1429,7 @@ class StoreAmazonFRKindleStore(StoreBase):
|
|||||||
headquarters = 'FR'
|
headquarters = 'FR'
|
||||||
formats = ['KINDLE']
|
formats = ['KINDLE']
|
||||||
|
|
||||||
|
|
||||||
class StoreAmazonITKindleStore(StoreBase):
|
class StoreAmazonITKindleStore(StoreBase):
|
||||||
name = 'Amazon IT Kindle'
|
name = 'Amazon IT Kindle'
|
||||||
author = 'Kovid Goyal'
|
author = 'Kovid Goyal'
|
||||||
@ -1335,6 +1439,7 @@ class StoreAmazonITKindleStore(StoreBase):
|
|||||||
headquarters = 'IT'
|
headquarters = 'IT'
|
||||||
formats = ['KINDLE']
|
formats = ['KINDLE']
|
||||||
|
|
||||||
|
|
||||||
class StoreAmazonESKindleStore(StoreBase):
|
class StoreAmazonESKindleStore(StoreBase):
|
||||||
name = 'Amazon ES Kindle'
|
name = 'Amazon ES Kindle'
|
||||||
author = 'Kovid Goyal'
|
author = 'Kovid Goyal'
|
||||||
@ -1344,6 +1449,7 @@ class StoreAmazonESKindleStore(StoreBase):
|
|||||||
headquarters = 'ES'
|
headquarters = 'ES'
|
||||||
formats = ['KINDLE']
|
formats = ['KINDLE']
|
||||||
|
|
||||||
|
|
||||||
class StoreAmazonUKKindleStore(StoreBase):
|
class StoreAmazonUKKindleStore(StoreBase):
|
||||||
name = 'Amazon UK Kindle'
|
name = 'Amazon UK Kindle'
|
||||||
author = 'Kovid Goyal'
|
author = 'Kovid Goyal'
|
||||||
@ -1353,6 +1459,7 @@ class StoreAmazonUKKindleStore(StoreBase):
|
|||||||
headquarters = 'UK'
|
headquarters = 'UK'
|
||||||
formats = ['KINDLE']
|
formats = ['KINDLE']
|
||||||
|
|
||||||
|
|
||||||
class StoreArchiveOrgStore(StoreBase):
|
class StoreArchiveOrgStore(StoreBase):
|
||||||
name = 'Archive.org'
|
name = 'Archive.org'
|
||||||
description = u'An Internet library offering permanent access for researchers, historians, scholars, people with disabilities, and the general public to historical collections that exist in digital format.' # noqa
|
description = u'An Internet library offering permanent access for researchers, historians, scholars, people with disabilities, and the general public to historical collections that exist in digital format.' # noqa
|
||||||
@ -1362,6 +1469,7 @@ class StoreArchiveOrgStore(StoreBase):
|
|||||||
headquarters = 'US'
|
headquarters = 'US'
|
||||||
formats = ['DAISY', 'DJVU', 'EPUB', 'MOBI', 'PDF', 'TXT']
|
formats = ['DAISY', 'DJVU', 'EPUB', 'MOBI', 'PDF', 'TXT']
|
||||||
|
|
||||||
|
|
||||||
class StoreBubokPublishingStore(StoreBase):
|
class StoreBubokPublishingStore(StoreBase):
|
||||||
name = 'Bubok Spain'
|
name = 'Bubok Spain'
|
||||||
description = u'Bubok Publishing is a publisher, library and store of books of authors from all around the world. They have a big amount of books of a lot of topics' # noqa
|
description = u'Bubok Publishing is a publisher, library and store of books of authors from all around the world. They have a big amount of books of a lot of topics' # noqa
|
||||||
@ -1371,6 +1479,7 @@ class StoreBubokPublishingStore(StoreBase):
|
|||||||
headquarters = 'ES'
|
headquarters = 'ES'
|
||||||
formats = ['EPUB', 'PDF']
|
formats = ['EPUB', 'PDF']
|
||||||
|
|
||||||
|
|
||||||
class StoreBubokPortugalStore(StoreBase):
|
class StoreBubokPortugalStore(StoreBase):
|
||||||
name = 'Bubok Portugal'
|
name = 'Bubok Portugal'
|
||||||
description = u'Bubok Publishing Portugal is a publisher, library and store of books of authors from Portugal. They have a big amount of books of a lot of topics' # noqa
|
description = u'Bubok Publishing Portugal is a publisher, library and store of books of authors from Portugal. They have a big amount of books of a lot of topics' # noqa
|
||||||
@ -1380,6 +1489,7 @@ class StoreBubokPortugalStore(StoreBase):
|
|||||||
headquarters = 'PT'
|
headquarters = 'PT'
|
||||||
formats = ['EPUB', 'PDF']
|
formats = ['EPUB', 'PDF']
|
||||||
|
|
||||||
|
|
||||||
class StoreBaenWebScriptionStore(StoreBase):
|
class StoreBaenWebScriptionStore(StoreBase):
|
||||||
name = 'Baen Ebooks'
|
name = 'Baen Ebooks'
|
||||||
description = u'Sci-Fi & Fantasy brought to you by Jim Baen.'
|
description = u'Sci-Fi & Fantasy brought to you by Jim Baen.'
|
||||||
@ -1389,6 +1499,7 @@ class StoreBaenWebScriptionStore(StoreBase):
|
|||||||
headquarters = 'US'
|
headquarters = 'US'
|
||||||
formats = ['EPUB', 'LIT', 'LRF', 'MOBI', 'RB', 'RTF', 'ZIP']
|
formats = ['EPUB', 'LIT', 'LRF', 'MOBI', 'RB', 'RTF', 'ZIP']
|
||||||
|
|
||||||
|
|
||||||
class StoreBNStore(StoreBase):
|
class StoreBNStore(StoreBase):
|
||||||
name = 'Barnes and Noble'
|
name = 'Barnes and Noble'
|
||||||
description = u'The world\'s largest book seller. As the ultimate destination for book lovers, Barnes & Noble.com offers an incredible array of content.'
|
description = u'The world\'s largest book seller. As the ultimate destination for book lovers, Barnes & Noble.com offers an incredible array of content.'
|
||||||
@ -1397,6 +1508,7 @@ class StoreBNStore(StoreBase):
|
|||||||
headquarters = 'US'
|
headquarters = 'US'
|
||||||
formats = ['NOOK']
|
formats = ['NOOK']
|
||||||
|
|
||||||
|
|
||||||
class StoreBeamEBooksDEStore(StoreBase):
|
class StoreBeamEBooksDEStore(StoreBase):
|
||||||
name = 'Beam EBooks DE'
|
name = 'Beam EBooks DE'
|
||||||
author = 'Charles Haley'
|
author = 'Charles Haley'
|
||||||
@ -1408,6 +1520,7 @@ class StoreBeamEBooksDEStore(StoreBase):
|
|||||||
formats = ['EPUB', 'MOBI', 'PDF']
|
formats = ['EPUB', 'MOBI', 'PDF']
|
||||||
affiliate = True
|
affiliate = True
|
||||||
|
|
||||||
|
|
||||||
class StoreBiblioStore(StoreBase):
|
class StoreBiblioStore(StoreBase):
|
||||||
name = u'Библио.бг'
|
name = u'Библио.бг'
|
||||||
author = 'Alex Stanev'
|
author = 'Alex Stanev'
|
||||||
@ -1417,6 +1530,7 @@ class StoreBiblioStore(StoreBase):
|
|||||||
headquarters = 'BG'
|
headquarters = 'BG'
|
||||||
formats = ['EPUB, PDF']
|
formats = ['EPUB, PDF']
|
||||||
|
|
||||||
|
|
||||||
class StoreCdpStore(StoreBase):
|
class StoreCdpStore(StoreBase):
|
||||||
name = 'Cdp.pl'
|
name = 'Cdp.pl'
|
||||||
author = u'Tomasz Długosz'
|
author = u'Tomasz Długosz'
|
||||||
@ -1428,6 +1542,7 @@ class StoreCdpStore(StoreBase):
|
|||||||
formats = ['EPUB', 'MOBI', 'PDF']
|
formats = ['EPUB', 'MOBI', 'PDF']
|
||||||
affiliate = True
|
affiliate = True
|
||||||
|
|
||||||
|
|
||||||
class StoreChitankaStore(StoreBase):
|
class StoreChitankaStore(StoreBase):
|
||||||
name = u'Моята библиотека'
|
name = u'Моята библиотека'
|
||||||
author = 'Alex Stanev'
|
author = 'Alex Stanev'
|
||||||
@ -1438,6 +1553,7 @@ class StoreChitankaStore(StoreBase):
|
|||||||
headquarters = 'BG'
|
headquarters = 'BG'
|
||||||
formats = ['FB2', 'EPUB', 'TXT', 'SFB']
|
formats = ['FB2', 'EPUB', 'TXT', 'SFB']
|
||||||
|
|
||||||
|
|
||||||
class StoreEbookNLStore(StoreBase):
|
class StoreEbookNLStore(StoreBase):
|
||||||
name = 'eBook.nl'
|
name = 'eBook.nl'
|
||||||
description = u'De eBookwinkel van Nederland'
|
description = u'De eBookwinkel van Nederland'
|
||||||
@ -1447,6 +1563,7 @@ class StoreEbookNLStore(StoreBase):
|
|||||||
formats = ['EPUB', 'PDF']
|
formats = ['EPUB', 'PDF']
|
||||||
affiliate = False
|
affiliate = False
|
||||||
|
|
||||||
|
|
||||||
class StoreEbookpointStore(StoreBase):
|
class StoreEbookpointStore(StoreBase):
|
||||||
name = 'Ebookpoint'
|
name = 'Ebookpoint'
|
||||||
author = u'Tomasz Długosz'
|
author = u'Tomasz Długosz'
|
||||||
@ -1458,6 +1575,7 @@ class StoreEbookpointStore(StoreBase):
|
|||||||
formats = ['EPUB', 'MOBI', 'PDF']
|
formats = ['EPUB', 'MOBI', 'PDF']
|
||||||
affiliate = True
|
affiliate = True
|
||||||
|
|
||||||
|
|
||||||
class StoreEbookscomStore(StoreBase):
|
class StoreEbookscomStore(StoreBase):
|
||||||
name = 'eBooks.com'
|
name = 'eBooks.com'
|
||||||
description = u'Sells books in multiple electronic formats in all categories. Technical infrastructure is cutting edge, robust and scalable, with servers in the US and Europe.' # noqa
|
description = u'Sells books in multiple electronic formats in all categories. Technical infrastructure is cutting edge, robust and scalable, with servers in the US and Europe.' # noqa
|
||||||
@ -1467,6 +1585,7 @@ class StoreEbookscomStore(StoreBase):
|
|||||||
formats = ['EPUB', 'LIT', 'MOBI', 'PDF']
|
formats = ['EPUB', 'LIT', 'MOBI', 'PDF']
|
||||||
affiliate = True
|
affiliate = True
|
||||||
|
|
||||||
|
|
||||||
class StoreEbooksGratuitsStore(StoreBase):
|
class StoreEbooksGratuitsStore(StoreBase):
|
||||||
name = 'EbooksGratuits.com'
|
name = 'EbooksGratuits.com'
|
||||||
description = u'Ebooks Libres et Gratuits'
|
description = u'Ebooks Libres et Gratuits'
|
||||||
@ -1486,6 +1605,7 @@ class StoreEbooksGratuitsStore(StoreBase):
|
|||||||
# formats = ['EPUB', 'PDF']
|
# formats = ['EPUB', 'PDF']
|
||||||
# affiliate = True
|
# affiliate = True
|
||||||
|
|
||||||
|
|
||||||
class StoreEKnigiStore(StoreBase):
|
class StoreEKnigiStore(StoreBase):
|
||||||
name = u'еКниги'
|
name = u'еКниги'
|
||||||
author = 'Alex Stanev'
|
author = 'Alex Stanev'
|
||||||
@ -1496,6 +1616,7 @@ class StoreEKnigiStore(StoreBase):
|
|||||||
formats = ['EPUB', 'PDF', 'HTML']
|
formats = ['EPUB', 'PDF', 'HTML']
|
||||||
affiliate = True
|
affiliate = True
|
||||||
|
|
||||||
|
|
||||||
class StoreEmpikStore(StoreBase):
|
class StoreEmpikStore(StoreBase):
|
||||||
name = 'Empik'
|
name = 'Empik'
|
||||||
author = u'Tomasz Długosz'
|
author = u'Tomasz Długosz'
|
||||||
@ -1506,6 +1627,7 @@ class StoreEmpikStore(StoreBase):
|
|||||||
formats = ['EPUB', 'MOBI', 'PDF']
|
formats = ['EPUB', 'MOBI', 'PDF']
|
||||||
affiliate = True
|
affiliate = True
|
||||||
|
|
||||||
|
|
||||||
class StoreFeedbooksStore(StoreBase):
|
class StoreFeedbooksStore(StoreBase):
|
||||||
name = 'Feedbooks'
|
name = 'Feedbooks'
|
||||||
description = u'Feedbooks is a cloud publishing and distribution service, connected to a large ecosystem of reading systems and social networks. Provides a variety of genres from independent and classic books.' # noqa
|
description = u'Feedbooks is a cloud publishing and distribution service, connected to a large ecosystem of reading systems and social networks. Provides a variety of genres from independent and classic books.' # noqa
|
||||||
@ -1514,6 +1636,7 @@ class StoreFeedbooksStore(StoreBase):
|
|||||||
headquarters = 'FR'
|
headquarters = 'FR'
|
||||||
formats = ['EPUB', 'MOBI', 'PDF']
|
formats = ['EPUB', 'MOBI', 'PDF']
|
||||||
|
|
||||||
|
|
||||||
class StoreGoogleBooksStore(StoreBase):
|
class StoreGoogleBooksStore(StoreBase):
|
||||||
name = 'Google Books'
|
name = 'Google Books'
|
||||||
description = u'Google Books'
|
description = u'Google Books'
|
||||||
@ -1522,6 +1645,7 @@ class StoreGoogleBooksStore(StoreBase):
|
|||||||
headquarters = 'US'
|
headquarters = 'US'
|
||||||
formats = ['EPUB', 'PDF', 'TXT']
|
formats = ['EPUB', 'PDF', 'TXT']
|
||||||
|
|
||||||
|
|
||||||
class StoreGutenbergStore(StoreBase):
|
class StoreGutenbergStore(StoreBase):
|
||||||
name = 'Project Gutenberg'
|
name = 'Project Gutenberg'
|
||||||
description = u'The first producer of free ebooks. Free in the United States because their copyright has expired. They may not be free of copyright in other countries. Readers outside of the United States must check the copyright laws of their countries before downloading or redistributing our ebooks.' # noqa
|
description = u'The first producer of free ebooks. Free in the United States because their copyright has expired. They may not be free of copyright in other countries. Readers outside of the United States must check the copyright laws of their countries before downloading or redistributing our ebooks.' # noqa
|
||||||
@ -1531,6 +1655,7 @@ class StoreGutenbergStore(StoreBase):
|
|||||||
headquarters = 'US'
|
headquarters = 'US'
|
||||||
formats = ['EPUB', 'HTML', 'MOBI', 'PDB', 'TXT']
|
formats = ['EPUB', 'HTML', 'MOBI', 'PDB', 'TXT']
|
||||||
|
|
||||||
|
|
||||||
class StoreKoboStore(StoreBase):
|
class StoreKoboStore(StoreBase):
|
||||||
name = 'Kobo'
|
name = 'Kobo'
|
||||||
description = u'With over 2.3 million eBooks to browse we have engaged readers in over 200 countries in Kobo eReading. Our eBook listings include New York Times Bestsellers, award winners, classics and more!' # noqa
|
description = u'With over 2.3 million eBooks to browse we have engaged readers in over 200 countries in Kobo eReading. Our eBook listings include New York Times Bestsellers, award winners, classics and more!' # noqa
|
||||||
@ -1540,6 +1665,7 @@ class StoreKoboStore(StoreBase):
|
|||||||
formats = ['EPUB']
|
formats = ['EPUB']
|
||||||
affiliate = True
|
affiliate = True
|
||||||
|
|
||||||
|
|
||||||
class StoreKoobeStore(StoreBase):
|
class StoreKoobeStore(StoreBase):
|
||||||
name = 'Koobe'
|
name = 'Koobe'
|
||||||
author = u'Tomasz Długosz'
|
author = u'Tomasz Długosz'
|
||||||
@ -1551,6 +1677,7 @@ class StoreKoobeStore(StoreBase):
|
|||||||
formats = ['EPUB', 'MOBI', 'PDF']
|
formats = ['EPUB', 'MOBI', 'PDF']
|
||||||
affiliate = True
|
affiliate = True
|
||||||
|
|
||||||
|
|
||||||
class StoreLegimiStore(StoreBase):
|
class StoreLegimiStore(StoreBase):
|
||||||
name = 'Legimi'
|
name = 'Legimi'
|
||||||
author = u'Tomasz Długosz'
|
author = u'Tomasz Długosz'
|
||||||
@ -1561,6 +1688,7 @@ class StoreLegimiStore(StoreBase):
|
|||||||
formats = ['EPUB', 'PDF', 'MOBI']
|
formats = ['EPUB', 'PDF', 'MOBI']
|
||||||
affiliate = True
|
affiliate = True
|
||||||
|
|
||||||
|
|
||||||
class StoreLibreDEStore(StoreBase):
|
class StoreLibreDEStore(StoreBase):
|
||||||
name = 'ebook.de'
|
name = 'ebook.de'
|
||||||
author = 'Charles Haley'
|
author = 'Charles Haley'
|
||||||
@ -1571,6 +1699,7 @@ class StoreLibreDEStore(StoreBase):
|
|||||||
formats = ['EPUB', 'PDF']
|
formats = ['EPUB', 'PDF']
|
||||||
affiliate = True
|
affiliate = True
|
||||||
|
|
||||||
|
|
||||||
class StoreLitResStore(StoreBase):
|
class StoreLitResStore(StoreBase):
|
||||||
name = 'LitRes'
|
name = 'LitRes'
|
||||||
description = u'ebooks from LitRes.ru'
|
description = u'ebooks from LitRes.ru'
|
||||||
@ -1582,6 +1711,7 @@ class StoreLitResStore(StoreBase):
|
|||||||
formats = ['EPUB', 'TXT', 'RTF', 'HTML', 'FB2', 'LRF', 'PDF', 'MOBI', 'LIT', 'ISILO3', 'JAR', 'RB', 'PRC']
|
formats = ['EPUB', 'TXT', 'RTF', 'HTML', 'FB2', 'LRF', 'PDF', 'MOBI', 'LIT', 'ISILO3', 'JAR', 'RB', 'PRC']
|
||||||
affiliate = True
|
affiliate = True
|
||||||
|
|
||||||
|
|
||||||
class StoreManyBooksStore(StoreBase):
|
class StoreManyBooksStore(StoreBase):
|
||||||
name = 'ManyBooks'
|
name = 'ManyBooks'
|
||||||
description = u'Public domain and creative commons works from many sources.'
|
description = u'Public domain and creative commons works from many sources.'
|
||||||
@ -1591,6 +1721,7 @@ class StoreManyBooksStore(StoreBase):
|
|||||||
headquarters = 'US'
|
headquarters = 'US'
|
||||||
formats = ['EPUB', 'FB2', 'JAR', 'LIT', 'LRF', 'MOBI', 'PDB', 'PDF', 'RB', 'RTF', 'TCR', 'TXT', 'ZIP']
|
formats = ['EPUB', 'FB2', 'JAR', 'LIT', 'LRF', 'MOBI', 'PDB', 'PDF', 'RB', 'RTF', 'TCR', 'TXT', 'ZIP']
|
||||||
|
|
||||||
|
|
||||||
class StoreMillsBoonUKStore(StoreBase):
|
class StoreMillsBoonUKStore(StoreBase):
|
||||||
name = 'Mills and Boon UK'
|
name = 'Mills and Boon UK'
|
||||||
author = 'Charles Haley'
|
author = 'Charles Haley'
|
||||||
@ -1601,6 +1732,7 @@ class StoreMillsBoonUKStore(StoreBase):
|
|||||||
formats = ['EPUB']
|
formats = ['EPUB']
|
||||||
affiliate = True
|
affiliate = True
|
||||||
|
|
||||||
|
|
||||||
class StoreMobileReadStore(StoreBase):
|
class StoreMobileReadStore(StoreBase):
|
||||||
name = 'MobileRead'
|
name = 'MobileRead'
|
||||||
description = u'Ebooks handcrafted with the utmost care.'
|
description = u'Ebooks handcrafted with the utmost care.'
|
||||||
@ -1610,6 +1742,7 @@ class StoreMobileReadStore(StoreBase):
|
|||||||
headquarters = 'CH'
|
headquarters = 'CH'
|
||||||
formats = ['EPUB', 'IMP', 'LRF', 'LIT', 'MOBI', 'PDF']
|
formats = ['EPUB', 'IMP', 'LRF', 'LIT', 'MOBI', 'PDF']
|
||||||
|
|
||||||
|
|
||||||
class StoreNextoStore(StoreBase):
|
class StoreNextoStore(StoreBase):
|
||||||
name = 'Nexto'
|
name = 'Nexto'
|
||||||
author = u'Tomasz Długosz'
|
author = u'Tomasz Długosz'
|
||||||
@ -1620,6 +1753,7 @@ class StoreNextoStore(StoreBase):
|
|||||||
formats = ['EPUB', 'MOBI', 'PDF']
|
formats = ['EPUB', 'MOBI', 'PDF']
|
||||||
affiliate = True
|
affiliate = True
|
||||||
|
|
||||||
|
|
||||||
class StoreNookUKStore(StoreBase):
|
class StoreNookUKStore(StoreBase):
|
||||||
name = 'Nook UK'
|
name = 'Nook UK'
|
||||||
author = 'Charles Haley'
|
author = 'Charles Haley'
|
||||||
@ -1629,6 +1763,7 @@ class StoreNookUKStore(StoreBase):
|
|||||||
headquarters = 'UK'
|
headquarters = 'UK'
|
||||||
formats = ['NOOK']
|
formats = ['NOOK']
|
||||||
|
|
||||||
|
|
||||||
class StoreOpenBooksStore(StoreBase):
|
class StoreOpenBooksStore(StoreBase):
|
||||||
name = 'Open Books'
|
name = 'Open Books'
|
||||||
description = u'Comprehensive listing of DRM free ebooks from a variety of sources provided by users of calibre.'
|
description = u'Comprehensive listing of DRM free ebooks from a variety of sources provided by users of calibre.'
|
||||||
@ -1637,6 +1772,7 @@ class StoreOpenBooksStore(StoreBase):
|
|||||||
drm_free_only = True
|
drm_free_only = True
|
||||||
headquarters = 'US'
|
headquarters = 'US'
|
||||||
|
|
||||||
|
|
||||||
class StoreOzonRUStore(StoreBase):
|
class StoreOzonRUStore(StoreBase):
|
||||||
name = 'OZON.ru'
|
name = 'OZON.ru'
|
||||||
description = u'ebooks from OZON.ru'
|
description = u'ebooks from OZON.ru'
|
||||||
@ -1648,6 +1784,7 @@ class StoreOzonRUStore(StoreBase):
|
|||||||
formats = ['TXT', 'PDF', 'DJVU', 'RTF', 'DOC', 'JAR', 'FB2']
|
formats = ['TXT', 'PDF', 'DJVU', 'RTF', 'DOC', 'JAR', 'FB2']
|
||||||
affiliate = True
|
affiliate = True
|
||||||
|
|
||||||
|
|
||||||
class StorePragmaticBookshelfStore(StoreBase):
|
class StorePragmaticBookshelfStore(StoreBase):
|
||||||
name = 'Pragmatic Bookshelf'
|
name = 'Pragmatic Bookshelf'
|
||||||
description = u'The Pragmatic Bookshelf\'s collection of programming and tech books avaliable as ebooks.'
|
description = u'The Pragmatic Bookshelf\'s collection of programming and tech books avaliable as ebooks.'
|
||||||
@ -1657,6 +1794,7 @@ class StorePragmaticBookshelfStore(StoreBase):
|
|||||||
headquarters = 'US'
|
headquarters = 'US'
|
||||||
formats = ['EPUB', 'MOBI', 'PDF']
|
formats = ['EPUB', 'MOBI', 'PDF']
|
||||||
|
|
||||||
|
|
||||||
class StorePublioStore(StoreBase):
|
class StorePublioStore(StoreBase):
|
||||||
name = 'Publio'
|
name = 'Publio'
|
||||||
description = u'Publio.pl to księgarnia internetowa, w której mogą Państwo nabyć e-booki i audiobooki.'
|
description = u'Publio.pl to księgarnia internetowa, w której mogą Państwo nabyć e-booki i audiobooki.'
|
||||||
@ -1667,6 +1805,7 @@ class StorePublioStore(StoreBase):
|
|||||||
formats = ['EPUB', 'MOBI', 'PDF']
|
formats = ['EPUB', 'MOBI', 'PDF']
|
||||||
affiliate = True
|
affiliate = True
|
||||||
|
|
||||||
|
|
||||||
class StoreRW2010Store(StoreBase):
|
class StoreRW2010Store(StoreBase):
|
||||||
name = 'RW2010'
|
name = 'RW2010'
|
||||||
description = u'Polski serwis self-publishingowy. Pliki PDF, EPUB i MOBI. Maksymalna cena utworu nie przekracza u nas 10 złotych!'
|
description = u'Polski serwis self-publishingowy. Pliki PDF, EPUB i MOBI. Maksymalna cena utworu nie przekracza u nas 10 złotych!'
|
||||||
@ -1677,6 +1816,7 @@ class StoreRW2010Store(StoreBase):
|
|||||||
headquarters = 'PL'
|
headquarters = 'PL'
|
||||||
formats = ['EPUB', 'MOBI', 'PDF']
|
formats = ['EPUB', 'MOBI', 'PDF']
|
||||||
|
|
||||||
|
|
||||||
class StoreSmashwordsStore(StoreBase):
|
class StoreSmashwordsStore(StoreBase):
|
||||||
name = 'Smashwords'
|
name = 'Smashwords'
|
||||||
description = u'An ebook publishing and distribution platform for ebook authors, publishers and readers. Covers many genres and formats.'
|
description = u'An ebook publishing and distribution platform for ebook authors, publishers and readers. Covers many genres and formats.'
|
||||||
@ -1687,6 +1827,7 @@ class StoreSmashwordsStore(StoreBase):
|
|||||||
formats = ['EPUB', 'HTML', 'LRF', 'MOBI', 'PDB', 'RTF', 'TXT']
|
formats = ['EPUB', 'HTML', 'LRF', 'MOBI', 'PDB', 'RTF', 'TXT']
|
||||||
affiliate = True
|
affiliate = True
|
||||||
|
|
||||||
|
|
||||||
class StoreVirtualoStore(StoreBase):
|
class StoreVirtualoStore(StoreBase):
|
||||||
name = 'Virtualo'
|
name = 'Virtualo'
|
||||||
author = u'Tomasz Długosz'
|
author = u'Tomasz Długosz'
|
||||||
@ -1697,6 +1838,7 @@ class StoreVirtualoStore(StoreBase):
|
|||||||
formats = ['EPUB', 'MOBI', 'PDF']
|
formats = ['EPUB', 'MOBI', 'PDF']
|
||||||
affiliate = True
|
affiliate = True
|
||||||
|
|
||||||
|
|
||||||
class StoreWaterstonesUKStore(StoreBase):
|
class StoreWaterstonesUKStore(StoreBase):
|
||||||
name = 'Waterstones UK'
|
name = 'Waterstones UK'
|
||||||
author = 'Charles Haley'
|
author = 'Charles Haley'
|
||||||
@ -1707,6 +1849,7 @@ class StoreWaterstonesUKStore(StoreBase):
|
|||||||
formats = ['EPUB', 'PDF']
|
formats = ['EPUB', 'PDF']
|
||||||
affiliate = False
|
affiliate = False
|
||||||
|
|
||||||
|
|
||||||
class StoreWeightlessBooksStore(StoreBase):
|
class StoreWeightlessBooksStore(StoreBase):
|
||||||
name = 'Weightless Books'
|
name = 'Weightless Books'
|
||||||
description = u'An independent DRM-free ebooksite devoted to ebooks of all sorts.'
|
description = u'An independent DRM-free ebooksite devoted to ebooks of all sorts.'
|
||||||
@ -1716,6 +1859,7 @@ class StoreWeightlessBooksStore(StoreBase):
|
|||||||
headquarters = 'US'
|
headquarters = 'US'
|
||||||
formats = ['EPUB', 'HTML', 'LIT', 'MOBI', 'PDF']
|
formats = ['EPUB', 'HTML', 'LIT', 'MOBI', 'PDF']
|
||||||
|
|
||||||
|
|
||||||
class StoreWHSmithUKStore(StoreBase):
|
class StoreWHSmithUKStore(StoreBase):
|
||||||
name = 'WH Smith UK'
|
name = 'WH Smith UK'
|
||||||
author = 'Charles Haley'
|
author = 'Charles Haley'
|
||||||
@ -1725,6 +1869,7 @@ class StoreWHSmithUKStore(StoreBase):
|
|||||||
headquarters = 'UK'
|
headquarters = 'UK'
|
||||||
formats = ['EPUB', 'PDF']
|
formats = ['EPUB', 'PDF']
|
||||||
|
|
||||||
|
|
||||||
class StoreWolneLekturyStore(StoreBase):
|
class StoreWolneLekturyStore(StoreBase):
|
||||||
name = 'Wolne Lektury'
|
name = 'Wolne Lektury'
|
||||||
author = u'Tomasz Długosz'
|
author = u'Tomasz Długosz'
|
||||||
@ -1734,6 +1879,7 @@ class StoreWolneLekturyStore(StoreBase):
|
|||||||
headquarters = 'PL'
|
headquarters = 'PL'
|
||||||
formats = ['EPUB', 'MOBI', 'PDF', 'TXT', 'FB2']
|
formats = ['EPUB', 'MOBI', 'PDF', 'TXT', 'FB2']
|
||||||
|
|
||||||
|
|
||||||
class StoreWoblinkStore(StoreBase):
|
class StoreWoblinkStore(StoreBase):
|
||||||
name = 'Woblink'
|
name = 'Woblink'
|
||||||
author = u'Tomasz Długosz'
|
author = u'Tomasz Długosz'
|
||||||
@ -1744,6 +1890,7 @@ class StoreWoblinkStore(StoreBase):
|
|||||||
formats = ['EPUB', 'MOBI', 'PDF', 'WOBLINK']
|
formats = ['EPUB', 'MOBI', 'PDF', 'WOBLINK']
|
||||||
affiliate = True
|
affiliate = True
|
||||||
|
|
||||||
|
|
||||||
class XinXiiStore(StoreBase):
|
class XinXiiStore(StoreBase):
|
||||||
name = 'XinXii'
|
name = 'XinXii'
|
||||||
description = ''
|
description = ''
|
||||||
|
@ -7,6 +7,7 @@ import re, os, shutil
|
|||||||
from calibre import CurrentDir
|
from calibre import CurrentDir
|
||||||
from calibre.customize import Plugin
|
from calibre.customize import Plugin
|
||||||
|
|
||||||
|
|
||||||
class ConversionOption(object):
|
class ConversionOption(object):
|
||||||
|
|
||||||
'''
|
'''
|
||||||
@ -46,6 +47,7 @@ class ConversionOption(object):
|
|||||||
long_switch=self.long_switch, short_switch=self.short_switch,
|
long_switch=self.long_switch, short_switch=self.short_switch,
|
||||||
choices=self.choices)
|
choices=self.choices)
|
||||||
|
|
||||||
|
|
||||||
class OptionRecommendation(object):
|
class OptionRecommendation(object):
|
||||||
LOW = 1
|
LOW = 1
|
||||||
MED = 2
|
MED = 2
|
||||||
@ -82,6 +84,7 @@ class OptionRecommendation(object):
|
|||||||
repr(self.recommended_value) +
|
repr(self.recommended_value) +
|
||||||
' is not a string or a number')
|
' is not a string or a number')
|
||||||
|
|
||||||
|
|
||||||
class DummyReporter(object):
|
class DummyReporter(object):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@ -90,6 +93,7 @@ class DummyReporter(object):
|
|||||||
def __call__(self, percent, msg=''):
|
def __call__(self, percent, msg=''):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def gui_configuration_widget(name, parent, get_option_by_name,
|
def gui_configuration_widget(name, parent, get_option_by_name,
|
||||||
get_option_help, db, book_id, for_output=True):
|
get_option_help, db, book_id, for_output=True):
|
||||||
import importlib
|
import importlib
|
||||||
|
@ -39,6 +39,8 @@ class Plugin(_Plugin):
|
|||||||
self.height_pts = self.height * 72./self.dpi
|
self.height_pts = self.height * 72./self.dpi
|
||||||
|
|
||||||
# Input profiles {{{
|
# Input profiles {{{
|
||||||
|
|
||||||
|
|
||||||
class InputProfile(Plugin):
|
class InputProfile(Plugin):
|
||||||
|
|
||||||
author = 'Kovid Goyal'
|
author = 'Kovid Goyal'
|
||||||
@ -64,6 +66,7 @@ class SonyReaderInput(InputProfile):
|
|||||||
fbase = 12
|
fbase = 12
|
||||||
fsizes = [7.5, 9, 10, 12, 15.5, 20, 22, 24]
|
fsizes = [7.5, 9, 10, 12, 15.5, 20, 22, 24]
|
||||||
|
|
||||||
|
|
||||||
class SonyReader300Input(SonyReaderInput):
|
class SonyReader300Input(SonyReaderInput):
|
||||||
|
|
||||||
name = 'Sony Reader 300'
|
name = 'Sony Reader 300'
|
||||||
@ -72,6 +75,7 @@ class SonyReader300Input(SonyReaderInput):
|
|||||||
|
|
||||||
dpi = 200
|
dpi = 200
|
||||||
|
|
||||||
|
|
||||||
class SonyReader900Input(SonyReaderInput):
|
class SonyReader900Input(SonyReaderInput):
|
||||||
|
|
||||||
author = 'John Schember'
|
author = 'John Schember'
|
||||||
@ -81,6 +85,7 @@ class SonyReader900Input(SonyReaderInput):
|
|||||||
|
|
||||||
screen_size = (584, 978)
|
screen_size = (584, 978)
|
||||||
|
|
||||||
|
|
||||||
class MSReaderInput(InputProfile):
|
class MSReaderInput(InputProfile):
|
||||||
|
|
||||||
name = 'Microsoft Reader'
|
name = 'Microsoft Reader'
|
||||||
@ -92,6 +97,7 @@ class MSReaderInput(InputProfile):
|
|||||||
fbase = 13
|
fbase = 13
|
||||||
fsizes = [10, 11, 13, 16, 18, 20, 22, 26]
|
fsizes = [10, 11, 13, 16, 18, 20, 22, 26]
|
||||||
|
|
||||||
|
|
||||||
class MobipocketInput(InputProfile):
|
class MobipocketInput(InputProfile):
|
||||||
|
|
||||||
name = 'Mobipocket Books'
|
name = 'Mobipocket Books'
|
||||||
@ -105,6 +111,7 @@ class MobipocketInput(InputProfile):
|
|||||||
fbase = 18
|
fbase = 18
|
||||||
fsizes = [14, 14, 16, 18, 20, 22, 24, 26]
|
fsizes = [14, 14, 16, 18, 20, 22, 24, 26]
|
||||||
|
|
||||||
|
|
||||||
class HanlinV3Input(InputProfile):
|
class HanlinV3Input(InputProfile):
|
||||||
|
|
||||||
name = 'Hanlin V3'
|
name = 'Hanlin V3'
|
||||||
@ -117,6 +124,7 @@ class HanlinV3Input(InputProfile):
|
|||||||
fbase = 16
|
fbase = 16
|
||||||
fsizes = [12, 12, 14, 16, 18, 20, 22, 24]
|
fsizes = [12, 12, 14, 16, 18, 20, 22, 24]
|
||||||
|
|
||||||
|
|
||||||
class HanlinV5Input(HanlinV3Input):
|
class HanlinV5Input(HanlinV3Input):
|
||||||
|
|
||||||
name = 'Hanlin V5'
|
name = 'Hanlin V5'
|
||||||
@ -127,6 +135,7 @@ class HanlinV5Input(HanlinV3Input):
|
|||||||
screen_size = (584, 754)
|
screen_size = (584, 754)
|
||||||
dpi = 200
|
dpi = 200
|
||||||
|
|
||||||
|
|
||||||
class CybookG3Input(InputProfile):
|
class CybookG3Input(InputProfile):
|
||||||
|
|
||||||
name = 'Cybook G3'
|
name = 'Cybook G3'
|
||||||
@ -139,6 +148,7 @@ class CybookG3Input(InputProfile):
|
|||||||
fbase = 16
|
fbase = 16
|
||||||
fsizes = [12, 12, 14, 16, 18, 20, 22, 24]
|
fsizes = [12, 12, 14, 16, 18, 20, 22, 24]
|
||||||
|
|
||||||
|
|
||||||
class CybookOpusInput(InputProfile):
|
class CybookOpusInput(InputProfile):
|
||||||
|
|
||||||
author = 'John Schember'
|
author = 'John Schember'
|
||||||
@ -152,6 +162,7 @@ class CybookOpusInput(InputProfile):
|
|||||||
fbase = 16
|
fbase = 16
|
||||||
fsizes = [12, 12, 14, 16, 18, 20, 22, 24]
|
fsizes = [12, 12, 14, 16, 18, 20, 22, 24]
|
||||||
|
|
||||||
|
|
||||||
class KindleInput(InputProfile):
|
class KindleInput(InputProfile):
|
||||||
|
|
||||||
name = 'Kindle'
|
name = 'Kindle'
|
||||||
@ -164,6 +175,7 @@ class KindleInput(InputProfile):
|
|||||||
fbase = 16
|
fbase = 16
|
||||||
fsizes = [12, 12, 14, 16, 18, 20, 22, 24]
|
fsizes = [12, 12, 14, 16, 18, 20, 22, 24]
|
||||||
|
|
||||||
|
|
||||||
class IlliadInput(InputProfile):
|
class IlliadInput(InputProfile):
|
||||||
|
|
||||||
name = 'Illiad'
|
name = 'Illiad'
|
||||||
@ -175,6 +187,7 @@ class IlliadInput(InputProfile):
|
|||||||
fbase = 12
|
fbase = 12
|
||||||
fsizes = [7.5, 9, 10, 12, 15.5, 20, 22, 24]
|
fsizes = [7.5, 9, 10, 12, 15.5, 20, 22, 24]
|
||||||
|
|
||||||
|
|
||||||
class IRexDR1000Input(InputProfile):
|
class IRexDR1000Input(InputProfile):
|
||||||
|
|
||||||
author = 'John Schember'
|
author = 'John Schember'
|
||||||
@ -188,6 +201,7 @@ class IRexDR1000Input(InputProfile):
|
|||||||
fbase = 16
|
fbase = 16
|
||||||
fsizes = [12, 14, 16, 18, 20, 22, 24]
|
fsizes = [12, 14, 16, 18, 20, 22, 24]
|
||||||
|
|
||||||
|
|
||||||
class IRexDR800Input(InputProfile):
|
class IRexDR800Input(InputProfile):
|
||||||
|
|
||||||
author = 'Eric Cronin'
|
author = 'Eric Cronin'
|
||||||
@ -200,6 +214,7 @@ class IRexDR800Input(InputProfile):
|
|||||||
fbase = 16
|
fbase = 16
|
||||||
fsizes = [12, 14, 16, 18, 20, 22, 24]
|
fsizes = [12, 14, 16, 18, 20, 22, 24]
|
||||||
|
|
||||||
|
|
||||||
class NookInput(InputProfile):
|
class NookInput(InputProfile):
|
||||||
|
|
||||||
author = 'John Schember'
|
author = 'John Schember'
|
||||||
@ -222,6 +237,7 @@ input_profiles.sort(cmp=lambda x,y:cmp(x.name.lower(), y.name.lower()))
|
|||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
|
|
||||||
class OutputProfile(Plugin):
|
class OutputProfile(Plugin):
|
||||||
|
|
||||||
author = 'Kovid Goyal'
|
author = 'Kovid Goyal'
|
||||||
@ -424,6 +440,7 @@ class iPadOutput(OutputProfile):
|
|||||||
'''
|
'''
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
|
|
||||||
class iPad3Output(iPadOutput):
|
class iPad3Output(iPadOutput):
|
||||||
|
|
||||||
screen_size = comic_screen_size = (2048, 1536)
|
screen_size = comic_screen_size = (2048, 1536)
|
||||||
@ -433,6 +450,7 @@ class iPad3Output(iPadOutput):
|
|||||||
description = _('Intended for the iPad 3 and similar devices with a '
|
description = _('Intended for the iPad 3 and similar devices with a '
|
||||||
'resolution of 1536x2048')
|
'resolution of 1536x2048')
|
||||||
|
|
||||||
|
|
||||||
class TabletOutput(iPadOutput):
|
class TabletOutput(iPadOutput):
|
||||||
name = 'Tablet'
|
name = 'Tablet'
|
||||||
short_name = 'tablet'
|
short_name = 'tablet'
|
||||||
@ -441,6 +459,7 @@ class TabletOutput(iPadOutput):
|
|||||||
screen_size = (10000, 10000)
|
screen_size = (10000, 10000)
|
||||||
comic_screen_size = (10000, 10000)
|
comic_screen_size = (10000, 10000)
|
||||||
|
|
||||||
|
|
||||||
class SamsungGalaxy(TabletOutput):
|
class SamsungGalaxy(TabletOutput):
|
||||||
name = 'Samsung Galaxy'
|
name = 'Samsung Galaxy'
|
||||||
short_name = 'galaxy'
|
short_name = 'galaxy'
|
||||||
@ -448,6 +467,7 @@ class SamsungGalaxy(TabletOutput):
|
|||||||
'a resolution of 600x1280')
|
'a resolution of 600x1280')
|
||||||
screen_size = comic_screen_size = (600, 1280)
|
screen_size = comic_screen_size = (600, 1280)
|
||||||
|
|
||||||
|
|
||||||
class NookHD(TabletOutput):
|
class NookHD(TabletOutput):
|
||||||
name = 'Nook HD+'
|
name = 'Nook HD+'
|
||||||
short_name = 'nook_hd_plus'
|
short_name = 'nook_hd_plus'
|
||||||
@ -455,6 +475,7 @@ class NookHD(TabletOutput):
|
|||||||
'a resolution of 1280x1920')
|
'a resolution of 1280x1920')
|
||||||
screen_size = comic_screen_size = (1280, 1920)
|
screen_size = comic_screen_size = (1280, 1920)
|
||||||
|
|
||||||
|
|
||||||
class SonyReaderOutput(OutputProfile):
|
class SonyReaderOutput(OutputProfile):
|
||||||
|
|
||||||
name = 'Sony Reader'
|
name = 'Sony Reader'
|
||||||
@ -485,6 +506,7 @@ class KoboReaderOutput(OutputProfile):
|
|||||||
fbase = 12
|
fbase = 12
|
||||||
fsizes = [7.5, 9, 10, 12, 15.5, 20, 22, 24]
|
fsizes = [7.5, 9, 10, 12, 15.5, 20, 22, 24]
|
||||||
|
|
||||||
|
|
||||||
class SonyReader300Output(SonyReaderOutput):
|
class SonyReader300Output(SonyReaderOutput):
|
||||||
|
|
||||||
author = 'John Schember'
|
author = 'John Schember'
|
||||||
@ -494,6 +516,7 @@ class SonyReader300Output(SonyReaderOutput):
|
|||||||
|
|
||||||
dpi = 200
|
dpi = 200
|
||||||
|
|
||||||
|
|
||||||
class SonyReader900Output(SonyReaderOutput):
|
class SonyReader900Output(SonyReaderOutput):
|
||||||
|
|
||||||
author = 'John Schember'
|
author = 'John Schember'
|
||||||
@ -504,6 +527,7 @@ class SonyReader900Output(SonyReaderOutput):
|
|||||||
screen_size = (600, 999)
|
screen_size = (600, 999)
|
||||||
comic_screen_size = screen_size
|
comic_screen_size = screen_size
|
||||||
|
|
||||||
|
|
||||||
class SonyReaderT3Output(SonyReaderOutput):
|
class SonyReaderT3Output(SonyReaderOutput):
|
||||||
|
|
||||||
author = 'Kovid Goyal'
|
author = 'Kovid Goyal'
|
||||||
@ -522,6 +546,7 @@ class GenericEink(SonyReaderOutput):
|
|||||||
description = _('Suitable for use with any e-ink device')
|
description = _('Suitable for use with any e-ink device')
|
||||||
epub_periodical_format = None
|
epub_periodical_format = None
|
||||||
|
|
||||||
|
|
||||||
class GenericEinkLarge(GenericEink):
|
class GenericEinkLarge(GenericEink):
|
||||||
|
|
||||||
name = 'Generic e-ink large'
|
name = 'Generic e-ink large'
|
||||||
@ -531,6 +556,7 @@ class GenericEinkLarge(GenericEink):
|
|||||||
screen_size = (600, 999)
|
screen_size = (600, 999)
|
||||||
comic_screen_size = screen_size
|
comic_screen_size = screen_size
|
||||||
|
|
||||||
|
|
||||||
class GenericEinkHD(GenericEink):
|
class GenericEinkHD(GenericEink):
|
||||||
|
|
||||||
name = 'Generic e-ink HD'
|
name = 'Generic e-ink HD'
|
||||||
@ -550,6 +576,7 @@ class JetBook5Output(OutputProfile):
|
|||||||
screen_size = (480, 640)
|
screen_size = (480, 640)
|
||||||
dpi = 168.451
|
dpi = 168.451
|
||||||
|
|
||||||
|
|
||||||
class SonyReaderLandscapeOutput(SonyReaderOutput):
|
class SonyReaderLandscapeOutput(SonyReaderOutput):
|
||||||
|
|
||||||
name = 'Sony Reader Landscape'
|
name = 'Sony Reader Landscape'
|
||||||
@ -561,6 +588,7 @@ class SonyReaderLandscapeOutput(SonyReaderOutput):
|
|||||||
screen_size = (784, 1012)
|
screen_size = (784, 1012)
|
||||||
comic_screen_size = (784, 1012)
|
comic_screen_size = (784, 1012)
|
||||||
|
|
||||||
|
|
||||||
class MSReaderOutput(OutputProfile):
|
class MSReaderOutput(OutputProfile):
|
||||||
|
|
||||||
name = 'Microsoft Reader'
|
name = 'Microsoft Reader'
|
||||||
@ -572,6 +600,7 @@ class MSReaderOutput(OutputProfile):
|
|||||||
fbase = 13
|
fbase = 13
|
||||||
fsizes = [10, 11, 13, 16, 18, 20, 22, 26]
|
fsizes = [10, 11, 13, 16, 18, 20, 22, 26]
|
||||||
|
|
||||||
|
|
||||||
class MobipocketOutput(OutputProfile):
|
class MobipocketOutput(OutputProfile):
|
||||||
|
|
||||||
name = 'Mobipocket Books'
|
name = 'Mobipocket Books'
|
||||||
@ -585,6 +614,7 @@ class MobipocketOutput(OutputProfile):
|
|||||||
fbase = 18
|
fbase = 18
|
||||||
fsizes = [14, 14, 16, 18, 20, 22, 24, 26]
|
fsizes = [14, 14, 16, 18, 20, 22, 24, 26]
|
||||||
|
|
||||||
|
|
||||||
class HanlinV3Output(OutputProfile):
|
class HanlinV3Output(OutputProfile):
|
||||||
|
|
||||||
name = 'Hanlin V3'
|
name = 'Hanlin V3'
|
||||||
@ -597,6 +627,7 @@ class HanlinV3Output(OutputProfile):
|
|||||||
fbase = 16
|
fbase = 16
|
||||||
fsizes = [12, 12, 14, 16, 18, 20, 22, 24]
|
fsizes = [12, 12, 14, 16, 18, 20, 22, 24]
|
||||||
|
|
||||||
|
|
||||||
class HanlinV5Output(HanlinV3Output):
|
class HanlinV5Output(HanlinV3Output):
|
||||||
|
|
||||||
name = 'Hanlin V5'
|
name = 'Hanlin V5'
|
||||||
@ -605,6 +636,7 @@ class HanlinV5Output(HanlinV3Output):
|
|||||||
|
|
||||||
dpi = 200
|
dpi = 200
|
||||||
|
|
||||||
|
|
||||||
class CybookG3Output(OutputProfile):
|
class CybookG3Output(OutputProfile):
|
||||||
|
|
||||||
name = 'Cybook G3'
|
name = 'Cybook G3'
|
||||||
@ -618,6 +650,7 @@ class CybookG3Output(OutputProfile):
|
|||||||
fbase = 16
|
fbase = 16
|
||||||
fsizes = [12, 12, 14, 16, 18, 20, 22, 24]
|
fsizes = [12, 12, 14, 16, 18, 20, 22, 24]
|
||||||
|
|
||||||
|
|
||||||
class CybookOpusOutput(SonyReaderOutput):
|
class CybookOpusOutput(SonyReaderOutput):
|
||||||
|
|
||||||
author = 'John Schember'
|
author = 'John Schember'
|
||||||
@ -632,6 +665,7 @@ class CybookOpusOutput(SonyReaderOutput):
|
|||||||
|
|
||||||
epub_periodical_format = None
|
epub_periodical_format = None
|
||||||
|
|
||||||
|
|
||||||
class KindleOutput(OutputProfile):
|
class KindleOutput(OutputProfile):
|
||||||
|
|
||||||
name = 'Kindle'
|
name = 'Kindle'
|
||||||
@ -651,6 +685,7 @@ class KindleOutput(OutputProfile):
|
|||||||
|
|
||||||
mobi_ems_per_blockquote = 2.0
|
mobi_ems_per_blockquote = 2.0
|
||||||
|
|
||||||
|
|
||||||
class KindleDXOutput(OutputProfile):
|
class KindleDXOutput(OutputProfile):
|
||||||
|
|
||||||
name = 'Kindle DX'
|
name = 'Kindle DX'
|
||||||
@ -668,6 +703,7 @@ class KindleDXOutput(OutputProfile):
|
|||||||
ratings_char = u'\u2605'
|
ratings_char = u'\u2605'
|
||||||
mobi_ems_per_blockquote = 2.0
|
mobi_ems_per_blockquote = 2.0
|
||||||
|
|
||||||
|
|
||||||
class KindlePaperWhiteOutput(KindleOutput):
|
class KindlePaperWhiteOutput(KindleOutput):
|
||||||
|
|
||||||
name = 'Kindle PaperWhite'
|
name = 'Kindle PaperWhite'
|
||||||
@ -679,6 +715,7 @@ class KindlePaperWhiteOutput(KindleOutput):
|
|||||||
dpi = 212.0
|
dpi = 212.0
|
||||||
comic_screen_size = screen_size
|
comic_screen_size = screen_size
|
||||||
|
|
||||||
|
|
||||||
class KindleVoyageOutput(KindleOutput):
|
class KindleVoyageOutput(KindleOutput):
|
||||||
|
|
||||||
name = 'Kindle Voyage'
|
name = 'Kindle Voyage'
|
||||||
@ -691,6 +728,7 @@ class KindleVoyageOutput(KindleOutput):
|
|||||||
dpi = 300.0
|
dpi = 300.0
|
||||||
comic_screen_size = screen_size
|
comic_screen_size = screen_size
|
||||||
|
|
||||||
|
|
||||||
class KindlePaperWhite3Output(KindleVoyageOutput):
|
class KindlePaperWhite3Output(KindleVoyageOutput):
|
||||||
|
|
||||||
name = 'Kindle PaperWhite 3'
|
name = 'Kindle PaperWhite 3'
|
||||||
@ -713,6 +751,7 @@ class KindleFireOutput(KindleDXOutput):
|
|||||||
dpi = 169.0
|
dpi = 169.0
|
||||||
comic_screen_size = (570, 1016)
|
comic_screen_size = (570, 1016)
|
||||||
|
|
||||||
|
|
||||||
class IlliadOutput(OutputProfile):
|
class IlliadOutput(OutputProfile):
|
||||||
|
|
||||||
name = 'Illiad'
|
name = 'Illiad'
|
||||||
@ -725,6 +764,7 @@ class IlliadOutput(OutputProfile):
|
|||||||
fbase = 12
|
fbase = 12
|
||||||
fsizes = [7.5, 9, 10, 12, 15.5, 20, 22, 24]
|
fsizes = [7.5, 9, 10, 12, 15.5, 20, 22, 24]
|
||||||
|
|
||||||
|
|
||||||
class IRexDR1000Output(OutputProfile):
|
class IRexDR1000Output(OutputProfile):
|
||||||
|
|
||||||
author = 'John Schember'
|
author = 'John Schember'
|
||||||
@ -739,6 +779,7 @@ class IRexDR1000Output(OutputProfile):
|
|||||||
fbase = 16
|
fbase = 16
|
||||||
fsizes = [12, 14, 16, 18, 20, 22, 24]
|
fsizes = [12, 14, 16, 18, 20, 22, 24]
|
||||||
|
|
||||||
|
|
||||||
class IRexDR800Output(OutputProfile):
|
class IRexDR800Output(OutputProfile):
|
||||||
|
|
||||||
author = 'Eric Cronin'
|
author = 'Eric Cronin'
|
||||||
@ -753,6 +794,7 @@ class IRexDR800Output(OutputProfile):
|
|||||||
fbase = 16
|
fbase = 16
|
||||||
fsizes = [12, 14, 16, 18, 20, 22, 24]
|
fsizes = [12, 14, 16, 18, 20, 22, 24]
|
||||||
|
|
||||||
|
|
||||||
class NookOutput(OutputProfile):
|
class NookOutput(OutputProfile):
|
||||||
|
|
||||||
author = 'John Schember'
|
author = 'John Schember'
|
||||||
@ -767,6 +809,7 @@ class NookOutput(OutputProfile):
|
|||||||
fbase = 16
|
fbase = 16
|
||||||
fsizes = [12, 12, 14, 16, 18, 20, 22, 24]
|
fsizes = [12, 12, 14, 16, 18, 20, 22, 24]
|
||||||
|
|
||||||
|
|
||||||
class NookColorOutput(NookOutput):
|
class NookColorOutput(NookOutput):
|
||||||
name = 'Nook Color'
|
name = 'Nook Color'
|
||||||
short_name = 'nook_color'
|
short_name = 'nook_color'
|
||||||
@ -776,6 +819,7 @@ class NookColorOutput(NookOutput):
|
|||||||
comic_screen_size = (594, 900)
|
comic_screen_size = (594, 900)
|
||||||
dpi = 169
|
dpi = 169
|
||||||
|
|
||||||
|
|
||||||
class PocketBook900Output(OutputProfile):
|
class PocketBook900Output(OutputProfile):
|
||||||
|
|
||||||
author = 'Chris Lockfort'
|
author = 'Chris Lockfort'
|
||||||
@ -787,6 +831,7 @@ class PocketBook900Output(OutputProfile):
|
|||||||
dpi = 150.0
|
dpi = 150.0
|
||||||
comic_screen_size = screen_size
|
comic_screen_size = screen_size
|
||||||
|
|
||||||
|
|
||||||
class PocketBookPro912Output(OutputProfile):
|
class PocketBookPro912Output(OutputProfile):
|
||||||
|
|
||||||
author = 'Daniele Pizzolli'
|
author = 'Daniele Pizzolli'
|
||||||
|
@ -24,9 +24,11 @@ from calibre.constants import DEBUG
|
|||||||
|
|
||||||
builtin_names = frozenset([p.name for p in builtin_plugins])
|
builtin_names = frozenset([p.name for p in builtin_plugins])
|
||||||
|
|
||||||
|
|
||||||
class NameConflict(ValueError):
|
class NameConflict(ValueError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def _config():
|
def _config():
|
||||||
c = Config('customize')
|
c = Config('customize')
|
||||||
c.add_opt('plugins', default={}, help=_('Installed plugins'))
|
c.add_opt('plugins', default={}, help=_('Installed plugins'))
|
||||||
@ -58,6 +60,7 @@ def load_plugin(path_to_zip_file): # {{{
|
|||||||
|
|
||||||
# Enable/disable plugins {{{
|
# Enable/disable plugins {{{
|
||||||
|
|
||||||
|
|
||||||
def disable_plugin(plugin_or_name):
|
def disable_plugin(plugin_or_name):
|
||||||
x = getattr(plugin_or_name, 'name', plugin_or_name)
|
x = getattr(plugin_or_name, 'name', plugin_or_name)
|
||||||
plugin = find_plugin(x)
|
plugin = find_plugin(x)
|
||||||
@ -71,6 +74,7 @@ def disable_plugin(plugin_or_name):
|
|||||||
ep.remove(x)
|
ep.remove(x)
|
||||||
config['enabled_plugins'] = ep
|
config['enabled_plugins'] = ep
|
||||||
|
|
||||||
|
|
||||||
def enable_plugin(plugin_or_name):
|
def enable_plugin(plugin_or_name):
|
||||||
x = getattr(plugin_or_name, 'name', plugin_or_name)
|
x = getattr(plugin_or_name, 'name', plugin_or_name)
|
||||||
dp = config['disabled_plugins']
|
dp = config['disabled_plugins']
|
||||||
@ -81,6 +85,7 @@ def enable_plugin(plugin_or_name):
|
|||||||
ep.add(x)
|
ep.add(x)
|
||||||
config['enabled_plugins'] = ep
|
config['enabled_plugins'] = ep
|
||||||
|
|
||||||
|
|
||||||
def restore_plugin_state_to_default(plugin_or_name):
|
def restore_plugin_state_to_default(plugin_or_name):
|
||||||
x = getattr(plugin_or_name, 'name', plugin_or_name)
|
x = getattr(plugin_or_name, 'name', plugin_or_name)
|
||||||
dp = config['disabled_plugins']
|
dp = config['disabled_plugins']
|
||||||
@ -96,6 +101,7 @@ default_disabled_plugins = set([
|
|||||||
'Overdrive', 'Douban Books', 'OZON.ru', 'Edelweiss', 'Google Images', 'Big Book Search',
|
'Overdrive', 'Douban Books', 'OZON.ru', 'Edelweiss', 'Google Images', 'Big Book Search',
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
def is_disabled(plugin):
|
def is_disabled(plugin):
|
||||||
if plugin.name in config['enabled_plugins']:
|
if plugin.name in config['enabled_plugins']:
|
||||||
return False
|
return False
|
||||||
@ -111,6 +117,7 @@ _on_preprocess = {}
|
|||||||
_on_postprocess = {}
|
_on_postprocess = {}
|
||||||
_on_postadd = []
|
_on_postadd = []
|
||||||
|
|
||||||
|
|
||||||
def reread_filetype_plugins():
|
def reread_filetype_plugins():
|
||||||
global _on_import
|
global _on_import
|
||||||
global _on_postimport
|
global _on_postimport
|
||||||
@ -171,6 +178,7 @@ run_plugins_on_preprocess = functools.partial(_run_filetype_plugins,
|
|||||||
run_plugins_on_postprocess = functools.partial(_run_filetype_plugins,
|
run_plugins_on_postprocess = functools.partial(_run_filetype_plugins,
|
||||||
occasion='postprocess')
|
occasion='postprocess')
|
||||||
|
|
||||||
|
|
||||||
def run_plugins_on_postimport(db, book_id, fmt):
|
def run_plugins_on_postimport(db, book_id, fmt):
|
||||||
customization = config['plugin_customization']
|
customization = config['plugin_customization']
|
||||||
fmt = fmt.lower()
|
fmt = fmt.lower()
|
||||||
@ -186,6 +194,7 @@ def run_plugins_on_postimport(db, book_id, fmt):
|
|||||||
plugin.name)
|
plugin.name)
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
|
|
||||||
|
|
||||||
def run_plugins_on_postadd(db, book_id, fmt_map):
|
def run_plugins_on_postadd(db, book_id, fmt_map):
|
||||||
customization = config['plugin_customization']
|
customization = config['plugin_customization']
|
||||||
for plugin in _on_postadd:
|
for plugin in _on_postadd:
|
||||||
@ -203,22 +212,28 @@ def run_plugins_on_postadd(db, book_id, fmt_map):
|
|||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
# Plugin customization {{{
|
# Plugin customization {{{
|
||||||
|
|
||||||
|
|
||||||
def customize_plugin(plugin, custom):
|
def customize_plugin(plugin, custom):
|
||||||
d = config['plugin_customization']
|
d = config['plugin_customization']
|
||||||
d[plugin.name] = custom.strip()
|
d[plugin.name] = custom.strip()
|
||||||
config['plugin_customization'] = d
|
config['plugin_customization'] = d
|
||||||
|
|
||||||
|
|
||||||
def plugin_customization(plugin):
|
def plugin_customization(plugin):
|
||||||
return config['plugin_customization'].get(plugin.name, '')
|
return config['plugin_customization'].get(plugin.name, '')
|
||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
# Input/Output profiles {{{
|
# Input/Output profiles {{{
|
||||||
|
|
||||||
|
|
||||||
def input_profiles():
|
def input_profiles():
|
||||||
for plugin in _initialized_plugins:
|
for plugin in _initialized_plugins:
|
||||||
if isinstance(plugin, InputProfile):
|
if isinstance(plugin, InputProfile):
|
||||||
yield plugin
|
yield plugin
|
||||||
|
|
||||||
|
|
||||||
def output_profiles():
|
def output_profiles():
|
||||||
for plugin in _initialized_plugins:
|
for plugin in _initialized_plugins:
|
||||||
if isinstance(plugin, OutputProfile):
|
if isinstance(plugin, OutputProfile):
|
||||||
@ -227,6 +242,7 @@ def output_profiles():
|
|||||||
|
|
||||||
# Interface Actions # {{{
|
# Interface Actions # {{{
|
||||||
|
|
||||||
|
|
||||||
def interface_actions():
|
def interface_actions():
|
||||||
customization = config['plugin_customization']
|
customization = config['plugin_customization']
|
||||||
for plugin in _initialized_plugins:
|
for plugin in _initialized_plugins:
|
||||||
@ -238,6 +254,7 @@ def interface_actions():
|
|||||||
|
|
||||||
# Preferences Plugins # {{{
|
# Preferences Plugins # {{{
|
||||||
|
|
||||||
|
|
||||||
def preferences_plugins():
|
def preferences_plugins():
|
||||||
customization = config['plugin_customization']
|
customization = config['plugin_customization']
|
||||||
for plugin in _initialized_plugins:
|
for plugin in _initialized_plugins:
|
||||||
@ -248,6 +265,8 @@ def preferences_plugins():
|
|||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
# Library Closed Plugins # {{{
|
# Library Closed Plugins # {{{
|
||||||
|
|
||||||
|
|
||||||
def available_library_closed_plugins():
|
def available_library_closed_plugins():
|
||||||
customization = config['plugin_customization']
|
customization = config['plugin_customization']
|
||||||
for plugin in _initialized_plugins:
|
for plugin in _initialized_plugins:
|
||||||
@ -256,6 +275,7 @@ def available_library_closed_plugins():
|
|||||||
plugin.site_customization = customization.get(plugin.name, '')
|
plugin.site_customization = customization.get(plugin.name, '')
|
||||||
yield plugin
|
yield plugin
|
||||||
|
|
||||||
|
|
||||||
def has_library_closed_plugins():
|
def has_library_closed_plugins():
|
||||||
for plugin in _initialized_plugins:
|
for plugin in _initialized_plugins:
|
||||||
if isinstance(plugin, LibraryClosedPlugin):
|
if isinstance(plugin, LibraryClosedPlugin):
|
||||||
@ -266,6 +286,7 @@ def has_library_closed_plugins():
|
|||||||
|
|
||||||
# Store Plugins # {{{
|
# Store Plugins # {{{
|
||||||
|
|
||||||
|
|
||||||
def store_plugins():
|
def store_plugins():
|
||||||
customization = config['plugin_customization']
|
customization = config['plugin_customization']
|
||||||
for plugin in _initialized_plugins:
|
for plugin in _initialized_plugins:
|
||||||
@ -273,17 +294,20 @@ def store_plugins():
|
|||||||
plugin.site_customization = customization.get(plugin.name, '')
|
plugin.site_customization = customization.get(plugin.name, '')
|
||||||
yield plugin
|
yield plugin
|
||||||
|
|
||||||
|
|
||||||
def available_store_plugins():
|
def available_store_plugins():
|
||||||
for plugin in store_plugins():
|
for plugin in store_plugins():
|
||||||
if not is_disabled(plugin):
|
if not is_disabled(plugin):
|
||||||
yield plugin
|
yield plugin
|
||||||
|
|
||||||
|
|
||||||
def stores():
|
def stores():
|
||||||
stores = set([])
|
stores = set([])
|
||||||
for plugin in store_plugins():
|
for plugin in store_plugins():
|
||||||
stores.add(plugin.name)
|
stores.add(plugin.name)
|
||||||
return stores
|
return stores
|
||||||
|
|
||||||
|
|
||||||
def available_stores():
|
def available_stores():
|
||||||
stores = set([])
|
stores = set([])
|
||||||
for plugin in available_store_plugins():
|
for plugin in available_store_plugins():
|
||||||
@ -295,6 +319,8 @@ def available_stores():
|
|||||||
# Metadata read/write {{{
|
# Metadata read/write {{{
|
||||||
_metadata_readers = {}
|
_metadata_readers = {}
|
||||||
_metadata_writers = {}
|
_metadata_writers = {}
|
||||||
|
|
||||||
|
|
||||||
def reread_metadata_plugins():
|
def reread_metadata_plugins():
|
||||||
global _metadata_readers
|
global _metadata_readers
|
||||||
global _metadata_writers
|
global _metadata_writers
|
||||||
@ -308,6 +334,7 @@ def reread_metadata_plugins():
|
|||||||
for ft in plugin.file_types:
|
for ft in plugin.file_types:
|
||||||
_metadata_writers[ft].append(plugin)
|
_metadata_writers[ft].append(plugin)
|
||||||
|
|
||||||
|
|
||||||
def metadata_readers():
|
def metadata_readers():
|
||||||
ans = set([])
|
ans = set([])
|
||||||
for plugins in _metadata_readers.values():
|
for plugins in _metadata_readers.values():
|
||||||
@ -315,6 +342,7 @@ def metadata_readers():
|
|||||||
ans.add(plugin)
|
ans.add(plugin)
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
|
|
||||||
def metadata_writers():
|
def metadata_writers():
|
||||||
ans = set([])
|
ans = set([])
|
||||||
for plugins in _metadata_writers.values():
|
for plugins in _metadata_writers.values():
|
||||||
@ -322,6 +350,7 @@ def metadata_writers():
|
|||||||
ans.add(plugin)
|
ans.add(plugin)
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
|
|
||||||
class QuickMetadata(object):
|
class QuickMetadata(object):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@ -335,6 +364,7 @@ class QuickMetadata(object):
|
|||||||
|
|
||||||
quick_metadata = QuickMetadata()
|
quick_metadata = QuickMetadata()
|
||||||
|
|
||||||
|
|
||||||
class ApplyNullMetadata(object):
|
class ApplyNullMetadata(object):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@ -348,6 +378,7 @@ class ApplyNullMetadata(object):
|
|||||||
|
|
||||||
apply_null_metadata = ApplyNullMetadata()
|
apply_null_metadata = ApplyNullMetadata()
|
||||||
|
|
||||||
|
|
||||||
class ForceIdentifiers(object):
|
class ForceIdentifiers(object):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@ -361,6 +392,7 @@ class ForceIdentifiers(object):
|
|||||||
|
|
||||||
force_identifiers = ForceIdentifiers()
|
force_identifiers = ForceIdentifiers()
|
||||||
|
|
||||||
|
|
||||||
def get_file_type_metadata(stream, ftype):
|
def get_file_type_metadata(stream, ftype):
|
||||||
mi = MetaInformation(None, None)
|
mi = MetaInformation(None, None)
|
||||||
|
|
||||||
@ -380,6 +412,7 @@ def get_file_type_metadata(stream, ftype):
|
|||||||
continue
|
continue
|
||||||
return mi
|
return mi
|
||||||
|
|
||||||
|
|
||||||
def set_file_type_metadata(stream, mi, ftype, report_error=None):
|
def set_file_type_metadata(stream, mi, ftype, report_error=None):
|
||||||
ftype = ftype.lower().strip()
|
ftype = ftype.lower().strip()
|
||||||
if ftype in _metadata_writers:
|
if ftype in _metadata_writers:
|
||||||
@ -401,6 +434,7 @@ def set_file_type_metadata(stream, mi, ftype, report_error=None):
|
|||||||
else:
|
else:
|
||||||
report_error(mi, ftype, traceback.format_exc())
|
report_error(mi, ftype, traceback.format_exc())
|
||||||
|
|
||||||
|
|
||||||
def can_set_metadata(ftype):
|
def can_set_metadata(ftype):
|
||||||
ftype = ftype.lower().strip()
|
ftype = ftype.lower().strip()
|
||||||
for plugin in _metadata_writers.get(ftype, ()):
|
for plugin in _metadata_writers.get(ftype, ()):
|
||||||
@ -412,6 +446,7 @@ def can_set_metadata(ftype):
|
|||||||
|
|
||||||
# Add/remove plugins {{{
|
# Add/remove plugins {{{
|
||||||
|
|
||||||
|
|
||||||
def add_plugin(path_to_zip_file):
|
def add_plugin(path_to_zip_file):
|
||||||
make_config_dir()
|
make_config_dir()
|
||||||
plugin = load_plugin(path_to_zip_file)
|
plugin = load_plugin(path_to_zip_file)
|
||||||
@ -429,6 +464,7 @@ def add_plugin(path_to_zip_file):
|
|||||||
initialize_plugins()
|
initialize_plugins()
|
||||||
return plugin
|
return plugin
|
||||||
|
|
||||||
|
|
||||||
def remove_plugin(plugin_or_name):
|
def remove_plugin(plugin_or_name):
|
||||||
name = getattr(plugin_or_name, 'name', plugin_or_name)
|
name = getattr(plugin_or_name, 'name', plugin_or_name)
|
||||||
plugins = config['plugins']
|
plugins = config['plugins']
|
||||||
@ -453,11 +489,13 @@ def remove_plugin(plugin_or_name):
|
|||||||
|
|
||||||
# Input/Output format plugins {{{
|
# Input/Output format plugins {{{
|
||||||
|
|
||||||
|
|
||||||
def input_format_plugins():
|
def input_format_plugins():
|
||||||
for plugin in _initialized_plugins:
|
for plugin in _initialized_plugins:
|
||||||
if isinstance(plugin, InputFormatPlugin):
|
if isinstance(plugin, InputFormatPlugin):
|
||||||
yield plugin
|
yield plugin
|
||||||
|
|
||||||
|
|
||||||
def plugin_for_input_format(fmt):
|
def plugin_for_input_format(fmt):
|
||||||
customization = config['plugin_customization']
|
customization = config['plugin_customization']
|
||||||
for plugin in input_format_plugins():
|
for plugin in input_format_plugins():
|
||||||
@ -465,6 +503,7 @@ def plugin_for_input_format(fmt):
|
|||||||
plugin.site_customization = customization.get(plugin.name, None)
|
plugin.site_customization = customization.get(plugin.name, None)
|
||||||
return plugin
|
return plugin
|
||||||
|
|
||||||
|
|
||||||
def all_input_formats():
|
def all_input_formats():
|
||||||
formats = set()
|
formats = set()
|
||||||
for plugin in input_format_plugins():
|
for plugin in input_format_plugins():
|
||||||
@ -472,6 +511,7 @@ def all_input_formats():
|
|||||||
formats.add(format)
|
formats.add(format)
|
||||||
return formats
|
return formats
|
||||||
|
|
||||||
|
|
||||||
def available_input_formats():
|
def available_input_formats():
|
||||||
formats = set()
|
formats = set()
|
||||||
for plugin in input_format_plugins():
|
for plugin in input_format_plugins():
|
||||||
@ -487,6 +527,7 @@ def output_format_plugins():
|
|||||||
if isinstance(plugin, OutputFormatPlugin):
|
if isinstance(plugin, OutputFormatPlugin):
|
||||||
yield plugin
|
yield plugin
|
||||||
|
|
||||||
|
|
||||||
def plugin_for_output_format(fmt):
|
def plugin_for_output_format(fmt):
|
||||||
customization = config['plugin_customization']
|
customization = config['plugin_customization']
|
||||||
for plugin in output_format_plugins():
|
for plugin in output_format_plugins():
|
||||||
@ -494,6 +535,7 @@ def plugin_for_output_format(fmt):
|
|||||||
plugin.site_customization = customization.get(plugin.name, None)
|
plugin.site_customization = customization.get(plugin.name, None)
|
||||||
return plugin
|
return plugin
|
||||||
|
|
||||||
|
|
||||||
def available_output_formats():
|
def available_output_formats():
|
||||||
formats = set([])
|
formats = set([])
|
||||||
for plugin in output_format_plugins():
|
for plugin in output_format_plugins():
|
||||||
@ -505,11 +547,13 @@ def available_output_formats():
|
|||||||
|
|
||||||
# Catalog plugins {{{
|
# Catalog plugins {{{
|
||||||
|
|
||||||
|
|
||||||
def catalog_plugins():
|
def catalog_plugins():
|
||||||
for plugin in _initialized_plugins:
|
for plugin in _initialized_plugins:
|
||||||
if isinstance(plugin, CatalogPlugin):
|
if isinstance(plugin, CatalogPlugin):
|
||||||
yield plugin
|
yield plugin
|
||||||
|
|
||||||
|
|
||||||
def available_catalog_formats():
|
def available_catalog_formats():
|
||||||
formats = set([])
|
formats = set([])
|
||||||
for plugin in catalog_plugins():
|
for plugin in catalog_plugins():
|
||||||
@ -518,6 +562,7 @@ def available_catalog_formats():
|
|||||||
formats.add(format)
|
formats.add(format)
|
||||||
return formats
|
return formats
|
||||||
|
|
||||||
|
|
||||||
def plugin_for_catalog_format(fmt):
|
def plugin_for_catalog_format(fmt):
|
||||||
for plugin in catalog_plugins():
|
for plugin in catalog_plugins():
|
||||||
if fmt.lower() in plugin.file_types:
|
if fmt.lower() in plugin.file_types:
|
||||||
@ -526,6 +571,8 @@ def plugin_for_catalog_format(fmt):
|
|||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
# Device plugins {{{
|
# Device plugins {{{
|
||||||
|
|
||||||
|
|
||||||
def device_plugins(include_disabled=False):
|
def device_plugins(include_disabled=False):
|
||||||
for plugin in _initialized_plugins:
|
for plugin in _initialized_plugins:
|
||||||
if isinstance(plugin, DevicePlugin):
|
if isinstance(plugin, DevicePlugin):
|
||||||
@ -536,6 +583,7 @@ def device_plugins(include_disabled=False):
|
|||||||
plugin.do_delayed_plugin_initialization()
|
plugin.do_delayed_plugin_initialization()
|
||||||
yield plugin
|
yield plugin
|
||||||
|
|
||||||
|
|
||||||
def disabled_device_plugins():
|
def disabled_device_plugins():
|
||||||
for plugin in _initialized_plugins:
|
for plugin in _initialized_plugins:
|
||||||
if isinstance(plugin, DevicePlugin):
|
if isinstance(plugin, DevicePlugin):
|
||||||
@ -545,6 +593,8 @@ def disabled_device_plugins():
|
|||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
# Metadata sources2 {{{
|
# Metadata sources2 {{{
|
||||||
|
|
||||||
|
|
||||||
def metadata_plugins(capabilities):
|
def metadata_plugins(capabilities):
|
||||||
capabilities = frozenset(capabilities)
|
capabilities = frozenset(capabilities)
|
||||||
for plugin in all_metadata_plugins():
|
for plugin in all_metadata_plugins():
|
||||||
@ -552,6 +602,7 @@ def metadata_plugins(capabilities):
|
|||||||
not is_disabled(plugin):
|
not is_disabled(plugin):
|
||||||
yield plugin
|
yield plugin
|
||||||
|
|
||||||
|
|
||||||
def all_metadata_plugins():
|
def all_metadata_plugins():
|
||||||
for plugin in _initialized_plugins:
|
for plugin in _initialized_plugins:
|
||||||
if isinstance(plugin, Source):
|
if isinstance(plugin, Source):
|
||||||
@ -559,6 +610,8 @@ def all_metadata_plugins():
|
|||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
# Viewer plugins {{{
|
# Viewer plugins {{{
|
||||||
|
|
||||||
|
|
||||||
def all_viewer_plugins():
|
def all_viewer_plugins():
|
||||||
for plugin in _initialized_plugins:
|
for plugin in _initialized_plugins:
|
||||||
if isinstance(plugin, ViewerPlugin):
|
if isinstance(plugin, ViewerPlugin):
|
||||||
@ -566,6 +619,8 @@ def all_viewer_plugins():
|
|||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
# Editor plugins {{{
|
# Editor plugins {{{
|
||||||
|
|
||||||
|
|
||||||
def all_edit_book_tool_plugins():
|
def all_edit_book_tool_plugins():
|
||||||
for plugin in _initialized_plugins:
|
for plugin in _initialized_plugins:
|
||||||
if isinstance(plugin, EditBookToolPlugin):
|
if isinstance(plugin, EditBookToolPlugin):
|
||||||
@ -576,6 +631,7 @@ def all_edit_book_tool_plugins():
|
|||||||
|
|
||||||
_initialized_plugins = []
|
_initialized_plugins = []
|
||||||
|
|
||||||
|
|
||||||
def initialize_plugin(plugin, path_to_zip_file):
|
def initialize_plugin(plugin, path_to_zip_file):
|
||||||
try:
|
try:
|
||||||
p = plugin(path_to_zip_file)
|
p = plugin(path_to_zip_file)
|
||||||
@ -587,10 +643,12 @@ def initialize_plugin(plugin, path_to_zip_file):
|
|||||||
raise InvalidPlugin((_('Initialization of plugin %s failed with traceback:')
|
raise InvalidPlugin((_('Initialization of plugin %s failed with traceback:')
|
||||||
%tb) + '\n'+tb)
|
%tb) + '\n'+tb)
|
||||||
|
|
||||||
|
|
||||||
def has_external_plugins():
|
def has_external_plugins():
|
||||||
'True if there are updateable (zip file based) plugins'
|
'True if there are updateable (zip file based) plugins'
|
||||||
return bool(config['plugins'])
|
return bool(config['plugins'])
|
||||||
|
|
||||||
|
|
||||||
def initialize_plugins(perf=False):
|
def initialize_plugins(perf=False):
|
||||||
global _initialized_plugins
|
global _initialized_plugins
|
||||||
_initialized_plugins = []
|
_initialized_plugins = []
|
||||||
@ -638,6 +696,7 @@ def initialize_plugins(perf=False):
|
|||||||
|
|
||||||
initialize_plugins()
|
initialize_plugins()
|
||||||
|
|
||||||
|
|
||||||
def initialized_plugins():
|
def initialized_plugins():
|
||||||
for plugin in _initialized_plugins:
|
for plugin in _initialized_plugins:
|
||||||
yield plugin
|
yield plugin
|
||||||
@ -646,6 +705,7 @@ def initialized_plugins():
|
|||||||
|
|
||||||
# CLI {{{
|
# CLI {{{
|
||||||
|
|
||||||
|
|
||||||
def build_plugin(path):
|
def build_plugin(path):
|
||||||
from calibre import prints
|
from calibre import prints
|
||||||
from calibre.ptempfile import PersistentTemporaryFile
|
from calibre.ptempfile import PersistentTemporaryFile
|
||||||
@ -663,6 +723,7 @@ def build_plugin(path):
|
|||||||
os.remove(t.name)
|
os.remove(t.name)
|
||||||
prints(u'Plugin updated:', plugin.name, plugin.version)
|
prints(u'Plugin updated:', plugin.name, plugin.version)
|
||||||
|
|
||||||
|
|
||||||
def option_parser():
|
def option_parser():
|
||||||
parser = OptionParser(usage=_('''\
|
parser = OptionParser(usage=_('''\
|
||||||
%prog options
|
%prog options
|
||||||
@ -687,6 +748,7 @@ def option_parser():
|
|||||||
help=_('Disable the named plugin'))
|
help=_('Disable the named plugin'))
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
|
|
||||||
def main(args=sys.argv):
|
def main(args=sys.argv):
|
||||||
parser = option_parser()
|
parser = option_parser()
|
||||||
if len(args) < 2:
|
if len(args) < 2:
|
||||||
|
@ -20,6 +20,7 @@ from calibre.customize import (Plugin, numeric_version, platform,
|
|||||||
# python 2.x that prevents importing from zip files in locations whose paths
|
# python 2.x that prevents importing from zip files in locations whose paths
|
||||||
# have non ASCII characters
|
# have non ASCII characters
|
||||||
|
|
||||||
|
|
||||||
def get_resources(zfp, name_or_list_of_names):
|
def get_resources(zfp, name_or_list_of_names):
|
||||||
'''
|
'''
|
||||||
Load resources from the plugin zip file
|
Load resources from the plugin zip file
|
||||||
@ -48,6 +49,7 @@ def get_resources(zfp, name_or_list_of_names):
|
|||||||
|
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
|
|
||||||
def get_icons(zfp, name_or_list_of_names):
|
def get_icons(zfp, name_or_list_of_names):
|
||||||
'''
|
'''
|
||||||
Load icons from the plugin zip file
|
Load icons from the plugin zip file
|
||||||
@ -83,6 +85,7 @@ def get_icons(zfp, name_or_list_of_names):
|
|||||||
|
|
||||||
_translations_cache = {}
|
_translations_cache = {}
|
||||||
|
|
||||||
|
|
||||||
def load_translations(namespace, zfp):
|
def load_translations(namespace, zfp):
|
||||||
null = object()
|
null = object()
|
||||||
trans = _translations_cache.get(zfp, null)
|
trans = _translations_cache.get(zfp, null)
|
||||||
@ -109,6 +112,7 @@ def load_translations(namespace, zfp):
|
|||||||
namespace['_'] = trans.ugettext
|
namespace['_'] = trans.ugettext
|
||||||
namespace['ngettext'] = trans.ungettext
|
namespace['ngettext'] = trans.ungettext
|
||||||
|
|
||||||
|
|
||||||
class PluginLoader(object):
|
class PluginLoader(object):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@ -9,6 +9,7 @@ __docformat__ = 'restructuredtext en'
|
|||||||
|
|
||||||
SPOOL_SIZE = 30*1024*1024
|
SPOOL_SIZE = 30*1024*1024
|
||||||
|
|
||||||
|
|
||||||
def _get_next_series_num_for_list(series_indices, unwrap=True):
|
def _get_next_series_num_for_list(series_indices, unwrap=True):
|
||||||
from calibre.utils.config_base import tweaks
|
from calibre.utils.config_base import tweaks
|
||||||
from math import ceil, floor
|
from math import ceil, floor
|
||||||
@ -39,6 +40,7 @@ def _get_next_series_num_for_list(series_indices, unwrap=True):
|
|||||||
return float(tweaks['series_index_auto_increment'])
|
return float(tweaks['series_index_auto_increment'])
|
||||||
return 1.0
|
return 1.0
|
||||||
|
|
||||||
|
|
||||||
def _get_series_values(val):
|
def _get_series_values(val):
|
||||||
import re
|
import re
|
||||||
series_index_pat = re.compile(r'(.*)\s+\[([.0-9]+)\]$')
|
series_index_pat = re.compile(r'(.*)\s+\[([.0-9]+)\]$')
|
||||||
@ -54,6 +56,7 @@ def _get_series_values(val):
|
|||||||
pass
|
pass
|
||||||
return (val, None)
|
return (val, None)
|
||||||
|
|
||||||
|
|
||||||
def get_data_as_dict(self, prefix=None, authors_as_string=False, ids=None, convert_to_local_tz=True):
|
def get_data_as_dict(self, prefix=None, authors_as_string=False, ids=None, convert_to_local_tz=True):
|
||||||
'''
|
'''
|
||||||
Return all metadata stored in the database as a dict. Includes paths to
|
Return all metadata stored in the database as a dict. Includes paths to
|
||||||
|
@ -12,20 +12,25 @@ from future_builtins import map
|
|||||||
|
|
||||||
from calibre.ebooks import BOOK_EXTENSIONS
|
from calibre.ebooks import BOOK_EXTENSIONS
|
||||||
|
|
||||||
|
|
||||||
def splitext(path):
|
def splitext(path):
|
||||||
key, ext = os.path.splitext(path)
|
key, ext = os.path.splitext(path)
|
||||||
return key, ext[1:].lower()
|
return key, ext[1:].lower()
|
||||||
|
|
||||||
|
|
||||||
def formats_ok(formats):
|
def formats_ok(formats):
|
||||||
return len(formats) > 0
|
return len(formats) > 0
|
||||||
|
|
||||||
|
|
||||||
def path_ok(path):
|
def path_ok(path):
|
||||||
return not os.path.isdir(path) and os.access(path, os.R_OK)
|
return not os.path.isdir(path) and os.access(path, os.R_OK)
|
||||||
|
|
||||||
|
|
||||||
def compile_glob(pat):
|
def compile_glob(pat):
|
||||||
import fnmatch
|
import fnmatch
|
||||||
return re.compile(fnmatch.translate(pat), flags=re.I)
|
return re.compile(fnmatch.translate(pat), flags=re.I)
|
||||||
|
|
||||||
|
|
||||||
def compile_rule(rule):
|
def compile_rule(rule):
|
||||||
mt = rule['match_type']
|
mt = rule['match_type']
|
||||||
if 'with' in mt:
|
if 'with' in mt:
|
||||||
@ -45,6 +50,7 @@ def compile_rule(rule):
|
|||||||
ans = lambda filename: not func(filename)
|
ans = lambda filename: not func(filename)
|
||||||
return ans, rule['action'] == 'add'
|
return ans, rule['action'] == 'add'
|
||||||
|
|
||||||
|
|
||||||
def filter_filename(compiled_rules, filename):
|
def filter_filename(compiled_rules, filename):
|
||||||
for q, action in compiled_rules:
|
for q, action in compiled_rules:
|
||||||
if q(filename):
|
if q(filename):
|
||||||
@ -52,6 +58,7 @@ def filter_filename(compiled_rules, filename):
|
|||||||
|
|
||||||
_metadata_extensions = None
|
_metadata_extensions = None
|
||||||
|
|
||||||
|
|
||||||
def metadata_extensions():
|
def metadata_extensions():
|
||||||
# Set of all known book extensions + OPF (the OPF is used to read metadata,
|
# Set of all known book extensions + OPF (the OPF is used to read metadata,
|
||||||
# but not actually added)
|
# but not actually added)
|
||||||
@ -60,6 +67,7 @@ def metadata_extensions():
|
|||||||
_metadata_extensions = frozenset(map(unicode, BOOK_EXTENSIONS)) | {'opf'}
|
_metadata_extensions = frozenset(map(unicode, BOOK_EXTENSIONS)) | {'opf'}
|
||||||
return _metadata_extensions
|
return _metadata_extensions
|
||||||
|
|
||||||
|
|
||||||
def listdir(root, sort_by_mtime=False):
|
def listdir(root, sort_by_mtime=False):
|
||||||
items = (os.path.join(root, x) for x in os.listdir(root))
|
items = (os.path.join(root, x) for x in os.listdir(root))
|
||||||
if sort_by_mtime:
|
if sort_by_mtime:
|
||||||
@ -74,12 +82,14 @@ def listdir(root, sort_by_mtime=False):
|
|||||||
if path_ok(path):
|
if path_ok(path):
|
||||||
yield path
|
yield path
|
||||||
|
|
||||||
|
|
||||||
def allow_path(path, ext, compiled_rules):
|
def allow_path(path, ext, compiled_rules):
|
||||||
ans = filter_filename(compiled_rules, os.path.basename(path))
|
ans = filter_filename(compiled_rules, os.path.basename(path))
|
||||||
if ans is None:
|
if ans is None:
|
||||||
ans = ext in metadata_extensions()
|
ans = ext in metadata_extensions()
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
|
|
||||||
def find_books_in_directory(dirpath, single_book_per_directory, compiled_rules=(), listdir_impl=listdir):
|
def find_books_in_directory(dirpath, single_book_per_directory, compiled_rules=(), listdir_impl=listdir):
|
||||||
dirpath = os.path.abspath(dirpath)
|
dirpath = os.path.abspath(dirpath)
|
||||||
if single_book_per_directory:
|
if single_book_per_directory:
|
||||||
@ -101,6 +111,7 @@ def find_books_in_directory(dirpath, single_book_per_directory, compiled_rules=(
|
|||||||
if formats_ok(formats):
|
if formats_ok(formats):
|
||||||
yield list(formats.itervalues())
|
yield list(formats.itervalues())
|
||||||
|
|
||||||
|
|
||||||
def import_book_directory_multiple(db, dirpath, callback=None,
|
def import_book_directory_multiple(db, dirpath, callback=None,
|
||||||
added_ids=None, compiled_rules=()):
|
added_ids=None, compiled_rules=()):
|
||||||
from calibre.ebooks.metadata.meta import metadata_from_formats
|
from calibre.ebooks.metadata.meta import metadata_from_formats
|
||||||
@ -121,6 +132,7 @@ def import_book_directory_multiple(db, dirpath, callback=None,
|
|||||||
break
|
break
|
||||||
return duplicates
|
return duplicates
|
||||||
|
|
||||||
|
|
||||||
def import_book_directory(db, dirpath, callback=None, added_ids=None, compiled_rules=()):
|
def import_book_directory(db, dirpath, callback=None, added_ids=None, compiled_rules=()):
|
||||||
from calibre.ebooks.metadata.meta import metadata_from_formats
|
from calibre.ebooks.metadata.meta import metadata_from_formats
|
||||||
dirpath = os.path.abspath(dirpath)
|
dirpath = os.path.abspath(dirpath)
|
||||||
@ -140,6 +152,7 @@ def import_book_directory(db, dirpath, callback=None, added_ids=None, compiled_r
|
|||||||
if callable(callback):
|
if callable(callback):
|
||||||
callback(mi.title)
|
callback(mi.title)
|
||||||
|
|
||||||
|
|
||||||
def recursive_import(db, root, single_book_per_directory=True,
|
def recursive_import(db, root, single_book_per_directory=True,
|
||||||
callback=None, added_ids=None, compiled_rules=()):
|
callback=None, added_ids=None, compiled_rules=()):
|
||||||
root = os.path.abspath(root)
|
root = os.path.abspath(root)
|
||||||
@ -156,6 +169,7 @@ def recursive_import(db, root, single_book_per_directory=True,
|
|||||||
break
|
break
|
||||||
return duplicates
|
return duplicates
|
||||||
|
|
||||||
|
|
||||||
def add_catalog(cache, path, title, dbapi=None):
|
def add_catalog(cache, path, title, dbapi=None):
|
||||||
from calibre.ebooks.metadata.book.base import Metadata
|
from calibre.ebooks.metadata.book.base import Metadata
|
||||||
from calibre.ebooks.metadata.meta import get_metadata
|
from calibre.ebooks.metadata.meta import get_metadata
|
||||||
@ -189,6 +203,7 @@ def add_catalog(cache, path, title, dbapi=None):
|
|||||||
|
|
||||||
return db_id, new_book_added
|
return db_id, new_book_added
|
||||||
|
|
||||||
|
|
||||||
def add_news(cache, path, arg, dbapi=None):
|
def add_news(cache, path, arg, dbapi=None):
|
||||||
from calibre.ebooks.metadata.meta import get_metadata
|
from calibre.ebooks.metadata.meta import get_metadata
|
||||||
from calibre.utils.date import utcnow
|
from calibre.utils.date import utcnow
|
||||||
|
@ -65,6 +65,7 @@ class DynamicFilter(object): # {{{
|
|||||||
self.ids = frozenset(ids)
|
self.ids = frozenset(ids)
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
|
|
||||||
class DBPrefs(dict): # {{{
|
class DBPrefs(dict): # {{{
|
||||||
|
|
||||||
'Store preferences as key:value pairs in the db'
|
'Store preferences as key:value pairs in the db'
|
||||||
@ -160,6 +161,8 @@ class DBPrefs(dict): # {{{
|
|||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
# Extra collators {{{
|
# Extra collators {{{
|
||||||
|
|
||||||
|
|
||||||
def pynocase(one, two, encoding='utf-8'):
|
def pynocase(one, two, encoding='utf-8'):
|
||||||
if isbytestring(one):
|
if isbytestring(one):
|
||||||
try:
|
try:
|
||||||
@ -173,11 +176,13 @@ def pynocase(one, two, encoding='utf-8'):
|
|||||||
pass
|
pass
|
||||||
return cmp(one.lower(), two.lower())
|
return cmp(one.lower(), two.lower())
|
||||||
|
|
||||||
|
|
||||||
def _author_to_author_sort(x):
|
def _author_to_author_sort(x):
|
||||||
if not x:
|
if not x:
|
||||||
return ''
|
return ''
|
||||||
return author_to_author_sort(x.replace('|', ','))
|
return author_to_author_sort(x.replace('|', ','))
|
||||||
|
|
||||||
|
|
||||||
def icu_collator(s1, s2):
|
def icu_collator(s1, s2):
|
||||||
return cmp(sort_key(force_unicode(s1, 'utf-8')),
|
return cmp(sort_key(force_unicode(s1, 'utf-8')),
|
||||||
sort_key(force_unicode(s2, 'utf-8')))
|
sort_key(force_unicode(s2, 'utf-8')))
|
||||||
@ -185,6 +190,8 @@ def icu_collator(s1, s2):
|
|||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
# Unused aggregators {{{
|
# Unused aggregators {{{
|
||||||
|
|
||||||
|
|
||||||
def Concatenate(sep=','):
|
def Concatenate(sep=','):
|
||||||
'''String concatenation aggregator for sqlite'''
|
'''String concatenation aggregator for sqlite'''
|
||||||
|
|
||||||
@ -199,6 +206,7 @@ def Concatenate(sep=','):
|
|||||||
|
|
||||||
return ([], step, finalize)
|
return ([], step, finalize)
|
||||||
|
|
||||||
|
|
||||||
def SortedConcatenate(sep=','):
|
def SortedConcatenate(sep=','):
|
||||||
'''String concatenation aggregator for sqlite, sorted by supplied index'''
|
'''String concatenation aggregator for sqlite, sorted by supplied index'''
|
||||||
|
|
||||||
@ -213,6 +221,7 @@ def SortedConcatenate(sep=','):
|
|||||||
|
|
||||||
return ({}, step, finalize)
|
return ({}, step, finalize)
|
||||||
|
|
||||||
|
|
||||||
def IdentifiersConcat():
|
def IdentifiersConcat():
|
||||||
'''String concatenation aggregator for the identifiers map'''
|
'''String concatenation aggregator for the identifiers map'''
|
||||||
|
|
||||||
@ -224,6 +233,7 @@ def IdentifiersConcat():
|
|||||||
|
|
||||||
return ([], step, finalize)
|
return ([], step, finalize)
|
||||||
|
|
||||||
|
|
||||||
def AumSortedConcatenate():
|
def AumSortedConcatenate():
|
||||||
'''String concatenation aggregator for the author sort map'''
|
'''String concatenation aggregator for the author sort map'''
|
||||||
|
|
||||||
@ -244,6 +254,7 @@ def AumSortedConcatenate():
|
|||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
|
|
||||||
class Connection(apsw.Connection): # {{{
|
class Connection(apsw.Connection): # {{{
|
||||||
|
|
||||||
BUSY_TIMEOUT = 10000 # milliseconds
|
BUSY_TIMEOUT = 10000 # milliseconds
|
||||||
@ -304,6 +315,7 @@ class Connection(apsw.Connection): # {{{
|
|||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
|
|
||||||
class DB(object):
|
class DB(object):
|
||||||
|
|
||||||
PATH_LIMIT = 40 if iswindows else 100
|
PATH_LIMIT = 40 if iswindows else 100
|
||||||
@ -1626,6 +1638,7 @@ class DB(object):
|
|||||||
|
|
||||||
def get_custom_book_data(self, name, book_ids, default=None):
|
def get_custom_book_data(self, name, book_ids, default=None):
|
||||||
book_ids = frozenset(book_ids)
|
book_ids = frozenset(book_ids)
|
||||||
|
|
||||||
def safe_load(val):
|
def safe_load(val):
|
||||||
try:
|
try:
|
||||||
return json.loads(val, object_hook=from_json)
|
return json.loads(val, object_hook=from_json)
|
||||||
|
@ -13,9 +13,11 @@ from threading import Thread, Event
|
|||||||
from calibre import prints
|
from calibre import prints
|
||||||
from calibre.ebooks.metadata.opf2 import metadata_to_opf
|
from calibre.ebooks.metadata.opf2 import metadata_to_opf
|
||||||
|
|
||||||
|
|
||||||
class Abort(Exception):
|
class Abort(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class MetadataBackup(Thread):
|
class MetadataBackup(Thread):
|
||||||
'''
|
'''
|
||||||
Continuously backup changed metadata into OPF files
|
Continuously backup changed metadata into OPF files
|
||||||
|
@ -35,20 +35,24 @@ from calibre.utils.config import prefs, tweaks
|
|||||||
from calibre.utils.date import now as nowf, utcnow, UNDEFINED_DATE
|
from calibre.utils.date import now as nowf, utcnow, UNDEFINED_DATE
|
||||||
from calibre.utils.icu import sort_key
|
from calibre.utils.icu import sort_key
|
||||||
|
|
||||||
|
|
||||||
def api(f):
|
def api(f):
|
||||||
f.is_cache_api = True
|
f.is_cache_api = True
|
||||||
return f
|
return f
|
||||||
|
|
||||||
|
|
||||||
def read_api(f):
|
def read_api(f):
|
||||||
f = api(f)
|
f = api(f)
|
||||||
f.is_read_api = True
|
f.is_read_api = True
|
||||||
return f
|
return f
|
||||||
|
|
||||||
|
|
||||||
def write_api(f):
|
def write_api(f):
|
||||||
f = api(f)
|
f = api(f)
|
||||||
f.is_read_api = False
|
f.is_read_api = False
|
||||||
return f
|
return f
|
||||||
|
|
||||||
|
|
||||||
def wrap_simple(lock, func):
|
def wrap_simple(lock, func):
|
||||||
@wraps(func)
|
@wraps(func)
|
||||||
def call_func_with_lock(*args, **kwargs):
|
def call_func_with_lock(*args, **kwargs):
|
||||||
@ -62,6 +66,7 @@ def wrap_simple(lock, func):
|
|||||||
return func(*args, **kwargs)
|
return func(*args, **kwargs)
|
||||||
return call_func_with_lock
|
return call_func_with_lock
|
||||||
|
|
||||||
|
|
||||||
def run_import_plugins(path_or_stream, fmt):
|
def run_import_plugins(path_or_stream, fmt):
|
||||||
fmt = fmt.lower()
|
fmt = fmt.lower()
|
||||||
if hasattr(path_or_stream, 'seek'):
|
if hasattr(path_or_stream, 'seek'):
|
||||||
@ -74,6 +79,7 @@ def run_import_plugins(path_or_stream, fmt):
|
|||||||
path = path_or_stream
|
path = path_or_stream
|
||||||
return run_plugins_on_import(path, fmt)
|
return run_plugins_on_import(path, fmt)
|
||||||
|
|
||||||
|
|
||||||
def _add_newbook_tag(mi):
|
def _add_newbook_tag(mi):
|
||||||
tags = prefs['new_book_tags']
|
tags = prefs['new_book_tags']
|
||||||
if tags:
|
if tags:
|
||||||
@ -86,6 +92,7 @@ def _add_newbook_tag(mi):
|
|||||||
|
|
||||||
dynamic_category_preferences = frozenset({'grouped_search_make_user_categories', 'grouped_search_terms', 'user_categories'})
|
dynamic_category_preferences = frozenset({'grouped_search_make_user_categories', 'grouped_search_terms', 'user_categories'})
|
||||||
|
|
||||||
|
|
||||||
class Cache(object):
|
class Cache(object):
|
||||||
|
|
||||||
'''
|
'''
|
||||||
@ -804,6 +811,7 @@ class Cache(object):
|
|||||||
path = self._field_for('path', book_id).replace('/', os.sep)
|
path = self._field_for('path', book_id).replace('/', os.sep)
|
||||||
except:
|
except:
|
||||||
return ()
|
return ()
|
||||||
|
|
||||||
def verify(fmt):
|
def verify(fmt):
|
||||||
try:
|
try:
|
||||||
name = self.fields['formats'].format_fname(book_id, fmt)
|
name = self.fields['formats'].format_fname(book_id, fmt)
|
||||||
@ -918,6 +926,7 @@ class Cache(object):
|
|||||||
return virtual_fields[fm.get(field, field)].sort_keys_for_books(get_metadata, lang_map)
|
return virtual_fields[fm.get(field, field)].sort_keys_for_books(get_metadata, lang_map)
|
||||||
if is_series:
|
if is_series:
|
||||||
idx_func = self.fields[idx].sort_keys_for_books(get_metadata, lang_map)
|
idx_func = self.fields[idx].sort_keys_for_books(get_metadata, lang_map)
|
||||||
|
|
||||||
def skf(book_id):
|
def skf(book_id):
|
||||||
return (func(book_id), idx_func(book_id))
|
return (func(book_id), idx_func(book_id))
|
||||||
return skf
|
return skf
|
||||||
@ -2160,6 +2169,7 @@ class Cache(object):
|
|||||||
if progress is not None:
|
if progress is not None:
|
||||||
progress(_('Completed'), total, total)
|
progress(_('Completed'), total, total)
|
||||||
|
|
||||||
|
|
||||||
def import_library(library_key, importer, library_path, progress=None, abort=None):
|
def import_library(library_key, importer, library_path, progress=None, abort=None):
|
||||||
from calibre.db.backend import DB
|
from calibre.db.backend import DB
|
||||||
metadata = importer.metadata[library_key]
|
metadata = importer.metadata[library_key]
|
||||||
|
@ -17,6 +17,7 @@ from calibre.utils.icu import sort_key, collation_order
|
|||||||
|
|
||||||
CATEGORY_SORTS = ('name', 'popularity', 'rating') # This has to be a tuple not a set
|
CATEGORY_SORTS = ('name', 'popularity', 'rating') # This has to be a tuple not a set
|
||||||
|
|
||||||
|
|
||||||
class Tag(object):
|
class Tag(object):
|
||||||
|
|
||||||
__slots__ = ('name', 'original_name', 'id', 'count', 'state', 'is_hierarchical',
|
__slots__ = ('name', 'original_name', 'id', 'count', 'state', 'is_hierarchical',
|
||||||
@ -51,6 +52,7 @@ class Tag(object):
|
|||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return str(self)
|
return str(self)
|
||||||
|
|
||||||
|
|
||||||
def find_categories(field_metadata):
|
def find_categories(field_metadata):
|
||||||
for category, cat in field_metadata.iteritems():
|
for category, cat in field_metadata.iteritems():
|
||||||
if (cat['is_category'] and cat['kind'] not in {'user', 'search'}):
|
if (cat['is_category'] and cat['kind'] not in {'user', 'search'}):
|
||||||
@ -59,6 +61,7 @@ def find_categories(field_metadata):
|
|||||||
cat['display'].get('make_category', False)):
|
cat['display'].get('make_category', False)):
|
||||||
yield (category, cat['is_multiple'].get('cache_to_list', None), True)
|
yield (category, cat['is_multiple'].get('cache_to_list', None), True)
|
||||||
|
|
||||||
|
|
||||||
def create_tag_class(category, fm):
|
def create_tag_class(category, fm):
|
||||||
cat = fm[category]
|
cat = fm[category]
|
||||||
dt = cat['datatype']
|
dt = cat['datatype']
|
||||||
@ -77,6 +80,7 @@ def create_tag_class(category, fm):
|
|||||||
return partial(Tag, use_sort_as_name=use_sort_as_name,
|
return partial(Tag, use_sort_as_name=use_sort_as_name,
|
||||||
is_editable=is_editable, category=category)
|
is_editable=is_editable, category=category)
|
||||||
|
|
||||||
|
|
||||||
def clean_user_categories(dbcache):
|
def clean_user_categories(dbcache):
|
||||||
user_cats = dbcache.pref('user_categories', {})
|
user_cats = dbcache.pref('user_categories', {})
|
||||||
new_cats = {}
|
new_cats = {}
|
||||||
@ -108,6 +112,7 @@ category_sort_keys[True]['name'] = \
|
|||||||
category_sort_keys[False]['name'] = \
|
category_sort_keys[False]['name'] = \
|
||||||
lambda x:sort_key(x.sort or x.name)
|
lambda x:sort_key(x.sort or x.name)
|
||||||
|
|
||||||
|
|
||||||
def get_categories(dbcache, sort='name', book_ids=None, first_letter_sort=False):
|
def get_categories(dbcache, sort='name', book_ids=None, first_letter_sort=False):
|
||||||
if sort not in CATEGORY_SORTS:
|
if sort not in CATEGORY_SORTS:
|
||||||
raise ValueError('sort ' + sort + ' not a valid value')
|
raise ValueError('sort ' + sort + ' not a valid value')
|
||||||
|
@ -14,6 +14,7 @@ from calibre.ptempfile import remove_dir
|
|||||||
from calibre.utils.filenames import remove_dir_if_empty
|
from calibre.utils.filenames import remove_dir_if_empty
|
||||||
from calibre.utils.recycle_bin import delete_tree, delete_file
|
from calibre.utils.recycle_bin import delete_tree, delete_file
|
||||||
|
|
||||||
|
|
||||||
class DeleteService(Thread):
|
class DeleteService(Thread):
|
||||||
|
|
||||||
''' Provide a blocking file delete implementation with support for the
|
''' Provide a blocking file delete implementation with support for the
|
||||||
@ -136,6 +137,8 @@ class DeleteService(Thread):
|
|||||||
shutil.rmtree(tdir)
|
shutil.rmtree(tdir)
|
||||||
|
|
||||||
__ds = None
|
__ds = None
|
||||||
|
|
||||||
|
|
||||||
def delete_service():
|
def delete_service():
|
||||||
global __ds
|
global __ds
|
||||||
if __ds is None:
|
if __ds is None:
|
||||||
@ -143,12 +146,14 @@ def delete_service():
|
|||||||
__ds.start()
|
__ds.start()
|
||||||
return __ds
|
return __ds
|
||||||
|
|
||||||
|
|
||||||
def shutdown(timeout=20):
|
def shutdown(timeout=20):
|
||||||
global __ds
|
global __ds
|
||||||
if __ds is not None:
|
if __ds is not None:
|
||||||
__ds.shutdown(timeout)
|
__ds.shutdown(timeout)
|
||||||
__ds = None
|
__ds = None
|
||||||
|
|
||||||
|
|
||||||
def has_jobs():
|
def has_jobs():
|
||||||
global __ds
|
global __ds
|
||||||
if __ds is not None:
|
if __ds is not None:
|
||||||
|
@ -21,17 +21,20 @@ from calibre.utils.icu import sort_key
|
|||||||
from calibre.utils.date import UNDEFINED_DATE, clean_date_for_sort, parse_date
|
from calibre.utils.date import UNDEFINED_DATE, clean_date_for_sort, parse_date
|
||||||
from calibre.utils.localization import calibre_langcode_to_name
|
from calibre.utils.localization import calibre_langcode_to_name
|
||||||
|
|
||||||
|
|
||||||
def bool_sort_key(bools_are_tristate):
|
def bool_sort_key(bools_are_tristate):
|
||||||
return (lambda x:{True: 1, False: 2, None: 3}.get(x, 3)) if bools_are_tristate else lambda x:{True: 1, False: 2, None: 2}.get(x, 2)
|
return (lambda x:{True: 1, False: 2, None: 3}.get(x, 3)) if bools_are_tristate else lambda x:{True: 1, False: 2, None: 2}.get(x, 2)
|
||||||
|
|
||||||
IDENTITY = lambda x: x
|
IDENTITY = lambda x: x
|
||||||
|
|
||||||
|
|
||||||
class InvalidLinkTable(Exception):
|
class InvalidLinkTable(Exception):
|
||||||
|
|
||||||
def __init__(self, name):
|
def __init__(self, name):
|
||||||
Exception.__init__(self, name)
|
Exception.__init__(self, name)
|
||||||
self.field_name = name
|
self.field_name = name
|
||||||
|
|
||||||
|
|
||||||
class Field(object):
|
class Field(object):
|
||||||
|
|
||||||
is_many = False
|
is_many = False
|
||||||
@ -166,6 +169,7 @@ class Field(object):
|
|||||||
ans.append(c)
|
ans.append(c)
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
|
|
||||||
class OneToOneField(Field):
|
class OneToOneField(Field):
|
||||||
|
|
||||||
def for_book(self, book_id, default_value=None):
|
def for_book(self, book_id, default_value=None):
|
||||||
@ -193,6 +197,7 @@ class OneToOneField(Field):
|
|||||||
for book_id in candidates:
|
for book_id in candidates:
|
||||||
yield cbm.get(book_id, default_value), {book_id}
|
yield cbm.get(book_id, default_value), {book_id}
|
||||||
|
|
||||||
|
|
||||||
class CompositeField(OneToOneField):
|
class CompositeField(OneToOneField):
|
||||||
|
|
||||||
is_composite = True
|
is_composite = True
|
||||||
@ -339,6 +344,7 @@ class CompositeField(OneToOneField):
|
|||||||
ans.add(book_id)
|
ans.add(book_id)
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
|
|
||||||
class OnDeviceField(OneToOneField):
|
class OnDeviceField(OneToOneField):
|
||||||
|
|
||||||
def __init__(self, name, table, bools_are_tristate):
|
def __init__(self, name, table, bools_are_tristate):
|
||||||
@ -403,6 +409,7 @@ class OnDeviceField(OneToOneField):
|
|||||||
for val, book_ids in val_map.iteritems():
|
for val, book_ids in val_map.iteritems():
|
||||||
yield val, book_ids
|
yield val, book_ids
|
||||||
|
|
||||||
|
|
||||||
class LazySortMap(object):
|
class LazySortMap(object):
|
||||||
|
|
||||||
__slots__ = ('default_sort_key', 'sort_key_func', 'id_map', 'cache')
|
__slots__ = ('default_sort_key', 'sort_key_func', 'id_map', 'cache')
|
||||||
@ -469,6 +476,7 @@ class ManyToOneField(Field):
|
|||||||
except KeyError:
|
except KeyError:
|
||||||
raise InvalidLinkTable(self.name)
|
raise InvalidLinkTable(self.name)
|
||||||
|
|
||||||
|
|
||||||
class ManyToManyField(Field):
|
class ManyToManyField(Field):
|
||||||
|
|
||||||
is_many = True
|
is_many = True
|
||||||
@ -534,6 +542,7 @@ class ManyToManyField(Field):
|
|||||||
except KeyError:
|
except KeyError:
|
||||||
raise InvalidLinkTable(self.name)
|
raise InvalidLinkTable(self.name)
|
||||||
|
|
||||||
|
|
||||||
class IdentifiersField(ManyToManyField):
|
class IdentifiersField(ManyToManyField):
|
||||||
|
|
||||||
def for_book(self, book_id, default_value=None):
|
def for_book(self, book_id, default_value=None):
|
||||||
@ -569,6 +578,7 @@ class IdentifiersField(ManyToManyField):
|
|||||||
ans.append(c)
|
ans.append(c)
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
|
|
||||||
class AuthorsField(ManyToManyField):
|
class AuthorsField(ManyToManyField):
|
||||||
|
|
||||||
def author_data(self, author_id):
|
def author_data(self, author_id):
|
||||||
@ -588,6 +598,7 @@ class AuthorsField(ManyToManyField):
|
|||||||
return ' & '.join(self.table.asort_map[k] for k in
|
return ' & '.join(self.table.asort_map[k] for k in
|
||||||
self.table.book_col_map[book_id])
|
self.table.book_col_map[book_id])
|
||||||
|
|
||||||
|
|
||||||
class FormatsField(ManyToManyField):
|
class FormatsField(ManyToManyField):
|
||||||
|
|
||||||
def for_book(self, book_id, default_value=None):
|
def for_book(self, book_id, default_value=None):
|
||||||
@ -618,6 +629,7 @@ class FormatsField(ManyToManyField):
|
|||||||
ans.append(c)
|
ans.append(c)
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
|
|
||||||
class LazySeriesSortMap(object):
|
class LazySeriesSortMap(object):
|
||||||
|
|
||||||
__slots__ = ('default_sort_key', 'sort_key_func', 'id_map', 'cache')
|
__slots__ = ('default_sort_key', 'sort_key_func', 'id_map', 'cache')
|
||||||
@ -638,12 +650,14 @@ class LazySeriesSortMap(object):
|
|||||||
val = self.cache[(item_id, lang)] = self.default_sort_key
|
val = self.cache[(item_id, lang)] = self.default_sort_key
|
||||||
return val
|
return val
|
||||||
|
|
||||||
|
|
||||||
class SeriesField(ManyToOneField):
|
class SeriesField(ManyToOneField):
|
||||||
|
|
||||||
def sort_keys_for_books(self, get_metadata, lang_map):
|
def sort_keys_for_books(self, get_metadata, lang_map):
|
||||||
sso = tweaks['title_series_sorting']
|
sso = tweaks['title_series_sorting']
|
||||||
ssk = self._sort_key
|
ssk = self._sort_key
|
||||||
ts = title_sort
|
ts = title_sort
|
||||||
|
|
||||||
def sk(val, lang):
|
def sk(val, lang):
|
||||||
return ssk(ts(val, order=sso, lang=lang))
|
return ssk(ts(val, order=sso, lang=lang))
|
||||||
sk_map = LazySeriesSortMap(self._default_sort_key, sk, self.table.id_map)
|
sk_map = LazySeriesSortMap(self._default_sort_key, sk, self.table.id_map)
|
||||||
@ -718,6 +732,7 @@ class TagsField(ManyToManyField):
|
|||||||
ans.append(c)
|
ans.append(c)
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
|
|
||||||
def create_field(name, table, bools_are_tristate):
|
def create_field(name, table, bools_are_tristate):
|
||||||
cls = {
|
cls = {
|
||||||
ONE_ONE: OneToOneField,
|
ONE_ONE: OneToOneField,
|
||||||
|
@ -23,6 +23,7 @@ Speeds up calibre startup with large libraries/libraries on a network share,
|
|||||||
with a composite custom column.
|
with a composite custom column.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
def resolved(f):
|
def resolved(f):
|
||||||
@wraps(f)
|
@wraps(f)
|
||||||
def wrapper(self, *args, **kwargs):
|
def wrapper(self, *args, **kwargs):
|
||||||
@ -32,6 +33,7 @@ def resolved(f):
|
|||||||
return f(self, *args, **kwargs)
|
return f(self, *args, **kwargs)
|
||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
class MutableBase(object):
|
class MutableBase(object):
|
||||||
|
|
||||||
@resolved
|
@resolved
|
||||||
@ -87,6 +89,7 @@ class FormatMetadata(MutableBase, MutableMapping):
|
|||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class FormatsList(MutableBase, MutableSequence):
|
class FormatsList(MutableBase, MutableSequence):
|
||||||
|
|
||||||
def __init__(self, formats, format_metadata):
|
def __init__(self, formats, format_metadata):
|
||||||
@ -106,6 +109,7 @@ class FormatsList(MutableBase, MutableSequence):
|
|||||||
ga = object.__getattribute__
|
ga = object.__getattribute__
|
||||||
sa = object.__setattr__
|
sa = object.__setattr__
|
||||||
|
|
||||||
|
|
||||||
def simple_getter(field, default_value=None):
|
def simple_getter(field, default_value=None):
|
||||||
def func(dbref, book_id, cache):
|
def func(dbref, book_id, cache):
|
||||||
try:
|
try:
|
||||||
@ -116,6 +120,7 @@ def simple_getter(field, default_value=None):
|
|||||||
return ret
|
return ret
|
||||||
return func
|
return func
|
||||||
|
|
||||||
|
|
||||||
def pp_getter(field, postprocess, default_value=None):
|
def pp_getter(field, postprocess, default_value=None):
|
||||||
def func(dbref, book_id, cache):
|
def func(dbref, book_id, cache):
|
||||||
try:
|
try:
|
||||||
@ -126,6 +131,7 @@ def pp_getter(field, postprocess, default_value=None):
|
|||||||
return ret
|
return ret
|
||||||
return func
|
return func
|
||||||
|
|
||||||
|
|
||||||
def adata_getter(field):
|
def adata_getter(field):
|
||||||
def func(dbref, book_id, cache):
|
def func(dbref, book_id, cache):
|
||||||
try:
|
try:
|
||||||
@ -140,6 +146,7 @@ def adata_getter(field):
|
|||||||
return {adata[i]['name']:adata[i][k] for i in author_ids}
|
return {adata[i]['name']:adata[i][k] for i in author_ids}
|
||||||
return func
|
return func
|
||||||
|
|
||||||
|
|
||||||
def dt_getter(field):
|
def dt_getter(field):
|
||||||
def func(dbref, book_id, cache):
|
def func(dbref, book_id, cache):
|
||||||
try:
|
try:
|
||||||
@ -150,6 +157,7 @@ def dt_getter(field):
|
|||||||
return ret
|
return ret
|
||||||
return func
|
return func
|
||||||
|
|
||||||
|
|
||||||
def item_getter(field, default_value=None, key=0):
|
def item_getter(field, default_value=None, key=0):
|
||||||
def func(dbref, book_id, cache):
|
def func(dbref, book_id, cache):
|
||||||
try:
|
try:
|
||||||
@ -163,6 +171,7 @@ def item_getter(field, default_value=None, key=0):
|
|||||||
return default_value
|
return default_value
|
||||||
return func
|
return func
|
||||||
|
|
||||||
|
|
||||||
def fmt_getter(field):
|
def fmt_getter(field):
|
||||||
def func(dbref, book_id, cache):
|
def func(dbref, book_id, cache):
|
||||||
try:
|
try:
|
||||||
@ -179,6 +188,7 @@ def fmt_getter(field):
|
|||||||
return format_metadata
|
return format_metadata
|
||||||
return func
|
return func
|
||||||
|
|
||||||
|
|
||||||
def approx_fmts_getter(dbref, book_id, cache):
|
def approx_fmts_getter(dbref, book_id, cache):
|
||||||
try:
|
try:
|
||||||
return cache['formats']
|
return cache['formats']
|
||||||
@ -187,6 +197,7 @@ def approx_fmts_getter(dbref, book_id, cache):
|
|||||||
cache['formats'] = ret = list(db.field_for('formats', book_id))
|
cache['formats'] = ret = list(db.field_for('formats', book_id))
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
def series_index_getter(field='series'):
|
def series_index_getter(field='series'):
|
||||||
def func(dbref, book_id, cache):
|
def func(dbref, book_id, cache):
|
||||||
try:
|
try:
|
||||||
@ -202,6 +213,7 @@ def series_index_getter(field='series'):
|
|||||||
return ret
|
return ret
|
||||||
return func
|
return func
|
||||||
|
|
||||||
|
|
||||||
def has_cover_getter(dbref, book_id, cache):
|
def has_cover_getter(dbref, book_id, cache):
|
||||||
try:
|
try:
|
||||||
return cache['has_cover']
|
return cache['has_cover']
|
||||||
@ -211,6 +223,8 @@ def has_cover_getter(dbref, book_id, cache):
|
|||||||
return ret
|
return ret
|
||||||
|
|
||||||
fmt_custom = lambda x:list(x) if isinstance(x, tuple) else x
|
fmt_custom = lambda x:list(x) if isinstance(x, tuple) else x
|
||||||
|
|
||||||
|
|
||||||
def custom_getter(field, dbref, book_id, cache):
|
def custom_getter(field, dbref, book_id, cache):
|
||||||
try:
|
try:
|
||||||
return cache[field]
|
return cache[field]
|
||||||
@ -219,6 +233,7 @@ def custom_getter(field, dbref, book_id, cache):
|
|||||||
cache[field] = ret = fmt_custom(db.field_for(field, book_id))
|
cache[field] = ret = fmt_custom(db.field_for(field, book_id))
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
def composite_getter(mi, field, dbref, book_id, cache, formatter, template_cache):
|
def composite_getter(mi, field, dbref, book_id, cache, formatter, template_cache):
|
||||||
try:
|
try:
|
||||||
return cache[field]
|
return cache[field]
|
||||||
@ -239,6 +254,7 @@ def composite_getter(mi, field, dbref, book_id, cache, formatter, template_cache
|
|||||||
return 'ERROR WHILE EVALUATING: %s' % field
|
return 'ERROR WHILE EVALUATING: %s' % field
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
def virtual_libraries_getter(dbref, book_id, cache):
|
def virtual_libraries_getter(dbref, book_id, cache):
|
||||||
try:
|
try:
|
||||||
return cache['virtual_libraries']
|
return cache['virtual_libraries']
|
||||||
@ -248,6 +264,7 @@ def virtual_libraries_getter(dbref, book_id, cache):
|
|||||||
ret = cache['virtual_libraries'] = ', '.join(vls)
|
ret = cache['virtual_libraries'] = ', '.join(vls)
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
def user_categories_getter(proxy_metadata):
|
def user_categories_getter(proxy_metadata):
|
||||||
cache = ga(proxy_metadata, '_cache')
|
cache = ga(proxy_metadata, '_cache')
|
||||||
try:
|
try:
|
||||||
@ -293,6 +310,7 @@ for field in ('formats', 'format_metadata'):
|
|||||||
getters[field] = fmt_getter(field)
|
getters[field] = fmt_getter(field)
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
|
|
||||||
class ProxyMetadata(Metadata):
|
class ProxyMetadata(Metadata):
|
||||||
|
|
||||||
def __init__(self, db, book_id, formatter=None):
|
def __init__(self, db, book_id, formatter=None):
|
||||||
|
@ -24,6 +24,7 @@ from calibre.db.write import clean_identifier, get_series_values
|
|||||||
from calibre.utils.date import utcnow
|
from calibre.utils.date import utcnow
|
||||||
from calibre.utils.search_query_parser import set_saved_searches
|
from calibre.utils.search_query_parser import set_saved_searches
|
||||||
|
|
||||||
|
|
||||||
def cleanup_tags(tags):
|
def cleanup_tags(tags):
|
||||||
tags = [x.strip().replace(',', ';') for x in tags if x.strip()]
|
tags = [x.strip().replace(',', ';') for x in tags if x.strip()]
|
||||||
tags = [x.decode(preferred_encoding, 'replace')
|
tags = [x.decode(preferred_encoding, 'replace')
|
||||||
@ -36,6 +37,7 @@ def cleanup_tags(tags):
|
|||||||
ans.append(tag)
|
ans.append(tag)
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
|
|
||||||
def create_backend(
|
def create_backend(
|
||||||
library_path, default_prefs=None, read_only=False,
|
library_path, default_prefs=None, read_only=False,
|
||||||
progress_callback=lambda x, y:True, restore_all_prefs=False,
|
progress_callback=lambda x, y:True, restore_all_prefs=False,
|
||||||
@ -45,6 +47,7 @@ def create_backend(
|
|||||||
progress_callback=progress_callback,
|
progress_callback=progress_callback,
|
||||||
load_user_formatter_functions=load_user_formatter_functions)
|
load_user_formatter_functions=load_user_formatter_functions)
|
||||||
|
|
||||||
|
|
||||||
class LibraryDatabase(object):
|
class LibraryDatabase(object):
|
||||||
|
|
||||||
''' Emulate the old LibraryDatabase2 interface '''
|
''' Emulate the old LibraryDatabase2 interface '''
|
||||||
@ -748,6 +751,7 @@ for prop in ('author_sort', 'authors', 'comment', 'comments', 'publisher', 'max_
|
|||||||
def getter(prop):
|
def getter(prop):
|
||||||
fm = {'comment':'comments', 'metadata_last_modified':
|
fm = {'comment':'comments', 'metadata_last_modified':
|
||||||
'last_modified', 'title_sort':'sort', 'max_size':'size'}.get(prop, prop)
|
'last_modified', 'title_sort':'sort', 'max_size':'size'}.get(prop, prop)
|
||||||
|
|
||||||
def func(self, index, index_is_id=False):
|
def func(self, index, index_is_id=False):
|
||||||
return self.get_property(index, index_is_id=index_is_id, loc=self.FIELD_MAP[fm])
|
return self.get_property(index, index_is_id=index_is_id, loc=self.FIELD_MAP[fm])
|
||||||
return func
|
return func
|
||||||
@ -793,6 +797,7 @@ for field in (
|
|||||||
if has_case_change:
|
if has_case_change:
|
||||||
field = field[1:]
|
field = field[1:]
|
||||||
acc = field == 'series'
|
acc = field == 'series'
|
||||||
|
|
||||||
def func(self, book_id, val, notify=True, commit=True, allow_case_change=acc):
|
def func(self, book_id, val, notify=True, commit=True, allow_case_change=acc):
|
||||||
ret = self.new_api.set_field(field, {book_id:val}, allow_case_change=allow_case_change)
|
ret = self.new_api.set_field(field, {book_id:val}, allow_case_change=allow_case_change)
|
||||||
if notify:
|
if notify:
|
||||||
@ -804,6 +809,7 @@ for field in (
|
|||||||
else:
|
else:
|
||||||
null_field = field in {'title', 'sort', 'uuid'}
|
null_field = field in {'title', 'sort', 'uuid'}
|
||||||
retval = (True if field == 'sort' else None)
|
retval = (True if field == 'sort' else None)
|
||||||
|
|
||||||
def func(self, book_id, val, notify=True, commit=True):
|
def func(self, book_id, val, notify=True, commit=True):
|
||||||
if not val and null_field:
|
if not val and null_field:
|
||||||
return (False if field == 'sort' else None)
|
return (False if field == 'sort' else None)
|
||||||
@ -857,6 +863,7 @@ LibraryDatabase.get_author_id = MT(
|
|||||||
for field in ('tags', 'series', 'publishers', 'ratings', 'languages'):
|
for field in ('tags', 'series', 'publishers', 'ratings', 'languages'):
|
||||||
def getter(field):
|
def getter(field):
|
||||||
fname = field[:-1] if field in {'publishers', 'ratings'} else field
|
fname = field[:-1] if field in {'publishers', 'ratings'} else field
|
||||||
|
|
||||||
def func(self):
|
def func(self):
|
||||||
return [[tid, tag] for tid, tag in self.new_api.get_id_map(fname).iteritems()]
|
return [[tid, tag] for tid, tag in self.new_api.get_id_map(fname).iteritems()]
|
||||||
return func
|
return func
|
||||||
@ -865,6 +872,7 @@ for field in ('tags', 'series', 'publishers', 'ratings', 'languages'):
|
|||||||
for field in ('author', 'tag', 'series'):
|
for field in ('author', 'tag', 'series'):
|
||||||
def getter(field):
|
def getter(field):
|
||||||
field = field if field == 'series' else (field+'s')
|
field = field if field == 'series' else (field+'s')
|
||||||
|
|
||||||
def func(self, item_id):
|
def func(self, item_id):
|
||||||
return self.new_api.get_item_name(field, item_id)
|
return self.new_api.get_item_name(field, item_id)
|
||||||
return func
|
return func
|
||||||
@ -873,6 +881,7 @@ for field in ('author', 'tag', 'series'):
|
|||||||
for field in ('publisher', 'series', 'tag'):
|
for field in ('publisher', 'series', 'tag'):
|
||||||
def getter(field):
|
def getter(field):
|
||||||
fname = 'tags' if field == 'tag' else field
|
fname = 'tags' if field == 'tag' else field
|
||||||
|
|
||||||
def func(self, item_id):
|
def func(self, item_id):
|
||||||
self.new_api.remove_items(fname, (item_id,))
|
self.new_api.remove_items(fname, (item_id,))
|
||||||
return func
|
return func
|
||||||
@ -888,6 +897,7 @@ for func in (
|
|||||||
def getter(func):
|
def getter(func):
|
||||||
if func.startswith('!'):
|
if func.startswith('!'):
|
||||||
func = func[1:]
|
func = func[1:]
|
||||||
|
|
||||||
def meth(self, include_composites=True):
|
def meth(self, include_composites=True):
|
||||||
return getattr(self.field_metadata, func)(include_composites=include_composites)
|
return getattr(self.field_metadata, func)(include_composites=include_composites)
|
||||||
elif func == 'search_term_to_field_key':
|
elif func == 'search_term_to_field_key':
|
||||||
|
@ -11,6 +11,7 @@ import traceback, sys
|
|||||||
from threading import Lock, Condition, current_thread
|
from threading import Lock, Condition, current_thread
|
||||||
from calibre.utils.config_base import tweaks
|
from calibre.utils.config_base import tweaks
|
||||||
|
|
||||||
|
|
||||||
class LockingError(RuntimeError):
|
class LockingError(RuntimeError):
|
||||||
|
|
||||||
is_locking_error = True
|
is_locking_error = True
|
||||||
@ -19,9 +20,11 @@ class LockingError(RuntimeError):
|
|||||||
RuntimeError.__init__(self, msg)
|
RuntimeError.__init__(self, msg)
|
||||||
self.locking_debug_msg = extra
|
self.locking_debug_msg = extra
|
||||||
|
|
||||||
|
|
||||||
class DowngradeLockError(LockingError):
|
class DowngradeLockError(LockingError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def create_locks():
|
def create_locks():
|
||||||
'''
|
'''
|
||||||
Return a pair of locks: (read_lock, write_lock)
|
Return a pair of locks: (read_lock, write_lock)
|
||||||
@ -48,6 +51,7 @@ def create_locks():
|
|||||||
wrapper = DebugRWLockWrapper if tweaks.get('newdb_debug_locking', False) else RWLockWrapper
|
wrapper = DebugRWLockWrapper if tweaks.get('newdb_debug_locking', False) else RWLockWrapper
|
||||||
return wrapper(l), wrapper(l, is_shared=False)
|
return wrapper(l), wrapper(l, is_shared=False)
|
||||||
|
|
||||||
|
|
||||||
class SHLock(object): # {{{
|
class SHLock(object): # {{{
|
||||||
'''
|
'''
|
||||||
Shareable lock class. Used to implement the Multiple readers-single writer
|
Shareable lock class. Used to implement the Multiple readers-single writer
|
||||||
@ -207,6 +211,7 @@ class SHLock(object): # {{{
|
|||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
|
|
||||||
class RWLockWrapper(object):
|
class RWLockWrapper(object):
|
||||||
|
|
||||||
def __init__(self, shlock, is_shared=True):
|
def __init__(self, shlock, is_shared=True):
|
||||||
@ -225,6 +230,7 @@ class RWLockWrapper(object):
|
|||||||
def owns_lock(self):
|
def owns_lock(self):
|
||||||
return self._shlock.owns_lock()
|
return self._shlock.owns_lock()
|
||||||
|
|
||||||
|
|
||||||
class DebugRWLockWrapper(RWLockWrapper):
|
class DebugRWLockWrapper(RWLockWrapper):
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
@ -249,6 +255,7 @@ class DebugRWLockWrapper(RWLockWrapper):
|
|||||||
__enter__ = acquire
|
__enter__ = acquire
|
||||||
__exit__ = release
|
__exit__ = release
|
||||||
|
|
||||||
|
|
||||||
class SafeReadLock(object):
|
class SafeReadLock(object):
|
||||||
|
|
||||||
def __init__(self, read_lock):
|
def __init__(self, read_lock):
|
||||||
|
@ -22,6 +22,7 @@ NON_EBOOK_EXTENSIONS = frozenset([
|
|||||||
'opf', 'swp', 'swo'
|
'opf', 'swp', 'swo'
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
class Restorer(Cache):
|
class Restorer(Cache):
|
||||||
|
|
||||||
def __init__(self, library_path, default_prefs=None, restore_all_prefs=False, progress_callback=lambda x, y:True):
|
def __init__(self, library_path, default_prefs=None, restore_all_prefs=False, progress_callback=lambda x, y:True):
|
||||||
@ -35,6 +36,7 @@ class Restorer(Cache):
|
|||||||
def no_op(self, *args, **kwargs):
|
def no_op(self, *args, **kwargs):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class Restore(Thread):
|
class Restore(Thread):
|
||||||
|
|
||||||
def __init__(self, library_path, progress_callback=None):
|
def __init__(self, library_path, progress_callback=None):
|
||||||
|
@ -12,6 +12,7 @@ import os
|
|||||||
from calibre import prints
|
from calibre import prints
|
||||||
from calibre.utils.date import isoformat, DEFAULT_DATE
|
from calibre.utils.date import isoformat, DEFAULT_DATE
|
||||||
|
|
||||||
|
|
||||||
class SchemaUpgrade(object):
|
class SchemaUpgrade(object):
|
||||||
|
|
||||||
def __init__(self, db, library_path, field_metadata):
|
def __init__(self, db, library_path, field_metadata):
|
||||||
@ -421,6 +422,7 @@ class SchemaUpgrade(object):
|
|||||||
'Cache has_cover'
|
'Cache has_cover'
|
||||||
self.db.execute('ALTER TABLE books ADD COLUMN has_cover BOOL DEFAULT 0')
|
self.db.execute('ALTER TABLE books ADD COLUMN has_cover BOOL DEFAULT 0')
|
||||||
data = self.db.get('SELECT id,path FROM books', all=True)
|
data = self.db.get('SELECT id,path FROM books', all=True)
|
||||||
|
|
||||||
def has_cover(path):
|
def has_cover(path):
|
||||||
if path:
|
if path:
|
||||||
path = os.path.join(self.library_path, path.replace('/', os.sep),
|
path = os.path.join(self.library_path, path.replace('/', os.sep),
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user