趣味と実益と現実逃避で更新されるblogです.
役に立つことから無意味なことまでさまざま書いていきます.
|
June 14th, 2007 |
OPML2Twitterをつくってみた(Read: 30707) |
参照: |
先日plnetにknockingまとめをつくったんですが,折角なので二次利用しよう!!ってことでベタですけどTwitterに放り込んでみた. |
![]() Twitter posted by (C)ELF 上鍵 いまさら感なものですが,昨晩少しと昼休みにざっとつくってみました. まずplnet.最近で言うとaboutmeっぽいやつですけどずいぶん前からあります. ようするに自分のいろんなCGM系コンテンツがある人がそれらのRSSなどのフィードを用いて1箇所にまとめちゃいなYO!!ってサービスです. インターフェースもこなれていて使い勝手は悪くないです.ぜひ一度お試しください. ![]() plnet.jp posted by (C)ELF 上鍵 ![]() plnet.jp posted by (C)ELF 上鍵 ただ外部フィードの追加をする際には実際のフィードのURLを指定するようにしましょう. plnetはフィードのautodiscoveryが有効ですが,OPML出力の際にxmlUrlがフィードではなく,フォームで入力したURLになってしまうようです. 今回はここで結構はまりました.調査に協力してくださったkomagataさんthx. で,処理の流れは下記のような手順で書きました. - OPMLを取得する - simplexmlで解析し,フィードURL群を束ねる - XML_Feed_Parserでエントリ群の題名,URL,日付を取得する - エントリをTwitterに送る,とりあえず複数エントリある場合の送信は2分間隔でおこなう. 今回ちょっとしたテクニック? ですが,手抜きをしたくてCLIながらセッションを使ってみました(昔からやってみたかった). 知ってました? session_start()ってCLIでも使えるんですよ. うまく使うとスケジューリングでバッチ処理を行うときに継続処理っぽいことができるようになります. 今回は「過去に送ったフィードは送信しない」」というあたりにセッションを使いました. 昼休みに適当に書いたので処理は雑多ですが,Services_TwitterとXML_Feed_Parserの手抜きな使い方サンプルにはなるかもしれません. 興味がある人はどんどん改造するなり捨てるなりしてくださいね. ちなみにこのサンプルを動かすにはいくつかのPEARパッケージが必要になります.下記を参考に必要なパッケージをインストールしておいてください. ・Services_Twitter ・PEAR :: Package :: XML_Feed_Parser $ pear channel-discover pear.hawklab.jp $ pear install --alldeps -f http://labs.transrain.net/files/Services_Twitter-0.3.0.tgz $ pear install --alldeps XML_Feed_Parser <?php require_once "Services/Twitter.php"; require_once 'HTTP/Request.php'; require_once 'XML/Feed/Parser.php'; define('NOW', time()); define('USERNAME', 'xxx'); define('PASSWORD', 'xxx'); define('SESSION_ID', 'xxx'); define('REPOST_WAIT', 120); function getUrlContent($url) { $result = null; $req = &new HTTP_Request($url); if (!PEAR::isError($req->sendRequest())) { $result = $req->getResponseBody(); } return $result; } if (php_sapi_name() == 'cli') { ini_set('session.gc_maxlifetime', 2592000); session_save_path(dirname(__FILE__)); session_id(SESSION_ID); } else { // cronで動かすつもりなのでCLI以外では動作させない(面倒なので) header('Content-Type: text/plain; charset=UTF-8'); echo 'Can not executable.'; exit; } mb_language('Japanese'); mb_internal_encoding('UTF-8'); session_start(); $previousTime = $_SESSION['previousTime']; $expireTime = strtotime('-60 days'); $newFeed = array(); $st =& new Services_Twitter(USERNAME, PASSWORD); $st->setAppName('OPML Notifier'); $st->setAppVersion('0.1.0'); $webUrls = array(); $feed_contentsUrls = array(); $newEntries = array(); echo "Fetch OPML:\n"; $opml = getUrlContent('http://plnet.jp/knocking/opml'); $xml = simplexml_load_string($opml); foreach ($xml->body->outline as $item) { foreach ( $item->attributes() as $name=>$value) { if ($name == 'xmlUrl') { $feed_contentsUrls[] = $value; } } } foreach ($feed_contentsUrls as $name=>$url) { echo "Fetch Feed: $url\n"; $feed_contents = getUrlContent($url); try { $feed_obj = new XML_Feed_Parser($feed_contents); foreach ($feed_obj as $entry) { $time = $entry->pubDate == 0? $entry->date: $entry->pubDate; if ($expireTime < $time && isset($_SESSION['pushed'][$entry->link]) != true) { $newEntries[$time][] = $entry; } } } catch (XML_Feed_Parser_Exception $e) { die('フィードが無効です: ' . $e->getMessage()); // @FIXME: ちゃんと終了処理をしよう exit; } } ksort($newEntries); foreach ($newEntries as $time=>$entries) { foreach ($entries as $index=>$entry) { $short_title = mb_strimwidth($entry->title, 0, 30, '...'); $st->setUpdate("New entry: $short_title {$entry->link}"); printf("%s | %02d | %-40s | %s\n", strftime('%Y-%m-%d %H:%M:%S', $time), $index, $short_title, $entry->link); $_SESSION['pushed'][$entry->link] = NOW; sleep(REPOST_WAIT); } } ?> |
ELF Jun 14th, 2007 02:09 / [ 編集 ]
[ コメントする ] [ トラックバック(1) ] [ ] |
トピックの参照元
| ▼最近のトピック
| ▼ 人気のトピック |
[ POST ] [ AddLink ] [ CtlPanel ]
<< | 1月 | >> | ||||
日 | 月 | 火 | 水 | 木 | 金 | 土 |
* | * | * | * | * | 1 | 2 |
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 | * | * | * | * | * | * |