-
Notifications
You must be signed in to change notification settings - Fork 0
/
library.py
67 lines (56 loc) · 2.33 KB
/
library.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import os
import errno
import shutil
import tempfile
import cPickle as pickle
# TODO: Right now, Libraries don't provide any sort of locking. That means that,
# if two users request the same nonexistent resource at around the same time,
# they may both end up computing it. Bummer.
class Library:
def __init__(self, root_path):
self.root_path = os.path.realpath(root_path)
# Gets the value at `paths` out of the library. If it's not found, runs
# `thunk()` to create it, then stores that at `paths` (and returns it).
def get(self, thunk, *paths):
full_path = os.path.join(self.root_path, *paths)
# print 'GETTING', paths
try:
with open(full_path, 'rb') as f:
# print ' CACHE HIT; LOADING'
value = pickle.load(f)
# print ' LOADED'
return value
except IOError as exc:
if exc.errno != errno.ENOENT:
raise
# print ' CACHE MISS; CALCULATING'
value = thunk()
# print ' CALCULATED; SAVING'
full_path_dirname = os.path.dirname(full_path)
if not os.path.exists(full_path_dirname):
try:
os.makedirs(full_path_dirname)
except OSError as exc:
if exc.errno != errno.EEXIST:
raise
with open(full_path, 'wb') as f:
pickle.dump(value, f)
# print ' SAVED'
return value
# Copies the directory located at `paths` out of the library. If it's not
# found, runs `thunk(temp_dir)`, which should populate the directory
# `temp_dir`, then stores that at `paths` (and returns it).
def get_dir(self, ultimate_destination, thunk, *paths):
full_path = os.path.join(self.root_path, *paths)
if not os.path.exists(full_path):
temp_dir = tempfile.mkdtemp()
thunk(temp_dir)
full_path_dirname = os.path.dirname(full_path)
if not os.path.exists(full_path_dirname):
try:
os.makedirs(full_path_dirname)
except OSError as exc:
if exc.errno != errno.EEXIST:
raise
shutil.copytree(temp_dir, full_path)
shutil.copytree(full_path, ultimate_destination)