{"id":13695685,"url":"https://github.com/kaliber-scala/play-s3","last_synced_at":"2025-05-03T13:32:53.432Z","repository":{"id":7178045,"uuid":"8479965","full_name":"kaliber-scala/play-s3","owner":"kaliber-scala","description":"S3 module for Play","archived":true,"fork":false,"pushed_at":"2019-04-11T19:40:33.000Z","size":272,"stargazers_count":119,"open_issues_count":15,"forks_count":49,"subscribers_count":32,"default_branch":"master","last_synced_at":"2024-08-03T18:19:52.494Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Scala","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kaliber-scala.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-02-28T13:49:30.000Z","updated_at":"2023-07-03T18:24:24.000Z","dependencies_parsed_at":"2022-08-19T21:50:59.097Z","dependency_job_id":null,"html_url":"https://github.com/kaliber-scala/play-s3","commit_stats":null,"previous_names":["kaliber/play-s3"],"tags_count":19,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kaliber-scala%2Fplay-s3","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kaliber-scala%2Fplay-s3/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kaliber-scala%2Fplay-s3/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kaliber-scala%2Fplay-s3/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kaliber-scala","download_url":"https://codeload.github.com/kaliber-scala/play-s3/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224364354,"owners_count":17299055,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-02T18:00:32.302Z","updated_at":"2024-11-12T23:30:45.134Z","avatar_url":"https://github.com/kaliber-scala.png","language":"Scala","funding_links":[],"categories":["Libraries"],"sub_categories":["Others"],"readme":"\n*This repository is no longer maintained*\n\nJust create a fork, if you want I can list it here.\n\n-------------\n\nAmazon Simple Storage Service (S3) module for Play 2.6\n=====================================================\n\nA minimal S3 API wrapper. Allows you to list, get, add and remove items from a bucket.\n\nHas some extra features that help with direct upload and authenticated url generation.\n\n**Note: this version uses the new aws 4 signer, this requires you to correctly set the region**\n\nImportant changes\n-----------------\n**10.0.0**\n - Upgraded to Play 2.7\n\n-----------------\n**9.0.0**\n - Upgraded to Play 2.6\n - Upgraded to Scala 2.12\n\n**8.0.0**\n - Upgraded to Play 2.5\n\n**7.0.0**\n - Organisation has been changed to 'net.kaliber'\n - Resolver (maven repository) has been moved\n - `fromConfig` and `fromConfiguration` methods have been renamed to `fromApplication`. Added `fromConfiguration`\n   methods that can be used without access to an application (useful for application loaders introduced in Play 2.4)\n\nInstallation\n------------\n\n``` scala\n  val appDependencies = Seq(\n    \"net.kaliber\" %% \"play-s3\" % \"9.0.0\"\n\n    // use the following version for play 2.5\n    \"net.kaliber\" %% \"play-s3\" % \"8.0.0\"\n    // use the following version for play 2.4\n    \"net.kaliber\" %% \"play-s3\" % \"7.0.2\"\n    // use the following version for play 2.3\n    \"nl.rhinofly\" %% \"play-s3\" % \"6.0.0\"\n    // use the following version for play 2.2\n    //\"nl.rhinofly\" %% \"play-s3\" % \"4.0.0\"\n    // use the following version for play 2.1\n    //\"nl.rhinofly\" %% \"play-s3\" % \"3.1.1\"\n  )\n\n    // use the following for play 2.5 and 2.4\n  resolvers += \"Kaliber Internal Repository\" at \"https://jars.kaliber.io/artifactory/libs-release-local\"\n\n  // use the following for play 2.3 and below\n  resolvers += \"Rhinofly Internal Repository\" at \"http://maven-repository.rhinofly.net:8081/artifactory/libs-release-local\"\n```\n\nConfiguration\n-------------\n\n`application.conf` should contain the following information:\n\n``` scala\naws.accessKeyId=AmazonAccessKeyId\naws.secretKey=AmazonSecretKey\n```\n\nIf you are hosting in a specific region that can be specified. If you are using another S3\nimplementation (like riakCS), you can customize the domain name and https usage with these values:\n\n``` scala\n#default is us-east-1\ns3.region=\"eu-west-1\"\n#default is determined by the region, see: http://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region\ns3.host=\"your.domain.name\"\n#default is true\ns3.https=false\n#default is true\n#required in case dots are present in the bucket name and https is enabled\ns3.pathStyleAccess=false\n```\n\nUsage\n-----\n\nGetting a S3 instance:\n\n``` scala\nval s3 = S3.fromApplication(playApplication)\n// or\nval s3 = S3.fromConfiguration(wsClient, playConfiguration)\n```\n\nGetting a bucket:\n\n``` scala\nval bucket = s3.getBucket(\"bucketName\")\n```\n\nAdding a file:\n\n``` scala\n//not that acl and headers are optional, the default value for acl is set to PUBLIC_READ.\n\nval result = bucket + BucketFile(fileName, mimeType, byteArray, acl, headers)\n//or\nval result = bucket add BucketFile(fileName, mimeType, byteArray, acl, headers)\n\nresult\n  .map { unit =\u003e\n    Logger.info(\"Saved the file\")\n  }\n  .recover {\n    case S3Exception(status, code, message, originalXml) =\u003e Logger.info(\"Error: \" + message)\n  }\n\n```\n\nRemoving a file:\n\n``` scala\nval result = bucket - fileName\n//or\nval result = bucket remove fileName\n\n```\n\nRetrieving a file:\n\n``` scala\nval result = bucket get \"fileName\"\n\nresult.map {\n    case BucketFile(name, contentType, content, acl, headers) =\u003e //...\n}\n//or\nval file = Await.result(result, 10 seconds)\nval BucketFile(name, contentType, content, acl, headers) = file\n```\n\nListing the contents of a bucket:\n\n``` scala\nval result = bucket.list\n\nresult.map { items =\u003e\n  items.map {\n    case BucketItem(name, isVirtual) =\u003e //...\n  }\n}\n\n//or using a prefix\nval result = bucket list \"prefix\"\n```\n\nRetrieving a private url:\n\n``` scala\nval url = bucket.url(\"fileName\", expirationFromNowInSeconds)\n```\n\nRenaming a file:\n\n``` scala\nval result = bucket rename(\"oldFileName\", \"newFileName\", ACL)\n```\n\nMultipart file upload:\n\n``` scala\n\n// Retrieve an upload ticket\nval result:Future[BucketFileUploadTicket] =\n  bucket initiateMultipartUpload BucketFile(fileName, mimeType)\n\n// Upload the parts and save the tickets\nval result:Future[BucketFilePartUploadTicket] =\n  bucket uploadPart (uploadTicket, BucketFilePart(partNumber, content))\n\n// Complete the upload using both the upload ticket and the part upload tickets\nval result:Future[Unit] =\n  bucket completeMultipartUpload (uploadTicket, partUploadTickets)\n\n```\n\nUpdating the ACL of a file:\n\n``` scala\nval result:Future[Unit] = bucket updateACL (\"fileName\", ACL)\n```\n\nRetrieving the ACL of a file:\n\n``` scala\nval result = testBucket.getAcl(\"private2README.txt\")\n\nfor {\n aclList \u003c- result\n grant \u003c- aclList\n} yield\n  grant match {\n    case Grant(FULL_CONTROL, CanonicalUser(id, displayName)) =\u003e //...\n    case Grant(READ, Group(uri)) =\u003e //...\n  }\n```\n\nBrowser upload helpers:\n\n``` scala\nval `1 minute from now` = System.currentTimeMillis + (1 * 60 * 1000)\n\n// import condition builders\nimport fly.play.s3.upload.Condition._\n\n// create a policy and set the conditions\nval policy =\n  testBucket.uploadPolicy(expiration = new Date(`1 minute from now`))\n    .withConditions(\n      key startsWith \"test/\",\n      acl eq PUBLIC_READ,\n      successActionRedirect eq expectedRedirectUrl,\n      header(CONTENT_TYPE) startsWith \"text/\",\n      meta(\"tag\").any)\n    .toPolicy\n\n// import Form helper\nimport fly.play.s3.upload.Form\n\nval formFieldsFromPolicy = Form(policy).fields\n\n// convert the form fields from the policy to an actial form\nformFieldsFromPolicy\n  .map {\n    case FormElement(name, value, true) =\u003e\n      s\"\"\"\u003cinput type=\"text\" name=\"$name\" value=\"$value\" /\u003e\"\"\"\n    case FormElement(name, value, false) =\u003e\n      s\"\"\"\u003cinput type=\"hidden\" name=\"$name\" value=\"$value\" /\u003e\"\"\"\n  }\n\n// make sure you add the file form field as last\nval allFormFields =\n  formFieldsFromPolicy.mkString(\"\\n\") +\n  \"\"\"\u003cinput type=\"text\" name=\"file\" /\u003e\"\"\"\n```\n\nMore examples can be found in the `S3Spec` in the `test` folder. In order to run the tests you need\nan `application.conf` file in the `test/conf` that looks like this:\n\n``` scala\naws.accessKeyId=\"...\"\naws.secretKey=\"...\"\n\ns3.region=\"eu-west-1\"\n\ntestBucketName=s3playlibrary.rhinofly.net\n```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkaliber-scala%2Fplay-s3","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkaliber-scala%2Fplay-s3","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkaliber-scala%2Fplay-s3/lists"}