Code Monkey home page Code Monkey logo

i3-agenda's Introduction

AUR version PyPI Version Badge

What is this?

It's a script that communicates with Google's calendar API, it will go through your calendars and print the next calendar event details.
You can take this output and show it on your i3-bar or polybar

example example

How does it work

It will read your next 10 events from each of your calendars, then go through them all and figure out which one is closest.
It will print the time and title of the closest event.

Setup

Google API

https://developers.google.com/calendar/quickstart/python

  1. You need to create a Google API project and download your OAuth 2.0 credentials json file.You first need to create a project here, then add Google Calendar support, then download the credentials.json file. Alternatively, you can just use this link and click "Enable the Google Calendar API". This will create a project, add Google Calendar support, and let you download the file in 1 click. If you're having trouble, you can use this tutorial for more information https://developers.google.com/calendar/auth. Another great guide can be found here if you're still having trouble: https://github.com/jay0lee/GAM/wiki/CreatingClientSecretsFile.
  2. Download the credentials file to somewhere on your computer.
  3. Proceed to installation phase.

Installation

After downloading the credentials file, install the package.

Pipx

Using pipx will save you time and it's cross-platform. It is a package manager for Python that allows you to easily install and run Python packages in isolated environments.

pipx install https://github.com/rosenpin/i3-agenda

Pip

  1. sudo pip install .
  2. Try running i3-agenda -c $CREDENTIALS_FILE_PATH with "$CREDENTIALS_FILE_PATH" replaced with the path to the credentials.json file you downloaded in the previous step.
  3. Add configuration to your bar (examples in the Examples section below).

Arch Linux (AUR)

  1. yay -S i3-agenda-git
  2. Try running i3-agenda -c $CREDENTIALS_FILE_PATH with "$CREDENTIALS_FILE_PATH" replaced with the path to the credentials.json file you downloaded in the previous step.
  3. Add configuration to your bar (examples in the Examples section below).

Manual

Dependencies

You need to install some python libraries first.
Make sure python3 is your default python.
Run sudo pip3 install python-bidi google-api-python-client google-auth-httplib2 google-auth-oauthlib

  1. Clone the repo to a local directory cd ~/ && git clone https://github.com/rosenpin/i3-agenda && cd i3-agenda
  2. Run the script python3 i3_agenda/i3_agenda.py -c $CREDENTIALS_FILE_PATH with "$CREDENTIALS_FILE_PATH" replaced with the path to the credentials.json file you downloaded in the previous step. If configured correctly, it will prompt you to log in in your browser, accept everything. It should print your next event.
  3. Optional: you can run sudo python setup.py install to add the script to your path so you can run i3-agenda anywhere.
  4. Add configuration to your bar (examples in the Examples section below).

Usage

  -h, --help            show this help message and exit
  --credentials CREDENTIALS, -c CREDENTIALS
                        path to your credentials.json file
  --conf CONF, -cd CONF
                        path to the i3agenda configuration and cache folder
  --cachettl CACHETTL, -ttl CACHETTL
                        time for cache to be kept in minutes
  --update, -u          when using this flag it will not load previous results from cache, it will however save new results to cache.
                        You can use this flag to refresh all the cache forcefully
  --ids IDS [IDS ...], -i IDS [IDS ...]
                        list of calendar ids to fetch, space separated. If  none is specified all calendars will be fetched
  --maxres MAXRES, -r MAXRES
                        max number of events to query Google's API for each of your calendars.
                        Increase this number if you have lot of events in your google calendar
  --today, -d           print only today events
  --no-event-text TEXT  text to display when there are no events
  --hide-event-after HIDE_EVENT_AFTER
                        minutes to show events after they start before showing the next event.
                        If not specified, the current event will be shown until it ends
  --show-event-before SHOW_EVENT_BEFORE
                        minutes to show events before they start. If not specified, the next event will be shown regardless of when it starts
  --date-format DATE_FORMAT
                        the date format like %d/%m/%y. Default is %d/%m
  --limchar LIMCHAR, -l LIMCHAR
                        the max characters that the displayed event can contain
  --skip SKIP, -s SKIP  the number of events to skip from the most recent

Filter displayed calendars

To display events only from certain calendars use the --ids parameter and pass a list of calendar id, space separated.
To obtain the calendar id you can check the settings page of the calendar on Google (usually is the owner email, if it's not shared).
Leaving the list empty will fetch all calendars (default behavior).

Notes

Known issues

It might not work properly if you have more than 10 all day events, this can be fixed by increasing the maxResults variable.

RTL support

If you use RTL or some of your events contain RTL languages, you will need to pipe pybidi with the script. Example: i3-agenda -c ~/.google_credentials.json -ttl 60 | pybidi

Caching

It uses a caching mechanism so you won't have to contact Google servers every minute, to set the cache TTL use the -ttl flag.
Example: i3-agenda --ttl 60 to set the TTL to 60 (meaning it will contact Google again every hour).
This means that if you create a new event, it might take an hour for the script to recognize it.

Multi account support

Multi account support is not officialy supported, but you can use the workaround from this issue: #35 (comment)

Examples

Example polybar configuration:

example

modules-center = agenda
....
[module/agenda]
type = custom/script
; Show the next event and forget cache automatically every 60 minutes
exec = i3-agenda -c ~/.google_credentials.json -ttl 60
; left click to launch Google Calendar
click-left = chromium https://calendar.google.com/calendar/r/day
; right click force update the cache, if for example you just added a new event
click-right = notify-send "syncing..." && i3-agenda -c ~/.google_credentials.json --update && notify-send -t 2000 "sync finished"
interval = 60

Example SwiftBar configuration

example This will show your next event as the menu bar title, when you press it you will see a dropdown with all your today events You can call the file agenda.2m.sh to make it refresh every 2 minutes

#!/bin/bash
# <swiftbar.hideAbout>true</swiftbar.hideAbout>

i3-agenda -c ~/.google_credentials.json -ttl 60 --limchar 30

echo "---"
href="href='https://calendar.google.com/calendar/u/0/r/'"

i=1
while :; do
    event=$(i3-agenda -c ~/.google_credentials.json -ttl 60 --limchar 30 --skip $i --today)
    ((i++))
    if [[ "$event" == "No events" ]];then
        exit 0
    fi
    echo "$event | $href"
done

Example i3block configuration:

[i3-agenda]
command=i3-agenda -c ~/.google_credentials.json -ttl 60
interval=60

Example output of the script:
10:55 Grocery shopping

How to use the skip flag to scroll events

Edit the polybar configuration creating two modules:

[module/agenda-ipc]
type = custom/ipc

hook-0 = i3-agenda -c ~/.google_credentials.json --skip $(cat ~/.config/i3-agenda/i3-agenda-skip.tmp || echo 0)
hook-1 = ~/.config/polybar/scripts/i3agenda-onscroll.sh down && i3-agenda -c ~/.google_credentials.json --skip $(cat ~/.config/i3-agenda/i3-agenda-skip.tmp || echo 0)
hook-2 = ~/.config/polybar/scripts/i3agenda-onscroll.sh up && i3-agenda -c ~/.google_credentials.json --skip $(cat ~/.config/i3-agenda/i3-agenda-skip.tmp || echo 0)

format = %{F#61afef}%{F-} <output>

; left click to launch Google Calendar
click-left = firefox https://calendar.google.com/calendar/u/0/r
; right click force update the cache, if for example you just added a new event
click-right = rm ~/.config/i3-agenda/i3-agenda-skip.tmp; i3-agenda -c ~/.config/i3-agenda/client_secret.json --update && notify-send "i3-agenda" "Sync completed"

; show the previous event
scroll-down = polybar-msg hook agenda-ipc 2
; show the next event
scroll-up = polybar-msg hook agenda-ipc 3

[module/agenda]
type = custom/script
interval = 900
exec = polybar-msg hook agenda-ipc 1
label =

Add both modules to the bar, for example:

modules-center = agenda agenda-ipc

In the polybar scripts folder add the file i3agenda-onscroll.sh:

#!/usr/bin/env bash
if [ -n "${1}" ]; then
  file=~/.config/i3-agenda/i3-agenda-skip.tmp
  typeset -i skip=$(cat $file || echo 0)
  if [[ "${1}" == "up" ]]; then
    skip+=1
  elif [[ "${1}" == "down" && $skip -gt 0 ]]; then
    skip=$(( skip - 1))
  fi
  echo $skip > $file
fi

i3-agenda's People

Contributors

alessio-perugini avatar aspieln3r avatar fabfurnari avatar fgionghi avatar howardjohn avatar igorfroehner avatar kristinn avatar ktl-xv avatar martinbrylski avatar matclab avatar mmngreco avatar notdodo avatar otreblan avatar rosenpin avatar sanyatuning avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

i3-agenda's Issues

Option to show all day events

Currently, we filter out all day events in the get_closest function
This is done because otherwise, the all day event will always be shown when it's taking place even if other events are more relevant

Option 1:

Make this optional using a flag

Option 2:

Show other event unless the end time of the all day event is before the start time of the closest event

I personally prefer option 2 as it will do things the 'smart' way, only show all day events if there's nothing else more interesting

Add option to only show events if they are within X minutes

It would be great to have a flag to only show unstarted events that are up to X minutes way. This would be the pair to --hide-event-after. For example, could call this --show-event-before

I would expect something like this:
--show-event-before=15m --hide-event-after=15m to start showing an event 15m before it begins, and then remove it 15m after it starts.

This is useful to not crowd the bar when there are no nearby events. It can also serve as a 'notification' that I should be in a meeting now or soon.

I would be willing to send a PR for this if desired.

refactor

Refactor the code

-[ ] separate to multiple files and objects (1 for Google communication, 1 for event object, 1 for logic etc..)

  • move logic and boilerplate code to functions, make the code easier to read
  • fix PEP incompatibilities

Refactoring

  • Move constant (numbers/strings) values to consts
  • Rename main file from init to main/i3-agenda.py
  • Separate functions with 3+ indentation levels or over 15 lines
  • Clean up event.py file (choose logical separation between methods/file functions)

Token revoked

Traceback (most recent call last):
  File "/usr/bin/i3-agenda", line 33, in <module>
    sys.exit(load_entry_point('i3-agenda==1.4', 'console_scripts', 'i3-agenda')())
  File "/usr/lib/python3.9/site-packages/i3_agenda-1.4-py3.9.egg/i3_agenda/__init__.py", line 99, in main
  File "/usr/lib/python3.9/site-packages/i3_agenda-1.4-py3.9.egg/i3_agenda/__init__.py", line 273, in connect
  File "/home/tomer/.local/lib/python3.9/site-packages/google/oauth2/credentials.py", line 200, in refresh
    access_token, refresh_token, expiry, grant_response = _client.refresh_grant(
  File "/home/tomer/.local/lib/python3.9/site-packages/google/oauth2/_client.py", line 248, in refresh_grant
    response_data = _token_endpoint_request(request, token_uri, body)
  File "/home/tomer/.local/lib/python3.9/site-packages/google/oauth2/_client.py", line 124, in _token_endpoint_request
    _handle_error_response(response_body)
  File "/home/tomer/.local/lib/python3.9/site-packages/google/oauth2/_client.py", line 60, in _handle_error_response
    raise exceptions.RefreshError(error_details, response_body)
google.auth.exceptions.RefreshError: ('invalid_grant: Token has been expired or revoked.', '{\n  "error": "invalid_grant",\n  "error_description": "Token has been expired or revoked."\n}')

If you revoked the token, or it was automatically revoked for some reason, you will need to re-initialize it

--today event conflicts with cache

If the --today flag is passed, it will be ignored if events are already cached. This renders the today flag pretty much useless in some circumstances. And likewise if the --today flag is passed, then it isn't, still no events will show up because the cache won't update.
We could fix it by filtering out events that won't occur before today at midnight after the following line:
https://github.com/rosenpin/i3-agenda/pull/60/files#diff-821976daf1fa35b6e9ffdc01f915b015c451d21b8ca7c96d736fe4a9492f364eR30

def load_events(args) -> List[Event]:
    events = None
    if not args.update:
        events = load_cache(args.cachettl)
        # HERE
        # add filter call here, filter irrelevant events if the today flag is set to True
    if events is None:
        events = get_events(args.credentials, args.ids, args.maxres, args.today)
        save_cache(events)
    return events

found here #60 (comment)

Add option to clear cache

Something like --refresh or --update to prevent the function load_cache() of returning the event list.

This is useful after you update something in the calendar and want to force the update without setting --cachettl to a low value or deleting the file manually.

i3agenda_google_token.pickle not found

Hi, I followed the instruction and encountered the following error after I authorize it in the browser. Could you help me with it? Thank you!

❯ i3-agenda -c ~/client_secret_googleusercontent.com.json
Please visit this URL to authorize this application: https://accounts.google.com/.....

Traceback (most recent call last):
  File "/Users/A.Y/miniconda3/bin/i3-agenda", line 8, in <module>
    sys.exit(main())
  File "/Users/A.Y/miniconda3/lib/python3.8/site-packages/i3_agenda/__init__.py", line 42, in main
    events = load_events(args)
  File "/Users/A.Y/miniconda3/lib/python3.8/site-packages/i3_agenda/__init__.py", line 33, in load_events
    events = get_events(args.credentials, args.ids, args.maxres, args.today)
  File "/Users/A.Y/miniconda3/bin/API.py", line 121, in get_events
    service = connect(credentials)
  File "/Users/A.Y/miniconda3/bin/API.py", line 19, in connect
    creds = get_credentials(credspath)
  File "/Users/A.Y/miniconda3/bin/API.py", line 47, in get_credentials
    with open(TMP_TOKEN, "wb") as token:
FileNotFoundError: [Errno 2] No such file or directory: '/Users/A.Y/.i3agenda/i3agenda_google_token.pickle'

Dependency Error

Under current Manjaro/i3 I get this (possible) python dependency error while executing i3agenda:

Traceback (most recent call last):
  File "/usr/bin/i3-agenda", line 33, in <module>
    sys.exit(load_entry_point('i3-agenda==1.3', 'console_scripts', 'i3-agenda')())
  File "/usr/bin/i3-agenda", line 22, in importlib_load_entry_point
    for entry_point in distribution(dist_name).entry_points
  File "/usr/lib/python3.9/importlib/metadata.py", line 524, in distribution
    return Distribution.from_name(distribution_name)
  File "/usr/lib/python3.9/importlib/metadata.py", line 187, in from_name
    raise PackageNotFoundError(name)
importlib.metadata.PackageNotFoundError: i3-agenda

I hope you can help

Suddenly "Bad Request" Error

My output on arch

➜  Downloads i3-agenda -c ~/Dropbox/else/WEB/.google_credentials.json -ttl 60
Traceback (most recent call last):
  File "/usr/bin/i3-agenda", line 33, in <module>
    sys.exit(load_entry_point('i3-agenda==1.5', 'console_scripts', 'i3-agenda')())
  File "/usr/lib/python3.9/site-packages/i3_agenda/__init__.py", line 132, in main
    service = connect(args.credentials)
  File "/usr/lib/python3.9/site-packages/i3_agenda/__init__.py", line 348, in connect
    creds.refresh(Request())
  File "/usr/lib/python3.9/site-packages/google/oauth2/credentials.py", line 208, in refresh
    access_token, refresh_token, expiry, grant_response = _client.refresh_grant(
  File "/usr/lib/python3.9/site-packages/google/oauth2/_client.py", line 248, in refresh_grant
    response_data = _token_endpoint_request(request, token_uri, body)
  File "/usr/lib/python3.9/site-packages/google/oauth2/_client.py", line 124, in _token_endpoint_request
    _handle_error_response(response_body)
  File "/usr/lib/python3.9/site-packages/google/oauth2/_client.py", line 60, in _handle_error_response
    raise exceptions.RefreshError(error_details, response_body)
google.auth.exceptions.RefreshError: ('invalid_grant: Bad Request', '{\n  "error": "invalid_grant",\n  "error_description": "Bad Request"\n}')

Not sure what happened... Thank you!

cache is never updated

Looking at the code I see :

def load_cache(cachettl: int) -> Optional[List[Event]]:
    if not os.path.exists(CACHE_PATH):
        return None

    if os.path.getmtime(CACHE_PATH) - time.time() > cachettl * 60:
        return None

But os.path.getmtime(CACHE_PATH) - time.time() is negative and thus the function always return the cache content, whatever the value of cachettl is.

Make the Google authentication file more persistent

Currently, it's saved in /tmp, meaning it will prompt the user to sign in on every reboot.
If we place it somewhere in the user's home it should survive reboots. If we're going this way this path should also be specified as a command line argument

Catch exception and only show them when verbose

Catch exceptions and only show them when used with a -v flag.

When an exception occurs we should only show a short message like "failed getting events".

This is so when the user doesn't have internet access a short message will be shown instead of "traceback error..."

Display the event date

I'm wondering if it wouldn't make sense to display the event date if the event doesn't occur "today"?

For instance, the next event currently in my personal calendar isn't until 22:00 tomorrow. However, the i3-agenda script outputs it as just 22:00 (omitting the date).

What is your opinion?

Bug: KeyError when The Event has no Summary Field

➜ Downloads i3-agenda
Traceback (most recent call last):
File "/usr/bin/i3-agenda", line 8, in
sys.exit(main())
File "/usr/lib/python3.8/site-packages/i3_agenda/init.py", line 97, in main
events = getEvents(service, allowed_calendars_ids, args.maxres,
File "/usr/lib/python3.8/site-packages/i3_agenda/init.py", line 147, in getEvents
all.append(Event(event['summary'], is_allday(start_time), unix_time, end_time))
KeyError: 'summary'

Looks like some commit broke it cuz it used to work for me on Manjaro i3. After adding a summary field, it works again.

Move calendars ids to command line argument

Currently there's a list of calendar IDs in the beginning of the script, I would prefer it if it will be provided as command line arguments instead

This way, users will not have to modify the script to select specific calendars

Looking for maintainer

I no longer use i3 (moved to mac) so I no longer use and update this plugin.
Looking for someone to help maintain this repo
I can continue doing code reviews but it will be difficult for me to test this plugin as a menu bar
For more details or if you are interested feel free to email me or comment on this issue

Crash when --credentials is empty

Traceback (most recent call last):
  File "./__init__.py", line 149, in <module>
    main()
  File "./__init__.py", line 45, in main
    service = connect(args.credentials)
  File "./__init__.py", line 132, in connect
    if not os.path.exists(credspath):
  File "/usr/lib/python3.8/genericpath.py", line 19, in exists
    os.stat(path)
TypeError: stat: path should be string, bytes, os.PathLike or integer, not NoneType

module 'pyparsing' has no attribute 'downcaseTokens'

I think maybe my Arch upgraded the package too forward and broke a dependency.

Downloads i3-agenda -c /home/zack/drive/else/Configs/google_calendar_credentials.json -ttl 10     
Traceback (most recent call last):
  File "/usr/bin/i3-agenda", line 33, in <module>
    sys.exit(load_entry_point('i3-agenda==1.6.3', 'console_scripts', 'i3-agenda')())
  File "/usr/lib/python3.9/site-packages/i3_agenda/__init__.py", line 59, in main
    events = load_events(args)
  File "/usr/lib/python3.9/site-packages/i3_agenda/__init__.py", line 39, in load_events
    from API import get_events
  File "/usr/bin/API.py", line 9, in <module>
    from googleapiclient.discovery import build, Resource
  File "/usr/lib/python3.9/site-packages/googleapiclient/discovery.py", line 42, in <module>
    import httplib2
  File "/usr/lib/python3.9/site-packages/httplib2/__init__.py", line 52, in <module>
    from . import auth
  File "/usr/lib/python3.9/site-packages/httplib2/auth.py", line 20, in <module>
    auth_param_name = token.copy().setName("auth-param-name").addParseAction(pp.downcaseTokens)
AttributeError: module 'pyparsing' has no attribute 'downcaseTokens'

Error after upgrade

Traceback (most recent call last):
  File "/usr/lib/python3.9/site-packages/pkg_resources/__init__.py", line 568, in _build_master
    ws.require(__requires__)
  File "/usr/lib/python3.9/site-packages/pkg_resources/__init__.py", line 886, in require
    needed = self.resolve(parse_requirements(requirements))
  File "/usr/lib/python3.9/site-packages/pkg_resources/__init__.py", line 777, in resolve
    raise VersionConflict(dist, req).with_context(dependent_req)
pkg_resources.ContextualVersionConflict: (chardet 4.0.0 (/usr/lib/python3.9/site-packages), Requirement.parse('chardet<4.0,>=2.0'), {'aiohttp'})

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/bin/i3-agenda", line 33, in <module>
    sys.exit(load_entry_point('i3-agenda==1.4', 'console_scripts', 'i3-agenda')())
  File "/usr/bin/i3-agenda", line 25, in importlib_load_entry_point
    return next(matches).load()
  File "/usr/lib/python3.9/importlib/metadata.py", line 77, in load
    module = import_module(match.group('module'))
  File "/usr/lib/python3.9/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 972, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
  File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 664, in _load_unlocked
  File "<frozen importlib._bootstrap>", line 627, in _load_backward_compatible
  File "<frozen zipimport>", line 259, in load_module
  File "/usr/lib/python3.9/site-packages/i3_agenda-1.4-py3.9.egg/i3_agenda/__init__.py", line 19, in <module>
  File "/home/tomer/.local/lib/python3.9/site-packages/googleapiclient/discovery.py", line 49, in <module>
    import google.api_core.client_options
  File "/home/tomer/.local/lib/python3.9/site-packages/google/api_core/__init__.py", line 20, in <module>
    from pkg_resources import get_distribution
  File "/usr/lib/python3.9/site-packages/pkg_resources/__init__.py", line 3243, in <module>
    def _initialize_master_working_set():
  File "/usr/lib/python3.9/site-packages/pkg_resources/__init__.py", line 3226, in _call_aside
    f(*args, **kwargs)
  File "/usr/lib/python3.9/site-packages/pkg_resources/__init__.py", line 3255, in _initialize_master_working_set
    working_set = WorkingSet._build_master()
  File "/usr/lib/python3.9/site-packages/pkg_resources/__init__.py", line 570, in _build_master
    return cls._build_from_requirements(__requires__)
  File "/usr/lib/python3.9/site-packages/pkg_resources/__init__.py", line 583, in _build_from_requirements
    dists = ws.resolve(reqs, Environment())
  File "/usr/lib/python3.9/site-packages/pkg_resources/__init__.py", line 772, in resolve
    raise DistributionNotFound(req, requirers)
pkg_resources.DistributionNotFound: The 'chardet<4.0,>=2.0' distribution was not found and is required by aiohttp

On arch after package update you may run into the above errors.

Solution

To fix it, you need to update aiohttp. Just run the following command:
pip install aiohttp

Google Refresh Token error

Traceback (most recent call last):
  File "/opt/homebrew/bin/i3-agenda", line 8, in <module>
    sys.exit(main())
  File "/opt/homebrew/lib/python3.9/site-packages/i3_agenda/__init__.py", line 59, in main
    events = load_events(args)
  File "/opt/homebrew/lib/python3.9/site-packages/i3_agenda/__init__.py", line 50, in load_events
    events = get_events(args.credentials, args.ids, args.maxres, args.today)
  File "/opt/homebrew/bin/API.py", line 122, in get_events
    service = connect(credentials)
  File "/opt/homebrew/bin/API.py", line 19, in connect
    creds = get_credentials(credspath)
  File "/opt/homebrew/bin/API.py", line 43, in get_credentials
    creds.refresh(Request())
  File "/opt/homebrew/lib/python3.9/site-packages/google/oauth2/credentials.py", line 302, in refresh
    ) = reauth.refresh_grant(
  File "/opt/homebrew/lib/python3.9/site-packages/google/oauth2/reauth.py", line 347, in refresh_grant
    _client._handle_error_response(response_data)
  File "/opt/homebrew/lib/python3.9/site-packages/google/oauth2/_client.py", line 60, in _handle_error_response
    raise exceptions.RefreshError(error_details, response_data)
google.auth.exceptions.RefreshError: ('invalid_grant: Token has been expired or revoked.', {'error': 'invalid_grant', 'error_description': 'Token has been expired or revoked.'})

I got this error. I tried generating a different credentials.json file but it still didn't work. Is there any way to fix this

Exits with stacktrace after upgrading python-google-auth from 1.21.3 -> 1.22.0

System

  • OS: Arch Linux 5.8.12-zen
  • python up to date
  • python-google-auth 1.22.0
  • i3-agenda version 1.3-1 from the AUR

Stacktrace

Traceback (most recent call last):
  File "/usr/bin/i3-agenda", line 33, in <module>
    sys.exit(load_entry_point('i3-agenda==1.3', 'console_scripts', 'i3-agenda')())
  File "/usr/bin/i3-agenda", line 25, in importlib_load_entry_point
    return next(matches).load()
  File "/usr/lib/python3.8/importlib/metadata.py", line 77, in load
    module = import_module(match.group('module'))
  File "/usr/lib/python3.8/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
  File "<frozen importlib._bootstrap>", line 991, in _find_and_load
  File "<frozen importlib._bootstrap>", line 961, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
  File "<frozen importlib._bootstrap>", line 991, in _find_and_load
  File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 671, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 783, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/usr/lib/python3.8/site-packages/i3_agenda/__init__.py", line 18, in <module>
    from google_auth_oauthlib.flow import InstalledAppFlow
  File "/usr/lib/python3.8/site-packages/google_auth_oauthlib/__init__.py", line 21, in <module>
    from .interactive import get_user_credentials
  File "/usr/lib/python3.8/site-packages/google_auth_oauthlib/interactive.py", line 24, in <module>
    import google_auth_oauthlib.flow
  File "/usr/lib/python3.8/site-packages/google_auth_oauthlib/flow.py", line 68, in <module>
    import google.oauth2.credentials
  File "/usr/lib/python3.8/site-packages/google/oauth2/credentials.py", line 44, in <module>
    from google.oauth2 import _client
  File "/usr/lib/python3.8/site-packages/google/oauth2/_client.py", line 35, in <module>
    from google.auth import jwt
  File "/usr/lib/python3.8/site-packages/google/auth/jwt.py", line 57, in <module>
    from google.auth import _service_account_info
  File "/usr/lib/python3.8/site-packages/google/auth/_service_account_info.py", line 22, in <module>
    from google.auth import crypt
  File "/usr/lib/python3.8/site-packages/google/auth/crypt/__init__.py", line 43, in <module>
    from google.auth.crypt import rsa
  File "/usr/lib/python3.8/site-packages/google/auth/crypt/rsa.py", line 20, in <module>
    from google.auth.crypt import _cryptography_rsa
  File "/usr/lib/python3.8/site-packages/google/auth/crypt/_cryptography_rsa.py", line 28, in <module>
    import pkg_resources
  File "/usr/lib/python3.8/site-packages/pkg_resources/__init__.py", line 3239, in <module>
    def _initialize_master_working_set():
  File "/usr/lib/python3.8/site-packages/pkg_resources/__init__.py", line 3222, in _call_aside
    f(*args, **kwargs)
  File "/usr/lib/python3.8/site-packages/pkg_resources/__init__.py", line 3251, in _initialize_master_working_set
    working_set = WorkingSet._build_master()
  File "/usr/lib/python3.8/site-packages/pkg_resources/__init__.py", line 567, in _build_master
    ws.require(__requires__)
  File "/usr/lib/python3.8/site-packages/pkg_resources/__init__.py", line 884, in require
    needed = self.resolve(parse_requirements(requirements))
  File "/usr/lib/python3.8/site-packages/pkg_resources/__init__.py", line 770, in resolve
    raise DistributionNotFound(req, requirers)
pkg_resources.DistributionNotFound: The 'aiohttp<4.0.0dev,>=3.6.2' distribution was not found and is required by google-auth

Looks like just a dependency, I'll see what I can find.

Google Refresh Token error

Traceback (most recent call last):
  File "/opt/homebrew/bin/i3-agenda", line 8, in <module>
    sys.exit(main())
  File "/opt/homebrew/lib/python3.9/site-packages/i3_agenda/__init__.py", line 59, in main
    events = load_events(args)
  File "/opt/homebrew/lib/python3.9/site-packages/i3_agenda/__init__.py", line 50, in load_events
    events = get_events(args.credentials, args.ids, args.maxres, args.today)
  File "/opt/homebrew/bin/API.py", line 122, in get_events
    service = connect(credentials)
  File "/opt/homebrew/bin/API.py", line 19, in connect
    creds = get_credentials(credspath)
  File "/opt/homebrew/bin/API.py", line 43, in get_credentials
    creds.refresh(Request())
  File "/opt/homebrew/lib/python3.9/site-packages/google/oauth2/credentials.py", line 302, in refresh
    ) = reauth.refresh_grant(
  File "/opt/homebrew/lib/python3.9/site-packages/google/oauth2/reauth.py", line 347, in refresh_grant
    _client._handle_error_response(response_data)
  File "/opt/homebrew/lib/python3.9/site-packages/google/oauth2/_client.py", line 60, in _handle_error_response
    raise exceptions.RefreshError(error_details, response_data)
google.auth.exceptions.RefreshError: ('invalid_grant: Token has been expired or revoked.', {'error': 'invalid_grant', 'error_description': 'Token has been expired or revoked.'})

I got this error. I tried generating a different credentials.json file but it still didn't work. Is there any way to fix this

Limiting Size of Summary

When the size of the summary of a event is too long my i3bar gets messy. So I'm proposing to consider adding a command line argument to choose the size of the summaries, putting "..." to the end to indicate that it is cut. Like -l 7, and the event that was like "meeting with costumer" would turn to "meeting...".

help message for the --date-format flag is missleading

the date-format flag is only respected if there are no events in the next week. If there's an event today, no date will appear. If the event is tomorrow, "Tomorrow at ..." will appear. If it's this week, it will say "Friday at ..." For example.

The help message should mention that it will only be respected if there are no events in the next week

        if self.is_today():
            return f"{event_datetime:%H:%M} " + result
        elif self.is_tomorrow():
            return f"{event_datetime:Tomorrow at %H:%M} " + result
        elif self.is_this_week():
            return f"{event_datetime:%a at %H:%M} " + result
        else:
            return f"{event_datetime:{date_format} at %H:%M} " + result

AUR i3-agenda-git installation - No module named 'config'

Hi @rosenpin,
I wanted to get latest version in order to follow your advice about #35, unfortunately I hit an after-installation issue. The executable can not run and this is the error:


Package (1)    Old Version        New Version        Net Change

i3-agenda-git  1.6.r0.gadd66eb-1  1.6.r0.gadd66eb-1    0.00 MiB

~ took 20s 

➜ i3-agenda
Traceback (most recent call last):
  File "/usr/bin/i3-agenda", line 33, in <module>
    sys.exit(load_entry_point('i3-agenda==1.6', 'console_scripts', 'i3-agenda')())
  File "/usr/bin/i3-agenda", line 25, in importlib_load_entry_point
    return next(matches).load()
  File "/usr/lib/python3.9/importlib/metadata.py", line 77, in load
    module = import_module(match.group('module'))
  File "/usr/lib/python3.9/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 972, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
  File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 680, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 850, in exec_module
  File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
  File "/usr/lib/python3.9/site-packages/i3_agenda/__init__.py", line 6, in <module>
    import config
ModuleNotFoundError: No module named 'config'

Do you have any advice? It was working when I installed just yay i3-agenda

aur package is installing lib files in /usr/bin

while it's already in /usr/lib :

chmouel@pignon 🦅 ~% pacman -Ql i3-agenda-git|grep .py$    
i3-agenda-git /usr/bin/API.py
i3-agenda-git /usr/bin/cache_utils.py
i3-agenda-git /usr/bin/config.py
i3-agenda-git /usr/bin/event.py
i3-agenda-git /usr/lib/python3.10/site-packages/i3_agenda/API.py
i3-agenda-git /usr/lib/python3.10/site-packages/i3_agenda/__init__.py
i3-agenda-git /usr/lib/python3.10/site-packages/i3_agenda/cache_utils.py
i3-agenda-git /usr/lib/python3.10/site-packages/i3_agenda/config.py
i3-agenda-git /usr/lib/python3.10/site-packages/i3_agenda/event.py
chmouel@pignon 🦅 ~% 

Long-lasting Focus/Highlight Color

image

As you can see at the bottom, my event is in red text and white background. It seems to start when the event is about to happen but it just doesn't go away even after the starting time of the event. Left and/or right clicking doesn't get rid of it. Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.