Code Monkey home page Code Monkey logo

thumbsup's Introduction

thumbsup

NPM License Standard - JavaScript Style Guide

Linux Tests Dependencies

Twitter LinkedIn Facebook


https://thumbsup.github.io

Banner


Turn any folder with photos & videos into a web gallery.

  • thumbnails & multiple resolutions for fast previews
  • mobile friendly website with customisable themes
  • only rebuilds changed files: it's fast!
  • uses relative paths so you can deploy the pages anywhere
  • works great with Amazon S3 for static hosting

Quick start

Simply point thumbsup to a folder with photos & videos. All nested folders become separate albums.

npm install -g thumbsup
thumbsup --input ./photos --output ./gallery

Screen recording

There are many command line arguments to customise the output. See the website for the full documentation: https://thumbsup.github.io.

Sample gallery

See a sample gallery online at https://thumbsup.github.io/demos/themes/mosaic/

sample gallery

Requirements

Thumbsup requires the following dependencies:

And optionally:

  • FFmpeg to process videos: brew install ffmpeg
  • Gifsicle to process animated GIFs: brew install gifsicle
  • dcraw to process RAW photos: brew install dcraw
  • ImageMagick for HEIC support (needs to be compiled with --with-heic)

You can run thumbsup as a Docker container (ghcr.io/thumbsup/thumbsup) which pre-packages all the dependencies above. Read the thumbsup on Docker documentation for more detail.

docker run -v `pwd`:/work ghcr.io/thumbsup/thumbsup [...]

Command line arguments

This reflects the CLI for the latest code on master. For the latest published version please refer to the docs on the website.


Usages:
  thumbsup [required] [options]
  thumbsup --config config.json


Required:
  --input   Path to the folder with all photos/videos  [string] [required]
  --output  Output path for the static website  [string] [required]

Input options:
  --scan-mode           How files are indexed  [choices: "full", "partial", "incremental"] [default: "full"]
  --include-photos      Include photos in the gallery  [boolean] [default: true]
  --include-videos      Include videos in the gallery  [boolean] [default: true]
  --include-raw-photos  Include raw photos in the gallery  [boolean] [default: false]
  --include             Glob pattern of files to include  [array]
  --exclude             Glob pattern of files to exclude  [array]

Output options:
  --thumb-size          Pixel size of the square thumbnails  [number] [default: 120]
  --small-size          Pixel height of the small photos  [number] [default: 300]
  --large-size          Pixel height of the fullscreen photos  [number] [default: 1000]
  --photo-quality       Quality of the resized/converted photos  [number] [default: 90]
  --video-quality       Quality of the converted video (percent)  [number] [default: 75]
  --video-bitrate       Bitrate of the converted videos (e.g. 120k)  [string] [default: null]
  --video-format        Video output format  [choices: "mp4", "webm"] [default: "mp4"]
  --video-hwaccel       Use hardware acceleration (requires bitrate)  [choices: "none", "vaapi"] [default: "none"]
  --video-stills        Where the video still frame is taken  [choices: "seek", "middle"] [default: "seek"]
  --video-stills-seek   Number of seconds where the still frame is taken  [number] [default: 1]
  --photo-preview       How lightbox photos are generated  [choices: "resize", "copy", "symlink", "link"] [default: "resize"]
  --video-preview       How lightbox videos are generated  [choices: "resize", "copy", "symlink", "link"] [default: "resize"]
  --photo-download      How downloadable photos are generated  [choices: "resize", "copy", "symlink", "link"] [default: "resize"]
  --video-download      How downloadable videos are generated  [choices: "resize", "copy", "symlink", "link"] [default: "resize"]
  --link-prefix         Path or URL prefix for "linked" photos and videos  [string]
  --cleanup             Remove any output file that's no longer needed  [boolean] [default: false]
  --concurrency         Number of parallel parsing/processing operations  [number] [default: 2]
  --output-structure    File and folder structure for output media  [choices: "folders", "suffix"] [default: "folders"]
  --gm-args             Custom image processing arguments for GraphicsMagick  [array]
  --watermark           Path to a transparent PNG to be overlaid on all images  [string]
  --watermark-position  Position of the watermark  [choices: "Repeat", "Center", "NorthWest", "North", "NorthEast", "West", "East", "SouthWest", "South", "SouthEast"]

