Closed JJJHolscher closed 8 months ago
I got it to work by editing the following functions in autoload/calendar/google/client.vim
function! calendar#google#client#access_token() abort
let cache = s:cache.get('access_token')
if type(cache) != type({}) || type(cache) == type({}) && !has_key(cache, 'access_token')
call calendar#google#client#initialize_access_token()
let cache = s:cache.get('access_token')
if type(cache) != type({}) || type(cache) == type({}) && !has_key(cache, 'access_token')
return 1
endif
let content = cache
else
let content = cache
endif
return content.access_token
endfunction
let s:server_py_path = expand('<sfile>:p:h') . '/server.py'
function! calendar#google#client#initialize_access_token() abort
if !executable('python3')
call calendar#echo#error('Python 3 is required.')
return
endif
let content = json_decode(system("python /path/to/gcal.py"))
if calendar#google#client#access_token_response(content)
return
endif
let g:calendar_google_event_downloading_list = 0
let g:calendar_google_event_download = 3
silent! let b:calendar.event._updated = 3
endfunction
function! calendar#google#client#refresh_token() abort
let cache = s:cache.get('refresh_token')
if type(cache) == type({}) && has_key(cache, 'refresh_token') && type(cache.refresh_token) == type('')
let content = json_decode(system("python /path/to/gcal.py"))
if calendar#google#client#access_token_response(content)
return 1
endif
return content.access_token
else
return 1
endif
endfunction
function! calendar#google#client#access_token_response(content) abort
if !has_key(a:content, 'token')
call calendar#echo#error_message('google_access_token_fail')
return 1
else
let a:content.access_token = a:content.token
call s:cache.save('access_token', a:content)
if has_key(a:content, 'refresh_token') && type(a:content.refresh_token) == type('')
call s:cache.save('refresh_token', { 'refresh_token': a:content.refresh_token })
endif
endif
endfunction
gcal.py (install gcsa with pip install gcsa
)
import os
import sys
from gcsa.google_calendar import GoogleCalendar
with open(os.devnull, 'w') as f:
# supress the print message that requests to authenticate in the browser
# otherwise the output is not valid json that calendar.vim can interpret
sys.stdout = f
cred = GoogleCalendar(credentials_path="/home/user/gcal-credentials.json").credentials
sys.stdout = sys.__stdout__
print(cred.to_json())
gcsa will refresh the token upon calling this script and also pops up the authentication window in your browser if the token is not present or expired.
I'll open a PR if you think this adds, though I do think this method should replace the existing authentication method instead of being an alternative option. Also some of the other code probably became redundant with my fix, but I lack the knowledge about the code base as to efficiently prune the redundancies.
gcsa does not provide tasks, for that we'd need to use the google.oauth2 lib instead. Now I re-use the code from gcsa's authentication.py (instead of the above gcal.py) which, after adding the tasks scope, does work with tasks.
I stopped using this plugin.
Many of my gcal tools use Python's gcsa library. I like this library since it accepts the json file one downloads from google cloud, and stores the token in a pickle file. Gcsa takes care of opening the login page and refreshing the token. Also I can have multiple programs share the token so I only need to authenticate once.
Calendar.vim has its own authentication workflow which has the upsides of less dependencies and staying within vimscript. But it regularly bugs out for me and requires me to create a .vim file out of the json and occasionally I need to manually delete the cache.
I would like calendar.vim to be able to work with the json file. Preferably by using gcsa such that I can share the pickle file. Gcsa has been very reliable for me throughout my 2-year usage.