photo-helper 0.2.10 → 0.3

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: 72ceb15c03d99b057c67256c085549136c8ba316
4
- data.tar.gz: 03e82ca1efe158858eab5c189705275a071215d1
3
+ metadata.gz: e4bbf183dc81a5e29d5e0a0d8007073494144da3
4
+ data.tar.gz: 53085441c3aec638bd8b4a5e6362dd9f2de88164
5
5
  SHA512:
6
- metadata.gz: 1f06f55c4a414864ba7436950322ce7538c2bff225b5cf3243d8c4a87ec67dd0d5a6f622a3331407530a89a54f4d5626ff9ca030a3032b4448b50d16c0d1ab07
7
- data.tar.gz: f4dbfa2de0930a5a3dc361b1dfabe4759fc15f919c00bdce35338bda1c77162e03781703adf472d9655c85d6c83b139838db2badefc93eb7d7006105f2eca888
6
+ metadata.gz: 0d872ce3085f8282759470f87eeb8acc04e5409d18ec958a1ee3ac557829e223d7ff09165f09fbcbafa419e87b715ee6851d5904f851c20949fe60223c47da45
7
+ data.tar.gz: a6cc39c361ed40180fa1c030cbec37fb4c51c30c9a1e04dde194bb8aef1f1f7d1b2f2fe3726f434f6d04c6baf1776a4b2abc6fc836fb7debe958f610b9c2b48b
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- photo-helper (0.2.10)
4
+ photo-helper (0.3)
5
5
  ejson
6
6
  mimemagic
7
7
  mini_magick
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  require "bundler/setup"
4
5
 
@@ -8,7 +8,9 @@ class FileHelper
8
8
  end
9
9
 
10
10
  def self.is_jpeg?(path)
11
- extension = File.extname(path)
11
+ # remove . from the beginning
12
+ extension = File.extname(path)[1..-1]
13
+ return false if extension.nil?
12
14
  JPEG_EXTENSIONS.include? extension.downcase
13
15
  end
14
16
  end
@@ -1,15 +1,17 @@
1
+ # frozen_string_literal: true
1
2
  class ImageHelper
2
- IMAGE_CLASS_REGEX = %r{xmp:Label="(.+)"}
3
- RATING_REGEX = %r{xmp:Rating="(.+)"}
4
-
3
+ IMAGE_CLASS_REGEX = /xmp:Label="(.+)"/
4
+ RATING_REGEX = /xmp:Rating="(.+)"/
5
+
5
6
  def self.xmp(image)
6
7
  xmp = File.join(File.dirname(image), File.basename(image, ".*") + ".XMP")
7
- return unless File.exists?(xmp)
8
+ return unless File.exist?(xmp)
8
9
  File.read(xmp)
9
10
  end
10
11
 
11
12
  def self.color_class(image)
12
13
  contents = xmp(image)
14
+ return if contents.nil?
13
15
  matches = contents.match(IMAGE_CLASS_REGEX)
14
16
  matches[1] if matches
15
17
  end
@@ -32,4 +34,11 @@ class ImageHelper
32
34
  def self.is_5_star?(image)
33
35
  rating(image) == '5'
34
36
  end
37
+
38
+ def self.is_jpeg?(path)
39
+ # remove . from the beginning
40
+ extension = File.extname(path)[1..-1]
41
+ return false if extension.nil?
42
+ JPEG_EXTENSIONS.include? extension.downcase
43
+ end
35
44
  end
