Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update current code #5

Merged
merged 1 commit into from
Aug 9, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
57 changes: 53 additions & 4 deletions java/compress_image/Index.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,14 @@
import java.util.stream.*;
import java.util.Base64;
import com.google.gson.Gson;
import com.tinify.*;

import com.tinify.Source;
import com.tinify.Tinify;
import java.io.*;
import io.kraken.client.model.response.SuccessfulUploadResponse;
import io.kraken.client.model.request.DirectUploadRequest;
import io.kraken.client.impl.DefaultKrakenIoClient;
import io.kraken.client.KrakenIoClient;
import io.kraken.client.exception.KrakenIoRequestException;
/**
* Enum for provider names
* @param name is provider name
Expand Down Expand Up @@ -75,14 +81,36 @@ public RuntimeResponse main(RuntimeRequest req, RuntimeResponse res) throws Exce
return errorResponse;
}
String apiKey = req.getVariables().get(apiKeyVariable);
String secretKey = req.getVariables().get("KRAKENIO_API_SECRET");

// compressed image in Base64 string
String compressedImage = "compressed image is under implementation";
String compressedImage = "";

// response data to return
Map<String, Object> responseData = new HashMap<>();

// TODO: compress image using provider API and store the result in compressedImage variable
if (Provider.TINY_PNG.getName().equals(provider)) {
// Decode image from Base64 string
byte[] imageByte = convertToByte(image);

// Compress image
byte[] compressedImageByte = tinifyCompress(imageByte, apiKey);

// Encode image to Base64 string
compressedImage = convertToBase64(compressedImageByte);
} else {
// Decode input string
byte[] imageBytes = convertToByte(image);

String urlResponse = krakenioCompress(imageBytes, apiKey, secretKey);

URL url = new URL(urlResponse);
InputStream inputStream = url.openStream();
byte[] compressedImageBytes = inputStream.readAllBytes();
compressedImage = convertToBase64(compressedImageBytes);
inputStream.close();
}

// TODO: check if compressedImage is valid

Expand Down Expand Up @@ -205,8 +233,29 @@ private String convertToBase64(byte [] byteInput) {
* @return byte [] compressed image
*/

private String tinifyCompress(byte [] image, String apiKey) {
private byte [] tinifyCompress(byte [] image, String apiKey) throws Exception {
Tinify.setKey(apiKey);
Source source = Tinify.fromBuffer(image);
return source.toBuffer();
}

private String krakenioCompress(byte [] image, String apiKey, String secretKey) throws Exception {
if (apiKey == null || apiKey.trim().isEmpty()) {
throw new IllegalArgumentException("API key is empty");
}
final KrakenIoClient client = new DefaultKrakenIoClient(apiKey, secretKey);

final DirectUploadRequest request = DirectUploadRequest.builder(new ByteArrayInputStream(image)).withLossy(true).build();
final SuccessfulUploadResponse response = client.directUpload(request);
try {

if (response.getSuccess()) {
return response.getKrakedUrl();
} else {
throw new IOException("Kraken.io failed to compress image");
}
} catch (Exception e) {
System.out.println("Error: " + e.getMessage());
}
return null;
}
61 changes: 41 additions & 20 deletions java/compress_image/README.md
Original file line number Diff line number Diff line change
@@ -1,45 +1,66 @@
# compress_image
# Compress .png Images

Welcome to the documentation of this function 👋 We strongly recommend keeping this file in sync with your function's logic to make sure anyone can easily understand your function in the future. If you don't need documentation, you can remove this file.
A Ruby Cloud Function that compresses png images.

## 🤖 Documentation

Simple function similar to typical "hello world" example, but instead, we return a simple JSON that tells everyone how awesome developers are.

<!-- Update with your description, for example 'Create Stripe payment and return payment URL' -->
`image` and `provider` are recieved from the payload, where `image` is a base64 encoded string and `provider` is either [`tinypng`](https://tinypng.com) or [`krakenio`](https://kraken.io)

_Example input:_

This function expects no input
```json
{
"provider": "tinypng",
"image": "iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAf0lEQVR4nO2Wuw2AMAxEbw1gpMwDDMBcGQpooDKydGVAoXCK6J7k6qyc83MCCFGP/Yz+CkDF4KHmjgowbQF0CKFrCDUiwztqxabHCL0/xwcNhoI2UdsjC8g0mQvaSs1zwkg0uQAsAEaGm9/UPCeU7eMj6loTEpf6ZOQWMxd98gAhZnS6XEZcNQAAAABJRU5ErkJggg==",

}
```

<!-- If input is expected, add example -->
> `krakenio` is also a supported provider

_Example output:_

<!-- Update with your expected output -->

```json
{
"areDevelopersAwesome": true
"success": true,
"image": "iVBORw0KGgoAAAANSUhEUgAAACAAAAAgBAMAAACBVGfHAAAAG1BMVEUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACUUeIgAAAACHRSTlMA8712Sxr5g97cFtUAAAA9SURBVCjPY6Aa6AADfAIcDSA8KoBTgLGVgSFCAEmAqZmBwUIBSYClzTQ4wwE52Cs6OtpR4oFFUciBerEKAP58HnyLtZsYAAAAAElFTkSuQmCC"
}
```

## 📝 Environment Variables
## 📝 Variables

List of environment variables used by this cloud function:
> only selected provider's api keys are neccessary, ie. kraken's api keys are not neccessary when choosing tinypng as the provider.

- No special environment variables are required for the cloud function.
- **TINYPNG_API** - API key for tinypng service
- **KRAKENIO_KEY** - API key for kraken-io service
- **KRAKENIO_SECRET** - API Secret for kraken-io service

## 🚀 Deployment

There are two ways of deploying the Appwrite function, both having the same results, but each using a different process. We highly recommend using CLI deployment to achieve the best experience.
1. Clone this repository, and enter this function folder:

```
$ git clone https://github.com/open-runtimes/examples.git && cd examples
$ cd ruby/compress_image
```

### Using CLI
2. Enter this function folder and build the code:
```
docker run --rm --interactive --tty --volume $PWD:/usr/code openruntimes/java:v2-11.0 sh /usr/local/src/build.sh
```
As a result, a `code.tar.gz` file will be generated.
3. Start the Open Runtime:
```
docker run -p 3000:3000 -e INTERNAL_RUNTIME_KEY=secret-key -e INTERNAL_RUNTIME_ENTRYPOINT=Index.java --rm --interactive --tty --volume $PWD/code.tar.gz:/tmp/code.tar.gz:ro openruntimes/java:v2-11.0 sh /usr/local/src/start.sh
```

Make sure you have [Appwrite CLI](https://appwrite.io/docs/command-line#installation) installed, and you have successfully logged into your Appwrite server. To make sure Appwrite CLI is ready, you can use the command `appwrite client --debug` and it should respond with green text `✓ Success`.
4. Execute function:

Make sure you are in the same folder as your `appwrite.json` file and run `appwrite deploy function` to deploy your function. You will be prompted to select which functions you want to deploy.
```shell
curl http://localhost:3000/ -d '{"variables":{"TINYPNG_API":"[YOUR_API_KEY]"},"payload":"{\"provider\":\"tinypng\",\"image\":\"iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAf0lEQVR4nO2Wuw2AMAxEbw1gpMwDDMBcGQpooDKydGVAoXCK6J7k6qyc83MCCFGP/Yz+CkDF4KHmjgowbQF0CKFrCDUiwztqxabHCL0/xwcNhoI2UdsjC8g0mQvaSs1zwkg0uQAsAEaGm9/UPCeU7eMj6loTEpf6ZOQWMxd98gAhZnS6XEZcNQAAAABJRU5ErkJggg==\"}"}' -H "X-Internal-Challenge: secret-key" -H "Content-Type: application/json"
```

### Manual using tar.gz
Your function is now listening on port `3000`, and you can execute it by sending `POST` request with appropriate authorization headers. To learn more about runtime, you can visit Python runtime [README](https://github.com/open-runtimes/open-runtimes/tree/main/runtimes/java-11.0).

Manual deployment has no requirements and uses Appwrite Console to deploy the tag. First, enter the folder of your function. Then, create a tarball of the whole folder and gzip it. After creating `.tar.gz` file, visit Appwrite Console, click on the `Deploy Tag` button and switch to the `Manual` tab. There, set the `entrypoint` to `src/Index.java`, and upload the file we just generated.
## 📝 Notes
- This function is designed for use with Appwrite Cloud Functions. You can learn more about it in [Appwrite docs](https://appwrite.io/docs/functions).
- This example is compatible with Java 11.0. Other versions may work but are not guaranteed to work as they haven't been tested.
7 changes: 5 additions & 2 deletions java/compress_image/deps.gradle
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
dependencies {
implementation 'com.google.code.gson:gson:2.9.0'
compile 'com.tinify:tinify:latest.release'
implementation 'com.google.code.gson:gson:2.10.1'
implementation 'com.tinify:tinify:1.8.3'
implementation('io.kraken.client:client:1.1.2'){
exclude module: 'javax.inject'
}
}