src/main/scala/fis/notif/Notification.scala
changeset 108 ef4e3e0ef83f
equal deleted inserted replaced
107:26e9d0e4a619 108:ef4e3e0ef83f
       
     1 /*
       
     2  * Copyright 2012 Tomas Zeman <tzeman@volny.cz>
       
     3  *
       
     4  * Licensed under the Apache License, Version 2.0 (the "License");
       
     5  * you may not use this file except in compliance with the License.
       
     6  * You may obtain a copy of the License at
       
     7  *
       
     8  *     http://www.apache.org/licenses/LICENSE-2.0
       
     9  *
       
    10  * Unless required by applicable law or agreed to in writing, software
       
    11  * distributed under the License is distributed on an "AS IS" BASIS,
       
    12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
       
    13  * See the License for the specific language governing permissions and
       
    14  * limitations under the License.
       
    15  */
       
    16 package fis.notif
       
    17 
       
    18 import fis.aaa.model.{User, UserContacts}
       
    19 import javax.mail.internet.MimeUtility
       
    20 import net.liftweb.common._
       
    21 import net.liftweb.http._
       
    22 import net.liftweb.util._
       
    23 import net.liftweb.util.Helpers._
       
    24 import net.tz.lift.snippet._
       
    25 import scala.xml.NodeSeq
       
    26 
       
    27 import Mailer._
       
    28 
       
    29 case class Notification(_path: String, _title: CssTr,
       
    30   _content: CssTr, _note: CssTr, _from: From, _subject: String,
       
    31   _mailTypes: Seq[MailTypes]) {
       
    32 
       
    33   def title(t: CssTr) = this.copy(_title = t)
       
    34   def title(t: NodeSeq) = this.copy(_title = lift(t))
       
    35   def content(c: CssTr) = this.copy(_content = c)
       
    36   def note(n: CssTr) = this.copy(_note = n)
       
    37   def note(n: String) = this.copy(_note = "*" #> n)
       
    38   def from(f: From) = this.copy(_from = f)
       
    39   def subject(s: String) = this.copy(_subject = s)
       
    40   def >> (mt: MailTypes) = this.copy(_mailTypes = _mailTypes :+ mt)
       
    41   def >> (u: User) = this.copy(_mailTypes = _mailTypes ++
       
    42     (UserContacts(u) map { c => To(c.workMail.get, Box !! c.linkName)}))
       
    43   def to(u: Box[User]): Notification = u.dmap(this)(>> _)
       
    44 
       
    45   private def lift(ns: NodeSeq): CssTr = { _ => ns }
       
    46 }
       
    47 
       
    48 object Notification {
       
    49   def make: Notification = Notification("entity/notif", ClearNodes,
       
    50     ClearNodes, ClearNodes, From(Props.get("sender.email") openOr "",
       
    51     Props.get("sender.name")), "", Nil)
       
    52 }
       
    53 
       
    54 class NotificationEngine extends Loggable {
       
    55 
       
    56   type Tr = Notification => Notification
       
    57 
       
    58   import java.util.concurrent.atomic.AtomicReference
       
    59   import scala.collection.mutable.ArrayBuffer
       
    60 
       
    61   private lazy val _rules = new ArrayBuffer[Rule]()
       
    62 
       
    63   class RuleEntrance(val name: String) {
       
    64     def when(cond: => Boolean) = new {
       
    65       def then(f: Tr*) = {
       
    66         val r = new Rule(name, cond, f.toSeq)
       
    67         _rules += r
       
    68         logger.debug("Defined new rule: %s, rules count: %d".format(r.name,
       
    69           _rules.size))
       
    70         r
       
    71       }
       
    72     }
       
    73   }
       
    74 
       
    75   implicit def str2ruleEntrance(name: String) = new RuleEntrance(name)
       
    76 
       
    77   class Rule(val name: String, cond: => Boolean, tr: Seq[Tr]) {
       
    78     lazy val n = Notification.make
       
    79     def active: Boolean = cond
       
    80     def apply() = tr.foldLeft(n)((_n, f) => f(_n))
       
    81   }
       
    82 
       
    83   def subject(s: String): Tr = _.subject(s)
       
    84   def title(t: CssTr): Tr = _.title(t)
       
    85   def content(c: CssTr): Tr = _.content(c)
       
    86   def to(u: Box[User]): Tr = _.to(u)
       
    87   def note(n: CssTr): Tr = _.note(n)
       
    88   def note(n: String): Tr = _.note(n)
       
    89 
       
    90   private def enc(s: String) = MimeUtility.encodeText(s, "utf-8", null)
       
    91 
       
    92   def execute(f: => Rule) = {
       
    93     withBaseUrl.run(Props.get("url.base") openOr "") {
       
    94       f
       
    95       for {
       
    96         r <- _rules if r.active
       
    97         (out, n) <- {
       
    98           val n = r()
       
    99           S.runTemplate(n._path split "/" toList,
       
   100             "title" -> n._title,
       
   101             "panel" -> n._content,
       
   102             "note" -> n._note) map(_ -> n)
       
   103         }
       
   104       } yield {
       
   105         sendMail(n._from, Subject(enc(n._subject)), (n._mailTypes :+ XHTMLMailBodyType(out)):_*)
       
   106         (n, n._subject, n._mailTypes flatMap {
       
   107           case To(to, _) => Full(to)
       
   108           case CC(cc, _) => Full(cc)
       
   109           case _ => Empty
       
   110         })
       
   111       }
       
   112     }
       
   113   }
       
   114 
       
   115 }
       
   116 
       
   117 // vim: set ts=2 sw=2 et: