blob: c98f0ba14a87205387e7e9d7926b8d2ee807d29c [file] [log] [blame]
Guido van Rossum5f07b841995-04-26 22:57:11 +00001"""Utilities to read and write CVS admin files (esp. CVS/Entries)"""
2
3import string
4import os
5import time
6
7
8class Entry:
9
10 """Class representing one (parsed) line from CVS/Entries"""
11
12 def __init__(self, line):
13 words = string.splitfields(line, '/')
14 self.file = words[1]
15 self.rev = words[2]
16 dates = words[3] # ctime, mtime
17 if dates[:7] == 'Initial':
18 self.ctime = None
19 self.mtime = None
20 self.new = 1
21 else:
22 self.ctime = unctime(dates[:24])
23 self.mtime = unctime(dates[25:])
24 self.new = 0
25 self.extra = words[4]
26 self.sum = None
27
28 def unparse(self):
29 if self.new:
30 dates = "Initial %s" % self.file
31 else:
32 dates = gmctime(self.ctime) + ' ' + gmctime(self.mtime)
33 return "/%s/%s/%s/%s/\n" % (
34 self.file,
35 self.rev,
36 dates,
37 self.extra)
38
39 def setsum(self, sum):
40 self.sum = sum
41
42 def getsum(self):
43 return self.sum
44
45 def sethexsum(self, hexsum):
46 self.setsum(unhexify(hexsum))
47
48 def gethexsum(self):
49 if self.sum:
50 return hexify(self.sum)
51 else:
52 return None
53
54
55class CVS:
56
57 """Class representing the contents of CVS/Entries (and CVS/Sums)"""
58
59 def __init__(self):
60 self.readentries()
61
62 def readentries(self):
63 self.entries = {}
64 f = self.cvsopen("Entries")
65 while 1:
66 line = f.readline()
67 if not line: break
68 e = Entry(line)
69 self.entries[e.file] = e
70 f.close()
71
72 def readsums(self):
73 try:
74 f = self.cvsopen("Sums")
75 except IOError:
76 return
77 while 1:
78 line = f.readline()
79 if not line: break
80 words = string.split(line)
81 [file, rev, hexsum] = words
82 e = self.entries[file]
83 if e.rev == rev:
84 e.sethexsum(hexsum)
85 f.close()
86
87 def writeentries(self):
88 f = self.cvsopen("Entries", 'w')
89 for file in self.keys():
90 f.write(self.entries[file].unparse())
91 f.close()
92
93 def writesums(self):
94 if self.cvsexists("Sums"):
95 f = self.cvsopen("Sums", 'w')
96 else:
97 f = None
98 for file in self.keys():
99 e = self.entries[file]
100 hexsum = e.gethexsum()
101 if hexsum:
102 if not f:
103 f = self.cvsopen("Sums", 'w')
104 f.write("%s %s %s\n" % (file, e.rev, hexsum))
105 if f:
106 f.close()
107
108 def keys(self):
109 keys = self.entries.keys()
110 keys.sort()
111 return keys
112
113 def cvsexists(self, file):
114 file = os.path.join("CVS", file)
115 return os.path.exists(file)
116
117 def cvsopen(self, file, mode = 'r'):
118 file = os.path.join("CVS", file)
119 if 'r' not in mode:
120 self.backup(file)
121 return open(file, mode)
122
123 def backup(self, file):
124 if os.path.isfile(file):
125 bfile = file + '~'
126 os.rename(file, bfile)
127
128
129hexify_format = '%02x' * 16
130def hexify(sum):
131 "Return a hex representation of a 16-byte string (e.g. an MD5 digest)"
132 return hexify_format % tuple(map(ord, sum))
133
134def unhexify(hexsum):
135 "Return the original from a hexified string"
136 sum = ''
137 for i in range(0, len(hexsum), 2):
138 sum = sum + chr(string.atoi(hexsum[i:i+2], 16))
139 return sum
140
141
142unctime_monthmap = {}
143def unctime(date):
144 if not unctime_monthmap:
145 months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
146 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
147 i = 0
148 for m in months:
149 i = i+1
150 unctime_monthmap[m] = i
151 words = string.split(date) # Day Mon DD HH:MM:SS YEAR
152 year = string.atoi(words[4])
153 month = unctime_monthmap[words[1]]
154 day = string.atoi(words[2])
155 [hh, mm, ss] = map(string.atoi, string.splitfields(words[3], ':'))
156 ss = ss - time.timezone
157 return time.mktime((year, month, day, hh, mm, ss, 0, 0, 0))
158
159def gmctime(t):
160 return time.asctime(time.gmtime(t))
161
162def test_unctime():
163 now = int(time.time())
164 t = time.gmtime(now)
165 at = time.asctime(t)
166 print 'GMT', now, at
167 print 'timezone', time.timezone
168 print 'local', time.ctime(now)
169 u = unctime(at)
170 print 'unctime()', u
171 gu = time.gmtime(u)
172 print '->', gu
173 print time.asctime(gu)
174
175def test():
176 x = CVS()
177 keys = x.entries.keys()
178 keys.sort()
179 for file in keys:
180 e = x.entries[file]
181 print file, e.rev, gmctime(e.ctime), gmctime(e.mtime), e.extra,
182 print e.gethexsum()
183
184
185if __name__ == "__main__":
186 test()