Generate dictionary list from downloaded list
app/src/main/java/eu/lepiller/nani/DictionaryActivity.java
39 | 39 | setSupportActionBar(toolbar); | |
40 | 40 | ||
41 | 41 | final ListView list_view = findViewById(R.id.dictionary_view); | |
42 | + | final SwipeRefreshLayout refresher = findViewById(R.id.dictionary_refresh_layout); | |
43 | + | ||
42 | 44 | final ArrayList<Dictionary> dictionaries = DictionaryFactory.getDictionnaries(getApplicationContext()); | |
43 | 45 | adapter = new DictionariesAdapter(getApplicationContext(), dictionaries); | |
44 | 46 | list_view.setAdapter(adapter); | |
45 | 47 | ||
48 | + | if(dictionaries.size() == 0) { | |
49 | + | Snackbar.make(findViewById(R.id.dictionary_view), getString(R.string.no_dico_list), | |
50 | + | Snackbar.LENGTH_LONG).show(); | |
51 | + | new DownloadTask(refresher).execute(); | |
52 | + | } | |
53 | + | ||
46 | 54 | list_view.setOnItemClickListener(new AdapterView.OnItemClickListener() { | |
47 | 55 | @Override | |
48 | 56 | public void onItemClick(AdapterView<?> parent, View view, int position, long id) { | |
… | |||
52 | 60 | } | |
53 | 61 | }); | |
54 | 62 | ||
55 | - | final SwipeRefreshLayout refresher = findViewById(R.id.dictionary_refresh_layout); | |
56 | 63 | refresher.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { | |
57 | 64 | @Override | |
58 | 65 | public void onRefresh() { | |
… | |||
105 | 112 | protected void onPostExecute(Integer i) { | |
106 | 113 | super.onPostExecute(i); | |
107 | 114 | refresher.setRefreshing(false); | |
115 | + | DictionaryFactory.updatePackageList(); | |
108 | 116 | adapter.notifyDataSetChanged(); | |
109 | 117 | if(i == null) | |
110 | 118 | return; |
app/src/main/java/eu/lepiller/nani/dictionary/DictionaryFactory.java
1 | 1 | package eu.lepiller.nani.dictionary; | |
2 | 2 | ||
3 | 3 | import android.content.Context; | |
4 | + | import android.os.Build; | |
5 | + | import android.os.LocaleList; | |
6 | + | import android.util.ArrayMap; | |
7 | + | import android.util.Log; | |
4 | 8 | ||
9 | + | import java.io.BufferedReader; | |
5 | 10 | import java.io.File; | |
11 | + | import java.io.FileInputStream; | |
12 | + | import java.io.FileNotFoundException; | |
13 | + | import java.io.FileReader; | |
14 | + | import java.io.IOException; | |
6 | 15 | import java.net.MalformedURLException; | |
7 | 16 | import java.net.URL; | |
8 | 17 | import java.util.ArrayList; | |
18 | + | import java.util.HashMap; | |
19 | + | import java.util.List; | |
20 | + | import java.util.Locale; | |
21 | + | import java.util.Map; | |
9 | 22 | ||
10 | 23 | import eu.lepiller.nani.R; | |
11 | 24 | import eu.lepiller.nani.result.Result; | |
… | |||
14 | 27 | private static DictionaryFactory instance; | |
15 | 28 | private static ArrayList<Dictionary> dictionaries; | |
16 | 29 | private static File cacheDir; | |
30 | + | private static File listFile; | |
31 | + | private static List<String> languages; | |
32 | + | ||
33 | + | private static final int LIST_PARSER_NONE = 0; | |
34 | + | private static final int LIST_PARSER_SYNOPSIS = 1; | |
35 | + | private static final int LIST_PARSER_DESCRIPTION = 2; | |
36 | + | private static final String TAG = "FACTORY"; | |
17 | 37 | ||
18 | 38 | private DictionaryFactory(Context context) { | |
19 | 39 | cacheDir = context.getCacheDir(); | |
40 | + | listFile = new File(cacheDir + "/list"); | |
41 | + | languages = new ArrayList<>(); | |
42 | + | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { | |
43 | + | LocaleList l = context.getResources().getConfiguration().getLocales(); | |
44 | + | for(int i=0;i<l.size();i++) { | |
45 | + | Locale locale = l.get(i); | |
46 | + | languages.add(locale.getISO3Language()); | |
47 | + | languages.add(locale.getLanguage()); | |
48 | + | languages.add(locale.getLanguage().split("[_-]+]")[0]); | |
49 | + | } | |
50 | + | } else { | |
51 | + | Locale locale = context.getResources().getConfiguration().locale; | |
52 | + | languages.add(locale.getISO3Language()); | |
53 | + | languages.add(locale.getLanguage()); | |
54 | + | languages.add(locale.getLanguage().split("[_-]+]")[0]); | |
55 | + | } | |
56 | + | languages.add("en"); | |
57 | + | Log.d(TAG, languages.toString()); | |
58 | + | updatePackageList(); | |
59 | + | } | |
60 | + | ||
61 | + | private static String chooseLanguage(Map<String, StringBuilder> data) { | |
62 | + | for(String l: languages) { | |
63 | + | if(data.containsKey(l)) | |
64 | + | return data.get(l).toString(); | |
65 | + | } | |
66 | + | return null; | |
67 | + | } | |
68 | + | ||
69 | + | public static void updatePackageList() { | |
20 | 70 | dictionaries = new ArrayList<>(); | |
21 | - | dictionaries.add(new RadicalDict("RadK", | |
22 | - | context.getString(R.string.dico_radk), | |
23 | - | context.getString(R.string.dico_radk_long), | |
24 | - | cacheDir, | |
25 | - | "https://nani.lepiller.eu/dicos/radicals.nani")); | |
26 | - | dictionaries.add(new JMDict("JMdict_e", | |
27 | - | context.getString(R.string.dico_jmdict_e), | |
28 | - | context.getString(R.string.dico_jmdict_long), | |
29 | - | cacheDir, | |
30 | - | "https://nani.lepiller.eu/dicos/JMdict_e.nani")); | |
31 | - | dictionaries.add(new JMDict("JMdict_dut", | |
32 | - | context.getString(R.string.dico_jmdict_dut), | |
33 | - | context.getString(R.string.dico_jmdict_long), | |
34 | - | cacheDir, | |
35 | - | "https://nani.lepiller.eu/dicos/JMdict_dut.nani")); | |
36 | - | dictionaries.add(new JMDict("JMdict_fre", | |
37 | - | context.getString(R.string.dico_jmdict_fre), | |
38 | - | context.getString(R.string.dico_jmdict_long), | |
39 | - | cacheDir, | |
40 | - | "https://nani.lepiller.eu/dicos/JMdict_fre.nani")); | |
41 | - | dictionaries.add(new JMDict("JMdict_ger", | |
42 | - | context.getString(R.string.dico_jmdict_ger), | |
43 | - | context.getString(R.string.dico_jmdict_long), | |
44 | - | cacheDir, | |
45 | - | "https://nani.lepiller.eu/dicos/JMdict_ger.nani")); | |
46 | - | dictionaries.add(new JMDict("JMdict_hun", | |
47 | - | context.getString(R.string.dico_jmdict_hun), | |
48 | - | context.getString(R.string.dico_jmdict_long), | |
49 | - | cacheDir, | |
50 | - | "https://nani.lepiller.eu/dicos/JMdict_hun.nani")); | |
51 | - | dictionaries.add(new JMDict("JMdict_rus", | |
52 | - | context.getString(R.string.dico_jmdict_rus), | |
53 | - | context.getString(R.string.dico_jmdict_long), | |
54 | - | cacheDir, | |
55 | - | "https://nani.lepiller.eu/dicos/JMdict_rus.nani")); | |
56 | - | dictionaries.add(new JMDict("JMdict_slv", | |
57 | - | context.getString(R.string.dico_jmdict_slv), | |
58 | - | context.getString(R.string.dico_jmdict_long), | |
59 | - | cacheDir, | |
60 | - | "https://nani.lepiller.eu/dicos/JMdict_slv.nani")); | |
61 | - | dictionaries.add(new JMDict("JMdict_spa", | |
62 | - | context.getString(R.string.dico_jmdict_spa), | |
63 | - | context.getString(R.string.dico_jmdict_long), | |
64 | - | cacheDir, | |
65 | - | "https://nani.lepiller.eu/dicos/JMdict_spa.nani")); | |
66 | - | dictionaries.add(new JMDict("JMdict_swe", | |
67 | - | context.getString(R.string.dico_jmdict_swe), | |
68 | - | context.getString(R.string.dico_jmdict_long), | |
69 | - | cacheDir, | |
70 | - | "https://nani.lepiller.eu/dicos/JMdict_swe.nani")); | |
71 | + | if(listFile.exists()) { | |
72 | + | try { | |
73 | + | BufferedReader br = new BufferedReader(new FileReader(listFile)); | |
74 | + | String line; | |
75 | + | ||
76 | + | Map<String, StringBuilder> synopsis = new HashMap<>(); | |
77 | + | Map<String, StringBuilder> description = new HashMap<>(); | |
78 | + | String sha256 = ""; | |
79 | + | int size = 0; | |
80 | + | String type = ""; | |
81 | + | int entries = 0; | |
82 | + | String url = ""; | |
83 | + | String name = ""; | |
84 | + | int current = LIST_PARSER_NONE; | |
85 | + | String currentLanguage = ""; | |
86 | + | ||
87 | + | while((line = br.readLine()) != null) { | |
88 | + | if(line.isEmpty()) { | |
89 | + | // create dictionary | |
90 | + | if(type.compareTo("radk") == 0) { | |
91 | + | dictionaries.add(new RadicalDict(name, | |
92 | + | chooseLanguage(synopsis), | |
93 | + | chooseLanguage(description), | |
94 | + | cacheDir, | |
95 | + | url)); | |
96 | + | } else if (type.compareTo("jmdict") == 0) { | |
97 | + | dictionaries.add(new JMDict(name, | |
98 | + | chooseLanguage(synopsis), | |
99 | + | chooseLanguage(description), | |
100 | + | cacheDir, | |
101 | + | url)); | |
102 | + | } | |
103 | + | } | |
104 | + | ||
105 | + | if(line.startsWith("[")) { | |
106 | + | name = line.substring(1, line.length() - 1); | |
107 | + | } else if(line.startsWith(" ")) { | |
108 | + | StringBuilder sb; | |
109 | + | switch (current) { | |
110 | + | case LIST_PARSER_DESCRIPTION: | |
111 | + | sb = description.get(currentLanguage); | |
112 | + | if(sb != null) { | |
113 | + | sb.append(" "); | |
114 | + | sb.append(line.trim()); | |
115 | + | } | |
116 | + | break; | |
117 | + | case LIST_PARSER_SYNOPSIS: | |
118 | + | sb = synopsis.get(currentLanguage); | |
119 | + | if(sb != null) { | |
120 | + | sb.append(" "); | |
121 | + | sb.append(line.trim()); | |
122 | + | } | |
123 | + | break; | |
124 | + | default: | |
125 | + | break; | |
126 | + | } | |
127 | + | } else if(line.startsWith("synopsis=")) { | |
128 | + | String[] content = line.split("="); | |
129 | + | currentLanguage = content[1]; | |
130 | + | current = LIST_PARSER_SYNOPSIS; | |
131 | + | StringBuilder sb = new StringBuilder(); | |
132 | + | sb.append(line.substring(10 + currentLanguage.length()).trim()); | |
133 | + | synopsis.put(currentLanguage, sb); | |
134 | + | } else if(line.startsWith("description=")) { | |
135 | + | String[] content = line.split("="); | |
136 | + | currentLanguage = content[1]; | |
137 | + | current = LIST_PARSER_DESCRIPTION; | |
138 | + | StringBuilder sb = new StringBuilder(); | |
139 | + | sb.append(line.substring(13 + currentLanguage.length()).trim()); | |
140 | + | description.put(currentLanguage, sb); | |
141 | + | } else if(line.startsWith("sha256=")) { | |
142 | + | sha256 = line.substring(7); | |
143 | + | } else if(line.startsWith("type=")) { | |
144 | + | type = line.substring(5); | |
145 | + | } else if(line.startsWith("url=")) { | |
146 | + | url = line.substring(4); | |
147 | + | } else if(line.startsWith("size=")) { | |
148 | + | size = Integer.parseInt(line.substring(5)); | |
149 | + | } else if(line.startsWith("entries=")) { | |
150 | + | entries = Integer.parseInt(line.substring(8)); | |
151 | + | } | |
152 | + | } | |
153 | + | } catch (FileNotFoundException e) { | |
154 | + | e.printStackTrace(); | |
155 | + | } catch (IOException e) { | |
156 | + | e.printStackTrace(); | |
157 | + | } | |
158 | + | } | |
71 | 159 | } | |
72 | 160 | ||
73 | 161 | public static void prepare(Context context) { | |
… | |||
125 | 213 | } | |
126 | 214 | ||
127 | 215 | public static File getListFile() { | |
128 | - | return new File(cacheDir + "/list"); | |
216 | + | return listFile; | |
129 | 217 | } | |
130 | 218 | } |
app/src/main/res/values/strings.xml
60 | 60 | <string name="error_dico_url">Error fetching dictionary list: malformed URL.</string> | |
61 | 61 | <string name="error_dico_io">Error fetching dictionary list: cannot write to cache file.</string> | |
62 | 62 | <string name="error_dico_not_found">Error fetching dictionary list: cannot find it on server.</string> | |
63 | + | <string name="no_dico_list">Dictionary list not yet downloaded, updating???</string> | |
63 | 64 | ||
64 | 65 | <!-- Result view --> | |
65 | 66 | <string name="sense_number">%d.</string> |