"""
open/dulcinea/lib/ui/browse.qpy
"""
from dulcinea.archive import TarFileWrapper, ZipFileWrapper
from qp.fill.stored_file import thumbnail_response
from qp.fill.directory import Directory
from qp.fill.html import htmltag, href
from qp.fill.static import FileStream
from qp.pub.common import get_request, get_response
from qp.pub.common import header, footer, not_found
import mimetypes
import tarfile
import zipfile
import sys
import os
from qp.fill.stored_file import guess_mime_type
class ArchiveDirectory (Directory):
def __init__(self, path_to_archive, path_in_archive='',
archive_wrapper=None, decorate=None, obj=None):
self.path_to_archive = path_to_archive
self.path_in_archive = path_in_archive
self.archive_wrapper = archive_wrapper
self.obj = obj
if decorate:
self.decorate = decorate
def get_archive_wrapper(self):
if not self.archive_wrapper:
if zipfile.is_zipfile(self.path_to_archive):
self.archive_wrapper = ZipFileWrapper(self.path_to_archive)
else:
self.archive_wrapper = TarFileWrapper(self.path_to_archive)
return self.archive_wrapper
def get_exports(self):
if self.path_in_archive:
crumb = self.path_in_archive.split('/')[-2]
else:
crumb = 'Browse'
yield ('', '_q_index', crumb, None)
def __call__(self):
if not self.path_in_archive:
get_response().set_content_type('application/octet-stream', None)
try:
stat = os.stat(self.path_to_archive)
except OSError:
print(sys.exc_info()[1])
not_found()
return FileStream(open(self.path_to_archive, 'rb'), length=stat.st_size)
def _q_lookup(self, component):
member_name = self.path_in_archive + component
if self.get_archive_wrapper().has_member(member_name): # file
return self.file_response(member_name)
member_name += '/'
# if not self.get_archive_wrapper().has_member(member_name): # not found
# return None
# directory
return self.__class__(self.path_to_archive,
path_in_archive=member_name,
archive_wrapper=self.archive_wrapper,
decorate=self.decorate,
obj=self.obj)
def file_response(self, member_name):
mime_type = guess_mime_type(member_name, fallback='text/plain')
get_response().set_content_type(mime_type, None)
return self.get_archive_wrapper().get_member_response(member_name)
def get_children(self):
child_name_slashes = self.path_in_archive.count('/')
children = [
name[len(self.path_in_archive):]
for name in self.get_archive_wrapper().get_names()
if (name.startswith(self.path_in_archive) and
child_name_slashes == name[:-1].count('/') and
name != '/')
]
return sorted(children)
def _q_index(self):
def directory:xml():
if self.path_in_archive.count('/') > 1:
href('..', '..')
'
'
else:
href('../..', '..')
'
'
for child in self.get_children():
href(child,
child, css_class="filename")
'
'
return self.decorate(self.obj,
directory(),
title=self.path_in_archive)
def decorate:xml(self, obj, content, title=None):
header(title)
'