Skip to content

Commit

Permalink
Merge 863ca5a into 7304d3b
Browse files Browse the repository at this point in the history
  • Loading branch information
cslzchen committed Jun 19, 2018
2 parents 7304d3b + 863ca5a commit a4caaca
Show file tree
Hide file tree
Showing 121 changed files with 1,724 additions and 84 deletions.
184 changes: 168 additions & 16 deletions mfr/extensions/zip/render.py
Original file line number Diff line number Diff line change
@@ -1,36 +1,188 @@
import os
import zipfile
from typing import List, Union
from zipfile import ZipFile, ZipInfo

import markupsafe
from mako.lookup import TemplateLookup

from mfr.core import extension
from mfr.core.utils import sizeof_fmt
from mfr.core.extension import BaseRenderer


class ZipRenderer(extension.BaseRenderer):
class ZipRenderer(BaseRenderer):

TEMPLATE = TemplateLookup(
directories=[
os.path.join(os.path.dirname(__file__), 'templates')
]).get_template('viewer.mako')

def render(self):
zip_file = zipfile.ZipFile(self.file_path, 'r')

filelist = [{'name': markupsafe.escape(file.filename),
'size': sizeof_fmt(int(file.file_size)),
'date': "%d-%02d-%02d %02d:%02d:%02d" % file.date_time[:6]} for file in zip_file.filelist
if not file.filename.startswith('__MACOSX')]

message = '' if filelist else 'This zip file is empty.'

return self.TEMPLATE.render(zipped_filenames=filelist, message=message)

@property
def file_required(self):
return True

@property
def cache_result(self):
return True

def render(self):

zip_file = ZipFile(self.file_path, 'r')

# ``ZipFile.filelist`` contains both files and folder. Using ``obj`` for better clarity.
obj_list = self.sanitize_obj_list(zip_file.filelist)
obj_tree = self.obj_list_to_tree(obj_list)

return self.TEMPLATE.render(data=obj_tree, base=self.assets_url)

def obj_list_to_tree(self, obj_list: list) -> List[dict]:
"""Build the object tree from the object list. Each node is represented using a dictionary,
where non-leaf nodes represent folders and leaves represent files. Return a list which
contains only one element: the root node.
:param obj_list: the object list
:rtype: ``List[dict]``
:return: a list which contains only one element: the root node.
"""

# Build the root node of the tree
tree_root = {
'text': self.metadata.name + self.metadata.ext,
'icon': self.assets_url + '/img/file-ext-zip.png',
'children': []
}

for obj in obj_list:

# For each object, always start from the root of the tree
parent = tree_root
path_from_root = obj.filename
is_folder = path_from_root[-1] == '/'
path_segments = [segment for segment in path_from_root.split('/') if segment]
last_index = len(path_segments) - 1

# Iterate through the path segments list. Add the segment to tree if not already there
# and update the details with the current object if it is the last one along the path.
for index, segment in enumerate(path_segments):

# Check if the segment has already been added
siblings = parent.get('children', [])
current_node = self.find_node_among_siblings(segment, siblings)

# Found
if current_node:
if index == last_index:
# If it is the last segment, this node must be a folder and represents the
# current object. Update it with the objects' info and break.
assert is_folder
self.update_node_with_attributes(current_node, obj, is_folder=is_folder)
break
# Otherwise, jump to the next segment with the current node as the new parent
parent = current_node
continue

# Not found
new_node = {
'text': segment,
'children': [],
}
if index == last_index:
# If it is the last segment, the node represents the current object. Update the
# it with the objects' info, add it to the siblings and break.
self.update_node_with_attributes(new_node, obj, is_folder=is_folder)
siblings.append(new_node)
break

# Otherwise, append the new node to tree, jump to the next segment with the current
# node as the new parent
siblings.append(new_node)
parent = new_node
continue

return [tree_root, ]

def update_node_with_attributes(self, node: dict, obj: ZipInfo, is_folder: bool=True) -> None:
"""Update details (date, size, icon, etc.) of the node with the given object.
:param node: the node to update
:param obj: the object that the node represents
:param is_folder: the folder flag
"""

date = '%d-%02d-%02d %02d:%02d:%02d' % obj.date_time[:6]
size = sizeof_fmt(int(obj.file_size)) if obj.file_size else ''

if is_folder:
icon_path = self.assets_url + '/img/folder.png'
else:
ext = (os.path.splitext(obj.filename)[1].lstrip('.')).lower()
if self.icon_exists(ext):
icon_path = '{}/img/file-ext-{}.png'.format(self.assets_url, ext)
else:
icon_path = '{}/img/file-ext-generic.png'.format(self.assets_url)

node.update({
'icon': icon_path,
'data': {
'date': date,
'size': size,
},
})

@staticmethod
def icon_exists(ext: str) -> bool:
"""Check if an icon exists for the given file type. The extension string is converted to
lower case.
:param ext: the file extension str
:rtype: ``bool``
:return: ``True`` if found; ``False`` otherwise
"""

return os.path.isfile(os.path.join(
os.path.dirname(__file__),
'static',
'img',
'file-ext-{}.png'.format(ext.lower())
))

@staticmethod
def sanitize_obj_list(obj_list: list) -> list:
"""Remove macOS system and temporary files. Current implementation only removes '__MACOSX/'
and '.DS_Store'. If necessary, extend the sanitizer to exclude more file types.
:param obj_list: a list of full paths for each file and folder in the zip
:rtype: ``list``
:return: a sanitized list
"""

sanitized_obj_list = []

for obj in obj_list:

obj_path = obj.filename
# Ignore macOS '__MACOSX' folder for zip file
if obj_path.startswith('__MACOSX/'):
continue
# Ignore macOS '.DS_STORE' file
if obj_path == '.DS_Store' or obj_path.endswith('/.DS_Store'):
continue

sanitized_obj_list.append(obj)

return sanitized_obj_list

@staticmethod
def find_node_among_siblings(segment: str, siblings: list) -> Union[dict, None]:
"""Find if the folder or file represented by the path segment has already been added.
:param segment: the path segment
:param siblings: the list containing all added sibling nodes
:rtype: ``Union[dict, None]``
:return: the node if found or ``None`` otherwise
"""

for sibling in siblings:

if sibling.get('text', '') == segment:
return sibling

return None
Binary file added mfr/extensions/zip/static/img/file-ext-3gp.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added mfr/extensions/zip/static/img/file-ext-7z.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added mfr/extensions/zip/static/img/file-ext-ace.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added mfr/extensions/zip/static/img/file-ext-ai.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added mfr/extensions/zip/static/img/file-ext-aif.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added mfr/extensions/zip/static/img/file-ext-aiff.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added mfr/extensions/zip/static/img/file-ext-amr.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added mfr/extensions/zip/static/img/file-ext-asf.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added mfr/extensions/zip/static/img/file-ext-asx.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added mfr/extensions/zip/static/img/file-ext-bat.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added mfr/extensions/zip/static/img/file-ext-bin.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added mfr/extensions/zip/static/img/file-ext-bmp.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added mfr/extensions/zip/static/img/file-ext-bup.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added mfr/extensions/zip/static/img/file-ext-cab.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added mfr/extensions/zip/static/img/file-ext-cbr.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added mfr/extensions/zip/static/img/file-ext-cda.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added mfr/extensions/zip/static/img/file-ext-cdl.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added mfr/extensions/zip/static/img/file-ext-cdr.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added mfr/extensions/zip/static/img/file-ext-chm.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added mfr/extensions/zip/static/img/file-ext-dat.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added mfr/extensions/zip/static/img/file-ext-divx.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added mfr/extensions/zip/static/img/file-ext-dll.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added mfr/extensions/zip/static/img/file-ext-dmg.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added mfr/extensions/zip/static/img/file-ext-doc.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added mfr/extensions/zip/static/img/file-ext-docx.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added mfr/extensions/zip/static/img/file-ext-dss.png
Binary file added mfr/extensions/zip/static/img/file-ext-dvf.png
Binary file added mfr/extensions/zip/static/img/file-ext-dwg.png
Binary file added mfr/extensions/zip/static/img/file-ext-eml.png
Binary file added mfr/extensions/zip/static/img/file-ext-eps.png
Binary file added mfr/extensions/zip/static/img/file-ext-exe.png
Binary file added mfr/extensions/zip/static/img/file-ext-fla.png
Binary file added mfr/extensions/zip/static/img/file-ext-flv.png
Binary file added mfr/extensions/zip/static/img/file-ext-generic.png
Binary file added mfr/extensions/zip/static/img/file-ext-gif.png
Binary file added mfr/extensions/zip/static/img/file-ext-gz.png
Binary file added mfr/extensions/zip/static/img/file-ext-hqx.png
Binary file added mfr/extensions/zip/static/img/file-ext-htm.png
Binary file added mfr/extensions/zip/static/img/file-ext-html.png
Binary file added mfr/extensions/zip/static/img/file-ext-ifo.png
Binary file added mfr/extensions/zip/static/img/file-ext-indd.png
Binary file added mfr/extensions/zip/static/img/file-ext-iso.png
Binary file added mfr/extensions/zip/static/img/file-ext-jar.png
Binary file added mfr/extensions/zip/static/img/file-ext-jpeg.png
Binary file added mfr/extensions/zip/static/img/file-ext-jpg.png
Binary file added mfr/extensions/zip/static/img/file-ext-lnk.png
Binary file added mfr/extensions/zip/static/img/file-ext-log.png
Binary file added mfr/extensions/zip/static/img/file-ext-m4a.png
Binary file added mfr/extensions/zip/static/img/file-ext-m4b.png
Binary file added mfr/extensions/zip/static/img/file-ext-m4p.png
Binary file added mfr/extensions/zip/static/img/file-ext-m4v.png
Binary file added mfr/extensions/zip/static/img/file-ext-mcd.png
Binary file added mfr/extensions/zip/static/img/file-ext-mdb.png
Binary file added mfr/extensions/zip/static/img/file-ext-mid.png
Binary file added mfr/extensions/zip/static/img/file-ext-mov.png
Binary file added mfr/extensions/zip/static/img/file-ext-mp2.png
Binary file added mfr/extensions/zip/static/img/file-ext-mp3.png
Binary file added mfr/extensions/zip/static/img/file-ext-mp4.png
Binary file added mfr/extensions/zip/static/img/file-ext-mpeg.png
Binary file added mfr/extensions/zip/static/img/file-ext-mpg.png
Binary file added mfr/extensions/zip/static/img/file-ext-msi.png
Binary file added mfr/extensions/zip/static/img/file-ext-mswmm.png
Binary file added mfr/extensions/zip/static/img/file-ext-ogg.png
Binary file added mfr/extensions/zip/static/img/file-ext-pdf.png
Binary file added mfr/extensions/zip/static/img/file-ext-png.png
Binary file added mfr/extensions/zip/static/img/file-ext-pps.png
Binary file added mfr/extensions/zip/static/img/file-ext-ps.png
Binary file added mfr/extensions/zip/static/img/file-ext-psd.png
Binary file added mfr/extensions/zip/static/img/file-ext-pst.png
Binary file added mfr/extensions/zip/static/img/file-ext-ptb.png
Binary file added mfr/extensions/zip/static/img/file-ext-pub.png
Binary file added mfr/extensions/zip/static/img/file-ext-py.png
Binary file added mfr/extensions/zip/static/img/file-ext-qbb.png
Binary file added mfr/extensions/zip/static/img/file-ext-qbw.png
Binary file added mfr/extensions/zip/static/img/file-ext-qxd.png
Binary file added mfr/extensions/zip/static/img/file-ext-ram.png
Binary file added mfr/extensions/zip/static/img/file-ext-rar.png
Binary file added mfr/extensions/zip/static/img/file-ext-rm.png
Binary file added mfr/extensions/zip/static/img/file-ext-rmvb.png
Binary file added mfr/extensions/zip/static/img/file-ext-rtf.png
Binary file added mfr/extensions/zip/static/img/file-ext-sea.png
Binary file added mfr/extensions/zip/static/img/file-ext-ses.png
Binary file added mfr/extensions/zip/static/img/file-ext-sit.png
Binary file added mfr/extensions/zip/static/img/file-ext-sitx.png
Binary file added mfr/extensions/zip/static/img/file-ext-ss.png
Binary file added mfr/extensions/zip/static/img/file-ext-swf.png
Binary file added mfr/extensions/zip/static/img/file-ext-tgz.png
Binary file added mfr/extensions/zip/static/img/file-ext-thm.png
Binary file added mfr/extensions/zip/static/img/file-ext-tif.png
Binary file added mfr/extensions/zip/static/img/file-ext-tmp.png
Binary file added mfr/extensions/zip/static/img/file-ext-torrent.png
Binary file added mfr/extensions/zip/static/img/file-ext-ttf.png
Binary file added mfr/extensions/zip/static/img/file-ext-txt.png
Binary file added mfr/extensions/zip/static/img/file-ext-vcd.png
Binary file added mfr/extensions/zip/static/img/file-ext-vob.png
Binary file added mfr/extensions/zip/static/img/file-ext-wav.png
Binary file added mfr/extensions/zip/static/img/file-ext-wma.png
Binary file added mfr/extensions/zip/static/img/file-ext-wmv.png
Binary file added mfr/extensions/zip/static/img/file-ext-wps.png
Binary file added mfr/extensions/zip/static/img/file-ext-xls.png
Binary file added mfr/extensions/zip/static/img/file-ext-xlsx.png
Binary file added mfr/extensions/zip/static/img/file-ext-xpi.png
Binary file added mfr/extensions/zip/static/img/file-ext-zip.png
Binary file added mfr/extensions/zip/static/img/folder.png
4 changes: 4 additions & 0 deletions mfr/extensions/zip/static/js/jstree.min.js

Large diffs are not rendered by default.

0 comments on commit a4caaca

Please sign in to comment.