17
17
from .client import find_box , BoxClient
18
18
from .log import persistent_log
19
19
from .queue import RedisArchiveQueue
20
+ from .slugify import slugify
20
21
21
22
22
23
log = logging .getLogger (__name__ )
@@ -251,46 +252,33 @@ def copy_community_to_box(community):
251
252
log .info ("Connecting to Box." )
252
253
box = BoxClient (find_box (community ), get_current_registry ().settings )
253
254
254
- def realize_archive (archive , folder , path , copied ):
255
+ def realize_archive (archive , folder , path = '' ):
256
+ contents = box .contents (folder )
255
257
for name , item in archive .items ():
256
- subpath = path + (name ,)
257
- joined = '/' + '/' .join (subpath )
258
- if joined in copied :
259
- log .info ("Skipping existing file %s" , joined )
260
- continue
258
+ subpath = path + '/' + name
261
259
if isinstance (item , ArchiveFolder ):
262
- log .info ("Creating folder %s" , joined )
263
- if name in folder :
264
- subfolder = folder [name ]
260
+ if name in contents :
261
+ log .info ("Exists folder %s" , subpath )
262
+ subfolder = contents [name ]
263
+ assert subfolder .type == 'folder' , subpath
265
264
else :
266
- subfolder = folder .mkdir (name )
267
- realize_archive (item , subfolder , subpath , copied )
265
+ log .info ("Creating folder %s" , subpath )
266
+ subfolder = folder .create_subfolder (name )
267
+ realize_archive (item , subfolder , subpath )
268
268
else :
269
- log .info ("Uploading (%d) %s" , len (copied ), joined )
270
- try :
271
- folder .upload (name , item .open ())
272
- except :
273
- transaction .abort ()
274
- transaction .begin ()
275
- community .archive_copied = copied
276
- community .archive_last_copied = joined
277
- transaction .commit ()
278
- raise
279
- copied .append (joined )
269
+ name = slugify (name )
270
+ subpath = "%s (%s)" % (subpath , name )
271
+ if name in contents :
272
+ log .info ("Exists file %s" , subpath )
273
+ assert contents [name ].type == 'file' , subpath
274
+ else :
275
+ log .info ("Uploading file %s" , subpath )
276
+ folder .upload_stream (item .open (), name )
280
277
281
278
path = reversed ([o .__name__ for o in lineage (community ) if o .__name__ ])
282
- copied = []
283
- if getattr (community , 'archive_copied' , None ) is not None :
284
- copied = community .archive_copied
285
- log .info ("Resuming copy of: %s" , resource_path (community ))
286
- folder = box .root ().get_or_make ('Karl Archive' , * path )
287
- if folder and not copied :
288
- transaction .abort ()
289
- raise ValueError (
290
- 'Cannot archive community, folder already exists: %s' % (
291
- '/' + '/' .join (path )))
292
-
293
- realize_archive (archive (community ), folder , tuple (path ), copied )
279
+ folder = box .get_or_make ('Karl Archive' , * path )
280
+
281
+ realize_archive (archive (community ), folder )
294
282
community .archive_status = 'reviewing'
295
283
if getattr (community , 'archive_copied' , None ) is not None :
296
284
del community .archive_copied
@@ -386,6 +374,10 @@ def worker():
386
374
parser = OptionParser (usage , description = __doc__ )
387
375
parser .add_option ('-C' , '--config' , dest = 'config' , default = None ,
388
376
help = "Specify a paster config file. Defaults to $CWD/etc/karl.ini" )
377
+ parser .add_option ('-r' , '--refresh-authentication' , action = 'store_true' ,
378
+ help = "Refresh box authentication" )
379
+ parser .add_option ('--archive-community' ,
380
+ help = "Manually archive a commmunity to box." )
389
381
390
382
options , args = parser .parse_args ()
391
383
if args :
@@ -397,19 +389,26 @@ def worker():
397
389
root , closer = open_root (config )
398
390
399
391
registry = get_current_registry ()
392
+ sentry_dsn = registry .settings .get ('sentry_dsn' )
400
393
queue = RedisArchiveQueue .from_settings (registry .settings )
394
+
395
+ if options .refresh_authentication :
396
+ BoxClient (find_box (root ), registry .settings ).refresh ()
397
+ return
398
+
401
399
closer ()
400
+ root ._p_jar .close ()
402
401
403
- transaction .commit ()
404
- transaction .manager .explicit = True
405
- root ._p_jar .explicit_transactions = True
406
- # Cause the connection to rollback the current trans wo starting a new one.
407
- transaction .begin (); transaction .abort ()
402
+ if options .archive_community :
403
+ path = '/communities/' + options .archive_community
404
+ operation = queue .COPY_QUEUE_KEY
405
+ root , closer = open_root (config )
406
+ community = find_resource (root , path )
407
+ else :
408
+ log .info ("Waiting for work." )
409
+ operation , community = next (work_queue (queue , config ))
408
410
409
- log .info ("Waiting for work." )
410
- operation , community = next (work_queue (queue , config ))
411
411
log .info ("Got work." )
412
- transaction .begin ()
413
412
with persistent_log (community ) as plog :
414
413
try :
415
414
if operation == queue .COPY_QUEUE_KEY :
@@ -430,6 +429,9 @@ def worker():
430
429
transaction .begin ()
431
430
community .archive_status = 'exception'
432
431
transaction .commit ()
432
+ if sentry_dsn :
433
+ import raven
434
+ raven .Client (sentry_dsn ).captureException ()
433
435
raise
434
436
finally :
435
437
# Persist log in its own transaction so that even if there is an
0 commit comments