images_gallery 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/lib/images_gallery/cli.rb +4 -4
  3. data/lib/images_gallery/generator.rb +5 -4
  4. data/lib/images_gallery/models/collection.rb +17 -0
  5. data/lib/images_gallery/models/image.rb +21 -0
  6. data/lib/images_gallery/models/source.rb +107 -0
  7. data/lib/images_gallery/version.rb +1 -1
  8. data/lib/images_gallery/views/base.rb +57 -0
  9. data/lib/images_gallery/views/index.rb +2 -2
  10. data/lib/images_gallery/views/make.rb +2 -2
  11. data/lib/images_gallery/views/model.rb +2 -2
  12. data/spec/lib/images_gallery/cli_spec.rb +3 -3
  13. data/spec/lib/images_gallery/{collection_spec.rb → models/collection_spec.rb} +2 -2
  14. data/spec/lib/images_gallery/{image_spec.rb → models/image_spec.rb} +2 -2
  15. data/spec/lib/images_gallery/{source_spec.rb → models/source_spec.rb} +2 -2
  16. data/spec/lib/images_gallery/{view_spec.rb → views/base_spec.rb} +2 -2
  17. data/spec/lib/images_gallery/views/index_spec.rb +1 -5
  18. data/spec/lib/images_gallery/views/make_spec.rb +1 -5
  19. data/spec/lib/images_gallery/views/model_spec.rb +1 -5
  20. data/spec/support/helpers.rb +7 -0
  21. data/spec/tmp/canon/canon_eos_20d.html +1 -0
  22. data/spec/tmp/canon/canon_eos_400d_digital.html +1 -0
  23. data/spec/tmp/canon.html +1 -0
  24. data/spec/tmp/fuji_photo_film_co_ltd/slp1000se.html +1 -0
  25. data/spec/tmp/fuji_photo_film_co_ltd.html +1 -0
  26. data/spec/tmp/fujifilm/finepix_s6500fd.html +1 -0
  27. data/spec/tmp/fujifilm.html +1 -0
  28. data/spec/tmp/index.html +1 -0
  29. data/spec/tmp/leica/d_lux_3.html +1 -0
  30. data/spec/tmp/leica.html +1 -0
  31. data/spec/tmp/nikon_corporation/nikon_d80.html +1 -0
  32. data/spec/tmp/nikon_corporation.html +1 -0
  33. data/spec/tmp/panasonic/dmc_fz30.html +1 -0
  34. data/spec/tmp/panasonic.html +1 -0
  35. data/spec/tmp/unknown_make/unknown_model.html +1 -0
  36. data/spec/tmp/unknown_make.html +1 -0
  37. metadata +14 -14
  38. data/lib/images_gallery/collection.rb +0 -15
  39. data/lib/images_gallery/image.rb +0 -19
  40. data/lib/images_gallery/source.rb +0 -104
  41. data/lib/images_gallery/view.rb +0 -55
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6776c25e3826043bb0f8a6b2fd9264670288ffec
4
- data.tar.gz: 9a89ef53659d2fbaeb782345752432db6995519a
3
+ metadata.gz: 67e420173590772158f6bab51506ccd9a836fe5c
4
+ data.tar.gz: d53ff9a4c056c12d17d31396b8325841ad16111e
5
5
  SHA512:
6
- metadata.gz: e9e1951ea8e2bfcbe22142fc19cb514150aa1f1e6532583e8b401aaf9966075c76f284727d14d9906ca65ea8cb63b78b7d34f98aa744cc849486966e044cb500
7
- data.tar.gz: c6f5e80500100a94b18050ff6a5d0ad841ec5f97df50cfc618d11a0af91ca148543a42fe7eac6800cdd405dd54eb662ac72498668b1ef9b4f725de6c9212facf
6
+ metadata.gz: 74de38ecf7c3ab952260a7403218354f05eccb271310f77b05872a83b1aa89555c91a6092f3b99bbaf2c6e90dd19ef6f0f2aa459773ea968fba535f3f607175e
7
+ data.tar.gz: 01e3e36847c68a09f17f8892c793898788b28087f0e2933e2ac1ec41d3aa66dd17875b5166bff707c6df2993633e56e56c30c339479821e6cfcda42579995480
@@ -6,15 +6,15 @@ module ImagesGallery
6
6
  class CLI < Thor
