grass_po_stats.py 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. #!/usr/bin/env python
  2. #############################################################################
  3. #
  4. # MODULE: Languages information and statistics (Python)
  5. # AUTHOR(S): Luca Delucchi <lucadeluge@gmail.com>
  6. # Pietro Zambelli <peter.zamb@gmail.com>
  7. # PURPOSE: Create a json file containing languages translations
  8. # information and statistics.
  9. # COPYRIGHT: (C) 2012 by the GRASS Development Team
  10. #
  11. # This program is free software under the GNU General
  12. # Public License (>=v2). Read the file COPYING that
  13. # comes with GRASS for details.
  14. #
  15. #############################################################################
  16. from __future__ import print_function
  17. import os, sys
  18. import subprocess
  19. import json
  20. import glob
  21. import codecs
  22. def read_po_files(inputdirpath):
  23. """Return a dictionary with for each language the list of *.po files"""
  24. originalpath = os.getcwd()
  25. os.chdir(inputdirpath)
  26. languages = {}
  27. for pofile in glob.glob("*.po"):
  28. lang = pofile.split('_')[1:]
  29. # check if are two definitions like pt_br
  30. if len(lang) == 2:
  31. lang = ['_'.join(lang)]
  32. lang = lang[0].split('.')[0]
  33. # if keys is not in languages add it and the file's name
  34. if lang not in languages:
  35. languages[lang] = [pofile, ]
  36. # add only files name
  37. else:
  38. languages[lang].append(pofile)
  39. os.chdir(originalpath)
  40. return languages
  41. def read_msgfmt_statistics(msg, lgood, lfuzzy, lbad):
  42. """Return a dictionary, and the good, fuzzy and bad values from a string"""
  43. langdict = {}
  44. # split the output
  45. out = msg.split(b',')
  46. # TODO maybe check using regex
  47. # check for each answer
  48. for o in out:
  49. o = o.lower().strip()
  50. # each answer is written into dictionary and
  51. # the value add to variable for the sum
  52. if b'untranslated' in o:
  53. val = int(o.split(b' ')[0])
  54. langdict['bad'] = val
  55. lbad += val
  56. elif b'fuzzy' in o:
  57. val = int(o.split(b' ')[0])
  58. langdict['fuzzy'] = val
  59. lfuzzy += val
  60. else:
  61. val = int(o.split(b' ')[0])
  62. langdict['good'] = val
  63. lgood += val
  64. return langdict, lgood, lfuzzy, lbad
  65. def langDefinition(fil):
  66. f = codecs.open(fil, encoding='utf-8', errors='replace', mode='r')
  67. for l in f.readlines():
  68. if '"Language-Team:' in l:
  69. lang = l.split(' ')[1:-1]
  70. break
  71. f.close()
  72. if len(lang) == 2:
  73. return " ".join(lang)
  74. elif len(lang) == 1:
  75. return lang[0]
  76. else:
  77. return ""
  78. def get_stats(languages, directory):
  79. """Return a dictionary with the statistic for each language"""
  80. # output dictionary to transform in json file
  81. output = {}
  82. # TO DO TOTALS OF ENGLISH WORD FOR EACH FILE
  83. # all the total string in english
  84. output['totals'] = {}
  85. # all the information about each lang
  86. output['langs'] = {}
  87. # for each language
  88. for lang, pofilelist in languages.items():
  89. output['langs'][lang] = {}
  90. output['langs'][lang]['total'] = {}
  91. output['langs'][lang]['name'] = langDefinition(os.path.join(directory, pofilelist[0]))
  92. # variables to create sum for each language
  93. lgood = 0
  94. lfuzzy = 0
  95. lbad = 0
  96. # for each file
  97. for flang in pofilelist:
  98. fpref = flang.split('_')[0]
  99. # run msgfmt for statistics
  100. # TODO check if it's working on windows
  101. process = subprocess.Popen(['msgfmt', '--statistics',
  102. os.path.join(directory,flang)],
  103. stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  104. msg = process.communicate()[1].strip()
  105. # check if some errors occurs
  106. if msg.find(b'error') != -1:
  107. # TODO CHECK IF grass.warning()
  108. print("WARNING: file <%s> has some problems: <%s>" % (flang, msg))
  109. continue
  110. output['langs'][lang][fpref], lgood, lfuzzy, lbad = \
  111. read_msgfmt_statistics(msg, lgood, lfuzzy, lbad)
  112. # write the sum and total of each file
  113. output['langs'][lang]['total']['good'] = lgood
  114. output['langs'][lang]['total']['fuzzy'] = lfuzzy
  115. output['langs'][lang]['total']['bad'] = lbad
  116. output['langs'][lang]['total']['total'] = lgood + lfuzzy + lbad
  117. return output
  118. def writejson(stats, outfile):
  119. # load dictionary into json format
  120. fjson = json.dumps(stats, sort_keys=True, indent=4)
  121. # write a string with pretty style
  122. outjson = os.linesep.join([l.rstrip() for l in fjson.splitlines()])
  123. # write out file
  124. fout = open(outfile, 'w')
  125. fout.write(outjson)
  126. fout.write(os.linesep)
  127. fout.close()
  128. try:
  129. os.remove("messages.mo")
  130. except:
  131. pass
  132. def main(in_dirpath, out_josonpath):
  133. languages = read_po_files(in_dirpath)
  134. stats = get_stats(languages, in_dirpath)
  135. if os.path.exists(out_josonpath):
  136. os.remove(out_josonpath)
  137. writejson(stats, out_josonpath)
  138. if __name__ == "__main__":
  139. directory = 'po/'
  140. outfile = os.path.join(os.environ['GISBASE'], 'translation_status.json')
  141. sys.exit(main(directory, outfile))