나의 AutoHotKey 설정

기술과 생활 블로그 Lifehacker에서 처음 보고 윈도우용 매크로 중심 스크립트 언어인 오토핫키 (AutoHotKey)를 사용하기 시작했는데, 덕분에 키보드 사용이 편해졌다. Caps Lock 글쇠를 Ctrl로 만드니까 손이 한결 편하고, 윈도우+W로 워드프로세서를 켠다든가, 윈도우+N으로 노트패드++를 켠다든가 하는 단축도 한결 시간을 절약해준다. 뭐 고수들이 하는 활용에는 명함도 못 내밀겠고 주로 단축글쇠를 사용하고 있지만, 그것만으로도 컴퓨터를 사용하는 시간이 쾌적해졌다. 앞으로 기능을 알아가면서 더욱 편리하게 사용할 수 있을 것 같다.

우선 오토핫키를 사용하려면 설치를 해야 한다. 사이트에서 받아다가 (AutoHotKey_L이면 된다) 설치하고, 단축 글쇠를 편하게 사용하려면 시작 프로그램으로 설정한다. 시작 버튼에 우클릭을 하고 프로그램 -> 시작 프로그램에 들어가서 오토핫키 단축 아이콘을 복사해넣으면 된다. 아니면 시작 버튼을 누르고 시작 메뉴에서 오토핫키 단축 아이콘을 시작 프로그램 폴더에다 끌어다 놓아도 되고.

시작프로그램에 오토핫키 아이콘

이렇게


오토핫키 스크립트는 .ahk 확장명 텍스트 파일이다. 처음 시작하면 내 문서 폴더에다가 AutoHotKey.ahk 스크립트를 만드는데, 난 이 스크립트 파일 하나로 쭉 사용해오고 있다. 이 파일에다가 원하는 매크로를 지정해주면 된다. 자세한 사용법은 한국 사용자그룹에서 번역한 기본 설명이나 원래 사이트의 다른 자료를 참조하면 되지만, 기본 형식은 이렇다.

글쇠::효과

이 기본 문구를 이용해 글쇠 기능을 바꿀 수도 있고, 실행 단축 글쇠를 설정할 수도 있는 등 굉장히 다양한 효과를 낼 수 있다. 위에 얘기한 Caps Lock -> Ctrl 변환은 라이프해커에서 보고 따라한 것인데, 보다시피 아주 간단하다.

Capslock::Control

앞부분은 대문자 고정을 눌렀을 때 나는 효과라는 것을 알려주는 것이고, 뒷부분은 컨트롤을 누른 것과 같은 효과를 내라고 지정해준다. 이렇게 하면 컨트롤 글쇠 대신에 대문자 고정 글쇠를 사용해서 새끼손가락이 편해진다.

그렇다고 대문자 글쇠가 아예 없어지는 건 좀 서운하니까 역시 라이프해커에서 본 대로 Shift+Capslock으로 기존의 Capslock 효과를 내게 해두었다. 즉 다음과 같이 지정하면 된다.

+Capslock::Capslock
Capslock::Control

짐작했는지 모르겠지만 +는 시프트를 줄여서 표현한 것이다. 즉 위의 명령을 해석해보면 Shift와 Capslock -> Capslock이며, 그냥 Capslock -> Control 이 된다.

이렇게 글쇠 기능을 바꾸는 것은 글쇠 조합에도 마찬가지로 적용할 수 있다. 예를 들어 작업창을 전환하는 Alt와 Tab 단축키를 나는 오토핫키 사이트에서 발상을 얻어 다음과 같이 확장했다.

LAlt & CapsLock::AltTab
LShift & Tab::ShiftAltTab
RShift & Enter::AltTab
RShift & Backspace::ShiftAltTab

이 역시 읽어만 봐도 대충 짐작이 갈 것이다. 왼쪽 Alt + Capslock과 오른쪽 Shift + Enter는 Alt + Tab이고, 왼쪽 Shift + Tab와 오른쪽 Shift + BackSpace는 순서가 거꾸로 가는 Shift + Alt + Tab 이다.

이와 같이 스크립트를 고친 다음에는 작업줄에 있는 오토핫키 아이콘을 오른쪽 클릭해서 Reload Script를 선택하면 된다. (현재 돌리고 있는 스크립트를 편집하려면 Edit Script) 혹시 오류가 있으면 어느 줄에 오류가 났는지 알려주므로 디버깅하기도 쉽다.

또 하나 많이 사용한 기능은 프로그램 실행 단축 글쇠이다. 위에 얘기한 윈도우 + W를 눌러 워드프로세서를 실행시키는 명령은 다음과 같다.

#w::Run, %A_ProgramFiles%\Microsoft Office\Office12\WINWORD

#는 윈도우 글쇠의 줄임표이며, A_ProgramFiles는 프로그램 폴더 변수인데 일반적으로 C:\Program Files와 일치한다. 앞뒤에 % 표시를 붙인 것은 문자열 속에서 변수를 구분하는 표시이다.

노트패드++를 바로 실행시키는 명령어는 다음과 같다. (필자는 윈도우 기본 메모장을 노트패드++로 대체했으므로 메모장을 실행시키는 명령과 같다.)

#n::Run, %A_WinDir%\notepad.exe

A_WinDir는 윈도우 폴더로, 보통 C:\Windows이다.

폴더를 여는 것도 마찬가지로 실행 명령으로 할 수 있다.

#m::Run, %A_MyDocuments%

A_MyDocuments 역시 기본 변수인데, 짐작하겠지만 내 문서 폴더를 가리킨다.

바탕 화면에서 휴지통을 비롯해 아이콘을 모두 없애버린지라 휴지통을 비우는 것도 단축 글쇠로 처리한다.

#x::
FileRecycleEmpty, C:\
MsgBox, 쓰레기통을 비웠습니다.
return

이렇게 하면 휴지통을 비운 다음에 다음과 같은 알림 상자를 띄운다.

오토핫키 알림상자

확인 누르고 싶지!


마지막으로 내가 많이 쓰는 것은 창을 조작하는 명령이다. 역시 대단한 건 없고 그냥 현재 창을 조작하는 수준이다. 나는 작업줄을 화면 위에 감추어 둔지라 창을 줄이거나 크기를 바꾸려고 포인터를 화면 위로 가져가면 작업줄이 튀어나오는 일이 있어서 단축 글쇠는 더욱 필요한 기능이었다.

특히 번역을 한다거나 기타 두 개 파일을 가지고 작업할 때 창 하나는 모니터 상단 절반을 차지하게 하고 다른 하나는 모니터 하단 절반을 차지하게 해서 두 파일이 화면 위아래를 반씩 가득 채우는 것을 단축 글쇠로 하고 싶었다. 이 효과를 구현하면서 3가지 방법을 차례대로 시도했는데, 오토핫키 변수를 생각해볼 기회이기도 하니 하나씩 설명하겠다.

^!a::WinMove, A, , 0, 0, 1366, 384
^!s::WinMove, A, , 0, 384, 1366, 384

이것이 가장 단순한 방법이다. ^는 Ctrl, !는 Alt, WinMove는 창 이동과 크기 변경 명령이다. 그 다음은 창의 아이디를 넣는 부분인데 A는 현재 창을 가리키며, 그 다음에 공란으로 둔 부분은 창 제목, 그 다음 두 개의 숫자는 각자 창 왼쪽 위 모서리의 X와 Y값, 그 다음 두 숫자는 창의 너비와 높이이다. Ctrl + Alt + A를 누르면 현재 창이 화면의 상단 절반을 차지하고, Ctrl + Alt + S를 누르면 하단 절반을 차지한다.

보다시피 모든 숫자는 고정값, 그리고 필자 본인의 모니터 해상도 (1366 * 768)와 작업 해상도 (작업줄을 숨기므로 화면 전체로 작업)에 맞춘 수이다. 그 결과 해상도나 작업줄 설정이 달라지면 무리가 생긴다. 예를 들어 1024 * 768 해상도로 맞추면 창이 화면보다 넓어지며, 작업줄이 보이도록 설정하면 창 일부가 작업줄 밑으로 들어가 버린다.

해상도나 설정이 달라져도 적용하도록 만들 수는 없을까 생각해서 도움말 파일 변수 부분에서 A_ScreenWidth와 A_ScreenHeight 변수를 찾았다. 이는 화면 가로와 세로 해상도를 픽셀수로 표현한 시스템 변수이다. 그래서 고정값 대신 변수를 넣어 다음과 같이 고쳐보았다. (위 %를 넣지 않은 것은 문자열로 사용하는 것이 아니라서 그렇다. 알림창 같은 곳에 표시하려면 역시 %A_ScreenWidth% 하는 식으로 처리하면 된다.)

^!a::WinMove, A, , 0, 0, A_ScreenWidth, A_ScreenHeight /2
^!s::WinMove, A, , 0, A_ScreenHeight /2, A_ScreenWidth, A_ScreenHeight /2

현재 설정으로 A_ScreenWidth는 1366, A_ScreenHeight는 768이므로 위의 고정값 방식과 같은 결과이기는 하지만, 해상도를 바꾸어도 여전히 같은 효과가 난다는 점에서 좀 더 역동적이다.

하지만 도움말을 좀 더 읽어보니, 불행히도 A_ScreenWidth와 A_ScreenHeight는 화면 전체 해상도이지 작업 영역 해상도가 아니었다. 위 명령은 화면 전체를 사용하는 것을 상정하고 있으므로 작업줄을 숨기지 않도록 설정하면 역시 창이 작업줄 밑으로 들어가는 결과를 낳을 것이었다.

그래서 도움말 파일 링크를 따라가서 SysGet 명령을 찾아냈다. 하위 명령에 따라서는 작업줄 등의 설정도 반영해서 작업 영역을 알아낼 수 있는 명령이다. 즉, 하위 명령을 MonitorWorkArea로 해서

SysGet, 변수명, MonitorWorkArea

를 구하면 작업 영역 변수를 내서 변수명Left는 작업 구역 왼쪽 위 모서리의 X값, 변수명Top은 왼쪽 위 모서리의 Y값, 변수명Right는 작업 구역 오른쪽 아래 모서리의 X값, 변수명Bottom은 오른쪽 아래 모서리의 Y값을 내준다. 이 변수 설정 기능을 이용해서 단축 글쇠를 다음과 같이 변경했다.

^!a::
SysGet, Mon1, MonitorWorkArea
WinMove, A, , Mon1Left, Mon1Top, Mon1Right, (Mon1Bottom - Mon1Top) /2
return

^!s::
SysGet, Mon1, MonitorWorkArea
WinMove, A, , Mon1Left, (Mon1Bottom + Mon1Top) /2, Mon1Right, (Mon1Bottom - Mon1Top) /2
return

(여러 줄짜리 명령을 할 때면 저 return을 잊어서는 안 된다. 저걸 빼먹으면 다음 매크로까지 실행을 해서 피본다(..))

일견 복잡해지기는 했지만 논리적으로 생각하면 얼추 알 수 있다. Mon1은 모니터 속에서 작업 영역 좌표를 나타내는변수이다. 따라서 Ctrl+Alt+A를 하면 현재 창의 위치와 크기를 바꾸는데, 작업줄을 뺀 작업 영역의 왼쪽 위 꼭대기에서 시작해 가로는 작업 영역의 가로 길이와 같고, 세로는 작업 영역 세로 길이의 반인 창이 된다. 마찬가지로 Ctrl+Alt+S를 하면 작업 영역 왼쪽 가운데에서 시작해 가로는 작업 영역의 가로와 같고, 세로는 작업 영역 세로 길이의 반이 창이 된다. 해상도가 어떻든, 작업줄을 숨기든 보이든 마찬가지다. (모니터가 여러 대이면 문제가 될 수 있지만, 설명하기 귀찮으니 넘어간다.)

두 개의 창으로 모니터를 양분한 모습

이런 결과가 된다


여기서 더 나아가 하나의 단축 글쇠로 여러 창을 한꺼번에 움직일 수도 있고 화면 3등분, 4등분, 여러 모니터에 걸친 디스플레이 등 아주 다양한 설정을 할 수 있다. 일단은 소박한 단축 글쇠로 만족하지만, 차차 알아가면서 이 단순하면서도 강력한 스크립트로 더욱 편리한 컴퓨터 생활을 하고 싶어진다.

필요한 분이 있다면 보시라고 오토핫키 스크립트 파일을 공개한다. 각자 프로그램은 다르니까 그대로 적용은 안 되겠지만, 스크립트가 전부 단순해서 부담없이 한 번 분석해볼 여지는 있다. (혹은 보고 비웃거나(..))

2010/12/22 23:56 2010/12/22 23:56
로키
분류없음 2010/12/22 23:56

트랙백 주소 : http://lokasenna.pe.kr/blog/trackback/431

  1. 단축키 종결자 오토핫키 (AutoHotKey) tracked from 월풍도원(月風道院) - Delight on the Simple Life 2011/12/09 19:07  삭제

    강력한 단축키 메크로를 제공하는 무료 소프트웨어 오토핫키!단축키 종결자 오토핫키(AutoHotKey) 단축키용 소프트웨어로 HotKeyz를 오랫동안 이용했습니다. 윈도우에서 자주 쓰는 프로그램을 단축키로 등록해 놓고 쓰면 참 편했죠.문장을 자동 완성하는 핫스트링 기능이 있으면, 더 편하겠다 싶어,Phrase Express도 설치해 사용했습니다.&l...

댓글을 달아 주세요

텍스트큐브 RSS 리더 1.1.2 (2009/11/27)

