Last active
April 10, 2017 11:23
-
-
Save AdamNaj/30fecc6dad6b2a4a85ba855c43a10135 to your computer and use it in GitHub Desktop.
SXA Folder Synchronizer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<# | |
.SYNOPSIS | |
Synchronize local folder (with subfolders) with Media Library (matching structure) on a remote Sitecore instance | |
.DESCRIPTION | |
The script allows you to work with SXA Themes in a more comfortable way. | |
You can need specify the instance hostname, a folder to watch and the location of your Theme in Media Library | |
in the variables directly below and run the script that will monitor and upload your changes. | |
The script requires that SPE Remoting is deployed and enabled on the Sitecore Server. | |
The script requires that SPE Remoting PowerShell Module is installed on your local machine. | |
The following endpoints must be enabled: | |
- remoting | |
- mediaUpload | |
.NOTES | |
Author PowerShell: Adam Najmanowicz | |
Version: 1.0.0 29.March.2017 | |
#> | |
$ThemeFolder = 'C:\Projects\Showcase' | |
$MediaLibaryPath = "Project/Showcase/Themes/Showcase" | |
$protocolHost = "http://sxa" | |
$userName = "sitecore\admin" | |
$password = "b" | |
$global:skippedpaths = @(".sass-cache*","*optimized*", "Styles.css","node_modules*", "Showcase.zip", "Scripts\concat.js"); | |
function global:ShouldSkip([string] $path){ | |
$skipped = $false; | |
$global:skippedpaths | % { | |
if($path -like $_){ | |
return $true; | |
} | |
} | |
return $false; | |
} | |
function global:GetRelativePath{ | |
Param( | |
[string] $fullPath, | |
[string] $ThemeFolder | |
) | |
[System.Uri]$fileUri = [System.IO.Path]::GetDirectoryName($fullPath); | |
[System.Uri]$themeUri = "$ThemeFolder\" | |
[string]$relativePath = $themeUri.MakeRelativeUri($fileUri); | |
return $relativePath | |
} | |
Import-Module SPE | |
$filter = '*.*' | |
#$logfile = "C:\Projects\Showcase.log\outlog.$([DateTime]::Now.ToString('yyMMdd_HHmm')).txt" | |
$session = New-ScriptSession -Username $userName -Password $password -ConnectionUri $protocolHost | |
$MessageData = New-Object PSObject -Property @{MediaLibaryPath = $MediaLibaryPath.Trim("/"); logfile = $logfile; session = $session; ThemeFolder = $ThemeFolder.Trim("\")} | |
$fsw = New-Object IO.FileSystemWatcher $ThemeFolder, $filter -Property @{IncludeSubdirectories = $true; NotifyFilter = [IO.NotifyFilters]'FileName, LastWrite'} | |
Write-Host "Watching '$ThemeFolder'" -fore green | |
Register-ObjectEvent $fsw Created -SourceIdentifier FileCreated -MessageData $MessageData -Action { | |
$name = $Event.SourceEventArgs.Name | |
$changeType = $Event.SourceEventArgs.ChangeType | |
$timeStamp = $Event.TimeGenerated | |
$extension = [System.IO.Path]::GetExtension($fullPath).Replace(".", ""); | |
if(global:ShouldSkip $name){ | |
return; | |
} | |
Write-Host "[$timeStamp] [$extension] [$changeType] : '$name'" -fore DarkGreen | |
#Out-File -FilePath $Event.MessageData.logfile -Append -InputObject "The file '$name' was $changeType at $timeStamp" | |
} | Out-Null | |
Register-ObjectEvent $fsw Renamed -SourceIdentifier FileRenamed -MessageData $MessageData -Action { | |
$name = $Event.SourceEventArgs.Name; | |
$changeType = $Event.SourceEventArgs.ChangeType; | |
$timeStamp = $Event.TimeGenerated; | |
$fullPath = $Event.SourceEventArgs.FullPath; | |
$session = $Event.MessageData.session; | |
$MediaLibaryPath = $Event.MessageData.MediaLibaryPath; | |
$newFilenameWithoutExtension = [System.IO.Path]::GetFileNameWithoutExtension($fullPath); | |
$filenameWithoutExtension = [System.IO.Path]::GetFileNameWithoutExtension($Event.SourceEventArgs.OldName); | |
$extension = [System.IO.Path]::GetExtension($fullPath).Replace(".", ""); | |
$ThemeFolder = $Event.MessageData.ThemeFolder; | |
if(global:ShouldSkip $name){ | |
return; | |
} | |
[string]$relativePath = global:GetRelativePath $fullPath $ThemeFolder | |
$mediaPath = "master:/media library/$MediaLibaryPath/$relativePath/$filenameWithoutExtension" | |
Write-Host "[$timeStamp] [$extension] [$changeType] : '$name'" -fore DarkCyan | |
#Write-Host "'$name' $changeType at $timeStamp. Renaming in Media Library..." -fore Cyan | |
Invoke-RemoteScript -Session $session -ScriptBlock { | |
if(Test-Path $using:mediaPath) { | |
Rename-Item -Path $using:mediaPath -NewName $using:newFilenameWithoutExtension | |
} | |
} | |
Write-Host "[$timeStamp] [$extension] [SERVER:$changeType] : '$mediaPath'" -fore Cyan | |
#Write-Host "'$mediaPath' was renamed to 'master:\media library\$MediaLibaryPath\$relativePath\$newFilenameWithoutExtension'" -fore Cyan | |
} | Out-Null | |
Register-ObjectEvent $fsw Deleted -SourceIdentifier FileDeleted -MessageData $MessageData -Action { | |
$name = $Event.SourceEventArgs.Name; | |
$changeType = $Event.SourceEventArgs.ChangeType; | |
$timeStamp = $Event.TimeGenerated; | |
$fullPath = $Event.SourceEventArgs.FullPath; | |
$session = $Event.MessageData.session; | |
$MediaLibaryPath = $Event.MessageData.MediaLibaryPath; | |
$filenameWithoutExtension = [System.IO.Path]::GetFileNameWithoutExtension($fullPath); | |
$extension = [System.IO.Path]::GetExtension($fullPath).Replace(".", ""); | |
$ThemeFolder = $Event.MessageData.ThemeFolder; | |
[string]$relativePath = global:GetRelativePath $fullPath $ThemeFolder | |
if(global:ShouldSkip $name){ | |
return; | |
} | |
$mediaPath = "master:/media library/$MediaLibaryPath/$relativePath/$filenameWithoutExtension" | |
#Write-Host "'$name' $changeType at $timeStamp. Removing from Media Library..." -fore Red | |
Write-Host "[$timeStamp] [$extension] [$changeType] : '$name'" -fore DarkRed | |
Invoke-RemoteScript -Session $session -ScriptBlock { | |
if(Test-Path $using:mediaPath) { | |
Remove-Item -Path $using:mediaPath -Force | |
} | |
} | |
Write-Host "[$timeStamp] [$extension] [SERVER:$changeType] : '$mediaPath'" -fore Red | |
#Write-Host "'$mediaPath' was deleted" -fore Red | |
#Out-File -FilePath $Event.MessageData.logfile -Append -InputObject "The file '$name' was $changeType at $timeStamp" | |
} | Out-Null | |
Register-ObjectEvent $fsw Changed -SourceIdentifier FileChanged -MessageData $MessageData -Action { | |
$name = $Event.SourceEventArgs.Name; | |
$changeType = $Event.SourceEventArgs.ChangeType; | |
$timeStamp = $Event.TimeGenerated; | |
$fullPath = $Event.SourceEventArgs.FullPath; | |
$session = $Event.MessageData.session; | |
$MediaLibaryPath = $Event.MessageData.MediaLibaryPath; | |
$filenameWithoutExtension = [System.IO.Path]::GetFileNameWithoutExtension($fullPath); | |
$extension = [System.IO.Path]::GetExtension($fullPath).Replace(".", ""); | |
$ThemeFolder = $Event.MessageData.ThemeFolder; | |
if(global:ShouldSkip $name){ | |
return; | |
} | |
if((Get-Item $fullPath) -is [System.IO.DirectoryInfo]){ | |
Write-Host "'$name' is a folder - skipping upload." -fore White | |
return; | |
} | |
[string]$relativePath = global:GetRelativePath $fullPath $ThemeFolder | |
Write-Host "[$timeStamp] [$extension] [$changeType] : '$name'" -fore DarkYellow | |
#Write-Host "'$name' $changeType at $timeStamp. Uploading..." -fore Yellow | |
Get-Item -Path $fullPath | Send-RemoteItem -Session $session -RootPath Media -Destination "$MediaLibaryPath/$relativePath" | |
$mediaPath = "master:/media library/$MediaLibaryPath/$relativePath/$filenameWithoutExtension" | |
Write-Host "[$timeStamp] [$extension] [SERVER:$changeType] : '$mediaPath'" -fore Yellow | |
#Write-Host "'$mediaPath' was uploaded" -fore Yellow | |
#Out-File -FilePath $Event.MessageData.logfile -Append -InputObject "The file '$name' was $changeType at $timeStamp" | |
} | Out-Null | |
Write-Host "Uploaded to '$protocolHost/-/media/$MediaLibaryPath'" -fore green | |
Write-Host "Watcher started." -fore green | |
while($true) { Start-Sleep -Seconds 1 } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/"> | |
<sitecore> | |
<powershell> | |
<services> | |
<remoting enabled="false" requireSecureConnection="false"> | |
<patch:attribute name="enabled">true</patch:attribute> | |
<authorization> | |
<add Permission="Allow" IdentityType="User" Identity="sitecore\admin" /> | |
</authorization> | |
</remoting> | |
<mediaDownload enabled="false" requireSecureConnection="false"> | |
<patch:attribute name="enabled">true</patch:attribute> | |
</mediaDownload> | |
<mediaUpload enabled="false" requireSecureConnection="false"> | |
<patch:attribute name="enabled">true</patch:attribute> | |
</mediaUpload> | |
</services> | |
</powershell> | |
</sitecore> | |
</configuration> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment