mirror of
https://github.com/wakatime/sublime-wakatime.git
synced 2023-08-10 21:13:02 +03:00
Compare commits
12 Commits
Author | SHA1 | Date | |
---|---|---|---|
3504096082 | |||
5990947706 | |||
2246e31244 | |||
b55fe702d3 | |||
e0fbbb50bb | |||
32c0cb5a97 | |||
67d8b0d24f | |||
b8b2f4944b | |||
a20161164c | |||
405211bb07 | |||
ffc879c4eb | |||
1e23919694 |
44
HISTORY.rst
44
HISTORY.rst
@ -3,11 +3,47 @@ History
|
||||
-------
|
||||
|
||||
|
||||
9.0.1 (2019-11-24)
|
||||
++++++++++++++++++
|
||||
|
||||
- Upgrade wakatime-cli to v13.0.2.
|
||||
- Filter dependencies longer than 200 characters.
|
||||
- Close sqlite connection even when error raised.
|
||||
`wakatime#196 <https://github.com/wakatime/wakatime/issues/196>`_
|
||||
- Detect ColdFusion as root language instead of HTML.
|
||||
- New arguments for reading and writing ini config file.
|
||||
- Today argument shows categories when available.
|
||||
- Prevent unnecessarily debug log when syncing offline heartbeats.
|
||||
- Support for Python 3.7.
|
||||
|
||||
|
||||
9.0.0 (2019-06-23)
|
||||
++++++++++++++++++
|
||||
|
||||
- New optional config option hide_branch_names.
|
||||
`wakatime#183 <https://github.com/wakatime/wakatime/issues/183>`_
|
||||
|
||||
|
||||
8.7.0 (2019-05-29)
|
||||
++++++++++++++++++
|
||||
|
||||
- Prevent creating user sublime-settings file when api key already exists in
|
||||
common wakatime.cfg file.
|
||||
`#98 <https://github.com/wakatime/sublime-wakatime/issues/98>`_
|
||||
|
||||
|
||||
8.6.1 (2019-05-28)
|
||||
++++++++++++++++++
|
||||
|
||||
- Fix parsing common wakatime.cfg file.
|
||||
`#98 <https://github.com/wakatime/sublime-wakatime/issues/98>`_
|
||||
|
||||
|
||||
8.6.0 (2019-05-27)
|
||||
++++++++++++++++++
|
||||
|
||||
- Prevent prompting for api key when found from config file.
|
||||
`sublime-wakatime#98 <https://github.com/wakatime/sublime-wakatime/issues/98>`_
|
||||
`#98 <https://github.com/wakatime/sublime-wakatime/issues/98>`_
|
||||
|
||||
|
||||
8.5.0 (2019-05-10)
|
||||
@ -42,7 +78,7 @@ History
|
||||
|
||||
- Upgrade wakatime-cli to v10.8.4.
|
||||
- Use wakatime fork of certifi package.
|
||||
`sublime-wakatime#95 <https://github.com/wakatime/sublime-wakatime/issues/95>`_
|
||||
`#95 <https://github.com/wakatime/sublime-wakatime/issues/95>`_
|
||||
|
||||
|
||||
8.3.5 (2019-04-30)
|
||||
@ -61,11 +97,11 @@ History
|
||||
- Detect C++ language from all C++ file extensions.
|
||||
`vscode-wakatime#87 <https://github.com/wakatime/vscode-wakatime/issues/87>`_
|
||||
- Add ssl_certs_file arg and config for custom ca bundles.
|
||||
`#164 <https://github.com/wakatime/wakatime/issues/164>`_
|
||||
`wakatime#164 <https://github.com/wakatime/wakatime/issues/164>`_
|
||||
- Fix bug causing random project names when hide project names enabled.
|
||||
`vscode-wakatime#162 <https://github.com/wakatime/vscode-wakatime/issues/61>`_
|
||||
- Add support for UNC network shares without drive letter mapped on Winows.
|
||||
`#162 <https://github.com/wakatime/wakatime/issues/162>`_
|
||||
`wakatime#162 <https://github.com/wakatime/wakatime/issues/162>`_
|
||||
|
||||
|
||||
8.3.3 (2018-12-19)
|
||||
|
62
WakaTime.py
62
WakaTime.py
@ -8,7 +8,7 @@ Website: https://wakatime.com/
|
||||
==========================================================="""
|
||||
|
||||
|
||||
__version__ = '8.6.0'
|
||||
__version__ = '9.0.1'
|
||||
|
||||
|
||||
import sublime
|
||||
@ -140,12 +140,47 @@ ERROR = 'ERROR'
|
||||
# add wakatime package to path
|
||||
sys.path.insert(0, os.path.join(PLUGIN_DIR, 'packages'))
|
||||
try:
|
||||
from wakatime.main import parseConfigFile
|
||||
from wakatime.configs import parseConfigFile
|
||||
except ImportError:
|
||||
def parseConfigFile():
|
||||
return None
|
||||
|
||||
|
||||
class ApiKey(object):
|
||||
_key = None
|
||||
|
||||
def read(self):
|
||||
if self._key:
|
||||
return self._key
|
||||
|
||||
key = SETTINGS.get('api_key')
|
||||
if key:
|
||||
self._key = key
|
||||
return self._key
|
||||
|
||||
try:
|
||||
configs = parseConfigFile()
|
||||
if configs:
|
||||
if configs.has_option('settings', 'api_key'):
|
||||
key = configs.get('settings', 'api_key')
|
||||
if key:
|
||||
self._key = key
|
||||
return self._key
|
||||
except:
|
||||
pass
|
||||
|
||||
return self._key
|
||||
|
||||
def write(self, key):
|
||||
global SETTINGS
|
||||
self._key = key
|
||||
SETTINGS.set('api_key', str(key))
|
||||
sublime.save_settings(SETTINGS_FILE)
|
||||
|
||||
|
||||
APIKEY = ApiKey()
|
||||
|
||||
|
||||
def set_timeout(callback, seconds):
|
||||
"""Runs the callback after the given seconds delay.
|
||||
|
||||
@ -223,7 +258,7 @@ class FetchStatusBarCodingTime(threading.Thread):
|
||||
threading.Thread.__init__(self)
|
||||
|
||||
self.debug = SETTINGS.get('debug')
|
||||
self.api_key = SETTINGS.get('api_key', '')
|
||||
self.api_key = APIKEY.read() or ''
|
||||
self.proxy = SETTINGS.get('proxy')
|
||||
self.python_binary = SETTINGS.get('python_binary')
|
||||
|
||||
@ -270,29 +305,14 @@ class FetchStatusBarCodingTime(threading.Thread):
|
||||
|
||||
|
||||
def prompt_api_key():
|
||||
global SETTINGS
|
||||
|
||||
if SETTINGS.get('api_key'):
|
||||
if APIKEY.read():
|
||||
return True
|
||||
|
||||
try:
|
||||
configs = parseConfigFile()
|
||||
if configs is not None:
|
||||
if configs.has_option('settings', 'api_key'):
|
||||
key = configs.get('settings', 'api_key')
|
||||
if key:
|
||||
SETTINGS.set('api_key', str(key))
|
||||
sublime.save_settings(SETTINGS_FILE)
|
||||
return True
|
||||
except:
|
||||
pass
|
||||
|
||||
window = sublime.active_window()
|
||||
if window:
|
||||
def got_key(text):
|
||||
if text:
|
||||
SETTINGS.set('api_key', str(text))
|
||||
sublime.save_settings(SETTINGS_FILE)
|
||||
APIKEY.write(text)
|
||||
window.show_input_panel('[WakaTime] Enter your wakatime.com api key:', '', got_key, None, None)
|
||||
return True
|
||||
else:
|
||||
@ -568,7 +588,7 @@ class SendHeartbeatsThread(threading.Thread):
|
||||
threading.Thread.__init__(self)
|
||||
|
||||
self.debug = SETTINGS.get('debug')
|
||||
self.api_key = SETTINGS.get('api_key', '')
|
||||
self.api_key = APIKEY.read() or ''
|
||||
self.ignore = SETTINGS.get('ignore', [])
|
||||
self.include = SETTINGS.get('include', [])
|
||||
self.hidefilenames = SETTINGS.get('hidefilenames')
|
||||
|
@ -1,7 +1,7 @@
|
||||
__title__ = 'wakatime'
|
||||
__description__ = 'Common interface to the WakaTime api.'
|
||||
__url__ = 'https://github.com/wakatime/wakatime'
|
||||
__version_info__ = ('11', '0', '0')
|
||||
__version_info__ = ('13', '0', '2')
|
||||
__version__ = '.'.join(__version_info__)
|
||||
__author__ = 'Alan Hamlett'
|
||||
__author_email__ = 'alan@wakatime.com'
|
||||
|
@ -250,7 +250,11 @@ def get_time_today(args, use_ntlm_proxy=False):
|
||||
|
||||
if code == requests.codes.ok:
|
||||
try:
|
||||
text = response.json()['data'][0]['grand_total']['text']
|
||||
summary = response.json()['data'][0]
|
||||
if len(summary['categories']) > 1:
|
||||
text = ', '.join(['{0} {1}'.format(x['text'], x['name'].lower()) for x in summary['categories']])
|
||||
else:
|
||||
text = summary['grand_total']['text']
|
||||
session_cache.save(session)
|
||||
return text, SUCCESS
|
||||
except:
|
||||
|
@ -19,8 +19,8 @@ import time
|
||||
import traceback
|
||||
from .__about__ import __version__
|
||||
from .compat import basestring
|
||||
from .configs import parseConfigFile
|
||||
from .constants import AUTH_ERROR, DEFAULT_SYNC_OFFLINE_ACTIVITY
|
||||
from .configs import getConfigFile, parseConfigFile
|
||||
from .constants import AUTH_ERROR, DEFAULT_SYNC_OFFLINE_ACTIVITY, SUCCESS
|
||||
from .packages import argparse
|
||||
|
||||
|
||||
@ -62,6 +62,7 @@ def parse_arguments():
|
||||
parser.add_argument('--file', dest='file', action=FileAction,
|
||||
help=argparse.SUPPRESS)
|
||||
parser.add_argument('--key', dest='key', action=StoreWithoutQuotes,
|
||||
metavar='API_KEY',
|
||||
help='Your wakatime api key; uses api_key from ' +
|
||||
'~/.wakatime.cfg by default.')
|
||||
parser.add_argument('--write', dest='is_write', action='store_true',
|
||||
@ -75,10 +76,11 @@ def parse_arguments():
|
||||
help='Optional floating-point unix epoch timestamp. ' +
|
||||
'Uses current time by default.')
|
||||
parser.add_argument('--lineno', dest='lineno', action=StoreWithoutQuotes,
|
||||
metavar='INT',
|
||||
help='Optional line number. This is the current ' +
|
||||
'line being edited.')
|
||||
parser.add_argument('--cursorpos', dest='cursorpos',
|
||||
action=StoreWithoutQuotes,
|
||||
metavar='INT', action=StoreWithoutQuotes,
|
||||
help='Optional cursor position in the current file.')
|
||||
parser.add_argument('--entity-type', dest='entity_type',
|
||||
action=StoreWithoutQuotes,
|
||||
@ -104,13 +106,13 @@ def parse_arguments():
|
||||
'requests. By default, SSL certificates are ' +
|
||||
'verified.')
|
||||
parser.add_argument('--ssl-certs-file', dest='ssl_certs_file',
|
||||
action=StoreWithoutQuotes,
|
||||
metavar='FILE', action=StoreWithoutQuotes,
|
||||
help='Override the bundled Python Requests CA certs ' +
|
||||
'file. By default, uses certifi for ca certs.')
|
||||
parser.add_argument('--project', dest='project', action=StoreWithoutQuotes,
|
||||
help='Optional project name.')
|
||||
parser.add_argument('--alternate-project', dest='alternate_project',
|
||||
action=StoreWithoutQuotes,
|
||||
metavar='PROJECT', action=StoreWithoutQuotes,
|
||||
help='Optional alternate project name. ' +
|
||||
'Auto-discovered project takes priority.')
|
||||
parser.add_argument('--alternate-language', dest='alternate_language',
|
||||
@ -153,7 +155,12 @@ def parse_arguments():
|
||||
'folder name as the project, a ' +
|
||||
'.wakatime-project file is created with a ' +
|
||||
'random project name.')
|
||||
parser.add_argument('--hide-branch-names', dest='hide_branch_names',
|
||||
action='store_true',
|
||||
help='Obfuscate branch names. Will not send revision ' +
|
||||
'control branch names to api.')
|
||||
parser.add_argument('--exclude', dest='exclude', action='append',
|
||||
metavar='PATH',
|
||||
help='Filename patterns to exclude from logging. ' +
|
||||
'POSIX regex syntax. Can be used more than once.')
|
||||
parser.add_argument('--exclude-unknown-project',
|
||||
@ -161,6 +168,7 @@ def parse_arguments():
|
||||
help='When set, any activity where the project ' +
|
||||
'cannot be detected will be ignored.')
|
||||
parser.add_argument('--include', dest='include', action='append',
|
||||
metavar='PATH',
|
||||
help='Filename patterns to log. When used in ' +
|
||||
'combination with --exclude, files matching ' +
|
||||
'include will still be logged. POSIX regex ' +
|
||||
@ -177,20 +185,21 @@ def parse_arguments():
|
||||
help='Reads extra heartbeats from STDIN as a JSON ' +
|
||||
'array until EOF.')
|
||||
parser.add_argument('--log-file', dest='log_file',
|
||||
action=StoreWithoutQuotes,
|
||||
metavar='FILE', action=StoreWithoutQuotes,
|
||||
help='Defaults to ~/.wakatime.log.')
|
||||
parser.add_argument('--logfile', dest='logfile', action=StoreWithoutQuotes,
|
||||
help=argparse.SUPPRESS)
|
||||
parser.add_argument('--api-url', dest='api_url', action=StoreWithoutQuotes,
|
||||
metavar='URL',
|
||||
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,
|
||||
metavar='SECONDS', action=StoreWithoutQuotes,
|
||||
help='Number of seconds to wait when sending ' +
|
||||
'heartbeats to api. Defaults to 60 seconds.')
|
||||
parser.add_argument('--sync-offline-activity',
|
||||
parser.add_argument('--sync-offline-activity', metavar='AMOUNT',
|
||||
dest='sync_offline_activity',
|
||||
action=StoreWithoutQuotes,
|
||||
help='Amount of offline activity to sync from your ' +
|
||||
@ -205,7 +214,20 @@ def parse_arguments():
|
||||
action='store_true',
|
||||
help='Prints dashboard time for Today, then exits.')
|
||||
parser.add_argument('--config', dest='config', action=StoreWithoutQuotes,
|
||||
help='Defaults to ~/.wakatime.cfg.')
|
||||
metavar='FILE', help='Defaults to ~/.wakatime.cfg.')
|
||||
parser.add_argument('--config-section', dest='config_section',
|
||||
metavar='SECTION', action=StoreWithoutQuotes,
|
||||
help='Optional config section when reading or ' +
|
||||
'writing a config key. Defaults to [settings].')
|
||||
parser.add_argument('--config-read', dest='config_read',
|
||||
metavar='KEY', action=StoreWithoutQuotes,
|
||||
help='Prints value for the given config key, then ' +
|
||||
'exits.')
|
||||
parser.add_argument('--config-write', dest='config_write',
|
||||
nargs=2, metavar=('KEY', 'VALUE'),
|
||||
action=StoreWithoutQuotes,
|
||||
help='Writes value to a config key, then exits. ' +
|
||||
'Expects two arguments, key and value.')
|
||||
parser.add_argument('--verbose', dest='verbose', action='store_true',
|
||||
help='Turns on debug messages in log file.')
|
||||
parser.add_argument('--version', action='version', version=__version__)
|
||||
@ -213,13 +235,30 @@ def parse_arguments():
|
||||
# parse command line arguments
|
||||
args = parser.parse_args()
|
||||
|
||||
# parse ~/.wakatime.cfg file
|
||||
configs = parseConfigFile(args.config)
|
||||
|
||||
if args.config_read:
|
||||
section = args.config_section or 'settings'
|
||||
key = args.config_read
|
||||
print(configs.get(section, key))
|
||||
raise SystemExit(SUCCESS)
|
||||
|
||||
if args.config_write:
|
||||
section = args.config_section or 'settings'
|
||||
key = args.config_write[0]
|
||||
val = args.config_write[1]
|
||||
if not configs.has_section(section):
|
||||
configs.add_section(section)
|
||||
configs.set(section, key, val)
|
||||
with open(args.config or getConfigFile(), 'w', encoding='utf-8') as fh:
|
||||
configs.write(fh)
|
||||
raise SystemExit(SUCCESS)
|
||||
|
||||
# use current unix epoch timestamp by default
|
||||
if not args.timestamp:
|
||||
args.timestamp = time.time()
|
||||
|
||||
# parse ~/.wakatime.cfg file
|
||||
configs = parseConfigFile(args.config)
|
||||
|
||||
# update args from configs
|
||||
if not args.hostname:
|
||||
if configs.has_option('settings', 'hostname'):
|
||||
@ -294,8 +333,9 @@ def parse_arguments():
|
||||
pass
|
||||
if not args.exclude_unknown_project and configs.has_option('settings', 'exclude_unknown_project'):
|
||||
args.exclude_unknown_project = configs.getboolean('settings', 'exclude_unknown_project')
|
||||
boolean_or_list('hide_file_names', args, configs, alternative_names=['hide_filenames', 'hidefilenames'])
|
||||
boolean_or_list('hide_project_names', args, configs, alternative_names=['hide_projectnames', 'hideprojectnames'])
|
||||
_boolean_or_list('hide_file_names', args, configs, alternative_names=['hide_filenames', 'hidefilenames'])
|
||||
_boolean_or_list('hide_project_names', args, configs, alternative_names=['hide_projectnames', 'hideprojectnames'])
|
||||
_boolean_or_list('hide_branch_names', args, configs, alternative_names=['hide_branchnames', 'hidebranchnames'], default=None)
|
||||
if args.offline_deprecated:
|
||||
args.offline = False
|
||||
if args.offline and configs.has_option('settings', 'offline'):
|
||||
@ -340,7 +380,7 @@ def parse_arguments():
|
||||
return args, configs
|
||||
|
||||
|
||||
def boolean_or_list(config_name, args, configs, alternative_names=[]):
|
||||
def _boolean_or_list(config_name, args, configs, alternative_names=[], default=[]):
|
||||
"""Get a boolean or list of regexes from args and configs."""
|
||||
|
||||
# when argument flag present, set to wildcard regex
|
||||
@ -349,7 +389,7 @@ def boolean_or_list(config_name, args, configs, alternative_names=[]):
|
||||
setattr(args, config_name, ['.*'])
|
||||
return
|
||||
|
||||
setattr(args, config_name, [])
|
||||
setattr(args, config_name, default)
|
||||
|
||||
option = None
|
||||
alternative_names.insert(0, config_name)
|
||||
@ -361,7 +401,11 @@ def boolean_or_list(config_name, args, configs, alternative_names=[]):
|
||||
if option is not None:
|
||||
if option.strip().lower() == 'true':
|
||||
setattr(args, config_name, ['.*'])
|
||||
elif option.strip().lower() != 'false':
|
||||
elif option.strip().lower() == 'false':
|
||||
setattr(args, config_name, [])
|
||||
else:
|
||||
for pattern in option.split("\n"):
|
||||
if pattern.strip() != '':
|
||||
if not getattr(args, config_name):
|
||||
setattr(args, config_name, [])
|
||||
getattr(args, config_name).append(pattern)
|
||||
|
@ -131,5 +131,9 @@ class DependencyParser(object):
|
||||
if self.parser:
|
||||
plugin = self.parser(self.source_file, lexer=self.lexer)
|
||||
dependencies = plugin.parse()
|
||||
return list(filter(bool, set(dependencies)))
|
||||
|
||||
def filter_dependencies(dep):
|
||||
return dep and len(dep) <= 200
|
||||
|
||||
return list(filter(filter_dependencies, set(dependencies)))
|
||||
return []
|
||||
|
@ -43,7 +43,15 @@ class Heartbeat(object):
|
||||
cursorpos = None
|
||||
user_agent = None
|
||||
|
||||
_sensitive = ('dependencies', 'lines', 'lineno', 'cursorpos', 'branch')
|
||||
_sensitive_when_hiding_filename = (
|
||||
'dependencies',
|
||||
'lines',
|
||||
'lineno',
|
||||
'cursorpos',
|
||||
)
|
||||
_sensitive_when_hiding_branch = (
|
||||
'branch',
|
||||
)
|
||||
|
||||
def __init__(self, data, args, configs, _clone=None):
|
||||
if not data:
|
||||
@ -141,21 +149,24 @@ class Heartbeat(object):
|
||||
Returns a Heartbeat.
|
||||
"""
|
||||
|
||||
if not self.args.hide_file_names:
|
||||
return self
|
||||
|
||||
if self.entity is None:
|
||||
return self
|
||||
|
||||
if self.type != 'file':
|
||||
return self
|
||||
|
||||
if self.should_obfuscate_filename():
|
||||
self._sanitize_metadata()
|
||||
if self._should_obfuscate_filename():
|
||||
self._sanitize_metadata(keys=self._sensitive_when_hiding_filename)
|
||||
if self._should_obfuscate_branch(default=True):
|
||||
self._sanitize_metadata(keys=self._sensitive_when_hiding_branch)
|
||||
extension = u(os.path.splitext(self.entity)[1])
|
||||
self.entity = u('HIDDEN{0}').format(extension)
|
||||
elif self.should_obfuscate_project():
|
||||
self._sanitize_metadata()
|
||||
self._sanitize_metadata(keys=self._sensitive_when_hiding_filename)
|
||||
if self._should_obfuscate_branch(default=True):
|
||||
self._sanitize_metadata(keys=self._sensitive_when_hiding_branch)
|
||||
elif self._should_obfuscate_branch():
|
||||
self._sanitize_metadata(keys=self._sensitive_when_hiding_branch)
|
||||
|
||||
return self
|
||||
|
||||
@ -193,22 +204,6 @@ class Heartbeat(object):
|
||||
is_write=self.is_write,
|
||||
)
|
||||
|
||||
def should_obfuscate_filename(self):
|
||||
"""Returns True if hide_file_names is true or the entity file path
|
||||
matches one in the list of obfuscated file paths."""
|
||||
|
||||
for pattern in self.args.hide_file_names:
|
||||
try:
|
||||
compiled = re.compile(pattern, re.IGNORECASE)
|
||||
if compiled.search(self.entity):
|
||||
return True
|
||||
except re.error as ex:
|
||||
log.warning(u('Regex error ({msg}) for hide_file_names pattern: {pattern}').format(
|
||||
msg=u(ex),
|
||||
pattern=u(pattern),
|
||||
))
|
||||
return False
|
||||
|
||||
def should_obfuscate_project(self):
|
||||
"""Returns True if hide_project_names is true or the entity file path
|
||||
matches one in the list of obfuscated project paths."""
|
||||
@ -223,6 +218,49 @@ class Heartbeat(object):
|
||||
msg=u(ex),
|
||||
pattern=u(pattern),
|
||||
))
|
||||
|
||||
return False
|
||||
|
||||
def _should_obfuscate_filename(self):
|
||||
"""Returns True if hide_file_names is true or the entity file path
|
||||
matches one in the list of obfuscated file paths."""
|
||||
|
||||
for pattern in self.args.hide_file_names:
|
||||
try:
|
||||
compiled = re.compile(pattern, re.IGNORECASE)
|
||||
if compiled.search(self.entity):
|
||||
return True
|
||||
except re.error as ex:
|
||||
log.warning(u('Regex error ({msg}) for hide_file_names pattern: {pattern}').format(
|
||||
msg=u(ex),
|
||||
pattern=u(pattern),
|
||||
))
|
||||
|
||||
return False
|
||||
|
||||
def _should_obfuscate_branch(self, default=False):
|
||||
"""Returns True if hide_file_names is true or the entity file path
|
||||
matches one in the list of obfuscated file paths."""
|
||||
|
||||
# when project names or file names are hidden and hide_branch_names is
|
||||
# not set, we default to hiding branch names along with file/project.
|
||||
if default and self.args.hide_branch_names is None:
|
||||
return True
|
||||
|
||||
if not self.branch or not self.args.hide_branch_names:
|
||||
return False
|
||||
|
||||
for pattern in self.args.hide_branch_names:
|
||||
try:
|
||||
compiled = re.compile(pattern, re.IGNORECASE)
|
||||
if compiled.search(self.entity) or compiled.search(self.branch):
|
||||
return True
|
||||
except re.error as ex:
|
||||
log.warning(u('Regex error ({msg}) for hide_branch_names pattern: {pattern}').format(
|
||||
msg=u(ex),
|
||||
pattern=u(pattern),
|
||||
))
|
||||
|
||||
return False
|
||||
|
||||
def _unicode(self, value):
|
||||
@ -333,8 +371,8 @@ class Heartbeat(object):
|
||||
return False
|
||||
return find_project_file(self.entity) is None
|
||||
|
||||
def _sanitize_metadata(self):
|
||||
for key in self._sensitive:
|
||||
def _sanitize_metadata(self, keys=[]):
|
||||
for key in keys:
|
||||
setattr(self, key, None)
|
||||
|
||||
def __repr__(self):
|
||||
|
@ -38,7 +38,10 @@ def execute(argv=None):
|
||||
if argv:
|
||||
sys.argv = ['wakatime'] + argv
|
||||
|
||||
args, configs = parse_arguments()
|
||||
try:
|
||||
args, configs = parse_arguments()
|
||||
except SystemExit as ex:
|
||||
return ex.code
|
||||
|
||||
setup_logging(args, __version__)
|
||||
|
||||
@ -54,7 +57,7 @@ def execute(argv=None):
|
||||
hb = Heartbeat(vars(args), args, configs)
|
||||
if hb:
|
||||
heartbeats.append(hb)
|
||||
else:
|
||||
elif args.entity:
|
||||
log.debug(hb.skip)
|
||||
|
||||
if args.extra_heartbeats:
|
||||
|
@ -60,9 +60,12 @@ class Queue(object):
|
||||
}
|
||||
c.execute('INSERT INTO {0} VALUES (:id,:heartbeat)'.format(self.table_name), data)
|
||||
conn.commit()
|
||||
conn.close()
|
||||
except sqlite3.Error:
|
||||
log.traceback()
|
||||
try:
|
||||
conn.close()
|
||||
except: # pragma: nocover
|
||||
pass
|
||||
|
||||
def pop(self):
|
||||
if not HAS_SQL:
|
||||
|
@ -69,8 +69,6 @@ def get_project_info(configs, heartbeat, data):
|
||||
project_name = data.get('project') or heartbeat.args.project
|
||||
|
||||
hide_project = heartbeat.should_obfuscate_project()
|
||||
if hide_project and project_name is not None:
|
||||
return project_name, None
|
||||
|
||||
if project_name is None or branch_name is None:
|
||||
|
||||
@ -78,24 +76,25 @@ def get_project_info(configs, heartbeat, data):
|
||||
|
||||
plugin_name = plugin_cls.__name__.lower()
|
||||
plugin_configs = get_configs_for_plugin(plugin_name, configs)
|
||||
|
||||
project = plugin_cls(heartbeat.entity, configs=plugin_configs)
|
||||
|
||||
if project.process():
|
||||
project_name = project_name or project.name()
|
||||
if not hide_project:
|
||||
project_name = project_name or project.name()
|
||||
branch_name = branch_name or project.branch()
|
||||
if hide_project:
|
||||
branch_name = None
|
||||
project_name = generate_project_name()
|
||||
project_file = os.path.join(project.folder(), '.wakatime-project')
|
||||
try:
|
||||
with open(project_file, 'w') as fh:
|
||||
fh.write(project_name)
|
||||
except IOError:
|
||||
project_name = None
|
||||
break
|
||||
|
||||
if project_name is None and not hide_project:
|
||||
project_name = data.get('alternate_project') or heartbeat.args.alternate_project
|
||||
if project_name is None:
|
||||
if not hide_project:
|
||||
project_name = data.get('alternate_project') or heartbeat.args.alternate_project
|
||||
else:
|
||||
project_name = generate_project_name()
|
||||
project_file = os.path.join(project.folder(), '.wakatime-project')
|
||||
try:
|
||||
with open(project_file, 'w') as fh:
|
||||
fh.write(project_name)
|
||||
except IOError:
|
||||
project_name = None
|
||||
|
||||
return project_name, branch_name
|
||||
|
||||
|
@ -55,9 +55,12 @@ class SessionCache(object):
|
||||
}
|
||||
c.execute('INSERT INTO {0} VALUES (:value)'.format(self.table_name), values)
|
||||
conn.commit()
|
||||
conn.close()
|
||||
except: # pragma: nocover
|
||||
log.traceback(logging.DEBUG)
|
||||
try:
|
||||
conn.close()
|
||||
except: # pragma: nocover
|
||||
pass
|
||||
|
||||
def get(self):
|
||||
"""Returns a requests.Session object.
|
||||
@ -87,7 +90,7 @@ class SessionCache(object):
|
||||
try:
|
||||
conn.close()
|
||||
except: # pragma: nocover
|
||||
log.traceback(logging.DEBUG)
|
||||
pass
|
||||
|
||||
return session if session is not None else requests.session()
|
||||
|
||||
@ -101,9 +104,12 @@ class SessionCache(object):
|
||||
conn, c = self.connect()
|
||||
c.execute('DELETE FROM {0}'.format(self.table_name))
|
||||
conn.commit()
|
||||
conn.close()
|
||||
except:
|
||||
log.traceback(logging.DEBUG)
|
||||
try:
|
||||
conn.close()
|
||||
except: # pragma: nocover
|
||||
pass
|
||||
|
||||
def _get_db_file(self):
|
||||
home = '~'
|
||||
|
@ -259,6 +259,12 @@ def get_lexer(language):
|
||||
|
||||
|
||||
def use_root_language(language, lexer):
|
||||
override = {
|
||||
'Coldfusion HTML': 'ColdFusion',
|
||||
}
|
||||
if language in override:
|
||||
return override[language]
|
||||
|
||||
if lexer and hasattr(lexer, 'root_lexer'):
|
||||
return u(lexer.root_lexer.name)
|
||||
|
||||
|
Reference in New Issue
Block a user