Merge pull request #4 from 3onyc/feature/projectmap

Add a ProjectMap plugin
This commit is contained in:
Alan Hamlett 2013-12-13 03:14:02 -08:00
commit ce4d6ce3b7
4 changed files with 105 additions and 30 deletions

View file

@ -27,6 +27,8 @@ import sys
import time
import traceback
from ConfigParser import RawConfigParser
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'))
from .log import setup_logging
@ -51,16 +53,29 @@ class FileAction(argparse.Action):
values = os.path.realpath(values)
setattr(namespace, self.dest, values)
def checkUpdateConfigFile(configFile):
"""Checks if the config has a header section, if not add it for ConfigParser"""
with open(configFile) as fh:
configData = fh.read()
if not configData.strip().startswith('[settings]'):
configData = "[settings]\n" + configData.strip()
with open(configFile, 'w') as fh:
fh.write(configData)
def parseConfigFile(configFile):
if not configFile:
configFile = os.path.join(os.path.expanduser('~'), '.wakatime.conf')
checkUpdateConfigFile(configFile)
# define default config values
configs = {
defaults = {
'settings' : {
'api_key': None,
'ignore': [],
'verbose': False,
'verbose': False
},
}
if not os.path.isfile(configFile):
@ -68,24 +83,19 @@ def parseConfigFile(configFile):
try:
with open(configFile) as fh:
for line in fh:
line = line.split('=', 1)
if len(line) == 2 and line[0].strip() and line[1].strip():
line[0] = line[0].strip()
line[1] = line[1].strip()
if line[0] in configs:
if isinstance(configs[line[0]], list):
configs[line[0]].append(line[1])
elif isinstance(configs[line[0]], bool):
configs[line[0]] = True if line[1].lower() == 'true' else False
else:
configs[line[0]] = line[1]
else:
configs[line[0]] = line[1]
configs = RawConfigParser()
setConfigDefaults(configs, defaults)
configs.readfp(fh)
except IOError:
print('Error: Could not read from config file ~/.wakatime.conf')
return configs
def setConfigDefaults(config, defaults):
for section, values in defaults.iteritems():
if not config.has_section(section):
config.add_section(section)
for key, value in values.iteritems():
config.set(section, key, value)
def parseArguments(argv):
try:
@ -126,20 +136,21 @@ def parseArguments(argv):
# set arguments from config file
configs = parseConfigFile(args.config)
if not args.key:
default_key = configs.get('api_key')
default_key = configs.get('settings', 'api_key')
if default_key:
args.key = default_key
else:
parser.error('Missing api key')
for pattern in configs.get('ignore', []):
for pattern in configs.get('settings', 'ignore'):
if not args.ignore:
args.ignore = []
args.ignore.append(pattern)
if not args.verbose and 'verbose' in configs:
args.verbose = configs['verbose']
if not args.logfile and 'logfile' in configs:
args.logfile = configs['logfile']
return args
if not args.verbose and configs.has_option('settings', 'verbose'):
args.verbose = configs.getboolean('settings', 'verbose')
if not args.logfile and configs.has_option('settings', 'logfile'):
args.logfile = configs.get('settings', 'logfile')
return args, configs
def should_ignore(fileName, patterns):
@ -233,7 +244,7 @@ def send_action(project=None, branch=None, stats={}, key=None, targetFile=None,
def main(argv=None):
if not argv:
argv = sys.argv
args = parseArguments(argv)
args, config = parseArguments(argv)
setup_logging(args, __version__)
ignore = should_ignore(args.targetFile, args.ignore)
if ignore is not False:
@ -243,7 +254,7 @@ def main(argv=None):
branch = None
name = None
stats = get_file_stats(args.targetFile)
project = find_project(args.targetFile)
project = find_project(args.targetFile, config)
if project:
branch = project.branch()
name = project.name()

View file

@ -13,6 +13,7 @@ import logging
import os
from .projects.wakatime import WakaTime
from .projects.projectmap import ProjectMap
from .projects.git import Git
from .projects.mercurial import Mercurial
from .projects.subversion import Subversion
@ -22,15 +23,21 @@ log = logging.getLogger(__name__)
PLUGINS = [
WakaTime,
ProjectMap,
Git,
Mercurial,
Subversion,
]
def find_project(path):
def find_project(path, config):
for plugin in PLUGINS:
project = plugin(path)
plugin_name = plugin.__name__.lower()
if config.has_section(plugin_name):
plugin_config = config
else:
plugin_config = None
project = plugin(path, plugin_config)
if project.process():
return project
return None

View file

@ -22,8 +22,9 @@ class BaseProject(object):
be found for the current path.
"""
def __init__(self, path):
def __init__(self, path, settings):
self.path = path
self.settings = settings
def type(self):
""" Returns None if this is the base class.

View file

@ -0,0 +1,56 @@
# -*- coding: utf-8 -*-
"""
wakatime.projects.projectmap
~~~~~~~~~~~~~~~~~~~~~~~~~~
Information from ~/.waka-projectmap mapping folders (relative to home folder)
to project names
:author: 3onyc
:license: BSD, see LICENSE for more details.
"""
import logging
import os
from functools import partial
from ..packages import simplejson as json
from .base import BaseProject
log = logging.getLogger(__name__)
class ProjectMap(BaseProject):
def process(self):
if not self.settings:
return False
self.project = self._find_project()
return self.project != None
def _find_project(self):
has_option = partial(self.settings.has_option, 'projectmap')
get_option = partial(self.settings.get, 'projectmap')
paths = self._path_generator()
projects = map(get_option, filter(has_option, paths))
return projects[0] if projects else None
def branch(self):
return None
def name(self):
return self.project
def _path_generator(self):
"""
Generates paths from the current directory up to the user's home folder
stripping anything in the path before the home path
"""
path = self.path.replace(os.environ['HOME'], '')
while path != os.path.dirname(path):
yield path
path = os.path.dirname(path)