/src/main/scala/com/theintelligentbook/ibmodel/mongo/ChatComment.scala
Scala | 218 lines | 154 code | 51 blank | 13 comment | 0 complexity | c755f7e110354c8c4361b224006f3445 MD5 | raw file
- package com.theintelligentbook.ibmodel.mongo
- import com.mongodb.casbah.Imports._
- import java.util.Date
- import com.novus.salat._
- import com.novus.salat.global._
- import com.novus.salat.dao.SalatDAO
- import com.wbillingsley.handy.{RefItself, RefNone, RefById, Ref}
- import com.mongodb.util.JSON
- import com.novus.salat.annotations._
- case class ChatComment(
- _id:ObjectId = new ObjectId(),
- val anonymous:Boolean = true,
- @Key("book") _book:Option[ObjectId] = None,
- @Key("createdBy") _createdBy:Option[ObjectId] = None,
- val session:Option[String] = None,
- val comment:Option[String] = None,
- val topics:Seq[String] = Seq.empty[String],
- val created:Date = new Date()
- ) extends HasObjectId {
-
- def id = _id
-
- def book = Ref.fromOptionId(classOf[Book], _book)
-
- def createdBy = Ref.fromOptionId(classOf[Reader], _createdBy)
-
- }
- object ChatCommentDAO extends AbstractDAO[ChatComment]("chatComment") {
- /**
- * Gets chat comments for a book, optionally providing cursors for the range required.
- * @param book
- * @param after
- * @param before
- * @return
- */
- def findByBook(book:Ref[Book], after:Ref[ChatComment], before:Ref[ChatComment], maxElements:Option[Int]):Seq[ChatComment] = {
- book.getId match {
- case Some(bid) => {
- var map = MongoDBObject("book" -> bid)
- after.getId.foreach{afterId =>
- map ++= ("_id" $gt afterId)
- }
- before.getId.foreach{beforeId =>
- map ++= ("_id" $lt beforeId)
- }
- val cursor = sdao.find(map).sort(MongoDBObject("_id" -> -1))
- maxElements.foreach {max => cursor.limit(max)}
- cursor.toSeq
- }
- case None => Seq.empty[ChatComment]
- }
- }
- def newChatComment(
- anonymous:Boolean = true,
- book:Ref[Book] = RefNone,
- createdBy:Ref[Reader] = RefNone,
- session:Option[String] = None,
- comment:Option[String] = None,
- topics:Seq[String] = Seq.empty[String]
- ) = {
- val cc = new ChatComment(
- anonymous = anonymous,
- _book = book.getId.asInstanceOf[Option[ObjectId]],
- _createdBy = createdBy.getId.asInstanceOf[Option[ObjectId]],
- session = session,
- comment = comment,
- topics = topics
- )
- DAO.cache(RefById(classOf[ChatComment], cc.id), RefItself(cc))
- cc
- }
- def save(c:ChatComment) {
- DAO.cache(RefById(classOf[ChatComment], c.id), RefItself(c))
- sdao.save(c)
- }
-
- def updateStatsByDay(b:Ref[Book]) = {
-
- val mapJs = """
- function m() {
- var t = this.created
- t.setMinutes(0)
- t.setSeconds(0)
- t.setMilliseconds(0)
- var v = {
- book: this.book,
- time: t,
- readers: {},
- sessions: {},
- anonymous: 0,
- total: 1,
- kinds: {},
- sites: {},
- adjs: {},
- nouns: {},
- topics: {}
- }
-
- if (this.reader) { v.readers[this.reader] = 1 } else { v.anonymous = 1 }
- if (this.session) { v.sessions[this.session] = 1 }
- if (this.kind) { v.kinds[this.kind] = 1 }
- if (this.site) { v.sites[this.site] = 1 }
- if (this.adjs) { this.adjs.forEach(function(adj) { v.adjs[adj] = 1 }) }
- if (this.nouns) { this.nouns.forEach(function(noun) { v.nouns[noun] = 1 }) }
- if (this.topics) { this.topics.forEach(function(topic) { v.topics[topic] = 1 }) }
- emit( { book: this.book, time: t }, v )
- }
- """
-
- val reduceJs = """
- function r(k, values) {
- var n = { book: k.book, time: k.time, readers: {}, anonymous: 0, total: 0, sessions: {}, kinds: {}, sites: {}, adjs: {}, nouns: {}, topics: {}, ces: {} }
- values.forEach(function(value) {
- n.total += value.total
- n.anonymous += value.anonymous
-
- function accrue(from, into) {
- for (var k in from) {
- into[k] = (into[k] || 0) + from[k]
- }
- }
-
- accrue(value.readers, n.readers)
- accrue(value.sessions, n.sessions)
- accrue(value.kinds, n.kinds)
- accrue(value.sites, n.sites)
- accrue(value.adjs, n.adjs)
- accrue(value.nouns, n.nouns)
- accrue(value.topics, n.topics)
- })
-
- return n
- }
- """
-
-
- val bookId = b.getId.getOrElse(new ObjectId())
-
- val result = sdao.collection.mapReduce(mapJs, reduceJs, MapReduceMergeOutput("aggChats"), Some(Map("book" -> bookId)), sort=None, limit=None, finalizeFunction=None, jsScope=None, verbose=false)
- result.cursor
- }
-
- }
- /*
- * Below is temporary stuff for charting chat comments
- */
- case class AggChatCC(
- value:AggChatVal
- )
- /**
- * An Aggregated Events entry
- */
- case class AggChatVal(
-
- book:Option[ObjectId] = None,
-
- time:Date = new Date,
-
- sessions:Map[String, Int] = Map.empty[String, Int],
-
- readers:Map[String, Int] = Map.empty[String, Int],
-
- anonymous:Int = 0,
-
- kinds:Map[String, Int] = Map.empty[String, Int],
-
- sites:Map[String, Int] = Map.empty[String, Int],
-
- adjs:Map[String, Int] = Map.empty[String, Int],
-
- nouns:Map[String, Int] = Map.empty[String, Int],
-
- topics:Map[String, Int] = Map.empty[String, Int],
-
- ces:Map[String, Int] = Map.empty[String, Int]
- )
- object AggChatDAO {
- val collName = "aggChats"
- lazy val sdao = new SalatDAO[AggChatCC, ObjectId](DAO.getCollection(collName)) {
- }
- def aggEventsCC(b:Ref[Book]) = {
- sdao.find(Map("_id.book" -> b.getId.getOrElse(new ObjectId())))
- }
-
- def aggEventsJson(b:Ref[Book]):Seq[String] = {
- val c = DAO.getCollection("aggChats").find(Map("_id.book" -> b.getId.getOrElse(new ObjectId())))
- c.toSeq.map(o => JSON.serialize(o.get("value")))
- }
- }