나만의 'solved.ac' 티어 정리기

개요

여러가지 사건 사고와 맡았던 프로젝트를 하나 처리하고 나니 드디어 딴 짓(?)을 할 시간이 났다. 딴 짓이라고 해봐야, 알고리즘 문제 풀이를 다시 시작하는 것이지만…

나의 문제점은 항상 일을 끝내 놓고, 내 컴퓨터의 파일들은 잘 정리해도 프로젝트 자체는 잘 정리하지 않는다는 것이 문제였다. 그래서 작년부터는 그동안 풀었던 알고리즘 문제들 중 복구 가능한(?) 문제들을 복구해서 github에 정리하기 시작했다.

대표적으로 티어가 바뀐 문제 예시

문제는 정리를 하면서 발생했다. solved.ac의 티어 기준으로 문제를 풀고 정리했는데, 이게 바뀔 수 있다는 사실을 간과했다. (티어는 사람 손으로 매기는 걸 알면서… 왜 몰랐니…? 과거의 나…?)

알아채게 된 계기도 정말 웃기다… 지인과 풀이한 것을 되돌려보다가, 서로 기억하는 티어가 달라서 열어보니 바뀐 경우였다. 몰랐으면 몰랐지… 알아버린 이상 꼭 고쳐야 속이 편한데, 생각해보니 자동화해두지 않으면 나중에도 이런 문제가 발생할 것이 분명했다.

나만의 ‘solved.ac‘ 티어 정리기

그래서 만들었다 나만의 ‘solved.ac‘ 티어 정리기! 범용성은 매우 떨어진다. 애시당초… 내가 정리한 형식에 맞추어 다시 정리해주는 걸 짜는 것이라 그렇다. 그래도 나랑 비슷하게 정리했던 사람이라면 조금만 고치면 쓸 수 있을 수도?

구조

아무튼… 구조는 간단하다.

  1. 지정된 경로에 있는 폴더를 검사해서 문제 리스트를 만든다.
  2. 문제 리스트를 바탕으로 내가 적은 문제 티어와 문제 번호를 정규표현식을 이용해 가져온다.
  3. solved.ac의 api 서버에 request를 날려, 해당 문제의 현재 정보를 가져온다
  4. 티어 변화가 있는 문제들의 리스트를 만든다.
  5. 문제 README.md를 수정하고, 해당 티어 폴더로 이동시켜준다.
  6. github에 커밋은 수동으로 날린다! (혹시 모르니까 체크하고 보내기 위함!)

간단한 구조지만… 끝나고 나서 정리해서 그렇지 중간에 몇번 바꿨다. (원래는 API 서버에 요청하는 것도 아니고, 검색 기능을 이용해서 가져오고 있었다.) 그래서 그런지… “무지성 코딩”의 끝판왕이 되었다. 언젠가 성능 개선을 꼭… 해야겠다는 다짐을…

문제점

무지성 코딩의 발생 원인을 따져보니… 티어를 총 3가지 형식으로 나타내면서 문제가 발생했다.

1
2
3
dir : bronze
README.md : 브론즈 5
solved.ac : 1

브론즈 5 문제가 있다면, 위와 같이 세가지 형식으로 나타내야한다. 이걸 염두해두고, 처음부터 형식을 통일시키던가 변환해주는 함수를 하나만 만들어서 통일된 형태로 관리해야했는데 그러지 못해서 비교 한번 할때마다 변환해줘야 해서 복잡해졌다.

사용법

https://github.com/y2sman/algorithm_tier_modifier

아무튼... 일단 잘 돌아간다.

당장은 딴짓할 시간이 이제 없어서… 머리좀 정리되면 변수 정리해서 제대로 정리된 “나만의 ‘solved.ac‘티어 정리기 v0.2”로 돌아오겠다. (일단 작동은 하니까…???) 양심의 가책이 많이 남아서… 최대한 빨리 고쳐야겠다고 다짐하고, 그때까지… 아디오스…

ReactNative로 간단한 앱 만들기 파트1

개요

예전부터 생각하던 간단한 서비스가 있었다. 바로 24시간 카페 찾는 서비스! 사실 비슷한 서비스는 존재한다. 구글지도에 나오는 영업시간 정보라던가, 어떤 분이 개발하신 “밤새미”라던가. 하지만 밤새미는 최근 갱신이 잘 안된 것 같고, 구글지도는 솔직히 가끔 틀려서 믿기가 어려웠다. 그래서 ReactNative를 공부하는 김에 직접 개발에 도전하기로 했다!

무엇이 필요할까?

대략적인 컨셉