7
7
 
8
8
  desc 'generate SOURCE TARGET', 'Generate a static HTML images gallery in the TARGET directory from the SOURCE file contents.'
9
- def generate(source, target=nil, error=STDERR, out=STDOUT)
9
+ def generate(source, target, error=STDERR, out=STDOUT)
10
10
  begin
11
11
  out.puts generator.run(source, target)
12
12
  rescue ImagesGallery::SourceFileNotFoundError
13
- error.puts 'Please make sure the specified source file exists.'
13
+ error.puts 'ERROR: Please make sure the specified source file exists.'
14
14
  rescue ImagesGallery::TargetDirectoryNotFoundError
15
- error.puts 'Please make sure the specified target directory exists.'
15
+ error.puts 'ERROR: Please make sure the specified target directory exists.'
16
16
  rescue ImagesGallery::SourceFileInvalidError
17
- error.puts 'The source file is invalid. Please check it is well-formed XML.'
17
+ error.puts 'ERROR: The source file is invalid. Please check it is well-formed XML.'
18
18
  end
19
19
  end
20
20
 
@@ -1,5 +1,6 @@
1
1
  require 'images_gallery/errors'
2
- require 'images_gallery/source'
2
+ require 'images_gallery/models/collection'
3
+ require 'images_gallery/models/source'
3
4
  require 'images_gallery/views/index'
4
5
  require 'images_gallery/views/make'
5
6
  require 'images_gallery/views/model'
@@ -15,7 +16,7 @@ module ImagesGallery
15
16
  raise SourceFileNotFoundError unless File.file? source
16
17
  raise TargetDirectoryNotFoundError unless File.directory? target
17
18
 
18
- @source = Source.new(source)
19
+ @source = Models::Source.new(source)
19
20
  @target = target
20
21
 
21
22
  @source.parse
@@ -31,14 +32,14 @@ module ImagesGallery
31
32
  files['index'] = Views::Index.new(images).render
32
33
 
33
34
  images.makes.each do |make|
34
- images_by_make = Collection.new
35
+ images_by_make = Models::Collection.new
35
36
  images.select{ |image| image.make == make }.each do |image|
36
37
  images_by_make << image
37
38
  view = Views::Make.new(images_by_make)
38
39
  files[view.file_identifier(image.make)] = view.render
39
40
 
40
41
  images_by_make.models.each do |model|
41
- images_by_model = Collection.new
42
+ images_by_model = Models::Collection.new
42
43
  images_by_make.select{ |image| image.model == model }.each do |image|
43
44
  images_by_model << image
44
45
  view = Views::Model.new(images_by_model)
