cynq 0.0.2

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/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in cynq.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 RealGravity Inc.
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,78 @@
1
+ # Cynq
2
+
3
+ Easy synchronization of local files to cloud based storage.
4
+
5
+ Built on top of the Fog gem.
6
+
7
+ Note that this is an early release, and only supports AWS for remotes.
8
+
9
+ ## Installation
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ gem 'cynq'
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install cynq
22
+
23
+ ## Configuration
24
+
25
+ Cynq works best with 'project' directories. A directory that contains another directory
26
+ that contains what you want to upload to remote storage. Your ```cynq.yml```
27
+ configuration file will live in your project directory.
28
+
29
+ For example, if you had...
30
+
31
+ project_dir/
32
+ source_files/
33
+ build/
34
+ index.html
35
+ styles/style.css
36
+ cynq.yml
37
+
38
+ A sample configuration file would look like...
39
+
40
+ ```yaml
41
+ ---
42
+ local_root: build
43
+ remotes:
44
+ production:
45
+ directory: www.my-site-bucket.com
46
+ beta:
47
+ directory: beta.my-site-bucket.com
48
+ ```
49
+
50
+ This would instruct cynq to upload the contents of the ```build``` directory.
51
+ The ```build``` directory itself is not uploaded, making your ```index.hml```
52
+ file at the 'top-level' of your bucket.
53
+
54
+ You also need AWS key information in your environment. Make sure to do something
55
+ like the following (e.g. for bash)...
56
+
57
+ export AWS_ACCESS_KEY_ID=your_key_id
58
+ export AWS_SECRET_ACCESS_KEY=your_keys_secret
59
+
60
+
61
+ ## Usage
62
+
63
+ The following command uploads to the remote destination described as *beta*.
64
+
65
+ $ cynq deploy beta
66
+
67
+ If you just want to see what would happen...
68
+
69
+ $ cynq deploy --dry-run beta
70
+
71
+
72
+ ## Contributing
73
+
74
+ 1. Fork it
75
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
76
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
77
+ 4. Push to the branch (`git push origin my-new-feature`)
78
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
data/bin/cynq ADDED
@@ -0,0 +1,5 @@
1
+ require "rubygems"
2
+ gem "cynq"
3
+ require 'cynq'
4
+ require 'cynq/command'
5
+ Cynq::Command.start
data/cynq.gemspec ADDED
@@ -0,0 +1,20 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/cynq/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Darren Boyd"]
6
+ gem.email = ["dboyd@realgravity.com"]
7
+ gem.description = %q{Easy synchronization of local files to cloud based storage.}
8
+ gem.summary = %q{Copy files to the cloud.}
9
+ gem.homepage = "https://github.com/darrenboyd/cynq"
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "cynq"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = Cynq::VERSION
17
+
18
+ gem.add_dependency 'fog', '~> 1.1'
19
+ gem.add_dependency 'colorize', '~> 0.5'
20
+ end
data/lib/cynq.rb ADDED
@@ -0,0 +1,5 @@
1
+ require "cynq/version"
2
+
3
+ module Cynq
4
+ # Your code goes here...
5
+ end
@@ -0,0 +1,68 @@
1
+ require "thor"
2
+ require 'colorize'
3
+ require 'cynq/local'
4
+ require 'cynq/remote'
5
+ require 'yaml'
6
+
7
+ module Cynq
8
+ class Command < Thor
9
+ desc "deploy REMOTE", "Upload files to REMOTE"
10
+ method_option :dry_run, :type => :boolean, :aliases => "-n",
11
+ :default => false, :desc => 'Do not do anything.'
12
+ def deploy(remote)
13
+ load_config(remote)
14
+
15
+ if options.dry_run?
16
+ puts " Dry run executing...".green
17
+ end
18
+
19
+ local = Local.new(@local_root)
20
+ remote = Remote.new(@remote['directory'])
21
+
22
+ p local
23
+ p remote
24
+
25
+ keys = (local.keys + remote.keys).sort
26
+ keys.each do |key|
27
+ case
28
+ when local.missing?(key)
29
+ puts " deleting #{key}".red
30
+ remote.delete(key) unless options.dry_run?
31
+ when remote.missing?(key)
32
+ puts " adding #{key}".green
33
+ remote << local[key] unless options.dry_run?
34
+ when remote.modified?(local[key])
35
+ puts " modified #{key}".magenta
36
+ remote << local[key] unless options.dry_run?
37
+ else
38
+ puts " unchanged #{key}" unless options.dry_run?
39
+ end
40
+ end
41
+ end
42
+
43
+ no_tasks do
44
+ def load_config(remote)
45
+ conf_file = File.expand_path('cynq.yml')
46
+
47
+ unless File.exist?(conf_file)
48
+ $stderr.puts "Missing configuration file at #{conf_file}"
49
+ raise "Configuration not found"
50
+ end
51
+
52
+ @config = YAML::load_file(conf_file)
53
+ @local_root = File.expand_path(@config['local_root'])
54
+
55
+ unless Dir.exist?(@local_root)
56
+ $stderr.puts("The 'local_root' cannot be found: #{@local_root.to_s}")
57
+ raise "Configuration is invalid"
58
+ end
59
+
60
+ @remote = @config['remotes'][remote]
61
+ unless @remote
62
+ $stderr.puts("No environment matching '#{remote}' can be found.")
63
+ raise "Configuration is invalid"
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,78 @@
1
+ require 'fog'
2
+ require 'mime/types'
3
+
4
+ module Cynq
5
+ class Directory
6
+ attr_reader :connection, :keys, :bucket
7
+
8
+ def initialize(bucket_name)
9
+ establish_connection
10
+ find_bucket(bucket_name)
11
+ read_current_files
12
+ end
13
+
14
+ def include?(key)
15
+ keys.include?(key)
16
+ end
17
+
18
+ def missing?(key)
19
+ ! include? key
20
+ end
21
+
22
+ def [](key)
23
+ @current_files[key]
24
+ end
25
+
26
+ def <<(other_file)
27
+ if file = self[other_file.key]
28
+ file.body = other_file.body
29
+ else
30
+ file = @bucket.files.new({
31
+ :key => other_file.key,
32
+ :body => other_file.body
33
+ })
34
+ ct = content_type_for_key(other_file.key)
35
+ file.content_type = ct if ct
36
+ end
37
+ file.public = true
38
+ file.save
39
+ end
40
+
41
+ def delete(key)
42
+ if file = self[key]
43
+ file.destroy
44
+ end
45
+ end
46
+
47
+ def modified?(other_file)
48
+ other_file.etag != self[other_file.key].etag
49
+ end
50
+
51
+ def inspect
52
+ "#{self.class.name}: #{@bucket.key} (#{keys.size} files, #{size} bytes)"
53
+ end
54
+
55
+ def size
56
+ @current_files.values.inject(0) { |sum,file| sum + file.content_length }
57
+ end
58
+
59
+ def content_type_for_key(key)
60
+ types = MIME::Types.type_for(File.extname(key))
61
+ types.empty? ? nil : types.first.to_s
62
+ end
63
+
64
+ protected
65
+ def find_bucket(bucket_name)
66
+ @bucket = @connection.directories.get(bucket_name)
67
+ raise "Bucket not found #{bucket_name}" unless @bucket
68
+ end
69
+
70
+ def read_current_files
71
+ @current_files = @bucket.files.inject({}) do |hsh, file|
72
+ hsh[file.key] = file
73
+ hsh
74
+ end
75
+ @keys = Set.new(@current_files.keys)
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,13 @@
1
+ require 'digest'
2
+ require 'digest/md5'
3
+
4
+ module Cynq
5
+ module LocalFileExtension
6
+ def etag
7
+ Digest::MD5.file(path).to_s
8
+ end
9
+ end
10
+ end
11
+
12
+ require 'fog/local/models/storage/file'
13
+ Fog::Storage::Local::File.send(:include, Cynq::LocalFileExtension)
data/lib/cynq/local.rb ADDED
@@ -0,0 +1,25 @@
1
+ require 'cynq/directory'
2
+
3
+ module Cynq
4
+ class Local < Directory
5
+
6
+ def initialize(bucket_name)
7
+ # We expect a directory for a Local storage.
8
+ # However, we have to use the root of that
9
+ # directory as the 'root', and then the name
10
+ # of that directory as the bucket.
11
+ bucket_name = File.expand_path(bucket_name)
12
+ @local_root = File.dirname bucket_name
13
+ super(File.basename bucket_name)
14
+ require 'cynq/ext/fog'
15
+ end
16
+
17
+ protected
18
+ def establish_connection
19
+ @connection = Fog::Storage.new({
20
+ :provider => 'Local',
21
+ :local_root => @local_root })
22
+ end
23
+
24
+ end
25
+ end
@@ -0,0 +1,28 @@
1
+ require 'cynq/directory'
2
+
3
+ module Cynq
4
+ class Remote < Directory
5
+
6
+ protected
7
+ def establish_connection
8
+ key, secret = ENV['AWS_ACCESS_KEY_ID'], ENV['AWS_SECRET_ACCESS_KEY']
9
+
10
+ unless key && secret
11
+ $stderr.puts %Q{
12
+ AWS Keys are required to be in your environment.
13
+ Please set the following, to the appropriate values...
14
+ AWS_ACCESS_KEY_ID
15
+ AWS_SECRET_ACCESS_KEY
16
+ }
17
+ raise "Misconfigured AWS"
18
+ end
19
+
20
+ @connection = Fog::Storage.new({
21
+ :provider => 'AWS',
22
+ :aws_access_key_id => key,
23
+ :aws_secret_access_key => secret
24
+ })
25
+ end
26
+
27
+ end
28
+ end
@@ -0,0 +1,3 @@
1
+ module Cynq
2
+ VERSION = "0.0.2"
3
+ end
metadata ADDED
@@ -0,0 +1,83 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cynq
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Darren Boyd
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-06-22 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: fog
16
+ requirement: &70107579317080 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '1.1'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70107579317080
25
+ - !ruby/object:Gem::Dependency
26
+ name: colorize
27
+ requirement: &70107579316560 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: '0.5'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70107579316560
36
+ description: Easy synchronization of local files to cloud based storage.
37
+ email:
38
+ - dboyd@realgravity.com
39
+ executables:
40
+ - cynq
41
+ extensions: []
42
+ extra_rdoc_files: []
43
+ files:
44
+ - .gitignore
45
+ - Gemfile
46
+ - LICENSE
47
+ - README.md
48
+ - Rakefile
49
+ - bin/cynq
50
+ - cynq.gemspec
51
+ - lib/cynq.rb
52
+ - lib/cynq/command.rb
53
+ - lib/cynq/directory.rb
54
+ - lib/cynq/ext/fog.rb
55
+ - lib/cynq/local.rb
56
+ - lib/cynq/remote.rb
57
+ - lib/cynq/version.rb
58
+ homepage: https://github.com/darrenboyd/cynq
59
+ licenses: []
60
+ post_install_message:
61
+ rdoc_options: []
62
+ require_paths:
63
+ - lib
64
+ required_ruby_version: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ required_rubygems_version: !ruby/object:Gem::Requirement
71
+ none: false
72
+ requirements:
73
+ - - ! '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ requirements: []
77
+ rubyforge_project:
78
+ rubygems_version: 1.8.17
79
+ signing_key:
80
+ specification_version: 3
81
+ summary: Copy files to the cloud.
82
+ test_files: []
83
+ has_rdoc: