-
-
Save lenis0012/1f06e861e6210544e6d58c23d5c3b021 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import com.google.common.collect.Lists; | |
import com.google.common.collect.Maps; | |
import com.google.gson.*; | |
import com.google.gson.stream.JsonWriter; | |
import lombok.SneakyThrows; | |
import org.apache.commons.codec.binary.Hex; | |
import org.eclipse.jgit.api.Git; | |
import org.eclipse.jgit.lib.StoredConfig; | |
import spark.Request; | |
import spark.Response; | |
import java.io.*; | |
import java.security.MessageDigest; | |
import java.util.Collections; | |
import java.util.List; | |
import java.util.Map; | |
import java.util.concurrent.locks.ReadWriteLock; | |
import java.util.concurrent.locks.ReentrantReadWriteLock; | |
import static spark.Spark.*; | |
public class TranslationAPI { | |
private static final String CLONE_URL = "https://github.com/lenis0012/Translations.git"; | |
private static Gson gson; | |
public static void main(String[] args) { | |
TranslationAPI api = new TranslationAPI(); | |
gson = new GsonBuilder() | |
.setPrettyPrinting() | |
.create(); | |
port(9091); | |
get("/list", api::list, gson::toJson); | |
get("/language/:code", api::language, gson::toJson); | |
get("/update/:key", api::update, gson::toJson); | |
} | |
private final List<Translation> translations = Lists.newArrayList(); | |
private final Map<String, JsonObject> dataMap = Maps.newConcurrentMap(); | |
private final JsonParser jsonParser = new JsonParser(); | |
private final ReadWriteLock lock = new ReentrantReadWriteLock(); | |
public TranslationAPI() { | |
refresh(); | |
} | |
public Object language(Request req, Response res) { | |
res.type("application/json; charset=utf-8"); | |
JsonObject body = new JsonObject(); | |
lock.readLock().lock(); | |
JsonObject data = dataMap.get(req.params(":code")); | |
lock.readLock().unlock(); | |
if(data == null) { | |
body = new JsonObject(); | |
body.addProperty("success", false); | |
body.addProperty("error", "Invalid language code!"); | |
return body; | |
} | |
body.addProperty("success", true); | |
body.add("data", data); | |
return body; | |
} | |
public Object list(Request req, Response res) { | |
res.type("application/json; charset=utf-8"); | |
JsonObject body = new JsonObject(); | |
lock.readLock().lock(); | |
JsonArray translations = new JsonArray(); | |
for(Translation translation : this.translations) { | |
JsonObject json = new JsonObject(); | |
json.addProperty("code", translation.getCode()); | |
json.addProperty("localizedName", translation.getName()); | |
json.addProperty("authors", translation.getAuthors()); | |
json.addProperty("pluginVersion", translation.getPluginVersion()); | |
json.addProperty("updatedAt", translation.getUpdatedAt().getTime()); | |
translations.add(json); | |
} | |
lock.readLock().unlock(); | |
body.addProperty("success", true); | |
body.add("languages", translations); | |
return body; | |
} | |
public Object update(Request req, Response res) { | |
res.type("application/json"); | |
final String key = req.params(":key"); | |
if(key == null || !key.equals("{project.securityKey}")) { | |
JsonObject json = new JsonObject(); | |
json.addProperty("success", false); | |
json.addProperty("error", "Invalid key!"); | |
return json; | |
} | |
// Clear | |
System.out.println("Clearing target..."); | |
File target = new File("repo"); | |
target.mkdir(); | |
delete(target); | |
// Clone | |
System.out.println("Cloning repository..."); | |
try { | |
Git result = Git.cloneRepository().setURI(CLONE_URL).setDirectory(target).call(); | |
try { | |
StoredConfig config = result.getRepository().getConfig(); | |
config.setBoolean("core", null, "autocrlf", true); | |
config.save(); | |
} finally { | |
result.close(); | |
} | |
} catch(Exception e) { | |
System.err.println("Couldn't clone repo!"); | |
e.printStackTrace(); | |
} | |
// Generate times | |
File timesFile = new File("times.json"); | |
File hashesFile = new File("hashes.json"); | |
JsonObject times = jsonFromFile(timesFile); | |
JsonObject hashes = jsonFromFile(hashesFile); | |
for(File file : target.listFiles()) { | |
if(!file.getName().endsWith(".json")) continue; | |
String code = file.getName().split("\\.")[0]; | |
String hash = sha1sum(file); | |
if(!hashes.has(code)) { | |
System.out.println("New hash for " + code + ": " + hash); | |
hashes.addProperty(code, hash); | |
times.addProperty(code, System.currentTimeMillis()); | |
} else if(!hash.equals(hashes.get(code).getAsString())) { | |
System.out.println("Updated hash for " + code + ": " + hash); | |
hashes.addProperty(code, hash); | |
times.addProperty(code, System.currentTimeMillis()); | |
} | |
} | |
jsonToFile(timesFile, times); | |
jsonToFile(hashesFile, hashes); | |
// Refresh | |
System.out.println("Refreshing references..."); | |
refresh(); | |
System.out.println("Done!"); | |
JsonObject json = new JsonObject(); | |
json.addProperty("success", true); | |
return json; | |
} | |
private void delete(File file) { | |
if(file.isDirectory()) { | |
for(File f : file.listFiles()) { | |
delete(f); | |
} | |
} | |
while(!file.delete()); | |
} | |
private void refresh() { | |
lock.writeLock().lock(); | |
translations.clear(); | |
File dir = new File("repo"); | |
if(!dir.exists() || !dir.isDirectory()) { | |
lock.writeLock().unlock(); | |
return; | |
} | |
File timesFile = new File("times.json"); | |
JsonObject times = jsonFromFile(timesFile); | |
for(File file : dir.listFiles()) { | |
if(!file.getName().endsWith(".json")) continue; | |
String code = file.getName().split("\\.")[0]; | |
try { | |
JsonObject json = jsonFromFile(file); | |
long updatedAt = times.has(code) ? times.get(code).getAsLong() : System.currentTimeMillis(); | |
json.addProperty("updatedAt", updatedAt); | |
json.addProperty("code", code); | |
translations.add(new Translation(json)); | |
dataMap.put(code, json); | |
} catch(Exception e) { | |
System.err.println("Error while loading language " + code); | |
e.printStackTrace(); | |
} | |
} | |
Collections.sort(translations, (t1, t2) -> t1.getName().compareTo(t2.getName())); | |
lock.writeLock().unlock(); | |
} | |
@SneakyThrows | |
private JsonObject jsonFromFile(File file) { | |
if(!file.exists()) { | |
return new JsonObject(); | |
} | |
FileReader reader = new FileReader(file); | |
JsonObject json = jsonParser.parse(reader).getAsJsonObject(); | |
reader.close(); | |
return json; | |
} | |
@SneakyThrows | |
private void jsonToFile(File file, JsonObject json) { | |
JsonWriter writer = gson.newJsonWriter(new FileWriter(file)); | |
gson.toJson(json, writer); | |
writer.flush(); | |
writer.close(); | |
} | |
@SneakyThrows | |
private String sha1sum(File file) { | |
MessageDigest digest = MessageDigest.getInstance("SHA-1"); | |
digest.reset(); | |
FileInputStream input = null; | |
try { | |
input = new FileInputStream(file); | |
byte[] buffer = new byte[1024]; | |
int length; | |
while ((length = input.read(buffer)) != -1) { | |
digest.update(buffer, 0, length); | |
} | |
} catch(Exception e) { | |
System.err.println("Failed to create hash"); | |
e.printStackTrace(); | |
} finally { | |
if(input != null) { | |
try { | |
input.close(); | |
} catch(IOException e) {} | |
} | |
} | |
return Hex.encodeHexString(digest.digest()); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment