글쓰기 메뉴

업데이트

프레임워크 버전이 너무 올라가서 나중에 따라가려면 대형 공사가 될까 걱정되어 프레임워크 버전업. 하지만 이미 큰 공사였음. 아 힘들어.


텍스트 에디터도 자잘한 오류들이 많이 보여서 코드 정리 및 라이브러리들 일부 업데이트. 완전 힘듬.


별로 테스트 해볼 시간은 없어서 대충 동작되는 것 같아서 서버에 적용.


오류나면? 알려주삼.


사진등록도 테스트 할겸.. 배도 고플겸..
어디서 왔지?
[["synd.kr", 19], ["unknown", 51]]
다른 글들
1 0
Square

안드로이드 앱 업데이트

씬디는 원래 웹 버전이 베이스라 (아.. 시대착오적...) 초기부터 쓰시던 분들은 앱이 있는지도 모르실텐데 몇달전에 안드로이드만 우선적으로 (제가 안드유저라) 등록했었습니다.
저조차도 앱은 설치했지만 설치하고 보니 '당겨서 새로고침' 이 안되기에 뭔가 어색해서 안쓰고 있었죠.
그런데 간간히 안드 앱으로 사용자분들이 들어오시더니 급기야는 누군가 플레이스토어에 무려 리뷰를 남기신겁니다!!
화면 회전 시키면 첫페이지로 돌아간다는 오류 리포트를요.
엄청나게 짜증나는 오류일텐데 그걸 리뷰로 남겨주신 정성과 애정에 무한한 감사를 느꼈지만 과연 내가 언제 업뎃 작업을 할 수 있을까하는 걱정도 있었습니다.
그러다가 오늘 아침 드디어!!! 꽤 이른시간에 출근하게되어 상큼한 기분으로 풀충전되어있는 그 타이밍을 놓치지 않고! 앱을 업데이트했습니다.
회전 시 초기페이지 이동 오류와 '당겨서 새로고침' 을 추가했습니다.
혹시나 씬디 사용하시다가 오류나 버그가 아니여도 불편한점이 있거나 추가되면 좋겠다는 내용이 있으면 아무곳으로나 알려주세요.
씬디에 글로 써주시면 제일 좋구요.
사족)
당겨서 새로고침을 직접 구현하지 않고 안드로이드 SDK 에서 제공하는 SwipeRefreshLayout 을 사용해버렸네요.
구버전 호환성을 꼼꼼하게 확인하지 않았는데.. 업댓은 했으나 마음의 짐은 또 하나 생겼네요 ㅠ.ㅠ
0 0

rbenv 새로운 버전의 루비 설치하기

설치가능한 루비 버전의 목록은 아래처럼 확인할 수 있지
$ rbenv install --list
목록에 없는 최신 릴리즈의 Ruby 를 설치하려 할 때 rbenv 를 업데이트하면 되지. (Git 버전)
이렇게 하고 설치가능 목록을 다시 확인하면 따단~ 하고 새로운 릴리즈가 떠야하는데 새로운 버전의 루비가 목록에 없는 경우가 있어. 그럴땐 ruby-build 를 업데이트해주자.
잘 될꺼야.
0 0

우분투 14.04 wkhtmltopdf 설치

