(file) Return to Attach.pm CVS log (file) (dir) Up to [RizwankCVS] / geekymedia_web / twiki / lib / TWiki

  1 rizwank 1.1 # Module of TWiki Collaboration Platform, http://TWiki.org/
  2             #
  3             # Copyright (C) 2001-2004 Peter Thoeny, peter@thoeny.com
  4             #
  5             # For licensing info read license.txt file in the TWiki root.
  6             # This program is free software; you can redistribute it and/or
  7             # modify it under the terms of the GNU General Public License
  8             # as published by the Free Software Foundation; either version 2
  9             # of the License, or (at your option) any later version.
 10             #
 11             # This program is distributed in the hope that it will be useful,
 12             # but WITHOUT ANY WARRANTY; without even the implied warranty of
 13             # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 14             # GNU General Public License for more details, published at 
 15             # http://www.gnu.org/copyleft/gpl.html
 16             #
 17             # Notes:
 18             # - Latest version at http://twiki.org/
 19             # - Installation instructions in $dataDir/TWiki/TWikiDocumentation.txt
 20             # - Customize variables in TWiki.cfg when installing TWiki.
 21             
 22 rizwank 1.1 use strict;
 23             
 24             =begin twiki
 25             
 26             ---+ TWiki::Attach Module
 27             
 28             This package contains routines for dealing with attachments to topics.
 29             
 30             =cut
 31             
 32             package TWiki::Attach;
 33             
 34             use vars qw( %templateVars );
 35             
 36             # ======================
 37             =pod
 38             
 39             ---++ sub renderMetaData (  $web, $topic, $meta, $args, $isTopRev  )
 40             
 41             Generate a table of attachments suitable for the bottom of a topic
 42             view, using templates for the header, footer and each row.
 43 rizwank 1.1 | =$web= | the web |
 44             | =$topic= | the topic |
 45             | =$meta= | meta-data hash for the topic |
 46             | =$attrs= | hash of attachment arguments |
 47             | $isTopTopicRev | 1 if this topic is being rendered at the most recent revision |
 48             
 49             =cut
 50             
 51             sub renderMetaData
 52             {
 53                 my( $web, $topic, $meta, $attrs, $isTopTopicRev ) = @_;
 54             
 55                 my $showAll = TWiki::extractNameValuePair( $attrs, "all" );
 56                 my $showAttr = $showAll ? "h" : "";
 57             	my $a = ( $showAttr ) ? ":A" : "";
 58             
 59             	my @attachments = $meta->find( "FILEATTACHMENT" );
 60             
 61             	my $rows = "";
 62             	my $row = _getTemplate("ATTACH:files:row$a");
 63                 foreach my $attachment ( @attachments ) {
 64 rizwank 1.1 	  my $attrAttr = $attachment->{attr};
 65             
 66             	  if( ! $attrAttr || ( $showAttr && $attrAttr =~ /^[$showAttr]*$/ )) {
 67             		$rows .= _formatRow( $web,
 68             							 $topic,
 69             							 $attachment->{name},
 70             							 $attachment->{version},
 71             							 $isTopTopicRev,
 72             							 $attachment->{date},
 73             							 $attachment->{user},
 74             							 $attachment->{comment},
 75             							 $attachment,
 76             							 $row );
 77             	  }
 78                 }
 79             
 80                 my $text = "";
 81             
 82                 if( $showAll || $rows ne "" ) {
 83             	  my $header = _getTemplate("ATTACH:files:header$a");
 84             	  my $footer = _getTemplate("ATTACH:files:footer$a");
 85 rizwank 1.1 
 86             	  $text = "$header$rows$footer";
 87                 }
 88                 return $text;
 89             }
 90             
 91             # PRIVATE get a template, reading the attachment tables template
 92             # if not already defined.
 93             sub _getTemplate {
 94               my $template = shift;
 95             
 96               if ( ! defined( $templateVars{$template} )) {
 97             	TWiki::Store::readTemplate("attachtables");
 98               }
 99             
100               return TWiki::Store::handleTmplP($template);
101             }
102             
103             #=========================
104             =pod
105             
106 rizwank 1.1 ---++ sub formatVersions (  $theWeb, $theTopic, $attachment, $attrs )
107             
108             Generate a version history table for a single attachment
109             | =$web= | the web |
110             | =$topic= | the topic |
111             | =$attachment= | basename of attachment |
112             | =$attrs= | Hash of meta-data attributes |
113             
114             =cut
115             
116             sub formatVersions {
117               my( $web, $topic, $attachment, $attrs ) = @_;
118             
119               my $latestRev = TWiki::Store::getRevisionNumber( $web, $topic, $attachment );
120               $latestRev =~ m/\.(.*)/o;
121               my $maxRevNum = $1;
122             
123               my $header = _getTemplate("ATTACH:versions:header");
124               my $footer = _getTemplate("ATTACH:versions:footer");
125               my $row    = _getTemplate("ATTACH:versions:row");
126             
127 rizwank 1.1   my $rows ="";
128             
129               for( my $version = $maxRevNum; $version >= 1; $version-- ) {
130                 my $rev = "1.$version";
131             
132             	my( $date, $userName, $minorRev, $comment ) = 
133             	  TWiki::Store::getRevisionInfo( $web, $topic, $rev, $attachment );
134             	$rows .= _formatRow( $web, $topic,
135             						 $attachment,
136             						 $rev,
137             						 ( $rev eq $latestRev),
138             						 $date,
139             						 $userName,
140             						 $comment,
141             						 $attrs,
142             						 $row );
143               }
144             
145               return "$header$rows$footer";
146             }
147             
148 rizwank 1.1 #=========================
149             =pod
150             
151             ---++ sub _formatRow ( $web, $topic, $file, $rev, $topRev, $date, $userName, $comment, $attrs, $tmpl )
152             
153             Format a single row in an attachment table by expanding a template.
154             | =$web= | the web |
155             | =$topic= | the topic |
156             | =$file= | the attachment file name |
157             | =$rev= | the required revision; required to be a full (major.minor) revision number |
158             | =$topRev= | boolean indicating if this revision is the most recent revision |
159             | =$date= | date of _this revision_ of the attachment |
160             | =$userName= | user (not wikiname) who uploaded this revision |
161             | =$comment= | comment against this revision |
162             | =$attrs= | reference to a hash of other meta-data attributes for the attachment |
163             
164             =cut
165             
166             sub _formatRow {
167               my ( $web, $topic, $file, $rev, $topRev,
168             	   $date, $userName, $comment, $attrs, $tmpl ) = @_;
169 rizwank 1.1 
170               my $row = $tmpl;
171             
172               $row =~ s/%A_REV%/$rev/go;
173             
174               if ( $row =~ /%A_ICON%/o ) {
175             	my $fileIcon = filenameToIcon( $file );
176             	$row =~ s/%A_ICON%/$fileIcon/go;
177               }
178             
179               if ( $row =~ /%A_URL%/o ) {
180             	my $url;
181             
182             	if ( $topRev ) {
183             	  # I18N: To support attachments via UTF-8 URLs to attachment
184             	  # directories/files that use non-UTF-8 character sets, go through viewfile. 
185             	  # If using %PUBURL%, must URL-encode explicitly to site character set.
186             	  $url = TWiki::handleNativeUrlEncode( "%PUBURLPATH%/$web/$topic/$file" );
187             	} else {
188             	  $url = "%SCRIPTURLPATH%/viewfile%SCRIPTSUFFIX%/".
189             		"$web/$topic?rev=$rev&filename=$file";
190 rizwank 1.1 	}
191             	$row =~ s/%A_URL%/$url/go;
192               }
193             
194               if ( $row =~ /%A_SIZE%/o && $attrs ) {
195                 my $attrSize = $attrs->{size};
196             	$attrSize = 100 if( $attrSize < 100 );
197             	$attrSize = sprintf( "%1.1f&nbsp;K", $attrSize / 1024 );
198             	$row =~ s/%A_SIZE%/$attrSize/go;
199               }
200             
201               $comment =~ s/\|/&#124;/g;
202               $comment = "&nbsp;" unless ( $comment );
203               $row =~ s/%A_COMMENT%/$comment/go;
204             
205               if ( $row =~ /%A_ATTRS%/o && $attrs ) {
206             	my $attrAttr = $attrs->{attr};
207             	$attrAttr = $attrAttr || "&nbsp;";
208             	$row =~ s/%A_ATTRS%/$attrAttr/go;
209               }
210             
211 rizwank 1.1   $row =~ s/%A_FILE%/$file/go;
212             
213               $date = TWiki::formatTime( $date );
214               $row =~ s/%A_DATE%/$date/go;
215             
216               my $wikiUserName = TWiki::userToWikiName( $userName );
217               $row =~ s/%A_USER%/$wikiUserName/go;
218             
219               return $row;
220             }
221             
222             # =========================
223             =pod
224             
225             ---++ sub filenameToIcon (  $fileName  )
226             
227             Produce an image tailored to the type of the file, guessed from
228             it's extension.
229             
230             used in TWiki::handleIcon
231             
232 rizwank 1.1 =cut
233             
234             sub filenameToIcon
235             {
236                 my( $fileName ) = @_;
237             
238                 my @bits = ( split( /\./, $fileName ) );
239                 my $fileExt = lc $bits[$#bits];
240             
241                 my $tmp = &TWiki::getPubDir();
242                 my $iconDir = "$tmp/icn";
243                 my $iconUrl = "$TWiki::pubUrlPath/icn";
244                 my $iconList = &TWiki::Store::readFile( "$iconDir/_filetypes.txt" );
245                 foreach( split( /\n/, $iconList ) ) {
246                     @bits = ( split( / / ) );
247             	if( $bits[0] eq $fileExt ) {
248                         return "<img src=\"$iconUrl/$bits[1].gif\" width=\"16\" height=\"16\" align=\"top\" alt=\"\" border=\"0\" />";
249                     }
250                 }
251                 return "<img src=\"$iconUrl/else.gif\" width=\"16\" height=\"16\" align=\"top\" alt=\"\" border=\"0\" />";
252             }
253 rizwank 1.1 
254             # =========================
255             =pod
256             
257             ---++ sub removeFile ()
258             
259             Remove attachment macro for specified file from topic
260             return "", or error string
261             
262             =cut
263             
264             sub removeFile
265             {
266                 my $theFile = $_[1];
267                 my $error = "";
268                 
269                 # %FILEATTACHMENT{[\s]*"$theFile"[^}]*}%
270                 if( ! ( $_[0] =~ s/%FILEATTACHMENT{[\s]*"$theFile"[^}]*}%//) ) {
271                    $error = "Failed to remove attachment $theFile";
272                 }
273                 return $error;
274 rizwank 1.1 }
275             
276             # =========================
277             =pod
278             
279             ---++ sub updateProperties (  $fileName, $hideFile, $fileComment, $meta  )
280             
281             Not yet documented.
282             
283             =cut
284             
285             sub updateProperties
286             {
287                 my( $fileName, $hideFile, $fileComment, $meta ) = @_;
288             
289                 my %fileAttachment = $meta->findOne( "FILEATTACHMENT", $fileName );
290                 $fileAttachment{"attr"} = ( $hideFile ) ? "h" : "";
291                 $fileAttachment{"comment"} = $fileComment;
292                 $meta->put( "FILEATTACHMENT", %fileAttachment );
293                 # FIXME warning if no entry?
294             }
295 rizwank 1.1 
296             # =========================
297             =pod
298             
299             ---++ sub updateAttachment (  $fileVersion, $fileName, $filePath, $fileSize, $fileDate, $fileUser, $fileComment, $hideFile, $meta  )
300             
301             Add/update attachment for a topic
302             $text is full set of attachments, new attachments will be added to the end.
303             
304             =cut
305             
306             sub updateAttachment
307             {
308                 my ( $fileVersion, $fileName, $filePath, $fileSize, $fileDate, $fileUser, $fileComment, $hideFile, $meta ) = @_;
309             
310                 my $tmpAttr = ( $hideFile ) ? "h" : "";
311             
312                 my( $theFile, $theVersion, $thePath, $theSize, $theDate, $theUser, 
313                          $theComment, $theAttr ) = @_;
314             
315                 my @attrs = (
316 rizwank 1.1 				 "name"    => $fileName,
317             				 "version" => $fileVersion,
318             				 "path"    => $filePath,
319             				 "size"    => $fileSize,
320             				 "date"    => $fileDate,
321             				 "user"    => $fileUser,
322             				 "comment" => $fileComment,
323             				 "attr"    => $tmpAttr
324             				);
325             
326                 $meta->put( "FILEATTACHMENT", @attrs );
327             }
328             
329             #=========================
330             =pod
331             
332             ---++ sub migrateFormatForTopic (  $theWeb, $theTopic, $doLogToStdOut  )
333             
334             Not yet documented.
335             CODE_SMELL: Is this really necessary? migrateFormatForTopic?
336             
337 rizwank 1.1 =cut
338             
339             sub migrateFormatForTopic
340             {
341                my ( $theWeb, $theTopic, $doLogToStdOut ) = @_;
342                
343                my $text = TWiki::Store::readWebTopic( $theWeb, $theTopic );
344                my ( $before, $atext, $after ) = split( /<!--TWikiAttachment-->/, $text );
345                if( ! $before ) { $before = ""; }
346                if( ! $atext  ) { $atext  = ""; }
347             
348                if ( $atext =~ /<TwkNextItem>/ ) {
349                   my $newtext = migrateToFileAttachmentMacro( $atext );
350                   
351                   $text = "$before<!--TWikiAttachment-->$newtext<!--TWikiAttachment-->";
352             
353                   my ( $dontLogSave, $doUnlock, $dontNotify ) = ( "", "1", "1" );
354                   my $error = TWiki::Store::save( $theWeb, $theTopic, $text, "", $dontLogSave, $doUnlock, $dontNotify, "upgraded attachment format" );
355                   if ( $error ) {
356                      print "Attach: error from save: $error\n";
357                   }
358 rizwank 1.1       if ( $doLogToStdOut ) {
359                      print "Changed attachment format for $theWeb.$theTopic\n";
360                   }
361                }
362             }
363             
364             # =========================
365             =pod
366             
367             ---++ sub getOldAttachAttr (  $atext  )
368             
369             Get file attachment attributes for old html
370             format.
371             CODE_SMELL: Is this really necessary? getOldAttachAttr?
372             
373             =cut
374             
375             sub getOldAttachAttr
376             {
377                 my( $atext ) = @_;
378                 my $fileName="";
379 rizwank 1.1 	my $filePath="";
380             	my $fileSize="";
381             	my $fileDate="";
382             	my $fileUser="";
383             	my $fileComment="";
384                 my $before="";
385             	my $item="";
386             	my $after="";
387             
388                 ( $before, $fileName, $after ) = split( /<(?:\/)*TwkFileName>/, $atext );
389                 if( ! $fileName ) { $fileName = ""; }
390                 if( $fileName ) {
391                     ( $before, $filePath,    $after ) = split( /<(?:\/)*TwkFilePath>/, $atext );
392             	if( ! $filePath ) { $filePath = ""; }
393             	$filePath =~ s/<TwkData value="(.*)">//go;
394             	if( $1 ) { $filePath = $1; } else { $filePath = ""; }
395             	$filePath =~ s/\%NOP\%//goi;   # delete placeholder that prevents WikiLinks
396             	( $before, $fileSize,    $after ) = split( /<(?:\/)*TwkFileSize>/, $atext );
397             	if( ! $fileSize ) { $fileSize = "0"; }
398             	( $before, $fileDate,    $after ) = split( /<(?:\/)*TwkFileDate>/, $atext );
399             	if( ! $fileDate ) { 
400 rizwank 1.1             $fileDate = "";
401                     } else {
402                         $fileDate =~ s/&nbsp;/ /go;
403                         $fileDate = &TWiki::revDate2EpSecs( $fileDate );
404                     }
405             	( $before, $fileUser,    $after ) = split( /<(?:\/)*TwkFileUser>/, $atext );
406             	if( ! $fileUser ) { 
407                         $fileUser = ""; 
408                     } else {
409                         $fileUser = &TWiki::wikiToUserName( $fileUser );
410                     }
411             	$fileUser =~ s/ //go;
412             	( $before, $fileComment, $after ) = split( /<(?:\/)*TwkFileComment>/, $atext );
413             	if( ! $fileComment ) { $fileComment = ""; }
414                 }
415             
416                 return ( $fileName, $filePath, $fileSize, $fileDate, $fileUser, $fileComment );
417             }
418             
419             # =========================
420             =pod
421 rizwank 1.1 
422             ---++ sub migrateToFileAttachmentMacro (  $meta, $text  )
423             
424             Migrate old HTML format, to %FILEATTACHMENT ... format
425             for one piece of text
426             CODE_SMELL: Is this really necessary? migrateToFileAttachmentMacro?
427             
428             =cut
429             
430             sub migrateToFileAttachmentMacro
431             {
432                my ( $meta, $text ) = @_;
433                
434                
435                my ( $before, $atext, $after ) = split( /<!--TWikiAttachment-->/, $text );
436                $text = $before || "";
437                $text .= $after if( $after );
438                $atext  = "" if( ! $atext  );
439             
440                if( $atext =~ /<TwkNextItem>/ ) {
441                   my $line = "";
442 rizwank 1.1       foreach $line ( split( /<TwkNextItem>/, $atext ) ) {
443                       my( $fileName, $filePath, $fileSize, $fileDate, $fileUser, $fileComment ) =
444                          getOldAttachAttr( $line );
445             
446                       if( $fileName ) {
447             			my @attrs = (
448             						"name"    => $fileName,
449             						"version" => "",
450             						"path"    => $filePath,
451             						"size"    => $fileSize,
452             						"date"    => $fileDate,
453             						"user"    => $fileUser,
454             						"comment" => $fileComment,
455             						"attr"    => ""
456             					   );
457             			$meta->put( "FILEATTACHMENT", @attrs );
458                       }
459                    }
460                } else {
461                    # Format of macro that came before META:ATTACHMENT
462                    my $line = "";
463 rizwank 1.1        foreach $line ( split( /\n/, $atext ) ) {
464                        if( $line =~ /%FILEATTACHMENT{\s"([^"]*)"([^}]*)}%/ ) {
465                            my $name = $1;
466                            my $rest = $2;
467                            $rest =~ s/^\s*//;
468                            my @values = TWiki::Store::keyValue2list( $rest );
469                            unshift @values, $name;
470                            unshift @values, "name";
471                            $meta->put( "FILEATTACHMENT", @values );
472                        }
473                    }
474                }
475                    
476                return $text;
477             }
478             
479             
480             # =========================
481             =pod
482             
483             ---++ sub upgradeFrom1v0beta (  $meta  )
484 rizwank 1.1 
485             CODE_SMELL: Is this really necessary? upgradeFrom1v0beta?
486             
487             =cut
488             
489             sub upgradeFrom1v0beta
490             {
491                my( $meta ) = @_;
492                
493                my @attach = $meta->find( "FILEATTACHMENT" );
494                foreach my $att ( @attach ) {
495                    my $date = $att->{"date"};
496                    if( $date =~ /-/ ) {
497                        $date =~ s/&nbsp;/ /go;
498                        $date = TWiki::revDate2EpSecs( $date );
499                    }
500                    $att->{"date"} = $date;
501                    $att->{"user"} = &TWiki::wikiToUserName( $att->{"user"} );
502                }
503             }
504             
505 rizwank 1.1 1;

Rizwan Kassim
Powered by
ViewCVS 0.9.2