Skip to content

Commit

Permalink
Item9322: Update Config.spec, PerlTidy,
Browse files Browse the repository at this point in the history
   Restore configurable RemoveMissing option
   Report results back to the rest user.

git-svn-id: http://svn.foswiki.org/trunk/UpdateAttachmentsPlugin@10272 0b4bb1d4-4e5a-0410-9cc4-b2b747904278
  • Loading branch information
GeorgeClark authored and GeorgeClark committed Dec 12, 2010
1 parent 1c1bad2 commit b434f6e
Show file tree
Hide file tree
Showing 2 changed files with 132 additions and 65 deletions.
183 changes: 126 additions & 57 deletions lib/Foswiki/Plugins/UpdateAttachmentsPlugin.pm
Expand Up @@ -18,61 +18,72 @@ use strict;

our $VERSION = '$Rev$';
our $RELEASE = 'Foswiki-1.0';
our $SHORTDESCRIPTION = 'A batched alternative to AutoAttachments (adds and removes attachements)';
our $SHORTDESCRIPTION =
'A batched alternative to AutoAttachments (adds and removes attachements)';
our $NO_PREFS_IN_TOPIC = 1;

my $debug = 0;

sub initPlugin {
my( $topic, $web, $user, $installWeb ) = @_;
my ( $topic, $web, $user, $installWeb ) = @_;

# check for Plugins.pm versions
if( $Foswiki::Plugins::VERSION < 2.1 ) {
Foswiki::Func::writeWarning( "Version mismatch between UpdateAttachmentsPlugin and Plugins.pm" );
if ( $Foswiki::Plugins::VERSION < 2.1 ) {
Foswiki::Func::writeWarning(
"Version mismatch between UpdateAttachmentsPlugin and Plugins.pm");
return 0;
}

$debug = $Foswiki::cfg{Plugins}{UpdateAttachmentsPlugin}{Debug} || 0;
Foswiki::Func::registerRESTHandler('update', \&restUpdate);
Foswiki::Func::registerRESTHandler( 'update', \&restUpdate );
return 1;
}


sub restUpdate {
my $session = shift;
my $store = $session->{store};
my $web = $session->{webName};
my $store = $session->{store};
my $web = $session->{webName};

print STDERR "update the attachments of $web\n" if $debug;

#force autoattach off, as we need to know the real META
my $cfgAutoAttach = $Foswiki::cfg{AutoAttachPubFiles};
$Foswiki::cfg{AutoAttachPubFiles} = 0;
#TODO: consider the lighter weight aproach of scanning timestamps in the pub dir
# checking&updating only those topics that have newer timestamp pub files
# (it would only helps adding attachments, not removing them)
my $topicsTested = 0;
my $topicsUpdated = 0;

#TODO: consider the lighter weight aproach of scanning timestamps in the pub dir
# checking&updating only those topics that have newer timestamp pub files
# (it would only helps adding attachments, not removing them)

my $topicsTested = 0;
my $topicsUpdated = 0;
my $attachmentsIgnored = 0;
my $attachmentsRemoved = 0;
my $attachmentsAdded = 0;
my $attachmentsAdded = 0;
my $attachmentsUpdated = 0;
my $detailedReport = '';

#TODO: test user's access to web (rest already tests for web CHANGE access)
my @topicNames = Foswiki::Func::getTopicList( $web );
my @topicNames = Foswiki::Func::getTopicList($web);
foreach my $topic (@topicNames) {
# test user's permission on this topic (do this first, eventually this check may not read the topic.. for now it will populate the cache)
next if (!Foswiki::Func::checkAccessPermission( 'CHANGE', Foswiki::Func::getWikiName(), undef, $topic, $web ));

my $changed = 0;
my $topicObject = Foswiki::Meta->load( $session, $web, $topic );

if ( !$topicObject->haveAccess('CHANGE') ) {
$detailedReport .=
"bypassed $web.$topic - no permission to change <br/>\n";
$topicObject->finish();
next;
}

my $topicObject = Foswiki::Meta->load($session, $web, $topic);
my @knownAttachments = $topicObject->find('FILEATTACHMENT');
my ($attachmentsFoundInPub, $attachmentsRemovedFromMeta, $attachmentsAddedToMeta, $attachmentsUpdatedInMeta) =
synchroniseAttachmentsList($topicObject, \@knownAttachments );
my (
$attachmentsFoundInPub, $attachmentsRemovedFromMeta,
$attachmentsAddedToMeta, $attachmentsUpdatedInMeta
) = synchroniseAttachmentsList( $topicObject, \@knownAttachments );

# @validAttachmentsFound will contain the replacment attachment Metadata
my @validAttachmentsFound;

foreach my $foundAttachment (@$attachmentsFoundInPub) {

# test if the attachment filename is valid without having to
Expand All @@ -83,7 +94,8 @@ sub restUpdate {
&& $validated eq $foundAttachment->{name} )
{

print STDERR 'AutoAttachPubFiles ignoring '
$detailedReport .=
'AutoAttachPubFiles ignoring '
. $foundAttachment->{name} . ' in '
. $topicObject->getPath()
. ' - not a valid Foswiki Attachment filename';
Expand All @@ -96,31 +108,57 @@ sub restUpdate {
$topicObject->putAll( 'FILEATTACHMENT', @validAttachmentsFound )
if @validAttachmentsFound;


#TODO: actually test that they are the same! (update size, date etc)
print STDERR "$web.$topic has ".scalar(@knownAttachments)." in meta, ".scalar(@$attachmentsFoundInPub)." in pub dir\n" if $debug;

$changed = scalar(@$attachmentsRemovedFromMeta) + scalar(@$attachmentsAddedToMeta) + scalar(@$attachmentsUpdatedInMeta);
print STDERR "$web.$topic has "
. scalar(@knownAttachments)
. " in meta, "
. scalar(@$attachmentsFoundInPub)
. " in pub dir\n"
if $debug;

$changed =
scalar(@$attachmentsRemovedFromMeta) +
scalar(@$attachmentsAddedToMeta) +
scalar(@$attachmentsUpdatedInMeta);

if ($changed) {
$topicObject->save( comment => 'UpdateAttachments' );
$topicObject->save( comment => 'UpdateAttachments' );
print STDERR "updating the attachments of $web.$topic\n" if $debug;
$topicsUpdated++;
$attachmentsRemoved += scalar(@$attachmentsRemovedFromMeta);
$attachmentsAdded += scalar(@$attachmentsAddedToMeta);
$attachmentsAdded += scalar(@$attachmentsAddedToMeta);
$attachmentsUpdated += scalar(@$attachmentsUpdatedInMeta);

$detailedReport .= "Updating $web.$topic <br/>\n";
foreach my $attach (@$attachmentsRemovedFromMeta) {
$detailedReport .= "Removed $attach <br/>";
}
foreach my $attach (@$attachmentsAddedToMeta) {
$detailedReport .= "Added $attach <br/>";
}
foreach my $attach (@$attachmentsUpdatedInMeta) {
$detailedReport .= "Updated $attach <br/>";
}
}
$topicsTested++;
$topicObject->finish();

#TODO: $Foswiki::cfg{Plugins}{UpdateAttachmentsPlugin}{BatchLimit}

}

print STDERR "UpdateAttachments checked $topicsTested, updated $topicsUpdated, removed $attachmentsRemoved attachments, $attachmentsIgnored ignored" if $debug;
print STDERR
"UpdateAttachments checked $topicsTested, updated $topicsUpdated, removed $attachmentsRemoved attachments, $attachmentsIgnored ignored"
if $debug;

# Restore auto-attach setting. (This *really* ought to be disabled if using this plugin
$Foswiki::cfg{AutoAttachPubFiles} = $cfgAutoAttach ;
# Restore auto-attach setting. (This *really* ought to be disabled if using this plugin
$Foswiki::cfg{AutoAttachPubFiles} = $cfgAutoAttach;

return "UpdateAttachments Topics checked $topicsTested, updated $topicsUpdated, <br/> Attachments updated $attachmentsUpdated, added $attachmentsAdded, removed $attachmentsRemoved attachments, $attachmentsIgnored ignored";
return <<HERE
UpdateAttachments Topics checked $topicsTested, updated $topicsUpdated, <br/>
Attachments updated $attachmentsUpdated, added $attachmentsAdded, removed $attachmentsRemoved, ignored $attachmentsIgnored <br/><br/>
$detailedReport
HERE
}

=begin TML
Expand All @@ -141,12 +179,12 @@ put in the new tom.
sub synchroniseAttachmentsList {
my ( $topicObject, $attachmentsKnownInMeta ) = @_;

my %filesListedInPub = _getAttachmentStats($topicObject);
my %filesListedInMeta = ();
my %filesToAddToMeta = ();
my %filesListedInPub = _getAttachmentStats($topicObject);
my %filesListedInMeta = ();
my %filesToAddToMeta = ();
my @filesRemovedFromMeta = ();
my @filesAddedToMeta = ();
my @filesUpdatedInMeta = ();
my @filesAddedToMeta = ();
my @filesUpdatedInMeta = ();

# You need the following lines if you want metadata to supplement
# the filesystem
Expand All @@ -157,12 +195,16 @@ sub synchroniseAttachmentsList {

foreach my $file ( keys %filesListedInPub ) {
if ( $filesListedInMeta{$file} ) {
if ( $filesListedInMeta{$file}{size} ne $filesListedInPub{$file}{size} ||
$filesListedInMeta{$file}{date} ne $filesListedInPub{$file}{date} ) {
if ( $filesListedInMeta{$file}{size} ne
$filesListedInPub{$file}{size}
|| $filesListedInMeta{$file}{date} ne
$filesListedInPub{$file}{date} )
{
$filesListedInPub{$file}{autoattached} = "1";
push @filesUpdatedInMeta, $file;
print STDERR "Updating $file \n";
}

# Bring forward any missing yet wanted attribute
foreach my $field qw(comment attr user version autoattached) {
if ( $filesListedInMeta{$file}{$field} ) {
Expand All @@ -172,14 +214,26 @@ sub synchroniseAttachmentsList {
}
}
else {

#default attachment owner to {AttachAsUser}
push @filesAddedToMeta, $file;
print STDERR "Adding $file \n";
$filesListedInPub{$file}{autoattached} = "1";
if ((defined($Foswiki::cfg{Plugins}{UpdateAttachmentsPlugin}{AttachAsUser})) &&
($Foswiki::cfg{Plugins}{UpdateAttachmentsPlugin}{AttachAsUser} ne '')) {
$filesListedInPub{$file}{user} = $Foswiki::cfg{Plugins}{UpdateAttachmentsPlugin}{AttachAsUser};
#TODO: needs testing for the generalised usermapping case - shoudl store cUID
if (
(
defined(
$Foswiki::cfg{Plugins}{UpdateAttachmentsPlugin}
{AttachAsUser}
)
)
&& ( $Foswiki::cfg{Plugins}{UpdateAttachmentsPlugin}
{AttachAsUser} ne '' )
)
{
$filesListedInPub{$file}{user} =
$Foswiki::cfg{Plugins}{UpdateAttachmentsPlugin}{AttachAsUser};

#TODO: needs testing for the generalised usermapping case - shoudl store cUID
}
}
}
Expand All @@ -188,17 +242,26 @@ sub synchroniseAttachmentsList {
# would show files that were in Meta but have disappeared from Pub.

foreach my $file ( keys %filesListedInMeta ) {
if (! $filesListedInPub{$file} ) {
print STDERR "Removing $file \n";
push @filesRemovedFromMeta, $file;
if ( !$filesListedInPub{$file} ) {
if (
$Foswiki::cfg{Plugins}{UpdateAttachmentsPlugin}{RemoveMissing} )
{
print STDERR "Removing $file \n" if $debug;
push @filesRemovedFromMeta, $file;
}
else {
$filesListedInPub{$file} = $filesListedInMeta{$file};
print STDERR "Retained missing attachment $file\n" if $debug;
}
}
}

# Do not change this from array to hash, you would lose the
# proper attachment sequence
my @deindexedBecauseMetaDoesnotIndexAttachments = values(%filesListedInPub);

return \@deindexedBecauseMetaDoesnotIndexAttachments, \@filesRemovedFromMeta, \@filesAddedToMeta, \@filesUpdatedInMeta;
return \@deindexedBecauseMetaDoesnotIndexAttachments,
\@filesRemovedFromMeta, \@filesAddedToMeta, \@filesUpdatedInMeta;
}

=begin TML
Expand All @@ -211,7 +274,10 @@ Get list of attachment names actually stored for topic.

sub getAttachmentList {
my $topicObject = shift;
my $dir = "$Foswiki::cfg{PubDir}/" . $topicObject->web() . "/" . $topicObject->topic();
my $dir =
"$Foswiki::cfg{PubDir}/"
. $topicObject->web() . "/"
. $topicObject->topic();
my $dh;
opendir( $dh, $dir ) || return ();
my @files = grep { !/^[.*_]/ && !/,v$/ } readdir($dh);
Expand All @@ -222,9 +288,12 @@ sub getAttachmentList {
# returns {} of filename => { key => value, key2 => value }
# for any given web, topic
sub _getAttachmentStats {
my $topicObject = shift;
my $topicObject = shift;
my %attachmentList = ();
my $dir = "$Foswiki::cfg{PubDir}/" . $topicObject->web() . '/' . $topicObject->topic();
my $dir =
"$Foswiki::cfg{PubDir}/"
. $topicObject->web() . '/'
. $topicObject->topic();
foreach my $attachment ( getAttachmentList($topicObject) ) {
my @stat = stat( $dir . "/" . $attachment );
$attachmentList{$attachment} =
Expand All @@ -246,8 +315,8 @@ sub _constructAttributesForAutoAttached {
date => $stat->[9],

# user => 'UnknownUser', #safer _not_ to default - Foswiki will fill it in when it needs to
comment => '',
attr => '',
comment => '',
attr => '',
);

if ( $#$stat > 0 ) {
Expand Down
14 changes: 6 additions & 8 deletions lib/Foswiki/Plugins/UpdateAttachmentsPlugin/Config.spec
@@ -1,14 +1,12 @@
#---++ Extensions
#---+ Extensions
#---++ Update Attachments Plugin
# **STRING**
# To attribute attachments to a known user, set this to their WikiName. This user should exist,
# and be mappable to a login.
# and be mappable to a login. If not set, the default UnknownUser will be used.
$Foswiki::cfg{Plugins}{UpdateAttachmentsPlugin}{AttachAsUser} = '';
# **BOOLEAN**
# remove references to attachments that no longer exist in pub
$Foswiki::cfg{Plugins}{UpdateAttachmentsPlugin}{RemoveMissing} = $FALSE;
# Remove references to attachments that no longer exist in pub.
$Foswiki::cfg{Plugins}{UpdateAttachmentsPlugin}{RemoveMissing} = $TRUE;
# **BOOLEAN**
# use the _internal_ _noHandlersSave - This option causes the topic update code to write directly into the
# Store, bypassing the API's and other Handlers. This is *Strongly* not recommended. This may break in
# future and is not recomended unless you know the code.
$Foswiki::cfg{Plugins}{UpdateAttachmentsPlugin}{UseDangerousNoHandlersSave} = $FALSE;
# Enable debugging messages - printed to STDERR (Apache error_log file)
$Foswiki::cfg{Plugins}{UpdateAttachmentsPlugin}{Debug} = $FALSE;

0 comments on commit b434f6e

Please sign in to comment.