Remove usage of HistoryManager and replace with simplistic Undo logic

This commit is contained in:
Xevion
2021-09-03 20:06:53 -05:00
parent 925a5517b2
commit efb1b711be
3 changed files with 32 additions and 23 deletions

View File

@@ -17,6 +17,7 @@ from tzlocal import get_localzone
# If modifying these scopes, delete the file token.json.
from bulk_reminders import undo
from bulk_reminders.undo import IDPair
SCOPES = ['https://www.googleapis.com/auth/calendar']
TIME_REGEX = re.compile(r'\d{2}:\d{2}(?:AM|PM)')
@@ -118,14 +119,14 @@ class Event(object):
self.summary, self.start, self.end, self.description, self.status = summary, start, end, description, status
@classmethod
def from_api(cls, event: dict, history: Optional[undo.HistoryManager]) -> 'Event':
def from_api(cls, event: dict, history: List[IDPair]) -> 'Event':
"""Returns a Event object from a Google API Engine item."""
undo_stage = history.exists(event.get('id')) if history is not None else -1
in_history = any(pair.eventID == event.get('id') for pair in history)
return Event(summary=event.get('summary'),
start=isoparse(event['start'].get('dateTime', event['start'].get('date'))),
end=isoparse(event['end'].get('dateTime', event['end'].get('date'))),
description=event.get('description'),
status=f'Stage {undo_stage}' if undo_stage != -1 else 'Foreign')
status='Undoable' if in_history else 'Foreign')
@property
def body(self) -> dict:

View File

@@ -1,15 +1,15 @@
import logging
from typing import Iterator, List
from typing import Any, List, Set
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QMainWindow, QMessageBox
from bulk_reminders import api, undo
from bulk_reminders import api
from bulk_reminders.api import Event
from bulk_reminders.gui_base import Ui_MainWindow
from bulk_reminders.load import LoadDialog
from bulk_reminders.oauth import OAuthDialog
from bulk_reminders.undo import IDPair, Stage
from bulk_reminders.undo import IDPair
logging.basicConfig(format='[%(asctime)s] [%(levelname)s] [%(threadName)s] %(message)s')
logger = logging.getLogger(__file__)
@@ -60,7 +60,8 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.undoButton.clicked.connect(self.undo)
self.submitButton.clicked.connect(self.submit)
self.history = undo.HistoryManager('history.json')
self.history: List[IDPair] = []
self.historyCalendarID: str = ''
# Disable the undo button until undo stages are available
if len(self.history) == 0:
@@ -86,31 +87,31 @@ class MainWindow(QMainWindow, Ui_MainWindow):
def undo(self) -> None:
"""Get the latest undo stage and delete all events in that stage"""
latest = self.history.pop()
logging.info(f'Deleting {len(latest.events)} Events from Calendar {latest.commonCalendar}')
logging.info(f'Deleting {len(self.history)} Events from Calendar {self.historyCalendarID}')
self.progressBar.show()
self.progressBar.setMaximum(len(latest.events))
for i, entry in enumerate(latest.events):
self.progressBar.setMaximum(len(self.history))
for i, entry in enumerate(self.history):
logging.debug(f'Deleting Event {entry.eventID}')
self.calendar.service.events().delete(calendarId=entry.calendarID, eventId=entry.eventID).execute()
self.progressBar.setValue(i + 1)
self.progressBar.hide()
# Disable the undo button until undo stages are available
self.history = []
self.undoButton.setDisabled(len(self.history) == 0)
self.populate() # Refresh
def getForeign(self) -> Iterator[IDPair]:
def getForeign(self) -> Set[Any]:
"""Returns all events currently tracked that are not stored in the undo."""
undoableIDs = set(self.history.all_pairs())
for apiEvent in self.apiEvents:
pair = IDPair(calendarID=self.currentCalendarID, eventID=apiEvent['id'])
if pair not in undoableIDs:
yield pair
foreign = {event.get('id'): event for event in self.apiEvents}
undoableIDs = set(pair.eventID for pair in self.history)
return {foreign[eventID] for eventID in undoableIDs.difference(foreign.keys())}
def submit(self) -> None:
newStage = Stage(index=self.history.nextIndex(), commonCalendar=self.currentCalendarID)
self.historyCalendarID = self.currentCalendarID
self.history = []
logger.info(f'Submitting {len(self.readyEvents)} events to API')
self.progressBar.show()
@@ -118,13 +119,13 @@ class MainWindow(QMainWindow, Ui_MainWindow):
for i, event in enumerate(self.readyEvents):
logger.debug(f'Submitting "{event.summary}" scheduled to start on {event.start.isoformat()}....')
result = self.calendar.service.events().insert(calendarId=self.currentCalendarID, body=event.body).execute()
newStage.events.append(IDPair(self.currentCalendarID, result.get('id')))
self.history.append(IDPair(self.currentCalendarID, result.get('id')))
self.progressBar.setValue(i + 1)
self.undoButton.setDisabled(len(self.history) == 0)
self.readyEvents.clear()
self.progressBar.hide()
self.history.addStage(newStage)
self.populate()
def populate(self) -> None:
@@ -134,9 +135,9 @@ class MainWindow(QMainWindow, Ui_MainWindow):
events = list(self.readyEvents)
events.extend([Event.from_api(event, self.history) for event in self.apiEvents])
ready, undoable, stage, foreign = len(self.readyEvents), self.history.getTotal(), len(self.history), len(list(self.getForeign()))
ready, undoable, foreign = len(self.readyEvents), len(self.history), len(list(self.getForeign()))
total = ready + undoable + foreign
self.eventCountLabel.setText(f'{len(self.readyEvents)} ready, {undoable} undoable in {stage} stages, {foreign} foreign ({total})')
self.eventCountLabel.setText(f'{len(self.readyEvents)} ready, {undoable} undoable, {foreign} foreign ({total})')
self.eventsView.setRowCount(len(events))
logger.debug(f'Populating table with {self.eventsView.rowCount()} events.')

View File

@@ -1,6 +1,6 @@
import logging
import os
from typing import Iterator, List
from typing import Any, Iterator, List
import jsonpickle
@@ -68,6 +68,13 @@ class HistoryManager(object):
self.stages.insert(0, newStage)
self.save()
def verify(self, calendarID: str, known_events: List[Any]) -> None:
"""Given a calendar ID and a list of events from this calendar, make sure there are no IDPairs in storage that no longer exist any more."""
pass
def collapse(self) -> None:
pass
class Stage(object):
def __init__(self, index: int, commonCalendar: str) -> None: