diff --git a/src/apply.py b/src/apply.py index a2e67da..cf85d2a 100644 --- a/src/apply.py +++ b/src/apply.py @@ -18,6 +18,7 @@ def apply_changes( ) -> None: categories = wp.list_categories() category_map = _build_category_map(categories) + wp_timezone = wp.get_timezone() _create_missing_categories(result, wp, category_map) _create_missing_tags(result, wp) @@ -27,7 +28,7 @@ def apply_changes( for post in result.posts: if not post.should_update: continue - _apply_post(post, wp, category_map) + _apply_post(post, wp, category_map, wp_timezone) state.posts[post.identity] = PostState( source_timestamp=post.source_timestamp, materialized_at=int(time.time()), @@ -74,7 +75,12 @@ def _create_missing_tags(result: EvaluationResult, wp: WordPressCLI) -> None: 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] = [] for path in post.categories: 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] 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) 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( created_on: Optional[str], last_modified: Optional[str], + wp_timezone, ) -> tuple[Optional[str], Optional[str]]: if not created_on and not last_modified: return created_on, last_modified - now = datetime.now() - created_dt = _parse_post_date(created_on) - modified_dt = _parse_post_date(last_modified) + now = datetime.now(wp_timezone) + created_dt = _parse_post_date(created_on, wp_timezone) + modified_dt = _parse_post_date(last_modified, wp_timezone) if created_dt and created_dt > now: created_dt = now @@ -139,10 +146,11 @@ def _normalize_post_dates( 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: return None 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: return None diff --git a/src/wp_cli.py b/src/wp_cli.py index 4264776..65f9612 100644 --- a/src/wp_cli.py +++ b/src/wp_cli.py @@ -3,8 +3,10 @@ from __future__ import annotations import json import subprocess from dataclasses import dataclass +from datetime import timedelta, timezone from pathlib import Path from typing import Dict, List, Optional +from zoneinfo import ZoneInfo from .errors import WordPressError @@ -78,6 +80,26 @@ class WordPressCLI: except ValueError as 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: result = self._run( [