flickr-tools 0.0.2
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.
- data/LICENSE +23 -0
- data/README.md +55 -0
- data/bin/flickr-tools +14 -0
- data/doc/flickr-upload.sh +9 -0
- data/doc/flickr.yml.example +3 -0
- data/lib/flickr-tools.rb +10 -0
- data/lib/flickr-tools/auth.rb +49 -0
- data/lib/flickr-tools/command.rb +38 -0
- data/lib/flickr-tools/core_ext.rb +5 -0
- data/lib/flickr-tools/get_set.rb +103 -0
- data/lib/flickr-tools/upload.rb +83 -0
- data/lib/flickr-tools/version.rb +3 -0
- data/lib/flickr_fu_ext.rb +14 -0
- data/lib/tempdir.rb +132 -0
- metadata +113 -0
data/LICENSE
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
Copyright (c) 2010 Jens Krämer, jk@jkraemer.net
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
|
+
|
22
|
+
|
23
|
+
|
data/README.md
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
Flickr toolchain
|
2
|
+
================
|
3
|
+
|
4
|
+
Collection of simple command line tools I use to handle my flickr needs.
|
5
|
+
|
6
|
+
Use at your own risk, ymmv.
|
7
|
+
|
8
|
+
Authorization
|
9
|
+
-------------
|
10
|
+
|
11
|
+
First of all you need to get an API key at flickr.com. Put the key and the secret into ~/.flickr-tools/flickr.yml:
|
12
|
+
|
13
|
+
key: your-flickr-api-key
|
14
|
+
secret: your-flickr-secret
|
15
|
+
token_cache: token_cache.yml
|
16
|
+
|
17
|
+
|
18
|
+
Now call
|
19
|
+
|
20
|
+
flickr-tools Auth username
|
21
|
+
|
22
|
+
This will prompt you to visit an URL at flickr.com to authorize write access for the application. Do so and press Enter.
|
23
|
+
The token received from flickr will be stored in ~/.flickr-tools/username.yml for further use.
|
24
|
+
|
25
|
+
|
26
|
+
|
27
|
+
Listing sets
|
28
|
+
------------
|
29
|
+
|
30
|
+
flickr-tools GetSet username
|
31
|
+
|
32
|
+
will list all sets in your flickr account.
|
33
|
+
|
34
|
+
|
35
|
+
Download whole set
|
36
|
+
------------------
|
37
|
+
|
38
|
+
flickr-tools GetSet username setname
|
39
|
+
|
40
|
+
Use this command to download all pictures (in 'original' size) of the named set. The result is a single zip file containing all images.
|
41
|
+
You can use the set id (as printed out by the set listing from above) or a fragment/regexp matching the set title. The first matching
|
42
|
+
set will be exported.
|
43
|
+
|
44
|
+
|
45
|
+
Upload Picture
|
46
|
+
--------------
|
47
|
+
|
48
|
+
flickr-tools Upload username /path/to/picture
|
49
|
+
|
50
|
+
I intend to use this command to directly upload images to flickr from a batch output queue in [Bibble](http://bibblelabs.com/).
|
51
|
+
Flickr metadata (privacy, tags, title, description) is extracted from iptc metadata contained in the picture. See lib/flickr-tools/upload.rb
|
52
|
+
for how it's mapped (and modify to suit your needs).
|
53
|
+
|
54
|
+
NOTE: Upload doesn't work, seems I'll have to fix flickr_fu first to make it work...
|
55
|
+
|
data/bin/flickr-tools
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'flickr-tools'
|
4
|
+
include FlickrTools
|
5
|
+
|
6
|
+
cmd = ARGV.shift
|
7
|
+
app = FlickrTools::const_get(cmd).new ARGV
|
8
|
+
|
9
|
+
# puts "running #{app.inspect}"
|
10
|
+
unless cmd == 'Auth'
|
11
|
+
FlickrTools::Auth.new(ARGV).check_token
|
12
|
+
end
|
13
|
+
app.run
|
14
|
+
|
data/lib/flickr-tools.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'flickr-tools/command'
|
2
|
+
|
3
|
+
module FlickrTools
|
4
|
+
|
5
|
+
# USAGE:
|
6
|
+
# flickr-tools Auth username
|
7
|
+
#
|
8
|
+
# the username argument is just a shorthand to identify the same user in further calls to other flickr-tools commands, must not equal your flickr username.
|
9
|
+
class Auth < Command
|
10
|
+
|
11
|
+
def run
|
12
|
+
authorize
|
13
|
+
end
|
14
|
+
|
15
|
+
def check_token(required_perms = :write)
|
16
|
+
res = flickr.auth.check_token
|
17
|
+
allowed_perms = case required_perms
|
18
|
+
when :read
|
19
|
+
%w(read write delete)
|
20
|
+
when :write
|
21
|
+
%w(write delete)
|
22
|
+
when :delete
|
23
|
+
%w(delete)
|
24
|
+
end
|
25
|
+
perm = res.auth.perms.to_s
|
26
|
+
if allowed_perms.include?(perm)
|
27
|
+
true
|
28
|
+
else
|
29
|
+
puts "insufficient permissions: #{perm}, required was: #{required_perms}"
|
30
|
+
false
|
31
|
+
end
|
32
|
+
rescue Exception
|
33
|
+
puts "check_token failed: #{$!}\n#{$!.backtrace.join("\n")}"
|
34
|
+
# authorize
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
def authorize
|
39
|
+
@flickr = nil
|
40
|
+
FileUtils.rm_f @token_cache
|
41
|
+
puts "please visit the following url, then press <enter> once you have authorized:"
|
42
|
+
# request permissions
|
43
|
+
puts flickr.auth.url(:delete)
|
44
|
+
STDIN.gets
|
45
|
+
flickr.auth.cache_token
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module FlickrTools
|
2
|
+
|
3
|
+
class Command
|
4
|
+
|
5
|
+
def self.find_config_dir
|
6
|
+
config_dir = File.expand_path('../../../config', __FILE__)
|
7
|
+
unless File.directory?(config_dir)
|
8
|
+
config_dir = File.join(ENV['HOME'], '.flickr-tools')
|
9
|
+
FileUtils.mkdir_p config_dir
|
10
|
+
end
|
11
|
+
return config_dir
|
12
|
+
end
|
13
|
+
|
14
|
+
|
15
|
+
def initialize(argv)
|
16
|
+
@config_dir = self.class.find_config_dir
|
17
|
+
@args = argv.dup
|
18
|
+
@name = @args.shift
|
19
|
+
@token_cache = File.join(@config_dir, "#{@name}.yml")
|
20
|
+
@flickr_yml = File.join @config_dir, 'flickr.yml'
|
21
|
+
unless File.readable?(@flickr_yml)
|
22
|
+
FileUtils.cp File.expand_path('../../../doc/flickr.yml.example', __FILE__), @flickr_yml
|
23
|
+
puts "Please get a flickr API key and secret from flickr.com and edit #{@flickr_yml} accordingly."
|
24
|
+
exit 1
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
protected
|
29
|
+
|
30
|
+
def flickr
|
31
|
+
@flickr ||= Flickr.new(@flickr_yml, :token_cache => @token_cache)
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
require 'flickr_fu'
|
2
|
+
require 'zip/zipfilesystem'
|
3
|
+
require 'open-uri'
|
4
|
+
|
5
|
+
require 'flickr-tools/command'
|
6
|
+
|
7
|
+
# USAGE:
|
8
|
+
# flickr-tools GetSet jk
|
9
|
+
# flickr-tools GetSet jk setname
|
10
|
+
module FlickrTools
|
11
|
+
class GetSet < Command
|
12
|
+
|
13
|
+
def run
|
14
|
+
set = @args.shift
|
15
|
+
|
16
|
+
if set.nil? || set.blank?
|
17
|
+
show_sets
|
18
|
+
else
|
19
|
+
get_set set
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
def show_sets
|
25
|
+
puts "getting sets for #{@name}"
|
26
|
+
flickr.photosets.get_list.each do |set|
|
27
|
+
puts set_description(set)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def get_set(id, size = :original)
|
32
|
+
if set = find_set(id)
|
33
|
+
puts "getting set #{set_description set}"
|
34
|
+
dir = set.title.to_filename
|
35
|
+
FileUtils.mkdir_p dir
|
36
|
+
puts "downloading to #{dir}/"
|
37
|
+
per_page = 200
|
38
|
+
@queue = Queue.new
|
39
|
+
1.upto((set.num_photos.to_i / per_page) + 1) do |page|
|
40
|
+
puts "."
|
41
|
+
set.get_photos(:page => page, :per_page => per_page).each do |p|
|
42
|
+
@queue.enq({ :url => p.url(size), :filename => "#{dir}/#{p.title.to_filename}.jpg" })
|
43
|
+
end
|
44
|
+
end
|
45
|
+
puts "found #{@queue.size} photos"
|
46
|
+
spawn_workers
|
47
|
+
wait_for_workers
|
48
|
+
else
|
49
|
+
puts "no set matching #{id} found."
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
protected
|
54
|
+
|
55
|
+
def find_set(id)
|
56
|
+
flickr.photosets.get_list.find{|set| set.id == id || set.title =~ /#{id}/i }
|
57
|
+
end
|
58
|
+
|
59
|
+
def set_description(set)
|
60
|
+
"#{set.id} #{set.title} (#{set.num_photos} photos)"
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
def spawn_workers(n = 5)
|
65
|
+
@workers = []
|
66
|
+
n.times do
|
67
|
+
t = Thread.new do
|
68
|
+
while !@stop && p = @queue.deq
|
69
|
+
begin
|
70
|
+
puts "downloading #{p[:url]}"
|
71
|
+
open( p[:url] ){ |f| (File.open(p[:filename], "w") << f.read).close }
|
72
|
+
rescue Exception
|
73
|
+
retries = (p[:retries] || 0) + 1
|
74
|
+
if retries < 3
|
75
|
+
@queue.enq p
|
76
|
+
else
|
77
|
+
puts "giving up downloading #{p.inspect}:\n#{$!}.message"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
@workers << t
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def wait_for_workers
|
87
|
+
while !@queue.empty?
|
88
|
+
puts "#{@queue.size} items left..."
|
89
|
+
sleep 30
|
90
|
+
end
|
91
|
+
puts "killing workers..."
|
92
|
+
@stop = true
|
93
|
+
@workers.each { |w| w.join }
|
94
|
+
puts "Done."
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
|
101
|
+
|
102
|
+
|
103
|
+
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'flickr_fu'
|
2
|
+
# require 'exifr'
|
3
|
+
require 'iptc'
|
4
|
+
require 'pp'
|
5
|
+
|
6
|
+
require 'flickr-tools/command'
|
7
|
+
|
8
|
+
module FlickrTools
|
9
|
+
|
10
|
+
# Upload one or more image files to flickr.
|
11
|
+
#
|
12
|
+
# USAGE:
|
13
|
+
# flickr-tools Upload jk path/to/image ...
|
14
|
+
#
|
15
|
+
# Flickr metadata is determined from the picture's IPTC metadata:
|
16
|
+
# title - iptc/Headline
|
17
|
+
# description - iptc/Caption
|
18
|
+
# tags - iptc/Keywords minus IGNORE_KEYWORDS and PRIVACY_KEYWORDS
|
19
|
+
# privacy - privacy level is set to the given PRIVACY_KEYWORD if also the 'privacy' keyword is present in iptc keywords, public otherwise.
|
20
|
+
#
|
21
|
+
# The keyword-to-tags treatment might seem strange, the reason is that Bibble uses hierarchical keyword trees which get flattened when written
|
22
|
+
# to IPTC meta data. That's why my pictures have these abstract first level keywords like 'place' and 'year' which I don't want to appear on flickr.
|
23
|
+
class Upload < Command
|
24
|
+
|
25
|
+
# list of keywords not to be used as flickr tags
|
26
|
+
IGNORE_KEYWORDS = %w(place year privacy subject)
|
27
|
+
|
28
|
+
# list of keywords used to determine the flickr privacy level. Photos are public by default.
|
29
|
+
PRIVACY_KEYWORDS = %w(private friends family friends_and_family)
|
30
|
+
|
31
|
+
def run
|
32
|
+
@uploader = Flickr::Uploader.new flickr
|
33
|
+
@args.each { |f| upload_file f }
|
34
|
+
puts "done."
|
35
|
+
end
|
36
|
+
|
37
|
+
protected
|
38
|
+
|
39
|
+
def upload_file(file)
|
40
|
+
if File.readable?(file)
|
41
|
+
meta = { :content_type => :photo, :safety_level => :safe, :hidden => false }.merge(metadata_for(file))
|
42
|
+
puts "uploading #{file} with\n#{meta.inspect}"
|
43
|
+
response = @uploader.upload file, meta
|
44
|
+
|
45
|
+
puts response.photoid
|
46
|
+
options = { :photo_id => response.photoid, :tags => meta[:tags] }
|
47
|
+
flickr.send_request('flickr.photos.setTags', options, :post)
|
48
|
+
else
|
49
|
+
puts "file not found: #{file}"
|
50
|
+
end
|
51
|
+
rescue Exception
|
52
|
+
puts "Error uploading #{file}: #{$!}\n#{$!.backtrace.join("\n")}"
|
53
|
+
end
|
54
|
+
|
55
|
+
def metadata_for(file)
|
56
|
+
iptc = iptc(file)
|
57
|
+
keywords = iptc["iptc/Keywords"].value rescue ''
|
58
|
+
{
|
59
|
+
:title => (iptc["iptc/Headline"].value.first rescue File.basename(file)),
|
60
|
+
:description => (iptc["iptc/Caption"].value.first rescue ''),
|
61
|
+
:tags => keywords_to_tags(keywords).join(' '),
|
62
|
+
:privacy => privacy(keywords)
|
63
|
+
}
|
64
|
+
end
|
65
|
+
|
66
|
+
def privacy(keywords)
|
67
|
+
privacy = ((keywords.include?('privacy') ? (keywords & PRIVACY_KEYWORDS).first : nil ) || 'public').to_sym
|
68
|
+
end
|
69
|
+
|
70
|
+
def keywords_to_tags(keywords)
|
71
|
+
keywords.map(&:downcase) - IGNORE_KEYWORDS - PRIVACY_KEYWORDS
|
72
|
+
end
|
73
|
+
|
74
|
+
def iptc(file)
|
75
|
+
IPTC::JPEG::Image.new(file).values
|
76
|
+
end
|
77
|
+
|
78
|
+
# def exif(file)
|
79
|
+
# pp EXIFR::JPEG.new(file).exif
|
80
|
+
# end
|
81
|
+
|
82
|
+
end
|
83
|
+
end
|
data/lib/tempdir.rb
ADDED
@@ -0,0 +1,132 @@
|
|
1
|
+
=begin rdoc
|
2
|
+
|
3
|
+
== tempdir.rb - provides class Tempdir
|
4
|
+
|
5
|
+
=== Synopsis
|
6
|
+
In order to
|
7
|
+
|
8
|
+
1. create a temporary directory with a name starting with "hoge",
|
9
|
+
2. show the name of that directory, and
|
10
|
+
3. show its properties with the system "ls -dl" command:
|
11
|
+
|
12
|
+
require 'tempdir'
|
13
|
+
|
14
|
+
d = Tempdir.new("hoge")
|
15
|
+
p d.to_s
|
16
|
+
system("ls", "-dl", d.to_s)
|
17
|
+
|
18
|
+
After the run, the directory will appear to be removed. That is: if you
|
19
|
+
are not running inside it, which may provide you a means to create a
|
20
|
+
directory with a unique name that will be available after the run.
|
21
|
+
|
22
|
+
=== Description
|
23
|
+
<i>tempdir.rb</i> provides the Tempdir class, which is analogous to the
|
24
|
+
Tempfile class, but manipulates temporary directories. Derived from a
|
25
|
+
proposal of nobu.nokada@softhome.net. He added the class to
|
26
|
+
tempfile.rb, but since it does not seem to appear in cvs, I'll keep
|
27
|
+
it apart in tempdir.rb.
|
28
|
+
|
29
|
+
=end
|
30
|
+
|
31
|
+
require 'tmpdir'
|
32
|
+
|
33
|
+
module AutoRemoval #:nodoc: all
|
34
|
+
MAX_TRY = 10
|
35
|
+
@@cleanlist = []
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def make_tmpname(basename, n)
|
40
|
+
sprintf('%s%d.%d', basename, $$, n)
|
41
|
+
end
|
42
|
+
private :make_tmpname
|
43
|
+
|
44
|
+
def createtmp(basename, tmpdir=Dir::tmpdir) # :nodoc:
|
45
|
+
if $SAFE > 0 and tmpdir.tainted?
|
46
|
+
tmpdir = '/tmp'
|
47
|
+
end
|
48
|
+
|
49
|
+
lock = nil
|
50
|
+
n = failure = 0
|
51
|
+
|
52
|
+
begin
|
53
|
+
Thread.critical = true
|
54
|
+
begin
|
55
|
+
tmpname = File.join(tmpdir, make_tmpname(basename, n))
|
56
|
+
n += 1
|
57
|
+
end until !@@cleanlist.include?(tmpname) and yield(tmpname)
|
58
|
+
rescue
|
59
|
+
p $!
|
60
|
+
failure += 1
|
61
|
+
retry if failure < MAX_TRY
|
62
|
+
raise "cannot generate tempfile `%s'" % tmpname
|
63
|
+
ensure
|
64
|
+
Thread.critical = false
|
65
|
+
end
|
66
|
+
|
67
|
+
tmpname
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.callback(path, clear) # :nodoc:
|
71
|
+
@@cleanlist << path
|
72
|
+
data = [path]
|
73
|
+
pid = $$
|
74
|
+
return Proc.new {
|
75
|
+
if pid == $$
|
76
|
+
path, tmpfile = *data
|
77
|
+
|
78
|
+
print "removing ", path, "..." if $DEBUG
|
79
|
+
|
80
|
+
tmpfile.close if tmpfile
|
81
|
+
|
82
|
+
# keep this order for thread safeness
|
83
|
+
if File.exist?(path)
|
84
|
+
clear.call(path)
|
85
|
+
end
|
86
|
+
@@cleanlist.delete(path)
|
87
|
+
|
88
|
+
print "done\n" if $DEBUG
|
89
|
+
end
|
90
|
+
}, data
|
91
|
+
end
|
92
|
+
|
93
|
+
def self.unregister(path)
|
94
|
+
@@cleanlist.delete(path)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
require 'pathname'
|
99
|
+
class Tempdir < Pathname #:nodoc: all
|
100
|
+
include AutoRemoval
|
101
|
+
|
102
|
+
def initialize(*args)
|
103
|
+
require 'fileutils'
|
104
|
+
|
105
|
+
tmpname = createtmp(*args) do |tmpname|
|
106
|
+
unless File.exist?(tmpname)
|
107
|
+
Dir.mkdir(tmpname, 0700)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
super(tmpname)
|
112
|
+
@clean_proc, = AutoRemoval.callback(tmpname, FileUtils.method(:rm_rf))
|
113
|
+
ObjectSpace.define_finalizer(self, @clean_proc) end
|
114
|
+
|
115
|
+
def open(basename, *modes, &block)
|
116
|
+
File.open(self+basename, *modes, &block)
|
117
|
+
end
|
118
|
+
|
119
|
+
def clear
|
120
|
+
FileUtils.rm_rf(@tmpname)
|
121
|
+
@clean_proc.call
|
122
|
+
ObjectSpace.undefine_finalizer(self)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
if __FILE__ == $0
|
127
|
+
# $DEBUG = true
|
128
|
+
d = Tempdir.new("hoge")
|
129
|
+
p d.to_s
|
130
|
+
system("ls", "-dl", d.to_s)
|
131
|
+
p d
|
132
|
+
end
|
metadata
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: flickr-tools
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.0.2
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Jens Kraemer
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2011-04-27 00:00:00 +02:00
|
14
|
+
default_executable:
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: rubyzip
|
18
|
+
prerelease: false
|
19
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
20
|
+
none: false
|
21
|
+
requirements:
|
22
|
+
- - ">="
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: "0"
|
25
|
+
type: :runtime
|
26
|
+
version_requirements: *id001
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: xml-magic
|
29
|
+
prerelease: false
|
30
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
31
|
+
none: false
|
32
|
+
requirements:
|
33
|
+
- - ">="
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: "0"
|
36
|
+
type: :runtime
|
37
|
+
version_requirements: *id002
|
38
|
+
- !ruby/object:Gem::Dependency
|
39
|
+
name: tomk32-flickr_fu
|
40
|
+
prerelease: false
|
41
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 0.3.4
|
47
|
+
type: :runtime
|
48
|
+
version_requirements: *id003
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: iptc
|
51
|
+
prerelease: false
|
52
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: 0.0.2
|
58
|
+
type: :runtime
|
59
|
+
version_requirements: *id004
|
60
|
+
description: You're definitely going to want to replace a lot of this
|
61
|
+
email:
|
62
|
+
- jk@jkraemer.net
|
63
|
+
executables:
|
64
|
+
- flickr-tools
|
65
|
+
extensions: []
|
66
|
+
|
67
|
+
extra_rdoc_files: []
|
68
|
+
|
69
|
+
files:
|
70
|
+
- lib/flickr-tools/auth.rb
|
71
|
+
- lib/flickr-tools/command.rb
|
72
|
+
- lib/flickr-tools/core_ext.rb
|
73
|
+
- lib/flickr-tools/get_set.rb
|
74
|
+
- lib/flickr-tools/upload.rb
|
75
|
+
- lib/flickr-tools/version.rb
|
76
|
+
- lib/flickr-tools.rb
|
77
|
+
- lib/flickr_fu_ext.rb
|
78
|
+
- lib/tempdir.rb
|
79
|
+
- bin/flickr-tools
|
80
|
+
- LICENSE
|
81
|
+
- README.md
|
82
|
+
- doc/flickr-upload.sh
|
83
|
+
- doc/flickr.yml.example
|
84
|
+
has_rdoc: true
|
85
|
+
homepage: http://github.com/carlhuda/newgem
|
86
|
+
licenses: []
|
87
|
+
|
88
|
+
post_install_message:
|
89
|
+
rdoc_options: []
|
90
|
+
|
91
|
+
require_paths:
|
92
|
+
- lib
|
93
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
94
|
+
none: false
|
95
|
+
requirements:
|
96
|
+
- - ">="
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: "0"
|
99
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
100
|
+
none: false
|
101
|
+
requirements:
|
102
|
+
- - ">="
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: 1.3.6
|
105
|
+
requirements: []
|
106
|
+
|
107
|
+
rubyforge_project: newgem
|
108
|
+
rubygems_version: 1.5.3
|
109
|
+
signing_key:
|
110
|
+
specification_version: 3
|
111
|
+
summary: flickr utitlity library
|
112
|
+
test_files: []
|
113
|
+
|