[Golang] SMTP를 이용한 메일 보내기

Go는 기본으로 제공하는 net//smtp 패키지를 통해 메일을 보낼 수 있습니다. 아래의 코드는 MicroSoft의 Live를 통해 메일을 보내는 코드입니다.

package main

import (
    "fmt"
    "net/smtp"
)

func main() {
    auth := smtp.PlainAuth("", "hjkim@geoservice.co.kr", "@pw", "smtp.live.com")

    from := "hjkim@geoservice.co.kr"
    to := []string{"korea.gisdeveloper@gmail.com", "geoservice@naver.com"}

    headerSubject := "Subject: 아기공룡 둘리 ㅡ 강민규\r\n"
    headerBlank := "\r\n"

    body := `
        요리 보고 저리 봐도 음음 알 수 없는 둘리~ 둘리~ 
        빙하타고 내려와 음음 친구를 만났지만 

        일억년전 옛날이 너무나 그리워 
        보고픈 엄마찾아 모두함께 나가자 하아 하아 

        기쁠때도 슬플때도 음음 우리 곁엔 둘리~ 둘리~ 
        오랜세월 흘러온~ 둘리와 친구되어 

        고~향은 다르지만 모두가 한마음 
        아득한 엄마나라 우리 함께 떠나자~ 하아 하아 

        <후렴> 
        외로운 둘리는 귀여운 아기공룡 
        호이 호이 둘리는 초능력 내친구(재주꾼) 
        호이 호이 호이 호이  
    `

    msg := []byte(headerSubject + headerBlank + body)

    err := smtp.SendMail("smtp.live.com:587", auth, from, to, msg)
    if err != nil {
        panic(err)
    }

    fmt.Println("done")
}

9번 코드에서 smtp 서버의 주소로 smtp.live.com를 지정했으며, 이 서버의 계정(hjkim@geoservice.co.kr)과 암호(@pw)를 지정합니다. 그리고 12번 코드에서 메일을 받을 주소를 배열을 통해 지정할 수 있습니다. 그리고 14번에 메일의 제목을, 17번에서 메일의 내용을 입력하고 이 제목과 내용을 36번 코드에서처럼 하나의 바이트 배열루 묶습니다. 이렇게 묶은 바이트 메일을 38번 코드를 통해 전송하면 됩니다.

의심, 근심 그리고 욕심

“혹자는 의심은 마음의 고름이고, 근심은 마음의 주름이며 욕심은 마음의 기름이라고 했다. 고름과 주름 그리고 기름은 그 사람의 몸과 마음을 상하게 한다. 의심은 호기심으로, 근심은 관심으로, 욕심은 동심으로 달리 마음을 바꿔 몸과 마음을 건강하게 해야 할 것이다.”

[GIS] FingerEyes-Xr for HTML5 ㅡ Code로 GraphicLayer에 마커 추가하기

FingerEyes-Xr은 그래픽 레이어를 통해 지도 상의 원하는 위치에 다양한 그래픽 요소를 추가해 표현할 수 있는데요. 이와 관련된 API를 정리해 봅니다. 그래픽 요소를 추가하기 위해서 그래픽 레이어가 하나 필요합니다. 아래의 코드를 통해 그래픽 레이어를 추가합니다.

var gfxLyr = new Xr.layers.GraphicLayer("g");
map.layers().add(gfxLyr);

그래픽 레이어의 이름을 ‘g’로 하여 이 이름을 통해 그래픽 레이어 객체를 얻을 수 있습니다. 이 그래픽 레이어에 마커를 3개 추가할 것인데요. 아래의 코드처럼 마커를 추가하는 함수를 만들어 사용하겠습니다.

function addPoint(gl, id, x, y, imgUrl) {
    var rs = gl.rowSet();
    var p = new Xr.PointD(x, y);
    var psd = new Xr.data.PointShapeData(p);
    var pgr = new Xr.data.PointGraphicRow(id, psd);
    var ims = new Xr.symbol.ImageMarkerSymbol({
        width: 48, height: 48,
        url: imgUrl
    });

    pgr.markerSymbol(ims);

    rs.add(pgr);
}

위의 addPoint 함수는 총 5개의 인자를 받습니다. 첫번째 gl은 그래픽 레이어 객체이고, id는 추가할 마커 그래픽 요소의 id값이며, x와 y는 마커가 위치할 좌표.. 끝으로 imgUrl은 마커를 지도 상에 표시할때 어떤 이미지로 표시할지에 대한 이미지 URL에 대한 문자열입니다. 이제 다음 코드처럼 3개의 마커 그래픽 요소를 추가할 수 있습니다. 아래의 코드는 버튼의 이벤트 함수 안이나.. DB 서버로부터 어떤 조회가 완료되었을 때 호출되는 함수에 위치하면 될 것입니다.

