Commit 6db6a70f authored by nanahira's avatar nanahira

get data from database..

parent b31fa4aa
Pipeline #3248 failed with stages
in 6 minutes and 53 seconds
...@@ -5864,6 +5864,11 @@ ...@@ -5864,6 +5864,11 @@
"resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
"integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A=="
}, },
"moment": {
"version": "2.29.1",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz",
"integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ=="
},
"ms": { "ms": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
......
import { Body, Controller, Get, Post, Query, Res } from '@nestjs/common'; import {
Body,
Controller,
Get,
Post,
Query,
Res,
Headers,
} from '@nestjs/common';
import { AppService, ScoreSheetData } from './app.service'; import { AppService, ScoreSheetData } from './app.service';
import { Response } from 'express'; import { Response } from 'express';
import {
CxcyReturnMessage,
CxcyReturnMessageLike,
} from './messages/CxcyReturnMessage';
@Controller() @Controller('api')
export class AppController { export class AppController {
constructor(private readonly appService: AppService) {} constructor(private readonly appService: AppService) {}
@Get('report.pdf') @Get('user/report.pdf')
async getPdf(@Query('data') dataRaw: string, @Res() res: Response) { async getPdf(
let data: any; @Headers('Authorization') userToken: string,
try { @Query('request_id') requestId: string,
data = JSON.parse(dataRaw); @Res()
} catch (e) { res: Response,
res.status(400).end({ message: 'bad JSON' }); ) {
if (!userToken) {
res
.status(401)
.json(new CxcyReturnMessage(requestId, 401, 'Empty user token.', null));
return; return;
} }
if (!data || !data.id || !data.name) { const data: CxcyReturnMessageLike<any> = await this.appService.getUserData(
res.status(400).end({ message: 'bad student data' }); userToken,
requestId,
);
if (!data.success) {
res.status(data.status_code || 500).json(data);
return;
}
if (!data.data || !data.data.user) {
res
.status(500)
.json(
new CxcyReturnMessage(requestId, 401, 'Some contents missing.', null),
);
return;
} }
const pdf = await this.appService.getPdf(data); const userData = data.data.user;
const pdf = await this.appService.getPdf(userData);
res.set({ res.set({
'Content-Type': 'application/pdf', 'Content-Type': 'application/pdf',
'Content-Disposition': `attachment; filename=${data.id}-${data.name}.pdf`, 'Content-Disposition': `attachment; filename=${userData.id}-${userData.name}.pdf`,
'Content-Length': pdf.length, 'Content-Length': pdf.length,
// prevent cache // prevent cache
......
...@@ -3,6 +3,11 @@ import { AppLogger } from './app.logger'; ...@@ -3,6 +3,11 @@ import { AppLogger } from './app.logger';
import mustache from 'mustache'; import mustache from 'mustache';
import * as fs from 'fs'; import * as fs from 'fs';
import mdToPdf from 'md-to-pdf'; import mdToPdf from 'md-to-pdf';
import axios from 'axios';
import {
CxcyReturnMessage,
CxcyReturnMessageLike,
} from './messages/CxcyReturnMessage';
export interface NameWise { export interface NameWise {
name: string; name: string;
...@@ -22,17 +27,45 @@ export interface ScoreSheetData { ...@@ -22,17 +27,45 @@ export interface ScoreSheetData {
@Injectable() @Injectable()
export class AppService { export class AppService {
template: string; template: string;
cxcyUrl: string;
constructor(private log: AppLogger) { constructor(private log: AppLogger) {
this.log.setContext('app'); this.log.setContext('app');
this.template = fs.readFileSync('./report.md.mustache', 'utf8'); this.template = fs.readFileSync('./report.md.mustache', 'utf8');
this.cxcyUrl = process.env.CXCY_URL || 'https://cxcy.momobako.com';
}
async getUserData(
userToken: string,
requestId: string,
): Promise<CxcyReturnMessageLike<any>> {
const url = `${this.cxcyUrl}/api/user/current`;
try {
const { data } = await axios.get(url, {
responseType: 'json',
params: { request_id: requestId },
headers: { Authorization: userToken },
validateStatus: () => true,
});
this.log.log(
`Got result from ${url} with ${userToken}: ${JSON.stringify(data)}`,
);
return data;
} catch (e) {
this.log.error(`Failed to request backend ${url}: ${e.toString()}`);
return new CxcyReturnMessage(
requestId,
500,
'backend request fail',
null,
);
}
} }
async getPdf(data: ScoreSheetData) { async getPdf(data: ScoreSheetData) {
this.log.log(data); this.log.log(`Rendering PDF with data ${JSON.stringify(data)}`);
const renderedMarkdownContent = mustache.render(this.template, data, null, { const renderedMarkdownContent = mustache.render(this.template, data, null, {
escape: (v) => v, escape: (v) => v,
}); });
this.log.log(renderedMarkdownContent);
const { content } = await mdToPdf({ content: renderedMarkdownContent }); const { content } = await mdToPdf({ content: renderedMarkdownContent });
return content; return content;
} }
......
import moment from 'moment';
export interface CxcyReturnMessageLike<T> {
success: boolean;
timestamp: number;
request_id: string;
status_code: number;
message: string;
data: T;
}
export class CxcyReturnMessage<T> implements CxcyReturnMessageLike<T> {
success: boolean;
timestamp: number;
constructor(
public request_id: string,
public status_code: number,
public message: string,
public data: T,
) {
this.success = status_code < 400;
this.timestamp = moment().unix();
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment