예전에 만들었던 한>중>한 번역기를 개선하기로 했다. 하는 김에 디스코드 봇도 개발하기로 결정했다.
사실 예전에 discord.js로 개발하다 도저히 내 맘대로 되지 않아서 방치해 두었기에 그런 실패도 극복해보고 싶었다.
단순히 discord.py를 이용해 봇을 개발한다면 전부 다 파이썬으로 개발해도 된다.
그런데 왠지 C# 으로 만들어놓은 것을 다시 파이썬으로 옮기기 귀찮았고 파이썬 상에서 dll을 활용하는 방법이 공부가 되지 않을까... 생각했다.
이번엔 글을 2 파트로 나눴고, 1에서는 라이브러리 개선사항을, 2에서는 봇 관련 내용으로 채울 예정이다.
기존에 쓰던 바이두 번역 API를 사용할 수 없게 되어서 파파고 API로 교체했다. 사용하기는 확실히 이쪽이 편한 듯.
교체하면서 코드 구조도 살짝 바꾸었다.
먼저 역직렬화 된 JSON 형태를 받을 클래스를 별도의 파일로 분리했다. 저번엔 같은 cs 파일에 내용물을 다 때려 넣었는데 정리를 하면서 별도의 파일로 분리했는데, 역시 이게 맞는 것 같다.
번역 API 코드는 네이버에서 제공하는 예제를 그대로 가져와서 내가 쓰기 좋게 변형을 살짝 했다.
public Translator(string Id, string Secret, string D_Id, string D_Secret)
{
url = "https://openapi.naver.com/v1/papago/n2mt";
Cliend_Id = Id;
Cliend_Secret = Secret;
Dect_Cliend_Id = D_Id;
Dect_Cliend_Secret = D_Secret;
list = new List<Tuple<string, string>>();
list.Add(new Tuple<string, string>("ko", "fr"));
list.Add(new Tuple<string, string>("fr", "en"));
list.Add(new Tuple<string, string>("en", "zh-CN"));
list.Add(new Tuple<string, string>("zh-CN", "ko"));
}
Translator 클래스의 생성자를 만든다.
번역과 언어 감지를 같이 활용할 것이기 때문에 둘의 Id와 Secret을 생성자에서 받아준다.
최대한 번역의 질을 떨어뜨릴 것이기 때문에 다중 번역을 수행할 것이다.나중에 사용할 List도 초기화 해 준다.
public string getDst(string input, bool insert = true)
{
PapagoLangDetector dect = new PapagoLangDetector(Dect_Cliend_Id, Dect_Cliend_Secret);
string output;
if(!dect.Detect(input))
return "입력된 문자열이 한국어가 아닙니다.";
output = getResponse(input, 0);
if (insert == true)
{
Random rnd = new Random();
int rndVal;
int tmp = 1;
int leng = output.Length;
while (tmp < leng)
{
rndVal = rnd.Next(1, 5);
if (output[tmp].Equals(" "))
{
//output = output.Insert(tmp + 1, " ");
tmp++;
}
else
output = output.Insert(tmp, " ");
tmp += rndVal;
leng = output.Length;
}
}
return output;
}
사용자로부터 입력을 받을 함수인 getDst().
첫 입력은 무조건 한국어로 받을 것이기 때문에 언어 감지를 활용해서 한국어인지 확인한다.
한국어가 아니라면 한국어가 아님을 알리는 문자열을 리턴하고 종료한다.
번역된 문자열을 받고 나서 insert가 True라면 받은 문자열에 랜덤으로 공백을 삽입한다.
공백 삽입은 문자열이 길어지면 문자열 끝까지 공백을 넣어주지 못하고 종료하는 문제가 있었는데,
leng이 문자열의 첫 상태의 길이를 저장하고 있었기 때문에 중간에 공백이 삽입되면서 길어지는 output의 길이를 반영하지 못했기에 벌어지는 문제였다.
tmp가 커짐에 따라 leng도 커지게 만들어서 해결.
PapagoResponse desJson = JsonConvert.DeserializeObject<PapagoResponse>(output);
stream.Close();
response.Close();
reader.Close();
if(i == 3)
return desJson.message.result.translatedText;
return getResponse(desJson.message.result.translatedText, ++i);
getResponse()의 마지막 부분이다.
다중번역을 수행하는 데 있어서 처음엔 단순히 for문을 떠올렸지만 뭔가 느낌이 없었다.
어차피 출력을 다시 입력으로 받을 것이기에 재귀로 구현하면 딱이라는 생각이 들어서 재귀로 구현했다.
코드가 깔끔해져서 보기가 좋아졌다.
이제 별도의 콘솔 프로젝트를 만들어서 제대로 동작하는지 확인하자.
의도한 대로 잘 동작한다. 긴 문자열을 넣은 테스트는 어제 실컷 했다.
아무래도 다중번역을 수행하다 보니 API 호출량이 무시무시한 속도로 오른다.
추후 사용량에 따라선 번역 중첩 횟수를 줄이든가 할 것 같다.
사실 API만 교체했지 기본적인 개념은 이전에 바이두 API를 사용한 때와 다른 것이 없기 때문에,
코드의 변경점만 기술했다.
'Study > C++ & C#' 카테고리의 다른 글
[C++] 스마트 포인터 (0) | 2023.02.04 |
---|---|
[C++] 다중 포인터 (0) | 2023.01.27 |
[C++] 포인터 기초 (0) | 2023.01.26 |
[C#, Python] C# 라이브러리를 이용한 discord.py 봇 개발 (2/2) (0) | 2023.01.15 |
[C#] WPF로 만들어 본 한>중>한 번역기 (0) | 2022.12.31 |