2012-04-19 21 views
24

C'erano alcuni servizi che utilizzavano l'API V1 di Google Traduttore per tradurre automaticamente i file .po.Traduci automaticamente i file .po?

Google ha interrotto l'API V1 e con V2 addebita $ 20 per 1.000.000 di parole.

Ho cercato ma non riesco a trovare nessuno strumento che offra la traduzione con la versione V2. Ci si aspetterebbe che qualcuno aggiorni il proprio strumento e addebiti $ 2 per 20.000 parole e ottenere un buon profitto.

Esistono strumenti a pagamento o gratuiti per tradurre automaticamente i file .po?

+1

Google non consente di rivendere le sue traduzioni pagati, secondo i suoi termini di servizio, in modo che nessuno sarebbe in grado di fare ciò che tu suggerisci ... – daveagp

risposta

1

Vedere i miei strumenti PHP liberi Potrans, che si traducono file PO utilizzando Google Translator API

Scaricare da repo qui: https://github.com/OzzyCzech/potrans

+0

È magnifico! Ho avuto alcuni bug con% s e% d variabili, ma tutto sommato, è grandioso. Grazie – JohnWolf

0

Sentiti libero di modificare questo post per apportare correzioni o migliore gestione degli errori. Non sono un esperto nel formato di file .po, ma penso che questo funzioni con i miei bisogni angular-gettext. Penso che l'unica libreria esterna che ho usato sia Json.NET di Newtonsoft. Non sono affiliato a Frengly. È arrivato su google. Ti consigliamo di utilizzare un'API di traduzione diversa se hai bisogno di più di 1 traduzione per 3 secondi. File


ingresso: template.pot

msgid "" 
msgstr "" 
"Content-Type: text/plain; charset=UTF-8\n" 
"Content-Transfer-Encoding: 8bit\n" 

#: Comment 
msgid "You do not have permission to view this application" 
msgstr "" 

msgid "You have permission to view this application" 
msgstr "" 

Comando di ingresso: > program.exe template.pot en es_VE fr_FR


Uscita File 1: en.cache.json Questo è stato creato in modo che qualsiasi traduzione uti la tua identità non deve essere colpita più e più volte.

{ 
    "es_VE": { 
    "You do not have permission to view this application": "Tu no la habana permiso que vista este aplicación", 
    "You have permission to view this application": "Tu tienes permiso que vista este aplicación" 
    }, 
    "fr_FR": { 
    "You do not have permission to view this application": "Vous le faites pas as autorisation a vue cette une demande", 
    "You have permission to view this application": "Tuas autorisation a vue cette une demande" 
    } 
} 

file di output 2: es_VE.po

msgid "" 
msgstr "" 
"Content-Type: text/plain; charset=UTF-8\n" 
"Content-Transfer-Encoding: 8bit\n" 

#: Comment 
msgid "You do not have permission to view this application" 
msgstr "Tu no la habana permiso que vista este aplicación" 

msgid "You have permission to view this application" 
msgstr "Tu tienes permiso que vista este aplicación" 

Output File 3: fr_FR.Po

msgid "" 
msgstr "" 
"Content-Type: text/plain; charset=UTF-8\n" 
"Content-Transfer-Encoding: 8bit\n" 

#: Comment 
msgid "You do not have permission to view this application" 
msgstr "Vous le faites pas as autorisation a vue cette une demande" 

msgid "You have permission to view this application" 
msgstr "Tuas autorisation a vue cette une demande" 

Fonte

public interface ICache 
{ 
    void Add(string language, IEntry entry); 

    IEntry Get(string language, string id); 

    string GetSerialized(); 
} 

public class JsonCache : ICache 
{ 
    private Dictionary<string, Dictionary<string, string>> _cache; 

    public JsonCache(string json) 
    { 
     this._cache = 
      json == null ? 
      new Dictionary<string, Dictionary<string, string>>() : 
      JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, string>>>(json); 
    } 

