cocoapods-aqara-localzedLoader 0.1.7 → 0.1.8

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: 1425f2176025a5e31074240b6e1566174a504c1b350b1bd05b02fbd8adb61891
4
- data.tar.gz: 6485256251c05bc2dc22efcdbe8c9a3eadd9a2fe792ea4bfc0c77e8367b18c0e
3
+ metadata.gz: b7fdeaa4c9af99d6d9d4530f324362ab1c5e467f49390465282cd9df5147e74f
4
+ data.tar.gz: 50c4a8eb1f2c97d91ecff0973a607c2d787eaa3f355fbd80408d0b96b4b97ca9
5
5
  SHA512:
6
- metadata.gz: d95812a3ffc7300fb79f55c5e78d48f73f73bf984a9ecd512207258e559be926f5ea99e7d663a0542d7033e1f7852819f5ae197b73690c8fd63201573bec4cd3
7
- data.tar.gz: 2b1a320136a23036c4caf748f4c7f2776e50c45eb3ec1d2462d0b9ab7e9758e487c28852c8a2cf4b4cfff5ab090ca39c22766708537384b0e0f0ba2b782fb881
6
+ metadata.gz: 9e39d70e6c65937d9c2a7537cb33764481b3c0ed29dbf83c7092720d233100865ac20b1053dcb374f5ae12629db29b191b6ca4aa0367a952d06a410b516b5e65
7
+ data.tar.gz: d8717544101f5bdf4955ae4512a7019dc4e6f6233eb7c5b295b93ed8fde7bee36c4fa0e64653d284874282c31177cd6d4f39fda068a48583a80211c33dc2e96f
@@ -2,6 +2,7 @@ import shutil
2
2
  import os, sys, stat
3
3
  import time
4
4
  import requests
5
+ import zipfile
5
6
  from typing import Optional
6
7
 
7
8
 
@@ -170,136 +171,85 @@ class CrowdinPlatform():
170
171
  "Content-Type": "application/json"
171
172
  }
172
173
 
173
- def _get_project_files(self) -> dict:
174
- """获取项目文件列表
174
+ def _get_directories(self) -> dict:
175
+ url = f"{self.base_url}/projects/{self.project_id}/directories"
176
+ resp = requests.get(url, headers=self._get_headers(), params={"limit": 500})
177
+ resp.raise_for_status()
178
+ return resp.json()
175
179
 
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
180
+ def _find_directory_id_by_path(self, directory_path: str) -> int:
181
+ dirs = self._get_directories()
182
+ for item in dirs["data"]:
183
+ data = item["data"]
184
+ if data.get("path") == directory_path:
185
+ return data["id"]
186
+ raise Exception(f"未找到目录: {directory_path}")
192
187
 
193
- Args:
194
- files_data: get_project_files 返回的数据
195
- file_name: 要查找的文件名
188
+ def build_directory_all_languages(self, directory_path: str) -> int:
196
189
 
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
190
+ print("开始获取 /APP 目录的directory_id...")
191
+ directory_id = self._find_directory_id_by_path(directory_path)
192
+ print(f"开始构建directory_id:{directory_id}的翻译文件")
193
+ url = f"{self.base_url}/projects/{self.project_id}/translations/builds/directories/{directory_id}"
206
194
 
207
- def _get_file_download_url(self, file_id: int) -> str:
208
- """获取文件下载 URL
209
195
 
210
- Args:
211
- file_id: 文件 ID
196
+ resp = requests.post(url, headers=self._get_headers())
197
+ resp.raise_for_status()
212
198
 
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 下载文件
199
+ build_id = resp.json()["data"]["id"]
200
+ return build_id
231
201
 
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
202
 
