Merge remote branch 'spunky/rfe11517'

This commit is contained in:
Doug Bell 2010-05-18 11:24:23 -05:00
commit 96a52c5748
7 changed files with 225 additions and 23 deletions

View file

@ -21,6 +21,8 @@
- fixed #11563: Syndicated Content - descriptionFirstParagraph cuts off
- fixed #11538: User invite mail: whitespace in message lost
- fixed #11549: Shortcut Asset cannot override Page Layout
- added #11502: Gallery: Allow specification of location when uploading ZIP archives
- added #11517: Gallery: Sorting of files uploaded in zip archives
7.9.4
- We're shipping underscore.js now for its suite of extremely handy utility

View file

@ -11,20 +11,25 @@ package WebGUI::Asset::Wobject::GalleryAlbum;
#-------------------------------------------------------------------
use strict;
use Class::C3;
use base qw(WebGUI::AssetAspect::RssFeed WebGUI::Asset::Wobject);
use Class::C3;
use Carp qw( croak );
use File::Find;
use File::Spec;
use File::Temp qw{ tempdir };
use Image::ExifTool qw( :Public );
use JSON;
use Tie::IxHash;
use WebGUI::International;
use WebGUI::Utility;
use WebGUI::HTML;
use WebGUI::ProgressBar;
use WebGUI::Storage;
# Do not move this instruction!
use Archive::Any;
=head1 NAME
@ -108,6 +113,12 @@ The name of the file archive to import.
A base set of properties to add to each file in the archive.
=head3 sortBy
Order in which files should be added to the gallery album. Legal values are
'name', 'date' and 'fileOrder'. If missing or invalid, files will be added as
ordered in the archive (default; corresponding to 'fileOrder').
=head3 $outputSub
A callback to use for outputting data, most likely to a progress bar. It expects the
@ -120,6 +131,7 @@ sub addArchive {
my $self = shift;
my $filename = shift;
my $properties = shift;
my $sortBy = shift;
my $outputSub = shift || sub {};
my $gallery = $self->getParent;
my $session = $self->session;
@ -139,6 +151,33 @@ sub addArchive {
find( {
wanted => $wanted,
}, $tempdirName );
# Sort files by date
if ($sortBy eq 'date') {
# Hash for storing last modified timestamps
my %mtimes;
my $exifTool = Image::ExifTool->new;
# Make ExifTool return epoch timestamps
$exifTool->Options('DateFormat', '%s');
# Iterate through all files
foreach my $file (@files) {
# Extract exif data from image
$exifTool->ExtractInfo( $file );
# Get last modified timestamp from exif data
$mtimes{$file} = $exifTool->GetValue('ModifyDate');
# Use last modified date of file as fallback
$mtimes{$file} = (stat($file))[9] unless $mtimes{$file};
}
# Sort files based on last modified timestamps
@files = sort { $mtimes{$a} <=> $mtimes{$b} } @files;
}
# Sort files by name
elsif ($sortBy eq 'name') {
@files = sort @files;
}
for my $filePath (@files) {
my ($volume, $directory, $filename) = File::Spec->splitpath( $filePath );
@ -988,12 +1027,29 @@ sub www_addArchive {
name => "keywords",
value => ( $form->get("keywords") ),
});
$var->{ form_location }
= WebGUI::Form::Text( $session, {
name => "location",
value => ( $form->get("location") ),
});
$var->{ form_friendsOnly }
= WebGUI::Form::yesNo( $session, {
name => "friendsOnly",
value => ( $form->get("friendsOnly") ),
});
$var->{ form_sortBy }
= WebGUI::Form::RadioList( $session, {
name => "sortBy",
value => [ "name" ],
options => {
name => $i18n->get("addArchive sortBy name", 'Asset_GalleryAlbum'),
date => $i18n->get("addArchive sortBy date", 'Asset_GalleryAlbum'),
fileOrder => $i18n->get("addArchive sortBy fileOrder", 'Asset_GalleryAlbum'),
},
});
return $self->processStyle(
$self->processTemplate($var, $self->getParent->get("templateIdAddArchive"))
@ -1011,26 +1067,39 @@ Process the form for adding an archive.
sub www_addArchiveSave {
my $self = shift;
# Return error message if the user viewing does not have permission to add files
return $self->session->privilege->insufficient unless $self->canAddFile;
my $session = $self->session;
my $form = $self->session->form;
my $i18n = WebGUI::International->new( $session, 'Asset_GalleryAlbum' );
my $pb = WebGUI::ProgressBar->new($session);
# Retrieve properties and sort order from form variables
my $properties = {
keywords => $form->get("keywords"),
location => $form->get("location"),
friendsOnly => $form->get("friendsOnly"),
};
my $sortBy = $form->get("sortBy");
# Create progress bar to keep the connection alive
$pb->start($i18n->get('Uploading archive'), $session->url->extras('adminConsole/assets.gif'));
# Retrieve storage containing the uploaded archive
my $storageId = $form->get("archive", "File");
my $storage = WebGUI::Storage->get( $session, $storageId );
if (!$storage) {
return $pb->finish($self->getUrl('func=addArchive;error='.$i18n->get('addArchive error too big')));
}
my $filename = $storage->getPath( $storage->getFiles->[0] );
eval { $self->addArchive( $filename, $properties, sub{ $pb->update(sprintf $i18n->get(shift), @_); }); };
# Get the full path to the archive
my $filename = $storage->getPath( $storage->getFiles->[0] );
# Try to add files in archive as photos
eval { $self->addArchive( $filename, $properties, $sortBy, sub{ $pb->update(sprintf $i18n->get(shift), @_); }); };
# Delete storage containing archive
$storage->delete;
if ( my $error = $@ ) {
return $pb->finish($self->getUrl('func=addArchive;error='.sprintf $i18n->get('addArchive error generic'), $error ));

View file

@ -250,10 +250,18 @@ our $HELP = {
name => 'form_keywords',
description => 'helpvar form_keywords',
},
{
name => 'form_location',
description => 'helpvar form_location',
},
{
name => 'form_friendsOnly',
description => 'helpvar form_friendsOnly',
},
{
name => 'form_sortBy',
description => 'helpvar form_sortBy',
},
],
},

View file

@ -277,11 +277,21 @@ our $I18N = {
message => 'The keywords for the files being uploaded.',
lastUpdated => 0,
},
'helpvar form_location' => {
message => 'The location for the files being uploaded.',
lastUpdated => 0,
},
'helpvar form_friendsOnly' => {
message => 'Should the file be friends only?',
lastUpdated => 0,
},
'helpvar form_sortBy' => {
message => 'Property according to which photos should be sorted.',
lastUpdated => 0,
},
'helpvar url_yes' => {
message => 'Confirm the delete of this Album.',
@ -451,13 +461,43 @@ our $I18N = {
lastUpdated => 0,
context => 'Label for the "keywords" field of the Add Archive page',
},
'addArchive location' => {
message => 'Location',
lastUpdated => 0,
context => 'Label for the "location" field of the Add Archive page',
},
'addArchive friendsOnly' => {
message => 'Friends Only',
lastUpdated => 0,
context => 'Label for the "friends only" field of the Add Archive page',
context => 'Label for the "friendsOnly" field of the Add Archive page',
},
'addArchive sortBy' => {
message => 'Sort By',
lastUpdated => 0,
context => 'Label for the "sortBy" field of the Add Archive page',
},
'addArchive sortBy name' => {
message => 'Name',
lastUpdated => 0,
context => 'Label for the "Name" radio button',
},
'addArchive sortBy date' => {
message => 'Date',
lastUpdated => 0,
context => 'Label for the "Date" radio button',
},
'addArchive sortBy fileOrder' => {
message => 'File Order',
lastUpdated => 0,
context => 'Label for the "File Order" radio button',
},
'template addArchive title' => {
message => "Add Zip Archive",
lastUpdated => 0,

View file

@ -25,7 +25,10 @@ use Test::Deep;
my $session = WebGUI::Test->session;
my $node = WebGUI::Asset->getImportNode($session);
my $versionTag = WebGUI::VersionTag->getWorking($session);
$versionTag->set({name=>"Album Test"});
$versionTag->set({name=>"Add Archive to Album Test"});
addToCleanup($versionTag);
my $gallery
= $node->addChild({
className => "WebGUI::Asset::Wobject::Gallery",
@ -35,6 +38,7 @@ my $gallery
groupIdEdit => 3, # Admins
ownerUserId => 3, # Admin
});
my $album
= $gallery->addChild({
className => "WebGUI::Asset::Wobject::GalleryAlbum",
@ -46,48 +50,127 @@ my $album
skipAutoCommitWorkflows => 1,
});
$album->addArchive( WebGUI::Test->getTestCollateralPath('elephant_images.zip') );
# Properties applied to every photo in the archive
my $properties = {
keywords => "something",
location => "somewhere",
friendsOnly => "1",
};
$versionTag->commit;
#----------------------------------------------------------------------------
# Tests
plan tests => 5;
plan tests => 11;
#----------------------------------------------------------------------------
# Test the addArchive sub
# elephant_images.zip contains three jpgs: Aana1.jpg, Aana2.jpg, Aana3.jpg
$versionTag = WebGUI::VersionTag->getWorking($session);
$album->addArchive( WebGUI::Test->getTestCollateralPath('elephant_images.zip'), $properties );
my $images = $album->getLineage(['descendants'], { returnObjects => 1 });
is( scalar @$images, 3, "addArchive() adds one asset per image" );
cmp_deeply(
cmp_bag(
[ map { $_->get("filename") } @$images ],
bag( "Aana1.jpg", "Aana2.jpg", "Aana3.jpg" ),
[ "Aana1.jpg", "Aana2.jpg", "Aana3.jpg" ],
"Names of files attached to Photo assets match filenames in archive"
);
cmp_deeply(
cmp_bag(
[ map { $_->get("title") } @$images ],
bag( "Aana1", "Aana2", "Aana3" ),
[ "Aana1", "Aana2", "Aana3" ],
"Titles of Photo assets match filenames in archive excluding extensions"
);
cmp_deeply(
cmp_bag(
[ map { $_->get("menuTitle") } @$images ],
bag( "Aana1", "Aana2", "Aana3" ),
[ "Aana1", "Aana2", "Aana3" ],
"Menu titles of Photo assets match filenames in archive excluding extensions"
);
cmp_deeply(
cmp_bag(
[ map { $_->get("url") } @$images ],
bag(
[
$session->url->urlize( $album->getUrl . "/Aana1" ),
$session->url->urlize( $album->getUrl . "/Aana2" ),
$session->url->urlize( $album->getUrl . "/Aana3" ),
),
],
"URLs of Photo assets match filenames in archive excluding extensions"
);
cmp_bag(
[ map { $_->get("keywords") } @$images ],
[ "something", "something", "something" ],
"Keywords of Photo assets match keywords in properties"
);
cmp_bag(
[ map { $_->get("location") } @$images ],
[ "somewhere", "somewhere", "somewhere" ],
"Location of Photo assets match keywords in properties"
);
cmp_bag(
[ map { $_->get("friendsOnly") } @$images ],
[ "1", "1", "1" ],
"Photo assets are viewable by friends only"
);
# Empty gallery album
$versionTag->rollback;
#----------------------------------------------------------------------------
# Test the sorting option of addArchive sub
# gallery_archive_sorting_test.zip contains four jpgs: photo1.jpg, photo2.jpg, photo3.jpg and photo4.jpg
# The following test covers sorting by date, name and file order (default).
$versionTag = WebGUI::VersionTag->getWorking($session);
# Add photos sorted by file order (default)
$album->addArchive( WebGUI::Test->getTestCollateralPath('gallery_archive_sorting_test.zip'), $properties, 'fileOrder' );
# Get all children
my $images = $album->getLineage(['descendants'], { returnObjects => 1 });
# Check order
cmp_deeply(
[ map { $_->get("filename") } @$images ],
[ "photo1.jpg", "photo2.jpg", "photo4.jpg", "photo3.jpg" ],
"Photos sorted by file order"
);
# Empty gallery album
$versionTag->rollback;
$versionTag = WebGUI::VersionTag->getWorking($session);
# Add photos sorted by date
$album->addArchive( WebGUI::Test->getTestCollateralPath('gallery_archive_sorting_test.zip'), $properties, 'date' );
# Get all children
my $images = $album->getLineage(['descendants'], { returnObjects => 1 });
# Check order
cmp_deeply(
[ map { $_->get("filename") } @$images ],
[ "photo4.jpg", "photo1.jpg", "photo3.jpg", "photo2.jpg" ],
"Photos sorted by date"
);
# Empty gallery album
$versionTag->rollback;
$versionTag = WebGUI::VersionTag->getWorking($session);
# Add photos sorted by name
$album->addArchive( WebGUI::Test->getTestCollateralPath('gallery_archive_sorting_test.zip'), $properties, 'name' );
# Get all children
my $images = $album->getLineage(['descendants'], { returnObjects => 1 });
# Check order
cmp_deeply(
[ map { $_->get("filename") } @$images ],
[ "photo1.jpg", "photo2.jpg", "photo3.jpg", "photo4.jpg" ],
"Photos sorted by name"
);
# Empty gallery album
$versionTag->rollback;
#----------------------------------------------------------------------------
# Test the www_addArchive page
#----------------------------------------------------------------------------
# Cleanup
END {
$versionTag->rollback;
}