csexton-captured 0.1.1 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/captured +1 -3
- data/lib/captured/file_tracker.rb +37 -0
- data/lib/captured/file_uploader.rb +70 -0
- data/lib/captured/fs_events.rb +54 -0
- data/lib/captured.rb +33 -0
- data/resources/captured.png +0 -0
- data/resources/green_check.png +0 -0
- data/resources/red_star.png +0 -0
- data/resources/red_x.png +0 -0
- data/resources/ruby.png +0 -0
- metadata +14 -2
data/bin/captured
CHANGED
@@ -1,9 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
require 'rubygems'
|
3
3
|
require 'optparse'
|
4
|
-
|
5
|
-
$:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
|
6
|
-
require 'captured'
|
4
|
+
require "#{File.dirname(__FILE__)}/../lib/captured"
|
7
5
|
|
8
6
|
options = {:config_file => "#{ENV['HOME']}/.captured.yml",
|
9
7
|
:watch_path => "#{ENV['HOME']}/Desktop/",
|
@@ -0,0 +1,37 @@
|
|
1
|
+
class FileTracker
|
2
|
+
attr_accessor :tracked_files
|
3
|
+
|
4
|
+
def initialize(options)
|
5
|
+
@options = options
|
6
|
+
@tracked_files = {}
|
7
|
+
end
|
8
|
+
|
9
|
+
def scan(paths, state)
|
10
|
+
puts "Scanning #{paths}"
|
11
|
+
paths.each do |path|
|
12
|
+
Dir["#{path}#{@options[:watch_pattern]}"].each do |file|
|
13
|
+
self.add file, state
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def add(file, state)
|
19
|
+
unless @tracked_files[file]
|
20
|
+
puts "Adding #{file} to tracked files as #{state}"
|
21
|
+
@tracked_files[file] = state
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def mark_processed(file)
|
26
|
+
puts "Marking #{file} processed"
|
27
|
+
@tracked_files[file] = :processed
|
28
|
+
end
|
29
|
+
|
30
|
+
def each_pending
|
31
|
+
@tracked_files.each_pair do |key, value|
|
32
|
+
if(value == :pending)
|
33
|
+
yield(key)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'digest/md5'
|
2
|
+
require 'erb'
|
3
|
+
|
4
|
+
class FileUploader
|
5
|
+
def self.upload(file, options)
|
6
|
+
self.new(options).process_upload(file)
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize(options)
|
10
|
+
@growl_path = options[:growl_path] || "/usr/local/bin/growlnotify"
|
11
|
+
@config = YAML.load_file(options[:config_file])
|
12
|
+
case @config['upload']['type']
|
13
|
+
when"eval"
|
14
|
+
@upload_proc = eval_proc
|
15
|
+
when"scp"
|
16
|
+
@upload_proc = scp_proc
|
17
|
+
when"ftp"
|
18
|
+
else
|
19
|
+
raise "Invalid Type"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def eval_proc
|
24
|
+
lambda do |file, remote_name|
|
25
|
+
remote_path = nil
|
26
|
+
unless eval @config['upload']['command']
|
27
|
+
raise "Upload failed: Bad Eval in config file"
|
28
|
+
end
|
29
|
+
# if the eval defines remote_path we will copy that to the clipboard
|
30
|
+
# otherwise we compute it ouselves
|
31
|
+
remote_path || "#{@config['upload']['url']}#{remote_name}"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def scp_proc
|
36
|
+
require 'net/scp'
|
37
|
+
require 'etc'
|
38
|
+
settings = @config['upload']
|
39
|
+
lambda do |file, remote_name|
|
40
|
+
puts "host = '#{settings['host']}'"
|
41
|
+
puts "user = '#{settings['user'] || Etc.getlogin}'"
|
42
|
+
puts "file = '#{file}'"
|
43
|
+
puts "path = '#{settings['path']+remote_name}'"
|
44
|
+
Net::SCP.upload!(settings['host'],
|
45
|
+
settings['user'] || Etc.getlogin,
|
46
|
+
file,
|
47
|
+
settings['path']+remote_name)
|
48
|
+
"#{@config['upload']['url']}#{remote_name}"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def process_upload(file)
|
53
|
+
remote_name = Digest::MD5.hexdigest(file+Time.now.to_i.to_s) + File.extname(file)
|
54
|
+
remote_path = @upload_proc.call(file, remote_name)
|
55
|
+
puts "Uploaded '#{file}' to '#{remote_path}'"
|
56
|
+
raise "Copy Failed" unless system("echo '#{remote_path}' | pbcopy")
|
57
|
+
growl("Uploaded Image", "#{File.dirname(File.expand_path(__FILE__))}/../../resources/green_check.png")
|
58
|
+
rescue => e
|
59
|
+
puts e
|
60
|
+
puts e.backtrace
|
61
|
+
growl(e)
|
62
|
+
end
|
63
|
+
|
64
|
+
def growl(msg, image = "#{File.dirname(File.expand_path(__FILE__))}/../../resources/red_x.png")
|
65
|
+
puts "grr: #{msg}"
|
66
|
+
if File.exists? @growl_path
|
67
|
+
raise "Growl Failed" unless system("#{@growl_path} -t 'Captured' -m '#{msg}' --image '#{image}'")
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'osx/foundation'
|
2
|
+
OSX.require_framework '/System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework'
|
3
|
+
|
4
|
+
class FSEvents
|
5
|
+
def initialize(dir = "#{HOME}/Desktop")
|
6
|
+
@watch_dir = dir
|
7
|
+
end
|
8
|
+
|
9
|
+
def run
|
10
|
+
callback = proc do |stream, ctx, numEvents, paths, marks, eventIDs|
|
11
|
+
|
12
|
+
#p stream
|
13
|
+
#p ctx
|
14
|
+
#p numEvents
|
15
|
+
#p paths.methods
|
16
|
+
#p marks.methods
|
17
|
+
#p eventIDs
|
18
|
+
|
19
|
+
paths.regard_as('*')
|
20
|
+
rpaths = []
|
21
|
+
numEvents.times { |i| rpaths << paths[i] }
|
22
|
+
|
23
|
+
yield(*rpaths)
|
24
|
+
end
|
25
|
+
|
26
|
+
allocator = OSX::KCFAllocatorDefault
|
27
|
+
context = nil
|
28
|
+
path = [@watch_dir] #[Dir.pwd]
|
29
|
+
sinceWhen = OSX::KFSEventStreamEventIdSinceNow
|
30
|
+
latency = 1.0
|
31
|
+
flags = 0
|
32
|
+
|
33
|
+
stream = OSX::FSEventStreamCreate(allocator, callback, context, path, sinceWhen, latency, flags)
|
34
|
+
unless stream
|
35
|
+
puts "Failed to create stream"
|
36
|
+
exit
|
37
|
+
end
|
38
|
+
|
39
|
+
OSX::FSEventStreamScheduleWithRunLoop(stream, OSX::CFRunLoopGetCurrent(), OSX::KCFRunLoopDefaultMode)
|
40
|
+
unless OSX::FSEventStreamStart(stream)
|
41
|
+
puts "Failed to start stream"
|
42
|
+
exit
|
43
|
+
end
|
44
|
+
|
45
|
+
puts "Watching #{path}"
|
46
|
+
|
47
|
+
OSX::CFRunLoopRun()
|
48
|
+
rescue Interrupt
|
49
|
+
OSX::FSEventStreamStop(stream)
|
50
|
+
OSX::FSEventStreamInvalidate(stream)
|
51
|
+
OSX::FSEventStreamRelease(stream)
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
data/lib/captured.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'captured/file_tracker'
|
2
|
+
require 'captured/file_uploader'
|
3
|
+
require 'captured/fs_events'
|
4
|
+
|
5
|
+
class Captured
|
6
|
+
def self.config_file
|
7
|
+
"#{ENV['HOME']}/.captured.yml"
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.run_once!(options)
|
11
|
+
watch_path = options[:watch_path] || "#{ENV['HOME']}/Desktop/"
|
12
|
+
Dir["#{watch_path}#{options[:watch_pattern]}"].each do |file|
|
13
|
+
if (File.mtime(file).to_i > (Time.now.to_i-10))
|
14
|
+
puts "#{file} is new"
|
15
|
+
FileUploader.upload(file, options)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.run_and_watch!(options)
|
21
|
+
watch_path = options[:watch_path] || "#{ENV['HOME']}/Desktop/"
|
22
|
+
tracker = FileTracker.new(options)
|
23
|
+
tracker.scan([desktop_dir], :existing)
|
24
|
+
e = FSEvents.new(watch_path)
|
25
|
+
e.run do |paths|
|
26
|
+
tracker.scan paths, :pending
|
27
|
+
tracker.each_pending do |file|
|
28
|
+
FileUploader.upload(file, options)
|
29
|
+
tracker.mark_processed(file)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
Binary file
|
Binary file
|
Binary file
|
data/resources/red_x.png
ADDED
Binary file
|
data/resources/ruby.png
ADDED
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: csexton-captured
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Christopher Sexton
|
@@ -23,10 +23,22 @@ extra_rdoc_files:
|
|
23
23
|
- LICENSE
|
24
24
|
- README.markdown
|
25
25
|
files:
|
26
|
+
- README.markdown
|
27
|
+
- bin/captured
|
26
28
|
- etc/captured.yml-example
|
27
29
|
- etc/launchd.plist.erb
|
30
|
+
- lib/captured.rb
|
31
|
+
- lib/captured/file_tracker.rb
|
32
|
+
- lib/captured/file_uploader.rb
|
33
|
+
- lib/captured/fs_events.rb
|
34
|
+
- resources/captured.png
|
35
|
+
- resources/green_check.png
|
36
|
+
- resources/red_star.png
|
37
|
+
- resources/red_x.png
|
38
|
+
- resources/ruby.png
|
39
|
+
- spec/captured_spec.rb
|
40
|
+
- spec/spec_helper.rb
|
28
41
|
- LICENSE
|
29
|
-
- README.markdown
|
30
42
|
has_rdoc: false
|
31
43
|
homepage: http://github.com/csexton/captured
|
32
44
|
post_install_message:
|