Initial commit
[kcnrtl.git] / kcnrtl / kcnrtl.py
1 #!/usr/bin/python
2 #-*- coding: utf-8 -*-
3 #
4 # KCnrtl is a simple and messy KDE graphical client to access
5 # the CNRTL linguistic resources
6 #
7 # Copyright (C) 2012 Bogdan Cordier
8 #
9 # This program is free software: you can redistribute it and/or modify
10 # it under the terms of the GNU General Public License as published by
11 # the Free Software Foundation, either version 3 of the License, or
12 # (at your option) any later version.
13 #
14 # This program is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 # GNU General Public License for more details.
18 #
19 # You should have received a copy of the GNU General Public License
20 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
21
22
23 import sys
24 import httplib2
25 from bs4 import BeautifulSoup
26 from PyQt4.QtCore import *
27 from PyQt4.QtGui import *
28 from gui.Ui_kcnrtl import Ui_MainWindow
29 import re
30 import shutil
31
32
33 def main():
34     app = QApplication(sys.argv)
35     myapp = Main()
36     myapp.show()
37     sys.exit(app.exec_())
38
39
40 class Main(QMainWindow):
41     def __init__(self, parent=None):
42         super(QWidget, self).__init__(parent)
43         #QWidget.__init__(self, parent)
44
45         self.ui = Ui_MainWindow()
46
47         self.ui.setupUi(self)
48
49         self.ui.lineEdit.selectAll()
50
51         self.ui.lineEdit.setFocus()
52
53         self.ui.comboBox.setCurrentIndex(0)
54
55         self.ui.checkBox.setChecked(False)
56
57         self.clipboard = QApplication.clipboard()
58
59         self.ui.lineEdit.returnPressed.connect(self.updateUi)
60
61         self.ui.comboBox.activated.connect(self.changeCombo)
62         
63         self.ui.webView.settings().setUserStyleSheetUrl(
64                                                QUrl.fromLocalFile(":/lexi.css"))
65
66         self.ui.listView.clicked.connect(self.rowClicked)
67
68         self.clipboard.dataChanged.connect(self.autoGetFromClipboard)
69
70     def updateUi(self):
71         try:
72             # Check if input text is a word
73             if len(unicode(self.ui.lineEdit.text()).split()) <= 1:
74                 self.typed = unicode(self.ui.lineEdit.text())
75                 self.getLexi(self.typed)
76                 self.ui.comboBox.clear()
77                 self.ui.comboBox.addItems(self.lexiForm())
78                 self.lexiContent()
79                 self.ui.listView.setModel(self.getSynoAnto("synonymie"))
80                 self.ui.listView_2.setModel(self.getSynoAnto("antonymie"))
81             else:
82                 self.ui.lineEdit.setText("Veuillez entrer UN mot")
83
84         except:
85             self.ui.lineEdit.setText("Veuillez entrer un mot")
86
87     # Copy selected item in list to the clipboard
88     def rowClicked(self, qmodelindex):
89         self.item = qmodelindex.data(Qt.DisplayRole).toString()
90         self.clipboard.setText(self.item)
91
92     def autoGetFromClipboard(self):
93         if self.ui.checkBox.isChecked():
94             self.ui.lineEdit.setText(unicode(self.clipboard.text()))
95             self.updateUi()
96
97     def changeCombo(self):
98         self.getLexi(self.typed)
99         self.lexiContent()
100     
101     def getSynoAnto(self, form):
102         tag = []
103         soup = BeautifulSoup(self.getHtml(self.typed, form))
104         tagy = soup.find_all('td', "%s_format" % (form[:4]))
105         i = 0
106         while i < len(tagy):
107             tag_a = tagy[i]
108             tag.append(tag_a.text)
109             i += 1
110         model = ListModel(tag, self)
111         return model
112      
113     def getLexi(self, text):
114         h = self.getHtml(text, "definition")
115         global soup
116         soup = BeautifulSoup(h, "lxml")
117         return soup
118
119     def lexiContent(self):
120         tagy = soup.find_all('div', {'id': 'contentbox'})
121         tag = str(tagy[0])
122         self.ui.webView.setHtml(tag.decode('utf8'))
123         return tagy
124
125     # Recupere les differentes formes
126     def lexiForm(self):
127         a = re.compile("return sendRequest\(5,'/definition/.*")
128         multdef = soup.find_all('a', {'onclick': a})
129         tagform = []
130         i = 0
131         while i < len(multdef):
132             multdef_a = multdef[i]
133             # Suppression des chiffres présents dans la chaîne
134             multdef_clean = ''.join(c for c in
135                                     multdef_a.text if not c.isdigit())
136             # Ajout de chaque chaîne à la liste tagform
137             tagform.append(multdef_clean)
138             i += 1
139         return tagform
140
141     def getHtml(self, text, form):
142         conn = httplib2.Http(".cache")
143         numdef = self.ui.comboBox.currentIndex()
144         if form == "definition":
145             htmlSource = conn.request("http://www.cnrtl.fr/%s/%s//%s" %
146                                         (form, text, numdef), "GET")
147         else:
148             htmlSource = conn.request("http://www.cnrtl.fr/%s/%s" %
149                                         (form, text), "GET")
150         return htmlSource[1]
151         
152     # Delete cache directory on close
153     def closeEvent(self, event):
154         shutil.rmtree('.cache')
155         print "closed"
156
157 class ListModel(QAbstractListModel):
158     def __init__(self, datain, parent=None, *args):
159         """ datain: a list where each item is a row
160         """
161         QAbstractListModel.__init__(self, parent, *args)
162         self.listdata = datain
163
164     def rowCount(self, parent=QModelIndex()):
165         return len(self.listdata)
166
167     def data(self, index, role):
168         if index.isValid() and role == Qt.DisplayRole:
169             return QVariant(self.listdata[index.row()])
170         else:
171             return QVariant()
172
173 if __name__ == "__main__":
174     main()