Skip to content

Commit

Permalink
Update widget to save email safely like NYtimes widget
Browse files Browse the repository at this point in the history
  • Loading branch information
PrimozGodec committed Aug 26, 2019
1 parent 4f4ea1b commit 9dc3d07
Showing 1 changed file with 91 additions and 60 deletions.
151 changes: 91 additions & 60 deletions orangecontrib/text/widgets/owpubmed.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import os
import re
from datetime import date

from AnyQt.QtCore import QDate, Qt
from AnyQt.QtWidgets import (QApplication, QComboBox, QDateEdit, QTextEdit,
QFrame, QDialog, QCalendarWidget, QVBoxLayout)
from validate_email import validate_email
QFrame, QDialog, QCalendarWidget, QVBoxLayout,
QFormLayout)

from Orange.widgets import gui
from Orange.widgets.credentials import CredentialManager
from Orange.widgets.settings import Setting
from Orange.widgets.widget import OWWidget, Msg
from orangecontrib.text.corpus import Corpus
Expand All @@ -20,11 +22,71 @@ def _i(name, icon_path='icons'):
return os.path.join(widget_path, icon_path, name)


EMAIL_REGEX = re.compile(r"[^@]+@[^@]+\.[^@]+")


def validate_email(email):
return EMAIL_REGEX.match(email)


class Output:
CORPUS = 'Corpus'


class OWPubmed(OWWidget):
class EmailCredentialsDialog(OWWidget):
name = "Pubmed Email"
want_main_area = False
resizing_enabled = False
email_manager = CredentialManager('Email')
email_input = ''

class Error(OWWidget.Error):
invalid_credentials = Msg('This email is invalid.')

def __init__(self, parent):
super().__init__()
self.parent = parent
self.api = None

form = QFormLayout()
form.setContentsMargins(5, 5, 5, 5)
self.email_edit = gui.lineEdit(
self, self, 'email_input', controlWidth=400)
form.addRow('Email:', self.email_edit)
self.controlArea.layout().addLayout(form)
self.submit_button = gui.button(
self.controlArea, self, "OK", self.accept)

self.load_credentials()

def setVisible(self, visible):
super().setVisible(visible)
self.email_edit.setFocus()

def load_credentials(self):
self.email_edit.setText(self.email_manager.key)

def save_credentials(self):
self.email_manager.key = self.email_input

def check_credentials(self):
if validate_email(self.email_input):
self.save_credentials()
return True
else:
return False

def accept(self, silent=False):
if not silent:
self.Error.invalid_credentials.clear()
valid = self.check_credentials()
if valid:
self.parent.sync_email(self.email_input)
super().accept()
else:
self.Error.invalid_credentials()

name = 'Pubmed'
description = 'Fetch data from Pubmed.'
icon = 'icons/Pubmed.svg'
Expand All @@ -39,7 +101,6 @@ class OWPubmed(OWWidget):
MIN_DATE = date(1800, 1, 1)

# Settings.
recent_emails = Setting([])
author = Setting('')
pub_date_from = Setting('')
pub_date_to = Setting('')
Expand All @@ -54,36 +115,34 @@ class OWPubmed(OWWidget):
includes_abstract = Setting(True)
includes_url = Setting(True)

email = None

class Warning(OWWidget.Warning):
no_query = Msg('Please specify the keywords for this query.')

class Error(OWWidget.Error):
api_error = Msg('API error: {}.')
email_error = Msg('Email not set. Pleas set it with the email button.')

def __init__(self):
super().__init__()

self.output_corpus = None
self.pubmed_api = None
self.progress = None
self.email_is_valid = False
self.record_count = 0
self.download_running = False

# API key
self.email_dlg = self.EmailCredentialsDialog(self)
gui.button(self.controlArea, self, 'Email',
callback=self.email_dlg.exec_,
focusPolicy=Qt.NoFocus)
gui.separator(self.controlArea)

# To hold all the controls. Makes access easier.
self.pubmed_controls = []

h_box = gui.hBox(self.controlArea)
label = gui.label(h_box, self, 'Email:')
label.setMaximumSize(label.sizeHint())
# Drop-down for recent emails.
self.email_combo = QComboBox(h_box)
self.email_combo.setMinimumWidth(150)
self.email_combo.setEditable(True)
self.email_combo.lineEdit().textChanged.connect(self.sync_email)
h_box.layout().addWidget(self.email_combo)
self.email_combo.activated[int].connect(self.select_email)

# RECORD SEARCH
self.search_tabs = gui.tabWidget(self.controlArea)
# --- Regular search ---
Expand Down Expand Up @@ -228,48 +287,29 @@ def __init__(self):
self,
'Number of records retrieved: /')

# Load the most recent emails.
self.set_email_list()

# Load the most recent queries.
self.set_keyword_list()

# Check the email and enable controls accordingly.
if self.recent_emails:
email = self.recent_emails[0]
self.email_is_valid = validate_email(email)

self.enable_controls()

def sync_email(self):
email = self.email_combo.currentText()
self.email_is_valid = validate_email(email)
self.enable_controls()

def enable_controls(self):
# Enable/disable controls accordingly.
for control in self.pubmed_controls:
control.setEnabled(self.email_is_valid)
if self.pubmed_api is None or self.pubmed_api.search_record_count == 0:
self.retrieve_records_button.setEnabled(False)
if not self.email_is_valid:
self.email_combo.setFocus()
def sync_email(self, email):
self.Error.email_error.clear()
self.email = email

def run_search(self):
self.Error.clear()
self.Warning.clear()

# check if email exists
if self.email is None:
self.Error.email_error()
return

self.run_search_button.setEnabled(False)
self.retrieve_records_button.setEnabled(False)

# Add the email to history.
email = self.email_combo.currentText()
if email not in self.recent_emails:
self.recent_emails.insert(0, email)

# Check if the PubMed object is present.
if self.pubmed_api is None:
self.pubmed_api = Pubmed(
email=email,
email=self.email,
progress_callback=self.api_progress_callback,
error_callback=self.api_error_callback,
)
Expand Down Expand Up @@ -309,6 +349,13 @@ def run_search(self):
self.enable_controls()
self.update_search_info()

def enable_controls(self):
# Enable/disable controls accordingly.
self.run_search_button.setEnabled(True)
enabled = self.pubmed_api is not None and \
not self.pubmed_api.search_record_count == 0
self.retrieve_records_button.setEnabled(enabled)

def retrieve_records(self):
self.Warning.clear()
self.Error.clear()
Expand All @@ -318,13 +365,11 @@ def retrieve_records(self):

if self.download_running:
self.download_running = False
self.run_search_button.setEnabled(True)
self.retrieve_records_button.setText('Retrieve records')
self.pubmed_api.stop_retrieving()
return

self.download_running = True
self.run_search_button.setEnabled(False)
self.output_corpus = None # Clear the old records.

# Change the button label.
Expand Down Expand Up @@ -401,20 +446,6 @@ def update_retrieval_info(self):
self.retrieval_info_label.sizeHint()
)

def select_email(self, n):
if n < len(self.recent_emails):
email = self.recent_emails[n]
del self.recent_emails[n]
self.recent_emails.insert(0, email)

if len(self.recent_emails) > 0:
self.set_email_list()

def set_email_list(self):
self.email_combo.clear()
for email in self.recent_emails:
self.email_combo.addItem(email)

def select_keywords(self, n):
if n < len(self.recent_keywords):
keywords = self.recent_keywords[n]
Expand Down

0 comments on commit 9dc3d07

Please sign in to comment.