@@ -355,7 +355,7 @@ def is_scalar_or_string(val):
355
355
class ViewVCCachedServer (urllib2 .BaseHandler ):
356
356
"""
357
357
Urllib2 handler that takes care of caching files.
358
- The file cache.pck holds the directory of files to be cached.
358
+ The file cache.pck holds the directory of files that have been cached.
359
359
"""
360
360
def __init__ (self , cache_dir , baseurl ):
361
361
self .cache_dir = cache_dir
@@ -386,9 +386,14 @@ def read_cache(self):
386
386
cache = cPickle .load (f )
387
387
f .close ()
388
388
389
+ # Earlier versions did not have the full paths in cache.pck
390
+ for url , (fn , x , y ) in cache .items ():
391
+ if not os .path .isabs (fn ):
392
+ cache [url ] = (self .in_cache_dir (fn ), x , y )
393
+
389
394
# If any files are deleted, drop them from the cache
390
395
for url , (fn , _ , _ ) in cache .items ():
391
- if not os .path .exists (self . in_cache_dir ( fn ) ):
396
+ if not os .path .exists (fn ):
392
397
del cache [url ]
393
398
394
399
self .cache = cache
@@ -398,14 +403,20 @@ def remove_stale_files(self):
398
403
Remove files from the cache directory that are not listed in
399
404
cache.pck.
400
405
"""
401
- listed = set ([fn for (_ , (fn , _ , _ )) in self .cache .items ()])
402
- for path in os .listdir (self .cache_dir ):
403
- if path not in listed and path != 'cache.pck' :
404
- thisfile = os .path .join (self .cache_dir , path )
405
- if not os .path .isdir (thisfile ):
406
- matplotlib .verbose .report ('ViewVCCachedServer:remove_stale_files: removing %s' % thisfile ,
407
- level = 'debug' )
408
- os .remove (thisfile )
406
+ # TODO: remove empty subdirectories
407
+ listed = set (fn for (_ , (fn , _ , _ )) in self .cache .items ())
408
+ existing = reduce (set .union ,
409
+ (set (os .path .join (dirpath , fn ) for fn in filenames )
410
+ for (dirpath , _ , filenames ) in os .walk (self .cache_dir )))
411
+ matplotlib .verbose .report (
412
+ 'ViewVCCachedServer: files listed in cache.pck: %s' % listed , 'debug' )
413
+ matplotlib .verbose .report (
414
+ 'ViewVCCachedServer: files in cache directory: %s' % existing , 'debug' )
415
+
416
+ for path in existing - listed - set ([self .in_cache_dir ('cache.pck' )]):
417
+ matplotlib .verbose .report ('ViewVCCachedServer:remove_stale_files: removing %s' % path ,
418
+ level = 'debug' )
419
+ os .remove (path )
409
420
410
421
def write_cache (self ):
411
422
"""
@@ -424,17 +435,12 @@ def cache_file(self, url, data, headers):
424
435
fn = url [len (self .baseurl ):]
425
436
fullpath = self .in_cache_dir (fn )
426
437
427
- #while os.path.exists(self.in_cache_dir(fn)):
428
- # fn = rightmost + '.' + str(random.randint(0,9999999))
429
-
430
-
431
-
432
- f = open (self .in_cache_dir (fn ), 'wb' )
438
+ f = open (fullpath , 'wb' )
433
439
f .write (data )
434
440
f .close ()
435
441
436
442
# Update the cache
437
- self .cache [url ] = (fn , headers .get ('ETag' ), headers .get ('Last-Modified' ))
443
+ self .cache [url ] = (fullpath , headers .get ('ETag' ), headers .get ('Last-Modified' ))
438
444
self .write_cache ()
439
445
440
446
# These urllib2 entry points are used:
@@ -459,9 +465,9 @@ def http_error_304(self, req, fp, code, msg, hdrs):
459
465
"""
460
466
url = req .get_full_url ()
461
467
fn , _ , _ = self .cache [url ]
462
- cachefile = self . in_cache_dir ( fn )
463
- matplotlib . verbose . report ( 'ViewVCCachedServer: reading data file from cache file "%s"' % cachefile )
464
- file = open (cachefile , 'rb' )
468
+ matplotlib . verbose . report ( 'ViewVCCachedServer: reading data file from cache file "%s"'
469
+ % fn , 'debug' )
470
+ file = open (fn , 'rb' )
465
471
handle = urllib2 .addinfourl (file , hdrs , url )
466
472
handle .code = 304
467
473
return handle
@@ -470,6 +476,8 @@ def http_response(self, req, response):
470
476
"""
471
477
Update the cache with the returned file.
472
478
"""
479
+ matplotlib .verbose .report ('ViewVCCachedServer: received response %d: %s'
480
+ % (response .code , response .msg ), 'debug' )
473
481
if response .code != 200 :
474
482
return response
475
483
else :
@@ -489,10 +497,10 @@ def get_sample_data(self, fname, asfileobj=True):
489
497
store it in the cachedir.
490
498
491
499
If asfileobj is True, a file object will be returned. Else the
492
- path to the file as a string will be returned
493
-
500
+ path to the file as a string will be returned.
494
501
"""
495
-
502
+ # TODO: time out if the connection takes forever
503
+ # (may not be possible with urllib2 only - spawn a helper process?)
496
504
497
505
# quote is not in python2.4, so check for it and get it from
498
506
# urllib if it is not available
@@ -501,12 +509,24 @@ def get_sample_data(self, fname, asfileobj=True):
501
509
import urllib
502
510
quote = urllib .quote
503
511
512
+ # retrieve the URL for the side effect of refreshing the cache
504
513
url = self .baseurl + quote (fname )
505
- response = self .opener .open (url )
506
-
507
-
508
- relpath = self .cache [url ][0 ]
509
- fname = self .in_cache_dir (relpath )
514
+ error = 'unknown error'
515
+ matplotlib .verbose .report ('ViewVCCachedServer: retrieving %s'
516
+ % url , 'debug' )
517
+ try :
518
+ response = self .opener .open (url )
519
+ except urllib2 .URLError , e :
520
+ # could be a missing network connection
521
+ error = str (e )
522
+
523
+ cached = self .cache .get (url )
524
+ if cached is None :
525
+ msg = 'file %s not in cache; received %s when trying to retrieve' \
526
+ % (fname , error )
527
+ raise KeyError (msg )
528
+
529
+ fname = cached [0 ]
510
530
511
531
if asfileobj :
512
532
return file (fname )
@@ -519,7 +539,7 @@ def get_sample_data(fname, asfileobj=True):
519
539
Check the cachedirectory ~/.matplotlib/sample_data for a sample_data
520
540
file. If it does not exist, fetch it with urllib from the mpl svn repo
521
541
522
- http://matplotlib.svn.sourceforge.net/viewvc /matplotlib/trunk/sample_data/
542
+ http://matplotlib.svn.sourceforge.net/svnroot /matplotlib/trunk/sample_data/
523
543
524
544
and store it in the cachedir.
525
545
@@ -539,7 +559,7 @@ def get_sample_data(fname, asfileobj=True):
539
559
if myserver is None :
540
560
configdir = matplotlib .get_configdir ()
541
561
cachedir = os .path .join (configdir , 'sample_data' )
542
- baseurl = 'http://matplotlib.svn.sourceforge.net/viewvc /matplotlib/trunk/sample_data/'
562
+ baseurl = 'http://matplotlib.svn.sourceforge.net/svnroot /matplotlib/trunk/sample_data/'
543
563
myserver = get_sample_data .myserver = ViewVCCachedServer (cachedir , baseurl )
544
564
545
565
return myserver .get_sample_data (fname , asfileobj = asfileobj )
0 commit comments