203
+ def wait_for_build(self, build_id: int, timeout: int = 120) -> None:
204
+ """等待构建完成"""
205
+ url = f"{self.base_url}/projects/{self.project_id}/translations/builds/{build_id}"
206
+ headers = self._get_headers()
207
+ start_time = time.time()
208
+ print("等待构建完成...")
209
+ while True:
210
+ resp = requests.get(url, headers=headers)
211
+ resp.raise_for_status()
212
+ status = resp.json()["data"]["status"]
213
+ print(f"当前构建状态: {status}")
214
+ if status == "finished":
215
+ print("构建完成")
216
+ return
217
+ elif status == "failed":
218
+ raise Exception("Crowdin 构建失败")
219
+ elif time.time() - start_time > timeout:
220
+ raise TimeoutError("等待 Crowdin 构建超时")
221
+ time.sleep(3)
222
+
223
+ def download_translations_zip(self, output_zip_path: str) -> None:
224
+ """下载整个项目的多语言文件 ZIP"""
225
+ build_id = self.build_directory_all_languages("/APP")
226
+ self.wait_for_build(build_id)
227
+ url = f"{self.base_url}/projects/{self.project_id}/translations/builds/{build_id}/download"
228
+ headers = self._get_headers()
229
+ resp = requests.get(url, headers=headers)
230
+ resp.raise_for_status()
231
+ download_url = resp.json()["data"]["url"]
232
+
233
+ # 下载 ZIP 文件
234
+ print(f"正在下载 ZIP 文件到 {output_zip_path} ...")
235
+ r = requests.get(download_url, stream=True)
236
+ r.raise_for_status()
237
+ os.makedirs(os.path.dirname(output_zip_path) or ".", exist_ok=True)
238
+ with open(output_zip_path, "wb") as f:
239
+ for chunk in r.iter_content(chunk_size=8192):
240
+ if chunk:
241
+ f.write(chunk)
242
+ print(f"多语言 ZIP 下载完成: {output_zip_path}")
243
+
244
+ def download_and_extract_translations(self, output_dir: str) -> None:
245
+ """下载并解压整个多语言文件"""
246
+ zip_path = "./crowdin_translations.zip"
247
+ self.download_translations_zip(zip_path)
248
+ print(f"正在解压 {zip_path} 到 {output_dir}")
249
+ with zipfile.ZipFile(zip_path, "r") as zip_ref:
250
+ zip_ref.extractall(output_dir)
251
+ os.remove(zip_path)
252
+ print(f"多语言文件已解压到: {output_dir}APP.xlsx")
303
253
 
304
254
  # 默认配置(需要设置)
305
255
  DEFAULT_ACCESS_TOKEN = "db0506fb755d528c7b9b750e15174d3cfa483859488da978748ad6b9e34d13dc94d8716810a2f978" # 需要设置
@@ -320,7 +270,7 @@ if __name__ == '__main__':
320
270
 
321
271
  if crowdin:
322
272
  platform = CrowdinPlatform(DEFAULT_ACCESS_TOKEN, DEFAULT_PROJECT_ID)
323
- target_path = f"{localizable_path}/APP/APP.xlsx"
324
- platform.update_source_language(DEFAULT_TARGET_FILE_NAME, target_path)
273
+ target_path = f"{localizable_path}/APP/"
274
+ platform.download_and_extract_translations(target_path)
325
275
  else:
326
276
  DownLatestLocalizableSource(localizable_path)
@@ -1,3 +1,3 @@
1
1
  module Localzedloader
2
- VERSION = "0.1.7"
2
+ VERSION = "0.1.8"
3
3
  end
metadata CHANGED
@@ -1,11 +1,11 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cocoapods-aqara-localzedLoader
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.7
4
+ version: 0.1.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - zhaoxifan
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
  date: 2025-12-31 00:00:00.000000000 Z
@@ -202,7 +202,7 @@ homepage: https://github.com/LuckZXF/cocoapods-aqara-localzedLoader
202
202
  licenses:
203
203
  - MIT
204
204
  metadata: {}
205
- post_install_message:
205
+ post_install_message:
206
206
  rdoc_options: []
207
207
  require_paths:
208
208
  - lib
@@ -217,8 +217,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
217
217
  - !ruby/object:Gem::Version
218
218
  version: '0'
219
219
  requirements: []
220
- rubygems_version: 3.0.3.1
221
- signing_key:
220
+ rubygems_version: 3.2.22
221
+ signing_key:
222
222
  specification_version: 4
223
223
  summary: Aqara 多语言从云端多语言平台下载并处理解析成Xcode需要的多语言文件
224
224
  test_files: