photostream 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.markdown ADDED
@@ -0,0 +1,43 @@
1
+ Photostream
2
+ =======
3
+
4
+ Makes it easer to access photos from your Photo Stream on a Mac.
5
+
6
+ This probably requires you to activate the Photo Stream in your iCloud
7
+ System Preferences.
8
+
9
+
10
+ Usage
11
+ -----
12
+
13
+ To get going:
14
+
15
+ photostream start <directory>
16
+
17
+ This will start it syncing to the given directory. If you don't supply a
18
+ directory, it will sync into `$HOME/Pictures/Photo Stream`.
19
+
20
+ photostream sync <directory>
21
+
22
+ This will perform a one-off sync. This is what gets run by the background job.
23
+ Again, if you don't supply a directory, the default will be used.
24
+
25
+ photostream stop
26
+
27
+ This will stop the sync, and remove the background job. It won't, however,
28
+ remove any of the linked files that it created. I'm afraid you'll need to do
29
+ that yourself.
30
+
31
+
32
+ How does it work?
33
+ ------
34
+
35
+ When Photo Stream is active, the pictures actually get downloaded to your Mac,
36
+ but in a hard-to-navigate nested directory structure of hashes.
37
+
38
+ This tool just creates a new directory with hard links to all the files in that
39
+ nested directory structure. It uses `launchd` to monitor when new photos appear
40
+ and resyncs the directory any time a new photo appears on your computer.
41
+
42
+ We have to use hard links so that the Finder will display the image with a
43
+ thumbnail.
data/bin/photostream ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH.unshift(File.expand_path("../../lib", __FILE__))
4
+ require "photostream"
5
+
6
+ PhotoStream.run(ARGV)
@@ -0,0 +1,80 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "fileutils"
4
+ require "erb"
5
+ require "rbconfig"
6
+
7
+ module PhotoStream
8
+ def self.run(args)
9
+ target = args[1] || File.join(ENV["HOME"], "Pictures", "Photo Stream")
10
+ if args[0] == "start"
11
+ start(target)
12
+ elsif args[0] == "stop"
13
+ stop
14
+ elsif args[0] == "sync"
15
+ sync(target)
16
+ else
17
+ puts "Usage: photostream [start|stop] <target directory>"
18
+ end
19
+ end
20
+
21
+ BASE_DIRECTORY = File.join(ENV["HOME"], "Library", "Application Support", "iLifeAssetManagement", "assets", "sub")
22
+ PLIST_PATH = File.join(ENV["HOME"], "Library", "LaunchAgents", "com.lazyatom.photostream.plist")
23
+ RUBY_INTERPRETER_PATH = File.join(RbConfig::CONFIG["bindir"],
24
+ RbConfig::CONFIG["RUBY_INSTALL_NAME"] +
25
+ RbConfig::CONFIG["EXEEXT"])
26
+
27
+ PLIST = <<-EOS
28
+ <?xml version="1.0" encoding="UTF-8"?>
29
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
30
+ <plist version="1.0">
31
+ <dict>
32
+ <key>Label</key>
33
+ <string>com.lazyatom.photostream</string>
34
+ <key>UserName</key>
35
+ <string><%= `whoami`.strip %></string>
36
+ <key>ProgramArguments</key>
37
+ <array>
38
+ <string><%= ruby %></string>
39
+ <string><%= bin %></string>
40
+ <string>sync</string>
41
+ <string><%= target_directory %></string>
42
+ </array>
43
+ <key>KeepAlive</key>
44
+ <false/>
45
+ <key>WatchPaths</key>
46
+ <array>
47
+ <string><%= base_directory %></string>
48
+ </array>
49
+ <key>RunAtLoad</key>
50
+ <true/>
51
+ </dict>
52
+ </plist>
53
+ EOS
54
+
55
+ def self.start(target_directory)
56
+ bin = File.expand_path($0)
57
+ base_directory = BASE_DIRECTORY
58
+ ruby = RUBY_INTERPRETER_PATH
59
+ File.open(PLIST_PATH, "w") do |f|
60
+ f.write ERB.new(PLIST.strip).result(binding)
61
+ end
62
+ `launchctl load #{PLIST_PATH}`
63
+ puts "Started syncing to #{target_directory}"
64
+ end
65
+
66
+ def self.stop
67
+ `launchctl unload #{PLIST_PATH}`
68
+ FileUtils.rm(PLIST_PATH) if File.exist?(PLIST_PATH)
69
+ puts "Stopped syncing"
70
+ end
71
+
72
+ def self.sync(target_directory)
73
+ puts "Making #{target_directory}"
74
+ FileUtils.mkdir_p(target_directory)
75
+ Dir[File.join(BASE_DIRECTORY, "*", "**")].each do |path|
76
+ FileUtils.ln(path, File.join(target_directory, File.basename(path)), force: true)
77
+ end
78
+ puts "Synced Photo Stream to #{target_directory}"
79
+ end
80
+ end
metadata ADDED
@@ -0,0 +1,51 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: photostream
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - James Adam
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-03-05 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description:
15
+ email: james@lazyatom.com
16
+ executables:
17
+ - photostream
18
+ extensions: []
19
+ extra_rdoc_files:
20
+ - README.markdown
21
+ files:
22
+ - README.markdown
23
+ - bin/photostream
24
+ - lib/photostream.rb
25
+ homepage: http://lazyatom.com
26
+ licenses: []
27
+ post_install_message:
28
+ rdoc_options:
29
+ - --main
30
+ - README.markdown
31
+ require_paths:
32
+ - lib
33
+ required_ruby_version: !ruby/object:Gem::Requirement
34
+ none: false
35
+ requirements:
36
+ - - ! '>='
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ required_rubygems_version: !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ! '>='
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ requirements: []
46
+ rubyforge_project:
47
+ rubygems_version: 1.8.23
48
+ signing_key:
49
+ specification_version: 3
50
+ summary: Makes it easier to deal with the Photo Stream via the Finder
51
+ test_files: []