cloud_door 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.
Files changed (44) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +23 -0
  3. data/.travis.yml +4 -0
  4. data/Gemfile +4 -0
  5. data/Guardfile +7 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +204 -0
  8. data/Rakefile +11 -0
  9. data/bin/dropbox +133 -0
  10. data/bin/onedrive +133 -0
  11. data/cloud_door.gemspec +38 -0
  12. data/cloud_door_config.yml +12 -0
  13. data/data/.gitkeep +0 -0
  14. data/data/testlist +0 -0
  15. data/lib/cloud_door.rb +114 -0
  16. data/lib/cloud_door/account.rb +27 -0
  17. data/lib/cloud_door/cloud_storage.rb +294 -0
  18. data/lib/cloud_door/cloud_yaml.rb +45 -0
  19. data/lib/cloud_door/config.rb +61 -0
  20. data/lib/cloud_door/console.rb +334 -0
  21. data/lib/cloud_door/dropbox.rb +166 -0
  22. data/lib/cloud_door/exceptions.rb +153 -0
  23. data/lib/cloud_door/file_list.rb +164 -0
  24. data/lib/cloud_door/onedrive.rb +180 -0
  25. data/lib/cloud_door/onedrive_api.rb +169 -0
  26. data/lib/cloud_door/token.rb +67 -0
  27. data/lib/cloud_door/version.rb +3 -0
  28. data/log/.gitkeep +0 -0
  29. data/spec/cloud_door/account_spec.rb +96 -0
  30. data/spec/cloud_door/cloud_storage_spec.rb +10 -0
  31. data/spec/cloud_door/cloud_yaml_spec.rb +32 -0
  32. data/spec/cloud_door/config_spec.rb +95 -0
  33. data/spec/cloud_door/console_spec.rb +633 -0
  34. data/spec/cloud_door/dropbox_spec.rb +625 -0
  35. data/spec/cloud_door/file_list_spec.rb +451 -0
  36. data/spec/cloud_door/onedrive_api_spec.rb +256 -0
  37. data/spec/cloud_door/onedrive_spec.rb +652 -0
  38. data/spec/cloud_door/token_spec.rb +81 -0
  39. data/spec/fabricators/account_fabricator.rb +5 -0
  40. data/spec/fabricators/cloud_yaml_fabricator.rb +5 -0
  41. data/spec/fabricators/config_fabrication.rb +5 -0
  42. data/spec/fabricators/token_fabricator.rb +10 -0
  43. data/spec/spec_helper.rb +55 -0
  44. metadata +380 -0
