worochi 0.0.7 → 0.0.10
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.
- checksums.yaml +4 -4
- data/lib/worochi/agent/{sample.rb → #example.rb} +2 -14
- data/lib/worochi/agent/dropbox.rb +3 -13
- data/lib/worochi/agent/github.rb +8 -23
- data/lib/worochi/agent.rb +46 -18
- data/lib/worochi/config/#example.yml +35 -0
- data/lib/worochi/config/dropbox.yml +14 -0
- data/lib/worochi/config/github.yml +17 -0
- data/lib/worochi/config.rb +9 -84
- data/lib/worochi/configurator.rb +120 -0
- data/lib/worochi/helper/github_helper.rb +111 -0
- data/lib/worochi/helper.rb +28 -7
- data/lib/worochi/item.rb +5 -3
- data/lib/worochi/log.rb +8 -14
- data/lib/worochi/oauth.rb +69 -0
- data/lib/worochi/version.rb +1 -1
- data/lib/worochi.rb +20 -3
- data/spec/cassettes/Worochi/_push/pushes_with_agents.yml +512 -0
- data/spec/cassettes/Worochi_Agent_Dropbox/_push_item/pushes_it_chunked_if_size_exceeds_limit.yml +1049 -0
- data/spec/cassettes/Worochi_Agent_Dropbox/_push_item_chunked/raises_an_error.yml +44 -0
- data/spec/cassettes/Worochi_Agent_Dropbox/_push_items/pushes_multiple_items.yml +165 -0
- data/spec/cassettes/Worochi_Agent_Dropbox/it_should_behave_like_a_service_agent/_files/raises_error_on_invalid_path.yml +38 -0
- data/spec/cassettes/Worochi_Agent_Dropbox/it_should_behave_like_a_service_agent/_files_and_folders/shows_detailed_listing.yml +79 -0
- data/spec/cassettes/Worochi_Agent_Dropbox/it_should_behave_like_a_service_agent/_files_and_folders/shows_detailed_listing_including_the_required_fields.yml +79 -0
- data/spec/cassettes/Worochi_Agent_Github/_list/works_with_absolute_paths.yml +12 -12
- data/spec/cassettes/Worochi_Agent_Github/_repos/lists_the_repos.yml +207 -0
- data/spec/cassettes/Worochi_Agent_Github/_source_branch/retrieves_the_master_branch_correctly.yml +6 -6
- data/spec/cassettes/Worochi_Agent_Github/it_should_behave_like_a_service_agent/_files/accepts_a_different_relative_path.yml +12 -12
- data/spec/cassettes/Worochi_Agent_Github/it_should_behave_like_a_service_agent/_files/contains_file1.yml +12 -12
- data/spec/cassettes/Worochi_Agent_Github/it_should_behave_like_a_service_agent/_files/does_not_contain_folder1.yml +12 -12
- data/spec/cassettes/Worochi_Agent_Github/it_should_behave_like_a_service_agent/_files/raises_error_on_invalid_path.yml +133 -0
- data/spec/cassettes/Worochi_Agent_Github/it_should_behave_like_a_service_agent/_files_and_folders/contains_folder1_and_file1.yml +24 -24
- data/spec/cassettes/Worochi_Agent_Github/it_should_behave_like_a_service_agent/_files_and_folders/shows_detailed_listing_including_the_required_fields.yml +133 -0
- data/spec/cassettes/Worochi_Agent_Github/it_should_behave_like_a_service_agent/_folders/accepts_a_different_relative_path.yml +12 -12
- data/spec/cassettes/Worochi_Agent_Github/it_should_behave_like_a_service_agent/_folders/contains_folder1.yml +12 -12
- data/spec/cassettes/Worochi_Agent_Github/it_should_behave_like_a_service_agent/_folders/does_not_contain_file1.yml +12 -12
- data/spec/cassettes/Worochi_Agent_Github/{_push_all → modifies_the_repo/_push_all}/pushes_a_list_of_items_to_create_a_new_commit.yml +80 -80
- data/spec/cassettes/Worochi_Agent_Github/{_push_all → modifies_the_repo/_push_all}/pushes_the_file_to_the_right_place.yml +60 -60
- data/spec/cassettes/Worochi_Agent_Github/modifies_the_repo/_push_blob/pushes_the_blob_even_when_it_is_larger_than_block_size.yml +181 -0
- data/spec/cassettes/Worochi_Agent_Github/modifies_the_repo/_push_item/pushes_a_single_item_and_makes_a_commit.yml +687 -0
- data/spec/cassettes/Worochi_Agent_Github/modifies_the_repo/_stream_blob/streams_the_file_as_an_Base64_JSON_field.yml +181 -0
- data/spec/cassettes/Worochi_OAuth/_flow_end/rejects_bad_code.yml +56 -0
- data/spec/{helper.rb → spec_helper.rb} +14 -1
- data/spec/support/aws_uri_matcher.rb +1 -1
- data/spec/support/shared_exampes_for_agents.rb +13 -2
- data/spec/support/test_files.rb +4 -4
- data/spec/worochi/agent/dropbox_spec.rb +29 -3
- data/spec/worochi/agent/github_spec.rb +54 -26
- data/spec/worochi/agent_spec.rb +34 -1
- data/spec/worochi/config_spec.rb +46 -30
- data/spec/worochi/helper/github_helper_spec.rb +94 -0
- data/spec/worochi/helper_spec.rb +15 -3
- data/spec/worochi/item_spec.rb +9 -6
- data/spec/worochi/log_spec.rb +30 -0
- data/spec/worochi/oauth_spec.rb +33 -0
- data/spec/worochi_spec.rb +25 -1
- data/worochi.gemspec +5 -1
- metadata +104 -11
- data/lib/worochi/helper/github.rb +0 -100
- data/spec/worochi/helper/github_spec.rb +0 -57
data/lib/worochi/helper.rb
CHANGED
@@ -1,18 +1,34 @@
|
|
1
|
-
require 'aws-sdk' unless Worochi::Config.s3_bucket.nil?
|
2
|
-
|
3
1
|
class Worochi
|
4
2
|
# Contains any global helper methods not specific to any individual service.
|
5
3
|
module Helper
|
6
4
|
class << self
|
7
5
|
# Given an S3 path, return the full URL for the corresponding object
|
8
|
-
# determined using the AWS SDK.
|
6
|
+
# determined using the AWS SDK. AWS_SECRET_ACCESS_KEY and
|
7
|
+
# AWS_ACCESS_KEY_ID should be present in ENV. The string should be
|
8
|
+
# formatted as: `s3:(bucket_name:)path/to/file`.
|
9
9
|
#
|
10
|
-
# @param path [String]
|
11
|
-
# @return [URI::
|
10
|
+
# @param path [String] S3 path
|
11
|
+
# @return [URI::HTTPS] URI of the file on S3
|
12
|
+
# @example Pre-configured bucket name
|
13
|
+
# Worochi::Config.s3_bucket = 'worochi'
|
14
|
+
# Worochi::Helper.s3_url('s3:test/path')
|
15
|
+
# # => #<URI::HTTPS URL:https://worochi.s3.amazonaws.com/test/path?AWSAccessKeyId=...>
|
16
|
+
# @example Custom bucket name
|
17
|
+
# Worochi::Helper.s3_url('s3:bucket-name:a/b')
|
18
|
+
# # => #<URI::HTTPS URL:https://bucket-name.s3.amazonaws.com/a/b?AWSAccessKeyId=...>
|
19
|
+
# @example Invalid syntax
|
20
|
+
# Worochi::Helper.s3_url('www.a.com/b.txt')
|
21
|
+
# # => Worochi::Error
|
12
22
|
def s3_url(path)
|
13
|
-
raise Error, 'S3
|
23
|
+
raise Error, 'Invalid S3 path' unless is_s3_path?(path)
|
14
24
|
path = path.sub(s3_prefix_re, '')
|
15
|
-
|
25
|
+
if match = /^(.*)\:/.match(path)
|
26
|
+
bucket = match[1]
|
27
|
+
path = path.sub(/^(.*)\:/, '')
|
28
|
+
end
|
29
|
+
bucket ||= Config.s3_bucket
|
30
|
+
raise Error, 'S3 bucket name is not defined' if bucket.nil?
|
31
|
+
AWS::S3.new.buckets[bucket].objects[path].url_for(:read)
|
16
32
|
end
|
17
33
|
|
18
34
|
# Check if a given path is an S3 path.
|
@@ -33,4 +49,9 @@ class Worochi
|
|
33
49
|
end
|
34
50
|
end
|
35
51
|
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# Load all helpers
|
55
|
+
Dir[File.join(File.dirname(__FILE__), 'helper/[^#]*.rb')].each do |file|
|
56
|
+
require 'worochi/helper/' + File.basename(file, '.rb')
|
36
57
|
end
|
data/lib/worochi/item.rb
CHANGED
@@ -102,8 +102,10 @@ class Worochi
|
|
102
102
|
if File.file?(source)
|
103
103
|
retrieve_local(source)
|
104
104
|
else
|
105
|
-
|
106
|
-
|
105
|
+
if Config.s3_enabled? && Helper.is_s3_path?(source)
|
106
|
+
source = Helper.s3_url(source)
|
107
|
+
end
|
108
|
+
retrieve_remote(source)
|
107
109
|
end
|
108
110
|
end
|
109
111
|
|
@@ -118,7 +120,7 @@ class Worochi
|
|
118
120
|
file
|
119
121
|
end
|
120
122
|
|
121
|
-
# Downloads a remote file using
|
123
|
+
# Downloads a remote file using `HTTP::Get`.
|
122
124
|
#
|
123
125
|
# @param file_url [String, URI] the URL of the file
|
124
126
|
# @return [Tempfile] the downloaded file
|
data/lib/worochi/log.rb
CHANGED
@@ -13,8 +13,10 @@ class Worochi
|
|
13
13
|
}
|
14
14
|
class << self
|
15
15
|
# Initializes the logging system.
|
16
|
-
|
17
|
-
|
16
|
+
#
|
17
|
+
# @param logdev [IO] target device to log to
|
18
|
+
def init(logdev=nil)
|
19
|
+
@logger = Logger.new(logdev || Config.logdev)
|
18
20
|
@logger.formatter = proc do |severity, datetime, progname, msg|
|
19
21
|
"[\033[#{SEVERITY_COLOR[severity]}m#{severity}\033[0m]: #{msg}\n"
|
20
22
|
end
|
@@ -22,30 +24,22 @@ class Worochi
|
|
22
24
|
|
23
25
|
# Prints DEBUG messages
|
24
26
|
def debug(message)
|
25
|
-
|
26
|
-
init_log if @logger.nil?
|
27
|
-
@logger.debug message
|
27
|
+
@logger.debug message unless Worochi::Config.silent?
|
28
28
|
end
|
29
29
|
|
30
30
|
# Prints WARN messages
|
31
31
|
def warn(message)
|
32
|
-
|
33
|
-
init_log if @logger.nil?
|
34
|
-
@logger.warn message
|
32
|
+
@logger.warn message unless Worochi::Config.silent?
|
35
33
|
end
|
36
34
|
|
37
35
|
# Prints INFO messages
|
38
36
|
def info(message)
|
39
|
-
|
40
|
-
init_log if @logger.nil?
|
41
|
-
@logger.info message
|
37
|
+
@logger.info message unless Worochi::Config.silent?
|
42
38
|
end
|
43
39
|
|
44
40
|
# Prints ERROR messages
|
45
41
|
def error(message)
|
46
|
-
|
47
|
-
init_log if @logger.nil?
|
48
|
-
@logger.error message
|
42
|
+
@logger.error message unless Worochi::Config.silent?
|
49
43
|
end
|
50
44
|
end
|
51
45
|
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'oauth2'
|
2
|
+
|
3
|
+
class Worochi
|
4
|
+
# Implements OAuth2 authorization code flow for obtaining user tokens.
|
5
|
+
class OAuth
|
6
|
+
# OAuth2 options.
|
7
|
+
# @return [Hashie::Mash]
|
8
|
+
attr_accessor :options
|
9
|
+
|
10
|
+
# The OAuth2 client
|
11
|
+
# @return [OAuth2::Client]
|
12
|
+
attr_reader :client
|
13
|
+
|
14
|
+
# @param service [Symbol] service name
|
15
|
+
# @param redirect_url [String] callback URL if required
|
16
|
+
def initialize(service, redirect_uri=nil)
|
17
|
+
@options = Worochi::Config.service_opts(service).oauth
|
18
|
+
options.service = service
|
19
|
+
options.redirect_uri = redirect_uri
|
20
|
+
opts = { site: options.site }
|
21
|
+
opts[:authorize_url] = options.authorize_url if options.authorize_url
|
22
|
+
opts[:token_url] = options.token_url if options.token_url
|
23
|
+
@client = OAuth2::Client.new(id, secret, opts)
|
24
|
+
end
|
25
|
+
|
26
|
+
# Returns the URL to start the authorization flow.
|
27
|
+
#
|
28
|
+
# @param state [String] optional security verification state
|
29
|
+
# @return [String] URL to begin flow
|
30
|
+
def flow_start(state=nil)
|
31
|
+
client.site = options.site
|
32
|
+
opts = { scope: scope }
|
33
|
+
opts[:state] = state if state
|
34
|
+
opts[:redirect_uri] = options.redirect_uri if options.redirect_uri
|
35
|
+
client.auth_code.authorize_url(opts)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Retrieves the token using the temporary authorization code.
|
39
|
+
#
|
40
|
+
# @param code [String] authorization code from the first part
|
41
|
+
# @return [OAuth2::AccessToken] OAuth2 token
|
42
|
+
def flow_end(code)
|
43
|
+
client.site = options.token_site || options.site
|
44
|
+
opts = {}
|
45
|
+
opts[:redirect_uri] = options.redirect_uri if options.redirect_uri
|
46
|
+
client.auth_code.get_token(code, opts)
|
47
|
+
end
|
48
|
+
|
49
|
+
alias_method :get_token, :flow_end
|
50
|
+
|
51
|
+
private
|
52
|
+
# @return [String] scope
|
53
|
+
def scope
|
54
|
+
options.scope || ''
|
55
|
+
end
|
56
|
+
|
57
|
+
# @return [String] environmental variable for client ID
|
58
|
+
def id
|
59
|
+
var = options.id_env || options.service.to_s.upcase + '_ID'
|
60
|
+
ENV[var]
|
61
|
+
end
|
62
|
+
|
63
|
+
# @return [String] environmental variable for client secret
|
64
|
+
def secret
|
65
|
+
var = options.secret_env || options.service.to_s.upcase + '_SECRET'
|
66
|
+
ENV[var]
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
data/lib/worochi/version.rb
CHANGED
data/lib/worochi.rb
CHANGED
@@ -1,9 +1,12 @@
|
|
1
|
+
require 'hashie'
|
2
|
+
require 'aws-sdk'
|
1
3
|
require 'worochi/config'
|
2
4
|
require 'worochi/error'
|
3
5
|
require 'worochi/log'
|
4
|
-
require 'worochi/helper'
|
5
6
|
require 'worochi/item'
|
6
7
|
require 'worochi/agent'
|
8
|
+
require 'worochi/oauth'
|
9
|
+
require 'worochi/helper'
|
7
10
|
|
8
11
|
# The main class for the gem. This and the {Agent} class are the main
|
9
12
|
# endpoints for interacting with the remote services.
|
@@ -16,6 +19,15 @@ class Worochi
|
|
16
19
|
# @return [Array]
|
17
20
|
attr_reader :agents
|
18
21
|
|
22
|
+
# Initialize configurations and logging.
|
23
|
+
#
|
24
|
+
# @return [nil]
|
25
|
+
def init
|
26
|
+
Config.load_yaml
|
27
|
+
Log.init
|
28
|
+
reset
|
29
|
+
end
|
30
|
+
|
19
31
|
# Creates a new {Worochi::Agent} and adds it to the list of agents
|
20
32
|
# listening to {Worochi.push} requests.
|
21
33
|
#
|
@@ -113,9 +125,14 @@ class Worochi
|
|
113
125
|
# @see Item.open
|
114
126
|
# @see Agent#push
|
115
127
|
def push(origin, opts={})
|
116
|
-
|
128
|
+
if @agents.empty?
|
129
|
+
Log.warn 'No push targets specified'
|
130
|
+
return false
|
131
|
+
end
|
117
132
|
@agents.each { |agent| agent.push(origin, opts) }
|
118
133
|
true
|
119
134
|
end
|
120
135
|
end
|
121
|
-
end
|
136
|
+
end
|
137
|
+
|
138
|
+
Worochi.init
|