[node 工具] 用 Node.js 将 bugzilla 上的 bug 列表导入到 excel 表格在线版本之一(server 端)

之前写了个 用 Node.js 将 bugzilla 上的 bug 列表导入到 excel 表格里 的 cli 工具虽然可以用,但考虑到一下几点,总觉得需要再做点什么。

  1. 界面简陋,我那截图上是在 VSCode 下的 git bash 里使用的,看起来倒还好一些。如果是在 CMD 下使用,不忍直视。
  2. 需要使用命令的方式启动,URL 地址还需要添加双引号,体验不好。
  3. 需要自行安装 nodejs 环境

因此我将这个工具做成了在线的版本,只要复制个 URL,点击开始,傻瓜操作,多人使用。

 1 var express = require(‘express‘);
 2 var bodyParser = require(‘body-parser‘);
 3 var childProcess = require(‘child_process‘);
 4 var fs = require(‘fs‘);
 5
 6 const MaxTask = 10;
 7 const port = 1024;
 8
 9 var app = express();
10
11 app.use(express.static(‘public‘));
12
13 app.get("/", function(req, res) {
14     console.log("[New Visitors]: " + req.ip.replace(/[^\d\.]/g, ""));
15     res.sendfile("./public/index.html");
16 });

首先加载模块,定义端口和同时运行的最大数目任务(下载 bug 的 server 扛得住,bugzilla server扛不住,任务一多连同事的正常使用也会变慢 )。

定义一个 express 的实例,设置静态文件目录。

设置首页。

1 var tasks = new Array();
2 app.use(bodyParser.json());

定义任务列表,因为 api 的数据格式是 json ,所以添加一个中间件解析数据

/*tasks = [{
    fingerprint: 12345678,
    startTime: 123456,
    saveName: "test.xlsx"
    child: child_process,
    status: [error|running|done],
    reason: "",
    total: 245,
    done: 34
}]*/

这是任务列表的数据结构

app.post(‘/start‘, function(req, res) {
    var fromIP = req.ip.replace(/[^\d\.]/g, "");
    if (getRunningNum() > (MaxTask - 1)) {
        res.json({ result: "fail", reason: "maxTask", maxTask: MaxTask });
        return;
    }

    var url = req.body.taskURL;
    var fingerprint = req.body.fingerprint;
    var index = getTaskIndex(fingerprint);
    if (index != -1) {
        if (tasks[index].status == "running") {
            res.json({ result: "fail", reason: "running" });
            return;
        } else {
            tasks.splice(index, 1);
            deleteExcel(fingerprint);
        }
    }
    var child = childProcess.fork("./transport.js", [url, fingerprint, fromIP]);

    console.log("[New Task]: From IP " + fromIP)

    tasks.push({ fingerprint: fingerprint, child: child, status: "running", startTime: (new Date()).getTime() });

    res.json({ result: "success", reason: "" });

    child.on(‘message‘, function(msg) {
        var id = 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;
        }
    });
});

收到一个任务请求 API。先判断是否达到最大任务数目,再根据 fingerprint 判断任务列表里是否已经存在当前浏览器的一个任务。如果有,并且正在运行,就返回错误。如果任务已经完成,从任务列表里删除。

启动一个子进程去下载 bug 信息,并将任务添加到任务列表。监听子进程的消息,实时更新任务列表的状态。

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

根据 fingerprint 来判断一个任务是否有在任务列表里

app.get("/status", 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 {
        res.json({ status: "error", reason: "noProcess" });
    }
})

获得当前任务的状态 API

app.get("/taskNum", function(req, res) {
    res.json({ running: getRunningNum(), max: MaxTask });
})
function getRunningNum() {
    var num = 0;
    for (var i in tasks) {
        if (tasks[i].status == "running")
            num++;
    }
    return num;
}

获得任务总数 API

app.get("/download", function(req, res) {
    var fingerprint = req.query.fingerprint;
    var files = fs.readdirSync(‘excel‘);
    var saveName = "result.xlsx";
    var index = 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" });
    }
})

下载 excel 结果 API

var server = app.listen(port, function() {
    console.log(‘Bug To Excel web site start at ‘ + (new Date).toLocaleString());
});

