장준영

Merge branch 'server' into 'master'

Server - 표준화 로직 구현

## server 단어 입력에 따른 표준화 로직 구현

1) 단어 입력
2) 한글인지 아닌지 검사
   - 한글 : 자,모음 표준화 시행
   - 영어,숫자,특수문자 포함 : 해당 문자가 있는 곳이 어디인지에 따라 모음위치인지 자음위치인지 판별한뒤, 표준화 시행

See merge request !1
1 -10새,10새기,10새리,10세리,10쉐이,10쉑,10스,10쌔, 10쌔기,10쎄,10알,10창,10탱,18것,18넘,18년,18노,18놈,18뇬,18럼,18롬,18새,18새끼,18색,18세끼,18세리,18섹,18쉑,18스,18아,ㄱㅐ,ㄲㅏ,ㄲㅑ,ㄲㅣ,ㅅㅂㄹㅁ,ㅅㅐ,ㅆㅂㄹㅁ,ㅆㅍ,ㅆㅣ,ㅆ앙,ㅍㅏ,凸, 갈보,갈보년,강아지,같은년,같은뇬,개같은,개구라,개년,개놈,개뇬,개대중,개독,개돼중,개랄,개보지,개뻥,개뿔,개새,개새기,개새끼,개새키,개색기,개색끼,개색키,개색히,개섀끼,개세,개세끼,개세이,개소리,개쑈, 개쇳기,개수작,개쉐,개쉐리,개쉐이,개쉑,개쉽,개스끼,개시키,개십새기, 개십새끼,개쐑,개씹,개아들,개자슥,개자지,개접,개좆,개좌식,개허접,걔새,걔수작,걔시끼,걔시키,걔썌,걸레,게색기,게색끼,광뇬,구녕,구라,구멍,그년,그새끼,냄비,놈현,뇬,눈깔,뉘미럴,니귀미,니기미,니미,니미랄,니미럴,니미씹,니아배,니아베,니아비,니어매,니어메,니어미,닝기리,닝기미,대가리,뎡신,도라이,돈놈,돌아이,돌은놈,되질래,뒈져,뒈져라,뒈진,뒈진다,뒈질, 뒤질래,등신,디져라,디진다,디질래,딩시,따식,때놈,또라이,똘아이,똘아이,뙈놈,뙤놈,뙨넘,뙨놈,뚜쟁,띠바,띠발,띠불,띠팔,메친넘,메친놈,미췬, 미췬,미친,미친넘,미친년,미친놈,미친새끼,미친스까이,미틴,미틴넘,미틴년, 미틴놈,바랄년,병자,뱅마,뱅신,벼엉신,병쉰,병신,부랄,부럴,불알,불할,붕가,붙어먹,뷰웅,븅,븅신,빌어먹,빙시,빙신,빠가,빠구리,빠굴,빠큐,뻐큐,뻑큐,뽁큐,상넘이,상놈을,상놈의,상놈이,새갸,새꺄,새끼,새새끼,새키,색끼,생쑈,세갸,세꺄,세끼,섹스,쇼하네,쉐,쉐기,쉐끼,쉐리,쉐에기,쉐키,쉑,쉣,쉨,쉬발,쉬밸,쉬벌,쉬뻘,쉬펄,쉽알,스패킹,스팽,시궁창,시끼,시댕,시뎅,시랄,시발,시벌,시부랄,시부럴,시부리,시불,시브랄,시팍,시팔,시펄,신발끈,심발끈,심탱,십8,십라,십새,십새끼,십세,십쉐,십쉐이,십스키,십쌔,십창,십탱,싶알,싸가지,싹아지,쌉년,쌍넘,쌍년,쌍놈,쌍뇬,쌔끼, 쌕,쌩쑈,쌴년,썅,썅년,썅놈,썡쇼,써벌,썩을년,썩을놈,쎄꺄,쎄엑, 쒸벌,쒸뻘,쒸팔,쒸펄,쓰바,쓰박,쓰발,쓰벌,쓰팔,씁새,씁얼,씌파,씨8, 씨끼,씨댕,씨뎅,씨바,씨바랄,씨박,씨발,씨방,씨방새,씨방세,씨밸,씨뱅,씨벌,씨벨,씨봉,씨봉알,씨부랄,씨부럴,씨부렁,씨부리,씨불,씨붕,씨브랄, 씨빠,씨빨,씨뽀랄,씨앙,씨파,씨팍,씨팔,씨펄,씸년,씸뇬,씸새끼,씹같,씹년,씹뇬,씹보지,씹새,씹새기,씹새끼,씹새리,씹세,씹쉐,씹스키,씹쌔,씹이,씹자지,씹질,씹창,씹탱,씹퇭,씹팔,씹할,씹헐,아가리,아갈,아갈이,아갈통,아구창,아구통,아굴,얌마,양넘,양년,양놈,엄창,엠병,여물통,염병,엿같,옘병,옘빙,오입,왜년,왜놈,욤병,육갑,은년,을년,이년,이새끼,이새키,이스끼,이스키,임마,자슥,잡것,잡넘,잡년,잡놈,저년,저새끼,접년,젖밥,조까,조까치,조낸,조또,조랭,조빠,조쟁이,조지냐,조진다,조찐, 조질래,존나,존나게,존니,존만, 존만한,좀물,좁년,좆,좁밥,좃까,좃또,좃만,좃밥,좃이,좃찐,좆같,좆까,좆나,좆또,좆만,좆밥,좆이,좆찐,좇같,좇이,좌식,주글,주글래,주데이,주뎅,주뎅이,주둥아리,주둥이,주접,주접떨,죽고잡,죽을래,죽통,쥐랄,쥐롤,쥬디,지랄,지럴,지롤,지미랄,짜식,짜아식,쪼다,쫍빱,찌랄,창녀,캐년,캐놈,캐스끼,캐스키,캐시키,탱구,팔럼,퍽큐,호로,호로놈,호로새끼,호로색,호로쉑,호로스까이,호로스키,후라들,후래자식,후레,후뢰,씨ㅋ발,ㅆ1발,씌발,띠발,띄발,뛰발,띠ㅋ발,뉘뮈
...\ No newline at end of file ...\ No newline at end of file
1 +README.md
2 +package.json
3 +package-lock.json
1 +{
2 + "env": {
3 + "browser": true,
4 + "es6": true
5 + },
6 + "extends": ["airbnb-base", "plugin:prettier/recommended"],
7 + "parserOptions": {
8 + "ecmaVersion": 6,
9 + "sourceType": "module"
10 + },
11 + "plugins": ["prettier"],
12 + "rules": {
13 + "semi": "error",
14 + "prettier/prettier": [
15 + "error",
16 + {
17 + "endOfLine": "auto"
18 + }
19 + ]
20 + }
21 +}
1 +#
2 +node_modules
3 +package-lock.json
4 +.DS_Store
5 +.env
...\ No newline at end of file ...\ No newline at end of file
1 +{
2 + "singleQuote": true,
3 + "semi": true,
4 + "useTabs": false,
5 + "tabWidth": 2,
6 + "trailingComma": "all",
7 + "printWidth": 100,
8 + "endOfLine": "lf"
9 + }
10 +
...\ No newline at end of file ...\ No newline at end of file
1 +const createError = require('http-errors');
2 +const express = require('express');
3 +const path = require('path');
4 +const cookieParser = require('cookie-parser');
5 +const logger = require('morgan');
6 +
7 +const indexRouter = require('./routes/index');
8 +
9 +const app = express();
10 +
11 +// view engine setup
12 +app.set('views', path.join(__dirname, 'views'));
13 +app.set('view engine', 'jade');
14 +
15 +app.use(logger('dev'));
16 +app.use(express.json());
17 +app.use(express.urlencoded({ extended: false }));
18 +app.use(cookieParser());
19 +app.use(express.static(path.join(__dirname, 'public')));
20 +
21 +app.use('/', indexRouter);
22 +
23 +// catch 404 and forward to error handler
24 +app.use(function (req, res, next) {
25 + next(createError(404));
26 +});
27 +
28 +module.exports = app;
1 +#!/usr/bin/env node
2 +
3 +/**
4 + * Module dependencies.
5 + */
6 +
7 +var app = require('../app');
8 +var debug = require('debug')('server:server');
9 +var http = require('http');
10 +
11 +/**
12 + * Get port from environment and store in Express.
13 + */
14 +
15 +var port = normalizePort(process.env.PORT || '3000');
16 +app.set('port', port);
17 +
18 +/**
19 + * Create HTTP server.
20 + */
21 +
22 +var server = http.createServer(app);
23 +
24 +/**
25 + * Listen on provided port, on all network interfaces.
26 + */
27 +
28 +server.listen(port);
29 +server.on('error', onError);
30 +server.on('listening', onListening);
31 +
32 +/**
33 + * Normalize a port into a number, string, or false.
34 + */
35 +
36 +function normalizePort(val) {
37 + var port = parseInt(val, 10);
38 +
39 + if (isNaN(port)) {
40 + // named pipe
41 + return val;
42 + }
43 +
44 + if (port >= 0) {
45 + // port number
46 + return port;
47 + }
48 +
49 + return false;
50 +}
51 +
52 +/**
53 + * Event listener for HTTP server "error" event.
54 + */
55 +
56 +function onError(error) {
57 + if (error.syscall !== 'listen') {
58 + throw error;
59 + }
60 +
61 + var bind = typeof port === 'string'
62 + ? 'Pipe ' + port
63 + : 'Port ' + port;
64 +
65 + // handle specific listen errors with friendly messages
66 + switch (error.code) {
67 + case 'EACCES':
68 + console.error(bind + ' requires elevated privileges');
69 + process.exit(1);
70 + break;
71 + case 'EADDRINUSE':
72 + console.error(bind + ' is already in use');
73 + process.exit(1);
74 + break;
75 + default:
76 + throw error;
77 + }
78 +}
79 +
80 +/**
81 + * Event listener for HTTP server "listening" event.
82 + */
83 +
84 +function onListening() {
85 + var addr = server.address();
86 + var bind = typeof addr === 'string'
87 + ? 'pipe ' + addr
88 + : 'port ' + addr.port;
89 + debug('Listening on ' + bind);
90 +}
1 +const db = require('../model/db');
2 +const profanity1 = require('./profanity1.json');
3 +const profanity2 = require('./profanity2.json');
4 +
5 +const insertDB = async () => {
6 + let sumOfProfanity = [...new Set([...profanity1.profanity,...profanity2.profanity])];
7 + sumOfProfanity = sumOfProfanity.map((element) => [element]);
8 + try {
9 + const insertQuery = "insert into profanity (content) values ?;";
10 + const result = await db.query(insertQuery, [sumOfProfanity]);
11 + console.log('yes');
12 + } catch (err) {
13 + console.log(err);
14 + }
15 +}
16 +
17 +module.exports = insertDB;
...\ No newline at end of file ...\ No newline at end of file
1 { 1 {
2 - "badwords": [ 2 + "profanity": [
3 "10새", 3 "10새",
4 "10새기", 4 "10새기",
5 "10새리", 5 "10새리",
......
1 +{
2 + "profanity": [
3 + "10새","10새기","10새리","10세리","10쉐이","10쉑","10스","10쌔", "10쌔기","10쎄","10알",
4 + "10창","10탱","18것","18넘","18년","18노","18놈","18뇬","18럼","18롬","18새","18새끼","18색","18세끼","18세리","18섹","18쉑","18스",
5 + "18아","ㄱㅐ","ㄲㅏ","ㄲㅑ","ㄲㅣ","ㅅㅂㄹㅁ","ㅅㅐ","ㅆㅂㄹㅁ","ㅆㅍ","ㅆㅣ","ㅆ앙","ㅍㅏ","凸", "갈보","갈보년","강아지","같은년","같은뇬",
6 + "개같은","개구라","개년","개놈","개뇬","개대중","개독","개돼중","개랄","개보지","개뻥","개뿔","개새","개새기","개새끼","개새키","개색기","개색끼",
7 + "개색키","개색히","개섀끼","개세","개세끼","개세이","개소리","개쑈", "개쇳기","개수작","개쉐","개쉐리","개쉐이","개쉑","개쉽","개스끼","개시키",
8 + "개십새기", "개십새끼","개쐑","개씹","개아들","개자슥","개자지","개접","개좆","개좌식","개허접","걔새","걔수작","걔시끼","걔시키","걔썌","걸레","게색기",
9 + "게색끼","광뇬","구녕","구라","구멍","그년","그새끼","냄비","놈현","뇬","눈깔","뉘미럴","니귀미","니기미","니미","니미랄","니미럴","니미씹","니아배","니아베",
10 + "니아비","니어매","니어메","니어미","닝기리","닝기미","대가리","뎡신","도라이","돈놈","돌아이","돌은놈","되질래","뒈져","뒈져라","뒈진","뒈진다","뒈질",
11 + "뒤질래","등신","디져라","디진다","디질래","딩시","따식","때놈","또라이","똘아이","똘아이","뙈놈","뙤놈","뙨넘","뙨놈","뚜쟁","띠바","띠발","띠불","띠팔","메친넘",
12 + "메친놈","미췬", "미췬","미친","미친넘","미친년","미친놈","미친새끼","미친스까이","미틴","미틴넘","미틴년", "미틴놈","바랄년","병자","뱅마","뱅신","벼엉신",
13 + "병쉰","병신","부랄","부럴","불알","불할","붕가","붙어먹","뷰웅","븅","븅신","빌어먹","빙시","빙신","빠가","빠구리","빠굴","빠큐","뻐큐","뻑큐","뽁큐","상넘이",
14 + "상놈을","상놈의","상놈이","새갸","새꺄","새끼","새새끼","새키","색끼","생쑈","세갸","세꺄","세끼","섹스","쇼하네","쉐","쉐기","쉐끼","쉐리","쉐에기","쉐키","쉑","쉣",
15 + "쉨","쉬발","쉬밸","쉬벌","쉬뻘","쉬펄","쉽알","스패킹","스팽","시궁창","시끼","시댕","시뎅","시랄","시발","시벌","시부랄","시부럴","시부리","시불","시브랄","시팍","시팔",
16 + "시펄","신발끈","심발끈","심탱","십8","십라","십새","십새끼","십세","십쉐","십쉐이","십스키","십쌔","십창","십탱","싶알","싸가지","싹아지","쌉년","쌍넘","쌍년","쌍놈","쌍뇬",
17 + "쌔끼", "쌕","쌩쑈","쌴년","썅","썅년","썅놈","썡쇼","써벌","썩을년","썩을놈","쎄꺄","쎄엑", "쒸벌","쒸뻘","쒸팔","쒸펄","쓰바","쓰박","쓰발","쓰벌","쓰팔","씁새","씁얼",
18 + "씌파","씨8", "씨끼","씨댕","씨뎅","씨바","씨바랄","씨박","씨발","씨방","씨방새","씨방세","씨밸","씨뱅","씨벌","씨벨","씨봉","씨봉알","씨부랄","씨부럴","씨부렁","씨부리",
19 + "씨불","씨붕","씨브랄", "씨빠","씨빨","씨뽀랄","씨앙","씨파","씨팍","씨팔","씨펄","씸년","씸뇬","씸새끼","씹같","씹년","씹뇬","씹보지","씹새","씹새기","씹새끼","씹새리",
20 + "씹세","씹쉐","씹스키","씹쌔","씹이","씹자지","씹질","씹창","씹탱","씹퇭","씹팔","씹할","씹헐","아가리","아갈","아갈이","아갈통","아구창","아구통","아굴","얌마","양넘",
21 + "양년","양놈","엄창","엠병","여물통","염병","엿같","옘병","옘빙","오입","왜년","왜놈","욤병","육갑","은년","을년","이년","이새끼","이새키","이스끼","이스키","임마","자슥",
22 + "잡것","잡넘","잡년","잡놈","저년","저새끼","접년","젖밥","조까","조까치","조낸","조또","조랭","조빠","조쟁이","조지냐","조진다","조찐","조질래","존나","존나게","존니",
23 + "존만", "존만한","좀물","좁년","좆","좁밥","좃까","좃또","좃만","좃밥","좃이","좃찐","좆같","좆까","좆나","좆또","좆만","좆밥","좆이","좆찐","좇같","좇이","좌식","주글",
24 + "주글래","주데이","주뎅","주뎅이","주둥아리","주둥이","주접","주접떨","죽고잡","죽을래","죽통","쥐랄","쥐롤","쥬디","지랄","지럴","지롤","지미랄","짜식","짜아식","쪼다",
25 + "쫍빱","찌랄","창녀","캐년","캐놈","캐스끼","캐스키","캐시키","탱구","팔럼","퍽큐","호로","호로놈","호로새끼","호로색","호로쉑","호로스까이","호로스키","후라들","후래자식",
26 + "후레","후뢰","씨ㅋ발","ㅆ1발","씌발","띠발","띄발","뛰발","띠ㅋ발","뉘뮈"
27 + ]
28 +}
...\ No newline at end of file ...\ No newline at end of file
1 +const mysql = require('mysql2/promise');
2 +const dotenv = require('dotenv');
3 +const path = require('path');
4 +
5 +dotenv.config({path:path.join(__dirname, "../.env")});
6 +
7 +const db = mysql
8 + .createPool({
9 + host: process.env.DB_HOST,
10 + user: process.env.DB_USER,
11 + port: process.env.DB_PORT,
12 + password: process.env.DB_PASSWORD,
13 + database: process.env.DB_DATABASE,
14 + connectionLimit: 10,
15 + });
16 +
17 +module.exports = db;
1 +{
2 + "name": "server",
3 + "version": "0.0.0",
4 + "private": true,
5 + "scripts": {
6 + "start": "node ./bin/www",
7 + "dev": "nodemon ./bin/www"
8 + },
9 + "dependencies": {
10 + "cookie-parser": "~1.4.4",
11 + "debug": "~2.6.9",
12 + "dotenv": "^8.2.0",
13 + "express": "~4.16.1",
14 + "hangul-js": "^0.2.6",
15 + "http-errors": "~1.6.3",
16 + "jade": "~1.11.0",
17 + "morgan": "~1.9.1",
18 + "mysql2": "^2.2.5"
19 + },
20 + "devDependencies": {
21 + "eslint": "^7.15.0",
22 + "eslint-config-airbnb-base": "^14.2.1",
23 + "eslint-config-prettier": "^7.0.0",
24 + "eslint-plugin-import": "^2.22.1",
25 + "eslint-plugin-prettier": "^3.2.0",
26 + "prettier": "^2.2.1"
27 + }
28 +}
1 +const express = require('express');
2 +
3 +const router = express.Router();
4 +
5 +/* GET home page. */
6 +router.post('/checkProfanity', (req, res) => {
7 + res.send('hello');
8 +});
9 +
10 +module.exports = router;
1 +/* eslint-disable no-use-before-define */
2 +/* eslint-disable no-restricted-syntax */
3 +const Hangul = require('hangul-js');
4 +
5 +const standardize = (word) => {
6 + let result = '';
7 + let newLetter = '';
8 + const disassembledWord = Hangul.disassemble(word);
9 + for (const [index, letter] of disassembledWord.entries()) {
10 + if (isKorean(letter)) {
11 + newLetter = Hangul.isConsonant(letter)
12 + ? standardizeConsonent(letter)
13 + : standardizeVowel(letter);
14 + } else {
15 + const preLetter = index === 1 ? '' : disassembledWord[index - 1];
16 + const nextLetter = index === disassembledWord.length - 1 ? '' : disassembledWord[index + 1];
17 + newLetter = isVowelSpecial(preLetter, letter, nextLetter)
18 + ? standardizeSpecialVowel(letter)
19 + : standardizeSpecialConsonent(letter);
20 + }
21 + result += newLetter;
22 + }
23 + return result;
24 +};
25 +
26 +const isKorean = (word) => {
27 + const numCheck = /[0-9]/; // 숫자
28 +
29 + const engCheck = /[a-zA-Z]/; // 문자
30 +
31 + const specialCheck = /[~!@#$%^&*()_+|<>?:{}]/; // 특수문자
32 +
33 + if (!numCheck.test(word) && !engCheck.test(word) && !specialCheck.test(word)) {
34 + return true;
35 + }
36 + return false;
37 +};
38 +
39 +const standardizeConsonent = (letter) => {
40 + switch (letter) {
41 + case ('ㄱ', 'ㄲ', 'ㅋ'):
42 + return 'ㄱ';
43 + case ('ㄷ', 'ㄸ', 'ㅌ'):
44 + return 'ㄷ';
45 + case ('ㅂ', 'ㅃ', 'ㅍ'):
46 + return 'ㅂ';
47 + case ('ㅅ', 'ㅆ'):
48 + return 'ㅅ';
49 + case ('ㅈ', 'ㅉ', 'ㅊ'):
50 + return 'ㅈ';
51 + default:
52 + return letter;
53 + }
54 +};
55 +
56 +const standardizeVowel = (letter) => {
57 + switch (letter) {
58 + case ('ㅏ', 'ㅑ'):
59 + return 'ㅏ';
60 + case ('ㅗ', 'ㅛ'):
61 + return 'ㅗ';
62 + case ('ㅐ', 'ㅒ', 'ㅔ', 'ㅖ', 'ㅙ', 'ㅚ', 'ㅝ', 'ㅞ'):
63 + return 'ㅐ';
64 + case ('ㅜ', 'ㅠ'):
65 + return 'ㅜ';
66 + case ('ㅓ', 'ㅕ'):
67 + return 'ㅓ';
68 + case ('ㅟ', 'ㅢ', 'ㅣ'):
69 + return 'ㅣ';
70 + default:
71 + return letter;
72 + }
73 +};
74 +
75 +const isVowelSpecial = (preLetter, letter, nextLetter) => {
76 + if (preLetter !== '') {
77 + if (nextLetter === '') {
78 + if (isKorean(preLetter)) {
79 + if (Hangul.isConsonant(preLetter)) {
80 + return true;
81 + }
82 + }
83 + } else if (isKorean(preLetter) && isKorean(nextLetter)) {
84 + if (Hangul.isConsonant(preLetter) && Hangul.isConsonant(nextLetter)) {
85 + return true;
86 + }
87 + }
88 + }
89 +
90 + return false;
91 +};
92 +
93 +const standardizeSpecialConsonent = (letter) => {
94 + switch (letter) {
95 + case ('g', 'ㅑ'):
96 + return 'ㅏ';
97 + case ('ㅗ', 'ㅛ'):
98 + return 'ㅗ';
99 + case ('ㅐ', 'ㅒ', 'ㅔ', 'ㅖ', 'ㅙ', 'ㅚ', 'ㅝ', 'ㅞ'):
100 + return 'ㅐ';
101 + case ('ㅜ', 'ㅠ'):
102 + return 'ㅜ';
103 + case ('ㅓ', 'ㅕ'):
104 + return 'ㅓ';
105 + case ('ㅟ', 'ㅢ', 'ㅣ'):
106 + return 'ㅣ';
107 + default:
108 + return letter;
109 + }
110 +};
111 +
112 +const standardizeSpecialVowel = (letter) => {
113 + switch (letter) {
114 + case ('g', 'ㅑ'):
115 + return 'ㅏ';
116 + case ('ㅗ', 'ㅛ'):
117 + return 'ㅗ';
118 + case ('ㅐ', 'ㅒ', 'ㅔ', 'ㅖ', 'ㅙ', 'ㅚ', 'ㅝ', 'ㅞ'):
119 + return 'ㅐ';
120 + case ('ㅜ', 'ㅠ'):
121 + return 'ㅜ';
122 + case ('ㅓ', 'ㅕ'):
123 + return 'ㅓ';
124 + case ('ㅟ', 'ㅢ', 'ㅣ'):
125 + return 'ㅣ';
126 + default:
127 + return letter;
128 + }
129 +};
130 +
131 +module.exports = { standardize };