@@ -0,0 +1,233 @@
1
+ # frozen_string_literal: true
2
+ require "helpers/smugmug_api"
3
+ require "helpers/image_helper"
4
+ require "helpers/file_helper"
5
+ require 'set'
6
+
7
+ class SmugmugAlbumHelper
8
+ attr_accessor :smugmug_api
9
+
10
+ # to figure out what to delete, read all xmp files, loop through uploaded files and check xmp file
11
+
12
+ PATH_REGEX = %r{^.+Pictures\/.+\/(\d{4})\/(\d{2})_.+\/[^_]+_([^\/]+)}
13
+ KEYWORD_WHITELITS = %w("instagram exported")
14
+
15
+ def initialize(search_path, album = nil)
16
+ @search_path = Pathname.new(search_path)
17
+ @smugmug = SmugmugAPI.new
18
+
19
+ @album_name = album || album_name
20
+
21
+ @album = @smugmug.get_or_create_album(@album_name, album_url: @location&.downcase)
22
+
23
+ @dl_album_name = File.join("dl", @album_name)
24
+ @dl_album = @smugmug.get_or_create_album(@dl_album_name, album_url: @location&.downcase)
25
+
26
+ @keyword_list = Set.new
27
+ end
28
+
29
+ def parse_path
30
+ if matches = "#{@search_path}/".to_s.match(PATH_REGEX)
31
+ @year = matches[1]
32
+ @month = Date::MONTHNAMES[matches[2].to_i].capitalize
33
+ @location = matches[3].split("_").map(&:capitalize).join(' ')
34
+ end
35
+ end
36
+
37
+ def album_name
38
+ parse_path
39
+ if @year && @month && @location
40
+ album_name_short = "#{@location} #{@month} #{@year}"
41
+ File.join(@year, @month, album_name_short)
42
+ else
43
+ puts 'Unable to determine album from path'
44
+ end
45
+ end
46
+
47
+ def image_list
48
+ Dir["#{@search_path}/**/*.{#{IMAGE_EXTENSIONS.join(',')}}"].reject { |p| FileHelper.ingore_file?(p) }
49
+ end
50
+
51
+ def exported_list
52
+ Dir["#{@search_path}/**/{Exported,exported}/*.{#{IMAGE_EXTENSIONS.join(',')}}"]
53
+ end
54
+
55
+ def instagram_list
56
+ Dir["#{@search_path}/**/{Instagram,instagram}/*.{#{IMAGE_EXTENSIONS.join(',')}}"]
57
+ end
58
+
59
+ def merge_exported(images = image_list, concat = false)
60
+ exported = Dir["#{@search_path}/**/{Exported,exported}/*.{#{IMAGE_EXTENSIONS.join(',')}}"]
61
+ unless concat
62
+ exported_basenames = exported.map { |p| File.basename(p, ".*") }
63
+ images = images.reject { |p| exported_basenames.include? File.basename(p, ".*") }
64
+ end
65
+ images.concat(exported)
66
+ end
67
+
68
+ def uploaded_to_hash(album)
69
+ uploaded = @smugmug.images(album[:id])
70
+ uploaded_hash = {}
71
+ uploaded.each do |u|
72
+ filename = File.basename(u[:filename], ".*")
73
+ push_hash_array(uploaded_hash, filename, u)
74
+ end
75
+ uploaded_hash
76
+ end
77
+
78
+ def image_list_to_hash(images)
79
+ image_list_hash = {}
80
+ images.each do |i|
81
+ filename = File.basename(i, ".*")
82
+ tags = image_dir_keywords(i)
83
+ @keyword_list.merge(tags) if tags
84
+ push_hash_array(image_list_hash, filename, file: i,
85
+ keywords: tags,
86
+ md5: Digest::MD5.file(i).hexdigest)
87
+ end
88
+ image_list_hash
89
+ end
90
+
91
+ def sync(album, image_list_hash, reject_trash = true)
92
+ uploaded_hash = uploaded_to_hash(album)
93
+
94
+ to_upload = {}
95
+ to_update = {}
96
+ to_delete = []
97
+
98
+ image_list_hash.each do |filename, images|
99
+ images.each do |image|
100
+ next unless ImageHelper.is_jpeg?(image[:file])
101
+ next if reject_trash && ImageHelper.color_class(image[:file]) == "Trash"
102
+
103
+ upload_image = true
104
+
105
+ if uploaded_hash.key?(filename)
106
+ !uploaded_hash[filename].each do |uploaded|
107
+ next unless uploaded_match_requested?(image, uploaded)
108
+
109
+ # & returns if in both arrays
110
+ upload_image = false
111
+ if uploaded[:md5] != image[:md5]
112
+ push_hash_array(to_update, image[:keywords], image.merge!(uri: uploaded[:uri]))
113
+ end
114
+ break
115
+ end
116
+ end
117
+
118
+ if upload_image
119
+ push_hash_array(to_upload, image[:keywords], image[:file])
120
+ end
121
+ end
122
+ end
123
+
124
+ uploaded_hash.each do |filename, uploaded_images|
125
+ uploaded_images.each do |uploaded|
126
+ if image_list_hash.key?(filename)
127
+ image_hash = image_list_hash[filename].find do |image|
128
+ uploaded_match_requested?(image, uploaded)
129
+ end
130
+ to_delete.push(uploaded) if image_hash.nil?
131
+ to_delete.push(uploaded) if reject_trash && ImageHelper.color_class(image_hash[:file]) == "Trash"
132
+ else
133
+ to_delete.push(uploaded)
134
+ end
135
+ end
136
+ end
137
+
138
+ to_upload.each do |keywords, images|
139
+ puts keywords
140
+ upload(album, images, keywords)
141
+ end
142
+
143
+ if to_delete.any?
144
+ puts "Deleting #{to_delete.count} images"
145
+ to_delete.each do |uploaded|
146
+ puts uploaded[:filename]
147
+ @smugmug.http(:delete, uploaded[:uri])
148
+ end
149
+ end
150
+
151
+ to_update.each do |keywords, images|
152
+ puts keywords
153
+ update(album, images, keywords)
154
+ end
155
+ end
156
+
157
+ def upload(album, pictures, keywords = nil)
158
+ puts "Uploading #{pictures.count} jpegs"
159
+
160
+ headers = {}
161
+ headers["X-Smug-Keywords"] = keywords.join(",") unless keywords.nil?
162
+
163
+ @smugmug.upload_images(pictures, album[:id], headers, workers: 8, filename_as_title: true)
164
+ end
165
+
166
+ def update(album, pictures, keywords = nil)
167
+ puts "Updating #{pictures.count} jpegs"
168
+
169
+ headers = {}
170
+ headers["X-Smug-Keywords"] = keywords.join(",") unless keywords.nil?
171
+
172
+ @smugmug.update_images(pictures, album[:id], headers, workers: 8, filename_as_title: true)
173
+ end
174
+
175
+ def upload_dl
176
+ @keyword_list = Set.new
177
+ puts "Uploading all images to album #{@album_name} --> #{@dl_album[:web_uri]}\n"
178
+
179
+ @image_list = image_list_to_hash(image_list)
180
+ @image_list = merge_hash_array(@image_list, image_list_to_hash(exported_list))
181
+ @image_list = merge_hash_array(@image_list, image_list_to_hash(instagram_list))
182
+
183
+ sync(@dl_album, @image_list, true)
184
+ end
185
+
186
+ def upload_select
187
+ @keyword_list = Set.new
188
+
189
+ pictures = image_list
190
+ pictures = pictures.select { |p| ImageHelper.is_select?(p) }
191
+ pictures = merge_exported(pictures)
192
+
193
+ puts "Uploading selects to album #{@album_name} --> #{@album[:web_uri]}\n"
194
+
195
+ @image_list = image_list_to_hash(pictures)
196
+
197
+ sync(@album, @image_list, true)
198
+ end
199
+
200
+ private
201
+
202
+ def push_hash_array(hash, key, item)
203
+ hash[key] = [] unless hash.key?(key)
204
+ hash[key].push(item)
205
+ hash
206
+ end
207
+
208
+ def merge_hash_array(hash1, hash2)
209
+ hash2.each do |key, value|
210
+ hash1[key] = [] unless hash1.key?(key)
211
+ hash1[key].concat(value)
212
+ end
213
+ hash1
214
+ end
215
+
216
+ def image_dir_keywords(image)
217
+ rel = Pathname.new(image).relative_path_from(@search_path).to_s.split("/")
218
+ # ignore first and last parts
219
+ rel &= KEYWORD_WHITELITS
220
+ return nil if rel.empty?
221
+ rel
222
+ end
223
+
224
+ def uploaded_match_requested?(image, uploaded)
225
+ if image[:keywords].nil?
226
+ # empty from keyword list
227
+ return true if uploaded[:keywords].nil? || @keyword_list & uploaded[:keywords] == Set.new
228
+ else
229
+ return true if image[:keywords] - uploaded[:keywords] == []
230
+ end
231
+ false
232
+ end
233
+ end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'helpers/secrets'
2
3
  require 'oauth'
3
4
  require 'uri'
@@ -7,16 +8,16 @@ require 'parallel'
7
8
 
8
9
  class SmugmugAPI
9
10
  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 = 'https://upload.smugmug.com/'.freeze
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/'
16
17
 
17
18
  def initialize(ejson_file = '~/.photo_helper.ejson')
18
19
  ejson_file = File.expand_path(ejson_file)
19
- @secrets = Secrets.new(ejson_file, %i[api_key api_secret])
20
+ @secrets = Secrets.new(ejson_file, %i(api_key api_secret))
20
21
  request_access_token if !@secrets["access_token"] || !@secrets["access_secret"]
21
22
 
22
23
  @http = get_access_token
@@ -69,8 +70,6 @@ class SmugmugAPI
69
70
  get('/api/v2!authuser')['User']
70
71
  end
71
72
 
72
- def images; end
73
-
74
73
  def folders
75
74
  folder_list = []
76
75
  resp = get('/api/v2/folder/user/bcaldwell!folderlist')
@@ -83,7 +82,6 @@ class SmugmugAPI
83
82
  def get_or_create_album(path, album_url: nil)
84
83
  folder_path = File.dirname(path).split('/').map(&:capitalize).join('/')
85
84
  album_name = File.basename(path).split(' ').map(&:capitalize).join(' ')
86
- puts album_name
87
85
  album = nil
88
86
 
89
87
  folder = get_or_create_folder(folder_path)
@@ -165,14 +163,14 @@ class SmugmugAPI
165
163
  @images.map { |i| i[:filename] }
166
164
  end
167
165
 
168
- def http(method, url, headers = {}, _body = nil)
169
- response = http_raw(method, url, headers, _body)
166
+ def http(method, url, headers = {}, body = nil)
167
+ response = http_raw(method, url, headers, body)
170
168
  raise 'Request failed' unless response.is_a? Net::HTTPSuccess
171
169
  JSON.parse(response.body)['Response']
172
170
  end
173
171
 
174
172
  def get(url, params = nil, headers = {})
175
- url.tr!(' ', '-')
173
+ url = url.tr(' ', '-')
176
174
  uri = URI.parse(url)
177
175
  uri.query = URI.encode_www_form(params) if params
178
176
  http(:get, uri.to_s, headers)
@@ -186,38 +184,53 @@ class SmugmugAPI
186
184
  JSON.parse(response.body)['Response']
187
185
  end
188
186
 
189
- def upload(image_path, album_id, headers = {})
187
+ def upload(image_path, album_id, headers = {}, filename_as_title: false)
190
188
  image = File.open(image_path)
191
189
 
192
190
  headers.merge!('Content-Type' => MimeMagic.by_path(image_path).type,
193
- 'X-Smug-AlbumUri' => "/api/v2/album/#{album_id}",
194
- 'X-Smug-ResponseType' => 'JSON',
195
- 'X-Smug-Version' => 'v2',
196
- 'charset' => 'UTF-8',
197
- 'Accept' => 'JSON',
198
- 'X-Smug-FileName' => File.basename(image_path),
199
- 'Content-MD5' => Digest::MD5.file(image_path).hexdigest)
191
+ 'X-Smug-AlbumUri' => "/api/v2/album/#{album_id}",
192
+ 'X-Smug-ResponseType' => 'JSON',
193
+ 'X-Smug-Version' => 'v2',
194
+ 'charset' => 'UTF-8',
195
+ 'Accept' => 'JSON',
196
+ 'X-Smug-FileName' => File.basename(image_path),
197
+ 'Content-MD5' => Digest::MD5.file(image_path).hexdigest)
198
+
199
+ headers['X-Smug-Title'] = File.basename(image_path, ".*") if filename_as_title
200
200
 
201
201
  resp = @uploader.post('/', image, headers)
202
202
  resp.body
203
203
  end
204
204
 
205
- def upload_images(images, album_id, headers = {}, workers: 4)
205
+ def upload_images(images, album_id, headers = {}, workers: 4, filename_as_title: false)
206
+ counter = 0
207
+ Parallel.each(images, in_processes: workers, progress: "Uploading images") do |image|
208
+ upload(image, album_id, headers, filename_as_title: filename_as_title)
209
+ # puts "#{counter}/#{images.count / workers}
210
+ puts "Done #{image}"
211
+ end
212
+ end
213
+
214
+ def update_images(images, album_id, headers = {}, workers: 4, filename_as_title: false)
206
215
  counter = 0
207
- Parallel.each(images, in_processes: workers) do |image|
208
- upload(image, album_id, headers)
209
- counter += 1
210
- puts "#{counter}/#{images.count / workers} Done #{image}"
216
+
217
+ Parallel.each(images, in_processes: workers, progress: "Updating images") do |image|
218
+ # replace not working, delete then upload
219
+ http(:delete, image[:uri])
220
+ upload(image[:file], album_id, headers, filename_as_title: filename_as_title)
221
+ # counter += 1
222
+ # puts "#{counter}/#{images.count / workers}
223
+ puts "Done #{image[:file]}"
211
224
  end
212
225
  end
213
226
 
214
227
  def request_access_token
215
228
  @consumer = OAuth::Consumer.new(@secrets.api_key, @secrets.api_secret,
216
- site: OAUTH_ORIGIN,
217
- name: 'photo-helper',
218
- request_token_path: REQUEST_TOKEN_URL,
219
- authorize_path: AUTHORIZE_URL,
220
- access_token_path: ACCESS_TOKEN_URL)
229
+ site: OAUTH_ORIGIN,
230
+ name: 'photo-helper',
231
+ request_token_path: REQUEST_TOKEN_URL,
232
+ authorize_path: AUTHORIZE_URL,
233
+ access_token_path: ACCESS_TOKEN_URL)
221
234
 
222
235
  # Generate request token
223
236
  @request_token = @consumer.get_request_token
@@ -244,9 +257,8 @@ class SmugmugAPI
244
257
  private
245
258
 
246
259
  def http_raw(method, url, headers = {}, _body = nil)
247
- url.tr!(' ', '-')
260
+ url = url.tr(' ', '-')
248
261
  headers['Accept'] = 'application/json'
249
-
250
262
  @http.request(method, url, headers)
251
263
  end
252
264
 
@@ -1,14 +1,14 @@
1
- require "mini_magick"
2
- require "helpers/file_helper"
1
+ require 'mini_magick'
2
+ require 'helpers/file_helper'
3
3
 
4
4
  module PhotoHelper
5
5
  class Compress < Thor
6
6
  include Thor::Actions
7
7
 
8
- method_option :recursive, aliases: "-r", type: :boolean, default: false
9
- method_option :overwrite, aliases: "-f", type: :boolean, default: false
10
- desc "images", "compress images in folder"
11
- def images(folder=nil)
8
+ method_option :recursive, aliases: '-r', type: :boolean, default: false
9
+ method_option :overwrite, aliases: '-o', type: :boolean, default: false
10
+ desc 'images', 'compress images in folder'
11
+ def images(folder = nil)
12
12
  folder ||= options[:folder]
13
13
 
14
14
  search_path = File.expand_path(folder)
@@ -21,28 +21,29 @@ module PhotoHelper
21
21
  end
22
22
 
23
23
  files.each do |file|
24
- next if File.basename(file, ".*").end_with? (".min")
24
+ next if File.basename(file, '.*').end_with? '.min'
25
25
  next unless FileHelper.is_jpeg?(file)
26
26
 
27
27
  image = MiniMagick::Image.open(file)
28
28
  orig_size = image.size
29
29
 
30
30
  image.combine_options do |b|
31
- b.sampling_factor "4:2:0"
31
+ b.sampling_factor '4:2:0'
32
32
  b.strip
33
- b.interlace "JPEG"
34
- b.colorspace "RGB"
33
+ b.interlace 'JPEG'
34
+ b.colorspace 'RGB'
35
35
  b.quality 85
36
36
  end
37
+ next if orig_size == image.size
37
38
  puts "#{file} (#{(orig_size / image.size) * 100}%)"
38
39
 
39
- output_path =
40
+ output_path =
40
41
  if options[:overwrite]
41
42
  file
42
43
  else
43
- File.join( File.dirname(file), File.basename(file, ".*") + ".min" + File.extname(file))
44
+ File.join(File.dirname(file), File.basename(file, '.*') + '.min' + File.extname(file))
44
45
  end
45
-
46
+
46
47
  image.write output_path
47
48
  end
48
49
  end
@@ -0,0 +1,30 @@
1
+ require 'helpers/file_helper'
2
+ require 'photo-helper/compress'
3
+
4
+ module PhotoHelper
5
+ class Screensaver < Thor
6
+ include Thor::Actions
7
+
8
+ method_option :overwrite, aliases: '-o', type: :boolean, default: false
9
+ desc 'move', 'Move best photos to screensaver folder and compress'
10
+ def move
11
+ files = Dir["#{BEST_OF_ROOT}/**/*"]
12
+
13
+ files.each do |file|
14
+ next unless FileHelper.is_jpeg?(file)
15
+ dest = File.join(SCREENSAVER_ROOT, File.basename(file))
16
+ next if File.exist?(dest)
17
+ puts file
18
+ FileUtils.copy(file, dest)
19
+ end
20
+
21
+ puts 'Compressing'
22
+
23
+ compress = PhotoHelper::Compress.new
24
+ compress.options = { overwrite: true }
25
+ compress.images(SCREENSAVER_ROOT)
26
+ end
27
+
28
+ default_task :move
29
+ end
30
+ end
@@ -1,4 +1,5 @@
1
- require 'helpers/smugmug'
1
+ # frozen_string_literal: true
2
+ require 'helpers/smugmug_album'
2
3
  require 'date'
3
4
  require 'helpers/image_helper'
4
5
 
@@ -11,28 +12,27 @@ module PhotoHelper
11
12
  method_option :folder, aliases: '-f', type: :string, default: '.'
12
13
  method_option :recursive, aliases: '-r', type: :boolean, default: false
13
14
  method_option :dry_run, aliases: '-d', type: :boolean, default: false
14
- def sync(folder = nil, album_name = nil)
15
+ def sync(folder = nil, _album_name = nil)
15
16
  search_path = File.expand_path(folder)
16
17
 
17
- @smugmug = SmugmugHelper.new(search_path)
18
+ @smugmug = SmugmugAlbumHelper.new(search_path)
18
19
 
19
20
  @smugmug.upload_select
20
21
  puts("\n")
21
- if album_name
22
- @smugmug.upload(album_name, @smugmug.image_list)
23
- else
24
- @smugmug.upload_dl
25
- end
22
+ # if album_name
23
+ # @smugmug.upload(album_name, @smugmug.image_list)
24
+ # else
25
+ @smugmug.upload_dl
26
+ # end
26
27
  end
27
28
 
28
29
  desc 'oauth', "fetch oauth credentials"
29
- def oauth()
30
+ def oauth
30
31
  SmugmugAPI.new.request_access_token
31
32
  end
32
33
 
33
34
  desc 'albums', "list albums with their weburl"
34
- method_option :folder, aliases: '-f', type: :string, default: '.'
35
- def albums(folder = nil, album_name = nil)
35
+ def albums
36
36
  @smugmug = SmugmugAPI.new