    public void Add(string language, IEntry entry) 
    { 
     if (!this._cache.ContainsKey(language)) 
     { 
      this._cache.Add(language, new Dictionary<string, string>()); 
     } 

     var languageCache = this._cache[language]; 

     languageCache.Add(entry.Id, entry.Value); 
    } 

    public IEntry Get(string language, string id) 
    { 
     if (!this._cache.ContainsKey(language)) 
     { 
      return null; 
     } 

     var languageCache = this._cache[language]; 

     Entry result = null; 

     if (languageCache.ContainsKey(id)) 
     { 
      result = new Entry(); 
      result.Id = id; 
      result.Value = languageCache[id]; 
     } 

     return result; 
    } 

    public string GetSerialized() 
    { 
     return JsonConvert.SerializeObject(this._cache, Formatting.Indented); 
    } 
} 

public interface IReader : IDisposable 
{ 
    IEntry Read(); 
} 

public class PoReader : IReader 
{ 
    private StreamReader _reader; 

    public PoReader(string fileName) 
    { 
     this._reader = new StreamReader(fileName); 
    } 

    public void Dispose() 
    { 
     if (this._reader != null) 
     { 
      this._reader.Dispose(); 
     } 
    } 

    public IEntry Read() 
    { 
     var entry = new Entry(); 

     while (entry.Id == null || entry.Value == null) 
     { 
      var line = this._reader.ReadLine(); 
      if (line == null) 
      { 
       return null; 
      } 

      if (line.StartsWith(Constants.StartComment)) 
      { 
       entry.Comment = line.Substring(Constants.StartComment.Length); 
      } 
      else if (line.StartsWith(Constants.StartId)) 
      { 
       entry.Id = line.Substring(Constants.StartId.Length); 
       // Remove the double quotes. 
       entry.Id = entry.Id.Substring(1, entry.Id.Length - 2); 
      } 
      else if (line.StartsWith(Constants.StartValue)) 
      { 
       entry.Value = line.Substring(Constants.StartValue.Length); 
       // Remove the double quotes. 
       entry.Value = entry.Value.Substring(1, entry.Value.Length - 2); 
      } 
     } 

     // Skip the first entry 
     if (entry.Id.Length == 0) 
     { 
      return this.Read(); 
     } 

     return entry; 
    } 
} 

public class CachedTranslator : ITranslator 
{ 
    private ITranslator _translator; 
    private ICache _cache; 

    public CachedTranslator(ICache cache, ITranslator translator) 
    { 
     this._translator = translator; 
     this._cache = cache; 
    } 

    public IEntry Translate(string language, IEntry entry) 
    { 
     var result = this._cache.Get(language, entry.Id); 
     if (result == null) 
     { 
      result = this._translator.Translate(language, entry); 
      this._cache.Add(language, result); 
     } 
     else 
     { 
      // We don't want to use the cached comment. 
      var clone = new Entry(); 

      clone.Comment = entry.Comment; 
      clone.Value = result.Value; 
      clone.Id = result.Id; 

      result = clone; 
     } 
     return result; 
    } 
} 

public class FrenglyTranslator : ITranslator 
{ 
    private string _password; 
    private string _email; 
    private string _inLanguage; 

    public FrenglyTranslator(string email, string password, string inLanguage) 
    { 
     this._email = email; 
     this._password = password; 
     this._inLanguage = inLanguage; 
    } 

    public IEntry Translate(string language, IEntry entry) 
    { 
     var url = string.Format("http://syslang.com?src={4}&dest={0}&text={1}&email={2}&password={3}&outformat=json", 
      language.Substring(0, 2), 
      entry.Id, 
      this._email, 
      this._password, 
      this._inLanguage); 

     var result = new Entry(); 
     result.Id = entry.Id; 
     result.Comment = entry.Comment; 

     using (var client = new HttpClient()) 
     { 
      var clientResult = client.GetStringAsync(url).Result; 
      var jo = (JObject)JsonConvert.DeserializeObject(clientResult);    
      result.Value = jo.Property("translation").Value.Value<string>(); 
     } 

     // Must wait 3 seconds between calls. 
     Thread.Sleep(3001); 

     return result; 
    } 
} 

public interface ITranslator 
{ 
    IEntry Translate(string language, IEntry entry); 
} 

public interface IWriter : IDisposable 
{ 
    void Write(IEntry entry); 
} 

public class PoWriter : IWriter 
{ 
    private StreamWriter _writer; 

    public PoWriter(string fileName) 
    { 
     this._writer = new StreamWriter(fileName); 

     var header = @"msgid """" 
msgstr """" 
""Content-Type: text/plain; charset=UTF-8\n"" 
""Content-Transfer-Encoding: 8bit\n"""; 

     this._writer.WriteLine(header); 
    } 

    public void Write(IEntry entry) 
    { 
     this._writer.WriteLine(); 

     if (entry.Comment != null && entry.Comment.Length > 0) 
     { 
      this._writer.WriteLine(Constants.StartComment + entry.Comment); 
     } 

     this._writer.WriteLine(string.Format("{0}\"{1}\"", Constants.StartId, entry.Id)); 
     this._writer.WriteLine(string.Format("{0}\"{1}\"", Constants.StartValue, entry.Value)); 
    } 

    public void Dispose() 
    { 
     if (this._writer != null) 
     { 
      this._writer.Dispose(); 
     } 
    } 
} 

public static class Constants 
{ 
    public const string StartComment = "#: "; 
    public const string StartId = "msgid "; 
    public const string StartValue = "msgstr "; 
} 

public class Entry : IEntry 
{ 
    public string Comment { get; set; } 

    public string Value { get; set; } 

    public string Id { get; set; } 
} 

public interface IEntry 
{ 
    string Comment { get; } 

    string Value { get; } 

    string Id { get; } 
} 

class Program 
{ 
    private const string cacheFileNameSuffix = ".cache.json"; 
    private const string frenglyEmail = "[email protected]"; 
    private const string frenglyPassword = "YourPassword"; 

    static void Main(string[] args) 
    { 
     // 
     // INITIALIZE 
     // 
     var inFileName = args[0]; 
     var inLanguage = args[1]; 
     var outLanguages = args.Skip(2); 

     // ICache 
     var cacheFileName = inLanguage + cacheFileNameSuffix; 
     var json = File.Exists(cacheFileName) ? File.ReadAllText(cacheFileName) : null; 
     ICache cache = new JsonCache(json); 

     // ITranslator 
     ITranslator translator = new FrenglyTranslator(frenglyEmail, frenglyPassword, inLanguage); 
     ITranslator cachedTranslator = new CachedTranslator(cache, translator); 

     // IWriters 
     var writers = new Dictionary<string, IWriter>(); 
     foreach (var language in outLanguages) 
     { 
      writers.Add(language, new PoWriter(language + ".po")); 
     } 

     try 
     { 
      using (IReader reader = new PoReader(inFileName)) 
      { 
       // 
       // RUN 
       // 
       IEntry entry = null; 
       while (true) 
       { 
        entry = reader.Read(); 
        if (entry == null) 
        { 
         break; 
        } 

        foreach (var kv in writers) 
        { 
         var translated = cachedTranslator.Translate(kv.Key, entry); 
         kv.Value.Write(translated); 
        } 
       } 
      } 
     } 
     finally 
     { 
      // Store the cache. 
      File.WriteAllText(cacheFileName, cache.GetSerialized()); 

      // 
      // CLEANUP 
      // 

      // Dispose of the writers. 
      foreach (var writer in writers.Values) 
      { 
       if (writer != null) 
       { 
        writer.Dispose(); 
       } 
      } 
     } 
    } 
}