Compare commits
10 Commits
0397f8d2d6
...
a974a49235
Author | SHA1 | Date |
---|---|---|
Dendy | a974a49235 | |
Dendy | 31cf2b5f2c | |
Dendy | 99c3469597 | |
Dendy | 26b115654b | |
Dendy | 4446c33fd2 | |
Dendy | b4066c1552 | |
Dendy | 903f648b58 | |
Dendy | 2e8fdf67f1 | |
Dendy | 6af686f3bd | |
Dendy | 918f9fb294 |
|
@ -0,0 +1,2 @@
|
||||||
|
name = "gaisen"
|
||||||
|
data_path = "./data"
|
|
@ -1,7 +1,6 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
import traceback
|
import traceback
|
||||||
import os
|
|
||||||
import posixpath
|
import posixpath
|
||||||
|
|
||||||
from flask import Flask, render_template, request
|
from flask import Flask, render_template, request
|
||||||
|
|
22
src/files.py
22
src/files.py
|
@ -2,6 +2,9 @@ import os
|
||||||
import posixpath
|
import posixpath
|
||||||
from typing import Self
|
from typing import Self
|
||||||
|
|
||||||
|
# TODO: Cut any dependency of DocumentNode on the backend implementation
|
||||||
|
# Maybe use some king of "yield" to achieve this?
|
||||||
|
|
||||||
|
|
||||||
class DocumentNode():
|
class DocumentNode():
|
||||||
def __init__(self, name: str, children: list):
|
def __init__(self, name: str, children: list):
|
||||||
|
@ -61,9 +64,12 @@ class DocumentNode():
|
||||||
if file.endswith('.md'):
|
if file.endswith('.md'):
|
||||||
file = file[:-3]
|
file = file[:-3]
|
||||||
|
|
||||||
if file not in children:
|
if file not in [x.name for x in children]:
|
||||||
children.append(DocumentNode(file, []))
|
children.append(DocumentNode(file, []))
|
||||||
|
|
||||||
|
# With this algorithm they're not properly sorted
|
||||||
|
children.sort(key=lambda x: x.name)
|
||||||
|
|
||||||
return DocumentNode(path.split('/')[-1], children)
|
return DocumentNode(path.split('/')[-1], children)
|
||||||
|
|
||||||
|
|
||||||
|
@ -75,13 +81,18 @@ class DocumentTree():
|
||||||
def get_node(self, path: str) -> DocumentNode | None:
|
def get_node(self, path: str) -> DocumentNode | None:
|
||||||
return self.root.get_child(path)
|
return self.root.get_child(path)
|
||||||
|
|
||||||
|
def reload(self) -> bool:
|
||||||
|
# TODO: Instead of doing this, actually reload
|
||||||
|
self.root = DocumentNode.get_tree(self.base, '')
|
||||||
|
return True
|
||||||
|
|
||||||
# ----- Document Operations -----
|
# ----- Document Operations -----
|
||||||
|
|
||||||
# Split and remerge for Windows
|
# Split and remerge for Windows
|
||||||
def document_read(self, path: str) -> str | None:
|
def document_read(self, path: str) -> str | None:
|
||||||
internal_path = os.path.join(self.base, *path.split('/')) + '.md'
|
internal_path = os.path.join(self.base, *path.split('/')) + '.md'
|
||||||
if os.path.exists(internal_path):
|
if os.path.exists(internal_path):
|
||||||
return open(internal_path).read()
|
return open(internal_path, 'r').read()
|
||||||
|
|
||||||
# File doesn't exist
|
# File doesn't exist
|
||||||
return None
|
return None
|
||||||
|
@ -89,8 +100,11 @@ class DocumentTree():
|
||||||
def document_write(self, path: str, text: str) -> None:
|
def document_write(self, path: str, text: str) -> None:
|
||||||
internal_path = os.path.join(self.base, *path.split('/')) + '.md'
|
internal_path = os.path.join(self.base, *path.split('/')) + '.md'
|
||||||
|
|
||||||
# TODO: Check if the directory exists before writing
|
# TODO: Probably add some sort of confirmation beforehand?
|
||||||
with open(internal_path) as file:
|
os.makedirs(os.path.dirname(internal_path), exist_ok=True)
|
||||||
|
with open(internal_path, 'w') as file:
|
||||||
file.write(text)
|
file.write(text)
|
||||||
|
|
||||||
|
self.reload()
|
||||||
|
|
||||||
# -------------------------------
|
# -------------------------------
|
||||||
|
|
|
@ -1,18 +1,15 @@
|
||||||
html {
|
|
||||||
min-height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
body {
|
||||||
padding: 20px;
|
/*padding: 20px;*/
|
||||||
background-color: #191919;
|
background-color: #191919;
|
||||||
color: white;
|
color: white;
|
||||||
font-family: monospace;
|
font-family: monospace;
|
||||||
margin-bottom: 100px;
|
/*margin-bottom: 100px;*/
|
||||||
|
min-height: 100vh;
|
||||||
|
margin: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
h1, h2, h3, h4, h5, h6 {
|
h1, h2 { color: orange; }
|
||||||
color: orange;
|
h3, h4 { color: gray; }
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
a {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
|
@ -23,12 +20,18 @@ a {
|
||||||
background-color: orange;
|
background-color: orange;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hr {
|
||||||
|
border: none;
|
||||||
|
border-bottom: 1px solid #444;
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
input {
|
input {
|
||||||
border: 1px solid black;
|
border: 1px solid black;
|
||||||
background-color: white;
|
background-color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
footer {
|
body > footer {
|
||||||
background-color: black;
|
background-color: black;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
left: 0;
|
left: 0;
|
||||||
|
@ -40,27 +43,56 @@ footer {
|
||||||
}
|
}
|
||||||
|
|
||||||
ul {
|
ul {
|
||||||
padding-left: 20px;
|
margin: 0px;
|
||||||
|
padding-left: 10px;
|
||||||
padding-bottom: 0px;
|
padding-bottom: 0px;
|
||||||
|
}
|
||||||
|
ul p {
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
margin-top: -2px;
|
||||||
|
margin-bottom: -1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
body > main {
|
||||||
|
display: flex;
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
body > main > * > *:not(hr) {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
body > main hr {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
body > main > nav {
|
||||||
|
background-color: black;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
body > main > nav ul {
|
||||||
list-style-type: none;
|
list-style-type: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
main {
|
body > main > article ul {
|
||||||
display: flex;
|
margin-bottom: 10px;
|
||||||
gap: 20px;
|
|
||||||
min-height: 80vh;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nav {
|
nav {
|
||||||
padding-right: 10px;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
border-right: 1px solid orange;
|
border-right: 1px solid #444;
|
||||||
width: 200px;
|
width: 200px;
|
||||||
}
|
}
|
||||||
|
|
||||||
article {
|
article {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
article > main {
|
||||||
|
flex-grow: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pre {
|
pre {
|
||||||
|
|
|
@ -2,12 +2,20 @@
|
||||||
|
|
||||||
{% block title %}{{ path }}{% endblock %}
|
{% block title %}{{ path }}{% endblock %}
|
||||||
|
|
||||||
{% macro render_tree(tree, root='/') %}
|
{% macro render_tree(tree, root='') %}
|
||||||
<ul>
|
<ul>
|
||||||
{% for entry in tree %}
|
{% for entry in tree %}
|
||||||
<li>
|
<li>
|
||||||
{% set url = path_join(root, entry.name) %}
|
{% set url = path_join(root, entry.name) %}
|
||||||
<a href="{{ url }}">{{ entry.name }}</a>
|
|
||||||
|
{#{% if loop.last or entry.children|length > 0 %}#}
|
||||||
|
{% if entry.children|length > 0 %}
|
||||||
|
▼
|
||||||
|
{% else %}
|
||||||
|
·
|
||||||
|
{% endif %}
|
||||||
|
<a href="{{ path_join('/', url ) }}">{{ entry.name }}</a>
|
||||||
|
|
||||||
{{ render_tree(entry.children, url) }}
|
{{ render_tree(entry.children, url) }}
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
@ -16,11 +24,19 @@
|
||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<main>
|
<main>
|
||||||
|
|
||||||
<nav>
|
<nav>
|
||||||
|
<div>
|
||||||
|
> <a href="/">index</a>/{{ path }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr/>
|
||||||
|
|
||||||
{{ render_tree(document_tree.root.children) }}
|
{{ render_tree(document_tree.root.children) }}
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<article>
|
<article>
|
||||||
|
<main>
|
||||||
{% if not edit %}
|
{% if not edit %}
|
||||||
{% if path != '' %}
|
{% if path != '' %}
|
||||||
<a href="/{{ path }}?edit">Edit</a>
|
<a href="/{{ path }}?edit">Edit</a>
|
||||||
|
@ -35,7 +51,11 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% else %}
|
{% else %}
|
||||||
<form method="POST" action="/{{ path }}">
|
<form method="POST" action="/{{ path }}">
|
||||||
<textarea id="markdown-textarea" name="text">{{ content }}</textarea>
|
{% set edit_content = content %}
|
||||||
|
{% if content is none %}
|
||||||
|
{% set edit_content = '# Title\n\nContent' %}
|
||||||
|
{% endif %}
|
||||||
|
<textarea id="markdown-textarea" name="text">{{ edit_content }}</textarea>
|
||||||
<input type="submit" value="Save"/>
|
<input type="submit" value="Save"/>
|
||||||
<form>
|
<form>
|
||||||
<script>
|
<script>
|
||||||
|
@ -61,16 +81,22 @@
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
</main>
|
||||||
|
|
||||||
<hr/>
|
<hr/>
|
||||||
|
|
||||||
{% for child in document_tree.get_node(path).children %}
|
{% for child in document_tree.get_node(path).children %}
|
||||||
|
|
||||||
|
|
||||||
{% if loop.first %}
|
{% if loop.first %}
|
||||||
|
<footer>
|
||||||
<h1>Children</h1>
|
<h1>Children</h1>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<a href="{{ path_join(path, child.name) }}">{{child.name}}</a>{% if not loop.last %},{% endif %}
|
<a href="{{ path_join(path, child.name) }}">{{child.name}}</a>{% if not loop.last %},{% endif %}
|
||||||
|
{% if loop.last %}
|
||||||
|
</footer>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
</article>
|
</article>
|
||||||
|
|
Loading…
Reference in New Issue