Mashup.OpenAPI2008.12.11 16:34

NHN-Daum, ‘2009 대한민국 매쉬업 경진대회’ 공동 개최  

올해 겨울에도 어김없이 매쉬업 경진대회가 시작 되었습니다. 더욱 풍성해진 행사 더 많아진 OpenAPI 그리고 이번에는 12월에 비발디에서 매쉬업 스키캠프 까지 예정으로 있다고 합니다.  

 

작년에 2회째 대회에 나가서, 여러 행사에 참여 하며 정말 많은 사람들을 만나며, 배운것 같습니다. 오픈 API 를 다루는게 처음이신 분들도 비교적 쉽게 접근할수 있고, 기존에 데이터가 없는 상태에서 멋진 컨텐츠를 만들수 있다는 것이 매쉬업에 가장 큰 매력이라 생각 합니다.  

금년에도, 많은 사람들과, 생각을 공유하고 좀 더 기발하고 멋진 작품들이 나왔으면 합니다.  

공식 홈 페이지 : http://mashupkorea.org/  

동강의 작년과 재작년 매쉬업 대회 리뷰
이태호님의 2009 매쉬업 경진대회가 열립니다. 
동강의 2008 대한민국 매쉬업 경진대회 출품작 : Yahweh Mini bible

 

Posted by Flash 동강
Mashup.OpenAPI2008.12.11 13:13

웹 2.0 이다. Openapi 라 해서 매쉬업 컨텐츠를 만들어야 된다는 말이 여기 저기에서 나오고 있습니다. 하지만 정작 매쉬업이 어떤 의미를 가지고 있는지에 대해 모르시는 분들이 많은것 같아서, 간단하게 Flash 로 만들어 보는 매쉬업 이라는 주제로 이야기를 해 볼까 합니다.

 우선 매쉬업 이란? 출처 : http://mashupkorea.com/2008/faq

매쉬업(Mashup)이란 여러 데이타 소스들을 가지고 한개이 웹 페이지를 구성하거나, 여러 기능을 하나의 어플리케이션에서 제공하도록 만드는 것을 말합니다. 여러 데이터 소스들은 Daum과 같은 오픈 API를 제공하는 회사에서 RSS, XML 등의 데이터 형식으로 가져오게 됩니다. 매쉬업은 이용하면 축적된 데이터 없이도 창의적인 서비스를 빠르게 만들어 볼 수 있습니다. 사용자들에게는 한번에 여러 서비스를 이용할 수 있도록 도와 줍니다.

매쉬업 서비스는 이미 만들어져 있는 여러 서비스들을 섞어 만들게 됩니다. 대개 웹 서비스를 처음 만들때는 축적된 기반 데이터가 없는 것이 일반적입니다. 따라서 매쉬업 서비스를 만든다는 것은 기존 서비스 제공자들이 제공하는 데이터 기반 위에 독특하고 창의적인 아이디어나 서비스를 여러 가지 각도로 실험해 볼 수 있습니다. 이를 통해 초기 비용을 절감할 수 있습니다.

또한 매쉬업은 자신이 만든 핵심 서비스에 부가 기능으로 기존 회사들의 API를 사용할 수 있습니다. 이렇게 함으로서 핵심 서비스에만 집중할 수 있게 해 줍니다. 해외에서는 기존 API 제공 회사와 3rd Party가 비지니스적으로 유기적인 관계를 맺고 다양한 매쉬업 사례가 나오고 있습니다.   

요약해서 말하면, 이미 기업에서 만든 공개한 API  여러개를 믹스해서 새로운 컨텐츠를 만드는 것을 의미 합니다. 예를 들어 기존에 부동산 사이트 에서는 간단하게 텍스트로 된 주소와 이미지 밖에 제공 되지 않았지만 구글 맵이나 네이버 맵을 연동하여 위치를 정확하게 보여 주어 사용자의 편의를 높이는 컨텐츠를 만들 수 있습니다.   

그러면 제공 되는 Openapi 는 어떤 것들이 있는가? 굉장히 많습니다. 대한민국에서 제공 되는 api 는 네이버api다음api을 중심으로한 검색 API 가 주를 이루지만, 구글에서 제공 하는 api 만 해도 굉장히 많고 다양한 종류가 있다는 것을 알 수 있습니다.   

이런 Openapi 를 어떻게 Flash 로 이용하는 것인가?

