mirror of
https://github.com/Xevion/bulk-reminders.git
synced 2025-12-06 01:14:29 -06:00
Remove usage of HistoryManager and replace with simplistic Undo logic
This commit is contained in:
@@ -17,6 +17,7 @@ from tzlocal import get_localzone
|
|||||||
|
|
||||||
# If modifying these scopes, delete the file token.json.
|
# If modifying these scopes, delete the file token.json.
|
||||||
from bulk_reminders import undo
|
from bulk_reminders import undo
|
||||||
|
from bulk_reminders.undo import IDPair
|
||||||
|
|
||||||
SCOPES = ['https://www.googleapis.com/auth/calendar']
|
SCOPES = ['https://www.googleapis.com/auth/calendar']
|
||||||
TIME_REGEX = re.compile(r'\d{2}:\d{2}(?:AM|PM)')
|
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
|
self.summary, self.start, self.end, self.description, self.status = summary, start, end, description, status
|
||||||
|
|
||||||
@classmethod
|
@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."""
|
"""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'),
|
return Event(summary=event.get('summary'),
|
||||||
start=isoparse(event['start'].get('dateTime', event['start'].get('date'))),
|
start=isoparse(event['start'].get('dateTime', event['start'].get('date'))),
|
||||||
end=isoparse(event['end'].get('dateTime', event['end'].get('date'))),
|
end=isoparse(event['end'].get('dateTime', event['end'].get('date'))),
|
||||||
description=event.get('description'),
|
description=event.get('description'),
|
||||||
status=f'Stage {undo_stage}' if undo_stage != -1 else 'Foreign')
|
status='Undoable' if in_history else 'Foreign')
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def body(self) -> dict:
|
def body(self) -> dict:
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
import logging
|
import logging
|
||||||
from typing import Iterator, List
|
from typing import Any, List, Set
|
||||||
|
|
||||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||||
from PyQt5.QtWidgets import QMainWindow, QMessageBox
|
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.api import Event
|
||||||
from bulk_reminders.gui_base import Ui_MainWindow
|
from bulk_reminders.gui_base import Ui_MainWindow
|
||||||
from bulk_reminders.load import LoadDialog
|
from bulk_reminders.load import LoadDialog
|
||||||
from bulk_reminders.oauth import OAuthDialog
|
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')
|
logging.basicConfig(format='[%(asctime)s] [%(levelname)s] [%(threadName)s] %(message)s')
|
||||||
logger = logging.getLogger(__file__)
|
logger = logging.getLogger(__file__)
|
||||||
@@ -60,7 +60,8 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|||||||
self.undoButton.clicked.connect(self.undo)
|
self.undoButton.clicked.connect(self.undo)
|
||||||
self.submitButton.clicked.connect(self.submit)
|
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
|
# Disable the undo button until undo stages are available
|
||||||
if len(self.history) == 0:
|
if len(self.history) == 0:
|
||||||
@@ -86,31 +87,31 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|||||||
|
|
||||||
def undo(self) -> None:
|
def undo(self) -> None:
|
||||||
"""Get the latest undo stage and delete all events in that stage"""
|
"""Get the latest undo stage and delete all events in that stage"""
|
||||||
latest = self.history.pop()
|
logging.info(f'Deleting {len(self.history)} Events from Calendar {self.historyCalendarID}')
|
||||||
logging.info(f'Deleting {len(latest.events)} Events from Calendar {latest.commonCalendar}')
|
|
||||||
|
|
||||||
self.progressBar.show()
|
self.progressBar.show()
|
||||||
self.progressBar.setMaximum(len(latest.events))
|
self.progressBar.setMaximum(len(self.history))
|
||||||
for i, entry in enumerate(latest.events):
|
for i, entry in enumerate(self.history):
|
||||||
logging.debug(f'Deleting Event {entry.eventID}')
|
logging.debug(f'Deleting Event {entry.eventID}')
|
||||||
self.calendar.service.events().delete(calendarId=entry.calendarID, eventId=entry.eventID).execute()
|
self.calendar.service.events().delete(calendarId=entry.calendarID, eventId=entry.eventID).execute()
|
||||||
self.progressBar.setValue(i + 1)
|
self.progressBar.setValue(i + 1)
|
||||||
self.progressBar.hide()
|
self.progressBar.hide()
|
||||||
|
|
||||||
# Disable the undo button until undo stages are available
|
# Disable the undo button until undo stages are available
|
||||||
|
self.history = []
|
||||||
self.undoButton.setDisabled(len(self.history) == 0)
|
self.undoButton.setDisabled(len(self.history) == 0)
|
||||||
self.populate() # Refresh
|
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."""
|
"""Returns all events currently tracked that are not stored in the undo."""
|
||||||
undoableIDs = set(self.history.all_pairs())
|
foreign = {event.get('id'): event for event in self.apiEvents}
|
||||||
for apiEvent in self.apiEvents:
|
undoableIDs = set(pair.eventID for pair in self.history)
|
||||||
pair = IDPair(calendarID=self.currentCalendarID, eventID=apiEvent['id'])
|
return {foreign[eventID] for eventID in undoableIDs.difference(foreign.keys())}
|
||||||
if pair not in undoableIDs:
|
|
||||||
yield pair
|
|
||||||
|
|
||||||
def submit(self) -> None:
|
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')
|
logger.info(f'Submitting {len(self.readyEvents)} events to API')
|
||||||
|
|
||||||
self.progressBar.show()
|
self.progressBar.show()
|
||||||
@@ -118,13 +119,13 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|||||||
for i, event in enumerate(self.readyEvents):
|
for i, event in enumerate(self.readyEvents):
|
||||||
logger.debug(f'Submitting "{event.summary}" scheduled to start on {event.start.isoformat()}....')
|
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()
|
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.progressBar.setValue(i + 1)
|
||||||
|
|
||||||
|
self.undoButton.setDisabled(len(self.history) == 0)
|
||||||
self.readyEvents.clear()
|
self.readyEvents.clear()
|
||||||
self.progressBar.hide()
|
self.progressBar.hide()
|
||||||
|
|
||||||
self.history.addStage(newStage)
|
|
||||||
self.populate()
|
self.populate()
|
||||||
|
|
||||||
def populate(self) -> None:
|
def populate(self) -> None:
|
||||||
@@ -134,9 +135,9 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|||||||
events = list(self.readyEvents)
|
events = list(self.readyEvents)
|
||||||
events.extend([Event.from_api(event, self.history) for event in self.apiEvents])
|
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
|
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))
|
self.eventsView.setRowCount(len(events))
|
||||||
logger.debug(f'Populating table with {self.eventsView.rowCount()} events.')
|
logger.debug(f'Populating table with {self.eventsView.rowCount()} events.')
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
from typing import Iterator, List
|
from typing import Any, Iterator, List
|
||||||
|
|
||||||
import jsonpickle
|
import jsonpickle
|
||||||
|
|
||||||
@@ -68,6 +68,13 @@ class HistoryManager(object):
|
|||||||
self.stages.insert(0, newStage)
|
self.stages.insert(0, newStage)
|
||||||
self.save()
|
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):
|
class Stage(object):
|
||||||
def __init__(self, index: int, commonCalendar: str) -> None:
|
def __init__(self, index: int, commonCalendar: str) -> None:
|
||||||
|
|||||||
Reference in New Issue
Block a user