photo-helper 0.1.6 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0be27d55e45279438bebd74f439291396788032b
4
- data.tar.gz: 709c806844f962459fb604b2db183a20ed486098
3
+ metadata.gz: 74fe4a8df21965e6b330ce5f80b52602a26b447a
4
+ data.tar.gz: f77f8d97e6e3019e948de0edb00bd61f58b8d92c
5
5
  SHA512:
6
- metadata.gz: d681f992c9f1d9d55b2b8c5430cdcb078324d0b3d536d6f0eaa3e59efc3aa2c0878f23127e106987afa36fa27322d688ae64dd3a9d11c0dd156b90ac54f93537
7
- data.tar.gz: e1e5f1d25db2160dbe097d5ac4070076685e96d93db73bfac37f8e0a6c984219146cc6e667f27fd0b0bd2c295d9cb804023590e887cce5915024dc79f9c58fef
6
+ metadata.gz: 3aec807f26f222bf5764fc2213c5efa75f88168fe24fa67c59d4bd0bd6cc8663580bb3bb0d8ff1deb08842c3a604e3bac02c77c2943426682dcf758a72d0765c
7
+ data.tar.gz: 0d8a2ec77bc0b2e5825cafa386bcc0a7b9ded76a538f3d21ef1065585270174001474cdf1bd6a918f9cf292ad3a33e4fe2cd574376c6791e8563a8367c2a12f5
data/.gitignore CHANGED
@@ -48,3 +48,5 @@ build-iPhoneSimulator/
48
48
 
49
49
  # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
50
50
  .rvmrc
51
+ .DS_Store
52
+ .byebug_history
data/Gemfile.lock CHANGED
@@ -1,8 +1,12 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- photo-helper (0.1.6)
4
+ photo-helper (0.2.0)
5
+ ejson
6
+ mimemagic
5
7
  mini_magick
8
+ oauth
9
+ parallel
6
10
  thor
7
11
 
8
12
  GEM
@@ -13,7 +17,9 @@ GEM
13
17
  builder (3.2.3)
14
18
  byebug (9.0.6)
15
19
  coderay (1.1.1)
20
+ ejson (1.1.0)
16
21
  method_source (0.8.2)
22
+ mimemagic (0.3.2)
17
23
  mini_magick (4.8.0)
18
24
  minitest (5.10.3)
19
25
  minitest-reporters (1.1.14)
@@ -21,6 +27,7 @@ GEM
21
27
  builder
22
28
  minitest (>= 5.0)
23
29
  ruby-progressbar
30
+ oauth (0.5.3)
24
31
  parallel (1.12.0)
25
32
  parser (2.4.0.0)
26
33
  ast (~> 2.2)
@@ -41,7 +48,7 @@ GEM
41
48
  unicode-display_width (~> 1.0, >= 1.0.1)
42
49
  ruby-progressbar (1.8.1)
43
50
  slop (3.6.0)
44
- thor (0.19.4)
51
+ thor (0.20.0)
45
52
  unicode-display_width (1.3.0)
46
53
 
47
54
  PLATFORMS
@@ -58,4 +65,4 @@ DEPENDENCIES
58
65
  rubocop
59
66
 
60
67
  BUNDLED WITH
61
- 1.15.4
68
+ 1.16.0
data/bin/console CHANGED
@@ -1,7 +1,12 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require "bundler/setup"
4
- require "kube-deploy"
4
+
5
+
6
+ lib = File.expand_path('../lib', __FILE__)
7
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
8
+
9
+ require 'photo_helper'
5
10
 
6
11
  # You can add fixtures and/or initialization code here to make experimenting
7
12
  # with your gem easier. You can also use a different console, if you like.
data/bin/smugmug ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'byebug'
5
+ require 'pp'
6
+
7
+ lib = File.expand_path('../lib', __FILE__)
8
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
9
+
10
+ require 'photo_helper'
11
+
12
+ require 'helpers/smugmug_api'
13
+
14
+ s = SmugmugAPI.new
15
+ puts s.image_list('xDT29x').sort
@@ -1,14 +1,14 @@
1
1
  class FileHelper
