src/main/scala/s3/website/model/push.scala in s3_website-2.10.0 vs src/main/scala/s3/website/model/push.scala in s3_website-2.11.0
- old
+ new
@@ -19,15 +19,15 @@
val defaultGzipExtensions = ".html" :: ".css" :: ".js" :: ".txt" :: ".ico" :: Nil
case class Gzip()
case class Zopfli()
- def encodingOnS3(s3Key: String)(implicit config: Config): Option[Either[Gzip, Zopfli]] =
+ def encodingOnS3(s3Key: S3Key)(implicit config: Config): Option[Either[Gzip, Zopfli]] =
config.gzip.flatMap { (gzipSetting: Either[Boolean, Seq[String]]) =>
val shouldZipThisFile = gzipSetting.fold(
- shouldGzip => defaultGzipExtensions exists s3Key.endsWith,
- fileExtensions => fileExtensions exists s3Key.endsWith
+ shouldGzip => defaultGzipExtensions exists s3Key.key.endsWith,
+ fileExtensions => fileExtensions exists s3Key.key.endsWith
)
if (shouldZipThisFile && config.gzip_zopfli.isDefined)
Some(Right(Zopfli()))
else if (shouldZipThisFile)
Some(Left(Gzip()))
@@ -69,55 +69,25 @@
mimeType + "; charset=utf-8"
else
mimeType
}
- lazy val maxAge: Option[Int] = {
- type GlobsMap = Map[String, Int]
- site.config.max_age.flatMap { (intOrGlobs: Either[Int, GlobsMap]) =>
- type GlobsSeq = Seq[(String, Int)]
- def respectMostSpecific(globs: GlobsMap): GlobsSeq = globs.toSeq.sortBy(_._1.length).reverse
- intOrGlobs
- .right.map(respectMostSpecific)
- .fold(
- (seconds: Int) => Some(seconds),
- (globs: GlobsSeq) => {
- val matchingMaxAge = (glob: String, maxAge: Int) =>
- rubyRuntime.evalScriptlet(
- s"""|# encoding: utf-8
- |File.fnmatch('$glob', "$s3Key")""".stripMargin)
- .toJava(classOf[Boolean])
- .asInstanceOf[Boolean]
- val fileGlobMatch = globs find Function.tupled(matchingMaxAge)
- fileGlobMatch map (_._2)
- }
- )
- }
- }
+ lazy val maxAge: Option[Int] =
+ site.config.max_age.flatMap(
+ _ fold(
+ (maxAge: Int) => Some(maxAge),
+ (globs: S3KeyGlob[Int]) => globs.globMatch(s3Key)
+ )
+ )
- lazy val cacheControl: Option[String] = {
- type GlobsMap = Map[String, String]
- site.config.cache_control.flatMap { (intOrGlobs: Either[String, GlobsMap]) =>
- type GlobsSeq = Seq[(String, String)]
- def respectMostSpecific(globs: GlobsMap): GlobsSeq = globs.toSeq.sortBy(_._1.length).reverse
- intOrGlobs
- .right.map(respectMostSpecific)
- .fold(
- (cacheCtrl: String) => Some(cacheCtrl),
- (globs: GlobsSeq) => {
- val matchingCacheControl = (glob: String, cacheControl: String) =>
- rubyRuntime.evalScriptlet(
- s"""|# encoding: utf-8
- |File.fnmatch('$glob', "$s3Key")""".stripMargin)
- .toJava(classOf[Boolean])
- .asInstanceOf[Boolean]
- val fileGlobMatch = globs find Function.tupled(matchingCacheControl)
- fileGlobMatch map (_._2)
- }
- )
- }
- }
+ lazy val cacheControl: Option[String] =
+ site.config.cache_control.flatMap(
+ _ fold(
+ (cacheCtrl: String) => Some(cacheCtrl),
+ (globs: S3KeyGlob[String]) => globs.globMatch(s3Key)
+ )
+ )
/**
* May throw an exception, so remember to call this in a Try or Future monad
*/
lazy val md5 = Upload md5 originalFile
@@ -156,44 +126,40 @@
else
Nil
}
def listSiteFiles(implicit site: Site, logger: Logger) = {
- def excludeFromUpload(s3Key: String) = {
+ def excludeFromUpload(s3Key: S3Key) = {
val excludeByConfig = site.config.exclude_from_upload exists {
- _.fold(
- // For backward compatibility, use Ruby regex matching
- (exclusionRegex: String) => rubyRegexMatches(s3Key, exclusionRegex),
- (exclusionRegexes: Seq[String]) => exclusionRegexes exists (rubyRegexMatches(s3Key, _))
- )
+ _.s3KeyRegexes.exists(_ matches s3Key)
}
- val neverUpload = "s3_website.yml" :: ".env" :: Nil
+ val neverUpload = "s3_website.yml" :: ".env" :: Nil map (k => S3Key.build(k, site.config.s3_key_prefix))
val doNotUpload = excludeByConfig || (neverUpload contains s3Key)
if (doNotUpload) logger.debug(s"Excluded $s3Key from upload")
doNotUpload
}
recursiveListFiles(site.rootDirectory)
.filterNot(_.isDirectory)
.filterNot(f => excludeFromUpload(site.resolveS3Key(f)))
}
}
-case class Redirect(s3Key: String, redirectTarget: String, needsUpload: Boolean) {
+case class Redirect(s3Key: S3Key, redirectTarget: String, needsUpload: Boolean) {
def uploadType = RedirectFile
}
-private case class RedirectSetting(source: String, target: String)
+private case class RedirectSetting(source: S3Key, target: String)
object 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 :+ RedirectSetting(sourceToTarget._1, applySlashIfNeeded(sourceToTarget._2))
+ redirects :+ RedirectSetting(sourceToTarget._1, applyRedirectRules(sourceToTarget._2))
}
}
def redirectsWithExistsOnS3Info =
s3FileFutures.map(_.right.map { s3Files =>
val existingRedirectKeys = s3Files.filter(_.size == 0).map(_.s3Key).toSet
@@ -210,23 +176,24 @@
redirectsWithExistsOnS3Info
else
allConfiguredRedirects
}
- private def applySlashIfNeeded(redirectTarget: String) = {
+ private def applyRedirectRules(redirectTarget: String)(implicit config: Config) = {
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
+ s"${config.s3_key_prefix.map(prefix => s"/$prefix").getOrElse("")}/$redirectTarget"
}
def apply(redirectSetting: RedirectSetting, needsUpload: Boolean): Redirect =
Redirect(redirectSetting.source, redirectSetting.target, needsUpload)
}
-case class S3File(s3Key: String, md5: MD5, size: Long)
+case class S3File(s3Key: S3Key, md5: MD5, size: Long)
object S3File {
- def apply(summary: S3ObjectSummary): S3File = S3File(summary.getKey, summary.getETag, summary.getSize)
+ def apply(summary: S3ObjectSummary)(implicit site: Site): S3File =
+ S3File(S3Key.build(summary.getKey, None), summary.getETag, summary.getSize)
}