upgrade wakatime cli to v4.0.4

This commit is contained in:
Alan Hamlett 2015-03-09 15:23:29 -07:00
parent 307029c37a
commit 440e33b8b7
1087 changed files with 21913 additions and 587 deletions

View file

@ -24,7 +24,7 @@ from os.path import expanduser, dirname, basename, realpath, join
ACTION_FREQUENCY = 2 ACTION_FREQUENCY = 2
ST_VERSION = int(sublime.version()) ST_VERSION = int(sublime.version())
PLUGIN_DIR = dirname(realpath(__file__)) PLUGIN_DIR = dirname(realpath(__file__))
API_CLIENT = '%s/packages/wakatime/wakatime-cli.py' % PLUGIN_DIR API_CLIENT = '%s/packages/wakatime/cli.py' % PLUGIN_DIR
SETTINGS_FILE = 'WakaTime.sublime-settings' SETTINGS_FILE = 'WakaTime.sublime-settings'
SETTINGS = {} SETTINGS = {}
LAST_ACTION = { LAST_ACTION = {
@ -37,9 +37,7 @@ LOCK = threading.RLock()
PYTHON_LOCATION = None PYTHON_LOCATION = None
# add wakatime package to path # add wakatime package to path
sys.path.insert(0, join(PLUGIN_DIR, 'packages', 'wakatime')) sys.path.insert(0, join(PLUGIN_DIR, 'packages'))
from wakatime import parseConfigFile
# check if we have SSL support # check if we have SSL support
try: try:
@ -80,10 +78,14 @@ def prompt_api_key():
createConfigFile() createConfigFile()
default_key = '' default_key = ''
try:
from wakatime.base import parseConfigFile
configs = parseConfigFile() configs = parseConfigFile()
if configs is not None: if configs is not None:
if configs.has_option('settings', 'api_key'): if configs.has_option('settings', 'api_key'):
default_key = configs.get('settings', 'api_key') default_key = configs.get('settings', 'api_key')
except:
pass
if SETTINGS.get('api_key'): if SETTINGS.get('api_key'):
return True return True
@ -208,7 +210,7 @@ class SendActionThread(threading.Thread):
if self.debug: if self.debug:
cmd.append('--verbose') cmd.append('--verbose')
if HAS_SSL: if HAS_SSL:
if self.debug: #if self.debug:
print('[WakaTime] %s' % ' '.join(cmd)) print('[WakaTime] %s' % ' '.join(cmd))
code = wakatime.main(cmd) code = wakatime.main(cmd)
if code != 0: if code != 0:
@ -217,8 +219,8 @@ class SendActionThread(threading.Thread):
python = python_binary() python = python_binary()
if python: if python:
cmd.insert(0, python) cmd.insert(0, python)
if self.debug: #if self.debug:
print('[WakaTime] %s' % ' '.join(cmd)) print('[WakaTime] %s %s' % (python, ' '.join(cmd)))
if platform.system() == 'Windows': if platform.system() == 'Windows':
Popen(cmd, shell=False) Popen(cmd, shell=False)
else: else:

View file

@ -1,39 +0,0 @@
*.py[cod]
# C extensions
*.so
# Packages
*.egg
*.egg-info
dist
build
eggs
parts
bin
var
sdist
develop-eggs
.installed.cfg
lib
lib64
# Installer logs
pip-log.txt
# Unit test / coverage reports
.coverage
.tox
nosetests.xml
# Translations
*.mo
# Mr Developer
.mr.developer.cfg
.project
.pydevproject
virtualenv
venv
.DS_Store

View file

@ -1,15 +0,0 @@
WakaTime is written and maintained by Alan Hamlett and
various contributors:
Development Lead
----------------
- Alan Hamlett <alan.hamlett@gmail.com>
Patches and Suggestions
-----------------------
- 3onyc <3onyc@x3tech.com>
- userid <xixico@ymail.com>

View file

@ -1,304 +0,0 @@
History
-------
3.0.5 (2015-01-13)
++++++++++++++++++
- ignore errors from malformed markup (too many closing tags)
3.0.4 (2015-01-06)
++++++++++++++++++
- remove unused dependency, which is missing in some python environments
3.0.3 (2014-12-25)
++++++++++++++++++
- detect JavaScript frameworks from script tags in Html template files
3.0.2 (2014-12-25)
++++++++++++++++++
- detect frameworks from JavaScript and JSON files
3.0.1 (2014-12-23)
++++++++++++++++++
- handle unknown language when parsing dependencies
3.0.0 (2014-12-23)
++++++++++++++++++
- detect libraries and frameworks for C++, Java, .NET, PHP, and Python files
2.1.11 (2014-12-22)
+++++++++++++++++++
- fix offline logging when response from api is None
2.1.10 (2014-12-15)
+++++++++++++++++++
- prevent queuing offline heartbeats which will never be valid (400 errors)
2.1.9 (2014-12-05)
++++++++++++++++++
- fix bug preventing offline heartbeats from being purged after uploaded
2.1.8 (2014-12-04)
++++++++++++++++++
- fix UnicodeDecodeError when building user agent string
- handle case where response is None
2.1.7 (2014-11-30)
++++++++++++++++++
- upgrade pygments to v2.0.1
- always log an error when api key is incorrect
2.1.6 (2014-11-18)
++++++++++++++++++
- fix list index error when detecting subversion project
2.1.5 (2014-11-17)
++++++++++++++++++
- catch exceptions when getting current machine time zone
2.1.4 (2014-11-12)
++++++++++++++++++
- when Python was not compiled with https support, log an error to the log file
2.1.3 (2014-11-10)
++++++++++++++++++
- correctly detect branch name for subversion projects
2.1.2 (2014-10-07)
++++++++++++++++++
- still log heartbeat when something goes wrong while reading num lines in file
2.1.1 (2014-09-30)
++++++++++++++++++
- fix bug where binary file opened as utf-8
2.1.0 (2014-09-30)
++++++++++++++++++
- python3 compatibility changes
2.0.8 (2014-08-29)
++++++++++++++++++
- supress output from svn command
2.0.7 (2014-08-27)
++++++++++++++++++
- find svn binary location from common install directories
2.0.6 (2014-08-07)
++++++++++++++++++
- encode json data as str when passing to urllib
2.0.5 (2014-07-25)
++++++++++++++++++
- option in .wakatime.cfg to obfuscate file names
2.0.4 (2014-07-25)
++++++++++++++++++
- use unique logger namespace to prevent collisions in shared plugin environments
2.0.3 (2014-06-18)
++++++++++++++++++
- use project from command line arg when no revision control project is found
2.0.2 (2014-06-09)
++++++++++++++++++
- include python3.2 compatible versions of simplejson, pytz, and tzlocal
- disable offline logging when Python was not compiled with sqlite3 module
2.0.1 (2014-05-26)
++++++++++++++++++
- fix bug in queue preventing actions with NULL values from being purged
2.0.0 (2014-05-25)
++++++++++++++++++
- offline time logging using sqlite3 to queue editor events
1.0.2 (2014-05-06)
++++++++++++++++++
- ability to set project from command line argument
1.0.1 (2014-03-05)
++++++++++++++++++
- use new domain name wakatime.com
1.0.0 (2014-02-05)
++++++++++++++++++
- detect project name and branch name from mercurial revision control
0.5.3 (2014-01-15)
++++++++++++++++++
- bug fix for unicode in Python3
0.5.2 (2014-01-14)
++++++++++++++++++
- minor bug fix for Subversion on non-English systems
0.5.1 (2013-12-13)
++++++++++++++++++
- second line in .wakatime-project file now sets branch name
0.5.0 (2013-12-13)
++++++++++++++++++
- Convert ~/.wakatime.conf to ~/.wakatime.cfg and use configparser format
- new [projectmap] section in cfg file for naming projects based on folders
0.4.10 (2013-11-13)
+++++++++++++++++++
- Placing .wakatime-project file in a folder will read the project's name from that file
0.4.9 (2013-10-27)
++++++++++++++++++
- New config for ignoring files from regular expressions
- Parse more options from config file (verbose, logfile, ignore)
0.4.8 (2013-10-13)
++++++++++++++++++
- Read git HEAD file to find current branch instead of running git command line
0.4.7 (2013-09-30)
++++++++++++++++++
- Sending local olson timezone string in api request
0.4.6 (2013-09-22)
++++++++++++++++++
- Sending total lines in file and language name to api
0.4.5 (2013-09-07)
++++++++++++++++++
- Fixed relative import error by adding packages directory to sys path
0.4.4 (2013-09-06)
++++++++++++++++++
- Using urllib2 again because of intermittent problems sending json with requests library
0.4.3 (2013-09-04)
++++++++++++++++++
- Encoding json as utf-8 before making request
0.4.2 (2013-09-04)
++++++++++++++++++
- Using requests package v1.2.3 from pypi
0.4.1 (2013-08-25)
++++++++++++++++++
- Fix bug causing requests library to omit POST content
0.4.0 (2013-08-15)
++++++++++++++++++
- Sending single branch instead of multiple tags
0.3.1 (2013-08-08)
++++++++++++++++++
- Using requests module instead of urllib2 to verify SSL certs
0.3.0 (2013-08-08)
++++++++++++++++++
- Allow importing directly from Python plugins
0.1.1 (2013-07-07)
++++++++++++++++++
- Refactored
- Simplified action events schema
0.0.1 (2013-07-05)
++++++++++++++++++
- Birth

View file

@ -1,31 +0,0 @@
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
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided
with the distribution.
* 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.
THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View file

@ -1,2 +0,0 @@
include README.rst LICENSE HISTORY.rst
recursive-include wakatime *.py

View file

@ -1,20 +0,0 @@
WakaTime
========
Fully automatic time tracking for programmers.
This is the common interface for the WakaTime api. You shouldn't need to directly use this package unless you are creating a new plugin or your text editor's plugin asks you to install the wakatime-cli interface.
Go to http://wakatime.com to install the plugin for your text editor.
Installation
------------
pip install wakatime
Usage
-----
https://wakatime.com/

View file

@ -0,0 +1,9 @@
__title__ = 'wakatime'
__description__ = 'Common interface to the WakaTime api.'
__url__ = 'https://github.com/wakatime/wakatime'
__version_info__ = ('4', '0', '4')
__version__ = '.'.join(__version_info__)
__author__ = 'Alan Hamlett'
__author_email__ = 'alan@wakatime.com'
__license__ = 'BSD'
__copyright__ = 'Copyright 2014 Alan Hamlett'

View file

@ -0,0 +1,17 @@
# -*- coding: utf-8 -*-
"""
wakatime
~~~~~~~~
Common interface to the WakaTime api.
http://wakatime.com
:copyright: (c) 2013 Alan Hamlett.
:license: BSD, see LICENSE for more details.
"""
__all__ = ['main']
from .base import main

View file

@ -1,10 +1,9 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
""" """
wakatime wakatime.base
~~~~~~~~ ~~~~~~~~~~~~~
Common interface to the WakaTime api. wakatime module entry point.
http://wakatime.com
:copyright: (c) 2013 Alan Hamlett. :copyright: (c) 2013 Alan Hamlett.
:license: BSD, see LICENSE for more details. :license: BSD, see LICENSE for more details.
@ -12,13 +11,6 @@
from __future__ import print_function from __future__ import print_function
__title__ = 'wakatime'
__version__ = '3.0.5'
__author__ = 'Alan Hamlett'
__license__ = 'BSD'
__copyright__ = 'Copyright 2014 Alan Hamlett'
import base64 import base64
import logging import logging
import os import os
@ -31,26 +23,24 @@ try:
import ConfigParser as configparser import ConfigParser as configparser
except ImportError: except ImportError:
import configparser import configparser
try:
from urllib2 import HTTPError, Request, urlopen
except ImportError:
from urllib.error import HTTPError
from urllib.request import Request, urlopen
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), 'packages')) sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), 'packages'))
from .__about__ import __version__
from .compat import u, open, is_py3 from .compat import u, open, is_py3
from .queue import Queue from .offlinequeue import Queue
from .log import setup_logging from .log import setup_logging
from .project import find_project from .project import find_project
from .stats import get_file_stats from .stats import get_file_stats
from .packages import argparse from .packages import argparse
from .packages import simplejson as json from .packages import simplejson as json
from .packages import requests
from .packages.requests.exceptions import RequestException
try: try:
from .packages import tzlocal from .packages import tzlocal
except: except:
from .packages import tzlocal3 from .packages import tzlocal3 as tzlocal
log = logging.getLogger('WakaTime') log = logging.getLogger('WakaTime')
@ -143,29 +133,43 @@ def parseArguments(argv):
parser.add_argument('--file', dest='targetFile', metavar='file', parser.add_argument('--file', dest='targetFile', metavar='file',
action=FileAction, required=True, action=FileAction, required=True,
help='absolute path to file for current heartbeat') help='absolute path to file for current heartbeat')
parser.add_argument('--key', dest='key',
help='your wakatime api key; uses api_key from '+
'~/.wakatime.conf by default')
parser.add_argument('--write', dest='isWrite',
action='store_true',
help='when set, tells api this 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')
parser.add_argument('--time', dest='timestamp', metavar='time', parser.add_argument('--time', dest='timestamp', metavar='time',
type=float, type=float,
help='optional floating-point unix epoch timestamp; '+ help='optional floating-point unix epoch timestamp; '+
'uses current time by default') 'uses current time by default')
parser.add_argument('--write', dest='isWrite', parser.add_argument('--notfile', dest='notfile', action='store_true',
action='store_true', help='when set, will accept any value for the file. for example, '+
help='note heartbeat was triggered from writing to a file') 'a domain name or other item you want to log time towards.')
parser.add_argument('--plugin', dest='plugin', parser.add_argument('--proxy', dest='proxy',
help='optional text editor plugin name and version '+ help='optional https proxy url; for example: '+
'for User-Agent header') 'https://user:pass@localhost:8080')
parser.add_argument('--project', dest='project_name', parser.add_argument('--project', dest='project_name',
help='optional project name; will auto-discover by default') help='optional project name; will auto-discover by default')
parser.add_argument('--key', dest='key',
help='your wakatime api key; uses api_key from '+
'~/.wakatime.conf by default')
parser.add_argument('--disableoffline', dest='offline', parser.add_argument('--disableoffline', dest='offline',
action='store_false', action='store_false',
help='disables offline time logging instead of queuing logged time') help='disables offline time logging instead of queuing logged time')
parser.add_argument('--hidefilenames', dest='hidefilenames', parser.add_argument('--hidefilenames', dest='hidefilenames',
action='store_true', action='store_true',
help='obfuscate file names; will not send file names to api') help='obfuscate file names; will not send file names to api')
parser.add_argument('--exclude', dest='exclude', action='append',
help='filename patterns to exclude from logging; POSIX regex '+
'syntax; can be used more than once')
parser.add_argument('--include', dest='include', action='append',
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('--ignore', dest='ignore', action='append', parser.add_argument('--ignore', dest='ignore', action='append',
help='filename patterns to ignore; POSIX regex syntax; can be used more than once') help=argparse.SUPPRESS)
parser.add_argument('--logfile', dest='logfile', parser.add_argument('--logfile', dest='logfile',
help='defaults to ~/.wakatime.log') help='defaults to ~/.wakatime.log')
parser.add_argument('--config', dest='config', parser.add_argument('--config', dest='config',
@ -191,23 +195,43 @@ def parseArguments(argv):
default_key = None default_key = None
if configs.has_option('settings', 'api_key'): if configs.has_option('settings', 'api_key'):
default_key = configs.get('settings', 'api_key') default_key = configs.get('settings', 'api_key')
elif configs.has_option('settings', 'apikey'):
default_key = configs.get('settings', 'apikey')
if default_key: if default_key:
args.key = default_key args.key = default_key
else: else:
parser.error('Missing api key') parser.error('Missing api key')
if not args.ignore: if not args.exclude:
args.ignore = [] args.exclude = []
if configs.has_option('settings', 'ignore'): if configs.has_option('settings', 'ignore'):
try: try:
for pattern in configs.get('settings', 'ignore').split("\n"): for pattern in configs.get('settings', 'ignore').split("\n"):
if pattern.strip() != '': if pattern.strip() != '':
args.ignore.append(pattern) args.exclude.append(pattern)
except TypeError:
pass
if configs.has_option('settings', 'exclude'):
try:
for pattern in configs.get('settings', 'exclude').split("\n"):
if pattern.strip() != '':
args.exclude.append(pattern)
except TypeError:
pass
if not args.include:
args.include = []
if configs.has_option('settings', 'include'):
try:
for pattern in configs.get('settings', 'include').split("\n"):
if pattern.strip() != '':
args.include.append(pattern)
except TypeError: except TypeError:
pass pass
if args.offline and configs.has_option('settings', 'offline'): if args.offline and configs.has_option('settings', 'offline'):
args.offline = configs.getboolean('settings', 'offline') args.offline = configs.getboolean('settings', 'offline')
if not args.hidefilenames and configs.has_option('settings', 'hidefilenames'): if not args.hidefilenames and configs.has_option('settings', 'hidefilenames'):
args.hidefilenames = configs.getboolean('settings', 'hidefilenames') args.hidefilenames = configs.getboolean('settings', 'hidefilenames')
if not args.proxy and configs.has_option('settings', 'proxy'):
args.proxy = configs.get('settings', 'proxy')
if not args.verbose and configs.has_option('settings', 'verbose'): if not args.verbose and configs.has_option('settings', 'verbose'):
args.verbose = configs.getboolean('settings', 'verbose') args.verbose = configs.getboolean('settings', 'verbose')
if not args.verbose and configs.has_option('settings', 'debug'): if not args.verbose and configs.has_option('settings', 'debug'):
@ -218,15 +242,29 @@ def parseArguments(argv):
return args, configs return args, configs
def should_ignore(fileName, patterns): def should_exclude(fileName, include, exclude):
if fileName is not None and fileName.strip() != '':
try: try:
for pattern in patterns: for pattern in include:
try:
compiled = re.compile(pattern, re.IGNORECASE)
if compiled.search(fileName):
return False
except re.error as ex:
log.warning(u('Regex error ({msg}) for include pattern: {pattern}').format(
msg=u(ex),
pattern=u(pattern),
))
except TypeError:
pass
try:
for pattern in exclude:
try: try:
compiled = re.compile(pattern, re.IGNORECASE) compiled = re.compile(pattern, re.IGNORECASE)
if compiled.search(fileName): if compiled.search(fileName):
return pattern return pattern
except re.error as ex: except re.error as ex:
log.warning(u('Regex error ({msg}) for ignore pattern: {pattern}').format( log.warning(u('Regex error ({msg}) for exclude pattern: {pattern}').format(
msg=u(ex), msg=u(ex),
pattern=u(pattern), pattern=u(pattern),
)) ))
@ -248,19 +286,23 @@ def get_user_agent(plugin):
user_agent=user_agent, user_agent=user_agent,
plugin=u(plugin), plugin=u(plugin),
) )
else:
user_agent = u('{user_agent} Unknown/0').format(
user_agent=user_agent,
)
return user_agent return user_agent
def send_heartbeat(project=None, branch=None, stats={}, key=None, targetFile=None, def send_heartbeat(project=None, branch=None, stats={}, key=None, targetFile=None,
timestamp=None, isWrite=None, plugin=None, offline=None, timestamp=None, isWrite=None, plugin=None, offline=None,
hidefilenames=None, **kwargs): hidefilenames=None, notfile=False, proxy=None, **kwargs):
url = 'https://wakatime.com/api/v1/heartbeats' url = 'https://wakatime.com/api/v1/heartbeats'
log.debug('Sending heartbeat to api at %s' % url) log.debug('Sending heartbeat to api at %s' % url)
data = { data = {
'time': timestamp, 'time': timestamp,
'file': targetFile, 'file': targetFile,
} }
if hidefilenames and targetFile is not None: if hidefilenames and targetFile is not None and not notfile:
data['file'] = data['file'].rsplit('/', 1)[-1].rsplit('\\', 1)[-1] data['file'] = data['file'].rsplit('/', 1)[-1].rsplit('\\', 1)[-1]
if len(data['file'].strip('.').split('.', 1)) > 1: if len(data['file'].strip('.').split('.', 1)) > 1:
data['file'] = u('HIDDEN.{ext}').format(ext=u(data['file'].strip('.').rsplit('.', 1)[-1])) data['file'] = u('HIDDEN.{ext}').format(ext=u(data['file'].strip('.').rsplit('.', 1)[-1]))
@ -282,15 +324,17 @@ def send_heartbeat(project=None, branch=None, stats={}, key=None, targetFile=Non
# setup api request # setup api request
request_body = json.dumps(data) request_body = json.dumps(data)
request = Request(url=url, data=str.encode(request_body) if is_py3 else request_body) api_key = u(base64.b64encode(str.encode(key) if is_py3 else key))
request.add_header('User-Agent', get_user_agent(plugin)) auth = u('Basic {api_key}').format(api_key=api_key)
request.add_header('Content-Type', 'application/json') headers = {
auth = u('Basic {key}').format(key=u(base64.b64encode(str.encode(key) if is_py3 else key))) 'User-Agent': get_user_agent(plugin),
request.add_header('Authorization', auth) 'Content-Type': 'application/json',
'Accept': 'application/json',
ALWAYS_LOG_CODES = [ 'Authorization': auth,
401, }
] proxies = {}
if proxy:
proxies['https'] = proxy
# add Olson timezone to request # add Olson timezone to request
try: try:
@ -298,64 +342,44 @@ def send_heartbeat(project=None, branch=None, stats={}, key=None, targetFile=Non
except: except:
tz = None tz = None
if tz: if tz:
request.add_header('TimeZone', u(tz.zone)) headers['TimeZone'] = u(tz.zone)
# log time to api # log time to api
response = None response = None
try: try:
response = urlopen(request) response = requests.post(url, data=request_body, headers=headers,
except HTTPError as exc: proxies=proxies)
exception_data = { except RequestException:
'response_code': exc.getcode(),
sys.exc_info()[0].__name__: u(sys.exc_info()[1]),
}
if log.isEnabledFor(logging.DEBUG):
exception_data['traceback'] = traceback.format_exc()
if offline:
if response is None or response.getcode() != 400:
queue = Queue()
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:
log.error({
'response_code': response.getcode(),
})
else:
log.error(exception_data)
except:
exception_data = { exception_data = {
sys.exc_info()[0].__name__: u(sys.exc_info()[1]), sys.exc_info()[0].__name__: u(sys.exc_info()[1]),
} }
if log.isEnabledFor(logging.DEBUG): if log.isEnabledFor(logging.DEBUG):
exception_data['traceback'] = traceback.format_exc() exception_data['traceback'] = traceback.format_exc()
if offline: if offline:
if response is None or response.getcode() != 400:
queue = Queue() queue = Queue()
queue.push(data, json.dumps(stats), plugin) queue.push(data, json.dumps(stats), plugin)
if 'unknown url type: https' in u(sys.exc_info()[1]): if log.isEnabledFor(logging.DEBUG):
log.error(exception_data)
elif log.isEnabledFor(logging.DEBUG):
log.warn(exception_data) log.warn(exception_data)
if response is not None and response.getcode() in ALWAYS_LOG_CODES:
log.error({
'response_code': response.getcode(),
})
else: else:
log.error(exception_data) log.error(exception_data)
else: else:
if response is not None and response.getcode() == 201: response_code = response.status_code if response is not None else None
response_content = response.text if response is not None else None
if response_code == 201:
log.debug({ log.debug({
'response_code': response.getcode(), 'response_code': response_code,
}) })
return True return True
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 offline:
if response is None or response.getcode() != 400: if response_code != 400:
queue = Queue() queue = Queue()
queue.push(data, json.dumps(stats), plugin) queue.push(data, json.dumps(stats), plugin)
if log.isEnabledFor(logging.DEBUG): if response_code == 401:
log.error({
'response_code': response_code,
'response_content': response_content,
})
elif log.isEnabledFor(logging.DEBUG):
log.warn({ log.warn({
'response_code': response_code, 'response_code': response_code,
'response_content': response_content, 'response_content': response_content,
@ -383,17 +407,19 @@ def main(argv=None):
setup_logging(args, __version__) setup_logging(args, __version__)
ignore = should_ignore(args.targetFile, args.ignore) exclude = should_exclude(args.targetFile, args.include, args.exclude)
if ignore is not False: if exclude is not False:
log.debug(u('File ignored because matches pattern: {pattern}').format( log.debug(u('File not logged because matches exclude pattern: {pattern}').format(
pattern=u(ignore), pattern=u(exclude),
)) ))
return 0 return 0
if os.path.isfile(args.targetFile): if os.path.isfile(args.targetFile) or args.notfile:
stats = get_file_stats(args.targetFile) stats = get_file_stats(args.targetFile, notfile=args.notfile)
project = None
if not args.notfile:
project = find_project(args.targetFile, configs=configs) project = find_project(args.targetFile, configs=configs)
branch = None branch = None
project_name = args.project_name project_name = args.project_name
@ -421,7 +447,9 @@ def main(argv=None):
isWrite=heartbeat['is_write'], isWrite=heartbeat['is_write'],
plugin=heartbeat['plugin'], plugin=heartbeat['plugin'],
offline=args.offline, offline=args.offline,
hidefilenames=args.hidefilenames) hidefilenames=args.hidefilenames,
notfile=args.notfile,
proxy=args.proxy)
if not sent: if not sent:
break break
return 0 # success return 0 # success

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
""" """
wakatime-cli wakatime.cli
~~~~~~~~~~~~ ~~~~~~~~~~~~
Command-line entry point. Command-line entry point.
@ -9,11 +9,9 @@
:license: BSD, see LICENSE for more details. :license: BSD, see LICENSE for more details.
""" """
from __future__ import print_function
import os import os
import sys import sys
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import wakatime import wakatime
if __name__ == '__main__': if __name__ == '__main__':

View file

@ -12,7 +12,6 @@
import os import os
from . import TokenParser from . import TokenParser
from ..compat import u
FILES = { FILES = {

View file

@ -30,7 +30,6 @@ class CustomEncoder(json.JSONEncoder):
try: try:
encoded = super(CustomEncoder, self).default(obj) encoded = super(CustomEncoder, self).default(obj)
except UnicodeDecodeError: except UnicodeDecodeError:
encoding = sys.getfilesystemencoding()
obj = u(obj) obj = u(obj)
encoded = super(CustomEncoder, self).default(obj) encoded = super(CustomEncoder, self).default(obj)
return encoded return encoded
@ -63,7 +62,7 @@ class JsonFormatter(logging.Formatter):
return CustomEncoder().encode(data) return CustomEncoder().encode(data)
def formatException(self, exc_info): def formatException(self, exc_info):
return exec_info[2].format_exc() return sys.exec_info[2].format_exc()
def set_log_level(logger, args): def set_log_level(logger, args):

Some files were not shown because too many files have changed in this diff Show more