diff --git a/wakatime/__init__.py b/wakatime/__init__.py index 561e445..80aa44b 100644 --- a/wakatime/__init__.py +++ b/wakatime/__init__.py @@ -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: @@ -312,7 +314,7 @@ def send_action(project=None, branch=None, stats=None, key=None, targetFile=None if offline: if response is not None and 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: @@ -330,7 +332,7 @@ def send_action(project=None, branch=None, stats=None, key=None, targetFile=None if offline: if response is not None and 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): @@ -352,7 +354,7 @@ def send_action(project=None, branch=None, stats=None, key=None, targetFile=None if offline: if response is not None and 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/wakatime/queue.py b/wakatime/queue.py index e6ff1f4..06a2b6c 100644 --- a/wakatime/queue.py +++ b/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, 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': data.get('stats'), + 'misc': data.get('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/wakatime/stats.py b/wakatime/stats.py index 3f4b4b8..8afff9a 100644 --- a/wakatime/stats.py +++ b/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