Libra: 도서관 전자책 검색 및 대출 프로그램

Lybra: 도서관 전자책 검색 및 대출 프로그램 만들었습니다.

전자책 읽는 것을 좋아해서 개인적으로 쓰려고 만들었는데, 유용할 것 같아서 일반 공개합니다. django 2 + vue.js + bootstrap 4 로 만들었고 SPA(Single-page application) 형태로 디자인 했습니다. 제가 UX 엔지니어가 아니다보니 UI는 좀 불편할 수 있습니다.

경기도 (+안양시) 거주하시는 분들 중 경기도 사이버도서관이나 안양시 도서관 전자책을 많이 보시는 분들에게는 유용할 것 같습니다. 필요없는 카테고리의 책들(e.g. 아동 도서)를 아예 책 목록에서 감춰버리거나, 관심이 있는 책들, 읽은 책들, 혹은 목록에서 안보이게 만들고 싶은 책들을 마킹해둘 수 있어서 관심가는 책들을 정해두고 한권씩 시간날 때 마다 빌려보는데 유용합니다.

아래 주소에서 회원 가입하시면 사용할 수 있습니다.

https://libra.sunghwanyoo.com

자동 대출 기능은 일반 사용자는 불가능한데요, 경기도 사이버도서관 id / password를 서버에 저장해두어야 하기 때문입니다. 보안 문제가 있다보니 자동 대출 기능까지 전체 오픈하는 것은 조금 생각을 해보아야 할 것 같습니다.

참고로 이름의 의미는 사서(Librarian)의 앞 5글자를 따왔고, 황도 12궁 가운데 하나인 천칭자리(Libra)를 뜻하기도 합니다.

바쁘다보니 간간히 업데이트는 하겠지만 자주는 힘들 것 같네요. 문의 사항은 shyoo at sunghwanyoo dot com 으로 해주세요.

애니 및 드라마 자막 다운로드 서비스

안녕하세요,

자주 사용하던 smidown.com 이 다운되어서 임시로 애니, 일드 및 미드 자막 제작자 분들이 업로드한 자막을 수집해서 보여주는 사이트를 만들었습니다.

사용자 삽입 이미지

다음 주소 방문하시면 됩니다 : http://subtitle.sunghwanyoo.com

검색 기능 등은 지원하지 않습니다만, 나중에 추가하도록 하겠습니다. ^^

콘티 작성 및 찬양곡 연관도 분석 툴

(updated 2014.3.24)

취미생활로 제작하던 콘티 작성 및 찬양도 연관도 분석 툴을 공개합니다. 콘티를 짤 때 연결되는 곡들을 만들기 위해서 찬양집 목록을 뒤적이는 분들이 많으실 것 같은데요, 자동으로 연관된 가사를 가진 곡들이나 해당 곡과 같은 콘티에 들어갔던 적이 많은 곡들을 보여주는 도구입니다.

다음 주소를 방문하시면 됩니다 : http://project.sunghwanyoo.com/similar_worship

사용자 삽입 이미지
첫 화면을 보면, 기본적으로 가장 많이 불리는 곡 가운데 하나인 “예배합니다”와 “그 사랑”과 관련된 곡들이 화면상에 보여지게 됩니다.

메뉴를 보면 다음과 같은 기능들이 있습니다.

1. Relations

선택된 곡 (여기에서는 “예배합니다”와 “그 사랑”)과 관련된 곡들을 선정하는 기준을 설정합니다.  “By used”는, 같은 콘티에서 있었던 곡들 중에 가장 많이 선택된 곡을 출력하고(즉 같이 불려진 횟수), “By lyric”은 가사의 내용을 기반으로 가장 유사한 곡들을 출력해줍니다. “All”은 이 둘을 적절히 조합하여 출력해줍니다.

2. Layout

곡들을 화면상에 어떻게 출력할지를 결정합니다. “By similarity”는 유사한 곡들(같이 불려진 횟수 혹은 가사 유사성)이 가급적 근처에 붙어있을 수 있도록 하고, “By key”는 Key 별로 분류해서 출력해주는 역할을 합니다. 곡별로 있는 원들은 Key를 의미하므로, 아래와 같이 “By key”를 선택하면 색깔별로 모이는 것을 볼 수 있습니다.

사용자 삽입 이미지

3. Filter

