首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >静态博客生成器-Python烧瓶- ValueError

静态博客生成器-Python烧瓶- ValueError
EN

Stack Overflow用户
提问于 2015-03-07 19:24:43
回答 1查看 818关注 0票数 0

我正试图使用python烧瓶框架构建一个静态博客生成器,但我遇到了一个问题。我们的目标是使用Frozen将我的Flask应用程序冻结到一组静态文件中,这样我就可以将文件推送到Github页面。python脚本运行良好,但当我在终端中输入构建命令时,问题就出现了。

请允许我详细说明以下步骤:

命令行输入:

代码语言:javascript
复制
python generator.py build

命令行输出:

代码语言:javascript
复制
Traceback (most recent call last):
  File "generator.py", line 152, in <module>
    freezer.freeze()
  File "/home/chris/.virtualenvs/blog/local/lib/python2.7/site-packages/flask_frozen/__init__.py", line 166, in freeze
    new_filename = self._build_one(url)
  File "/home/chris/.virtualenvs/blog/local/lib/python2.7/site-packages/flask_frozen/__init__.py", line 280, in _build_one
    % (response.status, url))
ValueError: Unexpected status '500 INTERNAL SERVER ERROR' on URL /feed.atom

我查看了ValueError的python文档,以了解它的含义。

异常ValueError 当内置操作或函数接收到具有正确类型但值不适当的参数时,就会引发这种情况,并且这种情况不会由更精确的异常(如IndexError )来描述。

下面是终端输出中提到的python脚本中的代码行:

代码语言:javascript
复制
@app.route('/feed.atom')
def feed():
    feed = AtomFeed('Recent Articles',
                    feed_url=request.url,
                    url=request.url_root)
    posts = blog.posts[:10]
    title = lambda p: '%s: %s' % (p.title, p.subtitle) if hasattr(p, 'subtitle') else p.title
    for post in posts:
        feed.add(title(post),
            unicode(post.html),
            content_type='html',
            author=post.author.name,
            url=post.url(_external=True),
            updated=post.date,
            published=post.date)
    return feed.get_response()

if __name__ == '__main__':
    if len(sys.argv) > 1 and sys.argv[1] == 'build':
        freezer.freeze()
    else:
        post_files = [post.filepath for post in blog.posts]
        app.run(port=8000, debug=True, extra_files=post_files)

如果您需要查看整个python脚本:

代码语言:javascript
复制
import os
import sys
import collections

from flask import Flask, render_template, url_for, abort, request
from flask.ext.frozen import Freezer
from werkzeug import cached_property
from werkzeug.contrib.atom import AtomFeed
import markdown
import yaml


FREEZER_BASE_URL = 'http://example.com'
FREEZER_DESTINATION_IGNORE = ['.git*', 'CNAME']
DOMAIN = 'example.com'
POSTS_FILE_EXTENSION = '.md'


class SortedDict(collections.MutableMapping):
    def __init__(self, items=None, key=None, reverse=False):
        self._items = {}
        self._keys = []
        if key:
            self._key_fn = lambda k: key(self._items[k])
        else:
            self._key_fn = lambda k: self._items[k]
        self._reverse = reverse

        if items is not None:
            self.update(items)

    def __getitem__(self, key):
        return self._items[key]

    def __setitem__(self, key, value):
        self._items[key] = value
        if key not in self._keys:
            self._keys.append(key)
            self._keys.sort(key=self._key_fn, reverse=self._reverse)

    def __delitem__(self, key):
        self._items.pop(key)
        self._keys.remove(key)

    def __len__(self):
        return len(self._keys)

    def __iter__(self):
        for key in self._keys:
            yield key

    def __repr__(self):
        return '%s(%s)' % (self.__class__.__name__, self._items)

class Blog(object):
    def __init__(self, app, root_dir='', file_ext=None):
        self.root_dir = root_dir
        self.file_ext = file_ext if file_ext is not None else app.config['POSTS_FILE_EXTENSION']
        self._app = app
        self._cache = SortedDict(key=lambda p: p.date, reverse=True)
        self._initialize_cache()

    @property
    def posts(self):
        if self._app.debug:
            return self._cache.values()
        else:
            return [post for post in self._cache.values() if post.published]

    def get_post_or_404(self, path):
        """Returns the Post object for the given path or raises a NotFound exception
        """
        try:
            return self._cache[path]
        except KeyError:
            abort(404)

    def _initialize_cache(self):
        """Walks the root directory and adds all posts to the cache
        """
        for (root, dirpaths, filepaths) in os.walk(self.root_dir):
            for filepath in filepaths:
                filename, ext = os.path.splitext(filepath)
                if ext == self.file_ext:
                    path = os.path.join(root, filepath).replace(self.root_dir, '')
                    post = Post(path, root_dir=self.root_dir)
                    self._cache[post.urlpath] = post


class Post(object):
    def __init__(self, path, root_dir=''):
        self.urlpath = os.path.splitext(path.strip('/'))[0]
        self.filepath = os.path.join(root_dir, path.strip('/'))
        self.published = False
        self._initialize_metadata()

    @cached_property
    def html(self):
        with open(self.filepath, 'r') as fin:
            content = fin.read().split('\n\n', 1)[1].strip()
        return markdown.markdown(content, extensions=['codehilite'])

    def url(self, _external=False):
        return url_for('post', path=self.urlpath, _external=_external)

    def _initialize_metadata(self):
        content = ''
        with open(self.filepath, 'r') as fin:
            for line in fin:
                if not line.strip():
                    break
                content += line
        self.__dict__.update(yaml.load(content))

app = Flask(__name__)
app.config.from_object(__name__)
blog = Blog(app, root_dir='posts')
freezer = Freezer(app)

@app.template_filter('date')
def format_date(value, format='%B %d, %Y'):
    return value.strftime(format)

@app.route('/')
def index():
    return render_template('index.html', posts=blog.posts)

@app.route('/blog/<path:path>/')
def post(path):
    post = blog.get_post_or_404(path)
    return render_template('post.html', post=post)

@app.route('/feed.atom')
def feed():
    feed = AtomFeed('Recent Articles',
                    feed_url=request.url,
                    url=request.url_root)
    posts = blog.posts[:10]
    title = lambda p: '%s: %s' % (p.title, p.subtitle) if hasattr(p, 'subtitle') else p.title
    for post in posts:
        feed.add(title(post),
            unicode(post.html),
            content_type='html',
            author=post.author.name,
            url=post.url(_external=True),
            updated=post.date,
            published=post.date)
    return feed.get_response()

if __name__ == '__main__':
    if len(sys.argv) > 1 and sys.argv[1] == 'build':
        freezer.freeze()
    else:
        post_files = [post.filepath for post in blog.posts]
        app.run(port=8000, debug=True, extra_files=post_files)

说到烧瓶,我仍然是个新手,所以我不完全确定如何解决这个问题。如果有人能帮忙,我会很感激的。如果你需要更多的信息,请告诉我,我已经尽量详细了。

谢谢

EN

回答 1

Stack Overflow用户

发布于 2015-03-08 13:56:53

烧瓶-冻结提高ValueError,因为您的/feed.xml端点返回一个500,内部服务器错误,而不是一个200,成功的响应。烧瓶-冻结假设你不想保存400或500级错误的结果,并引发一个错误,这样你就可以查看潜在的问题。

要查看错误,请访问浏览器中的/feed.xml并查看错误响应。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28918986

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档