dropbox 0.0.10 → 1.0.0

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.
@@ -1,213 +0,0 @@
1
- require 'rubygems'
2
- require 'nokogiri'
3
- require 'mechanize'
4
-
5
- Mechanize.html_parser = Nokogiri::HTML
6
-
7
- # TODO: Tests (mock out expected DropBox output)
8
- # TODO: Directory object, File object
9
-
10
- class DropBox
11
- #before_filter :login_filter, :except => [:login]
12
-
13
- def initialize(email, password, folder_namespace = "")
14
- @email = email
15
- @password = password
16
- @agent = Mechanize.new
17
- @folder_namespace = folder_namespace.gsub(/^\//,"")
18
- @logged_in = false
19
- end
20
-
21
- def agent
22
- @agent
23
- end
24
-
25
- # Lists all the files and folders in a given directory
26
- def index(path = "/")
27
- login_filter
28
- path = namespace_path(path)
29
-
30
- list = @agent.post("/browse2#{path}?ajax=yes", {"d"=> 1, "t" => @token })
31
-
32
- listing = list.search('div.browse-file-box-details').collect do |file|
33
- details = {}
34
- details['name'] = file.at('div.details-filename a').content.strip
35
- details['url'] = file.at('div.details-filename a')["href"]
36
- #details['size'] = file.at('div.details-size a').try(:content).try(:strip)
37
- #details['modified'] = file.at('div.details-modified a').try(:content).try(:strip)
38
-
39
- if match_data = details['url'].match(/^\/browse_plain(.*)$/)
40
- details['directory'] = true
41
- details['path'] = normalize_namespace(match_data[1])
42
- elsif match_data = details['url'].match(%r{^https?://[^/]*/get(.*)$})
43
- details['directory'] = false
44
- details['path'] = normalize_namespace(match_data[1])
45
- elsif match_data = details['url'].match(%r{^https?://[^/]*/u/\d*/(.*)$})
46
- details['directory'] = false
47
- details['path'] = "Public/#{match_data[1]}"
48
- else
49
- raise "could not parse path from Dropbox URL: #{details['url'] }"
50
- end
51
-
52
- details
53
- end
54
-
55
- return listing
56
- end
57
-
58
- alias :list :index
59
-
60
- # Lists the full history for a file on DropBox
61
- def list_history(path)
62
- login_filter
63
-
64
- path = namespace_path(path)
65
-
66
- history = @agent.get("/revisions#{path}")
67
- listing = history.search("table.filebrowser > tr").select{|r| r.search("td").count > 1 }.collect do |r|
68
-
69
- # warning, this is very brittle!
70
- details = {}
71
- details["version"] = r.search("td a").first.content.strip
72
- details["url"] = r.search("td a").first["href"]
73
- details["size"] = r.search("td").last.content.strip
74
- details["modified"] = r.search("td")[2].content.strip
75
- details["version_id"] = details["url"].match(/^.*sjid=([\d]*)$/)[1]
76
- details['path'] = normalize_namespace(details['url'][33..-1])
77
-
78
- details
79
- end
80
-
81
- return listing
82
- end
83
-
84
- # Downloads the specified file from DropBox
85
- def show(path)
86
- require 'pathname'
87
- # change to before filter
88
- login_filter
89
-
90
- # round about way of getting the secure url we need
91
- # path = namespace_path(path)
92
- pathname = Pathname.new(path)
93
- url = self.list(pathname.dirname.to_s).detect{ |f| f["name"] == pathname.basename.to_s }["url"]
94
-
95
- #https://dl-web.dropbox.com/get/testing.txt?w=0ff80d5d&sjid=125987568
96
- @agent.get(url).content
97
- end
98
-
99
- alias :get :show
100
-
101
- # Creates a directory
102
- def create_directory(new_path, destination = "/" )
103
- # change to before filter
104
- login unless @logged_in
105
- destination = namespace_path(destination)
106
- @agent.post("/cmd/new#{destination}",{"to_path"=>new_path, "folder"=>"yes", "t" => @token }).code == "200"
107
- end
108
-
109
- # Uploads a file to DropBox under the given filename
110
- def create(file, destination = "/")
111
- # change to before filter
112
- if @logged_in
113
- home_page = @agent.get('https://www.dropbox.com/home')
114
- else
115
- home_page = login
116
- end
117
-
118
- upload_form = home_page.forms.detect{ |f| f.action == "https://dl-web.dropbox.com/upload" }
119
- upload_form.dest = namespace_path(destination)
120
- upload_form.file_uploads.first.file_name = file if file
121
-
122
- @agent.submit(upload_form).code == "200"
123
- end
124
-
125
- alias :update :create
126
-
127
- # Renames a file or folder in the DropBox
128
- def rename(file, destination)
129
- login_filter
130
- file = namespace_path(file)
131
- destination = namespace_path(destination)
132
- @agent.post("/cmd/rename#{file}", {"to_path"=> destination, "t" => @token }).code == "200"
133
- end
134
-
135
- # Deletes a file/folder from the DropBox (accepts string path or an array of string paths)
136
- def destroy(paths)
137
- login_filter
138
- paths = [paths].flatten
139
- paths = paths.collect { |path| namespace_path(path) }
140
- @agent.post("/cmd/delete", {"files"=> paths, "t" => @token }).code == "200"
141
- end
142
-
143
- # Permanently deletes a file from the DropBox (no history!) accepts arrays, as #destroy does
144
- def purge(paths)
145
- login_filter
146
- paths = [paths].flatten
147
- paths = paths.collect { |path| namespace_path(path) }
148
- @agent.post("/cmd/purge", {"files"=> paths, "t" => @token }).code == "200"
149
- end
150
-
151
- # Will give a hash of the amount of space left on the DropBox, the amound used, the calculated amount free (all as a 1 d.p. rounded GB value) and the percentage used (scraped)
152
- def usage_stats
153
- login_filter
154
-
155
- stats_page = @agent.get("/account")
156
-
157
- stats = stats_page.at('#usage-percent').content.scan(/(\d+(?:\.\d+)?)%\ used\ \((\d+(?:\.\d+)?)([MG])B of (\d+(?:\.\d+)?)GB\)/).collect{ |d|
158
- { :used => d[1].to_f * ((d[2] == "G") ? 1024 : 1),
159
- :total => d[3].to_f * 1024,
160
- :free => (d[3].to_f * 1024 - d[1].to_f * ((d[2] == "G") ? 1024 : 1)),
161
- :percent => Percentage.new(d[0].to_f/100)
162
- }
163
- }[0]
164
-
165
- regular_data = stats_page.at('span.bar-graph-legend.bar-graph-normal').next.content.scan(/\((\d+(?:\.\d+)?)([MG])B/)[0]
166
- stats[:regular_used] = regular_data[0].to_f * ((regular_data[1] == "G") ? 1024 : 1) unless regular_data.nil?
167
-
168
- shared_data = stats_page.at('span.bar-graph-legend.bar-graph-shared').next.content.scan(/\((\d+(?:\.\d+)?)([MG])B/)[0]
169
- stats[:shared_used] = shared_data[0].to_f * ((shared_data[1] == "G") ? 1024 : 1) unless shared_data.nil?
170
-
171
- return stats
172
- end
173
-
174
- private
175
- def namespace_path(path)
176
- # remove the start slash if we have one
177
- path.gsub(/^\//,"")
178
- new_path = if @folder_namespace.empty?
179
- "/#{path}"
180
- else
181
- "/#{@folder_namespace}/#{path}"
182
- end
183
- new_path.gsub("//","/")
184
- end
185
-
186
- def normalize_namespace(file)
187
- file.gsub(/^\/#{@folder_namespace}/,"")
188
- end
189
-
190
- def login
191
- page = @agent.get('https://www.dropbox.com/login')
192
- login_form = page.forms.detect { |f| f.action == "/login" }
193
- login_form.login_email = @email
194
- login_form.login_password = @password
195
-
196
- home_page = @agent.submit(login_form)
197
- # todo check if we are logged in! (ie search for email and "Log out"
198
- @logged_in = true
199
- @token = home_page.at('//script[contains(text(), "TOKEN")]').content.match("TOKEN: '(.*)',$")[1]
200
-
201
- # check if we have our namespace
202
-
203
- home_page
204
- end
205
-
206
- def login_filter
207
- login unless @logged_in
208
- end
209
- end
210
-
211
- # this file doesn't use the standard ruby indent settings, so the following
212
- # modeline will make sure that the whitespace stays consistent.
213
- # vim:noexpandtab tabstop=4 shiftwidth=4