Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Added folder and search capability

  • Loading branch information...
commit ed5537efefbca4bddc9d6042486dfad10890dce1 1 parent 7421115
@sv1jsb authored
View
57 app.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-from flask import Flask, redirect, render_template, send_file, url_for, request, flash
+from flask import Flask, redirect, render_template, send_file, url_for, request, flash, session, abort
from werkzeug import secure_filename
from beefish import decrypt, encrypt
import boto
@@ -9,6 +9,7 @@
from peewee import *
import mimetypes
import datetime
+import os.path
DEBUG = True
SECRET_KEY = "kas45hdas67dhkasd8aksd78ad7"
@@ -29,7 +30,9 @@ class Meta:
filename = CharField()
created_date = DateTimeField(default=datetime.datetime.now)
encrypted = BooleanField(default=False)
-
+ folder = BooleanField(default=False)
+ parent = CharField(null=True)
+
def get_mimetype(self):
return mimetypes.guess_type(self.filename)[0]
@@ -43,7 +46,7 @@ def create_tables():
def upload_handler(instance, file_obj):
bucket = get_bucket(app.config['AWSID'], app.config['AWSKEY'], app.config['AWSBUCKET'])
- key = bucket.new_key(instance.filename)
+ key = bucket.new_key(os.path.join(instance.parent,instance.filename))
if instance.get_mimetype():
key.set_metadata('Content-Type', instance.get_mimetype())
@@ -64,13 +67,28 @@ def upload_handler(instance, file_obj):
@app.route('/')
def index():
- return render_template('index.html', files=File.select().order_by('filename'))
+ if request.args.get('folder',None):
+ folder = request.args.get('folder')
+ session['folder'] = os.path.join('/',folder)
+ else:
+ session['folder'] = '/'
+ files = File.filter(parent=session['folder']).order_by((File,'folder','DESC'),(File,'filename'))
+ if session['folder'].endswith('/'):
+ path=session['folder']
+ else:
+ path=session['folder']+'/'
+ tmp = path[:-1].split('/')
+ breads = []
+ for i in range(1,len(tmp)+1):
+ breads.append({'url':'/'.join(tmp[0:i]),'name':tmp[i-1]})
+ breads[0]={'url':'/','name':'Home'}
+ return render_template('index.html', files=files, breads=breads, path=path)
@app.route('/add/', methods=['POST'])
def add():
if request.files['file']:
file_obj = request.files['file']
- instance = File.get_or_create(filename=secure_filename(file_obj.filename))
+ instance = File.get_or_create(parent = session['folder'], filename = secure_filename(file_obj.filename))
try:
upload_handler(instance, file_obj)
except:
@@ -79,8 +97,17 @@ def add():
else:
instance.save()
else:
- flash("You did not choose a file! Try again")
- return redirect(url_for('index'))
+ flash("You did not choose a file! Try again.")
+ return redirect(url_for('index')+'?folder=%s'%session['folder'])
+
+@app.route('/mkdir/', methods=['POST'])
+def mkdir():
+ if request.form.get('directory'):
+ instance = File(parent=session['folder'],folder=True,filename = secure_filename(request.form.get('directory')))
+ instance.save()
+ else:
+ flash("You did not provide a directory name! Try again.")
+ return redirect(url_for('index')+'?folder=%s'%session['folder'])
@app.route('/download/<int:file_id>/', methods=['GET', 'POST'])
def download(file_id):
@@ -91,7 +118,7 @@ def download(file_id):
# fetch the encrypted file contents from S3 and store in a memory
bucket = get_bucket(app.config['AWSID'], app.config['AWSKEY'], app.config['AWSBUCKET'])
- key_obj = bucket.get_key(file.filename)
+ key_obj = bucket.get_key(os.path.join(file.parent,file.filename))
# read the contents of the key into an in-memory file
enc_buffer = StringIO()
@@ -131,14 +158,24 @@ def delete(file_id):
except File.DoesNotExist:
abort(404)
bucket = get_bucket(app.config['AWSID'], app.config['AWSKEY'], app.config['AWSBUCKET'])
- key_obj = bucket.get_key(file.filename)
+ key_obj = bucket.get_key(os.path.join(file.parent,file.filename))
if key_obj:
try:
key_obj.delete()
except:
flash("There was an error deleting your file from S3!")
file.delete_instance()
- return redirect(url_for('index'))
+ return redirect(url_for('index')+'?folder=%s'%session['folder'])
+
+@app.route('/search/')
+def search():
+ if request.args.get('q',None):
+ files = File.filter(filename__icontains=request.args.get('q')).order_by((File,'folder','DESC'),(File,'filename'))
+ if files.count() == 0:
+ files=None
+ return render_template('search_results.html', files=files)
+ else:
+ return redirect(url_for('index')+'?folder=%s'%session['folder'])
if __name__ == '__main__':
app.run()
View
13 templates/base.html
@@ -44,6 +44,9 @@
</a>
<a class="brand" href="/">AWS Encrypted Files</a>
<div class="nav-collapse">
+ <form class="navbar-search pull-right" method="get" action="/search/">
+ <input type="text" name="q" class="search-query" placeholder="Search">
+ </form>
</div><!--/.nav-collapse -->
</div>
</div>
@@ -51,16 +54,6 @@
</div>
<div class="container">
- {% with messages = get_flashed_messages() %}
- {% if messages %}
- <div class="alert alert-error">
- <button type="button" class="close" data-dismiss="alert">×</button>
- {% for message in messages %}
- <strong>Error!</strong> {{ message }}
- {% endfor %}
- </div>
- {% endif %}
- {% endwith %}
{% block content %}
{% endblock %}
View
63 templates/index.html
@@ -14,36 +14,89 @@
<label>Password</label>
<input type="password" name="password" />
<div class="form-actions">
- <button type="submit" class="btn btn-primary">Upload</button>
+ <button type="submit" class="btn btn-primary"><i class="icon-upload"></i> Upload</button>
<a href="javascript:void(0);" class="btn" data-dismiss="modal">Cancel</a>
</div>
</fieldset>
</form>
</div>
</div>
+<div class="modal fade hide" id="MkDir">
+ <div class="modal-header">
+ <button type="button" class="close" data-dismiss="modal">×</button>
+ <h3>New folder</h3>
+ </div>
+ <div class="modal-body" id="MkDirBody">
+ <form method="post" action="/mkdir/">
+ <fieldset>
+ <label>Folder name</label>
+ <input type="text" name="directory" />
+ <div class="form-actions">
+ <button type="submit" class="btn btn-primary"><i class="icon-folder-close"></i> Create</button>
+ <a href="javascript:void(0);" class="btn" data-dismiss="modal">Cancel</a>
+ </div>
+ </fieldset>
+ </form>
+ </div>
+</div>
+{% with messages = get_flashed_messages() %}
+ {% if messages %}
+ <div class="alert alert-error" id="message">
+ <button type="button" class="close" data-dismiss="alert">×</button>
+ {% for message in messages %}
+ <strong>Error!</strong> {{ message }}
+ {% endfor %}
+ </div>
+ {% endif %}
+{% endwith %}
<div class="well">
- <button class="btn btn-primary" onclick="showAddFile();">Add files</button>
+ <button class="btn btn-primary" onclick="showAddFile();"><i class="icon-upload"></i> Add file</button> <button class="btn btn-primary" onclick="showMkDir();"><i class="icon-folder-close"></i> New Folder</button>
</div>
+<ul class="breadcrumb">
+{% for bread in breads %}
+ {% if loop.last %}
+ <li class="active">{{bread.name}}</li>
+ {% else %}
+ <li><a href="/?folder={{bread.url}}">{{bread.name}}</a> <span class="divider">/</span></li>
+ {% endif %}
+{% endfor %}
+</ul>
+
<h3>File list</h3>
<table class="table table-striped">
-<thead><th>Name</th><th>Encrypted</th><th>Actions</th></thead>
+<thead><th style="width:12px;">&nbsp;</th><th>Name</th><th>Encrypted</th><th>Actions</th></thead>
<tbody>
+{% if path != '/' %}
+<tr><td><i class="icon-folder-close"></i></td><td><a href="/?folder={{breads[-2].url}}">..</a></td><td>&nbsp;</td><td>&nbsp;</td></tr>
+{% endif %}
{% for file in files %}
-<tr><td><a href="/download/{{file.id}}/" onclick="return downloadFile(this,'{{file.id}}');">{{file.filename}}</a></td><td id="encrypted">{{file.encrypted}}</td><td><a href="/delete/{{file.id}}/" onclick="return confirm('Are you sure?')">Delete</a></td></tr>
+{% if file.folder %}
+<tr><td><i class="icon-folder-close"></i></td><td><a href="/?folder={{path}}{{file.filename}}">{{file.filename}}</a></td><td>&nbsp;</td><td><a href="/delete/{{file.id}}/" onclick="return confirm('Are you sure?')">Delete</a></td></tr>
+{% else %}
+<tr><td>&nbsp;</td><td><a href="/download/{{file.id}}/" onclick="return downloadFile(this,'{{file.id}}');">{{file.filename}}</a></td><td id="encrypted">{{file.encrypted}}</td><td><a href="/delete/{{file.id}}/" onclick="return confirm('Are you sure?')">Delete</a></td></tr>
+{% endif %}
{% endfor %}
</tbody>
</table>
{% endblock %}
{% block scripts %}
<script type="text/javascript">
+$(document).ready(function() {
+ if ($("#message")){
+ setTimeout(function(){$("#message").hide()},5000);
+ }
+});
function showAddFile(){
$("#AddFile").modal("show");
}
+function showMkDir(){
+ $("#MkDir").modal("show");
+}
function downloadFile(obj, file_id) {
if($(obj).parents("tr").children("#encrypted").html() == "False"){
return true;
} else {
- $(obj).parents('tr').after('<tr id="passwordtr"><td colspan=3><form method="post" action="/download/'+file_id+'/" class="form-inline" name="passwordform">Password: <input type="password" name="password" /> <button class="btn btn-primary" onclick="return submitpassform(this);">Download</button> <button class="btn" onclick="deletepasstr();">Cancel</button></form></td></tr>');
+ $(obj).parents('tr').after('<tr id="passwordtr"><td colspan=3><form method="post" action="/download/'+file_id+'/" class="form-inline" name="passwordform">Password: <input type="password" name="password" /> <button class="btn btn-primary" onclick="return submitpassform(this);"><i class="icon-download-alt"></i> Download</button> <button class="btn" onclick="deletepasstr();">Cancel</button></form></td></tr>');
return false;
}
}
View
22 templates/search_results.html
@@ -0,0 +1,22 @@
+{% extends "base.html" %}
+{% block content %}
+<h3>Search results</h3>
+{% if files %}
+<table class="table table-striped">
+<thead><th style="width:12px;">&nbsp;</th><th>Name</th><th>Encrypted</th><th>Path</th></thead>
+<tbody>
+{% for file in files %}
+ {% if file.folder %}
+ <tr><td><i class="icon-folder-close"></i></td><td><a href="/?folder={{file.parent}}">{{file.filename}}</a></td><td>&nbsp;</td><td>{{file.parent}}</td></tr>
+ {% else %}
+ <tr><td>&nbsp;</td><td><a href="/?folder={{file.parent}}">{{file.filename}}</a></td><td id="encrypted">{{file.encrypted}}</td><td>{{file.parent}}</td></tr>
+ {% endif %}
+{% endfor %}
+</tbody>
+</table>
+{% else %}
+ <br />
+ <div class="alert">Your query had no results!</div>
+{% endif %}
+{% endblock %}
+
Please sign in to comment.
Something went wrong with that request. Please try again.