서비스 이름이나 컨셉 뭐 이런것도 중요하고, 세부 기능도 중요하지만… 가장 중요한 것은 24시 영업하는 카페에 대한 정보가 필요했다. 이번 글에서는 이 정보들을 가져올 크롤러에 대해 간단히만 이야기하고 넘어가겠다. (사실… 자꾸 글을 안쓰니 미뤄서… 이렇게 써야 완성할것 같아서 쓰는중이다. 나중에 더 수정될 예정…!)

24시 카페정보 수집하기

먼저, 서울에 영업중인 프랜차이즈 카페들 중 24시간 영업을 하고 있는 프랜차이즈 카페들을 뒤져서 리스트로 만들었다.

  • 탐앤탐스
  • 할리스커피
  • 엔제리너스
  • 카페베네
  • 커핀그루나루
  • 커피스미스
  • 요거프레소 (사이트 리뉴얼로 인한 수정 필요)

당장 찾아본 데이터는 위와 같았다. 대부분의 브랜드들이 거의 24시 영업을 하고 있지는 않았다. Covid-19의 영향인지, 그 이후로 영업시간을 단축한 경우도 있었다. 어떤 브랜드의 경우 24시간 영업을 하지만, 조건부로 하는 경우도 있었다.

크롤러 개발 목표 설정

장기적으로 공식 정보를 바탕으로 서비스에서 사용할 데이터를 갱신할 예정이므로, 사이트 구조가 바뀌어도 작동하도록 개발하는 것이 옳으나… 시간적 문제도 있으니 일단 그냥 대충 초기 데이터만 수집하는 것을 목표로 크롤러를 만드는 것을 목표로 했다. (사실 무엇보다 제대로 짜는건 모르겠다 _ 나중에 scrapy를 좀 공부해야겠다.)

Seoul_24h_cafe

seoul_24h_cafe 코드는 여기서 확인할 수 있다. (현재 수정중이라 private 상태. 완성 후 공개 예정) 구조는 간단하다. 각 카페별로 파싱모듈을 나누고, 가져온 데이터를 취합한다. 취합한 데이터를 DB로 보내주면 되는 구조이다. OOP를 제대로 배워본 적이 없어, 구조가 조금 어색할 수는 있다.

Robots.txt

아무리 크롤러를 잘 만들지는 못해도… 지킬건 지켜야한다. 특정 사이트를 대상으로 크롤러를 짤 예정이라 robots.txt를 확인하는 모듈까지는 필요가 없겠지만, 혹시라도 존재하는지 수동으로 확인했다. (나중에 필요시 추가 예정) 생각보다 robots.txt가 없는 경우가 많았다.

  • 카페베네
1
2
User-agent: * 
Allow: /
  • 커피스미스
1
2
3
4
5
6
7
8
9
# XML Sitemap & Google News Feeds version 4.5.1 - http://status301.net/wordpress-plugins/xml-sitemap-feed/
Sitemap: http://coffeesmith.co.kr/sitemap.xml

User-agent: *
Disallow: /wp/wp-admin/

User-agent: Yeti
Allow: /
Disallow: /wp/wp-admin/

2021년 3월 16일 기준으로 2개 회사에서만 robots.txt가 있었고, 딱히 내가 하려는 크롤링 범위에 제한되는 경우는 없었다. 그럼 이제 딱히 크롤러를 돌리지 못할 이유가 없으니 데이터를 수집하러 가자!

데이터 수집

데이터 수집은 내가 잘 만들었거나, 엄청난 아이디어가 있는 것도 아니었기 때문에 특별히 설명할 내용은 없다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class TomTom:
def __init__(self):
print("---Starting TomTom---")
self.uid = []
self.storelist = []

def GetUid(self):
post = urllib.parse.urlencode({'keyword' : '서울', 'info4_1': '24시간'}).encode('UTF-8')
url = urllib.request.Request("https://www.tomntoms.com/store/domestic_store_search.html", post)
url.add_header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko")
data = urllib.request.urlopen(url)
data = BeautifulSoup(data, features="html.parser", from_encoding='utf-8')
result = str(data.find_all('script')[17])
self.uid = re.findall('\'([0-9]{0,3})\'', result)

def GetStoreInfo(self):
for i in self.uid:
url = urllib.request.Request("https://www.tomntoms.com/pop/pop_store_info.html?uid="+str(i))
url.add_header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko")
data = urllib.request.urlopen(url)
data = BeautifulSoup(data, features="html.parser", from_encoding='utf-8')

result_type = "C1"
result_name = data.find('h2', class_='tit')
result_location = data.find('p', class_='desc')
result_tel = data.find('a', class_='desc ff-roboto')

#print(result_name.text, result_location.text, result_tel.text)
self.storelist += [{ 'type' : result_type, 'name' : result_name.text, 'location' : result_location.text, 'tel' : result_tel.text, 'time' : '24시간' }]
return self.storelist

