use of com.ichi2.utils.JSONException in project AnkiChinaAndroid by ankichinateam.
the class ImportTest method testAnki2Mediadupes.
@Test
public void testAnki2Mediadupes() throws IOException, JSONException, ImportExportException {
List<String> expected;
List<String> actual;
// add a note that references a sound
Note n = testCol.newNote();
n.setField(0, "[sound:foo.mp3]");
long mid = n.model().getLong("id");
testCol.addNote(n);
// add that sound to the media folder
FileOutputStream os;
os = new FileOutputStream(new File(testCol.getMedia().dir(), "foo.mp3"), false);
os.write("foo".getBytes());
os.close();
testCol.close();
// it should be imported correctly into an empty deck
Collection empty = Shared.getEmptyCol(InstrumentationRegistry.getInstrumentation().getTargetContext());
Importer imp = new Anki2Importer(empty, testCol.getPath());
imp.run();
expected = Collections.singletonList("foo.mp3");
actual = Arrays.asList(new File(empty.getMedia().dir()).list());
actual.retainAll(expected);
assertEquals(expected.size(), actual.size());
// and importing again will not duplicate, as the file content matches
empty.remCards(empty.getDb().queryLongList("select id from cards"));
imp = new Anki2Importer(empty, testCol.getPath());
imp.run();
expected = Collections.singletonList("foo.mp3");
actual = Arrays.asList(new File(empty.getMedia().dir()).list());
actual.retainAll(expected);
assertEquals(expected.size(), actual.size());
n = empty.getNote(empty.getDb().queryLongScalar("select id from notes"));
assertTrue(n.getFields()[0].contains("foo.mp3"));
// if the local file content is different, and import should trigger a rename
empty.remCards(empty.getDb().queryLongList("select id from cards"));
os = new FileOutputStream(new File(empty.getMedia().dir(), "foo.mp3"), false);
os.write("bar".getBytes());
os.close();
imp = new Anki2Importer(empty, testCol.getPath());
imp.run();
expected = Arrays.asList("foo.mp3", String.format("foo_%s.mp3", mid));
actual = Arrays.asList(new File(empty.getMedia().dir()).list());
actual.retainAll(expected);
assertEquals(expected.size(), actual.size());
n = empty.getNote(empty.getDb().queryLongScalar("select id from notes"));
assertTrue(n.getFields()[0].contains("_"));
// if the localized media file already exists, we rewrite the note and media
empty.remCards(empty.getDb().queryLongList("select id from cards"));
os = new FileOutputStream(new File(empty.getMedia().dir(), "foo.mp3"));
os.write("bar".getBytes());
os.close();
imp = new Anki2Importer(empty, testCol.getPath());
imp.run();
expected = Arrays.asList("foo.mp3", String.format("foo_%s.mp3", mid));
actual = Arrays.asList(new File(empty.getMedia().dir()).list());
actual.retainAll(expected);
assertEquals(expected.size(), actual.size());
n = empty.getNote(empty.getDb().queryLongScalar("select id from notes"));
assertTrue(n.getFields()[0].contains("_"));
empty.close();
}
use of com.ichi2.utils.JSONException in project AnkiChinaAndroid by ankichinateam.
the class FilteredDeckOptions method onCreate.
@Override
// Tracked as #5019 on github
@SuppressWarnings("deprecation")
protected void onCreate(Bundle icicle) {
Themes.setThemeLegacy(this);
super.onCreate(icicle);
UsageAnalytics.sendAnalyticsScreenView(this);
mCol = CollectionHelper.getInstance().getCol(this);
if (mCol == null) {
finish();
return;
}
Bundle extras = getIntent().getExtras();
if (extras != null && extras.containsKey("did")) {
mDeck = mCol.getDecks().get(extras.getLong("did"));
} else {
mDeck = mCol.getDecks().current();
}
registerExternalStorageListener();
if (mCol == null || mDeck.getInt("dyn") != 1) {
Timber.w("No Collection loaded or deck is not a dyn deck");
finish();
return;
} else {
mPref = new DeckPreferenceHack();
mPref.registerOnSharedPreferenceChangeListener(this);
this.addPreferencesFromResource(R.xml.cram_deck_options);
this.buildLists();
this.updateSummaries();
}
// Set the activity title to include the name of the deck
String title = getResources().getString(R.string.deckpreferences_title);
if (title.contains("XXX")) {
try {
title = title.replace("XXX", mDeck.getString("name"));
} catch (JSONException e) {
title = title.replace("XXX", "???");
}
}
this.setTitle(title);
// Add a home button to the actionbar
getSupportActionBar().setHomeButtonEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
use of com.ichi2.utils.JSONException in project AnkiChinaAndroid by ankichinateam.
the class ModelFieldEditor method repositionFieldDialog.
/*
* Allows the user to select a number less than the number of fields in the current model to
* reposition the current field to
* Processing time is scales with number of items
*/
private void repositionFieldDialog() {
mFieldNameInput = new EditText(this);
mFieldNameInput.setRawInputType(InputType.TYPE_CLASS_NUMBER);
new MaterialDialog.Builder(this).title(String.format(getResources().getString(R.string.model_field_editor_reposition), 1, mFieldLabels.size())).positiveText(R.string.dialog_ok).customView(mFieldNameInput, true).onPositive((dialog, which) -> {
String newPosition = mFieldNameInput.getText().toString();
int pos;
try {
pos = Integer.parseInt(newPosition);
} catch (NumberFormatException n) {
UIUtils.showThemedToast(this, getResources().getString(R.string.toast_out_of_range), true);
return;
}
if (pos < 1 || pos > mFieldLabels.size()) {
UIUtils.showThemedToast(this, getResources().getString(R.string.toast_out_of_range), true);
} else {
changeHandler listener = changeFieldHandler();
// Input is valid, now attempt to modify
try {
mCol.modSchema();
CollectionTask.launchCollectionTask(REPOSITION_FIELD, listener, new TaskData(new Object[] { mMod, mNoteFields.getJSONObject(mCurrentPos), pos - 1 }));
} catch (ConfirmModSchemaException e) {
// Handle mod schema confirmation
ConfirmationDialog c = new ConfirmationDialog();
c.setArgs(getResources().getString(R.string.full_sync_confirmation));
Runnable confirm = () -> {
try {
mCol.modSchemaNoCheck();
String newPosition1 = mFieldNameInput.getText().toString();
int pos1 = Integer.parseInt(newPosition1);
CollectionTask.launchCollectionTask(REPOSITION_FIELD, listener, new TaskData(new Object[] { mMod, mNoteFields.getJSONObject(mCurrentPos), pos1 - 1 }));
dismissContextMenu();
} catch (JSONException e1) {
throw new RuntimeException(e1);
}
};
c.setConfirm(confirm);
c.setCancel(mConfirmDialogCancel);
ModelFieldEditor.this.showDialogFragment(c);
}
}
}).negativeText(R.string.dialog_cancel).show();
}
use of com.ichi2.utils.JSONException in project AnkiChinaAndroid by ankichinateam.
the class CardContentProvider method addModelToCursor.
private void addModelToCursor(Long modelId, Models models, MatrixCursor rv, String[] columns) {
Model jsonObject = models.get(modelId);
MatrixCursor.RowBuilder rb = rv.newRow();
try {
for (String column : columns) {
if (column.equals(FlashCardsContract.Model._ID)) {
rb.add(modelId);
} else if (column.equals(FlashCardsContract.Model.NAME)) {
rb.add(jsonObject.getString("name"));
} else if (column.equals(FlashCardsContract.Model.FIELD_NAMES)) {
JSONArray flds = jsonObject.getJSONArray("flds");
String[] allFlds = new String[flds.length()];
for (int idx = 0; idx < flds.length(); idx++) {
allFlds[idx] = flds.getJSONObject(idx).optString("name", "");
}
rb.add(Utils.joinFields(allFlds));
} else if (column.equals(FlashCardsContract.Model.NUM_CARDS)) {
rb.add(jsonObject.getJSONArray("tmpls").length());
} else if (column.equals(FlashCardsContract.Model.CSS)) {
rb.add(jsonObject.getString("css"));
} else if (column.equals(FlashCardsContract.Model.DECK_ID)) {
// #6378 - Anki Desktop changed schema temporarily to allow null
rb.add(jsonObject.optLong("did", Consts.DEFAULT_DECK_ID));
} else if (column.equals(FlashCardsContract.Model.SORT_FIELD_INDEX)) {
rb.add(jsonObject.getLong("sortf"));
} else if (column.equals(FlashCardsContract.Model.TYPE)) {
rb.add(jsonObject.getLong("type"));
} else if (column.equals(FlashCardsContract.Model.LATEX_POST)) {
rb.add(jsonObject.getString("latexPost"));
} else if (column.equals(FlashCardsContract.Model.LATEX_PRE)) {
rb.add(jsonObject.getString("latexPre"));
} else if (column.equals(FlashCardsContract.Model.NOTE_COUNT)) {
rb.add(models.useCount(jsonObject));
} else {
throw new UnsupportedOperationException("Column \"" + column + "\" is unknown");
}
}
} catch (JSONException e) {
Timber.e(e, "Error parsing JSONArray");
throw new IllegalArgumentException("Model " + modelId + " is malformed", e);
}
}
use of com.ichi2.utils.JSONException in project AnkiChinaAndroid by ankichinateam.
the class CollectionTask method doInBackgroundConfRemove.
private TaskData doInBackgroundConfRemove(TaskData param) {
Timber.d("doInBackgroundConfRemove");
Collection col = getCol();
Object[] data = param.getObjArray();
DeckConfig conf = (DeckConfig) data[0];
try {
// Note: We do the actual removing of the options group in the main thread so that we
// can ask the user to confirm if they're happy to do a full sync, and just do the resorting here
// When a conf is deleted, all decks using it revert to the default conf.
// Cards must be reordered according to the default conf.
int order = conf.getJSONObject("new").getInt("order");
int defaultOrder = col.getDecks().getConf(1).getJSONObject("new").getInt("order");
if (order != defaultOrder) {
conf.getJSONObject("new").put("order", defaultOrder);
col.getSched().resortConf(conf);
}
col.save();
return new TaskData(true);
} catch (JSONException e) {
return new TaskData(false);
}
}
Aggregations