Header

  1. View current page

    heartonbit님의 노트

Profile_img_60x60_01
0

ImageStock

ImageStock (Textcube Plugin)

 

사용자 스토리

 

[이미지 넣기]

  1. 블로그 편집창을 연다.
  2. ImageStock 버튼을 클릭한다.
  3. 새창 혹은 ajax 윈도우에 설정한 블로그의 이미지들이 줄줄이 뜬다.(RSS로 구현된 부분은 MetaWeblog API로 교체)
  4. 이미지를 클릭하면 해당 이미지가 에디터 창에 와서 붙는다.
  5. 글을 저장하면 이미지를 가져온 포스트에 트랙백이 보내진다.

 

[블로그 설정하기]

  1. 플러그인 환경설정창을 연다.
  2. 해당 블로그의 RSS 주소를 입력한다.
  3. 확인을 입력하면 RSS주소를 검증하고 값을 저장한다.

 

해결해야할 것들

  • 편집창에 버튼을 보이게 하는 문제
  • 블로그 RSS에서 이미지를 추출하여 HTML로 뿌려주는 PHP

    • PHP함수 : getImageStockView rss를 통해 preg_match_all로 이미지를 가져와서 화면에 뿌려주는 함수(페이징을 할끄나, 일단 없이) - 작업중

      • 티스토리 전용 정규식 완료
      • 이미지 검색 페이지 디자인 CSS로 이쁘게 
      • loading time이 너무 기니 paging ajax? (ajax없이 구현)
    • Javascript함수 : 이미지 클릭시 에디터에 특정 태그를 박아주는 함수 (알라딘 서적검색 참조)
  • 이미지버튼 클릭시 새창을 띄우는 문제 (dojo ajax이용? 음... javascript에 이미 불러와져있는 것을 알 수 있는가? require_once 같은 함수가 필요-DOM으로 구현)
  • 이미지를 클릭하면 이미지 태그를 에디터창에 뿌리도록 javascript
  • 이미지갤러리식으로 해야하는가?
  • 이미지 버튼 디자인 혹은 style sheet 이용
  • Javascript에 PHP require_once와 같은 함수 구현 - 텍스트큐브 포럼에 제안
  • RDF 등 기타 신디케이트 규격 구현 - 나중에
  • MetaWeblog API getPost 를 이용해서 이미지 파싱해오기 (오래된 포스트의 이미지도 가져오기 위해) http://kwon37xi.springnote.com/pages/871502
  • 캡션 함께 가져오기

     

 

작업로그

2008/09/26 00:14:09

JParker님 플리커 플러그인 참고 (참고라기보다는 숫제 복제에 가까운...) 플러그인 틀 생성

AddPostEditorToolbox 이벤트 사용하여 편집창에 버튼 삽입 (이미지는 아직 없음)

img 태그 regex 검색 : /\<img.+?src="(.+?)".+?\/>/ ->이상한 정규식 --)?

 

2008/09/28 01:09:50

PHP getImageStockView함수 작업중

HTTPRequest를 통해서 rss 주소를 가지고 피드를 가져오는 것 - 성공 (실패시 에러처리 필요)

가져온 피드에서 이미지 주소 추출 정규식 - 반성공 (유의미한 이미지만 가져와야함, 현재 CCL 이미지를 가져오는 오류)

섬네일을 가져와서 오리지날 주소를 생성해야할 듯

예)

http://cfs8.tistory.com/original/36/tistory/2008/09/09/23/23/48c686d34f80d

http://cfs8.tistory.com/image/36/tistory/2008/09/09/23/23/48c686d34f80d

CCL 이미지경로 (추출하지 말 것)

http://cfs.tistory.com/www/resource/admin/editor/ccl_black01.png

 

javascript require_once : DOM Script를 통해 해당 javascript 화일이 로딩되었는지 확인

http://kevin.vanzonneveld.net/techblog/article/javascript_equivalent_for_phps_require/

http://blog.gloridea.net/archive/20071109

 

HTTPRequest 객체생성시 arguments

  1.     function HTTPRequest() {
            switch (func_num_args()) {
                case 0:
                    break;
                case 1:
                    $this->url = func_get_arg(0);
                    break;
                default:
                case 2:
                    $this->method = func_get_arg(0);
                    $this->url = func_get_arg(1);
                    break;
            }
        }

 

2008/09/29 12:20:09

정규식의 이해

. : 어떤 문자가 와도 상관없음

* : 0~무한반복 0 or more

+ : 1~무한반복 1 or more

? : 반복없이 한번만 있을수도 있고 없을수도 있다 0 or 1

[a-z] : 알파벳 소문자

[\s] : 공백문자

^ 제외

.*? : anything

 

2008/09/30 02:08:22

regex분석

