LuaSocket

in-house 툴에서 주어진 데이터를 확인하고 결과 내용을 메일로 전송할 일이 생겼는데, 간단한 툴이기 때문에 그냥 100% 루아로만 작성해보고 싶었다. 그래서 lua 자체로 메일 보내는 기능을 찾아봤는데, LuaSocket을 이용하면 쉽게 보낼 수 있더라. 별도로 다운받아서 빌드해 사용할 수도 있지만 Lua For Windows를 설치하면 자동으로 같이 설치된다.

사용법은 정말 별것이 없다. SMTP 소개 페이지에 있는 샘플 코드 복사해다가 실행시키면 그냥 실행됨 –_-)b 다만 메일에 한글을 쓰려고 하니 제대로 동작하지 않는다. – 그것이 이 글을 적는 이유이기도 하다 – utf-8 인코딩으로 텍스트를 보내고 싶다면 아래 코드를 참고하면 된다.

local smtp = require("socket.smtp")
local ltn12 = require("ltn12")
local mime = require("mime")

local function headerencode(src)
    return "=?UTF-8?B?" ..
        ltn12.source.chain(
            ltn12.source.string(src),
            ltn12.filter.chain(
                mime.encode("base64"),
                mime.wrap()
            )
        )() ..
        "?="
end

local mesgt = {
    headers = {
        From = headerencode('あわわわ') .. " ",
        To = headerencode('あわわわ') .. " ",
        Subject = headerencode("日本語の件名"),
        ['Content-Type'] = 'text/plain; charset="UTF-8";',
        ['Content-Transfer-Encoding'] = 'base64',
    },
    body = ltn12.source.chain(
        ltn12.source.string("日本語の本文も送信できます."),
        ltn12.filter.chain(
            mime.encode("base64"),
            mime.wrap()
        )
    )
}

assert(smtp.send{
    from = "",
    rcpt = "",
    source = smtp.message(mesgt),
    server = 'localhost'
})

코드는 여기에서 가져와서 indentation만 수정했음.

lua 자체에서 메일 보내는게 어려우면 python이나 powershell로 단계적으로 넘어가려고 했는데, 이 정도면 충분히 만족 :)

Posted by leafbird 트랙백 0 : 댓글 0

댓글을 달아 주세요

작업하면서 요긴했던 팁들을 이 포스트에 꾸준히 업데이트. 우선 오늘 알아낸 것 부터.

lua에서 현재 작업경로(working directory) 알아내기.

val = io.popen( 'cd' ):read( '*line' )

 
io.popen() 함수를 알면 이해할 수 있다. 인자로 받은 다른 프로세스를 실행하고, 그 프로세스의 출력물을 얻어오는 함수. PIL책에는 언급 되어있지 않지만 레퍼런스에 설명이 정리되어 있다. ( http://www.lua.org/manual/5.1/manual.html#pdf-io.popen )

 
Posted by leafbird 트랙백 0 : 댓글 0

댓글을 달아 주세요

------------------------------------------------------------------------------------------------
-- 테스트 프레임웍

DataTest = {
    totalCount = 0,
    success = 0,
    fail = 0,
}

function DataTest:Check( cond, ... )

    self.totalCount = self.totalCount + 1

    if not cond then
        self.fail = self.fail + 1
        print( string.format( ... ) )
        return false
    end

    self.success = self.success + 1
    return true

end

function DataTest:Dump()
    return string.format( "총 테스트 개수 : %d \n 성공 : %d \n 실패 : %d \n",
        self.totalCount,
        self.success,
        self.fail )
end

function DataTest:FinalReport()

    if self.fail == 0 then
        print( string.format( "%d개의 테스트를 모두 통과했습니다.", self.totalCount ) )
    else
        error( string.format( "%d개의 테스트중 %d개가 실패했습니다.", self.totalCount, self.fail ) )
    end

end

------------------------------------------------------------------------------------------------
-- 실제 테스트 진행

function TestValidation()
  
    local a = 1
    local b = 2

    DataTest:Check( a == 1, '데이터의 값이 유효하지 않습니다. a : %d', a )
    DataTest:Check( a == 2, '데이터의 값이 유효하지 않습니다. a : %d', a )
    DataTest:Check( a == b, '값이 동일하지 않습니다. a : %d, b : %d', a, b )

end

TestValidation()

------------------------------------------------------------------------------------------------
-- 테스트 결과 출력

print( DataTest:Dump() )

DataTest:FinalReport()

루아의 유닛테스트 프레임워크가 몇가지 되는데, 루아 위키에 잘 정리 되어 있다 ( http://lua-users.org/wiki/UnitTesting ) 이 중에서 가장 쓸만한 건 위키 페이지에도 가장 디테일하게 설명된 LuaUnit이 괜찮아 보임. LuaUnit은 초기에 류광님이 제작한 버전에서 개선된 코드인 듯 하다. 나중에 로직 테스트할 때 사용해볼 예정.

루아 포맷으로 제작된 데이터의 유효성을 검사하기 위해 유닛테스트 프레임웍을 사용해 볼까 하고 검색을 좀 해봤다. 일단은 괜찮은 프레임워크 찾아서 붙여두고 데이터 체크만 먼저 해두었다가, 나중에 같은 코드 써서 로직 유닛테스트까지 같이 하려고 했는데, 데이터 검증에는 유닛테스트 프레임워크가 좀 안 맞는 것 같아서 그냥 간단히 제작했다.

setup / teardown 같은 것도 필요 없고, suit 묶음은 있으면 좋겠지만… 이런 것도 굳이 필요는 없고, 데이터 체크에 필요한 기능은 딱 세가지.

  1. 체크리스트를 통과 못한 데이터에 대해서 기획자가 쉽게 읽을 수 있는 한글 코멘트를 적을 수 있을 것.
  2. 체크리스트 개수, 실패/성공 개수 등을 나중에 리포트 받을 수 있을 것.
  3. cpp에서 스크립트를 실행하고 나서 테스트 통과 / 실패 여부를 확인할 수 있을 것.

… 이것만 있으면 충분했다. 처음엔 만드는데 오래 걸릴 줄 알고 피했는데 막상 필요한 기능만 짜보니 금방 끝난다.

루아 짱.

Posted by leafbird 트랙백 0 : 댓글 0

댓글을 달아 주세요

lua syntax 컬러링 해주는 애드인.

vs2008용은 아래 링크에서 다운로드.

http://vslua.codeplex.com/

vs2010에서는 이번에 새로 추가된 확장 관리자(Extension Manager) 방식으로 제공된다.

http://visualstudiogallery.msdn.microsoft.com/7af51f37-07ad-4d6b-9c2b-00672bb051ad/

예전에 다른 종류의 어떤 애드인을 잠깐 설치했었다가,
block comment ( --[[ ... ]] ) 의 컬러링을 제대로 지원 못해서 바로 삭제한 적이 있는데
이건 깔끔하게 잘 된다.

추천 -_-)b

Posted by leafbird 트랙백 0 : 댓글 2

댓글을 달아 주세요

  1. addr | edit/del | reply Favicon of https://blueasa.tistory.com BlogIcon blueasa 2011.05.22 01:48 신고

    좋은 정보 감사합니다. :)

    • addr | edit/del Favicon of https://devnote.tistory.com BlogIcon leafbird 2011.05.23 23:51 신고

      아... 네 ㅎㅎ
      근데 제가 지금 이거 쓰고 있는 중인데요,
      이녀석도 가끔 블록 코멘트 (--[[ ]])의 컬러를 제대로 처리 못 해주는 경우가 있더군요.
      이상하게 루아 컬러링 애드인들은 다 그쪽 기능에 문제가 있네요. 그게 딱히 어려운거 같지도 않은데...
      참고 하세요 ^^;

사용자 삽입 이미지


코드는 lua_tinker의 샘플에 있는 코드를 토대로 내가 조금 수정했다.

예전에는 콘솔에서 프롬프트를 출력하고 대화형 IO 처리를 하기 위해서 적지 않은 분량의 코드를 직접 작성했는데
이제는 lua_interpreter 갖다 붙이고, 도움말 출력 코드도 직접 작성하는 대신 위에 있는 저 lua 함수를 쓰고나니 이제 콘솔 인터페이스는 전혀 신경쓸것 없이 메인 로직만 작성하면 그만이다.

devnote 블로그에서 console IO 처리를 위한 코드를 올려 두었었는데, 이제 아무짝에도 쓸모없겠군 +_+...
Posted by leafbird 트랙백 0 : 댓글 0

댓글을 달아 주세요

[lua] objinfo

2008. 3. 8. 12:05 from 프로그래밍 팁/lua
lua_tinker 0.5b 예제(sample3.lua) 에 나왔던 유틸리티 함수.


-- 어떠한 객체의 metatable을 통해 등록된 클래스와 그 함수들을 살펴보는 함수
-------------------------------------------------------------------------------
function objinfo(obj)

    local meta = getmetatable(obj)
    if meta ~= nil then
        metainfo(meta)
    else
        print("no object infomation !!")
    end
end

function metainfo(meta)

    if meta ~= nil then
        local name = meta["__name"]
        if name ~= nil then
            metainfo(meta["__parent"])
            print("<"..name..">")
            for key,value in pairs(meta) do 
                if not string.find(key, "__..") then 
                    if type(value) == "function" then
                        print("\t[f] "..name..":"..key.."()")
                    elseif type(value) == "userdata" then
                        print("\t[v] "..name..":"..key)
                    end
                end
            end
        end
    end
end
-------------------------------------------------------------------------------
Posted by leafbird 트랙백 0 : 댓글 0

댓글을 달아 주세요