Files
bulk-reminders/bulk_reminders/load.py
Xevion 1a6dea4513 Improve data + time parsing functionality
Now allows one to enter just one date or one date and time together.
2021-09-03 17:33:14 -05:00

64 lines
2.3 KiB
Python

import logging
import os
import re
from typing import List, Optional
from PyQt5.QtCore import QSize, QTimer
from PyQt5.QtGui import QMovie
from PyQt5.QtWidgets import QApplication, QDialog, QLabel
from bulk_reminders.api import Event
from bulk_reminders.load_base import Ui_Dialog
logger = logging.getLogger(__file__)
logger.setLevel(logging.DEBUG)
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):
def __init__(self, *args, **kwargs):
super(QDialog, self).__init__(*args, **kwargs)
self.setupUi(self)
self.spinner = QLabel()
path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'loading.gif')
self.movie = QMovie(path)
self.movie.setScaledSize(QSize(26, 26))
self.spinner.setMovie(self.movie)
self.movie.start()
self.spinner.hide()
self.spinner.setFixedSize(23, 23)
self.horizontalLayout.addWidget(self.spinner)
self.plainTextEdit.textChanged.connect(self.edited)
self.parseTimer = QTimer()
self.parseTimer.timeout.connect(self.parse)
self.parseTimer.setSingleShot(True)
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_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))
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)
def edited(self) -> None:
"""Prepare a timer to be fired to parse the edited text"""
self.parseTimer.stop()
self.spinner.show()
self.parseTimer.start(500) # 0.5 seconds