Создание RSS-канала в Google App Engine - PullRequest
3 голосов
/ 14 декабря 2011

Я хочу предоставить RSS-канал в google app engine / python.

Я пытался использовать обычный обработчик запросов и генерировать xml-ответ.Когда я получаю прямой доступ к URL-адресу канала, я вижу его правильно, однако, когда я пытаюсь подписаться на канал в Google Reader, он говорит, что

'Запрашиваемый канал не можетнайдено. '

Интересно, правильный ли этот подход.Я подумывал об использовании статического XML-файла и обновлении его с помощью заданий cron.Но пока GAE не поддерживает файловый ввод / вывод, этот подход, похоже, не сработает.

Как решить эту проблему?Спасибо!

Ответы [ 3 ]

6 голосов
/ 14 декабря 2011

Я предлагаю 2 решения:

  1. GAE-REST Вы можете просто добавить свой проект и настроить его, и он создаст RSS для вас, но проект устарел и больше не поддерживается.

  2. Делайте так, как я, используйте шаблон, чтобы написать список, и, как это, я смог бы успешно генерировать RSS (GeoRSS), который можно читать через google reader, где шаблон:

    <title>{{host}}</title>
    <link href="http://{{host}}" rel="self"/>
    <id>http://{{host}}/</id>
    <updated>2011-09-17T08:14:49.875423Z</updated>
    <generator uri="http://{{host}}/">{{host}}</generator>
    
    {% for entity in entities %}
    
    <entry>
    
    <title><![CDATA[{{entity.title}}]]></title>
    <link href="http://{{host}}/vi/{{entity.key.id}}"/>
    <id>http://{{host}}/vi/{{entity.key.id}}</id>
    <updated>{{entity.modified.isoformat}}Z</updated>
    <author><name>{{entity.title|escape}}</name></author>
    <georss:point>{{entity.geopt.lon|floatformat:2}},{{entity.geopt.lat|floatformat:2}}</georss:point>
    <published>{{entity.added}}</published>
    <summary type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml">{{entity.text|escape}}</div>
    </summary>
    
    </entry>
    
    {% endfor %}
    
    </feed>
    

Мой обработчик (вы также можете сделать это с помощью Python 2.7 как функция вне обработчика для более минимального решения):

class GeoRSS(webapp2.RequestHandler):

    def get(self):
        start = datetime.datetime.now() - timedelta(days=60)
        count = (int(self.request.get('count'
                 )) if not self.request.get('count') == '' else 1000)
        try:
            entities = memcache.get('entities')
        except KeyError:
            entity = Entity.all().filter('modified >',
                                  start).filter('published =',
                    True).order('-modified').fetch(count)
        memcache.set('entities', entities)
        template_values = {'entities': entities, 'request': self.request,
                           'host': os.environ.get('HTTP_HOST',
                           os.environ['SERVER_NAME'])}
        dispatch = 'templates/georss.html'
        path = os.path.join(os.path.dirname(__file__), dispatch)
        output = template.render(path, template_values)
        self.response.headers['Cache-Control'] = 'public,max-age=%s' \
            % 86400
        self.response.headers['Content-Type'] = 'application/rss+xml'
        self.response.out.write(output)

Надеюсь, кое-что из этого сработало для вас, у меня оба способа сработали.

2 голосов
/ 15 декабря 2011

Нет ничего особенного в генерации XML в отличие от HTML - при условии, что вы правильно установили тип контента. Передайте ваш фид в валидатор на http://validator.w3.org/feed/, и он скажет вам, что с ним не так.

Если это не поможет, вам нужно показать нам свой источник - мы не сможем отладить ваш код для вас, если вы не покажете его нам.

2 голосов
/ 14 декабря 2011

У меня есть генератор каналов Atom для моего блога, который работает на AppEngine / Python.Я использую шаблонизатор Django 1.2 для создания канала.Мой шаблон выглядит так:

<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"
      xml:lang="en"
      xml:base="http://www.example.org">
  <id>urn:uuid:4FC292A4-C69C-4126-A9E5-4C65B6566E05</id>
  <title>Adam Crossland's Blog</title>
  <subtitle>opinions and rants on software and...things</subtitle>
  <updated>{{ updated }}</updated>
  <author>
    <name>Adam Crossland</name>
    <email>adam@adamcrossland.net</email>
  </author>
  <link href="http://blog.adamcrossland.net/" />
  <link rel="self" href="http://blog.adamcrossland.net/home/feed" />
  {% for each_post in posts %}{{ each_post.to_atom|safe }}
  {% endfor %}
</feed>

Примечание: если вы используете что-либо из этого, вам нужно будет создать свой собственный uuid для входа в узел id .

Обновленный узел должен содержать время и дату последнего обновления содержимого канала в формате rfc 3339 .К счастью, в Python есть библиотека, которая позаботится об этом за вас.Отрывок из контроллера, который генерирует канал:

    from rfc3339 import rfc3339

    posts = Post.get_all_posts()
    self.context['posts'] = posts

    # Initially, we'll assume that there are no posts in the blog and provide
    # an empty date.
    self.context['updated'] = ""

    if posts is not None and len(posts) > 0:
        # But there are posts, so we will pick the most recent one to get a good
        # value for updated.
        self.context['updated'] = rfc3339(posts[0].updated(), utc=True)

    response.content_type = "application/atom+xml"

Не беспокойтесь о вещах self.context['updated'].Вот как моя структура предоставляет ярлык для установки переменных шаблона.Часть импорта заключается в том, что я кодирую дату, которую хочу использовать с функцией rfc3339.Кроме того, я установил свойство content_type объекта Response равным application/atom+xml.

Единственный другой отсутствующий фрагмент - это то, что шаблон использует метод с именем to_atom для превращения объекта Post в Atom-форматированные данные:

def to_atom(self):
    "Create an ATOM entry block to represent this Post."

    from rfc3339 import rfc3339

    url_for = self.url_for()
    atom_out = "<entry>\n\t<title>%s</title>\n\t<link href=\"http://blog.adamcrossland.net/%s\" />\n\t<id>%s</id>\n\t<summary>%s</summary>\n\t<updated>%s</updated>\n  </entry>" % (self.title, url_for, self.slug_text, self.summary_for(), rfc3339(self.updated(), utc=True))

    return atom_out

Это все, что требуется, насколько я знаю, и этот код генерирует совершенно приятный и работающий канал для моего блога.Теперь, если вы действительно хотите использовать RSS вместо Atom, вам нужно изменить формат шаблона канала, шаблона Post и content_type, но я думаю, что это суть того, что вам нужно сделать, чтобы получить каналгенерируется из приложения AppEngine / Python.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...