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,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