aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO8
-rw-r--r--assets/admin.css41
-rw-r--r--assets/cargohold.css15
-rw-r--r--backend/Admin.py19
-rw-r--r--backend/config.py6
-rw-r--r--backend/utils.py16
-rw-r--r--interface/admin_aliases.tmpl40
-rw-r--r--interface/admin_delete.tmpl21
-rw-r--r--interface/admin_dirs.tmpl6
-rw-r--r--interface/admin_files.tmpl21
-rw-r--r--interface/admin_rename.tmpl40
-rw-r--r--interface/admin_upload.tmpl36
-rw-r--r--interface/listing.htm3
13 files changed, 246 insertions, 26 deletions
diff --git a/TODO b/TODO
index 4964457..d0db819 100644
--- a/TODO
+++ b/TODO
@@ -3,7 +3,13 @@ HTML-only frontend
Automatic resizing for gallery mode
Alias titles
'Download all' button
-
+Password protection per alias
+'Scramble' file links (do not make the parent directory available via the individual links)
Admin
Size limit administration
+
+JS Admin
+ Rename
+ Create Alias
+ Delete
diff --git a/assets/admin.css b/assets/admin.css
index 4fdc5fb..bf93fbc 100644
--- a/assets/admin.css
+++ b/assets/admin.css
@@ -26,20 +26,53 @@ div.entry {
vertical-align: center;
}
-div.entry a.button {
+a.button {
padding: 0.5em;
background-color: #c8e;
text-decoration: none;
margin-left: 0.5em;
- display: block;
+ /*display: block;*/
border-radius: 0.5em;
}
-a.delete {
+.info, .permission {
+ padding: 0.5em;
+ background-color: #c8e;
+ border-radius: 0.5em;
+ margin-left: 0.5em;
+ text-decoration: none;
+ color: #453;
+}
+
+.button.delete {
background-color: #f79 !important;
}
-a.directory {
+.button.active {
+ background-color: #569;
+}
+
+.permission {
+ background-color: #366;
+ color: #acb;
+}
+
+.permission.disabled {
+ text-decoration: line-through;
+ background-color: #636;
+}
+
+a.entry {
text-decoration: none;
color: #aade88;
}
+
+span.dirname {
+ font-weight: bold;
+ font-style: italic;
+}
+
+#topmenu, #action {
+ display: inline-flex;
+ margin: 1em;
+}
diff --git a/assets/cargohold.css b/assets/cargohold.css
index 747b916..df40b98 100644
--- a/assets/cargohold.css
+++ b/assets/cargohold.css
@@ -98,9 +98,14 @@ html {
background-color: #728;
padding: 0.5em;
text-align: left;
+}
+
+#header h1 {
font-size: 120%;
font-weight: bold;
font-family: sans;
+ display: inline-block;
+ margin: 0;
}
#container {
@@ -167,3 +172,13 @@ html {
border-radius: 1em;
background-color: #8885;
}
+
+.footer, .footer a {
+ text-align: right;
+ text-decoration: none;
+ color: #777;
+}
+
+.footer {
+ padding: 1em;
+}
diff --git a/backend/Admin.py b/backend/Admin.py
index a844aff..2070293 100644
--- a/backend/Admin.py
+++ b/backend/Admin.py
@@ -8,7 +8,10 @@ template_factory = jinja2.Environment(loader=jinja2.FileSystemLoader('../interfa
admin_dirs = template_factory.get_template("admin_dirs.tmpl")
admin_files = template_factory.get_template("admin_files.tmpl")
+admin_upload = template_factory.get_template("admin_upload.tmpl")
admin_delete = template_factory.get_template("admin_delete.tmpl")
+admin_rename = template_factory.get_template("admin_rename.tmpl")
+admin_aliases = template_factory.get_template("admin_aliases.tmpl")
def route(path, env, post):
auth = config.Auth.get(env)
@@ -39,11 +42,19 @@ def route(path, env, post):
files = utils.dirlisting(directory, True, False)
return [admin_files.render({"user": auth["user"], "listing": files, "directory": utils.sanitize_filename(path[1])}), [("Content-Type", "text/html")], "200 OK"]
+ # Upload
+ if len(path) == 3 and path[2] == "upload":
+ return [admin_upload.render({"user": auth["user"], "directory": utils.sanitize_filename(path[1])}), [("Content-Type", "text/html")], "200 OK"]
+
# Alias management / Limits config
- # TODO
+ if len(path) == 3 and path[2] == "aliases":
+ aliases = utils.aliases(auth["user"], utils.sanitize_filename(path[1]))
+ return [admin_aliases.render({"user": auth["user"], "directory": utils.sanitize_filename(path[1]), "aliases": aliases, "baseurl": config.baseurl}), [("Content-Type", "text/html")], "200 OK"]
# Renaming
- # TODO
+ if len(path) == 3 and path[2] == "rename":
+ # TODO
+ return [admin_rename.render({"user": auth["user"], "directory": utils.sanitize_filename(path[1])}), [("Content-Type", "text/html")], "200 OK"]
# Deletion
if len(path) == 3 and path[2] == "delete":
@@ -52,9 +63,7 @@ def route(path, env, post):
return utils.redirect("/admin")
files = utils.dirlisting(directory, True, False)
if len(files) == 0 or env.get("QUERY_STRING", "") == "confirm":
- # TODO remove contents
- # TODO remove aliases
- os.rmdir(directory)
+ utils.cleanup(auth["user"], utils.sanitize_filename(path[1]))
return utils.redirect("/admin")
return [admin_delete.render({"user": auth["user"], "listing": files, "directory": utils.sanitize_filename(path[1])}), [("Content-Type", "text/html")], "200 OK"]
diff --git a/backend/config.py b/backend/config.py
index 2de63bc..a4a1209 100644
--- a/backend/config.py
+++ b/backend/config.py
@@ -8,5 +8,11 @@ global_limit = 0
user_subdirs = True
# Path to the backing database
database = "cargohold.db3"
+
+# Settings for the web admin panel
+
+# Base URL for rendering alias links
+baseurl = "https://files.stumpf.es/"
+
# Select the authentication provider for the web admin interface
import NoneAuth as Auth
diff --git a/backend/utils.py b/backend/utils.py
index bab7ebe..1e23e63 100644
--- a/backend/utils.py
+++ b/backend/utils.py
@@ -57,3 +57,19 @@ def dirlisting(path, files, dirs):
listing.append({"name": entry, "size": size})
return listing
+
+def cleanup(user, subdir):
+ directory = userdir(user) + subdir + "/"
+ print("Cleaning up %s" % (directory, ))
+ # TODO
+ # Remove contents
+ # Remove aliases
+ os.rmdir(directory)
+ return
+
+def aliases(user, subdir):
+ aliases = []
+ data = db.cursor().execute("SELECT alias, access, storage, display FROM aliases WHERE user = :user AND real = :dir", {"user": user, "dir": subdir}).fetchall()
+ for alias in data:
+ aliases.append({"alias": alias[0], "access": alias[1], "storage": alias[2], "display": alias[3]})
+ return aliases
diff --git a/interface/admin_aliases.tmpl b/interface/admin_aliases.tmpl
new file mode 100644
index 0000000..97315f7
--- /dev/null
+++ b/interface/admin_aliases.tmpl
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
+ <meta name="robots" content="noindex,nofollow" />
+ <title>cargohold</title>
+ <link rel="stylesheet" href="/assets/cargohold.css" />
+ <link rel="stylesheet" href="/assets/admin.css" />
+ <link rel="icon" href="/assets/cargohold.ico" />
+ </head>
+ <body>
+ <div id="header">
+ <h1>cargohold - <span class="dirname">{{ directory }}</span></h1>
+ <a class="button" href="/admin">Back to overview</a>
+ </div>
+
+ <div id="container">
+ <div id="topmenu">
+ <a class="button" href="/admin/{{ directory }}">View</a>
+ <a class="button" href="/admin/{{ directory }}/upload">Upload</a>
+ <a class="button" href="/admin/{{ directory }}/rename">Rename</a>
+ <a class="button active" href="/admin/{{ directory }}/aliases">Links</a>
+ <a class="button delete" href="/admin/{{ directory }}/delete">Delete</a>
+ </div>
+
+ <div id="listing">
+ {% for alias in aliases %}
+ <div class="entry">
+ <a class="entry" href="{{ baseurl }}{{ alias.alias }}">{{ baseurl }}{{ alias.alias }}</a>
+ <a class="permission {% if 'r' not in alias.access %}disabled{% endif %}" href="#">Download</a>
+ <a class="permission {% if 'c' not in alias.access %}disabled{% endif %}" href="#">Upload</a>
+ <a class="permission {% if 'd' not in alias.access %}disabled{% endif %}" href="#">Delete</a>
+ <a class="permission" href="#">Previews</a>
+ </div>
+ {% endfor %}
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/interface/admin_delete.tmpl b/interface/admin_delete.tmpl
index bf6d8a2..102d908 100644
--- a/interface/admin_delete.tmpl
+++ b/interface/admin_delete.tmpl
@@ -11,24 +11,35 @@
</head>
<body>
<div id="header">
- cargohold - Administration
+ <h1>cargohold - <span class="dirname">{{ directory }}</span></h1>
+ <a class="button" href="/admin">Back to overview</a>
</div>
<div id="container">
+ <div id="topmenu">
+ <a class="button" href="/admin/{{ directory }}">View</a>
+ <a class="button" href="/admin/{{ directory }}/upload">Upload</a>
+ <a class="button" href="/admin/{{ directory }}/rename">Rename</a>
+ <a class="button" href="/admin/{{ directory }}/aliases">Links</a>
+ <a class="button active" href="/admin/{{ directory }}/delete">Delete</a>
+ </div>
+
<div id="message">
- This will delete the directory <span class="highlight">{{ directory }}</span>.
+ This will delete the directory <span class="highlight dirname">{{ directory }}</span>.
<br />
This directory still contains {{ listing | length }} files.
</div>
+
<div id="dirlisting">
{% for file in listing %}
<div class="entry">
- <a class="file" href="#">{{ file.name }}</a>
+ <a class="entry" href="/admin/{{ directory }}/file/{{ file.name }}">{{ file.name }}</a>
</div>
{% endfor %}
</div>
+
<div id="action">
- <a class="button" href="/admin">Cancel</a>
- <a class="button delete" href="?confirm">Confirm &amp; delete</a>
+ <a class="button" href="/admin/{{ directory }}">Cancel</a>
+ <a class="button delete" href="?confirm">Confirm &amp; delete all</a>
</div>
</div>
</body>
diff --git a/interface/admin_dirs.tmpl b/interface/admin_dirs.tmpl
index cebaa62..d7c5317 100644
--- a/interface/admin_dirs.tmpl
+++ b/interface/admin_dirs.tmpl
@@ -11,7 +11,7 @@
</head>
<body>
<div id="header">
- cargohold - Administration
+ <h1>cargohold - All directories</h1>
</div>
<div id="container">
{% if error %}
@@ -28,9 +28,9 @@
<div id="dirlisting">
{% for dir in listing %}
<div class="entry">
- <a class="directory" href="/admin/{{dir.name}}">{{dir.name}}</a>
+ <a class="entry" href="/admin/{{dir.name}}">{{dir.name}}</a>
<a class="button" href="/admin/{{dir.name}}/rename">Rename</a>
- <a class="button" href="/admin/{{dir.name}}/aliases">Aliases</a>
+ <a class="button" href="/admin/{{dir.name}}/aliases">{{dir.nlinks}} Links</a>
<a class="delete button" href="/admin/{{dir.name}}/delete">Delete</a>
</div>
{% endfor %}
diff --git a/interface/admin_files.tmpl b/interface/admin_files.tmpl
index 76b63d5..b0828b6 100644
--- a/interface/admin_files.tmpl
+++ b/interface/admin_files.tmpl
@@ -11,18 +11,25 @@
</head>
<body>
<div id="header">
- cargohold - Administration
+ <h1>cargohold - <span class="dirname">{{ directory }}</span></h1>
+ <a class="button" href="/admin">Back to overview</a>
</div>
+
<div id="container">
- {% if message %}
- <div id="message">
- {{ message }}
- </div>
- {% endif %}
+ <div id="topmenu">
+ <a class="button active" href="/admin/{{ directory }}">View</a>
+ <a class="button" href="/admin/{{ directory }}/upload">Upload</a>
+ <a class="button" href="/admin/{{ directory }}/rename">Rename</a>
+ <a class="button" href="/admin/{{ directory }}/aliases">Links</a>
+ <a class="button delete" href="/admin/{{ directory }}/delete">Delete</a>
+ </div>
+
<div id="dirlisting">
{% for file in listing %}
<div class="entry">
- <a class="file" href="#">{{ file.name }}</a>
+ <a class="entry" href="/admin/{{ directory }}/file/{{ file.name }}">{{ file.name }}</a>
+ <div class="info">{{ (file.size / 1024 / 1024) | round(2, "ceil") }} MB</div>
+ <a class="button delete" href="/admin/{{ directory }}/delete/{{ file.name }}">Delete</a>
</div>
{% endfor %}
</div>
diff --git a/interface/admin_rename.tmpl b/interface/admin_rename.tmpl
new file mode 100644
index 0000000..a760cb5
--- /dev/null
+++ b/interface/admin_rename.tmpl
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
+ <meta name="robots" content="noindex,nofollow" />
+ <title>cargohold</title>
+ <link rel="stylesheet" href="/assets/cargohold.css" />
+ <link rel="stylesheet" href="/assets/admin.css" />
+ <link rel="icon" href="/assets/cargohold.ico" />
+ </head>
+ <body>
+ <div id="header">
+ <h1>cargohold - <span class="dirname">{{ directory }}</span></h1>
+ <a class="button" href="/admin">Back to overview</a>
+ </div>
+
+ <div id="container">
+ <div id="topmenu">
+ <a class="button" href="/admin/{{ directory }}">View</a>
+ <a class="button" href="/admin/{{ directory }}/upload">Upload</a>
+ <a class="button active" href="/admin/{{ directory }}/rename">Rename</a>
+ <a class="button" href="/admin/{{ directory }}/aliases">Links</a>
+ <a class="button delete" href="/admin/{{ directory }}/delete">Delete</a>
+ </div>
+
+ <div>
+ This will rename the directory <span class="highlight dirname">{{ directory }}</span>.
+ <br />
+ All aliases will be kept intact.
+ </div>
+
+ <input type="text" placeholder="New name" />
+
+ <div id="action">
+ <a class="button" href="?confirm">Rename</a>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/interface/admin_upload.tmpl b/interface/admin_upload.tmpl
new file mode 100644
index 0000000..be5b298
--- /dev/null
+++ b/interface/admin_upload.tmpl
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
+ <meta name="robots" content="noindex,nofollow" />
+ <title>cargohold</title>
+ <link rel="stylesheet" href="/assets/cargohold.css" />
+ <link rel="stylesheet" href="/assets/admin.css" />
+ <link rel="icon" href="/assets/cargohold.ico" />
+ </head>
+ <body>
+ <div id="header">
+ <h1>cargohold - <span class="dirname">{{ directory }}</span></h1>
+ <a class="button" href="/admin">Back to overview</a>
+ </div>
+
+ <div id="container">
+ <div id="topmenu">
+ <a class="button" href="/admin/{{ directory }}">View</a>
+ <a class="button active" href="/admin/{{ directory }}/upload">Upload</a>
+ <a class="button" href="/admin/{{ directory }}/rename">Rename</a>
+ <a class="button" href="/admin/{{ directory }}/aliases">Links</a>
+ <a class="button delete" href="/admin/{{ directory }}/delete">Delete</a>
+ </div>
+
+ <div>
+ TBD
+ </div>
+
+ <div id="action">
+ <a class="button" href="#">Upload</a>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/interface/listing.htm b/interface/listing.htm
index 5866825..7cc2b62 100644
--- a/interface/listing.htm
+++ b/interface/listing.htm
@@ -11,7 +11,7 @@
</head>
<body>
<div id="header">
- cargohold
+ <h1>cargohold</h1>
</div>
<div id="container">
<div class="tab-wrap">
@@ -55,5 +55,6 @@
</div>
</div>
</div>
+ <div class="footer"><a href="https://git.services.cbcdn.com/cargohold/">cargohold</a> is a free and open source project</div>
</body>
</html>