-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathTranslatorBase.cs
114 lines (96 loc) · 3.08 KB
/
TranslatorBase.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Newtonsoft.Json;
namespace VPet.Plugin.AutoMTL
{
public abstract class TranslatorBase
{
// Stuff that needs to be implemented in class that adds a translator
// cf. TranslatorGoogle
public static string providerName = "None";
public static string providerId = "none";
// Provider needs to implement this function, actually translates a string
// This class takes care of all the caching and rate limiting
public abstract string TranslateString(string input);
// This is the getter that returns all the languages that can be used
public static Dictionary<string, string> providedLanguages => null;
// Other stuff
// Can be changed on the fly
public long msBetweenCalls;
// Can't be changed on the fly, needs to clear cache and restart
public bool titleCase;
public readonly string srcLang;
public readonly string dstLang;
// Private stuff
private readonly string cacheBase;
private readonly string cacheFile;
private TextInfo txtInfo;
private Dictionary<string, string> cache;
private long lastTime;
public TranslatorBase(string srcLang, string dstLang, string cacheBase)
{
this.lastTime = 0;
this.titleCase = true;
this.msBetweenCalls = 20;
this.srcLang = srcLang;
this.dstLang = dstLang;
this.cacheBase = cacheBase + @"\mtl";
string providerId = TranslatorMananger.GetProviderId(this);
this.cacheFile = this.cacheBase + String.Format(@"\{0}-{1}-{2}.json", providerId, srcLang, dstLang);
this.txtInfo = new CultureInfo("en-US", false).TextInfo;
InitCache();
}
void InitCache()
{
if (!Directory.Exists(cacheBase))
Directory.CreateDirectory(cacheBase);
if (File.Exists(cacheFile))
cache = JsonConvert.DeserializeObject<Dictionary<string, string>>(File.ReadAllText(cacheFile));
else
cache = new Dictionary<string, string>();
}
void SaveCache()
{
File.WriteAllText(cacheFile, JsonConvert.SerializeObject(cache, Formatting.Indented));
}
public void ClearCache()
{
cache.Clear();
if (File.Exists(cacheFile))
File.Delete(cacheFile);
}
public string Translate(string input)
{
// Already in cache
if (cache.ContainsKey(input))
return cache[input];
// Do rate limiting if needed
long currentTime = DateTimeOffset.Now.ToUnixTimeMilliseconds();
long timeDiff = currentTime - lastTime;
if (timeDiff < msBetweenCalls)
Thread.Sleep((int)timeDiff);
lastTime = DateTimeOffset.Now.ToUnixTimeMilliseconds();
// Run the translator
string output = TranslateString(input);
if (output == null)
return null;
// Check if it's the same as the input (could be same language)
if (output.ToLower().Trim() == input.ToLower().Trim())
return null;
// Format if needed
if (titleCase)
output = txtInfo.ToTitleCase(output);
// Cache the output and return
cache[input] = output;
// Saving at every change is not great...
SaveCache();
return output;
}
}
}