photo-helper 0.1.6 → 0.2.0

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 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