@@ -0,0 +1,17 @@
1
+ require 'images_gallery/models/image'
2
+
3
+ module ImagesGallery
4
+ module Models
5
+ class Collection < Array
6
+
7
+ def makes
8
+ map { |image| image.make }.uniq.sort
9
+ end
10
+
11
+ def models
12
+ map { |image| image.model }.uniq.sort
13
+ end
14
+
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,21 @@
1
+ module ImagesGallery
2
+ module Models
3
+ class Image
4
+
5
+ attr_accessor :id, :src, :make, :model
6
+
7
+ def make
8
+ @make || 'Unknown Make'
9
+ end
10
+
11
+ def model
12
+ @model || 'Unknown Model'
13
+ end
14
+
15
+ def description
16
+ "Image #{@id}"
17
+ end
18
+
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,107 @@
1
+ require 'libxml'
2
+
3
+ require 'images_gallery/models/collection'
4
+ require 'images_gallery/models/image'
5
+
6
+ module ImagesGallery
7
+ module Models
8
+ class Source
9
+
10
+ include LibXML
11
+ include XML::SaxParser::Callbacks
12
+
13
+ attr_reader :images
14
+
15
+ # Provides a collection of images to presenters
16
+ #
17
+ # Extracts some images attributes from an XML collection of works
18
+ # and collects the images as plain Ruby objects so other classes
19
+ # can use them with presentational purpose.
20
+ #
21
+ # This class should be able to parse efficiently large XML files.
22
+ #
23
+ # file - Path to an XML representation of the images (metadata, EXIF)
24
+ #
25
+ # Example:
26
+ #
27
+ # source = ImagesGallery::Source.new('path/to/source.xml')
28
+ # source.parse # creates a Collection of Images
29
+ # source.images # is available after parsing
30
+ #
31
+ # Returns a Source object, ready to parse the corresponding XML file.
32
+ def initialize(file)
33
+ @file = XML::SaxParser.file(file)
34
+ @file.callbacks = self
35
+ end
36
+
37
+ def parse
38
+ @images = Models::Collection.new
39
+ begin
40
+ @file.parse
41
+ rescue LibXML::XML::Error
42
+ raise SourceFileInvalidError
43
+ end
44
+ end
45
+
46
+ # Callbacks can't be private, yet they are not part of the public API.
47
+
48
+ def on_start_element(element, attributes)
49
+ @current_element = element
50
+
51
+ if element == 'work'
52
+ @current_image = Models::Image.new
53
+ end
54
+
55
+ if element == 'url' && attributes['type'] == 'small'
56
+ @current_element = 'thumbnail URL'
57
+ end
58
+ end
59
+
60
+ def on_end_element(element)
61
+ if element == 'work'
62
+ @images << @current_image
63
+ end
64
+
65
+ if element == 'id'
66
+ @current_image.id = @current_id
67
+ end
68
+
69
+ if element == 'make'
70
+ @current_image.make = @current_make
71
+ end
72
+
73
+ if element == 'model'
74
+ @current_image.model = @current_model
75
+ end
76
+
77
+ if @current_element == 'thumbnail URL'
78
+ @current_image.src = @current_src
79
+ end
80
+
81
+ @current_element = nil
82
+ end
83
+
84
+ def on_characters(char)
85
+ if @current_element == 'id'
86
+ @current_id = char
87
+ end
88
+
89
+ if @current_element == 'make'
90
+ @current_make = char
91
+ end
92
+
93
+ if @current_element == 'model'
94
+ @current_model = char
95
+ end
96
+
97
+ if @current_element == 'thumbnail URL'
98
+ @current_src = char
99
+ end
100
+ end
101
+
102
+ def on_end_document
103
+ @current_element = nil
104
+ end
105
+ end
106
+ end
107
+ end
@@ -1,3 +1,3 @@
1
1
  module ImagesGallery
2
- VERSION = '1.0.0'
2
+ VERSION = '1.0.1'
3
3
  end
@@ -0,0 +1,57 @@
1
+ require 'erb'
2
+
3
+ module ImagesGallery
4
+ module Views
5
+ class Base
6
+
7
+ # Provides context and helpers to the corresponding template
8
+ #
9
+ # Any variable defined in the context of this class will be accessible
10
+ # from the corresponding ERb template.
11
+ # See http://ruby-doc.org/stdlib-2.2.2/libdoc/erb/rdoc/ERB.html#method-i-result
12
+ #
13
+ # Usage:
14
+ #
15
+ # Do not instanciate this class, define subclasses instead an define their
16
+ # template methods as demonstrated in Views::Index.
17
+ #
18
+ # Conventionally, templates could be stored in images_gallery/templates, but
19
+ # there is no obligation to follow the convention.
20
+ #
21
+ # This class not meant to be instanciated, subclasses do return View instances (kind of).
22
+ def initialize
23
+ @template = File.new(template)
24
+ end
25
+
26
+ def template
27
+ raise NotImplementedError
28
+ end
29
+
30
+ def render
31
+ ERB.new(File.new(template).read).result(binding)
32
+ end
33
+
34
+ def thumbnails(images)
35
+ template = File.expand_path('../../templates/_thumbnails.html.erb', __FILE__)
36
+ ERB.new(File.new(template).read).result(binding)
37
+ end
38
+
39
+ def navigation(links)
40
+ template = File.expand_path('../../templates/_navigation.html.erb', __FILE__)
41
+ ERB.new(File.new(template).read).result(binding)
42
+ end
43
+
44
+ def link_to(depth, make, model=nil)
45
+ ('../' * depth) + file_identifier(make, model) + '.html'
46
+ end
47
+
48
+ def file_identifier(make, model=nil)
49
+ if model.nil?
50
+ "#{make.to_filename}"
51
+ else
52
+ "#{make.to_filename}/#{model.to_filename}"
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -1,10 +1,10 @@
1
1
  require 'erb'
