def Report(self, subcount_created=0, subcount_updated=0): str_tips = [] self.counts.created.completed.subcount = subcount_created self.counts.updated.completed.subcount = subcount_updated str_tips += self.ReportSingle('were newly created', self.counts.created, self.info.str_value('created')) str_tips += self.ReportSingle('already exist and were updated', self.counts.updated, self.info.str_value('updated')) str_tips += self.ReportSingle('already exist but were unchanged', self.counts.skipped, process_subcounts=False) if self.counts.error: str_tips.append("%d Error(s) occurred " % self.counts.error.val) if self.status == EvernoteAPIStatus.ExceededLocalLimit: str_tips.append( "Action was prematurely terminated because locally-defined limit of %d was exceeded." % self.counts.max_allowed) report_title = " > %s Complete" % self.info.Action if self.counts.total is 0: report_title += self.info.FormatLine(": No {r} were processed") show_report(report_title, self.ReportHeader, str_tips, blank_line_before=False, do_print=self.__do_print) log_blank('counters') log(self.counts.fullSummary(self.name + ': End'), 'counters')
def HandleSocketError(e, strErrorBase): global latestSocketError errorcode = e[0] friendly_error_msgs = { errno.ECONNREFUSED: "Connection was refused", errno.WSAECONNRESET: "Connection was reset or forcibly closed by the remote host", errno.ETIMEDOUT: "Connection timed out" } if errorcode not in errno.errorcode: log_error("Unknown socket error (%s) occurred: %s" % (str(errorcode), str(e))) return False error_constant = errno.errorcode[errorcode] if errorcode in friendly_error_msgs: strError = friendly_error_msgs[errorcode] else: strError = "Unhandled socket error (%s) occurred" % error_constant latestSocketError = { 'code': errorcode, 'friendly_error_msg': strError, 'constant': error_constant } strError = "Error: %s while %s\r\n" % (strError, strErrorBase) log_error(" SocketError.%s: " % error_constant + strError) log_error(str(e)) log(" SocketError.%s: " % error_constant + strError, 'api') if EVERNOTE.API.EDAM_RATE_LIMIT_ERROR_HANDLING is EVERNOTE.API.RateLimitErrorHandling.AlertError: showInfo(strError) elif EVERNOTE.API.EDAM_RATE_LIMIT_ERROR_HANDLING is EVERNOTE.API.RateLimitErrorHandling.ToolTipError: show_tooltip(strError) return True
def HandleSocketError(e, strErrorBase): global latestSocketError errorcode = e[0] friendly_error_msgs = { errno.ECONNREFUSED: "Connection was refused", errno.WSAECONNRESET: "Connection was reset or forcibly closed by the remote host", errno.ETIMEDOUT: "Connection timed out" } if errorcode not in errno.errorcode: log_error("Unknown socket error (%s) occurred: %s" % (str(errorcode), str(e))) return False error_constant = errno.errorcode[errorcode] if errorcode in friendly_error_msgs: strError = friendly_error_msgs[errorcode] else: strError = "Unhandled socket error (%s) occurred" % error_constant latestSocketError = {'code': errorcode, 'friendly_error_msg': strError, 'constant': error_constant} strError = "Error: %s while %s\r\n" % (strError, strErrorBase) log_error(" SocketError.%s: " % error_constant + strError) log_error(str(e)) log(" SocketError.%s: " % error_constant + strError, 'api') if EVERNOTE.API.EDAM_RATE_LIMIT_ERROR_HANDLING is EVERNOTE.API.RateLimitErrorHandling.AlertError: showInfo(strError) elif EVERNOTE.API.EDAM_RATE_LIMIT_ERROR_HANDLING is EVERNOTE.API.RateLimitErrorHandling.ToolTipError: show_tooltip(strError) return True
def checkLimits(self): if not -1 < self.counts.max_allowed <= self.counts.updated + self.counts.created: return True log("Count exceeded- Breaking with status " + str(self.status), self.label, do_print=self.__do_print) self.reportStatus(EvernoteAPIStatus.ExceededLocalLimit) return False
def __init__(self, title=None, content=None, guid=None, tags=None, notebookGuid=None, updateSequenceNum=None, whole_note=None, db_note=None): """ :type whole_note: evernote.edam.type.ttypes.Note :type db_note: sqlite3.dbapi2.Row """ self.Status = EvernoteAPIStatus.Uninitialized self.TagNames = tags if whole_note is not None: if self.TagNames is None: self.TagNames = whole_note.tagNames self.Title = EvernoteNoteTitle(whole_note) self.Content = whole_note.content self.Guid = whole_note.guid self.NotebookGuid = whole_note.notebookGuid self.UpdateSequenceNum = whole_note.updateSequenceNum self.Status = EvernoteAPIStatus.Success return if db_note is not None: self.Title = EvernoteNoteTitle(db_note) db_note_keys = db_note.keys() for key in [ 'content', 'guid', 'notebookGuid', 'updateSequenceNum', 'tagNames', 'tagGuids' ]: if not key in db_note_keys: log_error( "FATAL ERROR: Unable to find key %s in db note %s! \n%s" % (key, self.FullTitle, db_note_keys)) log( "Values: \n\n" + str({k: db_note[k] for k in db_note_keys}), 'EvernoteNotePrototypeInit') else: setattr(self, upperFirst(key), db_note[key]) self.TagNames = decode(self.TagNames) self.Content = decode(self.Content) self.process_tags() self.Status = EvernoteAPIStatus.Success return self.Title = EvernoteNoteTitle(title) self.Content = content self.Guid = guid self.NotebookGuid = notebookGuid self.UpdateSequenceNum = updateSequenceNum self.Status = EvernoteAPIStatus.Manual
def step(self, title=None, **kw): if self.hasActionInfo and self.isProgressCheck and title: title_str = ("%" + str(len('#' + str(self.max))) + "s: %s") % ('#' + str(self.count), title) progress_str = ' [%s]' % self.progress title_len = ANKNOTES.FORMATTING.LINE_LENGTH_TOTAL - 1 - 2 - len(progress_str) log_path = self.label + ('' if self.label.endswith('\\') else '-') + 'progress' if not self.__reported_progress: self.info.BannerHeader(filename=log_path, bh_wrap_filename=False) self.__reported_progress = True log(title_str.ljust(title_len) + progress_str, log_path, timestamp=False, do_print=self.__do_print, **kw) return self.isProgressCheck
def HandleUnicodeError(log_header, e, guid, title, action='', attempt=1, content=None, field=None, attempt_max=3, attempt_min=1): global lastUnicodeError object = "" e_type = e.__class__.__name__ is_unicode = e_type.find("Unicode") > -1 if is_unicode: content_type = e.object.__class__.__name__ object = e.object[e.start - 20:e.start + 20] elif not content: content = "Not Provided" content_type = "N/A" else: content_type = content.__class__.__name__ log_header += ': ' + e_type + ': {field}' + content_type + ( ' <%s>' % action if action else '') save_header = log_header.replace('{field}', '') + ': ' + title log_header = log_header.format(field='%s: ' % field if field else '') new_error = lastUnicodeError != save_header if is_unicode: return_val = 1 if attempt < attempt_max else -1 if new_error: log(save_header + '\n' + '-' * ANKNOTES.FORMATTING.LINE_LENGTH, 'unicode', replace_newline=False) lastUnicodeError = save_header log(ANKNOTES.FORMATTING.TIMESTAMP_PAD + '\t - ' + (('Field %s' % field if field else 'Unknown Field') + ': ').ljust(20) + str_safe(object), 'unicode', timestamp=False) else: return_val = 0 if attempt is 1 and content: log_dump(content, log_header, 'NonUnicodeErrors') if (new_error and attempt >= attempt_min) or not is_unicode: log_error(log_header + "\n - Error: %s\n - GUID: %s\n - Title: %s%s" % (str(e), guid, str_safe(title), '' if not object else "\n - Object: %s" % str_safe(object))) return return_val
def scalar(self, sql='1', *a, **kw): log_text = 'Call to DB.ankdb_scalar():' if not isinstance(self, ank_DB): log_text += '\n - Self: ' + pf(self) if a: log_text += '\n - Args: ' + pf(a) if kw: log_text += '\n - KWArgs: ' + pf(kw) last_query='<None>' if hasattr(self, 'ankdb_lastquery'): last_query = self.ankdb_lastquery if is_str(last_query): last_query = last_query[:50] else: last_query = pf(last_query) log_text += '\n - Last Query: ' + last_query log(log_text + '\n', 'sql\\ankdb_scalar') try: res = self.execute(sql, a, kw) except TypeError as e: log(" > ERROR with ankdb_scalar while executing query: %s\n > LAST QUERY: %s" % (str(e), last_query), 'sql\\ankdb_scalar', crosspost='sql\\ankdb_scalar-error') raise if not isinstance(res, sqlite.Cursor): log(' > Cursor: %s' % pf(res), 'sql\\ankdb_scalar') try: res = res.fetchone() except TypeError as e: log(" > ERROR with ankdb_scalar while fetching result: %s\n > LAST QUERY: %s" % (str(e), last_query), 'sql\\ankdb_scalar', crosspost='sql\\ankdb_scalar-error') raise log_blank('sql\\ankdb_scalar') if res: return res[0] return None
def displayInitialInfo(self, max=None, interval=None, automated=None, enabled=None, **kw): if max: self.__max = max if interval: self.__interval = interval if automated is not None: self.__automated = automated if enabled is not None: self.__enabled = enabled if self.emptyResults: if not self.Automated and self.__report_if_empty: log('report: ' + self.Aborted, self.Label) show_report(self.Aborted, blank_line_before=False) else: log('report: [automated] ' + self.Aborted, self.Label) return self.setStatus(EvernoteAPIStatus.EmptyRequest) if self.__enabled is False: log("Not starting - stopwatch.ActionInfo: enabled = false ", self.Label, do_print=self.__do_print) if not automated: show_report(self.ActionLine("Aborted", "Action has been disabled"), blank_line_before=False) return self.setStatus(EvernoteAPIStatus.Disabled) log(self.Initiated, do_print=self.__do_print) self.BannerHeader() return self.setStatus(EvernoteAPIStatus.Initialized)
def __init__(self, max=None, interval=100, info=None, infoStr=None, automated=None, begin=True, label=None, display_initial_info=None, max_allowed=None, do_print=False, **kw): """ :type info : ActionInfo """ args = DictCaseInsensitive(kw, locals(), delete='kw infoStr info max self') simple_label = False self.counts = EvernoteCounter() self.__interval = interval self.__reported_progress = False if not isinstance(max, int): if hasattr(max, '__len__'): max = len(max) else: max = None self.counts.max = -1 if max is not None: self.counts.max = max args.max = self.counts.max if is_str(info): # noinspection PyTypeChecker info = ActionInfo(info, **args) elif infoStr and not info: info = ActionInfo(infoStr, **args) elif label and not info: simple_label = True if display_initial_info is None: display_initial_info = False info = ActionInfo(label, **args) elif label: info.Label = label if self.counts.max > 0 and info and (info.Max is None or info.Max < 1): info.Max = max self.counts.max_allowed = self.counts.max if max_allowed is None else max_allowed self.__did_break = True self.__do_print = do_print self.__info = info self.__action_initialized = False self.__action_attempted = self.hasActionInfo and (display_initial_info is not False) if self.__action_attempted: if self.info is None: log("Unexpected; Timer '%s' has no ActionInfo instance" % label, do_print=True) else: self.__action_initialized = self.info.displayInitialInfo(**args) is EvernoteAPIStatus.Initialized if begin: self.reset(False) log_blank(filename='counters') log(self.counts.fullSummary(self.name + ': Start'), 'counters')
def HandleEDAMRateLimitError(e, strError): global latestEDAMRateLimit if not e.errorCode is EDAMErrorCode.RATE_LIMIT_REACHED: return False latestEDAMRateLimit = e.rateLimitDuration m, s = divmod(e.rateLimitDuration, 60) strError = "Error: Rate limit has been reached while %s\r\n" % strError strError += "Please retry your request in {} min".format("%d:%02d" % (m, s)) log_strError = " EDAMErrorCode.RATE_LIMIT_REACHED: " + strError.replace('\r\n', '\n') log_error(log_strError) log(log_strError, 'api') if EVERNOTE.API.EDAM_RATE_LIMIT_ERROR_HANDLING is EVERNOTE.API.RateLimitErrorHandling.AlertError: showInfo(strError) elif EVERNOTE.API.EDAM_RATE_LIMIT_ERROR_HANDLING is EVERNOTE.API.RateLimitErrorHandling.ToolTipError: show_tooltip(strError) return True
def unescape_text(title, try_decoding=False): title_orig = title global __text_escape_phrases if try_decoding: title = decode(title) try: for i in range(0, len(__text_escape_phrases), 2): title = title.replace(__text_escape_phrases[i + 1], __text_escape_phrases[i]) title = title.replace(u" ", u" ") except Exception: if try_decoding: raise UnicodeError title_new = unescape_text(title, True) log(title + '\n' + title_new + '\n\n', 'unicode') return title_new return title
def reset(self, reset_counter=True): # keep = [] # if self.counts: # keep = [self.counts.max, self.counts.max_allowed] # del self.__counts if reset_counter: log("Resetting counter", 'counters') if self.counts is None: self.counts = EvernoteCounter() else: self.counts.reset() # if keep: # self.counts.max = keep[0] # self.counts.max_allowed = keep[1] if not self.__stopped: self.stop() self.__stopped = None self.__start = self.__time()
def Report(self, subcount_created=0, subcount_updated=0): str_tips = [] self.counts.created.completed.subcount = subcount_created self.counts.updated.completed.subcount = subcount_updated str_tips += self.ReportSingle('were newly created', self.counts.created, self.info.str_value('created')) str_tips += self.ReportSingle('already exist and were updated', self.counts.updated, self.info.str_value('updated')) str_tips += self.ReportSingle('already exist but were unchanged', self.counts.skipped, process_subcounts=False) if self.counts.error: str_tips.append("%d Error(s) occurred " % self.counts.error.val) if self.status == EvernoteAPIStatus.ExceededLocalLimit: str_tips.append("Action was prematurely terminated because locally-defined limit of %d was exceeded." % self.counts.max_allowed) report_title = " > %s Complete" % self.info.Action if self.counts.total is 0: report_title += self.info.FormatLine(": No {r} were processed") show_report(report_title, self.ReportHeader, str_tips, blank_line_before=False, do_print=self.__do_print) log_blank('counters') log(self.counts.fullSummary(self.name + ': End'), 'counters')
def HandleEDAMRateLimitError(e, strError): global latestEDAMRateLimit if not e.errorCode is EDAMErrorCode.RATE_LIMIT_REACHED: return False latestEDAMRateLimit = e.rateLimitDuration m, s = divmod(e.rateLimitDuration, 60) strError = "Error: Rate limit has been reached while %s\r\n" % strError strError += "Please retry your request in {} min".format("%d:%02d" % (m, s)) log_strError = " EDAMErrorCode.RATE_LIMIT_REACHED: " + strError.replace( '\r\n', '\n') log_error(log_strError) log(log_strError, 'api') if EVERNOTE.API.EDAM_RATE_LIMIT_ERROR_HANDLING is EVERNOTE.API.RateLimitErrorHandling.AlertError: showInfo(strError) elif EVERNOTE.API.EDAM_RATE_LIMIT_ERROR_HANDLING is EVERNOTE.API.RateLimitErrorHandling.ToolTipError: show_tooltip(strError) return True
def step(self, title=None, **kw): if self.hasActionInfo and self.isProgressCheck and title: title_str = ("%" + str(len('#' + str(self.max))) + "s: %s") % ('#' + str(self.count), title) progress_str = ' [%s]' % self.progress title_len = ANKNOTES.FORMATTING.LINE_LENGTH_TOTAL - 1 - 2 - len( progress_str) log_path = self.label + ('' if self.label.endswith('\\') else '-') + 'progress' if not self.__reported_progress: self.info.BannerHeader(filename=log_path, bh_wrap_filename=False) self.__reported_progress = True log(title_str.ljust(title_len) + progress_str, log_path, timestamp=False, do_print=self.__do_print, **kw) return self.isProgressCheck
def __init__(self, title=None, content=None, guid=None, tags=None, notebookGuid=None, updateSequenceNum=None, whole_note=None, db_note=None): """ :type whole_note: evernote.edam.type.ttypes.Note :type db_note: sqlite3.dbapi2.Row """ self.Status = EvernoteAPIStatus.Uninitialized self.TagNames = tags if whole_note is not None: if self.TagNames is None: self.TagNames = whole_note.tagNames self.Title = EvernoteNoteTitle(whole_note) self.Content = whole_note.content self.Guid = whole_note.guid self.NotebookGuid = whole_note.notebookGuid self.UpdateSequenceNum = whole_note.updateSequenceNum self.Status = EvernoteAPIStatus.Success return if db_note is not None: self.Title = EvernoteNoteTitle(db_note) db_note_keys = db_note.keys() for key in ['content', 'guid', 'notebookGuid', 'updateSequenceNum', 'tagNames', 'tagGuids']: if not key in db_note_keys: log_error( "FATAL ERROR: Unable to find key %s in db note %s! \n%s" % (key, self.FullTitle, db_note_keys)) log("Values: \n\n" + str({k: db_note[k] for k in db_note_keys}), 'EvernoteNotePrototypeInit') else: setattr(self, upperFirst(key), db_note[key]) self.TagNames = decode(self.TagNames) self.Content = decode(self.Content) self.process_tags() self.Status = EvernoteAPIStatus.Success return self.Title = EvernoteNoteTitle(title) self.Content = content self.Guid = guid self.NotebookGuid = notebookGuid self.UpdateSequenceNum = updateSequenceNum self.Status = EvernoteAPIStatus.Manual
def Init(self, table='*', force=False): table = self._fmt_query_(table) log("Rebuilding tables: %s" % table, 'sql\\ankDB') if table == '*' or table == TABLES.EVERNOTE.NOTES: self.execute( """CREATE TABLE IF NOT EXISTS `{n}` ( `guid` TEXT NOT NULL UNIQUE, `nid` INTEGER NOT NULL DEFAULT -1, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `updated` INTEGER NOT NULL, `created` INTEGER NOT NULL, `updateSequenceNum` INTEGER NOT NULL, `notebookGuid` TEXT NOT NULL, `tagGuids` TEXT NOT NULL, `tagNames` TEXT NOT NULL, PRIMARY KEY(guid) );""") if table == '*' or table == TABLES.EVERNOTE.NOTES_HISTORY: self.execute( """CREATE TABLE IF NOT EXISTS `%s` ( `guid` TEXT NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `updated` INTEGER NOT NULL, `created` INTEGER NOT NULL, `updateSequenceNum` INTEGER NOT NULL, `notebookGuid` TEXT NOT NULL, `tagGuids` TEXT NOT NULL, `tagNames` TEXT NOT NULL)""" % TABLES.EVERNOTE.NOTES_HISTORY) if table == '*' or table == TABLES.TOC_AUTO: self.execute( """CREATE TABLE IF NOT EXISTS `%s` ( `root_title` TEXT NOT NULL UNIQUE, `contents` TEXT NOT NULL, `tagNames` TEXT NOT NULL, `notebookGuid` TEXT NOT NULL, PRIMARY KEY(root_title) );""" % TABLES.TOC_AUTO) if table == '*' or table == TABLES.NOTE_VALIDATION_QUEUE: self.execute( """CREATE TABLE IF NOT EXISTS `%s` ( `guid` TEXT, `title` TEXT NOT NULL, `contents` TEXT NOT NULL, `tagNames` TEXT NOT NULL DEFAULT ',,', `notebookGuid` TEXT, `validation_status` INTEGER NOT NULL DEFAULT 0, `validation_result` TEXT, `noteType` TEXT);""" % TABLES.NOTE_VALIDATION_QUEUE) if table == '*' or table == TABLES.SEE_ALSO: self.InitSeeAlso(force) if table == '*' or table == TABLES.EVERNOTE.TAGS: self.InitTags(force) if table == '*' or table == TABLES.EVERNOTE.NOTEBOOKS: self.InitNotebooks(force)
def __init__(self, path=None, text=None, timeout=0, init_db=True, table=None): self._table_ = table self.ankdb_lastquery = None self.echo = False if not init_db: return encpath = path if isinstance(encpath, unicode): encpath = encode(path) if path: log('Creating local ankDB instance from path: ' + path, 'sql\\ankDB') self._db = sqlite.connect(encpath, timeout=timeout) self._db.row_factory = sqlite.Row if text: self._db.text_factory = text self._path = path else: log('Creating local ankDB instance from Anki DB instance at: ' + mw.col.db._path, 'sql\\ankDB') self._db = mw.col.db._db """ :type : sqlite.Connection """ self._db.row_factory = sqlite.Row self._path = mw.col.db._path
def HandleUnicodeError(log_header, e, guid, title, action='', attempt=1, content=None, field=None, attempt_max=3, attempt_min=1): global lastUnicodeError object = "" e_type = e.__class__.__name__ is_unicode = e_type.find("Unicode") > -1 if is_unicode: content_type = e.object.__class__.__name__ object = e.object[e.start - 20:e.start + 20] elif not content: content = "Not Provided" content_type = "N/A" else: content_type = content.__class__.__name__ log_header += ': ' + e_type + ': {field}' + content_type + (' <%s>' % action if action else '') save_header = log_header.replace('{field}', '') + ': ' + title log_header = log_header.format(field='%s: ' % field if field else '') new_error = lastUnicodeError != save_header if is_unicode: return_val = 1 if attempt < attempt_max else -1 if new_error: log(save_header + '\n' + '-' * ANKNOTES.FORMATTING.LINE_LENGTH, 'unicode', replace_newline=False) lastUnicodeError = save_header log(ANKNOTES.FORMATTING.TIMESTAMP_PAD + '\t - ' + ( ('Field %s' % field if field else 'Unknown Field') + ': ').ljust(20) + str_safe(object), 'unicode', timestamp=False) else: return_val = 0 if attempt is 1 and content: log_dump(content, log_header, 'NonUnicodeErrors') if (new_error and attempt >= attempt_min) or not is_unicode: log_error(log_header + "\n - Error: %s\n - GUID: %s\n - Title: %s%s" % ( str(e), guid, str_safe(title), '' if not object else "\n - Object: %s" % str_safe(object))) return return_val
def __init__(self, max=None, interval=100, info=None, infoStr=None, automated=None, begin=True, label=None, display_initial_info=None, max_allowed=None, do_print=False, **kw): """ :type info : ActionInfo """ args = DictCaseInsensitive(kw, locals(), delete='kw infoStr info max self') simple_label = False self.counts = EvernoteCounter() self.__interval = interval self.__reported_progress = False if not isinstance(max, int): if hasattr(max, '__len__'): max = len(max) else: max = None self.counts.max = -1 if max is not None: self.counts.max = max args.max = self.counts.max if is_str(info): # noinspection PyTypeChecker info = ActionInfo(info, **args) elif infoStr and not info: info = ActionInfo(infoStr, **args) elif label and not info: simple_label = True if display_initial_info is None: display_initial_info = False info = ActionInfo(label, **args) elif label: info.Label = label if self.counts.max > 0 and info and (info.Max is None or info.Max < 1): info.Max = max self.counts.max_allowed = self.counts.max if max_allowed is None else max_allowed self.__did_break = True self.__do_print = do_print self.__info = info self.__action_initialized = False self.__action_attempted = self.hasActionInfo and (display_initial_info is not False) if self.__action_attempted: if self.info is None: log("Unexpected; Timer '%s' has no ActionInfo instance" % label, do_print=True) else: self.__action_initialized = self.info.displayInitialInfo( **args) is EvernoteAPIStatus.Initialized if begin: self.reset(False) log_blank(filename='counters') log(self.counts.fullSummary(self.name + ': Start'), 'counters')
def counts(self): if self.__counts is None: log("Init counter from property: " + repr(self.__counts), "counters") self.__counts = EvernoteCounter() return self.__counts
def InitTags(self, force=False): if_exists = " IF NOT EXISTS" if not force else "" log("Rebuilding %stags table" % ('*' if force else ''), 'sql\\ankDB') self.execute( """CREATE TABLE%s `%s` ( `guid` TEXT NOT NULL UNIQUE, `name` TEXT NOT NULL, `parentGuid` TEXT, `updateSequenceNum` INTEGER NOT NULL, PRIMARY KEY(guid) );""" % ( if_exists, TABLES.EVERNOTE.TAGS))