diff --git a/src/calibre/devices/bambook/driver.py b/src/calibre/devices/bambook/driver.py index 930c67a159..e7fa66c939 100644 --- a/src/calibre/devices/bambook/driver.py +++ b/src/calibre/devices/bambook/driver.py @@ -29,12 +29,16 @@ class BAMBOOK(DeviceConfig, DevicePlugin): booklist_class = BookList book_class = Book + ip = None + FORMATS = [ "snb" ] VENDOR_ID = 0x230b PRODUCT_ID = 0x0001 BCD = None CAN_SET_METADATA = False THUMBNAIL_HEIGHT = 155 + EXTRA_CUSTOMIZATION_MESSAGE = \ + _("Device IP Address (restart calibre after changing)") icon = I("devices/bambook.png") # OPEN_FEEDBACK_MESSAGE = _( @@ -47,6 +51,10 @@ class BAMBOOK(DeviceConfig, DevicePlugin): METADATA_FILE_GUID = 'calibremetadata.snb' bambook = None + is_connected = False + + def __init__(self, ip): + self.ip = ip def reset(self, key='-1', log_packets=False, report_progress=None, detected_device=None) : @@ -60,15 +68,23 @@ class BAMBOOK(DeviceConfig, DevicePlugin): self.eject() # Connect self.bambook = Bambook() - self.bambook.Connect() + self.bambook.Connect(ip = self.ip, timeout = 10000) if self.bambook.GetState() != CONN_CONNECTED: self.bambook = None - raise Exception(_("Unable to connect to Bambook.")) + raise OpenFeedback(_("Unable to connect to Bambook. \n" + "If you are trying to connect via Wi-Fi, " + "please make sure the IP address of Bambook has been correctly configured.")) + self.is_connected = True + return True + + def unmount_device(self): + self.eject() def eject(self): if self.bambook: self.bambook.Disconnect() self.bambook = None + self.is_connected = False def post_yank_cleanup(self): self.eject() @@ -475,3 +491,8 @@ class BAMBOOK(DeviceConfig, DevicePlugin): def get_guid(uuid): guid = hashlib.md5(uuid).hexdigest()[0:15] + ".snb" return guid + +class BAMBOOKWifi(BAMBOOK): + def is_usb_connected(self, devices_on_system, debug=False, + only_presence=False): + return self.is_connected, self diff --git a/src/calibre/devices/bambook/libbambookcore.py b/src/calibre/devices/bambook/libbambookcore.py index a11c5e9e87..35d04ba4ac 100644 --- a/src/calibre/devices/bambook/libbambookcore.py +++ b/src/calibre/devices/bambook/libbambookcore.py @@ -329,6 +329,8 @@ class Bambook: self.handle = None def Connect(self, ip = DEFAULT_BAMBOOK_IP, timeout = 10000): + if ip == None or ip == '': + ip = DEFAULT_BAMBOOK_IP self.handle = BambookConnect(ip, timeout) if self.handle and self.handle != 0: return True diff --git a/src/calibre/ebooks/snb/input.py b/src/calibre/ebooks/snb/input.py index 659ca79619..d2acb257aa 100755 --- a/src/calibre/ebooks/snb/input.py +++ b/src/calibre/ebooks/snb/input.py @@ -46,14 +46,27 @@ class SNBInput(InputFormatPlugin): meta = snbFile.GetFileStream('snbf/book.snbf') if meta != None: meta = etree.fromstring(meta) - oeb.metadata.add('title', meta.find('.//head/name').text) - oeb.metadata.add('creator', meta.find('.//head/author').text, attrib={'role':'aut'}) - oeb.metadata.add('language', meta.find('.//head/language').text.lower().replace('_', '-')) - oeb.metadata.add('creator', meta.find('.//head/generator').text) - oeb.metadata.add('publisher', meta.find('.//head/publisher').text) - cover = meta.find('.//head/cover') - if cover != None and cover.text != None: - oeb.guide.add('cover', 'Cover', cover.text) + l = { 'title' : './/head/name', + 'creator' : './/head/author', + 'language' : './/head/language', + 'generator': './/head/generator', + 'publisher': './/head/publisher', + 'cover' : './/head/cover', } + d = {} + for item in l: + node = meta.find(l[item]) + if node != None: + d[item] = node.text if node.text != None else '' + else: + d[item] = '' + + oeb.metadata.add('title', d['title']) + oeb.metadata.add('creator', d['creator'], attrib={'role':'aut'}) + oeb.metadata.add('language', d['language'].lower().replace('_', '-')) + oeb.metadata.add('generator', d['generator']) + oeb.metadata.add('publisher', d['publisher']) + if d['cover'] != '': + oeb.guide.add('cover', 'Cover', d['cover']) bookid = str(uuid.uuid4()) oeb.metadata.add('identifier', bookid, id='uuid_id', scheme='uuid') diff --git a/src/calibre/gui2/actions/device.py b/src/calibre/gui2/actions/device.py index 744ab20d10..fb3e627789 100644 --- a/src/calibre/gui2/actions/device.py +++ b/src/calibre/gui2/actions/device.py @@ -12,11 +12,15 @@ from PyQt4.Qt import QToolButton, QMenu, pyqtSignal, QIcon from calibre.gui2.actions import InterfaceAction from calibre.utils.smtp import config as email_config from calibre.constants import iswindows, isosx +from calibre.customize.ui import is_disabled +from calibre.devices.bambook.driver import BAMBOOK class ShareConnMenu(QMenu): # {{{ connect_to_folder = pyqtSignal() connect_to_itunes = pyqtSignal() + connect_to_bambook = pyqtSignal() + config_email = pyqtSignal() toggle_server = pyqtSignal() dont_add_to = frozenset(['toolbar-device', 'context-menu-device']) @@ -34,6 +38,17 @@ class ShareConnMenu(QMenu): # {{{ self.connect_to_itunes_action = mitem if not (iswindows or isosx): mitem.setVisible(False) + mitem = self.addAction(QIcon(I('devices/bambook.png')), _('Connect to Bambook')) + mitem.setEnabled(True) + mitem.triggered.connect(lambda x : self.connect_to_bambook.emit()) + self.connect_to_bambook_action = mitem + bambook_visible = False + if not is_disabled(BAMBOOK): + device_ip = BAMBOOK.settings().extra_customization + if device_ip: + bambook_visible = True + self.connect_to_bambook_action.setVisible(bambook_visible) + self.addSeparator() self.toggle_server_action = \ self.addAction(QIcon(I('network-server.png')), @@ -88,6 +103,7 @@ class ShareConnMenu(QMenu): # {{{ def set_state(self, device_connected): self.connect_to_folder_action.setEnabled(not device_connected) self.connect_to_itunes_action.setEnabled(not device_connected) + self.connect_to_bambook_action.setEnabled(not device_connected) # }}} @@ -126,6 +142,7 @@ class ConnectShareAction(InterfaceAction): self.qaction.setMenu(self.share_conn_menu) self.share_conn_menu.connect_to_folder.connect(self.gui.connect_to_folder) self.share_conn_menu.connect_to_itunes.connect(self.gui.connect_to_itunes) + self.share_conn_menu.connect_to_bambook.connect(self.gui.connect_to_bambook) def location_selected(self, loc): enabled = loc == 'library' diff --git a/src/calibre/gui2/device.py b/src/calibre/gui2/device.py index 3b071aa024..6d289a3e5c 100644 --- a/src/calibre/gui2/device.py +++ b/src/calibre/gui2/device.py @@ -24,6 +24,7 @@ from calibre.utils.filenames import ascii_filename from calibre.devices.errors import FreeSpaceError from calibre.devices.apple.driver import ITUNES_ASYNC from calibre.devices.folder_device.driver import FOLDER_DEVICE +from calibre.devices.bambook.driver import BAMBOOK, BAMBOOKWifi from calibre.ebooks.metadata.meta import set_metadata from calibre.constants import DEBUG from calibre.utils.config import prefs, tweaks @@ -635,6 +636,10 @@ class DeviceMixin(object): # {{{ if dir is not None: self.device_manager.mount_device(kls=FOLDER_DEVICE, kind='folder', path=dir) + def connect_to_bambook(self): + self.device_manager.mount_device(kls=BAMBOOKWifi, kind='bambook', + path=BAMBOOK.settings().extra_customization) + def connect_to_itunes(self): self.device_manager.mount_device(kls=ITUNES_ASYNC, kind='itunes', path=None)