#!/usr/bin/ruby -Ks --
=begin
= Excite エキサイト : 翻訳＞テキスト翻訳 クライアント

copyright (c) 2000-2001 ZnZ <VFC04155@nifty.ne.jp>

== 使い方
* proxyを使う場合は"localhost:8080"のようにproxyを引数にしてnewする。
* enjaまたはjaenを翻訳したい文を引数にして呼び出すと翻訳結果の文字列を返す。

* 利用前に((<翻訳利用規約|URL:http://www.excite.co.jp/world/agreement/>))を
  ご覧ください。

== 変更履歴
=== 2001.04.10
* わざと使いにくくしててもあんまり意味がなかったので、
  標準入出力も扱えるようにした。
* 対話型モードをつけた。
* Readlineがあれば使うようにした。
* win以外なら^C対策をするようにした。(winだとsttyが無い可能性があるため。)
* win以外のReadlineの対話型モードのみEUCで入出力するようにした。
* enjaかjaenを含むファイル名で呼び出された場合はその動作をするようにした。
  (その場合も引数で動作を指定することは可能です。)
=end

require 'cgi'
require 'socket'
require 'nkf'

class ExciteWorldText
  DEBUGLOG = File.join((ENV['TMP'] || ENV['TEMP'] || '/tmp'),
                       'excite_world_text.txt')

  def initialize(http_proxy=nil)
    @url = 'http://www.excite.co.jp/world/text/'

    if http_proxy
      if /^([^:]+):(\d+)$/ =~ http_proxy
        @host = $1
        @port = $2
        @path = @url
      else
        raise ArgumentError, 'http_proxy must be "host:port"'
      end
    else
      @port = 80
      raise 'url error' unless /^http:\/\/([^\/]+)(\/.*)?$/ =~ @url
      @host = $1
      @path = $2 || '/'
      if /^([^:]+):(\d+)$/ =~ @host
        @host = $1
        @port = $2.to_i
      end
    end
  end

  def translate(msg, trans_type)
    case trans_type
    when 'enja'
      enja(msg)
    when 'jaen'
      jaen(msg)
    else
      raise ArgumentError, 'trans_type must be enja or jaen'
    end
  end

  def enja(before)
    post_text = encode(NKF.nkf('-Z', before), true)
    post(post_text)
  end

  def jaen(before)
    post_text = encode(before, false)
    post(post_text)
  end

  private

  def post(post_text)
    sock = TCPSocket.open(@host, @port)

    begin
      request = "POST #{@path} HTTP/1.0\r\n"+[
        "Host: www.excite.co.jp",
        "Connection: close",
        "Referer: #{@url}",
        "Content-Type: application/x-www-form-urlencoded",
        "Content-Length: #{post_text.size}",
      ].sort.join("\r\n")+"\r\n\r\n"+post_text+"\r\n"

      sock.print request
      result = sock.read
    ensure
      sock.close
    end

    if DEBUGLOG
      open(DEBUGLOG,'w') do |f|
        f.print result
      end
    end

    if /^HTTP\/1\.\d+\s+200/ =~ result
      if /<textarea\s[^>]+name="after"[^>]*>(.+)<\/textarea>/ =~ result
        $1
      elsif /<td><font size=-1 color=\#FF0000><center>(.+)<\/li><\/ul><\/font><\/td>/ =~ result
        $1.gsub(/<[^>]+>/, '')
      end
    else
      /(.+)\r?\n/ =~ result
      $1
    end
  end

  def encode(before, enja=true)
    post_data = []
    post_data << 'before='+CGI.escape(before)
    if enja
      post_data << 'wb_lp=ENJA'
    else
      post_data << 'wb_lp=JAEN'
    end
    post_data.join('&')
  end
end

if __FILE__ == $0
  trans_dir = $1 if /enja|jaen/ === $0

  if 1 <= ARGV.size and /^-(enja|jaen)$/ === ARGV[0]
    trans_dir = $1
    ARGV.shift
  end

  if trans_dir
    excite = ExciteWorldText.new(ENV['http_proxy'])
    if ARGV.empty?
      puts excite.__send__(trans_dir, STDIN.read)
    elsif '-i' == ARGV[0]
      begin
        require 'readline'
        unless /win/ === RUBY_PLATFORM
          stty_save = `stty -g`.chomp
          trap('INT') { system 'stty', stty_save; exit }
        end
        while line = Readline.readline("#{trans_dir}> ", true)
          case line
          when /^-(enja|jaen)$/
            trans_dir = $1
          else
            if /win/ === RUBY_PLATFORM
              puts excite.__send__(trans_dir, line)
            else
              puts NKF.nkf('-Se', excite.__send__(trans_dir, NKF.nkf('-Es', line)))
            end
          end
        end
      rescue LoadError
        while line = gets
          puts excite.__send__(trans_dir, line)
        end
      end
    else
      puts excite.__send__(trans_dir, ARGV.join(' '))
    end
  else
    puts "usage: #$0 -enja [-i] [Text for translation.]"
    puts "usage: #$0 -jaen [-i] [翻訳用テキスト。]"
    puts " -enja: English to Japanese"
    puts " -jaen: Japanese to English"
    puts "    -i: interactive mode"
  end
end

