diff --git a/plugin/packages/wakatime/__about__.py b/plugin/packages/wakatime/__about__.py index 1f3b4d6..13b3578 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__ = ('4', '1', '0') +__version_info__ = ('4', '1', '1') __version__ = '.'.join(__version_info__) __author__ = 'Alan Hamlett' __author_email__ = 'alan@wakatime.com' diff --git a/plugin/packages/wakatime/cli.py b/plugin/packages/wakatime/cli.py index 493fcf4..6144906 100644 --- a/plugin/packages/wakatime/cli.py +++ b/plugin/packages/wakatime/cli.py @@ -22,7 +22,7 @@ sys.path.insert(0, package_folder) # import local wakatime package try: import wakatime -except TypeError: +except (TypeError, ImportError): # on Windows, non-ASCII characters in import path can be fixed using # the script path from sys.argv[0]. # More info at https://github.com/wakatime/wakatime/issues/32 diff --git a/plugin/packages/wakatime/compat.py b/plugin/packages/wakatime/compat.py index ba8f107..5dbcfaa 100644 --- a/plugin/packages/wakatime/compat.py +++ b/plugin/packages/wakatime/compat.py @@ -20,6 +20,8 @@ is_py3 = (sys.version_info[0] == 3) if is_py2: # pragma: nocover def u(text): + if text is None: + return None try: return text.decode('utf-8') except: @@ -34,6 +36,8 @@ if is_py2: # pragma: nocover elif is_py3: # pragma: nocover def u(text): + if text is None: + return None if isinstance(text, bytes): return text.decode('utf-8') return str(text) diff --git a/plugin/packages/wakatime/languages/__init__.py b/plugin/packages/wakatime/languages/__init__.py index 1795880..1982778 100644 --- a/plugin/packages/wakatime/languages/__init__.py +++ b/plugin/packages/wakatime/languages/__init__.py @@ -10,6 +10,7 @@ """ import logging +import sys import traceback from ..compat import u, open, import_module @@ -53,8 +54,16 @@ class TokenParser(object): def _extract_tokens(self): if self.lexer: - with open(self.source_file, 'r', encoding='utf-8') as fh: - return self.lexer.get_tokens_unprocessed(fh.read(512000)) + try: + with open(self.source_file, 'r', encoding='utf-8') as fh: + return self.lexer.get_tokens_unprocessed(fh.read(512000)) + except: + pass + try: + with open(self.source_file, 'r', encoding=sys.getfilesystemencoding()) as fh: + return self.lexer.get_tokens_unprocessed(fh.read(512000)) + except: + pass return [] def _save_dependency(self, dep, truncate=False, separator=None, diff --git a/plugin/packages/wakatime/offlinequeue.py b/plugin/packages/wakatime/offlinequeue.py index 19e55a0..ab05189 100644 --- a/plugin/packages/wakatime/offlinequeue.py +++ b/plugin/packages/wakatime/offlinequeue.py @@ -21,6 +21,8 @@ try: except ImportError: HAS_SQL = False +from .compat import u + log = logging.getLogger('WakaTime') @@ -50,16 +52,16 @@ class Queue(object): try: conn, c = self.connect() heartbeat = { - 'file': data.get('entity'), + 'file': u(data.get('entity')), 'time': data.get('time'), - 'project': data.get('project'), - 'branch': data.get('branch'), + 'project': u(data.get('project')), + 'branch': u(data.get('branch')), 'is_write': 1 if data.get('is_write') else 0, - 'stats': stats, - 'misc': misc, - 'plugin': plugin, + 'stats': u(stats), + 'misc': u(misc), + 'plugin': u(plugin), } - c.execute('INSERT INTO heartbeat VALUES (:file,:time,:project,:branch,:is_write,:stats,:misc,:plugin)', heartbeat) + c.execute(u('INSERT INTO heartbeat VALUES (:file,:time,:project,:branch,:is_write,:stats,:misc,:plugin)'), heartbeat) conn.commit() conn.close() except sqlite3.Error: @@ -90,14 +92,14 @@ class Queue(object): 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]) + values.append(u(row[index])) else: clauses.append('{0} IS NULL'.format(row_name)) index += 1 if len(values) > 0: - c.execute('DELETE FROM heartbeat WHERE {0}'.format(' AND '.join(clauses)), values) + c.execute(u('DELETE FROM heartbeat WHERE {0}').format(u(' AND ').join(clauses)), values) else: - c.execute('DELETE FROM heartbeat WHERE {0}'.format(' AND '.join(clauses))) + c.execute(u('DELETE FROM heartbeat WHERE {0}').format(u(' AND ').join(clauses))) conn.commit() if row is not None: heartbeat = { diff --git a/plugin/packages/wakatime/packages/requests/certs.py b/plugin/packages/wakatime/packages/requests/certs.py index 47cc228..5463f38 100644 --- a/plugin/packages/wakatime/packages/requests/certs.py +++ b/plugin/packages/wakatime/packages/requests/certs.py @@ -21,12 +21,8 @@ except ImportError: """Return the preferred certificate bundle.""" # vendored bundle inside Requests is_py3 = (sys.version_info[0] == 3) - certdir = os.path.dirname( - __file__ - if is_py3 else - __file__.decode(sys.getfilesystemencoding()) - ) - return os.path.join(certdir, 'cacert.pem') + cacert = os.path.join(os.path.dirname(__file__), 'cacert.pem') + return cacert.encode('utf-8') if is_py3 else cacert if __name__ == '__main__': print(where()) diff --git a/plugin/packages/wakatime/projects/git.py b/plugin/packages/wakatime/projects/git.py index cf4d51e..db6c3f2 100644 --- a/plugin/packages/wakatime/projects/git.py +++ b/plugin/packages/wakatime/projects/git.py @@ -11,6 +11,7 @@ import logging import os +import sys from .base import BaseProject from ..compat import u, open @@ -38,8 +39,14 @@ class Git(BaseProject): try: with open(head, 'r', encoding='utf-8') as fh: return u(fh.readline().strip().rsplit('/', 1)[-1]) + except UnicodeDecodeError: + try: + with open(head, 'r', encoding=sys.getfilesystemencoding()) as fh: + return u(fh.readline().strip().rsplit('/', 1)[-1]) + except: + log.exception("Exception:") except IOError: - pass + log.exception("Exception:") return None def _project_base(self): diff --git a/plugin/packages/wakatime/projects/mercurial.py b/plugin/packages/wakatime/projects/mercurial.py index 5f222ee..11e15fa 100644 --- a/plugin/packages/wakatime/projects/mercurial.py +++ b/plugin/packages/wakatime/projects/mercurial.py @@ -11,6 +11,7 @@ import logging import os +import sys from .base import BaseProject from ..compat import u, open @@ -36,8 +37,14 @@ class Mercurial(BaseProject): try: with open(branch_file, 'r', encoding='utf-8') as fh: return u(fh.readline().strip().rsplit('/', 1)[-1]) + except UnicodeDecodeError: + try: + with open(branch_file, 'r', encoding=sys.getfilesystemencoding()) as fh: + return u(fh.readline().strip().rsplit('/', 1)[-1]) + except: + log.exception("Exception:") except IOError: - pass + log.exception("Exception:") return u('default') def _find_hg_config_dir(self, path): diff --git a/plugin/packages/wakatime/projects/subversion.py b/plugin/packages/wakatime/projects/subversion.py index e1ed061..cfc8233 100644 --- a/plugin/packages/wakatime/projects/subversion.py +++ b/plugin/packages/wakatime/projects/subversion.py @@ -46,13 +46,13 @@ class Subversion(BaseProject): '/usr/local/bin/svn', ] for location in locations: - with open(os.devnull, 'wb') as DEVNULL: - try: + try: + with open(os.devnull, 'wb') as DEVNULL: Popen([location, '--version'], stdout=DEVNULL, stderr=DEVNULL) self.binary_location = location return location - except: - pass + except: + pass self.binary_location = 'svn' return 'svn' diff --git a/plugin/packages/wakatime/projects/wakatime_project_file.py b/plugin/packages/wakatime/projects/wakatime_project_file.py index 97a4652..3b1b8db 100644 --- a/plugin/packages/wakatime/projects/wakatime_project_file.py +++ b/plugin/packages/wakatime/projects/wakatime_project_file.py @@ -13,6 +13,7 @@ import logging import os +import sys from .base import BaseProject from ..compat import u, open @@ -34,6 +35,13 @@ class WakaTimeProjectFile(BaseProject): with open(self.config, 'r', encoding='utf-8') as fh: self._project_name = u(fh.readline().strip()) self._project_branch = u(fh.readline().strip()) + except UnicodeDecodeError: + 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()) + except: + log.exception("Exception:") except IOError: log.exception("Exception:") diff --git a/plugin/packages/wakatime/stats.py b/plugin/packages/wakatime/stats.py index b04e7ac..db424c0 100644 --- a/plugin/packages/wakatime/stats.py +++ b/plugin/packages/wakatime/stats.py @@ -144,7 +144,12 @@ def number_lines_in_file(file_name): for line in fh: lines += 1 except: - return None + try: + with open(file_name, 'r', encoding=sys.getfilesystemencoding()) as fh: + for line in fh: + lines += 1 + except: + return None return lines @@ -180,5 +185,9 @@ def get_file_contents(file_name): with open(file_name, 'r', encoding='utf-8') as fh: text = fh.read(512000) except: - pass + try: + with open(file_name, 'r', encoding=sys.getfilesystemencoding()) as fh: + text = fh.read(512000) + except: + log.exception("Exception:") return text