Example #1
0
        static void Main( string[] args ) {
            print( "Content-type: text/html\n" );
            Console.OutputEncoding = Encoding.GetEncoding( _TEXT_ENC );
            string app_name = "webpoedit";
            string executing_file = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName;
            app_name = Path.GetFileNameWithoutExtension( executing_file ).ToLower();
            string cgi_name = Path.GetFileName( executing_file ).ToLower();
            StreamWriter logger = null;
            print( "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">" );

            print( "<html>" );
            print( "<head>" );
            print( "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=" + _TEXT_ENC + "\">" );
            print( "<meta http-equiv=\"Content-Style-Type\" content=\"text/css\">" );
            try {
                logger = new StreamWriter( "webpoedit.log", true );
                string project_name = "";
                StreamReader sr = null;
                if ( !File.Exists( config ) ) {
                    print( "<head><title>" + app_name + ": Error</title></head>" );
                    print( "<body>" );
                    print( "<b>configuration file not found</b>" );
                    print( "</body>" );
                    print( "</html>" );
                    return;
                }
                try {
                    sr = new StreamReader( config );
                    project_name = sr.ReadLine();
                } catch ( Exception ex ) {
                    print( "<head><title>" + app_name + ": Error<title></head>" );
                    print( "<body>" );
                    print( "<b>configuration file I/O error</b>" );
                    print( "</body>" );
                    print( "</html>" );
                    return;
                }
                print( "<link rel=\"stylesheet\" type=\"text/css\" href=\"" + project_name + "/style.css\">" );

                TextReader tr = Console.In;
                string stdin = "";
                string line = "";
                while ( (line = tr.ReadLine()) != null ) {
                    stdin += line;
                }
                string get_res = Environment.GetEnvironmentVariable( "QUERY_STRING" );
                string command0 = "";
                string author = "";
                List<KeyValuePair<string, string>> commands = new List<KeyValuePair<string, string>>();
                if ( get_res != "" ) {
                    string[] spl = get_res.Split( '&' );
                    for ( int i = 0; i < spl.Length; i++ ) {
                        string s = spl[i];
                        string[] spl2 = s.Split( "=".ToCharArray(), 2 );
                        commands.Add( new KeyValuePair<string, string>( spl2[0], spl2[1] ) );
                        if ( spl2[0] == "author" ) {
                            author = spl2[1];
                        } else {
                            if ( command0 == "" ) {
                                command0 = spl2[0];
                            }
                        }
                    }
                }
                if ( stdin != "" ) {
                    string[] spl = stdin.Split( '&' );
                    foreach ( string s in spl ) {
                        string[] spl2 = s.Split( "=".ToCharArray(), 2 );
                        commands.Add( new KeyValuePair<string, string>( spl2[0], spl2[1] ) );
                        if ( spl2[0] == "author" ) {
                            author = spl2[1];
                        }
                        if ( spl2[0] == "rauthor" ) {
                            author = enc_b64( dec_url( spl2[1] ) );
                        }
                    }
                }
                Messaging.loadMessages( project_name );
#if DEBUG
                if ( commands.Count > 0 ) print( "commands[0].Key=" + commands[0].Key + "; commands[0].Value=" + commands[0].Value );
#endif
                if ( author == "" ) {
                    print( "<title>" + project_name + " localization</title>" );
                    print( "</head>" );
                    print( "<body>" );
                    print( "<div class=\"top\"><br>&nbsp;&nbsp;<a href=\"" + cgi_name + "\">" + project_name + "</a></div>" );
                    print( "enter your nickname<br>" );
                    print( "<form method=\"post\" action=\"" + cgi_name + "?start=0\">" );
                    print( "<input type=\"text\" name=\"rauthor\" size=30 value=\"\">" );
                    print( "<input type=\"submit\" value=\"start\"></form>" );
                    print( "</body>" );
                    print( "</html>" );
                } else if ( command0 == "start" ) {
                    logger.WriteLine( DateTime.Now + " start; author=" + dec_b64( author ) );
                    // 現在編集可能な言語ファイルのリストを表示
                    print( "<title>" + project_name + " localization</title>" );
                    print( "</head>" );
                    print( "<body>" );
                    print( "<div class=\"top\"><br>&nbsp;&nbsp;<a href=\"" + cgi_name + "?start=0&author=" + author + "\">" + project_name + "</a></div>" );
                    print( "<h4>List of language configuration</h4>" );
                    print( "  <table class=\"padleft\" border=0 cellspacing=0 width=\"100%\">" );
                    print( "    <tr>" );
                    print( "      <td class=\"header\">Language</td>" );
                    print( "      <td class=\"header\">Progress</td>" );
                    print( "      <td class=\"header\">Download language config</td>" );
                    print( "    </tr>" );
                    List<string> languages = new List<string>( Messaging.getRegisteredLanguage() );
                    int count = -1;
                    MessageBody mben = new MessageBody( "en", Path.Combine( project_name, "en.po" ) );
                    foreach ( string lang in languages ) {
                        if ( lang == "en" ) {
                            continue;
                        }
                        count++;
                        string class_kind = "\"even\"";
                        if ( count % 2 != 0 ) {
                            class_kind = "\"odd\"";
                        }
                        print( "    <tr>" );
                        string desc = "";
                        for ( int i = 0; i < _LANGS.GetUpperBound( 0 ) + 1; i++ ) {
                            if ( _LANGS[i, 1] == lang ) {
                                desc = _LANGS[i, 0];
                                break;
                            }
                        }

                        // 進捗率を計算。
                        MessageBody mb = new MessageBody( lang, Path.Combine( project_name, lang + ".po" ) );
                        int en_count = mben.list.Count;
                        int lang_count = 0;
                        foreach ( string id in mben.list.Keys ) {
                            if ( mb.list.ContainsKey( id ) ) {
                                if ( mb.list[id].message != id ) {
                                    lang_count++;
                                }
                            }
                        }
                        float prog = (float)lang_count / (float)en_count * 100.0f;
                        print( "      <td class=" + class_kind + ">" + desc + "&nbsp;[" + lang + "]&nbsp;&nbsp;<a href=\"" + cgi_name + "?target=" + lang + "&author=" + author + "\">edit</a></td>" );
                        print( "      <td class=" + class_kind + ">" + prog.ToString( "0.00" ) + "% translated</td>" );
                        print( "      <td class=" + class_kind + "><a href=\"" + project_name + "/" + lang + ".po\">Download</a></td>" );
                        print( "    </tr>" );
                    }
                    print( "  </table>" );
                    print( "  <br>" );
                    print( "<h4>If you want to create new language configuration, select language and press \"create\" button.</h4>" );
                    print( "  <div class=\"padleft\">" );
                    print( "  <form method=\"post\" action=\"" + cgi_name + "?create=0&author=" + author + "\">" );

                    // ブラウザの使用言語を取得
                    string http_accept_language = Environment.GetEnvironmentVariable( "HTTP_ACCEPT_LANGUAGE" );
                    string[] spl = http_accept_language.Split( ',' );
                    Dictionary<string, float> accept_language_list = new Dictionary<string, float>();
                    foreach ( string s in spl ) {
                        // ja,fr;q=0.7,de;q=0.3
                        if ( s.Contains( ";" ) ) {
                            string[] spl2 = s.Split( ';' ); //spl2 = { "fr", "q=0.7" }
                            if ( spl2.Length >= 2 ) {
                                string[] spl3 = spl2[1].Split( '=' ); //spl3 = { "q", "0.7" }
                                if ( spl3.Length >= 2 ) {
                                    float q = 0.0f;
                                    if ( float.TryParse( spl3[1], out q ) ) {
                                        accept_language_list.Add( spl2[0], q );
                                    }
                                }
                            }
                        } else {
                            accept_language_list.Add( s, 1.0f );
                        }
                    }
                    // 最も品質値の高い言語はどれか
                    string most_used = "en";
                    float most_used_q = 0.0f;
                    foreach ( string key in accept_language_list.Keys ) {
                        if ( most_used_q < accept_language_list[key] ) {
                            most_used = key;
                            most_used_q = accept_language_list[key];
                        }
                    }

                    // 未作成の言語設定ファイルを列挙
                    print( "  <select name=\"lang\">" );
                    int len = _LANGS.GetUpperBound( 0 ) + 1;
                    for ( int i = 0; i < len; i++ ) {
                        if ( languages.Contains( _LANGS[i, 1] ) ) {
                            print( "    <option value=\"" + _LANGS[i, 1] + "\" disabled>" + _LANGS[i, 0] );
                        } else if ( most_used == _LANGS[i, 1] ) {
                            print( "    <option value=\"" + _LANGS[i, 1] + "\" selected>" + _LANGS[i, 0] );
                        } else {
                            print( "    <option value=\"" + _LANGS[i, 1] + "\">" + _LANGS[i, 0] );
                        }
                    }
                    print( "  <input type=\"submit\" value=\"create\">" );
                    print( "  </form>" );
                    print( "  </div>" );
                    print( "</body>" );
                    print( "</html>" );
                } else if ( command0 == "target" || command0 == "update" || command0 == "create" ) {
                    // 指定された言語の現在の状態を表示。
                    string lang = commands[0].Value;

                    List<string> keys = new List<string>( Messaging.getKeys( "en" ) );
                    keys.Sort();

                    if ( command0 == "create" ) {
                        foreach ( KeyValuePair<string, string> v in commands ) {
                            if ( v.Key == "lang" ) {
                                lang = v.Value;
                                break;
                            }
                        }
                        string newpo = Path.Combine( project_name, lang + ".po" );
                        MessageBody mb0 = null;
                        if ( File.Exists( newpo ) ) {
                            // すでに存在するlangでcreateが指定された場合
                            mb0 = new MessageBody( lang, newpo );
                        } else {
                            mb0 = new MessageBody( lang );
                        }
                        Messaging.setLanguage( "en" );
                        foreach ( string id in keys ) {
                            if ( !mb0.list.ContainsKey( id ) ) {
                                MessageBodyEntry item = Messaging.getMessageDetail( id );
                                MessageBodyEntry add = new MessageBodyEntry( item.message, item.location.ToArray() );
                                mb0.list.Add( id, add );
                            }
                        }

                        // google language apiを使って訳せるところは訳す。en -> [lang]の結果が元のenと異なり、かつ、en -> [lang] -> enが元のenと同じなら翻訳できたとみなす
                        //url: http://ajax.googleapis.com/ajax/services/language/translate?v=1.0&q=hello%20world&langpair=en%7Cit
                        //{"responseData": {"translatedText":"ciao mondo"}, "responseDetails": null, "responseStatus": 200}
                        foreach ( string en_query in keys ) {
                            if ( en_query == mb0.getMessage( en_query ) ) {
                                string lang_query = translate( en_query, "en", lang );
                                string en_revert = translate( lang_query, lang, "en" );
                                if ( en_query.ToLower() == en_revert.ToLower() ) {
                                    mb0.list[en_query].message = lang_query;
                                    logger.WriteLine( "    translated: {id,value}={" + en_query + "," + lang_query + "}" );
                                }
                            }
                        }

                        mb0.write( newpo );
                    }

                    bool is_rtl = Util.isRightToLeftLanguage( lang );
                    logger.WriteLine( DateTime.Now + " " + command0 + "; lang=" + lang + "; author=" + dec_b64( author ) );

                    print( "<title>" + project_name + "&nbsp;&gt;&gt;&nbsp;" + lang + "</title>" );
                    print( "</head>" );
                    if ( is_rtl ) {
                        print( "<body dir=\"rtl\">" );
                    } else {
                        print( "<body>" );
                    }
                    print( "<form method=\"post\" action=\"" + cgi_name + "?update=" + lang + "&author=" + author + "\">" );
                    print( "<div class=\"top\"><br>&nbsp;&nbsp;<a href=\"" + cgi_name + "?start=0&author=" + author + "\">" + project_name + "</a>&gt;&gt;" + lang + "</div>" );
                    print( "<div align=\"center\">" );
                    print( "<table border=0 cellspacing=0 width=\"100%\">" );
                    print( "  <tr>" );
                    print( "    <td class=\"header\">English</td>" );
                    print( "    <td class=\"header\">translation</td>" );
                    print( "  </tr>" );
                    Messaging.setLanguage( lang );
                    MessageBody mb = new MessageBody( lang, Path.Combine( project_name, lang + ".po" ) );
                    if ( command0 == "update" ) {
                        string[] spl = stdin.Split( '&' );
                        foreach ( string s in spl ) {
                            string[] spl2 = s.Split( '=' );
                            if ( spl2.Length >= 2 ) {
                                string id = dec_b64( spl2[0] );
                                string value = dec_url( spl2[1] ).Replace( "\\n", "\n" );
                                if ( mb.list.ContainsKey( id ) ) {
                                    if ( keys.Contains( id ) ) {
                                        string old = mb.list[id].message;
                                        mb.list[id].message = value;
                                        if ( old != value ) {
                                            logger.WriteLine( "    replaced: {id,value,old_value}={" + id + "," + value + "," + old + "}" );
                                        }
                                    } else {
                                        mb.list.Remove( id );
                                    }
                                } else if ( keys.Contains( id ) ) {
                                    mb.list.Add( id, new MessageBodyEntry( value, new string[]{} ) );
                                    logger.WriteLine( "    added: {id,value}={" + id + "," + value + "}" );
                                }
                            }
                        }
                        mb.write( Path.Combine( project_name, lang + ".po" ) );
                    }
                    int count = -1;
                    foreach ( string key in keys ) {
                        count++;
                        string class_kind = "\"even\"";
                        if ( count % 2 != 0 ) {
                            class_kind = "\"odd\"";
                        }
                        string id = enc_b64( key );
                        print( "  <tr>" );
                        print( "    <td class=" + class_kind + ">" + key.Replace( "\n", "\\" + "n" ) + "</td>" );
                        string msg = mb.getMessage( key );
                        print( "    <td nowrap class=" + class_kind + ">" );
                        if ( msg == key ) {
                            print( "      <input type=\"text\" name=\"" + id + "\" class=\"highlight\" size=60 value=\"" + msg.Replace( "\n", "\\" + "n" ) + "\">" );
                        } else {
                            print( "      <input type=\"text\" name=\"" + id + "\" size=60 value=\"" + msg.Replace( "\n", "\\" + "n" ) + "\">" );
                        }
                        print( "      <input type=\"submit\" value=\"submit\">" );
                        print( "    </td>" );
                        print( "  </tr>" );
                    }
                    print( "</table>" );
                    print( "</div>" );
                    print( "</form>" );
                    print( "</body>" );
                    print( "</html>" );
                }
            } catch ( Exception exm ) {
                logger.WriteLine( DateTime.Now + " error; exm=" + exm );
                print( "<head><title>" + app_name + ": Error</title></head>" );
                print( "<body>" );
                print( "</body>" );
                print( "</html>" );
            } finally {
                if ( logger != null ) {
                    logger.Close();
                }
            }
        }