37
37
  albums = @smugmug.albums_long
38
38
 
@@ -1,3 +1,4 @@
1
- module KubeDeploy
2
- VERSION = '0.2.10'.freeze
1
+ # frozen_string_literal: true
2
+ module PhotoHelper
3
+ VERSION = '0.3'
3
4
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'thor'
2
3
 
3
4
  require 'helpers/printer'
@@ -9,17 +10,20 @@ require 'photo-helper/move'
9
10
  require 'photo-helper/instagram'
10
11
  require 'photo-helper/compress'
11
12
  require 'photo-helper/smugmug'
13
+ require 'photo-helper/screensaver'
12
14
 
13
- # todo: move to config file
15
+ # TODO: move to config file
14
16
  RAW_EXTENSION = "dng"
15
17
  RAW_EXTENSIONS = [RAW_EXTENSION, "DNG", "ORF"]
16
18
  JPEG_EXTENSION = "JPG"
17
- JPEG_EXTENSIONS = ["JPG", "jpg", "jpeg"]
19
+ JPEG_EXTENSIONS = %w(JPG jpg jpeg)
18
20
  IMAGE_EXTENSIONS = JPEG_EXTENSIONS.concat([])
19
- PHOTOS_ROOT = "/Users/benjamincaldwell/Pictures/Pictures"
20
- JPEG_ROOT ="/Users/benjamincaldwell/Pictures/jpegs"
21
- IGNORE_FOLDERS = ["instagram", "exported", "edited"]
22
- SELECT_COLOR_TAGS = ["Winner", "Winner alt", "Superior", "Superior alt"]
21
+ PHOTOS_ROOT = File.expand_path("~/Pictures/Pictures")
22
+ BEST_OF_ROOT = File.expand_path("~/Pictures/Pictures/Best\ of")
23
+ SCREENSAVER_ROOT = File.expand_path("~/Pictures/screensaver")
24
+ JPEG_ROOT = File.expand_path("~/Pictures/jpegs")
25
+ IGNORE_FOLDERS = %w(instagram exported edited)
26
+ SELECT_COLOR_TAGS = ["Winner", "Winner alt", "Superior", "Superior alt", "Typical", "Typical alt"]
23
27
 
24
28
  module PhotoHelper
25
29
  class CLI < Thor
@@ -37,6 +41,7 @@ module PhotoHelper
37
41
  register PhotoHelper::Instagram, :instagram, "instagram", "Do something else"
38
42
  register PhotoHelper::Move, :move, "move", "Do something else"
39
43
  register PhotoHelper::Compress, :compress, "compress", "Do something else"
40
- register PhotoHelper::Smugmug, :smugmug, "smugmug", "Interface with Smugmug"
44
+ register PhotoHelper::Smugmug, :smugmug, "smugmug", "Interface with Smugmug"
45
+ register PhotoHelper::Screensaver, :screensaver, "screensaver", "Move best photos to screensaver folder and compress"
41
46
  end
42
47
  end
@@ -5,7 +5,7 @@ require 'photo-helper/version'
5
5
 
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = "photo-helper"
8
- spec.version = KubeDeploy::VERSION
8
+ spec.version = PhotoHelper::VERSION
9
9
  spec.authors = ["Benjamin Caldwell"]
10
10
  spec.email = ["caldwellbenjamin8@gmail.com"]
11
11
 
@@ -27,7 +27,7 @@ Gem::Specification.new do |spec|
27
27
  spec.add_development_dependency "pry"
28
28
  spec.add_development_dependency "byebug"
29
29
  spec.add_development_dependency "rubocop"
30
-
30
+
31
31
  spec.add_dependency "thor"
32
32
  spec.add_dependency "mini_magick"
33
33
  spec.add_dependency "ejson"
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.2.10
4
+ version: '0.3'
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-11-25 00:00:00.000000000 Z
11
+ date: 2017-12-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -216,7 +216,7 @@ files:
216
216
  - lib/helpers/image_helper.rb
217
217
  - lib/helpers/printer.rb
218
218
  - lib/helpers/secrets.rb
219
- - lib/helpers/smugmug.rb
219
+ - lib/helpers/smugmug_album.rb
220
220
  - lib/helpers/smugmug_api.rb
221
221
  - lib/helpers/trash.rb
222
222
  - lib/photo-helper/compress.rb
@@ -224,6 +224,7 @@ files:
224
224
  - lib/photo-helper/generate.rb
225
225
  - lib/photo-helper/instagram.rb
226
226
  - lib/photo-helper/move.rb
227
+ - lib/photo-helper/screensaver.rb
227
228
  - lib/photo-helper/smugmug.rb
228
229
  - lib/photo-helper/version.rb
229
230
  - lib/photo_helper.rb
@@ -1,84 +0,0 @@
1
- require "helpers/smugmug_api"
2
- require "helpers/image_helper"
3
- require "helpers/file_helper"
4
-
5
- class SmugmugHelper
6
- attr_accessor :smugmug_api
7
-
8
- # to figure out what to delete, read all xmp files, loop through uploaded files and check xmp file
9
-
10
- PATH_REGEX = %r{^.+Pictures\/.+\/(\d{4})\/(\d{2})_.+\/[^_]+_([^\/]+)}
11
-
12
- def initialize(search_path)
13
- @search_path = search_path
14
- @smugmug = SmugmugAPI.new
15
- end
16
-
17
- def parse_path
18
- if matches = "#{@search_path}/".to_s.match(PATH_REGEX)
19
- @year = matches[1]
20
- @month = Date::MONTHNAMES[matches[2].to_i].capitalize
21
- @location = matches[3].split("_").map(&:capitalize).join(' ')
22
- end
23
- end
24
-
25
- def album_name
26
- parse_path
27
- if @year && @month && @location
28
- folder = "#{@month} #{@year}"
29
- album_name_short = "#{@location} #{@month} #{@year}"
30
- File.join(@year, @month, album_name_short)
31
- else
32
- puts 'Unable to determine album from path'
33
- end
34
- end
35
-
36
- def image_list
37
- # todo: exclude exported path
38
- Dir["#{@search_path}/**/*.{#{IMAGE_EXTENSIONS.join(",")}}"].reject{ |p| FileHelper.ingore_file?(p) }
39
- end
40
-
41
- def merge_exported(images = image_list)
42
- exported = Dir["#{@search_path}/**/{Exported,exported}/*.{#{IMAGE_EXTENSIONS.join(",")}}"]
43
- exported_basenames = exported.map{ |p| File.basename(p, ".*") }
44
- images = images.reject { |p| exported_basenames.include? File.basename(p, ".*") }
45
- images.concat(exported)
46
- end
47
-
48
- def upload(album_name, pictures, reject_trash = true)
49
- album = @smugmug.get_or_create_album(album_name, album_url: @location&.downcase)
50
- puts "#{album[:web_uri]}\n"
51
-
52
- # remove uploaded pictures
53
- uploaded = @smugmug.image_list(album[:id])
54
-
55
- pictures = pictures.reject do |p|
56
- if reject_trash
57
- return true if ImageHelper.color_class(p) == "Trash"
58
- end
59
- uploaded.include? File.basename(p)
60
- end
61
-
62
- puts "Uploading #{pictures.count} jpegs"
63
-
64
- @smugmug.upload_images(pictures, album[:id], workers: 8)
65
- end
66
-
67
- def upload_dl
68
- @album_name = album_name
69
- @album_name = File.join("dl", @album_name)
70
-
71
- puts "Uploading all images to album #{@album_name}"
72
- upload(@album_name, image_list)
73
- end
74
-
75
- def upload_select
76
- @album_name = album_name
77
- pictures = image_list
78
- pictures = pictures.select{ |p| ImageHelper.is_select?(p)}
79
- pictures = merge_exported(pictures)
80
-
81
- puts "Uploading selects to album #{@album_name}"
82
- upload(@album_name, pictures)
83
- end
84
- end