From cb219ea13988a6864d05315aafa4d49d9bec7be5 Mon Sep 17 00:00:00 2001 From: Thorsten Bus Date: Sun, 1 Mar 2026 18:46:10 +0100 Subject: [PATCH] [AI] extend ProFileGenerator with macro, media, and label creation --- php/src/ProFileGenerator.php | 104 ++++++++++++++++++++++++++--- php/tests/ProFileGeneratorTest.php | 97 +++++++++++++++++++++++++++ 2 files changed, 191 insertions(+), 10 deletions(-) diff --git a/php/src/ProFileGenerator.php b/php/src/ProFileGenerator.php index fe50cf9..d248d61 100644 --- a/php/src/ProFileGenerator.php +++ b/php/src/ProFileGenerator.php @@ -6,11 +6,15 @@ namespace ProPresenter\Parser; use Rv\Data\Action; use Rv\Data\Action\ActionType; +use Rv\Data\Action\LayerType; +use Rv\Data\Action\MacroType; +use Rv\Data\Action\MediaType; use Rv\Data\Action\SlideType; use Rv\Data\ApplicationInfo; use Rv\Data\ApplicationInfo\Application; use Rv\Data\ApplicationInfo\Platform; use Rv\Data\Color; +use Rv\Data\CollectionElementType; use Rv\Data\Cue; use Rv\Data\Graphics\Element as GraphicsElement; use Rv\Data\Graphics\Feather; @@ -30,6 +34,9 @@ use Rv\Data\Graphics\Stroke\Style as StrokeStyle; use Rv\Data\Graphics\Text; use Rv\Data\Graphics\Text\VerticalAlignment; use Rv\Data\Group; +use Rv\Data\Media; +use Rv\Data\Media\ImageTypeProperties; +use Rv\Data\Media\Metadata; use Rv\Data\Presentation; use Rv\Data\Presentation\Arrangement; use Rv\Data\Presentation\CCLI; @@ -38,6 +45,8 @@ use Rv\Data\PresentationSlide; use Rv\Data\Slide; use Rv\Data\Slide\Element as SlideElement; use Rv\Data\Slide\Element\TextScroller; +use Rv\Data\URL; +use Rv\Data\URL\Platform as UrlPlatform; use Rv\Data\UUID; use Rv\Data\Version; @@ -71,7 +80,7 @@ final class ProFileGenerator foreach ($groupData['slides'] as $slideData) { $cueUuid = self::newUuidString(); $cueIdentifiers[] = self::uuidFromString($cueUuid); - $cues[] = self::buildCue($cueUuid, $slideData['text'], $slideData['translation'] ?? null); + $cues[] = self::buildCue($cueUuid, $slideData); } $cueGroup = new CueGroup(); @@ -139,11 +148,14 @@ final class ProFileGenerator return $applicationInfo; } - private static function buildCue(string $cueUuid, string $text, ?string $translation): Cue + private static function buildCue(string $cueUuid, array $slideData): Cue { - $elements = [self::buildSlideElement('Orginal', $text)]; - if ($translation !== null) { - $elements[] = self::buildSlideElement('Deutsch', $translation); + $elements = []; + if (isset($slideData['text'])) { + $elements[] = self::buildSlideElement('Orginal', (string) $slideData['text']); + if (isset($slideData['translation']) && $slideData['translation'] !== null) { + $elements[] = self::buildSlideElement('Deutsch', (string) $slideData['translation']); + } } $slide = new Slide(); @@ -156,18 +168,90 @@ final class ProFileGenerator $slideType = new SlideType(); $slideType->setPresentation($presentationSlide); + $actions = [self::buildSlideAction($slideType)]; + + if (isset($slideData['media'])) { + $actions[] = self::buildMediaAction( + (string) $slideData['media'], + (string) ($slideData['format'] ?? 'JPG'), + ); + } + + if (isset($slideData['macro']) && is_array($slideData['macro'])) { + $actions[] = self::buildMacroAction($slideData['macro']); + } + + $cue = new Cue(); + $cue->setUuid(self::uuidFromString($cueUuid)); + $cue->setActions($actions); + $cue->setIsEnabled(true); + if (isset($slideData['label'])) { + $cue->setName((string) $slideData['label']); + } + + return $cue; + } + + private static function buildSlideAction(SlideType $slideType): Action + { $action = new Action(); $action->setUuid(self::newUuid()); $action->setType(ActionType::ACTION_TYPE_PRESENTATION_SLIDE); $action->setSlide($slideType); $action->setIsEnabled(true); - $cue = new Cue(); - $cue->setUuid(self::uuidFromString($cueUuid)); - $cue->setActions([$action]); - $cue->setIsEnabled(true); + return $action; + } - return $cue; + private static function buildMacroAction(array $macroData): Action + { + $parentCollection = new CollectionElementType(); + $parentCollection->setParameterName((string) ($macroData['collectionName'] ?? '--MAIN--')); + $parentCollection->setParameterUuid(self::uuidFromString((string) ($macroData['collectionUuid'] ?? ''))); + + $identification = new CollectionElementType(); + $identification->setParameterName((string) ($macroData['name'] ?? '')); + $identification->setParameterUuid(self::uuidFromString((string) ($macroData['uuid'] ?? ''))); + $identification->setParentCollection($parentCollection); + + $macroType = new MacroType(); + $macroType->setIdentification($identification); + + $action = new Action(); + $action->setUuid(self::newUuid()); + $action->setType(ActionType::ACTION_TYPE_MACRO); + $action->setMacro($macroType); + $action->setIsEnabled(true); + + return $action; + } + + private static function buildMediaAction(string $absoluteUrl, string $format): Action + { + $url = new URL(); + $url->setAbsoluteString($absoluteUrl); + $url->setPlatform(UrlPlatform::PLATFORM_MACOS); + + $metadata = new Metadata(); + $metadata->setFormat($format); + + $mediaElement = new Media(); + $mediaElement->setUuid(self::newUuid()); + $mediaElement->setUrl($url); + $mediaElement->setMetadata($metadata); + $mediaElement->setImage(new ImageTypeProperties()); + + $mediaType = new MediaType(); + $mediaType->setLayerType(LayerType::LAYER_TYPE_FOREGROUND); + $mediaType->setElement($mediaElement); + + $action = new Action(); + $action->setUuid(self::newUuid()); + $action->setType(ActionType::ACTION_TYPE_MEDIA); + $action->setMedia($mediaType); + $action->setIsEnabled(true); + + return $action; } private static function buildSlideElement(string $name, string $text): SlideElement diff --git a/php/tests/ProFileGeneratorTest.php b/php/tests/ProFileGeneratorTest.php index dbe893b..bdc6afe 100644 --- a/php/tests/ProFileGeneratorTest.php +++ b/php/tests/ProFileGeneratorTest.php @@ -318,4 +318,101 @@ class ProFileGeneratorTest extends TestCase $song = ProFileReader::read($filePath); $this->assertSame('Write Song', $song->getName()); } + + #[Test] + public function testGenerateWithMacro(): void + { + $song = ProFileGenerator::generate( + 'Macro Song', + [ + [ + 'name' => 'Verse 1', + 'color' => [0.1, 0.2, 0.3, 1.0], + 'slides' => [ + [ + 'text' => 'Line 1', + 'macro' => [ + 'name' => 'Macro Name', + 'uuid' => '11111111-2222-3333-4444-555555555555', + 'collectionName' => '--MAIN--', + 'collectionUuid' => '8D02FC57-83F8-4042-9B90-81C229728426', + ], + ], + ], + ], + ], + [ + ['name' => 'normal', 'groupNames' => ['Verse 1']], + ], + ); + + $slide = $song->getSlides()[0]; + $this->assertTrue($slide->hasMacro()); + $this->assertSame('Macro Name', $slide->getMacroName()); + $this->assertSame('11111111-2222-3333-4444-555555555555', $slide->getMacroUuid()); + } + + #[Test] + public function testGenerateMediaSlide(): void + { + $song = ProFileGenerator::generate( + 'Media Song', + [ + [ + 'name' => 'Verse 1', + 'color' => [0.1, 0.2, 0.3, 1.0], + 'slides' => [ + [ + 'media' => 'file:///tmp/test-image.jpg', + 'format' => 'JPG', + ], + ], + ], + ], + [ + ['name' => 'normal', 'groupNames' => ['Verse 1']], + ], + ); + + $slide = $song->getSlides()[0]; + $this->assertTrue($slide->hasMedia()); + $this->assertSame('file:///tmp/test-image.jpg', $slide->getMediaUrl()); + $this->assertSame('JPG', $slide->getMediaFormat()); + $this->assertSame('', $slide->getPlainText()); + } + + #[Test] + public function testGenerateMediaSlideWithLabelAndMacro(): void + { + $song = ProFileGenerator::generate( + 'Media Macro Song', + [ + [ + 'name' => 'Verse 1', + 'color' => [0.1, 0.2, 0.3, 1.0], + 'slides' => [ + [ + 'media' => 'file:///tmp/test-image-2.jpg', + 'format' => 'JPG', + 'label' => 'Image Slide Label', + 'macro' => [ + 'name' => 'Image Macro', + 'uuid' => 'AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE', + ], + ], + ], + ], + ], + [ + ['name' => 'normal', 'groupNames' => ['Verse 1']], + ], + ); + + $slide = $song->getSlides()[0]; + $this->assertTrue($slide->hasMedia()); + $this->assertSame('Image Slide Label', $slide->getLabel()); + $this->assertTrue($slide->hasMacro()); + $this->assertSame('Image Macro', $slide->getMacroName()); + $this->assertSame('AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE', $slide->getMacroUuid()); + } }