Skip to content

Commit

Permalink
Added folder and search capability
Browse files Browse the repository at this point in the history
  • Loading branch information
sv1jsb committed Sep 16, 2012
1 parent 7421115 commit ed5537e
Show file tree
Hide file tree
Showing 4 changed files with 130 additions and 25 deletions.
57 changes: 47 additions & 10 deletions app.py
Original file line number Original file line Diff line number Diff line change
@@ -1,14 +1,15 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- 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 werkzeug import secure_filename
from beefish import decrypt, encrypt from beefish import decrypt, encrypt
import boto import boto
from StringIO import StringIO from StringIO import StringIO
from peewee import * from peewee import *
import mimetypes import mimetypes
import datetime import datetime
import os.path


DEBUG = True DEBUG = True
SECRET_KEY = "kas45hdas67dhkasd8aksd78ad7" SECRET_KEY = "kas45hdas67dhkasd8aksd78ad7"
Expand All @@ -29,7 +30,9 @@ class Meta:
filename = CharField() filename = CharField()
created_date = DateTimeField(default=datetime.datetime.now) created_date = DateTimeField(default=datetime.datetime.now)
encrypted = BooleanField(default=False) encrypted = BooleanField(default=False)

folder = BooleanField(default=False)
parent = CharField(null=True)

def get_mimetype(self): def get_mimetype(self):
return mimetypes.guess_type(self.filename)[0] return mimetypes.guess_type(self.filename)[0]


Expand All @@ -43,7 +46,7 @@ def create_tables():


def upload_handler(instance, file_obj): def upload_handler(instance, file_obj):
bucket = get_bucket(app.config['AWSID'], app.config['AWSKEY'], app.config['AWSBUCKET']) 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(): if instance.get_mimetype():
key.set_metadata('Content-Type', instance.get_mimetype()) key.set_metadata('Content-Type', instance.get_mimetype())


Expand All @@ -64,13 +67,28 @@ def upload_handler(instance, file_obj):


@app.route('/') @app.route('/')
def index(): 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']) @app.route('/add/', methods=['POST'])
def add(): def add():
if request.files['file']: if request.files['file']:
file_obj = 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: try:
upload_handler(instance, file_obj) upload_handler(instance, file_obj)
except: except:
Expand All @@ -79,8 +97,17 @@ def add():
else: else:
instance.save() instance.save()
else: else:
flash("You did not choose a file! Try again") flash("You did not choose a file! Try again.")
return redirect(url_for('index')) 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']) @app.route('/download/<int:file_id>/', methods=['GET', 'POST'])
def download(file_id): def download(file_id):
Expand All @@ -91,7 +118,7 @@ def download(file_id):


# fetch the encrypted file contents from S3 and store in a memory # fetch the encrypted file contents from S3 and store in a memory
bucket = get_bucket(app.config['AWSID'], app.config['AWSKEY'], app.config['AWSBUCKET']) 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 # read the contents of the key into an in-memory file
enc_buffer = StringIO() enc_buffer = StringIO()
Expand Down Expand Up @@ -131,14 +158,24 @@ def delete(file_id):
except File.DoesNotExist: except File.DoesNotExist:
abort(404) abort(404)
bucket = get_bucket(app.config['AWSID'], app.config['AWSKEY'], app.config['AWSBUCKET']) 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: if key_obj:
try: try:
key_obj.delete() key_obj.delete()
except: except:
flash("There was an error deleting your file from S3!") flash("There was an error deleting your file from S3!")
file.delete_instance() 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__': if __name__ == '__main__':
app.run() app.run()
13 changes: 3 additions & 10 deletions templates/base.html
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -44,23 +44,16 @@
</a> </a>
<a class="brand" href="/">AWS Encrypted Files</a> <a class="brand" href="/">AWS Encrypted Files</a>
<div class="nav-collapse"> <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><!--/.nav-collapse -->
</div> </div>
</div> </div>


</div> </div>


<div class="container"> <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 %} {% block content %}
{% endblock %} {% endblock %}


Expand Down
63 changes: 58 additions & 5 deletions templates/index.html
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -14,36 +14,89 @@ <h3>Add file</h3>
<label>Password</label> <label>Password</label>
<input type="password" name="password" /> <input type="password" name="password" />
<div class="form-actions"> <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> <a href="javascript:void(0);" class="btn" data-dismiss="modal">Cancel</a>
</div> </div>
</fieldset> </fieldset>
</form> </form>
</div> </div>
</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"> <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> </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> <h3>File list</h3>
<table class="table table-striped"> <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> <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 %} {% 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 %} {% endfor %}
</tbody> </tbody>
</table> </table>
{% endblock %} {% endblock %}
{% block scripts %} {% block scripts %}
<script type="text/javascript"> <script type="text/javascript">
$(document).ready(function() {
if ($("#message")){
setTimeout(function(){$("#message").hide()},5000);
}
});
function showAddFile(){ function showAddFile(){
$("#AddFile").modal("show"); $("#AddFile").modal("show");
} }
function showMkDir(){
$("#MkDir").modal("show");
}
function downloadFile(obj, file_id) { function downloadFile(obj, file_id) {
if($(obj).parents("tr").children("#encrypted").html() == "False"){ if($(obj).parents("tr").children("#encrypted").html() == "False"){
return true; return true;
} else { } 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; return false;
} }
} }
Expand Down
22 changes: 22 additions & 0 deletions templates/search_results.html
Original file line number Original file line Diff line number Diff line change
@@ -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 %}

0 comments on commit ed5537e

Please sign in to comment.