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)
}