RackPluginAtom
# = $Id: atom.rb, v 0.4 2010-10-11
# Copyright (C) 2010 KITAITI Makoto <KitaitiMakoto@gmail.com>
#
# A Hiki plugin to syndicate Atom feed
#
# rss.rb plugin is very helpful for creating this plugin, thanks!
#
# == Requirement
# * rss library which can make Atom feeds
# (If your rss lib cannot, download from
# http://www.cozmixng.org/~rwiki/?cmd=view;name=RSS+Parser)
#
# == Environment
# Operation checked under:
# * Ruby 1.8.7
# * Hiki 0.8.8.1
#
# == To Do
# * Selection of the number of syndicated pages at admin page
# * Syndication per page
#
# == License
# atom.rb, en/atom.rb and ja/atom.rb are
# distributed under the GPL v2.(see {HIKIROOT}/doc/COPYING.)
def atom
pages = atom_recent_updates(10) # Magic number!
last_modified = pages.first.values[0][:last_modified]
header = {}
if_modified_since = @request.env['HTTP_IF_MODIFIED_SINCE']
if_modified_since = Time.parse(if_modified_since) if if_modified_since
if if_modified_since and last_modified <= if_modified_since
return ::Hiki::Response.new([], 304, header)
else
body = atom_body(pages)
header['Last-Modified'] = last_modified.httpdate
header['Content-Type'] = 'application/atom+xml'
header['charset'] = body.encoding
header['Content-Language'] = @conf.lang
header['Pragma'] = 'no-cache'
header['Cache-Control'] = 'no-cache'
return ::Hiki::Response.new(body.to_s.to_utf8, 200, header)
end
end
def atom_recent_updates(page_count = 10)
@db.page_info.sort_by do |p|
p[p.keys[0]][:last_modified]
end.last(page_count).reverse
end
def atom_body(pages)
require 'rss/maker'
RSS::Maker.make('atom') do |maker|
maker.encoding = 'UTF-8'
maker.channel.author = @conf.author_name
maker.channel.about = @conf.index_url + '?c=atom'
maker.channel.title = @conf.site_name + ' : ' + label_atom_recent
maker.channel.description = @conf.site_name + ' ' + label_atom_recent
maker.channel.language = @conf.lang
maker.channel.date = pages.first.values[0][:last_modified]
maker.channel.rights = 'Copyright (C) ' + @conf.author_name
maker.channel.generator do |generator|
generator.uri = 'http://hikiwiki.org/'
generator.version = ::Hiki::VERSION
generator.content = 'Hiki'
end
maker.channel.links.new_link do |link|
link.rel = 'self'
link.type = 'application/atom+xml'
link.href = maker.channel.about
end
maker.channel.links.new_link do |link|
link.rel = 'alternate'
link.type = 'text/html'
link.href = @conf.index_url + '?c=recent'
end
pages.each do |p|
maker.items.new_item do |item|
name = p.keys[0]
src = @db.load_backup(name) || ''
dst = @db.load(name) || ''
case @conf['atom.mode']
when :unidiff
content = h(unified_diff(src, dst)).strip.gsub(/\n/, "<br>\n").gsub(/ /, ' ')
when :worddiff_digest
content = word_diff(src, dst, true).strip.gsub(/\n/, "<br>\n")
when :worddiff_full
content = word_diff(src, dst).strip.gsub(/\n/, "<br>\n")
when :html_full
tokens = @db.load_cache(name)
unless tokens
parser = @conf.parser.new(@conf)
tokens = parser.parse(@db.load(name))
@db.save_cache(name, tokens)
end
tmp = @conf.use_plugin
@conf.use_plugin = false
formatter = @conf.formatter.new(tokens, @db, Plugin.new(@conf.options, @conf), @conf)
content = formatter.to_s
@conf.use_plugin = tmp
else
raise "Invalid atom.mode: #{@conf['atom.mode']}"
end
if content.empty?
content = shorten(dst).strip.gsub(/\n/, "<br>\n")
end
uri = @conf.index_url + '?' + name.escape
item.title = page_name(name)
item.link = uri
item.author = p[name][:editor] if p[name][:editor]
item.date = p[name][:last_modified].utc.strftime('%Y-%m-%dT%H:%M:%S+00:00')
item.content.type = 'html'
item.content.content = content
end
end
end
end
add_body_enter_proc do
@conf['atom.mode'] ||= :unidiff
@conf['atom.menu'] ? add_plugin_command('atom', 'Atom') : add_plugin_command('atom', nil)
end
add_header_proc do
%Q| <link rel="alternate" type="application/atom+xml" title="Atom" href="#{@conf.index_url}?c=atom">|
end
def saveconf_atom
@conf['atom.mode'] = @request.params['atom.mode'].intern if @mode == 'saveconf'
end
if @request.params['conf'] == 'atom' && @mode == 'saveconf'
@conf['atom.menu'] = (@request.params['atom.menu'] == 'true')
end
add_conf_proc('atom', label_atom_config) do
saveconf_atom
str = <<HTML
<h3 class="subtitle">#{label_atom_mode_title}</h3>
<p><select name="atom.mode">
HTML
label_atom_mode_candidate.each_pair do |value, label|
str << %Q|<option value="#{value}"#{' selected' if @conf['atom.mode'] == value}>#{label}</option>\n|
end
str << "</select></p>\n"
str << <<HTML
<h3 class="subtitle">#{label_atom_menu_title}</h3>
<p><select name="atom.menu">
HTML
label_atom_menu_candidate.each_index do |i|
str << %Q|<option value="#{[true,false][i]}"#{' selected' if @conf['atom.menu'] == [true,false][i]}>#{label_atom_menu_candidate[i]}</option>\n|
end
str << "</select></p>\n"
end
export_plugin_methods :atom
Referer | 225 | 160 | 30 | 26 | 25 | 12 | 12 | 11 | 9 | 9 | 9 | 9 | 9 | 9 | 9 | 9 | 9 | 9 | 9 | 9 | 9 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 5 | 5 | 5 | 5 | 5 | 5 | 5 | 5 | 4 | 4 | 4 | 4 | 4 | 3 | 3 | 3 | 3 | 3 | 3 | 3 | 3 | 3 | 3 | 3 | 3 | 3 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
Keyword(s):
References:[Hiki Atomプラグイン]