변경사항 (가장 최근의 "다른 사용자에 의한 수정"부터)
(소소한 수정)
| -363,7 +363,7 | 
| a bit polished of this matter, here: UseMod:WikiPatches/BulkLock. \\ | 
| Hope it's fun ... <mysign(JuanmaMP,2012-5-15 12:59 am)> | 
|  | 
| : Wow, you're so active in usemod.com! Great! :-D <mysign([[Raymundo]],2012-5-15 1:50 am)> | 
| : Wow, you're so active in usemod.org! Great! :-D <mysign([[Raymundo]],2012-5-15 1:50 am)> | 
|  | 
| yep, for the being time, a really peaceful place ... :)) <mysign(JuanmaMP,2012-5-15 2:08 am)> | 
|  | 
| -374,6 +374,8 | 
| Good night over there. <mysign(JuanmaMP,2012-5-15 2:21 am)> | 
|  | 
| if you prefer erased my last comment to your choice. I wanted uploading a typical login snapshot into a web but finally it returned that thing. Sorry. <mysign(JuanmaMP,2012-5-15 4:43 pm)> | 
|  | 
| : LOL, I had to guess 'what is that?' hahaha. It's okay. <mysign([[Raymundo]],2012-5-15 9:45 pm)> | 
| <longcomments(100)> | 
| ---- | 
| [[위키위키분류]] | 
-  /화일업로드를 통해 업로드한 화일들의 목록을 출력하고, 화일을 삭제할 수 있게 하는 인터페이스를 제공한다.
-  필수 요구 사항:
-  /화일업로드 패치가 적용되어 있어야 의미가 있다.
-  이 패치에 맞춰서 /역링크 패치가 조금 수정되었다. 확인할 것.
 
-  선택 요구 사항:
-  사용법 : <uploadedfiles>
-  화일 목록이 테이블로 출력된다. 화일의 이름, 화일의 크기, 업로드한 날짜와 시각이 출력되며, 가장 최근에 업로드한 화일이 가장 위에 출력된다. (이 테이블과 그 안의 쉘들은 "uploadedfiles" 라는 클래스로 지정되어 있다. UseModWiki스타일쉬트에서 색상을 조절할 것)
-  화일 이름을 클릭하면 해당 화일을 브라우저로 열 수 있다.
-  화일 이름 왼쪽에 있는  아이콘을 클릭하면 해당 화일을 링크하고 있는 페이지를 찾는다. 이 아이콘은 "IconDir 로 지정된 디렉토리/upload-search.gif" 으로 존재해야 한다. 이 때 "Upload:화일명" 의 역링크를 찾는 방식으로 검색한다. 즉 http URL 을 그대로 적어넣은 경우에는 찾을 수 없다. 아이콘을 클릭하면 해당 화일을 링크하고 있는 페이지를 찾는다. 이 아이콘은 "IconDir 로 지정된 디렉토리/upload-search.gif" 으로 존재해야 한다. 이 때 "Upload:화일명" 의 역링크를 찾는 방식으로 검색한다. 즉 http URL 을 그대로 적어넣은 경우에는 찾을 수 없다.
-  관리자 권한을 갖고 있는 경우는 각 화일의 이름 왼쪽에 체크박스가 나타난다. 
-   (관리자 권한이 있는 경우의 출력화면) (관리자 권한이 있는 경우의 출력화면)
-  삭제하고자 하는 화일의 왼쪽에 있는 체크박스에 체크를 하고 "선택한 화일 삭제"를 클릭하면 삭제된다. (되살릴 수 없으니 주의할 것)
 
-  wiki.pl
sub MacroSubst {
    ...
    $txt =~ s/(\&__LT__;uploadedfiles\&__GT__;)/&MacroUploadedFiles($1)/gei;
    return $txt;
}
-  함수를 통채로 추가
sub MacroUploadedFiles {
    my ($itself) = (@_);
    my (@files, %filesize, %filemtime, $size, $totalSize);
    my $txt;
    my $uploadsearch = "<img style='border:0' src='$IconUrl/upload-search.gif'>";
    my $canDelete = &UserIsAdmin();
    if (!(-e $UploadDir)) {
        &CreateDir($UploadDir);
    }
    opendir (DIR, "$UploadDir") || die Ts('cant opening %s', $UploadDir) . ": $!";
    @files = grep { !/^\.\.?$/ } readdir(DIR);
    close (DIR);
    $totalSize = 0;
    foreach (@files) {
        $filesize{$_} = (-s "$UploadDir/$_");
        $totalSize += $filesize{$_};
        $filemtime{$_} = ($Now - (-M "$UploadDir/$_") * 86400);
    }
    @files = sort {
        $filemtime{$b} <=> $filemtime{$a}
                ||
                $a cmp $b
    } @files;
    my ( @dirs, @p_files );
    foreach my $f ( @files ) {
        if ( -d "$UploadDir/$f" ) {
            push @dirs, $f;
        }
        else {
            push @p_files, $f;
        }
    }
    $txt = $q->start_form("post","$ScriptName","");
    $txt .= "<input type='hidden' name='action' value='deleteuploadedfiles'>";
    $txt .= "<input type='hidden' name='pagename' value='$OpenPageName'>";
    $txt .= "<TABLE class='uploadedfiles'>";
    $txt .= "<TR class='uploadedfiles'>";
    if ($canDelete) {
        $txt .= "<TH class='uploadedfiles'><b>".T('Delete')."</b></TH>";
    }
    $txt .= "<TH class='uploadedfiles'><b>".T('File Name')."</b></TH>".
        "<TH class='uploadedfiles'><b>".T('Size (byte)')."</b></TH>".
        "<TH class='uploadedfiles'><b>".T('Date')."</b></TH>";
    $txt .= "</TR>\n";
    foreach (@dirs, @p_files) {
        $txt .= "<TR class='uploadedfiles'>";
        if ($canDelete) {
            $txt .= "<TD class='uploadedfiles' align='center'>";
            $txt .= "<input type='checkbox' name='files' value='$_'></input> ";
            $txt .= "</TD>";
        }
        $txt .= "<TD class='uploadedfiles'>";
        $txt .= &GetReverseLink("Upload:$_", $uploadsearch) . " ";
        if ( -d "$UploadDir/$_" ) {
            $txt .= "$_/";
        }
        else {
            $txt .= "<a href='$UploadUrl/$_'>$_</a>";
        }
        $txt .= "</TD>";
        $size = $filesize{$_};
        while ($size =~ m/(\d+)(\d{3})((,\d{3})*$)/) {
            $size = "$1,$2$3";
        }
        $txt .= "<TD class='uploadedfiles' align='right'>$size</TD>";
        $txt .= "<TD class='uploadedfiles'>".&TimeToText($filemtime{$_})."</TD>";
        $txt .= "</TR>\n";
    }
    $txt .= "<TR class='uploadedfiles'>";
    $txt .= "<TD class='uploadedfiles'> </TD>" if ($canDelete);
    $txt .= "<TD class='uploadedfiles'>";
    $txt .= "<b>". Ts('Total %s files', ($#files + 1))."</b>";
    $txt .= "</TD>";
    while ($totalSize =~ m/(\d+)(\d{3})((,\d{3})*$)/) {
        $totalSize = "$1,$2$3";
    }
    $txt .= "<TD class='uploadedfiles' align='right'>";
    $txt .= "<b>$totalSize</b>";
    $txt .= "</TD>";
    $txt .= "<TD class='uploadedfiles'> </TD></TR>\n";
    $txt .= "</TABLE>";
    $txt .= $q->submit(T('Delete Checked Files')) if ($canDelete);
    $txt .= $q->endform;
    return $txt;
}
- 
sub DoOtherRequest {
    ...
        } elsif ($action eq "upload") {
            &DoUpload();
        } elsif ($action eq "deleteuploadedfiles") {
            &DoDeleteUploadedFiles();
        } else {
            
            &ReportError(Ts('Invalid action parameter %s', $action));
    ...
}
-  함수를 통채로 추가
sub DoDeleteUploadedFiles {
    my (%vars, @files);
    print &GetHeader("", T('Delete Uploaded Files'), "");
    if (!(&UserIsAdmin())) {
        print T('Deleting is not allowed');
        print "<br>\n";
    } else {
        %vars = $q->Vars;
        @files = split(/\0/,$vars{'files'}, -1);
        foreach (@files) {
            if ( -d "$UploadDir/$_" ) {
                foreach my $sub_f ( glob("$UploadDir/$_/*") ) {
                    unlink $sub_f;
                }
                if ( rmdir "$UploadDir/$_" ) {
                    print Ts('%s is deleted successfully', $_)."<br>";
                }
                else {
                    print Ts('%s can not be deleted', $_). " : $!<br>";
                }
            }
            else {
                if (unlink ("$UploadDir/$_")) {
                    print Ts('%s is deleted successfully', $_)."<br>";
                } else {
                    print Ts('%s can not be deleted', $_). " : $!<br>";
                }
            }
        }
    }
    if (&GetParam('pagename') ne "") {
        print "<hr size='1'>".Ts('Return to %s' , &GetPageLink(&GetParam('pagename')));
    }
    print &GetCommonFooter();
}
-  translations/korean.pl
Delete
삭제
File Name
화일명
Size (byte)
크기 (byte)
Date
날짜
Total %s files
전체 화일 갯수 : %s
Delete Checked Files
선택한 화일 삭제
Delete Uploaded Files
업로드한 화일 삭제
Deleting is not allowed
화일 삭제가 허용되지 않습니다
%s is deleted successfully
%s 화일이 삭제되었습니다
%s can not be deleted
%s 화일을 삭제할 수 없습니다
Notes
돋보기 아이콘을 클릭했을 때, 어떻게 검색을 할 것인가를 궁리해 봤는데
-  "화일명" 을 full text search 하는 방법 - NoSmoke 에서 이렇게 하고 있던데, 페이지 수가 늘어날 때 full text search 속도가 어떤지는 이미 알고 있기에, 그다지 좋아 보이지 않습니다. 그리고 "화일명" 앞에 3_, 4_ 등의 prefix 가 붙는 경우라던가, {{{ }}} 등 안에 있어서 실제로는 링크가 아닌 경우 등도 검색에 걸리는 게 맘에 안 듭니다.
-  "Upload:화일명" 을 full text search 하는 방법 - 이도 저도 아닌...
-  "Upload:화일명" 의 역링크 검색을 하는 방법 - 이게 제일 정확하게 '링크'만을 찾아주고, 속도도 /링크를별도의화일로관리 패치가 되어 있으면 전체 텍스트 검색보다 훨씬 빠릅니다. 단 이 경우의 단점은 위에서 적었듯이 인터위키 형식으로 적지 않고 http 로 시작하는 전체 URL 로 링크를 해 버린 경우는 찾아 낼 수 없습니다.
추가 업데이트 내역
ext1.42b 에서 한 라인이 수정되었습니다. /화일업로드를 꼭 읽어보세요.
2268c2269
<       $txt .= "<a href='$UploadDir/$_'>$_</a>";
---
>       $txt .= "<a href='$UploadUrl/$_'>$_</a>";
ext1.95b
-  서버의 파일 시스템에 따라 (사실 정확한 이유는 모름) 디렉토리 목록을 읽었을 때 "."과 ".."이 제일 먼저 나오지 않는 경우가 있음. 이런 경우 출력되어야 할 파일이 출력되지 않고 "."와 ".."이 출력되는 문제가 있음. 수정.
-  테이블을 이루는 html출력을 한 줄로 처리하게 했더니 한 줄이 너무 길어지는 문제가 있음. 테이블 행마다 (TR태그쌍) 줄바꿈을 넣어줌.
ext2.25사용자 의견
Hi and good evening over there, 
a minor tweak: 
 
- if (!(-e $UploadDir)) { 
        &CreateDir($UploadDir); 
-    } 
 
"&CreateDir" implies "if (!(-e $UploadDir))", isn´t it?. 
Thanks. 
By the way, this great feature open the way to bulk actions on whole wiki. 
-  You're right. The 'if' test isn't necessary. Thank you. 
I'm sorry but I can't understand your second comment. 
You're right Raymundo, because I didn't put examples about that second comment. For instance, this snippet can be reuse in order to all-pages list with check box and to do selective erase, lock, hide and other actions over files (I hope to do something about this in a future).  I was having in mind during long time this feature that I am watching here!. :)
One more subject about file attributes (if you like), I use http://search.cpan.org/~rjray/Image-Size-3.230/lib/Image/Size.pm on my system, so I can obtain the dimensions of an image. 
Kind Regards. 
 
("open" wants to mean "opens" at previous comment of mine.) 
-  Oh, I see. :-) That's a good idea. 
Hi Mr. Raymundo,
this is an intend to implement a new action for admins that returns a list of all pages in order to check or uncheck the lock parameter, having bulk action style. 
It works fine for me (big thanks for your snippets). 
 
 
sub PrintPageLockList { 
  my ($pagename, @pagename); 
  my ($status, $altname); 
  my (@results) = @_; 
  my %hash; 
 
  print &GetHeader('', T("'Read' Bulk"), ''); 
  print $q->start_form("post","$ScriptName",""); 
  print "<input type='hidden' name='action' value='lockcheckedfiles'>"; 
  print "<input type='hidden' name='pagename' value='$OpenPageName'>"; 
  print '<ol>'; 
  foreach $pagename (&AllPagesList()) { 
    next if (&PageIsHidden($pagename)); 
    @pagename = split (/\//,$pagename); 
    print '<li>'; 
    if (-f &GetLockedPageFile($pagename)) { 
      print "<input type='checkbox' name='doit' value='$pagename' checked='1'></input> "; 
    } else { 
      print "<input type='checkbox' name='doit' value='$pagename' ></input> "; 
    } 
    if (!&GetParam('checked') && -f &GetLockedPageFile($pagename)) { 
      print "<input type='hidden' name='undo' value='$pagename' ></input>" ; 
    } 
    for (1 .. $#pagename) {print ' . ',} 
    print &GetPageLink($pagename); 
    }  
  } 
  print '<br>'; 
  print $q->submit(T('DoIt')) if (&UserIsAdmin()); 
  print $q->endform; 
  print '</ol>'; 
  print &GetFooterText(); 
} 
 
sub DoLockCheckedFiles { 
  my (%vars, %srav, %count, @doit, @undo, @diffs); 
  my $fname; 
  my $diffs; 
 
  print &GetHeader("", T('Lock Checked Files'), ""); 
  return  if (!&UserIsAdminOrError()); 
  %srav = 0; 
  %srav = $q->Vars; 
  @undo = split(/\0/,$srav{'undo'}, -1); 
  %vars = 0; 
  %vars = $q->Vars; 
  @doit = split(/\0/,$vars{'doit'}, -1); 
  # Uncommon elements (changes for submit: check to unchek or viceversa) 
  map $count{$_}++ , @doit, @undo; 
  $, = ""; 
  push (@diffs, grep $count{$_} == 1, @doit, @undo); 
  if (@diffs) { 
    foreach (@diffs) { 
      $fname = &GetLockedPageFile($_); 
      if (-f $fname) { 
        unlink $fname; 
        print Ts('%s is unlocked successfully', $_) .'<br>'; 
        next; 
      } 
      if (!-f $fname)  { 
        &WriteStringToFile($fname, "editing locked."); 
        print Ts('%s is locked successfully', $_) .'<br>'; 
      } 
    } 
  } else { 
    print T('Invalid URL or bulk does not exist --nothing done'); 
  } 
  print &GetFooterText(); 
} 
 
Good weekend! :) 
 
--JuanmaMP 
Sorry for $altname, &GetFooterText and perhaps, other oddities coming from my own hacked code. 
Regards 
Hi over there, 
a bit polished of this matter, here:  WikiPatches/BulkLock.
WikiPatches/BulkLock. 
Hope it's fun ... 
-  Wow, you're so active in usemod.org! Great! :-D 
yep, for the being time, a really peaceful place ... :)) 
the next patch that I would like uploading is "this site is hidden" (visibility under password).
Something like this:  
 .
. 
I'll share it. 
Good night over there. 
if you prefer erased my last comment to your choice. I wanted uploading a typical login snapshot into a web but finally it returned that thing. Sorry. 
-  LOL, I had to guess 'what is that?' hahaha. It's okay. 
위키위키분류