new version 0.1.3. Cleaned up plugin. Automatically creating ~/.wakatime.log file.

This commit is contained in:
Alan Hamlett 2013-07-02 02:24:04 -07:00
parent 3457b0b534
commit 61370df1ba
3 changed files with 161 additions and 177 deletions

View file

@ -1,7 +1,7 @@
vim-wakatime 0.1.2 vim-wakatime 0.1.2
=========== ===========
Automatic time tracking. Automatic time tracking for Vim.
Installation Installation
------------ ------------
@ -12,7 +12,7 @@ https://wakati.me
2) Run this shell command replacing KEY with your api key: 2) Run this shell command replacing KEY with your api key:
echo "api_key=KEY" > ~/.wakatime echo "api_key=KEY" >> ~/.wakatime
3) Using [Vundle](https://github.com/gmarik/vundle), the Vim plugin manager: 3) Using [Vundle](https://github.com/gmarik/vundle), the Vim plugin manager:

View file

@ -17,7 +17,7 @@ import logging as log
# Config # Config
version = '0.1.2' version = '0.1.3'
user_agent = 'vim-wakatime/%s (%s)' % (version, platform.platform()) user_agent = 'vim-wakatime/%s (%s)' % (version, platform.platform())
@ -118,14 +118,12 @@ def send_action(key, instance, action, task, timestamp, project, tags):
url = 'https://www.wakati.me/api/v1/actions' url = 'https://www.wakati.me/api/v1/actions'
data = { data = {
'type': action, 'type': action,
'task': task, 'task': os.path.realpath(task),
'time': time.time(), 'time': timestamp,
'instance_id': instance, 'instance_id': instance,
'project': project, 'project': project,
'tags': tags, 'tags': tags,
} }
if timestamp:
data['time'] = timestamp
request = urllib2.Request(url=url, data=json.dumps(data)) request = urllib2.Request(url=url, data=json.dumps(data))
request.add_header('User-Agent', user_agent) request.add_header('User-Agent', user_agent)
request.add_header('Content-Type', 'application/json') request.add_header('Content-Type', 'application/json')
@ -173,10 +171,13 @@ def main(argv):
if args.verbose: if args.verbose:
level = log.DEBUG level = log.DEBUG
del args.verbose del args.verbose
if not args.timestamp:
args.timestamp = time.time()
log.basicConfig(filename=os.path.expanduser('~/.wakatime.log'), format='%(asctime)s vim-wakatime/'+version+' %(levelname)s %(message)s', datefmt='%Y-%m-%dT%H:%M:%SZ', level=level) log.basicConfig(filename=os.path.expanduser('~/.wakatime.log'), format='%(asctime)s vim-wakatime/'+version+' %(levelname)s %(message)s', datefmt='%Y-%m-%dT%H:%M:%SZ', level=level)
tags = tags_from_path(args.task) if os.path.isfile(os.path.realpath(args.task)):
project = project_from_path(args.task) tags = tags_from_path(args.task)
send_action(project=project, tags=tags, **vars(args)) project = project_from_path(args.task)
send_action(project=project, tags=tags, **vars(args))
return 0 return 0

View file

@ -1,221 +1,204 @@
" ============================================================================ " ============================================================================
" File: wakatime.vim " File: wakatime.vim
" Description: invisible time tracker using Wakati.Me " Description: Automatic time tracking for Vim.
" Maintainer: Wakati.Me <support@wakatime.com> " Maintainer: Wakati.Me <support@wakatime.com>
" Version: 0.1.2 " Version: 0.1.3
" ============================================================================ " ============================================================================
" Init {{{ " Init {{{
" Check Vim version " Check Vim version
if v:version < 700 if v:version < 700
echoerr "This plugin requires vim >= 7." echoerr "This plugin requires vim >= 7."
finish
endif
" Check for Python support
if !has('python')
echoerr "This plugin requires Vim to be compiled with Python support."
finish
endif
" Check for required user-defined settings
if !exists("g:wakatime_api_key")
if filereadable(expand("$HOME/.wakatime"))
for s:line in readfile(expand("$HOME/.wakatime"))
let s:setting = split(s:line, "=")
if s:setting[0] == "api_key"
let g:wakatime_api_key = s:setting[1]
endif
endfor
endif
if !exists("g:wakatime_api_key")
finish finish
endif endif
endif
" Only load plugin once " Check for Python support
if exists("g:loaded_wakatime") if !has('python')
finish echoerr "This plugin requires Vim to be compiled with Python support."
endif finish
let g:loaded_wakatime = 1 endif
" Backup & Override cpoptions " Check for required user-defined settings
let s:old_cpo = &cpo if !exists("g:wakatime_api_key")
set cpo&vim if filereadable(expand("$HOME/.wakatime"))
for s:line in readfile(expand("$HOME/.wakatime"))
let s:setting = split(s:line, "=")
if s:setting[0] == "api_key"
let g:wakatime_api_key = s:setting[1]
endif
endfor
endif
if !exists("g:wakatime_api_key")
finish
endif
endif
let s:plugin_directory = expand("<sfile>:p:h") " Only load plugin once
if exists("g:loaded_wakatime")
finish
endif
let g:loaded_wakatime = 1
" Set default updatetime " Backup & Override cpoptions
if !exists("g:wakatime_updatetime") let s:old_cpo = &cpo
let g:wakatime_updatetime = 15 " 15 minutes set cpo&vim
endif
" We are not away until getting a CursorHold event let s:plugin_directory = expand("<sfile>:p:h")
let s:away_start = 0
" Create logfile if does not exist " Set default updatetime
exec "silent !touch ~/.wakatime.log" if !exists("g:wakatime_updatetime")
let g:wakatime_updatetime = 15 " 15 minutes
endif
python << ENDPYTHON " We are not away until getting a CursorHold event
import vim let s:away_start = 0
import uuid
import time
instance_id = str(uuid.uuid4()) " Create logfile if does not exist
vim.command('let s:instance_id = "%s"' % instance_id) exec "silent !touch ~/.wakatime.log"
ENDPYTHON
python import time
python import time
python import uuid
python import vim
python instance_id = str(uuid.uuid4())
python vim.command('let s:instance_id = "%s"' % instance_id)
" }}} " }}}
" Function Definitions {{{ " Function Definitions {{{
function! s:initVariable(var, value) function! s:setUpdateTime()
if !exists(a:var) if &updatetime < 60 * 1000 * 2
exec 'let ' . a:var . ' = ' . "'" . substitute(a:value, "'", "''", "g") . "'" let &updatetime = g:wakatime_updatetime * 60 * 1000
return 1 endif
endif endfunction
return 0 call s:setUpdateTime()
endfunction
function! s:setUpdateTime() function! s:GetCurrentFile()
if &updatetime < 60 * 1000 * 2 return expand("%:p")
let &updatetime = g:wakatime_updatetime * 60 * 1000 endfunction
endif
endfunction
call s:setUpdateTime() function! s:GetCurrentTime()
python vim.command('let current_time="%f"' % time.time())
return current_time
endfunction
function! s:GetCurrentFile() function! s:api(type, task, time)
return expand("%:p") if a:task != ''
endfunction exec "silent !python " . s:plugin_directory . "/wakatime.py --key" g:wakatime_api_key "--instance" s:instance_id "--action" a:type "--task" shellescape(a:task) "--time" a:time . " &"
endif
endfunction
function! s:api(type, task) function! s:getchar()
if a:task != '' let c = getchar()
exec "silent !python " . s:plugin_directory . "/wakatime.py --key" g:wakatime_api_key "--instance" s:instance_id "--action" a:type "--task" shellescape(a:task) . " &" if c =~ '^\d\+$'
endif let c = nr2char(c)
endfunction endif
return c
endfunction
function! s:api_with_time(type, task, time) function! Wakatime_isAway()
if a:task != '' return s:away_start
exec "silent !python " . s:plugin_directory . "/wakatime.py --key" g:wakatime_api_key "--instance" s:instance_id "--action" a:type "--task" shellescape(a:task) "--time" printf("%f", a:time) . " &" endfunction
endif
endfunction
function! s:getchar() function! s:allServersAway()
let c = getchar() if has('clientserver')
if c =~ '^\d\+$' let servers = split(serverlist())
let c = nr2char(c) for server in servers
endif if server != v:servername
return c if !remote_expr(server,'Wakatime_isAway()')
endfunction return 0
endif
function! Wakatime_isAway()
return s:away_start
endfunction
function! s:allServersAway()
if has('clientserver')
let servers = split(serverlist())
for server in servers
if server != v:servername
if !remote_expr(server,'Wakatime_isAway()')
return 0
endif endif
endif endfor
endfor endif
endif return 1
return 1 endfunction
endfunction
" }}} " }}}
" Event Handlers {{{ " Event Handlers {{{
function! s:bufenter() function! s:bufenter()
let task = s:GetCurrentFile() call s:api("open_file", s:GetCurrentFile(), s:GetCurrentTime())
call s:api("open_file", task) endfunction
endfunction
function! s:bufleave() function! s:bufleave()
let task = s:GetCurrentFile() call s:api("close_file", s:GetCurrentFile(), s:GetCurrentTime())
call s:api("close_file", task) endfunction
endfunction
function! s:vimenter() function! s:vimenter()
let task = s:GetCurrentFile() call s:api("open_editor", s:GetCurrentFile(), s:GetCurrentTime())
call s:api("open_editor", task) endfunction
endfunction
function! s:vimleave() function! s:vimleave()
let task = s:GetCurrentFile() call s:api("quit_editor", s:GetCurrentFile(), s:GetCurrentTime())
call s:api("quit_editor", task) endfunction
endfunction
function! s:bufwrite() function! s:bufwrite()
let task = s:GetCurrentFile() call s:api("write_file", s:GetCurrentFile(), s:GetCurrentTime())
call s:api("write_file", task) endfunction
endfunction
function! s:cursorhold() function! s:cursorhold()
let s:away_task = s:GetCurrentFile() let s:away_task = s:GetCurrentFile()
python vim.command("let s:away_start=%f" % (time.time() - (float(vim.eval("&updatetime")) / 1000.0))) python vim.command("let s:away_start=%f" % (time.time() - (float(vim.eval("&updatetime")) / 1000.0)))
autocmd Wakatime CursorMoved,CursorMovedI * call s:cursormoved() autocmd Wakatime CursorMoved,CursorMovedI * call s:cursormoved()
endfunction endfunction
function! s:cursormoved() function! s:cursormoved()
autocmd! Wakatime CursorMoved,CursorMovedI * autocmd! Wakatime CursorMoved,CursorMovedI *
" Don't do anything unless all other Vim instances are also away " Don't do anything unless all other Vim instances are also away
if !s:allServersAway() if !s:allServersAway()
let s:away_start = 0
call s:api("ping", s:away_task, s:GetCurrentTime())
return
endif
python vim.command("let away_end=%f" % time.time())
let away_unit = "minutes"
let away_duration = (away_end - s:away_start) / 60
if away_duration < 2
call s:setUpdateTime()
return
endif
if away_duration > 59
let away_duration = away_duration / 60
let away_unit = "hours"
endif
if away_duration > 59
let away_duration = away_duration / 60
let away_unit = "days"
endif
let answer = input(printf("You were away %.f %s. Add time to current file? (y/n)", away_duration, away_unit))
if answer != "y"
call s:api("minimize_editor", s:away_task, printf("%f", s:away_start))
call s:api("maximize_editor", s:away_task, printf("%f", away_end))
else
call s:api("ping", s:away_task, s:GetCurrentTime())
endif
let s:away_start = 0 let s:away_start = 0
call s:api("ping", s:away_task) "redraw!
return endfunction
endif
python vim.command("let away_end=%f" % time.time())
let away_unit = "minutes"
let away_duration = (away_end - s:away_start) / 60
if away_duration < 2
call s:setUpdateTime()
return
endif
if away_duration > 59
let away_duration = away_duration / 60
let away_unit = "hours"
endif
if away_duration > 59
let away_duration = away_duration / 60
let away_unit = "days"
endif
let answer = input(printf("You were away %.f %s. Add time to current file? (y/n)", away_duration, away_unit))
if answer != "y"
call s:api_with_time("minimize_editor", s:away_task, s:away_start)
call s:api_with_time("maximize_editor", s:away_task, away_end)
else
call s:api("ping", s:away_task)
endif
let s:away_start = 0
"redraw!
endfunction
" }}} " }}}
" Autocommand Events {{{ " Autocommand Events {{{
augroup Wakatime augroup Wakatime
autocmd! autocmd!
autocmd BufEnter * call s:bufenter() autocmd BufEnter * call s:bufenter()
autocmd BufLeave * call s:bufleave() autocmd BufLeave * call s:bufleave()
autocmd VimEnter * call s:vimenter() autocmd VimEnter * call s:vimenter()
autocmd VimLeave * call s:vimleave() autocmd VimLeave * call s:vimleave()
autocmd BufWritePost * call s:bufwrite() autocmd BufWritePost * call s:bufwrite()
autocmd CursorHold,CursorHoldI * call s:cursorhold() autocmd CursorHold,CursorHoldI * call s:cursorhold()
augroup END augroup END
" }}} " }}}