15
15
from argparse import ArgumentParser
16
16
from collections import Counter
17
17
import os
18
- from re import match
18
+ from dataclasses import dataclass
19
+ from re import match , search
19
20
from subprocess import call , run
20
21
import sys
22
+ from typing import Self
23
+ from urllib .parse import unquote
21
24
22
25
LANGUAGE = 'pl'
23
26
@@ -89,29 +92,51 @@ def recreate_tx_config():
89
92
)
90
93
91
94
95
+ @dataclass
96
+ class ResourceLanguageStatistics :
97
+ name : str
98
+ total_words : int
99
+ translated_words : int
100
+ total_strings : int
101
+ translated_strings : int
102
+
103
+ @classmethod
104
+ def from_api_v3_entry (cls , data : dict ) -> Self :
105
+ return cls (
106
+ name = search ('r:([^:]*)' , data ['id' ]).group (1 ),
107
+ total_words = data ['attributes' ]['total_words' ],
108
+ translated_words = data ['attributes' ]['translated_words' ],
109
+ total_strings = data ['attributes' ]['total_strings' ],
110
+ translated_strings = data ['attributes' ]['translated_strings' ],
111
+ )
112
+
113
+
92
114
def _get_resources ():
93
115
from requests import get
94
116
95
117
resources = []
96
- offset = 0
118
+ cursor = None
97
119
if os .path .exists ('.tx/api-key' ):
98
120
with open ('.tx/api-key' ) as f :
99
121
transifex_api_key = f .read ()
100
122
else :
101
123
transifex_api_key = os .getenv ('TX_TOKEN' )
102
124
while True :
103
125
response = get (
104
- f'https://api.transifex.com/organizations/python-doc/projects/{ PROJECT_SLUG } /resources/' ,
105
- params = {'language_code' : LANGUAGE , 'offset' : offset },
106
- auth = ('api' , transifex_api_key ),
126
+ 'https://rest.api.transifex.com/resource_language_stats' ,
127
+ params = {
128
+ 'filter[project]' : f'o:python-doc:p:{ PROJECT_SLUG } ' , 'filter[language]' : f'l:{ LANGUAGE } '
129
+ } | ({'page[cursor]' : cursor } if cursor else {}),
130
+ headers = {'Authorization' : f'Bearer { transifex_api_key } ' }
107
131
)
108
132
response .raise_for_status ()
109
- response_list = response .json ()
133
+ response_json = response .json ()
134
+ response_list = response_json ['data' ]
110
135
resources .extend (response_list )
111
- if len ( response_list ) < 100 :
136
+ if 'next' not in response_json [ 'links' ] :
112
137
break
113
- offset += len ( response_list )
114
- return resources
138
+ cursor = unquote ( search ( 'page\[cursor]=([^&]*)' , response_json [ 'links' ][ 'next' ]). group ( 1 ) )
139
+ return [ ResourceLanguageStatistics . from_api_v3_entry ( entry ) for entry in resources ]
115
140
116
141
117
142
def _get_number_of_translators ():
@@ -128,18 +153,18 @@ def _get_number_of_translators():
128
153
def recreate_readme ():
129
154
def language_switcher (entry ):
130
155
return (
131
- entry [ ' name' ] .startswith ('bugs' )
132
- or entry [ ' name' ] .startswith ('tutorial' )
133
- or entry [ ' name' ] .startswith ('library--functions' )
156
+ entry . name .startswith ('bugs' )
157
+ or entry . name .startswith ('tutorial' )
158
+ or entry . name .startswith ('library--functions' )
134
159
)
135
160
136
161
def average (averages , weights ):
137
162
return sum ([a * w for a , w in zip (averages , weights )]) / sum (weights )
138
163
139
164
resources = _get_resources ()
140
165
filtered = list (filter (language_switcher , resources ))
141
- average_list = [e [ 'stats' ][ 'translated' ][ 'percentage' ] for e in filtered ]
142
- weights_list = [e [ 'wordcount' ] for e in filtered ]
166
+ average_list = [e . translated_words / e . total_words for e in filtered ]
167
+ weights_list = [e . total_words for e in filtered ]
143
168
144
169
language_switcher_status = average (average_list , weights = weights_list ) * 100
145
170
number_of_translators = _get_number_of_translators ()
0 commit comments