mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-06-23 15:30:45 -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.debug_start_time = time.time()
|
||||
self.debug_time = time.time()
|
||||
self.client_can_stream_books = False
|
||||
|
||||
def _debug(self, *args):
|
||||
if not DEBUG:
|
||||
@ -343,7 +344,7 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin):
|
||||
# recv seems to return a pointer into some internal buffer.
|
||||
# Things get trashed if we don't make a copy of the data.
|
||||
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)
|
||||
if len(v) == 0:
|
||||
return '' # documentation says the socket is broken permanently.
|
||||
@ -382,7 +383,7 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin):
|
||||
raise
|
||||
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':
|
||||
self.noop_counter = 0
|
||||
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.device_socket.settimeout(self.MAX_CLIENT_COMM_TIMEOUT)
|
||||
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()
|
||||
self.device_socket.settimeout(None)
|
||||
if print_debug_info and extra_debug:
|
||||
@ -434,9 +456,13 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin):
|
||||
book_metadata.size = length
|
||||
infile.seek(0)
|
||||
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,
|
||||
'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)
|
||||
pos = 0
|
||||
failed = False
|
||||
@ -449,9 +475,10 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin):
|
||||
b = b64encode(b)
|
||||
opcode, result = self._call_client('BOOK_DATA',
|
||||
{'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
|
||||
if opcode != 'OK':
|
||||
if not self.client_can_stream_books and opcode != 'OK':
|
||||
self._debug('protocol error', opcode)
|
||||
failed = True
|
||||
break
|
||||
@ -619,6 +646,8 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin):
|
||||
self._close_device_socket()
|
||||
return False
|
||||
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.BASE_PACKET_LEN)
|
||||
exts = result.get('acceptedExtensions', None)
|
||||
@ -725,11 +754,15 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin):
|
||||
self._debug(oncard)
|
||||
if oncard is not 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)
|
||||
if opcode == 'OK':
|
||||
count = result['count']
|
||||
will_stream = 'willStream' in result;
|
||||
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},
|
||||
print_debug_info=False)
|
||||
if opcode == 'OK':
|
||||
@ -764,7 +797,6 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin):
|
||||
for i, book in enumerate(booklists[0]):
|
||||
if not self._metadata_already_on_device(book):
|
||||
self._set_known_metadata(book)
|
||||
self._debug('syncing book', book.lpath)
|
||||
opcode, result = self._call_client('SEND_BOOK_METADATA',
|
||||
{'index': i, 'data': book},
|
||||
print_debug_info=False)
|
||||
@ -904,6 +936,7 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin):
|
||||
self.max_book_packet_len = 0
|
||||
self.noop_counter = 0
|
||||
self.connection_attempts = {}
|
||||
self.client_can_stream_books = False
|
||||
try:
|
||||
self.listen_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
except:
|
||||
|
Loading…
x
Reference in New Issue
Block a user