gallerist 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +2 -0
- data/CONTRIBUTING.md +53 -0
- data/Gemfile +8 -0
- data/LICENSE +25 -0
- data/README.md +57 -0
- data/Rakefile +16 -0
- data/assets/stylesheets/main.scss +17 -0
- data/bin/gallerist +59 -0
- data/config.ru +21 -0
- data/gallerist.gemspec +32 -0
- data/lib/gallerist.rb +46 -0
- data/lib/gallerist/app.rb +230 -0
- data/lib/gallerist/errors.rb +12 -0
- data/lib/gallerist/helpers.rb +72 -0
- data/lib/gallerist/library.rb +100 -0
- data/lib/gallerist/middleware/raise_warmup_exceptions.rb +24 -0
- data/lib/gallerist/middleware/show_exceptions.rb +40 -0
- data/lib/gallerist/models/admin_data.rb +10 -0
- data/lib/gallerist/models/album.rb +30 -0
- data/lib/gallerist/models/album_photo.rb +20 -0
- data/lib/gallerist/models/base_model.rb +32 -0
- data/lib/gallerist/models/image_proxies_model.rb +11 -0
- data/lib/gallerist/models/image_proxy_state.rb +22 -0
- data/lib/gallerist/models/master.rb +25 -0
- data/lib/gallerist/models/model_resource.rb +22 -0
- data/lib/gallerist/models/person.rb +46 -0
- data/lib/gallerist/models/person_model.rb +10 -0
- data/lib/gallerist/models/person_photo.rb +39 -0
- data/lib/gallerist/models/photo.rb +100 -0
- data/lib/gallerist/models/tag.rb +31 -0
- data/lib/gallerist/models/tag_photo.rb +20 -0
- data/lib/rack/handler/unicorn.rb +34 -0
- data/views/500.erb +5 -0
- data/views/album.erb +9 -0
- data/views/index.erb +24 -0
- data/views/layout.erb +34 -0
- data/views/partials/thumbnail.erb +13 -0
- data/views/person.erb +9 -0
- data/views/photos.erb +9 -0
- data/views/tag.erb +9 -0
- metadata +183 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: ff2b65d33304727eae500b7fc80f7de3b925c9e9
|
4
|
+
data.tar.gz: 4725ef924d8903081662a61279c01fec06343499
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 16b0d2f8928d41365189e1159e59eae1a37b2256bfbfbd4c3aa28a0d87bc2a7405ba49d5d3c2c0d26876e7d5c7567b8de21d1349e16d043d9d0d350d6a2880f7
|
7
|
+
data.tar.gz: 8f3a100f666ffe5c626c9ca231b1b36cdbaaa402a52c83e0a105af6c3f676227bc07c159810923524b5e6ea84be02f2d0cd91c1dbbe4d9e68900511eed671352
|
data/.gitignore
ADDED
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
Contribution Guidelines
|
2
|
+
=======================
|
3
|
+
|
4
|
+
First of all, each single contribution is appreciated, whether a typo fix,
|
5
|
+
improved documentation, a fixed bug or a whole new feature.
|
6
|
+
|
7
|
+
## Making your changes
|
8
|
+
|
9
|
+
1. Fork the repository on GitHub
|
10
|
+
2. Create a topic branch with a descriptive name, e.g. `fix-issue-123` or
|
11
|
+
`feature-x`
|
12
|
+
3. Make your modifications, complying with the
|
13
|
+
[code conventions](#code-conventions)
|
14
|
+
4. Commit small logical changes, each with a descriptive commit message.
|
15
|
+
Please don˚t mix unrelated changes in a single commit.
|
16
|
+
5. Don˚t commit things that are unrelated to the whole change.
|
17
|
+
|
18
|
+
## Commit messages
|
19
|
+
|
20
|
+
Please format your commit messages as follows:
|
21
|
+
|
22
|
+
Short summary of the change (up to 50 characters)
|
23
|
+
|
24
|
+
Optionally add a more extensive description of your change after a
|
25
|
+
blank line. Wrap the lines in this and the following paragraphs after
|
26
|
+
72 characters.
|
27
|
+
|
28
|
+
## Submitting your changes
|
29
|
+
|
30
|
+
1. Push your changes to a topic branch in your fork of the repository.
|
31
|
+
2. [Submit a pull request][pr] to the original repository.
|
32
|
+
Describe your changes as short as possible, but as detailed as needed for
|
33
|
+
others to get an overview of your modifications.
|
34
|
+
|
35
|
+
## Code conventions
|
36
|
+
|
37
|
+
* White spaces:
|
38
|
+
* Indent using 2 spaces
|
39
|
+
* Line endings must be line feeds (\n)
|
40
|
+
* Add a newline at the end of a file
|
41
|
+
* Name conventions:
|
42
|
+
* `UpperCamelCase` for classes and modules
|
43
|
+
* `lower_case` for variables and methods
|
44
|
+
* `UPPER_CASE` for constants
|
45
|
+
|
46
|
+
## Further information
|
47
|
+
|
48
|
+
* [General GitHub documentation][gh-help]
|
49
|
+
* [GitHub pull request documentation][gh-pr]
|
50
|
+
|
51
|
+
[gh-help]: https://help.github.com
|
52
|
+
[gh-pr]: https://help.github.com/send-pull-requests
|
53
|
+
[pr]: https://github.com/koraktor/gallerist/pull/new
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
Copyright (c) 2015, Sebastian Staudt
|
2
|
+
All rights reserved.
|
3
|
+
|
4
|
+
Redistribution and use in source and binary forms, with or without modification,
|
5
|
+
are permitted provided that the following conditions are met:
|
6
|
+
|
7
|
+
* Redistributions of source code must retain the above copyright notice,
|
8
|
+
this list of conditions and the following disclaimer.
|
9
|
+
* Redistributions in binary form must reproduce the above copyright notice,
|
10
|
+
this list of conditions and the following disclaimer in the documentation
|
11
|
+
and/or other materials provided with the distribution.
|
12
|
+
* Neither the name of the author nor the names of its contributors
|
13
|
+
may be used to endorse or promote products derived from this software
|
14
|
+
without specific prior written permission.
|
15
|
+
|
16
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
17
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
18
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
19
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
20
|
+
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
21
|
+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
22
|
+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
23
|
+
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
24
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
25
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/README.md
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
Gallerist
|
2
|
+
=========
|
3
|
+
|
4
|
+
Gallerist is a web application to browse libraries of Apple Photos and iPhoto.
|
5
|
+
It is built on top of [Sinatra][sinatra].
|
6
|
+
|
7
|
+
## Requirements
|
8
|
+
|
9
|
+
* One or more Photos or iPhoto libraries (`.photoslibrary` or `.photolibrary`
|
10
|
+
directories)
|
11
|
+
* Ruby 2.x with Bundler
|
12
|
+
|
13
|
+
OS X 10.9 and above ship with Ruby 2.0. You will only have to install Bundler
|
14
|
+
(`gem install bundler`) to get started.
|
15
|
+
|
16
|
+
## Installation
|
17
|
+
|
18
|
+
Gallerist can be simply installed as a Ruby gem.
|
19
|
+
|
20
|
+
```shell
|
21
|
+
$ gem install gallerist
|
22
|
+
```
|
23
|
+
|
24
|
+
*Note*: You might need to use `sudo` if you’re installing into your system
|
25
|
+
Ruby, e.g. when not using rbenv or RVM.
|
26
|
+
|
27
|
+
If you want to run the current development code please use Git to clone the
|
28
|
+
repository.
|
29
|
+
|
30
|
+
## Usage
|
31
|
+
|
32
|
+
```shell
|
33
|
+
$ bin/gallerist ~/Pictures/Photos\ Library.photoslibrary
|
34
|
+
```
|
35
|
+
|
36
|
+
After that the application is served on port 9292 by default. You can open it
|
37
|
+
by simply browsing to `http://localhost:9292`.
|
38
|
+
|
39
|
+
Further command-line arguments are available, see `gallerist --help` for more
|
40
|
+
information.
|
41
|
+
|
42
|
+
## Caveats
|
43
|
+
|
44
|
+
* iPhoto libraries work to a certain degree as iPhoto’s events are not
|
45
|
+
listed, only albums.
|
46
|
+
* Gallerist works on a copy of the library databases, i.e. changes to the
|
47
|
+
original library will not be reflected instantly. You will have to restart
|
48
|
+
the web app first.
|
49
|
+
|
50
|
+
## Future plans
|
51
|
+
|
52
|
+
* Support for internal categories like photo stream and videos
|
53
|
+
* Support for moments and places
|
54
|
+
* Performance improvements
|
55
|
+
|
56
|
+
[brew]: http://brew.sh
|
57
|
+
[sinatra]: http://www.sinatrarb.com
|
data/Rakefile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# This code is free software; you can redistribute it and/or modify it under
|
2
|
+
# the terms of the new BSD License.
|
3
|
+
#
|
4
|
+
# Copyright (c) 2015, Sebastian Staudt
|
5
|
+
|
6
|
+
require 'rubygems/package_task'
|
7
|
+
|
8
|
+
spec = Gem::Specification.load 'gallerist.gemspec'
|
9
|
+
Gem::PackageTask.new spec do |pkg|
|
10
|
+
end
|
11
|
+
|
12
|
+
# Task to clean the package directory
|
13
|
+
desc 'Clean package directory'
|
14
|
+
task :clean do
|
15
|
+
FileUtils.rm_rf 'pkg'
|
16
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
/**
|
2
|
+
* This code is free software; you can redistribute it and/or modify it under
|
3
|
+
* the terms of the new BSD License.
|
4
|
+
*
|
5
|
+
* Copyright (c) 2015, Sebastian Staudt
|
6
|
+
*/
|
7
|
+
|
8
|
+
@import 'bootstrap';
|
9
|
+
|
10
|
+
.navbar-inverse .navbar-brand:hover {
|
11
|
+
color: $navbar-inverse-brand-color;
|
12
|
+
}
|
13
|
+
|
14
|
+
.tag {
|
15
|
+
display: inline-block;
|
16
|
+
margin-right: 1pt;
|
17
|
+
}
|
data/bin/gallerist
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This code is free software; you can redistribute it and/or modify it under
|
4
|
+
# the terms of the new BSD License.
|
5
|
+
#
|
6
|
+
# Copyright (c) 2015, Sebastian Staudt
|
7
|
+
|
8
|
+
require 'optparse'
|
9
|
+
require 'rack'
|
10
|
+
|
11
|
+
ENV['RACK_ENV'] ||= 'production'
|
12
|
+
|
13
|
+
server_options = { port: 9292 }
|
14
|
+
opts = OptionParser.new do |opts|
|
15
|
+
opts.banner = 'Usage: gallerist [options] <library>'
|
16
|
+
|
17
|
+
opts.separator ''
|
18
|
+
opts.separator 'Options:'
|
19
|
+
opts.on('-p', '--port PORT', 'Specify on which port to listen') do |port|
|
20
|
+
server_options[:port] = port
|
21
|
+
end
|
22
|
+
opts.on('-d', '--debug', 'Enable debug mode') do
|
23
|
+
ENV['RACK_ENV'] = 'development'
|
24
|
+
end
|
25
|
+
|
26
|
+
opts.separator ''
|
27
|
+
opts.separator 'Arguments:'
|
28
|
+
opts.separator opts.summary_indent + '<library> The path to the photo library to open.'
|
29
|
+
|
30
|
+
opts.separator ''
|
31
|
+
opts.separator 'Advanced options:'
|
32
|
+
opts.on('-n', '--no-copy', 'Disable temporary copies of the library databases') do
|
33
|
+
ENV['GALLERIST_NOCOPY'] = 'true'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
opts.parse!
|
37
|
+
|
38
|
+
$LOAD_PATH << File.join(__dir__, '..', 'lib')
|
39
|
+
|
40
|
+
require 'gallerist'
|
41
|
+
|
42
|
+
config_path = File.expand_path File.join(__dir__, '..', 'config.ru')
|
43
|
+
|
44
|
+
ENV['GALLERIST_LIBRARY'] = ARGV[0]
|
45
|
+
|
46
|
+
if ENV['GALLERIST_LIBRARY'].nil?
|
47
|
+
puts opts.help
|
48
|
+
exit 1
|
49
|
+
end
|
50
|
+
|
51
|
+
begin
|
52
|
+
Rack::Server.start config: config_path,
|
53
|
+
server: :unicorn,
|
54
|
+
Port: server_options[:port],
|
55
|
+
worker_processes: 4
|
56
|
+
rescue Gallerist::LibraryInUseError
|
57
|
+
$stderr.puts 'The library is currently in use.' <<
|
58
|
+
' Is it currently opened in Photos?'
|
59
|
+
end
|
data/config.ru
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# This code is free software; you can redistribute it and/or modify it under
|
2
|
+
# the terms of the new BSD License.
|
3
|
+
#
|
4
|
+
# Copyright (c) 2015, Sebastian Staudt
|
5
|
+
|
6
|
+
unless defined? Gallerist
|
7
|
+
$LOAD_PATH << File.join(__dir__, 'lib')
|
8
|
+
require 'gallerist'
|
9
|
+
end
|
10
|
+
|
11
|
+
warmup do |app|
|
12
|
+
Rack::MockRequest.new(app).get '/',
|
13
|
+
'rack.errors' => $stderr,
|
14
|
+
'rack.warmup' => true
|
15
|
+
end
|
16
|
+
|
17
|
+
map '/assets' do
|
18
|
+
run Gallerist::App.sprockets
|
19
|
+
end
|
20
|
+
|
21
|
+
run Gallerist::App
|
data/gallerist.gemspec
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# This code is free software; you can redistribute it and/or modify it under
|
2
|
+
# the terms of the new BSD License.
|
3
|
+
#
|
4
|
+
# Copyright (c) 2015, Sebastian Staudt
|
5
|
+
|
6
|
+
$LOAD_PATH << File.join(__dir__, 'lib')
|
7
|
+
|
8
|
+
require 'gallerist'
|
9
|
+
|
10
|
+
Gem::Specification.new do |s|
|
11
|
+
s.name = 'gallerist'
|
12
|
+
s.version = Gallerist::VERSION
|
13
|
+
s.platform = Gem::Platform::RUBY
|
14
|
+
s.authors = [ 'Sebastian Staudt' ]
|
15
|
+
s.email = [ 'koraktor@gmail.com' ]
|
16
|
+
s.homepage = 'https://github.com/koraktor/gallerist'
|
17
|
+
s.license = 'BSD'
|
18
|
+
s.summary = 'A web application to browse Apple Photos and iPhoto libraries'
|
19
|
+
s.description = 'View Photos and iPhoto libraries in your browser'
|
20
|
+
|
21
|
+
s.add_dependency 'activerecord', '~> 4.2'
|
22
|
+
s.add_dependency 'bootstrap-sass', '~> 3.3'
|
23
|
+
s.add_dependency 'rack', '~> 1.6'
|
24
|
+
s.add_dependency 'sinatra', '~> 1.4'
|
25
|
+
s.add_dependency 'sprockets-helpers', '~> 1.1'
|
26
|
+
s.add_dependency 'sqlite3', '~> 1.3'
|
27
|
+
s.add_dependency 'unicorn', '~> 4.8'
|
28
|
+
|
29
|
+
s.executables = [ 'gallerist' ]
|
30
|
+
s.files = `git ls-files`.split
|
31
|
+
s.require_paths = 'lib'
|
32
|
+
end
|
data/lib/gallerist.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
# This code is free software; you can redistribute it and/or modify it under
|
2
|
+
# the terms of the new BSD License.
|
3
|
+
#
|
4
|
+
# Copyright (c) 2015, Sebastian Staudt
|
5
|
+
|
6
|
+
module Gallerist
|
7
|
+
|
8
|
+
VERSION = '0.1.0'
|
9
|
+
|
10
|
+
autoload :App, 'gallerist/app'
|
11
|
+
autoload :Helpers, 'gallerist/helpers'
|
12
|
+
autoload :Library, 'gallerist/library'
|
13
|
+
autoload :LibraryInUseError, 'gallerist/errors'
|
14
|
+
autoload :RaiseWarmupExceptions, 'gallerist/middleware/raise_warmup_exceptions'
|
15
|
+
autoload :ShowExceptions, 'gallerist/middleware/show_exceptions'
|
16
|
+
|
17
|
+
# Models
|
18
|
+
|
19
|
+
MODELS = {}
|
20
|
+
|
21
|
+
def self.model(name, file)
|
22
|
+
autoload name, file
|
23
|
+
|
24
|
+
MODELS[name] = file
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.load_models
|
28
|
+
MODELS.values.each { |file| require file }
|
29
|
+
end
|
30
|
+
|
31
|
+
model :AdminData, 'gallerist/models/admin_data'
|
32
|
+
model :Album, 'gallerist/models/album'
|
33
|
+
model :AlbumPhoto, 'gallerist/models/album_photo'
|
34
|
+
model :BaseModel, 'gallerist/models/base_model'
|
35
|
+
model :ImageProxiesModel, 'gallerist/models/image_proxies_model'
|
36
|
+
model :ImageProxyState, 'gallerist/models/image_proxy_state'
|
37
|
+
model :Master, 'gallerist/models/master'
|
38
|
+
model :ModelResource, 'gallerist/models/model_resource'
|
39
|
+
model :Person, 'gallerist/models/person'
|
40
|
+
model :PersonModel, 'gallerist/models/person_model'
|
41
|
+
model :PersonPhoto, 'gallerist/models/person_photo'
|
42
|
+
model :Photo, 'gallerist/models/photo'
|
43
|
+
model :Tag, 'gallerist/models/tag'
|
44
|
+
model :TagPhoto, 'gallerist/models/tag_photo'
|
45
|
+
|
46
|
+
end
|
@@ -0,0 +1,230 @@
|
|
1
|
+
# This code is free software; you can redistribute it and/or modify it under
|
2
|
+
# the terms of the new BSD License.
|
3
|
+
#
|
4
|
+
# Copyright (c) 2015, Sebastian Staudt
|
5
|
+
|
6
|
+
require 'active_record'
|
7
|
+
require 'bootstrap-sass'
|
8
|
+
require 'logger'
|
9
|
+
require 'sinatra/sprockets-helpers'
|
10
|
+
|
11
|
+
class Gallerist::App < Sinatra::Base
|
12
|
+
|
13
|
+
register Sinatra::Sprockets::Helpers
|
14
|
+
|
15
|
+
configure do
|
16
|
+
enable :logging
|
17
|
+
|
18
|
+
set :root, File.join(root, '..', '..')
|
19
|
+
|
20
|
+
set :library_path, ENV['GALLERIST_LIBRARY']
|
21
|
+
set :copy_dbs, !ENV['GALLERIST_NOCOPY']
|
22
|
+
set :views, File.join(root, 'views')
|
23
|
+
|
24
|
+
set :sprockets, Sprockets::Environment.new(root)
|
25
|
+
|
26
|
+
sprockets.append_path File.join(root, 'assets', 'stylesheets')
|
27
|
+
sprockets.cache = Sprockets::Cache::FileStore.new Dir.tmpdir
|
28
|
+
sprockets.css_compressor = :scss
|
29
|
+
|
30
|
+
configure_sprockets_helpers do |helpers|
|
31
|
+
helpers.debug = development?
|
32
|
+
end
|
33
|
+
|
34
|
+
Bootstrap.load!
|
35
|
+
end
|
36
|
+
|
37
|
+
configure :development do
|
38
|
+
set :logging, ::Logger::DEBUG
|
39
|
+
|
40
|
+
debug_logger = ::Logger.new($stdout, ::Logger::DEBUG)
|
41
|
+
|
42
|
+
sprockets.logger = debug_logger
|
43
|
+
ActiveRecord::Base.logger = debug_logger
|
44
|
+
end
|
45
|
+
|
46
|
+
error 500 do |error|
|
47
|
+
@title = 'Error'
|
48
|
+
|
49
|
+
raise error if env['rack.errors'].is_a? StringIO
|
50
|
+
|
51
|
+
erb :'500'
|
52
|
+
end
|
53
|
+
|
54
|
+
helpers Gallerist::Helpers
|
55
|
+
|
56
|
+
def send_library_file(file, options = {})
|
57
|
+
logger.debug "Serving file '%s' from library..." % [ file ]
|
58
|
+
|
59
|
+
file_path = File.join(library.path, file)
|
60
|
+
response = catch(:halt) { send_file file_path, options }
|
61
|
+
if response == 404
|
62
|
+
logger.error "File '%s' could not be served, because it does not exist." % file
|
63
|
+
end
|
64
|
+
|
65
|
+
halt response
|
66
|
+
end
|
67
|
+
|
68
|
+
def library
|
69
|
+
unless settings.respond_to? :library
|
70
|
+
settings.set :library, Gallerist::Library.new(settings.library_path)
|
71
|
+
|
72
|
+
logger.info "Loading library from \"#{library.path}\""
|
73
|
+
|
74
|
+
if settings.copy_dbs
|
75
|
+
logger.debug 'Creating temporary copy of the main library database...'
|
76
|
+
library.copy_base_db
|
77
|
+
logger.debug ' Completed.'
|
78
|
+
end
|
79
|
+
|
80
|
+
ActiveRecord::Base.establish_connection({
|
81
|
+
adapter: 'sqlite3',
|
82
|
+
database: library.library_db
|
83
|
+
})
|
84
|
+
ActiveRecord::Base.connection.exec_query 'PRAGMA journal_mode="MEMORY";'
|
85
|
+
|
86
|
+
if settings.copy_dbs
|
87
|
+
logger.debug 'Creating temporary copies of additional library databases...'
|
88
|
+
library.copy_extra_dbs
|
89
|
+
logger.debug ' Completed.'
|
90
|
+
end
|
91
|
+
|
92
|
+
logger.info " Found library with type '%s'." % [ library.app_id ]
|
93
|
+
|
94
|
+
Gallerist.load_models
|
95
|
+
Gallerist::BaseModel.descendants.each do |model|
|
96
|
+
logger.debug "Setting up %s for library type '%s'" % [ model, library.type ]
|
97
|
+
|
98
|
+
model.setup_for library.type
|
99
|
+
end
|
100
|
+
|
101
|
+
Gallerist::ImageProxiesModel.establish_connection({
|
102
|
+
adapter: 'sqlite3',
|
103
|
+
database: library.image_proxies_db
|
104
|
+
})
|
105
|
+
Gallerist::ImageProxiesModel.connection.exec_query 'PRAGMA journal_mode="MEMORY";'
|
106
|
+
|
107
|
+
Gallerist::PersonModel.establish_connection({
|
108
|
+
adapter: 'sqlite3',
|
109
|
+
database: library.person_db
|
110
|
+
})
|
111
|
+
Gallerist::PersonModel.connection.exec_query 'PRAGMA journal_mode="MEMORY";'
|
112
|
+
end
|
113
|
+
settings.library
|
114
|
+
end
|
115
|
+
|
116
|
+
def navbar_for(obj)
|
117
|
+
@navbar = [[ '/', library.name ]]
|
118
|
+
|
119
|
+
case obj
|
120
|
+
when :all_photos
|
121
|
+
@navbar << [ '/photos', 'All photos' ]
|
122
|
+
when :favorites
|
123
|
+
@navbar << [ '/favorites', 'Favorites' ]
|
124
|
+
when Gallerist::Album
|
125
|
+
@navbar << [ '/albums', 'Albums' ]
|
126
|
+
@navbar << [ '/albums/%s' % [ obj.id ], obj.name ]
|
127
|
+
when Gallerist::Person
|
128
|
+
@navbar << [ '/persons', 'Persons' ]
|
129
|
+
@navbar << [ '/persons/%s' % [ obj.id ], obj.name ]
|
130
|
+
when Gallerist::Tag
|
131
|
+
@navbar << [ '/tags', 'Tags' ]
|
132
|
+
@navbar << [ '/tags/%s' % [ obj.simple_name ], obj.name ]
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def photo(id)
|
137
|
+
Gallerist::Photo.find id
|
138
|
+
rescue ActiveRecord::RecordNotFound
|
139
|
+
logger.error 'Could not find the photo with ID #%s.' % [ id ]
|
140
|
+
not_found
|
141
|
+
end
|
142
|
+
|
143
|
+
def self.setup_default_middleware(builder)
|
144
|
+
builder.use Sinatra::ExtendedRack
|
145
|
+
builder.use Gallerist::ShowExceptions if show_exceptions?
|
146
|
+
builder.use Gallerist::RaiseWarmupExceptions
|
147
|
+
|
148
|
+
setup_logging builder
|
149
|
+
end
|
150
|
+
|
151
|
+
get '/' do
|
152
|
+
@title = library.name
|
153
|
+
|
154
|
+
@albums = library.albums.visible.nonempty.order :date
|
155
|
+
@persons = library.persons
|
156
|
+
@tags = library.tags.nonempty.order 'photos_count desc'
|
157
|
+
|
158
|
+
navbar_for :root
|
159
|
+
|
160
|
+
erb :index
|
161
|
+
end
|
162
|
+
|
163
|
+
get '/albums/:id' do
|
164
|
+
@album = library.albums.find params[:id]
|
165
|
+
@title = @album.name
|
166
|
+
|
167
|
+
navbar_for @album
|
168
|
+
|
169
|
+
erb :album
|
170
|
+
end
|
171
|
+
|
172
|
+
get '/favorites' do
|
173
|
+
@photos = library.photos.favorites
|
174
|
+
@title = 'Favorites'
|
175
|
+
|
176
|
+
navbar_for :favorites
|
177
|
+
|
178
|
+
erb :photos
|
179
|
+
end
|
180
|
+
|
181
|
+
get '/persons/:id' do
|
182
|
+
@person = library.persons.find params[:id]
|
183
|
+
@title = @person.name
|
184
|
+
|
185
|
+
navbar_for @person
|
186
|
+
|
187
|
+
erb :person
|
188
|
+
end
|
189
|
+
|
190
|
+
get '/photos' do
|
191
|
+
@photos = library.photos
|
192
|
+
@title = 'All photos'
|
193
|
+
|
194
|
+
navbar_for :all_photos
|
195
|
+
|
196
|
+
erb :photos
|
197
|
+
end
|
198
|
+
|
199
|
+
get '/photos/:id' do
|
200
|
+
photo = photo params[:id]
|
201
|
+
|
202
|
+
send_library_file photo.image_path,
|
203
|
+
disposition: :inline,
|
204
|
+
filename: photo.file_name
|
205
|
+
end
|
206
|
+
|
207
|
+
get '/tags/:name' do
|
208
|
+
@tag = library.tags.find_by_simple_name params[:name]
|
209
|
+
@title = @tag.name
|
210
|
+
|
211
|
+
navbar_for @tag
|
212
|
+
|
213
|
+
erb :tag
|
214
|
+
end
|
215
|
+
|
216
|
+
get '/thumbs/:id' do
|
217
|
+
photo = photo params[:id]
|
218
|
+
|
219
|
+
if photo.thumbnail_available?
|
220
|
+
thumbnail_path = photo.small_thumbnail_path
|
221
|
+
else
|
222
|
+
thumbnail_path = photo.preview_path
|
223
|
+
end
|
224
|
+
|
225
|
+
send_library_file thumbnail_path,
|
226
|
+
disposition: :inline,
|
227
|
+
filename: 'thumb_%s' % [ photo.file_name ]
|
228
|
+
end
|
229
|
+
|
230
|
+
end
|