| 1 | #!/usr/bin/python
|
|---|
| 2 | # -*- coding: utf-8 -*-
|
|---|
| 3 |
|
|---|
| 4 | from __future__ import unicode_literals, print_function
|
|---|
| 5 |
|
|---|
| 6 | import urllib2 as u2
|
|---|
| 7 | import xml.etree.ElementTree as ET
|
|---|
| 8 | import collections as col
|
|---|
| 9 | import sys, codecs, locale
|
|---|
| 10 | sys.stdout = codecs.getwriter(locale.getpreferredencoding())(sys.stdout)
|
|---|
| 11 |
|
|---|
| 12 | Stat = col.namedtuple('Stat', ['count', 'name', 'branch', 'work',
|
|---|
| 13 | 'untranslated','fuzzy', 'translated', 'total'])
|
|---|
| 14 |
|
|---|
| 15 | titles = Stat(count=('Номер', 'rjust'), name=('Име', 'ljust'),
|
|---|
| 16 | branch=('Клон', 'ljust'), work=('Работа', 'rjust'),
|
|---|
| 17 | untranslated=('Непреведени', 'rjust'), fuzzy=('Мъгляви', 'rjust'),
|
|---|
| 18 | translated=('Преведени', 'rjust'), total=('Всичко', 'rjust'))
|
|---|
| 19 |
|
|---|
| 20 | #titles = Stat(count=('Number', 'rjust'), name=('Name', 'ljust'),
|
|---|
| 21 | # branch=('Branch', 'ljust'), work=('Work', 'ljust'),
|
|---|
| 22 | # untranslated=('Untranslated', 'ljust'), fuzzy=('Fuzyy', 'rjust'),
|
|---|
| 23 | # translated=('Translated', 'rjust'), total=('All', 'rjust'))
|
|---|
| 24 |
|
|---|
| 25 |
|
|---|
| 26 | def get_versions():
|
|---|
| 27 | versions_url = 'https://l10n.gnome.org/releases/xml'
|
|---|
| 28 | versions_data = u2.urlopen(versions_url)
|
|---|
| 29 |
|
|---|
| 30 | versions_tree = ET.parse(versions_data)
|
|---|
| 31 | versions_root = versions_tree.getroot()
|
|---|
| 32 | versions_xpath = './object/field[@name="name"]'
|
|---|
| 33 | version_elements = versions_root.findall(versions_xpath)
|
|---|
| 34 | versions = [e.text for e in version_elements]
|
|---|
| 35 | return versions
|
|---|
| 36 |
|
|---|
| 37 |
|
|---|
| 38 | def get_stats(version):
|
|---|
| 39 | stats_url = 'https://l10n.gnome.org/languages/bg/{}/xml'.format(version)
|
|---|
| 40 | stats_data = u2.urlopen(stats_url)
|
|---|
| 41 | stats_tree = ET.parse(stats_data)
|
|---|
| 42 | stats_root = stats_tree.getroot()
|
|---|
| 43 | stats_xpath = './category/module'
|
|---|
| 44 | stats_elements = stats_root.findall(stats_xpath)
|
|---|
| 45 | results = []
|
|---|
| 46 | for stats_el in stats_elements:
|
|---|
| 47 | stat_id = stats_el.attrib['id']
|
|---|
| 48 | stat_branch = stats_el.attrib['branch']
|
|---|
| 49 | domains = stats_el.findall('./domain')
|
|---|
| 50 | for dom in domains:
|
|---|
| 51 | dom_id = dom.attrib['id']
|
|---|
| 52 | if dom_id == 'po':
|
|---|
| 53 | name = stat_id
|
|---|
| 54 | elif dom_id.startswith('po-'):
|
|---|
| 55 | name = '{}-{}'.format(stat_id, dom_id[3:])
|
|---|
| 56 | else:
|
|---|
| 57 | name = '{}-{}'.format(stat_id ,dom_id)
|
|---|
| 58 | translated = int(dom.findtext('./translated'))
|
|---|
| 59 | fuzzy = int(dom.findtext('./fuzzy'))
|
|---|
| 60 | untranslated = int(dom.findtext('./untranslated'))
|
|---|
| 61 | work = fuzzy + untranslated
|
|---|
| 62 | total = work + translated
|
|---|
| 63 | s = Stat(count=None, name=name, branch=stat_branch,
|
|---|
| 64 | translated=translated, fuzzy=fuzzy,
|
|---|
| 65 | untranslated=untranslated, work=work, total=total)
|
|---|
| 66 | results.append(s)
|
|---|
| 67 | # sorts are stable
|
|---|
| 68 | results.sort(key=lambda s: s.name)
|
|---|
| 69 | results.sort(key=lambda s: s.fuzzy, reverse=True)
|
|---|
| 70 | results.sort(key=lambda s: s.untranslated, reverse=True)
|
|---|
| 71 | results.sort(key=lambda s: s.work, reverse=True)
|
|---|
| 72 | for i, s in enumerate(results):
|
|---|
| 73 | results[i] = s._replace(count=i+1)
|
|---|
| 74 | return results
|
|---|
| 75 |
|
|---|
| 76 |
|
|---|
| 77 | def stats_max_lengths_sums(stats):
|
|---|
| 78 | name = 0
|
|---|
| 79 | branch = 0
|
|---|
| 80 | sum_translated = 0
|
|---|
| 81 | sum_fuzzy = 0
|
|---|
| 82 | sum_untranslated = 0
|
|---|
| 83 | sum_work = 0
|
|---|
| 84 | sum_total = 0
|
|---|
| 85 |
|
|---|
| 86 | for s in stats:
|
|---|
| 87 | name = max(name, len(s.name))
|
|---|
| 88 | branch = max(branch, len(s.branch))
|
|---|
| 89 | sum_translated = sum_translated + s.translated
|
|---|
| 90 | sum_fuzzy = sum_fuzzy + s.fuzzy
|
|---|
| 91 | sum_untranslated = sum_untranslated + s.untranslated
|
|---|
| 92 | sum_work = sum_work + s.work
|
|---|
| 93 | sum_total = sum_total + s.total
|
|---|
| 94 |
|
|---|
| 95 | max_len = Stat(count=len(str(len(stats))), name=name, branch=branch,
|
|---|
| 96 | translated=len(str(sum_translated)), fuzzy=len(str(sum_fuzzy)),
|
|---|
| 97 | untranslated=len(str(sum_untranslated)), work=len(str(sum_work)),
|
|---|
| 98 | total=len(str(sum_total)))
|
|---|
| 99 | sums = Stat(count=len(stats), name='', branch='', translated=sum_translated,
|
|---|
| 100 | fuzzy=sum_fuzzy, untranslated=sum_untranslated, work=sum_work,
|
|---|
| 101 | total=sum_total)
|
|---|
| 102 | return {'max_len': max_len, 'sums': sums}
|
|---|
| 103 |
|
|---|
| 104 |
|
|---|
| 105 | def divider(s):
|
|---|
| 106 | inner = '┼'.join(['─' * (f + 1) for f in s])
|
|---|
| 107 | return '├' + inner + '┤'
|
|---|
| 108 |
|
|---|
| 109 | def start(s):
|
|---|
| 110 | inner = '┬'.join(['─' * (f + 1) for f in s])
|
|---|
| 111 | return '┌' + inner + '┐'
|
|---|
| 112 |
|
|---|
| 113 | def end(s):
|
|---|
| 114 | inner = '┴'.join(['─' * (f + 1) for f in s])
|
|---|
| 115 | return '└' + inner + '┘'
|
|---|
| 116 |
|
|---|
| 117 |
|
|---|
| 118 | def stat_line(max_len, s):
|
|---|
| 119 | args = []
|
|---|
| 120 | for i in range(len(max_len)):
|
|---|
| 121 | width = max_len[i] + 1
|
|---|
| 122 | method_name = 'rjust' if isinstance(s[i], int) else 'ljust'
|
|---|
| 123 | part = getattr(str(s[i]), method_name)(width)[:width]
|
|---|
| 124 | args.append(part)
|
|---|
| 125 |
|
|---|
| 126 | result = '│{0}│{1}│{2}│{3}│{4}│{5}│{6}│{7}│'.format(*tuple(args))
|
|---|
| 127 | return result
|
|---|
| 128 |
|
|---|
| 129 |
|
|---|
| 130 | def title_line(max_len):
|
|---|
| 131 | args = []
|
|---|
| 132 | for i in range(len(max_len)):
|
|---|
| 133 | width = max_len[i] + 1
|
|---|
| 134 | method_name = titles[i][1]
|
|---|
| 135 | part = getattr(titles[i][0], method_name)(width)[:width]
|
|---|
| 136 | args.append(part)
|
|---|
| 137 |
|
|---|
| 138 | result = '│{0}│{1}│{2}│{3}│{4}│{5}│{6}│{7}│'.format(*tuple(args))
|
|---|
| 139 | return result
|
|---|
| 140 |
|
|---|
| 141 |
|
|---|
| 142 | def main():
|
|---|
| 143 | #a = sys.args
|
|---|
| 144 | #versions = get_versions()
|
|---|
| 145 | #if not len(a) == 1 or a[0] not in versions:
|
|---|
| 146 | # print('Give single argument, one of: {} '.format(versions))
|
|---|
| 147 | # print('Will use {}'.format(versions[0]))
|
|---|
| 148 | stats = get_stats('gnome-3-20')
|
|---|
| 149 | sms = stats_max_lengths_sums(stats)
|
|---|
| 150 | max_len = sms['max_len']
|
|---|
| 151 | sums = sms['sums']
|
|---|
| 152 |
|
|---|
| 153 | print(max_len)
|
|---|
| 154 | print(sums)
|
|---|
| 155 | s = start(max_len)
|
|---|
| 156 | d = divider(max_len)
|
|---|
| 157 | e = end(max_len)
|
|---|
| 158 | print(s)
|
|---|
| 159 | print(title_line(max_len))
|
|---|
| 160 | print(d)
|
|---|
| 161 | for s in stats:
|
|---|
| 162 | print(stat_line(max_len, s))
|
|---|
| 163 | print(d)
|
|---|
| 164 | print(stat_line(max_len, sums))
|
|---|
| 165 | print(e)
|
|---|
| 166 |
|
|---|
| 167 | if __name__ == '__main__':
|
|---|
| 168 | main()
|
|---|
| 169 |
|
|---|
| 170 |
|
|---|
| 171 |
|
|---|
| 172 |
|
|---|