mobilize-base 1.0.1 → 1.0.2
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.
- data/lib/mobilize-base/extensions/google_drive.rb +30 -5
- data/lib/mobilize-base/extensions/string.rb +3 -1
- data/lib/mobilize-base/handlers/{emailer.rb → email.rb} +5 -5
- data/lib/mobilize-base/handlers/gbook.rb +73 -0
- data/lib/mobilize-base/handlers/gdrive.rb +72 -0
- data/lib/mobilize-base/handlers/gfile.rb +55 -0
- data/lib/mobilize-base/handlers/gsheet.rb +123 -0
- data/lib/mobilize-base/handlers/{mongoer.rb → mongodb.rb} +8 -8
- data/lib/mobilize-base/jobtracker.rb +37 -8
- data/lib/mobilize-base/models/dataset.rb +4 -4
- data/lib/mobilize-base/models/job.rb +43 -55
- data/lib/mobilize-base/models/requestor.rb +24 -27
- data/lib/mobilize-base/version.rb +1 -1
- data/lib/mobilize-base.rb +7 -7
- data/lib/samples/gdrive.yml +3 -0
- data/test/mobilize_test.rb +24 -40
- data/test/test_helper.rb +0 -13
- metadata +8 -5
- data/lib/mobilize-base/handlers/gdriver.rb +0 -303
@@ -1,303 +0,0 @@
|
|
1
|
-
module Mobilize
|
2
|
-
module Gdriver
|
3
|
-
def Gdriver.config
|
4
|
-
Base.config('gdrive')[Base.env]
|
5
|
-
end
|
6
|
-
|
7
|
-
def Gdriver.owner_email
|
8
|
-
Gdriver.config['owner']['email']
|
9
|
-
end
|
10
|
-
|
11
|
-
def Gdriver.password(email)
|
12
|
-
if email == Gdriver.owner_email
|
13
|
-
Gdriver.config['owner']['pw']
|
14
|
-
else
|
15
|
-
worker = Gdriver.workers(email)
|
16
|
-
return worker['pw'] if worker
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
def Gdriver.admins
|
21
|
-
Gdriver.config['admins']
|
22
|
-
end
|
23
|
-
|
24
|
-
def Gdriver.workers(email=nil)
|
25
|
-
if email.nil?
|
26
|
-
Gdriver.config['workers']
|
27
|
-
else
|
28
|
-
Gdriver.workers.select{|w| w['email'] == email}.first
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
def Gdriver.worker_emails
|
33
|
-
Gdriver.workers.map{|w| w['email']}
|
34
|
-
end
|
35
|
-
|
36
|
-
def Gdriver.admin_emails
|
37
|
-
Gdriver.admins.map{|w| w['email']}
|
38
|
-
end
|
39
|
-
|
40
|
-
#email management - used to make sure not too many emails get used at the same time
|
41
|
-
def Gdriver.get_worker_email_by_mongo_id(mongo_id)
|
42
|
-
active_emails = Mobilize::Resque.jobs('working').map{|j| j['email'] if j['email']}.compact
|
43
|
-
Gdriver.workers.sort_by{rand}.each do |w|
|
44
|
-
if !(active_emails.include?(w['email']))
|
45
|
-
Mobilize::Resque.update_job_email(mongo_id,w['email'])
|
46
|
-
return w['email']
|
47
|
-
end
|
48
|
-
end
|
49
|
-
#return false if none are available
|
50
|
-
return false
|
51
|
-
end
|
52
|
-
|
53
|
-
def Gdriver.root(email=nil)
|
54
|
-
email ||= Gdriver.owner_email
|
55
|
-
pw = Gdriver.password(email)
|
56
|
-
GoogleDrive.login(email,pw)
|
57
|
-
end
|
58
|
-
|
59
|
-
def Gdriver.files(email=nil,params={})
|
60
|
-
root = Gdriver.root(email)
|
61
|
-
root.files(params)
|
62
|
-
end
|
63
|
-
|
64
|
-
def Gdriver.books(email=nil,params={})
|
65
|
-
Gdriver.files(email,params).select{|f| f.class==GoogleDrive::Spreadsheet}
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
class Gfiler
|
70
|
-
def Gfiler.find_by_title(title,email=nil)
|
71
|
-
Gdriver.files(email).select{|f| f.title==title}.first
|
72
|
-
end
|
73
|
-
|
74
|
-
def Gfiler.find_by_dst_id(dst_id,email=nil)
|
75
|
-
dst = Dataset.find(dst_id)
|
76
|
-
Gfiler.find_by_title(dst.path,email)
|
77
|
-
end
|
78
|
-
|
79
|
-
def Gfiler.add_admin_acl_by_dst_id(dst_id)
|
80
|
-
#adds admins and workers as writers
|
81
|
-
file = Gfiler.find_by_dst_id(dst_id)
|
82
|
-
file.add_admin_acl
|
83
|
-
return true
|
84
|
-
end
|
85
|
-
|
86
|
-
def Gfiler.add_admin_acl_by_title(title)
|
87
|
-
file = Gfiler.find_by_title(title)
|
88
|
-
file.add_admin_acl
|
89
|
-
return true
|
90
|
-
end
|
91
|
-
|
92
|
-
def Gfiler.add_worker_acl_by_title(title)
|
93
|
-
file = Gfiler.find_by_title(title)
|
94
|
-
file.add_worker_acl
|
95
|
-
return true
|
96
|
-
end
|
97
|
-
|
98
|
-
def Gfiler.update_acl_by_dst_id(dst_id,email,role="writer",edit_email=nil)
|
99
|
-
dst = Dataset.find(dst_id)
|
100
|
-
Gfiler.update_acl_by_title(dst.path,email,role,edit_email)
|
101
|
-
end
|
102
|
-
|
103
|
-
def Gfiler.update_acl_by_title(title,email,role="writer",edit_email=nil)
|
104
|
-
file = Gfiler.find_by_title(title,edit_email)
|
105
|
-
raise "File #{title} not found" unless file
|
106
|
-
file.update_acl(email,role)
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
module Gbooker
|
111
|
-
def Gbooker.find_all_by_title(title,email=nil)
|
112
|
-
Gdriver.books(email,{"title"=>title,"title-exact"=>"true"})
|
113
|
-
end
|
114
|
-
def Gbooker.find_or_create_by_title(title,email)
|
115
|
-
books = Gdriver.books(email,{"title"=>title,"title-exact"=>"true"})
|
116
|
-
#there should only be one book with each title, otherwise we have fail
|
117
|
-
book = nil
|
118
|
-
if books.length>1
|
119
|
-
#some idiot process created a duplicate book.
|
120
|
-
#Fix by renaming all but one with dst entry's key
|
121
|
-
dst = Dataset.find_by_handler_and_name('gbooker',title)
|
122
|
-
dkey = dst.url.split("key=").last
|
123
|
-
books.each do |b|
|
124
|
-
bkey = b.resource_id.split(":").last
|
125
|
-
if bkey == dkey
|
126
|
-
book = b
|
127
|
-
else
|
128
|
-
#delete the invalid book
|
129
|
-
b.delete
|
130
|
-
("Deleted duplicate book #{title}").oputs
|
131
|
-
end
|
132
|
-
end
|
133
|
-
else
|
134
|
-
book = books.first
|
135
|
-
end
|
136
|
-
if book.nil?
|
137
|
-
#add book using owner email
|
138
|
-
#http
|
139
|
-
book = Gdriver.root.create_spreadsheet(title)
|
140
|
-
("Created book #{title} at #{Time.now.utc.to_s}").oputs
|
141
|
-
end
|
142
|
-
#delete Sheet1 if there are other sheets
|
143
|
-
#http
|
144
|
-
if (sheets = book.worksheets).length>1
|
145
|
-
sheet1 = sheets.select{|s| s.title == "Sheet1"}.first
|
146
|
-
#http
|
147
|
-
sheet1.delete if sheet1
|
148
|
-
end
|
149
|
-
#always make sure books have admin acl
|
150
|
-
book.add_admin_acl
|
151
|
-
return book
|
152
|
-
end
|
153
|
-
|
154
|
-
def Gbooker.find_or_create_by_dst_id(dst_id,email=nil)
|
155
|
-
#creates by title, updates acl, updates dataset with url
|
156
|
-
dst = Dataset.find(dst_id)
|
157
|
-
r = Requestor.find(dst.requestor_id)
|
158
|
-
book = nil
|
159
|
-
#http
|
160
|
-
book = Gdriver.root.spreadsheet_by_url(dst.url) if dst.url
|
161
|
-
#manually try 5 times to validate sheet since we can't just try again and again
|
162
|
-
5.times.each do
|
163
|
-
begin
|
164
|
-
book.resource_id
|
165
|
-
#if no error then break loop
|
166
|
-
break
|
167
|
-
rescue=>exc
|
168
|
-
if book.nil? or exc.to_s.index('Invalid document id')
|
169
|
-
book = Gbooker.find_or_create_by_title(dst.name,email)
|
170
|
-
#if invalid doc then update url w new book and break loop
|
171
|
-
dst.update_attributes(:url=>book.human_url)
|
172
|
-
break
|
173
|
-
end
|
174
|
-
end
|
175
|
-
end
|
176
|
-
#add requestor write access
|
177
|
-
book.update_acl(r.email)
|
178
|
-
return book
|
179
|
-
end
|
180
|
-
end
|
181
|
-
|
182
|
-
module Gsheeter
|
183
|
-
|
184
|
-
def Gsheeter.max_cells
|
185
|
-
400000
|
186
|
-
end
|
187
|
-
|
188
|
-
def Gsheeter.read(name,email=nil)
|
189
|
-
sheet = Gsheeter.find_or_create_by_name(name,email)
|
190
|
-
sheet.to_tsv
|
191
|
-
end
|
192
|
-
|
193
|
-
def Gsheeter.write(name,tsv,email=nil)
|
194
|
-
sheet = Gsheeter.find_or_create_by_name(name,email)
|
195
|
-
sheet.write(tsv)
|
196
|
-
end
|
197
|
-
|
198
|
-
def Gsheeter.find_all_by_name(name,email)
|
199
|
-
book_title,sheet_title = name.split("/")
|
200
|
-
books = Gdriver.books(email,{"title"=>book_title,"title-exact"=>"true"})
|
201
|
-
sheets = books.map{|b| b.worksheets}.flatten.select{|w| w.title == sheet_title }
|
202
|
-
sheets
|
203
|
-
end
|
204
|
-
|
205
|
-
def Gsheeter.find_or_create_by_name(name,email=nil,rows=100,cols=20)
|
206
|
-
book_title,sheet_title = name.split("/")
|
207
|
-
book = Gbooker.find_or_create_by_title(book_title,email)
|
208
|
-
#http
|
209
|
-
sheet = book.worksheets.select{|w| w.title==sheet_title}.first
|
210
|
-
if sheet.nil?
|
211
|
-
#http
|
212
|
-
sheet = book.add_worksheet(sheet_title,rows,cols)
|
213
|
-
("Created sheet #{name} at #{Time.now.utc.to_s}").oputs
|
214
|
-
end
|
215
|
-
return sheet
|
216
|
-
end
|
217
|
-
|
218
|
-
def Gsheeter.find_or_create_by_dst_id(dst_id,email=nil)
|
219
|
-
#creates by title, updates acl, updates dataset with url
|
220
|
-
dst = Dataset.find(dst_id)
|
221
|
-
r = Requestor.find(dst.requestor_id)
|
222
|
-
name = dst.name
|
223
|
-
book_title,sheet_title = name.split("/")
|
224
|
-
#make sure book exists and is assigned to this user
|
225
|
-
r.find_or_create_gbook_by_title(book_title,email)
|
226
|
-
#add admin write access
|
227
|
-
sheet = Gsheeter.find_or_create_by_name(name)
|
228
|
-
sheet_title = nil
|
229
|
-
return sheet
|
230
|
-
end
|
231
|
-
|
232
|
-
def Gsheeter.read_by_job_id(job_id)
|
233
|
-
j = Job.find(job_id)
|
234
|
-
#reserve email account for read
|
235
|
-
email = Gdriver.get_worker_email_by_mongo_id(job_id)
|
236
|
-
return false unless email
|
237
|
-
#pull tsv from cache
|
238
|
-
j.param_sheet_dsts.first.read_cache
|
239
|
-
end
|
240
|
-
|
241
|
-
def Gsheeter.read_by_dst_id(dst_id,email=nil)
|
242
|
-
dst = Dataset.find(dst_id)
|
243
|
-
name = dst.name
|
244
|
-
sheet = Gsheeter.find_or_create_by_name(name,email)
|
245
|
-
output = sheet.to_tsv
|
246
|
-
return output
|
247
|
-
end
|
248
|
-
|
249
|
-
def Gsheeter.write_by_dst_id(dst_id,tsv,email=nil)
|
250
|
-
dst = Dataset.find(dst_id)
|
251
|
-
#see if this is a specific cell
|
252
|
-
name = dst.name
|
253
|
-
return false unless email
|
254
|
-
#create temp tab, write data to it, checksum it against the source
|
255
|
-
tempsheet = Gsheeter.find_or_create_by_name("#{name}_temp")
|
256
|
-
tempsheet.write(tsv)
|
257
|
-
#delete current sheet, replace it with temp one
|
258
|
-
sheet = Gsheeter.find_or_create_by_name(dst.name)
|
259
|
-
title = sheet.title
|
260
|
-
#http
|
261
|
-
sheet.delete
|
262
|
-
begin
|
263
|
-
tempsheet.rename(title)
|
264
|
-
rescue
|
265
|
-
#need this because sometimes it gets confused and tries to rename twice
|
266
|
-
end
|
267
|
-
"Write successful for #{write_name}".oputs
|
268
|
-
return true
|
269
|
-
end
|
270
|
-
|
271
|
-
def Gsheeter.write_by_job_id(job_id)
|
272
|
-
j = Job.find(job_id)
|
273
|
-
r = j.requestor
|
274
|
-
tgt_name = if j.destination.split("/").length==1
|
275
|
-
"#{r.jobspec_title}#{"/"}#{j.destination}"
|
276
|
-
else
|
277
|
-
j.destination
|
278
|
-
end
|
279
|
-
sheet_dst = Dataset.find_or_create_by_handler_and_name('gsheeter',tgt_name)
|
280
|
-
sheet_dst.update_attributes(:requestor_id=>r.id.to_s) if sheet_dst.requestor_id.nil?
|
281
|
-
email = Gdriver.get_worker_email_by_mongo_id(job_id)
|
282
|
-
#return false if there are no emails available
|
283
|
-
return false unless email
|
284
|
-
#create temp tab, write data to it, checksum it against the source
|
285
|
-
tempsheet_dst = Dataset.find_or_create_by_handler_and_name('gsheeter',"#{tgt_name}_temp")
|
286
|
-
tempsheet_dst.update_attributes(:requestor_id=>r.id.to_s) if tempsheet_dst.requestor_id.nil?
|
287
|
-
tempsheet = Gsheeter.find_or_create_by_dst_id(tempsheet_dst.id.to_s)
|
288
|
-
#tsv is the second to last stage's output (the last is the write)
|
289
|
-
tsv = Dataset.find(j.tasks[j.prior_task]['output_dst_id']).read
|
290
|
-
tempsheet.write(tsv,true,job_id)
|
291
|
-
#delete current sheet, replace it with temp one
|
292
|
-
sheet = Gsheeter.find_or_create_by_name(tgt_name,email)
|
293
|
-
title = sheet.title
|
294
|
-
#http
|
295
|
-
sheet.delete
|
296
|
-
tempsheet.title = title
|
297
|
-
tempsheet.save
|
298
|
-
sheet_dst.update_attributes(:url=>tempsheet.spreadsheet.human_url)
|
299
|
-
"Write successful for #{tgt_name}".oputs
|
300
|
-
return true
|
301
|
-
end
|
302
|
-
end
|
303
|
-
end
|