Steem.js으로 자신의 블로그 post 정보 응용

in #kr-dev6 years ago (edited)

Steem.js으로 자신의 블로그 post 정보 응용



블로그 post를 읽어오는 post들이 이미 많습니다. 하지만 오늘 이 주제로 포스팅을 하게 된 이유는 코딩의 응용력을 어떻게 키우는지 한번 그 과정을 살펴보시라는 의미로 포스트를 작성했네요. 오래된 포스트 중에 태그 정보를 가져오는 함수에 재귀함수 사용하여 전체 태그 정보를 가져오는 것을 보고 코딩이 재미있어 보여서 한번 이 재귀함수 원리를 다른 함수에서 적용하여 원하는 정보를 추출하고 싶어서 간단히 실험을 하였습니다. 오늘 포스트 의도는 뭔가를 하나의 원리를 배우면 거기서 멈추지 말고 다른 곳에서 그 원리를 어떻게 적용하여 자기것으로 어떻게 만들어 가는지 보여주기 위함입니다. 그냥 태그를 재귀함수로 써서 가져왔구나 하고 끝나면 발전이 없고 자기것이 되지 않습니다. 나중에, 아두이노를 공부하시는 분들도 재미삼아서 Steem.js API 함수 중 하나 선택해서 재귀함수를 적용을 해보셨으면 합니다. 이제 본격적으로 자신의 블로그 게시물 정보 중 타이틀 정보만 우선 전체 출력하는 실험을 해보겠습니다.


[준비상태]

<script src="https://cdn.steemjs.com/lib/latest/steem.min.js"></script>
<script>

   아래 자바스크립트 코딩을 삽입하는 위치;
  
</script>

1. getDiscussionsByBlog()함수로 블로그 post 정보 얻기



링크 걸려 있는 해당 포스트 @morning이 함수에 대한 설명을 잘해 놓았는데 콜백함수에서 재귀함수가 처음 잘 연상이 안되더군요. 일반적인 재귀함수에서는 해당 함수를 재호출함으로서 쉽게 표현하는데 콜백은 잘 이미지가 안그려지더군요. @kdj 님의 태그를 불러오는 재귀함수 예제를 보면서 이런식으로 재호출을 이뤄지는 것을 대충 감을 잡아서 본젹적으로 블로그 post 정보를 읽을 수 있게 되었네요.

var query = {
  "tag": "codingman",
  "limit": 3
};

getDiscussionsByBlog()함수에 들어가는 인자로, tag, limit가 있습니다. tag는 자신의 id이고 limit은 post 출력 수 입니다. 여기서 post는 가장 최근에 올린 post순입니다.

steem.api.getDiscussionsByBlog(query, function(err, discussionsByBlog) {          
      for(d in discussionsByBlog){
        console.log(err, discussionsByBlog[d].title);       
      }
});

이 문장을 수행하면,

[결과]

이렇게 출력이 됩니다. 'codingman'이라는 사람의 블로그에 최근 올려진 post 3개의 title(제목)을 가져오게 왔습니다.

2. getDiscussionsByBlog()의 문제점


어떤 문제점을 가지고 있을까요. 곰곰히 생각 해보세요. limit의 숫자가 바로 제한이 되어 post를 가져오게 됩니다. 정확히 말하면 해당 스티미언의 쓴 post를 전체를 가져오기 위해서 limit의 숫자를 정의하기가 애매합니다. 참 막연해 지는 부분입니다. 그리고 여러분이 자신의 post의 보팅한 정보를 읽는 다고 가정을 하면 몇개의 post를 읽어와야 할까요. 5개, 10개 갯수의 제한도 막연해 집니다. 7일 이전 post로 최종 보상을 받기 전 post를 관리하고 싶다면 7일 이전의 post를 전부 가져와서 모니터링 하면 좋겠죠. 그럼 갯수를 몇개까지 해야 할까요. 하루에 1편을 쓴 사람이라면 7개만 불러오면 되겠지만 하루에 2편이상 쓴 사람이라면 limit 숫자를 정하는 것도 애매해지겠죠.

limit의 숫자로 정하기가 난감한 함수입니다. 그래서, 이 함수를 재귀함수로 이용해서 재호출함으로써 이런 문제점을 해결 할 수 있습니다.

3. 재귀함수


재귀함수에 대해 간단히 살펴보고 진행 하겠습니다.
[0~입력수 까지의 합을 구하는 식]

function sum(num){  
  if(num == 0 ) return 0;
  else return num+sum(num-1);
}
console.log(sum(10));

0이 될때까지 if문으로 sum()함수가 재호출됩니다. 10이 입력이 되면 순차적으로

10+sum(10-1)
10+9+sum(9-1)
...
10+9+8+7+6+5+4+3+2+1+sum(1-1)

마지막 호출 sum(1-1)은 0이니깐 if(0==0)이 참이라서 0을 최종 리턴하고 끝나게 됩니다. 이렇게 동작하는게 일반적인 재귀함수입니다. 이 코딩은 쉬운데 Steem.j API 공부할 때 콜백함수에서 재귀함수를 떠올려보니깐 잘 연상이 안되더군요. 우연히 오래전 올린 post 였지만 재귀함수를 사용하는 코딩을 보고 콜백함수를 저런식으로 재귀함수로 처리했구나 하고 정리가 되더군요.

(function run(){
  steem.api.getDiscussionsByBlog(query, function(err, discussionsByBlog) {          
    });
    if(조건) return;
    else run();
})();

그니깐 콜백함수를 재귀함수로 호출하는게 아니라 콜백함수와 함께 로직을 run()함수라는 사용자 정의함수를 묶어서 사용자 정의함수를 호출하면 쉽게 되는데 콜백함수 자체만 바라보고 생각해서 삽질이 잠깐 되었네요.

대충 steem.js API함수를 콜백함수를 재귀함수로 재 호출할 때 이런 느낌으로 코딩하시면 됩니다. 하지만 위와 같이 코딩하면 똑같은 정보만 계속 읽어오게 됩니다. getDiscussionsByBlog()함수에는 인자가 2개가 더 있는데 제대로 재귀함수를 적용하여 출력해보도록 하겠습니다.

4. getDiscussionsByBlog()함수로 블로그 post 전체 출력


var query = {
  "tag": "codingman",
  "limit": 10,
  "start_author": "author",
  "start_permlink": "permlink" }

"start_author"과 "start_permlink"가 있습니다. 블로그 post 중에서 시작 지점 post의 id와 post의 링크주소 입니다. 만약 10개의 post를 읽어왔다면 그 다음 10번째 post의 "author", "permlink" 정보를 기준으로 다시 10개를 읽어 올 수 있게 됩니다.

재귀함수로 합친 코딩은,

var query = {
  "tag": "codingman",
  "limit": 10
};

var cnt=0;

(function run(){
  steem.api.getDiscussionsByBlog(query, function(err, discussionsByBlog) {    

    for(var i=0;i<discussionsByBlog.length-1;i++){ //10개의 post중 마지막 post는 출력 안함
      console.log(err, discussionsByBlog[i].title);     
    }

    cnt=discussionsByBlog.length; //post 수

    if(cnt<10){
      console.log(err, discussionsByBlog[cnt-1].title);  //10개 미만이면 마지막 post 그냥 출력   
      return;
    }
    else{
      query.start_author= discussionsByBlog[cnt-1].author; //10번째 post "author"
      query.start_permlink= discussionsByBlog[cnt-1].permlink; //10번째 post "permlink"
      //console.log(query);

      run(); //10개 post 였으니 다음 10개 post를 읽이 위해서 재 호출
    }
  });
})();

[결과]

재귀함수를 사용할 수 있게 되었으니깐 제 블로그 게시물이나 전체 읽어와 봐야 겠다는 생각에 순간 떠오르는 생각으로 코딩을 한거라 별로인 코딩이지만 결과는 만족스럽게 출력 되었네요.

5. 블로그 post 정보를 읽으면 뭘 할 수 있을까요.


1) 보상 7일이전의 블로그 정보를 읽어 활용 할 수 있다.

재귀함수로 일정기간의 post을 읽을 수 있습니다. if문에 "discussionsByBlog[i].created"에서 마지막 post가 만들어진 "created" 시간을 비교해서 충족된 post만 출력하게 하면 쉽게 해결 할 수 있습니다. 간단히 코딩을 하면 다음과 같습니다.


var query = {
  "tag": "codingman", 
  "limit": 7
};

var cnt=0;

var dt = new Date();  
dt.setDate(dt.getDate() - 7);
var endTime = dt.toISOString().split('.')[0];

(function run(){
  steem.api.getDiscussionsByBlog(query, function(err, discussionsByBlog) {    
    
    cnt=discussionsByBlog.length;

    for(var i=0;i<cnt-1;i++){
      if(discussionsByBlog[i].created>=endTime){
        console.log(err,discussionsByBlog[i].title );     
      }
    }    
    
    if(cnt<7 || discussionsByBlog[cnt-1].created<endTime){      
      return;     
    } 
    else{
      query.start_author= discussionsByBlog[cnt-1].author;
      query.start_permlink= discussionsByBlog[cnt-1].permlink;
     // console.log(query);
      
      run();
    } 
  });
})();

[결과]

결과는 1일 1 포스트를 하기 때문에 7개의 포스트 제목을 출력했네요. 1일에 여러개의 post를 블로그에 올리셨다면 7개 이상의 포스트가 출력 되겠죠. 한번 본인의 id로 검색을 해보세요.

추가로, 7일의 post에서 리스팀 post가 있을 경우는 다른 사람의 post 날짜까지 계산되어 버립니다. 자신의 것만 가져올려면 어떻게 해야 할까요. if문에 post의 author와 query.tag가 일치한 post만 출력시키면 됩니다.

for(var i=0;i<cnt-1;i++){
      if(discussionsByBlog[i].author==query.tag && discussionsByBlog[i].created>=endTime){      
        console.log(err,discussionsByBlog[i].title );        
      }
    }    

if 조건문에서 tag(블로그id)의 post의 작성자 author이 일치하고 post작성 시간이 7일이전에 작성한 post인지 체크를 통해서 참이면 해당 post 제목을 출력하라는 명령문이 됩니다.

한가지 더 추가

    if(cnt<7 || discussionsByBlog[cnt-1].created<endTime){      
      return;     
    } 
    else{
      query.start_author= discussionsByBlog[cnt-1].author;
      query.start_permlink= discussionsByBlog[cnt-1].permlink;
     // console.log(query);
      
      run();
    } 

여기서, 무조건 읽어들인 마지막 post의 만들어진 시간으로 비교하면 문제가 발생 할 수 있게 됩니다. 가령, 한달 전 post를 리스팀 한다고 가정하면 자동으로 재귀함수가 종료하게 되겠죠.

[조건 수정 - 자신의 post만 읽고 자신의 post의 마지막 읽은 post의 만들어진 날짜를 비교]

수정하면은,

var nextTime;

    for(var i=0;i<cnt-1;i++){
      if(discussionsByBlog[i].author==query.tag && discussionsByBlog[i].created>=endTime){      
        console.log(err,discussionsByBlog[i].title );     
        nextTime=discussionsByBlog[i].created;
      }
    }    
    
    if(cnt<7 || nextTime<endTime){      
      return;         
    }
    else{
      query.start_author= discussionsByBlog[cnt-1].author;
      query.start_permlink= discussionsByBlog[cnt-1].permlink;
     // console.log(query);      
      run();
    } 

보면,

nextTime=discussionsByBlog[i].created;

이 nextTime변수의 시간값을 저장하는데 자신의 post의 작성된 시간을 계속 저장합니다. for문이 끝날때까지 돌면 마지막 자신이 작성한 post의 시간이 저장되어 있겠죠.

if문에서

 if(cnt<7 || nextTime<endTime){    
        return;  
 }

자신이 만들 시간이 7일이전에 작성했으면 사실상 7일이후에 보상 못받으니깐 더 이상 진행 할 필요 없이 재귀함수를 나오면 되겠죠.

[완성]

var query = {
  "tag": "codingman", 
  "limit": 7
};

var cnt=0;

var dt = new Date();  
dt.setDate(dt.getDate() - 7);
var endTime = dt.toISOString().split('.')[0];
var nextTime;

(function run(){
  steem.api.getDiscussionsByBlog(query, function(err, discussionsByBlog) {    
    
    cnt=discussionsByBlog.length;

    for(var i=0;i<cnt-1;i++){
      if(discussionsByBlog[i].author==query.tag && discussionsByBlog[i].created>=endTime){      
        console.log(err,discussionsByBlog[i].title );     
        nextTime=discussionsByBlog[i].created;
      }
    }    
    
    if(cnt<7 || nextTime<endTime){      
      return;         
    }
    else{
      query.start_author= discussionsByBlog[cnt-1].author;
      query.start_permlink= discussionsByBlog[cnt-1].permlink;
     // console.log(query);
      
      run();
    } 
  });
})();

어떻게 getDiscussionsByBlog()함수로 여기까지 코딩되어 왔는지 그 과정을 잘 살펴보시기 바랍니다. 처음부터 그냥 뚝딱! 하고 코딩이 완성되지 않스니다. 초기 Bolog정보를 읽어오는 것에서 출발해서 읽어온 정보에서 원한느 정보를 선택하고 그 원하는 정보를 토대로 조건을 만들고 그 조건이 정확하게 출력되는 여러가지를 추가하고 삭제하면 변경하면서 코딩이 다듬어집니다. 이 코딩도 완전한 코딩이라고 보기 어렵지만 그래도 어느정도 완성된 코딩이라 할 수 있습니다. 여기서 console.log()함수 부분을 html의 특정 태그로 결과를 출력하면 마무리 되겠죠.