Album options:
  --albums-from            How files are grouped into albums  [array] [default: ["%path"]]
  --sort-albums-by         How to sort albums  [choices: "title", "start-date", "end-date"] [default: "start-date"]
  --sort-albums-direction  Album sorting direction  [choices: "asc", "desc"] [default: "asc"]
  --sort-media-by          How to sort photos and videos  [choices: "filename", "date"] [default: "date"]
  --sort-media-direction   Media sorting direction  [choices: "asc", "desc"] [default: "asc"]
  --home-album-name        Name of the top-level album  [string] [default: "Home"]
  --album-page-size        Max number of files displayed on a page  [number] [default: null]
  --album-zip-files        Create a ZIP file per album  [boolean] [default: false]
  --include-keywords       Keywords to include in %keywords  [array]
  --exclude-keywords       Keywords to exclude from %keywords  [array]
  --include-people         Names to include in %people  [array]
  --exclude-people         Names to exclude from %people  [array]
  --album-previews         How previews are selected  [choices: "first", "spread", "random"] [default: "first"]

Website options:
  --index                 Filename of the home page  [string] [default: "index.html"]
  --albums-output-folder  Output subfolder for HTML albums (default: website root)  [string] [default: "."]
  --theme                 Name of a built-in gallery theme  [choices: "classic", "cards", "mosaic", "flow"] [default: "classic"]
  --theme-path            Path to a custom theme  [string]
  --theme-style           Path to a custom LESS/CSS file for additional styles  [string]
  --theme-settings        Path to a JSON file with theme settings  [string]
  --title                 Website title  [string] [default: "Photo album"]
  --footer                Text or HTML footer  [string] [default: null]
  --google-analytics      Code for Google Analytics tracking  [string]
  --embed-exif            Embed the exif metadata for each image into the gallery page  [boolean] [default: false]
  --locale                Locale for regional settings like dates  [string] [default: "en"]
  --seo-location          Location where the site will be hosted. If provided, sitemap.xml and robots.txt will be created.  [string] [default: null]

Misc options:
  --config         JSON config file (one key per argument)  [string]
  --database-file  Path to the database file  [string]
  --log-file       Path to the log file  [string]
  --log            Print a detailed text log  [choices: "default", "info", "debug", "trace"] [default: "default"]
  --dry-run        Update the index, but don't create the media files / website  [boolean] [default: false]

Deprecated:
  --original-photos       Copy and allow download of full-size photos (use --photo-download=copy)  [boolean]
  --original-videos       Copy and allow download of full-size videos (use --video-download=copy)  [boolean]
  --albums-date-format    How albums are named in <date> mode [moment.js pattern]
  --css                   Path to a custom provided CSS/LESS file for styling  [string]
  --download-photos       Target of the photo download links  [choices: "large", "copy", "symlink", "link"]
  --download-videos       Target of the video download links  [choices: "large", "copy", "symlink", "link"]
  --download-link-prefix  Path or URL prefix for linked downloads  [string]
  --usage-stats           Enable anonymous usage statistics  [boolean]

Options:
  --version  Show version number  [boolean]
  --help     Show help  [boolean]


 The optional JSON config should contain a single object with one key
 per argument, not including the leading "--". For example:
 { "sort-albums-by": "start-date" }

Contributing

We welcome all issues and pull requests!

If you are facing any issues or getting crashes, please try the following options to help troubleshoot:

thumbsup [options] --log debug
# [16:04:56] media/thumbs/photo-1446822622709-e1c7ad6e82d52.jpg [started]
# [16:04:57] media/thumbs/photo-1446822622709-e1c7ad6e82d52.jpg [completed]

thumbsup [options] --log trace
# [16:04:56] media/thumbs/photo-1446822622709-e1c7ad6e82d52.jpg [started]
# gm "identify" "-ping" "-format" "%[EXIF:Orientation]" [...]
# gm "convert" "-quality" "90" "-resize" "x400>" "+profile" [...]
# [16:04:57] media/thumbs/photo-1446822622709-e1c7ad6e82d52.jpg [completed]

If you want to contribute some code, please check out the contributing guidelines for an overview of the design and a run-through of the different automated/manual tests.

Disclaimer

While a lot of effort is put into testing Thumbsup (over 400 automated tests), the software is provided as-is under the MIT license. The authors cannot be held responsible for any unintended behaviours.

We recommend running Thumbsup with the least appropriate privilege, such as giving read-only access to the source images. The Docker setup detailed in the documentation follows this advice.

thumbsup's People

Contributors

almirkadric avatar amcolash avatar bglopez avatar darrellmozingo avatar dependabot[bot] avatar dravenst avatar felixonmars avatar galactictech avatar hnizdil avatar jaller94 avatar jareware avatar klikini avatar lucienve avatar navneetkarnani avatar oliverdain avatar pierrecle-dkt avatar rakoo avatar rprieto avatar tribut avatar vid0vid0 avatar vojta001 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

thumbsup's Issues

Autoplay videos enhancement

In case anyone is looking for a way to autoplay videos in blueimp, here's a hack I found. It appears to work on desktop browsers, but not iOS.

Just add this to the end of your blueimp call:

onslideend: function (index, slide) {
// Confirm this is a video file, and if so force it to play
if (this.list[index].getAttribute('type') == 'video/mp4') {
// Find the pause/play button on the video and force a click
document.getElementsByClassName("video-content")[0].lastChild.click();
}
}

Accept command line args in a separate file

There's starting to be a lot of args & flags. It would be nice if it also supported saving them all in a separate file, for example:

$ thumbsup conf.opts

conf.opts

--input /media
--output ./tmp
--title My gallery

Error on video poster generation

Have been using Thumbsup for some time. It's great. Recently I've received this error:

List all files      [====================] 8238/8238 files
Update metadata     [====================] up to date
Original photos     [====================] up to date
Original videos     [====================] up to date
Photos (large)      [====================] up to date
Photos (thumbs)     [====================] up to date
Videos (resized)    [====================] up to date
Videos (poster)     [--------------------] 1/114 files
{ [Error: Command failed: gm convert: Request did not return an image.
] code: 1, signal: null }

It seems to be error-ing on a video file, but I'm not sure which video file is causing the issue. Any ideas?

Thanks!

Report progress of operations

Maybe either a dot for each file processed

Building large thumbnails
............................... OK

or show the number of files to process / finished

Building large thumbnails
[===============         ] 17 / 24 files

Maybe node-progress?

Convert MTS videos into MP4

mts videos from an AVCHD camera can have interlacing artefacts. We could convert them to mp4 automatically when generating the smaller size.

template/theme for merging into existing static generator site

@rprieto I am using Hugo to generate sites in particular a landing page with a section for a gallery rather than a stand alone site template like thumbsup has. https://github.com/dkebler/landingpage-hugo-flex

For now I've simply generated my thumbsup site, then moved the media folder into my hugo site and changed my template to include the head css and body js in your template, moved the "media" id of the rendered template to a shortcode file in Hugo and load all lightgallery stuff from jsdeliver. It works for a one off project but now I'd like to fork thumbsup and automate this.

I don't see why it couldn't be just an option in the existing repo. Will need to be able to set the path of the media folder, could even be completely outside of hugo site's public/static like in a s3 bucket. Need to merge all thumbsup css in a single file for easier addition to hugo template and then be able to set/control where the template processing output is sent (in Hugo's case to a shortcode file that the user can then add to any section .md file.

Any interest in adding this feature to your project? If not I'll just go on my merry way.

FYI I putz around with this project and thumbsup (using handlebars) could be nice feature/module. https://github.com/dkebler/4S
Thanks for you efforts!

Gallery Fail if No Sub-Folders in Source Folder

Bug report

thumbsup V2.0.1
npm 4.2.0
node v7.10.1
Operating system: Ubuntu Server 16.04

About the bug...

  • Is the behaviour different from expected? yes
  • Can you provide steps to reproduce the issue? yes

This a newcomer's simplest possible test of thumbsup.

  1. Put a selection of image files in a folder (herinafter "source_folder").
  2. Run thumbsup thus: thumbsup --input /full/path/to/source_folder --output /somewhere/temp

Result is that the output includes a gallery file called .html and a corresponding link to.html in index.html. The generated gallery does not work when loaded onto a server as the server doesn't recognise .html as a valid HTML file. (I nearly walked away from thumbsup at this point.)

It looks as if the code does not cope with most basic case where there are images in the source folder passed to thumbsup.

Possible solutions? Maybe use the source folder name if images are found in the source folder rather than in a sub-folder?

Sort files by EXIF date when possible

Not sure what the best way is to implement this.

  • how expensive is it to read EXIF data?
  • can we afford to read it on every build, to sort the web pages?
  • should we maintain an index of all files & dates, and only read files that are newer than the index?

metadata.json

[
  { file: 'media/2014/paris001.jpg', date: 135873927 }
  { file: 'media/2014/paris002.jpg', date: 135874139 }
]

Folder sorting

Folders are now sorted alphabetically. There should be an option to sort them by date, ie. "date of the earliest photo in that folder".

-bash: thumbsup: command not found

I have Homebrew installed, as well as node, graphicsmagick and ffmpeg dependencies. Installed thumbsup with npn install thumbsup.

Whenever I run a version of

thumbsup --input "/media/photos" --output "./website" --title "My holidays" --thumb-size 200 --large-size 1500 --sort-folders date

It returns command not found.

I'm not an expert, so including the npm-debug.log write out:

0 info it worked if it ends with ok
1 verbose cli [ 'node', '/usr/local/bin/npm', 'run', 'example' ]
2 info using [email protected]
3 info using [email protected]
4 verbose node symlink /usr/local/bin/node
5 verbose config Skipping project config: /Users/jonathanarcher/.npmrc. (matches userconfig)
6 error Error: ENOENT, open '/Users/jonathanarcher/Pictures/theodonovan/package.json'
7 error If you need help, you may report this *entire* log,
7 error including the npm and node versions, at:
7 error     <http://github.com/npm/npm/issues>
8 error System Darwin 13.1.0
9 error command "node" "/usr/local/bin/npm" "run" "example"
10 error cwd /Users/jonathanarcher/Pictures/theodonovan
11 error node -v v0.10.30
12 error npm -v 2.0.0-alpha-5
13 error path /Users/jonathanarcher/Pictures/theodonovan/package.json
14 error code ENOENT
15 error errno 34
16 verbose exit [ 34, true ]

Possible Light Gallery plugin issue with version 2.0.0-alpha

Hello,

I recently installed thumbsup 2.0.0-alpha from NPM. It works great, and does exactly what I need. I noticed that videos don't seem to work though.

A quick check and it looks like it's unable to find the light gallery plugins (video, autoplay, pager etc.) as they don't seem to be in the public/light-gallery/js folder.

Could it be that I've done something wrong?

Thanks,
Richard.

Rebuilds more photos than necessary (metadata = 1 hour off)

On one occasion, thumbsup tried to rebuild more photos than necessary.
Adding some debugging, it seemed that:

file real date (in Finder) in thumbsup
source file Sun May 25 2014 19:09 metadata.json said 1401012582000 (Sun May 25 2014 20:09:42 GMT+1000)
destination thumbmail Sun May 25 2014 19:40 fs.stat said 1401010814000 (Sun May 25 2014 19:40:14 GMT+1000)

So the cache data (metadata.json) was an hour off, and the destination seemed out of date - when it really wasn't. Deleting metadata.json and doing a full rebuild fixed it.

Note: A diff between the old and rebuilt metadata.json shows many photos where fileDate is exactly 1 hour apart. Since this happened the day after daylight savings, it could be related?

Caption Enhancement

I create photo captions currently in Google Picasa. These captions are saved in the IPTC block of the image. I found some code to allow you to retrieve these using the ImageMagick identify function.

It would be great to add these to the exif data you're retrieving in exif.js currently.

var im  = require('imagemagick');
...
function(callback){
    im.identify(['-format', '%[IPTC:2:120]', filePath ], function(err, metadata){
        if (err) return callback(new Error('Failed to read caption ' + err + filePath));
    callback(null, { 
        caption: metadata ? metadata.trimRight() : ''
});

Customizable homepage

Right now the homepage defaults to the oldest album or gallery which doesn't quite seem right. I'd suggest we a different default for the homepage. Maybe we can do something like the sets display on flickr: https://www.flickr.com/photos/markwkoester/sets, meaning cover pic thumbnail and gallery title and picture count.

It might also be good to provide an option to just use an html page with some text.

Ideally it should be provide a template file homepage.hbs, like gallery.hbs.

On Mac OS X 10.11.3 100% CPU hang

I can't seem to glean much debugging info, but I can very consistently reproduce a 100% CPU (node process) hang on this step every time I have tried running this with a single photo and one subdir.
thumbsup --input ./inputdir --output ./outputdir
List all files [====================] 1/1 files
Update metadata [====================] 1/1 files
Photos (large) [====================] 1/1 files
Photos (thumbs) [====================] 1/1 files
Videos (resized) [====================] up to date
Videos (poster) [====================] up to date
Videos (thumbs) [====================] up to date
Static website <---- here's the hang

Lower video quality, but keep original media

Original video media is usually not web-friendly.

Use ffmpeg to lower the quality and allow web-streaming, while keeping the original video in original for the download link.

error on first run

Hi I see an error :/

what's wrong?

$ thumbsup --input ./funy --output ./gallery

Finding media [=========================] 8/8 done
Updating database [-------------------------] 0/8 /Users/jankowalski/.nvm/versions/node/v7.7.2/lib/node_modules/thumbsup/src/index.js:30
fileCollection = dbFiles.map(f => new File(f, opts))
^

TypeError: Cannot read property 'map' of undefined

Problems with second level directory

If I make a second level directory, like my_album/first/second it won't work:

Error: ENOENT, open '/home/data1/protected/public_html/www.yourweb.com/images/show/first/second.html']
errno: 34,
code: 'ENOENT',
path: '/home/data1/protected/public_html/www.yourweb.com/images/show/first/second.html' }

Increase the number of themes available

Hi there! Fantastic little module, thanks ever so much ๐Ÿ˜!

It would be lovely to have a small range of other themes (viz. a few other .css) that can be loaded in place of the original default one. What are your thoughts on this?

Cheers! Again, great job!

James.

custom css

enhancement -

Add loading of custom.css after all others in the head. Do not overwrite this file when building the gallery. As it stands viewer.css is overwritten when building and is loaded before lightgallery.css.

I'm working on a pr for this.

Ability to add a photo to several albums

Currently there is by-date and by-folder, which take a whole collection and create nested albums to represent them. You can only choose one or the other.

It would be nice to have the concept of mapping rules, which transform a photo into a target album. Then for each photo/video we can apply all mapping rules and put them in all corresponding albums. For example:

  • with the rule All folders/$path the photo will be added to All folders/Holidays/NewYork
  • with the rule By year/$yyyy/$mmm the photo will also be added to By year/2010/October

And this could also eventually support conditions, e.g.

file.path ~= /*/          => Browse/$path
file.path ~= /holidays/   => Holidays/$yyyy/$dirname

Or to automatically have an album with your best photos

# assuming they're flagged with a particular keyword in EXIF or IPTC
exif.comment ~= "fav"     => Best photos/$yyyy

Add optional cache busting

When hosting galleries behind a reverse proxy or CDN, things can get cached for too long. For example

  • index.html might not contain the latest albums
  • 2016-10.html might not contain the latest photos
  • thumbs/IMG4595.jpg might not update if you changed something

Some options:

  1. simply set a low TTL. However it's a compromise between caching efficiency and deployment speed. Always waiting 1h after uploading new galleries to see the changes is annoying.
  2. keep a high TTL but invalidate all cache after deploying. In CloudFront it's as easy as /* and counts as 1 invalidation ($0.005)
  3. add a cache busting query string at the end of the albums & media links. For efficiency it could simply be the last modified date that we already capture in metadata.json
  4. change the name of the assets themselves. This might be tricky because the generated website would keep growing in size unless cleaned up.

2.0.0 -Cannot read property 'map' of undefined

docker run -t -v /etc/localtime:/etc/localtime -v pwd:/work -u $(id -u):$(id -g) thumbsup:2.x.x thumbsup --input /work/media --output /work/gallery --sort-albums-by title --original-photos true

Finding media [=========================] 2/2 done
Updating database [-------------------------] 0/2 /usr/lib/node_modules/thumbsup/src/index.js:30
fileCollection = dbFiles.map(f => new File(f, opts))
^

TypeError: Cannot read property 'map' of undefined
at EventEmitter.database.update (/usr/lib/node_modules/thumbsup/src/index.js:30:33)
at emitOne (events.js:96:13)
at EventEmitter.emit (events.js:188:7)
at exiftool.read (/usr/lib/node_modules/thumbsup/node_modules/exiftool-json-db/lib/files.js:62:33)
at ChildProcess.child.on (/usr/lib/node_modules/thumbsup/node_modules/exiftool-json-db/lib/exiftool.js:52:5)
at emitOne (events.js:96:13)
at ChildProcess.emit (events.js:188:7)
at Process.ChildProcess._handle.onexit (internal/child_process.js:213:12)
at onErrorNT (internal/child_process.js:367:16)
at _combinedTickCallback (internal/process/next_tick.js:80:11)

Incorrect QuickTime Tag in getDate

Bug report

If running as an npm package:

Thumbsup version: 2.1.0
exiftool version: 10.55

The exiftools tags that are read from quicktime formats like mp4 videos
contains a tag called "CreateDate" for the creation date of the content:
see https://sno.phy.queensu.ca/~phil/exiftool/TagNames/QuickTime.html -- QuickTime MovieHeader Tags

In the function getDate in src/model/media.js a wrong Tag "CreationDate" is filtered for in Quicktime
content -- therefore not the correct content date but the file date is returned.

I don't know if this tag is named differently in other sources, but for my mp4's "CreateDate" is the
correct one.

Minor Directory and Path Issues

Great project! I've been looking for something like this for quite awhile.

A few fix ideas.

  1. I was seeing an error when I had additional levels in them with sub-directories with photos in them. I think the fix is to change this line in metadata.js from this:

glob('*/.{jpg,jpeg,png,mp4,mov,mts,m2ts}', globOptions, callback);

to this:

glob('{,/}.{jpg,jpeg,png,mp4,mov,mts,m2ts}', globOptions, callback);

  1. I was running into issues on Windows with the output web files having the slashes in the wrong direction. A simple change to the model.js file to find/replace slashes after the join function was helpful. I found a replaceAll function to do this:

String.prototype.replaceAll = function(str1, str2, ignore)
{
return this.replace(new RegExp(str1.replace(/([/,!^${}.*+?|<>-&])/g,"$&"),(ignore?"gi":"g")),(typeof(str2)=="string")?str2.replace(/$/g,"$$$$"):str2);
}

then update each of the join statements to something like this:
thumb: path.join('media', 'thumbs', file).replaceAll('','/'),

  1. I was getting an uncaught exception in exif.js when it was processing a bad file. I added a try/catch block around the exif.create() statement to fix it.

ffmpeg aac plugin require "experimental" flag when built from source (e.g. Ubuntu 14.04)

Hi there,

It's all working beautifully on Ubuntu 14.04 for pictures but having battles with ffmpeg. Not only was it an absolute horror to get installed from src (https://trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu) but now I am getting an error when running thumbsup.

I have a small mp4 video in my input directory and I'm getting the following error when running thumbsup at the bottom there about aac. Where do I need to add -strict -2 to get it to work?

root@ip-172-31-26-7:~# thumbsup --config config.json
List all files      [====================] 66/66 files
Update metadata     [====================] up to date
Original photos     [====================] 65/65 files
Photos (large)      [====================] 65/65 files
Photos (thumbs)     [====================] 65/65 files
Videos (resized)    [====================] 1/1 files

{ [Error: Command failed: ffmpeg version 2.7.2 Copyright (c) 2000-2015 the FFmpeg developers
  built with gcc 4.8 (Ubuntu 4.8.4-2ubuntu1~14.04)
  configuration: 
  libavutil      54. 27.100 / 54. 27.100
  libavcodec     56. 41.100 / 56. 41.100
  libavformat    56. 36.100 / 56. 36.100
  libavdevice    56.  4.100 / 56.  4.100
  libavfilter     5. 16.101 /  5. 16.101
  libswscale      3.  1.101 /  3.  1.101
  libswresample   1.  2.100 /  1.  2.100
Trailing options were found on the commandline.
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/root/mholtby-photos/Video_Testing_With_A_Longer_Album_Title_For_Pops/IMG_2595.mp4':
  Metadata:
    major_brand     : mp42
    minor_version   : 1
    compatible_brands: mp41mp42isom
    creation_time   : 2015-07-20 17:44:12
  Duration: 00:00:13.93, start: 0.000000, bitrate: 2942 kb/s
    Stream #0:0(und): Video: h264 (Baseline) (avc1 / 0x31637661), yuv420p(tv, bt709), 960x720, 2869 kb/s, 30.01 fps, 30 tbr, 600 tbn, 1200 tbc (default)
    Metadata:
      rotate          : 90
      creation_time   : 2015-07-20 17:44:12
      handler_name    : Core Media Video
    Side data:
      displaymatrix: rotation of -90.00 degrees
    Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, mono, fltp, 62 kb/s (default)
    Metadata:
      creation_time   : 2015-07-20 17:44:12
      handler_name    : Core Media Audio
[aac @ 0x20aba40] The encoder 'aac' is experimental but experimental codecs are not enabled, add '-strict -2' if you want to use it.
] killed: false, code: 1, signal: null }

Please help! ! !

Romain Prieto Hello!

Great works, what specific installation in a Mac-specific methods deployed to Dropbox shared galleries! Thank you.

In the End Operation:

brew install Node
brew install graphicsmagick
brew install ffmpeg

npm install -g thumbsup

How then should continue?

Thank you very much for your help!

New option to cleanup output folder

It would be nice to have an option to remove any obsolete files in the output folder. This is for cases where you remove a photo, and even though the HTML gallery doesn't have it anymore the output folder still contains the thumbnail etc...

For example:

{
  "input": "./media",
  "output": "./website",
  "cleanup": true
}

Or in case it ends up being an expensive operation, it could be a separate command like

thumbsup cleanup

Custom paths for templates / themes

Feature request

First of all, thanks for thumbsup, it's really speedy compared to what I used previously :)

I'm currently setting up a personal photogallery, and even though I enjoy the simplicity of thumbsup, I wanted to do some more advanced templates, as my current gallery has a specific markup and I wanted to use a specific lightbox for displaying the images.

I looked into the thumbsup code, and noticed that it's not possible to define templates/themes outside of the standard ones provided by default, and so I've created a fork, adding a few options, to override where thumbsup looks for templates / themes, as well as adding custom files to the public folder - to give full control of rendering.

I'm unsure if this is something you're interested in? If so, I'll make a PR for it, with the changes I'm currently running with :)

Decouple folder structure from rendered pages

It would be nice to allow different configurable views. Right now thumbsup generates albums based on the folder structures, but since it also maintains a metadata.json index it should be easy to generate many different views without much processing. It could be part of the configuration, e.g.

"views": [
  // generate 1 album per folder
  // there could be more options for sub-folders
  "folders": {
    "sort": "name"
  },
  // generate 1 album per date
  // e.g. "2016-01", "2016-02"...
  "date": {
    "group": "month",
    "format": "yyyy-mm",
    "sort": "date"
  }
]

You could potentially generate multiple album structures, and have a way to toggle the different views as part of the website navigation, i.e. "show me all folders", "show me all dates"...

Eventually, we could also have complex views like

filesystem links original-photos

This might be considered an enhancement, but from space usage p.o.v. a bug.
When original-photos is set to true, is there a need to copy the files to another folder?
One suggestion is to have an option to create links to them instead of duplicating GBs of pictures.
PS: It was noted that even with original-photos, also duplicated the pictures in two places: originals and large, therefore 3 times the same pics.

Lazy Loading

What about adding lazy loading onto the galleries? This would mean only automatically loading the first X thumbnails and loading others as one scrolls down.

This might be a feature to pass on but since I live in one of the internet dead zones of the world (China), data loads due matter and a bigger gallery of mine ends up at over 1MB with thumbnails, I thought I'd mention it.

