Each new project we start is being developed in Scala. Therefore, we are in need of a Scala programmer who loves to write beautiful code. No more legacy projects or maintenance of old systems of which the original programmer is already six feet under. What we need is new, fresh code for awesome projects.
Are you the Scala programmer we are looking for? Take a look at the job description (in Dutch) and give the Scala puzzle a try! Send us your solution and you will be invited for a job interview.
A minimal S3 API wrapper. Allows you to list, get, add and remove items from a bucket.
val appDependencies = Seq(
"nl.rhinofly" %% "play-s3" % "3.3.3"
// use the following version for play 2.1
//"nl.rhinofly" %% "play-s3" % "3.1.1"
)
val main = PlayProject(appName, appVersion, appDependencies, mainLang = SCALA).settings(
resolvers += "Rhinofly Internal Repository" at "http:https://maven-repository.rhinofly.net:8081/artifactory/libs-release-local"
)
application.conf
should contain the following information:
aws.accessKeyId=AmazonAccessKeyId
aws.secretKey=AmazonSecretKey
If you are using another S3 implementation (like riakCS), you can customize the domain name and https usage with these values:
#default is s3.amazonaws.com
s3.host="your.domain.name"
#default is false
s3.https=true
Getting a bucket:
val bucket = S3("bucketName")
//with other credentials
implicit val credentials = ...
val bucket = S3("bucketName")
//or
val bucket = S3("bucketName")(credentials)
Adding a file:
//not that acl and headers are optional, the default value for acl is set to PUBLIC_READ.
val result = bucket + BucketFile(fileName, mimeType, byteArray, acl, headers)
//or
val result = bucket add BucketFile(fileName, mimeType, byteArray, acl, headers)
result
.map { unit =>
Logger.info("Saved the file")
}
.recover {
case S3Exception(status, code, message, originalXml) => Logger.info("Error: " + message)
}
Removing a file:
val result = bucket - fileName
//or
val result = bucket remove fileName
Retrieving a file:
val result = bucket get "fileName"
result.map {
case BucketFile(name, contentType, content, acl, headers) => //...
}
//or
val file = Await.result(result, 10 seconds)
val BucketFile(name, contentType, content, acl, headers) = file
Listing the contents of a bucket:
val result = bucket.list
result.map { items =>
items.map {
case BucketItem(name, isVirtual) => //...
}
}
//or using a prefix
val result = bucket list "prefix"
Retrieving a private url:
val url = bucket.url("fileName", expirationFromNowInSeconds)
Renaming a file:
val result = bucket rename("oldFileName", "newFileName", ACL)
Multipart file upload:
// Retrieve an upload ticket
val result:Future[BucketFileUploadTicket] =
bucket initiateMultipartUpload BucketFile(fileName, mimeType)
// Upload the parts and save the tickets
val result:Future[BucketFilePartUploadTicket] =
bucket uploadPart (uploadTicket, BucketFilePart(partNumber, content))
// Complete the upload using both the upload ticket and the part upload tickets
val result:Future[Unit] =
bucket completeMultipartUpload (uploadTicket, partUploadTickets)
Updating the ACL of a file:
val result:Future[Unit] = bucket updateACL ("fileName", ACL)
Retrieving the ACL of a file:
val result = testBucket.getAcl("private2README.txt")
for {
aclList <- result
grant <- aclList
} yield
grant match {
case Grant(FULL_CONTROL, CanonicalUser(id, displayName)) => //...
case Grant(READ, Group(uri)) => //...
}
Browser upload helpers:
val `1 minute from now` = System.currentTimeMillis + (1 * 60 * 1000)
// import condition builders
import fly.play.s3.upload.Condition._
// create a policy and set the conditions
val policy =
testBucket.uploadPolicy(expiration = new Date(`1 minute from now`))
.withConditions(
key startsWith "test/",
acl eq PUBLIC_READ,
successActionRedirect eq expectedRedirectUrl,
header(CONTENT_TYPE) startsWith "text/",
meta("tag").any)
// import Form helper
import fly.play.s3.upload.Form
val formFieldsFromPolicy = Form(policy).fields
// convert the form fields from the policy to an actial form
formFieldsFromPolicy
.map {
case FormElement(name, value, true) =>
s"""<input type="text" name="$name" value="$value" />"""
case FormElement(name, value, false) =>
s"""<input type="hidden" name="$name" value="$value" />"""
}
// make sure you add the file form field as last
val allFormFields =
formFieldsFromPolicy.mkString("\n") +
"""<input type="text" name="file" />"""
More examples can be found in the S3Spec
in the test
folder. In order to run the tests you need
an application.conf
file in the test/conf
folder containing a valid aws.accessKeyId
and aws.secretKey
.