Skip to content

Commit

Permalink
Merge branch 'master' into idempotent-requests
Browse files Browse the repository at this point in the history
  • Loading branch information
mtrezza authored Jun 11, 2024
2 parents 039d197 + a08c5d1 commit 76673eb
Show file tree
Hide file tree
Showing 16 changed files with 561 additions and 18 deletions.
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
# [4.3.0](https://github.com/parse-community/Parse-SDK-Android/compare/4.2.1...4.3.0) (2024-02-18)


### Features

* Add support for uploading a `ParseFile` from a URI ([#1207](https://github.com/parse-community/Parse-SDK-Android/issues/1207)) ([83aec68](https://github.com/parse-community/Parse-SDK-Android/commit/83aec68cb7f95e0116b3878b8cda099fd3a2e200))

## [4.2.1](https://github.com/parse-community/Parse-SDK-Android/compare/4.2.0...4.2.1) (2023-08-25)


### Bug Fixes

* Missing Proguard rules for R8 in full mode ([#1196](https://github.com/parse-community/Parse-SDK-Android/issues/1196)) ([7db0965](https://github.com/parse-community/Parse-SDK-Android/commit/7db09650447db2e0f82247240ae51687189cd03f))

# [4.2.0](https://github.com/parse-community/Parse-SDK-Android/compare/4.1.0...4.2.0) (2023-02-22)


Expand Down
33 changes: 26 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,18 +45,39 @@ The Parse Android SDK has the following Android API and [Gradle Plugin][gradle-p

## Add Dependency

Add this in your root `build.gradle` file (**not** your module `build.gradle` file):
Add the line `maven { url 'https://www.jitpack.io' }` to your `settings.gradle` file, inside the `repositories` property, for example:

```gradle
allprojects {
dependencyResolutionManagement {
repositories {
...
maven { url "https://jitpack.io" }
maven { url 'https://www.jitpack.io' }
}
}
```

Then, add the library to your project `build.gradle`
Older versions of Android studio require different steps. See the following list of Android Studio versions for alternative instructions. You can find the version of your Android Studio installation by clicking on *Help > About* in the top menu.

<details>
<summary>Arctic Fox | 2020.3.1 or older</summary>
<br>

>
> Add this in your root `build.gradle` file, **not** your module `build.gradle` file:
>
> ```gradle
> allprojects {
> repositories {
> ...
> maven { url "https://jitpack.io" }
> }
> }
> ```
>
> Then, add the library to your project `build.gradle` file.
</details>
Then, add the library to your (module:app) `build.gradle` file, replacing `latest.version.here` with the version of the Parse Android SDK you would like to use. We commend always updating your app to use the [latest release](https://github.com/parse-community/Parse-SDK-Android/releases) version.
```gradle
ext {
Expand All @@ -81,8 +102,6 @@ dependencies {
}
```
replacing `latest.version.here` with the latest released version (see JitPack badge above).

## Setup

Initialize Parse in a custom class that extends `Application`:
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
version = 4.2.0
version = 4.3.0
android.enableJetifier = true
android.useAndroidX = true
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "parse-sdk-android",
"version": "4.2.0",
"version": "4.3.0",
"repository": {
"type": "git",
"url": "git+https://github.com/parse-community/Parse-SDK-Android.git"
Expand Down
10 changes: 8 additions & 2 deletions parse/release-proguard.pro
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
-keep @com.parse.ParseClassName class com.parse.*
-keepnames class com.parse.** { *; }
-keepclassmembers public class * extends com.parse.** {
public <init>(...);
}

# Required for Parse
-keepattributes *Annotation*
-keepattributes Signature
# https://github.com/square/okio#proguard
-dontwarn okio.**

# Retracing stacktraces
-keepattributes LineNumberTable,SourceFile
-renamesourcefileattribute SourceFile
59 changes: 59 additions & 0 deletions parse/src/main/java/com/parse/ParseCountingUriHttpBody.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* Copyright (c) 2015-present, Parse, LLC.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package com.parse;

import android.net.Uri;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

class ParseCountingUriHttpBody extends ParseUriHttpBody {

private static final int DEFAULT_CHUNK_SIZE = 4096;
private static final int EOF = -1;

private final ProgressCallback progressCallback;

public ParseCountingUriHttpBody(Uri uri, ProgressCallback progressCallback) {
this(uri, null, progressCallback);
}

public ParseCountingUriHttpBody(
Uri uri, String contentType, ProgressCallback progressCallback) {
super(uri, contentType);
this.progressCallback = progressCallback;
}

@Override
public void writeTo(OutputStream output) throws IOException {
if (output == null) {
throw new IllegalArgumentException("Output stream may not be null");
}

final InputStream fileInput =
Parse.getApplicationContext().getContentResolver().openInputStream(uri);
try {
byte[] buffer = new byte[DEFAULT_CHUNK_SIZE];
int n;
long totalLength = getContentLength();
long position = 0;
while (EOF != (n = fileInput.read(buffer))) {
output.write(buffer, 0, n);
position += n;

if (progressCallback != null) {
int progress = (int) (100 * position / totalLength);
progressCallback.done(progress);
}
}
} finally {
ParseIOUtils.closeQuietly(fileInput);
}
}
}
27 changes: 27 additions & 0 deletions parse/src/main/java/com/parse/ParseFile.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
*/
package com.parse;

import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
import com.parse.boltsinternal.Continuation;
Expand Down Expand Up @@ -64,6 +65,7 @@ public ParseFile[] newArray(int size) {
*/
/* package for tests */ byte[] data;
/* package for tests */ File file;
/* package for tests */ Uri uri;
private State state;

/**
Expand Down Expand Up @@ -102,6 +104,21 @@ public ParseFile(String name, byte[] data, String contentType) {
this.data = data;
}

/**
* Creates a new file from a content uri, file name, and content type. Content type will be used
* instead of auto-detection by file extension.
*
* @param name The file's name, ideally with extension. The file name must begin with an
* alphanumeric character, and consist of alphanumeric characters, periods, spaces,
* underscores, or dashes.
* @param uri The file uri.
* @param contentType The file's content type.
*/
public ParseFile(String name, Uri uri, String contentType) {
this(new State.Builder().name(name).mimeType(contentType).build());
this.uri = uri;
}

/**
* Creates a new file from a byte array.
*
Expand Down Expand Up @@ -274,6 +291,16 @@ private Task<Void> saveAsync(
progressCallbackOnMainThread(
uploadProgressCallback),
cancellationToken);
} else if (uri != null) {
saveTask =
getFileController()
.saveAsync(
state,
uri,
sessionToken,
progressCallbackOnMainThread(
uploadProgressCallback),
cancellationToken);
} else {
saveTask =
getFileController()
Expand Down
44 changes: 44 additions & 0 deletions parse/src/main/java/com/parse/ParseFileController.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
*/
package com.parse;

import android.net.Uri;
import com.parse.boltsinternal.Task;
import com.parse.http.ParseHttpRequest;
import java.io.File;
Expand Down Expand Up @@ -163,6 +164,49 @@ public Task<ParseFile.State> saveAsync(
ParseExecutors.io());
}

public Task<ParseFile.State> saveAsync(
final ParseFile.State state,
final Uri uri,
String sessionToken,
ProgressCallback uploadProgressCallback,
Task<Void> cancellationToken) {
if (state.url() != null) { // !isDirty
return Task.forResult(state);
}
if (cancellationToken != null && cancellationToken.isCancelled()) {
return Task.cancelled();
}

final ParseRESTCommand command =
new ParseRESTFileCommand.Builder()
.fileName(state.name())
.uri(uri)
.contentType(state.mimeType())
.sessionToken(sessionToken)
.build();

return command.executeAsync(restClient, uploadProgressCallback, null, cancellationToken)
.onSuccess(
task -> {
JSONObject result = task.getResult();
ParseFile.State newState =
new ParseFile.State.Builder(state)
.name(result.getString("name"))
.url(result.getString("url"))
.build();

// Write data to cache
try {
ParseFileUtils.writeUriToFile(getCacheFile(newState), uri);
} catch (IOException e) {
// do nothing
}

return newState;
},
ParseExecutors.io());
}

public Task<File> fetchAsync(
final ParseFile.State state,
@SuppressWarnings("UnusedParameters") String sessionToken,
Expand Down
25 changes: 25 additions & 0 deletions parse/src/main/java/com/parse/ParseFileUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*/
package com.parse;

import android.net.Uri;
import androidx.annotation.NonNull;
import java.io.File;
import java.io.FileInputStream;
Expand Down Expand Up @@ -115,6 +116,30 @@ public static void writeByteArrayToFile(File file, byte[] data) throws IOExcepti
}
}

/**
* Writes a content uri to a file creating the file if it does not exist.
*
* <p>NOTE: As from v1.3, the parent directories of the file will be created if they do not
* exist.
*
* @param file the file to write to
* @param uri the content uri with data to write to the file
* @throws IOException in case of an I/O error
* @since Commons IO 1.1
*/
public static void writeUriToFile(File file, Uri uri) throws IOException {
OutputStream out = null;
InputStream in = null;
try {
in = Parse.getApplicationContext().getContentResolver().openInputStream(uri);
out = openOutputStream(file);
ParseIOUtils.copyLarge(in, out);
} finally {
ParseIOUtils.closeQuietly(out);
ParseIOUtils.closeQuietly(in);
}
}

// -----------------------------------------------------------------------

/**
Expand Down
Loading

0 comments on commit 76673eb

Please sign in to comment.