11/* eslint-disable no-await-in-loop */
2+ import path from 'path' ;
23import EscPosEncoder from '@freedom_sky/esc-pos-encoder' ;
4+ import fs from 'fs-extra' ;
35import superagent from 'superagent' ;
46import { config } from '../config' ;
57import {
@@ -8,6 +10,7 @@ import {
810
911const post = ( url : string ) => superagent . post ( new URL ( url , config . server ) . toString ( ) ) . set ( 'Accept' , 'application/json' ) ;
1012const encoder = new EscPosEncoder ( ) ;
13+ const logger = new Logger ( 'balloon' ) ;
1114
1215const i18n = {
1316 zh : {
@@ -30,42 +33,72 @@ const i18n = {
3033 } ,
3134} ;
3235
36+ let template = [
37+ '#align center' ,
38+ '' ,
39+ '#bold true' ,
40+ '#size 2' ,
41+ '#receipt' ,
42+ '' ,
43+ '#id' ,
44+ '' ,
45+ '#bold false' ,
46+ '#size 1' ,
47+ '===============================' ,
48+ '' ,
49+ '#location' ,
50+ '#problem' ,
51+ '#color' ,
52+ '#comment' ,
53+ '' ,
54+ '#align center' ,
55+ '#bold true' ,
56+ '===============================' ,
57+ '' ,
58+ '#size 0' ,
59+ '#team' ,
60+ '#status' ,
61+ '#time' ,
62+ ] ;
63+ try {
64+ template = fs . readFileSync ( path . resolve ( process . cwd ( ) , 'balloon.template' ) , 'utf8' ) . split ( '\n' ) . map ( ( i ) => i . trim ( ) ) ;
65+ } catch ( e ) {
66+ logger . info ( 'Using builtin balloon template' ) ;
67+ }
68+
3369export const receiptBalloonText = (
3470 id : number , location : string , problem : string , color : string , comment : string , teamname : string , status : string , lang : 'zh' | 'en' = 'zh' ,
35- ) => encoder
36- . initialize ( )
37- . codepage ( 'cp936' )
38- . setPinterType ( config . balloonType ?? 80 ) // wrong typo in the library
39- . align ( 'center' )
40- . line ( '' )
41- . bold ( true )
42- . size ( 2 )
43- . line ( i18n [ lang ] . receipt )
44- . emptyLine ( 1 )
45- . line ( `ID: ${ String ( id ) . substring ( 0 , 8 ) } ` )
46- . emptyLine ( 1 )
47- . bold ( false )
48- . size ( 1 )
49- . line ( '===============================' )
50- . emptyLine ( 1 )
51- . oneLine ( i18n [ lang ] . location , location )
52- . oneLine ( i18n [ lang ] . problem , problem )
53- . oneLine ( i18n [ lang ] . color , color )
54- . oneLine ( i18n [ lang ] . comment , comment )
55- . emptyLine ( 1 )
56- . align ( 'center' )
57- . bold ( true )
58- . line ( '================================' )
59- . emptyLine ( 1 )
60- . size ( 0 )
61- . line ( `${ i18n [ lang ] . team } : ${ teamname } ` )
62- . line ( `${ i18n [ lang ] . status } :` )
63- . line ( `${ status } ` )
64- . emptyLine ( 1 )
65- . line ( 'Powered by hydro-dev/xcpc-tools' )
66- . emptyLine ( 2 )
67- . cut ( )
68- . encode ( ) ;
71+ ) => {
72+ let enc = encoder . initialize ( ) . codepage ( 'cp936' ) . setPinterType ( config . balloonType ?? 80 ) ;
73+ const commands = {
74+ align : ( align : 'center' | 'left' | 'right' ) => enc . align ( align ) ,
75+ emptyLine : ( lines : number ) => enc . emptyLine ( lines ) ,
76+ bold : ( bold : boolean ) => enc . bold ( bold ) ,
77+ size : ( size : number ) => enc . size ( size ) ,
78+ line : ( line : string ) => enc . line ( line ) ,
79+ oneLine : ( left : string , right : string ) => enc . oneLine ( left , right ) ,
80+ cut : ( ) => enc . cut ( ) ,
81+ id : ( ) => enc . line ( `ID: ${ String ( id ) . substring ( 0 , 8 ) } ` ) ,
82+ location : ( ) => enc . oneLine ( i18n [ lang ] . location , location ) ,
83+ problem : ( ) => enc . oneLine ( i18n [ lang ] . problem , problem ) ,
84+ color : ( ) => enc . oneLine ( i18n [ lang ] . color , color ) ,
85+ comment : ( ) => enc . oneLine ( i18n [ lang ] . comment , comment ) ,
86+ team : ( ) => enc . line ( `${ i18n [ lang ] . team } : ${ teamname } ` ) ,
87+ status : ( ) => enc . line ( `${ i18n [ lang ] . status } :\n${ status } ` ) ,
88+ time : ( ) => enc . line ( `Time: ${ new Date ( ) . toLocaleString ( ) } ` ) ,
89+ } ;
90+ for ( const line of template ) {
91+ if ( ! line . startsWith ( '#' ) ) enc = enc . line ( line ) ;
92+ const [ command , ...rawArgs ] = line . slice ( 1 ) . split ( ' ' ) ;
93+ const args = rawArgs . map ( ( arg ) => ( arg === 'true' ? true : arg === 'false' ? false : Number . isSafeInteger ( arg ) ? + arg : arg ) ) ;
94+ if ( commands [ command ] ) enc = commands [ command ] ( ...args ) ;
95+ }
96+ return enc
97+ . line ( 'Powered by hydro-dev/xcpc-tools' )
98+ . emptyLine ( 1 )
99+ . cut ( )
100+ . encode ( ) ;
101+ } ;
69102
70103export const plainBalloonText = (
71104 id : number , location : string , problem : string , color : string , comment : string , teamname : string , status : string , lang : 'zh' | 'en' = 'zh' ,
@@ -79,8 +112,6 @@ ${i18n[lang].color}: ${color}
79112${ i18n [ lang ] . comment } : ${ comment }
80113` ;
81114
82- const logger = new Logger ( 'balloon' ) ;
83-
84115let timer = null ;
85116let printer = null ;
86117
0 commit comments