화면상에 곡이 너무 많을 경우, 중요도 순으로 이를 필터링하는 기능을 합니다.

4. Sort

그다지 중요하지는 않는데, 곡들을 정렬할 때 출력 횟수를 기준으로 하는지 아니면 연결된 링크의 수를 기반으로 하는지를 결정합니다. 그냥 놔두셔도 됩니다.

* 곡별 정보 분석

화면상에 있는 각 곡의 이름 혹은 원 위에 마우스 커서를 올리면 가사 첫줄 제목과 작곡자 등의 정보가 보여집니다. 여기에서 “콘티에 추가”를 클릭하시면 오른쪽 콘티 리스트에 곡이 추가됩니다.

사용자 삽입 이미지

아직까지 콘티상의 곡을 삭제하거나 하는 기능은 없지만, 조만간 추가할 예정입니다. 그리고 콘티상의 곡을 클릭하시면 옆에 pin 아이콘이 나타나면서, 해당 곡을 중심으로 새로이 연관곡들을 갱신해서 화면에 출력해주게 됩니다. 이 때 여러곡을 선택해서 분석하실 수도 있습니다.

사용자 삽입 이미지

마지막으로 화면상에 없는 곡들은 위에 있는 검색 기능으로 콘티상에 추가하실 수 있습니다. 원하는 곡을 입력하고 Search 를 누르시면 됩니다.

사용자 삽입 이미지

악보보기나 음악듣기와 같은 기능들은 저작권 문제로 구현하지 않았습니다. 공개 버전에서는 추후 가사 보기 같은 기능 혹은 부분 악보보기 기능이라도 구현해 볼 예정입니다.

그럼 콘티 짜실 때 도움이 되었으면 좋겠습니다. ^^

Installing pptpd on Ubuntu

Recently I had to set up VPN server on my Ubuntu server 10.04.

Yes, Ubuntu 10.04 is old but the following guide  will also work for latest  Ubuntu systems as well.

pptpd is the VPN server that provides microsoft VPN protocol, which will mostly work fine with any vpn connection from Windows, OSX, or iOS systems.

Anyway, here are the steps for installing and configuring pptpd:

1. Install pptpd

sudo apt-get install pptpd

2. Configure your IP

sudo vi /etc/pptpd

(Use nano if you are not familiar with vi/vim)

At the last two bottom lines, pptpd would already have configured localip and remoteip according to your system. If not, you should modify it.

For example, if your server’s IP is 192.168.0.20, then you may configure as follows:

localip 192.168.0.20
remoteip 192.168.0.230-239

It will make pptpd to use server ip address as 192.168.0.20 while vpn clients that access to this server will use remove ip range from 192.168.0.230 – 192.168.0.239. It also means, you will allow only 10 multiple vpn client connections at a time. You can increase it if you want, but make sure remoteip range doesn’t overlap with localip.

3. Configure ppp options

In your /etc/pptpd/conf file, there may be options file location. It probably will be /etc/ppp/pptpd-options. Let’s open it and make sure we have right encryption level.

sudo vi /etc/ppp/pptpd-options

Do not allow pap, chap, and mschap.

refuse-pap
refuse-chap
refuse-mschap

Allow ms-chapv2 (which is more secure) and mppe-128.

require-mschap-v2
require-mpp3-128

I think those are already default option. If so, you don’t need to make any change.

Also, you need to configure DNS.  Check /etc/resolve.conf if your server already have configured DNS. If that address is 22.22.22.22 and 22.22.22.23 configure ms-dns as

ms-dns 22.22.22.22
ms-dns 22.22.22.23

Otherwise you may use Google’s DNS server.

ms-dns 8.8.8.8
ms-dns 8.8.4.4

4. Configure account for user

Lastly, you should configure user account for the VPN connection.

sudo vi /etc/ppp/chap-secrets

And add

testuser pptpd testpassword *

Then you may be able to connect to VPN with ID=testuser PW=testpassword.

Note that if you use special characters like “#” in the password, that will cause trouble. I recommend to use just alphanumeric for your password. Also, make sure your chap-secrets file in unix CRLF format. (I spent couple of hours to find the problem that pptpd didn’t let me log in–it was due to chap-secrets file)

5. Restart pptpd

You can simply

sudo server pptpd start

to start the pptpd server or

sudo server pptpd restart

