Search code examples
pythonflaskdirectory-structurestatic-files

Display content of files in a particular directory using Flask


I am implementing an app using Flask and I am trying to display the content of text files I put in log directory. So i have done this:

@app.route('/files', methods = ['GET'])
def config():
    if 'username' in session :
        path = os.path.expanduser(u'~/path/to/log/')
        return render_template('files.html', tree=make_tree(path))
    else:
        return redirect(url_for('login'))

def make_tree(path):
    tree = dict(name=os.path.basename(path), children=[])
    try: lst = os.listdir(path)
    except OSError:
        pass #ignore errors
    else:
        for name in lst:
            fn = os.path.join(path, name)
            if os.path.isdir(fn):
                tree['children'].append(make_tree(fn))
            else:
                tree['children'].append(dict(name=name))
    return tree

in my html page files.html:

<title>Path: {{ tree.name }}</title>
<h1>{{ tree.name }}</h1>

<div class="accordion-heading" >
    <div class="accordion-toggle" >
         <a data-toggle="collapse"  data-target="#files_list" href="#files_list">
            <b>

<ul>
{%- for item in tree.children recursive %}
 <div class="well well-sm">   <li>{{ item.name }} </div>
    {%- if item.children -%}
        <ul>{{ loop(item.children) }}</ul>
    {%- endif %}</li>
{%- endfor %}
</ul>

 </b></div>
         </a>
    </div>

This only displays the names of the files inside my log directory but I am not able to display the content of the files. I thought maybe I can use something like:

import fnmatch
def display_files():
    for dirpath, dirs, files in os.walk('log'):
        for filename in fnmatch.filter(files, '*.*'):
        with open(os.path.join(dirpath, filename)) as f:
            file_contents = f.read().strip()
            print file_contents

    return render_template('files.html',title="index",file_contents=file_contents) 

Any help please??


Solution

  • You probably can read contents of your file and pass it to template in make_tree function like that:

    def make_tree(path):
        tree = dict(name=os.path.basename(path), children=[])
        try: lst = os.listdir(path)
        except OSError:
            pass #ignore errors
        else:
            for name in lst:
                fn = os.path.join(path, name)
                if os.path.isdir(fn):
                    tree['children'].append(make_tree(fn))
                else:
                    with open(fn) as f:
                        contents = f.read()
                    tree['children'].append(dict(name=name, contents=contents))
        return tree
    

    and just add <pre>{{ item.contents }}</pre> to the place where you want to display the contents of the file. For example, here:

    {%- for item in tree.children recursive %}
         <div class="well well-sm">
            <li>
                {{ item.name }}
                <pre>{{ item.contents }}</pre>
                {%- if item.children -%}
                    <ul>{{ loop(item.children) }}</ul>
                {%- endif %}
            </li>
        </div>
    {%- endfor %}
    

    This is kind of ugly, but it should show the correct data.