v0.1.0 - initial release #1

Merged
peisongxiao merged 12 commits from v0.1.0 into master 2026-02-08 23:38:12 +00:00
2 changed files with 38 additions and 8 deletions
Showing only changes of commit 7953bd07f7 - Show all commits

View File

@@ -18,6 +18,7 @@ def apply_changes(
) -> None: ) -> None:
categories = wp.list_categories() categories = wp.list_categories()
category_map = _build_category_map(categories) category_map = _build_category_map(categories)
wp_timezone = wp.get_timezone()
_create_missing_categories(result, wp, category_map) _create_missing_categories(result, wp, category_map)
_create_missing_tags(result, wp) _create_missing_tags(result, wp)
@@ -27,7 +28,7 @@ def apply_changes(
for post in result.posts: for post in result.posts:
if not post.should_update: if not post.should_update:
continue continue
_apply_post(post, wp, category_map) _apply_post(post, wp, category_map, wp_timezone)
state.posts[post.identity] = PostState( state.posts[post.identity] = PostState(
source_timestamp=post.source_timestamp, source_timestamp=post.source_timestamp,
materialized_at=int(time.time()), materialized_at=int(time.time()),
@@ -74,7 +75,12 @@ def _create_missing_tags(result: EvaluationResult, wp: WordPressCLI) -> None:
wp.create_tag(tag) wp.create_tag(tag)
def _apply_post(post: PostPlan, wp: WordPressCLI, category_map: Dict[tuple[int, str], int]) -> None: def _apply_post(
post: PostPlan,
wp: WordPressCLI,
category_map: Dict[tuple[int, str], int],
wp_timezone,
) -> None:
category_ids: List[int] = [] category_ids: List[int] = []
for path in post.categories: for path in post.categories:
segments = [segment for segment in path.split("/") if segment] segments = [segment for segment in path.split("/") if segment]
@@ -88,7 +94,7 @@ def _apply_post(post: PostPlan, wp: WordPressCLI, category_map: Dict[tuple[int,
parent = category_map[map_key] parent = category_map[map_key]
category_ids.append(parent) category_ids.append(parent)
created_on, last_modified = _normalize_post_dates(post.created_on, post.last_modified) created_on, last_modified = _normalize_post_dates(post.created_on, post.last_modified, wp_timezone)
post_id = wp.find_post_id(post.identity) post_id = wp.find_post_id(post.identity)
if post_id is None: if post_id is None:
@@ -119,13 +125,14 @@ def _apply_post(post: PostPlan, wp: WordPressCLI, category_map: Dict[tuple[int,
def _normalize_post_dates( def _normalize_post_dates(
created_on: Optional[str], created_on: Optional[str],
last_modified: Optional[str], last_modified: Optional[str],
wp_timezone,
) -> tuple[Optional[str], Optional[str]]: ) -> tuple[Optional[str], Optional[str]]:
if not created_on and not last_modified: if not created_on and not last_modified:
return created_on, last_modified return created_on, last_modified
now = datetime.now() now = datetime.now(wp_timezone)
created_dt = _parse_post_date(created_on) created_dt = _parse_post_date(created_on, wp_timezone)
modified_dt = _parse_post_date(last_modified) modified_dt = _parse_post_date(last_modified, wp_timezone)
if created_dt and created_dt > now: if created_dt and created_dt > now:
created_dt = now created_dt = now
@@ -139,10 +146,11 @@ def _normalize_post_dates(
return created_str, modified_str return created_str, modified_str
def _parse_post_date(value: Optional[str]) -> Optional[datetime]: def _parse_post_date(value: Optional[str], wp_timezone) -> Optional[datetime]:
if not value: if not value:
return None return None
try: try:
return datetime.strptime(value, "%Y-%m-%d %H:%M:%S") parsed = datetime.strptime(value, "%Y-%m-%d %H:%M:%S")
return parsed.replace(tzinfo=wp_timezone)
except ValueError: except ValueError:
return None return None

View File

@@ -3,8 +3,10 @@ from __future__ import annotations
import json import json
import subprocess import subprocess
from dataclasses import dataclass from dataclasses import dataclass
from datetime import timedelta, timezone
from pathlib import Path from pathlib import Path
from typing import Dict, List, Optional from typing import Dict, List, Optional
from zoneinfo import ZoneInfo
from .errors import WordPressError from .errors import WordPressError
@@ -78,6 +80,26 @@ class WordPressCLI:
except ValueError as exc: except ValueError as exc:
raise WordPressError(f"Invalid tag id from wp cli: {output}") from exc raise WordPressError(f"Invalid tag id from wp cli: {output}") from exc
def get_timezone(self):
tz_name = self._run(
["wp", "option", "get", "timezone_string"],
capture_output=True,
).stdout.strip()
if tz_name and tz_name.upper() != "UTC":
try:
return ZoneInfo(tz_name)
except Exception:
pass
offset_value = self._run(
["wp", "option", "get", "gmt_offset"],
capture_output=True,
).stdout.strip()
try:
offset = float(offset_value)
except ValueError:
offset = 0.0
return timezone(timedelta(hours=offset))
def create_category(self, name: str, parent: int) -> int: def create_category(self, name: str, parent: int) -> int:
result = self._run( result = self._run(
[ [