2010-11-29 13:38 墳墓 (Brian Hsu)
上面一樣,將微網誌上的訊息匯整成一個網頁,方便尋找。
雖然網路上已經有許多現成的噗浪備份工具,但不知道為什麼,我就是沒辦法成功備份我所有的噗文……所以,那就自己寫一個吧!
這個備份工具是用昨天發佈的 SPlurk 寫成的,與其他的備份工具相比,非常陽春,甚至可以說是沒有任何功能,但他至少可以完全備份完我河道上的噗文就是了。
使用說明
- 下載 PlurkBackup.zip
- 安裝 Java Runtime
- 解壓縮 PlurkBackup.zip
- 執行 run.bat,接著會看到像右邊一樣的視窗
- 輸入帳號密碼就會開始備份,備份完以後會出現 allBackups.html 和 myPlurks.html 兩個檔案,分別是河道上全部的噗和只有自己的噗
程式碼說明
以下就是這次噗浪備份工具的程式碼,總共只有 96 行。:)
重點說明如下:
- 66 行定義的 fetchPlurks 遞迴取得所有的噗--如果這次取回來的噗文列表不是空的,就繼續從最後一則噗文的時間點再往後抓舊的噗文,直到沒有噗文為止。
- 在 83 行的時候用上述的函式,並將時間設定成執行程式的時間--那他就會從最新的噗抓到最舊的噗,也就是說,會抓回來使用者河道上所有的噗文(包括自己和其他人的)
- 86 行會將 83 行抓回來的噗依時間先後排序。
- 89 行會將 83 行抓回來的噗依時間先後排序,並過慮出使用者自己的噗(噗文的 ownerID = 登入使用者的 userID)
- 用 50 行定義的 outputHTMLFile 輸出成 HTML 檔案
- 先輸出 HTML 和表格標頭
- 將傳入的 List 裡每一則噗文都用 convertToHTML 函式轉成 HTML 格式後輸出
- 輸出表格和 HTML 結束標籤
- 收工回家
package org.bone.plurkbackup
import org.bone.splurk._
import org.bone.splurk.constant._
import org.bone.splurk.model._
import java.util.Date
import java.text.SimpleDateFormat
object Main
{
val apiKey = "wQsqUmmcp69aCblemZ34pM5wywnlAyS9"
val plurkClient = new PlurkClient(apiKey)
val dateFormatter = new SimpleDateFormat ("yyyy-MM-dd")
val timeFormatter = new SimpleDateFormat ("hh:mm:ss")
var allUsers: Map[Long, PlurkUser] = Map()
lazy val username = {
print ("Enter your Plurk username:")
Console.readLine()
}
lazy val password = {
print ("Enter your Plurk password:")
Console.readLine()
}
// 將噗文轉成 HTML 格式
def convertToHTML (plurk: Plurk) = {
val userInfo = allUsers(plurk.ownerID)
val dateWithLink = <a href={plurk.plurkURL}>{dateFormatter.format(plurk.posted)}</a>
val time = timeFormatter.format(plurk.posted)
val userURL = "http://plurk.com/" + userInfo.nickName
val username = userInfo.displayName.getOrElse(userInfo.fullName.getOrElse(userInfo.nickName))
val userLink = <a href={userURL}>{username}</a>
val qualifier = plurk.qualifierTranslated.getOrElse(plurk.qualifier.text)
val content = plurk.content;
"""
|<tr>
| <td>%s</td>
| <td>%s</td>
| <td>%s</td>
| <td>%s</td>
| <td>%s</td>
|</tr>
""".stripMargin.format(dateWithLink, time, userLink, qualifier, content)
}
// 輸出成檔案
def outputHTMLFile (filename: String, plurks: List[Plurk])
{
import java.io._
val printWriter = new PrintWriter(new File(filename), "utf-8")
printWriter.println("<html>")
printWriter.println("<body>")
printWriter.println("<table border=\"1\" cellpadding=\"3\">")
printWriter.println(plurks.map(convertToHTML).mkString)
printWriter.println("</table>")
printWriter.println("</body>")
printWriter.println("</html>")
printWriter.close()
}
// 遞迴取得河道上所有的噗文
def fetchPlurks (dateBound: Date, filter: Option[PlurkFilter.PlurkFilter] = None): List[Plurk] = {
val (users, plurks) = plurkClient.Timeline.getPlurks (limit = 30,
olderThan = Some(dateBound),
filter = filter)
allUsers = allUsers ++ users
plurks match {
case Nil => Nil
case xs: List[_] =>
println ("Chunk:" + xs.length)
xs.foreach {x => println ("Processing plurkID %d..." format(x.plurkID)) }
fetchPlurks(xs.last.posted, filter) ++ xs
}
}
def main (args: Array[String]) {
val profile = plurkClient.Users.login (username, password)
val allPlurks = fetchPlurks (new Date)
// 河道上所有的噗
val allPlurksBackup = allPlurks.sortWith(_.posted.getTime > _.posted.getTime)
// 只有自己的噗
val myPlurksBackup = allPlurks.sortWith(_.posted.getTime > _.posted.getTime).
filter(_.ownerID == profile.userInfo.userID)
// 備份啦
outputHTMLFile ("allPlurks.html", allPlurksBackup)
outputHTMLFile ("myPlurks.html", myPlurksBackup)
}
}

回響