위가 탐앤탐스의 경우인데, 프랜차이즈 하나마다 클래스를 만드는 식으로 큰 틀을 잡았다. 대부분의 프랜차이즈들이 리스트에서는 세부정보(정확하게는 내가 필요한 정보들)를 보여주지 않고, 세부정보를 보여주는 페이지가 따로 있었다.

regexr 사이트님... 정말 감사합니다...

내가 필요한 정보가 “서울”내에서 “24시”영업을 하는 지점의 정보였기 때문에 리스트에서 해당 지점들의 uid를 1차적으로 수집한 뒤, uid를 바탕으로 세부정보를 조회하는 구조를 사용했다. 정규표현식을 사용하는게 오히려 더 편할 것 같아, 이번에는 많이 사용했다.

여기서도 많이 배웠다.

파이썬 정규표현식(re) 사용법 에서도 많이 배웠다. 혹시라도 필요하다면 정리를 되게 잘 해둔 것 같으니 참고하면 좋을 것 같다. 어쨋든… 대부분의 경우엔 이런 방식으로 빠르게 구현이 가능했다. 문제는… 지속 가능한 크롤러로 바꿀때 고생은 좀 하겠지만… 공부 좀 하면 답이 나오겠지… 라고 생각하고 있다.

데이터 가공

취합한 데이터들을 모두 모았으면 이제 가공을 해야한다. 가공이라고 해봤자 특별한 내용은 없다. 여러 프랜차이즈들의 정보를 취합하다보니 약간씩 수집한 데이터들의 차이가 존재했다.

  • 지점명에 프랜차이즈 명이 들어가는 경우
1
{'type': 'C3', 'name': '엔젤 불광역', 'location': '서울 은평구 대조동6-5번지 신흥빌딩 1층', 'tel': '02-389-9571  ', 'time': '24시간'}
  • 전화번호가 T.으로 시작하는 경우
1
{'type': 'C1', 'name': '논현점', 'location': '서울특별시 강남구 강남대로118길 43 ', 'tel': 'T.02-516-1030', 'time': '24시간'}
  • 영업 시간이 일부만 2시간인 경우
1
{'type': 'C5', 'name': '퍼플멤버스 신도림 라운지', 'location': '서울특별시 구로구 경인로 661 (신도림동)', 'tel': '02-2068-0048', 'time': '일~목(공휴일) 08:00~25:00, 금~토 24Hours'}
1
{'type': 'C7', 'name': '이태원점', 'location': '서울특별시 용산구 이태원로 153, 2층', 'tel': '02-797-6740', 'time': '월~목,일 9:00-02:00, 금토 9:00-08:00(24시간 영업)'}

예시와 함께 정리한 내용을 위에서 확인할 수 있다. 큰 문제는 없지만, 그래도 통일성을 위해 약간의 정리를 하고자 했다. 일단 “000점”과 같은 형태로 지점명을 통일하고, 전화번호 형식은 숫자만을 남겨두고자 했다. 영업시간 같은 경우에도 정리를 하고 싶었으나… 양식이 생각보다 너무 제멋대로라서 일단은 보류했다.

가공 방식은 간단하다. 정규표현식을 주로 사용해서 데이터가 올바른 형태인지 확인하고, 수정해주는 과정을 거쳤다.

데이터 전송

까지 현재 작성 완료. 추후 개발 완료시 더 추가될 예정.

디자인 초보가 만든 디자인 실제로 개발하기

시작 하기 전…

혹시 “디자인 초보의 험난한 디자인 개선기”를 읽지 않았다면, 지금 개발하는 HackRSS가 무엇인지에 대한 간단한 설명과 왜 이렇게 하고 있는지에 대해 아주 조금 더 이해할 수 있기 때문에 꼭 읽고 이 게시글도 읽었으면 좋겠다!

개요

머리 많이 굴려서 만든 태그 검색 기능 사용자들은 이렇게 피드를 확인할 수 있다!

자, 이제 “디자인 초보의 험난한 디자인 개선기”에서 그린 시안을 직접 React로 구현해보자. 기존에 작업했었던 코드는 전부 날렸다! 프론트부터 백엔드까지! 프론트의 경우 JS에서 React로 변경되어 처음부터 깔끔하게 시작하기로 하였고, 백엔드는 겸사겸사 새로운 기능들이 추가되며 리팩토링 할 겸 초기화했다.

개발 상황

다행히도 내가 개선 작업에 참여했을 때 보다 인원이 조-금 늘었다! 하지만 추가된 인원들이 개발자는 아니라서 두명이서 작업했다. 둘이 모여야 React 코드가 완성되기 때문에 우리는 이 상황을 “풀스택 개발자”에 빗대어 “하프스택 개발자”라고 표현했다.

우리끼린 정말 웃었다. 재미 없다면 심심한 사과를…

개발

특별히 뭐 React에 대해서 적을 건 없다. 나보다 더 똑똑한 사람들이 이미 많이 정리해 놨기 때문에… (Velopert님 책 정말 좋아요! 많이 배웠습니다!) 나는 그냥 개발하면서 느꼈던 것들을 소소하게 적어보려고 한다.

참고로 내가 맡은 부분을 어떻게 설명해야할지 모르겠어서 그냥 대충 절반은 내가 했다.

시작하며 느낀것

기간

2020년 6월 18일에 개발을 시작해서 2020년 12월 22일에 완성하였다. 원래 목표는 프론트만 개발하는 걸로 7월내 개발 완료였는데, 백엔드 개발이 추가되며 일정이 밀렸다. 게다가 개발만 하면 나오는 문제점들이 발목을 잡았다. 자세한건 아래 항목들에서 설명하겠다. 그렇게 미루고, 새로 개발할 내용이 추가되고 하다보니 결국 12월까지 밀렸다. 일정은 넉넉하면서도… 올바른 설계와 함께 설정되어야 한다는 것을 느꼈다.

설계의 중요성

매번 느끼는 것이지만… 개발을 할 때는 설계를 열심히 해야한다. 특히, 초급 개발자라면 더더욱…! 화면설계서와 API 명세서, DB 정도는 필수적으로 완성해놓고 개발을 시작해야 편하다고 생각한다.

대충 이정도로 그려놓고 시작했다.

이번 HackRSS 개발에서는 Figma를 사용하여 메인페이지와 일부 동작들에 대한 설계를 완료하고 개발을 진행하였다. 약 50%정도 완료한 상태에서 개발을 시작하였는데, 후반부 작업으로 갈 수록 문제가 생겼다.

그려둔 디자인을 실제로 구현해서 다양한 해상도에서 보았을때 어색해진 점이 있었다던가, 중간에 기능이 변경되서 임기응변으로 고쳐서 구현해야 했다던가… 구현 자체가 난이도가 있어서 대체한 경우도 있었다.

물론 완벽한 설계라는건 존재할 수 없겠지만, 최소한 그 시점에서 제시된 기능들에 대한 설계 작업을 완료하고 이에 대한 검토 작업까지 마무리하고 개발에 들어가는 것이 좋겠다고 느꼈다.

협업툴의 중요성

이슈 트래커의 중요성

QA 때 이와 같이 사용했을때 가장 편리했다.

개발자라면 Git의 Issue를 잘 활용하면 되지만, 팀 프로젝트라 개발자 이외의 사람들도 포함되어 있어 외부 이슈 트래커를 사용했다. 이번에 사용한건 Asana를 사용했는데, 꽤 마음에 들었다. 부가적인 기능들은 유료지만, 무료 기능을 사용하면서도 부족한 점은 없었다.

개인적으로는 Git과 연동이 되는 이슈 트래커를 사용했으면 좋겠다는 생각은 있지만, 팀 활동이라는게 여러 사람이 함께 사용하는 것이니 그정도는 괜찮았다.

오히려 늦게 사용해서 조금 아쉬웠고, 귀찮다고 마감일 지정을 안해두고 사용해서 까먹는 경우가 많았다. 아무튼… 이슈 래커 중요하다! 꼭 계획대로 잘 사용하자!

SourceTree

VS Code에도 Git 관련 기능을 붙일 수 있지만, 탐탁치가 않았다. 이번 작업에서는 SourceTree를 적극적으로 활용했다. 매우 만족하고 있지만, 맥 버전과는 다르게 윈도우 버전의 안정성이 너무 좋지 못했다.

대부분의 작업을 맥에서 하긴 했지만, 윈도우에서 꼭 확인은 해봐야 했기 때문에 좀 불편했다. 윈도우에서는 Github Desktop을 사용했는데 이것도 뭐 괜찮았다.

Git은 뭐… 사실 CLI 사용해도 되는거라 취향의 차이지만, 아무래도 커밋 그래프 같은 것을 바로 확인할 수 있다는 점에서 사용하는 것이 효율이 더 좋은 것 같다.

내가 만든 디자인한 것을 구현하며 느낀것

Material-UI

나 같은 경우에는 대부분의 CSS를 styled-component를 이용하는 것을 선호한다. 배경색과 폰트 정도만 글로벌 CSS를 수정하고 나머지는 하나하나 지정하며 개발했다. 그러다보니 Dropdown을 추가할 때 문제가 있었다. 내가 원하는 기능들을 가지고 있는 적당한 패키지들을 찾아 나섰는데 찾을 수가 없었다.

게다가 Bootstrap이나 Sementic-UI 같은 프레임워크를 쓰면 CSS가 다 깨져서 사용할 수 없었다. (물론 내가 잘 못 쓰는 것 일 수도?) 이런 문제들을 Material-UI가 모두 해결해주었다! 기능도 충분하고, CSS도 안깨지고! 정말 최고다!

이 밖에도 대부분의 기능에서 Material-UI를 이용하여 초기 구현을 마쳤지만… 정말 내가 원하는 대로 구현하려면 역시 직접 구현해야한다는 생각을 하게 되었다. 시간적 여유가 있다면, 아마 하나하나 대체해 나갈 것 같다.

그림과 구현물의 차이

내가 그린 디자인 시안대로 보고 만들지만, 그대로 만들기는 정말 어려웠다.

원래 이런 비율로 그린 시안이... 이렇게 약간 어색한 비율로 개발되었다...

왜 이런 문제가 발생했을까에 대해 고민을 해봤는데, 결국은 비율의 문제라는 결론을 내렸다. 설계 단계에서 사용자들이 자주 사용할 것으로 예상되는 해상도의 화면 설계를 준비하는 것이 이런 문제점을 해소할 수 있을 것 같다.

특히, HackRSS에서는 RSS를 보여주는 박스의 크기가 유동적인데 이에 대한 고민을 너무 하지 않은 것 같다. 당장은 아쉽지만… 추후에 꼭 수정해야겠다고 생각하고 있다. 모바일과 PC 모두에서 편한 UX를 고민해야겠다.

미디어쿼리는 한 사이즈 크게…

반응형 웹을 준비하면서 미디어쿼리를 세팅할 때 잘못 생각한 부분이 있었다.

max-width:1920px와 max-width:1600px를 작업한다면, 1920px에서 사용할 옵션을 1600px에 넣어야한다! 물론 모든 경우는 아니고, 나와 같이 박스 사이즈가 작아진다면… 1600에서 300px로 예상한 박스 사이즈가 너무 커지거나 작아지는 경우가 발생! 다음부터는 최소-최대 사이즈를 적절하게 고려해서 해야겠다.

사실 아닐 수도 있는데… 검색을 해봐도 명퀘한 해답이 없었고, 내가 남들과 생각하는게 조금 다른가보다… 아무튼 그랬다.

Redux는 필수인가? 그렇다.

사실 처음에는 왜 꼭 써야한다고 하는지가 와닫지 않았다. 직접 구현해보고서야 느끼게 되었다. 초기 세팅이 조금 힘들긴 해도, 관리 측면에서 보면 너무 편했다.

다만… 설계 부족이 여기서도 문제를 일으켰던 것 같다. Redux 쪽은 중반부 개발까지 다른 팀원(그래봤자 2인 개발)이 맡았다가, 후반부 작업에서 내가 이어받았는데 설계 자체가 없던 기능을 구현하려고 하니 내공 부족으로 조금 힘들었다. 지금 되돌아보면 조금 더 최적화(?)를 할 수 있었을 것 같은데, 너무 낭비해서 구현한 느낌이다.

Pages-Containers-Components와 중구난방으로 넘어다니는 props

이 글을 올리고 나서 직후에 할 작업이 바로… 내부 구조 개선이다…

이것도 설계 부족의 여파인 것 같은데… 중간에 내가 내부 구조를 한번 바꾸자고 해서 한번 바꾸고, 통합할 수 있어보이는 components들이 있고, 분리할 수 있는 components들이 보여 이 작업을 수행했었는데… 이게 더 복잡하게 만들어 버린 것 같다.

사실 구조의 정답은 모르겠다. 유명한 사람들이 짜둔 코드 구조를 보고 이렇게 하면 되겠구나를 배운거라… 그래도 일관성 있는 구조를 유지해야, 추후 다른 개발자가 투입되도 쉽게 알아볼 수 있을 것 같아… 여기에도 남겨둔다.

꼭… 처음에 설계를 잘 하고 시작해서 이런 구조도 합의를 잘 하고 시작하자!

남은 후속 개발들…

아직 개발할 기능들이 많-이 남아있다. 유지보수 하면서 하나하나 기능들을 추가시켜 나가보며 더 공부해야겠다.

광고

구글 애드센스 정말 귀찮다… 아직도 못달았다… 들어갈 공간을 마련해야 승인을 받는데… 이게 정말 마땅치가 않네~

개발을 어떻게 했다…를 이렇게 써보는 것이 처음이라 어떻게 써야할지 모르겠다. 오픈소스도 아니니 공개도 못하고… 참고 자료를 올려가며 설명을 하고싶어도… 대부분 코드니 또 애매하다 _ 아무튼 HackRSS 개발기는 여기서 마무리한다. 끝!

완성본

https://hackrss.kr/ 에서 확인 가능!

디자인 초보의 험난한 디자인 개선기

개요

어쩌다보니… React를 공부하게 됬고, 그에 맞추어 사이트 디자인을 “아주 약간” 공부하게 되었다. 누군가에게는 도움이 될까 해서… 생초보의 프론트엔드 작업 내용을 정리해봤다.

HackRSS?

HackRSS는 컴퓨터 보안(쉽게 말해 해킹)에 관련된 정보들을 수집해서 사용자들에게 보여주는 서비스이다. 초기 기획에 나도 참여했었고, 중간에 잠깐 다른 일이 있어 빠졌다가 다시 시간이 나서 지금 상태에서 개선 작업에 참여하게 되었다.

현재 상태 점검

테스트 버전의 HackRSS Feedly의 Cardview

기존의 HackRSS는 RSS라는 이름에서 알 수 있듯, RSS 관련 서비스중의 최고인 Feedly를 벤치마킹해서 개발하였다. 그러다보니 기능적으로는 Feedly와 차이점이 분명 존재하지만 디자인적으로 개선하여 우리만의 색을 만들기는 어려웠다.

물론 Feedly에도 기존의 HackRSS에도 문제는 많다. 당연히 우리가 더 문제 덩어리다. 기획을 제대로 하고 만든 서비스가 아니라, 프로토타입 정도로 개발한 서비스(거의 1인 개발)라 여러가지 문제점들이 있었다.

개선 작업에 참여하며 여러가지 문제점들을 확인하며, HackRSS에서 중점적으로 내세울 기능들을 선별하여 이를 강조하는 형태의 디자인을 해보기로 했다.

디자인 갈아엎기!

자 그럼 이제 문제점도 파악했고, 핵심 기능에 대한 선별도 끝냈다. 그럼 프론트 디자인은 어떻게 해야할까? 나는 UI/UX 설계나 디자인과는 거리를 두고 살았다. (대학에서도 수업 한번 들은 적 없다.) 어떻게 해결을 해야할까 막막하던 와중 Velog에 Velopert님이 올리신 “벨로그 홈에 그리드 뷰 되살리기 1편: 문제 확인과 벤치마킹”라는 글을 보게 되었다.

그리드 뷰?

네모난 화면의 네모난… 세상…이 아니라, Feedly의 Card View와 같이 격자 모양으로 배치를 해서 사용자에게 보여주는 걸 그리드 뷰라고 하는 것 같다. 생각보다 많은 사이트들에서 그리드 뷰를 사용하고 있고, HackRSS에서도 이를 활용하면 좋을 것 같았다.

여러 사이트들을 둘러보자!

이제 그리드 뷰를 활용하자는 방향을 정했으니, 다양한 사이트들을 돌아보며 디자인 컨셉을 정해보기로 했다. 일단 “벨로그 홈에 그리드 뷰 되살리기 1편: 문제 확인과 벤치마킹” 사이트에 올라와있는 참고용 사이트들부터 둘러보았다.

Velog와 비슷하게 텍스트 위주의 서비스를 개발할 예정이라, 역시 이미지 위주로 서비스 하는 곳들은 대부분 제외했다. 그렇게 둘러보고 남은 사이트들이 Velog, Surfit, Feedly 정도였다.

"Surfit"의 메인 페이지가 위와 같다.

특히, Surfit이 매우 인상깊었다. 이미지가 존재하지 않을 경우에도 적절한 비율로 컨텐츠를 보여주면서도, HackRSS에서 추가하려던 기능(태그, 북마크)등도 이미 서비스 하고 있었다.

이런 사이트들에 덧붙여 모바일 UI/UX도 여러 커뮤니티 사이트들이나 국내 메이저 웹사이트를 둘러봤다.

2단 레이아웃의 꿈

기존의 디자인에서 확인할 수 있듯이, 원래는 2단 레이아웃을 사용하고자 하였다. 서비스 특성상 RSS 컨텐츠들을 정리해서 본인만의 아카이브로 만드는 것을 중점적으로 생각하고 있었기 때문이다.

"벨로그 홈에 그리드 뷰 되살리기"에서 인용해온 글

그런데 이게 쉽지 않다는 것을 보았다. 그래서 깔끔하게 포기했다. 개발 경험치가 더 쌓이면 그때 도전하리…

새로운 디자인 적용

자 그럼 이제 둘러볼 만큼 둘러봤고 새로운 디자인을 그려볼 시간이다. 나는 이 작업에 Figma를 사용했다. 기본적인 포토샵 기능을 사용할 줄 아는 상태여서 사용법도 단축키도 비슷해서 사용하는데 편리했다.

연습작

2단 레아이웃 안녕...

사실 이렇게 2단 레이아웃을 바탕으로 가안도 그렸었다. 위에 깔끔하게 포기했다고 했는데 사실… 해보고 맘에 안들어서 포기했다. 정말 어렵더라. 그냥 묻어두기엔 아까워서 같이 올렸다.

