diff --git a/setup/install.py b/setup/install.py index 20a484bf6f..56546cd7d4 100644 --- a/setup/install.py +++ b/setup/install.py @@ -191,6 +191,8 @@ class Develop(Command): if not os.path.exists(self.staging_bindir): os.makedirs(self.staging_bindir) self.info('Installing binary:', path) + if os.path.lexists(path) and not os.path.exists(path): + os.remove(path) open(path, 'wb').write(script) os.chmod(path, self.MODE) self.manifest.append(path) diff --git a/src/calibre/debug.py b/src/calibre/debug.py index 63e11ae368..d18d1a4479 100644 --- a/src/calibre/debug.py +++ b/src/calibre/debug.py @@ -32,9 +32,6 @@ Run an embedded python interpreter. help='Add a simple plugin (i.e. a plugin that consists of only a ' '.py file), by specifying the path to the py file containing the ' 'plugin code.') - parser.add_option('--pdfreflow', default=None, - help='Path to PDF file to try and reflow. Output will be placed in ' - 'current directory. ') return parser @@ -117,11 +114,6 @@ def main(args=sys.argv): prints('CALIBRE_RESOURCES_PATH='+sys.resources_location) prints('CALIBRE_EXTENSIONS_PATH='+sys.extensions_location) prints('CALIBRE_PYTHON_PATH='+os.pathsep.join(sys.path)) - elif opts.pdfreflow: - from calibre.ebooks.pdf.reflow import option_parser as px, run - from calibre.utils.logging import default_log - opts2, args = px().parse_args(['xxxx', '-vvvv', opts.pdfreflow]) - run(opts2, opts.pdfreflow, default_log) else: from calibre import ipython ipython() diff --git a/src/calibre/devices/__init__.py b/src/calibre/devices/__init__.py index 7cf98913f3..466a9ec20a 100644 --- a/src/calibre/devices/__init__.py +++ b/src/calibre/devices/__init__.py @@ -97,6 +97,8 @@ def debug(ioreg_to_tmp=False, buf=None): out('Devices possibly connected:', end=' ') for dev, det in connected_devices: out(dev.name, end=', ') + if not connected_devices: + out('None', end='') out(' ') for dev, det in connected_devices: out('Trying to open', dev.name, '...', end=' ') diff --git a/src/calibre/devices/cybook/driver.py b/src/calibre/devices/cybook/driver.py index 5ac0d4999c..8790cea6b8 100644 --- a/src/calibre/devices/cybook/driver.py +++ b/src/calibre/devices/cybook/driver.py @@ -34,6 +34,7 @@ class CYBOOK(USBMS): VENDOR_NAME = 'BOOKEEN' WINDOWS_MAIN_MEM = re.compile(r'CYBOOK_(OPUS|GEN3)__-FD') WINDOWS_CARD_A_MEM = re.compile('CYBOOK_(OPUS|GEN3)__-SD') + OSX_MAIN_MEM_VOL_PAT = re.compile(r'/Cybook') EBOOK_DIR_MAIN = 'eBooks' EBOOK_DIR_CARD_A = 'eBooks' diff --git a/src/calibre/devices/usbms/device.py b/src/calibre/devices/usbms/device.py index f01133c301..fd7cf262dc 100644 --- a/src/calibre/devices/usbms/device.py +++ b/src/calibre/devices/usbms/device.py @@ -71,6 +71,11 @@ class Device(DeviceConfig, DevicePlugin): OSX_CARD_A_MEM = None OSX_CARD_B_MEM = None + # Used by the new driver detection to disambiguate main memory from + # storage cards. Should be a regular expression that matches the + # main memory mount point assigned by OS X + OSX_MAIN_MEM_VOL_PAT = None + MAIN_MEMORY_VOLUME_LABEL = '' STORAGE_CARD_VOLUME_LABEL = '' STORAGE_CARD2_VOLUME_LABEL = None @@ -415,6 +420,16 @@ class Device(DeviceConfig, DevicePlugin): if len(matches) > 2: drives['cardb'] = matches[2] + pat = self.OSX_MAIN_MEM_VOL_PAT + if pat is not None and len(drives) > 1 and 'main' in drives: + if pat.search(drives['main']) is None: + main = drives['main'] + for x in ('carda', 'cardb'): + if x in drives and pat.search(drives[x]): + drives['main'] = drives.pop(x) + drives[x] = main + break + return drives def osx_bsd_names(self): diff --git a/src/calibre/gui2/dialogs/tag_editor.py b/src/calibre/gui2/dialogs/tag_editor.py index 573316fa0f..ca3f7176f1 100644 --- a/src/calibre/gui2/dialogs/tag_editor.py +++ b/src/calibre/gui2/dialogs/tag_editor.py @@ -43,7 +43,9 @@ class TagEditor(QDialog, Ui_TagEditor): self.connect(self.add_tag_button, SIGNAL('clicked()'), self.add_tag) self.connect(self.delete_button, SIGNAL('clicked()'), self.delete_tags) self.connect(self.add_tag_input, SIGNAL('returnPressed()'), self.add_tag) - if not islinux: + if islinux: + self.available_tags.itemDoubleClicked.connect(self.apply_tags) + else: self.connect(self.available_tags, SIGNAL('itemActivated(QListWidgetItem*)'), self.apply_tags) self.connect(self.applied_tags, SIGNAL('itemActivated(QListWidgetItem*)'), self.unapply_tags) diff --git a/src/calibre/library/save_to_disk.py b/src/calibre/library/save_to_disk.py index 581a1e400d..5076f10d86 100644 --- a/src/calibre/library/save_to_disk.py +++ b/src/calibre/library/save_to_disk.py @@ -23,7 +23,8 @@ DEFAULT_SEND_TEMPLATE = '{author_sort}/{title} - {authors}' FORMAT_ARG_DESCS = dict( title=_('The title'), authors=_('The authors'), - author_sort=_('The author sort string'), + author_sort=_('The author sort string. To use only the first letter ' + 'of the name use {author_sort[0]}'), tags=_('The tags'), series=_('The series'), series_index=_('The series number. To get leading zeros use {series_index:0>3s}'), @@ -94,6 +95,15 @@ def preprocess_template(template): template = template.decode(preferred_encoding, 'replace') return template +def safe_format(x, format_args): + try: + return x.format(**format_args).strip() + except IndexError: # Thrown if user used [] and index is out of bounds + pass + except AttributeError: # Thrown if user used a non existing attribute + pass + return '' + def get_components(template, mi, id, timefmt='%b %Y', length=250, sanitize_func=ascii_filename, replace_whitespace=False, to_lowercase=False): @@ -124,7 +134,7 @@ def get_components(template, mi, id, timefmt='%b %Y', length=250, format_args['pubdate'] = strftime(timefmt, mi.pubdate.timetuple()) format_args['id'] = str(id) components = [x.strip() for x in template.split('/') if x.strip()] - components = [x.format(**format_args).strip() for x in components] + components = [safe_format(x, format_args) for x in components] components = [sanitize_func(x) for x in components if x] if not components: components = [str(id)]