flickr_offline_gallery 0.0.1
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 +7 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +25 -0
- data/Rakefile +6 -0
- data/bin/flickr_offline_gallery +18 -0
- data/erb/photo.html.erb +14 -0
- data/erb/photoset.html.erb +14 -0
- data/flickr_offline_gallery.gemspec +24 -0
- data/lib/flickr_offline_gallery/photo.rb +64 -0
- data/lib/flickr_offline_gallery/photo_size.rb +8 -0
- data/lib/flickr_offline_gallery/photo_sizes.rb +14 -0
- data/lib/flickr_offline_gallery/photoset.rb +31 -0
- data/lib/flickr_offline_gallery/photoset_downloader.rb +28 -0
- data/lib/flickr_offline_gallery/version.rb +3 -0
- data/lib/flickr_offline_gallery.rb +52 -0
- metadata +105 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 7d4ef914ca24ac0dcb26664919d275d97c91568f
|
4
|
+
data.tar.gz: 9db952754cf9040551478c733989e2f31bfaf6d4
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8b8233697f3c093b928e0459ebb91233b2018b7180faed26c77f1543a55dd04e58343c0f55c207d26ebe572ce12f11c42adfd4c234a04bfbe78a6e5b138e7b8d
|
7
|
+
data.tar.gz: 070ddb4019f6f63ff1a89415d5447c063accc642e776268b8cb664706cdcc6564b769bae83dbb3d05dde791e915692fbd63df5e6b432d02dae87ed17489dc9f0
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Lucas Parry
|
2
|
+
|
3
|
+
MIT License, unless you're the NSA in which case you can die in a fire
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# FlickrOfflineGallery
|
2
|
+
|
3
|
+
A tool to cache an offline copy of a flickr photoset, complete with all the html
|
4
|
+
embed fragments for all available sizes, allowing you to pick out photos for
|
5
|
+
blog posts/etc even without an internet connection.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
$ gem install flickr_offline_gallery
|
10
|
+
|
11
|
+
## Usage
|
12
|
+
|
13
|
+
$ flickr_offline_gallery <Flickr photoset id>
|
14
|
+
|
15
|
+
In a url like
|
16
|
+
`http://www.flickr.com/photos/83213379@N00/sets/72157636831703404/`, the
|
17
|
+
photoset id is the last part. ie `72157636831703404`
|
18
|
+
|
19
|
+
## Contributing
|
20
|
+
|
21
|
+
1. Fork it ( http://github.com/lparry/flickr_offline_gallery/fork )
|
22
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
23
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
24
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
25
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'flickr_offline_gallery'
|
4
|
+
|
5
|
+
FlickRaw.api_key = "#{ENV["FLICKR_API_KEY"]}"
|
6
|
+
FlickRaw.shared_secret = "#{ENV["FLICKR_SHARED_SECRET"]}"
|
7
|
+
|
8
|
+
if ARGV.size != 1
|
9
|
+
puts "FlickrOfflineGallery"
|
10
|
+
puts "--------------------"
|
11
|
+
puts "Create a local mirror of a Flickr photoset, complete with html embed fragments"
|
12
|
+
puts "\tUsage:"
|
13
|
+
puts "\t\tflickr_offline_gallery <flickr_photoset_id>"
|
14
|
+
exit
|
15
|
+
end
|
16
|
+
|
17
|
+
photoset = FlickrOfflineGallery::Photoset.new(ARGV.first)
|
18
|
+
FlickrOfflineGallery.render_photoset(photoset)
|
data/erb/photo.html.erb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
<html>
|
2
|
+
<head></head>
|
3
|
+
<body>
|
4
|
+
<img src="<%= source %>" />
|
5
|
+
<% sizes.each do |size| %>
|
6
|
+
<p><%= size.label %> </p>
|
7
|
+
<textarea style="height: 60px; width:800px;">
|
8
|
+
<a href="<%= photo_url %>" title="<%= title %> by <%= author %>, on Flickr"><img src="<%= size.source %>" width="<%= size.width %>" height="<%= size.height %>" alt="<%= title %>"></a>
|
9
|
+
</textarea>
|
10
|
+
<% end %>
|
11
|
+
</body>
|
12
|
+
</html>
|
13
|
+
|
14
|
+
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<html>
|
2
|
+
<head></head>
|
3
|
+
<body>
|
4
|
+
Photoset: <%= photoset.title %> by <% photoset.username %>
|
5
|
+
<% photos.each do |photo| %>
|
6
|
+
<a href="<%= photo.local_html_path %>"><img src="<%= photo.local_jpg_path %>"
|
7
|
+
width="<%= photo.sizes[size].width %>"
|
8
|
+
height="<%= photo.sizes[size].height %>"
|
9
|
+
/></a>
|
10
|
+
<% end %>
|
11
|
+
</body>
|
12
|
+
</html>
|
13
|
+
|
14
|
+
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'flickr_offline_gallery/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "flickr_offline_gallery"
|
8
|
+
spec.version = FlickrOfflineGallery::VERSION
|
9
|
+
spec.authors = ["Lucas Parry"]
|
10
|
+
spec.email = ["lparry@gmail.com"]
|
11
|
+
spec.summary = %q{Build a local copy of a flickr photoset}
|
12
|
+
spec.description = %q{Build a local copy of a flickr photoset, including html embed codes for all image sizes, for the purpose off picking photos for your blog even when there's no internet}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT, unless you're the NSA"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.4"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
spec.add_dependency "flickraw"
|
24
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module FlickrOfflineGallery
|
2
|
+
class Photo
|
3
|
+
|
4
|
+
attr_reader :id, :secret, :set
|
5
|
+
|
6
|
+
def initialize(horrible_flickraw_response_junk, photoset_id = nil)
|
7
|
+
@id = horrible_flickraw_response_junk["id"]
|
8
|
+
@secret = horrible_flickraw_response_junk["secret"]
|
9
|
+
@set = photoset_id
|
10
|
+
puts "Initialized #{@id}"
|
11
|
+
end
|
12
|
+
|
13
|
+
def title
|
14
|
+
info.title
|
15
|
+
end
|
16
|
+
|
17
|
+
def date
|
18
|
+
@date ||= DateTime.parse(info.dates["taken"])
|
19
|
+
end
|
20
|
+
|
21
|
+
def url
|
22
|
+
if set
|
23
|
+
"#{base_url}in/set-#{set}"
|
24
|
+
else
|
25
|
+
base_url
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def img_filename
|
30
|
+
"#{id}.jpg"
|
31
|
+
end
|
32
|
+
|
33
|
+
def local_jpg_path
|
34
|
+
"#{::FlickrOfflineGallery::Variables.slug}/#{img_filename}"
|
35
|
+
end
|
36
|
+
|
37
|
+
def local_html_path
|
38
|
+
local_jpg_path.sub(/\.jpg$/, ".html")
|
39
|
+
end
|
40
|
+
|
41
|
+
def base_url
|
42
|
+
@base_url ||= info.urls.find{|u| u["type"] == "photopage"}["_content"]
|
43
|
+
end
|
44
|
+
|
45
|
+
def sizes
|
46
|
+
@size ||= PhotoSizes.new(raw_sizes.to_a)
|
47
|
+
end
|
48
|
+
|
49
|
+
def author
|
50
|
+
@info.owner.username
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def info
|
56
|
+
@info ||= OpenStruct.new(flickr.photos.getInfo(:photo_id => @id).to_hash)
|
57
|
+
end
|
58
|
+
|
59
|
+
def raw_sizes
|
60
|
+
@raw_sizes ||= flickr.photos.getSizes :photo_id => @id
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module FlickrOfflineGallery
|
2
|
+
class PhotoSizes < OpenStruct
|
3
|
+
# commont attrs: large large_1600 large_2048 large_square medium medium_640 medium_800 original small small_320 square thumbnail
|
4
|
+
def initialize(raw_sizes)
|
5
|
+
super Hash[raw_sizes.map{|s| [s["label"].downcase.gsub(" ", "_"), PhotoSize.new(s)] }]
|
6
|
+
end
|
7
|
+
|
8
|
+
def each
|
9
|
+
to_h.values.each do |value|
|
10
|
+
yield(value)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module FlickrOfflineGallery
|
2
|
+
class Photoset
|
3
|
+
def initialize(photoset_id)
|
4
|
+
@photoset_id = photoset_id
|
5
|
+
::FlickrOfflineGallery::Variables.slug = slug
|
6
|
+
end
|
7
|
+
|
8
|
+
def username
|
9
|
+
info.username
|
10
|
+
end
|
11
|
+
|
12
|
+
def title
|
13
|
+
info.title
|
14
|
+
end
|
15
|
+
|
16
|
+
def slug
|
17
|
+
title.downcase.gsub(/[^a-z0-9]/, "-").gsub(/-+/, "-")
|
18
|
+
end
|
19
|
+
|
20
|
+
def photos
|
21
|
+
raise "photoset has more than 500 images and I'm too lazy to handle that right now" if info.pages > 1
|
22
|
+
@photos ||= info.photo.map { |raw_response| Photo.new(raw_response, @photoset_id) }
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def info
|
28
|
+
@info ||= OpenStruct.new(flickr.photosets.getPhotos(:photoset_id => @photoset_id).to_hash)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module FlickrOfflineGallery
|
2
|
+
class PhotosetDownloader
|
3
|
+
def initialize(photoset, size = "medium_800")
|
4
|
+
@photoset = photoset
|
5
|
+
@size = size
|
6
|
+
end
|
7
|
+
|
8
|
+
def download
|
9
|
+
photos.each do |photo|
|
10
|
+
url = photo.sizes[@size].source
|
11
|
+
local_path = photo.local_jpg_path
|
12
|
+
FileUtils.mkdir_p(File.dirname(local_path))
|
13
|
+
|
14
|
+
unless File.exist?(local_path)
|
15
|
+
#TODO: this is lazy, so sue me
|
16
|
+
`curl --location -so "#{local_path}" "#{url}"`
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def photos
|
24
|
+
@photoset.photos
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'flickraw'
|
2
|
+
require 'erb'
|
3
|
+
require 'fileutils'
|
4
|
+
|
5
|
+
require "flickr_offline_gallery/version"
|
6
|
+
require "flickr_offline_gallery/photo_size"
|
7
|
+
require "flickr_offline_gallery/photo_sizes"
|
8
|
+
require "flickr_offline_gallery/photo"
|
9
|
+
require "flickr_offline_gallery/photoset"
|
10
|
+
require "flickr_offline_gallery/photoset_downloader"
|
11
|
+
|
12
|
+
module FlickrOfflineGallery
|
13
|
+
class Variables
|
14
|
+
class << self
|
15
|
+
attr_accessor :slug
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.download(photoset)
|
20
|
+
PhotosetDownloader.new(photoset).download
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.render_photoset(photoset)
|
24
|
+
download(photoset)
|
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
|
+
end
|
34
|
+
|
35
|
+
def self.render_photo_pages(photoset)
|
36
|
+
photoset.photos.each do |p|
|
37
|
+
render_photo_page(p)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.render_photo_page(photo)
|
42
|
+
File.open(photo.local_html_path, "w") do |f|
|
43
|
+
f.write render_erb("photo", :source => photo.img_filename, :sizes => photo.sizes, :photo_url => photo.url, :title => photo.title, :author => photo.author)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.render_erb(template, locals)
|
48
|
+
full_template_path = File.expand_path("../../erb/#{template}.html.erb",__FILE__)
|
49
|
+
raise "unknown template: #{full_template_path}" unless File.exist?(full_template_path)
|
50
|
+
ERB.new(File.read(full_template_path)).result(OpenStruct.new(locals).instance_eval { binding })
|
51
|
+
end
|
52
|
+
end
|
metadata
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: flickr_offline_gallery
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Lucas Parry
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-01-03 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.4'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.4'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
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: flickraw
|
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
|
+
description: Build a local copy of a flickr photoset, including html embed codes for
|
56
|
+
all image sizes, for the purpose off picking photos for your blog even when there's
|
57
|
+
no internet
|
58
|
+
email:
|
59
|
+
- lparry@gmail.com
|
60
|
+
executables:
|
61
|
+
- flickr_offline_gallery
|
62
|
+
extensions: []
|
63
|
+
extra_rdoc_files: []
|
64
|
+
files:
|
65
|
+
- ".gitignore"
|
66
|
+
- Gemfile
|
67
|
+
- LICENSE.txt
|
68
|
+
- README.md
|
69
|
+
- Rakefile
|
70
|
+
- bin/flickr_offline_gallery
|
71
|
+
- erb/photo.html.erb
|
72
|
+
- erb/photoset.html.erb
|
73
|
+
- flickr_offline_gallery.gemspec
|
74
|
+
- lib/flickr_offline_gallery.rb
|
75
|
+
- lib/flickr_offline_gallery/photo.rb
|
76
|
+
- lib/flickr_offline_gallery/photo_size.rb
|
77
|
+
- lib/flickr_offline_gallery/photo_sizes.rb
|
78
|
+
- lib/flickr_offline_gallery/photoset.rb
|
79
|
+
- lib/flickr_offline_gallery/photoset_downloader.rb
|
80
|
+
- lib/flickr_offline_gallery/version.rb
|
81
|
+
homepage: ''
|
82
|
+
licenses:
|
83
|
+
- MIT, unless you're the NSA
|
84
|
+
metadata: {}
|
85
|
+
post_install_message:
|
86
|
+
rdoc_options: []
|
87
|
+
require_paths:
|
88
|
+
- lib
|
89
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - ">="
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
95
|
+
requirements:
|
96
|
+
- - ">="
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '0'
|
99
|
+
requirements: []
|
100
|
+
rubyforge_project:
|
101
|
+
rubygems_version: 2.2.0
|
102
|
+
signing_key:
|
103
|
+
specification_version: 4
|
104
|
+
summary: Build a local copy of a flickr photoset
|
105
|
+
test_files: []
|