# encoding: ascii
# api: powershell
# title: DekiWiki Module
# description: DekiWiki module, a package of a few script cmdlets (more to come, I promise) for working with DekiWiki. Included so far: Set-DekiCredential, Get-DekiContent, Set-DekiContent, New-DekiContent, Get-DekiFile … conspicuously absent: Add-DekiFile, Remove-DekiFile, Remove-DekiContent …
# version: 1.0
# type: module
# license: CC0
# function: Set-DekiCredential
# x-poshcode-id: 671
# x-archived: 2010-03-30T09:01:44
#
# See Also: ConvertTo-DekiContent
#
## DekiWiki Module -note this is a v2 module, but I think you can dot-source in v1 if you remove the last line ;)
####################################################################################################
## The first of many script cmdlets for working with DekiWiki, based on their REST api sdk "Dream"
## You need log4net.dll mindtouch.core.dll mindtouch.dream.dll and SgmlReaderDll.dll from the SDK
## Download DREAM from http://sourceforge.net/project/showfiles.php?group_id=173074
## Unpack it, and you can find these dlls in the "dist" folder.
####################################################################################################
## More details to come with the next version. Sorry, it's time for bed ;)
## History:
## v 1.0 Set-DekiCredential, Get-DekiContent, Set-DekiContent, New-DekiContent, Get-DekiFile
##
[Reflection.Assembly]::LoadFile( "$PSScriptRoot\mindtouch.dream.dll" )
$url = "http://powershell.wik.is" #
$api = "$url/@api/deki"
$plug = [MindTouch.Dream.Plug]::New($api);
$cred = $null
function Set-DekiCredential {
param($Credential=$(Get-Credential))
$global:cred = $Credential
}
function Get-DekiCredential {
if(!$global:cred) { Set-DekiCredential $(Get-Credential) }
return $global:cred.GetNetworkCredential();
}
$DreamText = [MindTouch.Dream.MimeType]::TEXT
$DreamXml = [MindTouch.Dream.MimeType]::XML
$DreamHtml = [MindTouch.Dream.MimeType]::HTML
function Get-DekiContent {
param( $pageName = "Test_Page" )
$pageName = [System.Web.HttpUtility]::UrlEncode( [System.Web.HttpUtility]::UrlEncode( $pageName ) )
$plug.At("pages", "=$pageName", "contents").With("mode", "view").Get().AsDocument().AsXmlNode
}
# Get-DekiFile will LIST all files if called with just a PageName
# Otherwise, fileName can be a single fileName, or wildcards
function Get-DekiFile {
param( $pageName = "Test_Page", [string[]]$fileNames, $destinationFolder )
$encodedPageName = Encode-Twice $pageName
$files = $plug.At("pages", "=$encodedPageName", "files").Get().AsDocument().AsXmlNode.file
if(!$fileNames) {
return $files
} else {
foreach($fileName in $fileNames) {
foreach($file in $($files | where { $_.filename -like $fileName } )) {
$encodedFileName = [System.Web.HttpUtility]::UrlEncode( [System.Web.HttpUtility]::UrlEncode( $($file.filename) ) )
Write-Verbose "Fetching $($file.filename) from $pageName"
# Note that you can resize, if it's a picture: .With("size", "bestfit").With("width", 100).With("height", 100).Get();
$message = $plug.At("pages", "=$encodedPageName", "files", "=$encodedFileName").Get()
$fullName = $(Get-FileName $file.filename destinationFolder)
&{
$writer = new-object System.IO.FileStream $fullName, "Create"
$bytes = $message.AsBytes()
$writer.Write($bytes,0,$bytes.Length)
trap {
$writer.Flush()
$writer.Close()
}
$writer.Flush()
$writer.Close()
}
write-output (get-item $fullName)
}
}
}
}
function Set-DekiContent {
param( $pageName = "Test_Page", $content = (throw "You must specify page contents"), $section )
$encodedPageName = Encode-Twice $pageName
# you have to pre-authenticate ...
$null = $plug.At("users", "authenticate").WithCredentials( $(Get-DekiCredential) ).Get()
if( $content -is [System.Xml.XmlDocument]) {
$msg = [MindTouch.Dream.DreamMessage]::Ok( $content )
} else {
$msg = [MindTouch.Dream.DreamMessage]::Ok( $DreamText, $content )
}
Write-Verbose "Updating $pageName at $(UtcNow "yyyyMMddhhmmss"): $($msg.ContentLength) bytes"
Write-Verbose "$($msg.AsText())"
$partway = $plug.At("pages", "=$encodedPageName", "contents").With("edittime",$(UtcNow "yyyyMMddhhmmss"))
if($section) {
$result = $partway.With("Section",0).Post( $msg )
} else {
$result = $partway.Post( $msg )
}
if($result.IsSuccessful) {
return "$url/$pageName"
} else {
return $result.Response
}
trap [MindTouch.Dream.DreamResponseException] {
Write-Error "TRAPPED DreamResponseException`n`n$($_.Exception.Response | Out-String)`n`n`n$($_.Exception.Response.Headers | Out-String)"
break;
}
}
function New-DekiContent {
param( $pageName = "Test_Page", $content = (throw "You must specify page contents") )
$encodedPageName = Encode-Twice $pageName
# you have to pre-authenticate ...
$null = $plug.At("users", "authenticate").WithCredentials( $(Get-DekiCredential) ).Get()
if( $content -is [System.Xml.XmlDocument]) {
$msg = [MindTouch.Dream.DreamMessage]::Ok( $content )
} else {
$msg = [MindTouch.Dream.DreamMessage]::Ok( $DreamText, $content )
}
Write-Verbose "Updating $pageName at $(UtcNow "yyyyMMddhhmmss"): $($msg.ContentLength) bytes"
Write-Verbose "$($msg.AsText())"
$result = $plug.At("pages", "=$encodedPageName", "contents").With("abort", "exists").With("edittime",$(UtcNow "yyyyMMddhhmmss")).Post( $msg )
trap [MindTouch.Dream.DreamResponseException] {
Write-Error "TRAPPED DreamResponseException`n`n$($_.Exception.Response | Out-String)`n`n`n$($_.Exception.Response.Headers | Out-String)"
}
if($result.IsSuccessful) {
return "$url/$pageName"
} else {
return $result.Response
}
}
## Utility Functions
function UtcNow {
Param($Format="")
[DateTime]::Now.ToUniversalTime().ToString($Format)
}
function Encode-Twice {
param([string]$text)
return [System.Web.HttpUtility]::UrlEncode( [System.Web.HttpUtility]::UrlEncode( $text ) )
}
function Get-FileName {
param($fileName=$([IO.Path]::GetRandomFileName()), $path)
$fileName = $fileName.trim("\/""'")
if($path -and (Test-Path $path)){
$fileName = Split-Path $fileName -leaf
Join-Path $path $fileName
} elseif((Split-Path $fileName) -and (Test-Path (Split-Path $fileName))) {
return $fileName
} else {
Join-Path (Convert-Path (Get-Location -PSProvider "FileSystem")) (Split-Path $fileName -Leaf)
}
}
Export-ModuleMember Set-DekiCredential, Get-DekiContent, Set-DekiContent, New-DekiContent, Get-DekiFile