{"id":13558082,"url":"https://github.com/henrylawson/photish","last_synced_at":"2025-04-03T12:31:45.546Z","repository":{"id":56887995,"uuid":"45771530","full_name":"henrylawson/photish","owner":"henrylawson","description":"Fast, simple, configurable photo portfolio website generator","archived":false,"fork":false,"pushed_at":"2020-09-20T12:14:31.000Z","size":1715,"stargazers_count":150,"open_issues_count":6,"forks_count":11,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-03-13T03:36:27.374Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/henrylawson.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-11-08T07:40:43.000Z","updated_at":"2024-10-18T03:25:42.000Z","dependencies_parsed_at":"2022-08-21T00:50:53.738Z","dependency_job_id":null,"html_url":"https://github.com/henrylawson/photish","commit_stats":null,"previous_names":[],"tags_count":35,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/henrylawson%2Fphotish","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/henrylawson%2Fphotish/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/henrylawson%2Fphotish/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/henrylawson%2Fphotish/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/henrylawson","download_url":"https://codeload.github.com/henrylawson/photish/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247002451,"owners_count":20867464,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T12:04:44.154Z","updated_at":"2025-04-03T12:31:40.534Z","avatar_url":"https://github.com/henrylawson.png","language":"Ruby","funding_links":[],"categories":["Ruby","others","Static Site Generation"],"sub_categories":[],"readme":"# Photish\n\nPhotish is a simple, convention based (but configurable) static photo site\ngenerator. Photish allows you to group your photo collections by folder.\nMetadata can be written alongside the photo in a [YAML](http://yaml.org/) file\nwith the same name as the photo.\n\nPhotish will crawl through your directory of photos and metadata, and render\nthe information in your website templates. Photish supports all template\nengines implemented by [Tilt](https://github.com/rtomayko/tilt) (currently over\n30 formats). It will also read your configuration and automatically convert\nyour images to your configured size, dimensions, colourscheme, etc using\n[ImageMagick](http://www.imagemagick.org/) or\n[GraphicsMagick](http://www.graphicsmagick.org/). Using this information,\nPhotish creates a complete static website that can be hosted on an\n[NGINX](http://nginx.org/), [Apache HTTP Server](https://httpd.apache.org/), or\neven on [Github Pages](https://pages.github.com/).\n\nPhotish has been created with speed and efficiency in mind. Threads are used\nto parallelize image transcoding to achieve maximum utilization of your CPU\nduring generation. A cache file is then used to ensure that unless the image\nhas changed, it is not needlessly regenerated. This results in a responsive\nand fast local development environment, making it easy to perfect the design\nof your photo based website without having to wait for regeneration.\n\n## Example\n\n[Photish Montage](https://foinq.com/photish-montage/index.html) - A quick\nmockup to show what can be done with Photish. [Source\nhere](https://github.com/henrylawson/photish-montage).\n\n## Getting Started\n\nIt is strongly recommended to read through the [Installation](#installation)\nand [Usage](#usage) sections before seriously using Photish, however to get up\nand running:\n\n1. Ensure [ImageMagick](http://www.imagemagick.org/) (or\n   [GraphicsMagick](http://www.graphicsmagick.org/)) and\n   [Exiftool](http://www.sno.phy.queensu.ca/~phil/exiftool/) are installed (see\n   [Dependencies](#dependencies))\n1. Install Photish with `gem install photish` or with a [native installer](#installation)\n1. Create a base project with `photish init --example`\n1. Generate the HTML using `photish generate`\n1. Run a local HTTP server to view the site with `photish host`\n1. View your photo site at [http://localhost:9876](http://localhost:9876/)\n\n## Project Health\n\nCategory | Purpose | Badge\n---------|---------|------\n **Package** | RubyGem | [![Gem Version](https://badge.fury.io/rb/photish.svg)](https://badge.fury.io/rb/photish)\n             | Debian  | [![Download](https://api.bintray.com/packages/henrylawson/deb/photish/images/download.svg)](https://bintray.com/henrylawson/deb/photish/_latestVersion)\n             | RPM     | [![Download](https://api.bintray.com/packages/henrylawson/rpm/photish/images/download.svg)](https://bintray.com/henrylawson/rpm/photish/_latestVersion)\n **CI/CD Pipeline** | Main Build, Package and Release | [![Build Status](https://snap-ci.com/henrylawson/photish/branch/master/build_image)](https://snap-ci.com/henrylawson/photish/branch/master)\n                    | JRuby \u0026 Rubinius Builds | [![Build Status](https://travis-ci.org/henrylawson/photish.svg)](https://travis-ci.org/henrylawson/photish)\n                    | Windows Build | [![Build status](https://ci.appveyor.com/api/projects/status/b2pj9985aeylx0mi?svg=true)](https://ci.appveyor.com/project/HenryLawson/photish)\n **Code Quality**   | Dependency Versions | [![Dependency Status](https://gemnasium.com/henrylawson/photish.svg)](https://gemnasium.com/henrylawson/photish)\n                    | Code Climate GPA | [![Code Climate](https://codeclimate.com/github/henrylawson/photish/badges/gpa.svg)](https://codeclimate.com/github/henrylawson/photish)\n                    | Test Coverage | [![Test Coverage](https://codeclimate.com/github/henrylawson/photish/badges/coverage.svg)](https://codeclimate.com/github/henrylawson/photish/coverage)\n                    | Quality Metrics | [![Issue Count](https://codeclimate.com/github/henrylawson/photish/badges/issue_count.svg)](https://codeclimate.com/github/henrylawson/photish/issues)\n\n# Documentation\n\n- [Overview](#overview)\n- [Latest Version](#latest-version)\n- [Installation](#installation)\n  - [Dependencies](#dependencies)\n  - [Ruby Gem](#ruby-gem)\n  - [Debian Package](#debian-package)\n  - [RPM Package](#rpm-package)\n  - [Linux Binaries](#linux-binaries)\n  - [Windows Binaries](#windows-binaries)\n- [Usage](#usage)\n  - [Initialize](#initialize)\n    - [Basic Photish Structure](#basic-photish-structure)\n    - [Template Engines](#template-engines)\n    - [Site Assets](#site-assets)\n    - [Config File Options](#config-file-options)\n    - [Customizing Templates](#customizing-templates)\n      - [Layout Template](#layout-template)\n      - [Collection Template](#collection-template)\n      - [Album Template](#album-template)\n      - [Photo Template](#photo-template)\n      - [Template Helpers](#template-helpers)\n    - [Custom Rendered Content](#custom-rendered-content)\n      - [Gallery Page](#gallery-page)\n      - [Asset Page](#asset-page)\n  - [Generate](#generate)\n    - [Execution Order](#execution-order)\n    - [Image Conversion Tools](#image-conversion-tools)\n    - [Workers and Threads](#workers-and-threads)\n    - [Caching](#caching)\n      - [Automatic Rengeneration](#automatic-regeneration)\n      - [Forced Regeneration](#forced-regeneration)\n    - [Crude Performance Measures](#crude-performance-measures)\n  - [Host](#host)\n  - [Deploy](#deploy)\n  - [Rake Task](#rake-task)\n  - [Plugins](#plugins)\n    - [Template Helper Plugins](#template-helper-plugins)\n    - [Deployment Engine Plugins](#deployment-engine-plugins)\n    - [Plugin Loading](#plugin-loading)\n- [Development](#development)\n  - [Code Changes](#code-changes)\n  - [Services](#services)\n- [Contributing](#contributing)\n- [Versioning](#versioning)\n- [License](#license)\n\n## Overview\n\nPhotish turns this:\n\n    ./my_new_photo_site\n    ├── config.yml\n    ├── photos\n    │   ├── Big Dogs\n    │   │   ├── Tired Dogs.jpg\n    │   │   └── Winking Dog.jpg\n    │   └── Small Dogs\n    │       ├── Fluffy Dogs\n    │       │   ├── Exhausted Dogs.jpg\n    │       │   ├── Exhausted Dogs.yml\n    │       │   ├── Many Dogs.jpg\n    │       │   └── Many Dogs.yml\n    │       ├── Sleepy Dog.jpg\n    │       ├── Sleepy Dog.yml\n    │       └── Squishy Dogs\n    │           └── Big Ear Dog.jpg\n    └── site\n        ├── _templates\n        │   ├── album.slim\n        │   ├── collection.slim\n        │   ├── layout.slim\n        │   └── photo.slim\n        ├── custom.html\n        ├── images\n        │   └── crumbs.gif\n        └── styles\n            └── basic.css\n\nInto this:\n\n    ./my_new_photo_site\n    └── output\n        ├── big-dogs\n        │   ├── index.html\n        │   ├── tired-dogs\n        │   │   ├── images\n        │   │   │   ├── tired-dogs-low.jpg\n        │   │   │   └── tired-dogs-original.jpg\n        │   │   └── index.html\n        │   └── winking-dog\n        │       ├── images\n        │       │   ├── winking-dog-low.jpg\n        │       │   └── winking-dog-original.jpg\n        │       └── index.html\n        ├── custom.html\n        ├── index.html\n        ├── small-dogs\n        │   ├── fluffy-dogs\n        │   │   ├── exhausted-dogs\n        │   │   │   ├── images\n        │   │   │   │   ├── exhausted-dogs-low.jpg\n        │   │   │   │   └── exhausted-dogs-original.jpg\n        │   │   │   └── index.html\n        │   │   ├── index.html\n        │   │   └── many-dogs\n        │   │       ├── images\n        │   │       │   ├── many-dogs-low.jpg\n        │   │       │   └── many-dogs-original.jpg\n        │   │       └── index.html\n        │   ├── index.html\n        │   ├── sleepy-dog\n        │   │   ├── images\n        │   │   │   ├── sleepy-dog-low.jpg\n        │   │   │   └── sleepy-dog-original.jpg\n        │   │   └── index.html\n        │   └── squishy-dogs\n        │       ├── big-ear-dog\n        │       │   ├── images\n        │       │   │   ├── big-ear-dog-low.jpg\n        │       │   │   └── big-ear-dog-original.jpg\n        │       │   └── index.html\n        │       └── index.html\n        ├── images\n        │   └── crumbs.gif\n        └── styles\n            └── basic.css\n\nA breakdown of the before and after is as follows:\n\n1. For the **Collection** of photos in \"Photos\" an _index.html_ was created\n1. For each **Album** (that is a folder in the \"Photos\" collection), an\n   _index.html_ was created in a slugified sub folder\n1. For each **Photo** (an image file in the album), another _index.html_ was\n   created in a slugified sub folder named after the original photo\n1. For each of these Photos, a version of the **Image** was made in both \"low\"\n   and \"original\" quality in a sub folder called _images_\n\nThe number of Images and the quality of each is completely configurable. Using\nthe templating language of your choice you can easily generate a Photo\ncollection driven website with all of your photos available in various\nqualities and formats.\n\n## Latest Version\n\nPhotish follows [Semantic Versioning 2.0.0](http://semver.org/).\n\nReleases happen regularly and automatically from\n[Snap-CI](https://snap-ci.com/henrylawson/photish/branch/master).\n\nThe [latest version](https://github.com/henrylawson/photish/releases/latest) is\npublished with artifacts on GitHub.\n\n## Installation\n\nPhotish is available across all platforms as a [Ruby Gem](#ruby-gem). The\nrecommended installation is the [Ruby Gem](#ruby-gem) as not all features are\ncurrently available on the platform native packages.\n\nFor convenience Photish is also packaged in platform native installers. The\nplatform native installers come with all the Ruby Gems and Ruby runtime bundled\ninside the package. This means you simply need to install the package and you\ncan immediately use Photish without having to configure Ruby or any Gems, this\nis done using [Travelling Ruby](phusion.github.io/traveling-ruby/).\n\nInstructions are provided for each platform native installation:\n\n- [Debian Package](#debian-package)\n- [RPM Package](#rpm-package)\n- [Linux Binaries](#linux-binaries)\n- [Windows Binaries](#windows-binaries)\n\n### Dependencies\n\nPhotish has dependencies on certain software:\n\n- [ImageMagick](http://www.imagemagick.org/) or\n  [GraphicsMagick](http://www.graphicsmagick.org/) for image conversion\n- [Exiftool](http://www.sno.phy.queensu.ca/~phil/exiftool/) for image metadata\n  retrieval\n\nThese packages are not listed as hard dependencies in any of the provided\npackages as it is only needed during runtime, and in the case of\n[Exiftool](http://www.sno.phy.queensu.ca/~phil/exiftool/), if [Exif\nMetadata](https://en.wikipedia.org/wiki/Exchangeable_image_file_format) is not\nread during the generation of any templates, the dependency is not required.\n\n**On MacOSX, using [Brew](http://brew.sh/)**\n\n    $ brew install imagemagick # or brew install graphicsmagick\n    $ brew install exiftool\n\n**On Ubuntu or Debian**\n\n    $ sudo apt-get install imagemagick # or sudo apt-get install graphicsmagick\n    $ sudo apt-get install libimage-exiftool-perl\n\n**On CentOS, RedHat, etc.**\n\n    $ sudo yum install ImageMagick\n    $ sudo yum install perl-Image-ExifTool\n\n**On Windows**\n\nPlease check the dependencies website for the latest Windows installation\nsteps.\n\n### Ruby Gem\n\nPhotish supports multiple ruby versions:\n\nRuby Version                              | Minimum | Maximum | Comments\n----------------------------------------- |---------|---------|---------\n[MRI Ruby](https://www.ruby-lang.org/en/) | 2.0     | HEAD    | Very stable, all tests pass consistently\n[JRuby](http://jruby.org/)                | 9.0     | HEAD    | Mostly stable, smoke test passes consistently, full feature test flakey\n[Rubinius](http://rubinius.com/)          | 2.0     | HEAD    | Mostly stable, smoke test passes consistently, full feature test flakey\n\nThe latest version and all releases of Photish are tested against the above\nruby versions in the [CI pipeline](https://travis-ci.org/henrylawson/photish).\n\nBefore installing Photish, ensure you have the latest version of\n[Bundler](http://bundler.io/) for your ruby version.\n\nInstall the gem locally by running:\n\n    $ gem install photish\n\nAlternatively, use [Bundler](http://bundler.io/). Create a folder for your\nphoto site so you can track the version of Photish you are building with:\n\n    $ mkdir my_new_photo_site\n    $ cd my_new_photo_site\n    $ bundle init\n    $ echo 'gem \"photish\"' \u003e\u003e Gemfile\n    $ bundle install\n\n### Debian Package\n\nThe latest Debian package for amd64 and i386 architectures is available on\n[Bintray](https://bintray.com/henrylawson/deb) and uploaded to the latest\n[Photish Github\nRelease](https://github.com/henrylawson/photish/releases/latest).\n\nTo be up to date with the latest version of Photish, we recommend you add our\nDebian repository and install using apt-get:\n\n    $ # add the repository and SSH key\n    $ echo \"deb https://dl.bintray.com/henrylawson/deb all main\" | sudo tee -a /etc/apt/sources.list\n    $ sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys F608A664B7DFFFEA\n    $\n    $ # update keys and latest packages\n    $ sudo apt-get update \u0026\u0026 sudo apt-key update\n    $\n    $ # install photish\n    $ sudo apt-get install photish\n\nIf you have downloaded the *.deb file, simply install it with `dpkg`:\n\n    $ sudo dpkg -i photish*.deb\n\n### RPM Package\n\nThe latest RPM package for x86_64 and i386 architectures is available on\n[Bintray](https://bintray.com/henrylawson/rpm) and uploaded to the latest\n[Photish Github\nRelease](https://github.com/henrylawson/photish/releases/latest).\n\nTo be up to date with the latest version of Photish, we recommend you add our\nYUM repository and install using yum:\n\n    $ # add the repository and SSH key\n    $ wget https://bintray.com/henrylawson/rpm/rpm -O bintray-henrylawson-rpm.repo\n    $ sudo mv bintray-henrylawson-rpm.repo /etc/yum.repos.d/\n    $\n    $ # install photish\n    $ sudo yum install -y photish\n\nIf you have downloaded the *.rpm file, simply install it with `rpm`:\n\n    $ sudo rpm -Uh photish*.rpm\n\n### Linux Binaries\n\nIf you are using a distribution of Linux that we do not have a native package\ninstaller for, you can manually install Photish and use it by downloading the\nPhotish x64 and x86 binaries from the [Photish Github\nRelease](https://github.com/henrylawson/photish/releases/latest).\n\nYou can then extract the binaries to your desired location and use them.\n\n    $ tar -zxf photish-*-linux-*.tar.gz -C /destination\n\n### Windows Binaries\n\nIf you are using Windows, you can manually install Photish and use it by\ndownloading the Photish x86 binaries from the [Photish Github\nRelease](https://github.com/henrylawson/photish/releases/latest).\n\nYou can then extract the binaries to your desired location and use them.\n\n## Usage\n\nOnce you have photish installed. Get started with the following commands:\n\n### Initialize\n\nA skeleton site can be created by running the below command inside the\n`my_new_photo_site` folder:\n\n    $ photish init --example\n\nA barebones site can be created with:\n\n    $ photish init\n\n#### Basic Photish Structure\n\nInside your `my_new_photo_site` folder, you will have a:\n\nFile or Folder                    | Purpose\n--------------------------------- | -------\n`photos`                          | folder, for your photo collection and metadata\n`site`                            | folder for your templates, assets and static pages\n`site/_plugins`                   | folder for plugins to be loaded from\n`site/_templates`                 | folder for your templates\n`site/_templates/layout.slim`     | file for the basic layout for all pages\n`site/_templates/collection.slim` | template file for your collection page\n`site/_templates/album.slim`      | template file for your album page(s)\n`site/_templates/photo.slim`      | template file for your photo page(s)\n`config.yml`                      | file to store all configuration in YAML format\n\n#### Template Engines\n\nBy default Photish uses [Slim](http://slim-lang.com/) as the template language.\nThe templates can be in any format supported by\n[Tilt](https://github.com/rtomayko/tilt). To use a different template language:\n\n1. Create a `layout`, `collection`, `album` and `photo` file in the\n   `site/_templates` folder, with the file extension of the template engine you\n   prefer, supported extensions are documented by\n   [Tilt](https://github.com/rtomayko/tilt)\n1. Update `config.yml` to reference your newly created template files\n1. Re write the basic template code in your chosen language\n\n#### Site Assets\n\nAny content not starting with an `_` (underscore) in the `site` folder will be\ncopied to the `output` folder.\n\nIn the example in the Overview section. There are a few static asset files.\nThese are:\n\n1. `site/styles/basic.css`\n1. `site/images/crumbs.gif`\n1. `site/custom.html`\n\nBoth of these files were copied by Photish to the output folder, respecting\ntheir folder/file hierarchy:\n\n1. `output/styles/basic.css`\n1. `site/custom.html`\n\nAs documented in the Generate section, assets are copied before the site\ncontent is generated. If an asset has a conflicting name and path with a\ngenerated file, the generated file will clobber the asset.\n\n#### Config File Options\n\nThe default way to express config is in the `config.yml` file. However config\ncan also be overridden using the `--config_override` flag to any of the Photish\ncommands. When using the `--config_override` flag, the config must be expressed\nas [JSON](http://www.json.org/). For example, to override logging when calling\nthe Generate command, you can use:\n\n    $ photish generate --config_override='{\"logging\":{\"colorize\":false}}'\n\nThis method of config override is only recommended for cases where the value\nneeds to be temporarily overridden, such as during a deployment or while\ndebugging.\n\nBelow is a complete `config.yml` file, recommended practice is to only set the\nconfig values you need, otherwise just use the defaults, the file can be empty\nand Photish will still function:\n\n```yaml\nport: 9876\nqualities:\n  - name: Original\n    params: []\n  - name: Low\n    params: ['-resize', '200x200']\ntemplates:\n  layout: layout.slim\n  collection: collection.slim\n  album: album.slim\n  photo: photo.slim\nlogging:\n  colorize: true\n  level: 'debug'\n  output: ['stdout', 'file']\nurl:\n  host: http://mydomain.com\n  base: 'subdirectory'\n  type: 'relative_uri'\nworkers: 4\nthreads: 2\nforce: false\nplugins: ['ssh_deploy', 'other_plugin']\nimage_extensions: ['jpg', 'gif']\npage_extension: 'slim'\ndependencies:\n  minimagick:\n    cli: 'imagemagick'\n    cli_path: '/usr/bin/convert'\n    timeout: 3600\n  miniexiftool:\n    command: '/usr/bin/'\n```\n\nThe meanings and purpose of each field is defined below:\n\nField                  | Purpose\n---------------------- | -------\n`port`                 | the port number that the `photish host` command will bind to, default is `9876`\n`qualities`            | an array of `name` and `params` fields for **Images**\n`qualities[]/name`     | the name of the **Image** quality\n`qualities[]/params`   | the parameters to be provided to the ImageMagick or GraphicsMagick `convert` utility  for the **Image** file quality\n`templates`            | a listing of the various template files\n`templates/layout`     | the layout template file in the `site/_templates` folder, must be overridden if using a different template engine\n`templates/collection` | the collection template file in the `site/_templates` folder, must be overridden if using a different template engine\n`templates/album`      | the album template file in the `site/_templates` folder, must be overridden if using a different template engine\n`templates/photo`      | the photo template file in the `site/_templates` folder, must be overridden if using a different template engine\n`logging`              | a listing of the various logging options\n`logging/colorize`     | when outputting to `STDOUT`, `true` to use color, `false` for none\n`logging/level`        | the default logging level, it is advised to keep this at `debug`, supported are `debug`, `info`, `warn`, `error` and `fatal`\n`logging/output`       | the appenders for the logger, `stdout` goes to `STDOUT`, `file` goes to `log/photish.log`\n`url`                  | a listing of the various url options\n`url/host`             | if you would like URLs generated with a specific host prefix, you can define it here, otherwise leave it as '/' or do not set this configuration at all\n`url/base`             | if your website will be hosted in a sub folder and will not be accessible at the root of the host, you can specify the sub folder(s) here, this will also mean your website will be hosted in a sub folder when ran using `photish host`\n`url/type`             | if your website URLs require the host name in them, you can use `absolute_uri` (i.e. http://mysite.com/subdirectory/index.html), if you would prefer to generate URLs that end at the root, you can use `absolute_relative` (i.e. /subdirectory/index.html)\n`workers`              | the number of workers to create, for computers with multiple processors, photish is configured by default to spawn a worker for each process, a worker is responsible for image generation and html generation, load balancing is done randomly via a simple round robin allocation\n`threads`              | the number of threads each worker should create to handle image magick transcoding\n`force`                | this should always be false, if true, all content will be regenerated and nothing cached\n`plugins`              | an array of plugin names that have been included in your Gemfile and that Photish should require into it's runtime\n`image_extensions`     | by default, Photish has a complete list of image extensions, however if you choose too, you can explicitly list the extensions that Photish should use to find images\n`page_extension`       | the extension of **Pages** files that will live amongst the photo collection\n`dependencies`         | this section is for the configuration of third party tools\n`dependencies/minimagick`          | configuration for [minimagick](https://github.com/minimagick/minimagick), the wrapping library around [ImageMagick](http://www.imagemagick.org/) or [GraphicsMagick](http://www.graphicsmagick.org/)\n`dependencies/minimagick/cli`      | provide `imagemagick`, or `graphicsmagick` depending on your chosen library\n`dependencies/minimagick/cli_path` | if the above executables are not in your PATH, you can provide the location explicitly here\n`dependencies/minimagick/timeout`  | terminate a command after the provided number of seconds\n`dependencies/miniexiftool` | configuration for [mini_exiftool](https://github.com/janfri/mini_exiftool), the wrapping library around [Exif Tool](http://www.sno.phy.queensu.ca/~phil/exiftool/)\n`dependencies/miniexiftool/command` | if exiftool is not in your PATH, you can provide the location explicitly here\n\n#### Customizing Templates\n\nBelow is the documentation for the various data available inside\neach of the templates.\n\n**Note:** `{type}` is a place holder depending on your chosen template engine\nthe file extension will change. By default the template engine is\n[Slim](http://slim-lang.com/), so templates will end with the _slim_ extension.\n\n##### Layout Template\n\n`site/_templates/layout.{type}`\n\nExample:\n\n```slim\ndoctype html\nhtml\n  head\n    title Master Layout\n  body\n    == yield\n```\n\nThe layout template is the base layout for all the other templates. The\n`collection`, `album` and `photo` templates will be rendered inside this\nlayout. The layout template **must** include the `yield` statement to bind the\nsub template inside it. Below is an example [Slim](http://slim-lang.com/)\ntemplate, the other templates will be bound where the `yield` statement is:\n\n##### Collection Template\n\n`site/_templates/collection.{type}`\n\nExample:\n\n```slim\nh1 Photo Collection\n- albums.each do |album|\n  div.album\n    div.album-title\n      a href=album.url\n        | #{album.name}\n```\n\nThe collection template becomes the `index.html` for the root of the website.\n\nThis template is passed the\n[Collection](https://github.com/henrylawson/photish/blob/master/lib/photish/gallery/collection.rb)\nmodel when rendered.\n\nAttribute or Method | Description\n------------------- | -----------\nurl                 | the URL of this page\nmetadata            | an object with methods for the attributes in the `photos.yml` file\nalbums              | an array of child [Albums](https://github.com/henrylawson/photish/blob/master/lib/photish/gallery/album.rb) within this folder\nall_albums          | an array of all child [Albums](https://github.com/henrylawson/photish/blob/master/lib/photish/gallery/album.rb)\nall_photos          | an array of all child [Photos](https://github.com/henrylawson/photish/blob/master/lib/photish/gallery/photo.rb)\nall_images          | an array of all child [Images](https://github.com/henrylawson/photish/blob/master/lib/photish/gallery/image.rb)\nall_pages           | an array of all child [Pages](https://github.com/henrylawson/photish/blob/master/lib/photish/gallery/page.rb)\n\n##### Album Template\n\n`site/_templates/album.{type}`\n\nExample:\n\n```slim\nh1 Album\nh2\n  a href=url\n    | #{name}\ndiv.album-photos\n  - photos.each do |photo|\n    div.album-photo\n      a href=photo.url title=photo.name\n        img src=photo.images.find{ |i|i.quality_name=='Low' }.url alt=photo.name\n```\n\nFor each folder in the `photos` directory, a slugified album folder is created\nwith an `index.html` in it.\n\nThis template is passed the\n[Album](https://github.com/henrylawson/photish/blob/master/lib/photish/gallery/album.rb)\nmodel when rendered.\n\nAttribute or Method | Description\n------------------- | -----------\nname                | the name of the folder, i.e. `photos/My album/` will become `My album`\nurl                 | the URL of this page\nmetadata            | an object with methods for the attributes in the `{album_name}.yml` file stored at the same level as the album\nalbums              | an array of child [Albums](https://github.com/henrylawson/photish/blob/master/lib/photish/gallery/album.rb) within this folder\nall_albums          | an array of all child [Albums](https://github.com/henrylawson/photish/blob/master/lib/photish/gallery/album.rb)\nall_photos          | an array of all child [Photos](https://github.com/henrylawson/photish/blob/master/lib/photish/gallery/photo.rb)\nall_images          | an array of all child [Images](https://github.com/henrylawson/photish/blob/master/lib/photish/gallery/image.rb)\nall_pages           | an array of all child [Pages](https://github.com/henrylawson/photish/blob/master/lib/photish/gallery/page.rb)\n\n##### Photo Template\n\n`site/_templates/photo.{type}`\n\nExample:\n\n```slim\nh1 Photo\nh2\n  a href=url\n    | #{name}\n  div.album-photos\n    - images.each do |image|\n      div.album-photo\n        a href=image.url title=image.name\n          img src=image.url alt=image.quality_name\n```\n\nFor each image in an Albums directory, a slugified photo folder is created\nwith an `index.html` in it.\n\nThis template is passed the\n[Photo](https://github.com/henrylawson/photish/blob/master/lib/photish/gallery/photo.rb)\nmodel when rendered.\n\nAttribute or Method | Description\n------------------- | -----------\nname                | the name of the photo, i.e. `photos/My album/My dog.jpg` will become `My dog`\nurl                 | the URL of this page\nmetadata            | an object with methods for the attributes in the `{photo_name}.yml` file stored at the same level as the photo\nexif                | an object with methods for the exif data of the original photo file\nimages              | an array of all the [Images](https://github.com/henrylawson/photish/blob/master/lib/photish/gallery/image.rb) for this photo, an Image will be a version of the photo in the quality configured in `config.yml`\n\n#### Template Helpers\n\nA template helper is a simple method that is available in the template that can\nbe called to render complex information.\n\nFor example in a template, the method `breadcrumbs` can be called:\n\n```slim\ndiv.content\n  div.site-breadcrumbs\n    == breadcrumbs\n```\n\nWhen rendered this will result in an unordered list of pages above the\ncurrent page in the hierarchy:\n\n```html\n\u003cdiv class=\"content\"\u003e\n  \u003cdiv class=\"site-breadcrumbs\"\u003e\n    \u003cul class=\"breadcrumbs\"\u003e\n      \u003cli class=\"breadcrumb crumb-0 crumb-first\"\u003e\n        \u003ca href=\"/index.html\"\u003eHome\u003c/a\u003e\n      \u003c/li\u003e\n      \u003cli class=\"breadcrumb crumb-1\"\u003e\n        \u003ca href=\"/big-dogs/index.html\"\u003eBig Dogs\u003c/a\u003e\n      \u003c/li\u003e\n      \u003cli class=\"breadcrumb crumb-2 crumb-last\"\u003e\n        \u003ca href=\"/big-dogs/tired-dogs/index.html\"\u003eTired Dogs\u003c/a\u003e\n      \u003c/li\u003e\n    \u003c/ul\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\n```\n\nCustom template helpers are supported through [Plugins](#plugins).\n\nBy default, Photish comes with the following helpers:\n\nMethod              | Description\n------------------- | -----------\nbreadcrumbs         | an unordered list of pages above the current page in the hierarchy\nbuild_url(\\*pieces) | use this to ensure your URLs have the correct host name and base directory, to avoid having it hard coded in the template\n\n#### Custom Rendered Content\n\n##### Gallery Page\n\nA gallery page is a simple way to create a custom web page within the\ncollection or album of your gallery that will render within your site's [Layout\nTemplate](#layout-template).\n\nFor example, if you would like to create a \"more details\" page somewhere within\nan album, or the collection root, and you would like it rendered in the [Layout\nTemplate](#layout-template) to have a consistent look and feel, you can do it\nby creating a Gallery Page such as `more-about.slim` anywhere in your `photos`\ndirectory. The file extension is determined using the `page_extension` [Config\nFile Option](#config-file-option). A Gallery Page can live anywhere and you can\nhave as many of them as you like within the `photos` directory.\n\n`photos/**/*.{page_extension}`\n\n```slim\ndiv.more-about-album\n  h2 The More Details Page\n  p Lorem ipsum...\n  p Lorem ipsum...\n  p Lorem ipsum...\n```\n\nAs with other gallery generated content, a gallery page is accessible from the\n`all_pages` method within the [Collection](#collection-template) or\n[Album](#album-template) template.\n\n##### Asset Page\n\nAn Asset Page is a custom page that lives inside your `site` directory that\nis rendered using your template engine of choice. When an Asset Page template\nis rendered it is not rendered inside the site's [Layout\nTemplate](#layout-template). Asset Page's are standalone templates. Like other\nassets, they maintain the same folder structure in the `output` directory that\nthey have in the `site` directory. When rendered, the template is passed the\nCollection model, as such they have access to all attributes that a [Collection\nTemplate](#collection-template) does.\n\nFor example, if you would like to create an index page of all albums in your\ncollection you can create the following file:\n\n`site/index/all_albums.html.{page_extension}`\n\n```slim\ndoctype html\nhtml\n  head\n    title All Albums\n  body\n    ol\n      - all_albums.each do |album|\n        li #{album.name}\n```\n\nWhen rendered, the above Asset Page will be available at\n[http://localhost:9876/index/all_albums.html](http://localhost:9876/index/all_albums.html).\n\nIt is important to note that once rendered, the template extension is removed\nand the basename is used for the final filename. This allows you to specify\ncustom extensions before the `page_extension` such as TXT or XML. In the\nexample above, HTML is specified.\n\n[An\nexample](https://github.com/henrylawson/photish/blob/master/lib/photish/assets/example/site/sitemap.xml.slim)\nusage of an Asset Page is in the [include example\nsite](https://github.com/henrylawson/photish#initialize), it uses an Asset Page\nto create a [sitemap.xml](https://www.xml-sitemaps.com/)\n\n### Generate\n\nThe static HTML can be generated by running the below command inside the\n`my_new_photo_site` folder:\n\n    $ photish generate\n\nAll generated content will be written to the `output` folder by default.\n\n#### Execution Order\n\nThe Generate command does the following:\n\n1. Crawls the `photos` directory for photos and metadata\n1. Creates a site structure of Collection, Album(s), Photo(s) and Image(s)\n1. Copies all files in the `site` folder **not** beginning with an `_`\n   (underscore) to the `output` folder as these are viewed as \"static\" assets.\n   That is, folders like `_templates` are ignored\n1. Renders the HTML _index_ file(s) for the Collection, Album(s), Photo(s) and\n   Image(s) to the `output` folder\n1. Converts all Photo(s) to the configured quality versions, writing various\n   images to the `output` folder\n\n#### Image Conversion Tools\n\nPhotish supports [ImageMagick](http://www.imagemagick.org/) or\n[GraphicsMagick](http://www.graphicsmagick.org/) for image conversion.\n\nBy default, Photish will assume [ImageMagick](http://www.imagemagick.org/) is\ninstalled. To change this, ensure\n[GraphicsMagick](http://www.graphicsmagick.org/) is installed and the utility\nis availabe on the PATH. Then ensure that the [Config File\nOption](#config-file-option) `dependencies/minimagick/cli` is set to\n`graphicsmagick`. For example:\n\n```yaml\ndependencies:\n  minimagick:\n    cli: graphicsmagick\n```\n\nIf [ImageMagick](http://www.imagemagick.org/) or\n[GraphicsMagick](http://www.graphicsmagick.org/) is not available on the PATH\nyou can manually specify it's location by setting\n`dependencies/minimagick/cli_path`. For example:\n\n```yaml\ndependencies:\n  minimagick:\n    cli_path: '/usr/bin/convert'\n```\n\n#### Workers and Threads\n\nIn order to achieve maximum utilization of all processors on a computer during\ngeneration, Photish has the ability to create multiple workers and threads.\n\nA worker is a spawned sub process created by the Generate command. The worker\nsub process is responsible for generating the HTML and Images for a subset of\nthe collection.\n\nWithin each worker, threads are created when calling out to the Image Magick\nbinary. During conversion, Image Magick often does not reach full processor\nutilization so rather then block the whole worker, it can be more performant to\nspawn multiple Image Magick processes at once.\n\nFor collections with a large number of images and HTML pages, multiple workers\nand threads can be used to rapidly speed up generation. However, if the\ncollection has a small number of photos and pages, workers and threads will\nincrease the generation time as loading a new ruby process and creating\nmultiple threads may have a higher setup time then just generating everything\nin a single ruby process and thread.\n\nThe number of workers and threads is configurable in the [config\nfile](#config-file-options) with the `workers` and `threads` options. By\ndefault, Photish will spawn a thread for each processor detected on the\ncomputer. It will then run this on a single worker.\n\nWhen configuring more than 1 worker, it is important to remember that each\nworker will spawn their own set of threads, if 4 workers are created, each with\n2 threads, it means in total Photish will manage 8 threads and potentially run\n8 Image Magick processes concurrently.  When tweaking the number of workers and\nthreads it is important to consider IO bottlenecks as this will most likely be\nthe limiting factor in performance.\n\n#### Caching\n\nPhotish caches the generation of images to avoid regeneration when the\nGenerate command is run or the generate event is triggered while hosting\na local version of Photish with the Host command.\n\nThe cache file is stored in the `output_dir` and is named `.changes.yml`.\n\n##### Automatic Regeneration\n\nImages are regenerated when a photo is modified, renamed or moved.\n\nChanging the `qualities` option in the config file will also trigger a full\nregeneration of all images.\n\n##### Forced Regeneration\n\nTo do a full regeneration, run the Generate command with the `--force`\nflag:\n\n    $ photish generate --force\n\nThe host command also supports the `--force` flag, to do a full regeneration\non every change:\n\n    $ photish host --force\n\n### Crude Performance Measures\n\nBelow are some crude performance measures to get a ballpark idea of how\nPhotish performs when generating for a large collection.\n\n**Benchmark Computer:**\n\n    MacBook Pro (Retina, 13-inch, Early 2015)\n    2.7 GHz Intel Core i5 (4 processors)\n    8 GB 1867 MHz DDR3\n\n\nPhotos  | Size (M) | Workers   | Threads | Total Threads | Time (Seconds)\n--------|----------|-----------|---------|---------------|----------------\n934     | 464      | 1         | 1       | 1             | 601\n934     | 464      | 2         | 1       | 2             | 367\n934     | 464      | 4         | 1       | 4             | 312\n934     | 464      | 8         | 1       | 8             | 328\n934     | 464      | 1         | 2       | 2             | 346\n934     | 464      | 1         | 4       | 4             | **288**\n934     | 464      | 1         | 8       | 8             | 290\n934     | 464      | 2         | 2       | 4             | 309\n\nIt is interesting to note the 20-30 second difference between using 4 workers\nvs. 4 threads. The time difference is due to the setup time of creating a whole\nnew ruby process for each worker.\n\n### Host\n\nTo test and view your changes locally, the host command can be used to run a\nlocal\n[WEBrick](http://ruby-doc.org/stdlib-1.9.3/libdoc/webrick/rdoc/WEBrick.html)\nserver to serve the HTML files:\n\n    $ photish host\n\nThe local version of your website will be visible at\n[http://localhost:9876/](http://localhost:9876/).\n\nThe Host command will also automatically regenerate the website on startup and\nwhen a file is added, removed or modified in the `photo_dir` or `site_dir`.\n\nNote, when running in this mode any Image Conversion errors are swallowed and\nlogged. This is done as it is quite common for image files to be moved while\nconversion is in progress. Rather then terminate the Host, the file move is\nrecorded and regeneration will be triggered once the current generation\ncompletes.\n\n### Deploy\n\nPhotish provides a plugin type specifically for deployments, called the\n[Deployment Engine](#deployment-engine-plugins). Once a deploy plugin is\nconfigured, it can be ran by passing the deploy plugins name as a value with\nthe `engine` argument.\n\n    $ photish deploy --engine=name\n\nTo utilize a Deployment Engine Plugin someone in the community has written,\ntake a look at [Plugin Loading](#plugin-loading) for how to include it in your\nsite.\n\nIf you would like to write a [Deployment Engine\nPlugin](#deployment-engine-plugins) instructions are available in the [plugin\nsection](#deployment-engine-plugins).\n\n### Rake Task\n\nIf you would prefer to use Photish as a task in\n[Rake](http://rake.rubyforge.org/). A helper class is available to create\ncustom rake tasks that call Photish. The helper class is defined in\n[Photish::Rake::Task](https://github.com/henrylawson/photish/blob/master/lib/photish/rake/task.rb).\n\nIn your Rakefile, simply add the following to wrap the generate command:\n\n```ruby\nPhotish::Rake::Task.new(:generate, 'Compiles the project to HTML') do |t|\n  t.options = \"generate\"\nend\n```\n\nThe above code will define a rake task called `generate` which can be ran\nby using `rake generate`. It is the equivalent of `photish generate`.\n\n### Plugins\n\nPhotish supports extension through the creation of plugins.\n\n#### Template Helper Plugins\n\nTo create a template helper plugin you must:\n\n1. Create a **Ruby Module** in the `Photish::Plugin` module namespace, if\n   you are packaging the plugin as a Gem, you can implement your module one\n   level deeper in the namespace to allow for the Gem namespace, e.g.\n   `Photish::Plugin::MyGemPlugin::MyTemplateHelper`\n1. Make the plugin available for [loading](#plugin-loading)\n1. Implement the `self.is_for?(type)` method\n1. Implement your custom helper method(s)\n\nA simple plugin is bellow, this plugin is for all [Photo\nTemplate](#photo-template)'s as the `self.is_for?(type)` method only returns\ntrue for `Photish::Plugin::Type::Photo` types. When the `shout` method is\ncalled inside the template, it will render the message in bold wrapped in the\n\"I am shouting\" text.\n\n**site/_plugins/shout.rb**\n```ruby\nmodule Photish::Plugin::Shout\n  def self.is_for?(type)\n    Photish::Plugin::Type::Photo == type\n  end\n\n  def shout(message)\n    \"\u003cstrong\u003eI am shouting '#{message}'!!!\u003c/strong\u003e\"\n  end\nend\n\n```\nA Template Helper Plugin `self.is_for?(type)` method could potentially receive\nany of the below types, simply return true for the types the Template Helper\nPlugin supports:\n\n1. `Photish::Plugin::Type::Collection`\n1. `Photish::Plugin::Type::Album`\n1. `Photish::Plugin::Type::Photo`\n1. `Photish::Plugin::Type::Image`\n1. `Photish::Plugin::Type::Page`\n\nTo use the Template Helper Plugin, simply call the custom method(s) in your\ntemplate file. For the above example, it can be used by calling the `shout`\nmethod in a template file:\n\n**site/_templates/photo.slim**\n```slim\ndiv.my-shouting-content\n  == shout(\"HELLO\")\n```\n\nSome \"core\" Template Helper plugins available in Photish by default are:\n\n1. [Breadcrumb](https://github.com/henrylawson/photish/blob/master/lib/photish/plugin/core/breadcrumb.rb)\n1. [BuildUrl](https://github.com/henrylawson/photish/blob/master/lib/photish/plugin/core/build_url.rb)\n1. [Metadatable](https://github.com/henrylawson/photish/blob/master/lib/photish/plugin/core/metadatable.rb)\n1. [Exifable](https://github.com/henrylawson/photish/blob/master/lib/photish/plugin/core/exifable.rb)\n\n#### Deployment Engine Plugins\n\nTo create a deployment engine plugin you must:\n\n1. Create a **Ruby Class** in the `Photish::Plugin` module namespace, if\n   you are packaging the plugin as a Gem, you can implement your module one\n   level deeper in the namespace to allow for the Gem namespace, e.g.\n   `Photish::Plugin::MyGemPlugin::MyDeployEngine`\n1. Make the plugin available for [loading](#plugin-loading)\n1. Implement a `self.is_for?(type)` method and respond true when it receives\n   the `Photish::Plugin::Type::Deploy` type\n1. Implement a `self.engine_name` method and respond with the name of the\n   engine, this needs to match the value the user will pass on the\n   [Deploy](#deploy) command\n1. Implement a constructor, it should expect two argumnets `initialize(config,\n   log)`, a structure representing the config file and an instance of the\n   logger\n1. Finally the plugin should also implement a `deploy_site` method, this method\n   will execute the actual deployment\n\nA simple sample implementation is below:\n\n**site/_plugins/my_custom_deploy.rb**\n```ruby\nmodule Photish::Plugin::MyCustomDeploy\n  def initialize(config, log)\n    @config = config\n    @log = log\n  end\n\n  def self.is_for?(type)\n    Photish::Plugin::Type::Photo == type\n  end\n\n  def self.engine_name\n    'my_custom_deploy'\n  end\n\n  def deploy_site\n    @log.debug \"Deploying using my plugin\"\n    FileUtils.cp(@config.output_dir, '/srv/www')\n  end\nend\n```\n\nSome reference implementations of deploy plugins are:\n\n1. [Photish SSH Deploy](https://github.com/henrylawson/photish-plugin-sshdeploy)\n1. [Tmp Dir Deploy](https://github.com/henrylawson/photish/blob/master/lib/photish/assets/example/site/_plugins/tmpdir_deploy.rb)\n\n### Plugin Loading\n\nPhotish supports the following methods of Plugin loading.\n\n#### Site Folder Loading\n\nBy default, Photish will automatically load all files in the `site/_plugins`\ndirectory. This is the most simple way and is recommended if you just want to\nwrite a simple helper specific to your site.\n\nThe example site created when running `photish generate --example` uses this\nmethod to load plugins.\n\n#### Explicit Gem Loading\n\nThis is recommended method if you want to utilize a plugin created by someone\nelse in the community - rather than simply copy pasting their code to your\n`site/_plugins` directory. It is done by including a Gem in your Photish site's\n`Gemfile` and listing the require path of the Gem in the `plugins` [Config File\nOption](#config-file-options).\n\nAn example of Explicit Gem Loading is provided by the [Photish\nMontage](https://github.com/henrylawson/photish-montage) demo that explicitly\nloads the\n[Photish::Plugin::Sshdeploy](https://github.com/henrylawson/photish-plugin-sshdeploy)\nGem.\n\nTo load a Gem as a plugin, first of all add the Gem to your Gemfile:\n\n**Gemfile**\n\n```Gemfile\ngem 'photish-plugin-sshdeploy'\n```\n\nAnd in your Photish config, ensure it is listed in your `plugins` [Config File\nOption](#config-file-options).\n\n**config.yml**\n\n```YAML\nplugins: ['photish/plugin/sshdeploy']\n```\n\nThen run `bundle install`.\n\nTo confirm that it is installed correctly, when you run the `photish generate`\ncommand, you should see the plugin load:\n\n**log/photish.log or STDOUT**\n\n```\n...\n... Photish::Plugin::Repository: Found plugin Photish::Plugin::Sshdeploy::Deploy\n...\n```\n\nNote the 'photish-plugin-sshdeploy' Gem has other install steps documented in\nit's [README](https://github.com/henrylawson/photish-plugin-sshdeploy).\n\n## Development\n\n### Code Changes\n\nIf you would like to contribute to Photish by creating a new feature or fixing\nbugs, you are more then welcome!\n\nTo develop:\n\n    $ git clone git@github.com:henrylawson/photish.git\n    $ cd photish\n    $ ./bin/setup     # installs dependencies mentioned in output\n    $ rake            # runs the tests\n    $ vim             # open up the project and begin contributing\n    $ ./bin/console   # for an interactive prompt\n\nTo release:\n\n    $ rake dev:bump       # update version, create commit when prompted\n\nThe Snap CI will then detect that this is a tagged commit on MASTER and it will\ngenerate a build and release it.\n\nIf you need ideas on how to help, checkout our\n[TODO](https://github.com/henrylawson/photish/blob/master/TODO.md) list.\n\n### Services\n\nPhotish uses a range of services. Before contributing it is worth browsing\nthrough these services to understand how Photish is configured and is using\nthem:\n\n1. [Snap CI](https://snap-ci.com/henrylawson/photish/branch/master) is used as\n   the primary CI/CD server. All builds and tests are ran from Snap CI. Snap CI\n   is also used to release new versions of Photish to\n   [Github](https://github.com) and [Bintray](https://bintray.com).\n1. [Github](https://github.com/henrylawson/photish) is used for source control.\n   It is also used to record\n   [releases](https://github.com/henrylawson/photish/releases),\n   [issues](https://github.com/henrylawson/photish/issues),\n   [documentation](https://github.com/henrylawson/photish/blob/master/README.md)\n   and [todos](https://github.com/henrylawson/photish/blob/master/TODO.md).\n1. [Travis CI](https://travis-ci.org/henrylawson/photish) is used for the\n   testing of JRuby and Rubinius builds.\n1. [AppVeyor](https://ci.appveyor.com/project/HenryLawson/photish) is used for\n   testing and packaging of the Windows build.\n1. [Code Climate](https://codeclimate.com/github/henrylawson/photish) is used\n   to monitor high test coverage and quality code.\n1. [Gemnasium](https://gemnasium.com/henrylawson/photish) is used to ensure all\n   dependencies are up to date.\n1. Bintray [DEB](https://bintray.com/henrylawson/deb/photish/view) \u0026\n   [RPM](https://bintray.com/henrylawson/rpm/photish/view) binary install\n   packages for Linux distributions.\n\n## Contributing\n\nBug reports and pull requests are welcome on GitHub at\nhttps://github.com/henrylawson/photish. This project is intended to be a safe,\nwelcoming space for collaboration, and contributors are expected to adhere to\nthe [Contributor Covenant](http://contributor-covenant.org) code of conduct.\n\n## License\n\nThe gem is available as open source under the terms of the [MIT\nLicense](https://opensource.org/licenses/MIT).\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhenrylawson%2Fphotish","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhenrylawson%2Fphotish","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhenrylawson%2Fphotish/lists"}