개발프로그램2023. 3. 16. 15:29

열차 알리미 프로그램의 사용방법을 자세히 알려드리겠습니다.

 

열차 알리미는 KTX / SRX / ITX / 새마을호 / 무궁화호 / 통근열차 등의 열차 승차권이 나왔을때 (예매 가능) 알려주는 프로그램입니다.

 

프로그램은 아래 링크에서 다운 받으실 수 있습니다.

https://bemeal2.tistory.com/318

 

 

 

1. 예약정보 설정하기

 

 

 

 

 

1. 열차선택

    Finder 탭에서, 예약하고자 하는 열차의 - 열차구분 출발역 도착역 출발일자 출발시간 인원 좌석종류 등을 선택합니다.

 

2. 탐색설정

   Interval / Limit Count 를 설정합니다.

   Interval 은 예약탐색중간 의 대기 기간입니다.

   5 ~ 10 으로 설정되어 있다면, 예약확인하고, 다음번 예약확인까지 5,000~10,000(밀리초) 사이의 랜덤값으로 대기후에, 다시 예약을 확인하게 됩니다.

   Limit Count 는 예약확인하여, 성공하기 까지, 몇번을 예약확인 try(탐색) 할지 한도를 설정합니다.

 

3. [추가버튼]

   신규등록시에는 추가 버튼을 누르면, 상단으로 입력한 예약정보가 입력이 되고,

   수정 모드에서는 수정 버튼이 활성화 됩니다.

 

4. 탐색 목록 확인

   추가/수정된 결과목록이 나오며, 이 목록을 선택하고, 탐색 시작을 할 수 있습니다.

 

 

1-1. 예약대기 가능시 알림

 

예약대기는 코레일 예약사이트에서만 이용 가능한 서비스입니다.

예약대기를 신청하면, 실제 예약가능한 자리가 나오면 좌석배정이 됩니다.

좌석배정이 되면, 당일 24:00분까지 결제하면 예약이 완료됩니다.

 

 

 

 

[예약대기] 도 모두 매진 상태일때,

 

[예약대기 가능시 알림] 선택해 놓으면,

와 같이 코레일 사이트에서 예약대기가 가능할 때 알려주게 됩니다.

 

 

 

 

 

 

 

 

2. 탐색 시작하기

 

 

 

 

탐색을 시작할 예약데이터를 선택합니다.

Start 버튼을 누르면, 탐색이 시작 됩니다.

 

Interval 간격으로 주기적으로, 예약이 가능한지 체크를 하게 되며,

LimitCount 까지 체크하고, 못찾으면 자동 종료됩니다.

 

 

 

3. 예약 가능 알림 받기

 

 

탐색이 시작되고, 티켓 예약이 가능할때 알림이 전송 됩니다.

 

 

 

Sound 에 체크가 되어 있다면, 탐색성공시 스피커로 팡파레 소리가 나오게 됩니다.

 

메신저 알림이 등록되어 있다면, 메신저로도 알림이 발송 됩니다.

 

 

 

 

 

링크 : Telegram 토큰 생성 방법
링크 : Slack 토큰 생성 방법
링크 : Line 토큰 생성 방법

 

 

 

 

 

 

탐색 성공시  웹브라우저 열기를 설정하면,

네이버예매사이트 또는 코레일 사이트로 웹브라우저가 자동으로 띄어집니다.

 

 

 

 

 

 

쿨타임기능은, 탐색성공후에 지정된 시간만큼 휴식후에 탐색을 재개하는 기능입니다.

(없음 : 탐색성공후 바로 종료)

 

 

Posted by 헝개
개발프로그램2023. 3. 16. 14:00

열차 알리미는 KTX / SRX / ITX / 새마을호 / 무궁화호 등의 열차 승차권이 나왔을때 (예매 가능) 알려주는 프로그램입니다.

 

코레일 사이트에서 예매가능한 열차에 대해서 알림을 받을 수 있습니다.

KTX/SRT
ITX-청춘
새마을호/ITX-새마을
무궁화호/누리로

 

 

 

 

Finder 에서 열차구분 / 인원 / 날짜 / 시간 등의 정보를 입력하고, 추가를 누루면, 상단 예약 목록으로 추가 됩니다.

상단 목록을 선택하고 Start 를 누루면, 예매 가능한 승차권이 있을때 알림을 받을 수 있습니다.

 

예약일자와 열차구분에 맞는 좌석이 나오면, [탐색성공]에 텍스트로 표시가 되며, 스피커를 통해서 Sound 를 내보내고, 
Telegram, Slack, Line 메신저로 푸시 메세지를 보내주고, PC에서는 바로 웹브라우저/웹뷰를 띄어주게 된다.

(링크 : Telegram 토큰 생성 방법)
(링크 : Slack 토큰 생성 방법)
(링크 : Line 토큰 생성 방법)

 

 

ps. 윈도우7 이상, 닷넷 프레임웍 4.8 이상이 설치되어 있어야 실행됩니다.

 

 

자세한 사용방법 안내

bemeal2.tistory.com/295

 

 

(주의사항)

 

1. 개인적인 용도로만 사용해야 하며, 
2. 본 프로그램을 사용시, 코레일 예매사이트 서버에 부하를 일으키게 되면, 즉각 사용을 중지해야 하며, 
3. 본 프로그램을 사용하다 발생하는 모든 책임은 사용자에게 있습니다.

4. 열차 티켓을 매점매석하거나, 되파는 행위는 법적인 처벌을 받을 수 있습니다.

 

 

TrainNotifier_v1.0.8.zip
2.27MB

 

 

 

압축을 풀고 TrainNotifier.exe 를 실행하세요.

readme.txt 파일을 읽어주세요.

 

 

 

본 프로그램의 첨부파일을 다른곳에 게시하실 수 없습니다. 
블로그 링크를 올리거나 소개하는 것은 전혀 상관이 없습니다.
카페가 블로그 등에 많은 소개 부탁드립니다.

 

Posted by 헝개
개발팁2022. 10. 28. 15:26

LINE 메신저의 그룹에서 그룹을 추가한다.

 

 

 

그룹을 만들때는 알림을 받아야 하기 때문에,

 

 

LINE Notify 를 선택해줘야 한다.

 

LINE Notify 가 친구에 안나온다면, 친구추가를 먼저 하고 진행해야 한다.

 

 

 

 

 

 

이제 웹브라우저로 아래 링크에 들어가서,

 

API 토큰을 생성해야 한다.

 

 

https://notify-bot.line.me/

 

 

 

로그인후에, 상단 오른쪽의 이름을 클릭하고, My page 로 들어가서,

 

Generate token 을 클릭한다.

 

 

 

 

 

 

아까 만들었던 그룹명을 선택한다.

 

Generate token 을 누르면, token 이 생성된다.

 

 

 

API 문서는 이 사이트에서 볼 수 있다.

 

https://notify-bot.line.me/doc/en/

 

 

API 메서드가 여러개가 있는데, 이중에 메세지 전송하는 API 만 보면 아래와 같다.

 

 

 

간단하게

POST 로 https://notify-api.line.me/api/notify 를 호출하면 되고,
인증은 Bearer 에 위에서 생상한 token 을 넣어주면 되고,
메세지는 form data 로
message=test_message

 

이렇게 호출해주면 메세지가 전송이 된다.

 

curl -X POST -H "Authorization: Bearer 토큰을이곳에입력하세요" -F "message=foobar" https://notify-api.line.me/api/notify

 

command 창에서 위와같이 실행해보면, 메세지가 전송되는걸 볼 수 있다.

 

 

 

Posted by 헝개
개발팁2022. 7. 27. 15:56

타자게임이란 키보드 타자 연습을 위한 게임으로,

한라인의 문장을 제시해주고, 똑같이 입력하면 성공, 그렇지 못하면 실패로 체크하고,

성공하면, 분당 타수를 알려주는, 간단한 게임을 말한다.

 

개인적으로 혼자서 연습도 가능하지만, 이를 채팅방에 적용하면, 다수의 사람과 경쟁을 통해 성취감을 얻을 수도 있다.

 

타자게임을 만들때 필요한 것은,

 

1. 한글 한줄 문장 데이터이다.

2. 한글을 초/중/종 성으로 쪼개는 작업이 필요하다.

3. 분당 타수를 계산하는 로직을 적용하면 된다.

 

 

 

 

 

프로그램은 시작 버튼을 누르면, 제시어를 보여주고, 똑같이 입력을 하면, 결과를 보여준다.

 

 

 

1. 한글 한줄 문장 데이터이다.

 

문장 데이터는 많을수록 좋다.

 

 

한컴 타자연습 사이트 - 짧은글 연습에서 문장을 가져왔다.

 


2692개의 문장이 제공되고 있다.

 

해당 문장은 DB 에 입력해서 꺼내와도 되고, 구글시트에 넣어놓고 꺼내와도 상관없다.

 

예제는 구글시트에 한줄 문장을 관리하기 때문에, 구글API 가 필요하다.

 

nuget 패키지 관리자에서, Google.Apis.Sheets.v4 를 설치한다.

 

 

 

public static List<string> GetTypingSentenceList()
{
List<string> result;

string _apikey = "***********************";
string _sheetid = "***********************";

result = new List<string>();

try
{
// API 서비스 생성
var service = new SheetsService(new BaseClientService.Initializer()
{
ApplicationName = "GoogleDocs .net API",
ApiKey = _apikey
});

var request = service.Spreadsheets.Values.Get(_sheetid, "타자!A1:A");

ValueRange response = request.Execute();
IList<IList<Object>> values = response.Values;
if (values != null && values.Count > 0)
{
foreach (var row in values)
{
if (row[0] != null && row[0].ToString() != "")
result.Add(row[0].ToString());
}
}

}
catch (Exception e1)
{
MessageBox.Show(e1.Message);
}

return result;
}

 

전체 한줄문장 목록은 이렇게 google sheet 에서 읽어오면 된다.

 

이렇게 읽어온 데이터는 캐시에 저장해두었다가, 요청시마다 꺼내서, 랜덤하게 한 라인을 select 하면 된다.

 

 

시작버튼 클릭시 처리 로직

 

Random rand = new Random();

// 문장 뽑기
List<string> sentence_list = GoogleDocsRepository.GetTypingSentenceList();
int rndNum = rand.Next(0, sentence_list.Count);
string sentence = sentence_list[rndNum].Trim();

this.txtKeyword.Text = sentence;

// 타자수 계산 : 1. 글자를 초/중/종 성으로 쪼갠다.
string[] split_words = HangulWorker.GetDisassemble(sentence, true);
// 타자수 계산 : 2. 글자수를 계산한다.
this._typingCount = HangulWorker.GetTypingSize(split_words);

this._isStart = true;
this._isKeyKirstPress = false;
this.txtInput.Focus();

 

이제 TextBox 에 첫 글자가 입력되는 순간부터 시간을 재고, 단어 입력이 끝나면, 결과를 발표하면 된다.

 

 

2. 한글을 초/중/종 성으로 쪼개는 작업이 필요하다.

 

제시어에서 글자를 모두 초/중/종 성으로 쪼개서, 타자수를 계산해야한다.

한글이라고 모두 2번의 타자가 아니기 때문이다.

 

안녕하세요 를 초/중/종 성으로 쪼개면

ㅇ ㅏ ㄴ ㄴ ㅕ ㅇ ㅎ ㅏ ㅅ ㅔ ㅇ ㅇ

12글자가 되는 것이다.

 

이중에 된발음 ㄲ, ㄸ 이런 글자는 shift 키를 누르고 글짜를 누르기 때문에, 두번의 타자로 계산할지 정의가 필요하다.

예제에서는 한번의 타자로 계산했다.

 

또한 종성에서는

갉 갏 값  등으로 ㄺ ㅀ ㅄ 등의 글자들이 있는데, 이 종성 글자들은 타자수 두번으로 계산해야 한다.

 

시작버튼 클릭시 처리 로직에서 사용한 HangulWorker 의 기본 코드

 

// 유니코드표에서의 기본 위치
private const int hangulStartingPoint = 0xAC00;  // hangulStartingPoint : 유니코드에서 '가'의 위치

// 자소 목록
private static List<string> chosungHangulWords = (
new string[] { "ㄱ", "ㄲ", "ㄴ", "ㄷ", "ㄸ", "ㄹ", "ㅁ", "ㅂ", "ㅃ", "ㅅ"
 , "ㅆ", "ㅇ", "ㅈ", "ㅉ", "ㅊ", "ㅋ", "ㅌ", "ㅍ", "ㅎ" }
).ToList<string>();    // 초성 19개 요소
private static List<string> jungsungHangulWords = (
   new string[] { "ㅏ", "ㅐ", "ㅑ", "ㅒ", "ㅓ", "ㅔ", "ㅕ", "ㅖ", "ㅗ", "ㅘ"
 , "ㅙ", "ㅚ", "ㅛ", "ㅜ", "ㅝ", "ㅞ", "ㅟ", "ㅠ", "ㅡ", "ㅢ"
 , "ㅣ" }
   ).ToList<string>();    // 중성 21개 요소
private static List<string> jongsungHangulWords = (
   new string[] { string.Empty, "ㄱ", "ㄲ", "ㄳ", "ㄴ", "ㄵ", "ㄶ", "ㄷ", "ㄹ", "ㄺ"
 , "ㄻ", "ㄼ", "ㄽ", "ㄾ", "ㄿ", "ㅀ", "ㅁ", "ㅂ", "ㅄ", "ㅅ"
 , "ㅆ", "ㅇ", "ㅈ", "ㅊ", "ㅋ", "ㅌ", "ㅍ", "ㅎ" }
   ).ToList<string>();    // 종성 28개 요소

 

아래는, 한글문장을 초/중/종 성의 글자별로 쪼개는 GetDisassemble 함수 본문이다.

 

public static string[] GetDisassemble(string str, bool bSkipBase)
{
if (str == "") return null;

List<string> list = new List<string>();
int uniValue;   // 유니코드 상의 글자 위치
int iTemp;
string s;

for (int n = 0; n < str.Length; n++)
{
uniValue = 0;
s = str.Substring(n, 1);
byte[] bytes = Encoding.Unicode.GetBytes(s);
// 빅앤디안 방식이지만 아래 계산 편이를 위해 리틀앤디안으로 변환


// 유니코드 상의 글자 위치 구하기
for (int b = 0; b < bytes.Length; b++)
{
uniValue += (int)(bytes[b] * Math.Pow(256.0, b));
}

if (uniValue < hangulStartingPoint) { list.Add(s); continue; }

// 초성
list.Add(chosungHangulWords[(uniValue - hangulStartingPoint) / jongsungMultiply]);


// 중성
list.Add(jungsungHangulWords[(uniValue - hangulStartingPoint) % jongsungMultiply / jongsungHangulWords.Count]);

// 종성
iTemp = (uniValue - hangulStartingPoint) % jongsungHangulWords.Count;
if (bSkipBase && iTemp == 0) continue;
list.Add(jongsungHangulWords[iTemp]);
}

return list.ToArray();
}

 

GetDisassemble  에서 쪼개진 글자 배열에서 타자수를 계산하는 GetTypingSize 함수 본문이다.

 

public static int GetTypingSize(string[] str_list)
{
int addCount = str_list.Select(d => d == "ㅘ" || d == "ㅙ" || d == "ㅚ" || d == "ㅝ" || d == "ㅞ" || d == "ㅟ" || d == "ㅢ" || d == "ㄳ" || d == "ㄵ" || d == "ㄶ" || d == "ㄺ" || d == "ㄻ" || d == "ㄼ" || d == "ㄽ" || d == "ㄾ" || d == "ㄾ" || d == "ㅀ" || d == "ㅄ").Count(d => d);

return str_list.Length + addCount;
}

 

초/중/종 성을 모두 1글자로 취급하며,

ㅟ ㅚ ㄻ ㄼ  등의 글자는 2글자로 취급하도록 계산하였다.

 

 

3. 분당 타수를 계산하는 로직을 적용하면 된다.

 

이제, 입력글자가 모두 일치 할경우, 분당 타수를 계산해서 알려주면 끝이다.

 

입력 TextBox 의 KeyDown 이벤트를 아래와 같이 정의한다.

 

private void txtInput_KeyDown(object sender, KeyEventArgs e)
{
if (this._isStart == true)
{
if (this._isKeyKirstPress == false)
{
this._isKeyKirstPress = true;
this._startDateTime = System.DateTime.Now;
}

if (this.txtKeyword.Text == this.txtInput.Text)
{
this._isStart = false;
this.checkDone();
}
}
}

 

이제 분당 타수를 표시해주면 끝이난다.

 

private void checkDone()
{
TimeSpan elapsed = DateTime.Now - this._startDateTime;

double typingMM = Math.Round(_typingCount * (60000.0 / elapsed.TotalMilliseconds));

this.txtResult.Text = $"{typingMM:N0} 타/분";
}

 

 

코드를 모두 적용하고, 프로그램을 실행하면, 아래와 같은 결과가 나오게 된다.

 

 

 

 

이것은 혼자하는 타자게임이지만, 채팅방에 이 로직을 적용하면, 여러명이서 경쟁하면서 게임을 즐길 수 있다.

 

아래는, 실제 네이버웍스메신저 단톡방에 메세지Bot 으로 구현한 타자 게임이다.

 

 

 

 

직접 만든 채팅방에 적용할 수 있다면, 좀더 편리한 UI 로 구현할 수 있을 것이다.

 

 

Posted by 헝개
개발팁2022. 4. 7. 11:53

PC에 이더넷 어댑터가 여러개 설치되어 있거나, Virtual Box 와 같은 Virtual Marchine 이 설치되어 있다면,

IP주소 / 맥어드레스를 구하는 다른 소스로는 엉뚱한 IP/Mac 주소를 반환하는 경우가 있다.

정확한 사용 주소를 가져오는 C# 코드는 아래와 같다.

 

 

IP주소

 

            string ipAddress = "";

            using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, 0))
            {
                socket.Connect("8.8.8.8", 65530);
                IPEndPoint endPoint = socket.LocalEndPoint as IPEndPoint;
                ipAddress = endPoint.Address.ToString();
            }

 

 

맥어드레스

 

            string macAddress = "";

            ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
            using (ManagementObjectCollection moc = mc.GetInstances())
            {
                foreach (ManagementObject mo in moc)
                {
                    if (mo["MacAddress"] != null)
                    {
                        if ((bool)mo["IPEnabled"] == true)
                        {
                            macAddress = mo["MacAddress"].ToString();
                            break;
                        }

                        mo.Dispose();
                    }
                }

            }
Posted by 헝개
개발팁2022. 3. 29. 14:04

mysql 또는 mariadb 에는 slow query 를 탐지해서 log 파일에 저장해주는 기능이 있다.

DB 튜닝을 위해, 속도가 느린 쿼리를 탐지해서 알려주는 기능은 참 유용한 기능이다.

 

현재, slow query 탐지 기능이 동작중인지 확인하려면, 쿼리창에 아래와 같이 실행해주면 알 수 있다.

 

show variables like 'slow_query_%';
show variables like 'long_query_%';

 

 

slow_query_log 가 OFF 상태로 동작중이지 않다.

 

탐지 기능을 켜려면,

 

mysql 이 설치된 폴더의 data 폴더아래 my.ini 설정 파일을 수정해야 한다.

 

MariaDB 10.5 버전이 설치되어 있다면, 아마도 아래와 같은 경로일 것이다.

 

C:\Program Files\MariaDB 10.5\data\my.ini

 

파일을 편집기로 열어서 아래와 같은 내용을 추가해준다.

 

slow_query_log = 1
slow_query_log_file = C:/slowlog/mysql-slow.log
long_query_time = 5

 

slow_query_log = 1

SLOW QUERY 탐지 기능을 사용한다는 의미이다.

 

slow_query_log_file = C:/slowlog/mysql-slow.log

슬로우 쿼리가 저장되는 경로와 파일명인데, 경로 규칙에 주의 해야 한다.

\ 문자가 아니라 / 문자로 폴더가 구분된다.

 

long_query_time = 5

초단위로 입력하며, 5초 이상의 쿼리를 탐지하겠다는 내용이다.

 

 

mysql 서비스를 재시작해야, 변경된 내용이 적용된다.

 

# mysql
net stop MySQL & net start MySQL
# mariadb
net stop mariadb & net start mariadb

 

윈도우의 서비스 항목에서 재시작하거나, command 창에서 재시작 해도 된다.

 

 

 

이제 변경된 설정을 확인해보면 된다.

 

show variables like 'slow_query_%';
show variables like 'long_query_%';

 

 

설정한 경로에 log 파일도 생성되었다.

 

 

슬로우쿼리 탐지가 잘 되는지 테스트 쿼리를 날려서 확인해 볼 수 있다.

 

SELECT SLEEP(5), 'slow query test.';

 

 

슬로우쿼리가 탐지될때마다, 로그 파일의 뒤에 계속 추가가 된다.

 

여기까지만 해도, 주기적으로 로그파일을 열어보고, 확인하면 되지만, 실시간으로 알림을 받을 수 있는 방법이 있다.

 

C# 의 FileSystemWatcher 를 이용하면, 파일의 내용이 변경되는걸 감지해서, slack 이나 naverworks 등의 메신저로 단체 채팅방에 알림메세지를 발송 할 수 있다.

 

 

FileSystemWatcher watcher = new FileSystemWatcher();

watcher.Filter = "mysql-slow.log";
watcher.Path = "C:\\slowlog\\";
watcher.IncludeSubdirectories = false;


watcher.NotifyFilter = NotifyFilters.DirectoryName |
   NotifyFilters.LastWrite |
   NotifyFilters.FileName |
   NotifyFilters.Size;

watcher.Changed += Watcher_Changed;
watcher.EnableRaisingEvents = true;

 

그리고, 파일에 추가되는 내용만 알림을 해야 하기 때문데, 파일 스트림의 position 을 전역변수로 기록해두자.

 

FileInfo fileinfo = new FileInfo(this.logFullPath);

if (this.streamPosition > fileinfo.Length)
{
       this.streamPosition = fileinfo.Length;
}            

 

Watcher_Changed 이벤트에서는 파일이 변경되었으니, append 된 내용만 알림을 보내면 된다.

 

using (FileStream stream = fileinfo.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
  stream.Position = this.streamPosition;

  using (StreamReader reader = new StreamReader(stream))
  {
    string mesageContent = reader.ReadToEnd()

    // MessageSend(messageContent);
  }
}

 

이렇게 해서 테스트를 해보면, 실시간 알림이 안오고, 한참 있다가 알림이 오게 되는걸 볼 수 있다.

 

이유는, 윈도우 시스템 (NTFS) 이 파일에 쓰기 버퍼를 사용하기 때문이다.

즉, 일정한 시간이 지나야 버퍼를 실제 물리적인 파일에 저장하기 때문이다.

 

윈도우 시스템이 실시간으로 파일을 변경하도록 하기 위해서는

로그파일을 Open / Close 를 주기적으로 해주면 된다.

 

 

try
{
  // NTFS 의 파일 캐싱으로 인해 로그파일이 변화를 watcher 가 즉시 탐지하지 못한다.
  // 파일 변화를 즉시 감지하기 위해 open 모드로 읽고 닫기를 한다.
  File.Open(this.logFullPath, FileMode.Open).Close();
}
catch (Exception)
{
}

 

try catch 를 쓰는 이유는, 로그 파일을 mysql 이 잡고 있기 때문에, Exception 이 발생하기 때문이다.

하지만, 이렇게 주기적으로 해당 파일을 건들어 주면, 윈도우 시스템이 버퍼를 파일로 저장하는 효과를 얻을 수 있어,

실시간 파일 감시가 가능해지기 때문이다.

 

이렇게 해서, 프로그램을 돌려놓고, slow query 를 발생해보면, 알림이 오는것을 확인할 수 있다.

 

 

네이버웍스 메신저르 알림을 보낸 샘플이다.

 

주의할점은 슬로우 쿼리는 트랜잭션 단위의 쿼리가 아니라, 쿼리문장 단위로 탐지를 한다는 점이다.

 

 

Posted by 헝개
개발팁2022. 3. 22. 18:46

웹API 및 Rest API 에서 swagger 는 강력한 테스트 도구이자, 문서화 도구이며,

API 를 사용하는 개발자와의 인터페이스 도구이다.

 

 

Swagger 설치 및 환경 설정

 

 

 

NuGet 패키지관리자에서 swashbuckle 을 검색해서 최신버전을 설치한다.

 

 

 

프로젝트 설정에서

웹 > 시작 작업 > 특정 페이지

 

swagger/ui/index

 

를 입력한다.

 

 

이제 F5 를 눌러 디버그를 해보면, 바로 swagger 페이지가 호출된다.

 

 

REST API 의 기본 샘플인 Values 컨트롤러에 대한 API 테스트 화면이다.

 

API 테스트 도구로서는 훌륭하지만, 문서화로써는 부족하다.

 

 

 

프로젝트 설정 > 빌드 > 출력

XML 문서 파일 체크를 한다.

 

 

 

 

 

 

App_Start > SwaggerConfig.cs 파일을 편집한다.

 

EnableSwagger 아래에 아래 라인을 추가한다.

 

c.IncludeXmlComments(string.Format(@"{0}\bin\WebApiTest.xml",
       System.AppDomain.CurrentDomain.BaseDirectory));

 

그리고, 테스트용 Api 컨트롤러 TodoController.cs 를 생성한다.

 

    public class TodoController : ApiController
    {
        // GET api/Todo
        public IEnumerable<string> Get()
        {
            return new string[] { "value1", "value2" };
        }

        // GET api/Todo/5
        public string Get(int id)
        {
            return "value";
        }

        // POST api/Todo
        /// <summary>
        /// Test 데이터 업로드 (dynamic by json)
        /// </summary>
        /// <remarks>
        /// {<br />
        ///     UserID: "round1",<br />
        ///     UserName: "홍길동",<br />
        ///     WorkTitle: "데이터 백업"<br />
        /// }<br />
        /// </remarks>
        /// <param name="data">
        /// json object {<br />
        /// UserID: 유저아이디<br />
        /// UserName: 유저이름<br />
        /// WorkTitle: 작업이름<br />
        /// }<br />
        /// </param>
        /// <returns></returns>
        public string Post([FromBody] dynamic data)
        {
            return "Data Posted : " + data.UserID + "=" + data.UserName + "<br />" + data.WorkTitle;
        }


        // PUT api/Todo/5
        /// <summary>
        /// PUT 데이터
        /// </summary>
        /// <remarks>
        /// {<br />
        ///     UserID: "round1",<br />
        ///     UserName: "홍길동",<br />
        ///     WorkTitle: "데이터 백업"<br />
        /// }<br />
        /// </remarks>
        /// <param name="data">
        /// json object {<br />
        /// UserID: 유저아이디<br />
        /// UserName: 유저이름<br />
        /// WorkTitle: 작업이름<br />
        /// }<br />
        /// </param>
        public string Put(int id, [FromBody] dynamic data)
        {
            return "put : " + data.WorkTitle;
        }

        // DELETE api/Todo/5
        public void Delete(int id)
        {
        }
    }

 

샘플데이터로 ValuesController 를 복사해서 수정했다.

Post / Put 메서드에 xml 주석이 들어가 있는것을 볼 수 있다.

 

프로젝트를 빌드 하면, 이 주석이 bin/WebApiTest.xml 파일로 저장이 되고,

Swagger 에서는 의 xml 을 읽어서 화면을 만들어 주게 된다.

 

 

 

TodoController 에서 메서드에 작성한 xml 주석이 swagger 에 잘 나온다.

 

xml 주석에 작성해둔 json 샘플 양식도 복사해서 붙여 넣기 하고,

Try it out! 을 누르면, 테스트도 간편하게 된다.

 

 

여기서 한가지 더 개선을 해본다면,

 

 

매번 json 샘플을 복사해서, parametar 에 붙여넣기를 해야 하는데, 이걸 자동화 해볼 것이다.

 

 

 


// Copyright 헝그리개발자(https://bemeal2.tistory.com)
// 소스는 자유롭게 사용가능합니다. Copyright 는 삭제하지 마세요.

$(document).ready(function () {

$(".toggleOperation").on('click', function (e) {

let el_content = $(e.target).closest("li.operation").find(".content");

setTimeout(function () {
if (el_content.css("display") == "block") {

let param_text = el_content.children(".markdown").text();

let el_textarea = el_content.find("textarea.body-textarea");

el_textarea.val(param_text);
let ev = new Event('input', { bubbles: true });
ev.simulated = true;

el_textarea[0].dispatchEvent(ev);

}
}, 500);

});


});

 

js 폴더를 만들고 그 아래  swager-control.js 파일을 생성한다.

 

.js 파일의 내용은 위와 같이 넣어준다.

 

 

그리고, 속성창에서 빌드작업을 [포함리소스] 로 바꿔준다.

 

SwaggerConfig.cs 파일을 열어서, EnableSwaggerUI 아래에 아래와 같이 추가해준다.

 

                .EnableSwaggerUi(c =>
                    {
                        c.InjectJavaScript(thisAssembly, "WebApiTest.js.swagger-control.js");

 

여기서 주의 할 점은 .js 파일의 경로를 지정하는 방식이다.

 

프로젝트명.폴더명.파일명  이러한 규칙으로 작성해야 한다.

 

상식적으로는 js 폴더 아래에  swagger-control.js  파일이 있으니까

"/js/swagger-control.js"  라고 해야 할것 같지만. 그렇지 않다.

 

WebApiTest 라는 프로젝트명.js라는폴더명.swagger-control.js라는파일명

 

이렇게 해서, 

"WebApiTest.js.swagger-control.js"

 

이러한 양식으로 입력해줘야 한다.

 

 

이제 swagger 페이지를 열어보면, 파라미터가 자동으로 입력된것을 볼 수 있다.

API 테스트를 위해서 Try it out! 만 눌러주면 된다!!!

 

Posted by 헝개
개발팁2022. 3. 21. 18:55

Jenkins 는 Rest API 를 통해, Project / Job 을 조회하고,

빌드하고, 결과를 확인할 수 있다.

 

 

Rest API 를 이용하면, 빌드완료후에, 빌드 결과를 메신저로 단체방에 공유 할 수 있다.

 

 

Rest API 사용하기

 

 

 

Jenkins 에 로그인하고, 오른쪽 상단에 로그인한 ID 를 클릭한다.

 

 

 

설정 메뉴를 클릭한다.

 

 

ADD NEW TOKEN 을 클릭한다.

 

 

Default name 을 입력하고, GENERATE 를 클릭하면, Token String 이 생성된다.

 

 

이 토큰문자가 REST API 를 호출할때, 인증하는 수단이 된다.

 

형식은 위에서 입력한 이름:토큰스트링 형식이다.

 

ex)

admin:12eb2d6e1d73cfa260d9e42e4d3f080b19

 

이 값은 Basic API 호출시에는 Base64 String 으로 변환해서 호출해야 한다.

간단히 fiddler 의 text wizard 에서 변환해서 쓰면 된다.

 

 

 

base64 string ex)

YWRtaW46MTJlYjJkNmUxZDczY2ZhMjYwZDllNDJlNGQzZjA4MGIxOQ==

 

 

 

Jenkins Rest API 호출

 

Job 조회 / 빌드 조회 URL 뒤에  /api/json   또는 /api/xml 만 붙여주면된다.

(소문자로 입력해야 한다.)

 

웹브라우저에서 로그인 한 상태에서, JOB 조회 화면뒤에 api/json 을 붙여보면 된다.

 

 

 

 

 

 

웹브라우저에서는 jenkins 사이트에 로그인이 된 상태에서 호출했기 때문에, 조회가 정상적으로 이뤄진다.

curl 명령어로 command prompt 에서 실행해보자.

 

 

curl -X GET "http://url:port/job/BUILD/job/BUILD_CLIENT_FOR_Develop/api/json" -H "Content-Type: application/json"

 

오류가 날 것이다. 아래와같이 Basic Authorization 을 추가하여 호출해보자.

 

curl -X GET "http://url:port/job/BUILD/job/BUILD_CLIENT_FOR_Develop/api/json" -H "Content-Type: application/json" -H "Authorization: Basic YWRtaW46MTJlYjJkNmUxZDczY2ZhMjYwZDllNDJlNGQzZjA4MGIxOQ=="

 

 

결과가 잘 나올 것이다.

 

 

 

Jenkins 결과 확인 API

 

빌드 결과 확인 API
{jobUrl}{buildNumber}/api/json

빌드 결과 Console 확인 API
{jobUrl}{buildNumber}/consoleText

 

 

Jenkins 빌드 후 조치

 

 

 

Jenkins 의 job 설정에서 빌드 후 조치

 

Execute Windows batch command 를 통해서, 빌드완료후에, 빌드결과 알림 Console Application 을 호출할것이다.

 

jenkins_build_noti.bat

 

파일과, 그 안에서 호출하는 Application 을 만들어야 한다.

 

Application 은 Visual Studio 에서 Console Application 으로 만들면 된다.

 

 

 

jenkins_build_noti.bat

 

D:\경로\Util.NaverWorks.BuildNoti.exe "jenkins" "%JOB_URL%" "%BUILD_NUMBER%"

 

jenkins 빌드가 완료되면, 전역변수

 

%JOB_URL% 에 현재 빌드된 job 의 url 이 자동으로 입력되고,

%BUILD_NUMBER% 에는 빌드된 빌드번호가 자동으로 입력된다.

 

 

 

Console Application

 

main 함수

            if (args.Length >= 1)
            {
                using (NaverWorksNoti noti = new NaverWorksNoti())
                {
                    switch (args[0])
                    {
                        case "jenkins":
                            noti.SendJenkins(args[1], args[2]);
                            break;
                        default:
                            WriteUsage();
                            break;
                    }

                    return 0;   // always return success
                }

 

여기서 주의 할 점은 return 0 이다. 0 이 아닌 값을 리턴하면,  jenkins 는 빌드가 실패한걸로 처리하게 된다.

 

 

SendJenkins 함수

string url = $"{jobUrl}{buildNumber}/api/json";

 

using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

client.DefaultRequestHeaders.Add("Authorization", "Basic YWRtaW46MTJlYjJkNmUxZDczY2ZhMjYwZDllNDJlNGQzZjA4MGIxOQ==");

HttpResponseMessage response = client.GetAsync(url).Result;
string result = response.Content.ReadAsStringAsync().Result;

dynamic objResult = JsonConvert.DeserializeObject(result);

........

}

 

