diff --git a/cloudinary-core/src/main/scala/com/cloudinary/Uploader.scala b/cloudinary-core/src/main/scala/com/cloudinary/Uploader.scala index e7839b3..6425cc8 100644 --- a/cloudinary-core/src/main/scala/com/cloudinary/Uploader.scala +++ b/cloudinary-core/src/main/scala/com/cloudinary/Uploader.scala @@ -89,7 +89,15 @@ class Uploader(implicit val cloudinary: Cloudinary) { callApi[UploadResponse]("upload", params.toMap, file, resourceType, params.signed, requestTimeout) } + def uploadLarge(file: AnyRef, params: LargeUploadParameters = LargeUploadParameters(), resourceType: String = "raw", bufferSize: Int = 20000000) = { + uploadLargeInternal(file, params, resourceType, bufferSize) + } + def uploadLargeRaw(file: AnyRef, params: LargeUploadParameters = LargeUploadParameters(), bufferSize: Int = 20000000) = { + uploadLargeInternal(file, params, "raw", bufferSize) + } + + private def uploadLargeInternal(file: AnyRef, params: LargeUploadParameters = LargeUploadParameters(), resourceType: String, bufferSize: Int = 20000000) = { val (input, fileName) = file match { case s: String => val f = new File(s) @@ -99,7 +107,7 @@ class Uploader(implicit val cloudinary: Cloudinary) { case is: InputStream => (is, None) } try { - uploadLargeRawPart(input, params, fileName, bufferSize) + uploadLargePart(input, params, fileName, resourceType, bufferSize) } catch { case e: Exception => input.close() @@ -107,7 +115,7 @@ class Uploader(implicit val cloudinary: Cloudinary) { } } - private def uploadLargeRawPart(input: InputStream, params: LargeUploadParameters, originalFileName: Option[String], bufferSize: Int, partNumber: Int = 1): Future[LargeRawUploadResponse] = { + private def uploadLargePart(input: InputStream, params: LargeUploadParameters, originalFileName: Option[String], resourceType: String = "image", bufferSize: Int, partNumber: Int = 1): Future[LargeRawUploadResponse] = { val uploadParams = params.toMap + ("part_number" -> partNumber.toString) val (last, buffer) = readChunck(input, bufferSize) val part = new ByteArrayPart("file", buffer) @@ -115,16 +123,16 @@ class Uploader(implicit val cloudinary: Cloudinary) { (partNumber, last) match { case (_, true) => input.close() - callApi[LargeRawUploadResponse]("upload_large", uploadParams + ("final" -> "1"), part, "raw") + callApi[LargeRawUploadResponse]("upload_large", uploadParams + ("final" -> "1"), part, resourceType) case (1, _) => - val responseFuture = callApi[LargeRawUploadResponse]("upload_large", uploadParams, part, "raw") + val responseFuture = callApi[LargeRawUploadResponse]("upload_large", uploadParams, part, resourceType) responseFuture.flatMap { response => - uploadLargeRawPart(input, params.publicId(response.public_id).uploadId(response.upload_id.get), originalFileName, bufferSize, partNumber + 1) + uploadLargePart(input, params.publicId(response.public_id).uploadId(response.upload_id.get), originalFileName, resourceType, bufferSize, partNumber + 1) } case _ => - val responseFuture = callApi[LargeRawUploadResponse]("upload_large", uploadParams, part, "raw") + val responseFuture = callApi[LargeRawUploadResponse]("upload_large", uploadParams, part, resourceType) responseFuture.flatMap { - response => uploadLargeRawPart(input, params, originalFileName, bufferSize, partNumber + 1) + response => uploadLargePart(input, params, originalFileName, resourceType, bufferSize, partNumber + 1) } } } @@ -241,10 +249,10 @@ class Uploader(implicit val cloudinary: Cloudinary) { val cloudinaryUploadUrl = cloudinary.cloudinaryApiUrl("upload", resourceType) s""" - """ diff --git a/cloudinary-core/src/test/resources/rxnvjzsnhjxa4qdqik7i.mp4 b/cloudinary-core/src/test/resources/rxnvjzsnhjxa4qdqik7i.mp4 new file mode 100644 index 0000000..ed139d6 Binary files /dev/null and b/cloudinary-core/src/test/resources/rxnvjzsnhjxa4qdqik7i.mp4 differ diff --git a/cloudinary-core/src/test/scala/com/cloudinary/UploaderSpec.scala b/cloudinary-core/src/test/scala/com/cloudinary/UploaderSpec.scala index d79e62b..591ae82 100644 --- a/cloudinary-core/src/test/scala/com/cloudinary/UploaderSpec.scala +++ b/cloudinary-core/src/test/scala/com/cloudinary/UploaderSpec.scala @@ -232,7 +232,7 @@ class UploaderSpec extends MockableFlatSpec with Matchers with OptionValues with it should "prevent non whitelisted formats from being uploaded if allowed_formats is specified" in { Await.result(for { error <- uploader.upload(s"$testResourcePath/logo.png", options.allowedFormats(Set("jpg"))).recover{case e => e} - } yield {error}, 5.seconds).isInstanceOf[BadRequest] should equal(true) + } yield {error}, 5.seconds).isInstanceOf[BadRequest] should equal(true) } it should "allow non whitelisted formats if type is specified and convert to that type" in { @@ -266,7 +266,7 @@ class UploaderSpec extends MockableFlatSpec with Matchers with OptionValues with UploadParameters().callback("http://localhost/cloudinary_cors.html"), Map("class" -> "myclass")) should include("class=\"cloudinary-fileupload myclass\"") } - + it should "support requesting manual moderation" in { Await.result(for { result <- uploader.upload(s"$testResourcePath/logo.png", options.moderation("manual")) @@ -275,35 +275,35 @@ class UploaderSpec extends MockableFlatSpec with Matchers with OptionValues with result.moderation.head.kind should equal("manual") }, 10.seconds) } - + it should "support requesting raw conversion" in { val error = Await.result(for { e <- uploader.upload(s"$testResourcePath/docx.docx", options.rawConvert("illegal"), "raw").recover{case e => e} } yield e, 10.seconds) error.asInstanceOf[BadRequest].message should include("not a valid") } - + it should "support requesting categorization" in { val error = Await.result(for { e <- uploader.upload(s"$testResourcePath/logo.png", options.categorization("illegal")).recover{case e => e} } yield e, 10.seconds) error.asInstanceOf[BadRequest].message should include("is invalid") } - + it should "support requesting detection" in { val error = Await.result(for { e <- uploader.upload(s"$testResourcePath/logo.png", options.detection("illegal")).recover{case e => e} } yield e, 10.seconds) error.asInstanceOf[BadRequest].message should include("not a valid") } - + it should "support requesting auto_tagging" in { val error = Await.result(for { e <- uploader.upload(s"$testResourcePath/logo.png", options.autoTagging(0.5)).recover{case e => e} } yield e, 10.seconds) error.asInstanceOf[BadRequest].message should include("Must use") } - + it should "support uploading large raw files" in { Await.result(for { response <- uploader.uploadLargeRaw(s"$testResourcePath/docx.docx", LargeUploadParameters().tags(Set("large_upload_test_tag"))) @@ -314,8 +314,19 @@ class UploaderSpec extends MockableFlatSpec with Matchers with OptionValues with }, 10.seconds) } + it should "support uploading large video files" in { + Await.result(for { + response <- uploader.uploadLarge(s"$testResourcePath/rxnvjzsnhjxa4qdqik7i.mp4", LargeUploadParameters().tags(Set("large_upload_test_tag")), "video") + } yield { + response.bytes should equal(new java.io.File(s"$testResourcePath/rxnvjzsnhjxa4qdqik7i.mp4").length()) + response.tags should equal(List("large_upload_test_tag")) + response.done should equal(Some(true)) + response.resource_type should equal("video") + }, 10.seconds) + } + it should "support unsigned uploading using presets" taggedAs(UploadPresetTest) in { - val c = cloudinary.withConfig(Map("api_key" -> null, "api_secret" -> null)) + val c = cloudinary.withConfig(Map("api_key" -> null, "api_secret" -> null)) val (presetName, uploadResult) = Await.result(for { preset <- api.createUploadPreset(UploadPreset(unsigned = true, settings = options.folder("upload_folder"))) result <- uploader.unsignedUpload(s"$testResourcePath/logo.png", preset.name) @@ -351,4 +362,4 @@ class UploaderSpec extends MockableFlatSpec with Matchers with OptionValues with duration should be < 2000L }).test } -} \ No newline at end of file +}