Repository: pimutils/khal
Issue: ikhal: Deleting multiple instances of the same recurring event raises khal.khalendar.exceptions.EtagMissmatch

I was experiencing the same issue as explained in #793. I saw this should have been fixed by  https://github.com/pimutils/khal/pull/1158/commits

So I updated my khal instance from github:

```
pip install --user git+https://github.com/pimutils/khal
...
Successfully installed khal-0.10.6.dev104+gb824798
```

In my calendar there is a recurring event from which I want to delete [EDIT:  ~two consecutive~ multiple] instances. If I do this in ikhal and close I ikhal, only the first instance is deleted and an exception is raised:

```python
Traceback (most recent call last):
  File "/home/lars/.local/lib/python3.10/site-packages/khal/ui/__init__.py", line 1364, in start_pane
    loop.run()
  File "/home/lars/.local/lib/python3.10/site-packages/urwid/main_loop.py", line 287, in run
    self._run()
  File "/home/lars/.local/lib/python3.10/site-packages/urwid/main_loop.py", line 385, in _run
    self.event_loop.run()
  File "/home/lars/.local/lib/python3.10/site-packages/urwid/main_loop.py", line 790, in run
    self._loop()
  File "/home/lars/.local/lib/python3.10/site-packages/urwid/main_loop.py", line 827, in _loop
    self._watch_files[fd]()
  File "/home/lars/.local/lib/python3.10/site-packages/urwid/raw_display.py", line 416, in <lambda>
    wrapper = lambda: self.parse_input(
  File "/home/lars/.local/lib/python3.10/site-packages/urwid/raw_display.py", line 515, in parse_input
    callback(processed, processed_codes)
  File "/home/lars/.local/lib/python3.10/site-packages/urwid/main_loop.py", line 412, in _update
    self.process_input(keys)
  File "/home/lars/.local/lib/python3.10/site-packages/urwid/main_loop.py", line 519, in process_input
    something_handled |= bool(self.unhandled_input(k))
  File "/home/lars/.local/lib/python3.10/site-packages/urwid/main_loop.py", line 565, in unhandled_input
    return self._unhandled_input(input)
  File "/home/lars/.local/lib/python3.10/site-packages/khal/ui/base.py", line 205, in on_key_press
    self.backtrack()
  File "/home/lars/.local/lib/python3.10/site-packages/khal/ui/base.py", line 190, in backtrack
    cb(data)
  File "/home/lars/.local/lib/python3.10/site-packages/khal/ui/__init__.py", line 1118, in cleanup
    self.collection.delete_instance(href, etag, account, rec_id)
  File "/home/lars/.local/lib/python3.10/site-packages/khal/khalendar/khalendar.py", line 243, in delete_instance
    raise EtagMissmatch()
khal.khalendar.exceptions.EtagMissmatch
```

EDIT: Deleting only one instance of a recurring event works as expected. It does not matter if I delete two or three events and the events do not have to be consecutive

Changed files:
khal/ui/__init__.py

diff --git a/khal/ui/__init__.py b/khal/ui/__init__.py
index 3a9f4379..da8e8de9 100644
--- a/khal/ui/__init__.py
+++ b/khal/ui/__init__.py
@@ -1109,12 +1109,20 @@ class ClassicView(Pane):
 
     def cleanup(self, data):
         """delete all events marked for deletion"""
+        # If we delete several recuids from the same vevent, the etag will
+        # change after each deletion. As we check for matching etags before
+        # deleting, deleting any subsequent recuids will fail.
+        # We therefore keep track of the etags of the events we already
+        # deleted.
+        updated_etags = {}
         for part in self._deleted[ALL]:
             account, href, etag = part.split('\\n', 2)
             self.collection.delete(href, etag, account)
         for part, rec_id in self._deleted[INSTANCES]:
             account, href, etag = part.split('\\n', 2)
-            self.collection.delete_instance(href, etag, account, rec_id)
+            etag = updated_etags.get(href) or etag
+            event = self.collection.delete_instance(href, etag, account, rec_id)
+            updated_etags[event.href] = event.etag
 
     def keypress(self, size, key):
         binds = self._conf['keybindings']