cloud_door 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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,153 @@
1
+ module CloudDoor
2
+ class FileNameEmptyException < StandardError
3
+ def message
4
+ 'filename is not set.'
5
+ end
6
+
7
+ def to_s
8
+ message
9
+ end
10
+ end
11
+
12
+ class DirectoryNameEmptyException < StandardError
13
+ def message
14
+ 'directory name is not set.'
15
+ end
16
+
17
+ def to_s
18
+ message
19
+ end
20
+ end
21
+
22
+ class SetIDException < StandardError
23
+ def message
24
+ 'not found input file name.'
25
+ end
26
+
27
+ def to_s
28
+ message
29
+ end
30
+ end
31
+
32
+ class NotFileException < StandardError
33
+ def message
34
+ 'target is not file.'
35
+ end
36
+
37
+ def to_s
38
+ message
39
+ end
40
+ end
41
+
42
+ class NotDirectoryException < StandardError
43
+ def message
44
+ 'target is not directory.'
45
+ end
46
+
47
+ def to_s
48
+ message
49
+ end
50
+ end
51
+
52
+ class NoDataException < StandardError
53
+ def message
54
+ 'not found request data.'
55
+ end
56
+
57
+ def to_s
58
+ message
59
+ end
60
+ end
61
+
62
+ class TokenClassException < StandardError
63
+ def message
64
+ 'token is not Token Class.'
65
+ end
66
+
67
+ def to_s
68
+ message
69
+ end
70
+ end
71
+
72
+ class FileNotExistsException < StandardError
73
+ end
74
+
75
+ class RequestMethodNotFoundException < StandardError
76
+ end
77
+
78
+ class RequestPropertyNotFoundException < StandardError
79
+ end
80
+
81
+ class AccessCodeNotIncludeException < StandardError
82
+ def message
83
+ 'access code not include in redirect url.'
84
+ end
85
+
86
+ def to_s
87
+ message
88
+ end
89
+ end
90
+
91
+ class UnauthorizedException < StandardError
92
+ def message
93
+ 'authentication failed.'
94
+ end
95
+
96
+ def to_s
97
+ message
98
+ end
99
+ end
100
+
101
+ class HttpConnectionException < StandardError
102
+ def message
103
+ 'access to storage failed.'
104
+ end
105
+
106
+ def to_s
107
+ message
108
+ end
109
+ end
110
+
111
+ class UploadFailedException < StandardError
112
+ def message
113
+ 'upload file to storage failed.'
114
+ end
115
+
116
+ def to_s
117
+ message
118
+ end
119
+ end
120
+
121
+ class DeleteFailedException < StandardError
122
+ def message
123
+ 'delete file from storage failed.'
124
+ end
125
+
126
+ def to_s
127
+ message
128
+ end
129
+ end
130
+
131
+ class MkdirFailedException < StandardError
132
+ def message
133
+ 'make directory on storage failed.'
134
+ end
135
+
136
+ def to_s
137
+ message
138
+ end
139
+ end
140
+
141
+ class AbstractClassException < StandardError
142
+ def message
143
+ 'this class is abstract class. please make inherited subclass.'
144
+ end
145
+
146
+ def to_s
147
+ message
148
+ end
149
+ end
150
+
151
+ class AbstractMethodException < StandardError
152
+ end
153
+ end
@@ -0,0 +1,164 @@
1
+ module CloudDoor
2
+ class FileList
3
+ attr_accessor :list_file, :list_name
4
+ attr_reader :list
5
+
6
+ def initialize(list_name, data_path, id = nil)
7
+ @list_name = list_name
8
+ @data_path = data_path
9
+ if (id.nil?)
10
+ @list_file = @data_path + @list_name
11
+ else
12
+ list_dir = @data_path + "#{id}"
13
+ unless File.exists?(list_dir)
14
+ Dir.mkdir(list_dir)
15
+ end
16
+ @list_file = "#{list_dir}/#{@list_name}"
17
+ end
18
+ @list = nil
19
+ end
20
+
21
+ def set_locate(id)
22
+ list_dir = @data_path + "#{id}"
23
+ unless File.exists?(list_dir)
24
+ Dir.mkdir(list_dir)
25
+ end
26
+ @list_file = "#{list_dir}/#{@list_name}"
27
+ end
28
+
29
+ def load_list
30
+ list = []
31
+ if File.exist?(@list_file)
32
+ marshal = File.open(@list_file).read
33
+ list = Marshal.load(marshal)
34
+ return false unless list.is_a?(Array)
35
+ end
36
+ @list = list
37
+ true
38
+ end
39
+
40
+ def write_file_list(items, file_id = '', file_name = '')
41
+ return false if load_list == false
42
+ if @list.empty?
43
+ add_list_top(items)
44
+ elsif file_name =~ CloudStorage::PARENT_DIR_PAT
45
+ back = file_name.scan(CloudStorage::PARENT_DIR_PAT).size + 1
46
+ remove_list(back)
47
+ else
48
+ if file_name.nil? || file_name.empty?
49
+ update_list(items)
50
+ else
51
+ add_list(items, file_id, file_name)
52
+ end
53
+ end
54
+ end
55
+
56
+ def add_list_top(items)
57
+ return false if items.nil? || !items.is_a?(Hash)
58
+ @list = []
59
+ @list << {'id' => 'top', 'name' => 'top', 'items' => items}
60
+ write_file
61
+ end
62
+
63
+ def add_list(items, file_id, file_name)
64
+ return false if items.nil? || !items.is_a?(Hash)
65
+ return false if file_id.nil? || file_id.empty?
66
+ return false if file_name.nil? || file_name.empty?
67
+ return false if load_list == false
68
+ @list << {'id' => file_id, 'name' => file_name, 'items' => items}
69
+ write_file
70
+ end
71
+
72
+ def update_list(items)
73
+ return false if items.nil? || !items.is_a?(Hash)
74
+ return false if load_list == false
75
+ last_node = @list[-1]
76
+ @list[-1] = {'id' => last_node['id'], 'name' => last_node['name'], 'items' => items}
77
+ write_file
78
+ end
79
+
80
+ def remove_list(back)
81
+ return false if load_list == false
82
+ size = @list.size
83
+ return false if back > size
84
+ last = size - back
85
+ @list = @list[0..last]
86
+ write_file
87
+ end
88
+
89
+ def delete_file
90
+ File.delete(@list_file) if File.exist?(@list_file)
91
+ true
92
+ rescue
93
+ false
94
+ end
95
+
96
+ def pull_parent_id
97
+ convert_name_to_id('current')
98
+ end
99
+
100
+ def pull_current_dir
101
+ return false if load_list == false
102
+ return '/top' if @list.size < 2
103
+ files = []
104
+ @list.each { |part| files << part['name'] unless part['name'].nil? }
105
+ '/' + files.join('/')
106
+ end
107
+
108
+ def pull_file_properties(file_name)
109
+ if @list.nil?
110
+ return false if load_list == false
111
+ end
112
+ return false if @list.empty?
113
+ items = @list.last['items']
114
+ return false if items.empty? || !items.key?(file_name)
115
+ items[file_name]
116
+ end
117
+
118
+ def convert_name_to_id(mode, file_name = '')
119
+ return false if load_list == false
120
+ return false unless %w(current parent target).include?(mode)
121
+ send("convert_#{mode}_id", file_name)
122
+ end
123
+
124
+ def top?(file_name)
125
+ back = (file_name.scan(CloudStorage::PARENT_DIR_PAT).size) + 1
126
+ @list.count < back
127
+ end
128
+
129
+ private
130
+
131
+ def write_file
132
+ marshal = Marshal.dump(@list)
133
+ open(@list_file, 'wb') { |file| file << marshal }
134
+ true
135
+ rescue
136
+ false
137
+ end
138
+
139
+ def convert_current_id(*)
140
+ if @list.count < 2
141
+ nil
142
+ else
143
+ @list.last['id']
144
+ end
145
+ end
146
+
147
+ def convert_parent_id(file_name)
148
+ back = (file_name.scan(CloudStorage::PARENT_DIR_PAT).size) + 1
149
+ return false if @list.size < back
150
+ last = @list.size - back
151
+ if last == 0
152
+ nil
153
+ else
154
+ @list[list.size - back]['id']
155
+ end
156
+ end
157
+
158
+ def convert_target_id(file_name)
159
+ properties = pull_file_properties(file_name)
160
+ return false unless properties
161
+ properties['id']
162
+ end
163
+ end
164
+ end
@@ -0,0 +1,180 @@
1
+ require 'cloud_door/cloud_storage'
2
+ require 'cloud_door/onedrive_api'
3
+
4
+ module CloudDoor
5
+ class OneDrive < CloudStorage
6
+ attr_accessor :token, :file_list, :file_id, :file_name,
7
+ :up_file_name, :mkdir_name, :parent_id
8
+ attr_reader :config, :account
9
+
10
+ # user root file_id
11
+ ROOT_ID = 'me/skydrive'
12
+ # onedrive login site components
13
+ LOGIN_COMPONENTS = {
14
+ 'account_text_name' => 'login',
15
+ 'password_text_name' => 'passwd',
16
+ 'signin_button_id' => 'idSIButton9',
17
+ 'accept_button_id' => 'idBtn_Accept'
18
+ }
19
+ TIME_PROPERTY_PAT = /_time$/
20
+ STORAGE_NAME = 'OneDrive'
21
+
22
+ def initialize(session_id = nil)
23
+ @config = Config.new('onedrive')
24
+ @account = Account.new('onedrive', @config.data_path)
25
+ @token = Token.new('onedrive_token', @config.data_path, session_id)
26
+ @file_list = FileList.new('onedrive_list', @config.data_path, session_id)
27
+ @file_id = nil
28
+ @root_id = ROOT_ID
29
+ @storage_name = STORAGE_NAME
30
+ @session_id = session_id
31
+ end
32
+
33
+ def load_token
34
+ token_file = File.basename(@token.token_file)
35
+ @token = Token.load_token(token_file, @config.data_path, @session_id)
36
+ end
37
+
38
+ def refresh_token
39
+ raise TokenClassException unless @token.is_a?(Token)
40
+ info = request_refresh_token
41
+ raise NoDataException if info.nil?
42
+ @token.set_attributes(info)
43
+ @token.write_token
44
+ rescue => e
45
+ handle_exception(e)
46
+ end
47
+
48
+ def login(login_account, login_password)
49
+ @account.login_account = login_account
50
+ @account.login_password = login_password
51
+ url = login_browser
52
+ info = request_get_token(url)
53
+ raise NoDataException if info.nil?
54
+ @session_id = reset_token(info)
55
+ items = pull_files
56
+ @file_list.delete_file
57
+ @file_list.write_file_list(items)
58
+ if @config.session_use?
59
+ @session_id
60
+ else
61
+ true
62
+ end
63
+ rescue => e
64
+ handle_exception(e)
65
+ end
66
+
67
+ private
68
+
69
+ def request_get_token(url)
70
+ query = URI.parse(url).query
71
+ raise AccessCodeNotIncludeException if query.nil?
72
+ params = CGI.parse(query)
73
+ raise AccessCodeNotIncludeException unless params.key?('code')
74
+ code = params['code'][0]
75
+ api = OneDriveApi.new(@token.access_token)
76
+ api.request_get_token(
77
+ code,
78
+ @config.client_id,
79
+ @config.client_secret,
80
+ @config.redirect_url
81
+ )
82
+ end
83
+
84
+ def request_refresh_token
85
+ api = OneDriveApi.new(@token.access_token)
86
+ api.request_refresh_token(
87
+ @token.refresh_token,
88
+ @config.client_id,
89
+ @config.client_secret,
90
+ @config.redirect_url
91
+ )
92
+ end
93
+
94
+ def request_user
95
+ api = OneDriveApi.new(@token.access_token)
96
+ api.request_user
97
+ end
98
+
99
+ def request_dir
100
+ file_id = @parent_id || @file_id || ROOT_ID
101
+ api = OneDriveApi.new(@token.access_token)
102
+ api.request_dir(file_id)
103
+ end
104
+
105
+ def request_file
106
+ api = OneDriveApi.new(@token.access_token)
107
+ api.request_file(@file_id)
108
+ end
109
+
110
+ def request_download
111
+ api = OneDriveApi.new(@token.access_token)
112
+ contens = api.request_download(@file_id)
113
+ open("#{@file_name}", 'wb') { |file| file << contens }
114
+ end
115
+
116
+ def request_upload(file_path)
117
+ api = OneDriveApi.new(@token.access_token)
118
+ api.request_upload(file_path, @parent_id)
119
+ end
120
+
121
+ def request_delete
122
+ api = OneDriveApi.new(@token.access_token)
123
+ api.request_delete(@file_id)
124
+ end
125
+
126
+ def request_mkdir
127
+ parent_id = @parent_id || ROOT_ID
128
+ api = OneDriveApi.new(@token.access_token)
129
+ api.request_mkdir(@mkdir_name, parent_id)
130
+ end
131
+
132
+ def pull_files
133
+ dir = pick_cloud_info('request_dir', 'data')
134
+ return {} if dir.nil? || !dir.is_a?(Array) || dir.count == 0
135
+ items = {}
136
+ dir.each do |item|
137
+ type = get_type_from_id(item['id'])
138
+ items[item['name']] = {'id' => item['id'], 'type' => type}
139
+ end
140
+ items
141
+ end
142
+
143
+ def format_property(info)
144
+ items = {}
145
+ info.each do |key, val|
146
+ if key =~ TIME_PROPERTY_PAT
147
+ items[key] = DateTime.parse(info[key]).strftime('%Y-%m-%d %H:%M:%S')
148
+ else
149
+ items[key] = info[key]
150
+ end
151
+ end
152
+ items
153
+ end
154
+
155
+ def get_type_from_id(file_id)
156
+ file_id.split('.')[0]
157
+ end
158
+
159
+ def login_browser
160
+ auth_url = OneDriveApi.make_auth_url(@config.client_id, @config.redirect_url)
161
+ browser = Watir::Browser.new :phantomjs
162
+ # input account
163
+ browser.goto(auth_url)
164
+ browser.wait
165
+ browser.text_field(:name, LOGIN_COMPONENTS['account_text_name']).set @account.login_account
166
+ browser.text_field(:name, LOGIN_COMPONENTS['password_text_name']).set @account.login_password
167
+ browser.button(:id, LOGIN_COMPONENTS['signin_button_id']).click
168
+ browser.wait
169
+ # allow access
170
+ browser.button(:id, LOGIN_COMPONENTS['accept_button_id']).click
171
+ browser.wait
172
+ # get redirect url
173
+ url = browser.url
174
+ browser.close
175
+ url
176
+ rescue => e
177
+ handle_exception(e)
178
+ end
179
+ end
180
+ end