Permalink
Browse files

you can't just let lists get infinitely long.

Replaced the reduce function with a technique that uses an object
instead.  Better match to the data, much more efficient on the json
bytes.
  • Loading branch information...
1 parent e9d1cd7 commit 60efc80ae362905fe95fdf2d40fdd13b5876ae38 @isaacs committed Dec 13, 2010
Showing with 92 additions and 33 deletions.
  1. +92 −33 log.js
View
125 log.js
@@ -7,85 +7,106 @@ ddoc.language = "javascript"
ddoc.rewrites =
[ { from: "/", to:"/_list/listRooms/rooms", method: "GET" }
- , { from: "/:room", to:"/_list/listDates/dates", method: "GET" }
+ , { from: "/:room/", to:"/_list/listDates/dates", method: "GET" }
, { from: "/:room/:date/", to:"/_list/listMessages/messages", method:"GET" }
+ , { from: "/-/message/:message", to:"/../../:message", method:"GET" }
]
ddoc.views.rooms =
{ map : function (doc) {
- if (doc.type === "room") {
- emit(doc._id, doc._id)
- }
+ if (doc.type === "room") emit(doc._id, doc._id)
}
}
+
ddoc.lists.listRooms = function (doc, req) {
var row
, rooms = {}
start({ headers: {"content-type":"text/html"}})
- send("<html><ul>")
+ send("<h1>rooms</h1> <ul>")
while (row = getRow()) {
+ if (row.value === "PM") continue
send("<li><a href='/" + row.value.replace(/#/g, '').toLowerCase()
+ "'>"+row.value+"</a></li>")
}
send("</ul>")
}
+// ddoc.views.dates = ddoc.views.rooms
+// ddoc.lists.listDates = ddoc.lists.listRooms
+// return
ddoc.views.dates =
{ map: function (doc) {
- if (!doc.when) return
+ if (!doc.when || !doc.where
+ || 0 !== doc.where.indexOf("#")) return
var w = new Date(doc.when)
w = w.getUTCFullYear()
+ "-" + (w.getUTCMonth()+1)
+ "-" + w.getUTCDate()
var i = w + (doc.where.replace(/#/g, '')).toLowerCase()
- emit(i, [{ date:w, room : doc.where }])
+ var em = {}
+ em[doc.where] = [w]
+ emit(i, [em])
}
, reduce : function (keys, values) {
var uniquekeys = []
- , em = []
+ , em = {}
// first flatten
values.forEach(function (v) {
- if (Array.isArray(v)) {
+ if (v.forEach) {
v.forEach(arguments.callee)
return
}
- if (uniquekeys.indexOf(v.date+v.room) !== -1) return
- uniquekeys.push(v.date+v.room)
- em.push(v)
+ // each value is a {$room:[$dates],...} collection
+ Object.keys(v).forEach(function (room) {
+ em[room] = em[room] || []
+ v[room].forEach(function (date) {
+ if (em[room].indexOf(date) === -1) em[room].push(date)
+ })
+ })
})
return em
}
}
+
+
+
ddoc.lists.listDates = function (head, req) {
start({headers:{"content-type":"text/html"}})
- if (req.query.room) send("<h1>"+req.query.room+"</h1>")
+ send("<h1><a href=/>rooms</a> ")
+ if (req.query && req.query.room) send(req.query.room)
+ send("</h1>")
var dates = getRow().value
if (!dates) {
- send("nada")
+ send("<p>nada")
return
}
- ;(req.query.room
- ? dates.filter(function (d) {
- return d.room.toLowerCase() === "#"+req.query.room.toLowerCase()
- })
- : dates
- ).forEach(function (d) {
- send("<li><a href='/"+d.room.replace(/#/g, '').toLowerCase() + "/"+
- d.date+"/'>"+(req.query.room ? "" : d.room) + " "+d.date+"</a></li>")
+ send("<ul>")
+ var rooms = Object.keys(dates)
+ if (req.query.room) rooms = rooms.filter(function (r) {
+ return r.toLowerCase() === "#" + req.query.room.toLowerCase()
+ })
+ rooms.forEach(function (room) {
+ dates[room].forEach(function (d) {
+ send("<li><a href='/"+room.replace(/#/g, '').toLowerCase() + "/" +
+ d+"/'>"+(req.query.room ? "" : room)+" "+d+"</a></li>")
+ })
})
}
+
+
ddoc.views.messages =
{ map: function (doc) {
- if (doc.type !== "message") return
+ if (doc.type === "room") return
emit(doc._id, doc)
}
}
+
ddoc.lists.listMessages = function (head, req) {
start({headers:{"content-type":"text/html"}})
var msg
- , startTime
+ , startTime, startDate
, end
if (req.query.date) {
startTime = + (new Date(req.query.date))
@@ -94,6 +115,15 @@ ddoc.lists.listMessages = function (head, req) {
end = Date.now()
startTime = end - (24*60*60*1000)
}
+ startDate = new Date(startTime)
+ var h = "<h1><a href=/>rooms</a> "
+ + (req.query.room ? "<a href='/"+(req.query.room)+"/'>"
+ + req.query.room + "</a>"
+ : "") + " "
+ + startDate.getUTCFullYear() + "-"
+ + (startDate.getUTCMonth() + 1) + "-"
+ + startDate.getUTCDate() + "</h1>"
+ send(h)
var msgs = []
while (msg = getRow()) {
if (!msg.value) continue
@@ -109,27 +139,56 @@ ddoc.lists.listMessages = function (head, req) {
msgs = msgs.sort(function (a, b) {
return a.timestamp > b.timestamp ? 1 : -1
})
- function sani (s) {
- return s.replace(/&/g, '&amp;').replace(/</g, '&gt;')
+ function sani (s, link) {
+ if (!s) return ""
+ s = s.replace(/&/g, '&amp;')
+ .replace(/"/g, '&quot;')
+ .replace(/</g, '&lt;')
+ // if (link) s = s.replace(
+ // /\b((?:ftp|http):\/\/[\w\d_-]+(:?\.[\w\d_-]*)*(:?\/[^\?\s\#]*)?(:?\?[^\s\#]*)?(:?\#[^\s]*)?)/gi,
+ // '<a href="$1">$1</a>')
+ return s
}
- send("<style type=text/css>p { font-family:monospace;padding:0;"
- + " margin:0 0 0 10ex ; text-indent:-10ex }"
+ send("<style type=text/css>p { font-family:monospace; margin:0; padding:0;"
+ + "position:relative; overflow:hidden; }"
+ + "p a.l { text-decoration:none; color:inherit; display:block;"
+ + " margin: -4em 0 0; padding: 4em 0 0; }"
+ + "span.l { display:block; margin:0; padding:0;"
+ + " padding:0 2ex 0 10ex ; text-indent:-10ex; background:#fff;"
+ + " position:relative; }"
+ + "p a.l:target span { background:#ffc }"
+ + "p a.l:hover span { background:#eef }"
+ + "p a.expand { position:absolute; right:1ex; top:0;"
+ + " padding:0; margin:0; display:none; color:#eef;"
+ + "}"
+ + "p:hover a.expand { display:block; background:#cfc }"
+ + ".PART, .QUIT, .JOIN { color: #ccc; text-align:center }"
+ + "body { padding:0 0 5em }"
+ "html,body { width:100%; overflow-x:hidden }</style>")
msgs.forEach(function (m) {
- // send(toJSON(m))
var o = ""
- o += new Date(m.when).toISOString().substr(11,8) + " "
+// if (req.query.room && req.query.room.match(/testing/)) {
+// return send( "<p>" + JSON.stringify(m) + "</p>" )
+// }
+ if (m.command === "PRIVMSG") {
+ o += new Date(m.when).toISOString().substr(11,8) + " "
+ }
if (!req.query.room) o += (m.where+" ")
- o += ("<b>"+sani(m.nick)+"</b>")
+ o += ("<b>"+sani(m.nick||m.user)+"</b>")
if (m.what.indexOf("\u0001ACTION ") === 0) {
m.what = m.what.substr("\u0001ACTION".length)
m.what = m.what.substr(0, m.what.length - 1)
} else o += ": "
- o += sani(m.what)
- o = "<p>"+o+"</p>"
+ o += sani(m.what, true)
+ o = "<p class='"+m.command+"'><a id='"+m._id
+ + "' class=l name='"+m._id+"' href='#"+m._id+"'>"
+ + "<span class=l>"+ o
+ + "</span></a><a class=expand href='/-/message/"+m._id+"'>+</a></p>"
send(o)
})
}
+
+
ddoc.validate_doc_update = function (newDoc, oldDoc, user) {
if (user.roles.indexOf("_admin") === -1) throw {forbidden:"admins only"}
}

0 comments on commit 60efc80

Please sign in to comment.