2
2
 
3
- require 'images_gallery/view'
3
+ require 'images_gallery/views/base'
4
4
 
5
5
  module ImagesGallery
6
6
  module Views
7
- class Index < ImagesGallery::View
7
+ class Index < Base
8
8
 
9
9
  attr_reader :depth, :links, :sample_images, :title
10
10
  private :depth, :links, :sample_images, :title
@@ -1,10 +1,10 @@
1
1
  require 'erb'
2
2
 
3
- require 'images_gallery/view'
3
+ require 'images_gallery/views/base'
4
4
 
5
5
  module ImagesGallery
6
6
  module Views
7
- class Make < ImagesGallery::View
7
+ class Make < Base
8
8
 
9
9
  attr_reader :depth, :links, :make, :sample_images, :title
10
10
  private :depth, :links, :make, :sample_images, :title
@@ -1,10 +1,10 @@
1
1
  require 'erb'
2
2
 
3
- require 'images_gallery/view'
3
+ require 'images_gallery/views/base'
4
4
 
5
5
  module ImagesGallery
6
6
  module Views
7
- class Model < ImagesGallery::View
7
+ class Model < Base
8
8
 
9
9
  attr_reader :depth, :links, :make, :model, :sample_images, :title
10
10
  private :depth, :links, :make, :model, :sample_images, :title
@@ -32,7 +32,7 @@ describe 'CLI' do
32
32
  stderr = double()
33
33
  allow(command_line_interface).to receive_message_chain(:generator, :run) { raise ImagesGallery::SourceFileNotFoundError }
34
34
 
35
- expect(stderr).to receive_message_chain(:puts).with('Please make sure the specified source file exists.')
35
+ expect(stderr).to receive_message_chain(:puts).with('ERROR: Please make sure the specified source file exists.')
36
36
  command_line_interface.generate('source', 'target', stderr)
37
37
  end
38
38
  end
@@ -43,7 +43,7 @@ describe 'CLI' do
43
43
  stderr = double()
44
44
  allow(command_line_interface).to receive_message_chain(:generator, :run) { raise ImagesGallery::TargetDirectoryNotFoundError }
45
45
 
46
- expect(stderr).to receive_message_chain(:puts).with('Please make sure the specified target directory exists.')
46
+ expect(stderr).to receive_message_chain(:puts).with('ERROR: Please make sure the specified target directory exists.')
47
47
  command_line_interface.generate('source', 'target', stderr)
48
48
  end
49
49
  end
@@ -54,7 +54,7 @@ describe 'CLI' do
54
54
  stderr = double()
55
55
  allow(command_line_interface).to receive_message_chain(:generator, :run) { raise ImagesGallery::SourceFileInvalidError }
56
56
 
57
- expect(stderr).to receive_message_chain(:puts).with('The source file is invalid. Please check it is well-formed XML.')
57
+ expect(stderr).to receive_message_chain(:puts).with('ERROR: The source file is invalid. Please check it is well-formed XML.')
58
58
  command_line_interface.generate('source', 'target', stderr)
59
59
  end
60
60
  end
@@ -1,9 +1,9 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  module ImagesGallery
4
- describe 'Collection' do
4
+ describe 'Models::Collection' do
5
5
 
6
- let(:collection) { Collection.new }
6
+ let(:collection) { Models::Collection.new }
7
7
 
8
8
  it_behaves_like 'a collection'
9
9
 
@@ -1,9 +1,9 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  module ImagesGallery
4
- describe 'Image' do
4
+ describe 'Models::Image' do
5
5
 
