Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,9 @@ fastlane/report.xml
.idea/

app/CMakeUserPresets.json

infra/scw-transfer/terraform.tfvars

venv/

infra/scw-transfer/.terraform/
11 changes: 1 addition & 10 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import org.apache.tools.ant.filters.ReplaceTokens
plugins {
id 'com.android.application'
id 'com.google.gms.google-services'
id 'com.google.firebase.crashlytics'
id 'app.opendocument.conanandroidgradleplugin'
}

Expand Down Expand Up @@ -51,6 +50,7 @@ android {
)
}
}

Comment thread
TomTasche marked this conversation as resolved.
Outdated
}

flavorDimensions "default"
Expand Down Expand Up @@ -93,8 +93,6 @@ android {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.txt'

firebaseCrashlytics.nativeSymbolUploadEnabled true
ndk.debugSymbolLevel = "full"
}
}
Expand Down Expand Up @@ -135,13 +133,6 @@ android {
}

dependencies {
implementation platform('com.google.firebase:firebase-bom:34.1.0')
implementation 'com.google.firebase:firebase-storage'
implementation 'com.google.firebase:firebase-auth'
implementation 'com.google.firebase:firebase-crashlytics-ndk'
implementation 'com.google.firebase:firebase-analytics'
implementation 'com.google.firebase:firebase-config'

implementation 'com.google.android.gms:play-services-ads:24.3.0'
implementation 'com.google.android.play:review:2.0.2'
implementation 'com.google.android.ump:user-messaging-platform:3.1.0'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,12 @@
import android.os.Parcel;
import android.os.Parcelable;

import com.google.firebase.analytics.FirebaseAnalytics;

import java.io.File;
import java.util.LinkedList;
import java.util.List;

import at.tomtasche.reader.nonfree.AnalyticsManager;
import at.tomtasche.reader.nonfree.AnalyticsConstants;
import at.tomtasche.reader.nonfree.CrashManager;

public abstract class FileLoader {
Expand Down Expand Up @@ -86,7 +85,7 @@ void callOnSuccess(Result result) {
mainHandler.post(new Runnable() {
@Override
public void run() {
analyticsManager.report("loader_success_" + type, FirebaseAnalytics.Param.CONTENT_TYPE, result.options.fileType, FirebaseAnalytics.Param.CONTENT, result.options.fileExtension);
analyticsManager.report("loader_success_" + type, AnalyticsConstants.PARAM_CONTENT_TYPE, result.options.fileType, AnalyticsConstants.PARAM_CONTENT, result.options.fileExtension);

FileLoaderListener strongReferenceListener = listener;
if (strongReferenceListener != null) {
Expand All @@ -103,7 +102,7 @@ void callOnError(Result result, Throwable t) {
mainHandler.post(new Runnable() {
@Override
public void run() {
analyticsManager.report("loader_error_" + type, FirebaseAnalytics.Param.CONTENT_TYPE, result.options.fileType, FirebaseAnalytics.Param.CONTENT, result.options.fileExtension);
analyticsManager.report("loader_error_" + type, AnalyticsConstants.PARAM_CONTENT_TYPE, result.options.fileType, AnalyticsConstants.PARAM_CONTENT, result.options.fileExtension);

FileLoaderListener strongReferenceListener = listener;
if (strongReferenceListener != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,11 @@

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
import com.google.firebase.analytics.FirebaseAnalytics;

import java.io.File;
import java.io.OutputStream;

import at.tomtasche.reader.R;
import at.tomtasche.reader.nonfree.AnalyticsConstants;
import at.tomtasche.reader.nonfree.AnalyticsManager;
import at.tomtasche.reader.nonfree.ConfigManager;
import at.tomtasche.reader.nonfree.CrashManager;
Expand Down Expand Up @@ -134,12 +133,12 @@ public void onSuccess(FileLoader.Result result) {
if (result.loaderType == FileLoader.LoaderType.METADATA) {
if (!coreLoader.isSupported(options)) {
crashManager.log("we do not expect this file to be an ODF: " + options.originalUri.toString());
analyticsManager.report("load_odf_error_expected", FirebaseAnalytics.Param.CONTENT_TYPE, options.fileType);
analyticsManager.report("load_odf_error_expected", AnalyticsConstants.PARAM_CONTENT_TYPE, options.fileType);
}

loadWithType(FileLoader.LoaderType.CORE, options);
} else {
analyticsManager.report("load_success", FirebaseAnalytics.Param.CONTENT_TYPE, options.fileType, FirebaseAnalytics.Param.CONTENT, result.loaderType.toString());
analyticsManager.report("load_success", AnalyticsConstants.PARAM_CONTENT_TYPE, options.fileType, AnalyticsConstants.PARAM_CONTENT, result.loaderType.toString());

if (currentListener != null) {
currentListener.onLoadSuccess(result);
Expand Down Expand Up @@ -167,7 +166,7 @@ public void onError(FileLoader.Result result, Throwable error) {
}

if (result.loaderType == FileLoader.LoaderType.CORE) {
analyticsManager.report("load_odf_error", FirebaseAnalytics.Param.CONTENT_TYPE, options.fileType);
analyticsManager.report("load_odf_error", AnalyticsConstants.PARAM_CONTENT_TYPE, options.fileType);

if (rawLoader.isSupported(options)) {
loadWithType(FileLoader.LoaderType.RAW, options);
Expand All @@ -192,7 +191,7 @@ public void onError(FileLoader.Result result, Throwable error) {

// MetadataLoader failed, so there's no point in trying to parse or upload the file

analyticsManager.report("load_error", FirebaseAnalytics.Param.CONTENT_TYPE, options.fileType, FirebaseAnalytics.Param.CONTENT, result.loaderType.toString());
analyticsManager.report("load_error", AnalyticsConstants.PARAM_CONTENT_TYPE, options.fileType, AnalyticsConstants.PARAM_CONTENT, result.loaderType.toString());

if (currentListener != null) {
currentListener.onError(result, error);
Expand Down Expand Up @@ -238,7 +237,7 @@ private void saveSync(FileLoader.Result lastResult, Uri outFile, String htmlDiff
}
});
} catch (Throwable e) {
analyticsManager.report("save_error", FirebaseAnalytics.Param.CONTENT_TYPE, lastResult.options.fileType);
analyticsManager.report("save_error", AnalyticsConstants.PARAM_CONTENT_TYPE, lastResult.options.fileType);
crashManager.log(e, lastResult.options.originalUri);

if (currentListener != null) {
Expand Down Expand Up @@ -287,4 +286,4 @@ public interface LoaderListener {
void onUnsupported(FileLoader.Result result);
void onSaveError();
}
}
}
145 changes: 67 additions & 78 deletions app/src/main/java/at/tomtasche/reader/background/OnlineLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,12 @@
import android.content.Context;
import android.net.Uri;
import android.os.Build;
import android.os.Handler;

import androidx.annotation.RequiresApi;

import com.google.android.gms.tasks.Task;
import com.google.android.gms.tasks.Tasks;
import com.google.firebase.auth.AuthResult;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.storage.FirebaseStorage;
import com.google.firebase.storage.StorageMetadata;
import com.google.firebase.storage.StorageReference;
import com.google.firebase.storage.UploadTask;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
Expand All @@ -26,14 +17,11 @@
import java.net.URL;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.util.UUID;
import java.util.concurrent.ExecutionException;

import at.tomtasche.reader.nonfree.AnalyticsManager;
import at.tomtasche.reader.nonfree.CrashManager;

public class OnlineLoader extends FileLoader {

private static final String TRANSFER_BASE_URL = "https://transfershxuil1jyq-transfer-sh.functions.fnc.nl-ams.scw.cloud";

// https://help.joomlatools.com/article/169-google-viewer
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Complete_list_of_MIME_types
private static final String[] MIME_WHITELIST = {"text/", "image/", "video/", "audio/",
Expand Down Expand Up @@ -76,26 +64,11 @@ public class OnlineLoader extends FileLoader {

private final CoreLoader coreLoader;

private StorageReference storage;
private FirebaseAuth auth;

public OnlineLoader(Context context, CoreLoader coreLoader) {
super(context, LoaderType.ONLINE);
this.coreLoader = coreLoader;
}

@Override
public void initialize(FileLoaderListener listener, Handler mainHandler, Handler backgroundHandler, AnalyticsManager analyticsManager, CrashManager crashManager) {
super.initialize(listener, mainHandler, backgroundHandler, analyticsManager, crashManager);

try {
storage = FirebaseStorage.getInstance().getReference();
auth = FirebaseAuth.getInstance();
} catch (Throwable e) {
crashManager.log(e);
}
}

@Override
public boolean isSupported(Options options) {
String fileType = options.fileType;
Expand Down Expand Up @@ -126,10 +99,10 @@ public void loadSync(Options options) {
try {
Uri viewerUri;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O &&
("text/rtf".equals(options.fileType) || "application/vnd.wordperfect".equals(options.fileType) || coreLoader.isSupported(options) || "application/vnd.ms-excel".equals(options.fileType) || "application/msword".equals(options.fileType) || "application/vnd.ms-powerpoint".equals(options.fileType) || options.fileType.startsWith("application/vnd.openxmlformats-officedocument.") || options.fileType.equals("application/pdf"))) {
Comment thread
TomTasche marked this conversation as resolved.
("text/rtf".equals(options.fileType))) {
viewerUri = doOnlineConvert(options);
} else {
viewerUri = doFirebaseConvert(options);
viewerUri = doTransferUpload(options);
}

result.partTitles.add(null);
Expand Down Expand Up @@ -175,66 +148,82 @@ private Uri doOnlineConvert(Options options) throws IOException {
return Uri.parse(basePath + redirectUrl);
}

private Uri doFirebaseConvert(Options options) throws ExecutionException, InterruptedException, UnsupportedEncodingException {
if (auth == null || storage == null) {
throw new RuntimeException("firebase not initialized");
private Uri doTransferUpload(Options options) throws IOException {
File binaryFile = AndroidFileCache.getCacheFile(context, options.cacheUri);
String filename = options.filename;
if (filename == null || filename.isEmpty()) {
filename = "document." + options.fileExtension;
}

Task<AuthResult> authenticationTask = null;
String currentUserId = null;
if (auth.getCurrentUser() != null) {
currentUserId = auth.getCurrentUser().getUid();
} else {
authenticationTask = auth.signInAnonymously();
String encodedFilename = URLEncoder.encode(filename, StreamUtil.ENCODING);
String basePath = ensureTrailingSlash(TRANSFER_BASE_URL);
HttpURLConnection connection = (HttpURLConnection) new URL(basePath + encodedFilename).openConnection();
connection.setRequestMethod("PUT");
connection.setDoOutput(true);
connection.setInstanceFollowRedirects(false);
if (!"N/A".equals(options.fileType)) {
connection.setRequestProperty("Content-Type", options.fileType);
}

if (authenticationTask != null) {
Tasks.await(authenticationTask);

currentUserId = authenticationTask.getResult().getUser().getUid();
try (OutputStream outputStream = connection.getOutputStream()) {
Files.copy(binaryFile.toPath(), outputStream);
outputStream.flush();
}

StorageMetadata.Builder metadataBuilder = new StorageMetadata.Builder();
if (!"N/A".equals(options.fileType)) {
metadataBuilder.setContentType(options.fileType);
}
int responseCode = connection.getResponseCode();
if (responseCode >= 200 && responseCode < 300) {
String downloadUrl = readBody(connection);
if (downloadUrl == null || downloadUrl.isEmpty()) {
downloadUrl = connection.getHeaderField("Location");
}

String filePath = currentUserId + "/" + UUID.randomUUID() + "." + options.fileExtension;
StorageReference reference = storage.child("uploads/" + filePath);
UploadTask uploadTask = reference.putFile(options.cacheUri, metadataBuilder.build());
Tasks.await(uploadTask);
if (downloadUrl == null || downloadUrl.isEmpty()) {
throw new IOException("server couldn't handle request");
}

if (uploadTask.isSuccessful()) {
Uri viewerUri;
if (coreLoader.isSupported(options)) {
// ODF does not seem to be supported by google docs viewer
String downloadUrl = "https://us-central1-admob-app-id-9025061963.cloudfunctions.net/download?filePath=" + filePath;
return buildViewerUri(options, downloadUrl.trim());
} else {
String error = readError(connection);
throw new IOException("server couldn't handle request: " + responseCode + " " + error);
}
}

viewerUri = Uri.parse(MICROSOFT_VIEWER_URL + downloadUrl);
} else {
Task<Uri> urlTask = reference.getDownloadUrl();
Tasks.await(urlTask);
String downloadUrl = urlTask.getResult().toString();
private Uri buildViewerUri(Options options, String downloadUrl) throws UnsupportedEncodingException {
if (coreLoader.isSupported(options)) {
// ODF does not seem to be supported by google docs viewer
return Uri.parse(MICROSOFT_VIEWER_URL + downloadUrl);
} else {
return Uri.parse(GOOGLE_VIEWER_URL + URLEncoder.encode(downloadUrl, StreamUtil.ENCODING));
}
}

viewerUri = Uri.parse(GOOGLE_VIEWER_URL + URLEncoder.encode(downloadUrl, StreamUtil.ENCODING));
}
private String ensureTrailingSlash(String base) {
if (base.endsWith("/")) {
return base;
}

return viewerUri;
} else {
throw new RuntimeException("server couldn't handle request");
return base + "/";
}

private String readBody(HttpURLConnection connection) throws IOException {
InputStream inputStream = connection.getInputStream();
if (inputStream == null) {
return null;
}

return StreamUtil.readFully(inputStream);
}

@Override
public void close() {
super.close();

backgroundHandler.post(new Runnable() {
@Override
public void run() {
auth = null;
storage = null;
private String readError(HttpURLConnection connection) {
try {
InputStream errorStream = connection.getErrorStream();
if (errorStream == null) {
return null;
}
});

return StreamUtil.readFully(errorStream);
} catch (Throwable t) {
return null;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package at.tomtasche.reader.background;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
Expand Down Expand Up @@ -27,6 +28,13 @@ public static void copy(InputStream in, File dst) throws IOException {
out.close();
}

public static String readFully(InputStream in) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
copy(in, out);

return out.toString(ENCODING);
}

// taken from: https://stackoverflow.com/a/9293885/198996
public static void copy(InputStream in, OutputStream out) throws IOException {
try {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package at.tomtasche.reader.nonfree;

public final class AnalyticsConstants {

private AnalyticsConstants() {
}

public static final String PARAM_CONTENT_TYPE = "content_type";
public static final String PARAM_CONTENT = "content";
public static final String PARAM_ITEM_NAME = "item_name";

public static final String EVENT_SELECT_CONTENT = "select_content";
public static final String EVENT_VIEW_ITEM = "view_item";
public static final String EVENT_ADD_TO_CART = "add_to_cart";
public static final String EVENT_SEARCH = "search";
}
Loading
Loading