use of com.ichi2.anki.Pair in project Anki-Android by Ramblurr.
the class CardEditor method fetchIntentInformation.
private void fetchIntentInformation(Intent intent) {
Bundle extras = intent.getExtras();
if (ACTION_CREATE_FLASHCARD.equals(intent.getAction())) {
// mSourceLanguage = extras.getString(SOURCE_LANGUAGE);
// mTargetLanguage = extras.getString(TARGET_LANGUAGE);
mSourceText = new String[2];
mSourceText[0] = extras.getString(SOURCE_TEXT);
mSourceText[1] = extras.getString(TARGET_TEXT);
} else {
String first;
String second;
if (extras.getString(Intent.EXTRA_SUBJECT) != null) {
first = extras.getString(Intent.EXTRA_SUBJECT);
} else {
first = "";
}
if (extras.getString(Intent.EXTRA_TEXT) != null) {
second = extras.getString(Intent.EXTRA_TEXT);
} else {
second = "";
}
Pair<String, String> messages = new Pair<String, String>(first, second);
/* Filter garbage information */
Pair<String, String> cleanMessages = new FilterFacade(getBaseContext()).filter(messages);
mSourceText = new String[2];
mSourceText[0] = cleanMessages.first;
mSourceText[1] = cleanMessages.second;
}
}
use of com.ichi2.anki.Pair in project Anki-Android by Ramblurr.
the class Media method zipAdded.
// Media syncing - bundling zip files to send to server
// Because there's no standard filename encoding for zips, and because not
// all zip clients support retrieving mtime, we store the files as ascii
// and place a json file in the zip with the necessary information.
// /////////////////////////////////////////////////////
/**
* Add files to a zip until over SYNC_ZIP_SIZE. Return zip data.
*
* @return Returns a tuple with two objects. The first one is the zip file contents, the second a list with the
* filenames of the files inside the zip.
*/
public Pair<File, List<String>> zipAdded() {
File f = new File(mCol.getPath().replaceFirst("collection\\.anki2$", "tmpSyncToServer.zip"));
String sql = "select fname from log where type = " + Integer.toString(MEDIA_ADD);
List<String> filenames = mMediaDb.queryColumn(String.class, sql, 0);
List<String> fnames = new ArrayList<String>();
try {
ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(f)));
zos.setLevel(8);
JSONObject files = new JSONObject();
int cnt = 0;
long sz = 0;
byte[] buffer = new byte[2048];
boolean finished = true;
for (String fname : filenames) {
fnames.add(fname);
File file = new File(getDir(), fname);
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file), 2048);
ZipEntry entry = new ZipEntry(Integer.toString(cnt));
zos.putNextEntry(entry);
int count = 0;
while ((count = bis.read(buffer, 0, 2048)) != -1) {
zos.write(buffer, 0, count);
}
zos.closeEntry();
bis.close();
files.put(Integer.toString(cnt), fname);
sz += file.length();
if (sz > SYNC_ZIP_SIZE) {
finished = false;
break;
}
cnt += 1;
}
if (finished) {
zos.putNextEntry(new ZipEntry("_finished"));
zos.closeEntry();
}
zos.putNextEntry(new ZipEntry("_meta"));
zos.write(Utils.jsonToString(files).getBytes());
zos.close();
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
} catch (JSONException e) {
throw new RuntimeException(e);
}
return new Pair<File, List<String>>(f, fnames);
}
use of com.ichi2.anki.Pair in project Anki-Android by Ramblurr.
the class Collection method _renderQA.
public HashMap<String, String> _renderQA(Object[] data, List<String> args) {
// data is [cid, nid, mid, did, ord, tags, flds]
// unpack fields and create dict
String[] flist = Utils.splitFields((String) data[6]);
Map<String, String> fields = new HashMap<String, String>();
long modelId = (Long) data[2];
JSONObject model = mModels.get(modelId);
Map<String, Pair<Integer, JSONObject>> fmap = mModels.fieldMap(model);
for (String fname : fmap.keySet()) {
fields.put(fname, flist[fmap.get(fname).first]);
}
fields.put("Tags", ((String) data[5]).trim());
try {
fields.put("Type", (String) model.get("name"));
fields.put("Deck", mDecks.name((Long) data[3]));
JSONObject template;
if (model.getInt("type") == Sched.MODEL_STD) {
template = model.getJSONArray("tmpls").getJSONObject((Integer) data[4]);
} else {
template = model.getJSONArray("tmpls").getJSONObject(0);
}
fields.put("Card", template.getString("name"));
fields.put("c" + (((Integer) data[4]) + 1), "1");
// render q & a
HashMap<String, String> d = new HashMap<String, String>();
try {
d.put("id", Long.toString((Long) data[0]));
String qfmt = template.getString("qfmt");
String afmt = template.getString("afmt");
String html;
String format;
// runFilter mungeFields for type "q"
Models.fieldParser fparser = new Models.fieldParser(fields);
Matcher m = fClozePattern.matcher(qfmt);
format = m.replaceFirst(String.format(Locale.US, "{{cq:%d:", ((Integer) data[4]) + 1));
m = fAltClozePattern.matcher(format);
format = m.replaceFirst(String.format(Locale.US, "<%%cq:%d:", ((Integer) data[4]) + 1));
html = mModels.getCmpldTemplate(format).execute(fparser);
html = (String) AnkiDroidApp.getHooks().runFilter("mungeQA", html, "q", fields, model, data, this);
d.put("q", html);
// empty cloze?
if (model.getInt("type") == Sched.MODEL_CLOZE) {
if (getModels()._availClozeOrds(model, (String) data[6], false).size() == 0) {
d.put("q", "Please edit this note and add some cloze deletions.");
}
}
fields.put("FrontSide", d.get("q"));
// runFilter mungeFields for type "a"
fparser = new Models.fieldParser(fields);
m = fClozePattern.matcher(afmt);
format = m.replaceFirst(String.format(Locale.US, "{{ca:%d:", ((Integer) data[4]) + 1));
m = fAltClozePattern.matcher(format);
format = m.replaceFirst(String.format(Locale.US, "<%%ca:%d:", ((Integer) data[4]) + 1));
html = mModels.getCmpldTemplate(format).execute(fparser);
html = (String) AnkiDroidApp.getHooks().runFilter("mungeQA", html, "a", fields, model, data, this);
d.put("a", html);
// empty cloze?
if (model.getInt("type") == Sched.MODEL_CLOZE) {
if (getModels()._availClozeOrds(model, (String) data[6], false).size() == 0) {
d.put("q", AnkiDroidApp.getAppResources().getString(com.ichi2.anki.R.string.empty_cloze_warning, "<a href=" + HELP_SITE + "#cloze>" + AnkiDroidApp.getAppResources().getString(com.ichi2.anki.R.string.help_cloze) + "</a>"));
}
}
} catch (MustacheException e) {
Resources res = AnkiDroidApp.getAppResources();
String templateError = String.format(TEMPLATE_ERROR, res.getString(R.string.template_error), res.getString(R.string.template_error_detail), e.getMessage(), res.getString(R.string.note_type), model.getString("name"), res.getString(R.string.card_type), template.getString("name"), res.getString(R.string.template_error_fix));
d.put("q", templateError);
d.put("a", templateError);
}
return d;
} catch (JSONException e) {
throw new RuntimeException(e);
}
}
use of com.ichi2.anki.Pair in project Anki-Android by Ramblurr.
the class Models method fieldMap.
/** "Mapping of field name -> (ord, field). */
public Map<String, Pair<Integer, JSONObject>> fieldMap(JSONObject m) {
JSONArray ja;
try {
ja = m.getJSONArray("flds");
// TreeMap<Integer, String> map = new TreeMap<Integer, String>();
Map<String, Pair<Integer, JSONObject>> result = new HashMap<String, Pair<Integer, JSONObject>>();
for (int i = 0; i < ja.length(); i++) {
JSONObject f = ja.getJSONObject(i);
result.put(f.getString("name"), new Pair<Integer, JSONObject>(f.getInt("ord"), f));
}
return result;
} catch (JSONException e) {
throw new RuntimeException(e);
}
}
use of com.ichi2.anki.Pair in project Anki-Android by Ramblurr.
the class Models method _availClozeOrds.
public ArrayList<Integer> _availClozeOrds(JSONObject m, String flds, boolean allowEmpty) {
String[] sflds = Utils.splitFields(flds);
Map<String, Pair<Integer, JSONObject>> map = fieldMap(m);
Set<Integer> ords = new HashSet<Integer>();
Matcher matcher1 = null;
try {
matcher1 = fClozePattern1.matcher(m.getJSONArray("tmpls").getJSONObject(0).getString("qfmt"));
// Libanki makes two finds for each case of the cloze tags, but we embed both in the pattern.
// Please note, that this approach is not 100% correct, as we allow cases like {{cloze:...%>
} catch (JSONException e) {
throw new RuntimeException(e);
}
while (matcher1.find()) {
String fname = matcher1.group(1);
if (!map.containsKey(fname)) {
continue;
}
int ord = map.get(fname).first;
Matcher matcher2 = fClozePattern2.matcher(sflds[ord]);
while (matcher2.find()) {
ords.add(Integer.parseInt(matcher2.group(1)) - 1);
}
}
if (ords.contains(-1)) {
ords.remove(-1);
}
if (ords.isEmpty() && allowEmpty) {
// empty clozes use first ord
return new ArrayList<Integer>(Arrays.asList(new Integer[] { 0 }));
}
return new ArrayList<Integer>(ords);
}
Aggregations