wkhtmltopdf 는 HTML 페이지를 PDF 로 만들어주는 오픈소스 도구로 Qt WebKit 엔진을 사용한다. 자매품인 wkhtmltoimage 는 같은 방식으로 HTML 을 다양한 형식의 이미지로 변환시켜준다.
Ubuntu 14.04 에서 apt-get 으로 wkhtmltopdf 패키지를 설치할 수 있으나 Qt 가 wkhtmltopdf 에 맟춰 패치되지 않았다면 몇 가지 기능이 제한된다. 예를 들면 HTML 에 있는 링크가 PDF 에 사라지는 등의 오류가 있을 수 있다. 관련 옵션은 --enable-external-link 인데 Qt 가 패치되어 있지 않으면 해당 옵션을 켤 수 없다. 
그러니 wkhtmltopdf 홈페이지에서 컴파일되어 있는 바이너리를 다운받아 설치하도록 하자. 만사가 편하다.
* 우분투 서버를 사용하고 있을 경우 X 시스템과 폰트관련 패키지가 설치되어 있지 않다. 이럴 경우 먼저 필요한 패키지와 폰트를 설치하자.
폰트는 마음에 드는 패키지를 찾아 설치하면 되는데 별도의 설정없이 바로 사용할 수 있는 한글 폰트는 unfonts, baekmuk, nanum 정도 되겠다. 각각 패키지는 아래와 같다. (우분투위키에서 CJK 폰트 참고)
은폰트 - unfonts
백묵폰트 - baekmuk
나눔폰트 - nanum
폰트툴과 폰트가 설치 된 후 wkhtmltopdf 다운로드 페이지에서 Ubuntu Trusty (14.04.1) 버전(64-bit)의 .deb 파일을 다운받아 아래와 같이 설치한다. 
설치 후 아래와 같이 확인할 수 있다.
webpage/url 이라는 주소의 웹페이지를 save.pdf 로 변환하는 명령어 예제는 다음과 같다. 자세한 옵션은 man wkhtmltopdf 로 확인할 수 있다.
--print-media-type
스크린 타입이 아니라 프린트 미디어로 PDF를 렌더한다.
--page-size
페이지 사이즈를 지정한다. Letter, A4, A3 등의 형식으로 지정할 수 있다.
* 공식 홈페이지에서 전체 리스트 링크를 제공하고 있으나 현재 사용이 연결이 되지 않는다. 소스에서 확인한 전체 리스트는 이 곳에 적어둔다.
* --page-width, --page-height 로 페이지 크기를 지정할 수 있다 
--dpi
dpi (dots per inch) 값을 지정한다.
-T, -B, -L, -R
상(Top), 하(Bottom), 좌(Left), 우(Right) 여백을 지정한다.
요즘 웹페이지의 PDF 변환이나 이미지 캡처는 요즘 PhantomJS 를 사용한 방식이 훨씬 많이 소개되고 있다. 의존패키지에 대한 고려나 설정에 대한 부담감이 없기 때문일텐데 개인적으로 wkhtmlto* 를 오래전부터 사용하고 있어서 정리해봤다.
1 0

레일즈4 어플리케이션 이름 변경

2.x 버전에서 어플리케이션 이름 변경해봤었는데 '아, 그냥 프로젝트 새로 만들고 소스 카피가 좋겠다' 라는 생각이 들 정도로 변경해야 할 파일의 갯수가 찝찝한 기분을 지울 수 없었지.
그 이후로 한참 그럴 필요가 없었는데 이번에 기존 소스를 카피할 일이 생겼지.
레일즈 4.1.x 이상의 버전에서 단 2개의 파일에만 어플리케이션의 이름이 지정되어 있더군. 깔끔하게 정리된겨.
config/application.rb 파일에서 module 이름을 변경하고,
config/initializers/session_store.rb 파일에서는 세션 스토어의 키 이름만 변경해주면 끝!

수고하고 있는 루비 커뮤니티에 축복을! ㅋㅋ
+)
3버전이나 4.0.x 버전에서는 https://github.com/get/Rename 을 사용해서 깔끔하게 변경가능.
참고)
https://stackoverflow.com/questions/20988813/how-to-rename-rails-4-app/23753608#23753608?newreg=15907dbe38c743fa9f7aca841050ba57
2 3
Square

아! 무선 해피해킹!
드디어 HHKB 블투버전!

해피 해킹 키보드 프로페셔널2 버전을 10년째 쓰고 있습니다.
2007년 이케부쿠로 빅카메라에서 구입한 해피 해킹 프로2 는 아직도 키감을 포함해 한결같은 성능으로 매일의 작업에 사용되고 있죠.
단 하나. hhkb 에 바라는 것이 있었다면.. "무선".
유선이라서 문제가 된적은 없습니다만 무선으로 책상을 정리하고 싶은 강한 욕망은 hhkb 를 대체할 수 없음에 항상 억눌려있었습니다.
그런데! 그런데! PFU 에서 드디어 블루투스 버전을 출시한답니다.
블루투스 3.0 클래스 2, 프로파일은 HID 1.0, 하위버전 호환가능하며 4대까지 페어링 지원이랍니다.
전원은 AA 건전지 2개로 스펙에 따르면 3개월 사용가능하다고 하네요. 전원 공급을 위한 USB 단자가 있습니다만 케이블은 미포함이고 연결용으로는 사용할 수 없다고 합니다.
일본 아마존에서 한정판매로 진행되고 있으며 4월 20일까지만 주문가능합니다.
가격은 29,700엔. 검정색만 있고 영문각인과 무각, 일본어배열-일본어 각인 총 3종이네요.
영문 무각으로 구매해야겠네요.. 안사고 버틸 방법이 없...
PFU Online,
HHKB BT
1 0

