14)?14/E.length:1;if(D==0){y.setAttribute("transform","translate("+(z*11.35)+","+(z*9.7)+") scale(1,"+w+")")}else{y.setAttribute("transform","translate("+(z*0.65)+","+(z*0.8)+") scale(-1,"+(-w)+")")}return y};var b=function(I,P,T){var R=document;var M=R.createElementNS(d,"svg");var K=T[97];var S=j;if(S==0){S=(I/12c){S=c}}console.log(I,P,S);M.setAttribute("width",S*12);M.setAttribute("height",S*10);M.style.verticalAlign="bottom";var J=Math.floor(S*1.25);var H=Math.floor(S*0.75);var N;if(window.devicePixelRatio&&window.devicePixelRatio>=2){N=1/2}else{N=1}var Q=R.createElementNS(d,"g");var v=R.createElementNS(d,"rect");v.setAttribute("x",J);v.setAttribute("y",H);v.setAttribute("width",S*9+1);v.setAttribute("height",S*9+1);v.setAttribute("stroke-width",2);v.setAttribute("stroke",q);v.setAttribute("fill","none");Q.appendChild(v);for(var O=0;O<9;O++){if(O){var V=R.createElementNS(d,"line");var X=R.createElementNS(d,"line");V.setAttribute("x1",O*S+J+N/2);V.setAttribute("x2",O*S+J+N/2);V.setAttribute("y1",H+N/2);V.setAttribute("y2",H+S*9+N/2);V.setAttribute("stroke-width",N);V.setAttribute("stroke",q);X.setAttribute("y1",O*S+H+N/2);X.setAttribute("y2",O*S+H+N/2);X.setAttribute("x1",J+N/2);X.setAttribute("x2",J+S*9+N/2);X.setAttribute("stroke-width",N);X.setAttribute("stroke",q);Q.appendChild(V);Q.appendChild(X)}var U=R.createElementNS(d,"text");var W=R.createElementNS(d,"text");U.setAttribute("x",O*S+J+S/2);U.setAttribute("y",H-S/6);U.setAttribute("font-family",e);U.textContent=h.charAt(8-O);U.setAttribute("font-size",S*0.4);U.setAttribute("fill",q);U.setAttribute("text-anchor","middle");Q.appendChild(U);W.setAttribute("x",J+S*9+S*0.35);W.setAttribute("y",O*S+H+S*0.6);W.textContent=s.charAt(O);W.setAttribute("font-size",S*0.4);W.setAttribute("font-family",e);W.setAttribute("fill",q);W.setAttribute("text-anchor","middle");Q.appendChild(W)}M.appendChild(Q);for(var O=0;O<81;O++){if(T[O]>0){var G=(O%9)*S+J+S/2+N/2;var F=Math.floor(O/9)*S+H+S/2+N/2;var A=R.createElementNS(d,"g");var L=t.charAt((T[O]-1)&15);var z=R.createElementNS(d,"text");z.setAttribute("fill",q);if("全圭杏".indexOf(L)!=-1){var z=R.createElementNS(d,"text");z.setAttribute("font-size",S*0.82);L=t.charAt((T[O]-1)&7);if(O==K){z.setAttribute("class","szLastMove")}else{z.setAttribute("font-family",e)}z.setAttribute("text-anchor","middle");z.setAttribute("dy",-S*0.09);z.textContent="成";A.appendChild(z);z=R.createElementNS(d,"text");z.setAttribute("dy",S*0.32+S*0.41);if(T[O]>16){A.setAttribute("transform","translate("+(G)+","+(F)+") scale(-1,-0.5)")}else{A.setAttribute("transform","translate("+(G)+","+(F)+") scale(1,0.5)")}}else{z.setAttribute("dy",S*0.32);if(T[O]>16){A.setAttribute("transform","translate("+(G)+","+(F)+") scale(-1,-1)")}else{A.setAttribute("transform","translate("+(G)+","+(F)+")")}}z.setAttribute("font-size",S*0.82);if(O==K){z.setAttribute("class","szLastMove")}else{z.setAttribute("font-family",e)}z.setAttribute("text-anchor","middle");z.textContent=L;A.appendChild(z);M.appendChild(A)}}var C=g(0,R,S,T);M.appendChild(C);var B=g(1,R,S,T);M.appendChild(B);var E=document.createElement("div");E.style.position="relative";E.style.width=S*12+"px";E.style.height=S*10+"px";E.style.overflow="auto";(function(w){w.onmouseover=function(x){this.childNodes[1].style.display="block"};w.onmouseout=function(x){this.childNodes[1].style.display="none"}})(E);var D=document.createElement("div");D.style.position="absolute";D.style.right=0+"px";D.style.top=0+"px";D.style.zIndex="9999";D.style.width="30px";D.style.height="16px";D.style.borderRadius="4px";D.style.backgroundColor="#CCC";D.style.display="none";D.style.fontSize="14px";D.style.lineHeight="1";D.style.color="black";D.style.cursor="pointer";D.style.baseline="middle";D.title="表示切替(局面図⇔kif形式)";D.style.textAlign="center";D.innerHTML="⇔";D.onclick=function(){var w=this.parentNode;if(this.previousSibling.style.display=="none"){this.previousSibling.style.display="";this.nextSibling.style.display="none"}else{this.previousSibling.style.display="none";this.nextSibling.style.display=""}};E.appendChild(M);E.appendChild(D);return E};l()}); tdiary-contrib-5.1.0/js/show_and_hide.js 0000664 0000000 0000000 00000002062 13570131474 0020221 0 ustar 00root root 0000000 0000000 /*
* show_and_hide.js : javascript for show_and_hide.rb plugin of tDiary
*
* Copyright (C) 2011 by tamoot
* You can distribute it under GPL.
*/
$( function() {
function show_and_hide(target) {
$('.show_and_hide_toggle', target).each( function() {
$(this).click( function() {
$('.show_and_hide#'+$(this).attr('data-showandhideid')).slideToggle(400);
});
});
};
// for AutoPagerize
$(window).on('AutoPagerize_DOMNodeInserted', function(event) {
show_and_hide(event.target);
});
// for AuthPatchWork
// NOTE: jQuery.bind() cannot handle an event that include a dot charactor.
// see http://todayspython.blogspot.com/2011/06/autopager-autopagerize.html
if(window.addEventListener) {
window.addEventListener('AutoPatchWork.DOMNodeInserted', function(event) {
show_and_hide(event.target);
}, false);
} else if(window.attachEvent) {
window.attachEvent('onAutoPatchWork.DOMNodeInserted', function(event) {
show_and_hide(event.target);
});
};
show_and_hide(document)
$('.show_and_hide').hide();
});
tdiary-contrib-5.1.0/js/slideshow.js 0000664 0000000 0000000 00000006164 13570131474 0017436 0 ustar 00root root 0000000 0000000 /*
* slideshow.js : show slides
*
* Copyright (C) 2016 by TADA Tadashi
* Distributed under the GPL2 or any later version.
*/
$(function(){
function isFullscreenEnabled(doc) {
return(
doc.fullscreenEnabled ||
doc.webkitFullscreenEnabled ||
doc.mozFullScreenEnabled ||
doc.msFullscreenEnabled ||
false
);
};
function requestFullscreen(element) {
var funcs = [
'requestFullscreen',
'webkitRequestFullscreen',
'mozRequestFullScreen',
'msRequestFullscreen',
];
$.each(funcs, function(idx, func) {
if (element[func]) {
element[func]();
return false;
}
});
};
function isFullscreen() {
if (document.fullscreenElement ||
document.webkitFullscreenElement ||
document.mozFullScreenElement ||
document.msFullscreenElement ) {
return true;
}
return false;
};
function startSlideShow(content) {
if (!isFullscreenEnabled(document)) {
return false;
}
var slides = [];
$.each(content.children(), function(i, elem) {
var e = $(elem).clone();
if (e.prop('tagName') == 'H3') { // main title
$('a', e).remove(); // section anchor
$('span', e).remove(); // hatena start etc...
$('button.slideshow', e).remove();
slides.push([$('').append(e)]);
} else if (e.prop('tagName') == 'H4') { // page title
slides.push([e, $('
')]);
} else {
var last = slides[slides.length-1];
last[last.length-1].append(e);
}
});
var screen = window.screen;
var slide = $('
').
addClass('slide').
css('width', screen.width).
css('height', screen.height);
var current_page = 0;
var firstClick = true;
$('body').append(slide);
slide.append(slides[current_page]);
requestFullscreen(slide[current_page]);
$(document).on({
'keydown': function(e) {
if (e.keyCode == 13 || e.keyCode == 34 || e.keyCode == 39) { // next page
if (slides.length - 1 > current_page) {
e.preventDefault();
slide.empty().append(slides[++current_page]);
}
} else if (e.keyCode == 37 || e.keyCode == 33) { // prev page
if (current_page > 0) {
e.preventDefault();
slide.empty().append(slides[--current_page]);
}
} else if (e.keyCode == 36) { // [Home] to top page
e.preventDefault();
slide.empty().append(slides[current_page = 0]);
} else if (e.keyCode == 35) { // [End] to bottom page
e.preventDefault();
slide.empty().append(slides[current_page = slides.length-1]);
}
},
'click': function() {
if (!firstClick && slides.length - 1 > current_page) {
slide.empty().append(slides[++current_page]);
}
firstClick = false;
},
'fullscreenchange webkitfullscreenchange mozfullscreenchange msfullscreenchange': function() {
if (!isFullscreen()) { // fullscreen was closed
$(document).off('keydown').off('click');
slide.remove();
}
}
});
return true;
};
$('.slideshow').on('click', function(e){
var section = $(this).parent().parent();
e.preventDefault();
if (!startSlideShow(section)) {
alert("couldn't start slideshow.")
return;
}
});
});
tdiary-contrib-5.1.0/js/socialbutton.js 0000664 0000000 0000000 00000006372 13570131474 0020144 0 ustar 00root root 0000000 0000000 /**
* socialbutton.js -
*
* Copyright (C) 2011 by MATSUOKA Kohei
* You can distribute it under GPL.
*/
/**
* SYNOPSIS
*
* you can set options at socialbutton.rb
*
* $tDiary.plugin.socialbutton.enables =
* ['twitter', 'hatena', 'facebook_like', 'evernote'];
*
* $tDiary.plugin.socialbutton.options = {
* twitter: { via: 'machu' }
* };
*
*/
$(function() {
// load config from tDiary plugin (socialbutton.rb)
var config = $tDiary.plugin.socialbutton;
// set options for jQuery.socialbutton
var callbacks = {
twitter: function(url, title) {
var link = url;
var pos = 0;
if ((pos = url.indexOf('#')) > 0) {
link = url.substr(0, pos)
}
return {
url: link,
text: title,
button: 'horizontal',
lang: $('html').attr('lang').substr(0,2)
};
},
hatena: function(url, title) {
return {
url: url,
title: title,
button: 'simple-balloon'
};
},
facebook_like: function(url, title) {
return {
url: url,
button: 'button_count',
locale: $('html').attr('lang').replace('-', '_')
};
},
pinterest: function(url, title) {
return {
url: url,
media: $('p img:first', $('div.section h3 a[name=' + url.substr(-3) + ']').parent().parent()).attr('src'),
description: title,
button: 'horizontal',
};
},
};
function socialbutton(target) {
$('.socialbuttons').css('height', '1em')
var bottom = $(window).height() + $(window).scrollTop();
$($tDiary.blogkit ? '.day' : '.day .section')
.filter(function() {
return bottom > $(this).offset().top;
})
.filter(function() {
return $(this).find('.socialbutton').length == 0
})
.each(function() {
var anchor = $(this).find('h3 a');
if ($tDiary.blogkit) {
var link = $(this).children('h2').find('a:first').get(0);
var url = link ? link.href : document.URL;
var title = $(this).children('h2').find('.title').text();
} else if (anchor.length == 0) {
// The section may not have an anchor on etdiary style.
// https://github.com/tdiary/tdiary-contrib/issues/59
var url = ($(this).parents('.day').find('h2 a:first').get(0)||'').href;
var title = $(this).parents('.day').find('h2 .title').text();
} else {
var url = anchor.get(0).href;
var title = anchor.attr('title');
}
if (url && title) {
// console.debug('loading socialbutton: ' + title);
var socialbuttons = $(this).find('.socialbuttons');
append_button(url, title, socialbuttons);
}
});
}
function append_button(url, title, socialbuttons) {
$.each(config.enables, function(i, service) {
var options = callbacks[service](url, title.replace(/"/g, '"'));
$.extend(options, config.options[service]);
$('
')
.css("float", "left")
.css("margin-right", "0.5em")
.appendTo(socialbuttons)
.socialbutton(service, options);
});
}
$(window).on('scroll', function(event) {
socialbutton(document);
});
socialbutton(document);
});
tdiary-contrib-5.1.0/js/twitter_anywhere.js 0000664 0000000 0000000 00000001161 13570131474 0021031 0 ustar 00root root 0000000 0000000 /*
* twitter_anywhere.js : use Twitter@Anywhere
*
* Copyright (C) 2012 by tamoot
* You can distribute it under GPL.
*/
$( function() {
// load config from tDiary plugin (twitter_anywhere.rb)
var config = $tDiary.plugin.twitter_anywhere;
// hovarcards
var expand = config.hovercards.expand_default;
$.each(config.selectors, function(i, css){
twttr.anywhere(function(twitter) {
twitter(css).hovercards(expand);
});
});
});
// tweet box
function showTweetBox(option) {
twttr.anywhere(function (T) {
T("#tweetbox").tweetBox(option);
});
}
tdiary-contrib-5.1.0/js/yahoo_kousei.js 0000664 0000000 0000000 00000001066 13570131474 0020127 0 ustar 00root root 0000000 0000000 $( function() {
$( '.plugin_yahoo_search_result_raw' ).each( function( index ) {
$(this).click( function() {
var pos = $($('td', $(this)).get(3)).text().split(',');
sp = parseInt(pos[0]);
ep = parseInt(pos[1]);
var o = $( 'textarea[name="body"]' ).get( 0 );
o.focus();
if ( jQuery.browser.msie ) {
var range = document.selection.createRange();
range.collapse();
range.moveStart( 'character', sp );
range.moveEnd( 'character', ep );
range.select();
} else {
o.setSelectionRange( sp , sp + ep );
}
} );
} );
} );
tdiary-contrib-5.1.0/lib/ 0000775 0000000 0000000 00000000000 13570131474 0015222 5 ustar 00root root 0000000 0000000 tdiary-contrib-5.1.0/lib/bayes.rb 0000664 0000000 0000000 00000010751 13570131474 0016656 0 ustar 00root root 0000000 0000000 # Copyright (C) 2007, KURODA Hiraku
# You can redistribute it and/or modify it under GPL2.
require "pstore"
module Bayes
module CHARSET
def self.setup_re(m)
o = $KCODE
$KCODE = m::KCODE
m.const_set(:RE_MESSAGE_TOKEN, Regexp.union(m::RE_KATAKANA, m::RE_KANJI, /[a-zA-Z]+/))
$KCODE=o
end
module EUC
KCODE = "e"
KATAKANA = "\xa5\xa2-\xa5\xf3"
BAR = "\xa1\xbc"
KANJI = "\xb0\xa1-\xfc\xfe"
RE_KATAKANA = /[#{KATAKANA}#{BAR}]{2,}/eo
RE_KANJI = /[#{KANJI}]{2,}/eo
CHARSET.setup_re(self)
end
module UTF8
KCODE = "u"
def self.c2u(c)
[c].pack("U")
end
def self.utf_range(a, b)
"#{c2u(a)}-#{c2u(b)}"
end
KATAKANA = utf_range(0x30a0, 0x30ff)
BAR = c2u(0x30fc)
KANJI = utf_range(0x4e00, 0x9faf)
RE_KATAKANA = /[#{KATAKANA}#{BAR}]{2,}/uo
RE_KANJI = /[#{KANJI}]{2,}/uo
CHARSET.setup_re(self)
end
end
class TokenList < Array
attr_reader :charset
def initialize(charset=nil)
unless charset
charset =
case $KCODE
when /^e/i
CHARSET::EUC
else
CHARSET::UTF8
end
end
@charset = charset
end
alias _concat concat
def concat(array, prefix=nil)
if prefix
_concat(array.map{|i| "#{prefix} #{i.to_s}"})
else
_concat(array)
end
end
alias _push push
def push(item, prefix=nil)
if prefix
_push("#{prefix} #{item.to_s}")
else
_push(item)
end
end
def add_host(host, prefix=nil)
if /^(?:\d{1,3}\.){3}\d{1,3}$/ =~ host
while host.size>0
push(host, prefix)
host = host[/^(.*?)\.?\d+$/, 1]
end
else
push(host, prefix)
h = host
while /^(.*?)[-_.](.*)$/=~h
h = $2
push($1, prefix)
push(h, prefix)
end
end
self
end
def add_url(url, prefix=nil)
if %r[^(?:https?|ftp)://(.*?)(?::\d+)?/(.*?)\/?(\?.*)?$] =~ url
host, path = $1, $2
add_host(host, prefix)
if path.size>0
push(path, prefix)
p = path
re = %r[^(.*)[-_./](.*?)$]
while re=~p
p = $1
push($2, prefix)
push(p, prefix)
end
end
end
self
end
def add_message(message, prefix=nil)
concat(message.scan(@charset::RE_MESSAGE_TOKEN), prefix)
self
end
def add_mail_addr(addr, prefix=nil)
push(addr, prefix)
name, host = addr.split(/@/)
return self if (name||"").empty?
host ||= ""
push(name, prefix)
add_host(host, prefix)
self
end
end
class FilterBase
attr_reader :spam, :ham, :db_name, :charset
def initialize(db_name=nil, charset=nil)
@spam = self.class::Corpus.new
@ham = self.class::Corpus.new
@charset = charset
@db_name = db_name
if db_name && File.exist?(db_name)
PStore.new(db_name).transaction(true) do |db|
@spam = db["spam"]
@ham = db["ham"]
@charset = db["charset"]
end
end
end
def save(db_name=nil)
db_name ||= @db_name
@db_name ||= db_name
return unless @db_name
PStore.new(@db_name).transaction do |db|
db["spam"] = @spam
db["ham"] = @ham
db["charset"] = @charset
yield(db) if block_given?
end
end
def [](token)
score(token)
end
end
class PlainBayes < FilterBase
class Corpus < Hash
def initialize
super(0.0)
end
def <<(src)
s = src.size.to_f
src.each do |i|
self[i] += 1/s
end
end
end
def score(token)
return nil unless @spam.include?(token) || @ham.include?(token)
s = @spam[token]
h = @ham[token]
s/(s+h)
end
def estimate(tokens, take=15)
s = tokens.uniq.map{|i| score(i)}.compact.sort{|a, b| (0.5-a).abs <=> (0.5-b)}.reverse[0...take]
return nil if s.empty? || s.include?(1.0) && s.include?(0.0)
prod = s.inject(1.0){|r, i| r*i}
return prod/(prod+s.inject(1.0){|r, i| r*(1-i)})
end
end
class PaulGraham < FilterBase
class Corpus < Hash
attr_reader :count
def initialize
super(0)
@count = 0
end
def <<(src)
@count += 1
src.each do |i|
self[i] += 1
end
end
end
def score(token)
return 0.4 unless @spam.include?(token) or @ham.include?(token)
g = @ham.count==0 ? 0.0 : [1.0, 2*@ham[token]/@ham.count.to_f].min
b = @spam.count==0 ? 0.0 : [1.0, @spam[token]/@spam.count.to_f].min
r = [0.01, [0.99, b/(g+b)].min].max
r
end
def estimate(tokens, take=15)
s = tokens.uniq.map{|i| score(i)}.compact.sort{|a, b| (0.5-a).abs <=> (0.5-b)}.reverse[0...take]
return nil if s.empty? || s.include?(1.0) && s.include?(0.0)
prod = s.inject(1.0){|r, i| r*i}
return prod/(prod+s.inject(1.0){|r, i| r*(1-i)})
end
end
end
tdiary-contrib-5.1.0/lib/bayes/ 0000775 0000000 0000000 00000000000 13570131474 0016325 5 ustar 00root root 0000000 0000000 tdiary-contrib-5.1.0/lib/bayes/convert.rb 0000664 0000000 0000000 00000001230 13570131474 0020326 0 ustar 00root root 0000000 0000000 # Copyright (C) 2008, KURODA Hiraku
# You can redistribute it and/or modify it under GPL2.
require "bayes"
require "kconv"
module Bayes
module CHARSET
module EUC
KCONV = Kconv::EUC
end
module UTF8
KCONV = Kconv::UTF8
end
end
class FilterBase
def convert_corpus(corpus, to_code, from_code)
r = self.class::Corpus.new
corpus.each do |k, v|
r[k.kconv(to_code::KCONV, from_code::KCONV)] = v
end
r
end
private :convert_corpus
def convert(to_code, from_code)
@charset = to_code
@ham = convert_corpus(@ham, to_code, from_code)
@spam = convert_corpus(@spam, to_code, from_code)
end
end
end
tdiary-contrib-5.1.0/lib/exifparser/ 0000775 0000000 0000000 00000000000 13570131474 0017372 5 ustar 00root root 0000000 0000000 tdiary-contrib-5.1.0/lib/exifparser/README 0000664 0000000 0000000 00000000442 13570131474 0020252 0 ustar 00root root 0000000 0000000 ExifParserは、tdiary-contribの管理から外れました。
通常は以下のコマンドによりインストールすることができます。
#gem install exifparser
もしくは、
$git clone https://github.com/kp1/exifparser.git
でソースコードを取得可能です。
tdiary-contrib-5.1.0/lib/extensions/ 0000775 0000000 0000000 00000000000 13570131474 0017421 5 ustar 00root root 0000000 0000000 tdiary-contrib-5.1.0/lib/extensions/contrib.rb 0000664 0000000 0000000 00000000410 13570131474 0021401 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
require 'tdiary/extensions'
module TDiary
module Extensions
class Contrib
def self.sp_path
File.join(TDiary::Contrib.root, 'plugin')
end
def self.assets_path
File.join(TDiary::Contrib.root, 'js')
end
end
end
end
tdiary-contrib-5.1.0/lib/tdiary-contrib.rb 0000664 0000000 0000000 00000000231 13570131474 0020475 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
require 'extensions/contrib'
module TDiary
class Contrib
def self.root
File.expand_path('../..', __FILE__)
end
end
end
tdiary-contrib-5.1.0/lib/tdiary/ 0000775 0000000 0000000 00000000000 13570131474 0016516 5 ustar 00root root 0000000 0000000 tdiary-contrib-5.1.0/lib/tdiary/contrib/ 0000775 0000000 0000000 00000000000 13570131474 0020156 5 ustar 00root root 0000000 0000000 tdiary-contrib-5.1.0/lib/tdiary/contrib/version.rb 0000664 0000000 0000000 00000000076 13570131474 0022173 0 ustar 00root root 0000000 0000000 module TDiary
class Contrib
VERSION = "5.1.0"
end
end
tdiary-contrib-5.1.0/lib/wgs2tky.rb 0000664 0000000 0000000 00000003061 13570131474 0017161 0 ustar 00root root 0000000 0000000 #
# wgs2tky.rb
# -- GPS data converter
#
# kp
# Destributed under the GPL
class Wgs2Tky
Pi = Math::PI
Rd = Pi/180
# WGS84
A = 6378137.0 # 赤道半径
F = 1/298.257223563 # 扁平率
E2 = F*2 - F*F # 第一離心率
# Tokyo
A_ = 6378137.0 - 739.845 # 6377397.155
F_ = 1/298.257223563 - 0.000010037483
# 1 / 299.152813
E2_ = F_*2 - F_*F_
Dx = +128
Dy = -481
Dz = -664
def Wgs2Tky.conv!(lat,lon,h = 0)
b = lat[0].to_f + lat[1].to_f/60 + lat[2].to_f/3600
l = lon[0].to_f + lon[1].to_f/60 + lon[2].to_f/3600
(x,y,z) = Wgs2Tky._llh2xyz(b,l,h,A,E2)
x+=Dx
y+=Dy
z+=Dz
(b,l,h) = Wgs2Tky._xyz2llh(x,y,z,A_,E2_)
lat[0..2]=Wgs2Tky._deg2gdms(b)
lon[0..2]=Wgs2Tky._deg2gdms(l)
end
private
include Math
extend Math
def Wgs2Tky._llh2xyz(b,l,h,a,e2)
b *= Rd
l *= Rd
sb = sin(b)
cb = cos(b)
rn = a / Math.sqrt(1-e2*sb*sb)
x = (rn+h)*cb*cos(l)
y = (rn+h)*cb*sin(l)
z = (rn*(1-e2)+h) * sb
return x,y,z
end
def Wgs2Tky._xyz2llh(x,y,z,a,e2)
bda = sqrt(1-e2)
po = sqrt(x*x+y*y)
t = atan2(z,po*bda)
st = sin(t)
ct = cos(t)
b = atan2(z+e2*a/bda*st*st*st,po-e2*a*ct*ct*ct)
l = atan2(y,x)
sb = sin(b)
rn = a / sqrt(1-e2*sb*sb)
h = po / cos(b) - rn
return b/Rd,l/Rd,h
end
def Wgs2Tky._deg2gdms(deg)
sf = deg*3600
s = sf.to_i%60
m = (sf/60).to_i%60
d = (sf/3600).to_i
s += sf - sf.to_i
return d,m,s
end
end
tdiary-contrib-5.1.0/misc/ 0000775 0000000 0000000 00000000000 13570131474 0015407 5 ustar 00root root 0000000 0000000 tdiary-contrib-5.1.0/misc/section_footer2/ 0000775 0000000 0000000 00000000000 13570131474 0020513 5 ustar 00root root 0000000 0000000 tdiary-contrib-5.1.0/misc/section_footer2/buzzurl.yaml 0000664 0000000 0000000 00000000325 13570131474 0023114 0 ustar 00root root 0000000 0000000 url: http://buzzurl.jp/entry/
src: http://buzzurl.jp/static/image/api/icon/add_icon_mini_10.gif
title:
ja: このエントリを含む Buzzurl
=: this entry on Buzzurl
counter: http://buzzurl.jp/api/counter/
tdiary-contrib-5.1.0/misc/section_footer2/fc2.yaml 0000664 0000000 0000000 00000000351 13570131474 0022050 0 ustar 00root root 0000000 0000000 url: http://bookmark.fc2.com/search/detail?url=
src: http://bookmark.fc2.com/img/add-16.gif
title:
ja: このエントリを含む FC2ブックマーク
=: this entry on FC2 Bookmark
counter: http://bookmark.fc2.com/image/users/
tdiary-contrib-5.1.0/misc/section_footer2/ldc.yaml 0000664 0000000 0000000 00000000361 13570131474 0022141 0 ustar 00root root 0000000 0000000 url: http://clip.livedoor.com/page/
src: http://parts.blog.livedoor.jp/img/cmn/clip_16_16_w.gif
title:
ja: このエントリを含む livedoor クリップ
=: this entry on livedoor clip
counter: http://image.clip.livedoor.com/counter/
tdiary-contrib-5.1.0/misc/section_footer2/retweet.yaml 0000664 0000000 0000000 00000000352 13570131474 0023056 0 ustar 00root root 0000000 0000000 url: 'http://twitter.com/home?status=RT @your-twitter-account: %s '
src: http://kayakaya.net/parts/tdiary/retweet.gif
title:
ja: このエントリをRetweetする
=: Retweet for this entry
counter:
usesubtitle: !ruby/regexp /%s/
tdiary-contrib-5.1.0/misc/section_footer2/twitter.yaml 0000664 0000000 0000000 00000000330 13570131474 0023075 0 ustar 00root root 0000000 0000000 url: 'http://twitter.com/home?status=Reading: %s '
src: http://twitter-badges.s3.amazonaws.com/t_mini-a.png
title:
ja: このエントリをTweetする
=: Tweet this entry
counter:
usesubtitle: !ruby/regexp /%s/
tdiary-contrib-5.1.0/misc/section_footer2/yahoo.yaml 0000664 0000000 0000000 00000000374 13570131474 0022522 0 ustar 00root root 0000000 0000000 url: http://bookmarks.yahoo.co.jp/url?url=
src: http://i.yimg.jp/images/sicons/ybm16.gif
title:
ja: このエントリを含む Yahoo!ブックマーク
=: this entry on Yahoo! JAPAN Bookmarks
counter: http://num.bookmarks.yahoo.co.jp/image/small/
tdiary-contrib-5.1.0/plugin/ 0000775 0000000 0000000 00000000000 13570131474 0015752 5 ustar 00root root 0000000 0000000 tdiary-contrib-5.1.0/plugin/add_bookmark.rb 0000664 0000000 0000000 00000006267 13570131474 0020727 0 ustar 00root root 0000000 0000000 # add_bookmark.rb $Revision 1.3 $
#
# Copyright (c) 2005 SHIBATA Hiroshi
# You can redistribute it and/or modify it under GPL2.
require 'uri'
def bookmark_init
@conf['add.bookmark.delicious'] ||= ''
@conf['add.bookmark.hatena'] ||= ''
@conf['add.bookmark.livedoor'] ||= ''
@conf['add.bookmark.buzzurl'] ||= ''
end
add_subtitle_proc do |date, index, subtitle|
bookmark_init
caption = %Q|#{subtitle} |
section_url = @conf.base_url + anchor(date.strftime('%Y%m%d')) + '#p' + ('%02d' % index)
if @conf['add.bookmark.delicious'] == 't' then
escaped_url = URI.escape(section_url, /[^-.!~*'()\w]/n)
caption += %Q||
caption += %Q| |
caption += %Q| |
end
if @conf['add.bookmark.hatena'] == 't' then
caption += %Q||
caption += %Q| |
caption += %Q| |
end
if @conf['add.bookmark.livedoor'] == 't' then
caption += %Q||
caption += %Q| |
caption += %Q| |
end
if @conf['add.bookmark.buzzurl'] == 't' then
caption += %Q||
caption += %Q| |
caption += %Q| |
end
<<-HTML
#{caption}
HTML
end
add_conf_proc( 'add_bookmark', @add_bookmark_label ) do
add_bookmark_conf_proc
end
def add_bookmark_conf_proc
bookmark_init
saveconf_add_bookmark
bookmark_categories = [
'add.bookmark.delicious',
'add.bookmark.hatena',
'add.bookmark.livedoor',
'add.bookmark.buzzurl'
]
r = ''
r << %Q|#{@add_bookmark_label} #{@add_bookmark_desc}
|
end
if @mode == 'saveconf'
def saveconf_add_bookmark
@conf['add.bookmark.delicious'] = @cgi.params['add.bookmark.delicious'][0]
@conf['add.bookmark.hatena'] = @cgi.params['add.bookmark.hatena'][0]
@conf['add.bookmark.livedoor'] = @cgi.params['add.bookmark.livedoor'][0]
@conf['add.bookmark.buzzurl'] = @cgi.params['add.bookmark.buzzurl'][0]
end
end
tdiary-contrib-5.1.0/plugin/apple_webclip.rb 0000664 0000000 0000000 00000001323 13570131474 0021104 0 ustar 00root root 0000000 0000000 #
# apple_webclip.rb - Add icon information for Apple WebClip.
#
# Copyright (C) 2008, TADA Tadashi
# You can redistribute it and/or modify it under GPL.
#
add_header_proc do
if @conf['apple_webclip.url'] and @conf['apple_webclip.url'].size > 0
%Q| \n|
else
''
end
end
add_conf_proc( 'apple_webclip', 'Apple WebClip' ) do
if @mode == 'saveconf' then
@conf['apple_webclip.url'] = @cgi.params['apple_webclip.url'][0]
end
<<-HTML
Icon URL
Create and cpecify PNG file 60x60 pixels.
HTML
end
tdiary-contrib-5.1.0/plugin/appstore.rb 0000664 0000000 0000000 00000002121 13570131474 0020130 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
#
# appstore.rb - embeded AppStore data for tDiary,
# use App Store Affliate Resources Search API.
# http://www.apple.com/itunes/affiliates/resources/documentation/itunes-store-web-service-search-api.html
#
# Copyright (C) 2011, tamoot
# You can redistribute it and/or modify it under GPL2.
#
require 'uri'
if /\A(?:latest|day|month|nyear|preview)\z/ =~ @mode
enable_js('appstore.js')
end
def appstore_detail(url)
appstore_dom = ''
begin
appstore_dom = appstore_common(url, {:detail => true})
rescue
appstore_dom = "Error. message=#{$!.message}. "
end
end
def appstore_common(url, params)
return %Q|#{url} | if feed?
appstore_uri = URI::parse(url)
id = appstore_uri.path.split('/').last.gsub('id', '')
raise StandardError.new("AppStore ID: not found from #{url}..") if id.nil? || id == ''
return %Q| |
end
# Local Variables:
# mode: ruby
# indent-tabs-mode: t
# tab-width: 3
# ruby-indent-level: 3
# End:
# vim: ts=3
tdiary-contrib-5.1.0/plugin/bigpresen.rb 0000664 0000000 0000000 00000005422 13570131474 0020260 0 ustar 00root root 0000000 0000000 # bigpresen.rb $Revision: 1.03 $
#
# bigpresen : クリックで進行する「高橋メソッド」風巨大文字プレゼンテーションを挿入
#
# パラメタ :
# str : 本文。"|"はスライドの区切り、"/"はスライド内の改行となる。
# "|"と"|"を表示する場合には、前に"\"をつけてエスケープ。
# width : スライドの幅。ピクセルで指定。(デフォルト : 480)
# height : スライドの高さ。ピクセルで指定。(デフォルト : 320)
#
# 日記本文に、<%= bigpresen 'str','width','height' %> の形式で記述します。
# 文字のサイズは、表示テキストとスライドのサイズに合うよう自動的に調整されます。
# JavaScriptとDHTMLを用いて動かすので、閲覧環境によっては表示されないこともあります。
#
# Copyright (c) 2006 Maripo Goda
# mailto:madin@madin.jp
# Document URL http://www.madin.jp/works/plugin.html
# You can redistribute it and/or modify it under GPL2.
@bigPresenID = 0;
def bigpresen (str='', width='480',height='320')
scriptID = 'bp' + @bigPresenID.to_s
@bigPresenID += 1;
presen_ary = str.gsub("\\/",'⁄').gsub("\\|","&\#65073").split(/\|/);
presen_ary.collect!{|s|
s = '"' + s.gsub('/',' ') + '"'
}
presen_str = presen_ary.join(',')
return <
JavaScript Required.
《START》
HTML
end
tdiary-contrib-5.1.0/plugin/bitly.rb 0000664 0000000 0000000 00000002113 13570131474 0017417 0 ustar 00root root 0000000 0000000 #
# bitly.rb - shorten URL by bit.ly.
#
# usage: shorten_url_you_got = bitly( 'long_url' ) || long_url
# (because bitly returns nil sometime.)
#
# required some options below:
# @options['biyly.login'] : your login ID of bit.ly.
# @options['biyly.key'] : your API key of biy.ly.
#
# Copyright (C) 2010, TADA Tadashi
# You can redistribute it and/or modify it under GPL.
#
require 'json'
require 'net/http'
def bitly( long_url )
return nil if !long_url or long_url.empty?
@bitly_cache ||= {} # cached only on memory
return @bitly_cache[long_url] if @bitly_cache[long_url]
login = @conf['bitly.login']
key = @conf['bitly.key']
# proxy
px_host, px_port = (@conf['proxy'] || '').split( /:/ )
px_port = 80 if px_host and !px_port
query = "/v3/shorten?longUrl=#{CGI::escape long_url}&login=#{login}&apiKey=#{key}&format=json"
begin
Net::HTTP.version_1_2
res = Net::HTTP::Proxy(px_host, px_port).get('api.bit.ly', "#{query}")
@bitly_cache[long_url] = JSON::parse(res, &:read)['data']['url']
rescue TypeError => te# biy.ly returns an error.
nil
end
end
tdiary-contrib-5.1.0/plugin/bootstrap-navi.rb 0000664 0000000 0000000 00000002571 13570131474 0021254 0 ustar 00root root 0000000 0000000 # Show navi for twitter-bootstrap theme
#
# Copyright (c) KAOD Masanori
# You can redistribute it and/or modify it under GPL.
def bootstrap_navi(options = {})
default_options = {
:navbar_class => nil,
:site_name? => true,
:search_form? => true
}
options = default_options.merge(options)
body = ""
if options[:site_name?]
body += <<-EOS
#{h @conf.html_title}
EOS
end
body += <<-EOS
#{navi_user.gsub(/span/, "li")}
#{navi_admin.gsub(/span/, "li")}
EOS
if options[:search_form?]
body += <<-EOS
EOS
end
<<-EOS
EOS
end
add_header_proc do
%Q| |
end
tdiary-contrib-5.1.0/plugin/brow_si.rb 0000664 0000000 0000000 00000001510 13570131474 0017740 0 ustar 00root root 0000000 0000000 #
# brow_si.rb: insert brow.si code
#
# Copyright (C) 2012 by hb
#
add_conf_proc( "brow_si", "Brow.si" ) do
if @mode == "saveconf"
@conf["brow.si.site_id"] = @cgi.params["brow.si.site_id"][0]
end
<<-HTML
Website Brow.si Site ID
HTML
end
add_footer_proc do
if @conf["brow.si.site_id"] and @conf.smartphone?
<<-SCRIPT
SCRIPT
end
end
tdiary-contrib-5.1.0/plugin/canonical.rb 0000664 0000000 0000000 00000000212 13570131474 0020221 0 ustar 00root root 0000000 0000000 # canonical.rb
if /latest/ =~ @mode then
add_header_proc do
<<-HTML
HTML
end
end
tdiary-contrib-5.1.0/plugin/category_similar.rb 0000664 0000000 0000000 00000004621 13570131474 0021637 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
# category_similar.rb:
# * shows similar posts under the diary
# * depends on plugin/category.rb
# You can redistribute it and/or modify it under the same license as tDiary.
def category_similar(categories, max_item)
info = Category::Info.new(@cgi, @years, @conf)
months = [['01', '02', '03'], ['04', '05', '06'], ['07', '08', '09'], ['10', '11', '12']][@date.strftime("%m").to_i / (3 + 1)] # quarter
years = { @date.strftime("%Y") => months }
hash = @category_cache.categorize(info.category, years)
items = []
hash.values_at(*categories).inject({}){|r, i|
r.merge i if !r.nil? and !i.nil?
}.to_a.each do |ymd_ary|
ymd = ymd_ary[0]
ary = ymd_ary[1]
next if ymd == @date.strftime('%Y%m%d')
t = Time.local(ymd[0,4], ymd[4,2], ymd[6,2]).strftime(@conf.date_format)
ary.each do |idx, title, excerpt|
items << %Q|#{t}#p#{'%02d' % idx} #{apply_plugin(title)}|
end
end
unless items.empty?
'' +
"
#{category_similar_label} " +
"
" +
items.sort.reverse[0, max_item].map{|i| "#{i}" }.join("\n") +
" " +
"
"
end
end
add_conf_proc('category_similar', category_similar_label, 'basic') do
if @mode == 'saveconf'
@conf["category_similar.excludes"] =
@cgi.params["category_similar.excludes"][0]
@conf["category_similar.section_amounts"] =
@cgi.params["category_similar.section_amounts"][0].to_i
end
<<-HTML
#{category_similar_label}
#{category_similar_excludes}
#{category_similar_amounts}
HTML
end
add_body_leave_proc do |date, idx|
diary = @diaries[date.strftime('%Y%m%d')]
if @mode =~ /day/ and diary.categorizable?
categories = []
diary.each_section do |s|
categories += s.categories unless s.categories.empty?
end
categories.delete_if do |i|
@conf['category_similar.excludes'].split(/\r?\n/).include? i
end
category_similar(categories, @conf['category_similar.section_amounts'])
end
end
# Local Variables:
# mode: ruby
# indent-tabs-mode: t
# tab-width: 3
# ruby-indent-level: 3
# End:
# vim: ts=3
tdiary-contrib-5.1.0/plugin/category_to_tag.rb 0000664 0000000 0000000 00000003054 13570131474 0021453 0 ustar 00root root 0000000 0000000 #
# category_to_tag.rb - show categories list in end of each section
#
# Copyright (C) 2005, TADA Tadashi
# You can redistribute it and/or modify it under GPL2.
#
if respond_to?( :categorized_title_of_day ) then # BlogKit
def categorized_title_of_day( date, title )
@category_to_tag_list = {}
cats, stripped = title.scan( /^((?:\[[^\]]+\])+)\s*(.*)/ )[0]
if cats then
cats.scan( /\[([^\]]+)\]+/ ).flatten.each do |tag|
@category_to_tag_list[tag] = true # true when blog
end
else
stripped = title
end
stripped
end
add_body_leave_proc do |date|
feed? ? '' : category_to_tag_list
end
elsif respond_to?( :category_anchor ) # diary
add_section_enter_proc do |date, index|
@category_to_tag_list = {}
''
end
alias subtitle_link_original subtitle_link
def subtitle_link( date, index, subtitle )
s = ''
if subtitle then
s = subtitle.sub( /^(\[([^\[]+?)\])+/ ) do
$&.scan( /\[(.*?)\]/ ) do |tag|
@category_to_tag_list[CGI::unescapeHTML(tag[0])] = false # false when diary
end
''
end
end
subtitle_link_original( date, index, s.strip )
end
add_section_leave_proc do |date, index|
feed? ? '' : category_to_tag_list
end
end
def category_to_tag_list
if @category_to_tag_list and not @category_to_tag_list.empty? then
r = '\n"
end
end
tdiary-contrib-5.1.0/plugin/category_to_tagcloud.rb 0000664 0000000 0000000 00000010354 13570131474 0022503 0 ustar 00root root 0000000 0000000 #
# category_to_tagcloud.rb
#
# Usage:
# <% tag_list n %>
# n: 表示最大数(default: nil)
#
# options configurable through settings:
# @options['tagcloud.hidecss'] : cssの出力 default: false
#
# This plugin modifes and includes tagcloud-ruby.
# http://yatsu.info/articles/2005/08/05/ruby%E3%81%A7tagcloud-tagcloud-ruby
require 'pstore'
def category_enable?
!@plugin_files.grep(/\/category\-legacy\.rb$/).empty?
end
def add tag, url, count, elapsed_time
@counts[tag] = count
@urls[tag] = url
@elapsed_times[tag] = elapsed_time
end
def print_html
tags = @counts.sort_by {|a, b| b }.reverse.map {|a, b| a }
return '' if tags.empty?
tags = tags[0..@limit-1] if @limit
if tags.size == 1
tag = tags[0]
url = @urls[tag]
elapsed_time = @elapsed_times[tag]
return %{\n}
end
min = Math.sqrt(@counts[tags.last])
max = Math.sqrt(@counts[tags.first])
factor = 0
# special case all tags having the same count
if max - min == 0
min = min - 24
factor = 1
else
factor = 24 / (max - min)
end
html = %{}
tags.sort{|a,b| a.downcase <=> b.downcase}.each do |tag|
count = @counts[tag]
level = ((Math.sqrt(count) - min) * factor).to_i
html << %{#{tag} \n}
end
html << " "
html
end
def init_category_to_tagcloud
@counts = Hash.new
@urls = Hash.new
@elapsed_times = Hash.new
@conf['category_to_tagcloud.cache'] ||= "#{@cache_path}/category2tagcloud.cache"
@limit = nil
end
def tag_list limit = nil
return '' if bot?
return '' unless category_enable?
begin
init_category_to_tagcloud
cache = @conf['category_to_tagcloud.cache']
@limit = limit
PStore.new(cache).transaction(read_only=true) do |db|
break unless db.root?('tagcloud') or db.root?('last_update')
break if Time.now.strftime('%Y%m%d').to_i > db['last_update']
@counts = db['tagcloud'][0]
@urls = db['tagcloud'][1]
@elapsed_times = db['tagcloud'][2]
end
gen_tag_list if @urls.empty?
print_html
rescue TypeError
'category plugin does not support category_to_tagcloud plugin. use category_legacy plugin instead of categoty plugin.
'
end
end
def styleclass diff
c = ' old'
if diff > 30
c = " oldest"
elsif diff > 14
c = " older"
elsif diff < 7
c = " hot"
end
c
end
def gen_tag_list
init_category_to_tagcloud if @mode == 'append' or @mode == 'replace'
cache = @conf['category_to_tagcloud.cache']
info = Category::Tagcloud_Info.new(@cgi, @years, @conf)
categorized = @category_cache.categorize(info.category, info.years)
categorized.keys.each do |key|
count = categorized[key].size
ymd = categorized[key].keys.sort.reverse
diff = (Time.now - Time.local(ymd[0][0,4], ymd[0][4,2], ymd[0][6,2])) / 86400
url = "#{@conf.index}?category=#{CGI.escape(key)}"
add(key, url, count, "#{styleclass(diff.to_i)}")
end
PStore.new(cache).transaction do |db|
db['last_update'] = Time.now.strftime('%Y%m%d').to_i
db['tagcloud'] = [@counts, @urls, @elapsed_times]
end
end
def tagcloud_css
r = ''
r = "\t\n"
r
end
add_update_proc do
gen_tag_list if @mode == 'append' or @mode == 'replace'
end
add_header_proc do
tagcloud_css unless @conf['tagcloud.hidecss']
end
if category_enable?
module Category
class Tagcloud_Info < Info
def years
now_year = Time.now.year
now_month = Time.now.month
r = Hash.new
months = [
['01'],['01','02'],['01','02','03'],['02','03','04'],['03','04','05'],
['04','05','06'],['05','06','07'],['06','07','08'],['07','08','09'],
['08','09','10'],['09','10','11'],['10','11','12']
][now_month - 1]
r[now_year.to_s] = months
case now_month
when 1
r["#{now_year - 1}"] = ['11','12']
when 2
r["#{now_year - 1}"] = ['12']
end
r
end
end
end
end
## vim: ts=3
tdiary-contrib-5.1.0/plugin/cocomment.rb 0000664 0000000 0000000 00000001732 13570131474 0020266 0 ustar 00root root 0000000 0000000 # cocomment.rb $Revision: 1.6 $
#
# Copyright (C) 2006 by Hiroshi SHIBATA
# You can redistribute it and/or modify it under GPL2.
#
if @mode == 'day' and not bot?
add_body_enter_proc do |date|
<<-SCRIPT
SCRIPT
end
end
# Local Variables:
# mode: ruby
# indent-tabs-mode: t
# tab-width: 3
# ruby-indent-level: 3
# End:
# vi: ts=3 sw=3
tdiary-contrib-5.1.0/plugin/code-prettify.rb 0000664 0000000 0000000 00000000567 13570131474 0021065 0 ustar 00root root 0000000 0000000 # Source code embedded plugin for tDiary.
# Copyright (C) 2012 Koichiro Ohba
# License under MIT.
add_header_proc do
<<-EOS
EOS
end
def code(content, lang = nil)
<<-EOS
#{content}
EOS
end
tdiary-contrib-5.1.0/plugin/coderay.rb 0000664 0000000 0000000 00000003627 13570131474 0017735 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
#
# coderay.rb - easy syntax highlighting for selected languages
# refer to the URL below.
# http://coderay.rubychan.de/
#
# Copyright (C) 2013, tamoot
# You can redistribute it and/or modify it under GPL2.
#
require 'cgi'
require 'erb'
require 'coderay'
@coderay_default_css ||= ::CodeRay::Encoders[:html]::CSS.new(:default).stylesheet
def coderay(lang, text, options = {})
html = ::CodeRay.scan(text, lang).html(:line_numbers => :inline, :bold_every => false, :line_number_anchors => false)
%Q||
end
add_header_proc do
coderay_css = ''
if @conf['coderay.css.url'] && @conf['coderay.css.url'].size > 0
coderay_css = %Q| |
else
coderay_css = <<-STYLE
STYLE
end
coderay_css
end
add_conf_proc( 'coderay', 'CodeRay' ) do
if @mode == 'saveconf' then
@conf['coderay.css.url'] = @cgi.params['coderay.css.url'][0]
end
coderay_conf = <<-HTML
custom style
The stylesheet path is used instead of CodeRay default.
Path:
sample:
#{CGI::escape_html(' ')}
Print default stylesheet of CodeRay
1. The coderay command installed along with the CodeRay gem can print out a stylesheet for you.
bundle exec coderay stylesheet > /your/tdiary/path/coderay.css
2. Edit your stylesheet and modify permissions.
HTML
coderay_conf
end
# Local Variables:
# mode: ruby
# indent-tabs-mode: t
# tab-width: 3
# ruby-indent-level: 3
# End:
# vim: ts=3
tdiary-contrib-5.1.0/plugin/coderwall.rb 0000664 0000000 0000000 00000001463 13570131474 0020257 0 ustar 00root root 0000000 0000000 require 'open-uri'
require 'timeout'
require 'json'
def coderwall(name, size = [60, 60])
begin
cache = "#{@cache_path}/coderwall.json"
json = File.read(cache)
File::delete(cache) if Time::now > File::mtime( cache ) + 60*60*24
rescue Errno::ENOENT
begin
Timeout.timeout(10) do
json = open( "https://coderwall.com/#{name}.json" ) {|f| f.read }
end
open(cache, 'wb') {|f| f.write(json) }
rescue Timeout::Error
return ""
end
end
html = ''
JSON.parse(json)['badges'].each do |badge|
html << %Q|
|
end
html << '
'
end
# Local Variables:
# mode: ruby
# indent-tabs-mode: t
# tab-width: 3
# ruby-indent-level: 3
# End:
# vim: ts=3
tdiary-contrib-5.1.0/plugin/comment_pushbullet.rb 0000775 0000000 0000000 00000005351 13570131474 0022217 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
# comment_pushbullet.rb
#
# メールの代わりにPushbulletサービスを使ってツッコミを知らせる
# プラグインを有効にした上で、Access Tokenを設定する
#
# Options:
# 設定画面から指定できるもの
# @options['comment_pushbullet.access_token']
# 自分のPushbulletアカウントのAccess Token https://www.pushbullet.com/account
# 設定画面から指定できるもの(ツッコミメールと共通)
# @options['comment_mail.enable']
# メールを送るかどうかを指定する。true(送る)かfalse(送らない)。
# 無指定時はfalse。
# @options['comment_mail.header']
# メールのSubjectに使う文字列。振り分け等に便利なように指定する。
# 実際のSubjectは「指定文字列:日付-1」のように、日付とコメント番号が
# 付く。ただし指定文字列中に、%に続く英字があった場合、それを
# 日付フォーマット指定を見なす。つまり「日付」の部分は
# 自動的に付加されなくなる(コメント番号は付加される)。
# 無指定時には空文字。
#
# tdiary.confでのみ指定できるもの:
#
# Copyright (c) 2015 TADA Tadashi
# You can distribute this file under the GPL2 or any later version.
#
def comment_pushbullet
require 'pushbullet_ruby'
header = (@conf['comment_mail.header'] || '').dup
header << ":#{@conf.date_format}" unless /%[a-zA-Z%]/ =~ header
serial = @diaries[@date.strftime('%Y%m%d')].count_comments(true)
title = %Q|#{@date.strftime(header)}-#{serial} #{@comment.name}|
body = @comment.body.sub( /[\r\n]+\Z/, '' )
link = @conf.base_url + anchor(@date.strftime('%Y%m%d')) + '#c' + "%02d"%serial
client = PushbulletRuby::Client.new(@conf['comment_pushbullet.access_token'])
params = {title: title, url: link, body: body}
client.push_link(id: client.me, params: params)
end
add_update_proc do
comment_pushbullet if @mode == 'comment'
end
add_conf_proc( 'comment_mail', comment_mail_conf_label, 'tsukkomi' ) do
comment_mail_basic_setting
comment_mail_basic_html
end
add_conf_proc( 'comment_pushbullet', 'Pushbullet', 'tsukkomi' ) do
if @mode == 'saveconf' then
@conf['comment_pushbullet.access_token'], = @cgi.params['comment_pushbullet.access_token']
end
<<-HTML
Pushbullet Access Token
Access Token (see https://www.pushbullet.com/account )
HTML
end
# Local Variables:
# mode: ruby
# indent-tabs-mode: t
# tab-width: 3
# ruby-indent-level: 3
# End:
tdiary-contrib-5.1.0/plugin/datepicker.rb 0000664 0000000 0000000 00000001165 13570131474 0020415 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
#
# datepickr.rb - show jQuery UI datepicker
#
# Copyright (C) 2012, tamoot
# You can redistribute it and/or modify it under GPL.
#
#
# not support
#
return if feed?
if /\A(?:form|preview|append|edit|update)\z/ =~ @mode
enable_js('//ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js')
if @conf.lang == 'ja'
enable_js('//ajax.googleapis.com/ajax/libs/jqueryui/1/i18n/jquery.ui.datepicker-ja.min.js')
end
enable_js('datepicker.js')
end
# Local Variables:
# mode: ruby
# indent-tabs-mode: t
# tab-width: 3
# ruby-indent-level: 3
# End:
# vim: ts=3
tdiary-contrib-5.1.0/plugin/day2section.rb 0000664 0000000 0000000 00000000617 13570131474 0020527 0 ustar 00root root 0000000 0000000 #
# day2section.rb - tDiary plugin
#
# When a visitor accesses to day page without section anchor, navigate to first section.
#
# Copyright (c) MATSUOKA Kohei
# Distributed under the GPL
#
add_footer_proc do
if @mode == 'day'
<<-SCRIPT
SCRIPT
end
end
tdiary-contrib-5.1.0/plugin/del_footer.rb 0000664 0000000 0000000 00000005002 13570131474 0020416 0 ustar 00root root 0000000 0000000 =begin
delicious.rb
Delicious から その日付分のメモを取ってきて表示するプラグイン
tdiary.conf で以下を設定します。tDiaryの設定画面からも設定可能です。
@options['delicious.id'] = 'YOUR DELICIOUS ID HERE'
@options['delicious.pw'] = 'YOUR DELICIOUS PW HERE'
proxy は以下に設定します。
@options['amazon.proxy'] = 'PROXY_HOST:PORT'
reference:
* mm_footer.rb by ishinao san
* rss-show.rb (in Hiki) by TAKEUCHI Hitoshi san
* fujisan.rb by Michitaka Ohno.
=end
require 'net/https'
require 'rexml/document'
require 'fileutils'
def delicious_save_cache cache_file, file
FileUtils.mkdir_p "#{@cache_path}/delicious"
File.open("#{@cache_path}/delicious/#{cache_file}", 'w') do |f|
f.flock(File::LOCK_EX)
f.puts file
f.flock(File::LOCK_UN)
end
end
def delicious_parse_xml(xml)
posts = []
REXML::Document.new(xml).elements.each("posts/post") do |post|
post = <<-EOS
#{post.attribute("description").to_s}
EOS
posts << post.delete("\r\n")
end
return posts
end
def delicious_get_html(date = Date.now)
req = Net::HTTP::Get.new "/v1/posts/get?dt=#{date.strftime('%Y-%m-%d')}"
req.basic_auth @options['delicious.id'], @options['delicious.pw']
https = Net::HTTP.new('api.del.icio.us', 443)
https.use_ssl = true
parsed = https.start {|w|
response = w.request(req)
delicious_parse_xml(response.body)
}
delicious_save_cache date.strftime("%Y-%m-%d"), parsed
end
add_edit_proc do |date|
delicious_get_html date
nil
end
add_body_leave_proc do |date|
path = "#{@cache_path}/delicious/#{date.strftime('%Y-%m-%d')}"
ret = ''
if File.exist? path
File.open(path) do |file|
ret = <<-EOS
Delicious
EOS
end
end
ret
end
def delicious_init
@conf['delicious.id'] ||= ""
@conf['delicious.pw'] ||= ""
@conf['delicious.title'] ||= "Todey's URL Clip"
end
add_conf_proc( 'delicious', @delicious_label_conf ) do
delicious_conf_proc
end
def delicious_conf_proc
if @mode == 'saveconf' then
@conf['delicious.id'] = @cgi.params['delicious.id'][0]
@conf['delicious.pw'] = @cgi.params['delicious.pw'][0]
end
delicious_init
<<-HTML
#{@delicious_label_id}
#{@delicious_label_pw}
HTML
end
tdiary-contrib-5.1.0/plugin/description_from_body.rb 0000664 0000000 0000000 00000001113 13570131474 0022656 0 ustar 00root root 0000000 0000000 #
# description_from_body.rb - set meta description by first section's body in day mode
#
# Copyright (C) 2011, TADA Tadashi
# You can redistribute it and/or modify it under GPL.
#
alias description_tag_dfb_orig description_tag
def description_tag
if @mode == 'day' then
diary = @diaries[@date.strftime '%Y%m%d']
return '' unless diary
body = ''
diary.each_section do |sec|
body = remove_tag( apply_plugin( sec.body_to_html ) ).strip
break
end
%Q| |
else
description_tag_dfb_orig
end
end
tdiary-contrib-5.1.0/plugin/development.rb 0000664 0000000 0000000 00000000701 13570131474 0020617 0 ustar 00root root 0000000 0000000 # development.rb - utility methods for plugin developers
#
# Copyright (c) 2011 MATSUOKA Kohei
# You can redistribute it and/or modify it under GPL2.
#
# load standard version jquery.js instead of jquery.min.js
alias :jquery_tag_original :jquery_tag
def jquery_tag
jquery_tag_original.gsub(/\.min/, '')
end
# js cache clear by seconds.
def script_tag_query_string
"?#{TDIARY_VERSION}#{Time::now.strftime('%Y%m%d%H%M%S')}"
end
tdiary-contrib-5.1.0/plugin/editor.rb 0000664 0000000 0000000 00000000376 13570131474 0017573 0 ustar 00root root 0000000 0000000 #
# editor.rb - support writing using wiki/gfm notation.
#
# Copyright (c) 2012 MATSUOKA Kohei
# You can distribute it under GPL.
#
# load javascript
if /\A(form|edit|preview|showcomment)\z/ === @mode then
enable_js('editor.js')
end
tdiary-contrib-5.1.0/plugin/en/ 0000775 0000000 0000000 00000000000 13570131474 0016354 5 ustar 00root root 0000000 0000000 tdiary-contrib-5.1.0/plugin/en/add_bookmark.rb 0000664 0000000 0000000 00000000775 13570131474 0021327 0 ustar 00root root 0000000 0000000 # en/add_bookmark.rb $Revision 1.3 $
#
# English resource of add_bookmark.rb
# You can redistribute it and/or modify it under GPL2.
#
@add_bookmark_label = 'add to bookmark'
@add_bookmark_desc = 'Please check the link that wants to be displayed.'
@caption_delicious = 'add to del.icio.us'
@caption_hatena = 'add to Hatena bookmark'
@caption_livedoor = 'add to livedoor clip'
@caption_buzzurl = 'add to Buzzurl'
@bookmark_label = [
'del.icio.us',
'Hatena bookmark',
'livedoor Clip',
'Buzzurl'
]
tdiary-contrib-5.1.0/plugin/en/category-lite.rb 0000664 0000000 0000000 00000002527 13570131474 0021457 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
#
# en/category-lite.rb : tDiary plugin for show category pages (light edition)
#
# Copyright (C) 2015 TADA Tadashi
# Distributed under the GPL2 or any later version.
#
@category_conf_label = 'Category'
def category_conf_html
r = <<-HTML
Build category index
To use the category feature, you should build category index.
Check the box below and press OK to build category index.
Build category index
It takes several or several tens of second to create it. But your diaries are many or the server has low spec, it will be timeout. Rebuild index on off-line again.
Edit Support
Category names can be shown under the 'Article' form.
Flat List
Dropdown List/option>
Hide
HTML
r
end
# Local Variables:
# mode: ruby
# indent-tabs-mode: t
# tab-width: 3
# ruby-indent-level: 3
# End:
# vim: ts=3
tdiary-contrib-5.1.0/plugin/en/del_footer.rb 0000664 0000000 0000000 00000000424 13570131474 0021023 0 ustar 00root root 0000000 0000000 #
# English resource of delicious plugin $Revision: 1.0 $
#
# Copyright (C) 2006 SHIBATA Hiroshi
# You can redistribute it and/or modify it under GPL2.
#
@delicious_label_conf = 'del.icio.us'
@delicious_label_id = 'User ID'
@delicious_label_pw = 'Password'
tdiary-contrib-5.1.0/plugin/en/git-register.rb 0000664 0000000 0000000 00000000254 13570131474 0021307 0 ustar 00root root 0000000 0000000 @estraier_register_conf_label = 'Git'
@estraier_register_conf_header = 'commit all'
@estraier_register_conf_description = 'To commit all, check the box and submit \'OK\'.'
tdiary-contrib-5.1.0/plugin/en/livedoor_weather.rb 0000664 0000000 0000000 00000001752 13570131474 0022250 0 ustar 00root root 0000000 0000000 #
# English resource of livedoor_weather plugin $Revision$
#
# Copyright (C) 2006 SHIBATA Hiroshi
# You can redistribute it and/or modify it under GPL2.
#
#
# setting of tdiary.conf
# @options['lwws.city_id'] : City ID where weather information is specified.
#
@lwws_plugin_name = 'livedoor weather'
@lwws_label_city_id = 'City ID'
@lwws_desc_city_id = 'City ID where weather information is specified. Please select City ID from among Point definition table(RSS) '
@lwws_label_disp_item = 'View items'
@lwws_desc_disp_item = 'Please select the item to want to display.'
@lwws_icon_label = 'Icon'
@lwws_icon_desc = 'Weather information is displayed in the icon. '
@lwws_max_temp_label = 'Max Tempreture'
@lwws_min_temp_label = 'Min Tempreture'
@celsius_label = 'C'
@lwws_label_cache = 'Auto update of cache'
@lwws_desc_cache = 'Enable auto update.'
@lwws_desc_cache_time = 'Please set number of update time.'
tdiary-contrib-5.1.0/plugin/en/microsummary.rb 0000664 0000000 0000000 00000001004 13570131474 0021423 0 ustar 00root root 0000000 0000000 # ja/microsummary.rb
#
# Japanese resources for microsummary.rb
#
# Copyright (c) 2006 elytsllams
# Distributed under the GPL
#
if @mode == 'conf' || @mode == 'saveconf'
add_conf_proc( 'microsummary', 'Microsummary Generator' ) do
saveconf_microsummary
microsummary_init
<<-HTML
URI for microsummary generator XML
HTML
end
end
tdiary-contrib-5.1.0/plugin/en/nicovideo.rb 0000664 0000000 0000000 00000002742 13570131474 0020665 0 ustar 00root root 0000000 0000000 #
# ja/nicovideo.rb - Japanese resource
#
# Copyright (C) TADA Tadashi
# Distributed under GPL.
#
def nicovideo_feed( i )
<<-HTML
HTML
end
def nicovideo_html( i )
<<-HTML
#{h i[:title]} (#{i[:length].split(/:/).map{|j|'%02d' % j.to_i}.join(':')})
#{i[:date][0,10]} Posted
#{i[:view].scan(/\d+?(?=\d{3}*$)/).join(",")} Views
#{i[:comment_num].scan(/\d+?(?=\d{3}*$)/).join(",")} Comments
#{i[:mylist].scan(/\d+?(?=\d{3}*$)/).join(",")} Mylists
HTML
end
tdiary-contrib-5.1.0/plugin/en/openid.rb 0000664 0000000 0000000 00000000404 13570131474 0020155 0 ustar 00root root 0000000 0000000 # openid.rb: English resource
@openid_conf_label = 'OpenID'
@openid_service_label = 'OpenID Service'
@openid_service_desc = 'select your OpenID service name.'
@openid_id_label = 'Your ID'
@openid_id_desc = 'Specify your ID of OpenID service selected above.'
tdiary-contrib-5.1.0/plugin/en/profile.rb 0000664 0000000 0000000 00000000366 13570131474 0020346 0 ustar 00root root 0000000 0000000 #
# profile.rb: english resource of profile plugin for tDiary
#
# Copyright (C) 2017 by Tada, Tadashi
# Distributed under the GPL.
#
module ::Profile
module Service
class Gravatar < Base
HOST = 'en.gravatar.com'
end
end
end
tdiary-contrib-5.1.0/plugin/en/section_footer.rb 0000664 0000000 0000000 00000000551 13570131474 0021724 0 ustar 00root root 0000000 0000000 # section_footer.rb: English resource
@section_footer_delicious_label = "del.icio.us history for this entry"
@section_footer_hatenabm_label = "this entry on Hatena Bookmark"
@section_footer_ldclip_label = "this entry on livedoor clip"
@section_footer_buzzurl_label = "this entry on Buzzurl"
@section_footer_yahoobm_label = "this entry on Yahoo! JAPAN Bookmark"
tdiary-contrib-5.1.0/plugin/en/section_footer2.rb 0000664 0000000 0000000 00000000217 13570131474 0022005 0 ustar 00root root 0000000 0000000 # section_footer2.rb: English resource
@section_footer2_delicious_label = "Delicious history for this entry"
@section_footer2_locale = 'en_US'
tdiary-contrib-5.1.0/plugin/en/socialbutton.rb 0000664 0000000 0000000 00000000374 13570131474 0021413 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
# section_footer2.rb: English resource
@socialbutton_label_conf = 'Social buttons'
@socialbutton_label_enables = 'enable social button names'
@socialbutton_label_twitter_via = 'screen name of the user to attribute the tweet to'
tdiary-contrib-5.1.0/plugin/everytrail.rb 0000664 0000000 0000000 00000001023 13570131474 0020461 0 ustar 00root root 0000000 0000000 #
# everytrail.rb: everytrail plugin is obsoleted
#
def everytrail_obsoleted(label = nil)
if label
"(EveryTrail is obsoleted. [#{h label}])
"
else
"(EveryTrail is obsoleted.)
"
end
end
def everytrail( trip_id, label = nil, size = [400, 300] )
everytrail_obsoleted(label)
end
def everytrail_flash( trip_id, label = nil, size = [400, 300] )
everytrail_obsoleted(label)
end
def everytrail_widget( trip_id, latitude = nil, longtitude = nil, label = nil, size = [400, 300] )
everytrail_obsoleted()
end
tdiary-contrib-5.1.0/plugin/facebook_comments.rb 0000664 0000000 0000000 00000004040 13570131474 0021753 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
# Copyright (C) 2011, KADO Masanori
# You can redistribute it and/or modify it under GPL.
add_header_proc do
<<-HTML
HTML
end
def facebook_comments(href = '')
<<-HTML
HTML
end
add_body_leave_proc do |date|
if @mode == 'day'
href = @conf.base_url + anchor( @date.strftime('%Y%m%d') )
facebook_comments(href)
end
end
add_conf_proc( 'Facebook Comments', 'Facebook Comments', 'etc' ) do
if @mode == 'saveconf' then
@conf['facebook_comments.YOUR_FACEBOOK_USER_ID'] =
@cgi.params['facebook_comments.YOUR_FACEBOOK_USER_ID'][0]
@conf['facebook_comments.YOUR_APPLICATION_ID'] =
@cgi.params['facebook_comments.YOUR_APPLICATION_ID'][0]
@conf['facebook_comments.num_posts'] =
@cgi.params['facebook_comments.num_posts'][0]
@conf['facebook_comments.width'] =
@cgi.params['facebook_comments.width'][0]
end
<<-HTML
YOUR_FACEBOOK_USER_ID
YOUR_APPLICATION_ID
num posts
width
HTML
end
# Local Variables:
# mode: ruby
# indent-tabs-mode: t
# tab-width: 3
# ruby-indent-level: 3
# End:
# vim: ts=3
tdiary-contrib-5.1.0/plugin/flickr.rb 0000664 0000000 0000000 00000016544 13570131474 0017563 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
# show photo image on Flickr.com
#
# usage:
# flickr(photo_id[, size[, place]])
# - photo_id: The id of the photo to show.
# - size: Size of photo. (optional)
# Choose from square, thumbnail, small, medium, or large.
# - place: class name of img element. default is 'flickr'.
#
# flickr_left(photo_id[, size])
#
# flickr_right(photo_id[, size])
#
# options configurable through settings:
# @conf['flickr.apikey'] : a key for access Flickr API
# @conf['flickr.default_size'] : default image size
#
# Copyright (c) MATSUOKA Kohei
# Distributed under the GPL
#
require 'net/https'
require 'digest/md5'
require 'rexml/document'
@conf['flickr.apikey'] ||= 'f7e7fb8cc34e52db3e5af5e1727d0c0b'
@conf['flickr.default_size'] ||= 'medium'
if /\A(form|edit|preview|showcomment)\z/ === @mode then
enable_js('flickr.js')
add_js_setting('$tDiary.plugin.flickr')
add_js_setting('$tDiary.plugin.flickr.apiKey', %Q|'#{@conf['flickr.apikey']}'|)
add_js_setting('$tDiary.plugin.flickr.userId', %Q|'#{@conf['flickr.user_id']}'|)
end
def flickr(photo_id, size = nil, place = 'flickr')
if @conf['flickr.apikey'] == nil || @conf['flickr.apikey'].empty?
return '[ERROR] flickr.rb: API Key is not specified.'
end
size ||= @conf['flickr.default_size']
photo = flickr_photo_info(photo_id.to_s, size)
unless photo
return '[ERROR] flickr.rb: failed to get photo.'
end
%Q| |
end
def flickr_left(photo_id, size = nil)
flickr(photo_id, size, 'left')
end
def flickr_right(photo_id, size = nil)
flickr(photo_id, size, 'right')
end
def flickr_photo_info(photo_id, size)
photo = {}
begin
flickr_open('flickr.photos.getInfo', photo_id) {|f|
if defined?(Oga)
res = Oga.parse_xml(f)
photo[:page] = res.xpath('/rsp/photo/urls/url').text
photo[:title] = res.xpath('/rsp/photo/title').text
else
res = REXML::Document.new(f)
photo[:page] = res.elements['//rsp/photo/urls/url'].text
photo[:title] = res.elements['//rsp/photo/title'].text
end
}
flickr_open('flickr.photos.getSizes', photo_id) {|f|
if defined?(Oga)
res = Oga.parse_xml(f)
res.xpath('//rsp/sizes/size').each do |s|
if s.get('label').downcase == size.downcase
photo[:src] = s.get('source')
photo[:width] = s.get('width')
photo[:height] = s.get('height')
end
end
else
res = REXML::Document.new(f)
res.elements.each('//rsp/sizes/size') do |s|
if s.attributes['label'].downcase == size.downcase
photo[:src] = s.attributes['source']
photo[:width] = s.attributes['width']
photo[:height] = s.attributes['height']
end
end
end
}
rescue Exception => e
return nil
end
photo
end
def flickr_open(method, photo_id)
cache_dir = "#{@cache_path}/flickr"
Dir::mkdir(cache_dir) unless File::directory?(cache_dir)
file = "#{cache_dir}/#{photo_id}.#{method}"
if !File.exist?(file) || File.size(file) == 0
req = Flickr::Request.new(@conf['flickr.apikey'])
req['method'] = method
req['photo_id'] = photo_id
begin
Timeout.timeout(5) do
open(file, 'w') {|fout|
fout.puts req.open
}
end
rescue TimeoutError, OpenSSL::OpenSSLError => e
File.delete(file)
raise e
end
end
open(file) {|f| yield f }
end
# delete cache files
def flickr_clear_cache
cache_dir = "#{@cache_path}/flickr"
Dir.glob("#{cache_dir}/*.flickr.photos.{getInfo,getSizes}") do |cache|
# File.unlink(cache)
File.rename(cache, "#{cache}.org")
end
end
FLICKER_FORM_PID = 'plugin_flickr_pid'
if @conf['flickr.input_support']
add_edit_proc do |date|
<<-FORM
FORM
end
end
def flickr_slideshow(tag, id = nil)
id ||= @conf['flickr.id']
return unless id
%Q||
end
def flickr_slideshow_by_set(set_id)
return unless set_id
%Q||
end
module Flickr
class Request < Hash
def initialize(api_key, secret = nil)
self['api_key'] = api_key
@secret = secret
end
def open
Net::HTTP.version_1_2
https = Net::HTTP.new('www.flickr.com', 443)
https.use_ssl = true
https.start {
response = https.get(query)
response.body
}
end
def query
sign = @secret ? "&api_sig=#{signature}" : ''
base_path + sort.map{|key, val| "#{key}=#{val}" }.join('&') + sign
end
def signature
data = sort.map{|key, val| "#{key}#{val}" }.join
Digest::MD5.hexdigest("#{@secret}#{data}")
end
def base_path
'/services/rest/?'
end
end
class RequestAuth < Request
def base_path
'/services/auth/?'
end
end
end
tdiary-contrib-5.1.0/plugin/gist.rb 0000664 0000000 0000000 00000001012 13570131474 0017237 0 ustar 00root root 0000000 0000000 # show code snippet via gist.github.com
#
# usage:
# gist(gist_id)
# - gist_id: The id of the code snippet on gitst.github.com (e.g. 2056 for http://gist.github.com/2056)
#
# Copyright (c) KAKUTANI Shintaro
# Distributed under the GPL
def gist( gist_id )
gist_snippet_url = "http://gist.github.com/#{gist_id}"
return (<<-EOS).chomp
EOS
end
tdiary-contrib-5.1.0/plugin/git-register.rb 0000664 0000000 0000000 00000013526 13570131474 0020713 0 ustar 00root root 0000000 0000000 #!/usr/bin/env ruby
# -*- coding: utf-8 -*-
# git-register.rb
#
# Copyright (C) 2011 hajime miyauchi
# You can redistribute it and/or modify it under GPL2.
#
# tDiaryのデータを日別でGitに登録するプラグインです
#
# 1. プラグインディレクトリ(例: plugin)にgit-register.rbを設置。
# 2. プラグインディレクトリにja/git-register.rb、en/git-register.rbを設置。
# 3. tdiary.confにリポジトリを指定(リポジトリの場所を/var/git-respoと仮定)
# @options["git.repository_dir"] = "/var/git-repos"
# 4. リポジトリを作成(Apacheの起動ユーザをapacheと仮定)
# $ mkdir /var/git-repos
# $ cd /var/git-repos
# $ git init
# $ git config user.name "自分の名前"
# $ git config user.email "メールアドレス"
# $ chown apache.apache -R /var/git-repos
# 5. リポジトリに一括commit(tDiaryのインストールディレクトリを/var/www/tdiaryと仮定)
# $ cd /var/www/tdiary
# $ ruby --encoding=UTF-8 git-register.rb
#
mode = ""
if $0 == __FILE__
require 'cgi'
ARGV << '' # dummy argument against cgi.rb offline mode.
@cgi = CGI::new
mode = "CMD"
else
mode = "PLUGIN"
end
if mode == "PLUGIN"
add_body_leave_proc do |date|
end
end
unless $tdiary_git_register_loaded
$tdiary_git_register_loaded ||= true
if mode == "CMD"
tdiary_path = "."
tdiary_conf = "."
$stdout.sync = true
def usage
puts "git-register.rb"
puts " register to git index files from tDiary's database."
puts " usage: ruby --encoding=UTF-8 git-register.rb [-p ] [-c ]"
exit
end
require 'getoptlong'
parser = GetoptLong::new
parser.set_options(['--path', '-p', GetoptLong::REQUIRED_ARGUMENT], ['--conf', '-c', GetoptLong::REQUIRED_ARGUMENT])
begin
parser.each do |opt, arg|
case opt
when '--path'
tdiary_path = arg
when '--conf'
tdiary_conf = arg
end
end
rescue
usage
exit( 1 )
end
tdiary_conf = tdiary_path unless tdiary_conf
Dir::chdir( tdiary_conf )
begin
$:.unshift tdiary_path
require "#{tdiary_path}/tdiary"
rescue LoadError
$stderr.puts "git-register.rb: cannot load tdiary.rb. <#{tdiary_path}/tdiary>\n"
$stderr.puts " usage: ruby --encoding=UTF-8 git-register.rb [-p ] [-c ]"
exit( 1 )
end
end
module ::TDiary
#
# Register
#
class GitRegister < TDiaryBase
def initialize(repository_dir, diary)
@repository_dir = repository_dir
@diary = diary
@date = diary.date
end
def execute()
dir = @date.strftime("#{@repository_dir}%Y%m/")
Dir::mkdir( dir ) unless FileTest::directory?( dir )
td2_file = @date.strftime("#{dir}%Y%m%d.td2")
fh = File::open(td2_file, 'w')
fh.puts( "Date: #{@date}" )
fh.puts( "Title: #{@diary.title}" )
fh.puts( "Last-Modified: #{@diary.last_modified.to_i}" )
fh.puts( "Visible: #{@diary.visible? ? 'true' : 'false'}" )
fh.puts( "Format: #{@diary.style}" )
fh.puts
fh.puts( @diary.to_src.gsub( /\r/, '' ).gsub( /\n\./, "\n.." ) )
fh.close
# commit
require 'shellwords'
msg = "#{ENV['REMOTE_ADDR']} - #{ENV['REMOTE_HOST']}"
Dir.chdir("#{@repository_dir}") do
td2_file2 = @date.strftime("%Y%m/%Y%m%d.td2")
system("git add -- #{Shellwords.shellescape(td2_file2)}".untaint)
system("git commit -q -m \"#{msg}\" -- #{Shellwords.shellescape(td2_file2)}".untaint)
end
end
protected
def mode; 'day'; end
def cookie_name; ''; end
def cookie_mail; ''; end
def convert(str)
str
end
end
#
# Main
#
class GitRegisterMain < TDiaryBase
def initialize(conf)
super(CGI::new, 'day.rhtml', conf)
end
def execute(out = $stdout)
require 'fileutils'
repository_dir = @conf['git.repository_dir']
calendar
@years.keys.sort.reverse_each do |year|
out << "(#{year.to_s}/) "
@years[year.to_s].sort.reverse_each do |month|
@io.transaction(Time::local(year.to_i, month.to_i)) do |diaries|
diaries.sort.reverse_each do |day, diary|
out << diary.date.strftime('%m%d ')
GitRegister.new(repository_dir, diary).execute
end
false
end
end
end
end
end
end
if mode == "CMD"
begin
require 'cgi'
if TDiary::Config.instance_method(:initialize).arity != 0
# for tDiary 2.1 or later
cgi = CGI.new
conf = TDiary::Config::new(cgi)
else
# for tDiary 2.0 or earlier
conf = TDiary::Config::new
end
conf.header = ''
conf.footer = ''
conf.show_comment = true
conf.hide_comment_form = true
conf.show_nyear = false
def conf.bot?; true; end
TDiary::GitRegisterMain.new(conf).execute
rescue
print $!, "\n"
$@.each do |v|
print v, "\n"
end
exit( 1 )
end
puts
else
add_update_proc do
conf = @conf.clone
conf.header = ''
conf.footer = ''
conf.show_comment = true
conf.hide_comment_form = true
conf.show_nyear = false
def conf.bot?; true; end
repository_dir = @conf['git.repository_dir']
diary = @diaries[@date.strftime('%Y%m%d')]
TDiary::GitRegister.new(repository_dir, diary).execute
end
if !@conf['git.hideconf'] && (@mode == 'conf' || @mode == 'saveconf')
args = ['git_register', @git_register_conf_label]
args << 'update' if TDIARY_VERSION > '2.1.3'
add_conf_proc(*args) do
str = <<-HTML
#{@git_register_conf_header}
#{@git_register_conf_description}
HTML
if @mode == 'saveconf'
if @cgi.valid?( 'git_register_rebuild' )
str << 'The following diaries were registered.
'
out = ''
TDiary::GitRegisterMain.new(@conf).execute(out)
str << "#{out}
"
end
end
str
end
end
end
end # $tdiary_git_register_loaded
# Local Variables:
# mode: ruby
# indent-tabs-mode: t
# tab-width: 3
# ruby-indent-level: 3
# End:
tdiary-contrib-5.1.0/plugin/github_badge.rb 0000664 0000000 0000000 00000002023 13570131474 0020700 0 ustar 00root root 0000000 0000000 # Github Badge, by drnic plugin.
# http://drnicjavascript.rubyforge.org/github_badge/
#
# usage:
# github_badge(username, list_length, head, theme, title, show_all)
# - username: user name on github.com
# - list_length: project list length
# - theme: specify theme for badge. "white" or "black".
# - title: top text display on the badge.
# - show_all: 'Show All' message.
#
# Copyright (c) 2008 KAKUTANI Shintaro
# Distributed under the GPL
def github_badge( username, list_length = 10, head = "div", theme = "white", title = "My Projects", show_all = "Show all" )
return (<<-EOS).chomp
EOS
end
tdiary-contrib-5.1.0/plugin/github_link.rb 0000664 0000000 0000000 00000000406 13570131474 0020576 0 ustar 00root root 0000000 0000000 def gh_link(gh_identifier, text=nil)
text = gh_identifier.split('/').last if text.nil?
id_and_name, number = gh_identifier.split('#')
url = "https://github.com/#{id_and_name}"
url = url + "/issues/#{number}" if number
"#{h text} "
end
tdiary-contrib-5.1.0/plugin/goo_gl.rb 0000664 0000000 0000000 00000002063 13570131474 0017546 0 ustar 00root root 0000000 0000000 #
# goo_gl.rb - shorten URL by goo.gl
#
# usage: shorten_url_you_got = goo_gl( 'long_url' ) || long_url
#
# Copyright (C) 2011, tamoot
# You can redistribute it and/or modify it under GPL.
#
require 'json'
require 'net/https'
def goo_gl( long_url )
return nil if !long_url or long_url.empty?
# on memory
@goo_gl_cache ||= {} # cached only on memory
return @goo_gl_cache[long_url] if @goo_gl_cache[long_url]
# proxy
px_host, px_port = (@conf['proxy'] || '').split( /:/ )
px_port = 80 if px_host and !px_port
# params
params = {'longUrl' => long_url}.to_json
https = nil
begin
https = Net::HTTP::Proxy(px_host, px_port).new('www.googleapis.com', 443)
https.use_ssl = true
res, body = https.post("/urlshortener/v1/url", params, {'Content-Type' => 'application/json'})
@goo_gl_cache[long_url] = JSON::parse(body)["id"] if res.code == '200'
rescue Exception => e
# do nothing..
ensure
https.finish if https && https.started?
end
return @goo_gl_cache[long_url]
end
tdiary-contrib-5.1.0/plugin/google_adsense.rb 0000664 0000000 0000000 00000014270 13570131474 0021261 0 ustar 00root root 0000000 0000000 #
# Google AdSense plugin for tDiary
#
# Copyright (C) 2004 Kazuhiko
# You can redistribute it and/or modify it under GPL2.
#
# modified by TADA Tadashi
#
def google_adsense( layout = nil, slot = nil )
google_adsense_init( layout )
google_ad_client = "pub-3317603667498586"
google_ad_size = [
[468, 60], # 0
[120, 600], # 1
[728, 90], # 2
[300, 250], # 3
[125, 125], # 4
[160, 600], # 5
[120, 240], # 6
[180, 150], # 7
[250, 250], # 8
[336, 280], # 9
[200, 200], # 10
[234, 60] # 11
]
result = <<-EOF
EOF
result.gsub( /^\t+/, '' )
end
def google_adsense_init( layout )
if layout != nil then
@conf['google_adsense.layout'] = layout.to_i
else
@conf['google_adsense.layout'] = 0 unless @conf['google_adsense.layout']
end
@conf['google_adsense.layout'] = @conf['google_adsense.layout'].to_i
if @conf['google_adsense.layout'] < 0 or @conf['google_adsense.layout'] > 11 then
@conf['google_adsense.layout'] = 0
end
@conf['google_adsense.color.border'] = 'CCCCCC' unless @conf['google_adsense.color.border']
@conf['google_adsense.color.bg'] = 'FFFFFF' unless @conf['google_adsense.color.bg']
@conf['google_adsense.color.link'] = '000000' unless @conf['google_adsense.color.link']
@conf['google_adsense.color.url'] = '666666' unless @conf['google_adsense.color.url']
@conf['google_adsense.color.text'] = '333333' unless @conf['google_adsense.color.text']
end
add_section_leave_proc do |date,index|
if @mode == 'day' and index == 1 and @conf['google_adsense.slot'] then
%Q|#{google_adsense( 0, @conf['google_adsense.slot'] )}
|
else
''
end
end
# insert section target tags
add_body_enter_proc do |date|
"\n"
end
add_body_leave_proc do |date|
"\n"
end
add_conf_proc( 'google_adsense', 'Google AdSense' ) do
if @mode == 'saveconf' then
@conf['google_adsense.layout'] = @cgi.params['google_adsense.layout'][0].to_i
@conf['google_adsense.color.border'] = @cgi.params['google_adsense.color.border'][0]
@conf['google_adsense.color.bg'] = @cgi.params['google_adsense.color.bg'][0]
@conf['google_adsense.color.link'] = @cgi.params['google_adsense.color.link'][0]
@conf['google_adsense.color.url'] = @cgi.params['google_adsense.color.url'][0]
@conf['google_adsense.color.text'] = @cgi.params['google_adsense.color.text'][0]
else
google_adsense_init( nil )
end
<<-HTML
バナーのサイズ(#{@conf['google_adsense.layout']})
広告バナーのサイズは全部で12種類あります。お好きなサイズを選んでください。
横長微小・広告1つ(234x60)
横長小・広告2つ(468x60)
横長大・広告4つ(728x90)
方形微小・広告1つ(125x125)
方形小・広告2つ(200x200)
方形中・広告3つ(250x250)
矩形小・広告1つ(180x150)
矩形大・広告4つ(300x250)
矩形特大・広告4つ(336x280)
縦長小・広告2つ(120x240)
縦長中・広告4つ(120x600)
縦長大・広告5つ(160x600)
バナーの色
バナーの各パーツの色を指定できます。HTMLやCSSと同じ、6桁の16進数で指定します。
HTML
end
tdiary-contrib-5.1.0/plugin/google_analytics.rb 0000664 0000000 0000000 00000004200 13570131474 0021616 0 ustar 00root root 0000000 0000000 #
# Google Analytics plugin for tDiary
#
# Copyright (C) 2005 TADA Tadashi
# You can redistribute it and/or modify it under GPL2.
#
if /^(?:latest|day|month|nyear|search)$/ =~ @mode then
add_footer_proc do
google_analytics_insert_code
end
end
def google_analytics_insert_code
return '' unless @conf['google_analytics.profile']
<<-HTML
HTML
end
# UA-53836-1
add_conf_proc( 'google_analytics', 'Google Analytics' ) do
if @mode == 'saveconf' then
@conf['google_analytics.profile'] = @cgi.params['google_analytics.profile'][0]
@conf['google_analytics.amp.profile'] = @cgi.params['google_analytics.amp.profile'][0]
end
r = <<-HTML
Google Analytics Profile
set your Profile ID (NNNNN-N)
HTML
if defined? AMP
r << <<-HTML
Google Analytics Profile for AMP page
set your Profile ID (NNNNN-N) for AMP page
HTML
end
r
end
if defined? AMP
add_amp_header_proc do
%Q||
end
add_amp_body_enter_proc do
profile_id = %w(google_analytics.amp.profile google_analytics.profile).map {|key|
@conf[key]
}.find {|profile|
profile && !profile.empty?
}
<<-HTML
HTML
end
end
tdiary-contrib-5.1.0/plugin/google_map.rb 0000664 0000000 0000000 00000014215 13570131474 0020413 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
#
# google_map.rb - embeded Google Map for tDiary, use Google Maps JavaScript API V3.
# https://developers.google.com/maps/documentation/javascript/tutorial
#
# Copyright (C) 2010, tamoot
# You can redistribute it and/or modify it under GPL2.
#
def google_map(lat, lon, params = {})
params.merge!(:lat => lat, :lon => lon)
google_map_common(params)
end
def google_geomap(address, params = {})
params.merge!(:address => address)
google_map_common(params)
end
def google_map_common(params)
params[:id] ||= ''
params[:lat] ||= 0.0
params[:lon] ||= 0.0
params[:address] ||= nil
params[:zoom] ||= 10
params[:html] ||= nil
params[:title] ||= nil
params[:width] ||= 320
params[:height] ||= 240
params[:type] ||= :ROADMAP
params[:overview]||= false
if feed?
require 'cgi'
url = nil
if params[:lat].nonzero? && params[:lon].nonzero?
query = "#{params[:lat]},#{params[:lon]}"
url = %Q|https://maps.google.com/maps?q=#{CGI::escape(query)}|
elsif params[:address] != nil
query = params[:address]
url = %Q|https://maps.google.com/maps?q=#{CGI::escape(query)}|
end
return %Q|#{url} | if url
end
dom_id = "#{@gmap_date.strftime("%Y%m%d")}_#{@gmap_count}"
params.merge!(:id => dom_id)
@gmap_data << params
@gmap_count += 1
%Q|
|
end
add_header_proc do
if /\A(?:latest|day|month|nyear|preview)\z/ =~ @mode
%Q|\n|
end
end
add_body_enter_proc do |date|
@gmap_data = []
@gmap_date = date
@gmap_count = 0
''
end
add_body_leave_proc do |date|
gmap_scripts = ''
if !feed? && @gmap_data.any?
gmap_scripts = %Q|\n|
end
gmap_scripts
end
add_conf_proc('google_map', 'Google Maps', 'etc') do
if @mode == 'saveconf' then
@conf['google_map.key'], = @cgi.params['google_map.key']
end
<<-HTML
Google Maps API Key
API Key (see developers.google.com/maps )
HTML
end
def google_map_script(hash)
str = ''
str << %Q|google.maps.event.addDomListener(window, 'load', function() {\n|
str << %Q| var mapdiv = document.getElementById("#{hash[:id]}");\n|
str << %Q| if(mapdiv){\n|
str << %Q| var myOptions = {\n|
str << %Q| zoom: #{hash[:zoom]},\n|
str << %Q| overviewMapControl: #{hash[:overview]},\n|
str << %Q| overviewMapControlOptions: {\n|
str << %Q| opened: #{hash[:overview]}\n|
str << %Q| },\n|
str << %Q| center: new google.maps.LatLng(#{hash[:lat]}, #{hash[:lon]}),\n|
str << %Q| mapTypeId: google.maps.MapTypeId.#{hash[:type]},\n|
str << %Q| scaleControl: true\n|
str << %Q| };\n|
str << %Q| var gMap = new google.maps.Map(mapdiv, myOptions);\n|
# set Marker
if hash[:title]
str << %Q| var marker = new google.maps.Marker({\n|
str << %Q| position: new google.maps.LatLng(#{hash[:lat]}, #{hash[:lon]}),\n|
str << %Q| map: gMap,\n|
str << %Q| title: '#{hash[:title]}'\n|
str << %Q| });\n|
# set InfoWindow
if hash[:html]
str << %Q| var infowindow = new google.maps.InfoWindow({\n|
str << %Q| content: '#{hash[:html]} ',\n|
str << %Q| size: new google.maps.Size(350, 200)\n|
str << %Q| });\n|
str << %Q| infowindow.open(gMap, marker);\n|
end # :html
end # :title
str << %Q| };\n|
str << %Q|});\n|
str
end
def google_geomap_script(hash)
str = ''
str << %Q|google.maps.event.addDomListener(window, 'load', function() {\n|
str << %Q| var mapdiv = document.getElementById("#{hash[:id]}");\n|
str << %Q| if(mapdiv){\n|
str << %Q| var geocoder = new google.maps.Geocoder();\n|
str << %Q| if(geocoder) {\n|
str << %Q| geocoder.geocode( { 'address': '#{hash[:address]}'}, function(results, status) {\n|
str << %Q| if (status == google.maps.GeocoderStatus.OK) {\n|
str << %Q| var geoLat = results[0].geometry.location;\n|
str << %Q| var myOptions = {\n|
str << %Q| zoom: #{hash[:zoom]},\n|
str << %Q| overviewMapControl: #{hash[:overview]},\n|
str << %Q| overviewMapControlOptions: {\n|
str << %Q| opened: #{hash[:overview]}\n|
str << %Q| },\n|
str << %Q| center: geoLat,\n|
str << %Q| mapTypeId: google.maps.MapTypeId.#{hash[:type]},\n|
str << %Q| scaleControl: true\n|
str << %Q| };\n|
str << %Q| var gMap = new google.maps.Map(mapdiv, myOptions);\n|
# set Marker
if hash[:title]
str << %Q| var marker = new google.maps.Marker({\n|
str << %Q| position: geoLat,\n|
str << %Q| map: gMap,\n|
str << %Q| title: '#{hash[:title]}'\n|
str << %Q| });\n|
# set InfoWindow
if hash[:html]
str << %Q| var infowindow = new google.maps.InfoWindow({\n|
str << %Q| content: '#{hash[:html]} ',\n|
str << %Q| size: new google.maps.Size(350, 200)\n|
str << %Q| });\n|
str << %Q| infowindow.open(gMap, marker);\n|
end # :html
end # :title
str << %Q| }else{\n|
str << %Q| alert("Geocode was not successful for the following reason: " + status)\n|
str << %Q| }\n|
str << %Q| });\n|
str << %Q| }\n|
str << %Q| }\n|
str << %Q|});\n|
str
end
# Local Variables:
# mode: ruby
# indent-tabs-mode: t
# tab-width: 3
# ruby-indent-level: 3
# End:
# vim: ts=3
tdiary-contrib-5.1.0/plugin/google_photos.rb 0000664 0000000 0000000 00000006463 13570131474 0021160 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
# show Google Photos
#
# Copyright (c) MATSUOKA Kohei
# Distributed under the GPL
#
def google_photos(src, width, height, alt="photo", place="photo", scale=nil)
scale = scale || @conf['google_photos.scale'] || 100
width = width.to_i * (scale.to_f / 100)
height = height.to_i * (scale.to_f / 100)
%Q| |
end
def google_photos_left(src, width, height, alt="photo", scale=nil)
scale = scale || @conf['google_photos.scale'] || 100
width = width.to_i * (scale.to_f / 100)
height = height.to_i * (scale.to_f / 100)
google_photos(src, width, height, alt, 'left')
end
def google_photos_right(src, width, height, alt="photo", scale=nil)
scale = scale || @conf['google_photos.scale'] || 100
width = width.to_i * (scale.to_f / 100)
height = height.to_i * (scale.to_f / 100)
google_photos(src, width, height, alt, 'right')
end
if /\A(form|edit|preview|showcomment)\z/ === @mode then
enable_js('google_photos.js')
add_js_setting('$tDiary.plugin.google_photos')
add_js_setting('$tDiary.plugin.google_photos.api_key', @conf['google_photos.api_key'].to_json)
add_js_setting('$tDiary.plugin.google_photos.client_id', @conf['google_photos.client_id'].to_json)
add_footer_proc do
''
end
end
add_edit_proc do |date|
<<-FORM
FORM
end
add_conf_proc('google_photos', 'Googleフォト') do
if @mode == 'saveconf'
@conf['google_photos.api_key'] = @cgi.params['google_photos.api_key'][0]
@conf['google_photos.client_id'] = @cgi.params['google_photos.client_id'][0]
@conf['google_photos.scale'] = @cgi.params['google_photos.scale'][0]
@conf['google_photos.scale'] = 100 if @conf['google_photos.scale'].nil? || @conf['google_photos.scale'].empty?
end
r = <<-_HTML
概要
Googleフォトの写真を日記に表示します。
機能
Googleフォトの写真を選択して日記に貼り付ける
PC上の写真をGoogleフォトへアップロードする
制約事項
サムネイルを使用しているため、サイズが512pxまでしか表示できません
使い方
このプラグインを使うためには、Google Developers ConsoleからAPIキーと認証用クライアントIDを取得する必要があります。
手順はGoogleフォトプラグインを利用するためのAPIキーとクライアントIDの取得手順 を参考にしてください。
APIキー
認証用クライアントID
サムネイルからの縮小率 (単位%。数値1〜100)
_HTML
end
tdiary-contrib-5.1.0/plugin/google_sitemaps.rb 0000664 0000000 0000000 00000003461 13570131474 0021464 0 ustar 00root root 0000000 0000000 # google_sitemap.rb
# Copyright (c) 2006 http://d.bulkitem.com/
# Distributed under the GPL
add_update_proc do
require 'time'
headers = Array.new
header = Hash.new
Dir.glob(@conf.data_path + '/????/*.td2') { |data_file|
File.open(data_file) { |buffer|
buffer.each { |line|
line.strip!
if line == "." then
if header['visible'] then
headers.push(header.clone)
end
header.clear
end
if %r|^Date: ([0-9]+)$|i =~ line then
header['loc'] = sprintf(@conf['google_sitemaps.uri_format'], $1)
end
if %r|^Last-Modified: ([0-9]+)$|i =~ line then
header['lastmod'] = Time.at($1.to_i).iso8601
end
if %r|^Visible: (.+)$|i =~ line then
if $1.upcase == "TRUE" then
header['visible'] = true
else
header['visible'] = false
end
end
}
}
}
headers.sort! { |a, b| b['loc'] <=> a['loc']}
top_page_uri = File::dirname(@conf['google_sitemaps.uri_format']) + '/'
now_datetime = Time.now.iso8601
File.open(@conf['google_sitemaps.output_file'], 'w') do |fp|
fp.write %Q[\n]
fp.write %Q[\n]
fp.write %Q[ #{CGI::escapeHTML(top_page_uri)} #{now_datetime} \n]
headers.each { |entry|
fp.write %Q[ #{CGI::escapeHTML(entry['loc'])} #{entry['lastmod']} \n]
}
fp.write %Q[ \n]
end
end
def saveconf_google_sitemaps
if @mode == 'saveconf' then
@conf['google_sitemaps.uri_format'] = @cgi.params['google_sitemaps.uri_format'][0]
@conf['google_sitemaps.output_file'] = @cgi.params['google_sitemaps.output_file'][0]
end
end
tdiary-contrib-5.1.0/plugin/google_universal_analytics.rb 0000664 0000000 0000000 00000002475 13570131474 0023722 0 ustar 00root root 0000000 0000000 #
# Google Universal Analytics plugin for tDiary
#
# Copyright (C) 2014 TSUNEMATSU Shinya
# You can redistribute it and/or modify it under GPL2.
#
if /^(?:latest|day|month|nyear|search)$/ =~ @mode then
add_footer_proc do
google_universal_analytics_insert_code
end
end
def google_universal_analytics_insert_code
return '' unless @conf['google_universal_analytics.profile']
<<-HTML
HTML
end
# UA-53836-1
add_conf_proc( 'google_universal_analytics', 'Google Universal Analytics' ) do
if @mode == 'saveconf' then
@conf['google_universal_analytics.profile'] = @cgi.params['google_universal_analytics.profile'][0]
end
<<-HTML
Google Universal Analytics Profile
set your Profile ID (NNNNN-N)
HTML
end
tdiary-contrib-5.1.0/plugin/google_webmaster.rb 0000664 0000000 0000000 00000001407 13570131474 0021626 0 ustar 00root root 0000000 0000000 # encoding: utf-8
# google-webmaster.rb - embed a meta tag to let Google Webmaster tool know your verification code.
#
# Copyright (C) 2012, Tatsuya Sato
# You can redistribute it and/or modify it under GPL2.
#
add_header_proc do
" "
end
add_conf_proc('Google Webmaster', 'Google ウェブマスターツール', 'etc') do
if @mode == 'saveconf'
@conf['google_webmaster.verification'] = @cgi.params['google_webmaster.verification'][0]
end
<<-HTML
Google ウェブマスターツールの検証コード
HTML
end
tdiary-contrib-5.1.0/plugin/hatena_bookmark_nocomment.rb 0000664 0000000 0000000 00000000307 13570131474 0023503 0 ustar 00root root 0000000 0000000 # hatena_bookmark_nocomment.rb
#
# Copyright (c) 2008 SHIBATA Hiroshi
# Distributed under the GPL2
#
add_header_proc do
%Q| |
end
tdiary-contrib-5.1.0/plugin/hatena_star.rb 0000664 0000000 0000000 00000004415 13570131474 0020574 0 ustar 00root root 0000000 0000000 # hatena_star.rb
# Itoshi Nikaido
# Distributed under the GPL
@hatena_star_options = {
'token' => 'Token',
'star.image' => '.hatena-star-star-image',
'star.add' => '.hatena-star-add-button-image',
'comment.image' => '.hatena-star-comment-button-image'
}
add_header_proc do
hatena_star = %Q|\t\n|
hatena_star << %Q|\t\n|
hatena_star << %Q|\t\n|
end
add_conf_proc( 'hatena_star', 'Hatena::Star' ) do
if( @mode == 'saveconf' ) then
@hatena_star_options.keys.each do |o|
@conf["hatena_star.#{o}"] = @cgi.params["hatena_star.#{o}"][0].strip
if @conf["hatena_star.#{o}"].length == 0 then
@conf["hatena_star.#{o}"] = nil
end
end
end
<<-HTML
Token
Star Image (URL)
Add Star Image (URL)
Comment Image (URL)
HTML
end
tdiary-contrib-5.1.0/plugin/hb_footer.rb 0000664 0000000 0000000 00000014667 13570131474 0020264 0 ustar 00root root 0000000 0000000 #
# hb_footer.rb
#
# はてなブックマーク (http://b.hatena.ne.jp/) のコメントを該当日付に貼り付けるtDiaryプラグイン
# 改造版rss_recent Version 0.0.5i2と共に使用する
#
# Licence: GPL
# Author: ishinao
#
add_body_leave_proc do |date|
if @mode == 'day' or @mode == 'latest'
diary = @diaries[date.strftime('%Y%m%d')]
pnum = 1
hbsrc = ''
diary.each_section do |para|
td_url = "http://tdiary.ishinao.net/#{date.strftime('%Y%m%d')}.html%23p#{'%02d' % pnum}"
hb_url = "http://b.hatena.ne.jp/entry/#{td_url}"
rss_url = "http://b.hatena.ne.jp/entry/rss/#{td_url}"
template_head = %Q[\n"
cache_time = 3600;
if date.strftime('%Y-%m-%d') != Time.now.strftime('%Y-%m-%d')
cache_time = 3600 * 12;
end
hbsrc << hb_footer(rss_url, 50, cache_time, template_head, template_list, template_foot)
pnum+=1
end
hbsrc
else
''
end
end
# rss-recent.rb: RSS recent plugin
#
# rss_recnet: show recnet list from RSS
# parameters (default):
# url: URL of RSS
# max: max of list itmes(5)
# cache_time: cache time(second) of RSS(60*60)
# template_head: rendering header part
# template_list: rendering RSS item part(with loop)
# template_foot: rendering footer part
#
# Copyright (c) 2003-2004 Kouhei Sutou
# Distributed under the GPL
#
# Modified using template string and content:encoded
# Version 0.0.5i2 by ishinao
#
require "rss/rss"
RSS_RECENT_FIELD_SEPARATOR = "\0"
RSS_RECENT_ENTRY_SEPARATOR = "\1"
RSS_RECENT_VERSION = "0.0.5i2"
RSS_RECENT_HTTP_HEADER = {
"User-Agent" => "tDiary RSS recent plugin version #{RSS_RECENT_VERSION}. " <<
"Using RSS parser version is #{::RSS::VERSION}.",
}
def hb_footer(url, max = 5, cache_time = 3600, \
template_head = "\n", \
template_list = ' \n', \
template_foot = " \n")
url.untaint
cache_file = "#{@cache_path}/rss-recent.#{CGI.escape(url)}"
hb_footer_cache_rss(url, cache_file, cache_time.to_i)
return '' unless test(?r, cache_file)
rv = template_head
i = 0
hb_footer_read_from_cache(cache_file).each do |title, url, time, content, description|
break if i >= max
next if (url.nil? or title.nil?)
rv << eval('%Q[' + template_list + ']')
i += 1
end
rv << template_foot
if i > 0
rv
else
''
end
end
class InvalidResourceError < StandardError; end
def hb_footer_cache_rss(url, cache_file, cache_time)
cached_time = nil
cached_time = File.mtime(cache_file) if File.exist?(cache_file)
if cached_time.nil? or Time.now > cached_time + cache_time
require 'time'
require 'open-uri'
require 'net/http'
require 'uri/generic'
require 'rss/parser'
require 'rss/1.0'
require 'rss/2.0'
require 'rss/dublincore'
require 'rss/content'
begin
uri = URI.parse(url)
raise URI::InvalidURIError if uri.scheme != "http"
rss_source = hb_footer_fetch_rss(uri, cached_time)
raise InvalidResourceError if rss_source.nil?
# parse RSS
rss = ::RSS::Parser.parse(rss_source, false)
raise ::RSS::Error if rss.nil?
# pre processing
begin
rss.output_encoding = @conf.charset || charset
rescue ::RSS::UnknownConversionMethodError
end
rss_infos = rss.items.collect do |item|
hb_footer_pubDate_to_dc_date(item)
[item.title, item.link, item.dc_date, item.content_encoded, item.description]
end
hb_footer_write_to_cache(cache_file, rss_infos)
rescue URI::InvalidURIError
hb_footer_write_to_cache(cache_file, [['Invalid URI', url]])
rescue InvalidResourceError, ::RSS::Error
# hb_footer_write_to_cache(cache_file, [['Invalid Resource', url]])
# when cannot get valid RSS, use old cache
end
end
end
def hb_footer_fetch_rss(uri, cache_time)
rss = nil
begin
uri.open(hb_footer_http_header(cache_time)) do |f|
case f.status.first
when "200"
rss = f.read
# STDERR.puts "Got RSS of #{uri}"
when "304"
# not modified
# STDERR.puts "#{uri} does not modified"
else
raise InvalidResourceError
end
end
rescue TimeoutError, SocketError, StandardError,
SecurityError # occured in redirect
raise InvalidResourceError
end
rss
end
def hb_footer_http_header(cache_time)
header = RSS_RECENT_HTTP_HEADER.dup
if cache_time.respond_to?(:rfc2822)
header["If-Modified-Since"] = cache_time.rfc2822
end
header
end
def hb_footer_write_to_cache(cache_file, rss_infos)
File.open(cache_file, 'w') do |f|
f.flock(File::LOCK_EX)
rss_infos.each do |info|
f << info.join(RSS_RECENT_FIELD_SEPARATOR)
f << RSS_RECENT_ENTRY_SEPARATOR
end
f.flock(File::LOCK_UN)
end
end
def hb_footer_read_from_cache(cache_file)
require 'time'
infos = []
File.open(cache_file) do |f|
while info = f.gets(RSS_RECENT_ENTRY_SEPARATOR)
info = info.chomp(RSS_RECENT_ENTRY_SEPARATOR)
infos << info.split(RSS_RECENT_FIELD_SEPARATOR)
end
end
infos.collect do |title, url, time, content, description|
[
hb_footer_convert(title),
hb_footer_convert(url),
hb_footer_convert(time) {|time| Time.parse(time)},
hb_footer_convert(content),
hb_footer_convert(description),
]
end
end
def hb_footer_convert(str)
if str.nil? or str.empty?
nil
else
if block_given?
yield str
else
str
end
end
end
# from RWiki
def hb_footer_modified(t)
return '-' unless t
dif = (Time.now - t).to_i
dif = dif / 60
return "#{dif}m" if dif <= 60
dif = dif / 60
return "#{dif}h" if dif <= 24
dif = dif / 24
return "#{dif}d"
end
# from RWiki
def hb_footer_modified_class(t)
return 'dangling' unless t
dif = (Time.now - t).to_i
dif = dif / 60
return "modified-hour" if dif <= 60
dif = dif / 60
return "modified-today" if dif <= 24
dif = dif / 24
return "modified-month" if dif <= 30
return "modified-year" if dif <= 365
return "modified-old"
end
def hb_footer_pubDate_to_dc_date(target)
if target.respond_to?(:pubDate)
class << target
alias_method(:dc_date, :pubDate)
end
end
end
tdiary-contrib-5.1.0/plugin/hb_footer4sec.rb 0000664 0000000 0000000 00000014470 13570131474 0021033 0 ustar 00root root 0000000 0000000 #
# hb_footer.rb
#
# はてなブックマーク (http://b.hatena.ne.jp/) のコメントを該当セクションに貼り付けるtDiaryプラグイン
# 改造版rss_recent Version 0.0.5i2と共に使用する
#
# Licence: GPL
# Author: ishinao
#
add_section_leave_proc do |date, index|
td_url = "http://tdiary.ishinao.net/#{date.strftime('%Y%m%d')}.html%23p#{'%02d' % index}"
hb_url = "http://b.hatena.ne.jp/entry/#{td_url}"
rss_url = "http://b.hatena.ne.jp/entry/rss/#{td_url}"
template_head = %Q[\n"
cache_time = 3600;
if date.strftime('%Y-%m-%d') != Time.now.strftime('%Y-%m-%d')
cache_time = 3600 * 12;
end
hb_footer4sec(rss_url, 50, cache_time, template_head, template_list, template_foot)
end
# rss-recent.rb: RSS recent plugin
#
# rss_recnet: show recnet list from RSS
# parameters (default):
# url: URL of RSS
# max: max of list itmes(5)
# cache_time: cache time(second) of RSS(60*60)
# template_head: rendering header part
# template_list: rendering RSS item part(with loop)
# template_foot: rendering footer part
#
# Copyright (c) 2003-2004 Kouhei Sutou
# Distributed under the GPL
#
# Modified using template string and content:encoded
# Version 0.0.5i2 by ishinao
#
require "rss/rss"
RSS_RECENT_FIELD_SEPARATOR = "\0"
RSS_RECENT_ENTRY_SEPARATOR = "\1"
RSS_RECENT_VERSION = "0.0.5i2"
RSS_RECENT_HTTP_HEADER = {
"User-Agent" => "tDiary RSS recent plugin version #{RSS_RECENT_VERSION}. " <<
"Using RSS parser version is #{::RSS::VERSION}.",
}
def hb_footer4sec(url, max = 5, cache_time = 3600, \
template_head = "\n", \
template_list = ' \n', \
template_foot = " \n")
url.untaint
cache_file = "#{@cache_path}/rss-recent.#{CGI.escape(url)}"
hb_footer4sec_cache_rss(url, cache_file, cache_time.to_i)
return '' unless test(?r, cache_file)
rv = template_head
i = 0
hb_footer4sec_read_from_cache(cache_file).each do |title, url, time, content, description|
break if i >= max
next if (url.nil? or title.nil?)
rv << eval('%Q[' + template_list + ']')
i += 1
end
rv << template_foot
if i > 0
rv
else
''
end
end
class InvalidResourceError < StandardError; end
def hb_footer4sec_cache_rss(url, cache_file, cache_time)
cached_time = nil
cached_time = File.mtime(cache_file) if File.exist?(cache_file)
if cached_time.nil? or Time.now > cached_time + cache_time
require 'time'
require 'open-uri'
require 'net/http'
require 'uri/generic'
require 'rss/parser'
require 'rss/1.0'
require 'rss/2.0'
require 'rss/dublincore'
require 'rss/content'
begin
uri = URI.parse(url)
raise URI::InvalidURIError if uri.scheme != "http"
rss_source = hb_footer4sec_fetch_rss(uri, cached_time)
raise InvalidResourceError if rss_source.nil?
# parse RSS
rss = ::RSS::Parser.parse(rss_source, false)
raise ::RSS::Error if rss.nil?
# pre processing
begin
rss.output_encoding = @conf.charset || charset
rescue ::RSS::UnknownConversionMethodError
end
rss_infos = rss.items.collect do |item|
hb_footer4sec_pubDate_to_dc_date(item)
[item.title, item.link, item.dc_date, item.content_encoded, item.description]
end
hb_footer4sec_write_to_cache(cache_file, rss_infos)
rescue URI::InvalidURIError
hb_footer4sec_write_to_cache(cache_file, [['Invalid URI', url]])
rescue InvalidResourceError, ::RSS::Error
# hb_footer4sec_write_to_cache(cache_file, [['Invalid Resource', url]])
# when cannot get valid RSS, use old cache
end
end
end
def hb_footer4sec_fetch_rss(uri, cache_time)
rss = nil
begin
uri.open(hb_footer4sec_http_header(cache_time)) do |f|
case f.status.first
when "200"
rss = f.read
# STDERR.puts "Got RSS of #{uri}"
when "304"
# not modified
# STDERR.puts "#{uri} does not modified"
else
raise InvalidResourceError
end
end
rescue TimeoutError, SocketError, StandardError,
SecurityError # occured in redirect
raise InvalidResourceError
end
rss
end
def hb_footer4sec_http_header(cache_time)
header = RSS_RECENT_HTTP_HEADER.dup
if cache_time.respond_to?(:rfc2822)
header["If-Modified-Since"] = cache_time.rfc2822
end
header
end
def hb_footer4sec_write_to_cache(cache_file, rss_infos)
File.open(cache_file, 'w') do |f|
f.flock(File::LOCK_EX)
rss_infos.each do |info|
f << info.join(RSS_RECENT_FIELD_SEPARATOR)
f << RSS_RECENT_ENTRY_SEPARATOR
end
f.flock(File::LOCK_UN)
end
end
def hb_footer4sec_read_from_cache(cache_file)
require 'time'
infos = []
File.open(cache_file) do |f|
while info = f.gets(RSS_RECENT_ENTRY_SEPARATOR)
info = info.chomp(RSS_RECENT_ENTRY_SEPARATOR)
infos << info.split(RSS_RECENT_FIELD_SEPARATOR)
end
end
infos.collect do |title, url, time, content, description|
[
hb_footer4sec_convert(title),
hb_footer4sec_convert(url),
hb_footer4sec_convert(time) {|time| Time.parse(time)},
hb_footer4sec_convert(content),
hb_footer4sec_convert(description),
]
end
end
def hb_footer4sec_convert(str)
if str.nil? or str.empty?
nil
else
if block_given?
yield str
else
str
end
end
end
# from RWiki
def hb_footer4sec_modified(t)
return '-' unless t
dif = (Time.now - t).to_i
dif = dif / 60
return "#{dif}m" if dif <= 60
dif = dif / 60
return "#{dif}h" if dif <= 24
dif = dif / 24
return "#{dif}d"
end
# from RWiki
def hb_footer4sec_modified_class(t)
return 'dangling' unless t
dif = (Time.now - t).to_i
dif = dif / 60
return "modified-hour" if dif <= 60
dif = dif / 60
return "modified-today" if dif <= 24
dif = dif / 24
return "modified-month" if dif <= 30
return "modified-year" if dif <= 365
return "modified-old"
end
def hb_footer4sec_pubDate_to_dc_date(target)
if target.respond_to?(:pubDate)
class << target
alias_method(:dc_date, :pubDate)
end
end
end
tdiary-contrib-5.1.0/plugin/hb_footer4sec_js.rb 0000664 0000000 0000000 00000001671 13570131474 0021526 0 ustar 00root root 0000000 0000000 # hb_footer4sec_js.rb $Revision 1.0 $
#
# Copyright (c) 2008 SHIBATA Hiroshi
# You can redistribute it and/or modify it under GPL2.
#
def permalink( date, index, escape = true )
ymd = date.strftime( "%Y%m%d" )
uri = @conf.index.dup
uri.sub!( %r|\A(?!https?://)|i, @conf.base_url )
uri.gsub!( %r|/\.(?=/)|, "" ) # /././ -> /
link = uri + anchor( "#{ymd}p%02d" % index )
link.sub!( "#", "%23" ) if escape
link
end
add_section_leave_proc do |date, index|
if @mode == 'day' and not bot?
<<-SCRIPT
SCRIPT
end
end
tdiary-contrib-5.1.0/plugin/hide_comment_form.rb 0000664 0000000 0000000 00000000105 13570131474 0021751 0 ustar 00root root 0000000 0000000 def hide_comment_form
@conf.hide_comment_form = true
return ''
end
tdiary-contrib-5.1.0/plugin/hide_sidebar_smartphone.rb 0000664 0000000 0000000 00000000266 13570131474 0023145 0 ustar 00root root 0000000 0000000 # hide_sidebar_smartphone.rb
#
# Copyright (C) 2011 by TADA Tadashi
# You can distribute it under GPL2 or any later version.
#
enable_js( 'hide_sidebar_smartphone.js' )
tdiary-contrib-5.1.0/plugin/iddy.rb 0000664 0000000 0000000 00000004567 13570131474 0017244 0 ustar 00root root 0000000 0000000 #
# iddy.rb: iddy.jp plugin for tDiary
#
# Copyright (C) 2007 by TADA Tadashi
# Distributed under GPL.
#
######################################################################
# If you will modify or release another version of this code,
# please get your own application key from iddy.jp and replace below.
######################################################################
@iddy_key = 'f93d2f38442fae3a1f08e82f84d335112cca0855'
require 'open-uri'
require 'timeout'
require 'rexml/document'
def iddy( id )
begin
cache = "#{@cache_path}/iddy.xml"
xml = open( cache ) {|f| f.read }
if Time::now > File::mtime( cache ) + 60*60 then
File::delete( cache ) # clear cache 1 hour later
end
rescue Errno::ENOENT
begin
xml = iddy_call_api( id, @iddy_key )
open( cache, 'wb' ) {|f| f.write( xml ) }
rescue Timeout::Error
return 'No data.
'
end
end
doc = REXML::Document::new( xml )
if doc.elements[1].attribute( 'status' ).to_s == 'fail' then
return 'iddy.jp returns fail.
'
end
user = doc.elements.to_a( '*/*/user' )[0].elements
profileurl = user.to_a( 'profileurl' )[0]
unless profileurl then
return 'No profile URL on iddy.jp.
'
end
imageurl = user.to_a( 'imageurl' )[0]
name = user.to_a( 'name' )[0]
nameroma = user.to_a( 'nameroma' )[0]
mail = user.to_a( 'mail' )[0]
submail = user.to_a( 'submail' )[0]
html = ''
@conf.to_native( html )
end
def iddy_call_api( id, key )
request = "http://iddy.jp/api/user/?apikey=#{key}"
request << "&accountname=#{id}"
proxy = @conf['proxy']
proxy = 'http://' + proxy if proxy
Timeout.timeout( 3 ) do
open( request, :proxy => proxy ) {|f| f.read }
end
end
tdiary-contrib-5.1.0/plugin/image_ex.rb 0000664 0000000 0000000 00000035372 13570131474 0020067 0 ustar 00root root 0000000 0000000 # coding: utf-8
# image_plugin_ex.rb
# version 0.3
# -pv-
#
# 名称:
# 絵日記Plugin機能追加版
#
# 概要:
# 日記更新画面からの画像アップロード、サムネイル作成、本文への表示
#
# 使う場所:
# 本文
#
# 使い方:
# image( number, 'altword', thumbnail ) - 画像を表示します。
# number - 画像の番号0、1、2等
# altword - imgタグの altに入れる文字列
# thumbnail - サムネイル(小さな画像)を指定する(省略可)
#
# image_left( number, 'altword', thumbnail ) - imageにclass=leftを追加します。
# image_right( number, 'altword', thumbnail ) - imageにclass=rightを追加します。
#
# image_link( number, 'desc' ) - 画像へのリンクを生成します。
# number - 画像の番号0、1、2等
# desc - 画像の説明
#
# その他:
# tDiary version 1.5.4以降で動作します。
# tdiary.confで、
# 画像ファイルを保存するディレクトリ
# @options['image.dir']
# 画像ファイルのURL
# @options['image.url']
# 縮小画像の生成方法
# @options['image.url']
# 0 - 縮小画像を生成しない
# 1 - ImageMagickのconvertで縮小画王を生成
# 2 - netpbm群で縮小画王を生成
# を設定してください。
# また、@secure = trueな環境では動作しません。
#
# 詳しくは、
# http://shimoi.s26.xrea.com/hiki/hiki.xcg?TdiaryEnikkiEx
# をご覧下さい。
#
# ライセンスについて:
# Copyright (c) 2002 Daisuke Kato
# Copyright (c) 2002 Toshi Okada
# Copyright (c) 2003 Yoshimi KURUMA
#
# You can redistribute it and/or modify it under GPL2.
#
=begin Changelog
2003-05-16 Yoshimi KURUMA
* method 'image' is extended to show a thumbnail.
* new method: 'image_link'.
* version 0.3
2003-05-16 Yoshimi KURUMA
* modify illegal option names.
* version 0.2.
2003-05-16 Yoshimi KURUMA
* support manual upload of thumbnail when useresize == 0
2003-04-27 Yoshimi KURUMA
* link element is removed when no thumbnail.
2003-04-25 Yoshimi KURUMA
* add JavaScript for insert plugin tag into diary.
* upload/delete form style changed.
2003-04-24 Yoshimi KURUMA
* upload/delete form style changed.
2003-04-22 Yoshimi KURUMA
* version 0.1 first form_proc version.
=end
@image_dir = @options && @options['image.dir'] || './images/'
@image_dir.chop! if /\/$/ =~ @image_dir
@image_url = @options && @options['image.url'] || './images/'
@image_url.chop! if /\/$/ =~ @image_url
@imageex_thumbnailsize = @options && @options['image_ex.previewsize'] || 120
@imageex_yearlydir = @options && @options['image_ex.yearlydir'] || 0
enable_js("image_ex.js")
add_body_enter_proc do |date|
@image_date = date.strftime("%Y%m%d")
@image_year = date.strftime("%Y")
""
end
def image( id, alt = "image", id2 = nil, width = nil, place="none" )
@image_date ||= @date.strftime("%Y%m%d")
@image_year ||= @date.strftime("%Y")
if @imageex_yearlydir == 1
image_url = %Q[#{@image_url}/#{@image_year}/]
image_dir = %Q[#{@image_dir}/#{@image_year}/]
else
image_url = %Q[#{@image_url}/]
image_dir = %Q[#{@image_dir}/]
end
image_dir.untaint
Dir.mkdir(image_dir) unless File.directory?(image_dir)
list = imageList(@image_date, image_dir).untaint
slist = imageList(@image_date, image_dir, "s").untaint
if width
width_tag = %Q[width="#{h width}"]
else
width_tag = ""
end
if id2
%Q[ ]
else
if slist[id.to_i]
%Q[ ]
else
if list[id.to_i]
# %Q[ ]
%Q[ ]
end
end
end
end
def image_left( id, alt = "image", id2 = nil, width=nil )
image( id, alt, id2, width, "left" )
end
def image_right( id, alt = "image", id2 = nil, width=nil )
image( id, alt, id2, width, "right" )
end
def image_link( id, str )
@image_date ||= @date.strftime("%Y%m%d")
@image_year ||= @date.strftime("%Y")
if @imageex_yearlydir == 1
image_url = %Q[#{@image_url}/#{@image_year}/]
image_dir = %Q[#{@image_dir}/#{@image_year}/]
else
image_url = %Q[#{@image_url}/]
image_dir = %Q[#{@image_dir}/]
end
list = imageList(@image_date, image_dir).untaint
%Q[#{str} ]
end
###
def imageList(date, image_dir='@image_dir', prefix="")
date = "#{prefix}"+date
image_path = []
Dir.foreach(image_dir){ |file|
if file =~ /(.*)\_(.*)\.(.*)/
if $1 == date
image_path[$2.to_i] = file
end
end
}
image_path
end
add_form_proc do |date|
begin
# ENV['PATH'] = nil
imageex_useresize = @options && @options['image_ex.useresize'] || 0
imageex_converttype = @options && @options['image_ex.converttype'] || 0
imageex_thresholdsize = @options && @options['image_ex.thresholdsize'] || 160
imageex_convertedwidth = @options && @options['image_ex.convertedwidth'] || 160
imageex_convertedheight = @options && @options['image_ex.convertedheight'] || 120
if imageex_useresize == 1 || imageex_useresize ==2
begin
require 'image_size.rb'
rescue LoadError
imageex_useresize = 0
end
end
if imageex_useresize == 1
def resize_image(orig, new, width, height, imageex_convertedwidth, imageex_convertedheight, orig_type, new_type)
imageex_convertpath = @options && @options['image_ex.convertpath'] || "convert"
imageex_convertpath
if width > height
imageex_convertedsize = %Q[#{imageex_convertedwidth}x#{imageex_convertedheight}]
imageex_convertedsize
else
imageex_convertedsize = %Q[#{imageex_convertedheight}x#{imageex_convertedwidth}]
imageex_convertedsize
end
system(imageex_convertpath , "-auto-orient", "-geometry", imageex_convertedsize , orig, new)
if FileTest::size?( new ) == 0
File::delete( new )
end
end
elsif imageex_useresize == 2
def resize_image(orig, new, width, height, imageex_convertedwidth, imageex_convertedheight, orig_type, new_type)
pnmscale = @options && @options['image_ex.pnmscalepath'] || "pnmscale"
jpegtopnm = @options && @options['image_ex.jpegtopnmpath'] || "jpegtopnm"
pnmtojpeg = @options && @options['image_ex.pnmtojpegpath'] || "pnmtojpeg"
pngtopnm = @options && @options['image_ex.pngtopnmpath'] || "pngtopnm"
pnmtopng = @options && @options['image_ex.pnmtopngpath'] || "pnmtopng"
giftopnm = @options && @options['image_ex.giftopnmpath'] || "giftopnm"
tifftopnm = @options && @options['image_ex.tifftopnmpath'] || "tifftopnm"
bmptopnm = @options && @options['image_ex.bmptopnmpath'] || "bmptopnm"
downtype = orig_type.downcase
topnm = eval("#{downtype}topnm")
if new_type == "jpg"
pnmto = pnmtojpeg
elsif new_type == "png"
pnmto = pnmtopng
end
if width > height
imageex_convertedsize ="#{imageex_convertedwidth}"
else
imageex_convertedsize ="#{imageex_convertedheight}"
end
com_line =%Q[#{topnm} #{orig} | #{pnmscale} --width #{imageex_convertedsize} | #{pnmto} > #{new}]
system( com_line )
if FileTest::size?( new ) == 0
File::delete( new )
end
end
end
def dayimagelist( image_dir, image_date, prefix="")
image_path = []
image_dir.untaint
Dir.foreach(image_dir){ |file|
if file=~ /(.*)\_(.*)\.(.*)/
if $1 == "#{prefix}" + image_date.to_s
image_path[$2.to_i] = file
end
end
}
return image_path
end
if @cgi.params['plugin_image_add'][0] && @cgi.params['plugin_image_file'][0].original_filename != ''
image_dir = @cgi.params['plugin_image_dir'][0].read.untaint
image_filename = ''
image_extension = ''
image_date = date.strftime("%Y%m%d")
image_filename = @cgi.params['plugin_image_file'][0].original_filename
if image_filename =~ /(\.jpg|\.jpeg|\.gif|\.png)\z/i
image_extension = $1
image_name = dayimagelist(image_dir, image_date)
image_file = image_dir+image_date+"_"+image_name.length.to_s+image_extension.downcase
image_file.untaint
File::umask( 022 )
File::open( image_file, "wb" ) {|f|
f.print @cgi.params['plugin_image_file'][0].read
}
end
if imageex_useresize == 1 or imageex_useresize == 2
open(image_file,"rb") do |fh|
img = ImageSize.new(fh.read)
begin
# old image_size.rb
width = img.get_width
height = img.get_height
orig_type = img.get_type
rescue NoMethodError
# image_size gem
width = img.width
height = img.height
orig_type = (img.format || "OTHER").to_s.upcase
end
if imageex_converttype == 0
new_type = "jpg"
elsif imageex_converttype == 1
new_type = "png"
end
if width
if width > imageex_thresholdsize or height > imageex_thresholdsize
small_image_file = %Q[#{image_dir}s#{image_date}_#{image_name.length.to_s}.#{new_type}]
resize_image(image_file, small_image_file, width, height, imageex_convertedwidth, imageex_convertedheight, orig_type, new_type)
end
end
end
end
elsif @cgi.params['plugin_image_thumbnail'][0] && @cgi.params['plugin_image_file'][0].original_filename != ''
image_dir = @cgi.params['plugin_image_dir'][0].read.untaint
image_filename = ''
image_extension = ''
image_date = date.strftime("%Y%m%d")
image_filename = @cgi.params['plugin_image_file'][0].original_filename
if image_filename =~ /(\.jpg|\.jpeg|\.gif|\.png)\z/i
image_extension = $1
image_name = @cgi.params['plugin_image_name'][0].read.untaint
image_file=image_dir+"s"+image_name+image_extension.downcase
image_file.untaint
File::umask( 022 )
File::open( image_file, "wb" ) {|f|
f.print @cgi.params['plugin_image_file'][0].read
}
end
elsif @cgi.params['plugin_image_del'][0]
image_dir = @cgi.params['plugin_image_dir'][0]
image_date = date.strftime("%Y%m%d")
image_name = dayimagelist( image_dir, image_date)
image_name2= dayimagelist( image_dir, image_date, "s")
@cgi.params['plugin_image_id'].untaint.each do |id|
if image_name[id.to_i]
image_file=image_dir+image_name[id.to_i]
image_file.untaint
if File::exist?(image_file)
File::delete(image_file)
end
end
if image_name2[id.to_i]
image_file2=image_dir+image_name2[id.to_i]
image_file2.untaint
if File::exist?(image_file2)
File::delete(image_file2)
end
end
end
end
rescue Exception
puts "Content-Type: text/plain\n\n"
puts "#$! (#{$!.type})"
puts ""
puts $@.join( "\n" )
end
if @imageex_yearlydir == 1
image_dir = %Q[#{@image_dir}/#{@date.year}/]
else
image_dir = %Q[#{@image_dir}/]
end
if @imageex_yearlydir == 1
image_url = %Q[#{@image_url}/#{@date.year}/]
else
image_url = %Q[#{@image_url}/]
end
Dir.mkdir(image_dir) unless File.directory?(image_dir)
n_image = imageList(@date.strftime("%Y%m%d"), image_dir).length
list = imageList(@date.strftime("%Y%m%d"), image_dir)
slist = imageList(@date.strftime("%Y%m%d"), image_dir, "s")
pretable=""
posttable=""
if n_image > 0
pretable<< %Q[]
end
if @conf.respond_to?(:style) and @conf.style =~ /Wiki$/i
image_plugin_tag1 = "{{"
image_plugin_tag2 = "}}"
elsif @conf.respond_to?(:style) and @conf.style =~ /RD$/i
image_plugin_tag1 = "((%"
image_plugin_tag2 = "%))"
else
image_plugin_tag1 = "<%="
image_plugin_tag2 = "%>"
end
r = ''
r << %Q[
]
i = ''
i << ""
nt=0
id=0
while id < n_image do
thumbnail_tag = ''
if slist[id.to_i]
src_tag = %Q[src="#{h image_url}#{h slist[id.to_i]}"]
alt_tag = %Q[alt="#{h slist[id.to_i]}"]
else
src_tag = %Q[src="#{h image_url}#{h list[id.to_i]}"]
alt_tag = %Q[alt="#{h list[id.to_i]}"]
thumbnail_tag = %Q[] if imageex_useresize == 0
end
ptag = "#{image_plugin_tag1}image #{id}, '画像の説明'#{image_plugin_tag2}"
i<< %Q[ ] if slist[id.to_i] || list[id.to_i]
nt += 1 if slist[id.to_i] || list[id.to_i]
if nt > 0 and nt%2 == 0
i<< %Q[ ]
end
id +=1
end
if n_image > 0
r << %Q[]
end
r << %Q[]
end
# vim: set ts=3 sw=3 noexpandtab :
tdiary-contrib-5.1.0/plugin/image_gps.rb 0000664 0000000 0000000 00000013744 13570131474 0020243 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
# image_gps.rb $Revision: 1.1 $
#
# 概要:
#
#
# 使い方:
# 絵日記Plugin(image.rb)とおなじ
#
# Copyright (c) 2009,2010 kp
# Distributed under the GPL
#
=begin ChangeLog
2010-04-21 kp
* スマートフォン対応
* Google Maps API Keyが設定されていない場合はStaticMAPを生成しない
* リンク先をGoogle Mapsに統一
2009-06-03 kp
* first version
* fork from image_gps2.rb
=end
begin
require 'exifparser'
rescue
retry if require 'rubygems'
end
def tky2wgs lat,lon
lat_w = lat - lat*0.00010695 + lon*0.000017464 + 0.0046017
lon_w = lon - lat*0.000046038 - lon*0.000083043 + 0.010040
lat = lat_w
lon = lon_w
return lat,lon
end
def image( id, alt = 'image', thumbnail = nil, size = nil, place = 'photo' )
if @conf.secure then
image = "#{@image_date}_#{id}.jpg"
image_t = "#{@image_date}_#{thumbnail}.jpg" if thumbnail
else
image = image_list( @image_date )[id.to_i]
image_t = image_list( @image_date )[thumbnail.to_i] if thumbnail
end
if size
if size.kind_of?(Array)
if size.length > 1
size = %Q| width="#{h size[0]}" height="#{h size[1]}"|
elsif size.length > 0
size = %Q| width="#{h size[0]}"|
end
else
size = %Q| width="#{size.to_i}"|
end
elsif @image_maxwidth and not @conf.secure then
_, w, _ = image_info( "#{@image_dir}/#{image}".untaint )
if w > @image_maxwidth then
size = %Q[ width="#{h @image_maxwidth}"]
else
size = ""
end
end
show_exif_info = @conf['image_gps.show_exif_info']
show_exif_info = '' if show_exif_info.nil?
google_maps_api_key = @conf['image_gps.google_maps_api_key']
google_maps_api_key = '' if google_maps_api_key.nil?
if (@conf['image_gps.map_link_url'].nil? || @conf['image_gps.map_link_url'].empty?)
map_link_url = '"//maps.google.co.jp/maps?q=#{lat},#{lon}"'
else
map_link_url = '"'+@conf['image_gps.map_link_url']+'"'
end
exif = ExifParser.new("#{@image_dir}/#{image}".untaint) rescue nil
if exif
#GPS Info
begin
raise if exif['GPSLatitudeRef'].value.length==0
raise if exif['GPSLongitudeRef'].value.length==0
lat = exif['GPSLatitude'].value
lat = lat[0].to_f + lat[1].to_f/60 + lat[2].to_f/3600
lat = -lat if exif['GPSLatitudeRef'].value == 'S'
lon = exif['GPSLongitude'].value
lon = lon[0].to_f + lon[1].to_f/60 + lon[2].to_f/3600
lon = -lon if exif['GPSLongitudeRef'].value == 'W'
datum = exif['GPSMapDatum'].value if exif.tag?('GPSMapDatum')
lat,lon = tky2wgs(lat,lon) if datum == 'TOKYO'
rescue
lat = nil
end
# show exif info
sep=' ' # ToDo: separator to config param.
detail =%Q[]
show_exif_info.split(' ').each{|e|
detail += "#{exif[e].to_s}"+sep if exif.tag?(e)
}
unless lat.nil?
unless google_maps_api_key == ''
map_img = %Q["//maps.googleapis.com/maps/api/staticmap?format=gif&]
map_img += %Q[center=#{lat},#{lon}&zoom=14&size=200x200&markers=#{lat},#{lon}&]
map_img += %Q[key=#{google_maps_api_key}&sensor=false"]
end
map_link = %Q[]
map_link += %Q[MAP]
map_link += %Q[ ] if map_img
map_link += " "
detail += map_link
end
detail += "
"
end
img = %Q[ ]
img_t = %Q[ ]
url = ''
url += %Q[]
url
end
add_header_proc do
if @mode !~ /conf$/ and not bot? then
<<-HTML
HTML
else
''
end
end
add_conf_proc('image_gps','image_gpsの設定','etc') do
if @mode == 'saveconf' then
@conf['mage_gps.google_maps_api_key'] = @cgi.params['image_gps.google_maps_api_key'][0]
@conf['image_gps.show_exif_info'] = @cgi.params['image_gps.show_exif_info'][0]
@conf['image_gps.map_link_url'] = @cgi.params['image_gps.map_link_url'][0]
end
<<-HTML
Google Static Maps API Key
Map Link URL
地図サイトへのリンクURLを設定します。空欄の場合、Googleマップへリンクされます。
パラメータとして\#{lat},\#{lon}が使用できます。それぞれ緯度、経度に展開されます。
下のセレクタから選択すると各サービスのデフォルト値が設定されます。
--select service--
Googleマップ
Yahoo地図
マピオン
Bing Maps
HTML
end
tdiary-contrib-5.1.0/plugin/inline_wiki.rb 0000664 0000000 0000000 00000000171 13570131474 0020577 0 ustar 00root root 0000000 0000000 # Copyright (C) 2009 Hideki Sakamoto
require 'hikidoc'
def inline_wiki(buf)
HikiDoc::to_html(buf)
end
tdiary-contrib-5.1.0/plugin/instagr.rb 0000664 0000000 0000000 00000001512 13570131474 0017745 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
#
# instagr.rb - plugin to insert images on instagr.am
# !! integrated into the instagram.rb.
# !! Please use the instagram.rb
#
# Copyright (C) 2011-2015, tamoot
# You can redistribute it and/or modify it under GPL2.
#
# usage:
# <%= instagr 'short URL instag.ram' =>
# <%= instagr 'short URL instag.ram', size} =>
#
# available size option:
# :small => 150x150 pixel
# :medium => 306x306 pixel (default)
# :large => 612x612 pixel
def instagr( short_url, size = :medium)
if respond_to?(:instagram)
instagram( short_url, size )
else
return %Q|instagr.rb was integrated into instagram.rb. Please use the instagram.rb|
end
end
# Local Variables:
# mode: ruby
# indent-tabs-mode: t
# tab-width: 3
# ruby-indent-level: 3
# End:
# vim: ts=3
tdiary-contrib-5.1.0/plugin/instagram.rb 0000664 0000000 0000000 00000004036 13570131474 0020267 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
#
# instagram.rb - embed your photo/videos in instagram to a diary
#
# Author: Tatsuya Sato
# License: GPL
require 'cgi'
require 'json'
require 'uri'
require 'net/http'
require 'open-uri'
def instagram(*args)
uri = URI::parse(args[0])
return instagram_iframe(*args) if uri.scheme.nil?
return instagram_serverside(*args)
end
def instagram_iframe(code, width=612, height=700)
return <<-BODY
BODY
end
def instagram_serverside( short_url, size = :medium)
return %Q|Argument is empty.. #{short_url}
| if !short_url or short_url.empty?
option = option.nil? ? {} : option
# img size
size = size.to_sym if size != :medium
maxwidth_data = {:medium => 320, :large => 612}
maxwidth = maxwidth_data[ size ] ? maxwidth_data[ size ] : maxwidth_data[:medium]
# proxy
px_host, px_port = (@conf['proxy'] || '').split( /:/ )
px_port = 80 if px_host and !px_port
# query
query = "?url=#{CGI::escape(short_url)}&maxwidth=#{maxwidth}"
begin
Net::HTTP.version_1_2
res = Net::HTTP::Proxy(px_host, px_port).get('api.instagram.com', "/oembed/#{query}")
json_data = JSON::parse( res, &:read )
width = option[:width] ? option[:width] : json_data["width"]
height = option[:height] ? option[:height] : json_data["height"]
return <<-INSTAGR_DOM
#{h json_data["author_name"]}'s photo.
INSTAGR_DOM
rescue
return %Q|Failed Open URL.. #{short_url} #{h $!}
|
end
end
# Local Variables:
# mode: ruby
# indent-tabs-mode: t
# tab-width: 3
# ruby-indent-level: 3
# End:
# vim: ts=3
tdiary-contrib-5.1.0/plugin/ja/ 0000775 0000000 0000000 00000000000 13570131474 0016344 5 ustar 00root root 0000000 0000000 tdiary-contrib-5.1.0/plugin/ja/add_bookmark.rb 0000664 0000000 0000000 00000001122 13570131474 0021302 0 ustar 00root root 0000000 0000000 # ja/add_bookmark.rb $Revision 1.3 $
#
# Japanese resource of add_bookmark.rb
# You can redistribute it and/or modify it under GPL2.
#
@add_bookmark_label = 'ブックマーク追加'
@add_bookmark_desc = 'ページに埋め込みたいリンクをチェックしてください。'
@caption_delicious = 'del.icio.usに追加'
@caption_hatena = 'はてなブックマークに追加'
@caption_livedoor = 'livedoor クリップに追加'
@caption_buzzurl = 'Buzzurl に追加'
@bookmark_label = [
'del.icio.us',
'はてなブックマーク',
'livedoor クリップ',
'Buzzurl'
]
tdiary-contrib-5.1.0/plugin/ja/category-lite.rb 0000664 0000000 0000000 00000003510 13570131474 0021440 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
#
# ja/category-lite.rb : tDiary plugin for show category pages (light edition)
#
# Copyright (C) 2015 TADA Tadashi
# Distributed under the GPL2 or any later version.
#
@category_conf_label = 'カテゴリ'
def category_conf_html
r = <<-HTML
カテゴリインデックスの作成
カテゴリの機能を利用するにはカテゴリインデックスをあらかじめ作成しておく必要があります。
カテゴリインデックスを作成するには
以下のチェックを入れてからOKボタンを押してください。
カテゴリインデックスの作成
数秒から数十秒でインデックスの作成は終了しますが、日記の量が多い場合やサーバの性能が低い場合はタイムアウトしてしまう場合があります。この場合はオフラインで作成して下さい。
日記編集サポート
日記編集画面の「本文」の下にカテゴリ名を一覧表示することができます。
カテゴリ名をクリックすると「本文」にそのカテゴリ名が挿入されます(要JavaScript)。
一覧表示
ドロップダウンリスト
表示しない
HTML
r
end
# Local Variables:
# mode: ruby
# indent-tabs-mode: t
# tab-width: 3
# ruby-indent-level: 3
# End:
# vim: ts=3
tdiary-contrib-5.1.0/plugin/ja/del_footer.rb 0000664 0000000 0000000 00000000476 13570131474 0021022 0 ustar 00root root 0000000 0000000 #
# English resource of delicious plugin $Revision: 1.0 $
#
# Copyright (C) 2006 SHIBATA Hiroshi
# You can redistribute it and/or modify it under GPL2.
#
@delicious_label_conf = 'del.icio.us'
@delicious_label_id = 'del.icio.usのユーザーID'
@delicious_label_pw = 'del.icio.usのパスワード'
tdiary-contrib-5.1.0/plugin/ja/flickr.rb 0000664 0000000 0000000 00000007420 13570131474 0020146 0 ustar 00root root 0000000 0000000 # flickr.rb Japanese resources
add_conf_proc('flickr', 'Flickr プラグイン') do
if @mode == 'saveconf'
@conf['flickr.default_size'] = @cgi.params['flickr.default_size'][0]
@conf['flickr.user_id'] = @cgi.params['flickr.user_id'][0]
@conf['flickr.input_support'] = !!(@cgi.params['flickr.input_support'][0] == "true")
if @cgi.params['flickr.clear'][0] == "true"
flickr_clear_cache
end
end
flickr_bookmarklet = CGI.escapeHTML %Q{javascript:(function(){var w=window;w.page_photo_id||/^\/photos\/[^/]+\/(\d+)\//.test(w.location.pathname)?w.location.href="#{@conf.base_url}#{@update}?#{FLICKER_FORM_PID}="+w.page_photo_id||RegExp.$1:void(0);})()}
r = <<-_HTML
Flickr に登録した画像を日記に表示するプラグインです。日記の本文中で下記のように呼び出します。
<%=flickr 画像ID, 画像サイズ%>
画像ID
それぞれの写真に一意に付けられる番号です。 画像IDは Flickr で画像を表示したときの URL に含まれています。
画像サイズ
表示する画像の大きさを square, large square, thumbnail, small, small 320, medium, medium 640, medium 800, large から指定します。 この値は省略できます。省略すると、画像は設定画面(この画面)で指定したサイズで表示されます。
標準の画像サイズ
画像サイズを省略してプラグインを呼び出した場合のサイズを指定します。
_HTML
%w(square large\ square thumbnail small small\ 320 medium medium\ 640 medium\ 800 large).each do |size|
selected = (size == @conf['flickr.default_size']) ? 'selected' : ''
r << %Q|#{size} |
end
r <<<<-_HTML
FlickrのユーザID
Flickr上でのあなたのユーザIDを入力してください。
※ Flickr ID は「19594487@N00」のような文字列です。分からないときは idgettr.com で調べることができます。
Bookmarklet
写真をかんたんに tDiary の日記へ載せるための Bookmarklet です。Bookmarklet を登録しなくても Flickr プラグインは使えますが、登録すればより便利になります。
Flickr to tDiary (このリンクをブラウザのお気に入り・ブックマークに登録してください)
使い方
Flickr にアクセスし、日記に載せたい写真のページを開いて、この Bookmarklet を実行してください。
日記の編集フォームの下に先ほどの写真が表示されます。
「本文に追加」ボタンを押すと、日記中にこの写真を表示するための記述(プラグイン)が追記されます。
編集画面からの入力補助
写真を一覧から選べるようにする
キャッシュファイルの削除
Flickrプラグインが使用しているキャッシュを削除します。
キャッシュを削除する
_HTML
end
tdiary-contrib-5.1.0/plugin/ja/git-register.rb 0000664 0000000 0000000 00000000253 13570131474 0021276 0 ustar 00root root 0000000 0000000 @git_register_conf_label = 'Git'
@git_register_conf_header = 'Gitへ再登録'
@git_register_conf_description = 'Gitへ再登録する場合はOKを押してください'
tdiary-contrib-5.1.0/plugin/ja/google_sitemaps.rb 0000664 0000000 0000000 00000003323 13570131474 0022053 0 ustar 00root root 0000000 0000000 # google_sitemap.rb
# Copyright (c) 2006 http://d.bulkitem.com/
# Distributed under the GPL
add_conf_proc('google_sitemaps', 'Google sitemap') do
saveconf_google_sitemaps
request_uri = File::dirname(@cgi.request_uri)
if request_uri == "/"
@conf['google_sitemaps.uri_format'] ||= 'http://' + @cgi.server_name + '/index.cgi?date=%s'
else
@conf['google_sitemaps.uri_format'] ||= 'http://' + @cgi.server_name + request_uri + '/index.cgi?date=%s'
end
@conf['google_sitemaps.output_file'] ||= File::dirname(ENV['SCRIPT_FILENAME']) + '/sitemap.xml'
if File.writable_real?(@conf['google_sitemaps.output_file']) == false
msg = "[NG] 指定されているファイルの書き込み権限がありません。 "
else
msg = "[OK] 指定されているファイルの書き込み権限があります。"
end
<<-HTML
Google ウェブマスターツール用のSitemap XMLを出力する設定を行います。
アドレスフォーマット
日付別表示時のURLフォーマットを指定します。日付文字列の部分は%s にしてください。
eg. http://www.example.com/inex.cgi?date=%s http://www.example.com/%s .html
XMLファイルの出力先
出力するファイルを絶対パスで指定します。
#{msg}
HTML
end
tdiary-contrib-5.1.0/plugin/ja/livedoor_weather.rb 0000664 0000000 0000000 00000002424 13570131474 0022235 0 ustar 00root root 0000000 0000000 #
# Japanese resource of livedoor_weather plugin $Revision$
#
# Copyright (C) 2006 SHIBATA Hiroshi
# You can redistribute it and/or modify it under GPL2.
#
#
# tdiary.confにおける設定:
# @options['lwws.city_id'] : 天気情報を取得したい都市のIDを指定(設定画面から編集可能)
#
@lwws_plugin_name = 'livedoor 天気情報'
@lwws_label_city_id = '都市IDの設定'
@lwws_desc_city_id = '天気情報を取得する都市IDを指定します。全国の地点定義表(RSS) 内の「1次細分区(cityタグ)」のidから選択してください。(初期設定は東京)'
@lwws_label_disp_item = '表示項目の設定'
@lwws_desc_disp_item = '表示させたい項目を選択してください。'
@lwws_icon_label = 'アイコン表示の設定'
@lwws_icon_desc = '天気情報をアイコン表示にする(詳細へのリンクは画像に設定)'
@lwws_max_temp_label = '最高気温'
@lwws_min_temp_label = '最低気温'
@celsius_label = '℃'
@lwws_label_cache = 'キャッシュの自動更新'
@lwws_desc_cache = '自動更新を有効にする。'
@lwws_desc_cache_time = 'キャッシュの更新間隔を時間で指定します。(初期設定は6時間)'
tdiary-contrib-5.1.0/plugin/ja/microsummary.rb 0000664 0000000 0000000 00000001004 13570131474 0021413 0 ustar 00root root 0000000 0000000 # ja/microsummary.rb
#
# Japanese resources for microsummary.rb
#
# Copyright (c) 2006 elytsllams
# Distributed under the GPL
#
if @mode == 'conf' || @mode == 'saveconf'
add_conf_proc( 'microsummary', 'Microsummary Generator' ) do
saveconf_microsummary
microsummary_init
<<-HTML
URI for microsummary generator XML
HTML
end
end
tdiary-contrib-5.1.0/plugin/ja/nicovideo.rb 0000664 0000000 0000000 00000003220 13570131474 0020645 0 ustar 00root root 0000000 0000000 #
# ja/nicovideo.rb - Japanese resource
#
# Copyright (C) TADA Tadashi
# Distributed under GPL.
#
def nicovideo_feed( i )
<<-HTML
HTML
end
def nicovideo_html( i )
<<-HTML
#{i[:date][0,10]}
再生: #{i[:view].scan(/\d+?(?=\d{3}*$)/).join(",")}
コメント: #{i[:comment_num].scan(/\d+?(?=\d{3}*$)/).join(",")}
マイリスト: #{i[:mylist].scan(/\d+?(?=\d{3}*$)/).join(",")}
#{h i[:title]} (#{i[:length].split(/:/).map{|j|'%02d' % j.to_i}.join(':')}) #{i[:desc]}
HTML
end
tdiary-contrib-5.1.0/plugin/ja/openid.rb 0000664 0000000 0000000 00000000575 13570131474 0020156 0 ustar 00root root 0000000 0000000 # openid.rb: Japanese resource
@openid_conf_label = 'OpenID'
@openid_service_label = 'OpenID認証サービス名'
@openid_service_desc = 'あなたが使っているOpenIDの認証サービス名を選んでください'
@openid_id_label = 'あなたのID'
@openid_id_desc = '上で選択した認証サービスに登録してある、あなたのIDを入力してください'
tdiary-contrib-5.1.0/plugin/ja/section_footer.rb 0000664 0000000 0000000 00000000677 13570131474 0021725 0 ustar 00root root 0000000 0000000 # section_footer.rb: Japanese resource
@section_footer_delicious_label = "このエントリの del.icio.us history"
@section_footer_hatenabm_label = "このエントリを含むはてなブックマーク"
@section_footer_ldclip_label = "このエントリを含む livedoor クリップ"
@section_footer_buzzurl_label = "このエントリを含む Buzzurl"
@section_footer_yahoobm_label = "このエントリを含む Yahoo!ブックマーク"
tdiary-contrib-5.1.0/plugin/ja/section_footer2.rb 0000664 0000000 0000000 00000000257 13570131474 0022001 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
# section_footer2.rb: Japanese resource
@section_footer2_delicious_label = "このエントリの Delicious history"
@section_footer2_locale = 'ja_JP'
tdiary-contrib-5.1.0/plugin/ja/socialbutton.rb 0000664 0000000 0000000 00000000466 13570131474 0021405 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
# section_footer2.rb: Japanese resource
@socialbutton_label_conf = 'ソーシャルボタン'
@socialbutton_label_enables = 'ボタンを表示するサービス'
@socialbutton_label_twitter_via = 'ツイート時に表示するユーザ名(あなたのTwitterアカウント名)'
tdiary-contrib-5.1.0/plugin/ja/yo_update.rb 0000664 0000000 0000000 00000004050 13570131474 0020661 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
#
# yo_update.rb - Japanese resource
#
# Copyright (C) 2014, zunda
#
# Permission is granted for use, copying, modification,
# distribution, and distribution of modified versions of this
# work under the terms of GPL version 2 or later.
#
def yo_update_conf_label
'更新時にYoを送る'
end
def yo_update_test_result_label(username, result)
"- #{h username} に Yo を送りました: #{h result} "
end
def yo_update_conf_html(conf, n_subscribers, test_result)
action_label = {
'send_on_update' => '日記が追加された時',
'send_on_comment' => 'ツッコミされた時',
}
<<-HTML
API key
Username
Yo を送るタイミング
Yo を にリンク (不要なら空白)をつけて送ってみる#{test_result}
現在の受信者数
#{h n_subscribers}
Yoボタン
ページのどこかに下記を追加してください
<div id="yo-button"></div>
やり方
個人用 Yo アカウントで http://dev.justyo.co/ にログインする
ページ内の指示に従って APIアカウントを作成する。
Callback URL は空白のままにしてください
API key と API username を上にコピーする
HTML
end
tdiary-contrib-5.1.0/plugin/jdate.rb 0000664 0000000 0000000 00000001221 13570131474 0017362 0 ustar 00root root 0000000 0000000 # jdate.rb $Revision: 1.1 $
#
#「%J」で日本語の曜日名を出す
# pluginに入れるだけで動作する。
# 日付フォーマットなどで「%J」を指定するとそこが日本語の曜日になる
#
# Copyright (c) 2003 TADA Tadashi
# You can distribute this file under the GPL.
#
unless Time::new.respond_to?( :strftime_jdate_backup ) then
eval( <<-MODIFY_CLASS, TOPLEVEL_BINDING )
class Time
alias strftime_jdate_backup strftime
JWDAY = %w(日 月 火 水 木 金 土)
def strftime( format )
strftime_jdate_backup( format.gsub( /%J/, JWDAY[self.wday] ) )
end
end
MODIFY_CLASS
end
tdiary-contrib-5.1.0/plugin/jholiday.rb 0000664 0000000 0000000 00000000670 13570131474 0020105 0 ustar 00root root 0000000 0000000 require 'Calendar.rb'
require 'date'
unless Time::new.respond_to?( :strftime_holiday_backup )
then
eval( <<-MODIFY_CLASS, TOPLEVEL_BINDING )
class Time
alias strftime_holiday_backup strftime
def strftime( format )
holiday = ""
day = Day.new(self.day,self.month,self.year,self.wday)
holiday = day.holiday_name_jp if day.holiday?
strftime_holiday_backup( format.gsub( /%K/, holiday ) )
end
end
MODIFY_CLASS
end
tdiary-contrib-5.1.0/plugin/jmonth.rb 0000664 0000000 0000000 00000001354 13570131474 0017601 0 ustar 00root root 0000000 0000000 # jmonth.rb $Revision: 1.1 $
#
#「%i」で日本語の陰暦月名を出す
# pluginに入れるだけで動作する。
# 日付フォーマットなどで「%i」を指定するとそこが陰暦月名になる
#
# Copyright (c) 2005 sasasin/SuzukiShinnosuke
# You can distribute this file under the GPL.
#
unless Time::new.respond_to?( :strftime_jmonth_backup ) then
eval( <<-MODIFY_CLASS, TOPLEVEL_BINDING )
class Time
alias strftime_jmonth_backup strftime
JMONTH = %w(睦月 如月 弥生 卯月 皐月 水無月 文月 葉月 長月 神無月 霜月 師走)
def strftime( format )
strftime_jmonth_backup( format.gsub( /%i/, JMONTH[self.month-1] ) )
end
end
MODIFY_CLASS
end
tdiary-contrib-5.1.0/plugin/jquery_ui_theme.rb 0000664 0000000 0000000 00000002233 13570131474 0021475 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
#
# jquery_ui.rb - use jQuery UI
#
# Copyright (C) 2012, tamoot
# You can redistribute it and/or modify it under GPL.
#
#
# not support
#
return if feed?
add_header_proc do
if /\A(?:form|preview|append|edit|update)\z/ =~ @mode
themes = @conf['jquery_ui.theme']
if themes.nil? || theme == ''
themes = 'base'
end
jquery_ui = ''
jquery_ui << %Q| \n|
jquery_ui
else
''
end
end
add_conf_proc( 'jquery_ui_theme', 'jQuery UI Theme' ) do
if @mode == 'saveconf' then
@conf['jquery_ui.theme'] = @cgi.params['jquery_ui.theme'][0]
end
<<-HTML
Theme name
sample) blitzer, flick .. See JQuery UI Theme.
default is base .
HTML
end
# Local Variables:
# mode: ruby
# indent-tabs-mode: t
# tab-width: 3
# ruby-indent-level: 3
# End:
# vim: ts=3
tdiary-contrib-5.1.0/plugin/jroku.rb 0000664 0000000 0000000 00000001670 13570131474 0017435 0 ustar 00root root 0000000 0000000 # jroku.rb $Revision: 1.1 $
#
#「%R」で六曜を出す
# 動かすためには
# http://www.funaba.org/calendar.html#calendar
# で配布されているClendarモジュールと付属しているcalclass.rbが必要
# 日付フォーマットなどで「%R」を指定するとそこが六曜になる
#
# Copyright (c) 2005 SHIBATA Hiroshi
# You can distribute this file under the GPL.
#
require 'calclass.rb'
unless Time::new.respond_to?( :strftime_jroku_backup ) then
eval( <<-MODIFY_CLASS, TOPLEVEL_BINDING )
class Time
alias strftime_jroku_backup strftime
JROKU = %w(大安 赤口 先勝 友引 先負 仏滅)
def strftime( format )
d=Gregorian.new(self.month, self.day, self.year)
q_d = Calendar.kyureki_from_absolute(d.abs)
index = (q_d[0] + q_d[2]) % 6
strftime_jroku_backup( format.gsub( /%R/, JROKU[index] ) )
end
end
MODIFY_CLASS
end
tdiary-contrib-5.1.0/plugin/jyear.rb 0000664 0000000 0000000 00000002133 13570131474 0017410 0 ustar 00root root 0000000 0000000 # jyear.rb $Revision: 1.1 $
#
# 西暦を和暦に変換するプラグイン。
# 日記やツッコミの日付フォーマットで使う。
# 「%Y」で「2005」のところを、「%K」で「平成17」と表示。
# pluginに入れるだけで動作する。
#
# Copyright (c) 2005 sasasin/SuzukiShinnosuke
# You can distribute this file under the GPL.
#
unless Time::new.respond_to?( :strftime_jyear_backup ) then
eval( <<-MODIFY_CLASS, TOPLEVEL_BINDING )
class Time
alias strftime_jyear_backup strftime
def strftime( format )
case self.year
when 0 .. 1926
gengo = "昔々"
if self.year == 1926 && self.month == 12 && self.day >=25 then
gengo = "昭和元年"
end
when 1927 .. 1989
jyear = self.year - 1925
gengo = "昭和" + jyear.to_s
if self.year == 1989 && self.month == 1 && self.day >= 8 then
gengo = "平成元年"
end
else
jyear = self.year - 1988
gengo = "平成" + jyear.to_s
end
strftime_jyear_backup( format.gsub( /%K/, gengo ) )
end
end
MODIFY_CLASS
end
tdiary-contrib-5.1.0/plugin/latlonglab_route.rb 0000664 0000000 0000000 00000001231 13570131474 0021631 0 ustar 00root root 0000000 0000000 #
# latlonglab_route.rb - tDiary plugin for LatLongLab Route
#
# Copyright (C) 2009, Michitaka Ohno
# Copyright (C) 2010, KAYA Satoshi
# You can redistribute it and/or modify it under GPL2.
#
def route( id, w = 480, h = 480 )
if feed?
return %Q|Link to LatLongLab Route
|
end
if @conf.iphone?
w = 240
h = 380
end
<<-HTML
HTML
end
tdiary-contrib-5.1.0/plugin/lazy_referer.rb 0000664 0000000 0000000 00000001762 13570131474 0020776 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8; -*-
#
# lazy_referer.rb: lazy loading referer
#
# Copyright (C) 2013 by MATSUOKA Kohei
# You can distribute it under GPL.
#
if /^(day|form|edit)$/ =~ @mode and not bot? then
enable_js('referer.js')
#
# overwrite method: draw only referer area (content will feach with ajax)
#
def referer_of_today_long( diary, limit )
return if limit == 0
return unless diary
date = diary.date.strftime('%Y%m%d')
# FIXME: endpoint is should created by TDiary::Plugin, because easy customize routing
endpoint = "#{@conf.index}?plugin=referer&date=#{date}"
%Q[#{referer_today} \n]
end
end
#
# return referer of date as is (html)
#
add_content_proc('referer') do |date|
diary = @diaries[date]
referer_load_current( diary )
referer_of_today_long( diary, 100 )
end
# Local Variables:
# mode: ruby
# indent-tabs-mode: t
# tab-width: 3
# ruby-indent-level: 3
# End:
tdiary-contrib-5.1.0/plugin/livedoor_weather.rb 0000664 0000000 0000000 00000013157 13570131474 0021650 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
# livedoor_weather.rb
#
# insert weather information using livedoor weather web service.
#
# Copyright (C) 2007 SHIBATA Hiroshi
# You can redistribute it and/or modify it under GPL2.
#
require 'open-uri'
require 'timeout'
require 'time'
@lwws_rest_url = 'http://weather.livedoor.com/forecast/webservice/json/v1'
def lwws_init
@conf['lwws.city_id'] ||= 130010
@conf['lwws.icon.disp'] ||= ""
@conf['lwws.max_temp.disp'] ||= ""
@conf['lwws.min_temp.disp'] ||= ""
@conf['lwws.cache'] ||= ""
@conf['lwws.cache_time'] ||= 6
end
def lwws_request( city_id )
url = @lwws_rest_url.dup
url << "?city=#{city_id}"
proxy = @conf['proxy']
proxy = 'http://' + proxy if proxy
Timeout.timeout( 10 ) do
open( url, :proxy => proxy ) {|f| f.read }
end
end
def lwws_get
lwws_init
city_id = @conf['lwws.city_id']
cache_time = @conf['lwws.cache_time'] * 60 * 60
file_name = "#{@cache_path}/lwws/#{Time.now.strftime("%Y%m%d")}.json"
begin
Dir.mkdir("#{@cache_path}/lwws") unless File.directory?("#{@cache_path}/lwws")
cached_time = if File.exist?( file_name )
File.mtime( file_name )
else
nil
end
update = true if @conf['lwws.cache'] == "t" && cached_time && Time.now > cached_time + cache_time
if cached_time.nil? || update
json = lwws_request(city_id)
File.open(file_name, 'wb') {|f| f.write(json)}
end
rescue => e
@logger.error( e )
end
end
def lwws_to_html(date)
lwws_init
file_name = "#{@cache_path}/lwws/#{date.strftime("%Y%m%d")}.xml"
begin
# http://weather.livedoor.com/help/restapi_close
if Time.parse('20130331') < date
file_name.sub!(/xml/, 'json')
require 'json'
doc = JSON.parse(File.read(file_name))
telop = @conf.to_native( doc["forecasts"][0]["telop"], 'utf-8' )
# 「今日」のデータに気温は含まれない場合がある
max_temp = doc["forecasts"][0]["temperature"]["max"]["celsius"] rescue nil
min_temp = doc["forecasts"][0]["temperature"]["min"]["celsius"] rescue nil
detail_url = doc["link"]
title = @conf.to_native( doc["forecasts"][0]["image"]["title"], 'utf-8' )
url = doc["forecasts"][0]["image"]["url"]
width = doc["forecasts"][0]["image"]["width"]
height = doc["forecasts"][0]["image"]["height"]
else
require 'rexml/document'
doc = REXML::Document.new(File.read(file_name)).root
telop = @conf.to_native( doc.elements["telop"].text, 'utf-8' )
max_temp = doc.elements["temperature/max/celsius"].text
min_temp = doc.elements["temperature/min/celsius"].text
detail_url = doc.elements["link"].text
title = @conf.to_native( doc.elements["image/title"].text, 'utf-8' )
url = doc.elements["image/url"].text
width = doc.elements["image/width"].text
height = doc.elements["image/height"].text
end
result = ""
result << %Q||
if @conf['lwws.icon.disp'] != "t" then
result << %Q|
#{telop} |
else
result << %Q|
|
end
if @conf['lwws.max_temp.disp'] == "t" and not max_temp.nil? then
result << %Q| #{@lwws_max_temp_label}:#{h(max_temp)}#{@celsius_label}|
end
if @conf['lwws.min_temp.disp'] == "t" and not min_temp.nil? then
result << %Q| #{@lwws_min_temp_label}:#{h(min_temp)}#{@celsius_label}|
end
result << %Q|
|
result
rescue StandardError, Errno::ENOENT => e
@logger.error( e )
''
end
end
def lwws_conf_proc
lwws_init
if @mode == 'saveconf' then
@conf['lwws.city_id'] = @cgi.params['lwws.city_id'][0].to_i
@conf['lwws.icon.disp'] = @cgi.params['lwws.icon.disp'][0]
@conf['lwws.max_temp.disp'] = @cgi.params['lwws.max_temp.disp'][0]
@conf['lwws.min_temp.disp'] = @cgi.params['lwws.min_temp.disp'][0]
@conf['lwws.cache'] = @cgi.params['lwws.cache'][0]
@conf['lwws.cache_time'] = @cgi.params['lwws.cache_time'][0].to_i
end
result = ''
result << <<-HTML
#{@lwws_label_city_id}
#{@lwws_desc_city_id}
HTML
result << %Q|#{@lwws_icon_label} |
checked = "t" == @conf['lwws.icon.disp'] ? ' checked' : ''
result << %Q| #{@lwws_icon_desc}
|
result << %Q|#{@lwws_label_disp_item} |
result << %Q|#{@lwws_desc_disp_item}
|
result << %Q||
result << %Q|#{@lwws_label_cache} |
checked = "t" == @conf['lwws.cache'] ? ' checked' : ''
result << %Q| #{@lwws_desc_cache}
|
result << %Q|#{@lwws_desc_cache_time}
|
result << %Q|
|
result
end
add_body_enter_proc do |date|
unless feed? or bot?
lwws_to_html(date)
end
end
add_update_proc do
lwws_get
end
add_conf_proc( 'lwws', @lwws_plugin_name ) do
lwws_conf_proc
end
# Local Variables:
# mode: ruby
# indent-tabs-mode: t
# tab-width: 3
# ruby-indent-level: 3
# End:
# vim: ts=3
tdiary-contrib-5.1.0/plugin/make_link.rb 0000664 0000000 0000000 00000002043 13570131474 0020230 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
# Copyright (C) 2011, KADO Masanori
# You can redistribute it and/or modify it under GPL.
# needs category.rb plugin
add_edit_proc do
<<-HTML
Link URL:
Get Title and Link
HTML
end
tdiary-contrib-5.1.0/plugin/makerss_category.rb 0000664 0000000 0000000 00000001664 13570131474 0021650 0 ustar 00root root 0000000 0000000 #
# makerss_category.rb: extension for makerss plugin.
#
# Copyright (C) 2007 by SHIBATA Hiroshi
# Distributed under GPL2.
#
# Usage:
# @conf['makerss.category'] = ["mixi", "sns"]
#
class MakeRssCategory < MakeRssFull
def title
'(category only)'
end
def item( seq, body, rdfsec )
return unless rdfsec.section.respond_to?( :body_to_html )
return if rdfsec.section.categories.length == 0
rdfsec.section.categories.each do |category|
if @conf['makerss.category'].include?(category)
super
end
end
end
def file
f = @conf['makerss.category.file'] || 'category.rdf'
f = 'category.rdf' if f.length == 0
f =~ %r|^/| ? f : "#{document_root}/#{f}"
end
def write( encoder )
super( encoder )
end
def url
u = @conf['makerss.category.url'] || "#{@conf.base_url}category.rdf"
u = "#{@conf.base_url}category.rdf" if u.length == 0
u
end
end
@makerss_rsses << MakeRssCategory::new( @conf, @cgi )
tdiary-contrib-5.1.0/plugin/makerss_comment.rb 0000664 0000000 0000000 00000001326 13570131474 0021470 0 ustar 00root root 0000000 0000000 #
# makerss_comment.rb: extension for makerss plugin.
#
# Copyright (C) 2007 by SHIBATA Hiroshi
# Distributed under GPL2.
#
class MakeRssComments < MakeRssFull
def title
'(comments only)'
end
def item( seq, body, rdfsec )
return if rdfsec.section.respond_to?( :body_to_html )
super
end
def file
f = @conf['makerss.no_comments.file'] || 'comments.rdf'
f = 'comments.rdf' if f.length == 0
f =~ %r|^/| ? f : "#{document_root}/#{f}"
end
def write( encoder )
super( encoder )
end
def url
u = @conf['makerss.no_comments.url'] || "#{@conf.base_url}comments.rdf"
u = "#{@conf.base_url}comments.rdf" if u.length == 0
u
end
end
@makerss_rsses << MakeRssComments::new( @conf, @cgi )
tdiary-contrib-5.1.0/plugin/mathjax.rb 0000664 0000000 0000000 00000001407 13570131474 0017735 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
# mathjax.rb $Revision: $
#
# MathJaxを使った数式表示のためのプラグイン
#
# MathJaxでTeXやMathMLを使った数式を埋め込むことができます。
#
# MathJaxについては、http://www.mathjax.org/ を参照のこと
#
# Copyright (C) 2014 by Yuh Ohmura
#
=begin ChangeLog
2017-06-05 Yuh Ohmura
* Modity MathJax address.
2014-12-17 Yuh Ohmura
* created.
=end
add_header_proc do
'
'
end
tdiary-contrib-5.1.0/plugin/microsummary.rb 0000664 0000000 0000000 00000003352 13570131474 0021031 0 ustar 00root root 0000000 0000000 # microsummary.rb
#
# Copyright (c) 2006 elytsllams
# Distributed under the GPL
#
add_header_proc do
generator_xml = @conf['generator.xml']
if generator_xml != nil and @mode == 'latest' and !@cgi.valid?( 'date' )
%Q|\t \n|
end
end
def create_xml file_name
xml = <<-XML
-
-
^#{@conf.base_url.gsub(/\./, '\\.')}$
XML
begin
File::open( file_name, 'w' ) do |f|
f.print to_utf8( xml )
end
rescue
end
end
def microsummary_init
@conf['generator.xml'] ||= ""
create_xml( @conf['generator.xml'] ) unless File::exists? @conf['generator.xml']
end
if @mode == 'saveconf'
def saveconf_microsummary
@conf['generator.xml'] = @cgi.params['generator.xml'][0]
end
end
tdiary-contrib-5.1.0/plugin/mm_footer.rb 0000664 0000000 0000000 00000012403 13570131474 0020266 0 ustar 00root root 0000000 0000000 #
# mm_footer.rb
#
# MM ( http://1470.net/mm/) のmylistを各日付に貼り付けるtDiaryプラグイン
#
# Licence: GPL
# Author: ishinao
#
require 'nkf'
add_body_leave_proc do |date|
oldest_date = Time.local(2005, 1, 11)
if date > oldest_date
if @mode == 'day' or @mode == 'latest'
if date < Time.local(2006, 7, 6)
mm_user = 82 # your MM id
url = "http://1470.net/mm/mylist.html/#{mm_user}?date=#{date.strftime('%Y-%m-%d')}"
rssurl = "http://1470.net/mm/mylist.html/#{mm_user}?date=#{date.strftime('%Y-%m-%d')}&mode=rss"
template_list = '#{content} '
else
userName = 'hsbt' # your 1470.net id
url = "http://1470.net/user/#{userName}/#{date.strftime('%Y/%m/%d')}"
rssurl = "http://1470.net/user/#{userName}/#{date.strftime('%Y/%m/%d')}/feed"
template_list = '#{content.gsub(/href="\//, "href=\"http://1470.net\/")} '
end
template_head = %Q[\n"
cache_time = 3600;
if date.strftime('%Y-%m-%d') != Time.now.strftime('%Y-%m-%d')
cache_time = 3600 * 12;
end
NKF.nkf('-e', mm_footer(rssurl, 50, cache_time, template_head, template_list, template_foot))
else
''
end
end
end
require "rss/rss"
MM_FOOTER_FIELD_SEPARATOR = "\0"
MM_FOOTER_ENTRY_SEPARATOR = "\1"
MM_FOOTER_VERSION = "0.0.5i"
MM_FOOTER_HTTP_HEADER = {
"User-Agent" => "tDiary RSS recent plugin version #{MM_FOOTER_VERSION}. " <<
"Using RSS parser version is #{::RSS::VERSION}.",
}
def mm_footer(url, max = 5, cache_time = 3600, \
template_head = "\n", \
template_list = ' \n', \
template_foot = " \n")
url.untaint
cache_file = "#{@cache_path}/rss-recent/rss-recent.#{CGI.escape(url)}"
mm_footer_cache_rss(url, cache_file, cache_time.to_i)
return '' unless test(?r, cache_file)
rv = template_head
i = 0
mm_footer_read_from_cache(cache_file).each do |title, url, time, content|
break if i >= max
next if (url.nil? or title.nil?)
rv << eval('%Q[' + template_list + ']')
i += 1
end
rv << template_foot
if i > 0
rv
else
''
end
end
class InvalidResourceError < StandardError; end
def mm_footer_cache_rss(url, cache_file, cache_time)
cached_time = nil
cached_time = File.mtime(cache_file) if File.exist?(cache_file)
if cached_time.nil? or Time.now > cached_time + cache_time
require 'time'
require 'open-uri'
require 'net/http'
require 'uri/generic'
require 'rss/parser'
require 'rss/1.0'
require 'rss/2.0'
require 'rss/dublincore'
require 'rss/content'
begin
uri = URI.parse(url)
raise URI::InvalidURIError if uri.scheme != "http"
rss_source = mm_footer_fetch_rss(uri, cached_time)
raise InvalidResourceError if rss_source.nil?
# parse RSS
rss = ::RSS::Parser.parse(rss_source, false)
raise ::RSS::Error if rss.nil?
# pre processing
begin
rss.output_encoding = @conf.charset || charset
rescue ::RSS::UnknownConversionMethodError
end
rss_infos = rss.items.collect do |item|
mm_footer_pubDate_to_dc_date(item)
[item.title, item.link, item.dc_date, item.content_encoded]
end
mm_footer_write_to_cache(cache_file, rss_infos)
rescue URI::InvalidURIError
mm_footer_write_to_cache(cache_file, [['Invalid URI', url]])
rescue InvalidResourceError, ::RSS::Error
# mm_footer_write_to_cache(cache_file, [['Invalid Resource', url]])
# when cannot get valid RSS, use old cache
end
end
end
def mm_footer_fetch_rss(uri, cache_time)
rss = nil
begin
uri.open(mm_footer_http_header(cache_time)) do |f|
case f.status.first
when "200"
rss = f.read
# STDERR.puts "Got RSS of #{uri}"
when "304"
# not modified
# STDERR.puts "#{uri} does not modified"
else
raise InvalidResourceError
end
end
rescue TimeoutError, SocketError, StandardError,
SecurityError # occured in redirect
raise InvalidResourceError
end
rss
end
def mm_footer_http_header(cache_time)
header = MM_FOOTER_HTTP_HEADER.dup
if cache_time.respond_to?(:rfc2822)
header["If-Modified-Since"] = cache_time.rfc2822
end
header
end
def mm_footer_write_to_cache(cache_file, rss_infos)
File.open(cache_file, 'w') do |f|
f.flock(File::LOCK_EX)
rss_infos.each do |info|
f << info.join(MM_FOOTER_FIELD_SEPARATOR)
f << MM_FOOTER_ENTRY_SEPARATOR
end
f.flock(File::LOCK_UN)
end
end
def mm_footer_read_from_cache(cache_file)
require 'time'
infos = []
File.open(cache_file) do |f|
while info = f.gets(MM_FOOTER_ENTRY_SEPARATOR)
info = info.chomp(MM_FOOTER_ENTRY_SEPARATOR)
infos << info.split(MM_FOOTER_FIELD_SEPARATOR)
end
end
infos.collect do |title, url, time, content|
[
mm_footer_convert(title),
mm_footer_convert(url),
mm_footer_convert(time) {|time| Time.parse(time)},
mm_footer_convert(content)
]
end
end
def mm_footer_convert(str)
if str.nil? or str.empty?
nil
else
if block_given?
yield str
else
str
end
end
end
def mm_footer_pubDate_to_dc_date(target)
if target.respond_to?(:pubDate)
class << target
alias_method(:dc_date, :pubDate)
end
end
end
tdiary-contrib-5.1.0/plugin/monthly_autopagerize.rb 0000664 0000000 0000000 00000003415 13570131474 0022553 0 ustar 00root root 0000000 0000000 #
# monthly_autopagerize.rb - tDiary plugin
#
# add and tags for AutoPagerize at monthly mode
#
# Copyright (C) 2009 MATSUI Shinsuke
# You can redistribute it and/or modify it under GPL2.
#
if @mode == 'month' then
add_header_proc do
stream = @conf['monthly_autopagerize.stream'] || 0
result = String.new
ym = []
@years.keys.each do |y|
ym += @years[y].collect {|m| y + m}
end
ym.sort!
now = @date.strftime( '%Y%m' )
return '' unless ym.index( now )
prev_month = ym.index( now ) == 0 ? nil : ym[ym.index( now )-1]
next_month = ym[ym.index( now )+1]
case stream
#when 0
# rel_prev_month = 'next'
# rel_next_month = 'prev'
when 1
rel_prev_month = 'prev'
rel_next_month = 'next'
else
rel_prev_month = 'next'
rel_next_month = 'prev'
end
if prev_month then
result << %Q[ \n\t]
end
if next_month then
result << %Q[ \n\t]
end
result.chop.chop
end
end
add_conf_proc( 'monthly_autopagerize', 'Monthly AutoPagerize' ) do
if @mode == 'saveconf' then
@conf['monthly_autopagerize.stream'] = @cgi.params['monthly_autopagerize.stream'][0].to_i
end
<<-HTML
Stream of Monthly AutoPagerize
To Past
To Future
HTML
end
# Local Variables:
# mode: ruby
# indent-tabs-mode: t
# tab-width: 3
# ruby-indent-level: 3
# End:
# vi: ts=3 sw=3
tdiary-contrib-5.1.0/plugin/my_hotentry.rb 0000664 0000000 0000000 00000007744 13570131474 0020674 0 ustar 00root root 0000000 0000000 # show my hot-entry in Hatena::Bookmark
#
# usage:
# <%= my_hotentry %>
#
# Copyright (c) MATSUOKA Kohei
# Distributed under the GPL
#
require 'uri'
require 'open-uri'
require 'rexml/document'
require 'pstore'
require 'timeout'
# 人気の日記のソート順(新着順: eid, 注目順: hot, 人気順: count)
@conf ||= {}
@conf['my_hotentry.sort'] ||= 'hot'
class MyHotEntry
def initialize(dbfile)
@dbfile = dbfile
end
# 人気の日記の一覧を返す
def entries
r = nil
PStore.new(@dbfile).transaction(true) do |db|
r = db[:entries]
end
r || []
end
# 人気の日記一覧を取得する
def update(base_url, options = {})
options[:title] ||= ''
options[:sort] ||= 'eid'
options[:threshold] ||= 3
# RSSを取得
rss = nil
rss_url = 'http://b.hatena.ne.jp/entrylist?mode=rss&url='
rss_url << URI.escape(base_url, /[^-.!~*'()\w]/n)
rss_url << "&sort=#{options[:sort]}&threshold=#{options[:threshold]}"
begin
Timeout.timeout(5) do
# convert Tempfile to String because REXML can't accept Tempfile
open(rss_url) do |f|
rss = REXML::Document.new(f.readlines.join("\n"))
end
end
rescue TimeoutError => e
return
end
# RDF/itemが空ならDBを更新しない (たまにitemが空のデータが返るため)
return if rss.elements['rdf:RDF/item'].nil?
# キャッシュに格納する
PStore.new(@dbfile).transaction do |db|
db[:entries] = []
rss.elements.each('rdf:RDF/item') do |item|
url = item.elements['link'].text
title = item.elements['title'].text
# リンク先のタイトルからサイト名と日付を取り除く
title.sub!(/(?: - )?#{options[:html_title]}(?: - )?/, '')
title.sub!(/\(\d{4}-\d{2}-\d{2}\)/, '')
db[:entries].push({ :url => url, :title => title })
end
end
end
end
# キャッシュファイルのパスを取得する
def my_hotentry_dbfile
cache_dir = "#{@cache_path}/hatena"
Dir::mkdir(cache_dir) unless File::directory?(cache_dir)
"#{cache_dir}/my_hotentry.dat"
end
# 人気の日記一覧を表示する
def my_hotentry(count = 5)
dbfile = my_hotentry_dbfile
hotentry = MyHotEntry.new(dbfile)
r = %Q||
r << %Q|\n|
end
# 人気の日記一覧を更新する
def my_hotentry_update
dbfile = my_hotentry_dbfile
hotentry = MyHotEntry.new(dbfile)
hotentry.update(@conf.base_url,
:html_title => @conf.html_title,
:sort => @conf['my_hotentry.sort'])
end
if __FILE__ == $0
# コマンドラインから実行した場合
# tdiary.conf に base_url を設定しないと動作しない
begin
require 'tdiary'
rescue LoadError
STDERR.puts "tdiary.rb not found."
STDERR.puts "please execute in tdiary base directory"
exit 1
end
cgi = CGI::new
@conf = TDiary::Config::new(cgi)
@cache_path = @conf.cache_path || "#{@conf.data_path}cache"
my_hotentry_update
puts my_hotentry
else
# 人気の日記一覧を取得する (日記更新時)
add_update_proc do
# ツッコミ時は実行しない
if @mode == 'append' or @mode == 'replace'
begin
my_hotentry_update
rescue
end
end
end
end
tdiary-contrib-5.1.0/plugin/navi_day.rb 0000664 0000000 0000000 00000006763 13570131474 0020105 0 ustar 00root root 0000000 0000000 #
# navi_day.rb
#
# navi_day: 「前の日記」や「次の日記」を“月またぎ”に対応させる。
#
# 日単位での表示の時の「前の日記」や「次の日記」のリンクが、
# 異なる月の日記を正しく指せない場合があるという tDiary の制限を
# 解消するプラグインです。以前よりある navi_user.rb と機能的には
# 同じですが、navi_user.rb よりは処理がずっと軽くなっています。
# また、日記の表示状態(非表示の日記)に対する考慮もなされています。
#
# tDiary 2.0 以降で使えると思います。セキュアモードでも使えますが、
# セキュアモードの場合は、モバイル端末からのアクセスに対しては
# このプラグインは効力を持ちません(tDiary セキュア環境の制限:
# モバイル端末の場合は本文を出力するときに calc_links が呼ばれる
# ため)。
#
# navi_user.rb と併用すると navi_user.rb の方が優先されますので、
# このプラグインを使うときには必ず navi_user.rb を外してください。
#
# Copyright (C) 2007, MIYASAKA Masaru
# You can redistribute it and/or modify it under GPL2.
#
# Last Modified : May 27, 2007
#
# for tDiary 2.0.X
if not TDiaryMonth.method_defined?(:diaries) then
eval( <<-MODIFY_CLASS, TOPLEVEL_BINDING )
module TDiary
class TDiaryMonth
attr_reader :diaries
end
end
MODIFY_CLASS
end
class NaviDayCGI
attr_reader :params
def referer; nil; end
def initialize
@params = Hash.new([])
end
end
alias :calc_links_navi_day_backup :calc_links
def calc_links
if not @conf.secure and \
(/day|edit/ =~ @mode or \
/latest|month|nyear/ =~ @mode) then
if /(latest|month|nyear)/ === @mode
today = @diaries.keys.sort[-1]
else
today = @date.strftime('%Y%m%d')
end
days = @diaries.keys
days |= [today]
days.sort!
days.unshift(nil).push(nil)
today_index = days.index(today)
days[0 .. today_index - 1].reverse_each do |prev_day|
@prev_day = prev_day
break unless @prev_day
break if (@mode == 'edit') or @diaries[@prev_day].visible?
end
days[today_index + 1 .. -1].each do |next_day|
@next_day = next_day
break unless @next_day
break if (@mode == 'edit') or @diaries[@next_day].visible?
end
if not @prev_day or not @next_day then
cgi = NaviDayCGI.new
years = []
@years.each do |k, v|
v.each do |m|
years << k + m
end
end
this_month = @date.strftime('%Y%m')
years |= [this_month]
years.sort!
years.unshift(nil).push(nil)
this_month_index = years.index(this_month)
years[0 .. this_month_index - 1].reverse_each do |prev_month|
break unless not @prev_day and prev_month
cgi.params['date'] = [prev_month]
diaries = TDiaryMonth.new(cgi, '', @conf).diaries
days = diaries.keys.sort
days.unshift(nil)
days.reverse_each do |prev_day|
@prev_day = prev_day
break unless @prev_day
break if (@mode == 'edit') or diaries[@prev_day].visible?
end
end
years[this_month_index + 1 .. -1].each do |next_month|
break unless not @next_day and next_month
cgi.params['date'] = [next_month]
diaries = TDiaryMonth.new(cgi, '', @conf).diaries
days = diaries.keys.sort
days.push(nil)
days.each do |next_day|
@next_day = next_day
break unless @next_day
break if (@mode == 'edit') or diaries[@next_day].visible?
end
end
end
else
calc_links_navi_day_backup
end
end
tdiary-contrib-5.1.0/plugin/navi_this_month.rb 0000664 0000000 0000000 00000000630 13570131474 0021467 0 ustar 00root root 0000000 0000000 # navi-this-month.rb
# ref. http://www.tom.sfc.keio.ac.jp/~sakai/d/?date=20080628#p01
#
alias navi_this_month__orig__navi_user_day navi_user_day
def navi_user_day
result = navi_this_month__orig__navi_user_day
if @mode=='day'
this_month = @date.strftime( '%Y%m' )
result << navi_item( "#{@index}#{anchor this_month}", "#{navi_this_month}" )
end
result
end
def navi_this_month; "月表示"; end
tdiary-contrib-5.1.0/plugin/nhk_program_info.rb 0000664 0000000 0000000 00000005704 13570131474 0021627 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
#
# nhk_program_info.rb - embedded NHK program information
# refer to following URL.
# http://api-portal.nhk.or.jp/ja
#
# Copyright (C) 2014, tamoot
# You can redistribute it and/or modify it under GPL2.
#
require 'json'
require 'date'
require 'timeout'
require 'open-uri'
def nhk_program_info(id, service, area = nil)
area = @conf['nhk_api.default.area'] if area.nil? || area == ""
json = nil
begin
json = call_nhk_json(id, service, area)
rescue
return %Q|#{__FILE__}: error, #{$!}
|
end
stime = DateTime::parse(json["start_time"]).strftime("%Y/%m/%d %H:%M:%S")
etime = DateTime::parse(json["end_time"]).strftime("%Y/%m/%d %H:%M:%S")
return <<-PROGRAM_HTML
PROGRAM_HTML
end
def call_nhk_json(id, service, area)
data = nil
nhk_endpoint = "http://api.nhk.or.jp/v1/pg/info/#{area}/#{service}/#{id}.json?key=#{@conf['nhk_api.id']}"
nhk_cache_path = "#{@cache_path}/nhk"
Dir::mkdir(nhk_cache_path) unless File::directory?(nhk_cache_path)
cache = "#{nhk_cache_path}/#{area}_#{service}_#{id}.json"
begin
data = File.read(cache)
File::delete(cache) if Time::now > File::mtime( cache ) + 60*60*24*30
rescue
open_param = [nhk_endpoint]
open_param << {:proxy => "http://#{@conf['proxy']}"} if @conf['proxy']
status = nil
data = nil
Timeout.timeout(10) do
open(*open_param){ |ff| data = ff.read; status = ff.status[0] }
end
raise "API Error" if status.to_s != '200'
File::open(cache, 'wb') {|f| f.write(data) }
end
JSON::parse(data)['list'][service][0]
end
add_conf_proc( 'nhk', 'NHK API' ) do
if @mode == 'saveconf' then
@conf['nhk_api.id'] = @cgi.params['nhk_api.id'][0]
@conf['nhk_api.default.area'] = @cgi.params['nhk_api.default.area'][0]
end
<<-HTML
API key
Register your tDiary and get API key.
Go NHK API settings.
Default Area
Refer NHK API settings.
HTML
end
# Local Variables:
# mode: ruby
# indent-tabs-mode: t
# tab-width: 3
# ruby-indent-level: 3
# End:
# vim: ts=3
tdiary-contrib-5.1.0/plugin/nicovideo.rb 0000664 0000000 0000000 00000007615 13570131474 0020267 0 ustar 00root root 0000000 0000000 #
# nicovideo.rb - tDiary plugin for Nico Nico Video
#
# Copyright (C) 2012 TADA Tadashi
# You can modify and/or distribute it under GPL.
#
# usage:
# Link to the movie and show thumbnail, description...:
# <%= nicovideo 'sm99999999' %>
#
# Link to the movie with original label:
# <%= nicovideo 'sm99999999', 'movie title' %>
#
# Link to the movie with original label and link:
# <%= nicovideo 'sm99999999', 'movie title', 'http://example.com/video' %>
#
# Show Inline player:
# <%= nicovideo_player 'sm99999999' %>
#
# Show Inline player with size:
# <%= nicovideo_player 'sm99999999', [400,300] %>
#
require 'net/http'
require 'timeout'
enable_js('nicovideo.js') unless base_url =~ /\Ahttps:/
def nicovideo_call_api( video_id )
uri = "http://ext.nicovideo.jp/api/getthumbinfo/#{video_id}"
proxy = @conf['proxy']
proxy = 'http://' + proxy if proxy
xml = Timeout.timeout( feed? ? 10 : 2 ) {
px_host, px_port = (@conf['proxy'] || '').split( /:/ )
px_port = 80 if px_host and !px_port
Net::HTTP::Proxy( px_host, px_port ).get_response( URI::parse( uri ) ).body
}
status = xml.scan(%r||).flatten.first
if status == 'ok' then
raw_api = xml.scan(%r|(.*) |m).flatten.first.scan(%r|<(.*?)>(.*)|)
api = {}
raw_api.each do |key, value|
api[key] = @conf.to_native( value )
end
api
else
raise ::Errno::ENOENT::new
end
end
def nicovideo_inline( video_id, elem, label = nil, link = nil )
i = {}
i[:id] = video_id
i[:url] = link || elem['watch_url']
i[:thumb] = elem['thumbnail_url']
i[:title] = label || elem['title']
i[:desc] = elem['description']
i[:comment] = elem['last_res_body']
i[:date] = elem['first_retrieve']
i[:length] = elem['length']
i[:view] = elem['view_counter']
i[:comment_num] = elem['comment_num']
i[:mylist] = elem['mylist_counter']
if feed? then
result = nicovideo_feed( i )
else
result = nicovideo_html( i )
end
result.gsub( /^\t+/, '' )
end
def nicovideo_iframe( video_id )
%Q|\n|
end
def nicovideo_player(video_id, size = [640,360])
if feed?
nicovideo(video_id)
else
q = size ? "?w=#{h size[0]}&h=#{h size[1]}" : ''
%Q||
end
end
def nicovideo( video_id, label = nil, link = nil )
begin
r = ''
r << %Q||
api = nicovideo_call_api( video_id )
thumb = @conf.to_native( nicovideo_inline( video_id, api, label, link ), 'UTF-8' )
r << thumb
r << '
'
if feed?
r.gsub!( /]*)?>/, '' )
r.gsub!( %r{ }, '' )
else
r << %Q||
end
r
rescue ::Errno::ENOENT
"Sorry, #{video_id} was deleted. "
rescue Timeout::Error, NoMethodError, SecurityError, StandardError
puts $!
$@.each{|l| puts l}
nicovideo_iframe( video_id )
end
end
tdiary-contrib-5.1.0/plugin/notify_miniblog.rb 0000664 0000000 0000000 00000007220 13570131474 0021470 0 ustar 00root root 0000000 0000000 #
# Copyright (C) 2007 peo
# You can redistribute it and/or modify it under GPL2.
#
# modified hsbt.
require 'net/http'
@miniblog_config = (Struct.const_defined?("MiniBlogConfig") ? Struct::MiniBlogConfig :
Struct.new("MiniBlogConfig", :host, :path))
@miniblog_list = {
'HatenaHaiku' => @miniblog_config.new('h.hatena.ne.jp', '/api/statuses/update.json'),
}
module Miniblog
class Updater
def initialize( user, pass, config )
@user = user
@pass = pass
@config = config
end
# this code is based on http://la.ma.la/blog/diary_200704111918.htm
def update( status )
Net::HTTP.version_1_2
req = Net::HTTP::Post.new(@config.path)
req.basic_auth(@user, @pass)
req.body = status
Net::HTTP.start( @config.host, 80 ) do |http|
response = http.request(req)
if response.body =~ /error/
raise 'update failed.'
end
end
end
end
end
def notify_miniblog
notify_miniblog_init
date = @date.strftime('%Y%m%d')
diary = @diaries[date]
sectitle = ''
index = 0
diary.each_section do |sec|
index += 1
sectitle = sec.subtitle
end
# strip category
sectitle.gsub!(/\[[^\]]+\] */, '')
url = URI.encode(@conf.base_url + anchor("#{date}p%02d" % index), /[^-.!~*'()\w]/n)
prefix = @conf['miniblog.notify.prefix']
format = @conf['miniblog.notify.format']
source = 'tdiary/notify_miniblog.rb'
status = 'status=' + format % [prefix, sectitle, url] + '&source=' + source
if @conf['miniblog.service'] == "HatenaHaiku" then
status += '&keyword=id:' + @conf['miniblog.user']
end
config = @miniblog_list[@conf['miniblog.service']]
begin
miniblog_updater = Miniblog::Updater.new(@conf['miniblog.user'], @conf['miniblog.pass'], config)
miniblog_updater.update( status )
rescue => e
@logger.debug( e )
end
end
def notify_miniblog_init
@conf['miniblog.notify.prefix'] ||= '[blog update]'
@conf['miniblog.notify.format'] ||= '%s %s %s'
@conf['miniblog.service'] ||= 'Twitter'
end
add_update_proc do
if @mode == 'append' then
notify_miniblog if @cgi.params['miniblog.notify'][0] == 'true'
end
end
add_edit_proc do
checked = ''
if @mode == 'preview' then
checked = @cgi.params['miniblog.notify'][0] == 'true' ? ' checked' : ''
end
<<-HTML
Post the update to #{@conf['miniblog.service']}
HTML
end
add_conf_proc( 'notify_miniblog', 'MiniBlog' ) do
notify_miniblog_init
if @mode == 'saveconf' then
@conf['miniblog.service'] = @cgi.params['miniblog.service'][0]
@conf['miniblog.user'] = @cgi.params['miniblog.user'][0]
@conf['miniblog.pass'] = @cgi.params['miniblog.pass'][0]
@conf['miniblog.notify.prefix'] = @cgi.params['miniblog.notify.prefix'][0]
@conf['miniblog.notify.format'] = @cgi.params['miniblog.notify.format'][0]
end
options = ''
@miniblog_list.each_key do |key|
options << %Q|#{h key} \n|
end
<<-HTML
MiniBlog Service
#{options}
Account Name
Account Password
Notify prefix
Notify status format
HTML
end
# vim:ts=3
tdiary-contrib-5.1.0/plugin/ogp.rb 0000664 0000000 0000000 00000003624 13570131474 0017071 0 ustar 00root root 0000000 0000000 # ogp.rb - add Open Graph Protocol tags to header
#
# Copyright (c) 2011 MATSUOKA Kohei
# You can redistribute it and/or modify it under GPL2.
#
# @conf['ogp.facebook.app_id'] - your facebook application ID.
# @conf['ogp.facebook.admins'] - your facebook ID.
def ogp_description(html)
@conf.shorten(remove_tag(html), 200)
end
def ogp_image(html)
images = html.scan(/ @conf['ogp.facebook.app_id'],
'fb:admins' => @conf['ogp.facebook.admins']
}
if @mode == 'day'
# remove original og:image generated at 00default.rb
ogp.gsub!(/ ]+>\n/, '')
diary = @diaries[@date.strftime('%Y%m%d')]
if diary
sections = diary.instance_variable_get(:@sections)
section_index = @cgi.params['p'][0] || sections.size
begin
section = sections[section_index.to_i - 1].body_to_html
section_html = apply_plugin(section)
headers['og:description'] = ogp_description(section_html)
headers['og:image'] = ogp_image(section_html)
rescue
end
end
end
ogp + "\n" + headers.select {|key, val|
val && !val.empty?
}.map {|key, val|
%Q| |
}.join("\n")
end
add_conf_proc('Open Graph Protocol', 'Open Graph Protocol') do
if @mode == 'saveconf'
@conf['ogp.facebook.app_id'] = @cgi.params['ogp.facebook.app_id'][0]
@conf['ogp.facebook.admins'] = @cgi.params['ogp.facebook.admins'][0]
end
<<-HTML
Facebook Application ID
Facebook User ID
HTML
end
tdiary-contrib-5.1.0/plugin/ohmsha_estore.rb 0000664 0000000 0000000 00000000630 13570131474 0021136 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
# You can redistribute it and/or modify it under the same license as tDiary.
#
# display book info in https://estore.ohmsha.co.jp/ like amazon.rb
# USAGE: {{ohmsha_estore '978427406694P'}}
def ohmsha_estore( id, doc = nil )
"Ohmsha eBook Store is no longer available.
\n"
end
# Local Variables:
# mode: ruby
# indent-tabs-mode: t
# tab-width: 3
# ruby-indent-level: 3
# End:
tdiary-contrib-5.1.0/plugin/openid.rb 0000664 0000000 0000000 00000007712 13570131474 0017564 0 ustar 00root root 0000000 0000000 #
# openid.rb: Insert OpenID delegation information. $Revision: 1.10 $
#
# Copyright (C) 2005, TADA Tadashi
# You can redistribute it and/or modify it under GPL2.
#
@openid_config = (Struct.const_defined?("OpenIdConfig") ? Struct::OpenIdConfig :
Struct.new("OpenIdConfig", :openid, :openid2, :x_xrds_location))
if /^(?:latest|conf|saveconf)$/ =~ @mode then
@openid_list = {
# service => @openid_config.new(
# [openid.server, openid.delegate(replace as account name)], # openid
# [openid2.provider, openid2.local_id(replace as account name)], # openid2
# 'X-XRDS-Location(replace as account name)'),
'Hatena' => @openid_config.new(['https://www.hatena.ne.jp/openid/server', 'http://www.hatena.ne.jp//']),
'livedoor' => @openid_config.new(['http://auth.livedoor.com/openid/server', 'http://profile.livedoor.com/']),
'LiveJournal' => @openid_config.new(['http://www.livejournal.com/openid/server.bml', 'http://.livejournal.com/']),
'OpenID.ne.jp' => @openid_config.new(
['http://www.openid.ne.jp/user/auth', 'http://.openid.ne.jp'],
nil,
'http://.openid.ne.jp/user/xrds'),
'TypeKey' => @openid_config.new(['http://www.typekey.com/t/openid/', 'http://profile.typekey.com//']),
'Vox' => @openid_config.new(['http://www.vox.com/services/openid/server', 'http://.vox.com/']),
'myopenid.com' => @openid_config.new(
['http://www.myopenid.com/server', 'http://.myopenid.com'], # openid
['http://www.myopenid.com/server', 'http://.myopenid.com'], # openid2
"http://www.myopenid.com/xrds?username="),
'claimID.com' => @openid_config.new(
['http://openid.claimid.com/server', 'http://openid.claimid.com/'],
nil, #['http://openid.claimid.com/server', 'http://openid.claimid.com/'],
'http://claimid.com//xrds'),
'Personal Identity Provider (PIP)' => @openid_config.new(
['http://pip.verisignlabs.com/server', 'http://.pip.verisignlabs.com/'],
['http://pip.verisignlabs.com/server', 'http://.pip.verisignlabs.com/'],
'http://pip.verisignlabs.com/user//yadisxrds'),
'Yahoo! Japan' => @openid_config.new(
nil,
['https://open.login.yahooapis.jp/openid/op/auth', 'https://me.yahoo.co.jp/a/'],
'http://open.login.yahoo.co.jp/openid20/www.yahoo.co.jp/xrds'),
'Yahoo!' => @openid_config.new(
nil,
['https://open.login.yahooapis.com/openid/op/auth', 'https://me.yahoo.com/a/'],
'http://open.login.yahooapis.com/openid20/www.yahoo.com/xrds'),
}
if @conf['openid.service'] and @conf['openid.id'] then
openid_service = @openid_list[@conf['openid.service']]
openid_id = @conf['openid.id']
result = ''
add_header_proc do
result = <<-HTML if openid_service.openid
HTML
result << <<-HTML if openid_service.openid2
HTML
result << <<-HTML if openid_service.x_xrds_location
HTML
result.gsub( /^\t{2}/, '' )
end if openid_service
end
end
add_conf_proc( 'openid', @openid_conf_label ) do
if @mode == 'saveconf' then
@conf['openid.service'] = @cgi.params['openid.service'][0]
@conf['openid.id'] = @cgi.params['openid.id'][0]
end
options = ''
@openid_list.each_key do |key|
options << %Q|#{h key} \n|
end
<<-HTML
#{@openid_service_label}
#{@openid_service_desc}
#{options}
#{@openid_id_label}
#{@openid_id_desc}
HTML
end
tdiary-contrib-5.1.0/plugin/opensearch_ad.rb 0000664 0000000 0000000 00000002050 13570131474 0021067 0 ustar 00root root 0000000 0000000 # opensearch_ad.rb $Revision: 1.1 $
#
# Copyright (c) 2008 SHIBATA Hiroshi
# Distributed under the GPL
#
if /\A(?:latest|day)\z/ =~ @mode then
if @conf['opensearch.xml'] and @conf['opensearch.title'] then
opensearch_xml = @conf['opensearch.xml']
opensearch_title = @conf['opensearch.title']
add_header_proc do
result = <<-HTML
HTML
result.gsub( /^\t\t/, '' )
end
end
end
add_conf_proc( 'opensearch_ad', 'OpenSearch Auto-Discovery' ) do
if @mode == 'saveconf'
@conf['opensearch.xml'] = @cgi.params['opensearch.xml'][0]
@conf['opensearch.title'] = @cgi.params['opensearch.title'][0]
end
<<-HTML
Tilte for OpenSearch
URI for OpenSearch description XML
HTML
end
tdiary-contrib-5.1.0/plugin/picasa.rb 0000664 0000000 0000000 00000001435 13570131474 0017542 0 ustar 00root root 0000000 0000000 # show photo image on Picasa Web Album
#
# usage:
# picasa( src[, title[, place]] )
# - src: The url of the photo to show.
# - title: title of photo. (optional)
# - place: class name of img element. default is 'photo'.
#
# picasa_left( src[, title] )
#
# picasa_right( src[, title] )
#
# options configurable through settings:
# @conf['picasa.user'] : picasa username
# @conf['picasa.default_size'] : default image size
#
# Copyright (c) hb
# Distributed under the GPL.
#
def picasa( src, alt = "photo", place = 'photo' )
%Q| |
end
def picasa_left( src, alt = "photo" )
picasa( src, alt, 'left' )
end
def picasa_right( src, alt = "photo" )
picasa( src, alt, 'right' )
end
tdiary-contrib-5.1.0/plugin/plantuml.rb 0000664 0000000 0000000 00000003341 13570131474 0020134 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
# create image by PlantUML http://plantuml.com/
#
# Copyright (c) tamoot
# Distributed under the GPL
#
require 'uri'
require 'zlib'
require 'digest/md5'
module ::PlantUML
module Deflate
CHARS ||= ('0'..'9').to_a + ('A'..'Z').to_a + ('a'..'z').to_a + ['-', '_']
def self.compress(text)
compressed = Zlib::Deflate.deflate(text, Zlib::BEST_COMPRESSION)
compressed.chars.each_slice(3).map do |chars|
append3bytes(chars[0].ord, chars[1]&.ord.to_i, chars[2]&.ord.to_i)
end.join
end
private
def self.append3bytes(b1, b2, b3)
[
b1 >> 2,
((b1 & 0x3) << 4) | (b2 >> 4),
((b2 & 0xF) << 2) | (b3 >> 6),
b3 & 0x3F,
].map { |c| CHARS[c & 0x3F] || '?' }.join
end
end
end
def plantuml(text)
html = %Q||
begin
uri = URI::parse( @conf['plantuml.server'] )
uri.path.gsub!(/\/+$/, "")
uri.path << '/png/' << PlantUML::Deflate::compress(text)
html << %Q|
|
rescue
html << %Q|Error: #{$!.message}|
end
html << %Q|
|
end
add_conf_proc('plantuml_server', 'PlantUMLサーバ') do
if @mode == 'saveconf'
@conf['plantuml.server'] = @cgi.params['plantuml.server'][0]
end
r = <<-_HTML
Summary
The image is generated by using specified PlantUML server.
URL
Please specify the PlantUML server URL (official site or your own PlantUML server)
Official PlantUML server: http://www.plantuml.com/plantuml/
_HTML
r
end
tdiary-contrib-5.1.0/plugin/playstore.rb 0000664 0000000 0000000 00000007313 13570131474 0020325 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
# playstore.rb
#
# 概要:
# GooglePlay(play.google.com)へのリンクを生成します。
#
# 使い方:
# playstore'app_id' or playstore_txt'app_id'
#
# Copyright (c) 2014 kp
# Distributed under the GPL
#
begin
require 'market_bot'
rescue
retry if require 'rubygems'
end
require 'date'
class PlayStore < MarketBot::Play::App
def initialize(app_id,option={})
super(app_id,option)
end
def save(path)
File.open(path,"wb"){ |f|
Marshal.dump(self.html,f)
}
end
def load(path)
File.open(path,"rb"){ |f|
begin
html = Marshal.restore(f)
rescue
html = nil
end
}
unless html.nil?
result = PlayStore.parse(html)
response_handler(html)
end
return html
end
def self.valid?(app_id)
return app_id.downcase =~ /^([a-z_]{1}[a-z0-9_]*(\.[a-z_]{1}[a-z0-9_]*)*)$/
end
end
def playstore_load_cache(app)
return nil
path="#{@cache_path}/playstore/#{app.package}"
begin
stat = File::Stat.new(path)
rescue Errno::ENOENT
return nil
end
m = Date.parse(stat.mtime.to_s)
return nil if Date.today - m > 7 # 1week before
return app.load(path)
end
def playstore_save_cache(app)
path="#{@cache_path}/playstore/#{app.package}"
dir = File.dirname(path)
Dir.mkdir(dir) unless File.directory?(dir)
app.save(path)
end
def playstore_main(app_id)
unless PlayStore.valid?(app_id)
return :invalid
end
app = PlayStore.new(app_id,lang:'ja')
if playstore_load_cache(app).nil?
begin
app.update
rescue
return :notfound
end
save = true
else
save = false
end
if app.nil?
return :notfound
else
playstore_save_cache(app) if save
return app
end
end
def playstore(app_id)
app = playstore_main(app_id)
case app
when :invalid
<<-HTML
package name is invalid(#{app_id}).
HTML
when :notfound
<<-HTML
HTML
else
<<-HTML
HTML
end
end
def playstore_text(app_id)
app = playstore_main(app_id)
case app
when :invalid
"package name is invalid(#{app_id}). "
when :notfound
"#{app_id} was not found "
else
%Q[#{app.title} ]
end
end
add_header_proc do
if @mode !~ /conf$/ and not bot? then
<<-HTML
HTML
else
''
end
end
# Local Variables:
# mode: ruby
# indent-tabs-mode: t
# tab-width: 3
# ruby-indent-level: 3
# End:
# vim: ts=3
tdiary-contrib-5.1.0/plugin/plugin_checker.rb 0000664 0000000 0000000 00000002770 13570131474 0021267 0 ustar 00root root 0000000 0000000 # plugin_checker.rb
#
# Copyright (c) 2012 MATSUOKA Kohei
# You can redistribute it and/or modify it under GPL2.
#
def plugin_checker_js_settings
enable_js('plugin_checker.js')
add_js_setting('$tDiary.plugins', plugins.to_json)
add_js_setting('$tDiary.mode', @mode.to_json)
end
if /\A(form|edit|preview|showcomment)\z/ === @mode
add_header_proc do
<<-STYLE
STYLE
end
plugin_checker_js_settings
end
tdiary-contrib-5.1.0/plugin/popit.rb 0000664 0000000 0000000 00000001660 13570131474 0017435 0 ustar 00root root 0000000 0000000 # popit.rb:plugin embedding POP on POPit(http://pop-it.jp)
#
# usage:
# popit(pop_id) - pop_id: The id of the POP on POPit (e.g. 2000 http://pop-it.jp/item/amazon/1989/pop/2000 )
#
# Copyright (c) KAYA Satoshi
# You can redistributed it and/or modify if under GPL2.
#
def popit(pop_id, size = "large")
return unless pop_id
width_size = {"large" => "260", "small" => "180" }
height_size = {"large" => "380", "small" => "220" }
width_style = {"large" => "220px", "small" => "160px" }
sizequery = size == "large" ? "?size=large" : ''
r = ""
r << %Q||
r << %Q||
return r
end
tdiary-contrib-5.1.0/plugin/prettify.rb 0000664 0000000 0000000 00000001403 13570131474 0020143 0 ustar 00root root 0000000 0000000 # prettify.rb
if /\A(?:latest|day|month|nyear)\z/ =~ @mode then
add_header_proc do
<<-HTML
HTML
end
end
tdiary-contrib-5.1.0/plugin/prezi.rb 0000664 0000000 0000000 00000002155 13570131474 0017433 0 ustar 00root root 0000000 0000000 #
# prezi.rb: plugin embedding presentation on prezi.com
#
# Copyright (C) 2010 TADA Tadashi
# You can redistribute it and/or modify it under GPL2.
#
def prezi( prezi_id, label = 'Link to presentation', size = [512,384] )
%Q| |
end
tdiary-contrib-5.1.0/plugin/profile.rb 0000664 0000000 0000000 00000012176 13570131474 0017746 0 ustar 00root root 0000000 0000000 #
# profile.rb: profile plugin for tDiary
#
# usage:
# profile(id[, service = :gravatar])
# - id: user ID for profile service
# - service: profile service (default is :gravatar)
# Choose from :github, :gravatar, :hatena
#
# Copyright (C) 2009 by MATSUOKA Kohei < http://www.machu.jp/ >
# Distributed under the GPL.
#
require 'timeout'
require 'rexml/document'
require 'open-uri'
require 'digest/md5'
require 'pstore'
module ::Profile
module Service
# base class for profile services
class Base
# default attributes
attr_reader :id
attr_reader :image
attr_reader :name
attr_reader :mail
attr_reader :description
attr_reader :link
# class instance variables
class << self
attr_reader :properties
attr_reader :endpoint_proc
end
# set property and xpath pair for parse XML document
def self.property(property, path)
@properties ||= {}
@properties[property] = path
end
# set endpoint proc (this proc is called by initialize method with id)
def self.endpoint(&block)
@endpoint_proc = block
end
def initialize(id, options = {})
@id = id
@options = options
if self.class.endpoint_proc
endpoint = self.class.endpoint_proc.call(id)
doc = fetch(endpoint)
parse(doc)
end
end
# get a XML document from endpoint and create REXML::Document instance
def fetch(endpoint)
Timeout.timeout(5) do
open(endpoint) do |f|
doc = REXML::Document.new(f)
end
end
end
# parse XML document with properties
def parse(doc)
self.class.properties.each do |property, path|
if doc.elements[path]
value = doc.elements[path].text
instance_variable_set("@#{property}", value)
end
end
end
end
# github.com
class GitHub < Base
property :name, 'name'
property :mail, 'email'
property :image, 'avatar_url'
endpoint {|id| "https://api.github.com/users/#{id}" }
def link
"http://github.com/#{@id}"
end
def fetch(endpoint)
require 'json'
Timeout.timeout(5) do
doc = open(endpoint) {|f| JSON.parse(f.read) }
end
end
def parse(doc)
self.class.properties.each do |property, key|
instance_variable_set("@#{property}", doc[key]) if doc[key]
end
end
end
# twitter.com
class Twitter < Base
# dummy class
end
# iddy.jp, for backward compatibility
class Iddy < Base
# dummy class
end
# gravatar.com
class Gravatar < Base
HOST = 'ja.gravatar.com' unless const_defined?(:HOST)
endpoint {|id|
hash = Digest::MD5.hexdigest(id.downcase)
"https://#{HOST}/#{hash}.json"
}
def image
size = @options[:size] ? "?s=#{@options[:size]}" : ""
"#{@image_base}#{size}"
end
def fetch(endpoint)
require 'json'
Timeout.timeout(5) do
begin
doc = open(endpoint) {|f| JSON.parse(f.read) }
rescue RuntimeError => err
if err.message =~ /^redirection forbidden: /
endpoint.sub!(/www/, @options[:lang])
retry
else
raise
end
end
end
end
def parse(doc)
instance_variable_set("@name", doc['entry'][0]['displayName'])
instance_variable_set("@mail", @id)
instance_variable_set("@image_base", doc['entry'][0]['thumbnailUrl'])
instance_variable_set("@link", doc['entry'][0]['profileUrl'])
instance_variable_set("@description", doc['entry'][0]['aboutMe'])
end
end
class Hatena < Base
def image
prefix = id[0..1]
"http://www.hatena.ne.jp/users/#{prefix}/#{id}/profile.gif"
end
def link
"http://www.hatena.ne.jp/#{id}/"
end
end
end
end
PROFILE_VERSION = '20090909'
def profile(id, service = :gravatar, options = {})
html = ''
service_class = {
:github => Profile::Service::GitHub,
:gravatar => Profile::Service::Gravatar,
:hatena => Profile::Service::Hatena,
}[service.to_s.downcase.to_sym] || Profile::Service::Gravatar
# TODO: create cache manager class
# cache = "#{@cache_path}/profile.yaml"
cache = "#{@cache_path}/profile.pstore"
profile = nil
# db = YAML::Store.new(cache)
db = PStore.new(cache)
db.transaction do
key = service_class.name
db[key] ||= {} # initialize db
updated = db[key][:updated]
if updated && (Time::now < updated + 60 * 60) && db[key][:version] == PROFILE_VERSION
# use cache
profile = db[key][:profile]
else
# get latest date and update cache
begin
profile = service_class.new(id, options.merge(lang: @conf.lang))
rescue Timeout::Error, StandardError
return html << %Q{ no profile
}
end
db[key][:updated] = Time::now
db[key][:profile] = profile
db[key][:version] = PROFILE_VERSION
end
end
html << %Q{ }
end
tdiary-contrib-5.1.0/plugin/puboo.rb 0000664 0000000 0000000 00000005056 13570131474 0017431 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
# Copyright (C) 2013, TADA Tadashi
# Original code from tatsu_zine.rb by KADO Masanori
# You can redistribute it and/or modify it under GPL.
#
# display book info in http://p.booklog.jp/ like amazon.rb
# USAGE: {{puboo 9999}}
require 'open-uri'
def puboo_cache_dir
cache = "#{@cache_path}/puboo"
Dir.mkdir( cache ) unless File.directory?( cache )
cache
end
def puboo_cache_set( id, result )
File.open( "#{puboo_cache_dir}/#{id}", "w" ) do |f|
f.write result
end
end
def puboo_cache_get( id )
File.open( "#{puboo_cache_dir}/#{id}", "r" ) do |f|
f.read
end
rescue
nil
end
def puboo( id, doc = nil )
if !@conf.secure and !(result = puboo_cache_get(id)).nil?
return result
end
link = "http://p.booklog.jp/book/#{id}"
doc ||= open( link ).read.force_encoding('UTF-8')
title = doc.match(%r| 価格.*?(.*?) .*? |m).to_a[1]
author = doc.match(%r|作者 (.*?) |m).to_a[1].gsub(/<.*?>/, '').strip
result = <<-EOS
#{h title}
#{h author}
#{h price}
EOS
puboo_cache_set( id, result ) unless @conf.secure
result
rescue
link
end
if __FILE__ == $0
require 'test/unit'
class TestTatsuZine < Test::Unit::TestCase
def setup
@conf = Struct.new("Conf", :secure).new(true)
def h(str); str; end
end
def test_puboo
expect = <<-EOS
入門Puppet - Automate Your Infrastructure
栗林健太郎
890円(税込)
EOS
assert_equal expect, puboo('70667')
end
end
end
# Local Variables:
# mode: ruby
# indent-tabs-mode: t
# tab-width: 3
# ruby-indent-level: 3
# End:
tdiary-contrib-5.1.0/plugin/pygments_css.rb 0000664 0000000 0000000 00000010317 13570131474 0021017 0 ustar 00root root 0000000 0000000 #
# pygments.rb: insert CSS for html formatted code with Pygments.
#
# Copyright (C) 2012 SHIBATA Hiroshi
# You can redistribute it and/or modify it under GPL2.
#
add_header_proc do
<<-STYLE
STYLE
end
tdiary-contrib-5.1.0/plugin/rating.rb 0000664 0000000 0000000 00000030452 13570131474 0017567 0 ustar 00root root 0000000 0000000 # $Revision:0.1$
# rating.rb: 複数軸による記事評価とグラフ表示
# for tDiary
#
# 使い方
# そのまま plugin ディレクトリに置きます。
# '設定' -> 'rating.rb Configuration' で、評価軸や
# 表示内容を設定。
# くわしくは
# http://www.maripo.jp/diary/?date=20071019
#
# Copyright (c) 2007 Mariko/Maripo GODA
# http://www.maripo.jp/
# You can redistribute it and/or modify it under GPL.
require 'pstore'
require 'cgi'
@dbase = "#{@cache_path}/rating.db"
#########################################
# Config (Form)
#########################################
add_conf_proc('rating', 'rating.rb Configuration') do
rating_config = RatingConfig.new(@dbase)
form_string = ""
if @mode == 'saveconf'
# save conf
index = 0
# edit axes
rating_config.each { |axis_config|
#check values
if (@cgi.params["label" + index.to_s][0] != "" && (@cgi.params["range" + index.to_s][0]).to_i > 0)
axis_config.edit(@cgi.params["label" + index.to_s][0], @cgi.params["label_max" + index.to_s][0],@cgi.params["label_min" + index.to_s][0],@cgi.params["range" + index.to_s][0].to_i,@cgi.params["order" + index.to_s][0].to_i,@cgi.params["display" + index.to_s][0]!=nil)
index += 1
end
}
if (@cgi.params["label_new"][0] != "" && @cgi.params["range_new"][0].to_i > 0)
# add new axis
rating_config.add_axis(@cgi.params["label_new"][0], @cgi.params["label_max_new"][0], @cgi.params["label_min_new"][0], @cgi.params["range_new"][0].to_i)
end
rating_config.save_to_db
end
# print conf form
form_string += <
フィードバックフォームの設定をします。軸はいくつでも作成することができます。
作者 の blog に追加情報が書いてあるかもしれません。
設定方法
順 … 表示される順番です。小さいほうから順に並びます。番号が飛んでもOK。
表示 … いらない軸はチェックを外してしまってください。
軸の名前 … (例) "この記事は参考になりましたか"
最低ラベル … 例 "まったく参考にならない"
最高ラベル … 例 "とても参考になった"
選択肢数 … 例 : 1~5の5段階なら "5"
設定内容
'
form_string #evaluate
end
#########################################
# Entry of the day
#########################################
add_body_leave_proc do |date|
graph_string = ""
form_string = ""
contentString = ""
#initialize DateEval object
todays_eval = DateEval.new(date.strftime('%Y%m%d'), @dbase)
#initialize RatingConfig object
@rating_config = RatingConfig.new(@dbase)
graph_string += <
[分布をみる]
HTML
form_string += '' + "\n"
form_string += ('
'+"\n"
(form_string + graph_string)
end
#########################################
# class RatingConfig
#########################################
class RatingConfig
@axes
@max_axis_id= 0
@dbase
def initialize (dbase)
@dbase = dbase
db = PStore.new(@dbase)
db.transaction do
#begin transaction
if db.root?("config")
@axes = Hash.new
obj = db["config"]
@max_axis_id = obj[0]
obj.each{|ary|
id = ary[4]
@axes[id] = AxisConfig.new(ary[0],ary[1],ary[2],ary[3],ary[4],ary[5],ary[6])
}
else
@axes = Hash.new
@max_axis_id = 0
end
end
#end transaction
end #end initialize
def save_to_db
save_array = Array.new
db = PStore.new(@dbase)
save_array.push(@max_axis_id)
each {|axis_config|
save_array.push(axis_config.to_array)
}
db.transaction do
#begin transaction
db["config"] = save_array
end
#end transaction
end #end save_to_db
def add_axis (label, label_max, label_min, range)
@max_axis_id += 1
new_axis = AxisConfig.new(label, label_max, label_min, range, @max_axis_id, 0, true)
@axes[@max_axis_id] = new_axis
end #end add_axis
def edit_axis (axis_id, label, label_max, label_min, range, order,display)
target_axis = @axes[axis_id]
target_axis.edit(label, label_max, label_min, range, order,display)
end
def length
return @axes.size
end #end length
def each
@axes.to_a.sort {|a, b| a[1].order <=> b[1].order}.each {|key ,axis_conf|
yield axis_conf
}
end #end each
end
#########################################
# class AxisConfig
#########################################
class AxisConfig
@label
@label_max
@label_min
@range
@id
@order
@display = true
#accessors
attr_reader :label, :label_max, :label_min, :range, :id, :order, :display
def initialize (label, label_max, label_min, range, id,order,display)
@label = label
@label_max = label_max
@label_min = label_min
@range = range
@id = id
@order = order
@display = display
end #end initialize
def edit (label, label_max, label_min, range, order, display)
@label = label
@label_max = label_max
@label_min = label_min
@range = range
@order = order
@display = display
end #end initialize
def to_array
return [@label, @label_max, @label_min, @range, @id, @order,@display]
end
def disable
@hidden = true
end #end disable
def enable
@hidden = false
end #end disable
def check_label
return @display? "checked":""
end #end check_label
end
#########################################
# class DateEval
#########################################
class DateEval
@axes #axes[id][rank]
@date_string = ""
@dbase
@average #average[id]
@total #total[id]
GRAPH_PIXEL_LENGTH = 300
attr_reader :axes, :average, :total
# constructor
def initialize (date_string, dbase)
@dbase = dbase
@date_string = date_string
db = PStore.new(@dbase)
db.transaction do
#begin transaction
if db.root?(date_string)
#read
@axes = db[date_string]
else
#initialize
@axes = Hash.new
end
end
#end transaction
end #end constructor
def get_value(id, rank)
if @axes.key?(id) && @axes[id][rank] != nil
return @axes[id][rank]
else
return 0
end
end
def get_average(id)
sum = 0
vote = 0
unless @axes.key?(id)
return 0
end
for index in 0..@axes[id].length - 1
if @axes.key?(id) && @axes[id][index] != nil
vote += @axes[id][index]
sum += @axes[id][index] * index
end
end
if @axes[id].length == 0
return 0
else
return sum.to_f/vote + 1
end
end
def vote(id, rank)
unless @axes.key?(id)
@axes[id] = Array.new
end
if @axes[id][rank] != nil
@axes[id][rank] += 1
else
@axes[id][rank] = 1
end
end
def save_to_db
db = PStore.new(@dbase)
db.transaction do
#begin transaction
#save
db[@date_string] = @axes
end
#end transaction
end #end save_to_db
def get_graph_length (id, rank)
unless @axes.key?(id)
return 0
end
if @axes[id][rank] != nil
total = 0
@axes[id].each {|val|
unless val == nil
total += val
end
}
return (@axes[id][rank] * GRAPH_PIXEL_LENGTH / total).to_i
else
return 0
end
end #end
end # class dateEval end
#########################################
# Comment (vote)
#########################################
if (@mode == 'comment')
if @cgi.params["body"][0] != 'rating'
return
end
@dbase = "#{@cache_path}/rating.db"
#initialize RatingConfig object
rating_config = RatingConfig.new(@dbase)
#initialize DateEval object
todays_eval = DateEval.new(@cgi.params['date'][0], @dbase)
rating_config.each { |axis_config|
if @cgi.params["axis" + axis_config.id.to_s][0]!= nil
todays_eval.vote(axis_config.id, @cgi.params["axis" + axis_config.id.to_s][0].to_i)
end
}
todays_eval.save_to_db
end
tdiary-contrib-5.1.0/plugin/recent_estraier.rb 0000664 0000000 0000000 00000002575 13570131474 0021466 0 ustar 00root root 0000000 0000000 # recent_estraier.rb $Revision 1.1 $
#
# recent_estraier: Estraier検索語新しい順
# estsearch.cgiが作成する検索キーワードログから
# 最新xx件分の検索語を表示します。
# パラメタ:
# file: 検索キーワードログファイル名(絶対パス表記)
# estraier: estseach.cgiのパス
# limit: 表示件数(未指定時:5)
# make_link:
を生成するか?(未指定時:生成する)
#
#
# Copyright (c) 2005 SHIBATA Hiroshi
# Distributed under the GPL2.
#
require 'nkf'
def recent_estraier(file, estraier, limit = 5, make_link = true)
begin
lines = []
log = open(file)
if log.stat.size > 300 * limit then
log.seek(-300 * limit,IO::SEEK_END)
end
log.each_line do |line|
lines << line
end
result = ""
lines.reverse.each_with_index do |line,idx|
break if idx >= limit
word = NKF::nkf('-We -m0', line.split(/\t/)[2])
if word.empty? then
limit += 1
else
if make_link
result << %Q|#{h word} |
else
result << %Q|#{h word}|
end
end
end
result << %Q[ ]
rescue
%Q[#$! (#{$!.class}) cannot read #{file}.
]
end
end
tdiary-contrib-5.1.0/plugin/recent_tweet.rb 0000664 0000000 0000000 00000004126 13570131474 0020772 0 ustar 00root root 0000000 0000000 #
# recemt_tweet.rb: Twitter status plugin for tDiary
#
# Copyright (C) 2007 by Nishimoto Masaki
# Distributed under GPL.
#
require 'open-uri'
require 'timeout'
require 'rexml/document'
def recent_tweet( id, count )
begin
cache = "#{@cache_path}/recent_tweet.xml"
xml = open( cache ) {|f| f.read }
if Time::now > File::mtime( cache ) + 10*60 then
File::delete( cache ) # clear cache 10 minutes later
end
rescue Errno::ENOENT
begin
xml = recent_tweet_call_api( id )
open( cache, 'wb' ) {|f| f.write( xml ) }
rescue Timeout::Error, StandardError
return %Q||
end
end
begin
doc = REXML::Document::new( xml )
if doc then
html = ''
@conf.to_native( html )
else
return ''
end
rescue REXML::ParseException
return ''
end
end
def recent_tweet_call_api( id )
request = "http://twitter.com/statuses/user_timeline/#{id}.xml"
proxy = @conf['proxy']
proxy = 'http://' + proxy if proxy
Timeout.timeout( 10 ) do
open( request, :proxy => proxy ) {|f| f.read }
end
end
tdiary-contrib-5.1.0/plugin/retweet.rb 0000664 0000000 0000000 00000005236 13570131474 0017764 0 ustar 00root root 0000000 0000000 #
# retweet.rb - show retweet count in each section
# This plugin uses a Topsy Retweet Button for Web Sites powered by Topsy.com
#
# Copyright (C) 2010, MATSUOKA Kohei
# You can redistribute it and/or modify it under GPL2.
#
#
# settings for Topsy Retweet Button.
# see: http://labs.topsy.com/button/retweet-button/#global_settings
#
# your Twitter username
@topsy_nick = "your_twitter_account"
# retweet button color
#@topsy_theme = "blue"
# retweet button text
#@topsy_retweet_text = "retweet"
unless defined?(permalink)
def permalink( date, index, escape = true )
ymd = date.strftime( "%Y%m%d" )
uri = @conf.index.dup
uri.sub!( %r|\A(?!https?://)|i, @conf.base_url )
uri.gsub!( %r|/\.(?=/)|, "" ) # /././ -> /
link = uri + anchor( "#{ymd}p%02d" % index )
link.sub!( "#", "%23" ) if escape
link
end
end
unless defined?(subtitle)
def subtitle( date, index, escape = true )
diary = @diaries[date.strftime( "%Y%m%d" )]
return "" unless diary
sn = 1
diary.each_section do |section|
if sn == index
old_apply_plugin = @options["apply_plugin"]
@options["apply_plugin"] = true
title = apply_plugin( section.subtitle_to_html, true )
@options["apply_plugin"] = old_apply_plugin
title.gsub!( /(?=")/, "\\" ) if escape
return title
end
sn += 1
end
end
end
# load Tospy's script and initialize
add_header_proc do
r = ""
r << %Q|\n|
return r unless @topsy_theme or @topsy_nick or @topsy_retweet_text
r << %Q|\n|
end
# show retweet button in top of section
add_section_enter_proc do |date, index|
<<-"EOS"
EOS
end
# show retweet button in end of section
add_section_leave_proc do |date, index|
<<-"EOS"
EOS
end
tdiary-contrib-5.1.0/plugin/rubykaigi.rb 0000664 0000000 0000000 00000011361 13570131474 0020267 0 ustar 00root root 0000000 0000000 #
# rubykaigi.rb: make badges of RubyKaigi.
#
# usage: <%= rubykaigi 'role', 'size' %>
# role: attendee (default), speaker, sponsor, staff, committer, individual sponsor, away
# size: large(160x160), small(160x90)
#
# Copyright (C) TADA Tadashi
# Distributed under GPL.
#
def rubykaigi2015( role = 'attendee', size = nil )
r = role.split(/[ _]+/).join('-')
s = "-@#{h size}" unless size.nil? || size == "1x"
%Q| |
end
def rubykaigi2014( role = 'attendee', size = nil )
r = role.split(/[ _]+/).join('-')
s = "@#{h size}" unless size.nil?
%Q| |
end
def rubykaigi2013( role = 'attendee', size = nil )
r = role.split(/[ _]+/).map{|s| s.capitalize}.join
s = "@#{h size}" unless size.nil?
%Q| |
end
def sappororubykaigi2012( role = 'attendee' )
r = role.split(/[ _]+/).map{|s| s.capitalize}.join
%Q| |
end
def kansairubykaigi04( role = 'attendee' )
badges = {
'attendee' => "attendee_taiyou",
'speaker' => "speaker_shika",
'staff' => "staff_daibutsu"
}
%Q| |
end
def rubykaigi2011( role = 'attendee', size = 'large' )
badges = Hash::new( 'attendee' ).update({
'committer' => 'committer',
'individual sponsor' => 'individualSponsor',
'sponsor' => 'sponsor',
'staff' => 'staff',
'speaker' => 'speaker',
'attendee' => 'attendee',
'away' => 'attendeeAway'
})
width, height = size == 'large' ? ['160','160'] : ['160', '90']
%Q| |
end
alias :rubykaigi :rubykaigi2015
#----- OLD EDITIONS -----#
def sappororubykaigi03( role = 'attendee' )
%Q| |
end
def rubykaigi2010( role = 'attendee' )
badges = Hash::new( 'attendee' ).update({
'committer' => 'committer',
'individual sponsor' => 'individual_sponsor',
'sponsor' => 'sponsor',
'staff' => 'staff',
'speaker' => 'speaker',
'attendee' => 'attendee',
'away' => 'away'
})
%Q| |
end
def rubykaigi2009( role = 'attendee' )
%Q| |
end
def rubykaigi2008( role = 'attendee' )
img = case role
when 'speaker'
1
when 'sponsor'
2
when 'staff'
3
else
role = 'attendee'
0
end
%Q| |
end
def sappororubykaigi02( role = 'attendee' )
%Q| |
end
# Local Variables:
# mode: ruby
# indent-tabs-mode: t
# tab-width: 3
# ruby-indent-level: 3
# End:
# vim: ts=3
tdiary-contrib-5.1.0/plugin/search-bing.rb 0000664 0000000 0000000 00000005050 13570131474 0020461 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
#
# search-bing.rb - site search plugin sample using Bing API.
#
# Copyright (C) 2011, TADA Tadashi
# You can redistribute it and/or modify it under GPL.
#
# Needed these options below:
#
# @options['search-bing.appid'] : Your Bing AppId
# @options['search.result_filter'] : your dialy's URL format of DAY mode into Regexp.
# @options['search-bing.base'] : Base URI of your diary (for debugging)
#
require 'timeout'
require 'json'
require 'open-uri'
def search_title
'全文検索 by Bing'
end
def search_input_form( q )
r = <<-HTML
HTML
end
def search_bing_api( q, start = 0 )
appid = @conf['search-bing.appid']
u = 'https://api.datamarket.azure.com/Bing/SearchWeb/v1/Web'
u << "?Query=%27#{q}%27&Options=%27EnableHighlighting%27&$top=50&$skip=#{start}&$format=Json"
uri = URI( u )
begin
open( uri, {:http_basic_authentication => [appid, appid]} ).read
rescue SecurityError
### FIX ME: mysterious error at 1st access to the API
open( uri, {:http_basic_authentication => [appid, appid]} ).read
end
### FIX ME: this code failed on Timeout error, temporary using open-uri above.
# px_host, px_port = (@conf['proxy'] || '').split( /:/ )
# px_port = 8080 if px_host and !px_port
# res = Net::HTTP::Proxy( px_host, px_port ).start( uri.host, uri.port ) do |http|
# req = Net::HTTP::Get.new( uri.request_uri )
# req.basic_auth( appid, appid )
# res = http.request( req )
# end
# res.body
end
def search_to_html( str )
(str || '').gsub( /\uE000/, '' ).gsub( /\uE001/, ' ' )
end
def search_result
query = CGI::unescape( @cgi.params['q'][0] )
start = CGI::unescape( @cgi.params['start'][0] || '0' ).to_i
begin
uri = URI::parse( @conf['search-bing.base'] || @conf.base_url )
q = "#{query} site:#{uri.host}"
q << %Q| inurl:"#{uri.path}"| unless uri.path == '/'
json = JSON::parse(search_bing_api(u(q.untaint), start))
rescue Net::HTTPError
return %Q|#$!
|
end
r = search_input_form( query )
r << ''
r << ''
# no search navi on Bing search because no total result not supported
r << '
'
r
end
tdiary-contrib-5.1.0/plugin/search-google-custom.rb 0000664 0000000 0000000 00000004274 13570131474 0022335 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
#
# search-google-custom.rb - site search plugin using Goole Custom Search.
#
# Copyright (C) 2011, hb
# You can redistribute it and/or modify it under GPL.
#
# Needed these options below:
#
# @options["search-google-custom.id"] : Your Google Custome Search ID
# @options["search-google-custom.cof"] : 広告の表示場所(9:右,10:一番上と右,11:一番上と下)
# @options["search-google-custom.width"] : 検索結果のフレームの幅
# @options["search-google-custom.height"] : 検索結果のフレームの高さ
# @options["search-google-custom.search_label"] : 検索テキストボックス左のラベル
# @options["search-google-custom.button_text"] : 検索ボタンに書かれる文字列
#
def search_title
'全文検索 by Google カスタム検索'
end
add_footer_proc do
%Q||
end
def search_input_form(q='')
cof = @conf["search-google-custom.cof"] || 9
search_label = @conf["search-google-custom.search_label"] || '検索キーワード:'
button_text = @conf["search-google-custom.button_text"] || '検索'
r = <<-HTML
HTML
end
def search_result
w = @conf["search-google-custom.width"] || 600
h = @conf["search-google-custom.height"] || 1300
r = <<-HTML
HTML
end
tdiary-contrib-5.1.0/plugin/search-yahoo-websearch.rb 0000664 0000000 0000000 00000007227 13570131474 0022632 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
#
# search-yahoo-websearch.rb - Yahoo!デベロッパーネットワークのWeb検索APIを利用した検索プラグイン.
#
# Copyright (C) 2011, hb
# You can redistribute it and/or modify it under GPL.
#
# オプション
#
# @options['search-yahoo-websearch.appid'] : アプリケーションID(必須)
# @options['search-yahoo-websearch.premium'] : アップグレード版利用時はtrueを指定する(任意)
#
def search_title
'全文検索 by Yahoo! ウェブ検索'
end
def search_input_form( q )
r = <<-HTML
HTML
end
def request_url
if @conf['search-yahoo-websearch.premium']
'http://search.yahooapis.jp/PremiumWebSearchService/V1/webSearch'
else
'http://search.yahooapis.jp/WebSearchService/V2/webSearch'
end
end
def search_to_html( str )
(str || '').gsub( /(?:]*)?>)+/, '' ).gsub( %r{<(/?)b[ \t\n\r]*>}, '<\\1strong>' )
end
def yahoo_websearch_api( q, start = 1 )
url = request_url
appid = @conf['search-yahoo-websearch.appid']
uri = URI::parse( @conf.base_url )
url << "?appid=#{appid}&query=#{q}&results=20&start=#{start}&format=html&site=#{uri.host}"
proxy = @conf['proxy']
proxy = 'http://' + proxy if proxy
proxy_host, proxy_port = nil
if proxy
proxy_host = proxy_uri.host
proxy_port = proxy_uri.port
end
proxy_class = Net::HTTP::Proxy(proxy_host, proxy_port)
query = URI.parse(url)
req = Net::HTTP::Get.new(query.request_uri)
http = proxy_class.new(query.host, query.port)
http.open_timeout = 20
http.read_timeout = 20
res = http.start do
http.request(req)
end
res.body
end
def yahoo_websearch_attribution
<<-EOF
EOF
end
def search_result
query = CGI::unescape( @cgi.params['q'][0] )
start = CGI::unescape( @cgi.params['start'][0] || '1' ).to_i
begin
uri = URI::parse( @conf.base_url )
xml = yahoo_websearch_api( u( query.untaint ), start )
doc = REXML::Document::new( REXML::Source.new( xml ) ).root
err = doc.elements.to_a( '/Error/Message' )[0]
if err
return %Q|ERROR - #{err.text}
|
end
rescue OpenURI::HTTPError
return %Q|#$!
|
end
r = ''
r << ''
pos = doc.elements["/ResultSet"].attributes["firstResultPosition"]
unless pos == '1'
r << %Q|
<前の20件 |
end
total = doc.elements["/ResultSet"].attributes["totalResultsAvailable"]
ret = doc.elements["/ResultSet"].attributes["totalResultsReturned"]
if ret.to_i == 20 and pos.to_i + 19 < 1000
r << %Q|
次の20件> |
end
r << '
'
r << yahoo_websearch_attribution
r
end
tdiary-contrib-5.1.0/plugin/search-yahoo.rb 0000664 0000000 0000000 00000005754 13570131474 0020674 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
#
# search-yahoo.rb - site search plugin sample using Yahoo! Search BOSS API.
#
# Copyright (C) 2009, TADA Tadashi
# You can redistribute it and/or modify it under GPL.
#
# Needed these options below:
#
# @options['search-yahoo.appid'] : Your BOSS APPID
# @options['search-yahoo.result_filter'] : your dialy's URL format of DAY mode into Regexp.
#
require 'timeout'
require 'rexml/document'
require 'net/http'
Net::HTTP.version_1_2
def search_title
'全文検索 by Yahoo! Search BOSS'
end
def search_input_form( q )
r = <<-HTML
HTML
end
def search_boss_api( q, start = 0 )
url = 'http://boss.yahooapis.com/ysearch/web/v1/'
appid = @conf['search-yahoo.appid']
url << "#{q}?appid=#{appid}&format=xml&count=20&start=#{start}"
proxy = @conf['proxy']
proxy = 'http://' + proxy if proxy
proxy_host, proxy_port = nil
if proxy
proxy_host = proxy_uri.host
proxy_port = proxy_uri.port
end
proxy_class = Net::HTTP::Proxy(proxy_host, proxy_port)
query = URI.parse(url)
req = Net::HTTP::Get.new(query.request_uri)
http = proxy_class.new(query.host, query.port)
http.open_timeout = 20
http.read_timeout = 20
res = http.start do
http.request(req)
end
res.body
end
def search_to_html( str )
(str || '').gsub( /(?:]*)?>)+/, '' ).gsub( %r{<(/?)b[ \t\n\r]*>}, '<\\1strong>' )
end
def search_result
query = CGI::unescape( @cgi.params['q'][0] )
start = CGI::unescape( @cgi.params['start'][0] || '0' ).to_i
begin
uri = URI::parse( @conf.base_url )
q = "#{query} site:#{uri.host}"
q << %Q| inurl:"#{uri.path}"| unless uri.path == '/'
xml = search_boss_api( u( q.untaint ), start )
doc = REXML::Document::new( REXML::Source.new( xml ) ).root
res = doc.elements.to_a( '/ysearchresponse' )[0]
unless res.attribute( 'responsecode' ).value == '200' then
return 'ERROR
'
end
rescue OpenURI::HTTPError
return %Q|#$!
|
end
r = search_input_form( query )
r << ''
r << ''
doc.elements.to_a( '/ysearchresponse/prevpage' ).each do |p|
if /start=\d+/ =~ p.text then
r << %Q|
<前の20件 |
end
end
doc.elements.to_a( '/ysearchresponse/nextpage' ).each do |n|
if /start=\d+/ =~ n.text then
r << %Q|
次の20件> |
end
end
r << '
'
r
end
tdiary-contrib-5.1.0/plugin/section_footer.rb 0000664 0000000 0000000 00000014635 13570131474 0021332 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
# section_footer.rb
#
# Copyright (c) 2005 SHIBATA Hiroshi
# You can redistribute it and/or modify it under GPL2.
#
require 'digest/md5'
require 'open-uri'
require 'timeout'
def permalink( date, index, escape = true )
ymd = date.strftime( "%Y%m%d" )
uri = @conf.index.dup
uri.sub!( %r|\A(?!https?://)|i, @conf.base_url )
uri.gsub!( %r|/\.(?=/)|, "" ) # /././ -> /
link = uri + anchor( "#{ymd}p%02d" % index )
link.sub!( "#", "%23" ) if escape
link
end
add_header_proc do
<<-SCRIPT
SCRIPT
end
add_section_enter_proc do |date, index|
@category_to_tag_list = {}
end
alias subtitle_link_original subtitle_link
def subtitle_link( date, index, subtitle )
s = ''
if subtitle then
s = subtitle.sub( /^(\[([^\[]+?)\])+/ ) do
$&.scan( /\[(.*?)\]/ ) do |tag|
@category_to_tag_list[tag] = false # false when diary
end
''
end
end
subtitle_link_original( date, index, s.strip )
end
add_section_leave_proc do |date, index|
r = '\n"
end
def add_permalink(date, index)
r = " | "
r << %Q|Permalink |
return r
end
def add_hatenabm(date, index)
r = " | "
r << %Q| |
return r
end
def add_ldclip(date, index)
r = " | "
r << %Q| |
return r
end
def add_buzzurl(date, index)
r = " | "
r << %Q| |
return r
end
def add_delicious(date, index)
url_md5 = Digest::MD5.hexdigest(permalink(date, index, false))
r = " | "
r << %Q| |
return r
end
def add_delicious_json(date, index)
require 'fileutils'
begin
require 'json'
rescue
retry if require 'rubygems'
end
url_md5 = Digest::MD5.hexdigest(permalink(date, index, false))
cache_dir = "#{@cache_path}/delicious/#{date.strftime( "%Y%m" )}/"
file_name = "#{cache_dir}/#{url_md5}.json"
cache_time = 8 * 60 * 60 # 8 hour
update = false
count = 0
r = " | "
r << %Q| |
begin
FileUtils.mkdir_p( cache_dir ) unless File::directory?( cache_dir )
cached_time = nil
cached_time = File::mtime( file_name ) if File::exist?( file_name )
unless cached_time.nil?
if Time.now > cached_time + cache_time
update = true
end
end
if cached_time.nil? or update
begin
Timeout.timeout(10) do
open( "http://feeds.delicious.com/v2/json/urlinfo/#{url_md5}") do |file|
File::open( file_name, 'wb' ) do |f|
f.write( file.read )
end
end
end
rescue => e
@logger.debug( e )
end
end
rescue
end
begin
File::open( file_name ) do |f|
data = JSON.parse(@conf.to_native( f.read, 'utf-8' ))
unless data[0].nil?
count = data[0]["total_posts"].to_i
end
end
rescue
end
if count > 0
r << %Q| #{count} users |
else
r << %Q| |
end
return r
end
def add_yahoobm(date, index)
r = " | "
r << %Q|
|
return r
end
tdiary-contrib-5.1.0/plugin/section_footer2.rb 0000664 0000000 0000000 00000016763 13570131474 0021420 0 ustar 00root root 0000000 0000000 # section_footer2.rb
#
# Copyright (c) 2008 SHIBATA Hiroshi
# You can redistribute it and/or modify it under GPL2.
#
require 'digest/md5'
require 'timeout'
require 'open-uri'
require 'yaml'
require 'pathname'
begin
require 'json'
rescue LoadError
retry if require 'rubygems'
end
def permalink( date, index, escape = true )
ymd = date.strftime( "%Y%m%d" )
uri = @conf.index.dup
uri.sub!( %r|\A(?!https?://)|i, @conf.base_url )
uri.gsub!( %r|/\.(?=/)|, "" ) # /././ -> /
link = uri + anchor( "#{ymd}p%02d" % index )
link.sub!( "#", "%23" ) if escape
link
end
unless defined?(subtitle)
def subtitle( date, index, escape = true )
diary = @diaries[date.strftime( "%Y%m%d" )]
return "" unless diary
sn = 1
diary.each_section do |section|
if sn == index
old_apply_plugin = @options["apply_plugin"]
@options["apply_plugin"] = true
title = apply_plugin( section.subtitle_to_html, true )
@options["apply_plugin"] = old_apply_plugin
title.gsub!( /(?=")/, "\\" ) if escape
return title
end
sn += 1
end
''
end
end
def init_buttons_status
@installed_buttons = ['yaml', 'delicious', 'hatena', 'facebook', 'twitter', 'plusone']
if @conf['section_footer2.isDisplay'].nil?
@conf['section_footer2.isDisplay'] = ''
end
end
add_header_proc do
<<-"EOS"
EOS
end
add_section_enter_proc do |date, index|
@category_to_tag_list = {}
init_buttons_status
''
end
alias section_footer2_subtitle_link_original subtitle_link unless defined?( section_footer2_subtitle_link_original )
def subtitle_link( date, index, subtitle )
s = ''
@subtitle = subtitle
if subtitle then
s = subtitle.sub( /^(?:\[[^\[]+?\])+/ ) do
$&.scan( /\[(.*?)\]/ ) do |tag|
@category_to_tag_list[tag.shift] = false # false when diary
end
''
end
end
section_footer2_subtitle_link_original( date, index, s.strip )
end
add_section_leave_proc do |date, index|
unless feed? or bot?
r = '\n"
end
end
def call_delicious_json( url_md5 )
json = nil
begin
Timeout.timeout(10) do
open( "http://feeds.delicious.com/v2/json/urlinfo/#{url_md5}" ) do |f|
json = JSON.parse( f.read )
end
end
rescue => e
@logger.debug( e )
end
return json
end
def add_delicious( date, index )
url_md5 = Digest::MD5.hexdigest(permalink(date, index, false))
db_file = "#{@cache_path}/delicious.cache"
r = ''
r << %Q| |
begin
cache_time = 8 * 60 * 60 # 12 hour
PStore.new(db_file).transaction do |db|
entry = db[url_md5]
entry = { :count => 0, :update=> Time.at(0) } if entry.nil?
if Time.now > entry[:update] + cache_time
json = call_delicious_json( url_md5 )
entry[:count] = json[0]["total_posts"].to_i unless json[0].nil?
entry[:update] = Time.now
db[url_md5] = entry
end
if entry[:count] > 0
r << %Q| #{entry[:count]} user|
r << 's' if entry[:count] > 1
end
end
rescue => e
@logger.debug( e )
end
r << ' '
r << ' | '
return r
end
def add_hatena( date, index )
%Q! | !
end
def add_facebook(date, index)
# add Facebook Like!
r = ''
r << %Q! | !
end
def add_twitter(date, index)
r = <<-"EOS"
|
EOS
end
def add_plusone(date, index)
%Q! | !
end
def add_yaml(date, index)
r = ''
yaml_dir = "#{@cache_path}/yaml/"
Dir.glob( yaml_dir + "*.yaml" ) do |file|
r << parse_sbm_yaml(file, date, index)
end
return r
end
def add_button_by_service(date, index)
r = ''
@installed_buttons.each do |button|
if @conf['section_footer2.isDisplay'].include?(button) then
method = "add_" + button + "(date, index)"
unless method.nil? then
r << instance_eval(method)
end
end
end
return r
end
def parse_sbm_yaml(file, date, index)
config = YAML.load( Pathname.new( file ).expand_path.read )
r = ""
unless config.nil?
url = config["url"]
unless config['usesubtitle'].nil?
sub = (@subtitle || '').sub( /\A(?:\[[^\]]*\])+ */, '' )
sub = apply_plugin( sub, true ).strip
regexp = config["usesubtitle"]
url.gsub!(regexp, sub)
char_space = ' '
end
title = config["title"][@conf.lang]
r << %Q||
r << %Q| |
r << %Q| | unless config["counter"].nil?
r << ' '
r << ' | '
end
return r
end
add_conf_proc('section_footer2', 'Section Footer Button') do
if @mode == 'saveconf' then
@conf['section_footer2.isDisplay'] = ''
@cgi.params['section_footer2.isDisplay'].each do |item|
@conf['section_footer2.isDisplay'] << item + '\n'
end
end
r = '表示するボタンをチェックしてください(YAMLをチェックすると各自でインストールしたYAMLのボタンをすべて表示します) '
r << ''
init_buttons_status
@installed_buttons.each do |button|
if @conf['section_footer2.isDisplay'].include?(button) then
item_checked = "checked"
else
item_checked = ''
end
r << %Q| #{button}|
end
r << '
'
end
# Local Variables:
# mode: ruby
# indent-tabs-mode: t
# tab-width: 3
# ruby-indent-level: 3
# End:
# vim: ts=3
tdiary-contrib-5.1.0/plugin/section_permalink.rb 0000664 0000000 0000000 00000003034 13570131474 0022005 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
# Copyright (C) 2011, KADO Masanori
# You can redistribute it and/or modify it under GPL.
#
# section_permalink.rb
# - enables section permalink and shows section title
def section_mode?
@mode == 'day' and @cgi.params['p'][0].to_s != ""
end
# Change permalink
def anchor( s )
if /^([\-\d]+)#?([pct]\d*)?$/ =~ s then
if $2 then
s1 = $1
s2 = $2
if $2 =~ /^p/
"?date=#{s1}&p=#{s2.gsub(/p/, '')}"
else
"?date=#{s1}.html##{s2}"
end
else
"?date=#$1"
end
else
""
end
end
# Change HTML title to section name
alias :_orig_title_tag :title_tag
def title_tag
if section_mode? and diary = @diaries[@date.strftime('%Y%m%d')]
sections = diary.instance_variable_get(:@sections)
title = ""
section = sections[@cgi.params['p'][0].to_i - 1].stripped_subtitle_to_html
title << apply_plugin(section, true).chomp
title << " - #{h @html_title}"
title << "(#{@date.strftime( '%Y-%m-%d' )})" if @date
title << " "
return title
else
_orig_title_tag
end
rescue
_orig_title_tag
end
add_header_proc do
if section_mode? and diary = @diaries[@date.strftime('%Y%m%d')]
index = @cgi.params['p'][0]
<<-EOS
EOS
end
end
# Local Variables:
# mode: ruby
# indent-tabs-mode: t
# tab-width: 3
# ruby-indent-level: 3
# End:
# vim: ts=3
tdiary-contrib-5.1.0/plugin/section_permalink_anchor.rb 0000664 0000000 0000000 00000001326 13570131474 0023341 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
# Copyright (C) 2011, KADO Masanori
# You can redistribute it and/or modify it under GPL.
#
# section_permalink_anchor.rb
# - enables section permalink with mod_rewrite
# - depends on section_permalink.rb
#
# sample .htaccess:
#
# RewriteEngine on
# RewriteRule ^([0-9\-]+)p?([0-9]*)\.html$ ?date=$1&p=$2 [L]
#
def anchor( s )
if /^([\-\d]+)#?([pct]\d*)?$/ =~ s then
if $2 then
s1 = $1
s2 = $2
if $2 =~ /^p/
"#{s1}#{s2}.html"
else
"#{s1}.html##{s2}"
end
else
"#$1.html"
end
else
""
end
end
# Local Variables:
# mode: ruby
# indent-tabs-mode: t
# tab-width: 3
# ruby-indent-level: 3
# End:
# vim: ts=3
tdiary-contrib-5.1.0/plugin/select-style.rb 0000664 0000000 0000000 00000002521 13570131474 0020714 0 ustar 00root root 0000000 0000000 #
# select-style.rb: select a style from installed styles
#
# add a line below, after load_cgi_conf in tdiary.conf:
# @style = @options2['style'] if @options2 && @options2['style']
#
def saveconf_style
if @mode == 'saveconf' then
@conf['style'] = @cgi.params['style'][0]
end
end
def enum_styles
TDiary::Style.constants(false).grep(/Diary$/).delete_if{|s|
s =~ /Base|Categorizable|Uncategorizable/
}.map{|s|
s.to_s.sub(/Diary$/, '').downcase
}.each{|s|
yield s
}
end
add_conf_proc( 'style', 'スタイル', 'update' ) do
saveconf_style
labels = {
'tdiary' => 'tDiary',
'wiki' => 'Wiki',
'gfm' => 'GFM',
'etdiary' => 'etDiary',
'emptdiary' => 'emptDiary',
'rd' => 'RD',
}
r = <<-HTML
スタイルの指定
スタイル (日記の文法) を指定します。
HTML
enum_styles do |style|
label = labels[style] || style
select = if (label == @conf['style']) or (!@conf['style'] && style == 'tdiary')
' selected'
else
''
end
r << %Q|#{labels[style] || style} |
end
r << <<-HTML
スタイルについての詳細はスタイル - tDiary の記法 をごらんください。
HTML
end
tdiary-contrib-5.1.0/plugin/select_style.rb 0000664 0000000 0000000 00000002313 13570131474 0020775 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
#
# select_style.rb: a plugin for selecting styles
# Distributed under the GPL
#
# [CAUTION] You need to insert a line to tdiary.conf after "load_cgi_conf"
# @style = @options2['style'] if @options2['style']
#
# styles
def saveconf_style
if @mode == 'saveconf' then
@conf['style'] = @cgi.params['style'][0]
end
end
if @mode =~ /^(conf|saveconf)$/ then
@conf_style_list = []
Dir::glob( "#{::TDiary::PATH}/tdiary/{style/,}*_style.rb" ) do |style_file|
style = File::basename( style_file ).sub( /_style\.rb$/, '' )
@conf_style_list << style
end
end
add_conf_proc( 'style', 'スタイル' ) do
saveconf_style
r = <<-HTML
スタイルの指定
スタイル (日記の文法) を指定します。
HTML
@conf_style_list.each do |style|
r << %Q|#{style} |
end
r << <<-HTML
スタイルについての詳細はスタイル - tDiary の記法 をごらんください。
HTML
end
tdiary-contrib-5.1.0/plugin/select_theme.rb 0000664 0000000 0000000 00000004332 13570131474 0020742 0 ustar 00root root 0000000 0000000 # Copyright (C) 2005 akira yamada
# You can redistribute it and/or modify it under GPL2.
THEME_BASE = File.join(::TDiary::PATH, 'theme')
CACHE_FILE = File.join(@cache_path, 'theme_list')
def get_theme_list
if FileTest.exist?(CACHE_FILE) &&
File.mtime(CACHE_FILE) >= File.mtime(THEME_BASE)
File.open(CACHE_FILE, 'r') do |i|
i.flock(File::LOCK_EX)
return Marshal.load(i.read)
end
end
list = []
Dir.glob(File.join(THEME_BASE, '*')).sort.each do |dir|
theme = dir.sub(%r[.*/theme/], '')
next unless FileTest::file?("#{dir}/#{theme}.css".untaint)
name = theme.split(/_/).collect{|s| s.capitalize}.join(' ')
list << [theme, name]
end
File.open(CACHE_FILE, 'w') do |o|
o.flock(File::LOCK_EX)
o.puts Marshal.dump(list)
end
return list
end
def select_theme_form
options = ''
get_theme_list.each do |theme, name|
options << %Q!\t#{h name} \n!
if theme == DEFAULT_THEME
options = %Q!\t(default) \n! + options
end
end
<
#{options}
HTML
end
def label
'use'
end
def check_theme(name)
return false if name.nil? || name.empty?
FileTest.file?(File.join(THEME_BASE, name, name + '.css'))
end
with_cgiparam = false
theme = nil
if @cgi.params['select_theme'] && @cgi.params['select_theme'][0]
tmp = @cgi.params['select_theme'][0].gsub(/[^-.\w]/, '')
tmp.untaint
if check_theme(tmp)
theme = tmp
with_cgiparam = true
end
end
if theme.nil? && @cgi.cookies && @cgi.cookies.include?('tdiary_select_theme')
tmp = @cgi.cookies['tdiary_select_theme'][0].gsub(/[^-.\w]/, '')
tmp.untaint
theme = tmp if check_theme(tmp)
end
if theme.nil?
theme = @conf.theme
end
cookie_path = File::dirname( @cgi.script_name )
cookie_path += '/' if cookie_path !~ /\/$/
cookie = CGI::Cookie::new(
'name' => 'tdiary_select_theme',
'value' => theme,
'path' => cookie_path,
'expires' => Time::now.gmtime + 90*24*60*60) # 90days
add_cookie(cookie)
# XXX: OK?
DEFAULT_THEME = @conf.theme
@conf.theme = theme
tdiary-contrib-5.1.0/plugin/shogizumen.rb 0000664 0000000 0000000 00000000463 13570131474 0020472 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
#
# shogizumen.rb -- Just enable shogizumen.min
#
# Copyright (c) KITADAI, Yukinori
# MIT License
#
# shogizumen.min.js is under MIT license.
enable_js('shogizumen.min.js')
def shogizumen(zumen_string)
'' + zumen_string + ' '
end
tdiary-contrib-5.1.0/plugin/show_and_hide.rb 0000664 0000000 0000000 00000003267 13570131474 0021102 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
#
# show_and_hide.rb - Show or hide the elements with a sliding motion using jQuery.
#
# Copyright (C) 2011, tamoot
# You can redistribute it and/or modify it under GPL2.
#
require 'digest/md5'
if /\A(?:latest|day|month|nyear|preview)\z/ =~ @mode
enable_js('show_and_hide.js')
end
def show_and_hide(contents, title = 'Show contents',
type = :link,
rss_title = '(Hide contents on RSS. See my page...)')
data_id = show_and_hide_id(contents)
toggle_attr = {:class => 'show_and_hide_toggle',
:"data-showandhideid" => data_id}
dom_contents = ''
if feed? # RSS
dom_contents = h(rss_title)
elsif type.to_s == 'button'
toggle_attr.merge!(:value => title, :type => "button")
dom_contents = %Q| | +
show_and_hide_contents(contents, data_id)
else
toggle_attr.merge!(:href => 'javascript:void(0)')
dom_contents = %Q|#{h(title)} | +
show_and_hide_contents(contents, data_id)
end
dom_contents
end
def show_and_hide_id(contents)
@@show_and_hide_counter ||= 0
@@show_and_hide_counter += 1
"#{Time::now.strftime("%s")}_#{@@show_and_hide_counter}_#{ Digest::MD5.hexdigest(contents)}"
end
def show_and_hide_contents(contents, id)
%Q|#{h(contents)} |
end
def hash2attr(hash)
attrs = []
hash.keys.each do |k|
attrs << %Q|#{k}="#{hash[k]}"|
end
attrs.join(" ")
end
# Local Variables:
# mode: ruby
# indent-tabs-mode: t
# tab-width: 3
# ruby-indent-level: 3
# End:
# vim: ts=3
tdiary-contrib-5.1.0/plugin/slideshare.rb 0000664 0000000 0000000 00000000605 13570131474 0020423 0 ustar 00root root 0000000 0000000 #
# slideshare.rb - insert some services of slideshare.net
#
# Copyright (C) 2011, Kiwamu Okabe .
# You can redistribute it and/or modify it under GPL2.
#
def slideshare( embed_code )
%Q||
end
tdiary-contrib-5.1.0/plugin/slideshow.rb 0000664 0000000 0000000 00000000656 13570131474 0020307 0 ustar 00root root 0000000 0000000 #
# slideshow.rb : tDiary plugin for show slides
#
# Copyright (C) 2016 TADA Tadashi
# Distributed under the GPL2 or any later version.
#
# @options['slideshow.css'] = "URL of CSS"
#
enable_js('slideshow.js')
def slideshow
%Q|Start Slideshow >> |
end
if @conf['slideshow.css']
add_header_proc do
%Q[ ]
end
end
tdiary-contrib-5.1.0/plugin/socialbutton.rb 0000664 0000000 0000000 00000003776 13570131474 0021022 0 ustar 00root root 0000000 0000000 # socialbutton.rb
#
# Copyright (c) 2011 MATSUOKA Kohei
# You can redistribute it and/or modify it under GPL2.
#
# enable social button names
@conf['socialbutton.enables'] ||= 'twitter,hatena,facebook_like'
# screen name of the user to attribute the tweet to
@conf['socialbutton.twitter.via'] ||= ''
def socialbutton_js_settings
enable_js('jquery.socialbutton.js')
enable_js('socialbutton.js')
add_js_setting('$tDiary.plugin.socialbutton')
# convert array to json
add_js_setting('$tDiary.plugin.socialbutton.enables',
%Q|["#{@conf['socialbutton.enables'].split(',').join('", "')}"]|)
if @conf['socialbutton.twitter.via'] != ''
options = "{ twitter: { via: '#{@conf['socialbutton.twitter.via']}' } }"
else
options = "{}"
end
add_js_setting('$tDiary.plugin.socialbutton.options', options)
end
add_conf_proc('socialbutton', @socialbutton_label_conf) do
@conf['socialbutton.enables'] ||= []
if @mode == 'saveconf'
@conf['socialbutton.enables'] = @cgi.params['socialbutton.enables'].join(",")
@conf['socialbutton.twitter.via'] = @cgi.params['socialbutton.twitter.via'][0]
end
result = <<-HTML
#{@socialbutton_label_enables}
#{@socialbutton_label_twitter_via}
HTML
end
if @mode =~ /^(latest|day|month|nyear)$/
socialbutton_footer = Proc.new { %Q|
| }
if respond_to?(:blogkit?) && blogkit?
add_body_leave_proc(&socialbutton_footer)
else
add_section_leave_proc(&socialbutton_footer)
end
# load javascript
socialbutton_js_settings()
end
tdiary-contrib-5.1.0/plugin/squeeze.rb 0000775 0000000 0000000 00000015603 13570131474 0017770 0 ustar 00root root 0000000 0000000 #!/usr/bin/env ruby
# squeeze.rb
#
# Create daily HTML file from tDiary database.
#
# See URLs below for more details.
# http://ponx.s5.xrea.com/hiki/squeeze.rb.html (English)
# http://ponx.s5.xrea.com/hiki/ja/squeeze.rb.html (Japanese)
#
# Copyright (C) 2002 MUTOH Masao
# You can redistribute it and/or modify it under GPL2 or any later version.
#
# The original version of this file was distributed with squeeze
# TADA Tadashi with GPL2 or any later version.
#
unless $tdiary_squeeze_loaded
$tdiary_squeeze_loaded ||= true
mode = defined?(TDiary) ? "PLUGIN" : ENV["REQUEST_METHOD"]? "CGI" : "CMD"
if mode == "CMD" || mode == "CGI"
output_path = "./html/"
tdiary_path = "."
tdiary_conf = "."
suffix = ''
all_data = false
overwrite = false
compat = false
$stdout.sync = true
if mode == "CMD"
def usage
puts "squeeze $Revision: 1.25 $"
puts " making html files from tDiary's database."
puts " usage: ruby squeeze.rb [-p ] [-c ] [-a] [-s] [-x suffix] "
exit
end
require 'getoptlong'
parser = GetoptLong::new
parser.set_options(['--path', '-p', GetoptLong::REQUIRED_ARGUMENT],
['--conf', '-c', GetoptLong::REQUIRED_ARGUMENT],
['--suffix', '-x', GetoptLong::REQUIRED_ARGUMENT],
['--all', '-a', GetoptLong::NO_ARGUMENT],
['--overwrite', '-o', GetoptLong::NO_ARGUMENT],
['--squeeze', '-s', GetoptLong::NO_ARGUMENT])
begin
parser.each do |opt, arg|
case opt
when '--path'
tdiary_path = arg.dup.untaint
when '--conf'
tdiary_conf = arg
when '--suffix'
suffix = arg
when '--all'
all_data = true
when '--overwrite'
overwrite = true
when '--squeeze'
compat = true
end
end
rescue
usage
exit( 1 )
end
output_path = ARGV.shift
usage unless output_path
output_path = File::expand_path(output_path)
output_path += '/' if /\/$/ !~ output_path
tdiary_conf = tdiary_path unless tdiary_conf
Dir::chdir( tdiary_conf )
ARGV << '' # dummy argument against cgi.rb offline mode.
$:.unshift tdiary_path
else
@options = Hash.new
File::readlines("tdiary.conf").each {|item|
if item =~ /@options/
begin
eval(item)
rescue SyntaxError
end
end
}
output_path = @options['squeeze.output_path'] || @options['yasqueeze.output_path']
suffix = @options['squeeze.suffix'] || ''
all_data = @options['squeeze.all_data'] || @options['yasqueeze.all_data']
overwrite = @options['squeeze.overwrite']
compat = @options['squeeze.compat_path'] || @options['yasqueeze.compat_path']
if FileTest::symlink?( __FILE__ ) then
org_path = File::dirname( File::readlink( __FILE__ ) )
else
org_path = File::dirname( __FILE__ )
end
$:.unshift( org_path.untaint )
end
begin
require "tdiary"
rescue LoadError
$stderr.print "squeeze.rb: cannot load tdiary.rb. <#{tdiary_path}/tdiary>\n"
exit( 1 )
end
end
#
# Dairy Squeeze
#
module ::TDiary
class YATDiarySqueeze < TDiaryBase
def initialize(diary, dest, all_data, overwrite, compat, conf, suffix)
@ignore_parser_cache = true
cgi = CGI::new
def cgi.referer; nil; end
def cgi.user_agent; 'bot'; end
super( cgi, 'day.rhtml', conf )
@diary = diary
@date = diary.date
@diaries = {@date.strftime('%Y%m%d') => @diary} if @diaries.size == 0
@dest = dest
@all_data = all_data
@overwrite = overwrite
@compat = compat
@suffix = suffix
end
def execute
if @compat
dir = @dest
name = @diary.date.strftime('%Y%m%d')
else
dir = @dest + "/" + @diary.date.strftime('%Y')
name = @diary.date.strftime('%m%d')
Dir.mkdir(dir, 0755) unless File.directory?(dir)
end
filename = dir + "/" + name + @suffix
if FileTest.exist?( filename ) and @overwrite
File::delete( filename )
end
if @diary.visible? or @all_data
if not FileTest::exist?(filename) or
File::mtime(filename) != @diary.last_modified
File::open(filename, 'w'){|f| f.write(eval_rhtml)}
File::utime(@diary.last_modified, @diary.last_modified, filename)
end
else
if FileTest.exist?(filename) and ! @all_data
name = "remove #{name}"
File::delete(filename)
else
name = ""
end
end
name
end
protected
def mode
'day'
end
def cookie_name; ''; end
def cookie_mail; ''; end
end
end
#
# Main
#
module ::TDiary
class YATDiarySqueezeMain < TDiaryBase
def initialize(dest, all_data, overwrite, compat, conf, suffix)
@ignore_parser_cache = true
cgi = CGI::new
def cgi.referer; nil; end
super( cgi, 'day.rhtml', conf )
calendar
@years.keys.sort.each do |year|
print "(#{year.to_s}/) "
@years[year.to_s].sort.each do |month|
diaries2 = nil
@io.transaction(Time::local(year.to_i, month.to_i)) do |diaries|
diaries2 = diaries
DIRTY_NONE
end
diaries2.sort.each do |day, diary|
print YATDiarySqueeze.new(diary, dest, all_data, overwrite, compat, conf, suffix).execute + " "
end
end
end
end
end
end
squeeze_navi_on_footer = ''
if mode == "CGI" || mode == "CMD"
if mode == "CGI"
print %Q[Content-type:text/html\n\n
Squeeze for tDiary
Squeeze for tDiary
$Revision: 1.25 $
Copyright (C) 2002 MUTOH Masao<mutoh@highway.ne.jp>
Start!
]
end
begin
require 'cgi'
cgi = CGI.new
def cgi.user_agent; 'bot'; end
conf = TDiary::Config::new(cgi)
conf.header = ''
conf.footer = squeeze_navi_on_footer
conf.show_comment = true
conf.hide_comment_form = true
output_path = "#{conf.data_path}/cache/html" unless output_path
Dir.mkdir(output_path, 0755) unless File.directory?(output_path)
::TDiary::YATDiarySqueezeMain.new(output_path, all_data, overwrite, compat, conf, suffix)
rescue
print $!, "\n"
$@.each do |v|
print v, "\n"
end
exit( 1 )
end
if mode == "CGI"
print "End!
\n"
else
print "\n\n"
end
else
add_update_proc do
conf = @conf.clone
conf.header = ''
conf.footer = squeeze_navi_on_footer
conf.show_comment = true
conf.hide_comment_form = true
diary = @diaries[@date.strftime('%Y%m%d')]
dir = @options['squeeze.output_path'] || @options['yasqueeze.output_path']
dir = @cache_path + "/html" unless dir
Dir.mkdir(dir, 0755) unless File.directory?(dir)
::TDiary::YATDiarySqueeze.new(diary, dir,
@options['squeeze.all_data'] || @options['yasqueeze.all_data'],
@options['squeeze.overwrite'],
@options['squeeze.compat_path'] || @options['yasqueeze.compat_path'],
conf,
@options['squeeze.suffix'] || ''
).execute
end
end
end
# Local Variables:
# mode: ruby
# indent-tabs-mode: t
# tab-width: 3
# ruby-indent-level: 3
# End:
tdiary-contrib-5.1.0/plugin/steam.rb 0000664 0000000 0000000 00000001104 13570131474 0017404 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
# steam.rb $Revision: 1.0 $
#
# 概要:
# steam(store.steampowered.com)のゲームのウィジェットを
# 貼るプラグインです。
#
# 使い方:
# steamの任意のゲームのID(store.steampowered.com/app/{id})
# を指定することにより、ウィジェットが貼り付けられます。
#
# Copyright (c) 2016 kp
# Distributed under the GPL
#
=begin ChangeLog
=end
def steam( id )
%Q[]
end
tdiary-contrib-5.1.0/plugin/tatsu_zine.rb 0000664 0000000 0000000 00000005010 13570131474 0020460 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
# Copyright (C) 2011, KADO Masanori
# You can redistribute it and/or modify it under GPL.
#
# display book info in http://tatsu-zine.com/ like amazon.rb
# USAGE: {{tatsu_zine 1}}
require 'open-uri'
def tatsu_zine_cache_dir
cache = "#{@cache_path}/tatsu-zine"
Dir.mkdir( cache ) unless File.directory?( cache )
cache
end
def tatsu_zine_cache_set( id, result )
File.open( "#{tatsu_zine_cache_dir}/#{id}", "w" ) do |f|
f.write result
end
end
def tatsu_zine_cache_get( id )
File.open( "#{tatsu_zine_cache_dir}/#{id}", "r" ) do |f|
f.read
end
rescue
nil
end
def tatsu_zine( id, doc = nil )
if !@conf.secure and !(result = tatsu_zine_cache_get(id)).nil?
return result
end
link = "https://tatsu-zine.com/books/#{id}"
doc ||= open(link, ssl_verify_mode: OpenSSL::SSL::VERIFY_NONE).read
title = doc.match(%r| |).to_a[1]
image = doc.match(%r| |).to_a[1]
price = doc.match(%r|span itemprop="price">(.*)|).to_a[1]
author = doc.match(%r|(.*)
|).to_a[1]
result = <<-EOS
#{h title}
#{h author}
#{h price}
EOS
tatsu_zine_cache_set( id, result ) unless @conf.secure
result
rescue => e
@logger.error(e)
link
end
if __FILE__ == $0
require 'test/unit'
class TestTatsuZine < Test::Unit::TestCase
def setup
@conf = Struct.new("Conf", :secure).new(true)
def h(str); str; end
end
def test_tatsu_zine
expect = <<-EOS
Ruby環境構築講座 Windows編
arton
1036
EOS
assert_equal expect, tatsu_zine('winrubybuild')
end
end
end
# Local Variables:
# mode: ruby
# indent-tabs-mode: t
# tab-width: 3
# ruby-indent-level: 3
# End:
tdiary-contrib-5.1.0/plugin/tdiarytimes2.rb 0000664 0000000 0000000 00000026516 13570131474 0020731 0 ustar 00root root 0000000 0000000 # tdiarytimes.rb $originalRevision: 1.1 $
#
# Copyright (c) 2003 neuichi
# Distributed under the GPL
#
# 2003-12-01 circle extention added by Minero Aoki
# $Id: tdiarytimes2.rb,v 1.2 2007/01/11 02:55:26 tadatadashi Exp $
#
# プラグイン配布ページ
# http://i.loveruby.net/w/tdiarytimes.html
#
# 動作条件:
# ruby-gdが使える環境が必要です。
#
# 使い方:
# このプラグインをプラグインディレクトリに入れ、
# index.rbと同じディレクトリに、tdiarytimes.pngという名前の
# サーバが書き込み権限を持っているファイルを作ります。
# これで日記に書き込みするごとに、tdiarytimes.pngに
# 画像を書き込みます。
#
# 日記上からこのpngファイルを呼び出すには、
# tDiray上からプラグインとして
# <%=tdiarytimes%>
# として呼び出します。
# 引数としてimgタグのaltの文字列を指定することも出来ます。
# <%=tdiarytimes '文字列'%>
#
# また、tdiary.confに以下のオプションを書き込むことにより、
# カスタマイズをすることが出来ます。
#
# @options['tdiarytimes.width'] = 400
# 四角の横幅。デフォルト値400。
# 実際に出力される画像サイズは、これに+10したサイズ。
#
# @options['tdiarytimes.height'] = 20
# 四角の縦幅。デフォルト値20。
# 実際に出力される画像サイズは、これに+16したサイズ。
#
# @options['tdiarytimes.file'] = 'tdiarytimes.png'
# 出力する画像ファイル名。デフォルトは'tdiarytimes.png'
#
# @options['tdiarytimes.fillcolor'] = '#444444'
# 四角の色。デフォルトは'#444444'
#
# @options['tdiarytimes.linecolor'] = '#ffffff'
# 縦棒の色。デフォルトは'#ffffff'
#
# @options['tdiarytimes.textcolor'] = '#444444'
# 文字色。デフォルトは'#444444'
#
# @options['tdiarytimes.fadeout'] = false
# フェードアウトするか。デフォルトはfalse。
# フェードアウトしたいときには true にすればよい。
#
# @options['tdiarytimes.fadeoutcolor'] = '#ffffff'
# フェードアウトするとき、
# デフォルトではfillcolorへとフェードアウトしていく。
# ここで色を指定するとその色へとフェードアウトしていく。
# デフォルトは false
#
# @options['tdiarytimes.text'] = 'T D I A R Y T I M E S'
# 出力する文字。デフォルトは'T D I A R Y T I M E S'。なお半角英数字のみ対応。
#
# @options['tdiarytimes.day'] = 30
# ログを保存する最大日数。デフォルトは30。
# この場合、30日以上経ったデータは消去され、縦棒として描画されなくなる。
#
require 'GD'
::GD::Image.module_eval {
def tiny_string(text, x, y, color)
string(GD::Font::TinyFont, x, y, text, color)
end
def small_string(text, x, y, color)
string(GD::Font::SmallFont, x, y, text, color)
end
}
# Ruby 1.6 missing File.read
unless ::File.respond_to?(:read)
def (::File).read(fname)
File.open(fname) {|f|
return f.read
}
end
end
# Ruby 1.6 missing MatchData#captures
unless ::MatchData.method_defined?(:captures)
::MatchData.module_eval {
def captures
a = to_a()
a.shift
a
end
}
end
class TDiaryTimes
class << TDiaryTimes
alias newobj new
end
def TDiaryTimes.new(datadir, options)
case options['tdiarytimes.shape']
when 'bar', nil
c = TDiaryTimesBar
when 'circle'
c = TDiaryTimesCircle
else
raise ArgumentError, "unknown tdiarytimes.shape: #{options['tdiarytimes.shape']}"
end
c.newobj("#{datadir}/tdiarytimes", options)
end
def initialize(dbfile, options)
@dbfile = dbfile
@image_file = options['tdiarytimes.file'] || 'tdiarytimes.png'
@day = options['tdiarytimes.day'] || 30
@keepdb = options['tdiarytimes.keepdb']
end
attr_reader :image_file
def update_image
now = Time.now
mtimes = (load_database() + [now]).reject {|tm|
(now - tm) > (60 * 60 * 24 * @day)
}
image = create_image(mtimes)
File.open(@image_file, 'w') {|png|
image.png(png)
}
save_database(mtimes) unless @keepdb
end
private
#
# database
#
def load_database
begin
return Marshal.load(File.read(@dbfile))
rescue Errno::ENOENT
return []
end
end
def save_database(content)
File.open(@dbfile, 'w') {|f|
Marshal.dump(content, f)
}
end
#
# common paint methods
#
def fadeout_color(srccolor, destcolor, time)
par = (Time.now - time).to_f / (60 * 60 * 24 * @day)
r, g, b = *zip(parse_rgb(srccolor), parse_rgb(destcolor))\
.map {|src, dest| src - (src - dest) * par }.map {|c| c.to_i }
sprintf('#%02x%02x%02x', r, g, b)
end
def parse_rgb(str)
hex = '[\da-f]'
m = /\A\#(#{hex}{2})(#{hex}{2})(#{hex}{2})\z/io.match(str) or
raise ArgumentError, "tdiarytimes: not color: #{str.inspect}"
m.captures.map {|c| c.hex }
end
def zip(*lists)
result = []
lists[0].each_index do |idx|
result.push lists.map {|lst| lst[idx] }
end
result
end
end
class TDiaryTimesBar < TDiaryTimes
def initialize(dbfile, options)
super
@text = options['tdiarytimes.text'] || 'T D I A R Y T I M E S'
@width = options['tdiarytimes.width'].to_i || 400
@height = options['tdiarytimes.height'].to_i || 20
@textcolor = options['tdiarytimes.textcolor'] || '#444444'
@fillcolor = options['tdiarytimes.fillcolor'] || '#444444'
@linecolor = options['tdiarytimes.linecolor'] || '#ffffff'
@fadeoutcolor = options['tdiarytimes.fadeoutcolor'] || @fillcolor
@fadeoutp = options['tdiarytimes.fadeout']
end
def html(alt)
%Q[ ].gsub(/\s+/, ' ')
end
private
GAP_W = 16
GAP_H = 16
def create_image(mtimes)
image = GD::Image.new(@width + GAP_W, @height + GAP_H)
image.transparent(image.colorAllocate('#fffffe'))
image.interlace = true
image.tiny_string @text, (GAP_W / 2), 0, image.colorAllocate(@textcolor)
image.filledRectangle 0 + GAP_W / 2, 0 + GAP_H / 2,
image.width - GAP_W / 2, image.height - GAP_H / 2,
image.colorAllocate(@fillcolor)
if @fadeoutp
paint_lines_fadeout image, mtimes, @linecolor, @fadeoutcolor
else
paint_lines image, mtimes, @linecolor
end
paint_hours image, image.colorAllocate(@textcolor),
(image.width - GAP_W > 160 ? 2 : 4)
image
end
def paint_lines(image, mtimes, color)
gdcolor = image.colorAllocate(color)
mtimes.each do |time|
line image, time, gdcolor
end
end
def paint_lines_fadeout(image, mtimes, linecolor, destcolor)
mtimes.each do |time|
line image, time,
image.colorAllocate(fadeout_color(linecolor, destcolor, time))
end
end
def line(image, time, color)
x0 = (image.width - GAP_W).to_f * (time.hour * 60 + time.min) / (60 * 24)
x = (x0 + (GAP_W / 1.25)).to_i
image.line x, 0 + (GAP_H / 2),
x, image.height - (GAP_H / 2),
color
end
def paint_hours(image, color, stepping)
0.step(24, stepping) do |hour|
image.tiny_string hour.to_s,
(image.width - GAP_W) * (hour.to_f / 24) + (GAP_W / 2) - 4,
image.height - (GAP_H / 2),
color
end
end
end
class TDiaryTimesCircle < TDiaryTimes
def initialize(dbfile, options)
super
#@text # cannot change now
@width = options['tdiarytimes.width'].to_i || 80
@height = options['tdiarytimes.height'].to_i || 80
@textcolor = options['tdiarytimes.textcolor'] || '#444444'
@fillcolor = options['tdiarytimes.fillcolor'] || '#444444'
@linecolor = options['tdiarytimes.linecolor'] || '#ffffff'
@fadeoutcolor = options['tdiarytimes.fadeoutcolor'] || @fillcolor
@fadeoutp = options['tdiarytimes.fadeout']
end
def html(alt)
%Q[ ].gsub(/\s+/, ' ')
end
private
MIN_DEGREE = 0
MAX_DEGREE = 250
BAR_WIDTH = 24
TRANSCOLOR = '#ffffff'
def create_image(mtimes)
image = GD::Image.new(@width, @height)
trans = image.colorAllocate(TRANSCOLOR)
image.transparent trans
image.interlace = true
paint_outer_circle image, trans
if @fadeoutp
paint_lines_fadeout image, mtimes, @linecolor, @fadeoutcolor
else
paint_lines image, mtimes, @linecolor
end
paint_inner_circle image, trans
textcolor = image.colorAllocate(@textcolor)
image.small_string 'tdiary', @width / 2 + 1, 11, textcolor
image.small_string 'times', @width / 2 + 4, 21, textcolor
image
end
def paint_outer_circle(image, trans)
image.filledArc @width / 2, @height / 2,
@width, @height,
MIN_DEGREE, MAX_DEGREE,
if @fillcolor == TRANSCOLOR
then trans
else image.colorAllocate(@fillcolor)
end,
0
end
def paint_inner_circle(image, trans)
image.filledArc @width / 2, @height / 2,
@width - BAR_WIDTH * 2,
(@width - BAR_WIDTH * 2) * (@height.to_f / @width),
0, 360, trans, 0
end
def paint_lines(image, mtimes, color)
gdcolor = image.colorAllocate(color)
mtimes.each do |time|
line image, time, gdcolor
end
end
def paint_lines_fadeout(image, mtimes, linecolor, destcolor)
mtimes.each do |time|
line image, time,
image.colorAllocate(fadeout_color(linecolor, destcolor, time))
end
end
def line(image, time, color)
d0 = (time.hour * 60 + time.min).to_f / (60 * 24)
d = MIN_DEGREE + (MAX_DEGREE - MIN_DEGREE) * d0
image.line @width / 2, @height / 2,
@width / 2 + degcos(d) * (@width / 2) * 0.95,
@height / 2 + degsin(d) * (@height / 2) * 0.95,
color
end
include Math
def degsin(d)
sin(d / (180 / Math::PI))
end
def degcos(d)
cos(d / (180 / Math::PI))
end
end
def tdiarytimes(alt = nil)
TDiaryTimes.new(@conf.data_path, @options).html(alt)
end
if $0 == __FILE__ # debugging
tmp_options_bar = {
'tdiarytimes.shape' => 'bar',
'tdiarytimes.textcolor' => '#666666',
'tdiarytimes.linecolor' => '#df0000',
'tdiarytimes.fillcolor' => '#0f5f0f',
'tdiarytimes.fadeout' => true,
'tdiarytimes.keepdb' => false # for debug
}
tmp_options_circle = {
'tdiarytimes.shape' => 'circle',
'tdiarytimes.textcolor' => '#000000',
'tdiarytimes.linecolor' => '#bfbfbf',
'tdiarytimes.fillcolor' => '#2f2f7f',
'tdiarytimes.fadeout' => true,
'tdiarytimes.keepdb' => false # for debug
}
@mode = 'latest'
@conf = Object.new
def @conf.data_path
'.'
end
case ARGV[0]
when 'bar'
@options = tmp_options_bar
else
@options = tmp_options_circle
end
TDiaryTimes.new(@conf.data_path, @options).update_image
puts tdiarytimes()
exit 0
end
if /append|replace/ =~ @mode
TDiaryTimes.new(@conf.data_path, @options).update_image
end
tdiary-contrib-5.1.0/plugin/tdiarytimes_flashstyle.rb 0000664 0000000 0000000 00000035536 13570131474 0023107 0 ustar 00root root 0000000 0000000 # tdiarytimes_flashstyle.rb $Revision: 1.2 $
#
# Copyright (c) 2004 phonondrive
# Distributed under the GPL
#
# プラグイン配布ページ:
# http://phonondrive.com/trd/
# --------------------------------------------------------------------
#
#
#
# Abstract:
# --------------------------------------------------------------------
# 日記を登録した時間帯をタイムライン上に記録します。記録されたエントリは
# 日時の経過と共にフェードアウトしていきます。このような MTBlogTimes や
# tdiarytimes.rb と同等の機能を Flash で実現します。
# ruby-gd のインストール作業も必要ないため、すぐに使用出来ます。
#
#
# Usage:
# --------------------------------------------------------------------
# プラグインは、プラグインフォルダに入れて下さい。
#
# プラグインは、プラグインフォルダに入れてください。
# tdiarytimes*.swf を tdiary.rb と同じフォルダにアップロードします。
# ヘッダ、フッタ部に記述した <%= tdiarytimes_flashstyle %> の部分に、
# Flash アプレットが表示されます。
# tdiarytimes.log は日記登録時に .swf と同じフォルダに作成されます。
#
# ※ tdiarytimes_textstyle.rb との互換性はありません。
#
#
# Options:
# --------------------------------------------------------------------
# タイムラインの色、透明度、サイズなどは、プリファレンス画面で設定できます。
#
#
# In secure mode:
# --------------------------------------------------------------------
# たぶん動作しません。
#
#
=begin ChangeLog
2004.05.02 phonondrive
* version 1.1.2
タイムラインが曜日別の Flash を追加
2004.05.02 phonondrive
* version 1.1.1
タイムラインが円形で、時刻盤が曜日表示の Flash を追加
ログファイルが存在しない時にエラーが出る不具合を修正
2004.04.28 phonondrive
* version 1.1.0
タイムラインが円形の Flash を追加
2004.04.27 phonondrive
* version 1.0.1
時刻目盛テキストの色が変更されない不具合を修正
2004.04.25 phonondrive
* version 1.0.0
=end
# --------------------------------------------------------------------
# プラグインの動作
# --------------------------------------------------------------------
def tdiarytimes_flashstyle
if @conf['tdiarytimes_f.templete'] == nil or @conf['tdiarytimes_f.templete'] == ""
%Q|使用を開始するには、プリファレンス画面 にて一度設定を完了して下さい。(tdiarytimes-flashstyle)|
else
logname = ((@conf['tdiarytimes_f.log_path'] != "" and @conf['tdiarytimes_f.log_path'] != nil) ? @conf['tdiarytimes_f.log_path'] : "tdiarytimes.log")
@conf['tdiarygraph_f.templete'].sub(/&uid/, "\\&=#{File.mtime(logname.untaint).to_i}")
end
end
# --------------------------------------------------------------------
# 日記登録時の処理
# --------------------------------------------------------------------
if /\A(?:append|replace)\z/ =~ @mode and @cgi.params['hide'][0] != 'true' then
logname = ((@conf['tdiarytimes_f.log_path'] != "" and @conf['tdiarytimes_f.log_path'] != nil) ? @conf['tdiarytimes_f.log_path'] : "tdiarytimes.log")
entr_lifetime = ((@conf['tdiarytimes_f.entr_lifetime'] != "" and @conf['tdiarytimes_f.entr_lifetime'] != nil) ? @conf['tdiarytimes_f.entr_lifetime'].to_i * 60 * 60 * 24 : 30 * 24 * 60 * 60)
entr_interval = ((@conf['tdiarytimes_f.entr_interval'] != "" and @conf['tdiarytimes_f.entr_interval'] != nil) ? @conf['tdiarytimes_f.entr_interval'] : 2 * 60 * 60)
begin
logs = open(logname){|io| io.read }.chomp.split(',')
rescue
logs = ""
end
if (Time.now.to_i - logs.max.to_i) > entr_interval.to_i
logs << "#{Time.now.to_i}"
open(logname, "w"){|io|
io.write(logs.find_all{|item| (Time.now.to_i - item.to_i) < entr_lifetime.to_i }.join(','))
}
end
end
# --------------------------------------------------------------------
# プリファレンス画面での設定
# --------------------------------------------------------------------
add_conf_proc( 'tdiarytimes_f', 'tdiarytimes-flashstyle の設定' ) do
if @mode == 'saveconf' then
filename = "tdiarytimes234x30.swf"
width = "234"
height = "30"
argvs = ""
argv = Array.new
@conf['tdiarytimes_f.uid'] = @cgi.params['uid'][0]
argv << "#{Time.now.to_i}&uid" if @conf['tdiarytimes_f.uid'] == "1"
@conf['tdiarytimes_f.type'] = @cgi.params['type'][0]
@conf['tdiarytimes_f.filename'] = @cgi.params['filename'][0]
@conf['tdiarytimes_f.width'] = @cgi.params['width'][0]
@conf['tdiarytimes_f.height'] = @cgi.params['height'][0]
@conf['tdiarytimes_f.log_path'] = @cgi.params['log_path'][0]
argv << "log_path=#{@cgi.params['log_path'][0]}" if @cgi.params['log_path'][0] != ""
@conf['tdiarytimes_f.text_visible'] = @cgi.params['text_visible'][0]
argv << "text_visible=#{@cgi.params['text_visible'][0]}" if @cgi.params['text_visible'][0] == "0"
@conf['tdiarytimes_f.text_text'] = @cgi.params['text_text'][0]
argv << "text_text=#{CGI::escape @cgi.params['text_text'][0].upcase}" if @cgi.params['text_text'][0] != ""
@conf['tdiarytimes_f.text_rgb'] = @cgi.params['text_rgb'][0]
argv << "text_rgb=0x#{@cgi.params['text_rgb'][0]}" if @cgi.params['text_rgb'][0] != ""
@conf['tdiarytimes_f.face_visible'] = @cgi.params['face_visible'][0]
argv << "face_visible=#{@cgi.params['face_visible'][0]}" if @cgi.params['face_visible'][0] == "0"
@conf['tdiarytimes_f.face_rgb'] = @cgi.params['face_rgb'][0]
argv << "face_rgb=0x#{@cgi.params['face_rgb'][0]}" if @cgi.params['face_rgb'][0] != ""
@conf['tdiarytimes_f.stage_rgb'] = @cgi.params['stage_rgb'][0]
argv << "stage_rgb=0x#{@cgi.params['stage_rgb'][0]}" if @cgi.params['stage_rgb'][0] != ""
@conf['tdiarytimes_f.stage_alpha'] = @cgi.params['stage_alpha'][0]
argv << "stage_alpha=#{@cgi.params['stage_alpha'][0]}" if @cgi.params['stage_alpha'][0] != ""
@conf['tdiarytimes_f.bg_rgb'] = @cgi.params['bg_rgb'][0]
argv << "bg_rgb=0x#{@cgi.params['bg_rgb'][0]}" if @cgi.params['bg_rgb'][0] != ""
@conf['tdiarytimes_f.bg_alpha'] = @cgi.params['bg_alpha'][0]
argv << "bg_alpha=#{@cgi.params['bg_alpha'][0]}" if @cgi.params['bg_alpha'][0] != ""
@conf['tdiarytimes_f.bar_rgb'] = @cgi.params['bar_rgb'][0]
argv << "bar_rgb=0x#{@cgi.params['bar_rgb'][0]}" if @cgi.params['bar_rgb'][0] != ""
@conf['tdiarytimes_f.bar_width'] = @cgi.params['bar_width'][0]
argv << "bar_width=#{@cgi.params['bar_width'][0]}" if @cgi.params['bar_width'][0] != ""
@conf['tdiarytimes_f.entr_interval'] = @cgi.params['entr_interval'][0]
@conf['tdiarytimes_f.entr_lifetime'] = @cgi.params['entr_lifetime'][0]
@conf['tdiarytimes_f.fade_time'] = @cgi.params['fade_time'][0]
argv << "fade_time=#{@cgi.params['fade_time'][0]}" if @cgi.params['fade_time'][0] != ""
@conf['tdiarytimes_f.preview'] = @cgi.params['preview'][0]
if @cgi.params['type'][0] == "0"
filename = @cgi.params['filename'][0]
width = @cgi.params['width'][0]
height = @cgi.params['height'][0]
elsif @cgi.params['type'][0]
filename = "tdiarytimes#{@cgi.params['type'][0].delete('-')}.swf"
width = @cgi.params['type'][0].split('-').first.split('x')[0]
height = @cgi.params['type'][0].split('-').first.split('x')[1]
end
if argv.size > 0 then argvs = "?#{argv.join('&')}" end
@conf['tdiarytimes_f.templete'] = tdiarytimes_flashstyle_templete(filename, argvs, width, height)
end
<<-HTML
設定の概要
() 内は初期値です。初期値を使用する場合は、空欄のままで構いません。色は RRGGBB 形式で指定して下さい。不透明度は 0 (透明) 〜 100 (不透明) です。線幅はピクセルで指定します。
プレビュー
#{tdiarytimes_flashstyle_preview}
表示する Flash アプレットの選択
プリセットを使用しない
tdiarytimes125x30.swf, 125x30
tdiarytimes234x30.swf, 234x30
tdiarytimes468x30.swf, 468x30
tdiarytimes125x125r.swf, 125x125 (円形)
tdiarytimes125x125r7.swf, 125x125 (円形, 曜日)
tdiarytimes125x125s.swf, 125x125 (曜日別)
プリセットを使用しない場合は、以下で指定して下さい。
Flash のファイル名
Flash の表示幅
Flash の表示高さ
タイトルテキスト
タイトルテキストの表示有無 (表示)
表示
非表示
タイトルテキスト (TDIARYTIMES-FLASHSTYLE) 使用出来る文字は、英大文字 (A-Z) と数字 (0-9)、および記号のみです。
タイトルテキストの色 (333333)
時刻目盛テキスト
時刻目盛テキストの表示有無 (表示)
表示
非表示
時刻目盛テキストの色 (333333)
背景や棒グラフの色
背景の色 (FFFFFF)
背景の不透明度 (0)
タイムラインの背景の色 (333333)
タイムラインの背景の不透明度 (100)
タイムラインに記録される棒グラフの色 (EEEEEE)
タイムラインに記録される棒グラフの線幅 (1)
タイムラインに記録される棒グラフの寿命日数 (30)
ログ管理
前回の日記登録から設定時間内はエントリを新規登録しない (2)
設定日数後にログファイルからエントリを削除する (30)
本プラグインが作成するログファイル名 (tdiarytimes.log)
ユニークID を使用したファイル取得
ファイル取得のリクエストにユニークID (例えば ?#{Time.now.to_i}) を含めることにより、古いファイルがブラウザにキャッシュされたままになるのを防ぎます。Flash のユニークID はプリファレンス設定時に、ログファイルのユニークID はエントリ登録時に更新されます。
ユニークID の付加 (付加する)
付加する
付加しない
プレビュー
表示したい SWF ファイル (.swf) が tdiary.rb と同じフォルダにアップロードされている必要があります。また、ログファイルが SWF ファイルと同じフォルダに作成されていない場合にはグラフが表示されません。
プレビュー (非表示)
非表示
表示
HTML
end
def tdiarytimes_flashstyle_preview
%Q|#{if @conf['tdiarytimes_f.preview'] == "1" then "#{tdiarytimes_flashstyle}" else "プレビュー表示を有効にすると、ここに Flash が表示されます。" end}
|
end
def tdiarytimes_flashstyle_templete( filename="tdiarytimes234x30.swf", argvs="", width="234", height="30" )
<<-r
r
end
tdiary-contrib-5.1.0/plugin/tdiarytimes_textstyle.rb 0000664 0000000 0000000 00000026626 13570131474 0022776 0 ustar 00root root 0000000 0000000 # tdiarytimes_textstyle.rb $Revision: 1.3 $
#
# Copyright (c) 2004 phonondrive
# Distributed under the GPL
#
# プラグイン配布ページ:
# http://phonondrive.com/trd/
# --------------------------------------------------------------------
#
#
#
# Abstract:
# --------------------------------------------------------------------
# 日記を登録した時間帯をタイムライン上に記録します。
# 記録されたエントリは日時の経過と共にフェードアウトしていきます。
# このような MTBlogTimes や tdiarytimes と同等の機能をテキストで実現します。
# また、テキストベースであることを生かした柔軟なサイトデザインが可能です。
# ruby-gd のインストール作業も必要ないため、すぐに使用出来ます。
#
#
# Usage:
# --------------------------------------------------------------------
# プラグインは、プラグインフォルダに入れてください。
# ヘッダ、あるいはフッタ部に入力した <%= tdiarytimes_textstyle %>
# の位置にタイムライン文字列が展開されます。
# 新しいエントリの記録や保持期間の過ぎた古いエントリの削除は、
# 日記の追加および登録時に行われます。
# ただし、エントリのフェードアウト効果はリアルタイムに計算されます。
# エントリの表示分解能は10分ごとです。
#
#
# Options:
# --------------------------------------------------------------------
#
# 現在、次の9つのオプションが用意されています。
#
# init_text 日記の登録されていない時間帯の文字列 (任意の文字列)
# entr_text 日記が登録された時間帯の文字列 (任意の文字列)
# init_color 日記の登録されていない時間帯の文字列の色 (RRBBGG形式で指定)
# entr_color 日記が登録された時間帯の文字列の色 (RRBBGG形式で指定)
# fade_color 日記が登録された時間帯の文字列のフェードアウト先の色 (RRBBGG形式で指定)
# init_css タイムライン文字列全体のCSS設定 (CSSの書式に準拠)
# entr_css 日記が登録された時間帯の文字列のCSS設定 (CSSの書式に準拠)
# title_text オブジェクト上にマウスをポイントした時のTIPS文字列 (任意の文字列)
# fade_time ログとして保存しておく(フェードアウトに要する)日数 (任意の数値)
# entr_interval 前回のエントリ登録から指定時間以内は新規登録しない (任意の数値)
#
# オプション値の設定方法には3つの方法があり、その優先順位は次の通りです。
# <%= tdiarytimes_textstyle %> 引数指定 > tdiary.conf設定値 > デフォルト値
#
# entr_intervalを除いた全てのオプション値は <%= %> への引数指定により設定出来るため、
# ページにごとに意匠を変更するなど自由度の高いサイトデザインが可能です。
# 一方で、全てのオプションにデフォルト値が用意されているため、
# 全く設定を行わなくても動作します。
# デフォルト値の具体的な値については、tdiary.confへの記述方法の項を参照して下さい。
#
#
# <%= tdiarytimes_textstyle %>への引数指定によるオプション設定方法
# --------------------------------------------------------------------
#【書式】
# <%= tdiarytimes_textstyle init_text, entr_text, init_color, entr_color, fade_color, init_css, entr_css, title_text, fade_time %>
#
#【記述例】
# <%=tdiarytimes_textstyle "●","●","004400","66ff66","004400","background-color:#002200;font-size:9px",nil,"TEXTSTYLE!!",15 %>
#
# ※ tdiary.conf指定値、またはデフォルト値を使用したい場合は、引数に nil を指定してください。
#
#
# tdiary.confへの記述によるオプション設定方法
# --------------------------------------------------------------------
#【記述例】 (例として指定されている値は、プラグイン本体の持つデフォルト値です)
# @options['tdiarytimes_textstyle.init_text'] = "|"
# @options['tdiarytimes_textstyle.entr_text'] = "|"
# @options['tdiarytimes_textstyle.init_color'] = "444444"
# @options['tdiarytimes_textstyle.entr_color'] = "eeeeee"
# @options['tdiarytimes_textstyle.fade_color'] = "444444"
# @options['tdiarytimes_textstyle.init_css'] = "background-color:#444444;"
# @options['tdiarytimes_textstyle.entr_css'] = ""
# @options['tdiarytimes_textstyle.title_text'] = "TDIARYTIMES-TEXTSTYLE"
# @options['tdiarytimes_textstyle.fade_time'] = 30
# @options['tdiarytimes_textstyle.entr_interval'] = 1
#
# ※ fade_time の単位は日、entr_interval の単位は時間です。
# ※ ログとして保存しておく期間(フェードアウト期間)を過ぎたデータエントリは、
# 指定期間経過後の次回日記追加時にログファイルから削除されます。
# この期間を決定する fade_time 値は、<%= %> 引数からは指定出来ません。
# デフォルト値(30日)以外の値を用いたい場合は、必ず tdiary.conf にて指定して下さい。
# 同様に、entr_interval もデフォルト値(1時間)以外に設定したい場合は、
# tdiary.conf にて指定して下さい。ちなみに0.5だと30分間隔になります。
#
#
# In secure mode:
# --------------------------------------------------------------------
# 現在のところ動作しません。(ログファイルを読み込めない為)
#
#
# Acknowledgements:
# --------------------------------------------------------------------
# This plugin is based on tdiarytimes.rb $Revision: 1.3 $
# Copyright (c) 2003 neuichi
# Distributed under the GPL
# http://nmnl.jp/hiki/software/?tDiary+%3A%3A+Plugin
#
#
=begin ChangeLog
2004.03.04 phonondrive
* version 1.0.4
非応答USER-AGENTリストを更新しました。
2004.02.05 phonondrive
* version 1.0.3
フェードアウト効果の計算結果が正しく出力されない点を修正しました。
2004.01.30 phonondrive
* version 1.0.2
最低登録間隔のオプション (entr_interval) を追加。
前回のエントリ登録から指定時間以内は新規登録しないようにしました。
2004.01.29 phonondrive
* version 1.0.1
replace(登録)時もエントリを記録するようにしました。
次のUSER-AGENTからの呼び出しには結果を出力しないようにしました。
モバイル端末 (tDiary準拠)
テキストブラウザ (w3m, Lynx, links)
CSS非対応ブラウザ (Mosaic, Lite, iCab, JustView, WebExplorer)
検索ボット (bot, crawler, Spider, Slurp, inktomi, Sidewinder, naver)
その他 (libwww, antenna)
2004.01.28 phonondrive
* version 1.0.0
=end
# tDiarytimes_textstyle の結果を出力しない USER-AGENT リスト
# モバイル端末、テキストブラウザ、CSS非対応ブラウザ、検索ボット、アンテナなど
# 大文字・小文字は区別しません。
def tdiarytimes_textstyle_ignore_user_agent; "w3m|Lynx|links|Mosaic|Lite|iCab|JustView|WebExplorer|bot|crawler|Spider|Slurp|inktomi|Sidewinder|naver|libwww|archiver|http|check|WDB|WWWC|WWWD|samidare|tamatebako|NATSU-MICAN|hina|antenna"; end
# --------------------------------------------------------------------
# 日記登録時の処理
# --------------------------------------------------------------------
if /^(append|replace)$/ =~ @mode then
# オプション値(エントリ保持期間)の読み込みと設定
fade_time = @options['tdiarytimes_textstyle.fade_time'] || 30
fade_time = 24 * 60 * 60 * fade_time.to_f
entr_interval = @options['tdiarytimes_textstyle.entr_interval'] || 1
entr_interval = 60 * 60 * entr_interval.to_f
# ログデータの読み込み
cache = "#{@cache_path}/tdiarytimes_textstyle"
Dir::mkdir( cache ) unless File::directory?( cache )
begin
io = open("#{cache}/tdiarytimes_textstyle.dat","r")
ary_data = Marshal.load(io)
io.close
# 1.0.1 >> 1.0.2 ログデータ移行用
if ary_data.size == 144
ary_data.push(Time.now.to_i - entr_interval - 1)
end
rescue
# ログがない場合は仮データを用意
ary_data = Array.new(145) {|i| 0 }
end
# 不良データや寿命が来たエントリを削除する
(0..143).each {|i|
delta = (Time.now.to_i - ary_data[i])/fade_time.to_f
if delta < 0 || delta > 1
ary_data[i] = 0
end
}
# 最低登録間隔を経過していたら、日記が登録された時間帯に新しいエントリをセットする
if (Time.now.to_i - ary_data[144]) > entr_interval.to_f
ary_data[(Time.now.strftime('%H').to_i*6 + Time.now.strftime('%M').to_f/10).to_i] = Time.now.to_i
# 最終登録時間の記録
ary_data[144] = Time.now.to_i
end
# ログデータの書き込み
io = open("#{cache}/tdiarytimes_textstyle.dat","w")
Marshal.dump(ary_data,io)
io.close
end
# --------------------------------------------------------------------
# プラグイン表示時の動作
# --------------------------------------------------------------------
def tdiarytimes_textstyle(init_text = nil, entr_text = nil, init_color = nil, entr_color = nil, fade_color = nil, init_css = nil, entr_css = nil, title_text = nil, fade_time = nil)
r = ""
# オプション値の読み込みと設定
init_text = @options['tdiarytimes_textstyle.init_text'] || "|" unless init_text
entr_text = @options['tdiarytimes_textstyle.entr_text'] || "|" unless entr_text
init_color = @options['tdiarytimes_textstyle.init_color'] || "444444" unless init_color
entr_color = @options['tdiarytimes_textstyle.entr_color'] || "eeeeee" unless entr_color
fade_color = @options['tdiarytimes_textstyle.fade_color'] || "444444" unless fade_color
init_css = @options['tdiarytimes_textstyle.init_css'] || "background-color:#444444;" unless init_css
entr_css = @options['tdiarytimes_textstyle.entr_css'] || "" unless entr_css
title_text = @options['tdiarytimes_textstyle.title_text'] || "TDIARYTIMES-TEXTSTYLE" unless title_text
fade_time = @options['tdiarytimes_textstyle.fade_time'] || 30 unless fade_time
entr_color_rgb = entr_color.unpack("a2a2a2")
fade_color_rgb = fade_color.unpack("a2a2a2")
fade_time = 24 * 60 * 60 * fade_time.to_f
# ログデータの読み込み
cache = "#{@cache_path}/tdiarytimes_textstyle"
begin
io = open("#{cache}/tdiarytimes_textstyle.dat","r")
ary_data = Marshal.load(io)
io.close
rescue
# ログファイルが見つからない場合はエラーとダミーデータを表示
r << %Q|Error! cannot open log file.|
ary_data = Array.new(145) {|i| 0 }
end
# htmlデータの出力
r << %Q||
(0..143).each {|i|
data = ary_data[i]
if data != 0
delta = (Time.now.to_i - data)/fade_time.to_f
if delta < 0
# 不良エントリ対策
now_color = init_color
elsif delta > 1
# フェードアウト期間超過エントリ対策
now_color = fade_color
else
# 正常なエントリの処理
now_color = ""
(0..2).each{|i|
now_color << format("%02x", entr_color_rgb[i].hex + ((fade_color_rgb[i].hex - entr_color_rgb[i].hex)*delta).to_i)
}
end
r << %Q|#{entr_text} |
else
r << %Q|#{init_text}|
end
}
r << %Q| |
end
end
tdiary-contrib-5.1.0/plugin/title_anchor.rb 0000664 0000000 0000000 00000000444 13570131474 0020754 0 ustar 00root root 0000000 0000000 #
# title_anchor.rb:
#
# Copyright (C) 2007 by SHIBATA Hiroshi
# Distributed under GPL2.
#
def title_anchor
r = ''
if /^latest$/ =~ @mode
r << %Q|#{h @conf.html_title} |
else
r << %Q||
end
r
end
tdiary-contrib-5.1.0/plugin/tweet_quote.rb 0000664 0000000 0000000 00000015443 13570131474 0020653 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
#
# tweet_quote.rb - tDiary plugin to quote tweet on twitter.com,
# formaly known as blackbird-pie.rb
#
# Copyright (C) 2010, hb
#
# usage:
# <%= tweet_quote "id|url" %>
# or
# <%= twitter_quote "id|url" %>
# or
# <%= blackbird_pie "id|url" %>
# or
# <%= bbp "id|url" %>
#
require 'pstore'
require 'open-uri'
require 'timeout'
require 'time'
require 'uri'
require 'openssl'
require 'json'
def twitter_quote_option_keys
%w( oauth_consumer_key oauth_consumer_secret oauth_token oauth_token_secret render_method ).map{|k| "twitter_quote.#{k}" }
end
def twitter_statuses_show_api( tweet_id )
url = "https://api.twitter.com/1.1/statuses/show.json"
unsafe = /[^a-zA-Z0-9\-\.\_\~]/
parameters = {
:id => tweet_id
}
oauth_parameters = {
:oauth_consumer_key => @conf["twitter_quote.oauth_consumer_key"],
:oauth_nonce => OpenSSL::Digest.hexdigest( "MD5", "#{Time.now.to_f}#{rand}" ),
:oauth_signature_method => "HMAC-SHA1",
:oauth_timestamp => Time.now.to_i.to_s,
:oauth_token => @conf["twitter_quote.oauth_token"],
:oauth_version => "1.0"
}
data = "GET{URI.escape( url, unsafe )}&"
data << URI.escape( oauth_parameters.merge( parameters ).sort.map{|k, v| "#{k}=#{v}" }.join( "&" ), unsafe )
oauth_parameters[:oauth_signature] = [OpenSSL::HMAC.digest(
OpenSSL::Digest::SHA1.new,
URI.escape( "#{@conf["twitter_quote.oauth_consumer_secret"]}{@conf["twitter_quote.oauth_token_secret"]}" ),
data
)].pack( "m" ).chomp
proxy = @conf['proxy']
proxy = 'http://' + proxy if proxy
headers = {
"Authorization" => %Q[OAuth #{oauth_parameters.map{|k ,v| "#{URI.escape( k.to_s, unsafe )}=\"#{URI.escape( v, unsafe )}\""}.join( "," )}],
:proxy => proxy
}
Timeout.timeout( 20 ) do
open( "#{url}?#{parameters.map{|k,v| "#{k}=#{v}"}.join( "&" )}", headers ) {|f| f.read }
end
end
def render_widget(tweet_id, screen_name, name, background_url, profile_backgound_color, avatar, source, timestamp, content)
<<-HTML
HTML
end
def render_bbp(tweet_id, screen_name, name, background_url, profile_backgound_color, avatar, source, timestamp, content)
<<-HTML
HTML
end
def twitter_status_json_to_html( json )
tweet_id = json['id_str']
screen_name = json['user']['screen_name']
name = json['user']['name']
background_url = json['user']['profile_background_image_url']
profile_background_color = "##{json['user']['profile_background_color']}"
avatar = json['user']['profile_image_url']
source = json['source']
timestamp = Time.parse( json['created_at'] )
content = json['text']
content.gsub!( URI.regexp( %w|http https| ) ){ %Q|#{$&} | }
content = content.split( /(<[^>]*>)/ ).map {|s|
next s if s[/\A]
s.gsub!( /@(?>([a-zA-Z0-9_]{1,15}))(?![a-zA-Z0-9_])/ ){ %Q|#{$&} | }
s.gsub( /#([a-zA-Z0-9]{1,16})/ ){ %Q|#{$&} | }
}.join
if @conf['twitter_quote.render_method'] == 'widget'
render_widget(tweet_id, screen_name, name, background_url, profile_backgound_color, avatar, source, timestamp, content)
else
render_bbp(tweet_id, screen_name, name, background_url, profile_backgound_color, avatar, source, timestamp, content)
end
end
def tweet_quote( src )
return unless twitter_quote_option_keys.all?{|v| @options.key? v }
if %r|http(?:s)?://twitter.com/(?:#!/)?[^/]{1,15}/status(?:es)?/([0-9]+)| =~ src.to_s.downcase
src = $1
end
return unless /\A[0-9]+\z/ =~ src.to_s
cache = "#{@cache_path}/tweet_quote.pstore"
json = nil
db = PStore.new( cache )
db.transaction do
key = src
db[key] ||= {}
if db[key][:json] && /\A(?:latest|day|month|nyear)\z/ =~ @mode
json = db[key][:json]
else
begin
json = twitter_statuses_show_api( src )
rescue OpenURI::HTTPError
return %Q||
end
db[key][:json] = json
end
end
twitter_status_json_to_html( JSON.parse( json ) )
end
add_conf_proc( 'twitter_quote', 'Embedded Tweets' ) do
if @mode == 'saveconf'
twitter_quote_option_keys.each do |k|
@conf[k] = @cgi.params[k][0]
end
end
<<-HTML
Twitter OAuth settings
Consumer key
Consumer secret
Your access token
Access token
Access token secret
Render method
Bbp
Widget
HTML
end
alias :blackbird_pie :tweet_quote
alias :bbp :tweet_quote
alias :twitter_quote :tweet_quote
tdiary-contrib-5.1.0/plugin/twitpic.rb 0000664 0000000 0000000 00000000500 13570131474 0017755 0 ustar 00root root 0000000 0000000 #
# twitpic.rb: plugin to insert images on twitpic.com.
#
# Copyright (C) 2010 TADA Tadashi
# You can redistribute it and/or modify it under GPL2.
#
def twitpic(image_id, label = 'Image on Twitpic', place = 'photo')
%Q|#{h label}
|
end
tdiary-contrib-5.1.0/plugin/twitter.rb 0000664 0000000 0000000 00000002326 13570131474 0020004 0 ustar 00root root 0000000 0000000 # twitter.rb $Revision: 1.1 $
# Copyright (C) 2007 Michitaka Ohno
# You can redistribute it and/or modify it under GPL2.
require 'timeout'
require 'time'
require 'open-uri'
require 'rexml/document'
@twitter_statuses = []
if /^(latest|day)$/ =~ @mode then
add_header_proc do
xml = nil
Timeout.timeout( 5 ) do
begin
xml = open( "http://twitter.com/statuses/user_timeline/#{@conf['twitter.user']}.xml" ){|f| f.read}
rescue Exception
end
end
doc = REXML::Document.new( xml ).root if xml
if doc then
doc.elements.each( 'status' ) do |e|
@twitter_statuses << [@conf.to_native( e.elements['text'].text ), Time.parse( e.elements['created_at'].text ).localtime]
end
end
''
end
end
add_body_leave_proc do |date|
today_statuses = []
@twitter_statuses.each do |t, d|
today_statuses << [t, d] if d.to_a[3,3] == date.to_a[3,3]
end
if !today_statuses.empty?
r = %Q[]
r << %Q[
]
today_statuses.sort{|a, b| b.last<=>a.last}.each do |t, d|
r << %Q[
#{CGI::escapeHTML( t )} (#{d.strftime( '%H:%M:%S' )})
]
end
r << %Q[
]
else
''
end
end
tdiary-contrib-5.1.0/plugin/twitter_anywhere.rb 0000664 0000000 0000000 00000012307 13570131474 0021706 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
#
# twitter_anywhere.rb - bringing the Twitter communication platform to tDiary
# refer to the URL below.
# https://dev.twitter.com/docs/anywhere/welcome
#
# Copyright (C) 2010-2012, tamoot
# You can redistribute it and/or modify it under GPL2.
#
def follow_button(account)
return not_support_anywhere unless support_anywhere?
return not_ready_anywhere unless ready_anywhere?
if account.nil? || account == ''
return anywhere_plugin_error("Account name is not specified.")
end
<<-FOLLOW_API
FOLLOW_API
end
def tweet_box(label = nil, content = nil, option = {})
return not_support_anywhere unless support_anywhere?
return not_ready_anywhere unless ready_anywhere?
init_tweetbox
@tweetbox_opt.merge!(option)
@tweetbox_opt.merge!(:height => 120) unless option[:height].to_i > 0
@tweetbox_opt.merge!(:width => 480) unless option[:width].to_i > 0
@tweetbox_opt.merge!(:label => label) if label
@tweetbox_opt.merge!(:defaultContent => content) if content
%Q||
end
def twitter_anywhere_settings
enable_js('twitter_anywhere.js')
add_js_setting('$tDiary.plugin.twitter_anywhere')
selectors = @conf['twitter_anywhere.hovercards.selectors'].split(',').collect do |selector|
%Q|"#{selector.strip}"|
end
add_js_setting('$tDiary.plugin.twitter_anywhere.selectors',
"[#{selectors.join(',')}]" )
expanded = '{}'
if @conf['twitter_anywhere.hovercards.expand_default'] == 'true'
expanded = '{"expanded":true}'
end
add_js_setting('$tDiary.plugin.twitter_anywhere.hovercards')
add_js_setting('$tDiary.plugin.twitter_anywhere.hovercards.expand_default',
expanded)
end
add_header_proc do
if /\A(?:latest|day|month|nyear|preview)\z/ =~ @mode
if ready_anywhere?
%Q||
else
''
end
end
end
def init_tweetbox
@tweetbox_json_opt ||= []
@tweetbox_opt ||= {}
end
add_footer_proc do |date|
if /\A(?:latest|day|month|nyear|preview)\z/ =~ @mode
if ready_anywhere?
init_tweetbox
@tweetbox_opt.each_pair do |k, v|
@tweetbox_json_opt << "\"#{k}\":\"#{v}\""
end
tweet_box_call = %Q|\n|
else
''
end
else
''
end
end
add_conf_proc( 'twitter_anywhere', 'Twitter Anywhere' ) do
if @mode == 'saveconf' then
@conf['twitter_anywhere.id'] = @cgi.params['twitter_anywhere.id'][0]
@conf['twitter_anywhere.hovercards.selectors'] = @cgi.params['twitter_anywhere.hovercards.selectors'][0]
@conf['twitter_anywhere.hovercards.expand_default'] = @cgi.params['twitter_anywhere.hovercards.expand_default'][0]
end
expand_true = ""
expand_false = "selected"
if @conf['twitter_anywhere.hovercards.expand_default'] == "true"
expand_true = "selected"
expand_false = ""
end
<<-HTML
Consumer key
Register your tDiary and get Consumer key.
Go Twitter OAuth settings.
Rending Hovercards
CSS Selector To limit the scope of where Hovercards appear
example) div.section p, div.commentshort p, div.commentbody p
Expanded by Default
true
false
HTML
end
def support_anywhere?
return !feed?
end
def ready_anywhere?
if @conf['twitter_anywhere.id'] && @conf['twitter_anywhere.id'].size > 0
return true
end
return false
end
def not_support_anywhere
'[Twitter@Anywhere] not support this environment.'
end
def not_ready_anywhere
anywhere_plugin_error(
"Twitter consumer Key not specified.",
%Q|Go Twitter OAuth settings. |)
end
def anywhere_plugin_error(message, detail= '')
<<-PLUGIN_ERROR
[ERROR] twitter_anywhere.rb: #{message}
#{detail}
PLUGIN_ERROR
end
if /\A(?:latest|day|month|nyear|preview)\z/ =~ @mode
twitter_anywhere_settings
end
# Local Variables:
# mode: ruby
# indent-tabs-mode: t
# tab-width: 3
# ruby-indent-level: 3
# End:
# vim: ts=3
tdiary-contrib-5.1.0/plugin/twitter_badge.rb 0000664 0000000 0000000 00000002110 13570131474 0021115 0 ustar 00root root 0000000 0000000 #
# twitter_badge.rb: insert 'Follow me' badge of Twitter.
#
# Copyright (C) 2010 TADA Tadashi
# You can redistribute it and/or modify it under GPL2.
#
def twitter_badge( account, opt = {} )
return '' unless account
@twitter_badge_setting = {
:account => account,
:label => (opt[:label] || 'follow-me'),
:color => (opt[:color] || '#35ccff'),
:side => (opt[:side] || 'right')[0,1],
:top => (opt[:top] || 136).to_i,
:delay => (opt[:delay] || 5).to_i * 1000,
}
'' # do nothing in this method.
end
add_footer_proc do
if @twitter_badge_setting then
t = @twitter_badge_setting
<<-TEXT
TEXT
else
''
end
end
tdiary-contrib-5.1.0/plugin/twitter_js.rb 0000664 0000000 0000000 00000003560 13570131474 0020501 0 ustar 00root root 0000000 0000000 # twitter_js.rb $Revision: 1.1 $
# Copyright (C) 2007 Michitaka Ohno
# You can redistribute it and/or modify it under GPL2.
if /\A(?:latest|day)\z/ =~ @mode then
if @conf['twitter.user'] then
twitter_user = @conf['twitter.user']
add_header_proc do
result = <<-HTML
HTML
result.gsub( /^\t\t/, '' )
end
add_body_leave_proc do |date|
result = <<-HTML
HTML
result.gsub( /^\t\t/, '' )
end
end
end
add_conf_proc( 'twitter_js', 'Twitter' ) do
if @mode == 'saveconf' then
@conf['twitter.user'] = @cgi.params['twitter.user'][0]
end
<<-HTML
Account Name
HTML
end
tdiary-contrib-5.1.0/plugin/twitter_summary_card.rb 0000664 0000000 0000000 00000005043 13570131474 0022551 0 ustar 00root root 0000000 0000000 # Twitter Summary Card plugin
#
#
# Copyright (c) 2013 Tatsuya Sato
def twitter_summary_card_description
section_index = @cgi.params['p'][0]
if @mode == 'day'
diary = @diaries[@date.strftime('%Y%m%d')]
sections = diary.instance_variable_get(:@sections)
section = nil
if section_index
section = sections[section_index.to_i - 1].body_to_html
else
section = sections.first.body_to_html
end
@conf.shorten(apply_plugin(section, true), 200)
else
@conf.description
end
end
add_header_proc do
card_type = 'summary'
image_src = @conf.banner
if @mode == 'day' && @conf['twitter_summary_card.use_attached_image']
images = image_list(@date.strftime('%Y%m%d'))
unless images.empty?
card_type = 'summary_large_image'
image_src = "#{@image_url}/#{images.first}"
end
end
headers = {
'twitter:card' => card_type,
'twitter:site' => @conf['twitter_summary_card.site'] || @conf['twitter_summary_card.creator'],
'twitter:creator' => @conf['twitter_summary_card.creator'],
'twitter:title' => title_tag.match(/>([^<]+)/).to_a[1],
'twitter:description' => twitter_summary_card_description,
'twitter:image:src' => image_src
}
headers = headers.select { |_, v| v && not(v.empty?) }
headers = headers.map do |k, v|
%Q| |
end
headers.join("\n")
end
add_conf_proc('Twitter Summary Card', 'Twitter Summary Card') do
if @mode == 'saveconf'
@conf['twitter_summary_card.site'] = @cgi.params['twitter_summary_card.site'][0]
@conf['twitter_summary_card.creator'] = @cgi.params['twitter_summary_card.creator'][0]
@conf['twitter_summary_card.use_attached_image'] = @cgi.params['twitter_summary_card.use_attached_image'][0] == "on"
end
<<-HTML
Twitter Summary Card
Please refer to the following documentation at first.
Your tDiary's Twitte account
Creator's Twitter account
Use attached image
HTML
end
tdiary-contrib-5.1.0/plugin/ustream.rb 0000664 0000000 0000000 00000001111 13570131474 0017751 0 ustar 00root root 0000000 0000000 #
# ustream.rb - insert some services of Ustream.tv
#
# Copyright (C) 2010, TADA Tadashi .
# You can redistribute it and/or modify it under GPL2.
#
def ustream( id, type = :recorded )
if type == :live then
return ''
end
# insert recorded video
if feed? then
return %Q|Link to Ustream ##{id} |
end
%Q||
end
tdiary-contrib-5.1.0/plugin/vimeo.rb 0000664 0000000 0000000 00000000722 13570131474 0017417 0 ustar 00root root 0000000 0000000 #
# vimeo.rb - insert some services of vimeo.com
#
# Copyright (C) 2011, Kiwamu Okabe .
# You can redistribute it and/or modify it under GPL2.
#
def vimeo( id )
if feed? then
return %Q|Link to vimeo ##{id}
|
end
%Q||
end
tdiary-contrib-5.1.0/plugin/volatile.rb 0000664 0000000 0000000 00000004647 13570131474 0020131 0 ustar 00root root 0000000 0000000 # hide old diaries
#
# options configurable through settings:
# @conf['volatile.limit'] : number of diaries to show
#
# Copyright (c) MATSUOKA Kohei
# Distributed under the GPL
#
module ::TDiary
# 複数の日記を一括して更新するためのクラス
class TDiaryBulkUpdate < TDiaryUpdate
def initialize( cgi, rhtm, conf )
super
date = Time::local( *cgi.params['date'][0].scan( /^(\d{4})(\d\d)$/ )[0] )
@io.transaction( date ) do |diaries|
yield(diaries)
# DIRTY_DIARYは@ioへ日記を更新することを伝えるフラグ
DIRTY_DIARY
end
end
end
end
# 古い日記を非表示にするプラグイン
class VolatileDiaryPlugin
def initialize(conf)
@conf = conf
@limit = conf['volatile.limit'] || 10
end
# all を true にすると全ての日記を対象とする
def update(years, all = false)
each_recent_diary(years) do |date, diary, count|
diary.show(count <= @limit)
all || count <= @limit
end
end
def each_recent_diary(years)
cgi = CGI.new
count = 1
break_flag = false
years.keys.sort.reverse_each do |year|
years[year].sort.reverse_each do |month|
cgi.params['date'] = ["#{year}#{month}"]
cgi.params['year'] = [year]
cgi.params['month'] = [month]
cgi.params['day'] = ["1"]
m = TDiaryBulkUpdate::new(cgi, '', @conf) {|diaries|
# diaries.class is Hash (date => diary)
diaries.sort.reverse_each do |date, diary|
unless yield(date, diary, count)
break_flag = true
break
end
count += 1
end
}
break if break_flag
end
break if break_flag
end
end
end
add_update_proc do
# 古い日記を非表示にする
plugin = VolatileDiaryPlugin.new(@conf)
plugin.update(@years)
end
add_conf_proc('volatile', "揮発性日記", 'update') do
if @mode == 'saveconf' then
@conf['volatile.limit'] = @cgi.params['volatile.limit'][0].to_i
p = VolatileDiaryPlugin.new(@conf)
p.update(@years, true)
end
r = <<-HTML
日記の更新時に古い日記を非表示にします。
公開する日記の件数
公開したい日記の件数を入力してください。
HTML
r
end
tdiary-contrib-5.1.0/plugin/vote.rb 0000664 0000000 0000000 00000005605 13570131474 0017262 0 ustar 00root root 0000000 0000000 # tdiary_vote.rb $Revision: 2 $
# Copyright (C) 2006 Michitaka Ohno
# You can redistribute it and/or modify it under GPL2.
#
# ref. http://elpeo.jp/diary/20060622.html#p01
#
# .tdiary-vote {
# float: left;
# background-color: aqua;
# }
require 'digest/md5'
require 'pstore'
@tdiary_vote_db = "#{@cache_path}/tdiary_vote"
@tdiary_vote_label = "投票"
@tdiary_vote_date = nil
def vote( *items )
return '' unless @tdiary_vote_date
h, voted = get_vote( @tdiary_vote_date, @cgi.cookies['tdiary_vote'][0] )
max = h.empty? ? 1 : h.values.max
r = %Q[]
items.sort{|a, b| h[b] <=> h[a]}.each do |item|
num = h[item]
r << %Q[]
r << %Q[#{CGI.escapeHTML( item )} ]
r << %Q[ #{num} ]
unless voted then
r << %Q[]
r << %Q[]
r << %Q[ ]
end
r << %Q[ ]
end
r << %Q[
]
end
def get_vote( date, uid )
h = Hash.new(0)
voted = false
file = "#{@tdiary_vote_db}/#{date.strftime( "%Y%m%d" )}.db"
if File.exist?( file ) then
PStore.new( file ).transaction do |db|
h.update( db['vote'] ) if db.root?( 'vote' )
voted = db['voter'].include?( uid ) if db.root?( 'voter' )
db.abort
end
end
[h, voted]
end
def add_vote( date, item, uid )
Dir::mkdir( @tdiary_vote_db ) unless File::directory?( @tdiary_vote_db )
file = "#{@tdiary_vote_db}/#{date.strftime( "%Y%m%d" )}.db"
PStore.new( file ).transaction do |db|
db['voter'] = Hash.new unless db.root?( 'voter' )
db.abort if db['voter'].include?( uid )
db['voter'][uid] = @cgi.remote_addr
db['vote'] = Hash.new(0) unless db.root?( 'vote' )
db['vote'][item] += 1
end
end
add_body_enter_proc do |date|
@tdiary_vote_date = date
''
end
add_body_leave_proc do |date|
@tdiary_vote_date = nil
''
end
unless bot? then
if @mode == 'comment' && @cgi.valid?( 'vote' ) && @cgi.cookies['tdiary_vote'][0] then
add_vote( @date, @cgi.params['vote'][0], @cgi.cookies['tdiary_vote'][0] )
end
add_footer_proc do
uid = @cgi.cookies['tdiary_vote'][0] || Digest::MD5.hexdigest( @cgi.remote_addr + Time.now.to_s + rand.to_s )
cookie_path = File::dirname( @cgi.script_name )
cookie_path += '/' if cookie_path !~ /\/$/
cookie = CGI::Cookie::new(
'name' => 'tdiary_vote',
'value' => uid,
'path' => cookie_path,
'expires' => Time.now.gmtime + 30*24*60*60
)
add_cookie( cookie )
''
end
end
tdiary-contrib-5.1.0/plugin/wikiloc.rb 0000664 0000000 0000000 00000001733 13570131474 0017744 0 ustar 00root root 0000000 0000000 #
# wikiloc.rb: plugin embedding trip map on wikiloc.
#
# Copyright (C) 2008 MUNEDA Takahiro
# You can redistribute it and/or modify it under GPL2.
#
# derived from everytrail.rb, Copyright (C) 2008 TADA Tadashi
#
# Parameters:
# @trip_id : your trip id
# @measures : on/off
# @maptype : M/S/H/T
# @size : [width,height]
#
# Please see the following address about the details:
# http://www.wikiloc.com/forum/posts/list/14.page
#
# ChangeLog:
# 20080706: Initial release
# 20080713: Change default parameters
#
def wikiloc( trip_id, measures = "off", maptype = "M", size = [500,400] )
size.collect! {|i| i.to_i }
size[0] = 500 if size[0] == 0
size[1] = 400 if size[1] == 0
%Q||
end
tdiary-contrib-5.1.0/plugin/windex.rb 0000664 0000000 0000000 00000032711 13570131474 0017601 0 ustar 00root root 0000000 0000000 #!/usr/bin/env ruby
# windex.rb $Revision: 1.2 $
#
# windex: 索引を生成する
# パラメタ:
# str: キーワード文字列
# readname: 読み仮名
#
# wikw: 索引からアンカーを生成する
# パラメタ:
# str: キーワード文字列
#
# このファイルをtDiaryのトップディレクトリにも配置し、CGIとして
# 実行することで索引ページを出力できます。
#
# CGI動作時の引数
# http://(日記URL)/windex.rb?kw=(キーワード文字列)
# とキーワードを指定してアクセスすることでそのキーワードに関係する日記の
# 日付一覧を出力できます。一つだけの場合にはその日付の日記への
# リダイレクトを出力します。
#
# tdiary.confによる設定
# @options['windex.generate_all'] = true
# 全ての日記から索引を生成します。これは時間がかかるので、索引の全生成を
# 行いたいときだけtrueに設定して更新を行うような使い方を想定しています。
#
# Copyright (c) 2003 Gony
# Distributed under the GPL
#
mode = ""
if $0 == __FILE__
mode = "CGI"
if FileTest.symlink?(__FILE__) == true
org_path = File.dirname(File.readlink(__FILE__))
else
org_path = File.dirname(__FILE__)
end
$:.unshift(org_path)
require "pstore"
require "tdiary"
tdiarybase = TDiary::TDiaryBase
else
tdiarybase = TDiaryBase
end
class WITDiary < tdiarybase
def load_plugins
super
end
def generate_wordindex(date,plugin,index)
wordindex = WIWordIndex.new
@io.transaction(date) do |diaries|
wordindex.generate(diaries,plugin,index)
end
return wordindex
end
end
class WIWordIndex
def initialize
@windex = {}
@dates = []
end
def generate(diaries,plugin,index)
diaries.each_value do |diary|
num_section = 1
diary.each_section do |section|
anchor = index \
+ plugin.anchor(diary.date.strftime("%Y%m%d")) \
+ "#p%02d" % num_section
if section.subtitle != nil
scan(section.subtitle,anchor)
end
scan(section.body,anchor)
num_section = num_section + 1
end
end
end
def load(dir)
@windex = {}
Dir.mkdir(dir) unless File.directory?(dir)
PStore.new(dir + "/windex").transaction do |pstore|
@dates = pstore.roots
@dates.each do |key|
windex_tmp = pstore[key]
windex_tmp.each_key do |key_windex|
if @windex.has_key?(key_windex) == false
@windex[key_windex] = {"readname" => nil,
"anchor" => []}
end
if @windex[key_windex]["readname"] == nil \
&& windex_tmp[key_windex].has_key?("readname") == true
@windex[key_windex]["readname"] = windex_tmp[key_windex]["readname"]
end
@windex[key_windex]["anchor"].concat(windex_tmp[key_windex]["anchor"])
end
end
end
end
def save(dir,keyname)
if File.directory?(dir) == false
Dir.mkdir(dir,0755)
end
PStore.new(dir + "/windex").transaction do |pstore|
pstore[keyname] = @windex
end
end
def generate_html(page)
return page.generate_html(@windex)
end
def has_key?(key)
return @windex.has_key?(key)
end
def [](key)
return @windex[key]
end
private
def scan(body,anchor)
to_delimiter_end = {
"(" => ")","[" => "]","{" => "}","<" => ">",
}
wistrs = body.scan(%r[<%\s*=\s*windex\s*[^(<%)]*\s*%>])
wistrs.each do |wistr|
# 引数抽出
argstr = wistr.gsub(%r[<%\s*=\s*windex\s*],"")
argstr = argstr.gsub(%r[\s*%>],"")
args = []
flag_done = false
while flag_done == false
pos_delimiter = argstr.index(%r['|"|%[Qq].]) #"'
if pos_delimiter != nil
# デリミタ文字取得
delimiter = argstr.scan(%r['|"|%[Qq].])[0] #"'
if delimiter.length == 3
delimiter_end = delimiter[2].chr
if to_delimiter_end.has_key?(delimiter_end)
delimiter_end = to_delimiter_end[delimiter_end]
end
else
delimiter_end = delimiter
end
# デリミタまでの文字列を削除
argstr = argstr[(pos_delimiter + delimiter.length)..-1]
pos_delimiter = argstr.index(delimiter_end)
if pos_delimiter != nil
if pos_delimiter > 0
# 引数として取得
args << argstr[0..(pos_delimiter - 1)]
else
args << ""
end
# デリミタまでの文字列を削除
argstr = argstr[(pos_delimiter + delimiter_end.length)..-1]
else
flag_done = true
end
else
flag_done = true
end
end
if args.length > 0
if @windex.has_key?(args[0]) == false
# ハッシュを生成
@windex[args[0]] = {"readname" => nil,"anchor" => []}
end
if args.length > 1 && @windex[args[0]]["readname"] == nil && args[1] != ""
@windex[args[0]]["readname"] = args[1]
end
@windex[args[0]]["anchor"] << anchor
end
end
end
end
class WIIndexPage
def initialize(title,css)
@title = title
@css = css
end
def generate_html(windex)
body = ""
# 大項目名 => 名前の配列 のハッシュを生成
subindex_to_name = {}
windex.keys.each do |key|
subindex = ""
if windex[key]["readname"] != nil
subindex = get_subindex(windex[key]["readname"])
else
subindex = get_subindex(key)
end
if subindex_to_name.has_key?(subindex) == false
subindex_to_name[subindex] = []
end
subindex_to_name[subindex] << key
end
# 大項目名ごとにHTMLを生成
if subindex_to_name.has_key?("記号") == true
body << generate_html_subindex(windex,subindex_to_name,"記号")
end
subindex_to_name.keys.sort.each do |key|
if key != "記号"
body << generate_html_subindex(windex,subindex_to_name,key)
end
end
body = <<-BODY
#{h @title}(索引)
#{@css}
#{@title} [索引]
BODY
return body
end
private
def generate_html_subindex(windex,subindex_to_name,key)
readname_to_name = {}
subindex_to_name[key].each do |name|
key_new = ""
if windex[name]["readname"] != nil
key_new = windex[name]["readname"]
else
key_new = name
end
if readname_to_name.has_key?(key_new) == false
readname_to_name[key_new] = []
end
readname_to_name[key_new] << name
end
body = %Q[#{key} \n]
# 読み仮名のソートでループ -> 名前のソートでループ
keys = readname_to_name.keys
if keys.empty? == false
keys.sort.each do |readname|
readname_to_name[readname].sort.each do |name|
body << "
#{name} ... "
num_anchor = 1
windex[name]["anchor"].sort.each do |anchor|
body = body + %Q[#{num_anchor} ]
if num_anchor < windex[name]["anchor"].length
body = body + ","
end
num_anchor = num_anchor + 1
end
body << "
"
end
end
end
body << "\n
\n"
return body
end
def get_subindex(name)
to_plainhiragana = {
"ぁ" => "あ","ぃ" => "い","ぅ" => "う","ぇ" => "え","ぉ" => "お",
"が" => "か","ぎ" => "き","ぐ" => "く","げ" => "け","ご" => "こ",
"ざ" => "さ","じ" => "し","ず" => "す","ぜ" => "せ","ぞ" => "そ",
"だ" => "た","ぢ" => "ち","っ" => "つ","づ" => "つ","で" => "て","ど" => "と",
"ば" => "は","ぱ" => "は","び" => "ひ","ぴ" => "ひ","ぶ" => "ふ","ぷ" => "ふ","べ" => "へ","ぺ" => "へ","ぼ" => "ほ","ぽ" => "ほ",
"ゃ" => "や","ゅ" => "ゆ","ょ" => "よ",
"ゎ" => "わ","ヴ" => "う","ヵ" => "か","ヶ" => "け",
}
to_1byte = {
"!" => "!",'”' => '"',"#" => "#","$" => "$","%" => "%","&" => "&","’" => "'","(" => "(",")" => ")","*" => "*","+" => "+","," => ",","−" => "-","." => ".","/" => "/",
"0" => "0","1" => "1","2" => "2","3" => "3","4" => "4","5" => "5","6" => "6","7" => "7","8" => "8","9" => "9",":" => ":",";" => ";","<" => "<","=" => "=",">" => ">","?" => "?",
"@" => "@","A" => "A","B" => "B","C" => "C","D" => "D","E" => "E","F" => "F","G" => "G","H" => "H","I" => "I","J" => "J","K" => "K","L" => "L","M" => "M","N" => "N","O" => "O",
"P" => "P","Q" => "Q","R" => "R","S" => "S","T" => "T","U" => "U","V" => "V","W" => "W","X" => "X","Y" => "Y","Z" => "Z","[" => "[","¥" => "\\","]" => "]","^" => "^","_" => "_",
"a" => "a","b" => "b","c" => "c","d" => "d","e" => "e","f" => "f","g" => "g","h" => "h","i" => "i","j" => "j","k" => "k","l" => "l","m" => "m","n" => "n","o" => "o",
"p" => "p","q" => "q","r" => "r","s" => "s","t" => "t","u" => "u","v" => "v","w" => "w","x" => "x","y" => "y","z" => "z","{" => "{","|" => "|","}" => "}","‾" => "~",
}
topchr = name[0,1]
if topchr.count("\xA1-\xFE") == 1
# マルチバイト文字
topchr = name[0,2]
end
if to_1byte.has_key?(topchr) == true
topchr = to_1byte[topchr]
end
if topchr.length == 1
# シングルバイト文字の処理
topchr = topchr.upcase
if (0x21 <= topchr[0] && topchr[0] <= 0x2F) \
|| (0x3A <= topchr[0] && topchr[0] <= 0x40) \
|| (0x5B <= topchr[0] && topchr[0] <= 0x60) \
|| (0x7B <= topchr[0] && topchr[0] <= 0x7B)
topchr = "記号"
end
else
# マルチバイト文字の処理
# カタカナ->ひらがな変換
code = topchr[0] * 0x100 + topchr[1]
if 0xA5A1 <= code && code <= 0xA5F3
topchr = 0xA4.chr + topchr[1].chr
end
# 濁点 / 半濁点 撥音など変換
if to_plainhiragana.has_key?(topchr) == true
topchr = to_plainhiragana[topchr]
end
end
return topchr
end
end
class WIRedirectPage
def initialize(key)
@key = key
end
def generate_html(windex)
anchor = windex[@key]["anchor"][0]
body = <<-BODY
moving...
Wait or Click here!
BODY
return body
end
end
class WISinglePage
def initialize(title,date_format,css,key)
@title = title
@date_format = date_format
@css = css
@key = key
end
def generate_html(windex)
anchors = windex[@key]["anchor"]
body = %Q[#{@key} \n]
anchors.sort.each do |anchor|
str_date = anchor.scan(/\d{8}/)[0]
date = Time.local(str_date[0..3].to_i,str_date[4..5].to_i,str_date[6..7].to_i)
body << %Q[
#{date.strftime(@date_format)}
\n]
end
body << "\n
\n"
body = <<-BODY
#{h @title}(索引)
#{@css}
#{@title} [索引]
BODY
return body
end
end
class WIErrorPage
def initialize(title,css,key)
@title = title
@css = css
@key = key
end
def generate_html(windex)
body = <<-BODY
#{h @title}(索引)
#{@css}
#{@title} [索引]
キーワード「#{h @key}」は登録されていません。
BODY
return body
end
end
def windex(str,readname = "")
return str
end
def wikw(str)
if @wordindex.has_key?(str) == true
anchors = @wordindex[str]["anchor"]
if anchors.length == 1
return %Q[#{str} ]
else
body = "#{str}("
num_anchor = 1
anchors.sort.each do |anchor|
body << %Q[#{num_anchor} ]
if num_anchor < anchors.length
body << ","
end
num_anchor = num_anchor + 1
end
body << ")"
return body
end
end
return str
end
if mode != "CGI"
@wordindex = WIWordIndex.new
@wordindex.load(@cache_path + "/windex")
add_update_proc do
if @conf.options["windex.generate_all"] == true
tdiary = WITDiary.new(@cgi,"day.rhtml",@conf)
@years.each_key do |year|
@years[year.to_s].each do |month|
date = Time::local(year,month)
wordindex = tdiary.generate_wordindex(date,self,@conf.index)
wordindex.save(@cache_path + "/windex",date.strftime('%Y%m'))
end
end
else
wordindex = WIWordIndex.new
wordindex.generate(@diaries,self,@conf.index)
wordindex.save(@cache_path + "/windex",@date.strftime('%Y%m'))
end
end
else
cgi = CGI.new
conf = TDiary::Config.new(cgi)
cache_path = conf.data_path + "cache"
plugin = WITDiary.new(cgi,"day.rhtml",conf).load_plugins
wordindex = WIWordIndex.new
wordindex.load(cache_path + "/windex")
if cgi.valid?('kw') == true
key = cgi.params['kw'][0]
if wordindex.has_key?(key) == true
num_anchor = wordindex[key]["anchor"].length
if num_anchor == 0
page = WIErrorPage.new(conf.html_title,plugin.css_tag,key)
elsif num_anchor == 1
page = WIRedirectPage.new(key)
else
page = WISinglePage.new(conf.html_title,conf.date_format,plugin.css_tag,key)
end
else
page = WIErrorPage.new(conf.html_title,plugin.css_tag,key)
end
else
page = WIIndexPage.new(conf.html_title,plugin.css_tag)
end
body = wordindex.generate_html(page)
header = {
"type" => "text/html",
"charset" => "UTF-8",
"Content-Length" => body.size.to_s,
"Pragma" => "no-cache",
"Cache-Control" => "no-cache",
"Vary" => "User-Agent",
}
head = cgi.header(header)
print head
print body
end
tdiary-contrib-5.1.0/plugin/yahoo_kousei.rb 0000664 0000000 0000000 00000005434 13570131474 0021003 0 ustar 00root root 0000000 0000000 #
# yahoo_kousei.rb -
# Yahoo!JAPANデベロッパーネットワークの校正支援APIを利用して、
# 日本語文の校正作業を支援します。文字の入力ミスや言葉の誤用がないか、
# わかりにくい表記や不適切な表現が使われていないかなどをチェックします。
#
# Copyright (c) 2010, hb
# You can redistribute it and/or modify it under GPL.
#
# 設定:
#
# @options['yahoo_kousei.appid'] : アプリケーションID(必須)
# @options['yahoo_kousei.filter_group'] :
# 指摘グループの番号をコンマで区切って指定します。
# @options['yahoo_kousei.no_filter'] :
# filter_groupで指定した指摘グループから除外する指摘を指定します。
#
# 設定値は http://developer.yahoo.co.jp/webapi/jlp/kousei/v1/kousei.html を参照
#
require 'timeout'
require 'rexml/document'
require 'net/http'
Net::HTTP.version_1_2
def kousei_api( sentence )
appid = @conf['yahoo_kousei.appid']
query = "appid=#{appid}&sentence=#{URI.encode( sentence.gsub( /\n/, '' ) )}"
query << "&filter_group=" + @conf['yahoo_kousei.filter_group'] if @conf['yahoo_kousei.filter_group']
query << "&no_filter=" + @conf['yahoo_kousei.no_filter'] if @conf['yahoo_kousei.no_filter']
px_host, px_port = (@conf['proxy'] || '').split( /:/ )
px_port = 80 if px_host and !px_port
xml = ''
Net::HTTP::Proxy( px_host, px_port ).start( 'jlp.yahooapis.jp' ) do |http|
xml = http.post( '/KouseiService/V1/kousei', query ).body
end
xml
end
def kousei_result( result_set )
html = <<-HTML
文章校正結果
HTML
doc = REXML::Document::new( result_set )
results = REXML::XPath.match( doc, "//Result" )
if results.empty?
html << "指摘項目は見つかりませんでした。
"
else
html << ''
html << '対象表記 候補文字 詳細情報 場所 '
doc.elements.each( '//ResultSet/Result' ) do |r|
html << %Q|#{r.elements['Surface'].text} #{r.elements['ShitekiWord'].text} #{r.elements['ShitekiInfo'].text} #{r.elements['StartPos'].text},#{r.elements['Length'].text} |
end
html << '
'
end
html
end
add_edit_proc do
if @mode == 'preview' && @conf['yahoo_kousei.appid'] then
xml = kousei_api( @cgi.params['body'][0] )
<<-HTML
HTML
end
end
if /\A(form|edit|preview|showcomment)\z/ === @mode then
enable_js( 'yahoo_kousei.js' )
end
tdiary-contrib-5.1.0/plugin/yahoo_map.rb 0000664 0000000 0000000 00000006710 13570131474 0020257 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
#
# yahoo_map.rb - embeded Yahoo! JAPAN Map for tDiary
#
# Copyright (C) 2010, KAYA Satoshi
# You can redistribute it and/or modify it under GPL2.
#
add_header_proc do
init_ymap
r = ''
if @conf['yahoo_jp.appid'] and @conf['yahoo_jp.appid'].size > 0
r << %Q||
end
end
add_conf_proc( 'yahoo_jp_appid', 'Yahoo! JAPAN Application ID' ) do
if @mode == 'saveconf' then
@conf['yahoo_jp.appid'] = @cgi.params['yahoo_jp.appid'][0]
end
<<-HTML
Yahoo! JAPAN Application ID
Get Application id
HTML
end
add_footer_proc do |date|
insert_ymap_js
end
def init_ymap
@ymap_container = Array.new
end
def generate_ymapid(lat, lon, layer, size)
ymapid = 'ymapid' << lat.to_s << lon.to_s << layer.to_s << size
ymapid.delete('.')
end
def yahoo_map(lat, lon, options = {})
options[:layer] ||= 17
options[:size] ||= 'medium'
if feed?
return %Q|Link to Yahoo! JAPAN Map
|
end
# define map size
height = {'small'=> '240px', 'medium' => '360px', 'large' => '480px'}
width = {'small' => '320px', 'medium' => '480px', 'large' => '640px'}
size = options[:size]
ymapid = generate_ymapid(lat, lon, options[:layer], options[:size])
ymap_info = {:ymapid => ymapid, :lat => lat, :lon => lon, :layer => options[:layer]}
@ymap_container << ymap_info
%Q|
|
end
def insert_ymap_js
r = ''
if @ymap_container.size > 0 and not feed? then
r << %Q||
end
end
# Local Variables:
# mode: ruby
# indent-tabs-mode: t
# tab-width: 3
# ruby-indent-level: 3
# End:
# vim: ts=3
tdiary-contrib-5.1.0/plugin/yo_update.rb 0000664 0000000 0000000 00000015352 13570131474 0020276 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
#
# yo_update.rb - Yo all when an entry or a comment is posted
#
# Copyright (C) 2014, zunda
#
# Permission is granted for use, copying, modification,
# distribution, and distribution of modified versions of this
# work under the terms of GPL version 2 or later.
#
require 'uri'
require 'timeout'
require 'net/http'
require 'json'
YO_UPDATE_TIMEOUT = 10
class YoUpdateError < StandardError; end
def yo_update_url(date = nil, frag = nil) # date: Time frag: e.g. 'p01'
url = @conf.index.dup
url[0, 0] = base_url unless %r|^https?://|i =~ url
url.gsub!( %r|/\./|, '/' )
if date
ymd = date.strftime('%Y%m%d')
anc = frag ? "#{ymd}##{frag}" : ymd
url += anchor(anc)
end
url
end
def yo_update_api_key
r = @conf['yo_update.api_key']
if not r or r.empty?
return nil
end
return r
end
def yo_update_access_api(req)
if @conf['proxy']
proxy_uri = URI("http://" + @conf['proxy'])
proxy_addr = proxy_uri.host
proxy_port = proxy_uri.port
else
proxy_addr = nil
proxy_port = nil
end
begin
Timeout.timeout(YO_UPDATE_TIMEOUT) do
return Net::HTTP.start(req.uri.host, req.uri.port, proxy_addr, proxt_port){|http|
http.request(req)
}
end
rescue Timeout::Error
raise YoUpdateError, "Timeout accessing Yo API"
rescue SocketError => e
raise YoUpdateError, e.message
end
end
def yo_update_send_yo(username = nil, url = '')
api_key = yo_update_api_key
unless api_key
raise YoUpdateError, "Yo API Key is not set"
end
data = {'api_token' => api_key}
data['link'] = url unless url.empty?
unless username
req = Net::HTTP::Post.new(URI("http://api.justyo.co/yoall/"))
req.set_form_data(data)
expected = '{}'
else
req = Net::HTTP::Post.new(URI("http://api.justyo.co/yo/"))
data['username'] = username
req.set_form_data(data)
expected = '{"result": "OK"}'
end
res = yo_update_access_api(req)
data = res.body
unless data == expected
raise YoUpdateError, "error from Yo API: #{data}"
end
return data
end
def yo_update_send_yo_or_log(username = nil, url = '')
return unless yo_update_api_key
begin
yo_update_send_yo(username, url)
rescue YoUpdateError => e
@logger.error "yo_update.rb: #{e.message}"
end
end
def yo_update_subscribers_count
api_key = yo_update_api_key
unless api_key
raise YoUpdateError, "Yo API Key is not set"
end
req = Net::HTTP::Get.new(
URI("http://api.justyo.co/subscribers_count/?api_token=#{URI.escape(api_key)}")
)
res = yo_update_access_api(req)
data = res.body
begin
r = JSON::parse(data)
if r.has_key?('result')
return r['result']
else
raise YoUpdateError, "Error from Yo API: #{data}"
end
rescue JSON::ParserError
raise YoUpdateError, "Error from Yo API: #{data}"
end
end
unless defined? yo_update_conf_label # maybe defined in a language resource
def yo_update_conf_label
'Send Yo with updates'
end
end
unless defined? yo_update_test_result_label # maybe defined in a language resource
def yo_update_test_result_label(username, result)
"- Sent to #{h username} and got #{h result} "
end
end
unless defined? yo_update_conf_html # maybe defined in a language resource
def yo_update_conf_html(conf, n_subscribers, test_result)
action_label = {
'send_on_update' => 'when an entry is added',
'send_on_comment' => 'when a comment is posted',
}
<<-HTML
API key
Username
Send Yo
Test sending Yo! to with optional link #{test_result}
Current Subscribers
#{h n_subscribers}
Yo button
Add the following to somewhere or your diary.
<div id="yo-button"></div>
Howto
Sign in with your personal Yo account at http://dev.justyo.co/
Follow the instructions to obtain new API account.
Please leave the Callback URL blank.
Copy the API key and API username above.
HTML
end
end
add_conf_proc('yo_update', yo_update_conf_label) do
test_result = ''
if @mode == 'saveconf' then
@conf['yo_update.api_key'] = @cgi.params['yo_update.api_key'][0]
@conf['yo_update.username'] = @cgi.params['yo_update.username'][0]
@conf['yo_update.send_on_update'] = (@cgi.params['yo_update.send_on_update'][0] == 't')
@conf['yo_update.send_on_comment'] = (@cgi.params['yo_update.send_on_comment'][0] == 't')
test_username = @cgi.params['yo_update.test'][0]
test_link = @cgi.params['yo_update.link'][0]
if test_username and not test_username.empty?
begin
result = yo_update_send_yo(test_username, test_link)
rescue YoUpdateError => e
result = e.message
end
test_result = yo_update_test_result_label(test_username, result)
end
end
unless @conf.has_key?('yo_update.send_on_update')
@conf['yo_update.send_on_update'] = true
end
begin
n_subscribers = yo_update_subscribers_count
rescue YoUpdateError => e
n_subscribers = e.message
end
yo_update_conf_html(@conf, n_subscribers, test_result)
end
add_update_proc do
if @mode == 'append' and @conf['yo_update.send_on_update']
url = yo_update_url(@date) # link to the date
yo_update_send_yo_or_log(nil, url)
elsif @mode == 'comment' and @comment and @comment.visible? and @conf['yo_update.send_on_comment']
frag = "c%02d" % @diaries[@date.strftime("%Y%m%d")].count_comments(true)
url = yo_update_url(@date, frag)
yo_update_send_yo_or_log(nil, url)
end
end
add_header_proc do
if @conf['yo_update.api_key']
triggers = []
triggers << 'Entry' if @conf['yo_update.send_on_update']
triggers << 'Tsukkomi' if @conf['yo_update.send_on_comment']
trigger_str = "#{triggers.join(' or ')} is added"
<<-HTML
HTML
end
end
# Local Variables:
# mode: ruby
# indent-tabs-mode: t
# tab-width: 3
# ruby-indent-level: 3
# End:
# vim: ts=3 sw=3
tdiary-contrib-5.1.0/plugin/youtube.rb 0000664 0000000 0000000 00000001622 13570131474 0017774 0 ustar 00root root 0000000 0000000 #
# youtube.rb: YouTube plugin for tDiary
#
# Copyright (C) 2010 by TADA Tadashi
#
# usage: <%= youtube 'VIDEO_ID' %>
#
def youtube( video_id, size = [425,350] )
if feed?
%Q||
else
<<-TAG
TAG
end
end
def youtube_custom( video_id, size = [416,337] )
<<-TAG
TAG
end
tdiary-contrib-5.1.0/plugin/yshop.rb 0000664 0000000 0000000 00000014067 13570131474 0017451 0 ustar 00root root 0000000 0000000 # yshop.rb $Revision: 3 $
# Copyright (C) 2008 Michitaka Ohno
# You can redistribute it and/or modify it under GPL2.
# ja/yshop.rb
@yshop_label_conf ='Yahoo!ショッピング'
@yshop_label_appid = 'アプリケーションID'
@yshop_label_affiliate_type = 'アフィリエイトの種類'
@yshop_label_yid = 'Yahoo! JAPANアフィリエイト'
@yshop_label_vc = 'バリューコマースアフィリエイト'
@yshop_label_affiliate_id = 'アフィリエイトID'
@yshop_label_imgsize = '表示するイメージのサイズ'
@yshop_label_medium = '普通'
@yshop_label_small = '小さい'
@yshop_label_clearcache = 'キャッシュの削除'
@yshop_label_clearcache_desc = 'イメージ関連情報のキャッシュを削除する(Yahoo!ショッピング上の表示と矛盾がある場合に試して下さい)'
require 'rexml/document'
require 'open-uri'
require 'kconv'
eval( <<-TOPLEVEL_CLASS, TOPLEVEL_BINDING )
require 'erb'
include ERB::Util
TOPLEVEL_CLASS
def yshop_get( param, store )
if Hash === param then
param = param.dup
elsif /^(\d{8}|\d{13})$/ === param then
param = {:jan => $1}
else
param = {:query => param.to_s}
end
param[:store_id] = store if store
cache = "#{@cache_path}/yshop"
Dir::mkdir( cache ) unless File::directory?( cache )
file = "#{cache}/#{u( param.to_s )}.xml"
begin
xml = File::read( file )
rescue
qs = []
qs << 'appid='+u( @conf['yshop.appid']||'YahooDemo' )
qs << 'affiliate_type='+u( @conf['yshop.affiliate_type'] ) if @conf['yshop.affiliate_type']
qs << 'affiliate_id='+u( @conf['yshop.affiliate_id'] ) if @conf['yshop.affiliate_id']
[:query, :jan, :isbn, :store_id].each do |item|
qs << "#{item}="+u( param[item].toutf8 ) if param.include?( item )
end
qs << 'hits=1'
xml = open( 'http://shopping.yahooapis.jp/ShoppingWebService/V1/itemSearch?'+(qs*'&') ){|f| f.read}
open( file, 'wb' ) {|f| f.write( xml )} if xml
end
REXML::Document.new( xml ).root if xml
end
def yshop_get_image( doc )
img = Struct.new( :size, :src, :width, :height ).new
if @conf['yshop.imgsize'] == 1 then
img.size = 'Small'
img.width = img.height = 76
else
img.size = 'Medium'
img.width = img.height = 146
end
begin
img.src = doc.elements["Result/Hit/Image/#{img.size}"].text
rescue
img.src = "http://i.yimg.jp/images/sh/noimage/#{img.width}x#{img.height}.gif"
end
img
end
def yshop_get_brands( doc )
begin
@conf.to_native( doc.elements['Result/Hit/Brands/Name'].text )
rescue
'-'
end
end
def yshop_get_price( doc )
begin
r = doc.elements['Result/Hit/Price'].text
nil while r.gsub!(/(.*\d)(\d\d\d)/, '\1,\2')
"\\"+r
rescue
'(no price)'
end
end
def yshop_get_shop( doc )
begin
@conf.to_native( doc.elements['Result/Hit/Store/Name'].text )
rescue
'-'
end
end
def yshop_get_html( param, store, pos )
doc = yshop_get( param, store )
return unless doc && doc.attributes['totalResultsReturned'].to_i > 0
name = @conf.to_native( doc.elements["Result/Hit/Name"].text )
link = doc.elements["Result/Hit/Url"].text
img = yshop_get_image( doc )
r = %Q[]
r << %Q[ ] if img.src
r << h( name )
r << %Q[ ]
end
def yshop_image( param, store = nil )
yshop_get_html( param, store, 'amazon' )
end
def yshop_image_left( param, store = nil )
yshop_get_html( param, store, 'left' )
end
def yshop_image_right( param, store = nil )
yshop_get_html( param, store, 'right' )
end
def yshop_detail( param, store = nil )
doc = yshop_get( param, store )
return unless doc && doc.attributes['totalResultsReturned'].to_i > 0
name = @conf.to_native( doc.elements["Result/Hit/Name"].text )
link = doc.elements["Result/Hit/Url"].text
img = yshop_get_image( doc )
brands = yshop_get_brands( doc )
price = yshop_get_price( doc )
shop = yshop_get_shop( doc )
<<-HTML
#{h( name )}
#{h( brands )}
#{h( shop )}
#{h( price )}
HTML
end
add_conf_proc( 'yshop', @yshop_label_conf ) do
yshop_conf_proc
end
def yshop_conf_proc
if @mode == 'saveconf' then
@conf['yshop.imgsize'] = @cgi.params['yshop.imgsize'][0].to_i
if @cgi.params['yshop.clearcache'][0] == 'true' then
Dir["#{@cache_path}/yshop/*"].each do |cache|
File::delete( cache.untaint )
end
end
if @cgi.params['yshop.appid'][0].empty? then
@conf['yshop.appid'] = nil
else
@conf['yshop.appid'] = @cgi.params['yshop.appid'][0]
end
if @cgi.params['yshop.affiliate_id'][0].empty? then
@conf['yshop.affiliate_type'] = nil
@conf['yshop.affiliate_id'] = nil
else
@conf['yshop.affiliate_type'] = @cgi.params['yshop.affiliate_type'][0]
@conf['yshop.affiliate_id'] = @cgi.params['yshop.affiliate_id'][0]
end
end
<<-HTML
#{@yshop_label_appid}
#{@yshop_label_affiliate_type}
#{@yshop_label_yid}
#{@yshop_label_vc}
#{@yshop_label_affiliate_id}
#{@yshop_label_imgsize}
#{@yshop_label_medium}
#{@yshop_label_small}
#{@yshop_label_clearcache}
#{@yshop_label_clearcache_desc}
HTML
end
tdiary-contrib-5.1.0/plugin/zenback.rb 0000664 0000000 0000000 00000002042 13570131474 0017712 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
# Copyright (C) 2011, KADO Masanori
# You can redistribute it and/or modify it under GPL.
def insert_zenback
return if feed?
@conf['zenback.script'] || ''
end
if @mode == 'day' and (respond_to?(:section_mode?) ? section_mode? : true)
add_title_proc do |date, title|
"#{title}"
end
add_body_enter_proc do
""
end
if defined? add_comment_leave_proc
add_comment_leave_proc do
"" +
insert_zenback
end
else
add_body_leave_proc do
"" +
insert_zenback
end
end
end
add_conf_proc( 'zenback', 'zenback', 'etc' ) do
if @mode == 'saveconf' then
@conf['zenback.script'] = @cgi.params['zenback.script'][0]
end
<<-HTML
Script Code
HTML
end
# Local Variables:
# mode: ruby
# indent-tabs-mode: t
# tab-width: 3
# ruby-indent-level: 3
# End:
# vim: ts=3
tdiary-contrib-5.1.0/spec/ 0000775 0000000 0000000 00000000000 13570131474 0015406 5 ustar 00root root 0000000 0000000 tdiary-contrib-5.1.0/spec/apple_webclip_spec.rb 0000664 0000000 0000000 00000001757 13570131474 0021565 0 ustar 00root root 0000000 0000000 $:.unshift(File.dirname(__FILE__))
require 'spec_helper'
describe "apple_webclip plugin" do
def setup_apple_webclip_plugin( url )
fake_plugin(:apple_webclip) { |plugin|
plugin.conf['apple_webclip.url'] = url
}
end
describe "url is enabled" do
before do
plugin = setup_apple_webclip_plugin('http://example.com/example.png')
@header_snippet = plugin.header_proc
end
it "header include url" do
expect(@header_snippet).to eq(%Q|\t |)
end
end
describe "url is disabled" do
describe "url is empty" do
before do
plugin = setup_apple_webclip_plugin('')
@header_snippet = plugin.header_proc
end
it "header is empty" do
expect(@header_snippet).to be_empty
end
end
describe "url is nil" do
before do
plugin = setup_apple_webclip_plugin(nil)
@header_snippet = plugin.header_proc
end
it "header is empty" do
expect(@header_snippet).to be_empty
end
end
end
end
tdiary-contrib-5.1.0/spec/fixtures/ 0000775 0000000 0000000 00000000000 13570131474 0017257 5 ustar 00root root 0000000 0000000 tdiary-contrib-5.1.0/spec/fixtures/flickr/ 0000775 0000000 0000000 00000000000 13570131474 0020531 5 ustar 00root root 0000000 0000000 tdiary-contrib-5.1.0/spec/fixtures/flickr/5950109223.flickr.photos.getInfo.xml 0000664 0000000 0000000 00000002123 13570131474 0026512 0 ustar 00root root 0000000 0000000
RubyKaigi 2011
0
rubykaigi
https://www.flickr.com/photos/machu/5950109223/
tdiary-contrib-5.1.0/spec/fixtures/flickr/5950109223.flickr.photos.getSizes.xml 0000664 0000000 0000000 00000003607 13570131474 0026724 0 ustar 00root root 0000000 0000000
tdiary-contrib-5.1.0/spec/fixtures/github.json 0000664 0000000 0000000 00000000767 13570131474 0021446 0 ustar 00root root 0000000 0000000 {"type":"User","login":"schacon","public_repos":150,"public_gists":80,"followers":5328,"html_url":"https://github.com/schacon","created_at":"2008-01-27T17:19:28Z","blog":"http://scottchacon.com","company":"GitHub","email":"schacon@gmail.com","avatar_url":"https://avatars.githubusercontent.com/u/70?v=3","hireable":false,"following":19,"name":"Scott Chacon","bio":null,"id":70,"location":"San Francisco, CA","url":"https://api.github.com/users/schacon","gravatar_id":"9375a9529679f1b42b567a640d775e7d"}
tdiary-contrib-5.1.0/spec/fixtures/gravatar.json 0000664 0000000 0000000 00000001415 13570131474 0021762 0 ustar 00root root 0000000 0000000 {"entry":[{"id":"7329339","hash":"3b3be63a4c2a439b013787725dfce802","requestHash":"3b3be63a4c2a439b013787725dfce802","profileUrl":"http:\/\/gravatar.com\/tdiary","preferredUsername":"tdiary","thumbnailUrl":"http:\/\/2.gravatar.com\/avatar\/3b3be63a4c2a439b013787725dfce802","photos":[{"value":"http:\/\/2.gravatar.com\/avatar\/3b3be63a4c2a439b013787725dfce802","type":"thumbnail"},{"value":"http:\/\/2.gravatar.com\/userimage\/7329339\/3b3be63a4c2a439b013787725dfce802"}],"profileBackground":{"color":"#e78736"},"name":{"givenName":"diary","familyName":"t","formatted":"tDiary"},"displayName":"tDiary","aboutMe":"The tDiary system","currentLocation":"JAPAN","emails":[{"primary":"true","value":"iHaveAn@email.com"}],"urls":[{"value":"http:\/\/www.tdiary.org","title":"tDiary"}]}]}
tdiary-contrib-5.1.0/spec/fixtures/my_hotentry/ 0000775 0000000 0000000 00000000000 13570131474 0021640 5 ustar 00root root 0000000 0000000 tdiary-contrib-5.1.0/spec/fixtures/my_hotentry/entrylist-empty.xml 0000664 0000000 0000000 00000001673 13570131474 0025562 0 ustar 00root root 0000000 0000000
はてなブックマーク - 新着エントリー - empty-url.example.com
http://b.hatena.ne.jp/entrylist?sort=eid&threshold=3&url=http%3A%2F%2Fempty-url.example.com
empty-url.example.com の新着エントリー
tdiary-contrib-5.1.0/spec/fixtures/my_hotentry/entrylist.xml 0000664 0000000 0000000 00000301042 13570131474 0024417 0 ustar 00root root 0000000 0000000
はてなブックマーク - 新着エントリー - 『ブログなら「はてなダイアリー」 - 写真・画像・動...』
http://b.hatena.ne.jp/entrylist?sort=eid&threshold=3&url=http%3A%2F%2Fd.hatena.ne.jp%2F
『ブログなら「はてなダイアリー」 - 写真・画像・動...』 の新着エントリー
-
【踊ってみた?】マジLOVE2000%【涼宮あつき】 100万再生達成 - An Empty Box >> pikayan’s Diary
http://d.hatena.ne.jp/pikayan/20150103/p1
ニコニコ考察, ニコニコ紹介ニコニコ動画での現存するミリオン達成動画が合計2020作へ。削除込みで2182作。 【ニコニコ動画】【踊ってみた?】マジLOVE2000%【涼宮あつき】 31日13時1分頃、総合再生回数100万回突破。涼宮あつきさんによるブレイクダンス。“同一うp主さんで2作品ミリオン達成”270人目。同楽曲でのミリオン達成は、中毒になる動画(sm20526080)、Ver.クプラ(s...
<blockquote cite="http://d.hatena.ne.jp/pikayan/20150103/p1" title="【踊ってみた?】マジLOVE2000%【涼宮あつき】 100万再生達成 - An Empty Box >> pikayan’s Diary"><cite><img src="http://cdn-ak.favicon.st-hatena.com/?url=http%3A%2F%2Fd.hatena.ne.jp%2Fpikayan%2F" alt="" /> <a href="http://d.hatena.ne.jp/pikayan/20150103/p1">【踊ってみた?】マジLOVE2000%【涼宮あつき】 100万再生達成 - An Empty Box >> pikayan’s Diary</a></cite><p>ニコニコ考察, ニコニコ紹介ニコニコ動画での現存するミリオン達成動画が合計2020作へ。削除込みで2182作。 【ニコニコ動画】【踊ってみた?】マジLOVE2000%【涼宮あつき】 31日13時1分頃、総合再生回数100万回突破。涼宮あつきさんによるブレイクダンス。“同一うp主さんで2作品ミリオン達成”270人目。同楽曲でのミリオン達成は、中毒になる動画(sm20526080)、Ver.クプラ(s...</p><p><a href="http://b.hatena.ne.jp/entry/http://d.hatena.ne.jp/pikayan/20150103/p1"><img src="http://b.hatena.ne.jp/entry/image/http://d.hatena.ne.jp/pikayan/20150103/p1" alt="はてなブックマーク - 【踊ってみた?】マジLOVE2000%【涼宮あつき】 100万再生達成 - An Empty Box >> pikayan’s Diary" title="はてなブックマーク - 【踊ってみた?】マジLOVE2000%【涼宮あつき】 100万再生達成 - An Empty Box >> pikayan’s Diary" border="0" style="border: none" /></a> <a href="http://b.hatena.ne.jp/append?http://d.hatena.ne.jp/pikayan/20150103/p1"><img src="http://b.hatena.ne.jp/images/append.gif" border="0" alt="はてなブックマークに追加" title="はてなブックマークに追加" /></a></p></blockquote>
2015-01-04T16:19:05+09:00
アニメとゲーム
1
-
成田山へ - がりぼんさんどこ行くの?
http://d.hatena.ne.jp/garibon33/20150104/1420335640
10:40ども!読者のみなさんは、初詣とかって毎年行くところを決めてる?もしくは、何か所も行ったりする??がりぼんはさ、近くに大きな 成田山 というお寺があるの。もちろん近所の神社にも行くけど、成田さんにもわりと行くかな?今年は雪で階段が危ないからって、父さんとおっかさんは節分に行くって言ってたな。近くには国宝の 犬山城 もあって、近所の人だけじゃなく、わざわざ車で遠くから観光がてら来る人もいるみ...
<blockquote cite="http://d.hatena.ne.jp/garibon33/20150104/1420335640" title="成田山へ - がりぼんさんどこ行くの?"><cite><img src="http://cdn-ak.favicon.st-hatena.com/?url=http%3A%2F%2Fd.hatena.ne.jp%2Fgaribon33%2F" alt="" /> <a href="http://d.hatena.ne.jp/garibon33/20150104/1420335640">成田山へ - がりぼんさんどこ行くの?</a></cite><p><a href="http://d.hatena.ne.jp/garibon33/20150104/1420335640"><img src="http://cdn-ak.b.st-hatena.com/entryimage/238072375-1420355148.jpg" alt="成田山へ - がりぼんさんどこ行くの?" title="成田山へ - がりぼんさんどこ行くの?" class="entry-image" /></a></p><p>10:40ども!読者のみなさんは、初詣とかって毎年行くところを決めてる?もしくは、何か所も行ったりする??がりぼんはさ、近くに大きな 成田山 というお寺があるの。もちろん近所の神社にも行くけど、成田さんにもわりと行くかな?今年は雪で階段が危ないからって、父さんとおっかさんは節分に行くって言ってたな。近くには国宝の 犬山城 もあって、近所の人だけじゃなく、わざわざ車で遠くから観光がてら来る人もいるみ...</p><p><a href="http://b.hatena.ne.jp/entry/http://d.hatena.ne.jp/garibon33/20150104/1420335640"><img src="http://b.hatena.ne.jp/entry/image/http://d.hatena.ne.jp/garibon33/20150104/1420335640" alt="はてなブックマーク - 成田山へ - がりぼんさんどこ行くの?" title="はてなブックマーク - 成田山へ - がりぼんさんどこ行くの?" border="0" style="border: none" /></a> <a href="http://b.hatena.ne.jp/append?http://d.hatena.ne.jp/garibon33/20150104/1420335640"><img src="http://b.hatena.ne.jp/images/append.gif" border="0" alt="はてなブックマークに追加" title="はてなブックマークに追加" /></a></p></blockquote>
2015-01-04T16:05:17+09:00
暮らし
1
-
慰安婦問題、ピンチをチャンスに変えよう! - ジェンダーとメディア・ブログ
http://d.hatena.ne.jp/discour/20140922/p1
朝日新聞が8月5日「慰安婦問題を考える」特集で、過去の吉田清治証言に基づく記事を取消して以降のメディアの朝日新聞叩きは異常である。産経新聞は、ずっと慰安婦問題で論陣を張ってきているからまあそうだろうと思うが、これまで慰安婦問題にそう熱心でなかった新聞や週刊誌、月刊誌などあらゆるメディアが総出で朝日新聞の記事取消騒動に乗じて、朝日新聞が記事を取り消したゆえに、「慰安婦問題は捏造」だったという言説をま...
<blockquote cite="http://d.hatena.ne.jp/discour/20140922/p1" title="慰安婦問題、ピンチをチャンスに変えよう! - ジェンダーとメディア・ブログ"><cite><img src="http://cdn-ak.favicon.st-hatena.com/?url=http%3A%2F%2Fd.hatena.ne.jp%2Fdiscour%2F" alt="" /> <a href="http://d.hatena.ne.jp/discour/20140922/p1">慰安婦問題、ピンチをチャンスに変えよう! - ジェンダーとメディア・ブログ</a></cite><p>朝日新聞が8月5日「慰安婦問題を考える」特集で、過去の吉田清治証言に基づく記事を取消して以降のメディアの朝日新聞叩きは異常である。産経新聞は、ずっと慰安婦問題で論陣を張ってきているからまあそうだろうと思うが、これまで慰安婦問題にそう熱心でなかった新聞や週刊誌、月刊誌などあらゆるメディアが総出で朝日新聞の記事取消騒動に乗じて、朝日新聞が記事を取り消したゆえに、「慰安婦問題は捏造」だったという言説をま...</p><p><a href="http://b.hatena.ne.jp/entry/http://d.hatena.ne.jp/discour/20140922/p1"><img src="http://b.hatena.ne.jp/entry/image/http://d.hatena.ne.jp/discour/20140922/p1" alt="はてなブックマーク - 慰安婦問題、ピンチをチャンスに変えよう! - ジェンダーとメディア・ブログ" title="はてなブックマーク - 慰安婦問題、ピンチをチャンスに変えよう! - ジェンダーとメディア・ブログ" border="0" style="border: none" /></a> <a href="http://b.hatena.ne.jp/append?http://d.hatena.ne.jp/discour/20140922/p1"><img src="http://b.hatena.ne.jp/images/append.gif" border="0" alt="はてなブックマークに追加" title="はてなブックマークに追加" /></a></p></blockquote>
2015-01-04T15:57:56+09:00
世の中
1
-
サザンオールスターズ「東京VICTORY」雑感 - TAKUYAONLINE
http://d.hatena.ne.jp/takuya/20150104/1420352110
音楽サザンオールスターズの「東京VICTORY」っていう曲を最初に聴いたとき、すごく驚いて、いくらなんでも滅茶苦茶だろうって思った。時を駆けるよ Time goes round 変わりゆく My hometown 彗星(ほし)が流れるように 夢の未来へ Space goes round 友よ Forever young みんな頑張って それ行け Get the chance!!どこに驚いたかってい...
<blockquote cite="http://d.hatena.ne.jp/takuya/20150104/1420352110" title="サザンオールスターズ「東京VICTORY」雑感 - TAKUYAONLINE"><cite><img src="http://cdn-ak.favicon.st-hatena.com/?url=http%3A%2F%2Fd.hatena.ne.jp%2Ftakuya%2F" alt="" /> <a href="http://d.hatena.ne.jp/takuya/20150104/1420352110">サザンオールスターズ「東京VICTORY」雑感 - TAKUYAONLINE</a></cite><p>音楽サザンオールスターズの「東京VICTORY」っていう曲を最初に聴いたとき、すごく驚いて、いくらなんでも滅茶苦茶だろうって思った。時を駆けるよ Time goes round 変わりゆく My hometown 彗星(ほし)が流れるように 夢の未来へ Space goes round 友よ Forever young みんな頑張って それ行け Get the chance!!どこに驚いたかってい...</p><p><a href="http://b.hatena.ne.jp/entry/http://d.hatena.ne.jp/takuya/20150104/1420352110"><img src="http://b.hatena.ne.jp/entry/image/http://d.hatena.ne.jp/takuya/20150104/1420352110" alt="はてなブックマーク - サザンオールスターズ「東京VICTORY」雑感 - TAKUYAONLINE" title="はてなブックマーク - サザンオールスターズ「東京VICTORY」雑感 - TAKUYAONLINE" border="0" style="border: none" /></a> <a href="http://b.hatena.ne.jp/append?http://d.hatena.ne.jp/takuya/20150104/1420352110"><img src="http://b.hatena.ne.jp/images/append.gif" border="0" alt="はてなブックマークに追加" title="はてなブックマークに追加" /></a></p></blockquote>
2015-01-04T15:20:21+09:00
エンタメ
2
-
2014年の映画 124本 - OnFire
http://d.hatena.ne.jp/biwacovic/20150104/1420336076
(内訳)洋画新作 61洋画旧作 24邦画新作 18邦画旧作 21費用合計 134200円(平均1082.3円/1本)時間合計 13236分(平均106.7分/1本)幌馬車キートン・サイレント集フェイシズチャイニーズ・ブッキーを殺した男恋するミナミ危険な関係アイドル・イズ・デッド ノンちゃんのプロパガンダ大戦争ドラッグ・ウォー 毒戦・ふ・た・り・ぼ・っ・ち・ビフォア・ミッドナイトMUDポール・ヴァー...
<blockquote cite="http://d.hatena.ne.jp/biwacovic/20150104/1420336076" title="2014年の映画 124本 - OnFire"><cite><img src="http://cdn-ak.favicon.st-hatena.com/?url=http%3A%2F%2Fd.hatena.ne.jp%2Fbiwacovic%2F" alt="" /> <a href="http://d.hatena.ne.jp/biwacovic/20150104/1420336076">2014年の映画 124本 - OnFire</a></cite><p>(内訳)洋画新作 61洋画旧作 24邦画新作 18邦画旧作 21費用合計 134200円(平均1082.3円/1本)時間合計 13236分(平均106.7分/1本)幌馬車キートン・サイレント集フェイシズチャイニーズ・ブッキーを殺した男恋するミナミ危険な関係アイドル・イズ・デッド ノンちゃんのプロパガンダ大戦争ドラッグ・ウォー 毒戦・ふ・た・り・ぼ・っ・ち・ビフォア・ミッドナイトMUDポール・ヴァー...</p><p><a href="http://b.hatena.ne.jp/entry/http://d.hatena.ne.jp/biwacovic/20150104/1420336076"><img src="http://b.hatena.ne.jp/entry/image/http://d.hatena.ne.jp/biwacovic/20150104/1420336076" alt="はてなブックマーク - 2014年の映画 124本 - OnFire" title="はてなブックマーク - 2014年の映画 124本 - OnFire" border="0" style="border: none" /></a> <a href="http://b.hatena.ne.jp/append?http://d.hatena.ne.jp/biwacovic/20150104/1420336076"><img src="http://b.hatena.ne.jp/images/append.gif" border="0" alt="はてなブックマークに追加" title="はてなブックマークに追加" /></a></p></blockquote>
2015-01-04T15:17:56+09:00
エンタメ
1
-
篠田魔孤と久保田創二 - mmpoloの日記
http://d.hatena.ne.jp/mmpolo/20150104/1420334496
昨年が没後50年だった無名の画家篠田魔孤については以前ここで紹介したことがある。・伝説の画家・篠田魔孤を誰も知らない(2007年1月7日) 上に掲載したような優れた絵を描いていながら無名のまま亡くなった。作品は散逸し、もうほとんど魔孤さんのことも絵のことも知る人がいなくなった。そういう私も生前の魔孤さんに会ったことはないし、作品も図版でしか見たことがない。その魔孤さんが亡くなったのが1964年11...
<blockquote cite="http://d.hatena.ne.jp/mmpolo/20150104/1420334496" title="篠田魔孤と久保田創二 - mmpoloの日記"><cite><img src="http://cdn-ak.favicon.st-hatena.com/?url=http%3A%2F%2Fd.hatena.ne.jp%2Fmmpolo%2F" alt="" /> <a href="http://d.hatena.ne.jp/mmpolo/20150104/1420334496">篠田魔孤と久保田創二 - mmpoloの日記</a></cite><p><a href="http://d.hatena.ne.jp/mmpolo/20150104/1420334496"><img src="http://cdn-ak.b.st-hatena.com/entryimage/238068427-1420352225.jpg" alt="篠田魔孤と久保田創二 - mmpoloの日記" title="篠田魔孤と久保田創二 - mmpoloの日記" class="entry-image" /></a></p><p>昨年が没後50年だった無名の画家篠田魔孤については以前ここで紹介したことがある。・伝説の画家・篠田魔孤を誰も知らない(2007年1月7日) 上に掲載したような優れた絵を描いていながら無名のまま亡くなった。作品は散逸し、もうほとんど魔孤さんのことも絵のことも知る人がいなくなった。そういう私も生前の魔孤さんに会ったことはないし、作品も図版でしか見たことがない。その魔孤さんが亡くなったのが1964年11...</p><p><a href="http://b.hatena.ne.jp/entry/http://d.hatena.ne.jp/mmpolo/20150104/1420334496"><img src="http://b.hatena.ne.jp/entry/image/http://d.hatena.ne.jp/mmpolo/20150104/1420334496" alt="はてなブックマーク - 篠田魔孤と久保田創二 - mmpoloの日記" title="はてなブックマーク - 篠田魔孤と久保田創二 - mmpoloの日記" border="0" style="border: none" /></a> <a href="http://b.hatena.ne.jp/append?http://d.hatena.ne.jp/mmpolo/20150104/1420334496"><img src="http://b.hatena.ne.jp/images/append.gif" border="0" alt="はてなブックマークに追加" title="はてなブックマークに追加" /></a></p></blockquote>
2015-01-04T15:16:34+09:00
暮らし
1
-
ガンダムの神様現れる - 自閉症児 渡の宝箱
http://d.hatena.ne.jp/kuboyumi/20141228/1420026753
さて、今朝は前から子供達が楽しみにしていた東京スカイツリー。朝4時からおきて準備する子供達。我が家は朝が早いのです。朝からがっつり和食をいただきました。食べ放題って素敵。さて今日の目指すは東京スカイツリー。朝8時からだと待ち時間ゼロで登れました。東京の街を見て、楽しみました。これおかしいと思ったのは、全国のキティちゃん。なんで大阪が、たこ焼きで、松山が俳句なんだよ!大阪がたこ焼きだったら、松山はみ...
<blockquote cite="http://d.hatena.ne.jp/kuboyumi/20141228/1420026753" title="ガンダムの神様現れる - 自閉症児 渡の宝箱"><cite><img src="http://cdn-ak.favicon.st-hatena.com/?url=http%3A%2F%2Fd.hatena.ne.jp%2Fkuboyumi%2F" alt="" /> <a href="http://d.hatena.ne.jp/kuboyumi/20141228/1420026753">ガンダムの神様現れる - 自閉症児 渡の宝箱</a></cite><p><a href="http://d.hatena.ne.jp/kuboyumi/20141228/1420026753"><img src="http://cdn-ak.b.st-hatena.com/entryimage/238067863-1420351238.jpg" alt="ガンダムの神様現れる - 自閉症児 渡の宝箱" title="ガンダムの神様現れる - 自閉症児 渡の宝箱" class="entry-image" /></a></p><p>さて、今朝は前から子供達が楽しみにしていた東京スカイツリー。朝4時からおきて準備する子供達。我が家は朝が早いのです。朝からがっつり和食をいただきました。食べ放題って素敵。さて今日の目指すは東京スカイツリー。朝8時からだと待ち時間ゼロで登れました。東京の街を見て、楽しみました。これおかしいと思ったのは、全国のキティちゃん。なんで大阪が、たこ焼きで、松山が俳句なんだよ!大阪がたこ焼きだったら、松山はみ...</p><p><a href="http://b.hatena.ne.jp/entry/http://d.hatena.ne.jp/kuboyumi/20141228/1420026753"><img src="http://b.hatena.ne.jp/entry/image/http://d.hatena.ne.jp/kuboyumi/20141228/1420026753" alt="はてなブックマーク - ガンダムの神様現れる - 自閉症児 渡の宝箱" title="はてなブックマーク - ガンダムの神様現れる - 自閉症児 渡の宝箱" border="0" style="border: none" /></a> <a href="http://b.hatena.ne.jp/append?http://d.hatena.ne.jp/kuboyumi/20141228/1420026753"><img src="http://b.hatena.ne.jp/images/append.gif" border="0" alt="はてなブックマークに追加" title="はてなブックマークに追加" /></a></p></blockquote>
2015-01-04T15:00:07+09:00
暮らし
1
-
Myo がやっと届きました!! - 強火で進め
http://d.hatena.ne.jp/nakamura001/20141204/1417693695
Myo はこんな事や、こんな事ができます。Unity で作られた MyoとOculus Riftを使ったデモ - 強火で進めhttp://d.hatena.ne.jp/nakamura001/20140319/1395254765その Myo がやっと届きました。ちなみに注文した日付を確認した所、 2013/02/26 06:15 でした。最初は2013年の年末に届くって話だったんですけねorz1...
<blockquote cite="http://d.hatena.ne.jp/nakamura001/20141204/1417693695" title="Myo がやっと届きました!! - 強火で進め"><cite><img src="http://cdn-ak.favicon.st-hatena.com/?url=http%3A%2F%2Fd.hatena.ne.jp%2Fnakamura001%2F" alt="" /> <a href="http://d.hatena.ne.jp/nakamura001/20141204/1417693695">Myo がやっと届きました!! - 強火で進め</a></cite><p><a href="http://d.hatena.ne.jp/nakamura001/20141204/1417693695"><img src="http://cdn-ak.b.st-hatena.com/entryimage/238067851-1420351211.jpg" alt="Myo がやっと届きました!! - 強火で進め" title="Myo がやっと届きました!! - 強火で進め" class="entry-image" /></a></p><p>Myo はこんな事や、こんな事ができます。Unity で作られた MyoとOculus Riftを使ったデモ - 強火で進めhttp://d.hatena.ne.jp/nakamura001/20140319/1395254765その Myo がやっと届きました。ちなみに注文した日付を確認した所、 2013/02/26 06:15 でした。最初は2013年の年末に届くって話だったんですけねorz1...</p><p><a href="http://b.hatena.ne.jp/entry/http://d.hatena.ne.jp/nakamura001/20141204/1417693695"><img src="http://b.hatena.ne.jp/entry/image/http://d.hatena.ne.jp/nakamura001/20141204/1417693695" alt="はてなブックマーク - Myo がやっと届きました!! - 強火で進め" title="はてなブックマーク - Myo がやっと届きました!! - 強火で進め" border="0" style="border: none" /></a> <a href="http://b.hatena.ne.jp/append?http://d.hatena.ne.jp/nakamura001/20141204/1417693695"><img src="http://b.hatena.ne.jp/images/append.gif" border="0" alt="はてなブックマークに追加" title="はてなブックマークに追加" /></a></p></blockquote>
2015-01-04T14:59:48+09:00
テクノロジー
1
-
まんだらけが千葉県佐原にとんでもないビルを作っている模様w - 東洋黒客は勇者である
http://d.hatena.ne.jp/thk/20150103
年始年末はコミケの同人誌(中古)を漁りに秋葉原に繰り出している東洋黒客です、こんばんわ。年始年末は秋葉原の店舗も営業時間が不安定のため、各オタショップのサイトをチェックして営業時間を調べていたのですがまんだらけのページにとんでもない情報が載ってました。http://www.mandarake.co.jp/ え・・・なにこれ・・・ドン引き・・・。20世紀少年かよwww しかも、もうできあがりつつある...
<blockquote cite="http://d.hatena.ne.jp/thk/20150103" title="まんだらけが千葉県佐原にとんでもないビルを作っている模様w - 東洋黒客は勇者である"><cite><img src="http://cdn-ak.favicon.st-hatena.com/?url=http%3A%2F%2Fd.hatena.ne.jp%2Fthk%2F" alt="" /> <a href="http://d.hatena.ne.jp/thk/20150103">まんだらけが千葉県佐原にとんでもないビルを作っている模様w - 東洋黒客は勇者である</a></cite><p><a href="http://d.hatena.ne.jp/thk/20150103"><img src="http://cdn-ak.b.st-hatena.com/entryimage/238067748-1420350733.jpg" alt="まんだらけが千葉県佐原にとんでもないビルを作っている模様w - 東洋黒客は勇者である" title="まんだらけが千葉県佐原にとんでもないビルを作っている模様w - 東洋黒客は勇者である" class="entry-image" /></a></p><p>年始年末はコミケの同人誌(中古)を漁りに秋葉原に繰り出している東洋黒客です、こんばんわ。年始年末は秋葉原の店舗も営業時間が不安定のため、各オタショップのサイトをチェックして営業時間を調べていたのですがまんだらけのページにとんでもない情報が載ってました。http://www.mandarake.co.jp/ え・・・なにこれ・・・ドン引き・・・。20世紀少年かよwww しかも、もうできあがりつつある...</p><p><a href="http://b.hatena.ne.jp/entry/http://d.hatena.ne.jp/thk/20150103"><img src="http://b.hatena.ne.jp/entry/image/http://d.hatena.ne.jp/thk/20150103" alt="はてなブックマーク - まんだらけが千葉県佐原にとんでもないビルを作っている模様w - 東洋黒客は勇者である" title="はてなブックマーク - まんだらけが千葉県佐原にとんでもないビルを作っている模様w - 東洋黒客は勇者である" border="0" style="border: none" /></a> <a href="http://b.hatena.ne.jp/append?http://d.hatena.ne.jp/thk/20150103"><img src="http://b.hatena.ne.jp/images/append.gif" border="0" alt="はてなブックマークに追加" title="はてなブックマークに追加" /></a></p></blockquote>
2015-01-04T14:51:48+09:00
世の中
1
-
ストライクウィッチーズ Operation Victory Arrow vol.1 サン・トロンの雷鳴 [DVD] - はてなキーワード
http://d.hatena.ne.jp/asin/B00NNKBUF8
お得情報Amazonマーケットプレイス ¥ 3,446 よりKADOKAWA / 角川書店 - DVD - 2014/12/12 ¥ 3,676(定価 ¥ 4,968)26%OFF
<blockquote cite="http://d.hatena.ne.jp/asin/B00NNKBUF8" title="ストライクウィッチーズ Operation Victory Arrow vol.1 サン・トロンの雷鳴 [DVD] - はてなキーワード"><cite><img src="http://cdn-ak.favicon.st-hatena.com/?url=http%3A%2F%2Fd.hatena.ne.jp%2F" alt="" /> <a href="http://d.hatena.ne.jp/asin/B00NNKBUF8">ストライクウィッチーズ Operation Victory Arrow vol.1 サン・トロンの雷鳴 [DVD] - はてなキーワード</a></cite><p><a href="http://d.hatena.ne.jp/asin/B00NNKBUF8"><img onerror="Hatena.Bookmark.Video.rescueThumbnail(this);" src="http://ecx.images-amazon.com/images/I/41UFa79qZ8L._SL75_.jpg" alt="ストライクウィッチーズ Operation Victory Arrow vol.1 サン・トロンの雷鳴 [DVD]" title="ストライクウィッチーズ Operation Victory Arrow vol.1 サン・トロンの雷鳴 [DVD]" class="asin" /></a></p><p>お得情報Amazonマーケットプレイス ¥ 3,446 よりKADOKAWA / 角川書店 - DVD - 2014/12/12 ¥ 3,676(定価 ¥ 4,968)26%OFF</p><p><a href="http://b.hatena.ne.jp/entry/http://d.hatena.ne.jp/asin/B00NNKBUF8"><img src="http://b.hatena.ne.jp/entry/image/http://d.hatena.ne.jp/asin/B00NNKBUF8" alt="はてなブックマーク - ストライクウィッチーズ Operation Victory Arrow vol.1 サン・トロンの雷鳴 [DVD] - はてなキーワード" title="はてなブックマーク - ストライクウィッチーズ Operation Victory Arrow vol.1 サン・トロンの雷鳴 [DVD] - はてなキーワード" border="0" style="border: none" /></a> <a href="http://b.hatena.ne.jp/append?http://d.hatena.ne.jp/asin/B00NNKBUF8"><img src="http://b.hatena.ne.jp/images/append.gif" border="0" alt="はてなブックマークに追加" title="はてなブックマークに追加" /></a></p></blockquote>
2015-01-04T14:45:08+09:00
テクノロジー
1
-
撒き餌レンズの隠された機能大公開! - 亀猫のチャリカメ成長記!
http://d.hatena.ne.jp/kame-neko/20111123/p1
-カメラ-GXR+A12 50mmF2.5一万円出せばおつりがくる純正レンズ、それがEF50mmF1.8II。びっくりするほど安いが、画質は(絞れば)凄い。通称は「撒き餌」。安いからといって手を出すと満足してしまい、より高いレンズを買ってしまうキヤノンの商法である。さてそんなレンズの弱点だが、質感が値段相応だと言うことだ。もちろん映りに関係することではないのだが、その安っぽさが尋常ではない。特にM...
<blockquote cite="http://d.hatena.ne.jp/kame-neko/20111123/p1" title="撒き餌レンズの隠された機能大公開! - 亀猫のチャリカメ成長記!"><cite><img src="http://cdn-ak.favicon.st-hatena.com/?url=http%3A%2F%2Fd.hatena.ne.jp%2Fkame-neko%2F" alt="" /> <a href="http://d.hatena.ne.jp/kame-neko/20111123/p1">撒き餌レンズの隠された機能大公開! - 亀猫のチャリカメ成長記!</a></cite><p><a href="http://d.hatena.ne.jp/kame-neko/20111123/p1"><img src="http://cdn-ak.b.st-hatena.com/entryimage/238067566-1420349858.jpg" alt="撒き餌レンズの隠された機能大公開! - 亀猫のチャリカメ成長記!" title="撒き餌レンズの隠された機能大公開! - 亀猫のチャリカメ成長記!" class="entry-image" /></a></p><p>-カメラ-GXR+A12 50mmF2.5一万円出せばおつりがくる純正レンズ、それがEF50mmF1.8II。びっくりするほど安いが、画質は(絞れば)凄い。通称は「撒き餌」。安いからといって手を出すと満足してしまい、より高いレンズを買ってしまうキヤノンの商法である。さてそんなレンズの弱点だが、質感が値段相応だと言うことだ。もちろん映りに関係することではないのだが、その安っぽさが尋常ではない。特にM...</p><p><a href="http://b.hatena.ne.jp/entry/http://d.hatena.ne.jp/kame-neko/20111123/p1"><img src="http://b.hatena.ne.jp/entry/image/http://d.hatena.ne.jp/kame-neko/20111123/p1" alt="はてなブックマーク - 撒き餌レンズの隠された機能大公開! - 亀猫のチャリカメ成長記!" title="はてなブックマーク - 撒き餌レンズの隠された機能大公開! - 亀猫のチャリカメ成長記!" border="0" style="border: none" /></a> <a href="http://b.hatena.ne.jp/append?http://d.hatena.ne.jp/kame-neko/20111123/p1"><img src="http://b.hatena.ne.jp/images/append.gif" border="0" alt="はてなブックマークに追加" title="はてなブックマークに追加" /></a></p></blockquote>
2015-01-04T14:37:07+09:00
テクノロジー
1
-
フランソワーズ・アルディ - 不連続な読書日記
http://d.hatena.ne.jp/orion-n/20150103
今年の初買いは、篠綾子さんの『幻の神器』。定家が探偵役をつとめる平安京ミステリー、「藤原定家・謎合秘帖」シリーズの第一弾。胸が躍る。 その翌日、なんの脈絡もなくフランソワーズ・アルディの『私小説』と『夜のフランソワーズ』を購入した。 『私小説』は1973年の作品。二十歳をすぎた頃、毎日くりかえし聴きこんだ。『夜のフランソワーズ』はたぶん初聴だと思うが、とても懐かしい。 フランソワーズ・アルディが憧...
<blockquote cite="http://d.hatena.ne.jp/orion-n/20150103" title="フランソワーズ・アルディ - 不連続な読書日記"><cite><img src="http://cdn-ak.favicon.st-hatena.com/?url=http%3A%2F%2Fd.hatena.ne.jp%2Forion-n%2F" alt="" /> <a href="http://d.hatena.ne.jp/orion-n/20150103">フランソワーズ・アルディ - 不連続な読書日記</a></cite><p>今年の初買いは、篠綾子さんの『幻の神器』。定家が探偵役をつとめる平安京ミステリー、「藤原定家・謎合秘帖」シリーズの第一弾。胸が躍る。 その翌日、なんの脈絡もなくフランソワーズ・アルディの『私小説』と『夜のフランソワーズ』を購入した。 『私小説』は1973年の作品。二十歳をすぎた頃、毎日くりかえし聴きこんだ。『夜のフランソワーズ』はたぶん初聴だと思うが、とても懐かしい。 フランソワーズ・アルディが憧...</p><p><a href="http://b.hatena.ne.jp/entry/http://d.hatena.ne.jp/orion-n/20150103"><img src="http://b.hatena.ne.jp/entry/image/http://d.hatena.ne.jp/orion-n/20150103" alt="はてなブックマーク - フランソワーズ・アルディ - 不連続な読書日記" title="はてなブックマーク - フランソワーズ・アルディ - 不連続な読書日記" border="0" style="border: none" /></a> <a href="http://b.hatena.ne.jp/append?http://d.hatena.ne.jp/orion-n/20150103"><img src="http://b.hatena.ne.jp/images/append.gif" border="0" alt="はてなブックマークに追加" title="はてなブックマークに追加" /></a></p></blockquote>
2015-01-04T14:10:19+09:00
エンタメ
1
-
2013-02-12 - 弁護士ラベンダー読書日記
http://d.hatena.ne.jp/la-law/20130212#p2
文体は好み。系統でいえば朝吹真理子だと思いました。そして中勘助(中勘助みたいというのが、私の最上の褒め言葉です)。文体が美しいのに、その美しい文体で表現する対象が美しいものばかりでなく人間の醜さもあるってところが、ますます中勘助っぽい(「銀の匙」じゃなくて「犬」や「でーぱだった」の路線の中勘助ね)。そして、文体が美しいのに、表現の対象は美しさそのものではなくて、美しいものが失われていくさま、失われ...
<blockquote cite="http://d.hatena.ne.jp/la-law/20130212#p2" title="2013-02-12 - 弁護士ラベンダー読書日記"><cite><img src="http://cdn-ak.favicon.st-hatena.com/?url=http%3A%2F%2Fd.hatena.ne.jp%2Fla-law%2F" alt="" /> <a href="http://d.hatena.ne.jp/la-law/20130212#p2">2013-02-12 - 弁護士ラベンダー読書日記</a></cite><p>文体は好み。系統でいえば朝吹真理子だと思いました。そして中勘助(中勘助みたいというのが、私の最上の褒め言葉です)。文体が美しいのに、その美しい文体で表現する対象が美しいものばかりでなく人間の醜さもあるってところが、ますます中勘助っぽい(「銀の匙」じゃなくて「犬」や「でーぱだった」の路線の中勘助ね)。そして、文体が美しいのに、表現の対象は美しさそのものではなくて、美しいものが失われていくさま、失われ...</p><p><a href="http://b.hatena.ne.jp/entry/http://d.hatena.ne.jp/la-law/20130212%23p2"><img src="http://b.hatena.ne.jp/entry/image/http://d.hatena.ne.jp/la-law/20130212%23p2" alt="はてなブックマーク - 2013-02-12 - 弁護士ラベンダー読書日記" title="はてなブックマーク - 2013-02-12 - 弁護士ラベンダー読書日記" border="0" style="border: none" /></a> <a href="http://b.hatena.ne.jp/append?http://d.hatena.ne.jp/la-law/20130212%23p2"><img src="http://b.hatena.ne.jp/images/append.gif" border="0" alt="はてなブックマークに追加" title="はてなブックマークに追加" /></a></p></blockquote>
2015-01-04T14:09:33+09:00
暮らし
1
-
筑波大学附属図書館貴重書コレクション - LABYRINTHUS IMAGINATIONIS
http://d.hatena.ne.jp/theseus/20141209/p1
国内でも、西洋の数学や哲学の貴重書が電子化されているものがありますが、筑波大学はなかなか充実していると思われたので紹介。筑波大学附属図書館から、次のところに入ります。貴重書コレクション(電子化リスト)下の方までスクロールすると、分野別に貴重書が分かれています。たとえば、ステヴィンの著作がありました。ほかにも、スホーテン版デカルト『幾何学』(1659)や、ヨハン・ベルヌーイ全集(1742)などがあり...
<blockquote cite="http://d.hatena.ne.jp/theseus/20141209/p1" title="筑波大学附属図書館貴重書コレクション - LABYRINTHUS IMAGINATIONIS"><cite><img src="http://cdn-ak.favicon.st-hatena.com/?url=http%3A%2F%2Fd.hatena.ne.jp%2Ftheseus%2F" alt="" /> <a href="http://d.hatena.ne.jp/theseus/20141209/p1">筑波大学附属図書館貴重書コレクション - LABYRINTHUS IMAGINATIONIS</a></cite><p>国内でも、西洋の数学や哲学の貴重書が電子化されているものがありますが、筑波大学はなかなか充実していると思われたので紹介。筑波大学附属図書館から、次のところに入ります。貴重書コレクション(電子化リスト)下の方までスクロールすると、分野別に貴重書が分かれています。たとえば、ステヴィンの著作がありました。ほかにも、スホーテン版デカルト『幾何学』(1659)や、ヨハン・ベルヌーイ全集(1742)などがあり...</p><p><a href="http://b.hatena.ne.jp/entry/http://d.hatena.ne.jp/theseus/20141209/p1"><img src="http://b.hatena.ne.jp/entry/image/http://d.hatena.ne.jp/theseus/20141209/p1" alt="はてなブックマーク - 筑波大学附属図書館貴重書コレクション - LABYRINTHUS IMAGINATIONIS" title="はてなブックマーク - 筑波大学附属図書館貴重書コレクション - LABYRINTHUS IMAGINATIONIS" border="0" style="border: none" /></a> <a href="http://b.hatena.ne.jp/append?http://d.hatena.ne.jp/theseus/20141209/p1"><img src="http://b.hatena.ne.jp/images/append.gif" border="0" alt="はてなブックマークに追加" title="はてなブックマークに追加" /></a></p></blockquote>
2015-01-04T14:07:49+09:00
学び
1
-
【読書感想】abさんご - 琥珀色の戯言
http://d.hatena.ne.jp/fujipon/20130218
abさんご作者: 黒田夏子出版社/メーカー: 文藝春秋発売日: 2013/01メディア: ハードカバー購入: 9人 クリック: 912回この商品を含むブログ (36件) を見るabさんご作者: 黒田夏子出版社/メーカー: 文藝春秋発売日: 2013/02/09メディア: Kindle版購入: 4人 クリック: 171回この商品を含むブログ (3件) を見る内容紹介史上最高齢・75歳で芥川賞を受賞し...
<blockquote cite="http://d.hatena.ne.jp/fujipon/20130218" title="【読書感想】abさんご - 琥珀色の戯言"><cite><img src="http://cdn-ak.favicon.st-hatena.com/?url=http%3A%2F%2Fd.hatena.ne.jp%2Ffujipon%2F" alt="" /> <a href="http://d.hatena.ne.jp/fujipon/20130218">【読書感想】abさんご - 琥珀色の戯言</a></cite><p>abさんご作者: 黒田夏子出版社/メーカー: 文藝春秋発売日: 2013/01メディア: ハードカバー購入: 9人 クリック: 912回この商品を含むブログ (36件) を見るabさんご作者: 黒田夏子出版社/メーカー: 文藝春秋発売日: 2013/02/09メディア: Kindle版購入: 4人 クリック: 171回この商品を含むブログ (3件) を見る内容紹介史上最高齢・75歳で芥川賞を受賞し...</p><p><a href="http://b.hatena.ne.jp/entry/http://d.hatena.ne.jp/fujipon/20130218"><img src="http://b.hatena.ne.jp/entry/image/http://d.hatena.ne.jp/fujipon/20130218" alt="はてなブックマーク - 【読書感想】abさんご - 琥珀色の戯言" title="はてなブックマーク - 【読書感想】abさんご - 琥珀色の戯言" border="0" style="border: none" /></a> <a href="http://b.hatena.ne.jp/append?http://d.hatena.ne.jp/fujipon/20130218"><img src="http://b.hatena.ne.jp/images/append.gif" border="0" alt="はてなブックマークに追加" title="はてなブックマークに追加" /></a></p></blockquote>
2015-01-04T14:05:15+09:00
暮らし
1
-
ふしぎなせかい「abさんご」 - 静寂(しじま)を待ちながら
http://d.hatena.ne.jp/CultureNight/20130327/1364459444
日記, art149回芥川賞受賞作品「abさんご」がえらい問題作だった。 abさんご作者: 黒田夏子出版社/メーカー: 文藝春秋発売日: 2013/01メディア: ハードカバー購入: 9人 クリック: 912回この商品を含むブログ (36件) を見る ミーハー魂全開で読み始めたが、こんなに読中と読後で印象が違う小説は過去にない。 特徴は何といっても独特の文体だ。 横書きだし、固有名詞がほとんどない...
<blockquote cite="http://d.hatena.ne.jp/CultureNight/20130327/1364459444" title="ふしぎなせかい「abさんご」 - 静寂(しじま)を待ちながら"><cite><img src="http://cdn-ak.favicon.st-hatena.com/?url=http%3A%2F%2Fd.hatena.ne.jp%2FCultureNight%2F" alt="" /> <a href="http://d.hatena.ne.jp/CultureNight/20130327/1364459444">ふしぎなせかい「abさんご」 - 静寂(しじま)を待ちながら</a></cite><p><a href="http://d.hatena.ne.jp/CultureNight/20130327/1364459444"><img src="http://cdn-ak.b.st-hatena.com/entryimage/238063648-1420347866.jpg" alt="ふしぎなせかい「abさんご」 - 静寂(しじま)を待ちながら" title="ふしぎなせかい「abさんご」 - 静寂(しじま)を待ちながら" class="entry-image" /></a></p><p>日記, art149回芥川賞受賞作品「abさんご」がえらい問題作だった。 abさんご作者: 黒田夏子出版社/メーカー: 文藝春秋発売日: 2013/01メディア: ハードカバー購入: 9人 クリック: 912回この商品を含むブログ (36件) を見る ミーハー魂全開で読み始めたが、こんなに読中と読後で印象が違う小説は過去にない。 特徴は何といっても独特の文体だ。 横書きだし、固有名詞がほとんどない...</p><p><a href="http://b.hatena.ne.jp/entry/http://d.hatena.ne.jp/CultureNight/20130327/1364459444"><img src="http://b.hatena.ne.jp/entry/image/http://d.hatena.ne.jp/CultureNight/20130327/1364459444" alt="はてなブックマーク - ふしぎなせかい「abさんご」 - 静寂(しじま)を待ちながら" title="はてなブックマーク - ふしぎなせかい「abさんご」 - 静寂(しじま)を待ちながら" border="0" style="border: none" /></a> <a href="http://b.hatena.ne.jp/append?http://d.hatena.ne.jp/CultureNight/20130327/1364459444"><img src="http://b.hatena.ne.jp/images/append.gif" border="0" alt="はてなブックマークに追加" title="はてなブックマークに追加" /></a></p></blockquote>
2015-01-04T14:04:17+09:00
暮らし
1
-
『a b さんご』 - firecats & dogs
http://d.hatena.ne.jp/firecat/20130407
abさんご作者: 黒田夏子出版社/メーカー: 文藝春秋発売日: 2013/01メディア: ハードカバー購入: 9人 クリック: 912回この商品を含むブログ (36件) を見る話題作を読んでみた。以下、感想。ひらがなの多用は読み違いを誘うところがあり、てにをはもちょっと変わっている。昨今はあまり用いられないのではと思われる言葉も使用されるし、造語ではないかと考えさせられる言葉もある。受身形が多用さ...
<blockquote cite="http://d.hatena.ne.jp/firecat/20130407" title="『a b さんご』 - firecats & dogs"><cite><img src="http://cdn-ak.favicon.st-hatena.com/?url=http%3A%2F%2Fd.hatena.ne.jp%2Ffirecat%2F" alt="" /> <a href="http://d.hatena.ne.jp/firecat/20130407">『a b さんご』 - firecats & dogs</a></cite><p>abさんご作者: 黒田夏子出版社/メーカー: 文藝春秋発売日: 2013/01メディア: ハードカバー購入: 9人 クリック: 912回この商品を含むブログ (36件) を見る話題作を読んでみた。以下、感想。ひらがなの多用は読み違いを誘うところがあり、てにをはもちょっと変わっている。昨今はあまり用いられないのではと思われる言葉も使用されるし、造語ではないかと考えさせられる言葉もある。受身形が多用さ...</p><p><a href="http://b.hatena.ne.jp/entry/http://d.hatena.ne.jp/firecat/20130407"><img src="http://b.hatena.ne.jp/entry/image/http://d.hatena.ne.jp/firecat/20130407" alt="はてなブックマーク - 『a b さんご』 - firecats & dogs" title="はてなブックマーク - 『a b さんご』 - firecats & dogs" border="0" style="border: none" /></a> <a href="http://b.hatena.ne.jp/append?http://d.hatena.ne.jp/firecat/20130407"><img src="http://b.hatena.ne.jp/images/append.gif" border="0" alt="はてなブックマークに追加" title="はてなブックマークに追加" /></a></p></blockquote>
2015-01-04T14:01:23+09:00
暮らし
1
-
『abさんご』──後半「楽屋」が見えてくるのが惜しい(笑) - 山下晴代の「積ん読亭日常」
http://d.hatena.ne.jp/palaceatene/20130529/1369761390
『abさんご』(黒田夏子著、2013年1月、文藝春秋刊) 私は本作を読んで、すぐは、「紫式部日記」のような日本語の清逸な世界を感じさせて、なかなかよいと思った。まず、導入部など、唐突なはじまりがよいし、a地点からb地点という、説明のない抽象性は、言葉そのものの手触りを感じさせて、さすが、蓮實重彦の選んだ作だと思った。まず、蓮實氏は、「日本語を私に教えてくれる作品、どきどきさせてくれるものを望む」と...
<blockquote cite="http://d.hatena.ne.jp/palaceatene/20130529/1369761390" title="『abさんご』──後半「楽屋」が見えてくるのが惜しい(笑) - 山下晴代の「積ん読亭日常」"><cite><img src="http://cdn-ak.favicon.st-hatena.com/?url=http%3A%2F%2Fd.hatena.ne.jp%2Fpalaceatene%2F" alt="" /> <a href="http://d.hatena.ne.jp/palaceatene/20130529/1369761390">『abさんご』──後半「楽屋」が見えてくるのが惜しい(笑) - 山下晴代の「積ん読亭日常」</a></cite><p><a href="http://d.hatena.ne.jp/palaceatene/20130529/1369761390"><img src="http://cdn-ak.b.st-hatena.com/entryimage/238063574-1420347487.jpg" alt="『abさんご』──後半「楽屋」が見えてくるのが惜しい(笑) - 山下晴代の「積ん読亭日常」" title="『abさんご』──後半「楽屋」が見えてくるのが惜しい(笑) - 山下晴代の「積ん読亭日常」" class="entry-image" /></a></p><p>『abさんご』(黒田夏子著、2013年1月、文藝春秋刊) 私は本作を読んで、すぐは、「紫式部日記」のような日本語の清逸な世界を感じさせて、なかなかよいと思った。まず、導入部など、唐突なはじまりがよいし、a地点からb地点という、説明のない抽象性は、言葉そのものの手触りを感じさせて、さすが、蓮實重彦の選んだ作だと思った。まず、蓮實氏は、「日本語を私に教えてくれる作品、どきどきさせてくれるものを望む」と...</p><p><a href="http://b.hatena.ne.jp/entry/http://d.hatena.ne.jp/palaceatene/20130529/1369761390"><img src="http://b.hatena.ne.jp/entry/image/http://d.hatena.ne.jp/palaceatene/20130529/1369761390" alt="はてなブックマーク - 『abさんご』──後半「楽屋」が見えてくるのが惜しい(笑) - 山下晴代の「積ん読亭日常」" title="はてなブックマーク - 『abさんご』──後半「楽屋」が見えてくるのが惜しい(笑) - 山下晴代の「積ん読亭日常」" border="0" style="border: none" /></a> <a href="http://b.hatena.ne.jp/append?http://d.hatena.ne.jp/palaceatene/20130529/1369761390"><img src="http://b.hatena.ne.jp/images/append.gif" border="0" alt="はてなブックマークに追加" title="はてなブックマークに追加" /></a></p></blockquote>
2015-01-04T13:57:52+09:00
エンタメ
1
-
「炊き出しに公園が使えないなら私有地を使えばいいじゃない」 - 法華狼の日記
http://d.hatena.ne.jp/hokke-ookami/20150103/1420344848
年末から年始にかけて渋谷区の公園が閉鎖され、ホームレスへの炊き出し活動がおこななくなったという報道があった。東京・渋谷区:宮下公園など3日まで閉鎖 ホームレス締め出し - 毎日新聞 それに対するid:kyoumoe氏のブログエントリを見ていて、よくわからなくなった。まず12月30日づけのエントリ。ホームレスを利用して政治的主張をしたがる人々 - 今日も得る物なしZそれはそれとして俺が疑問に思ってい...
<blockquote cite="http://d.hatena.ne.jp/hokke-ookami/20150103/1420344848" title="「炊き出しに公園が使えないなら私有地を使えばいいじゃない」 - 法華狼の日記"><cite><img src="http://cdn-ak.favicon.st-hatena.com/?url=http%3A%2F%2Fd.hatena.ne.jp%2Fhokke-ookami%2F" alt="" /> <a href="http://d.hatena.ne.jp/hokke-ookami/20150103/1420344848">「炊き出しに公園が使えないなら私有地を使えばいいじゃない」 - 法華狼の日記</a></cite><p>年末から年始にかけて渋谷区の公園が閉鎖され、ホームレスへの炊き出し活動がおこななくなったという報道があった。東京・渋谷区:宮下公園など3日まで閉鎖 ホームレス締め出し - 毎日新聞 それに対するid:kyoumoe氏のブログエントリを見ていて、よくわからなくなった。まず12月30日づけのエントリ。ホームレスを利用して政治的主張をしたがる人々 - 今日も得る物なしZそれはそれとして俺が疑問に思ってい...</p><p><a href="http://b.hatena.ne.jp/entry/http://d.hatena.ne.jp/hokke-ookami/20150103/1420344848"><img src="http://b.hatena.ne.jp/entry/image/http://d.hatena.ne.jp/hokke-ookami/20150103/1420344848" alt="はてなブックマーク - 「炊き出しに公園が使えないなら私有地を使えばいいじゃない」 - 法華狼の日記" title="はてなブックマーク - 「炊き出しに公園が使えないなら私有地を使えばいいじゃない」 - 法華狼の日記" border="0" style="border: none" /></a> <a href="http://b.hatena.ne.jp/append?http://d.hatena.ne.jp/hokke-ookami/20150103/1420344848"><img src="http://b.hatena.ne.jp/images/append.gif" border="0" alt="はてなブックマークに追加" title="はてなブックマークに追加" /></a></p></blockquote>
2015-01-04T13:50:12+09:00
世の中
2
-
[design] - I Get Around The Media 楠見清のメディア回游
http://d.hatena.ne.jp/donburaco/searchdiary?word=*%5Bdesign%5D
book, designこれからのデザインに必要なことは何だろうと考えていたら「共用品」という言葉に行き当たった。子どもも大人も高齢者も障害者も身体的な特性にかかわりなく、多くの人がともに利用しやすいもの。英語ではアクセシブル・デザイン(使いやすい設計)と呼ばれバリア・フリーやユニバーサル・デザインを包括する考え方として広まってきている。デザイン・プロダクトのアクセシビリティーについて考えるための...
<blockquote cite="http://d.hatena.ne.jp/donburaco/searchdiary?word=*%5Bdesign%5D" title="[design] - I Get Around The Media 楠見清のメディア回游"><cite><img src="http://cdn-ak.favicon.st-hatena.com/?url=http%3A%2F%2Fd.hatena.ne.jp%2Fdonburaco%2F" alt="" /> <a href="http://d.hatena.ne.jp/donburaco/searchdiary?word=*%5Bdesign%5D">[design] - I Get Around The Media 楠見清のメディア回游</a></cite><p><a href="http://d.hatena.ne.jp/donburaco/searchdiary?word=*%5Bdesign%5D"><img src="http://cdn-ak.b.st-hatena.com/entryimage/238063171-1420346942.jpg" alt="[design] - I Get Around The Media 楠見清のメディア回游" title="[design] - I Get Around The Media 楠見清のメディア回游" class="entry-image" /></a></p><p>book, designこれからのデザインに必要なことは何だろうと考えていたら「共用品」という言葉に行き当たった。子どもも大人も高齢者も障害者も身体的な特性にかかわりなく、多くの人がともに利用しやすいもの。英語ではアクセシブル・デザイン(使いやすい設計)と呼ばれバリア・フリーやユニバーサル・デザインを包括する考え方として広まってきている。デザイン・プロダクトのアクセシビリティーについて考えるための...</p><p><a href="http://b.hatena.ne.jp/entry/http://d.hatena.ne.jp/donburaco/searchdiary?word=*%5Bdesign%5D"><img src="http://b.hatena.ne.jp/entry/image/http://d.hatena.ne.jp/donburaco/searchdiary?word=*%5Bdesign%5D" alt="はてなブックマーク - [design] - I Get Around The Media 楠見清のメディア回游" title="はてなブックマーク - [design] - I Get Around The Media 楠見清のメディア回游" border="0" style="border: none" /></a> <a href="http://b.hatena.ne.jp/append?http://d.hatena.ne.jp/donburaco/searchdiary?word=*%5Bdesign%5D"><img src="http://b.hatena.ne.jp/images/append.gif" border="0" alt="はてなブックマークに追加" title="はてなブックマークに追加" /></a></p></blockquote>
2015-01-04T13:46:55+09:00
暮らし
1
-
プロジェクション・ネックレス - Campaign_Otaku
http://d.hatena.ne.jp/y_sequi/20150101/1420056207
Technology女性へのプレゼントとしてアクセサリーは定番だけど、近い将来、それは"モノ"ではなく"プロジェクション"になるかも知れない。panGeneratorが開発中の"Neclumi"は女性の首元にネックレスをプロジェクションするという趣向。現在は"picoprojector"でプロジェクションし、iPhone Appでネックレスの形状や動きを選択する形式。単なるプロジェクションなら人の...
<blockquote cite="http://d.hatena.ne.jp/y_sequi/20150101/1420056207" title="プロジェクション・ネックレス - Campaign_Otaku"><cite><img src="http://cdn-ak.favicon.st-hatena.com/?url=http%3A%2F%2Fd.hatena.ne.jp%2Fy_sequi%2F" alt="" /> <a href="http://d.hatena.ne.jp/y_sequi/20150101/1420056207">プロジェクション・ネックレス - Campaign_Otaku</a></cite><p><a href="http://d.hatena.ne.jp/y_sequi/20150101/1420056207"><img src="http://cdn-ak.b.st-hatena.com/entryimage/238062817-1420346253.jpg" alt="プロジェクション・ネックレス - Campaign_Otaku" title="プロジェクション・ネックレス - Campaign_Otaku" class="entry-image" /></a></p><p>Technology女性へのプレゼントとしてアクセサリーは定番だけど、近い将来、それは"モノ"ではなく"プロジェクション"になるかも知れない。panGeneratorが開発中の"Neclumi"は女性の首元にネックレスをプロジェクションするという趣向。現在は"picoprojector"でプロジェクションし、iPhone Appでネックレスの形状や動きを選択する形式。単なるプロジェクションなら人の...</p><p><a href="http://b.hatena.ne.jp/entry/http://d.hatena.ne.jp/y_sequi/20150101/1420056207"><img src="http://b.hatena.ne.jp/entry/image/http://d.hatena.ne.jp/y_sequi/20150101/1420056207" alt="はてなブックマーク - プロジェクション・ネックレス - Campaign_Otaku" title="はてなブックマーク - プロジェクション・ネックレス - Campaign_Otaku" border="0" style="border: none" /></a> <a href="http://b.hatena.ne.jp/append?http://d.hatena.ne.jp/y_sequi/20150101/1420056207"><img src="http://b.hatena.ne.jp/images/append.gif" border="0" alt="はてなブックマークに追加" title="はてなブックマークに追加" /></a></p></blockquote>
2015-01-04T13:37:13+09:00
学び
1
-
赤い星、青い星、暗い星 - カガクのじかん
http://d.hatena.ne.jp/inyoko/20150101/stars_red_blue_and_dark
【管理人より】私が勤務する塾の高3生向けの記事です。もちろん他の方にも理解していただけるように書きますが、ある程度は「物理」の知識が必要かもしれません。 受験生の皆さん、受験前の忙しい時期にアクセスありがとうございます。日頃からあまりしゃべるのが上手でなく、伝え切れていないことがあるように思っているので、このような記事を書こうと思いました。 最新の「コムタス通信*1」は見てくれましたか?センター...
<blockquote cite="http://d.hatena.ne.jp/inyoko/20150101/stars_red_blue_and_dark" title="赤い星、青い星、暗い星 - カガクのじかん"><cite><img src="http://cdn-ak.favicon.st-hatena.com/?url=http%3A%2F%2Fd.hatena.ne.jp%2Finyoko%2F" alt="" /> <a href="http://d.hatena.ne.jp/inyoko/20150101/stars_red_blue_and_dark">赤い星、青い星、暗い星 - カガクのじかん</a></cite><p><a href="http://d.hatena.ne.jp/inyoko/20150101/stars_red_blue_and_dark"><img src="http://cdn-ak.b.st-hatena.com/entryimage/238059242-1420345147.jpg" alt="赤い星、青い星、暗い星 - カガクのじかん" title="赤い星、青い星、暗い星 - カガクのじかん" class="entry-image" /></a></p><p>【管理人より】私が勤務する塾の高3生向けの記事です。もちろん他の方にも理解していただけるように書きますが、ある程度は「物理」の知識が必要かもしれません。 受験生の皆さん、受験前の忙しい時期にアクセスありがとうございます。日頃からあまりしゃべるのが上手でなく、伝え切れていないことがあるように思っているので、このような記事を書こうと思いました。 最新の「コムタス通信*1」は見てくれましたか?センター...</p><p><a href="http://b.hatena.ne.jp/entry/http://d.hatena.ne.jp/inyoko/20150101/stars_red_blue_and_dark"><img src="http://b.hatena.ne.jp/entry/image/http://d.hatena.ne.jp/inyoko/20150101/stars_red_blue_and_dark" alt="はてなブックマーク - 赤い星、青い星、暗い星 - カガクのじかん" title="はてなブックマーク - 赤い星、青い星、暗い星 - カガクのじかん" border="0" style="border: none" /></a> <a href="http://b.hatena.ne.jp/append?http://d.hatena.ne.jp/inyoko/20150101/stars_red_blue_and_dark"><img src="http://b.hatena.ne.jp/images/append.gif" border="0" alt="はてなブックマークに追加" title="はてなブックマークに追加" /></a></p></blockquote>
2015-01-04T13:18:42+09:00
学び
1
-
福岡空港に第2滑走路が増設される件について - ” Wer Y sagt, muss auch Z sagen. ”で行こう
http://d.hatena.ne.jp/kagura-may/20150104/p1
かつての啓徳空港@香港・九龍もかくやと言うくらい、住宅街の真ん中に鎮座する福岡空港。一時は海側に全く新規の空港を新設という話があったけど、結局、現滑走路とターミナルの間の空間に新滑走路を押し込むことに正式決定。ユーザーからすると使い勝手が変わらないんでありがたいけど、住民からすると、騒音も危険性も現状の2倍になるんだよな。少し複雑気分。 それはそれとして、今回の記事で気になったのは次の下り。 空...
<blockquote cite="http://d.hatena.ne.jp/kagura-may/20150104/p1" title="福岡空港に第2滑走路が増設される件について - ” Wer Y sagt, muss auch Z sagen. ”で行こう"><cite><img src="http://cdn-ak.favicon.st-hatena.com/?url=http%3A%2F%2Fd.hatena.ne.jp%2Fkagura-may%2F" alt="" /> <a href="http://d.hatena.ne.jp/kagura-may/20150104/p1">福岡空港に第2滑走路が増設される件について - ” Wer Y sagt, muss auch Z sagen. ”で行こう</a></cite><p><a href="http://d.hatena.ne.jp/kagura-may/20150104/p1"><img src="http://cdn-ak.b.st-hatena.com/entryimage/238059078-1420344573.jpg" alt="福岡空港に第2滑走路が増設される件について - ” Wer Y sagt, muss auch Z sagen. ”で行こう" title="福岡空港に第2滑走路が増設される件について - ” Wer Y sagt, muss auch Z sagen. ”で行こう" class="entry-image" /></a></p><p>かつての啓徳空港@香港・九龍もかくやと言うくらい、住宅街の真ん中に鎮座する福岡空港。一時は海側に全く新規の空港を新設という話があったけど、結局、現滑走路とターミナルの間の空間に新滑走路を押し込むことに正式決定。ユーザーからすると使い勝手が変わらないんでありがたいけど、住民からすると、騒音も危険性も現状の2倍になるんだよな。少し複雑気分。 それはそれとして、今回の記事で気になったのは次の下り。 空...</p><p><a href="http://b.hatena.ne.jp/entry/http://d.hatena.ne.jp/kagura-may/20150104/p1"><img src="http://b.hatena.ne.jp/entry/image/http://d.hatena.ne.jp/kagura-may/20150104/p1" alt="はてなブックマーク - 福岡空港に第2滑走路が増設される件について - ” Wer Y sagt, muss auch Z sagen. ”で行こう" title="はてなブックマーク - 福岡空港に第2滑走路が増設される件について - ” Wer Y sagt, muss auch Z sagen. ”で行こう" border="0" style="border: none" /></a> <a href="http://b.hatena.ne.jp/append?http://d.hatena.ne.jp/kagura-may/20150104/p1"><img src="http://b.hatena.ne.jp/images/append.gif" border="0" alt="はてなブックマークに追加" title="はてなブックマークに追加" /></a></p></blockquote>
2015-01-04T13:09:17+09:00
世の中
1
-
2015-01-04 - お気に入り商品の紹介
http://d.hatena.ne.jp/neme_asuka/20150104#1420344031
13:00 | @titagun: ダイエット・健康等、の商品を割引価格、特別価格で取り扱っています。 URL こちらのサイトも運営していますので、どうぞ。 URL URL2015-01-04 08:16:48 via twittbot.net@titagun: 今までの常識をくつがえすスイングで 「飛んで曲がらない」ボールを実現します。 URL2015-01-03 23:06:20 via tw...
<blockquote cite="http://d.hatena.ne.jp/neme_asuka/20150104#1420344031" title="2015-01-04 - お気に入り商品の紹介"><cite><img src="http://cdn-ak.favicon.st-hatena.com/?url=http%3A%2F%2Fd.hatena.ne.jp%2Fneme_asuka%2F" alt="" /> <a href="http://d.hatena.ne.jp/neme_asuka/20150104#1420344031">2015-01-04 - お気に入り商品の紹介</a></cite><p>13:00 | @titagun: ダイエット・健康等、の商品を割引価格、特別価格で取り扱っています。 URL こちらのサイトも運営していますので、どうぞ。 URL URL2015-01-04 08:16:48 via twittbot.net@titagun: 今までの常識をくつがえすスイングで 「飛んで曲がらない」ボールを実現します。 URL2015-01-03 23:06:20 via tw...</p><p><a href="http://b.hatena.ne.jp/entry/http://d.hatena.ne.jp/neme_asuka/20150104%231420344031"><img src="http://b.hatena.ne.jp/entry/image/http://d.hatena.ne.jp/neme_asuka/20150104%231420344031" alt="はてなブックマーク - 2015-01-04 - お気に入り商品の紹介" title="はてなブックマーク - 2015-01-04 - お気に入り商品の紹介" border="0" style="border: none" /></a> <a href="http://b.hatena.ne.jp/append?http://d.hatena.ne.jp/neme_asuka/20150104%231420344031"><img src="http://b.hatena.ne.jp/images/append.gif" border="0" alt="はてなブックマークに追加" title="はてなブックマークに追加" /></a></p></blockquote>
2015-01-04T13:04:17+09:00
テクノロジー
1
-
もうこれからずっとこの国はこの一言でいいんじゃないかな、というフレーズを思いついた。 - こころ世代のテンノーゲーム
http://d.hatena.ne.jp/umeten/20141227/p1
「要は、お金がないんでしょ?貧乏人は非国民。」 非国民奥崎謙三は訴える!!!―「ゆきゆきて神軍」の凱歌posted with amazlet at 14.12.27奥崎 謙三 新泉社 売り上げランキング: 657,764 Amazon.co.jpで詳細を見るツイートする
<blockquote cite="http://d.hatena.ne.jp/umeten/20141227/p1" title="もうこれからずっとこの国はこの一言でいいんじゃないかな、というフレーズを思いついた。 - こころ世代のテンノーゲーム"><cite><img src="http://cdn-ak.favicon.st-hatena.com/?url=http%3A%2F%2Fd.hatena.ne.jp%2Fumeten%2F" alt="" /> <a href="http://d.hatena.ne.jp/umeten/20141227/p1">もうこれからずっとこの国はこの一言でいいんじゃないかな、というフレーズを思いついた。 - こころ世代のテンノーゲーム</a></cite><p>「要は、お金がないんでしょ?貧乏人は非国民。」 非国民奥崎謙三は訴える!!!―「ゆきゆきて神軍」の凱歌posted with amazlet at 14.12.27奥崎 謙三 新泉社 売り上げランキング: 657,764 Amazon.co.jpで詳細を見るツイートする</p><p><a href="http://b.hatena.ne.jp/entry/http://d.hatena.ne.jp/umeten/20141227/p1"><img src="http://b.hatena.ne.jp/entry/image/http://d.hatena.ne.jp/umeten/20141227/p1" alt="はてなブックマーク - もうこれからずっとこの国はこの一言でいいんじゃないかな、というフレーズを思いついた。 - こころ世代のテンノーゲーム" title="はてなブックマーク - もうこれからずっとこの国はこの一言でいいんじゃないかな、というフレーズを思いついた。 - こころ世代のテンノーゲーム" border="0" style="border: none" /></a> <a href="http://b.hatena.ne.jp/append?http://d.hatena.ne.jp/umeten/20141227/p1"><img src="http://b.hatena.ne.jp/images/append.gif" border="0" alt="はてなブックマークに追加" title="はてなブックマークに追加" /></a></p></blockquote>
2015-01-04T12:54:56+09:00
世の中
1
-
「Web業界からEC業界に行ってブチ当たった、皆が教えてくれない「EC業界の見えない壁」の正体を、もやっと掴めました!」を読んで(次回ミーティングのために)整理してみました - リア
http://d.hatena.ne.jp/ryuka01/20150104/1420341384
年明けで様々な記事を読んでいたところ、以下の記事を発見しました。Web業界からEC業界に行ってブチ当たった、皆が教えてくれない「EC業界の見えない壁」の正体を、もやっと掴めました!ECサイトの運営に携わっている方にはぜひ読んでいただきたい内容です。 記事を書かれている永上さんは、以前の会社が一緒だったこと、そして過去にブログで取り上げていただいたこと(参考:「えがちゃん」に取材をしていただきました...
<blockquote cite="http://d.hatena.ne.jp/ryuka01/20150104/1420341384" title="「Web業界からEC業界に行ってブチ当たった、皆が教えてくれない「EC業界の見えない壁」の正体を、もやっと掴めました!」を読んで(次回ミーティングのために)整理してみました - リア"><cite><img src="http://cdn-ak.favicon.st-hatena.com/?url=http%3A%2F%2Fd.hatena.ne.jp%2Fryuka01%2F" alt="" /> <a href="http://d.hatena.ne.jp/ryuka01/20150104/1420341384">「Web業界からEC業界に行ってブチ当たった、皆が教えてくれない「EC業界の見えない壁」の正体を、もやっと掴めました!」を読んで(次回ミーティングのために)整理してみました - リア</a></cite><p><a href="http://d.hatena.ne.jp/ryuka01/20150104/1420341384"><img src="http://cdn-ak.b.st-hatena.com/entryimage/238058800-1420343719.jpg" alt="「Web業界からEC業界に行ってブチ当たった、皆が教えてくれない「EC業界の見えない壁」の正体を、もやっと掴めました!」を読んで(次回ミーティングのために)整理してみました - リア" title="「Web業界からEC業界に行ってブチ当たった、皆が教えてくれない「EC業界の見えない壁」の正体を、もやっと掴めました!」を読んで(次回ミーティングのために)整理してみました - リア" class="entry-image" /></a></p><p>年明けで様々な記事を読んでいたところ、以下の記事を発見しました。Web業界からEC業界に行ってブチ当たった、皆が教えてくれない「EC業界の見えない壁」の正体を、もやっと掴めました!ECサイトの運営に携わっている方にはぜひ読んでいただきたい内容です。 記事を書かれている永上さんは、以前の会社が一緒だったこと、そして過去にブログで取り上げていただいたこと(参考:「えがちゃん」に取材をしていただきました...</p><p><a href="http://b.hatena.ne.jp/entry/http://d.hatena.ne.jp/ryuka01/20150104/1420341384"><img src="http://b.hatena.ne.jp/entry/image/http://d.hatena.ne.jp/ryuka01/20150104/1420341384" alt="はてなブックマーク - 「Web業界からEC業界に行ってブチ当たった、皆が教えてくれない「EC業界の見えない壁」の正体を、もやっと掴めました!」を読んで(次回ミーティングのために)整理してみました - リア" title="はてなブックマーク - 「Web業界からEC業界に行ってブチ当たった、皆が教えてくれない「EC業界の見えない壁」の正体を、もやっと掴めました!」を読んで(次回ミーティングのために)整理してみました - リア" border="0" style="border: none" /></a> <a href="http://b.hatena.ne.jp/append?http://d.hatena.ne.jp/ryuka01/20150104/1420341384"><img src="http://b.hatena.ne.jp/images/append.gif" border="0" alt="はてなブックマークに追加" title="はてなブックマークに追加" /></a></p></blockquote>
2015-01-04T12:54:56+09:00
テクノロジー
38
-
2014-12-15 - 空中キャンプ
http://d.hatena.ne.jp/zoot32/20141215#p1
これが最終の回答です。どの方もユニークな内容で、とてもおもしろいです。ランキングがすべてじゃないなと、あらためて思います。参加いただいた方ありがとうございました。TMC 男性@tmc_stmFORMA サッドティー 円卓 こっこ、ひと夏のイマジンブラッド・ピット.繰り返し見たい/誰かと見たい作品でまとめました。tomtom 男性@ss_wasshoiレゴ・ムービー ゴジラ イコライザーイコライザー...
<blockquote cite="http://d.hatena.ne.jp/zoot32/20141215#p1" title="2014-12-15 - 空中キャンプ"><cite><img src="http://cdn-ak.favicon.st-hatena.com/?url=http%3A%2F%2Fd.hatena.ne.jp%2Fzoot32%2F" alt="" /> <a href="http://d.hatena.ne.jp/zoot32/20141215#p1">2014-12-15 - 空中キャンプ</a></cite><p><a href="http://d.hatena.ne.jp/zoot32/20141215#p1"><img src="http://cdn-ak.b.st-hatena.com/entryimage/238058776-1420343560.jpg" alt="2014-12-15 - 空中キャンプ" title="2014-12-15 - 空中キャンプ" class="entry-image" /></a></p><p>これが最終の回答です。どの方もユニークな内容で、とてもおもしろいです。ランキングがすべてじゃないなと、あらためて思います。参加いただいた方ありがとうございました。TMC 男性@tmc_stmFORMA サッドティー 円卓 こっこ、ひと夏のイマジンブラッド・ピット.繰り返し見たい/誰かと見たい作品でまとめました。tomtom 男性@ss_wasshoiレゴ・ムービー ゴジラ イコライザーイコライザー...</p><p><a href="http://b.hatena.ne.jp/entry/http://d.hatena.ne.jp/zoot32/20141215%23p1"><img src="http://b.hatena.ne.jp/entry/image/http://d.hatena.ne.jp/zoot32/20141215%23p1" alt="はてなブックマーク - 2014-12-15 - 空中キャンプ" title="はてなブックマーク - 2014-12-15 - 空中キャンプ" border="0" style="border: none" /></a> <a href="http://b.hatena.ne.jp/append?http://d.hatena.ne.jp/zoot32/20141215%23p1"><img src="http://b.hatena.ne.jp/images/append.gif" border="0" alt="はてなブックマークに追加" title="はてなブックマークに追加" /></a></p></blockquote>
2015-01-04T12:52:20+09:00
エンタメ
1
-
POCO C++ライブラリがスゴイ. - なぜか数学者にはワイン好きが多い
http://d.hatena.ne.jp/tullio/20090430
非常にシンプルま味ですが,黒胡椒がピリッときて良い感じです.ホントにシンプルで,原材料名は「ブラックペッパー」「食塩」「糖類(砂糖,オリゴ糖)」「チキンエキスパウダー(乳を含む)」「オニオンパウダー」「ガーリックパウダー」等です.確かに表面に,ブラックペッパーらしき黒い香辛料が見えます.
<blockquote cite="http://d.hatena.ne.jp/tullio/20090430" title="POCO C++ライブラリがスゴイ. - なぜか数学者にはワイン好きが多い"><cite><img src="http://cdn-ak.favicon.st-hatena.com/?url=http%3A%2F%2Fd.hatena.ne.jp%2Ftullio%2F" alt="" /> <a href="http://d.hatena.ne.jp/tullio/20090430">POCO C++ライブラリがスゴイ. - なぜか数学者にはワイン好きが多い</a></cite><p><a href="http://d.hatena.ne.jp/tullio/20090430"><img src="http://cdn-ak.b.st-hatena.com/entryimage/238058657-1420343026.jpg" alt="POCO C++ライブラリがスゴイ. - なぜか数学者にはワイン好きが多い" title="POCO C++ライブラリがスゴイ. - なぜか数学者にはワイン好きが多い" class="entry-image" /></a></p><p>非常にシンプルま味ですが,黒胡椒がピリッときて良い感じです.ホントにシンプルで,原材料名は「ブラックペッパー」「食塩」「糖類(砂糖,オリゴ糖)」「チキンエキスパウダー(乳を含む)」「オニオンパウダー」「ガーリックパウダー」等です.確かに表面に,ブラックペッパーらしき黒い香辛料が見えます.</p><p><a href="http://b.hatena.ne.jp/entry/http://d.hatena.ne.jp/tullio/20090430"><img src="http://b.hatena.ne.jp/entry/image/http://d.hatena.ne.jp/tullio/20090430" alt="はてなブックマーク - POCO C++ライブラリがスゴイ. - なぜか数学者にはワイン好きが多い" title="はてなブックマーク - POCO C++ライブラリがスゴイ. - なぜか数学者にはワイン好きが多い" border="0" style="border: none" /></a> <a href="http://b.hatena.ne.jp/append?http://d.hatena.ne.jp/tullio/20090430"><img src="http://b.hatena.ne.jp/images/append.gif" border="0" alt="はてなブックマークに追加" title="はてなブックマークに追加" /></a></p></blockquote>
2015-01-04T12:43:31+09:00
暮らし
1
-
5アンペア生活への挑戦 - hatehei666の日記
http://d.hatena.ne.jp/hatehei666/20141219/1418955637
11:20 「快楽を愛する者は貧しい人となり、ぶどう酒や油を愛する者は富むことがない」(箴言21:17)。 『5アンペア生活をやってみた』(斉藤健一郎著)を読みました。著者斉藤氏は現在40歳、朝日新聞の記者をやっており、以前そうした題のコラムを新聞に載せた事があります(*私も過去ログで触れました)。今度岩波ジュニア新書で項を新たにして出しました。 斉藤氏は2011年3月11日東日本大震災の時は郡山...
<blockquote cite="http://d.hatena.ne.jp/hatehei666/20141219/1418955637" title="5アンペア生活への挑戦 - hatehei666の日記"><cite><img src="http://cdn-ak.favicon.st-hatena.com/?url=http%3A%2F%2Fd.hatena.ne.jp%2Fhatehei666%2F" alt="" /> <a href="http://d.hatena.ne.jp/hatehei666/20141219/1418955637">5アンペア生活への挑戦 - hatehei666の日記</a></cite><p><a href="http://d.hatena.ne.jp/hatehei666/20141219/1418955637"><img src="http://cdn-ak.b.st-hatena.com/entryimage/238058580-1420342732.jpg" alt="5アンペア生活への挑戦 - hatehei666の日記" title="5アンペア生活への挑戦 - hatehei666の日記" class="entry-image" /></a></p><p>11:20 「快楽を愛する者は貧しい人となり、ぶどう酒や油を愛する者は富むことがない」(箴言21:17)。 『5アンペア生活をやってみた』(斉藤健一郎著)を読みました。著者斉藤氏は現在40歳、朝日新聞の記者をやっており、以前そうした題のコラムを新聞に載せた事があります(*私も過去ログで触れました)。今度岩波ジュニア新書で項を新たにして出しました。 斉藤氏は2011年3月11日東日本大震災の時は郡山...</p><p><a href="http://b.hatena.ne.jp/entry/http://d.hatena.ne.jp/hatehei666/20141219/1418955637"><img src="http://b.hatena.ne.jp/entry/image/http://d.hatena.ne.jp/hatehei666/20141219/1418955637" alt="はてなブックマーク - 5アンペア生活への挑戦 - hatehei666の日記" title="はてなブックマーク - 5アンペア生活への挑戦 - hatehei666の日記" border="0" style="border: none" /></a> <a href="http://b.hatena.ne.jp/append?http://d.hatena.ne.jp/hatehei666/20141219/1418955637"><img src="http://b.hatena.ne.jp/images/append.gif" border="0" alt="はてなブックマークに追加" title="はてなブックマークに追加" /></a></p></blockquote>
2015-01-04T12:38:42+09:00
暮らし
1
-
国が年間被ばく線量設定基準20ミリシーベルト以下にした経緯等 - hatehei666の日記
http://d.hatena.ne.jp/hatehei666/20141223/1419300068
11:01 「しかし、あなたがたは偽りをでっちあげる者、あなたがたはみな、能なしの医者だ」(ヨブ13:4)。 日野行介著『福島原発事故 県民健康管理調査の闇』を読みました。福島県「県民健康管理調査」検討委員会が議論を秘密扱いし、事実を隠ぺいした経緯を、毎日新聞社所属の日野氏は徹底的に追及しています。これまで断片的な報道が幾つかありましたが、1冊の本に収まってみると、これまで目に見えなかったものが、...
<blockquote cite="http://d.hatena.ne.jp/hatehei666/20141223/1419300068" title="国が年間被ばく線量設定基準20ミリシーベルト以下にした経緯等 - hatehei666の日記"><cite><img src="http://cdn-ak.favicon.st-hatena.com/?url=http%3A%2F%2Fd.hatena.ne.jp%2Fhatehei666%2F" alt="" /> <a href="http://d.hatena.ne.jp/hatehei666/20141223/1419300068">国が年間被ばく線量設定基準20ミリシーベルト以下にした経緯等 - hatehei666の日記</a></cite><p><a href="http://d.hatena.ne.jp/hatehei666/20141223/1419300068"><img src="http://cdn-ak.b.st-hatena.com/entryimage/238058362-1420342549.jpg" alt="国が年間被ばく線量設定基準20ミリシーベルト以下にした経緯等 - hatehei666の日記" title="国が年間被ばく線量設定基準20ミリシーベルト以下にした経緯等 - hatehei666の日記" class="entry-image" /></a></p><p>11:01 「しかし、あなたがたは偽りをでっちあげる者、あなたがたはみな、能なしの医者だ」(ヨブ13:4)。 日野行介著『福島原発事故 県民健康管理調査の闇』を読みました。福島県「県民健康管理調査」検討委員会が議論を秘密扱いし、事実を隠ぺいした経緯を、毎日新聞社所属の日野氏は徹底的に追及しています。これまで断片的な報道が幾つかありましたが、1冊の本に収まってみると、これまで目に見えなかったものが、...</p><p><a href="http://b.hatena.ne.jp/entry/http://d.hatena.ne.jp/hatehei666/20141223/1419300068"><img src="http://b.hatena.ne.jp/entry/image/http://d.hatena.ne.jp/hatehei666/20141223/1419300068" alt="はてなブックマーク - 国が年間被ばく線量設定基準20ミリシーベルト以下にした経緯等 - hatehei666の日記" title="はてなブックマーク - 国が年間被ばく線量設定基準20ミリシーベルト以下にした経緯等 - hatehei666の日記" border="0" style="border: none" /></a> <a href="http://b.hatena.ne.jp/append?http://d.hatena.ne.jp/hatehei666/20141223/1419300068"><img src="http://b.hatena.ne.jp/images/append.gif" border="0" alt="はてなブックマークに追加" title="はてなブックマークに追加" /></a></p></blockquote>
2015-01-04T12:35:37+09:00
世の中
1
tdiary-contrib-5.1.0/spec/fixtures/twitter.xml 0000664 0000000 0000000 00000006567 13570131474 0021521 0 ustar 00root root 0000000 0000000
65589541
tDiary.org
tDiary
tDiaryオフィシャルアカウント
http://a0.twimg.com/profile_images/379668735/square_logo_normal.png
https://si0.twimg.com/profile_images/379668735/square_logo_normal.png
http://www.tdiary.org/
false
286
FFFFFF
333333
0084B4
D0FFD0
D0FFD0
261
Fri Aug 14 07:50:23 +0000 2009
3
32400
Tokyo
http://a0.twimg.com/images/themes/theme1/bg.png
https://si0.twimg.com/images/themes/theme1/bg.png
false
false
false
false
313
ja
false
31
false
false
false
Mon Sep 17 00:04:52 +0000 2012
247486242491604992
RT @hsbt: DefaultIO から RdbIO へのインポータできた #tdiary
<a href="http://www.crowy.net/" rel="nofollow">Crowy</a>
false
false
2
false
Mon Sep 17 00:01:16 +0000 2012
247485333179101185
DefaultIO から RdbIO へのインポータできた #tdiary
<a href="http://mzp.github.com/atig/" rel="nofollow">atig.rb</a>
false
false
2
false
tdiary-contrib-5.1.0/spec/flicker_spec.rb 0000664 0000000 0000000 00000002034 13570131474 0020363 0 ustar 00root root 0000000 0000000 $:.unshift(File.dirname(__FILE__))
require 'spec_helper'
describe "flickr plugin" do
let(:plugin) { fake_plugin(:flickr) }
before(:all) do
stub_request(:get, "https://www.flickr.com/services/rest/?api_key=f7e7fb8cc34e52db3e5af5e1727d0c0b&method=flickr.photos.getInfo&photo_id=5950109223")
.to_return(status: 200, body: File.new('spec/fixtures/flickr/5950109223.flickr.photos.getInfo.xml'))
stub_request(:get, "https://www.flickr.com/services/rest/?api_key=f7e7fb8cc34e52db3e5af5e1727d0c0b&method=flickr.photos.getSizes&photo_id=5950109223")
.to_return(status: 200, body: File.new('spec/fixtures/flickr/5950109223.flickr.photos.getSizes.xml'))
end
describe '#flickr' do
subject { plugin.flickr('5950109223', size = nil) }
it do
expect(subject).to eq %Q| |
end
end
end
tdiary-contrib-5.1.0/spec/gist_spec.rb 0000664 0000000 0000000 00000000761 13570131474 0017717 0 ustar 00root root 0000000 0000000 $:.unshift(File.dirname(__FILE__))
require 'spec_helper'
describe "gist plugin" do
DUMMY_GIST_ID = 1234567890
it 'should render javascript tag with specified gist-id' do
plugin = fake_plugin(:gist)
snippet = plugin.gist(DUMMY_GIST_ID)
expected = (<<-EOS).chomp
EOS
expect(snippet).to eq(expected)
end
end
tdiary-contrib-5.1.0/spec/github_link_spec.rb 0000664 0000000 0000000 00000002345 13570131474 0021250 0 ustar 00root root 0000000 0000000 $:.unshift(File.dirname(__FILE__))
require 'spec_helper'
describe "github link plugin" do
let(:plugin) { fake_plugin(:github_link) }
subject { plugin.gh_link(*args) }
describe 'repository page' do
let(:args) { ['tdiary/tdiary-contrib'] }
it 'should render repository a tag' do
is_expected.to eq(%(tdiary-contrib ))
end
end
describe 'issues page' do
let(:args) { ['tdiary/tdiary-contrib#100'] }
it 'should render issues a tag' do
is_expected.to eq(%(tdiary-contrib#100 ))
end
end
context "When given altenative text" do
let(:text) { 'This project' }
let(:github_identifier) { 'tdiary/tdiary-contrib' }
let(:args) { [github_identifier, text] }
it 'should render repository a tag with the specified text' do
is_expected.to eq(%(#{text} ))
end
context "but the text is including ' }
it 'should render a link text after sanitizing.' do
is_expected.not_to eq(%(#{text} ))
end
end
end
end
tdiary-contrib-5.1.0/spec/google_analytics_spec.rb 0000664 0000000 0000000 00000002742 13570131474 0022275 0 ustar 00root root 0000000 0000000 $:.unshift(File.dirname(__FILE__))
require 'spec_helper'
describe "google_analytics plugin" do
def setup_google_analytics_plugin(profile_id, mode)
fake_plugin(:google_analytics) { |plugin|
plugin.mode = mode
plugin.conf['google_analytics.profile'] = profile_id
}
end
describe "should render javascript" do
before do
@plugin = setup_google_analytics_plugin('53836-1', 'latest')
end
it "for footer" do
snippet = @plugin.footer_proc
expect(snippet).to eq(expected_html_footer_snippet)
end
end
describe "should render javascript" do
before do
@plugin = setup_google_analytics_plugin('53836-1', 'conf')
end
it "for footer" do
snippet = @plugin.footer_proc
expect(snippet).to be_empty
end
end
describe "should not render when profile_id is empty" do
before do
@plugin = setup_google_analytics_plugin(nil, 'latest')
end
it "for footer" do
snippet = @plugin.footer_proc
expect(snippet).to be_empty
end
end
def expected_html_footer_snippet
expected = <<-SCRIPT
SCRIPT
expected.gsub( /^\t/, '' ).chomp
end
end
tdiary-contrib-5.1.0/spec/google_universal_analytics_spec.rb 0000664 0000000 0000000 00000003074 13570131474 0024364 0 ustar 00root root 0000000 0000000 $:.unshift(File.dirname(__FILE__))
require 'spec_helper'
describe "google_universal_analytics plugin" do
def setup_google_universal_analytics_plugin(profile_id, mode)
fake_plugin(:google_universal_analytics) { |plugin|
plugin.mode = mode
plugin.conf['google_universal_analytics.profile'] = profile_id
}
end
describe "should render javascript" do
before do
@plugin = setup_google_universal_analytics_plugin('53836-1', 'latest')
end
it "for footer" do
snippet = @plugin.footer_proc
expect(snippet).to eq(expected_html_footer_snippet)
end
end
describe "should render javascript" do
before do
@plugin = setup_google_universal_analytics_plugin('53836-1', 'conf')
end
it "for footer" do
snippet = @plugin.footer_proc
expect(snippet).to be_empty
end
end
describe "should not render when profile_id is empty" do
before do
@plugin = setup_google_universal_analytics_plugin(nil, 'latest')
end
it "for footer" do
snippet = @plugin.footer_proc
expect(snippet).to be_empty
end
end
def expected_html_footer_snippet
expected = <<-SCRIPT
SCRIPT
expected.gsub( /^\t/, '' ).chomp
end
end
tdiary-contrib-5.1.0/spec/jdate_spec.rb 0000664 0000000 0000000 00000000772 13570131474 0020042 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
$:.unshift(File.dirname(__FILE__))
require 'spec_helper'
require 'time'
describe "jdate plugin" do
{
'20080121' => '月',
'20080122' => '火',
'20080123' => '水',
'20080124' => '木',
'20080125' => '金',
'20080126' => '土',
'20080127' => '日',
}.each do |k,v|
it { expect(setup_jdate_plugin(Time.parse(k)).date.strftime('%J')).to eq(v) }
end
def setup_jdate_plugin(date)
fake_plugin(:jdate) {|plugin| plugin.date = date}
end
end
tdiary-contrib-5.1.0/spec/jmonth_spec.rb 0000664 0000000 0000000 00000001276 13570131474 0020252 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
$:.unshift(File.dirname(__FILE__))
require 'spec_helper'
require 'time'
describe "jmonth plugin" do
{
'2007/01/01' => '睦月',
'2007/02/01' => '如月',
'2007/03/01' => '弥生',
'2007/04/01' => '卯月',
'2007/05/01' => '皐月',
'2007/06/01' => '水無月',
'2007/07/01' => '文月',
'2007/08/01' => '葉月',
'2007/09/01' => '長月',
'2007/10/01' => '神無月',
'2007/11/01' => '霜月',
'2007/12/01' => '師走'
}.each do |k,v|
it { expect(setup_jmonth_plugin(Time.parse(k)).date.strftime('%i')).to eq(v) }
end
def setup_jmonth_plugin(date)
fake_plugin(:jmonth) { |plugin| plugin.date = date }
end
end
tdiary-contrib-5.1.0/spec/jyear_spec.rb 0000664 0000000 0000000 00000000761 13570131474 0020063 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
$:.unshift(File.dirname(__FILE__))
require 'spec_helper'
require 'time'
describe "jyear plugin" do
{
'1925/01/01' => '昔々',
'1926/12/25' => '昭和元年',
'1927/01/01' => '昭和2',
'1989/01/08' => '平成元年',
'1990/01/01' => '平成2',
}.each do |k,v|
it { expect(setup_jyear_plugin(Time.parse(k)).date.strftime('%K')).to eq(v) }
end
def setup_jyear_plugin(date)
fake_plugin(:jyear) { |plugin| plugin.date = date }
end
end
tdiary-contrib-5.1.0/spec/my_hotentry_spec.rb 0000664 0000000 0000000 00000004415 13570131474 0021332 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
$:.unshift(File.dirname(__FILE__))
require 'spec_helper'
require 'tmpdir'
require 'fileutils'
describe "MyHotEntry" do
def cache_filename
"#{File.basename(__FILE__, ".rb")}-#{$$}"
end
before(:each) do
stub_request(:get, "http://b.hatena.ne.jp/entrylist?mode=rss&url=http%3A%2F%2Fd.hatena.ne.jp%2F&sort=eid&threshold=3")
.to_return(status: 200, body: File.new('spec/fixtures/my_hotentry/entrylist.xml'))
stub_request(:get, "http://b.hatena.ne.jp/entrylist?mode=rss&sort=eid&threshold=3&url=http://empty-url.example.com/")
.to_return(status: 200, body: File.new('spec/fixtures/my_hotentry/entrylist-empty.xml'))
fake_plugin(:my_hotentry)
@cache_path = File.join(Dir.tmpdir, cache_filename)
Dir.mkdir(@cache_path)
@dbfile = "#{@cache_path}/my_hotentry.dat"
@base_url = 'http://d.hatena.ne.jp/'
@hotentry = MyHotEntry.new(@dbfile)
end
after(:each) do
FileUtils.rmtree(@cache_path)
end
describe "#update" do
before do
@hotentry.update(@base_url)
@entries = @hotentry.entries
end
it "キャッシュファイルが生成されていること" do
expect(File).to be_file(@dbfile)
end
it "人気の日記が取得できていること" do
expect(@entries.size).to be > 0
end
it "取得したエントリにbase_urlとタイトルが含まれていること" do
@entries.each do |entry|
expect(entry[:url]).to be_include(@base_url)
expect(entry[:title].size).to be > 0
end
end
end
describe "何度もupdateした場合" do
before do
@hotentry.update(@base_url)
@original_entry_size = @hotentry.entries.size
@hotentry.update(@base_url)
@entry_size = @hotentry.entries.size
end
it "キャッシュサイズが大きくならないこと" do
expect(@entry_size).to eq(@original_entry_size)
end
end
describe "取得結果が空の場合" do
before do
@exist_url = 'http://d.hatena.ne.jp/'
@empty_url = 'http://empty-url.example.com/'
end
it "キャッシュをクリアしないこと" do
@hotentry.update(@empty_url)
expect(@hotentry.entries.size).to eq(0)
@hotentry.update(@exist_url)
expect(@hotentry.entries.size).to be > 0
exist_size = @hotentry.entries.size
@hotentry.update(@empty_url)
expect(@hotentry.entries.size).to eq(exist_size)
end
end
end
tdiary-contrib-5.1.0/spec/openid_spec.rb 0000664 0000000 0000000 00000015572 13570131474 0020235 0 ustar 00root root 0000000 0000000 $:.unshift(File.dirname(__FILE__))
require 'spec_helper'
describe "openid plugin w/" do
def setup_open_id_plugin(service, userid)
fake_plugin(:openid) { |plugin|
plugin.mode = 'latest'
plugin.conf['openid.service'] = service
plugin.conf['openid.id'] = userid
}
end
describe "Hatena" do
before do
plugin = setup_open_id_plugin('Hatena', 'tdtds')
@header_snippet = plugin.header_proc
end
it { expect(@header_snippet).to include_link_tag_with(
:rel => 'openid.server',
:href => 'https://www.hatena.ne.jp/openid/server')}
it { expect(@header_snippet).to include_link_tag_with(
:rel => 'openid.delegate',
:href => 'http://www.hatena.ne.jp/tdtds/')}
end
describe "livedoor" do
before do
plugin = setup_open_id_plugin('livedoor', 'tdtds')
@header_snippet = plugin.header_proc
end
it { expect(@header_snippet).to include_link_tag_with(
:rel => 'openid.server',
:href => 'http://auth.livedoor.com/openid/server')}
it { expect(@header_snippet).to include_link_tag_with(
:rel => 'openid.delegate',
:href => 'http://profile.livedoor.com/tdtds')}
end
describe "LiveJournal" do
before do
plugin = setup_open_id_plugin('LiveJournal', 'tdtds')
@header_snippet = plugin.header_proc
end
it { expect(@header_snippet).to include_link_tag_with(
:rel => 'openid.server',
:href => 'http://www.livejournal.com/openid/server.bml')}
it { expect(@header_snippet).to include_link_tag_with(
:rel => 'openid.delegate',
:href => 'http://tdtds.livejournal.com/')}
end
describe "OpenID.ne.jp" do
before do
plugin = setup_open_id_plugin('OpenID.ne.jp', 'tdtds')
@header_snippet = plugin.header_proc
end
it { expect(@header_snippet).to include_link_tag_with(
:rel => 'openid.server',
:href => 'http://www.openid.ne.jp/user/auth')}
it { expect(@header_snippet).to include_link_tag_with(
:rel => 'openid.delegate',
:href => 'http://tdtds.openid.ne.jp')}
it { expect(@header_snippet).to include_xrds_meta_tag_with(
:content => 'http://tdtds.openid.ne.jp/user/xrds')}
end
describe "TypeKey" do
before do
plugin = setup_open_id_plugin('TypeKey', 'tdtds')
@header_snippet = plugin.header_proc
end
it { expect(@header_snippet).to include_link_tag_with(
:rel => 'openid.server',
:href => 'http://www.typekey.com/t/openid/')}
it { expect(@header_snippet).to include_link_tag_with(
:rel => 'openid.delegate',
:href => 'http://profile.typekey.com/tdtds/')}
end
describe "Vox" do
before do
plugin = setup_open_id_plugin('Vox', 'tdtds')
@header_snippet = plugin.header_proc
end
it { expect(@header_snippet).to include_link_tag_with(
:rel => 'openid.server',
:href => 'http://www.vox.com/services/openid/server')}
it { expect(@header_snippet).to include_link_tag_with(
:rel => 'openid.delegate',
:href => 'http://tdtds.vox.com/')}
end
describe "myopenid.com" do
before do
@plugin = setup_open_id_plugin('myopenid.com', 'tdtds')
@header_snippet = @plugin.header_proc
end
it { expect(@header_snippet).to include_xrds_meta_tag_with(
:content => "http://www.myopenid.com/xrds?username=tdtds")}
it { expect(@header_snippet).to include_link_tag_with(
:rel => "openid.server",
:href => "http://www.myopenid.com/server")}
it { expect(@header_snippet).to include_link_tag_with(
:rel => "openid.delegate",
:href => "http://tdtds.myopenid.com")}
it { expect(@header_snippet).to include_link_tag_with(
:rel => "openid2.provider",
:href => "http://www.myopenid.com/server")}
it { expect(@header_snippet).to include_link_tag_with(
:rel => "openid2.local_id",
:href => "http://tdtds.myopenid.com")}
end
describe "claimID.com" do
before do
@plugin = setup_open_id_plugin('claimID.com', 'tdtds')
@header_snippet = @plugin.header_proc
end
it { expect(@header_snippet).to include_xrds_meta_tag_with(
:content => "http://claimid.com/tdtds/xrds")}
it { expect(@header_snippet).to include_link_tag_with(
:rel => "openid.server",
:href => "http://openid.claimid.com/server")}
it { expect(@header_snippet).to include_link_tag_with(
:rel => "openid.delegate",
:href => "http://openid.claimid.com/tdtds")}
end
describe "Personal Identity Provider (PIP)" do
before do
@plugin = setup_open_id_plugin('Personal Identity Provider (PIP)', 'tdtds')
@header_snippet = @plugin.header_proc
end
it { expect(@header_snippet).to include_xrds_meta_tag_with(
:content => "http://pip.verisignlabs.com/user/tdtds/yadisxrds")}
it { expect(@header_snippet).to include_link_tag_with(
:rel => "openid.server",
:href => "http://pip.verisignlabs.com/server")}
it { expect(@header_snippet).to include_link_tag_with(
:rel => "openid.delegate",
:href => "http://tdtds.pip.verisignlabs.com/")}
it { expect(@header_snippet).to include_link_tag_with(
:rel => "openid2.provider",
:href => "http://pip.verisignlabs.com/server")}
it { expect(@header_snippet).to include_link_tag_with(
:rel => "openid2.local_id",
:href => "http://tdtds.pip.verisignlabs.com/")}
end
describe "Yahoo! Japan" do
before do
plugin = setup_open_id_plugin('Yahoo! Japan', 'tdtds')
@header_snippet = plugin.header_proc
end
it { expect(@header_snippet).to include_link_tag_with(
:rel => 'openid2.provider',
:href => 'https://open.login.yahooapis.jp/openid/op/auth')}
it { expect(@header_snippet).to include_link_tag_with(
:rel => 'openid2.local_id',
:href => 'https://me.yahoo.co.jp/a/tdtds')}
it { expect(@header_snippet).not_to include_link_tag_with(
:rel => "openid.server")}
it { expect(@header_snippet).not_to include_link_tag_with(
:rel => "openid.delegate")}
end
describe "Yahoo!" do
before do
plugin = setup_open_id_plugin('Yahoo!', 'tdtds')
@header_snippet = plugin.header_proc
end
it { expect(@header_snippet).to include_link_tag_with(
:rel => 'openid2.provider',
:href => 'https://open.login.yahooapis.com/openid/op/auth')}
it { expect(@header_snippet).to include_link_tag_with(
:rel => 'openid2.local_id',
:href => 'https://me.yahoo.com/a/tdtds')}
it { expect(@header_snippet).not_to include_link_tag_with(
:rel => "openid.server")}
it { expect(@header_snippet).not_to include_link_tag_with(
:rel => "openid.delegate")}
end
RSpec::Matchers.define :include_link_tag_with do |options|
description do
"include #{options[:rel]} link tag"
end
match do |actual|
expected = %| | if options[:href]
actual.include?( expected )
end
end
RSpec::Matchers.define :include_xrds_meta_tag_with do |options|
description do
"include XRDS meta tag"
end
match do |actual|
expected = (<<-"EOS").chomp
EOS
actual.include?( expected )
end
end
end
tdiary-contrib-5.1.0/spec/opensearch_ad_spec.rb 0000664 0000000 0000000 00000002622 13570131474 0021542 0 ustar 00root root 0000000 0000000 $:.unshift(File.dirname(__FILE__))
require 'spec_helper'
describe "opensearch_ad plugin w/" do
def setup_opensearch_ad_plugin(title, xml, mode)
fake_plugin(:opensearch_ad) { |plugin|
plugin.mode = mode
plugin.conf['opensearch.title'] = title
plugin.conf['opensearch.xml'] = xml
}
end
describe "in day mode" do
before do
plugin = setup_opensearch_ad_plugin('OpenSearch', 'http://example.com/opensearch.xml', 'day')
@header_snippet = plugin.header_proc
end
it { expect(@header_snippet).to eq(expected_link_tag_with(
:title => 'OpenSearch',
:xml => 'http://example.com/opensearch.xml'))}
end
describe "in latest mode" do
before do
plugin = setup_opensearch_ad_plugin('OpenSearch', 'http://example.com/opensearch.xml', 'latest')
@header_snippet = plugin.header_proc
end
it { expect(@header_snippet).to eq(expected_link_tag_with(
:title => 'OpenSearch',
:xml => 'http://example.com/opensearch.xml'))}
end
describe "in edit mode" do
before do
plugin = setup_opensearch_ad_plugin('OpenSearch', 'http://example.com/opensearch.xml', 'edit')
@header_snippet = plugin.header_proc
end
it { expect(@header_snippet).to be_empty }
end
def expected_link_tag_with(options)
result = <<-HTML
HTML
result.gsub( /^\t/, '' ).chomp
end
end
tdiary-contrib-5.1.0/spec/profile_spec.rb 0000664 0000000 0000000 00000003660 13570131474 0020412 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
require 'spec_helper'
require 'profile'
describe "Profile::Service" do
describe "GitHub" do
before do
require 'json'
allow_any_instance_of(Profile::Service::GitHub).to receive(:fetch).and_return(JSON.parse(File.read("spec/fixtures/github.json")))
# workaround for run spec on various environment.
require 'openssl'
OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE
# http://develop.github.com/p/general.html
@profile = Profile::Service::GitHub.new("schacon")
end
it "should include name, mail, image properties" do
expect(@profile.name).to eq("Scott Chacon")
expect(@profile.mail).to eq("schacon@gmail.com")
expect(@profile.image).to eq("https://avatars.githubusercontent.com/u/70?v=3")
end
end
describe "Gravatar" do
# http://ja.gravatar.com/site/implement/hash/
before do
require 'json'
allow_any_instance_of(Profile::Service::Gravatar).to receive(:fetch).and_return(JSON.parse(File.read("spec/fixtures/gravatar.json")))
@profile = Profile::Service::Gravatar.new("iHaveAn@email.com")
end
it "should include name, mail, image properties" do
expect(@profile.name).to eq("tDiary")
expect(@profile.mail).to eq("iHaveAn@email.com")
expect(@profile.image).to eq("http://2.gravatar.com/avatar/3b3be63a4c2a439b013787725dfce802")
end
context 'with options' do
before do
@profile = Profile::Service::Gravatar.new("iHaveAn@email.com", :size => 40)
end
it "should specify size option" do
expect(@profile.image).to eq("http://2.gravatar.com/avatar/3b3be63a4c2a439b013787725dfce802?s=40")
end
end
end
describe "Hatena" do
before do
@profile = Profile::Service::Hatena.new("kmachu")
end
it "should include image property" do
expect(@profile.image).to eq("http://www.hatena.ne.jp/users/km/kmachu/profile.gif")
end
end
end
tdiary-contrib-5.1.0/spec/rcov.opts 0000664 0000000 0000000 00000000047 13570131474 0017267 0 ustar 00root root 0000000 0000000 -x /var/lib/gem
-x spec/spec_helper.rb
tdiary-contrib-5.1.0/spec/spec_helper.rb 0000664 0000000 0000000 00000007346 13570131474 0020236 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
$:.unshift(File.expand_path(File.join(File.dirname(__FILE__), "..", "plugin")))
if ENV['COVERAGE'] == 'simplecov'
require 'simplecov'
SimpleCov.start do
add_filter '/spec/'
add_filter '/vendor/'
end
end
require 'erb'
require 'webmock/rspec'
require 'tmpdir'
RSpec.configure do |c|
# create a temporary directory used by the plugin for cache
c.before(:all) do
@cache_path = Dir.mktmpdir
end
c.after(:all) do
FileUtils.rmtree(@cache_path)
end
end
# FIXME PluginFake in under construction.
class PluginFake
include ERB::Util
attr_reader :conf
attr_accessor :mode, :date
def initialize
@conf = Config.new
@cache_path = ""
@mode = ""
@date = nil
@header_procs = []
@footer_procs = []
@update_procs = []
@conf_procs = []
@edit_procs = []
@body_enter_procs = []
@body_leave_procs = []
end
def add_conf_proc( key, label, genre=nil, &block )
@conf_procs << block
end
def add_edit_proc(&block)
@edit_procs << block
end
def add_header_proc(&block)
@header_procs << block
end
def add_footer_proc(&block)
@footer_procs << block
end
def add_update_proc(&block)
@update_procs << block
end
def conf_proc
r = []
@conf_procs.each do |proc|
r << proc.call
end
r.join.chomp
end
def header_proc
r = []
@header_procs.each do |proc|
r << proc.call
end
r.join.chomp
end
def footer_proc
r = []
@footer_procs.each do |proc|
r << proc.call
end
r.join.chomp
end
def add_body_enter_proc(&block)
@body_enter_procs << block
end
def body_enter_proc( date )
r = []
@body_enter_procs.each do |proc|
r << proc.call( date )
end
r.join.chomp
end
def add_body_leave_proc(&block)
@body_leave_procs << block
end
def body_leave_proc( date )
r = []
@body_leave_procs.each do |proc|
r << proc.call( date )
end
r.join.chomp
end
class Config
attr_accessor :index, :html_title, :cgi
def initialize
@cgi = CGIFake.new
@options = {}
@options2 = {}
@index = './'
@html_title = ''
bot = ["bot", "spider", "antenna", "crawler", "moget", "slurp"]
bot += @options['bot'] || []
@bot = Regexp::new( "(#{bot.uniq.join( '|' )})", true )
end
def []( key )
@options[key]
end
def []=( key, val )
@options2[key] = @options[key] = val
end
def delete( key )
@options.delete( key )
@options2.delete( key )
end
def base_url
begin
if @options['base_url'].length > 0 then
return @options['base_url']
end
rescue
end
end
def mobile_agent?
false
end
def smartphone?
false
end
def bot?
@bot =~ @cgi.user_agent
end
end
def feed?
false
end
def iphone?
false
end
alias ipod? iphone?
end
class CGIFake
attr_accessor :user_agent
def initialize
@user_agent = ""
end
def mobile_agent?
false
end
def iphone?
false
end
end
def fake_plugin( name_sym, cgi=nil, base=nil, &block )
plugin = PluginFake.new
yield plugin if block_given?
file_path = plugin_path( name_sym, base )
plugin_name = File.basename( file_path, ".rb" )
plugin.instance_variable_set(:@cache_path, @cache_path)
plugin.instance_eval do
eval( File.read( file_path ), binding,
"(#{File.basename(file_path)})", 1 )
end
plugin_sym = plugin_name.to_sym
if plugin.class.private_method_defined?( plugin_sym )
plugin.__send__( :public, plugin_sym )
end
plugin
end
def plugin_path( plugin_sym, base=nil )
paths = []
paths << ( base ? base : "plugin" )
paths << "#{plugin_sym.to_s}.rb"
File.expand_path( File.join( paths ))
end
def anchor( s )
if /^([\-\d]+)#?([pct]\d*)?$/ =~ s then
if $2 then
"?date=#$1##$2"
else
"?date=#$1"
end
else
""
end
end
# Local Variables:
# mode: ruby
# indent-tabs-mode: t
# tab-width: 3
# ruby-indent-level: 3
# End:
# vim: ts=3
tdiary-contrib-5.1.0/spec/title_anchor_spec.rb 0000664 0000000 0000000 00000001643 13570131474 0021424 0 ustar 00root root 0000000 0000000 $:.unshift(File.dirname(__FILE__))
require 'spec_helper'
describe "title_anchor plugin" do
def setup_title_anchor_plugin(mode)
fake_plugin(:title_anchor) { |plugin|
plugin.mode = mode
plugin.conf.index = ''
plugin.conf.html_title = "HsbtDiary"
}
end
describe "in day mode" do
before do
@plugin = setup_title_anchor_plugin('day')
end
it { expect(@plugin.title_anchor).to eq(expected_html_title_in_day(
:index => '',
:html_title => 'HsbtDiary'))}
end
describe "in latest mode" do
before do
@plugin = setup_title_anchor_plugin('latest')
end
it { expect(@plugin.title_anchor).to eq(expected_html_title_in_latest(
:html_title => 'HsbtDiary'))}
end
def expected_html_title_in_day(options)
expected = %{}
end
def expected_html_title_in_latest(options)
expected = %{#{options[:html_title]} }
end
end
tdiary-contrib-5.1.0/spec/twitter_js_spec.rb 0000664 0000000 0000000 00000006135 13570131474 0021150 0 ustar 00root root 0000000 0000000 $:.unshift(File.dirname(__FILE__))
require 'spec_helper'
require 'time'
describe "twitter_js plugin" do
def setup_twitter_js_plugin(mode, user_id)
fake_plugin(:twitter_js) { |plugin|
plugin.mode = mode
plugin.conf['twitter.user'] = user_id
plugin.date = Time.parse("20080124")
}
end
describe "should render javascript and div tag in day" do
before do
@plugin = setup_twitter_js_plugin("day", "123456789")
end
it "for header" do
snippet = @plugin.header_proc
expect(snippet).to eq(expected_html_header_snippet("123456789"))
end
it "for body leave" do
snippet = @plugin.body_leave_proc(Time.parse("20080124"))
expect(snippet).to eq(expected_html_body_snippet)
end
end
describe "should render javascript and div tag in latest" do
before do
@plugin = setup_twitter_js_plugin("latest", "123456789")
end
it "for header" do
snippet = @plugin.header_proc
expect(snippet).to eq(expected_html_header_snippet("123456789"))
end
it "for body leave" do
snippet = @plugin.body_leave_proc(Time.parse("20080124"))
expect(snippet).to eq(expected_html_body_snippet)
end
end
describe "should not render in edit" do
before do
@plugin = setup_twitter_js_plugin("edit", "123456789")
end
it "for header" do
snippet = @plugin.header_proc
expect(snippet).to be_empty
end
it "for body leave" do
snippet = @plugin.body_leave_proc(Time.parse("20080124"))
expect(snippet).to be_empty
end
end
describe "should not render when user_id is empty" do
before do
@plugin = setup_twitter_js_plugin("edit", "")
end
it "for header" do
snippet = @plugin.header_proc
expect(snippet).to be_empty
end
it "for body leave" do
snippet = @plugin.body_leave_proc(Time.parse("20080124"))
expect(snippet).to be_empty
end
end
def expected_html_header_snippet(user_id)
expected = <<-EXPECTED
EXPECTED
expected.gsub(/^\t/, '').chomp
end
def expected_html_body_snippet
expected = <<-HTML
HTML
expected.gsub( /^\t/, '' ).chomp
end
end
tdiary-contrib-5.1.0/spec/youtube_spec.rb 0000664 0000000 0000000 00000001172 13570131474 0020442 0 ustar 00root root 0000000 0000000 $:.unshift(File.dirname(__FILE__))
require 'spec_helper'
describe "youtube plugin" do
DUMMY_YOUTUBE_VIDEO_ID = 1234567890
{
'Mozilla' => %|\t\t\n\t\t\n\t\t
\n|
}.each do |k,v|
it 'should render object tag in :user_agent' do
plugin = fake_plugin(:youtube)
cgi = CGIFake.new
cgi.user_agent = k
plugin.conf.cgi = cgi
expect(plugin.youtube(DUMMY_YOUTUBE_VIDEO_ID)).to eq(v)
end
end
end
tdiary-contrib-5.1.0/style/ 0000775 0000000 0000000 00000000000 13570131474 0015614 5 ustar 00root root 0000000 0000000 tdiary-contrib-5.1.0/style/hatena_style.rb 0000775 0000000 0000000 00000062363 13570131474 0020636 0 ustar 00root root 0000000 0000000 #!/usr/bin/env ruby -Ke
# Copyright(c) 2004 URABE, Shyouhei.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this code, to deal in the code without restriction, including without
# limitation the rights to use, copy, modify, merge, publish, distribute,
# sublicense, and/or sell copies of the code, and to permit persons to whom the
# code is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the code.
#
# THE CODE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHOR OR COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE CODE OR THE USE OR OTHER DEALINGS IN THE
# CODE.
# $Id: hatena_style.rb,v 1.12 2007-02-27 06:57:14 kazuhiko Exp $
# Hatena::Diary compatible style
# Works only under ruby 1.8.1 or later
[
'uri',
'net/http',
'cgi',
'pstore',
'time',
].each {|f| require f }
class TDiary::HatenaDiary
include TDiary::DiaryBase, TDiary::CategorizableDiary
def initialize(date, title, body, modified=Time.now)
init_diary
@sections = []
replace date, title, body
@last_modified = modified
end
def style
'Hatena'
end
def replace(date, title, body)
set_date date
set_title title
@sections.clear
append body
end
def append(body, author=nil)
@sections.concat Hatena::Diary.parse(body, author)
self
end
def each_section(&block)
@sections.each(&block)
end
def to_src
@sections.inject('') {|r, i| r << i.to_src }
end
def to_html(opt, mode=:HTML)
j = 0
@sections.inject('') {|r, i|
j += 1
r << '' if mode != :CHTML
r << i.convert(mode, date, j, opt)
r << '
' if mode != :CHTML
r
}
end
def to_s
sprintf('date=%s, title=%s, body=%s',
date.strftime('%Y%m%d'),
title,
@sections.map {|i| '[%s]' % i}.join)
end
end
# This is the namespace module
module Hatena
def Hatena.conf
ObjectSpace.each_object do |diary|
next unless diary.kind_of?(TDiary::TDiaryBase)
return diary.instance_eval { @conf }
end
end
Diary = Object.new
API = Object.new
# get a text of hatena-style, and convert it into parse tree.
def Diary.parse(str, author)
str.gsub(/\r(?!\n)/,"\n")\
.delete("\r")\
.gsub(/^\*/,'**')\
.split(/^\*/)\
.inject([]) {|r, i| i.empty? ? r : r << Hatena::Section.new(i, author) }
end
# find the cache_path from entore ruby world
# could someone please tell me more eficient way to do this...
def API.cache_path
ret = Hatena.conf.cache_path || Hatena.conf.data_path + '/cache'
unless FileTest.directory?(ret)
begin
Dir.mkdir(ret)
rescue Errno::EEXIST
; # OK
end
end
ret
end
def API.update_kw(kw)
return false if File.exist?(kw) && Time.now - File.mtime(kw) < 86400
File.open(kw, IO::WRONLY|IO::CREAT) do |fp|
break unless fp.flock(IO::LOCK_EX|IO::LOCK_NB)
uri = ::URI.parse('http://d.hatena.ne.jp/images/keyword/keywordlist')
Timeout.timeout(60) do
Net::HTTP.version_1_1
Net::HTTP.new(uri.host, uri.port).start do |http|
res, body = http.get(uri.request_uri,
{'User-Agent' => "tDiary/#{TDIARY_VERSION}"})
fp.seek(0, IO::SEEK_SET)
fp.write(body)
end
end
end
true
end
def API.update_db(kw, db)
raise if API.update_kw kw
raise unless FileTest.exist? db.path
false
rescue
str = File.open(kw, IO::RDONLY) do |fp|
fp.flock(IO::LOCK_SH)
fp.read
end
a = str.gsub(/\\s/,' ') \
.gsub(/\\(?!\|)/,'') \
.scan(/(?:[^|]|\\\|)*[^\\](?=\||\z)/)
db.transaction do
db['trie'] = Trie.new(a)
end
true
end
# The trie of keywords
# Keywords are chached, chache expires every day (24h)
def API.keywords
path = API.cache_path
kw = path + '/keywordlist'
db = PStore.new(path + '/keywords.pstore')
if API.update_db(kw, db) || @ret.nil?
db.transaction(IO::RDONLY) do
@ret = db['trie']
end
end
return @ret
end
end
# Deterministic finate automata
class Hatena::Trie
private
def add(kw)
h = @hash1
kw.split(//e).each do |c|
unless h.has_key? c
tmp = Hash.new
@ary << tmp
h[c] = tmp
end
h = h[c]
end
@hash2[h] = kw
end
def initialize(a)
@ary = Array.new
@hash1 = Hash.new
@hash2 = Hash.new
a.each {|kw| add kw }
end
public
def match(str)
ret = nil
h = @hash1
a = str.split(//e)
i = 0
j = 0
while c = a[i + j]
if h[c]
h = h[c]
if @hash2[h]
ret = @hash2[h]
end
f = false
j += 1
else
return ret if ret
h = @hash1 # reset
i += 1
j = 0
end
end
return ret
end
end
# --------
# Parser Tree Nodes
class Hatena::Section
def initialize(str, author)
t = Time.now
@author = author.freeze
@src = str.gsub(/^\*t\*/, '*%d*' % t.to_i)\
.gsub(/<(ins|del)>/, '<\1 datetime="%s">' % t.xmlschema)
@tree = Hatena::Block.new(@src)
end
def convert(mode, date, i, opt)
@tree.convert(mode, date, i, opt, author)
end
def to_src
@src
end
def categories
@tree.title.categories
end
def author
@author
end
def body
@tree.body.to_s
end
def subtitle
@tree.title.to_s
end
def stripped_subtitle
@tree.title.strip.to_s
end
def body_to_html
@tree.body.convert(:HTML)
end
def subtitle_to_html
@tree.title.convert(:HTML)
end
def stripped_subtitle_to_html
@tree.title.strip.convert(:HTML)
end
end
# Block level elements
class Hatena::Block
attr_reader :to_s, :title, :body
def initialize(str) # Too long. Needs refactoring.
if str.nil?
@title = Hatena::Title.new('') # dummy
@body = Hatena::Inline.new('') # dummy
@to_s = ''
elsif str[0] == ?*
t,b = *str.split(/\n/,2)
@title = Hatena::Title.new(t)
@body = Hatena::BlockAndorInline.new(b, false)
@to_s = t + "\n" + (b||'')
else
@to_s = str
@title = Hatena::Title.new('') # dummy
@body = Hatena::BlockAndorInline.new(str, false)
end
end
def convert(mode, date=nil, i=nil, opt=nil, author=nil)
if title_is_dummy?
@body.convert(mode)
else
@title.convert(mode, date, i, opt, author) + "\n" + @body.convert(mode)
end
end
def title_is_dummy?
@to_s[0] == ?*
end
end
# Section subtitle
class Hatena::Title
attr_reader :to_s, :categories, :strip
def initialize(str)
if m = /\A\*([0-9]+)\*/.match(str)
@time = Time.at(Integer(m[1]))
@to_s = m.post_match.freeze
elsif m = /\A\*([a-zA-Z0-9_]+)\*/.match(str)
@name = m[1]
@to_s = m.post_match.freeze
else
@to_s = (str[1..-1]||'').freeze
end
@categories = to_s.scan(/\[(.*?)\]/).map{|a| a[0] }
@strip = Hatena::Inline.new(Regexp.last_match ? Regexp.last_match.post_match : to_s)
end
def convert(mode, date=nil, i=nil, opt=nil, author=nil)
id = ('p%02d' % (i || 0))
h = '%0.32b' % rand(0x100000000)
case
when date.nil?
categories.map {|i|
"<%=category_anchor <<'#{h}'.chomp\n#{i}\n#{h}\n%>"
}.join + strip.convert(mode)
when mode == :CHTML
sprintf('* %s%s ',
@name ? %Q{ ID"=#@name"} : '',
id,
(opt['multi_user'] && author) ? "[#{author}]" : '',
strip.convert(mode))
else
sprintf('',
@name ? %Q{ id="#@name"} : '',
opt['anchor'] ? 'name="%s" ' % id : '',
opt['index'],
date.strftime('%Y%m%d'),
@name || id,
opt['section_anchor'],
categories.map {|cat|
"<%=category_anchor <<'#{h}'.chomp\n#{cat}\n#{h}\n%>"
}.join,
(opt['multi_user'] && author) ? "[#{author}]" : '',
strip.convert(mode),
@time ? %Q!#{@time.strftime('%H:%M')} ! : '')
end
end
end
# Sequence of block level elements and/or inline level elements
# or sequence of block level elements only.
class Hatena::BlockAndorInline
def initialize(str, allowinline = true)
@elems = Array.new
pbuffer = '' # paragraph buffer
flush_pbuffer = lambda{
next if pbuffer.empty?
if allowinline
@elems.push Hatena::Inline.new(pbuffer)
else
@elems.push Hatena::Paragraph.new(pbuffer)
end
pbuffer.replace('')
}
lines = str.concat("\n").scan(/.*\n/)
until lines.empty?
case
when lines[0][0] == ?-
flush_pbuffer.call
buffer = ''
until lines.empty?
break unless lines[0][0] == ?-
buffer.concat lines.shift
end
@elems.push Hatena::Itemize.new(buffer)
when lines[0][0] == ?+
flush_pbuffer.call
buffer = ''
until lines.empty?
break unless lines[0][0] == ?+
buffer.concat lines.shift
end
@elems.push Hatena::Enumerate.new(buffer)
when lines[0][0] == ?:
flush_pbuffer.call
buffer = ''
until lines.empty?
break unless lines[0][0] == ?:
break unless lines[0].rindex(?:) != 0
buffer.concat lines.shift
end
@elems.push Hatena::Description.new(buffer)
when lines[0] == ">>\n"
flush_pbuffer.call
buffer = ''
nest = 0
until lines.empty?
nest += 1 if lines[0] == ">>\n"
nest -= 1 if lines[0] == "<<\n"
buffer.concat lines.shift
break if nest <= 0
end
@elems.push Hatena::Quote.new(buffer)
when lines[0] == ">|\n"
flush_pbuffer.call
buffer = ''
until lines.empty?
str1 = lines.shift
buffer.concat str1
break if /\|<$/ =~ str1
end
@elems.push Hatena::Verbatim.new(buffer)
when lines[0] == ">||\n"
flush_pbuffer.call
buffer = ''
until lines.empty?
str1 = lines.shift
buffer.concat str1
break if /\|\|<$/ =~ str1
end
@elems.push Hatena::SuperVerbatim.new(buffer)
when lines[0][0,5] == '><$/ =~ lines.shift
end
when lines[0][0,2] == '><'
flush_pbuffer.call
buffer = ''
until lines.empty?
str1 = lines.shift
buffer.concat str1
break if /><$/ =~ str1
end
@elems.push Hatena::UnParagraph.new(buffer)
else
pbuffer.concat lines.shift
if pbuffer[-3..-1] == "\n\n\n"
flush_pbuffer.call
end
end
end
flush_pbuffer.call
end
def convert(mode)
@elems.inject('') {|r, i| r << i.convert(mode) << "\n" }
end
end
# Itemize
# extension to Hatena: nest can be more than 3 level.
class Hatena::Itemize
def initialize(str)
@elems = Array.new
lines = str.gsub(/^-/,'').scan(/.*\n/)
buffer = ''
until lines.empty?
case
when lines[0][0] == ?-
until lines.empty?
break unless lines[0][0] == ?-
buffer.concat lines.shift
end
@elems.push Hatena::BlockAndorInline.new(buffer)
buffer = ''
when lines[0][0] == ?+
until lines.empty?
break unless lines[0][0] == ?+
buffer.concat lines.shift
end
@elems.push Hatena::BlockAndorInline.new(buffer)
buffer = ''
when lines[0][0] == ?:
until lines.empty?
break unless lines[0][0] == ?:
break unless lines[0].rindex(?:) != 0
buffer.concat lines.shift
end
@elems.push Hatena::BlcokAndorInline.new(buffer)
buffer = ''
else
@elems.push Hatena::Inline.new(buffer) unless buffer.empty?
buffer = lines.shift
end
end
@elems.push Hatena::Inline.new(buffer) unless buffer.empty?
end
def convert(mode)
template = nil
if mode == :CHTML
template = ["", "\n%s "]
else
template = ["", "\n%s "]
end
template[0] % @elems.inject('') {|r, i|
r << template[1] % i.convert(mode)
}
end
end
# Enumerate
# Extension to Hatena: nest can be more than 3 level
class Hatena::Enumerate
def initialize(str)
@elems = Array.new
lines = str.gsub(/^\+/,'').scan(/.*\n/)
buffer = ''
until lines.empty?
case
when lines[0][0] == ?-
until lines.empty?
break unless lines[0][0] == ?-
buffer.concat lines.shift
end
@elems.push Hatena::BlockAndorInline.new(buffer)
buffer = ''
when lines[0][0] == ?+
until lines.empty?
break unless lines[0][0] == ?+
buffer.concat lines.shift
end
@elems.push Hatena::BlockAndorInline.new(buffer)
buffer = ''
when lines[0][0] == ?:
until lines.empty?
break unless lines[0][0] == ?:
break unless lines[0].rindex(?:) != 0
buffer.concat lines.shift
end
@elems.push Hatena::BlcokAndorInline.new(buffer)
buffer = ''
else
@elems.push Hatena::Inline.new(buffer) unless buffer.empty?
buffer = lines.shift
end
end
@elems.push Hatena::Inline.new(buffer) unless buffer.empty?
end
def convert(mode)
template = nil
if mode == :CHTML
template = ["%s\n ", "\n%s "]
else
template = ["%s\n ", "\n%s "]
end
template[0] % @elems.inject('') {|r, i|
r << template[1] % i.convert(mode)
}
end
end
# Description list
# Extension to hatena : term only and descriotion only are OK
# :term:
# ::desc
# Extension to Hatena : can be combined with lists
class Hatena::Description
def initialize(str)
@elems = Array.new
str.each_line do |l|
raise SyntaxError unless l[0] == ?:
l = l[1..-1]
buffer = ''
# while l =~ /[^:]*#{URI.regexp}/o
# buffer.concat Regexp.last_match.to_s
# l = Regexp.last_match.post_match
# end
dt,dd = *l.split(/:/,2)
buffer.concat dt
@elems.push([
buffer.empty? ? nil : Hatena::Inline.new(buffer),
(dd.nil? || dd.empty?) ? nil : Hatena::Inline.new(dd)
])
end
end
def convert(mode)
template = nil
if mode == :CHTML
template = ["%s\n ", "\n%s ", "%s "]
else
template = ["%s\n ", "\n%s ", "%s "]
end
template[0] % @elems.inject('') {|r, i|
r << template[1] % i[0].convert(mode) unless i[0].nil?
r << template[2] % i[1].convert(mode) unless i[1].nil?
r
}
end
end
# block level quote
# Extension to hatena : nest can be more than 2 level.
class Hatena::Quote
def initialize(str)
@elems = Hatena::Block.new(str[3..-4])
end
def convert(mode)
template = nil
if mode == :CHTML
template = "\n%s\n "
else
template = "\n%s\n "
end
sprintf(template,@elems.convert(mode))
end
end
# preformatted text
class Hatena::Verbatim
def initialize(str)
@str = str[3..-4].freeze
end
def convert(mode)
template = nil
if mode == :CHTML
template = "%s "
else
template = "%s "
end
sprintf(template,CGI.escapeHTML(@str))
end
end
# preformatted text
class Hatena::SuperVerbatim
def initialize(str)
@str = str[3..-5].freeze
end
def convert(mode)
template = nil
if mode == :CHTML
template = "%s "
else
template = "%s "
end
sprintf(template,CGI.escapeHTML(@str))
end
end
# non-paragraph blocklevel
class Hatena::UnParagraph
def initialize(str)
@elems = Hatena::Inline.new(str[1..-3])
# 0123...
# >
# ... ...
# ...
<\n
# ...-321
end
def convert(mode)
@elems.convert(mode)
end
end
# paragraph
# Extension to Hatena: not using but begins next paragraph
class Hatena::Paragraph
def initialize(str)
@elems = Hatena::Inline.new(str.gsub(/\n\n\n/,''))
end
def convert(mode)
template = nil
if mode == :CHTML
template = "\n%s\n
"
else
template = "\n%s\n
"
end
sprintf(template, @elems.convert(mode))
end
end
# inline elements
class Hatena::Inline
def initialize(str)
@elems = Array.new
inside_a = false
return if str == "\n"
until str.empty?
case str
when /\A\[\](.*?)\[\]/m
@elems.push Hatena::CDATA.new(Regexp.last_match[1])
when /\A\)\(\((.*?)\)\)\(/m, /\A\(\(\((.*?)\)\)\)/m
@elems.push Hatena::CDATA.new('((')
@elems.push Hatena::Inline.new(Regexp.last_match[1])
@elems.push Hatena::CDATA.new('))')
when /\A\(\((.*?)\)\)/m
@elems.push Hatena::Footnote.new(Regexp.last_match[1])
when /\A#{tag_regex}/o
@elems.push Hatena::TAG.new(Regexp.last_match.to_s)
if str.index("") == 0
inside_a = false
end
when /\A\[amazon:(.*?)\]/m
@elems.push Hatena::AmazonSearch.new(Regexp.last_match[1], true)
when /\A\[google:(.*?)\]/m
@elems.push Hatena::Google.new(Regexp.last_match[1], true)
when /\A\[(?:(#{gid_regex}):)?keyword:(.*?)\]/m, /\A\[\[(.*?)\]\]/m
group, keyword = Regexp.last_match.captures
@elems.push Hatena::Keyword.new(group, keyword, true)
when /\A\[(?:(#{gid_regex}|[ad]):)?id:([a-zA-Z][-a-zA-Z0-9_]{1,30}[a-zA-Z0-9])\]/m,
/\A(?:(#{gid_regex}|[ad]):)?id:([a-zA-Z][-a-zA-Z0-9_]{1,30}[a-zA-Z0-9](?::(?:[0-9]+|about))?)/
sid, id = Regexp.last_match.captures
@elems.push Hatena::ID.new(sid, id, true)
when /\A\[(?i:ISBN|ASIN):(.*?)(?::image(?::(?:small|large))?)?\]/m,
/(?i:ISBN|ASIN):([-0-9A-Za-z]+)(?::image(?::(?:small|large))?)?/
@elems.push Hatena::Amazon.new(Regexp.last_match[1], true)
when /\A\[tex:(.*?)\]/m
@elems.push Hatena::TeX.new(Regexp.last_match[1])
when /\A#{gid_regex}/
@elems.push Hatena::Group.new(Regexp.last_match.to_s, true)
when /\A\[((?i:https?|ftp|mailto):.+?)\]/m, /\A(#{URI.regexp})/o
@elems.push Hatena::URI.new(Regexp.last_match[1])
else
/.+?(?=[\[\]()<>]|(?i:https?|ftp|mailto|id|ISBN|ASIN)|[adg]:|$)/m =~ str
if inside_a
@elems.push Hatena::CDATA.new(Regexp.last_match.to_s)
else
@elems.push Hatena::Sentence.new(Regexp.last_match.to_s)
end
end
str = Regexp.last_match.post_match
end
end
def convert(mode)
@elems.inject('') {|r, i| r << i.convert(mode) }
end
private
# tag_regex was quoted from http://www.din.or.jp/~ohzaki/perl.htm#HTML_Tag
def tag_regex
/<[^"'<>]*(?:"[^"]*"[^"'<>]*|'[^']*'[^"'<>]*)*(?:>|(?=<)|$)/
end
def gid_regex
/g:[a-zA-Z][a-zA-Z0-9]{2,23}/
end
end
# String that surely doesn't contain any keywords
# String that can contain keyword is a Sentence
class Hatena::CDATA
def initialize(str)
@str = str.freeze
end
def convert(mode)
@str
end
end
# footnote
# footnote.rb required
class Hatena::Footnote
def initialize(str)
@str = str
@heredoc = rand(0x100000000)
end
def convert(mode)
sprintf("<%%=fn <<'%0.32b'.chomp\n%s\n%0.32b\n%%>", @heredoc, @str, @heredoc)
end
end
# HTML tags
# Disadvantanegs from hatena : is not supported
# Extension to Hatena : ERB expression can be written
class Hatena::TAG
def initialize(str)
@elems = Array.new
return if /', @str, @str.delete('-')) # %=
else
sprintf('http://www.amazon.co.jp/exec/obidos/ASIN/%s/%s',
@str,
Hatena.conf['amazon.aid'] || '')
end
end
end
# Amazon search
# http://d.hatena.ne.jp/hatenadiary/20040310#1078879113
class Hatena::AmazonSearch
def initialize(str, tag_p)
@str = str
@tag_p = tag_p
end
def convert(mode)
uri = 'http://www.amazon.co.jp/exec/obidos/external-search?mode=blended&tag=%s&encoding-string-jp=%%c6%%fc%%cb%%dc%%b8%%ec&keyword=%s' % [Hatena.conf['amazon.aid'] || '', URI.escape(@str, /[^-_.!~*'()a-zA-Z0-9]/)]
return uri unless @tag_p
template=nil
if mode == :CHTML
template = 'amazon:%s '
else
template = 'amazon:%s '
end
sprintf(template, uri, @str)
end
end
# TeX expressoin
# texdiary http://kumamushi.org/~k/texdiary/ required
class Hatena::TeX
def initialize(expr)
@expr
end
def convert(mode)
sprintf('<%%=eq "%s"%%>' % @expr) #%=
end
end
# String that can contain keywords
# String that cannot contain keywords is a CDATA
class Hatena::Sentence
def initialize(str)
@elems = Array.new
return if str.nil? || str.empty?
if false # kw = Hatena::API.keywords.match(str)
m = Regexp.new(Regexp.quote(kw)).match(str)
@elems.push Hatena::CDATA.new(m.pre_match)
@elems.push Hatena::Keyword.new(nil, kw, true)
@elems.push Hatena::Sentence.new(m.post_match)
else
@elems.push Hatena::CDATA.new(str)
end
end
def convert(mode)
@elems.inject('') {|r, i| r << i.convert(mode) }
end
end
# Local Variables:
# mode: ruby
# code: euc-jp-unix
# End:
tdiary-contrib-5.1.0/style/markdown_style.rb 0000664 0000000 0000000 00000012526 13570131474 0021211 0 ustar 00root root 0000000 0000000 #
# markdown_style.rb: Markdown style for tDiary 2.x format. $Revision: 1.10 $
#
# if you want to use this style, add @style into tdiary.conf below:
#
# @style = 'Markdown'
#
# Copyright (C) 2003, TADA Tadashi
# Copyright (C) 2004, MoonWolf
# You can distribute this under GPL.
#
require 'bluecloth'
module TDiary
class MarkdownSection
attr_reader :subtitle, :author
attr_reader :categories, :stripped_subtitle
attr_reader :subtitle_to_html, :stripped_subtitle_to_html, :body_to_html
def initialize( fragment, author = nil )
@author = author
@subtitle, @body = fragment.split( /\n/, 2 )
@subtitle.sub!(/^\#\s*/,'')
@body ||= ''
@categories = get_categories
@stripped_subtitle = strip_subtitle
@subtitle_to_html = @subtitle ? to_html('# ' + @subtitle).gsub(/\A|<\/h\d>\z/io, '') : nil
@stripped_subtitle_to_html = @stripped_subtitle ? to_html('# ' + @stripped_subtitle).gsub(/\A|<\/h\d>\z/io, '') : nil
@body_to_html = to_html(@body)
end
def subtitle=(subtitle)
@categories = categories
cat_str = ""
categories.each {|cat|
cat_str << "[#{cat}]"
}
@subtitle = (subtitle || '').sub(/^# /,"\##{cat_str} ")
@strip_subtitle = strip_subtitle
end
def body
@body.dup
end
def body=(str)
@body = str
end
def categories=(categories)
@categories = categories
cat_str = ""
categories.each {|cat|
cat_str << "[#{cat}]"
}
@subtitle = "#{cat_str} " + (strip_subtitle || '')
@strip_subtitle = strip_subtitle
end
def to_src
r = ''
r << "\##{@subtitle}\n" if @subtitle
r << @body
end
def html4( date, idx, opt )
r = %Q[\n]
r << do_html4( date, idx, opt )
r << "
\n"
end
def do_html4( date, idx, opt )
r = ''
subtitle = to_html('# ' + @subtitle)
subtitle = subtitle.sub(/(\[([^\[]+?)\])+/) {
$&.gsub(/\[(.*?)\]/) {
$1.split(/,/).collect {|c|
%Q|<%= category_anchor("#{c}") %>|
}.join
}
}
subtitle.sub!(//,%Q[">#{opt['section_anchor']} ])
if opt['anchor'] then
subtitle.sub!(/|)
end
r << subtitle
r << @body_to_html
r
end
def chtml( date, idx, opt )
r = ''
r << to_html(@subtitle)
r << @body_to_html
r
end
def to_s
to_src
end
private
def to_html(string)
r = BlueCloth.new( string ).to_html
r.gsub!(/"
}
r
end
def get_categories
return [] unless @subtitle
cat = /(\\?\[([^\[]+?)\\?\])+/.match(@subtitle).to_a[0]
return [] unless cat
cat.scan(/\\?\[(.*?)\\?\]/).collect do |c|
c[0].split(/,/)
end.flatten
end
def strip_subtitle
return nil unless @subtitle
r = @subtitle.sub(/^((\\?\[[^\[]+?\]\\?)+\s+)?/, '')
if r.empty?
nil
else
r
end
end
end
class MarkdownDiary
include DiaryBase
include CategorizableDiary
def initialize( date, title, body, modified = Time::now )
init_diary
replace( date, title, body )
@last_modified = modified
end
def style
'Markdown'
end
def replace( date, title, body )
set_date( date )
set_title( title )
@sections = []
append( body )
end
def append( body, author = nil )
section = nil
body.each_line do |l|
case l
when /^\#[^\#]/
@sections << MarkdownSection::new( section, author ) if section
section = l
else
section = '' unless section
section << l
end
end
if section
section << "\n" unless section=~/\n\n\z/
@sections << MarkdownSection::new( section, author )
end
@last_modified = Time::now
self
end
def each_section
@sections.each do |section|
yield section
end
end
def add_section(subtitle, body)
sec = MarkdownSection::new("\n")
sec.subtitle = subtitle
sec.body = body
@sections << sec
@sections.size
end
def delete_section(index)
@sections.delete_at(index - 1)
end
def to_src
r = ''
each_section do |section|
r << section.to_src
end
r
end
def to_html( opt, mode = :HTML )
case mode
when :CHTML
to_chtml( opt )
else
to_html4( opt )
end
end
def to_html4( opt )
r = ''
idx = 1
each_section do |section|
r << section.html4( date, idx, opt )
idx += 1
end
r
end
def to_chtml( opt )
r = ''
idx = 1
each_section do |section|
r << section.chtml( date, idx, opt )
idx += 1
end
r
end
def to_s
"date=#{date.strftime('%Y%m%d')}, title=#{title}, body=[#{@sections.join('][')}]"
end
end
end
tdiary-contrib-5.1.0/style/wikiext_style.rb 0000664 0000000 0000000 00000000620 13570131474 0021043 0 ustar 00root root 0000000 0000000 # wikiext_style.rb: when using wiki style, extends behavior.
#
# Just place this file into tdiary/style directory.
#
# Copyright (C) 2012, kdmsnr
# You can distribute this under GPL.
#
module TDiary
class WikiextDiary # dummy class
end
end
require "hikidoc"
class HikiDoc
class HTMLOutput
def paragraph(lines)
@f.puts "#{lines.join("")}
"
end
end
end
tdiary-contrib-5.1.0/tdiary-contrib.gemspec 0000664 0000000 0000000 00000002635 13570131474 0020761 0 ustar 00root root 0000000 0000000 # coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'tdiary/contrib/version'
Gem::Specification.new do |spec|
spec.name = "tdiary-contrib"
spec.version = TDiary::Contrib::VERSION
spec.authors = ["tDiary contributors"]
spec.email = ["support@tdiary.org"]
spec.summary = %q{tDiary contributions package}
spec.description = %q{tDiary contributions package that includes plugins, styles, utilities, libraries, filters, and extended io.}
spec.homepage = "http://www.tdiary.org/"
spec.license = "GPL-2 and/or others"
spec.files = Dir[
'README.md',
'README.en.md',
'Rakefile',
'doc/**/*',
'filter/**/*',
'io/**/*',
'js/**/*',
'lib/**/*',
'misc/**/*',
'plugin/**/*',
'spec/**/*',
'style/**/*',
'util/**/*'
]
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
spec.require_paths = ["lib"]
spec.add_dependency 'tdiary', '~> 5.0'
spec.add_dependency 'pushbullet_ruby'
spec.add_development_dependency "bundler", ">= 1.3", "< 3.0"
spec.add_development_dependency "rake"
spec.add_development_dependency "rspec"
spec.add_development_dependency "simplecov"
spec.add_development_dependency "webmock"
spec.add_development_dependency "pry"
end
tdiary-contrib-5.1.0/util/ 0000775 0000000 0000000 00000000000 13570131474 0015431 5 ustar 00root root 0000000 0000000 tdiary-contrib-5.1.0/util/clean-spam/ 0000775 0000000 0000000 00000000000 13570131474 0017451 5 ustar 00root root 0000000 0000000 tdiary-contrib-5.1.0/util/clean-spam/README.ja 0000664 0000000 0000000 00000000072 13570131474 0020721 0 ustar 00root root 0000000 0000000 See http://www.namazu.org/~satoru/diary/20040923.html#p01
tdiary-contrib-5.1.0/util/clean-spam/tdiary-comment-clean 0000775 0000000 0000000 00000001665 13570131474 0023423 0 ustar 00root root 0000000 0000000 #!/usr/bin/env ruby
#
# Copyright (C) 2004 Satoru Takabayashi
# You can redistribute it and/or modify it under GPL2.
#
puts "Usage: tdiary-comment-clean PATTERN FILE..." if ARGV.length == 0
pattern = Regexp.new(ARGV.shift)
file_names = ARGV
deleted_comments = []
file_names.each {|file_name|
i = File.open(file_name)
first_line = i.gets
comments = []
comment = ""
while line = i.gets
if line == ".\n"
comments.push(comment)
comment = ""
else
comment << line
end
end
i.close
tmp_name = "tmp.#{Process.pid}"
File.open(tmp_name, "w") {|o|
o.print first_line
comments.each {|comment|
if pattern.match(comment)
deleted_comments.push(comment)
else
o.print comment
o.puts "."
end
}
}
File.rename(file_name, file_name + ".bak")
File.rename(tmp_name, file_name)
}
deleted_comments.each {|comment|
print comment
puts "."
}
tdiary-contrib-5.1.0/util/clean-spam/tdiary-comment-clean2 0000775 0000000 0000000 00000003332 13570131474 0023476 0 ustar 00root root 0000000 0000000 #!/usr/bin/env ruby
#
# Copyright (C) 2004 Satoru Takabayashi
# You can redistribute it and/or modify it under GPL2.
#
# Modified by machu ( http://www.machu.jp/diary/ )
# 2008-03-07: adding last-modified filter with -a and -b option
#
require 'optparse'
after_date = Time.at(0)
before_date = Time.now
test = false
opt = OptionParser.new
opt.on('-a AFTER_HOUR') {|v|
after_date = Time.at(Time.now - 60 * 60 * v.to_i)
}
opt.on('-b BEFORE_HOUR') {|v|
before_date = Time.at(Time.now - 60 * 60 * v.to_i)
}
opt.on('-t') {|v|
test = true
}
opt.parse!(ARGV)
puts "Usage: tdiary-comment-clean [-a AFTER_HOUR] [-b BEFORE_HOUR] PATTERN FILE..." if ARGV.length == 0
pattern = Regexp.new(ARGV.shift)
file_names = ARGV
class Comment
attr_accessor :body, :date
def initialize
@body = ""
end
def <<(body)
if body.match(/^Last-Modified: (\d+)$/)
@date = Time.at($1.to_i)
end
@body << body
end
end
deleted_comments = []
file_names.each {|file_name|
i = File.open(file_name)
first_line = i.gets
comments = []
comment = Comment.new
while line = i.gets
if line == ".\n"
comments.push(comment)
comment = Comment.new
else
comment << line
end
end
i.close
tmp_name = "tmp.#{Process.pid}"
File.open(tmp_name, "w") {|o|
o.print first_line
comments.each {|comment|
if pattern.match(comment.body) and (before_date > comment.date) and (after_date < comment.date)
deleted_comments.push(comment)
else
o.print comment.body
o.puts "."
end
}
}
File.rename(file_name, file_name + ".bak") unless test
File.rename(tmp_name, file_name) unless test
}
deleted_comments.each {|comment|
print comment.body
puts "."
}
tdiary-contrib-5.1.0/util/clean-spam/tdiary-referer-clean 0000775 0000000 0000000 00000002004 13570131474 0023377 0 ustar 00root root 0000000 0000000 #!/usr/bin/env ruby
#
# Copyright (C) 2004 Satoru Takabayashi
# You can redistribute it and/or modify it under GPL2.
#
puts "Usage: tdiary-referer-clean PATTERN FILE..." if ARGV.length == 0
pattern = Regexp.new(ARGV.shift)
file_names = ARGV
deleted_referers = []
file_names.each {|file_name|
tmp_name = "tmp.#{Process.pid}"
i = File.open(file_name)
o = File.open(tmp_name, "w")
first_line = i.gets
o.print first_line
while true
date_line = i.gets
break if date_line.nil?
raise unless /^Date: /.match(date_line)
blank_line = i.gets
raise unless blank_line == "\n"
o.print date_line
o.print blank_line
while line = i.gets
if line == ".\n"
o.print line
next
end
if pattern.match(line)
deleted_referers.push(line)
else
o.print line
end
end
end
i.close
o.close
File.rename(file_name, file_name + ".bak")
File.rename(tmp_name, file_name)
}
deleted_referers.each {|referer| print referer }
tdiary-contrib-5.1.0/util/convert_pstore.rb 0000664 0000000 0000000 00000002512 13570131474 0021032 0 ustar 00root root 0000000 0000000 #
# convert utf-8 in pstore.
#
# usage: convert_pstore.rb file1
#
$KCODE = 'u'
require 'nkf'
require "pstore"
begin
require "iconv"
rescue LoadError
end
def convert_pstore( file )
db = PStore.new( file )
begin
roots = db.transaction{ db.roots }
rescue ArgumentError
if /\Aundefined class\/module (.+?)(::)?\z/ =~ $!.message
klass = $1
if /EmptdiaryString\z/ =~ klass
eval( "class #{klass} < String; end" )
else
eval( "class #{ klass}; end" )
end
retry
end
end
db.transaction do
roots.each do |root|
convert_element( db[root] )
end
end
end
def convert_element( data )
case data
when Hash, Array
data.each_with_index do |e, i|
if String === e
data[i] = migrate_to_utf8( e )
else
convert_element( e )
end
end
else
data.instance_variables.each do |e|
var = data.instance_variable_get( e )
if String === var
data.instance_variable_set( e, migrate_to_utf8( var ) )
else
convert_element( var )
end
end
end
end
def migrate_to_utf8( str )
to_native( str, 'EUC-JP' )
end
def to_native( str, charset = nil )
begin
Iconv.conv('utf-8', charset || 'utf-8', str)
rescue
from = case charset
when /^utf-8$/i
'W'
when /^shift_jis/i
'S'
when /^EUC-JP/i
'E'
else
''
end
NKF::nkf("-m0 -#{from}w", str)
end
end
convert_pstore( ARGV[0] )
tdiary-contrib-5.1.0/util/estraier-search/ 0000775 0000000 0000000 00000000000 13570131474 0020512 5 ustar 00root root 0000000 0000000 tdiary-contrib-5.1.0/util/estraier-search/ChangeLog 0000664 0000000 0000000 00000002016 13570131474 0022263 0 ustar 00root root 0000000 0000000 2007-02-23 SHIBATA Hiroshi
* estraier-search.rb: add override whatsnew plugin.
2007-02-18 Kazuhiko
* estraier-search.rb: add 'require "date"'.
2007-02-16 Kazuhiko
* estraier-register.rb, estraier-search.rb: rename
@last_modified attribute to @mdate.
* estraier-register.rb: register all visible comments (ie. not
limit to 100).
2007-02-15 Kazuhiko
* estraier-search.rb, estraier.rhtml: support similarity search.
* estraier-register.rb, estraier-search.rb: support
"estraier.with_user_name" option.
* estraier-search.rb, estraier.rhtml: support changing a phrase
format.
2007-02-14 Kazuhiko
* estraier.rxml: add guid elements and escape contents of
description elements.
* estraier-register.rb, estraier-search.rb: add the
'estraier.path' variable.
* estraier.rhtml: revise for more tdiary-like outputs.
2007-02-13 Kazuhiko
* initial release: ported from rast-search.
tdiary-contrib-5.1.0/util/estraier-search/README.ja 0000664 0000000 0000000 00000010474 13570131474 0021771 0 ustar 00root root 0000000 0000000 estraier-search README
===================
Hyper Estraier を用いた tDiary
検索環境です。
特徴
----------
日記の更新と連動して自動的にインデックスを更新するので、いつでも最新の
情報で検索することができます。日記を HTML 化した後に必要な部分だけを取
り出してインデックスを作成するので、ヘッダやフッタなどによる検索ノイズ
がなく、また、プラグインの出力が検索対象になるという特徴があります。
必要なもの
----------
* tDiary 1.5 以降
* Ruby 1.8.2 以降
* Hyper Estraier 1.4 以降
(ピュアRubyインターフェイス estraierpure.rb も必要です)
セットアップ
------------
1. estraier-register.rb を tDiary の プラグインディレクトリにコピーします。
2. estraier-search.rb を tDiary の index.rb があるディレクトリにコピー
します。必要なら index.rb と同じようにシンボリックリンクを張ったり
名前を変えたりしてください。
3. CGI として実行可能にします。
$ chmod a+x estraier-search.rb
4. 必要なら #! のパスを変更します。
5. estraier.rhtml と estraier.rxml と i.estraier.rhtml を tDiary の
skel/ ディレクトリにコピーします。
6. Hyper Estraier のノードマスタをセットアップします。その際、設定ファ
イル(ノードマスタのrootdirの下の_conf)に、以下を追加してください。
attrindex: @uri{{!}}str
この設定がないと、登録エントリが増えた際に、著しくパフォーマンスが
低下します。
7. ノードマスタから、tDiary用のノードサーバを作成し、その接続情報を
tdiary.conf に記述します。デフォルトでは、以下のように記述したのと
同じ設定です。
@options["estraier.host"] = "localhost"
@options["estraier.port"] = 1978
@options["estraier.path"] = "/node/"
@options["estraier.node"] = "tdiary"
@options["estraier.name"] = "admin"
@options["estraier.password"] = "admin"
8. estraier-register.rb プラグインを有効にします。(tDiary の plugin/
ディレクトリにコピーするか、プラグイン選択のディレクトリにコピーし
てブラウザから有効に設定します。言語リソースファイルの
en/estraier-register.rb と ja/estraier-register.rb も、プラグインディ
レクトリの en/ 以下およびja/ 以下にコピーしてください。)
9. 既存の日記コンテンツに対して検索インデックスを作成します。tDiary の
設定画面から「Estraier検索」を選び、「Estraier検索のインデックスを
再構築する場合は、チェックボックスをチェックしてOKを押してください」
というメッセージに従ってチェックしてOKを押すと、
インデックスの作成は、tDiary の CGI の実行権限で以下のように実行する
ことでも可能です。
ruby estraier-register.rb [-p tdiary.rbのあるディレクトリ] [-c tdiary.confのあるディレクトリ]
10. 自分の tDiary の好きな場所 (例えばヘッダ) に以下のようなフォームを加
えてください。
search-form.rb プラグインを有効にしている場合は、以下のように書くこ
ともできます。
<%= search_form("estraier-search.rb", "query") %>
以上です。
検索のしかた
------------
estraier-search の検索対象は、日記本文、ツッコミ、TrackBack です。
検索方法については、
http://hyperestraier.sourceforge.net/uguide-ja.html#searchcond をご覧
ください。検索条件の書式を指定していない場合は、「簡便書式」で検索を行
います。
連絡先
------
かずひこ
http://www.fdiary.net/
バグ報告は以下のどこかにお願いします。
* tdiary-devel ML
* 直接メール
tdiary-contrib-5.1.0/util/estraier-search/en/ 0000775 0000000 0000000 00000000000 13570131474 0021114 5 ustar 00root root 0000000 0000000 tdiary-contrib-5.1.0/util/estraier-search/en/estraier-register.rb 0000664 0000000 0000000 00000000336 13570131474 0025103 0 ustar 00root root 0000000 0000000 @estraier_register_conf_label = 'Estraier Search'
@estraier_register_conf_header = 'Rebuild Estraier search index'
@estraier_register_conf_description = 'To rebuild Estraier search index, check the box and submit \'OK\'.'
tdiary-contrib-5.1.0/util/estraier-search/estraier-register.rb 0000775 0000000 0000000 00000016422 13570131474 0024507 0 ustar 00root root 0000000 0000000 #!/usr/bin/env ruby
# estraier-register.rb
#
# Copyright (C) 2007 Kazuhiko
# You can redistribute it and/or modify it under GPL2.
#
require "estraierpure"
unless $tdiary_estraier_register_loaded
$tdiary_estraier_register_loaded ||= true
mode = ""
if $0 == __FILE__
require 'cgi'
ARGV << '' # dummy argument against cgi.rb offline mode.
@cgi = CGI::new
mode = "CMD"
else
mode = "PLUGIN"
end
if mode == "CMD"
tdiary_path = "."
tdiary_conf = "."
$stdout.sync = true
def usage
puts "hyper-estraier-register.rb $Revision: 1.1.2.13 $"
puts " register to hyper-estraier index files from tDiary's database."
puts " usage: ruby hyper-estraier-regiser.rb [-p ] [-c ]"
exit
end
require 'getoptlong'
parser = GetoptLong::new
parser.set_options(['--path', '-p', GetoptLong::REQUIRED_ARGUMENT], ['--conf', '-c', GetoptLong::REQUIRED_ARGUMENT])
begin
parser.each do |opt, arg|
case opt
when '--path'
tdiary_path = arg
when '--conf'
tdiary_conf = arg
end
end
rescue
usage
exit( 1 )
end
tdiary_conf = tdiary_path unless tdiary_conf
Dir::chdir( tdiary_conf )
begin
$:.unshift tdiary_path
require "#{tdiary_path}/tdiary"
rescue LoadError
$stderr.puts "hyper-estraier-register.rb: cannot load tdiary.rb. <#{tdiary_path}/tdiary>\n"
$stderr.puts " usage: ruby hyper-estraier-regiser.rb [-p ] [-c ]"
exit( 1 )
end
end
module ::TDiary
#
# Database
#
class EstraierDB
attr_accessor :db
attr_reader :conf
def initialize(conf)
@conf = conf
@host = @conf["estraier.host"] || "localhost"
@port = @conf["estraier.port"] || 1978
@path = @conf["estraier.path"] || "/node/"
@node = @conf["estraier.node"] || "tdiary"
@name = @conf["estraier.name"] || "admin"
@password = @conf["estraier.password"] || "admin"
end
def transaction
db = EstraierPure::Node.new
db.set_url("http://#{@host}:#{@port}#{@path}#{@node}")
db.set_auth(@name, @password)
if db.doc_num < 0
raise "Database not found : http://#{@host}:#{@port}#{@path}#{@node}"
end
@db = db
yield self
end
def cache_path
@conf.cache_path || "#{@conf.data_path}cache"
end
end
#
# Register
#
class EstraierRegister < TDiaryBase
def initialize(estraier_db, diary)
@db = estraier_db.db
super(CGI::new, 'day.rhtml', estraier_db.conf)
@diary = diary
@date = diary.date
@diaries = {@date.strftime('%Y%m%d') => @diary} if @diaries.empty?
@plugin = ::TDiary::Plugin::new(
'conf' => @conf,
'cgi' => @cgi,
'cache_path' => @io.cache_path,
'diaries' => @diaries
)
def @plugin.apply_plugin_alt( str, remove_tag = false )
apply_plugin( str, remove_tag )
end
end
def execute(force = false)
date = @date.strftime('%Y%m%d')
cond = EstraierPure::Condition.new
if @conf["estraier.with_user_name"]
cond.add_attr("@uri STRBW #{@conf.user_name}:#{date}")
else
cond.add_attr("@uri STRBW #{date}")
end
result = @db.search(cond, 0)
if result
for i in 0...result.doc_num
doc_id = result.get_doc(i).attr("@id")
@db.out_doc(doc_id)
end
end
return unless @diary.visible?
# body
index = 0
anchor = ''
@diary.each_section do |section|
index += 1
@conf['apply_plugin'] = true
anchor = "#{date}p%02d" % index
title = CGI.unescapeHTML( @plugin.apply_plugin_alt( section.subtitle_to_html, true ).strip )
if title.empty?
title = @plugin.apply_plugin_alt( section.body_to_html, true ).strip
title = @conf.shorten( CGI.unescapeHTML( title ), 20 )
end
last_modified = @diary.last_modified.strftime("%FT%T")
body = CGI.unescapeHTML( @plugin.apply_plugin_alt( section.body_to_html, true ).strip )
doc = EstraierPure::Document.new
doc.add_attr("@title", title)
if @conf["estraier.with_user_name"]
doc.add_attr("@uri", "#{@conf.user_name}:#{anchor}")
else
doc.add_attr("@uri", anchor)
end
doc.add_attr("@mdate", last_modified)
doc.add_hidden_text(title)
doc.add_text(body)
@db.put_doc(doc)
end
# comment
@diary.each_visible_comment do |comment, index|
if /^(TrackBack|Pingback)$/i =~ comment.name
anchor = "#{date}t%02d" % index
title = "TrackBack (#{comment.name})"
else
anchor = "#{date}c%02d" % index
title = "#{@plugin.comment_description_short} (#{comment.name})"
end
body = comment.body
doc = EstraierPure::Document.new
doc.add_attr("@title", title)
if @conf["estraier.with_user_name"]
doc.add_attr("@uri", "#{@conf.user_name}:#{anchor}")
else
doc.add_attr("@uri", anchor)
end
doc.add_attr("@mdate", comment.date.strftime("%FT%T"))
doc.add_hidden_text(title)
doc.add_text(body)
@db.put_doc(doc)
end
end
protected
def mode; 'day'; end
def cookie_name; ''; end
def cookie_mail; ''; end
def convert(str)
str
end
end
#
# Main
#
class EstraierRegisterMain < TDiaryBase
def initialize(conf)
super(CGI::new, 'day.rhtml', conf)
end
def execute(out = $stdout)
require 'fileutils'
calendar
db = EstraierDB.new(conf)
db.transaction do |estraier_db|
@years.keys.sort.reverse_each do |year|
out << "(#{year.to_s}/) "
@years[year.to_s].sort.reverse_each do |month|
@io.transaction(Time::local(year.to_i, month.to_i)) do |diaries|
diaries.sort.reverse_each do |day, diary|
EstraierRegister.new(estraier_db, diary).execute
out << diary.date.strftime('%m%d ')
end
false
end
end
end
end
end
end
end
if mode == "CMD"
begin
require 'cgi'
if TDiary::Config.instance_method(:initialize).arity != 0
# for tDiary 2.1 or later
cgi = CGI.new
request = TDiary::Request.new(ENV, cgi)
conf = TDiary::Config::new(cgi, request)
else
# for tDiary 2.0 or earlier
conf = TDiary::Config::new
end
conf.header = ''
conf.footer = ''
conf.show_comment = true
conf.hide_comment_form = true
conf.show_nyear = false
def conf.bot?; true; end
TDiary::EstraierRegisterMain.new(conf).execute
rescue
print $!, "\n"
$@.each do |v|
print v, "\n"
end
exit( 1 )
end
puts
else
add_update_proc do
conf = @conf.clone
conf.header = ''
conf.footer = ''
conf.show_comment = true
conf.hide_comment_form = true
conf.show_nyear = false
def conf.bot?; true; end
diary = @diaries[@date.strftime('%Y%m%d')]
TDiary::EstraierDB.new(conf).transaction do |estraier_db|
TDiary::EstraierRegister.new(estraier_db, diary).execute(true)
end
end
if !@conf['estraier.hideconf'] && (@mode == 'conf' || @mode == 'saveconf')
args = ['estraier_register', @estraier_register_conf_label]
args << 'update' if TDIARY_VERSION > '2.1.3'
add_conf_proc(*args) do
str = <<-HTML
#{@estraier_register_conf_header}
#{@estraier_register_conf_description}
HTML
if @mode == 'saveconf'
if @cgi.valid?( 'estraier_register_rebuild' )
str << 'The following diaries were registered.
'
out = ''
TDiary::EstraierRegisterMain.new(@conf).execute(out)
str << "#{out}
"
end
end
str
end
end
end
end # $tdiary_estraier_register_loaded
tdiary-contrib-5.1.0/util/estraier-search/estraier-search.rb 0000775 0000000 0000000 00000015327 13570131474 0024133 0 ustar 00root root 0000000 0000000 #!/usr/bin/env ruby
# -*- coding: utf-8; -*-
# estraier-search.rb $Revision: 1.1.2.12 $
#
# Copyright (C) 2007 Kazuhiko
# You can redistribute it and/or modify it under GPL2.
#
BEGIN { $stdout.binmode }
begin
Encoding::default_external = 'UTF-8'
rescue NameError
$KCODE = 'n'
end
require "estraierpure"
require "enumerator"
require "date"
if FileTest::symlink?( __FILE__ ) then
org_path = File::dirname( File::readlink( __FILE__ ) )
else
org_path = File::dirname( __FILE__ )
end
$:.unshift( org_path.untaint )
require 'tdiary'
#
# class TDiaryEstraier
#
module TDiary
class TDiaryEstraier < ::TDiary::TDiaryBase
MAX_PAGES = 20
SORT_OPTIONS = [
["score", "スコア順"],
["date", "日付順"],
]
ORDER_OPTIONS = [
["asc", "昇順"],
["desc", "降順"],
]
FORM_OPTIONS = [
["simple", "簡便書式"],
["normal", "通常書式"],
]
NUM_OPTIONS = [10, 20, 30, 50, 100]
def initialize( cgi, rhtml, conf )
super
@host = @conf["estraier.host"] || "localhost"
@port = @conf["estraier.port"] || 1978
@path = @conf["estraier.path"] || "/node/"
@node = @conf["estraier.node"] || "tdiary"
parse_args
format_form
if @query.empty?
@msg = '検索条件を入力して、「検索」ボタンを押してください'
else
search
end
end
def load_plugins
super
# add a opensearch rss link
@plugin.instance_variable_get('@header_procs').unshift Proc.new {
cgi_url = @conf.base_url.sub(%r|/[^/]*$|, '/') + (@cgi.script_name ? _(File.basename(@cgi.script_name)) : '')
%Q|\t \n|
}
# override some plugins
def @plugin.sn(number = nil); ''; end
def @plugin.whats_new; ''; end
end
def eval_rxml
require 'time'
load_plugins
ERB::new( File::open( "#{PATH}/skel/estraier.rxml" ){|f| f.read }.untaint ).result( binding )
end
private
def parse_args
@query = @cgi["query"].strip
@start = @cgi["start"].to_i
@num = @cgi["num"].to_i
if @num < 1
@num = 10
elsif @num > 100
@num = 100
end
@sort = @cgi["sort"].empty? ? "score" : @cgi["sort"]
@order = @cgi["order"].empty? ? "desc" : @cgi["order"]
@form = @cgi["form"].empty? ? "simple" : @cgi["form"]
end
def search
@db = EstraierPure::Node.new
@db.set_url("http://#{@host}:#{@port}#{@path}#{@node}")
begin
t = Time.now
cond = create_search_options
cond.set_phrase(convert(@query))
@result = @db.search(cond, 0)
@secs = Time.now - t
rescue
@msg = "エラー: #{_($!.to_s + $@.join)}"
end
end
def format_result_item(item)
@date = item.attr('@uri')
if @conf["estraier.with_user_name"]
@date.gsub!(/.*:/, "")
end
@date_str = Date.parse(@date).strftime(@conf.date_format)
@last_modified = item.attr('@mdate')
@title = _(item.attr('@title'))
@summary = _(item.snippet).gsub(/\t.*/, "").gsub(/\n\n/, " ... ").delete("\n")
for term in @query.split
@title.gsub!(Regexp.new(Regexp.quote(CGI.escapeHTML(term)), true, @encoding), "\\& ")
@summary.gsub!(Regexp.new(Regexp.quote(CGI.escapeHTML(term)), true, @encoding), "\\& ")
end
query = "[SIMILAR]"
item.keywords.split(/\t/).each_slice(2).collect do |k, s|
query << " WITH #{s} #{k}"
end
@similar = "%s?query=%s" %
[_(@cgi.script_name || ""), CGI::escape(query)]
end
def format_links(result)
page_count = (result.doc_num - 1) / @num + 1
current_page = @start / @num + 1
first_page = current_page - (MAX_PAGES / 2 - 1)
if first_page < 1
first_page = 1
end
last_page = first_page + MAX_PAGES - 1
if last_page > page_count
last_page = page_count
end
buf = "\n"
if current_page > 1
buf.concat(format_link("前へ", @start - @num, @num))
end
if first_page > 1
buf.concat("... ")
end
for i in first_page..last_page
if i == current_page
buf.concat("#{i} ")
else
buf.concat(format_link(i.to_s, (i - 1) * @num, @num))
end
end
if last_page < page_count
buf.concat("... ")
end
if current_page < page_count
buf.concat(format_link("次へ", @start + @num, @num))
end
buf.concat("
\n")
return buf
end
def format_anchor(start, num)
return format('?query=%s;start=%d;num=%d;sort=%s;order=%s', CGI::escape(@query), start, num, _(@sort), _(@order))
end
def format_link(label, start, num)
return format('%s ', _(@cgi.script_name ? @cgi.script_name : ""), format_anchor(start, num), _(label))
end
def create_search_options
cond = EstraierPure::Condition.new
if @conf["estraier.with_user_name"]
cond.add_attr("@uri STRBW #{@conf.user_name}:")
end
if @sort == "date"
order = "@uri"
else
order = ""
end
if @order == "asc"
order = "[SCA]" if order.empty?
else
unless order.empty?
order << " STRD"
end
end
if @form == "simple"
cond.set_options(EstraierPure::Condition::SIMPLE)
end
cond.set_order(order)
return cond
end
def format_options(options, value)
return options.collect { |val, label|
if val == value
"#{_(label)} "
else
"#{_(label)} "
end
}.join("\n")
end
def format_form
@num_options = NUM_OPTIONS.collect { |n|
if n == @num
"#{n}件ずつ "
else
"#{n}件ずつ "
end
}.join("\n")
@sort_options = format_options(SORT_OPTIONS, @sort)
@order_options = format_options(ORDER_OPTIONS, @order)
@form_options = format_options(FORM_OPTIONS, @form)
end
def _(str)
CGI::escapeHTML(str)
end
def convert(str)
@conf.to_native(str)
end
end
end
begin
@cgi = CGI::new
if ::TDiary::Config.instance_method(:initialize).arity != 0
# for tDiary 2.1 or later
request = ::TDiary::Request.new(ENV, @cgi)
conf = ::TDiary::Config::new(@cgi, request)
else
# for tDiary 2.0 or earlier
conf = ::TDiary::Config::new
end
tdiary = TDiary::TDiaryEstraier::new( @cgi, 'estraier.rhtml', conf )
head = {
'type' => 'text/html',
'Vary' => 'User-Agent'
}
if @cgi['type'] == 'rss'
head['type'] = "application/xml; charset=#{conf.encoding}"
body = tdiary.eval_rxml
else
body = tdiary.eval_rhtml
end
head['charset'] = conf.encoding
head['Content-Length'] = body.bytesize.to_s
head['Pragma'] = 'no-cache'
head['Cache-Control'] = 'no-cache'
print @cgi.header( head )
print body
rescue Exception
if @cgi then
print @cgi.header( 'type' => 'text/plain' )
else
print "Content-Type: text/plain\n\n"
end
puts "#$! (#{$!.class})"
puts ""
puts $@.join( "\n" )
end
tdiary-contrib-5.1.0/util/estraier-search/estraier.rhtml 0000664 0000000 0000000 00000003656 13570131474 0023412 0 ustar 00root root 0000000 0000000
<%= _(@conf.html_title) %> [全文検索]
<% if @msg %>
<%= @msg %>
<% else %>
<% @end = [@result.doc_num, @start + @num].min %>
<%= _(@conf.to_native(@query)) %> の検索結果
<%= @result.doc_num %> 件中 <%= @start + 1 %> - <%= @end %> 件目
(<%= @secs %> 秒)
<% if @result.doc_num > @num %>
<%= format_links(@result) %>
<% end %>
<% for i in @start...@end %>
<% item = @result.get_doc(i) || next %>
<% format_result_item(item) %>
<%= @conf.to_native(@summary) %>
<% end %>
<% if @result.doc_num > @num %>
<%= format_links(@result) %>
<% end %>
<% end %>
tdiary-contrib-5.1.0/util/estraier-search/estraier.rxml 0000664 0000000 0000000 00000002403 13570131474 0023233 0 ustar 00root root 0000000 0000000 "?>
<%= _( @conf.html_title ) %> [全文検索]: <%= _(@query) %>
<%= @conf.base_url.sub(%r|/[^/]*$|, '/') %><%= _(@cgi.script_name ? File.basename(@cgi.script_name) : "") %><%= format_anchor(@start, @num) %>
HyperEstraier 検索: <%= _(@query) %>
ja-JP
<%= @result.doc_num %>
<%= @start + 1 %>
<%= @num %>
<% for i in @start...@start+@num %>
<% item = @result.get_doc(i) || next %>
<% format_result_item(item) %>
-
<%= _(@date.sub(/^(\d{4})(\d{2})(\d{2}).*/, "\\1-\\2-\\3")) %> <%= _(@conf.to_native(@title)) %>
<%= @conf.base_url %><%= @plugin.anchor(@date) %>
<%= _(CGI.rfc1123_date(Time.parse(@last_modified))) %>
<%= _(@conf.to_native(@summary)) %>
<%= @conf.base_url %><%= @plugin.anchor(@date) %>
<% end %>
tdiary-contrib-5.1.0/util/estraier-search/i.estraier.rhtml 0000664 0000000 0000000 00000001704 13570131474 0023631 0 ustar 00root root 0000000 0000000 <%= _(@conf.html_title) %> [全文検索]
<% if @msg %>
<%= @msg %>
<% else %>
<%= @result.doc_num %>件中<%= @start + 1 %>-<%= [@result.doc_num, @start + @num].min %>件目
<% for i in @start...@start+@num %><% item = @result.get_doc(i) || next %><% format_result_item(item) %>
<% end %>
<% if @result.doc_num > @num %>
<%= format_links(@result) %>
<% end %>
<% end %>
tdiary-contrib-5.1.0/util/estraier-search/ja/ 0000775 0000000 0000000 00000000000 13570131474 0021104 5 ustar 00root root 0000000 0000000 tdiary-contrib-5.1.0/util/estraier-search/ja/estraier-register.rb 0000664 0000000 0000000 00000000465 13570131474 0025076 0 ustar 00root root 0000000 0000000 @estraier_register_conf_label = 'Estraier検索'
@estraier_register_conf_header = 'Estraier検索インデックスの再構築'
@estraier_register_conf_description = 'Estraier検索のインデックスを再構築する場合は、チェックボックスをチェックしてOKを押してください。'
tdiary-contrib-5.1.0/util/image-gallery/ 0000775 0000000 0000000 00000000000 13570131474 0020150 5 ustar 00root root 0000000 0000000 tdiary-contrib-5.1.0/util/image-gallery/README.ja 0000664 0000000 0000000 00000002041 13570131474 0021416 0 ustar 00root root 0000000 0000000 tDiary Image Gallery Ver 2.1.0 -- README.ja --
Copyright (c) 2005-2014 N.KASHIJUKU
You can redistribute it and/or modify it under GPL2.
===================
■概要
image or image_ex プラグインで日記に貼り付けた画像ファイルの一覧表示ページを生成する、
tDiaryの拡張機能(プラグイン & Ruby CGI)です。
■使い方の詳細は…
以下のサイトをご覧下さい。
・ドキュメント・サイト
http://exception.rash.jp/tdiary/image-gallery2.html
・作者の日記のサポート・ページ
http://exception.rash.jp/diary/?date=20010101
■サンプルは…
・作者の日記
http://exception.rash.jp/diary/
・Image Gallery Listモード
http://exception.rash.jp/diary/image-gallery.rb
・Image Gallery SideShowモード
http://exception.rash.jp/diary/image-gallery.rb?mode=slide
・Image Gallery Viewerモード
http://exception.rash.jp/diary/image-gallery.rb?mode=viewer;key=20090222_0
tdiary-contrib-5.1.0/util/image-gallery/image-gallery.rb 0000775 0000000 0000000 00000040710 13570131474 0023221 0 ustar 00root root 0000000 0000000 #!/usr/bin/env ruby
# -*- coding: utf-8 -*-
# image-gallery.rb $Revision: 2.1.0 $
#
# Copyright (c) 2005-2013 N.KASHIJUKU
# You can redistribute it and/or modify it under GPL2.
if RUBY_VERSION >= '1.9.0'
Encoding::default_external = 'UTF-8'
$LOAD_PATH.push('./')
end
if FileTest::symlink?( __FILE__ ) then
org_path = File::dirname( File::readlink( __FILE__ ) )
else
org_path = File::dirname( __FILE__ )
end
$:.unshift( org_path.untaint )
$:.unshift( (org_path + '/lib').untaint ) unless $:.include?( org_path + '/lib' )
require 'tdiary'
require 'pstore'
require 'date'
# class TDiaryGallery
#
module TDiary
class ImageData
attr_reader :file, :url, :title, :subtitle, :date, :width, :height, :type
attr_writer :file, :url, :title, :subtitle, :date, :width, :height, :type
end
class TDiaryGallery < ::TDiary::TDiaryBase
MAX_PAGES = 20
ORDER_OPTIONS = [
["asc", "新しい順"],
["desc", "古い順"],
]
MODE_OPTIONS = [
["list", "リスト"],
["slide", "スライド"],
]
def initialize( cgi, rhtml, conf )
super
@img_version = "2.1.0"
@image_hash = Hash[]
@image_num = 0
@image_keys = []
@images = []
@exifstr = []
@t_page_title = ""
get_conf(conf)
parse_args(cgi)
format_form
read_cache
make_image_data
check_name_filter_dateformat
make_page_title
end
private
def get_conf(conf)
@column = conf.options['image-gallery.column'].to_i
@column = 3 if @column == 0
@line = conf.options['image-gallery.line'].to_i
@line = 4 if @line == 0
@num = @line * @column
@width = conf.options['image-gallery.width']
@width = "160" if @width == nil
@vwidth = conf.options['image-gallery.vwidth']
@vwidth = "640" if @vwidth == nil
@show_exif = conf.options['image-gallery.show_exif']
@show_exif = false if @show_exif == nil
@use_mid_image = conf.options['image-gallery.use_mid_image']
@use_mid_image = false if @use_mid_image == nil
end
def parse_args(cgi)
@start = cgi["start"].to_i
@order = @cgi["order"].empty? ? "asc" : @cgi["order"]
@name_filter = @cgi["name"].empty? ? "" : @cgi["name"].strip
@title_filter = @cgi["title"].empty? ? "" : @cgi["title"].strip
@subtitle_filter = @cgi["subtitle"].empty? ? "" : @cgi["subtitle"].strip
@mode = @cgi["mode"].empty? ? "list" : @cgi["mode"].strip
@mode = "list" if @mode != "viewer" and @mode != "slide" and @mode != "fslide"
@key = cgi["key"].empty? ? "" : cgi["key"].strip
@page_title = cgi["pagetitle"].empty? ? "" : @cgi["pagetitle"].strip
@show_inputfield = true;
show_inputfield = @cgi["showinputfield"].strip
@show_inputfield = false if show_inputfield == "false"
end
def read_cache
begin
db = PStore.new("#{@io.cache_path}/gallery/image-gallery2.dat") # for tDiary 3.1.3 or later
rescue
db = PStore.new("#{cache_path}/gallery/image-gallery2.dat") # for tDiary 3.1.2 or faster
end
db.transaction do
@image_hash = db["recent_image_hash"]
@image_keys = db["recent_image_keys"]
@image_url = db["recent_image_url"]
@image_dir = db["recent_image_dir"]
db.abort
end
end
def make_image_data
if @name_filter != "" or @title_filter != "" or @subtitle_filter != ""
@image_keys.reject! { |key|
image = @image_hash[key]
(@name_filter != "" and image.file.match(@name_filter) == nil) or
(@title_filter != "" and image.title.match(@title_filter) == nil) or
(@subtitle_filter != "" and image.subtitle.match(@subtitle_filter) == nil)
}
end
@image_num = @image_keys.length
@image_keys = @image_keys.reverse if @order == "asc"
if @mode == "list" or @mode == "slide" or @mode == "fslide"
if @key != ""
index = @image_keys.index(@key)
if index != nil
@start = (index / @num) * @num
else
return
end
end
@num.times do |i|
index = @start + i
break if @image_keys[index] == nil
@images.push(@image_hash[@image_keys[index]])
end
elsif @mode == "viewer"
if @key != ""
index = @image_keys.index(@key)
if index != nil
@start = index
else
@start = 0
end
end
@images.push(@image_hash[@image_keys[@start]])
width, height = @images[0].width.to_i, @images[0].height.to_i
size = ((width > height ? width : height) > @vwidth.to_i) ? @vwidth : width
if width > height
@sizestr = %Q[width="#{size}" height="#{(size.to_i*height/width).to_s}"]
else
@sizestr = %Q[width="#{(size.to_i*width/height).to_s}" height="#{size}"]
end
if @show_exif and @images[0].type == "jpg"
begin
require 'exifparser'
@exifstr = read_exif_data("#{@image_dir}/#{@images[0].file}")
rescue
exp = []
exp.push(($!).to_s)
($!).backtrace.each do |btinfo|
exp.push(btinfo)
end
@exifstr = exp
end
end
end
end
def check_name_filter_dateformat
@page_year = ""
@page_month = ""
@page_day = ""
@page_date = nil
return if @name_filter == ""
t_name_filter = @name_filter.dup
t_name_filter["^"] = "" if t_name_filter[0] == ?^
t_name_filter = t_name_filter[5,8] if t_name_filter[4] == ?/
begin
if t_name_filter.index(/[\d]{8}/) != nil
@page_year = t_name_filter[0,4]
@page_month = t_name_filter[4,2]
@page_day = t_name_filter[6,2]
@page_date = Date.new(@page_year.to_i, @page_month.to_i, @page_day.to_i)
elsif t_name_filter.index(/[\d]{6}/) != nil
@page_year = t_name_filter[0,4]
@page_month = t_name_filter[4,2]
@page_date = Date.new(@page_year.to_i, @page_month.to_i, 1)
elsif t_name_filter.index(/[\d]{4}/) != nil and t_name_filter[0,4].to_i >= 1970
@page_year = t_name_filter[0,4]
@page_date = Date.new(@page_year.to_i, 1, 1)
end
rescue
@page_year = ""
@page_month = ""
@page_day = ""
@page_date = nil
return
end
end
def make_page_title
return if @page_title == ""
@t_page_title = String.new(@page_title)
@t_page_title.gsub!("@year", @page_year)
@t_page_title.gsub!("@month", @page_month)
@t_page_title.gsub!("@day", @page_day)
begin
@t_page_title.gsub!("@subtitle", @images[0].subtitle)
rescue
end
end
def format_links(count)
page_count = (count - 1) / @num + 1
current_page = @start / @num + 1
first_page = current_page - (MAX_PAGES / 2 - 1)
if first_page < 1
first_page = 1
end
last_page = first_page + MAX_PAGES - 1
if last_page > page_count
last_page = page_count
end
buf = "\n"
if current_page > 1
buf << format_link("«先頭へ ", 0, 0, @mode)
buf << format_link("<前へ", @start - @num, @num, @mode)
end
if first_page > 1
buf << "... "
end
for i in first_page..last_page
if i == current_page
buf << "#{i} "
else
buf << format_link(i.to_s, (i - 1) * @num, @num, @mode)
end
end
if last_page < page_count
buf << "... "
end
if current_page < page_count
buf << format_link("次へ>", @start + @num, @num, @mode)
buf.concat(format_link(" 最後へ»", (page_count - 1) * @num, 0, @mode))
end
buf << "
\n"
return buf
end
def format_link(label, start, num, mode)
return format('%s ',
_(@cgi.script_name ? @cgi.script_name : ''),
mode,
make_cgi_param,
start, label)
end
def format_links_viewer
buf = "\n"
if @start == 0
buf << "«前へ"
else
buf << format_link_viewer("«前へ", @image_keys[@start - 1])
end
buf << " | "
buf << format_link("一覧へ", (@start / @num) * @num, 0, "list")
buf << " | "
if @start == @image_keys.length - 1
buf << "次へ»"
else
buf << format_link_viewer("次へ»", @image_keys[@start + 1])
end
buf << "
\n"
return buf
end
def format_link_viewer(label, key)
return format('%s ',
_(@cgi.script_name ? @cgi.script_name : ''),
make_cgi_param,
key, label)
end
def format_link_viewer_image(key)
return format('%s?%smode=viewer;key=%s',
_(@cgi.script_name ? @cgi.script_name : ''),
make_cgi_param,
key)
end
def format_links_date
return "" unless @name_filter != "" and @title_filter == "" and @subtitle_filter == ""
begin
buf = "\n"
if @page_day != ""
yesterday = (@page_date - 1).strftime("%Y%m%d")
tomorrow = (@page_date + 1).strftime("%Y%m%d")
buf << format_link_date(%Q[«#{(@page_date - 1).to_s}], yesterday)
buf << format(' | %s | ', _(@cgi.script_name ? @cgi.script_name : ''), _(@mode), _(@order), '全画像')
buf << format_link_date(%Q[#{(@page_date + 1).to_s}»], tomorrow)
elsif @page_month != ""
prevmonth = (@page_date << 1).strftime("%Y%m")
nextmonth = (@page_date >> 1).strftime("%Y%m")
if @name_filter[0] == ?^ and @name_filter[5] == ?/
prevmonth = %Q[^#{prevmonth[0,4]}/#{prevmonth}]
nextmonth = %Q[^#{nextmonth[0,4]}/#{nextmonth}]
elsif @name_filter[0] == ?^
prevmonth = %Q[^#{prevmonth[0,4]}]
nextmonth = %Q[^#{nextmonth[0,4]}]
end
buf << format_link_date(%Q[«#{(@page_date << 1).to_s[0,7]}], prevmonth)
buf << format(' | %s | ', _(@cgi.script_name ? @cgi.script_name : ''), _(@mode), _(@order), '全画像')
buf << format_link_date(%Q[#{(@page_date >> 1).to_s[0,7]}»], nextmonth)
elsif @page_year != ""
year = @page_year.to_i
buf << format_link_date(%Q[«#{(year - 1).to_s}], "^"+(year - 1).to_s)
buf << format(' | %s | ', _(@cgi.script_name ? @cgi.script_name : ''), _(@mode), _(@order), '全画像')
buf << format_link_date(%Q[#{(year + 1).to_s}»], "^"+(year + 1).to_s)
end
buf << "
\n"
return buf
rescue
return ""
end
end
def format_link_date(label, name_filter)
cgi_params = make_cgi_param
if cgi_params.gsub!(/name=[^;]*;/, "name=#{CGI::escape(name_filter)};") == nil
cgi_params = "name=" + CGI::escape(name_filter) + ";" + cgi_params
end
return format('%s ',
_(@cgi.script_name ? @cgi.script_name : ''),
@mode,
cgi_params,
label)
end
def format_link_viewer_date(label, name_filter)
return format('%s ',
_(@cgi.script_name ? @cgi.script_name : ''),
CGI::escape(name_filter),
label)
end
def format_link_viewer_category(subtitle)
buf = ""
subtitle.scan(/\[[^\]]*\]/).each do |category|
tag = category[1..-2]
next if tag[0] == ?[
buf << format('[%s ]',
_(@cgi.script_name ? @cgi.script_name : ''),
CGI::escape("\\[" + tag + "\\]"), tag)
end
return buf
end
def format_link_list_category(images)
categories = []
images.each do |image|
categories |= image.subtitle.scan(/\[[^\]]*\]/)
end
buf = ""
categories.each do |category|
tag = category[1..-2]
next if tag[0] == ?[
buf << format('[%s ]',
_(@cgi.script_name ? @cgi.script_name : ''),
CGI::escape("\\[" + tag + "\\]"), tag)
end
return buf
end
def get_other_mode_link
case @mode
when "list"
format_link("[SLIDESHOW]", @start, @num, "slide") + format_link("[SLIDESHOW(FullScreen)]", @start, @num, "fslide")
when "slide"
format_link("[LIST]", @start, @num, "list") + format_link("[SLIDESHOW(FullScreen)]", @start, @num, "fslide")
when "fslide"
format_link("[LIST]", @start, @num, "list") + format_link("[SLIDESHOW]", @start, @num, "slide")
end
end
def make_cgi_param
buf = ""
buf << "name=#{CGI::escape(@name_filter)};" if @name_filter != ""
buf << "title=#{CGI::escape(@title_filter)};" if @title_filter != ""
buf << "subtitle=#{CGI::escape(@subtitle_filter)};" if @subtitle_filter != ""
buf << "pagetitle=#{CGI::escape(@page_title)};" if @page_title != ""
buf << "showinputfield=false;" if not @show_inputfield
buf << "order=#{@order};"
return buf
end
def format_options(options, value)
return options.collect { |val, label|
if val == value
"#{_(label)} "
else
"#{_(label)} "
end
}.join("\n")
end
def format_form
@order_options = format_options(ORDER_OPTIONS, @order)
@mode_options = format_options(MODE_OPTIONS, @mode )
end
def _(str)
CGI::escapeHTML(str)
end
def read_exif_data(file)
exifstr = []
str = ""
exif = ExifParser.new(file)
return exifstr if exif == nil
exifstr.push("-- IFD0 (main image) --")
exif.each(:IFD0) do |tag|
next if tag.name == "Unknown"
str = "#{tag.name} : #{tag.to_s}"
exifstr.push(str)
end
exifstr.push("-- Exif SubIFD --")
exif.each(:Exif) do |tag|
next if tag.name == "Unknown"
str = "#{tag.name} : #{tag.to_s}"
exifstr.push(str)
end
exifstr.push("-- MakerNote --")
exif.each(:MakerNote) do |tag|
next if tag.name == "Unknown" or tag.name == "NikonCameraSerialNumber"
str = "#{tag.name} : #{tag.to_s}"
exifstr.push(str)
end
exifstr.push("-- GPS --")
exif.each(:GPS) do |tag|
next if tag.name == "Unknown"
str = "#{tag.name} : #{tag.to_s}"
exifstr.push(str)
end
return exifstr
end
def js_start_gallery
if @mode == "fslide"
<<-EOS
EOS
elsif @mode == "slide"
<<-EOS2
EOS2
end
end
end
end
begin
@cgi = CGI::new
if TDiary::Config.instance_method(:initialize).arity == 0
# for tDiary 2.0 or earlier
conf = TDiary::Config::new
else
# for tDiary 2.1 or later
request = TDiary::Request.new( ENV, @cgi )
conf = TDiary::Config::new(@cgi, request)
end
tdiary = TDiary::TDiaryGallery::new( @cgi, 'gallery.rhtml', conf )
head = {
'type' => 'text/html',
'Vary' => 'User-Agent'
}
body = tdiary.eval_rhtml
head['charset'] = conf.encoding
head['Content-Length'] = body.bytesize.to_s
head['Pragma'] = 'no-cache'
head['Cache-Control'] = 'no-cache'
print @cgi.header( head )
print body
rescue Exception
if @cgi then
print @cgi.header( 'type' => 'text/plain' )
else
print "Content-Type: text/plain\n\n"
end
puts "#$! (#{$!.class})"
puts ""
puts $@.join( "\n" )
end
tdiary-contrib-5.1.0/util/image-gallery/js/ 0000775 0000000 0000000 00000000000 13570131474 0020564 5 ustar 00root root 0000000 0000000 tdiary-contrib-5.1.0/util/image-gallery/js/SmoothGallery/ 0000775 0000000 0000000 00000000000 13570131474 0023355 5 ustar 00root root 0000000 0000000 tdiary-contrib-5.1.0/util/image-gallery/js/SmoothGallery/Changelog 0000664 0000000 0000000 00000004123 13570131474 0025167 0 ustar 00root root 0000000 0000000 v1.0:
* Initial release
v1.0.1:
* Fixed bug in jd.gallery.js that prevented more than 10 images in
carousel.
* Fixed bug in resizer.php that prevented filenames with extensions in
uppercase.
v1.2:
* Fixed thumbGenerator name
* Fixed jumping thumbnails bug
* In options:
- Added useExternalCarousel (boolean, with carouselElement as an element)
- Added populateFrom option (element)
- Added showCarouselLabel option (boolean)
- Added activateCarouselScroller (boolean)
- Added slideInfoZoneSlide (boolean)
* Switched to mootools 1.11
* Added plugin support for digitarald's history manager
* Made a version compatible with name-spaced mootools (to be used with prototype, jquery or others)
v2.0:
* Code got cleaner, with some refactored functions. Should still be 80% backward-compatible.
* Gallery Set (to select which gallery you want to see and switch between galleries) mode.
> (replaces the buggy picture wall in earlier betas).
* Changed populate functions (more modular)
* Added Flush and recreate functions for slides and carousel
* Added transitions engine
* Real preloader for the slides.
* Preloader for the carousel thanks to Tomocchino's preloader class.
* In options:
- Added options related to new features
- Added thumbIdleOpacity (float)
- Allowed carouselElement to be an ID of the element (string)
- Added thumbCloseCarousel (boolean)
- Added carouselHorizontal (boolean) to prevent spliting the carousel in multiple lines if it's horizontal (default: true)
* Transitions (change the effect using defaultTransition option):
- Old default is fade.
- Real Cross-Fading for transparent PNGs: crossfade.
- Fading to background: fadebg.
- Some example of a neat fade&slide effect: fadeslideleft.
- Continuous scrolling :
+ continuoushorizontal
+ continuousvertical
v2.1beta1:
* Compatible with mootools 1.2
* Fixed carouselHorizontal
* Fixed external carousel bug
* Update History manager from Digitarald
* Added plugin support for digitarald's ReMooz (demozoom.html to see it) tdiary-contrib-5.1.0/util/image-gallery/js/SmoothGallery/css/ 0000775 0000000 0000000 00000000000 13570131474 0024145 5 ustar 00root root 0000000 0000000 tdiary-contrib-5.1.0/util/image-gallery/js/SmoothGallery/css/ReMooz.css 0000664 0000000 0000000 00000005671 13570131474 0026103 0 ustar 00root root 0000000 0000000 .remooz-element
{
cursor: -moz-zoom-in;
}
/**
* Box layout
*/
.remooz-box
{
position: absolute;
top: 0;
left: 0;
background: #000 no-repeat center;
z-index: 100;
}
.remooz-loading
{
background-image: url(spinner.gif);
}
.remooz-body
{
width: 100%;
height: 100%;
}
.remooz-box-focus.remooz-type-image .remooz-body
{
cursor: -moz-zoom-out;
}
.remooz-box-dragging .remooz-body
{
cursor: move;
}
/**
* Close button
*/
.remooz-btn-close
{
position: absolute;
left: -15px;
top: -15px;
width: 30px;
height: 30px;
text-decoration: none;
border: 0;
background: url(closebox.png) no-repeat center;
visibility: hidden;
cursor: pointer;
}
.remooz-engine-trident4 .remooz-btn-close
{
background-image: url(closebox.gif);
}
/**
* Caption title
*/
.remooz-title
{
position: relative;
left: 0;
top: 15px;
text-align: left;
}
.remooz-title-bg
{
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-color: #000;
z-index: 99;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
/* shadow opacity differs from box shadow because its default set to opacity 0.8 */
-webkit-box-shadow: 0 0 10px rgba(0, 0, 0, 0.9);
}
.remooz-title-content
{
position: relative;
padding: 5px 15px;
color: #fff;
z-index: 101;
font: 11px/1.5 Verdana, Geneva, Arial, Helvetica, sans-serif;
}
.remooz-engine-trident4 .remooz-title-bg
{
display: none;
}
.remooz-engine-trident4 .remooz-title-content
{
background-color: #333;
}
.remooz-title-content h6
{
font-size: 1.2em;
font-weight: bold;
color: #eee;
}
.remooz-title-content p
{
color: #eee;
}
/**
* Type specific
*/
.remooz-type-image img
{
display: block;
border: 0;
width: 100%;
height: 100%;
}
/**
* Shadow
*/
.remooz-bg
{
position: absolute;
width: 33px;
height: 40px;
}
.remooz-bg-n
{
left: 0;
top: -40px;
width: 100%;
background: url(remo_bg_n.png) repeat-x;
}
.remooz-bg-ne
{
right: -33px;
top: -40px;
background: url(remo_bg_ne.png) no-repeat;
}
.remooz-bg-e
{
right: -33px;
top: 0;
height: 100%;
background: url(remo_bg_e.png) repeat-y;
}
.remooz-bg-se
{
right: -33px;
bottom: -40px;
background: url(remo_bg_se.png) no-repeat;
}
.remooz-bg-s
{
left: 0;
bottom: -40px;
width: 100%;
background: url(remo_bg_s.png) repeat-x;
}
.remooz-bg-sw
{
left: -33px;
bottom: -40px;
background: url(remo_bg_sw.png) no-repeat;
}
.remooz-bg-w
{
left: -33px;
top: 0;
height: 100%;
background: url(remo_bg_w.png) repeat-y;
}
.remooz-bg-nw
{
left: -33px;
top: -40px;
background: url(remo_bg_nw.png) no-repeat;
}
tdiary-contrib-5.1.0/util/image-gallery/js/SmoothGallery/css/img/ 0000775 0000000 0000000 00000000000 13570131474 0024721 5 ustar 00root root 0000000 0000000 tdiary-contrib-5.1.0/util/image-gallery/js/SmoothGallery/css/img/carrow1.gif 0000664 0000000 0000000 00000000363 13570131474 0026770 0 ustar 00root root 0000000 0000000 GIF89a +++,,,222...000111///
***!!!###---
&&& 333 ! , p'$Ag E[u0ϋ`B1*Bap$)!y&)#T dC',D{ kvg,ޑ9R~wOK)BE)@B>737$.! ; tdiary-contrib-5.1.0/util/image-gallery/js/SmoothGallery/css/img/carrow2.gif 0000664 0000000 0000000 00000000361 13570131474 0026767 0 ustar 00root root 0000000 0000000 GIF89a +++,,,222...000111///
***!!!###---
&&& 333 ! , n'AhRGeK,]:'`+
!8y$H
Qa5Gh >>DN;(E]HS(F{$N6AC>"@D" "! ; tdiary-contrib-5.1.0/util/image-gallery/js/SmoothGallery/css/img/closebox.gif 0000664 0000000 0000000 00000000537 13570131474 0027233 0 ustar 00root root 0000000 0000000 GIF89a eee%%%===***000qqqRRRMMMBBB! , ` "2B1p
Bb;t H$
:^!l$ǩ8TtH4+#\&Md`%A$0A]B1z~
B&Ny`A(WyN'W{'NyB&]iAyB*AVBfp ."
aWd; MH$