FazBrowse GitHub Viewer
|
Trending
|
URL:
|
Home
Tools:
[Download Repo ZIP]
[View Raw Code]
[Original HTTPS Page]
python-docs-de/tools/tx_push.py at 3.14 · python/python-docs-de · GitHub
python
python-docs-de
Repository navigation
Code
Issues
Pull requests
2
(2)
Actions
Security and quality
Insights
Expand file tree
Breadcrumbs
python-docs-de
/
tools
/
tx_push.py
Copy path
More file actions
More file actions
Latest commit
History
History
History
194 lines (159 loc) · 6.69 KB
Breadcrumbs
python-docs-de
/
tools
/
tx_push.py
Copy path
File metadata and controls
194 lines (159 loc) · 6.69 KB
Raw
Copy raw file
Download raw file
Open symbols panel
Edit and raw actions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
#!/usr/bin/env python3
"""Interaktiver Transifex-Push: fragt, welche Dateien hochgeladen werden.
Das Skript liest .tx/config des aktuellen Branches, ordnet jeder .po-Datei
ihren Transifex-Resource-Namen zu und stellt sie zur Auswahl. Gepusht wird
mit der forcierten Kombination, die wir beim Abgleich benutzen:
tx push -t -l de -f --skip --replace-edited-strings <resource> ...
-t nur Uebersetzungen (die Quelltexte kommen
aus CPython, nicht von uns)
-l de nur die deutsche Sprache
-f Zeitstempel-Sperre aus ("remote is newer")
--replace-edited-strings ueberschreibt auch in Transifex bearbeitete
Strings -- GitHub ist die Quelle der Wahrheit
--skip bricht nicht ab, wenn eine Ressource zickt
Aufruf:
python tools/tx_push.py # geaenderte Dateien vorschlagen
python tools/tx_push.py --alle # alle Dateien aus .tx/config
python tools/tx_push.py howto # nach Pfad filtern
python tools/tx_push.py library/csv.po
python tools/tx_push.py --dry-run howto # nur zeigen, nicht pushen
"""
import
argparse
import
configparser
import
re
import
subprocess
import
sys
from
pathlib
import
Path
try
:
import
polib
except
ImportError
:
polib
=
None
# Fortschrittsanzeige ist dann eben leer
def
git
(
*
args
:
str
)
->
str
:
e
=
subprocess
.
run
([
"git"
,
*
args
],
capture_output
=
True
,
text
=
True
)
return
e
.
stdout
if
e
.
returncode
==
0
else
""
def
repo_wurzel
()
->
Path
:
aus
=
git
(
"rev-parse"
,
"--show-toplevel"
).
strip
()
if
not
aus
:
sys
.
exit
(
"Kein Git-Repository -- bitte im python-docs-de-Verzeichnis starten."
)
return
Path
(
aus
)
def
ressourcen
(
wurzel
:
Path
)
->
dict
:
"""{po-Pfad: (projekt, resource)} aus .tx/config."""
pfad
=
wurzel
/
".tx"
/
"config"
if
not
pfad
.
is_file
():
sys
.
exit
(
f"
{
pfad
}
nicht gefunden."
)
cfg
=
configparser
.
ConfigParser
()
cfg
.
read
(
pfad
,
encoding
=
"utf-8"
)
aus
=
{}
for
name
in
cfg
.
sections
():
# [o:python-doc:p:python-314:r:howto--index]
m
=
re
.
match
(
r"o:([^:]+):p:([^:]+):r:(.+)"
,
name
)
if
not
m
:
continue
_org
,
projekt
,
resource
=
m
.
groups
()
abschnitt
=
cfg
[
name
]
datei
=
abschnitt
.
get
(
"trans.de"
)
or
abschnitt
.
get
(
"file_filter"
,
""
)
datei
=
datei
.
replace
(
"<lang>"
,
"de"
).
strip
()
if
datei
:
aus
[
datei
]
=
(
projekt
,
resource
)
if
not
aus
:
sys
.
exit
(
"In .tx/config wurden keine Ressourcen gefunden."
)
return
aus
def
geaenderte_dateien
(
wurzel
:
Path
)
->
set
:
""".po-Dateien, die sich gegenueber origin/<branch> oder im Baum geaendert haben."""
branch
=
git
(
"branch"
,
"--show-current"
).
strip
()
kandidaten
=
set
()
for
befehl
in
(
[
"diff"
,
"--name-only"
],
# unversionierte Aenderungen
[
"diff"
,
"--name-only"
,
"--cached"
],
# gestaged
[
"diff"
,
"--name-only"
,
f"origin/
{
branch
}
...HEAD"
],
# noch nicht gepusht
):
for
zeile
in
git
(
*
befehl
).
splitlines
():
if
zeile
.
endswith
(
".po"
):
kandidaten
.
add
(
zeile
)
return
kandidaten
def
stand
(
wurzel
:
Path
,
datei
:
str
)
->
str
:
"""'123/456 (27 %)' -- oder leer, wenn polib fehlt."""
if
polib
is
None
:
return
""
p
=
wurzel
/
datei
if
not
p
.
is_file
():
return
"fehlt lokal"
try
:
po
=
polib
.
pofile
(
str
(
p
))
except
Exception
:
return
"nicht lesbar"
gesamt
=
len
([
e
for
e
in
po
if
not
e
.
obsolete
])
fertig
=
len
([
e
for
e
in
po
if
not
e
.
obsolete
and
e
.
translated
()])
prozent
=
100
*
fertig
//
gesamt
if
gesamt
else
0
return
f"
{
fertig
}
/
{
gesamt
}
(
{
prozent
}
%)"
def
auswahl_lesen
(
anzahl
:
int
)
->
list
:
"""'1,3-5' oder 'a' einlesen und in Indizes uebersetzen."""
while
True
:
roh
=
input
(
"
\n
Nummern (z. B. 1,3-5), a = alle, q = Abbruch: "
).
strip
().
lower
()
if
roh
in
(
"q"
,
""
):
sys
.
exit
(
"Abgebrochen."
)
if
roh
==
"a"
:
return
list
(
range
(
anzahl
))
indizes
=
set
()
try
:
for
teil
in
roh
.
replace
(
" "
,
""
).
split
(
","
):
if
"-"
in
teil
:
von
,
bis
=
teil
.
split
(
"-"
,
1
)
indizes
.
update
(
range
(
int
(
von
)
-
1
,
int
(
bis
)))
else
:
indizes
.
add
(
int
(
teil
)
-
1
)
except
ValueError
:
print
(
"Das habe ich nicht verstanden."
)
continue
if
any
(
i
<
0
or
i
>=
anzahl
for
i
in
indizes
):
print
(
f"Nur 1 bis
{
anzahl
}
sind gueltig."
)
continue
return
sorted
(
indizes
)
def
main
()
->
None
:
p
=
argparse
.
ArgumentParser
(
description
=
__doc__
,
formatter_class
=
argparse
.
RawDescriptionHelpFormatter
)
p
.
add_argument
(
"muster"
,
nargs
=
"*"
,
help
=
"Pfadteile zum Filtern, z. B. howto"
)
p
.
add_argument
(
"--alle"
,
action
=
"store_true"
,
help
=
"alle Dateien aus .tx/config zur Auswahl stellen"
)
p
.
add_argument
(
"--dry-run"
,
action
=
"store_true"
,
help
=
"Befehl nur anzeigen, nicht ausfuehren"
)
args
=
p
.
parse_args
()
wurzel
=
repo_wurzel
()
branch
=
git
(
"branch"
,
"--show-current"
).
strip
()
karte
=
ressourcen
(
wurzel
)
projekt
=
next
(
iter
(
karte
.
values
()))[
0
]
dateien
=
sorted
(
karte
)
herkunft
=
"alle Ressourcen aus .tx/config"
if
args
.
muster
:
dateien
=
[
d
for
d
in
dateien
if
any
(
m
in
d
for
m
in
args
.
muster
)]
herkunft
=
"Treffer fuer "
+
", "
.
join
(
args
.
muster
)
elif
not
args
.
alle
:
geaendert
=
geaenderte_dateien
(
wurzel
)
&
set
(
karte
)
if
geaendert
:
dateien
=
sorted
(
geaendert
)
herkunft
=
"geaenderte Dateien"
else
:
print
(
"Keine geaenderten .po-Dateien gefunden -- zeige alle.
\n
"
)
if
not
dateien
:
sys
.
exit
(
"Keine passende Datei gefunden."
)
print
(
f"Branch
{
branch
}
-> Transifex-Projekt
{
projekt
}
(
{
herkunft
}
)
\n
"
)
breite
=
max
(
len
(
d
)
for
d
in
dateien
)
for
i
,
d
in
enumerate
(
dateien
,
1
):
print
(
f"
{
i
:>3
}
{
d
:<{
breite
}
}
{
karte
[
d
][
1
]:<28
}
{
stand
(
wurzel
,
d
)
}
"
)
gewaehlt
=
[
dateien
[
i
]
for
i
in
auswahl_lesen
(
len
(
dateien
))]
ziele
=
[
f"
{
karte
[
d
][
0
]
}
.
{
karte
[
d
][
1
]
}
"
for
d
in
gewaehlt
]
befehl
=
[
"tx"
,
"push"
,
"-t"
,
"-l"
,
"de"
,
"-f"
,
"--skip"
,
"--replace-edited-strings"
,
*
ziele
]
print
(
"
\n
Befehl:
\n
"
+
" "
.
join
(
befehl
)
+
"
\n
"
)
for
d
in
gewaehlt
:
print
(
f"
{
d
}
->
{
karte
[
d
][
1
]
}
"
)
if
args
.
dry_run
:
print
(
"
\n
--dry-run: nichts gepusht."
)
return
if
input
(
"
\n
Jetzt pushen? [j/N] "
).
strip
().
lower
()
not
in
(
"j"
,
"ja"
):
sys
.
exit
(
"Abgebrochen."
)
print
()
sys
.
exit
(
subprocess
.
run
(
befehl
,
cwd
=
wurzel
).
returncode
)
if
__name__
==
"__main__"
:
main
()
Back
|
FazBrowse Home
|
New Git URL