이용 하는 방법은 여러가지가 존재 하고 있지만, 기본적으로 api 를 제공 하고 있는 서버에 요청을 보내고 그 요청에 대한 응답을 받는 형식과(REST방식),  블로그에 글 쓰기 와  같은 서버 측에 xml 파일을 전송하여 서버에 데이터를 저장하는 XML-RPC 방법이 주로 사용 됩니다. 여기에서 제가 다룰 내용은 REST 방식을 이용한 검색 부분 입니다.  

앞으로의 진행을 수월하게 따라 가기 위해서는 Actionscript3.0 에서의 XML 클래스와 Loader 클래스에 대한 이해가 필요 합니다. Loader 클래스에 대한 내용, XML 클래스에 대한 내용은 레퍼런스를 참고하세요.  

우선 사용할 API 는 네이버의 이미지검색 API 입니다. 이 API 를 사용하기 위해서는 http://openapi.naver.com/register.nhn 에서 API 사용 KEY 를 받으셔야 합니다.  

API KEY 까지 받으셨다면 다음 글 부터 시작해 보겠습니다.

Posted by Flash 동강
Mashup.OpenAPI2008.12.11 12:37

2007년에 매쉬업 경진대회를 준비 하고 컨퍼런스와 엑스포 등등 여러 행사를 구경 다닌지가 어그제 같은데 벌써 5월 입니다. 2007년 출품작들과 수상작들 그리고 해외 매쉬업을 보면서 이것 저것 아이디어를 생각해 보았는데, 역시,,,, 잘 생각나지 않았던건, 웹이라는 공간 자체가 이미 없는것 없는 찾아 보면 이미 있던 것들 뿐이라 더 그랬는지도 모르겠습니다.  

오랜만에 매쉬업 공식 사이트(http://mashupkorea.org/) 에 방문하니 2009 년 매쉬업에 대한 포스팅이 올라 와서 그에 자극을  받아 '내가 본 2007-2008 매쉬업 경진 대회' 라는 글을 써 볼까 한다. 2008 매쉬업 컨퍼런스에 참가 했을 당시 2007 년 대상 수상작인 '거침없이 글짓기' 에 대한 프리젠테이션이 있었다. 


웹이 라는 광대한 DB 를 최대한 활용한 누구나 그 DB 를 사용하겠다는 생각을 하지만, 이런 식으로 사용 하겠다는  생각이나 할 수 있을까? 실제로 서비스로 내 놓아도 손색없을 정도의 아이디어와 실용성을 자랑 하였다.  입이 쩍~! 다만 속도의 문제가 있었지만, 매쉬업 이란 이런 것이로 구나 하는 생각을 들게 한 작품이었다. 단순한 아이디어 지만, 영어 공부 도우미 라는 많은 사람들이 원하는 영작도우미라는 아이디어에서 시작해서 웹이라는 거대한 DB 를 활용한 최고의 작품이었다.

 2007 대한민국매쉬업 경진대회 우수상
네이버 카페 플생사모(http://cafe.naver.com/flashdev.cafe) 에서 스카야마 라는 아이디로 활동중인 서희만 군 적은 나이임에도 불구 하고 Flash 에 대한 열정과 새로운 것에 대한 열정은 남들에게 뒤지지 않아 보인다.  

Lump Of Thought 역시, 매쉬업이라는 키워드를 잘 맞추고 있다. '무엇을 보여 주는가?' 와 함께 '어떻게 보여 주는가? ' 에 초점을 두어 사용자들의 시각을 자극한다. 검색의 특징중 하나인 '연관검색' 에 최대한 촛점을 맞춰서 자신의 검색한 대상에 대한 연관된 대상을 지속적으로 이어 나갈 수 있게 해 놓았다. Flash 로 만들어져 서비스 뿐만 아니라, UI 에도 많이 신경쓴게 보이는 작품 이었다.  

2008 대한민국 매쉬업 경진대회 우수상
Daum Devday 때 같이 프로젝트 하면서 알게된 NAuction 을 만드신 오창훈 님 (http://lovedev.tistory.com)

 

 매쉬업 작품을 출품하기 전에 플생사모에 미리 올라온 NAuction 을 보고 기가 죽어서 시무룩 해 있던게 생각난다. 기존 쇼핑 사이트의 복잡한 페이지 이동과, 리뷰가 빈약한 점을 최대한 공약한 NAuction metoday 와 연동하여 해당 상품에 대한 리뷰를 미투데이에 작성하여 구매의 편리함을 더 해 주고 있다. AIR 라는 데스크톱 어플리케이션이라는 특징을 활용하여, 사람들에게 지름신을 내려 주시는 Flex 기반(?) 매쉬업 작품이었다.  

2008 대한민국 매쉬업 경진대회 장려상


1회 , 2회 연속 수상에 빛나는 이태호 님의 Text Grinder 개인적인 생각으로 2008 출품 작중 가장 뛰어난 퀄러티를 자랑하고 있다. 다만,,,,,, 기능이 너무 많아 뭐가 뭔지 모르겠다는 단점이 있다.;;;;  (이태호님 죄송;; ) 기억에 남은 기능중 하나는 검색을 하여 검색된 문서를 자신이 소장할수 있게 HTML 로 저장할 수 있다. 

같은 학교 선배가 만든 Bookmate , 서울시내에 있는 도서관 통합검색 뿐만 아니라

 
도서관에 있는 도서 정보를 제공하고 종고 거래 서비스를 할수 있게 되어 있다. 도서 구매의 목적이 아니라 서울시에 있는 도서관에 대한 도서정보를 간편하게 검색하는건 물론이고, UI 적인 편안함도 제공한다. 

2008 년 대한민국 매쉬업 경진대회 대상작 aFeeLog , 본선에 진출하고 aFeeLog 를 만든 선배에게 '장려상이나 타면 다행이죠' 라고


말 했었는데, 설마 설마... 대상을 타 버렸다. 기존에 블로그에 있는 음악들을 블로그 파싱을 통해 음원만 끌어 오는 방법으로 음악 서비스를 제공한다. 또한 사용자들의 참여로 인해 날씨에 따른 감성이 축적되고 그 축적된 DB 는 감성에 맞는 추천음악을 제공할수 있게 만들어 놓았다.  

2008 년 대한민국 매쉬업 경진대회 특별상 '다음 블로그 API 상' - Yahweh


기독교 인들을 대상으로한 성경 공부 프로그램이다. 로컬 DB 안에 저장되어 있는 성경으로 성경책이 필요 없으며 각 성경 구절에 대한 자신의 생각을 적는 큐티(?) 라는 기독교인이 성경 공부 하는 작업을 할수 있다. 자신의 생각을 적는 곳은 자신의 다음 블로그에 기록이 된다. 또한 개인 사용자들은 자신의 주소를 프로그램에 입력함으로서 어느 지방에 누가 이런 생각을 적었는지 알수 있으며, 즉석만남(?) 도 가능 할것 같다는 생각을 하며 만들었다.  

2007-2008 년 출품작은 무수히 많았지만 지극히 개인적으로 기억에 남는 것들을 정리해 보았다. 이번 대회를 통해 놀랄 만한 아이디어도 볼수 있었고, 퀄러티도 느낄 수 있었다. 그리고 무엇 보다 열정을 느낄수 있었다. 많은 행사를 통해 Openapi 와 매쉬업을 전달해 주신 대회 관계자분들께 감사하단 말을 드리고 싶다.   

또한 행사가 끝난지는 오래 되었지만, 숭실대학교 미디어학부에서 2008 매쉬업 경진대회 '대상' 과 '특별상' 이 모두 나왔다는게 자랑 스럽다. 2009년 새로운 매쉬업 경진대회를 기대하며, 그때 까지 아이디어 구상을...ㄷㄷㄷ

Posted by Flash 동강
Mashup.OpenAPI2008.12.11 12:04

매쉬업 경진 대회에 이어 다음 Dev Day 를 갔다 왔습니다. 구현의 목적이 아니라, 여러 사람이 자신의 생각을 공유 할수 있는 장이 된거 같아서 좋았습니다. 푸짐한 아웃백 점심식사와, 푸짐한 경품들,, 코딩하는 동안 삽질만 한거 같지만 즐거운 토요일 이었습니다. 6월에 있을 Dev day 가 또 기다려 지네요.ㅎ  

오늘 다음 Dev Day 2008 에 가서 팀들과 함께 만든 다음 블로그 어플리케이션 입니다. 기존의 다음 블로그를 사용하시는 분이 브라우져를 거치지 않고 자신의 블로그의 정보를 메신져 형태로 알수 있게 해 주는 프로그램입니다. 싸이를 하시는 분이라면 네이트온 메신져의 "새글 알림이" 라고 생각하시면 되겠네요. 아직 구현 단계라 스샷과 메인 소스만 첨부 합니다.ㅎ
Flex ㅋㅋ 하면 할수록 매력 적인데, 쉽지 않네요;;; Flash 하던데로 하면 되겠지 하면서 진행했는데 곳곳에서 삽질 ...

5시간 동안 삽질만 한거 같습니다;; 

 

자신의 블로그 정보를 알려 줍니다. 댓글이 달렷을 경우 위와 같은 창으로 표시해 줍니다.

자신의 블로그에 Posting 하는 창 


 글을 읽어 보는 부분 

 
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="init()" width="420" height="541" xmlns:component="component.*" borderColor="#FBFBFB" themeColor="#F7F9FB" horizontalScrollPolicy="off" verticalScrollPolicy="off">
  3.         <mx:Script>
  4.                 <![CDATA[
  5.                 import mx.controls.List;
  6.                 import mx.events.FlexEvent;
  7.                 import mx.collections.ArrayCollection;
  8.                 import mx.containers.VBox;
  9.                 import mx.controls.Text;
  10.                 import mx.core.Container;       
  11.                 import flash.display.Sprite;
  12.                 import flash.events.Event;
  13.                 import data.db.SettingManager
  14.                 import blog.read.ReadList;
  15.                 import blog.read.ReadContents;
  16.                 import blog.read.ReadComment;
  17.                
  18.                 import mx.controls.Alert;
  19.                 import component.LoginPanel;
  20.                 import blog.write.WriteContents;
  21.                 import component.CompleteButton;
  22.                 import blog.login.BlogLogin;
  23.                 import com.adobe.air.notification.NotificationClickedEvent;
  24.                 import com.adobe.air.notification.Purr;
  25.                 import com.adobe.air.notification.AbstractNotification;
  26.                 import com.adobe.air.notification.Notification;
  27.                        
  28.                 public var resultList:XML;
  29.                 public var resultContents:XML;
  30.                 public var resultComments:XML;
  31.                        
  32.                 private var Postwrite:WriteContents = new WriteContents();
  33.                 private var settingManager:SettingManager;
  34.                
  35.                 public var tmpObj:Object;
  36.                 private const iconURL: String = "128_128.png";
  37.                 private var bmp: Bitmap = null;
  38.                 private var count:uint;
  39.                 private var timer:Timer;
  40.                 private var purr:Purr = new Purr(1);
  41.  
  42.                
  43.                 private function init():void
  44.                 {
  45.                         settingManager = new SettingManager();
  46.                        
  47.                         tmpObj = new Object();
  48.                        
  49.                                
  50.                         login_mc.addEventListener(MouseEvent.CLICK, onLoginhandler);
  51.                        
  52.                        
  53.        
  54.                
  55.                        
  56.                 }
  57.                 private function completeHandler(evt:Event):void{
  58.                                
  59.                                 bmp = Bitmap(Loader(evt.target.loader).content);
  60.                                 purr.setIcons([bmp.bitmapData], "This is tooltip");
  61.                                 var m: NativeMenu = new NativeMenu();
  62.                                 m.addItem(new NativeMenuItem('Show'));
  63.                                 m.addItem(new NativeMenuItem('Close'));
  64.                                 purr.setMenu(m);
  65.                                 showNoti("새글이 올라왔습니다.");
  66.                         }
  67.                        
  68.                         private function ioErrorHandler(evt:Event):void{
  69.                                
  70.                         }
  71.  
  72.                
  73.                         private function showNoti(str:String):void{
  74.                                 var icon:Bitmap = bmp;
  75.                                 purr.addTextNotificationByParams("DaumDesktop for DevDay", str, AbstractNotification.BOTTOM_RIGHT, 5, icon);
  76.                                
  77.                         }
  78.                
  79.                 private function onSendhandler(evt:MouseEvent):void
  80.                 {
  81.                         Postwrite.contentsWrite(post_mc.title_txt.text,post_mc.contents_txt.text,"tag");
  82.                
  83.                 }
  84.                 private function onLoginhandler(evt:MouseEvent):void
  85.                 {
  86.                         var popLogin:LoginPanel = new LoginPanel();
  87.                         popLogin.x = 90;
  88.                         popLogin.y = 100;
  89.                         addChild(popLogin);
  90.                        
  91.                 }
  92.                 public function onCompleteHandler(event : Event) : void {
  93.                                 var loader:Loader = new Loader();
  94.                                 loader.load(new URLRequest(iconURL));
  95.                                 loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);
  96.                         loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
  97.                            
  98.                         timer = new Timer(3000, 1);
  99.                                 timer.addEventListener(TimerEvent.TIMER,
  100.                                         function(e:TimerEvent):void{
  101.                                         purr.alert(NotificationType.INFORMATIONAL, NativeApplication.nativeApplication.activeWindow);
  102.                                         });
  103.                                
  104.                                
  105.                                 resultList = event.target.respond_list;
  106.                                 drawList();
  107.                                 event.target.removeEventListener(Event.COMPLETE, onCompleteHandler);
  108.                         }
  109.                        
  110.                         private function drawList():void{
  111.                                 var kItem:XML = new XML();
  112.                                 for(var i:int = 0;i < resultList.item.length();i++){                                   
  113.                                         var kVBox:VBox = new VBox();
  114.                                         kItem = resultList.item[i];
  115.                                         kVBox.label = kItem.date + " : " + kItem.title + " [" + kItem.commentCnt + "]";
  116.                                         kVBox.width = 400;
  117.                                         kVBox.name = kItem.link;
  118.                                         kVBox.addEventListener(FlexEvent.SHOW,viewPostHandler);                                        
  119.                                         listAccordion.addChild(kVBox);
  120.                                        
  121.                                         if(i == 0){
  122.                                                 getPost(kItem.link);
  123.                                         }                                      
  124.                                 }                                                              
  125.                         }
  126.                        
  127.                         private function viewPostHandler(evt:FlexEvent):void{                          
  128.                                 getPost(evt.target.name);                              
  129.                         }
  130.                        
  131.                         private function getPost(_link:String):void{
  132.                                 if(tmpObj[_link]) return;
  133.                                
  134.                                 var rc:ReadContents = new ReadContents();
  135.                                 settingManager.loadData();     
  136.                                 rc.contentsread(settingManager.name, _link.split("/")[4]);
  137.                                 rc.addEventListener(Event.COMPLETE, onCompleteGetPostHandler);
  138.                                 //trace(_link);
  139.                                 tmpObj[_link] = true;                          
  140.                         }
  141.  
  142.                         private function onCompleteGetPostHandler(event : Event):void {
  143.                                 //trace(event.target.respond_contents);
  144.                                 resultContents = event.target.respond_contents;
  145.                                 var kText:Text = new Text();
  146.                                 kText.text = resultContents.elements('description');
  147.                                 listAccordion.selectedChild.addChild(kText);
  148.                                 event.target.removeEventListener(Event.COMPLETE, onCompleteGetPostHandler);
  149.                                 showNoti(kText.text);
  150.                         }
  151.                
  152.                        
  153.                 ]]>
  154.         </mx:Script>
  155.         <mx:TabNavigator id="tab_mc" x="10" y="34" width="400" height="500">
  156.                 <mx:Canvas id="read_mc" label="Post" width="100%" height="100%">
  157.                         <mx:Accordion id="listAccordion" x="10" y="10" width="379" height="446">
  158.                                
  159.                         </mx:Accordion>
  160.                
  161.                 </mx:Canvas>
  162.                
  163.                 <mx:Canvas id="write_mc" label="Write" width="100%" height="100%">
  164.                         <component:PostEditor id="post_mc"  x="10" y="9"/>
  165.                 </mx:Canvas>
  166.         </mx:TabNavigator>
  167.         <mx:Button id="login_mc" x="354" y="29" label="Login"/>
  168.         <mx:Label x="10" y="8" text="Daum bloger assistence on AIR" fontWeight="bold"/>
  169.        
  170. </mx:WindowedApplication>

 여러 사람이 단시간에 코딩한거라 지져분 하네요.ㅎ 우선은 메인 mxml 만 올림니다.ㅎ
코딩 뿐만 아니라, 여러 가지로 정말 도움이 되는 말씀을 해 주신 GS eshop 의 "오창훈" 님께 감사 인사 드리고 싶습니다. 꾸벅 



Posted by Flash 동강