Home‎ > ‎ProgramTool‎ > ‎

Plagger_

http://plagger.org/trac

サイボウズからメンバーリストを取り出す 改訂

このスクリプトで完結するようにしました。

assets/plugins/CustomFeed-Script/cybozuUserList.pl
#!/usr/bin/perl -w
use strict;
use utf8;
use Encode;
use LWP::UserAgent;
use HTML::ResolveLink;
use HTML::TreeBuilder::XPath;
use YAML;

my $email    = 'ytesaki@xxx.co.jp';
my $password = 'password';
my $url  = "http://xxx.co.jp/cgi-bin/cbag/";
my @postHash={
    _System => 'login',
    _Login => '1',
    _Account => $email,
    Password => $password,
    'notimecard' => 1,
};
my $ua = LWP::UserAgent->new();
$ua  ->credentials("xxx.co.jp:80", "area", "xxx", "password");

my $res = $ua->post($url."ag.cgi?page=UserListIndex&GID=0", @postHash);

die "Cannot access Cybozu Office 6 (" . $url . ")."
    unless $res->is_success;
my $resolver = HTML::ResolveLink->new( base => $url );
my $html = decode('shift_jis', $res->content);
my $tree = HTML::TreeBuilder::XPath->new;
$tree->parse($html);
$tree->eof;

my $feed = {
    title => 'サイボウズ ユーザリスト',
    link  => "http://xxx.co.jp/cgi-bin/cbag/ag.cgi?page=UserListIndex&GID=0",
};

my @links = $tree->findnodes(q(//table[@class="dataList"]/tr/td[1]/a));

while (my $node = shift @links) {
    my $link = $node->attr('href');
    my $member_res = $ua->post( URI->new_abs($link,$url)->as_string,@postHash);
    my $member_html = decode('shift_jis', $member_res->content);
    my $member_tree = HTML::TreeBuilder::XPath->new;
    $member_tree->parse($member_html);
    $member_tree->eof;
    my $body = $member_tree->findnodes(q(//table[@class="dataView"]//tr[9]/td[1]/*))->[0];
    push @{$feed->{entry}}, {
        title => $node->as_text,
        link => URI->new_abs($link,$url)->as_string,
        body => $resolver->resolve( $body->as_HTML),
    };
}

binmode STDOUT, ":utf8";
print YAML::Dump $feed;

mixiへのポスト

mixiの外部ブログってたりいよね。
自分のmixiの日記の設定、JotSpotにしてるので気になっていたことは気になっていた。

http://blog.livedoor.jp/lalha/archives/50155360.html
この記事を読んで、「Plaggerでやればいいんじゃないかな。」なぁんて、ブックマークのコメントにも書いてしまったので、とりあえずぐぐってみる。

やっぱり、やってる人はやってるね。
http://ultra.boy.jp/?p=858
http://xcezx.net/blog/development/plagger-plugin-publish-mixidiary-2.html

ということで、使わせていただきます。
ありがとうございました。

なんか、EntryFullTextから後うまくいってない気もするけど、そのあたりはぼちぼちやることにしよう。

社内での利用

インストールの難しさ、モジュールへの依存性などから、業務で使うとしてもお客様への納品物には使えないかと。
ただ、社内で使う分には、色々やってみたいと思っている。

Widget::Simple をいじって使う

今、社内でいろいろバラバラにあるサービスから、フィードを取ってきてまとめたページというのを作っている。
既にあるモノをやめちゃうと言うのは、やっかいな話しだからね。

http://d.hatena.ne.jp/s_nobu/20060819/1155969449

単純に 24時間以内の投稿であれば new マーク付けたかっただけなのだけど、これのまねっこでいけた。

もしかしたら、もっとシンプルな方法もありそうな気がする。

pukiwikiのRSSから更新情報をリストする

あ、pukiwikiのRSS自体、ちょっといじってます。

config.yaml wikiの例

global:
assets_path: /plagger/assets
timezone: Asia/Tokyo
log:
level: debug
plugins:
- module: Subscription::Config
config:
feed:
- url: http://localhost/index.php?cmd=rss&ver=1.0
- module: Filter::Substrttl
config:\\\\
start: 0
length: 25
always: 0
- module: Widget::Simple
config:
widget: new
rule:
module: Fresh
duration: 1440
- module: SmartFeed::All
rule:
module: Limit
limit: 10
config:
title: みんなのwikiメモ
- module: Publish::Planet
rule:
expression: $args->{feed}->id eq 'smartfeed:all'
config:
dir: /htdocs/wiki
theme: minnare_wiki

出力には、planetのテンプレをいじってつかってます。
多分、もうちょっとスマートな方法はあるはずだけど、わかるところでみたいな。

assets/plugins/Publish-Planet/minnare_wiki/template/index.tt

[% USE util = Plagger.Util -%]
<ul class="links mt10">
[% FOREACH entry = entries %]
<li>[% IF entry.widgets %][% FOREACH widget = entry.widgets %]
<span class="new">[[% widget.html(entry) %]] </span>[% END %][% END %]
<a href="[% entry.permalink | html %]">[% entry.title.html %]</a></li>
[% END %]
</ul>

なんでわざわざplanet使っているかというと、最初pythonのplanetでやろうとしていたから。

サイボウズからメンバ一覧と写真を取り出してみる

これは、まだ試しているだけだけど、サイボウズから情報を取り出して、他のサービスで使ってみるためのテスト。
思想的にはSOA? 違うって。

これは、実のところおいらにとっては、大変だった。perlのモジュールどころか、文法さえちゃんと理解してないし。^^;

ちなみにサイボウズ6。
「ユーザー名簿」のページから名前の部分のリンクを取り出し
名前のリンク先の「ユーザー情報の詳細」ページから、写真へのリンクを取り出しplanetに吐き出し。

config.yaml

global:
plugins:
- module: CustomFeed::Script
- module: Subscription::Config
config:
feed:
- script:assets/plugins/CustomFeed-Script/cybozuUserList.pl
- module: Filter::EntryFullText
- module: Bundle::Planet
config:
title: Planet Plagger
description: Everything Plagger from the Web
dir: /planet/
url: http://localhost/planet/
theme: sixapart-std
stylesheet: http://bulknews.typepad.com/blog/styles.css

当たり前だが、サイボウズはRSSなんて吐いてくれない。
更に、サイボウズには、ID,Password認証の上にベーシック認証がかかっている。
というわけで、CustomFeed でメンバ一覧のRSSを生成する。
ちなみに下記のも他のCustomFeedをコピーして適当に書き換えただけなので、useでいらないものがたくさん入っていると思う。
サイボウズの認証に関しては、Cybozu2ical がなければわからなかったとおもう。



HTML::TreeBuilder::XPath がなんかスゴイ。スクレイピングには必須のツールかも。
ただし、構造的にあまりに酷いhtmlだとパースできないけどね。タグの入れ子間違えとか。
Xpathの書き方、読み直しちゃいましたよ。
http://www.infoteria.com/jp/contents/xml-data/REC-xpath-19991116-jpn.htm

assets/plugins/CustomFeed-Script/cybozuUserList.pl

#!/usr/bin/perl -w
use strict;
use utf8;
use WWW::Mechanize;
use LWP::UserAgent;
use DateTime;
use DateTime::Format::W3CDTF;
use Encode;
use LWP::Simple;
use HTML::TreeBuilder::XPath;
use URI;
use YAML;
my $email = 'ytesaki@xxxx.co.jp';
my $password = 'password';
my $url = "http://cb.xxxx.co.jp/xxxx/cb/";
my $ua = LWP::UserAgent->new();
$ua ->credentials("xxx.xxx.co.jp", "auth", "id", "password");
my $res = $ua->post($url."ag.cgi?page=UserListIndex&GID=0", {
_System => 'login',
_Login => '1',
_Account => $email,
Password => $password,
'notimecard' => 1,
});
die "Cannot access Cybozu Office 6 (" . $url . ")."
unless $res->is_success;
my $html = decode('shift_jis', $res->content);
my $tree = HTML::TreeBuilder::XPath->new;
$tree->parse($html);
$tree->eof;
#print $html;
my $feed = {
title => 'サイボウズ ユーザリスト',
link => "http://cb.xxxx.co.jp/xxxxx/cb/ag.cgi?page=UserListIndex&GID=0",
};
my @links = $tree->findnodes(q(//table[@class="dataList"]/tr/td[1]/a));
while (my $node = shift @links) {
my $link = $node->attr('href');
push @{$feed->{entry}}, {
title => $node->as_text,
link => URI->new_abs($link,$url)->as_string,
};
}
binmode STDOUT, ":utf8";
print YAML::Dump $feed;

で、EntryFullTextで、各メンバの画像をとってくるで、いけるとおもったんだけど。
とってこれない…。
そりゃそうなのだが、EntryFullTextでも、ログイン処理させなきゃいけないわけ。
この例では、EntryFullTextに無理くり手をいれて、認証させたのだけど、そのあたりはあまりに酷い(他でEntryFullText使えなくなる)ので、載せない。
本当は、当然そんなことすべきではなくて、先のcybozuUserList.plの中で写真の取り込みまで書いてしまえば済むことだと思う。
単に、EntryFullText使いたかっただけ。

assets/plugins/Filter-EntryFullText/cybozuUserPic.yaml

author: ytesaki
handle: http://xxxx\\\\.co\\\\.jp/cgi-bin/cbag/+.*?
extract: <th align="left" nowrap>写真</th>.*?<td>(.*?)</td></tr>
extract_capture: body

後で気がついたのだが、EntryFullTextでもDomによる取得ができたらしい。
extract_xpath というパラメタで対応しているようだ。

http://wiki.shibuya.pl/?HowToEntryFullText

Plaggerについて

今更すぎだけど。
perlで書かれたプラグイン型のFeedアグリゲータ。
もうちょっとわかりやすく言うと、情報 を収集・加工し任意の形で出力できるソフトウェア、及びフレームワーク。作成者は、Six Apartの宮川 達彦 さん。業界的には相当有名な方です。
今は、VOXというBlog+SNSみたいなサービス開発に携わっているそうです。

使い方の例

  • mixiやfrepa等のSNSを自動巡回して最新日記を取得し、Gmailへ
  • YouTubeから動画を落として、iPodに転送
  • BlogやWebサイトの自動更新
  • ブックマークへの自動登録

色物

  • Googleで検索するとピザが届く
  • 新着情報がくるとパソコンのトレイを開けて知らせる

魅力

  • なんでもできる。(嘘)「それPla」ってことばがはやりました。
    • 無限のソースと、様々なフィルタリング、あらゆる出力フォーマット
  • 豊富なplugin、面白い事例群
  • RSSなどのFeedの利用についての、今後の可能性を見せてくれている
  • Pluginでいろんな機能をつなぎ合わせるという思想
  • 手段のためには目的を選ばないみたいな馬鹿馬鹿しさ

困難

  • まず、インストールが難しい。あまりに多くのCPANモジュールに依存しているためである。ただ、最近では簡単にインストール出来るパッケージもあるらしい。
  • ドキュメントは基本英語。まぁ、日本語の情報が欲しかったらBlogまわりとか検索するしか。
  • プログラムがまったくできないと、わからないので面白くない

Comments