예제 #1
0
def test_get_page():
    with app.app_context():
        page = storage.get_page('my-page/')
        assert isinstance(page, Page)
        assert page.rel_url == 'my-page/'
        assert page.unique_key == '/my-page/'
        assert page.format == 'markdown'
        assert (page.meta, page.raw_content) == FileStorage.read_file(
            os.path.join(current_app.instance_path, 'pages', 'my-page',
                         'index.md'))

        page = storage.get_page('my-page/index.html')
        assert page.rel_url == 'my-page/index.html'
        assert page.unique_key == '/my-page/'
        assert page.format == 'markdown'

        page = storage.get_page('index.html')
        assert page.rel_url == 'index.html'
        assert page.unique_key == '/index.html'
        assert page.format == 'markdown'

        page = storage.get_page('test-page.html')
        assert page.rel_url == 'test-page.html'
        assert page.unique_key == '/test-page.html'
        assert page.format == 'txt'

        page = storage.get_page('test-page-draft.html')
        assert page is None
        page = storage.get_page('test-page-draft.html', include_draft=True)
        assert page is not None

        page = storage.get_page('test-non-exists.html')
        assert page is None
        page = storage.get_page('non-exists/non-exists.html')
        assert page is None
예제 #2
0
def generate_pages_by_file():
    """Generates custom pages of 'file' storage type."""
    from veripress import app
    from veripress.model import storage
    from veripress.model.parsers import get_standard_format_name
    from veripress.helpers import traverse_directory

    deploy_dir = get_deploy_dir()

    def copy_file(src, dst):
        makedirs(os.path.dirname(dst), mode=0o755, exist_ok=True)
        shutil.copyfile(src, dst)

    with app.app_context(), app.test_client() as client:
        root_path = os.path.join(app.instance_path, 'pages')
        for path in traverse_directory(root_path):
            rel_path = os.path.relpath(path, root_path)  # e.g. 'a/b/c/index.md'
            filename, ext = os.path.splitext(rel_path)  # e.g. ('a/b/c/index', '.md')
            if get_standard_format_name(ext[1:]) is not None:
                # is source of custom page
                rel_url = filename.replace(os.path.sep, '/') + '.html'  # e.g. 'a/b/c/index.html'
                page = storage.get_page(rel_url, include_draft=False)
                if page is not None:
                    # it's not a draft, so generate the html page
                    makedirs(os.path.join(deploy_dir, os.path.dirname(rel_path)), mode=0o755, exist_ok=True)
                    with open(os.path.join(deploy_dir, filename + '.html'), 'wb') as f:
                        f.write(client.get('/' + rel_url).data)
                if app.config['PAGE_SOURCE_ACCESSIBLE']:
                    copy_file(path, os.path.join(deploy_dir, rel_path))
            else:
                # is other direct files
                copy_file(path, os.path.join(deploy_dir, rel_path))
예제 #3
0
def page(rel_url):
    if not validate_custom_page_path(rel_url):
        abort(403)

    fixed_rel_url, exists = storage.fix_page_relative_url(rel_url)
    if exists:
        file_path = fixed_rel_url
        return send_file(file_path)
    elif fixed_rel_url is None:
        # relative url is invalid
        # this is never possible when visiting this site in web browser
        abort(404)  # pragma: no cover
    elif rel_url != fixed_rel_url:
        # it's not the correct relative url, so redirect
        return redirect(url_for('.page', rel_url=fixed_rel_url))

    resp = cache.get('view-handler.' + rel_url)
    if resp is not None:
        return resp  # pragma: no cover, here just get the cached response

    page_ = storage.get_page(rel_url, include_draft=False)
    if page_ is None:
        abort(404)

    page_d = page_.to_dict()
    del page_d['raw_content']
    page_d['content'] = get_parser(page_.format).parse_whole(page_.raw_content)
    page_d['content'], page_d['toc'], page_d['toc_html'] = \
        parse_toc(page_d['content'])
    page_d['url'] = make_abs_url(page_.unique_key)
    page_ = page_d

    resp = custom_render_template(page_['layout'] + '.html', entry=page_)
    cache.set('view-handler.' + rel_url, resp, timeout=2 * 60)
    return resp
예제 #4
0
def pages(page_path):
    if not validate_custom_page_path(page_path):
        raise ApiException(
            error=Error.NOT_ALLOWED,
            message='The visit of path "{}" is not allowed.'.format(page_path)
        )

    rel_url, exists = storage.fix_relative_url('page', page_path)
    if exists:
        file_path = rel_url
        return send_file(file_path)
    elif rel_url is None:
        # pragma: no cover
        # it seems impossible to make this happen,
        # see code of 'fix_relative_url'
        raise ApiException(
            error=Error.BAD_PATH,
            message='The path "{}" cannot be recognized.'.format(page_path)
        )
    else:
        page_d = cache.get('api-handler.' + rel_url)
        if page_d is not None:
            return page_d  # pragma: no cover, here just get the cached dict

        page = storage.get_page(rel_url, include_draft=False)
        if page is None:
            raise ApiException(error=Error.RESOURCE_NOT_EXISTS)
        page_d = page.to_dict()
        del page_d['raw_content']
        page_d['content'] = get_parser(
            page.format).parse_whole(page.raw_content)

        cache.set('api-handler.' + rel_url, page_d, timeout=2 * 60)
        return page_d
예제 #5
0
def index(page_num=1):
    if page_num <= 1 and request.path != '/':
        return redirect(url_for('.index'))  # redirect '/page/1' to '/'

    index_page = storage.get_page('index.html', include_draft=False)
    if index_page is not None:
        # there is an 'index.*' custom page, we use this as index.
        return page('index.html')

    all_posts = storage.get_posts(include_draft=False)

    count = current_app.config['ENTRIES_PER_PAGE']
    start = (page_num - 1) * count

    posts = []
    for post_ in islice(
            all_posts, start, start + count +
            1):  # slice an additional one to check if there is more
        post_d = post_.to_dict()
        del post_d['raw_content']
        post_d['preview'], post_d['has_more_content'] = get_parser(
            post_.format).parse_preview(post_.raw_content)
        post_d['url'] = make_abs_url(post_.unique_key)
        posts.append(post_d)

    if start > 0:
        next_page_num = page_num - 1
        next_url = url_for(
            '.index', page_num=next_page_num if next_page_num != 1 else None)
    else:
        next_url = None
    if len(posts) > count:
        # the additional one is included
        posts = posts[:count]
        prev_url = url_for('.index', page_num=page_num + 1)
    else:
        prev_url = None

    return dict(entries=posts, next_url=next_url, prev_url=prev_url)