Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env node
- /*
- 更新: 可以补充今天的工作项了
- 依赖node版本7.6以上
- 使用前:
- npm install -g nodemailer
- 将config里的XXXX替换成自己的信息
- 使用方法:
- 1. 将本文件放到项目根目录(注意不要add到git里,必要时可设置.gitignore)
- 2. 在项目根目录执行 node dailyreport.js
- */
- const nodemailer = require('nodemailer');
- const readline = require('readline');
- const config = {
- gitName : 'XXXX',
- mailTansport: {
- host : 'smtp.ym.163.com',
- secure: true,
- port : 994,
- auth : {
- user: 'XXXX@yuanxin2015.com',
- pass: 'XXXXX',
- },
- },
- mailSubject : `工作日报_XXXX_${generatorDate()}`,
- mailFrom : '"XXXX" <zhangyu@yuanxin2015.com>',
- mailTo : [
- // 'XXXXX@yuanxin2015.com',
- // 'zhangbm@yuanxin2015.com',
- 'XXXXX@yuanxin2015.com',
- ],
- }
- ;(async () => {
- let todayWorksArr = await getGitLog() || [];
- printArr(todayWorksArr, '\n今天的工作内容(Commits):');
- todayWorksArr = todayWorksArr.concat(await getWorkList('今天的补充'));
- printArr(todayWorksArr, '\n今天的工作内容:');
- let tomorrowWorksArr = await getWorkList('明天');
- printArr(tomorrowWorksArr, '\n明天的工作计划:');
- let HTML = generatorHTML(todayWorksArr, tomorrowWorksArr);
- if (await confirm('\n确认发送吗?(yes)')) {
- console.log('\n邮件发送中……');
- let log = await sendDailyPort(HTML);
- console.log(log);
- process.exit(0);
- }
- process.exit(0);
- })()
- .catch(err => {
- console.log(err);
- process.exit(0);
- });
- async function confirm (message) {
- const rl = readline.createInterface({
- input : process.stdin,
- output: process.stdout,
- prompt: '',
- });
- return new Promise((resolve, reject) => {
- rl.write(message + '\n');
- rl.on('line', line => {
- switch (line.trim().toLowerCase()) {
- case 'n':
- case 'no':
- resolve(false);
- rl.close();
- break;
- case '':
- case 'y':
- case 'yes':
- default:
- resolve(true);
- rl.close();
- break;
- }
- });
- });
- }
- function printArr (arr, msg) {
- if (msg) {console.log(msg);}
- if (arr && arr.length > 0) {
- return arr.forEach(item => console.log(' ' + item));
- } else {
- return console.log(' 什么也没有');
- }
- }
- //日期生成
- function generatorDate () {
- let date = new Date();
- return `${date.getFullYear()}${preZeroFill(date.getMonth() + 1, 2)}${preZeroFill(date.getDate(), 2)}`;
- }
- //补零函数
- function preZeroFill (num, size) {
- if (num >= Math.pow(10, size)) { // 如果num本身位数不小于size位
- return num.toString();
- } else {
- var _str = Array(size + 1).join('0') + num;
- return _str.slice(_str.length - size);
- }
- }
- //HTML生成
- function generatorHTML (gitLogArr, tomorrowWorksArr) {
- let todayHtmlContent = '';
- let todayHtmlTable = '';
- if (gitLogArr && gitLogArr.length > 0) {
- gitLogArr.forEach((item, index) => {
- todayHtmlContent += `
- <tr>
- <td>${index + 1}</td>
- <td>${item}</td>
- </tr>
- `;
- });
- todayHtmlTable = `
- <p style="color:#1F497D">今天工作内容:</p>
- <table class="table table-bordered">
- <tr style="border-bottom: solid 1pt #333;">
- <th style="width:70px">序号</th>
- <th>工作任务项</th>
- </tr>
- ${todayHtmlContent}
- </table>
- `;
- }
- let tomorrowHtmlContent = '';
- let tomorrowHtmlTable = '';
- if (tomorrowWorksArr && tomorrowWorksArr.length > 0) {
- tomorrowWorksArr.forEach((item, index) => {
- tomorrowHtmlContent += `
- <tr>
- <td>${index + 1}</td>
- <td>${item}</td>
- </tr>
- `;
- });
- tomorrowHtmlTable = `
- <p style="color:#1F497D">明天工作计划:</p>
- <table class="table table-bordered">
- <tr style="border-bottom: solid 1pt #333;">
- <th style="width:70px">序号</th>
- <th>工作任务项</th>
- </tr>
- ${tomorrowHtmlContent}
- </table>
- `;
- }
- // console.log(todayHtmlTable,tomorrowHtmlTable);
- let html = `
- <style>${renderStyle()}</style>
- ${todayHtmlTable}
- ${tomorrowHtmlTable}
- `;
- return html;
- }
- //获取gitLog
- async function getGitLog () {
- const cmdStr = `git log --since="6am" --author="${config.gitName}" --pretty=format:"%s" --no-merges`; // --since="6am"
- const exec = require('child_process').exec;
- return new Promise((resolve, reject) => {
- exec(cmdStr, function (err, stdout, stderr) {
- if (err) {
- reject(err);
- } else {
- if (stdout.toString().trim() === '') {resolve(null);}
- let gitLogArr = stdout.toString().trim().split('\n');
- resolve(gitLogArr);
- }
- });
- });
- }
- //邮件发送
- function sendDailyPort (HTML, callback) {
- return new Promise((resolve, reject) => {
- const transporter = nodemailer.createTransport(config.mailTansport);
- const mailOptions = {
- from : config.mailFrom, // sender address
- to : config.mailTo, // ["liuzhen@yuanxin2015.com","zhangbm@yuanxin2015.com","zhangyu@yuanxin2015.com"], // list of receivers
- subject: config.mailSubject, // Subject line
- html : HTML,
- };
- // 测试账号
- // transporter.verify(function (error, success) {
- // if (error) {
- // reject(error)
- // } else {
- // resolve('Server is ready to take our messages')
- // }
- // })
- // 发送邮件
- transporter.sendMail(mailOptions, function (error, info) {
- if (error) {
- callback && callback(error);
- reject(error);
- } else {
- callback && callback(null, info.response);
- resolve(info.response);
- }
- });
- });
- }
- function getWorkList (dayStr) {
- const rl = readline.createInterface({
- input : process.stdin,
- output: process.stdout,
- prompt: '',
- });
- return new Promise((resolve, reject) => {
- rl.question(`是否录入入${dayStr}工作计划?(yes)`, answer => {
- switch (answer.toLowerCase()) {
- case 'n':
- case 'no':
- case 'not':
- rl.write(`${dayStr}计划缺省\n`);
- resolve([]);
- break;
- case '':
- case 'y':
- case 'yes':
- default:
- let works = [];
- rl.write(`请录入${dayStr}工作计划,回车录入下一项,键入 end 以结束录入:\n`);
- rl.on('line', function (line) {
- switch (line.trim()) {
- case '':
- break;
- case 'end':
- resolve(works);
- rl.close();
- break;
- default:
- works.push(line);
- break;
- }
- });
- }
- });
- });
- }
- function renderStyle () {
- return `
- table {
- border-spacing: 0;
- border-collapse: collapse;
- }
- td,
- th {
- padding: 0;
- }
- table {
- background-color: transparent;
- }
- caption {
- padding-top: 8px;
- padding-bottom: 8px;
- color: #777;
- text-align: left;
- }
- th {
- text-align: left;
- }
- .table {
- width: 100%;
- max-width: 100%;
- margin-bottom: 20px;
- }
- .table > thead > tr > th,
- .table > tbody > tr > th,
- .table > tfoot > tr > th,
- .table > thead > tr > td,
- .table > tbody > tr > td,
- .table > tfoot > tr > td {
- padding: 8px;
- line-height: 1.42857143;
- vertical-align: top;
- border-top: 1px solid #ddd;
- }
- .table > thead > tr > th {
- vertical-align: bottom;
- border-bottom: 2px solid #ddd;
- }
- .table > caption + thead > tr:first-child > th,
- .table > colgroup + thead > tr:first-child > th,
- .table > thead:first-child > tr:first-child > th,
- .table > caption + thead > tr:first-child > td,
- .table > colgroup + thead > tr:first-child > td,
- .table > thead:first-child > tr:first-child > td {
- border-top: 0;
- }
- .table > tbody + tbody {
- border-top: 2px solid #ddd;
- }
- .table .table {
- background-color: #fff;
- }
- .table-condensed > thead > tr > th,
- .table-condensed > tbody > tr > th,
- .table-condensed > tfoot > tr > th,
- .table-condensed > thead > tr > td,
- .table-condensed > tbody > tr > td,
- .table-condensed > tfoot > tr > td {
- padding: 5px;
- }
- .table-bordered {
- border: 1px solid #ddd;
- }
- .table-bordered > thead > tr > th,
- .table-bordered > tbody > tr > th,
- .table-bordered > tfoot > tr > th,
- .table-bordered > thead > tr > td,
- .table-bordered > tbody > tr > td,
- .table-bordered > tfoot > tr > td {
- border: 1px solid #ddd;
- }
- .table-bordered > thead > tr > th,
- .table-bordered > thead > tr > td {
- border-bottom-width: 2px;
- }
- .table-striped > tbody > tr:nth-of-type(odd) {
- background-color: #f9f9f9;
- }
- .table-hover > tbody > tr:hover {
- background-color: #f5f5f5;
- }
- table col[class*="col-"] {
- position: static;
- display: table-column;
- float: none;
- }
- table td[class*="col-"],
- table th[class*="col-"] {
- position: static;
- display: table-cell;
- float: none;
- }
- .table > thead > tr > td.active,
- .table > tbody > tr > td.active,
- .table > tfoot > tr > td.active,
- .table > thead > tr > th.active,
- .table > tbody > tr > th.active,
- .table > tfoot > tr > th.active,
- .table > thead > tr.active > td,
- .table > tbody > tr.active > td,
- .table > tfoot > tr.active > td,
- .table > thead > tr.active > th,
- .table > tbody > tr.active > th,
- .table > tfoot > tr.active > th {
- background-color: #f5f5f5;
- }
- .table-hover > tbody > tr > td.active:hover,
- .table-hover > tbody > tr > th.active:hover,
- .table-hover > tbody > tr.active:hover > td,
- .table-hover > tbody > tr:hover > .active,
- .table-hover > tbody > tr.active:hover > th {
- background-color: #e8e8e8;
- }
- .table > thead > tr > td.success,
- .table > tbody > tr > td.success,
- .table > tfoot > tr > td.success,
- .table > thead > tr > th.success,
- .table > tbody > tr > th.success,
- .table > tfoot > tr > th.success,
- .table > thead > tr.success > td,
- .table > tbody > tr.success > td,
- .table > tfoot > tr.success > td,
- .table > thead > tr.success > th,
- .table > tbody > tr.success > th,
- .table > tfoot > tr.success > th {
- background-color: #dff0d8;
- }
- .table-hover > tbody > tr > td.success:hover,
- .table-hover > tbody > tr > th.success:hover,
- .table-hover > tbody > tr.success:hover > td,
- .table-hover > tbody > tr:hover > .success,
- .table-hover > tbody > tr.success:hover > th {
- background-color: #d0e9c6;
- }
- .table > thead > tr > td.info,
- .table > tbody > tr > td.info,
- .table > tfoot > tr > td.info,
- .table > thead > tr > th.info,
- .table > tbody > tr > th.info,
- .table > tfoot > tr > th.info,
- .table > thead > tr.info > td,
- .table > tbody > tr.info > td,
- .table > tfoot > tr.info > td,
- .table > thead > tr.info > th,
- .table > tbody > tr.info > th,
- .table > tfoot > tr.info > th {
- background-color: #d9edf7;
- }
- .table-hover > tbody > tr > td.info:hover,
- .table-hover > tbody > tr > th.info:hover,
- .table-hover > tbody > tr.info:hover > td,
- .table-hover > tbody > tr:hover > .info,
- .table-hover > tbody > tr.info:hover > th {
- background-color: #c4e3f3;
- }
- .table > thead > tr > td.warning,
- .table > tbody > tr > td.warning,
- .table > tfoot > tr > td.warning,
- .table > thead > tr > th.warning,
- .table > tbody > tr > th.warning,
- .table > tfoot > tr > th.warning,
- .table > thead > tr.warning > td,
- .table > tbody > tr.warning > td,
- .table > tfoot > tr.warning > td,
- .table > thead > tr.warning > th,
- .table > tbody > tr.warning > th,
- .table > tfoot > tr.warning > th {
- background-color: #fcf8e3;
- }
- .table-hover > tbody > tr > td.warning:hover,
- .table-hover > tbody > tr > th.warning:hover,
- .table-hover > tbody > tr.warning:hover > td,
- .table-hover > tbody > tr:hover > .warning,
- .table-hover > tbody > tr.warning:hover > th {
- background-color: #faf2cc;
- }
- .table > thead > tr > td.danger,
- .table > tbody > tr > td.danger,
- .table > tfoot > tr > td.danger,
- .table > thead > tr > th.danger,
- .table > tbody > tr > th.danger,
- .table > tfoot > tr > th.danger,
- .table > thead > tr.danger > td,
- .table > tbody > tr.danger > td,
- .table > tfoot > tr.danger > td,
- .table > thead > tr.danger > th,
- .table > tbody > tr.danger > th,
- .table > tfoot > tr.danger > th {
- background-color: #f2dede;
- }
- .table-hover > tbody > tr > td.danger:hover,
- .table-hover > tbody > tr > th.danger:hover,
- .table-hover > tbody > tr.danger:hover > td,
- .table-hover > tbody > tr:hover > .danger,
- .table-hover > tbody > tr.danger:hover > th {
- background-color: #ebcccc;
- }
- .table-responsive {
- min-height: .01%;
- overflow-x: auto;
- }
- `;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement