Skip to content

[BUG] Sync from gcal to tw fails because of wrong duration format #141

@TxAnton

Description

@TxAnton

Describe the bug

Command running:
tw_gcal_sync --all -c "tw" --google-secret <my-google-secret> -v

Local (tw) changes are synced to google properly. However when I make any changes on google calendar and try to sync, it fails with an error:

taskw_ng.exceptions.TaskwarriorError: [b'task', b'rc.verbose=new-uuid', b'rc.json.array=TRUE', b'rc.confirmation=no', b'rc.dependency.confirmation=no', b'rc.recurrence.confirmation=no', b'rc.context=none', b'rc.uda.syncallduration.type=duration', b'rc.uda.syncallduration.label="Syncall Duration"', b'e4a1b40b-16b2-49bb-b20d-39c1699ea1ad', b'modify', b'description:"hello"', b'due:"20241214T003000Z"', b'entry:"20241214T233935Z"', b'modified:"20241215T001423Z"', b'scheduled:"20241213T000000Z"', b'status:"pending"', b'syncallduration:"0:30:00"'] #2; stderr:"b"The duration value '0:30:00' is not supported.""; stdout:"b''"
12:40:50.66 | WARNING  	| 

See full log at the end

The error itself "The duration value '0:30:00' is not supported." comes from taskwarrior, that expects duration in this format (ISO-8601 + aliases). But either google calendar of syncall gives colon-delimited time.

As a result nothing is synced, not just duration

To Reproduce

  1. task add hello due:tomorrow
  2. tw_gcal_sync ... should execute successfully.
  3. Open calendar to see event there, 30 minutes long
  4. Modify event on google calendar in any way (title, date, etc.)
  5. tw_gcal_sync ... gives "taskw_ng.exceptions.TaskwarriorError" as in description above

Expected Behavior

Duration should sync. So, converted to ISO_8601
But I'd personally be ok with it ignored. So maybe it cat be made optional

Versions

