I?ve decided to 1-up the game from my previous post and zip something that isn?t really a real file but rather a blob in a Sitecore database. The script below is based heavily on the last post but instead of just zipping content of a flat folder traverses the Sitecore item tree and zips all files beneath the current folder.
If you have downloaded the 2.1 version of the Sitecore PowerShell Console from the Sitecore Marketplace you will actually have the script deployed on your system already.
Here?s how it looks like for your user in the Content Editor:
The script that performs the operation looks as follows:
########################################################################### # # # The script zips all files in the media library under the current folder # # and allows users to download the zip. # # # ########################################################################### # # The ZipFiles function is based on noam's answer # on the following Stack Overflow's page: http://bit.ly/PsZip # function ZipItems( $zipArchive, $sourcedir ) { Set-Location $sourcedir [System.Reflection.Assembly]::Load("WindowsBase,Version=3.0.0.0, ` Culture=neutral, PublicKeyToken=31bf3856ad364e35") | Out-Null $ZipPackage=[System.IO.Packaging.ZipPackage]::Open($zipArchive, ` [System.IO.FileMode]::OpenOrCreate, [System.IO.FileAccess]::ReadWrite) $items = gci -recurse $sourceDir [byte[]]$buff = new-object byte[] 40960 $i = 0; ForEach ($item In $items) { $i++ if([Sitecore.Resources.Media.MediaManager]::HasMediaContent($item)){ $mediaItem = New-Object "Sitecore.Data.Items.MediaItem" $item; $mediaStream = $mediaItem.GetMediaStream(); $fileName = Resolve-Path -Path $item.ProviderPath -Relative $fileName = "$fileName.$($item.Extension)" ` -replace "\\","/" -replace "./", "/" # Print out the file - the list will show up once the file is downloaded "Added: $fileName" # Show progress for the operation Write-Progress -Activity "Zipping Files " ` -CurrentOperation "Adding $fileName" ` -Status "$i out of $($items.Length)" ` -PercentComplete ($i *100 / $items.Length) $partUri = New-Object System.Uri($fileName, [System.UriKind]::Relative) $partUri = [System.IO.Packaging.PackUriHelper]::CreatePartUri($partUri); $part = $ZipPackage.CreatePart($partUri, ` "application/zip", ` [System.IO.Packaging.CompressionOption]::Maximum) $stream=$part.GetStream(); do { $count = $mediaStream.Read($buff, 0, $buff.Length) $stream.Write($buff, 0, $count) } while ($count -gt 0) $stream.Close() $mediaStream.Close() } } $ZipPackage.Close() } #the location will be set by PowerShell automatically based on which item was clicked $location = get-location $dateTime = Get-Date -format "yyyy-MM-d_hhmmss" $zipName = Split-Path -leaf $location | % { $_ -replace " ", ""} $dataFolder = [Sitecore.Configuration.Settings]::DataFolder $zipPath = "$dataFolder\$zipName-$datetime.zip" # Call the Zipping function ZipItems $zipPath $location #Send user the file, add -NoDialog if you want to skip the download dialog Download-File -FullName $zipPath | Out-Null # Cleanup after yourself Remove-Item $zipPath # Close the results window - we don't really need to see the results Close-Window
And here?s what your user will show after it gets run:
Yep, the script actually shows progress while the files are being zipped and then pops up the download dialog showing you the file size, quite rich experience for less than 50 lines of code, eh?
Now how do we integrate the script with the Content Editor?
All you really need to do is Save the script in the proper place in the library:
Once the Script is saved, we can limit the script to be available only when you right click on items in in the Media Library by editing the script Runtime properties:
Happy scripting!
This entry (Permalink) was posted on Monday, July 15th, 2013 at 11:00 pm and is filed under Code Samples, Downloadable, Open Source, PowerShell, Sitecore, Software Development, Solution, Web applications. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response , or trackback from your own site.