2) post 보팅 내역이 들어 있기 때문에 보팅금액을 알 수 있습니다.



보팅금액을 자신의 7일 이전의 post들에서 개별적으로 구할 수 있습니다. 위 참조 링크 소스를 보고 편집만 잘 하셔서 코딩을 하면 됩니다. 제가 코딩을 하면 포스트가 너무 길어질 것 같아서 @tradingideas님의 포스트 링크를 걸어 놓았으니깐 한번 가셔서 보팅금액 계산이 어떤 식으로 이뤄지는지만 살펴보세요. 그리고 오늘 배운 getDiscussionsByBlog()안의 보팅 정보를 가지고 계산하시면 됩니다. 즉, votes들의 정보만 따로 추출해서 나머지 계산식에 맞게 코딩을 하시면 원하는 결과를 얻을 수 있겠죠.

그외에도 블로그 post 정보를 가지고 다른 표현도 많습니다. 위 2가지는 예를 든 것 뿐이죠.

마무리


더 이야기 하고 싶지만 여기서 멈추겠습니다. 한가지만 더 추가하면 7일 이전의 post를 구할 수 있게 되면은 7일동안 보팅한 스티미언 정보를 가져올 수 있게 됩니다. 따로 그 정보를 html 테이블 형식으로 만들면 함수 한개로 엑셀 파일로 변경이 가능합니다. 그러면 엑셀로 챠트를 만들 수 있고요. 또 보팅한 스티미언 정보를 아디를 변수에 저장한다면 따로 해당 아디에 7일 이전 post를 역으로 추출이 가능합니다. 교차 정보를 비교할 수 있게 됩니다. 활용도가 크겠죠. 그리고, 구글스프레드시트에 원격으로 데이터를 저장할 수 있습니다. 구글 검색 키워드로 "구글스프레드시트 DB"치시면 설정하는 방법에 대한 블로그 post들이 검색 되니깐 한번 사용해 보시는 것도 재미 있을 거라 생각됩니다. getDiscussionsByBlog()함수에서 처음 스티미언 ID만 있으면 됩니다. ID만 있으면 7일이전의 post 정보를 얻을 수 있습니다. 자신의 7일정보와 상대의 7일정보를 얻을 수 있다면 많은 것들 할 수 있게 되겠죠. 더 이상 이야기 하면 자동봇 쪽으로 가게 되니깐 거론하지 않겠습니다.

저는 자동봇보다는 수작업을 좋아 합니다. steem.js API 함수 중에 읽는 함수를 좋아하지만 쓰는 함수를 싫어 합니다. 쓰는 함수를 쓰게 되면은 자동봇을 만들고 싶어지니깐요 그러면 스티미언 활동이 정상적으로 안될 것 같아서 아예 쓰는 함수는 쳐다보지도 않고 있습니다.

코딩은 이렇게 공부하셔야 합니다. 어떤 하나를 이해하게 되면 그 하나를 통해서 다른 곳에서 적용하게 되고 또 적용하는 가운데에서 새로운 생각들을 추가하면서 응용력을 키우게 됩니다. 여러분들도 코딩을 공부할 때는 어떤 함수 하나를 배우게 되면 그 함수 자체로만 끝내서는 안되고 이 함수로 무엇을 할 수 있을까 끊임없이 자신에게 질문을 던지면서 상상력을 발휘해야 합니다.

왜! 아두이노 관련 포스트 끝날 때마다 상상력을 발휘해 보세요. 하는 이유를 아시겠지요.

주말이라서 잠깐 외도를 하였네요. 코딩을 다듬어야 하는데 처음 생각나는대로 증흥적으로 대충 코딩한거라 맘에는 안드는 코딩이네요

Sort:  

내용 잘 보고 갑니다~~^^

방문해주셔서 감사합니다.

마치 거미줄 처럼 서로 이어져 있군요 ^^ 처음에만 맥락을 보는눈까지 가기 어렵겠지만서두요 ㅎㅎ

어떻게 연결하느냐에 따라서 다양한 결과물을 만들어 낼 수 있다는 게 진짜 재밌는 것 같아요.

5월 다시 파이팅해요!
호출에 감사드립니다!

내일은 어버이날!
부모님과 함께~~!

Loading...

Coin Marketplace

STEEM 0.19
TRX 0.15
JST 0.029
BTC 63651.41
ETH 2679.55
USDT 1.00
SBD 2.80