Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions gcalcli/argparsers.py
Original file line number Diff line number Diff line change
Expand Up @@ -609,6 +609,12 @@ def get_argument_parser():
'from lavender, sage, grape, flamingo, banana, tangerine, '
'peacock, graphite, blueberry, basil, tomato.',
)
add.add_argument(
'--availability',
default='busy',
choices=['free', 'busy'],
help='Event availability (free/busy status). Default is busy.',
)
add.add_argument('--title', default=None, type=str, help='Event title')
add.add_argument(
'--who',
Expand Down
3 changes: 2 additions & 1 deletion gcalcli/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,8 @@ def main():

gcal.AddEvent(parsed_args.title, parsed_args.where, estart, eend,
parsed_args.description, parsed_args.who,
parsed_args.reminders, parsed_args.event_color)
parsed_args.reminders, parsed_args.event_color,
parsed_args.availability)

elif parsed_args.command == 'search':
gcal.TextQuery(
Expand Down
12 changes: 12 additions & 0 deletions gcalcli/details.py
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,17 @@ class ID(SimpleSingleFieldHandler):
fieldnames = ['id']


class Availability(SimpleSingleFieldHandler):
"""Handler for event availability (free/busy)."""

fieldnames = ['transparency']

@classmethod
def _get(cls, event):
val = event.get(cls.fieldnames[0], 'opaque')
return 'free' if val == 'transparent' else 'busy'


Comment on lines +362 to +369
Copy link

Copilot AI Feb 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Availability is currently using fieldnames = ['transparency'], which makes TSV output label the column as transparency even though values are free/busy. It also makes agendaupdate patch/insert treat the input field as transparency and the inherited _patch will set the event's transparency to free/busy (invalid for the Google API). Suggest using fieldnames = ['availability'] and overriding _patch to map free|busy to transparent|opaque (and keeping _get reading from event.get('transparency', 'opaque')).

Suggested change
fieldnames = ['transparency']
@classmethod
def _get(cls, event):
val = event.get(cls.fieldnames[0], 'opaque')
return 'free' if val == 'transparent' else 'busy'
fieldnames = ['availability']
@classmethod
def _get(cls, event):
# Read the underlying Google API transparency value and map it
# to a user-facing availability value.
val = event.get('transparency', 'opaque')
return 'free' if val == 'transparent' else 'busy'
@classmethod
def _patch(cls, event, value):
"""Map user-facing availability (free/busy) to API transparency."""
if value == 'free':
event['transparency'] = 'transparent'
elif value == 'busy':
event['transparency'] = 'opaque'
else:
raise ReadonlyError('availability',
f"invalid availability value: {value}")

Copilot uses AI. Check for mistakes.
class Action(SingleFieldHandler):
"""Handler specifying event processing during an update."""

Expand All @@ -377,6 +388,7 @@ def _get(cls, event):
('calendar', Calendar),
('email', Email),
('attendees', Attendees),
('availability', Availability),
('action', Action)])
HANDLERS_READONLY = {Url, Calendar}

Expand Down
4 changes: 3 additions & 1 deletion gcalcli/gcal.py
Original file line number Diff line number Diff line change
Expand Up @@ -1464,12 +1464,14 @@ def QuickAddEvent(self, event_text, reminders=None):

return new_event

def AddEvent(self, title, where, start, end, descr, who, reminders, color):
def AddEvent(self, title, where, start, end, descr, who, reminders, color,
availability='busy'):

calendar = self._prompt_for_calendar(self.cals)

event = {}
event['summary'] = title
event['transparency'] = 'transparent' if availability == 'free' else 'opaque'
Copy link

Copilot AI Feb 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line exceeds the configured Ruff line-length (80) and will likely fail formatting/linting. Consider wrapping it over multiple lines (or using an explicit mapping/dict) to keep within the project's line-length limit.

Suggested change
event['transparency'] = 'transparent' if availability == 'free' else 'opaque'
if availability == 'free':
event['transparency'] = 'transparent'
else:
event['transparency'] = 'opaque'

Copilot uses AI. Check for mistakes.

if self.options['allday']:
event['start'] = {'date': start}
Expand Down
20 changes: 20 additions & 0 deletions tests/test_gcalcli.py
Original file line number Diff line number Diff line change
Expand Up @@ -393,3 +393,23 @@ def test_next_cut(PatchedGCalI):

event_title = "樹貞 fun fun fun"
assert gcal._next_cut(event_title) == (8, 6)

def test_add_event_availability(PatchedGCalI):
cal_names = parse_cal_names(['jcrowgey@uw.edu'], printer=None)
gcal = PatchedGCalI(
cal_names=cal_names, allday=False, default_reminders=True)
assert gcal.AddEvent(title='transparent event',
where='anywhere',
start='now',
end='tomorrow',
descr='testing',
who='anyone',
reminders=None,
color='banana',
availability='free')

gcal.api_tracker.verify_all_mutating_calls([
CallMatcher('insert',
body_has_fields={'summary', 'start', 'end', 'transparency'},
body_fields={'transparency': 'transparent'})
])
Copy link

Copilot AI Feb 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new availability behavior is only tested for the free -> transparent branch. Since the code also sets opaque for the default/busy case (and always includes the transparency field), consider adding an assertion/test covering availability='busy' (or omitting the arg) to prevent regressions in the default behavior.

Suggested change
])
])
def test_add_event_availability_busy(PatchedGCalI):
cal_names = parse_cal_names(['jcrowgey@uw.edu'], printer=None)
gcal = PatchedGCalI(
cal_names=cal_names, allday=False, default_reminders=True)
assert gcal.AddEvent(title='opaque event',
where='anywhere',
start='now',
end='tomorrow',
descr='testing',
who='anyone',
reminders=None,
color='banana')
gcal.api_tracker.verify_all_mutating_calls([
CallMatcher('insert',
body_has_fields={'summary', 'start', 'end', 'transparency'},
body_fields={'transparency': 'opaque'})
])

Copilot uses AI. Check for mistakes.