src/main/scala/fis/notif/Notification.scala
changeset 108 ef4e3e0ef83f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/scala/fis/notif/Notification.scala	Tue Apr 23 10:36:04 2013 +0200
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2012 Tomas Zeman <tzeman@volny.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 fis.notif
+
+import fis.aaa.model.{User, UserContacts}
+import javax.mail.internet.MimeUtility
+import net.liftweb.common._
+import net.liftweb.http._
+import net.liftweb.util._
+import net.liftweb.util.Helpers._
+import net.tz.lift.snippet._
+import scala.xml.NodeSeq
+
+import Mailer._
+
+case class Notification(_path: String, _title: CssTr,
+  _content: CssTr, _note: CssTr, _from: From, _subject: String,
+  _mailTypes: Seq[MailTypes]) {
+
+  def title(t: CssTr) = this.copy(_title = t)
+  def title(t: NodeSeq) = this.copy(_title = lift(t))
+  def content(c: CssTr) = this.copy(_content = c)
+  def note(n: CssTr) = this.copy(_note = n)
+  def note(n: String) = this.copy(_note = "*" #> n)
+  def from(f: From) = this.copy(_from = f)
+  def subject(s: String) = this.copy(_subject = s)
+  def >> (mt: MailTypes) = this.copy(_mailTypes = _mailTypes :+ mt)
+  def >> (u: User) = this.copy(_mailTypes = _mailTypes ++
+    (UserContacts(u) map { c => To(c.workMail.get, Box !! c.linkName)}))
+  def to(u: Box[User]): Notification = u.dmap(this)(>> _)
+
+  private def lift(ns: NodeSeq): CssTr = { _ => ns }
+}
+
+object Notification {
+  def make: Notification = Notification("entity/notif", ClearNodes,
+    ClearNodes, ClearNodes, From(Props.get("sender.email") openOr "",
+    Props.get("sender.name")), "", Nil)
+}
+
+class NotificationEngine extends Loggable {
+
+  type Tr = Notification => Notification
+
+  import java.util.concurrent.atomic.AtomicReference
+  import scala.collection.mutable.ArrayBuffer
+
+  private lazy val _rules = new ArrayBuffer[Rule]()
+
+  class RuleEntrance(val name: String) {
+    def when(cond: => Boolean) = new {
+      def then(f: Tr*) = {
+        val r = new Rule(name, cond, f.toSeq)
+        _rules += r
+        logger.debug("Defined new rule: %s, rules count: %d".format(r.name,
+          _rules.size))
+        r
+      }
+    }
+  }
+
+  implicit def str2ruleEntrance(name: String) = new RuleEntrance(name)
+
+  class Rule(val name: String, cond: => Boolean, tr: Seq[Tr]) {
+    lazy val n = Notification.make
+    def active: Boolean = cond
+    def apply() = tr.foldLeft(n)((_n, f) => f(_n))
+  }
+
+  def subject(s: String): Tr = _.subject(s)
+  def title(t: CssTr): Tr = _.title(t)
+  def content(c: CssTr): Tr = _.content(c)
+  def to(u: Box[User]): Tr = _.to(u)
+  def note(n: CssTr): Tr = _.note(n)
+  def note(n: String): Tr = _.note(n)
+
+  private def enc(s: String) = MimeUtility.encodeText(s, "utf-8", null)
+
+  def execute(f: => Rule) = {
+    withBaseUrl.run(Props.get("url.base") openOr "") {
+      f
+      for {
+        r <- _rules if r.active
+        (out, n) <- {
+          val n = r()
+          S.runTemplate(n._path split "/" toList,
+            "title" -> n._title,
+            "panel" -> n._content,
+            "note" -> n._note) map(_ -> n)
+        }
+      } yield {
+        sendMail(n._from, Subject(enc(n._subject)), (n._mailTypes :+ XHTMLMailBodyType(out)):_*)
+        (n, n._subject, n._mailTypes flatMap {
+          case To(to, _) => Full(to)
+          case CC(cc, _) => Full(cc)
+          case _ => Empty
+        })
+      }
+    }
+  }
+
+}
+
+// vim: set ts=2 sw=2 et: