com.ichi2.libanki.sync.FullSyncer.java Source code

Java tutorial

Introduction

Here is the source code for com.ichi2.libanki.sync.FullSyncer.java

Source

/***************************************************************************************
 * Copyright (c) 2012 Norbert Nagold <norbert.nagold@gmail.com>                         *
 *                                                                                      *
 * This program is free software; you can redistribute it and/or modify it under        *
 * the terms of the GNU General Public License as published by the Free Software        *
 * Foundation; either version 3 of the License, or (at your option) any later           *
 * version.                                                                             *
 *                                                                                      *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY      *
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A      *
 * PARTICULAR PURPOSE. See the GNU General Public License for more details.             *
 *                                                                                      *
 * You should have received a copy of the GNU General Public License along with         *
 * this program.  If not, see <http://www.gnu.org/licenses/>.                           *
 ****************************************************************************************/

package com.ichi2.libanki.sync;

import android.database.sqlite.SQLiteDatabaseCorruptException;

import com.ichi2.anki.AnkiDatabaseManager;
import com.ichi2.anki.AnkiDb;
import com.ichi2.anki.R;
import com.ichi2.anki.exception.UnknownHttpResponseException;
import com.ichi2.async.Connection;
import com.ichi2.libanki.Collection;
import com.ichi2.libanki.Consts;
import com.ichi2.libanki.Utils;
import com.ichi2.utils.VersionUtils;

import org.apache.http.HttpResponse;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Locale;

import timber.log.Timber;

public class FullSyncer extends HttpSyncer {

    Collection mCol;
    Connection mCon;

    public FullSyncer(Collection col, String hkey, Connection con) {
        super(hkey, con);
        mPostVars = new HashMap<String, Object>();
        mPostVars.put("k", hkey);
        mPostVars.put("v",
                String.format(Locale.US, "ankidroid,%s,%s", VersionUtils.getPkgVersionName(), Utils.platDesc()));
        mCol = col;
        mCon = con;
    }

    @Override
    public String syncURL() {
        return Consts.SYNC_BASE + "sync/";
    }

    @Override
    public Object[] download() throws UnknownHttpResponseException {
        InputStream cont;
        try {
            HttpResponse ret = super.req("download");
            if (ret == null) {
                return null;
            }
            cont = ret.getEntity().getContent();
        } catch (IllegalStateException e1) {
            throw new RuntimeException(e1);
        } catch (IOException e1) {
            return null;
        }
        if (mCol == null) {
            Timber.e("Collection was unexpectedly null");
            return null;
        }
        String path = mCol.getPath();
        mCol.close(false);
        mCol = null;
        String tpath = path + ".tmp";
        try {
            super.writeToFile(cont, tpath);
        } catch (IOException e) {
            Timber.e(e, "Full sync failed to download collection.");
            return new Object[] { "sdAccessError" };
        }
        // first check, if account needs upgrade (from 1.2)
        try {
            FileInputStream fis = new FileInputStream(tpath);
            if (super.stream2String(fis, 15).equals("upgradeRequired")) {
                return new Object[] { "upgradeRequired" };
            }
        } catch (FileNotFoundException e1) {
            throw new RuntimeException(e1);
        }
        // check the received file is ok
        mCon.publishProgress(R.string.sync_check_download_file);
        try {
            AnkiDb d = AnkiDatabaseManager.getDatabase(tpath);
            if (!d.queryString("PRAGMA integrity_check").equalsIgnoreCase("ok")) {
                Timber.e("Full sync - downloaded file corrupt");
                return new Object[] { "remoteDbError" };
            }
        } catch (SQLiteDatabaseCorruptException e) {
            Timber.e("Full sync - downloaded file corrupt");
            return new Object[] { "remoteDbError" };
        } finally {
            AnkiDatabaseManager.closeDatabase(tpath);
        }
        // overwrite existing collection
        File newFile = new File(tpath);
        if (newFile.renameTo(new File(path))) {
            return new Object[] { "success" };
        } else {
            return new Object[] { "overwriteError" };
        }
    }

    @Override
    public Object[] upload() throws UnknownHttpResponseException {
        // make sure it's ok before we try to upload
        mCon.publishProgress(R.string.sync_check_upload_file);
        if (!mCol.getDb().queryString("PRAGMA integrity_check").equalsIgnoreCase("ok")) {
            return new Object[] { "dbError" };
        }
        if (!mCol.basicCheck()) {
            return new Object[] { "dbError" };
        }
        // apply some adjustments, then upload
        mCol.beforeUpload();
        String filePath = mCol.getPath();
        mCol.close();
        HttpResponse ret;
        mCon.publishProgress(R.string.sync_uploading_message);
        try {
            ret = super.req("upload", new FileInputStream(filePath));
            if (ret == null) {
                return null;
            }
            int status = ret.getStatusLine().getStatusCode();
            if (status != 200) {
                // error occurred
                return new Object[] { "error", status, ret.getStatusLine().getReasonPhrase() };
            } else {
                return new Object[] { super.stream2String(ret.getEntity().getContent()) };
            }
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        } catch (IllegalStateException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}