base/src/sqwl/cms/Server.scala
author Tomas Zeman <tomas@functionals.cz>
Tue, 29 Dec 2020 16:46:47 +0100
changeset 33 fa0f19a74283
parent 32 2d14f02ba3bd
permissions -rw-r--r--
CMS API update

/*
 * Copyright 2018-2020 Tomas Zeman <tomas@functionals.cz>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package sqwl.cms

import akka.actor.typed.ActorSystem
import akka.actor.typed.scaladsl.Behaviors
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.headers.ETag
import akka.http.scaladsl.model.{ContentTypes, HttpEntity, HttpHeader, HttpResponse}
import akka.http.scaladsl.server.Directives._

import scala.collection.immutable
import scala.concurrent.ExecutionContextExecutor

trait Server extends App with Service[Nothing] with config with UrlScheme {

  override implicit val system: ActorSystem[Nothing] =
    ActorSystem(Behaviors.empty, "Server")
  override implicit val executor: ExecutionContextExecutor =
    system.executionContext

  protected def content: iContent

  val asArticle = Segment.flatMap(content.articleByPath(_))
  val asCategory = Segment.flatMap(content.categoryByPath(_))
  val asTag = Segment.flatMap(content.tagByPath(_))

  private def asHtml(st: ViewState): HttpResponse = {
    val s = Layout(content, st).render
    HttpResponse(
      headers = immutable.Seq[HttpHeader](ETag(MD5(s))),
      entity = HttpEntity(ContentTypes.`text/html(UTF-8)`,
      "<!DOCTYPE html>" + s))
  }

  private val routes = get {
    pathPrefix(http.prefix) {
      pathEnd {
        complete(asHtml(Dashboard))
      } ~ pathPrefix(asArticle) { article =>
        pathEnd {
          complete(asHtml(ViewArticle(article)))
        } ~ getFromDirectory(content.articleAssets(article).toString)
      } ~ path(asCategory) { category =>
        complete(asHtml(ViewCategory(category)))
      } ~ path(TAG / asTag) { tag =>
        complete(asHtml(ViewTag(tag)))
      }
    } ~ pathPrefix(http.prefix / ASSETS) {
      getFromResourceDirectory("META-INF/resources/webjars")
    } ~ pathPrefix(http.prefix / PUBLIC / content.icon._1) {
      getFromFile(content.icon._2.toFile)
    } ~ pathPrefix(http.prefix / PUBLIC / content.styleSheet._1) {
      getFromFile(content.styleSheet._2.toFile)
    } ~ pathPrefix(http.prefix / PUBLIC) {
      getFromDirectory(content.publicAssets.toString)
    }
  }

  Http().newServerAt(http.interface, http.port).bind(routes)

}