OSDN Git Service

Update changelog&releasenotes
[winmerge-jp/winmerge-jp.git] / Translations / GetTranslationsStatus.py
1 #!/usr/bin/python
2 # -*- coding: utf-8 -*-;
3
4 # The MIT License
5
6 # Copyright (c) 2009-2018 Tim Gerundt <tim@gerundt.de>
7
8 # Permission is hereby granted, free of charge, to any person obtaining a copy
9 # of this software and associated documentation files (the "Software"), to deal
10 # in the Software without restriction, including without limitation the rights
11 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 # copies of the Software, and to permit persons to whom the Software is
13 # furnished to do so, subject to the following conditions:
14
15 # The above copyright notice and this permission notice shall be included in
16 # all copies or substantial portions of the Software.
17
18 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 # THE SOFTWARE.
25
26 # $Id$
27
28 # Python script to get the status of the translations
29
30 import os
31 import os.path
32 import string
33 import re
34 import time
35 import codecs
36
37 class TranslationsStatus(object):
38     def __init__(self):
39         self._projects = []
40     
41     @property
42     def projects(self):
43         return self._projects
44     
45     @property
46     def languages(self):
47         ''' Return a list with all languages '''
48         temp = []
49         for project in self._projects: #For all projects...
50             for language in project.languages: #For all languages...
51                 if language not in temp: #If language NOT in list...
52                     temp.append(language)
53         temp.sort()
54         return temp
55     
56     @property
57     def noneTemplateLanguages(self):
58         ''' Return a list with all NONE template languages '''
59         temp = []
60         for project in self._projects: #For all projects...
61             for language in project.noneTemplateLanguages: #For all NONE template languages...
62                 if language not in temp: #If language NOT in list...
63                     temp.append(language)
64         temp.sort()
65         return temp
66     
67     def clear(self):
68         self._projects = []
69     
70     def addProject(self, project):
71         self._projects.append(project)
72     
73     def writeToXmlFile(self, xmlpath):
74         xmlfile = codecs.open(xmlpath, 'w', 'utf-8')
75         xmlfile.write('<?xml version="1.0" encoding="UTF-8"?>\n')
76         xmlfile.write('<status>\n')
77         xmlfile.write('  <update>%s</update>\n' % (time.strftime('%Y-%m-%d')))
78         for project in self._projects: #For all projects...
79             xmlfile.write('  <translations project="%s">\n' % (project.name))
80             for language in project.languages: #For all (sorted) languages...
81                 status1 = project[language]
82                 if status1.template: #If a template file...
83                     xmlfile.write('    <translation template="1">\n')
84                     xmlfile.write('      <language>%s</language>\n' % (status1.language))
85                     xmlfile.write('      <file>%s</file>\n' % (status1.filename))
86                     xmlfile.write('      <update>%s</update>\n' % (status1.updatedate[0:10]))
87                     xmlfile.write('      <strings>\n')
88                     xmlfile.write('        <count>%u</count>\n' % (status1.count))
89                     xmlfile.write('        <translated>%u</translated>\n' % (status1.count))
90                     xmlfile.write('        <fuzzy>0</fuzzy>\n')
91                     xmlfile.write('        <untranslated>0</untranslated>\n')
92                     xmlfile.write('      </strings>\n')
93                     xmlfile.write('    </translation>\n')
94                 else: #If NOT a template file...
95                     xmlfile.write('    <translation>\n')
96                     xmlfile.write('      <language>%s</language>\n' % (status1.language))
97                     xmlfile.write('      <file>%s</file>\n' % (status1.filename))
98                     xmlfile.write('      <update>%s</update>\n' % (status1.updatedate[0:10]))
99                     xmlfile.write('      <strings>\n')
100                     xmlfile.write('        <count>%u</count>\n' % (status1.count))
101                     xmlfile.write('        <translated>%u</translated>\n' % (status1.translated))
102                     xmlfile.write('        <fuzzy>%u</fuzzy>\n' % (status1.fuzzy))
103                     xmlfile.write('        <untranslated>%u</untranslated>\n' % (status1.untranslated))
104                     xmlfile.write('      </strings>\n')
105                     if status1.translators: #If translators exists...
106                         xmlfile.write('      <translators>\n')
107                         for translator in status1.translators: #For all translators...
108                             if (translator.ismaintainer): #If maintainer...
109                                 xmlfile.write('        <translator maintainer="1">\n')
110                             else: #If NOT maintainer...
111                                 xmlfile.write('        <translator>\n')
112                             xmlfile.write('          <name>%s</name>\n' % (translator.name))
113                             if (translator.mail): #If mail address exists...
114                                 xmlfile.write('          <mail>%s</mail>\n' % (translator.mail))
115                             xmlfile.write('        </translator>\n')
116                         xmlfile.write('      </translators>\n')
117                     xmlfile.write('    </translation>\n')
118             xmlfile.write('  </translations>\n')
119         xmlfile.write('</status>\n')
120         xmlfile.close()
121     
122     def writeToHtmlFile(self, htmlpath):
123         htmlfile = codecs.open(htmlpath, 'w', 'utf-8')
124         
125         htmlfile.write('<!DOCTYPE html>\n')
126         htmlfile.write('<html lang="en">\n')
127         htmlfile.write('<head>\n')
128         htmlfile.write('  <title>Translations Status</title>\n')
129         htmlfile.write('  <meta http-equiv="content-type" content="text/html; charset=UTF-8">\n')
130         htmlfile.write('  <style>\n')
131         htmlfile.write('  <!--\n')
132         htmlfile.write('    body {\n')
133         htmlfile.write('      font-family: Calibri,Helvetica,Arial,sans-serif;\n')
134         htmlfile.write('    }\n')
135         htmlfile.write('    h1, h2, h3, h4, h5, h6 {\n')
136         htmlfile.write('      font-family: Cambria,"Times New Roman",Times,serif;\n')
137         htmlfile.write('    }\n')
138         htmlfile.write('    .status {\n')
139         htmlfile.write('      border-collapse: collapse;\n')
140         htmlfile.write('      border: 1px solid #d2d2d2;\n')
141         htmlfile.write('    }\n')
142         htmlfile.write('    .status th, .status td {\n')
143         htmlfile.write('      padding: .3em;\n')
144         htmlfile.write('      border: 1px solid #d2d2d2;\n')
145         htmlfile.write('    }\n')
146         htmlfile.write('    .status th {\n')
147         htmlfile.write('      background: #f2f2f2;\n')
148         htmlfile.write('    }\n')
149         htmlfile.write('    .status tr:nth-child(odd) {\n')
150         htmlfile.write('      background: #f9f9f9;\n')
151         htmlfile.write('    }\n')
152         htmlfile.write('    .left { text-align: left; }\n')
153         htmlfile.write('    .center { text-align: center; }\n')
154         htmlfile.write('    .right { text-align: right; }\n')
155         htmlfile.write('\n')
156         htmlfile.write('    .translated { color: #2D802B; }\n')
157         htmlfile.write('    .fuzzy { color: #05359B; }\n')
158         htmlfile.write('    .untranslated { color: #D42323; }\n')
159         htmlfile.write('  -->\n')
160         htmlfile.write('  </style>\n')
161         htmlfile.write('</head>\n')
162         htmlfile.write('<body>\n')
163         htmlfile.write('<h1>Translations Status</h1>\n')
164         htmlfile.write('<p>Status from <strong>%s</strong>:</p>\n' % (time.strftime('%Y-%m-%d')))
165         for project in self._projects: #For all projects...
166             htmlfile.write('<h2>%s</h2>\n' % (project.name))
167             htmlfile.write('<table class="status">\n')
168             htmlfile.write('  <tr>\n')
169             htmlfile.write('    <th class="left">Language</th>\n')
170             htmlfile.write('    <th class="right">Total</th>\n')
171             htmlfile.write('    <th class="right translated">Translated</th>\n')
172             htmlfile.write('    <th class="right fuzzy">Fuzzy</th>\n')
173             htmlfile.write('    <th class="right untranslated">Untranslated</th>\n')
174             htmlfile.write('    <th class="right">Complete</th>\n')
175             htmlfile.write('    <th class="center">Last Update</th>\n')
176             htmlfile.write('  </tr>\n')
177             for language in project.languages: #For all (sorted) languages...
178                 status1 = project[language]
179                 htmlfile.write('  <tr>\n')
180                 htmlfile.write('    <td class="left">%s</td>\n' % (status1.language))
181                 if status1.template: #If a template file...
182                     if status1.count > 0: #If KNOWN status...
183                         htmlfile.write('    <td class="right">%u</td>\n' % (status1.count))
184                         htmlfile.write('    <td class="right translated">%u</td>\n' % (status1.count))
185                         htmlfile.write('    <td class="right fuzzy">0</td>\n')
186                         htmlfile.write('    <td class="right untranslated">0</td>\n')
187                         htmlfile.write('    <td class="right">100 %</td>\n')
188                     else: #If UNKNOWN status...
189                         htmlfile.write('    <td class="right">-</td>\n')
190                         htmlfile.write('    <td class="right translated">-</td>\n')
191                         htmlfile.write('    <td class="right fuzzy">-</td>\n')
192                         htmlfile.write('    <td class="right untranslated">-</td>\n')
193                         htmlfile.write('    <td class="right">-</td>\n')
194                     htmlfile.write('    <td class="center">%s</td>\n' % (status1.updatedate[0:10]))
195                 else: #If NOT a template file...
196                     if status1.count > 0: #If KNOWN status...
197                         htmlfile.write('    <td class="right">%u</td>\n' % (status1.count))
198                         htmlfile.write('    <td class="right translated">%u</td>\n' % (status1.translated))
199                         htmlfile.write('    <td class="right fuzzy">%u</td>\n' % (status1.fuzzy))
200                         htmlfile.write('    <td class="right untranslated">%u</td>\n' % (status1.untranslated))
201                         htmlfile.write('    <td class="right">%u %%</td>\n' % (status1.complete))
202                     else: #If UNKNOWN status...
203                         htmlfile.write('    <td class="right">-</td>\n')
204                         htmlfile.write('    <td class="right translated">-</td>\n')
205                         htmlfile.write('    <td class="right fuzzy">-</td>\n')
206                         htmlfile.write('    <td class="right untranslated">-</td>\n')
207                         htmlfile.write('    <td class="right">-</td>\n')
208                     htmlfile.write('    <td class="center">%s</td>\n' % (status1.updatedate[0:10]))
209                 htmlfile.write('  </tr>\n')
210             htmlfile.write('</table>\n')
211         
212         #Translators...
213         htmlfile.write('<h2>Translators</h2>\n')
214         htmlfile.write('<table class="status">\n')
215         htmlfile.write('  <tr>\n')
216         htmlfile.write('    <th class="left">Language</th>\n')
217         for project in self._projects: #For all projects...
218             htmlfile.write('    <th class="left">%s</th>\n' % project.name)
219         htmlfile.write('  </tr>\n')
220         for language in self.noneTemplateLanguages: #For all NONE template languages...
221             htmlfile.write('  <tr>\n')
222             htmlfile.write('    <td>%s</td>\n' % language)
223             for project in self._projects: #For all projects...
224                 status1 = project[language]
225                 if status1:
226                     htmlfile.write('    <td>')
227                     if status1.translators: #If translators exists...
228                         for translator in status1.translators: #For all translators...
229                             if (translator.ismaintainer): #If maintainer...
230                                 if (translator.mail): #If mail address exists...
231                                     htmlfile.write('<strong title="Maintainer"><a href="mailto:%s">%s</a></strong><br>' % (translator.mail, translator.name))
232                                 else: #If NO mail address exists...
233                                     htmlfile.write('<strong title="Maintainer">%s</strong><br>' % (translator.name))
234                             else: #If NOT maintainer...
235                                 if (translator.mail): #If mail address exists...
236                                     htmlfile.write('<a href="mailto:%s">%s</a><br>' % (translator.mail, translator.name))
237                                 else: #If NO mail address exists...
238                                     htmlfile.write('%s<br>' % (translator.name))
239                     htmlfile.write('</td>\n')
240                 else:
241                     htmlfile.write('    <td></td>\n')
242             htmlfile.write('  </tr>\n')
243         htmlfile.write('</table>\n')
244         
245         htmlfile.write('</body>\n')
246         htmlfile.write('</html>\n')
247         htmlfile.close()
248     
249     def writeToMdFile(self, mdpath):
250         mdfile = codecs.open(mdpath, 'w', 'utf-8')
251         
252         mdfile.write('# Translations Status\n\n')
253         mdfile.write('Status from **%s**:\n\n' % (time.strftime('%Y-%m-%d')))
254         for project in self._projects: #For all projects...
255             mdfile.write('## %s\n\n' % (project.name))
256             mdfile.write('| Language             | Total | Translated | Fuzzy | Untranslated | Complete | Last Update |\n')
257             mdfile.write('|:---------------------|------:|-----------:|------:|-------------:|---------:|:-----------:|\n')
258             for language in project.languages: #For all (sorted) languages...
259                 status1 = project[language]
260                 formatedlanguage = status1.language.ljust(20)
261                 formatedupdatedate = status1.updatedate[0:10].center(11)
262                 if status1.template: #If a template file...
263                     if status1.count > 0: #If KNOWN status...
264                         formatedcount = str(status1.count).rjust(5)
265                         formatedtranslated = str(status1.count).rjust(10)
266                         mdfile.write('| %s | %s | %s |     0 |            0 |    100 %% | %s |\n' % (formatedlanguage, formatedcount, formatedtranslated, formatedupdatedate))
267                     else: #If UNKNOWN status...
268                         mdfile.write('| %s |     - |          - |     - |            - |        - | %s |\n' % (formatedlanguage, formatedupdatedate))
269                 else: #If NOT a template file...
270                     if status1.count > 0: #If KNOWN status...
271                         formatedcount = str(status1.count).rjust(5)
272                         formatedtranslated = str(status1.translated).rjust(10)
273                         formatedfuzzy = str(status1.fuzzy).rjust(5)
274                         formateduntranslated = str(status1.untranslated).rjust(12)
275                         formatedcomplete = str(status1.complete).rjust(6)
276                         mdfile.write('| %s | %s | %s | %s | %s | %s %% | %s |\n' % (formatedlanguage, formatedcount, formatedtranslated, formatedfuzzy, formateduntranslated, formatedcomplete, formatedupdatedate))
277                     else: #If UNKNOWN status...
278                         mdfile.write('| %s |     - |          - |     - |            - |        - | %s |\n' % (formatedlanguage, formatedupdatedate))
279             mdfile.write('\n')
280         
281         #Translators...
282         mdfile.write('## Translators\n')
283         for project in self._projects: #For all projects...
284             mdfile.write('\n### %s\n' % project.name)
285             for language in self.noneTemplateLanguages: #For all NONE template languages...
286                 status1 = project[language]
287                 if status1:
288                     if status1.translators: #If translators exists...
289                         mdfile.write('\n * %s\n' % language)
290                         for translator in status1.translators: #For all translators...
291                             if (translator.ismaintainer): #If maintainer...
292                                 if (translator.mail): #If mail address exists...
293                                     mdfile.write('   - [%s](mailto:%s) *Maintainer*\n' % (translator.name, translator.mail.replace(" ", "%20")))
294                                 else: #If NO mail address exists...
295                                     mdfile.write('   - %s *Maintainer*\n' % (translator.name))
296                             else: #If NOT maintainer...
297                                 if (translator.mail): #If mail address exists...
298                                     mdfile.write('   - [%s](mailto:%s)\n' % (translator.name, translator.mail.replace(" ", "%20")))
299                                 else: #If NO mail address exists...
300                                     mdfile.write('   - %s\n' % (translator.name))
301         
302         mdfile.close()
303
304 class Project(object):
305     def __getitem__(self, key):
306         for status in self._status: #For all status...
307             if status.language == key:
308                 return status
309         return None
310     
311     @property
312     def name(self):
313         return self._name
314     
315     @property
316     def status(self):
317         return self._status
318     
319     @property
320     def languages(self):
321         ''' Return a list with all languages '''
322         temp = []
323         for status in self._status: #For all status...
324             temp.append(status.language)
325         temp.sort()
326         return temp
327     
328     @property
329     def noneTemplateLanguages(self):
330         ''' Return a list with all NONE template languages '''
331         temp = []
332         for status in self._status: #For all status...
333             if not status.template: #If NOT a template...
334                 temp.append(status.language)
335         temp.sort()
336         return temp
337
338 class Status(object):
339     @property
340     def filepath(self):
341         return self._filepath
342     
343     @property
344     def filename(self):
345         return os.path.basename(self._filepath)
346     
347     @property
348     def template(self):
349         return self._template
350     
351     @property
352     def charset(self):
353         return self._charset
354     
355     @property
356     def language(self):
357         if self._poeditlanguage: #If "X-Poedit-Language"...
358             return self._poeditlanguage
359         else: #If NOT "X-Poedit-Language"...
360             return os.path.splitext(self.filename)[0]
361     
362     @property
363     def count(self):
364         return self._count
365     
366     @property
367     def translated(self):
368         return self._translated
369     
370     @property
371     def untranslated(self):
372         return self._untranslated
373     
374     @property
375     def fuzzy(self):
376         return self._fuzzy
377     
378     @property
379     def complete(self):
380         return self._complete
381     
382     @property
383     def updatedate(self):
384         return self._updatedate
385     
386     @property
387     def translators(self):
388         return self._translators
389     
390     def calculateCompleteness(self):
391         if self._count > 0:
392             self._complete = round(((self._translated + self._fuzzy) * 100 / self._count))
393         else:
394             self._complete = 0.0
395
396 class Translator(object):
397     def __init__(self, name, mail, ismaintainer):
398         self.name = name
399         self.mail = mail
400         self.ismaintainer = ismaintainer
401
402 class PoProject(Project):
403     def __init__(self, name, potfile, podir):
404         self._name = name
405         self._status = []
406         
407         #PO files...
408         for itemname in os.listdir(podir): #For all dir items...
409             fullitempath = os.path.abspath(os.path.join(podir, itemname))
410             if os.path.isfile(fullitempath): #If a file...
411                 filename = os.path.splitext(itemname)
412                 if str.lower(filename[1]) == '.po': #If a PO file...
413                     self._status.append(PoStatus(fullitempath, False))
414         
415         #POT file...
416         self._status.append(PoStatus(os.path.abspath(potfile), True))
417
418 class PoStatus(Status):
419     def __init__(self, filepath, template):
420         self._filepath = filepath
421         self._template = template
422         self._charset = self._getCharsetFromPoFile(filepath)
423         self._count = 0
424         self._translated = 0
425         self._untranslated = 0
426         self._fuzzy = 0
427         self._complete = 0.0
428         self._porevisiondate = ''
429         self._potcreationdate = ''
430         self._poeditlanguage = ''
431         self._translators = []
432         
433         if self._charset == '': #If NO charset found...
434            return
435         
436         if os.access(filepath, os.R_OK): #If PO(T) file can read...
437           reMsgId = re.compile('^msgid "(.*)"$', re.IGNORECASE)
438           reMsgStr = re.compile('^msgstr "(.*)"$', re.IGNORECASE)
439           reMsgContinued = re.compile('^"(.*)"$', re.IGNORECASE)
440           reTranslator = re.compile('^# \* (.*)$', re.IGNORECASE)
441           rePoRevisionDate = re.compile('PO-Revision-Date: ([0-9 :\+\-]+)', re.IGNORECASE)
442           rePotCreationDate = re.compile('POT-Creation-Date: ([0-9 :\+\-]+)', re.IGNORECASE)
443           rePoeditLanguage = re.compile('X-Poedit-Language: ([A-Z \(\)\-_]+)', re.IGNORECASE)
444           
445           iMsgStarted = 0
446           sMsgId = ''
447           sMsgStr = ''
448           bIsFuzzy = False
449           bIsMaintainer = False
450           
451           encoding = self._charset.lower()
452           pofile = codecs.open(filepath, 'r', encoding)
453           for line in pofile: #For all lines...
454               line = line.strip()
455               if line: #If NOT empty line...
456                   if line[0] != '#': #If NOT comment line...
457                       if reMsgId.findall(line): #If "msgid"...
458                           iMsgStarted = 1
459                           tmp = reMsgId.findall(line)
460                           sMsgId = tmp[0]
461                       elif reMsgStr.findall(line): #If "msgstr"...
462                           iMsgStarted = 2
463                           tmp = reMsgStr.findall(line)
464                           sMsgStr = tmp[0]
465                       elif reMsgContinued.findall(line): #If "msgid" or "msgstr" continued...
466                           tmp = reMsgContinued.findall(line)
467                           if iMsgStarted == 1:
468                               sMsgId = sMsgId + tmp[0]
469                           elif iMsgStarted == 2:
470                               sMsgStr = sMsgStr + tmp[0]
471                   else: #If comment line...
472                       iMsgStarted = -1
473                       if line.startswith('#,'): #If "Reference" line...
474                           if line.find('fuzzy') > -1: #If "fuzzy"...
475                               bIsFuzzy = True
476                       elif line.startswith('# Maintainer:'): #If maintainer list starts...
477                           bIsMaintainer = True
478                       elif line.startswith('# Translators:'): #If translators list starts...
479                           bIsMaintainer = False
480                       elif reTranslator.findall(line): #If translator/maintainer...
481                           translator = reTranslator.findall(line)
482                           if re.findall('\<(.*)\>', translator[0]): #If mail address exists...
483                               tmp = re.findall('(.*) \<(.*)\>', translator[0])
484                               sName = tmp[0][0]
485                               sMail = tmp[0][1]
486                           else: #If mail address NOT exists...
487                               sName = translator[0]
488                               sMail = ''
489                           self._translators.append(Translator(sName, sMail, bIsMaintainer))
490               else: #If empty line...
491                   iMsgStarted = 0
492               
493               if iMsgStarted == 0: #If NOT inside a translation...
494                   if sMsgId != '':
495                       self._count += 1
496                       if bIsFuzzy == False: #If NOT a fuzzy translation...
497                           if sMsgStr != '':
498                               self._translated += 1
499                           else:
500                               self._untranslated += 1
501                       else: #If a fuzzy translation...
502                           self._fuzzy += 1
503                   elif sMsgStr != '':
504                       tmp = rePoRevisionDate.findall(sMsgStr)
505                       if tmp: #If "PO-Revision-Date"...
506                           #TODO: Convert to date!
507                           self._porevisiondate = tmp[0]
508                       tmp = rePotCreationDate.findall(sMsgStr)
509                       if tmp: #If "POT-Creation-Date"...
510                           #TODO: Convert to date!
511                           self._potcreationdate = tmp[0]
512                       tmp = rePoeditLanguage.findall(sMsgStr)
513                       if tmp: #If "X-Poedit-Language"...
514                           self._poeditlanguage = tmp[0]
515                   sMsgId = ''
516                   sMsgStr = ''
517                   bIsFuzzy = False
518           pofile.close()
519           
520           self.calculateCompleteness()
521     
522     @property
523     def updatedate(self):
524         if self._template: #if template...
525             return self._potcreationdate
526         else: #if NOT template...
527             return self._porevisiondate
528     
529     def _getCharsetFromPoFile(self, filepath):
530         charset = ''
531         if os.access(filepath, os.R_OK): #If PO(T) file can read...
532             reContentTypeCharset = re.compile('charset=([A-Z0-9\-]+)', re.IGNORECASE)
533             rePoeditSourceCharset = re.compile('X-Poedit-SourceCharset: ([A-Z0-9\-]+)', re.IGNORECASE)
534             
535             pofile = open(filepath, 'r', errors='ignore')
536             
537             for line in pofile: #For all lines...
538                 line = line.strip()
539                 
540                 tmp = reContentTypeCharset.findall(line)
541                 if tmp: #If "Content-Type-Charset"...
542                     charset = tmp[0]
543                     break
544                 tmp = rePoeditSourceCharset.findall(line)
545                 if tmp: #If "X-Poedit-SourceCharset"...
546                     charset = tmp[0]
547                     break
548             pofile.close()
549         return charset
550
551 class InnoSetupProject(Project):
552     def __init__(self, name, templatefile, translationsdir):
553         self._name = name
554         self._status = []
555         
556         #Translations files...
557         for itemname in os.listdir(translationsdir): #For all dir items...
558             fullitempath = os.path.abspath(os.path.join(translationsdir, itemname))
559             if os.path.isfile(fullitempath): #If a file...
560                 filename = os.path.splitext(itemname)
561                 if str.lower(filename[1]) == '.isl': #If a ISL file...
562                     if filename[0] != 'English': #If NOT the English file...
563                         self._status.append(InnoSetupStatus(fullitempath, False))
564         
565         #Template file...
566         self._status.append(InnoSetupStatus(os.path.abspath(templatefile), True))
567
568 class InnoSetupStatus(Status):
569     def __init__(self, filepath, template):
570         self._filepath = filepath
571         self._template = template
572         self._count = 0
573         self._translated = 0
574         self._untranslated = 0
575         self._fuzzy = 0
576         self._updatedate = ''
577         self._translators = []
578     
579     @property
580     def language(self):
581         if self._template: #if template...
582             return 'English'
583         else: #if NOT template...
584             filename = os.path.splitext(self.filename)
585             return filename[0].replace('_', '')
586
587 class ReadmeProject(Project):
588     def __init__(self, name, templatefile, translationsdir):
589         self._name = name
590         self._status = []
591         
592         #Translations files...
593         for itemname in os.listdir(translationsdir): #For all dir items...
594             fullitempath = os.path.abspath(os.path.join(translationsdir, itemname))
595             if os.path.isfile(fullitempath): #If a file...
596                 filename = os.path.splitext(itemname)
597                 if str.lower(filename[1]) == '.txt': #If a TXT file...
598                     self._status.append(ReadmeStatus(fullitempath, False))
599         
600         #Template file...
601         self._status.append(ReadmeStatus(os.path.abspath(templatefile), True))
602
603 class ReadmeStatus(Status):
604     def __init__(self, filepath, template):
605         self._filepath = filepath
606         self._template = template
607         self._count = 0
608         self._translated = 0
609         self._untranslated = 0
610         self._fuzzy = 0
611         self._updatedate = ''
612         self._translators = []
613     
614     @property
615     def language(self):
616         if self._template: #if template...
617             return 'English'
618         else: #if NOT template...
619             filename = os.path.splitext(self.filename)
620             return filename[0].replace('ReadMe-', '')
621
622 def main():
623     status = TranslationsStatus()
624     status.addProject(PoProject('WinMerge', 'WinMerge/English.pot', 'WinMerge'))
625     status.addProject(PoProject('ShellExtension', 'ShellExtension/English.pot', 'ShellExtension'))
626     status.addProject(InnoSetupProject('InnoSetup', 'InnoSetup/English.isl', 'InnoSetup'))
627     status.addProject(ReadmeProject('Docs/Readme', 'Docs/ReadMe.txt', 'Docs/Readme'))
628     status.writeToXmlFile('TranslationsStatus.xml')
629     status.writeToHtmlFile('TranslationsStatus.html')
630     status.writeToMdFile('TranslationsStatus.md')
631
632 # MAIN #
633 if __name__ == "__main__":
634     main()