diff options
Diffstat (limited to 'fbin/templates')
-rw-r--r-- | fbin/templates/base.html | 70 | ||||
-rw-r--r-- | fbin/templates/file-modals.html | 59 | ||||
-rw-r--r-- | fbin/templates/files.html | 73 | ||||
-rw-r--r-- | fbin/templates/help.html | 30 | ||||
-rw-r--r-- | fbin/templates/images.html | 29 | ||||
-rw-r--r-- | fbin/templates/modal.html | 17 | ||||
-rw-r--r-- | fbin/templates/upload.html | 25 | ||||
-rw-r--r-- | fbin/templates/uploaded.html | 14 |
8 files changed, 317 insertions, 0 deletions
diff --git a/fbin/templates/base.html b/fbin/templates/base.html new file mode 100644 index 0000000..bab0f7b --- /dev/null +++ b/fbin/templates/base.html @@ -0,0 +1,70 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <title>{{ config.SITE_NAME }}{% if title %} — {{ title }}{% endif %}</title> + <link rel="stylesheet" href="{{ url_for('static', filename = 'css/bootstrap.min.css') }}" type="text/css"> + <link rel="stylesheet" href="{{ url_for('static', filename = 'css/style.css') }}" type="text/css"> +{% block head %} +{% endblock %} +</head> +<body> +<nav class="navbar navbar-default navbar-inverse navbar-static-top"> + <div id="container-fluid"> + <div id="navbar-header"> + <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar"> + <span class="sr-only">Toggle navigation</span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + </button> + <a class="navbar-brand" href="{{ url_for('.index') }}">{{ config.SITE_NAME }}</a> + </div> + <div id="navbar" class="collapse navbar-collapse"> + <ul class="nav navbar-nav"> + {{ nav_html('.upload', 'Upload') }} + {% if current_user.is_authenticated %} + {{ nav_html('.files', 'Files') }} + {{ nav_html('.images', 'Images') }} + {{ nav_html('.account', 'Account') }} + {{ nav_html('.logout', 'Logout') }} + {% else %} + {{ nav_html('.login', 'Login') }} + {% endif %} + {# nav_html('.help', 'Help') #} + </ul> + </div> + </div> +</nav> +<div id="content" class="{% if fullwidth %}container-fluid{% else %}container{% endif %}"> +{% if title %} + <div class="page-header"> + <h1> + {{ title }} + {% if subtitle %} + <small>{{ subtitle }}</small> + {% endif %} + </h1> + </div> +{% endif %} +{% with messages = get_flashed_messages(with_categories = True) %} +{% for category, message in messages %} +<div class="alert alert-{{ {'error': 'danger', 'warning': 'warning', 'success': 'success'}.get(category, 'info') }}" role="alert"> + <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button> + {{ message }} +</div> +{% endfor %} +{% endwith %} +{% block content %} +{% endblock %} +</div> +<script src="{{ url_for('static', filename = 'js/jquery.min.js') }}"></script> +<script src="{{ url_for('static', filename = 'js/jquery.lazy.min.js') }}"></script> +<script src="{{ url_for('static', filename = 'js/bootstrap.min.js') }}"></script> +<script src="{{ url_for('static', filename = 'js/bootstrap-filestyle.min.js') }}"></script> +{% block scripts %} +{% endblock %} +</body> +</html> diff --git a/fbin/templates/file-modals.html b/fbin/templates/file-modals.html new file mode 100644 index 0000000..9e4d422 --- /dev/null +++ b/fbin/templates/file-modals.html @@ -0,0 +1,59 @@ +<div class="modal fade" id="modal-filename" tabindex="-1" role="dialog" aria-labelledby="modal-filename-label"> + <div class="modal-dialog" role="document"> + <div class="modal-content"> + <div class="modal-header"> + <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> + <h4 class="modal-title" id="modal-filename-label">Change filename</h4> + </div> + <div class="modal-body"> + <form method="post" action="{{ url_for('.file_edit') }}" id="filename-form"> + <input type="hidden" class="hash" name="hash"> + <div class="form-group"> + <label for="filename" class="control-label">Filename:</label> + <input type="text" class="form-control" id="filename" name="filename"> + </div> + <div id="modal-filename-spinner"> + <span class="glyphicon glyphicon-cog spinner" aria-hidden="true"></span> + Saving… + </div> + </form> + </div> + <div class="modal-footer"> + <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button> + <button type="submit" class="btn btn-primary" id="modal-filename-confirm" form="filename-form"> + <span class="glyphicon glyphicon-floppy-disk" aria-hidden="true"></span> + Save changes + </button> + </div> + </div> + </div> +</div> +<div class="modal fade" id="modal-delete" tabindex="-1" role="dialog" aria-labelledby="modal-delete-label"> + <div class="modal-dialog" role="document"> + <div class="modal-content"> + <div class="modal-header"> + <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> + <h4 class="modal-title" id="modal-delete-label">Delete file</h4> + </div> + <div class="modal-body"> + <form method="post" action="{{ url_for('.file_edit') }}" id="delete-form"> + <input type="hidden" class="hash" name="hash"> + <input type="hidden" name="delete" value="1"> + Are you sure you want to delete the file <strong><span id="modal-delete-filename"></span></strong>? + This cannot be undone. + <div id="modal-delete-spinner"> + <span class="glyphicon glyphicon-cog spinner" aria-hidden="true"></span> + Deleting… + </div> + </form> + </div> + <div class="modal-footer"> + <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button> + <button type="submit" class="btn btn-danger" id="modal-delete-confirm" form="delete-form"> + <span class="glyphicon glyphicon-remove" aria-hidden="true"></span> + Delete + </button> + </div> + </div> + </div> +</div> diff --git a/fbin/templates/files.html b/fbin/templates/files.html new file mode 100644 index 0000000..cae04fa --- /dev/null +++ b/fbin/templates/files.html @@ -0,0 +1,73 @@ +{% extends "base.html" %} +{% block content %} +<p>You have {{ files|length() }} uploaded files totaling {{ total_size }}.</p> +<table class="table table-striped"> +<thead> + <tr> + <th>File</th> + <th></th> + <th>Size</th> + <th>Date</th> + <th></th> + </tr> +</thead> +<tbody> + {% for file in files %} + <tr> + <td> + <a href="{{ url_for('.file', hash = file.hash, filename = file.filename) }}" id="filename-{{ loop.index }}">{{ file.filename }}</a> + </td> + <td> + <small> + <a href="{{ url_for('.file', hash = file.hash) }}">hash</a> + {% if file.ext %} + – <a href="{{ url_for('.file', hash = file.hash, ext = file.ext) }}">ext.</a> + {% endif %} + </small> + </td> + <td>{{ file.formatted_size }}</td> + <td>{{ file.formatted_date }}</td> + <td> + <button type="button" class="btn btn-primary btn-xs" data-toggle="modal" data-target="#modal-filename" data-index="{{ loop.index }}" data-file-hash="{{ file.hash }}"> + <span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> + <span class="sr-only">Rename</span> + </button> + <button type="button" class="btn btn-danger btn-xs" data-toggle="modal" data-target="#modal-delete" data-index="{{ loop.index }}" data-file-hash="{{ file.hash }}"> + <span class="glyphicon glyphicon-remove" aria-hidden="true"></span> + <span class="sr-only">Delete</span> + </button> + </td> + </tr> + {% else %} + <tr><td><em>(No file uploads yet.)</em></td></tr> + {% endfor %} +</tbody> +</table> +{% include "file-modals.html" %} +{% endblock %} +{% block scripts %} +<script> +$('#modal-filename').on('show.bs.modal', function(event) { + $('#modal-filename-spinner').hide(); + var button = $(event.relatedTarget); + var filename = $('#filename-' + button.data('index')).text().trim(); + $(this).find('input#filename').val(filename); + $(this).find('input.hash').val(button.data('file-hash')); +}).on('shown.bs.modal', function(event) { + $(this).find('input#filename').focus(); +}); +$('#modal-filename-confirm').click(function(event) { + $('#modal-filename-spinner').show(); +}); +$('#modal-delete').on('show.bs.modal', function(event) { + $('#modal-delete-spinner').hide(); + var button = $(event.relatedTarget); + var filename = $('#filename-' + button.data('index')).text().trim(); + $(this).find('#modal-delete-filename').text(filename); + $(this).find('input.hash').val(button.data('file-hash')); +}); +$('#modal-delete-confirm').click(function(event) { + $('#modal-delete-spinner').show(); +}); +</script> +{% endblock %} diff --git a/fbin/templates/help.html b/fbin/templates/help.html new file mode 100644 index 0000000..899cd78 --- /dev/null +++ b/fbin/templates/help.html @@ -0,0 +1,30 @@ +{% extends "base.html" %} +{% block content %} +<div class="alert alert-danger"> + <h2> + <span class="glyphicon glyphicon-alert" aria-hidden="true"></span> + TODO: Update this page. + </h2> +</div> +<div class="alert alert-warning"> + <span class="glyphicon glyphicon-alert" aria-hidden="true"></span> + Everything below this point is outdated and should be disregarded until further notice. +</div> +<s> +<p>Usage: POST to <a href="$scheme://${host}${settings.virtual_root}u">$scheme://${host}${settings.virtual_root}u</a> with filedata given to "file" and original filename to "filename". Login is done by generating a login token and sending it as the cookie "token".</p> +<p>cURL examples, <code>get_token</code>: +<blockquote><pre><code>$ curl $scheme://${host}${settings.virtual_root}a?method=get_token -F username=foo -F password=bar +{"status": true, "message": null, "method": "get_token", "token": "cb42eb38eb516d9dfcaaa742d1da0b3ad454b2bd05a8b4daa6d01e9587d7c759"}</code></pre></blockquote> +Upload using the token: +<blockquote><pre><code>$ curl -b 'token=cb42eb38eb516d9dfcaaa742d1da0b3ad454b2bd05a8b4daa6d01e9587d7c759' -F 'file=@image.png' -F 'filename=image.png' -F 'api=1' $scheme://${host}${settings.virtual_root}u +OK sjLUD</code></pre></blockquote> +To expire the current token: +<blockquote><pre><code>$ curl $scheme://${host}${settings.virtual_root}a?method=expire_token -F token=cb42eb38eb516d9dfcaaa742d1da0b3ad454b2bd05a8b4daa6d01e9587d7c759 +{"status": true, "message": null, "method": "expire_token"}</code></pre></blockquote> +If you get HTTP 417 responses, try adding:<code>-H 'Expect:'</code>.</p> +<p>By adding the key-value pair "api=1" you will get machine-readable responses in the form: <code>response result</code> where <code>response</code> is either <code>ERROR</code> or <code>OK</code>, +and <code>result</code> is the file hash in the case of <code>OK</code>, or an error message in the case of <code>ERROR</code> (see example above). +The hash can be used to construct URLs in which the paths begin with <code>/f/hash</code> where <code>hash</code> is the hash received.</p> +<p>Any file extension an be appended to the hash, and for convenience the original filename (or whatever filename you prefer) can be appended after an additional slash after the hash.</p> +</s> +{% endblock %} diff --git a/fbin/templates/images.html b/fbin/templates/images.html new file mode 100644 index 0000000..c4bfd8f --- /dev/null +++ b/fbin/templates/images.html @@ -0,0 +1,29 @@ +{% extends "base.html" %} +{% block content %} +<p>You have {{ files|length() }} uploaded images totaling {{ total_size }}.</p> +{% if files %} +<div class="row"> + {% for file in files %} + <div class="image-thumbnail"> + <a href="{{ url_for('.file', hash = file.hash, ext = file.ext) }}" title="{{ file.filename }}" class="thumbnail"> + <img class="lazy" data-src="{{ url_for('.thumb', hash = file.hash) }}" alt="{{ file.filename }}"> + <noscript><img src="{{ url_for('.thumb', hash = file.hash) }}" alt="{{ file.filename }}"></noscript> + </a> + </div> + {% endfor %} +</div> +{% else %} +<div><em>(No image uploads yet.)</em></div> +{% endif %} +{% endblock %} +{% block scripts %} +<script> +$(document).ready(function() { + $('img.lazy').Lazy({ + onError: function(element) { + element.attr('src', '{{ url_for('static', filename = 'img/no-thumbnail.png') }}'); + } + }); +}); +</script> +{% endblock %} diff --git a/fbin/templates/modal.html b/fbin/templates/modal.html new file mode 100644 index 0000000..ca9fb5a --- /dev/null +++ b/fbin/templates/modal.html @@ -0,0 +1,17 @@ +<div class="modal fade" tabindex="-1" role="dialog"> + <div class="modal-dialog" role="document"> + <div class="modal-content"> + <div class="modal-header"> + <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> + <h4 class="modal-title">Title</h4> + </div> + <div class="modal-body"> + … + </div> + <div class="modal-footer"> + <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button> + <button type="button" class="btn btn-primary">Ok</button> + </div> + </div> + </div> +</div> diff --git a/fbin/templates/upload.html b/fbin/templates/upload.html new file mode 100644 index 0000000..643e09d --- /dev/null +++ b/fbin/templates/upload.html @@ -0,0 +1,25 @@ +{% extends "base.html" %} +{% block content %} +{% if current_user.is_authenticated or config.ALLOW_ANONYMOUS_UPLOADS %} +<form method="post" enctype="multipart/form-data" class="form-horizontal"> + <div class="form-group"> + <input type="file" name="file" style="display: none" onchange="$('#file-filename').text($('#file').val())"> + </div> + <div class="form-group"> + <button type="submit" value="Upload" class="btn btn-primary btn"> + <span class="glyphicon glyphicon-cloud-upload" aria-hidden="true"></span> + Upload + </button> + </div> +</form> +{% else %} +<div class="alert alert-warning">You must be <a href="{{ url_for('.login') }}">logged in</a> to upload files.</div> +{% endif %} +{% endblock %} +{% block scripts %} +<script> +$(document).ready(function() { + $(':file').filestyle('placeholder', 'No file'); +}); +</script> +{% endblock %} diff --git a/fbin/templates/uploaded.html b/fbin/templates/uploaded.html new file mode 100644 index 0000000..84a541c --- /dev/null +++ b/fbin/templates/uploaded.html @@ -0,0 +1,14 @@ +{% extends "base.html" %} +{% block content %} +<p>Your file has been uploaded:</p> +<ul> + <li><a href="{{ url_for('.file', hash = file.hash, filename = file.filename, _external = True) }}">{{ url_for('.file', hash = file.hash, filename = file.filename, _external = True) }}</a></li> + <li><a href="{{ url_for('.file', hash = file.hash, ext = file.ext, _external = True) }}">{{ url_for('.file', hash = file.hash, ext = file.ext, _external = True) }}</a></li> + <li><a href="{{ url_for('.file', hash = file.hash, _external = True) }}">{{ url_for('.file', hash = file.hash, _external = True) }}</a></li> +</ul> +{% if current_user.is_authenticated %} +<p>Your file will also appear in <a href="{{ url_for('.files') }}">your file list</a>.</p> +{% else %} +<p>If you were <a href="{{ url_for('.login') }}">logged in</a>, your file would also appear in <a href="{{ url_for('.files') }}">your file list</a>.</p> +{% endif %} +{% endblock %} |