diff --git a/src/streamer/localize/localize.py b/src/streamer/localize/localize.py index fcf0fa4..adb94a2 100644 --- a/src/streamer/localize/localize.py +++ b/src/streamer/localize/localize.py @@ -22,16 +22,18 @@ def localize_shard( adjusted_moment: datetime = extract_datetime_from_marker_list(shard.markers, moment) for marker in shard.markers: - normalized_marker = marker.lower() + if marker in config.markers: + marker_definition = config.markers[marker] + for placement in marker_definition.placements: + if set(placement.if_with) <= set(shard.markers): + dimension = config.dimensions[placement.dimension] - if marker_definition := config.markers[normalized_marker]: - dimension_name = marker_definition.dimension - dimension = config.dimensions[marker_definition.dimension] + value = placement.value or marker - if dimension.propagate: - position[dimension_name] = normalized_marker - else: - private_position[dimension_name] = normalized_marker + if dimension.propagate: + position[placement.dimension] = value + else: + private_position[placement.dimension] = value children = [ localize_shard(child, config, position, adjusted_moment) diff --git a/src/streamer/localize/repostory_configuration.py b/src/streamer/localize/repostory_configuration.py index 95f32fe..3e37651 100644 --- a/src/streamer/localize/repostory_configuration.py +++ b/src/streamer/localize/repostory_configuration.py @@ -1,4 +1,5 @@ from typing import Optional + from pydantic import BaseModel @@ -8,9 +9,15 @@ class Dimension(BaseModel): propagate: bool = False +class MarkerPlacement(BaseModel): + if_with: list[str] = [] + dimension: str + value: str | None = None + + class Marker(BaseModel): display_name: str - dimension: str + placements: list[MarkerPlacement] class RepositoryConfiguration(BaseModel): @@ -18,4 +25,4 @@ class RepositoryConfiguration(BaseModel): markers: dict[str, Marker] -__all__ = ["Dimension", "Marker", "RepositoryConfiguration"] +__all__ = ["Dimension", "Marker", "MarkerPlacement", "RepositoryConfiguration"] diff --git a/test/test_localize.py b/test/test_localize.py index f6c0dc0..5f1ed65 100644 --- a/test/test_localize.py +++ b/test/test_localize.py @@ -5,6 +5,7 @@ from streamer.localize.localized_shard import LocalizedShard from streamer.localize.repostory_configuration import ( Dimension, Marker, + MarkerPlacement, RepositoryConfiguration, ) from streamer.parse.shard import Shard, StreamFile @@ -21,15 +22,30 @@ repository_configuration = RepositoryConfiguration( comment="Timestamp this entry was created at", propagate=True, ), + "timesheet": Dimension( + display_name="Timesheet", + comment="Time Cards for Time Tracking", + propagate=True, + ), }, markers={ - "streamer": Marker(display_name="Streamer", dimension="project"), - "jobhunting": Marker(display_name="JobHunting", dimension="project"), + "Streamer": Marker( + display_name="Streamer", + placements=[ + MarkerPlacement(dimension="project"), + MarkerPlacement( + if_with=["Timesheet"], dimension="timesheet", value="coding" + ), + ], + ), + "JobHunting": Marker( + display_name="JobHunting", placements=[MarkerPlacement(dimension="project")] + ), }, ) -class TestExtractDateTime: +class TestLocalize: def test_project_simple_stream_file(self): stream_file = StreamFile( file_name="20250622-121000 Test File.md", @@ -45,5 +61,27 @@ class TestExtractDateTime: start_line=1, end_line=1, children=[], - location={"project": "streamer", "file": stream_file.file_name}, + location={"project": "Streamer", "file": stream_file.file_name}, + ) + + def test_timesheet_use_case(self): + stream_file = StreamFile( + file_name="20260131-210000 Test File.md", + shard=Shard(start_line=1, end_line=1, markers=["Timesheet", "Streamer"]), + ) + + assert localize_stream_file( + stream_file, repository_configuration + ) == LocalizedShard( + moment=datetime(2026, 1, 31, 21, 0, 0, 0), + markers=["Timesheet", "Streamer"], + tags=[], + start_line=1, + end_line=1, + children=[], + location={ + "file": stream_file.file_name, + "project": "Streamer", + "timesheet": "coding", + }, )