root / trunk / twisted / web2 / dirlist.py

Revision 16161, 4.0 kB (checked in by wsanchez, 3 years ago)

Add content-type header to dirlist response

Line 
1 # Copyright (c) 2001-2004 Twisted Matrix Laboratories.
2 # See LICENSE for details.
3
4 """Directory listing."""
5
6 # system imports
7 import os
8 import urllib
9 import stat
10 import time
11
12 # twisted imports
13 from twisted.web2 import iweb, resource, http, http_headers
14
15 def formatFileSize(size):
16     if size < 1024:
17         return '%i' % size
18     elif size < (1024**2):
19         return '%iK' % (size / 1024)
20     elif size < (1024**3):
21         return '%iM' % (size / (1024**2))
22     else:
23         return '%iG' % (size / (1024**3))
24
25 class DirectoryLister(resource.Resource):
26     def __init__(self, pathname, dirs=None,
27                  contentTypes={},
28                  contentEncodings={},
29                  defaultType='text/html'):
30         self.contentTypes = contentTypes
31         self.contentEncodings = contentEncodings
32         self.defaultType = defaultType
33         # dirs allows usage of the File to specify what gets listed
34         self.dirs = dirs
35         self.path = pathname
36         resource.Resource.__init__(self)
37
38     def data_listing(self, request, data):
39         if self.dirs is None:
40             directory = os.listdir(self.path)
41             directory.sort()
42         else:
43             directory = self.dirs
44
45         files = []
46
47         for path in directory:
48             url = urllib.quote(path, '/')
49             fullpath = os.path.join(self.path, path)
50             try:
51                 st = os.stat(fullpath)
52             except OSError:
53                 continue
54             if stat.S_ISDIR(st.st_mode):
55                 url = url + '/'
56                 files.append({
57                     'link': url,
58                     'linktext': path + "/",
59                     'size': '',
60                     'type': '-',
61                     'lastmod': time.strftime("%Y-%b-%d %H:%M", time.localtime(st.st_mtime))
62                     })
63             else:
64                 from twisted.web2.static import getTypeAndEncoding
65                 mimetype, encoding = getTypeAndEncoding(
66                     path,
67                     self.contentTypes, self.contentEncodings, self.defaultType)
68                
69                 filesize = st.st_size
70                 files.append({
71                     'link': url,
72                     'linktext': path,
73                     'size': formatFileSize(filesize),
74                     'type': mimetype,
75                     'lastmod': time.strftime("%Y-%b-%d %H:%M", time.localtime(st.st_mtime))
76                     })
77
78         return files
79
80     def __repr__(self): 
81         return '<DirectoryLister of %r>' % self.path
82        
83     __str__ = __repr__
84
85
86     def render(self, request):
87         title = "Directory listing for %s" % urllib.unquote(request.path)
88    
89         s= """<html><head><title>%s</title><style>
90           th, .even td, .odd td { padding-right: 0.5em; font-family: monospace}
91           .even-dir { background-color: #efe0ef }
92           .even { background-color: #eee }
93           .odd-dir {background-color: #f0d0ef }
94           .odd { background-color: #dedede }
95           .icon { text-align: center }
96           .listing {
97               margin-left: auto;
98               margin-right: auto;
99               width: 50%%;
100               padding: 0.1em;
101               }
102
103           body { border: 0; padding: 0; margin: 0; background-color: #efefef;}
104           h1 {padding: 0.1em; background-color: #777; color: white; border-bottom: thin white dashed;}
105 </style></head><body><div class="directory-listing"><h1>%s</h1>""" % (title,title)
106         s+="<table>"
107         s+="<tr><th>Filename</th><th>Size</th><th>Last Modified</th><th>File Type</th></tr>"
108         even = False
109         for row in self.data_listing(request, None):
110             s+='<tr class="%s">' % (even and 'even' or 'odd',)
111             s+='<td><a href="%(link)s">%(linktext)s</a></td><td align="right">%(size)s</td><td>%(lastmod)s</td><td>%(type)s</td></tr>' % row
112             even = not even
113                
114         s+="</table></div></body></html>"
115         response = http.Response(200, {}, s)
116         response.headers.setHeader("content-type", http_headers.MimeType('text', 'html'))
117         return response
118
119 __all__ = ['DirectoryLister']
Note: See TracBrowser for help on using the browser.