├── config.json ├── YASGG ├── Dockerfile ├── lib ├── HTML5UP │ ├── Lens.pm │ └── Lens │ │ └── Utils.pm └── HTML5UP.pm ├── README.md └── template.html /config.json: -------------------------------------------------------------------------------- 1 | { 2 | "site": { 3 | "name": "YASGG", 4 | "description": "Gallery Generator based on Lens" 5 | }, 6 | "social": { 7 | "twitter": "false", 8 | "instagram": "false", 9 | "github": "false", 10 | "email": "false" 11 | } 12 | } -------------------------------------------------------------------------------- /YASGG: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | use Getopt::Long qw(GetOptions); 3 | use Cwd qw(abs_path); 4 | use FindBin; 5 | use lib abs_path("$FindBin::Bin/lib"); 6 | use HTML5UP::Lens; 7 | 8 | my ($PICTURESFROM, $HELP); 9 | my $FORKS = 1; 10 | my $OUTPUTTO = abs_path("$FindBin::Bin/_site"); 11 | my $CONFIGFROM = abs_path("$FindBin::Bin/config.json"); 12 | my $TEMPLATE = abs_path("$FindBin::Bin/html5up-lens"); 13 | GetOptions( 14 | 'config=s' => \$CONFIGFROM, 15 | 'pictures=s' => \$PICTURESFROM, 16 | 'out=s' => \$OUTPUTTO, 17 | 'forks=i' => \$FORKS, 18 | 'help' => \$HELP) or help(); 19 | 20 | $help && help(); 21 | $PICTURESFROM || help(); 22 | 23 | my $lens = HTML5UP::Lens->new( 24 | ConfigFrom => $CONFIGFROM, 25 | PicturesFrom => $PICTURESFROM, 26 | OutputTo => $OUTPUTTO, 27 | TemplateFrom => $TEMPLATE, 28 | Forks => $FORKS, 29 | ); 30 | 31 | $lens->Build; 32 | 33 | sub help { 34 | print "\n" . abs_path($0)." --config configfile.json --pictures /files" . "\n"; 35 | exit 0; 36 | } -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine 2 | 3 | RUN apk add \ 4 | wget \ 5 | build-base \ 6 | perl \ 7 | perl-dev \ 8 | perl-app-cpanminus \ 9 | imagemagick-perlmagick \ 10 | perl-moo \ 11 | perl-file-slurp \ 12 | perl-file-copy-recursive \ 13 | perl-strictures \ 14 | perl-getopt-long \ 15 | perl-parallel-forkmanager \ 16 | perl-try-tiny \ 17 | imagemagick 18 | 19 | # Only available in edge testing at this moment 20 | RUN apk add perl-sys-cpu --repository=http://dl-cdn.alpinelinux.org/alpine/edge/testing 21 | 22 | # A bunch of dependencies to speed up cpan install 23 | RUN apk add \ 24 | perl-capture-tiny \ 25 | perl-module-build \ 26 | perl-test-sharedfork \ 27 | perl-yaml-libyaml \ 28 | perl-test-differences \ 29 | perl-text-diff \ 30 | perl-json-maybexs \ 31 | perl-cpanel-json-xs 32 | 33 | RUN cpanm install CSS::Sass Template::Liquid File::JSON::Slurper Image::Magick::Thumbnail && rm -fr root/.cpanm 34 | RUN sed -i '/use warnings::register;/s/^#//' /usr/local/share/perl5/site_perl/Image/Magick/Thumbnail.pm -------------------------------------------------------------------------------- /lib/HTML5UP/Lens.pm: -------------------------------------------------------------------------------- 1 | package HTML5UP::Lens; 2 | 3 | use Moo; 4 | use strictures 2; 5 | use Data::Dumper; 6 | use File::Slurp qw / write_file /; 7 | use HTML5UP::Lens::Utils; 8 | 9 | 10 | extends 'HTML5UP'; 11 | 12 | my $sass = { 13 | 'assets/sass/main.scss' => 'assets/css/main.css', 14 | 'assets/sass/noscript.scss' => 'assets/css/noscript.css' 15 | }; 16 | 17 | has PicturesFrom => ( 18 | is => 'ro', 19 | required => 1, 20 | isa => sub { 21 | die "Directory does not exists: ".$_[0] 22 | unless -e $_[0]; 23 | } 24 | ); 25 | 26 | has thumbnailsPerRow => (is => 'ro',); 27 | 28 | has Forks => ( is => 'ro' ); 29 | 30 | 31 | sub Build { 32 | my $self = shift; 33 | 34 | $self->_Copy_Template_To_Output; 35 | unlink $self->OutputTo."/LICENSE.txt" if -e $self->OutputTo."/LICENSE.txt"; 36 | unlink $self->OutputTo."/README.txt" if -e $self->OutputTo."/README.txt"; 37 | unlink glob $self->OutputTo."'/images/fulls/*.*'"; 38 | unlink glob $self->OutputTo."'/images/thumbs/*.*'"; 39 | 40 | foreach my $sass_file (keys %{$sass}) { 41 | $self->_Sass_To_CSS( 42 | $self->OutputTo .'/'. $sass_file, #input sass path 43 | $self->OutputTo.'/'. $sass->{$sass_file}, #output sass path 44 | ); 45 | } 46 | 47 | HTML5UP::Lens::Utils->new->Copy_Pictures($self); 48 | $self->Config->{pictures} = HTML5UP::Lens::Utils->new->Find_Pictures($self); 49 | HTML5UP::Lens::Utils->new->Generate_Thumbnails($self); 50 | write_file($self->OutputTo .'/index.html', $self->_render_Template); 51 | } 52 | 53 | 1; 54 | -------------------------------------------------------------------------------- /lib/HTML5UP/Lens/Utils.pm: -------------------------------------------------------------------------------- 1 | package HTML5UP::Lens::Utils; 2 | 3 | use Moo; 4 | use strictures 2; 5 | use File::Find; 6 | use File::Basename; 7 | use Image::Magick::Thumbnail 0.06; 8 | use Data::Dumper; 9 | use File::Copy::Recursive qw(rcopy_glob fcopy rcopy dircopy fmove rmove dirmove); 10 | use Try::Tiny; 11 | 12 | sub Copy_Pictures { 13 | shift; 14 | my $self = shift; 15 | my $copy_from_template = $self->PicturesFrom . "/*.jpg"; 16 | my $copy_to_template = $self->OutputTo . "/images/fulls/"; 17 | rcopy_glob($copy_from_template, $copy_to_template) or die $!; 18 | } 19 | 20 | sub Find_Pictures { 21 | shift; 22 | my $self = shift; #fixme 23 | my @arr; 24 | find( 25 | { 26 | wanted => sub { 27 | -f and push @arr, $_ 28 | if (fileparse($_, qr/\.[^.]*/))[2] eq '.jpg'; 29 | }, 30 | follow => 0 31 | }, 32 | $self->PicturesFrom 33 | ); 34 | my @p = sort { $a cmp $b } @arr; 35 | return \@p; 36 | } 37 | 38 | sub Generate_Thumbnails { 39 | shift; 40 | my $self = shift; # fixme 41 | 42 | my $pm; 43 | if($self->Forks > 1) { 44 | try { 45 | require Parallel::ForkManager; 46 | Parallel::ForkManager->import(); 47 | my $MAX = $self->Forks; 48 | $pm = Parallel::ForkManager->new( $MAX ); 49 | }; 50 | } 51 | 52 | foreach(@{$self->Config->{pictures}}) { 53 | if($pm) { my $pid = $pm->start and next; } 54 | my $src = Image::Magick->new; 55 | $src->Read($self->OutputTo ."/images/fulls/$_"); 56 | my ($thumb, $x, $y) = Image::Magick::Thumbnail::create( 57 | $src, 58 | '660x525' 59 | ); 60 | $thumb->Write($self->OutputTo ."/images/thumbs/$_"); 61 | if($pm) { $pm->finish; } 62 | } 63 | if($pm) { $pm->wait_all_children; } 64 | return; 65 | } 66 | 67 | 1; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # YASGG 2 | 3 | ## Overview 4 | 5 | YASGG is a gallery generator based on the beautiful [Lens template][lens_template] by [html5up][html5up_website]. 6 | 7 | ![Lens][lens_screenshot] 8 | 9 | ## Prerequisites 10 | 11 | - [git][git_tool] 12 | - [docker][docker_tool] / [podman][podman_tool] 13 | 14 | ## Getting Started 15 | 16 | Start by cloning YASGG and html5up-lens: 17 | 18 | ```shell 19 | $ git clone https://github.com/someone-stole-my-name/YASGG.git 20 | $ cd YASGG 21 | $ git clone https://github.com/someone-stole-my-name/html5up-lens.git 22 | ``` 23 | 24 | Replace the original `index.html` with the templated version: 25 | 26 | ```shell 27 | $ cp template.html html5up-lens/index.html 28 | ``` 29 | 30 | Build the image: 31 | 32 | ```shell 33 | $ docker build -t yasgg . 34 | ``` 35 | 36 | ### Generate the gallery 37 | 38 | Modify the `config.json` with your own settings and then: 39 | 40 | ```shell 41 | $ GALLERY=/home/Christian/Pictures 42 | $ YASGG=$(pwd) 43 | $ docker run --rm -v $GALLERY:/gallery -v $YASGG:/YASGG yasgg /YASGG/YASGG --pictures /gallery 44 | ``` 45 | 46 | `GALLERY` is the directory that contains your `*.jpg` pictures. 47 | 48 | **Note:** _If using `podman` rootless containers you may have to relabel. See [Release Notes 1.6.0][podman_tool_1.6.0_Release_Notes]._ 49 | 50 | ### Preview 51 | 52 | ```shell 53 | $ SITE=$(pwd)/_site 54 | $ docker run --rm -v $SITE:/usr/share/nginx/html:ro -d nginx:latest 55 | ``` 56 | 57 | [docker_tool]:https://docs.docker.com/install/ 58 | [git_tool]:https://git-scm.com/downloads 59 | [html5up_website]:https://html5up.net/ 60 | [podman_tool]:https://github.com/containers/libpod/blob/master/install.md 61 | [podman_tool_1.6.0_Release_Notes]:https://github.com/containers/libpod/blob/master/RELEASE_NOTES.md#160 62 | [lens_screenshot]:https://i.imgur.com/4dl0I8w.jpg 63 | [lens_template]:https://html5up.net/lens 64 | -------------------------------------------------------------------------------- /lib/HTML5UP.pm: -------------------------------------------------------------------------------- 1 | package HTML5UP; 2 | use Moo; 3 | use strictures 2; 4 | use File::Copy::Recursive qw(dircopy); 5 | use CSS::Sass; 6 | use File::Slurp qw(write_file read_file); 7 | use Template::Liquid; 8 | use File::JSON::Slurper qw/ read_json /; 9 | 10 | has ConfigFrom => ( 11 | is => 'ro', 12 | required => 1, 13 | isa => sub { 14 | die "File is not readable: ".$_[0] 15 | unless -r $_[0]; 16 | }, 17 | ); 18 | 19 | has TemplateFrom => ( 20 | is => 'ro', 21 | required => 1, 22 | isa => sub { 23 | die "Check Directory: ".$_[0] 24 | unless -e $_[0]; 25 | }, 26 | ); 27 | 28 | has OutputTo => ( 29 | is => 'ro', 30 | required => 1, 31 | isa => sub { 32 | die "Unable to create: ".$_[0] 33 | unless -e $_[0] 34 | or mkdir $_[0]; 35 | } 36 | ); 37 | 38 | has Template => ( 39 | is => 'lazy', 40 | ); 41 | 42 | has Config => ( 43 | is => 'lazy', 44 | ); 45 | 46 | sub _build_Template { 47 | my $self = shift; 48 | my $template = read_file($self->TemplateFrom .'/index.html'); 49 | return Template::Liquid->parse($template); 50 | } 51 | 52 | sub _build_Config { 53 | my $self = shift; 54 | return read_json($self->ConfigFrom); 55 | } 56 | 57 | sub _render_Template { 58 | my $self = shift; 59 | 60 | my @arr_t; 61 | foreach my $top (keys %{$self->Config}) { 62 | if( ref($self->Config->{$top}) eq ref {} ) { 63 | foreach my $in (keys %{$self->Config->{$top}}) { 64 | if($self->Config->{$top}->{$in} eq 'false') { 65 | delete($self->Config->{$top}->{$in}); 66 | } 67 | } 68 | delete($self->Config->{$top}) and next unless %{ $self->Config->{$top} }; 69 | } 70 | push @arr_t, $top; 71 | push @arr_t, $self->Config->{$top}; 72 | } 73 | 74 | return $self->Template->render(@arr_t); 75 | } 76 | 77 | sub _Copy_Template_To_Output { 78 | my $self = shift; 79 | return dircopy($self->TemplateFrom,$self->OutputTo); 80 | } 81 | 82 | sub _Sass_To_CSS { 83 | my $self = shift; 84 | my ($source,$output) = @_; 85 | 86 | my $sass = CSS::Sass->new( 87 | output_style => SASS_STYLE_COMPRESSED, 88 | source_comments => 0, 89 | dont_die => 0, 90 | ); 91 | my $css = $sass->compile_file($source); 92 | write_file($output, $css); 93 | } 94 | 95 | 1; -------------------------------------------------------------------------------- /template.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {{ site.name }} 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 34 | 35 | 36 |
37 | {% for item in pictures %} 38 |
39 | 40 | 42 |
43 | {% endfor %} 44 |
45 | 46 | 47 | 52 | 53 |
54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | --------------------------------------------------------------------------------