photostream 0.1.0

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.
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: []