PC 버전

Sidbar 없는 버전 Sidebar 있는 버전

최종본은 결국 1단 레이아웃을 사용하였고, 사용자들이 주로 이용해야할 기능들을 전부 사이드바로 이동시켰다. 어떻게 보면 사용자 입장에서 본인이 직접 아카이브한 RSS 컨텐츠들을 확인하기 위한 과정이 늘어났지만, 전문적으로 배운 사람이 아니라 당장은 이게 최선이었다.

모바일 지원

Sidebar 없는 버전 Sidebar 있는 버전

모바일 화면을 보면 알겠지만, 사실 모바일 시안을 그리고 그 시안을 바탕으로 PC 시안도 그린 형태다. PC 시안이 마음에 들지는 않지만… 시간적 여유가 없어서 우선적으로 하나를 그리고 이에 맞추어 작업했다.

다크모드?!

요즘 다크모드가 대세고, 나도 즐겨 이용하고 있어서 물론 시안은 그려놨지만… 개발을 얼마나 빨리 할 수 있을지 모르겠어… 여기엔 적지 않았다.

사실 여기까지 적고 생각해보니 결국은 Velopert님의 “벨로그 홈에 그리드 뷰 되살리기”가 너무 좋았다는 결론의 글이 된 것 같다. 근데 진짜 도움이 많이 됬다. 나와 같이 프론트 개발을 안해봤는데 해야한다면, 꼭 읽어보고 시작하기를 추천한다!

이제 다음편은 이렇게 야매로 만든 나의 디자인을 React로 구현하는 편이다.

참고자료

8-point 그리드로 디자인하기 디자인을 하면서 아무 생각 없이 디자인을 했는데, 8의 배수로 작업해야한다는 좋은 글이 있어 참고자료에 같이 남겨뒀다.

GoSo Helper with python

개요

어쩌다보니 디시인사이드의 게시글들 중 특정 키워드를 가진 게시글을 가져와서 PDF로 만드는 자동화 작업을 한 적이 있었다. 그렇다. 고소를 위한 증거 수집이다. 이번 게시글은 그때 만들었던 코드를 일부 수정한 버전이다.

GoSo Helper?

사이트의 특성상 게시글이 너무 많다. 하지만 게시판 별로 태그가 충실히 나뉘어 있으며, 글번호도 게시판마다 다르다. 그래서 크롤링 자체는 쉽다… 라고 말하려고 했는데, 공개를 위해 테스트를 해보니 작동하지 않았다…

대충 이유를 찾아보니, 크롤러 방지용으로 User-Agent를 검사하는 기능이 추가된 것 같았다. 그래서 겸사겸사 수정하면서 개선버전을 만들었다.

개선된 GoSo Helper는 기존의 PDF 인쇄를 특정 외부 사이트에서 받아오는 형식으로 만드는 대신, pdfkit을 이용하여 자체적으로 출력하도록 개발하였다. 또한, 멀티프로세싱 관련 코드도 조금 더 개선하였다.

그래도 오래 걸린다. 이전의 기억을 되돌려보면… 10만건 확인하는데 3시간이었나…? 아무튼 오래 걸린다. 물리적으로 어쩔 수 없다. 이 이상으로 빠르면 서버에서 접속을 끊었던걸로 기억한다

변경점?

기존의 Goso Helper는 python의 pool을 이용하였다. 오래전 일이라 기억이 잘 안나긴 하지만, 당시 속도 문제와 신뢰성 문제가 존재했다. 그래서 Process로 변경하였다.

변경하면서 대충 나혼자 쓰려고 만들었던 코드들도 개선을 조금 했는데… 귀찮기도 하고 시간이 너무 많이 드는 것 같아 적당히 고쳤다. 그래서 코드가 좀 엉망이다. 그래도 잘 돌아가니까…? 괜찮은가?

기능

match_str에 리스트 형태로 키워드를 넣고, 시작 글번호와 끝 글번호를 넣어주면, 그 범위 내에서 게시글을 찾는다. 키워드를 가지고 있는 게시글의 경우에는 web archive 사이트로 보내고, PDF화 한다.

두가지를 동시에 하는 이유는 어차피 고소하려면 PDF로 뽑아서 가야하고, Web archive 사이트로 보내서 백업본을 만드려는 이유다.

사용법

https://github.com/y2sman/goso_helper

개선 버전은 정확히 확인을 못했다. 이전 버전으로는 게시글 10만건 까지 돌려봤었다. 하지만 이번 개선버전은 시간 부족으로 100개정도 까지만 확인했기 때문에, 너무 많으면 중간에 꺼질 수도 있다.

Twitch chat bot with python

개요

