⚙️ 개발
고3, 치열했던 그때 그 시절의 나 : 1편
갑작스러운 코로나19 등장..
심심해서 Github 정리하다가 약 3년 지난 고등학교 때 개발했던 코드를 보게 되었음.
지금 보면 그때 당시 코드가 매우 난잡하고 비효율적인 부분이 있으나 내가 무슨 의도로 그렇게 했는지는 알 수 있어서 오랜만에 추억..🥲
코로나19가 한창일 때 우리는 등교하기 전에 건강상태 자가진단 앱을 이용해서 당일 건강상태를 설문하고 “등교가 가능합니다.” 문구가 나와야지만 학교로 등교할 수 있었지..?

처음 앱을 구동하면 학교, 성명, 생년월일과 비밀번호를 입력해야 하고 빠짐없이 입력하고 확인 버튼을 누르면 개인정보가 앱에 등록되며 설문을 할 수 있는 페이지로 이동됐었음.

약 5개의 문항이 있는데 1개의 문항이라도 코로나19에 의심 가는 항목을 선택하면 등교 불가 멘트가 떴고, 의심 가는 항목을 선택하지 않고 제출하면 등교가 가능했음.
앞으로 매일 아침 등교 전 꼭 하고 오라고 할 때는 별생각이 없었는데 일주일이 지나고 한 달이 지나니 슬슬 귀찮아지고 까먹고 안 하는 날도 종종 있어서 절대적으로 귀찮은 행위를 하는 것을 싫어하는 나는 이 작업을 자동화 시키고 싶은 마음이 200% !!!
자가진단 자동화는
hcskr 모듈을 이용했으나, 현재 교육부의 앱 폐기 요청으로 라이브러리가 삭제되었습니다.
처음 개발했을 때 모습.
나는 중학교 때부터 Python과 HTML로 웹 개발에 관심이 있었고 따로 공부도 했었음. 옛날에 해왔던 것도 있고 관련 라이브러리도 제공되어 있어서 쉽게 접하고 개발할 수 있었음.
원래 목적이었던 자가진단 자동화가 완료되었고 실제로 실행된 모습. 자가진단이 진행되었다는 메시지를 카톡으로 받을까 디스코드로 받을까 고민했었는데 나랑 내 친구들 대부분이 디스코드를 사용하고 있어서 같이 있는 디스코드 채널로 진행 메시지를 전송함.
코드는 다음과 같다.
msg = "**< :syringe: 자가진단 알림 >**\n\n" for key in storage.keys(): name = storage[key]["name"] birth = storage[key]["birth"] level = storage[key]["level"] region = storage[key]["region"] school = storage[key]["school"] customloginname = storage[key]["customloginname"] password = storage[key]["password"] datas = await hcskr.asyncSelfCheck(name, birth, region, school, level, password, customloginname) if datas["code"] != "PASSWORD": msg += f"자가진단을 완료했다. (`{name}`)\n" else: msg += f"자가진단을 실패했다. (`{name}`)\n" async with aiohttp.ClientSession() as cs: webhook = discord.Webhook.from_url(url="", adapter=discord.AsyncWebhookAdapter(cs)) await webhook.send(msg)
msg 변수에 메시지를 담고 hcskr 모듈을 이용해서 미리 설정해둔 유저 데이터로 자가진단을 실시하고 결괏값을 디스코드 웹훅을 통해 채널로 전송시킴.친구들이 모두 편하고 좋다고 했었고, 매일 아침마다 해왔던 자가진단을 이제는 하지 않아도 된다는 심리적 안정감과 늘어난 내 시간에 대해서 뿌듯함을 느끼고 있었는데, 승현(고등학교 친구임)이가 학교 급식을 아침마다 네이버 들어가서 찾아보는 게 귀찮다고 하길래 방법을 찾다가 자가진단 알림이랑 같이 급식 알림을 보내게 만들기로 했음.
급식 데이터 수집은
nipy 모듈을 이용했음!!
승현이의 추가 요구사항을 반영한 뒤 모습.
생각한 그대로 작동이 되어서 만족스러운 결과였음.
nipy 모듈이 너무 잘 되어 있어서 쉽게 만들 수 있었던 것 같고, 이로써 우리의 아침 시간은 더욱 여유로워짐 🤭코드는 다음과 같다.
msgs = "**< :fork_and_knife: 오늘의 급식 >**\n\n" now = str(datetime.datetime.now()) datas = nipy.Smeal("서울", "B100000587", "4") send = datas.day(now[:4], now[5:7], now[8:10], "2").replace("<br/>", "\n").replace("*", " ") if send == "NO DATABASE": msgs += "오늘은 급식이 없습니다." elif send == "급식이 예정되지 않았거나 정보가 존재하지 않습니다.": msgs += "오늘은 급식이 없습니다." else: msgs += send async with aiohttp.ClientSession() as cs: webhook = discord.Webhook.from_url(url="", adapter=discord.AsyncWebhookAdapter(cs)) await webhook.send(msgs)
이 코드도 자가진단 자동화 코드와 비슷하게
msgs 변수에 메시지를 담고 nipy 모듈에서 요구하는 값을 넣어주면 그날의 중식 메뉴 데이터 값을 받을 수 있었음.자가진단 자동화에 당일 중식 메뉴까지 알려주는 알림봇(?)을 만들어줬는데 기능에 만족하지 못한 승현이가 또 요구사항을 제시함..
이번에 제시한 건 “당일의 시간표” ..
시간표는 왠지 모르겠지만 자꾸 까먹기도 했고, 통학 길에 시간표를 미리 보면서 수업 준비를 할 수 있다는 장점이 존재해서 바로 만들기로 함.

