desoto-photoapp 0.4.7 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Binary file
@@ -0,0 +1,3 @@
1
+ source ~/.bash_profile
2
+ photoapp process
3
+ photoapp upload
@@ -21,25 +21,30 @@ def update
21
21
  system "rm -rf /Applications/#{app}.app"
22
22
  system "cp -r #{Photoapp.gem_dir("assets/#{app}.app")} /Applications/"
23
23
  end
24
+
25
+ install_plist
26
+ end
27
+
28
+ def install_plist
29
+ path = File.expand_path("~/Library/LaunchAgents")
30
+ FileUtils.mkdir_p(path)
31
+
32
+ dest = File.join(path, 'com.desotocaverns.photoapp.plist')
33
+ plist = Photoapp::Session.new({}).plist
34
+
35
+ File.open(dest, 'w') do |io|
36
+ io.write(plist)
37
+ end
24
38
 
25
- folder_actions_path = File.expand_path("~/Library/Workflows/Applications/Folder\\ Actions/")
26
- system "mkdir -p #{folder_actions_path}"
27
- system "rm -rf #{File.join(folder_actions_path, "photoapp-process.workflow")}"
28
- system "cp -r #{Photoapp.gem_dir('assets/photoapp-process.workflow')} #{folder_actions_path}"
39
+ system "launchctl unload #{dest}"
40
+ system "launchctl load -w -F #{dest}"
29
41
  end
30
42
 
31
43
  def actions
32
44
  system "open /System/Library/Image\\ Capture/Support/Application/AutoImporter.app"
33
-
34
- system 'open '+folder_actions_setup
35
45
  end
36
46
 
37
47
  def setup
38
- unless `ls /Library/Automator` =~ /Import Files into Photos/
39
- system "say 'please install Automator actions for Photos app'"
40
- system "open #{Photoapp.gem_dir('assets/photos-action-installer.pkg')}"
41
- end
42
-
43
48
  update
44
49
  actions
45
50
  end
@@ -97,6 +102,8 @@ when 'setup'
97
102
  setup
98
103
  when 'update'
99
104
  update
105
+ when 'plist'
106
+ install_plist
100
107
  when 'set-actions'
101
108
  actions
102
109
  when 'process'
@@ -108,5 +115,10 @@ when 'reprint'
108
115
  Photoapp::Session.new(options).reprint
109
116
  when 'import'
110
117
  Photoapp::Session.new(options).import
118
+ when 'print'
119
+ Photoapp::Session.new(options).print
120
+ when 'optimize'
121
+ path = ARGV.join('')
122
+ path = nil if path.empty?
123
+ Photoapp::Session.new(options).optimize path
111
124
  end
112
-
@@ -50,6 +50,7 @@ module Photoapp
50
50
  'date_font_size' => 24,
51
51
  'config' => 'photoapp.yml',
52
52
  'upload' => 'upload',
53
+ 'upload_queue' => 'upload_queue',
53
54
  'print' => 'print',
54
55
  'photos_import' => 'photos_import',
55
56
  'reprint' => 'reprint'
@@ -64,6 +65,7 @@ module Photoapp
64
65
  end
65
66
 
66
67
  config['upload'] = root(config['upload'])
68
+ config['upload_queue'] = root(config['upload_queue'])
67
69
  config['print'] = root(config['print'])
68
70
  config['photos_import'] = root(config['photos_import'])
69
71
  config['reprint'] = root(config['reprint'])
@@ -78,24 +80,54 @@ module Photoapp
78
80
  end
79
81
 
80
82
  def process
83
+
81
84
  photos = load_photos
82
- tmp = root('.tmp')
83
- FileUtils.mkdir_p tmp
85
+ unless photos.empty?
84
86
 
85
- photos.map! do |f|
86
- p = process_image(f, tmp)
87
- p.write
88
- p
89
- end
87
+ # Announce photos
88
+ noun = photos.size == 1 ? "photo" : "photos"
89
+ system "say -v 'Daniel' 'processing #{photos.size} #{noun}'"
90
+
91
+ tmp = root('.tmp')
92
+ FileUtils.mkdir_p tmp
93
+
94
+ photos.map! do |f|
95
+ p = process_image(f, tmp)
96
+ p.write
97
+ p
98
+ end
99
+
100
+ optimize
90
101
 
91
- import
92
- print
102
+ import
103
+ print
93
104
 
94
- FileUtils.rm_rf tmp
105
+ FileUtils.rm_rf tmp
106
+ end
95
107
  end
96
108
 
109
+ # Import to Photos.app via AppleScript
97
110
  def import
98
- `automator -i #{config['photos_import']} #{Photoapp.gem_dir("lib/import-photos.workflow")}`
111
+ script = %Q{osascript -e 'set filePosixPath to "#{config['photos_import']}"
112
+ set importFolder to (POSIX file filePosixPath) as alias
113
+
114
+ set extensionsList to {"jpg", "jpeg"}
115
+ tell application "Finder" to set theFiles to every file of importFolder whose name extension is in extensionsList
116
+
117
+ if (count of theFiles) > 0 then
118
+ set imageList to {}
119
+ repeat with i from 1 to number of items in theFiles
120
+ set this_item to item i of theFiles as alias
121
+ set the end of imageList to this_item
122
+ end repeat
123
+
124
+ tell application "Photos"
125
+ activate
126
+ delay 1
127
+ import imageList skip check duplicates yes
128
+ end tell
129
+ end if'}
130
+ `#{script}`
99
131
  FileUtils.rm_rf config['photos_import']
100
132
  end
101
133
 
@@ -109,10 +141,19 @@ module Photoapp
109
141
  def process_image(photo, destination)
110
142
  path = File.join(destination, File.basename(photo))
111
143
  FileUtils.mv photo, path
112
- `automator -i #{path} #{Photoapp.gem_dir("lib/adjust-image.workflow")}`
113
144
  Photo.new(path, logo, self)
114
145
  end
115
146
 
147
+ def optimize(path=nil)
148
+ path ||= config['upload']
149
+ exec = Photoapp.gem_dir("bin/imageOptim")
150
+
151
+ if File.directory?(path)
152
+ `#{exec} -d #{path}`
153
+ else
154
+ `find #{path} | #{exec}`
155
+ end
156
+ end
116
157
 
117
158
  # grab all photos from config source
118
159
  def load_photos(path=nil)
@@ -135,12 +176,14 @@ module Photoapp
135
176
  photos = load_photos(config['upload'])
136
177
 
137
178
  if photos.size > 0
179
+ FileUtils.mkdir_p config['upload_queue']
180
+ FileUtils.mv photos, config['upload_queue']
181
+
138
182
  status = S3.new(@config).push
139
- FileUtils.rm photos
183
+ FileUtils.rm_rf config['upload_queue']
184
+
140
185
  many = photos.size != 1 ? "photos" : "photo"
141
- puts "Uploaded #{photos.size} #{many}."
142
- else
143
- puts "There are no photos to upload."
186
+ system "say -v 'Daniel' 'Uploaded #{photos.size} #{many}.'"
144
187
  end
145
188
  end
146
189
 
@@ -149,11 +192,8 @@ module Photoapp
149
192
  photos = Dir[*files].uniq
150
193
  if !photos.empty?
151
194
  system "lpr #{photos.join(' ')}"
152
- if photos.size == 1
153
- puts "Printing #{photos.size} photo"
154
- else
155
- puts "Printing #{photos.size} photos"
156
- end
195
+ count = photos.size == 1 ? "photo" : "photos"
196
+ puts "Printing #{photos.size} #{count}"
157
197
  else
158
198
  puts "No photos to print"
159
199
  end
@@ -168,9 +208,35 @@ module Photoapp
168
208
  photo = File.expand_path(photo)
169
209
  path = photo.sub(/\.jpe?g/i, '.copy.jpg')
170
210
  FileUtils.cp photo, path
171
- `automator -i #{path} #{Photoapp.gem_dir("lib/adjust-image.workflow")}`
172
211
 
173
212
  Photo.new(path, logo, self).write(path)
213
+ optimize path
214
+ end
215
+
216
+ def plist
217
+ %Q{<?xml version="1.0" encoding="UTF-8"?>
218
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
219
+ <plist version="1.0">
220
+ <dict>
221
+ <key>KeepAlive</key>
222
+ <dict>
223
+ <key>SuccessfulExit</key>
224
+ <false/>
225
+ </dict>
226
+ <key>Label</key>
227
+ <string>com.desotocaverns.photoapp</string>
228
+ <key>ProgramArguments</key>
229
+ <array>
230
+ <string>#{Photoapp.gem_dir('bin', 'process.sh')}</string>
231
+ </array>
232
+ <key>RunAtLoad</key>
233
+ <true/>
234
+ <key>WorkingDirectory</key>
235
+ <string>#{root}</string>
236
+ <key>StartInterval</key>
237
+ <integer>60</integer>
238
+ </dict>
239
+ </plist>}
174
240
  end
175
241
 
176
242
  end
@@ -17,7 +17,7 @@ module Photoapp
17
17
  end
18
18
 
19
19
  def image
20
- @image ||= Image.read(file).first.resize_to_fill(2100, 1500, NorthGravity)
20
+ @image ||= Image.read(file).first.resize_to_fill(2100, 1500, NorthGravity).modulate(0.99, 1.15).unsharp_mask(4.0, 1.5).sharpen(1.0, 1.1)
21
21
  end
22
22
 
23
23
  def watermark
@@ -1,3 +1,3 @@
1
1
  module Photoapp
2
- VERSION = "0.4.7"
2
+ VERSION = "0.5.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: desoto-photoapp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.7
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brandon Mathis
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-03-02 00:00:00.000000000 Z
11
+ date: 2018-03-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rmagick
@@ -160,17 +160,15 @@ files:
160
160
  - assets/photoapp-process.workflow/Contents/Info.plist
161
161
  - assets/photoapp-process.workflow/Contents/QuickLook/Thumbnail.png
162
162
  - assets/photoapp-process.workflow/Contents/document.wflow
163
- - assets/photos-action-installer.pkg
164
163
  - assets/watermark.png
165
164
  - bin/console
165
+ - bin/imageOptim
166
+ - bin/imageOptimAppleScriptLib
167
+ - bin/imageOptimBashLib
168
+ - bin/pngquant
169
+ - bin/process.sh
166
170
  - bin/setup
167
171
  - exe/photoapp
168
- - lib/adjust-image.workflow/Contents/Info.plist
169
- - lib/adjust-image.workflow/Contents/QuickLook/Preview.png
170
- - lib/adjust-image.workflow/Contents/document.wflow
171
- - lib/import-photos.workflow/Contents/Info.plist
172
- - lib/import-photos.workflow/Contents/QuickLook/Thumbnail.png
173
- - lib/import-photos.workflow/Contents/document.wflow
174
172
  - lib/photoapp.rb
175
173
  - lib/photoapp/photo.rb
176
174
  - lib/photoapp/s3.rb
@@ -1,8 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
- <plist version="1.0">
4
- <dict>
5
- <key>CFBundleName</key>
6
- <string>workflow</string>
7
- </dict>
8
- </plist>
@@ -1,345 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
- <plist version="1.0">
4
- <dict>
5
- <key>AMApplicationBuild</key>
6
- <string>409.2</string>
7
- <key>AMApplicationVersion</key>
8
- <string>2.5</string>
9
- <key>AMDocumentVersion</key>
10
- <string>2</string>
11
- <key>actions</key>
12
- <array>
13
- <dict>
14
- <key>action</key>
15
- <dict>
16
- <key>AMAccepts</key>
17
- <dict>
18
- <key>Container</key>
19
- <string>List</string>
20
- <key>Optional</key>
21
- <false/>
22
- <key>Types</key>
23
- <array>
24
- <string>com.apple.cocoa.path</string>
25
- </array>
26
- </dict>
27
- <key>AMActionVersion</key>
28
- <string>1.0.2</string>
29
- <key>AMApplication</key>
30
- <array>
31
- <string>Finder</string>
32
- </array>
33
- <key>AMParameterProperties</key>
34
- <dict>
35
- <key>recurse</key>
36
- <dict/>
37
- </dict>
38
- <key>AMProvides</key>
39
- <dict>
40
- <key>Container</key>
41
- <string>List</string>
42
- <key>Types</key>
43
- <array>
44
- <string>com.apple.cocoa.path</string>
45
- </array>
46
- </dict>
47
- <key>AMRequiredResources</key>
48
- <array/>
49
- <key>ActionBundlePath</key>
50
- <string>/System/Library/Automator/Get Folder Contents.action</string>
51
- <key>ActionName</key>
52
- <string>Get Folder Contents</string>
53
- <key>ActionParameters</key>
54
- <dict>
55
- <key>recurse</key>
56
- <false/>
57
- </dict>
58
- <key>BundleIdentifier</key>
59
- <string>com.apple.Automator.GetFolderContents</string>
60
- <key>CFBundleVersion</key>
61
- <string>1.0.2</string>
62
- <key>CanShowSelectedItemsWhenRun</key>
63
- <true/>
64
- <key>CanShowWhenRun</key>
65
- <true/>
66
- <key>Category</key>
67
- <array>
68
- <string>AMCategoryFilesAndFolders</string>
69
- </array>
70
- <key>Class Name</key>
71
- <string>GetFolderContents</string>
72
- <key>InputUUID</key>
73
- <string>7E8728FF-7ACC-42B8-AA00-011832942505</string>
74
- <key>Keywords</key>
75
- <array>
76
- <string>File</string>
77
- <string>Folder</string>
78
- </array>
79
- <key>OutputUUID</key>
80
- <string>D94B20FF-575A-4968-ADD4-5D8D5F1C3844</string>
81
- <key>UUID</key>
82
- <string>E2DBEF57-9022-4A18-8F53-4D7A7B5BAF19</string>
83
- <key>UnlocalizedApplications</key>
84
- <array>
85
- <string>Finder</string>
86
- </array>
87
- <key>arguments</key>
88
- <dict>
89
- <key>0</key>
90
- <dict>
91
- <key>default value</key>
92
- <false/>
93
- <key>name</key>
94
- <string>recurse</string>
95
- <key>required</key>
96
- <string>0</string>
97
- <key>type</key>
98
- <string>0</string>
99
- <key>uuid</key>
100
- <string>0</string>
101
- </dict>
102
- </dict>
103
- <key>isViewVisible</key>
104
- <true/>
105
- <key>location</key>
106
- <string>369.000000:102.000000</string>
107
- <key>nibPath</key>
108
- <string>/System/Library/Automator/Get Folder Contents.action/Contents/Resources/Base.lproj/main.nib</string>
109
- </dict>
110
- <key>isViewVisible</key>
111
- <true/>
112
- </dict>
113
- <dict>
114
- <key>action</key>
115
- <dict>
116
- <key>AMAccepts</key>
117
- <dict>
118
- <key>Container</key>
119
- <string>List</string>
120
- <key>Optional</key>
121
- <false/>
122
- <key>Types</key>
123
- <array>
124
- <string>com.apple.applescript.alias-object.image</string>
125
- </array>
126
- </dict>
127
- <key>AMActionVersion</key>
128
- <string>8</string>
129
- <key>AMApplication</key>
130
- <array/>
131
- <key>AMParameterProperties</key>
132
- <dict>
133
- <key>filterIdentifier</key>
134
- <dict/>
135
- <key>filterParameters</key>
136
- <dict/>
137
- </dict>
138
- <key>AMProvides</key>
139
- <dict>
140
- <key>Container</key>
141
- <string>List</string>
142
- <key>Types</key>
143
- <array>
144
- <string>com.apple.applescript.alias-object.image</string>
145
- </array>
146
- </dict>
147
- <key>AMRequiredResources</key>
148
- <array/>
149
- <key>ActionBundlePath</key>
150
- <string>/System/Library/Automator/Apply Quartz Composition Filter to Image Files.action</string>
151
- <key>ActionName</key>
152
- <string>Apply Quartz Composition Filter to Image Files</string>
153
- <key>ActionParameters</key>
154
- <dict>
155
- <key>filterIdentifier</key>
156
- <string>/color controls</string>
157
- <key>filterParameters</key>
158
- <dict>
159
- <key>brightness</key>
160
- <real>0.0</real>
161
- <key>contrast</key>
162
- <real>1.02</real>
163
- <key>hue</key>
164
- <real>0.0</real>
165
- <key>saturation</key>
166
- <real>1.1477118185863298</real>
167
- </dict>
168
- </dict>
169
- <key>BundleIdentifier</key>
170
- <string>com.apple.QuartzComposer.automatorActions.imageFilter</string>
171
- <key>CFBundleVersion</key>
172
- <string>8</string>
173
- <key>CanShowSelectedItemsWhenRun</key>
174
- <false/>
175
- <key>CanShowWhenRun</key>
176
- <true/>
177
- <key>Category</key>
178
- <array>
179
- <string>AMCategoryPhotos</string>
180
- </array>
181
- <key>Class Name</key>
182
- <string>QuartzComposerImageFilter</string>
183
- <key>InputUUID</key>
184
- <string>C88221E0-145B-4AB4-B31D-4B383E349474</string>
185
- <key>Keywords</key>
186
- <array>
187
- <string>Quartz Composer</string>
188
- <string>Image</string>
189
- </array>
190
- <key>OutputUUID</key>
191
- <string>BD275A9A-26F5-4986-A5BC-02C3C724F0CA</string>
192
- <key>UUID</key>
193
- <string>72C211D3-3FF6-43FE-85F8-098506C0141F</string>
194
- <key>arguments</key>
195
- <dict>
196
- <key>0</key>
197
- <dict>
198
- <key>default value</key>
199
- <string>/sepia</string>
200
- <key>name</key>
201
- <string>filterIdentifier</string>
202
- <key>required</key>
203
- <string>0</string>
204
- <key>type</key>
205
- <string>0</string>
206
- <key>uuid</key>
207
- <string>0</string>
208
- </dict>
209
- </dict>
210
- <key>isViewVisible</key>
211
- <true/>
212
- <key>location</key>
213
- <string>369.000000:413.000000</string>
214
- <key>nibPath</key>
215
- <string>/System/Library/Automator/Apply Quartz Composition Filter to Image Files.action/Contents/Resources/English.lproj/main.nib</string>
216
- </dict>
217
- <key>isViewVisible</key>
218
- <true/>
219
- </dict>
220
- <dict>
221
- <key>action</key>
222
- <dict>
223
- <key>AMAccepts</key>
224
- <dict>
225
- <key>Container</key>
226
- <string>List</string>
227
- <key>Optional</key>
228
- <false/>
229
- <key>Types</key>
230
- <array>
231
- <string>com.apple.applescript.alias-object.image</string>
232
- </array>
233
- </dict>
234
- <key>AMActionVersion</key>
235
- <string>8</string>
236
- <key>AMApplication</key>
237
- <array/>
238
- <key>AMParameterProperties</key>
239
- <dict>
240
- <key>filterIdentifier</key>
241
- <dict/>
242
- <key>filterParameters</key>
243
- <dict/>
244
- </dict>
245
- <key>AMProvides</key>
246
- <dict>
247
- <key>Container</key>
248
- <string>List</string>
249
- <key>Types</key>
250
- <array>
251
- <string>com.apple.applescript.alias-object.image</string>
252
- </array>
253
- </dict>
254
- <key>AMRequiredResources</key>
255
- <array/>
256
- <key>ActionBundlePath</key>
257
- <string>/System/Library/Automator/Apply Quartz Composition Filter to Image Files.action</string>
258
- <key>ActionName</key>
259
- <string>Apply Quartz Composition Filter to Image Files</string>
260
- <key>ActionParameters</key>
261
- <dict>
262
- <key>filterIdentifier</key>
263
- <string>/sharpen</string>
264
- <key>filterParameters</key>
265
- <dict>
266
- <key>amount</key>
267
- <real>0.059999999999999998</real>
268
- </dict>
269
- </dict>
270
- <key>BundleIdentifier</key>
271
- <string>com.apple.QuartzComposer.automatorActions.imageFilter</string>
272
- <key>CFBundleVersion</key>
273
- <string>8</string>
274
- <key>CanShowSelectedItemsWhenRun</key>
275
- <false/>
276
- <key>CanShowWhenRun</key>
277
- <true/>
278
- <key>Category</key>
279
- <array>
280
- <string>AMCategoryPhotos</string>
281
- </array>
282
- <key>Class Name</key>
283
- <string>QuartzComposerImageFilter</string>
284
- <key>InputUUID</key>
285
- <string>23954409-13D4-47BF-A14B-2B4812D957CE</string>
286
- <key>Keywords</key>
287
- <array>
288
- <string>Quartz Composer</string>
289
- <string>Image</string>
290
- </array>
291
- <key>OutputUUID</key>
292
- <string>9FAA26D0-490B-4E62-8A84-0263D47EBC99</string>
293
- <key>UUID</key>
294
- <string>8864A504-6BCC-4A02-A1B6-57A1ED94B1D9</string>
295
- <key>arguments</key>
296
- <dict>
297
- <key>0</key>
298
- <dict>
299
- <key>default value</key>
300
- <string>/sepia</string>
301
- <key>name</key>
302
- <string>filterIdentifier</string>
303
- <key>required</key>
304
- <string>0</string>
305
- <key>type</key>
306
- <string>0</string>
307
- <key>uuid</key>
308
- <string>0</string>
309
- </dict>
310
- </dict>
311
- <key>isViewVisible</key>
312
- <true/>
313
- <key>location</key>
314
- <string>369.000000:724.000000</string>
315
- <key>nibPath</key>
316
- <string>/System/Library/Automator/Apply Quartz Composition Filter to Image Files.action/Contents/Resources/English.lproj/main.nib</string>
317
- </dict>
318
- <key>isViewVisible</key>
319
- <true/>
320
- </dict>
321
- </array>
322
- <key>connectors</key>
323
- <dict>
324
- <key>3E4725D0-76D1-4075-B5FD-A60FD84DCB43</key>
325
- <dict>
326
- <key>from</key>
327
- <string>72C211D3-3FF6-43FE-85F8-098506C0141F - 72C211D3-3FF6-43FE-85F8-098506C0141F</string>
328
- <key>to</key>
329
- <string>8864A504-6BCC-4A02-A1B6-57A1ED94B1D9 - 8864A504-6BCC-4A02-A1B6-57A1ED94B1D9</string>
330
- </dict>
331
- <key>FA681B5B-3A8C-455A-A5BC-AA87FA5A5C73</key>
332
- <dict>
333
- <key>from</key>
334
- <string>E2DBEF57-9022-4A18-8F53-4D7A7B5BAF19 - E2DBEF57-9022-4A18-8F53-4D7A7B5BAF19</string>
335
- <key>to</key>
336
- <string>72C211D3-3FF6-43FE-85F8-098506C0141F - 72C211D3-3FF6-43FE-85F8-098506C0141F</string>
337
- </dict>
338
- </dict>
339
- <key>workflowMetaData</key>
340
- <dict>
341
- <key>workflowTypeIdentifier</key>
342
- <string>com.apple.Automator.workflow</string>
343
- </dict>
344
- </dict>
345
- </plist>