Skip to content

Commit 7f348f8

Browse files
committed
Merge branch 'master' of github.com:cloudinary/cloudinary_java
2 parents c52a294 + 0eb24b4 commit 7f348f8

File tree

39 files changed

+988
-78
lines changed

39 files changed

+988
-78
lines changed

CHANGES.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,6 @@
66
1.1.1 - 2014-12-18 - Support secure domain sharding. Don't sign version component. Support url suffix and use root path. Support tags in upload large.
77
1.1.2 - 2015-01-15 - fix support for string eager parameters
88
1.1.3 - 2015-02-24 - Added timeout parameter to admin api and Fixed test and configuration
9-
1.2.0 - 2015-04-13 - Support httpcomponents 4.4. Support for video tag and transformations. support ftp url upload. support eager_async in explicit. Fix UTF-8 issues in API. Improved parameter support for upload_large.
9+
1.2.0 - 2015-04-13 - Support httpcomponents 4.4. Support for video tag and transformations. support ftp url upload. support eager_async in explicit. Fix UTF-8 issues in API. Improved parameter support for upload_large.
10+
1.2.1 - 2015-06-18 - Fix HTML escaping (fixes upload tags). Allow android unsigned upload without api_key. Fix http44 response closing.
11+
1.2.2 - 2015-10-11 - support apache http 4.3 strategy. support easy overlay/underlay construction. support upload mappings api. support the restore api. normalize user agent. add invalidate flag to rename and explicit. support aspect ratio transformation param. Fix encoding issues when JVM default encoding is not UTF-8. support filename in upload options. close response objects in http44.

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ Cloudinary provides URL and HTTP based APIs that can be easily integrated with a
1414

1515
For Java, Cloudinary provides a library for simplifying the integration even further.
1616

17-
**Note:** Starting from version 1.1.0, you should depend on cloudinary-http42 for Java and cloudinary-android for Android. The artifact cloudinary is deprecated. From version 1.2.0 cloudinary-http44 is available.
17+
**Note:** Starting from version 1.1.0, you should depend on cloudinary-http42 for Java and cloudinary-android for Android. The artifact cloudinary is deprecated. From version 1.2.1 cloudinary-http44 is available. From version 1.2.2 cloudinary-http43 is available.
1818

1919
**Note:** This readme intended mainly for Web applications. For **Android** specific instructions, see: https://github.com/cloudinary/cloudinary_java/tree/master/cloudinary-android
2020

