Flask-AutoIndex-0.5/0000775000175000017500000000000012124040374015073 5ustar subleesublee00000000000000Flask-AutoIndex-0.5/docs/0000775000175000017500000000000012124040374016023 5ustar subleesublee00000000000000Flask-AutoIndex-0.5/docs/_themes/0000775000175000017500000000000012124040374017447 5ustar subleesublee00000000000000Flask-AutoIndex-0.5/docs/_themes/flask_theme_support.py0000644000175000017500000001141311436747640024114 0ustar subleesublee00000000000000# flasky extensions. flasky pygments style based on tango style from pygments.style import Style from pygments.token import Keyword, Name, Comment, String, Error, \ Number, Operator, Generic, Whitespace, Punctuation, Other, Literal class FlaskyStyle(Style): background_color = "#f8f8f8" default_style = "" styles = { # No corresponding class for the following: #Text: "", # class: '' Whitespace: "underline #f8f8f8", # class: 'w' Error: "#a40000 border:#ef2929", # class: 'err' Other: "#000000", # class 'x' Comment: "italic #8f5902", # class: 'c' Comment.Preproc: "noitalic", # class: 'cp' Keyword: "bold #004461", # class: 'k' Keyword.Constant: "bold #004461", # class: 'kc' Keyword.Declaration: "bold #004461", # class: 'kd' Keyword.Namespace: "bold #004461", # class: 'kn' Keyword.Pseudo: "bold #004461", # class: 'kp' Keyword.Reserved: "bold #004461", # class: 'kr' Keyword.Type: "bold #004461", # class: 'kt' Operator: "#582800", # class: 'o' Operator.Word: "bold #004461", # class: 'ow' - like keywords Punctuation: "bold #000000", # class: 'p' # because special names such as Name.Class, Name.Function, etc. # are not recognized as such later in the parsing, we choose them # to look the same as ordinary variables. Name: "#000000", # class: 'n' Name.Attribute: "#c4a000", # class: 'na' - to be revised Name.Builtin: "#004461", # class: 'nb' Name.Builtin.Pseudo: "#3465a4", # class: 'bp' Name.Class: "#000000", # class: 'nc' - to be revised Name.Constant: "#000000", # class: 'no' - to be revised Name.Decorator: "#888", # class: 'nd' - to be revised Name.Entity: "#ce5c00", # class: 'ni' Name.Exception: "bold #cc0000", # class: 'ne' Name.Function: "#000000", # class: 'nf' Name.Property: "#000000", # class: 'py' Name.Label: "#f57900", # class: 'nl' Name.Namespace: "#000000", # class: 'nn' - to be revised Name.Other: "#000000", # class: 'nx' Name.Tag: "bold #004461", # class: 'nt' - like a keyword Name.Variable: "#000000", # class: 'nv' - to be revised Name.Variable.Class: "#000000", # class: 'vc' - to be revised Name.Variable.Global: "#000000", # class: 'vg' - to be revised Name.Variable.Instance: "#000000", # class: 'vi' - to be revised Number: "#990000", # class: 'm' Literal: "#000000", # class: 'l' Literal.Date: "#000000", # class: 'ld' String: "#4e9a06", # class: 's' String.Backtick: "#4e9a06", # class: 'sb' String.Char: "#4e9a06", # class: 'sc' String.Doc: "italic #8f5902", # class: 'sd' - like a comment String.Double: "#4e9a06", # class: 's2' String.Escape: "#4e9a06", # class: 'se' String.Heredoc: "#4e9a06", # class: 'sh' String.Interpol: "#4e9a06", # class: 'si' String.Other: "#4e9a06", # class: 'sx' String.Regex: "#4e9a06", # class: 'sr' String.Single: "#4e9a06", # class: 's1' String.Symbol: "#4e9a06", # class: 'ss' Generic: "#000000", # class: 'g' Generic.Deleted: "#a40000", # class: 'gd' Generic.Emph: "italic #000000", # class: 'ge' Generic.Error: "#ef2929", # class: 'gr' Generic.Heading: "bold #000080", # class: 'gh' Generic.Inserted: "#00A000", # class: 'gi' Generic.Output: "#888", # class: 'go' Generic.Prompt: "#745334", # class: 'gp' Generic.Strong: "bold #000000", # class: 'gs' Generic.Subheading: "bold #800080", # class: 'gu' Generic.Traceback: "bold #a40000", # class: 'gt' } Flask-AutoIndex-0.5/docs/_themes/flask_small/0000775000175000017500000000000012124040374021737 5ustar subleesublee00000000000000Flask-AutoIndex-0.5/docs/_themes/flask_small/static/0000775000175000017500000000000012124040374023226 5ustar subleesublee00000000000000Flask-AutoIndex-0.5/docs/_themes/flask_small/static/flasky.css_t0000644000175000017500000001100111436747640025562 0ustar subleesublee00000000000000/* * flasky.css_t * ~~~~~~~~~~~~ * * Sphinx stylesheet -- flasky theme based on nature theme. * * :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ @import url("basic.css"); /* -- page layout ----------------------------------------------------------- */ body { font-family: 'Georgia', serif; font-size: 17px; color: #000; background: white; margin: 0; padding: 0; } div.documentwrapper { float: left; width: 100%; } div.bodywrapper { margin: 40px auto 0 auto; width: 700px; } hr { border: 1px solid #B1B4B6; } div.body { background-color: #ffffff; color: #3E4349; padding: 0 30px 30px 30px; } img.floatingflask { padding: 0 0 10px 10px; float: right; } div.footer { text-align: right; color: #888; padding: 10px; font-size: 14px; width: 650px; margin: 0 auto 40px auto; } div.footer a { color: #888; text-decoration: underline; } div.related { line-height: 32px; color: #888; } div.related ul { padding: 0 0 0 10px; } div.related a { color: #444; } /* -- body styles ----------------------------------------------------------- */ a { color: #004B6B; text-decoration: underline; } a:hover { color: #6D4100; text-decoration: underline; } div.body { padding-bottom: 40px; /* saved for footer */ } div.body h1, div.body h2, div.body h3, div.body h4, div.body h5, div.body h6 { font-family: 'Garamond', 'Georgia', serif; font-weight: normal; margin: 30px 0px 10px 0px; padding: 0; } {% if theme_index_logo %} div.indexwrapper h1 { text-indent: -999999px; background: url({{ theme_index_logo }}) no-repeat center center; height: {{ theme_index_logo_height }}; } {% endif %} div.body h2 { font-size: 180%; } div.body h3 { font-size: 150%; } div.body h4 { font-size: 130%; } div.body h5 { font-size: 100%; } div.body h6 { font-size: 100%; } a.headerlink { color: white; padding: 0 4px; text-decoration: none; } a.headerlink:hover { color: #444; background: #eaeaea; } div.body p, div.body dd, div.body li { line-height: 1.4em; } div.admonition { background: #fafafa; margin: 20px -30px; padding: 10px 30px; border-top: 1px solid #ccc; border-bottom: 1px solid #ccc; } div.admonition p.admonition-title { font-family: 'Garamond', 'Georgia', serif; font-weight: normal; font-size: 24px; margin: 0 0 10px 0; padding: 0; line-height: 1; } div.admonition p.last { margin-bottom: 0; } div.highlight{ background-color: white; } dt:target, .highlight { background: #FAF3E8; } div.note { background-color: #eee; border: 1px solid #ccc; } div.seealso { background-color: #ffc; border: 1px solid #ff6; } div.topic { background-color: #eee; } div.warning { background-color: #ffe4e4; border: 1px solid #f66; } p.admonition-title { display: inline; } p.admonition-title:after { content: ":"; } pre, tt { font-family: 'Consolas', 'Menlo', 'Deja Vu Sans Mono', 'Bitstream Vera Sans Mono', monospace; font-size: 0.85em; } img.screenshot { } tt.descname, tt.descclassname { font-size: 0.95em; } tt.descname { padding-right: 0.08em; } img.screenshot { -moz-box-shadow: 2px 2px 4px #eee; -webkit-box-shadow: 2px 2px 4px #eee; box-shadow: 2px 2px 4px #eee; } table.docutils { border: 1px solid #888; -moz-box-shadow: 2px 2px 4px #eee; -webkit-box-shadow: 2px 2px 4px #eee; box-shadow: 2px 2px 4px #eee; } table.docutils td, table.docutils th { border: 1px solid #888; padding: 0.25em 0.7em; } table.field-list, table.footnote { border: none; -moz-box-shadow: none; -webkit-box-shadow: none; box-shadow: none; } table.footnote { margin: 15px 0; width: 100%; border: 1px solid #eee; } table.field-list th { padding: 0 0.8em 0 0; } table.field-list td { padding: 0; } table.footnote td { padding: 0.5em; } dl { margin: 0; padding: 0; } dl dd { margin-left: 30px; } pre { padding: 0; margin: 15px -30px; padding: 8px; line-height: 1.3em; padding: 7px 30px; background: #eee; border-radius: 2px; -moz-border-radius: 2px; -webkit-border-radius: 2px; } dl pre { margin-left: -60px; padding-left: 60px; } tt { background-color: #ecf0f3; color: #222; /* padding: 1px 2px; */ } tt.xref, a tt { background-color: #FBFBFB; } a:hover tt { background: #EEE; } Flask-AutoIndex-0.5/docs/_themes/flask_small/layout.html0000644000175000017500000000125311436747640024160 0ustar subleesublee00000000000000{% extends "basic/layout.html" %} {% block header %} {{ super() }} {% if pagename == 'index' %}
{% endif %} {% endblock %} {% block footer %} {% if pagename == 'index' %}
{% endif %} {% endblock %} {# do not display relbars #} {% block relbar1 %}{% endblock %} {% block relbar2 %} {% if theme_github_fork %} Fork me on GitHub {% endif %} {% endblock %} {% block sidebar1 %}{% endblock %} {% block sidebar2 %}{% endblock %} Flask-AutoIndex-0.5/docs/_themes/flask_small/theme.conf0000644000175000017500000000027011436747640023724 0ustar subleesublee00000000000000[theme] inherit = basic stylesheet = flasky.css nosidebar = true pygments_style = flask_theme_support.FlaskyStyle [options] index_logo = '' index_logo_height = 120px github_fork = '' Flask-AutoIndex-0.5/docs/_themes/LICENSE0000644000175000017500000000337511436747640020501 0ustar subleesublee00000000000000Copyright (c) 2010 by Armin Ronacher. Some rights reserved. Redistribution and use in source and binary forms of the theme, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * The names of the contributors may not be used to endorse or promote products derived from this software without specific prior written permission. We kindly ask you to only use these themes in an unmodified manner just for Flask and Flask-related products, not for unrelated projects. If you like the visual style and want to use it for your own projects, please consider making some larger changes to the themes (such as changing font faces, sizes, colors or margins). THIS THEME IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS THEME, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Flask-AutoIndex-0.5/docs/_themes/flask/0000775000175000017500000000000012124040374020547 5ustar subleesublee00000000000000Flask-AutoIndex-0.5/docs/_themes/flask/static/0000775000175000017500000000000012124040374022036 5ustar subleesublee00000000000000Flask-AutoIndex-0.5/docs/_themes/flask/static/flasky.css_t0000644000175000017500000001413111436747640024401 0ustar subleesublee00000000000000/* * flasky.css_t * ~~~~~~~~~~~~ * * :copyright: Copyright 2010 by Armin Ronacher. * :license: Flask Design License, see LICENSE for details. */ {% set page_width = '940px' %} {% set sidebar_width = '220px' %} @import url("basic.css"); /* -- page layout ----------------------------------------------------------- */ body { font-family: 'Georgia', serif; font-size: 17px; background-color: white; color: #000; margin: 0; padding: 0; } div.document { width: {{ page_width }}; margin: 30px auto 0 auto; } div.documentwrapper { float: left; width: 100%; } div.bodywrapper { margin: 0 0 0 {{ sidebar_width }}; } div.sphinxsidebar { width: {{ sidebar_width }}; } hr { border: 1px solid #B1B4B6; } div.body { background-color: #ffffff; color: #3E4349; padding: 0 30px 0 30px; } img.floatingflask { padding: 0 0 10px 10px; float: right; } div.footer { width: {{ page_width }}; margin: 20px auto 30px auto; font-size: 14px; color: #888; text-align: right; } div.footer a { color: #888; } div.related { display: none; } div.sphinxsidebar a { color: #444; text-decoration: none; border-bottom: 1px dotted #999; } div.sphinxsidebar a:hover { border-bottom: 1px solid #999; } div.sphinxsidebar { font-size: 14px; line-height: 1.5; } div.sphinxsidebarwrapper { padding: 18px 10px; } div.sphinxsidebarwrapper p.logo { padding: 0 0 20px 0; margin: 0; text-align: center; } div.sphinxsidebar h3, div.sphinxsidebar h4 { font-family: 'Garamond', 'Georgia', serif; color: #444; font-size: 24px; font-weight: normal; margin: 0 0 5px 0; padding: 0; } div.sphinxsidebar h4 { font-size: 20px; } div.sphinxsidebar h3 a { color: #444; } div.sphinxsidebar p.logo a, div.sphinxsidebar h3 a, div.sphinxsidebar p.logo a:hover, div.sphinxsidebar h3 a:hover { border: none; } div.sphinxsidebar p { color: #555; margin: 10px 0; } div.sphinxsidebar ul { margin: 10px 0; padding: 0; color: #000; } div.sphinxsidebar input { border: 1px solid #ccc; font-family: 'Georgia', serif; font-size: 1em; } /* -- body styles ----------------------------------------------------------- */ a { color: #004B6B; text-decoration: underline; } a:hover { color: #6D4100; text-decoration: underline; } div.body h1, div.body h2, div.body h3, div.body h4, div.body h5, div.body h6 { font-family: 'Garamond', 'Georgia', serif; font-weight: normal; margin: 30px 0px 10px 0px; padding: 0; } div.body h1 { margin-top: 0; padding-top: 0; font-size: 240%; } div.body h2 { font-size: 180%; } div.body h3 { font-size: 150%; } div.body h4 { font-size: 130%; } div.body h5 { font-size: 100%; } div.body h6 { font-size: 100%; } a.headerlink { color: #ddd; padding: 0 4px; text-decoration: none; } a.headerlink:hover { color: #444; background: #eaeaea; } div.body p, div.body dd, div.body li { line-height: 1.4em; } div.admonition { background: #fafafa; margin: 20px -30px; padding: 10px 30px; border-top: 1px solid #ccc; border-bottom: 1px solid #ccc; } div.admonition tt.xref, div.admonition a tt { border-bottom: 1px solid #fafafa; } dd div.admonition { margin-left: -60px; padding-left: 60px; } div.admonition p.admonition-title { font-family: 'Garamond', 'Georgia', serif; font-weight: normal; font-size: 24px; margin: 0 0 10px 0; padding: 0; line-height: 1; } div.admonition p.last { margin-bottom: 0; } div.highlight { background-color: white; } dt:target, .highlight { background: #FAF3E8; } div.note { background-color: #eee; border: 1px solid #ccc; } div.seealso { background-color: #ffc; border: 1px solid #ff6; } div.topic { background-color: #eee; } p.admonition-title { display: inline; } p.admonition-title:after { content: ":"; } pre, tt { font-family: 'Consolas', 'Menlo', 'Deja Vu Sans Mono', 'Bitstream Vera Sans Mono', monospace; font-size: 0.9em; } img.screenshot { } tt.descname, tt.descclassname { font-size: 0.95em; } tt.descname { padding-right: 0.08em; } img.screenshot { -moz-box-shadow: 2px 2px 4px #eee; -webkit-box-shadow: 2px 2px 4px #eee; box-shadow: 2px 2px 4px #eee; } table.docutils { border: 1px solid #888; -moz-box-shadow: 2px 2px 4px #eee; -webkit-box-shadow: 2px 2px 4px #eee; box-shadow: 2px 2px 4px #eee; } table.docutils td, table.docutils th { border: 1px solid #888; padding: 0.25em 0.7em; } table.field-list, table.footnote { border: none; -moz-box-shadow: none; -webkit-box-shadow: none; box-shadow: none; } table.footnote { margin: 15px 0; width: 100%; border: 1px solid #eee; background: #fdfdfd; font-size: 0.9em; } table.footnote + table.footnote { margin-top: -15px; border-top: none; } table.field-list th { padding: 0 0.8em 0 0; } table.field-list td { padding: 0; } table.footnote td.label { width: 0px; padding: 0.3em 0 0.3em 0.5em; } table.footnote td { padding: 0.3em 0.5em; } dl { margin: 0; padding: 0; } dl dd { margin-left: 30px; } blockquote { margin: 0 0 0 30px; padding: 0; } ul, ol { margin: 10px 0 10px 30px; padding: 0; } pre { background: #eee; padding: 7px 30px; margin: 15px -30px; line-height: 1.3em; } dl pre, blockquote pre, li pre { margin-left: -60px; padding-left: 60px; } dl dl pre { margin-left: -90px; padding-left: 90px; } tt { background-color: #ecf0f3; color: #222; /* padding: 1px 2px; */ } tt.xref, a tt { background-color: #FBFBFB; border-bottom: 1px solid white; } a.reference { text-decoration: none; border-bottom: 1px dotted #004B6B; } a.reference:hover { border-bottom: 1px solid #6D4100; } a.footnote-reference { text-decoration: none; font-size: 0.7em; vertical-align: top; border-bottom: 1px dotted #004B6B; } a.footnote-reference:hover { border-bottom: 1px solid #6D4100; } a:hover tt { background: #EEE; } Flask-AutoIndex-0.5/docs/_themes/flask/static/small_flask.css0000644000175000017500000000172011436747640025055 0ustar subleesublee00000000000000/* * small_flask.css_t * ~~~~~~~~~~~~~~~~~ * * :copyright: Copyright 2010 by Armin Ronacher. * :license: Flask Design License, see LICENSE for details. */ body { margin: 0; padding: 20px 30px; } div.documentwrapper { float: none; background: white; } div.sphinxsidebar { display: block; float: none; width: 102.5%; margin: 50px -30px -20px -30px; padding: 10px 20px; background: #333; color: white; } div.sphinxsidebar h3, div.sphinxsidebar h4, div.sphinxsidebar p, div.sphinxsidebar h3 a { color: white; } div.sphinxsidebar a { color: #aaa; } div.sphinxsidebar p.logo { display: none; } div.document { width: 100%; margin: 0; } div.related { display: block; margin: 0; padding: 10px 0 20px 0; } div.related ul, div.related ul li { margin: 0; padding: 0; } div.footer { display: none; } div.bodywrapper { margin: 0; } div.body { min-height: 0; padding: 0; } Flask-AutoIndex-0.5/docs/_themes/flask/relations.html0000644000175000017500000000111611436747640023451 0ustar subleesublee00000000000000

Related Topics

Flask-AutoIndex-0.5/docs/_themes/flask/layout.html0000644000175000017500000000110611436747640022765 0ustar subleesublee00000000000000{%- extends "basic/layout.html" %} {%- block extrahead %} {{ super() }} {% if theme_touch_icon %} {% endif %} {% endblock %} {%- block relbar2 %}{% endblock %} {%- block footer %} {%- endblock %} Flask-AutoIndex-0.5/docs/_themes/flask/theme.conf0000644000175000017500000000017211436747640022535 0ustar subleesublee00000000000000[theme] inherit = basic stylesheet = flasky.css pygments_style = flask_theme_support.FlaskyStyle [options] touch_icon = Flask-AutoIndex-0.5/docs/_themes/README0000644000175000017500000000210511436747640020342 0ustar subleesublee00000000000000Flask Sphinx Styles =================== This repository contains sphinx styles for Flask and Flask related projects. To use this style in your Sphinx documentation, follow this guide: 1. put this folder as _themes into your docs folder. Alternatively you can also use git submodules to check out the contents there. 2. add this to your conf.py: sys.path.append(os.path.abspath('_themes')) html_theme_path = ['_themes'] html_theme = 'flask' The following themes exist: - 'flask' - the standard flask documentation theme for large projects - 'flask_small' - small one-page theme. Intended to be used by very small addon libraries for flask. The following options exist for the flask_small theme: [options] index_logo = '' filename of a picture in _static to be used as replacement for the h1 in the index.rst file. index_logo_height = 120px height of the index logo github_fork = '' repository name on github for the "fork me" badge Flask-AutoIndex-0.5/docs/index.rst0000664000175000017500000001160212123622634017670 0ustar subleesublee00000000000000Flask-AutoIndex ~~~~~~~~~~~~~~~ .. module:: flask_autoindex Flask-AutoIndex generates an index page for your `Flask`_ application automatically. The result just like `mod_autoindex`_, but the look is more awesome! Look at this: .. figure:: _static/example.png :alt: The screenshot of index page generated by Flask-AutoIndex This module contains pre-designed template and css file. It is default style, but you can make your own style. .. _Flask: http://flask.pocoo.org/ .. _mod_autoindex: http://httpd.apache.org/docs/current/mod/mod_autoindex.html Installation ============ Install Flask-AutoIndex with ``easy_install`` or ``pip`` command:: $ easy_install Flask-AutoIndex :: $ pip install Flask-AutoIndex or check out development version:: $ git clone git://github.com/sublee/flask-autoindex.git How to Use ========== Flask-AutoIndex is easy and extensible. It supports flask application. We will make the application in flask application. There is a basic usage:: import os.path from flask import Flask from flask.ext.autoindex import AutoIndex app = Flask(__name__) AutoIndex(app, browse_root=os.path.curdir) if __name__ == '__main__': app.run() After running the application, ``http://localhost/`` serves a generated index page which contains the file and directory list in current directory. Customizing =========== Routing a specified URL ``````````````````````` Just like a nomal flask application or module. Follow the below example:: @app.route('/helloworld') def helloworld(): return 'Hello, world!', 200 ``http://localhost/helloworld`` will serve ``Hello, world!`` not ``/helloworld`` directory. Adding an icon rule ``````````````````` If you want to present ``*.feed`` files with ``rss.png`` icon and present a directory named ``picture`` with ``folder_picture.png`` icon, follow the below example:: idx.add_icon_rule('rss.png', ext='feed') idx.add_icon_rule('folder_picture.png', dirname='pictures') You can change the root directory's icon to your own icon:: idx.add_icon_rule('http://example.org/favicon.ico', cls=RootDirectory) Also you can add the more complex rule with a function:: import re def is_flaskext(ent): return isinstance(ent, Directory) and re.match('[Ff]lask-', ent.name) idx.add_icon_rule('http://example.org/flask-extenstion.png', is_flaskext) Here is a nice example for changing directory's icon to its ``favicon.ico`` file if it exists:: def get_favicon(ent): favicon = 'favicon.ico' if type(ent) is Directory and favicon in ent: return '/' + os.path.join(ent.path, favicon) return False idx.add_icon_rule(get_favicon) .. seealso:: :meth:`AutoIndex.add_icon_rule` Changing Silk's path ```````````````````` :class:`AutoIndex` has ``**silk_options`` keyword arguments for :class:`Silk`. If you want to use the another path for serving silk icons, use ``silk_path`` keyword argument:: idx = AutoIndex(app, silk_path='/myicons') Now you can get a silk icon from ``http://localhost/myicons/folder.png`` not ``http://localhost/__icons__/folder.png``. .. seealso:: The documentation for `Flask-Silk `_ Redesigning the template ```````````````````````` :meth:`AutoIndex.render_autoindex` finds the template from the application's template directory first. When you made the ``autoindex.html`` to the application's template directory, :meth:`AutoIndex.render_autoindex` renders your template:: - myapplication - templates - autoindex.html - __init__.py - views.py Your templates could extend the default Flask-AutoIndex's template, it named ``__autoindex__/autoindex.html``. Here is a basic example: .. sourcecode:: jinja {% extends '__autoindex__/autoindex.html' %} {% block meta %} {{ super() }} {% endblock %} {% block header %}

My Application

{% endblock %} {% block footer %}
{% endblock %} API === Configuration ````````````` .. autoclass:: AutoIndex :members: Models `````` .. autoclass:: Entry :members: .. autoclass:: File :members: .. autoclass:: Directory :members: .. autoclass:: RootDirectory :members: Template ```````` Blocks ------ `meta` The innerHTML of ````. `header` The top of ````. `table` The table for the entry list. `footer` The bottom of ````. Variables --------- `curdir` The current directory object. `entries` The child entry list of ``curdir``. `sort_by` The sorting key. `order` Ascending order(``1``) or Descending order(``-1``). `endpoint` The endpoint which renders a generated page. Indices and tables ================== * :ref:`genindex` * :ref:`modindex` * :ref:`search` Flask-AutoIndex-0.5/docs/_static/0000775000175000017500000000000012124040374017451 5ustar subleesublee00000000000000Flask-AutoIndex-0.5/docs/_static/example.png0000644000175000017500000006012611437371571021631 0ustar subleesublee00000000000000PNG  IHDR}jS'tEXtSoftwareAdobe ImageReadyqe<_IDATx t[y4DYL 2-:eYr k]V ^[Z5&avP'6K*̚ mG("Lj#cb5d($<}^88AD[X$Ϸo}8PqZXh.w V=kn7Zn.__=1}g=t,+ʨf:3Xo}-7՚ 덿Jܤ~F³z?3HOh_!A)DVF볦=ƤT*|_ΜJK|%RSB359ϳdh+שw]۞|)Ϸ  s~-Wصѣz{ɷbۺ^w^fsm]=Ƃ\ !+!|d5PO vzG [FNI ef][+e>|tY 2O+|)ӧ'R.hsU`Cko+D>=L^_y>;2_{44`,4#m?=~X) S+O( ޏ@+yKSSh?wEi묝m-/=3O577 #!;QwCnyOc~WL49'?FAzϜ9f7'B1j?*/pG7V3;$y_18"#/IdE={7wQ_{T{{|?ܩ;O;ѣGE.>`yO{繗yRx}߰8}eQ~T+?a=v店1sw;+{ s靦Yum`Ia,{ighS ;-g{G|E7)[qC|N烆7'Bxj?ѣf^cz||J.y<`[-"&DJGP"7>g~Ǎgsu?#:yhH vEMsUޟ{c9dzgO }_Gfyg_<bCe+|FU\N#їo?z-ojaI!L,ww @w֙]@_>H!e0>>^SS3˨uuuh.5Z ܜ{g>|=Q~'a,$e/^wgfOϟ&MOk=u..?RXTӸ]>q7)}Pg `-Iv=I}|c1SO5ozgT zIO?|գI(D]"vcǒE`3I/kyonx5ƳT~iN,K|"ZKJد((ώ{㵟WGI6.{* (_BQfI~џݕP]ݺik̿ 캾 GӇ?ڵرRIJ:*Ϛ9ǘޭ OlIwa~pÏh֙b~[/IKa~w;>ow ~Rw7g~mXR.2DNz꒳hq{%Š)yp$&!~W&Uǐ)1U~*۰C? b0KOSWsԥ`qFv)Y!'Uo>;k,K7. %,~f(wLU"@+˃8<`].Byfw?F@*t> 2܌$n_5q?o U6YՋx-@u@gFG,^JdYpG]O.ǏN$u%oYTw> o_uMɼ4J*GQQtP_DQY*5JfY^pT|_;;u"})GՅOͶ6H.:NI?q?\Qcd6k Ӭ0q; *WolEWګ@@\R5ՀH(`y@&D7C2"Vns0[B)YzƫU$wwX20HF=Jڨ4Qmp3ʍo~u2յt4\U&ZK֬X[X.YG]ku6=K`EW[~CZbP,S˞,5+){ Kolb>tQ;XB^%"#`FuKK gjj7-e5c؎$bאfY8SܾXݤX{oow7|篮|Dbɫ Q#)_n{TąfF\9Iʛ H5z96]ڳ^j 3Bt )P&K9VX=l[ //݉r;6SzHE-o2~#g'ǪTWl۱dƯY[w}{a{h<wALn]pYP2̽bkԊ[%FTH?yfrW BXeT-/37G}pRAEKk[csD+"x$\2,pcVJ]Vc^kxG,D>f_&SOm۔!m>sgRt:d.C7uRTG){ 3N;Q,%Ă[A^a)DA9E.cK3qGtL[ha^SaM$XV[{<Ԧd:ѨGSS_#l?hmúJ: H9QTv᫒3jl#݋UvDPs5Ԗ7\Q]o _<'6?Շv߻oz6ʻZ[,>m_ޫ4f/ɽ< `UZ+(奬x!geו%,P$jE*wQ?bfZtRw<BydiRNi~:VOH ~ٕ"~] ].t* 3#t t]$8ό],g*m;  sk0ykUhA`Q|/`0 s`H^{L0XSsx˭crx-͡>R%ݤ|Zd{+ވK+HЊjtXy$;?w[W?S?9udMUuW7[lln}MB#@r9K-5x]qw( PcxbFTraaAݡV6(=p6*O~`˳,Zӛ<3"\v>3_eS3c?KS'=u7uǽ{Ӆ51\dH돔{{#%*6<_r8nArXicawc?b浆)O8*d9 B ZsWY~@\eɚ.ͦg毒K3/mڻs{붿nNjwx讪oYpiw|7V8}7ˆwwX20HF=yF= r_rLKm=9M%:B4oYeɚ$KRƪzѯַ޵=;fܡ̎kW?qe?&sפ5YlyDVCeJKgjh"Œ¶1.E^g#D+4bA\k:/Թ7oBnEXIXgWmV?uuu_WLبPiiWLM-h ߘZ#5Yʹ4 vM,q)ײd#nLM.3~?}?.Rfrs(fq}%W~GPXt0zȠz+?TdR-Yx 2fe } 6'и®(=)N\8a$. "Fk_)Xs){QaaQo2Pt,ƕCGa-t:t'7c$lG-oNUl::?.uKeS糩 ƒd`]uk.L'uiU*QɃ@o\ڙdۻH96k/-#Y.RP6/Hk'VaVb%s)^ \S&'HpRAu#֡ؔ\7WqdNdQ8\B [" M.oR}^l )b .=Υ'#3ť%.3eg wK.;gvagk$6ꙹkk񅛁X,fr?t.hN)qH eoW }ԎI2OʌEv AȪ'-*`311QN][?⤟M6}}6Ot*,D"*x#)eu4'.@`0FAssYeRU#u]Չԕ_m2Խΐ¿4CZK7eE饚ە;ICż殳mw4ZVɞo]~f:mZX¹+>bbDrig7)AxF=k $lEIo{Ur  Y骄po=_םv?x@#awVŻ{ DHYiR2`vT.ɯ/=9*K.K< sΥ-P.u;D.nETon*%BgXR+ldNaF4 {{-vˀ\!8Vuf{8Z"L2nܛWzA9BSJ3:i-\ y+!/(Ҕplw i4rؼ[;&=e,5ZQ56kF$u![Msu\=SGTU7zufKW1d~qW߯@&g_ 1Z;X1z6k S0qF#*>` -(Nj^MZfO9, \Nkܔ.ͦg毒K3/mڻs{붿nNjwx讪q cug6VpaC '+Ik/Ar8nE'\ekh9:dYNkܔKRƪzѯַ޵=;fܡ̎kW?qe?&sEtWZ8ȭ%* " >妮I&60T [c,}R6Z7&H"v iS^usp>Mt]VX.5#?zӄfLr\z22S$M_NqK\fpsԬ1=짓A@]mRMvݡ(߹4`eXN頶T[}p8݉>N:E;V\ҷƊw s.ΦegKRcl4+/ -}+8BJ'+{kghs7/:l5ϝOsfNYSUݸ͖-=[_Ǽ_}}Q.`ePcx#bP+t 13*?NԱežY3s)e35\֘>53 4uS'|Sǿ9y;y'=?>]Rо-b (#䎻q.u?b浆[8DfTD[hAQtUk檃O!sձ)].;M_%g_Z۴w^]Wmaݎ]U{7I@uf3B;bhDvimT6HͶ6B_W%Wɬ%-Yq(';2V_sd ;ΟNO q\5D³$WP݊p;oh3!:h !/uuuN29u8oiG9SS 3.a5cI^F1Ҽ4#ћձ8+zmw 42ӗIMSB uhv,77͏r)8K9jV`Z㊻CC{| F9!I@t:0vo^:^$9qMXcAKB6!sUs.ΦegKRcl4u}#ns>tѭf|8)c&wP?M0C̵-#5|#)XǢ#ECVz[ wS@2\zK_ҿ1'e.s-A 'e0;TF4Qrp{*6), $HG{QXa_ ׆,UG,/Gg`=}u"udjp uo9#k0f23$SK3؜j*zsbn/; =NBO6gbc.Z131rhU^`y8M4{5uԷzucpb҄|O/gG_=ljZ?G Uw>gO"UD~ a\U%*|fH0wWtčϺᱎE$h9!fW"zGs8b(3n ewDw.\?V#],8W@%yfttX \ ] Q ~`]a.bw ƚP 2BנE|mT؅,]+U%%ief3/ԅ@YnnRqpsLc:]qwHXrhOH:˷ ",H$&lvEX! IRVg7J //݉.]?z֊ [J=ȮM \6Mc-q''+<9.Mt}~qv6quK7H\9)LroEG!Ňj|P:6BUK_)'Bx,H,A鵅5XH$QrXx[ϕo*麗d8ȥ.1 0}\2Wt@~Ap "fD~*z.]Ɩf")JqOVFv)K:D"1^a˴t:QۜU(fM"  [FҐ.X.J=ϬjՉԕ_m2ԽΐL/͐g/cKBtu XnO/#vkiXDWDG\I#zXXIbq.2^S'|A5Q^ZN%,UՈDvՓ?Ϧ#qPU}{6TA䝎f;sM4!-NKA6ӝ0q/*olEWRw)3ˤ_kv8̥Ӽ].;M_%g_Z۴w^]Wmaݎ]U{7I@wLm6^k"ḻ*A*VO4iW FjSn|Ka~uΒp.7jm{m=wmΟ?whn;#f>O\z`b>zC!wSUd*\4qՂ$*tȖ&qAԢoZFk@$IĮ!kzx)]Wd),AG\$ ^%2d65eH24標n/GEK-&AB]v}-hqZk 13j9 Kw>Sb{-v7Q:.C`G:˼lF~8@ DWg [a9MgScsl|6uAxp\]R ;t:M!lBQzb6 Ah7 5I1Mnɐ[vdmQ*.XbD~7~nHKSO|rYBznBІ_8څ-bv5.:OFi_M|=Nvw*DV85򳥙#N+$Go.6H$b뇽qwڔR)I$47w7[r7/U#:k0ޞ:RCwp\5K\53)K3+L ^v{'Qev(6r{}Sig.?IooOk5VБVDʉפ󯎨BzH='ŬYNN;;EK=y(\ՉDvՓ?Ϧ#qPU}{66hoYҞ+{/G.~Wʬb̥;#yfVr(>tD:*+LNqYXk[__tJ'i&*',|^&7.:bY],@ ׏U.KUw.PIpV8W@%*tt`!<3|Tiy`5dWˤ]&S^`B Sg0O#Czg;[nw5dIv~~~0sȚ]nl=/h>hN7"EB@g )0٠M9䫍6`:4qC."\v>3_eS3c?KS'=u7uǽ{INZ]SK]sDA (#䎻xex]χyQbJ&dõ;$y!.GGܘ&\f6{\f\ғ]dқ;M9jӄ{['-C{rJLh`>p h4#j 0V*&LRZ=nѧciНԁv@!Rv'á"sUs.ΦegKRcl4+#&c=4_tEf|8)&wSM smˈ"av !Q5Mmp-><妻L $åǩ >nz{Ypv,[Nk߸OZ MHJ111Q})'En  K~?w*kx>;999>>NHCCo*Coe&丹}Cޘx"0FiPf*Y%1d"HcW $sWaP&UdT$4K,U.}mrjT ,+WEu^#P殰,?vT!r4f}уu 97[=fu Z_yLA)'n1e`FAAD=ֈEѨt&:LÑ7m42 [(gBVm$4c-T&g_) LSκ.u%qioOtVObͩeW})Ջܡ,G)y 76t|(%*:ֹ"7V8l V1 RF=QRkF5Xb$b-M%I[J)Uhi ʨh-C\S*v8E*W~/e7# jxkʱh U'8HLRߴ0[et޳-$?`uyk92\a|vE:}gյ?6lR~ y6k]Fc!voIGYJs@0Beڮ&*r"96ژݡzVPNޥ>x5zPxlW/>k]M }[$)An{WTTE$j9%TG-^ڂ G"LO\ZqwjWȦ:[Ӈo7XSy~:Ƃ7:8pݾX->3bb=NB>6&Av=h 'a6a^m`vSFhKevs vSF=ԖA/뤯l%aQ(sD^֡ 1}yر֒eztӗ/ɷv~ y:g|H3nUMYklEOx|::vfmH75(WE#*wk4Kޤ[ vCES2:2CȇO[lT%4P07hVntjFn=iٗ )n-'5PEG,:FFFƲlhTtlق(571Zj; @wwt]$8ό]@w\:bd2966dt#{F#Rݱcǚ5k R:~H/P~~nnN]*lv~~z8ޣ#p Qť[UUe0K֭۹sӧO:(]}Y/`Az󚚚Ν[v>GzTq94dw"027d946n ɷOqξηg%C7PNElg?NF\75l>梂hNWZ"^!3̍{^ARm gT~|1rWsUQ塭N hMzU**T,Kx t |{w'JNOO_tŋVԘn_t̨/2A[UΌ(Grqs9}&// 9I^Ubf@k I7iI Bs,eĨu|:wiP3Dl]tIA23nuo3yd½Lz갮mg-LXTЩQyZ+ H!Q52{DWWUǎnMze(UkupV-: w}b_.b鵅LrYsJMsdKG 5?ӕ{'w/3{#jo MZ}Dw+RuR}Dx> 9|@}G>"pSvD[Fֻ5W4K4'XG&swH>6;uOMxuix_"ƻɷO؏a'yOL`.~stoe_B ij yL3#tV/RxCu|D[__e-NZ^` ~?3@G@w.p].t* 3#jt]$8WX:t~>Le2{*Ttwرf$=}*oɺK6u]<@<V1{tҡN"Tzziݺu;w<}S /+,H/}^SSS[[ܹs^*8U")F Yo)v;+;T_UGRC3=*x6x#:!lGNFJR,_m&)f]0} :"WEE[L*hx vN |{w'JNOO_tŋVԘn_tj@W/sX}@]>$~rRE2]Q=|xDm=. 9 g!{4)ӵQ'6"DWT QR^P)|f%Z%3gP:%l /lYxzm|t2оw#2)ldڽ=Z_K92e6LK#i6qwU !tDo:/2_PSGMhYNݗ@K;+C-st^+%oXvEX\r$SUuIMK[>6{mFF&lML]"%Ef )I<6.KnimrGBh ^i =(JrÑETH':)KK,N`ŦGdW Vg~{:^*˭p;oqc3FyL&bg?$7!=o&;`8*wY#?5+98@tp]GuAnRޮTEpP]X(Dܺ/UG֮8 PXA9_׫])\VD"BvMLrީ|\wF6=?kydւFQFk 9ܭ/ɷGZo~h6HCfbn/qw-Ic#]a׃ ڨ=Ngޕv̵N|9iSjOt{Uuք0˨/oT]*2~e NՋcjJlgX#[>"]Y;Зn9{foW"x#=K[rp## R0ޭhȼAnJٱ/pnv*P0wOĬ v}hcSٳmڽv78Lս4߼ (NMl=uIQǷH4*[l1He: 5=F ] z @%yfttX \ K'ɱL&{5!@%t#'w{׬YC&(SMm6^"ḻ*A:[=Ѩ])yZ& qʹ(:\*2[OGsΝ,+Of)+nb/JusE]#XK@nZ\.yò{r\b]^r皱=şzy$_QB)\ـwxG>9.v@f조ɥ4iU;4l*vr h =4tLM-loLR-*אfRs MξrtU&/D娛.fb_kGZN!j]1-3[;x^ s)o_t{Fn*ukao\/{|BD]B_l?4YΛl =M|=,l}~ClFH渣78t`&NE@&tdJݲn1\buיaVV&IvMjXTp'ɖfⳳVS)춦OnόS[C5JsSOŏoIJ2F63=Zg)y:Mu6r_M 3>^t{D%T7M ta‚N smˈ">I\3fk#)"`#/jمT\fMG7N# 6yMKu]eۺG2G6d$u=ɳzgӷ !um',w\>"뷑,RSgb߁fcb!-|\z듑$оFvu}[|K^=N"8I}l3:zZ10ۋ2] .#_eW9=TM̚+"Yt- b./[E/Xzm!\ +xmzPS)mpտ{O_;v쳏|<9uڵ\pߗշS~W3Ie~&555<ȹsp/(ݽ<=?j\:NS5ɿųMMM`uSQ.x#bP+t 13*?NԱ^^YnZX]rޒڢ߶j}#35l{fg2T&onڸ~{_ne;i9 b"'.~x]χ a6PD[hAQtUk檃O!sձ6\FkOn ݺh]Ѩ^!Az}]6<^{Kc W7r|k֬ҋ)զ6qwU !tTzpݮµ61^mmmD7EJYM [Lz!j=UE;.jDTJw)ǽ0y5c{?'Hb$s$}^]S'>a7DothH;C^'d9w"0&Eoـӫb ޘ*C}h =*Hljj7-e5c,KjrKX2,sDlMיoyu֊ngg1\įSm=Mn16}OQCHȺ+_hу=dBXi牋T^|ݵE:[Asφ[[= &|QcAL| ➬ t g{tDĽFn( EʂDAs"[RGZR1S^ pLYu'.VJ}BjOXW/|Do#Y¥/< i=Uܯv' ij y({fcDwyv ii-.00w>w.mgY-;Cr-20Iim-tѥ%(\x"D/፧x)=Ơ@u!y ! @BF51MT*:eztfvwfK=Db۝o|˥9FfV@Cl^'15oGFsdLUy7Yd+i2+/e~2i]|}JzRq v8cVz>$z^>X6e[V0T5I{5M;g}}Ν;WN/< sωgOV9kumܾU63*+|u~˵76>* 7V-R36wޫ,--a0Dk~eʵK= acZ}\-jO\J}gO8+`&vsyG Won2x =&bo @pGx@ Ļt1iL-\9 @w.t~c?XL#9(wf}H{ːGiwA؏4}yao>~^^="ӧN ~®Ovy'g= $ ~"Cm}֏O#aĻcL*6j#:Kaa*'"1̖^m+m>T[uG S"MT<8)l%:RCdjh25[֩/Us'3 SJ֡ ۔}&SHfhj!Uw*kӃJ4 QbXP"dGҿi' Y+k/ roMDxoZk8hdrkd>q-]$z|pͨv]^b/lD%+*"rT<T^&Iv69iBAt*M* E59!1*6"U @QBGuSJMh_Y/(zzŒK-H '<ɖGEMze*G ɲ7N~s9+nȜ+_>/:(ڬ|odnؒdz.ɧu*/d 1 \3Üw ] ܿ'<}9|3]~IUfAfiAbjtzڢTR<9LU7'Zd2feNx:W 9vB-ڱz=k?KذjX`!Pf-ZCwiA.mJ&3!f Aw{:6"M70dqO'v5wE, alDHݳ(DW#;Wvy44$_<)bQf33Nn"t,,M4\޺>u4vg)01¿"jY-! K$**;ߴY7W2?aǕ32urr`uzFdvIO2m'(L#6EⲕhNݲ!{Ԫas%C }t'\xN#&4CJv##bM ,u!%uENP@M=UQG=_%$cR&ϳ-4X쩨2/'lUk)?)+.٦py{>biQe1hK-Nnm,M˞"6T꫑@)/p.w7k/vCwyG~!w̪/a?~׎ 5Yx Owm#S3CnD`[ol^/+2wwm}^p c?D10NtwQ_oʥeūݣRw{{H[=! }\*?P[M=l[?{.LCBjF:w3u{@@w flask-autoindex_resized iG'0IDATxq"օuÉ`U"0MD`8#V af6YnoX[-G[[[QEQEQ_,((EQEQ((EQEQE((XEQEQ,((EQEQE(("`QEQEQ,((EQEQ((EQEQE((XEQEQ,((EQEQ'KjSocɏ1sEQEQ"4%SO5f^7yZ< sEQEQOjqRgkMO!nATa,{&{4{8(N^S1c&Y =:').~bF_EQUrcRS=MKa*{u={xsZ`x1,(`=e?{wC@Wן`q|ŦO59Ɓt9sSK #sT5pSKu#E `1d0pU>ߕ~&q-W{*2Հ37SH;A:*4qt EUq3`C((;772``|[03n@Q)[t~\T|1^W5|Lah ZJ. oJ!/1(&2.eՏЂ6*m}`!eF؈zڰX!'% :vmC3F" n^ onтNR/mw/b܏A% [>""H*kQ˙c?[zZ>CB+V)sj!Ϥ_A`z.^zI;14Vcu@ajkz'!r~ < 1ݙ; h|8$ɺ4N`-jeSQNQtjo _Y^bA1S\=+;Rgt!Ҧe@I^WL'f+ fg')f5j 9FL4uZlJFxWG~iB?8o "#D;':6K ;SCu蛅負No뮟ٹ6m#HW?>!(yy^`:u3 X:g),{ පeUW[T,ϚޠW9>EaI}M:@,hWtu»Ա{V`UܭE:XUy!m=蜥t e>[ʒ=xɱCZtm*)qA :;Ukƿz7chAH+M\=%|6&$0}*/{R ^9k叶~.ߔmy˙j RuRy FmuyCOQ2Gb=|E6T;#({1দ(괥pׁ߉5݃ LF`K^>,`mXU̓6P^"LQHJ!_%E;d`6qxX>8]xN]8n>;*@;jK Rj. Jcb3\jW ={40bG#9lT6EgՠE&0,Yr=z5k_Byv>;V}*lnC#)ՎG?dS_AՔ ڍ|p+ C`akpi'#M XU,^YjR1'~7%+3G3dJr[ͬ2][$؉f| ?{#|ېU96Jѕ8C 25(Z:-kZX>{o0Ol c;@\?2.S|6 gà DoWKz`3Saj;RWn,*}P,l%1KήK\hc<,!ct9$1–e5E7rF_(' Q.=+&֐;7 :ߖw|`:: 4ތ qհ[4)H\7t+j^lnM:p>|n(ʼz!~YpDKcklX~i,tvg@ZPQ=m՘_cSW Xnzy‰ZMmuj `Z"J10˕~X4b5wZ}pw#8C/;]gcu[|LśVķE8Mw95t , c,`SjWps%uZ膸jRh54s e'S3 J uP$] _%Hc?N OEX~yRꞖkŮ[v;I[^'>U3}ѣ/_؎br]g(o1*os-+bnt#tl:Dt7zqc L\ejI} NG;G3 L 5yy1&S@KY:дTGYW%awڕH̆@@8v(%x6sͤA#]4Pxn빱>@ĐZ8njO*V eݫ/}@oFl۫6#Oum@}IYl}2icp4N!Q:U';VkW೐V^>n-pMmMx9G=V]h+ ڻ+??,\@GX/q6\5văq ƨ5z#,Yq^% ϶{K :;^LymSh޽U֭t_TvNIͪ@%:WhdH YVцG*WO9KYsZԦ]W.Я%akZon:K O{qpPWiZڤCo^r  N $b`)*SXekE YՊ7qm<8E5r^A5K_yl 9΃eP~ SkO`5`46FMZ*PuyhhV $~hcq %CEӀ+=~˗ל7_V`!Yf~^4X>]ch%>:Q@ԣeߗ)ӞW:,[gtHȊ:ӏd*w4Wi?X>VocGh3VZ̶8V LjBCÕH#p`/4xky}9o9Q@ʗ8+1zDps{zC+ oS!@sK:ՎuhXr?ǖ5-onZ[gK+CU[=KhWգMi^|cݿlZoX\5RL[g7xn=ep_!֣kڴ\^}$DZ7oS~2(gtX} e5r|0I m* ͰDGQgD~?TT)Ve~G+Q2bղᧈ xiJZ-h)g~4Ku&GF,)M=r鵭pvum꺔IݼWޣFup!n^ѧ]6II%ub:QmvJyzwxgHGm龌XR)-{Můw>Q;vW9e˖1=ʏP;UvffO-X(#~S&Nyc`d@[{'C1Fd1 DPe[a "+G) I>5`gqx_ɒT4۹̸ XOԾ X8K7:a!5L86ajI?4guoc"#`PX*Qih,!`EUW;rjG\{^8 [9aݭxSZu|)ite2Hu]`E6D[ >E݉`j`Ŭ|f0SC962)d vpq f1El\a$U"n0$= 4#ls1ʴ),U1zw{xy<ɁcB̴H؆+t _]4).C8ro6VNz҃Mk:`,WQ6혽#ŗ1Khms`{يA=V3_ u蓘ؑTTۢ{LJr?JM:7plPk=m't[O~./~XquzpuGp Bh`'8ogY~q{7%f$OK~Nm`i#»2ewh+|ZS&xB1VJ O6|RuU,Ē qɴY!OT2 :WԺ#'޾-o{%؃ |b3 @# M Vئ$ukwY21Qu:P@^:JbYvoO[ 9;*-%ٟǿf<[kybf-K Z/-|>+ (v1b|O;ɼ\ek*5zM® N)k)VWζ1+X!1%zh丹$TcqB#/ܷ݃U 94}5EeO,YWTUiEmqvp<թJ쫘1i4ֳ9ǨUcp+Oe R-$1JXI^Qg[M+yyp1ƹǀ[Ǻ؇G U6eÆm/u`%S`b;ɍuw{ tJNaMӅ{p=l70uב; ,(aޠn`(i?:2y* b೮/ z(r/f_!XdJq-5z0h6'fI=VP{J*wD 374iæ+~ v[ npB-S`%L"dEXm q=b9M i-YbZΟY뽞~'n}VohˇZO2z @V 5fD<\zCj9?eEO>"5fnt GlW\ͭsA#2XXDD}T骽U-ڭFQ 5IsB^{4辇p^E7W t`udzy 4u046+ۇWU-2 Nq|:w% S?-]n L+Q4M ]tIZ'ײuD7Hz+SRtWxHH!~Hύ+᳊zV} VvCO}[si)c8 8zОDj[.[ٴO)_XS,Ti}H4`[T0U( !kqm4\s\gADyy4sjh ~Q~R(A67}n"(ۑ|,;h}n_ƙ %=kWpLg yw?|& Z-Fjl=Gf*$:ixb)9~8anQ4MV"B,Q \ۜӲ4:5SU?M<%>) |weLT.n#tH'H[u.I_±Q}>T̊ZXVLϜ7П|K}>{fZH|I2"Y~6|VQZweּciulpO޻Z'㻛*o% 5@\ (cmT}p4J=#cߖcUM܎"WA=P^#ԛעFwVB!i( ֝Pep{rԇ~Ċ.{M%@~Mz6щ7(Y&3!,łժioZƴHP{@+Ӏen%"_G,e\'yd oِF}u-lv~6 >{u`KoѾX9`Ex9s{u)X\-@zG?.Wz D)ͱ^=ԓq2w+ZG'KRa‘AiC>"V]^%t@7L'`ŭWyKoLmiA<-dKA>˾Q8[,;ڗH?p$vMT%cj@֨`4*gg]td/lN=J:>+q-W%ElΠeۄڡHݡl.=8w儍uG?uNP꣤{ fVa@HbKHٱ=gu#pY7C8*]Ix +_Xi\y1nv8smQt'KyE]Y/Z% qLMI# `h!-ܯMQ& Mq W75#z4'1:٘UQ3Jϯʬ4q^$߸Dy>y\QL&)7ׯ94@Y=8i1t6;1gCbق%>Ωec?zp~*u?s^ :ʶ(O˴[kczkŀrNB5H% [Oο\}w% {P$L"JW*v7"Vs5RpUGUU y{ܬw};3!A=hAUh{\m g۩,Mh;#X/Lr:nNju] QE 6tQ@7gݒ }u{kX?G(.48L10+_v&枹[ hTP` {SR6_Ƃqu :rۙ)i_\ 8W \f|@N{^Ӎѳׁ :.jeV_ӈB ,N[tg4%%y6vᩅyq%!K,ݹ~]2rB*s US|"|ՔBgk,V,Xgg<_tyg~j}侚Nn\aNy]ꊙ~[~4[yX?I9bA=VpO T*W Z~rWl{vhPNS0Vr Y@,6p A[vXDdJ:~Je&X vbYӦ f,*7( Kza|.a,筼[ wӳ8^|h^vc XEQEQ,((EQEQE(("`QEQE((XEQEQ((EQEQE((XEQEQ,((EQEQE(("`QEQE((X((EQEQWڪIENDB`Flask-AutoIndex-0.5/docs/conf.py0000644000175000017500000001612012106747350017330 0ustar subleesublee00000000000000# -*- coding: utf-8 -*- # # Flask-AutoIndex documentation build configuration file, created by # sphinx-quickstart on Tue Aug 31 00:34:54 2010. # # This file is execfile()d with the current directory set to its containing dir. # # Note that not all possible configuration values are present in this # autogenerated file. # # All configuration values have a default; values that are commented out # serve to show the default. import sys, os # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. #sys.path.insert(0, os.path.abspath('.')) sys.path.append(os.path.abspath('_themes')) sys.path.append(os.path.abspath('..')) # -- General configuration ----------------------------------------------------- # If your documentation needs a minimal Sphinx version, state it here. #needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = ['sphinx.ext.autodoc'] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # The suffix of source filenames. source_suffix = '.rst' # The encoding of source files. #source_encoding = 'utf-8-sig' # The master toctree document. master_doc = 'index' # General information about the project. project = u'Flask-AutoIndex' copyright = u'2010-2013, Heungsub Lee' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. version = '0.2.0' # The full version, including alpha/beta/rc tags. release = '0.2.0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. #language = None # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: #today = '' # Else, today_fmt is used as the format for a strftime call. #today_fmt = '%B %d, %Y' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. exclude_patterns = ['_build'] # The reST default role (used for this markup: `text`) to use for all documents. #default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. #add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). #add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. #show_authors = False # The name of the Pygments (syntax highlighting) style to use. #pygments_style = 'sphinx' # A list of ignored prefixes for module index sorting. #modindex_common_prefix = [] # -- Options for HTML output --------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. html_theme = 'flask_small' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. html_theme_options = { 'index_logo': 'flask-autoindex.png', 'github_fork': 'sublee/flask-autoindex' } # Add any paths that contain custom themes here, relative to this directory. html_theme_path = ['_themes'] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". #html_title = None # A shorter title for the navigation bar. Default is the same as html_title. #html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. #html_logo = None # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. #html_favicon = 'favicon.ico' # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. #html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. #html_use_smartypants = True # Custom sidebar templates, maps document names to template names. #html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. #html_additional_pages = {} # If false, no module index is generated. #html_domain_indices = True # If false, no index is generated. #html_use_index = True # If true, the index is split into individual pages for each letter. #html_split_index = False # If true, links to the reST sources are added to the pages. #html_show_sourcelink = True # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. #html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. #html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. #html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). #html_file_suffix = None # Output file base name for HTML help builder. htmlhelp_basename = 'Flask-AutoIndexdoc' # -- Options for LaTeX output -------------------------------------------------- # The paper size ('letter' or 'a4'). #latex_paper_size = 'letter' # The font size ('10pt', '11pt' or '12pt'). #latex_font_size = '10pt' # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ ('index', 'Flask-AutoIndex.tex', u'Flask-AutoIndex Documentation', u'Heungsub Lee', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of # the title page. #latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. #latex_use_parts = False # If true, show page references after internal links. #latex_show_pagerefs = False # If true, show URL addresses after external links. #latex_show_urls = False # Additional stuff for the LaTeX preamble. #latex_preamble = '' # Documents to append as an appendix to all manuals. #latex_appendices = [] # If false, no module index is generated. #latex_domain_indices = True # -- Options for manual page output -------------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ ('index', 'flask-autoindex', u'Flask-AutoIndex Documentation', [u'Heungsub Lee'], 1) ] Flask-AutoIndex-0.5/MANIFEST.in0000664000175000017500000000046112123622634016636 0ustar subleesublee00000000000000include LICENSE recursive-include tests * recursive-exclude tests *.pyc recursive-include flask_autoindex/static * recursive-include flask_autoindex/templates * include docs/*.rst docs/conf.py recursive-include docs/_static * recursive-include docs/_themes *.py *.css *.css_t *.conf *.html LICENSE README Flask-AutoIndex-0.5/tests/0000775000175000017500000000000012124040374016235 5ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/blueprinttest/0000775000175000017500000000000012124040374021141 5ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/blueprinttest/static/0000775000175000017500000000000012124040374022430 5ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/blueprinttest/static/autoindex.css0000644000175000017500000000504511604610600025141 0ustar subleesublee00000000000000* { margin: 0; padding: 0; border: none; } body, table { font-family: sans-serif; font-size: 14px; } a:link, a:visited { text-decoration: none; } a:link { color: #36c; } a:visited { color: #333; } a:hover { text-decoration: underline; } #readme { padding: 10px 26px; border-bottom: 1px solid #eee; font-size: 12px; color: #333; background: #fafafa; } #readme pre { line-height: 1.2; } #readme p, #readme ul, #readme ol, #readme h1, #readme h2, #readme h3, #readme h4, #readme h5, #readme h6 { display: block; margin-bottom: 1em; } #readme h1, #readme h2, #readme h3, #readme h4, #readme h5, #readme h6 { padding: 0; color: #456; text-align: left; font-family: sans-serif; font-weight: bolder; } #readme pre code { display: block; padding: 9px; margin: 0 -10px 1em; border: 1px solid #cde; color: #567; background: #fff; } #readme li { margin-left: 2em; } #readme blockquote { padding: 9px; margin: 0 -10px 1em; border-left: 1px solid #cde; } #readme blockquote :last-child { margin-bottom: 0; } #readme h1 { font-size: 1.5em; } #readme h2 { font-size: 1.4em; } #readme h3 { font-size: 1.3em; } #readme h4 { font-size: 1.2em; } #readme h5 { font-size: 1.1em; } #readme h6 { font-size: 1em; } .breadcrumb { padding: 0; } .breadcrumb a { margin: 0; color: #666; font-size: 12px; } .breadcrumb .sep { color: #bbb; } .breadcrumb img { vertical-align: middle; } .breadcrumb h1 { font-size: 12px; font-weight: normal; padding: 5px; background: #f4f4f4; border-top: 1px solid #ccc; } table { border-collapse: collapse; width: 100%; background: #fff; } thead { border-bottom: 1px solid #ccc; } th { font-size: 11px; height: 30px; background: #ddd; background: -webkit-gradient( linear, left bottom, left top, color-stop(0, #ddd), color-stop(1, #eee) ); background: -moz-linear-gradient( center bottom, #ddd 0%, #eee 100% ); } th a:link, th a:visited { margin: 0 10px; color: #333; } th img { position: absolute; margin-left: -6px; } tbody { border: solid #ccc; border-width: 1px 0; } hr { margin: 0; border: none; } td { padding: 5px; font-size: 11px; color: #333; border-left: 1px dashed #eee; } td a { margin-right: 40px; font-size: 14px; } td.modified { text-align: center; } td.size { text-align: right; } .icon, .name { border: none; } .icon { width: 16px; padding-right: 0; } .modified { width: 105px; } .size { width: 60px; } address { padding: 5px; font-size: 11px; color: #333; text-align: right; } Flask-AutoIndex-0.5/tests/blueprinttest/static/asc.gif0000644000175000017500000000006511604610600023661 0ustar subleesublee00000000000000GIF89a !,   ≴Y[;Flask-AutoIndex-0.5/tests/blueprinttest/static/desc.gif0000644000175000017500000000006511604610600024031 0ustar subleesublee00000000000000GIF89a !,  ~^ZT;Flask-AutoIndex-0.5/tests/blueprinttest/__init__.py0000644000175000017500000000007511604500316023251 0ustar subleesublee00000000000000from flask import Blueprint bp = Blueprint('test', __name__) Flask-AutoIndex-0.5/tests/static/0000775000175000017500000000000012124040374017524 5ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.fla0000644000175000017500000000000011441650100021146 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.ico0000644000175000017500000000000011441650100021156 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.app0000644000175000017500000000000011441650100021164 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.java0000644000175000017500000000000011441650100021325 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.pptx0000644000175000017500000000000011441650100021377 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.log0000644000175000017500000000000011441650100021165 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.sys0000644000175000017500000000000011441650100021222 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.asp0000644000175000017500000000000011441650100021167 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.smi0000644000175000017500000000000011441650100021174 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.cfg0000644000175000017500000000000011441650100021143 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.php0000644000175000017500000000000011441650100021173 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.avi0000644000175000017500000000000011441650100021163 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.cpl0000644000175000017500000000000011441650100021162 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.mov0000644000175000017500000000000011441650100021205 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.jsp0000644000175000017500000000000011441650100021200 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.yml0000644000175000017500000000000011441650100021205 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.bin0000644000175000017500000000000011441650100021154 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.bup0000644000175000017500000000000011441650100021172 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.tar0000644000175000017500000000000011441650100021172 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.xlsx0000644000175000017500000000000011441650100021402 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.json0000644000175000017500000000000011441650100021355 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.com0000644000175000017500000000000011441650100021162 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.eps0000644000175000017500000000000011441650100021173 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.csv0000644000175000017500000000000011441650100021177 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.tgz0000644000175000017500000000000011441650100021210 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.tif0000644000175000017500000000000011441650100021166 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.py0000644000175000017500000000000011441650100021034 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.zip0000644000175000017500000000000011441650100021206 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.exe0000644000175000017500000000000011441650100021165 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.ppt0000644000175000017500000000000011441650100021207 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.js0000644000175000017500000000000011441650100021020 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.psd0000644000175000017500000000000011441650100021172 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.docx0000644000175000017500000000000011441650100021341 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.iso0000644000175000017500000000000011441650100021176 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.flv0000644000175000017500000000000011441650100021173 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.css0000644000175000017500000000000011441650100021174 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.h0000644000175000017500000000000011441650100020633 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.vb0000644000175000017500000000000011441650100021013 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.sh0000644000175000017500000000000011441650100021016 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.pkg0000644000175000017500000000000011441650100021165 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.7z0000644000175000017500000000000011441650100020744 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.tar.gz0000644000175000017500000000000011441650100021611 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.xls0000644000175000017500000000000011441650100021212 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.xsl0000644000175000017500000000000011441650100021212 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.applescript0000644000175000017500000000000011441650100022732 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.markdown0000644000175000017500000000000011441650100022226 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.toast0000644000175000017500000000000011441650100021536 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.wmv0000644000175000017500000000000011441650100021215 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.vcd0000644000175000017500000000000011441650100021160 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.vcf0000644000175000017500000000000011441650100021162 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.txt0000644000175000017500000000000011441650100021223 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.conf0000644000175000017500000000000011441650100021331 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.bat0000644000175000017500000000000011441650100021152 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.ttf0000644000175000017500000000000011441650100021201 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.svg0000644000175000017500000000000011441650100021203 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.sql0000644000175000017500000000000011441650100021203 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.gif0000644000175000017500000000000011441650100021151 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.mid0000644000175000017500000000000011441650100021155 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.htm0000644000175000017500000000000011441650100021174 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.mp40000644000175000017500000000000011441650100021104 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.rtf0000644000175000017500000000000011441650100021177 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.jpeg0000644000175000017500000000000011441650100021331 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/helloworld.txt0000644000175000017500000000001611437336331022442 0ustar subleesublee00000000000000Hello, world! Flask-AutoIndex-0.5/tests/static/test.md0000644000175000017500000000000011441650100021004 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.mpa0000644000175000017500000000000011441650100021161 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.ai0000644000175000017500000000000011441650100020775 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.cer0000644000175000017500000000000011441650100021155 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.dll0000644000175000017500000000000011441650100021157 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.wav0000644000175000017500000000000011441650100021201 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.less0000644000175000017500000000000011441650100021352 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.alz0000644000175000017500000000000011441650100021172 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.c0000644000175000017500000000000011441650100020626 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.pdf0000644000175000017500000000000011441650100021155 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.mpeg0000644000175000017500000000000011441650100021334 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.rb0000644000175000017500000000000011441650100021007 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.mp30000644000175000017500000000000011441650100021103 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.xhtml0000644000175000017500000000000011441650100021540 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.cur0000644000175000017500000000000011441650100021175 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.ics0000644000175000017500000000000011441650100021162 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.doc0000644000175000017500000000000011441650100021151 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.rss0000644000175000017500000000000011441650100021213 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.ini0000644000175000017500000000000011441650100021163 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.cgi0000644000175000017500000000000011441650100021146 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.png0000644000175000017500000000000011441650100021170 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.html0000644000175000017500000000000011441650100021350 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.db0000644000175000017500000000000011441650100020771 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.jpg0000644000175000017500000000000011441650100021164 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.torrent0000644000175000017500000000000011441650100022101 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.xml0000644000175000017500000000000011441650100021204 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.rar0000644000175000017500000000000011441650100021170 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.swf0000644000175000017500000000000011441650100021203 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.bak0000644000175000017500000000000011441650100021141 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.hwp0000644000175000017500000000000011441650100021202 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.bmp0000644000175000017500000000000011441650100021162 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.cab0000644000175000017500000000000011441650100021131 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.tmp0000644000175000017500000000000011441650100021204 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.dmg0000644000175000017500000000000011441650100021153 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.jar0000644000175000017500000000000011441650100021160 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.mpg0000644000175000017500000000000011441650100021167 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/static/test.cpp0000644000175000017500000000000011441650100021166 0ustar subleesublee00000000000000Flask-AutoIndex-0.5/tests/__init__.py0000664000175000017500000002255712123717024020363 0ustar subleesublee00000000000000import os.path import mimetypes import unittest from flask import * from flask.ext.autoindex import * __file__ = __file__.replace('.pyc', '.py') browse_root = os.path.abspath(os.path.dirname(__file__)) class RootDirectoryTestCase(unittest.TestCase): def setUp(self): self.rootdir = RootDirectory(browse_root) def test_root_dir(self): assert isinstance(self.rootdir, RootDirectory) assert self.rootdir.path == '.' assert os.path.samefile(self.rootdir.abspath, browse_root) assert os.path.isdir(self.rootdir.abspath) def test_init(self): assert isinstance(Directory(browse_root), RootDirectory) assert isinstance(Directory('.', self.rootdir), RootDirectory) assert isinstance(Entry(browse_root), RootDirectory) assert isinstance(Entry('.', self.rootdir), RootDirectory) def test_same_object(self): assert self.rootdir is RootDirectory(browse_root) assert self.rootdir is Directory(browse_root) assert self.rootdir is Directory('.', self.rootdir) assert self.rootdir is Entry(browse_root) assert self.rootdir is Entry('.', self.rootdir) assert RootDirectory(browse_root) is Directory(browse_root) assert RootDirectory(browse_root) is Entry('.', self.rootdir) assert Entry(browse_root) is Directory('.', self.rootdir) def test_get_child_file(self): file = self.rootdir.get_child('__init__.py') assert isinstance(file, File) assert file.ext == 'py' assert file.path == '__init__.py' assert file.rootdir is self.rootdir def test_get_child_dir(self): dir = self.rootdir.get_child('static') assert isinstance(dir, Directory) assert dir.path == 'static' assert dir.rootdir is self.rootdir def test_contain(self): assert 'static' in self.rootdir assert '__init__.py' in self.rootdir assert Entry('static', self.rootdir) in self.rootdir assert Entry('__init__.py', self.rootdir) in self.rootdir assert '^_^' not in self.rootdir class DirectoryTestCase(unittest.TestCase): def setUp(self): self.rootdir = RootDirectory(browse_root) self.static = Directory('static', self.rootdir) def test_dir(self): assert isinstance(self.static, Directory) assert self.static.path == 'static' assert os.path.samefile(self.static.abspath, os.path.join(browse_root, 'static')) assert os.path.isdir(self.static.abspath) def test_init(self): assert isinstance(Directory('static', self.rootdir), Directory) assert isinstance(Entry('static', self.rootdir), Directory) def test_same_object(self): assert self.static is Directory('static', self.rootdir) assert self.static is Entry('static', self.rootdir) assert Directory('static', self.rootdir) is \ Entry('static', self.rootdir) assert self.static.parent is self.rootdir def test_get_child_file(self): file = self.static.get_child('test.txt') assert isinstance(file, File) assert file.ext == 'txt' assert file.path == 'static/test.txt' assert file.rootdir is self.rootdir def test_contain(self): assert 'test.py' in self.static assert Entry('static/test.py', self.rootdir) in self.static assert '^_^' not in self.static class FileTestCase(unittest.TestCase): def setUp(self): self.rootdir = RootDirectory(browse_root) self.itself = File('__init__.py', self.rootdir) def test_file(self): assert isinstance(self.itself, File) assert self.itself.path == '__init__.py' assert os.path.samefile(self.itself.abspath, os.path.join(browse_root, '__init__.py')) assert os.path.isfile(self.itself.abspath) def test_init(self): assert isinstance(File('__init__.py', self.rootdir), File) assert isinstance(Entry('__init__.py', self.rootdir), File) assert isinstance(File('static/test.txt', self.rootdir), File) assert isinstance(Entry('static/test.txt', self.rootdir), File) def test_same_object(self): assert self.itself is File('__init__.py', self.rootdir) assert self.itself is Entry('__init__.py', self.rootdir) assert File('__init__.py', self.rootdir) is \ Entry('__init__.py', self.rootdir) def test_properties(self): source = ''.join(file(__file__).readlines()) assert self.itself.data.strip() == source.strip() assert self.itself.size == len(source) assert self.itself.ext == 'py' assert self.itself.mimetype == mimetypes.guess_type(__file__) class ApplicationTestCase(unittest.TestCase): def setUp(self): self.app = Flask(__name__) self.app2 = Flask(__name__) self.idx = AutoIndex(self.app, browse_root, add_url_rules=True) self.idx2 = AutoIndex(self.app2, silk_path='/myicons') @self.app2.route('/') @self.app2.route('/') def autoindex(path='.'): return self.idx2.render_autoindex(path, browse_root) def get(self, path): return self.app.test_client().get(path) def get2(self, path): return self.app2.test_client().get(path) def test_css(self): for get in self.get, self.get2: rv = get('/__autoindex__/autoindex.css') assert 200 == rv.status_code def test_icon(self): rv = self.get('/__icons__/page_white.png') rv2 = self.get2('/myicons/page_white.png') assert 294 == len(rv.data) assert rv.data == rv2.data def test_autoindex(self): for get in self.get, self.get2: rv = get('/') assert '__init__.py' in rv.data def test_own_static_file(self): rv = self.get('/static/helloworld.txt') assert 'Hello, world!' == rv.data.strip() def test_own_page(self): for get in self.get, self.get2: rv = get('/test') assert not 'foo bar foo bar' == rv.data.strip() @self.app.route('/test') def sublee(): return 'foo bar foo bar', 200 @self.app2.route('/test') def sublee(): return 'foo bar foo bar', 200 for get in self.get, self.get2: rv = get('/test') assert 'foo bar foo bar' == rv.data.strip() def test_builtin_icon_rule(self): testset = {'7z': 'page_white_zip.png', 'avi': 'film.png', 'cer': 'key.png', 'html': 'page_white_code.png', 'iso': 'cd.png', 'rss': 'feed.png'} for ext, icon in testset.iteritems(): file = self.idx.rootdir.get_child('static/test.' + ext) assert file.guess_icon().endswith(icon) def test_custom_icon_rule(self): file = self.idx.rootdir.get_child('__init__.py') original_icon_url = file.guess_icon() self.idx.add_icon_rule('table.png', ext='py') customized_icon_url = file.guess_icon() assert original_icon_url.endswith('page_white_python.png') assert customized_icon_url.endswith('table.png') class SubdomainTestCase(unittest.TestCase): def setUp(self): from blueprinttest import bp app = Flask(__name__) app.config['SERVER_NAME'] = 'example.org' AutoIndex(bp, browse_root) app.register_blueprint(bp, subdomain='test') self.app = app def get(self, path): return self.app.test_client().get(path, 'http://test.example.org/') def test_css(self): rv = self.get('/static/autoindex.css') assert 200 == rv.status_code, 'could not found preloaded css file.' def test_icon(self): rv = self.get('/__icons__/page_white.png') assert 294 == len(rv.data), 'could not found preloaded icon file.' def test_browse(self): rv = self.get('/') assert 'Index of /' in rv.data assert '__init__.py' in rv.data def test_own_static_file(self): rv = self.get('/static/helloworld.txt') assert 'Hello, world!' == rv.data.strip() class WithoutSubdomainTestCase(unittest.TestCase): def setUp(self): from blueprinttest import bp app = Flask(__name__) AutoIndex(bp, browse_root) app.register_blueprint(bp) self.app = app def get(self, path): return self.app.test_client().get(path) def test_css(self): rv = self.get('/static/autoindex.css') assert 200 == rv.status_code, 'could not found preloaded css file.' def test_icon(self): rv = self.get('/__icons__/page_white.png') assert 294 == len(rv.data), 'could not found preloaded icon file.' def test_browse(self): rv = self.get('/') assert 'Index of /' in rv.data assert '__init__.py' in rv.data def suite(): suite = unittest.TestSuite() suite.addTest(unittest.makeSuite(RootDirectoryTestCase)) suite.addTest(unittest.makeSuite(DirectoryTestCase)) suite.addTest(unittest.makeSuite(FileTestCase)) suite.addTest(unittest.makeSuite(ApplicationTestCase)) # These cases will be passed on Flask next generation. # suite.addTest(unittest.makeSuite(SubdomainTestCase)) # suite.addTest(unittest.makeSuite(WithoutSubdomainTestCase)) return suite if __name__ == '__main__': unittest.main(defaultTest='suite') Flask-AutoIndex-0.5/PKG-INFO0000664000175000017500000000241012124040374016165 0ustar subleesublee00000000000000Metadata-Version: 1.1 Name: Flask-AutoIndex Version: 0.5 Summary: The mod_autoindex for Flask Home-page: http://pythonhosted.org/Flask-AutoIndex Author: Heungsub Lee Author-email: sub@subl.ee License: BSD Description: Flask-AutoIndex --------------- Flask-AutoIndex generates an index page for your `Flask`_ application automatically. The result just like `mod_autoindex`_, but the look is more awesome! Look at this: .. _Flask: http://flask.pocoo.org/ .. _mod_autoindex: http://httpd.apache.org/docs/current/mod/mod_autoindex.html Links ````` * `documentation `_ * `development version `_ Platform: any Classifier: Development Status :: 4 - Beta Classifier: Environment :: Web Environment Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: BSD License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content Classifier: Topic :: Software Development :: Libraries :: Python Modules Flask-AutoIndex-0.5/Flask_AutoIndex.egg-info/0000775000175000017500000000000012124040374021605 5ustar subleesublee00000000000000Flask-AutoIndex-0.5/Flask_AutoIndex.egg-info/PKG-INFO0000644000175000017500000000241012124040374022675 0ustar subleesublee00000000000000Metadata-Version: 1.1 Name: Flask-AutoIndex Version: 0.5 Summary: The mod_autoindex for Flask Home-page: http://pythonhosted.org/Flask-AutoIndex Author: Heungsub Lee Author-email: sub@subl.ee License: BSD Description: Flask-AutoIndex --------------- Flask-AutoIndex generates an index page for your `Flask`_ application automatically. The result just like `mod_autoindex`_, but the look is more awesome! Look at this: .. _Flask: http://flask.pocoo.org/ .. _mod_autoindex: http://httpd.apache.org/docs/current/mod/mod_autoindex.html Links ````` * `documentation `_ * `development version `_ Platform: any Classifier: Development Status :: 4 - Beta Classifier: Environment :: Web Environment Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: BSD License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content Classifier: Topic :: Software Development :: Libraries :: Python Modules Flask-AutoIndex-0.5/Flask_AutoIndex.egg-info/not-zip-safe0000644000175000017500000000000111437362746024051 0ustar subleesublee00000000000000 Flask-AutoIndex-0.5/Flask_AutoIndex.egg-info/top_level.txt0000644000175000017500000000002012124040374024325 0ustar subleesublee00000000000000flask_autoindex Flask-AutoIndex-0.5/Flask_AutoIndex.egg-info/dependency_links.txt0000644000175000017500000000000112124040374025651 0ustar subleesublee00000000000000 Flask-AutoIndex-0.5/Flask_AutoIndex.egg-info/requires.txt0000644000175000017500000000003212124040374024176 0ustar subleesublee00000000000000Flask>=0.8 Flask-Silk>=0.2Flask-AutoIndex-0.5/Flask_AutoIndex.egg-info/SOURCES.txt0000644000175000017500000000660212124040374023473 0ustar subleesublee00000000000000LICENSE MANIFEST.in README setup.cfg setup.py Flask_AutoIndex.egg-info/PKG-INFO Flask_AutoIndex.egg-info/SOURCES.txt Flask_AutoIndex.egg-info/dependency_links.txt Flask_AutoIndex.egg-info/not-zip-safe Flask_AutoIndex.egg-info/requires.txt Flask_AutoIndex.egg-info/top_level.txt docs/conf.py docs/index.rst docs/_static/example.png docs/_static/flask-autoindex.png docs/_themes/LICENSE docs/_themes/README docs/_themes/flask_theme_support.py docs/_themes/flask/layout.html docs/_themes/flask/relations.html docs/_themes/flask/theme.conf docs/_themes/flask/static/flasky.css_t docs/_themes/flask/static/small_flask.css docs/_themes/flask_small/layout.html docs/_themes/flask_small/theme.conf docs/_themes/flask_small/static/flasky.css_t flask_autoindex/__init__.py flask_autoindex/entry.py flask_autoindex/icons.py flask_autoindex/static/asc.gif flask_autoindex/static/autoindex.css flask_autoindex/static/desc.gif flask_autoindex/templates/__autoindex__/autoindex.html flask_autoindex/templates/__autoindex__/macros.html flaskext/test.py flaskext/autoindex/converters.py tests/__init__.py tests/blueprinttest/__init__.py tests/blueprinttest/static/asc.gif tests/blueprinttest/static/autoindex.css tests/blueprinttest/static/desc.gif tests/static/helloworld.txt tests/static/test.7z tests/static/test.ai tests/static/test.alz tests/static/test.app tests/static/test.applescript tests/static/test.asp tests/static/test.avi tests/static/test.bak tests/static/test.bat tests/static/test.bin tests/static/test.bmp tests/static/test.bup tests/static/test.c tests/static/test.cab tests/static/test.cer tests/static/test.cfg tests/static/test.cgi tests/static/test.com tests/static/test.conf tests/static/test.cpl tests/static/test.cpp tests/static/test.css tests/static/test.csv tests/static/test.cur tests/static/test.db tests/static/test.dll tests/static/test.dmg tests/static/test.doc tests/static/test.docx tests/static/test.eps tests/static/test.exe tests/static/test.fla tests/static/test.flv tests/static/test.gif tests/static/test.h tests/static/test.htm tests/static/test.html tests/static/test.hwp tests/static/test.ico tests/static/test.ics tests/static/test.ini tests/static/test.iso tests/static/test.jar tests/static/test.java tests/static/test.jpeg tests/static/test.jpg tests/static/test.js tests/static/test.json tests/static/test.jsp tests/static/test.less tests/static/test.log tests/static/test.markdown tests/static/test.md tests/static/test.mid tests/static/test.mov tests/static/test.mp3 tests/static/test.mp4 tests/static/test.mpa tests/static/test.mpeg tests/static/test.mpg tests/static/test.pdf tests/static/test.php tests/static/test.pkg tests/static/test.png tests/static/test.ppt tests/static/test.pptx tests/static/test.psd tests/static/test.py tests/static/test.rar tests/static/test.rb tests/static/test.rss tests/static/test.rtf tests/static/test.sh tests/static/test.smi tests/static/test.sql tests/static/test.svg tests/static/test.swf tests/static/test.sys tests/static/test.tar tests/static/test.tar.gz tests/static/test.tgz tests/static/test.tif tests/static/test.tmp tests/static/test.toast tests/static/test.torrent tests/static/test.ttf tests/static/test.txt tests/static/test.vb tests/static/test.vcd tests/static/test.vcf tests/static/test.wav tests/static/test.wmv tests/static/test.xhtml tests/static/test.xls tests/static/test.xlsx tests/static/test.xml tests/static/test.xsl tests/static/test.yml tests/static/test.zipFlask-AutoIndex-0.5/setup.py0000664000175000017500000000316412123723561016616 0ustar subleesublee00000000000000""" Flask-AutoIndex --------------- Flask-AutoIndex generates an index page for your `Flask`_ application automatically. The result just like `mod_autoindex`_, but the look is more awesome! Look at this: .. _Flask: http://flask.pocoo.org/ .. _mod_autoindex: http://httpd.apache.org/docs/current/mod/mod_autoindex.html Links ````` * `documentation `_ * `development version `_ """ import re from setuptools import setup def run_tests(): from tests import suite return suite() setup( name='Flask-AutoIndex', version='0.5', license='BSD', author='Heungsub Lee', author_email=re.sub('((sub).)(.*)', r'\2@\1.\3', 'sublee'), url='http://pythonhosted.org/Flask-AutoIndex', description='The mod_autoindex for Flask', long_description=__doc__, packages=['flask_autoindex'], include_package_data=True, package_data={'flask_autoindex': ['static/*', 'templates/__autoindex__/*']}, zip_safe=False, platforms='any', install_requires=['Flask>=0.8', 'Flask-Silk>=0.2'], test_suite='__main__.run_tests', classifiers=[ 'Development Status :: 4 - Beta', 'Environment :: Web Environment', 'Intended Audience :: Developers', 'License :: OSI Approved :: BSD License', 'Operating System :: OS Independent', 'Programming Language :: Python', 'Topic :: Internet :: WWW/HTTP :: Dynamic Content', 'Topic :: Software Development :: Libraries :: Python Modules' ] ) Flask-AutoIndex-0.5/LICENSE0000644000175000017500000000266412106602300016077 0ustar subleesublee00000000000000Copyright (c) 2010-2013 by Heungsub Lee. Some rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * The names of the contributors may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Flask-AutoIndex-0.5/flaskext/0000775000175000017500000000000012124040374016714 5ustar subleesublee00000000000000Flask-AutoIndex-0.5/flaskext/autoindex/0000775000175000017500000000000012124040374020714 5ustar subleesublee00000000000000Flask-AutoIndex-0.5/flaskext/autoindex/converters.py0000644000175000017500000000234611604515156023472 0ustar subleesublee00000000000000from flaskext.autoindex.entry import File class Converters(object): def add_markdown_converter(self): """Adds a markdown converter if :mod:`markdown` exists.""" try: from markdown import Markdown def markdown_converter(file): text = file.data.decode('utf-8') return Markdown().convert(text) for ext in ['markdown', 'md']: File.add_html_converter_by_ext(markdown_converter, ext) except ImportError: pass def add_html_converter(self): """Adds a HTML converter.""" skip = lambda f: f.data.encode('utf-8') for ext in ['html', 'htm', 'xhtml']: File.add_html_converter_by_ext(skip, ext) def add_plain_converter(self): """Adds a plain text converter.""" def plain_converter(file): text = file.data.decode('utf-8') return '
{0}
'.format(text) def is_plain(file): return file.ext == 'txt' or not file.ext File.add_html_converter(plain_converter, is_plain) converters = Converters() for meth in dir(converters): if meth.startswith('add_') and meth.endswith('_converter'): getattr(converters, meth)() Flask-AutoIndex-0.5/flaskext/test.py0000644000175000017500000000000611437065775020261 0ustar subleesublee00000000000000A = 1 Flask-AutoIndex-0.5/flask_autoindex/0000775000175000017500000000000012124040374020253 5ustar subleesublee00000000000000Flask-AutoIndex-0.5/flask_autoindex/static/0000775000175000017500000000000012124040374021542 5ustar subleesublee00000000000000Flask-AutoIndex-0.5/flask_autoindex/static/autoindex.css0000664000175000017500000000506712123622634024270 0ustar subleesublee00000000000000* { margin: 0; padding: 0; border: none; } body, table { font-family: Helvetica, Arial, sans-serif; font-size: 14px; } a:link, a:visited { text-decoration: none; } a:link { color: #36c; } a:visited { color: #333; } a:hover { text-decoration: underline; } #readme { padding: 10px 26px; border-bottom: 1px solid #eee; font-size: 12px; color: #333; background: #fafafa; } #readme pre { line-height: 1.2; } #readme p, #readme ul, #readme ol, #readme h1, #readme h2, #readme h3, #readme h4, #readme h5, #readme h6 { display: block; margin-bottom: 1em; } #readme h1, #readme h2, #readme h3, #readme h4, #readme h5, #readme h6 { padding: 0; color: #456; text-align: left; font-family: sans-serif; font-weight: bolder; } #readme pre code { display: block; padding: 9px; margin: 0 -10px 1em; border: 1px solid #cde; color: #567; background: #fff; } #readme li { margin-left: 2em; } #readme blockquote { padding: 9px; margin: 0 -10px 1em; border-left: 1px solid #cde; } #readme blockquote :last-child { margin-bottom: 0; } #readme h1 { font-size: 1.5em; } #readme h2 { font-size: 1.4em; } #readme h3 { font-size: 1.3em; } #readme h4 { font-size: 1.2em; } #readme h5 { font-size: 1.1em; } #readme h6 { font-size: 1em; } .breadcrumb { padding: 0; } .breadcrumb a { margin: 0; color: #666; font-size: 12px; } .breadcrumb .sep { color: #bbb; } .breadcrumb img { vertical-align: middle; } .breadcrumb h1 { font-size: 12px; font-weight: normal; padding: 5px; background: #f4f4f4; border-top: 1px solid #ccc; } table { border-collapse: collapse; width: 100%; background: #fff; } thead { border-bottom: 1px solid #ccc; } th { font-size: 11px; height: 30px; background: #ddd; background: -webkit-gradient( linear, left bottom, left top, color-stop(0, #ddd), color-stop(1, #eee) ); background: -moz-linear-gradient( center bottom, #ddd 0%, #eee 100% ); } th a:link, th a:visited { margin: 0 10px; color: #333; } th img { position: absolute; margin-left: -6px; } tbody { border: solid #ccc; border-width: 1px 0; } hr { margin: 0; border: none; } td { padding: 5px; font-size: 11px; color: #333; border-left: 1px dashed #eee; } td a { margin-right: 40px; font-size: 14px; } td.modified { text-align: center; } td.size { text-align: right; } .icon, .name { border: none; } .icon { width: 16px; padding-right: 0; } .modified { width: 120px; } .size { width: 60px; } address { padding: 5px; font-size: 11px; color: #333; text-align: right; } Flask-AutoIndex-0.5/flask_autoindex/static/asc.gif0000664000175000017500000000006512123622634023004 0ustar subleesublee00000000000000GIF89a !,   ≴Y[;Flask-AutoIndex-0.5/flask_autoindex/static/desc.gif0000664000175000017500000000006512123622634023154 0ustar subleesublee00000000000000GIF89a !,  ~^ZT;Flask-AutoIndex-0.5/flask_autoindex/templates/0000775000175000017500000000000012124040374022251 5ustar subleesublee00000000000000Flask-AutoIndex-0.5/flask_autoindex/templates/__autoindex__/0000775000175000017500000000000012124040374025045 5ustar subleesublee00000000000000Flask-AutoIndex-0.5/flask_autoindex/templates/__autoindex__/macros.html0000664000175000017500000000343212123622634027225 0ustar subleesublee00000000000000{% macro entry(ent) %} {% set icon = ent.guess_icon() %} {% if icon %} {% endif %} {%- if ent.name == ".." -%} Parent folder {%- else -%} {{ ent.name }} {%- endif -%} {% if ent.size %} {{ ent.size|filesizeformat }} {% else %} - {% endif %} {% endmacro %} {% macro th(key, label, colspan=1) %} {%- if sort_by == key and order > 0 -%} {{ label }} {%- else -%} {{ label }} {%- endif -%} {%- if sort_by == key -%} {%- if order > 0 -%} ASC {%- elif order < 0 -%} DESC {%- endif -%} {%- endif -%} {% endmacro %} {% macro thead() %} {{ th("name", "Name", 2) }} {{ th("modified", "Last modified") }} {{ th("size", "Size") }} {% endmacro %} {% macro breadcrumb(ent) %} {% set parent = ent.parent %} {% if parent %} {{ breadcrumb(parent) }} » {% endif %} {% set icon = ent.guess_icon() %} {% if icon %} {% endif %} {% if not ent.is_root() %} {{ ent.name }} {% endif %} {% endmacro %} Flask-AutoIndex-0.5/flask_autoindex/templates/__autoindex__/autoindex.html0000664000175000017500000000201012123622634027730 0ustar subleesublee00000000000000{% from "__autoindex__/macros.html" import entry, thead, breadcrumb with context %} Index of {{ curdir.path }} {% block meta %} {% endblock %} {% block header %}{% endblock %} {% block table %} {{ thead() }} {% if not curdir.is_root() %} {% endif %} {% for ent in entries %} {{ entry(ent) }} {% endfor %}
{% endblock %} {% block footer %} {% set env = request.environ %}
{{ env.SERVER_SOFTWARE }} Server at {{ env.HTTP_HOST }} Port {{ env.SERVER_PORT }}
{% endblock %} Flask-AutoIndex-0.5/flask_autoindex/entry.py0000664000175000017500000002426512123622634022003 0ustar subleesublee00000000000000import os.path import re from urlparse import urljoin from datetime import datetime from mimetypes import guess_type from fnmatch import fnmatch from werkzeug import cached_property from flask import url_for, send_file Default = None def _make_mimetype_matcher(mimetype): return lambda ent: fnmatch(guess_type(ent.name)[0] or '', mimetype) def _make_args_for_entry(args, kwargs): if not args: raise TypeError('path is required, but not given') rootdir = autoindex = None args = list(args) try: path = kwargs.get('path', args.pop(0)) rootdir = kwargs.get('rootdir', args.pop(0)) autoindex = kwargs.get('autoindex', args.pop(0)) except IndexError: pass return (path, rootdir, autoindex) class _EntryMeta(type): """The meta class for :class:`Entry`.""" def __call__(cls, *args, **kwargs): """If an instance already initialized, just returns.""" ent = cls.__new__(cls, *args, **kwargs) try: ent.path except AttributeError: ent.__init__(*args, **kwargs) return ent class Entry(object): """This class wraps file or directory. It is an abstract class, but it returns a derived instance. You can make an instance such as:: directory = Entry('/home/someone/public_html') assert isinstance(foler, Directory) file = Entry('/home/someone/public_html/favicon.ico') assert isinstance(file, File) """ __metaclass__ = _EntryMeta HIDDEN = re.compile('^\.') def __new__(cls, *args, **kwargs): """Returns a file or directory instance.""" path, rootdir, autoindex = _make_args_for_entry(args, kwargs) if rootdir: abspath = os.path.join(rootdir.abspath, path) else: abspath = os.path.abspath(path) if os.path.isdir(abspath): return Directory.__new__(Directory, path, rootdir, autoindex) elif os.path.isfile(abspath): return File.__new__(File, path, rootdir, autoindex) else: raise IOError('{0} does not exists.'.format(abspath)) def __init__(self, path, rootdir=None, autoindex=None): """Initializes an entry instance.""" self.rootdir = rootdir self.autoindex = autoindex try: rootpath = self.rootdir.abspath if not autoindex and self.rootdir: self.autoindex = self.rootdir.autoindex except AttributeError: rootpath = '' self.path = path self.abspath = os.path.join(rootpath, self.path) self.name = os.path.basename(self.abspath) self.hidden = bool(self.HIDDEN.match(self.name)) if self.rootdir: self.rootdir._register_descendant(self) def is_root(self): """Returns ``True`` if it is a root directory.""" return isinstance(self, RootDirectory) @property def parent(self): if self.is_root(): return None elif os.path.samefile(os.path.dirname(self.abspath), self.rootdir.abspath): return self.rootdir return Entry(os.path.dirname(self.path), self.rootdir) @property def modified(self): """Returns modified time of this.""" return datetime.fromtimestamp(os.path.getmtime(self.abspath)) @classmethod def add_icon_rule(cls, icon, rule=None): """Adds a new icon rule globally.""" cls.icon_map.append((icon, rule)) @classmethod def add_icon_rule_by_name(cls, icon, name): """Adds a new icon rule by the name globally.""" cls.add_icon_rule(icon, lambda ent: ent.name == name) @classmethod def add_icon_rule_by_class(cls, icon, _class): """Adds a new icon rule by the class globally.""" cls.add_icon_rule(icon, lambda ent: isinstance(ent, _class)) def guess_icon(self): """Guesses an icon from itself.""" def get_icon_url(): try: if self.autoindex: icon_map = self.autoindex.icon_map + self.icon_map else: icon_map = self.icon_map for icon, rule in icon_map: if not rule and callable(icon): matched = icon = icon(self) else: matched = rule(self) if matched: return icon except AttributeError: pass try: return self.default_icon except AttributeError: raise GuessError('There is no matched icon.') try: return urljoin(url_for('.silkicon', filename=''), get_icon_url()) except (AttributeError, RuntimeError): return get_icon_url() class File(Entry): """This class wraps a file.""" EXTENSION = re.compile('\.([^.]+)$') default_icon = 'page_white.png' icon_map = [] def __new__(cls, path, rootdir=None, autoindex=None): try: return rootdir._descendants[(path, autoindex)] except (AttributeError, KeyError): pass return object.__new__(cls) def __init__(self, path, rootdir=None, autoindex=None): super(File, self).__init__(path, rootdir, autoindex) try: self.ext = re.search(self.EXTENSION, self.name).group(1) except AttributeError: self.ext = None @cached_property def data(self): """Data of this file.""" return ''.join(open(self.abspath).readlines()) @cached_property def mimetype(self): """A mimetype of this file.""" return guess_type(self.abspath) @cached_property def size(self): """A size of this file.""" return os.path.getsize(self.abspath) @classmethod def add_icon_rule_by_ext(cls, icon, ext): """Adds a new icon rule by the file extension globally.""" cls.add_icon_rule(icon, lambda ent: ent.ext == ext) @classmethod def add_icon_rule_by_mimetype(cls, icon, mimetype): """Adds a new icon rule by the mimetype globally.""" cls.add_icon_rule(icon, _make_mimetype_matcher(mimetype)) class Directory(Entry): """This class wraps a directory.""" default_icon = 'folder.png' icon_map = [] def __new__(cls, *args, **kwargs): """If the path is same with root path, it returns a :class:`RootDirectory` object. """ path, rootdir, autoindex = _make_args_for_entry(args, kwargs) if not rootdir: return RootDirectory(path, autoindex) try: return rootdir._descendants[(path, autoindex)] except KeyError: pass rootpath = rootdir.abspath if os.path.samefile(os.path.join(rootpath, path), rootpath): if not rootdir: rootdir = RootDirectory(rootpath, autoindex) return rootdir return object.__new__(cls) def explore(self, sort_by='name', order=1, show_hidden=False): """It is a generator. Each item is a child entry.""" def compare(ent1, ent2): def asc(): if sort_by != 'modified' and type(ent1) is not type(ent2): return 1 if type(ent1) is File else -1 else: try: return cmp(getattr(ent1, sort_by), getattr(ent2, sort_by)) except AttributeError: return cmp(getattr(ent1, 'name'), getattr(ent2, 'name')) return asc() * order if not self.is_root(): yield _ParentDirectory(self) rootdir = self.rootdir else: rootdir = self entries = os.listdir(self.abspath) entries = (Entry(os.path.join(self.path, name), rootdir) \ for name in entries) entries = sorted(entries, cmp=compare) for ent in entries: if show_hidden or not ent.hidden: yield ent def get_child(self, childname): """Returns a child file or directory.""" if childname in self: if self.path != '.': path = os.path.join(self.path, childname) else: path = childname return Entry(path, self.rootdir) else: raise IOError('{0} does not exist'.format(childname)) def __contains__(self, path_or_entry): """Checks this directory has a file or directory. public_html = Directory('public_html') 'favicon.ico' in public_html File('favicon.ico', public_html) in public_html """ if isinstance(path_or_entry, Entry): path = os.path.relpath(path_or_entry.path, self.path) if os.path.pardir in path: return False else: path = path_or_entry return os.path.exists(os.path.join(self.abspath, path)) class RootDirectory(Directory): """This class wraps a root directory.""" default_icon = 'server.png' icon_map = [] _rootdirs = {} def __new__(cls, path, autoindex=None): try: return RootDirectory._rootdirs[(path, autoindex)] except KeyError: return object.__new__(cls) def __init__(self, path, autoindex=None): super(RootDirectory, self).__init__('.', autoindex=autoindex) self.abspath = os.path.abspath(path) self.rootdir = self self._descendants = {} RootDirectory._register_rootdir(self) @classmethod def _register_rootdir(cls, rootdir): cls._rootdirs[(rootdir.abspath, rootdir.autoindex)] = rootdir def _register_descendant(self, entry): self._descendants[(entry.path, entry.autoindex)] = entry class _ParentDirectory(Directory): """This class wraps a parent directory.""" default_icon = 'arrow_turn_up.png' icon_map = [] def __new__(cls, *args, **kwargs): return object.__new__(cls) def __init__(self, child_directory): path = os.path.join(child_directory.path, '..') super(_ParentDirectory, self).__init__(path, child_directory.rootdir) class GuessError(RuntimeError): pass class MarkupError(RuntimeError): pass Flask-AutoIndex-0.5/flask_autoindex/icons.py0000664000175000017500000000510412123622634021744 0ustar subleesublee00000000000000from flask.ext.autoindex.entry import File, Default by_extension = [ ('page_white_python.png', 'py'), ('python.png', 'pyc'), ('page_white_text_width.png', ['md', 'markdown', 'rst', 'rtf']), ('page_white_code.png', ['html', 'htm', 'cgi']), ('page_white_visualstudio.png', ['asp', 'vb']), ('page_white_ruby.png', 'rb'), ('page_code.png', 'xhtml'), ('page_white_code_red.png', ['xml', 'xsl', 'xslt', 'yml']), ('script.png', ['js', 'json', 'applescript', 'htc']), ('layout.png', ['css', 'less']), ('page_white_php.png', 'php'), ('page_white_c.png', 'c'), ('page_white_cplusplus.png', 'cpp'), ('page_white_h.png', 'h'), ('database.png', ['db', 'sqlite', 'sqlite3']), ('page_white_database.png', 'sql'), ('page_white_gear.png', ['conf', 'cfg', 'ini', 'reg', 'sys']), ('page_white_zip.png', ['zip', 'tar', 'gz', 'tgz', '7z', 'alz', 'rar', \ 'bin', 'cab']), ('cup.png', 'jar'), ('page_white_cup.png', ['java', 'jsp']), ('application_osx_terminal.png', 'sh'), ('page_white_acrobat.png', 'pdf'), ('package.png', ['pkg', 'dmg']), ('shape_group.png', ['ai', 'svg', 'eps']), ('application_osx.png', 'app'), ('cursor.png', 'cur'), ('feed.png', 'rss'), ('cd.png', ['iso', 'vcd', 'toast']), ('page_white_powerpoint.png', ['ppt', 'pptx']), ('page_white_excel.png', ['xls', 'xlsx', 'csv']), ('page_white_word.png', ['doc', 'docx']), ('page_white_flash.png', 'swf'), ('page_white_actionscript.png', ['fla', 'as']), ('comment.png', 'smi'), ('disk.png', ['bak', 'bup']), ('application_xp_terminal.png', ['bat', 'com']), ('application.png', 'exe'), ('key.png', 'cer'), ('cog.png', ['dll', 'so']), ('pictures.png', 'ics'), ('error.png', 'log'), ('music.png', 'mpa'), ('font.png', ['ttf', 'eot']), ('vcard.png', 'vcf'), ('page_white.png', Default) ] by_filename = [ ('page_white_gear.png', ['Makefile', 'Rakefile']) ] by_mimetype = [ ('page_white_text.png', 'text/*'), ('picture.png', 'image/*'), ('music.png', 'audio/*'), ('film.png', 'video/*') ] def to_list(val): if not getattr(val, '__iter__', False): return [val] else: return val for icon, exts in by_extension: for ext in to_list(exts): File.add_icon_rule_by_ext(icon, ext) for icon, filenames in by_filename: for name in to_list(filenames): File.add_icon_rule_by_name(icon, name) for icon, mimetypes in by_mimetype: for mimetype in to_list(mimetypes): File.add_icon_rule_by_mimetype(icon, mimetype) Flask-AutoIndex-0.5/flask_autoindex/__init__.py0000664000175000017500000002137012123723644022376 0ustar subleesublee00000000000000""" flask_autoindex ~~~~~~~~~~~~~~~ The mod_autoindex for `Flask `_. :copyright: (c) 2010-2013 by Heungsub Lee. :license: BSD, see LICENSE for more details. """ import os.path import re from werkzeug import cached_property from jinja2 import FileSystemLoader, TemplateNotFound from flask import * from flask.ext.silk import Silk from .entry import * from . import icons __version__ = '0.5' __autoindex__ = '__autoindex__' class AutoIndex(object): """This class makes the Flask application to serve automatically generated index page. The wrapped application will route ``/`` and ``/`` when ``add_url_rules`` is ``True``. Here's a simple example:: app = Flask(__name__) AutoIndex(app, '/home/someone/public_html', add_url_rules=True) :param base: a flask application :param browse_root: a path which is served by root address. :param add_url_rules: if it is ``True``, the wrapped application routes ``/`` and ``/`` to autoindex. default is ``True``. :param **silk_options: keyword options for :class:`flask.ext.silk.Silk` """ shared = None def _register_shared_autoindex(self, state=None, app=None): """Registers a magic module named __autoindex__.""" app = app or state.app if __autoindex__ not in app.blueprints: static_folder = os.path.join(__path__[0], 'static') template_folder = os.path.join(__path__[0], 'templates') shared = Blueprint(__autoindex__, __name__, template_folder=template_folder) @shared.route('/__autoindex__/') def static(filename): return send_from_directory(static_folder, filename) app.register_blueprint(shared) def __new__(cls, base, *args, **kwargs): if isinstance(base, Flask): return object.__new__(AutoIndexApplication) elif isinstance(base, Blueprint): return object.__new__(AutoIndexBlueprint) else: raise TypeError("'base' should be Flask or Blueprint.") def __init__(self, base, browse_root=None, add_url_rules=True, **silk_options): """Initializes an autoindex instance.""" self.base = base if browse_root: self.rootdir = RootDirectory(browse_root, autoindex=self) else: self.rootdir = None silk_options['silk_path'] = silk_options.get('silk_path', '/__icons__') self.silk = Silk(self.base, **silk_options) self.icon_map = [] self.converter_map = [] if add_url_rules: @self.base.route('/') @self.base.route('/') def autoindex(path='.'): return self.render_autoindex(path) def render_autoindex(self, path, browse_root=None, template=None, endpoint='.autoindex'): """Renders an autoindex with the given path. :param path: the relative path :param browse_root: if it is specified, it used to a path which is served by root address. :param template: a template name :param endpoint: an endpoint which is a function """ if browse_root: rootdir = RootDirectory(browse_root, autoindex=self) else: rootdir = self.rootdir path = re.sub(r'\/*$', '', path) abspath = os.path.join(rootdir.abspath, path) if os.path.isdir(abspath): sort_by = request.args.get('sort_by', 'name') order = {'asc': 1, 'desc': -1}[request.args.get('order', 'asc')] curdir = Directory(path, rootdir) entries = curdir.explore(sort_by=sort_by, order=order) if callable(endpoint): endpoint = endpoint.__name__ context = dict(curdir=curdir, entries=entries, sort_by=sort_by, order=order, endpoint=endpoint) if template: return render_template(template, **context) try: template = '{0}autoindex.html'.format(self.template_prefix) return render_template(template, **context) except TemplateNotFound as e: template = '{0}/autoindex.html'.format(__autoindex__) return render_template(template, **context) elif os.path.isfile(abspath): return send_file(abspath) else: return abort(404) def add_icon_rule(self, icon, rule=None, ext=None, mimetype=None, name=None, filename=None, dirname=None, cls=None): """Adds a new icon rule. There are many shortcuts for rule. You can use one or more shortcuts in a rule. `rule` A function which returns ``True`` or ``False``. It has one argument which is an instance of :class:`Entry`. Example usage:: def has_long_name(ent): return len(ent.name) > 10 idx.add_icon_rule('brick.png', rule=has_log_name) Now the application represents files or directorys such as ``very-very-long-name.js`` with ``brick.png`` icon. `ext` A file extension or file extensions to match with a file:: idx.add_icon_rule('ruby.png', ext='ruby') idx.add_icon_rule('bug.png', ext=['bug', 'insect']) `mimetype` A mimetype or mimetypes to match with a file:: idx.add_icon_rule('application.png', mimetype='application/*') idx.add_icon_rule('world.png', mimetype=['image/icon', 'x/*']) `name` A name or names to match with a file or directory:: idx.add_icon_rule('error.png', name='error') idx.add_icon_rule('database.png', name=['mysql', 'sqlite']) `filename` Same as `name`, but it matches only a file. `dirname` Same as `name`, but it matches only a directory. If ``icon`` is callable, it is used to ``rule`` function and the result is used to the url for an icon. This way is useful for getting an icon url dynamically. Here's a nice example:: def get_favicon(ent): favicon = 'favicon.ico' if type(ent) is Directory and favicon in ent: return '/' + os.path.join(ent.path, favicon) return False idx.add_icon_rule(get_favicon) Now a directory which has a ``favicon.ico`` guesses the ``favicon.ico`` instead of silk's ``folder.png``. """ if name: filename = name directoryname = name if ext: File.add_icon_rule_by_ext.im_func(self, icon, ext) if mimetype: File.add_icon_rule_by_mimetype.im_func(self, icon, mimetype) if filename: File.add_icon_rule_by_name.im_func(self, icon, filename) if dirname: Directory.add_icon_rule_by_name.im_func(self, icon, dirname) if cls: Entry.add_icon_rule_by_class.im_func(self, icon, cls) if callable(rule) or callable(icon): Entry.add_icon_rule.im_func(self, icon, rule) @property def template_prefix(self): raise NotImplementedError() class AutoIndexApplication(AutoIndex): """An AutoIndex which supports flask applications.""" template_prefix = '' def __init__(self, app, browse_root=None, **silk_options): super(AutoIndexApplication, self).__init__(app, browse_root, **silk_options) self.app = app self._register_shared_autoindex(app=self.app) class AutoIndexBlueprint(AutoIndex): """An AutoIndex which supports flask blueprints. .. versionadded:: 0.3.1 """ def __init__(self, blueprint, browse_root=None, **silk_options): super(AutoIndexBlueprint, self).__init__(blueprint, browse_root, **silk_options) self.blueprint = self.base self.blueprint.record_once(self._register_shared_autoindex) @cached_property def template_prefix(self): return self.blueprint.name + '/' class AutoIndexModule(AutoIndexBlueprint): """Deprecated module support. .. versionchanged:: 0.3.1 ``AutoIndexModule`` was deprecated. Use ``AutoIndexBlueprint`` instead. """ def __init__(self, *args, **kwargs): import warnings warnings.warn('AutoIndexModule is deprecated; ' \ 'use AutoIndexBlueprint instead.', DeprecationWarning) super(AutoIndexModule, self).__init__(*args, **kwargs) @property def mod(self): return self.blueprint Flask-AutoIndex-0.5/README0000644000175000017500000000007711567652410015767 0ustar subleesublee00000000000000Flask-AutoIndex A mod_autoindex for Flask. Under development. Flask-AutoIndex-0.5/setup.cfg0000664000175000017500000000020412124040374016710 0ustar subleesublee00000000000000[build_sphinx] source-dir = docs/ build-dir = docs/_build all_files = 1 [egg_info] tag_build = tag_date = 0 tag_svn_revision = 0