« Plagger + Catalyst = Plalyst or PlaCata ? メソッド | メイン | 思いついた、CDTubeをよりそれっぽくする方法 »

CDTubeの作り方

CDTubeの作り方をソースつきで追ってみる。まずはPlaggerのconfig.yaml

global:
  assets_path: /path/to/assets
  timezone: Asia/Tokyo

plugins:

  - module: Subscription::Config
    config:
      feed:
         - url: http://www.tbs.co.jp/cdtv/cddb/thisweek-j.html

  - module: CustomFeed::Config
  
  - module: Filter::CountdownTube
    config:
      locale: jp
      associate_id: xxxxxxxxxx-22
      developer_token: XXXXXXXXXX

  - module: Filter::ForcePermalink

  - module: Publish::Feed
    config:
      format: RSS
      dir: ../root
      filename: index.xml

  - module: Publish::JavaScript
    config:
      dir: ../root
      filename: index.js
      
  - module: Store::DBIC
    config:
      schema_class: Plagger::Schema::SQLite
      connect_info: [ 'dbi:SQLite:/path/to/plagger.db', ]

CustomFeed::Configのassets内のyaml。authorにアーティスト名、ランキングの順位を無理やりrateプロパティに入れている

match: http://www¥.tbs¥.co¥.jp/cdtv/cddb/thisweek-j¥.html
extract: <td class="t1" align="right">(.*?)¥.</td>.*?songdb/song.*?">(.*?)</a>.*?artistdb/artist.*?">(.*?)</a>
extract_capture: rank track artist
extract_after_hook: |
  $data->{title} = $data->{track};
  $data->{author} = $data->{artist};
  $data->{rate} = $data->{rank};

Filter::CountdownTubeはこんな感じ。titleとauthorを元にAmazonとYouTubeに検索をかけている。mizzyさんが作ったPluginを参考にさせていただきました。後ほどCatalystで使うためにbodyにYouTubeのビデオIDを入れる。

package Plagger::Plugin::Filter::CountdownTube;

use strict;
use base qw( Plagger::Plugin );
use Net::Amazon;
use Net::Amazon::Request::Keyword;
use Encode;
use HTML::Entities;

sub register {
    my($self, $context) = @_;
    $context->register_hook(
        $self,
        'update.entry.fixup' => ¥&filter,
    );
}

sub filter {
    my($self, $context, $args) = @_;
    my $e = $args->{entry};

    my $attr;
    $attr->{token}  = $self->conf->{developer_token};
    $attr->{locale} = $self->conf->{locale};
    $attr->{affiliate_id} = $self->conf->{associate_id};

    my $keywords = $e->title . " " . $e->author;

        decode_entities($keywords);

    $context->log( info => "Searching $keywords on Amazon...");
    my $item = search_aws($attr, $keywords, "music-jp");
        my $video_id = search_youtube($self,$context,$keywords);
        if($video_id eq ''){
                $video_id = search_youtube($self,$context,decode_entities($e->title));
        }
        
    if($item){
        $e->link($item->url);
        $e->icon({ url => $item->ImageUrlSmall });
        $e->summary($item->ProductDescription);
                $e->body($video_id);
    }
}

sub search_aws {
    my($attr, $keywords, $mode) = @_;

    my $ua = Net::Amazon->new(%$attr);

    $keywords = encode("UTF-8", "$keywords");
    my $req = Net::Amazon::Request::Keyword->new(
        keyword => $keywords,
        mode    => $mode,
    );

    my $response = $ua->request($req);
    my $item = ($response->properties())[0];
    return $item;
}

sub search_youtube{
        my ($self,$context,$query) = @_;
    my $url  = URI->new('http://youtube.com/results');
    my $file = $self->cache->path_to('youtube_search_result.html');

    $query = encode('UTF-8', $query) unless $context->conf->{no_decode_utf8};
    $context->log( info => 'Getting YouTube search results for ' . $query );

    my $ua = Plagger::UserAgent->new;
        $url->query_form(
                                         search_type     => 'search_videos',
                                         search_query    => $query,
                                 );
        
        my $res = $ua->mirror( $url->as_string => $file );
        if($res->is_error){
                $context->log( error => $res->status );
                return;
        }
        
        open my $fh, "<:encoding(utf-8)", $file
            or return $context->log(error => "$file: $!");

        my $video_id;
        while (<$fh>) {
                m!<a href="/watch¥?v=(.*?)"!
                        and do{
                                $video_id = $1;
                                $context->log(info => "$video_id get!");
                                last;
                        };
        };
        return $video_id;
}

1;

フィードの準備ができたので、Catalystのアプリを実装。PlaggerからStore-DBICされたSQLiteのdbがモデルになる。DBIC::Schemeのヘルパースクリプトを使ってクラスを自動生成。

$ ./script/cdtube_create.pl model Plagger DBIC::Schema CDTube::Model::Schema create=static dbi:SQLite:/path/to/plagger.db

次にコントローラーの実装。必要に応じてモデルにもメソッドを追加する。コントローラーはRoot.pmのみで済ませた。DBIC::Scheme、初めて使ったけどいい感じです。諸事情のため、reseltsetのpagerは使ってない。

package CDTube::Controller::Root;

use strict;
use warnings;
use base 'Catalyst::Controller';
use Data::Dumper;

__PACKAGE__->config->{namespace} = '';

sub default : Private {
    my ( $self, $c ) = @_;
        my $of = $c->request->arguments->[0] || 1;
        if($of > 100){$of = 1};
        $c->log->debug("of is $of");
        my @entries;
        my $it = $c->model('Plagger::Entry')->search(
                                                                                                {},
                                                                                                    { order_by => 'cast(rate AS INTEGER) ASC',
                                                                                             });
        while(my $e = $it->next ){
                if($e->rate > ($of - 1)){
                        if($e->rate < ( $of + 10)){
                                push(@entries,$e);
                        }
                }
        }
        my @feed = $c->model('Plagger::Feed')->all;
        my $week = $feed[0]->week;

        $c->stash->{week} = $week;
        $c->stash->{of} = $of;
        $c->stash->{entries} = ¥@entries;
        $c->stash->{template} = 'index.tt';
}

sub end : ActionClass('RenderView') {}

1;

後はビューの実装。$entry->bodyでYouTubeのビデオIDがとれるのでそのままembedのタグに入れ込む。 ページング処理がちょっと複雑になったけど、わりとあっさりとできた。と、一通り完成したら、細かい修正加えて、HTMLをMT風にしてスタイルを適用。あとはmod_perlで動くことを確認して、できあがりです。

トラックバック

このエントリーのトラックバックURL:
http://yusukebe.com/mt/mt-tb.cgi/2047

この一覧は、次のエントリーを参照しています: CDTubeの作り方:

» PlaggerとCatalystでCDTVならぬCDTube作ってみた 送信元 ゆーすけべー日記
Plaggerでエロサイトばかり作っていてもなんなんで、某すがちゃんに「Plagger使ったなんか面白いアイデアない?」と聞いた。 某すがちゃん... [詳しくはこちら]

» コンテンツ入りhtml自動生成 送信元 インターネット 情報局
★コンテンツ入りhtml自動生成、アップロードからリンク貼り作業まで完全自動、... [詳しくはこちら]

コメントを投稿

(いままで、ここでコメントしたことがないときは、コメントを表示する前にこのブログのオーナーの承認が必要になることがあります。承認されるまではコメントは表示されません。そのときはしばらく待ってください。)


ブログSEO対策:track word seo