$SendPingAllowed = 0; # 0 - anyone, 1 - who can edit, 2 - who is admin
* 날짜 시간 | 트랙백 핑을 보낸 트랙백URL 또는 트랙백을 보낼때 Permalink URL 을 입력했다면 * 날짜 시간 | 트랙백 핑을 보낸 게시물의 Permalink URL
* 보낸 트랙백 1 * 보낸 트랙백 2 * 보낸 트랙백 3 <trackbacksent>
* 블로그 이름 시간 ** 제목 : ... ** 내용 : ...
* 블로그 이름 1 ** 제목 1 ** 내용 1 * 블로그 이름 2 ** 제목 2 ** 내용 2
### trackback 보내기 $SendPingAllowed = 0; # 0 - anyone, 1 - who can edit, 2 - who is admin
### 패치를 위해 추가된 환경설정 변수 use vars qw( ... $SendPingAllowed );
sub BrowsePage { ... if ($EditPagePos >= 2) { $fullHtml .= &GetTrackbackGuide($id); # 이 줄 추가 $fullHtml .= &GetEditGuide($id, $goodRevision); # luke added } ... }
sub BrowseExternUrl { ... } elsif ((&GetParam('InFrame','') eq '2') && ($EditGuideInExtern)) { print &GetHeader($id, "$id [InBottomFrame]",$oldId); print "<hr>\n"; print &GetTrackbackGuide($id); # 이 줄 추가 print &GetEditGuide($id, ''); print &GetMinimumFooter(); return; ... }
sub GetFooterText { ... if ($EditPagePos eq 1 or $EditPagePos eq 3) { $result .= &GetTrackbackGuide($id); # 이 줄 추가 $result .= &GetEditGuide($id, $rev); } ...
sub MacroSubst { ... $txt =~ s/&__LT__;color\(([^,)]+),([^\n]+?)\)&__GT__;/&MacroColor($1, $2)/gei; ### <trackbacksent> $txt =~ s/(((^|\n)\* .*)*\n?)(&__LT__;trackbacksent&__GT__;)/&MacroTrackbackSent($4,$1)/gei; $txt =~ s/(((^|\n)\* .*\n\*\* .*\n\*\* .*)*\n?)(&__LT__;trackbackreceived&__GT__;)/&MacroTrackbackReceived($4,$1)/gei; ### ############### return $txt; }
다음 두 함수 통채로 추가
sub MacroTrackbackSent { my ($itself, $trackbacks) = @_; my $title = &T('No Trackback sent'); my $count = ($trackbacks =~ s/((^|\n)\* .*)/$1/g); $title = &Ts('Trackback sent [%s]', $count) if ($count); return &MacroMemo("", $title, $trackbacks, "trackbacklist"); } sub MacroTrackbackReceived { my ($itself, $trackbacks) = @_; my $title = &T('No Trackback received'); my $count = ($trackbacks =~ s/((^|\n)\* .*\n\*\* .*\n\*\* .*)/$1/g); $title = &Ts('Trackback received [%s]', $count) if ($count); return &MacroMemo("", $title, $trackbacks, "trackbacklist"); }
다음 함수 수정
sub GetParam { my ($name, $default) = @_; my $result; $result = $q->param($name); ### POST 로 넘어올 경우의 데이타 처리 - 아래 세 줄 추가 if (!defined($result)) { $result = $q->url_param($name); } if (!defined($result)) { ... }
sub DoOtherRequest { ... } elsif ($action eq "rss") { &DoRss(); ### Trackback - 아래 줄 추가 } elsif ($action eq "send_ping") { &DoSendTrackbackPing($id); ### ############### } else { # Later improve error reporting &ReportError(Ts('Invalid action parameter %s', $action)); } return; } ... }
아래 함수의 제일 마지막 줄 수정
sub DoPostMain { ... &ReBrowsePage($id, "", 1) if ($id ne "!!"); # if 문 추가 }
다음 함수들 통채로 추가
sub DoSendTrackbackPing { require Net::Trackback::Client; require Net::Trackback::Ping; my ($id) = @_; my ($ping_url, $title, $url, $excerpt, $blog_name, $ping_permalink); my $validid = &ValidId($id); my $result = ""; $ping_url = &GetParam('ping_url'); $title = &GetParam('title'); $url = &GetParam('url'); $excerpt = &GetParam('excerpt'); $blog_name = &GetParam('blog_name'); $ping_permalink = &GetParam('ping_permalink'); if ($validid ne '') { $result .= $validid; } elsif (!&UserCanSendTrackbackPing($id)) { $result .= &T('You are not allowed to send Trackback ping of this page'); } elsif ($ping_url eq '') { $result .= &T('No Ping URL'); } else { my $ping = Net::Trackback::Ping->new; $ping->ping_url("$ping_url"); $ping->title("$title"); $ping->url("$url"); $ping->excerpt("$excerpt"); $ping->blog_name("$blog_name"); my $client = Net::Trackback::Client->new(); $client->charset("$HttpCharset"); my $msg = $client->send_ping($ping); my $msg_str = $msg->to_xml; my ($code, $message) = ($msg_str =~ m!<error>(\d+).*<message>(.*?)</message>!s); if ($msg->is_success) { sleep(1); $Now = time; &OpenPage($id); &OpenDefaultText(); my $string = $Text{'text'}; my $macro = "\<trackbacksent\>"; if ($string =~ /$macro/) { my $timestamp = &CalcDay($Now) . " " . &CalcTime($Now); my $newtrackbacksent = "* $timestamp | " . (($ping_permalink ne '')?$ping_permalink:$ping_url); $string =~ s/($macro)/$newtrackbacksent\n$1/; &DoPostMain($string, $id, &T('New Trackback Sent'), $Section{'ts'}, 0, 0, "!!"); } $result .= &T('Ping successfully sent'); } else { $result .= &Ts('Error occurred: %s', "$code - $message"); } } print &GetHttpHeader(); print &GetHtmlHeader("$SiteName : ". &T('Send Trackback Ping'), ""); print $q->h2(&T('Send Trackback Ping')) . "\n"; print $result; print "<hr size='1'>".Ts('Return to %s' , &GetPageLink($id)); print $q->end_html; return; } sub UserCanSendTrackbackPing { my ($id) = @_; return 0 if (! -f &GetPageFile($id)); return 1 if ($SendPingAllowed == 0); return 1 if (&UserIsAdmin()); return 1 if (($SendPingAllowed == 1) && (&UserCanEdit($id))); return 0; } sub PageCanReceiveTrackbackPing { my ($id) = @_; return 0 if (! -f &GetPageFile($id)); return 0 if (defined $HiddenPage{$id}); return 0 if (-f &GetLockedPageFile($id)); return 1; } sub GetTrackbackGuide { my ($id) = @_; my $result = "\n<HR class='footer'>\n<DIV class='trackbackguide'>"; my $trackbackguide = "<P>"; $FullUrl = $q->url(-full=>1) if ($FullUrl eq ""); my $encoded = &EncodeUrl($id); my $url = $FullUrl . &ScriptLinkChar() . "action=tb&id=$encoded"; if (&PageCanReceiveTrackbackPing($id)) { $trackbackguide .= &T('Trackback address of this page:')." ". "<input type=\"button\" title=\"". &T('Copy the address to the clipboard.'). "\" value=\"". &T('Copy'). "\" onClick=\"copy_clip('','$url');\"> ". $url; } else { $trackbackguide .= &T('This page can not receive Trackback'); } if (&UserCanSendTrackbackPing($id)) { $FullUrl = $q->url(-full=>1) if ($FullUrl eq ""); my $url = $FullUrl . &ScriptLinkChar . $encoded; my $title = $id; if ($FreeLinks) { $title =~ s/_/ /g; # Display with spaces } my $excerpt = $Text{'text'}; $excerpt =~ s/<.*?>//g; if (length($excerpt) > 255) { $excerpt = substr($excerpt, 0, 252); $excerpt =~ s/(([\x80-\xff].)*)[\x80-\xff]?$/$1/; $excerpt .= "..."; } $excerpt =~ s/(\r?\n)/ /g; $excerpt = &QuoteHtml($excerpt); $excerpt =~ s/"/"/g; # " 를 quot;로 변환 $trackbackguide .= "\n<BR>"; $trackbackguide .= &GetFormStart("Trackback_ping") . &GetHiddenValue("action", "send_ping") . &GetHiddenValue("title", "$title") . &GetHiddenValue("blog_name", "$SiteName") . &GetHiddenValue("excerpt", "$excerpt") . &GetHiddenValue("url", "$url") . &GetHiddenValue("id", "$id") . "<TABLE style='border: none;'>" . "<TR><TD style='border: none;' colspan=2>" . &T('Send Trackback Ping of this page to:') . "</TD></TR>" . "<TR><TD style='border: none;'>" . &T('Trackback URL:') . "</TD>" . "<TD style='border: none;'>" . $q->textfield(-name=>"ping_url", -default=>"", -override=>1, -size=>100, -maxlength=>200) . "</TD></TR>" . "<TR><TD style='border: none;'>" . &T('Permalink URL (optional):') . "</TD>" . "<TD style='border: none;'>" . $q->textfield(-name=>"ping_permalink", -default=>"", -override=>1, -size=>100, -maxlength=>200) . "</TD></TR>" . "<TR><TD style='text-align: center; border: none;' colspan=2>" . $q->submit(&T('Send Ping')) . "</TD></TR>" . "</TABLE>" . $q->endform; } $result .= &MacroMemo("", &T('Send Trackback'), $trackbackguide, "trackbackguidecontent"); $result .= "</DIV>"; }
이 함수는 나름대로 중요하여, 따로 빼어서 표시해 둔다. 이 함수는 스트링을 인자로 받아서, 다음 문자를 제외하고는 한바이트씩 "%FF"와 같이 두자리의 16진수로 변환한다.
sub EncodeUrl { my ($string) = @_; $string =~ s!([^/a-zA-Z0-9_.-])!uc sprintf "%%%02x", ord($1)!eg; return $string; }
sub action_tb { use strict; my $id = &GetParam("id",""); $id =~ s/\s+$//; my $normal_id = $id; my $url = &GetParam('url'); my $title = &GetParam('title', $url); my $blog_name = &GetParam('blog_name'); my $excerpt = &GetParam('excerpt'); # tcode my $tcode = &GetParam('tc',""); my ($code_today, $code_yesterday); $code_today = &simple_crypt(length($id).substr(&CalcDay($Now),5)); $code_yesterday = &simple_crypt(length($id).substr(&CalcDay($Now - 86400),5)); if (($tcode ne $code_today) && ($tcode ne $code_yesterday)) { # spam &SendTrackbackResponse("1", "SPAM trackback"); return; } # 인코딩 컨버트 if ($q->content_type() =~ /charset=(.+)\b/i) { # POST요청이면서, 인코딩이 명시되어 있는 경우 my $remote_enc = $1; $title = convert_encode($title, "$remote_enc", "$HttpCharset"); $blog_name = convert_encode($blog_name, "$remote_enc", "$HttpCharset"); $excerpt = convert_encode($excerpt, "$remote_enc", "$HttpCharset"); } else { # 인코딩을 추측해서 변환 $title = guess_and_convert($title); $blog_name = guess_and_convert($blog_name); $excerpt = guess_and_convert($excerpt); } # 블로그 지원을 위한 꽁수 my ($blogrcpage, $blogrccomment); if ($id =~ m/(.+)(\/|%2f|%2F)(.+)/) { $blogrcpage = "$1/BlogRc"; } else { $blogrcpage = "BlogRc"; } if (-f &GetPageFile($blogrcpage)) { $blogrccomment = $excerpt; } else { $blogrcpage = ""; } # 처음 200글자까지만 남김 $excerpt = (&split_string($excerpt, 200))[0]; $excerpt .= " ..."; $excerpt =~ s/(\r?\n)/ /g; $excerpt = &QuoteHtml($excerpt); $excerpt = "<nowiki>$excerpt</nowiki>"; if ($FreeLinks) { $normal_id = &FreeToNormal($id); } if ($url eq '') { &SendTrackbackResponse("1", "No URL (url)"); } elsif ($id eq '') { &SendTrackbackResponse("1", "No Pagename (id)"); } elsif (!&PageCanReceiveTrackbackPing($normal_id)) { &SendTrackbackResponse("1", "Invalid Pagename (Page is missing, or Trackback is not allowed)"); } elsif (my $bannedText = &TextIsBanned($blog_name.$url.$title.$excerpt)) { &SendTrackbackResponse("1", "[$bannedText] is a Banned text"); } else { &OpenPage($normal_id); &OpenDefaultText(); my $string = $Text{'text'}; my $macro = "\<trackbackreceived\>"; if (!($string =~ /$macro/)) { $string .= "\n$macro\n"; } my $timestamp = &CalcDay($Now) . " " . &CalcTime($Now); my $newtrackbackreceived = "* " . &Ts('Trackback from %s', "'''<nowiki>$blog_name</nowiki>'''") . " $timestamp\n" . "** " . &T('Title:') . " [$url $title]\n" . "** " . &T('Content:') . " $excerpt"; $string =~ s/($macro)/$newtrackbackreceived\n$1/; # 블로그 지원을 위한 꽁수 if ($blogrcpage) { $blogrccomment =~ s/(\r?\n)/ /g; $blogrccomment =~ s/\[/{/g; $blogrccomment =~ s/\]/}/g; # 처음 30글자까지만 남김 $blogrccomment = (&split_string($blogrccomment, 30))[0]; $blogrccomment .= " ..."; $blogrccomment = &QuoteHtml($blogrccomment); $blogrccomment =~ s/----+/---/g; $blogrccomment =~ s/^ *//; $blogrccomment = "T) $blogrccomment"; my ($fname, $status, $data); $fname = &GetPageFile($blogrcpage); if (-f $fname) { ($status, $data) = &ReadFile($fname); if ($status) { my %temp_Page = split(/$FS1/, $data, -1); my %temp_Section = split(/$FS2/, $temp_Page{'text_default'}, -1); my %temp_Text = split(/$FS3/, $temp_Section{'data'}, -1); my $blogrc_Text = $temp_Text{'text'}; my $date = &CalcDayNow(); if ($date =~ /(\d+)-(\d+)-(\d+)/) { $date = sprintf("%4d-%02d-%02d",$1,$2,$3); } if ($blogrc_Text =~ /^\*/m) { $blogrc_Text =~ s/^\*/* [[$id|$blogrccomment]] $date\n*/m; } else { $blogrc_Text .= "\n* [[$id|$blogrccomment]] $date"; } my $backup = $Section{'ts'}; &DoPostMain($blogrc_Text, $blogrcpage, "", $temp_Section{'ts'}, 0, 1, "!!"); $Section{'ts'} = $backup; } } } &DoPostMain($string, $id, &T('New Trackback Received'), $Section{'ts'}, 0, 0, "!!"); &SendTrackbackResponse(0, ""); } } sub SendTrackbackResponse { my ($code, $message) = @_; if ($code == 0) { print <<END; Content-Type: application/xml; charset: iso-8859-1\n <?xml version="1.0" encoding="iso-8859-1"?> <response> <error>0</error> </response> END } else { print <<END; Content-Type: application/xml; charset: iso-8859-1\n <?xml version="1.0" encoding="iso-8859-1"?> <response> <error>$code</error> <message>$message</message> </response> END } } 1;
/* 트랙백 주고받기 안내영역 */ DIV.trackbackguide { text-align: left; background: transparent; border: none; color: black; } /* 트랙백 주고받기 가이드 */ DIV.trackbackguidecontent { background: transparent; border: none; } A.trackbackguidecontent:link, A.trackbackguidecontent:active, A.trackbackguidecontent:visited, A.trackbackguidecontent:hover { background: transparent; color: blue; text-decoration: none; } A.trackbackguidecontent:hover { text-decoration: underline; } /* trackbacksent, trackbackreceived 매크로 */ DIV.trackbacklist { background-color:#F8F8F8; color:#000; border:1px solid silver; padding:5px; } A.trackbacklist:link, A.trackbacklist:active, A.trackbacklist:visited, A.trackbacklist:hover { background: transparent; color: blue; text-decoration: none; } A.trackbacklist:hover { text-decoration: underline; }
ext1.109d에서 클립보드 복사 기능을 넣으면서 추가된 자바스크립트 함수
// msg - 사용자에게 확인창을 띄울때 출력되는 메시지 // - ""이면 확인창 띄우지 않음 // text - 클립보드에 복사될 텍스트 // 출처: http://www.krikkit.net/howto_javascript_copy_clipboard.html // modified by raymundo, gypark@gmail.com // Copyright (C) krikkit - krikkit@gmx.net // --> http://www.krikkit.net // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. function copy_clip(msg, text) { if (msg != "") { if (!confirm(msg)) return; } // IE if (window.clipboardData) { window.clipboardData.setData("Text", text); } // Firefox/Mozilla else if (window.netscape) { // firefox/mozilla 에서 동작하기 위해서는 사용자 프로파일 디렉토리에 prefs.js 파일에 다음과 같이 적어준다 // user_pref("signed.applets.codebase_principal_support", true); // 또는 "about:config" 페이지를 열어서 다음 항목의 값을 true로 설정해 준다 // signed.applets.codebase_principal_support alert("If it fails to copy, check the option:\n\nsigned.applets.codebase_principal_support = true\n\nin \"about:config\" page."); netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect'); var clip = Components.classes['@mozilla.org/widget/clipboard;1'].createInstance(Components.interfaces.nsIClipboard); if (!clip) return; var trans = Components.classes['@mozilla.org/widget/transferable;1'].createInstance(Components.interfaces.nsITransferable); if (!trans) return; trans.addDataFlavor('text/unicode'); var str = Components.classes["@mozilla.org/supports-string;1"].createInstance(Components.interfaces.nsISupportsString); var copytext=text; str.data=copytext; trans.setTransferData("text/unicode",str,copytext.length*2); var clipid=Components.interfaces.nsIClipboard; if (!clip) return false; clip.setData(trans,null,clipid.kGlobalClipboard); } return false; }
Send Trackback 트랙백 주고받기 Send Trackback Ping of this page to: 이 페이지의 트랙백 핑을 다음 주소로 보냄: Trackback URL: 트랙백 URL: Permalink URL (optional): 해당 글의 URL (선택사항): Send Ping 트랙백 핑 보내기 You are not allowed to send Trackback ping of this page 이 페이지의 트랙백 핑을 보낼 권한이 없습니다 No Ping URL 트랙백 핑을 받을 주소가 없습니다 New Trackback Sent 트랙백 핑을 보냄 Error occurred: %s 에러가 발생했습니다: %s Send Trackback Ping 트랙백 핑 보내기 Ping successfully sent 핑을 보내는 데 성공했습니다 Trackback address of this page: 이 페이지의 트랙백 주소: Copy 복사 Copy the address to the clipboard. 이 주소를 클립보드에 복사합니다. This page can not receive Trackback 이 페이지로는 트랙백을 보낼 수 없습니다 Trackback from %s %s 로부터의 트랙백 Title: 제목: Content: 내용: New Trackback Received 트랙백 핑을 받음 No Trackback sent 보낸 트랙백 없음 Trackback sent [%s] 보낸 트랙백 [%s] No Trackback received 받은 트랙백 없음 Trackback received [%s] 받은 트랙백 [%s]
ext1.61c -
ext1.82b -
ext1.90a - 다른 사이트에 트랙백을 보낼 때, 트랙백 핑 데이타의 url항목의 값에 한글이 들어간 경우 (한글이름 페이지의 경우) 인코딩하도록 함.
ext1.96b - 스팸트랙백을 막을 수 있을까 해서, 페이지의 트랙백 주소를 하이퍼링크가 아니라 평범한 텍스트로 출력하게 함.
ext1.100
ext1.101~103a
ext1.107c
ext1.109d
ext1.109e
ext1.110
ext2.1g
불여우에서 Linkification 확장을 써서 불편함을 못느끼고 있었군요.
음 참고 있지 않는 정도가 아니라, 이 패치 때문에 오히려 그 Linkifcation 이 트랙백 주소 부분에 대해서 동작을 못하는군요. 동작하게 해주려면, Linkifcation 설정에 들어가서 고급->차단된 요소에 *[@onclick] 항목을 제거해줘야 하더군요. 이건 이거대로 불편한데... 표시된 주소를 클릭했을 때 복사하지 말고 옆에다가 따로 버튼을 만들던가 해야겠습니다.
불여우 사용자를 위한 옵션 설명문... 사실 넣기 싫어서 안 넣은게 아니었는데요 ^^ 문제가 좀 있습니다. 뭐 저도 어디 적어둬야겠다 싶은 터라 말이 나온김에 부연 설명을 하면...
일단, 불여우에서 제대로 복사가 되었는지 안 되었는지를 판단하고 복사가 안 된 경우만 따로 에러를 출력할 방법을 못 찾았습니다.
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
위 코드를 실행할때 그 옵션에 따라서 성공/실패가 갈리는데, 옵션이 꺼져 있으면 그냥 스크립트가 종료되어버리는 것 같더군요.
if (netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect')) {
alert("성공");
} else {
alert("실패");
}
이런 식으로 if 를 써서 비교하려고 해도 안 되더라고요. (해 보면, 옵션이 켜져 있으면 "실패"- 뜻밖에도 -가 뜨고, 꺼져 있으면 아무 반응 없음)
따라서 복사를 시도하기 전에 창을 띄워야 합니다. 그럼 FF 사용자는 무조건 확인창을 한번 눌러줘야 하는 것도 불편하고... 더 큰 문제는 옵션이 켜져 있어도 알림창은 뜰 것이기 때문에 찾아온 사람 입장에서는 "옵션이 켜져 있는데 왜 자꾸 뜨냐"라고 생각할까봐.. =.=;;; 어찌 보면 별 거 아닌데 괜히 신경 쓰이더라고요 ^^
창을 띄우는게 아니라 버튼의 title 속성에 넣어서 클릭하기 전에 가리켰을 때 나오게 할까도 했는데... 정작 FF에서는 title 문자열이 길면 뒤를 잘라먹고 말줄임표로 줄여서 표시해버리더군요 OTL
별 수 없이 "만일 복사에 실패했다면, 이 옵션을 체크하라"는 식으로 창을 띄울 생각입니다. 근데 스크립트에 직접 넣을 스트링이라 영작해야 되겠군요 =.=; "If it failes to copy, check the option:" 정도면 되려나요.
트랙백을 보내려고 했더니 에러가 나요.
Can't locate object method "charset" via package "Net::Trackback::Client" (perhaps you forgot to load "Net::Trackback::Client"?) at /home/4/nyxity35/www/wiki/wiki.pl line 9143.
For help, please send mail to the webmaster (postmaster@nyxity.com), giving this error message and the time and date of the error.
9143째 줄은 DoSendTrackbackPing 함수의
$client->charset("$HttpCharset");
부분입니다.
음, 지난 몇 년 간 사용한 적이 없군... 삭제할까.. -_-
2.34에서 삭제했습니다.
아... 삭제되었군요.