RSS, Atom 등 피드를 읽어와서 사이드바 혹은 치환자 위치에 보여주는 플러그인입니다. 치환자 방식으로 사용할 때 치환자명은 [##_SimplePie_RSS_##] 입니다. 구버전은 언제나처럼 버전 관리글에 있습니다.

버전 1.1.2

최신 변경사항
- 피드 그룹을 사용할 때 발생하는 오류를 바로잡았습니다.
- 설정창을 정리하고 치환자 설명을 보강하고 수정하였습니다.

호환성과 버그 보고

이 플러그인은 SimplePie 파서에 의존하므로 심플파이 사용 환경이 되지 않으면 사용할 수 없습니다. 왠만한 현대적인 호스팅은 다 됩니다만, 확인하려면 플러그인 경로/sp.php로 들어가면 됩니다. 예를 들어 mydomain.com의 blog 폴더에 태터를 설치하셨다면

http://mydomain.com/blog/plugins/Loki_SimplePieRSS/sp.php

가 호환성 확인 페이지 주소입니다.

플러그인이 작동하지 않으면 먼저 위의 호환성 테스트를 해보시고, 호환이 된다면 디버그 모드로 들어가서 에러 메시지를 확인하시고 이상 증상과 함께 에러 메시지를 알려주시기 바랍니다.

사용 예시


사용 예시를 두 가지 제시하면 다음과 같습니다.

첫 번째는 아주 단순하게 1번 그룹에 모든 피드를 넣고 시간 역순대로 보여주는 형태입니다. 아이템 제목 길이는 9자로 축약하고, 제목 위에 마우스를 가져다 대면 원래 길이의 제목이 보이게 했습니다. 스킨은 설레는 마음 (핑크)입니다.

1번 예시

예시 1


<div class="feed">
<h3>피드</h3>

<ul>
<item>
<li> <a href="[##_item_permalink_##]" title="[##_item_title_full_##]">[##_item_title_##]<br />
<span class="name">[##_feed_title_##]</span>
<span class="date">[##_item_date_or_time_##]</span></a>
</li>
</item>
</ul>
</div>

설레는 마음 스킨은 메뉴 첫머리에 이미지를 사용하므로 "Recent Feed" 이미지 (RecentFeed.gif)를 만들어서 skin/customize/1/images 폴더에 넣고, 스킨 편집으로 들어가서 스타일 시트에 다음 줄을 추가했습니다.

.sideinfo .feed h3 { background:url(images/RecentFeed.gif);}

두 번째 예시는 피드 그룹을 블로그 피드와 트위터 피드 2개 설정해서 함께 보여주는 방식입니다. 사용 스킨은 O-range-O입니다.

사용자 삽입 이미지
<!-- recent feeds -->
        <group>
                <div id="[##_group_id_##]" class="listbox">
                    <h3>[##_group_name_##]</h3>
                    <ul><item>
                        <li>
                            <a href="[##_item_permalink_##]" title="[##_item_title_full_##]">[##_item_title_##]</a><br />
                            <span class="date">[##_item_date_or_time_##]</span> <span class="name">[##_feed_title_##]</span>
                        </li>
                    </item></ul>
                </div>
      </group>
피드 그룹에 따른 반복영역을 <group></group>으로 설정한 후 그룹명 치환자를 넣었습니다. 그리고 group_id 치환자를 (group1, group2 등) 아이디로 넣어서 아이디에 따라 헤더 이미지가 들어가도록 시트를 잡아주었습니다.
#group1 h3 {
    background: transparent
    url(http://lokasenna.pe.kr/blog/skin/orangeo_orange/css/image/orange_sidebar_feeds.gif) top left no-repeat !important;
    margin-bottom:0 !important;
}

#group2 h3 {
    background: transparent
    url(http://lokasenna.pe.kr/blog/skin/orangeo_orange/css/image/orange_sidebar_tweets.gif) top left no-repeat !important;
    margin-bottom:0 !important;
}
그리고 설정창에서는 그룹 이름을 지정해서 위의 group_name 치환자 자리에 들어갈 이름을 정해주었습니다.

사용자 삽입 이미지

즐겁게 사용하시고, 문제나 질문, 칭찬(?) 등이 있으면 댓글 달아주세요~
2009/11/27 16:15 2009/11/27 16:15
로키
분류없음 2009/11/27 16:15

트랙백 주소 : http://lokasenna.pe.kr/blog/trackback/67

  1. dj furniture tracked from dj furniture 2011/12/12 18:57  삭제

    Blin classics of the genre, I laughed heartily ...

댓글을 달아 주세요

  1. kimatg 2008/01/14 13:18  수정/삭제  댓글쓰기

    혹시 텍스트큐브에서 사용 가능한가요?
    복사하고 플러그인 메뉴에서 활성화 시킨다음에 사이드바에 추가하려니까 안되네요
    간단한 RSS리더 플러그인 필요해서 뒤져보니 제대로 되는게 없는거 같네요 ㅡ,.ㅡ;;

    • 로키 2008/01/15 01:52  수정/삭제

      지금 이 블로그도 텍스트큐브인데 사용중이라 (아래 Recent Feed 메뉴) 아마 되는 것 같아요. 여기 올린 것보다는 업그레이드 버전이긴 하지만요. 조만간 제가 지금 사용하는 판으로 텍스트큐브 사이트와 이곳에 올릴 테니 그때 되는지 한 번 봐주시면 감사하겠습니다.

    • kimatg 2008/01/15 17:57  수정/삭제

      감솨합니다! (__)

    • 로키 2008/01/18 12:30  수정/삭제

      버전 1.0.0 공개했습니다. 여전히 동작하지 않으면 글에 나온 것과 같이 호환성 테스트와 디버그 모드에서 에러 메시지 확인 후 알려주세요~

    • kimatg 2008/01/19 11:33  수정/삭제

      일단 정말 감사합니다! :)
      설치할때 폴더 명에서 1.0.0 빼줘야 된다고 알려주셔야겠네요..

      그런데, 저번 버전과 같이 문제가... 사이드바에 추가할수 없다는 거네요
      설정 페이지도 다 잘 나오는데, 플러그인을 활성화 시키고 사이드바 페이지로 가면 드래그 할 수가 없네요 ㅡ,.ㅡ;; 문제가 뭔지를 모르겠습니다

    • 로키 2008/01/20 08:03  수정/삭제

      디버깅 모드와 플러그인 활성화 후 사이드바 페이지에 들어가셔서 에러 메시지가 있나 확인해주시겠어요? 하나 짐작가는 건 있습니다만..

  2. 티아 2008/01/19 15:11  수정/삭제  댓글쓰기

    안녕하세요~참 유용한 플러그인이라 관심갖고 봤습니다.
    제가 텍큐 1.6 베타2를 쓰고있거든요~
    설정은 되는거 같은데. 어라 사이드바에서 추가가 안되는 문제점이 있네요.
    호환성테스트를 하면.페이지 오류를 보이며 흰바탕이 나옵니다.~

    조금 아쉬운 부분입니다...
    그럼 좋은 주말 되십시요~

    • 로키 2008/01/20 08:07  수정/삭제

      말씀 감사합니다.^^ 저한테는 재현이 안 되는 문제라 도움이 필요할 것 같네요. 플러그인 활성화 후 디버그 모드로 사이드바 페이지를 봤을 때 에러 메시지가 뜨나 확인해주시면 감사하겠습니다.

  3. kimatg 2008/01/21 10:13  수정/삭제  댓글쓰기

    디버깅 모드 켜고 보니
    SimpleRSS 플러그인 박스안에

    Fatal error: Call to undefined function: str_ireplace() in /home/kimatg/public_html/plugins/Loki_SimplePieRSS/index.php on line 106

    라고 나오네요;;

    • 로키 2008/01/21 16:45  수정/삭제

      아, 예상대로 str_ireplace가 문제였군요. PHP 버전이 왠만하면 있을 만한 기능인데 그게 없는 호스팅이 또 있네요. 텍스트큐브 쓰시니까 PHP 버전이 많이 낮지는 않다고 가정하고 혹시 str_replace는 될까 하여 str_ireplace 대신 str_replace를 사용한 버전을 올려뒀으니 그건 되나 확인해주시겠어요?

    • kimatg 2008/01/21 20:36  수정/삭제

      으음... 귀찮게해서 참 죄송합니다만 ㅜ.ㅜ

      이제는

      Fatal error: Call to undefined function: stripos() in /home/kimatg/public_html/plugins/Loki_SimplePieRSS/index.php on line 301

      라고 나오는군요. 흠 ㅠㅠ

    • 로키 2008/01/22 00:36  수정/삭제

      귀찮긴요, 고칠 수 있으니까 좋네요. PHP 빌드가 좀 특이한 경우이신 것 같기는 하지만요. 뭔가 대소문자 구분 없는 기능에 원수진 빌드이려나요..(..) stripos를 strpos로 고쳤으니 메인 1.0.0 파일로 되나 다시 해봐주시고, 에러가 또 있다면 알려주시면 감사하겠습니다.

    • kimatg 2008/01/22 11:14  수정/삭제

      답변 감사합니다^^
      그런데 업로드해주신 파일에는 그대로 stripos라고 수정 안되어있는거같네요.. 그래서 그냥 stripos라고 나오는 부분을 다 strpos로 바꾸고 업로드해보니..!
      사이드바에 추가가 되네요.
      그런데 또다른 문제가...
      이제는 아예 메인 페이지가 뜨지를 않고

      Fatal error: Call to undefined function: htmlspecialchars_decode() in /home/kimatg/public_html/plugins/Loki_SimplePieRSS/index.php on line 490

      라고 하는 군요. 아놔 도대체 제 서버에 뭔 문제가 있는지ㅠㅠ

      덧: 아 그리고 플러그인 환경설정 페이지에서 설정 수정하고 저장하려하면 "데이터 처리 페이지를 찾을 수 없습니다" 라고 나오네요. 그리고... 또하나, "가져올 분류" 는 뭐에 쓰는건가요? -,.-;;

    • 로키 2008/01/22 21:00  수정/삭제

      아.. 아마 PHP 버전이 5가 아닌 4라서 그런 것 같네요. 찾아본 바로는 없는 기능들은 다 PHP 5에 추가된 것들이에요. 아직 버전 4를 사용하는 빌드도 있을 테니 그걸 감안해야겠군요. 일단 html_entity_decode로 고쳐서 다시 올렸습니다.

      데이터 처리 페이지 부분은 전혀 모르겠네요. 일단 에러 메시지를 다 잡아도 계속 나타나는지 보도록 하죠. '가져올 분류'는 대상 피드 중 특정 분류에 속하는 글만 가져오고 싶을 때 사용하는 것입니다. 예를 들어 어떤 블로그에 일기, 잡담, 뉴스 분류가 있는데 일기나 잡담 분류에 속한 글만 가져오려면 '가져올 분류'에는 '일기, 잡담'을 입력하는 거죠.

    • kimatg 2008/01/23 21:24  수정/삭제

      아! 이제 완벽하게 되네요
      멋진 플러그인 +애프터서비스(?) 정말 너무너무 감사드립니다!!
      그리고 수고하셨습니다^^

    • kimatg 2008/01/23 21:53  수정/삭제

      아 그런데 하나만 더 여쭤봐도 되겠습니까;;

      음.. 제 블로그는 스킨 디자인할때도 W3C XHTML/CSS 준수해서 전체 사이트가 테스트 통과하도록 노력하고 있거든요 그래서 플러그인 설치한 후에도 꼭 테스트 해보는데
      RSS 플러그인 부분에서 한부분이 걸리는거 같네요.

      제 사이트 소스를 보면
      RSS플러그인 주변 (h3태그를 "recent anime"라고 이름바꿨습니다)에
      <ol> 태그 안에
      <div id="group1" class="">
      가 붙네요... 플러그인 설정 페이지에는 보이지 않는데, 이게 걸리는거 같네요.

      뭐 플러그인 작동에는 전혀 상관없는 사소한 일이지만
      한번 체크해주시면 진~~짜 감사하겠습니다!! (_ _;;)

    • 로키 2008/01/23 23:55  수정/삭제

      그렇잖아도 고민되던 점을 짚어주셨네요. 그룹 태그를 만들기 전에 피드 그룹 관리를 자동화하려고 div를 강제했는데, 헤더 부분이랑 균형이 맞지 않아서 오히려 이해하기 어려워진 것 같아요. 그룹 하나짜리 간단한 피드 리더에는 별 필요가 없기도 하고, 말씀대로 표준화 문제도 생기고요. PHP 4랑 호환되게 고친 점이랑 전부터 고민하던 이 부분에 대한 해결까지 해서 작은 버전업을 해야겠습니다.

      아, 그리고 플러그인 활용하신 거 멋져요~ 디자인이 사이트와 잘 어울리는 점도 그렇고요. 제가 본 다른 피드 플러그인들은 특정 디자인을 이미 선택해서 사이트에 비해 튀는 게 아쉬웠는데, 사용자가 자유롭게 디자인하면 얼마나 멋진지 보니 뿌듯하네요.

    • kimatg 2008/01/24 00:22  수정/삭제

      네 감사합니다^^
      이제야 플러그인에 맞게 "약간의" 리디자인을 마쳤네요 ㅎㅎ

      다시한번 멋진 플러그인 감사드리고요, 버전업 기대하겠습니다! :)

  4. 종횡무진 2008/01/23 22:16  수정/삭제  댓글쓰기

    플러그인 제작까지 하세요? 정말 대단하세요^^

    • 로키 2008/01/23 23:57  수정/삭제

      감사합니다.^^ 취미 수준 코딩이지만 재밌게 하고 있어요.

  5. 하얀별 2009/05/02 08:58  수정/삭제  댓글쓰기

    티스토리에서 해당 기능을 사용하고 싶은데 어떻게 하면 될까요? ㅠㅠ

    • 로키 2009/05/02 11:27  수정/삭제

      아마 텍스트큐브에서만 되는 것 같아요. 플러그인을 업로드할 수 있어야 하니까요.

  6. lhovamp 2009/05/04 09:39  수정/삭제  댓글쓰기

    [엄친아/엄친딸] 없는 세상에서 살고 싶어요. [...]

    • 로키 2009/05/04 14:34  수정/삭제

      아니 왜 여기서 엄친아/딸이 나오는데! (..)

  7. 매치어 2009/11/27 12:22  수정/삭제  댓글쓰기

    뒷북이지만 이 리더 플러그인 받아서 잘 쓰고 있습니다~ textcube 설치파일에 기본으로 들어있던 리더기가 제 호스팅 환경에선 작동이 안 되어서 고민했는데 이건 잘 되네요. ^^

    • 로키 2009/11/27 16:20  수정/삭제

      뒷북 감사합니다~ 덕분에 생각이 나서 버전업을 했네요. 피드 넣으신 모습 멋집니다! 역시 디자인은 사용자가 원하는 게 최고에요.

  8. kimatg 2011/04/30 21:04  수정/삭제  댓글쓰기

    안녕하세요!
    엄청 오랜만에 찾아들어와봤습니다 /ㅅ/
    블로그가 뭔가 많이 바뀐듯 한데, 다행히 이 글은 아직 지우지 않으셨네요...

    다름이 아니라 오늘 텍큐를 드디어 1.7에서 1.8.6으로 판올림했는데, 멀쩡히 작동하던 SimplePie RSS 플러그인이 갑자기 안되더라구요 ㅠ

    아무리 설정 만져봐도 사이드바 위젯 설정 창에서 끌어다 넣을수가 없습니다. 플러그인 모듈 상자 이후로 컨텐츠가 짤리고 더이상 로드 안되는걸 보아 뭔가 문제가 있는거 같긴 한데.. 도저히 모르겠더군요.

    잠시 요 위에 있는 예전 댓글을 살펴보니.. PHP4 버전과 호환되도록 수정하신거 같은데 (그래서 이제까지 잘 써왔지만요) 막상 PHP5로 지원하는 호스팅으로 옮겨오고 나니까 작동이 안 되는걸까요?

    이 글 자체도 오래 된데다가 이런 작업 하시는거 이미 접으셨을지 잘 모르겠지만
    혹시 시간이 나신다면 좀 봐주시면 감사하겠습니다 ㅠㅠ

    • 로키 2011/05/03 21:47  수정/삭제

      우와 반갑습니다~ 오랜만이에요! 이거 그렇잖아도 메타블로그와 연계해서 데이터베이스 방식으로 판올림해야겠다고 생각하고 있었는데 귀차니즘으로 뻗어있었군요(..)

      문의 주신 문제는 디버그 모드를 켜시고 어떤 에러가 나타나는지 알려주시겠어요? 아마 말씀하신 것이 원인이 아닐까 생각하기는 하지만요.

      디버그 모드는 블로그 설치 폴더의 config.php 파일에서

      $service['debugmode'] = true;

      를 언코멘트해주시면 됩니다.

    • kimatg 2011/05/03 23:16  수정/삭제

      작업하실 생각이 있으시다니 다행이네요^^

      디버그모드 키고 꾸미기>사이드바 들어가면 페이지 상단에
      Undefined index: title(8)
      File: /home/hosting_users/zvuc/www/library/plugins.php:181

      가 뜨고

      <추가가능한 플러그인>의 SimplePie RSS 박스 내에
      Undefined variable: group_id(8)
      File: /home/hosting_users/zvuc/www/plugins/Loki_SimplePieRSS/arrays.php:39
      Undefined variable: group_id(8)
      File: /home/hosting_users/zvuc/www/plugins/Loki_SimplePieRSS/arrays.php:40
      Undefined variable: group_name(8)
      File: /home/hosting_users/zvuc/www/plugins/Loki_SimplePieRSS

      가 뜨네요

      도움이 되셨으면 하네요^^

파이썬 Tkinter에서 프로토콜 핸들러 사용

한동안 안하다가 조금씩이라도 해서 완성하자는 생각으로 코딩 프로젝트를 다시 잡았다. 그 과정에서 생긴 문제를 하나 해결해서 적어본다.

이 IRC 클라이언트를 만들면서 (가제 PRC) 처음부터 의도한 것은 기존 IRC 클라이언트보다 더 사용하기 쉽게 하자는 생각이었는데, 그 일환으로 초대 (INVITE) 이벤트도 텍스트 중심이 아닌 그래픽 인터페이스 중심으로 처리했다. 누군가에게 초대가 들어오면 그 사실만 알리는 게 아니라 초대받은 채널에 바로 입장할 수 있는 선택창을 띄우는 것.

초대받은 스크린샷

PRC에서 초대를 받았을 때 뜨는 메시지


그런데 여기서 문제가 생겼다. 어느쪽 선택지를 고르든 무조건 연결이 끊어지는 결과가 발생하는 것. 왜 그럴까 하고 소스를 뒤지다가 원인을 발견했다. 프로그램 창을 닫으면 서버 연결을 끊는 이벤트 바인딩을 넣어놓았는데, 그 바인딩을 메시지박스에서 계승하고 있던 게 문제였다. 다음은 관련 코드.

class App:

    def __init__(self, master):
        """초기 위젯 렌더링"""

        self.master = master
        #전체 창을 self.master 변수로 설정해서 같은 클래스 내 다른 함수에서도 부를 수 있게 한다

        self.master.bind("<Destroy>",self.closeWindow)
        #요 부분이 문제였다. closeWindow 함수는 연결을 끊는 함수인데 메시지박스에서 Yes를 선택하든 No를 선택하든 마찬가지로 창을 닫는 이벤트이니까 (<Destroy>) 같은 closeWindow 함수를 발동시킨다.

    #중략

    def closeWindow(self,event=None):
        """창이 닫히면 연결 끊기"""

        if self.connected:
            self.closeConnect()
            #연결이 되어 있다면 끊으라는 명령

    #후략


unbind로 바인딩을 끊으려고 해도 tkMessageBox 모듈로는 그게 좀 애매했다. tkMessageBox 모듈은 이런 식으로 불러오게 되어 있다.

        import tkMessagebox
        if tkMessageBox.askyesno(receivedInvite,askWhetherJoin):
            self.joinChannel(channel)

위젯이면 unbind를 할 수 있겠지만 위젯이 아니라 모듈로 바로 작업하는 거라서 그렇게도 할 수 없었다. 그렇다고 창을 닫을 때 동시에 서버 연결을 끊지 않으면 핑 타임아웃이 될 때까지는 같은 닉으로 재접속할 수 없으므로 사용하기 쉬운 IRC 프로그램을 만든다는 취지에도 어울리지 않았다.

그래서 검색하다가 발견한 것이 윈도우 매니져 프로토콜이었다. 창 닫는 버튼을 누른다고 바로 창을 닫는 대신 다른 이벤트를 먼저 발생시키는 이벤트라고 한다. 즉, 창을 닫으면 지정 함수를 발동시키는 게 아니라 사용자가 창을 닫는다는 명령을 내리면 함수를 발동시킨다는 미묘하면서도 중요한 차이다.

예시를 보고 바인딩 대신 프로토콜 핸들러로 바꿔본 결과는 성공. 서버 접속을 끊는 함수 바인딩이 메시지박스에 계승되지 않아서 원하는 효과를 낼 수 있었다.

class App:

   def __init__(self, master):
        """초기 위젯 렌더링"""

       self.master = master

        self.master.protocol("WM_DELETE_WINDOW",self.closeWindow)
        #바인딩 대신 프로토콜 핸들러로 바꾸었다

    #중략

   def closeWindow(self,event=None):
        """창 닫으라는 명령을 받으면 연결 끊고 창 닫기"""

       if self.connected:
           self.closeConnect()
            #연결이 되어 있다면 끊으라는 명령

        self.master.event_generate("<Destroy>")
        #그리고 창을 닫는다

    #후략


해피엔딩~ 초대받은 채널에 입장을 선택하면 자동으로 입장하고, 거절하면 입장하지 않는다. 어느 쪽이든 연결은 끊어지지 않는다. 이벤트 바인딩은 메시지 박스에 계승이 되고 프로토콜 핸들러는 안 되는 이유는 알 듯 말 듯 하면서 잘 모르겠지만(..) 어쨌든 좋은 게 좋은 거 아닌가.

자동입장한 스크린샷

접속 해제 없는 자동 입장 성공!


이런 식으로 천천히 작업하다 보면 언젠가는 완성을 볼 수 있겠지. 그러다 보면 코딩도 좀 늘어 있을까. 몇 달만에 본 소스인데도 막상 작업을 시작하니 대충 뭘 했는지 생각나는 거 보면 역시 배우는 방법 중에서는 해보는 게 으뜸인 듯 싶다.
2009/01/22 20:38 2009/01/22 20:38
로키
분류없음 2009/01/22 20:38

트랙백 주소 : http://lokasenna.pe.kr/blog/trackback/296

  1. Torture. tracked from Torture. 2011/08/19 21:20  삭제

    Torture.

  2. Viagra. tracked from Viagra. 2011/08/21 03:37  삭제

    Viagra.

  3. Ultram. tracked from Ultram. 2011/08/21 23:38  삭제

    Ultram.

  4. Zoloft. tracked from Zoloft. 2011/08/22 07:56  삭제

    Zoloft.

  5. Airfare. tracked from Cheap airfare. 2011/08/22 18:52  삭제

    Robots cheap business class airfare. Discount airfare. Cheap airfare. Cheap last minute airfare. First class first class airfare.

  6. Handjob gallery. tracked from Handjob gallery. 2011/08/23 20:57  삭제

    Handjob gallery.

  7. Free torture. tracked from Free torture. 2011/08/24 10:23  삭제

    Free torture.

  8. Diflucan. tracked from Diflucan. 2011/08/25 02:40  삭제

    Diflucan.

  9. Torture. tracked from Torture. 2011/08/25 06:25  삭제

    Torture.

  10. Torture. tracked from Torture. 2011/08/25 17:05  삭제

    Torture.

  11. Free handjob movies. tracked from Free handjob movies. 2011/08/27 09:58  삭제

    Free handjob movies.

  12. Animal sex tubes. tracked from Animal sex tubes. 2011/08/28 08:08  삭제

    Animal sex tubes.

  13. Big boobs. tracked from Big boobs. 2011/09/18 00:34  삭제

    Big boobs.

  14. Free animal sex. tracked from Free animal sex. 2011/09/18 19:10  삭제

    Free animal sex.

  15. Big tits. tracked from Big tits. 2011/09/20 10:33  삭제

    Big tits.

  16. Zoo sex. tracked from Gallery sex zoo free. 2011/09/21 03:58  삭제

    Gay zoo sex. Zoo sex sex. Zoo sex.

  17. Oxycodone. tracked from Oxycodone. 2011/09/21 12:08  삭제

    Oxycodone.

  18. Oxycodone addiction. tracked from Oxycodone addiction. 2011/09/22 03:20  삭제

    Effects of oxycodone. Oxycodone addiction. Oxycodone.

  19. Ambien. tracked from Recreational ambien. 2011/09/22 11:39  삭제

    Ambien without prescription. Buy ambien online. Ambien. Ambien addiction. Buy ambien.

  20. Anal sex advice. tracked from Anal sex. 2011/09/23 03:39  삭제

    Anal sex. Free anal sex pics.

  21. Cheap airfare. tracked from Cheap airfare. 2011/09/24 04:06  삭제

    Cheap airfare.

  22. Zoloft. tracked from Zoloft. 2011/09/25 14:26  삭제

    Zoloft.

  23. Big tits. tracked from Big tits. 2011/09/25 23:24  삭제

    Big tits.

  24. Free adult movies. tracked from Free adult movies. 2011/10/23 13:50  삭제

    Free adult movies.

  25. Free pornstars. tracked from Free pornstars. 2011/10/23 22:58  삭제

    Free pornstars.

  26. Free homemade porn. tracked from Free homemade porn. 2011/10/24 00:42  삭제

    Free homemade porn.

  27. Free naked women pictures. tracked from Naked masturbating women. 2011/10/24 12:13  삭제

    Beautiful naked women. Naked women. Naked women pictures. Free naked women. Naked women pics.

  28. Free adult movies. tracked from Free adult movies. 2011/10/25 04:13  삭제

    Free adult movies.

  29. Anal sex. tracked from Anal sex. 2011/10/25 16:32  삭제

    Free anal sex movies. Tranny anal sex. Her first anal sex. Anal sex.

  30. Silver daddies. tracked from Silver daddies. 2011/10/26 17:02  삭제

    Silver daddies.

  31. Torture tubes. tracked from Torture tubes. 2011/10/27 23:30  삭제

    Torture tubes.

  32. Free adult movies. tracked from Free adult movies. 2011/10/28 10:12  삭제

    Free adult movies. Free adult porn movies.

  33. Blowjob. tracked from Blowjob. 2011/10/29 02:23  삭제

    Blowjob.

  34. Silver daddies. tracked from Silver daddies. 2011/10/30 00:59  삭제

    Silver daddies.

  35. Www.silver daddies. tracked from Silver daddies. 2011/10/31 01:59  삭제

    Silver daddies.

  36. Silver daddies. tracked from Silver daddies. 2011/11/03 16:54  삭제

    Silver daddies.

  37. Britney spears no underwear photos. tracked from Britney spears underwear. 2011/11/04 00:44  삭제

    Brittany spears no underwear. Britney spears in her underwear. Men in underwear.

댓글을 달아 주세요

  1. lhovamp 2009/01/23 08:39  수정/삭제  댓글쓰기

    자. 어서 닭둘기를 대체해 주세요 (먼산)

    • 로키 2009/01/24 20:44  수정/삭제

      다 하면 IRC쪽은 적어도 RPG용으로는 피진보다 낫겠고, IRC 서버에서 받는 정보의 한계 때문에 이걸로 MSN을 대체하기는 힘들겠지만... 좀 재밌는 생각이 하나 떠오르긴 하네. IRC 클라이언트이지만 친구 목록과 온라인 상태를 표시할 수는 있을지도. 비록 완전 실시간은 아니겠지만 말야.

  2. 종횡무진 2009/01/24 10:53  수정/삭제  댓글쓰기

    로키님은 여전히 소스 코딩 작업에서 헤어 나오지 못하셨군요.^^
    오랜만에 들렸습니다.
    새해 인사하려구요.
    올 한해에도 건강하시고 복 많이 받으세요.^_______^

  3. orches 2009/01/29 20:40  수정/삭제  댓글쓰기

    잘 지내셨나요? 오랜만에 인사하러 들렀습니다.
    새해 복 많이 받으셔요 ^ (너무 오랜만에 드린 인사라.. 쟤 누구?.. 하실 것 같 ;ㅅ;)
    와! 소스 코팅 중이셨군요!! 막 신기신기하답니다.. ^^

    • 로키 2009/01/30 15:56  수정/삭제

      이야 오랜만입니다. 잘 지내셨는지..^^ 블로그에 업데이트도 하시고, 조금은 여유가 생기신 것 같아서 좋네요.

문자열에서 0에서 14까지의 숫자 찾아내기

IRC를 통해 주고받는 문자열 내에서 색깔 코드를 찾아내는 방법을 생각하다가 0부터 14까지의 숫자만 찾아내는 정규식 패턴을 짜봤다. (사실 이 색깔 코드도 mIRC랑 CTCP가 서로 달라서 어느 장단에 춤을 추어야 하나 고민 중. 특히 국내에서는 가장 흔한 클라이언트인 mIRC와의 호환은 꽤 유혹이 되지만, CTCP가 IRC 표준이라고 하면 그쪽에 맞추는 게 맞지 않을까.) 문제가 되는 건 이게 한 자리 수일 수도 있고 두 자리 수일 수도 있다는 것인데, 그래서 몇 번의 시행착오 끝에 나온 것은...

1[0-4]|(?<![0-9])[0-9]

정규식에서 | 는 '이거 아니면 저거'라는 뜻이니까 먼저 1 뒤에 0부터 4까지의 숫자가 있는 걸 찾아보고 (즉 10~14), 그게 아니면 앞에 숫자가 없는 0부터 9까지의 한자리수 숫자를 찾아보게 된다. 숫자 자체만 찾아야지 앞뒤 글자는 찾으려는 부분이 아니니까 [^0-9][0-9]는 아니고. 이렇게 하면 색깔 코드 바로 다음에 숫자가 나와도 색깔 코드하고 섞이는 일을 최대한 피할 수 있다. 예를 들어

chr(3) + '26번째 서랍에 있어요'

같은 문자열은 원래 chr(3) + '2'라는 색깔 코드 뒤에 '6번째 서랍에 있어요'라는 문장이 있는 것인데, 그냥 숫자를 찾았다가는 26이라는 존재하지 않는 색깔 코드를 붙이려고 해서 색도 표시가 안 되고 문장에서 숫자를 끊어먹어서 '번째 서랍에 있어요'가 된다. 반면 위의 정규식으로 하면 26이 아닌 2만 찾으니까 제대로 표시할 수 있다.

물론 이런 건 좀 어쩔 수가 없다.

chr(3) + '14번 타자입니다'

chr(3) + 14는 유효한 색깔 코드니까 이건 chr(3) + 1 색으로 '4번 타자입니다'라고 하려고 했는지 아니면 chr(3) + 14 색으로 '번 타자입니다'라고 하려고 했는지 컴퓨터는 알 수 없다. (사람이야 알지만..) 이런 문제 때문에 CTCP에 따르면 칸을 떼어서 색깔 코드와 실제 쓰려는 문장을 구분해야 하는데, 그렇게 칸을 떼면 mIRC에서 알아서 칸을 없애줄지 잘 모르겠어서. 음. 이 컴에서는 mIRC 구동이 안 되는데 어떻게 테스트하나. 그래서 mIRC 스크립팅 대안으로 파이썬을 배우기 시작한 건데 이런 식으로 다시 발목을 잡는 mIRC..ㅠㅠ
2008/08/18 09:33 2008/08/18 09:33
로키
tags :
분류없음 2008/08/18 09:33

트랙백 주소 : http://lokasenna.pe.kr/blog/trackback/228

댓글을 달아 주세요

유니코드 유감

어째서! 어째서 '원' 자가 들어간다고 멀티바이트로 설정한 문자열이 유니코드가 되어버리는 거냐..ㅡㅡ++++ '인'도 멀티바이트고 '제한'도 멀티바이트인데 '인원 제한'이나 '원'은 무조건 유니코드라니, 말이 돼? (크아악)
2008/07/10 05:34 2008/07/10 05:34
로키
tags :
분류없음 2008/07/10 05:34

트랙백 주소 : http://lokasenna.pe.kr/blog/trackback/196

댓글을 달아 주세요

  1. Xenosia 2008/07/10 09:15  수정/삭제  댓글쓰기

    그것이 최적화 랜덤의 법칙입 [..]

  2. 종횡무진 2008/07/10 17:53  수정/삭제  댓글쓰기

    분명히 한글로 쓰여진 글임에도 불구하고 저에겐 외계어 ㅋㅋㅋㅋ
    문제 해결에 성공하시길!^^

  3. Sihaya 2008/07/11 11:40  수정/삭제  댓글쓰기

    케케케.. (...)
    유니코드.. orz

꾸역꾸역 진행 중

어제는 아침 9시 반부터 오후 4시 반까지 모의고사 보고 들어와서 그냥 작정하고 놀았다. 그간 벼르던 코딩도 좀 하면서 이전에 적었던 모종의 프로젝트 진도를 조금 더 나갔다. 생각만큼 진척이 빠르지는 않았지만...

스크린샷

약간은 모양을 갖추기 시작


무엇보다 인코딩 문제가 골치아프다. 유니코드를 위젯에 직접 쓸 수는 없는데 사용자가 위젯에 입력한 문자열은 유니코드라든지 하는 상황에 @_@ 상태. 또 어떤 위젯에는 유니코드 직접 입력이 되고... 어찌어찌 한글 표시는 되게 해놨지만, 소스가 꼬인 상태여서 인코딩을 통합적으로 처리하는 기능을 만들어야 할 것 같다.

인코딩 다음에는 한동안 자료 구조를 짜봐야 할 것 같다. 예를 들어 지금은 이런 식으로 가고 있는데...

self.channels = [
{'name':'#포도원의제다이',
'users':['@Eldir','Loki'],
'lines':['Loki님이 입장하셨습니다.',]},
]

이 구조에는 추가할 것도 많지만, 변경할 것도 있다. 예를 들어 나중에 타자 중 알림까지 구현할 것을 생각하면 'users' 키는 단어 리스트 대신 딕셔너리 리스트로 하는 게 나을 수도 있다.

'users': [
{'name':'@Eldir', 'typing': False},
{'name': 'Loki', 'typing': True}
]

대신 사용자 리스트 정렬 같은 게 귀찮아지긴 한다. 사용자 정보는 타자중 표시만 있어도 된다면 이름을 딕셔너리 키로 사용하는 것도 한 방법일 듯.

'users': {
'@Eldir': True,
'Loki': False,
}

하는 식으로. 정렬은 keys() 목록 정렬로 해결할 수 있을 테고.

'lines' 부분 역시 태그 정보까지 표시할 수 있게 확장해야 한다. 지금 생각하는 건 사용자가 직접 입력할 리가 없는 특수문자로 문자열을 갈라서 정보를 표시하는 정도. 대충 이런 식? (아마 몇 번 돌려보고 디버깅하기까지는 애로사항이 꽃피겠지만...)

line = '안녕, 여러분!¿red,0,2¿bold,1,4¿strike,4,7'

self.channels[self.currChan]['lines'].append(line)

totalLines = str(len(lines))

splitline = line.split('¿')

self.displayText.insert(END,splitline[0].strip()+'\n','default')

try:
    taginfo = splitline[1:]
    for tag in taginfo:
       tagIndex = tag.split(',')
       self.displayText.tag_add(tagIndex[0],\
        "%s.%s" % (totalLines,tagIndex[1]), \
        "%s.%s" % (totalLines,tagIndex[2]))

except IndexError:
    pass

여기에 태그에 따라 글씨 색, 크기 등을 바꾸는 부분을 처리하면 ', 여러분!' 같은 같잖은 짓을 할 수 있다. 역시 인코딩이 괴롭히기는 해서, 한글로는 글자 수 처리가 제대로 안 되고 유니코드로 처리해야 할 것 같다. 유니코드를 제대로 처리할 체계만 갖추면 비교적 풍부한 포매팅 선택지를 제공할 수 있을 듯. 제공하는 게 과연 좋을지는 생각해볼 문제이긴 하다.

사용자 삽입 이미지
사용자 삽입 이미지
참, 원래는 이름을 DiRC로 하려고 했는데 이미 있어서 어려울 것 같다. DieRC나 DiceRC는 어감이 썩 좋지 않고 IRC 클라이언트라는 점도 덜 사는 것 같고. 무난해서 결국은 그렇게 갈지도 모르지만, pertho, 혹은 peorth (<-- 저 룬문자이지, 요 아가씨가 아님-->) 룬을 어떻게 활용할 수 있을까도 궁리하고 있다.

페어토 혹은 페이오스는 제비뽑는 상자 혹은 주사위 컵을 상징한다고 한다. 친구끼리 하는 즐거운 놀이를 뜻할 수도 있고 운명과 예언을 상징할 수도 있는, 어찌 보면 다소 이율배반적인 룬. 기본적으로는 여성적 신비와 자궁의 창조적 에너지를 가리킨다.

생각해보면 무엇이 나올지 모르는 주사위 컵이나 제비상자와 수많은 미래의 가능성을 품는 자궁, 그리고 예측불허인 미래나 운명은 일맥상통하는 데가 있다. 우연의 변덕, 무한한 가능성과 즐거운 놀이를 나타낸다는 점에서 페이오스 룬은 RPG 클라이언트에 꽤 어울리는 것 같다. 여성의 신비나 여성적 창조성이라는 뜻은 RPG계의 남초 현상을 살짝 찌르기도 하고..ㅋㅋ

문제는 어떻게 활용하느냐인데... 아이콘은 페이오스 룬의 입구에 주사위 하나 있는 정도로 처리하면 될 것 같고, 문제는 이름. Pertho/Peorth와 Python을 합성한 Pyrtho나 Pyorth도 생각해볼 수 있겠지만, 이름에서 의미가 확 살지 않는 건 좀 아쉽다. PeoRC도 그렇고...

사실 정말로 하고 싶은 이름은 따로 있긴 하다. 페이오스 룬의 가장 마음에 드는 번역, Dicebox. 깔끔하고 의미 전달 잘 되고 정말 딱인데 아쉽게도 내가 생각해낸 게 아니라서 쓸 수가 없다. SF 웹코믹 제목이거든. Dicecup도 생각할 수 있지만 역시 딱은 아니고, 이래저래 생각해 보고 있다.

어쨌든 답답하면 답답한 대로, 막히면 막히는 대로 꾸역꾸역 진행하고 있는 프로젝트다. 이리저리 생각해보고 머리쓰는 게 나름 재밌다. 이렇게 찌끄덕찌끄덕거리다 언젠가 완성할 수 있을까.
2008/07/04 21:59 2008/07/04 21:59
로키
tags :
분류없음 2008/07/04 21:59

트랙백 주소 : http://lokasenna.pe.kr/blog/trackback/195

댓글을 달아 주세요

  1. lhovamp 2008/07/05 08:57  수정/삭제  댓글쓰기

    와- 즐거운 마음으로 완성 기다리겠사옵니다 +_+

    • 로키 2008/07/06 21:35  수정/삭제

      나도 어서 완성되었으면..(..)

  2. 종횡무진 2008/07/05 13:34  수정/삭제  댓글쓰기

    로키님의 그 열정의 산실~
    열매의 맛이 얼마나 달콤할지 기대해도 되겠죠?(부담이 되시려나?^^;)

    • 로키 2008/07/06 21:37  수정/삭제

      푸핫.. ORPG 하시는지는 모르겠지만 어쩌면 안하시는 분들에게도 유용할지도요.

  3. Xenosia 2008/07/05 22:31  수정/삭제  댓글쓰기

    인코딩과 유니코드<-> 멀티바이트는 프로세스 통신의 적이죠! [..]
    저도 착수해야 하는데 시간과 자금이 [..]

    • 로키 2008/07/06 21:38  수정/삭제

      흑흑 골치아프더라고요. 이제 어느 정도 잡힌 듯 싶지만.. 어서 착수하십 (철썩철썩)

  4. Sihaya 2008/07/07 10:23  수정/삭제  댓글쓰기

    아하하하하하... 저런 건 무조건 화이팅입니다~~

  5. buy website traffic 2011/09/23 18:04  수정/삭제  댓글쓰기

    감사합니다

그림에 글씨를 쓰는 간단한 PIL 스크립트

시간이 없어서 많이는 못하고 있지만 계속 생각은 하고 있는 코딩 프로젝트 때문에 이미지를 다루는 파이썬 라이브러리인 PIL (Python Imaging Library)을 사용해 보았다. 여기저기 예시를 참조한 끝에 빈 주사위 그림에 숫자를 그려넣는 스크립트를 만들었다. 아래는 그 스크립트.

#PIL에서 필요한 모듈 가져오기
from PIL import Image, ImageFont, ImageDraw

#이미지 경로와 폰트 파일 (트루타입) 설정
imgdir = 'images/'
fontfile = 'images/andlso.ttf'

#숫자 파일 만드는 기능
#아래 pasteImg에서 이쪽을 참조하므로 순서상 앞이어야 한다.
#프로젝트에 실제 사용할 때는 클래스라 순서는 상관없겠지만..
def makenumber(string,filename,color,size):
    """
    @string: string
    @filename: string
    @color: hex string
    @size: int
    """
    #글자체를 트루타입으로 불러온다
    font = ImageFont.truetype(fontfile,size)

    #글씨의 가로세로를 튜플로 구한다 가로 50, 세로 100이라면 (50, 100) 하는 식으로 나온다
    imgsize = font.getsize(string)

    #새로운 투명 이미지를 만든다  
    pic = Image.new("RGBA", imgsize, (0,0,0,0))
    draw = ImageDraw.Draw(pic)

    #투명 이미지에 지정한 문자열을 지정한 글자체와 색으로 쓴다
    draw.text((0,0),string,font=font,fill=color)

    #이미지를 지정한 파일명으로 저장하고 파일명 출력
    pic.save("%s%s.png" % (imgdir,filename),'png')

    return filename

#그림 위에 다른 투명 그림을 덧붙이는 기능
def pasteImg(bgfile,string,filename,color,size,ext,overwrite=False):
    """
    @bgfile: string
    @string: string
    @filename: string
    @color: hex
    @size: 2-tuple
    @ext: string
    @overwrite: boolean
    """
    #덮어쓰기가 0이면 지정한 숫자 파일이 있나 확인하고 없으면 만듦
    if not overwrite:

        try:
            #숫자파일이 있나 확인하느라 열어보고...
            fg = Image.open("%s%s.%s"%(imgdir,filename,ext))
        except IOError:
            #없어서 에러나면 makenumber를 불러서 숫자 파일 제작
            makenumber(string,filename,color,size)
            fg = Image.open("%s%s.%s"%(imgdir,filename,ext))

    #덮어쓰기가 1이면 무조건 숫자 파일을 만듦
    else:
        makenumber(string,filename,color,size)
        fg = Image.open("%s%s.%s"%(imgdir,filename,ext))

    #배경이 될 그림을 열고...
    bg = Image.open("%s%s.%s"%(imgdir,bgfile,ext))

    #배경 그림과 숫자 그림의 가로세로를 튜플로 낸 후..
    W, H = bg.size
    w, h = fg.size

    #배경과 붙여넣을 그림의 가로세로 차이의 반값을 구해서...
    x, y = (W-w)/2, (H-h)/2

    #위에서 낸 x, y를 왼쪽 위 구석으로 해서 숫자 파일을 붙여넣음
    #뒤에 숫자 파일 핸들러를 다시 지정해주는 건 투명 파일로 붙여넣는 데 필수라고 한다
    #이유는 모른다. 그냥 어디 게시판에서 찾은 해결책
    bg.paste(fg, (x,y), fg)

    #숫자를 붙여넣은 그림을 저장한다
    bg.save("%s%s/%s.%s"% (imgdir,bgfile,filename,ext), ext)

#그리고 기능을 사용
#빈 d20 (20면체 주사위) 그림에 1~20까지 숫자를 그려넣은 후
#(글자 크기는 30, 숫자는 검정색)
#images/d20 폴더에 파일명 1png에서 20.png으로 저장

i=1

while i<=20:
    pasteImg('d20',str(i),str(i),'#000',30,'png',True)
    i = i + 1

이렇게 해놓으면 주사위 그림과 폰트 파일만 있으면 어떤 주사위든 쉽게 만들 수 있다. 이런 거라든지...

사용자 삽입 이미지
뭐 별로 예쁘진 않다. 내게 너무 많은 걸 바라지 말아주길..(..) 하지만 중요한 건 주사위 그림 일일히 만들지 않아도 좋은 주사위 그림만 있으면 쉽사리 숫자를 그려서 만들 수 있다는 점. 다만 그림이 투시도 느낌이 아니면 숫자를 그릴 때 좀 더 정밀한 계산을 해야겠지.

한 한 달 전에 만들어놓은 스크립트인데, 이거 보니 다시 코딩하고 싶다..;_; 시험공부 지겨워, 엉엉.
2008/06/21 03:54 2008/06/21 03:54
로키
tags :
분류없음 2008/06/21 03:54

트랙백 주소 : http://lokasenna.pe.kr/blog/trackback/187

댓글을 달아 주세요

  1. Xenosia 2008/06/21 04:47  수정/삭제  댓글쓰기

    힘내십..저도 야근 지겹습 [크흑]


    Ps. PHP 4일 째 모군 [..]

  2. Sihaya 2008/06/21 14:49  수정/삭제  댓글쓰기

    해야 하는 공부니 포기하고 열심히 하십쇼~ ㅇㅅㅇ/

  3. akudoku 2010/02/02 17:11  수정/삭제  댓글쓰기

    감사합니다.
    많은 도움 받았습니다.

    • 로키 2010/02/02 21:26  수정/삭제

      다행입니다^^ 정작 저는 코딩에서 손 뗀지 오래돼서 봐도 모르겠지만, @_@ 누군가 도움이 되시는 분이 있다니 좋네요.

    • lhovamp 2010/02/06 10:23  수정/삭제

      님이 여길 어찌 알고 왔삼?
      이래서 세상이 좁은 건가!

대장정의 첫걸음

파이썬 (Python)과 Tkinter로 IRC 클라이언트를 만드는 작업을 어제 시작했다. 어제오늘 시행착오 엄청나게 겪으면서 배운 게 정말 많아서 갈 길이 멀다는 실감이 새삼 들었다. 처음부터 생각하는 기능을 다 넣으려고 했다가는 시작도 제대로 못하고 포기할 것 같아서 일단 뼈대부터 시작해 하나하나 덧붙이면서 늘려가고 있다. Grid 레이아웃 관리자는 위젯을 하나씩 덧붙이기가 쉽기도 하고.

지금까지 갖춘 모습은 이 정도.

스크린샷

뼈만 앙상~


모습으로만 보면 아직 별 거 없지만, 처음부터 걸린 문제였던 서버 입력 처리를 해결한 후라 나름 뿌듯하다. 이전에 콘솔용 IRC 봇을 만들어 봤는데도 GUI로 넘어오니까 잘 안 돼서 결국 관련 예시를 참조해서 쓰레딩 (threading) 처리를 하니까 됐다. 쓰레딩 구문 부분을 주로 참고하고 큐는 목록으로 대체한 후 .pop(0)을 이용했고, GUI 생성을 단일 기능으로 처리하는 등 예시 코드하고는 좀 달라졌지만.

IRC에서 오는 메시지를 프로그램에 전부 표시하지는 않고 (개발하는 동안에는 디버깅용으로 IDLE 콘솔에는 표시하지만), 상태표시줄을 만들어서 메시지 종류에 따라 인증 중, 연결 실패, 연결 성공 등 상태만 요약해서 표시했다. 저 상태표시줄의 또 다른 주요 용도는 나중에 누구누구는 타자 중이라고 표시하는 것. 어느 세월에 거기까지 만드나...

여기서부터 할 일은 일단 서버와 채널 목록을 저장해 놓게 딕셔너리를 만들어서 피클 (pickle)로 쟁여놓고(..) 편집하는 인터페이스를 만드는 것. 설정 사항은 만들면서 잔뜩 늘어날 테니 지금부터 딕셔너리로 관리하는 게 좋겠지. 자동 조인 채널 목록은 딕셔너리에서 채널 창으로 옮겨놓고, 일단 채널에 모두 들어가지면 들어간 채널마다 탭 인터페이스를 만들어서 '들어갈 채널' 문구를 '현재 채널'로 바꾸고 '나가기' 버튼을 만들... 아아 복잡해진다..ㅠㅠ

어쨌든 일단은 설정 딕셔너리 만들고 저 텍스트 창에 뭔가 표시하는 게 급선무겠지. 그 다음에는 채널에 있는 사람 표시하는 목록, 그 다음은 정보 표시창. 입력창은 비교적 쉽게 만들 수 있을 듯. 여러 채널이나 탭 인터페이스는 그 다음에 생각하도록 하자. 메뉴바도 만들고... 그것까지 완성하면 이제 공포의 주사위 패널이 기다리고 있구나..(..) 프로그램 공부한 적 없는 인간에게는 산 넘어 산이라고밖에는...

재미로 하는 것인 만큼 조급하게 생각할 필요는 없겠지. 느긋하게 마음 먹고 틈틈이 작업하다 보면 프로그램도 모양새를 갖추고 파이썬 실력도 많이 늘을 것 같다.
2008/05/30 02:45 2008/05/30 02:45
로키
tags :
분류없음 2008/05/30 02:45

트랙백 주소 : http://lokasenna.pe.kr/blog/trackback/174

댓글을 달아 주세요

  1. 종횡무진 2008/05/30 09:11  수정/삭제  댓글쓰기

    무슨 말인지 이해는 못 하겠으나 아주 즐거운 일을 하시는 건 분명한 거 같네요.
    저는 한때 중학교시절 나모웹에디터를 이용해 네띠앙계정으로 홈페이지를 만들면서
    컴퓨터 프로그래머가 되야지 라고 했으나...
    제가 그러기에는 너무나 부족한 사람이라는 걸 일찍히 깨닫고 선회하여 다른 공부를 하고 있지만 텍스트 큐브를 매만지며 이루지 못한? 꿈을 해갈하고 있어서
    참 즐거운 면이 있더라구요 ㅋㅋㅋ

    • 로키 2008/05/31 07:42  수정/삭제

      확실히 웹페이지 돌리는 건 재밌죠..ㅋㅋ 옛날 초등학교 때 간단한 프로그래밍을 배운 일이 있었는데, 그때는 하나도 이해 못하고 있다가 ('x = x + 1이라니, 말이 안 되잖아!') 늦게 배운 도둑질에 시간 가는 줄 모르고 있네요..^^

  2. Xenosia 2008/05/30 09:40  수정/삭제  댓글쓰기

    오, 모래지옥에 빠지신겁.. [퍽]
    도와드릴 수 있는 부분은 도와드리겠습..

    [파이썬 안써본 프로그래머 모군 [..]

    • 로키 2008/05/31 07:43  수정/삭제

      모래지옥인가요 엉엉. 그렇잖아도 신경쓰이는 문제가 하나 있어서 (서버 입력 가져오는 무한 루프가 끝나지 않고 있는 것 같은) 기회 되면 상담 청하겠습니다~

  3. Wishsong 2008/05/30 17:23  수정/삭제  댓글쓰기

    빨리 완성해! (언제나 그렇듯이 감나무 밑에서 입을 떡 벌리고 있는 승한이)

    • 로키 2008/05/31 07:44  수정/삭제

      에에잇 이런! 적어도 '차를 타다 줄게, 누나'라든지 '어깨를 주물러 줄게' 정도는 돼야지! (..)

작은 실험.

최근 코딩 프로젝트에서 불러오는 피드가 많아지면서 페이지 로딩 속도가 느려졌다. 페이지 첫머리에  무조건 피드를 불러오고 데이터베이스에 입력하는 스크립트를 넣어놓고 있었으니 당연한 일이다. 사실 '대개의 사용자에게' 페이지 로딩을 빠르게 하는 법은 전부터 생각하고 있었지만, 안하고 있다가 이번에 스크립트 처리 속도가 2초를 넘어가는 걸 보고 마침내 실행에 옮겼다.

해결책은 꽤 간단하다. 모든 사용자의 접속 때마다 피드를 불러오고 처리하는 게 아니라, 피드 처리 링크를 따로 달아서 피드 업데이트를 자동화 대신 수동화하는 거다. 대부분의 사용자는 피드 처리를 거칠 필요가 없고, '새로운 기사 불러오기' 링크를 클릭하는 사용자만 1~2초 로딩 시간을 들여 피드를 불러오고 데이터베이스에 입력하는 스크립트를 발동하면 된다. 덕분에 페이지가 많이 가벼워져서, 스크립트 처리 속도는 2초를 넘는 수준에서 다시 0.6~0.8초 수준으로 떨어졌다.

사용자 전체로 보면 이쪽이 더 효율이 높은 것은 당연하다. 2초, 0.6초는 서버에서 스크립트를 처리하는 시간 얘기고 브라우저에서 서버에 페이지를 요청하고 사용자에게 보이도록 화면에 표시하는 시간은 또 따로 있다. 따라서 모든 사용자가 페이지에 들어올 때마다 그 몇 초를 허비하는 게 없어졌으니 시간 면에서도, 서버 부담 면에서도 절약한 것은 적지 않다.

다만, 전에 망설였던 것은 이게 전체 사용자로 보면 시간을 많이 절약해주는 대신 새 기사가 나왔는지 확인하려는 사용자에게 링크를 클릭하는 약간의 노력과 몇 초의 로딩 시간을 요구한다는 점이다. 즉, 페이지에 들어오는 모든 사용자에게 요구했던 1.2~1.4초의 시간을 하루에 한두 명의 사용자에게 전가한 셈이 된다.

그게 내게는 이 문제의 흥미로운 점이다. 전체적인 절약은 큰데, 어차피 이전의 낭비야 (나만 빼고) 별로 의식하지 않았던 반면, 새로 기사가 있나 확인하려고 링크를 클릭하는 사용자는 클릭하는 수고와 추가 로딩 시간을 의식할 수밖에 없다. 그래서 과연 시간 절약을 사람들이 체감할까, 차라리 다같이 시간을 조금씩 더 낭비하면서도 아무도 의식하지 못하는 편이 체감 면에서는 더 효율적이지 않을까 싶다. (비록 그 체감이 거짓이기는 하지만.)

이게 어떻게 보면 상당수의 정책이나 체계의 역설이기도 하지 않나 싶다. 전체의 부담을 소수에게 옮겨서 집단 전체의 효용은 큰데, 그 효용의 수혜자는 좋아진 걸 별로 의식하지 못하고 부담이 생긴 소수는 자신에게 생긴 새로운 부담을 의식하는. 비유하자면 자유무역이 그렇다. 사회 전체적으로 생기는 효용은 굉장하지만, 어차피 그 효용이라는 게 대개의 사람에게는 물건 값이 약간 내려간 정도인데 무역으로 도태되게 된 기업과 관련자는 생계 자체에 위협을 받으니까.

물론 내 피드 수집 페이지는 자유무역과는 여러모로 경우가 다르다. 규모는 말할 것도 없고, 링크를 클릭하는 노력은 아주 적은 건 둘째치고라도 자발적이니까. 전체적으로는 별로 의식하지 못하는 절감의 대가로 소수가 비용 증대를 의식해야 한다는 점에서만 약간 비슷한 데가 있을 뿐. 그런 의미에서 역시 이건 '작은' 실험이다. 업데이트를 수동화한 것이 업데이트 주기에 어떤 영향이 있을지, 새로운 기사가 있는지 보려면 따로 링크를 클릭해야 한다는 것을 사용자들이 부담으로 인식할까, 아니면 재밌어할지 궁금하다.

수정: 업데이트가 잦다면 몰라도 또 링크를 의미 없이 누르는 일이 너무 잦아지는 것 같아서 이제는 그냥 마지막 확인한 시점에서 6시간이 지났으면 불러오는 스크립트를 자동으로 돌리게 했다. chron이 안 되는 서버이지만 데이터베이스로 흉내는 내는 셈.
2008/05/02 07:24 2008/05/02 07:24
로키
분류없음 2008/05/02 07:24

트랙백 주소 : http://lokasenna.pe.kr/blog/trackback/163

댓글을 달아 주세요

PyRTF에 다국적 지원을 추가하는 방법

mIRC 로그를 RTF 파일로 정리하는 프로그램을 짜면서 초장에 제일 막혔던 건 RTF의 한국어 인코딩 부분이었다. PyRTF라고 파이썬으로 꽤 고레벨에서 RTF 파일을 만드는 모듈을 발견하기는 했는데, 이게 다국어 지원이 전혀 없다는 걸 깨닫고 욕이 나왔다. (..) 버전 0.45 정도에 과한 기대를 해도 안 되겠지만 말야.

위키피디아에서 RTF 표준에 대한 기사를 보고서도 한참 헤맨 게, utf-8 디코딩을 해서 유니코드를 내려고 해도 결과는 이런 식이었거든.

>> print '안녕'.decode('utf-8').encode('unicode_escape')
>> \uc548\ub155

문제는 저건 RTF 파일에서 받지를 않는다는 점. 워드프로세서로 열어보면 안 나온다. 그래서 역으로 워드프로세서로 '안녕'을 치고 에딧패드 (EditPad)로 열어보니 다음과 같이 나왔다.

\u50504\'3f\u45397\'3f\u33\'3f

이 차이를 가지고 한동안 끙끙대다가 ord 기능을 알게 되어서 결국 다음과 같은 식으로 해결했다.

def ordinalCode(string, enc):

    ordcode =''
    string = string.decode(enc)
    ordinals = [ord(x) for x in string]

    for ordinal in ordinals:
        #디버깅 코드
        #print ordinal
        ordcode = "%s\\u%d\\'3f" % (ordcode,ordinal)

    return ordcode

이 기능을 달아두고 RTF 파일을 만들 때는 예를 들어 추가할 내용을 string이라고 하면

enc = 'utf-8'
newline = ordinalCode(string, enc)
p.append(newline)
section.append(p)

하는 식이 된다. 사실 글자 뒤마다 붙은 \'3f가 무슨 뜻인지도 모르고 \u50504와 \uc538의 차이가 뭔지도 모르겠다. 그걸 알 만큼 공부했으면 프로그래머지, 허접 취미 코더겠나. 내가 아는 건 해보니 일단 됐다는 것. 그리고 내가 테스트해본 한 이렇게 하면 우리말로도 PyRTF를 이용해 RTF를 쓸 수 있겠다는 정도이다. 막혔던 문제에 대해 해결책을 찾아낸다는 건 즐거운 일~
2008/04/02 21:06 2008/04/02 21:06
로키
tags :
분류없음 2008/04/02 21:06

트랙백 주소 : http://lokasenna.pe.kr/blog/trackback/146

댓글을 달아 주세요

  1. 종횡무진 2008/04/02 22:39  수정/삭제  댓글쓰기

    프로그램 만지며 에러를 고치는 것도 큰 재미죠^^
    로키님은 정말 못하시는게 없는 거 같아서 부럽니다^_____^

    • 로키 2008/04/03 04:40  수정/삭제

      문제를 해결한 순간의 그 쾌감이 비할 데가 없죠.^^ 못하는 게 없긴요, 잘하는 거 빼고 다 못해요(??)

Powerd by Textcube, designed by criuce
rss