Added inline unzip

pull/207/head
M66B 3 years ago
parent 3810533334
commit cafe0189c0

@ -6,10 +6,11 @@
### Next version ### Next version
* Enabled [sqlite analyze](https://sqlite.org/lang_analyze.html) * Added option to show contents of zipped attachments
* Added [linear back-off scheme](https://github.com/M66B/FairEmail/blob/master/FAQ.md#user-content-faq123)
* Added option to sort reply templates by frequency of use * Added option to sort reply templates by frequency of use
* Added basic [DMARC](https://en.wikipedia.org/wiki/DMARC) report viewer * Added basic [DMARC](https://en.wikipedia.org/wiki/DMARC) report viewer
* Added [linear back-off scheme](https://github.com/M66B/FairEmail/blob/master/FAQ.md#user-content-faq123)
* Enabled [sqlite analyze](https://sqlite.org/lang_analyze.html)
* Small improvements and minor bug fixes * Small improvements and minor bug fixes
* Updated translations * Updated translations

@ -6,10 +6,11 @@
### Next version ### Next version
* Enabled [sqlite analyze](https://sqlite.org/lang_analyze.html) * Added option to show contents of zipped attachments
* Added [linear back-off scheme](https://github.com/M66B/FairEmail/blob/master/FAQ.md#user-content-faq123)
* Added option to sort reply templates by frequency of use * Added option to sort reply templates by frequency of use
* Added basic [DMARC](https://en.wikipedia.org/wiki/DMARC) report viewer * Added basic [DMARC](https://en.wikipedia.org/wiki/DMARC) report viewer
* Added [linear back-off scheme](https://github.com/M66B/FairEmail/blob/master/FAQ.md#user-content-faq123)
* Enabled [sqlite analyze](https://sqlite.org/lang_analyze.html)
* Small improvements and minor bug fixes * Small improvements and minor bug fixes
* Updated translations * Updated translations

@ -166,6 +166,7 @@ public class FragmentOptionsDisplay extends FragmentBase implements SharedPrefer
private SwitchCompat swImagesPlaceholders; private SwitchCompat swImagesPlaceholders;
private SwitchCompat swImagesInline; private SwitchCompat swImagesInline;
private SwitchCompat swButtonExtra; private SwitchCompat swButtonExtra;
private SwitchCompat swUnzip;
private SwitchCompat swAttachmentsAlt; private SwitchCompat swAttachmentsAlt;
private SwitchCompat swThumbnails; private SwitchCompat swThumbnails;
@ -197,7 +198,8 @@ public class FragmentOptionsDisplay extends FragmentBase implements SharedPrefer
"message_zoom", "overview_mode", "override_width", "message_zoom", "overview_mode", "override_width",
"display_font", "contrast", "monospaced_pre", "display_font", "contrast", "monospaced_pre",
"background_color", "text_color", "text_size", "text_font", "text_align", "text_separators", "background_color", "text_color", "text_size", "text_font", "text_align", "text_separators",
"collapse_quotes", "image_placeholders", "inline_images", "button_extra", "attachments_alt", "thumbnails", "collapse_quotes", "image_placeholders", "inline_images", "button_extra",
"unzip", "attachments_alt", "thumbnails",
"bundled_fonts", "parse_classes", "bundled_fonts", "parse_classes",
"authentication", "authentication_indicator" "authentication", "authentication_indicator"
}; };
@ -314,6 +316,7 @@ public class FragmentOptionsDisplay extends FragmentBase implements SharedPrefer
swImagesPlaceholders = view.findViewById(R.id.swImagesPlaceholders); swImagesPlaceholders = view.findViewById(R.id.swImagesPlaceholders);
swImagesInline = view.findViewById(R.id.swImagesInline); swImagesInline = view.findViewById(R.id.swImagesInline);
swButtonExtra = view.findViewById(R.id.swButtonExtra); swButtonExtra = view.findViewById(R.id.swButtonExtra);
swUnzip = view.findViewById(R.id.swUnzip);
swAttachmentsAlt = view.findViewById(R.id.swAttachmentsAlt); swAttachmentsAlt = view.findViewById(R.id.swAttachmentsAlt);
swThumbnails = view.findViewById(R.id.swThumbnails); swThumbnails = view.findViewById(R.id.swThumbnails);
swBundledFonts = view.findViewById(R.id.swBundledFonts); swBundledFonts = view.findViewById(R.id.swBundledFonts);
@ -1165,6 +1168,13 @@ public class FragmentOptionsDisplay extends FragmentBase implements SharedPrefer
} }
}); });
swUnzip.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
prefs.edit().putBoolean("unzip", checked).apply();
}
});
swAttachmentsAlt.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { swAttachmentsAlt.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override @Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
@ -1430,6 +1440,7 @@ public class FragmentOptionsDisplay extends FragmentBase implements SharedPrefer
swImagesPlaceholders.setChecked(prefs.getBoolean("image_placeholders", true)); swImagesPlaceholders.setChecked(prefs.getBoolean("image_placeholders", true));
swImagesInline.setChecked(prefs.getBoolean("inline_images", false)); swImagesInline.setChecked(prefs.getBoolean("inline_images", false));
swButtonExtra.setChecked(prefs.getBoolean("button_extra", false)); swButtonExtra.setChecked(prefs.getBoolean("button_extra", false));
swUnzip.setChecked(prefs.getBoolean("unzip", false));
swAttachmentsAlt.setChecked(prefs.getBoolean("attachments_alt", false)); swAttachmentsAlt.setChecked(prefs.getBoolean("attachments_alt", false));
swThumbnails.setChecked(prefs.getBoolean("thumbnails", true)); swThumbnails.setChecked(prefs.getBoolean("thumbnails", true));

@ -94,6 +94,8 @@ import java.util.TimeZone;
import java.util.UUID; import java.util.UUID;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import javax.activation.DataHandler; import javax.activation.DataHandler;
import javax.activation.FileDataSource; import javax.activation.FileDataSource;
@ -3372,6 +3374,77 @@ public class MessageHelper {
} catch (Throwable ex) { } catch (Throwable ex) {
Log.e(ex); Log.e(ex);
} }
else if ("application/zip".equals(local.type)) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
boolean unzip = prefs.getBoolean("unzip", false);
if (unzip) {
// https://developer.android.com/reference/java/util/zip/ZipInputStream
try (ZipInputStream zis = new ZipInputStream(
new BufferedInputStream(new FileInputStream(local.getFile(context))))) {
int subsequence = 1;
ZipEntry ze;
while ((ze = zis.getNextEntry()) != null)
try {
String name = ze.getName();
long total = ze.getSize();
// isDirectory:
// A directory entry is defined to be one whose name ends with a '/'.
if (ze.isDirectory() ||
(name != null && name.endsWith("\\"))) {
Log.i("Zipped folder=" + name);
continue;
}
Log.i("Zipped attachment seq=" + local.sequence + ":" + subsequence +
" " + name + ":" + total);
EntityAttachment entry = new EntityAttachment();
entry.message = local.message;
entry.sequence = local.sequence;
entry.subsequence = subsequence++;
entry.name = name;
entry.type = Helper.guessMimeType(entry.name);
entry.size = total;
entry.id = db.attachment().insertAttachment(entry);
File efile = entry.getFile(context);
Log.i("Unzipping to " + efile);
int last = 0;
long size = 0;
try (OutputStream os = new FileOutputStream(efile)) {
byte[] buffer = new byte[Helper.BUFFER_SIZE];
for (int len = zis.read(buffer); len != -1; len = zis.read(buffer)) {
size += len;
os.write(buffer, 0, len);
int progress = (int) (size * 100 / total);
if (progress / 20 > last / 20) {
last = progress;
db.attachment().setProgress(entry.id, progress);
}
}
} catch (Throwable ex) {
Log.e(ex);
db.attachment().setError(entry.id, Log.formatThrowable(ex));
db.attachment().setAvailable(entry.id, true); // unrecoverable
}
db.attachment().setDownloaded(entry.id, efile.length());
} finally {
zis.closeEntry();
}
} catch (Throwable ex) {
Log.e(ex);
db.attachment().setError(local.id, Log.formatThrowable(ex));
}
}
}
} }
} }

@ -1750,6 +1750,17 @@
app:layout_constraintTop_toBottomOf="@id/tvImagesInlineHint" app:layout_constraintTop_toBottomOf="@id/tvImagesInlineHint"
app:switchPadding="12dp" /> app:switchPadding="12dp" />
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/swUnzip"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:text="@string/title_advanced_unzip"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/swButtonExtra"
app:switchPadding="12dp" />
<androidx.appcompat.widget.SwitchCompat <androidx.appcompat.widget.SwitchCompat
android:id="@+id/swAttachmentsAlt" android:id="@+id/swAttachmentsAlt"
android:layout_width="0dp" android:layout_width="0dp"
@ -1758,7 +1769,7 @@
android:text="@string/title_advanced_attachments_alt" android:text="@string/title_advanced_attachments_alt"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/swButtonExtra" app:layout_constraintTop_toBottomOf="@id/swUnzip"
app:switchPadding="12dp" /> app:switchPadding="12dp" />
<androidx.appcompat.widget.SwitchCompat <androidx.appcompat.widget.SwitchCompat

@ -508,6 +508,7 @@
<string name="title_advanced_preview_italic">Show message preview in italics</string> <string name="title_advanced_preview_italic">Show message preview in italics</string>
<string name="title_advanced_preview_lines">Number of preview lines</string> <string name="title_advanced_preview_lines">Number of preview lines</string>
<string name="title_advanced_addresses">Expand address details by default</string> <string name="title_advanced_addresses">Expand address details by default</string>
<string name="title_advanced_unzip">Show contents of zipped attachments</string>
<string name="title_advanced_attachments_alt">Show attachments after the message text</string> <string name="title_advanced_attachments_alt">Show attachments after the message text</string>
<string name="title_advanced_thumbnails">Show image thumbnails after the message text</string> <string name="title_advanced_thumbnails">Show image thumbnails after the message text</string>
<string name="title_advanced_message_text_zoom2">Default message text zoom: %1$s %%</string> <string name="title_advanced_message_text_zoom2">Default message text zoom: %1$s %%</string>

@ -6,10 +6,11 @@
### Next version ### Next version
* Enabled [sqlite analyze](https://sqlite.org/lang_analyze.html) * Added option to show contents of zipped attachments
* Added [linear back-off scheme](https://github.com/M66B/FairEmail/blob/master/FAQ.md#user-content-faq123)
* Added option to sort reply templates by frequency of use * Added option to sort reply templates by frequency of use
* Added basic [DMARC](https://en.wikipedia.org/wiki/DMARC) report viewer * Added basic [DMARC](https://en.wikipedia.org/wiki/DMARC) report viewer
* Added [linear back-off scheme](https://github.com/M66B/FairEmail/blob/master/FAQ.md#user-content-faq123)
* Enabled [sqlite analyze](https://sqlite.org/lang_analyze.html)
* Small improvements and minor bug fixes * Small improvements and minor bug fixes
* Updated translations * Updated translations

Loading…
Cancel
Save