Search in sources :

Example 31 with Media

use of com.ichi2.libanki.Media in project Anki-Android by Ramblurr.

the class DeckTask method doInBackgroundExportApkg.

private TaskData doInBackgroundExportApkg(TaskData... params) {
    // Log.i(AnkiDroidApp.TAG, "doInBackgroundExportApkg");
    Object[] data = params[0].getObjArray();
    String colPath = (String) data[0];
    String apkgPath = (String) data[1];
    boolean includeMedia = (Boolean) data[2];
    byte[] buf = new byte[1024];
    try {
        try {
            AnkiDb d = AnkiDatabaseManager.getDatabase(colPath);
        } catch (SQLiteDatabaseCorruptException e) {
            // collection is invalid
            return new TaskData(false);
        } finally {
            AnkiDatabaseManager.closeDatabase(colPath);
        }
        // export collection
        ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(apkgPath));
        FileInputStream colFin = new FileInputStream(colPath);
        ZipEntry ze = new ZipEntry("collection.anki2");
        zos.putNextEntry(ze);
        int len;
        while ((len = colFin.read(buf)) >= 0) {
            zos.write(buf, 0, len);
        }
        zos.closeEntry();
        colFin.close();
        // export media
        JSONObject media = new JSONObject();
        if (includeMedia) {
            File mediaDir = new File(AnkiDroidApp.getCurrentAnkiDroidMediaDir());
            if (mediaDir.exists() && mediaDir.isDirectory()) {
                File[] mediaFiles = mediaDir.listFiles();
                int c = 0;
                for (File f : mediaFiles) {
                    FileInputStream mediaFin = new FileInputStream(f);
                    ze = new ZipEntry(Integer.toString(c));
                    zos.putNextEntry(ze);
                    while ((len = mediaFin.read(buf)) >= 0) {
                        zos.write(buf, 0, len);
                    }
                    zos.closeEntry();
                    media.put(Integer.toString(c), f.getName());
                }
            }
        }
        ze = new ZipEntry("media");
        zos.putNextEntry(ze);
        InputStream mediaIn = new ByteArrayInputStream(Utils.jsonToString(media).getBytes("UTF-8"));
        while ((len = mediaIn.read(buf)) >= 0) {
            zos.write(buf, 0, len);
        }
        zos.closeEntry();
        zos.close();
    } catch (FileNotFoundException e) {
        return new TaskData(false);
    } catch (IOException e) {
        return new TaskData(false);
    } catch (JSONException e) {
        return new TaskData(false);
    }
    return new TaskData(true);
}
Also used : AnkiDb(com.ichi2.anki.AnkiDb) ByteArrayInputStream(java.io.ByteArrayInputStream) FileInputStream(java.io.FileInputStream) InputStream(java.io.InputStream) ZipEntry(java.util.zip.ZipEntry) FileNotFoundException(java.io.FileNotFoundException) SQLiteDatabaseCorruptException(android.database.sqlite.SQLiteDatabaseCorruptException) JSONException(org.json.JSONException) IOException(java.io.IOException) FileInputStream(java.io.FileInputStream) JSONObject(org.json.JSONObject) ByteArrayInputStream(java.io.ByteArrayInputStream) ZipOutputStream(java.util.zip.ZipOutputStream) FileOutputStream(java.io.FileOutputStream) JSONObject(org.json.JSONObject) ZipFile(java.util.zip.ZipFile) File(java.io.File)

Example 32 with Media

use of com.ichi2.libanki.Media in project Anki-Android by Ramblurr.

the class SdCardReceiver method onReceive.

@Override
public void onReceive(Context context, Intent intent) {
    if (intent.getAction().equals(Intent.ACTION_MEDIA_EJECT)) {
        // Log.i(AnkiDroidApp.TAG, "media eject detected - closing collection and sending broadcast");
        Intent i = new Intent();
        i.setAction(MEDIA_EJECT);
        context.sendBroadcast(i);
        Collection col = AnkiDroidApp.getCol();
        if (col != null) {
            col.close();
        }
    } else if (intent.getAction().equals(Intent.ACTION_MEDIA_MOUNTED)) {
        // Log.i(AnkiDroidApp.TAG, "media mount detected - sending broadcast");
        Intent i = new Intent();
        i.setAction(MEDIA_MOUNT);
        context.sendBroadcast(i);
    }
}
Also used : Collection(com.ichi2.libanki.Collection) Intent(android.content.Intent)

Example 33 with Media

use of com.ichi2.libanki.Media in project Anki-Android by Ramblurr.

the class NoteService method importMediaToDirectory.

/**
 * Considering the field is new, if it has media handle it
 *
 * @param field
 */
private static void importMediaToDirectory(IField field) {
    String tmpMediaPath = null;
    switch(field.getType()) {
        case AUDIO:
            tmpMediaPath = field.getAudioPath();
            break;
        case IMAGE:
            tmpMediaPath = field.getImagePath();
            break;
        case TEXT:
        default:
            break;
    }
    if (tmpMediaPath != null) {
        try {
            File inFile = new File(tmpMediaPath);
            if (inFile.exists()) {
                Collection col = AnkiDroidApp.getCol();
                String mediaDir = col.getMedia().getDir() + "/";
                File mediaDirFile = new File(mediaDir);
                File parent = inFile.getParentFile();
                // If already there.
                if (mediaDirFile.getAbsolutePath().contentEquals(parent.getAbsolutePath())) {
                    return;
                }
                File outFile = new File(mediaDir + inFile.getName());
                if (!outFile.exists()) {
                    if (field.hasTemporaryMedia()) {
                        // Move
                        inFile.renameTo(outFile);
                    } else {
                        // Copy
                        InputStream in = new FileInputStream(tmpMediaPath);
                        OutputStream out = new FileOutputStream(outFile.getAbsolutePath());
                        byte[] buf = new byte[1024];
                        int len;
                        while ((len = in.read(buf)) > 0) {
                            out.write(buf, 0, len);
                        }
                        in.close();
                        out.close();
                    }
                    switch(field.getType()) {
                        case AUDIO:
                            field.setAudioPath(outFile.getAbsolutePath());
                            break;
                        case IMAGE:
                            field.setImagePath(outFile.getAbsolutePath());
                            break;
                        default:
                            break;
                    }
                }
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
Also used : FileInputStream(java.io.FileInputStream) InputStream(java.io.InputStream) OutputStream(java.io.OutputStream) FileOutputStream(java.io.FileOutputStream) FileOutputStream(java.io.FileOutputStream) Collection(com.ichi2.libanki.Collection) IOException(java.io.IOException) File(java.io.File) FileInputStream(java.io.FileInputStream)

Example 34 with Media

use of com.ichi2.libanki.Media 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);
    }
}
Also used : HashMap(java.util.HashMap) FileNotFoundException(java.io.FileNotFoundException) IOException(java.io.IOException) ZipFile(java.util.zip.ZipFile) Collection(com.ichi2.libanki.Collection) JsonReader(com.google.gson.stream.JsonReader) FileReader(java.io.FileReader) Resources(android.content.res.Resources) ZipFile(java.util.zip.ZipFile) File(java.io.File) HashMap(java.util.HashMap) Map(java.util.Map) TreeMap(java.util.TreeMap)

Example 35 with Media

use of com.ichi2.libanki.Media in project Anki-Android by Ramblurr.

the class NoteService method saveMedia.

/**
 * Saves the multimedia associated with this card to proper path inside anki folder. For each field associated with
 * the note it checks for the following condition a. The field content should have changed b. The field content does
 * not already point to a media inside anki media path If both condition satisfies then it copies the file inside
 * the media path and deletes the file referenced by the note
 *
 * @param note
 */
public static void saveMedia(final MultimediaEditableNote noteNew) {
    // if (noteNew.getModelId() == noteOld.getModelId())
    // {
    // int fieldCount = noteNew.getNumberOfFields();
    // for (int i = 0; i < fieldCount; i++)
    // {
    // IField newField = noteNew.getField(i);
    // IField oldField = noteOld.getField(i);
    // if
    // (newField.getFormattedValue().equals(oldField.getFormattedValue()))
    // {
    // continue;
    // }
    // importMediaToDirectory(newField);
    // }
    // }
    // else
    // {
    int fieldCount = noteNew.getNumberOfFields();
    for (int i = 0; i < fieldCount; i++) {
        IField newField = noteNew.getField(i);
        importMediaToDirectory(newField);
    }
// }
}
Also used : IField(com.ichi2.anki.multimediacard.fields.IField)

Aggregations

File (java.io.File)43 IOException (java.io.IOException)26 Collection (com.ichi2.libanki.Collection)25 JSONObject (com.ichi2.utils.JSONObject)19 ArrayList (java.util.ArrayList)17 Test (org.junit.Test)17 ZipFile (java.util.zip.ZipFile)14 JSONException (com.ichi2.utils.JSONException)10 FileOutputStream (java.io.FileOutputStream)10 List (java.util.List)10 JSONArray (com.ichi2.utils.JSONArray)9 FileInputStream (java.io.FileInputStream)9 FileNotFoundException (java.io.FileNotFoundException)9 SharedPreferences (android.content.SharedPreferences)8 JSONObject (org.json.JSONObject)8 Resources (android.content.res.Resources)7 Uri (android.net.Uri)7 RobolectricTest (com.ichi2.anki.RobolectricTest)7 ConfirmModSchemaException (com.ichi2.anki.exception.ConfirmModSchemaException)7 AnkiPackageImporter (com.ichi2.libanki.importer.AnkiPackageImporter)7