Implement robust from/to conversion of datetimes to offsets from the epoch for all dates in the range supprted by the datetime module (1 AD to 9999 AD)

Merge branch 'master' of https://github.com/GRiker/calibre
This commit is contained in:
Kovid Goyal 2013-11-12 08:53:04 +05:30
commit 45b1c409e6
2 changed files with 41 additions and 18 deletions

View File

@ -601,7 +601,7 @@ class libiMobileDevice():
error = self.lib.afc_remove_path(byref(self.afc), str(path)) error = self.lib.afc_remove_path(byref(self.afc), str(path))
if error: if error:
self._log(" ERROR: %s" % self._afc_error(error)) self._log_error(" ERROR: %s path:%s" % (self._afc_error(error), repr(path)))
def stat(self, path): def stat(self, path):
''' '''
@ -650,7 +650,7 @@ class libiMobileDevice():
error = self.lib.afc_client_free(byref(self.afc)) & 0xFFFF error = self.lib.afc_client_free(byref(self.afc)) & 0xFFFF
if error: if error:
self._log(" ERROR: %s" % self._afc_error(error)) self._log_error(" ERROR: %s" % self._afc_error(error))
def _afc_client_new(self): def _afc_client_new(self):
''' '''
@ -810,7 +810,7 @@ class libiMobileDevice():
error = self.lib.afc_file_close(byref(self.afc), error = self.lib.afc_file_close(byref(self.afc),
handle) & 0xFFFF handle) & 0xFFFF
if error: if error:
self._log(" ERROR: %s" % self._afc_error(error)) self._log_error(" ERROR: %s handle:%s" % (self._afc_error(error), handle))
def _afc_file_open(self, filename, mode='r'): def _afc_file_open(self, filename, mode='r'):
''' '''
@ -850,7 +850,7 @@ class libiMobileDevice():
byref(handle)) & 0xFFFF byref(handle)) & 0xFFFF
if error: if error:
self._log(" ERROR: %s" % self._afc_error(error)) self._log_error(" ERROR: %s filename:%s" % (self._afc_error(error), repr(filename)))
return None return None
else: else:
return handle return handle
@ -887,13 +887,13 @@ class libiMobileDevice():
size, size,
byref(bytes_read)) & 0xFFFF byref(bytes_read)) & 0xFFFF
if error: if error:
self._log(" ERROR: %s" % self._afc_error(error)) self._log_error(" ERROR: %s handle:%s" % (self._afc_error(error), handle))
return data return data
else: else:
data = create_string_buffer(size) data = create_string_buffer(size)
error = self.lib.afc_file_read(byref(self.afc), handle, byref(data), size, byref(bytes_read)) error = self.lib.afc_file_read(byref(self.afc), handle, byref(data), size, byref(bytes_read))
if error: if error:
self._log(" ERROR: %s" % self._afc_error(error)) self._log_error(" ERROR: %s handle:%s" % (self._afc_error(error), handle))
return data.value return data.value
def _afc_file_write(self, handle, content, mode='w'): def _afc_file_write(self, handle, content, mode='w'):
@ -933,7 +933,7 @@ class libiMobileDevice():
len(content), len(content),
byref(bytes_written)) & 0xFFFF byref(bytes_written)) & 0xFFFF
if error: if error:
self._log(" ERROR: %s" % self._afc_error(error)) self._log_error(" ERROR: %s handle:%s" % (self._afc_error(error), handle))
return False return False
return True return True
@ -1012,7 +1012,7 @@ class libiMobileDevice():
byref(infolist)) & 0xFFFF byref(infolist)) & 0xFFFF
file_stats = {} file_stats = {}
if error: if error:
self._log(" ERROR: %s" % self._afc_error(error)) self._log_error(" ERROR: %s path:%s" % (self._afc_error(error), repr(path)))
else: else:
num_items = 0 num_items = 0
item_list = [] item_list = []
@ -1049,7 +1049,7 @@ class libiMobileDevice():
error = self.lib.afc_make_directory(byref(self.afc), error = self.lib.afc_make_directory(byref(self.afc),
str(path)) & 0xFFFF str(path)) & 0xFFFF
if error: if error:
self._log(" ERROR: %s" % self._afc_error(error)) self._log_error(" ERROR: %s path:%s" % (self._afc_error(error), repr(path)))
return error return error
@ -1078,7 +1078,7 @@ class libiMobileDevice():
str(directory), str(directory),
byref(dirs)) & 0xFFFF byref(dirs)) & 0xFFFF
if error: if error:
self._log(" ERROR: %s" % self._afc_error(error)) self._log_error(" ERROR: %s directory:%s" % (self._afc_error(error), repr(directory)))
else: else:
num_dirs = 0 num_dirs = 0
dir_list = [] dir_list = []
@ -1126,7 +1126,7 @@ class libiMobileDevice():
error = self.lib.house_arrest_client_free(byref(self.house_arrest)) & 0xFFFF error = self.lib.house_arrest_client_free(byref(self.house_arrest)) & 0xFFFF
if error: if error:
error = error - 0x10000 error = error - 0x10000
self._log(" ERROR: %s" % self._house_arrest_error(error)) self._log_error(" ERROR: %s" % self._house_arrest_error(error))
def _house_arrest_client_new(self): def _house_arrest_client_new(self):
''' '''
@ -1302,7 +1302,7 @@ class libiMobileDevice():
if error: if error:
error = error - 0x10000 error = error - 0x10000
self._log(" ERROR: %s" % self._idevice_error(error)) self._log_error(" ERROR: %s" % self._idevice_error(error))
def _idevice_get_device_list(self): def _idevice_get_device_list(self):
''' '''
@ -1326,7 +1326,7 @@ class libiMobileDevice():
self._log(" no connected devices") self._log(" no connected devices")
else: else:
device_list = None device_list = None
self._log(" ERROR: %s" % self._idevice_error(error)) self._log_error(" ERROR: %s" % self._idevice_error(error))
else: else:
index = 0 index = 0
while devices[index]: while devices[index]:
@ -1859,6 +1859,20 @@ class libiMobileDevice():
else: else:
debug_print() debug_print()
def _log_error(self, *args):
'''
Print error message with location regardless of self.verbose
'''
arg1 = arg2 = ''
if len(args) > 0:
arg1 = args[0]
if len(args) > 1:
arg2 = args[1]
debug_print(self.LOCATION_TEMPLATE.format(cls=self.__class__.__name__,
func=sys._getframe(1).f_code.co_name, arg1=arg1, arg2=arg2))
def _log_location(self, *args): def _log_location(self, *args):
''' '''
''' '''

View File

@ -69,6 +69,7 @@ local_tz = _local_tz = SafeLocalTimeZone()
UNDEFINED_DATE = datetime(101,1,1, tzinfo=utc_tz) UNDEFINED_DATE = datetime(101,1,1, tzinfo=utc_tz)
DEFAULT_DATE = datetime(2000,1,1, tzinfo=utc_tz) DEFAULT_DATE = datetime(2000,1,1, tzinfo=utc_tz)
EPOCH = datetime(1970, 1, 1, tzinfo=_utc_tz)
def is_date_undefined(qt_or_dt): def is_date_undefined(qt_or_dt):
d = qt_or_dt d = qt_or_dt
@ -210,16 +211,24 @@ def now():
def utcnow(): def utcnow():
return datetime.utcnow().replace(tzinfo=_utc_tz) return datetime.utcnow().replace(tzinfo=_utc_tz)
def utcfromtimestamp(stamp): def utcfromtimestamp(stamp):
try: try:
return datetime.utcfromtimestamp(stamp).replace(tzinfo=_utc_tz) return datetime.utcfromtimestamp(stamp).replace(tzinfo=_utc_tz)
except ValueError: except ValueError:
# Raised if stamp if out of range for the platforms gmtime function # Raised if stamp is out of range for the platforms gmtime function
# We print the error for debugging, but otherwise ignore it # For example, this happens with negative values on windows
try:
return EPOCH + timedelta(seconds=stamp)
except (ValueError, OverflowError):
# datetime can only represent years between 1 and 9999
import traceback import traceback
traceback.print_exc() traceback.print_exc()
return utcnow() return utcnow()
def timestampfromdt(dt, assume_utc=True):
return (as_utc(dt, assume_utc=assume_utc) - EPOCH).total_seconds()
# Format date functions # Format date functions
def fd_format_hour(dt, strf, ampm, hr): def fd_format_hour(dt, strf, ampm, hr):