パスワードを忘れた? アカウント作成
788344 journal
Ruby

d3pの日記: 日記のRSS

日記 by d3p

/.Jの日記のRSS(http://srad.jp/journals/rss)が前と大分変わってしまい、
ログインしないと実質使えないみたいやら、
content:encodedがなくなってるやら、
前みたいにタイトルにユーザ名入れて欲しいやらで、
http://srad.jp/journalをパースしてAtomにして返すrubyスクリプト組んでみました。
単にNokogiri使ってみたかったのもありますが。
最初はRSS返すように作っていたのですが、rubyのライブラリでCDATAがうまく返せなかったので断念…

一応キャッシュ作って負荷軽減。ツッコミ歓迎。NYSLで。

動いているもの→http://d3p.orz.hm/slashdot-j-journal.atom

↓ソース↓

#!/usr/bin/env ruby
 
# -*- coding: utf-8 -*-
 
require "rubygems"
require "nokogiri"
require "open-uri"
 
url = "http://srad.jp/journals"
atomfile = "./journals.atom"
atomxml = ""
 
class Journal
  attr_reader :title, :author, :description, :content, :url, :datetime
  def initialize(doc)
    #Nokogiriでパースしたデータを格納
    @title = doc.search("h2")[0].search("a")[1].content
    @author = doc.search("div.details")[0].search("a")[0].content
    @description = doc.search("div.p")[0].search("p").map{|c|c.content}.join()
    @content = doc.search("div.p")[0].to_html
    @url = doc.search("h2")[0].search("a")[1].attr("href")
    @datetime = parse_date(doc.search("time")[0].attr("datetime"))
  end
  def parse_date(str)
    /(\d+)年(\d+)月(\d+)日.*?(\d+)時(\d+)分/ =~ str
    return Time.local($1.to_i, $2.to_i, $3.to_i, $4.to_i, $5.to_i)
  end
end
 
#ローカルのatomファイル読みに行く関数
def atom_from_local(af)
  f = File.open(af, "r")
  f.flock(File::LOCK_EX)
  atomxml = f.read
  f.flock(File::LOCK_UN)
  f.close()
  return atomxml
end
 
#前回の更新から1分経過していないときはローカルのAtomを返す
if (FileTest.exist?(atomfile)&&(Time.now - File.open(atomfile).mtime < 60))
  atomxml = atom_from_local(atomfile)
else
  f = File.open(atomfile, "w")
  #誰かがファイルロックしてるときは更新を待ってローカルのAtomを返す
  if !(f.flock(File::LOCK_EX || File::LOCK_NB))
    atomxml = atom_from_local(atomfile)
  else
    doc = Nokogiri::HTML(open(url))
    articles = doc.search("article")
 
    atom = Nokogiri::XML::Builder.new(:encoding => 'UTF-8') do |xml|
      xml.feed("xmlns" => "http://www.w3.org/2005/Atom") do |feed|
        feed.title "Slashdot Japan Journal Atom"
        feed.subtitle "/.J みんなの日記のAtom"
        feed.link(:href => url)
        feed.author do |author|
          author.name "Slashdot Japan Journal Atom Script"
        end
        feed.updated Time.now.xmlschema
        articles.each do |article|
          if (article.attr("data-fhtype") == "journal")
            j = Journal.new(article)
            feed.entry do |entry|
 
              entry.link(:href => j.url)
              entry.title "[#{j.author}] #{j.title}"
              entry.summary j.description
              entry.author do |author|
                author.name j.author
              end
              entry.published j.datetime.xmlschema
              entry.updated j.datetime.xmlschema
              entry.content(:type => "html").text j.content + "<a href='#{j.url}'>本文を読む</a>"
            end
          end
        end
      end
    end
    atomxml = atom.to_xml
    f.write(atomxml)
    f.flock(File::LOCK_UN)
    f.close()
  end
end
 
#出力
puts "Content-type: text/xml\n\n"
puts atomxml

この議論は賞味期限が切れたので、アーカイブ化されています。 新たにコメントを付けることはできません。
typodupeerror

計算機科学者とは、壊れていないものを修理する人々のことである

読み込み中...