mobilize-base 1.0.1 → 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|