diff --git a/Pipfile b/Pipfile index 3b4bad3..d92729d 100644 --- a/Pipfile +++ b/Pipfile @@ -10,6 +10,8 @@ pyqt5 = "*" google-api-python-client = "*" google-auth-httplib2 = "*" google-auth-oauthlib = "*" +dateutil = "*" +python-dateutil = "*" [requires] python_version = "3.7" diff --git a/bulk_reminders/api.py b/bulk_reminders/api.py index 2d7a83b..6039d86 100644 --- a/bulk_reminders/api.py +++ b/bulk_reminders/api.py @@ -62,6 +62,7 @@ class Calendar(object): # Referencing the primary calendar should be done with the ID 'primary' if entry.get('primary', False): entry['id'] = 'primary' + yield entry # Continue loading more calendars @@ -69,12 +70,12 @@ class Calendar(object): if page_token is None: break - def getEvents(self, calendarID: str) -> None: + def getEvents(self, calendarID: str) -> List[Any]: now = datetime.datetime.utcnow().isoformat() + 'Z' # 'Z' indicates UTC time - events_result = self.service.events().list(calendarId=calendarID, timeMin=now, - maxResults=10, singleEvents=True, - orderBy='startTime').execute() - events = events_result.get('items', []) + events = self.service.events().list(calendarId=calendarID, timeMin=now, + maxResults=2500, singleEvents=True, + orderBy='startTime').execute() + return events.get('items', []) def getCalendarsSimplified(self) -> List[Tuple[str, str]]: """Extracts the bare minimum required information from the Calendar.""" diff --git a/bulk_reminders/gui.py b/bulk_reminders/gui.py index a9caaaa..09b491d 100644 --- a/bulk_reminders/gui.py +++ b/bulk_reminders/gui.py @@ -1,7 +1,9 @@ -from PyQt5 import QtCore, QtGui -from PyQt5.QtWidgets import QDialog, QMainWindow +import dateutil +from PyQt5 import QtCore, QtGui, QtWidgets +from PyQt5.QtWidgets import QDialog, QMainWindow, QTableWidgetItem +from dateutil.parser import isoparse -from bulk_reminders import api +from bulk_reminders import api, undo from bulk_reminders.gui_base import Ui_MainWindow from bulk_reminders.oauth import OAuthDialog @@ -13,17 +15,18 @@ class MainWindow(QMainWindow, Ui_MainWindow): self.setupUi(self) self.show() - calendar = api.Calendar() + self.calendar = api.Calendar() + self.currentCalendarID = 'primary' # Authenticate user into Google API Engine - self.authenticated = calendar.authenticate_via_token() + self.authenticated = self.calendar.authenticate_via_token() if not self.authenticated: - temp_dialog = OAuthDialog(callback=calendar.authenticate_via_oauth) + temp_dialog = OAuthDialog(callback=self.calendar.authenticate_via_oauth) temp_dialog.show() - calendar.setupService() + self.calendar.setupService() # Get Calendars, Setup Calendar Selection Combobox - calendars = calendar.getCalendarsSimplified() + calendars = self.calendar.getCalendarsSimplified() self.comboModel = QtGui.QStandardItemModel() for id, summary in calendars: item = QtGui.QStandardItem(summary) @@ -32,7 +35,55 @@ class MainWindow(QMainWindow, Ui_MainWindow): self.calendarCombobox.setModel(self.comboModel) self.calendarCombobox.currentIndexChanged[int].connect(self.comboBoxChanged) + # Setup Column View headers + self.eventsView.setColumnCount(4) + self.eventsView.setHorizontalHeaderLabels(['Summary', 'Status', 'Start', 'End']) + header = self.eventsView.horizontalHeader() + header.setSectionResizeMode(0, QtWidgets.QHeaderView.Stretch) + header.setSectionResizeMode(1, QtWidgets.QHeaderView.ResizeToContents) + header.setSectionResizeMode(2, QtWidgets.QHeaderView.ResizeToContents) + header.setSectionResizeMode(3, QtWidgets.QHeaderView.ResizeToContents) + self.eventsView.verticalHeader().hide() + + self.undoButton.clicked().connect(self.undoEvents) + self.submitButton.clicked().connect(self.submitEvents) + + # Disable the undo button until undo stages are available + if len(undo.stages) == 0: + self.undoButton.setDisabled(True) + + self.populate() + + def undo(self) -> None: + latest = undo.stages.pop(0) + for entry in latest: + + # Disable the undo button until undo stages are available + if len(undo.stages) == 0: + self.undoButton.setDisabled(True) + + def populate(self) -> None: + """Re-populate the table with all of the events""" + self.events = self.calendar.getEvents(self.currentCalendarID) + self.eventsView.setRowCount(len(self.events)) + for row, event in enumerate(self.events): + print(event) + summaryItem = QTableWidgetItem(event['summary']) + summaryItem.setData(QtCore.Qt.UserRole) + summaryItem.setForeground(QtGui.QColor("blue")) + self.eventsView.setItem(row, 0, summaryItem) + start, end = event['start'], event['end'] + start, end = start.get('date') or start.get('dateTime'), end.get('date') or end.get('dateTime') + start, end = isoparse(start), isoparse(end) + + formatString = '%b %d, %Y'if event['start'].get('date') is not None else '%b %d, %Y %I:%M %Z' + self.eventsView.setItem(row, 1, QTableWidgetItem('Foreign')) + self.eventsView.setItem(row, 2, QTableWidgetItem(start.strftime(formatString))) + self.eventsView.setItem(row, 3, QTableWidgetItem(end.strftime(formatString))) + + @QtCore.pyqtSlot(int) def comboBoxChanged(self, row) -> None: """When the Calendar Selection combobox""" - self.currentCalendar = self.comboModel.item(row).data() + self.currentCalendarID = self.comboModel.item(row).data() + self.populate() diff --git a/bulk_reminders/gui_base.py b/bulk_reminders/gui_base.py index e67b454..f920a36 100644 --- a/bulk_reminders/gui_base.py +++ b/bulk_reminders/gui_base.py @@ -24,6 +24,11 @@ class Ui_MainWindow(object): self.centralwidget.setObjectName("centralwidget") self.gridLayout = QtWidgets.QGridLayout(self.centralwidget) self.gridLayout.setObjectName("gridLayout") + self.eventsView = QtWidgets.QTableWidget(self.centralwidget) + self.eventsView.setObjectName("eventsView") + self.eventsView.setColumnCount(0) + self.eventsView.setRowCount(0) + self.gridLayout.addWidget(self.eventsView, 1, 0, 1, 1) self.verticalLayout = QtWidgets.QVBoxLayout() self.verticalLayout.setObjectName("verticalLayout") self.horizontalLayout_2 = QtWidgets.QHBoxLayout() @@ -53,9 +58,6 @@ class Ui_MainWindow(object): self.undoButton.setObjectName("undoButton") self.horizontalLayout.addWidget(self.undoButton) self.verticalLayout.addLayout(self.horizontalLayout) - self.eventsView = QtWidgets.QColumnView(self.centralwidget) - self.eventsView.setObjectName("eventsView") - self.verticalLayout.addWidget(self.eventsView) self.gridLayout.addLayout(self.verticalLayout, 0, 0, 1, 1) MainWindow.setCentralWidget(self.centralwidget) self.menubar = QtWidgets.QMenuBar(MainWindow)