OS Version (cat /etc/*-release; uname -a)

PRETTY_NAME="LMDE 6 (faye)"
NAME="LMDE"
VERSION_ID="6"
VERSION="6 (faye)"
VERSION_CODENAME=faye
ID=linuxmint
HOME_URL="https://www.linuxmint.com/"
SUPPORT_URL="https://forums.linuxmint.com/"
BUG_REPORT_URL="http://linuxmint-troubleshooting-guide.readthedocs.io/en/latest/"
PRIVACY_POLICY_URL="https://www.linuxmint.com/"
ID_LIKE=debian
DEBIAN_CODENAME=bookworm
Linux skip 6.1.0-25-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.106-3 (2024-08-26) x86_64 GNU/Linux

Python version

Python 3.11.2

--version of your executable

tw_gcal_sync, version 1.8.8
Installed via pip install syncall[google,tw]

task --version
3.2.0

Additional context

tw_gtasks_sync actually behaves same way for me (sync to google tasks works, sync back doesn't), but no error is printed

Full log for tw_gcal_sync:

Click to expand
$ tw_gcal_sync --all -c "tw" --google-secret <my-google-secret> -v 
12:40:49.81 | DEBUG    	| Initialising...
12:40:49.81 | DEBUG    	| Initialising preferences manager -> /home/myuser/.config/syncall
12:40:49.81 | INFO     	| Loading preferences...
12:40:49.81 | DEBUG    	| Loading cached configuration - tw____None__.yaml
12:40:49.81 | INFO     	| 

Configuration: 
===============

  - TW Filter             : 
  - TW Tags               : ()
  - TW Project            : None
  - TW Sync All Tasks     : True
  - Google Calendar       : tw
  - Prefer scheduled dates: False



12:40:49.81 | DEBUG    	| Initializing Taskwarrior instance using config file: /home/myuser/.taskrc
12:40:49.81 | DEBUG    	| Using a custom configuration file ... -> tw____None__.yaml
12:40:49.81 | DEBUG    	| Initialising preferences manager -> /home/myuser/.config/syncall
12:40:49.81 | INFO     	| Loading preferences...
12:40:49.85 | DEBUG    	| Connecting to Google Calendar...
12:40:49.85 | INFO     	| Using already cached credentials...
12:40:50.27 | DEBUG    	| Connected to Google Calendar.
12:40:50.27 | INFO     	| Initializing Taskwarrior...
12:40:50.54 | DEBUG    	| Using the following filter to fetch TW tasks: (  )
12:40:50.61 | INFO     	| Detecting changes from GCal...
12:40:50.62 | DEBUG    	| 

New Items:      0
Modified Items: 1
	e8u8vvj9184gjn1khh8lf3s0po
Deleted Item:   0

12:40:50.62 | INFO     	| Detecting changes from Tw...
12:40:50.62 | DEBUG    	| 

New Items:      0
Modified Items: 0
Deleted Item:   0

12:40:50.62 | DEBUG    	| Fetching GCal item for id -> e8u8vvj9184gjn1khh8lf3s0po
12:40:50.62 | INFO     	| [GCal] Updating item [hello     ] at Tw...
12:40:50.65 | ERROR    	| [Tw Update an item using the given side helper] Operation failed.
12:40:50.65 | DEBUG    	| [Tw Update an item using the given side helper] Operation failed.
Traceback (most recent call last):

  File "/home/myuser/.venv/bin/tw_gcal_sync", line 8, in <module>
    sys.exit(main())
    │   │    └ <Command main>
    │   └ <bound method ExitHooks.exit of <bubop.exit_hooks.ExitHooks object at 0x7f0efd98e210>>
    └ <module 'sys' (built-in)>
  File "/home/myuser/.venv/lib/python3.11/site-packages/click/core.py", line 1157, in __call__
    return self.main(*args, **kwargs)
           │    │     │       └ {}
           │    │     └ ()
           │    └ <function BaseCommand.main at 0x7f0eff9d18a0>
           └ <Command main>
  File "/home/myuser/.venv/lib/python3.11/site-packages/click/core.py", line 1078, in main
    rv = self.invoke(ctx)
         │    │      └ <click.core.Context object at 0x7f0effbe4f90>
         │    └ <function Command.invoke at 0x7f0eff9d2480>
         └ <Command main>
  File "/home/myuser/.venv/lib/python3.11/site-packages/click/core.py", line 1434, in invoke
    return ctx.invoke(self.callback, **ctx.params)
           │   │      │    │           │   └ {'tw_project': None, 'pdb_on_error': False, 'tw_sync_all_tasks': True, 'gcal_calendar': 'tw', 'google_secret': '/home/myuser/Do...
           │   │      │    │           └ <click.core.Context object at 0x7f0effbe4f90>
           │   │      │    └ <function main at 0x7f0efd141d00>
           │   │      └ <Command main>
           │   └ <function Context.invoke at 0x7f0eff9d0e00>
           └ <click.core.Context object at 0x7f0effbe4f90>
  File "/home/myuser/.venv/lib/python3.11/site-packages/click/core.py", line 783, in invoke
    return __callback(*args, **kwargs)
                       │       └ {'tw_project': None, 'pdb_on_error': False, 'tw_sync_all_tasks': True, 'gcal_calendar': 'tw', 'google_secret': '/home/myuser/Do...
                       └ ()
  File "/home/myuser/.venv/lib/python3.11/site-packages/syncall/scripts/tw_gcal_sync.py", line 226, in main
    aggregator.sync()
    │          └ <function Aggregator.sync at 0x7f0efd336f20>
    └ <syncall.aggregator.Aggregator object at 0x7f0efd1b7a10>
  File "/home/myuser/.venv/lib/python3.11/site-packages/syncall/aggregator.py", line 215, in sync
    self._synchronizer.sync(changes_A=changes_A, changes_B=changes_B)
    │    │             │              │                    └ SideChanges(new=set(), modified=set(), deleted=set())
    │    │             │              └ SideChanges(new=set(), modified={'e8u8vvj9184gjn1khh8lf3s0po'}, deleted=set())
    │    │             └ <function Synchronizer.sync at 0x7f0efed53d80>
    │    └ <item_synchronizer.synchronizer.Synchronizer object at 0x7f0efd1dc550>
    └ <syncall.aggregator.Aggregator object at 0x7f0efd1b7a10>
  File "/home/myuser/.venv/lib/python3.11/site-packages/item_synchronizer/synchronizer.py", line 153, in sync
    return self._sync(changes_A=changes_A, changes_B=changes_B)
           │    │               │                    └ SideChanges(new=set(), modified=set(), deleted=set())
           │    │               └ SideChanges(new=set(), modified={'e8u8vvj9184gjn1khh8lf3s0po'}, deleted=set())
           │    └ <function Synchronizer._sync at 0x7f0efed53ec0>
           └ <item_synchronizer.synchronizer.Synchronizer object at 0x7f0efd1dc550>
  File "/home/myuser/.venv/lib/python3.11/site-packages/item_synchronizer/synchronizer.py", line 270, in _sync
    self._convert_n_update_to_B(id_B, item_A)
    │    │                      │     └ {'kind': 'calendar#event', 'etag': '"3468511292674000"', 'id': 'e8u8vvj9184gjn1khh8lf3s0po', 'status': 'confirmed', 'htmlLink...
    │    │                      └ 'e4a1b40b-16b2-49bb-b20d-39c1699ea1ad'
    │    └ <function Synchronizer._convert_n_update_to_B at 0x7f0efed53ce0>
    └ <item_synchronizer.synchronizer.Synchronizer object at 0x7f0efd1dc550>
  File "/home/myuser/.venv/lib/python3.11/site-packages/item_synchronizer/synchronizer.py", line 141, in _convert_n_update_to_B
    self._updater_to_B(id_B, converted_item)
    │    │             │     └ {'annotations': [], 'status': 'pending', 'description': 'hello', 'syncallduration': datetime.timedelta(seconds=1800), 'due': ...
    │    │             └ 'e4a1b40b-16b2-49bb-b20d-39c1699ea1ad'
    │    └ <function Synchronizer._decide_catch_exc.<locals>.wrapper at 0x7f0efd1d1940>
    └ <item_synchronizer.synchronizer.Synchronizer object at 0x7f0efd1dc550>
> File "/home/myuser/.venv/lib/python3.11/site-packages/item_synchronizer/synchronizer.py", line 84, in wrapper
    return fn(*args, **kargs)
           │   │       └ {}
           │   └ ('e4a1b40b-16b2-49bb-b20d-39c1699ea1ad', {'annotations': [], 'status': 'pending', 'description': 'hello', 'syncallduration': ...
           └ functools.partial(<bound method Aggregator.updater_to of <syncall.aggregator.Aggregator object at 0x7f0efd1b7a10>>, helper=Si...
  File "/home/myuser/.venv/lib/python3.11/site-packages/syncall/aggregator.py", line 257, in updater_to
    side.update_item(item_id, **item)
    │    │           │          └ {'annotations': [], 'status': 'pending', 'description': 'hello', 'syncallduration': datetime.timedelta(seconds=1800), 'due': ...
    │    │           └ 'e4a1b40b-16b2-49bb-b20d-39c1699ea1ad'
    │    └ <function TaskWarriorSide.update_item at 0x7f0efd2d96c0>
    └ <syncall.taskwarrior.taskwarrior_side.TaskWarriorSide object at 0x7f0efd97c210>
  File "/home/myuser/.venv/lib/python3.11/site-packages/syncall/taskwarrior/taskwarrior_side.py", line 197, in update_item
    self._tw.task_update(d)
    │    │   │           └ {'description': 'hello', 'due': datetime.datetime(2024, 12, 14, 0, 30, tzinfo=tzutc()), 'entry': datetime.datetime(2024, 12, ...
    │    │   └ <function TaskWarrior.task_update at 0x7f0efd2d87c0>
    │    └ <taskw_ng.warrior.TaskWarrior object at 0x7f0efd33a990>
    └ <syncall.taskwarrior.taskwarrior_side.TaskWarriorSide object at 0x7f0efd97c210>
  File "/home/myuser/.venv/lib/python3.11/site-packages/taskw_ng/warrior.py", line 573, in task_update
    self._execute(task_uuid, "modify", *modification)
    │    │        │                     └ ['description:"hello"', 'due:"20241214T003000Z"', 'entry:"20241214T233935Z"', 'modified:"20241215T001423Z"', 'scheduled:"2024...
    │    │        └ UUID('e4a1b40b-16b2-49bb-b20d-39c1699ea1ad')
    │    └ <function TaskWarrior._execute at 0x7f0efd2c3ce0>
    └ <taskw_ng.warrior.TaskWarrior object at 0x7f0efd33a990>
  File "/home/myuser/.venv/lib/python3.11/site-packages/taskw_ng/warrior.py", line 248, in _execute
    raise TaskwarriorError(command, stderr, stdout, proc.returncode)
          │                │        │       │       │    └ 2
          │                │        │       │       └ <Popen: returncode: 2 args: [b'task', b'rc.verbose=new-uuid', b'rc.json.arra...>
          │                │        │       └ b''
          │                │        └ b"The duration value '0:30:00' is not supported.\n"
          │                └ [b'task', b'rc.verbose=new-uuid', b'rc.json.array=TRUE', b'rc.confirmation=no', b'rc.dependency.confirmation=no', b'rc.recurr...
          └ <class 'taskw_ng.exceptions.TaskwarriorError'>

taskw_ng.exceptions.TaskwarriorError: [b'task', b'rc.verbose=new-uuid', b'rc.json.array=TRUE', b'rc.confirmation=no', b'rc.dependency.confirmation=no', b'rc.recurrence.confirmation=no', b'rc.context=none', b'rc.uda.syncallduration.type=duration', b'rc.uda.syncallduration.label="Syncall Duration"', b'e4a1b40b-16b2-49bb-b20d-39c1699ea1ad', b'modify', b'description:"hello"', b'due:"20241214T003000Z"', b'entry:"20241214T233935Z"', b'modified:"20241215T001423Z"', b'scheduled:"20241213T000000Z"', b'status:"pending"', b'syncallduration:"0:30:00"'] #2; stderr:"b"The duration value '0:30:00' is not supported.""; stdout:"b''"
12:40:50.66 | WARNING  	| 

Google Calendar
---------------
	* Items created: 0
	* Items updated: 0
	* Items deleted: 0

Taskwarrior
-----------
	* Items created: 0
	* Items updated: 1
	* Items deleted: 0

12:40:50.69 | SUCCESS  	| Sync completed successfully. You can now use the -b/--combination option to refer to this particular combination

  tw_gcal_sync --combination tw____None__.yaml

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions