use of com.ichi2.anki.Download in project Anki-Android by Ramblurr.
the class DeckPicker method onCreateDialog.
@Override
protected Dialog onCreateDialog(int id) {
StyledDialog dialog;
Resources res = getResources();
StyledDialog.Builder builder = new StyledDialog.Builder(this);
switch(id) {
case DIALOG_OK:
builder.setPositiveButton(R.string.ok, null);
dialog = builder.create();
break;
case DIALOG_NO_SDCARD:
builder.setMessage("The SD card could not be read. Please, turn off USB storage.");
builder.setPositiveButton(R.string.ok, null);
dialog = builder.create();
break;
case DIALOG_SELECT_HELP:
builder.setTitle(res.getString(R.string.help_title));
builder.setItems(new String[] { res.getString(R.string.help_tutorial), res.getString(R.string.help_online), res.getString(R.string.help_faq) }, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {
if (arg1 == 0) {
createTutorialDeck();
} else {
if (Utils.isIntentAvailable(DeckPicker.this, "android.intent.action.VIEW")) {
Intent intent = new Intent("android.intent.action.VIEW", Uri.parse(getResources().getString(arg1 == 1 ? R.string.link_help : R.string.link_faq)));
startActivity(intent);
} else {
startActivity(new Intent(DeckPicker.this, Info.class));
}
}
}
});
dialog = builder.create();
break;
case DIALOG_CONNECTION_ERROR:
builder.setTitle(res.getString(R.string.connection_error_title));
builder.setIcon(R.drawable.ic_dialog_alert);
builder.setMessage(res.getString(R.string.connection_error_message));
builder.setPositiveButton(res.getString(R.string.retry), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
sync();
}
});
builder.setNegativeButton(res.getString(R.string.cancel), null);
dialog = builder.create();
break;
case DIALOG_SYNC_CONFLICT_RESOLUTION:
builder.setTitle(res.getString(R.string.sync_conflict_title));
builder.setIcon(android.R.drawable.ic_input_get);
builder.setMessage(res.getString(R.string.sync_conflict_message));
builder.setPositiveButton(res.getString(R.string.sync_conflict_local), mSyncConflictResolutionListener);
builder.setNeutralButton(res.getString(R.string.sync_conflict_remote), mSyncConflictResolutionListener);
builder.setNegativeButton(res.getString(R.string.sync_conflict_cancel), mSyncConflictResolutionListener);
builder.setCancelable(true);
dialog = builder.create();
break;
case DIALOG_LOAD_FAILED:
builder.setMessage(res.getString(R.string.open_collection_failed_message, BackupManager.BROKEN_DECKS_SUFFIX, res.getString(R.string.repair_deck)));
builder.setTitle(R.string.open_collection_failed_title);
builder.setIcon(R.drawable.ic_dialog_alert);
builder.setPositiveButton(res.getString(R.string.error_handling_options), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
showDialog(DIALOG_ERROR_HANDLING);
}
});
builder.setNegativeButton(res.getString(R.string.close), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
finishWithAnimation();
}
});
builder.setOnCancelListener(new OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
finishWithAnimation();
}
});
dialog = builder.create();
break;
case DIALOG_DB_ERROR:
builder.setMessage(R.string.answering_error_message);
builder.setTitle(R.string.answering_error_title);
builder.setIcon(R.drawable.ic_dialog_alert);
builder.setPositiveButton(res.getString(R.string.error_handling_options), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
showDialog(DIALOG_ERROR_HANDLING);
}
});
builder.setNeutralButton(res.getString(R.string.answering_error_report), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent i = new Intent(DeckPicker.this, Feedback.class);
i.putExtra("request", RESULT_DB_ERROR);
dialog.dismiss();
startActivityForResult(i, REPORT_ERROR);
if (AnkiDroidApp.SDK_VERSION > 4) {
ActivityTransitionAnimation.slide(DeckPicker.this, ActivityTransitionAnimation.RIGHT);
}
}
});
builder.setNegativeButton(res.getString(R.string.close), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (!AnkiDroidApp.colIsOpen()) {
finishWithAnimation();
}
}
});
builder.setCancelable(true);
dialog = builder.create();
break;
case DIALOG_ERROR_HANDLING:
builder.setTitle(res.getString(R.string.error_handling_title));
builder.setIcon(R.drawable.ic_dialog_alert);
builder.setSingleChoiceItems(new String[] { "1" }, 0, null);
builder.setOnCancelListener(new OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
if (mLoadFailed) {
// dialog has been called because collection could not be opened
showDialog(DIALOG_LOAD_FAILED);
} else {
// dialog has been called because a db error happened
showDialog(DIALOG_DB_ERROR);
}
}
});
builder.setNegativeButton(res.getString(R.string.cancel), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (mLoadFailed) {
// dialog has been called because collection could not be opened
showDialog(DIALOG_LOAD_FAILED);
} else {
// dialog has been called because a db error happened
showDialog(DIALOG_DB_ERROR);
}
}
});
dialog = builder.create();
break;
case DIALOG_USER_NOT_LOGGED_IN_ADD_SHARED_DECK:
builder.setTitle(res.getString(R.string.connection_error_title));
builder.setIcon(R.drawable.ic_dialog_alert);
builder.setMessage(res.getString(R.string.no_user_password_error_message));
builder.setNegativeButton(res.getString(R.string.cancel), null);
builder.setPositiveButton(res.getString(R.string.log_in), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent myAccount = new Intent(DeckPicker.this, MyAccount.class);
myAccount.putExtra("notLoggedIn", true);
startActivityForResult(myAccount, LOG_IN_FOR_SHARED_DECK);
if (AnkiDroidApp.SDK_VERSION > 4) {
ActivityTransitionAnimation.slide(DeckPicker.this, ActivityTransitionAnimation.FADE);
}
}
});
dialog = builder.create();
break;
case DIALOG_USER_NOT_LOGGED_IN_SYNC:
builder.setTitle(res.getString(R.string.connection_error_title));
builder.setIcon(R.drawable.ic_dialog_alert);
builder.setMessage(res.getString(R.string.no_user_password_error_message));
builder.setNegativeButton(res.getString(R.string.cancel), null);
builder.setPositiveButton(res.getString(R.string.log_in), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent myAccount = new Intent(DeckPicker.this, MyAccount.class);
myAccount.putExtra("notLoggedIn", true);
startActivityForResult(myAccount, LOG_IN_FOR_SYNC);
if (AnkiDroidApp.SDK_VERSION > 4) {
ActivityTransitionAnimation.slide(DeckPicker.this, ActivityTransitionAnimation.FADE);
}
}
});
dialog = builder.create();
break;
case DIALOG_NO_CONNECTION:
builder.setTitle(res.getString(R.string.connection_error_title));
builder.setIcon(R.drawable.ic_dialog_alert);
builder.setMessage(res.getString(R.string.connection_needed));
builder.setPositiveButton(res.getString(R.string.ok), null);
dialog = builder.create();
break;
case DIALOG_DELETE_DECK:
if (!AnkiDroidApp.colIsOpen() || mDeckList == null) {
return null;
}
// Message is set in onPrepareDialog
builder.setTitle(res.getString(R.string.delete_deck_title));
builder.setIcon(R.drawable.ic_dialog_alert);
builder.setPositiveButton(res.getString(R.string.yes), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
DeckTask.launchDeckTask(DeckTask.TASK_TYPE_DELETE_DECK, new DeckTask.TaskListener() {
@Override
public void onPreExecute() {
mProgressDialog = StyledProgressDialog.show(DeckPicker.this, "", getResources().getString(R.string.delete_deck), true);
}
@Override
public void onPostExecute(TaskData result) {
if (result == null) {
return;
}
Object[] res = result.getObjArray();
updateDecksList((TreeSet<Object[]>) res[0], (Integer) res[1], (Integer) res[2]);
if (mFragmented) {
selectDeck(AnkiDroidApp.getCol().getDecks().selected());
}
if (mProgressDialog.isShowing()) {
try {
mProgressDialog.dismiss();
} catch (Exception e) {
Log.e(AnkiDroidApp.TAG, "onPostExecute - Dialog dismiss Exception = " + e.getMessage());
}
}
}
@Override
public void onProgressUpdate(TaskData... values) {
}
}, new TaskData(AnkiDroidApp.getCol(), mCurrentDid));
}
});
builder.setNegativeButton(res.getString(R.string.cancel), null);
dialog = builder.create();
break;
case DIALOG_SELECT_STATISTICS_TYPE:
dialog = ChartBuilder.getStatisticsDialog(this, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
boolean muh = mFragmented ? AnkiDroidApp.getSharedPrefs(AnkiDroidApp.getInstance().getBaseContext()).getBoolean("statsRange", true) : true;
DeckTask.launchDeckTask(DeckTask.TASK_TYPE_LOAD_STATISTICS, mLoadStatisticsHandler, new DeckTask.TaskData(AnkiDroidApp.getCol(), which, mFragmented ? AnkiDroidApp.getSharedPrefs(AnkiDroidApp.getInstance().getBaseContext()).getBoolean("statsRange", true) : true));
}
}, mFragmented);
break;
case DIALOG_CONTEXT_MENU:
String[] entries = new String[3];
// entries[CONTEXT_MENU_DECK_SUMMARY] =
// "XXXsum";//res.getStringArray(R.array.statistics_type_labels)[0];
// entries[CONTEXT_MENU_CUSTOM_DICTIONARY] =
// res.getString(R.string.contextmenu_deckpicker_set_custom_dictionary);
// entries[CONTEXT_MENU_RESET_LANGUAGE] =
// res.getString(R.string.contextmenu_deckpicker_reset_language_assignments);
entries[CONTEXT_MENU_COLLAPSE_DECK] = res.getString(R.string.contextmenu_deckpicker_collapse_deck);
entries[CONTEXT_MENU_RENAME_DECK] = res.getString(R.string.contextmenu_deckpicker_rename_deck);
entries[CONTEXT_MENU_DELETE_DECK] = res.getString(R.string.contextmenu_deckpicker_delete_deck);
builder.setTitle("Context Menu");
builder.setIcon(R.drawable.ic_menu_manage);
builder.setItems(entries, mContextMenuListener);
dialog = builder.create();
break;
case DIALOG_REPAIR_COLLECTION:
builder.setTitle(res.getString(R.string.backup_repair_deck));
builder.setMessage(res.getString(R.string.repair_deck_dialog, BackupManager.BROKEN_DECKS_SUFFIX));
builder.setIcon(R.drawable.ic_dialog_alert);
builder.setPositiveButton(res.getString(R.string.yes), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
DeckTask.launchDeckTask(DeckTask.TASK_TYPE_REPAIR_DECK, mRepairDeckHandler, new DeckTask.TaskData(AnkiDroidApp.getCol(), AnkiDroidApp.getCollectionPath()));
}
});
builder.setNegativeButton(res.getString(R.string.no), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
showDialog(DIALOG_ERROR_HANDLING);
}
});
builder.setOnCancelListener(new OnCancelListener() {
@Override
public void onCancel(DialogInterface arg0) {
showDialog(DIALOG_ERROR_HANDLING);
}
});
dialog = builder.create();
break;
case DIALOG_SYNC_SANITY_ERROR:
builder.setPositiveButton(getString(R.string.sync_sanity_local), mSyncSanityFailListener);
builder.setNeutralButton(getString(R.string.sync_sanity_remote), mSyncSanityFailListener);
builder.setNegativeButton(res.getString(R.string.sync_conflict_cancel), mSyncSanityFailListener);
builder.setTitle(res.getString(R.string.sync_log_title));
dialog = builder.create();
break;
case DIALOG_SYNC_UPGRADE_REQUIRED:
builder.setMessage(res.getString(R.string.upgrade_required, res.getString(R.string.link_anki)));
builder.setPositiveButton(res.getString(R.string.retry), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
sync("download", mSyncMediaUsn);
}
});
builder.setNegativeButton(res.getString(R.string.cancel), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (mLoadFailed) {
// dialog has been called because collection could not be opened
showDialog(DIALOG_LOAD_FAILED);
} else {
// dialog has been called because a db error happened
showDialog(DIALOG_DB_ERROR);
}
}
});
builder.setOnCancelListener(new OnCancelListener() {
@Override
public void onCancel(DialogInterface arg0) {
if (mLoadFailed) {
// dialog has been called because collection could not be opened
showDialog(DIALOG_LOAD_FAILED);
} else {
// dialog has been called because a db error happened
showDialog(DIALOG_DB_ERROR);
}
}
});
builder.setTitle(res.getString(R.string.sync_log_title));
dialog = builder.create();
break;
case DIALOG_SYNC_LOG:
builder.setTitle(res.getString(R.string.sync_log_title));
builder.setPositiveButton(res.getString(R.string.ok), null);
dialog = builder.create();
break;
case DIALOG_BACKUP_NO_SPACE_LEFT:
builder.setTitle(res.getString(R.string.attention));
builder.setMessage(res.getString(R.string.backup_deck_no_space_left));
builder.setPositiveButton(res.getString(R.string.ok), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
loadCollection();
}
});
// builder.setNegativeButton(res.getString(R.string.dont_show_again), new
// DialogInterface.OnClickListener() {
// @Override
// public void onClick(DialogInterface arg0, int arg1) {
// PrefSettings.getSharedPrefs(getBaseContext()).edit().putBoolean("dontShowLowMemory", true).commit();
// }
// });
builder.setCancelable(true);
builder.setOnCancelListener(new OnCancelListener() {
@Override
public void onCancel(DialogInterface arg0) {
loadCollection();
}
});
dialog = builder.create();
break;
case DIALOG_SD_CARD_NOT_MOUNTED:
if (mNotMountedDialog == null || !mNotMountedDialog.isShowing()) {
mNotMountedDialog = StyledOpenCollectionDialog.show(DeckPicker.this, getResources().getString(R.string.sd_card_not_mounted), new OnCancelListener() {
@Override
public void onCancel(DialogInterface arg0) {
finishWithAnimation();
}
}, new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivityForResult(new Intent(DeckPicker.this, Preferences.class), PREFERENCES_UPDATE);
}
});
}
dialog = null;
break;
case DIALOG_IMPORT:
builder.setTitle(res.getString(R.string.import_title));
builder.setMessage(res.getString(R.string.import_message, mImportPath));
builder.setPositiveButton(res.getString(R.string.import_message_add), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
DeckTask.launchDeckTask(DeckTask.TASK_TYPE_IMPORT, mImportAddListener, new TaskData(AnkiDroidApp.getCol(), mImportPath, false));
mImportPath = null;
}
});
builder.setNeutralButton(res.getString(R.string.import_message_replace), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Resources res = getResources();
StyledDialog.Builder builder = new StyledDialog.Builder(DeckPicker.this);
builder.setTitle(res.getString(R.string.import_title));
builder.setMessage(res.getString(R.string.import_message_replace_confirm, mImportPath));
builder.setPositiveButton(res.getString(R.string.yes), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
DeckTask.launchDeckTask(DeckTask.TASK_TYPE_IMPORT_REPLACE, mImportReplaceListener, new TaskData(AnkiDroidApp.getCol(), mImportPath));
mImportPath = null;
}
});
builder.setNegativeButton(res.getString(R.string.no), null);
builder.show();
}
});
builder.setNegativeButton(res.getString(R.string.cancel), null);
builder.setCancelable(true);
dialog = builder.create();
break;
case DIALOG_IMPORT_SELECT:
builder.setTitle(res.getString(R.string.import_title));
dialog = builder.create();
break;
case DIALOG_IMPORT_HINT:
builder.setTitle(res.getString(R.string.import_title));
builder.setMessage(res.getString(R.string.import_hint, AnkiDroidApp.getCurrentAnkiDroidDirectory()));
builder.setPositiveButton(res.getString(R.string.ok), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
showDialog(DIALOG_IMPORT_SELECT);
}
});
builder.setNegativeButton(res.getString(R.string.cancel), null);
dialog = builder.create();
break;
case DIALOG_IMPORT_LOG:
builder.setIcon(R.drawable.ic_dialog_alert);
builder.setTitle(res.getString(R.string.import_title));
builder.setPositiveButton(res.getString(R.string.ok), null);
dialog = builder.create();
break;
case DIALOG_NO_SPACE_LEFT:
builder.setTitle(res.getString(R.string.attention));
builder.setMessage(res.getString(R.string.sd_space_warning, BackupManager.MIN_FREE_SPACE));
builder.setPositiveButton(res.getString(R.string.ok), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
finishWithAnimation();
}
});
// builder.setNegativeButton(res.getString(R.string.dont_show_again), new
// DialogInterface.OnClickListener() {
// @Override
// public void onClick(DialogInterface arg0, int arg1) {
// PrefSettings.getSharedPrefs(getBaseContext()).edit().putBoolean("dontShowLowMemory", true).commit();
// }
// });
builder.setCancelable(true);
builder.setOnCancelListener(new OnCancelListener() {
@Override
public void onCancel(DialogInterface arg0) {
finishWithAnimation();
}
});
dialog = builder.create();
break;
case DIALOG_RESTORE_BACKUP:
File[] files = BackupManager.getBackups(new File(AnkiDroidApp.getCollectionPath()));
mBackups = new File[files.length];
for (int i = 0; i < files.length; i++) {
mBackups[i] = files[files.length - 1 - i];
}
if (mBackups.length == 0) {
builder.setTitle(getResources().getString(R.string.backup_restore));
builder.setMessage(res.getString(R.string.backup_restore_no_backups));
builder.setPositiveButton(res.getString(R.string.ok), new Dialog.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
showDialog(DIALOG_ERROR_HANDLING);
}
});
builder.setCancelable(true).setOnCancelListener(new OnCancelListener() {
@Override
public void onCancel(DialogInterface arg0) {
showDialog(DIALOG_ERROR_HANDLING);
}
});
} else {
String[] dates = new String[mBackups.length];
for (int i = 0; i < mBackups.length; i++) {
dates[i] = mBackups[i].getName().replaceAll(".*-(\\d{4}-\\d{2}-\\d{2})-(\\d{2})-(\\d{2}).anki2", "$1 ($2:$3 h)");
}
builder.setTitle(res.getString(R.string.backup_restore_select_title));
builder.setIcon(android.R.drawable.ic_input_get);
builder.setSingleChoiceItems(dates, dates.length, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
DeckTask.launchDeckTask(DeckTask.TASK_TYPE_RESTORE_DECK, mRestoreDeckHandler, new DeckTask.TaskData(new Object[] { AnkiDroidApp.getCol(), AnkiDroidApp.getCollectionPath(), mBackups[which].getPath() }));
}
});
builder.setCancelable(true).setOnCancelListener(new OnCancelListener() {
@Override
public void onCancel(DialogInterface arg0) {
showDialog(DIALOG_ERROR_HANDLING);
}
});
}
dialog = builder.create();
break;
case DIALOG_NEW_COLLECTION:
builder.setTitle(res.getString(R.string.backup_new_collection));
builder.setMessage(res.getString(R.string.backup_del_collection_question));
builder.setPositiveButton(res.getString(R.string.ok), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
AnkiDroidApp.closeCollection(false);
String path = AnkiDroidApp.getCollectionPath();
AnkiDatabaseManager.closeDatabase(path);
if (BackupManager.moveDatabaseToBrokenFolder(path, false)) {
loadCollection();
} else {
showDialog(DIALOG_ERROR_HANDLING);
}
}
});
builder.setNegativeButton(res.getString(R.string.no), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {
showDialog(DIALOG_ERROR_HANDLING);
}
});
builder.setCancelable(true);
builder.setOnCancelListener(new OnCancelListener() {
@Override
public void onCancel(DialogInterface arg0) {
showDialog(DIALOG_ERROR_HANDLING);
}
});
dialog = builder.create();
break;
case DIALOG_FULL_SYNC_FROM_SERVER:
builder.setTitle(res.getString(R.string.backup_full_sync_from_server));
builder.setMessage(res.getString(R.string.backup_full_sync_from_server_question));
builder.setPositiveButton(res.getString(R.string.ok), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
sync("download", mSyncMediaUsn);
}
});
builder.setNegativeButton(res.getString(R.string.no), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {
showDialog(DIALOG_ERROR_HANDLING);
}
});
builder.setCancelable(true);
builder.setOnCancelListener(new OnCancelListener() {
@Override
public void onCancel(DialogInterface arg0) {
showDialog(DIALOG_ERROR_HANDLING);
}
});
dialog = builder.create();
break;
default:
dialog = null;
}
if (dialog != null) {
dialog.setOwnerActivity(this);
}
return dialog;
}
use of com.ichi2.anki.Download in project Anki-Android by Ramblurr.
the class Info method downloadCollection.
private void downloadCollection() {
SharedPreferences preferences = AnkiDroidApp.getSharedPrefs(getBaseContext());
String hkey = preferences.getString("hkey", "");
if (hkey.length() == 0) {
showDialog(DIALOG_USER_NOT_LOGGED_IN_SYNC);
} else {
Connection.sync(mSyncListener, new Connection.Payload(new Object[] { hkey, preferences.getBoolean("syncFetchesMedia", true), "download", 0 }));
}
}
use of com.ichi2.anki.Download in project Anki-Android by Ramblurr.
the class Connection method doInBackgroundUpgradeDecks.
private Payload doInBackgroundUpgradeDecks(Payload data) {
// Enable http request canceller
mCancelCallback = new CancelCallback();
String path = (String) data.data[0];
File ankiDir = new File(path);
if (!ankiDir.isDirectory()) {
data.success = false;
data.data = new Object[] { "wrong anki directory" };
return data;
}
// step 1: gather all .anki files into a zip, without media.
// we must store them as 1.anki, 2.anki and provide a map so we don't run into
// encoding issues with the zip file.
File[] fileList = ankiDir.listFiles(new OldAnkiDeckFilter());
List<String> corruptFiles = new ArrayList<String>();
JSONObject map = new JSONObject();
byte[] buf = new byte[1024];
String zipFilename = path + "/upload.zip";
String colFilename = path + AnkiDroidApp.COLLECTION_PATH;
try {
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipFilename));
int n = 1;
for (File f : fileList) {
String deckPath = f.getAbsolutePath();
// set journal mode to delete
try {
AnkiDb d = AnkiDatabaseManager.getDatabase(deckPath);
} catch (SQLiteDatabaseCorruptException e) {
// ignore invalid .anki files
corruptFiles.add(f.getName());
continue;
} finally {
AnkiDatabaseManager.closeDatabase(deckPath);
}
// zip file
String tmpName = n + ".anki";
FileInputStream in = new FileInputStream(deckPath);
ZipEntry ze = new ZipEntry(tmpName);
zos.putNextEntry(ze);
int len;
while ((len = in.read(buf)) >= 0) {
zos.write(buf, 0, len);
}
zos.closeEntry();
map.put(tmpName, f.getName());
n++;
}
// if all .anki files were found corrupted, abort
if (fileList.length == corruptFiles.size()) {
data.success = false;
data.data = new Object[] { sContext.getString(R.string.upgrade_deck_web_upgrade_failed) };
return data;
}
ZipEntry ze = new ZipEntry("map.json");
zos.putNextEntry(ze);
InputStream in = new ByteArrayInputStream(Utils.jsonToString(map).getBytes("UTF-8"));
int len;
while ((len = in.read(buf)) >= 0) {
zos.write(buf, 0, len);
}
zos.closeEntry();
zos.close();
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
} catch (JSONException e) {
throw new RuntimeException(e);
}
File zipFile = new File(zipFilename);
// step 1.1: if it's over 50MB compressed, it must be upgraded by the user
if (zipFile.length() > 50 * 1024 * 1024) {
data.success = false;
data.data = new Object[] { sContext.getString(R.string.upgrade_deck_web_upgrade_exceeds) };
return data;
}
// step 2: upload zip file to upgrade service and get token
BasicHttpSyncer h = new BasicHttpSyncer(null, null);
// note: server doesn't expect it to be gzip compressed, because the zip file is compressed
// enable cancelling
publishProgress(R.string.upgrade_decks_upload, null, true);
try {
HttpResponse resp = h.req("upgrade/upload", new FileInputStream(zipFile), 0, false, null, mCancelCallback);
if (resp == null && !isCancelled()) {
data.success = false;
data.data = new Object[] { sContext.getString(R.string.upgrade_deck_web_upgrade_failed) };
return data;
}
String result;
String key = null;
if (!isCancelled()) {
result = h.stream2String(resp.getEntity().getContent());
if (result != null && result.startsWith("ok:")) {
key = result.split(":")[1];
} else {
data.success = false;
data.data = new Object[] { sContext.getString(R.string.upgrade_deck_web_upgrade_failed) };
return data;
}
}
while (!isCancelled()) {
result = h.stream2String(h.req("upgrade/status?key=" + key).getEntity().getContent());
if (result.equals("error")) {
data.success = false;
data.data = new Object[] { "error" };
return data;
} else if (result.startsWith("waiting:")) {
publishProgress(R.string.upgrade_decks_upload, result.split(":")[1]);
} else if (result.equals("upgrading")) {
publishProgress(new Object[] { R.string.upgrade_decks_upgrade_started });
} else if (result.equals("ready")) {
break;
} else {
data.success = false;
data.data = new Object[] { sContext.getString(R.string.upgrade_deck_web_upgrade_failed) };
return data;
}
Thread.sleep(1000);
}
// gzip compression if the client says it can handle it
if (!isCancelled()) {
publishProgress(new Object[] { R.string.upgrade_decks_downloading });
resp = h.req("upgrade/download?key=" + key, null, 6, true, null, mCancelCallback);
// uploads/downloads have finished so disable cancelling
}
publishProgress(R.string.upgrade_decks_downloading, null, false);
if (isCancelled()) {
return null;
}
if (resp == null) {
data.success = false;
data.data = new Object[] { sContext.getString(R.string.upgrade_deck_web_upgrade_failed) };
return data;
}
// step 5: check the received file is valid
InputStream cont = resp.getEntity().getContent();
if (!h.writeToFile(cont, colFilename)) {
data.success = false;
data.data = new Object[] { sContext.getString(R.string.upgrade_deck_web_upgrade_sdcard, new File(colFilename).length() / 1048576 + 1) };
(new File(colFilename)).delete();
return data;
}
// check the received file is ok
publishProgress(new Object[] { R.string.sync_check_download_file });
publishProgress(R.string.sync_check_download_file);
try {
AnkiDb d = AnkiDatabaseManager.getDatabase(colFilename);
if (!d.queryString("PRAGMA integrity_check").equalsIgnoreCase("ok")) {
data.success = false;
data.data = new Object[] { sContext.getResources() };
return data;
}
} finally {
AnkiDatabaseManager.closeDatabase(colFilename);
}
Collection col = AnkiDroidApp.openCollection(colFilename);
ArrayList<String> decks = col.getDecks().allNames(false);
ArrayList<String> failed = new ArrayList<String>();
ArrayList<File> mediaDirs = new ArrayList<File>();
for (File f : fileList) {
String name = f.getName().replaceFirst("\\.anki$", "");
if (!decks.contains(name)) {
failed.add(name);
} else {
mediaDirs.add(new File(f.getAbsolutePath().replaceFirst("\\.anki$", ".media")));
}
}
File newMediaDir = new File(col.getMedia().getDir());
// step 6. move media files to new media directory
publishProgress(new Object[] { R.string.upgrade_decks_media });
ArrayList<String> failedMedia = new ArrayList<String>();
File curMediaDir = null;
for (File mediaDir : mediaDirs) {
curMediaDir = mediaDir;
// Check if media directory exists and is local
if (!curMediaDir.exists() || !curMediaDir.isDirectory()) {
// If not try finding it in dropbox 1.2.x
curMediaDir = new File(AnkiDroidApp.getDropboxDir(), mediaDir.getName());
if (!curMediaDir.exists() || !curMediaDir.isDirectory()) {
// No media for this deck
continue;
}
}
// Found media dir, copy files
for (File m : curMediaDir.listFiles()) {
try {
Utils.copyFile(m, new File(newMediaDir, m.getName()));
} catch (IOException e) {
failedMedia.add(curMediaDir.getName().replaceFirst("\\.media$", ".anki"));
break;
}
}
}
data.data = new Object[] { failed, failedMedia, newMediaDir.getAbsolutePath() };
data.success = true;
return data;
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (InterruptedException e) {
throw new RuntimeException(e);
} catch (IllegalStateException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
(new File(zipFilename)).delete();
}
}
use of com.ichi2.anki.Download in project Anki-Android by Ramblurr.
the class Connection method doInBackgroundDownloadMissingMedia.
/**
* Downloads any missing media files according to the mediaURL deckvar.
*
* @param data
* @return The return type contains data.resultType and an array of Integer in data.data. data.data[0] is the number
* of total missing media, data.data[1] is the number of downloaded ones.
*/
private Payload doInBackgroundDownloadMissingMedia(Payload data) {
Log.i(AnkiDroidApp.TAG, "DownloadMissingMedia");
HashMap<String, String> missingPaths = new HashMap<String, String>();
HashMap<String, String> missingSums = new HashMap<String, String>();
Decks deck = (Decks) data.data[0];
// pass it to the return object so we close the deck in the deck picker
data.result = deck;
// deck.getDeckName();
String syncName = "";
data.success = false;
data.data = new Object[] { 0, 0, 0 };
// if (!deck.hasKey("mediaURL")) {
// data.success = true;
// return data;
// }
// deck.getVar("mediaURL");
String urlbase = "";
if (urlbase.equals("")) {
data.success = true;
return data;
}
// deck.mediaDir(true);
String mdir = "";
int totalMissing = 0;
int missing = 0;
int grabbed = 0;
Cursor cursor = null;
try {
// deck.getDB().getDatabase().rawQuery("SELECT filename, originalPath FROM media", null);
cursor = null;
String path = null;
String f = null;
while (cursor.moveToNext()) {
f = cursor.getString(0);
path = mdir + "/" + f;
File file = new File(path);
if (!file.exists()) {
missingPaths.put(f, path);
missingSums.put(f, cursor.getString(1));
Log.i(AnkiDroidApp.TAG, "Missing file: " + f);
}
}
} finally {
if (cursor != null) {
cursor.close();
}
}
totalMissing = missingPaths.size();
data.data[0] = new Integer(totalMissing);
if (totalMissing == 0) {
data.success = true;
return data;
}
publishProgress(Boolean.FALSE, new Integer(totalMissing), new Integer(0), syncName);
URL url = null;
HttpURLConnection connection = null;
String path = null;
String sum = null;
int readbytes = 0;
byte[] buf = new byte[4096];
for (String file : missingPaths.keySet()) {
try {
android.net.Uri uri = android.net.Uri.parse(Uri.encode(urlbase, ":/@%") + Uri.encode(file));
url = new URI(uri.toString()).toURL();
connection = (HttpURLConnection) url.openConnection();
connection.connect();
if (connection.getResponseCode() == 200) {
path = missingPaths.get(file);
InputStream is = connection.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is, 4096);
FileOutputStream fos = new FileOutputStream(path);
while ((readbytes = bis.read(buf, 0, 4096)) != -1) {
fos.write(buf, 0, readbytes);
Log.i(AnkiDroidApp.TAG, "Downloaded " + readbytes + " file: " + path);
}
fos.close();
// Verify with checksum
sum = missingSums.get(file);
if (true) {
// sum.equals("") || sum.equals(Utils.fileChecksum(path))) {
grabbed++;
} else {
// Download corrupted, delete file
Log.i(AnkiDroidApp.TAG, "Downloaded media file " + path + " failed checksum.");
File f = new File(path);
f.delete();
missing++;
}
} else {
Log.e(AnkiDroidApp.TAG, "Connection error (" + connection.getResponseCode() + ") while retrieving media file " + urlbase + file);
Log.e(AnkiDroidApp.TAG, "Connection message: " + connection.getResponseMessage());
if (missingSums.get(file).equals("")) {
// Ignore and keep going
missing++;
} else {
data.success = false;
data.data = new Object[] { file };
return data;
}
}
connection.disconnect();
} catch (URISyntaxException e) {
Log.e(AnkiDroidApp.TAG, Log.getStackTraceString(e));
} catch (MalformedURLException e) {
Log.e(AnkiDroidApp.TAG, Log.getStackTraceString(e));
Log.e(AnkiDroidApp.TAG, "MalformedURLException while download media file " + path);
if (missingSums.get(file).equals("")) {
// Ignore and keep going
missing++;
} else {
data.success = false;
data.data = new Object[] { file };
return data;
}
} catch (IOException e) {
Log.e(AnkiDroidApp.TAG, Log.getStackTraceString(e));
Log.e(AnkiDroidApp.TAG, "IOException while download media file " + path);
if (missingSums.get(file).equals("")) {
// Ignore and keep going
missing++;
} else {
data.success = false;
data.data = new Object[] { file };
return data;
}
} finally {
if (connection != null) {
connection.disconnect();
}
}
publishProgress(Boolean.TRUE, new Integer(totalMissing), new Integer(grabbed + missing), syncName);
}
data.data[1] = new Integer(grabbed);
data.data[2] = new Integer(missing);
data.success = true;
return data;
}
use of com.ichi2.anki.Download in project Anki-Android by Ramblurr.
the class DownloadManagerService method addIncompleteDownloads.
// It could be part of the AIDL Interface but at the moment no Activity uses it directly
public void addIncompleteDownloads() {
Log.i(AnkiDroidApp.TAG, "DownloadManagerService - Adding incomplete downloads:");
File dir = new File(mDestination + "/tmp/");
File[] fileList = dir.listFiles(new IncompleteDownloadsFilter());
if (fileList != null) {
for (File file : fileList) {
String filename = file.getName();
Log.i(AnkiDroidApp.TAG, "Filename = " + filename);
// Personal decks
if (filename.endsWith(".anki.tmp")) {
Download download = new Download(filename.substring(0, filename.length() - ".anki.tmp".length()));
download.setDownloaded(file.length());
mPersonalDeckDownloads.add(download);
} else // Shared decks
if (filename.endsWith(".shared.zip.tmp")) {
filename = filename.substring(0, filename.length() - ".shared.zip.tmp".length());
int lastDotPosition = filename.lastIndexOf(".");
String identifier = filename.substring(lastDotPosition + 1, filename.length());
String title = filename.substring(0, lastDotPosition);
SharedDeckDownload download = new SharedDeckDownload(Integer.parseInt(identifier), title);
download.setDownloaded(file.length());
mSharedDeckDownloads.add(download);
} else // Shared but not totally updated decks
if (filename.endsWith(".anki.updating")) {
String title = filename.substring(0, filename.length() - ".anki.updating".length());
SharedDeckDownload download = new SharedDeckDownload(title);
SharedPreferences pref = AnkiDroidApp.getSharedPrefs(getBaseContext());
String pausedPref = "paused:" + mDestination + "/tmp/" + download.getFilename() + ".anki.updating";
if (pref.getBoolean(pausedPref, false)) {
download.setStatus(SharedDeckDownload.STATUS_PAUSED);
} else {
download.setStatus(SharedDeckDownload.STATUS_UPDATING);
}
mSharedDeckDownloads.add(download);
}
}
notifyObservers();
}
// If no decks were added, stop the service
stopIfFinished();
}
Aggregations