[Node tool] uses node. js to import the list of bugs on Bugzilla to one of the online versions of the Excel table (server side)

Source: Internet
Author: User

I've written a CLI tool that uses node. js to import a bug list from Bugzilla to an Excel table, but with a few points in mind, you always feel like you need to do something else.

    1. The interface was rough, and I was using it in Git bash under Vscode, and it looked good. If it is used under CMD, you can't bear to look straight.
    2. Need to start with a command, URL address also need to add double quotation marks, the experience is not good.
    3. Need to install NODEJS environment yourself

So I made this tool into an online version, just copy the URL, click Start, fool operation, multi-person use.

1 varExpress = require (' Express ');2 varBodyparser = require (' Body-parser '));3 varChildprocess = require (' child_process '));4 varFS = require (' FS ');5 6Const MAXTASK = 10;7Const PORT = 1024;8 9 varApp =Express ();Ten  OneApp.use (express.static (' public '))); A  -App.get ("/",function(req, res) { -Console.log ("[New Visitors]:" + req.ip.replace (/[^\d\.) /g, "")); theRes.sendfile ("./public/index.html"); -});

Load the module first, define the port and the maximum number of simultaneous runs (the server that downloads the bug can hold up, Bugzilla server can't handle it, and the task will slow down the normal use of a colleague).

Define an instance of express, set the static file directory.

Set the home page.

1 var New Array (); 2 App.use (Bodyparser.json ());

Define the task list because the API's data format is JSON, so add a middleware parsing data

/* tasks = [{    fingerprint:12345678,    starttime:123456,    savename: ' test.xlsx '    child:child_process ,    status: [Error|running|done],    reason: "",    total:245,    done:34}]* /

This is the data structure of the task list

App.post ('/start ',function(req, res) {varFROMIP = Req.ip.replace (/[^\d\.) /g, ""); if(Getrunningnum () > (MaxTask-1) {Res.json ({result:"Fail", Reason: "Maxtask", maxtask:maxtask}); return; }    varURL =Req.body.taskURL; varFingerprint =Req.body.fingerprint; varindex =Gettaskindex (fingerprint); if(Index! =-1) {        if(Tasks[index].status = = "Running"{Res.json ({result:"Fail", Reason: "Running" }); return; } Else{tasks.splice (index,1);        Deleteexcel (fingerprint); }    }    varChild = Childprocess.fork ("./transport.js", [url, fingerprint, FROMIP]); Console.log ("[New Task]: from IP" +fromip) Tasks.push ({fingerprint:fingerprint, child:child, Status:"Running", StartTime: (NewDate ()). GetTime ()}); Res.json ({result:"Success", Reason: "" }); Child.on (' Message ',function(msg) {varID =Gettaskindex (Msg.fingerprint); if(id! =-1) {Tasks[id].status=Msg.status; Tasks[id].reason=Msg.reason; Tasks[id].total=Msg.total; Tasks[id].done=Msg.done; Tasks[id].savename=Msg.savename; }    });});

Receive a task request API. Determine whether the maximum number of tasks is reached, and then determine if the task list already has a task in the current browser based on fingerprint. If there is, and is running, an error is returned. If the task is complete, delete it from the task list.

Start a child process to download the bug information and add the task to the Task list. Listens for messages from child processes, updating the status of the task list in real time.

1 function Gettaskindex (fingerprint) {2      for (var in tasks) {3         if (Tasks[i].fingerprint = = fingerprint) 4             return i; 5     }6     return -1; 7 }

Determine if a task is in the task list according to fingerprint

function (req, res) {    var fingerprint = req.query.fingerprint;     var i = gettaskindex (fingerprint);     if (I! =-1) {        Res.json ({status:tasks[i].status, Reason:tasks[i].reason, Total:tasks[i].total, Done:tasks[i]. Done});     Else {        "error", Reason: "Noprocess" });}    )

Get the status API for the current task

function (req, res) {    Res.json ({running:getrunningnum (), max:maxtask});})
function Getrunningnum () {    var num = 0;      for (var in tasks) {        if (tasks[i].status = = "Running")            num ++;    }     return num;}

Get the total number of tasks API

App.get ("/download",function(req, res) {varFingerprint =Req.query.fingerprint; varFiles = Fs.readdirsync (' Excel '); varSavename = "Result.xlsx"; varindex =Gettaskindex (fingerprint); if(Index! =-1) Savename=Tasks[index].savename; if(Files.indexof (fingerprint + ". xlsx")! =-1) {Res.type ("Application/binary"); Res.download ("excel/" + fingerprint + ". xlsx", Savename); } Else{Res.json ({status:"Fail" }); }})

Download the Excel Results API

var function () {    console.log (' Bug to Excel Web site start at ' + (new  Date). toLocaleString ());});

Start the server

SetInterval (Cleartask, 1 * 60 * 60);functionCleartask () {varCurrent = (NewDate ()). GetTime ();  for(varIinchtasks) {        if(parseint (Current-tasks[i].starttime)/$) > 1 * 60 * 60) {deleteexcel (tasks[i].fingerprint); Tasks.splice (i,1); }    }}functionDeleteexcel (fingerprint) {varFile = "excel/" + fingerprint + ". xlsx"; Fs.exists (file,function(exists) {if(exists) {fs.unlink (file,function(err) {if(Err) {Console.log ("Delete" + file + "failed.");        }            }); }    })}

Every one hours to determine whether the task is out of date, and indeed expires, delete the Excel file and move out of the task list.

The server that provides the static files and APIs is the above. Next look at the child process is if you go to download the bug information and generate Excel table. There is also a status update to the parent process.

The code to download the bug information is actually similar to the previous one in the CLI. But one of the most important changes is that the CLI tool is a bug to fetch information, so the burden on the server, when the bug has hundreds of, and the server connection often error.

Therefore, in the online version of this change to every 200 bugs to send a request. This greatly reduces the number of connections, but also makes a lot faster. Makes it possible to support multiple tasks at the same time.

Please refer to the CLI for most of the code. This is only the section that downloads the bug information and updates the status of the task.

varSplitlength = 200;. Then (function(bugs) {varSplitbugs =NewArray ();  Do{Splitbugs.push (Bugs.splice (0, splitlength)); }     while(Bugs.length > 0)    varDone = 0; returnPromise.all (Splitbugs.map (function(Eachgroup, index) {varSplitpromise =Getlongformat (Eachgroup); Splitpromise.then (function() { done+=eachgroup.length; Msg.done=Done ;        Process.send (msg); })        returnsplitpromise; }))})

After getting the array of bug IDs, divide the array every 200

functionGetlongformat (bugs) {varPostData = Bugs.join ("&") + "&ctype=xml&excludefield=attachmentdata"; returnPostfunc (Bugurl, PostData,function(URL, data) {var$ =cheerio.load (data); varXmllists = $ ("Bugzilla bug"); varBuglists =NewArray (); Xmllists.each (function(key) {varOnebug =Xmllists.eq (key); varOneinfo =NewObject (); Oneinfo.id= Onebug.children ("bug_id"). text (); Oneinfo.url= Bugurl + "? id=" +oneinfo.id; Oneinfo.summary= Onebug.children ("Short_desc"). text (); Oneinfo.reporter= Onebug.children ("reporter"). text (); Oneinfo.product= Onebug.children ("Product"). text (); Oneinfo.component= Onebug.children ("Component"). text (); Oneinfo.version= Onebug.children ("Version"). text (); Oneinfo.status= Onebug.children ("Bug_status"). text (); Oneinfo.priority= Onebug.children ("Priority"). text (); Oneinfo.security= Onebug.children ("bug_security"). text (); Oneinfo.assign= Onebug.children ("assigned_to"). text (); Oneinfo.comment=NewArray (); varComments = Onebug.children ("Long_desc"); Comments.each (function(key) {varwho = Comments.eq (key). Find (the "who"). text (); varwhen = Comments.eq (key). Find ("Bug_when"). text (); when= When.replace (/([^\s]+) \s.*$/g, "$"); vardesc = Comments.eq (key). Find ("TheText"). text (); if(key = = 0 && who = =oneinfo.reporter) {oneinfo.detail=desc; return true; } oneInfo.comment.push ({' Who ': Who, ' when ': when, ' desc ': desc});        }) Buglists.push (Oneinfo); }) Msg.done=buglists.length;        Process.send (msg); returnbuglists; })}

The 200 bug IDs are appended to the POST request data, and the resulting data is the XML format for all bugs, parsing each XML to get each bug information. Please refer to the CLI for writing to the Excel section

Get the Excel table

[Node tool] uses node. js to import the list of bugs on Bugzilla to one of the online versions of the Excel table (server side)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.