New feature: --filter-input

What about the idea of an input filter? Only the files that pass the filter would be processed and resized, and appear in the galleries. It could be a new CLI argument, parsed with https://www.npmjs.com/package/safe-eval:

--filter-input "file => file.meta.favourite === true"

Or maybe passing the path to a Node.js module:

--filter-input-path ~/filter.js

And the filter script can look like:

// filter.js
module.exports = (file) => {

  // based on the file path
  return file.path.match(/holidays/)
  
  // or based on metadata
  return file.meta.favourite === true
  return file.meta.rating > 4
  return file.meta.keywords.include('holidays')

}

Support Photo Titles

I really like what you are doing here. Simple and understandable approach to static photo gallery generation and using nodejs to boot! Bravo!

I'd like to add Title support so that title gets shown for images. I guess the step would be generate some of that info into metadata.json as a new line so we'd end up with something like

"filename.jpg": {
"fileDate": 1412499522000,
"mediaDate": 1408641125000,
"mediaType": "photo",
"title":"title-here-using-filename"
},

Make full-size uploads an option (& change the download button accordingly)

Original / full-size media can be quite big. It would be nice to have an options that doesn't copy the full-size media into the website folder. We'd also need to change the download button so it downloads the smaller size instead.

This could either be --no-original-photos and --no-original-videos, or we could even make it the default, and add --include-original-photos, --include-original-videos.

Represent input/output as a new data structure

For now, files are generated based on a nice-looking DSL like

buildStep({
  message: 'Videos: poster',
  ext:     'mp4|mov|mts|m2ts',
  dest:    '/large/$path/$name.jpg',
  func:    thumbs.videoLarge
})

The benefit is it's that very easy to read, but the downsides are

  1. hard to create new features that need to know about inputs and output, e.g. #33 (tracking output files that are no longer required)
  2. logic for output paths is found in multiple files, with makes features like #32 (changing the output naming convention) harder

It could look like:

// Array<File>

{
  // so far, same data as <metadata.json>
  filePath 'input/path/photo.jpg',
  fileDate: 1486379695124,
  mediaType: 'photo',
  exif: {
    date: 1486379695124,
    caption: 'Nice photo'
  },
  // extra section for corresponding output files
  output: {
    thumb: 'output/path/photo-thumb.jpg',
    large: 'output/path/photo-large.jpg',
    original: 'output/path/photo.jpg'
  }
}

The make logic would have to change to something like this, which is quite legible too:

buildStep({
  message: 'Videos: poster',
  filter:  (f) => f.mediaType === 'video',
  dest:    (f) => f.output.large,
  func:    thumbs.videoLarge
})

And this structure could then be used to create the current File objects (maybe rename to AlbumEntry/Media, that get grouped into albums.

album.media = [
  new Media(file)
]

Investigate integration with diaporama

Github: https://github.com/gre/diaporama
Demo: http://greweb.me/diaporama/

Some ideas:

  • diaporama for every album, similar to the lightgallery slideshow
  • diaporama for the whole gallery

Sample diaporama.json

{
  "generator": { "version": "0.2.2", "url": "https://github.com/gre/diaporama-maker" },
  "timeline": [
    {
      "kenburns": {
        "easing": [ 0.3161764705882353, 0.007407407407407418, 0.75, 0.75 ],
        "from": [ 0.880167474730694, [ 0.5754716981132075, 0.31512605042016806 ] ],
        "to": [ 1, [ 0.6344339622641509, 0.23109243697478993 ] ]
      },
      "image": "./example1/framboises.jpg",
      "duration": 3600,
      "transitionNext": { "name": "directionalwipe", "duration": 1000 }
    },
    {
      "kenburns": {
        "easing": [ 0.25, 0.25, 0.5919117647058824, 0.9925925925925926 ],
        "from": [ 0.7895868757190729, [ 0.4080188679245283, 0.4045936395759717 ] ],
        "to": [ 1, [ 0.6698113207547169, 0.6484098939929329 ] ]
      },
      "image": "./example1/cafes.jpeg",
      "duration": 4000,
      "transitionNext": {
        "uniforms": { "smoothness": 0.03 },
        "name": "undulating burn out",
        "duration": 1400
      }
    }
  ]
}

Issues with sorting and timestamps

I found a few issues with the app:

  1. When adding albums and sorting by date, I found I wanted the newest first however there was no way to change sort order
  2. When sorting by date, and lack of exif data, it would use ctime instead of mtime for timestamp entries. This caused issues when touching up photos as this would change the ctime which cannot be changed without unmounting the filesystem and modifying the inode vs being able to arbitrarily set the mtime (eg via touch)

I know very little about javascript, and even less about node, so I humbly present my naive approach on how I solved the issues with config toggles.

Suggestion: improve legibility by flattening output structure

thumbsup currently generates the following structure:

โ”œโ”€โ”€ media
โ”‚ย ย  โ”œโ”€โ”€ large
โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ album1
โ”‚ย ย  โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ sunset.jpg
โ”‚ย ย  โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ tree.jpg
โ”‚ย ย  โ”‚ย ย  โ”‚ย ย  โ””โ”€โ”€ water.jpg
โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ album2
โ”‚ย ย  โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ bridge.jpg
โ”‚ย ย  โ”‚ย ย  โ”‚ย ย  โ””โ”€โ”€ lighthouse.jpg
โ”‚ย ย  โ”œโ”€โ”€ original
โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ album1
โ”‚ย ย  โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ sunset.jpg
โ”‚ย ย  โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ tree.jpg
โ”‚ย ย  โ”‚ย ย  โ”‚ย ย  โ””โ”€โ”€ water.jpg
โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ album2
โ”‚ย ย  โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ bridge.jpg
โ”‚ย ย  โ”‚ย ย  โ”‚ย ย  โ””โ”€โ”€ lighthouse.jpg
โ”‚ย ย  โ””โ”€โ”€ thumbs
โ”‚ย ย      โ”œโ”€โ”€ album1
โ”‚ย ย      โ”‚ย ย  โ”œโ”€โ”€ sunset.jpg
โ”‚ย ย      โ”‚ย ย  โ”œโ”€โ”€ tree.jpg
โ”‚ย ย      โ”‚ย ย  โ””โ”€โ”€ water.jpg
โ”‚ย ย      โ”œโ”€โ”€ album2
โ”‚ย ย      โ”‚ย ย  โ”œโ”€โ”€ bridge.jpg
โ”‚ย ย      โ”‚ย ย  โ””โ”€โ”€ lighthouse.jpg

It has advantages, like the fact the ./media/original folder should be identical to the source. However if there's an issue with a given image it's painful having to browse multiple folders to see what's wrong. It can also be confusing when searching for a given file to find 3 files with the same name (original, large, thumbnail).

I was thinking of the following:

โ”œโ”€โ”€ media
โ”‚ย ย  โ”œโ”€โ”€ album1
โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ sunset.jpg
โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ sunset_large.jpg
โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ sunset_thumb.jpg
โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ tree.jpg
โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ tree_large.jpg
โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ tree_thumb.jpg
โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ water.jpg
โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ water_large.jpg
โ”‚ย ย  โ”‚ย ย  โ””โ”€โ”€ water_thumb.jpg
โ”‚ย ย  โ”œโ”€โ”€ album2
โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ bridge.jpg
โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ bridge_large.jpg
โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ bridge_thumb.jpg
โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ lighthouse.jpg
โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ lighthouse_large.jpg
โ”‚ย ย  โ”‚ย ย  โ””โ”€โ”€ lighthouse_thumb.jpg

Only thing.... that's a breaking change and no one wants to rebuild their entire website. If we go down this path we'll need some sort of migration tool.

Unexpected error: stderr maxBuffer exceeded

This is happening while processing a 240MB / 2min MOV video, and crashes thumbsup with

Unexpected error: stderr maxBuffer exceeded

The command being run before it crashes is

ffmpeg -i "movie.mov" -y "movie.mp4" -f mp4 -vcodec libx264 -ab 96k -vb 1200k

When run manually, you can see the output contains a lot of these:

Past duration 0.696281 too large
[...]
Past duration 0.999992 too large

From a quick read, it seems that's not really an issue, just a warning. It's probably OK to ignore, or could be fixed by setting the frame rate explicitly.

Regarding the crash though, it's probably happening because thumbsup uses child_process.exec (in resize.js) which buffers the whole command output in memory - and the stderr output here exceeds the default buffer length. If this is the cause, it could be fixed by using spawn instead, and using a growing in-memory buffer - or simply ignoring stderr/stdout if the data is not used.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.