1
2
3
4
5
6
7
8
9
10
11 import os, sys, md5
12 import glob, tarfile, zipfile
13 import cStringIO
14
15 from constants import Constants
16 from util import Util
17
19
21 '''
22 Creates a new instance of MobileCodeManager, which is responsible for
23 moving mobile codes between application server and clients.
24
25 @param worker: Parent worker of this manager.
26 '''
27 self._worker = worker
28
29
30 self._remoteCodeCache = {}
31
32 self._fileListCache = {}
33
35 '''
36 Clears internal caches used in mobile code manager.
37 '''
38 self._remoteCodeCache = {}
39 self._fileListCache = {}
40
41 - def pathMD5(self, distribution, path):
42 '''
43 Computes MD5 for a group of files.
44
45 @type distribution: string
46 @param distribution: String that represents the distribution name.
47 @type path: string
48 @param path: Directory name that will be exported as mobile code. This
49 should be in UNIX semantics.
50 '''
51
52
53 distribution = str(distribution)
54 path = str(path)
55
56 md5hash = md5.new()
57
58 for nextFile in self._fileList(distribution, path):
59 fileName = os.path.join(self._worker.directory(),
60 Constants.WORK_DIRECTORY,
61 distribution,
62 nextFile)
63 packageItem = os.stat(fileName)
64
65 md5hash.update(os.path.basename(fileName))
66 md5hash.update('%s' % packageItem.st_size)
67
68 digest = md5hash.hexdigest()
69
70 return digest
71
73 '''
74 Returns compressed package data for the given distribution and path.
75
76 @type distribution: string
77 @param distribution: String that represents the distribution name.
78 @type path: string
79 @param path: Directory name that will be exported as mobile code. This
80 should be in UNIX semantics.
81 '''
82
83
84 distribution = str(distribution)
85 path = str(path)
86
87 try:
88 return self._remoteCodeCache[(distribution, path)]
89 except KeyError:
90 pass
91
92
93 buffer = cStringIO.StringIO()
94
95
96 newPkg = zipfile.ZipFile(buffer, 'w')
97
98 fileList = self._fileList(distribution, path)
99
100 for distFile in fileList:
101 packageItem = open(os.path.join(self._worker.directory(),
102 Constants.WORK_DIRECTORY,
103 distribution,
104 distFile), 'rb')
105
106 newPkg.writestr(distFile, packageItem.read())
107
108
109
110 newPkg.close()
111
112 contents = buffer.getvalue()
113
114 buffer.close()
115
116 self._remoteCodeCache[(distribution, path)] = contents
117
118 return contents
119
121 '''
122 Returns a list of files under distribution I{distribution} requested by
123 I{path}. List is ordered according to file name. UNIX file semantics are
124 used for representing file names.
125
126 @type distribution: string
127 @param distribution: String that represents the distribution name.
128 @type path: string
129 @param path: Directory name that will be exported as mobile code. This
130 should be in UNIX semantics.
131 '''
132
133
134 distribution = str(distribution)
135 path = str(path)
136
137 try:
138 return self._fileListCache[(distribution, path)]
139 except KeyError:
140 pass
141
142 retval = []
143
144 distDir = os.path.join(self._worker.directory(), Constants.WORK_DIRECTORY, distribution)
145 fileList = Util.globRecursively(distDir)
146
147
148
149 for candFile in fileList:
150 fileName = candFile[len(distDir)+1:]
151 if fileName.startswith(path.replace('/', os.path.sep) + os.path.sep):
152 retval.append(fileName)
153
154
155
156 pathElements = path.split('/')
157 for index in xrange(len(pathElements)):
158 initPyZipPath = os.path.join(*(pathElements[:index] + ['__init__.py' + Constants.PY_COMPILED_EXT]))
159 initPyPath = distDir + os.path.sep + initPyZipPath
160 if initPyPath in fileList:
161 retval.append(initPyZipPath)
162
163
164 retval.sort()
165
166 self._fileListCache[(distribution, path)] = retval
167 return retval
168