#!/usr/bin/ruby --disable-all # A cgi-bin script that translates between languages. It relies on apertium # being installed on the machine. # # CGI works with environment variables. Here are the ones that matter: # # PATH_INFO: // # QUERY_STRING: Some%20text%20to%20translate # # We expect to be called like: /cgi-bin/translate/eng/spa?Food # # If we don't have two languages, make it a Not Found error. # If we don't have a query string to translate, ask for one. require 'cgi' LANGUAGE_PAIRS = %w[en-es es-en] Encoding.default_internal = Encoding::UTF_8 Encoding.default_external = Encoding::UTF_8 class Object def blank? nil? || self&.empty? end end def respond!(code, meta, body = nil) STDOUT.print("#{code} #{meta}\r\n") STDOUT.print(body) unless body.blank? exit 0 end def ask!(prompt) respond!(10, prompt) end def ok!(meta, body = nil) respond!(20, meta, body) end def temp_fail!(meta = 'Temporary Failure') respond!(40, meta) end def not_found!(meta = 'Not Found') respond!(51, meta) end def extract_langpair(path) return if path.blank? || !path.start_with?('/') _, src, dst, *rest = path.split('/') return unless rest.empty? pair = [src, dst].join('-') return unless LANGUAGE_PAIRS.include?(pair) pair end def extract_text(query) return "" if query.blank? CGI.unescape(query) end LANG_PAIR = extract_langpair(ENV['PATH_INFO']) not_found! if LANG_PAIR.blank? TRANSLATE = extract_text(ENV['QUERY_STRING']) # TODO: we could detect a URL and translate the whole page sometime, perhaps ask!('Enter text to translate') if TRANSLATE.blank? require 'open3' translation, status = Open3.capture2({'LC_ALL' => 'C.UTF-8'}, 'apertium', '-un', LANG_PAIR, stdin_data: TRANSLATE, binmode: true) translation = translation.force_encoding("UTF-8") temp_fail!("Couldn't get translation") unless status.success? ok!('text/plain; charset="utf-8"', translation)