src/main/scala/s3/website/model/push.scala in s3_website-2.6.1 vs src/main/scala/s3/website/model/push.scala in s3_website-2.7.0

- old
+ new

@@ -9,10 +9,11 @@ import s3.website._ import s3.website.model.Upload.tika import s3.website.model.Encoding.encodingOnS3 import java.io.File.createTempFile import org.apache.commons.io.IOUtils.copy +import scala.concurrent.{ExecutionContextExecutor, Future} import scala.util.Try object Encoding { val defaultGzipExtensions = ".html" :: ".css" :: ".js" :: ".txt" :: Nil @@ -146,33 +147,58 @@ .filterNot(_.isDirectory) .filterNot(f => excludeFromUpload(site.resolveS3Key(f))) } } -case class Redirect(s3Key: String, redirectTarget: String) { +case class Redirect(s3Key: String, redirectTarget: String, needsUpload: Boolean) { def uploadType = RedirectFile } +private case class RedirectSetting(source: String, target: String) + object Redirect { - def resolveRedirects(implicit config: Config): Seq[Redirect] = - config.redirects.fold(Nil: Seq[Redirect]) { sourcesToTargets => - sourcesToTargets.foldLeft(Seq(): Seq[Redirect]) { + type Redirects = Future[Either[ErrorReport, Seq[Redirect]]] + + def resolveRedirects(s3FileFutures: Future[Either[ErrorReport, Seq[S3File]]]) + (implicit config: Config, executor: ExecutionContextExecutor, pushOptions: PushOptions): Redirects = { + val redirectSettings = config.redirects.fold(Nil: Seq[RedirectSetting]) { sourcesToTargets => + sourcesToTargets.foldLeft(Seq(): Seq[RedirectSetting]) { (redirects, sourceToTarget) => - redirects :+ Redirect(sourceToTarget._1, applySlashIfNeeded(sourceToTarget._2)) + redirects :+ RedirectSetting(sourceToTarget._1, applySlashIfNeeded(sourceToTarget._2)) } + } + def redirectsWithExistsOnS3Info = + s3FileFutures.map(_.right.map { s3Files => + val existingRedirectKeys = s3Files.filter(_.size == 0).map(_.s3Key).toSet + redirectSettings.map(redirectSetting => + Redirect(redirectSetting, needsUpload = !existingRedirectKeys.contains(redirectSetting.source)) + ) + }) + val uploadOnlyMissingRedirects = + config.treat_zero_length_objects_as_redirects.contains(true) && !pushOptions.force + val allConfiguredRedirects = Future(Right(redirectSettings.map(redirectSetting => + Redirect(redirectSetting, needsUpload = true) + ))) + if (uploadOnlyMissingRedirects) + redirectsWithExistsOnS3Info + else + allConfiguredRedirects } private def applySlashIfNeeded(redirectTarget: String) = { val isExternalRedirect = redirectTarget.matches("https?:\\/\\/.*") val isInSiteRedirect = redirectTarget.startsWith("/") if (isInSiteRedirect || isExternalRedirect) redirectTarget else "/" + redirectTarget // let the user have redirect settings like "index.php: index.html" in s3_website.ml } + + def apply(redirectSetting: RedirectSetting, needsUpload: Boolean): Redirect = + Redirect(redirectSetting.source, redirectSetting.target, needsUpload) } -case class S3File(s3Key: String, md5: MD5) +case class S3File(s3Key: String, md5: MD5, size: Long) object S3File { - def apply(summary: S3ObjectSummary): S3File = S3File(summary.getKey, summary.getETag) + def apply(summary: S3ObjectSummary): S3File = S3File(summary.getKey, summary.getETag, summary.getSize) }