2014. 3. 27. 12:28

개인적인 프로젝트에 쓰려고 만든건데, 서버 구현을 WEBrick이 아니라 Sinatra로 바꾸면서 무쓸모해짐...ㅜㅜ

그래도 혹시 WEBrick을 쓰면서 동일 포트로 웹소켓을 쓰고 싶은 사람이 있다면 참고해주시길.

websocket 젬을 사용해서 WebSocket을 구현했기 때문에 아마 호환성이 높을 것으로 생각된다.

https://github.com/gwangyi/WEBrick-WebSocket

ps. github readme파일 만드는거 어떻게 하는지 모르겠다...ㅜㅜ

'프로그래밍 > Ruby' 카테고리의 다른 글

WebSocket Servlet for WEBrick  (0) 2014.03.27
POVIS 자동화 라이브러리  (0) 2010.10.06
Fortune Delivery  (0) 2010.06.17
Ruby-GNOME2-0.19.4 for Windows  (1) 2010.04.27
ruby 동영상 플레이어 라이브러리 with DirectShow  (0) 2010.04.18
Ruby-GTK2 0.19.3 for Windows  (0) 2010.04.13
2010. 10. 6. 23:52

오래간만의 포스팅은 Povis 자동화 라이브러리이다.

이전에도 올렸었던 것 같기도 한데, 이번에 추가된 내용은 식단표를 읽어오는 내용이다.

포비스 시스템 자체가 약간 병맛나서 익스 6.0, 7.0으로밖에 들어갈 수 없기도 하지만, 더해서 올라오는 식단표도 어딘가에서 재사용하기 구려서 파싱하는 프로그램을 만들었다.

당연히 POVIS에 접속해야하므로 아이디와 비번이 있어야 긁어올 수 있다.

루비로 되어 있고, nokogiri와 net/http, open-uri 라이브러리를 필요로 한다.

아... 저 세개가 다 내 던파 캐릭 이름이군ㅋ


'프로그래밍 > Ruby' 카테고리의 다른 글

WebSocket Servlet for WEBrick  (0) 2014.03.27
POVIS 자동화 라이브러리  (0) 2010.10.06
Fortune Delivery  (0) 2010.06.17
Ruby-GNOME2-0.19.4 for Windows  (1) 2010.04.27
ruby 동영상 플레이어 라이브러리 with DirectShow  (0) 2010.04.18
Ruby-GTK2 0.19.3 for Windows  (0) 2010.04.13
2010. 6. 17. 12:32

내가 다니는 학교 POSTECH은 기숙사 학교기 때문에, 배달 음식을 시켜먹는 일이 잦다.
근데 요즘 돈도 없었고 먹을 일도 잘 없어 배달음식을 자주 안시켜먹었더니, 뭐가 맛있고 뭐가 괜찮은지 모르는 상황에 이르렀다.
그래서 랜덤으로 배달메뉴를 고르는 프로그램을 만들어야겠다는 결론에 도달했다.

루비로 짰는데, CGI로 짤려고 했더니 매번 호출때마다 파싱해 오는게 너무 느려서 standalone web server로 만들었다.

웹서버 코드는 웹서핑 해서 나온 코드를 대충 때려박아 넣었다.

핵심인 배달업체 페이지 분석에서 학교 홈페이지가 공개되면 여러모로 곤란해질듯 하여 그 부분은 X로 마스킹 했으니, 그냥 켜면 절대 돌아가지 않는다.

'프로그래밍 > Ruby' 카테고리의 다른 글

WebSocket Servlet for WEBrick  (0) 2014.03.27
POVIS 자동화 라이브러리  (0) 2010.10.06
Fortune Delivery  (0) 2010.06.17
Ruby-GNOME2-0.19.4 for Windows  (1) 2010.04.27
ruby 동영상 플레이어 라이브러리 with DirectShow  (0) 2010.04.18
Ruby-GTK2 0.19.3 for Windows  (0) 2010.04.13
2010. 4. 27. 20:44
지난번에 0.19.3 버전을 컴파일해서 올렸었는데, 그새 새 버전이 나온데다가 인스톨러로 만들어 보겠답시고 다시 삽질해보았다.

... 그러나, 인스톨러로 만드는 법은 여전히 모르겠고, 바뀐 것은 0.19.4 버전을 쓸 수 있게 되었다는 점 정도? -_-....

이번엔 컴파일 방법을 같이 첨부해 두겠다. MinGW, MSYS 등의 외계어들을 보면 두드러기가 나는 분들은 위의 파일과 GNOME2 런타임을 설치하면 사용할 수 있다. 이 런타임은 먼저 http://gladewin32.sourceforge.net/에서 Gtk+ Runtime Environment를 받아서 깐 다음 http://ftp.gnome.org/pub/gnome/binaries/win32/ 에서 필요한 라이브러리를 받아다 C:\GTK에 덮어 풀면 동작한다.

먼저 밝혀 두는 것은, 이 설치 과정은 http://d.hatena.ne.jp/luna_8bit/20090321/1237598167 문서를 참조하였다.

수정사항: CAIRO_PATH를 설정해 주지 않으면 컴파일이 되지 않는데, 까먹고 빼먹었다 -_-
  1. 컴파일을 위한 준비물
    MinGW, MSYS, GTK Development Environment, 그리고 GNOME2 환경을 구성하는 라이브러리들의dev 버전들.
    MinGW는 5.1.6 버전 인스톨러를 받아서 Current 버전들을 설치했다. MSYS는 1.0.11을 다운로드받았다. Gtk+ 2.12.9 Development Environment를 사용하였고, 각각의 라이브러리의 버전은 다음과 같다.
    poppler-dev 0.12.0-1
    poppler-data 0.4.0
    libgnomeprintui-dev 2.12.1
    libgnomeprint-dev 2.12.1
    libgnomecanvas-dev 2.30.1-1
    libgnome-dev 2.24.1-1
    libbonoboui-dev 2.24.0-1
    libbonobo-dev 2.24.0-1
    gtksourceview-dev 1.8.5
    gtksourceview-dev 2.10.0
    goocanvas-dev 0.15
    gnome-vfs-dev 2.24.1-1
    gail-dev 1.22.0
    ORBit2-dev 2.14.16-1
    GConf-dev 2.22.0-3
    이 중 poppler-dev는 dependancy 안에 들어가면 존재하고, poppler-data는 http://poppler.freedesktop.org/에서 받을 수 있다.

    시작하기 전에, msys를 띄우고
    $ export PKG_CONFIG_PATH=/c/GTK/lib/pkgconfig
    $ export PATH=/c/GTK/bin:$PATH
    을 수행시켜 환경을 준비시킨다.
  2. Compile and Install ruby
    http://ruby-lang.org/ 에서 루비 최신 버전 소스파일을 받는다. 참고로 이번에는 1.8.7 p249를 받아 컴파일했다.
    다운로드를 받으면 압축을 푼 디렉토리에서 다음을 수행해서 루비를 컴파일한다.

    $ ./configure --prefix=/ruby-gnome2-dev/dist
    $ make
    $ make install

     여기서 --prefix 옵션을 줘서, 모든 작업이 종료된 후 /ruby-gnome2-dev/dist에 ruby와 ruby-gnome2 바인딩을 위치시킬 것이다. 참고로, 여기서 ruby를 다시 컴파일 하는 이유는 루비 홈페이지에서 제공되는 루비는 Microsoft Visual C 컴파일러로 컴파일이 되어 있어서 native extension을 컴파일 할 때 같은 것을 써야만 하기 때문에, ruby-gnome2를 MinGW로 컴파일하기 위해서 ruby를 다시 컴파일하는 것이다.
  3. Compile and Install rcairo
    다음 단계는 rcairo를 컴파일하고 설치하는 것이다. http://cairographics.org/releases/에서 rcairo의 최신 버전을 다운받아 압축을 풀고, 그 디렉토리에서 다음을 수행한다.

    $ /c/ruby-gnome2-dev/dist/bin/ruby.exe extconf.rb --ruby=/c/ruby-gnome2-dev/dist/bin/ruby.exe --with-override-variables=prefix=/c/GTK
    $ make
    $ make install

     당연한 이야기이지만, 첫 번째 줄에서 줄 바꿈은 없다. 여기서 가정하고 있는 것은 C 드라이버에서 작업중이고 GTK 런타임은 C:\GTK에 설치되었다는 것이다. --with-override-variables=prefix=/c/GTK가 빠지면 이후 pkg-config가 오작동하게 되기 때문에 꼭 필요하다. 위에서는 prefix에 /c/가 없지만 여기서는 필요하다는 것에 주의할 필요가 있다.
  4. Modify Ruby-GNOME2 source code
    http://ruby-gnome2.sourceforge.jp 에서 최신의 ruby-gnome2 소스파일을 다운받는다. 여기서는 0.19.4를 이용했다.
    컴파일 에러를 방지하기 위한 수정이 두 군데 필요하고, 기능상 미비한 점을 보강하기 위한 수정이 두 군데 필요하다. 두 번째 것은 굳이 할 필요는 없지만, 해 두면 여러모로 유익하기 때문에 추가해 둔다. 참고로 참조한 문서에서 수정해야한다고 한 부분은 최신 버전에서는 모두 해결된 것으로 보인다.

    C:\GTK\include\jmorecfg.h 에서
    160행

    #ifndef XMD_H => #if !defined(XMD_H) && !defined(_BASETSD_H)
    226행
    #ifndef HAVE_BOOLEAN => #if !defined(HAVE_BOOLEAN) && !defined(_RPCNDR_H)

    다음은 유용성을 위해 추가하는 내용이다. 행 번호는 위에서부터 수정한 뒤의 파일을 기준으로 삼았다.

    ruby-gnome2-all-0.19.4\gtk\src\rbgdkdraw.c 에서
    388행 다음에 다음 9줄 삽입

    #ifdef GDK_WINDOWING_WIN32

    #include <gdk/gdkwin32.h>

    static VALUE

    gdkdraw_get_hwnd(self)

        VALUE self;

    {

        return ULONG2NUM(GDK_WINDOW_HWND(_SELF(self)));

    }

    #endif

    473행 다음에 다음 3줄 삽입
    #ifdef GDK_WINDOWING_WIN32
        rb_define_method(gdkDrawable, "hwnd", gdkdraw_get_hwnd, 0);
    #endif
    마지막으로, ruby-gnome2-all-0.19.4\gtk\src 디렉토리에서 다음 명령을 수행해 파일을 하나 만들어 둔다.

    $ ar q libruby-gtk2.a

     이걸 해 두지 않으면, 이 파일을 만들어야할 때 이 파일을 요구하는 어처구니 없는 일이 발생한다 -_-
  5. Compile and install Ruby-GNOME2
    컴파일 하기 전에 CAIRO_PATH를 설정해주어야 한다. 여기선 1.8.1을 사용한 것으로 한다.

     $ export CAIRO_PATH=/c/ruby-gnome2-dev/rcairo-1.8.1


    이제 컴파일을 시작한다. 먼저, ruby-gnome2-all-0.19.4\glib 디렉토리로 옮긴 다음 다음과 같이 make를 수행한다. 단, make install은 하지 않는다.

    $ /c/ruby-gnome2-dev/dist/bin/ruby.exe extconf.rb --ruby=/c/ruby-gnome2-dev/dist/bin/ruby.exe
    $ make

    glib이 컴파일 다 되면 이제 한 단계 위로 돌아가서 전체 대상에 대해 컴파일을 수행한다. 단, 한번에 컴파일이 완료되지 않기 때문에 make install은 하지 않는다.

    $ /c/ruby-gnome2-dev/dist/bin/ruby.exe extconf.rb --ruby=/c/ruby-gnome2-dev/dist/bin/ruby.exe

    $ make
    중간에 gnome-print, gnome-printui가 실패할텐데, 한번 수행해서 libart가 컴파일되고 나면 다시 make를 수행하고 make install으로 설치한다.

    $ make
    $ make install

     최종적으로 만들어지는 라이브러리는 다음과 같다.

    -----

    Target libraries: glib, gdkpixbuf, pango, atk, gtk, bonobo, bonoboui, gconf, gnome, gnomecanvas, gnomeprint, gnomeprintui, gnomevfs, goocanvas, gtkglext, gtksourceview, gtksourceview2, libart, libglade, poppler, rsvg

    Ignored libraries: gstreamer, gtkhtml2, gtkmozembed, libgda, panel-applet, vte

    -----

    이것은 extconf를 수행할 때 뜨는 것으로, 컴파일이 완료됐을 때는 Ignored libraries는 나오지 않는다.
  6. Distribute
    루비와 루비 바인딩 자체는 C:\ruby-gnome2-dev\dist 안에 있는 것을 그대로 배포하면 된다. 만약 기존에 설치된 루비에 라이브러리를 추가할 경우는 C:\ruby-gnome2-dev\dist\lib\ruby\site_ruby\1.8 안에 있는 모든 파일을 복사하면 된다.
    단순하게 Gtk만 사용할 경우에는 런타임을 다 설치할 것 없이, C:\GTK\bin에 들어 있는 dll들과 config로 끝나는 파일들, reconfig.bat, gdk-pixbuf-query-loaders.exe. gtk-query-immodules-2.0.exe, pango-querymodules.exe 파일을 bin 디렉토리에 복사하고, C:\GTK\lib 안의 gtk-2.0, pango 디렉토리를 lib에, C:\GTK\etc의 fonts, gtk-2.0, pango를 etc에, C:\GTK\share에 sgml, themes, xml을 복사하면 정상적으로 동작한다. 이에 관한 내용은 사실, 좀 더 찾아보고 시도한 다음에 확실하게 할 필요가 있을 듯 하다.

'프로그래밍 > Ruby' 카테고리의 다른 글

POVIS 자동화 라이브러리  (0) 2010.10.06
Fortune Delivery  (0) 2010.06.17
Ruby-GNOME2-0.19.4 for Windows  (1) 2010.04.27
ruby 동영상 플레이어 라이브러리 with DirectShow  (0) 2010.04.18
Ruby-GTK2 0.19.3 for Windows  (0) 2010.04.13
네이트온 자동 로그인  (0) 2009.12.04
  • Favicon of http://www.jaketjfleece.com/ BlogIcon jaket online 2012.11.06 19:47

    이 게시물은 웹 프로그래머와 관련된 모든 새 개인 홈 페이지의 지원에 좋은 결실이며 그들이 연구하고 연습을 수행해야합니다.

2010. 4. 18. 23:06
개인적인 프로그램 제작에 있어서 multi-platform 동영상 재생 stub을 만들어야 할 일이 생겼다.

언어는 ruby를 사용해서 어느 정도 cross platform을 구현할 것이고, UI는 맥에도 리눅스에도 심지어 윈도에도 포팅된 GTK를 쓰면 요 세 군데는 무난하게 cross platform 어플이 만들어 지기 때문에 큰 걱정을 안했다.

근데 문제는 동영상 재생이었다. Ruby-GNOME2에 포함된 Ruby/GStreamer는 기본적으로 윈도용에는 컴파일이 되지 않고, 설혹 구현된다 하더라도 윈도에서는 GStreamer 런타임이 '보통' 없는데다 쓰는 어플도 없으니 쓸데없이 파일만 커진다. 따라서, DirectShow로 구현한 동영상 재생 stub을 루비로 가져와서 쓴다면 플랫폼에 따라 GStreamer와 취사선택해서 쓸 수 있을테니 좋을 거라는 생각에 C extension을 짜봤다.

