From e35c74e5b4ab487d9a83626700ba341bb60165b7 Mon Sep 17 00:00:00 2001 From: Alan Hamlett Date: Thu, 4 Jan 2018 23:35:46 -0800 Subject: [PATCH] upgrade wakatime-cli to v10.1.0 --- plugin/packages/wakatime/__about__.py | 2 +- plugin/packages/wakatime/api.py | 6 +++ plugin/packages/wakatime/arguments.py | 54 ++++++++++++++----- plugin/packages/wakatime/heartbeat.py | 20 ++++--- plugin/packages/wakatime/logger.py | 2 +- .../packages/wakatime/projects/projectfile.py | 23 +++----- plugin/packages/wakatime/utils.py | 12 +++++ 7 files changed, 81 insertions(+), 38 deletions(-) diff --git a/plugin/packages/wakatime/__about__.py b/plugin/packages/wakatime/__about__.py index 02030a3..b680411 100644 --- a/plugin/packages/wakatime/__about__.py +++ b/plugin/packages/wakatime/__about__.py @@ -1,7 +1,7 @@ __title__ = 'wakatime' __description__ = 'Common interface to the WakaTime api.' __url__ = 'https://github.com/wakatime/wakatime' -__version_info__ = ('10', '0', '5') +__version_info__ = ('10', '1', '0') __version__ = '.'.join(__version_info__) __author__ = 'Alan Hamlett' __author_email__ = 'alan@wakatime.com' diff --git a/plugin/packages/wakatime/api.py b/plugin/packages/wakatime/api.py index 2728c60..a6d0b4c 100644 --- a/plugin/packages/wakatime/api.py +++ b/plugin/packages/wakatime/api.py @@ -144,6 +144,11 @@ def send_heartbeats(heartbeats, args, configs, use_ntlm_proxy=False): _process_server_results(heartbeats, code, content, results, args, configs) session_cache.save(session) return SUCCESS + else: + log.debug({ + 'response_code': code, + 'response_text': content, + }) if should_try_ntlm: return send_heartbeats(heartbeats, args, configs, use_ntlm_proxy=True) @@ -157,6 +162,7 @@ def send_heartbeats(heartbeats, args, configs, use_ntlm_proxy=False): def _process_server_results(heartbeats, code, content, results, args, configs): log.debug({ 'response_code': code, + 'results': results, }) for i in range(len(results)): diff --git a/plugin/packages/wakatime/arguments.py b/plugin/packages/wakatime/arguments.py index 81e24fe..a2ff819 100644 --- a/plugin/packages/wakatime/arguments.py +++ b/plugin/packages/wakatime/arguments.py @@ -103,12 +103,17 @@ def parse_arguments(): 'auto-detected language') parser.add_argument('--hostname', dest='hostname', action=StoreWithoutQuotes, help='hostname of '+ 'current machine.') - parser.add_argument('--disableoffline', dest='offline', + parser.add_argument('--disable-offline', dest='offline', action='store_false', help='disables offline time logging instead of queuing logged time') + parser.add_argument('--disableoffline', dest='offline_deprecated', + action='store_true', help=argparse.SUPPRESS) + parser.add_argument('--hide-filenames', dest='hide_filenames', + action='store_true', + help='obfuscate filenames; will not send file names to api') parser.add_argument('--hidefilenames', dest='hidefilenames', action='store_true', - help='obfuscate file names; will not send file names to api') + help=argparse.SUPPRESS) parser.add_argument('--exclude', dest='exclude', action='append', help='filename patterns to exclude from logging; POSIX regex '+ 'syntax; can be used more than once') @@ -116,15 +121,24 @@ def parse_arguments(): help='filename patterns to log; when used in combination with '+ '--exclude, files matching include will still be logged; '+ 'POSIX regex syntax; can be used more than once') + parser.add_argument('--include-only-with-project-file', + dest='include_only_with_project_file', + action='store_true', + help='disables tracking folders unless they contain '+ + 'a .wakatime-project file; defaults to false') parser.add_argument('--ignore', dest='ignore', action='append', help=argparse.SUPPRESS) parser.add_argument('--extra-heartbeats', dest='extra_heartbeats', action='store_true', help='reads extra heartbeats from STDIN as a JSON array until EOF') - parser.add_argument('--logfile', dest='logfile', action=StoreWithoutQuotes, + parser.add_argument('--log-file', dest='log_file', action=StoreWithoutQuotes, help='defaults to ~/.wakatime.log') - parser.add_argument('--apiurl', dest='api_url', action=StoreWithoutQuotes, + parser.add_argument('--logfile', dest='logfile', action=StoreWithoutQuotes, + help=argparse.SUPPRESS) + parser.add_argument('--api-url', dest='api_url', action=StoreWithoutQuotes, help='heartbeats api url; for debugging with a local server') + parser.add_argument('--apiurl', dest='apiurl', action=StoreWithoutQuotes, + help=argparse.SUPPRESS) parser.add_argument('--timeout', dest='timeout', type=int, action=StoreWithoutQuotes, help='number of seconds to wait when sending heartbeats to api; '+ 'defaults to 60 seconds') @@ -194,6 +208,8 @@ def parse_arguments(): args.exclude.append(pattern) except TypeError: # pragma: nocover pass + if not args.include_only_with_project_file and configs.has_option('settings', 'include_only_with_project_file'): + args.include_only_with_project_file = configs.get('settings', 'include_only_with_project_file') if not args.include: args.include = [] if configs.has_option('settings', 'include'): @@ -203,18 +219,26 @@ def parse_arguments(): args.include.append(pattern) except TypeError: # pragma: nocover pass - if args.hidefilenames: - args.hidefilenames = ['.*'] + if not args.hide_filenames and args.hidefilenames: + args.hide_filenames = args.hidefilenames + if args.hide_filenames: + args.hide_filenames = ['.*'] else: - args.hidefilenames = [] + args.hide_filenames = [] + option = None if configs.has_option('settings', 'hidefilenames'): option = configs.get('settings', 'hidefilenames') + if configs.has_option('settings', 'hide_filenames'): + option = configs.get('settings', 'hide_filenames') + if option is not None: if option.strip().lower() == 'true': - args.hidefilenames = ['.*'] + args.hide_filenames = ['.*'] elif option.strip().lower() != 'false': for pattern in option.split("\n"): if pattern.strip() != '': - args.hidefilenames.append(pattern) + args.hide_filenames.append(pattern) + if args.offline_deprecated: + args.offline = False if args.offline and configs.has_option('settings', 'offline'): args.offline = configs.getboolean('settings', 'offline') if not args.proxy and configs.has_option('settings', 'proxy'): @@ -235,11 +259,15 @@ def parse_arguments(): args.verbose = configs.getboolean('settings', 'verbose') if not args.verbose and configs.has_option('settings', 'debug'): args.verbose = configs.getboolean('settings', 'debug') - if not args.logfile and configs.has_option('settings', 'logfile'): - args.logfile = configs.get('settings', 'logfile') - if not args.logfile and os.environ.get('WAKATIME_HOME'): + if not args.log_file and args.logfile: + args.log_file = args.logfile + if not args.log_file and configs.has_option('settings', 'log_file'): + args.log_file = configs.get('settings', 'log_file') + if not args.log_file and os.environ.get('WAKATIME_HOME'): home = os.environ.get('WAKATIME_HOME') - args.logfile = os.path.join(os.path.expanduser(home), '.wakatime.log') + args.log_file = os.path.join(os.path.expanduser(home), '.wakatime.log') + if not args.api_url and args.apiurl: + args.api_url = args.apiurl if not args.api_url and configs.has_option('settings', 'api_url'): args.api_url = configs.get('settings', 'api_url') if not args.timeout and configs.has_option('settings', 'timeout'): diff --git a/plugin/packages/wakatime/heartbeat.py b/plugin/packages/wakatime/heartbeat.py index 6b93632..c0b2e02 100644 --- a/plugin/packages/wakatime/heartbeat.py +++ b/plugin/packages/wakatime/heartbeat.py @@ -14,7 +14,7 @@ import re from .compat import u, json from .project import get_project_info from .stats import get_file_stats -from .utils import get_user_agent, should_exclude, format_file_path +from .utils import get_user_agent, should_exclude, format_file_path, find_project_file log = logging.getLogger('WakaTime') @@ -66,9 +66,12 @@ class Heartbeat(object): return if self.type == 'file': self.entity = format_file_path(self.entity) - if self.type == 'file' and (not self.entity or not os.path.isfile(self.entity)): - self.skip = u('File does not exist; ignoring this heartbeat.') - return + if not self.entity or not os.path.isfile(self.entity): + self.skip = u('File does not exist; ignoring this heartbeat.') + return + if self._excluded_by_missing_project_file(): + self.skip = u('Skipping because missing .wakatime-project file in parent path.') + return project, branch = get_project_info(configs, self, data) self.project = project @@ -103,7 +106,7 @@ class Heartbeat(object): Returns a Heartbeat. """ - if not self.args.hidefilenames: + if not self.args.hide_filenames: return self if self.entity is None: @@ -112,7 +115,7 @@ class Heartbeat(object): if self.type != 'file': return self - for pattern in self.args.hidefilenames: + for pattern in self.args.hide_filenames: try: compiled = re.compile(pattern, re.IGNORECASE) if compiled.search(self.entity): @@ -183,6 +186,11 @@ class Heartbeat(object): def _excluded_by_pattern(self): return should_exclude(self.entity, self.args.include, self.args.exclude) + def _excluded_by_missing_project_file(self): + if not self.args.include_only_with_project_file: + return False + return find_project_file(self.entity) is None + def __repr__(self): return self.json() diff --git a/plugin/packages/wakatime/logger.py b/plugin/packages/wakatime/logger.py index 2883ad7..9bb51fe 100644 --- a/plugin/packages/wakatime/logger.py +++ b/plugin/packages/wakatime/logger.py @@ -75,7 +75,7 @@ def setup_logging(args, version): for handler in logger.handlers: logger.removeHandler(handler) set_log_level(logger, args) - logfile = args.logfile + logfile = args.log_file if not logfile: logfile = '~/.wakatime.log' handler = logging.FileHandler(os.path.expanduser(logfile)) diff --git a/plugin/packages/wakatime/projects/projectfile.py b/plugin/packages/wakatime/projects/projectfile.py index 9ca6d80..73d5cc3 100644 --- a/plugin/packages/wakatime/projects/projectfile.py +++ b/plugin/packages/wakatime/projects/projectfile.py @@ -12,11 +12,11 @@ """ import logging -import os import sys from .base import BaseProject from ..compat import u, open +from ..utils import find_project_file log = logging.getLogger('WakaTime') @@ -25,7 +25,7 @@ log = logging.getLogger('WakaTime') class ProjectFile(BaseProject): def process(self): - self.config = self._find_config(self.path) + self.config = find_project_file(self.path) self._project_name = None self._project_branch = None @@ -33,13 +33,13 @@ class ProjectFile(BaseProject): try: with open(self.config, 'r', encoding='utf-8') as fh: - self._project_name = u(fh.readline().strip()) - self._project_branch = u(fh.readline().strip()) + self._project_name = u(fh.readline().strip()) or None + self._project_branch = u(fh.readline().strip()) or None except UnicodeDecodeError: # pragma: nocover try: with open(self.config, 'r', encoding=sys.getfilesystemencoding()) as fh: - self._project_name = u(fh.readline().strip()) - self._project_branch = u(fh.readline().strip()) + self._project_name = u(fh.readline().strip()) or None + self._project_branch = u(fh.readline().strip()) or None except: log.traceback(logging.WARNING) except IOError: # pragma: nocover @@ -53,14 +53,3 @@ class ProjectFile(BaseProject): def branch(self): return self._project_branch - - def _find_config(self, path): - path = os.path.realpath(path) - if os.path.isfile(path): - path = os.path.split(path)[0] - if os.path.isfile(os.path.join(path, '.wakatime-project')): - return os.path.join(path, '.wakatime-project') - split_path = os.path.split(path) - if split_path[1] == '': - return None - return self._find_config(split_path[0]) diff --git a/plugin/packages/wakatime/utils.py b/plugin/packages/wakatime/utils.py index f85ab1f..d7a3bc6 100644 --- a/plugin/packages/wakatime/utils.py +++ b/plugin/packages/wakatime/utils.py @@ -82,3 +82,15 @@ def format_file_path(filepath): def get_hostname(args): return args.hostname or socket.gethostname() + + +def find_project_file(path): + path = os.path.realpath(path) + if os.path.isfile(path): + path = os.path.split(path)[0] + if os.path.isfile(os.path.join(path, '.wakatime-project')): + return os.path.join(path, '.wakatime-project') + split_path = os.path.split(path) + if split_path[1] == '': + return None + return find_project_file(split_path[0])