diff --git a/.gitignore b/.gitignore index af24c17..729280b 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ content/ .eggs *.egg-info dist/ +.idea diff --git a/appveyor.yml b/appveyor.yml index b911faa..c9afc64 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -build: off +build: false environment: matrix: diff --git a/setup.py b/setup.py index 0420cce..a2ef4b9 100644 --- a/setup.py +++ b/setup.py @@ -10,16 +10,15 @@ author='Alexander Jung-Loddenkemper', author_email='alexander@julo.ch', url='https://github.com/alexanderjulo/wiki', - packages=find_packages(), + packages=find_packages(exclude=['tests']), include_package_data=True, python_requires='>3.7', install_requires=[ 'Flask>=0.9', - 'Click>=6,<7', + 'Click>=6', 'Flask-Login>=0.4', 'Flask-WTF>=0.8', 'Markdown>=2.2.0', - 'Pygments>=1.5', 'WTForms>=1.0.2', 'Werkzeug>=0.8.3', 'python-markdown-math' diff --git a/tests/__init__.py b/tests/__init__.py index 777d335..33693e9 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -2,7 +2,7 @@ import os import shutil from tempfile import mkdtemp -from tempfile import mkstemp +# from tempfile import mkstemp from unittest import TestCase from wiki.core import Wiki @@ -18,7 +18,6 @@ class WikiBaseTestCase(TestCase): - #: The contents of the ``config.py`` file. config_content = CONFIGURATION @@ -69,7 +68,6 @@ def create_file(self, name, content=u'', folder=None): return path - def tearDown(self): """ Will remove the root directory and all contents if one diff --git a/tests/test_core.py b/tests/test_core.py index 93b81c5..a948c79 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -14,7 +14,6 @@ from . import WikiBaseTestCase - PAGE_CONTENT = u"""\ title: Test tags: one, two, 3, jö @@ -28,12 +27,10 @@ Hello, how are you guys? """ - CONTENT_HTML = u"""\
Hello, how are you guys?
Is it not magnificent?
""" - WIKILINK_PAGE_CONTENT = u"""\ title: link @@ -100,7 +97,7 @@ def test_handle_spaces(self): other spaces correctly substituted. """ assert (clean_url(' /hello you/wonderful/person ') - == '/hello_you/wonderful/person') + == '/hello_you/wonderful/person') def test_handle_uppercase(self): """ @@ -228,7 +225,6 @@ def setUp(self): self.page_path = self.create_file('test.md', self.page_content) - def test_page_loading_fails(self): """ Assert that content is loaded correctly from disk. diff --git a/wiki/__init__.py b/wiki/__init__.py index b2e2239..180f704 100644 --- a/wiki/__init__.py +++ b/wiki/__init__.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- from wiki.core import Wiki __all__ = ['Wiki'] diff --git a/wiki/cli.py b/wiki/cli.py index a3eeb1c..b436fea 100644 --- a/wiki/cli.py +++ b/wiki/cli.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- """ CLI ~~~ @@ -7,6 +8,7 @@ import click from wiki.web import create_app + @click.group() @click.option('--directory', type=click.Path(exists=True), default=None) @click.pass_context @@ -15,6 +17,7 @@ def main(ctx, directory): Base setup for all the following commands. \b + :param ctx: context? :param str directory: the directory to run wiki in, optional. If no directory is provided the current directory will be used. @@ -34,6 +37,7 @@ def web(ctx, debug, host, port): Run the web app. \b + :param ctx: context? :param bool debug: whether or not to run the web app in debug mode. :param str host: Set the host to 0.0.0.0 to connect from outside. diff --git a/wiki/core.py b/wiki/core.py index 58113f3..0c42ead 100644 --- a/wiki/core.py +++ b/wiki/core.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- """ Wiki core ~~~~~~~~~ @@ -97,7 +98,7 @@ def __init__(self, text): 'fenced_code', 'meta', 'tables', - 'mdx_math' # mathjax support + 'mdx_math' # mathjax support ]) self.input = text self.markdown = None @@ -123,7 +124,6 @@ def process_markdown(self): """ self.html = self.md.convert(self.pre) - def split_raw(self): """ Split text into raw meta and content. @@ -141,12 +141,13 @@ def process_meta(self): # entries, so we have to loop over the meta values a second # time to put them into a dictionary in the correct order self.meta = OrderedDict() - for line in self.meta_raw.split('\n'): - key = line.split(':', 1)[0] - # markdown metadata always returns a list of lines, we will - # reverse that here - self.meta[key.lower()] = \ - '\n'.join(self.md.Meta[key.lower()]) + if self.md.Meta: # skip meta-less + for line in self.meta_raw.split('\n'): + key = line.split(':', 1)[0] + # markdown metadata always returns a list of lines, we will + # reverse that here + self.meta[key.lower()] = \ + '\n'.join(self.md.Meta[key.lower()]) def process_post(self): """ @@ -174,6 +175,9 @@ def process(self): class Page(object): def __init__(self, path, url, new=False): + self.content = None + self._html = None + self.body = None self.path = path self.url = url self._meta = OrderedDict() @@ -321,7 +325,7 @@ def index(self): root = os.path.abspath(self.root) for cur_dir, _, files in os.walk(root): # get the url of the current directory - cur_dir_url = cur_dir[len(root)+1:] + cur_dir_url = cur_dir[len(root) + 1:] for cur_file in files: path = os.path.join(cur_dir, cur_file) if cur_file.endswith('.md'): @@ -382,7 +386,7 @@ def index_by_tag(self, tag): tagged.append(page) return sorted(tagged, key=lambda x: x.title.lower()) - def search(self, term, ignore_case=True, attrs=['title', 'tags', 'body']): + def search(self, term, ignore_case=True, attrs=('title', 'tags', 'body')): pages = self.index() regex = re.compile(term, re.IGNORECASE if ignore_case else 0) matched = [] diff --git a/wiki/web/__init__.py b/wiki/web/__init__.py index c1f5e91..9f13e0a 100644 --- a/wiki/web/__init__.py +++ b/wiki/web/__init__.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- import os from flask import current_app @@ -9,23 +10,28 @@ from wiki.core import Wiki from wiki.web.user import UserManager + class WikiError(Exception): pass + def get_wiki(): wiki = getattr(g, '_wiki', None) if wiki is None: wiki = g._wiki = Wiki(current_app.config['CONTENT_DIR']) return wiki + current_wiki = LocalProxy(get_wiki) + def get_users(): users = getattr(g, '_users', None) if users is None: users = g._users = UserManager(current_app.config['CONTENT_DIR']) return users + current_users = LocalProxy(get_users) @@ -52,6 +58,7 @@ def create_app(directory): loginmanager = LoginManager() loginmanager.login_view = 'wiki.user_login' + @loginmanager.user_loader def load_user(name): return current_users.get_user(name) diff --git a/wiki/web/forms.py b/wiki/web/forms.py index 9da436d..3debc83 100644 --- a/wiki/web/forms.py +++ b/wiki/web/forms.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- """ Forms ~~~~~ @@ -12,6 +13,7 @@ from wtforms import PasswordField from wtforms.validators import InputRequired from wtforms.validators import ValidationError +from wtforms.validators import EqualTo from wiki.core import clean_url from wiki.web import current_wiki @@ -58,3 +60,15 @@ def validate_password(form, field): return if not user.check_password(field.data): raise ValidationError('Username and password do not match.') + + +class RegistrationForm(FlaskForm): + name = StringField('Username', [InputRequired()]) + password = PasswordField('Password', [InputRequired()]) + password_confirm = PasswordField('Confirm Password', + validators=[InputRequired(), EqualTo('password')]) + + def validate_name(form, field): + user = current_users.get_user(form.name.data) + if user: + raise ValidationError('This username already exist.') diff --git a/wiki/web/routes.py b/wiki/web/routes.py index af4cc2b..3b68d80 100644 --- a/wiki/web/routes.py +++ b/wiki/web/routes.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- """ Routes ~~~~~~ @@ -8,6 +9,7 @@ from flask import render_template from flask import request from flask import url_for +from flask import current_app from flask_login import current_user from flask_login import login_required from flask_login import login_user @@ -18,9 +20,11 @@ from wiki.web.forms import LoginForm from wiki.web.forms import SearchForm from wiki.web.forms import URLForm +from wiki.web.forms import RegistrationForm from wiki.web import current_wiki from wiki.web import current_users from wiki.web.user import protect +from wiki.web.user import UserManager bp = Blueprint('wiki', __name__) @@ -38,6 +42,11 @@ def home(): @bp.route('/index/') @protect def index(): + import locale + current_app.logger.info("defaultlocale: {}".format(locale.getdefaultlocale())) + current_app.logger.info("locale: {}".format(locale.getlocale())) + current_app.logger.info("preferredencoding: {}".format(locale.getpreferredencoding())) + locale.setlocale(locale.LC_ALL, 'ru_RU') pages = current_wiki.index() return render_template('index.html', pages=pages) @@ -50,6 +59,7 @@ def display(url): @bp.route('/create/', methods=['GET', 'POST']) +@login_required @protect def create(): form = URLForm() @@ -60,6 +70,7 @@ def create(): @bp.route('/edit/