이제 objResult 라는 json 객체에서 빌드 성공/실패 여부를 판단하고, 알림 메세지를 만들어 내면 된다.

 

bool buildSuccess = objResult.result.ToString() == "SUCCESS";

 

result 값이 SUCCESS 라면 빌드성공 아니면 실패로 처리하면 된다.

 

actions 의 parameters 를 통해 job 빌드시 사용한 파라미터를 가져올 수 도 있다.

 

                    for (int i = 0; i < objResult.actions.Count; i++)
                    {
                        if (objResult.actions[i].parameters != null)
                        {
                            for (int k = 0; k < objResult.actions[i].parameters.Count; k++)
                            {
                                if (objResult.actions[i].parameters[k].value != null && objResult.actions[i].parameters[k].value.ToString() != "")
                                {
                                        
                                    sbParameter.Append($"{objResult.actions[i].parameters[k].name.ToString()} : {objResult.actions[i].parameters[k].value.ToString()}");

sbParameter.AppendLine();
                                }
                            }
                        }
                    }

 

svn 연동해서, 빌드하는 경우, changeSet 을 통해서, svn 커밋내용들을 가져올 수 있다.

 

if (objResult.changeSet.items != null)
{
for (int i = 0; i < objResult.changeSet.items.Count; i++)
{
sbMessage.AppendLine($"{objResult.changeSet.items[i].user.ToString()} : {(objResult.changeSet.items[i].date == null ? "" : Convert.ToDateTime(objResult.changeSet.items[i].date).ToLocalTime().ToString())}");
sbMessage.Append(objResult.changeSet.items[i].msg.ToString());

sbMessage.AppendLine();
}
}

 

빌드가 실패한경우에는 consoleText 를 보여줘서, 오류를 확인하도록 할 수도 있다.

 

string consoleUrl = $"{jobUrl}{buildNumber}/consoleText";

 

response = client.GetAsync(consoleUrl).Result;
byte[] resultBytes = response.Content.ReadAsByteArrayAsync().Result;

// EUC-KR 인코딩
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
string resultText = Encoding.GetEncoding(51949).GetString(resultBytes);

sbMessage.Append(resultText);

 

 

이렇게 단체방에 전송할 메세지를 만들어서 단체방 메세지를 보낼 수 있다.

 

 

 

알림 메세지 예제

 

아래 예제는 네이버웍스에 Bot 을 생성해서, 단체방에 메세지를 보낸 화면이고, api 가 제공된다면 다른 메신저로 보낼 수도 있다.

 

Posted by 헝개
정보공유2021. 9. 15. 15:42

파이썬이나 어플리케이션을 만들어서 슬랙봇을 이용해서 슬랙 채널에 메세지를 자동화 할 수 있다.

 

 

 

1. Webhook URL 을 이용하는 방법

 

 

 

 

 

일단, 슬랙에 webhook 을 추가해야 한다.

 

슬랙에서 [더보기] -> [앱] 을 눌러서, incoming webhooks 를 추가한다.

 

 

 

 

 

 

추가 버튼을 누르면 아래와 같은 webkhook 설정 화면이 나온다.

 

 

 

 

채널에 포스트

슬랙봇 메세지를 수신할 채널(채팅방)을 선택한다.

이미 만들어진 채널을 선택 할 수 있고, 1:1 대화방이나, 자기 자신을 선택할 수 있다.

또는, 새 채널 생성 으로 새로 만들어서 진행 할 수 도 있다.

 

웹후크 URL

일종의 웹토큰으로, 슬랙봇에서 메세지를 보낼때는 별도의 로그인없이. 웹후크 URL 만 알면, 메세지를 보낼 수 있다.

해당 주소를 복사해서 저장해 놓자.

 

이름 / 이미지는 슬랙봇의 이름과 이미지이므로 필요하면 설정하면 된다.

 

 

 

 

설정저장 버튼만 누르면, 준비는 끝난다.

 

 

위에서 저장한 웹후크 URL 로 바로 메세지를 날릴 수 있다.

 

cmd 창에서 curl 을 통해 아래와 같이 하면, 바로 메세지를 바로 전송해 볼 수 있다.

 

 

첫번째 예제 : 메세지 보내기

 

curl -X POST --data-urlencode "payload={\"text\":\"hello\r\nit's my test\"}" https://hooks.slack.com/services/T028FNHBY0Y/B02EFULB2AX/QdIhJkolfuh0Sz1********

 

성공한 경우 리턴값은 문자열로 ok 라고 나온다.

 

 

두번째 예제 : 메세지 + 이름 + 아이콘

 

첫번째로 메세지만 넣어서 보내면, 설정한 이름/아이콘으로 봇이 표시되지만,

봇의 이름/아이콘도 바꿔서 보낼 수 있다.

 

curl -X POST --data-urlencode "payload={\"username\": \"webhookbot\", \"icon_emoji\": \":ghost:\", \"text\":\"hello\r\nit's my test\"}" https://hooks.slack.com/services/T028FNHBY0Y/B02EFULB2AX/QdIhJkolfuh0********

 

 

 

 

위의 예제는 curl 을 이용한 테스트였고, postman 어플리케이션을 통해서도 테스트 해볼 수 있다.

 

 

 

 

웹후크URL 을 넣어주고 POST 방식으로 설정한다.

 

Body 에는 json 형식으로 넣어준다.

 

Send 를 누르면, 결과가 나온다. => ok

 

 

 

 

 

 

2. OAuth token 을 이용하는 방법

 

웹브라우저의 주소창에 아래 주소를 치고 들어간다.

 

https://api.slack.com/

 

Create an app 을 누르고, 나오는 화면에서 From scratch 를 선택한다.

 

 

 

 

 

App Name 에 봇의 이름을 적어준다.

아래에는 메세지를 전송할 Workspace 를 선택한다.

 

 

 

 

다음 화면에서, OAuth & Permissions 를 선택하고, 스크를을 아래로 내리면,

 

 

 

 

Scopes 선택화면이 나온다.

Add an OAuth Scope 를 눌럿, chat:write 를 선택한다.

 

 

 

 

다시 스크롤을 위로 올려서, Install to Workspace 를 눌러준다.

 

 

 

 

생성된 OAuth Token 을 복사해서 저장해준다.

 

 

여기까지 작업을 하면, 이제 해당 Workspace 에 메세지를 보낼 수 있는 봇이 생성이 된것이다.

 

이제, 봇이 메세지를 보내게 되는 채널(채팅방) 을 설정해야 한다.

 

 

 

슬랙으로 가서, 메세지를 수신할 채널정보를 보면 하단에, 채널 ID 가 있다.

 

 

OAuth Token 과 함께 채널 ID 도 함께 저장해 두자.

메세지를 보낼 때 이 2개의 값만 있으면, 메세지를 채널로 보낼 수 있게 된다.

 

통합을 눌러서, 앱 추가 를 눌러서, 아까 생성한 봇을 선택한다.

 

 

 

 

이제, cmd 창에서 curl 명령어로 TEST 메세지를 보낼 수 있다.

 

1. 인증테스트로 OAuth Token 이 올바른지 확인한다.

 

Authorization: Bearer 뒤에 아까 받은 token 을 입력한다.

curl -H "Authorization: Bearer xoxb-2505273309281-***********************************" https://slack.com/api/auth.test

 

결과는 json 으로 나오며, "ok": true 로 나오면 성공한 것이다.

 

 

2. 메세지 전송 테스트

 

Authorization: Bearer 뒤에 아까 받은 token 을 입력한다.

channel= 뒤에 채널ID 를 넣어준다.

curl -d "text=it is just test message" -d "channel=C02********" -H "Authorization: Bearer xoxb-2505273309281-*******************************" -X POST https://slack.com/api/chat.postMessage

 

결과는 json 으로 나오며, "ok": true 로 나오면 성공한 것이다.

 

 

슬랙에서는 위와같이 메세지가 오게 된다.

 

 

Posted by 헝개
리뷰2021. 4. 1. 15:30

집에서 책상용 의자로 사용했던 의자는

듀오백, 한샘, 시디즈 를 사용했는데,

 

메리페어 와우 라는 의자가 편하다고 하여 이번에 구입하게 됐다.

 

와우 체어는 와우1과 와우2 2종류가 있는데,

와우1은 등받이가 위로 갈수록 좁아지는것이고, 와우2는 위로 갈수록 넓어지는 것이다.

 

어깨가 좁은 사람은 와우1, 어깨가 넓은 사람은 와우2가 어울린다고 하겠다.

 

 

와우1 체어

 

와우2 체어

 

 

재질에 따라 종류가 5가지로 구분이 되는데,

TPE, 메쉬, 패브릭, 인조가죽, 천연가죽으로  천연가죽 제품이 10만원 더 비싸다.

 

메쉬나 패브릭, 가죽 의자는 많이 써봤지만, TPE 의자는 처음 들어본다.

TPE 란?

 

 

 

고무보다는 단단하고 플라스틱보다는 말랑거리는 재질이라고 한다.

 

 

제품은 본체, 다리 바퀴 로 나눠져서 발송이 되는데,

조립은 다리에 바퀴를 끼우고, 본체를 끼우기만 하면 끝난다.

 

 

조립설명서에서, 1, 2 번으로 조립은 끝나고, 3,4,5 는 사용방법이 되겠다.

 

 

 

 

제품에는 방청윤활제인 WD-40 (미니) 도 포함되어 있다.

센스있게 품질보증서의 구매일자는 택배 배송받는 날짜로 되어 있다.

 

 

구입한 제품은 블랙프레임 그레이TPE 제품이다.

제품 구성에 TPE 는, 그레이와 망고 밖에 없었는데, 새로 나온 색상인가보다.

좌판, 등판등은 그레이TPE와 동일한데, 프레임이 블랙색상이다.

 

 

 

 

처음 앉았을때는 차갑고 딱딱한 느낌이다.

물론 TPE 재질이라 완전 딱딱한 형태는 아니고 하드하면서 약간 플렉서블한 느낌이다.

 

기존에 등판은 메쉬, 좌판은 패브릭 제품을 쓰다가 바꾼거라 적응기간이 필요하겠다.

일단 등판이 메쉬를 사용한 의자는 의자 뒷면에 섬유먼지가 쌓이게 되는데,

TPE 재질이라 옷 등판이 닳지는 않으리라 기대해본다.

 

몇시간 정도 앉았더니 적응이 되어 편한 느낌이 든다.

의자의 전체 프레임은 잘 만들어진 하나의 시스템(SYSTEM) 처럼 유기적으로 동작하는 느낌이 든다.

 

비싼 가격을 지불했지만, 가격이 리즈너블하게 느껴진다.

 

 

 

메리페어의 의자에 대한 철학이 그대로 녹아있는 제품이 아닌가 한다.

 

 

의자에서 조절이 가능한 부분은 전부 조절이 된다고 보면 된다.

의자 등받이 각도 조절 및 고정이 가능하고,

다른 의자들은 등받이만 움직인다거나, 등받이랑 좌판이랑 함께 움직이는데 이때 각도가 유지되는 형태로 움직이는데 반해, 와우 체어는 등받이가 움직이면서 좌판이 시스템적으로 같이 움직이는 형태를 취하고 있다.

 

리클라인 글라이드 모션 이라고 하는듯 하다.

 

 

자세한 사용법은 제조사의 동영상 사용법을 보면 되겠다.

 

youtu.be/EIRxh72cmKc

 

Posted by 헝개