to restart pptpd.

6. Check what’s going on with syslog

If VPN doesn’t work, you may want to check out what’s going on under the hood. All the message will be recorded through syslog. So

sudo tail -f /var/log/messages

will show you any log associated with pptpd.

I hope this helps whom wants to run VPN server on Ubuntu.

Cheers,

문제로 풀어보는 알고리즘 0.3 생각해보기 풀이 – Ruby version

연구실에서 실험 중에 facebook 에 링크가 하나 올라왔길래 풀어봅니다. ㅎㅎ 자꾸 딴 짓 하면 안되는데…;;

원본 문제는 http://www.insightbook.co.kr/post/3814 에 게제되어 있습니다.

배열 arr[]과 위치 s, t가 있을 때,
arr[s], arr[s+1], … , arr[t-1]을 오른쪽으로 한 칸씩 이동하고,
arr[t]는 arr[s]로 복사하는 것을 ’1만큼 오른쪽으로 회전시켰다’고 한다.

예를 들어 길이가 8인 배열에서 s=2, t=6이면 다음 그림처럼 바뀐다.

길이가 n인 배열의 위치는 0, 1, 2, … , n-1이다.

문제 :
k를 인자로 받아서 k만큼 오른쪽으로 회전시키는 함수를 작성하라.
단, 1만큼 오른쪽으로 이동시키는 과정을 k번 반복해서는 안 된다.

조건 1 : 작성하는 언어에는 제한이 없습니다.
조건 2 : 답안으로 작성하신 글 제목에는 ‘문제로 풀어보는 알고리즘 0.3 생각해보기 풀이’라는 문장이 들어가야 합니다. (저희 블로그에도 트랙백을 걸어주세요.)

(주의: 이 코딩 인터뷰는 인사이트 입사와는 무관합니다. ㅡㅁㅡ /)

shift(array, k)를 어떻게 구현하냐는 것인데요,

일반적으로 생각하기 쉬운 알고리즘은 2가지 정도가 있습니다.

첫째는 array를 하나 더 만들어서 각 element를 새로운 배열의 (element+k) MOD n 위치로 복사하는 방법이 있습니다. 가장 일반적인 방법이지만, 창의적이지는 않지요.

둘째는, 해답이라기 보다도 트릭이겠지만, 위의 (element_k) MOD n 을 함수처럼 제공하는 방법이 있습니다. 즉 shift(array, k, i)를 억세스하면 shift 된 array를 반환시키는 방법이죠. 하지만 이것은 문제에서 요구하는 방법은 아니니까 패스…

스크립팅 언어를 사용하면 코딩량을 줄일 수 있는 다른 괜찮은 트릭이 나오겠지만, 문제에서 코딩량 보다는 O(n) 알고리즘을 어떻게 효율적으로 구현하느냐의 트릭을 요구하는 것 같아서 한 번 reverse 를 3번 구현해서 shift를 구현하는 방법을 사용해 보았습니다. 예전 고등학생 때 올림피아드 준비하면서 알아뒀던 알고리즘인데, 여기서 다시 볼 줄은 몰랐네요. ㅎㅎ

ruby 로 된 답을 한번 제시해봅니다.

#!/usr/bin/ruby

# Reverse the array
def rev(a,s,e)
    for i in 0..(e-s-1)/2 do
        tmp=a[s+i]
        a[s+i]=a[e-i]
        a[e-i]=tmp
    end
end

# Shift the array with size of k with three reverses
def func(a,k)
    rev(a,0,a.length-1)
    rev(a,0,k-1)
    rev(a,k,a.length-1)
end

arr = Array.new
arr = [1, 2, 3, 4, 5, 6]

puts "Original = " + arr.inspect

func(arr,3)

puts "Shifted  = " + arr.inspect

rev()를 3번 이용해서 Shift 시키게 됩니다. rev()는 주어진 array의 주어진 범위 내에 있는 원소들의 위치를 반대 방향으로 만들어주는 함수입니다.

하나씩 뜯어보면

    rev(a,0,a.length-1)

를 실행하면

a = [6, 5, 4, 3, 2, 1]

이 됩니다. 그 상태에서

    rev(a,0,k-1)

를 실행하면

a = [4, 5, 6, 3, 2, 1]

이 되고, 마지막으로

    rev(a,k,a.length-1)

를 실행하면

a = [4, 5, 6, 1, 2, 3]

이 되어서 shift 연산을 완료하게 됩니다.

실제로 shift를 구현할 때 위 방법이 많이 쓰이는지는 모르겠군요. 메모리 가격이 중요했던 예전에는 array 하나로 해결할 수 있는 저런 알고리즘이 각광을 받았는데, 요즘은 뭐… 그냥 알아보기 쉬운 코드가 제일이 아닌가 싶습니다.

array가 정수라고 가정해서 덧셈을 이용한 swap을 하면 tmp 변수도 필요없이 swap 하는 트릭도 있습니다만, 대신 속도가 느려서 요즘은 쓸 일 없겠죠.

내가 사용하는 bash prompt

bash prompt 를 어떻게 꾸미느냐는 사람 취향에 따라 다르겠지만, 나는 아래와 같이 사용한다.

PS1=”\n\[\e[30;1m\](\`if [ \$? = 0 ]; then echo \[\e[32m\]^_^\[\e[0m\]; else echo \[\e[31m\]O_O\[\e[0m\]; fi\`\[\e[30;1m\])-(\[\e[37;1m\]\u@\h\[\e[30;1m\])-(\[\e[37;1m\]jobs:\j\[\e[30;1m\])-(\[\e[37;1m\]cpus:\`ps u | grep `whoami` | awk ‘{ SUM += \$3 } END {print SUM}’\`%\[\e[30;1m\])-(\[\e[33;1m\]\w\[\e[30;1m\])\n(\[\[\e[37;1m\]! \!\[\e[30;1m\])-> \[\e[0m\]”

이하는 스크린샷:

사용자 삽입 이미지2개의 라인에 걸쳐 이전 커맨드의 성공 여부, 자신의 whoami 및 hostname, job 개수, cpu 점유율, 그리고 현재 디렉토리를 차례로 표시하기 때문에 보다 편하게 사용할 수 있다. 짧은 프롬프트를 원하는 분들에게는 비추.

다른 괜찮은 bash prompt 를 참조하려면 아래 사이트를 방문하면 된다:

http://maketecheasier.com/8-useful-and-interesting-bash-prompts/2009/09/04

Ubuntu 10.04에 AWstats 설치하기

아파치 웹로그를 분석하는 툴로 가장 많이 알려진 것이 webalizer입니다.

webalizer보다도 좀 더 강력한 분석 결과를 제공하는 것이 AWstats 인데, 이를 우분투에 설치하는 방법입니다. 다음의 문서를 참조하였습니다. : http://ubuntu-tutorials.com/2008/01/16/configuring-awstats-on-ubuntu-server/

1. 패키지 설치

다음 명령어로 먼저 awstats를 설치합니다.

sudo apt-get install awstats libgeoip1 libgeoip-dev libgeo-ip-perl

2. conf 파일 수정

각 virtual host 별로 conf 파일을 만들어주어야 합니다. host 명을 domain.tld 라고 하면, 다음과 같은 형식으로 새로 config 파일을 하나 생성해줍니다. 저의 경우에는 localhost로 명명했습니다.

sudo cp /etc/awstats/awstats.conf /etc/awstat/awstats.domain.tld.conf

그리고 생성된 파일을 수정합니다.

sudo vi /etc/awstats/awstats.domain.tld.conf

이 때 수정할 항목으로는

  • LogFile=”/var/log/apache2/access.log”
  • LogFormat=1
  • SiteDomain=”domain.tld”
  • HostAliases=”www.domain.tld localhost 127.0.0.1″

위와 같은 것들이 있습니다.

추가적으로 GeoCity 정보를 이용하기 위해서는 다음과 같이 데이터파일을 직접 다운받아 설치합니다.

wget
http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz  (위의 줄까지 한 줄입니다)
gzip -d GeoLiteCity.dat.gz
sudo mv GeoLiteCity.dat /usr/share/GeoIP

또한 GeoIP를 활성화 시키기 위해서 다음 라인을 활성화 시켜고, GeoIP.dat 파일 경로를 적어줍니다.

  • DNSLookup=0
  • LoadPlugin=”geoip GEOIP_STANDARD /usr/share/GeoIP/GeoIP.dat”

추가적으로 GeoCity 정보를 활성화하려면 아래 라인을 활성화시켜줍니다.

  • LoadPlugin=”geoip GEOIP_STANDARD /usr/share/GeoIP/GeoLiteCity.dat”

3. apache 설정

저의 경우에는 다음과 같이 awstats.conf 파일을 새로 하나 만들었습니다.

sudo vi /etc/apache2/conf.d/awstats.conf

파일 내용은 다음과 같습니다.

Alias /awstatsclasses “/usr/share/awstats/lib/”
Alias /awstats-icon/ “/usr/share/awstats/icon/”
Alias /awstatscss “/usr/share/doc/awstats/examples/css”
ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
ScriptAlias /awstats/ /usr/lib/cgi-bin/
Options ExecCGI -MultiViews +SymLinksIfOwnerMatch

저장하고, apache를 재시작합니다.

sudo /etc/init.d/apache2 restart

4. 과거 로그 파일 처리하기

저의 경우에는 logrotate가 설치되어 있기에, 과거 gz로 압축된 로그들을 처리해야 했습니다. 다음과 같은 명령어를 통해 간단하게 과거의 로그들을 하나로 통합해서 분석할 수 있습니다.

이 때 주의할 점은, awstats는 가장 마지막으로 parse된 파일 이후의 것만 처리하기 때문에 과거 로그를 먼저 import 한 다음에 최신 로그를 처리해야 한다는 것입니다. 즉 4번 단계를 먼저 하고 5번 단계를 하시면 되며, 과거 쌓인 내역이 없거나 분석하기 원치 않으시는 경우에는 바로 5번 단계로 넘어가시면 됩니다.

cd /var/log/apache2
gzip -d access.log.*.gz
sudo /usr/share/doc/awstats/examples/logresolvemerge.pl access.log.* >> access_combined.log
sudo /usr/lib/cgi-bin/awstats.pl -config=localhost -LogFile=”/var/log/apache2/access_combined.log”

아마 초기 업데이트에는 많은 시간이 소요될 것입니다.

5. 업데이트

최근 로그(access.log)는 아래와 같은 명령어를 통해 업데이트 가능합니다.

sudo /usr/lib/cgi-bin/awstats.pl -config=domain.tld -update

이를 아래와 같이 crontab 에 등록시켜두면 매 시간마다 자동으로 로그를 바탕으로 업데이트하게 됩니다.

6. cron에 등록

sudo crontab -e

그리고 아래 내용을 등록합니다.

0 * * * * /usr/lib/cgi-bin/awstats.pl -config=domain.tld -update >/dev/null

7. 확인

위와 같이 모든 셋업 과정이 끝납니다. 웹브라우저에서 아래 주소로 접속하면 됩니다.

http://domain.tld/awstats/awstats.pl

저의 경우에는 도메인 이름을 localhost로 등록해서, 아래와 같이 접속해야 했습니다.

http://domain.tld/awstats/awstats.pl?config=localhost

네이버캐스트 클래식 팟캐스트 (podcast)

안녕하세요,

네이버캐스트 클래식을 즐겨듣는데, 매번 접속해서 듣기가 좀 불편해서 Podcast 서비스를 만들어보았습니다.

itunes 를 켜시고 메뉴의 “고급” > “Podcast 등록” 에서 아래 주소를 붙여넣으시면 됩니다.

http://tools.sunghwanyoo.com/naver_classic/podcast_naver_classic.php

15일이 지나면 1분 듣기로 자동 전환되니 참고하시기 바랍니다. ^^

그럼..

[Greasemonkey] 파일딕에서 클럽박스 검색시 클럽명 보여주는 스크립트

요즘 클럽서치가 더 이상 릴리즈되지 않는 관계로 파일딕(filedic.com)에서 클럽박스 파일을 검색하는 일이 많아졌습니다.

이 때 각 파일에 대한 클럽명이 표시되지 않아 파일을 그냥 다운받아도 되는지, 박스 가입하고 받아야 하는지 알 수 없는 경우가 많은데요,

이를 위해 다음과 같이 각 클럽 링크 옆에 클럽명을 보여주는 그리스몽키 스크립트를 작성했습니다.

사용자 삽입 이미지

먼저 파이어폭스를 설치하시고 greasemonkey add-on 을 설치하신 다음 아래 링크를 방문하시면 됩니다.

http://userscripts.org/scripts/source/32871.user.js

그럼..^^