최종적으로 개발이 완료된 모습.
nipy 모듈에서 당일의 시간표 데이터를 가져올 수 있었지만 직관적으로 확인하고 싶어서 이미지로 전송하기로 했음.코드는 다음과 같다.
week = datetime.datetime.today().weekday() classroom01 = ["101.jpg", "102.jpg", "103.jpg", "104.jpg", "105.jpg", "null", "null"] classroom02 = ["null", "null", "null", "null", "null", "null", "null"] async with aiohttp.ClientSession() as cs: webhook = discord.Webhook.from_url(url="", adapter=discord.AsyncWebhookAdapter(cs)) try: await webhook.send("**< :calendar_spiral: 오늘의 1반 시간표 >**", file=discord.File(classroom01[week])) except: await webhook.send("**< :calendar_spiral: 오늘의 1반 시간표 >**\n\n시간표가 없습니다.") try: await webhook.send("**< :calendar_spiral: 오늘의 2반 시간표 >**", file=discord.File(classroom02[week])) except: await webhook.send("**< :calendar_spiral: 오늘의 2반 시간표 >**\n\n시간표가 없습니다.")
week 변수에 datetime의 weekday()를 넣었음. 이 코드는 월요일부터 일요일까지를 1~7 숫자로 반환해 주는 코드고 classroom 리스트에 시간표 이미지 파일을 넣음.마지막으로 결괏값은
classroom 리스트를 week로 인덱스를 찾아서 그날의 시간표 이미지를 전송하는 방식으로 값을 얻어냄.최종적으로 완성된 코드는 아래에 올려두었고, 파일은 자체적으로 구비해둔 서버 컴퓨터에서 스케줄링 프로그램에 코드 파일을 등록하고 매일 07시에 실행되도록 설정했음.
# -*- coding: utf-8 -*- import discord # 디스코드 웹훅을 위한 모듈 import asyncio # 비동기 프로그래밍을 위한 모듈 import aiohttp # 통신을 위한 모듈 import hcskr # 자가진단을 위한 모듈 import nipy # 급식 데이터를 받기 위한 모듈 import datetime # 시간 값을 받기 위한 모듈 import sys # 시스템 모듈 async def main(): storage = { # 자가진단 데이터 입력 "Discord User Id":{ "name":"김도원", # 이름 입력 "birth":"030204", # 생년월일 입력 "level":"고등학교", # 학교 등급 입력 "region":"서울", # 학교 지역 입력 "school":"미래산업과학고등학교", # 학교 이름 입력 "password":"2580" # 자가진단 앱 비밀번호 입력 } } msg = "**< :syringe: 자가진단 알림 >**\n\n" for key in storage.keys(): name = storage[key]["name"] # 위에 입력한 자가진단 데이터 가져오기 birth = storage[key]["birth"] level = storage[key]["level"] region = storage[key]["region"] school = storage[key]["school"] customloginname = storage[key]["customloginname"] password = storage[key]["password"] datas = await hcskr.asyncSelfCheck(name, birth, region, school, level, password, customloginname) # 입력한 변수를 넣어서 자가진단 실시 if datas["code"] != "PASSWORD": msg += f"자가진단을 완료했다. (`{name}`)\n" else: msg += f"자가진단을 실패했다. (`{name}`)\n" async with aiohttp.ClientSession() as cs: webhook = discord.Webhook.from_url(url="웹훅 링크", adapter=discord.AsyncWebhookAdapter(cs)) await webhook.send(msg) # 디스코드 웹훅 전송 코드 msgs = "**< :fork_and_knife: 오늘의 급식 >**\n\n" now = str(datetime.datetime.now()) datas = nipy.Smeal("서울", "B100000587", "4") send = datas.day(now[:4], now[5:7], now[8:10], "2").replace("<br/>", "\n").replace("*", " ") if send == "NO DATABASE": msgs += "오늘은 급식이 없습니다." elif send == "급식이 예정되지 않았거나 정보가 존재하지 않습니다.": msgs += "오늘은 급식이 없습니다." else: msgs += send async with aiohttp.ClientSession() as cs: webhook = discord.Webhook.from_url(url="웹훅 링크", adapter=discord.AsyncWebhookAdapter(cs)) await webhook.send(msgs) # 디스코드 웹훅 전송 코드 week = datetime.datetime.today().weekday() classroom01 = ["101.jpg", "102.jpg", "103.jpg", "104.jpg", "105.jpg", "null", "null"] classroom02 = ["null", "null", "null", "null", "null", "null", "null"] async with aiohttp.ClientSession() as cs: webhook = discord.Webhook.from_url(url="웹훅 링크", adapter=discord.AsyncWebhookAdapter(cs)) try: await webhook.send("**< :calendar_spiral: 오늘의 1반 시간표 >**", file=discord.File(classroom01[week])) except: await webhook.send("**< :calendar_spiral: 오늘의 1반 시간표 >**\n\n시간표가 없습니다.") try: await webhook.send("**< :calendar_spiral: 오늘의 2반 시간표 >**", file=discord.File(classroom02[week])) except: await webhook.send("**< :calendar_spiral: 오늘의 2반 시간표 >**\n\n시간표가 없습니다.") loop = asyncio.get_event_loop() loop.run_until_complete(main()) sys.exit()
다음은 구글 클래스룸? 자동 출첵 만든 거 있는데.. 그거 포스팅함.