우분투 몽고DB 설치 및 부팅 시 자동 실행 - Install MongoDB on Ubuntu & Start MongoDB on system start

설치는 매우 간단하고 MongoDB 공홈에 최신 버전으로 갱신된 문서가 있어 해당 페이지를 참고하면 된다.
공홈 설치 문서 링크:

https://docs.mongodb.com/manual/tutorial/install-mongodb-on-ubuntu/
GPG Key
리스트파일 생성 (16.04. 기타 버전은 공홈 참조)

패키지 디비 갱신
MongoDB 설치

근래의 대부분의 배포본은 Upstart  대신 Systemd를 사용하기 때문에 위와 같이 설치된 MongoDB 역시 init 스크립트를 제공하지 않는다.
service 커맨드로 시작, 중지, 재시작 등의 관리가 가능하나 systemctl 커맨드를 익히는게 바람직하다고 본다.
systemd 를 사용해 MongoDB 를 초기 실행 시키기 위해 다음의 파일을 작성한다.
/etc/systemd/system/mongodb.service

Unit 섹션의 Description 은 서비스에 대한 간단한 설명을 포함한다.
같은 섹션의 After 는 네트워크 연결 후 구동하겠다는 의미
Service 섹션의 User 는 서비스 실행 사용자를 지정하고 ExecStart 는 실제 구동 커맨드를 입력한다.
Install 섹션의 WantedBy 는 실행 타깃을 구분하는데 multi-user.target 은 기존 런레벨 2,3,4 로 일반적인 부팅 시에 동작된다.
구동
상태 확인
정지
부팅 시 실행
systemd 의 target 에 대해 보다 자세히 알고 싶다면 아래의 링크를 참조.
https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/System_Administrators_Guide/sect-Managing_Services_with_systemd-Targets.html
systemd 에 대해 보다 자세히 알고 싶다면 아래의 링크를 참조
http://lunatine.net/about-systemd/
1 0

리디렉션 페이지에 구글 아날리틱스 코드 집어넣기

리디렉션 되는 페이지에 구글 웹로그 분석기 추적 코드를 넣고 meta 태그나 스크립트로 페이지를 이동시키면 데이터 수집이 완료되지 않은 상태로 페이지가 종료되고 로그가 남지 않는 문제가 있지.
리디렉션을 5초 정도로 잡아도 무관하다면 그냥 5초로 잡고 돌려도 OK.
리디렉션 타깃 페이지가 같은 도메인 아래에 있다면 타깃 페이지에 추적 코드가 있는 것 만으로 레퍼러로 처리되어 데이터가 수집되니까 이것도 OK.
하지만 리디렉션을 외부 사이트로 보내야하고 1~5초 정도 사용자를 묶어두는게 부담스럽다면 추적 코드의 동작이 완료된 후 리디렉션을 실행하면 되겠지.
2013년부터 사용된 Google Universal Analytics 추적 코드라면 hitCallback 콜백을 사용하면 되고 혹시 2013년 이전 코드라면 글로벌 오브젝트인 _gaq 큐에 함수를 밀어넣으면 된다네.
추적 코드 어딘가에 _gaq 가 있으면 그냥 오래된 코드, _gaq 가 없고 다음과 같이 추적코드가 시작된다면 Universal.
오래된 버전에서는 아래처럼 리디렉션이 가능
Universal 버전에서는 아래처럼 hitCallback을 사용할 수 있음
이상 끝!
1 2

파손

서피스 프로 3를 가방에 넣은채로 살짝 떨어트렸는데 모서리로 떨어졌나보다.
우측 상단이 살짝 깨지고, 액정 유리에 금이 하나 생겨서 점점 진화하고 있다. 다행인건, 액정 보호 필름을 붙여놔서 더 이상의 피해는 없을 것 이라는 점. 그리고, 터치도 이상없이 잘 먹힌다. 
서피스 프로 3는 부분 수리가 안되는 놈이라 리퍼를 받아야 하는데, 물경 464000원이 든다고 한다. 그래서 일단 이대로 쓰기로 결정을 했다. 서피스 프로 3가 시장에 풀리면서 과거 서피스 버전을 리퍼 받을때 서피스 프로 3로 해주던 때가 있었으니까, 이걸 이대로 좀 더 쓰다가 서피스 프로 4로 리퍼 제품을 줄때 리퍼를 받아야겠다(는 희망사항). 아니면, 기능에 이상이 생길 때 리퍼를 받자. 
속이 쓰리다. 부글부글.
0 2

Rails4, MySQL 4바이트 유니코드
(아이폰 특수문자 등의 Emoji) 지원 설정

MySQL의 utf8 문자셋은 3-Byte UTF-8 Unicode Encoding 을 지원하지.
3 bytes 면 사실 대부분의 글자가 다 표현되거든. 한중일, 중동, Latin 및 특수문자 다 포함해서 말이야.
그런데 원래 UTF-8 은 4 bytes 까지 기록할 수 있어. (그보다 더 옛날 스펙은 6 bytes 까지)
하지만 별로 쓸일도 없고 해서 MySQL 같은 몇몇 소프트웨어는 UTF-8 을 3 bytes 까지만 지원하는겨.
꽤 오랫동안 별 문제없었지만 아이폰의 특수문자 - Emoji 가 4 bytes 유니코드라서 이거 지원 안되는 DB에는 데이터가 제대로 안들어가는 문제가 생긴거지.
아이폰 사용자도 많고 이모지 사용도 꽤 잦기 때문에 - 인스타그램 이딴건 글자보다 이모지가 더 많아! - 이제는 우리도 4 bytes 유니코드를 지원해야 하는거지.
지금 서비스에서 이모지가 저장되는지 아닌지는 다음 문장을 복사해서 저장해보면 알 수 있지.
제대로 저장이 안된다면 이제 설정을 시작해보자.
준비물
MySQL 버전 5.5.3 이상!
차사고와 DB 사고는 항상 일어날 수 있지. 한 백번쯤 백업해놔.
1. database.yml 에서 인코딩 등 수정
2. MySQL 인덱스 길이 수정
3. 데이터베이스 재생성 또는 테이블 수정
이제 긴장 좀 때리자.
3-1 디비를 전부 삭제하고 다시 만들어도 되는 경우
3-2 디비 재성성이 불가능한 경우
1) 데이터베이스 수정
2) 테이블 수정
3) 컬럼 수정
3-3 점검걸고 데이터 백업하고 디비 재성성 후 restore
이거 편하긴하겠지만 무슨일이 생겨도 난 책임 못 진다.
진짜 책임 못 진다. 백업 백번하고 로컬 PC랑 다른 서버에 여기저기 보관해라.
뭔지 잘 모르겠으면 그냥 하지마라.
1) 일단 데이터만 백업
2) 디비 재생성
3) 데이터 리스토어
끝!
1 3

페이스북 임베드 URL,
소셜 플러그인 (XFBML) 파싱

임베드 대상 페이스북 콘텐츠는 "포스트", "비디오", "사진" 이렇게 종류별로, 웹과 모바일에서 각각 URL 형식이 조금씩 달라 프로그램으로 이를 처리하기 위해 동일한 형태의 주소가 필요하다.
SDK를 사용해 페북 컨텐츠를 임베드하는 경우 기준이 되는 URL 은 웹용 URL 이다.
뭐, URL은 딱보면 알겠지만 fbid 라는 고유ID만 빼오면 된다. 
모바일에서 포스트에 대한 주소만 URL 파라미터로 처리되어 있고 나머지는 전부 URL Path에 포함되어 있으니 아래와 같은 정규식으로 fbid부터 발라내자
정규식은 Ruby 2.x 버전에서만 동작을 확인했지만 look-behind 와 look-ahead 외에 정규식 엔진을 타는 내용이 없기 때문에 동작이 안된다면 그 부분만 수정하자.
사실 효율을 생각한다면 저딴 정규식으로 한방에 fbid 를 뽑는 것 보다 fbid 가 파라미터로 존재하는 케이스를 분리시키고 나머지 정규식도 2회로 나눠 돌리는게 더 좋지만... 귀찮으니 한 줄로 하자.
상식적으로 fbid 만 뽑아내면 될 것 같으나 페북 임베드에 사용되는 URL은 사용자 아이디가 버킷 이름처럼 포함되어 있다. 문제는 모바일 URL에 사용자 아이디-문자-가 없다는 점.
이 문제는 페이스북의 짧은 주소 fb.com 을 사용해 해결할 수 있다. http://fb.com/<fbid>의 형식으로 리퀘스트를 보내면 해당하는 완성된 주소로 리디렉션 시켜준다. - 임베드 코드 생성 시 fb.com 을 그냥 쓸 수 있으면 좋을텐데 안되더라.
curl 로 리디렉션된 최종 URL을 뽑는 코드는 아래와 같다.
내가 쓰는 Typhoeus 에선 아래처럼 최종 URL을 받으면 된다. 
이렇게 얻은 URL 로 
위와 같은 XFBML을 사용해 임베드가 가능하다. 다양한 옵션은 페북 문서 확인.
Javascript SDK 를 사용하는 경우 SDK 가 로드된 후 FB 객체를 initialize 하면서 페이지에 있는 모든 XFBML 을 파싱할 수 있고, 이와 다른 타이밍에 추가적으로 XFBML 을 파싱해야하는 경우는 아래의 코드로 가능하다.
특정 엘레먼트만 파싱하려면
jQuery 로 돔을 잡아 파싱하려면
이렇게 파싱하면 컨텐츠가 임베드된다.
1 1
Square

[3분 복붙] 기사면 랜딩 PV 2배로 올리기.
브라우저 뒤로가기 제어.
이딴거 만들지 말자.

