flickr_offline_gallery 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.rspec +2 -0
- data/Gemfile +9 -0
- data/{LICENSE.txt → _LICENSE.txt} +0 -0
- data/bin/flickr_offline_gallery +2 -1
- data/erb/photo.html.erb +23 -2
- data/erb/photoset.html.erb +2 -1
- data/fixtures/vcr_cassettes/full_photo_sizes.yml +152 -0
- data/fixtures/vcr_cassettes/full_photo_sizes_with_janky_metadata.yml +147 -0
- data/fixtures/vcr_cassettes/image_downloads.yml +15096 -0
- data/fixtures/vcr_cassettes/init.yml +160 -0
- data/fixtures/vcr_cassettes/photo.yml +71 -0
- data/fixtures/vcr_cassettes/photo_sizes.yml +84 -0
- data/fixtures/vcr_cassettes/photo_with_janky_metadata.yml +70 -0
- data/fixtures/vcr_cassettes/photoset.yml +663 -0
- data/fixtures/vcr_cassettes/photset_downloader_spec.yml +1017 -0
- data/flickr_offline_gallery.gemspec +2 -1
- data/lib/flickr_offline_gallery/flickr_a_p_i.rb +23 -0
- data/lib/flickr_offline_gallery/gallery_generator.rb +26 -0
- data/lib/flickr_offline_gallery/path_manager.rb +37 -0
- data/lib/flickr_offline_gallery/photo.rb +28 -21
- data/lib/flickr_offline_gallery/photo_page.rb +23 -0
- data/lib/flickr_offline_gallery/photo_size.rb +9 -4
- data/lib/flickr_offline_gallery/photo_sizes.rb +11 -7
- data/lib/flickr_offline_gallery/photoset.rb +27 -6
- data/lib/flickr_offline_gallery/photoset_downloader.rb +21 -5
- data/lib/flickr_offline_gallery/photoset_index_page.rb +17 -0
- data/lib/flickr_offline_gallery/template_renderer.rb +42 -0
- data/lib/flickr_offline_gallery/verbose_puts.rb +8 -0
- data/lib/flickr_offline_gallery/version.rb +1 -1
- data/lib/flickr_offline_gallery.rb +7 -40
- data/spec/flickr_offline_gallery/gallery_generator_spec.rb +35 -0
- data/spec/flickr_offline_gallery/path_manager_spec.rb +34 -0
- data/spec/flickr_offline_gallery/photo_page_spec.rb +42 -0
- data/spec/flickr_offline_gallery/photo_size_spec.rb +32 -0
- data/spec/flickr_offline_gallery/photo_sizes_spec.rb +23 -0
- data/spec/flickr_offline_gallery/photo_spec.rb +81 -0
- data/spec/flickr_offline_gallery/photoset_downloader_spec.rb +27 -0
- data/spec/flickr_offline_gallery/photoset_spec.rb +35 -0
- data/spec/flickr_offline_gallery/template_renderer_spec.rb +51 -0
- data/spec/flickr_offline_gallery/verbose_puts_spec.rb +33 -0
- data/spec/spec_helper.rb +82 -0
- metadata +59 -5
@@ -0,0 +1,23 @@
|
|
1
|
+
module FlickrOfflineGallery
|
2
|
+
class FlickrAPI
|
3
|
+
def self.instance
|
4
|
+
@instance ||= FlickRaw::Flickr.new
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.get_photoset(photoset_id)
|
8
|
+
instance.photosets.getPhotos(:photoset_id => photoset_id).to_hash
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.get_photo_info(photo_id)
|
12
|
+
instance.photos.getInfo(:photo_id => photo_id).to_hash
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.get_photo_sizes(photo_id)
|
16
|
+
instance.photos.getSizes(:photo_id => photo_id).to_a
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# No thanks Flickraw. Not even once.
|
23
|
+
undef flickr
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module FlickrOfflineGallery
|
2
|
+
|
3
|
+
class GalleryGenerator
|
4
|
+
|
5
|
+
def initialize(photoset)
|
6
|
+
@photoset = photoset
|
7
|
+
end
|
8
|
+
|
9
|
+
def render_photoset(size)
|
10
|
+
download_images(size)
|
11
|
+
render_photo_pages
|
12
|
+
PhotosetIndexPage.new(@photoset).write
|
13
|
+
end
|
14
|
+
|
15
|
+
def download_images(size = "medium_800")
|
16
|
+
PhotosetDownloader.new(@photoset, size).download
|
17
|
+
end
|
18
|
+
|
19
|
+
def render_photo_pages
|
20
|
+
@photoset.photos.each do |photo|
|
21
|
+
PhotoPage.new(photo).write
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module FlickrOfflineGallery
|
2
|
+
class PathManager
|
3
|
+
|
4
|
+
attr_reader :base_path
|
5
|
+
|
6
|
+
def initialize(base_path, slug)
|
7
|
+
@base_path = base_path
|
8
|
+
@slug = slug
|
9
|
+
end
|
10
|
+
|
11
|
+
def photo_output_path
|
12
|
+
File.join(base_path, @slug)
|
13
|
+
end
|
14
|
+
|
15
|
+
def index_page
|
16
|
+
"#{photo_output_path}.html"
|
17
|
+
end
|
18
|
+
|
19
|
+
def full_path_for(photo_id, extension)
|
20
|
+
File.join(photo_output_path, filename_for_photo(photo_id, extension))
|
21
|
+
end
|
22
|
+
|
23
|
+
def relative_path_for(photo_id, extension)
|
24
|
+
File.join(@slug, filename_for_photo(photo_id, extension))
|
25
|
+
end
|
26
|
+
|
27
|
+
def filename_for_photo(photo_id, extension)
|
28
|
+
"#{photo_id}.#{extension}"
|
29
|
+
end
|
30
|
+
|
31
|
+
def back_to_index
|
32
|
+
"../#{@slug}.html"
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
@@ -1,46 +1,53 @@
|
|
1
1
|
module FlickrOfflineGallery
|
2
2
|
class Photo
|
3
|
+
include VerbosePuts
|
3
4
|
|
4
|
-
|
5
|
-
|
6
|
-
def initialize(horrible_flickraw_response_junk, photoset_id = nil)
|
5
|
+
def initialize(horrible_flickraw_response_junk, args = {})
|
6
|
+
@path_manager = args[:path_manager]
|
7
7
|
@id = horrible_flickraw_response_junk["id"]
|
8
|
-
@
|
9
|
-
@set = photoset_id
|
8
|
+
@photoset_id = args[:photoset_id]
|
10
9
|
eager_load
|
11
|
-
|
10
|
+
verbose_puts %(Fetched data about photo #{@id}: "#{title}")
|
12
11
|
end
|
13
12
|
|
14
13
|
def title
|
15
14
|
info.title
|
16
15
|
end
|
17
16
|
|
18
|
-
def date
|
19
|
-
@date ||= DateTime.parse(info.dates["taken"])
|
20
|
-
end
|
21
|
-
|
22
17
|
def url
|
23
|
-
if
|
24
|
-
"#{base_url}in/set-#{
|
18
|
+
if @photoset_id
|
19
|
+
"#{base_url}in/set-#{@photoset_id}"
|
25
20
|
else
|
26
21
|
base_url
|
27
22
|
end
|
28
23
|
end
|
29
24
|
|
25
|
+
def base_url
|
26
|
+
@base_url ||= info.urls.find{|u| u["type"] == "photopage"}["_content"]
|
27
|
+
end
|
28
|
+
|
30
29
|
def img_filename
|
31
|
-
|
30
|
+
@path_manager.filename_for_photo(@id, :jpg)
|
32
31
|
end
|
33
32
|
|
34
|
-
def
|
35
|
-
|
33
|
+
def full_jpg_path
|
34
|
+
@path_manager.full_path_for(@id, :jpg)
|
36
35
|
end
|
37
36
|
|
38
|
-
def
|
39
|
-
|
37
|
+
def full_html_path
|
38
|
+
@path_manager.full_path_for(@id, :html)
|
40
39
|
end
|
41
40
|
|
42
|
-
def
|
43
|
-
@
|
41
|
+
def relative_jpg_path
|
42
|
+
@path_manager.relative_path_for(@id, :jpg)
|
43
|
+
end
|
44
|
+
|
45
|
+
def relative_html_path
|
46
|
+
@path_manager.relative_path_for(@id, :html)
|
47
|
+
end
|
48
|
+
|
49
|
+
def back_to_index_url
|
50
|
+
@path_manager.back_to_index
|
44
51
|
end
|
45
52
|
|
46
53
|
def sizes
|
@@ -59,11 +66,11 @@ module FlickrOfflineGallery
|
|
59
66
|
end
|
60
67
|
|
61
68
|
def info
|
62
|
-
@info ||= OpenStruct.new(
|
69
|
+
@info ||= OpenStruct.new(FlickrAPI.get_photo_info(@id))
|
63
70
|
end
|
64
71
|
|
65
72
|
def raw_sizes
|
66
|
-
@raw_sizes ||=
|
73
|
+
@raw_sizes ||= FlickrAPI.get_photo_sizes(@id)
|
67
74
|
end
|
68
75
|
|
69
76
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module FlickrOfflineGallery
|
2
|
+
class PhotoPage < TemplateRenderer
|
3
|
+
|
4
|
+
def initialize(photo)
|
5
|
+
@photo = photo
|
6
|
+
super("photo")
|
7
|
+
end
|
8
|
+
|
9
|
+
def render
|
10
|
+
render_erb(:back_to_index_page => @photo.back_to_index_url,
|
11
|
+
:image_url => @photo.img_filename,
|
12
|
+
:sizes => @photo.sizes,
|
13
|
+
:photo_page_url => @photo.url,
|
14
|
+
:title => @photo.title,
|
15
|
+
:author => @photo.author)
|
16
|
+
end
|
17
|
+
|
18
|
+
def write
|
19
|
+
write_file(@photo.full_html_path)
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
@@ -1,8 +1,13 @@
|
|
1
1
|
module FlickrOfflineGallery
|
2
|
-
class PhotoSize
|
3
|
-
|
4
|
-
|
5
|
-
|
2
|
+
class PhotoSize
|
3
|
+
|
4
|
+
attr_reader :label, :width, :height, :url
|
5
|
+
|
6
|
+
def initialize(flickraw_response)
|
7
|
+
@label = flickraw_response.label
|
8
|
+
@height = flickraw_response.height
|
9
|
+
@width = flickraw_response.width
|
10
|
+
@url = flickraw_response.source
|
6
11
|
end
|
7
12
|
|
8
13
|
def key
|
@@ -1,15 +1,19 @@
|
|
1
1
|
module FlickrOfflineGallery
|
2
|
-
class PhotoSizes
|
3
|
-
|
2
|
+
class PhotoSizes
|
3
|
+
|
4
4
|
def initialize(raw_sizes)
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
5
|
+
@sizes = Hash[raw_sizes.map do |s|
|
6
|
+
size = PhotoSize.new(s)
|
7
|
+
[size.key, size]
|
8
|
+
end]
|
9
|
+
end
|
10
|
+
|
11
|
+
def [](key)
|
12
|
+
@sizes[key.to_s]
|
9
13
|
end
|
10
14
|
|
11
15
|
def each
|
12
|
-
|
16
|
+
@sizes.values.each do |value|
|
13
17
|
yield(value)
|
14
18
|
end
|
15
19
|
end
|
@@ -1,8 +1,12 @@
|
|
1
1
|
module FlickrOfflineGallery
|
2
2
|
class Photoset
|
3
|
-
|
3
|
+
|
4
|
+
include VerbosePuts
|
5
|
+
|
6
|
+
def initialize(photoset_id, args = {})
|
4
7
|
@photoset_id = photoset_id
|
5
|
-
|
8
|
+
@output_base_path = args[:output_path] || "."
|
9
|
+
eager_load
|
6
10
|
end
|
7
11
|
|
8
12
|
def username
|
@@ -14,19 +18,36 @@ module FlickrOfflineGallery
|
|
14
18
|
end
|
15
19
|
|
16
20
|
def slug
|
17
|
-
title.downcase.
|
21
|
+
title.downcase.tr_s("^a-z0-9", "-")
|
18
22
|
end
|
19
23
|
|
20
24
|
def photos
|
21
25
|
raise "photoset has more than 500 images and I'm too lazy to handle that right now" if info.pages > 1
|
22
|
-
|
23
|
-
@photos ||= info.photo.map
|
26
|
+
verbose_puts "Initializing photoset... " unless @photos
|
27
|
+
@photos ||= info.photo.map do |raw_response|
|
28
|
+
Photo.new(raw_response,
|
29
|
+
:photoset_id => @photoset_id,
|
30
|
+
:path_manager => path_manager)
|
31
|
+
end.tap{ verbose_puts "Finished initializing photoset!" }
|
32
|
+
end
|
33
|
+
|
34
|
+
def index_page_filename
|
35
|
+
path_manager.index_page
|
24
36
|
end
|
25
37
|
|
26
38
|
private
|
27
39
|
|
40
|
+
def path_manager
|
41
|
+
PathManager.new(@output_base_path, slug)
|
42
|
+
end
|
43
|
+
|
44
|
+
def eager_load
|
45
|
+
info
|
46
|
+
photos
|
47
|
+
end
|
48
|
+
|
28
49
|
def info
|
29
|
-
@info ||= OpenStruct.new(
|
50
|
+
@info ||= OpenStruct.new(FlickrAPI.get_photoset(@photoset_id))
|
30
51
|
end
|
31
52
|
end
|
32
53
|
end
|
@@ -1,5 +1,9 @@
|
|
1
|
+
require 'httparty'
|
1
2
|
module FlickrOfflineGallery
|
2
3
|
class PhotosetDownloader
|
4
|
+
|
5
|
+
include VerbosePuts
|
6
|
+
|
3
7
|
def initialize(photoset, size)
|
4
8
|
@photoset = photoset
|
5
9
|
@size = size
|
@@ -7,14 +11,13 @@ module FlickrOfflineGallery
|
|
7
11
|
|
8
12
|
def download
|
9
13
|
photos.each do |photo|
|
10
|
-
url = photo.sizes[@size].
|
11
|
-
local_path = photo.
|
14
|
+
url = photo.sizes[@size].url
|
15
|
+
local_path = photo.full_jpg_path
|
12
16
|
FileUtils.mkdir_p(File.dirname(local_path))
|
13
17
|
|
14
18
|
unless File.exist?(local_path)
|
15
|
-
|
16
|
-
|
17
|
-
puts "Downloaded #{local_path}"
|
19
|
+
download_file(url, local_path)
|
20
|
+
verbose_puts "Downloaded #{local_path}"
|
18
21
|
end
|
19
22
|
end
|
20
23
|
end
|
@@ -25,5 +28,18 @@ module FlickrOfflineGallery
|
|
25
28
|
@photoset.photos
|
26
29
|
end
|
27
30
|
|
31
|
+
def download_file(url, destination)
|
32
|
+
resp = http_get(url)
|
33
|
+
File.open(destination, "wb") do |file|
|
34
|
+
file.write(resp.body)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def http_get(url)
|
39
|
+
response = HTTParty.get(url)
|
40
|
+
raise "unhandled response code: #{response.code}" unless response.code == 200
|
41
|
+
response
|
42
|
+
end
|
43
|
+
|
28
44
|
end
|
29
45
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module FlickrOfflineGallery
|
2
|
+
class PhotosetIndexPage < TemplateRenderer
|
3
|
+
|
4
|
+
def initialize(photoset)
|
5
|
+
@photoset = photoset
|
6
|
+
super("photoset")
|
7
|
+
end
|
8
|
+
|
9
|
+
def render
|
10
|
+
render_erb(:photoset => @photoset, :photos => @photoset.photos, :size => "medium")
|
11
|
+
end
|
12
|
+
|
13
|
+
def write
|
14
|
+
write_file(@photoset.index_page_filename)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module FlickrOfflineGallery
|
2
|
+
class TemplateRenderer
|
3
|
+
|
4
|
+
include VerbosePuts
|
5
|
+
|
6
|
+
def initialize(template)
|
7
|
+
@template = template
|
8
|
+
end
|
9
|
+
|
10
|
+
def template_path
|
11
|
+
File.expand_path("../../../erb/#{@template}.html.erb",__FILE__)
|
12
|
+
end
|
13
|
+
|
14
|
+
def template_directory
|
15
|
+
File.expand_path("../../../erb/", __FILE__)
|
16
|
+
end
|
17
|
+
|
18
|
+
def template_contents
|
19
|
+
raise "Unknown template: #{template_path}" unless File.exist?(template_path)
|
20
|
+
@template_content ||= File.read(template_path)
|
21
|
+
end
|
22
|
+
|
23
|
+
def render_erb(locals)
|
24
|
+
ERB.new(template_contents).result(OpenStruct.new(locals).instance_eval { binding })
|
25
|
+
end
|
26
|
+
|
27
|
+
def render
|
28
|
+
raise "not implemented"
|
29
|
+
end
|
30
|
+
|
31
|
+
def write
|
32
|
+
raise "not implemented"
|
33
|
+
end
|
34
|
+
|
35
|
+
def write_file(filename)
|
36
|
+
File.open(filename, 'w') do |file|
|
37
|
+
file.write render
|
38
|
+
end
|
39
|
+
verbose_puts "Wrote out #{filename}"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -3,52 +3,19 @@ require 'erb'
|
|
3
3
|
require 'fileutils'
|
4
4
|
|
5
5
|
require "flickr_offline_gallery/version"
|
6
|
+
require "flickr_offline_gallery/verbose_puts"
|
7
|
+
require "flickr_offline_gallery/path_manager"
|
6
8
|
require "flickr_offline_gallery/photo_size"
|
7
9
|
require "flickr_offline_gallery/photo_sizes"
|
8
10
|
require "flickr_offline_gallery/photo"
|
9
11
|
require "flickr_offline_gallery/photoset"
|
10
12
|
require "flickr_offline_gallery/photoset_downloader"
|
13
|
+
require "flickr_offline_gallery/flickr_a_p_i"
|
14
|
+
require "flickr_offline_gallery/template_renderer"
|
15
|
+
require "flickr_offline_gallery/photo_page"
|
16
|
+
require "flickr_offline_gallery/photoset_index_page"
|
17
|
+
require "flickr_offline_gallery/gallery_generator"
|
11
18
|
|
12
19
|
module FlickrOfflineGallery
|
13
|
-
class Variables
|
14
|
-
class << self
|
15
|
-
attr_accessor :slug
|
16
|
-
end
|
17
|
-
end
|
18
20
|
|
19
|
-
def self.download(photoset, size = "medium_800")
|
20
|
-
PhotosetDownloader.new(photoset, size).download
|
21
|
-
end
|
22
|
-
|
23
|
-
def self.render_photoset(photoset, size)
|
24
|
-
download(photoset, size)
|
25
|
-
render_photo_pages(photoset)
|
26
|
-
render_photoset_index_page(photoset)
|
27
|
-
end
|
28
|
-
|
29
|
-
def self.render_photoset_index_page(photoset)
|
30
|
-
File.open("#{photoset.slug}.html", "w") do |f|
|
31
|
-
f.write render_erb("photoset", :photoset => photoset, :photos => photoset.photos, :size => "medium")
|
32
|
-
end
|
33
|
-
puts "#{photoset.slug}.html"
|
34
|
-
end
|
35
|
-
|
36
|
-
def self.render_photo_pages(photoset)
|
37
|
-
photoset.photos.each do |p|
|
38
|
-
render_photo_page(p)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
def self.render_photo_page(photo)
|
43
|
-
File.open(photo.local_html_path, "w") do |f|
|
44
|
-
f.write render_erb("photo", :source => photo.img_filename, :sizes => photo.sizes, :photo_url => photo.url, :title => photo.title, :author => photo.author)
|
45
|
-
end
|
46
|
-
puts "Rendered #{photo.local_html_path}"
|
47
|
-
end
|
48
|
-
|
49
|
-
def self.render_erb(template, locals)
|
50
|
-
full_template_path = File.expand_path("../../erb/#{template}.html.erb",__FILE__)
|
51
|
-
raise "unknown template: #{full_template_path}" unless File.exist?(full_template_path)
|
52
|
-
ERB.new(File.read(full_template_path)).result(OpenStruct.new(locals).instance_eval { binding })
|
53
|
-
end
|
54
21
|
end
|