From 3fe47846572032fc83d8300c596de6ded4f456a2 Mon Sep 17 00:00:00 2001 From: Alan Hamlett Date: Wed, 3 Oct 2018 00:46:21 -0700 Subject: [PATCH] upgrade wakatime-cli to v10.4.0 --- packages/wakatime/__about__.py | 2 +- packages/wakatime/compat.py | 6 +- packages/wakatime/heartbeat.py | 82 +++++++++++++++++++++++- packages/wakatime/projects/subversion.py | 12 ++-- 4 files changed, 93 insertions(+), 9 deletions(-) diff --git a/packages/wakatime/__about__.py b/packages/wakatime/__about__.py index 29babca..1bd0b4f 100644 --- a/packages/wakatime/__about__.py +++ b/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', '3', '0') +__version_info__ = ('10', '4', '0') __version__ = '.'.join(__version_info__) __author__ = 'Alan Hamlett' __author_email__ = 'alan@wakatime.com' diff --git a/packages/wakatime/compat.py b/packages/wakatime/compat.py index 744f3ee..18dc141 100644 --- a/packages/wakatime/compat.py +++ b/packages/wakatime/compat.py @@ -11,6 +11,7 @@ import codecs +import os import platform import subprocess import sys @@ -115,4 +116,7 @@ class Popen(subprocess.Popen): except AttributeError: pass kwargs['startupinfo'] = startupinfo - super(Popen, self).__init__(*args, **kwargs) + if 'env' not in kwargs: + kwargs['env'] = os.environ.copy() + kwargs['env']['LANG'] = 'en-US' if is_win else 'en_US.UTF-8' + subprocess.Popen.__init__(self, *args, **kwargs) diff --git a/packages/wakatime/heartbeat.py b/packages/wakatime/heartbeat.py index 73c25f5..7adbde0 100644 --- a/packages/wakatime/heartbeat.py +++ b/packages/wakatime/heartbeat.py @@ -10,8 +10,9 @@ import os import logging import re +from subprocess import PIPE -from .compat import u, json +from .compat import u, json, is_win, Popen from .exceptions import SkipHeartbeat from .project import get_project_info from .stats import get_file_stats @@ -85,6 +86,7 @@ class Heartbeat(object): return if self.type == 'file': self.entity = format_file_path(self.entity) + self._format_local_file() if not self._file_exists(): self.skip = u('File does not exist; ignoring this heartbeat.') return @@ -236,6 +238,84 @@ class Heartbeat(object): return (self.entity and os.path.isfile(self.entity) or self.args.local_file and os.path.isfile(self.args.local_file)) + def _format_local_file(self): + """When args.local_file empty on Windows, tries to map args.entity to a + unc path. + + Updates args.local_file in-place without returning anything. + """ + + if self.type != 'file': + return + + if not is_win: + return + + if self._file_exists(): + return + + self.args.local_file = self._to_unc_path(self.entity) + + def _to_unc_path(self, filepath): + drive, rest = self._splitdrive(filepath) + if not drive: + return filepath + + stdout = None + try: + stdout, stderr = Popen(['net', 'use'], stdout=PIPE, stderr=PIPE).communicate() + except OSError: + pass + else: + if stdout: + cols = None + for line in stdout.strip().splitlines()[1:]: + line = u(line) + if not line.strip(): + continue + if not cols: + cols = self._unc_columns(line) + continue + start, end = cols.get('local', (0, 0)) + if not start and not end: + break + local = line[start:end].strip().split(':')[0].upper() + if not local.isalpha(): + continue + if local == drive: + start, end = cols.get('remote', (0, 0)) + if not start and not end: + break + remote = line[start:end].strip() + return remote + rest + + return filepath + + def _unc_columns(self, line): + cols = {} + current_col = u('') + newcol = False + start, end = 0, 0 + for char in line: + if char.isalpha(): + if newcol: + cols[current_col.strip().lower()] = (start, end) + current_col = u('') + start = end + newcol = False + current_col += u(char) + else: + newcol = True + end += 1 + if start != end and current_col: + cols[current_col.strip().lower()] = (start, -1) + return cols + + def _splitdrive(self, filepath): + if filepath[1:2] != ':' or not filepath[0].isalpha(): + return None, filepath + return filepath[0].upper(), filepath[2:] + def _excluded_by_pattern(self): return should_exclude(self.entity, self.args.include, self.args.exclude) diff --git a/packages/wakatime/projects/subversion.py b/packages/wakatime/projects/subversion.py index d4f9572..ac6487b 100644 --- a/packages/wakatime/projects/subversion.py +++ b/packages/wakatime/projects/subversion.py @@ -70,17 +70,17 @@ class Subversion(BaseProject): if not self._is_mac() or self._has_xcode_tools(): stdout = None try: - os.environ['LANG'] = 'en_US' - stdout, stderr = Popen([ - self._find_binary(), 'info', os.path.realpath(path) - ], stdout=PIPE, stderr=PIPE).communicate() + stdout, stderr = Popen( + [self._find_binary(), 'info', os.path.realpath(path)], + stdout=PIPE, + stderr=PIPE, + ).communicate() except OSError: pass else: if stdout: for line in stdout.splitlines(): - line = u(line) - line = line.split(': ', 1) + line = u(line).split(': ', 1) if len(line) == 2: info[line[0]] = line[1] return info