From 8b2357ec783c55da3080cdd933c4e07bb15f747c Mon Sep 17 00:00:00 2001 From: Alan Hamlett Date: Mon, 22 Dec 2014 00:55:59 -0600 Subject: [PATCH] upgrade wakatime-cli to v2.1.11 to fix offline logging --- plugin/packages/wakatime/HISTORY.rst | 6 +++ plugin/packages/wakatime/LICENSE | 6 ++- plugin/packages/wakatime/wakatime/__init__.py | 43 ++++++++++--------- plugin/packages/wakatime/wakatime/queue.py | 38 ++++++++-------- plugin/packages/wakatime/wakatime/stats.py | 2 + 5 files changed, 54 insertions(+), 41 deletions(-) diff --git a/plugin/packages/wakatime/HISTORY.rst b/plugin/packages/wakatime/HISTORY.rst index 64ceb74..843cfe3 100644 --- a/plugin/packages/wakatime/HISTORY.rst +++ b/plugin/packages/wakatime/HISTORY.rst @@ -3,6 +3,12 @@ History ------- +2.1.11 (2014-12-22) ++++++++++++++++++++ + +- fix offline logging when response from api is None + + 2.1.10 (2014-12-15) +++++++++++++++++++ diff --git a/plugin/packages/wakatime/LICENSE b/plugin/packages/wakatime/LICENSE index 4383c5e..08bb777 100644 --- a/plugin/packages/wakatime/LICENSE +++ b/plugin/packages/wakatime/LICENSE @@ -1,4 +1,6 @@ -Copyright (c) 2013 Alan Hamlett https://wakatime.com +BSD 3-Clause License + +Copyright (c) 2014 by the respective authors (see AUTHORS file). All rights reserved. Redistribution and use in source and binary forms, with or without @@ -12,7 +14,7 @@ modification, are permitted provided that the following conditions are met: in the documentation and/or other materials provided with the distribution. -* Neither the names of Wakatime or WakaTime, nor the names of its +* Neither the names of WakaTime, nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. diff --git a/plugin/packages/wakatime/wakatime/__init__.py b/plugin/packages/wakatime/wakatime/__init__.py index 561e445..d13f109 100644 --- a/plugin/packages/wakatime/wakatime/__init__.py +++ b/plugin/packages/wakatime/wakatime/__init__.py @@ -13,7 +13,7 @@ from __future__ import print_function __title__ = 'wakatime' -__version__ = '2.1.10' +__version__ = '2.1.11' __author__ = 'Alan Hamlett' __license__ = 'BSD' __copyright__ = 'Copyright 2014 Alan Hamlett' @@ -142,14 +142,14 @@ def parseArguments(argv): description='Common interface for the WakaTime api.') parser.add_argument('--file', dest='targetFile', metavar='file', action=FileAction, required=True, - help='absolute path to file for current action') + help='absolute path to file for current heartbeat') parser.add_argument('--time', dest='timestamp', metavar='time', type=float, help='optional floating-point unix epoch timestamp; '+ 'uses current time by default') parser.add_argument('--write', dest='isWrite', action='store_true', - help='note action was triggered from writing to a file') + help='note heartbeat was triggered from writing to a file') parser.add_argument('--plugin', dest='plugin', help='optional text editor plugin name and version '+ 'for User-Agent header') @@ -251,7 +251,7 @@ def get_user_agent(plugin): return user_agent -def send_action(project=None, branch=None, stats=None, key=None, targetFile=None, +def send_action(project=None, branch=None, stats={}, key=None, targetFile=None, timestamp=None, isWrite=None, plugin=None, offline=None, hidefilenames=None, **kwargs): url = 'https://wakatime.com/api/v1/actions' @@ -270,6 +270,8 @@ def send_action(project=None, branch=None, stats=None, key=None, targetFile=None data['lines'] = stats['lines'] if stats.get('language'): data['language'] = stats['language'] + if stats.get('dependencies'): + data['dependencies'] = stats['dependencies'] if isWrite: data['is_write'] = isWrite if project: @@ -310,9 +312,9 @@ def send_action(project=None, branch=None, stats=None, key=None, targetFile=None if log.isEnabledFor(logging.DEBUG): exception_data['traceback'] = traceback.format_exc() if offline: - if response is not None and response.getcode() != 400: + if response is None or response.getcode() != 400: queue = Queue() - queue.push(data, plugin) + queue.push(data, json.dumps(stats), plugin) if log.isEnabledFor(logging.DEBUG): log.warn(exception_data) if response is not None and response.getcode() in ALWAYS_LOG_CODES: @@ -328,9 +330,9 @@ def send_action(project=None, branch=None, stats=None, key=None, targetFile=None if log.isEnabledFor(logging.DEBUG): exception_data['traceback'] = traceback.format_exc() if offline: - if response is not None and response.getcode() != 400: + if response is None or response.getcode() != 400: queue = Queue() - queue.push(data, plugin) + queue.push(data, json.dumps(stats), plugin) if 'unknown url type: https' in u(sys.exc_info()[1]): log.error(exception_data) elif log.isEnabledFor(logging.DEBUG): @@ -350,9 +352,9 @@ def send_action(project=None, branch=None, stats=None, key=None, targetFile=None response_code = response.getcode() if response is not None else None response_content = response.read() if response is not None else None if offline: - if response is not None and response.getcode() != 400: + if response is None or response.getcode() != 400: queue = Queue() - queue.push(data, plugin) + queue.push(data, json.dumps(stats), plugin) if log.isEnabledFor(logging.DEBUG): log.warn({ 'response_code': response_code, @@ -407,16 +409,17 @@ def main(argv=None): ): queue = Queue() while True: - action = queue.pop() - if action is None: + heartbeat = queue.pop() + if heartbeat is None: break - sent = send_action(project=action['project'], - targetFile=action['file'], - timestamp=action['time'], - branch=action['branch'], - stats={'language': action['language'], 'lines': action['lines']}, - key=args.key, isWrite=action['is_write'], - plugin=action['plugin'], + sent = send_action(project=heartbeat['project'], + targetFile=heartbeat['file'], + timestamp=heartbeat['time'], + branch=heartbeat['branch'], + stats=json.loads(heartbeat['stats']), + key=args.key, + isWrite=heartbeat['is_write'], + plugin=heartbeat['plugin'], offline=args.offline, hidefilenames=args.hidefilenames) if not sent: @@ -426,5 +429,5 @@ def main(argv=None): return 102 # api error else: - log.debug('File does not exist; ignoring this action.') + log.debug('File does not exist; ignoring this heartbeat.') return 0 diff --git a/plugin/packages/wakatime/wakatime/queue.py b/plugin/packages/wakatime/wakatime/queue.py index e6ff1f4..2f57ab3 100644 --- a/plugin/packages/wakatime/wakatime/queue.py +++ b/plugin/packages/wakatime/wakatime/queue.py @@ -32,35 +32,35 @@ class Queue(object): def connect(self): conn = sqlite3.connect(self.DB_FILE) c = conn.cursor() - c.execute('''CREATE TABLE IF NOT EXISTS action ( + c.execute('''CREATE TABLE IF NOT EXISTS heartbeat ( file text, time real, project text, - language text, - lines integer, branch text, is_write integer, + stats text, + misc text, plugin text) ''') return (conn, c) - def push(self, data, plugin): + def push(self, data, stats, plugin, misc=None): if not HAS_SQL: return try: conn, c = self.connect() - action = { + heartbeat = { 'file': data.get('file'), 'time': data.get('time'), 'project': data.get('project'), - 'language': data.get('language'), - 'lines': data.get('lines'), 'branch': data.get('branch'), 'is_write': 1 if data.get('is_write') else 0, + 'stats': stats, + 'misc': misc, 'plugin': plugin, } - c.execute('INSERT INTO action VALUES (:file,:time,:project,:language,:lines,:branch,:is_write,:plugin)', action) + c.execute('INSERT INTO heartbeat VALUES (:file,:time,:project,:branch,:is_write,:stats,:misc,:plugin)', heartbeat) conn.commit() conn.close() except sqlite3.Error: @@ -72,7 +72,7 @@ class Queue(object): return None tries = 3 wait = 0.1 - action = None + heartbeat = None try: conn, c = self.connect() except sqlite3.Error: @@ -82,13 +82,13 @@ class Queue(object): while loop and tries > -1: try: c.execute('BEGIN IMMEDIATE') - c.execute('SELECT * FROM action LIMIT 1') + c.execute('SELECT * FROM heartbeat LIMIT 1') row = c.fetchone() if row is not None: values = [] clauses = [] index = 0 - for row_name in ['file', 'time', 'project', 'language', 'lines', 'branch', 'is_write']: + for row_name in ['file', 'time', 'project', 'branch', 'is_write']: if row[index] is not None: clauses.append('{0}=?'.format(row_name)) values.append(row[index]) @@ -96,19 +96,19 @@ class Queue(object): clauses.append('{0} IS NULL'.format(row_name)) index += 1 if len(values) > 0: - c.execute('DELETE FROM action WHERE {0}'.format(' AND '.join(clauses)), values) + c.execute('DELETE FROM heartbeat WHERE {0}'.format(' AND '.join(clauses)), values) else: - c.execute('DELETE FROM action WHERE {0}'.format(' AND '.join(clauses))) + c.execute('DELETE FROM heartbeat WHERE {0}'.format(' AND '.join(clauses))) conn.commit() if row is not None: - action = { + heartbeat = { 'file': row[0], 'time': row[1], 'project': row[2], - 'language': row[3], - 'lines': row[4], - 'branch': row[5], - 'is_write': True if row[6] is 1 else False, + 'branch': row[3], + 'is_write': True if row[4] is 1 else False, + 'stats': row[5], + 'misc': row[6], 'plugin': row[7], } loop = False @@ -120,4 +120,4 @@ class Queue(object): conn.close() except sqlite3.Error: log.debug(traceback.format_exc()) - return action + return heartbeat diff --git a/plugin/packages/wakatime/wakatime/stats.py b/plugin/packages/wakatime/wakatime/stats.py index 3f4b4b8..8afff9a 100644 --- a/plugin/packages/wakatime/wakatime/stats.py +++ b/plugin/packages/wakatime/wakatime/stats.py @@ -89,8 +89,10 @@ def number_lines_in_file(file_name): def get_file_stats(file_name): + dependencies = [] stats = { 'language': guess_language(file_name), + 'dependencies': dependencies, 'lines': number_lines_in_file(file_name), } return stats