Doge log

Abby CTO 雑賀 力王のオフィシャルサイトです

Twistedで作るローカルYoutubeサーバ その2

今度は見る側。Web部分を実装する。
flvplayerは適当に見つけたJW FLV PLAYER 3.9を使う。
Web側の実装は大体

  1. staticファイルの参照
  2. 一覧ページの作成
  3. 詳細ページの作成

ぐらい。

staticファイルの参照

Twistedで書かれたWebサーバにはデフォルトでstaticファイルの参照用の関数がある。
twisted.webはぼろいはずのでnevowの方のstaticモジュールを使う事をおすすめする。
(renderってDefferになってなくてブロックになるのだっけ?)

server.tac
from twisted.application import service, strports
from nevow import static
from nevow import appserver

page = web.ListPage()
page.putChild('flvplayer.swf', static.File('./flvplayer.swf'))
page.putChild('video', static.File(setting.repo))

site = appserver.NevowSite(page)
strports.service("8081", site).setServiceParent(application)

一番親に当たるのがListPage(後述)でputChildでそれ以降にパスを設定する。
static.Fileは指定したパスをResource化してくれる。
この例では

  1. http://localhost:8081/はListPageの内容
  2. http://localhost:8081/flvplayer.swfはserver.tacと同Dirにあるflvplayer.swf
  3. http://localhost:8081/videoはsetting.pyで指定したvideoの保存先Dir

もちろんIndex出さなくしたりもできるけどローカルなので最小構成で。

一覧ページの作成、詳細ページの作成

せっかくなのでnevowを使いまくろう。ということでPageを使う。

from nevow import rend
from nevow import loaders
from nevow import accessors
from nevow import inevow
from twisted.python import util
from twisted.python.components import registerAdapter

items = []

class VideoItem(object):
    pass

class ListPage(rend.Page):

    docFactory=loaders.xmlfile(util.sibpath(__file__, 'list.html'))
    
    def childFactory(self, ctx, segments):
        return DetailPage(segments)

    def data_list(self, ctx, data):
        return items

class DetailPage(rend.Page):
    addSlash = True
    docFactory=loaders.xmlfile(util.sibpath(__file__, 'detail.html'))
    
    def __init__(self, id):
        self.id = id

    def data_id(self, ctx, data):
        return '/flvplayer.swf?file=/video/%s.flv' % self.id

registerAdapter(accessors.ObjectContainer, VideoItem, inevow.IContainer)

ListPageは一覧、DetailPageは再生するページ。
docFactoryで対応するテンプレートを指定する。
テンプレートにはXHTML、stan、バギーなHTMLが指定できるけど今回はまじめにXHTMLを使う。
ハッカーはstanを使うといいと思う。変態的だし。
ListPageは上記のtacにも出て来たけど一番URLの親に割り当てている。
その子としてDetailPageがいる。
Twistedは割と子クラスをガンガン足してそれにURLもついていくパターン(積み上げ式)でURLを構築するケースが多いんじゃないか。
(それがいやでresolverを作ったんだけど)
childFactoryは自ページの一階層次のURLにきたときに呼ばれる。
この例ではhttp://localhost:8081/<☆>/の☆の部分をDetailPageに渡している。
htmlを見ないとわかりづらいけど☆の部分にはvideoidを渡す仕様になっていてDetailPageで実際に再生する際のvideoidをレンダリングする。
VideoItemはvideoを表すクラス。itemsには現在保持している(再生可能な)VideoItemが入っているイメージ。
ListPageはこのitemを返しているだけ。
registerAdapterを使っている理由はレンダリングする際に独自Objectを使用するため。
registerしてないとレンダリング時にうまく呼び出せない。
ながいのでこの辺で。
次はテンプレート部、XHTMLレンダリング部分。
うくく。