cocoapods-aqara-localzedLoader 0.1.4 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 795d106ed32e894b1e09d27b5ea84afda20ba23d4e8e11f8ae0fe6a6fe1ec1e5
|
|
4
|
+
data.tar.gz: 3da5d0f1c604a3c805dbcc3fbdb9ef127199778c9e74899407d785dd958b366e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 312c90c5f9bfa427d653eba01c8345f05457b16ab2527987991cf19427b5f0deacaf88a08a37c7485a270eaed2ccbeeab96fa6ce28821f1a5816bd8e6bfd123b
|
|
7
|
+
data.tar.gz: 6331e59b66c6f13d7a35eb0a55a2087cf608be23a609422dd2d1b85318d9ed4d49581a8448699568777d6493f6a5750e873fc7ecfa414b4ad49db86ad1806e2e
|
|
@@ -2,9 +2,10 @@ import shutil
|
|
|
2
2
|
import os, sys, stat
|
|
3
3
|
import time
|
|
4
4
|
import requests
|
|
5
|
-
|
|
5
|
+
from typing import Optional
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
|
|
8
|
+
######### 火山多语言 #############
|
|
8
9
|
|
|
9
10
|
from volcengine.iam.IamService import IamService
|
|
10
11
|
|
|
@@ -138,23 +139,182 @@ def DownLatestLocalizableSource(downloadPath):
|
|
|
138
139
|
print('下载 excel 成功:', out_file)
|
|
139
140
|
|
|
140
141
|
|
|
141
|
-
|
|
142
|
-
# def Unzip():
|
|
143
|
-
# f = zipfile.ZipFile("./localizable.zip", 'r') # 压缩文件位置
|
|
144
|
-
# for file in f.namelist():
|
|
145
|
-
# f.extract(file, "../") # 解压位置
|
|
146
|
-
# f.close()
|
|
147
|
-
# os.remove('./localizable.zip')
|
|
148
|
-
|
|
149
142
|
def UpdateSource_language():
|
|
150
143
|
DownLatestLocalizableSource()
|
|
151
144
|
return './download.xlsx'
|
|
152
145
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
146
|
+
|
|
147
|
+
#######################################
|
|
148
|
+
|
|
149
|
+
##### Crowdin #########
|
|
150
|
+
|
|
151
|
+
class CrowdinPlatform():
|
|
152
|
+
"""Crowdin 翻译平台"""
|
|
153
|
+
|
|
154
|
+
def __init__(self, access_token: str, project_id: str, base_url: str = "https://aqara.crowdin.com/api/v2"):
|
|
155
|
+
"""初始化 Crowdin 平台
|
|
156
|
+
|
|
157
|
+
Args:
|
|
158
|
+
access_token: 访问令牌
|
|
159
|
+
project_id: 项目 ID
|
|
160
|
+
base_url: API 基础 URL
|
|
161
|
+
"""
|
|
162
|
+
self.access_token = access_token
|
|
163
|
+
self.project_id = project_id
|
|
164
|
+
self.base_url = base_url
|
|
165
|
+
|
|
166
|
+
def _get_headers(self) -> dict:
|
|
167
|
+
"""获取 API 请求头"""
|
|
168
|
+
return {
|
|
169
|
+
"Authorization": f"Bearer {self.access_token}",
|
|
170
|
+
"Content-Type": "application/json"
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
def _get_project_files(self) -> dict:
|
|
174
|
+
"""获取项目文件列表
|
|
175
|
+
|
|
176
|
+
Returns:
|
|
177
|
+
dict: API 返回的文件列表数据
|
|
178
|
+
"""
|
|
179
|
+
url = f"{self.base_url}/projects/{self.project_id}/files"
|
|
180
|
+
headers = self._get_headers()
|
|
181
|
+
params = {"limit": 500}
|
|
182
|
+
print(f"Request: GET {url} with params {params}")
|
|
183
|
+
response = requests.get(url, headers=headers, params=params)
|
|
184
|
+
#print(f"Response: {response.status_code}")
|
|
185
|
+
# print(f"Response Body: {response.text}")
|
|
186
|
+
if response.status_code != 200:
|
|
187
|
+
raise Exception(f"获取项目文件列表失败: {response.status_code}, {response.text}")
|
|
188
|
+
return response.json()
|
|
189
|
+
|
|
190
|
+
def _find_file_id_by_name(self, files_data: dict, file_name: str) -> Optional[int]:
|
|
191
|
+
"""从文件列表中查找指定文件名的 fileId
|
|
192
|
+
|
|
193
|
+
Args:
|
|
194
|
+
files_data: get_project_files 返回的数据
|
|
195
|
+
file_name: 要查找的文件名
|
|
196
|
+
|
|
197
|
+
Returns:
|
|
198
|
+
int: 文件的 ID,如果未找到则返回 None
|
|
199
|
+
"""
|
|
200
|
+
if "data" not in files_data:
|
|
201
|
+
raise Exception("文件列表数据格式错误: 缺少 'data' 字段")
|
|
202
|
+
for file_item in files_data["data"]:
|
|
203
|
+
if "data" in file_item and file_item["data"]["name"] == file_name:
|
|
204
|
+
return file_item["data"]["id"]
|
|
205
|
+
return None
|
|
206
|
+
|
|
207
|
+
def _get_file_download_url(self, file_id: int) -> str:
|
|
208
|
+
"""获取文件下载 URL
|
|
209
|
+
|
|
210
|
+
Args:
|
|
211
|
+
file_id: 文件 ID
|
|
212
|
+
|
|
213
|
+
Returns:
|
|
214
|
+
str: 下载 URL
|
|
215
|
+
"""
|
|
216
|
+
url = f"{self.base_url}/projects/{self.project_id}/files/{file_id}/download"
|
|
217
|
+
headers = self._get_headers()
|
|
218
|
+
print(f"Request: GET {url}")
|
|
219
|
+
response = requests.get(url, headers=headers)
|
|
220
|
+
#print(f"Response: {response.status_code}")
|
|
221
|
+
# print(f"Response Body: {response.text}")
|
|
222
|
+
if response.status_code != 200:
|
|
223
|
+
raise Exception(f"获取文件下载 URL 失败: {response.status_code}, {response.text}")
|
|
224
|
+
data = response.json()
|
|
225
|
+
if "data" not in data or "url" not in data["data"]:
|
|
226
|
+
raise Exception(f"下载 URL 数据格式错误: {data}")
|
|
227
|
+
return data["data"]["url"]
|
|
228
|
+
|
|
229
|
+
def _download_file_from_url(self, download_url: str, save_path: str, max_retries: int = 3) -> None:
|
|
230
|
+
"""从 URL 下载文件
|
|
231
|
+
|
|
232
|
+
Args:
|
|
233
|
+
download_url: 文件下载 URL
|
|
234
|
+
save_path: 保存路径
|
|
235
|
+
max_retries: 最大重试次数
|
|
236
|
+
"""
|
|
237
|
+
for attempt in range(max_retries):
|
|
238
|
+
try:
|
|
239
|
+
# print(f"Request: GET {download_url} (Attempt {attempt + 1}/{max_retries})")
|
|
240
|
+
response = requests.get(download_url, stream=True, timeout=60)
|
|
241
|
+
#print(f"Response: {response.status_code}")
|
|
242
|
+
if response.status_code != 200:
|
|
243
|
+
raise Exception(f"下载文件失败: {response.status_code}, {response.text}")
|
|
244
|
+
|
|
245
|
+
os.makedirs(os.path.dirname(save_path) if os.path.dirname(save_path) else ".", exist_ok=True)
|
|
246
|
+
with open(save_path, "wb") as f:
|
|
247
|
+
for chunk in response.iter_content(chunk_size=8192):
|
|
248
|
+
if chunk:
|
|
249
|
+
f.write(chunk)
|
|
250
|
+
#print(f"文件下载成功: {save_path}")
|
|
251
|
+
return
|
|
252
|
+
except (requests.exceptions.ChunkedEncodingError, requests.exceptions.RequestException, Exception) as e:
|
|
253
|
+
print(f"下载失败 (Attempt {attempt + 1}/{max_retries}): {e}")
|
|
254
|
+
if attempt < max_retries - 1:
|
|
255
|
+
wait_time = (attempt + 1) * 2
|
|
256
|
+
print(f"等待 {wait_time} 秒后重试...")
|
|
257
|
+
time.sleep(wait_time)
|
|
258
|
+
else:
|
|
259
|
+
raise Exception(f"文件下载最终失败,已重试 {max_retries} 次: {e}")
|
|
260
|
+
|
|
261
|
+
def download_file(self, target_file_name: str, output_path: str, **kwargs) -> None:
|
|
262
|
+
"""从 Crowdin 下载指定文件
|
|
263
|
+
|
|
264
|
+
Args:
|
|
265
|
+
target_file_name: 目标文件名
|
|
266
|
+
output_path: 输出文件路径
|
|
267
|
+
**kwargs: 其他参数(未使用)
|
|
268
|
+
"""
|
|
269
|
+
print(f"开始从 Crowdin 下载文件: {target_file_name}")
|
|
270
|
+
# 1. 获取项目文件列表
|
|
271
|
+
print("正在获取项目文件列表...")
|
|
272
|
+
files_data = self._get_project_files()
|
|
273
|
+
# 2. 查找目标文件的 fileId
|
|
274
|
+
print(f"正在查找文件: {target_file_name}")
|
|
275
|
+
file_id = self._find_file_id_by_name(files_data, target_file_name)
|
|
276
|
+
if file_id is None:
|
|
277
|
+
raise Exception(f"未找到文件: {target_file_name}")
|
|
278
|
+
print(f"找到文件 ID: {file_id}")
|
|
279
|
+
# 3. 获取下载 URL
|
|
280
|
+
print("正在获取下载 URL...")
|
|
281
|
+
download_url = self._get_file_download_url(file_id)
|
|
282
|
+
print("下载 URL 获取成功")
|
|
283
|
+
# 4. 下载文件
|
|
284
|
+
print("正在下载文件...")
|
|
285
|
+
self._download_file_from_url(download_url, output_path)
|
|
286
|
+
print("文件下载完成")
|
|
287
|
+
|
|
288
|
+
def update_source_language(self, target_file_name: str, output_path: str, **kwargs) -> None:
|
|
289
|
+
"""从 Crowdin 更新源语言文件
|
|
290
|
+
|
|
291
|
+
Args:
|
|
292
|
+
target_file_name: 目标文件名
|
|
293
|
+
output_path: 输出文件路径(最终保存位置)
|
|
294
|
+
**kwargs: 其他参数(未使用)
|
|
295
|
+
"""
|
|
296
|
+
temp_file = "./APP.xlsx"
|
|
297
|
+
self.download_file(target_file_name, temp_file, **kwargs)
|
|
298
|
+
os.makedirs(os.path.dirname(output_path), exist_ok=True)
|
|
299
|
+
shutil.copy(temp_file, output_path)
|
|
300
|
+
os.remove(temp_file)
|
|
301
|
+
print(f"源语言文件已更新: {output_path}")
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
# 默认配置(需要设置)
|
|
305
|
+
DEFAULT_ACCESS_TOKEN = "db0506fb755d528c7b9b750e15174d3cfa483859488da978748ad6b9e34d13dc94d8716810a2f978" # 需要设置
|
|
306
|
+
DEFAULT_PROJECT_ID = "71" # 需要设置
|
|
307
|
+
DEFAULT_TARGET_FILE_NAME = "APP.xlsx"
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
############################
|
|
157
311
|
|
|
158
312
|
if __name__ == '__main__':
|
|
159
313
|
localizable_path = sys.argv[1]
|
|
160
|
-
|
|
314
|
+
crowdin = sys.argv[2]
|
|
315
|
+
if crowdin:
|
|
316
|
+
platform = CrowdinPlatform(DEFAULT_ACCESS_TOKEN, DEFAULT_PROJECT_ID)
|
|
317
|
+
target_path = f"{localizable_path}/APP/APP.xlsx"
|
|
318
|
+
platform.update_source_language(DEFAULT_TARGET_FILE_NAME, target_path)
|
|
319
|
+
else:
|
|
320
|
+
DownLatestLocalizableSource(localizable_path)
|
|
@@ -23,6 +23,7 @@ class File_util
|
|
|
23
23
|
zh_cn_col = first_row.cells.index { |c| c && c.value == 'zh-CN' }
|
|
24
24
|
|
|
25
25
|
if zh_cn_col
|
|
26
|
+
puts "正在删除zh-CN列的译文...".red
|
|
26
27
|
worksheet.each do |row|
|
|
27
28
|
row&.cells&.delete_at(zh_cn_col)
|
|
28
29
|
end
|
|
@@ -31,6 +32,7 @@ class File_util
|
|
|
31
32
|
last_col_index = worksheet[0].cells.size # 当前最后一列索引+1
|
|
32
33
|
|
|
33
34
|
# 遍历 B 列(索引 1)所有行
|
|
35
|
+
puts "正在将Source列的文案复制到zh-CN列,请稍等...".yellow
|
|
34
36
|
worksheet.each_with_index do |row, row_index|
|
|
35
37
|
b_value = row && row[1] ? row[1].value : nil
|
|
36
38
|
worksheet.add_cell(row_index, last_col_index, b_value)
|
|
@@ -38,6 +40,7 @@ class File_util
|
|
|
38
40
|
|
|
39
41
|
worksheet[0].cells[last_col_index] = worksheet.add_cell(0, last_col_index, 'zh-CN')
|
|
40
42
|
workbook.write(filename)
|
|
43
|
+
puts "已成功将Source文案作为zh-CN语言的译文".green
|
|
41
44
|
end
|
|
42
45
|
|
|
43
46
|
row1 = worksheet[0]
|
|
@@ -49,7 +52,7 @@ class File_util
|
|
|
49
52
|
self_key = ''
|
|
50
53
|
# 设置StringElement的值
|
|
51
54
|
row.cells.each_with_index do |cell, i|
|
|
52
|
-
next unless cell
|
|
55
|
+
next unless cell&.value
|
|
53
56
|
case i
|
|
54
57
|
when 0
|
|
55
58
|
self_key = cell.value
|
|
@@ -63,11 +63,7 @@ class BundleGenerater
|
|
|
63
63
|
sleep sleep_time
|
|
64
64
|
end
|
|
65
65
|
puts "当前进行第#{@@download_Count}次尝试下载多语言文件"
|
|
66
|
-
|
|
67
|
-
system "crowdin download sources"
|
|
68
|
-
else
|
|
69
|
-
system "cd #{File.dirname(__FILE__)};python3 DownloadNewLanguage.py #{project_path}"
|
|
70
|
-
end
|
|
66
|
+
system "cd #{File.dirname(__FILE__)};python3 DownloadNewLanguage.py #{project_path} #{crowdin}"
|
|
71
67
|
@@download_Count = @@download_Count + 1
|
|
72
68
|
end
|
|
73
69
|
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: cocoapods-aqara-localzedLoader
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.6
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- zhaoxifan
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2025-12-
|
|
11
|
+
date: 2025-12-30 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|