Open main menu
Home
Random
Donate
Recent changes
Special pages
Community portal
Preferences
About Stockhub
Disclaimers
Search
User menu
Talk
Contributions
Create account
Log in
Editing
Module:Sandbox/Aidan9382/DiscussionOverview
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
--[=[ A module designed to provide an overall summary and some statistics on a discussion board Inspired by, and partially borrowed from, [[Module:Sandbox/Smalljim/DiscussionIndexTest]] --]=] local Transcluder = require("Module:Transcluder") local p = {} table.find = function(t,o) --Used to luau, so assumed this existed. Heres a quick version for a,b in next,t do if b == o then return true end end return false end local lang = mw.getContentLanguage() local function getTime(timestamp) return tonumber(lang:formatDate("U",timestamp)) end local function concatUsers(users) local final = "" for _,user in next,users do if string.match(user,"^%d+%.%d+%.%d+%.%d+$") or string.match(user,"^%x+:[%x:]+$") then --Lazy but mostly working basic IPv6 regex final = final .. "[[Special:Contributions/"..user.."|"..user.."]], " else final = final .. "[[:User:"..user.."|"..user.."]], " end end return string.sub(final,1,-3) end --Specialised version of Sandbox/Smalljim/ParsePageTest.formatDateDiff that just does hours (better for sorting cause im not learning wikitables) local function formatDateDiff( date_diff ) return tonumber( math.floor(date_diff/(6*60))/10 ) .. ' hours'; end --Specialised version of Transcluder.getSections, using a similar design local function getSectionData(text) local sections = {} text = "\n"..text.."\n== " while true do local section,content = string.match(text,"\n==%s*([^=]-)%s*==\n(.-)\n==[^=]") if not section then break end text = string.sub(text,string.find(text,content,1,true)+#content,-1) sections[#sections+1] = {name=section,content=content} end return sections end --This is a bloody mess of a mix of ideas, but it mostly works, so im dealing with it local function getUserMentions(text) --Returns a list of users, and if they were considered a "participant" or someone who was just mentioned local mentions = {} --Timestamp is %d%d:%d%d, %d%d? %w+ %d%d%d%d %(UTC%)) but we allow some (minor) leniancy for those who just slightly edit their dates so that it still picks up local timestampRegex = "((%d%d:%d%d, %d%d? %w+,? %d%d%d%d) %(UTC%))" local userRegex = "(%[%[:?User:([^|%]]+))" local userTalkRegex = "(%[%[:?User:([^|%]]+))" local userContribRegex = "(%[%[:?Special:Contributions/([^|%]]+))" for line in string.gmatch(text,"[^\n]+") do --Split by line and check all content on said line. This assumes all signatures never use newlines, which they should not be doing anyways. --Bar of entry for being labelled a "participant" is a valid timestamp along with their user/usertalk/contribs --Users can be noted as being both a participant and a mention during the data, so be smart in using this data local usersOnThisLine = {} for _,reg in next,{userRegex,userTalkRegex,userContribRegex} do local index = 1 while true do local targetText = string.sub(line,index,-1) local wholeText,identifier = string.match(targetText,reg) if not wholeText then break end if not string.find(identifier,"/") then --Avoid subpage nonsense mw.log("Found user on reg",reg,"name is",identifier) usersOnThisLine[string.find(targetText,reg)] = identifier end index = index + string.find(targetText,reg) + #wholeText end end --Start associating timestamps with users local index = 1 local pindex = {} --Lazy coding local participants = {} while true do local targetText = string.sub(line,index,-1) local wholeText,identifier = string.match(targetText,timestampRegex) if not wholeText then break end --Backtrack through the text for a mention local timestampLocation = string.find(targetText,identifier) local user,where for i = timestampLocation,1,-1 do user,where = usersOnThisLine[i],i if user then break end end if user then participants[#participants+1] = {user=user,when=identifier,participated=true} pindex[user] = true --else: be confused as hell end index = index + timestampLocation + #wholeText end local pings = {} for _,user in next,usersOnThisLine do if not pings[user] and not pindex[user] then --If they participated on a line, just ignore all pings pings[user] = true end end --Integrate the new data for user,_ in next,pings do mentions[#mentions+1] = {user=user,participated=false} end for _,userData in next,participants do mentions[#mentions+1] = userData end end return mentions end function p.main(frame) local page = frame.args[1] or frame.args.page assert(type(page)=="string","Invalid or no page provided") local success,text = pcall(Transcluder.get,page) assert(success,text) local sections = getSectionData(text) local tableContent = '{| class="wikitable sortable"\n! Section !! Initiator !! Last Comment !! Size !! Participants !! Mentions' for _,section in next,sections do local sanitisedName = string.gsub(string.gsub(section.name,"%[%[:?[^|]-|([^%]]-)]]","%1"),"%[%[:?([^%]]-)]]","%1") local wikilinkAnchor = "[[:"..page.."#"..sanitisedName.."|"..sanitisedName.."]]" local membersInText = getUserMentions(section.content) local uniqueParticipants = {} for _,userData in next,membersInText do if userData.participated and not table.find(uniqueParticipants,userData.user) then uniqueParticipants[#uniqueParticipants+1] = userData.user end end local now = getTime() local orderedComments = {} for _,userData in next,membersInText do if userData.participated then local when = getTime(userData.when) if now > when then --Ensure comment is from the past if #orderedComments == 0 then orderedComments[#orderedComments+1] = {user=userData.user,when=when} else for i = 1,#orderedComments do local comment = orderedComments[i] if when < comment.when then for i2 = #orderedComments+1,i,-1 do orderedComments[i2] = orderedComments[i2-1] end orderedComments[i] = {user=userData.user,when=when} break end if i == #orderedComments then orderedComments[#orderedComments+1] = {user=userData.user,when=when} --Reached the end, latest comment break end end end end end end mw.logObject(orderedComments) local firstComment,lastComment if #orderedComments == 0 then firstComment = "N/A" lastComment = "N/A" elseif #orderedComments == 1 then firstComment = formatDateDiff(now-orderedComments[1].when) .. " ago" .. "<br>" .. concatUsers({orderedComments[1].user}) lastComment = "N/A" else firstComment = formatDateDiff(now-orderedComments[1].when) .. " ago" .. "<br>" .. concatUsers({orderedComments[1].user}) lastComment = formatDateDiff(now-orderedComments[#orderedComments].when) .. " ago" .. "<br>" .. concatUsers({orderedComments[#orderedComments].user}) end local participants = #uniqueParticipants .. ": " .. concatUsers(uniqueParticipants) local mentions = "Could be calculated but I'm lazy" local sectionContent = "\n|-\n| "..wikilinkAnchor.." || "..firstComment.." || "..lastComment.." || "..#section.content.." || "..participants.." || "..mentions tableContent = tableContent .. sectionContent end return tableContent .. "\n|}" end function p.maindev(frame) local content = p.main(frame) return content .. "\n\n" .. frame:extensionTag("syntaxhighlight",content,{lang="html5"}) end p.getSectionData = getSectionData p.getUserMentions = getUserMentions return p
Summary:
Please note that all contributions to Stockhub may be edited, altered, or removed by other contributors. If you do not want your writing to be edited mercilessly, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource (see
Stockhub:Copyrights
for details).
Do not submit copyrighted work without permission!
Cancel
Editing help
(opens in new window)
Templates used on this page:
WP:ANI
(
edit
)
User talk:Aidan9382
(
edit
)
Module:Sandbox/Aidan9382/DiscussionOverview
(
edit
)
Module:Sandbox/Aidan9382/DiscussionOverview/doc
(
edit
)
Module:TNT
(
edit
)
Module:Transcluder
(
edit
)