1
0
mirror of https://github.com/tiyn/amphora-wiki.git synced 2025-10-17 05:11:16 +02:00

Compare commits

8 Commits

Author SHA1 Message Date
d5cf8d6d13 added favicon 2024-04-14 02:42:25 +02:00
ff35dbe3ae make logo standard 2024-04-14 02:27:09 +02:00
ff169d2795 more modern link style added 2024-04-14 02:02:47 +02:00
6287111899 improved light style for better readability 2024-04-14 00:44:50 +02:00
cdf6660cae minor style changes, added graphics volume 2024-04-13 23:56:08 +02:00
0bc1a955a6 readme: fixed typo 2022-07-30 23:56:52 +02:00
563ac37e5e removing empty logo 2022-07-29 23:21:27 +02:00
f766803f3b src: fixed quote-signs 2022-07-29 23:05:31 +02:00
14 changed files with 137 additions and 107 deletions

View File

@@ -10,6 +10,8 @@ RUN pip3 install -r requirements.txt
VOLUME /wiki/templates/entry
VOLUME /wiki/static/graphics
EXPOSE 5000
ENTRYPOINT [ "python3" ]

View File

@@ -15,7 +15,7 @@ I however just want to put my markdown files in a directory and get a working wi
- [ ] Option to get plain text file
- [ ] Optimize CSS for code
- [x] Start page
- [ ] Overview of pages and namespaces
- [x] Overview of pages and namespaces
- [x] Search page
- [x] Full-text search
- [x] Show first few lines of each match (preview)
@@ -60,12 +60,13 @@ The `config.py` can be found in the `src` folder.
Set the following volumes with the -v tag.
| Volume-Name | Container mount | Description |
| ----------- | ------------------------- | ------------------------------------------------------------ |
| config-file | /wiki/src/config.py | Config file |
| entries | /wiki/src/templates/entry | Directory for wiki entries |
| css | /wiki/src/static/css | (optional) Directory for css files |
| html | /wiki/src/templates | (optional) Directory for templates (entry-volume not needed) |
| Volume-Name | Container mount | Description |
| ------------- | ----------------------- | ------------------------------------------------------------ |
| `config-file` | `/wiki/config.py` | Config file |
| `entries` | `/wiki/templates/entry` | Directory for wiki entries |
| `graphics` | `/wiki/static/graphics` | Directory for images needed for entries |
| `css` | `/wiki/static/css` | (optional) Directory for css files |
| `html` | `/wiki/templates` | (optional) Directory for templates (entry-volume not needed) |
#### Ports

View File

@@ -1,3 +1,3 @@
#!/bin/sh
docker-compose down
docker-compose up -d
docker-compose up -d --build

View File

@@ -18,38 +18,38 @@ STYLE = config.STYLE
@app.errorhandler(404)
def page_not_found(e):
return render_template('error.html', title=TITLE, errorcode='404', style=STYLE), 404
return render_template("error.html", title=TITLE, errorcode="404", style=STYLE), 404
@app.route('/')
@app.route('/index.html')
@app.route("/")
@app.route("/index.html")
def index():
return render_template('index.html', title=TITLE, style=STYLE), 200
return render_template("index.html", title=TITLE, style=STYLE), 200
@app.route('/search', methods=['GET', 'POST'])
@app.route('/search.html', methods=['GET', 'POST'])
@app.route("/search", methods=["GET", "POST"])
@app.route("/search.html", methods=["GET", "POST"])
def search():
form = SearchForm()
if request.method == 'POST':
query_str = request.form['query_str']
if request.method == "POST":
query_str = request.form["query_str"]
content = cont.gen_query_res_string(query_str)
return render_template('search.html', title=TITLE, style=STYLE, form=form, content=content), 200
return render_template('search.html', title=TITLE, style=STYLE, form=form, content=''), 200
return render_template("search.html", title=TITLE, style=STYLE, form=form, content=content), 200
return render_template("search.html", title=TITLE, style=STYLE, form=form, content=""), 200
@app.route('/entry/<path:fullurl>')
@app.route("/entry/<path:fullurl>")
def entry(fullurl):
content = cont.gen_stand_string(fullurl)
return render_template('entry.html', title=TITLE, style=STYLE, content=content), 200
return render_template("entry.html", title=TITLE, style=STYLE, content=content), 200
@app.route('/namespace/', defaults={'fullurl': ''})
@app.route('/namespace/<path:fullurl>')
def namespace(fullurl=''):
@app.route("/namespace/", defaults={"fullurl": ""})
@app.route("/namespace/<path:fullurl>")
def namespace(fullurl=""):
content = cont.gen_arch_string(fullurl)
if content == None:
return render_template('error.html', title=TITLE, errorcode='404', style=STYLE), 404
return render_template('entry.html', title=TITLE, style=STYLE, content=content), 200
return render_template("error.html", title=TITLE, errorcode="404", style=STYLE), 404
return render_template("entry.html", title=TITLE, style=STYLE, content=content), 200
if __name__ == '__main__':
app.run(host='0.0.0.0')
if __name__ == "__main__":
app.run(host="0.0.0.0")

View File

@@ -1,13 +1,13 @@
# Name/title of your blog
TITLE = 'Amphora Wiki'
TITLE = "Amphora Wiki"
# URL for your website: e.g. https://domain.tld
WEBSITE = 'localhost:5000'
WEBSITE = "localhost:5000"
# Theme for the blog: dark, light
STYLE = 'dark'
STYLE = "dark"
###############################################
## NO CHANGES RECOMMENDED ##
###############################################
ENTRY_DIR = 'templates/entry'
ENTRY_DIR = "templates/entry"

View File

@@ -26,13 +26,13 @@ def gen_stand_string(path_ex):
string: html-formatted string string equivalent to the file
"""
filename = os.path.join(ENTRY_DIR, path_ex)
result = ''
result = ""
if path.exists(filename):
title = open(filename,encoding='utf-8').readline().rstrip('\n').lstrip('#').lstrip(' ')
text = open(filename,encoding='utf-8').readlines()[1:]
filename_no_end = filename.split('.', 1)[0]
result += '<h1>' + title + '</h1>\n'
if filename.endswith('.md'):
title = open(filename,encoding="utf-8").readline().rstrip("\n").lstrip("#").lstrip(" ")
text = open(filename,encoding="utf-8").readlines()[1:]
filename_no_end = filename.split(".", 1)[0]
result += "<h1>" + title + "</h1>\n"
if filename.endswith(".md"):
result += gen_md_content(filename, 1)
return result
@@ -48,18 +48,18 @@ def gen_md_content(path_ex, depth):
Returns:
string: html-formatted string string equivalent to the markdown file
"""
result = ''
result = ""
if path.exists(path_ex):
filename = path_ex.split('.', 1)
filename = path_ex.split(".", 1)
fileend = filename[len(filename) - 1]
header = '#'
header = "#"
for i in range(depth):
header += '#'
header += ' '
markdown_lines = open(path_ex, 'r',encoding='utf-8').readlines()[1:]
markdown_text = ''
header += "#"
header += " "
markdown_lines = open(path_ex, "r",encoding="utf-8").readlines()[1:]
markdown_text = ""
for line in markdown_lines:
markdown_text += line.replace('# ', header)
markdown_text += line.replace("# ", header)
result = markdown.markdown(
markdown_text, extensions=["fenced_code", "tables", "nl2br"])
return result
@@ -80,28 +80,27 @@ def gen_arch_string(path_ex):
name_list = os.listdir(full_path)
full_list = [os.path.join(full_path, i) for i in name_list]
contents = sorted(full_list, key=os.path.getctime)
content_string = ''
last_month = ''
content_string = ""
last_month = ""
for file in reversed(contents):
filename = pathlib.PurePath(file)
if os.path.isfile(filename):
title = open(filename).readline().rstrip('\n').lstrip('#').lstrip(' ')
entry_or_namespace = 'entry'
title = open(filename).readline().rstrip("\n").lstrip("#").lstrip(" ")
entry_or_namespace = "entry"
elif os.path.isdir(filename):
title = filename.name
entry_or_namespace = 'namespace'
entry_or_namespace = "namespace"
else:
continue
filename = filename.name
if filename[0] != '.' and filename.__contains__('.'):
filename = filename.split('.', 1)[0]
content_string += '<li>'
content_string += title + ' ['
content_string += '<a href="' + '/'+ entry_or_namespace +'/' + \
path_ex.rstrip("/") + '/' + pathlib.PurePath(file).name + '">' + 'standalone' + '</a>'
content_string += '] <br>'
content_string += '</li>\n'
content_string += '</ul>\n'
if filename[0] != "." and filename.__contains__("."):
filename = filename.split(".", 1)[0]
content_string += "<li>"
content_string += "<a href=\"" + "/"+ entry_or_namespace +"/" + \
path_ex.rstrip("/") + "/" + pathlib.PurePath(file).name + "\">" + title + "</a>"
content_string += "<br>"
content_string += "</li>\n"
content_string += "</ul>\n"
return content_string
@@ -117,17 +116,17 @@ def gen_query_res_string(query_str):
string: html-formated search result
"""
src_results = search.search(query_str)
res_string = ''
res_string += '<ul>\n'
res_string = ""
res_string += "<ul>\n"
for result in src_results:
title = result['title']
path = result['path']
title = result["title"]
path = result["path"]
preview = create_preview(path)
path = '/entry/' + path.split('/', 2)[2]
res_string += '<li><a href="' + path + '">' + markdown.markdown(title) + '</a><br>'
res_string += '<div class="description">' + preview + '</div>'
res_string += '</li>'
res_string += '</ul>\n'
path = "/entry/" + path.split("/", 2)[2]
res_string += "<li><a href=\"" + path + "\">" + markdown.markdown(title) + "</a><br>"
res_string += "<div class=\"description\">" + preview + "</div>"
res_string += "</li>"
res_string += "</ul>\n"
return res_string
@@ -141,9 +140,9 @@ def create_preview(path):
Returns:
string: html-formated preview
"""
file = open(path, 'r',encoding='utf-8')
file = open(path, "r",encoding="utf-8")
first_lines = file.readlines()
preview = ''
preview = ""
preview_length = 3
for i, line in enumerate(first_lines):
if i == 0:
@@ -151,10 +150,10 @@ def create_preview(path):
if i > preview_length:
break
if not line.isspace():
preview += markdown.markdown(line) + '<br>'
preview += markdown.markdown(line) + "<br>"
else:
preview_length += 1
preview += '...<br>'
preview += "...<br>"
return preview
print(gen_arch_string('system-software'))
print(gen_arch_string("system-software"))

View File

@@ -1,11 +1,9 @@
from flask_wtf import FlaskForm
from flask_wtf import CSRFProtect
from wtforms import TextField, SubmitField, ValidationError, validators
from flask_wtf import CSRFProtect, FlaskForm
from wtforms import StringField, SubmitField, ValidationError, validators
csrf = CSRFProtect()
class SearchForm(FlaskForm):
query_str = TextField(
"Query", [validators.Required("Please enter the search term")])
submit = SubmitField("Search")
query_str = StringField("Query", [validators.DataRequired("Please enter the search term")])
submit = SubmitField("Search")

View File

@@ -1,5 +1,5 @@
Markdown==3.1.1
WTForms==2.2.1
Flask==1.1.2
Flask_WTF==0.14.3
Whoosh==2.7.4
Markdown
WTForms
Flask
Flask_WTF
Whoosh

View File

@@ -29,7 +29,7 @@ def createSearchableData(root):
for r, d, f in os.walk(root):
for file in f:
path = os.path.join(r, file)
fp = open(path,encoding='utf-8')
fp = open(path,encoding="utf-8")
title = fp.readline()
text = title + fp.read()
writer.add_document(title=title, path=path, content=text)
@@ -55,7 +55,7 @@ def search_times(query_str, topN):
matches = s.search(query, limit=topN)
for match in matches:
results.append(
{'title': match['title'], 'path': match['path'], 'match': match.score})
{"title": match["title"], "path": match["path"], "match": match.score})
return results

View File

@@ -6,7 +6,7 @@
--error: rgb(255,0,0);
--footerbg0: rgb(192,192,192);
--link0: rgb(0,0,120);
--link1: rgb(255,255,255);
--link1: rgb(0,0,0);
--menulink0: rgb(0,0,120);
--menulink1: rgb(255,255,255);
--menubg0: rgb(192,192,192);

View File

@@ -29,16 +29,6 @@ html {
overflow-x: hidden;
}
code {
border-radius: 25px;
padding-left: 20px;
padding-right: 20px;
page-break-inside: avoid;
font-family: monospace;
white-space: pre;
display: inline-block
}
footer {
height: 100px;
padding-top: 20px;
@@ -48,10 +38,6 @@ footer .center {
text-align: center;
}
ul {
padding-left: 10px;
}
.container {
min-height: 100%;
padding-bottom: 50px;
@@ -90,6 +76,10 @@ ul {
padding-top: 10px;
}
.main-menu-dropdown img {
float: left;
}
.main-menu-dropdown span {
float: left;
font-family: monospace;
@@ -165,3 +155,40 @@ ul {
right: 0;
}
}
.entry {
border-radius: 0 10px 30px 0;
margin-bottom: 20px;
padding: 10px;
}
.entry h1,
.entry h2 {
margin: 5px auto 2px auto;
}
.entry ul {
padding-left: 20;
}
figure {
padding:20px;
}
ul {
padding-left:20px;
}
ol {
padding-left:20px;
}
code {
border-radius: 25px;
padding-left: 20px;
padding-right: 20px;
page-break-inside: avoid;
font-family: monospace;
white-space: pre;
display: inline-block
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

View File

@@ -2,20 +2,23 @@
<head>
<title>{{ title }}</title>
<link href="{{ url_for('static', filename='css/' + style + '.css') }}" rel="stylesheet" type="text/css">
<link rel="icon" type="image/x-icon" href="{{ url_for('static', filename='graphics/logo.png') }}">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width" initial-scale=1.0>
</head>
<body>
<!-- Menu -->
<div class="main-menu-dropdown">
<!-- <img class="logo" src="/static/images/logo.png"> -->
<span>{{ title }}</span>
<a href="{{ url_for('index') }}">
<img class="logo" src="{{ url_for('static', filename='graphics/logo.png') }}">
<span>{{ title }}</span>
</a>
<input type="checkbox" id="main-menu-check">
<label for="main-menu-check" class="show-menu">&#9776;</label>
<div class="main-menu">
<a href="/">Startpage</a>
<a href="/namespace">Namespaces</a>
<a href="/search">Search</a>
<a href="{{ url_for('index') }}">Startpage</a>
<a href="{{ url_for('namespace') }}">Namespaces</a>
<a href="{{ url_for('search') }}">Search</a>
<label for="main-menu-check" class="hide-menu">X</label>
</div>
</div>
@@ -26,7 +29,7 @@
<!-- Content -->
<footer>
<div class="center">
Made with <a href="https://github.com/tiyn/tiyny-wiki">Amphora Wiki</a>.
Made with <a href="https://github.com/tiyn/amphora-wiki">Amphora Wiki</a>.
</div>
</footer>
</body>