启动 server

setInterval(clearTask, 1 * 60 * 60);

function clearTask() {
    var current = (new Date()).getTime();
    for (var i in tasks) {
        if (parseInt((current - tasks[i].startTime) / 1000) > 1 * 60 * 60) {
            deleteExcel(tasks[i].fingerprint);
            tasks.splice(i, 1);
        }
    }
}

function deleteExcel(fingerprint) {
    var file = "excel/" + fingerprint + ".xlsx";
    fs.exists(file, function(exists) {
        if (exists) {
            fs.unlink(file, function(err) {
                if (err) {
                    console.log("Delete " + file + " failed.");
                }
            });
        }
    })
}

每隔一个小时判断任务是否过期,果然过期,就删除 excel 文件和移出任务列表。



提供静态文件和 API 的 server 就是以上这样。接下来看子进程是如果去下载 bug 信息以及生成 excel 表格。同时也有将状态更新到父进程。

下载 bug 信息的代码,其实跟之前 cli 那篇差不多。但是有个最重要的改动是,cli 那个工具是一个一个 bug 去取信息的,这样对服务器的负担重,在 bug 有几百个的时候,和服务器的连接经常出错。

因此在在线版本这里改成每 200 个 bug 发送一次请求。这样就大大减少了连接数目,而且还使得速度快了很多。使得同时支持多个任务成为了可能。

大部分代码请参考 cli 那篇。这里只说分块下载 bug 信息的部分以及更新任务状态。

var splitLength = 200;

.then(function(bugs) {
    var splitBugs = new Array();
    do {
        splitBugs.push(bugs.splice(0, splitLength));
    }
    while (bugs.length > 0)

    var done = 0;

    return Promise.all(splitBugs.map(function(eachGroup, index) {
        var splitPromise = getLongFormat(eachGroup);

        splitPromise.then(function() {
            done += eachGroup.length;
            msg.done = done;
            process.send(msg);
        })

        return splitPromise;
    }))
})

在获得 bug id 的数组后,将数组每隔200个分出来

function getLongFormat(bugs) {
    var postData = bugs.join("&") + "&ctype=xml&excludefield=attachmentdata";
    return postFunc(bugUrl, postData, function(url, data) {
        var $ = cheerio.load(data);
        var xmlLists = $("bugzilla bug");
        var bugLists = new Array();
        xmlLists.each(function(key) {
            var oneBug = xmlLists.eq(key);
            var oneInfo = new Object();
            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 = new Array();
            var comments = oneBug.children("long_desc");
            comments.each(function(key) {
                var who = comments.eq(key).find("who").text();
                var when = comments.eq(key).find("bug_when").text();
                when = when.replace(/([^\s]+)\s.*$/g, "$1");
                var desc = 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);

        return bugLists;
    })
}

将 200 个 bug id 附在 post 请求数据里发送出去,得到的数据是所有 bug 的 xml 格式,解析每个 xml 得到每个 bug 信息。至于写入到 excel 部分,还请参考 cli 那篇

得到的 excel 表格

原文地址:https://www.cnblogs.com/liqingjht/p/8283430.html

时间: 2024-11-10 09:11:55

[node 工具] 用 Node.js 将 bugzilla 上的 bug 列表导入到 excel 表格在线版本之一(server 端)的相关文章

用Node.js 将bugzilla上的bug列表导入到excel表格里

公司用bugzilla管理产品bug,最近用Node.js做了个东西,方便能够把bug的相关信息导入到excel表格里,好做后续的管理分析. 直接贴代码,写上注释好了.转载请注明出处. var request = require("request") var cheerio = require("cheerio"); var Excel = require('exceljs'); var colors = require("colors"); v

PHP 和 JS 导入导出csv表格(上)

CSV简介 在开发后台管理系统的时候,几乎无可避免的会遇到需要导入导出Excel表格的需求.csv也是表格的一种,其中文名为"逗号分隔符文件".在Excel中打开如下图左边所示,在记事本打开如下图右边所示: 再看包含特殊字符的表格 与xls或xlsx 表格相类似,CSV文件也是用来表示二维表格.而不同的是: 1.CSV是一种纯文本文件,任何编辑器都能打开并读取它:xls(x)是专用的二进制文件,要用表格软件才能正常打开,否则乱码: 2.CSV的体积很小,比如上面的表格内容,csv只有几

【游戏开发】Excel表格批量转换成lua的转表工具

一.简介 在上篇博客<[游戏开发]Excel表格批量转换成CSV的小工具> 中,我们介绍了如何将策划提供的Excel表格转换为轻便的CSV文件供开发人员使用.实际在Unity开发中,很多游戏都是使用Lua语言进行开发的.如果要用Lua直接读取CSV文件的话,又要写个对应的CSV解析类,不方便的同时还会影响一些加载速度,牺牲游戏性能.因此我们可以直接将Excel表格转换为lua文件,这样就可以高效.方便地在Lua中使用策划配置的数据了.在本篇博客中,马三将会和大家一起,用C#语言实现一个Exce

Nodejs学习笔记(八)--- Node.js + Express 实现上传文件功能(felixge/node-formidable)

目录 前言 formidable简介 创建项目并安装formidable 实现上传功能 运行结果 部分疑惑解析 写在之后 前言 前面讲了一个构建网站的示例,这次在此基础上再说说web的常规功能----文件上传,示例以一个上传图片的功能为例子 上传功能命名用formidable实现,示例很简单! PS:最近比较忙,距上一次更新已经比较久了^_^! formidable简介 nodejs原生实现上传还是比较麻烦,有兴趣的自已去参考一下网上有网友写的代码 这里选择了formidable,也是githu

node.js安装后输入“node -v”提示&#39;node&#39; 不是内部或外部命令,也不是可运行的程序的解决方法

换个电脑,重新搭配环境的时候遇到的问题.node.js已经在官网进行下载安装了,但是VScode里面显示不是内部的命令,也不是可运行的程序 但是在cmd控制台还是能查到的 借助网上的方法进行了测试和调配并没有成功,路径我也进行了配置了,不知道是哪里的问题,先在这里凑合着用吧 ps:windows+r----<  输入cmd-------<打开控制台(此处可以使用命令) 网站上的方法: https://blog.csdn.net/KingJulien2/article/details/73302

node工具之nodemon

nodemon nodemon是一种工具,可以自动检测到目录中的文件更改时通过重新启动应用程序来调试基于node.js的应用程序. 安装 npm install -g nodemon //或 npm install --save-dev nodemon 使用 nodemon ./main.js // 启动node服务 nodemon ./main.js localhost 6677 // 在本地6677端口启动node服务 "start": "ts-node -r tscon

Node实现简单的表单+图片上传+路由

Node实现一个表单处理+图片上传功能,不是用express 1.使用formidable模块用于上传文件(图片)的处理.注意form表单要使用multipart/form-data属性. 2.使用chunk分段接收,原因是当接受了一小段,可能就给别人服务了.防止一个过大的表单阻塞了整个进程 3.上传上去的图片使用formidable自定义路径,用fs改名. 4.实现简单的路由. var http = require("http"); var querystring = require

node.js 操作excel 表格与XML文件常用的npm

在日常工作中会经常用到把一些excel表格文件转化为json,xml,js等格式的文件,下面就是我在日常中用到的这些npm. 1.node-xlsx: node-xlsx可以把excel文件转化为上面说所的几种文件格式,常用方式可以查看github的源码与实例:node-xlsx 在操作文件中直接引用 var xlsx = require("node-xlsx"); 读取excel var list = xlsx.parse("./excel/" + excelNa

简单使用grunt工具合并压缩js和css

前段时间因为项目中的报表写了一个Jquery插件,开源到github上,参考以往大神们写的插件的姿势,决定搞了像模像样一点.言归正传.前端工程师对这些工具:Node,bower,grunt,npm这些工具应该都很熟悉.今天就简单介绍一下grunt的用法. grunt的介绍及安装请看着:getting-started,中文文档,写的也比较详细. 一个完整grunt项目小包含以下模块或配置文件 npm:node的包管理器,管理(安装)相关插件 grunt-cli:执行grunt任务的工具,但是注意安