diff --git a/src/calibre/devices/usbms/driver.py b/src/calibre/devices/usbms/driver.py index 92e57e7447..1666398fc9 100644 --- a/src/calibre/devices/usbms/driver.py +++ b/src/calibre/devices/usbms/driver.py @@ -294,6 +294,19 @@ class USBMS(CLI, Device): self.report_progress(1.0, _('Sending metadata to device...')) debug_print('USBMS: finished sync_booklists') + @classmethod + def build_template_regexp(cls): + def replfunc(match): + if match.group(1) in ['title', 'series', 'series_index', 'isbn']: + return '(?P<' + match.group(1) + '>.+?)' + elif match.group(1) == 'authors': + return '(?P.+?)' + else: + return '(.+?)' + template = cls.save_template().rpartition('/')[2] + print 'bftr', template + return re.compile(re.sub('{([^}]*)}', replfunc, template) + '([_\d]*$)') + @classmethod def path_to_unicode(cls, path): if isbytestring(path): @@ -355,22 +368,17 @@ class USBMS(CLI, Device): from calibre.ebooks.metadata.meta import metadata_from_formats from calibre.customize.ui import quick_metadata with quick_metadata: - return metadata_from_formats(fmts) + return metadata_from_formats(fmts, force_read_metadata=True, + pattern=cls.build_template_regexp()) @classmethod - def book_from_path(cls, prefix, path): + def book_from_path(cls, prefix, lpath): from calibre.ebooks.metadata import MetaInformation - - if cls.settings().read_metadata or cls.MUST_READ_METADATA: - mi = cls.metadata_from_path(cls.normalize_path(os.path.join(prefix, path))) - else: - from calibre.ebooks.metadata.meta import metadata_from_filename - mi = metadata_from_filename(cls.normalize_path(os.path.basename(path)), - re.compile(r'^(?P[ \S]+?)[ _]-[ _](?P<author>[ \S]+?)_+\d+')) + mi = cls.metadata_from_path(cls.normalize_path(os.path.join(prefix, lpath))) if mi is None: - mi = MetaInformation(os.path.splitext(os.path.basename(path))[0], + mi = MetaInformation(os.path.splitext(os.path.basename(lpath))[0], [_('Unknown')]) - size = os.stat(cls.normalize_path(os.path.join(prefix, path))).st_size - book = cls.book_class(prefix, path, other=mi, size=size) + size = os.stat(cls.normalize_path(os.path.join(prefix, lpath))).st_size + book = cls.book_class(prefix, lpath, other=mi, size=size) return book diff --git a/src/calibre/ebooks/metadata/meta.py b/src/calibre/ebooks/metadata/meta.py index f5a327a0d6..eae8171362 100644 --- a/src/calibre/ebooks/metadata/meta.py +++ b/src/calibre/ebooks/metadata/meta.py @@ -27,16 +27,16 @@ for i, ext in enumerate(_METADATA_PRIORITIES): def path_to_ext(path): return os.path.splitext(path)[1][1:].lower() -def metadata_from_formats(formats): +def metadata_from_formats(formats, force_read_metadata=False, pattern=None): try: - return _metadata_from_formats(formats) + return _metadata_from_formats(formats, force_read_metadata, pattern) except: - mi = metadata_from_filename(list(iter(formats))[0]) + mi = metadata_from_filename(list(iter(formats), pattern)[0]) if not mi.authors: mi.authors = [_('Unknown')] return mi -def _metadata_from_formats(formats): +def _metadata_from_formats(formats, force_read_metadata=False, pattern=None): mi = MetaInformation(None, None) formats.sort(cmp=lambda x,y: cmp(METADATA_PRIORITIES[path_to_ext(x)], METADATA_PRIORITIES[path_to_ext(y)])) @@ -51,7 +51,9 @@ def _metadata_from_formats(formats): with open(path, 'rb') as stream: try: newmi = get_metadata(stream, stream_type=ext, - use_libprs_metadata=True) + use_libprs_metadata=True, + force_read_metadata=force_read_metadata, + pattern=pattern) mi.smart_update(newmi) except: continue @@ -69,18 +71,21 @@ def is_recipe(filename): return filename.startswith('calibre') and \ filename.rpartition('.')[0].endswith('_recipe_out') -def get_metadata(stream, stream_type='lrf', use_libprs_metadata=False): +def get_metadata(stream, stream_type='lrf', use_libprs_metadata=False, + force_read_metadata=False, pattern=None): pos = 0 if hasattr(stream, 'tell'): pos = stream.tell() try: - return _get_metadata(stream, stream_type, use_libprs_metadata) + return _get_metadata(stream, stream_type, use_libprs_metadata, + force_read_metadata, pattern) finally: if hasattr(stream, 'seek'): stream.seek(pos) -def _get_metadata(stream, stream_type, use_libprs_metadata): +def _get_metadata(stream, stream_type, use_libprs_metadata, + force_read_metadata=False, pattern=None): if stream_type: stream_type = stream_type.lower() if stream_type in ('html', 'html', 'xhtml', 'xhtm', 'xml'): stream_type = 'html' @@ -100,8 +105,8 @@ def _get_metadata(stream, stream_type, use_libprs_metadata): mi = MetaInformation(None, None) name = os.path.basename(getattr(stream, 'name', '')) - base = metadata_from_filename(name) - if is_recipe(name) or prefs['read_file_metadata']: + base = metadata_from_filename(name, pat=pattern) + if force_read_metadata or is_recipe(name) or prefs['read_file_metadata']: mi = get_file_type_metadata(stream, stream_type) if base.title == os.path.splitext(name)[0] and base.authors is None: # Assume that there was no metadata in the file and the user set pattern @@ -139,7 +144,7 @@ def metadata_from_filename(name, pat=None): pat = re.compile(prefs.get('filename_pattern')) name = name.replace('_', ' ') match = pat.search(name) - if match: + if match is not None: try: mi.title = match.group('title') except IndexError: