Пример #1
0
 def __init__(self, config: Config):
     self.config = config
     self.cache: Cache = Cache.instance(self)
     self.exclusions: List[Pattern] = list(
         map(lambda e: re.compile(e), config.get('content', 'exclusions')))
     self.root_path: Path = Path(config.get('content', 'root')).resolve()
     self.root: Directory = Directory(self)
     self.theme: Theme = Theme(self)
     self.auth_provider: AuthProvider = AuthProvider.instance(self)
Пример #2
0
def test_serve_non_markdown_file():

    markdownup = MarkdownUp(
        Config.from_dict({
            'content': {
                'root':
                str(
                    Path(__file__).parent / '..' / '..' / 'test_resources' /
                    'dummy_docs')
            }
        }))

    response = markdownup.get('/dummy-asset.txt')

    assert response.status == '200 OK'
    assert next(response.body).decode('UTF-8') == 'Dummy asset content.'
Пример #3
0
def test_prevent_access_outside_root():

    markdownup = MarkdownUp(
        Config.from_dict({
            'content': {
                'root':
                str(
                    Path(__file__).parent / '..' / '..' / 'test_resources' /
                    'dummy_docs' / 'subdir')
            }
        }))

    response = markdownup.get('../index.md')

    assert response.status == '400 Bad Request'
    assert response.body[0] == b'400 Bad Request'
Пример #4
0
def test_search():

    markdownup = MarkdownUp(
        Config.from_dict({
            'content': {
                'root':
                str(
                    Path(__file__).parent / '..' / '..' / 'test_resources' /
                    'dummy_docs')
            }
        }))

    results = search(markdownup, {'auth': {}}, ["THIS"])

    assert len(results) == 2
    assert results[0].name == 'Hello, World!'
    assert results[1].name == 'Hello, nested World!'
Пример #5
0
def test_hidden_file_request_yields_404():

    # 404 because we don't want to expose the fact it exists

    markdownup = MarkdownUp(
        Config.from_dict({
            'content': {
                'root':
                str(
                    Path(__file__).parent / '..' / '..' / 'test_resources' /
                    'dummy_docs')
            }
        }))

    response = markdownup.get('/.hidden.md')

    assert response.status == '404 Not Found'
Пример #6
0
def test_get():

    markdownup = MarkdownUp(
        Config.from_dict({
            'theme': 'bare',
            'content': {
                'root':
                str(
                    Path(__file__).parent / '..' / '..' / 'test_resources' /
                    'dummy_docs'),
                'indices': []
            }
        }))

    response = markdownup.get('/index.md')

    assert response.status == '200 OK'
    assert response.body[
        0] == b'<h1>Hello, World!</h1>\n<p>This is a markdown file.</p>'
Пример #7
0
def test_get_hidden_file_with_proper_config():

    markdownup = MarkdownUp(
        Config.from_dict({
            'theme': 'bare',
            'content': {
                'root':
                str(
                    Path(__file__).parent / '..' / '..' / 'test_resources' /
                    'dummy_docs'),
                'exclusions': []
            }
        }))

    response = markdownup.get('/.hidden.md')

    assert response.status == '200 OK'
    assert response.body[
        0] == b'<p>This file must not be served with the default configuration.</p>'
Пример #8
0
def test_get_theme_asset():

    markdownup = MarkdownUp(
        Config.from_dict({
            'theme':
            str(
                Path(__file__).parent / '..' / '..' / 'test_resources' /
                'test_theme'),
            'content': {
                'root':
                str(
                    Path(__file__).parent / '..' / '..' / 'test_resources' /
                    'dummy_docs')
            }
        }))

    response = markdownup.get('/frame.css')

    assert response.status == '200 OK'
    assert next(response.body).decode('UTF-8') == 'p { color: #111; }'
Пример #9
0
def test_title_not_on_first_line():

    markdownup = MarkdownUp(
        Config.from_dict({
            'theme':
            str(
                Path(__file__).parent / '..' / '..' / 'test_resources' /
                'test_theme'),
            'content': {
                'root':
                str(
                    Path(__file__).parent / '..' / '..' / 'test_resources' /
                    'dummy_docs')
            }
        }))

    response = markdownup.get('/title_not_on_first_line.md')

    assert response.status == '200 OK'
    assert response.body[
        0] == b'Title goes here: Title\n\nContent goes here:\n\n<p>Some text first.</p>\n<h1>Title</h1>'
Пример #10
0
def test_search_with_auth():

    markdownup = MarkdownUp(
        Config.from_dict({
            'content': {
                'root':
                str(
                    Path(__file__).parent / '..' / '..' / 'test_resources' /
                    'dummy_docs'),
            }
        }))

    results = search(markdownup,
                     {'auth': {
                         'authenticated': {
                             'roles': {'keepers'}
                         }
                     }}, ["THIS"])

    assert len(results) == 3
    assert results[0].name == 'Hello, World!'
    assert results[1].name == 'Hello, nested World!'
    assert results[2].name == 'Hello, secret nested World!'
Пример #11
0
 def __init__(self, config: Config):
     super().__init__(
         (config.get('cache', 'host'), config.get('cache', 'port')),
         _BuiltinCacheHandler)
     self.cache = {}
Пример #12
0
def _main():

    if len(sys.argv) == 2:

        # initialize config based on argv
        config = None
        as_path = Path(sys.argv[1])
        if as_path.is_dir():
            config = Config.from_dict({'content': {'root': sys.argv[1]}})
        elif as_path.is_file():
            config = Config.from_file(as_path)
            os.chdir(
                as_path.parent)  # pretend to run from the config's parent dir
        else:
            print(f'No such file or directory: {as_path}')
            exit(1)

        # launch a new process for the built in cache server if configured
        if config.get('cache', 'type') == 'builtin':
            Process(daemon=True,
                    target=BuiltinCacheServer(config).serve_forever).start()

        # TODO if configured process and cache all markdown files

        # launch the main MarkdownUp WSGI application
        markdownup = MarkdownUp(config)
        Process(target=WsgiApplication(markdownup).run).start()
        signal.pause(
        )  # sleep indefinitely, makes for a cleaner ctrl+c termination

        # if the above returns we exit normally
        exit(0)

    if len(sys.argv) > 2:
        if sys.argv[1] == '--start-config':
            config = yaml.dump(default_config)
            target_file = Path(sys.argv[2])
            if target_file.exists():
                print('Target file exists, not doing anything')
                exit(2)
            target_file.write_text(config)
            exit(0)
        elif sys.argv[1] == '--start-theme':
            target_dir = Path(sys.argv[2])
            if target_dir.exists():
                print('Target dir exists, not doing anything')
                exit(3)
            theme_name = 'default' if len(sys.argv) == 3 else sys.argv[3]
            theme_dir = Path(__file__).parent / 'themes' / theme_name
            if not theme_dir.exists():
                theme_names = ', '.join(
                    theme.name for theme in theme_dir.parent.iterdir()
                    if theme.is_dir())
                print(f'No such theme "{theme_name}", themes: {theme_names}')
                exit(4)
            shutil.copytree(theme_dir, target_dir)
            exit(0)

    print('Usage option 1: <path-to-markdown-root-directory>\n'
          'Usage option 2: <path-to-config-file>\n'
          'Usage option 3: --start-config <path-to-new-file>\n'
          'Usage option 4: --start-theme <path-to-new-theme> [<seed-theme>]')
    exit(5)