photo-helper 0.2.10 → 0.3

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