2
- def self.directory(path)
3
- File.dirname(path).split("/").last
4
- end
2
+ def self.directory(path)
3
+ File.dirname(path).split('/').last
4
+ end
5
5
 
6
- def self.ingore_file?(path)
7
- IGNORE_FOLDERS.include? directory(path).downcase
8
- end
6
+ def self.ingore_file?(path)
7
+ IGNORE_FOLDERS.include? directory(path).downcase
8
+ end
9
9
 
10
- def self.is_jpeg?(path)
11
- extension = File.extname(path)
12
- [".jpeg", ".jpg"].include? extension.downcase
13
- end
14
- end
10
+ def self.is_jpeg?(path)
11
+ extension = File.extname(path)
12
+ ['.jpeg', '.jpg'].include? extension.downcase
13
+ end
14
+ end
@@ -0,0 +1,11 @@
1
+ class ImageHelper
2
+ IMAGE_CLASS_REGEX = %r{xmp:Label="(.+)"}
3
+
4
+ def self.color_class(image)
5
+ xmp = File.join(File.dirname(image), File.basename(image, ".*") + ".XMP")
6
+ return unless File.exists?(xmp)
7
+ contents = File.read(xmp)
8
+ matches = contents.match(IMAGE_CLASS_REGEX)
9
+ matches[1] if matches
10
+ end
11
+ end
@@ -0,0 +1,83 @@
1
+ # require "ejson"
2
+
3
+ require 'open3'
4
+ require 'pathname'
5
+ require 'json'
6
+
7
+ class Secrets
8
+ def initialize(config_file = nil, required = [])
9
+ @secrets = {}
10
+ unless config_file.nil?
11
+ load_from_ejson(config_file)
12
+ load_from_env(@secrets.keys)
13
+ end
14
+ unless required.empty?
15
+ load_from_env(required)
16
+ check_required(required)
17
+ end
18
+ end
19
+
20
+ def load_from_ejson(ejson_path)
21
+ ejson_path = File.absolute_path(ejson_path) unless Pathname.new(ejson_path).absolute?
22
+ raise "config file: #{ejson_path} not found" unless File.exist?(ejson_path)
23
+
24
+ encrypted_json = JSON.parse(File.read(ejson_path))
25
+ public_key = encrypted_json['_public_key']
26
+ private_key_path = "/opt/ejson/keys/#{public_key}"
27
+ raise "Private key is not listed in #{private_key_path}." unless File.exist?(private_key_path)
28
+
29
+ output, status = Open3.capture2e("ejson", "decrypt", ejson_path.to_s)
30
+ raise "ejson: #{output}" unless status.success?
31
+
32
+ secrets = JSON.parse(output)
33
+ secrets = hash_symblize_keys(secrets)
34
+
35
+ @secrets.merge!(secrets)
36
+ end
37
+
38
+ def load_from_env(keys)
39
+ secrets = {}
40
+ keys.each do |key|
41
+ key = key.to_s
42
+ next if key.start_with?("_")
43
+ value = ENV[key.upcase]
44
+ secrets[key] = value unless value.nil?
45
+ end
46
+
47
+ secrets = hash_symblize_keys(secrets)
48
+ @secrets.merge!(secrets)
49
+ end
50
+
51
+ def check_required(required = [])
52
+ required.each { |key| raise "required secrets not set: #{key}" if @secrets[key].nil? }
53
+ end
54
+
55
+ def method_missing(key, *args)
56
+ value = @secrets[key]
57
+ return value unless value.nil?
58
+ puts "no secret for key: #{key}"
59
+ super
60
+ end
61
+
62
+ def respond_to_missing?(*args)
63
+ super
64
+ end
65
+
66
+ def hash_symblize_keys(hash)
67
+ hash.keys.each do |key|
68
+ hash[(begin
69
+ key.to_sym
70
+ rescue
71
+ key
72
+ end) || key] = hash.delete(key)
73
+ end
74
+ hash
75
+ end
76
+ end
77
+
78
+ # a = Secrets.new("config/secrets.ejson", [:hello])
79
+
80
+ # a.check_required([:cloud_at_cost_email, :cloud_at_cost_api_key])
81
+
82
+ # puts a.cloud_at_cost_email
83
+ # puts a.hello
@@ -0,0 +1,268 @@
1
+ require 'helpers/secrets'
2
+ require 'oauth'
3
+ require 'uri'
4
+ require 'json'
5
+ require 'mimemagic'
6
+ require 'parallel'
7
+
8
+ class SmugmugAPI
9
+ attr_accessor :http, :uploader
10
+ OAUTH_ORIGIN = 'https://secure.smugmug.com'.freeze
11
+ REQUEST_TOKEN_URL = '/services/oauth/1.0a/getRequestToken'.freeze
12
+ ACCESS_TOKEN_URL = '/services/oauth/1.0a/getAccessToken'.freeze
13
+ AUTHORIZE_URL = '/services/oauth/1.0a/authorize'.freeze
14
+ API_ENDPOINT = 'https://api.smugmug.com'.freeze
15
+ UPLOAD_ENDPOINT = 'http://upload.smugmug.com/'.freeze
16
+
17
+ def initialize(ejson_file = '~/.photo_helper.ejson')
18
+ ejson_file = File.expand_path(ejson_file)
19
+ @secrets = Secrets.new(ejson_file, %i[api_key api_secret])
20
+ get_access_token if !@secrets.access_token || !@secrets.access_secret
21
+
22
+ @http = get_access_token
23
+ @uploader = get_access_token(UPLOAD_ENDPOINT)
24
+ user_resp = user
25
+ @user = user_resp['NickName']
26
+ @root_node = File.basename(user_resp['Uris']['Node']['Uri'])
27
+ end
28
+
29
+ def albums
30
+ albums_list = []
31
+ start = 1
32
+ count = 100
33
+ loop do
34
+ resp = get("/api/v2/user/#{@user}!albums", start: start, count: count)
35
+
36
+ resp['Album'].each do |album|
37
+ albums_list.push(album_parser(album))
38
+ end
39
+ break if (start + count) > resp['Pages']['Total'].to_i
40
+ start += count
41
+ end
42
+ albums_list
43
+ end
44
+
45
+ def albums_long(path = '', node_id = @root_node)
46
+ album_list = []
47
+ node_children(node_id)['Node'].each do |node|
48
+ node_path = path.empty? ? node['Name'] : File.join(path, node['Name'])
49
+ case node['Type']
50
+ when 'Folder'
51
+ album_list.concat(albums_long(node_path, node['NodeID']))
52
+ when 'Album'
53
+ album_list.push(path: node_path,
54
+ name: node['Name'],
55
+ web_uri: node['WebUri'],
56
+ node_uri: node['Uri'],
57
+ id: File.basename(node['Uris']['Album']['Uri']))
58
+ end
59
+ end
60
+ album_list
61
+ end
62
+
63
+ def node_children(id)
64
+ get("/api/v2/node/#{id}!children")
65
+ end
66
+
67
+ def user
68
+ get('/api/v2!authuser')['User']
69
+ end
70
+
71
+ def images; end
72
+
73
+ def folders
74
+ folder_list = []
75
+ resp = get('/api/v2/folder/user/bcaldwell!folderlist')
76
+ resp['FolderList'].each do |folder|
77
+ folder_list.push(folder_parser(folder))
78
+ end
79
+ folder_list
80
+ end
81
+
82
+ def get_or_create_album(path, album_url: nil)
83
+ folder_path = File.dirname(path).split('/').map(&:capitalize).join('/')
84
+ album_name = File.basename(path).split(' ').map(&:capitalize).join(' ')
85
+ puts album_name
86
+ album = nil
87
+
88
+ folder = get_or_create_folder(folder_path)
89
+ resp = get(folder[:albums_url])
90
+ albums = get(folder[:albums_url])['Album'] if resp.key? 'Album'
91
+ albums ||= []
92
+ albums.each do |album_raw|
93
+ next unless album_raw['Name'] == album_name
94
+ album = album_parser(album_raw)
95
+ end
96
+
97
+ if album.nil?
98
+ url = "/api/v2/folder/user/#{@user}"
99
+ url += "/#{folder_path}" unless folder_path.empty?
100
+ url += '!albums'
101
+ album_url = album_name if album_url.nil?
102
+ resp = post(url, Name: album_name,
103
+ UrlName: album_url.tr(' ', '-').capitalize,
104
+ Privacy: 'Unlisted',
105
+ SmugSearchable: "No",
106
+ SortMethod: "Date Taken",
107
+ LargestSize: "X4Large",
108
+ SortDirection: "Ascending",
109
+ WorldSearchable: false,
110
+ EXIF: false,
111
+ Printable: false,
112
+ Filenames: true)
113
+ album_raw = resp['Album']
114
+ album = album_parser(album_raw)
115
+ end
116
+ album
117
+ end
118
+
119
+ def get_or_create_folder(path)
120
+ parts = path.split('/')
121
+ current_path = ''
122
+ folder = nil
123
+
124
+ parts.each do |part|
125
+ part = part.capitalize
126
+ new_path = current_path.empty? ? part : File.join(current_path, part)
127
+ resp = http_raw(:get, "/api/v2/folder/user/#{@user}/#{new_path}")
128
+ if resp.is_a? Net::HTTPSuccess
129
+ folder_raw = JSON.parse(resp.body)['Response']['Folder']
130
+ folder = folder_parser(folder_raw)
131
+ else
132
+ url = "/api/v2/folder/user/#{@user}"
133
+ url += "/#{current_path}" unless current_path.empty?
134
+ url += '!folders'
135
+ resp = post(url, Name: part.capitalize,
136
+ UrlName: part.tr(' ', '-').capitalize,
137
+ Privacy: 'Unlisted')
138
+ folder = folder_parser(resp['Folder'])
139
+ end
140
+ current_path = new_path
141
+ end
142
+
143
+ folder
144
+ end
145
+
146
+ def images(album_id)
147
+ images = []
148
+ start = 1
149
+ count = 100
150
+ loop do
151
+ images_raw = get("/api/v2/album/#{album_id}!images", start: start, count: count)
152
+ return [] unless images_raw.key? 'AlbumImage'
153
+ images_raw['AlbumImage'].each do |image|
154
+ images.push(imager_parser(image))
155
+ end
156
+ break if (start + count) > images_raw['Pages']['Total'].to_i
157
+ start += count
158
+ end
159
+ images
160
+ end
161
+
162
+ def image_list(album_id)
163
+ @images = images(album_id)
164
+ @images.map { |i| i[:filename] }
165
+ end
166
+
167
+ def http(method, url, headers = {}, _body = nil)
168
+ response = http_raw(method, url, headers, _body)
169
+ raise 'Request failed' unless response.is_a? Net::HTTPSuccess
170
+ JSON.parse(response.body)['Response']
171
+ end
172
+
173
+ def get(url, params = nil, headers = {})
174
+ url.tr!(' ', '-')
175
+ uri = URI.parse(url)
176
+ uri.query = URI.encode_www_form(params) if params
177
+ http(:get, uri.to_s, headers)
178
+ end
179
+
180
+ def post(url, body = {}, headers = {})
181
+ url.tr!(' ', '-')
182
+ headers['Accept'] = 'application/json'
183
+ response = @http.post(url, body, headers)
184
+ raise "Request failed\n#{response.body}" unless response.is_a? Net::HTTPSuccess
185
+ JSON.parse(response.body)['Response']
186
+ end
187
+
188
+ def upload(image_path, album_id, headers = {})
189
+ image = File.open(image_path)
190
+
191
+ headers.merge!('Content-Type' => MimeMagic.by_path(image_path).type,
192
+ 'X-Smug-AlbumUri' => "/api/v2/album/#{album_id}",
193
+ 'X-Smug-ResponseType' => 'JSON',
194
+ 'X-Smug-Version' => 'v2',
195
+ 'charset' => 'UTF-8',
196
+ 'Accept' => 'JSON',
197
+ 'X-Smug-FileName' => File.basename(image_path),
198
+ 'Content-MD5' => Digest::MD5.file(image_path).hexdigest)
199
+
200
+ resp = @uploader.post('/', image, headers)
201
+ resp.body
202
+ end
203
+
204
+ def upload_images(images, album_id, headers = {}, workers: 4)
205
+ counter = 0
206
+ Parallel.each(images, in_processes: workers) do |image|
207
+ upload(image, album_id, headers)
208
+ counter += 1
209
+ puts "#{counter}/#{images.count / workers} Done #{image}"
210
+ end
211
+ end
212
+
213
+ private
214
+
215
+ def request_access_token
216
+ raise 'Not Implemented'
217
+ end
218
+
219
+ def http_raw(method, url, headers = {}, _body = nil)
220
+ url.tr!(' ', '-')
221
+ headers['Accept'] = 'application/json'
222
+
223
+ @http.request(method, url, headers)
224
+ end
225
+
226
+ def get_access_token(endpoint = API_ENDPOINT)
227
+ @consumer = OAuth::Consumer.new(
228
+ @secrets.api_key,
229
+ @secrets.api_secret,
230
+ site: endpoint
231
+ )
232
+ # # Create the access_token for all traffic
233
+ OAuth::AccessToken.new(@consumer, @secrets.access_token, @secrets.access_secret)
234
+ end
235
+
236
+ def folder_parser(folder)
237
+ {
238
+ name: folder['Name'],
239
+ url_name: folder['UrlName'],
240
+ web_uri: folder['UrlPath'],
241
+ uri: folder['Uri'],
242
+ albums_url: folder['Uris']['FolderAlbums']['Uri'],
243
+ type: 'folder'
244
+ }
245
+ end
246
+
247
+ def album_parser(album)
248
+ { name: album['Name'],
249
+ id: album['AlbumKey'],
250
+ web_uri: album['WebUri'],
251
+ images_uri: album['Uris']['AlbumImages']['Uri'],
252
+ type: 'album' }
253
+ end
254
+
255
+ def imager_parser(image)
256
+ {
257
+ title: image['Title'],
258
+ filename: image['FileName'],
259
+ caption: image['Caption'],
260
+ keywords: image['KeywordArray'],
261
+ id: image['ImageKey'],
262
+ md5: image['ArchivedMD5'],
263
+ uri: image['Uri'],
264
+ web_uri: image['WebUri'],
265
+ type: 'image'
266
+ }
267
+ end
268
+ end
@@ -1,24 +1,24 @@
1
- require "helpers/trash"
1
+ require 'helpers/trash'
2
2
 
3
3
  module PhotoHelper
4
4
  class Delete < Thor
5
5
  include Thor::Actions
6
6
 
7
- map "j" => "jpeg"
8
- map "jpg" => "jpeg"
9
- map "jpgs" => "jpeg"
10
- map "jpegs" => "jpeg"
7
+ map 'j' => 'jpeg'
8
+ map 'jpg' => 'jpeg'
9
+ map 'jpgs' => 'jpeg'
10
+ map 'jpegs' => 'jpeg'
11
11
 
12
- desc "jpeg", "delete jpegs that have an raw with same name"
13
- method_option :folder, aliases: "-f", type: :string, default: "."
14
- method_option :hard, aliases: "-h", type: :boolean, default: false
15
- method_option :recursive, aliases: "-r", type: :boolean, default: false
12
+ desc 'jpeg', 'delete jpegs that have an raw with same name'
13
+ method_option :folder, aliases: '-f', type: :string, default: '.'
14
+ method_option :hard, aliases: '-h', type: :boolean, default: false
15
+ method_option :recursive, aliases: '-r', type: :boolean, default: false
16
16
  def jpeg(folder = nil)
17
17
  folder ||= options[:folder]
18
18
  puts folder
19
19
 
20
20
  search_path = File.expand_path(folder)
21
- jpeg_path = File.join(search_path, "jpegs")
21
+ jpeg_path = File.join(search_path, 'jpegs')
22
22
 
23
23
  files =
24
24
  if options[:recursive]
@@ -40,14 +40,13 @@ module PhotoHelper
40
40
  end
41
41
  end
42
42
 
43
- return unless File.exist?(jpeg_path) && yes?("Delete jpeg folder?")
44
- say "Deleting jpeg folder", :red
43
+ return unless File.exist?(jpeg_path) && yes?('Delete jpeg folder?')
44
+ say 'Deleting jpeg folder', :red
45
45
  if options[:hard]
46
46
  File.delete(jpeg_path)
47
47
  else
48
48
  File.trash(jpeg_path)
49
49
  end
50
-
51
50
  end
52
51
  end
53
52
  end
@@ -4,35 +4,32 @@ module PhotoHelper
4
4
  class Generate < Thor
5
5
  include Thor::Actions
6
6
 
7
- map "j" => "jpeg"
8
- map "jpg" => "jpeg"
9
- map "jpgs" => "jpeg"
10
- map "jpegs" => "jpeg"
7
+ map 'j' => 'jpeg'
8
+ map 'jpg' => 'jpeg'
9
+ map 'jpgs' => 'jpeg'
10
+ map 'jpegs' => 'jpeg'
11
11
 
12
- desc "jpeg", "generate jpeg from raw files"
13
- method_option :folder, aliases: "-f", type: :string, default: "."
12
+ desc 'jpeg', 'generate jpeg from raw files'
13
+ method_option :folder, aliases: '-f', type: :string, default: '.'
14
14
  method_option :dpi, type: :numeric, default: 350
