photo-helper 0.5.7 → 0.5.8
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 +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
|