/<img [^>]+ ? src=("|\')? (.*?)("|\')/si

/i : 대소문자 구분하지 않음

/s : including newline

 

http://cfs8.tistory.com/original/36/tistory/2008/09/09/23/23/48c686d34f80d

http://cfs8.tistory.com/image/36/tistory/2008/09/09/23/23/48c686d34f80d

CCL 이미지경로 (추출하지 말 것)

http://cfs.tistory.com/www/resource/admin/editor/ccl_black01.png

 

/<img.*?src=("|\')(http:\/\/cfs[0-9].*?)("|\').*?\/>/i

<img로 시작하고

src=가 나온다음 ' 혹은 " 가 오고나서 http://cfs[숫자].이 나오고

/>로 끝나는 태그

tistory에는 적용할 수 있으나 다른 블로그에 적용불가

 

/<img.*?src=["|\'](http:\/\/cfs[0-9].*?)["|\'].*?width=["|\'](.*?)["|\'].*?\/>/i

 

2008/10/01 16:08:11

ImageStock Blog RSS주소 셋팅 : 완료

플러그인 환경설정창

플러그인 환경설정값 가져오기

requireComponent('Textcube.Function.misc');

$cfg = misc::fetchConfigVal($data);

사용

$cfg['환경설정키']

 

아 위처럼 사용하면 안됨 1.6이후에 삭제될 예정

 

requireComponent('Textcube.Function.setting');

global $configVal;

$cfg = setting::fetchConfigVal($configVal)

$cfg['key'] : value

 

php function

html_entity_decode()

htmlentities()

 

에디터에 코드 삽입하는 코드 JP_FlickrYoutubeMediaSearch plugin default.js 45 line function mediaInsert()

 

WYSIWYG mode 검사

  1.         var isWYSIWYG = false;
            try{
                if(window.parent.editor.editMode == 'WYSIWYG'){
                    isWYSIWYG = true;
                }
            }
            catch(e){ }       

 

삽입

  1. if (isWYSIWYG) {
       window.parent.editor.command("Raw", '<img class="tatterObject" src="' + servicePath + adminSkin + '/image/spacer.gif"' + window.parent.editor.parseImageSize(mediaCode, "string", "css") + ' longDesc="' + window.parent.editor.objectSerialize(mediaCode) + '" />', "");
    } else {
       window.parent.insertTag(window.parent.editor.textarea, mediaCode,"");
    }
  2.  
  3.            var mediaCode = '<div ' + mAlignOption + '><a href="' + selectedMediaURL + '" ' + linkTarget + '><img src="' + imageSrc + '" border="0" /></a></div>';
                if (isWYSIWYG) {
                    window.parent.editor.command("Raw", mediaCode, "");
                } else {
                    window.parent.insertTag(window.parent.editor.textarea, mediaCode, "");
                }

 

window.open(strUrl,strTitle,str기타설정);

 

tc/plugins/FM_Modern

TTModernEditor.prototype.command = function (command,value1,value2)

"Raw"를 "RAW"로 잘못 써서 낭패!!

 

Textcube 전역변수

$blogUrl : /sandbox/tc

$serviceUrl : http://www.shimminkyu.com/sandbox/tc

$pluginUrl : /sandbox/tc/plugins/MG_BlogImageStock

 

기본 뼈대 완성

 

이미지를 클릭하면 이미지블로그의 해당 글이 떠야함

그러기 위해서는 rss result 파싱을 제대로 xml로 해야할 듯

차라리 잘됐다.

xml로 파싱해서 item 별로 이미지를 띄우면 되겠네.

해당글 주소는 link 태그에 있음

파싱부분 재작업~

 

2008/10/02 10:23:51

자바스크립, CSS 화일 분리 작업(정리좀 합시다)

팝업 자바스크립 함수 텍스트큐브 라이브러리에 쓸만한 함수가 없을까

openLinkInNewWindow() 가 있으나 <a> 태그 전용인데다가 새윈도우가 아니라 탭으로 뜬다.FF3

자바스크립 분리를 하려했으나 글작성 화면 가상치환자 SKIN_head_end 안먹음

ShowAdminHeader 이벤트가 있음

 

ShowAdminHeader, AddPostEditorToolbox listener return시

$target 파라미터를 반드시 붙여주어야함

 

현재는 티스토리만 가능 (이글루스도 가능)

네이버 블로그, 다음블로그, 구글블로거 등등은 나중에 테스트

 

이미지창 style 파일 분리

    <link type="text/css" rel="stylesheet" href="<?php echo $pluginURL;?>/style/default.css" />   

 

RSS를 받아와서 XML로 파싱한 다음 item별로 이미지 태그 읽어옴

 

문제발생 : listener이벤트 ShowAdminHeader 가 잘 말을 듣지 않는다. 코드를 뜯어볼 필요 있음 -> 일단 HTML 코드 안에 script 태그를 박는 것으로 우회

reader.common의 getRemoteFeed 함수를 복사해와서 썼었는데

리더를 사용하지 않아도 함수는 불러오나보다. 함수 중복으로 인한 에러로 보임.

getRemoteFeed -> ImageStock_getRemoteFeed로 함수명 변경후 이벤트 처리 제대로 됨 (함수명이 뭐 이러냐)

에잇 함수하나쓰자고 모델 전체를 require하는게 부담이었는데 이렇게 된 바에야

requireModel('reader.common') 얍!

 

나중에 페이지 캐쉬를 써보자!

 

2008/10/06 15:00:33

다중사용자 모드에서 문제 발생

imagestock의 URL이

$serviceURL/plugin/ImageStockView가 아니라

$serviceURL/[id]/plugin/ImageStockView 여야함

 

Textcube javascript에서 blogURL이란 전역변수를 지원하는데 이녀석이 BlogOwner를 포함하는 녀석

So, blogURL + '/plugin/ImageStockView/';

를 호출하면 해결됨

 

2008/11/19 11:26:17

이전에 작업했던 내용인데 이제야 로깅...

블로그 이미지스탁 플러그인 창이 편집창을 닫을때 그러니까 저장후 돌아가기 버튼을 눌렀을때

닫혔으면 좋겠다는 상미의 요청이 있었음.

저장후 돌아가기를 눌렀을때 따로 이벤트가 지정되어있지 않으므로(정말?)

entryManager 내부 코드를 오버라이딩해야함. 음...

 

이렇게...

  1.             //EntryManager.saveAndReturn function overriding
                var oldSaveAndReturn = entryManager.saveAndReturn;
                entryManager.saveAndReturn = function(){
                    if(stockWin != '') stockWin.close();
                    oldSaveAndReturn();
                }

 

음.. 이렇게 구현했더니  oldSaveAndReturn()을 실행하는 과정에 오류 발생

오류 메시지

이 페이지에서 탐색을 중지하시겠습니까?

아직 저장되지 않았습니다.

계속 진행은 확인을, 그렇지 않으면 취소를 선택하십시오.

 

확인을 누르면 저장되지 않은 상태로 목록으로 나감

 

function EntryManager.saveAndReturn 함수

tc/interface/owner/entry/edit/index.php

                                    this.saveAndReturn = function () {
                                        this.nowsaving = true;

//에러나는 곳

                                        var data = this.getData(true);


                                        if (data == null)
                                            return false;
                                        if(entryManager.isSaved == true) {
                                            var request = new HTTPRequest("POST", "<?php echo $blogURL;?>/owner/entry/finish/"+entryManager.entryId);
                                        } else {
                                            var request = new HTTPRequest("POST", "<?php echo $blogURL;?>/owner/entry/finish/");
                                        }

                                        request.message = "<?php echo _t('저장하고 있습니다.');?>";
                                        request.onSuccess = function () {
                                            entryManager.pageHolder.isHolding = function () {
                                                return false;
                                            }
                                            PM.removeRequest(this);
                                            var returnURI = "";
                                            var oForm = document.forms[0];
                                            var changedPermalink = trim(oForm.permalink.value);
<?php
if (isset($_GET['popupEditor'])) {
?>
                                            opener.location.href = opener.location.href;
                                            window.close();
<?php
} else if (isset($_GET['returnURL'])) {
    if(strpos($_GET['returnURL'],'/owner/entry')!==false) {
?>
                                            returnURI = "<?php echo escapeJSInCData($_GET['returnURL']);?>";
<?php
    } else {
?>
                                            if(originalPermalink == changedPermalink) {
                                                returnURI = "<?php echo escapeJSInCData($_GET['returnURL']);?>";
                                            } else {
                                                returnURI = "<?php echo escapeJSInCData("$blogURL/" . $entry['id']);?>";
                                            }
<?php
    }
?>
                                            window.location = returnURI;
<?php
} else {
?>
                                            window.location.href = "<?php echo $blogURL;?>/owner/entry";
<?php
}
?>
                                        }
                                        request.onError = function () {
                                            PM.removeRequest(this);
                                            alert("<?php echo _t('저장하지 못했습니다');?>");
                                            this.nowsaving = false;
                                        }
                                        PM.addRequest(request, "<?php echo _t('저장하고 있습니다.');?>");
                                        request.send(data);
                                    }

 

이상한 자바스크립트씨 ㅡㅡ;;;

함수 내부에 선언된 함수에서는 미리 선언되지 않은 변수를 사용해도 에러가 나지 않는다.

다시 말해서

 

function SomeClass(){

    this.val = 1;

    this.doSth = function(){

        alert(someclass.val);   //someclass소문자에 주목하자. 쩌기 아래에 SomeClass의 객체로 선언되어있다.

    }

}

var someclass = new SomeClass();

someclass.doSth();

 

에러가 날 것 같은가?

나지 않는다. ㅡㅡ;; alert창에 1이라고 떡 찍힌다.

내부 함수는 호출될때 바인딩이 되기 때문이라고 짐작된다.

안에서 무슨 짓을 하건

호출상황에서만 조건이 만족되면 된다는 의미.

 

그럼 이건 어떤가

function SomeClass(){

    this.val = 1;

    this.doSth = function(){

        someclass.val = 2;

        this.val = 3

        alert(someclass.val);   //someclass소문자에 주목하자. 쩌기 아래에 SomeClass의 객체로 선언되어있다.

    }

}

var someclass = new SomeClass();

someclass.val = 4;

someclass.doSth();

 

떡하니 3 찍혀주신다.

this건 객체명이건 동일한 주소가 되는 것 같다.

 

너무 멀리왔는데 entryManager의 오류는 이 this에서 왔다.

  1. //EntryManager.saveAndReturn function overriding
    var oldSaveAndReturn = entryManager.saveAndReturn;
    entryManager.saveAndReturn = function(){
       if(stockWin != '') stockWin.close();
       oldSaveAndReturn();
    }

이 짧은 함수내에는 치명적인 오류가 내재해있다.

그것은 oldSaveAndReturn 함수내에 this가 쓰일 경우, this가 의미하는 entryManager를 찾아가지 못한다는 것이다!!!

이 함수를 다음과 같이 고치면

  1. //EntryManager.saveAndReturn function overriding
    var entryManager.oldSaveAndReturn = entryManager.saveAndReturn;
    entryManager.saveAndReturn = function(){
       if(stockWin != '') stockWin.close();
       entryManager.oldSaveAndReturn();
    }

내부의 this는 entryManager를 잘 찾아감으로써 문제가 해결된다.

휴...

 

2008/12/07 13:08:56

티스토리 이미지 캡션까지 가져오기 - 정규식 수정

가져와야할 부분

  1. <div class="imageblock center" style="text-align: center; clear: both;">
    <a target="_blank" rel="lightbox" href="http://cfs15.tistory.com/original/23/tistory/2008/12/06/23/12/493a883b1fb65">
    <img height="653" width="482" alt="" src="http://cfs15.tistory.com/original/23/tistory/2008/12/06/23/12/493a883b1fb65"/>
    </a>
    <p class="cap1">창문 밖으로 보이는 나무</p>
    </div>

 

기존 정규식

/<img.*?src=["|\'](http:\/\/cfs[0-9].*?)["|\'].*?width=["|\'](.*?)["|\'].*?\/>/i

 

정규식

<div class="imageblock 으로 시작하고

<img로 시작해서 src="image url"이 있고

<p class="cap1">이미지캡션 </p>

</div>로 끝남

 

/<div[^>]class=["|\']imageblock.*?>.*?<img.*?src=["|\'](http:\/\/cfs[0-9].*?)["|\'].*?<\/div>/si

<p[^>]class="cap1">(.*?)<\/p>

오동작 : 캡션이 없는 이미지는 아예 가져오지 않음 ㅡㅡ;

 

먼저, 이미지 URL과 이후 태그 모두를 가져온후, 다시 preg_replace를 이용해 <p> 태그 내부 문자열만 가져옴

이런 식

  1. $regex = '/<div[^>]class=["|\']imageblock.*?>.*?<img.*?src=["|\'](http:\/\/cfs[0-9].*?)["|\'].*?\/>(.*?)<\/div>/si';
    $result = preg_match_all($regex, $desc, $matches);
    $subRgx = '/.*?<p[^>]class="cap1">(.*?)<\/p>.*?/si';
    $matches[2] = preg_replace($subRgx, '$1', $matches[2]);

 

preg_replace가 의도한대로 동작하지 않음

  1. $regex = '/<div[^>]class=["|\']imageblock.*?>.*?<img.*?src=["|\'](http:\/\/cfs[0-9].*?)["|\'].*?\/>(.*?)<\/div>/si';
    $result = preg_match_all($regex, $desc, $matches);
    $subRgx = '/<p[^>]class="cap1">(.*?)<\/p>/si';
    for($i = 0; $i < count($matches[2]);$i++){
        preg_match($subRgx, $matches[2][$i], $subMatch);
        $matches[2][$i] = $subMatch[1];
    }

 

for 돌려서 강제로 대입

 

foreach 문에서 한가지

  1. foreach(array_expression as &$var){
  2.     //Do Something
  3. }

php4 부터 foreach구문 지원, php5부터 레퍼런스 변수 전달 가능 (php4에서는 안되네 ㅡㅡ; )

 

 

History

Last edited on 12/07/2008 23:37 by 망고

Comments (0)

You must log in to leave a comment. Please sign in.