compatibility R 4.0
[iramuteq] / parse_factiva_xml.py
1 #!/bin/env python
2 # -*- coding: utf-8 -*-
3 #Author: Pierre Ratinaud
4 #Copyright (c) 2008-2010 Pierre Ratinaud
5 #License: GNU/GPL
6
7 import xml.dom.minidom
8 import wx.lib.filebrowsebutton as filebrowse
9 import os
10 import codecs
11 import re
12 import wx
13 from parse_factiva_mail import ParseFactivaMail
14 from parse_factiva_txt import ParseFactivaPaste
15 from parse_europress import ParseEuropress
16 from import_txm import TXM2IRA
17 from functions import BugReport
18
19 def ParseDocument(filename) :
20     with codecs.open(filename, 'r', 'utf-8') as f :
21         content = f.read()
22     content = content.replace('<hlt>', ' ').replace('</hlt>', ' ')
23     dom = xml.dom.minidom.parseString(content.encode("utf-8"))
24     result = []
25     articles = dom.getElementsByTagName("article")
26     for article in articles :
27         headline = article.getElementsByTagName("headline")
28         if headline != [] :
29             para_headline = headline[0].getElementsByTagName("paragraph")
30             val_headline = [val.firstChild.nodeValue.replace('\n', ' ') for val in para_headline]
31         else :
32             val_headline = []
33         leadParagraph = article.getElementsByTagName("leadParagraph")
34         if leadParagraph != [] :
35             para_leadParagraph = leadParagraph[0].getElementsByTagName("paragraph")
36             val_leadParagraph = [val.firstChild.nodeValue.replace('\n', ' ') for val in para_leadParagraph]
37         else :
38             val_leadParagraph = []
39         publicationDate = article.getElementsByTagName("publicationDate")
40         if publicationDate != [] :
41             para_publicationDate = publicationDate[0].getElementsByTagName("date")
42             if para_publicationDate == [] :
43                 para_publicationDate = publicationDate[0].getElementsByTagName("dateTime")
44             val_publicationDate = [val.firstChild.nodeValue.replace('\n', ' ') for val in para_publicationDate]
45         else :
46             val_publicationDate = []
47         sourceName = article.getElementsByTagName("sourceName")
48         if sourceName != [] :
49             val_sourceName = sourceName[0].firstChild.nodeValue.replace('\n', ' ')
50         else :
51             val_sourceName = 'INCONNU'
52         tailParagraphs = article.getElementsByTagName("tailParagraphs")
53         if tailParagraphs != [] :
54             para_tailParagraphs = tailParagraphs[0].getElementsByTagName("paragraph")
55             val_tailParagraphs = [val.firstChild.nodeValue.replace('\n', ' ') for val in para_tailParagraphs]
56         else :
57             val_tailParagraphs = []
58         inter = [' '.join(val_headline), val_sourceName,' '.join(val_publicationDate), ' '.join(val_leadParagraph), ' '.join(val_tailParagraphs)]
59         inter = [re.sub(ur'[ "\n\r]+', ' ',  val).replace('"',' ').replace('\n', ' ').replace('\r', ' ')  for val in inter]
60         #inter = ['"' + val +'"' for val in inter]
61         result.append(inter)
62     return result
63     
64 def getcorpus_from_xml(xmldir, corpus_out):
65     files = os.listdir(xmldir)
66     files = [os.path.join(xmldir,f) for f in files if os.path.splitext(f)[1] == '.xml']
67     if len(files) == 0 :
68         return 'nofile'
69     fileout = codecs.open(corpus_out, 'w', 'utf-8')
70     for f in files :
71         rs = ParseDocument(f)
72         #dates = [row[2].split('-') for row in rs]
73         #dates = [[date[0],date[1],date[2].split('T')[0]] for date in dates]
74         #txt = '\n'.join(['\n'.join([' '.join([u'****', '*%s' % row[1].replace(' ','_').replace('\'','_'), '*%s' % row[2].replace('-','_')]), row[3], row[4]]) for row in rs])
75         #avec la date decompose
76         txt = '\n'.join(['\n'.join([' '.join([u'****', '*s_%s' % row[1].replace(' ','').replace('\'',''), '*annee_%s' % row[2].split('-')[0], '*mois_%s' % row[2].split('-')[1], '*jour_%s' % row[2].split('-')[2].split('T')[0]]), row[3], row[4]]) for row in rs])
77         fileout.write(txt+'\n\n')
78     fileout.close()
79     return 'ok'
80
81 class PrefImport(wx.Dialog):
82     def __init__(self, parent, size=wx.DefaultSize, pos=wx.DefaultPosition, style=wx.DEFAULT_DIALOG_STYLE, methode = 'mail'):
83         pre = wx.PreDialog()
84         pre.SetExtraStyle(wx.DIALOG_EX_CONTEXTHELP)
85         pre.Create(parent, -1, '', pos, size, style)
86         self.PostCreate(pre)
87         self.methode = methode
88         if methode in ['xml', 'txm'] :
89             txt = _(u'Select a directory of xml files').decode('utf8')
90         elif methode == 'euro' :
91             txt = _(u'Select a directory of html files').decode('utf8')
92         elif methode == 'dmi' :
93             txt = _(u'Select a csv file').decode('utf8')
94         else :
95             txt = _(u'Select a directory of txt files').decode('utf8')
96         self.parent = parent
97         self.txt1 = wx.StaticText(self, -1, txt)
98         if methode != 'dmi' :
99             self.dbb = filebrowse.DirBrowseButton(self, -1, size=(450, -1), changeCallback = self.fbbCallback)
100         else :
101             self.dbb = filebrowse.FileBrowseButton(self, -1, size=(450, -1), fileMode = 2, changeCallback = self.fbbCallback)
102         self.dbb.SetLabel("")
103         self.txt2 = wx.StaticText(self, -1, _(u'Output file').decode('utf8'))
104         self.fbb = filebrowse.FileBrowseButton(self, -1, size=(450, -1), fileMode = 2)
105         self.fbb.SetLabel("")
106
107         self.btnsizer = wx.StdDialogButtonSizer()
108         btn_ok = wx.Button(self, wx.ID_OK)
109         btn = wx.Button(self, wx.ID_CANCEL)
110         self.btnsizer.AddButton(btn_ok)
111         self.btnsizer.AddButton(btn)
112         self.btnsizer.Realize()
113
114
115         self.Bind(wx.EVT_BUTTON, self.checkfile, btn_ok)
116
117         #self.SetButtonSizer(self.CreateStdDialogButtonSizer(wx.OK | wx.CANCEL))
118         self.Bind(wx.EVT_BUTTON, self.checkfile)
119
120         self. __do_layout()
121         #self.Fit()
122         self.SetMinSize(self.GetSize())
123     
124     def __do_layout(self):
125         sizer = wx.BoxSizer(wx.VERTICAL)
126         grid_sizer_1 = wx.BoxSizer(wx.HORIZONTAL)
127         grid_sizer_2 = wx.BoxSizer(wx.HORIZONTAL)
128         grid_sizer_1.Add(self.txt1, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, 0)
129         grid_sizer_1.Add(self.dbb, 2, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, 0)
130         grid_sizer_2.Add(self.txt2, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, 0)
131         grid_sizer_2.Add(self.fbb, 2, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, 0)
132         sizer.Add(grid_sizer_1, 0,  wx.EXPAND, 0)
133         sizer.Add(grid_sizer_2, 0,  wx.EXPAND, 0)
134         sizer.Add(self.btnsizer, 0,  wx.EXPAND, 0)
135         self.SetSizer(sizer)
136         sizer.Fit(self)
137         self.Layout()
138
139    
140     def fbbCallback(self, evt):
141         if self.fbb.GetValue() == "" :
142             if self.methode != 'dmi' :
143                 self.fbb.SetValue(os.path.join(self.dbb.GetValue(), 'corpus.txt'))
144             else :
145                 self.fbb.SetValue(os.path.join(os.path.dirname(self.dbb.GetValue()), 'corpus.txt'))
146         #self.log.write('FileBrowseButton: %s\n' % evt.GetString())
147
148     def checkfile(self, evt) :
149         if evt.GetId() == wx.ID_OK :
150             if self.dbb.GetValue() != "" :
151                 if self.methode == 'dmi' :
152                     if not os.path.exists(self.dbb.GetValue()) :
153                         dlg = wx.MessageDialog(self, 
154                         ' : '.join([self.dbb.GetValue(), _(u"this file doesn't exist")]), 'ATTENTION', wx.NO | wx.YES | wx.ICON_WARNING)
155                         dlg.CenterOnParent()
156                         if dlg.ShowModal() not in [wx.ID_NO, wx.ID_CANCEL]:
157                             self.EndModal(wx.ID_OK)
158                 if os.path.exists(self.fbb.GetValue()):
159                     dlg = wx.MessageDialog(self, 
160                     u"%s\nCe fichier existe, continuer quand même ?" % self.fbb.GetValue(), 'ATTENTION', wx.NO | wx.YES | wx.ICON_WARNING)
161                     dlg.CenterOnParent()
162                     if dlg.ShowModal() not in [wx.ID_NO, wx.ID_CANCEL]:
163                         self.EndModal(wx.ID_OK)
164                 else :
165                     self.EndModal(wx.ID_OK)
166             else :
167                 dlg = wx.MessageDialog(self, u"Vous devez choisir le répertoire contenant le ou les fichier(s) xml", 'ATTENTION', wx.OK | wx.ICON_WARNING)
168                 dlg.CenterOnParent()
169                 dlg.ShowModal()
170
171         else :
172             self.EndModal(wx.ID_CANCEL)
173
174 class ImportFactiva():
175     def __init__(self, parent, methode):
176         self.dial =  PrefImport(parent, methode=methode)
177         self.dial.CenterOnParent()
178         val = self.dial.ShowModal()
179         if val == wx.ID_OK :
180             xmldir = self.dial.dbb.GetValue()
181             corp_out = self.dial.fbb.GetValue()
182             self.dial.Destroy()
183             busy = wx.BusyInfo(_("Please wait...").decode('utf8'))
184             wx.SafeYield()
185             try :
186                 if methode == 'xml' :
187                     res = getcorpus_from_xml(xmldir, corp_out)
188                 elif methode == 'mail' :
189                     res = ParseFactivaMail(xmldir, corp_out, 'utf8', parent.syscoding)
190                 elif methode == 'txt' :
191                     res = ParseFactivaPaste(xmldir, corp_out, 'utf8', parent.syscoding)
192                 elif methode == 'txm' :
193                     res = TXM2IRA(xmldir, corp_out, 'utf8', parent.syscoding)
194                 elif methode == 'euro' :
195                     res = ParseEuropress(xmldir, corp_out, 'utf8', 'utf8')
196                 del busy
197                 if res == 'nofile' :
198                     dlg = wx.MessageDialog(parent, u"Pas de fichiers dans %s" % xmldir, 'ATTENTION', wx.OK | wx.ICON_WARNING)
199                     dlg.CenterOnParent()
200                     dlg.ShowModal()
201                     dlg.Destroy()
202                 else :
203                     msg = '\n'.join([_(u"Corpus created :").decode('utf8'), corp_out, _(u"Do you want to open it in IRaMuTeQ ?").decode('utf8')])
204                     dlg = wx.MessageDialog(parent, msg, _(u'Information').decode('utf8'), wx.YES_NO | wx.ICON_INFORMATION | wx.STAY_ON_TOP)
205                     dlg.CenterOnParent()
206                     val = dlg.ShowModal()
207                     if val == wx.ID_YES :
208                         dlg.Destroy()
209                         parent.filename = os.path.abspath(corp_out)
210                         parent.OpenText()
211                     else :
212                         dlg.Destroy()
213             except :
214                 del busy
215                 BugReport(parent)
216         else :
217             self.dial.Destroy()
218