# # 00default.rb: default plugins # # Copyright (C) 2010, TADA Tadashi # You can redistribute it and/or modify it under GPL2 or any later version. # # # setting @date # unless @date if @diary then @date = @diary.date else @date = case @mode when 'day' Time::local( *@cgi.params['date'][0].scan( /^(\d{4})(\d\d)(\d\d)/ ).flatten ) when 'month' Time::local( *@cgi.params['date'][0].scan( /^(\d{4})(\d\d)/ ).flatten ) when 'edit' Time::local( @cgi.params['year'][0].to_i, @cgi.params['month'][0].to_i, @cgi.params['day'][0].to_i ) else nil end end end # # make navigation buttons # def navi result = %Q[
\n] result << navi_user result << navi_admin result << %Q[
] end def navi_item( link, label, rel = nil ) result = %Q[#{label}\n] end def navi_user result = navi_user_default case @mode when 'latest' result << navi_user_latest when 'day' result << navi_user_day when 'month' result << navi_user_month when 'nyear' result << navi_user_nyear when 'edit' result << navi_user_edit else result << navi_user_else end result end def navi_user_default result = '' result << navi_item( h(@conf.index_page), h(navi_index) ) unless @conf.index_page.empty? result end def navi_user_latest result = '' result << navi_item( "#{h @conf.index}#{anchor( @conf['ndays.prev'] + '-' + @conf.latest_limit.to_s )}", "«#{navi_prev_ndays}", "next" ) if @conf['ndays.prev'] and not bot? result << navi_item( h(@conf.index), h(navi_latest) ) if @cgi.params['date'][0] result << navi_item( "#{h @conf.index}#{anchor( @conf['ndays.next'] + '-' + @conf.latest_limit.to_s )}", "#{navi_next_ndays}»", "prev") if @conf['ndays.next'] and not bot? result end def navi_user_day result = '' if @navi_user_days then result << navi_item( "#{h @conf.index}#{anchor @navi_user_days[0]}", "«#{h navi_prev_diary(navi_user_format(@navi_user_days[0]))}" ) if @navi_user_days[0] result << navi_item( h(@conf.index), h(navi_latest) ) result << navi_item( "#{h @conf.index}#{anchor @navi_user_days[2]}", "#{h navi_next_diary(navi_user_format(@navi_user_days[2]))}»" ) if @navi_user_days[2] end result end def navi_user_month 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] result = '' result << navi_item( "#{h @conf.index}#{anchor( prev_month )}", "«#{h navi_prev_month}" ) if prev_month and not bot? result << navi_item( h(@conf.index), h(navi_latest) ) result << navi_item( "#{h @conf.index}#{anchor( next_month )}", "#{h navi_next_month}»" ) if next_month and not bot? result end def navi_user_nyear result = '' result << navi_item( "#{h @conf.index}#{anchor @prev_day[4,4]}", "«#{h navi_prev_nyear(Time::local(*@prev_day.scan(/^(\d{4})(\d\d)(\d\d)$/)[0]))}" ) if @prev_day result << navi_item( h(@conf.index), h(navi_latest) ) unless @mode == 'latest' result << navi_item( "#{h @conf.index}#{anchor @next_day[4,4]}", "#{h navi_next_nyear(Time::local(*@next_day.scan(/^(\d{4})(\d\d)(\d\d)$/)[0]))}»" ) if @next_day result end def navi_user_edit result = '' if @prev_day then a = @prev_day.scan( /^(\d{4})(\d\d)(\d\d)$/ ).flatten result << navi_item( "#{h @conf.update}?edit=true;year=#{a[0]};month=#{a[1]};day=#{a[2]}", "«#{h navi_prev_diary(Time::local(*@prev_day.scan(/^(\d{4})(\d\d)(\d\d)$/)[0]))}" ) end result << navi_item( h(@conf.index), h(navi_latest) ) if @next_day then a = @next_day.scan( /^(\d{4})(\d\d)(\d\d)$/ ).flatten result << navi_item( "#{h @conf.update}?edit=true;year=#{a[0]};month=#{a[1]};day=#{a[2]}", "#{h navi_next_diary(Time::local(*@next_day.scan(/^(\d{4})(\d\d)(\d\d)$/)[0]))}»" ) end result end def navi_user_else navi_item( h(@conf.index), h(navi_latest) ) end def navi_user_format( day ) Time::local( *day.scan( /^(\d{4})(\d\d)(\d\d)$/ )[0] ) end def navi_admin if @mode == 'day' then result = navi_item( "#{h @conf.update}?edit=true;year=#{@date.year};month=#{@date.month};day=#{@date.day}", h(navi_edit), "nofollow" ) else result = navi_item( h(@conf.update), h(navi_update), "nofollow") end result << navi_item( "#{h @conf.update}?conf=default", h(navi_preference) ) if /^(latest|month|day|comment|conf|nyear|category.*)$/ !~ @mode result end def mobile_navi result = [] if @navi_user_days and @navi_user_days[0] result << %Q[[*]#{mobile_navi_prev_diary}] end if @mode != 'latest' result << %Q[[0]#{mobile_navi_latest}] end if @navi_user_days and @navi_user_days[2] result << %Q[[#]#{mobile_navi_next_diary}] end if @mode == 'day' then result << %Q[[5]#{mobile_navi_edit}] else result << %Q[[5]#{mobile_navi_update}] end result << %Q[[8]#{mobile_navi_preference}] unless /^(latest|month|day|conf|nyear)$/ === @mode result.join('|') end # # make calendar # def calendar result = %Q[
\n] @years.keys.sort.each do |year| result << %Q[
#{year}|] @years[year.to_s].sort.each do |month| m = "#{year}#{month}" result << %Q[#{month}|] end result << "
\n" end result << "
" end # # insert file # def insert( file ) begin File::readlines( file ).join rescue %Q[

#$! (#{h $!.class})
cannot read #{h file}.

] end end # # define DOCTYPE # def doctype %Q|| end # # default HTML header # add_header_proc do calc_links <<-HEADER #{author_name_tag} #{author_mail_tag} #{index_page_tag} #{icon_tag} #{ogp_tag} #{description_tag} #{css_tag.chomp} #{jquery_tag.chomp} #{script_tag.chomp} #{title_tag.chomp} #{robot_control.chomp} HEADER end def calc_links if /day|edit/ =~ @mode then today = @date.strftime('%Y%m%d') days = [] yms = [] this_month = today[0,6] @years.keys.each do |y| yms += @years[y].collect {|m| y + m} end yms |= [this_month] yms.sort! yms.unshift(nil).push(nil) yms[yms.index(this_month) - 1, 3].each do |ym| next unless ym now = @cgi.params['date'] # backup cgi = @cgi.clone cgi.params['date'] = [ym] m = TDiaryMonthWithoutFilter.new(cgi, '', @conf) @cgi.params['date'] = now # restore m.diaries.delete_if {|date,diary| !diary.visible?} days += m.diaries.keys.sort end days |= [today] days.sort! days.unshift(nil).push(nil) @navi_user_days = days[days.index(today) - 1, 3] @prev_day = @navi_user_days[0] @next_day = @navi_user_days[2] elsif @mode == 'nyear' y = 2000 # specify leam year m, d = @cgi.params['date'][0].scan(/^(\d\d)(\d\d)$/)[0] @prev_day = (Time.local(y, m, d) - 24*60*60).strftime( '%Y%m%d' ) @next_day = (Time.local(y, m, d) + 24*60*60).strftime( '%Y%m%d' ) end end def charset @conf.encoding end def last_modified_header '' end def content_script_type '' end def author_name_tag if @conf.author_name and not(@conf.author_name.empty?) then %Q[] else '' end end def author_mail_tag if @conf.author_mail and not(@conf.author_mail.empty?) then %Q[] else '' end end def index_page_tag result = '' if @conf.index_page and @conf.index_page.size > 0 then result << %Q[\n\t] end if @prev_day then case @mode when 'day' result << %Q[\n\t] when 'nyear' result << %Q[\n\t] end end if @next_day then case @mode when 'day' result << %Q[\n\t] when 'nyear' result << %Q[\n\t] end end result << %Q[\n\t] result.chop.chop end def icon_tag if @conf.icon and not(@conf.icon.empty?) then if /\.ico$/ =~ @conf.icon then %Q[] elsif /\.svg$/ =~ @conf.icon then %Q[] else %Q[] end else '' end end def ogp_tag ogp = { 'og:title' => title_tag.gsub(/<[^>]*>/, ""), } if @conf.banner && !@conf.banner.empty? ogp['og:image'] = @conf.banner end uri = @conf.index.dup uri[0, 0] = base_url if %r|^https?://|i !~ @conf.index uri.gsub!( %r|/\./|, '/' ) if @mode == 'day' then ogp['og:type'] = 'article' ogp['article:author'] = @conf.author_name ogp['og:site_name'] = @conf.html_title ogp['og:url'] = uri + anchor( @date.strftime( '%Y%m%d' ) ) else ogp['og:type'] = 'website' ogp['og:description'] = @conf.description ogp['og:url'] = uri end ogp.map { |k, v| %Q|| }.join("\n") end def description_tag if @conf.description and not(@conf.description.empty?) then %Q[] else '' end end def jquery_tag %Q[] end enable_js( '00default.js', async: false ) add_js_setting( '$tDiary.style', "'#{@conf.style.downcase.sub( /\Ablog/, '' )}'" ) if /^form|edit|preview|showcomment/ =~ @mode enable_js( '02edit.js', async: true ) end def script_tag_query_string "?#{TDIARY_VERSION}#{Time::now.strftime('%Y%m%d')}" end def js_url @cgi.is_a?(RackCGI) ? 'assets' : 'js' end def script_tag require 'uri' query = script_tag_query_string html = @javascripts.keys.sort.map {|script| async = @javascripts[script][:async] ? "async" : "" if URI(script).scheme or script =~ %r|\A//| %Q|| else %Q|| end }.join( "\n\t" ) html << "\n" << <<-HEAD HEAD end def theme_url @cgi.is_a?(RackCGI) ? 'assets' : 'theme' end def css_tag location, name = (@conf.theme || '').split(%r[/], 2) if @mode =~ /conf$/ then css = "#{h theme_url}/conf.css" elsif name && name.length > 0 css = __send__("theme_url_#{location}", name) css = theme_url_local('default') unless css # the location is not defined else css = @conf.css end title = File::basename( css, '.css' ) <<-CSS CSS end def robot_control if /^form|edit|preview|showcomment$/ =~ @mode then '' else '' end end # # title of day # add_title_proc do |date, title| title_of_day( date, title ) end def title_of_day( date, title ) r = <<-HTML #{date.strftime @conf.date_format} #{title} HTML return r.gsub( /^\t+/, '' ).chomp end add_title_proc do |date, title| nyear_link( date, title ) end def nyear_link( date, title ) if @conf.show_nyear and @mode != 'nyear' then m = date.strftime( '%m' ) d = date.strftime( '%d' ) years = @years.find_all {|year, months| months.include? m} if years.length >= 2 then %Q|#{title} [#{nyear_diary_label}]| else title end else title end end # # make anchor string # def anchor( s ) if /^([\-\d]+)#?([pct]\d*)?$/ =~ s then if $2 then "?date=#$1##$2" else "?date=#$1" end else "" end end # # subtitle # add_subtitle_proc do |date, index, subtitle| subtitle_link( date, index, subtitle ) end def make_category_link( subtitle ) r = '' if subtitle if respond_to?( :category_anchor ) then r << subtitle.sub( /^(\[([^\[]+?)\])+/ ) do $&.gsub( /\[(.*?)\]/ ) do $1.split( /,/ ).collect do |c| category_anchor( "#{CGI::unescapeHTML c}" ) end.join end end else r << subtitle end end r end def subtitle_link( date, index, subtitle ) r = '' if date then r << "#{@conf.section_anchor} ] end r << %Q[(#{h @author}) ] if @multi_user and @author and subtitle r << make_category_link( subtitle ) end # # make anchor tag in my diary # def my( a, str, title = nil ) date, _, frag = a.scan( /^(\d{4}|\d{6}|\d{8}|\d{8}-\d+)([^\d]*)?#?([pct]\d+)?$/ )[0] anc = frag ? "#{date}#{frag}" : date index = /^https?:/ =~ @conf.index ? '' : base_url index += @conf.index.sub(%r|^\./|, '') if title then %Q[#{str}] else %Q[#{str}] end end # # other resources # def submit_command if @mode == 'form' or @cgi.valid?( 'appendpreview' ) then 'append' else 'replace' end end def preview_command if @mode == 'form' or @cgi.valid?( 'appendpreview' ) then 'appendpreview' else 'replacepreview' end end # # make comment form # def comment_description begin if @conf.options['comment_description'].length > 0 then return @conf.options['comment_description'] end rescue end comment_description_default end def comment_form_text unless @diary then @diary = @diaries[@date.strftime( '%Y%m%d' )] return '' unless @diary end r = '' unless @conf.hide_comment_form then r = <<-FORM
FORM if @diary.count_comments( true ) >= @conf.comment_limit_per_day then r << <<-FORM FORM else r << <<-FORM
#{comment_name_label}:
#{comment_mail_label}:
#{comment_body_label}:
FORM end r << <<-FORM
FORM end r end add_footer_proc do if @mode != 'day' or bot? then '' elsif hide_comment_day_limit r = '' r << <<-JS JS else '' end end def comment_form return '' unless @mode == 'day' return '' if bot? return '' if hide_comment_day_limit comment_form_text end def hide_comment_day_limit if @conf.options.include?('spamfilter.date_limit') && @conf.options['spamfilter.date_limit'] && /\A\d+\z/ =~ @conf.options['spamfilter.date_limit'].to_s date_limit = @conf.options['spamfilter.date_limit'].to_s.to_i now = Time.now today = Time.local(now.year, now.month, now.day) limit = today - 24 * 60 * 60 * date_limit if @date < limit return true end end return false end # # service methods for comment_mail # def comment_mail_mime( str ) require 'nkf' NKF::nkf("-w -m0 -f30", str).lines.map do |s| %Q|=?UTF-8?B?#{[s.chomp].pack('m').gsub(/\n/, '')}?=| end end def comment_mail_send return unless @comment return unless @conf['comment_mail.enable'] return unless @conf['comment_mail.sendhidden'] or @comment.visible? case @conf['comment_mail.receivers'] when Array # for compatibility receivers = @conf['comment_mail.receivers'] when String receivers = @conf['comment_mail.receivers'].split( /[, ]+/ ) else receivers = [] end receivers = [@conf.author_mail] if receivers.compact.empty? return if receivers.empty? name = comment_mail_mime(@comment.name)[0] body = @comment.body.sub( /[\r\n]+\Z/, '' ) mail = @comment.mail mail = @conf.author_mail unless mail =~ %r<[0-9a-zA-Z_.-]+@[\(\)%!0-9a-zA-Z_$@.&+-,'"*-]+> mail = receivers[0] if mail.empty? now = Time::now g = now.dup.gmtime l = Time::local( g.year, g.month, g.day, g.hour, g.min, g.sec ) tz = (g.to_i - l.to_i) / 36 date = now.strftime( "%a, %d %b %Y %X " ) + sprintf( "%+05d", tz ) require 'socket' serial = @diaries[@date.strftime( '%Y%m%d' )].count_comments( true ) message_id = %Q!! subject_header = (@conf['comment_mail.header'] || '').dup subject_header << ":#{@conf.date_format}" unless /%[a-zA-Z%]/ =~ subject_header subject_header = @date.strftime(subject_header) subject_header = comment_mail_mime(subject_header).join("\n ") rmail = File::open("#{TDiary::PATH}/../views/mail.rtxt").read header = ERB::new(rmail).result(binding) text = NKF.nkf('-w -MB', [ body, "-- ", "#{@conf.index =~ %r|^https?://|i ? '': @conf.base_url}#{@conf.index.sub(%r|^\./|, '')}#{anchor(@date.strftime('%Y%m%d') + ('#c%02d' % serial))}", "IP: #{@cgi.remote_addr}", "Status: #{@comment.visible? ? 'shown' : 'hidden'}" ].join("\r\n")) comment_mail([header, text].join("\r\n"), receivers) end def comment_mail( text ) # no action in default. # override by each plugins. end def comment_mail_basic_setting if @mode == 'saveconf' then @conf['comment_mail.enable'] = @cgi.params['comment_mail.enable'][0] == 'true' ? true : false @conf['comment_mail.receivers'] = @cgi.params['comment_mail.receivers'][0].strip.gsub( /[\n\r]+/, ',' ) @conf['comment_mail.header'] = @cgi.params['comment_mail.header'][0] @conf['comment_mail.sendhidden'] = @cgi.params['comment_mail.sendhidden'][0] == 'true' ? true : false end end # # convert to UTF-8 # def to_utf8( str, charset = nil ) @conf.to_native( str, charset ) end # # layout # def brr; '
'; end def brl; '
'; end # # preferences (saving methods) # if @mode =~ /conf|saveconf/ enable_js( '01conf.js', async: true ) end # basic (default) def saveconf_default if @mode == 'saveconf' then @conf.html_title = @conf.to_native( @cgi.params['html_title'][0] ) @conf.author_name = @conf.to_native( @cgi.params['author_name'][0] ) @conf.author_mail = @cgi.params['author_mail'][0] @conf.index_page = @cgi.params['index_page'][0] @conf.description = @conf.to_native( @cgi.params['description'][0] ) @conf.icon = @cgi.params['icon'][0] @conf.banner = @cgi.params['banner'][0] @conf['base_url'] = @cgi.params['base_url'][0] @conf.x_frame_options = @cgi.params['x_frame_options'][0] @conf.x_frame_options = nil if @conf.x_frame_options.empty? end end # header/footer (header) def saveconf_header if @mode == 'saveconf' then @conf.header = @conf.to_native( @cgi.params['header'][0] ).lines.map(&:chomp).join( "\n" ).sub( /\n+\z/, '' ) @conf.footer = @conf.to_native( @cgi.params['footer'][0] ).lines.map(&:chomp).join( "\n" ).sub( /\n+\z/, '' ) end end # diaplay def saveconf_display if @mode == 'saveconf' then @conf.section_anchor = @conf.to_native( @cgi.params['section_anchor'][0] ) @conf.comment_anchor = @conf.to_native( @cgi.params['comment_anchor'][0] ) @conf.date_format = @conf.to_native( @cgi.params['date_format'][0] ) @conf.latest_limit = @cgi.params['latest_limit'][0].to_i @conf.latest_limit = 10 if @conf.latest_limit < 1 @conf.show_nyear = @cgi.params['show_nyear'][0] == 'true' ? true : false end end # timezone def saveconf_timezone if @mode == 'saveconf' then @conf.hour_offset = @cgi.params['hour_offset'][0].to_f end end # themes def conf_theme_list r = '' t = -1 @conf_theme_list.each_with_index do |theme, index| if theme[0] == @conf.theme then select = " selected" t = index end r << %Q|| end img = t == -1 ? 'nowprinting' : @conf.theme.sub(/^.*\//, '') r << <<-HTML

#{@theme_thumbnail_label}

#{@theme_location_comment} HTML end def theme_list_local(list) Dir::glob( theme_paths_local ).sort.map {|dir| theme = dir.sub( %r[.*/theme/], '') next unless FileTest::file?( "#{dir}/#{theme}.css" ) name = theme.split( /_/ ).collect{|s| s.capitalize}.join( ' ' ) list << ["local/#{theme}",name] } list end def theme_url_local(theme) "#{h theme_url}/#{h theme}/#{h theme}.css" end def theme_paths_local [::TDiary::PATH, TDiary.server_root].map {|d| "#{d}/theme/*" } end def saveconf_theme if @mode == 'saveconf' then @conf.theme = @cgi.params['theme'][0] @conf.css = @cgi.params['css'][0] end @conf_theme_list = methods.inject([]) {|conf_theme_list, method| if /^theme_list_/ =~ method.to_s __send__(method, conf_theme_list) else conf_theme_list end }.sort.compact.uniq end # comments def saveconf_comment if @mode == 'saveconf' then @conf.show_comment = @cgi.params['show_comment'][0] == 'true' ? true : false @conf.comment_limit = @cgi.params['comment_limit'][0].to_i @conf.comment_limit = 3 if @conf.comment_limit < 1 @conf.comment_limit_per_day = @cgi.params['comment_limit_per_day'][0].to_i @conf.comment_limit_per_day = 0 if @conf.comment_limit_per_day < 0 end end def saveconf_csrf_protection if @mode == 'saveconf' then err = nil check_method = 0 case @cgi.params['check_enabled'] when ['true'] else err = :param end case @cgi.params['check_referer'] when ['true'] check_method |= 1 when ['false'] check_method |= 0 else err = :param end case @cgi.params['check_key'] when ['true'] check_method |= 2 when ['false'] check_method |= 0 else err = :param end err = :param if check_method == 0 check_key = '' key_seed = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' 1.upto(30) do check_key << key_seed[rand( key_seed.length )] end if check_method & 2 != 0 && (!check_key || check_key == '') then err ||= :key end unless err old_key = @conf['csrf_protection_key'] old_method = @conf['csrf_protection_method'] @conf['csrf_protection_method'] = check_method @conf['csrf_protection_key'] = check_key if (check_method & 2 == 2 && (old_method & 2 == 0 || old_key != check_key)) @conf.save raise ForceRedirect, "#{h @conf.update}?conf=csrf_protection#{@cgi.referer ? '&referer_exists=true' : ''}" end end err else nil end end def saveconf_logger if @mode == 'saveconf' then @conf['log_level'] = @cgi.params['log_level'][0] end end def conf_logger_list log_level_list = ["DEBUG", "INFO", "WARN", "ERROR", "FATAL"] r = '' @conf['log_level'] ||= "INFO" log_level_list.each do |level| if level == @conf['log_level'] then select = " selected" end r << %Q|| end r << %Q|

| end def saveconf_recommendfilter if @mode == 'saveconf' && @cgi.params['recommend.filter'][0] == 'true' then @conf['sf.selected'] = "" @conf['comment_description'] = "ツッコミ・コメントがあればどうぞ! URIは1つまで入力可能です。" if @sp_path.inject(false){|r, dir| r || FileTest.exist?("#{dir}/hide-mail-field.rb") } if @conf['sp.selected'] @conf['sp.selected'].concat("hide-mail-field.rb\n") else @conf['sp.selected'] = "hide-mail-field.rb\n" end @conf['spamfilter.bad_mail_patts'] = "@" @conf['comment_description'].concat("spam対策でE-mail欄は隠してあります。もしE-mail欄が見えていても、何も入力しないで下さい。") end @conf['spamfilter.bad_comment_patts'] = "href=\r\nurl=\r\nURL=\r\n" @conf['spamfilter.bad_ip_addrs'] = "" @conf['spamfilter.bad_uri_patts'] = "" @conf['spamfilter.bad_uri_patts_for_mails'] = false @conf['spamfilter.date_limit'] = "7" @conf['spamfilter.debug_file'] = "" @conf['spamfilter.debug_mode'] = false @conf['spamfilter.filter_mode'] = false @conf['spamfilter.hide_commentform'] = true @conf['spamfilter.linkcheck'] = 1 @conf['spamfilter.max_rate'] = "0" @conf['spamfilter.max_uris'] = "1" @conf['spamfilter.resolv_check'] = true @conf['spamfilter.resolv_check_mode'] = false @conf['spamlookup.domain.list'] = "bsb.spamlookup.net\r\nmulti.surbl.org\r\nrbl.bulkfeeds.jp" @conf['spamlookup.ip.list'] = "dnsbl.spam-champuru.livedoor.com" @conf['spamlookup.safe_domain.list'] = "www.google.com\r\nwww.google.co.jp\r\nezsch.ezweb.ne.jp\r\nwww.yahoo.co.jp\r\nsearch.mobile.yahoo.co.jp\r\nwww.bing.com" end end # # old ruby alert # def old_ruby_alert if RUBY_VERSION < '2.0.0' and !@conf['old_ruby_alert.hide'] %Q|
× #{old_ruby_alert_message}
| else '' end end def old_ruby_alert_message "お使いのRuby #{RUBY_VERSION}は次のリリースからサポート対象外になります。" end add_conf_proc( 'old_ruby_alert', nil) do if @mode == 'saveconf' @conf['old_ruby_alert.hide'] = true end %Q|

OLD RUBY ALERT

| # dummy end # Local Variables: # mode: ruby # indent-tabs-mode: t # tab-width: 3 # ruby-indent-level: 3 # End: