export / import data

This commit is contained in:
stom79 2019-01-25 11:41:39 +01:00
parent 056f78955e
commit 8c4b4f85aa
7 changed files with 166 additions and 38 deletions

View File

@ -90,7 +90,9 @@ dependencies {
implementation 'com.android.support:multidex:1.0.3'
implementation 'com.google.android.exoplayer:exoplayer:2.9.3'
implementation 'com.github.stom79:android-upload-service:3.4.2-Mastalab'
implementation 'org.apache.poi:poi:3.16'
implementation 'com.github.mabbas007:TagsEditText:1.0.5'
implementation 'com.jaredrummler:material-spinner:1.3.1'
implementation 'com.github.stom79:SQLite2XL:1.0.5'
playstoreImplementation "io.github.kobakei:ratethisapp:$ratethisappLibraryVersion"
}

View File

@ -25,6 +25,7 @@ import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.BitmapFactory;
import android.graphics.PorterDuff;
import android.net.Uri;
import android.os.AsyncTask;
@ -54,6 +55,7 @@ import android.support.v7.widget.Toolbar;
import android.text.Editable;
import android.text.InputFilter;
import android.text.TextWatcher;
import android.util.Log;
import android.util.Patterns;
import android.util.SparseArray;
import android.view.Gravity;
@ -77,15 +79,23 @@ import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;
import com.ajts.androidmads.library.ExcelToSQLite;
import com.ajts.androidmads.library.SQLiteToExcel;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.File;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Random;
import java.util.Stack;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -123,6 +133,7 @@ import fr.gouv.etalab.mastodon.fragments.DisplayMutedInstanceFragment;
import fr.gouv.etalab.mastodon.fragments.DisplayNotificationsFragment;
import fr.gouv.etalab.mastodon.fragments.DisplayPeertubeNotificationsFragment;
import fr.gouv.etalab.mastodon.fragments.DisplayStatusFragment;
import fr.gouv.etalab.mastodon.fragments.SettingsFragment;
import fr.gouv.etalab.mastodon.fragments.SettingsPeertubeFragment;
import fr.gouv.etalab.mastodon.fragments.TabLayoutScheduleFragment;
import fr.gouv.etalab.mastodon.fragments.TabLayoutSettingsFragment;
@ -166,6 +177,7 @@ import static fr.gouv.etalab.mastodon.helper.Helper.changeUser;
import static fr.gouv.etalab.mastodon.helper.Helper.menuAccounts;
import static fr.gouv.etalab.mastodon.helper.Helper.unCheckAllMenuItems;
import static fr.gouv.etalab.mastodon.helper.Helper.updateHeaderAccountInfo;
import static fr.gouv.etalab.mastodon.sqlite.Sqlite.DB_NAME;
public abstract class BaseMainActivity extends BaseActivity
@ -211,6 +223,7 @@ public abstract class BaseMainActivity extends BaseActivity
private FloatingActionButton federatedTimelines;
public static UpdateAccountInfoAsyncTask.SOCIAL social;
SparseArray<Fragment> registeredFragments = new SparseArray<>();
private final int PICK_IMPORT = 5556;
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -222,7 +235,7 @@ public abstract class BaseMainActivity extends BaseActivity
userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
String token = sharedpreferences.getString(Helper.PREF_KEY_OAUTH_TOKEN, null);
instance = sharedpreferences.getString(Helper.PREF_INSTANCE, Helper.getLiveInstance(getApplicationContext()));
SQLiteDatabase db = Sqlite.getInstance(getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
SQLiteDatabase db = Sqlite.getInstance(getApplicationContext(), DB_NAME, null, Sqlite.DB_VERSION).open();
boolean displayFollowInstance = sharedpreferences.getBoolean(Helper.SET_DISPLAY_FOLLOW_INSTANCE, true);
Account account = new AccountDAO(getApplicationContext(), db).getAccountByToken(token);
if( account == null){
@ -1340,6 +1353,61 @@ public abstract class BaseMainActivity extends BaseActivity
startService(backupIntent);
}
return true;
case R.id.action_import_data:
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
if (ContextCompat.checkSelfPermission(BaseMainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) !=
PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(BaseMainActivity.this,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
TootActivity.MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);
return true;
}
}
intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
intent.setType("application/vnd.ms-excel");
String[] mimetypes = {"application/vnd.ms-excel"};
intent.putExtra(Intent.EXTRA_MIME_TYPES, mimetypes);
startActivityForResult(intent, PICK_IMPORT);
}else {
intent.setType("application/vnd.ms-excel");
Intent pickIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
Intent chooserIntent = Intent.createChooser(intent, getString(R.string.toot_select_import));
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[] {pickIntent});
startActivityForResult(chooserIntent, PICK_IMPORT);
}
return true;
case R.id.action_export_data:
SQLiteToExcel sqliteToExcel = new SQLiteToExcel(BaseMainActivity.this, DB_NAME);
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
final String fileName = "Mastalab_export_"+timeStamp+".xls";
sqliteToExcel.exportAllTables(fileName, new SQLiteToExcel.ExportListener() {
@Override
public void onStart() {
}
@Override
public void onCompleted(String filePath) {
final Intent intent = new Intent();
Random r = new Random();
final int notificationIdTmp = r.nextInt(10000);
File file = new File(filePath);
intent.setAction(android.content.Intent.ACTION_VIEW);
Uri uri = Uri.fromFile(file);
intent.setDataAndType(uri, "application/vnd.ms-excel");
Helper.notify_user(getApplicationContext(), intent, notificationIdTmp, BitmapFactory.decodeResource(getResources(),
R.mipmap.ic_launcher), Helper.NotifType.STORE, getString(R.string.save_over), getString(R.string.download_from, fileName));
Toasty.success(getApplicationContext(), getString(R.string.toast_saved),Toast.LENGTH_LONG).show();
}
@Override
public void onError(Exception e) {
Toasty.error(getApplicationContext(), getString(R.string.data_export_error_simple),Toast.LENGTH_LONG).show();
}
});
return true;
default:
return true;
}
@ -1730,7 +1798,7 @@ public abstract class BaseMainActivity extends BaseActivity
bundle.putString("instanceType","PEERTUBE");
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
String token = sharedpreferences.getString(Helper.PREF_KEY_OAUTH_TOKEN, null);
SQLiteDatabase db = Sqlite.getInstance(getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
SQLiteDatabase db = Sqlite.getInstance(getApplicationContext(), DB_NAME, null, Sqlite.DB_VERSION).open();
Account account = new AccountDAO(getApplicationContext(), db).getAccountByToken(token);
bundle.putString("targetedid",account.getUsername());
bundle.putBoolean("ownvideos", true);
@ -2066,7 +2134,7 @@ public abstract class BaseMainActivity extends BaseActivity
bundle.putString("instanceType","PEERTUBE");
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
String token = sharedpreferences.getString(Helper.PREF_KEY_OAUTH_TOKEN, null);
SQLiteDatabase db = Sqlite.getInstance(getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
SQLiteDatabase db = Sqlite.getInstance(getApplicationContext(), DB_NAME, null, Sqlite.DB_VERSION).open();
Account account = new AccountDAO(getApplicationContext(), db).getAccountByToken(token);
bundle.putString("targetedid",account.getUsername());
bundle.putBoolean("ownvideos", true);
@ -2189,7 +2257,7 @@ public abstract class BaseMainActivity extends BaseActivity
startActivity(myIntent);
finish();
}else {
SQLiteDatabase db = Sqlite.getInstance(BaseMainActivity.this, Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
SQLiteDatabase db = Sqlite.getInstance(BaseMainActivity.this, DB_NAME, null, Sqlite.DB_VERSION).open();
Account account = new AccountDAO(getApplicationContext(), db).getAccountByID(userId);
updateHeaderAccountInfo(activity, account, headerLayout);
}
@ -2199,12 +2267,37 @@ public abstract class BaseMainActivity extends BaseActivity
protected void onActivityResult(int requestCode, int resultCode,
Intent data) {
super.onActivityResult(requestCode, resultCode, data);
//noinspection StatementWithEmptyBody
if (requestCode == ERROR_DIALOG_REQUEST_CODE) {
// Adding a fragment via GooglePlayServicesUtil.showErrorDialogFragment
// before the instance state is restored throws an error. So instead,
// set a flag here, which will cause the fragment to delay until
// onPostResume.
if (requestCode == PICK_IMPORT && resultCode == Activity.RESULT_OK) {
if (data == null || data.getData() == null) {
Toasty.error(getApplicationContext(),getString(R.string.toot_select_file_error),Toast.LENGTH_LONG).show();
return;
}
ExcelToSQLite excelToSQLite = new ExcelToSQLite(getApplicationContext(), DB_NAME, true);
String filename = SettingsFragment.getPath(getApplicationContext(), data.getData());
assert filename != null;
excelToSQLite.importFromFile(filename, new ExcelToSQLite.ImportListener() {
@Override
public void onStart() {
Toasty.success(getApplicationContext(),getString(R.string.data_import_start),Toast.LENGTH_LONG).show();
}
@Override
public void onCompleted(String dbName) {
Log.v(Helper.TAG,"onCompleted");
Toasty.success(getApplicationContext(),getString(R.string.data_import_success_simple),Toast.LENGTH_LONG).show();
Intent changeAccount = new Intent(activity, MainActivity.class);
changeAccount.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
activity.finish();
activity.startActivity(changeAccount);
}
@Override
public void onError(Exception e) {
Log.v(Helper.TAG,"onError");
e.printStackTrace();
Toasty.error(getApplicationContext(),getString(R.string.data_import_error_simple),Toast.LENGTH_LONG).show();
}
});
}
}
@ -2362,7 +2455,7 @@ public abstract class BaseMainActivity extends BaseActivity
if (typePosition.get(position) == RetrieveFeedsAsyncTask.Type.TAG) {
if (tabLayout.getTabAt(position) != null && tabLayout.getTabAt(position).getText() != null) {
SQLiteDatabase db = Sqlite.getInstance(BaseMainActivity.this, Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
SQLiteDatabase db = Sqlite.getInstance(BaseMainActivity.this, DB_NAME, null, Sqlite.DB_VERSION).open();
List<TagTimeline> tagTimelines;
tagTimelines = new SearchDAO(BaseMainActivity.this, db).getTabInfo(tabLayout.getTabAt(position).getText().toString());
@ -2493,7 +2586,7 @@ public abstract class BaseMainActivity extends BaseActivity
}
String tabName = tabLayout.getTabAt(position).getText().toString().trim();
SQLiteDatabase db = Sqlite.getInstance(BaseMainActivity.this, Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
SQLiteDatabase db = Sqlite.getInstance(BaseMainActivity.this, DB_NAME, null, Sqlite.DB_VERSION).open();
List<TagTimeline> tagTimelines = new SearchDAO(BaseMainActivity.this, db).getTabInfo(tabName);
String tag;
@ -3001,7 +3094,7 @@ public abstract class BaseMainActivity extends BaseActivity
private void displayFollowInstances(){
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, android.content.Context.MODE_PRIVATE);
SQLiteDatabase db = Sqlite.getInstance(BaseMainActivity.this, Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
SQLiteDatabase db = Sqlite.getInstance(BaseMainActivity.this, DB_NAME, null, Sqlite.DB_VERSION).open();
federatedTimelines = findViewById(R.id.federated_timeline);
federatedTimelinesShow();
@ -3043,7 +3136,7 @@ public abstract class BaseMainActivity extends BaseActivity
public void onClick(View v) {
if( social == UpdateAccountInfoAsyncTask.SOCIAL.MASTODON)
new ManageListsAsyncTask(BaseMainActivity.this, ManageListsAsyncTask.action.GET_LIST, null, null, null, null, BaseMainActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
SQLiteDatabase db = Sqlite.getInstance(BaseMainActivity.this, Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
SQLiteDatabase db = Sqlite.getInstance(BaseMainActivity.this, DB_NAME, null, Sqlite.DB_VERSION).open();
new InstancesDAO(BaseMainActivity.this, db).cleanDoublon();
List<RemoteInstance> remoteInstances = new InstancesDAO(BaseMainActivity.this, db).getAllInstances();
popup = new PopupMenu(BaseMainActivity.this, federatedTimelines);
@ -3243,7 +3336,7 @@ public abstract class BaseMainActivity extends BaseActivity
dialogBuilder.setPositiveButton(R.string.validate, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
SQLiteDatabase db = Sqlite.getInstance(getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
SQLiteDatabase db = Sqlite.getInstance(getApplicationContext(), DB_NAME, null, Sqlite.DB_VERSION).open();
String instanceName = instance_list.getText().toString().trim();
new Thread(new Runnable(){
@Override

View File

@ -189,7 +189,7 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
private int currentCursorPosition, searchLength;
private TextView toot_space_left;
private String initialContent;
private final int MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE = 754;
public static final int MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE = 754;
private Account accountReply;
private View popup_trans;
private AlertDialog dialogTrans;

View File

@ -3596,7 +3596,8 @@ public class API {
while (i < jsonArray.length() ) {
JSONObject resobj = jsonArray.getJSONObject(i);
Emojis emojis1 = parseEmojis(resobj);
emojis.add(emojis1);
if( emojis1.isVisible_in_picker())
emojis.add(emojis1);
i++;
}
} catch (JSONException e) {
@ -3617,6 +3618,11 @@ public class API {
emojis.setShortcode(resobj.get("shortcode").toString());
emojis.setStatic_url(resobj.get("static_url").toString());
emojis.setUrl(resobj.get("url").toString());
try {
emojis.setVisible_in_picker((resobj.getBoolean("visible_in_picker")));
}catch (Exception e){
emojis.setVisible_in_picker(true);
}
}catch (Exception ignored){}
return emojis;
}

View File

@ -27,27 +27,10 @@ public class Emojis implements Parcelable {
private String shortcode;
private String static_url;
private String url;
private boolean visible_in_picker;
public Emojis(){}
protected Emojis(Parcel in) {
shortcode = in.readString();
static_url = in.readString();
url = in.readString();
}
public static final Creator<Emojis> CREATOR = new Creator<Emojis>() {
@Override
public Emojis createFromParcel(Parcel in) {
return new Emojis(in);
}
@Override
public Emojis[] newArray(int size) {
return new Emojis[size];
}
};
public String getShortcode() {
return shortcode;
}
@ -72,6 +55,14 @@ public class Emojis implements Parcelable {
this.url = url;
}
public boolean isVisible_in_picker() {
return visible_in_picker;
}
public void setVisible_in_picker(boolean visible_in_picker) {
this.visible_in_picker = visible_in_picker;
}
@Override
public int describeContents() {
return 0;
@ -79,8 +70,28 @@ public class Emojis implements Parcelable {
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(shortcode);
dest.writeString(static_url);
dest.writeString(url);
dest.writeString(this.shortcode);
dest.writeString(this.static_url);
dest.writeString(this.url);
dest.writeByte(this.visible_in_picker ? (byte) 1 : (byte) 0);
}
protected Emojis(Parcel in) {
this.shortcode = in.readString();
this.static_url = in.readString();
this.url = in.readString();
this.visible_in_picker = in.readByte() != 0;
}
public static final Creator<Emojis> CREATOR = new Creator<Emojis>() {
@Override
public Emojis createFromParcel(Parcel source) {
return new Emojis(source);
}
@Override
public Emojis[] newArray(int size) {
return new Emojis[size];
}
};
}

View File

@ -25,6 +25,14 @@
android:id="@+id/action_proxy"
android:title="@string/proxy_set"
app:showAsAction="never" />
<item
android:id="@+id/action_export_data"
android:title="@string/export_data"
app:showAsAction="never" />
<item
android:id="@+id/action_import_data"
android:title="@string/import_data"
app:showAsAction="never" />
<item
android:id="@+id/action_logout"
android:title="@string/action_logout"

View File

@ -545,6 +545,9 @@
<string name="data_export_toots">Export statuses for %1$s</string>
<string name="data_export_success">%1$s toots out of %2$s have been exported.</string>
<string name="data_export_error">Something went wrong when exporting data for %1$s</string>
<string name="data_export_error_simple">Something went wrong when exporting data!</string>
<string name="data_import_success_simple">Data have been imported!</string>
<string name="data_import_error_simple">Something went wrong when importing data!</string>
<!-- Proxy -->
<string name="proxy_set">Proxy</string>
<string name="proxy_type">Type</string>
@ -852,6 +855,11 @@
<string name="peertube_video_from_subscription"><![CDATA[<b>%1$s</b> published a new video: <b>%2$s</b>]]></string>
<string name="peertube_video_blacklist"><![CDATA[Your video <b>%1$s</b> has been blacklisted]]></string>
<string name="peertube_video_unblacklist"><![CDATA[Your video <b>%1$s</b> has been unblacklisted]]></string>
<string name="export_data">Export data</string>
<string name="import_data">Import Data</string>
<string name="toot_select_import">Select the file to import</string>
<string name="toot_select_file_error">An error occurred when selecting the backup file!</string>
<string name="data_import_start">Please, don\'t kill the app while processing. That can\'t be quite long.</string>
<!-- end languages -->