Code Duplication    Length = 71-85 lines in 2 locations

app.js 2 locations

@@ 75-159 (lines=85) @@
72
        res.status(404).send({ error: "参数不正确" });
73
        return;
74
    }
75
    if (fullLog) {
76
        var start = new Date();
77
        console.log(`${timeStamp()} Started to query the grades: `.cyan + req.query.id.yellow);
78
    }
79
    access.login(req.query.id, req.query.pwd, res, function (headers) {
80
        if (fullLog) {
81
            console.log(`${timeStamp()} Successfully logged in.`.green);
82
        }
83
84
        // 实际上xnxq01id为空的时候和GET这个URL的效果是一样的,都是查询所有学期
85
        superagent
86
            .post('http://csujwc.its.csu.edu.cn/jsxsd/kscj/yscjcx_list')
87
            .set(headers)
88
            .type('form')
89
            .send({
90
                xnxq01id: req.query.sem
91
            })
92
            .end(function (err, iires) {
93
                if (err) {
94
                    console.log(`${timeStamp()} Failed to get grades page\n${err.stack}`.red);
95
                    res.status(404).send({ error: '无法进入成绩页面' });
96
                    return next(err);
97
                }
98
                if (fullLog) {
99
                    console.log(`${timeStamp()} Successfully entered grades page.`.green);
100
                }
101
102
                let $ = cheerio.load(iires.text);
103
104
                let result = {
105
                    name: escaper.unescape($('#Top1_divLoginName').text().match(/\s.+\(/)[0].replace(/\s|\(/g, '')),
106
                    id: escaper.unescape($('#Top1_divLoginName').text().match(/\(.+\)/)[0].replace(/\(|\)/g, '')),
107
                    grades: {},
108
                    'subject-count': 0,
109
                    failed: {},
110
                    'failed-count': 0,
111
                };
112
113
                // 获取成绩列表
114
                $('#dataList tr').each(function (index) {
115
                    if (index === 0) {
116
                        return;
117
                    }
118
                    let element = $(this).find('td');
119
                    let title = escaper.unescape(element.eq(3).text().match(/].+$/)[0].substring(1));
120
121
                    let item = {
122
                        sem: escaper.unescape(element.eq(2).text()),
123
                        reg: escaper.unescape(element.eq(4).text()),
124
                        exam: escaper.unescape(element.eq(5).text()),
125
                        overall: escaper.unescape(element.eq(6).text())
126
                    };
127
                    if (req.query.details) {
128
                        item.id = escaper.unescape(element.eq(3).text().match(/\[.+\]/)[0].replace(/\[|\]/g, ''));
129
                        item.attr = escaper.unescape(element.eq(8).text());
130
                        item.genre = escaper.unescape(element.eq(9).text());
131
                        item.credit = escaper.unescape(element.eq(7).text());
132
                    }
133
134
                    // 如果有补考记录,则以最高分的为准
135
                    if (title in result.grades) {
136
                        // 暂不考虑NaN
137
                        if (item.overall < result.grades[title].overall) {
138
                            return;
139
                        }
140
                        if (!element.eq(6).css('color')) {
141
                            delete result.failed[title];
142
                        }
143
                    } else if (element.eq(6).css('color')) {
144
                        result.failed[title] = item;
145
                    }
146
147
                    result.grades[title] = item;
148
                });
149
150
                result['subject-count'] = Object.keys(result.grades).length;
151
                result['failed-count'] = Object.keys(result.failed).length;
152
153
                access.logout(headers, res, function() {
154
                    // 返回JSON
155
                    res.send(JSON.stringify(result));
156
                    if (fullLog) {
157
                        console.log(`${timeStamp()} Successfully logged out: `.green +
158
                            req.query.id.yellow +
159
                            ` (processed in ${new Date() - start} ms)`.green);
160
                    }
161
                });
162
            });
@@ 163-233 (lines=71) @@
160
                    }
161
                });
162
            });
163
    });
164
});
165
166
// 查考试API,通过GET传入用户名和密码
167
app.get(/^\/e(?:|xams)$/, function (req, res, next) {
168
    if (!req.query.id || !req.query.pwd || (req.query.sem && !(/^20\d{2}-20\d{2}-[1-2]$/).test(req.query.sem))) {
169
        res.status(404).send({ error: "参数不正确" });
170
        return;
171
    }
172
    if (fullLog) {
173
        var start = new Date();
174
        console.log(`${timeStamp()} Started to query the exams: `.cyan + req.query.id.yellow);
175
    }
176
    access.login(req.query.id, req.query.pwd, res, function (headers) {
177
        if (fullLog) {
178
            console.log(`${timeStamp()} Successfully logged in.`.green);
179
        }
180
181
        superagent
182
            .post('http://csujwc.its.csu.edu.cn/jsxsd/xsks/xsksap_list')
183
            .set(headers)
184
            .type('form')
185
            .send({
186
                xqlbmc: '',
187
                xnxqid: req.query.sem || getSem(),
188
                xqlb: ''
189
            })
190
            .end(function (err, iires) {
191
                if (err) {
192
                    console.log(`${timeStamp()} Failed to reach exams page\n${err.stack}`.red);
193
                    res.status(404).send({ error: '获取成绩失败' });
194
                    return next(err);
195
                }
196
                if (fullLog) {
197
                    console.log(`${timeStamp()} Successfully entered exams page.`.green);
198
                }
199
200
                let $ = cheerio.load(iires.text);
201
202
                let result = {
203
                    name: escaper.unescape($('#Top1_divLoginName').text().match(/\s.+\(/)[0].replace(/\s|\(/g, '')),
204
                    id: escaper.unescape($('#Top1_divLoginName').text().match(/\(.+\)/)[0].replace(/\(|\)/g, '')),
205
                    sem: req.query.sem || getSem(),
206
                    exams: {},
207
                    'exams-count': 0,
208
                };
209
210
                $('#dataList tr').each(function (index) {
211
                    if (index === 0) {
212
                        return;
213
                    }
214
                    let element = $(this).find('td');
215
                    let title = escaper.unescape(element.eq(3).text());
216
217
                    let item = {
218
                        time: escaper.unescape(element.eq(4).text()),
219
                        location: escaper.unescape(element.eq(5).text()),
220
                        seat: escaper.unescape(element.eq(6).text())
221
                    };
222
223
                    result.exams[title] = item;
224
                    result['exams-count']++;
225
                });
226
227
                access.logout(headers, res, function() {
228
                    res.send(JSON.stringify(result));
229
                    if (fullLog) {
230
                        console.log(`${timeStamp()} Successfully logged out: `.green +
231
                            req.query.id.yellow +
232
                            ` (processed in ${new Date() - start} ms)`.green);
233
                    }
234
                });
235
            });
236
    });