syncbox 0.0.1

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/bin/syncbox ADDED
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require Dir.getwd + '/lib/syncs3.rb'
4
+
5
+
6
+ if ARGV.first == "init"
7
+ Syncs3.config_init
8
+ elsif ARGV.first == "start"
9
+ puts "start."
10
+ Syncs3.start
11
+ elsif ARGV.first == "stop"
12
+ Syncs3.stop
13
+ puts "Stopped."
14
+ elsif ARGV.first == "status"
15
+ Syncs3.status
16
+ elsif ARGV.first == "restart"
17
+ # Syncs3.stop
18
+ # puts "restart."
19
+ # Syncs3.start
20
+ elsif ARGV.first == "list" && ARGV.last == "files"
21
+ Syncs3.file_status
22
+ elsif ARGV.first == "help"
23
+ puts "help"
24
+ else
25
+ put "No such command."
26
+ end
27
+
28
+
data/lib/syncbox.rb ADDED
@@ -0,0 +1,50 @@
1
+ require 'optparse'
2
+ require 'yaml'
3
+ require_relative 'syncbox/store.rb'
4
+ require_relative 'syncbox/syncer.rb'
5
+
6
+ module Syncbox
7
+ class Syncbox
8
+
9
+ def self.start
10
+ syncbox = Syncbox.new
11
+ syncbox.start
12
+ end
13
+
14
+ # read config path from command line, and load configs
15
+ # init a store instance
16
+ #
17
+ def initialize
18
+ config_file = option_parser[:config]
19
+ @local_directory = read_config(config_file, "local_directory")
20
+ config_s3 = read_config(config_file, "s3")
21
+ @store = Store.new("S3", config_s3)
22
+ end
23
+
24
+ # Init a Syncer object, and start sync
25
+ #
26
+ def start
27
+ syncer = Syncer.new(@local_directory, @store)
28
+ syncer.sync
29
+ end
30
+
31
+ private
32
+ def read_config(config_file, store)
33
+ config = YAML.load_file(config_file)
34
+ config[store]
35
+ end
36
+
37
+ def option_parser
38
+ options = {}
39
+ option_parser = OptionParser.new do |opts|
40
+ opts.banner = 'This is help messages.'
41
+ opts.on('-c file', '--config file', 'Pass-in config file path') do |value|
42
+ options[:config] = value
43
+ end
44
+ end.parse!
45
+ options
46
+ end
47
+ end
48
+ end
49
+
50
+
@@ -0,0 +1,42 @@
1
+ require_relative 'store/s3_bucket.rb'
2
+
3
+ module Syncbox
4
+ class Store
5
+
6
+ STORES = { "S3" => "S3Bucket", "Glacier" => "Glacier"}
7
+
8
+ # Initializes a store object
9
+ #
10
+ # @param [String] store
11
+ # @param [HASH] options
12
+ #
13
+ def initialize(store, options={})
14
+ raise ArgumentError, "Store #{store} is not supported." unless STORES.fetch(store)
15
+ class_name = STORES[store]
16
+ @store = Object.const_get("Syncbox").const_get(class_name).new(options)
17
+ end
18
+
19
+ # Add file to store.
20
+ #
21
+ # @param [String] file_path
22
+ #
23
+ # @return a public (not authenticated) URL for the object
24
+ #
25
+ def add(file_path)
26
+ @store.upload(file_path)
27
+ end
28
+
29
+ # delete file from store.
30
+ #
31
+ # @param [String] file_path
32
+ #
33
+ # @return nil
34
+ #
35
+ def delete(file_path)
36
+ @store.delete(file_path)
37
+ end
38
+
39
+ alias modify add
40
+
41
+ end
42
+ end
@@ -0,0 +1,76 @@
1
+ require 'aws-sdk'
2
+
3
+ module Syncbox
4
+ class S3Bucket
5
+
6
+ # Initializes a s3 bucket object
7
+ #
8
+ # @param [Hash] options
9
+ #
10
+ # options must include:
11
+ # * access_key_id
12
+ # * secret_access_key
13
+ # * bucket_name
14
+ #
15
+ # Note: modify the local files, triggers upload.
16
+ # Upload same name file, S3 will automatically replaced the original file.
17
+ # Cancel the upload in the middle of uploading will not replace the originmal file.
18
+ #
19
+ def initialize(options)
20
+ arguement_check(options)
21
+ s3 = AWS::S3.new(:access_key_id => options["access_key_id"], :secret_access_key => options["secret_access_key"])
22
+ bucket_name = options["bucket_name"]
23
+ @bucket = s3.buckets[bucket_name]
24
+ remote_accessible_check
25
+ end
26
+
27
+ # Uploads file to bucket.
28
+ #
29
+ # @param [String] file_path
30
+ #
31
+ # @return a public (not authenticated) URL for the object
32
+ #
33
+ def upload(file_path)
34
+ file_name = File.basename(file_path)
35
+ object = @bucket.objects[file_name]
36
+ object.write(:file => file_path)
37
+ object.public_url
38
+ end
39
+
40
+ # delete file from bucket.
41
+ #
42
+ # @param [String] file_path
43
+ #
44
+ # @return nil
45
+ #
46
+ def delete(file_path)
47
+ file_name = File.basename(file_path)
48
+ object = @bucket.objects[file_name]
49
+ object.delete
50
+ end
51
+
52
+
53
+ private
54
+ # check s3 arguments contains access_key_id, secret_access_key and bucket_name
55
+ #
56
+ def arguement_check(options)
57
+ begin
58
+ options.fetch("access_key_id") && options.fetch("secret_access_key") && options.fetch("bucket_name")
59
+ rescue KeyError
60
+ raise ArgumentError, "The access_key_id, secret_access_key and bucket_name options are required."
61
+ end
62
+ end
63
+
64
+ # check S3 access_key_id, secret_access_key is valid and bucket_name exists.
65
+ #
66
+ def remote_accessible_check
67
+ begin
68
+ raise ArgumentError, "Bucket doesn't exsit." unless @bucket.exists?
69
+ rescue AWS::S3::Errors::InvalidAccessKeyId
70
+ raise ArgumentError, 'AWS Access Key Id does not exist in our records.'
71
+ rescue AWS::S3::Errors::SignatureDoesNotMatch
72
+ raise ArgumentError, 'The request signature we calculated does not match the signature you provided. Check your key and signing method.'
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,40 @@
1
+ require_relative 'store.rb'
2
+ require 'listen'
3
+
4
+ module Syncbox
5
+ class Syncer
6
+
7
+ # Initializes listener
8
+ #
9
+ # @param [String] local_directory
10
+ # @param [Store] store
11
+ #
12
+ # Note: raise arguement error when local_directory does not exist.
13
+ def initialize(local_directory, store)
14
+ raise ArgumentError, "Local directory #{local_directory} does not exist." unless Dir.exists?(local_directory)
15
+ @local_directory = local_directory
16
+ @store = store
17
+ @listener = Listen.to(local_directory).latency(0.1)
18
+ end
19
+
20
+ # Listen to local directory
21
+ # Sync local action to remote store
22
+ #
23
+ def sync
24
+ callback = Proc.new do |modified, added, removed|
25
+ added && added.each do |add_file|
26
+ @store.add(@local_directory + "/" + add_file)
27
+ end
28
+ modified && modified.each do |modified_file|
29
+ @store.modify(@local_directory + "/" + modified_file)
30
+ end
31
+ removed && removed.each do |remove_file|
32
+ @store.remove(@local_directory + "/" + remove_file)
33
+ end
34
+ end
35
+ @listener.change(&callback) # convert the callback to a block and register it
36
+ @listener.start! # have to use !
37
+ end
38
+
39
+ end
40
+ end
metadata ADDED
@@ -0,0 +1,52 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: syncbox
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Ian Dai
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-02-01 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: A gem that automatically sync file to S3 or Glacier.
15
+ email: iandai.jp@gmail.com
16
+ executables:
17
+ - syncbox
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - lib/syncbox.rb
22
+ - lib/syncbox/store.rb
23
+ - lib/syncbox/store/s3_bucket.rb
24
+ - lib/syncbox/syncer.rb
25
+ - bin/syncbox
26
+ homepage: http://iandai.cc
27
+ licenses:
28
+ - MIT
29
+ post_install_message:
30
+ rdoc_options: []
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: syncbox
51
+ test_files: []
52
+ has_rdoc: