module(..., package.seeall) -- Load libraries require("controllerfunctions") require("format") -- Set variables local newrecordtxt = "[New]" local anytxt = "Any" local bugreportreceiver = "bugs@alpinelinux.org" local descr = { labels = { ['category'] = "Category", ['severity'] = "Severity", ['priority'] = "Priority", ['class'] = "Class", ['state'] = "State", ['skipclosed'] = "Skip/Hide closed", ['text'] = "Text in single-line fields", ['multitext'] = "Text in multi-line fields", ['responsible'] = "Responsible", ['originator'] = "Originator", ['release'] = "Alpine release", ['environment']="Environment", ['description']="Description", ['howtorepeat']="How-to-repeat this bug", ['fix']="Fix", ['synopsis']="One-line description*", ['from']="Your e-mail address*", ['reporter_name']="Your full name", ['reporter_id']="Your ID (Submitter ID)", ['reporter_org']="Your organization name", header = { ['received'] = "Received", ['to'] = "To", ['from'] = "From", ['date'] = "Date", ['message_id'] = "Message ID", ['subject'] = "Subject", ['return_path'] = "Return path", }, sfields = { ['number'] = "Number", ['class'] = "Class", ['responsible'] = "Responsible", ['category'] = "Category", ['priority'] = "Priority", ['confidential'] = "Confidential", ['originator'] = "Originator", ['severity'] = "Severity", ['keywords'] = "Keywords", ['arrival_date'] = "Arrival date", ['quarter'] = "Quarter", ['synopsis'] = "Synopsis", ['notify_list'] = "Notify list", ['submitter_id'] = "Submitter id", ['date_required'] = "Date required", ['release'] = "Release", ['last_modified'] = "Last modified", ['closed_date'] = "Closed date", ['state'] = "State", }, mfields = { ['environment'] = "Environment", ['release_note'] = "Release note", ['audit_trail'] = "Audit trail", ['howtorepeat'] = "How to repeat", ['organization'] = "Organization", ['fix'] = "Fix", ['unformatted'] = "Unformatted", }, }, audit_trail = { ['Responsible-Changed-From-To'] = "Responsible Changed", ['State-Changed-From-To'] = "State Changed", ['From'] = "Reply via E-mail", }, maildescriptions = { ['from'] = "From: ", ['reporter_id'] = ">Submitter-Id: ", ['xxx'] = ">Notify-List: ", ['originator'] = ">Originator: ", ['reporter_org'] = ">Organization: ", ['synopsis'] = ">Synopsis: ", ['xxx'] = ">Confidential: ", ['severity'] = ">Severity: ", ['priority'] = ">Priority: ", ['category'] = ">Category: ", ['class'] = ">Class: ", ['release'] = ">Release: ", ['environment'] = ">Environment: ", ['description'] = ">Description: ", ['howtorepeat'] = ">How-To-Repeat:", ['fix'] = ">Fix: ", }, } -- ################################################################################ -- PUBLIC FUNCTIONS default_action = "status" function status(self) return self.model.getstatus() end function listdatabases(self) return self.model.list_databases() end function listdatabasefiles(self) return self.model.list_database_files(self.clientdata.database) end function editdatabsefile(self) return controllerfunctions.handle_form(self, function() return self.model.read_database_file(self.clientdata.filename) end, self.model.update_database_file, self.clientdata, "Save", "Edit File", "File Saved") end function listconfigfiles(self) return self.model.list_config_files() end function editconfigfile(self) return controllerfunctions.handle_form(self, function() return self.model.read_config_file(self.clientdata.filename) end, self.model.update_config_file, self.clientdata, "Save", "Edit File", "File Saved") end function expert(self) local url = self.conf.script .. self.conf.prefix .. self.conf.controller local status=self.model.getstatus() local filedetailsresult, file = self.model:get_filedetails() -- Add buttons file.cmdsave = cfe ({ name="cmdsave", label="Apply settings", value="Apply", type="submit", }) return ( { option={ script=self.conf.script, prefix=self.conf.prefix, controller = self.conf.controller, action = "update", extra = "" }, status = status, file = file, modifications = modifications, url = url, } ) end function edit(self) -- Save changes local modifications = self.clientdata.filecontent or "" local cmdresult, cmdresultmsg if ( self.clientdata.cmdsave ) then cmdresult, cmdresultmsg = self.model:update_filecontent(modifications,self.clientdata.name) end local status = self.model:getstatus(self) local filedetailsresult, file = self.model:get_filedetails(self.clientdata.name) if not (filedetailsresult) then redirect(self, "status") end -- Add a cmd button to the view file.cmdsave = cfe({ name="cmdsave", label="Save/Apply above settings", value="Save", type="submit", }) if (cmdresult) then file.cmdsave.descr="* Changes has been saved!" end return { option={ script=self.conf.script, prefix=self.conf.prefix, controller = self.conf.controller, action = "edit", extra = "", }, modifications = modifications, file = file, status = status, } end --]] function query(self) local query = {} query.pr = cfe({ name="pr", label="Search string", }) query.pr_cmd = cfe({ name="pr_cmd", label=" ", type="submit", value="Submit", }) local tags = { "category", "severity", "priority", "class", "state", } for k,val in pairs(tags) do query[val] = cfe({ name=val, label=(descr.labels[val] or val), value=anytxt, type="select", option=self.model:get_select_opt(val), }) table.insert(query[val].option, 1, anytxt) -- If there is only a limited amount records, then present as radio buttons. if (#query[val].option < 6) then query[val].type="radio" end end local val = "responsible" query[val] = cfe({ name=val, label=(descr.labels[val] or val), value=anytxt, type="select", option=self.model:list_responsible(), }) table.insert(query[val].option, 1, anytxt) local tags = { "skipclosed", "text", "multitext", } for k,val in pairs(tags) do query[val] = cfe({ name=val, label=(descr.labels[val] or val), option=self.model:get_select_opt(val), }) end -- Show 'skipclosed' as a checkbox instead query.skipclosed.type="checkbox" query.skipclosed.checked="Yes" query.advanced_cmd = cfe({ name="advanced_cmd", label=" ", type="submit", value="Submit advanced query", }) -- Assume connection is down if you get no reply from it (disable buttons) if not (query['severity']['option']) or (#query['severity']['option'] < 2) then query.advanced_cmd.disabled="yes" query.advanced_cmd.errtxt="Lost connection to the server!" query.pr_cmd.disabled=query.advanced_cmd.disabled query.pr_cmd.errtxt=query.advanced_cmd.errtxt end return { option={ script=self.conf.script, prefix=self.conf.prefix, controller = self.conf.controller, action = "edit", extra = "", }, query = query, } end --------------------------------------------------------------------------- function summary(self) -- parse the search criterias - select boxes local action = "Query" local s = {} local invalid = nil if self.clientdata.pr then s["synopsis"] = self.model.validate_textfield(self.clientdata.pr) else for i, f in ipairs({"class", "category", "severity", "priority", "state", "responsible"}) do s[f] = self.model:validate_field(self.clientdata[f], f) end -- parse the search criterias - input boxes for i,f in ipairs({"text", "multitext", "originator"}) do s[f] = self.model.validate_textfield(self.clientdata[f] or "") -- replace this with ajax stuff? if action == "Query" and s[f] == nil then self.model:set_invalid_field(f) invalid = true end -- if field is blank, then ignore it if action == "Query" and s[f] == "" then s[f] = nil end end end -- we have found atleast one invalid field. reset the action if invalid then action = nil end if (self.clientdata.skipclosed) then s["skip-closed"] = "" else s["skip-closed"] = nil end -- Set the search criterias self.model:set_search_criteria(s) local summary = self.model:summary() --[[ -- Hide unwanted records local modsummary = {} for k,v in pairs(orgsummary) do if not ((orgsummary[k]['state'] == "closed") and ((orgsummary[k]['category'] == "test") or (orgsummary[k]['category'] == "spam"))) then table.insert(modsummary, v) end end summary = modsummary --]] return { option={ script=self.conf.script, prefix=self.conf.prefix, controller = self.conf.controller, action = "edit", extra = "", }, summary = summary, } end ----------------------------------------------------------------------- function queryresult(self) local query = {} local pr_id = self.clientdata.pr if (tonumber(pr_id)) then query.header, query.sfields, query.mfields = self.model:read_pr(pr_id) else return summary(self) end local myform = query.header for k,v in pairs(myform) do myform[k] = cfe({ name=k, label=descr.labels.header[k] or k, value=string.gsub(myform[k], "\"", ""), }) end local myform = query.sfields for k,v in pairs(myform) do myform[k] = cfe({ name=k, label=descr.labels.sfields[k] or k, value=string.gsub(myform[k], "\"", ""), }) end local myform = query.mfields for k,v in pairs(myform) do myform[k] = cfe({ name=k, label=descr.labels.mfields[k] or k, value=string.gsub(myform[k], "\"", ""), }) end local audit_trail_table = {} local checkstring = "" local checkstring2 = 0 table.insert(audit_trail_table, cfe({class="", label=""})) local tags = { "organization", "environment", "description", "how_to_repeat", "fix", "release_note", } for k,val in pairs(tags) do query.mfields[val].type="longtext" end local tags = { "category", "severity", "priority", "class", "state", } for k,val in pairs(tags) do query.sfields[val] = cfe({ name=val, label=(descr.labels[val] or val), value=query.sfields[val].value, type="select", option=self.model:get_select_opt(val), }) -- If there is only a limited amount records, then present as radio buttons. if (#query.sfields[val].option < 6) then query.sfields[val].type="radio" end end for k,v in pairs(format.string_to_table(query.mfields.audit_trail.value, "\n")) do if (v == "") then checkstring2 = checkstring2 + 1 end if (checkstring2 == 99) then table.insert(audit_trail_table, cfe({class="Unknown", label=""})) checkstring = "" checkstring2 = 0 end for k1, v1 in pairs(descr.audit_trail) do if (string.match(v, "^".. string.gsub(k1, "-", "%%-"))) then table.insert(audit_trail_table, cfe({class=k1, label=v1})) checkstring = k1 checkstring2 = 0 break end end if (#audit_trail_table > 0) then table.insert(audit_trail_table[#audit_trail_table], string.match(v, "^.+")) --Strips empty lines end end query.mfields.audit_trail.option=audit_trail_table return { option={ script=self.conf.script, prefix=self.conf.prefix, controller = self.conf.controller, action = "edit", extra = "", }, query = query, } end -------------------------------------------------------------------------- function report(self) local reportform = {} local status = self.model:getstatus(self) local alltags = { "reporter_name", "from", "reporter_id", "reporter_org", "synopsis","severity","priority","category","class","release","environment", "description", "howtorepeat", "fix", } self.clientdata.reporter_id = "web-users" for k,val in pairs(alltags) do reportform[val] = cfe({ name=val, label=(descr.labels[val] or val), value=(self.clientdata[val] or ""), }) end local tags = { "category", "priority","severity","class" } for k,val in pairs(tags) do reportform[val] = cfe({ name=val, label=(descr.labels[val] or val), value=(self.clientdata[val] or ""), type="select", option=self.model:get_select_opt(val), }) -- If there is only a limited amount records, then present as radio buttons. if (#reportform[val].option < 6) then reportform[val].type="radio" else table.insert(reportform[val].option, 1, "") end end reportform.description.type="longtext" reportform.howtorepeat.type="longtext" reportform.fix.type="longtext" reportform.environment.type="longtext" reportform.release.value=status.alpinerelease.value or "" -- Add buttons reportform.submit = cfe ({ name="submit", label=" ", -- hack value="Submit", type="submit", }) -- Assume connection is down if you get no reply from it (disable buttons) if not (reportform['severity']['option']) or (#reportform['severity']['option'] == 0) then reportform.submit.disabled = "yes" reportform.submit.errtxt = "Lost connection to the server!" end if (self.clientdata.submit) then if not (self.clientdata.from) or (#self.clientdata.from == 0) then reportform.from.errtxt = "You need to enter a valid e-mail address" end if not (self.clientdata.synopsis) or (#self.clientdata.synopsis == 0) then reportform.synopsis.errtxt = "You need to enter a valid online-description" end if not (self.clientdata.severity) or (#self.clientdata.severity == 0) then reportform.severity.errtxt = "You need to choose one of these options" end if not (self.clientdata.priority) or (#self.clientdata.priority == 0) then reportform.priority.errtxt = "You need to choose one of these options" end if not (self.clientdata.category) or (#self.clientdata.category == 0) then reportform.category.errtxt = "You need to choose one of these options" end if not (self.clientdata.class) or (#self.clientdata.class == 0) then reportform.class.errtxt = "You need to choose one of these options" end local noerrorsexists for k,v in pairs(alltags) do noerrorsexists = false if (reportform[v]['errtxt']) then break end noerrorsexists = true end -- If we had no errors, then we proceed with creating/sending the bugreport if (noerrorsexists) then local bugreport = {} table.insert(bugreport, "To: " .. (bugreportreceiver or "")) if not (self.clientdata.reporter_name) or (#self.clientdata.reporter_name == 0) then self.clientdata.reporter_name = "unknown" end table.insert(bugreport, "From: " .. self.clientdata.reporter_name .. " <" .. (self.clientdata.from or "") .. ">") table.insert(bugreport, "Reply-To: " .. (self.clientdata.from or "")) table.insert(bugreport, "") for k,v in pairs({"reporter_id", "notify_list", "originator", "synopsis", "confidential", "severity", "priority", "category", "class", "release", }) do if (v) and (descr.maildescriptions[v]) and (self.clientdata[v]) then table.insert(bugreport, descr.maildescriptions[v] .. self.clientdata[v] ) end end table.insert(bugreport, descr.maildescriptions.environment .. "\n" .. (self.clientdata.environment or "") .."\n" ) table.insert(bugreport, descr.maildescriptions.howtorepeat .. "\n" .. (self.clientdata.howtorepeat or "") .."\n" ) table.insert(bugreport, descr.maildescriptions.fix .. "\n" .. (self.clientdata.fix or "") .."\n" ) local bugreportsuccess, bugreport = self.model:sendbug(bugreport) if (bugreportsuccess) then redirect(self, "reportsuccess") end reportform.submit.errtxt = "Something went wrong because the report could not be sent.\n" .. bugreport end end return { option={ script=self.conf.script, prefix=self.conf.prefix, controller = self.conf.controller, action = "edit", extra = "", }, reportform = reportform, } end function reportsuccess() -- Just show that the report was successfully sent. end function queryeditpr(self) local query = {} query.pr = cfe({ name="pr", label="Query a specific PR number:", }) query.pr_cmd = cfe({ name="pr_cmd", label="Submit the query", type="submit", value="Submit", }) return { option={ script=self.conf.script, prefix=self.conf.prefix, controller = self.conf.controller, action = "edit", extra = "", }, query = query, } end function editpr(self) local queryresult = queryresult(self) local query = queryresult.query query.cmdsave = cfe({ name="cmdsave", label="Save above changes", type="submit", disabled="yes", errtxt="This button doesn't work. Still don't know howto send this edited information into gnats.", value="Submit", }) return { option={ script=self.conf.script, prefix=self.conf.prefix, controller = self.conf.controller, action = "edit", extra = "", }, query = query, } end