mirror of
https://github.com/Xevion/bulk-reminders.git
synced 2025-12-10 16:06:41 -06:00
Prepare loading of events from load dialog into main window
Add nicer label for counting events by type
This commit is contained in:
@@ -140,7 +140,7 @@ class Event(object):
|
|||||||
table.setItem(row, 3, QTableWidgetItem(self.end.strftime(formatString)))
|
table.setItem(row, 3, QTableWidgetItem(self.end.strftime(formatString)))
|
||||||
|
|
||||||
@classmethod
|
@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"""
|
"""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
|
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)])
|
second_time = re.match(TIME_REGEX, input[3 + (1 if first_time else 0)])
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
import dateutil
|
import itertools
|
||||||
|
from typing import Iterator, List
|
||||||
|
|
||||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||||
from PyQt5.QtWidgets import QDialog, QMainWindow, QTableWidgetItem
|
from PyQt5.QtWidgets import QMainWindow, QMessageBox
|
||||||
from dateutil.parser import isoparse
|
|
||||||
|
|
||||||
from bulk_reminders import api, undo
|
from bulk_reminders import api, undo
|
||||||
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.oauth import OAuthDialog
|
from bulk_reminders.oauth import OAuthDialog
|
||||||
|
|
||||||
|
|
||||||
@@ -36,6 +38,9 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|||||||
self.calendarCombobox.setModel(self.comboModel)
|
self.calendarCombobox.setModel(self.comboModel)
|
||||||
self.calendarCombobox.currentIndexChanged[int].connect(self.comboBoxChanged)
|
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
|
# Setup Column View headers
|
||||||
self.eventsView.setColumnCount(4)
|
self.eventsView.setColumnCount(4)
|
||||||
self.eventsView.setHorizontalHeaderLabels(['Summary', 'Status', 'Start', 'End'])
|
self.eventsView.setHorizontalHeaderLabels(['Summary', 'Status', 'Start', 'End'])
|
||||||
@@ -53,8 +58,24 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|||||||
if len(undo.stages) == 0:
|
if len(undo.stages) == 0:
|
||||||
self.undoButton.setDisabled(True)
|
self.undoButton.setDisabled(True)
|
||||||
|
|
||||||
|
self.loadEventsButton.clicked.connect(self.load_events)
|
||||||
|
self.cachedLoadText = ''
|
||||||
|
self.readyEvents = []
|
||||||
|
|
||||||
self.populate()
|
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:
|
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 = undo.stages.pop(0)
|
latest = undo.stages.pop(0)
|
||||||
@@ -65,13 +86,23 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|||||||
if len(undo.stages) == 0:
|
if len(undo.stages) == 0:
|
||||||
self.undoButton.setDisabled(True)
|
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:
|
def submit(self) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def populate(self) -> None:
|
def populate(self) -> None:
|
||||||
"""Re-populate the table with all of the events"""
|
"""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))
|
self.eventsView.setRowCount(len(self.events))
|
||||||
for row, event in enumerate(self.events):
|
for row, event in enumerate(self.events):
|
||||||
event.fill_row(row, self.eventsView)
|
event.fill_row(row, self.eventsView)
|
||||||
|
|||||||
@@ -52,6 +52,14 @@ class Ui_MainWindow(object):
|
|||||||
self.calendarCombobox.setMinimumSize(QtCore.QSize(140, 0))
|
self.calendarCombobox.setMinimumSize(QtCore.QSize(140, 0))
|
||||||
self.calendarCombobox.setObjectName("calendarCombobox")
|
self.calendarCombobox.setObjectName("calendarCombobox")
|
||||||
self.horizontalLayout.addWidget(self.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)
|
spacerItem = QtWidgets.QSpacerItem(30, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
|
||||||
self.horizontalLayout.addItem(spacerItem)
|
self.horizontalLayout.addItem(spacerItem)
|
||||||
self.undoButton = QtWidgets.QPushButton(self.centralwidget)
|
self.undoButton = QtWidgets.QPushButton(self.centralwidget)
|
||||||
@@ -73,7 +81,8 @@ class Ui_MainWindow(object):
|
|||||||
|
|
||||||
def retranslateUi(self, MainWindow):
|
def retranslateUi(self, MainWindow):
|
||||||
_translate = QtCore.QCoreApplication.translate
|
_translate = QtCore.QCoreApplication.translate
|
||||||
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
|
MainWindow.setWindowTitle(_translate("MainWindow", "Bulk Reminders"))
|
||||||
self.loadEventsButton.setText(_translate("MainWindow", "Load events"))
|
self.loadEventsButton.setText(_translate("MainWindow", "Load events"))
|
||||||
self.submitButton.setText(_translate("MainWindow", "Submit"))
|
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"))
|
self.undoButton.setText(_translate("MainWindow", "Undo"))
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
from typing import List
|
from typing import List, Optional
|
||||||
|
|
||||||
from PyQt5.QtCore import QSize, QTimer
|
from PyQt5.QtCore import QSize, QTimer
|
||||||
from PyQt5.QtGui import QMovie
|
from PyQt5.QtGui import QMovie
|
||||||
@@ -33,16 +33,16 @@ class LoadDialog(QDialog, Ui_Dialog):
|
|||||||
self.parseTimer.timeout.connect(self.parse)
|
self.parseTimer.timeout.connect(self.parse)
|
||||||
self.parseTimer.setSingleShot(True)
|
self.parseTimer.setSingleShot(True)
|
||||||
|
|
||||||
self.show()
|
|
||||||
self.parse()
|
|
||||||
|
|
||||||
self.parsed: List[Event] = []
|
self.parsed: List[Event] = []
|
||||||
|
self.eventCountLabel.setText('0 groups found.')
|
||||||
|
|
||||||
|
self.show()
|
||||||
|
|
||||||
def parse(self) -> None:
|
def parse(self) -> None:
|
||||||
"""Parse the events entered into the dialog"""
|
"""Parse the events entered into the dialog"""
|
||||||
self.spinner.hide()
|
self.spinner.hide()
|
||||||
results = [result.groups() for result in re.finditer(REGEX, self.plainTextEdit.toPlainText())]
|
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))
|
self.parsed = list(map(Event.parse_raw, results))
|
||||||
|
|
||||||
def edited(self) -> None:
|
def edited(self) -> None:
|
||||||
|
|||||||
@@ -18,3 +18,8 @@ def save() -> None:
|
|||||||
|
|
||||||
if os.path.exists('history.json'):
|
if os.path.exists('history.json'):
|
||||||
load()
|
load()
|
||||||
|
|
||||||
|
|
||||||
|
def getTotal() -> int:
|
||||||
|
"""Returns the total number of undoable events known."""
|
||||||
|
return sum(len(stage) for stage in stages)
|
||||||
|
|||||||
Reference in New Issue
Block a user