Main migration entry point.
(self)
| 253 | print(f" {subcat:<30} {count:3d} posts") |
| 254 | |
| 255 | def migrate(self) -> None: |
| 256 | """Main migration entry point.""" |
| 257 | mode = "[DRY RUN] " if self.dry_run else "" |
| 258 | print(f"\n{mode}Migrating WordPress posts to insights/") |
| 259 | print(f"Output directory: {self.output_dir}\n") |
| 260 | |
| 261 | posts = self.get_all_posts() |
| 262 | print(f"\nTotal posts to process: {len(posts)}") |
| 263 | |
| 264 | path_entries: Dict[str, List[dict]] = {} |
| 265 | |
| 266 | for i, post in enumerate(posts, 1): |
| 267 | self.stats["total"] += 1 |
| 268 | title = self.clean_title(post.get("title", {}).get("rendered", "")) |
| 269 | date = post.get("date", "")[:10] |
| 270 | print(f"[{i:3d}/{len(posts)}] [{date}] {title[:60]}") |
| 271 | |
| 272 | # Resolve category slugs (with delay to avoid rate limiting) |
| 273 | cat_ids = post.get("categories", []) |
| 274 | for cat_id in cat_ids: |
| 275 | self.get_category_slug(cat_id) |
| 276 | if cat_ids: |
| 277 | time.sleep(self.delay) |
| 278 | |
| 279 | try: |
| 280 | zh_file, fm = self.save_post(post) |
| 281 | if fm is None: |
| 282 | self.stats["skipped"] += 1 |
| 283 | print(f" SKIP (empty content)") |
| 284 | continue |
| 285 | |
| 286 | output_path = fm["category"] |
| 287 | if output_path not in path_entries: |
| 288 | path_entries[output_path] = [] |
| 289 | path_entries[output_path].append({ |
| 290 | "id": fm["id"], |
| 291 | "title": fm["title"], |
| 292 | "published_date": fm["published_date"], |
| 293 | "subcategory": fm["subcategory"], |
| 294 | "source_url": fm["source_url"], |
| 295 | "excerpt": fm.get("excerpt", {}), |
| 296 | }) |
| 297 | |
| 298 | self.stats["success"] += 1 |
| 299 | if self.dry_run: |
| 300 | print(f" -> [DRY] {output_path}/{post.get('slug', '')}.zh.md") |
| 301 | else: |
| 302 | print(f" -> {zh_file.relative_to(self.output_dir)}") |
| 303 | except Exception as e: |
| 304 | self.stats["error"] += 1 |
| 305 | print(f" ERROR: {e}") |
| 306 | |
| 307 | time.sleep(self.delay) |
| 308 | |
| 309 | if not self.dry_run: |
| 310 | print("\nUpdating _index.json files...") |
| 311 | for path, entries in path_entries.items(): |
| 312 | self.update_index(path, entries) |
no test coverage detected