root/platform/tdiary/plugin/hb_footer4sec.rb

Revision 5137, 6.3 kB (checked in by drry, 11 months ago)

platform/tdiary/doc/ja/comment_key.ja.html
platform/tdiary/util/tdiary-vim/ChangeLog
platform/tdiary/util/tdiary-vim/README
platform/tdiary/plugin/hb_footer4sec.rb: fixed file encoding to UTF-8.

Line 
1#
2# hb_footer.rb
3#
4# はてなブックマーク (http://b.hatena.ne.jp/) のコメントを該当セクションに貼り付けるtDiaryプラグイン
5# 改造版rss_recent Version 0.0.5i2と共に使用する
6#
7# Licence: GPL
8# Author: ishinao <ishinao@ishinao.net>
9#
10
11add_section_leave_proc do |date, index|
12  td_url = "http://tdiary.ishinao.net/#{date.strftime('%Y%m%d')}.html%23p#{'%02d' % index}"
13  hb_url = "http://b.hatena.ne.jp/entry/#{td_url}"
14  rss_url = "http://b.hatena.ne.jp/entry/rss/#{td_url}"
15
16  template_head = %Q[<div class="section">\n<h4>このセクションに対する<a href="#{CGI.escapeHTML(hb_url)}">はてブ</a></h4>\n<ul class="hb_footer">\n]
17  template_list = '<li><span class="date">#{time.strftime("%Y年%m月%d日")}</span> <span class="hatenaid"><a href="#{CGI.escapeHTML(url)}">#{CGI.escapeHTML(title)}</a></span> <span class="comment">#{CGI.escapeHTML(description.to_s)}</span></li>'
18  template_foot = "</ul>\n</div>\n"
19
20  cache_time = 3600;
21  if date.strftime('%Y-%m-%d') != Time.now.strftime('%Y-%m-%d')
22    cache_time = 3600 * 12;
23  end
24  hb_footer4sec(rss_url, 50, cache_time, template_head, template_list, template_foot)
25end
26
27# rss-recent.rb: RSS recent plugin
28#
29# rss_recnet: show recnet list from RSS
30#   parameters (default):
31#      url: URL of RSS
32#      max: max of list itmes(5)
33#      cache_time: cache time(second) of RSS(60*60)
34#      template_head: rendering header part
35#      template_list: rendering RSS item part(with loop)
36#      template_foot: rendering footer part
37#
38# Copyright (c) 2003-2004 Kouhei Sutou <kou@cozmixng.org>
39# Distributed under the GPL
40#
41# Modified using template string and content:encoded
42# Version 0.0.5i2 by ishinao <ishinao@ishinao.net>
43#
44
45require "rss/rss"
46
47RSS_RECENT_FIELD_SEPARATOR = "\0"
48RSS_RECENT_ENTRY_SEPARATOR = "\1"
49RSS_RECENT_VERSION = "0.0.5i2"
50RSS_RECENT_HTTP_HEADER = {
51        "User-Agent" => "tDiary RSS recent plugin version #{RSS_RECENT_VERSION}. " <<
52        "Using RSS parser version is #{::RSS::VERSION}.",
53}
54
55def hb_footer4sec(url, max = 5, cache_time = 3600, \
56        template_head = "<ul>\n", \
57        template_list = '<li><span class="#{hb_footer4sec_modified_class(time)}"><a href="#{CGI.escapeHTML(url)}" title="#{CGI.escapeHTML(title)}">#{CGI::escapeHTML(title)}</a></span></li>\n', \
58        template_foot = "</ul>\n")
59        url.untaint
60
61        cache_file = "#{@cache_path}/rss-recent.#{CGI.escape(url)}"
62
63        hb_footer4sec_cache_rss(url, cache_file, cache_time.to_i)
64       
65        return '' unless test(?r, cache_file)
66
67        rv = template_head
68       
69        i = 0
70        hb_footer4sec_read_from_cache(cache_file).each do |title, url, time, content, description|
71                break if i >= max
72                next if (url.nil? or title.nil?)
73                rv << eval('%Q[' + template_list + ']')
74                i += 1
75        end
76
77        rv << template_foot
78
79        if i > 0
80                rv
81        else
82                ''
83        end
84end
85
86class InvalidResourceError < StandardError; end
87
88def hb_footer4sec_cache_rss(url, cache_file, cache_time)
89
90        cached_time = nil
91        cached_time = File.mtime(cache_file) if File.exist?(cache_file)
92
93        if cached_time.nil? or Time.now > cached_time + cache_time
94                require 'time'
95                require 'open-uri'
96                require 'net/http'
97                require 'uri/generic'
98                require 'rss/parser'
99                require 'rss/1.0'
100                require 'rss/2.0'
101                require 'rss/dublincore'
102                require 'rss/content'
103               
104                begin
105                        uri = URI.parse(url)
106
107                        raise URI::InvalidURIError if uri.scheme != "http"
108
109                        rss_source = hb_footer4sec_fetch_rss(uri, cached_time)
110                       
111                        raise InvalidResourceError if rss_source.nil?
112
113                        # parse RSS
114                        rss = ::RSS::Parser.parse(rss_source, false)
115                        raise ::RSS::Error if rss.nil?
116
117                        # pre processing
118                        begin
119                                rss.output_encoding = @conf.charset || charset
120                        rescue ::RSS::UnknownConversionMethodError
121                        end
122
123                        rss_infos = rss.items.collect do |item|
124                                hb_footer4sec_pubDate_to_dc_date(item)
125                                [item.title, item.link, item.dc_date, item.content_encoded, item.description]
126                        end
127                        hb_footer4sec_write_to_cache(cache_file, rss_infos)
128
129                rescue URI::InvalidURIError
130                        hb_footer4sec_write_to_cache(cache_file, [['Invalid URI', url]])
131                rescue InvalidResourceError, ::RSS::Error
132#                       hb_footer4sec_write_to_cache(cache_file, [['Invalid Resource', url]])
133# when cannot get valid RSS, use old cache
134                end
135        end
136
137end
138
139def hb_footer4sec_fetch_rss(uri, cache_time)
140        rss = nil
141        begin
142                uri.open(hb_footer4sec_http_header(cache_time)) do |f|
143                        case f.status.first
144                        when "200"
145                                rss = f.read
146                                # STDERR.puts "Got RSS of #{uri}"
147                        when "304"
148                                # not modified
149                                # STDERR.puts "#{uri} does not modified"
150                        else
151                                raise InvalidResourceError
152                        end
153                end
154        rescue TimeoutError, SocketError, StandardError,
155                        SecurityError # occured in redirect
156                raise InvalidResourceError
157        end
158        rss
159end
160
161def hb_footer4sec_http_header(cache_time)
162        header = RSS_RECENT_HTTP_HEADER.dup
163        if cache_time.respond_to?(:rfc2822)
164                header["If-Modified-Since"] = cache_time.rfc2822
165        end
166        header
167end
168
169def hb_footer4sec_write_to_cache(cache_file, rss_infos)
170        File.open(cache_file, 'w') do |f|
171                f.flock(File::LOCK_EX)
172                rss_infos.each do |info|
173                        f << info.join(RSS_RECENT_FIELD_SEPARATOR)
174                        f << RSS_RECENT_ENTRY_SEPARATOR
175                end
176                f.flock(File::LOCK_UN)
177        end
178end
179
180def hb_footer4sec_read_from_cache(cache_file)
181        require 'time'
182        infos = []
183        File.open(cache_file) do |f|
184                while info = f.gets(RSS_RECENT_ENTRY_SEPARATOR)
185                        info = info.chomp(RSS_RECENT_ENTRY_SEPARATOR)
186                        infos << info.split(RSS_RECENT_FIELD_SEPARATOR)
187                end
188        end
189        infos.collect do |title, url, time, content, description|
190                [
191                        hb_footer4sec_convert(title),
192                        hb_footer4sec_convert(url),
193                        hb_footer4sec_convert(time) {|time| Time.parse(time)},
194                        hb_footer4sec_convert(content),
195            hb_footer4sec_convert(description),
196                ]
197        end
198end
199
200def hb_footer4sec_convert(str)
201        if str.nil? or str.empty?
202                nil
203        else
204                if block_given?
205                        yield str
206                else
207                        str
208                end
209        end
210end
211
212# from RWiki
213def hb_footer4sec_modified(t)
214        return '-' unless t
215        dif = (Time.now - t).to_i
216        dif = dif / 60
217        return "#{dif}m" if dif <= 60
218        dif = dif / 60
219        return "#{dif}h" if dif <= 24
220        dif = dif / 24
221        return "#{dif}d"
222end
223
224# from RWiki
225def hb_footer4sec_modified_class(t)
226        return 'dangling' unless t
227        dif = (Time.now - t).to_i
228        dif = dif / 60
229        return "modified-hour" if dif <= 60
230        dif = dif / 60
231        return "modified-today" if dif <= 24
232        dif = dif / 24
233        return "modified-month" if dif <= 30
234        return "modified-year" if dif <= 365
235        return "modified-old"
236end
237
238def hb_footer4sec_pubDate_to_dc_date(target)
239        if target.respond_to?(:pubDate)
240                class << target
241                        alias_method(:dc_date, :pubDate)
242                end
243        end
244end
Note: See TracBrowser for help on using the browser.