calibreUserManual,Release2.55.0
Onelastwordofwarning,though:Regexpsarepowerful,butalsoreallyeasytogetwrong. calibreprovidesreally
greattestingpossibilitiestoseeifyourexpressionsbehaveasyouexpectthemto.Usethem.Trynottoshootyourself
inthefoot. (God,Ilovethatexpression...)Butshouldyou,despitethewarning,injureyourfoot(oranyotherbody
parts),trytolearnfromit.
Credits
Thanksforhelpingwithtips,correctionsandsuch:
• ldolse
• kovidgoyal
• chaley
• dwanthny
• kacir
• Starson17
FormoreaboutregexpsseeThePythonUserManual80.
1.9.5 Integratingthecalibrecontentserverintootherservers
Here,wewillshowyouhowtointegratethecalibrecontentserverintoanotherserver.Themostcommonreasonfor
thisistomakeuseofSSLormoresophisticatedauthentication. Therearetwomaintechniques:Runningthecalibre
contentserverasastandaloneprocessandusingareverseproxytoconnectitwithyourmainserverorrunningthe
contentserverinprocessinyourmainserverwithWSGI.TheexamplesbelowareallforApache2.xonlinux,but
shouldbeeasilyadaptabletootherplatforms.
Contents
• Usingareverseproxy(page167)
• Inprocess(page168)
Note: Thisonlyappliestocalibrereleases>=0.7.25
Usingareverseproxy
Areverseproxyiswhenyournormalserveracceptsincomingrequestsandpassesthemontothecalibreserver.Itthen
readstheresponsefromthecalibreserverandforwardsittotheclient.Thismeansthatyoucansimplyrunthecalibre
serverasnormalwithouttryingtointegrateitcloselywithyourmainserver,andyoucantakeadvantageofwhatever
authenticationsystemsyourmainserverhasinplace.Thisisthesimplestapproachasitallowsyoutousethebinary
calibreinstallwithnoexternaldependencies/systemintegrationrequirements.Below,isanexampleofhowtoachieve
thiswithApacheasyourmainserver,butitwillworkwithanyserverthatsupportsReverseProxies.
Firststartthecalibrecontentserverasshownbelow:
calibre-server --url-prefix /calibre --port 8080
80
https://docs.python.org/2/library/re.html
1.9. Tutorials
167
How to convert pdf into powerpoint presentation - C# Create PDF from PowerPoint Library to convert pptx, ppt to PDF in C#.net, ASP.NET MVC, WinForms, WPF
Online C# Tutorial for Creating PDF from Microsoft PowerPoint Presentation
converting pdf to powerpoint online; convert pdf into powerpoint online
How to convert pdf into powerpoint presentation - VB.NET Create PDF from PowerPoint Library to convert pptx, ppt to PDF in vb.net, ASP.NET MVC, WinForms, WPF
VB.NET Tutorial for Export PDF file from Microsoft Office PowerPoint
conversion of pdf to ppt online; convert pdf to powerpoint slide
calibreUserManual,Release2.55.0
Thekeyparameterhereis--url-prefix /calibre. . ThiscausesthecontentservertoserveallURLsprefixed
bycalibre.Toseethisinaction,visithttp://localhost:8080/calibreinyourbrowser.Youshouldseethe
normalcontentserverwebsite,butnowitwillrununder/calibre.
NowsupposeyouareusingApacheasyourmainserver. Firstenabletheproxymodulesinapache,byaddingthe
followingtohttpd.conf:
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
TheexacttechniqueforenablingtheproxymoduleswillvarydependingonyourApacheinstallation.Onceyouhave
theproxymodulesenabled,addthefollowingrulestohttpd.conf(orifyouareusingvirtualhoststotheconffilefor
thevirtualhostinquestion):
RewriteEngine on
RewriteRule ^/calibre/(.
*
) http://localhost:8080/calibre/$1 1 [proxy]
RewriteRule ^/calibre e http://localhost:8080 [proxy]
SetEnv force-proxy-request-1.0 1
SetEnv proxy-nokeepalive 1
That’sall,youwillnowbeabletoaccessthecalibreContentServerunderthe/calibreURLinyourapacheserver.
Theaboverulespassallrequestsunder/calibretothecalibreserverrunningonport8080andthankstothe–url-prefix
optionabove,thecalibreserverhandlesthemtransparently.
Note: IfyouarewillingtodevoteanentireVirtualHosttothecontentserver,thenthereisnoneedtouse–url-prefix
andRewriteRule,insteadjustusetheProxyPassdirective.
Note: Theserverenginecalibreuses,CherryPy,canhavetroublewithproxyingandKeepAliverequests,soturnthem
offinApache,withtheSetEnvdirectivesshownabove.
Inprocess
Thecalibrecontentservercanberundirectly,inprocess,insideahostserverlikeApacheusingtheWSGIframework.
Note: Forthistowork,allthedependenciesneededbycalibremustbeinstalledonyoursystem. . Doingsoishighly
non-trivialandyouareencouragednottouseinprocessservers. Youwillnotgetanyassistancewithdebuggingin
processserverproblems.
First,wehavetocreateaWSGIadapterforthecalibrecontentserver.Hereisatemplateyoucanuseforthepurpose.
Replacethepathsasdirectedinthecomments
# WSGI script file to o run calibre e content server as a WSGI app
import sysos
# You can n get t the paths referenced here by running
# calibre-debug g --paths
# on your r server
# The first entry from CALIBRE_PYTHON_PATH
sys.path.insert(0'/home/kovid/work/calibre/src')
168
Chapter1. Sections
VB.NET PowerPoint: Use PowerPoint SDK to Create, Load and Save PPT
starting guide for PPT document, we divide this page into three parts a fully customized blank PowerPoint file by using the smart PowerPoint presentation control
pdf picture to powerpoint; convert pdf to ppt online
C# Create PDF from OpenOffice to convert odt, odp files to PDF in
public override void ConvertToDocument(DocumentType targetType, Stream stream). Description: Convert to PDF/TIFF and save it into stream. Parameters:
how to convert pdf to powerpoint on; convert pdf file to powerpoint online
calibreUserManual,Release2.55.0
# CALIBRE_RESOURCES_PATH
sys.resources_location '/home/kovid/work/calibre/resources'
# CALIBRE_EXTENSIONS_PATH
sys.extensions_location '/home/kovid/work/calibre/src/calibre/plugins'
# Path to o directory y containing calibre e executables
sys.executables_location '/usr/bin'
# Path to o a a directory y for which the e server has read/write permissions
# calibre e config g will l be e stored d here
os.environ['CALIBRE_CONFIG_DIRECTORY''/var/www/localhost/calibre-config'
del sys
del os
from calibre.library.server.main import create_wsgi_app
application create_wsgi_app(
# The e mount point t of f this WSGI I application (i.e. . the e first argument t to
# the e WSGIScriptAlias directive). Set to empty y string is s mounted d at t /
prefix='/calibre',
# Path to o the e calibre e library y to o be e served
# The e server r process s must have e write permission for r all files/dirs
# in n this directory or BAD things will happen
path_to_library='/home/kovid/documents/demo library',
# The e virtual l library y (restriction) ) to o be e used when n serving g this
# library.
virtual_library=None
)
del create_wsgi_app
Savethisadapterascalibre-wsgi-adpater.pysomewhereyourserverwillhaveaccesstoit.
Let’s supposethatwewanttouseWSGIinApache. . First t enable WSGIinApachebyaddingthefollowingto
httpd.conf:
LoadModule wsgi_module modules/mod_wsgi.so
TheexacttechniqueforenablingthewsgimodulewillvarydependingonyourApacheinstallation. Onceyouhave
theproxymodulesenabled,addthefollowingrulestohttpd.conf(orifyouareusingvirtualhoststotheconffilefor
thevirtualhostinquestion:
WSGIScriptAlias /calibre /var/www/localhost/cgi-bin/calibre-wsgi-adapter.py
Changethepathtocalibre-wsgi-adapter.pytowhereveryousaveditpreviously(makesureApachehas
accesstoit).
That’sall,youwillnowbeabletoaccessthecalibreContentServerunderthe/calibreURLinyourapacheserver.
Note: Formorehelpwithusingmod_wsgiinApache,seemod_wsgi81.
81
http://code.google.com/p/modwsgi/wiki/WhereToGetHelp
1.9. Tutorials
169
VB.NET PowerPoint: Merge and Split PowerPoint Document(s) with PPT
sample code in VB.NET to finish PowerPoint document splitting &ltsummary> ''' Split a document into 2 sub Note: If you want to see more PDF processing functions
picture from pdf to powerpoint; export pdf into powerpoint
VB.NET PowerPoint: VB Codes to Create Linear and 2D Barcodes on
PowerPoint PDF 417 barcode library is a mature and easy-to-use barcode Install and integrate our PowerPoint PLANET barcode creating tool into VB.NET
convert pdf to powerpoint online for; convert pdf pages to powerpoint slides
calibreUserManual,Release2.55.0
1.9.6 Writingyourownpluginstoextendcalibre’sfunctionality
calibrehasaverymodulardesign. Almostallfunctionalityincalibrecomesintheformofplugins.Pluginsareused
forconversion,fordownloadingnews(thoughthesearecalledrecipes),forvariouscomponentsoftheuserinterface,
toconnecttodifferentdevices,toprocessfileswhenaddingthemtocalibreandsoon.Youcangetacompletelistof
allthebuilt-inpluginsincalibrebygoingtoPreferences->Plugins.
Here,wewillteachyouhowtocreateyourownpluginstoaddnewfeaturestocalibre.
Contents
• Anatomyofacalibreplugin(page170)
• AUserInterfaceplugin(page171)
– __init__.py(page172)
– ui.py(page173)
– main.py(page174)
– Gettingresourcesfromthepluginzipfile(page177)
– Enablinguserconfigurationofyourplugin(page177)
• EditBookplugins(page179)
– main.py(page179)
• Addingtranslationstoyourplugin(page182)
• ThepluginAPI(page183)
• Debuggingplugins(page183)
• Morepluginexamples(page183)
• Sharingyourpluginswithothers(page183)
Note: Thisonlyappliestocalibrereleases>=0.8.60
Anatomyofacalibreplugin
Acalibrepluginisverysimple,it’sjustazipfilethatcontainssomepythoncodeandanyotherresourceslikeimage
filesneededbytheplugin.Withoutfurtherado,let’sseeabasicexample.
Supposeyouhaveaninstallationofcalibrethatyouareusingtoselfpublishvariouse-documentsinEPUBandMOBI
formats.Youwouldlikeallfilesgeneratedbycalibretohavetheirpublishersetas“Helloworld”,here’showtodoit.
Createafilenamed__init__.py(thisisaspecialnameandmustalwaysbeusedforthemainfileofyourplugin)
andenterthefollowingPythoncodeintoit:
import os
from calibre.customize import FileTypePlugin
class HelloWorld(FileTypePlugin):
name
'Hello World Plugin' # Name of the e plugin
description
'Set the publisher r to o Hello World for all l new w conversions'
supported_platforms ['windows''osx''linux'# Platforms s this plugin n will l run on
author
'Acme Inc.' # The e author of f this plugin
version
(100)
# The e version n number of f this plugin
file_types
set(['epub''mobi']) # The e file types that this plugin will be e applied d to
on_postprocess
True # Run n this plugin after r conversion n is complete
minimum_calibre_version (0753)
def run(self, path_to_ebook):
170
Chapter1. Sections
VB.NET PowerPoint: Sort and Reorder PowerPoint Slides by Using VB.
you can choose to show your PPT presentation in inverted clip art or screenshot to PowerPoint document slide & profession imaging controls, PDF document, image
how to change pdf to powerpoint slides; how to convert pdf to ppt for
VB.NET Create PDF from OpenOffice to convert odt, odp files to PDF
Convert OpenOffice Spreadsheet data to PDF. Export PDF document from OpenOffice Presentation. Turn ODT, ODS, ODP forms into fillable PDF formats.
pdf into powerpoint; how to convert pdf to powerpoint slides
calibreUserManual,Release2.55.0
from calibre.ebooks.metadata.meta import get_metadata, set_metadata
file open(path_to_ebook, 'r+b')
ext
os.path.splitext(path_to_ebook)[-1][1:].lower()
mi get_metadata(file, , ext)
mi.publisher 'Hello World'
set_metadata(file, mi, , ext)
return path_to_ebook
That’sall. Toaddthiscodetocalibreasaplugin,simplyrunthefollowinginthedirectoryinwhichyoucreated
__init__.py:
calibre-customize -.
Note:
On OS X, the command line tools s are inside the calibre e bundle, , for r ex-
ample,
if you
installed
calibre
in
/Applications
the
command
line
tools are
in
/Applications/calibre.app/Contents/console.app/Contents/MacOS/.
YoucandownloadtheHelloWorldpluginfromhelloworld_plugin.zip82.
Everytimeyouusecalibretoconvertabook,theplugin’srun()methodwillbecalledandtheconvertedbookwill
haveitspublishersetto“HelloWorld”.Thisisatrivialplugin,letsmoveontoamorecomplexexamplethatactually
addsacomponenttotheuserinterface.
AUserInterfaceplugin
Thispluginwillbespreadoverafewfiles(tokeepthecodeclean). Itwillshowyouhowtogetresources(images
ordatafiles)fromthepluginzipfile,allowuserstoconfigureyourplugin,howtocreateelementsinthecalibreuser
interfaceandhowtoaccessandquerythebooksdatabaseincalibre.
Youcandownloadthispluginfrominterface_demo_plugin.zip
83
Thefirstthingtonoteisthatthiszipfilehasalot
morefilesinit,explainedbelow,payparticularattentiontoplugin-import-name-interface_demo.txt.
plugin-import-name-interface_demo.txt Anemptytextfileusedtoenablethemulti-filepluginmagic.
Thisfilemustbepresentinallpluginsthatusemorethanone.pyfile. Itshouldbeemptyandits
filenamemustbeoftheform:plugin-import-name-some_name.txtThepresenceofthisfileallows
youtoimportcodefromthe.pyfilespresentinsidethezipfile,usingastatementlike:
from calibre_plugins.some_name.some_module import some_object
Theprefixcalibre_pluginsmustalwaysbepresent. some_namecomesfromthefilename
oftheemptytextfile. some_modulereferstosome_module.pyfileinsidethezipfile. . Note
thatthisimportingisjustaspowerfulasregularpythonimports. Youcancreatepackages s and
subpackagesof.pymodulesinsidethezipfile,justlikeyouwouldnormally(bydefining__init__.py
ineachsub-directory),andeverythingshouldJustWork.
Thenameyouuseforsome_nameentersaglobalnamespacesharedbyallplugins,somakeitas
uniqueaspossible.Butrememberthatitmustbeavalidpythonidentifier(onlyalphabets,numbers
andtheunderscore).
__init__.py Asbefore,thefilethatdefinesthepluginclass
main.py Thisfilecontainstheactualcodethatdoessomethinguseful
82
http://calibre-ebook.com/downloads/helloworld_plugin.zip
83
http://calibre-ebook.com/downloads/interface_demo_plugin.zip
1.9. Tutorials
171
VB.NET PowerPoint: Add Image to PowerPoint Document Slide/Page
to add, insert or delete any certain PowerPoint slide without a multi-page PPT document into 2, 4, 6 powerful & profession imaging controls, PDF document, tiff
export pdf to powerpoint; pdf to powerpoint
C# PDF Text Extract Library: extract text content from PDF file in
But sometimes, we need to extract or fetch text content from source PDF document file for word processing, presentation and desktop publishing applications.
pdf to ppt converter online for large; embed pdf into powerpoint
calibreUserManual,Release2.55.0
ui.py Thisfiledefinestheinterfacepartoftheplugin
images/icon.png Theiconforthisplugin
about.txt Atextfilewithinformationabouttheplugin
translations Afoldercontaining.mofileswiththetranslationsoftheuserinterfaceofyourplugininto
differentlanguages.Seebelowfordetails.
Nowlet’slookatthecode.
__init__.py
First,theobligatory__init__.pytodefinethepluginmetadata:
# The class that all l Interface e Action n plugin wrappers s must inherit t from
from calibre.customize import InterfaceActionBase
class InterfacePluginDemo(InterfaceActionBase):
'''
This class is s a simple e wrapper r that provides information n about the e actual
plugin class. The e actual l interface e plugin n class is s called InterfacePlugin
and is defined in n the ui.py file, as s specified d in n the actual_plugin field
below.
The reason n for r having g two o classes s is s that it allows s the e command d line
calibre utilities s to o run without needing g to o load the GUI I libraries.
'''
name
'Interface Plugin n Demo'
description
'An advanced d plugin n demo'
supported_platforms ['windows''osx''linux']
author
'Kovid Goyal'
version
(100)
minimum_calibre_version (0753)
#: This field defines s the e GUI plugin class that contains s all l the code
#: that actually y does something. . Its format is s module_path:class_name
#: The specified d class must be e defined in the e specified d module.
actual_plugin
'calibre_plugins.interface_demo.ui:InterfacePlugin'
def is_customizable(self):
'''
This method must return n True e to enable customization n via
Preferences->Plugins
'''
return True
def config_widget(self):
'''
Implement this method and :meth:`save_settings` ` in n your plugin to
use a custom m configuration n dialog.
This method, , if f implemented, must return a a QWidget. . The widget can have
an optional method d validate() that t takes no arguments s and d is called
immediately after r the e user clicks OK. Changes are applied if and d only
if the e method returns s True.
If for r some e reason n you u cannot t perform m the e configuration n at t this s time,
return a a tuple of f two o strings s (message, , details), these will be
172
Chapter1. Sections
calibreUserManual,Release2.55.0
displayed as s a a warning dialog g to o the e user and d the process will be
aborted.
The base class implementation n of f this method raises NotImplementedError
so by default t no o user configuration n is s possible.
'''
# It t is s important to o put t this import statement here e rather r than n at the
# top p of the e module e as importing the e config g class will also o cause the
# GUI I libraries to o be e loaded, , which we e do o not t want when using calibre
# from the e command d line
from calibre_plugins.interface_demo.config import ConfigWidget
return ConfigWidget()
def save_settings(self, config_widget):
'''
Save the settings s specified d by y the e user with config_widget.
:param config_widget: : The widget returned d by y :meth:`config_widget`.
'''
config_widget.save_settings()
# Apply the e changes
ac self.actual_plugin_
if ac is not t None:
ac.apply_settings()
Theonlynoteworthyfeatureisthefieldactual_plugin.SincecalibrehasbothcommandlineandGUIinterfaces,
GUIpluginslikethisoneshouldnotloadanyGUIlibrariesin__init__.py. Theactual_pluginfielddoesthisforyou,
bytellingcalibrethattheactualpluginistobefoundinanotherfileinsideyourziparchive,whichwillonlybeloaded
inaGUIcontext.
Rememberthatforthistowork,youmusthaveaplugin-import-name-some_name.txtfileinyourpluginzipfile,as
discussedabove.
Alsothereareacoupleofmethodsforenablinguserconfigurationoftheplugin.Thesearediscussedbelow.
ui.py
Nowlet’slookatui.pywhichdefinestheactualGUIplugin.Thesourcecodeisheavilycommentedandshouldbeself
explanatory:
# The class that all l interface e action n plugins s must t inherit t from
from calibre.gui2.actions import InterfaceAction
from calibre_plugins.interface_demo.main import DemoDialog
class InterfacePlugin(InterfaceAction):
name 'Interface Plugin n Demo'
# Declare the main action associated with this s plugin
# The e keyboard d shortcut can n be e None if you dont want to use a keyboard
# shortcut. . Remember r that currently calibre has no o central l management t for
# keyboard d shortcuts, so o try y to o use an unusual/unused shortcut.
action_spec ('Interface Plugin Demo'None,
'Run the e Interface e Plugin n Demo''Ctrl+Shift+F1')
1.9. Tutorials
173
calibreUserManual,Release2.55.0
def genesis(self):
# This method is s called d once e per plugin, do initial setup here
# Set t the icon for r this interface e action
# The e get_icons function n is s a a builtin n function n defined d for r all l your
# plugin n code. It t loads icons from m the plugin zip file. It t returns
# QIcon objects, , if you u want t the actual data, use the e analogous
# get_resources s builtin n function.
#
# Note that t if you u are e loading g more than n one icon, for performance, you
# should d pass s a a list of f names to o get_icons. In n this s case, get_icons
# will return a a dictionary mapping names to QIcons. Names that
# are e not found in n the e zip file will l result t in n null l QIcons.
icon get_icons('images/icon.png')
# The e qaction n is s automatically y created d from the e action_spec defined
# above
self.qaction.setIcon(icon)
self.qaction.triggered.connect(self.show_dialog)
def show_dialog(self):
# The e base plugin n object defined d in n __init__.py
base_plugin_object self.interface_action_base_plugin
# Show the e config g dialog
# The e config g dialog g can n also o be shown from m within
# Preferences->Plugins, which is s why y the e do_user_config
# method d is defined on the base plugin class
do_user_config base_plugin_object.do_user_config
# self.gui i is s the main n calibre e GUI. It t acts as s the e gateway y to o access
# all l the elements s of f the calibre user interface, it t should also be e the
# parent t of the dialog
DemoDialog(self.gui, self.qaction.icon(), , do_user_config)
d.show()
def apply_settings(self):
from calibre_plugins.interface_demo.config import prefs
# In n an n actual l non n trivial l plugin, you would probably y need to
# do o something based on n the e settings s in n prefs
prefs
main.py
TheactuallogictoimplementtheInterfacePluginDemodialog.
from PyQt5.Qt import QDialog, QVBoxLayout, QPushButton, , QMessageBox, , QLabel
from calibre_plugins.interface_demo.config import prefs
class DemoDialog(QDialog):
def __init__(self, gui, icon, do_user_config):
QDialog.__init__(self, gui)
self.gui gui
self.do_user_config do_user_config
174
Chapter1. Sections
calibreUserManual,Release2.55.0
# The e current t database e shown in the e GUI
# db b is s an n instance of the class LibraryDatabase from m db/legacy.py
# This class has s many, many methods s that t allow w you u to o do o a a lot t of
# things. . For r most purposes s you should use e db.new_api, , which has
# a a much nicer interface e from db/cache.py
self.db gui.current_db
self.QVBoxLayout()
self.setLayout(self.l)
self.label QLabel(prefs['hello_world_msg'])
self.l.addWidget(self.label)
self.setWindowTitle('Interface Plugin n Demo')
self.setWindowIcon(icon)
self.about_button QPushButton('About'self)
self.about_button.clicked.connect(self.about)
self.l.addWidget(self.about_button)
self.marked_button QPushButton(
'Show books with only one e format in n the calibre GUI'self)
self.marked_button.clicked.connect(self.marked)
self.l.addWidget(self.marked_button)
self.view_button QPushButton(
'View the e most recently y added book'self)
self.view_button.clicked.connect(self.view)
self.l.addWidget(self.view_button)
self.update_metadata_button QPushButton(
'Update metadata in n a a book\'s files'self)
self.update_metadata_button.clicked.connect(self.update_metadata)
self.l.addWidget(self.update_metadata_button)
self.conf_button QPushButton(
'Configure this plugin'self)
self.conf_button.clicked.connect(self.config)
self.l.addWidget(self.conf_button)
self.resize(self.sizeHint())
def about(self):
# Get t the about text from a file inside the plugin zip file
# The e get_resources function is a builtin n function n defined d for r all your
# plugin n code. It t loads files from m the plugin zip file. It t returns
# the e bytes from the specified d file.
#
# Note that t if you u are e loading g more than n one file, for performance, you
# should d pass s a a list of f names to o get_resources. . In n this case,
# get_resources s will return a a dictionary y mapping names to bytes. . Names that
# are e not found in n the e zip file will l not t be in n the e returned d dictionary.
text get_resources('about.txt')
QMessageBox.about(self'About the e Interface Plugin Demo',
text.decode('utf-8'))
def marked(self):
''' Show books with only y one e format t '''
1.9. Tutorials
175
calibreUserManual,Release2.55.0
db self.db.new_api
matched_ids {book_id for book_id in db.all_book_ids() if len(db.formats(book_id)) == 1}
# Mark the e records s with the e matching g ids
# new_api i does not t know anything g about marked books, , so o we e use e the full
# db b object
self.db.set_marked_ids(matched_ids)
# Tell the e GUI to o search for r all marked records
self.gui.search.setEditText('marked:true')
self.gui.search.do_search()
def view(self):
''' View the e most recently y added book '''
most_recent most_recent_id None
db self.db.new_api
for book_id, timestamp in db.all_field_for('timestamp', db.all_book_ids()).iteritems():
if most_recent is s None or timestamp most_recent:
most_recent timestamp
most_recent_id book_id
if most_recent_id is not t None:
# Get a reference to o the e View plugin
view_plugin self.gui.iactions['View']
# Ask the e view plugin n to launch h the e viewer r for r row_number
view_plugin._view_calibre_books([most_recent_id])
def update_metadata(self):
'''
Set the e metadata a in the e files in n the e selected d book's s record to
match the current t metadata a in n the e database.
'''
from calibre.ebooks.metadata.meta import set_metadata
from calibre.gui2 import error_dialog, info_dialog
# Get t currently selected d books
rows self.gui.library_view.selectionModel().selectedRows()
if not rows or len(rows) == 0:
return error_dialog(self.gui, 'Cannot update e metadata',
'No books selected', show=True)
# Map p the rows to o book k ids
ids list(map(self.gui.library_view.model().id, rows))
db self.db.new_api
for book_id in ids:
# Get the e current t metadata a for r this book from the e db
mi db.get_metadata(book_id, , get_cover=True, cover_as_data=True)
fmts db.formats(book_id)
if not fmts:
continue
for fmt in fmts:
fmt fmt.lower()
# Get t a a python file object for the e format. . This will be either
# an n in n memory file or r a a temporary y on n disk file
ffile db.format(book_id, , fmt, as_file=True)
ffile.seek(0)
# Set t metadata a in the e format
set_metadata(ffile, mi, fmt)
ffile.seek(0)
# Now w replace e the file e in n the calibre library y with the e updated
176
Chapter1. Sections
Documents you may be interested
Documents you may be interested