photish 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: bf314194e23c79c0044bb7ae4a1e89d85a75c249
4
+ data.tar.gz: 058379e40ecc0ebc40575335c620b626ba496874
5
+ SHA512:
6
+ metadata.gz: 71d79a7276c266b57e06f21811f823a5315c6941ec2c17498c1bb35e39eb0a51a2b9c7213b175a949b60923557d0fa1df007ad96306dd733481b50a942218646
7
+ data.tar.gz: 2a43e23ad1bc0e6a5623a8213df6c6acd686e8f3fdd77f44bf0aec6bef54ceb221a424a4f8334c9d15e84adacfc5d021468d8cdf51ab27f63073e4eb6383151f
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2.2
4
+ before_install: gem install bundler -v 1.10.6
@@ -0,0 +1,13 @@
1
+ # Contributor Code of Conduct
2
+
3
+ As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
4
+
5
+ We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion.
6
+
7
+ Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
8
+
9
+ Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.
10
+
11
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
12
+
13
+ This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/)
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in photish.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Henry Lawson
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,26 @@
1
+ # Photish
2
+
3
+ ## Installation
4
+
5
+ Install the gem locally by running:
6
+
7
+ $ gem install photish
8
+
9
+ ## Usage
10
+
11
+ TODO: Write usage instructions here
12
+
13
+ ## Development
14
+
15
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
16
+
17
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
18
+
19
+ ## Contributing
20
+
21
+ Bug reports and pull requests are welcome on GitHub at https://github.com/henrylawson/photish. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](contributor-covenant.org) code of conduct.
22
+
23
+ ## License
24
+
25
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
26
+
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+ require 'cucumber'
4
+ require 'cucumber/rake/task'
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ Cucumber::Rake::Task.new(:features) do |t|
9
+ t.cucumber_opts = "features --format pretty"
10
+ end
11
+
12
+ task :default => [:features, :spec]
data/TODO.md ADDED
@@ -0,0 +1,18 @@
1
+ # Photish Todo
2
+
3
+ ## Must Have
4
+
5
+
6
+ ## Might Have
7
+
8
+ 1. `init` command to get started
9
+ 1. `deploy` to deploy to github pages
10
+ 1. Better README.md
11
+ 1. Actual website, using photish
12
+ 1. Startup bash script should install image magick, libmagic, exiftool
13
+
14
+ ## Potential Features
15
+
16
+ 1. A sitemap feature
17
+ 1. A breadcrumb feature
18
+ 1. Relative/absolute with/without hostname URLs (for different host envs) with view helper
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "photish"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
data/exe/photish ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'photish/cli'
4
+ Photish::CLI.start
@@ -0,0 +1,38 @@
1
+ require 'thor'
2
+ require 'photish/generation'
3
+ require 'photish/host'
4
+
5
+ module Photish
6
+ class CLI < Thor
7
+ package_name "Photish"
8
+
9
+ desc "generate", "Generates the gallery static site"
10
+ method_option :photo_dir,
11
+ aliases: "-p",
12
+ desc: "The directory where the photos live"
13
+ method_option :site_dir,
14
+ aliases: "-s",
15
+ desc: "The location of the site config and template files"
16
+ method_option :output_dir,
17
+ aliases: "-o",
18
+ desc: "The output directory where the generated site should go"
19
+ def generate
20
+ Photish::Generation.new(options).execute
21
+ end
22
+
23
+ desc "host", "Generates the gallery static site"
24
+ method_option :photo_dir,
25
+ aliases: "-p",
26
+ desc: "The directory where the photos live"
27
+ method_option :site_dir,
28
+ aliases: "-s",
29
+ desc: "The location of the site config and template files"
30
+ method_option :output_dir,
31
+ aliases: "-o",
32
+ desc: "The output directory where the generated site should go"
33
+ def host
34
+ Photish::Host.new(options).execute
35
+ end
36
+ end
37
+ end
38
+
@@ -0,0 +1,32 @@
1
+ require 'photish/config/settings'
2
+ require 'photish/config/location'
3
+
4
+ module Photish
5
+ module Config
6
+ class AppSettings
7
+ def initialize(runtime_config)
8
+ @runtime_config = runtime_config
9
+ end
10
+
11
+ def config
12
+ @config ||= Config::Settings
13
+ .new(default_config)
14
+ .override(file_config)
15
+ .override(runtime_config)
16
+ end
17
+
18
+ private
19
+
20
+ attr_reader :runtime_config
21
+
22
+ def file_config
23
+ config_location = Config::Location.new(runtime_config[:site_dir])
24
+ Config::FileConfig.new(config_location.path).hash
25
+ end
26
+
27
+ def default_config
28
+ Config::DefaultConfig.new.hash
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,26 @@
1
+ module Photish
2
+ module Config
3
+ class DefaultConfig
4
+ def hash
5
+ {
6
+ port: 9876,
7
+ site_dir: File.join(Dir.pwd, 'site'),
8
+ photo_dir: File.join(Dir.pwd, 'photos'),
9
+ output_dir: File.join(Dir.pwd, 'output'),
10
+ qualities: [
11
+ { name: 'Original',
12
+ params: [] },
13
+ { name: 'Low',
14
+ params: ['-resize', '200x200'] }
15
+ ],
16
+ templates: {
17
+ layout: 'layout.slim',
18
+ collection: 'collection.slim',
19
+ album: 'album.slim',
20
+ photo: 'photo.slim'
21
+ }
22
+ }
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,20 @@
1
+ require 'yaml'
2
+
3
+ module Photish
4
+ module Config
5
+ class FileConfig
6
+ def initialize(config_file_path)
7
+ @config_file_path = config_file_path
8
+ end
9
+
10
+ def hash
11
+ @hash ||= YAML.load_file(config_file_path)
12
+ end
13
+
14
+ private
15
+
16
+ attr_reader :config_file_path
17
+ end
18
+ end
19
+ end
20
+
@@ -0,0 +1,37 @@
1
+ module Photish
2
+ module Config
3
+ class Location
4
+ FILE_NAME = 'config.yml'
5
+
6
+ def initialize(site_dir)
7
+ @site_dir = site_dir
8
+ end
9
+
10
+ def path
11
+ ensure_expected_path_exists
12
+ expected_path
13
+ end
14
+
15
+ private
16
+
17
+ attr_reader :site_dir
18
+
19
+ def ensure_expected_path_exists
20
+ return if File.exists?(expected_path)
21
+ raise "Config file does not exist at #{expected_path}"
22
+ end
23
+
24
+ def expected_path
25
+ File.join(directory, config_file_name)
26
+ end
27
+
28
+ def directory
29
+ site_dir || Dir.pwd
30
+ end
31
+
32
+ def config_file_name
33
+ FILE_NAME
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,34 @@
1
+ require 'yaml'
2
+ require 'active_support'
3
+ require 'active_support/core_ext'
4
+ require 'photish/config/default_config'
5
+ require 'photish/config/file_config'
6
+
7
+ module Photish
8
+ module Config
9
+ class Settings
10
+ def initialize(config = nil)
11
+ @config = compact_symbolize(config)
12
+ end
13
+
14
+ def val(key)
15
+ config[key.to_sym]
16
+ end
17
+
18
+ def override(hash)
19
+ cleaned_hash = compact_symbolize(hash)
20
+ self.class.new(config.merge(cleaned_hash))
21
+ end
22
+
23
+ private
24
+
25
+ attr_reader :config
26
+
27
+ def compact_symbolize(hash)
28
+ (hash || {})
29
+ .compact
30
+ .deep_symbolize_keys
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,59 @@
1
+ require 'photish/gallery/photo'
2
+ require 'photish/gallery/traits/urlable'
3
+ require 'photish/gallery/traits/albumable'
4
+ require 'photish/gallery/traits/metadatable'
5
+ require 'active_support'
6
+ require 'active_support/core_ext'
7
+ require 'filemagic'
8
+
9
+ module Photish
10
+ module Gallery
11
+ class Album
12
+
13
+ include ::Photish::Gallery::Traits::Urlable
14
+ include ::Photish::Gallery::Traits::Albumable
15
+ include ::Photish::Gallery::Traits::Metadatable
16
+
17
+ delegate :qualities, to: :parent, allow_nil: true
18
+
19
+ def initialize(parent, path)
20
+ @parent = parent
21
+ @path = path
22
+ end
23
+
24
+ def name
25
+ @name ||= File.basename(path)
26
+ end
27
+
28
+ def photos
29
+ @photos ||= Dir.entries(path)
30
+ .reject { |file| ['.', '..'].include?(file) }
31
+ .map { |file| File.join(path, file) }
32
+ .reject { |file| !File.file?(file) }
33
+ .reject { |file| !FileMagic.new(FileMagic::MAGIC_MIME).file(file).match(formats) }
34
+ .map { |file| Photo.new(self, file) }
35
+ end
36
+
37
+ private
38
+
39
+ attr_reader :path,
40
+ :parent
41
+
42
+ alias_method :base_url_name, :name
43
+
44
+ def album_class
45
+ self.class
46
+ end
47
+
48
+ def url_end
49
+ 'index.html'
50
+ end
51
+
52
+ def formats
53
+ Regexp.union([
54
+ /image/i
55
+ ])
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,37 @@
1
+ require 'photish/gallery/album'
2
+ require 'photish/gallery/traits/albumable'
3
+ require 'photish/gallery/traits/metadatable'
4
+
5
+ module Photish
6
+ module Gallery
7
+ class Collection
8
+
9
+ include ::Photish::Gallery::Traits::Urlable
10
+ include ::Photish::Gallery::Traits::Albumable
11
+ include ::Photish::Gallery::Traits::Metadatable
12
+
13
+ attr_reader :qualities
14
+
15
+ def initialize(path, qualities)
16
+ @path = path
17
+ @qualities = qualities
18
+ end
19
+
20
+ def base_url_parts
21
+ []
22
+ end
23
+
24
+ private
25
+
26
+ attr_reader :path
27
+
28
+ def album_class
29
+ Album
30
+ end
31
+
32
+ def url_end
33
+ 'index.html'
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,50 @@
1
+ require 'active_support'
2
+ require 'active_support/core_ext'
3
+
4
+ module Photish
5
+ module Gallery
6
+ class Image
7
+
8
+ include ::Photish::Gallery::Traits::Urlable
9
+
10
+ delegate :name,
11
+ :params,
12
+ to: :quality, prefix: true, allow_nil: true
13
+
14
+ attr_reader :path
15
+
16
+ def initialize(parent, path, quality)
17
+ @parent = parent
18
+ @path = path
19
+ @quality = quality
20
+ end
21
+
22
+ def name
23
+ @name ||= "#{basename} #{quality_name}"
24
+ end
25
+
26
+ private
27
+
28
+ attr_reader :parent,
29
+ :quality
30
+
31
+ alias_method :base_url_name, :name
32
+
33
+ def url_end
34
+ "#{slugify(basename)}-#{slugify(quality_name)}#{extension}"
35
+ end
36
+
37
+ def basename
38
+ @basename ||= File.basename(path, '.*')
39
+ end
40
+
41
+ def extension
42
+ @extentsion ||= File.extname(path)
43
+ end
44
+
45
+ def base_url_name
46
+ 'images'
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,46 @@
1
+ require 'photish/gallery/traits/urlable'
2
+ require 'photish/gallery/traits/metadatable'
3
+ require 'photish/gallery/image'
4
+ require 'active_support'
5
+ require 'active_support/core_ext'
6
+ require 'mini_exiftool'
7
+
8
+ module Photish
9
+ module Gallery
10
+ class Photo
11
+
12
+ include ::Photish::Gallery::Traits::Urlable
13
+ include ::Photish::Gallery::Traits::Metadatable
14
+
15
+ delegate :qualities, to: :parent, allow_nil: true
16
+
17
+ def initialize(parent, path)
18
+ @parent = parent
19
+ @path = path
20
+ end
21
+
22
+ def name
23
+ @name ||= File.basename(path, '.*')
24
+ end
25
+
26
+ def images
27
+ qualities.map { |quality| Photish::Gallery::Image.new(self, path, quality) }
28
+ end
29
+
30
+ def exif
31
+ MiniExiftool.new(path)
32
+ end
33
+
34
+ private
35
+
36
+ attr_reader :path,
37
+ :parent
38
+
39
+ alias_method :base_url_name, :name
40
+
41
+ def url_end
42
+ 'index.html'
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,30 @@
1
+ module Photish
2
+ module Gallery
3
+ module Traits
4
+ module Albumable
5
+ def albums
6
+ @albums ||= Dir.entries(path)
7
+ .reject { |file| ['.', '..'].include?(file) }
8
+ .map { |file| File.join(path, file) }
9
+ .reject { |file| !Dir.exist?(file) }
10
+ .map { |file| album_class.new(self, file) }
11
+ end
12
+
13
+ def all_albums
14
+ albums.map { |album| [album] + album.all_albums }
15
+ .flatten
16
+ end
17
+
18
+ def all_photos
19
+ all_albums.map(&:photos)
20
+ .flatten
21
+ end
22
+
23
+ def all_images
24
+ all_photos.map(&:images)
25
+ .flatten
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,33 @@
1
+ require 'yaml'
2
+ require 'recursive_open_struct'
3
+
4
+ module Photish
5
+ module Gallery
6
+ module Traits
7
+ module Metadatable
8
+ def metadata
9
+ return unless File.exists?(metadata_file)
10
+ RecursiveOpenStruct.new(YAML.load_file(metadata_file))
11
+ end
12
+
13
+ private
14
+
15
+ def basename
16
+ File.basename(path, extname)
17
+ end
18
+
19
+ def extname
20
+ File.extname(path)
21
+ end
22
+
23
+ def dirname
24
+ File.dirname(path)
25
+ end
26
+
27
+ def metadata_file
28
+ File.join(dirname, basename + '.yml')
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,27 @@
1
+ require 'cgi'
2
+
3
+ module Photish
4
+ module Gallery
5
+ module Traits
6
+ module Urlable
7
+ def url
8
+ '/' + url_parts.join('/')
9
+ end
10
+
11
+ def url_parts
12
+ base_url_parts + [url_end]
13
+ end
14
+
15
+ def base_url_parts
16
+ parent.base_url_parts + [slugify(base_url_name)]
17
+ end
18
+
19
+ private
20
+
21
+ def slugify(word)
22
+ CGI.escape(word.downcase.gsub(' ', '-'))
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,71 @@
1
+ require 'photish/log'
2
+ require 'photish/config/app_settings'
3
+ require 'photish/gallery/collection'
4
+ require 'photish/render/site'
5
+
6
+ module Photish
7
+ class Generation
8
+ include Photish::Log
9
+
10
+ def initialize(runtime_config)
11
+ @config = Photish::Config::AppSettings.new(runtime_config)
12
+ .config
13
+ end
14
+
15
+ def execute
16
+ log_important_config_values
17
+ log_album_and_photo_names
18
+ render_whole_site
19
+ log 'Site generation completed successfully'
20
+ end
21
+
22
+ private
23
+
24
+ attr_reader :config
25
+
26
+ def log_important_config_values
27
+ log "Photo directory: #{photo_dir}"
28
+ log "Site directory: #{site_dir}"
29
+ log "Output directory: #{output_dir}"
30
+ end
31
+
32
+ def log_album_and_photo_names
33
+ collection.albums.each do |album|
34
+ log album.name
35
+ log album.photos.map(&:name)
36
+ end
37
+ end
38
+
39
+ def render_whole_site
40
+ Photish::Render::Site.new(templates,
41
+ site_dir,
42
+ output_dir)
43
+ .all_for(collection)
44
+ end
45
+
46
+ def photo_dir
47
+ config.val(:photo_dir)
48
+ end
49
+
50
+ def output_dir
51
+ config.val(:output_dir)
52
+ end
53
+
54
+ def site_dir
55
+ config.val(:site_dir)
56
+ end
57
+
58
+ def collection
59
+ @collection ||= Gallery::Collection.new(photo_dir, qualities)
60
+ end
61
+
62
+ def qualities
63
+ config.val(:qualities)
64
+ .map { |quality| OpenStruct.new(quality) }
65
+ end
66
+
67
+ def templates
68
+ OpenStruct.new(config.val(:templates))
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,35 @@
1
+ require 'webrick'
2
+
3
+ module Photish
4
+ class Host
5
+ include Photish::Log
6
+
7
+ def initialize(runtime_config)
8
+ @config = Photish::Config::AppSettings.new(runtime_config)
9
+ .config
10
+ end
11
+
12
+ def execute
13
+ trap 'INT' do server.shutdown end
14
+ server.start
15
+ log "Site is running at 0.0.0.0:#{port}"
16
+ end
17
+
18
+ private
19
+
20
+ attr_reader :config
21
+
22
+ def server
23
+ @server ||= WEBrick::HTTPServer.new(Port: port,
24
+ DocumentRoot: output_dir)
25
+ end
26
+
27
+ def port
28
+ config.val(:port)
29
+ end
30
+
31
+ def output_dir
32
+ config.val(:output_dir)
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,7 @@
1
+ module Photish
2
+ module Log
3
+ def log(message)
4
+ puts "#{Time.now.iso8601} => #{message}"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,32 @@
1
+ require 'mini_magick'
2
+
3
+ module Photish
4
+ module Render
5
+ class ImageConversion
6
+
7
+ include Photish::Log
8
+
9
+ def initialize(output_dir)
10
+ @output_dir = output_dir
11
+ end
12
+
13
+ def render(images)
14
+ Array(images).each do |image|
15
+ output_file = File.join(output_dir, image.url_parts)
16
+ FileUtils.mkdir_p(File.join(output_dir, image.base_url_parts))
17
+
18
+ MiniMagick::Tool::Convert.new do |convert|
19
+ convert << image.path
20
+ convert.merge!(image.quality_params)
21
+ convert << output_file
22
+ log "Performing image conversion #{convert.command}"
23
+ end
24
+ end
25
+ end
26
+
27
+ private
28
+
29
+ attr_reader :output_dir
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,53 @@
1
+ require 'tilt'
2
+
3
+ module Photish
4
+ module Render
5
+ class Page
6
+
7
+ include Photish::Log
8
+
9
+ def initialize(layout_file, template_file, output_dir)
10
+ @layout_file = layout_file
11
+ @template_file = template_file
12
+ @output_dir = output_dir
13
+ end
14
+
15
+ def render(models)
16
+ Array(models).each do |model|
17
+ rendered_model = render_template_and_layout(model)
18
+ output_model_file = relative_to_output_dir(model.url_parts)
19
+ output_model_dir = relative_to_output_dir(model.base_url_parts)
20
+
21
+ log "Rendering #{model.url} with template #{template_file} to #{output_model_file}"
22
+
23
+ FileUtils.mkdir_p(output_model_dir)
24
+ File.write(output_model_file, rendered_model)
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ attr_reader :template_file,
31
+ :layout_file,
32
+ :output_dir
33
+
34
+ def relative_to_output_dir(url_parts)
35
+ File.join(output_dir, url_parts)
36
+ end
37
+
38
+ def render_template_and_layout(model)
39
+ layout.render(model) do
40
+ template.render(model)
41
+ end
42
+ end
43
+
44
+ def template
45
+ @template ||= Tilt.new(template_file)
46
+ end
47
+
48
+ def layout
49
+ @layout ||= Tilt.new(layout_file)
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,75 @@
1
+ require 'photish/render/page'
2
+ require 'photish/render/image_conversion'
3
+
4
+ module Photish
5
+ module Render
6
+ class Site
7
+ def initialize(templates, site_dir, output_dir)
8
+ @templates = templates
9
+ @site_dir = site_dir
10
+ @output_dir = output_dir
11
+ end
12
+
13
+ def all_for(collection)
14
+ move_non_ignored_site_contents
15
+
16
+ collection_template.render(collection)
17
+ album_template.render(collection.all_albums)
18
+ photo_template.render(collection.all_photos)
19
+
20
+ image_conversion.render(collection.all_images)
21
+ end
22
+
23
+ private
24
+
25
+ attr_reader :templates,
26
+ :site_dir,
27
+ :output_dir
28
+
29
+ def move_non_ignored_site_contents
30
+ FileUtils.mkdir_p(output_dir)
31
+ FileUtils.cp_r(non_ignored_site_contents, output_dir)
32
+ end
33
+
34
+ def image_conversion
35
+ Photish::Render::ImageConversion.new(output_dir)
36
+ end
37
+
38
+ def album_template
39
+ Photish::Render::Page.new(layout_file, template_album_file, output_dir)
40
+ end
41
+
42
+ def photo_template
43
+ Photish::Render::Page.new(layout_file, template_photo_file, output_dir)
44
+ end
45
+
46
+ def collection_template
47
+ Photish::Render::Page.new(layout_file, template_collection_file, output_dir)
48
+ end
49
+
50
+ def non_ignored_site_contents
51
+ Dir.glob(File.join(site_dir, '[!_]*'))
52
+ end
53
+
54
+ def layout_file
55
+ File.join(site_dir, templates_dir, templates.layout)
56
+ end
57
+
58
+ def template_collection_file
59
+ File.join(site_dir, templates_dir, templates.collection)
60
+ end
61
+
62
+ def template_album_file
63
+ File.join(site_dir, templates_dir, templates.album)
64
+ end
65
+
66
+ def template_photo_file
67
+ File.join(site_dir, templates_dir, templates.photo)
68
+ end
69
+
70
+ def templates_dir
71
+ '_templates'
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,3 @@
1
+ module Photish
2
+ VERSION = "0.1.0"
3
+ end
data/lib/photish.rb ADDED
@@ -0,0 +1,4 @@
1
+ require "photish/version"
2
+
3
+ module Photish
4
+ end
data/photish.gemspec ADDED
@@ -0,0 +1,39 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'photish/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "photish"
8
+ spec.version = Photish::VERSION
9
+ spec.authors = ["Henry Lawson"]
10
+ spec.email = ["henry.lawson@foinq.com"]
11
+
12
+ spec.summary = %q{A static photo site generator}
13
+ spec.description = %q{Using a collection of photos grouped by folder, photish will generate a the website content using templates that you provide.}
14
+ spec.homepage = "https://github.com/henrylawson/photish"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.bindir = "exe"
19
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_dependency "thor"
23
+ spec.add_dependency "activesupport"
24
+ spec.add_dependency "slim"
25
+ spec.add_dependency "tilt"
26
+ spec.add_dependency "mini_magick"
27
+ spec.add_dependency "ruby-filemagic"
28
+ spec.add_dependency "anemone"
29
+ spec.add_dependency "mini_exiftool"
30
+ spec.add_dependency "recursive-open-struct"
31
+
32
+ spec.add_development_dependency "bundler", "~> 1.10"
33
+ spec.add_development_dependency "rake", "~> 10.0"
34
+ spec.add_development_dependency "rspec"
35
+ spec.add_development_dependency "cucumber"
36
+ spec.add_development_dependency "aruba"
37
+ spec.add_development_dependency "pry"
38
+ spec.add_development_dependency "retriable"
39
+ end
metadata ADDED
@@ -0,0 +1,304 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: photish
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Henry Lawson
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2015-11-22 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: thor
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: activesupport
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: slim
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: tilt
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: mini_magick
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: ruby-filemagic
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: anemone
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: mini_exiftool
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: recursive-open-struct
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: bundler
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: '1.10'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: '1.10'
153
+ - !ruby/object:Gem::Dependency
154
+ name: rake
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "~>"
158
+ - !ruby/object:Gem::Version
159
+ version: '10.0'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - "~>"
165
+ - !ruby/object:Gem::Version
166
+ version: '10.0'
167
+ - !ruby/object:Gem::Dependency
168
+ name: rspec
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
181
+ - !ruby/object:Gem::Dependency
182
+ name: cucumber
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - ">="
186
+ - !ruby/object:Gem::Version
187
+ version: '0'
188
+ type: :development
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - ">="
193
+ - !ruby/object:Gem::Version
194
+ version: '0'
195
+ - !ruby/object:Gem::Dependency
196
+ name: aruba
197
+ requirement: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - ">="
200
+ - !ruby/object:Gem::Version
201
+ version: '0'
202
+ type: :development
203
+ prerelease: false
204
+ version_requirements: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - ">="
207
+ - !ruby/object:Gem::Version
208
+ version: '0'
209
+ - !ruby/object:Gem::Dependency
210
+ name: pry
211
+ requirement: !ruby/object:Gem::Requirement
212
+ requirements:
213
+ - - ">="
214
+ - !ruby/object:Gem::Version
215
+ version: '0'
216
+ type: :development
217
+ prerelease: false
218
+ version_requirements: !ruby/object:Gem::Requirement
219
+ requirements:
220
+ - - ">="
221
+ - !ruby/object:Gem::Version
222
+ version: '0'
223
+ - !ruby/object:Gem::Dependency
224
+ name: retriable
225
+ requirement: !ruby/object:Gem::Requirement
226
+ requirements:
227
+ - - ">="
228
+ - !ruby/object:Gem::Version
229
+ version: '0'
230
+ type: :development
231
+ prerelease: false
232
+ version_requirements: !ruby/object:Gem::Requirement
233
+ requirements:
234
+ - - ">="
235
+ - !ruby/object:Gem::Version
236
+ version: '0'
237
+ description: Using a collection of photos grouped by folder, photish will generate
238
+ a the website content using templates that you provide.
239
+ email:
240
+ - henry.lawson@foinq.com
241
+ executables:
242
+ - photish
243
+ extensions: []
244
+ extra_rdoc_files: []
245
+ files:
246
+ - ".gitignore"
247
+ - ".rspec"
248
+ - ".travis.yml"
249
+ - CODE_OF_CONDUCT.md
250
+ - Gemfile
251
+ - LICENSE.txt
252
+ - README.md
253
+ - Rakefile
254
+ - TODO.md
255
+ - bin/console
256
+ - bin/setup
257
+ - exe/photish
258
+ - lib/photish.rb
259
+ - lib/photish/cli.rb
260
+ - lib/photish/config/app_settings.rb
261
+ - lib/photish/config/default_config.rb
262
+ - lib/photish/config/file_config.rb
263
+ - lib/photish/config/location.rb
264
+ - lib/photish/config/settings.rb
265
+ - lib/photish/gallery/album.rb
266
+ - lib/photish/gallery/collection.rb
267
+ - lib/photish/gallery/image.rb
268
+ - lib/photish/gallery/photo.rb
269
+ - lib/photish/gallery/traits/albumable.rb
270
+ - lib/photish/gallery/traits/metadatable.rb
271
+ - lib/photish/gallery/traits/urlable.rb
272
+ - lib/photish/generation.rb
273
+ - lib/photish/host.rb
274
+ - lib/photish/log.rb
275
+ - lib/photish/render/image_conversion.rb
276
+ - lib/photish/render/page.rb
277
+ - lib/photish/render/site.rb
278
+ - lib/photish/version.rb
279
+ - photish.gemspec
280
+ homepage: https://github.com/henrylawson/photish
281
+ licenses:
282
+ - MIT
283
+ metadata: {}
284
+ post_install_message:
285
+ rdoc_options: []
286
+ require_paths:
287
+ - lib
288
+ required_ruby_version: !ruby/object:Gem::Requirement
289
+ requirements:
290
+ - - ">="
291
+ - !ruby/object:Gem::Version
292
+ version: '0'
293
+ required_rubygems_version: !ruby/object:Gem::Requirement
294
+ requirements:
295
+ - - ">="
296
+ - !ruby/object:Gem::Version
297
+ version: '0'
298
+ requirements: []
299
+ rubyforge_project:
300
+ rubygems_version: 2.4.5
301
+ signing_key:
302
+ specification_version: 4
303
+ summary: A static photo site generator
304
+ test_files: []