@@ -0,0 +1,169 @@
1
+ require 'logger'
2
+ require 'open-uri'
3
+ require 'rest_client'
4
+
5
+ module CloudDoor
6
+ class OneDriveApi
7
+ attr_accessor :access_token
8
+
9
+ # domain for auth
10
+ AUTH_BASE = 'https://login.live.com/'
11
+ # URL for auth
12
+ AUTH_FORMAT = AUTH_BASE +
13
+ 'oauth20_authorize.srf?client_id=%s&scope=%s&response_type=code&redirect_uri=%s'
14
+ # URL for get token
15
+ TOKEN_URL = AUTH_BASE + 'oauth20_token.srf'
16
+ # domain for action
17
+ ACTION_BASE = 'https://apis.live.net/v5.0/'
18
+ # URL for get user info
19
+ USER_FORMAT = ACTION_BASE + 'me?access_token=%s'
20
+ # URL for get directory
21
+ DIR_FORMAT = ACTION_BASE + '%s/files?access_token=%s'
22
+ # URL for get file info
23
+ FILE_FORMAT = ACTION_BASE + '%s?access_token=%s'
24
+ # URL for download file
25
+ DOWNLOAD_FORMAT = ACTION_BASE + '%s/content?suppress_redirects=true&access_token=%s'
26
+ # URL for upload file
27
+ UPLOAD_FORMAT = ACTION_BASE + '%s/files?access_token=%s'
28
+ # URL for delete file
29
+ DELETE_FORMAT = ACTION_BASE + '%s?access_token=%s'
30
+ # URL for make directory
31
+ MKDIR_FORMAT = ACTION_BASE + '%s'
32
+ # update scope
33
+ UPDATE_SCOPE = 'wl.skydrive_update,wl.offline_access'
34
+ # log_file
35
+ LOG_FILE = './log/request.log'
36
+
37
+ def initialize(access_token)
38
+ @access_token = access_token
39
+ end
40
+
41
+ def request_get_token(code, client_id, client_secret, redirect_url)
42
+ post_body = {
43
+ client_id: client_id,
44
+ client_secret: client_secret,
45
+ redirect_uri: redirect_url,
46
+ code: code,
47
+ grant_type: 'authorization_code'
48
+ }
49
+ header = {content_type: 'application/x-www-form-urlencoded'}
50
+ send_request(:post, TOKEN_URL, post_body, header)
51
+ end
52
+
53
+ def request_refresh_token(refresh_token, client_id, client_secret, redirect_url)
54
+ post_body = {
55
+ client_id: client_id,
56
+ client_secret: client_secret,
57
+ redirect_uri: redirect_url,
58
+ grant_type: 'refresh_token',
59
+ refresh_token: refresh_token
60
+ }
61
+ header = {content_type: 'application/x-www-form-urlencoded'}
62
+ send_request(:post, TOKEN_URL, post_body, header)
63
+ end
64
+
65
+ def request_user
66
+ url = USER_FORMAT % @access_token
67
+ send_request(:get, url)
68
+ end
69
+
70
+ def request_dir(file_id)
71
+ url = DIR_FORMAT % [file_id, @access_token]
72
+ send_request(:get, url)
73
+ end
74
+
75
+ def request_file(file_id)
76
+ url = FILE_FORMAT % [file_id, @access_token]
77
+ send_request(:get, url)
78
+ end
79
+
80
+ def request_download(file_id)
81
+ url = DOWNLOAD_FORMAT % [file_id, @access_token]
82
+ info = send_request(:get, url)
83
+ key = 'location'
84
+ raise NoDataException if info.nil? || !info.is_a?(Hash) || !info.key?(key)
85
+ file_url = info[key]
86
+ open(file_url).read
87
+ end
88
+
89
+ def request_upload(file_path, parent_id)
90
+ url = UPLOAD_FORMAT % [parent_id, @access_token]
91
+ send_request(:post_file, url, File.new(file_path, 'rb'))
92
+ end
93
+
94
+ def request_delete(file_id)
95
+ url = DELETE_FORMAT % [file_id, @access_token]
96
+ send_request(:delete, url)
97
+ end
98
+
99
+ def request_mkdir(name, parent_id)
100
+ url = MKDIR_FORMAT % parent_id
101
+ body = JSON('name' => name)
102
+ header = {
103
+ 'Authorization' => "Bearer #{@access_token}",
104
+ 'Content-Type' => 'application/json'
105
+ }
106
+ send_request(:post, url, body, header)
107
+ end
108
+
109
+ class << self
110
+ def make_auth_url(client_id, redirect_url)
111
+ AUTH_FORMAT % [client_id, UPDATE_SCOPE, redirect_url]
112
+ end
113
+ end
114
+
115
+ private
116
+
117
+ def send_request(method, url, body = '', header = {})
118
+ # if method == :get
119
+ # res = RestClient.get(url) do |response, request, result|
120
+ # request_log(response, request, result)
121
+ # response
122
+ # end
123
+ # elsif method == :post
124
+ # res = RestClient.post(url, body, header) do |response, request, result|
125
+ # request_log(response, request, result)
126
+ # response
127
+ # end
128
+ # elsif method == :delete
129
+ # res = RestClient.delete(url) do |response, request, result|
130
+ # request_log(response, request, result)
131
+ # response
132
+ # end
133
+ # elsif method == :post_file
134
+ # res = RestClient.post(url, :file => body) do |response, request, result|
135
+ # request_log(response, request, result)
136
+ # response
137
+ # end
138
+ # end
139
+ if method == :get
140
+ res = RestClient.get(url)
141
+ elsif method == :post
142
+ res = RestClient.post(url, body, header)
143
+ elsif method == :delete
144
+ res = RestClient.delete(url)
145
+ elsif method == :post_file
146
+ res = RestClient.post(url, file: body)
147
+ end
148
+ # raise NoDataException if res.body.nil? || res.body.empty?
149
+ return if res.body.nil? || res.body.empty?
150
+ JSON.parse(res.body)
151
+ rescue => e
152
+ if e.is_a?(RestClient::Unauthorized)
153
+ raise UnauthorizedException
154
+ elsif e.class.to_s.include?('RestClient')
155
+ raise HttpConnectionException
156
+ else
157
+ raise
158
+ end
159
+ end
160
+
161
+ def request_log(response, request, result)
162
+ logger = Logger.new(LOG_FILE)
163
+ log = "request:\n#{request.args.inspect}\n"
164
+ log << "result:\n#{result.inspect}\n"
165
+ log << "response:\n#{JSON.parse(response.body).inspect}\n"
166
+ logger.info(log)
167
+ end
168
+ end
169
+ end
@@ -0,0 +1,67 @@
1
+ module CloudDoor
2
+ class Token
3
+ attr_accessor :token_file, :token_type, :expires_in, :scope, :access_token,
4
+ :refresh_token, :user_id, :token_name
5
+ attr_reader :data_path
6
+
7
+ TOKEN_ITEMS = [
8
+ 'token_type',
9
+ 'expires_in',
10
+ 'scope',
11
+ 'access_token',
12
+ 'refresh_token',
13
+ 'user_id'
14
+ ]
15
+
16
+ def initialize(token_name, data_path, id = nil)
17
+ @token_name = token_name
18
+ @data_path = data_path
19
+ if id.nil?
20
+ @token_file = @data_path + @token_name
21
+ else
22
+ token_dir = @data_path + "#{id}"
23
+ unless File.exists?(token_dir)
24
+ Dir.mkdir(token_dir)
25
+ end
26
+ @token_file = "#{token_dir}/#{@token_name}"
27
+ end
28
+ end
29
+
30
+ def set_locate(id)
31
+ token_dir = @data_path + "#{id}"
32
+ unless File.exists?(token_dir)
33
+ Dir.mkdir(token_dir)
34
+ end
35
+ @token_file = "#{token_dir}/#{@token_name}"
36
+ end
37
+
38
+ def set_attributes(attributes)
39
+ TOKEN_ITEMS.each do |item|
40
+ instance_variable_set("@#{item}", attributes[item]) if attributes.key?(item)
41
+ end
42
+ end
43
+
44
+ def write_token
45
+ marshal = Marshal.dump(self)
46
+ open(@token_file, 'wb') { |file| file << marshal }
47
+ true
48
+ rescue
49
+ false
50
+ end
51
+
52
+ def self.load_token(token_name, data_path, id = nil)
53
+ if id.nil?
54
+ token_file = data_path + token_name
55
+ else
56
+ token_file = data_path + "#{id}/#{token_name}"
57
+ end
58
+ return nil unless File.exist?(token_file)
59
+ marshal = File.open(token_file).read
60
+ token = Marshal.load(marshal)
61
+ return nil unless token.is_a?(Token)
62
+ token
63
+ rescue
64
+ nil
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,3 @@
1
+ module CloudDoor
2
+ VERSION = "0.0.1"
3
+ end
File without changes
@@ -0,0 +1,96 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Account' do
4
+ let(:account_file) { './data/test.yml' }
5
+ describe 'isset_account?' do
6
+ subject { account.isset_account? }
7
+ let(:account) { Fabricate.build(:account, storage: 'onedrive', file: account_file) }
8
+ context 'account & password setted' do
9
+ before(:each) do
10
+ account.login_account = 'login@onedrive.com'
11
+ account.login_password = 'onedrive.com'
12
+ end
13
+ it { is_expected.to be_truthy }
14
+ end
15
+ context 'account not setted' do
16
+ before(:each) do
17
+ account.login_account = 'login@onedrive.com'
18
+ account.login_password = ''
19
+ end
20
+ it { is_expected.to be_falsey }
21
+ end
22
+ context 'password not setted' do
23
+ before(:each) do
24
+ account.login_account = ''
25
+ account.login_password = 'onedrive.com'
26
+ end
27
+ it { is_expected.to be_falsey }
28
+ end
29
+ end
30
+
31
+ describe 'load_yaml' do
32
+ before(:all) do
33
+ accounts = {
34
+ 'onedrive' => {
35
+ 'login_account' => 'login@onedrive.com',
36
+ 'login_password' => 'onedrive'
37
+ },
38
+ 'dropbox' => {
39
+ 'login_account' => 'login@dropbox.com',
40
+ 'login_password' => 'dropbox'
41
+ }
42
+ }
43
+ open('./data/test.yml', 'wb') { |file| YAML.dump(accounts, file) }
44
+ end
45
+ before(:each) { account.load_yaml }
46
+ context 'onedrive' do
47
+ let(:account) { Fabricate.build(:account, storage: 'onedrive', file: account_file) }
48
+ it { expect(account.login_account).to eq 'login@onedrive.com' }
49
+ it { expect(account.login_password).to eq 'onedrive' }
50
+ end
51
+ context 'dropbox' do
52
+ let(:account) { Fabricate.build(:account, storage: 'dropbox', file: account_file) }
53
+ it { expect(account.login_account).to eq 'login@dropbox.com' }
54
+ it { expect(account.login_password).to eq 'dropbox' }
55
+ end
56
+ after(:all) do
57
+ File.delete('./data/test.yml') if File.exist?('./data/test.yml')
58
+ end
59
+ end
60
+
61
+ describe 'update_yaml' do
62
+ before(:each) do
63
+ File.delete(account_file) if File.exist?(account_file)
64
+ account.update_yaml(update_params)
65
+ end
66
+ context 'onedrive' do
67
+ let(:account) { Fabricate.build(:account, storage: 'onedrive', file: account_file) }
68
+ let(:update_params) do
69
+ {
70
+ 'login_account' => 'login@onedrive.com',
71
+ 'login_password' => 'onedrive'
72
+ }
73
+ end
74
+ let(:load_file) { YAML.load_file(account_file)['onedrive'] }
75
+ it { expect(File.exist?(account_file)).to be_truthy }
76
+ it { expect(load_file['login_account']).to eq 'login@onedrive.com' }
77
+ it { expect(load_file['login_password']).to eq 'onedrive' }
78
+ end
79
+ context 'dropbox' do
80
+ let(:account) { Fabricate.build(:account, storage: 'dropbox', file: account_file) }
81
+ let(:update_params) do
82
+ {
83
+ 'login_account' => 'login@dropbox.com',
84
+ 'login_password' => 'dropbox'
85
+ }
86
+ end
87
+ let(:load_file) { YAML.load_file(account_file)['dropbox'] }
88
+ it { expect(File.exist?(account_file)).to be_truthy }
89
+ it { expect(load_file['login_account']).to eq 'login@dropbox.com' }
90
+ it { expect(load_file['login_password']).to eq 'dropbox' }
91
+ end
92
+ after(:each) do
93
+ File.delete(account_file) if File.exist?(account_file)
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,10 @@
1
+ require 'spec_helper'
2
+
3
+ # CloudStorage class is abstract class.
4
+ # then, test inherited subclass.
5
+ describe 'CloudStorage' do
6
+ describe 'initialize' do
7
+ subject { CloudDoor::CloudStorage.new }
8
+ it { expect { subject }.to raise_error(CloudDoor::AbstractClassException) }
9
+ end
10
+ end
@@ -0,0 +1,32 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'CloudYaml' do
4
+ describe 'load_yaml' do
5
+ subject { account.load_yaml }
6
+ account_file = './data/test.yml'
7
+ before(:all) do
8
+ accounts = {
9
+ 'onedrive' => {
10
+ 'login_account' => 'login@onedrive.com',
11
+ 'login_password' => 'onedrive'
12
+ }
13
+ }
14
+ open(account_file, 'wb') { |file| YAML.dump(accounts, file) }
15
+ end
16
+ context 'file & storage exists' do
17
+ let(:account) { Fabricate.build(:cloud_yaml, file: account_file) }
18
+ it { is_expected.to be_truthy }
19
+ end
20
+ context 'file not exists' do
21
+ let(:account) { Fabricate.build(:cloud_yaml, file: './data/example.yml') }
22
+ it { is_expected.to be_falsey }
23
+ end
24
+ context 'storage exists' do
25
+ let(:account) { Fabricate.build(:cloud_yaml, file: account_file, storage: 'example') }
26
+ it { is_expected.to be_falsey }
27
+ end
28
+ after(:all) do
29
+ File.delete(account_file) if File.exist?(account_file)
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,95 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Config' do
4
+ describe 'load_yaml' do
5
+ let(:config_file) { './data/test.yml' }
6
+ before(:all) do
7
+ configs = {
8
+ 'onedrive' => {
9
+ 'client_id' => '1234',
10
+ 'client_secret' => 'abcd',
11
+ 'redirect_url' => 'onedrive'
12
+ },
13
+ 'dropbox' => {
14
+ 'client_id' => '5678',
15
+ 'client_secret' => 'efgh',
16
+ 'redirect_url' => 'dropbox'
17
+ }
18
+ }
19
+ open('./data/test.yml', 'wb') { |file| YAML.dump(configs, file) }
20
+ end
21
+ before(:each) { config.load_yaml }
22
+ context 'onedrive' do
23
+ let(:config) { Fabricate.build(:config, storage: 'onedrive', file: config_file) }
24
+ it { expect(config.client_id).to eq '1234' }
25
+ it { expect(config.client_secret).to eq 'abcd' }
26
+ it { expect(config.redirect_url).to eq 'onedrive' }
27
+ end
28
+ context 'dropbox' do
29
+ let(:config) { Fabricate.build(:config, storage: 'dropbox', file: config_file) }
30
+ it { expect(config.client_id).to eq '5678' }
31
+ it { expect(config.client_secret).to eq 'efgh' }
32
+ it { expect(config.redirect_url).to eq 'dropbox' }
33
+ end
34
+ after(:all) do
35
+ File.delete('./data/test.yml') if File.exist?('./data/test.yml')
36
+ end
37
+ end
38
+
39
+ describe 'update_yaml' do
40
+ let(:config_file) { './data/test.yml' }
41
+ before(:each) do
42
+ File.delete(config_file) if File.exist?(config_file)
43
+ account.update_yaml(update_params)
44
+ end
45
+ context 'onedrive' do
46
+ let(:account) { Fabricate.build(:config, storage: 'onedrive', file: config_file) }
47
+ let(:update_params) do
48
+ {
49
+ 'client_id' => '1234',
50
+ 'client_secret' => 'abcd',
51
+ 'redirect_url' => 'onedrive'
52
+ }
53
+ end
54
+ let(:load_file) { YAML.load_file(config_file)['onedrive'] }
55
+ it { expect(File.exist?(config_file)).to be_truthy }
56
+ it { expect(load_file['client_id']).to eq '1234' }
57
+ it { expect(load_file['client_secret']).to eq 'abcd' }
58
+ it { expect(load_file['redirect_url']).to eq 'onedrive' }
59
+ end
60
+ context 'dropbox' do
61
+ let(:account) { Fabricate.build(:config, storage: 'dropbox', file: config_file) }
62
+ let(:update_params) do
63
+ {
64
+ 'client_id' => '5678',
65
+ 'client_secret' => 'efgh',
66
+ 'redirect_url' => 'dropbox'
67
+ }
68
+ end
69
+ let(:load_file) { YAML.load_file(config_file)['dropbox'] }
70
+ it { expect(File.exist?(config_file)).to be_truthy }
71
+ it { expect(load_file['client_id']).to eq '5678' }
72
+ it { expect(load_file['client_secret']).to eq 'efgh' }
73
+ it { expect(load_file['redirect_url']).to eq 'dropbox' }
74
+ end
75
+ after(:each) do
76
+ File.delete(config_file) if File.exist?(config_file)
77
+ end
78
+ end
79
+
80
+ describe 'init?' do
81
+ subject { config.init? }
82
+ let(:config) { Fabricate.build(:config) }
83
+ context 'initialized' do
84
+ before(:each) do
85
+ config.client_id = '1234'
86
+ config.client_secret = 'abcd'
87
+ config.redirect_url = 'onedrive'
88
+ end
89
+ it { is_expected.to be_truthy }
90
+ end
91
+ context 'not initialized' do
92
+ it { is_expected.to be_falsey }
93
+ end
94
+ end
95
+ end