diff --git a/bulk_reminders/api.py b/bulk_reminders/api.py index 73da8ff..6157ee0 100644 --- a/bulk_reminders/api.py +++ b/bulk_reminders/api.py @@ -140,7 +140,7 @@ class Event(object): table.setItem(row, 3, QTableWidgetItem(self.end.strftime(formatString))) @classmethod - def parse_raw(self, input: Tuple[str]) -> 'Event': + def parse_raw(cls, input: Tuple[str]) -> 'Event': """Takes in input that has been separated by a RegEx expression into groups and creates a Event object""" first_time = re.match(TIME_REGEX, input[2]) is not None second_time = re.match(TIME_REGEX, input[3 + (1 if first_time else 0)]) diff --git a/bulk_reminders/gui.py b/bulk_reminders/gui.py index d4af1bb..205c770 100644 --- a/bulk_reminders/gui.py +++ b/bulk_reminders/gui.py @@ -1,11 +1,13 @@ -import dateutil +import itertools +from typing import Iterator, List + from PyQt5 import QtCore, QtGui, QtWidgets -from PyQt5.QtWidgets import QDialog, QMainWindow, QTableWidgetItem -from dateutil.parser import isoparse +from PyQt5.QtWidgets import QMainWindow, QMessageBox from bulk_reminders import api, undo 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 @@ -36,6 +38,9 @@ class MainWindow(QMainWindow, Ui_MainWindow): self.calendarCombobox.setModel(self.comboModel) self.calendarCombobox.currentIndexChanged[int].connect(self.comboBoxChanged) + # Make sure the current calendar ID matches up + self.currentCalendarID = self.comboModel.item(self.calendarCombobox.currentIndex()).data() + # Setup Column View headers self.eventsView.setColumnCount(4) self.eventsView.setHorizontalHeaderLabels(['Summary', 'Status', 'Start', 'End']) @@ -53,8 +58,24 @@ class MainWindow(QMainWindow, Ui_MainWindow): if len(undo.stages) == 0: self.undoButton.setDisabled(True) + self.loadEventsButton.clicked.connect(self.load_events) + self.cachedLoadText = '' + self.readyEvents = [] + self.populate() + def load_events(self) -> None: + """Open the event loading dialog""" + dial = LoadDialog() + dial.plainTextEdit.setPlainText(self.cachedLoadText) + result = dial.exec() + if result == QMessageBox.Accepted: + self.cachedLoadText = dial.plainTextEdit.toPlainText() + self.readyEvents = dial.parsed + self.populate() + elif result == QMessageBox.Cancel: + pass + def undo(self) -> None: # Get the latest undo stage and delete all events in that stage latest = undo.stages.pop(0) @@ -65,13 +86,23 @@ class MainWindow(QMainWindow, Ui_MainWindow): if len(undo.stages) == 0: self.undoButton.setDisabled(True) + def getForeign(self) -> List[Event]: + """Returns all events currently tracked that are not stored in the undo.""" + events = {event['id'] : event for event in self.apiEvents} + undoableIDs = itertools.chain.from_iterable([[undoable['id'] for undoable in stage] for stage in undo.stages]) + foreignIDs = events.keys() - undoableIDs + return [events[foreignID] for foreignID in foreignIDs] + def submit(self) -> None: pass - def populate(self) -> None: """Re-populate the table with all of the events""" - self.events = [Event.from_api(event) for event in self.calendar.getEvents(self.currentCalendarID)] + self.apiEvents = self.calendar.getEvents(self.currentCalendarID) + self.events = [Event.from_api(event) for event in self.apiEvents] + ready, undoable, stage, foreign = len(self.readyEvents), undo.getTotal(), len(undo.stages), len(self.getForeign()) + total = ready + undoable + stage + foreign + self.eventCountLabel.setText(f'{len(self.readyEvents)} ready, {undoable} undoable in {stage} stages, {foreign} foreign ({total})') self.eventsView.setRowCount(len(self.events)) for row, event in enumerate(self.events): event.fill_row(row, self.eventsView) diff --git a/bulk_reminders/gui_base.py b/bulk_reminders/gui_base.py index f920a36..6ba4199 100644 --- a/bulk_reminders/gui_base.py +++ b/bulk_reminders/gui_base.py @@ -52,6 +52,14 @@ class Ui_MainWindow(object): self.calendarCombobox.setMinimumSize(QtCore.QSize(140, 0)) self.calendarCombobox.setObjectName("calendarCombobox") self.horizontalLayout.addWidget(self.calendarCombobox) + self.eventCountLabel = QtWidgets.QLabel(self.centralwidget) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.eventCountLabel.sizePolicy().hasHeightForWidth()) + self.eventCountLabel.setSizePolicy(sizePolicy) + self.eventCountLabel.setObjectName("eventCountLabel") + self.horizontalLayout.addWidget(self.eventCountLabel) spacerItem = QtWidgets.QSpacerItem(30, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) self.horizontalLayout.addItem(spacerItem) self.undoButton = QtWidgets.QPushButton(self.centralwidget) @@ -73,7 +81,8 @@ class Ui_MainWindow(object): def retranslateUi(self, MainWindow): _translate = QtCore.QCoreApplication.translate - MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow")) + MainWindow.setWindowTitle(_translate("MainWindow", "Bulk Reminders")) self.loadEventsButton.setText(_translate("MainWindow", "Load events")) self.submitButton.setText(_translate("MainWindow", "Submit")) + self.eventCountLabel.setText(_translate("MainWindow", "34 ready, 26 undoable in 3 stages, 18 prexisting (94)")) self.undoButton.setText(_translate("MainWindow", "Undo")) diff --git a/bulk_reminders/load.py b/bulk_reminders/load.py index 80960d6..8c07c06 100644 --- a/bulk_reminders/load.py +++ b/bulk_reminders/load.py @@ -1,6 +1,6 @@ import os import re -from typing import List +from typing import List, Optional from PyQt5.QtCore import QSize, QTimer from PyQt5.QtGui import QMovie @@ -33,16 +33,16 @@ class LoadDialog(QDialog, Ui_Dialog): self.parseTimer.timeout.connect(self.parse) self.parseTimer.setSingleShot(True) - self.show() - self.parse() - self.parsed: List[Event] = [] + self.eventCountLabel.setText('0 groups found.') + + self.show() def parse(self) -> None: """Parse the events entered into the dialog""" self.spinner.hide() results = [result.groups() for result in re.finditer(REGEX, self.plainTextEdit.toPlainText())] - self.eventCountLabel.setText(f'{len(results)} group{"s" if len(results) != 0 else ""} found.') + self.eventCountLabel.setText(f'{len(results)} group{"s" if len(results) != 1 else ""} found.') self.parsed = list(map(Event.parse_raw, results)) def edited(self) -> None: diff --git a/bulk_reminders/undo.py b/bulk_reminders/undo.py index 16242c0..72ff0d8 100644 --- a/bulk_reminders/undo.py +++ b/bulk_reminders/undo.py @@ -18,3 +18,8 @@ def save() -> None: if os.path.exists('history.json'): load() + + +def getTotal() -> int: + """Returns the total number of undoable events known.""" + return sum(len(stage) for stage in stages)