Skip to content

Commit

Permalink
Extract returning media & processing to the Files class
Browse files Browse the repository at this point in the history
  • Loading branch information
thekid committed Jan 1, 2025
1 parent 0addcb2 commit 4adf8a7
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 20 deletions.
20 changes: 8 additions & 12 deletions src/main/php/de/thekid/dialog/import/Source.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,26 +49,22 @@ public function parent(): ?string { return strstr($this->name(), '/', true) ?: n
/** Sets a parent for this source */
public function nestedIn(string $parent): self { $this->name= $parent.'/'.$this->name; return $this; }

/** Returns this source's origin */
public function origin(): Folder { return $this->origin; }

/** Yields all the media files in this source */
protected function mediaIn(Files $files): iterable {
static $processed= '/^(thumb|preview|full|video|screen)-/';

$images= [];
foreach ($this->entry['images'] ?? [] as $image) {
$images[$image['name']]= $image;
}

foreach ($this->origin->entries() as $path) {
$name= $path->name();
if ($path->isFile() && !preg_match($processed, $name) && ($processing= $files->processing($name))) {
$file= $path->asFile();
$name= $file->filename;

if (!isset($images[$name]) || $file->lastModified() > $images[$name]['modified']) {
yield new UploadMedia($this->entry['slug'], $file, $processing);
}
unset($images[$name]);
foreach ($files->in($this->origin) as $file => $processing) {
$name= $file->filename;
if (!isset($images[$name]) || $file->lastModified() > $images[$name]['modified']) {
yield new UploadMedia($this->entry['slug'], $file, $processing);
}
unset($images[$name]);
}

foreach ($images as $rest) {
Expand Down
31 changes: 29 additions & 2 deletions src/main/php/de/thekid/dialog/processing/Files.php
Original file line number Diff line number Diff line change
@@ -1,20 +1,47 @@
<?php namespace de\thekid\dialog\processing;

use io\Folder;

/** @test de.thekid.dialog.unittest.FilesTest */
class Files {
private $patterns= [];
private $processed= null;

/** Maps file extensions to a processing instance */
public function matching(array<string> $extensions, Processing $processing): self {
$this->patterns['/('.implode('|', array_map(preg_quote(...), $extensions)).')$/i']= $processing;
$this->processed= null;
return $this;
}

/** Returns a (cached) pattern to match all processed files */
public function processed(): string {
if (null !== $this->processed) return $this->processed;
$prefixes= [];
foreach ($this->patterns as $processing) {
foreach ($processing->prefixes() as $prefix) {
$prefixes[$prefix]= true;
}
}
return $this->processed= '/^('.implode('|', array_keys($prefixes)).')-/';
}

/** Returns processing instance based on filename, or NULL */
public function processing(string $filename): ?Processing {
foreach ($this->patterns as $pattern => $processing) {
if (preg_match($pattern, $filename)) return $processing;
if (!preg_match($this->processed(), $filename)) {
foreach ($this->patterns as $pattern => $processing) {
if (preg_match($pattern, $filename)) return $processing;
}
}
return null;
}

/** Yields files and their associated processing in a given folder */
public function in(Folder $origin): iterable {
foreach ($origin->entries() as $path) {
if ($path->isFile() && ($processing= $this->processing($path->name()))) {
yield $path->asFile() => $processing;
}
}
}
}
3 changes: 3 additions & 0 deletions src/main/php/de/thekid/dialog/processing/Processing.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ abstract class Processing {
/** Returns processing kind */
public abstract function kind(): string;

/** Returns prefixes used by the targets */
public function prefixes(): array<string> { return array_keys($this->targets); }

/**
* Adds a conversion target with a given prefix and conversion target.
* Fluent interface.
Expand Down
4 changes: 4 additions & 0 deletions src/main/php/de/thekid/dialog/processing/Videos.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,12 @@ class Videos extends Processing {

public function __construct(private string $executable= 'ffmpeg') { }

/** Returns processing kind */
public function kind(): string { return 'video'; }

/** Returns prefixes used by the targets */
public function prefixes(): array<string> { return [...parent::prefixes(), 'video', 'screen']; }

/** Executes a given external command and returns its exit code */
private function execute(string $command, array<string> $args): void {
$p= new Process($command, $args, null, null, [STDIN, STDOUT, STDERR]);
Expand Down
19 changes: 13 additions & 6 deletions src/test/php/de/thekid/dialog/unittest/FilesTest.php
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
<?php namespace de\thekid\dialog\unittest;

use de\thekid\dialog\processing\{Files, Images};
use de\thekid\dialog\processing\{Files, Images, ResizeTo, Processing};
use test\{Assert, Expect, Test, Values};

class FilesTest {

/** Returns a fixture with a given processing instance */
private function fixtureWith(Processing $processing): Files {
return new Files()->matching(['.jpg', '.jpeg'], $processing);
}

#[Test]
public function can_create() {
new Files();
Expand All @@ -13,16 +18,18 @@ public function can_create() {
#[Test, Values(['test.jpg', 'IMG_1234.JPG', '20221119-iOS.jpeg'])]
public function matching_jpeg_files($filename) {
$processing= new Images();
$fixture= new Files()->matching(['.jpg', '.jpeg'], $processing);

Assert::equals($processing, $fixture->processing($filename));
Assert::equals($processing, $this->fixtureWith($processing)->processing($filename));
}

#[Test, Values(['test-jpg', 'IMG_1234JPG', 'jpeg', '.jpeg-file'])]
public function unmatched_jpeg_files($filename) {
$processing= new Images();
$fixture= new Files()->matching(['.jpg', '.jpeg'], $processing);
Assert::null($this->fixtureWith($processing)->processing($filename));
}

Assert::null($fixture->processing($filename));
#[Test]
public function processed_pattern() {
$processing= new Images()->targeting('preview', new ResizeTo(720, 'jpg'));
Assert::equals('/^(preview)-/', $this->fixtureWith($processing)->processed());
}
}

0 comments on commit 4adf8a7

Please sign in to comment.