mirror of
https://github.com/M66B/FairEmail.git
synced 2025-03-15 16:39:37 +00:00
Concept export messages (untested)
This commit is contained in:
parent
d74cce47af
commit
4c4ded32d3
3 changed files with 126 additions and 0 deletions
|
@ -68,8 +68,10 @@ import androidx.recyclerview.widget.RecyclerView;
|
||||||
import com.google.android.material.snackbar.Snackbar;
|
import com.google.android.material.snackbar.Snackbar;
|
||||||
|
|
||||||
import java.text.NumberFormat;
|
import java.text.NumberFormat;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -555,6 +557,9 @@ public class AdapterFolder extends RecyclerView.Adapter<AdapterFolder.ViewHolder
|
||||||
popupMenu.getMenu().add(Menu.NONE, R.string.title_execute_rules, order++, R.string.title_execute_rules);
|
popupMenu.getMenu().add(Menu.NONE, R.string.title_execute_rules, order++, R.string.title_execute_rules);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (folder.accountProtocol == EntityAccount.TYPE_POP)
|
||||||
|
popupMenu.getMenu().add(Menu.NONE, R.string.title_export_messages, order++, R.string.title_export_messages);
|
||||||
|
|
||||||
int childs = 0;
|
int childs = 0;
|
||||||
if (folder.child_refs != null)
|
if (folder.child_refs != null)
|
||||||
for (TupleFolderEx child : folder.child_refs)
|
for (TupleFolderEx child : folder.child_refs)
|
||||||
|
@ -632,6 +637,9 @@ public class AdapterFolder extends RecyclerView.Adapter<AdapterFolder.ViewHolder
|
||||||
} else if (itemId == R.string.title_execute_rules) {
|
} else if (itemId == R.string.title_execute_rules) {
|
||||||
onActionExecuteRules();
|
onActionExecuteRules();
|
||||||
return true;
|
return true;
|
||||||
|
} else if (itemId == R.string.title_export_messages) {
|
||||||
|
onActionExportMessages();
|
||||||
|
return true;
|
||||||
} else if (itemId == R.string.title_edit_properties) {
|
} else if (itemId == R.string.title_edit_properties) {
|
||||||
onActionEditProperties();
|
onActionEditProperties();
|
||||||
return true;
|
return true;
|
||||||
|
@ -933,6 +941,26 @@ public class AdapterFolder extends RecyclerView.Adapter<AdapterFolder.ViewHolder
|
||||||
ask.show(parentFragment.getParentFragmentManager(), "folder:execute");
|
ask.show(parentFragment.getParentFragmentManager(), "folder:execute");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void onActionExportMessages() {
|
||||||
|
Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
|
||||||
|
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||||
|
intent.setType("*/*");
|
||||||
|
intent.putExtra(Intent.EXTRA_TITLE, "fairemail_" +
|
||||||
|
new SimpleDateFormat("yyyyMMdd").format(new Date().getTime()) + ".mbox");
|
||||||
|
Helper.openAdvanced(intent);
|
||||||
|
|
||||||
|
if (intent.resolveActivity(context.getPackageManager()) == null) { // // system/GET_CONTENT whitelisted
|
||||||
|
ToastEx.makeText(context, R.string.title_no_saf, Toast.LENGTH_LONG).show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
parentFragment.getArguments().putLong("selected_folder", folder.id);
|
||||||
|
|
||||||
|
parentFragment.startActivityForResult(
|
||||||
|
Helper.getChooser(context, intent),
|
||||||
|
FragmentFolders.REQUEST_EXPORT_MESSAGES);
|
||||||
|
}
|
||||||
|
|
||||||
private void onActionEditProperties() {
|
private void onActionEditProperties() {
|
||||||
LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(context);
|
LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(context);
|
||||||
lbm.sendBroadcast(
|
lbm.sendBroadcast(
|
||||||
|
|
|
@ -20,12 +20,14 @@ package eu.faircode.email;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import android.app.Dialog;
|
import android.app.Dialog;
|
||||||
|
import android.content.ContentResolver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
|
@ -55,17 +57,27 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||||
|
|
||||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||||
import com.google.android.material.snackbar.Snackbar;
|
import com.google.android.material.snackbar.Snackbar;
|
||||||
|
import com.sun.mail.mbox.MboxProvider;
|
||||||
|
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
import java.text.NumberFormat;
|
import java.text.NumberFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import javax.mail.Folder;
|
||||||
|
import javax.mail.Message;
|
||||||
import javax.mail.MessagingException;
|
import javax.mail.MessagingException;
|
||||||
|
import javax.mail.Session;
|
||||||
|
import javax.mail.Store;
|
||||||
|
|
||||||
import static android.app.Activity.RESULT_OK;
|
import static android.app.Activity.RESULT_OK;
|
||||||
|
|
||||||
|
@ -100,6 +112,7 @@ public class FragmentFolders extends FragmentBase {
|
||||||
static final int REQUEST_EMPTY_FOLDER = 2;
|
static final int REQUEST_EMPTY_FOLDER = 2;
|
||||||
static final int REQUEST_DELETE_FOLDER = 3;
|
static final int REQUEST_DELETE_FOLDER = 3;
|
||||||
static final int REQUEST_EXECUTE_RULES = 4;
|
static final int REQUEST_EXECUTE_RULES = 4;
|
||||||
|
static final int REQUEST_EXPORT_MESSAGES = 5;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
@ -603,6 +616,10 @@ public class FragmentFolders extends FragmentBase {
|
||||||
if (resultCode == RESULT_OK && data != null)
|
if (resultCode == RESULT_OK && data != null)
|
||||||
onExecuteRules(data.getBundleExtra("args"));
|
onExecuteRules(data.getBundleExtra("args"));
|
||||||
break;
|
break;
|
||||||
|
case REQUEST_EXPORT_MESSAGES:
|
||||||
|
if (resultCode == RESULT_OK && data != null)
|
||||||
|
onExportMessages(data.getData());
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} catch (Throwable ex) {
|
} catch (Throwable ex) {
|
||||||
Log.e(ex);
|
Log.e(ex);
|
||||||
|
@ -833,6 +850,86 @@ public class FragmentFolders extends FragmentBase {
|
||||||
}.execute(this, args, "folder:rules");
|
}.execute(this, args, "folder:rules");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void onExportMessages(Uri uri) {
|
||||||
|
long id = getArguments().getLong("selected_folder", -1L);
|
||||||
|
|
||||||
|
Bundle args = new Bundle();
|
||||||
|
args.putLong("id", id);
|
||||||
|
args.putParcelable("uri", uri);
|
||||||
|
|
||||||
|
new SimpleTask<Void>() {
|
||||||
|
@Override
|
||||||
|
protected void onPreExecute(Bundle args) {
|
||||||
|
ToastEx.makeText(getContext(), R.string.title_executing, Toast.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPostExecute(Bundle args) {
|
||||||
|
ToastEx.makeText(getContext(), R.string.title_completed, Toast.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Void onExecute(Context context, Bundle args) throws Throwable {
|
||||||
|
long fid = args.getLong("id");
|
||||||
|
Uri uri = args.getParcelable("uri");
|
||||||
|
|
||||||
|
if (!"content".equals(uri.getScheme())) {
|
||||||
|
Log.w("Export uri=" + uri);
|
||||||
|
throw new IllegalArgumentException(context.getString(R.string.title_no_stream));
|
||||||
|
}
|
||||||
|
|
||||||
|
DB db = DB.getInstance(context);
|
||||||
|
List<Long> ids = db.message().getMessageIdsByFolder(fid);
|
||||||
|
if (ids == null)
|
||||||
|
ids = new ArrayList<>();
|
||||||
|
|
||||||
|
File tmp = new File(context.getCacheDir(), "export_" + fid + ".mbox");
|
||||||
|
tmp.createNewFile();
|
||||||
|
|
||||||
|
System.setProperty("mail.mbox.locktype", "none");
|
||||||
|
|
||||||
|
Properties iprops = new Properties();
|
||||||
|
Session isession = Session.getDefaultInstance(iprops);
|
||||||
|
isession.addProvider(new MboxProvider());
|
||||||
|
|
||||||
|
Store istore = isession.getStore("mbox");
|
||||||
|
istore.connect();
|
||||||
|
|
||||||
|
try {
|
||||||
|
Folder ifolder = istore.getDefaultFolder().getFolder(tmp.getAbsolutePath());
|
||||||
|
ifolder.open(Folder.READ_WRITE);
|
||||||
|
|
||||||
|
for (long id : ids) {
|
||||||
|
EntityMessage message = db.message().getMessage(id);
|
||||||
|
if (message == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Message imessage = MessageHelper.from(context, message, null, isession, false);
|
||||||
|
ifolder.appendMessages(new Message[]{imessage});
|
||||||
|
}
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
istore.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
ContentResolver resolver = context.getContentResolver();
|
||||||
|
try (OutputStream out = resolver.openOutputStream(uri)) {
|
||||||
|
Helper.copy(new FileInputStream(tmp), out);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!BuildConfig.DEBUG)
|
||||||
|
tmp.delete();
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onException(Bundle args, Throwable ex) {
|
||||||
|
Log.unexpectedError(getParentFragmentManager(), ex);
|
||||||
|
}
|
||||||
|
}.execute(this, args, "folder:export");
|
||||||
|
}
|
||||||
|
|
||||||
public static class FragmentDialogApply extends FragmentDialogBase {
|
public static class FragmentDialogApply extends FragmentDialogBase {
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -788,6 +788,7 @@
|
||||||
<string name="title_edit_properties">Edit properties</string>
|
<string name="title_edit_properties">Edit properties</string>
|
||||||
<string name="title_edit_rules">Edit rules</string>
|
<string name="title_edit_rules">Edit rules</string>
|
||||||
<string name="title_execute_rules">Execute rules</string>
|
<string name="title_execute_rules">Execute rules</string>
|
||||||
|
<string name="title_export_messages">Export messages</string>
|
||||||
<string name="title_create_channel">Create notification channel</string>
|
<string name="title_create_channel">Create notification channel</string>
|
||||||
<string name="title_edit_channel">Edit notification channel</string>
|
<string name="title_edit_channel">Edit notification channel</string>
|
||||||
<string name="title_delete_channel">Delete notification channel</string>
|
<string name="title_delete_channel">Delete notification channel</string>
|
||||||
|
|
Loading…
Add table
Reference in a new issue