From 1a6dea45137e6d97eb420f8e7b7cacc2d9bab4b8 Mon Sep 17 00:00:00 2001 From: Xevion Date: Fri, 3 Sep 2021 17:33:14 -0500 Subject: [PATCH] Improve data + time parsing functionality Now allows one to enter just one date or one date and time together. --- bulk_reminders/api.py | 16 +++++++++++++--- bulk_reminders/gui.py | 1 + bulk_reminders/load.py | 12 +++++++----- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/bulk_reminders/api.py b/bulk_reminders/api.py index 33d8007..b2839b7 100644 --- a/bulk_reminders/api.py +++ b/bulk_reminders/api.py @@ -21,7 +21,7 @@ from bulk_reminders import undo SCOPES = ['https://www.googleapis.com/auth/calendar'] TIME_REGEX = re.compile(r'\d{2}:\d{2}(?:AM|PM)') DATE_FORMAT = '%Y-%m-%d' -DATETIME_FORMAT = DATE_FORMAT + ' %H:%M%p' +DATETIME_FORMAT = DATE_FORMAT + '%H:%M%p' logger = logging.getLogger(__file__) logger.setLevel(logging.DEBUG) @@ -171,9 +171,19 @@ class Event(object): @classmethod 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, second_time = input[2] is not None, input[4] is not None + first_time = input[2] is not None start = datetime.datetime.strptime(input[1] + (input[2] if first_time else ''), DATETIME_FORMAT if first_time else DATE_FORMAT) - end = datetime.datetime.strptime(input[3] + (input[4] if second_time else ''), DATETIME_FORMAT if second_time else DATE_FORMAT) + if input[3] is not None: + second_time = input[4] is not None + end = datetime.datetime.strptime(input[3] + (input[4] if second_time else ''), DATETIME_FORMAT if second_time else DATE_FORMAT) + else: + if first_time: + # But if a start time (hour & minute) was specified, make it end at the same time + end = start + else: + # If no second date is specified and no first time is either, it simply ends the next day and lasts 24 hours + end = start + datetime.timedelta(hours=24) + return Event( summary=input[0], start=start, diff --git a/bulk_reminders/gui.py b/bulk_reminders/gui.py index c75318a..dcdca20 100644 --- a/bulk_reminders/gui.py +++ b/bulk_reminders/gui.py @@ -141,6 +141,7 @@ class MainWindow(QMainWindow, Ui_MainWindow): self.eventsView.setRowCount(len(events)) logger.debug(f'Populating table with {self.eventsView.rowCount()} events.') for row, event in enumerate(events): + logger.debug(f'Event "{event.summary}" starts {event.start} and ends {event.end}') event.fill_row(row, self.eventsView) self.submitButton.setDisabled(len(self.readyEvents) < 0) diff --git a/bulk_reminders/load.py b/bulk_reminders/load.py index 6f19dd2..88d4657 100644 --- a/bulk_reminders/load.py +++ b/bulk_reminders/load.py @@ -13,8 +13,8 @@ from bulk_reminders.load_base import Ui_Dialog logger = logging.getLogger(__file__) logger.setLevel(logging.DEBUG) -REGEX = re.compile( - r'\s*([\w\d\s,-.;\'!\[\]()]{1,})\s+\|\s+(\d{4}-\d{2}-\d{2})\s+(\d{1,2}:\d{2}(?:AM|PM))?\s*(\d{4}-\d{2}-\d{2})(\d{1,2}:\d{2}(?:AM|PM))?') +REGEX_FULL_PARSE = re.compile( + r'\s*([\w\d\s,-.;\'!\[\]()]{1,})\s+\|\s+(\d{4}-\d{2}-\d{2})\s*(\d{1,2}:\d{2}(?:AM|PM))?\s*(\d{4}-\d{2}-\d{2})?\s*(\d{1,2}:\d{2}(?:AM|PM))?') class LoadDialog(QDialog, Ui_Dialog): @@ -45,12 +45,14 @@ class LoadDialog(QDialog, Ui_Dialog): 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())] + results = [result.groups() for result in re.finditer(REGEX_FULL_PARSE, self.plainTextEdit.toPlainText())] resultsText = f'{len(results)} group{"s" if len(results) != 1 else ""} found.' try: self.parsed = list(map(Event.parse_raw, results)) - except ValueError: - logger.debug('Dialog input has data errors (invalid dates etc.)') + for event in self.parsed: + logger.debug(f'Parsed: Event "{event.summary}" starts {event.start} and ends {event.end}') + except ValueError as error: + logger.warning('Dialog input has data errors (invalid dates etc.)', exc_info=error) resultsText += ' Data error.' self.eventCountLabel.setText(resultsText)