@@ -28,10 +28,10 @@ The cloudinary_java library is available in [Maven Central](https://repo1.maven.
2828
<dependency>
2929
<groupId>com.cloudinary</groupId>
3030
<artifactId>cloudinary-http44</artifactId>
31-
<version>1.2.0</version>
31+
<version>1.2.2</version>
3232
</dependency>
3333

34-
Alternatively, download cloudinary_java from [here](https://repo1.maven.org/maven2/com/cloudinary/cloudinary-core/1.2.0/cloudinary-core-1.2.0.jar) and [here](https://repo1.maven.org/maven2/com/cloudinary/cloudinary-http44/1.2.0/cloudinary-http44-1.2.0.jar)
34+
Alternatively, download cloudinary_java from [here](https://repo1.maven.org/maven2/com/cloudinary/cloudinary-core/1.2.2/cloudinary-core-1.2.2.jar) and [here](https://repo1.maven.org/maven2/com/cloudinary/cloudinary-http44/1.2.2/cloudinary-http44-1.2.2.jar)
3535
and see [pom.xml](https://github.com/cloudinary/cloudinary_java/blob/master/cloudinary-http44/pom.xml) for library dependencies.
3636

3737
## Try it right away
@@ -125,7 +125,7 @@ Assuming you have your Cloudinary configuration parameters defined (`cloud_name`
125125

126126
The following example uploads a local JPG to the cloud:
127127

128-
cloudinary.uploader().upload("my_picture.jpg", Cloudinary.emptyMap());
128+
cloudinary.uploader().upload("my_picture.jpg", ObjectUtils.emptyMap());
129129

130130
The uploaded image is assigned a randomly generated public ID. The image is immediately available for download through a CDN:
131131

cloudinary-android-test/pom.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@
55
<parent>
66
<groupId>com.cloudinary</groupId>
77
<artifactId>cloudinary-parent</artifactId>
8-
<version>1.2.1-SNAPSHOT</version>
8+
<version>1.2.3-SNAPSHOT</version>
99
</parent>
1010

1111
<groupId>com.cloudinary</groupId>
1212
<artifactId>cloudinary-android-test</artifactId>
13-
<version>1.2.1-SNAPSHOT</version>
13+
<version>1.2.3-SNAPSHOT</version>
1414
<packaging>apk</packaging>
1515
<name>Cloudinary Android Test Project</name>
1616

@@ -19,7 +19,7 @@
1919
<groupId>com.cloudinary</groupId>
2020
<artifactId>cloudinary-android</artifactId>
2121
<type>jar</type>
22-
<version>1.2.1-SNAPSHOT</version>
22+
<version>1.2.3-SNAPSHOT</version>
2323
</dependency>
2424
<dependency>
2525
<groupId>com.google.android</groupId>

cloudinary-android-test/src/main/java/com/cloudinary/test/UploaderTest.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,16 @@
66
import java.io.FileOutputStream;
77
import java.io.IOException;
88
import java.io.InputStream;
9+
import java.net.URLDecoder;
10+
import java.net.URLEncoder;
911
import java.util.Arrays;
1012
import java.util.Collections;
1113
import java.util.HashMap;
1214
import java.util.Map;
1315

1416
import org.cloudinary.json.JSONArray;
1517
import org.cloudinary.json.JSONObject;
18+
import org.junit.Test;
1619

1720
import android.test.InstrumentationTestCase;
1821
import android.util.Log;
@@ -323,6 +326,21 @@ public void testAutoTaggingRequest() {
323326
}
324327
}
325328

329+
@Test
330+
public void testFilenameOption() throws Exception {
331+
JSONObject result = new JSONObject(cloudinary.uploader().upload(getAssetStream(TEST_IMAGE), ObjectUtils.asMap("filename", "emanelif")));
332+
assertEquals("emanelif", result.getString("original_filename"));
333+
}
334+
335+
@Test
336+
public void testComplexFilenameOption() throws Exception {
337+
String complexFilename = "Universal Image Loader @#&=+-_.,!()~'%20.png";
338+
JSONObject result = new JSONObject(cloudinary.uploader().upload(getAssetStream(TEST_IMAGE), ObjectUtils.asMap("filename", complexFilename)));
339+
complexFilename = URLEncoder.encode(URLDecoder.decode(complexFilename, "ASCII"), "UTF-8").replace("+", " ").replace(".png", "");
340+
341+
assertEquals(complexFilename, result.getString("original_filename"));
342+
}
343+
326344
@SuppressWarnings("unchecked")
327345
public void testUploadLarge() throws Exception {
328346
// support uploading large files

cloudinary-android/README.md

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,15 @@ Cloudinary provides URL and HTTP based APIs that can be easily integrated with a
1414
For Android, Cloudinary provides a library for simplifying the integration even further. The library requires Android 2.3 or higher.
1515

1616
## Manual Setup ######################################################################
17-
Download cloudinary-core-1.1.0.jar from [here](http://search.maven.org/remotecontent?filepath=com/cloudinary/cloudinary/1.1.0/cloudinary-core-1.1.0.jar) and cloudinary-android-1.1.0.jar from [here](http://search.maven.org/remotecontent?filepath=com/cloudinary/cloudinary/1.1.0/cloudinary-android-1.1.0.jar)
18-
and put them in your libs folder.
17+
Download cloudinary-core-1.2.2.jar from [here](http://search.maven.org/remotecontent?filepath=com/cloudinary/cloudinary-core/1.2.2/cloudinary-core-1.2.2.jar) and cloudinary-android-1.2.2.jar from [here](http://search.maven.org/remotecontent?filepath=com/cloudinary/cloudinary-android/1.2.2/cloudinary-android-1.2.2.jar) and put them in your libs folder.
1918

2019
## Maven Integration ######################################################################
2120
The cloudinary_java library is available in [Maven Central](http://repo1.maven.org/maven/). To use it, add the following dependency to your pom.xml:
2221

2322
<dependency>
2423
<groupId>com.cloudinary</groupId>
2524
<artifactId>cloudinary-android</artifactId>
26-
<version>1.1.0</version>
25+
<version>1.2.2</version>
2726
</dependency>
2827

2928

@@ -129,7 +128,7 @@ Assuming you have your Cloudinary configuration parameters defined (`cloud_name`
129128

130129
The following example uploads a local JPG available as an InputStream to the cloud:
131130

132-
cloudinary.uploader().upload(inputStream, Cloudinary.emptyMap())
131+
cloudinary.uploader().upload(inputStream, ObjectUtils.emptyMap())
133132

134133
The uploaded image is assigned a randomly generated public ID. The image is immediately available for download through a CDN:
135134

@@ -139,7 +138,7 @@ The uploaded image is assigned a randomly generated public ID. The image is imme
139138

140139
You can also specify your own public ID:
141140

142-
cloudinary.uploader().upload("http://www.example.com/image.jpg", Cloudinary.asMap("public_id", "sample_remote"))
141+
cloudinary.uploader().upload("http://www.example.com/image.jpg", ObjectUtils.asMap("public_id", "sample_remote"))
143142

144143
cloudinary.url().generate("sample_remote.jpg")
145144

@@ -173,7 +172,7 @@ Your server can use any Cloudinary libraries (Ruby on Rails, PHP, Python & Djang
173172

174173
The following code uploads an image to Cloudinary with the parameters generated safely on the server side (e.g., from a JSON as in the example above):
175174

176-
cloudinary.uploader().upload(inputStream, Cloudinary.asMap("public_id", publicId, "signature", signature, "timestamp", timestamp, "api_key", api_key))
175+
cloudinary.uploader().upload(inputStream, ObjectUtils.asMap("public_id", publicId, "signature", signature, "timestamp", timestamp, "api_key", api_key))
177176

178177
You might want to reference uploaded Cloudinary images and raw files using an identifier string of the following format:
179178

cloudinary-android/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
<parent>
1111
<groupId>com.cloudinary</groupId>
1212
<artifactId>cloudinary-parent</artifactId>
13-
<version>1.2.1-SNAPSHOT</version>
13+
<version>1.2.3-SNAPSHOT</version>
1414
</parent>
1515

1616
<artifactId>cloudinary-android</artifactId>

cloudinary-android/src/main/java/com/cloudinary/android/MultipartUtility.java

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,13 @@
2323
public class MultipartUtility {
2424
private final String boundary;
2525
private static final String LINE_FEED = "\r\n";
26+
private static final String APPLICATION_OCTET_STREAM = "application/octet-stream";
2627
private HttpURLConnection httpConn;
2728
private String charset;
2829
private OutputStream outputStream;
2930
private PrintWriter writer;
3031

31-
public final static String USER_AGENT = "cld-android-" + Cloudinary.VERSION;
32+
public final static String USER_AGENT = "CloudinaryAndroid/" + Cloudinary.VERSION;
3233

3334

3435
/**
@@ -84,16 +85,21 @@ public void addFormField(String name, String value) {
8485
* a File to be uploaded
8586
* @throws IOException
8687
*/
87-
public void addFilePart(String fieldName, File uploadFile) throws IOException {
88-
String fileName = uploadFile.getName();
88+
public void addFilePart(String fieldName, File uploadFile, String fileName) throws IOException {
89+
if (fileName == null) fileName = uploadFile.getName();
8990
FileInputStream inputStream = new FileInputStream(uploadFile);
9091
addFilePart(fieldName, inputStream, fileName);
9192
}
93+
94+
public void addFilePart(String fieldName, File uploadFile) throws IOException {
95+
addFilePart(fieldName, uploadFile, "file");
96+
}
9297

9398
public void addFilePart(String fieldName, InputStream inputStream, String fileName) throws IOException {
99+
if (fileName == null) fileName = "file";
94100
writer.append("--" + boundary).append(LINE_FEED);
95101
writer.append("Content-Disposition: form-data; name=\"" + fieldName + "\"; filename=\"" + fileName + "\"").append(LINE_FEED);
96-
writer.append("Content-Type: " + URLConnection.guessContentTypeFromName(fileName)).append(LINE_FEED);
102+
writer.append("Content-Type: ").append(APPLICATION_OCTET_STREAM).append(LINE_FEED);
97103
writer.append("Content-Transfer-Encoding: binary").append(LINE_FEED);
98104
writer.append(LINE_FEED);
99105
writer.flush();

cloudinary-android/src/main/java/com/cloudinary/android/UploaderStrategy.java

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -27,23 +27,24 @@ public Map callApi(String action, Map<String, Object> params, Map options, Objec
2727
}
2828
boolean returnError = ObjectUtils.asBoolean(options.get("return_error"), false);
2929

30-
String apiKey = ObjectUtils.asString(options.get("api_key"), this.cloudinary().config.apiKey);
31-
if (apiKey == null)
32-
throw new IllegalArgumentException("Must supply api_key");
33-
3430
if (Boolean.TRUE.equals(options.get("unsigned"))) {
3531
// Nothing to do
36-
} else if (options.containsKey("signature") && options.containsKey("timestamp")) {
37-
params.put("timestamp", options.get("timestamp"));
38-
params.put("signature", options.get("signature"));
39-
params.put("api_key", apiKey);
4032
} else {
41-
String apiSecret = ObjectUtils.asString(options.get("api_secret"), this.cloudinary().config.apiSecret);
42-
if (apiSecret == null)
43-
throw new IllegalArgumentException("Must supply api_secret");
44-
params.put("timestamp", Long.valueOf(System.currentTimeMillis() / 1000L).toString());
45-
params.put("signature", this.cloudinary().apiSignRequest(params, apiSecret));
46-
params.put("api_key", apiKey);
33+
String apiKey = ObjectUtils.asString(options.get("api_key"), this.cloudinary().config.apiKey);
34+
if (apiKey == null)
35+
throw new IllegalArgumentException("Must supply api_key");
36+
if (options.containsKey("signature") && options.containsKey("timestamp")) {
37+
params.put("timestamp", options.get("timestamp"));
38+
params.put("signature", options.get("signature"));
39+
params.put("api_key", apiKey);
40+
} else {
41+
String apiSecret = ObjectUtils.asString(options.get("api_secret"), this.cloudinary().config.apiSecret);
42+
if (apiSecret == null)
43+
throw new IllegalArgumentException("Must supply api_secret");
44+
params.put("timestamp", Long.valueOf(System.currentTimeMillis() / 1000L).toString());
45+
params.put("signature", this.cloudinary().apiSignRequest(params, apiSecret));
46+
params.put("api_key", apiKey);
47+
}
4748
}
4849
String apiUrl = this.cloudinary().cloudinaryApiUrl(action, options);
4950
MultipartUtility multipart = new MultipartUtility(apiUrl, "UTF-8", this.cloudinary().randomPublicId(), (String) options.get("content_range"));
@@ -64,14 +65,15 @@ public Map callApi(String action, Map<String, Object> params, Map options, Objec
6465
if (file instanceof String && !((String) file).matches("ftp:.*|https?:.*|s3:.*|data:[^;]*;base64,([a-zA-Z0-9/+\n=]+)")) {
6566
file = new File((String) file);
6667
}
68+
String filename = (String) options.get("filename");
6769
if (file instanceof File) {
68-
multipart.addFilePart("file", (File) file);
70+
multipart.addFilePart("file", (File) file, filename);
6971
} else if (file instanceof String) {
7072
multipart.addFormField("file", (String) file);
7173
} else if (file instanceof InputStream) {
72-
multipart.addFilePart("file", (InputStream) file);
74+
multipart.addFilePart("file", (InputStream) file, filename);
7375
} else if (file instanceof byte[]) {
74-
multipart.addFilePart("file", new ByteArrayInputStream((byte[]) file));
76+
multipart.addFilePart("file", new ByteArrayInputStream((byte[]) file), filename);
7577
}
7678
HttpURLConnection connection = multipart.execute();
7779
int code;

cloudinary-core/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<parent>
55
<groupId>com.cloudinary</groupId>
66
<artifactId>cloudinary-parent</artifactId>
7-
<version>1.2.1-SNAPSHOT</version>
7+
<version>1.2.3-SNAPSHOT</version>
88
</parent>
99

1010
<artifactId>cloudinary-core</artifactId>

cloudinary-core/src/main/java/com/cloudinary/Api.java

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,5 +226,52 @@ public ApiResponse subFolders(String ofFolderPath, Map options) throws Exception
226226
options = ObjectUtils.emptyMap();
227227
return callApi(HttpMethod.GET, Arrays.asList("folders", ofFolderPath), ObjectUtils.emptyMap(), options);
228228
}
229+
230+
public ApiResponse restore(Iterable<String> publicIds, Map options) throws Exception {
231+
if (options == null)
232+
options = ObjectUtils.emptyMap();
233+
String resourceType = ObjectUtils.asString(options.get("resource_type"), "image");
234+
String type = ObjectUtils.asString(options.get("type"), "upload");
235+
Map params = new HashMap<String, Object>();
236+
params.put("public_ids", publicIds);
237+
return callApi(HttpMethod.POST, Arrays.asList("resources", resourceType, type, "restore"), params, options);
238+
}
239+
240+
public ApiResponse uploadMappings(Map options) throws Exception {
241+
if (options == null)
242+
options = ObjectUtils.emptyMap();
243+
return callApi(HttpMethod.GET, Arrays.asList("upload_mappings"),
244+
ObjectUtils.only(options, "next_cursor", "max_results"), options);
245+
}
246+
247+
public ApiResponse uploadMapping(String name, Map options) throws Exception {
248+
if (options == null)
249+
options = ObjectUtils.emptyMap();
250+
return callApi(HttpMethod.GET, Arrays.asList("upload_mappings"), ObjectUtils.asMap("folder", name), options);
251+
}
252+
253+
public ApiResponse deleteUploadMapping(String name, Map options) throws Exception {
254+
if (options == null)
255+
options = ObjectUtils.emptyMap();
256+
return callApi(HttpMethod.DELETE, Arrays.asList("upload_mappings"), ObjectUtils.asMap("folder", name), options);
257+
}
258+
259+
public ApiResponse updateUploadMapping(String name, Map options) throws Exception {
260+
if (options == null)
261+
options = ObjectUtils.emptyMap();
262+
Map params = new HashMap<String, Object>();
263+
params.put("folder", name);
264+
params.putAll(ObjectUtils.only(options, "template"));
265+
return callApi(HttpMethod.PUT, Arrays.asList("upload_mappings"), params, options);
266+
}
267+
268+
public ApiResponse createUploadMapping(String name, Map options) throws Exception {
269+
if (options == null)
270+
options = ObjectUtils.emptyMap();
271+
Map params = new HashMap<String, Object>();
272+
params.put("folder", name);
273+
params.putAll(ObjectUtils.only(options, "template"));
274+
return callApi(HttpMethod.POST, Arrays.asList("upload_mappings"), params, options);
275+
}
229276

230277
}

0 commit comments

Comments
 (0)