Module:Discussions

From Anthroposophy

Documentation for this module may be created at Module:Discussions/doc

local p = {}

function formatTimestamp(timestamp)
    -- Input timestamp in milliseconds
    local timestamp_ms = tonumber(timestamp) -- Default value for testing

    -- Convert milliseconds to seconds
    local timestamp_seconds = math.floor(timestamp_ms / 1000)

    -- Format the timestamp as Y-m-d
    local formatted_date = os.date("!%Y-%m-%d", timestamp_seconds)

    -- Return the formatted date
    return formatted_date
end

local function capitalizeFirstLetter(str)
    return mw.ustring.upper(mw.ustring.sub(str, 1, 1)) .. mw.ustring.sub(str, 2)
end

-- Function to format a timestamp into Y-m-d
local function formatTimestamp(timestamp)
    -- Ensure the input is a string and has the expected length
    if type(timestamp) ~= "string" or #timestamp < 8 then
        return nil -- Return nil for invalid input
    end

    -- Extract year, month, and day from the timestamp
    local year = timestamp:sub(1, 4)   -- First 4 characters (YYYY)
    local month = timestamp:sub(5, 6) -- Next 2 characters (MM)
    local day = timestamp:sub(7, 8)   -- Next 2 characters (DD)

    -- Return the formatted date as Y-m-d
    return string.format("%s-%s-%s", year, month, day)
end

function getTopicHistory(topicPage)

    local query = mw.ext.externalData.getWebData {
		url = 'https://anthroposophy.eu/w/api.php?action=flow&format=json&submodule=view-topic-history&page=' .. 
			mw.uri.encode(topicPage, "PATH") .. 
			'&vtloffset-dir=fwd&vtltoconly=1&vtlformat=wikitext',
            format = 'JSON with jsonpath',
            data = {
				revisions = '$..revisions'
            }
	    }
	    
	-- revisions
	local numberofrevs = 0
	if query.revisions and #query.revisions > 0 then
		numberofrevs = #query.revisions
	end
	
	-- posts
	local postIds = {}
	local counter = 0
	if query.revisions then
    	for _, revision in pairs(query.revisions) do
    		local postId = revision.postId
        	if postId and not postIds[postId] then
            	postIds[postId] = true
            	counter = counter + 1
        	end
    	end
	end
	
	-- authors
	local authors = {}
    for _, revision in ipairs(query.revisions) do
        local authorName = revision.author.name
        if authorName then
            authors[authorName] = true 
        end
    end
    
	local authorlist = {}
    for name, _ in pairs(authors) do
        table.insert(authorlist, string.format('[[User:%s|%s]]', name, name))
    end
	
	-- creator
	local creator = query.revisions[#query.revisions].author.name or ''
	local creatorlink = ''
	if creator ~= nil and creator ~= '' then
		creatorlink = string.format('[[User:%s|%s]]', creator, creator)
	end
	local created = query.revisions[#query.revisions].timestamp or ''
	
	-- last editor
	local lasteditor = query.revisions[1].author.name or ''
	local lasteditorlink = ''
	if lasteditor ~= nil and lasteditor ~= '' then
		lasteditorlink = string.format('[[User:%s|%s]]', lasteditor, lasteditor)
	end
	local lastedited = query.revisions[1].timestamp or ''
	
	-- authors
	local authors = {}
	
    for _, revision in ipairs(query.revisions) do
        local authorName = revision.author.name
        if authorName then
            authors[authorName] = true 
        end
    end
    
    local authorlist = {}
    for name, _ in pairs(authors) do
        table.insert(authorlist, string.format('[[User:%s|%s]]', name, name))
    end
    
    local printauthors = table.concat(authorlist, ', ')
    
    -- result table
    local data = {
		['numberofrevisions'] = numberofrevs,
		['createdby'] = creatorlink,
		['createdon'] = created,
		['lasteditedby'] = lasteditorlink,
		['lasteditedon'] = lastedited,
		['authors'] = printauthors,
		['numberofauthors'] = #authorlist,
		['numberofposts'] = counter
	}
	
    return data
end

function p.main(frame)

	local getdata = mw.ext.externalData.getDbData {
		db = 'fmc',
		from = 'flow_workflow',
		where = 'workflow_type = "discussion"',
		format = JSON,
		data = {
			page_title   = 'workflow_title_text',
			namespace    = 'workflow_namespace'
		}
	}

	local html = mw.html.create()
	
	local topics = html:tag('table')
		:attr('id', 'alldiscussions')
		:addClass('smwtable-clean sortable')
	
    for _, board in ipairs(getdata) do
    	
    	local ns = ''
    	
		if board['namespace'] == '1' then
    		ns = 'Talk:'
    	elseif board['namespace'] == '3' then
    		ns = 'User_talk:'
    	end
    	
        local title = ns .. board['page_title'] 
        
        local query = mw.ext.externalData.getWebData {
            url = 'https://anthroposophy.eu/w/api.php?action=flow&format=json&submodule=view-topiclist&page=' .. 
                   mw.uri.encode(title, "PATH") .. 
                  '&vtloffset-dir=fwd&vtltoconly=1&vtlformat=wikitext',
            format = 'JSON with jsonpath',
            data = {
            	revisions = '$..topiclist.revisions',
            	roots = '$..topiclist.roots',
            	posts = '$..topiclist.posts'
            }
	    }

		local roots = query.roots or {}	    
	    local posts = query.posts or {}
	    local revisions = query.revisions or {}

		for _, root in ipairs(roots) do
   			-- Check if the root exists in the posts table
       		if posts[root] then
           		-- Iterate through each post ID associated with the root
       			for _, post in ipairs(posts[root]) do
               		-- Check if the post ID exists in the revisions table
               		if revisions[post] then
                   		-- Append the root|revision pair to the results table
                   		local title = revisions[post].content.plaintext
                   		local sort_title = capitalizeFirstLetter(title:gsub("[\"']", ""))
                   		local updated = formatTimestamp(revisions[post].last_updated)
                   		
                   		local stats = getTopicHistory('Topic:' .. root) or {}
						local formattedCreated = formatTimestamp(stats.createdon)
						local formattedLastedited = formatTimestamp(stats.lasteditedon)
						
						local row = topics:tag('tr')
						row:tag('td')
							:attr('data-sort', sort_title)
							:wikitext(string.format('[[Topic:%s|%s]]'
                   				, root
                   				, title
                   			))
						row:tag('td')
							:wikitext(stats.createdby)
						row:tag('td')
							:attr('data-sort', formattedCreated)
							:wikitext(formattedCreated)								
						row:tag('td')
							:wikitext(stats.numberofauthors)
							:attr('data-sort', stats.numberofauthors)
						row:tag('td')
							:wikitext(stats.authors)
						row:tag('td')
							:wikitext(stats.numberofposts)
							:attr('data-sort', stats.numberofposts)
						row:tag('td')
							:wikitext(stats.lasteditedby)
						row:tag('td')
							:wikitext(formattedLastedited)
							:attr('data-sort', formattedLastedited)
               		end
       			end
       		end
   		end
    end

	return topics
end

function p.test()
	 local query = mw.ext.externalData.getWebData {
		url = 'https://anthroposophy.eu/w/api.php?action=flow&format=json&submodule=view-topic-history&page=' .. 
			mw.uri.encode(topicPage, "PATH") .. 
			'&vtloffset-dir=fwd&vtltoconly=1&vtlformat=wikitext',
            format = 'JSON with jsonpath',
            data = {
				revisions = '$..revisions'
            }
	    }
	    
	-- revisions
	local numberofrevs = 0
	if query.revisions and #query.revisions > 0 then
		numberofrevs = #query.revisions
	end
	
	-- posts
	local postIds = {}
	if query.revisions then
    	for _, revision in ipairs(query.revisions) do
    		local postId = revision.postId
        	if postId and not postIds[postId] then
            	postIds[postId] = true
        	end
    	end
	end
end	

return p