2012年3月5日 星期一

multi-feeds : 手工自製 rss 過濾混搭器

ckhung-feed.php 的輸出就是一個 rss feed 上一帖 提到: 用 feedrinse/filtermyrss/blastfeed/feedsifter 之類的 rss 過濾器, 再搭配 rssmixer/feedblendr/feedtwister/blogsieve 之類的 rss 混搭器, 可以從許多個 rss feeds 混搭出自創的客製化 rss feed。 但手工自製終究還是比別人提供的服務彈性更大。 例如 feedrinse 只提供一層的 and 或 or 過濾條件; 如果可以自己寫一小段簡單的 php 程式碼, 隨便你要用什麼 and/or/not 隨便你要疊幾層的邏輯組合, 或甚至用 regexp, 都很自由。 我寫的 multi-feeds 是一個小小的 php 程式, 你可以用 php 陣列的語法簡單描述你的 feeds 的來源、 並且用上述的一小段 php 程式碼當做篩選條件, 然後它就幫你產生一個 「過濾-混搭」 之後的新的 rss。 所有動作都可以自主定義, 不需要假手別人的網站; 也沒有個數的限制。

首先, 你需要一個可以上傳自己寫的 php 檔的網頁空間。 (或者可以在自己的 linux 電腦上安裝 libapache2-mod-php5) 其次, 下載 multi-feeds.tgz 裡面包含下列檔案:

  1. i/simplepie.inc: 讀取 rss 的函式庫
  2. i/FeedWriter.inc: 產生 rss 的函式庫; 被我小改過
  3. i/FeedItem.inc: 被 FeedWriter.inc 用到的小函式庫
  4. i/multi-feeds.inc: 我寫的小函式庫, 分析你的 php 陣列, 呼叫上面的函式庫, 過濾混搭出你要的結果。
  5. z/cit-jou.php: 輸出 HTML 的範例: 公民新聞混搭
  6. z/readings.php: 輸出 HTML 的範例: 我的閱讀清單
  7. z/feed-mixer.php: 這個有點複雜, php 生手勿近。 用同一個 php 檔, 根據不同的參數產生不同的 RSS2 feeds

我把包含檔跟範例檔拆開放在兩個不同的目錄; 你可以把他們放在一起。 先別管範例檔; 請先從下面簡單的程式開始, 把它剪貼到一個新的 php 檔, 例如叫做 ckhung-feed.php, 跟包含檔放在同一個目錄下。 從瀏覽器透過你的 apache (也就是說, 打網址 http://localhost/.../ckhung-feed.php 而不是用 「檔案」 「開啟」) 查看是否出現一個 rss feed 如右上圖, 內容是一些 [來自貴哥的噗浪及部落格] 混搭出來的訊息。

<?php

require_once('multi-feeds.inc');

$new_feed = array(
    'title' => '資訊人權貴的部落格和噗浪',
    'author' => '洪朝貴',
    'max_items' => 20,
    // 'output_format' => 'RSS2',
    'sources' => array(
        array(
            'id' => 'ㄓ疑',
            'url' => 'http://ckhung0.blogspot.com/feeds/posts/default',
        ),
        array(
            'id' => '玩具',
            'url' => 'http://newtoypia.blogspot.com/feeds/posts/default',
            'filter' => function ($description) { return ""; }
        ),
        array(
            'id' => '噗浪',
            'url' => 'http://www.plurk.com/ckhung0.xml',
            'filter' => function ($description) {
                if (preg_match("/#隱私|#SOPA|#著作權|#言論自由|#蘋果|#微軟/i", $description))
                    return $description;
            }
        ),
    ),
);

multi_feeds($new_feed);

?>

很簡單吧? 你的 php 檔只需要做三件事:

  1. 用 include 或 require 之類的句子納入 multi-feeds.inc 這個函式庫
  2. 用一個陣列定義你的 feed
  3. 呼叫 multi-feeds

來源定義當中, 最重要的幾個欄位是:

  1. title : 要顯示什麼標題?
  2. max_items : 每個來源最多抓幾則新聞? 注意: 經過過濾後, 每個來源真正顯示出來的筆數可能不到這個數字; 但若你有數個來源, 那麼經過合併之後, 可能還是會達到這個數字。
  3. output_format : 最終輸出格式。 可以是 RSS1, RSS2, ATOM 或 HTML。 預設是 RSS2。 若你想將抓來的新聞嵌在網頁裡, 像 我的首頁 這樣, 那就用 HTML。 (我修改 FeedWriter.inc 的部分主要就是加上這個格式)

當然, 最最重要的就是 sources, 指定新聞來源。 它不過就是一個陣列, 每個元素定義一個來源。 像這裡我定義了三個來源:

  1. 意見部落格 「資訊人權貴ㄓ疑」, 混搭時顯示的簡寫代號是 「ㄓ疑」; 每一則都完整顯示。
  2. 技術和雜記部落格 「玩具烏托邦」, 混搭時顯示的簡寫代號是 「玩具」; 每一則都顯示, 但只顯示標題。 (filter 欄位所指定的匿名過濾函數傳回空字串, 代表要顯示標題, 不要顯示內容。)
  3. 噗浪, 混搭時顯示的簡寫代號是 「噗浪」; 只顯示內文含有 「#隱私、 #SOPA、 #著作權、 #言論自由、 #蘋果、 #微軟」 其中任何一個字串的噗; 其餘通通略過。 (遇到這些噗, 就傳回整則噗文; 遇到其他噗就不傳回任何值, 代表略過。) 那個井字號是我在摹仿 twitter 的 hashtag 啦... 除了這裡自寫的過濾函數之外, 應該沒有別的軟體會對它有任何反應。 (聳肩)

修改成你自己的 rss 測試成功之後, 接下來是建立快取 (cache)。 這年代免費還不夠, 反應要快才留得住訪客; 造訪你的 rss 的讀者如果等太久, 應該會調頭就走吧。 先建立一個 cache 目錄, 例如 ~/php-cache 並且開放所有權限: chmod 777 ~/php-cache (很危險的設定, 所以請不要把它和你自己的其他目錄混用!) 然後進入 multi-feeds.php 找到 "Please remove" 那一段註解。 把 global $top; 那一句拿掉, 並且把下面設定 cache 路徑那一句 $cache_location = ... 改成你自己的設定 -- 檔案系統的路徑, 例如 /home/ckhung/php-cache 而不是瀏覽器所看到的路徑。 改完之後重新整理, 第一次應該還是有點慢; 但若修改正確, 第二次重新整理就變得快多了。 cache 內暫存的資料預設經過一小時 (3600 秒) 後會過時, 也就是說, 每一小時大概只會有一位訪客等很久。 (謎之音: 那如果我的 rss 每小時流量不及一人...)

範例程式當中的 z/feed-mixer.php 更進一步一口氣定義了多個混搭, 主要是因為我用噗浪當做課程公告的工具, 但是又把所有不相關的班級公告都混在一起, 這樣對學生不太友善。 為了怕學生嫌煩, 不只退訂我的噗浪還退選我的課 (謎之音: 科技英文是必修耶), 於是就採用這個方式分流: 給不同的參數, 就只得到該班相關的公告。 不過裡面的路徑及額外載入的檔案可能不適合你的系統, 需要小修改一下才能用。

沒有留言:

張貼留言