15
15
  def jpeg(folder = nil)
16
16
  folder ||= options[:folder]
17
17
  puts folder
18
18
 
19
19
  search_path = File.expand_path(folder)
20
- jpeg_path = File.join(search_path, "jpegs")
20
+ jpeg_path = File.join(search_path, 'jpegs')
21
21
 
22
- Dir.mkdir(jpeg_path) unless File.exists?(jpeg_path)
22
+ Dir.mkdir(jpeg_path) unless File.exist?(jpeg_path)
23
23
 
24
24
  files = Dir["#{search_path}/*.#{RAW_EXTENSION}"]
25
25
 
26
26
  files.each do |file|
27
- jpeg_file_name = File.basename(file.to_s, RAW_EXTENSION) + JPEG_EXTENSION
28
- next if File.exists? File.join(search_path, jpeg_file_name)
27
+ jpeg_file_name = File.basename(file.to_s, RAW_EXTENSION) + JPEG_EXTENSION
28
+ next if File.exist? File.join(search_path, jpeg_file_name)
29
29
  puts file
30
30
 
31
31
  `sips -s format jpeg #{file} -s dpiHeight #{options[:dpi]} -s dpiWidth #{options[:dpi]} --out "./jpegs/#{jpeg_file_name}.JPG"`
32
32
  end
33
-
34
-
35
33
  end
36
-
37
34
  end
38
35
  end
@@ -0,0 +1,48 @@
1
+ require 'helpers/smugmug_api'
2
+ require 'date'
3
+ require 'helpers/image_helper'
4
+
5
+ module PhotoHelper
6
+ class Smugmug < Thor
7
+ include Thor::Actions
8
+ PATH_REGEX = %r{^.+Pictures\/.+\/(\d{4})\/(\d{2})_.+\/[^_]+_([^\/]+)}
9
+
10
+ map 's' => 'sync'
11
+
12
+ desc 'sync', "sync folder's non-raw images with smugmug"
13
+ method_option :folder, aliases: '-f', type: :string, default: '.'
14
+ method_option :recursive, aliases: '-r', type: :boolean, default: false
15
+ method_option :dry_run, aliases: '-d', type: :boolean, default: false
16
+ def sync(folder = nil, album_name = nil)
17
+ search_path = File.expand_path(folder)
18
+ puts search_path
19
+ unless album_name
20
+ if matches = "#{search_path}/".to_s.match(PATH_REGEX)
21
+ year = matches[1]
22
+ month = Date::MONTHNAMES[matches[2].to_i].capitalize
23
+ location = matches[3].split("_").map(&:capitalize).join(' ')
24
+
25
+ folder = "#{month} #{year}"
26
+ album_name_short = "#{location} #{month} #{year}"
27
+ album_name = File.join(year, month, album_name_short)
28
+ else
29
+ puts 'Unable to determine album from path'
30
+ return
31
+ end
32
+ end
33
+ puts "Using album: #{album_name}"
34
+
35
+ @smugmug = SmugmugAPI.new
36
+ album = @smugmug.get_or_create_album(album_name, album_url: location.downcase)
37
+ puts "#{album[:web_uri]}\n"
38
+ pictures = Dir["#{search_path}/**/*.JPG"]
39
+
40
+ # remove uploaded pictures
41
+ uploaded = @smugmug.image_list(album[:id])
42
+ pictures = pictures.reject { |p| (ImageHelper.color_class(p) == "Trash" or uploaded.include? File.basename(p)) }
43
+ puts "Uploading #{pictures.count} jpegs"
44
+
45
+ @smugmug.upload_images(pictures, album[:id], workers: 8)
46
+ end
47
+ end
48
+ end
@@ -1,3 +1,3 @@
1
1
  module KubeDeploy
2
- VERSION = "0.1.6"
2
+ VERSION = "0.2.0"
3
3
  end
data/lib/photo_helper.rb CHANGED
@@ -8,6 +8,7 @@ require 'photo-helper/delete'
8
8
  require 'photo-helper/move'
9
9
  require 'photo-helper/instagram'
10
10
  require 'photo-helper/compress'
11
+ require 'photo-helper/smugmug'
11
12
 
12
13
  # todo: move to config file
13
14
  # RAW_EXTENSION = "ORF"
@@ -32,5 +33,6 @@ module PhotoHelper
32
33
  register PhotoHelper::Instagram, :instagram, "instagram", "Do something else"
33
34
  register PhotoHelper::Move, :move, "move", "Do something else"
34
35
  register PhotoHelper::Compress, :compress, "compress", "Do something else"
36
+ register PhotoHelper::Smugmug, :smugmug, "smugmug", "Interface with Smugmug"
35
37
  end
36
38
  end
data/photo-helper.gemspec CHANGED
@@ -30,4 +30,8 @@ Gem::Specification.new do |spec|
30
30
 
31
31
  spec.add_dependency "thor"
32
32
  spec.add_dependency "mini_magick"
33
+ spec.add_dependency "ejson"
34
+ spec.add_dependency "oauth"
35
+ spec.add_dependency "mimemagic"
36
+ spec.add_dependency "parallel"
33
37
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: photo-helper
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.6
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Benjamin Caldwell
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-10-17 00:00:00.000000000 Z
11
+ date: 2017-11-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -136,6 +136,62 @@ dependencies:
136
136
  - - ">="
137
137
  - !ruby/object:Gem::Version
138
138
  version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: ejson
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :runtime
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: oauth
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ type: :runtime
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ - !ruby/object:Gem::Dependency
168
+ name: mimemagic
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ type: :runtime
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
181
+ - !ruby/object:Gem::Dependency
182
+ name: parallel
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - ">="
186
+ - !ruby/object:Gem::Version
187
+ version: '0'
188
+ type: :runtime
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - ">="
193
+ - !ruby/object:Gem::Version
194
+ version: '0'
139
195
  description:
140
196
  email:
141
197
  - caldwellbenjamin8@gmail.com
@@ -153,15 +209,20 @@ files:
153
209
  - bin/console
154
210
  - bin/photo-helper
155
211
  - bin/setup
212
+ - bin/smugmug
156
213
  - exe/photo-helper
157
214
  - lib/helpers/file_helper.rb
215
+ - lib/helpers/image_helper.rb
158
216
  - lib/helpers/printer.rb
217
+ - lib/helpers/secrets.rb
218
+ - lib/helpers/smugmug_api.rb
159
219
  - lib/helpers/trash.rb
160
220
  - lib/photo-helper/compress.rb
161
221
  - lib/photo-helper/delete.rb
162
222
  - lib/photo-helper/generate.rb
163
223
  - lib/photo-helper/instagram.rb
164
224
  - lib/photo-helper/move.rb
225
+ - lib/photo-helper/smugmug.rb
165
226
  - lib/photo-helper/version.rb
166
227
  - lib/photo_helper.rb
167
228
  - photo-helper.gemspec