mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-07 10:14:46 -04:00
Send books using a streaming protocol instead of the request/response one.
This commit is contained in:
parent
774a56c1fa
commit
e00f4cf936
@ -168,6 +168,7 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin):
|
|||||||
self.noop_counter = 0
|
self.noop_counter = 0
|
||||||
self.debug_start_time = time.time()
|
self.debug_start_time = time.time()
|
||||||
self.debug_time = time.time()
|
self.debug_time = time.time()
|
||||||
|
self.client_can_stream_books = False
|
||||||
|
|
||||||
def _debug(self, *args):
|
def _debug(self, *args):
|
||||||
if not DEBUG:
|
if not DEBUG:
|
||||||
@ -343,7 +344,7 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin):
|
|||||||
# recv seems to return a pointer into some internal buffer.
|
# recv seems to return a pointer into some internal buffer.
|
||||||
# Things get trashed if we don't make a copy of the data.
|
# Things get trashed if we don't make a copy of the data.
|
||||||
self.device_socket.settimeout(self.MAX_CLIENT_COMM_TIMEOUT)
|
self.device_socket.settimeout(self.MAX_CLIENT_COMM_TIMEOUT)
|
||||||
v = self.device_socket.recv(self.BASE_PACKET_LEN)
|
v = self.device_socket.recv(2)
|
||||||
self.device_socket.settimeout(None)
|
self.device_socket.settimeout(None)
|
||||||
if len(v) == 0:
|
if len(v) == 0:
|
||||||
return '' # documentation says the socket is broken permanently.
|
return '' # documentation says the socket is broken permanently.
|
||||||
@ -382,7 +383,7 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin):
|
|||||||
raise
|
raise
|
||||||
time.sleep(0.1) # lets not hammer the OS too hard
|
time.sleep(0.1) # lets not hammer the OS too hard
|
||||||
|
|
||||||
def _call_client(self, op, arg, print_debug_info=True):
|
def _call_client(self, op, arg, print_debug_info=True, wait_for_response=True):
|
||||||
if op != 'NOOP':
|
if op != 'NOOP':
|
||||||
self.noop_counter = 0
|
self.noop_counter = 0
|
||||||
extra_debug = self.settings().extra_customization[self.OPT_EXTRA_DEBUG]
|
extra_debug = self.settings().extra_customization[self.OPT_EXTRA_DEBUG]
|
||||||
@ -399,6 +400,27 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin):
|
|||||||
self._debug('send string', s)
|
self._debug('send string', s)
|
||||||
self.device_socket.settimeout(self.MAX_CLIENT_COMM_TIMEOUT)
|
self.device_socket.settimeout(self.MAX_CLIENT_COMM_TIMEOUT)
|
||||||
self._send_byte_string((b'%d' % len(s)) + s)
|
self._send_byte_string((b'%d' % len(s)) + s)
|
||||||
|
if not wait_for_response:
|
||||||
|
return None, None
|
||||||
|
return self._receive_from_client(print_debug_info=print_debug_info)
|
||||||
|
except socket.timeout:
|
||||||
|
self._debug('timeout communicating with device')
|
||||||
|
self._close_device_socket()
|
||||||
|
raise TimeoutError('Device did not respond in reasonable time')
|
||||||
|
except socket.error:
|
||||||
|
self._debug('device went away')
|
||||||
|
self._close_device_socket()
|
||||||
|
raise ControlError(desc='Device closed the network connection')
|
||||||
|
except:
|
||||||
|
self._debug('other exception')
|
||||||
|
traceback.print_exc()
|
||||||
|
self._close_device_socket()
|
||||||
|
raise
|
||||||
|
raise ControlError(desc='Device responded with incorrect information')
|
||||||
|
|
||||||
|
def _receive_from_client(self, print_debug_info=True):
|
||||||
|
extra_debug = self.settings().extra_customization[self.OPT_EXTRA_DEBUG]
|
||||||
|
try:
|
||||||
v = self._read_string_from_net()
|
v = self._read_string_from_net()
|
||||||
self.device_socket.settimeout(None)
|
self.device_socket.settimeout(None)
|
||||||
if print_debug_info and extra_debug:
|
if print_debug_info and extra_debug:
|
||||||
@ -434,9 +456,13 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin):
|
|||||||
book_metadata.size = length
|
book_metadata.size = length
|
||||||
infile.seek(0)
|
infile.seek(0)
|
||||||
self._debug(lpath, length)
|
self._debug(lpath, length)
|
||||||
self._call_client('SEND_BOOK', {'lpath': lpath, 'length': length,
|
opcode, result = self._call_client('SEND_BOOK', {'lpath': lpath, 'length': length,
|
||||||
'metadata': book_metadata, 'thisBook': this_book,
|
'metadata': book_metadata, 'thisBook': this_book,
|
||||||
'totalBooks': total_books}, print_debug_info=False)
|
'totalBooks': total_books,
|
||||||
|
'willStreamBooks': self.client_can_stream_books},
|
||||||
|
print_debug_info=False,
|
||||||
|
wait_for_response=(not self.client_can_stream_books))
|
||||||
|
|
||||||
self._set_known_metadata(book_metadata)
|
self._set_known_metadata(book_metadata)
|
||||||
pos = 0
|
pos = 0
|
||||||
failed = False
|
failed = False
|
||||||
@ -449,9 +475,10 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin):
|
|||||||
b = b64encode(b)
|
b = b64encode(b)
|
||||||
opcode, result = self._call_client('BOOK_DATA',
|
opcode, result = self._call_client('BOOK_DATA',
|
||||||
{'lpath': lpath, 'position': pos, 'data': b},
|
{'lpath': lpath, 'position': pos, 'data': b},
|
||||||
print_debug_info=False)
|
print_debug_info=False,
|
||||||
|
wait_for_response=(not self.client_can_stream_books))
|
||||||
pos += blen
|
pos += blen
|
||||||
if opcode != 'OK':
|
if not self.client_can_stream_books and opcode != 'OK':
|
||||||
self._debug('protocol error', opcode)
|
self._debug('protocol error', opcode)
|
||||||
failed = True
|
failed = True
|
||||||
break
|
break
|
||||||
@ -619,6 +646,8 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin):
|
|||||||
self._close_device_socket()
|
self._close_device_socket()
|
||||||
return False
|
return False
|
||||||
self._debug('CC version #:', result.get('ccVersionNumber', 'unknown'))
|
self._debug('CC version #:', result.get('ccVersionNumber', 'unknown'))
|
||||||
|
self.client_can_stream_books = result.get('canStreamBooks', False)
|
||||||
|
self._debug('CC can stream', self.client_can_stream_books);
|
||||||
self.max_book_packet_len = result.get('maxBookContentPacketLen',
|
self.max_book_packet_len = result.get('maxBookContentPacketLen',
|
||||||
self.BASE_PACKET_LEN)
|
self.BASE_PACKET_LEN)
|
||||||
exts = result.get('acceptedExtensions', None)
|
exts = result.get('acceptedExtensions', None)
|
||||||
@ -725,11 +754,15 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin):
|
|||||||
self._debug(oncard)
|
self._debug(oncard)
|
||||||
if oncard is not None:
|
if oncard is not None:
|
||||||
return CollectionsBookList(None, None, None)
|
return CollectionsBookList(None, None, None)
|
||||||
opcode, result = self._call_client('GET_BOOK_COUNT', {})
|
opcode, result = self._call_client('GET_BOOK_COUNT', {'canStream':True})
|
||||||
bl = CollectionsBookList(None, self.PREFIX, self.settings)
|
bl = CollectionsBookList(None, self.PREFIX, self.settings)
|
||||||
if opcode == 'OK':
|
if opcode == 'OK':
|
||||||
count = result['count']
|
count = result['count']
|
||||||
|
will_stream = 'willStream' in result;
|
||||||
for i in range(0, count):
|
for i in range(0, count):
|
||||||
|
if will_stream:
|
||||||
|
opcode, result = self._receive_from_client(print_debug_info=False)
|
||||||
|
else:
|
||||||
opcode, result = self._call_client('GET_BOOK_METADATA', {'index': i},
|
opcode, result = self._call_client('GET_BOOK_METADATA', {'index': i},
|
||||||
print_debug_info=False)
|
print_debug_info=False)
|
||||||
if opcode == 'OK':
|
if opcode == 'OK':
|
||||||
@ -764,7 +797,6 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin):
|
|||||||
for i, book in enumerate(booklists[0]):
|
for i, book in enumerate(booklists[0]):
|
||||||
if not self._metadata_already_on_device(book):
|
if not self._metadata_already_on_device(book):
|
||||||
self._set_known_metadata(book)
|
self._set_known_metadata(book)
|
||||||
self._debug('syncing book', book.lpath)
|
|
||||||
opcode, result = self._call_client('SEND_BOOK_METADATA',
|
opcode, result = self._call_client('SEND_BOOK_METADATA',
|
||||||
{'index': i, 'data': book},
|
{'index': i, 'data': book},
|
||||||
print_debug_info=False)
|
print_debug_info=False)
|
||||||
@ -904,6 +936,7 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin):
|
|||||||
self.max_book_packet_len = 0
|
self.max_book_packet_len = 0
|
||||||
self.noop_counter = 0
|
self.noop_counter = 0
|
||||||
self.connection_attempts = {}
|
self.connection_attempts = {}
|
||||||
|
self.client_can_stream_books = False
|
||||||
try:
|
try:
|
||||||
self.listen_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
self.listen_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
except:
|
except:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user