cleanup
This commit is contained in:
parent
30e56fcff5
commit
a5518e277c
|
@ -1,3 +1,6 @@
|
|||
__pycache__/
|
||||
templates/content/
|
||||
bkp.*
|
||||
poetry.lock
|
||||
build
|
||||
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
import os
|
||||
|
||||
def make_tree(path="templates/content"):
|
||||
if '/' in path:
|
||||
tree = dict(name=path, children=[], type="directory")
|
||||
else:
|
||||
pass
|
||||
try: lst = os.listdir(path)
|
||||
except OSError:
|
||||
pass #ignore errors
|
||||
else:
|
||||
lst.sort()
|
||||
for name in lst:
|
||||
fn = os.path.join(path, name)
|
||||
if os.path.isdir(fn) and not fn.endswith(".git"):
|
||||
tree['children'].append(make_tree(fn))
|
||||
else:
|
||||
if fn.endswith('.md') and not name == "README.md":
|
||||
tree['children'].append(dict(name=fn))
|
||||
return tree
|
||||
|
||||
def cut_path_tree(tree, subdir, file_ending):
|
||||
for key, val in tree.items():
|
||||
if isinstance(val, list):
|
||||
for item in val:
|
||||
item["name"] = item["name"][len(subdir):]
|
||||
if item["name"].endswith(file_ending):
|
||||
item["name"] = item["name"][:-len(file_ending)]
|
||||
if isinstance(item, dict):
|
||||
cut_path_tree(item, subdir, file_ending)
|
||||
return tree
|
||||
|
||||
def cut_filetype_tree(tree, filetype):
|
||||
for key, val in tree.items():
|
||||
if isinstance(val, list):
|
||||
for item in val:
|
||||
if item["name"].endswith(filetype):
|
||||
item["name"] = item["name"][:-len(filetype)]
|
||||
if isinstance(item, dict):
|
||||
cut_filetype_tree(item, filetype)
|
||||
return tree
|
||||
|
||||
def list_files(path):
|
||||
doc_files = []
|
||||
for root, dirs, files in os.walk(path):
|
||||
for file in files:
|
||||
if file.endswith(".md") and not ".git" in root:
|
||||
doc_files.append(os.path.join(root,file))
|
||||
return doc_files
|
||||
|
||||
def build_index(path, file_ending):
|
||||
searchable = dict(index=[])
|
||||
file_list = list_files(path)
|
||||
for item in file_list:
|
||||
if item.endswith(file_ending):
|
||||
with open(item, 'r') as _f:
|
||||
data = _f.readlines()
|
||||
data[0] = data[0].strip('# \n')
|
||||
#searchable[data[0]] = [''.join(data), item[len(path):-len(file_ending)]]
|
||||
searchable["index"].append(dict(uri=item[len(path):-len(file_ending)] + '.html', title=data[0],tags=[],content=''.join(data), description=""))
|
||||
#searchable[str(uuid.uuid1())] = (dict(href=item[len(path):-len(file_ending)], title=data[0],tags=[],content=''.join(data)))
|
||||
if isinstance(item, dict):
|
||||
build_index(item)
|
||||
return searchable
|
|
@ -0,0 +1,21 @@
|
|||
[tool.poetry]
|
||||
name = "husk"
|
||||
version = "0.1.0"
|
||||
description = "Generate a website from a markdown repository"
|
||||
authors = ["Stefan Friese <mail@stefan.works>"]
|
||||
license = "GPLv2"
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.10"
|
||||
Flask = "^2.0.2"
|
||||
Frozen-Flask = "^0.18"
|
||||
Markdown = "^3.4.1"
|
||||
Flask-Markdown = "^0.3"
|
||||
Pygments = "^2.12.0"
|
||||
python-markdown-math = "*"
|
||||
|
||||
[tool.poetry.dev-dependencies]
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core>=1.0.0"]
|
||||
build-backend = "poetry.core.masonry.api"
|
120
start_site.py
120
start_site.py
|
@ -2,8 +2,6 @@
|
|||
|
||||
import os
|
||||
import uuid
|
||||
#from datetime import datetime
|
||||
#import pytz
|
||||
from flask import Flask, url_for, render_template, send_from_directory, jsonify, make_response
|
||||
from flaskext.markdown import Markdown
|
||||
import markdown
|
||||
|
@ -12,97 +10,15 @@ import markdown.extensions.codehilite
|
|||
import markdown.extensions.toc
|
||||
from markdown.extensions.toc import TocExtension
|
||||
from pygments.formatters import HtmlFormatter
|
||||
from helpers import make_tree, cut_path_tree, cut_filetype_tree, list_files, build_index
|
||||
|
||||
app = Flask(__name__)
|
||||
Markdown(app)
|
||||
|
||||
def make_tree(path="templates/content"):
|
||||
if '/' in path:
|
||||
tree = dict(name=path, children=[], type="directory")
|
||||
else:
|
||||
pass
|
||||
try: lst = os.listdir(path)
|
||||
except OSError:
|
||||
pass #ignore errors
|
||||
else:
|
||||
lst.sort()
|
||||
for name in lst:
|
||||
fn = os.path.join(path, name)
|
||||
if os.path.isdir(fn) and not fn.endswith(".git"):
|
||||
tree['children'].append(make_tree(fn))
|
||||
else:
|
||||
if fn.endswith('.md') and not name == "README.md":
|
||||
tree['children'].append(dict(name=fn))
|
||||
return tree
|
||||
|
||||
def cut_path_tree(tree, subdir, file_ending):
|
||||
for key, val in tree.items():
|
||||
if isinstance(val, list):
|
||||
for item in val:
|
||||
item["name"] = item["name"][len(subdir):]
|
||||
if item["name"].endswith(file_ending):
|
||||
item["name"] = item["name"][:-len(file_ending)]
|
||||
if isinstance(item, dict):
|
||||
cut_path_tree(item, subdir, file_ending)
|
||||
return tree
|
||||
|
||||
def cut_filetype_tree(tree, filetype):
|
||||
for key, val in tree.items():
|
||||
if isinstance(val, list):
|
||||
for item in val:
|
||||
if item["name"].endswith(filetype):
|
||||
item["name"] = item["name"][:-len(filetype)]
|
||||
if isinstance(item, dict):
|
||||
cut_filetype_tree(item, filetype)
|
||||
return tree
|
||||
|
||||
def list_files(path):
|
||||
doc_files = []
|
||||
for root, dirs, files in os.walk(path):
|
||||
for file in files:
|
||||
if file.endswith(".md") and not ".git" in root:
|
||||
doc_files.append(os.path.join(root,file))
|
||||
return doc_files
|
||||
#
|
||||
#def dir_structure():
|
||||
# for root, dirs, files in os.walk("./templates/content"):
|
||||
# if len(files) != 0:
|
||||
# print(root.split('/')[3:], [file[:-3] for file in files if file.endswith('.md')])
|
||||
#
|
||||
#def test_def():
|
||||
# for i,line in enumerate(l):
|
||||
# if len(line[0]) > 0:
|
||||
# dic[str(line[0][-1])] = line[-1]
|
||||
# result = {}
|
||||
# curr = result
|
||||
# for p in line[0]:
|
||||
# curr = curr.setdefault(p, {})
|
||||
#def other_test_def():
|
||||
# for root, dirs, files in os.walk("templates/content"):
|
||||
# #print(root[18:].split('/')[0])
|
||||
## print(root, files)
|
||||
# key = root[18:].split('/')[0]
|
||||
# d[key] = [file[:-3] for file in files]
|
||||
|
||||
def build_index(path, file_ending):
|
||||
searchable = dict(index=[])
|
||||
file_list = list_files(path)
|
||||
for item in file_list:
|
||||
if item.endswith(file_ending):
|
||||
with open(item, 'r') as _f:
|
||||
data = _f.readlines()
|
||||
data[0] = data[0].strip('# \n')
|
||||
#searchable[data[0]] = [''.join(data), item[len(path):-len(file_ending)]]
|
||||
searchable["index"].append(dict(uri=item[len(path):-len(file_ending)] + '.html', title=data[0],tags=[],content=''.join(data), description=""))
|
||||
#searchable[str(uuid.uuid1())] = (dict(href=item[len(path):-len(file_ending)], title=data[0],tags=[],content=''.join(data)))
|
||||
if isinstance(item, dict):
|
||||
build_index(item)
|
||||
return searchable
|
||||
|
||||
@app.route('/index.json')
|
||||
def index():
|
||||
searchable = build_index("templates/content", ".md")
|
||||
#searchable = dict(index=[ dict(title="Smp_000020", uri="/geneexp/sm/Smp_000020.1/",content="bifunctional protein NCOAT", tags=[], description=""), dict(title="Smp_000030",uri="/geneexp/sm/Smp_000030.1/",content="26s proteasome regulatory particle subunit", tags=[], description="")])
|
||||
response = make_response(searchable)
|
||||
response.headers["Content-Type"] = "application/json"
|
||||
#response.headers["Content-Encoding"] = "gzip"
|
||||
|
@ -131,41 +47,9 @@ def content(path="README"):
|
|||
response.headers["Content-Type"]: "text/html; charset=utf-8"
|
||||
return response
|
||||
|
||||
|
||||
#@app.route('/blog/<blog_item>/index.html')
|
||||
#def blog(blog_item, _date=meta_data):
|
||||
# return render_template(f"blog/{blog_item}/index.html", _date=meta_data[blog_item], )
|
||||
|
||||
#@app.route("/about.html")
|
||||
#def about():
|
||||
# return render_template("about.html")
|
||||
#
|
||||
#@app.route("/contact.html")
|
||||
#def contact():
|
||||
# return render_template("contact.html")
|
||||
|
||||
|
||||
@app.route('/favicon.ico')
|
||||
def favicon():
|
||||
return send_from_directory(os.path.join(app.root_path, 'static'), 'favicon.ico')
|
||||
|
||||
#@app.errorhandler(404)
|
||||
#def page_not_found(_error):
|
||||
# return render_template("/status_code/404.html"), 404
|
||||
#
|
||||
#@app.errorhandler(400)
|
||||
#def bad_request(_error):
|
||||
# return render_template("/status_code/400.html"), 400
|
||||
#
|
||||
#@app.errorhandler(500)
|
||||
#def internal_server_error(_error):
|
||||
# return render_template("/status_code/500.html"), 500
|
||||
|
||||
with app.test_request_context():
|
||||
#print(url_for("content"))
|
||||
#print(url_for("about"))
|
||||
# print(url_for("contact"))
|
||||
#print(url_for("rss"))
|
||||
#print(url_for("static", filename="stylesheet.css"))
|
||||
#print(meta_data)
|
||||
print(url_for("content", md_file="enumeration/windows/bloodhound"))
|
||||
print(url_for("content", md_file="README"))
|
||||
|
|
|
@ -4,11 +4,10 @@
|
|||
<head>
|
||||
{% block head %}
|
||||
<script src="https://cdn.jsdelivr.net/npm/fuse.js/dist/fuse.js"></script>
|
||||
<!-- mathjax -->
|
||||
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
|
||||
<script type="text/javascript" src="{{ url_for('static', filename='js/auto-complete.js') }}"></script>
|
||||
<script type="text/javascript" src="{{ url_for('static', filename='js/lunr.min.js')}}"></script>
|
||||
<script type="text/javascript" src="{{ url_for('static', filename='js/search.js')}}"></script>
|
||||
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
|
||||
<script type="text/javascript" src="{{ url_for('static', filename='js/auto-complete.js') }}"></script>
|
||||
<script type="text/javascript" src="{{ url_for('static', filename='js/lunr.min.js')}}"></script>
|
||||
<script type="text/javascript" src="{{ url_for('static', filename='js/search.js')}}"></script>
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='stylesheet.css') }}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='auto-complete.css') }}">
|
||||
<br>
|
||||
|
@ -19,7 +18,7 @@
|
|||
<body>
|
||||
<!-- topmenu -->
|
||||
<div class="menu">
|
||||
<a href="{{ url_for('content') }}" style="text-decoration:none">In the Open</a>
|
||||
<a href="{{ url_for('content') }}" style="text-decoration:none">Husk</a>
|
||||
</div>
|
||||
<div class="search-container">
|
||||
<label for="search-by"><i class="fas fa-search"></i></label>
|
||||
|
@ -65,109 +64,34 @@
|
|||
</div>
|
||||
|
||||
<script>
|
||||
function linkClick(obj) {
|
||||
function linkClick(obj) {
|
||||
if (obj.open) {
|
||||
console.log('open');
|
||||
//console.log('open');
|
||||
if (sessionStorage.getItem(obj.id) && !(sessionStorage.getItem(obj.id) === "open")) {
|
||||
sessionStorage.removeItem(obj.id);
|
||||
}
|
||||
sessionStorage.setItem(obj.id,"open");
|
||||
console.log(obj.id);
|
||||
|
||||
sessionStorage.setItem(obj.id,"open");
|
||||
console.log(obj.id);
|
||||
} else {
|
||||
console.log('closed');
|
||||
sessionStorage.removeItem(obj.id);
|
||||
|
||||
}
|
||||
// if (obj.open) {
|
||||
// console.log('open');
|
||||
// if (sessionStorage.getItem("opened") && !(sessionStorage.getItem("opened") === obj.id)) {
|
||||
// sessionStorage.removeItem("opened");
|
||||
// }
|
||||
// sessionStorage.setItem("opened", obj.id);
|
||||
// console.log(obj);
|
||||
//console.log('closed');
|
||||
sessionStorage.removeItem(obj.id);
|
||||
}
|
||||
}
|
||||
|
||||
// } else {
|
||||
// console.log('closed');
|
||||
// sessionStorage.removeItem("opened");
|
||||
//
|
||||
// }
|
||||
}
|
||||
|
||||
//if ( sessionStorage.getItem("opened")) {
|
||||
// var item = sessionStorage.getItem("opened")
|
||||
// document.getElementById(item)['open'] = 'open';
|
||||
//}
|
||||
let _keys = Object.keys(sessionStorage);
|
||||
if (_keys) {
|
||||
for ( let i = 0; i < _keys.length; i++ ) {
|
||||
document.getElementById(_keys[i])['open'] = 'open';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// const detailsElement = document.querySelector('.details-sidebar');
|
||||
// detailsElement.addEventListener('toggle', event => {
|
||||
// if (event.target.open) {
|
||||
// console.log('open');
|
||||
// if (sessionStorage.getItem("opened") && !(sessionStorage.getItem("opened") === detailsElement.id)) {
|
||||
// sessionStorage.removeItem("opened");
|
||||
// }
|
||||
// sessionStorage.setItem("opened", detailsElement.id);
|
||||
// console.log(detailsElement);
|
||||
//
|
||||
// } else {
|
||||
// console.log('closed');
|
||||
// sessionStorage.removeItem("opened");
|
||||
//
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// async function fetchIndexJSON() {
|
||||
// const response = await fetch('/index.json');
|
||||
// const index = await response.json();
|
||||
// return index;
|
||||
// }
|
||||
// // Extract the `q` query parameter
|
||||
//var queryStringRegex = /[\?&]q=([^&]+)/g;
|
||||
//var matches = queryStringRegex.exec(window.location.search);
|
||||
//if(matches && matches[1]) {
|
||||
// var value = decodeURIComponent(matches[1].replace(/\+/g, '%20'));
|
||||
//
|
||||
//
|
||||
// // fetchIndexJSON()
|
||||
// // .then(index => { console.log(index['index']);});
|
||||
// // Load the posts to search
|
||||
// fetch('/index').then(function(posts) {
|
||||
// // Remember to include Fuse.js before this script.
|
||||
//
|
||||
// var fuse = new Fuse(posts, {
|
||||
// keys: ['title', 'tags', 'content'] // What we're searching
|
||||
// });
|
||||
//
|
||||
// // Run the search
|
||||
// var results = fuse.search(value);
|
||||
// //console.log(results);
|
||||
//
|
||||
// // Generate markup for the posts, implement SearchResults however you want.
|
||||
// // var $results = SearchResults(results);
|
||||
//
|
||||
// // Add the element to the empty <div> from before.
|
||||
//// $('#searchResults').append($results);
|
||||
// });
|
||||
//}
|
||||
let _keys = Object.keys(sessionStorage);
|
||||
if (_keys) {
|
||||
for ( let i = 0; i < _keys.length; i++ ) {
|
||||
document.getElementById(_keys[i])['open'] = 'open';
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/mathjax@2/MathJax.js"></script>
|
||||
<script src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML" type="text/javascript"></script>
|
||||
</script>
|
||||
<script async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML" type="text/javascript"></script>
|
||||
<script type="text/x-mathjax-config">
|
||||
MathJax.Hub.Config({
|
||||
config: ["MMLorHTML.js"],
|
||||
jax: ["input/TeX", "output/HTML-CSS", "output/NativeMML"],
|
||||
extensions: ["MathMenu.js", "MathZoom.js"]
|
||||
});
|
||||
</script>
|
||||
MathJax.Hub.Config({
|
||||
config: ["MMLorHTML.js"],
|
||||
jax: ["input/TeX", "output/HTML-CSS", "output/NativeMML"],
|
||||
extensions: ["MathMenu.js", "MathZoom.js"]
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
Loading…
Reference in New Issue