Code Duplication    Length = 52-58 lines in 2 locations

app.js 2 locations

@@ 52-109 (lines=58) @@
49
var app = express();
50
51
// 查成绩API,通过GET传入用户名和密码
52
app.get('/grades/', function (req, res, next) {
53
    if (program.fulllog) {
54
        var start = new Date();
55
        console.log((timeStamp() + 'Started to query the grades: ').cyan + req.query.id.yellow);
56
    }
57
    access.login(req.query.id, req.query.pwd, res, function (headers, ires) {
58
        program.fulllog && console.log((timeStamp() + 'Successfully logged in.').green);
59
        var ret = {};
60
        var $ = cheerio.load(ires.text);
61
        ret.name = escaper.unescape($('.block1text').html()).match(/姓名:.+</)[0].replace('<', '').substring(3);
62
        ret.id = req.query.id;
63
64
        // 进入成绩页面
65
        superagent.get(base + $('li[title="我的成绩"] a').attr('href'))
66
            .set(headers)
67
            .end(function (err, iires) {
68
                if (err) {
69
                    console.log((timeStamp() + 'Failed to get grades page\n' + err.stack).red);
70
                    res.send({ error: '无法进入成绩页面' });
71
                    return next(err);
72
                }
73
                program.fulllog && console.log((timeStamp() + 'Successfully entered grades page.').green);
74
75
                $ = cheerio.load(iires.text);
76
77
                // 获取成绩列表
78
                let grades = {};
79
                let failed = {};
80
                $('#dataList').each(function (index) {
81
                    // cheerio没有实现jQuery的lt
82
                    if (index >= 2)
83
                        return;
84
                    $(this).find('tr[class!="theadCss"]').each(function() {
85
                        // 这段写得真是要吐血了
86
                        let subject = escaper.unescape($(this).find('td[align="left"]').eq(1).text());
87
                        if (subject) {
88
                            let score = $(this).find('font');
89
                            if (score.text())
90
                                grades[subject] = score.text();
91
                            if (score.css('color'))
92
                                failed[subject] = score.text();
93
                        }
94
                    });
95
                });
96
                ret.grades = grades;
97
                ret['subject-count'] = Object.getOwnPropertyNames(grades).length;
98
                ret.failed = failed;
99
                ret['failed-count'] = Object.getOwnPropertyNames(failed).length;
100
101
                // 完成所有工作后,登出
102
                access.logout(headers, res, function() {
103
                    // 第五步:返回JSON
104
                    res.send(JSON.stringify(ret));
105
                    program.fulllog && console.log((timeStamp() + 'Successfully logged out: ').green + req.query.id.yellow + (' (processed in ' + (new Date() - start) + 'ms)').green);
106
                });
107
            });
108
    });
109
});
110
111
// TODO: 对参数的正确性进行检查
112
@@ 114-165 (lines=52) @@
111
// TODO: 对参数的正确性进行检查
112
113
// 查考试API,通过GET传入用户名和密码
114
app.get('/exams/', function (req, res, next) {
115
    if (program.fulllog) {
116
        var start = new Date();
117
        console.log((timeStamp() + 'Started to query the exams: ').cyan + req.query.id.yellow);
118
    }
119
    access.login(req.query.id, req.query.pwd, res, function (headers, ires) {
120
        var ret = {};
121
        var $ = cheerio.load(ires.text);
122
        ret.name = escaper.unescape($('.block1text').html()).match(/姓名:.+</)[0].replace('<', '').substring(3);
123
        ret.id = req.query.id;
124
        
125
        superagent.post('http://csujwc.its.csu.edu.cn/jsxsd/xsks/xsksap_list')
126
            .set(headers)
127
            .type('form')
128
            .send({
129
                xqlbmc: '',
130
                xnxqid: '2016-2017-1',      //TODO: 添加别的选项,或者通过参数传入
131
                xqlb: ''
132
            })
133
            .end(function (err, iires) {
134
                if (err) {
135
                    console.log((timeStamp() + 'Failed to reach exams page\n' + err.stack).red);
136
                    res.send({ error: '获取成绩失败' });
137
                    return next(err);
138
                }
139
                program.fulllog && console.log((timeStamp() + 'Successfully entered exams page.').green);
140
141
                $ = cheerio.load(iires.text);
142
143
                let exams = [];
144
145
                $('#dataList tr').each(function (index) {
146
                    if (index === 0)
147
                        return;
148
                    let item = $(this).find('td');
149
                    let subject = {};
150
                    subject.subject = escaper.unescape(item.eq(3).text());
151
                    subject.time = escaper.unescape(item.eq(4).text());
152
                    subject.location = escaper.unescape(item.eq(5).text());
153
                    subject.seat = escaper.unescape(item.eq(6).text());
154
                    exams.push(subject);
155
                });
156
157
                ret.exams = exams;
158
159
                access.logout(headers, res, function() {
160
                    res.send(JSON.stringify(ret));
161
                    program.fulllog && console.log((timeStamp() + 'Successfully logged out: ').green + req.query.id.yellow + (' (processed in ' + (new Date() - start) + 'ms)').green);
162
                });
163
            });
164
    });
165
});
166
167
app.listen(port);
168
console.log((timeStamp() + 'The server is now running on port ' + port + '.').green);