mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Fix #1247 (Can't set rating in the main window)
This commit is contained in:
parent
9ac26ded49
commit
e6a5517cea
@ -313,6 +313,7 @@ def convert(htmlfile, opts, notification=None):
|
|||||||
logger.info('Output written to %s'%opts.output)
|
logger.info('Output written to %s'%opts.output)
|
||||||
if opts.extract_to is not None:
|
if opts.extract_to is not None:
|
||||||
epub.extractall(opts.extract_to)
|
epub.extractall(opts.extract_to)
|
||||||
|
epub.close()
|
||||||
|
|
||||||
|
|
||||||
def main(args=sys.argv):
|
def main(args=sys.argv):
|
||||||
|
@ -250,7 +250,7 @@ class MetaInformation(object):
|
|||||||
ans += u'Title : ' + unicode(self.title) + u'\n'
|
ans += u'Title : ' + unicode(self.title) + u'\n'
|
||||||
if self.authors:
|
if self.authors:
|
||||||
ans += u'Author : ' + (', '.join(self.authors) if self.authors is not None else u'None')
|
ans += u'Author : ' + (', '.join(self.authors) if self.authors is not None else u'None')
|
||||||
ans += ((' (' + self.author_sort + ')') if self.author_sort else '') + u'\n'
|
ans += ((' [' + self.author_sort + ']') if self.author_sort else '') + u'\n'
|
||||||
if self.publisher:
|
if self.publisher:
|
||||||
ans += u'Publisher: '+ unicode(self.publisher) + u'\n'
|
ans += u'Publisher: '+ unicode(self.publisher) + u'\n'
|
||||||
if self.book_producer:
|
if self.book_producer:
|
||||||
|
@ -16,7 +16,7 @@ from calibre.ebooks.metadata.epub import get_metadata as epub_metadata
|
|||||||
from calibre.ebooks.metadata.html import get_metadata as html_metadata
|
from calibre.ebooks.metadata.html import get_metadata as html_metadata
|
||||||
from calibre.ebooks.mobi.reader import get_metadata as mobi_metadata
|
from calibre.ebooks.mobi.reader import get_metadata as mobi_metadata
|
||||||
from calibre.ebooks.metadata.odt import get_metadata as odt_metadata
|
from calibre.ebooks.metadata.odt import get_metadata as odt_metadata
|
||||||
from calibre.ebooks.metadata.opf import OPFReader
|
from calibre.ebooks.metadata.opf2 import OPF
|
||||||
from calibre.ebooks.metadata.rtf import set_metadata as set_rtf_metadata
|
from calibre.ebooks.metadata.rtf import set_metadata as set_rtf_metadata
|
||||||
from calibre.ebooks.lrf.meta import set_metadata as set_lrf_metadata
|
from calibre.ebooks.lrf.meta import set_metadata as set_lrf_metadata
|
||||||
from calibre.ebooks.metadata.epub import set_metadata as set_epub_metadata
|
from calibre.ebooks.metadata.epub import set_metadata as set_epub_metadata
|
||||||
@ -174,13 +174,13 @@ def metadata_from_filename(name, pat=None):
|
|||||||
def opf_metadata(opfpath):
|
def opf_metadata(opfpath):
|
||||||
if hasattr(opfpath, 'read'):
|
if hasattr(opfpath, 'read'):
|
||||||
f = opfpath
|
f = opfpath
|
||||||
opfpath = getattr(f, 'name', '')
|
opfpath = getattr(f, 'name', os.getcwd())
|
||||||
else:
|
else:
|
||||||
f = open(opfpath, 'rb')
|
f = open(opfpath, 'rb')
|
||||||
try:
|
try:
|
||||||
opf = OPFReader(f, os.path.dirname(opfpath))
|
opf = OPF(f, os.path.dirname(opfpath))
|
||||||
if opf.application_id is not None:
|
if opf.application_id is not None:
|
||||||
mi = MetaInformation(opf, None)
|
mi = MetaInformation(opf)
|
||||||
if hasattr(opf, 'cover') and opf.cover:
|
if hasattr(opf, 'cover') and opf.cover:
|
||||||
cpath = os.path.join(os.path.dirname(opfpath), opf.cover)
|
cpath = os.path.join(os.path.dirname(opfpath), opf.cover)
|
||||||
if os.access(cpath, os.R_OK):
|
if os.access(cpath, os.R_OK):
|
||||||
@ -189,4 +189,6 @@ def opf_metadata(opfpath):
|
|||||||
mi.cover_data = (fmt, data)
|
mi.cover_data = (fmt, data)
|
||||||
return mi
|
return mi
|
||||||
except:
|
except:
|
||||||
|
import traceback
|
||||||
|
traceback.print_exc()
|
||||||
pass
|
pass
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
>
|
>
|
||||||
<metadata xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:opf="http://www.idpf.org/2007/opf">
|
<metadata xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:opf="http://www.idpf.org/2007/opf">
|
||||||
<dc:title py:with="attrs={'opf:files-as':mi.title_sort}" py:attrs="attrs">${mi.title}</dc:title>
|
<dc:title py:with="attrs={'opf:files-as':mi.title_sort}" py:attrs="attrs">${mi.title}</dc:title>
|
||||||
<dc:creator opf:role="aut" py:for="i, author in enumerate(mi.authors)" py:with="attrs={'opf:file-as':mi.author_sort if i==0 else None}" py:attrs="attrs">${author}</dc:creator>
|
<dc:creator opf:role="aut" py:for="i, author in enumerate(mi.authors)" py:attrs="{'opf:file-as':mi.author_sort} if mi.author_sort and i == 0 else {}">${author}</dc:creator>
|
||||||
<dc:contributor opf:role="bkp" py:with="attrs={'opf:files-as':__appname__}" py:attrs="attrs">${'%s (%s)'%(__appname__, __version__)} [http://${__appname__}.kovidgoyal.net]</dc:contributor>
|
<dc:contributor opf:role="bkp" py:with="attrs={'opf:files-as':__appname__}" py:attrs="attrs">${'%s (%s)'%(__appname__, __version__)} [http://${__appname__}.kovidgoyal.net]</dc:contributor>
|
||||||
<dc:identifier opf:scheme="${__appname__}" id="${__appname__}_id">${mi.application_id}</dc:identifier>
|
<dc:identifier opf:scheme="${__appname__}" id="${__appname__}_id">${mi.application_id}</dc:identifier>
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ __docformat__ = 'restructuredtext en'
|
|||||||
lxml based OPF parser.
|
lxml based OPF parser.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import sys, unittest, functools, os, mimetypes, uuid, glob
|
import sys, unittest, functools, os, mimetypes, uuid, glob, cStringIO
|
||||||
from urllib import unquote
|
from urllib import unquote
|
||||||
from urlparse import urlparse
|
from urlparse import urlparse
|
||||||
|
|
||||||
@ -17,7 +17,7 @@ from calibre.ebooks.chardet import xml_to_unicode
|
|||||||
from calibre import relpath
|
from calibre import relpath
|
||||||
from calibre.constants import __appname__, __version__
|
from calibre.constants import __appname__, __version__
|
||||||
from calibre.ebooks.metadata.toc import TOC
|
from calibre.ebooks.metadata.toc import TOC
|
||||||
from calibre.ebooks.metadata import MetaInformation
|
from calibre.ebooks.metadata import MetaInformation, get_parser
|
||||||
|
|
||||||
|
|
||||||
class Resource(object):
|
class Resource(object):
|
||||||
@ -418,6 +418,8 @@ class OPF(object):
|
|||||||
tags_path = XPath('descendant::*[re:match(name(), "subject", "i")]')
|
tags_path = XPath('descendant::*[re:match(name(), "subject", "i")]')
|
||||||
isbn_path = XPath('descendant::*[re:match(name(), "identifier", "i") and '+
|
isbn_path = XPath('descendant::*[re:match(name(), "identifier", "i") and '+
|
||||||
'(re:match(@scheme, "isbn", "i") or re:match(@opf:scheme, "isbn", "i"))]')
|
'(re:match(@scheme, "isbn", "i") or re:match(@opf:scheme, "isbn", "i"))]')
|
||||||
|
application_id_path= XPath('descendant::*[re:match(name(), "identifier", "i") and '+
|
||||||
|
'(re:match(@opf:scheme, "calibre|libprs500", "i") or re:match(@scheme, "calibre|libprs500", "i"))]')
|
||||||
manifest_path = XPath('descendant::*[re:match(name(), "manifest", "i")]/*[re:match(name(), "item", "i")]')
|
manifest_path = XPath('descendant::*[re:match(name(), "manifest", "i")]/*[re:match(name(), "item", "i")]')
|
||||||
manifest_ppath = XPath('descendant::*[re:match(name(), "manifest", "i")]')
|
manifest_ppath = XPath('descendant::*[re:match(name(), "manifest", "i")]')
|
||||||
spine_path = XPath('descendant::*[re:match(name(), "spine", "i")]/*[re:match(name(), "itemref", "i")]')
|
spine_path = XPath('descendant::*[re:match(name(), "spine", "i")]/*[re:match(name(), "itemref", "i")]')
|
||||||
@ -619,8 +621,12 @@ class OPF(object):
|
|||||||
def fget(self):
|
def fget(self):
|
||||||
matches = self.authors_path(self.metadata)
|
matches = self.authors_path(self.metadata)
|
||||||
if matches:
|
if matches:
|
||||||
ans = matches[0].get('opf:file-as', None)
|
for match in matches:
|
||||||
return ans if ans else matches[0].get('file-as', None)
|
ans = match.get('{%s}file-as'%self.NAMESPACES['opf'], None)
|
||||||
|
if not ans:
|
||||||
|
ans = match.get('file-as', None)
|
||||||
|
if ans:
|
||||||
|
return ans
|
||||||
|
|
||||||
def fset(self, val):
|
def fset(self, val):
|
||||||
matches = self.authors_path(self.metadata)
|
matches = self.authors_path(self.metadata)
|
||||||
@ -663,6 +669,23 @@ class OPF(object):
|
|||||||
|
|
||||||
return property(fget=fget, fset=fset)
|
return property(fget=fget, fset=fset)
|
||||||
|
|
||||||
|
@apply
|
||||||
|
def application_id():
|
||||||
|
|
||||||
|
def fget(self):
|
||||||
|
for match in self.application_id_path(self.metadata):
|
||||||
|
return match.text if match.text else None
|
||||||
|
|
||||||
|
def fset(self, val):
|
||||||
|
matches = self.application_id_path(self.metadata)
|
||||||
|
if not matches:
|
||||||
|
matches = [self.create_metadata_element('identifier', ns='dc',
|
||||||
|
attrib={'{%s}scheme'%self.NAMESPACES['opf']:'calibre'})]
|
||||||
|
matches[0].text = unicode(val)
|
||||||
|
|
||||||
|
return property(fget=fget, fset=fset)
|
||||||
|
|
||||||
|
|
||||||
@apply
|
@apply
|
||||||
def series():
|
def series():
|
||||||
|
|
||||||
@ -911,5 +934,49 @@ def suite():
|
|||||||
def test():
|
def test():
|
||||||
unittest.TextTestRunner(verbosity=2).run(suite())
|
unittest.TextTestRunner(verbosity=2).run(suite())
|
||||||
|
|
||||||
|
def option_parser():
|
||||||
|
return get_parser('opf')
|
||||||
|
|
||||||
|
def main(args=sys.argv):
|
||||||
|
parser = option_parser()
|
||||||
|
opts, args = parser.parse_args(args)
|
||||||
|
if len(args) != 2:
|
||||||
|
parser.print_help()
|
||||||
|
return 1
|
||||||
|
opfpath = os.path.abspath(args[1])
|
||||||
|
basedir = os.path.dirname(opfpath)
|
||||||
|
mi = MetaInformation(OPF(open(opfpath, 'rb'), basedir))
|
||||||
|
write = False
|
||||||
|
if opts.title is not None:
|
||||||
|
mi.title = opts.title
|
||||||
|
write = True
|
||||||
|
if opts.authors is not None:
|
||||||
|
aus = [i.strip() for i in opts.authors.split(',')]
|
||||||
|
mi.authors = aus
|
||||||
|
write = True
|
||||||
|
if opts.category is not None:
|
||||||
|
mi.category = opts.category
|
||||||
|
write = True
|
||||||
|
if opts.comment is not None:
|
||||||
|
mi.comments = opts.comment
|
||||||
|
write = True
|
||||||
|
if write:
|
||||||
|
mo = OPFCreator(basedir, mi)
|
||||||
|
ncx = cStringIO.StringIO()
|
||||||
|
mo.render(open(args[1], 'wb'), ncx)
|
||||||
|
ncx = ncx.getvalue()
|
||||||
|
if ncx:
|
||||||
|
f = glob.glob(os.path.join(os.path.dirname(args[1]), '*.ncx'))
|
||||||
|
if f:
|
||||||
|
f = open(f[0], 'wb')
|
||||||
|
else:
|
||||||
|
f = open(os.path.splitext(args[1])[0]+'.ncx', 'wb')
|
||||||
|
f.write(ncx)
|
||||||
|
f.close()
|
||||||
|
print MetaInformation(OPF(open(opfpath, 'rb'), basedir))
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
sys.exit(test())
|
sys.exit(test())
|
@ -479,10 +479,10 @@ class BooksModel(QAbstractTableModel):
|
|||||||
return False
|
return False
|
||||||
val = unicode(value.toString().toUtf8(), 'utf-8').strip() if column != 'rating' else \
|
val = unicode(value.toString().toUtf8(), 'utf-8').strip() if column != 'rating' else \
|
||||||
int(value.toInt()[0])
|
int(value.toInt()[0])
|
||||||
if col == 'rating':
|
if column == 'rating':
|
||||||
val = 0 if val < 0 else 5 if val > 5 else val
|
val = 0 if val < 0 else 5 if val > 5 else val
|
||||||
val *= 2
|
val *= 2
|
||||||
if col == 'series':
|
if column == 'series':
|
||||||
pat = re.compile(r'\[(\d+)\]')
|
pat = re.compile(r'\[(\d+)\]')
|
||||||
match = pat.search(val)
|
match = pat.search(val)
|
||||||
id = self.db.id(row)
|
id = self.db.id(row)
|
||||||
|
@ -242,7 +242,7 @@ class LibraryServer(object):
|
|||||||
' Feeds to read calibre books on a ipod with stanza.'
|
' Feeds to read calibre books on a ipod with stanza.'
|
||||||
books = []
|
books = []
|
||||||
for record in iter(self.db):
|
for record in iter(self.db):
|
||||||
if 'EPUB' in record['formats'].upper():
|
if 'EPUB' in record[FIELD_MAP['formats']].upper():
|
||||||
authors = ' & '.join([i.replace('|', ',') for i in record[2].split(',')])
|
authors = ' & '.join([i.replace('|', ',') for i in record[2].split(',')])
|
||||||
books.append(self.STANZA_ENTRY.generate(authors=authors,
|
books.append(self.STANZA_ENTRY.generate(authors=authors,
|
||||||
record=record,
|
record=record,
|
||||||
|
@ -23,7 +23,7 @@ entry_points = {
|
|||||||
'lit-meta = calibre.ebooks.metadata.lit:main',
|
'lit-meta = calibre.ebooks.metadata.lit:main',
|
||||||
'imp-meta = calibre.ebooks.metadata.imp:main',
|
'imp-meta = calibre.ebooks.metadata.imp:main',
|
||||||
'rb-meta = calibre.ebooks.metadata.rb:main',
|
'rb-meta = calibre.ebooks.metadata.rb:main',
|
||||||
'opf-meta = calibre.ebooks.metadata.opf:main',
|
'opf-meta = calibre.ebooks.metadata.opf2:main',
|
||||||
'odt-meta = calibre.ebooks.metadata.odt:main',
|
'odt-meta = calibre.ebooks.metadata.odt:main',
|
||||||
'epub-meta = calibre.ebooks.metadata.epub:main',
|
'epub-meta = calibre.ebooks.metadata.epub:main',
|
||||||
'txt2lrf = calibre.ebooks.lrf.txt.convert_from:main',
|
'txt2lrf = calibre.ebooks.lrf.txt.convert_from:main',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user