class TaggerDialog(QDialog): def __init__(self, args, **kwargs): super(TaggerDialog, self).__init__(**kwargs) self.reviewing = False self.args = args self.worker = TaggerWorker() self.thread = QThread() self.worker.moveToThread(self.thread) self.worker.on_error.connect(self.on_error) self.worker.on_review_ready.connect(self.on_review_ready) self.worker.on_stopped.connect(self.on_stopped) self.worker.on_progress.connect(self.on_progress) self.worker.on_updates_sent.connect(self.on_updates_sent) self.worker.on_mint_mfa.connect(self.on_mint_mfa) self.thread.started.connect( partial(self.worker.create_updates, args, self)) self.thread.start() self.init_ui() def init_ui(self): self.setWindowTitle('Tagger is running...') self.setModal(True) self.v_layout = QVBoxLayout() self.setLayout(self.v_layout) self.label = QLabel() self.v_layout.addWidget(self.label) self.progress = 0 self.progress_bar = QProgressBar() self.progress_bar.setRange(0, 0) self.v_layout.addWidget(self.progress_bar) self.button_bar = QHBoxLayout() self.v_layout.addLayout(self.button_bar) self.cancel_button = QPushButton('Cancel') self.button_bar.addWidget(self.cancel_button) self.cancel_button.clicked.connect(self.on_cancel) def on_error(self, msg): logger.error(msg) self.label.setText('Error: {}'.format(msg)) self.label.setStyleSheet('QLabel { color: red; font-weight: bold; }') self.cancel_button.setText('Close') self.cancel_button.clicked.connect(self.close) def open_amazon_order_id(self, order_id): if order_id: QDesktopServices.openUrl(QUrl(amazon.get_invoice_url(order_id))) def on_activated(self, index): # Only handle clicks on the order_id cell. if index.column() != 5: return order_id = self.updates_table_model.data(index, Qt.DisplayRole) self.open_amazon_order_id(order_id) def on_double_click(self, index): if index.column() == 5: # Ignore double clicks on the order_id cell. return order_id_cell = self.updates_table_model.createIndex(index.row(), 5) order_id = self.updates_table_model.data(order_id_cell, Qt.DisplayRole) self.open_amazon_order_id(order_id) def on_review_ready(self, results): self.reviewing = True self.progress_bar.hide() self.label.setText('Select below which updates to send to Mint.') self.updates_table_model = MintUpdatesTableModel(results.updates) self.updates_table = QTableView() self.updates_table.doubleClicked.connect(self.on_double_click) self.updates_table.clicked.connect(self.on_activated) def resize(): self.updates_table.resizeColumnsToContents() self.updates_table.resizeRowsToContents() min_width = sum( self.updates_table.columnWidth(i) for i in range(6)) self.updates_table.setMinimumSize(min_width + 20, 600) self.updates_table.setSelectionMode(QAbstractItemView.SingleSelection) self.updates_table.setSelectionBehavior(QAbstractItemView.SelectRows) self.updates_table.setModel(self.updates_table_model) self.updates_table.setSortingEnabled(True) resize() self.updates_table_model.layoutChanged.connect(resize) self.v_layout.insertWidget(2, self.updates_table) unmatched_button = QPushButton('View Unmatched Amazon orders') self.button_bar.addWidget(unmatched_button) unmatched_button.clicked.connect( partial(self.on_open_unmatched, results.unmatched_orders)) amazon_stats_button = QPushButton('Amazon Stats') self.button_bar.addWidget(amazon_stats_button) amazon_stats_button.clicked.connect( partial(self.on_open_amazon_stats, results.items, results.orders, results.refunds)) tagger_stats_button = QPushButton('Tagger Stats') self.button_bar.addWidget(tagger_stats_button) tagger_stats_button.clicked.connect( partial(self.on_open_tagger_stats, results.stats)) self.confirm_button = QPushButton('Send to Mint') self.button_bar.addWidget(self.confirm_button) self.confirm_button.clicked.connect(self.on_send) self.setGeometry(50, 50, self.width(), self.height()) def on_updates_sent(self, num_sent): self.label.setText( 'All done! {} newly tagged Mint transactions'.format(num_sent)) self.cancel_button.setText('Close') def on_open_unmatched(self, unmatched): self.unmatched_dialog = AmazonUnmatchedTableDialog(unmatched) self.unmatched_dialog.show() def on_open_amazon_stats(self, items, orders, refunds): self.amazon_stats_dialog = AmazonStatsDialog(items, orders, refunds) self.amazon_stats_dialog.show() def on_open_tagger_stats(self, stats): self.tagger_stats_dialog = TaggerStatsDialog(stats) self.tagger_stats_dialog.show() def on_send(self): self.progress_bar.show() updates = self.updates_table_model.get_selected_updates() self.confirm_button.hide() self.updates_table.hide() self.confirm_button.deleteLater() self.updates_table.deleteLater() self.adjustSize() QMetaObject.invokeMethod(self.worker, 'send_updates', Qt.QueuedConnection, Q_ARG(list, updates), Q_ARG(object, self.args)) def on_stopped(self): self.close() def on_progress(self, msg, max, value): self.label.setText(msg) self.progress_bar.setRange(0, max) self.progress_bar.setValue(value) def on_cancel(self): if not self.reviewing: QMetaObject.invokeMethod(self.worker, 'stop', Qt.QueuedConnection) else: self.close() def on_mint_mfa(self): mfa_code, ok = QInputDialog().getText(self, 'Please enter your Mint Code.', 'Mint Code:') QMetaObject.invokeMethod(self.worker, 'mfa_code', Qt.QueuedConnection, Q_ARG(int, mfa_code))