├── .gitattributes ├── .gitignore ├── Kconfig ├── LICENSE ├── Makefile ├── README.md ├── data ├── maps │ ├── navi_info.h │ ├── shahe_bike.h │ ├── shahe_walking.h │ ├── shahe_walking_busy.h │ ├── xtc_bike.h │ ├── xtc_walking.h │ └── xtc_walking_busy.h ├── src │ ├── course │ │ ├── 10500040 │ │ │ └── intro.txt │ │ ├── 31301024 │ │ │ └── intro.txt │ │ ├── 31302022 │ │ │ ├── 2010001001 │ │ │ │ ├── 2020211313 │ │ │ │ │ ├── 202206171250 │ │ │ │ │ │ ├── 2020212900 │ │ │ │ │ │ │ ├── 123.docx │ │ │ │ │ │ │ ├── FILE.ned │ │ │ │ │ │ │ ├── FILE.nef │ │ │ │ │ │ │ └── report_1.docx │ │ │ │ │ │ └── 2020212910 │ │ │ │ │ │ │ └── report_1.docx │ │ │ │ │ ├── homework.ned │ │ │ │ │ └── homework.nef │ │ │ │ └── res │ │ │ │ │ ├── FILE.ned │ │ │ │ │ ├── FILE.nef │ │ │ │ │ └── Intro.docx │ │ │ ├── exam.ned │ │ │ ├── exam.nef │ │ │ └── intro.txt │ │ ├── 31302060 │ │ │ └── intro.txt │ │ ├── 31302070 │ │ │ └── intro.txt │ │ ├── 31302120 │ │ │ └── intro.txt │ │ ├── 31302321 │ │ │ └── intro.txt │ │ ├── 31302470 │ │ │ └── intro.txt │ │ ├── 31312040 │ │ │ ├── exam.ned │ │ │ ├── exam.nef │ │ │ └── intro.txt │ │ ├── 31313041 │ │ │ ├── exam.ned │ │ │ ├── exam.nef │ │ │ └── intro.txt │ │ ├── 31321030 │ │ │ ├── exam.ned │ │ │ ├── exam.nef │ │ │ └── intro.txt │ │ ├── 33200081 │ │ │ └── intro.txt │ │ ├── 34110012 │ │ │ └── intro.txt │ │ ├── 34110021 │ │ │ └── intro.txt │ │ ├── 34110073 │ │ │ └── intro.txt │ │ ├── 34110092 │ │ │ └── intro.txt │ │ ├── 34110102 │ │ │ └── intro.txt │ │ ├── 38120010 │ │ │ ├── exam.ned │ │ │ ├── exam.nef │ │ │ └── intro.txt │ │ ├── courses.ned │ │ └── courses.nef │ ├── css │ │ ├── app.d1ad8af5.css │ │ └── chunk-vendors.0753abc9.css │ ├── favicon.ico │ ├── file │ │ ├── game-programmer-zh-cn.pdf.gz │ │ └── 屏幕截图 2022-06-13 131213.jpg │ ├── fonts │ │ ├── materialdesignicons-webfont.2e22fd77.eot │ │ ├── materialdesignicons-webfont.42483c73.woff │ │ ├── materialdesignicons-webfont.935d8e7a.woff2 │ │ └── materialdesignicons-webfont.9fcb655c.ttf │ ├── img │ │ ├── bg.ed3fd931.png │ │ ├── bg2.20dd4c41.png │ │ ├── item1.18a46c8b.png │ │ └── xitucheng.fb7ec5b3.png │ ├── index.html │ ├── js │ │ ├── app-legacy.903fce15.js │ │ ├── app-legacy.903fce15.js.map │ │ ├── app.22b64076.js │ │ ├── app.22b64076.js.map │ │ ├── chunk-vendors-legacy.4cf9307f.js │ │ ├── chunk-vendors-legacy.4cf9307f.js.map │ │ ├── chunk-vendors.79e03aa1.js │ │ └── chunk-vendors.79e03aa1.js.map │ ├── major │ │ ├── 80901.txt │ │ ├── majors.ned │ │ └── majors.nef │ ├── map │ │ ├── landmark.ned │ │ └── landmark.nef │ └── school │ │ ├── 313 │ │ └── intro.txt │ │ ├── classes.ned │ │ ├── classes.nef │ │ ├── schools.ned │ │ └── schools.nef ├── sys │ ├── database_test.ned │ ├── database_test.nef │ └── token │ │ ├── token.ned │ │ └── token.nef └── user │ ├── 0 │ └── 2010001005 │ │ ├── timetable.ned │ │ └── timetable.nef │ ├── 212 │ └── 0 │ │ └── 2010001007 │ │ ├── timetable.ned │ │ └── timetable.nef │ ├── 313 │ ├── 0 │ │ ├── 2010001001 │ │ │ ├── timetable.ned │ │ │ └── timetable.nef │ │ ├── 2010001003 │ │ │ ├── timetable.ned │ │ │ └── timetable.nef │ │ └── 2010001006 │ │ │ ├── timetable.ned │ │ │ └── timetable.nef │ ├── 2020211313 │ │ ├── event.ned │ │ └── event.nef │ ├── timetable.ned │ └── timetable.nef │ ├── 332 │ └── 0 │ │ └── 2010001004 │ │ ├── timetable.ned │ │ └── timetable.nef │ ├── 341 │ └── 0 │ │ └── 2010001002 │ │ ├── timetable.ned │ │ └── timetable.nef │ ├── 381 │ └── 0 │ │ └── 2010001005 │ │ ├── timetable.ned │ │ └── timetable.nef │ ├── users.ned │ └── users.nef ├── include ├── common.h ├── connect │ ├── HttpProtocal │ │ ├── HttpAdapter.h │ │ ├── HttpBase.h │ │ ├── HttpException.h │ │ ├── HttpManager.h │ │ ├── HttpProtocal.h │ │ ├── HttpRequest.h │ │ └── HttpResponse.h │ ├── Network │ │ ├── ManagerBase.h │ │ ├── ServerBase.h │ │ ├── ServerConfig.h │ │ ├── TAPManager.h │ │ ├── ThreadPool.h │ │ └── URLParser.h │ └── Timer │ │ ├── TimeLine.h │ │ ├── Timer.h │ │ ├── TimerConfig.h │ │ └── TimerManager.h ├── interfaces.h ├── libs │ ├── BalanceTree.h │ ├── BasicUtils.hpp │ ├── HashMap.hpp │ ├── Heap.hpp │ ├── NEDB.h │ ├── SimpleJson.hpp │ └── md5.h ├── router.conf ├── service │ ├── ClockSys.h │ ├── Event.h │ ├── NaviSys.h │ ├── TAPSystem.h │ └── User.h └── test │ └── define.h ├── lib └── libnedb.a ├── scripts ├── build.mk ├── colors.mk ├── config.mk ├── database.md ├── doc.md ├── intro.md └── mid-term repo.pptx ├── src ├── controller │ ├── ClassController.cpp │ ├── CourseController.cpp │ ├── EventController.cpp │ └── UserController.cpp ├── main.cpp ├── server │ ├── HttpProtocal │ │ ├── HttpAdapter.cpp │ │ ├── HttpBase.cpp │ │ ├── HttpException.cpp │ │ ├── HttpManager.cpp │ │ ├── HttpMessage.cpp │ │ └── HttpUtils.cpp │ ├── MD5 │ │ └── Md5.cpp │ ├── Network │ │ ├── ServerBase.cpp │ │ ├── TAPCenter.cpp │ │ ├── ThreadPool.cpp │ │ └── URLParser.cpp │ ├── TAPSystem.cpp │ └── Timer │ │ ├── TimeLine.cpp │ │ ├── Timer.cpp │ │ └── TimerManager.cpp ├── service │ ├── ClassServcie.cpp │ ├── ClockService.cpp │ ├── CourseService.cpp │ ├── EventService.cpp │ ├── FileService.cpp │ ├── NaviService.cpp │ ├── SignService.cpp │ ├── SqlService.cpp │ └── UserService.cpp └── test │ └── test.cpp ├── utils ├── favicon.ico ├── kconfig │ └── build │ │ ├── conf │ │ ├── lexer.lex.c │ │ ├── mconf │ │ ├── obj-conf │ │ ├── build │ │ │ ├── lexer.lex.d │ │ │ ├── lexer.lex.o │ │ │ ├── parser.tab.d │ │ │ └── parser.tab.o │ │ ├── conf.d │ │ ├── conf.o │ │ ├── confdata.d │ │ ├── confdata.o │ │ ├── expr.d │ │ ├── expr.o │ │ ├── preprocess.d │ │ ├── preprocess.o │ │ ├── symbol.d │ │ ├── symbol.o │ │ ├── util.d │ │ └── util.o │ │ ├── obj-mconf │ │ ├── build │ │ │ ├── lexer.lex.d │ │ │ ├── lexer.lex.o │ │ │ ├── parser.tab.d │ │ │ └── parser.tab.o │ │ ├── confdata.d │ │ ├── confdata.o │ │ ├── expr.d │ │ ├── expr.o │ │ ├── lxdialog │ │ │ ├── checklist.d │ │ │ ├── checklist.o │ │ │ ├── inputbox.d │ │ │ ├── inputbox.o │ │ │ ├── menubox.d │ │ │ ├── menubox.o │ │ │ ├── textbox.d │ │ │ ├── textbox.o │ │ │ ├── util.d │ │ │ ├── util.o │ │ │ ├── yesno.d │ │ │ └── yesno.o │ │ ├── mconf.d │ │ ├── mconf.o │ │ ├── preprocess.d │ │ ├── preprocess.o │ │ ├── symbol.d │ │ ├── symbol.o │ │ ├── util.d │ │ └── util.o │ │ ├── parser.output │ │ ├── parser.tab.c │ │ └── parser.tab.h ├── md5test.html ├── out ├── pic0.png ├── pic1.png ├── shaheM.png ├── shaheWalking.png ├── shahe_walking.tmx ├── xitucheng.tmx └── xtcM.png └── web └── old ├── index.css ├── index.html ├── main.js ├── schedule └── index.html ├── signin.html ├── signup.html ├── sql ├── help.html └── terminal.html ├── src ├── bg1.png ├── bg3.png ├── item1.jpg ├── item3.jpg └── item4.jpg └── user ├── index.css └── index.html /.gitattributes: -------------------------------------------------------------------------------- 1 | *.h linguist-language=C++ 2 | *.c linguist-language=C++ 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .server 2 | .vscode 3 | .config 4 | .config.old 5 | include/config 6 | include/generated 7 | nohup.out 8 | log 9 | .vscode-ctags 10 | build 11 | status.txt 12 | status.bk 13 | ttt 14 | ttt.cpp 15 | main-service 16 | log 17 | crash 18 | 19 | -------------------------------------------------------------------------------- /Kconfig: -------------------------------------------------------------------------------- 1 | mainmenu "Server Configuration Menu" 2 | 3 | config THREADS_MAXIMUM 4 | int "Set threads maximum (0 for auto)" 5 | default 0 6 | 7 | menu "Configure Network Arguments" 8 | choice 9 | prompt "Internet Protocol Version" 10 | default IPV4 11 | config IPV4 12 | bool "IPv4" 13 | config IPV6 14 | bool "IPv6" 15 | endchoice 16 | 17 | menu "Configure time out for BLOCK recv" 18 | config RECV_SECOND 19 | int "Second(s)" 20 | default 0 21 | config RECV_MICROSECOND 22 | int "Microsecond(us)" 23 | default 500000 24 | endmenu 25 | 26 | menu "Configure time out for BLOCK send" 27 | config SEND_SECOND 28 | int "Second(s)" 29 | default 0 30 | config SEND_MICROSECOND 31 | int "Microsecond(us)" 32 | default 500000 33 | endmenu 34 | 35 | menu "Configure transmission buffer" 36 | config BUFF_INIT_SIZE 37 | int "Initial Capacity of buffer" 38 | default 4096 39 | config BUFF_MAX_SIZE 40 | int "Maximum Capacity of buffer(Max File Size)" 41 | default 134217728 42 | endmenu 43 | 44 | 45 | config ADDR_ANY 46 | bool "Enable to bind port to all NIC on server machine" 47 | default y 48 | 49 | config HOST_ADDR 50 | string "Configure host ip address" 51 | depends on !ADDR_ANY 52 | 53 | config ADDR_REUSE 54 | bool "Enable to reuse address or port immediately" 55 | default y 56 | 57 | config PORT 58 | int "Configure server port" 59 | default 9006 60 | 61 | 62 | config LINTEN_Q_MAX 63 | int "Configure Maximum of connections in socket listening queue" 64 | default 16 65 | 66 | config MAX_EVENTS 67 | int "Configure Maximum of events in events pool" 68 | default 128 69 | 70 | endmenu 71 | 72 | menu "Timer System Options" 73 | 74 | config INIT_RATIO 75 | int "Initial acceleration Ratio (1s realtime : (n)s virtualtime)" 76 | default 1 77 | 78 | config TIME_ZONE 79 | int "Time zone setting (UTC)" 80 | default 8 81 | 82 | config HEART_TIMEOUT 83 | int "The waiting interval for heart beat packet (seconds)" 84 | default 60 85 | 86 | endmenu 87 | 88 | 89 | menu "Build Options" 90 | choice 91 | prompt "Compiler" 92 | default CC_GPP 93 | config CC_GCC 94 | bool "gcc" 95 | config CC_GPP 96 | bool "g++" 97 | config CC_CLANG 98 | bool "clang++" 99 | endchoice 100 | 101 | config CC 102 | string 103 | default "gcc" if CC_GCC 104 | default "g++" if CC_GPP 105 | default "clang++" if CC_CLANG 106 | default "none" 107 | 108 | choice 109 | prompt "Optimization Level" 110 | default CC_O2 111 | config CC_O0 112 | bool "O0" 113 | config CC_O1 114 | bool "O1" 115 | config CC_O2 116 | bool "O2" 117 | config CC_O3 118 | bool "O3" 119 | endchoice 120 | 121 | config CC_OPT 122 | string 123 | default "-O0" if CC_O0 124 | default "-O1" if CC_O1 125 | default "-O2" if CC_O2 126 | default "-O3" if CC_O3 127 | default "none" 128 | 129 | config CC_DEBUG 130 | bool "Enable debug information" 131 | default n 132 | 133 | endmenu 134 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | NAME = main-service 2 | 3 | WORK_DIR = $(shell pwd) 4 | SRC_DIR = $(WORK_DIR)/src 5 | BUILD_DIR = $(WORK_DIR)/build 6 | INCLUDE_DIR = $(WORK_DIR)/include 7 | LIB_DIR = $(WORK_DIR)/lib 8 | DATABASE = -lnedb 9 | 10 | PACKAGE = $(BUILD_DIR)/$(NAME) 11 | 12 | # set stdc++ 17 and multi-threads 13 | CXXFLAGS += -Wall -std=c++17 -pthread 14 | LDFLAGS = -L$(LIB_DIR) 15 | MODULES = $(filter-out src,$(notdir $(shell find $(SRC_DIR) -type d ) ) ) 16 | INCLUDES = $(addprefix -I ,$(INCLUDE_DIR)) 17 | 18 | OBJ_DIR = $(BUILD_DIR)/$(NAME)-obj 19 | 20 | # modules optional loading 21 | ifeq ($(MODS),) 22 | SOURCES = $(shell find src -name "*.cpp") 23 | else 24 | SOURCES = $(shell find $(addprefix src/,$(MODS)) -name "*.cpp") 25 | endif 26 | 27 | # include shell colors definitions 28 | -include scripts/colors.mk 29 | 30 | # include variables and rules generated by Kconfig automatically 31 | -include include/config/auto.conf 32 | -include include/config/auto.conf.cmd 33 | 34 | ifeq ($(wildcard .config),) 35 | $(warning $(COLOR_RED)Warning: .config does not exists!$(COLOR_END)) 36 | $(warning $(COLOR_RED)To build the project, first run 'make menuconfig'$(COLOR_END)) 37 | endif 38 | 39 | remove_quote = $(patsubst "%",%,$(1)) 40 | 41 | # re-configure default compilr 42 | ifneq ($(CONFIG_CC),) 43 | CXX = $(call remove_quote,$(CONFIG_CC)) 44 | endif 45 | 46 | # compilr optimization level (default -o2) 47 | ifneq ($(CONFIG_CC_OPT),) 48 | CXXFLAGS += $(call remove_quote,$(CONFIG_CC_OPT)) 49 | endif 50 | 51 | # debug mode , and C define "DEBUG" added 52 | ifeq ($(CONFIG_CC_DEBUG),y) 53 | CXXFLAGS += -DDEBUG -g 54 | endif 55 | 56 | # build project by origin Makefile 57 | include scripts/build.mk 58 | 59 | # import menuconfig makefile 60 | include scripts/config.mk 61 | 62 | .PHONY : clean .detect 63 | 64 | # detect 65 | .detect : 66 | ifeq ($(CONFIG_CC_DEBUG),y) 67 | @echo "$(C_YELLOW)Debug mode start up$(C_END)" 68 | endif 69 | @echo "$(C_BLUE)Module <$(MODULES)> has been detected...$(C_END)" 70 | 71 | # word count 72 | wc : 73 | @find . "(" -name "*.hpp" -or -name "*.cpp" -or -name "*.h" ")" -print | xargs wc -l 74 | 75 | # remove build dictionary 76 | clean : 77 | -rm -rf $(BUILD_DIR) 78 | 79 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![intro](./utils/pic0.png) 2 | # **TinyAndPretty 高校信息助理平台** 3 | ![avatar](https://badgen.net/badge/Language/C++17/orange) 4 | ![stars](https://badgen.net/badge/Dev%20Env./Linux/green) 5 | ![license](https://badgen.net/badge/License/Apache-2.0/blue) 6 | 7 | 🎉感谢您的驻足。如果本项目对您有帮助,请点一个✨Star表示支持~ 8 | 本项目为北京邮电大学计算机学院2022学年**数据结构课程设计**第六小组的拙作。项目涵盖了**B+Tree数据库原理与实现** 、 **Linux服务器开发实战** 、 **Vue前端设计部署** 、 **数据结构与算法**等诸多方面的全栈开发。从零开始共耗时三个月,历经近200次`commits`。模块**核心**部分精心匠造,注释文档~~全面~~、代码规范~~可靠~~;**业务**部分敏捷开发,基本囊括常见互联网业务。 9 | 10 | > 项目在线演示请戳这里👉[ Tiny & Pretty ](http://noui.cloud) 👈 (服务器已关闭) 11 | > 12 | > 项目部分接口请戳这里👉[ APIFox ](https://www.apifox.cn/apidoc/shared-255bbbcd-f00c-49a0-8c43-55d8677cf172) 👈 13 | > 14 | > 项目在线文档请戳这里👉[ Design ](https://docs.qq.com/doc/DR2p3RVZMVm93TE9J) 👈 15 | > 16 | > 网站操作指南请戳这里👉[ Instruction ](https://docs.qq.com/doc/DR0tqR0lTSWtUTWlu) 👈 17 | > 18 | > 前端界面预览请戳这里👉[ TAP Frontend ](https://github.com/BUPT-CS-Assignment/TAP-frontend) 👈 19 | 20 | 21 | 22 | 主体负责人和部分细分模块如下 23 | |Member|Jobs| 24 | |:---:|:---:| 25 | |[@Jianxff](https://github.com/Jianxff) |[NEDB](https://github.com/Jianxff/NEDB) / [Vue Page](https://github.com/Jianxff/TAP-frontend) / User Token | 26 | |[@LingZichao](https://github.com/LingZichao)| [HTTP Server](https://github.com/LingZichao/Tasty) / [JSON](https://github.com/LingZichao/SimpleJson) / Makefile | 27 | |[@Kqramazov](https://github.com/Kqramazov)| MD5 / A* / Landscaping | 28 | 29 | 您的每一次`issue`我们都将认真考虑,因此对于仍然存在的`BUG`或者`Advice`,欢迎您及时与我们沟通联系。 30 | 31 | 最后感谢各位组员的辛勤劳动,特别鸣谢王老师在课程中的细心答疑。 32 | 33 | ## 一.目录文件说明 ## 34 | ``` 35 | . 36 | ├── include //存放头文件(接口声明) 37 | │ ├── common.h //程序共用头 38 | │ ├── interfaces.h //模块接口,包含所有模块对外使用的函数定义 39 | │ ├── connect //网络通信模块 40 | │ │ ├── HttpProtocal //Http请求相应 41 | │ │ │── Network //服务器模块 42 | │ │ └── Timer //定时器有关的长连接支持 43 | │ │ 44 | │ ├── libs 45 | │ │ ├── BalanceTree.h //B+树模板 46 | │ │ ├── BasicUtils.h //基本小工具 47 | │ │ ├── Heap.hpp //小根堆实现 48 | │ │ ├── HashMap.hpp //蛤希表的实现 49 | │ │ ├── md5.h //MD5加密 50 | │ │ ├── NEdb.h //数据库接口头文件 51 | │ │ └── SimpleJson.hpp //JSON生成 52 | │ │ 53 | │ ├── service //后端业务服务模块 54 | │ │ 55 | │ ├── router.conf //URL路由配置文件 56 | │ └── test //测试模块 57 | │ 58 | ├── lib 59 | │ └── libnedb.a //数据库静态库文件 60 | │ 61 | ├── Kconfig //参数配置 62 | ├── LICENSE 63 | ├── Makefile 64 | ├── README.md 65 | │ 66 | ├── scripts //存放脚本及文档 67 | │ 68 | ├── src //项目源代码 69 | │ ├── main.cpp //主服务入口 70 | │ ├── server 71 | │ │ ├── HttpProtocal //Http相关解析的实现 72 | │ │ ├── MD5 //MD5算法的实现 73 | │ │ ├── Timer //服务器长连接有关的实现 74 | │ │ └── Network //服务器底层组件的实现 75 | │ │ 76 | │ ├── service //后台业务逻辑的实现 77 | │ ├── controller //用户权限控制 78 | │ │ 79 | │ └── test //测试接口 80 | │ 81 | ├── web //旧版本的网页文件 82 | ├── data //数据表文件 83 | │ ├── src 84 | │ │ ├── major 85 | │ │ └── school 86 | │ ├── sys 87 | │ │ ├── test 88 | │ │ └── token 89 | │ └── user 90 | │ 91 | │ 92 | └── utils //存放杂项 93 | ``` 94 | 95 | ## 二.自动化指令说明 ## 96 | 在项目文件夹根目录下使用如下指令,可快速使用相应功能。 97 | * i . 编译并运行。🚥请在`Linux`环境下配置服务器! 98 | ``` 99 | $ make run 100 | ``` 101 | 102 | * ii . 清除`build`编译文件夹。`disrclean`可清除`menuconfig`生成的配置文件。 103 | ``` 104 | $ make (dist)?clean 105 | ``` 106 | * iii . 启动菜单配置,调整程序运行参数 107 | ``` 108 | $ make menuconfig 109 | ``` 110 | -------------------------------------------------------------------------------- /data/maps/navi_info.h: -------------------------------------------------------------------------------- 1 | #ifndef __P_LIST__ 2 | #define __P_LIST__ 3 | 4 | namespace Building { 5 | 6 | enum BuildType { 7 | BUILD , 8 | AREA , 9 | }; 10 | 11 | struct Build { 12 | int id ; 13 | char name[32]; 14 | BuildType bt; 15 | int posx , posy; 16 | }; 17 | 18 | 19 | static const Build BuildingList[] = 20 | { 21 | {10001, "西大门" ,BUILD ,0,25}, 22 | {10002, "西门外卖点" ,AREA ,0,24}, 23 | {10003, "沙河快递站" ,BUILD ,4,21}, 24 | {10004, "基建处" ,BUILD ,0,20}, 25 | {10005, "田径场" ,BUILD ,21,6}, 26 | {10006, "篮球场" ,BUILD ,21,18}, 27 | {10007, "体育场AED" ,AREA ,19,13}, 28 | {10008, "学生公寓E区" ,BUILD ,26,6}, 29 | {10009, "学生公寓D2区" ,BUILD ,34,5}, 30 | {10010, "E区休憩区" ,AREA ,32,9}, 31 | {10011, "学生公寓C区" ,BUILD ,30,15}, 32 | {10012, "学生公寓B区" ,BUILD ,27,18}, 33 | {10013, "学生公寓A区" ,BUILD ,33,21}, 34 | {10014, "学生公寓D1区" ,BUILD ,36,18}, 35 | {10015, "生活服务区" ,BUILD ,33,21}, 36 | {10016, "沙河展览台" ,AREA ,27,28}, 37 | {10017, "信息楼S1" ,BUILD ,24,32}, 38 | {10018, "学生公寓S2" ,BUILD ,38,34}, 39 | {10019, "学生公寓S3" ,BUILD ,37,40}, 40 | {10020, "学生公寓S4" ,BUILD ,37,47}, 41 | {10021, "学生公寓S5" ,BUILD ,37,53}, 42 | {10022, "学生公寓S6" ,BUILD ,37,61}, 43 | {10023, "教工食堂" ,BUILD, 44 ,6}, 44 | {10024, "学生食堂" ,BUILD, 44, 17}, 45 | {10025, "校园西餐厅" ,BUILD, 50, 20}, 46 | {10026, "二维码广场" ,BUILD, 51, 13}, 47 | {10027, "公共教学楼" ,BUILD, 50, 36}, 48 | {10028, "沙河小公园" ,BUILD, 50, 49}, 49 | {10029, "南区食堂" ,BUILD, 48, 55}, 50 | {10030, "沙河南大门" ,BUILD, 63, 63}, 51 | {10031, "沙河南门外卖点",AREA, 62, 63}, 52 | {10032, "沙河医务室" ,BUILD, 56, 1}, 53 | {10033, "沙河办公楼" ,BUILD, 56, 6}, 54 | {10034, "沙河学生活动中心",BUILD,56 ,17}, 55 | {10035, "沙河小卖部" ,BUILD ,53,17}, 56 | {10036, "沙河邮局" ,BUILD ,56 ,24}, 57 | {10037, "ATM" ,AREA, 56, 24}, 58 | {10038, "东配楼" ,BUILD ,82,12}, 59 | {10039, "沙河咖啡厅" ,BUILD ,77,19}, 60 | {10040, "沙河图书馆" ,BUILD ,71,16}, 61 | {10041, "教学楼N楼" ,BUILD ,71,31}, 62 | {10042, "教学楼S楼" ,BUILD ,71,41}, 63 | {10043, "沙河报告厅" ,BUILD ,69,36}, 64 | {10044, "实验楼S1" ,BUILD ,101,31}, 65 | {10045, "实验楼S2" ,BUILD ,101,41}, 66 | {10046, "实验楼S3" ,BUILD ,101,50}, 67 | {10047, "理学院楼" ,BUILD ,91,56}, 68 | {10048, "售货机E" ,AREA ,28,6}, 69 | {10049, "售货机D2" ,AREA ,35,18}, 70 | {10050, "咖啡机S" ,AREA ,72,41}, 71 | 72 | {20001, "西土城西门" ,BUILD ,1,58}, 73 | {20002, "西土城主楼" ,BUILD ,42,59}, 74 | {20003, "西土城教一楼" ,BUILD ,39,46}, 75 | {20004, "西土城教二楼" ,BUILD ,39,76}, 76 | {20005, "西土城教三楼" ,BUILD ,16,76}, 77 | {20006, "西土城教四楼" ,BUILD ,16,44}, 78 | {20007, "科学会堂" ,BUILD ,55,59}, 79 | {20008, "创新楼" ,BUILD ,54,81}, 80 | {20009, "西土城图书馆" ,BUILD ,41,32}, 81 | {20010, "西土城篮球场" ,BUILD ,51,34}, 82 | }; 83 | constexpr unsigned long arrlen = sizeof(BuildingList) / sizeof(Build); 84 | 85 | struct BusInfo { 86 | int start_hour , start_mins; 87 | int num[7]; 88 | } ; 89 | 90 | static const BusInfo XTCBusList[] = { 91 | /* hour:mins | Sun | Mon | Tue | Wes | Thu | Fri | Sat | */ 92 | { 6 , 50 , 0 , 2 , 2 , 2 , 2 , 2 , 0 } , 93 | { 8 , 30 , 0 , 2 , 2 , 2 , 2 , 2 , 0 } , 94 | { 12 , 00 , 0 , 2 , 2 , 1 , 2 , 1 , 0 } , 95 | { 13 , 30 , 0 , 1 , 1 , 1 , 1 , 1 , 0 } , 96 | { 14 , 20 , 0 , 1 , 1 , 0 , 1 , 1 , 0 } , 97 | { 16 , 60 , 0 , 1 , 1 , 1 , 1 , 0 , 0 } 98 | 99 | }; 100 | 101 | constexpr unsigned long XTCarrlen = sizeof(XTCBusList) / sizeof(BusInfo); 102 | 103 | static const BusInfo SHBusList[] = { 104 | /* hour:mins | Sun | Mon | Tue | Wes | Thu | Fri | Sat | */ 105 | { 9 , 50 , 0 , 2 , 2 , 1 , 2 , 2 , 0 } , 106 | { 11 , 40 , 0 , 2 , 2 , 2 , 2 , 1 , 0 } , 107 | { 13 , 00 , 0 , 1 , 1 , 2 , 1 , 1 , 0 } , 108 | { 15 , 45 , 0 , 1 , 1 , 0 , 1 , 1 , 0 } , 109 | { 17 , 10 , 0 , 1 , 1 , 1 , 1 , 1 , 0 } , 110 | { 18 , 25 , 0 , 1 , 1 , 1 , 1 , 1 , 0 } , 111 | { 21 , 10 , 0 , 1 , 1 , 0 , 1 , 0 , 0 } 112 | 113 | }; 114 | 115 | constexpr unsigned long SHarrlen = sizeof(SHBusList) / sizeof(BusInfo); 116 | 117 | }; 118 | 119 | #endif -------------------------------------------------------------------------------- /data/src/course/10500040/intro.txt: -------------------------------------------------------------------------------- 1 | 形势与政策共5学期;每学期0.4学分,6学时。 -------------------------------------------------------------------------------- /data/src/course/31301024/intro.txt: -------------------------------------------------------------------------------- 1 | 电路学基础课程 -------------------------------------------------------------------------------- /data/src/course/31302022/2010001001/2020211313/202206171250/2020212900/123.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/data/src/course/31302022/2010001001/2020211313/202206171250/2020212900/123.docx -------------------------------------------------------------------------------- /data/src/course/31302022/2010001001/2020211313/202206171250/2020212900/FILE.ned: -------------------------------------------------------------------------------- 1 | 123.docxce79b6b05786489edb66c0273497893a -------------------------------------------------------------------------------- /data/src/course/31302022/2010001001/2020211313/202206171250/2020212900/FILE.nef: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/data/src/course/31302022/2010001001/2020211313/202206171250/2020212900/FILE.nef -------------------------------------------------------------------------------- /data/src/course/31302022/2010001001/2020211313/202206171250/2020212900/report_1.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/data/src/course/31302022/2010001001/2020211313/202206171250/2020212900/report_1.docx -------------------------------------------------------------------------------- /data/src/course/31302022/2010001001/2020211313/202206171250/2020212910/report_1.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/data/src/course/31302022/2010001001/2020211313/202206171250/2020212910/report_1.docx -------------------------------------------------------------------------------- /data/src/course/31302022/2010001001/2020211313/homework.ned: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/data/src/course/31302022/2010001001/2020211313/homework.ned -------------------------------------------------------------------------------- /data/src/course/31302022/2010001001/2020211313/homework.nef: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/data/src/course/31302022/2010001001/2020211313/homework.nef -------------------------------------------------------------------------------- /data/src/course/31302022/2010001001/res/FILE.ned: -------------------------------------------------------------------------------- 1 | Intro.docxce79b6b05786489edb66c0273497893a -------------------------------------------------------------------------------- /data/src/course/31302022/2010001001/res/FILE.nef: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/data/src/course/31302022/2010001001/res/FILE.nef -------------------------------------------------------------------------------- /data/src/course/31302022/2010001001/res/Intro.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/data/src/course/31302022/2010001001/res/Intro.docx -------------------------------------------------------------------------------- /data/src/course/31302022/exam.ned: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/data/src/course/31302022/exam.ned -------------------------------------------------------------------------------- /data/src/course/31302022/exam.nef: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/data/src/course/31302022/exam.nef -------------------------------------------------------------------------------- /data/src/course/31302022/intro.txt: -------------------------------------------------------------------------------- 1 | 数据结构课程设计,1.5学分。至高无上的课程!!!!! -------------------------------------------------------------------------------- /data/src/course/31302060/intro.txt: -------------------------------------------------------------------------------- 1 | 计算机组成原理实践设计课程 -------------------------------------------------------------------------------- /data/src/course/31302070/intro.txt: -------------------------------------------------------------------------------- 1 | 数字逻辑与数字系统实践设计课程 -------------------------------------------------------------------------------- /data/src/course/31302120/intro.txt: -------------------------------------------------------------------------------- 1 | 计算机网络课程设计基础课程 -------------------------------------------------------------------------------- /data/src/course/31302321/intro.txt: -------------------------------------------------------------------------------- 1 | 面向对象程序设计实践(Java)基础课程 -------------------------------------------------------------------------------- /data/src/course/31302470/intro.txt: -------------------------------------------------------------------------------- 1 | 面向对象程序设计实践(C++)基础课程 -------------------------------------------------------------------------------- /data/src/course/31312040/exam.ned: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/data/src/course/31312040/exam.ned -------------------------------------------------------------------------------- /data/src/course/31312040/exam.nef: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/data/src/course/31312040/exam.nef -------------------------------------------------------------------------------- /data/src/course/31312040/intro.txt: -------------------------------------------------------------------------------- 1 | 形式语言与自动机基础课程 -------------------------------------------------------------------------------- /data/src/course/31313041/exam.ned: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/data/src/course/31313041/exam.ned -------------------------------------------------------------------------------- /data/src/course/31313041/exam.nef: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/data/src/course/31313041/exam.nef -------------------------------------------------------------------------------- /data/src/course/31313041/intro.txt: -------------------------------------------------------------------------------- 1 | 计算机组成原理基础课程 -------------------------------------------------------------------------------- /data/src/course/31321030/exam.ned: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/data/src/course/31321030/exam.ned -------------------------------------------------------------------------------- /data/src/course/31321030/exam.nef: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/data/src/course/31321030/exam.nef -------------------------------------------------------------------------------- /data/src/course/31321030/intro.txt: -------------------------------------------------------------------------------- 1 | 计算机网络基础课程 -------------------------------------------------------------------------------- /data/src/course/33200081/intro.txt: -------------------------------------------------------------------------------- 1 | 毛泽东思想和中国特色社会主义理论体系概论基础课程 -------------------------------------------------------------------------------- /data/src/course/34110012/intro.txt: -------------------------------------------------------------------------------- 1 | 高等数学A(上) -------------------------------------------------------------------------------- /data/src/course/34110021/intro.txt: -------------------------------------------------------------------------------- 1 | 高等数学A(下) -------------------------------------------------------------------------------- /data/src/course/34110073/intro.txt: -------------------------------------------------------------------------------- 1 | 线性代数基础课程 -------------------------------------------------------------------------------- /data/src/course/34110092/intro.txt: -------------------------------------------------------------------------------- 1 | 概率论与随机过程 -------------------------------------------------------------------------------- /data/src/course/34110102/intro.txt: -------------------------------------------------------------------------------- 1 | 概率论与数理统计 -------------------------------------------------------------------------------- /data/src/course/38120010/exam.ned: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/data/src/course/38120010/exam.ned -------------------------------------------------------------------------------- /data/src/course/38120010/exam.nef: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/data/src/course/38120010/exam.nef -------------------------------------------------------------------------------- /data/src/course/38120010/intro.txt: -------------------------------------------------------------------------------- 1 | 体育基础基础课程(下) -------------------------------------------------------------------------------- /data/src/course/courses.ned: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/data/src/course/courses.ned -------------------------------------------------------------------------------- /data/src/course/courses.nef: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/data/src/course/courses.nef -------------------------------------------------------------------------------- /data/src/css/app.d1ad8af5.css: -------------------------------------------------------------------------------- 1 | #auth{background-image:url(/img/bg2.20dd4c41.png);background-size:cover;background-position:50%}.bg{background-color:rgba(0,0,0,.1)}.custom-loader{-webkit-animation:loader 1s infinite;animation:loader 1s infinite;display:flex}@-webkit-keyframes loader{0%{transform:rotate(0)}to{transform:rotate(1turn)}}@keyframes loader{0%{transform:rotate(0)}to{transform:rotate(1turn)}}.my-event[data-v-4db3afe9]{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;border-radius:2px;background-color:#1867c0;color:#fff;border:1px solid #1867c0;font-size:12px;padding:3px;cursor:pointer;margin-bottom:1px;left:4px;margin-right:8px;position:relative}.my-event.with-time[data-v-4db3afe9]{position:absolute;right:4px;margin-right:0}.map[data-v-66f424b9]{width:1050px;height:650px;background-image:url(/img/bg.ed3fd931.png);background-size:1050px 650px;background-repeat:no-repeat}.map2[data-v-66f424b9]{width:750px;height:1100px;background-image:url(/img/xitucheng.fb7ec5b3.png);background-size:750px 1100px;background-repeat:no-repeat}.block[data-v-66f424b9]{width:20px;height:20px;background:none}.map{width:1050px;height:650px;background-image:url(/img/bg.ed3fd931.png);background-size:1050px 650px}.map,.map2{background-repeat:no-repeat}.map2{width:750px;height:1100px;background-image:url(/img/xitucheng.fb7ec5b3.png);background-size:750px 1100px} -------------------------------------------------------------------------------- /data/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/data/src/favicon.ico -------------------------------------------------------------------------------- /data/src/file/game-programmer-zh-cn.pdf.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/data/src/file/game-programmer-zh-cn.pdf.gz -------------------------------------------------------------------------------- /data/src/file/屏幕截图 2022-06-13 131213.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/data/src/file/屏幕截图 2022-06-13 131213.jpg -------------------------------------------------------------------------------- /data/src/fonts/materialdesignicons-webfont.2e22fd77.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/data/src/fonts/materialdesignicons-webfont.2e22fd77.eot -------------------------------------------------------------------------------- /data/src/fonts/materialdesignicons-webfont.42483c73.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/data/src/fonts/materialdesignicons-webfont.42483c73.woff -------------------------------------------------------------------------------- /data/src/fonts/materialdesignicons-webfont.935d8e7a.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/data/src/fonts/materialdesignicons-webfont.935d8e7a.woff2 -------------------------------------------------------------------------------- /data/src/fonts/materialdesignicons-webfont.9fcb655c.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/data/src/fonts/materialdesignicons-webfont.9fcb655c.ttf -------------------------------------------------------------------------------- /data/src/img/bg.ed3fd931.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/data/src/img/bg.ed3fd931.png -------------------------------------------------------------------------------- /data/src/img/bg2.20dd4c41.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/data/src/img/bg2.20dd4c41.png -------------------------------------------------------------------------------- /data/src/img/item1.18a46c8b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/data/src/img/item1.18a46c8b.png -------------------------------------------------------------------------------- /data/src/img/xitucheng.fb7ec5b3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/data/src/img/xitucheng.fb7ec5b3.png -------------------------------------------------------------------------------- /data/src/index.html: -------------------------------------------------------------------------------- 1 | Tiny And Pretty
-------------------------------------------------------------------------------- /data/src/major/80901.txt: -------------------------------------------------------------------------------- 1 | 计算机科学与技术专业简介. -------------------------------------------------------------------------------- /data/src/major/majors.ned: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/data/src/major/majors.ned -------------------------------------------------------------------------------- /data/src/major/majors.nef: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/data/src/major/majors.nef -------------------------------------------------------------------------------- /data/src/map/landmark.ned: -------------------------------------------------------------------------------- 1 | ee教学楼f运动场g学生活动中心 -------------------------------------------------------------------------------- /data/src/map/landmark.nef: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/data/src/map/landmark.nef -------------------------------------------------------------------------------- /data/src/school/313/intro.txt: -------------------------------------------------------------------------------- 1 | 北京邮电大学1977年开设计算机通信本科专业,1985年成立计算机工程系,1998年成立计算机科学与技术学院。2008年,按照“学科归位”的原则,将计算机科学与技术学院等六个单位计算机学科的资源重新整合为计算机学院。2020年,将原计算机学院、软件学院、网络技术研究院调整、合并组建新的计算机学院(国家示范性软件学院),并支撑网络与交换技术国家重点实验室(北京邮电大学)。 2 | 学院的发展紧密结合国家重大战略需求、信息通信行业跨越式发展、计算机科学与技术学科的快速演进,经历了充满激情、艰苦奋斗的创业建设阶段,勇于开拓、协调发展的持续提高阶段,敢为人先、不断进取的全面发展阶段和凝心聚力、勇攀高峰的争创一流阶段,取得了一个又一个辉煌的业绩,为国家培养了一批又一批计算机专业人才和计算机通信复合型人才,成果凝结了北邮几代计算机人团结奋斗所付出的心血和汗水。同时,学院的办学水平迈上一个又一个新台阶,2017年教育部第四轮学科评估中,计算机科学与技术一级学科评估结果为A。2017年,计算机科学与技术学科入选国家“双一流”建设一流学科。2019年ESI计算机学科学术机构最新排名进入全球1‰。 -------------------------------------------------------------------------------- /data/src/school/classes.ned: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/data/src/school/classes.ned -------------------------------------------------------------------------------- /data/src/school/classes.nef: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/data/src/school/classes.nef -------------------------------------------------------------------------------- /data/src/school/schools.ned: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/data/src/school/schools.ned -------------------------------------------------------------------------------- /data/src/school/schools.nef: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/data/src/school/schools.nef -------------------------------------------------------------------------------- /data/sys/database_test.ned: -------------------------------------------------------------------------------- 1 | 0x770x540xff0xff0xff0xff0xff0xff 0xff 2 | 0xff  0xff 0xff 0xff0xff0xff0xff0xff0xff0xff0xff0xff0xff0xff0xff0xff0xff0xff0xff0xff0xff0xff 0xff!0xff"0xff#0xff$$0xff%0xff&0xff'0xff(0xff -------------------------------------------------------------------------------- /data/sys/database_test.nef: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/data/sys/database_test.nef -------------------------------------------------------------------------------- /data/sys/token/token.ned: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/data/sys/token/token.ned -------------------------------------------------------------------------------- /data/sys/token/token.nef: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/data/sys/token/token.nef -------------------------------------------------------------------------------- /data/user/0/2010001005/timetable.ned: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/data/user/0/2010001005/timetable.ned -------------------------------------------------------------------------------- /data/user/0/2010001005/timetable.nef: -------------------------------------------------------------------------------- 1 | timetable idcourseprofD1D2D3D4D5locroomcontact4 -------------------------------------------------------------------------------- /data/user/212/0/2010001007/timetable.ned: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/data/user/212/0/2010001007/timetable.ned -------------------------------------------------------------------------------- /data/user/212/0/2010001007/timetable.nef: -------------------------------------------------------------------------------- 1 | timetable idcourseprofD1D2D3D4D5locroomcontact4 -------------------------------------------------------------------------------- /data/user/313/0/2010001001/timetable.ned: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/data/user/313/0/2010001001/timetable.ned -------------------------------------------------------------------------------- /data/user/313/0/2010001001/timetable.nef: -------------------------------------------------------------------------------- 1 | timetable idcourseprofD1D2D3D4D5locroomcontact4 -------------------------------------------------------------------------------- /data/user/313/0/2010001003/timetable.ned: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/data/user/313/0/2010001003/timetable.ned -------------------------------------------------------------------------------- /data/user/313/0/2010001003/timetable.nef: -------------------------------------------------------------------------------- 1 | timetable idcourseprofD1D2D3D4D5locroomcontact4 -------------------------------------------------------------------------------- /data/user/313/0/2010001006/timetable.ned: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/data/user/313/0/2010001006/timetable.ned -------------------------------------------------------------------------------- /data/user/313/0/2010001006/timetable.nef: -------------------------------------------------------------------------------- 1 | timetable idcourseprofD1D2D3D4D5locroomcontact4 -------------------------------------------------------------------------------- /data/user/313/2020211313/event.ned: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/data/user/313/2020211313/event.ned -------------------------------------------------------------------------------- /data/user/313/2020211313/event.nef: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/data/user/313/2020211313/event.nef -------------------------------------------------------------------------------- /data/user/313/timetable.ned: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/data/user/313/timetable.ned -------------------------------------------------------------------------------- /data/user/313/timetable.nef: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/data/user/313/timetable.nef -------------------------------------------------------------------------------- /data/user/332/0/2010001004/timetable.ned: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/data/user/332/0/2010001004/timetable.ned -------------------------------------------------------------------------------- /data/user/332/0/2010001004/timetable.nef: -------------------------------------------------------------------------------- 1 | timetable idcourseprofD1D2D3D4D5locroomcontact4 -------------------------------------------------------------------------------- /data/user/341/0/2010001002/timetable.ned: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/data/user/341/0/2010001002/timetable.ned -------------------------------------------------------------------------------- /data/user/341/0/2010001002/timetable.nef: -------------------------------------------------------------------------------- 1 | timetable idcourseprofD1D2D3D4D5locroomcontact4 -------------------------------------------------------------------------------- /data/user/381/0/2010001005/timetable.ned: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/data/user/381/0/2010001005/timetable.ned -------------------------------------------------------------------------------- /data/user/381/0/2010001005/timetable.nef: -------------------------------------------------------------------------------- 1 | timetable idcourseprofD1D2D3D4D5locroomcontact4 -------------------------------------------------------------------------------- /data/user/users.ned: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/data/user/users.ned -------------------------------------------------------------------------------- /data/user/users.nef: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/data/user/users.nef -------------------------------------------------------------------------------- /include/common.h: -------------------------------------------------------------------------------- 1 | #ifndef __COMMON__ 2 | #define __COMMON__ 3 | /* 4 | This header file mainly contains std library 5 | and might be included in the whole project. 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | namespace fs = std::filesystem; 30 | 31 | #ifdef DEBUG 32 | #define IFDEBUG(...) __VA_ARGS__ 33 | #else 34 | #define IFDEBUG(...) 35 | #endif 36 | 37 | #endif -------------------------------------------------------------------------------- /include/connect/HttpProtocal/HttpAdapter.h: -------------------------------------------------------------------------------- 1 | #ifndef __HTTP_ADAPTER__ 2 | #define __HTTP_ADAPTER__ 3 | 4 | #include 5 | 6 | class Socket; 7 | class Connection; 8 | class HttpResponseBase; 9 | 10 | /* Adapter : make a bridge between socket and http io */ 11 | class HttpAdapter 12 | { 13 | private: 14 | std::shared_ptr sock; 15 | 16 | // dynamically convert base ptr to FileResponse 17 | bool branchFilePathResp(Connection *conn , std::shared_ptr ret); 18 | public: 19 | HttpAdapter(std::shared_ptr _sock) : sock(_sock) {}; 20 | // recv data from socket in a modern c++ way 21 | auto recvHttpData(Connection *conn) 22 | -> std::tuple< std::shared_ptr , size_t > ; 23 | 24 | // send data to socket also checking file 25 | void sendHttpData(Connection *conn , std::shared_ptr ret) ; 26 | }; 27 | 28 | #endif -------------------------------------------------------------------------------- /include/connect/HttpProtocal/HttpBase.h: -------------------------------------------------------------------------------- 1 | #ifndef __HTTP_BASE__ 2 | #define __HTTP_BASE__ 3 | 4 | #include 5 | 6 | /* commonly used http status code */ 7 | #define HTTP_STATUS_200 "HTTP/1.1 200 OK\r\n" 8 | #define HTTP_STATUS_202 "HTTP/1.1 202 Accepted\r\n" 9 | #define HTTP_STATUS_204 "HTTP/1.1 204 No Content\r\n" 10 | #define HTTP_STATUS_300 "HTTP/1.1 300 Multiple Choice\r\n" 11 | #define HTTP_STATUS_400 "HTTP/1.1 400 Bad Request\r\n" 12 | #define HTTP_STATUS_401 "HTTP/1.1 401 Unauthorized\r\n" 13 | #define HTTP_STATUS_403 "HTTP/1.1 403 Forbidden\r\n" 14 | #define HTTP_STATUS_404 "HTTP/1.1 404 Not Found\r\n" 15 | #define HTTP_STATUS_502 "HTTP/1.1 502 Bad Gateway\r\n" 16 | 17 | /* implementation of K-V string-pair dictionary */ 18 | class StringDict { 19 | 20 | using Dict = std::vector>; 21 | 22 | Dict item; 23 | size_t len = 0; 24 | 25 | /* init stringdict by two significant tokens */ 26 | void __init__(char * , const char * , const char *) noexcept; 27 | public : 28 | StringDict() = default; 29 | /* allow delayed construct */ 30 | StringDict(char* str , const char* token_1 , const char* token_2) {__init__(str , token_1 , token_2);} 31 | 32 | /* 33 | query and fetch origin data in this dict. 34 | is_insen : TRUE stands for 'Case insensitive' 35 | HttpException::NON_POS would occur when not found 36 | */ 37 | std::string& get(std::string_view _key, bool is_insen = false); 38 | 39 | /* query and fetch origin data in this dict. HttpException::NON_POS would occur when not found */ 40 | std::string& operator[] (std::string_view str) noexcept; 41 | 42 | /* append one pair to dict in the end */ 43 | void push(std::string _fir , std::string _sec) noexcept; 44 | 45 | /* display this stringdict on stdout */ 46 | void show(); 47 | 48 | /* calculate total length */ 49 | size_t length() const { return len; } 50 | 51 | /* stringize to byte stream / string */ 52 | size_t stringize(char *buff); 53 | }; 54 | 55 | /* implementation of the item in multipart/form-fata */ 56 | class FormData; 57 | class FormItem { 58 | friend class FormData; 59 | std::unique_ptr headers; 60 | std::unique_ptr data; 61 | std::string name = ""; 62 | std::string filename = ""; 63 | size_t len; 64 | public : 65 | /* constructor by byte range */ 66 | FormItem(uint8_t*_begin , uint8_t* _end); 67 | 68 | /* method of inverting tostring. NOT guarantee correctness */ 69 | operator std::string() const {return std::string((char *)data.get() , len);} 70 | 71 | /* method of inverting to filestream. NOT guarantee correctness */ 72 | friend std:: fstream& operator << (std:: fstream& out , const FormItem& _this); 73 | friend std::ofstream& operator << (std::ofstream& out , const FormItem& _this); 74 | 75 | /* calculate total length */ 76 | size_t length() const {return len;} 77 | 78 | /* query form key name */ 79 | std::string_view queryName() const {return name;} 80 | 81 | /* query form file name */ 82 | std::string_view queryFilename() const {return filename;} 83 | 84 | /* display this form item on stdout in the way of char */ 85 | void show(); 86 | }; 87 | 88 | /* implementation of the multipart/form-fata */ 89 | class FormData { 90 | std::string boundary; 91 | std::vector form; 92 | public : 93 | FormData(std::string& , uint8_t* , size_t) ; 94 | 95 | /* query form item by key nam */ 96 | FormItem& queryItem(std::string_view _name); 97 | }; 98 | 99 | #endif -------------------------------------------------------------------------------- /include/connect/HttpProtocal/HttpException.h: -------------------------------------------------------------------------------- 1 | #ifndef __HTTP_EXCEPT__ 2 | #define __HTTP_EXCEPT__ 3 | 4 | //Definition of all exception might occur in http module; 5 | enum class HttpException 6 | { 7 | NON_POS, //not found as a result of searching instrution 8 | ERROR_LEN, //verification error when Content-length differs from actual 9 | OUT_OF_LIMIT, //the size of request or file is too large 10 | NON_PATH, //url does not exists 11 | NON_CONN, //connection offline ahead of time 12 | NON_FORM //request body is not type of multipart/form-data 13 | }; 14 | 15 | #endif -------------------------------------------------------------------------------- /include/connect/HttpProtocal/HttpManager.h: -------------------------------------------------------------------------------- 1 | #ifndef __HTTP_MANAGER__ 2 | #define __HTTP_MANAGER__ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | /* HttpTask center manager */ 11 | class HttpManager : public ManagerBase 12 | { 13 | //specialize http io through adapter 14 | std::unique_ptr wrapper = std::make_unique(sock); 15 | 16 | HttpResponse *dispatchException(const HttpException& e); 17 | HttpResponseBase *taskExecute(Connection* conn, std::shared_ptr raw, size_t len); 18 | public: 19 | 20 | virtual bool protocalConfirm(const int magic_n) override; 21 | virtual bool createTask(Connection* conn) override; 22 | }; 23 | 24 | #endif -------------------------------------------------------------------------------- /include/connect/HttpProtocal/HttpProtocal.h: -------------------------------------------------------------------------------- 1 | #ifndef __HTTP__ 2 | #define __HTTP__ 3 | 4 | #include "HttpBase.h" 5 | #include "HttpRequest.h" 6 | #include "HttpResponse.h" 7 | 8 | #endif -------------------------------------------------------------------------------- /include/connect/HttpProtocal/HttpRequest.h: -------------------------------------------------------------------------------- 1 | #ifndef __HTTP_MSG__ 2 | #define __HTTP_MSG__ 3 | 4 | #include "HttpBase.h" 5 | 6 | class Connection; 7 | class HttpRequest { 8 | Connection *conn; 9 | 10 | std::unique_ptr params; 11 | std::unique_ptr headers; 12 | std::unique_ptr form; 13 | std::unique_ptr body; 14 | 15 | std::string method , path , version; 16 | 17 | size_t length ; 18 | public : 19 | HttpRequest(Connection* _conn , uint8_t* str, const size_t len); 20 | 21 | /* query form data by item key name */ 22 | FormItem& queryForm ( std::string_view key ); 23 | 24 | /* 25 | query parameters in url (GET only) 26 | is_insen : TRUE stands for 'Case insensitive' 27 | */ 28 | std::string_view queryParam ( std::string_view key , bool is_insen = false ) noexcept; 29 | 30 | /* 31 | query header item 32 | is_insen : TRUE stands for 'Case insensitive' 33 | */ 34 | std::string_view queryHeader( std::string_view key , bool is_insen = false ) noexcept; 35 | 36 | /* fetch and construct http body to string */ 37 | std::string getBody() ; 38 | 39 | /* query url path */ 40 | std::string_view Path() const noexcept { return path;} 41 | 42 | /* query url method */ 43 | std::string_view Method() const noexcept { return method;} 44 | 45 | /* query http protocal version */ 46 | std::string_view HttpVer() const noexcept { return version;} 47 | 48 | /* Connection */ 49 | auto getConnection() { return conn; } 50 | std::string_view queryClientIP() const noexcept ; 51 | 52 | 53 | size_t Length() const { return length; } 54 | }; 55 | #endif -------------------------------------------------------------------------------- /include/connect/HttpProtocal/HttpResponse.h: -------------------------------------------------------------------------------- 1 | #ifndef __HTTP_RESP__ 2 | #define __HTTP_RESP__ 3 | 4 | #include "HttpBase.h" 5 | 6 | class HttpResponseBase { 7 | protected : 8 | std::string status = HTTP_STATUS_200; 9 | std::unique_ptr headers = std::make_unique(); 10 | 11 | void setDefaultHeaders(); 12 | public : 13 | HttpResponseBase(); 14 | HttpResponseBase( const std::string& _status); 15 | void appendHeader(const std::string _fir , const std::string _sec) ; 16 | 17 | auto stringize() 18 | ->std::tuple, size_t>; 19 | virtual size_t length() const = 0; 20 | virtual size_t stringize(uint8_t **buff) = 0; 21 | virtual ~HttpResponseBase() {} 22 | }; 23 | 24 | 25 | class HttpResponse : public HttpResponseBase{ 26 | std::string body = ""; 27 | public : 28 | explicit HttpResponse() = default; 29 | explicit HttpResponse(std::string _body) ; 30 | explicit HttpResponse(std::string _body , const std::string _status); 31 | explicit HttpResponse(std::string _body, const std::string _msg, const std::string _status); 32 | 33 | virtual size_t length() const override; 34 | virtual size_t stringize(uint8_t **buff) override; 35 | }; 36 | 37 | class FileResponse : public HttpResponseBase{ 38 | //verison 1 : r/w fstream 39 | std::fstream body; 40 | //version 2 : read only file 41 | fs::path filepath; 42 | 43 | size_t body_len = 0; 44 | public : 45 | explicit FileResponse() = default; 46 | explicit FileResponse(std::fstream &_body , const std::string _type); 47 | explicit FileResponse(std::fstream &_body , const std::string _type , const std::string _status) ; 48 | 49 | virtual size_t length() const override; 50 | virtual size_t stringize(uint8_t **buff) override; 51 | 52 | /* ---- newly appended ---- */ 53 | /* more efficient way to tansfer static read-only file */ 54 | explicit FileResponse(fs::path _filepath , const std::string _type); 55 | explicit FileResponse(fs::path _filepath, const std::string _type, const std::string _msg); 56 | 57 | fs::path getFilepath() const {return filepath;} 58 | auto stringizeHeader() 59 | -> std::tuple , size_t>; 60 | }; 61 | 62 | #include 63 | using namespace SimpleJson; 64 | 65 | class JsonResponse : public HttpResponseBase{ 66 | Json body; 67 | public : 68 | explicit JsonResponse() = default; 69 | explicit JsonResponse(Json &_body); 70 | explicit JsonResponse(Json &_body, const std::string _msg, const std::string _status); 71 | explicit JsonResponse(Json &_body , const std::string _status); 72 | 73 | virtual size_t length() const override; 74 | virtual size_t stringize(uint8_t **buff) override; 75 | }; 76 | 77 | 78 | #endif -------------------------------------------------------------------------------- /include/connect/Network/ManagerBase.h: -------------------------------------------------------------------------------- 1 | #ifndef __MANAGER_BASE__ 2 | #define __MANAGER_BASE__ 3 | 4 | #include 5 | #include "ServerBase.h" 6 | 7 | class ManagerBase 8 | { 9 | protected : 10 | std::shared_ptr sock; 11 | std::shared_ptr epool; 12 | 13 | public: 14 | void setSock(std::shared_ptr _sock) 15 | {sock = _sock;} 16 | void setEpool(std::shared_ptr _epool) 17 | {epool = _epool;} 18 | 19 | virtual bool protocalConfirm(const int magic_n) = 0; 20 | virtual bool createTask(Connection* conn) = 0; 21 | }; 22 | 23 | #endif -------------------------------------------------------------------------------- /include/connect/Network/ServerBase.h: -------------------------------------------------------------------------------- 1 | #ifndef __SERVER_BASE__ 2 | #define __SERVER_BASE__ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | #include "ServerConfig.h" 13 | 14 | struct EventChannel { 15 | const int magic_n; 16 | const int fd ; 17 | void* ptr ; 18 | uint32_t type; 19 | }; 20 | 21 | class Connection 22 | { 23 | int connfd; 24 | 25 | struct sockaddr_in clientAddr; 26 | public: 27 | Connection(int _connfd , struct sockaddr_in _addr) 28 | : connfd(_connfd) , clientAddr(_addr) {} 29 | 30 | int getFD() const {return connfd;} 31 | void closeFD() {close(connfd);} 32 | const char*getAddr() const 33 | {return inet_ntoa(clientAddr.sin_addr);} 34 | }; 35 | 36 | 37 | 38 | /* unix socket */ 39 | class Socket 40 | { 41 | public : 42 | Socket(); 43 | ~Socket(); 44 | 45 | // get socket file descriptor in unix 46 | int getFD() const {return sockfd;} 47 | 48 | // recv raw data in the format of byte stream 49 | size_t recvData(int _connfd , uint8_t **data ,int flags = 0,size_t _buff_size = BUFF_INIT_SIZE); 50 | // block recv but don't flush buffer 51 | size_t recvPeekData(int _connfd , uint8_t **data); 52 | // non-block recv 53 | size_t recvNonBlockData(int _connfd , uint8_t **data); 54 | 55 | size_t recvCertainData(int _connfd , uint8_t **data , size_t len); 56 | // send raw data in the format of byte stream 57 | size_t sendData(int _connfd , uint8_t *data , size_t len); 58 | // send file (FULL path needed) 59 | size_t sendFile(int _connfd , const char* _fpath); 60 | // send file (FULL path needed) with header 61 | size_t sendFileWithHeader(int _connfd , const char* _fpath , uint8_t *header , size_t header_len); 62 | 63 | // handle one connection in TCP socket 64 | Connection* onConnect(); 65 | void offConnect(Connection* _conn); 66 | 67 | private : 68 | int sockfd; 69 | 70 | struct sockaddr_in address; 71 | }; 72 | 73 | 74 | /* unix event pool based on epoll */ 75 | class EventPool 76 | { 77 | using EpollFunc = std::function; 78 | public: 79 | EventPool(); 80 | /* 81 | const int magic_n; 82 | const int fd ; 83 | void* ptr ; 84 | uint32_t type; 85 | */ 86 | bool mountEvent (const EventChannel&& echannel); 87 | bool modifyEvent(const EventChannel&& echannel); 88 | 89 | template 90 | int createTimerEvent( 91 | const EventChannel&& echannel , 92 | std::chrono::duration timeval); 93 | 94 | bool removeEvent(const EventChannel* eptr); 95 | void Poll( const EpollFunc& func ); 96 | void Loop( const EpollFunc func ); 97 | 98 | private : 99 | int epfd; 100 | 101 | struct epoll_event events[MAX_EVENTS]; 102 | 103 | int createTimerFD(int64_t nsec); 104 | }; 105 | 106 | #define NETERROR(cond , tar) do {\ 107 | if((cond)) {perror( tar );exit(EXIT_FAILURE);}\ 108 | } while (0) 109 | 110 | 111 | template 112 | int EventPool::createTimerEvent( 113 | const EventChannel&& echannel , 114 | std::chrono::duration timeval) 115 | { 116 | auto duration = 117 | std::chrono::duration_cast< 118 | std::chrono::duration 119 | >(timeval); 120 | auto tfd = this->createTimerFD(duration.count()); 121 | 122 | 123 | this->mountEvent({ 124 | echannel.magic_n , 125 | tfd , 126 | echannel.ptr , 127 | echannel.type 128 | }); 129 | 130 | return tfd; 131 | } 132 | 133 | 134 | #endif -------------------------------------------------------------------------------- /include/connect/Network/ServerConfig.h: -------------------------------------------------------------------------------- 1 | #ifndef __SERVER_CONF__ 2 | #define __SERVER_CONF__ 3 | 4 | #include "../../generated/autoconf.h" 5 | 6 | /* ------------------------Auto Configure----------------------------*/ 7 | #define PORT CONFIG_PORT 8 | #define LISTEN_Q_MAX CONFIG_LINTEN_Q_MAX 9 | #define RECV_TIMEOUT {CONFIG_RECV_SECOND,CONFIG_RECV_MICROSECOND} 10 | #define SEND_TIMEOUT {CONFIG_SEND_SECOND,CONFIG_SEND_MICROSECOND} 11 | #define MAX_EVENTS CONFIG_MAX_EVENTS 12 | #define BUFF_INIT_SIZE CONFIG_BUFF_INIT_SIZE 13 | #define BUFF_MAX_SIZE CONFIG_BUFF_MAX_SIZE // (1024*1024*128) bytes 14 | 15 | 16 | #ifdef CONFIG_IPV4 17 | #define IPV_4 AF_INET 18 | #define PROTO_FAMILT AF_INET 19 | #endif 20 | 21 | #ifdef CONFIG_ADDR_ANY 22 | #define HOST_ADDR INADDR_ANY 23 | #endif 24 | 25 | #ifdef CONFIG_ADDR_REUSE 26 | #define ADDR_REUSE 1 27 | #endif 28 | 29 | /* ----------------------Manual Configure----------------------------*/ 30 | #define SOCK_TYPE SOCK_STREAM | SOCK_NONBLOCK 31 | #define SOCK_MAGICNUM 0x00 32 | #define HTTP_MAGICNUM 0xAA 33 | #define TIME_MAGICNUM 0xBB 34 | 35 | #endif -------------------------------------------------------------------------------- /include/connect/Network/TAPManager.h: -------------------------------------------------------------------------------- 1 | #ifndef __TAP_CENTER__ 2 | #define __TAP_CENTER__ 3 | 4 | #include 5 | 6 | class TAPCenter; 7 | class ManagerBase; 8 | 9 | class TAPManager{ 10 | public: 11 | TAPManager(); 12 | void start(); 13 | void loadSubManager( std::unique_ptr sub ); 14 | private: 15 | std::shared_ptr ptr; 16 | }; 17 | 18 | #endif -------------------------------------------------------------------------------- /include/connect/Network/ThreadPool.h: -------------------------------------------------------------------------------- 1 | #ifndef THREAD_POOL_H 2 | #define THREAD_POOL_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | class ThreadPool { 15 | public: 16 | ThreadPool(size_t); 17 | template 18 | auto enqueue(F&& f, Args&&... args) 19 | -> std::future< decltype(f(args...)) >; 20 | ~ThreadPool(); 21 | private: 22 | // need to keep track of threads so we can join them 23 | std::vector< std::thread > workers; 24 | // the task queue 25 | std::queue< std::function > tasks; 26 | 27 | // synchronization 28 | std::mutex queue_mutex; 29 | std::condition_variable condition; 30 | bool stop = false; 31 | }; 32 | 33 | 34 | // add new work item to the pool 35 | template 36 | auto ThreadPool::enqueue(F&& f, Args&&... args) 37 | -> std::future< decltype(f(args...)) > 38 | { 39 | using return_type = decltype(f(args...)); 40 | 41 | auto task = std::make_shared< std::packaged_task >( 42 | std::bind(std::forward(f), std::forward(args)...) 43 | ); 44 | 45 | std::future res = task->get_future(); 46 | { 47 | std::unique_lock lock(queue_mutex); 48 | 49 | // don't allow enqueueing after stopping the pool 50 | if(stop) 51 | throw std::runtime_error("enqueue on stopped ThreadPool"); 52 | 53 | tasks.emplace( [=]{ (*task)(); } ); 54 | } 55 | condition.notify_one(); 56 | return res; 57 | } 58 | 59 | 60 | 61 | #endif -------------------------------------------------------------------------------- /include/connect/Network/URLParser.h: -------------------------------------------------------------------------------- 1 | #ifndef __URL_PARSER__ 2 | #define __URL_PARSER__ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | using EntryFunc = std::function; 10 | 11 | 12 | // non thread safe! 13 | class URLParser { 14 | private : 15 | URLParser() ; 16 | URLParser(const URLParser&) ; 17 | URLParser(const URLParser&&) ; 18 | URLParser& operator = (const URLParser&&) ; 19 | std::string_view static_url = ""; 20 | std::unordered_mapurl_table; 21 | public : 22 | 23 | static URLParser &getInstance() { 24 | static URLParser instance; 25 | return instance; 26 | } 27 | EntryFunc& URLparse( std::string_view _url) ; 28 | bool preCheck( std::string_view _url , std::string_view _method = "") noexcept; 29 | }; 30 | 31 | #endif -------------------------------------------------------------------------------- /include/connect/Timer/TimeLine.h: -------------------------------------------------------------------------------- 1 | #ifndef __TIME_L__ 2 | #define __TIME_L__ 3 | 4 | #include 5 | #include 6 | #include "TimerConfig.h" 7 | 8 | namespace ct = std::chrono; 9 | 10 | /* 11 | TimeLine Struct 12 | 13 | Real_o-> 14 | o--------*------*-----> 15 | | ratio1 \ 2 / 3 16 | o----------*--*-------> 17 | Virl_o-> 18 | 19 | WARNING: NOT tested Muti-Thread Safety; 20 | */ 21 | class TimeLine 22 | { 23 | using tag_T = ct::system_clock::time_point; 24 | public: 25 | const std::vector getVirtualTime(void); 26 | 27 | void changeRate(uint32_t new_R); 28 | uint32_t getRate(void) ; 29 | 30 | private: 31 | std::shared_mutex t_lock; 32 | 33 | tag_T server_epoch = ct::system_clock::now(); 34 | tag_T save_real = server_epoch; 35 | tag_T save_virl = server_epoch; 36 | 37 | uint32_t runtime_r = INIT_RATIO; 38 | }; 39 | 40 | #endif -------------------------------------------------------------------------------- /include/connect/Timer/Timer.h: -------------------------------------------------------------------------------- 1 | #ifndef __TIMER__ 2 | #define __TIMER__ 3 | 4 | #include 5 | 6 | class HttpRequest; 7 | class HttpResponseBase; 8 | 9 | namespace Timer 10 | { 11 | 12 | extern void setHeartResponse(HttpResponseBase* reps); 13 | 14 | extern HttpResponseBase* createComet(HttpRequest& req , HttpResponseBase* fail_res); 15 | 16 | extern void launchBroadCast(HttpResponseBase* reps); 17 | 18 | extern void changeTimeLineRate(uint32_t new_R); 19 | 20 | extern uint32_t getTimeLineRate(void); 21 | 22 | extern const std::vector getVirtualTime(void); 23 | 24 | }; 25 | 26 | #endif -------------------------------------------------------------------------------- /include/connect/Timer/TimerConfig.h: -------------------------------------------------------------------------------- 1 | #ifndef __TIMER_CONF__ 2 | #define __TIMER_CONF__ 3 | 4 | #include "../../generated/autoconf.h" 5 | 6 | #define INIT_RATIO CONFIG_INIT_RATIO 7 | #define TIME_ZONE CONFIG_TIME_ZONE 8 | #define HEART_TIMEOUT CONFIG_HEART_TIMEOUT 9 | 10 | 11 | #endif -------------------------------------------------------------------------------- /include/connect/Timer/TimerManager.h: -------------------------------------------------------------------------------- 1 | #ifndef __TIMER_M__ 2 | #define __TIMER_M__ 3 | 4 | #include 5 | #include 6 | #include "../Network/ManagerBase.h" 7 | #include "TimerConfig.h" 8 | 9 | 10 | namespace ct = std::chrono; 11 | using Rep_T = std::shared_ptr; 12 | 13 | class HttpAdapter; 14 | /* TimerTask center manager */ 15 | class TimerManager : public ManagerBase 16 | { 17 | public: 18 | TimerManager(); 19 | 20 | static TimerManager* getInstance(); 21 | 22 | bool listenConnect(Connection *conn); 23 | void broadCast(Rep_T reps); 24 | void modifyHeartResp(Rep_T new_heartq); 25 | 26 | virtual bool protocalConfirm(const int magic_n) override; 27 | virtual bool createTask(Connection* conn) override; 28 | 29 | private : 30 | TimerManager(const TimerManager&) = delete; 31 | TimerManager(const TimerManager&&) = delete; 32 | TimerManager& operator = (const TimerManager&) = delete; 33 | TimerManager& operator = (const TimerManager&&)= delete; 34 | 35 | inline static TimerManager* myself; 36 | inline static Rep_T heart_q; 37 | 38 | std::unordered_map connPool; 39 | std::unique_ptr wrapper; 40 | }; 41 | 42 | 43 | #endif -------------------------------------------------------------------------------- /include/interfaces.h: -------------------------------------------------------------------------------- 1 | #ifndef __MAIN_INTERFACE__ 2 | #define __MAIN_INTERFACE__ 3 | 4 | /*============== SUBMODULE INTERFACES ==============*/ 5 | /* 6 | In this head file , you shall make sure your submodule 7 | interfaces be included , so that the main module could 8 | invoke your submodule through the entry function defined 9 | in 'router.conf' 10 | */ 11 | 12 | /*----------------- Network Module ----------------- */ 13 | #include 14 | #include 15 | 16 | #include 17 | #include 18 | using namespace SimpleJson; 19 | 20 | ////simplize entry define 21 | #define def_HttpEntry(name , request) extern HttpResponseBase* (name)(HttpRequest &request) 22 | 23 | 24 | /*------------------- Timer Module -------------------*/ 25 | #include 26 | 27 | /*---------------- Hello-world Module ----------------*/ 28 | def_HttpEntry(Link_Start , request); 29 | def_HttpEntry(Lent_Book , req); 30 | def_HttpEntry(Icon , req); 31 | def_HttpEntry(Check_It , req); 32 | 33 | /*---------------------MD5 Module---------------------*/ 34 | #include 35 | def_HttpEntry(MD5Test,req); 36 | 37 | /*----------------- Data-Base Module -----------------*/ 38 | #include 39 | #include 40 | #include 41 | 42 | /*----------------- Vue/Axios Module-----------------*/ 43 | 44 | def_HttpEntry(Main,req); 45 | 46 | /* User Service */ 47 | def_HttpEntry(API_Signin,req); 48 | def_HttpEntry(API_Signup,req); 49 | 50 | /* Access Check */ 51 | def_HttpEntry(API_Access,req); 52 | /* DataBase Test */ 53 | def_HttpEntry(API_SQL_Test,req); 54 | def_HttpEntry(API_SQL , req); 55 | def_HttpEntry(API_SQL_Help , req); 56 | 57 | def_HttpEntry(API_Course, req); 58 | def_HttpEntry(API_File,req); 59 | 60 | def_HttpEntry(API_Class,req); 61 | def_HttpEntry(API_School,req); 62 | def_HttpEntry(API_Major,req); 63 | 64 | def_HttpEntry(API_User,req); 65 | def_HttpEntry(API_Timetable,req); 66 | def_HttpEntry(API_Event,req); 67 | 68 | def_HttpEntry(LogCheck,req); 69 | 70 | 71 | def_HttpEntry(API_Clock , req); 72 | 73 | def_HttpEntry(MapTest ,req); 74 | 75 | 76 | def_HttpEntry(FileUpload , req); 77 | #endif -------------------------------------------------------------------------------- /include/libs/BasicUtils.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __BASIC_UTILS_HPP__ 2 | #define __BASIC_UTILS_HPP__ 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | /** 9 | * @brief Basic Utils NameSpace 10 | * 11 | */ 12 | namespace UTILSTD{ 13 | 14 | /** 15 | * @brief LOG info at console 16 | * 17 | * @param timeSwitch print time 18 | * @param content printf content 19 | * @param ... printf args 20 | * @return void 21 | */ 22 | inline void CONSOLE_LOG(bool timeSwitch, std::string content, ...){ 23 | /* Time Print */ 24 | if(timeSwitch == 1){ 25 | time_t timer; 26 | time(&timer); 27 | char* str = ctime(&timer); 28 | str[strlen(str) - 1] = '\0'; 29 | printf("[%s CST] ", str); 30 | } 31 | 32 | va_list args; 33 | va_start(args, content); 34 | vprintf(content.c_str(), args); 35 | va_end(args); 36 | 37 | } 38 | 39 | 40 | /** 41 | * @brief erase space at head and tail of a string 42 | * 43 | * @param str string 44 | * @return std::string 45 | */ 46 | inline std::string Trim(std::string str){ 47 | std::string temp = str; 48 | temp.erase(0, temp.find_first_not_of(" ")); 49 | temp.erase(temp.find_last_not_of(" ") + 1); 50 | return temp; 51 | } 52 | 53 | /** 54 | * @brief split string by char 55 | * 56 | * @param str string 57 | * @param c split charactor 58 | * @param length splited number 59 | * @return std::string* splited string array 60 | */ 61 | inline std::string* Split(std::string& str, char c, int& length){ 62 | if(str.length() == 0){ 63 | length = 0; 64 | return nullptr; 65 | } 66 | int count = 1; // 拆分部分数量 67 | int index = 0; // 字符索引位置 68 | int l = str.length(); 69 | index = str.find(c, index); 70 | while(index < l && index >= 0){ 71 | count++; 72 | index++; 73 | index = str.find(c, index); 74 | } 75 | std::string* words = new std::string[count]; //拆分部分数组 76 | int start = 0, end = str.find(c, start); 77 | for(int i = 0; i < count; i++){ 78 | words[i] = Trim(str.substr(start, end - start)); 79 | start = end + 1; 80 | end = str.find(c, start); 81 | if(end == -1) end = str.length(); 82 | } 83 | length = count; 84 | return words; 85 | } 86 | 87 | 88 | 89 | 90 | /** 91 | * @brief quick sort template 92 | * 93 | * @tparam T 94 | * @param array array pointer 95 | * @param l sort start position 96 | * @param r sort end position 97 | */ 98 | template 99 | void q_sort(T** array, int l, int r){ 100 | if(l >= r) return; 101 | int blank = l + rand() % (r - l + 1); 102 | int i = l, j = r; 103 | T* key = array[blank]; 104 | while(i < j){ 105 | while(j > blank){ 106 | if(*(array[j]) < *key){ 107 | array[blank] = array[j]; 108 | blank = j; 109 | } 110 | else j--; 111 | } 112 | while(i < blank){ 113 | if(*(array[i]) > *key){ 114 | array[blank] = array[i]; 115 | blank = i; 116 | } 117 | else i++; 118 | } 119 | } 120 | array[blank] = key; 121 | q_sort(array, l, blank - 1); 122 | q_sort(array, blank + 1, r); 123 | } 124 | 125 | } 126 | 127 | #endif -------------------------------------------------------------------------------- /include/libs/HashMap.hpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | #define HASH_SIZE_DEFAULT 1024 9 | 10 | // Thread-Safe HashMap 11 | template 12 | class HashNode 13 | { 14 | public: 15 | K key; 16 | V value; 17 | HashNode* next = nullptr; 18 | 19 | HashNode(K _key, V _value) : key(_key) , value(_value) {} 20 | ~HashNode() {next = nullptr; }// ? 21 | 22 | HashNode(const HashNode&) = delete; 23 | HashNode(const HashNode&&) = delete; 24 | HashNode& operator=(const HashNode&) = delete; 25 | HashNode& operator=(const HashNode&&) = delete; 26 | 27 | }; 28 | 29 | template 30 | class HashBucket 31 | { 32 | private: 33 | HashNode* head = nullptr; 34 | HashNode* tail = nullptr; 35 | mutable std::shared_timed_mutex b_mutex; 36 | 37 | using iterator = HashNode*; 38 | public: 39 | 40 | ~HashBucket() {this->clear();} 41 | 42 | // Function to find an entry in the bucket matching the key 43 | iterator find(K _key) 44 | { 45 | std::shared_lock lock{b_mutex}; 46 | 47 | for (iterator node = head ; node != nullptr ; node = node->next) { 48 | if (node->key == _key) { 49 | return node; 50 | } 51 | } 52 | return nullptr; 53 | } 54 | 55 | 56 | 57 | // Function to insert into the bucket 58 | bool insert(const K _key, const V _value) 59 | { 60 | // Exclusive lock to enable single write in the bucket 61 | std::unique_lock lock{b_mutex}; 62 | 63 | if (head == nullptr) { 64 | tail = head = new HashNode {_key , _value}; 65 | return true; 66 | } 67 | 68 | for (iterator node = head ; node != nullptr ; node = node->next ) { 69 | if (node->key == _key) { 70 | return false; 71 | } 72 | } 73 | 74 | tail = tail->next = new HashNode {_key , _value}; 75 | 76 | return true; 77 | } 78 | 79 | // Function to remove an entry from the bucket 80 | bool erase(const K _key) 81 | { 82 | std::unique_lock lock{b_mutex}; 83 | 84 | for (iterator node = head , prev = nullptr ; 85 | node != nullptr ; 86 | node = node->next) { 87 | 88 | if (node->key == _key) { 89 | prev->next = node->next; 90 | delete node; 91 | return true; 92 | } 93 | prev = node; 94 | } 95 | 96 | return false; 97 | } 98 | 99 | // Function to clear the bucket 100 | void clear() 101 | { 102 | std::unique_lock lock{b_mutex}; 103 | 104 | for (iterator node = head , prev = nullptr ; 105 | node != nullptr ; 106 | node = node->next) { 107 | 108 | if (prev != nullptr) { 109 | delete prev; 110 | } 111 | prev = node; 112 | } 113 | 114 | tail = head = nullptr; 115 | } 116 | 117 | 118 | }; 119 | 120 | template < 121 | typename K, 122 | typename V, 123 | size_t _table_size = HASH_SIZE_DEFAULT, 124 | typename F = std::hash 125 | > 126 | class HashMap 127 | { 128 | private: 129 | HashBucket *hashTable; 130 | F hasher; 131 | size_t table_size = 0; 132 | std::atomic node_num ; 133 | 134 | public: 135 | using iterator = HashNode*; 136 | inline static const iterator npos = nullptr; 137 | 138 | HashMap() : table_size(_table_size) { 139 | node_num = 0; 140 | hashTable = new HashBucket[_table_size]; // create the hash table as an array of hash buckets 141 | } 142 | 143 | ~HashMap() { 144 | delete[] hashTable; 145 | } 146 | // Copy and Move of the HashMap are not supported at this moment 147 | HashMap(const HashMap&) = delete; 148 | HashMap(const HashMap&&) = delete; 149 | HashMap& operator=(const HashMap&) = delete; 150 | HashMap& operator=(const HashMap&&) = delete; 151 | 152 | size_t size() const {return node_num;} 153 | bool empty() const {return !node_num;} 154 | 155 | 156 | V operator[](K key) { 157 | size_t hashValue = hasher(key) % table_size; 158 | return (hashTable[hashValue].find(key))->value; 159 | } 160 | // Function to find an entry in the hash map matching the key. 161 | iterator find(K key) noexcept 162 | { 163 | size_t hashValue = hasher(key) % table_size; 164 | return hashTable[hashValue].find(key); 165 | } 166 | 167 | // Function to insert into the hash map. 168 | bool insert(const K key, const V value) 169 | { 170 | size_t hashValue = hasher(key) % table_size; 171 | return hashTable[hashValue].insert(key, value) ? 172 | ({node_num++; true;}) : false; 173 | } 174 | 175 | // Function to remove an entry from the bucket, if found 176 | bool erase(const K key) 177 | { 178 | size_t hashValue = hasher(key) % table_size; 179 | return hashTable[hashValue].erase(key) ? 180 | ({node_num--; true;}) : false; 181 | } 182 | 183 | // Function to clean up the hasp map, i.e., remove all entries from it 184 | void clear() 185 | { 186 | for (size_t i = 0; i < table_size; i++) { 187 | (hashTable[i]).clear(); 188 | } 189 | } 190 | 191 | }; 192 | -------------------------------------------------------------------------------- /include/libs/Heap.hpp: -------------------------------------------------------------------------------- 1 | #ifndef HEAP_H 2 | #define HEAP_H 3 | 4 | #include 5 | #include 6 | #include 7 | //小根堆实现 8 | template 9 | class Heap { 10 | private: 11 | size_t heapLength , lastPos; 12 | T *heapNode ; 13 | 14 | public: 15 | Heap():heapLength(1) , lastPos(1){ 16 | heapNode = (T*)malloc(sizeof(T)); 17 | } 18 | ~Heap() { 19 | free(heapNode); 20 | } 21 | //输出堆内容 22 | void print() ; 23 | //判断堆是否为空 24 | bool empty() const ; 25 | //输出堆顶的元素 26 | T top() const ; 27 | //把一个节点放入堆中 28 | void push(T node); 29 | //删除堆顶元素 30 | void pop() ; 31 | }; 32 | 33 | template 34 | void Heap::print() { 35 | printf("lastPos : %d \n" ,lastPos); 36 | for(size_t i = 1 ; i < lastPos ; i++) { 37 | printf("%d " ,heapNode[i]); 38 | }printf("\n"); 39 | } 40 | 41 | template 42 | bool Heap::empty() const { 43 | return (lastPos == 1); 44 | } 45 | 46 | template 47 | T Heap::top() const { 48 | return heapNode[1]; 49 | } 50 | 51 | template 52 | void Heap::push(T node) { 53 | if(heapLength == lastPos) { 54 | try { 55 | heapLength <<= 1; 56 | heapNode = (T*)realloc(heapNode , sizeof(T) *heapLength); 57 | } 58 | catch(const std::bad_alloc& e) { 59 | std::cerr << e.what() << '\n'; 60 | } 61 | } 62 | heapNode[lastPos++] = node; 63 | for(size_t nowPos = lastPos-1; nowPos > 1 ;){ 64 | if(heapNode[nowPos] < heapNode[nowPos >> 1]) 65 | std::swap(heapNode[nowPos] , heapNode[nowPos >> 1]) , nowPos >>= 1; 66 | else break; 67 | } 68 | } 69 | 70 | template 71 | void Heap::pop() { 72 | std::swap(heapNode[--lastPos] , heapNode[1]); 73 | for(size_t nowPos = 1 ; nowPos <<= 1 ; ) { 74 | if( nowPos+1 < lastPos && heapNode[nowPos+1] < heapNode[nowPos] ) nowPos++; 75 | if( nowPos < lastPos && heapNode[nowPos] < heapNode[nowPos >> 1]) 76 | std::swap(heapNode[nowPos >> 1] , heapNode[nowPos]); 77 | else break; 78 | } 79 | } 80 | 81 | #endif -------------------------------------------------------------------------------- /include/libs/md5.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | #define F(x, y, z) ((x & y) | (~x & z)) 8 | #define G(x, y, z) ((x & z) | (y & ~z)) 9 | #define H(x, y, z) (x ^ y ^ z) 10 | #define I(x, y, z) (y ^ (x | ~z)) 11 | #define shift(x, n) ((x << n) | (x >> (32 - n))) 12 | 13 | #define FF(a, b, c, d, x, s, ac) a = b + ((shift((a + F(b, c, d) + x + ac), s))) 14 | #define GG(a, b, c, d, x, s, ac) a = b + ((shift((a + G(b, c, d) + x + ac), s))) 15 | #define HH(a, b, c, d, x, s, ac) a = b + ((shift((a + H(b, c, d) + x + ac), s))) 16 | #define II(a, b, c, d, x, s, ac) a = b + ((shift((a + I(b, c, d) + x + ac), s))) 17 | 18 | #define A seq[0] 19 | #define B seq[1] 20 | #define C seq[2] 21 | #define D seq[3] 22 | 23 | int md5_process(std::string f, uint8_t (&final)[17]); 24 | int md5_calculate(uint32_t (&seq)[4], const uint32_t buff[]); 25 | std::string md5(std::string f); 26 | 27 | int get_file_len(fstream &f); 28 | int md5_process(fstream &f, uint8_t (&final)[17]); 29 | std::string md5(fstream &f); -------------------------------------------------------------------------------- /include/router.conf: -------------------------------------------------------------------------------- 1 | /* 2 | Function prototype: 3 | ADD_URL( URL_PATH , ENTRY_NAME ); 4 | 5 | This Function will bind a string of http url path to your 6 | module entry function. At the time of receiving a request 7 | from http client , url parser will forward it to your own 8 | function with same name depends on above regulars. 9 | All these function are build-in. 10 | 11 | 这些函数将会把一个HTTP URL字符串与你的模块入口函数绑定,当 12 | 服务器接收到一个来自HTTP客户端的请求时,URL解析器会根据下面 13 | 的规则将请求转发至你同名的入口函数。 14 | 这些函数都是内建的 15 | */ 16 | 17 | /* System */ 18 | ADD_URL("/", Main); 19 | ADD_URL("/clock" , API_Clock); 20 | 21 | /* SQL */ 22 | ADD_URL("/sql", API_SQL); 23 | 24 | /* Sign */ 25 | ADD_URL("/signin", API_Signin); 26 | ADD_URL("/signup",API_Signup); 27 | 28 | /* Course */ 29 | ADD_URL("/course",API_Course); 30 | ADD_URL("/file",API_File); 31 | 32 | /* User */ 33 | ADD_URL("/access",API_Access); 34 | ADD_URL("/user",API_User); 35 | ADD_URL("/timetable",API_Timetable); 36 | ADD_URL("/event",API_Event); 37 | 38 | /* Class */ 39 | ADD_URL("/school",API_School); 40 | ADD_URL("/major",API_Major); 41 | ADD_URL("/class",API_Class); 42 | 43 | /* Other Test */ 44 | ADD_URL("/sql/help", API_SQL_Help); 45 | ADD_URL("/sql/test",API_SQL_Test); 46 | ADD_URL("/log",LogCheck); 47 | ADD_URL("/start" , Link_Start ); 48 | ADD_URL("/borrowbook" , Lent_Book); 49 | ADD_URL("/checkit" ,Check_It); 50 | ADD_URL("/md5",MD5Test); 51 | ADD_URL("/map",MapTest); 52 | ADD_URL("/upload" , FileUpload); -------------------------------------------------------------------------------- /include/service/ClockSys.h: -------------------------------------------------------------------------------- 1 | #ifndef __CLOCK_SYS__ 2 | #define __CLOCK_SYS__ 3 | 4 | #include 5 | #include 6 | 7 | namespace TimeStatus 8 | { 9 | enum TimeStatus { 10 | SUCC , 11 | BROAD, 12 | DUP, 13 | ERR 14 | }; 15 | } 16 | 17 | #endif -------------------------------------------------------------------------------- /include/service/Event.h: -------------------------------------------------------------------------------- 1 | #ifndef __SCHEDULE_CONTROL_H__ 2 | #define __SCHEDULE_CONTROL_H__ 3 | #include 4 | #include 5 | #define WEEK_NUM_TERM 20 6 | 7 | #define SET_TIME(code,timenum) ({code |= (1 << (timenum-1));}) 8 | #define WEEK_CHECK(weeks,week) ({(weeks >> (week-1)) & 0x1;}) 9 | 10 | class Course{ 11 | private: 12 | std::string id; 13 | std::string name; 14 | std::string time; 15 | std::string intro; 16 | public: 17 | Course(std::string id = "0"); 18 | int Query(bool intro = true); 19 | SimpleJson::Object Format(); 20 | int AddNew(std::string& detail,std::string& intro); 21 | Json getFile(std::string& prof); 22 | int Remove(); 23 | int AddWork(std::string& prof,std::string& classid,std::string& detail); 24 | Json getWork(std::string& prof,std::string& classid); 25 | int AddExam(std::string& detail); 26 | Json getExam(std::string& school,bool all = false); 27 | string getName(){return name;} 28 | string getTime(){return time;} 29 | Json getAll(); 30 | }; 31 | 32 | class Event{ 33 | private: 34 | std::string id; 35 | std::string start; 36 | std::string end; 37 | std::string name; 38 | std::string location; 39 | std::string info; 40 | std::string notice; 41 | public: 42 | Event(std::string id="0"); 43 | int Parse(std::string detail); 44 | SimpleJson::Object Format(); 45 | }; 46 | 47 | #endif -------------------------------------------------------------------------------- /include/service/NaviSys.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "../data/maps/navi_info.h" 7 | 8 | #include "../data/maps/shahe_walking.h" 9 | #include "../data/maps/shahe_bike.h" 10 | #include "../data/maps/shahe_walking_busy.h" 11 | 12 | #include "../data/maps/xtc_walking.h" 13 | #include "../data/maps/xtc_bike.h" 14 | #include "../data/maps/xtc_walking_busy.h" 15 | 16 | #define CALC_UNITS(arr) ( sizeof(arr) / sizeof(arr[0][0]) ) 17 | #define CALC_WIDTH(arr) ( sizeof(arr[0]) / sizeof(arr[0][0]) ) 18 | #define CALC_HEIGHT(arr) ( CALC_UNITS(arr) / CALC_WIDTH(arr) ) 19 | 20 | constexpr int SHAHE_MAX_HEIGHT = CALC_HEIGHT(shahe_walking); 21 | constexpr int SHAHE_MAX_WIDTH = CALC_WIDTH(shahe_walking); 22 | 23 | constexpr int XTC_MAX_HEIGHT = CALC_HEIGHT(xtc_walking); 24 | constexpr int XTC_MAX_WIDTH = CALC_WIDTH(xtc_walking); 25 | 26 | #define WALKABLE 0 27 | #define INF 0xfffffff 28 | 29 | static constexpr int dx[] = { 0, 0,-1, 1}; 30 | static constexpr int dy[] = {-1, 1, 0, 0}; 31 | 32 | constexpr size_t arrLen = (sizeof(dx) / sizeof(int)); 33 | 34 | struct Point2D { 35 | int x = 0; 36 | int y = 0; 37 | int dis = INF; 38 | Point2D* parent = nullptr; 39 | }; 40 | 41 | enum EvalueMode { 42 | SHORT_PATH , 43 | SHORT_TIME , 44 | SHORT_BIKE 45 | }; 46 | 47 | enum MapValue { 48 | SH, 49 | XTC 50 | }; -------------------------------------------------------------------------------- /include/service/TAPSystem.h: -------------------------------------------------------------------------------- 1 | #ifndef __SERVER_SYS_H__ 2 | #define __SERVER_SYS_H__ 3 | #include 4 | #include 5 | 6 | 7 | extern NEDBSTD::NEDB __DATABASE; //系统资源数据库 8 | extern std::string PROJECT_DIR; //项目路径 9 | extern std::string SYS_DIR; //系统路径 10 | extern std::string USER_DIR; //用户路径 11 | extern std::string SRC_DIR; //资源路径 12 | extern std::string TIME_STAMP; //启动时间 13 | 14 | #define TOKEN_ACCESS 1 15 | #define TOKEN_DENIED 0 16 | 17 | void TimeStampReset(); 18 | void DirectoryInit(); 19 | void ServicePreload(); 20 | void SQLTestGenerate(); 21 | 22 | std::string TokenSign(std::string userid); 23 | int TokenCheck(std::string userid,std::string token); 24 | 25 | #endif -------------------------------------------------------------------------------- /include/service/User.h: -------------------------------------------------------------------------------- 1 | #ifndef __USER_CONTROL_H__ 2 | #define __USER_CONTROL_H__ 3 | #include 4 | #include 5 | 6 | #define USER_ADMIN 3 7 | #define USER_SCHOOL 2 8 | #define USER_CLASS 1 9 | #define USER_COMMON 0 10 | 11 | class User{ 12 | protected: 13 | std::string id; 14 | std::string name; 15 | int auth; 16 | std::string gender; 17 | std::string majorid; 18 | std::string majorName; 19 | std::string schoolid; 20 | std::string schoolName; 21 | std::string classid; 22 | public: 23 | User(std::string id = "0"); 24 | std::string getSchool(){return schoolid;} 25 | std::string getName(){return name;} 26 | int Query(bool detail_name = true); 27 | Json Format(); 28 | int Signin(std::string& passwd); 29 | int Signup(std::string& passwd); 30 | int Update(std::string& value); 31 | int AddNew(std::string& detail); 32 | int ChangePwd(std::string& pwd); 33 | 34 | //Event Service 35 | Json getEvents(); 36 | int addEvent(std::string& value); 37 | int delEvent(std::string& id); 38 | int addNotice(std::string&id,std::string& code); 39 | 40 | //Resource 41 | 42 | //TimeTable Service 43 | Json getTimeTable(); 44 | }; 45 | 46 | class Professor:public User{ 47 | public: 48 | Professor(std::string id = ""):User(id){}; 49 | int AddHomework(std::string& detail); 50 | int DelHomework(std::string& detail); 51 | 52 | }; 53 | 54 | class Class{ 55 | private: 56 | std::string id; 57 | std::string schoolid; 58 | 59 | public: 60 | Class(std::string classid); 61 | int Query(); 62 | std::string getSchool(){return schoolid;} 63 | int getMemberNum(); 64 | Json getTimeTable(string schoolid="",string prof=""); 65 | Json getList(); 66 | int AddNew(std::string school); 67 | int AddCourse(std::string& courseid,std::string& prof,std::string& detail); 68 | 69 | }; 70 | 71 | 72 | #endif 73 | -------------------------------------------------------------------------------- /include/test/define.h: -------------------------------------------------------------------------------- 1 | #ifndef TEST 2 | #define TEST 3 | 4 | #include 5 | #include 6 | std::string getGMTtime(uint32_t offset = 0); 7 | #pragma GCC diagnostic ignored "-Wnarrowing" 8 | #pragma GCC diagnostic ignored "-Wunused-variable" 9 | 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /lib/libnedb.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/lib/libnedb.a -------------------------------------------------------------------------------- /scripts/build.mk: -------------------------------------------------------------------------------- 1 | OBJS = $(subst cpp,o,$(subst src,$(OBJ_DIR),$(SOURCES))) 2 | 3 | .DEFAULT_GOAL := root 4 | 5 | root : .detect $(PACKAGE) 6 | @echo "$(C_GREEN)[$(shell date +%F%n%T)] Compile Complete!$(C_END)" 7 | 8 | -include $(OBJS:.o=.d) 9 | 10 | $(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp 11 | @echo + CXX $< 12 | @mkdir -p $(dir $@) 13 | @$(CXX) $(CXXFLAGS) $(INCLUDES) -c -o $@ $< 14 | @$(CXX) $(INCLUDES) $< -MM -MF $(subst .o,.d,$@) -MT $@ -MT $(subst .o,.d,$@) 15 | 16 | $(PACKAGE): $(OBJS) 17 | @echo + LD $@ 18 | @$(CXX) $(CXXFLAGS) $(INCLUDES) -o $@ $(OBJS) $(LDFLAGS) $(DATABASE) 19 | 20 | .PHONY: run root 21 | 22 | run : .detect $(PACKAGE) 23 | @echo "$(C_BLUE)[$(shell date +%F%n%T)] RUNNING...$(C_END)" 24 | @$(PACKAGE) $(MAINARGS) 25 | @echo "$(C_GREEN)[$(shell date +%F%n%T)] SUCCESSFUL RUNNING$(C_END)" 26 | 27 | -------------------------------------------------------------------------------- /scripts/colors.mk: -------------------------------------------------------------------------------- 1 | C_END := \033[0m 2 | 3 | C_RED := \033[31;1m 4 | C_GREEN := \033[32;1m 5 | C_YELLOW:= \033[33;1m 6 | C_BLUE := \033[36;1m 7 | 8 | COLOR_RED := $(shell echo "\033[1;31m") 9 | COLOR_END := $(shell echo "\033[0m") 10 | -------------------------------------------------------------------------------- /scripts/config.mk: -------------------------------------------------------------------------------- 1 | Q := @ 2 | KCONFIG_PATH := $(WORK_DIR)/utils/kconfig 3 | Kconfig := $(WORK_DIR)/Kconfig 4 | rm-distclean += include/generated include/config .config .config.old 5 | silent := -s 6 | 7 | CONF := $(KCONFIG_PATH)/build/conf 8 | MCONF := $(KCONFIG_PATH)/build/mconf 9 | 10 | $(CONF): 11 | $(Q)$(MAKE) $(silent) -C $(KCONFIG_PATH) NAME=conf 12 | 13 | $(MCONF): 14 | $(Q)$(MAKE) $(silent) -C $(KCONFIG_PATH) NAME=mconf 15 | 16 | menuconfig: $(MCONF) $(CONF) 17 | $(Q)$(MCONF) $(Kconfig) 18 | $(Q)$(CONF) $(silent) --syncconfig $(Kconfig) 19 | 20 | savedefconfig: $(CONF) 21 | $(Q)$< $(silent) --$@=configs/defconfig $(Kconfig) 22 | 23 | %defconfig: $(CONF) 24 | $(Q)$< $(silent) --defconfig=configs/$@ $(Kconfig) 25 | $(Q)$< $(silent) --syncconfig $(Kconfig) 26 | 27 | .PHONY: menuconfig savedefconfig defconfig 28 | 29 | # Help text used by make help 30 | help: 31 | @echo ' menuconfig - Update current config utilising a menu based program' 32 | @echo ' savedefconfig - Save current config as configs/defconfig (minimal config)' 33 | 34 | distclean: clean 35 | -@rm -rf $(rm-distclean) 36 | 37 | .PHONY: help distclean 38 | -------------------------------------------------------------------------------- /scripts/doc.md: -------------------------------------------------------------------------------- 1 | <----Project Doc----> -------------------------------------------------------------------------------- /scripts/intro.md: -------------------------------------------------------------------------------- 1 | ![intro](../utils/pic1.png) 2 | ![avatar](https://badgen.net/badge/Language/C++17/orange) 3 | ![stars](https://badgen.net/badge/Dev%20Env./Linux/green) 4 | ![license](https://badgen.net/badge/License/Apache-2.0/blue) 5 | # **TinyAndPretty 小而美的网络服务框架** 6 | TinyAndPretty(TAP)是使用`Modern C++(11/14/17)`开发的网络服务框架,它秉持简单、易用、可扩展易开发的原则,帮助你快速构建~~可靠~~的``C++``后台服务。 7 | 8 | ## 分层的微核架构 ## 9 | TAP主体采用[微核架构](http://www.ruanyifeng.com/blog/2016/09/software-architecture.html)`(microkernel architecture)`,又称为"插件架构"`(plug-in architecture)`。TAP Center Manager(TAP中枢管理员)会负责系统整体的初始化、子管理员(plugins)的协调与调度,主要功能和业务逻辑都通过插件实现。 10 | * 良好的功能延伸性`(extensibility)`,需要什么功能,开发一个插件即可. 11 | * 功能之间是隔离的,插件可以独立的加载和卸载,使得它比较容易部署. 12 | * 可定制性高,适应不同的开发需要 13 | * 可以渐进式地开发,逐步增加功能 14 | 15 | ## UNIX友好的配置方式 ## 16 | 移植了`Kconfig`系统,在纯命令行环境下也有对人类友好的配置体验,可视化界面充分展示系统的所有参数细节。 17 | 18 | ## 纯粹事件驱动模型 ## 19 | 依托`Linux`系统高效的`Epoll`功能和`C++17`强大的泛型支持,本框架中的`Event Pool`支持了**事件管道**级别的抽象,将数据挂载和文件描述符监听结合起来,同时配合`timer fd`完成了纳米级定时事件的处理。 20 | 21 | 这一模型中,`TAP Center Manager`充当了总线功能,通过对插件的预设**模块魔数**进行判断完成调度。`Timer Manager`也被纳入这一框架中,通过`TimeLine`这一数据结构完成虚拟时间和现实时间的转换,省去了线程轮询的过程极大提高了CPU使用率。 22 | 23 | ## 易用的HTTP/1.1 + COMET ## 24 | 本框架支持了`HTTP` GET、POST、**multipart/form-data**、**Static Resource**等常见请求形式,并在此基础上实现了`COMET`长连接服务的支持,使得~~在懂得都懂的情况下的~~服务器获得了主动向客户端推送广播的能力。 25 | 26 | 同时基于`Modern C++`的现代语言功能,框架推荐支持`std::filesystem` 和 `std::chrono`等在内的现代库,充分使用`std::tuple`、`std::initialize_list`和结构化绑定联动的方式,简化了大量的操作流程,配置`HTTP`服务变得人性化,这一点在实际的线上项目开发中得到了检验。 27 | 28 | 同时`HTTP`响应服务支持了字符串类型的`HttpResponse`、经由`sendfile()`优化过的`FileResponse`、自主开发的`JsonResponse`。充分考虑多种常见实际业务情况。 29 | 30 | ## Reactor模型的单进程多线程服务 ## 31 | 本项目在启动初期就把超好用的并发服务的作为重要目标之一。为此移植了简洁好用的`Thread Pool`,同时使用了`RAII`风格的`std::unique_lock`/`std::shared_lock`操作`std::shared_mutex`等锁。整体高效使用。 32 | 33 | 34 | ## 未来提升的方向 ## 35 | 1. ~~多半咕咕,没有未来~~ 36 | 2. 分布式支持 37 | 3. `Linux`下自有网络协议栈 38 | 4. `WebSocket` 和 `HTTP/2` 的支持 39 | 5. ~~BUG FREE~~ 40 | 41 | 42 | 43 | ## 自动化指令说明 ## 44 | 在项目文件夹根目录下使用如下指令,可快速使用相应功能。 45 | * i . 编译全部工程. 46 | ``` 47 | $ make 48 | ``` 49 | * ii . 编译并运行。 50 | ``` 51 | $ make run 52 | ``` 53 | 54 | * iii . 清除`build`编译文件夹。`disrclean`可清除`menuconfig`生成的配置文件。 55 | ``` 56 | $ make (dist)?clean 57 | ``` 58 | * iv . 启动菜单配置,调整程序运行参数 59 | ``` 60 | $ make menuconfig 61 | ``` 62 | * v . 添加参数`MODS`可仅使选择的模块编译到工程中。 63 | ``` 64 | $ make MODS="module1 module2" (run)? 65 | ``` 66 | * vi. 添加参数`MAINARGS`可添加运行时命令行参数到`main()`函数中。 67 | ``` 68 | $ make MAINARGS="sql.db" run 69 | ``` 70 | * vii. 多线程编译,加快编译速度。如`-j2`双线程编译 71 | ``` 72 | $ make -j(\d*) 73 | ``` 74 | 75 | ## 添加模块说明 ## 76 | `src/`目录下的每一个文件夹为一个独立的模块,脚本将自动检测该***目录下*** 的子文件夹并进行编译链接。 77 | * i . 请在`include`文件夹下创建`$(MODULE_NAME)`子目录,用于存放该模块的头文件(即接口) 78 | * ii . 在该文件夹下定义`interface.h`文件,标识为该模块的调用接口。如若对该模块进行调用,请在代码中进行如下引用 79 | ```c++ 80 | #include <$(MODULE_NAME)/interface.h> 81 | ``` 82 | * iii . 在`include/router.conf`中配置路由信息 83 | * iii . 创建`src/$(MODULE_NAME)`子目录,并再次实现模块功能。 84 | * vi . 在`scripts`文件夹下存放对应的文档(可选)。 85 | -------------------------------------------------------------------------------- /scripts/mid-term repo.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/scripts/mid-term repo.pptx -------------------------------------------------------------------------------- /src/controller/ClassController.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | using namespace NEDBSTD; 6 | using namespace UTILSTD; 7 | 8 | Class::Class(string classid){ 9 | this->id = classid; 10 | } 11 | 12 | int Class::Query(){ 13 | int count, errCode; 14 | string retVal; 15 | errCode = __DATABASE.Select("classes", "school", "id = " + id, count, retVal); 16 | if(count == 0) schoolid = "0"; 17 | else schoolid = retVal.substr(retVal.find(';') + 1); 18 | return errCode; 19 | } 20 | 21 | Json Class::getTimeTable(string schoolid, string prof){ 22 | int count, len, length; 23 | string retVal; 24 | if(schoolid.length() == 0){ 25 | Query(); 26 | schoolid = this->schoolid; 27 | } 28 | NEDB _DB("/"); 29 | if(prof.length() == 0){ 30 | _DB.SetDir(USER_DIR + "/" + schoolid); _DB.Mount("timetable"); 31 | _DB.Select("timetable", "*", "id > " + id + "000 and id < " + id + "999", count, retVal); 32 | } 33 | else{ 34 | _DB.SetDir(USER_DIR + "/" + schoolid + "/0/" + prof); _DB.Mount("timetable"); 35 | _DB.Select("timetable", "*", "", count, retVal); 36 | } 37 | _DB.Close(); 38 | 39 | Json J; 40 | if(count == 0) return J; 41 | vector courses; 42 | 43 | string* str = Split(retVal, ';', len); 44 | for(int i = 1; i < len; i++){ 45 | string* info = Split(str[i], ',', length); 46 | Course course(info[1]); course.Query(false); 47 | User user(info[2]); user.Query(false); 48 | vector Tcode; 49 | for(int i = 3; i <= 7; i++){ 50 | Tcode.push_back(stoi(info[i])); 51 | } 52 | __DATABASE.Select("landmark", "name", "id=" + info[8], count, retVal); 53 | string location = retVal.substr(retVal.find(';') + 1); 54 | int classid = stoll(info[0]) / 1000; 55 | courses.push_back({ 56 | {"id",stoi(info[1])}, 57 | {"class",classid}, 58 | {"name",course.getName()}, 59 | {"profid",stoi(info[2])}, 60 | {"profname",user.getName()}, 61 | {"wcode",course.getTime()}, 62 | {"tcode",Tcode}, 63 | {"location",location}, 64 | {"room",info[9]}, 65 | {"contact",info[10]} 66 | }); 67 | delete[] info; 68 | } 69 | J.push_back({"courses",courses}); 70 | delete[] str; 71 | return J; 72 | } 73 | 74 | Json Class::getList(){ 75 | string ret; int count, len, length; 76 | int errCode = __DATABASE.Select("classes", "*", "", count, ret); 77 | Json J; 78 | if(errCode == NO_ERROR){ 79 | ret = ret.substr(ret.find_first_of(";") + 1); 80 | ret = ret.substr(ret.find_first_of(";") + 1); 81 | string* str = Split(ret, ';', len); 82 | vector js; 83 | for(int i = 0; i < len; i++){ 84 | string* temp = Split(str[i], ',', length); 85 | js.push_back({ 86 | {"id",stoi(temp[0])}, 87 | {"school",stoi(temp[1])} 88 | }); 89 | delete[] temp; 90 | } 91 | delete[] str; 92 | J.push_back({"data",js}); 93 | } 94 | return J; 95 | } 96 | 97 | int Class::AddCourse(std::string& courseid, std::string& prof, std::string& detail){ 98 | int errCode, count; string ret; 99 | if(__DATABASE.Select("courses", "id", "id=" + courseid, count, ret) != NO_ERROR){ 100 | return DATA_NOT_FOUND; 101 | } 102 | Query(); 103 | string dir = USER_DIR + "/" + schoolid; 104 | NEDB _DB(dir); 105 | errCode = _DB.Mount("timetable"); 106 | if(errCode == FILE_NOT_FOUND){ 107 | _DB.DirInit(); 108 | _DB.SetDefaultPageSize(1000); 109 | _DB.Create("timetable", "id int64,course int,prof int,D1 int,D2 int,D3 int,D4 int,D5 int,loc int,room int,contact int64"); 110 | } 111 | _DB.Close(); 112 | 113 | string info(courseid + "," + prof + "," + detail); 114 | NEDB _DB2(dir); _DB2.Mount("timetable"); 115 | errCode = _DB2.Select("timetable", "id", "id > " + id + "000 and id < " + id + "999", count, ret); 116 | if(count < 9) info = id + ("00" + to_string(count + 1)) + "," + info; 117 | else if(count < 99) info = id + ("0" + to_string(count + 1)) + "," + info; 118 | else if(count < 999) info = id + to_string(count) + "," + info; 119 | errCode = _DB2.Insert("timetable", "", info); 120 | _DB2.Close(); 121 | 122 | User user(prof); 123 | user.Query(); 124 | string dir2 = USER_DIR + "/" + user.getSchool() + "/0/" + prof; 125 | NEDB DB(dir2); 126 | errCode = DB.Mount("timetable"); 127 | if(errCode == FILE_NOT_FOUND){ 128 | DB.DirInit(); 129 | DB.SetDefaultPageSize(800); 130 | DB.Create("timetable", "id int64,course int,prof int,D1 int,D2 int,D3 int,D4 int,D5 int,loc int,room int,contact int64"); 131 | } 132 | DB.Close(); 133 | 134 | NEDB DB2(dir2); DB2.Mount("timetable"); 135 | errCode = DB2.Insert("timetable", "", info); 136 | 137 | if(errCode == NO_ERROR){ 138 | DB2.SetDir(SRC_DIR + "/course/" + courseid + "/" + prof); 139 | DB2.DirInit(); 140 | } 141 | DB2.Close(); 142 | return errCode; 143 | } 144 | 145 | 146 | int Class::AddNew(string school){ 147 | NEDB _DB(SRC_DIR + "/school/"); 148 | _DB.Mount("classes"); 149 | int errCode = _DB.Insert("classes", "", id + "," + school); 150 | if(errCode != NO_ERROR){ 151 | return errCode; 152 | } 153 | _DB.SetDir(USER_DIR + "/" + school + "/" + id); 154 | errCode = _DB.DirInit(); 155 | _DB.Close(); 156 | return errCode; 157 | } 158 | 159 | int Class::getMemberNum(){ 160 | NEDB DB(USER_DIR); 161 | 162 | if(DB.Mount("users") != NO_ERROR) return 0; 163 | int count; string ret; 164 | DB.Select("users", "id", "class = " + this->id, count, ret); 165 | return count; 166 | } -------------------------------------------------------------------------------- /src/controller/EventController.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | using namespace NEDBSTD; 5 | using namespace UTILSTD; 6 | 7 | Event::Event(string id){ 8 | this->id = id; 9 | } 10 | 11 | int Event::Parse(string detail){ 12 | int length; 13 | string *info = Split(detail,',',length); 14 | if(detail == "" || length != 7){ 15 | delete [] info; 16 | return PARAM_FORM_ERROR; 17 | } 18 | /* Fill Details */ 19 | //ID 20 | this->id = info[0]; 21 | 22 | //Start 23 | this->start = info[1]; 24 | 25 | //End 26 | this->end = info[2]; 27 | 28 | this->notice = info[3]; 29 | 30 | //Get Location Name 31 | int count; 32 | string retVal; 33 | __DATABASE.Select("landmark","name","id="+info[4],count,retVal); 34 | this->location = retVal.substr(retVal.find(';')+1); 35 | 36 | //Name 37 | this->name = info[5]; 38 | 39 | //Describe 40 | this->info = info[6]; 41 | 42 | 43 | 44 | delete [] info; 45 | return NO_ERROR; 46 | } 47 | 48 | SimpleJson::Object Event::Format(){ 49 | SimpleJson::Object J({ 50 | {"id",id.c_str()}, 51 | {"name",name.c_str()}, 52 | {"start",start.c_str()}, 53 | {"end",end.c_str()}, 54 | {"loc",location.c_str()}, 55 | {"info",info.c_str()}, 56 | {"notice",stoi(notice)} 57 | }); 58 | return J; 59 | } 60 | 61 | -------------------------------------------------------------------------------- /src/controller/UserController.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | using namespace NEDBSTD; 6 | using namespace UTILSTD; 7 | 8 | User::User(string id) 9 | { 10 | this->id = id; 11 | auth = USER_COMMON; 12 | } 13 | 14 | int User::Signin(string& passwd) 15 | { 16 | int count; 17 | string retVal; 18 | int errCode = __DATABASE.Select("token", "passwd", "id=" + id, count, retVal); 19 | if(errCode != 0) 20 | { 21 | return errCode; 22 | } 23 | retVal = retVal.substr(retVal.find(";") + 1); 24 | if(passwd != retVal) 25 | { 26 | return -1; 27 | } 28 | Query(); 29 | if(auth < USER_SCHOOL && (schoolid == "0" || classid == "0")) 30 | { 31 | return -2; 32 | } 33 | return NO_ERROR; 34 | } 35 | 36 | int User::Signup(string& passwd) 37 | { 38 | int errCode1 = __DATABASE.Insert("token", "", id + "," + passwd + ",0"); 39 | if(errCode1 != NO_ERROR) 40 | { 41 | return errCode1; 42 | } 43 | return __DATABASE.Insert("users", "id,auth", id + "," + to_string(auth)); 44 | } 45 | 46 | int User::ChangePwd(std::string& pwd) 47 | { 48 | int count; 49 | return __DATABASE.Update("token", "passwd = " + pwd, "id = " + id, count); 50 | 51 | } 52 | 53 | int User::Update(string& value) 54 | { 55 | int count; 56 | return __DATABASE.Update("users", value, "id=" + id, count); 57 | } 58 | 59 | int User::Query(bool d_name) 60 | { 61 | int count, length; 62 | string retVal; 63 | int errCode = __DATABASE.Select("users", "*", "id=" + id, count, retVal); 64 | if(errCode != NO_ERROR) 65 | { 66 | return errCode; 67 | } 68 | retVal = retVal.substr(retVal.find_first_of(';') + 1); 69 | string* str = Split(retVal, ',', length); 70 | if(length != 7) 71 | { 72 | delete[] str; 73 | return PARAM_FORM_ERROR; 74 | } 75 | auth = stoi(str[1]); 76 | name = str[2]; 77 | gender = (str[3] == "0" ? "女" : "男"); 78 | schoolid = str[4]; 79 | majorid = str[5]; 80 | classid = str[6]; 81 | delete[] str; 82 | if(d_name) 83 | { 84 | //School Name 85 | __DATABASE.Select("schools", "name", "id=" + schoolid, count, retVal); 86 | schoolName = retVal.substr(retVal.find(";") + 1); 87 | 88 | //Major Name 89 | __DATABASE.Select("majors", "name", "id=" + majorid, count, retVal); 90 | majorName = retVal.substr(retVal.find(";") + 1); 91 | } 92 | return NO_ERROR; 93 | } 94 | 95 | Json User::Format() 96 | { 97 | Json J; 98 | J.push_back({"id",stoi(id)}); 99 | J.push_back({"auth",auth}); 100 | J.push_back({"name",name}); 101 | J.push_back({"email","test@noui.cloud"}); 102 | J.push_back({"gender",gender}); 103 | J.push_back({"schoolid",schoolid}); 104 | J.push_back({"school",schoolName}); 105 | J.push_back({"majorid",majorid}); 106 | J.push_back({"major",majorName}); 107 | J.push_back({"classid",classid}); 108 | return J; 109 | } 110 | 111 | Json User::getTimeTable() 112 | { 113 | Class c(classid); 114 | if(auth == USER_SCHOOL) 115 | { 116 | return c.getTimeTable(schoolid, id); 117 | } 118 | else 119 | { 120 | return c.getTimeTable(schoolid); 121 | } 122 | 123 | } 124 | 125 | Json User::getEvents() 126 | { 127 | int count, temp; 128 | string ret, RET; 129 | NEDB _DB(USER_DIR + "/" + schoolid + "/" + classid); 130 | _DB.Mount("event"); 131 | string condition = "id > " + id + "000 and id < " + id + "999"; 132 | 133 | _DB.Select("event", "*", condition, count, ret); 134 | 135 | _DB.Select("event", "*", "id < 10000", temp, RET); 136 | 137 | //Manage Info 138 | int length, len; 139 | Json J; 140 | if(count == 0 && temp == 0) return J; 141 | string* str = Split(ret, ';', length), * STR = Split(RET, ';', len); 142 | vector events; 143 | for(int i = 1; count > 0 && i < length; i++) 144 | { 145 | Event event; event.Parse(str[i]); 146 | events.push_back(event.Format()); 147 | } 148 | for(int j = 1; temp > 0 && j < len; j++) 149 | { 150 | Event event; event.Parse(STR[j]); 151 | events.push_back(event.Format()); 152 | } 153 | J.push_back({"events",events}); 154 | 155 | delete[] str; delete[] STR; 156 | return J; 157 | } 158 | 159 | int User::addEvent(std::string& value) 160 | { 161 | if(value[value.find_first_of(',')] == '0') 162 | { 163 | if(auth < USER_CLASS) return SYSTEM_ERROR; 164 | } 165 | string dir = USER_DIR + "/" + schoolid + "/" + classid; 166 | NEDB _DB(dir); 167 | 168 | if(_DB.Mount("event") == FILE_NOT_FOUND) 169 | { 170 | _DB.DirInit(); 171 | _DB.SetDefaultPageSize(2000); 172 | _DB.Create("event", "id int64,start int64,end int64,notice int,loc int,name text,info longtext"); 173 | } 174 | _DB.Close(); 175 | 176 | 177 | NEDB DB(dir); 178 | DB.Mount("event"); 179 | int errCode = DB.Insert("event", "", value); 180 | 181 | DB.Close(); 182 | return errCode; 183 | } 184 | 185 | int User::delEvent(std::string& id) 186 | { 187 | NEDB _DB(USER_DIR + "/" + schoolid + "/" + classid); 188 | _DB.Mount("event"); 189 | int count; 190 | int res = _DB.Delete("event", "id=" + id, count); 191 | _DB.Close(); 192 | return res; 193 | } 194 | 195 | int User::AddNew(std::string& detail) 196 | { 197 | int errCode; 198 | errCode = __DATABASE.Insert("users", "", detail); 199 | if(errCode != NO_ERROR) 200 | { 201 | return errCode; 202 | } 203 | int idx = detail.find_first_of(','); 204 | string id = detail.substr(0, idx); 205 | string auth = detail.substr(idx + 1, 1); 206 | errCode = __DATABASE.Insert("token", "", id + "," + "123" + "," + auth); 207 | return errCode; 208 | } 209 | 210 | int User::addNotice(string& eventid, string& code){ 211 | string dir = USER_DIR + "/" + schoolid + "/" + classid; 212 | NEDB _DB(dir); 213 | 214 | _DB.Mount("event"); 215 | 216 | int count; 217 | int errCode = _DB.Update("event","notice="+code,"id="+eventid,count); 218 | 219 | _DB.Close(); 220 | return errCode; 221 | 222 | } 223 | -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | int main(int argv, const char* argc[]){ 8 | //Time Stamp Set 9 | TimeStampReset(); 10 | //Dir Init 11 | DirectoryInit(); 12 | //SQL Test Init 13 | SQLTestGenerate(); 14 | //Service Resource Init 15 | ServicePreload(); 16 | //Server Init 17 | TAPManager server; 18 | server.loadSubManager(std::make_unique()); 19 | server.loadSubManager(std::make_unique()); 20 | server.start(); 21 | 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /src/server/HttpProtocal/HttpAdapter.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | extern size_t preFetchLength(const char * str); 7 | extern size_t preFetchHeader(const char * str); 8 | 9 | /* receive raw byte stream */ 10 | auto HttpAdapter::recvHttpData(Connection *conn) 11 | -> std::tuple< std::shared_ptr , size_t > 12 | { 13 | size_t len = 0; 14 | uint8_t* data = nullptr; 15 | len = sock->recvPeekData(conn->getFD() , &data); 16 | 17 | // handle GET method 18 | if ( !strncmp((char *)data , "GET" , 3) ) { 19 | len = sock->recvNonBlockData(conn->getFD() , &data); 20 | 21 | // handle POST method 22 | } else if ( !strncmp((char *)data , "POST" , 4) ) { 23 | len = preFetchLength( (char *)data ); 24 | len += preFetchHeader( (char *)data ); 25 | len = sock->recvCertainData(conn->getFD() , &data , len + 4); // 4 : size of "\r\n\r\n" 26 | 27 | // generally handle 28 | } else 29 | len = sock->recvData(conn->getFD() , &data); 30 | 31 | return std::make_tuple( 32 | std::shared_ptr{data} , 33 | len); 34 | } 35 | 36 | /* file type specilized check ; true for filesystem response */ 37 | bool HttpAdapter::branchFilePathResp( 38 | Connection *conn , 39 | std::shared_ptr ret) 40 | { 41 | // File response checker 42 | auto file_resp = std::dynamic_pointer_cast (ret); 43 | if( file_resp == nullptr ) return false; 44 | 45 | // version checker 46 | fs::path target = file_resp->getFilepath(); 47 | if(target == "" ) return false; 48 | 49 | // hanle filesystem type FileResponse 50 | auto [buff, slen] = file_resp->stringizeHeader(); 51 | 52 | return sock->sendFileWithHeader( 53 | conn->getFD() , 54 | target.c_str() , 55 | buff.get() , 56 | slen); 57 | } 58 | 59 | void HttpAdapter::sendHttpData( 60 | Connection *conn , 61 | std::shared_ptr ret) 62 | { 63 | if (ret == nullptr) return ; 64 | // Successfully get response(even exception occurs) 65 | 66 | // specialized 67 | if (branchFilePathResp(conn , ret)) return ; 68 | // Send back to socket 69 | auto [buff, slen] = ret->stringize(); 70 | 71 | slen = sock->sendData(conn->getFD(), buff.get(), slen); 72 | } 73 | -------------------------------------------------------------------------------- /src/server/HttpProtocal/HttpBase.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | /*------------------------StringDict------------------------*/ 5 | 6 | char *nsplit(char *str, const char *token, int n); 7 | 8 | #define CUR_MOV(offset) do {\ 9 | cur += offset; \ 10 | if (cur >= len) \ 11 | return ; \ 12 | } while (0) 13 | 14 | //Initialize. the first token is the separator between two string in one pair 15 | // the second one is between two different pairs 16 | void StringDict::__init__( 17 | char *str, 18 | const char *token_1, 19 | const char *token_2) noexcept 20 | { 21 | char *fir, *sec; 22 | len = strlen(str); 23 | 24 | size_t cur = 0; 25 | size_t len_1 = strlen(token_1) , len_2 = strlen(token_2); 26 | 27 | for(;;) { 28 | fir = nsplit(str + cur, token_1, len_1); 29 | CUR_MOV(strlen(fir) + len_1); 30 | 31 | sec = nsplit(str + cur, token_2, len_2); 32 | item.push_back( std::make_pair(std::string{fir}, std::string{sec}) ); 33 | CUR_MOV(strlen(sec) + len_2); 34 | } 35 | } 36 | /* Query and Fetch origin data in this dict. HttpException::NON_POS would occur when not found */ 37 | std::string& StringDict::get(std::string_view key , bool is_insen) 38 | { 39 | for (auto& it : item) { 40 | 41 | if( 42 | std::equal( 43 | it.first.begin() , it.first.end() , 44 | key.begin() , 45 | [=](char a , char b){ 46 | return (!is_insen) ? a == b : 47 | std::tolower(a) == std::tolower(b); 48 | }) 49 | ) return it.second; 50 | 51 | } 52 | throw HttpException::NON_POS; 53 | } 54 | /* Append one pair to dict in the end */ 55 | void StringDict::push(std::string _fir, std::string _sec) noexcept 56 | { 57 | len += _fir.length() + 2 + _sec.length() + 2; 58 | item.push_back(std::make_pair(std::move(_fir), std::move(_sec))); 59 | } 60 | 61 | /* Display this stringdict on stdout */ 62 | void StringDict::show() 63 | { 64 | for (auto& it : item) { 65 | std::cout << it.first << "---" << it.second << "\n"; 66 | } 67 | } 68 | 69 | //query and fetch origin data in this dict. HttpException::NON_POS would occur when not found 70 | std::string& StringDict::operator[](std::string_view str) noexcept 71 | { 72 | try { 73 | return get(str); 74 | } catch (const HttpException& e) { 75 | item.push_back(std::make_pair( std::string{str} , "")); 76 | return (item.end() - 1)->second; 77 | } 78 | } 79 | 80 | #define BUFF_CPY(src , len) do {\ 81 | strncpy(buff + cur, src , len); \ 82 | cur += len;\ 83 | } while (0) 84 | //stringize to byte stream / string 85 | size_t StringDict::stringize(char* buff) 86 | { 87 | size_t cur = 0; 88 | 89 | #pragma GCC diagnostic push 90 | #pragma GCC diagnostic ignored "-Wstringop-truncation" 91 | for (auto& it : item) { 92 | //key string 93 | BUFF_CPY(it.first.c_str() , it.first.length()); 94 | BUFF_CPY(": " , 2); 95 | 96 | //value string 97 | BUFF_CPY(it.second.c_str() , it.second.length()); 98 | BUFF_CPY("\r\n" , 2); 99 | } 100 | BUFF_CPY("\r\n" , 2); 101 | #pragma GCC diagnostic pop 102 | return cur; 103 | } 104 | //Initialize. Constructor by byte range. it could be given by FormData ctor. 105 | // this range is from last boundary to next boundary 106 | FormItem::FormItem(uint8_t *_begin, uint8_t *_end) 107 | { 108 | //split the header info and create it 109 | nsplit((char *)_begin, "\r\n\r\n", 4); 110 | headers = std::make_unique((char *)_begin, ": ", "\r\n"); 111 | 112 | std::string& disposition = headers->get("Content-Disposition" , true); 113 | 114 | //split the filename* info 115 | if (size_t t_pos = disposition.find(" filename*"); 116 | t_pos != disposition.npos ) 117 | { 118 | // filename = disposition.substr(t_pos + 9); // 9 : sizeof "filename=" 119 | // filename = filename.substr(1, filename.length() - 2); // erase "" 120 | disposition = disposition.substr(0, t_pos - 1); // 2 : sizeof "; " 121 | } 122 | 123 | //split the filename info 124 | if (size_t t_pos = disposition.find(" filename"); 125 | t_pos != disposition.npos ) 126 | { 127 | std::cerr << t_pos << "\n"; 128 | filename = disposition.substr(t_pos + 10); // 10 : sizeof " filename=" 129 | filename = filename.substr(1, filename.length() - 2); // erase "" 130 | disposition = disposition.substr(0, t_pos - 1); // 1 : sizeof ";" 131 | } 132 | 133 | //split the key name info 134 | if (size_t t_pos = disposition.find(" name"); 135 | t_pos != disposition.npos ) 136 | { 137 | name = disposition.substr(t_pos + 6); // 6 : sizeof " name=" 138 | name = name.substr(1, name.length() - 2);// erase "" 139 | disposition = disposition.substr(0, t_pos - 1);// 1 : sizeof ";" 140 | } 141 | //the reminder is copied to body as form item data as byte stream. 142 | _begin += headers->length() + 4; 143 | 144 | len = _end - _begin; 145 | data = std::make_unique(len); 146 | memcpy(data.get(), _begin, len); 147 | } 148 | 149 | //method of inverting to filestream. NOT guarantee correctness 150 | std::fstream &operator<<(std::fstream& out, const FormItem& _this) 151 | { 152 | out.write((char *)(_this.data.get()), _this.len); 153 | return out; 154 | } 155 | std::ofstream &operator<<(std::ofstream& out, const FormItem& _this) 156 | { 157 | out.write((char *)(_this.data.get()), _this.len); 158 | return out; 159 | } 160 | 161 | //initialize. arguments could be given by HttpRequest ctor. 162 | FormData::FormData( 163 | std::string& _boundary, 164 | uint8_t *body, 165 | size_t len) 166 | : boundary(std::move(_boundary)) 167 | { 168 | uint8_t *fir = nullptr; 169 | 170 | for (size_t cur = 0; cur < len; cur++) { 171 | //detected boundary in body 172 | if (memcmp(body + cur , "--" , 2) || 173 | memcmp(body + cur + 2, boundary.c_str(), boundary.length()) ) 174 | continue; 175 | 176 | //skip the first one; 177 | if (fir != nullptr) 178 | form.emplace_back(fir, body + cur - 1); 179 | 180 | cur += 4 + boundary.length(); // 4 : sizeof "--" "\r\n" 181 | fir = body + cur; 182 | } 183 | } 184 | 185 | //query form item by key name 186 | FormItem& FormData::queryItem(std::string_view _name) 187 | { 188 | for (auto& it : form) { 189 | if (it.name == _name) 190 | return it; 191 | } 192 | throw HttpException::NON_POS; 193 | } 194 | -------------------------------------------------------------------------------- /src/server/HttpProtocal/HttpException.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | /* handle HTTP Exception */ 6 | HttpResponse* HttpManager::dispatchException(const HttpException &e) 7 | { 8 | switch (e) // near future 9 | { 10 | case HttpException::ERROR_LEN: 11 | std::cerr << "ERROR_LEN\n"; 12 | return new HttpResponse{"Error occur : ERROR_LEN"}; 13 | 14 | case HttpException::OUT_OF_LIMIT: 15 | std::cerr << "OUT_OF_LIMIT\n"; 16 | return new HttpResponse{"Error occur : FILE_OUT_OF_LIMIT"}; 17 | 18 | case HttpException::NON_PATH: 19 | std::cerr << "NON_PATH\n"; 20 | return new HttpResponse{"Error occur : NON_PATH"}; 21 | 22 | case HttpException::NON_CONN: 23 | return nullptr; 24 | 25 | default: 26 | std::cerr << "ELSE" << (int)e << "\n"; 27 | return nullptr; 28 | 29 | } 30 | } -------------------------------------------------------------------------------- /src/server/HttpProtocal/HttpManager.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | /* Judge by clip */ 4 | bool HttpManager::protocalConfirm(const int magic_n) 5 | { 6 | return (magic_n == HTTP_MAGICNUM); 7 | } 8 | 9 | 10 | bool HttpManager::createTask(Connection* conn) 11 | { 12 | //get full data from socket 13 | auto [raw, rlen] = wrapper->recvHttpData(conn); 14 | 15 | // peer soceket closed , task failure 16 | if(rlen == 0) return false; 17 | //execute 18 | std::shared_ptr ret(taskExecute(conn, raw, rlen)); 19 | 20 | //send back 21 | wrapper->sendHttpData( conn , ret ); 22 | 23 | return true; 24 | } 25 | 26 | 27 | HttpResponseBase *HttpManager::taskExecute( 28 | Connection* conn, 29 | std::shared_ptr raw, 30 | size_t len) 31 | { 32 | try { 33 | if (len == -1ULL) 34 | throw HttpException::OUT_OF_LIMIT; 35 | else if (len == 0) 36 | throw HttpException::NON_CONN; 37 | 38 | HttpRequest request {conn, raw.get(), len}; 39 | auto& entry = URLParser::getInstance().URLparse(request.Path()); 40 | return entry(request); 41 | 42 | } catch (const HttpException &e) { 43 | return dispatchException(e); 44 | } 45 | } -------------------------------------------------------------------------------- /src/server/HttpProtocal/HttpUtils.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | /* split str by token string */ 8 | char *nsplit(char *str, const char *token, int n) 9 | { 10 | char *ret = str; 11 | while ((strncmp(++str, token, n) || (*str = 0)) && (*str != 0)) ; 12 | return ret; 13 | } 14 | 15 | /* get GMT time */ 16 | static const char *wday[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; 17 | static const char *mons[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec"}; 18 | std::string getGMTtime(uint32_t offset) 19 | { 20 | time_t timep; 21 | time(&timep); 22 | timep += offset; 23 | struct tm p; 24 | gmtime_r(&timep, &p); 25 | 26 | char buff[32] = {0}; 27 | // Fri, 01 Apr 2022 07:26:49 GMT 28 | sprintf(buff , "%s, %02d %s %d %02d:%02d:%02d GMT", 29 | wday[p.tm_wday] , p.tm_mday , mons[p.tm_mon] , (1900 + p.tm_year), 30 | p.tm_hour , p.tm_min , p.tm_sec ); 31 | return buff; 32 | } 33 | 34 | 35 | std::string estimateFileType(std::filesystem::path p) 36 | { 37 | if (p.extension() == ".gz") p.replace_extension(); 38 | 39 | if (p.extension() == ".html") return "text/html"; 40 | else if(p.extension() == ".css") return "text/css"; 41 | else if(p.extension() == ".txt") return "text/plain"; 42 | else if(p.extension() == ".jpg") return "image/jpeg"; 43 | else if(p.extension() == ".png") return "image/png"; 44 | else if(p.extension() == ".gif") return "image/gif"; 45 | else if(p.extension() == ".json") return "application/json"; 46 | else if(p.extension() == ".js") return "application/javascript"; 47 | else if(p.extension() == ".pdf") return "application/pdf"; 48 | else if(p.extension() == ".mp4") return "video/mpeg4"; 49 | else if(p.extension() == ".mp3") return "audio/mp3"; 50 | else return "application/octet-stream"; 51 | } 52 | 53 | /* get http body's length in http header */ 54 | size_t preFetchLength(const char * str) 55 | { 56 | char buff[32] = {0}; 57 | size_t cur = 0; 58 | while ( strncasecmp(++str, "Content-Length: " , 16) && (*str)) ; 59 | if(*str) while ( (buff[cur++] = (str + 16)[cur]) != '\r' ) ; 60 | 61 | return cur == 0 ? -1ULL : atoll(buff); 62 | } 63 | 64 | /* get http header's length */ 65 | size_t preFetchHeader(const char * str) 66 | { 67 | size_t cur = 0; 68 | while ( strncmp((char *)str + cur , "\r\n\r\n" , 4) && str[cur++]); 69 | return cur; 70 | } 71 | -------------------------------------------------------------------------------- /src/server/Network/TAPCenter.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | class TAPCenter 8 | { 9 | private: 10 | TAPCenter(); 11 | TAPCenter(const TAPCenter &) = delete; 12 | TAPCenter(const TAPCenter &&) = delete; 13 | TAPCenter &operator=(const TAPCenter &) = delete; 14 | TAPCenter &operator=(const TAPCenter &&) = delete; 15 | 16 | public: 17 | std::shared_ptr sock; 18 | std::shared_ptr epool; 19 | std::unique_ptr thpool; 20 | std::vector> plugins; 21 | 22 | void start(); 23 | void distributeTask(EventChannel *eptr); 24 | static auto getInstance() { 25 | static std::shared_ptr ptr {new TAPCenter}; 26 | return ptr; 27 | } 28 | }; 29 | 30 | TAPCenter::TAPCenter() 31 | { 32 | sock = std::make_shared(); 33 | epool = std::make_shared(); 34 | thpool = std::make_unique 35 | (CONFIG_THREADS_MAXIMUM); 36 | 37 | epool->mountEvent( { 38 | SOCK_MAGICNUM , 39 | sock->getFD() , 40 | nullptr , 41 | EPOLLIN 42 | } ); 43 | } 44 | 45 | TAPManager::TAPManager() 46 | { 47 | ptr = TAPCenter::getInstance(); 48 | } 49 | void TAPManager::start() 50 | { 51 | ptr->start(); 52 | } 53 | 54 | /* load additonal plugin */ 55 | void TAPManager::loadSubManager(std::unique_ptr sub) 56 | { 57 | sub->setSock(ptr->sock); 58 | sub->setEpool(ptr->epool); 59 | ptr->plugins.emplace_back(std::move(sub)); 60 | } 61 | 62 | void TAPCenter::distributeTask(EventChannel *eptr) 63 | { 64 | for(auto& ptr : plugins) { 65 | 66 | if( !ptr->protocalConfirm(eptr->magic_n) ) continue ; 67 | // sock also =? why must = ?= 68 | thpool->enqueue([& , _eptr = eptr] 69 | { 70 | auto conn = static_cast(_eptr->ptr); 71 | //std::cerr << "Conn : " << conn->getFD() << "\n"; 72 | // create Http task and judge whether it's alive 73 | if ( ptr->createTask(conn) ) 74 | epool->modifyEvent( { 75 | _eptr->magic_n, 76 | _eptr->fd, 77 | conn, 78 | EPOLLIN | EPOLLET | EPOLLONESHOT 79 | } ); 80 | // peer socket close 81 | else { 82 | sock->offConnect(conn); 83 | // NEED TEST!!! 84 | epool->removeEvent(_eptr); 85 | } 86 | 87 | }); 88 | } 89 | } 90 | 91 | void TAPCenter::start() 92 | { 93 | epool->Loop([&](EventChannel* event) 94 | { 95 | auto type = event->type; 96 | //std::cerr << "MagincNum : " << event->magic_n << "\tFileD : " << event->fd << "\n"; 97 | // motivated by socket-fd, new connection arrive 98 | if(event->magic_n == SOCK_MAGICNUM) { 99 | 100 | for(;;) { 101 | // handled every new connection 102 | Connection* conn = sock->onConnect(); 103 | if(conn == nullptr) break; 104 | 105 | // start listening connection 106 | epool->mountEvent( { 107 | HTTP_MAGICNUM, 108 | conn->getFD(), 109 | conn, 110 | EPOLLIN | EPOLLET | EPOLLONESHOT 111 | } ); 112 | } 113 | 114 | // connection timeout. close forcely 115 | } else if (type & EPOLLHUP || type & EPOLLERR || type & EPOLLRDHUP) { 116 | auto conn = static_cast(event->ptr); 117 | sock->offConnect(conn); // another strage : by time out 118 | epool->removeEvent(event); 119 | 120 | // data from a connection arrived 121 | } else if (type == EPOLLIN) { 122 | // also move ownership to work-thread 123 | this->distributeTask(event); 124 | 125 | } 126 | }); 127 | } 128 | -------------------------------------------------------------------------------- /src/server/Network/ThreadPool.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | // the constructor just launches some amount of workers 5 | ThreadPool::ThreadPool(size_t threads) 6 | { 7 | if(!threads) 8 | threads = std::thread::hardware_concurrency(); 9 | 10 | UTILSTD::CONSOLE_LOG(true,"Workers Maximum : %lu\n" , threads); 11 | 12 | for(size_t i = 0 ; i < threads ; ++i) 13 | workers.emplace_back( [this] 14 | { 15 | for(;;) 16 | { 17 | std::function task; 18 | 19 | { 20 | std::unique_lock lock(this->queue_mutex); 21 | this->condition.wait(lock, 22 | [this]{ return this->stop || !this->tasks.empty(); }); 23 | if(this->stop && this->tasks.empty()) 24 | return; 25 | task = std::move(this->tasks.front()); 26 | this->tasks.pop(); 27 | } 28 | 29 | task(); 30 | } 31 | }); 32 | } 33 | 34 | // the destructor joins all threads 35 | ThreadPool::~ThreadPool() 36 | { 37 | { 38 | std::unique_lock lock(queue_mutex); 39 | stop = true; 40 | } 41 | condition.notify_all(); 42 | for(auto &worker: workers) 43 | worker.join(); 44 | } 45 | -------------------------------------------------------------------------------- /src/server/Network/URLParser.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define ADD_URL(_url, _func) url_table.emplace(_url, _func); 5 | 6 | extern std::string getGMTtime(uint32_t offset = 0); 7 | extern EntryFunc StaticResponse; 8 | 9 | URLParser::URLParser() 10 | { 11 | #include 12 | 13 | } 14 | 15 | EntryFunc& URLParser::URLparse(std::string_view _url) 16 | { 17 | try { 18 | return url_table.at( _url ); 19 | 20 | } catch(const std::out_of_range& e) { 21 | UTILSTD::CONSOLE_LOG(true,"unknow url '%s'\n", _url.data()); 22 | return StaticResponse; 23 | } 24 | } 25 | 26 | bool URLParser::preCheck(std::string_view _url, std::string_view _method) noexcept 27 | { 28 | if (_method == "GET" && _url == static_url) 29 | return true; 30 | else 31 | return false; 32 | 33 | return (url_table.find(_url) == url_table.end()); 34 | } -------------------------------------------------------------------------------- /src/server/TAPSystem.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | using namespace NEDBSTD; 6 | 7 | NEDB __DATABASE("/"); 8 | string PROJECT_DIR = "/"; 9 | string SYS_DIR = "/"; 10 | string USER_DIR = "/"; 11 | string SRC_DIR = "/"; 12 | string TIME_STAMP = "NAN"; 13 | 14 | string TokenSign(string userid) 15 | { 16 | return md5(userid + TIME_STAMP); 17 | } 18 | 19 | void TimeStampReset() 20 | { 21 | srand((unsigned)time(nullptr)); 22 | time_t p; 23 | time(&p); 24 | p += rand(); 25 | TIME_STAMP = md5(to_string(p)); 26 | } 27 | 28 | int TokenCheck(string userid, string token) 29 | { 30 | string res = md5(userid + TIME_STAMP); 31 | if(res == token) return TOKEN_ACCESS; 32 | return TOKEN_DENIED; 33 | } 34 | 35 | void ServicePreload() 36 | { 37 | NEDB_SETTING(32, 400, 50, 5); 38 | NEDB_DEBUG(DEBUG_DETAIL); 39 | NEDB_TIME_FLAG(true); 40 | __DATABASE.SetDir(SYS_DIR.c_str()); 41 | if(__DATABASE.DirInit() != 0) 42 | { 43 | UTILSTD::CONSOLE_LOG(true, "DIR ERROR"); 44 | return; 45 | } 46 | int num; 47 | __DATABASE.MountAll(num); 48 | if(__DATABASE.Open(SYS_DIR + "/token/token") == NO_ERROR) num++; 49 | if(__DATABASE.Open(SYS_DIR + "/test/database_test") == NO_ERROR) num++; 50 | if(__DATABASE.Open(SRC_DIR + "/major/majors") == NO_ERROR) num++; 51 | if(__DATABASE.Open(SRC_DIR + "/school/schools") == NO_ERROR) num++; 52 | if(__DATABASE.Open(SRC_DIR + "/school/classes") == NO_ERROR) num++; 53 | if(__DATABASE.Open(SRC_DIR + "/map/landmark") == NO_ERROR) num++; 54 | if(__DATABASE.Open(SRC_DIR + "/course/courses") == NO_ERROR) num++; 55 | if(__DATABASE.Open(USER_DIR + "/users") == NO_ERROR) num++; 56 | UTILSTD::CONSOLE_LOG(true, "DATABASE: %d Table Mounted\n", num); 57 | } 58 | 59 | void DirectoryInit() 60 | { 61 | PROJECT_DIR = get_current_dir_name(); 62 | UTILSTD::CONSOLE_LOG(true, "** PROJECT DIR ** %s\n", PROJECT_DIR.c_str()); 63 | //PROJECT_DIR = PROJECT_DIR.substr(0,PROJECT_DIR.find("/TAP")+4); 64 | USER_DIR = PROJECT_DIR + "/data/user"; 65 | SRC_DIR = PROJECT_DIR + "/data/src"; 66 | SYS_DIR = PROJECT_DIR + "/data/sys"; 67 | } 68 | 69 | def_HttpEntry(Main, req) 70 | { 71 | return new FileResponse{"data/src/index.html" , "text/html"}; 72 | } -------------------------------------------------------------------------------- /src/server/Timer/TimeLine.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | 4 | const std::vector 5 | TimeLine::getVirtualTime(void) 6 | { 7 | tag_T server_now = ct::system_clock::now(); 8 | tag_T virtual_now; 9 | 10 | { 11 | std::shared_lock grd {t_lock}; 12 | auto real_dur = ct::duration_cast 13 | (server_now - save_real); 14 | 15 | virtual_now = save_virl + 16 | ct::seconds{real_dur.count() * runtime_r}; 17 | } 18 | 19 | time_t timep = ct::system_clock::to_time_t( 20 | virtual_now + ct::hours{TIME_ZONE} 21 | ); 22 | 23 | struct tm p {0}; 24 | gmtime_r(&timep, &p); 25 | 26 | return {p.tm_year + 1900, 27 | p.tm_mon + 1, 28 | p.tm_mday, 29 | p.tm_wday, 30 | p.tm_hour, 31 | p.tm_min , 32 | p.tm_sec}; 33 | } 34 | 35 | void TimeLine::changeRate(uint32_t new_R) 36 | { 37 | 38 | tag_T server_now = ct::system_clock::now(); 39 | 40 | { 41 | std::unique_lock grd {t_lock}; 42 | auto real_dur = ct::duration_cast 43 | (server_now - save_real); 44 | 45 | this->save_virl += ct::seconds{real_dur.count() * runtime_r}; 46 | this->save_real = server_now; 47 | this->runtime_r = new_R; 48 | } 49 | 50 | } 51 | 52 | uint32_t TimeLine::getRate(void) 53 | { 54 | std::shared_lock grd {t_lock}; 55 | return runtime_r; 56 | } 57 | -------------------------------------------------------------------------------- /src/server/Timer/Timer.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | using namespace UTILSTD; 8 | 9 | /*------------------ TimeManager ------------------*/ 10 | 11 | HttpResponseBase* Timer::createComet( 12 | HttpRequest& req , 13 | HttpResponseBase* fail_res) 14 | { 15 | if (TimerManager::getInstance() 16 | ->listenConnect(req.getConnection()) 17 | ) {delete fail_res; return nullptr;} 18 | 19 | else { 20 | return fail_res; 21 | } 22 | } 23 | void Timer::launchBroadCast(HttpResponseBase* reps) 24 | { 25 | std::shared_ptr _reps {reps}; 26 | TimerManager::getInstance()->broadCast(_reps); 27 | } 28 | 29 | 30 | void Timer::setHeartResponse(HttpResponseBase* reps) 31 | { 32 | 33 | std::shared_ptr _reps {reps}; 34 | 35 | TimerManager::getInstance()->modifyHeartResp(_reps); 36 | } 37 | 38 | /*------------------ TimeLine ------------------*/ 39 | 40 | static TimeLine tline; 41 | 42 | void Timer::changeTimeLineRate(uint32_t new_R) 43 | { 44 | tline.changeRate(new_R); 45 | } 46 | 47 | uint32_t Timer::getTimeLineRate(void) 48 | { 49 | auto ret = tline.getRate(); 50 | return ret; 51 | } 52 | 53 | /* Format : Year / Month / Day / Weekday / Hour / Minutes / Seconds */ 54 | const std::vector Timer::getVirtualTime(void) 55 | { 56 | auto ret = tline.getVirtualTime(); 57 | return ret; 58 | } -------------------------------------------------------------------------------- /src/server/Timer/TimerManager.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | bool TimerManager::protocalConfirm(const int magic_n) { 5 | return (magic_n == TIME_MAGICNUM); 6 | } 7 | 8 | 9 | TimerManager* TimerManager::getInstance() 10 | { 11 | if (myself == nullptr) { 12 | std::cerr << "TimerManager HasNot Registered Yet! [TimerManager.cpp]\n"; 13 | std::abort(); 14 | } 15 | 16 | return myself; 17 | } 18 | 19 | TimerManager::TimerManager() 20 | { 21 | if (myself != nullptr) { 22 | std::cerr << "TimerManager MutiConstructed! [TimerManager.cpp]\n"; 23 | std::abort(); 24 | } 25 | 26 | Json j; 27 | j.push_back({"code" , -1}); 28 | j.push_back({"msg" , "60s pass by....HeartBeat Packet"}); 29 | 30 | heart_q = Rep_T { new JsonResponse{j, HTTP_STATUS_202} }; 31 | wrapper = std::make_unique(sock); 32 | myself = this; 33 | } 34 | 35 | bool TimerManager::listenConnect(Connection *conn) 36 | { 37 | if (connPool.count(conn) != 0) return false; 38 | 39 | int tfd = epool->createTimerEvent({ 40 | TIME_MAGICNUM , 41 | 0 , 42 | conn , 43 | EPOLLIN | EPOLLET | EPOLLONESHOT 44 | } , std::chrono::seconds{HEART_TIMEOUT}); 45 | 46 | connPool.emplace(conn , tfd); 47 | 48 | return true; 49 | } 50 | 51 | void TimerManager::modifyHeartResp(Rep_T new_heartq) 52 | { 53 | heart_q.reset(); 54 | 55 | heart_q = new_heartq; 56 | } 57 | 58 | 59 | void TimerManager::broadCast(Rep_T reps) 60 | { 61 | 62 | for(auto [conn , tfd] : connPool) { 63 | wrapper->sendHttpData(conn , reps); 64 | 65 | ::close(tfd); 66 | } 67 | 68 | connPool.clear(); 69 | } 70 | 71 | 72 | bool TimerManager::createTask(Connection* conn) 73 | { 74 | 75 | if(connPool.count(conn) == 0) return false; 76 | 77 | ::close(connPool[conn]); 78 | 79 | wrapper->sendHttpData(conn , heart_q); 80 | 81 | connPool.erase(conn); 82 | 83 | return false; 84 | } -------------------------------------------------------------------------------- /src/service/ClassServcie.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | using namespace NEDBSTD; 6 | using namespace UTILSTD; 7 | 8 | 9 | def_HttpEntry(API_Class, req) 10 | { 11 | string userid(req.queryHeader("userid")); 12 | string token(req.queryHeader("token")); 13 | string function(req.queryHeader("function")); 14 | string body = req.getBody(); 15 | 16 | CONSOLE_LOG(true,"* api/class called [user:%s function:%s]\n",userid.c_str(),function.c_str()); 17 | 18 | if(function == "intro") 19 | { 20 | Class c(string(req.queryParam("classid"))); 21 | int num = c.getMemberNum(); 22 | return new HttpResponse{"班级人数: " + to_string(num),"NO_ERROR",HTTP_STATUS_200}; 23 | } 24 | 25 | if(TokenCheck("10000", token) != TOKEN_ACCESS) 26 | { 27 | return new HttpResponse("ACCESS_DENIED", HTTP_STATUS_401); 28 | } 29 | 30 | if(function == "course") 31 | { 32 | Class c(string(req.queryParam("classid"))); 33 | string course(req.queryParam("course")); 34 | string prof(req.queryParam("prof")); 35 | 36 | return new HttpResponse{ 37 | "",NEexceptionName[c.AddCourse(course, prof, body)],HTTP_STATUS_200 38 | }; 39 | } 40 | 41 | if(function == "new") 42 | { 43 | Class c(string(req.queryParam("classid"))); 44 | 45 | return new HttpResponse{ 46 | "",NEexceptionName[c.AddNew(string(req.queryParam("school")))],HTTP_STATUS_200 47 | }; 48 | 49 | } 50 | 51 | if(function == "list") 52 | { 53 | Class c("0"); 54 | Json J = c.getList(); 55 | 56 | return new JsonResponse{ 57 | J,"NO_ERROR",HTTP_STATUS_200 58 | }; 59 | } 60 | 61 | if(function == "timetable") 62 | { 63 | Class c(string(req.queryParam("classid"))); 64 | Json J = c.getTimeTable(); 65 | 66 | return new JsonResponse{ 67 | J,"NO_ERROR",HTTP_STATUS_200 68 | }; 69 | } 70 | 71 | return new HttpResponse{"","NO_FUNCTION_MATCH",HTTP_STATUS_400}; 72 | 73 | } 74 | 75 | def_HttpEntry(API_School, req) 76 | { 77 | string userid(req.queryHeader("userid")); 78 | string token(req.queryHeader("token")); 79 | string function(req.queryHeader("function")); 80 | 81 | CONSOLE_LOG(true,"* api/school called [user:%s function:%s]\n",userid.c_str(),function.c_str()); 82 | 83 | if(function == "intro") 84 | { 85 | string school(req.queryParam("school")); 86 | string filepath = SRC_DIR + "/school/" + school + "/intro.txt"; 87 | return new FileResponse{ 88 | filepath,"text/html","NO_ERROR" 89 | }; 90 | } 91 | 92 | return new HttpResponse{"","NO_FUNCTION_MATCH",HTTP_STATUS_400}; 93 | 94 | } 95 | 96 | def_HttpEntry(API_Major, req) 97 | { 98 | string userid(req.queryHeader("userid")); 99 | string token(req.queryHeader("token")); 100 | string function(req.queryHeader("function")); 101 | 102 | CONSOLE_LOG(true,"* api/major called [user:%s function:%s]\n",userid.c_str(),function.c_str()); 103 | 104 | if(function == "intro") 105 | { 106 | string major(req.queryParam("major")); 107 | string filepath = SRC_DIR + "/major/" + major + ".txt"; 108 | return new FileResponse{ 109 | filepath,"text/html","NO_ERROR" 110 | }; 111 | } 112 | 113 | return new HttpResponse{"","NO_FUNCTION_MATCH",HTTP_STATUS_400}; 114 | 115 | } 116 | -------------------------------------------------------------------------------- /src/service/ClockService.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace UTILSTD; 3 | 4 | def_HttpEntry(API_Clock , req) { 5 | 6 | Json j; // used for response 7 | std::string_view action { req.queryParam("action") }; 8 | 9 | CONSOLE_LOG(true,"* api/clock called [action:%s]\n",action.data()); 10 | 11 | /* Start listening server broadcast Notification */ 12 | if (action == "c") { 13 | j.push_back({"code" , TimeStatus::DUP}); // for 14 | j.push_back({"msg" , "Connection Duplication!"}); 15 | 16 | return Timer::createComet(req , 17 | new JsonResponse{j}); 18 | 19 | /* Query Server Clock INFO */ 20 | } else if (action == "q") { 21 | auto t_table = Timer::getVirtualTime(); 22 | 23 | j.push_back({"code" , TimeStatus::SUCC}); 24 | j.push_back({"msg" , "Query Successfully!"}); 25 | j.push_back({"data" , { 26 | {"ratio" , (int)Timer::getTimeLineRate()} , 27 | {"year" , t_table[0]} , 28 | {"mon" , t_table[1]} , 29 | {"day" , t_table[2]} , 30 | {"week" , t_table[3]} , 31 | {"hour" , t_table[4]} , 32 | {"min" , t_table[5]} , 33 | {"sec" , t_table[6]} 34 | }}); 35 | 36 | return new JsonResponse{j}; 37 | 38 | /* Modify time speed , and inform all online user*/ 39 | } else if (action == "m") { 40 | Timer::changeTimeLineRate( 41 | std::stoi(req.queryParam("rate").data()) 42 | ); 43 | 44 | { // broadcast to all alive client; 45 | Json elc; 46 | elc.push_back({"code" , TimeStatus::BROAD}); 47 | elc.push_back({"msg" , "Time Rate Changed!"}); 48 | Timer::launchBroadCast( 49 | new JsonResponse{elc} 50 | ); 51 | } 52 | 53 | j.push_back({"code" , TimeStatus::SUCC}); 54 | j.push_back({"msg" , "Modify Successfully!"}); 55 | 56 | return new JsonResponse{j}; 57 | 58 | /* No 'action' param */ 59 | } else { 60 | j.push_back({"code" , TimeStatus::ERR}); 61 | j.push_back({"msg" , "Params Error:No 'action'"}); 62 | return new JsonResponse{j , HTTP_STATUS_400}; 63 | 64 | } 65 | } -------------------------------------------------------------------------------- /src/service/CourseService.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | using namespace NEDBSTD; 6 | using namespace UTILSTD; 7 | 8 | def_HttpEntry(API_Course, req) 9 | { 10 | string userid(req.queryHeader("userid")); 11 | string token(req.queryHeader("token")); 12 | string function(req.queryHeader("function")); 13 | 14 | CONSOLE_LOG(true,"* api/course called [user:%s function:%s]\n",userid.c_str(),function.c_str()); 15 | 16 | string body = req.getBody(); 17 | 18 | if(TokenCheck(userid, token) != TOKEN_ACCESS) 19 | { 20 | return new HttpResponse("ACCESS_DENIED", HTTP_STATUS_401); 21 | } 22 | 23 | if(function == "new") 24 | { 25 | if(userid != "10000") 26 | { 27 | return new HttpResponse("ACCESS_DENIED", HTTP_STATUS_401); 28 | } 29 | Course course; 30 | int index = body.find_first_of(";"); 31 | string str = body.substr(0, index); 32 | body = body.substr(index + 1); 33 | 34 | return new HttpResponse{ 35 | "",NEexceptionName[course.AddNew(str, body)],HTTP_STATUS_200 36 | }; 37 | 38 | } 39 | 40 | if(function == "list") 41 | { 42 | if(userid != "10000") 43 | { 44 | return new HttpResponse("ACCESS_DENIED\r\n", HTTP_STATUS_401); 45 | } 46 | 47 | Course c; 48 | Json J = c.getAll(); 49 | return new JsonResponse{ 50 | J,"NO_ERROR",HTTP_STATUS_200 51 | }; 52 | } 53 | 54 | if(function == "intro") 55 | { 56 | string id(req.queryParam("courseid")); 57 | string path = SRC_DIR + "/course/" + id + "/intro.txt"; 58 | 59 | return new FileResponse{ 60 | path,"text/html","NO_ERROR" 61 | }; 62 | } 63 | 64 | if(function == "addwork") 65 | { 66 | Course course(string(req.queryParam("courseid"))); 67 | string classid(req.queryParam("classid")); 68 | 69 | return new HttpResponse{ 70 | "",NEexceptionName[course.AddWork(userid, classid, body)],HTTP_STATUS_200 71 | }; 72 | } 73 | 74 | if(function == "getwork") 75 | { 76 | Course course(string(req.queryParam("courseid"))); 77 | string classid(req.queryParam("classid")); 78 | string prof(req.queryParam("prof")); 79 | Json J = course.getWork(prof, classid); 80 | 81 | return new JsonResponse{ 82 | J,"NO_ERROR",HTTP_STATUS_200 83 | }; 84 | 85 | } 86 | 87 | if(function == "addexam") 88 | { 89 | Course course(string(req.queryParam("courseid"))); 90 | 91 | return new HttpResponse{ 92 | "",NEexceptionName[course.AddExam(body)],HTTP_STATUS_200 93 | }; 94 | 95 | } 96 | 97 | if(function == "getexam") 98 | { 99 | Course course(string(req.queryParam("courseid"))); 100 | Json J; 101 | if(userid == "10000") 102 | { 103 | J = course.getExam(userid, true); 104 | } 105 | else 106 | { 107 | string classid(req.queryParam("classid")); 108 | string schoolid; 109 | if(classid != "0") 110 | { 111 | Class c(classid); c.Query(); 112 | schoolid = c.getSchool(); 113 | } 114 | else 115 | { 116 | schoolid = string(req.queryParam("schoolid")); 117 | } 118 | J = course.getExam(schoolid); 119 | } 120 | return new JsonResponse{ 121 | J,"NO_ERROR",HTTP_STATUS_200 122 | }; 123 | } 124 | 125 | if(function == "files") 126 | { 127 | Course course(string(req.queryParam("courseid"))); 128 | string prof(req.queryParam("prof")); 129 | Json J = course.getFile(prof); 130 | 131 | return new JsonResponse{ 132 | J,"NO_ERROR",HTTP_STATUS_200 133 | }; 134 | } 135 | 136 | return new HttpResponse{"","NO_FUNCTION_MATCH",HTTP_STATUS_400}; 137 | 138 | } 139 | 140 | 141 | def_HttpEntry(API_Timetable, req) 142 | { 143 | std::string userid(req.queryHeader("userid")); 144 | std::string token(req.queryHeader("token")); 145 | std::string function(req.queryHeader("function")); 146 | 147 | CONSOLE_LOG(true,"* api/timetable called [user:%s function:%s]\n",userid.c_str(),function.c_str()); 148 | 149 | std::string body = req.getBody(); 150 | std::string classid(req.queryParam("classid")); 151 | 152 | if(TokenCheck(userid, token) != TOKEN_ACCESS) 153 | { 154 | return new HttpResponse("ACCESS_DENIED", HTTP_STATUS_401); 155 | } 156 | 157 | if(function == "fetch"){ 158 | User user(userid); 159 | Json J; 160 | int errCode = user.Query(); 161 | if(errCode != NO_ERROR) 162 | { 163 | return new HttpResponse{ 164 | "",NEexceptionName[errCode],HTTP_STATUS_204 165 | }; 166 | } 167 | 168 | J = user.getTimeTable(); 169 | 170 | return new JsonResponse{ 171 | J,"NO_ERROR",HTTP_STATUS_200 172 | }; 173 | } 174 | 175 | return new HttpResponse{"","NO_FUNCTION_MATCH",HTTP_STATUS_400}; 176 | } -------------------------------------------------------------------------------- /src/service/EventService.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | using namespace NEDBSTD; 6 | using namespace UTILSTD; 7 | 8 | def_HttpEntry(API_Event, req) 9 | { 10 | std::string userid(req.queryHeader("userid")); 11 | std::string token(req.queryHeader("token")); 12 | std::string function(req.queryHeader("function")); 13 | 14 | CONSOLE_LOG(true, "* api/event called [user:%s function:%s]\n", userid.c_str(), function.c_str()); 15 | 16 | std::string body = req.getBody(); 17 | 18 | 19 | if(TokenCheck(userid, token) != TOKEN_ACCESS) 20 | { 21 | return new HttpResponse("ACCESS_DENIED", HTTP_STATUS_401); 22 | } 23 | 24 | User user(userid); 25 | int errCode = user.Query(); 26 | 27 | if(errCode != NO_ERROR) 28 | { 29 | return new HttpResponse{ 30 | "",NEexceptionName[errCode],HTTP_STATUS_200 31 | }; 32 | } 33 | 34 | if(function == "fetch") 35 | { 36 | Json J = user.getEvents(); 37 | return new JsonResponse{ 38 | J,"NO_ERROR",HTTP_STATUS_200 39 | }; 40 | } 41 | 42 | if(function == "notice") 43 | { 44 | string eventid(req.queryParam("eventid")); 45 | return new HttpResponse{ 46 | "",NEexceptionName[user.addNotice(eventid,body)],HTTP_STATUS_200 47 | }; 48 | } 49 | 50 | if(function == "new") 51 | { 52 | return new HttpResponse{ 53 | "",NEexceptionName[user.addEvent(body)],HTTP_STATUS_200 54 | }; 55 | } 56 | 57 | return new HttpResponse{"","NO_FUNCTION_MATCH",HTTP_STATUS_400}; 58 | } 59 | -------------------------------------------------------------------------------- /src/service/FileService.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | using namespace std; 7 | using namespace NEDBSTD; 8 | using namespace UTILSTD; 9 | 10 | void zipFile(std::string path) 11 | { 12 | ::signal(SIGCHLD, SIG_IGN); 13 | ::system(std::string{"gzip \"" + path + "\""}.c_str()); 14 | errno = 0; 15 | } 16 | 17 | def_HttpEntry(FileUpload, req) 18 | { 19 | auto filename = req.queryForm("payload").queryFilename(); 20 | std::string path{SRC_DIR + "/file/" + std::string{filename}}; 21 | 22 | CONSOLE_LOG(true, "api/upload called [filename:%s path:%s]\n", filename.data(), path.c_str()); 23 | 24 | std::ofstream file{path , ios::binary | ios::out}; 25 | 26 | std::cerr << std::string{req.queryForm("fil")} << endl; 27 | file << req.queryForm("payload"); 28 | file.close(); 29 | 30 | zipFile(path); 31 | return new HttpResponse{"Upload and Zip Success"}; 32 | } 33 | 34 | def_HttpEntry(API_File, req) 35 | { 36 | std::string userid(req.queryHeader("userid")); 37 | std::string token(req.queryHeader("token")); 38 | 39 | 40 | // if(TokenCheck(userid, token) != TOKEN_ACCESS) 41 | // { 42 | // return new HttpResponse("ACCESS_DENIED", HTTP_STATUS_401); 43 | // } 44 | 45 | string basic_name(req.queryForm("file").queryFilename()); 46 | string filepath(req.queryHeader("upload_path")); 47 | string filename(req.queryHeader("upload_name")); 48 | string type(req.queryHeader("upload_type")); 49 | 50 | //Rename 51 | basic_name = basic_name.substr(basic_name.find_last_of(".")); 52 | filename = filename + basic_name; 53 | 54 | std::string path(SRC_DIR + "/course/" + filepath); 55 | path += (type == "1" ? "res/" : (userid + "/")); 56 | 57 | NEDB _DB(path); 58 | _DB.DirInit(); 59 | if(_DB.Mount("FILE") == FILE_NOT_FOUND) 60 | { 61 | _DB.Create("FILE", "id int,name text,md5 longtext"); 62 | } 63 | _DB.Close(); 64 | 65 | //std::fstream file{path + filename , ios::binary | ios::out}; 66 | 67 | CONSOLE_LOG(true, "api/file called [user:%s file:%s]\n", userid.c_str(), (path + filename).c_str()); 68 | 69 | string md_5 = md5(req.queryForm("file")); 70 | bool flag = true; 71 | NEDB DB(path); 72 | DB.Mount("FILE"); 73 | int count, len, length; string ret; 74 | DB.Select("FILE", "md5", "", count, ret); 75 | if(count != 0) 76 | { 77 | string* md5s = Split(ret, ';', len); 78 | for(int i = 1; i < len + 1; i++) 79 | { 80 | if(md5s[i] == md_5) 81 | { 82 | flag = false; 83 | break; 84 | } 85 | } 86 | } 87 | 88 | if(!flag) 89 | { 90 | DB.Close(); 91 | 92 | return new HttpResponse{ 93 | "","FILE EXISTED",HTTP_STATUS_200 94 | }; 95 | } 96 | 97 | std::ofstream ofile{path + filename , ios::binary | ios::out}; 98 | DB.Insert("FILE", "", to_string(count + 1) + "," + filename + "," + md_5); 99 | ofile << req.queryForm("file"); 100 | ofile.close(); 101 | DB.Close(); 102 | 103 | zipFile(path); 104 | return new HttpResponse{ 105 | "Upload and Zip Success","NO_ERROR",HTTP_STATUS_200 106 | }; 107 | 108 | } -------------------------------------------------------------------------------- /src/service/SignService.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | using namespace NEDBSTD; 5 | using namespace UTILSTD; 6 | 7 | def_HttpEntry(API_Access, req) 8 | { 9 | string level(req.queryHeader("function")); 10 | string userid(req.queryHeader("userid")); 11 | string token(req.queryHeader("token")); 12 | if(TokenCheck((level == "3" ? "10000" : userid), token) != TOKEN_ACCESS) 13 | { 14 | return new HttpResponse("ACCESS_DENIED", HTTP_STATUS_401); 15 | } 16 | else 17 | { 18 | return new HttpResponse("NO_ERROR"); 19 | } 20 | } 21 | 22 | def_HttpEntry(API_Signin, req) 23 | { 24 | string userid(req.queryHeader("userid")); 25 | 26 | CONSOLE_LOG(true,"* api/signin called [user:%s]\n",userid.c_str()); 27 | 28 | string passwd = req.getBody(); 29 | User user(userid); 30 | int res = user.Signin(passwd); 31 | 32 | if(res == NO_ERROR) 33 | { 34 | CONSOLE_LOG(true,"user %s signed in\n",userid.c_str()); 35 | HttpResponse* resp = new HttpResponse("NO_ERROR"); 36 | resp->appendHeader("token", TokenSign(userid)); 37 | return resp; 38 | } 39 | else if(res == -1) 40 | { 41 | return new HttpResponse{"PASSWORD_MISMATCH"}; 42 | } 43 | else if(res == -2) 44 | { 45 | return new HttpResponse{"WAIT_FOR_CONFIRM"}; 46 | } 47 | else if(res == 31) 48 | { 49 | return new HttpResponse{"USER_UNREGISTERED"}; 50 | } 51 | else 52 | { 53 | return new HttpResponse{NEexceptionName[res]}; 54 | } 55 | } 56 | 57 | 58 | def_HttpEntry(API_Signup, req) 59 | { 60 | string userid(req.queryParam("userid")); 61 | 62 | CONSOLE_LOG(true,"* api/signup called [userid:%s]\n",userid.c_str()); 63 | 64 | string passwd(req.getBody()); 65 | User user(userid); 66 | 67 | return new HttpResponse{ 68 | "",NEexceptionName[user.Signup(passwd)],HTTP_STATUS_200 69 | }; 70 | } -------------------------------------------------------------------------------- /src/service/SqlService.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace NEDBSTD; 3 | using namespace UTILSTD; 4 | using namespace std; 5 | 6 | def_HttpEntry(API_SQL, req) 7 | { 8 | string userid(req.queryHeader("userid")); 9 | string token(req.queryHeader("token")); 10 | string function(req.queryHeader("function")); 11 | string ans = req.getBody(); 12 | 13 | if(TokenCheck("10000", token) != TOKEN_ACCESS) 14 | { 15 | return new HttpResponse("ACCESS_DENIED", HTTP_STATUS_401); 16 | } 17 | 18 | CONSOLE_LOG(true, "* api/sql called [function:%s]\n", function.c_str()); 19 | 20 | int count; 21 | string res; 22 | //Sql Query 23 | if(function == "run") 24 | { 25 | 26 | int errCode = __DATABASE.Query(ans, count, res); 27 | 28 | CONSOLE_LOG(true, "Query '%s' OK Return %s\n", ans.c_str(), NEexceptionName[errCode].c_str()); 29 | 30 | Json J; 31 | J.push_back({"count",count}); 32 | J.push_back({"retVal",res.c_str()}); 33 | 34 | return new JsonResponse{ 35 | J,NEexceptionName[errCode],HTTP_STATUS_200 36 | }; 37 | } 38 | //Get Table List 39 | if(function == "list") 40 | { 41 | int errCode = __DATABASE.Query("select tables;", count, res); 42 | Json J; 43 | int length; 44 | string* str = Split(res, ',', length); 45 | vector list; 46 | for(int i = 0; i < length; i++) 47 | { 48 | list.push_back(str[i]); 49 | } 50 | delete[] str; 51 | 52 | J.push_back({"list",list}); 53 | 54 | CONSOLE_LOG(true, "Query OK Return %s\n", NEexceptionName[errCode].c_str()); 55 | 56 | return new JsonResponse{ 57 | J,NEexceptionName[errCode],HTTP_STATUS_200 58 | }; 59 | } 60 | //Get Table Info 61 | if(function == "detail") 62 | { 63 | string tablename = ans; 64 | int errCode = __DATABASE.Select(tablename, "*", "", count, res); 65 | Json J; 66 | J.push_back({"name",tablename.c_str()}); 67 | string fields = res.substr(0, res.find_first_of(";")); 68 | J.push_back({"field",fields.c_str()}); 69 | string data = ""; 70 | if(errCode == NO_ERROR) 71 | { 72 | data = res.substr(res.find_first_of(";") + 1); 73 | } 74 | J.push_back({"data",data.c_str()}); 75 | 76 | CONSOLE_LOG(true, "Query OK Return %s\n", ans.c_str(), NEexceptionName[errCode].c_str()); 77 | 78 | return new JsonResponse{ 79 | J,NEexceptionName[errCode],HTTP_STATUS_200 80 | }; 81 | } 82 | 83 | int errCode; 84 | string* str = Split(ans, ';', count); 85 | 86 | //Update Table Info 87 | if(function == "update") 88 | { 89 | errCode = __DATABASE.Update(str[0], str[2], str[1], count); 90 | } 91 | 92 | //insert Table Info 93 | else if(function == "insert") 94 | { 95 | errCode = __DATABASE.Insert(str[0], str[1], str[2]); 96 | } 97 | 98 | //delete value 99 | else if(function == "delete") 100 | { 101 | errCode = __DATABASE.Delete(str[0], str[1], count); 102 | } 103 | 104 | else if(function == "drop") 105 | { 106 | errCode = __DATABASE.Drop(ans); 107 | } 108 | 109 | else 110 | { 111 | return new HttpResponse{"","NO_FUNCTION_MATCH",HTTP_STATUS_400}; 112 | } 113 | delete[] str; 114 | 115 | CONSOLE_LOG(true, "Query OK Return %s\n", ans.c_str(), NEexceptionName[errCode].c_str()); 116 | 117 | return new HttpResponse{ 118 | "",NEexceptionName[errCode],HTTP_STATUS_200 119 | }; 120 | 121 | } 122 | 123 | // EXAMPLE 2.2 FileResponse也支持从fstream发送文件,(目前仅存在与短连接) 124 | def_HttpEntry(API_SQL_Help, req) 125 | { 126 | return new FileResponse{"web/sql/help.html" , "text/html"}; 127 | } 128 | 129 | std::string DataBaseTestSQL = ""; 130 | void SQLTestGenerate() 131 | { 132 | for(int i = 1; i <= 100; i++) 133 | { 134 | DataBaseTestSQL += "insert into database_test values (" + std::to_string(i) + ",0xff);"; 135 | } 136 | DataBaseTestSQL += "delete from database_test where id>40 and id<160;select * from database_test;"; 137 | } 138 | 139 | static int id; 140 | def_HttpEntry(API_SQL_Test, req) 141 | { 142 | 143 | CONSOLE_LOG(true, "* api/sql/test called\n"); 144 | 145 | id++; 146 | int count; 147 | string res; 148 | CONSOLE_LOG(true, "TEST ID %d\n", id); 149 | 150 | int errCode = __DATABASE.Query("drop table database_test;", count, res); 151 | CONSOLE_LOG(true, "Dropping: Query %d OK return Code %d\n", id, errCode); 152 | 153 | errCode = __DATABASE.Query("create table database_test(id int,name text);", count, res); 154 | CONSOLE_LOG(true, "Creating: Query %d OK return Code %d\n", id, errCode); 155 | 156 | errCode = __DATABASE.Query(DataBaseTestSQL.c_str(), count, res); 157 | CONSOLE_LOG(true, "Testing: Query %d OK return Code %d\n", id, errCode); 158 | 159 | return new HttpResponse{NEexceptionName[errCode]}; 160 | 161 | } 162 | -------------------------------------------------------------------------------- /src/service/UserService.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | using namespace NEDBSTD; 5 | using namespace UTILSTD; 6 | 7 | def_HttpEntry(API_User, req) 8 | { 9 | string function(req.queryHeader("function")); 10 | string userid(req.queryHeader("userid")); 11 | string token(req.queryHeader("token")); 12 | 13 | CONSOLE_LOG(true,"* api/user called [user:%s function:%s]\n",userid.c_str(),function.c_str()); 14 | 15 | string body(req.getBody()); 16 | 17 | if(TokenCheck(userid, token) != TOKEN_ACCESS) 18 | { 19 | return new HttpResponse("ACCESS_DENIED\r\n", HTTP_STATUS_401); 20 | } 21 | 22 | if(function == "new") 23 | { 24 | if(userid != "10000"){ 25 | return new HttpResponse("ACCESS_DENIED", HTTP_STATUS_401); 26 | } 27 | User user; 28 | return new HttpResponse{ 29 | "",NEexceptionName[user.AddNew(body)],HTTP_STATUS_200 30 | }; 31 | 32 | } 33 | 34 | if(function == "list") 35 | { 36 | if(userid != "10000") 37 | { 38 | return new HttpResponse("ACCESS_DENIED", HTTP_STATUS_401); 39 | } 40 | string ret; 41 | int count; 42 | int errCode = __DATABASE.Select("users", "id,auth,name", "", count, ret); 43 | Json J; 44 | if(errCode == NO_ERROR) 45 | { 46 | string str = ret.substr(ret.find_first_of(';') + 1); 47 | J.push_back({"list",str}); 48 | } 49 | return new JsonResponse{ 50 | J,NEexceptionName[errCode],HTTP_STATUS_200 51 | }; 52 | } 53 | 54 | User user(userid); 55 | if(function == "fetch") 56 | { 57 | user.Query(); 58 | Json J = user.Format(); 59 | return new JsonResponse{ 60 | J,"NO_ERROR",HTTP_STATUS_200 61 | }; 62 | } 63 | 64 | if(function == "timetable") 65 | { 66 | user.Query(); 67 | Json J = user.getTimeTable(); 68 | return new JsonResponse{ 69 | J,"NO_ERROR",HTTP_STATUS_200 70 | }; 71 | } 72 | 73 | if(function == "pwd") 74 | { 75 | return new HttpResponse{ 76 | "",NEexceptionName[user.ChangePwd(body)],HTTP_STATUS_200 77 | }; 78 | } 79 | 80 | return new HttpResponse{"","NO_FUNCTION_MATCH",HTTP_STATUS_400}; 81 | } -------------------------------------------------------------------------------- /src/test/test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | // EXAMPLE 0 3 | // 如果需要添加一个入口, 需要在三处文件修改 (以后会简化吧...): 4 | // 1. interfaces.h 5 | // 2. router.conf 6 | // 3. test.cpp (your own .cpp) 7 | 8 | // EXAMPLE 1.0 HttpRequest 的一些基本使用,默认以text/html,参数为std::string 9 | def_HttpEntry(Link_Start , request){ 10 | std::string t; 11 | try { // multipart/from-data的使用 : 根据key查找,支持fstream和string 12 | std::string ans = request.queryForm("Key"); 13 | t += ans; 14 | ans = request.queryForm("Action"); 15 | t += ans; 16 | } catch (const HttpException& e) { 17 | switch (e) 18 | { 19 | case HttpException::NON_POS : //NON_POS : 有form,但没有这个key 20 | t += "OMG , I FAIL!"; 21 | break; 22 | 23 | case HttpException::NON_FORM: // NON_FORM : 没有form 24 | t += "

NOTHING!

"; 25 | t += "

no laughing matter...

"; 26 | break; 27 | default: break; 28 | } 29 | } 30 | return new HttpResponse{t}; 31 | } 32 | 33 | 34 | // EXAMPLE 2.1 FileResponse支持直接从指定文件路径发送文件,效率比较高,但是仅为只读文件 35 | def_HttpEntry(Lent_Book , req){ 36 | return new FileResponse{"utils/out" , "application/pdf"}; 37 | } 38 | 39 | 40 | // EXAMPLE 2.3 FileResponse建议使用c++17的std::filesystem 41 | // def_HttpEntry(Icon , req){ 42 | // fs::path p {"utils/favicon.ico"}; 43 | // if(fs::exists(p)) 44 | // return new FileResponse{p , "image/png"}; 45 | // else 46 | // return new HttpResponse{"404\nNOT FOUND" , HTTP_STATUS_404}; 47 | // } 48 | 49 | // EXAMPLE 3.1 JsonResponse返回一个json格式的数据 50 | // Apifox里有一个相关测试 51 | def_HttpEntry(Check_It , req) { 52 | Json j; 53 | j.push_back({"Name" , "Bupt"}); //支持字符串类型 54 | j.push_back({"location" , { 55 | {"E" , 116.20 } , 56 | {"N" , 39.56} } 57 | }); //支持结构体类型 58 | 59 | std::vector strs {"Double" , "One" , "Stream"}; 60 | j.push_back({"Grade" ,strs}); //支持来自vector的数组 61 | j.push_back({"Rate of Employment" , 99.9}); //支持数字(int, double) 62 | j.push_back({"Full of Budget" , false}); //支持 bool 63 | return new JsonResponse{j}; 64 | } 65 | 66 | def_HttpEntry(MD5Test,req){ 67 | std::string val = ""; 68 | std::string ans = req.getBody(); 69 | 70 | UTILSTD::CONSOLE_LOG(true,"* api/md5 called [res:%s]\n",ans.c_str()); 71 | 72 | std::string str_md5 = md5(ans); 73 | 74 | UTILSTD::CONSOLE_LOG(true,"Process Result : %s\n",str_md5.c_str()); 75 | 76 | return new HttpResponse{str_md5}; 77 | } 78 | 79 | def_HttpEntry(LogCheck,req){ 80 | UTILSTD::CONSOLE_LOG(true,"* api/log called\n"); 81 | return new FileResponse{".server/log","text/html"}; 82 | } 83 | 84 | def_HttpEntry(CometTest , req) { 85 | //Timer::createComet(req); 86 | std::string ans {}; 87 | 88 | auto table = Timer::getVirtualTime(); 89 | for(auto i : table) { 90 | ans += std::to_string(i) += " "; 91 | } 92 | 93 | return new HttpResponse{ans}; 94 | } 95 | 96 | def_HttpEntry(CometBroad , req) { 97 | Timer::launchBroadCast(new HttpResponse {"Hello , everyone\n"}); 98 | 99 | return new HttpResponse {"Successful launch"}; 100 | } -------------------------------------------------------------------------------- /utils/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/utils/favicon.ico -------------------------------------------------------------------------------- /utils/kconfig/build/conf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/utils/kconfig/build/conf -------------------------------------------------------------------------------- /utils/kconfig/build/mconf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/utils/kconfig/build/mconf -------------------------------------------------------------------------------- /utils/kconfig/build/obj-conf/build/lexer.lex.d: -------------------------------------------------------------------------------- 1 | /home/andrew/Desktop/TinyAndPretty/utils/kconfig/build/obj-conf/build/lexer.lex.o: \ 2 | build/lexer.lex.c lkc.h expr.h list.h lkc_proto.h build/parser.tab.h 3 | -------------------------------------------------------------------------------- /utils/kconfig/build/obj-conf/build/lexer.lex.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/utils/kconfig/build/obj-conf/build/lexer.lex.o -------------------------------------------------------------------------------- /utils/kconfig/build/obj-conf/build/parser.tab.d: -------------------------------------------------------------------------------- 1 | /home/andrew/Desktop/TinyAndPretty/utils/kconfig/build/obj-conf/build/parser.tab.o: \ 2 | build/parser.tab.c lkc.h expr.h list.h lkc_proto.h menu.c lkc.h 3 | -------------------------------------------------------------------------------- /utils/kconfig/build/obj-conf/build/parser.tab.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/utils/kconfig/build/obj-conf/build/parser.tab.o -------------------------------------------------------------------------------- /utils/kconfig/build/obj-conf/conf.d: -------------------------------------------------------------------------------- 1 | /home/andrew/Desktop/TinyAndPretty/utils/kconfig/build/obj-conf/conf.o: \ 2 | conf.c lkc.h expr.h list.h lkc_proto.h 3 | -------------------------------------------------------------------------------- /utils/kconfig/build/obj-conf/conf.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/utils/kconfig/build/obj-conf/conf.o -------------------------------------------------------------------------------- /utils/kconfig/build/obj-conf/confdata.d: -------------------------------------------------------------------------------- 1 | /home/andrew/Desktop/TinyAndPretty/utils/kconfig/build/obj-conf/confdata.o: \ 2 | confdata.c lkc.h expr.h list.h lkc_proto.h 3 | -------------------------------------------------------------------------------- /utils/kconfig/build/obj-conf/confdata.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/utils/kconfig/build/obj-conf/confdata.o -------------------------------------------------------------------------------- /utils/kconfig/build/obj-conf/expr.d: -------------------------------------------------------------------------------- 1 | /home/andrew/Desktop/TinyAndPretty/utils/kconfig/build/obj-conf/expr.o: \ 2 | expr.c lkc.h expr.h list.h lkc_proto.h 3 | -------------------------------------------------------------------------------- /utils/kconfig/build/obj-conf/expr.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/utils/kconfig/build/obj-conf/expr.o -------------------------------------------------------------------------------- /utils/kconfig/build/obj-conf/preprocess.d: -------------------------------------------------------------------------------- 1 | /home/andrew/Desktop/TinyAndPretty/utils/kconfig/build/obj-conf/preprocess.o: \ 2 | preprocess.c list.h lkc.h expr.h lkc_proto.h 3 | -------------------------------------------------------------------------------- /utils/kconfig/build/obj-conf/preprocess.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/utils/kconfig/build/obj-conf/preprocess.o -------------------------------------------------------------------------------- /utils/kconfig/build/obj-conf/symbol.d: -------------------------------------------------------------------------------- 1 | /home/andrew/Desktop/TinyAndPretty/utils/kconfig/build/obj-conf/symbol.o: \ 2 | symbol.c lkc.h expr.h list.h lkc_proto.h 3 | -------------------------------------------------------------------------------- /utils/kconfig/build/obj-conf/symbol.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/utils/kconfig/build/obj-conf/symbol.o -------------------------------------------------------------------------------- /utils/kconfig/build/obj-conf/util.d: -------------------------------------------------------------------------------- 1 | /home/andrew/Desktop/TinyAndPretty/utils/kconfig/build/obj-conf/util.o: \ 2 | util.c lkc.h expr.h list.h lkc_proto.h 3 | -------------------------------------------------------------------------------- /utils/kconfig/build/obj-conf/util.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/utils/kconfig/build/obj-conf/util.o -------------------------------------------------------------------------------- /utils/kconfig/build/obj-mconf/build/lexer.lex.d: -------------------------------------------------------------------------------- 1 | /home/andrew/Desktop/TinyAndPretty/utils/kconfig/build/obj-mconf/build/lexer.lex.o: \ 2 | build/lexer.lex.c lkc.h expr.h list.h lkc_proto.h build/parser.tab.h 3 | -------------------------------------------------------------------------------- /utils/kconfig/build/obj-mconf/build/lexer.lex.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/utils/kconfig/build/obj-mconf/build/lexer.lex.o -------------------------------------------------------------------------------- /utils/kconfig/build/obj-mconf/build/parser.tab.d: -------------------------------------------------------------------------------- 1 | /home/andrew/Desktop/TinyAndPretty/utils/kconfig/build/obj-mconf/build/parser.tab.o: \ 2 | build/parser.tab.c lkc.h expr.h list.h lkc_proto.h menu.c lkc.h 3 | -------------------------------------------------------------------------------- /utils/kconfig/build/obj-mconf/build/parser.tab.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/utils/kconfig/build/obj-mconf/build/parser.tab.o -------------------------------------------------------------------------------- /utils/kconfig/build/obj-mconf/confdata.d: -------------------------------------------------------------------------------- 1 | /home/andrew/Desktop/TinyAndPretty/utils/kconfig/build/obj-mconf/confdata.o: \ 2 | confdata.c lkc.h expr.h list.h lkc_proto.h 3 | -------------------------------------------------------------------------------- /utils/kconfig/build/obj-mconf/confdata.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/utils/kconfig/build/obj-mconf/confdata.o -------------------------------------------------------------------------------- /utils/kconfig/build/obj-mconf/expr.d: -------------------------------------------------------------------------------- 1 | /home/andrew/Desktop/TinyAndPretty/utils/kconfig/build/obj-mconf/expr.o: \ 2 | expr.c lkc.h expr.h list.h lkc_proto.h 3 | -------------------------------------------------------------------------------- /utils/kconfig/build/obj-mconf/expr.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/utils/kconfig/build/obj-mconf/expr.o -------------------------------------------------------------------------------- /utils/kconfig/build/obj-mconf/lxdialog/checklist.d: -------------------------------------------------------------------------------- 1 | /home/andrew/Desktop/TinyAndPretty/utils/kconfig/build/obj-mconf/lxdialog/checklist.o: \ 2 | lxdialog/checklist.c lxdialog/dialog.h 3 | -------------------------------------------------------------------------------- /utils/kconfig/build/obj-mconf/lxdialog/checklist.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/utils/kconfig/build/obj-mconf/lxdialog/checklist.o -------------------------------------------------------------------------------- /utils/kconfig/build/obj-mconf/lxdialog/inputbox.d: -------------------------------------------------------------------------------- 1 | /home/andrew/Desktop/TinyAndPretty/utils/kconfig/build/obj-mconf/lxdialog/inputbox.o: \ 2 | lxdialog/inputbox.c lxdialog/dialog.h 3 | -------------------------------------------------------------------------------- /utils/kconfig/build/obj-mconf/lxdialog/inputbox.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/utils/kconfig/build/obj-mconf/lxdialog/inputbox.o -------------------------------------------------------------------------------- /utils/kconfig/build/obj-mconf/lxdialog/menubox.d: -------------------------------------------------------------------------------- 1 | /home/andrew/Desktop/TinyAndPretty/utils/kconfig/build/obj-mconf/lxdialog/menubox.o: \ 2 | lxdialog/menubox.c lxdialog/dialog.h 3 | -------------------------------------------------------------------------------- /utils/kconfig/build/obj-mconf/lxdialog/menubox.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/utils/kconfig/build/obj-mconf/lxdialog/menubox.o -------------------------------------------------------------------------------- /utils/kconfig/build/obj-mconf/lxdialog/textbox.d: -------------------------------------------------------------------------------- 1 | /home/andrew/Desktop/TinyAndPretty/utils/kconfig/build/obj-mconf/lxdialog/textbox.o: \ 2 | lxdialog/textbox.c lxdialog/dialog.h 3 | -------------------------------------------------------------------------------- /utils/kconfig/build/obj-mconf/lxdialog/textbox.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/utils/kconfig/build/obj-mconf/lxdialog/textbox.o -------------------------------------------------------------------------------- /utils/kconfig/build/obj-mconf/lxdialog/util.d: -------------------------------------------------------------------------------- 1 | /home/andrew/Desktop/TinyAndPretty/utils/kconfig/build/obj-mconf/lxdialog/util.o: \ 2 | lxdialog/util.c lxdialog/dialog.h 3 | -------------------------------------------------------------------------------- /utils/kconfig/build/obj-mconf/lxdialog/util.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/utils/kconfig/build/obj-mconf/lxdialog/util.o -------------------------------------------------------------------------------- /utils/kconfig/build/obj-mconf/lxdialog/yesno.d: -------------------------------------------------------------------------------- 1 | /home/andrew/Desktop/TinyAndPretty/utils/kconfig/build/obj-mconf/lxdialog/yesno.o: \ 2 | lxdialog/yesno.c lxdialog/dialog.h 3 | -------------------------------------------------------------------------------- /utils/kconfig/build/obj-mconf/lxdialog/yesno.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/utils/kconfig/build/obj-mconf/lxdialog/yesno.o -------------------------------------------------------------------------------- /utils/kconfig/build/obj-mconf/mconf.d: -------------------------------------------------------------------------------- 1 | /home/andrew/Desktop/TinyAndPretty/utils/kconfig/build/obj-mconf/mconf.o: \ 2 | mconf.c lkc.h expr.h list.h lkc_proto.h lxdialog/dialog.h 3 | -------------------------------------------------------------------------------- /utils/kconfig/build/obj-mconf/mconf.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/utils/kconfig/build/obj-mconf/mconf.o -------------------------------------------------------------------------------- /utils/kconfig/build/obj-mconf/preprocess.d: -------------------------------------------------------------------------------- 1 | /home/andrew/Desktop/TinyAndPretty/utils/kconfig/build/obj-mconf/preprocess.o: \ 2 | preprocess.c list.h lkc.h expr.h lkc_proto.h 3 | -------------------------------------------------------------------------------- /utils/kconfig/build/obj-mconf/preprocess.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/utils/kconfig/build/obj-mconf/preprocess.o -------------------------------------------------------------------------------- /utils/kconfig/build/obj-mconf/symbol.d: -------------------------------------------------------------------------------- 1 | /home/andrew/Desktop/TinyAndPretty/utils/kconfig/build/obj-mconf/symbol.o: \ 2 | symbol.c lkc.h expr.h list.h lkc_proto.h 3 | -------------------------------------------------------------------------------- /utils/kconfig/build/obj-mconf/symbol.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/utils/kconfig/build/obj-mconf/symbol.o -------------------------------------------------------------------------------- /utils/kconfig/build/obj-mconf/util.d: -------------------------------------------------------------------------------- 1 | /home/andrew/Desktop/TinyAndPretty/utils/kconfig/build/obj-mconf/util.o: \ 2 | util.c lkc.h expr.h list.h lkc_proto.h 3 | -------------------------------------------------------------------------------- /utils/kconfig/build/obj-mconf/util.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/utils/kconfig/build/obj-mconf/util.o -------------------------------------------------------------------------------- /utils/kconfig/build/parser.tab.h: -------------------------------------------------------------------------------- 1 | /* A Bison parser, made by GNU Bison 3.5.1. */ 2 | 3 | /* Bison interface for Yacc-like parsers in C 4 | 5 | Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2020 Free Software Foundation, 6 | Inc. 7 | 8 | This program is free software: you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation, either version 3 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with this program. If not, see . */ 20 | 21 | /* As a special exception, you may create a larger work that contains 22 | part or all of the Bison parser skeleton and distribute that work 23 | under terms of your choice, so long as that work isn't itself a 24 | parser generator using the skeleton or a modified version thereof 25 | as a parser skeleton. Alternatively, if you modify or redistribute 26 | the parser skeleton itself, you may (at your option) remove this 27 | special exception, which will cause the skeleton and the resulting 28 | Bison output files to be licensed under the GNU General Public 29 | License without this special exception. 30 | 31 | This special exception was added by the Free Software Foundation in 32 | version 2.2 of Bison. */ 33 | 34 | /* Undocumented macros, especially those whose name start with YY_, 35 | are private implementation details. Do not rely on them. */ 36 | 37 | #ifndef YY_YY_BUILD_PARSER_TAB_H_INCLUDED 38 | # define YY_YY_BUILD_PARSER_TAB_H_INCLUDED 39 | /* Debug traces. */ 40 | #ifndef YYDEBUG 41 | # define YYDEBUG 0 42 | #endif 43 | #if YYDEBUG 44 | extern int yydebug; 45 | #endif 46 | 47 | /* Token type. */ 48 | #ifndef YYTOKENTYPE 49 | # define YYTOKENTYPE 50 | enum yytokentype 51 | { 52 | T_HELPTEXT = 258, 53 | T_WORD = 259, 54 | T_WORD_QUOTE = 260, 55 | T_ALLNOCONFIG_Y = 261, 56 | T_BOOL = 262, 57 | T_CHOICE = 263, 58 | T_CLOSE_PAREN = 264, 59 | T_COLON_EQUAL = 265, 60 | T_COMMENT = 266, 61 | T_CONFIG = 267, 62 | T_DEFAULT = 268, 63 | T_DEFCONFIG_LIST = 269, 64 | T_DEF_BOOL = 270, 65 | T_DEF_TRISTATE = 271, 66 | T_DEPENDS = 272, 67 | T_ENDCHOICE = 273, 68 | T_ENDIF = 274, 69 | T_ENDMENU = 275, 70 | T_HELP = 276, 71 | T_HEX = 277, 72 | T_IF = 278, 73 | T_IMPLY = 279, 74 | T_INT = 280, 75 | T_MAINMENU = 281, 76 | T_MENU = 282, 77 | T_MENUCONFIG = 283, 78 | T_MODULES = 284, 79 | T_ON = 285, 80 | T_OPEN_PAREN = 286, 81 | T_OPTION = 287, 82 | T_OPTIONAL = 288, 83 | T_PLUS_EQUAL = 289, 84 | T_PROMPT = 290, 85 | T_RANGE = 291, 86 | T_SELECT = 292, 87 | T_SOURCE = 293, 88 | T_STRING = 294, 89 | T_TRISTATE = 295, 90 | T_VISIBLE = 296, 91 | T_EOL = 297, 92 | T_ASSIGN_VAL = 298, 93 | T_OR = 299, 94 | T_AND = 300, 95 | T_EQUAL = 301, 96 | T_UNEQUAL = 302, 97 | T_LESS = 303, 98 | T_LESS_EQUAL = 304, 99 | T_GREATER = 305, 100 | T_GREATER_EQUAL = 306, 101 | T_NOT = 307 102 | }; 103 | #endif 104 | 105 | /* Value type. */ 106 | #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED 107 | union YYSTYPE 108 | { 109 | #line 36 "parser.y" 110 | 111 | char *string; 112 | struct symbol *symbol; 113 | struct expr *expr; 114 | struct menu *menu; 115 | enum symbol_type type; 116 | enum variable_flavor flavor; 117 | 118 | #line 119 "build/parser.tab.h" 119 | 120 | }; 121 | typedef union YYSTYPE YYSTYPE; 122 | # define YYSTYPE_IS_TRIVIAL 1 123 | # define YYSTYPE_IS_DECLARED 1 124 | #endif 125 | 126 | 127 | extern YYSTYPE yylval; 128 | 129 | int yyparse (void); 130 | 131 | #endif /* !YY_YY_BUILD_PARSER_TAB_H_INCLUDED */ 132 | -------------------------------------------------------------------------------- /utils/md5test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Tiny And Pretty 6 | 7 | 8 |

TAP MD5 Test

9 |

10 |
11 | String :
12 | 13 |
14 | 15 |

16 |
17 |
18 |
Result : 
19 |
20 |

21 |

22 |
23 |
24 |

25 | For More Infomation: 26 |
27 | 28 | 29 | 30 |

31 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /utils/out: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/utils/out -------------------------------------------------------------------------------- /utils/pic0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/utils/pic0.png -------------------------------------------------------------------------------- /utils/pic1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/utils/pic1.png -------------------------------------------------------------------------------- /utils/shaheM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/utils/shaheM.png -------------------------------------------------------------------------------- /utils/shaheWalking.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/utils/shaheWalking.png -------------------------------------------------------------------------------- /utils/xtcM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/utils/xtcM.png -------------------------------------------------------------------------------- /web/old/index.css: -------------------------------------------------------------------------------- 1 | body{ 2 | background:url(src/bg3.png); 3 | background-size: cover; 4 | } 5 | 6 | .main{ 7 | display: flex; 8 | flex-direction: column; 9 | margin:0; 10 | margin-left:5%; 11 | margin-right: 5%; 12 | } 13 | 14 | .main .head{ 15 | margin-top: 10px; 16 | background-color:whitesmoke; 17 | border:1px solid; 18 | border-radius:6px; 19 | width:16%; 20 | width: 150px; 21 | height: 45px; 22 | overflow: hidden; 23 | /* margin */ 24 | margin-bottom: 20px; 25 | /* padding */ 26 | box-sizing:border-box; 27 | padding:0; 28 | padding-left:15px; 29 | padding-top:6px; 30 | } 31 | 32 | .main .head:hover{ 33 | transform: scale(1.05); 34 | } 35 | 36 | .main .box{ 37 | max-width: 860px; 38 | color: white; 39 | width: auto; 40 | display: flex; 41 | flex-direction: row; 42 | flex-wrap: wrap; 43 | } 44 | 45 | .main .box .small{ 46 | /* size */ 47 | width: 180px; 48 | height: 250px; 49 | /* padding */ 50 | box-sizing:border-box; 51 | padding:15px; 52 | padding-left:10px; 53 | /* margin */ 54 | margin-right: 10px; 55 | margin-bottom: 10px; 56 | /* content */ 57 | display: flex; 58 | flex-direction: column-reverse; 59 | /* inside */ 60 | overflow: hidden; 61 | } 62 | 63 | .main .box .large{ 64 | /* size */ 65 | width: 460px; 66 | height: 250px; 67 | /* padding */ 68 | box-sizing:border-box; 69 | padding:15px; 70 | padding-left:10px; 71 | /* margin */ 72 | margin-bottom: 10px; 73 | /* content */ 74 | display: flex; 75 | flex-direction: column-reverse; 76 | /* inside */ 77 | overflow: hidden; 78 | } 79 | 80 | .main .box:hover *{ 81 | filter: blur(3px); 82 | } 83 | 84 | #database{ 85 | background:url(src/item1.jpg); 86 | background-size:260px; 87 | color: black; 88 | } 89 | #database:hover{ 90 | transform: scale(1.05); 91 | filter: blur(0); 92 | } 93 | #database:hover *{ 94 | filter: blur(0); 95 | } 96 | 97 | 98 | #md5{ 99 | background:url(src/item3.jpg); 100 | background-size: cover; 101 | } 102 | #md5:hover{ 103 | transform: scale(1.05); 104 | filter: blur(0); 105 | } 106 | #md5:hover *{ 107 | filter: blur(0); 108 | } 109 | 110 | #course{ 111 | background:url(src/item4.jpg); 112 | background-size:650px; 113 | } 114 | #course:hover{ 115 | transform: scale(1.05); 116 | filter: blur(0); 117 | } 118 | #course:hover *{ 119 | filter: blur(0); 120 | } -------------------------------------------------------------------------------- /web/old/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Tiny And Pretty 6 | 7 | 8 | 9 |

Tiny & Pretty

12 |
13 |
14 |
View Repo
15 |
@Github
16 |
17 |
18 |
19 |

Console

20 |

DataBase

21 |
22 |
23 |

MD5

24 |

Calculate

25 |
26 |
27 |

Course Assistance

28 |

Offline

29 |
30 |
31 |
32 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /web/old/main.js: -------------------------------------------------------------------------------- 1 | var ROOT = "http://" + location.host; 2 | 3 | function axiosPostWithToken(Url,Param,Val,Function,NoErrFuncton,ErrFunction,ExpFunction){ 4 | axios.post(Url,Val,{ 5 | params:Param, 6 | headers:{ 7 | 'content-type': 'multipart/form-data', 8 | 'function': Function, 9 | 'token':localStorage.getItem('token'), 10 | 'userid':localStorage.getItem('userid') 11 | } 12 | }) 13 | .then(res => { 14 | console.log(res); 15 | if(res.headers.msg == "NO_ERROR"){ 16 | NoErrFuncton(res); 17 | }else{ 18 | ErrFunction(res); 19 | } 20 | }) 21 | .catch(err => { 22 | console.log(err); 23 | ExpFunction(err); 24 | }); 25 | } 26 | 27 | function axiosGetWithToken(Url,Param,Function,NoErrFuncton,ErrFunction,ExpFunction){ 28 | axios.get(Url,{ 29 | params:Param, 30 | headers:{ 31 | 'content-type': 'multipart/form-data', 32 | 'function': Function, 33 | 'token':localStorage.getItem('token'), 34 | 'userid':localStorage.getItem('userid') 35 | } 36 | }) 37 | .then(res => { 38 | console.log(res); 39 | if(res.headers.msg == "NO_ERROR"){ 40 | NoErrFuncton(res); 41 | }else{ 42 | ErrFunction(res); 43 | } 44 | }) 45 | .catch(err => { 46 | console.log(err); 47 | ExpFunction(err); 48 | }) 49 | } -------------------------------------------------------------------------------- /web/old/schedule/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Tiny And Pretty 6 | 7 | 8 | 9 | 10 | 11 | 12 |

TAP TimeTable

13 |

14 |
15 | 19 | TimeTable 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 37 | 38 |
Sec.Mon.Tue.Wed.Thur.Fri.Sat.Sun.
第{{index+1}}节 33 | {{detail[val].name}}
34 | {{detail[val].prof}}
35 | {{detail[val].loc}} 36 |
39 |
40 |

41 |
42 |
43 |

44 | For More Infomation: 45 |
46 | 47 | 48 | 49 |

50 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /web/old/signin.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Tiny And Pretty 6 | 7 | 8 | 9 | 10 |

TAP Authentication

11 |

12 |
13 | UserID:
14 | 15 |
16 | Password:
17 | 18 |
19 | 20 | 21 |
22 |
23 |

24 |
25 |
26 |
27 |

28 | For More Infomation: 29 |
30 | 31 | 32 |

33 | 34 | 92 | 93 | -------------------------------------------------------------------------------- /web/old/signup.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Tiny And Pretty 6 | 7 | 8 | 9 | 10 |

TAP Sign Up

11 |

12 |
13 | UserID:
14 | 15 |
16 | Password:
17 | 18 |
19 | Password Confirm:
20 | 21 |
22 | 23 |
24 | 25 | 26 |

27 |

28 | Have an account already? 29 | 30 |

31 |
32 |
33 |
34 |

35 | For More Infomation: 36 |
37 | 38 | 39 | 40 |

41 | 42 | 97 | 98 | -------------------------------------------------------------------------------- /web/old/sql/help.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NEDB SQL INFO 6 | 7 | 8 |

SQL Form of NEDB

9 | 10 |
11 |
12 |
13 |

Data Type Support >

14 |

15 | [ int ] >>> int
16 | [ int64 ] >>> long int
17 | [ real ] >>> double
18 | [ text ] >>> char[32]
19 | [ longtext ] >>> char[255]
20 |


21 |

SQL FORM >

22 |

[TABLE CREATE]

23 |

create table 'table_name' ('data_title' 'data_type', ... );

24 |

* The first parm will be set as PRIMARY KEY by default.
25 | * Add 'key' after a parm to designate.
26 | * Parm typed 'longtext' is not allowed to be set as the PRIMARY KEY.
27 |


28 |

[TABLE REMOVE]

29 |

drop table 'table_name';


30 |

[DATA INSERT]

31 |

insert into 'table_name' ('parm_name', ...) values ('parm_value', ...);


32 |

[DATA SELECT]

33 |

select 'parm_name' from 'table_name' where 'conditions';


34 |

[DATA DELETE]

35 |

delete from 'table_name' where 'conditions';


36 |

[DATA UPDATE]

37 |

update 'table_name' set 'parm_name' = 'parm_value', ... where 'conditions';


38 |

[STRUCTURE CHECK]

39 |

describe table 'table_name';


40 |

[TABLES CHECK]

41 |

select tables;


42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /web/old/src/bg1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/web/old/src/bg1.png -------------------------------------------------------------------------------- /web/old/src/bg3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/web/old/src/bg3.png -------------------------------------------------------------------------------- /web/old/src/item1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/web/old/src/item1.jpg -------------------------------------------------------------------------------- /web/old/src/item3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/web/old/src/item3.jpg -------------------------------------------------------------------------------- /web/old/src/item4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BUPT-CS-Assignment/TinyAndPretty/70083a4bd5e821b820465895a6a89ec79f7c1285/web/old/src/item4.jpg -------------------------------------------------------------------------------- /web/old/user/index.css: -------------------------------------------------------------------------------- 1 | :root { 2 | overflow-y: auto; 3 | overflow-x: hidden; 4 | } 5 | 6 | html { 7 | overflow-y: scroll; 8 | } 9 | 10 | *{ 11 | margin: 0; 12 | padding: 0; 13 | box-sizing: border-box; 14 | } 15 | 16 | 17 | body{ 18 | width: 100vw; 19 | height: 100vh; 20 | overflow-x: hidden; 21 | 22 | background: #262626; 23 | /*background: linear-gradient(#4285f4, #d2d5fc); */ 24 | z-index: -1; 25 | } 26 | 27 | body::after{ 28 | content: ''; 29 | position: absolute; 30 | top: 0; 31 | left: 0; 32 | width: 100%; 33 | height: 100%; 34 | background:linear-gradient(#4285f4, #d2d5fc); 35 | clip-path: circle(20% at 10% 10%); 36 | z-index: -1; 37 | } 38 | 39 | body::before{ 40 | content: ''; 41 | position: absolute; 42 | top: 0; 43 | left: 0; 44 | width: 100%; 45 | height: 100%; 46 | background:linear-gradient(#ffbc00, #e23737); 47 | clip-path: circle(25% at right 70%); 48 | z-index: -1; 49 | } 50 | 51 | .main{ 52 | position: absolute; 53 | margin: 0; 54 | padding: 0; 55 | width: 100vw; 56 | height: 100vh; 57 | } 58 | 59 | 60 | 61 | .container{ 62 | position: relative; 63 | display: flex; 64 | margin-right: 20px; 65 | justify-content: center; 66 | align-items: center; 67 | width: 100vw; 68 | flex-wrap: wrap; 69 | z-index: 1; 70 | } 71 | .container .card{ 72 | position: relative; 73 | width: 25%; 74 | min-width: 310px; 75 | height: 400px; 76 | margin: 30px; 77 | box-shadow: 20px 20px 50px rgba(0,0,0,0.5); 78 | border-radius: 20px; 79 | background-color: rgba(255,255,255,0.1); 80 | overflow: hidden; 81 | display: flex; 82 | justify-content: center; 83 | align-items: center; 84 | border-top: rgba(255,255,255,0.5) 1px solid; 85 | border-left: rgba(255,255,255,0.5) 1px solid; 86 | backdrop-filter: blur(8px); 87 | } 88 | .container .card .content{ 89 | padding: 20px; 90 | } 91 | 92 | .container .card h2{ 93 | position: absolute; 94 | user-select:none; 95 | top: 10px; 96 | left: 20px; 97 | font-size: 5em; 98 | color: rgba(255,255,255,0.1); 99 | } 100 | 101 | .header{ 102 | margin-left: 5%; 103 | margin-right: 5%; 104 | margin-top: 30px; 105 | display: flex; 106 | justify-content: start; 107 | flex-wrap: wrap; 108 | } 109 | 110 | .header h1{ 111 | width: 100%; 112 | font-size: 4em; 113 | color: whitesmoke; 114 | } 115 | .header h2{ 116 | margin-top: 20px; 117 | font-size: 1.5em; 118 | color:azure; 119 | } 120 | 121 | .header a{ 122 | margin-left: 30px; 123 | margin-top: 22px; 124 | height: 30px; 125 | position: relative; 126 | display: inline-block; 127 | color: #000; 128 | font-size:small; 129 | font-weight:bold; 130 | border-radius: 20px; 131 | background-color: #fff; 132 | padding: 5px 20px; 133 | } 134 | 135 | .content .info_panel{ 136 | display: flex; 137 | flex-direction: column; 138 | align-items: flex-start; 139 | justify-content: center; 140 | flex-wrap: wrap; 141 | 142 | } 143 | 144 | .info_panel .panel_item{ 145 | margin-top: 10px; 146 | font-size:1.2em; 147 | font-weight: 700; 148 | color:whitesmoke 149 | } 150 | 151 | .card_expand{ 152 | display:none; 153 | position: absolute; 154 | top: 40px; 155 | left: 30px; 156 | right: 30px; 157 | bottom: 30px; 158 | width:90%; 159 | height:85%; 160 | margin:auto; 161 | padding: 30px; 162 | box-shadow: 20px 20px 50px rgba(0,0,0,0.5); 163 | border-radius: 30px; 164 | background-color: rgba(255, 255, 255, 0.8); 165 | overflow: hidden; 166 | display: flex; 167 | justify-content: center; 168 | align-items: center; 169 | border-top: rgba(255,255,255,0.5) 1px solid; 170 | border-left: rgba(255,255,255,0.5) 1px solid; 171 | backdrop-filter: blur(12px); 172 | z-index: 2; 173 | } 174 | 175 | #card_detail{ 176 | width: 100%; 177 | height: 100%; 178 | padding: 20px; 179 | } 180 | 181 | #blur_cover{ 182 | display:none; 183 | position: absolute; 184 | top:0; 185 | margin: 0; 186 | padding: 0; 187 | width: 100%; 188 | height: 100%; 189 | backdrop-filter: blur(12px); 190 | z-index: 1; 191 | } --------------------------------------------------------------------------------