photo-helper 0.5.7 → 0.5.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/lib/helpers/smugmug_album.rb +40 -23
- data/lib/helpers/smugmug_api.rb +31 -30
- data/lib/photo-helper/smugmug.rb +6 -6
- data/lib/photo-helper/version.rb +2 -1
- data/lib/photo_helper.rb +23 -22
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: df2fd10d6c5d02427159bbd75e24fda95e5510dcb2e2a8cb45ed3431a2306f00
|
4
|
+
data.tar.gz: dd8aa0cab5fbbba134c7c86067068cc75ce90d18c3ffcc74716e8aea8a3c3ace
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 570acf74899f3d5a27ef411f60e95220bcc1b394d3291b78f9737008ab2dce08af1a3ae3e7c33315fc1269dc879edccc68d818dd8658bf4678e0449137beef56
|
7
|
+
data.tar.gz: a8c341ec982464f94f311d11f749747b54ac53f2d24d766d34c974040e1f30dbb4c4b34cea5a1bd140e00e82521adb0b117a794972b57ec0f178b20b09ade4e5
|
data/Gemfile.lock
CHANGED
@@ -37,7 +37,6 @@ class SmugmugAlbumHelper
|
|
37
37
|
def initialize(search_path, album = nil)
|
38
38
|
@search_extensions = IMAGE_EXTENSIONS.concat(["XMP"])
|
39
39
|
|
40
|
-
|
41
40
|
@search_path = Pathname.new(search_path)
|
42
41
|
|
43
42
|
@smugmug = SmugmugAPI.new
|
@@ -49,7 +48,7 @@ class SmugmugAlbumHelper
|
|
49
48
|
@dl_album_name = File.join("dl", @album_name)
|
50
49
|
@dl_album = @smugmug.get_or_create_album(@dl_album_name, album_url: @location&.downcase)
|
51
50
|
|
52
|
-
@
|
51
|
+
@folder_keywords = Set.new
|
53
52
|
end
|
54
53
|
|
55
54
|
def parse_path
|
@@ -107,8 +106,13 @@ class SmugmugAlbumHelper
|
|
107
106
|
image_list_hash = {}
|
108
107
|
images.each do |i|
|
109
108
|
filename = File.basename(i, ".*")
|
110
|
-
|
111
|
-
|
109
|
+
|
110
|
+
# add keywords based on directory name and if the image is a select image
|
111
|
+
keywords = image_dir_keywords(i) || []
|
112
|
+
@folder_keywords.merge(keywords) if keywords.size
|
113
|
+
|
114
|
+
# do this after the keywords list because keywords_list is actually just directory keywords...
|
115
|
+
keywords.push("select") if ImageHelper.is_select?(i)
|
112
116
|
|
113
117
|
push_hash_array(image_list_hash, filename, file: i,
|
114
118
|
keywords: keywords,
|
@@ -122,8 +126,8 @@ class SmugmugAlbumHelper
|
|
122
126
|
|
123
127
|
to_upload = {}
|
124
128
|
to_update = {}
|
129
|
+
to_update_keywords = {}
|
125
130
|
to_delete = []
|
126
|
-
to_update_keywords = []
|
127
131
|
|
128
132
|
image_list_hash.each do |filename, images|
|
129
133
|
images.each do |image|
|
@@ -133,20 +137,19 @@ class SmugmugAlbumHelper
|
|
133
137
|
upload_image = true
|
134
138
|
|
135
139
|
if uploaded_hash.key?(filename)
|
136
|
-
|
137
|
-
|
140
|
+
uploaded_hash[filename].each do |uploaded|
|
141
|
+
if uploaded_match_requested?(image, uploaded)
|
138
142
|
if uploaded[:md5] == image[:md5]
|
139
|
-
|
143
|
+
# check for missing keywords using -
|
144
|
+
if image[:keywords] - uploaded[:keywords] != []
|
145
|
+
push_hash_array(to_update_keywords, image[:keywords], {image_uri: uploaded[:image_uri], keywords: uploaded[:keywords], filename: uploaded[:filename]})
|
146
|
+
end
|
147
|
+
else
|
148
|
+
push_hash_array(to_update, image[:keywords], image.merge!(uri: uploaded[:uri]))
|
140
149
|
end
|
141
|
-
|
150
|
+
upload_image = false
|
151
|
+
break
|
142
152
|
end
|
143
|
-
|
144
|
-
# & returns if in both arrays
|
145
|
-
upload_image = false
|
146
|
-
if uploaded[:md5] != image[:md5]
|
147
|
-
push_hash_array(to_update, image[:keywords], image.merge!(uri: uploaded[:uri]))
|
148
|
-
end
|
149
|
-
break
|
150
153
|
end
|
151
154
|
end
|
152
155
|
|
@@ -175,14 +178,21 @@ class SmugmugAlbumHelper
|
|
175
178
|
end
|
176
179
|
|
177
180
|
to_upload.each do |keywords, images|
|
178
|
-
puts keywords
|
179
181
|
upload(album, images, keywords)
|
180
182
|
end
|
181
183
|
|
182
184
|
to_update.each do |keywords, images|
|
183
|
-
puts keywords
|
184
185
|
update(album, images, keywords)
|
185
186
|
end
|
187
|
+
|
188
|
+
to_update_keywords.each do |keywords, images|
|
189
|
+
puts "Updating keywords #{keywords}"
|
190
|
+
images.each do |i|
|
191
|
+
@smugmug.update_keywords(i, keywords)
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
|
186
196
|
# puts "delete #{to_delete.count}???"
|
187
197
|
if delete && to_delete.any?
|
188
198
|
puts "Deleting #{to_delete.count} images"
|
@@ -218,17 +228,18 @@ class SmugmugAlbumHelper
|
|
218
228
|
@dl_album
|
219
229
|
end
|
220
230
|
|
221
|
-
@
|
231
|
+
@folder_keywords = Set.new
|
222
232
|
puts "Uploading all images to album #{album_name || @album_name} --> #{album[:web_uri]}\n"
|
223
233
|
|
224
234
|
@image_list = image_list_to_hash(image_list)
|
225
235
|
@image_list = merge_hash_array(@image_list, image_list_to_hash(exported_list))
|
226
236
|
@image_list = merge_hash_array(@image_list, image_list_to_hash(instagram_list))
|
237
|
+
|
227
238
|
sync(album, @image_list, true)
|
228
239
|
end
|
229
240
|
|
230
241
|
def collect_select
|
231
|
-
@
|
242
|
+
@folder_keywords = Set.new
|
232
243
|
|
233
244
|
pictures = image_list
|
234
245
|
pictures = pictures.select { |p| ImageHelper.is_select?(p) }
|
@@ -259,7 +270,7 @@ class SmugmugAlbumHelper
|
|
259
270
|
end
|
260
271
|
|
261
272
|
def upload_select
|
262
|
-
@
|
273
|
+
@folder_keywords = Set.new
|
263
274
|
|
264
275
|
pictures = image_list
|
265
276
|
pictures = pictures.select { |p| ImageHelper.is_select?(p) }
|
@@ -297,12 +308,18 @@ class SmugmugAlbumHelper
|
|
297
308
|
end
|
298
309
|
|
299
310
|
def uploaded_match_requested?(image, uploaded)
|
311
|
+
# for checking if match only care about folder keywords
|
300
312
|
if image[:keywords].nil?
|
301
313
|
# empty from keyword list
|
302
|
-
return true if uploaded[:keywords].nil? || @
|
303
|
-
elsif image[:keywords] - uploaded[:keywords] ==
|
314
|
+
return true if uploaded[:keywords].nil? || @folder_keywords & uploaded[:keywords] == Set.new
|
315
|
+
elsif @folder_keywords & image[:keywords] - uploaded[:keywords] == Set.new
|
304
316
|
return true
|
305
317
|
end
|
306
318
|
false
|
307
319
|
end
|
308
320
|
end
|
321
|
+
|
322
|
+
# class SmugmugImage
|
323
|
+
# def initialize(image_path)
|
324
|
+
# end
|
325
|
+
# end
|
data/lib/helpers/smugmug_api.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require 'helpers/secrets'
|
3
4
|
require 'oauth'
|
4
5
|
require 'uri'
|
@@ -8,17 +9,17 @@ require 'parallel'
|
|
8
9
|
|
9
10
|
class SmugmugAPI
|
10
11
|
attr_accessor :http, :uploader
|
11
|
-
OAUTH_ORIGIN = 'https://secure.smugmug.com'
|
12
|
-
REQUEST_TOKEN_URL = '/services/oauth/1.0a/getRequestToken'
|
13
|
-
ACCESS_TOKEN_URL = '/services/oauth/1.0a/getAccessToken'
|
14
|
-
AUTHORIZE_URL = '/services/oauth/1.0a/authorize'
|
15
|
-
API_ENDPOINT = 'https://api.smugmug.com'
|
16
|
-
UPLOAD_ENDPOINT = 'https://upload.smugmug.com/'
|
12
|
+
OAUTH_ORIGIN = 'https://secure.smugmug.com'.freeze
|
13
|
+
REQUEST_TOKEN_URL = '/services/oauth/1.0a/getRequestToken'.freeze
|
14
|
+
ACCESS_TOKEN_URL = '/services/oauth/1.0a/getAccessToken'.freeze
|
15
|
+
AUTHORIZE_URL = '/services/oauth/1.0a/authorize'.freeze
|
16
|
+
API_ENDPOINT = 'https://api.smugmug.com'.freeze
|
17
|
+
UPLOAD_ENDPOINT = 'https://upload.smugmug.com/'.freeze
|
17
18
|
|
18
19
|
def initialize(ejson_file = '~/.photo_helper.ejson')
|
19
20
|
ejson_file = File.expand_path(ejson_file)
|
20
|
-
@secrets = Secrets.new(ejson_file, %i
|
21
|
-
request_access_token if !@secrets[
|
21
|
+
@secrets = Secrets.new(ejson_file, %i[api_key api_secret])
|
22
|
+
request_access_token if !@secrets['access_token'] || !@secrets['access_secret']
|
22
23
|
|
23
24
|
@http = get_access_token
|
24
25
|
@uploader = get_access_token(UPLOAD_ENDPOINT)
|
@@ -198,29 +199,29 @@ class SmugmugAPI
|
|
198
199
|
image = File.open(image_path)
|
199
200
|
|
200
201
|
headers.merge!('Content-Type' => MimeMagic.by_path(image_path).type,
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
202
|
+
'X-Smug-AlbumUri' => "/api/v2/album/#{album_id}",
|
203
|
+
'X-Smug-ResponseType' => 'JSON',
|
204
|
+
'X-Smug-Version' => 'v2',
|
205
|
+
'charset' => 'UTF-8',
|
206
|
+
'Accept' => 'JSON',
|
207
|
+
'X-Smug-FileName' => File.basename(image_path),
|
208
|
+
'Content-MD5' => Digest::MD5.file(image_path).hexdigest)
|
208
209
|
|
209
|
-
headers['X-Smug-Title'] = File.basename(image_path,
|
210
|
+
headers['X-Smug-Title'] = File.basename(image_path, '.*') if filename_as_title
|
210
211
|
|
211
212
|
resp = @uploader.post('/', image, headers)
|
212
213
|
resp.body
|
213
214
|
end
|
214
215
|
|
215
216
|
def upload_images(images, album_id, headers = {}, workers: 4, filename_as_title: false)
|
216
|
-
Parallel.each(images, in_processes: workers, progress:
|
217
|
+
Parallel.each(images, in_processes: workers, progress: 'Uploading images') do |image|
|
217
218
|
upload(image, album_id, headers, filename_as_title: filename_as_title)
|
218
219
|
puts "Done #{image}\n"
|
219
220
|
end
|
220
221
|
end
|
221
222
|
|
222
223
|
def update_images(images, album_id, headers = {}, workers: 4, filename_as_title: false)
|
223
|
-
Parallel.each(images, in_processes: workers, progress:
|
224
|
+
Parallel.each(images, in_processes: workers, progress: 'Updating images') do |image|
|
224
225
|
# replace not working, delete then upload
|
225
226
|
http(:delete, image[:uri])
|
226
227
|
upload(image[:file], album_id, headers, filename_as_title: filename_as_title)
|
@@ -230,31 +231,31 @@ class SmugmugAPI
|
|
230
231
|
|
231
232
|
def collect_images(images, album_id)
|
232
233
|
return if images.empty?
|
233
|
-
images = images.join(
|
234
|
-
post("/api/v2/album/#{album_id}!collectimages",
|
234
|
+
images = images.join(',') if images.is_a? Array
|
235
|
+
post("/api/v2/album/#{album_id}!collectimages", 'CollectUris' => images)
|
235
236
|
end
|
236
237
|
|
237
238
|
def move_images(images, album_id)
|
238
|
-
|
239
|
-
|
240
|
-
|
239
|
+
return if images.empty?
|
240
|
+
images = images.join(',') if images.is_a? Array
|
241
|
+
post("/api/v2/album/#{album_id}!moveimages", 'MoveUris' => images)
|
241
242
|
end
|
242
243
|
|
243
244
|
def update_keywords(image, keywords, overwrite = false)
|
244
245
|
return if image.nil?
|
245
246
|
keywords = (image[:keywords] + keywords).uniq unless overwrite
|
246
|
-
|
247
|
+
|
247
248
|
# inspect need outwise it isnt encoded right
|
248
|
-
|
249
|
+
post("#{image[:image_uri]}?_method=PATCH", KeywordArray: keywords.inspect)
|
249
250
|
end
|
250
251
|
|
251
252
|
def request_access_token
|
252
253
|
@consumer = OAuth::Consumer.new(@secrets.api_key, @secrets.api_secret,
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
254
|
+
site: OAUTH_ORIGIN,
|
255
|
+
name: 'photo-helper',
|
256
|
+
request_token_path: REQUEST_TOKEN_URL,
|
257
|
+
authorize_path: AUTHORIZE_URL,
|
258
|
+
access_token_path: ACCESS_TOKEN_URL)
|
258
259
|
|
259
260
|
# Generate request token
|
260
261
|
@request_token = @consumer.get_request_token
|
data/lib/photo-helper/smugmug.rb
CHANGED
@@ -41,11 +41,11 @@ module PhotoHelper
|
|
41
41
|
albums = @smugmug.albums_long
|
42
42
|
|
43
43
|
albums_tree = {}
|
44
|
-
output = [
|
44
|
+
output = ['# Photos']
|
45
45
|
|
46
46
|
albums.each do |a|
|
47
47
|
parts = a[:path].split('/')
|
48
|
-
next if parts[0] ==
|
48
|
+
next if parts[0] == 'Trash'
|
49
49
|
|
50
50
|
album_name = parts.pop
|
51
51
|
parts.each_with_index do |part, i|
|
@@ -69,16 +69,16 @@ module PhotoHelper
|
|
69
69
|
until stack.empty?
|
70
70
|
key = stack.pop
|
71
71
|
item = key.inject(albums_tree, :fetch)
|
72
|
-
next if key.first ==
|
72
|
+
next if key.first == 'dl'
|
73
73
|
|
74
74
|
if item.is_a?(Hash)
|
75
|
-
stack.concat(item.keys.map{|a| key.clone.push(a)})
|
76
|
-
output.push("#{'#'*key.count} #{key.last}")
|
75
|
+
stack.concat(item.keys.map { |a| key.clone.push(a) })
|
76
|
+
output.push("#{'#' * key.count} #{key.last}")
|
77
77
|
next
|
78
78
|
end
|
79
79
|
|
80
80
|
begin
|
81
|
-
dl_item = [
|
81
|
+
dl_item = ['dl'].concat(key).inject(albums_tree, :fetch)
|
82
82
|
output.push(" **Selects: ** #{item}\n **All: ** #{dl_item}")
|
83
83
|
rescue
|
84
84
|
output.push(item)
|
data/lib/photo-helper/version.rb
CHANGED
data/lib/photo_helper.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require 'thor'
|
3
4
|
|
4
5
|
require 'helpers/printer'
|
@@ -13,36 +14,36 @@ require 'photo-helper/smugmug'
|
|
13
14
|
require 'photo-helper/screensaver'
|
14
15
|
|
15
16
|
# TODO: move to config file
|
16
|
-
RAW_EXTENSION =
|
17
|
-
RAW_EXTENSIONS = [RAW_EXTENSION,
|
18
|
-
JPEG_EXTENSION =
|
19
|
-
JPEG_EXTENSIONS =
|
20
|
-
IMAGE_EXTENSIONS = JPEG_EXTENSIONS.concat([])
|
21
|
-
PHOTOS_ROOT = File.expand_path(
|
17
|
+
RAW_EXTENSION = 'dng'.freeze
|
18
|
+
RAW_EXTENSIONS = [RAW_EXTENSION, 'DNG', 'ORF', 'RAF'].freeze
|
19
|
+
JPEG_EXTENSION = 'JPG'.freeze
|
20
|
+
JPEG_EXTENSIONS = [JPEG_EXTENSION, 'jpg', 'jpeg'].freeze
|
21
|
+
IMAGE_EXTENSIONS = JPEG_EXTENSIONS.dup.concat([])
|
22
|
+
PHOTOS_ROOT = File.expand_path('~/Pictures/Pictures')
|
22
23
|
BEST_OF_ROOT = File.expand_path("~/Pictures/Pictures/Best\ of")
|
23
|
-
SCREENSAVER_ROOT = File.expand_path(
|
24
|
-
JPEG_ROOT = File.expand_path(
|
25
|
-
IGNORE_FOLDERS = %w
|
26
|
-
SELECT_COLOR_TAGS = [
|
27
|
-
SELECT_RATING = 1 #greater than or equal to
|
24
|
+
SCREENSAVER_ROOT = File.expand_path('~/Pictures/screensaver')
|
25
|
+
JPEG_ROOT = File.expand_path('~/Pictures/jpegs')
|
26
|
+
IGNORE_FOLDERS = %w[instagram exported edited].freeze
|
27
|
+
SELECT_COLOR_TAGS = ['Winner', 'Winner alt', 'Superior', 'Superior alt', 'Typical', 'Typical alt'].freeze
|
28
|
+
SELECT_RATING = 1 # greater than or equal to
|
28
29
|
|
29
30
|
module PhotoHelper
|
30
31
|
class CLI < Thor
|
31
|
-
map
|
32
|
-
map
|
33
|
-
map
|
32
|
+
map 'g' => 'generathte'
|
33
|
+
map 'd' => 'delete'
|
34
|
+
map 's' => 'smugmug'
|
34
35
|
|
35
|
-
desc
|
36
|
+
desc 'version', 'displays installed version'
|
36
37
|
def version
|
37
38
|
puts PhotoHelper::VERSION
|
38
39
|
end
|
39
40
|
|
40
|
-
register PhotoHelper::Generate, :generate,
|
41
|
-
register PhotoHelper::Delete, :delete,
|
42
|
-
register PhotoHelper::Instagram, :instagram,
|
43
|
-
register PhotoHelper::Move, :move,
|
44
|
-
register PhotoHelper::Compress, :compress,
|
45
|
-
register PhotoHelper::Smugmug, :smugmug,
|
46
|
-
register PhotoHelper::Screensaver, :screensaver,
|
41
|
+
register PhotoHelper::Generate, :generate, 'generate', 'Do something else'
|
42
|
+
register PhotoHelper::Delete, :delete, 'delete', 'Do something else'
|
43
|
+
register PhotoHelper::Instagram, :instagram, 'instagram', 'Do something else'
|
44
|
+
register PhotoHelper::Move, :move, 'move', 'Do something else'
|
45
|
+
register PhotoHelper::Compress, :compress, 'compress', 'Do something else'
|
46
|
+
register PhotoHelper::Smugmug, :smugmug, 'smugmug', 'Interface with Smugmug'
|
47
|
+
register PhotoHelper::Screensaver, :screensaver, 'screensaver', 'Move best photos to screensaver folder and compress'
|
47
48
|
end
|
48
49
|
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.5.
|
4
|
+
version: 0.5.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Benjamin Caldwell
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-07-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -262,7 +262,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
262
262
|
version: '0'
|
263
263
|
requirements: []
|
264
264
|
rubyforge_project:
|
265
|
-
rubygems_version: 2.7.
|
265
|
+
rubygems_version: 2.7.10
|
266
266
|
signing_key:
|
267
267
|
specification_version: 4
|
268
268
|
summary: A tool to automatate my photo workflows
|