6
- let(:image) { Image.new }
6
+ let(:image) { Models::Image.new }
7
7
 
8
8
  it_behaves_like 'an image'
9
9
 
@@ -1,9 +1,9 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  module ImagesGallery
4
- describe 'Source' do
4
+ describe 'Models::Source' do
5
5
 
6
- let(:source) { Source.new('spec/fixtures/works.xml') }
6
+ let(:source) { Models::Source.new('spec/fixtures/works.xml') }
7
7
  let(:parser) { source }
8
8
 
9
9
  it_behaves_like 'a parser'
@@ -1,9 +1,9 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  module ImagesGallery
4
- describe 'View' do
4
+ describe 'Views::Base' do
5
5
 
6
- let(:view) { View.new }
6
+ let(:view) { Views::Base.new }
7
7
 
8
8
  it 'does not define :template' do
9
9
  expect { view.template }.to raise_error NotImplementedError
@@ -3,11 +3,7 @@ require 'spec_helper'
3
3
  module ImagesGallery
4
4
  describe 'Views::Index' do
5
5
 
6
- let(:data) do
7
- data = Collection.new
8
- data << Image.new
9
- end
10
-
6
+ let(:data) { images_collection }
11
7
  let(:view) { Views::Model.new(data) }
12
8
 
13
9
  it_behaves_like 'a view'
@@ -3,11 +3,7 @@ require 'spec_helper'
3
3
  module ImagesGallery
4
4
  describe 'Views::Make' do
5
5
 
6
- let(:data) do
7
- data = Collection.new
8
- data << Image.new
9
- end
10
-
6
+ let(:data) { images_collection }
11
7
  let(:view) { Views::Model.new(data) }
12
8
 
13
9
  it_behaves_like 'a view'
@@ -3,11 +3,7 @@ require 'spec_helper'
3
3
  module ImagesGallery
4
4
  describe 'Views::Model' do
5
5
 
6
- let(:data) do
7
- data = Collection.new
8
- data << Image.new
9
- end
10
-
6
+ let(:data) { images_collection }
11
7
  let(:view) { Views::Model.new(data) }
12
8
 
13
9
  it_behaves_like 'a view'
@@ -12,7 +12,14 @@ module Selectors
12
12
  end
13
13
  end
14
14
 
15
+ module ViewHelpers
16
+ def images_collection
17
+ ImagesGallery::Models::Collection.new << ImagesGallery::Models::Image.new
18
+ end
19
+ end
20
+
15
21
  RSpec.configure do |config|
16
22
  config.extend Selectors
17
23
  config.include Selectors
24
+ config.include ViewHelpers
18
25
  end
@@ -1,6 +1,7 @@
1
1
  <!DOCTYPE html>
2
2
  <html>
3
3
  <head>
4
+ <meta charset="utf-8">
4
5
  <title>Images by (Canon) Canon EOS 20D</title>
5
6
  <style type="text/css">
