Fix #1247 (Can't set rating in the main window)

This commit is contained in:
Kovid Goyal 2008-11-10 10:02:38 -08:00
parent 9ac26ded49
commit e6a5517cea
8 changed files with 87 additions and 17 deletions

View File

@ -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):

View File

@ -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:

View File

@ -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

View File

@ -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>

View File

@ -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)
@ -662,6 +668,23 @@ class OPF(object):
matches[0].text = unicode(val) matches[0].text = unicode(val)
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())

View File

@ -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)

View File

@ -242,11 +242,11 @@ 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,
port=self.opts.port, port=self.opts.port,
server=self.opts.hostname, server=self.opts.hostname,
).render('xml').decode('utf8')) ).render('xml').decode('utf8'))
@ -254,7 +254,7 @@ class LibraryServer(object):
cherrypy.response.headers['Last-Modified'] = self.last_modified(updated) cherrypy.response.headers['Last-Modified'] = self.last_modified(updated)
cherrypy.response.headers['Content-Type'] = 'text/xml' cherrypy.response.headers['Content-Type'] = 'text/xml'
return self.STANZA.generate(subtitle='', data=books, return self.STANZA.generate(subtitle='', data=books,
updated=updated, id='urn:calibre:main').render('xml') updated=updated, id='urn:calibre:main').render('xml')
@expose @expose

View File

@ -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',