def create_corpus(corpus_name, content): corpus = Corpus(corpus_name=corpus_name) corpus.save() base_text = create_text(corpus, corpus_name, content) return corpus, base_text
def get_or_create_index(path, schema, src): """Get or create an Index.""" index = open_dir(path) if exists_in(path) else create_in(path, schema) indexed_titles = set(field['title'] for field in gen_indexed_fields(index)) corpus = Corpus(src) documents = set(corpus.gen_documents()) update_index(index.writer(), indexed_titles, documents) return index
def main(): path_to_corpus = sys.argv[1] # ignore any additional parameters if not path_to_corpus: print 'No arguments specified.\nusage: python prep_corpus.py {folder(s) containing Enron corpus}\n' sys.exit(1) c = Corpus() c.build_sqlite_corpus(path_to_corpus)
def _get_json_resp(self, corpus=None, word=None): corpusname = corpus if not corpusname or not word: return {'ok':False, 'mess':'bad query'} corpus = Corpus.load_corpus(corpusname) count, relfreq = corpus.find_word(word) return {'ok':True, 'count':count, 'relfreq':relfreq}
def create_app(): app = Flask(__name__) app.corpus = Corpus(SRC) app.route("/")(index) app.route("/<name>")(article) app.route("/opensearch")(open_search) app.route("/search")(search_view) return app
def corpuses(): data = {k: v for k, v in request.data.items() if k != 'id'} if request.method == "POST": corpus = Corpus(**data) corpus.save() response = jsonify({'id': corpus.id, 'title': corpus.title}) response.status_code = 201 return response else: # GET # TO DO: separate retrievals for corpuses initialized by poet # vs merely participated corpus = Corpus.query.get(request.data['id']) response = jsonify({'id': corpus.id, 'title': corpus.title}) response.status_code = 200 return response
def launchResearch(self): if (self.inputTheme.text != ''): # Remise à zero du message d'erreur self.lblError.setText("") self.progressBar.setValue(10) # Instanciation du Corpus avec le thème tapé par l'utilisateur et la valeur booleenne de la case à cocher self.corpus = Corpus(self.inputTheme.text(), self.chkBoxExcludeStopWords.isChecked()) self.progressBar.setValue(20) # On englobe les appels dans un try/except. Comme ca en cas d'erreur, on affiche les erreurs. try: # Récupération des documents sur reddit self.getDocsFromReddit(self.inputTheme.text(), self.spArticlesMax.value()) self.progressBar.setValue(60) # Récupération des documents sur Arxiv self.getDocsFromArxiv(self.inputTheme.text(), self.spArticlesMax.value()) # Concaténation de tous les documents et nettoyage + Chargement des propriétés wordsByDoc et wordsStrByDoc self.corpus.fill_dicos_words("reddit") self.progressBar.setValue(80) # Concaténation de tous les documents et nettoyage + Chargement des propriétés wordsByDoc et wordsStrByDoc self.corpus.fill_dicos_words("arxiv") self.progressBar.setValue(100) self.progressBar.setValue(0) # Si aucune erreur, on affiche l'écran des actions self.openActions() except Exception as e: # En cas d'erreur : print(e) # J'affiche dans la console l'erreur self.progressBar.setValue( 0) # Je remet la barre de progression à zero # Enfin j'affiche un message d'erreur à l'utilisateur self.lblError.setText( "Erreur dans la récupération des données. Veuillez essayer avec un autre thème" )
def get_out_links(): corpus = Corpus('src') links = {} for doc in corpus.gen_documents(): text = doc.content try: refs = get_references(text) except: continue else: # print(doc.filename, refs) out_links = [] for ref in set(refs): try: canonical_name = get_canonical_name(ref) while not canonical_name.endswith('html'): canonical_name = get_canonical_name(canonical_name) except KeyError: # print('KeyError:', doc.title, ref) pass else: out_links.append(canonical_name) links[doc.filename] = set(out_links) return links
def GET(self): if not web.input().get('word'): err_mess = '<html><head><title>No Input Value</title></head>' err_mess+='<body>You must provide the word to be searched.</body></html>' return err_mess word = web.input().word table = [] for name in Corpus.names: corpus = Corpus.load_corpus(name) count, relfreq = corpus.find_word(word) tup = (corpus.fullname, count, '%1.4f%%' % (relfreq*100)) table.append(tup) if session.get('data'): f = open(STATIC_PATH+session['data']) count, relfreq = search_user_corpus(f, word) tup = ("Your Writing", count, '%1.4f%%' % (relfreq*100)) table.append(tup) return render.comparison(word=word, table=table)
def setupUi(self, MainWindow): # Initilisation d'1 instance de corpus à vide self.corpus = Corpus("", True) MainWindow.setObjectName("MainWindow") MainWindow.resize(619, 379) self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") # On place une frame sur notre fenetre. C'est sur cette frame qu'on va poser les autres composants (bouton...) self.frame = QtWidgets.QFrame(self.centralwidget) self.frame.setGeometry(QtCore.QRect(0, 0, 611, 371)) self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel) self.frame.setFrameShadow(QtWidgets.QFrame.Raised) self.frame.setObjectName("frame") # setStyleSheet = Personnalisation du look self.frame.setStyleSheet("background-color: white;") self.btnOK = QtWidgets.QPushButton(self.frame) self.btnOK.setGeometry(QtCore.QRect(250, 230, 111, 51)) self.btnOK.setObjectName("btnOK") # Au click du bouton OK, on lancher la fonction launchResearch pour demarrer la recherche de docs self.btnOK.clicked.connect(self.launchResearch) # On personnalise la police du bouton btnFont = QtGui.QFont() btnFont.setFamily("Fantasy") btnFont.setPointSize(14) btnFont.setBold(True) btnFont.setWeight(75) self.btnOK.setFont(btnFont) self.btnOK.setStyleSheet("QPushButton{\n" " background-color:#1976d2;\n" " border-radius: 15px;\n" " color:white;\n" " opacity: 0.9;\n" "}") self.lblArticlesMax = QtWidgets.QLabel(self.frame) self.lblArticlesMax.setGeometry(QtCore.QRect(20, 150, 71, 20)) self.lblArticlesMax.setObjectName("lblArticlesMax") # spArticlesMax = Permet de régler le nombre d'articles maximum à récupérer self.spArticlesMax = QtWidgets.QSpinBox(self.frame) self.spArticlesMax.setGeometry(QtCore.QRect(100, 150, 81, 22)) self.spArticlesMax.setObjectName("spArticlesMax") self.spArticlesMax.setMinimum(10) self.spArticlesMax.setMaximum(100000) # inputTheme = C'est le champ où l'utilisateur va taper son thème self.inputTheme = QtWidgets.QLineEdit(self.frame) self.inputTheme.setGeometry(QtCore.QRect(100, 100, 421, 21)) self.inputTheme.setObjectName("inputTheme") self.lblTitre = QtWidgets.QLabel(self.frame) self.lblTitre.setGeometry(QtCore.QRect(50, 20, 491, 51)) self.lblTitre.setAlignment(QtCore.Qt.AlignCenter) self.lblTitre.setObjectName("lblTitre") # On personnalise la police du titre titleFont = QtGui.QFont() titleFont.setFamily("Fantasy") titleFont.setPointSize(10) titleFont.setBold(True) titleFont.setWeight(75) self.lblTitre.setFont(titleFont) # lblTheme : Label "Thème" accompagnant le champ d'édition self.lblTheme = QtWidgets.QLabel(self.frame) self.lblTheme.setGeometry(QtCore.QRect(20, 100, 71, 20)) self.lblTheme.setObjectName("lblTheme") # progressBar : Barre de progression qui évolue apres le click sur le bouton OK self.progressBar = QtWidgets.QProgressBar(self.frame) self.progressBar.setGeometry(QtCore.QRect(35, 310, 541, 23)) self.progressBar.setProperty("value", 0) # par défaut on la rend visible et à 0% self.progressBar.setValue(0) self.progressBar.setVisible(True) self.progressBar.setObjectName("progressBar") self.progressBar.setStyleSheet("QProgressBar{\n" "background-color: #1976d2;\n" "color: white;\n" "border-style: none;\n" "text-align: center;\n" "\n" "}\n" " \n" "QProgressBar::chunk{\n" "background-color: #63a4ff;\n" "\n" "\n" "}\n" "") # On prévoit un label d'erreur qui s'affiche au dessus de la barre de progression en cas de retour d'erreur sur les appels API self.lblError = QtWidgets.QLabel(self.frame) self.lblError.setGeometry(QtCore.QRect(60, 290, 500, 20)) self.lblError.setText("") self.lblError.setObjectName("lblError") # chkBoxExcludeStopWords : Case à cocher pour permettre à l'utilisateur d'enlever les "mots vides" des documents (stopwords) self.chkBoxExcludeStopWords = QtWidgets.QCheckBox(self.frame) self.chkBoxExcludeStopWords.setChecked(True) self.chkBoxExcludeStopWords.setGeometry(QtCore.QRect( 100, 190, 281, 20)) self.chkBoxExcludeStopWords.setObjectName("chkBoxExcludeStopWords") MainWindow.setCentralWidget(self.centralwidget) # Appel à la fonction pour donner du texte à nos composants ("OK" pour le bouton OK...) self.retranslateUi(MainWindow) QtCore.QMetaObject.connectSlotsByName(MainWindow)
class Ui_MainWindow(object): # Fonction de setup de la fenetre def setupUi(self, MainWindow): # Initilisation d'1 instance de corpus à vide self.corpus = Corpus("", True) MainWindow.setObjectName("MainWindow") MainWindow.resize(619, 379) self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") # On place une frame sur notre fenetre. C'est sur cette frame qu'on va poser les autres composants (bouton...) self.frame = QtWidgets.QFrame(self.centralwidget) self.frame.setGeometry(QtCore.QRect(0, 0, 611, 371)) self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel) self.frame.setFrameShadow(QtWidgets.QFrame.Raised) self.frame.setObjectName("frame") # setStyleSheet = Personnalisation du look self.frame.setStyleSheet("background-color: white;") self.btnOK = QtWidgets.QPushButton(self.frame) self.btnOK.setGeometry(QtCore.QRect(250, 230, 111, 51)) self.btnOK.setObjectName("btnOK") # Au click du bouton OK, on lancher la fonction launchResearch pour demarrer la recherche de docs self.btnOK.clicked.connect(self.launchResearch) # On personnalise la police du bouton btnFont = QtGui.QFont() btnFont.setFamily("Fantasy") btnFont.setPointSize(14) btnFont.setBold(True) btnFont.setWeight(75) self.btnOK.setFont(btnFont) self.btnOK.setStyleSheet("QPushButton{\n" " background-color:#1976d2;\n" " border-radius: 15px;\n" " color:white;\n" " opacity: 0.9;\n" "}") self.lblArticlesMax = QtWidgets.QLabel(self.frame) self.lblArticlesMax.setGeometry(QtCore.QRect(20, 150, 71, 20)) self.lblArticlesMax.setObjectName("lblArticlesMax") # spArticlesMax = Permet de régler le nombre d'articles maximum à récupérer self.spArticlesMax = QtWidgets.QSpinBox(self.frame) self.spArticlesMax.setGeometry(QtCore.QRect(100, 150, 81, 22)) self.spArticlesMax.setObjectName("spArticlesMax") self.spArticlesMax.setMinimum(10) self.spArticlesMax.setMaximum(100000) # inputTheme = C'est le champ où l'utilisateur va taper son thème self.inputTheme = QtWidgets.QLineEdit(self.frame) self.inputTheme.setGeometry(QtCore.QRect(100, 100, 421, 21)) self.inputTheme.setObjectName("inputTheme") self.lblTitre = QtWidgets.QLabel(self.frame) self.lblTitre.setGeometry(QtCore.QRect(50, 20, 491, 51)) self.lblTitre.setAlignment(QtCore.Qt.AlignCenter) self.lblTitre.setObjectName("lblTitre") # On personnalise la police du titre titleFont = QtGui.QFont() titleFont.setFamily("Fantasy") titleFont.setPointSize(10) titleFont.setBold(True) titleFont.setWeight(75) self.lblTitre.setFont(titleFont) # lblTheme : Label "Thème" accompagnant le champ d'édition self.lblTheme = QtWidgets.QLabel(self.frame) self.lblTheme.setGeometry(QtCore.QRect(20, 100, 71, 20)) self.lblTheme.setObjectName("lblTheme") # progressBar : Barre de progression qui évolue apres le click sur le bouton OK self.progressBar = QtWidgets.QProgressBar(self.frame) self.progressBar.setGeometry(QtCore.QRect(35, 310, 541, 23)) self.progressBar.setProperty("value", 0) # par défaut on la rend visible et à 0% self.progressBar.setValue(0) self.progressBar.setVisible(True) self.progressBar.setObjectName("progressBar") self.progressBar.setStyleSheet("QProgressBar{\n" "background-color: #1976d2;\n" "color: white;\n" "border-style: none;\n" "text-align: center;\n" "\n" "}\n" " \n" "QProgressBar::chunk{\n" "background-color: #63a4ff;\n" "\n" "\n" "}\n" "") # On prévoit un label d'erreur qui s'affiche au dessus de la barre de progression en cas de retour d'erreur sur les appels API self.lblError = QtWidgets.QLabel(self.frame) self.lblError.setGeometry(QtCore.QRect(60, 290, 500, 20)) self.lblError.setText("") self.lblError.setObjectName("lblError") # chkBoxExcludeStopWords : Case à cocher pour permettre à l'utilisateur d'enlever les "mots vides" des documents (stopwords) self.chkBoxExcludeStopWords = QtWidgets.QCheckBox(self.frame) self.chkBoxExcludeStopWords.setChecked(True) self.chkBoxExcludeStopWords.setGeometry(QtCore.QRect( 100, 190, 281, 20)) self.chkBoxExcludeStopWords.setObjectName("chkBoxExcludeStopWords") MainWindow.setCentralWidget(self.centralwidget) # Appel à la fonction pour donner du texte à nos composants ("OK" pour le bouton OK...) self.retranslateUi(MainWindow) QtCore.QMetaObject.connectSlotsByName(MainWindow) # Fonction générée par PyQt5 UI code generator def retranslateUi(self, MainWindow): _translate = QtCore.QCoreApplication.translate MainWindow.setWindowTitle( _translate("MainWindow", "Projet Python 2021 - Laila DJEBLI / David HUYNH")) self.btnOK.setText(_translate("MainWindow", "OK")) self.lblArticlesMax.setText(_translate("MainWindow", "Articles max")) self.lblTitre.setText( _translate("MainWindow", "PROJET PYTHON LAILA DJEBLI / DAVID HUYNH")) self.lblTheme.setText(_translate("MainWindow", "Thème")) self.chkBoxExcludeStopWords.setText( _translate("MainWindow", "Exclure les stopwords (\"mots vides\")")) # Fonction qui permet d'ouvrir la fenetre d'action def openActions(self): self.window = QtWidgets.QMainWindow() self.uiActionScreen = Ui_ActionScreen( self.corpus ) # Instanciation de la classe Ui_ActionScreen située dans le fichier actionscreen.py self.uiActionScreen.setupUi(self.window) self.window.show() # On affiche cette fenetre # Fonction qui permet d'appeler les API et fait évoluer la barre de progression def launchResearch(self): if (self.inputTheme.text != ''): # Remise à zero du message d'erreur self.lblError.setText("") self.progressBar.setValue(10) # Instanciation du Corpus avec le thème tapé par l'utilisateur et la valeur booleenne de la case à cocher self.corpus = Corpus(self.inputTheme.text(), self.chkBoxExcludeStopWords.isChecked()) self.progressBar.setValue(20) # On englobe les appels dans un try/except. Comme ca en cas d'erreur, on affiche les erreurs. try: # Récupération des documents sur reddit self.getDocsFromReddit(self.inputTheme.text(), self.spArticlesMax.value()) self.progressBar.setValue(60) # Récupération des documents sur Arxiv self.getDocsFromArxiv(self.inputTheme.text(), self.spArticlesMax.value()) # Concaténation de tous les documents et nettoyage + Chargement des propriétés wordsByDoc et wordsStrByDoc self.corpus.fill_dicos_words("reddit") self.progressBar.setValue(80) # Concaténation de tous les documents et nettoyage + Chargement des propriétés wordsByDoc et wordsStrByDoc self.corpus.fill_dicos_words("arxiv") self.progressBar.setValue(100) self.progressBar.setValue(0) # Si aucune erreur, on affiche l'écran des actions self.openActions() except Exception as e: # En cas d'erreur : print(e) # J'affiche dans la console l'erreur self.progressBar.setValue( 0) # Je remet la barre de progression à zero # Enfin j'affiche un message d'erreur à l'utilisateur self.lblError.setText( "Erreur dans la récupération des données. Veuillez essayer avec un autre thème" ) # Appel API Reddit et alimentation du corpus def getDocsFromReddit(self, theme, nbResultatsMax): # Récupération des documents depuis Reddit reddit = praw.Reddit(client_id='0AlqCfHuOc5Hkg', client_secret='80PspjYMdTvF91ti9qZeWzAS2BU', user_agent='Reddit Irambique') hot_posts = reddit.subreddit(theme).hot(limit=nbResultatsMax) # On parcours les post reddit pour créer des docs for post in hot_posts: datet = dt.datetime.fromtimestamp(post.created) txt = post.title + ". " + post.selftext txt = txt.replace('\n', ' ') txt = txt.replace('\r', ' ') # Appel du constructeur RedditDocument (classe enfant de la classe Document) doc = RedditDocument(datet, post.title, txt) # Appel de la fonction add_doc pour ajouter le document tout juste instancié dans l'objet collection (du corpus) self.corpus.add_doc(doc) # Appel API Arxiv et alimentation du corpus def getDocsFromArxiv(self, theme, nbResultatsMax): # Récupération des documents depuis Arxiv url = 'http://export.arxiv.org/api/query?search_query=all:' + theme + '&start=0&max_results=' + str( nbResultatsMax) data = urllib.request.urlopen(url).read().decode() docsFromArxiv = xmltodict.parse(data)['feed']['entry'] # On parcours les post Arxiv pour créer des docs for doc in docsFromArxiv: datet = dt.datetime.strptime(doc['published'], '%Y-%m-%dT%H:%M:%SZ') txt = doc['title'] + ". " + doc['summary'] txt = txt.replace('\n', ' ') txt = txt.replace('\r', ' ') # Appel du constructeur ArxivDocument (classe enfant de la classe Document) doc = ArxivDocument(datet, doc['title'], txt) # Appel de la fonction add_doc pour ajouter le document tout juste instancié dans l'objet collection (du corpus) self.corpus.add_doc(doc)