6
7
  html, body {
@@ -1,6 +1,7 @@
1
1
  <!DOCTYPE html>
2
2
  <html>
3
3
  <head>
4
+ <meta charset="utf-8">
4
5
  <title>Images by (Canon) Canon EOS 400D DIGITAL</title>
5
6
  <style type="text/css">
6
7
  html, body {
data/spec/tmp/canon.html CHANGED
@@ -1,6 +1,7 @@
1
1
  <!DOCTYPE html>
2
2
  <html>
3
3
  <head>
4
+ <meta charset="utf-8">
4
5
  <title>Images by Canon</title>
5
6
  <style type="text/css">
6
7
  html, body {
@@ -1,6 +1,7 @@
1
1
  <!DOCTYPE html>
2
2
  <html>
3
3
  <head>
4
+ <meta charset="utf-8">
4
5
  <title>Images by (FUJI PHOTO FILM CO., LTD.) SLP1000SE</title>
5
6
  <style type="text/css">
6
7
  html, body {
@@ -1,6 +1,7 @@
1
1
  <!DOCTYPE html>
2
2
  <html>
3
3
  <head>
4
+ <meta charset="utf-8">
4
5
  <title>Images by FUJI PHOTO FILM CO., LTD.</title>
5
6
  <style type="text/css">
6
7
  html, body {
@@ -1,6 +1,7 @@
1
1
  <!DOCTYPE html>
2
2
  <html>
3
3
  <head>
4
+ <meta charset="utf-8">
4
5
  <title>Images by (FUJIFILM) FinePix S6500fd</title>
5
6
  <style type="text/css">
6
7
  html, body {
@@ -1,6 +1,7 @@
1
1
  <!DOCTYPE html>
2
2
  <html>
3
3
  <head>
4
+ <meta charset="utf-8">
4
5
  <title>Images by FUJIFILM</title>
5
6
  <style type="text/css">
6
7
  html, body {
data/spec/tmp/index.html CHANGED
@@ -1,6 +1,7 @@
1
1
  <!DOCTYPE html>
2
2
  <html>
3
3
  <head>
4
+ <meta charset="utf-8">
4
5
  <title>Index</title>
5
6
  <style type="text/css">
6
7
  html, body {
@@ -1,6 +1,7 @@
1
1
  <!DOCTYPE html>
2
2
  <html>
3
3
  <head>
4
+ <meta charset="utf-8">
4
5
  <title>Images by (LEICA) D-LUX 3</title>
5
6
  <style type="text/css">
6
7
  html, body {
data/spec/tmp/leica.html CHANGED
@@ -1,6 +1,7 @@
1
1
  <!DOCTYPE html>
2
2
  <html>
3
3
  <head>
4
+ <meta charset="utf-8">
4
5
  <title>Images by LEICA</title>
5
6
  <style type="text/css">
6
7
  html, body {
@@ -1,6 +1,7 @@
1
1
  <!DOCTYPE html>
2
2
  <html>
3
3
  <head>
4
+ <meta charset="utf-8">
4
5
  <title>Images by (NIKON CORPORATION) NIKON D80</title>
5
6
  <style type="text/css">
6
7
  html, body {
@@ -1,6 +1,7 @@
1
1
  <!DOCTYPE html>
2
2
  <html>
3
3
  <head>
4
+ <meta charset="utf-8">
4
5
  <title>Images by NIKON CORPORATION</title>
5
6
  <style type="text/css">
6
7
  html, body {
@@ -1,6 +1,7 @@
1
1
  <!DOCTYPE html>
2
2
  <html>
3
3
  <head>
4
+ <meta charset="utf-8">
4
5
  <title>Images by (Panasonic) DMC-FZ30</title>
5
6
  <style type="text/css">
6
7
  html, body {
@@ -1,6 +1,7 @@
1
1
  <!DOCTYPE html>
2
2
  <html>
3
3
  <head>
4
+ <meta charset="utf-8">
4
5
  <title>Images by Panasonic</title>
5
6
  <style type="text/css">
6
7
  html, body {
@@ -1,6 +1,7 @@
1
1
  <!DOCTYPE html>
2
2
  <html>
3
3
  <head>
4
+ <meta charset="utf-8">
4
5
  <title>Images by (Unknown Make) Unknown Model</title>
5
6
  <style type="text/css">
6
7
  html, body {
@@ -1,6 +1,7 @@
1
1
  <!DOCTYPE html>
2
2
  <html>
3
3
  <head>
4
+ <meta charset="utf-8">
4
5
  <title>Images by Unknown Make</title>
5
6
  <style type="text/css">
6
7
  html, body {
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: images_gallery
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gonzalo Bulnes Guilpain
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-06-26 00:00:00.000000000 Z
11
+ date: 2015-06-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: libxml-ruby
@@ -139,17 +139,17 @@ files:
139
139
  - config.ru
140
140
  - lib/images_gallery.rb
141
141
  - lib/images_gallery/cli.rb
142
- - lib/images_gallery/collection.rb
143
142
  - lib/images_gallery/errors.rb
144
143
  - lib/images_gallery/generator.rb
145
- - lib/images_gallery/image.rb
146
- - lib/images_gallery/source.rb
144
+ - lib/images_gallery/models/collection.rb
145
+ - lib/images_gallery/models/image.rb
146
+ - lib/images_gallery/models/source.rb
147
147
  - lib/images_gallery/templates/_navigation.html.erb
148
148
  - lib/images_gallery/templates/_thumbnails.html.erb
149
149
  - lib/images_gallery/templates/layout.html.erb
150
150
  - lib/images_gallery/test_application.rb
151
151
  - lib/images_gallery/version.rb
152
- - lib/images_gallery/view.rb
152
+ - lib/images_gallery/views/base.rb
153
153
  - lib/images_gallery/views/index.rb
154
154
  - lib/images_gallery/views/make.rb
155
155
  - lib/images_gallery/views/model.rb
@@ -162,11 +162,11 @@ files:
162
162
  - spec/fixtures/works.xml
163
163
  - spec/fixtures/works_large.xml
164
164
  - spec/lib/images_gallery/cli_spec.rb
165
- - spec/lib/images_gallery/collection_spec.rb
166
165
  - spec/lib/images_gallery/generator_spec.rb
167
- - spec/lib/images_gallery/image_spec.rb
168
- - spec/lib/images_gallery/source_spec.rb
169
- - spec/lib/images_gallery/view_spec.rb
166
+ - spec/lib/images_gallery/models/collection_spec.rb
167
+ - spec/lib/images_gallery/models/image_spec.rb
168
+ - spec/lib/images_gallery/models/source_spec.rb
169
+ - spec/lib/images_gallery/views/base_spec.rb
170
170
  - spec/lib/images_gallery/views/index_spec.rb
171
171
  - spec/lib/images_gallery/views/make_spec.rb
172
172
  - spec/lib/images_gallery/views/model_spec.rb
@@ -223,15 +223,15 @@ specification_version: 4
223
223
  summary: Generate efficient galleries of thumbnails from large XML representations
224
224
  of EXIF data.
225
225
  test_files:
226
- - spec/lib/images_gallery/view_spec.rb
227
226
  - spec/lib/images_gallery/generator_spec.rb
228
- - spec/lib/images_gallery/image_spec.rb
227
+ - spec/lib/images_gallery/models/image_spec.rb
228
+ - spec/lib/images_gallery/models/source_spec.rb
229
+ - spec/lib/images_gallery/models/collection_spec.rb
229
230
  - spec/lib/images_gallery/cli_spec.rb
230
231
  - spec/lib/images_gallery/views/index_spec.rb
232
+ - spec/lib/images_gallery/views/base_spec.rb
231
233
  - spec/lib/images_gallery/views/model_spec.rb
232
234
  - spec/lib/images_gallery/views/make_spec.rb
233
- - spec/lib/images_gallery/source_spec.rb
234
- - spec/lib/images_gallery/collection_spec.rb
235
235
  - spec/features/index_page_spec.rb
236
236
  - spec/features/models_pages/canon_eos_20d_page_spec.rb
237
237
  - spec/features/models_pages/lux_d_3_page_spec.rb
@@ -1,15 +0,0 @@
1
- require 'images_gallery/image'
2
-
3
- module ImagesGallery
4
- class Collection < Array
5
-
6
- def makes
7
- map { |image| image.make }.uniq.sort
8
- end
9
-
10
- def models
11
- map { |image| image.model }.uniq.sort
12
- end
13
-
14
- end
15
- end
@@ -1,19 +0,0 @@
1
- module ImagesGallery
2
- class Image
3
-
4
- attr_accessor :id, :src, :make, :model
5
-
6
- def make
7
- @make || 'Unknown Make'
8
- end
9
-
10
- def model
11
- @model || 'Unknown Model'
12
- end
13
-
14
- def description
15
- "Image #{@id}"
16
- end
17
-
18
- end
19
- end
@@ -1,104 +0,0 @@
1
- require 'libxml'
2
-
3
- require 'images_gallery/collection'
4
-
5
- module ImagesGallery
6
- class Source
7
-
8
- include LibXML
9
- include XML::SaxParser::Callbacks
10
-
11
- attr_reader :images
12
-
13
- # Provides a collection of images to presenters
14
- #
15
- # Extracts some images attributes from an XML collection of works
16
- # and collects the images as plain Ruby objects so other classes
17
- # can use them with presentational purpose.
18
- #
19
- # This class should be able to parse efficiently large XML files.
20
- #
21
- # file - Path to an XML representation of the images (metadata, EXIF)
22
- #
23
- # Example:
24
- #
25
- # source = ImagesGallery::Source.new('path/to/source.xml')
26
- # source.parse # creates a Collection of Images
27
- # source.images # is available after parsing
28
- #
29
- # Returns a Source object, ready to parse the corresponding XML file.
30
- def initialize(file)
31
- @file = XML::SaxParser.file(file)
32
- @file.callbacks = self
33
- end
34
-
35
- def parse
36
- @images = Collection.new
37
- begin
38
- @file.parse
39
- rescue LibXML::XML::Error
40
- raise SourceFileInvalidError
41
- end
42
- end
43
-
44
- # Callbacks can't be private, yet they are not part of the public API.
45
-
46
- def on_start_element(element, attributes)
47
- @current_element = element
48
-
49
- if element == 'work'
50
- @current_image = Image.new
51
- end
52
-
53
- if element == 'url' && attributes['type'] == 'small'
54
- @current_element = 'thumbnail URL'
55
- end
56
- end
57
-
58
- def on_end_element(element)
59
- if element == 'work'
60
- @images << @current_image
61
- end
62
-
63
- if element == 'id'
64
- @current_image.id = @current_id
65
- end
66
-
67
- if element == 'make'
68
- @current_image.make = @current_make
69
- end
70
-
71
- if element == 'model'
72
- @current_image.model = @current_model
73
- end
74
-
75
- if @current_element == 'thumbnail URL'
76
- @current_image.src = @current_src
77
- end
78
-
79
- @current_element = nil
80
- end
81
-
82
- def on_characters(char)
83
- if @current_element == 'id'
84
- @current_id = char
85
- end
86
-
87
- if @current_element == 'make'
88
- @current_make = char
89
- end
90
-
91
- if @current_element == 'model'
92
- @current_model = char
93
- end
94
-
95
- if @current_element == 'thumbnail URL'
96
- @current_src = char
97
- end
98
- end
99
-
100
- def on_end_document
101
- @current_element = nil
102
- end
103
- end
104
- end
@@ -1,55 +0,0 @@
1
- require 'erb'
2
-
3
- module ImagesGallery
4
- class View
5
-
6
- # Provides context and helpers to the corresponding template
7
- #
8
- # Any variable defined in the context of this class will be accessible
9
- # from the corresponding ERb template.
10
- # See http://ruby-doc.org/stdlib-2.2.2/libdoc/erb/rdoc/ERB.html#method-i-result
11
- #
12
- # Usage:
13
- #
14
- # Do not instanciate this class, define subclasses instead an define their
15
- # template methods as demonstrated in Views::Index.
16
- #
17
- # Conventionally, templates could be stored in images_gallery/templates, but
18
- # there is no obligation to follow the convention.
19
- #
20
- # This class not meant to be instanciated, subclasses do return View instances (kind of).
21
- def initialize
22
- @template = File.new(template)
23
- end
24
-
25
- def template
26
- raise NotImplementedError
27
- end
28
-
29
- def render
30
- ERB.new(File.new(template).read).result(binding)
31
- end
32
-
33
- def thumbnails(images)
34
- template = File.expand_path('../templates/_thumbnails.html.erb', __FILE__)
35
- ERB.new(File.new(template).read).result(binding)
36
- end
37
-
38
- def navigation(links)
39
- template = File.expand_path('../templates/_navigation.html.erb', __FILE__)
40
- ERB.new(File.new(template).read).result(binding)
41
- end
42
-
43
- def link_to(depth, make, model=nil)
44
- ('../' * depth) + file_identifier(make, model) + '.html'
45
- end
46
-
47
- def file_identifier(make, model=nil)
48
- if model.nil?
49
- "#{make.to_filename}"
50
- else
51
- "#{make.to_filename}/#{model.to_filename}"
52
- end
53
- end
54
- end
55
- end