짜 보니까, 생각보다 ruby extension만들기는 간단했다 -_-... 소스파일을 첨부한다.

사용하기 전에 DSPlayer.init를 통해 CoInitialize를 호출해 주어야 하고, 다 쓰고 나면 DSPlayer.cleanup으로 CoUninitialize를 호출해 주는 것이 좋다. 참고로 GC에서 제거될 때 생성한 COM object들을 해제해주어야 하지만 구체적으로 손대기 귀찮았기 때문에 각 객체를 close 메서드로 필히 닫아 주어야 한다.

DSPlayer.new로 객체를 생성하면 DSPlayer.open으로 동영상을 열 수 있다. 여기서 주의할 점은, GTK와의 integration을 목적으로 짠 녀석이라, 패러미터로 넘어가는 파일은 utf-8로 인코딩 되어 있어야 한다.

파일을 열었으면 play, pause, stop으로 제어가 가능하고, position 속성을 조작하여 초 단위로(Float) seeking이 가능하다. duration 속성도 사용 가능하다. 마찬가지로 단위는 초다.

snapshot 함수를 사용하게 되면 현재 스냅샷을 bmp 포맷으로 찍어준다. 스트링으로 반환하는데 파일로 저장하면 bmp 파일이 된다.

다른 창에 embeding하기 위해서는 owner_id에 대상 창의 hwnd를 int 형으로 변환해서 넣어주고 재생하면 된다. left, top, width, height 속성으로 동영상 창을 조절할 수 있다.

컴파일 환경은 ruby 1.8.7 (2008-05-31 patchlevel 0) [i386-mswin32]에 Microsoft Platform SDK February 2003, Microsoft DirectX 9.0 SDK Update (Summer 2004), Microsoft Visual C++ 6.0 에서 컴파일했다. 사실 ruby가 MSVC6.0이라 더 최신의 SDK에서 컴파일이 안되는 바람에 저 구시대의 유물들을 발굴하느라 고생 좀 했다 -_-...

'프로그래밍 > Ruby' 카테고리의 다른 글

Fortune Delivery  (0) 2010.06.17
Ruby-GNOME2-0.19.4 for Windows  (1) 2010.04.27
ruby 동영상 플레이어 라이브러리 with DirectShow  (0) 2010.04.18
Ruby-GTK2 0.19.3 for Windows  (0) 2010.04.13
네이트온 자동 로그인  (0) 2009.12.04
공개 한글 폰트 다운로더  (0) 2009.11.16
2010. 4. 13. 16:13
최근에 개인적인 사정으로 인해 DirectShow와 GTK를 ruby로 건드려야 하는 일이 생겼다. 근데 다 좋은데, DShow로 비디오 재생시킬 때 GTK쪽 윈도의 HWND를 알아야 할 필요가 생겼다.

물론 DShow extension에서 창을 하나 만들고 그 창에 비디오창을 임베딩 시킨 다음 그 hwnd를 GTK로 넘겨주어도 좋지만, 앞으로의 활용을 위해서 ruby-gtk2 측에서 hwnd를 반환하도록 수정시켜봤다.

많이 수정한 것은 아니고, gtk/rbgdkdraw.c에서 387행 #endif 밑에
388 #ifdef GDK_WINDOWING_WIN32
389 #include <gdk/gdkwin32.h>
390 static VALUE
391 gdkdraw_get_hwnd(self)
392     VALUE self;
393 {
394     return ULONG2NUM(GDK_WINDOW_HWND(_SELF(self)));
395 }
396 #endif
넣어주고, 이 함수를 루비 메서드로 하기 위해서 추가한 뒤의 행번호로 472행 #endif 밑에
473 #ifdef GDK_WINDOWING_WIN32
474     rb_define_method(gdkDrawable, "hwnd", gdkdraw_get_hwnd, 0);
475 #endif
넣어주면 끝. 컴파일 가이드는 http://ruby-gnome2.sourceforge.jp/hiki.cgi?compile_mingw 이 사이트를 보고 그대로 따라했고, cairo.h를 못 찾는 문제는 Makefile에 -I 옵션을 줘서 카이로 지정해주고, 기본 헤더파일에서 INT32나 boolean 중복 선언 문제는 기본 mingw 헤더를 수정해서 패스했다.

압축파일에 있는 .rb파일은 루비가 설치된 디렉토리가 C:\ruby일 때 C:\ruby\lib\ruby\site_ruby\1.8 에 넣고, so 파일은 C:\ruby\lib\ruby\site_ruby\1.8\i386-msvcrt 에 넣으면 큰 문제 없이 동작한다.

DirectShow를 ruby에서 쓰는건, 딱히 필터나 필터그래프를 있는 그대로 래핑해서 넣진 않았고, 당장 나에게 필요한 플레이어 기능만 짜넣어서 익스텐션을 만들고 있다. 나중에 완성되면 여기다 공개하도록 하겠다.

2009. 12. 4. 19:21
네이트온은 쓰다 보면, 다른 데서 로그인하거나 해서 튕긴 경우엔 다시 로그인하기가 귀찮다. 저장된 아이디와 비밀번호를 다 날려버리기 때문이다.

피씨방 등에서 접속하는 일이 많은 일반적인 사람들 기준에서는 저렇게 날려주는게 보안상 이로울 것이다. 아무 생각도 없이 공용 피씨방에서도 자동로그인 옵션을 넣어서 로그인했다가 피싱에 이용당한다던가 하는 일이 많은, 보안 개념이라곤 개미똥꾸멍만큼도 없는 한국인에게 있어서는 정말 유용하다. 유용하긴 하다. 근데 그런 기능은 선택할 수 있게 해 주면 좋지 않을까. 나처럼 두 컴퓨터를 쓰는 경우에는 번갈아가며 로그인해야하는데 저장된 비번이 날아가대니 얼마나 불편한지 모른다. MSN을 좀 닮아주면 안될까.

푸념은 여기까지 하고, 목마른 자가 우물을 판다고 직접 프로그램을 짜 보았다. Win32 API를 써야 할테니 C나 C++을 쓰는 편이 낫겠지만, 연습도 해보고 그냥 끄적거리기엔 루비가 훨 편하니까 루비를 사용해 보았다. 사용한 것은 루비 1.8.7 patchlevel 0 i386-mswin32 버전과 win32api 젬을 사용했다.

require 'Win32API'

class NateOnAutoLogin
  @@instance = nil
  @@find_window_ex = Win32API.new 'user32', 'FindWindowExA', 'LLPP', 'L'
  @@send_message = Win32API.new 'user32', 'SendMessage', 'LLLP', 'L'
  @@get_window_text = Win32API.new 'user32', 'GetWindowTextA', 'LPL', 'L'

  WM_KEYDOWN = 256
  WM_KEYUP = 257
  WM_CHAR = 258
  WM_COMMAND = 273
  WM_GETTEXT = 13

  VK_END = 35
  VK_UP = 38

  IDC_LOGIN = 0x3f2
  IDC_OTHER_LOGIN = 0x3f6
  IDC_DO_LOGIN = 0x3f5

  class << self
    alias orig_new new

    def new
      if @@instance.nil?
        @@instance = NateOnAutoLogin.orig_new
      else
        @@instance
      end
    end

    protected :orig_new
  end

  def login(id, pass)
    local_id, host = id.split '@'

    hwnd_nateon = @@find_window_ex.call 0, 0, nil, 'NateOn'
    sub = @@find_window_ex.call hwnd_nateon, 0, nil, nil
    login_dlg = @@find_window_ex.call sub, 0, '#32770', nil

    @@send_message.call login_dlg, WM_COMMAND, IDC_OTHER_LOGIN, nil
    @@send_message.call login_dlg, WM_COMMAND, IDC_DO_LOGIN, nil

    local_id_wnd = @@find_window_ex.call login_dlg, 0, 'Edit', nil
    local_id.each_byte {|chr| @@send_message.call local_id_wnd, WM_CHAR, chr, 0}

    host_wnd_a = @@find_window_ex.call login_dlg, 0, 'ComboBox', nil
    host_wnd_b = @@find_window_ex.call login_dlg, host_wnd_a, 'ComboBox', nil

    if @@find_window_ex.call(host_wnd_a, 0, nil, nil) == 0
      host_provided_wnd = host_wnd_a
      host_manual_wnd = host_wnd_b
    else
      host_provided_wnd = host_wnd_b
      host_manual_wnd = host_wnd_a
    end

    @@send_message.call host_provided_wnd, WM_KEYDOWN, VK_END, nil
    @@send_message.call host_provided_wnd, WM_KEYUP, VK_END, nil

    @@send_message.call host_provided_wnd, WM_KEYDOWN, VK_UP, nil
    @@send_message.call host_provided_wnd, WM_KEYUP, VK_UP, nil

    host.each_byte {|chr| @@send_message.call host_manual_wnd, WM_CHAR, chr, nil }

    password_wnd = @@find_window_ex.call login_dlg, local_id_wnd, 'Edit', nil
    pass.each_byte {|chr| @@send_message.call password_wnd, WM_CHAR, chr, nil }

    @@send_message.call login_dlg, WM_COMMAND, IDC_LOGIN, nil
  end
end

윈도 구조를 Spy++로 분석한 다음, SendMessage를 써서 키를 눌러주었다. 복잡하지 않다:$

NateOnAutoLogin을 싱글톤으로 구현했는데. new 메소드로 생성되는 객체 자체가 하나만 존재하게끔 손보아 보았다.

쓰기 위해서는, NateOnAutoLogin.new.login 'gwangyi@sfc.or.kr', ';didw;tsmv' 와 같은 식으로 해 주면 로그인된다.
2009. 11. 16. 15:14
리눅스 쓰다 보면 폰트가 참 별게 없다는 생각이 많이 든다. 그래서 며칠 전에 쓸려고 공짜 폰트를 뒤져봤는데, 생각보다 공짜 - 돈을 안내는 것만 - 인 폰트가 꽤 많았다. 근데 너무 흩어져있어서 -_-;; 한번에 받을 수 있는 스크립트를 짜봤다.

짜다보니 지쳐서 뒤로 갈수록 상태가 안좋아지는 문제가 있긴 한데 -_-;; 그래도 일단 당장에 쓰는데는 문제가 없을거다.

사용한 gem은 rubyzip (ZIP 파일로 압축된 폰트를 풀 때 쓴다), archive-tar-minitar(tar.gz나 tgz파일), highline (프롬프트), open-uri (Net::HTTP로 하나하나 받으려니 귀찮아서 사용 - open 함수로 간단하게 URL을 열 수 있게 해주는 젬), hpricot(HTML 파서)가 추가로 설치해야하는 젬들이고, 나머지는 유명하거나 stdlib으로 포함되어 있으니까 패스.

소스는 첨부된 것을 참조하면 된다.

여기서 재활용이 가능한 코드는, NForgeDownloader와 TarGzDistribution, ZipDistribution 정도이다. NForgeDownloader를 mixin해 넣고 initialize_downloader로 사이트 주소와 프로젝트명을 넣으면 download 함수를 호출함으로써 최신 버전을 받을 수 있다. xxxDistribution을 mixin하면 @downloaded에 지정된 파일을 클래스 이름에 해당하는 서브디렉토리를 만들어서 그 안에 풀어주는데, 저 변수는 NForgeDownloader의 download에서 설정되기 때문에 딱히 손을 안대도 알아서 받아서 풀어주는 메서드가 생긴다. get_preferred_item 함수를 통해서 받고싶은 파일의 이름을 지정할 수 있는데, 역시 Distribution 시리즈에서 자동으로 확장자가 자기가 처리할 수 있는 것을 받도록 한다.

rb 파일은 소스파일, exe파일은 이전에 올린바 있는 rubyscript2exe로 만든 패킹된 Self Extract 프로그램이다.

2009. 10. 20. 16:25
개인적으로, ruby는 배워보니까 정말 편리해서 RoR 외의 여러 부분에서 쓰고 있다. 심지어 간단한 CGI를 만들때도 ruby를 쓰기도 하는데 -_-;;

그러다가 ruby용 GTK 바인딩을 찾아서 꽤나 전에 신나게 썼었다. 단지 좀 아쉬웠던건 그 라이브러리 공식 홈페이지에서 제공하는 windows용 installer가 0.16 버전이라 상당히 불편했었다.

근데 시간도 꽤 지났고, 이 바닥에는 정말 할일 없는 사람이 널렸기 때문에 누군가 상위버전용 인스톨러를 만들지 않았을까, 하는 기대감에 혹시 있나 찾아보았다. 역시나, 누군가 해 두었다.

컴파일 하는 방법도 찾았기에 시간 나면 한번 컴파일을 따로 해봐야겠다.

여유가 나면 번역해서 컴파일 방법을 써 봐야겠다.

'프로그래밍 > Ruby' 카테고리의 다른 글

네이트온 자동 로그인  (0) 2009.12.04
공개 한글 폰트 다운로더  (0) 2009.11.16
Ruby-GNOME2 0.18 One-Click Installer for Windows  (0) 2009.10.20
rubyscript2exe 로 ruby-gnome2를 이용한 어플 패킹하기  (0) 2009.02.02
GMemRB 공개  (0) 2009.02.01
Ruby-GD2 in WIN32  (0) 2008.12.23
2009. 2. 2. 00:58
rubyscript2exe는 ruby 스크립트를 패킹해서 하나의 실행파일로 만들어주는 아주 유용한 툴이다. ruby는 스크립트 언어기 때문에 인터프리터가 필수고, 따라서 배포할 때에 루비 인터프리터와 함께 배포되어야 하는데다가 추가적인 gem을 사용했을 경우 전부를 한번에 패킹하기는 미친듯이 귀찮아진다. 게다가 대상이 윈도이기라도 하면 정말 여러가지로 골치가 아프지 않을 수 없다. 이러한 문제들을 해결할 수 있는 것이 rubyscript2exe라는 툴이다.

현재 ruby 1.8.6 patchlevel 287 이상에서 rubyscript2exe 0.5.3은 정상적으로 동작하지 않고 있다 -_-... $0이 freeze되어 있는데 수정하려 하는 문제인 것 같다. 하지만 ruby 홈페이지에서 원클릭 인스톨러로 받을 수 있는 윈도용 ruby 1.8.6 patchlevel 111에서는 문제가 없기 때문에 윈도 환경에서의 사용에는 큰 문제가 없을 것 같다.

이 것은 gem이기 때문에 gem 명령어를 통해서 간단하게 설치할 수 있다.
# gem install rubyscript2exe
그리고 대상 스크립트를 실행파일로 변환하고 싶을 때는 간단하게
$ rubyscript2exe target.rb
라고 치면 시간이 조금 걸리면서 완료된다.

그런데 다 좋은데... ruby-gnome2를 사용한 경우 글자 렌더링 엔진을 빼먹어서 글자가 하나도 찍히지 않는 불상사가 발생하는 문제점이 있다.

이 문제는 왜 발생하냐면, rubyscript2exe는 해당 루비 스크립트를 같이 패킹된 ruby 인터프리터를 사용하여 실행시키는데 여기에 포함된 GTK 라이브러리가 동작 할 때 필요한 파일이 같이 패킹이 되지 않았기 때문에 파일을 찾을 수 없어 발생하는 문제점이다.

이를 해결하기 위해서는 원리적으론, GTK 라이브러리에서 참조하는 파일들을 같이 패킹하여 실행시 언패킹되도록 하면 된다.

ruby가 설치된 곳이 C:\ruby 라고 한다면, ruby-gnome2를 설치하면 C:\ruby\lib\GTK 에 GTK가 설치된다. 이 곳에 있는 etc, share, lib 파일이 동시 패킹 대상이 된다.

rubyscript2exe는 인자로 루비스크립트가 아닌 디렉토리를 지정하게 되면 해당 디렉토리 안에 있는 모든 파일을 자동적으로 함께 패킹함과 동시에 그 안의 init.rb를 실행시키도록 구성되어 있다. 또한, RUBYSCRIPT2EXE 모듈 내의 method를 통해 여러 정보를 얻을 수 있는데, appdir은 패킹했던 파일들이 풀려 있는 디렉토리를 지칭한다. 이 것을 통해, 같이 패킹한 자료들에 접근할 수 있게 된다. 또 is_compiled? 라는 메소드가 있어, 이 스크립트가 rubyscript2exe를 통해 실행되고 있는지 아니면 일반적인 실행인지 체크할 수 있어 이 둘을 이용해 필요한 파일들을 준비시킬 수 있다.

rubyscript2exe는 패킹된 실행파일을 실행시킬 때, 대략 다음과 같은 트리구조를 갖도록 풀린다.
(홈 디렉토리)\eee\eee.application.nnn (nnn은 숫자)
└ app: 패킹했던 파일들을 풀어둔다.
└ bin: ruby 인터프리터와 필요한 dll들을 담아둔다.
└ lib: 사용한 gem이나 같이 패킹되지 않았지만 require를 통해 로드된 다른 ruby 스크립트들이 위치한다.
필요한  파일들인 etc 디렉토리와 lib, share 디렉토리들을 적당히 같이 패킹한 다음 프로그램 도입부에서 appdir을 통해 적당히 풀어주면 필요한 설정 파일들을 접근할 수 있게 되어 정상동작으로 한 걸음을 내딛을 수 있을 것이다.

그런데, 이렇게 해 주면 테마는 적용이 되어 이쁘게 나오는데 아직 한글이 정상적으로 나오지 않는다. 개발중인 머신에서는 잘 나오지만 말이다. 여기서 속으면 안된다.

이번엔 왜 안되느냐, 바로 pango의 글자 렌더링 엔진의 설정이 틀려버렸기 때문이다. etc 안에 설정파일이 존재하는데 열어보면 왜 문제가 되는지 바로 알 수 있을 것이다. 아마 ruby-gnome2가 설치된 경로로 절대경로가 되어 렌더링 엔진 dll파일들이 적혀 있는 것을 볼 수 있을 것인데, 이 것을 업데이트할 때는 pango-querymodules라는 유틸리티를 쓰는 것이 편하다. 이건 GTK 설치된 디렉토리의 bin에서 찾을 수 있다.

이제 이런 것들을 반영하여 언패킹때의 코드를 넣어주면 해결! 인데, 말로만 설명하면 와닿지 않기 때문에 gmemrb 에서 사용한 init.rb를 첨부하였다. 여기는 필요한 파일을 패킹/언패킹하기 위해 tar 파일을 썼으며(압축은 어차피 rubyscript2exe에서 한번 해 주기 때문에 생략했다) tar 파일을 핸들링하기 위해 archive-tar-minitar를 사용하였다. 하지만 전반적으로 이해하는덴 어렵지 않을 것이다.

require 'rubyscript2exe'
require 'archive/tar/minitar'
require 'fileutils'
if RUBYSCRIPT2EXE.is_compiled?
  Archive::Tar::Minitar.unpack(RUBYSCRIPT2EXE.appdir + "/env.tar", RUBYSCRIPT2EXE.appdir + "/..")
  Archive::Tar::Minitar.unpack(RUBYSCRIPT2EXE.appdir + "/locale.tar", RUBYSCRIPT2EXE.exedir)
  cmd = "\"#{RUBYSCRIPT2EXE.appdir}/../bin/pango-querymodules\" > \"#{RUBYSCRIPT2EXE.appdir}/../etc/pango/pango.modules\""
  cmd = cmd.gsub(/\//, "\\") if RUBY_PLATFORM =~ /win/
  system(cmd)
end

require 'gmemrb.rb'

GMemRB::GMemRB.new.show_all
Gtk.main

if RUBYSCRIPT2EXE.is_compiled?
  FileUtils.rm_rf RUBYSCRIPT2EXE.exedir + "/locale"
end
중요한 부분은 RUBYSCRIPT2EXE.is_compiled?로 묶여진 if 블록이다.

gmemrb의 경우 gettext를 쓰기 때문에 locale이 필요해서 실행파일이 위치한 곳에는 locale을 풀고 언패킹된 곳에는 gtk를 풀도록 되어 있다. 또한 pango-querymodules를 system 명령을 통해 실행시켜 그 결과를 바로 etc/pango/pango.modules 에 쓰도록 해서 위치를 업데이트하도록 되어 있다.

아마 저걸 참고로 해서 직접 작성해보면 가장 적절하게 느껴지는 형태로 쓸 수 있지 않을까 싶다.

rubyscript2exe 공식 홈페이지

'프로그래밍 > Ruby' 카테고리의 다른 글

공개 한글 폰트 다운로더  (0) 2009.11.16
Ruby-GNOME2 0.18 One-Click Installer for Windows  (0) 2009.10.20
rubyscript2exe 로 ruby-gnome2를 이용한 어플 패킹하기  (0) 2009.02.02
GMemRB 공개  (0) 2009.02.01
Ruby-GD2 in WIN32  (0) 2008.12.23
Ruby-GNOME2  (0) 2008.12.09