File: Synopsis/Formatters/HTML/Views/Directory.py 1
2
3
4
5
6
7
8
9from Synopsis import config
10from Synopsis.Processor import Parameter
11from Synopsis.Formatters.HTML.View import View
12from Synopsis.Formatters.HTML.Tags import *
13import os, stat, os.path, time, re
14
15def compile_glob(globstr):
16 """Returns a compiled regular expression for the given glob string. A
17 glob string is something like "*.?pp" which gets translated into
18 "^.*\..pp$"."""
19 glob = globstr.replace('.', '\.')
20 glob = glob.replace('?', '.')
21 glob = glob.replace('*', '.*')
22 glob = re.compile('^%s$'%glob)
23 return glob
24
25class Directory(View):
26 """A view that lists the content of a directory."""
27
28 src_dir = Parameter('', 'starting point for directory listing')
29 base_path = Parameter('', 'path prefix to strip off of the file names')
30 exclude = Parameter([], 'TODO: define an exclusion mechanism (glob based ?)')
31
32 def filename(self):
33
34 return self.__filename
35
36 def title(self):
37
38 return 'Directory Listing'
39
40 def root(self):
41
42 if self.main:
43 url = self.directory_layout.index()
44 else:
45 url = self.directory_layout.special('dir')
46 return url, self.title()
47
48 def filename_for_dir(self, dir):
49 """Returns the output filename for the given input directory."""
50
51 if dir == self.src_dir:
52 return self.root()[0]
53 else:
54 scope = rel(self.src_dir, dir).split(os.sep)
55 return self.directory_layout.scoped_special('dir', scope)
56
57 def register(self, frame):
58
59 View.register(self, frame)
60 self._exclude = [compile_glob(e) for e in self.exclude]
61 self.__filename = self.root()[0]
62
63 def register_filenames(self):
64
65 dirs = [self.src_dir]
66 while dirs:
67 dir = dirs.pop(0)
68 for entry in os.listdir(os.path.abspath(dir)):
69 exclude = 0
70 for re in self._exclude:
71 if re.match(entry):
72 exclude = 1
73 break
74 if exclude:
75 continue
76 entry_path = os.path.join(dir, entry)
77 if os.path.isdir(entry_path):
78 filename = self.filename_for_dir(dir)
79 self.processor.register_filename(filename, self, entry_path)
80 dirs.append(entry_path)
81
82 def process(self):
83
84 self.process_dir(self.src_dir)
85
86 def process_dir(self, path):
87
88
89 self.__filename = self.filename_for_dir(path)
90
91
92 self.start_file()
93 self.write_navigation_bar()
94
95 root = ''
96 if self.base_path != self.src_dir:
97 rel(self.base_path, self.src_dir)
98 if not len(root) or root[-1] != '/': root = root + '/'
99 if path is self.src_dir:
100 self.write('<h1> '+root)
101 else:
102 self.write('<h1>' + href(self.root()[0], root + ' '))
103 dirscope = []
104 scope = rel(self.src_dir, path).split(os.sep)
105
106 for dir in scope[:-1]:
107 dirscope.append(dir)
108 dirlink = self.directory_layout.scoped_special('dir', dirscope)
109 dirlink = rel(self.filename(), dirlink)
110
111 self.write(href(dirlink, dir+'/ '))
112 if len(scope) > 0:
113 self.write(scope[-1]+'/')
114 self.write(' - Directory listing</h1>')
115
116 self.write('<table summary="Directory Listing">\n')
117 self.write('<tr><th align=left>Name</th>')
118 self.write('<th align="right">Size (bytes)</th>')
119 self.write('<th align="right">Last modified (GMT)</th></tr>\n')
120
121 entries = os.listdir(os.path.abspath(path))
122 entries.sort()
123 files = []
124 dirs = []
125 for entry in entries:
126 exclude = 0
127 for re in self._exclude:
128 if re.match(entry):
129 exclude = 1
130 break
131 if exclude:
132 continue
133 entry_path = os.path.join(path, entry)
134 info = os.stat(entry_path)
135 if stat.S_ISDIR(info[stat.ST_MODE]):
136
137 scope = rel(self.src_dir, entry_path).split(os.sep)
138 linkpath = self.directory_layout.scoped_special('dir', scope)
139 linkpath = rel(self.filename(), linkpath)
140 self.write('<tr><td>%s</td><td></td><td align="right">%s</td></tr>\n'%(
141 href(linkpath, entry+'/'),
142 time.asctime(time.gmtime(info[stat.ST_MTIME]))))
143 dirs.append(entry_path)
144 else:
145 files.append((entry_path, entry, info))
146
147 for path, entry, info in files:
148 size = info[stat.ST_SIZE]
149 timestr = time.asctime(time.gmtime(info[stat.ST_MTIME]))
150
151 path = path[len(self.base_path):]
152 if path[0] == '/': path = path[1:]
153 linkpath = self.directory_layout.file_source(path)
154 rego = self.processor.filename_info(linkpath)
155 if rego:
156 linkurl = rel(self.filename(), linkpath)
157 self.write('<tr><td>%s</td><td align="right">%d</td><td align="right">%s</td></tr>\n'%(
158 href(linkurl, entry, target='content'), size, timestr))
159 else:
160
161 self.write('<tr><td>%s</td><td align="right">%d</td><td align="right">%s</td></tr>\n'%(
162 entry, size, timestr))
163
164 self.write('</table>')
165 self.end_file()
166
167
168 for dir in dirs:
169 self.process_dir(dir)
170
171 def end_file(self):
172 """Overrides end_file to provide synopsis logo"""
173
174 self.write('\n')
175 now = time.strftime(r'%c', time.localtime(time.time()))
176 logo = img(src=rel(self.filename(), 'synopsis.png'), alt='logo')
177 logo = href('http://synopsis.fresco.org', logo + ' synopsis', target='_blank')
178 logo += ' (version %s)'%config.version
179 self.write(div('logo', 'Generated on ' + now + ' by \n<br/>\n' + logo))
180 View.end_file(self)
181
Generated on Thu Apr 16 16:27:15 2009 by
synopsis (version devel)