From 6b0d4ee051f650b46af7ec50acf1122d44088fb5 Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Wed, 20 Apr 2022 10:12:14 +0100 Subject: modularize more --- katana.raku | 106 ++++----------------------------------- lib/Katana/Exec/Command.rakumod | 22 ++++++++ lib/Katana/HTML/Generate.rakumod | 22 ++++++++ lib/Katana/HTML/Tag.rakumod | 24 +++++++++ lib/Katana/Image/Elem.rakumod | 43 ++++++++++++++++ lib/Katana/Tag.rakumod | 44 ---------------- lib/Katana/Walk/Dir.rakumod | 36 +++++++++++++ 7 files changed, 157 insertions(+), 140 deletions(-) create mode 100644 lib/Katana/Exec/Command.rakumod create mode 100644 lib/Katana/HTML/Generate.rakumod create mode 100644 lib/Katana/HTML/Tag.rakumod create mode 100644 lib/Katana/Image/Elem.rakumod delete mode 100644 lib/Katana/Tag.rakumod create mode 100644 lib/Katana/Walk/Dir.rakumod diff --git a/katana.raku b/katana.raku index eee5927..59202a8 100755 --- a/katana.raku +++ b/katana.raku @@ -2,96 +2,12 @@ use v6.d; use lib 'lib'; -use Katana::Tag; -sub prefix:<❱>(*@args) { - say "❱ {@args}"; - my \proc = run @args, :out, :err; - .say if .chars > 0 - for proc.out.slurp(:close), proc.err.slurp(:close); -} - -sub prefix:<⁉>(*@args) { ❱ @args unless @args[*-1].IO.f } - -sub read-exif-info(Str $file) { - my %exif; - my \proc = run 'exiftool', $file, :out; - for proc.out.slurp(:close).split("\n") -> $line { - my ($key, $val) = $line.split(':')[0,1]; - next unless defined $val; - %exif{$key.trim} = $val.trim; - } - return %exif; -} - -class Image { - has Str $.basename; - has Str $!source; - has Str $!dist-dir; - has Str $.camera; - - submethod BUILD(IO::Path :$source, Str :$dist-dir) { - $!basename = $source.basename; - $!source = $source.path; - $!dist-dir = $dist-dir; - } - - method generate(Int :$thumb-geometry, Str :$bg-blur) { - my $thumb = "$!dist-dir/thumb/{$.basename}"; - ⁉ [|, $thumb-geometry, $!source, $thumb]; - - my $blur = "$!dist-dir/blur/{$.basename}"; - ⁉ [|, $thumb-geometry/4, '-blur', $bg-blur, $thumb, $blur]; - - my $large = "$!dist-dir/large/{$.basename}"; - ⁉ ['cp', $!source, $large]; - } - - method get-camera-model { - my %exif = read-exif-info "$!dist-dir/large/{$.basename}"; - my $make = %exif ?? %exif !! ''; - my $model = %exif{'Camera Model Name'} ?? %exif{'Camera Model Name'} !! ''; - $model ~~ s/$make //; # Don't stotter - $model = 'Unknown camera' if $model eq ''; - $!camera = "$make $model".trim; - } - - method tag(Str $class) { - "" - } -} - -sub dist-dirs(Str \dist-dir --> List) { dist-dir <<~>> } - -sub ensure-directories(Str \dist-dir) { - mkdir dist-dir unless dist-dir.IO.d; - mkdir $_ unless .IO.d for dist-dirs dist-dir; -} - -sub walk-dir(Str \dir, :&onFile, :&onDir = sub (\dir) {} ) { - return unless dir.IO.d; - for dir(dir) -> $fh { - given $fh { - when .d { walk-dir $fh.path, :&onFile, :&onDir } - default { &onFile($fh.path) } - } - } - &onDir(dir); -} - -sub cleanup-nonexistent (Str \dist-dir, @images) { - my $basenames = set @images.map:{ $_.basename }; - walk-dir dist-dir, - onFile => sub (\file) { - unlink file if file.IO.basename ∉ $basenames - }; -} - -sub make-mr-proper(Str \dist-dir) { - walk-dir dist-dir, - onFile => sub (\file) { unlink file }, - onDir => sub (\dir) { rmdir dir }; -} +use Katana::Exec::Command; +use Katana::HTML::Generate; +use Katana::HTML::Tag; +use Katana::Image::Elem; +use Katana::Walk::Dir; sub camera-stats(@images) { my %cameras; @@ -126,19 +42,18 @@ multi MAIN( push @html-elems, Tag.new: name => 'title', text => $title; - recurse-tags $doctype, @html-elems; + generate-from-tags $doctype, @html-elems; - exit; my @images = dir($in-dir, test => { "$in-dir/$_".IO.f }).map:{ - Image.new: source => $_, :$dist-dir + Elem.new: source => $_, :$dist-dir }; say "Found {@images.elems} images"; @images = @images.pick: * if $randomize; - cleanup-nonexistent $dist-dir, @images; - make-mr-proper $dist-dir if $mr-proper; - ensure-directories $dist-dir; + dir-cleanup-nonexistent $dist-dir, @images; + dir-make-mr-proper $dist-dir if $mr-proper; + dir-ensure $dist-dir; @images.hyper(:$degree).map:{ .get-camera-model; @@ -147,4 +62,3 @@ multi MAIN( .say for camera-stats @images; } - diff --git a/lib/Katana/Exec/Command.rakumod b/lib/Katana/Exec/Command.rakumod new file mode 100644 index 0000000..6cf0e38 --- /dev/null +++ b/lib/Katana/Exec/Command.rakumod @@ -0,0 +1,22 @@ +use v6.d; +unit module Katana::Exec::Command:api<1>; + +sub prefix:<❱>(*@args) is export { + say "❱ {@args}"; + my \proc = run @args, :out, :err; + .say if .chars > 0 for proc.out.slurp(:close), proc.err.slurp(:close); +} + +sub prefix:<⁉>(*@args) is export { ❱ @args unless @args[*-1].IO.f } + +sub read-exif-info(Str $file) is export { + my %exif; + my \proc = run 'exiftool', $file, :out; + for proc.out.slurp(:close).split("\n") -> $line { + my ($key, $val) = $line.split(':')[0,1]; + next unless defined $val; + %exif{$key.trim} = $val.trim; + } + return %exif; +} + diff --git a/lib/Katana/HTML/Generate.rakumod b/lib/Katana/HTML/Generate.rakumod new file mode 100644 index 0000000..fb020b4 --- /dev/null +++ b/lib/Katana/HTML/Generate.rakumod @@ -0,0 +1,22 @@ +use v6.d; + +unit module Katana::HTML::Generate:api<1>; + +multi sub generate-from-tags(Str $doctype, @tags) is export { + say $doctype; + generate-from-tags @tags; +} + +multi sub generate-from-tags(@tags) is export { + my @sgat; # tags spelled in reverse. + for @tags -> $tag { + say $tag.open; + say $tag.text if $tag.has-text; + unshift @sgat, $tag; + } + for @sgat -> $tag { + say $tag.close; + generate-from-tags $tag.succ if $tag.has-succ; + } +} + diff --git a/lib/Katana/HTML/Tag.rakumod b/lib/Katana/HTML/Tag.rakumod new file mode 100644 index 0000000..772a577 --- /dev/null +++ b/lib/Katana/HTML/Tag.rakumod @@ -0,0 +1,24 @@ +use v6.d; +unit module Katana::HTML:api<1>; + +class Tag is export { + has Str $.name; + has Str $.text; + has Str %.params; + has Tag @.succ; + + method has-text returns Bool { defined $.text } + method has-succ returns Bool { defined $.succ } + + method open returns Str { "<{$.name}{self.params}>" } + method close returns Str { "" } + + method params returns Str { + return '' unless defined %!params; + my @params; + for %!params.kv -> $key, $val { + push @params, " $key='$val'"; + } + return @params.join; + } +} diff --git a/lib/Katana/Image/Elem.rakumod b/lib/Katana/Image/Elem.rakumod new file mode 100644 index 0000000..3109e82 --- /dev/null +++ b/lib/Katana/Image/Elem.rakumod @@ -0,0 +1,43 @@ +use v6.d; + +use Katana::Exec::Command; + +unit module Katana::Image:api<1>; + +class Elem is export { + has Str $.basename; + has Str $!source; + has Str $!dist-dir; + has Str $.camera; + + submethod BUILD(IO::Path :$source, Str :$dist-dir) { + $!basename = $source.basename; + $!source = $source.path; + $!dist-dir = $dist-dir; + } + + method generate(Int :$thumb-geometry, Str :$bg-blur) { + my $thumb = "$!dist-dir/thumb/{$.basename}"; + ⁉ [|, $thumb-geometry, $!source, $thumb]; + + my $blur = "$!dist-dir/blur/{$.basename}"; + ⁉ [|, $thumb-geometry/4, '-blur', $bg-blur, $thumb, $blur]; + + my $large = "$!dist-dir/large/{$.basename}"; + ⁉ ['cp', $!source, $large]; + } + + method get-camera-model { + my %exif = read-exif-info "$!dist-dir/large/{$.basename}"; + my $make = %exif ?? %exif !! ''; + my $model = %exif{'Camera Model Name'} ?? %exif{'Camera Model Name'} !! ''; + $model ~~ s/$make //; # Don't stotter + $model = 'Unknown camera' if $model eq ''; + $!camera = "$make $model".trim; + } + + method tag(Str $class) { + "" + } +} + diff --git a/lib/Katana/Tag.rakumod b/lib/Katana/Tag.rakumod deleted file mode 100644 index c1b6204..0000000 --- a/lib/Katana/Tag.rakumod +++ /dev/null @@ -1,44 +0,0 @@ -use v6.d; - -unit module Katana:api<0>; - -class Tag is export { - has Str $.name; - has Str $.text; - has Str %.params; - has Tag @.succ; - - method has-text returns Bool { defined $.text } - method has-succ returns Bool { defined $.succ } - - method open returns Str {"<{$.name}{self.params}>" } - method close returns Str { "" } - - method params returns Str { - return '' unless defined %!params; - my @params; - for %!params.kv -> $key, $val { - push @params, " $key='$val'"; - } - return @params.join; - } -} - -multi sub recurse-tags(Str $doctype, @open-stack) is export { - say $doctype; - recurse-tags @open-stack; -} - -multi sub recurse-tags(@open-stack) is export { - my @close-stack; - for @open-stack -> $tag { - say $tag.open; - say $tag.text if $tag.has-text; - unshift @close-stack, $tag; - } - for @close-stack -> $tag { - say $tag.close; - recurse-tags $tag.succ if $tag.has-succ; - } -} - diff --git a/lib/Katana/Walk/Dir.rakumod b/lib/Katana/Walk/Dir.rakumod new file mode 100644 index 0000000..77370eb --- /dev/null +++ b/lib/Katana/Walk/Dir.rakumod @@ -0,0 +1,36 @@ +use v6.d; +use Katana::Image::Elem; +unit module Katana::Walk::Dir:api<1>; + +sub dist-dirs(Str \dist-dir --> List) { dist-dir <<~>> } + +sub dir-ensure(Str \dist-dir) is export { + mkdir dist-dir unless dist-dir.IO.d; + mkdir $_ unless .IO.d for dist-dirs dist-dir; +} + +sub dir-walk(Str \dir, :&onFile, :&onDir = sub (\dir) {} ) is export { + return unless dir.IO.d; + for dir(dir) -> $fh { + given $fh { + when .d { dir-walk $fh.path, :&onFile, :&onDir } + default { &onFile($fh.path) } + } + } + &onDir(dir); +} + +sub dir-cleanup-nonexistent (Str \dist-dir, @images) is export { + my $basenames = set @images.map:{ $_.basename }; + dir-walk dist-dir, + onFile => sub (\file) { + unlink file if file.IO.basename ∉ $basenames + }; +} + +sub dir-make-mr-proper(Str \dist-dir) is export { + dir-walk dist-dir, + onFile => sub (\file) { unlink file }, + onDir => sub (\dir) { rmdir dir }; +} + -- cgit v1.2.3