Skip to content

Commit

Permalink
v1.1
Browse files Browse the repository at this point in the history
  • Loading branch information
gechandesu committed Mar 28, 2021
1 parent 73f23a5 commit c024615
Show file tree
Hide file tree
Showing 10 changed files with 135 additions and 95 deletions.
19 changes: 18 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
# Changelog

## v1.1 2021.03.28

### Added

- **owl** switched to `markdown` module.
- `markdown_alerts` extension. Short admonition syntax.
- `markdown_del_ins` extension. Deleted and inserted text support.

### Changed

- Fixed `PASSWORD_FILE` detecting.
- Fixed path resolving. Now uses `os.path.join()`.

### Removed

- `markdown2`. Replaced by `markdown` module.

## v1.0 2021.03.23

### Added
Expand Down Expand Up @@ -27,4 +44,4 @@

## v0.1 2020.08.15

First version released.
First version released.
12 changes: 5 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# owl

![](https://img.shields.io/badge/owl-v1.0-%2300f)
![](https://img.shields.io/badge/owl-v1.1-blueviolet)

**owl** — is the minimalistic kn**owl**edge base web app written in Python.

Expand All @@ -22,13 +22,11 @@ App is now available at [http://localhost:5000/](http://localhost:5000/).

This solution is suitable for creating documentation or maintaining a personal knowledge base.

New in `v1.0`:
- This is brand new owl!
- New frontend and refactored backend.
- Bootstrap 5
- Optional authentication.
New in `v1.1`:
- Switched to [Python-Markdown](https://github.com/Python-Markdown/markdown).
- Added some new Markdown extensions.

See [CHANGELOG.md](CHANGELOG.md)
See [CHANGELOG.md](CHANGELOG.md).

# License

Expand Down
36 changes: 26 additions & 10 deletions config.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,32 @@
class Config(object):
DEBUG = False
SECRET_KEY = 'top_secret'
SECRET_KEY = None
PASSWORD_FILE = '.pw'
SIGN_IN = False # Enable or disable authentication
MARKDOWN_ROOT = 'docs/' # Path to your .md files
MARKDOWN_DOWLOADS = True
# See https://github.com/trentm/python-markdown2/wiki/Extras
MARKDOWN2_EXTRAS = [
'fenced-code-blocks',
'markdown-in-html',
'code-friendly',
'header-ids',
'strike',
'tables'
]
MARKDOWN_EXTRAS = [
'admonition',
'attr_list',
'codehilite',
'def_list',
'fenced_code',
'md_in_html',
'markdown_alerts',
'markdown_del_ins',
'tables',
'toc'
]
MARKDOWN_EXTRAS_CONFIGS = {
'markdown_alerts': {
'info': 'alert alert-info',
'note': 'alert alert-primary',
'tip': 'alert alert-success',
'success': 'alert alert-success',
'warning': 'alert alert-warning',
'danger': 'alert alert-danger'
},
'toc': {
'toc_depth': '2-5'
}
}
4 changes: 2 additions & 2 deletions docs/CONTENTS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
### Contents
# @v@

- [Home](/)
- [Home](/)
16 changes: 13 additions & 3 deletions docs/HOME.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
# @v@ owl took off!
# owl took off!

Read the [Docs](https://owl.gch.icu/docs/) to get started.
<pre class='raw'>
, ,
/\ /\
((@v@))
((;;; (\
\ ;;; \'
,V.V `
`` ``
</pre>

Also there is project's [git repository](https://gitea.gch.icu/gd/owl) ([mirror](https://github.com/gechandesu/owl)).
Read the [Docs](https://owl.gch.icu/docs/){target="_blank"} to get started.

Also there is project's [git repository](https://gitea.gch.icu/gd/owl) ([mirror on GitHub](https://github.com/gechandesu/owl)).

34 changes: 20 additions & 14 deletions owl.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
__version__ = '1.1'

import os
import re
from functools import wraps
from datetime import timedelta

import pygments
from markdown2 import Markdown
from markdown import Markdown

from flask import Flask
from flask import request
Expand All @@ -30,31 +32,35 @@ def read_file(filepath: str) -> str:
except IOError:
return 'Error: Cannot read file: {}'.format(filepath)

def get_path(path: str) -> str:
return os.path.join(app.config['MARKDOWN_ROOT'], path)

def render_html(filepath: str) -> str:
markdown = Markdown(extras=app.config['MARKDOWN2_EXTRAS'])
return markdown.convert(
read_file(
app.config['MARKDOWN_ROOT'] + filepath
)
)
html = Markdown(
extensions = app.config['MARKDOWN_EXTRAS'],
extension_configs = app.config['MARKDOWN_EXTRAS_CONFIGS']
)
return html.convert(
read_file(get_path(filepath))
)

def parse_title_from_markdown(filepath: str) -> str:
# This function parses article title from first level heading.
# It returns the occurrence of the first heading, and there
# can be nothing before it except empty lines and spaces.
article = read_file(app.config['MARKDOWN_ROOT'] + filepath)
article = read_file(get_path(filepath))
pattern = re.compile(r'^\s*#\s.*')
if pattern.search(article):
return pattern.search(article).group().strip()[2:]
else:
return 'Error: Cannot parse title from file:'.format(filepath)
return 'Error: Cannot parse title from file: {}'.format(filepath)

def parse_content_links(filepath: str) -> list:
# This function returns a list of links from a Markdown file.
# Only links contained in the list (ul ol li) are parsed.
r = re.compile(r'(.*(-|\+|\*|\d).?\[.*\])(\(.*\))', re.MULTILINE)
links = []
for tpl in r.findall(read_file(app.config['MARKDOWN_ROOT'] + filepath)):
for tpl in r.findall(read_file(get_path(filepath))):
for item in tpl:
if re.match(r'\(.*\)', item):
if item == '(/)':
Expand All @@ -67,8 +73,8 @@ def parse_content_links(filepath: str) -> list:
return links

def check_password(password: str) -> bool:
if os.path.exists('.pw'):
pw_hash = read_file('.pw')
if os.path.exists(app.config['PASSWORD_FILE']):
pw_hash = read_file(app.config['PASSWORD_FILE'])
return bcrypt.check_password_hash(pw_hash, password)
else:
return False
Expand Down Expand Up @@ -129,7 +135,7 @@ def index():
@app.route('/<path:path>/')
@login_required
def get_article(path):
if os.path.exists(app.config['MARKDOWN_ROOT'] + path + '.md'):
if os.path.exists(get_path(path) + '.md'):
return render_template(
'index.j2',
title = parse_title_from_markdown(path + '.md'),
Expand All @@ -144,7 +150,7 @@ def get_article(path):
@app.route('/<path:path>.md')
@login_required
def download_article(path):
if os.path.exists(app.config['MARKDOWN_ROOT'] + path + '.md') \
if os.path.exists(get_path(path) + '.md') \
and app.config['MARKDOWN_DOWLOADS']:
return send_from_directory(
app.config['MARKDOWN_ROOT'],
Expand Down
6 changes: 4 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
flask>=1.1
flask-bcrypt>=0.7
markdown2>=2.3
pygments>=2.6
pygments>=2.6
markdown>=3.3.4
markdown-alerts>=0.1
markdown-del-ins>=1.0.0
73 changes: 33 additions & 40 deletions static/css/style.css
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
body {
font-family: 'Ubuntu', sans-serif;
font-size: 19px;
font-size: 18px;
}

h1,
Expand Down Expand Up @@ -41,10 +41,28 @@ blockquote {

blockquote p { margin: 0; }

dl dt {
padding:0;
margin-top:16px;
font-size:1em;
font-style:italic;
font-weight:bold
}

dl dd {
padding:0 2rem;
margin-bottom:16px
}

/* Delete margin for admonitions */
.alert p:last-child {
margin: 0;
padding: 0;
}

/* Details and summary */

details, summary {
display: block;
margin: 1rem 0;
transition: 200ms linear;
}
Expand All @@ -54,45 +72,21 @@ summary {
transition: .3s;
}

/* Hide defaul marker */
details > summary { list-style: none; }
details summary::-webkit-details-marker { display: none; }

details[open] summary ~ * {
animation: open 0.3s ease-in-out;
}

@keyframes open {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}

details summary:before {
content: '+';
font-family: 'Ubuntu Mono';
font-size: 20px;
display: inline-flex;
padding: 0 0.3rem;
}

details[open] summary:before {
content: '-';
font-family: 'Ubuntu Mono';
font-size: 20px;
display: inline-flex;
padding: 0 0.3rem;
0% { opacity: 0; }
100% { opacity: 1; }
}

/* Code styling */

code,
pre {
font-family: 'Ubuntu Mono', monospace;
font-size: 19px;
font-size: 18px;
color: #d0d0d0;
}

Expand All @@ -111,7 +105,7 @@ code {
border-radius: 6px;
}

.raw-pre {
.raw {
color: unset;
background: unset;
}
Expand Down Expand Up @@ -168,15 +162,6 @@ code {
text-align: center;
}

/* Header bar */

.header {
display: block;
position: fixed;
height: 5rem;
background: unset;
}

/* Sidebar */

.sidebar-toggle-btn {
Expand Down Expand Up @@ -227,6 +212,13 @@ code {

.sidebar a:hover { text-decoration: underline; }

.sidebar h1,
.sidebar h2,
.sidebar h3,
.sidebar h4 {
margin-left: 1rem;
}

.sidebar ul,
.sidebar ol,
.sidebar li {
Expand Down Expand Up @@ -301,7 +293,8 @@ article.wide { max-width: 980px; }
@media (max-width: 1200px) {
.header { background: #ffffff; }
.sidebar { left: -300px; }
.sidebar-toggle-btn { left: 1rem; }
.sidebar-toggle-btn { left: 0.5rem; }
.signout-btn { right: 0.5rem; }
.content { margin-left: 0px; }
.sidebar.hide { left: 0px; }
.sidebar-toggle-btn.click { left: 316px; }
Expand Down
6 changes: 0 additions & 6 deletions templates/base.j2
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,6 @@
</head>
<body>

{% if session['logged_in'] %}
<div class="signout-btn">
<a href="/signout/" title="Sign out"><i class="bi bi-box-arrow-right"></i></a>
</div>
{% endif %}

{% block content %}
No content here
{% endblock %}
Expand Down
Loading

0 comments on commit c024615

Please sign in to comment.