var gl = map.layers("g");

addPoint(gl, 0, 938085, 1671020, "http://www.gisdeveloper.co.kr/images/pikachu.png");
addPoint(gl, 1, 938185, 1671020, "http://www.gisdeveloper.co.kr/images/pokeball.png");
addPoint(gl, 2, 938285, 1671020, "http://www.gisdeveloper.co.kr/images/weedle.png");

map.coordMapper().moveTo(938185, 1671020).zoomByMapScale(4000);

map.update();

이제 실행하면 다음 화면처럼 이미지 마커가 3개 표시된 것을 볼 수 있습니다.

여기서 좀더 진행해.. 이제 위의 3개의 마커를 클릭했을 때 정보창을 표시하도록 하겠습니다. 지도의 클릭 이벤트를 아래처럼 등록하는데요. 지도에 대한 map 객체를 얻어 온 코드 다음에 아래의 코드가 있으면 됩니다.

map.addEventListener(Xr.Events.MapClick, onMapClick);

이제 지도를 클릭할 때 onMapClick 함수가 호출되는데요. onMapClick 함수는 아래와 같습니다.

function onMapClick(e) {
    var gl = map.layers("g");
    var ids = gl.IdByMousePoint(e.viewX, e.viewY, true); // bOnlyOne
    var cntIds = ids.length;

    if(cntIds == 1) {
        var id = ids[0];
        var row = gl.rowSet().row(id);
        var ims = row.markerSymbol();
        var url = ims.url();

        gl.hilighting(id);

        var content = "";

        var infoWin = new Xr.ui.InfoWindowControl("iwc", map,
            new Xr.PointD(e.mapX, e.mapY), content, {  });

        map.userControls().remove("iwc");
        map.userControls().add(infoWin);
    }
}

3번 코드에서 IdByMousePoint 함수의 3번째 인자는 클릭 지점에 여러개의 그래픽 요소를 발견했다고 해도, 단 하나만을 얻겠다는 의미입니다. 이제 실행하고 지도 상에 표시된 마커 그래픽을 클릭하면 다음과 같은 결과를 볼 수 있습니다.

사용자 삽입 이미지

[Golang] JSON 인코딩(Encoding)과 디코딩(Decoding)

Text 기반의 데이터교환 및 전송을 위한 가장 최적화된 표준 포맷으로 JSON을 뽑을 수 있는데요. Go에서는 map이나 struct 타입 객체에 대해 JSON 문자열로 인코딩할 수 있습니다. 여기서 map의 경우에는 그 key의 타입이 string이 아닌 경우 해당 타입을 string으로 변환이 가능할 경우에만 JSON 인코딩이 가능합니다. 다음 코드는 사용자 정의 struct에 대한 map 객체를 인코딩하는 예제입니다.

package main

import (
    "encoding/json"
    "fmt"
)

type Detail struct {
    Age    int
    Active bool
}

func main() {
    mem := map[string]Detail{
        "Alex":    {10, true},
        "Dip2K":   {20, true},
        "Jackass": {15, false},
    }

    jsonBytes, err := json.Marshal(mem)
    if err != nil {
        panic(err)
    }

    jsonString := string(jsonBytes)

    fmt.Println(jsonString)
}

위의 코드를 실행하면 다음과 같은 결과를 볼 수 있습니다.

{"Alex":{"Age":10,"Active":true},"Dip2K":{"Age":20,"Active":true},"Jackass":{"Age":15,"Active":false}}

이제 다시 위에서 얻는 JSON 문자열을 객체로 인코딩해 보도록 하겠습니다. JSON 문자열을 다시 인코딩하기 위해서는 json.Unmarshal 함수를 사용합니다. 예제는 아래와 같습니다.

package main

import (
    "encoding/json"
    "fmt"
)

type Detail struct {
    Age    int
    Active bool
}

func main() {
    jsonString := `
        {
            "Alex":{"Age":10,"Active":true}, 
            "Dip2K":{"Age":20,"Active":true},
            "Jackass":{"Age":15,"Active":false}
        }`

    mem := make(map[string]Detail)
    err := json.Unmarshal([]byte(jsonString), &mem)
    if err != nil {
        panic(err)
    }

    fmt.Println(mem)
    fmt.Println("Dip2K's Active:", mem["Dip2K"].Active)
}

위의 코드에서 14번에 긴 문자열을 jsonString 변수에 담고 있는데요. 긴 문자열을 Go언어에서 입력하기 위한 방식으로 14~19번 코드를 주의해 보시기 바랍니다. 실행 결과는 다음과 같습니다.

map[Dip2K:{20 true} Jackass:{15 false} Alex:{10 true}]
Dip2K's Active: true