factiva
[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 #Lisense: GNU/GPL
6
7 import xml.dom.minidom
8 import wx.lib.sized_controls as sc
9 import wx.lib.filebrowsebutton as filebrowse
10 import os
11 import codecs
12 import sys
13 import re
14 import wx
15 from parse_factiva_mail import ParseFactivaMail
16 from parse_factiva_txt import ParseFactivaPaste
17
18 def ParseDocument(filename) :
19     print 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     i = 0
27     for article in articles :
28         headline = article.getElementsByTagName("headline")
29         if headline != [] :
30             para_headline = headline[0].getElementsByTagName("paragraph")
31             val_headline = [val.firstChild.nodeValue.replace('\n', ' ') for val in para_headline]
32         else :
33             val_headline = []
34         leadParagraph = article.getElementsByTagName("leadParagraph")
35         if leadParagraph != [] :
36             para_leadParagraph = leadParagraph[0].getElementsByTagName("paragraph")
37             val_leadParagraph = [val.firstChild.nodeValue.replace('\n', ' ') for val in para_leadParagraph]
38         else :
39             val_leadParagraph = []
40         publicationDate = article.getElementsByTagName("publicationDate")
41         if publicationDate != [] :
42             para_publicationDate = publicationDate[0].getElementsByTagName("date")
43             if para_publicationDate == [] :
44                 para_publicationDate = publicationDate[0].getElementsByTagName("dateTime")
45             val_publicationDate = [val.firstChild.nodeValue.replace('\n', ' ') for val in para_publicationDate]
46         else :
47             val_publicationDate = []
48         sourceName = article.getElementsByTagName("sourceName")
49         if sourceName != [] :
50             val_sourceName = sourceName[0].firstChild.nodeValue.replace('\n', ' ')
51         else :
52             val_sourceName = INCONNU
53         tailParagraphs = article.getElementsByTagName("tailParagraphs")
54         if tailParagraphs != [] :
55             para_tailParagraphs = tailParagraphs[0].getElementsByTagName("paragraph")
56             val_tailParagraphs = [val.firstChild.nodeValue.replace('\n', ' ') for val in para_tailParagraphs]
57         else :
58             val_tailParagraphs = []
59         inter = [' '.join(val_headline), val_sourceName,' '.join(val_publicationDate), ' '.join(val_leadParagraph), ' '.join(val_tailParagraphs)]
60         inter = [re.sub(ur'[ "\n\r]+', ' ',  val).replace('"',' ').replace('\n', ' ').replace('\r', ' ')  for val in inter]
61         #inter = ['"' + val +'"' for val in inter]
62         result.append(inter)
63     return result
64     
65 def getcorpus_from_xml(xmldir, corpus_out):
66     files = os.listdir(xmldir)
67     files = [os.path.join(xmldir,file) for file in files if os.path.splitext(file)[1] == '.xml']
68     if len(files) == 0 :
69         return 'nofile'
70     result = []
71     fileout = codecs.open(corpus_out, 'w', 'utf-8')
72     for file in files :
73         rs = ParseDocument(file)
74         #dates = [row[2].split('-') for row in rs]
75         #dates = [[date[0],date[1],date[2].split('T')[0]] for date in dates]
76         #txt = '\n'.join(['\n'.join([' '.join([u'****', '*%s' % row[1].replace(' ','_').replace('\'','_'), '*%s' % row[2].replace('-','_')]), row[3], row[4]]) for row in rs])
77         #avec la date decompose
78         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])
79         fileout.write(txt+'\n\n')
80     fileout.close()
81     return 'ok'
82
83 class PrefImport(wx.Dialog):
84     def __init__(self, parent, size=wx.DefaultSize, pos=wx.DefaultPosition, style=wx.DEFAULT_DIALOG_STYLE):
85         pre = wx.PreDialog()
86         pre.SetExtraStyle(wx.DIALOG_EX_CONTEXTHELP)
87         pre.Create(parent, -1, '', pos, size, style)
88         self.PostCreate(pre)
89
90         self.parent = parent
91         self.txt1 = wx.StaticText(self, -1, u"Répertoire des fichiers xml")
92         self.dbb = filebrowse.DirBrowseButton(self, -1, size=(450, -1), changeCallback = self.fbbCallback)
93         self.dbb.SetLabel("")
94         self.txt2 = wx.StaticText(self, -1, u"Fichier en sortie")
95         self.fbb = filebrowse.FileBrowseButton(self, -1, size=(450, -1), fileMode = 2)
96         self.fbb.SetLabel("")
97
98         self.btnsizer = wx.StdDialogButtonSizer()
99         btn_ok = wx.Button(self, wx.ID_OK)
100         btn = wx.Button(self, wx.ID_CANCEL)
101         self.btnsizer.AddButton(btn_ok)
102         self.btnsizer.AddButton(btn)
103         self.btnsizer.Realize()
104
105
106         self.Bind(wx.EVT_BUTTON, self.checkfile, btn_ok)
107
108         #self.SetButtonSizer(self.CreateStdDialogButtonSizer(wx.OK | wx.CANCEL))
109         self.Bind(wx.EVT_BUTTON, self.checkfile)
110
111         self. __do_layout()
112         #self.Fit()
113         self.SetMinSize(self.GetSize())
114     
115     def __do_layout(self):
116         sizer = wx.BoxSizer(wx.VERTICAL)
117         grid_sizer_1 = wx.BoxSizer(wx.HORIZONTAL)
118         grid_sizer_2 = wx.BoxSizer(wx.HORIZONTAL)
119         grid_sizer_1.Add(self.txt1, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, 0)
120         grid_sizer_1.Add(self.dbb, 2, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, 0)
121         grid_sizer_2.Add(self.txt2, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, 0)
122         grid_sizer_2.Add(self.fbb, 2, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, 0)
123         sizer.Add(grid_sizer_1, 0,  wx.EXPAND, 0)
124         sizer.Add(grid_sizer_2, 0,  wx.EXPAND, 0)
125         sizer.Add(self.btnsizer, 0,  wx.EXPAND, 0)
126         self.SetSizer(sizer)
127         sizer.Fit(self)
128         self.Layout()
129
130    
131     def fbbCallback(self, evt):
132         if self.fbb.GetValue() == "" :
133              self.fbb.SetValue(os.path.join(self.dbb.GetValue(), 'corpus.txt'))
134         #self.log.write('FileBrowseButton: %s\n' % evt.GetString())
135
136     def checkfile(self, evt) :
137         if evt.GetId() == wx.ID_OK :
138             if self.dbb.GetValue() != "" :
139                 if os.path.exists(self.fbb.GetValue()):
140                     dlg = wx.MessageDialog(self, 
141                     u"%s\nCe fichier existe, continuer quand même ?" % self.fbb.GetValue(), 'ATTENTION', wx.NO | wx.YES | wx.ICON_WARNING)
142                     dlg.CenterOnParent()
143                     if dlg.ShowModal() not in [wx.ID_NO, wx.ID_CANCEL]:
144                         self.EndModal(wx.ID_OK)
145                 else :
146                     self.EndModal(wx.ID_OK)
147             else :
148                 dlg = wx.MessageDialog(self, u"Vous devez choisir le répertoire contenant le ou les fichier(s) xml", 'ATTENTION', wx.OK | wx.ICON_WARNING)
149                 dlg.CenterOnParent()
150                 dlg.ShowModal()
151
152         else :
153             self.EndModal(wx.ID_CANCEL)
154
155
156
157 class ImportFactiva():
158     def __init__(self, parent, methode):
159        self.dial =  PrefImport(parent)
160        self.dial.CenterOnParent()
161        val = self.dial.ShowModal()
162        if val == wx.ID_OK :
163            xmldir = self.dial.dbb.GetValue()
164            corp_out = self.dial.fbb.GetValue()
165            if methode == 'xml' :
166                 res = getcorpus_from_xml(xmldir, corp_out)
167            elif methode == 'mail' :
168                res = ParseFactivaMail(xmldir, corp_out, 'utf8', parent.syscoding)
169            elif methode == 'txt' :
170                res = ParseFactivaPaste(xmldir, corp_out, 'utf8', parent.syscoding)
171            if res == 'nofile' :
172                 dlg = wx.MessageDialog(parent, u"Pas de fichier \'.xml\' dans %s" % xmldir, 'ATTENTION', wx.OK | wx.NO_DEFAULT | wx.ICON_WARNING)
173                 dlg.CenterOnParent()
174                 dlg.ShowModal()
175            #else :
176            #     parent.filename = corp_out
177            #     parent.OpenText()