Read from/write to Android resource files

This commit is contained in:
serso 2016-02-13 23:30:37 +01:00
parent 0a2753e6bf
commit f45585edc6
3 changed files with 108 additions and 67 deletions

View File

@ -6,6 +6,7 @@ import android.content.DialogInterface;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.annotation.StringRes;
import android.support.design.widget.TextInputLayout; import android.support.design.widget.TextInputLayout;
import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentActivity;
import android.support.v7.app.AlertDialog; import android.support.v7.app.AlertDialog;
@ -16,33 +17,10 @@ import android.view.KeyEvent;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.inputmethod.EditorInfo; import android.view.inputmethod.EditorInfo;
import android.widget.AdapterView; import android.widget.*;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import org.solovyev.android.calculator.App;
import org.solovyev.android.calculator.AppComponent;
import org.solovyev.android.calculator.BaseDialogFragment;
import org.solovyev.android.calculator.Clipboard;
import org.solovyev.android.calculator.Editor;
import org.solovyev.android.calculator.R;
import butterknife.Bind; import butterknife.Bind;
import butterknife.ButterKnife; import butterknife.ButterKnife;
import org.solovyev.android.calculator.*;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.inject.Inject; import javax.inject.Inject;
@ -50,6 +28,9 @@ import javax.measure.unit.Dimension;
import javax.measure.unit.NonSI; import javax.measure.unit.NonSI;
import javax.measure.unit.SI; import javax.measure.unit.SI;
import javax.measure.unit.Unit; import javax.measure.unit.Unit;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.util.*;
public class ConverterFragment extends BaseDialogFragment public class ConverterFragment extends BaseDialogFragment
implements AdapterView.OnItemSelectedListener, View.OnFocusChangeListener, TextView.OnEditorActionListener, View.OnClickListener, TextWatcher { implements AdapterView.OnItemSelectedListener, View.OnFocusChangeListener, TextView.OnEditorActionListener, View.OnClickListener, TextWatcher {
@ -359,7 +340,7 @@ public class ConverterFragment extends BaseDialogFragment
Toast.LENGTH_SHORT).show(); Toast.LENGTH_SHORT).show();
break; break;
} }
} catch (ParseException e) { } catch (ParseException ignored) {
} }
} }
@ -404,19 +385,19 @@ public class ConverterFragment extends BaseDialogFragment
} }
private enum MyDimension { private enum MyDimension {
TIME(Dimension.TIME, "Time"), TIME(Dimension.TIME, R.string.cpp_converter_time),
AMOUNT_OF_SUBSTANCE(Dimension.AMOUNT_OF_SUBSTANCE, "Amount of substance"), AMOUNT_OF_SUBSTANCE(Dimension.AMOUNT_OF_SUBSTANCE, R.string.cpp_converter_amount_of_substance),
ELECTRIC_CURRENT(Dimension.ELECTRIC_CURRENT, "Electric current"), ELECTRIC_CURRENT(Dimension.ELECTRIC_CURRENT, R.string.cpp_converter_electric_current),
LENGTH(Dimension.LENGTH, "Length"), LENGTH(Dimension.LENGTH, R.string.cpp_converter_length),
MASS(Dimension.MASS, "Mass"), MASS(Dimension.MASS, R.string.cpp_converter_mass),
TEMPERATURE(Dimension.TEMPERATURE, "Temperature"); TEMPERATURE(Dimension.TEMPERATURE, R.string.cpp_converter_termperature);
@NonNull @NonNull
public final Dimension dimension; public final Dimension dimension;
@NonNull @StringRes
public final String name; public final int name;
MyDimension(@NonNull Dimension dimension, @NonNull String name) { MyDimension(@NonNull Dimension dimension, @StringRes int name) {
this.dimension = dimension; this.dimension = dimension;
this.name = name; this.name = name;
} }
@ -442,7 +423,7 @@ public class ConverterFragment extends BaseDialogFragment
@Override @Override
public String toString() { public String toString() {
return dimension.name; return getString(dimension.name);
} }
} }
} }

View File

@ -5,4 +5,5 @@ dependencies {
compile 'commons-cli:commons-cli:1.3' compile 'commons-cli:commons-cli:1.3'
compile 'org.apache.httpcomponents:httpclient:4.5.1' compile 'org.apache.httpcomponents:httpclient:4.5.1'
compile 'org.json:json:20151123' compile 'org.json:json:20151123'
compile('org.simpleframework:simple-xml:2.7.1')
} }

View File

@ -9,27 +9,29 @@ import org.apache.http.util.EntityUtils;
import org.apache.http.util.TextUtils; import org.apache.http.util.TextUtils;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONObject; import org.json.JSONObject;
import org.simpleframework.xml.Attribute;
import org.simpleframework.xml.ElementList;
import org.simpleframework.xml.Root;
import org.simpleframework.xml.Text;
import org.simpleframework.xml.core.Persister;
import java.io.Closeable; import java.io.*;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
public class Main { public class Main {
public static void main(String... args) throws UnsupportedEncodingException { private static final Persister persister = new Persister();
final List<String> words = new ArrayList<>();
words.add("Time"); public static void main(String... args) throws Exception {
words.add("Amount of substance"); final String inFileName = "app/src/main/res/values/text_converter.xml";
words.add("Electric current"); final File inFile = new File(inFileName);
words.add("Length");
words.add("Mass"); final File outDir = new File("build/translations/res");
words.add("Temperature"); delete(outDir);
outDir.mkdirs();
final Resources resources = persister.read(Resources.class, inFile);
final List<String> languages = new ArrayList<>(); final List<String> languages = new ArrayList<>();
languages.add("ar"); languages.add("ar");
languages.add("cs"); languages.add("cs");
@ -51,14 +53,14 @@ public class Main {
final CloseableHttpClient client = HttpClients.createDefault(); final CloseableHttpClient client = HttpClients.createDefault();
try { try {
for (String language : languages) { for (String language : languages) {
final Map<String, String> translations = new HashMap<>(); final Resources translations = new Resources();
for (String word : words) { for (ResourceString string : resources.strings) {
final String translation = translate(client, word, language); final String translation = translate(client, string.value, language);
if (!TextUtils.isEmpty(translation)) { if (!TextUtils.isEmpty(translation)) {
translations.put(word, translation); translations.strings.add(new ResourceString(string.name, translation));
} }
} }
writeTranslations(translations, language); saveTranslations(translations, language, outDir, inFile.getName());
} }
} finally { } finally {
@ -66,6 +68,23 @@ public class Main {
} }
} }
private static boolean delete(File file) {
if(!file.exists()) {
return true;
}
if (file.isFile()) {
return file.delete();
}
boolean deleted = true;
final File[] children = file.listFiles();
if (children != null) {
for (File child : children) {
deleted &= delete(child);
}
}
return deleted && file.delete();
}
private static String translate(CloseableHttpClient client, String word, String language) private static String translate(CloseableHttpClient client, String word, String language)
throws UnsupportedEncodingException { throws UnsupportedEncodingException {
final String uri = final String uri =
@ -90,7 +109,15 @@ public class Main {
final JSONArray jsonLangLinks = jsonPage.getJSONArray("langlinks"); final JSONArray jsonLangLinks = jsonPage.getJSONArray("langlinks");
if (jsonLangLinks.length() > 0) { if (jsonLangLinks.length() > 0) {
final JSONObject jsonLangLink = jsonLangLinks.getJSONObject(0); final JSONObject jsonLangLink = jsonLangLinks.getJSONObject(0);
return jsonLangLink.getString("*"); final String translation = jsonLangLink.getString("*");
if (TextUtils.isBlank(translation)) {
return null;
}
final int i = translation.lastIndexOf(" (");
if(i >= 0) {
return translation.substring(0, i);
}
return translation;
} }
} }
} catch (IOException | RuntimeException e) { } catch (IOException | RuntimeException e) {
@ -102,20 +129,15 @@ public class Main {
return null; return null;
} }
private static void writeTranslations(Map<String, String> translations, String language) { private static void saveTranslations(Resources translations, String language, File outDir, String fileName) {
File dir = new File("out"); final File dir = new File(outDir, "values-" + androidLanguage(language));
dir.mkdirs(); dir.mkdirs();
FileWriter out = null; FileWriter out = null;
try { try {
out = new FileWriter(new File(dir, language + ".xml")); out = new FileWriter(new File(dir, fileName));
out.write("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"); out.write("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
out.write("<resources>\n"); persister.write(translations, out);
for (Map.Entry<String, String> entry : translations.entrySet()) { } catch (Exception e) {
out.write("<string name=\"" + entry.getKey() + "\">" + entry.getValue()
+ "</string>\n");
}
out.write("</resources>\n");
} catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} finally { } finally {
close(out); close(out);
@ -123,6 +145,17 @@ public class Main {
} }
private static String androidLanguage(String language) {
switch (language) {
case "pt":
return "pt-rpt";
case "zh":
return "zh-rcn";
default:
return language;
}
}
private static void close(Closeable closeable) { private static void close(Closeable closeable) {
if (closeable == null) { if (closeable == null) {
return; return;
@ -133,4 +166,30 @@ public class Main {
e.printStackTrace(); e.printStackTrace();
} }
} }
@Root
public static class Resources {
@ElementList(inline = true)
public List<ResourceString> strings = new ArrayList<>();
public Resources() {
}
}
@SuppressWarnings("unused")
@Root(name = "string")
public static class ResourceString {
@Attribute
public String name;
@Text
public String value;
public ResourceString() {
}
private ResourceString(String name, String value) {
this.name = name;
this.value = value;
}
}
} }