a3d3c895d488fa7519d0135547f5310d9463fc4a
2 # -*- coding: utf-8 -*-
4 Outil de partage de fichiers.
6 Copyright : Agence universitaire de la Francophonie — www.auf.org
7 Licence : GNU General Public Licence, version 2
8 Auteur : Jean Christophe André
9 Date de création : 26 août 2010
11 Depends: libapache2-mod-wsgi
13 Attention : le code n'est pas encore “thread-safe”...
20 ROOT_PATH
= '/srv/www/compta'
21 PAGE_TITLE
= u
'Rapport financier du BAP <em>(%s)</em>'
22 BACKGROUND_URL
= 'Bamboo2.png'
23 EXCLUDED_FILES
= [ 'description.txt' ]
24 INVALID_NAME
= u
'%s <span class="alert">(NOM INVALIDE)</span>'
26 html_template_filename
= os
.path
.abspath(__file__
.rstrip('.py') + '.tpl')
27 dir_description_filename
= 'description.txt'
29 dir_link_template
= u
"""%s<li class="dir"><a href="javascript:void(0)" onclick="sw('l%s')">%s</a> <em>(%s) <a href="%s">archive du dossier</a></em> %s</li>"""
30 dir_description_template
= u
""" <em>%s</em>"""
31 begin_content_template
= u
"""%s<div id="l%s" class="hidden"><ul>"""
32 end_content_template
= u
"""%s</ul></div>"""
33 file_link_template
= u
"""%s<li><a href="%s">%s</a> <em>(%s)</em></li>"""
36 if os
.path
.islink('.' + path
):
38 if not os
.path
.isdir('.' + path
):
43 if size
<= 1: return "0 octet"
44 if size
< 1024: return "%s octets" % size
46 if size
< 1024: return "%s Kio" % size
48 if size
< 1024: return "%s Mio" % size
50 if size
< 1024: return "%s Gio" % size
52 return "%s Tio" % size
54 def my_cmp(name1
, name2
):
55 m1
= re
.match('[0-9]+', name1
)
56 m2
= re
.match('[0-9]+', name2
)
58 return cmp(name1
, name2
)
62 return cmp(name1
[m1
.end():], name2
[m2
.end():])
70 names
= os
.listdir(path
)
77 if not os
.path
.islink(p
):
83 files
.sort(cmp=my_cmp
)
89 def dir_content(prefix
, root
, level
=0):
90 dirs
, files
= my_listdir(root
)
91 if not len(dirs
) and not len(files
):
97 path
= root
.rstrip('/') + '/' + d
98 sub_dir_content
, sub_dir_size
= dir_content(prefix
, path
, level
+ 1)
99 file_size_total
+= sub_dir_size
103 name
= d
.replace('_',' ')
105 name
= name
.decode('utf-8')
106 except UnicodeDecodeError:
107 name
= INVALID_NAME
% name
.decode('latin-1')
108 desc_file
= '.' + path
+ '/' + dir_description_filename
109 if os
.path
.isfile(desc_file
):
110 desc
= file(desc_file
).read().strip().replace('\n',' ')
111 desc
= dir_description_template
% desc
.decode('utf-8')
114 archive_path
= (prefix
+ path
+ '.tar').decode('utf-8')
115 archive_size
= human_size(sub_dir_size
)
116 content
.append(dir_link_template
% \
117 (space
, id_number
, name
, archive_size
, archive_path
, desc
))
118 content
.append(begin_content_template
% (space
, id_number
))
119 content
.extend(sub_dir_content
)
120 content
.append(end_content_template
% space
)
122 path
= root
.rstrip('/') + '/' + f
123 file_size
= os
.path
.getsize('.' + path
)
124 file_size_total
+= file_size
125 if file_size
> 0 and f
not in EXCLUDED_FILES
:
126 name
= f
.replace('_',' ')
128 name
= name
.decode('utf-8')
129 except UnicodeDecodeError:
130 name
= INVALID_NAME
% name
.decode('latin-1')
131 content
.append( file_link_template
% (space
,
132 urllib
.quote(prefix
+ path
), name
, human_size(file_size
)) )
133 return content
, file_size_total
140 def write(self
, data
):
141 self
._data
.append(data
)
143 return ''.join(self
._data
)
145 def tar_generator(path
, mode
='w|', bufsize
=65536):
146 buffer = FileBuffer()
148 tar
= tarfile
.open(mode
=mode
, fileobj
=buffer, bufsize
=bufsize
)
149 for root
, dirs
, files
in os
.walk(path
):
151 tar
.add(os
.path
.join(root
, name
), recursive
=False)
152 #yield '+ file: %s\n' % os.path.join(root, name)
159 def application(environ
, start_response
):
163 if False and not environ
.get('HTTP_USER'):
164 headers
= [('Content-Type', 'text/plain; charset=utf-8'), ]
165 start_response('401 Authorization Required', headers
)
166 return ['Authorization Required']
167 path
= environ
['PATH_INFO']
168 if not valid_path(os
.path
.dirname(path
)):
169 headers
= [('Content-Type', 'text/plain; charset=utf-8'), ]
170 start_response('404 Not Found', headers
)
172 if os
.path
.isfile('.' + path
):
173 if path
.endswith('.txt'):
174 mime_type
= 'text/plain; charset=utf-8'
175 elif path
.endswith('.pdf'):
176 mime_type
= 'application/pdf'
178 mime_type
= 'application/octet-stream'
179 length
= str(os
.path
.getsize('.' + path
))
180 headers
= [('Content-Type', mime_type
), ('Content-Length', length
), ]
181 start_response('200 OK', headers
)
182 return file('.' + path
)
183 if path
.endswith('.tar') and os
.path
.isdir('.' + path
[:-4]):
184 #headers = [('Content-Type', 'text/plain; charset=utf-8'), ]
185 headers
= [('Content-Type', 'application/octet-stream'), ]
186 start_response('200 OK', headers
)
187 return tar_generator('.' + path
[:-4])
188 content
, size
= dir_content(environ
['SCRIPT_NAME'], environ
['PATH_INFO'])
190 'page_title': PAGE_TITLE
% human_size(size
),
191 'background_url': BACKGROUND_URL
,
192 'content': '<ul>\n' + '\n'.join(content
) + '\n</ul>',
194 html_template
= file(html_template_filename
).read().decode('utf-8')
195 content
= (html_template
% environ
).encode('utf-8')
196 headers
= [('Content-Type', 'text/html; charset=utf-8'), ]
197 start_response('200 OK', headers
)
200 if __name__
== '__main__':
201 # this runs when script is started directly from commandline
203 # create a simple WSGI server and run the application
204 from wsgiref
import simple_server
205 print "Running test application - point your browser at http://localhost:8000/ ..."
206 httpd
= simple_server
.WSGIServer(('', 8000), simple_server
.WSGIRequestHandler
)
207 httpd
.set_app(application
)
208 httpd
.serve_forever()
210 # wsgiref not installed, just output html to stdout
211 for content
in application({}, lambda status
, headers
: None):