function handle()

in site/api/pminfo.lua [25:236]


function handle(r)
    cross.contentType(r, "application/json")
    local DEBUG = config.debug or false
    
    local t = {}
    local START = DEBUG and r:clock() or nil
    local tnow = START
    local DD = 14
    
    local NOWISH = math.floor(os.time() / 1800)
    local PMINFO_CACHE_KEY = "pminfo_cache_" .. r.hostname .. "-" .. NOWISH
    
    local cache = r:ivm_get(PMINFO_CACHE_KEY)
    if cache then
        r:puts(cache)
        return cross.OK
    end

    
    if DEBUG then
      table.insert(t, r:clock() - tnow)
      tnow = r:clock()
    end

    local daterange = {gt = "now-"..DD.."d", lt = "now+1d" }
    
    
    local QUERY = {
            bool = {
                must = {
                    {
                        range = {
                            date = daterange
                        }
                    }, 
                    {
                        term = {
                            private = false
                        }
                    }
                }
            }
    }

    
    local doc = elastic.raw {
        size = 0, 
        query = QUERY,
        aggs = {
            nlists = { 
                cardinality = {
                    field = "list_raw"
                }
            },
            cards = { 
                cardinality = {
                    field = "from_raw"
                }
            },
            weekly = { 
                date_histogram = {
                    field = "date",
                    interval = "1d"
                }
            }
        }
    }

    local nal = doc.aggregations.nlists.value 
    
    local total_docs = doc.hits.total
    
    local no_senders = doc.aggregations.cards.value
    
    
    if DEBUG then
      table.insert(t, r:clock() - tnow)
      tnow = r:clock()
    end
    
    local activity = {}
    
    for k, v in pairs (doc.aggregations.weekly.buckets) do
        table.insert(activity, {v.key, v.doc_count})
    end
        
    
    if DEBUG then
      table.insert(t, r:clock() - tnow)
      tnow = r:clock()
    end
    
    
    
    local num_threads = 0
    local emails = {}
    local squery = {
        _source = {'message-id','in-reply-to','subject','references','epoch'},
        query = QUERY,
        sort = {
            {
                epoch = {
                    order = "desc"
                }
            }
        },
        size = elastic.MAX_RESULT_WINDOW
    }
    local hits = {}
    
    if total_docs > elastic.MAX_RESULT_WINDOW then
        local sid
        doc, sid = elastic.scroll(squery) 
        while doc and doc.hits and doc.hits.hits and #doc.hits.hits > 0 do 
            for k, v in pairs(doc.hits.hits) do
                table.insert(hits, v)
            end
            doc, sid = elastic.scroll(sid)
        end
        elastic.clear_scroll(sid) 
    else
        local doc = elastic.raw(squery)
        hits = doc.hits.hits
    end
    
    
    if DEBUG then
      table.insert(t, r:clock() - tnow)
      tnow = r:clock()
    end
    
    for k = #hits, 1, -1 do
        local v = hits[k]
        local email = v._source
        local mid = email['message-id']
        local irt = email['in-reply-to']
        email.id = v._id
        email.irt = irt
        emails[mid] = {
            tid = v._id,
            nest = 1,
            children = {
                
            }
        }
        
        if not irt or #irt == 0 then
            irt = email.subject:gsub("^[a-zA-Z]+:%s+", "")
        end
        if not emails[irt] then
            for ref in email.references:gmatch("(%S+)") do
                if emails[ref] then
                    irt = ref
                    break
                end
            end
        end
        
        
        if not emails[irt] then
            irt = email.subject:gsub("^[a-zA-Z]+:%s+", "")
            while irt:match("^[a-zA-Z]+:%s+") do
                irt = irt:gsub("^[a-zA-Z]+:%s+", "")
            end
        end
        
        if emails[irt] then
            if emails[irt].nest < 50 then
                emails[mid].nest = emails[irt].nest + 1
                table.insert(emails[irt].children, emails[mid])
            end
        else
            if (#email['in-reply-to'] > 0) then
                emails[irt] = {
                    children = {
                        emails[mid]
                    },
                    nest = 1,
                    tid = v._id
                }
                emails[mid].nest = emails[irt].nest + 1
            end
            num_threads = num_threads + 1
        end
    end
    
    
    if DEBUG then
      table.insert(t, r:clock() - tnow)
      tnow = r:clock()
    end
    
    JSON.encode_max_depth(500)
    local listdata = {}
    listdata.max = MAXRESULTS
    listdata.no_threads = num_threads
    listdata.hits = total_docs
    listdata.participants = no_senders
    listdata.no_active_lists = nal
    if DEBUG then
      listdata.took = r:clock() - START
      listdata.debug = t
    end

    listdata.activity = activity
    
    local output = JSON.encode(listdata)
    r:ivm_set(PMINFO_CACHE_KEY, output)
    r:puts(output)
    
    return cross.OK
end