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