use of com.ichi2.async.CollectionTask.TASK_TYPE.IMPORT in project Anki-Android by ankidroid.
the class Media method maybeUpgrade.
public void maybeUpgrade() {
String oldpath = dir() + ".db";
File oldDbFile = new File(oldpath);
if (oldDbFile.exists()) {
mDb.execute(String.format(Locale.US, "attach \"%s\" as old", oldpath));
try {
String sql = "insert into media\n" + " select m.fname, csum, mod, ifnull((select 1 from log l2 where l2.fname=m.fname), 0) as dirty\n" + " from old.media m\n" + " left outer join old.log l using (fname)\n" + " union\n" + " select fname, null, 0, 1 from old.log where type=" + Consts.CARD_TYPE_LRN + ";";
mDb.execute(sql);
mDb.execute("delete from meta");
mDb.execute("insert into meta select dirMod, usn from old.meta");
mDb.commit();
} catch (Exception e) {
// if we couldn't import the old db for some reason, just start anew
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
mCol.log("failed to import old media db:" + sw.toString());
}
mDb.execute("detach old");
File newDbFile = new File(oldpath + ".old");
if (newDbFile.exists()) {
newDbFile.delete();
}
oldDbFile.renameTo(newDbFile);
}
}
use of com.ichi2.async.CollectionTask.TASK_TYPE.IMPORT in project Anki-Android by Ramblurr.
the class DeckTask method doInBackgroundImportAdd.
private TaskData doInBackgroundImportAdd(TaskData... params) {
// Log.i(AnkiDroidApp.TAG, "doInBackgroundImportAdd");
Resources res = AnkiDroidApp.getInstance().getBaseContext().getResources();
Collection col = params[0].getCollection();
String path = params[0].getString();
boolean sharedDeckImport = params[0].getBoolean();
ProgressCallback pc = null;
// don't report progress on shared deck import (or maybe should we?)
if (!sharedDeckImport) {
pc = new ProgressCallback(this, res);
}
int addedCount = -1;
try {
Anki2Importer imp = new Anki2Importer(col, path, pc);
AnkiDb ankiDB = col.getDb();
ankiDB.getDatabase().beginTransaction();
try {
addedCount = imp.run();
ankiDB.getDatabase().setTransactionSuccessful();
} finally {
ankiDB.getDatabase().endTransaction();
if (sharedDeckImport) {
File tmpFile = new File(path);
tmpFile.delete();
}
}
if (addedCount >= 0) {
ankiDB.execute("VACUUM");
ankiDB.execute("ANALYZE");
}
publishProgress(new TaskData(res.getString(R.string.import_update_counts)));
// Update the counts
DeckTask.TaskData result = doInBackgroundLoadDeckCounts(new TaskData(col));
if (result == null) {
return null;
}
return new TaskData(addedCount, result.getObjArray(), true);
} catch (RuntimeException e) {
Log.e(AnkiDroidApp.TAG, "doInBackgroundImportAdd - RuntimeException on importing cards: ", e);
AnkiDroidApp.saveExceptionReportFile(e, "doInBackgroundImportAdd");
return new TaskData(false);
} catch (IOException e) {
Log.e(AnkiDroidApp.TAG, "doInBackgroundImportAdd - IOException on importing cards: ", e);
AnkiDroidApp.saveExceptionReportFile(e, "doInBackgroundImportAdd");
return new TaskData(false);
}
}
use of com.ichi2.async.CollectionTask.TASK_TYPE.IMPORT in project Anki-Android by Ramblurr.
the class DeckTask method doInBackgroundImportReplace.
private TaskData doInBackgroundImportReplace(TaskData... params) {
// Log.i(AnkiDroidApp.TAG, "doInBackgroundImportReplace");
Collection col = params[0].getCollection();
String path = params[0].getString();
Resources res = AnkiDroidApp.getInstance().getBaseContext().getResources();
// extract the deck from the zip file
String fileDir = AnkiDroidApp.getCurrentAnkiDroidDirectory() + "/tmpzip";
File dir = new File(fileDir);
if (dir.exists()) {
BackupManager.removeDir(dir);
}
publishProgress(new TaskData(res.getString(R.string.import_unpacking)));
// from anki2.py
String colFile = fileDir + "/collection.anki2";
ZipFile zip;
try {
zip = new ZipFile(new File(path), ZipFile.OPEN_READ);
} catch (IOException e) {
Log.e(AnkiDroidApp.TAG, "doInBackgroundImportReplace - Error while unzipping: ", e);
AnkiDroidApp.saveExceptionReportFile(e, "doInBackgroundImportReplace0");
return new TaskData(false);
}
if (!Utils.unzipFiles(zip, fileDir, new String[] { "collection.anki2", "media" }, null) || !(new File(colFile)).exists()) {
return new TaskData(-2, null, false);
}
Collection tmpCol = null;
try {
tmpCol = Storage.Collection(colFile);
if (!tmpCol.validCollection()) {
tmpCol.close();
return new TaskData(-2, null, false);
}
} finally {
if (tmpCol != null) {
tmpCol.close();
}
}
publishProgress(new TaskData(res.getString(R.string.importing_collection)));
String colPath;
if (col != null) {
// unload collection and trigger a backup
colPath = col.getPath();
AnkiDroidApp.closeCollection(true);
BackupManager.performBackup(colPath, true);
}
// overwrite collection
colPath = AnkiDroidApp.getCollectionPath();
File f = new File(colFile);
f.renameTo(new File(colPath));
int addedCount = -1;
try {
col = AnkiDroidApp.openCollection(colPath);
// because users don't have a backup of media, it's safer to import new
// data and rely on them running a media db check to get rid of any
// unwanted media. in the future we might also want to duplicate this step
// import media
HashMap<String, String> nameToNum = new HashMap<String, String>();
HashMap<String, String> numToName = new HashMap<String, String>();
File mediaMapFile = new File(fileDir, "media");
if (mediaMapFile.exists()) {
JsonReader jr = new JsonReader(new FileReader(mediaMapFile));
jr.beginObject();
String name;
String num;
while (jr.hasNext()) {
num = jr.nextName();
name = jr.nextString();
nameToNum.put(name, num);
numToName.put(num, name);
}
jr.endObject();
jr.close();
}
String mediaDir = col.getMedia().getDir();
int total = nameToNum.size();
int i = 0;
for (Map.Entry<String, String> entry : nameToNum.entrySet()) {
String file = entry.getKey();
String c = entry.getValue();
File of = new File(mediaDir, file);
if (!of.exists()) {
Utils.unzipFiles(zip, mediaDir, new String[] { c }, numToName);
}
++i;
publishProgress(new TaskData(res.getString(R.string.import_media_count, (i + 1) * 100 / total)));
}
zip.close();
// delete tmp dir
BackupManager.removeDir(dir);
publishProgress(new TaskData(res.getString(R.string.import_update_counts)));
// Update the counts
DeckTask.TaskData result = doInBackgroundLoadDeckCounts(new TaskData(col));
if (result == null) {
return null;
}
return new TaskData(addedCount, result.getObjArray(), true);
} catch (RuntimeException e) {
Log.e(AnkiDroidApp.TAG, "doInBackgroundImportReplace - RuntimeException: ", e);
AnkiDroidApp.saveExceptionReportFile(e, "doInBackgroundImportReplace1");
return new TaskData(false);
} catch (FileNotFoundException e) {
Log.e(AnkiDroidApp.TAG, "doInBackgroundImportReplace - FileNotFoundException: ", e);
AnkiDroidApp.saveExceptionReportFile(e, "doInBackgroundImportReplace2");
return new TaskData(false);
} catch (IOException e) {
Log.e(AnkiDroidApp.TAG, "doInBackgroundImportReplace - IOException: ", e);
AnkiDroidApp.saveExceptionReportFile(e, "doInBackgroundImportReplace3");
return new TaskData(false);
}
}
use of com.ichi2.async.CollectionTask.TASK_TYPE.IMPORT in project AnkiChinaAndroid by ankichinateam.
the class AnkiActivity method showImportDialog.
@TargetApi(Build.VERSION_CODES.KITKAT)
@Override
public void showImportDialog(int id, String message) {
// On API19+ we only use import dialog to confirm, otherwise we use it the whole time
if ((CompatHelper.getSdkVersion() < 19) || (id == ImportDialog.DIALOG_IMPORT_ADD_CONFIRM) || (id == ImportDialog.DIALOG_IMPORT_REPLACE_CONFIRM)) {
Timber.d("showImportDialog() delegating to ImportDialog");
AsyncDialogFragment newFragment = ImportDialog.newInstance(id, message, this);
showAsyncDialogFragment(newFragment);
} else {
Timber.d("showImportDialog() delegating to file picker intent");
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("*/*");
intent.putExtra("android.content.extra.SHOW_ADVANCED", true);
intent.putExtra("android.content.extra.FANCY", true);
intent.putExtra("android.content.extra.SHOW_FILESIZE", true);
startActivityForResultWithoutAnimation(intent, PICK_APKG_FILE);
}
}
use of com.ichi2.async.CollectionTask.TASK_TYPE.IMPORT in project AnkiChinaAndroid by ankichinateam.
the class DialogHandler method handleMessage.
@Override
public void handleMessage(Message msg) {
Bundle msgData = msg.getData();
String messageName = sMessageNameList[msg.what];
UsageAnalytics.sendAnalyticsScreenView(messageName);
Timber.i("Handling Message: %s", messageName);
if (msg.what == MSG_SHOW_COLLECTION_LOADING_ERROR_DIALOG) {
// Collection could not be opened
mActivity.get().showDatabaseErrorDialog(DatabaseErrorDialog.DIALOG_LOAD_FAILED);
} else if (msg.what == MSG_SHOW_COLLECTION_IMPORT_REPLACE_DIALOG) {
// Handle import of collection package APKG
mActivity.get().showImportDialog(ImportDialog.DIALOG_IMPORT_REPLACE_CONFIRM, msgData.getString("importPath"));
} else if (msg.what == MSG_SHOW_COLLECTION_IMPORT_ADD_DIALOG) {
// Handle import of deck package APKG
mActivity.get().showImportDialog(ImportDialog.DIALOG_IMPORT_ADD_CONFIRM, msgData.getString("importPath"));
} else if (msg.what == MSG_SHOW_SYNC_ERROR_DIALOG) {
if (mActivity.get() instanceof DeckPicker) {
int id = msgData.getInt("dialogType");
String message = msgData.getString("dialogMessage");
((DeckPicker) mActivity.get()).showSyncErrorDialog(id, message);
}
} else if (msg.what == MSG_SHOW_EXPORT_COMPLETE_DIALOG) {
// Export complete
AsyncDialogFragment f = DeckPickerExportCompleteDialog.newInstance(msgData.getString("exportPath"));
mActivity.get().showAsyncDialogFragment(f);
} else if (msg.what == MSG_SHOW_MEDIA_CHECK_COMPLETE_DIALOG) {
if (mActivity.get() instanceof DeckPicker) {
// Media check results
int id = msgData.getInt("dialogType");
if (id != MediaCheckDialog.DIALOG_CONFIRM_MEDIA_CHECK) {
List<List<String>> checkList = new ArrayList<>();
checkList.add(msgData.getStringArrayList("nohave"));
checkList.add(msgData.getStringArrayList("unused"));
checkList.add(msgData.getStringArrayList("invalid"));
((DeckPicker) mActivity.get()).showMediaCheckDialog(id, checkList);
}
}
} else if (msg.what == MSG_SHOW_DATABASE_ERROR_DIALOG) {
// Database error dialog
mActivity.get().showDatabaseErrorDialog(msgData.getInt("dialogType"));
} else if (msg.what == MSG_SHOW_FORCE_FULL_SYNC_DIALOG) {
// Confirmation dialog for forcing full sync
ConfirmationDialog dialog = new ConfirmationDialog();
Runnable confirm = new Runnable() {
@Override
public void run() {
// Bypass the check once the user confirms
CollectionHelper.getInstance().getCol(AnkiDroidApp.getInstance()).modSchemaNoCheck();
}
};
dialog.setConfirm(confirm);
dialog.setArgs(msgData.getString("message"));
(mActivity.get()).showDialogFragment(dialog);
} else if (msg.what == MSG_DO_SYNC) {
if (mActivity.get() instanceof DeckPicker) {
SharedPreferences preferences = AnkiDroidApp.getSharedPrefs(mActivity.get());
Resources res = mActivity.get().getResources();
Collection col = mActivity.get().getCol();
String hkey = preferences.getString("hkey", "");
long millisecondsSinceLastSync = col.getTime().intTimeMS() - preferences.getLong("lastSyncTime", 0);
boolean limited = millisecondsSinceLastSync < INTENT_SYNC_MIN_INTERVAL;
if (!limited && hkey.length() > 0 && Connection.isOnline()) {
((DeckPicker) mActivity.get()).sync();
} else {
String err = res.getString(R.string.sync_error);
if (limited) {
long remainingTimeInSeconds = Math.max((INTENT_SYNC_MIN_INTERVAL - millisecondsSinceLastSync) / 1000, 1);
// getQuantityString needs an int
int remaining = (int) Math.min(Integer.MAX_VALUE, remainingTimeInSeconds);
String message = res.getQuantityString(R.plurals.sync_automatic_sync_needs_more_time, remaining, remaining);
mActivity.get().showSimpleNotification(err, message, NotificationChannels.Channel.SYNC);
} else {
mActivity.get().showSimpleNotification(err, res.getString(R.string.youre_offline), NotificationChannels.Channel.SYNC);
}
}
mActivity.get().finishWithoutAnimation();
}
}
}
Aggregations