require 'kconv'

@trackback_dir = "#{@plugindir}/trackback" unless @trackback_dir
@trackback_flavour = "html" unless @trackback_flavour
@recent_trackback_count = 5 unless @recent_trackback_count
@trackback_report_spam = (@trackback_report_spam.nil? || @trackback_report_spam == "on" || @trackback_report_spam == true) ? true : false
@trackback_check_revlink = false if @trackback_check_revlink.nil? || (@trackback_check_revlink != "on" && @trackback_check_revlink != true)

def trackback
  path = ""
  if @storys.size == 1 then
    reg = Regexp.new("#{@datadir}/((.*/)?[^.]*)\..*")
    @storys[0].sub(reg){ path = $1 }

    if @flavour == 'trackback' then
      if @cgi.params['__mode'][0] == 'rss' then
        File::open(@storys[0]){|f|
          @title = f.gets.chomp
          @body = f.read

          if Kconv.guess(@body) == Kconv::SJIS then
            if /[\020-\177][\200-\237]/n =~ @body or
               /[\300-\377][\000-\177\300-\377]/n =~ @body then
              @title = Uconv.sjistou8(@title)
	          @body = Uconv.sjistou8(@body)
            end
          elsif Kconv.guess(@body) == Kconv::EUC then
	        @title = Uconv.euctou8(@title)
	        @body = Uconv.euctou8(@body)
          end
        }
      
        print @cgi.header("type" => "text/xml")
        print <<EOS
<?xml version="1.0" encoding="utf-8"?>
<response>
<error>0</error>
<rss version="0.91"><channel>
<title>#{@title}</title>
<link>#{@url}#{@cgi.path_info}</link>
<description>#{rss10_shortbody}</description>
<language>#{@blog_language}</language>
EOS
        get_trackback(path){|title, url, blog_name, excerpt|
          print <<EOS
<item>
  <title>#{title}</title>
  <link>#{url}</link>
  <description>#{excerpt}</description>
</item>
EOS
        }
        
        print <<EOS
</channel>
</rss></response>
EOS
        
        @echo_off = true

        return
      end
     
      url = @cgi.params['url'][0]
      unless url
        print @cgi.header("type" => "text/html")
        print <<EOS
<?xml version="1.0" encoding="iso-8859-1"?>
<response>
<error>1</error>
<message>empty URL</message>
</response>
EOS
        @echo_off = true
        return
      end

      title = @cgi.params['title'][0] || ""
      excerpt = (@cgi.params['excerpt'][0] || "").gsub(/\r/, '')
      blog_name = @cgi.params['blog_name'][0] || ""

      if Kconv.guess(excerpt) == Kconv::JIS then
        title = Uconv.sjistou8(title.tosjis)
        url = Uconv.sjistou8(url.tosjis)
        excerpt = Uconv.sjistou8(excerpt.tosjis)
        blog_name = Uconv.sjistou8(blog_name.tosjis)
      elsif Kconv.guess(excerpt) == Kconv::EUC then
        title = Uconv.euctou8(title)
        url = Uconv.euctou8(url)
        excerpt = Uconv.euctou8(excerpt)
        blog_name = Uconv.euctou8(blog_name)
      elsif Kconv.guess(excerpt) == Kconv::SJIS then
        if /[\020-\177][\200-\237]/n =~ excerpt or
           /[\300-\377][\000-\177\300-\377]/n =~ excerpt then
          title = Uconv.sjistou8(title)
          url = Uconv.sjistou8(url)
          excerpt = Uconv.sjistou8(excerpt)
          blog_name = Uconv.sjistou8(blog_name)
        end
      end

      spam = false
      if (respond_to?(:check_spam) && check_spam(excerpt, url)) ||
         (@trackback_check_revlink && !check_revlink(url, path))
        spam = true

        print @cgi.header("type" => "text/html")
        print <<EOS
<?xml version="1.0" encoding="iso-8859-1"?>
<response>
<error>1</error>
<message>Your trackback is recognized as spam. Contact webmaster by mail if you need.</message>
</response>
EOS
        @echo_off = true

      else

        File::open("#{@trackback_dir}/#{CGI.escape(path)}","a") do |f|
          f.puts CGI.escapeHTML(title)
          f.puts CGI.escapeHTML(url)
          f.puts CGI.escapeHTML(blog_name)
          f.puts CGI.escapeHTML(excerpt)
          f.puts '--------'
          print @cgi.header("type" => "text/html")
          print <<EOS
<?xml version="1.0" encoding="iso-8859-1"?>
<response>
<error>0</error>
</response>
EOS
          @echo_off = true

          list = ""
          begin
            File::open("#{@trackback_dir}/recent.list","r"){|f|
              f.each_line do |line|
                line.chomp!
                if !line.nil? and line != ''
                  list += "#{line}\n"
                end
              end
            }
          rescue
          end
          name = ""
          if blog_name
            name = blog_name
          else
            name = title
          end
          File::open("#{@trackback_dir}/recent.list","w"){|f|
            f.print "#{path}\t#{CGI.escapeHTML(name)}\t"
            f.print "#{Time.now.strftime("%y-%m-%d")}\n"
            f.print list
          }
        end
      end

      if respond_to?(:send_mail) && (@trackback_report_spam || !spam)
        subject = "trackback to #{@url}/#{path}.#{@trackback_flavour}"
        subject = "(spam) #{subject}" if spam
        text = "#{subject}\n#{@cgi.remote_addr}\n#{title}\n#{url}\n#{blog_name}\n#{excerpt}\n"
        send_mail(nil, @mailto.untaint, subject, text)
      end
    end
  end
end

def trackback_count
  cnt = 0

  begin
    File::open("#{@trackback_dir}/#{CGI.escape(@path + @fn)}","r"){|f|
      while line = f.gets
        line.chomp!
        if line == '--------' then cnt += 1; end
      end
    }
  rescue
  end

  return cnt
end

def trackback_disp
  src = ""

  get_trackback(@path + @fn){|title, url, blog_name, excerpt|
    if /^.{0}(.{0,150})/ === excerpt
      excerpt = $1
    end

    src +=<<EOS
<div class="trackback">
<h5><a href="#{make_link(url)}">#{convert(blog_name)} : #{convert(title)}</a></h5>
#{convert(excerpt)}
</div>
EOS
  }
  
  return src
end

def get_trackback(path)

  begin
    File::open("#{@trackback_dir}/#{CGI.escape(path)}","r"){|f|
      while title = f.gets
        title.chomp!
        url = f.gets.chomp!
        blog_name = f.gets.chomp!
        excerpt = ""
        
        while line = f.gets
          line.chomp!
          if line == '--------' then break; end
          excerpt += line + "<br />"
        end
        
        if (title != '' or url != '') and excerpt != ''
          yield(title, url, blog_name, excerpt)
        end
        
      end
    }
  rescue
  end
end

def recent_trackback
  src = "<ul>\n"
  begin
    sw = {}
    File::open("#{@trackback_dir}/recent.list"){|f|
      lc = 1
      f.each_line do |ln|
        ln.chomp!
        if !ln.nil? and ln != ''
          m = ln.split(/\t/)
          src += %(<li><a href="#{@url}/#{m[0]}.html#trackback">#{m[1]} #{m[2]}</a></li>\n)
          lc += 1
          break if lc > @recent_trackback_count
        end
      end
    }
    
    src += "</ul>\n"
  rescue
  end
end

def make_link(url)
  if url =~ /(.*)\@(.*)/ then
    return "mailto:#{url}"
  elsif url =~ /http:.*/ then
    return url
  end
  
  return ""
end

def check_revlink(url, path)
  result = false
  begin
    uri = URI.parse(url)
    tpath = uri.path.empty? ? "/" : uri.path
    if uri.host == URI.parse(@url).host
      myurl = Regexp.compile(Regexp.quote(URI.parse("#{@url}/#{path}").path))
    else
      myurl = Regexp.compile(Regexp.quote("#{@url}/#{path}"))
    end
    target = Net::HTTP.start(uri.host.untaint, uri.port){|http|http.get(tpath).body}
    if myurl =~ target
      result = true
    end
  rescue
  end
  result
end
