기본 콘텐츠로 건너뛰기

2013의 게시물 표시

android(armv7)에 node.js 올리기. (Rockchip RK3188/MK809C)

http://masashi-k.blogspot.kr/2013/08/nodejs-on-android.html 이쪽 글을 참조했다. 환경은 일단 RK3188 계열인 MK809C로 시도해보았다. 먼저 루팅이 되어있고 Linux Installer나 Debian Tool kit등으로 리눅스를 설치했고 터미널 클라이언트나 SSH를 통해 접근 가능한 상태라고 가정한다. 현재 node.js의 안정(stable) 버전은 v0.10.23이므로 해당 소스를 다운받자. http://nodejs.org/download/ 에 들어가서 http://nodejs.org/dist/v0.10.23/node-v0.10.23.tar.gz 직접 소스를 받으면 된다. $ wget  http://nodejs.org/dist/v0.10.23/node-v0.10.23.tar.gz 으로 받자. $ tar xzf node-v0.10.23.tar.gz $ cd node-v0.10.23 해서 빌드 준비를 하자. $ ./configure --without-snapshot --dest-cpu=arm --dest-os=linux 로 먼저 빌드 환경을 잡고 바로 make 하기전에 thumb inter-working 관련 오류를 피하기 위해 macro-assembler-arm.cc 파일의 일부를 수정한다. 압축푼 경로를 기준으로 vi ./deps/v8/src/arm/macro-assembler-arm.cc 파일을 열어 60라인 근처를 수정하자. #if defined(USE_THUMB_INTERWORK) && !defined(CAN_USE_THUMB_INSTRUCTIONS) # error "For thumb inter-working we require an architecture which supports blx" #endif 아마 이런 부분이 있을 것이다. # error 부분 줄을 삭제하거나 // 처리 하자. ( http://

Multiple pub/sub collection in meteor

iron Router를 잘 쓰고 있는데 쓰다 보니 이상한 점이 있다. 페이지별로 subscribe 하는 것까지는 좋지만 당연히 여러 개의 page에 대해 subscribe를 해야 하는데 waitOn 같은 곳에서 여러 개의 collection에 대해 subscribe를 하다 보니 N번 화면을 갱신하기도 하고 코드도 좀 번거롭다. 여러 개의 Collection에 대한 pub/sub을 한 번에 할 수 없을까 생각하고 있었는데 https://github.com/meteor/meteor/pull/716 최근 내용을 보니까 구현이 되어있다! 이것도 undocumented라고 해야 하나 싶다. 아무튼, 좋다. Posts, Replies 두 개의 Collection이 있다고 할 때 autopublish package를 meteor(혹은 mrt) remove autopublish하여 삭제하고 수동 가입을 구현한다면 /model/model.coffee @Posts = new Meteor.Collection "posts" @Replies = new Meteor.Collection "replies" /client/subscribe.coffee Meteor.subscribe 'posts-replies' /server/publish.coffee Meteor.publish 'posts', ->   [Posts.find(), Replies.find()] 이렇게 [ ] 배열 형태로 묶어만 주면 된다. 좋은 패치라고 생각한다. 적극적으로 활용하자.

iron-router에서 /#/(hashbang) 을 사용할때 주의점( ex. verify-email등)

iron-router 적응 중인데 역시 대세다. 최근 server-side도 반영되어 구 router package에서 안심하고 넘어와도 되겠다 싶었다. E-mail 인증( http://spectrumdig.blogspot.kr/2013/10/meteor-e-mail.html )을 구현해 놓았는데 이게 실제로 해보니까 iron-router 에선 제대로 되지 않는다. 찾아보니 Server 쪽에서 해당 URL이 들어올때 패치하는 방법이 있다. https://github.com/EventedMind/iron-router/issues/3#issuecomment-20917649 Server 아래 Route 관련 부분에 Accounts.urls.resetPassword = (token) ->   Meteor.absoluteUrl "reset-password/#{token}" Accounts.urls.verifyEmail = (token) ->   Meteor.absoluteUrl "verify-email/#{token}" Accounts.urls.enrollAccount = (token) ->   Meteor.absoluteUrl "enroll-account/#{token}" 이런 식으로 넣어주면 된다.

meteor에서 특정 조건에서 head를 조작하기

server/header.js 식으로 server에서만 작동하는 코드를 만들자. Fiber = Npm.require("fibers"); WebApp.connectHandlers.use(function(req, res, next) { if (req.url==='/connect') { res.writeHead(200, {'Content-Type': 'text/html'}); Fiber(function() { res.write('<html>') res.write('<head>'); res.write('<meta property="qc:admins" content="2311172222411526554572637573766534" />'); res.write('<head>'); res.write('<body></body>'); res.write('</html>') res.end(); }).run(); } else { next(); } }); 위 코드는 weiyun 인증의 경우인데 <meta property="qc:admins" ... 를 사이트에서 요구하는 경우이다. 이런 식으로 meta를 요구하는 경우가 종종 있는데 아마 구글 서비스 중에도 있을 듯. 사이트 도구? 아마 그럴 것이다. 저번에도 이야기 했지만 WebApp.connectHandlers 요거 좋은 놈이다. 서버쪽에서 특정 url로 들어왔을때 예외처리를 하고 싶다면 이걸 사용하면 된다. 예의 경우는 /connect 로 들어왔을 때만 예외처리를 하고 나머지는 그냥 next()로 넘겼다.

SoX Library 컴파일하기(for OS X)

./osxbuild 실행 오류 $ ruby -e "$(curl -fsSL https://raw.github.com/mxcl/homebrew/go)" $ brew install automake 재시도 $ ./osxbuild configure.ac:21: installing './compile' configure.ac:10: installing './config.guess' configure.ac:10: installing './config.sub' configure.ac:12: installing './install-sh' configure.ac:12: installing './missing' libgsm/Makefile.am:35: error: Libtool library used but 'LIBTOOL' is undefined libgsm/Makefile.am:35:   The usual way to define 'LIBTOOL' is to add 'LT_INIT' libgsm/Makefile.am:35:   to 'configure.ac' and run 'aclocal' and 'autoconf' again. libgsm/Makefile.am:35:   If 'LT_INIT' is in 'configure.ac', make sure libgsm/Makefile.am:35:   its definition is in aclocal's search path. libgsm/Makefile.am: installing './depcomp' lpc10/Makefile.am:8: error: Libtool library used but 'LIBTOOL' is undefined

Genymotion 에서 Unroot/Root 상태 전환하기 위한 쉬운 방법.

Genymotion은 지옥 성능의 안드로이드 에뮬에 비해 확실히 쾌적하고 아름다운 툴이다. 최근 롬을 보면 기본 Su 설치 상태로 나오는데 일부 Root을 검사하는 앱에서 사용 제한이 걸리곤 한다. 멀티터치 같은 걸 시뮬하기 위해서 DroidMote를 사용한다던가 하는 용도를 봤을땐 Root가 필요하고 여러가지 이유로 개발환경에선 Root/Unroot를 다 쓸 수 있으면 좋다. Genymotion Configuration 아이콘을 찍고 Save 버튼 위 Always allow su access (bypass Superuser app)에 체크박스를 켜준다. Save 하면 아마 재부팅을 한다고 할 것이다. 재부팅하자. 요즘은 SuperSu 가 간단하니 SuperSu를 스토어에서 받자. 몇몇 가지를 묻는데 특별한 롬을 쓰느냐 물을 때 Normal 이랑 충돌이 있으니 기존 Su앱을 지우겠느냐에서 등등 상식적인 걸 체크하고 SuperSu를 다시 실행. 이제부턴 설정창에서 Su를 간편하게 껐다 켰다 할 수 있다.

meteor 에서 E-mail 인증하기

MAIL_URL은 gmail을 쓸 경우 다음과 같이 설정하면 된다. smtp:// 사용자계정 %40gmail.com: 계정암호 @smtp.gmail.com:465/ 혹은 google apps 계정은 경우 smtp:// 사용자계정 %40 구글Apps도메인 : 계정암호 @smtp.gmail.com:465/ ---- 가입자 확인 메일 발송엔 몇가지 문제가 있는데 1. Text로 메일을 보낸다. 2. Formatted 형식을 사용할 수 없다. 이건 내가 생각해봐도 좀 아니다 싶다. server 쪽에서 startup 할때 기존 Accounts.emailTemplate과 Accounts.sendVerificationEmail 등등이 제대로 작동하도록 바꿔치기 해주자. :: email.coffee Meteor.startup ->   # set Mail configuration   Email = Package.email.Email;   _.extend Accounts.emailTemplates,     from: "Gearlounge <no-reply@gearlounge.com>"     verifyEmail:       subject: (user)->         "#{"#{user.profile.displayName}님, "if (user.profile and user.profile.displayName)?}가입을 환영합니다."       html: (user, url)->         Handlebars.templates['verifyEmail'](           user: user.profile && user.profile.displayName           verifyEmailUrl: url           urlHome: Meteor.abs

Could not locate package.js 오류가 발생하면서 mrt/meteor 가 실행 안될때

/packages 디렉토리를 죄다 .gitignore로 등록해서 온 프로젝트가 있어서 지우고 다시 했더니 Could not locate package.js .. 오류가 발생했다. https://github.com/DiscoverMeteor/Microscope/issues/11 이 글을 참조. mrt uninstall --system 하고 다시 실행했더니 잘된다. 다행이네 다행이야.

node.js에서 angular.js 같은 동적 웹페이지를 사용할 때 crawling 문제

이전글 ( http://spectrumdig.blogspot.kr/2013/10/spiderable-package.html )에서 meteor가 어떻게 봇들에게 렌더링된 이후의 html을 전달하는지 보았다. 근데 만일 node.js에서 같은 구현을 해야한다면? 역시 request를 까발려서 _escaped_fragment_ 가 있는지 user-agent가 어떤 것인지 분별하면 된다. 방법이야 여러가지가 있을 텐데 preprocessor를 사용하여 가로채서 조건에 맞으면 처리하고 아닐 경우 next()로 포워딩하는 방법이 있고 ( https://github.com/acidsound/pushpot/blob/master/app.js#L30 ) Express/Connect Middle-ware를 사용하여 app.use(function(req, res, next){   if (req.query._escaped_fragment_ ||     [/^facebookexternalhit/i, /^linkedinbot/i, /^twitterbot/i].some(function(v) {       return v.test(req.headers['user-agent']);     })) {       // render by phantomJS       res.send(getHTMLfromPhantomJS(req.url));   } else {     next();   } 이런 식으로 처리해주면 되겠다.발로 짜서 실제 작동 여부는 모르겠다. getHTMLfromPhantomJS 는 물론 직접 구현하시라 :p https://github.com/meteor/meteor/blob/devel/packages/spiderable/spiderable.js 이런식으로 구현하면 됨.

spiderable package를 살펴보았다.

동적페이지를 만들면 웹크롤러들이 찌르러 왔다가 빈손으로 돌아가곤 한다. 이래서야 안될일. 발번역부터 시작해보자. // list of bot user agents that we want to serve statically, but do // not obey the _escaped_fragment_ protocol. The page is served // statically to any client whos user agent matches any of these // regexps. Users may modify this array. // // An original goal with the spiderable package was to avoid doing // user-agent based tests. But the reality is not enough bots support // the _escaped_fragment_ protocol, so we need to hardcode a list // here. I shed a silent tear. 우리가 정적으로 제공하고 싶지만 _escaped_fragment_ 프로토콜을 따르지 않는 봇 사용자 에이전트의 목록입니다. 페이지는 사용자 에이전트가 이러한 정규식 중 하나와 일치하는 모든 클라이언트에 정적으로 제공합니다. 사용자는 이 배열을 변경할 수 있습니다. spiderable 패키지와 원래 목표는 사용자 에이전트 기반의 테스트를 실시하는 것을 피하기 위해서였다. 하지만 현실은 봇들은 _escaped_fragment_ 프로토콜을 지원하지 않기 때문에, 여기에서는 목록을 하드 코딩해야합니다. 나는 조용히 눈물을 흘렸다. Spiderable.userAgentRegExps = [     /^facebookexternalhit/i, /^linkedinbot/i, /^twitterbot/i]; 요놈들! 말을 듣지 않는 나쁜 아이들이 니 놈들이렸다! 이 오라질 것들! 아래와 같

Meteor 에서 #constant를 사용하여 collection이 바뀌어도 특정 블록을 유지하기.

meteor는 collection을 기반으로 움직인다. 즉 collection이 변화가 있으면 해당하는 부분의 렌더링을 부분적으로 다시 하는데 고맙게도 preserve-input 이라는 패키지를 기본적으로 사용하여 전체를 다 로딩하지 않게끔 하고 있다. <head>   <title>replyExample</title> </head> <body>   {{> Posts}} </body> <template name="Posts">   <ul>     {{#each posts}}     <li>       {{message}}     </li>     {{/each}}   </ul>   <input type="text" class="newPost"/> </template> 최소한으로 컬렉션을 표시하는 html은 이런 형태일 것이다. @Posts = new Meteor.Collection "posts" if Meteor.isClient   Template.Posts.posts = ->     Posts.find {} .coffee의 내용은 이렇게 되겠지. 하지만 재귀적으로 글>댓글 형식으로 구현할 경우 다소 문제가 된다. <head>   <title>replyExample</title> </head> <body>   {{> Posts}} </body> <template name="Posts">   <ul>     {{#each posts}}     <li>       {{message}}  

Meteor의 Login유지 방식

역시 마루타는 atmosphere이다. 한번 로그인 한 사이트에 갈때마다 여러번 로그인 하는 건 세련되지 않다. 어떤식으로 Meteor에서 로그인 유지를 하는지 보자. 잡았다 요놈! Local Storage에 저장한다. 이게 Session 객체인지 Local Storage를 삭제하니까 실시간으로 로그아웃이 해제된다 + _+)!!! Meteor.loginToken으로 저장하고 확인하는구나. https://github.com/meteor/meteor/blob/devel/packages/accounts-base/localstorage_token.js 내용을 보니 localStroage에 대한 fallback( https://github.com/meteor/meteor/blob/devel/packages/localstorage/localstorage.js )을 따로 만들어 놓았다. 켁, 소스를 보니 IE일 경우 userData를 사용하네! http://msdn.microsoft.com/en-us/library/ms533007(v=vs.85).aspx 관련 내용 링크.

node.js 를 위한 vim 환경 설정.

tmux를 쓰다보니 vim 환경 설정 셋을 문득 만들어 보고 싶었다. 1. 일단 vim 먼저 받고 sudo apt-get install vim 2. manage your runtimepath 관리용 pathgen 설치 mkdir -p ~/.vim/autoload ~/.vim/bundle; \ curl -Sso ~/.vim/autoload/pathogen.vim \     https://raw.github.com/tpope/vim-pathogen/master/autoload/pathogen.vim 3. ~/.vimrc 없을테니 아래와 같이 생성. tab/indent 간격은 2에 탭 대신 space로 쓰기 위해 expandtab 추가 execute pathogen#infect() syntax on filetype plugin indent on set tabstop=2 set shiftwidth=2 set softtabstop=2 set expandtab 4. 아무 js 나 vim 으로 열어서 color 적용여부 확인 5. sensible plugin 설치 git clone git://github.com/tpope/vim-sensible.git ~/.vim/bundle/vim-sensible 6. node bundle 설치 git clone https://github.com/moll/vim-node.git ~/.vim/bundle/node 7. coffeescript bundle 설치 git clone https://github.com/kchmck/vim-coffee-script.git ~/.vim/bundle/vim-coffee-script/ 8. zen code 보다 더 좋은 Emmet 설치 - ctrl+y+, 로 활성화 git clone http://github.com/mattn/emmet-vim.git ~/.vim/bundle/emmet-vim 9. less 도 활성화 git clon

Meteor 에서 외부 Application으로 DDP 인증 (2) : SRP 교환

DDP로 인증을 하려면 네트웍상에 평문으로 보내지 않기 위해 SRP(Secure Remote Password) 라는 프로토콜로 변환한다. https://github.com/meteor/meteor/tree/devel/packages/srp package.js 를 보면 biginteger 와 sha256 을 사용한다. 구현해야할 부분은  https://github.com/meteor/meteor/blob/devel/packages/accounts-password/password_client.js#L10 이 곳 참조. password 를 가지고 다음과 같이.     s = new srp.Client password     request = s.startExchange()     if typeof selector == 'string'       selector =         if ~selector.indexof("@")         then username: selector         else email: selector     request.user = selector beginPasswordExchange 를 시작하는 부분의 인자는 request 자체를 사용. request 내용은 A를 키로 하는 SRP 암호문과 user를 키로하는 사용자명이 되겠다. method 쏴준다. A에 srp로 암호화한 문자를 사용. { msg: 'method',   method: 'beginPasswordExchange',   params:    [ { A: '439284960ce6bc7c163262b5629a467cd06bb982432615ec526a1ed204d2f76a1a254faaab6c5c9309e120d708e3e46fe58d8c5017aedb85efb9670cfcbf8a8b2dd996a6226f7be032bfedc23b1261093c0374e3

Meteor 에서 외부 Application으로 DDP 인증.

http://stackoverflow.com/questions/16729992/authenticating-with-meteor-via-ddp-and-srp Basic Auth로 websocket frame을 떠봤더니 o 1 오전 1:47:09 a["{\"server_id\":\"X43fG44wD7iJNCdoq\"}"] 42 오전 1:47:09 ["{\"msg\":\"connect\",\"version\":\"pre1\",\"support\":[\"pre1\"]}"] 69 오전 1:47:09 ["{\"msg\":\"sub\",\"id\":\"8jW8AaNcWf2iRhXWC\",\"name\":\"meteor.loginServiceConfiguration\",\"params\":[]}"] 110 오전 1:47:09 a["{\"msg\":\"connected\",\"session\":\"ZddaS7aatWT4i8nAR\"}"] 62 오전 1:47:09 a["{\"msg\":\"added\",\"collection\":\"users\",\"id\":\"aHC7AHZXbnhs7Efs9\",\"fields\":{\"username\":\"mone\",\"profile\":{\"photoSmall\"

intelliJ에서 actionscript3 사용시 외부 파일 문제.

source code 안에서 [Embed]를 사용하는 방법도 있지만 리소스를 실시간으로 로딩하여 초기 기동시간을 앞당기고 싶어서 Loader를 사용하여 swf를 실시간 로딩하였으나 데스크탑에뮬/iOS/Android가 각각 다르게 작동.     private var stageLoader:Loader; ..     stageLoader = new Loader();     stageLoader.load(new URLRequest("NoiseInfoSession01.swf")); 이런식으로 로드를 하려고 했더니 Error #2044: Unhandled IOErrorEvent:. text=Error #2035: URL Not Found. 오류 나신다. Project structure 에서 source를 추가했다. 기본은 src 폴더만 잡혀있는데 오른쪽 tree에서 loader에서 부를 swf가 있는 경로인 flash를 찍고 상단에 그 상단에 Sources 라고 써있는 부분을 클릭하면 Source Folders에 추가된다. 하지만 이게 전부가 아니다. 이 상태로는 장치에서 돌렸을때 역시 누락이 발생해서 URL오류가 난다. URL 경로가 잘못되었나 싶어서 봤더니 아니다. 아예 패키징할때 빠지는 현상이다. Android 와 iOS 탭 각각에 똑같이 추가할 파일들을 Path to file or folder 목록에 넣어주자. iPhone 5 대응용 Default-568h@2x.png 스플래시 파일도 동일한 요령으로 추가하면 된다. 보통 gitignore 할때 *.iml을 빼주곤 하는데 as3를 할땐 그래선 안된다. 위의 설정이 iml 파일안에 들어가므로 반드시 git 목록에 추가해놓자. 요약 1. 외부 파일은 Modules에서 Android/iOS 각각 추가 2. 데스크탑 에뮬을 위해 해당 폴더를 Sources에도 추가 3. iml도 형상관리

Renoise로 바닥부터 Sound Design (No Sample/No VST)

Renoise는 Ableton Live Standard 버전처럼 기본적으로 아무 악기가 없고 달랑 샘플러 하나가 전부인데 그마나 다행인건 멀티레이어라고나 할까. 샘플러만 있으면 사실 다 되지. 아날로그 웨이브 테이블을 최소단위로 넣어서 루프를 돌리면  되니까. 근데 그러면 무조건 폴리포니가 되어서 구조적으로 모노 신스는 구현이 불가능하다. 그것도 방법이 없는 건 아닌데 Bend 라든가 Glide 등등으로 하면 되니까. 그래도 모노 신스가 있었으면 좋겠는데 방법이 있더라. http://forum.renoise.com/index.php?/topic/27225-renoise-native-monophonic-synthesiser/  이 글을 보고 약간 충격을 받음. 이펙터만 있으면 역시 소리를 만들 수 있구나! 바로 시도에 들어감. 처음은 이런 상태. 나는 누군가. 여긴 어딘가. 키보드를 눌러도 아무 소리가 안난다. ESC 눌러서 첫번째 트랙 맨위에 Z(C-4 00) 하나 눌러 놓고 일단 플레이. 일단 이렇게 해놓고 소리가 날 수 있게 한단 말이지. 그럼 먼저 제네레이터. 일단 1byte짜리라도 뭐가 있어야 시작을 할 수 있으니 빈 샘플을 만들자. 1byte 짜리 빈 샘플을 만든다. 당연히 소리가 안난다. DC Offset을 만들어 00 인 상태를 바꿔보자. 퍽하고 클릭음이 생기면서 Master Scope 에 변화가 생겼다. Meter도 생겼다. 그런데 이건 소리라고 할 수 없다. RingMod(Ring Modulator)를 추가해보자. 오오 소리가 난다. 0인 경우엔 Ring Modulator를 적용해도 0으로 소용이 없지만 DC Offset으로 값을 변경한 후부터 Oscillator에 따라 파형이 생긴다. 기본적으로 440Hz의 음을 들을 수 있다. 무에서 유를 만들기는 했는데 Pitch도 Volume도 없다. 일단 Pitch부터 해보자. Key Tracker로 Destination을

Renoise 공부 - Recording Vocal / Interpolation / Multiple instance / Console

Renoise 는 기본이 Sample 를 Track에 찍는 것. 기준은 C4 일단 찍어놓고 LOOP을 돌리면서 shift+option+R 상태로 Sample Recorder를 기동 play 시 시작점을 지나지 않으면 소리가 나지 않는데 중간부터 재생해도 듣고 싶으면 Instrument Settings 에서 Auto seek을 활성화 해준다. Renoise AutoSeek 영상 참조. 연속된 값을 계속 채워 놓고 싶을때 처음과 끝만 써주고 cmd + I 로 밀어 넣는다. 복수개의 renoise 를 열고 싶을 때 - package 안쪽에 있는 renoise 를 직접 실행 Scripting Terminal & Editor 활성화 - Help / Show the Preferences Folder - config.xml ShowScriptingDevelopmentTools 항목 true. 저장 전 renoise를 닫을 것. - 재시작 후 tool 메뉴에서 확인 Multiple instance - /Applications/Renoise_Reg_Intel64.app/Contents/MacOS/Renoise - 혹은 open -n /Applications/Renoise_Reg_Intel64.app/ 전자는 log 를 볼 수 있고 후자는 그냥 실행한 것과 동일

Meteor 와 다른 언어/플랫폼과의 통신 수단인 DDP

Meteor 0.6.x 대부터 DDP 라는게 생겼는데 이걸로 Meteor application 과 다른 application 사이에 통신을 할 수 있는 인터페이스가 생겼다. Mobile 에서도 예외는 없는데 가령 websocket으로 직접 meteor 서버랑 붙어서 데이터를 교환하는게 가능. 이게 참 매우매우 강력하면서도 단순한 것이. collection에 subscribe 하는 것과 method 를 호출하는 것만으로 다른 언어에서도 meteor application처럼 쾌적하게 자료 교환을 할 수가 있다 :) DDP Spec. https://github.com/meteor/meteor/blob/master/packages/livedata/DDP.md 언어별 클라이언트 Node.js : https://github.com/alansikora/node-ddpclient Objective-C : https://github.com/alansikora/objective-c_ddp-client Ruby : https://github.com/tmeasday/ruby-ddp-client Java : https://github.com/kutrumbo/java-ddp-client Python : https://github.com/meteor/meteor/tree/master/examples/unfinished/python-ddp-client  (얘는 왜;;;) .NET : https://github.com/sonyarouje/DDPClient.NET

Meteor에서 REST API를 사용하는 방법 #2

server쪽 API를 router package를 사용해 쓰다보면 header 같은 걸 다루거나 할땐 너무 단순하게 만들어서 곤란할 수 있다. 이전에도 다룬 적( http://spectrumdig.blogspot.kr/2012/08/meteor-rest.html )이 있지만 __meteor_bootstrap__ 객체를 통해 접근하면 node.js 식의 접근이 가능하다. Meteor update와 함께 Npm 객체가 생겼으니 이를 이용해 connect 객체를 사용해보자 http://www.slideshare.net/cjoudrey/building-your-first-node-app-with-connect-express 위 슬라이드를 한번 보면 이해에 도움이 될 것이다. WebApp.connectHandlers 가 connect.createServer()라는 걸 기억하면 된다. connect = Npm.require 'connect' server = WebApp.connectHandlers server.use connect.router (app)-> app.get '/info', (req,res)-> res.end "info" app.get '/user/:id', (req,res)-> res.end "user id: #{req.params.id}" 이와 같은 코드를 server 디렉토리에 안에 넣거나 Meteor.isServer일때 실행하도록 하자. 파일 업로드나 쿼리 문자열 처리(ex: ?a=1&b=c)하려면 각각 bodyParser( http://www.senchalabs.org/connect/bodyParser.html ) 와 query( http://www.senchalabs.org/connect/query.html )를 추가하는 것이 좋다. 위의 해당 링크에 보면 소스까지 공개 해놓아서 이해하기 쉬우니

rvictl로 iOS Network packet을 보자.

iOS 5이후 부턴 USB로 장비를 연결하고 rvictl이란 명령으로 네트워크 패킷을 볼 수 있다고 한다. $ rvictl rvictl [-h][-l][-s <udid1> ... <udidN>][-x <udid1> ... <udidN>] Remote Virtual Interface Tool starts and stops a remote packet capture instance for any set of attached mobile devices. It can also provide feedback on any attached devices that are currently relaying packets back to this host. Options: -l, -L List currently active devices -s, -S Start a device or set of devices -x, -X Stop a device or set of devices 내용은 간단. UDID 입력하고 -s 로 시작 -l로 확인 -x로 정지. 한번 해보자 $ rvictl -s <UDID> Starting device <UDID> [SUCCEEDED] 이런 식으로 나오면 성공. USB연결을 꼭 확인하자. 참고로 iPhone Simulator 에서도 UDID만 있으면 작동한다는 이야기가 있음; 어디다 쓸진 모르겠지만;; 확인해보자. $ rvictl -l Current Active Devices: [1]  <UDID> 아까 그 UDID 가 목록에 있으면 성공. ifconfig 로 잘 들어갔나 확인해보자. $ ifconfig -l lo0 gif0 stf0 en0 p2p0 utun0 rvi0 rvi0이 들어갔으면 성공. $ ifconfig rvi0 rvi0: flags=3005<UP,DEBUG

Meteor 0.6.x 변경.

그동안 server-side 에서 fs 같은 객체를 쓰기 위해 @require = __meteor_bootstrap__.require 이렇게 만들어 썼었는데 이번 업데이트로 Npm을 정식지원하면서 require도 같이 변경되었습니다. @require = Npm.require 이렇게 쓰면 됩니다. https://github.com/meteor/meteor/blob/devel/History.md 참조

입코딩 : 비텍스트 파일에 대한 형상관리(CVS Problem with non-text files)

어렸을때 오락실용 게임을 만드는 회사에서 사운드관련 일을 한적이 있는데 당시 야마하 음원 칩을 쓰는 기판엔 음악 시퀀스를 텍스트로 받아서 미디를 텍스트로 바꿔서 올리는 툴을 만들었다. 만일 그 시절에 git+github 같은 툴이 있었다면 음원소스는 바이너리, 그 음원소스가 위치하는 메타 정보는 텍스트로 분리해서 음악관련 협업작업을 할 수도 있었을텐데 하는 생각이 들곤한다. 이건 사실 바이너리 형태인 모든 파일포멧의 한계랄까 어쩔 수가 없다. 사실 스프레드시트 같은 것도 csv 같은 경우는 텍스트라서 오토머지가 되거든. 나머지는 안되고. 오히려 xlsx 같이 XML 기반인 경우 압축해제만 하면 괜찮지. 생각해보면 xlsx, docx, pptx같은 XML 기반의 office 파일의 경우 저장 > 자동 압축해제 > COMMIT & PUSH 의 저장 기작과 FETCH > MERGE > office 생성 > 열기의 과정을 지원해주면 됨 실제로 말이 되게 하려면 XML간 Diff를 좀 친숙하게 기존 형식으로 비교해서 보여주면 될 것 같지만 배보다 배꼽이 더 큰 작업이 될 수도 있겠다 o><;; 비텍스트인 객체간의 차이를 보여주려면 골치 아플테고;; vba같은 스크립트로 만들어서 system명령을 호출하게 하는 방식으로 가능하게 할 수 있을 것 같긴 한데. 이 모든 난관을 다 극복하고 난 다음에도 여전히 형상관리 시스템에 대한 사용자 교육등등 극복해야할 과제는 남아있다. 간만에 입코딩을 했는데 돈 안되니까 일단 하지말자로 잠정 결론 짓는 걸로. 으하하. 가끔 뻘 개발이 하고 싶을때 이렇게 글로 가끔 풀어서 생각해보는 것도 나쁘지 않네. 입코딩으로 수천만원의 비용을 절약했어!

contentEditable 사용시 execCommand 에서 Selection 문제 해결법

contentEditable로 WYSWYG 에디터를 만들일이 있어서 하다보니 생각보다 까다로와서 기록해둔다. 먼저 javascript 구현체 http://jsbin.com/erukis/6/edit <!DOCTYPE html> <html> <head> <script src="http://code.jquery.com/jquery.min.js"></script> <link href="http://twitter.github.com/bootstrap/assets/css/bootstrap.css" rel="stylesheet" type="text/css" /> <link href="http://twitter.github.com/bootstrap/assets/css/bootstrap-responsive.css" rel="stylesheet" type="text/css" /> <script src="http://twitter.github.com/bootstrap/assets/js/bootstrap.js"></script> <meta name="description" content="mobile" /> <meta charset=utf-8 /> <meta name="viewport" content="width=device-width, initial-scale=1.0"/> <title></title> </head> <body>   <div class="edit" contentEditable="true">     여기를