대부분의 서비스가 보다 많은 활동 사용자를 목표로 함은 분명하다.
하지만 얼마나 많은 활동 사용자가 있는지를 가늠할 수 있는 지표에 대한 목표설정은 좀 다른 얘기라고 생각한다.
심지어 그 목표의 달성을 위한 실현 과정이 사용자들을 열받게 만든다면 이 얼마나 근시안적 추태인지...
PV (Page View, 페이지 조회수) 에 대해 강한 집착을 보이는 국내 언론사들이 근래 "뒤로가기"가 실행되는 경우 이전 페이지로 보내지 않고 메인페이지로 이동되도록 하는 기능을 속속 도입하고 있더라. (좀 됐지.. 내가 잠수였던거지..)
사용자 입장에선 개빡치는 UX. 
그렇지만 남들이 한다니까 자기들도 해달라는 클라이언트의 등장은 당연지사.
해당 기능을 도입한 사이트들을 둘러보니 대부분 광고대행사 등이 제공한 스크립트를 사용하는 것 같더라.
메인페이지를 거치는 것도 짜증나는데 그 중간에 광고까지 껴있으니 개짜증..
이딴거 누가 안만들면 좋겠는데 일개 개발자가 뭘 할 수 있겠냐 고민하다가...
클라이언트에게 만들어준 간단한 스크립트를 모두에게 제공하고 너도나도 다들 도입해서 더 많은 사용자들이 더 빠르게 빡돌게 만들면 슬슬 이딴 쓰레기 같은 기능을 버리지 않을까라는 골때리는 결론에 도달했다.
0.
jQuery 를 사용하고 있다고 가정한다.
1.
아래의 코드를 기사 페이지 등 기능이 동작될 페이지에서 로드되는 js 파일에 추가한다.
3번 라인 정규식 패턴안의 synd\.kr 부분은 자신의 도메인으로 변경한다.
2.
기능이 동작될 페이지 HTML 코드 사이에 아래의 코드를 삽입한다.
완성!
코드는 단순해서 쉽게 이해할 수 있겠지만 몇몇 부분을 설명해보자면...
1. pushState 이후에 replaceState 를 다시 콜하는 이유.
pushState 만으로 history 를 조작할 경우 firefox 에서 백버튼이 골때리게 반복된다.
external > page > main > page > main > external
replaceState 를 다시 콜하면 아래와 같이 의도한대로 동작된다.
external > page > main > external
2. popState 이벤트를 사용하지 않고 hashChange 를 사용하는 이유
페이스북 앱 등 in app browser 를 사용할 때 해쉬가 없는 경우 뒤로가기 실행시 popState 이벤트가 발생되지 않음
해쉬를 추가해야 뒤로가기 실행 시 기존 URL (해쉬없는) 로 페이지 변화없는 이동이 발생하고 이 타이밍에 hashChange 가 콜 됨.
또한, Safari 9버전 이하에서 popState 가 지멋대로 fire 됨.
3. 이건 좀 쓸데없는 설명이지만 location.href 는 history 에 기록되고 location.replace 는 history 에 남지 않기 때문에 replace 를 사용해야함.
지원브라우저
웹이고 모바일이고 html5 history api 를 지원하는 브라우저 (http://caniuse.com/#search=history) 에선 기본적으로 모두 동작된다고 기대할 수 있으나 아이폰 크롬에서 동작안됨.
그 외 페이스북 앱 등 인앱에서 웹뷰를 사용하는 경우도 정상 동작.
Tested.
Microsoft Edge.
Microsoft IE 11.
Firefox 52.x (Windows)
Firefox 47.x (Linux)
Firefox 52.x (Mac)

Firefox 52.x (Android)
Firefox 6.x (iOS)
Chrome 57.x (Windows)

Chrome 48.x (Linux)
Chrome 56.x (Mac)

Chrome 57.x (Android)
Chrome 57.x (iOS) *동작안됨
Safari 10.x (Mac)
Safari 10.x (iOS)
Android 6 browser 4.x
Facebook App
자 이제 자리에서 일어나서 팀장이든 부장이든 상사에게 "저희 PV 를 2배로 올리겠습니다!" 라고 보고하고 보다 많은 사용자들의 빡을 돌려(?) 주삼. 
1 1

Trix Editor 변경 작업 중단

누가 궁금할까 싶지만 에디터 변경을 예고한 적이 있고 작업을 중단했기 때문에 글을 남겨놔야지.
Trix 로 에디터 변경을 원했던 이유는 당연히 안정적인 입력을 위해서였지만 약 3일에 걸친 작업 끝에 다음과 같은 이유로 작업을 중단했다.
1. 2bytes 입력에서 몇가지 문제가 확인됨. 
- Trix 는 라인브레이커로 br 을 사용하고 div나 pre, figure 등의 블럭 엘리먼트가 들어오면 새로운 "블럭"을 만드는데 새로운 블럭의 첫 단락에서 확정적으로 자모음이 깨진다.
- Trix 는 contentEditable 을 사용해 IME 의 입력내용을 캐치하고 Trix::Document 를 생성하는데 2bytes 의 경우 한 글자를 위해 여러번의 키스트로크가 발생할 수 있기 때문에 글자의 순서가 변경되는 문제가 간혹 발생한다.
- 같은 이유로 입력된 글자를 contentEditable에 재출력할 때  다른 블럭으로 캐럿이 점프되는 경우가 있다.
2. 기존 사용하던 에디터의 안정성이 확보됐다.
- 사용 중이던 에디터가 갑자기 엄청난 숫자의 버그들을 쏟아냈으나 약 2달에 걸쳐 대부분의 버그가 수정됐다.
- 입력된 콘텐츠가 날아가는 치명적인 문제가 남았지만 원인을 찾을 수 있었고 소스 핵을 통해 해당 부분 스킵. 발생되는 사이드 이펙트는 서버단에서 저장 시 처리하도록 코드 수정.
Trix 의 개발은 계속 팔로우 하겠고 의미있는 버전업이 생기면 다시 개발을 고민해봐야겠다.