완성은 작년에 완성하여, 공개는 지금 하게되었다. 사실은 개인적으로 하고 있던 일에서 꼭 필요한 건 아니었지만, 막상 검색해보면 한글 자료는 많이 없어 이렇게 공개한다.

쉽게 만들었으니, 사용법 읽어보면 컴퓨터를 잘 못하는 사람도 사용할 수 있을 것이라고 믿는다.

채팅 Bot?

트위치라는 방송 플랫폼에서는 이미 많은 좋은 채팅 관리용 도구(싹둑, 나이트봇)가 있다. 19년 1월부터는 모더레이터 권한을 가진 유저라면, 특정 유저의 채팅 로그를 확인할 수 있는 기능도 추가되었다.

하지만 문제는 대부분의 이용자들은 이러한 기능들의 EASY 버전만 사용한다는 것이다. 사실 이러한 봇을 추가로 사용할 이유가 없는데도, 대부분의 모더레이터들에게 나이트봇 메세지 수정 권한이 없기 때문에 추가적으로 사용하는 것도 이와 같다. (싹둑이는 모르겠다. 이런 기능이 존재하는지)

뭐… 그냥 개인 봇을 사용하는 것이 좋아서 그럴 수도 있고.

기능

사실 기능을 구상할 단계에서는 이제는 공식 기능으로 추가된 채팅 로그를 확인 할 수 있는 등의 여러가지 기능도 구상하였는데… 너무 늦게 만들었다.

특별한 기능은 없고, 머릿속에 있던 채팅 봇의 필수 기능에다가 자동 백업 기능만 추가했다. 기본은 트위치에서 제공하는 샘플 코드 GitHub - twitchdev/chat-samples에서 가져왔다. 그냥 약간 수정해서 필수 기능만 만들었다.

문제점?

작동에는 문제가 없다. 어쩌다보니 공개가 늦어져서, 테스트 기간을 1년 넘게 가졌고 자잘한 버그들은 이미 다 수정했다.

걱정되는 부분중에 하나는 IRC의 tags를 핸들링 하는 코드를 짜기 귀찮아서… 그냥 처리했다. 혹시 모더레이터가 명령어를 수정하지 못할 수도 있다. 그런 경우엔… 트위치에서 API를 바꾼 경우라… 수동으로 고쳐야한다.

그래도 1년간 딱 1번 있었던 경우라 가용성에는 문제가 없을 것 같다. 시간 나면… 추가하겠다.

사용법

사용하기 전에 여러가지 선작업이 필요하다. 당연히 본인 계정에서 돌릴 것이 아니라면, bot 계정을 만들어야한다. 그리고 Oauth를 발급받고, 봇을 등록하는 과정을 거쳐야하는데…

챗봇 만들기 20분만에 트위치 챗봇 만들기! — Steemit

그건 그냥 이렇게 다른 블로그에서도 설명하고 있으니, 보고 따라하면 된다. 사이트 디자인만 달라졌으니 여기서는 설명하지 않겠다.

그리고 가능하다면 봇에 모더레이터 권한을 발급하는 것을 주는 것을 추천한다. 초당 메세지 전송 갯수가 정해져있는데, 모더레이터의 경우 이런 경우에 일반 유저보다 더 많은 메세지를 전송할 수 있다.

진짜 사용법

https://github.com/y2sman/twitch-chat-bot

끝! 사실 전공자 입장에서는 되게 쉬운 작업이다. 그래도 다른 일 하면서 문의하는 사람들이 꽤 있어서… 늦었지만 공개하게 되었는데, 문제 없이 잘 돌아갔으면 좋겠다!

Hexo & Icarus 블로그 시작

개요

작심 3일이긴 하지만 컴퓨터를 주업으로 해야할 사람에게는 블로그는 중요하다고 생각하고 있었다. 매번 글을 써야지… 써야지… 해두고서 까먹는 나지만 우연하게 발견한 블로그 디자인이 너무 마음에 들어 찾아보았더니 Hexo에 Icarus테마를 사용한 블로그였다.

Hexo? Icarus?

Hexo는 심플함을 표방하는 블로그 프레임워크다. 처음 보는 프레임워크라 사용법 docs를 보며 어떻게 쓰는지 알아보았는데, 테마 config파일과 Hexo의 config파일이 나뉘어있다는걸 몰라 처음에 고생했었다.

테마는?

가끔 블로그들을 보면 목차가 잘 안나와있는 블로그들이 많았다. 깔끔한 디자인이라 마음에는 들었지만, 정보를 찾는 입장에서는 편하지 않았다.

그래서 이 테마(hexo-theme-icarus)를 찾았다.

목차 구분이 명확하며, 각종 분류가 확실했다. 그리고 무엇보다도 내가 원하는 디자인이었다! 깔끔한 디자인… 새 블로그는 꼭 잘 써야겠다는 마음을 가지고 설정했다.

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×