twisted04

ガジェットの仕様の URL が見つかりませんでした

#!/usr/bin/python
# -*- coding: sjis -*-
# 複数のサイトからRSSを取得して一つのRSSにして再配信するための
# Twistedのサンプルアプリケーションです。


# 必要なモジュールをインポートする
from twisted.internet import reactor
from twisted.application.internet import TimerService
from twisted.web.client import getPage
from twisted.web import server, resource

import feedparser
from sqlobject import *


# RSSのフィード元を保存するためのRDBMSのテーブル
class Feed(SQLObject):
title = StringCol(notNone=True)
link = StringCol(notNone=True, unique=True)
entries = RelatedJoin("Entry")


# RSSの各エントリを保存するためのRDBMSのテーブル
class Entry(SQLObject):
title = StringCol(notNone=True)
href = StringCol(notNone=True, unique = True)
description = StringCol()
feeds = RelatedJoin("Feed")


# RSSのフィード元のテーブルを更新するための関数
def updateChannel(title, url):
feeds = Feed.select(Feed.q.link == url)
if not feeds.count():
feed = Feed(title=title, link=url)
else:
feed = feeds[0]
return feed

# RSSの各エントリを保存するための関数
def updateEntry(entry, channel):
entries = Entry.select(Entry.q.href == entry.link)
if not entries.count():
e = Entry(title = entry.title.encode("utf8"),
href = entry.link.encode("utf8"),
description = entry.setdefault("summary", "").encode("utf8"))
channel.addEntry(e)

# Twisted.web.clientのgetPageでページを取得したときに
# 処理されるコールバック関数
# この関数の中でRDBMSのFeedテーブルとEntryテーブルを更新します
def gotPage(content):
rss = feedparser.parse(content)
channel = updateChannel(rss.feed.title.encode("utf8"),
rss.feed.link.encode("utf8"))
for entry in rss.entries:
updateEntry(entry, channel)

# 各サイトから一度にRSSを取得します。
# リクエストは非同期に処理されます
def update(urls):
for url in urls:
if url:
getPage(url).addCallback(gotPage)

# RSSを再配信するためのサーバのサイトクラス
class RssFeeder(resource.Resource):
isLeaf = True

# HTTPのGETのリクエストはこの関数が処理します。
# ここでは、RSSファイルを作成して、そのファイルを返しています。
def render_GET(self, request):
entries = Entry.select(orderBy="-id")
content = []
content.append('')
content.append('')
content.append('OreOre Plannet')
host = request.getHost()
content.append('http://%s:%d/' %(host.host, host.port))
for entry in entries:
content.append('')
content.append('' + entry.title + '')
content.append('' + entry.href + '')
content.append('')
content.append('')
content.append('')
request.setHeader("Content-Type", "text/xml")
return "\r\n".join(content)


def main():
# アプリケーションの初期化を行います。

# URLのリストをplannet-url.txtから読み込んで
# リストに保存しています。
filename = "plannet-url.txt"
urls = open(filename).read().split("\n")

# RDBMSを初期化します。
# sqliteのデータベースをメモリ上に作成して、
# 必要なテーブルを作成します。
sqlhub.processConnection = connectionForURI('sqlite:/:memory:')
Entry.createTable()
Feed.createTable()

# HTTPサーバを初期化します。
# HTTPのリクエストを処理するためのオブジェクトを作成して、
# ポート番号1234でリクエストを待ちます。
site = server.Site(RssFeeder())
reactor.listenTCP(1234, site)

# タイマーを作成して、30分ごとにupdate関数をコールします。
# タイマーはreactorが動いてから1秒後に開始されます。
timer = TimerService(60*30, update, urls)
reactor.callLater(1, timer.startService)

# メインイベントループ
reactor.run()


if __name__ == "__main__":
main()
Comments