# encoding: ascii
# api: powershell
# title: Custom Speech Commands
# description: Pertains to the following
# version: 0.1
# type: module
# author: TylerT
# license: CC0
# function: Get-Definition
# x-poshcode-id: 1859
# x-archived: 2011-08-17T08:38:00
# x-published: 2011-05-17T22:01:00
#
# http://huddledmasses.org/control-your-pc-with-your-voice-and-powershell/
# http://poshcode.org/1195
#
#Filename commands.ps1
import-module "G:\Documents\Speech Macros\custom.psm1"
import-module "G:\Documents\Speech Macros\alice.psm1"
Add-SpeechCommands @{
"test command" = { Say $(Respond "3:2,4:0-2") }
" * the percentages * " = { Say $(Percentages) }
" * star date * " = { Say "Current, Star date,$("$((Get-Date).year).$([math]::round($((Get-Date).dayofyear)/365, 2)*100)" -replace "([A-Za-z0-9.]){1}","`$1 " -replace "\.","point")" }
" * mail * " = { Start-Process "https://mail.google.com" }
"Google * please" = { $term = $_ -replace "$Computer(.+?)Google (.+?) please", '$2'; Start-Process "http://www.google.com/search?q=$term" }
"What * time * " = { Say "It is $(Get-Date -f "h:mm tt")" }
"What is * time * " = { Say "It is $(Get-Date -f "h:mm tt")" }
"What time * " = { Say "It is $(Get-Date -f "h:mm tt")" }
" * some music * " = { Start-Process "grooveshark.exe" }
"What * date today" = { Say $(Get-Date -f "dddd, MMMM dd") }
#list processes
"What's running?" = {
$proc = ps | sort ws -desc
Say $("$($proc.Count) processes, including $($proc[0].name), which is using " +
"$([int]($proc[0].ws/1mb)) megabytes of memory")
}
#Word Definition
" * the definition for * please" = {$define = $_ -replace "$Computer(.+?)the definition for (.+?) please", '$2' ;$outtext = Get-Definition("$define");Say "Definitions for $define, , , $outtext"}
} -Computer "alice" -Verbose
#eof
#Filename custom.psm1
function Get-Definition($word) {
#.Synopsis
# Polls wiktionary for top text definitons for a given $word input
#.Description
# This Function parses the top $lines definitions for a given
# $term into one string formatted for speech synthesis
#
#
Say "Sure"
if($word -match " "){Say "Fail, one word at a time please"; break}
$page = "http://simple.wiktionary.org/wiki/$word"
$ie = new-object -com "InternetExplorer.Application"
$ie.visible = $false
$ie.navigate($page)
while($ie.busy){Start-Sleep 1}
$output = " "
$lines = 0
for($d=0;$d -le $lines;$d++) { ## grab the definition strings from each table
$ol = @($ie.Document.getElementsByTagName("ol"))[0]
$li = @($ol.getElementsByTagName("li"))[$d]
$def = @($li.innerHTML)
$output += "$def"
if($d -lt $lines){ $output += ", or, " }
}
$ie.Quit()
$closeIE = [System.Runtime.Interopservices.Marshal]::FinalReleaseComObject($ie)
Remove-Variable ie
$Clean-String($output)
}
function Clean-String([string]$str){
#.Synopsis
# Cleans string from web (most concerned about x/html tags)
#.Description
# Cleans input string of xml tags
# returns $str
#
#
$str = $str -replace "\<[^<]*\>", " "
$str = $str.replace(" ", "")
$str
}
function Respond($in, [string]$del = ","){
#.Synopsis
# Recursive.
# Returns a random response from $responses via the three dimensional array of choices: $choices[<groups>][<dimensions>][<values>]
# This function takes in a string indicating which responses from the $responses array
# to to choose from. It supports ranges (-) and direct selections (/) in each seed separated by (,).
#.Description
# the idea here is to respond based on this format: $in = "3:2,4:1-2,0/2-4/6:1"
# where 3:2 is a direct seed, 4:1-2 is a range seed (from 4:1 to 4:2),
# and 0/2-4/6:1 combines the two (effectively adds 0:1, 2:1, 3:1, 4:1, 5:1, 6:1 to the choices)
# In heap, the above example would effectively add 3:2, 4:1, 4:2, 0:1, 2:1, 3:1, 4:1, 5:1, 6:1 to the
# available choices, and will appear as $choices(@($xs(3),$ys(2)),@($xs(4),$ys(1,2)),@($xs(0,2,3,4,6),$ys(1)))
#
switch -wildcard ($del){
"`,"{
if($in -match "`,"){ #if more than one coordset, handle each
$coordsets = $in -split "`," #split coordsets apart
foreach($coordset in $coordsets){
$choices += ,(Respond $coordset "`:")
}
}
else{ #else pass the string to the next step,
$choices = ,(Respond $in "`:")
}
$choice = $choices[(get-random -min 0 -max $choices.count)] #choose one of the groups randomly
$responses[$choice[0]][$choice[1]];#pass response out of the function
}
"`:"{
$coords = $in -split "`:" #split coordset apart
foreach ($coord in $coords){
if(($coord -match "`/")-or($coord -match "`-")){ #if there's an or operator or a range
$dimensions += ,(Respond $coord "`/") # handle them, and add all values (in array) to this dimension (split fails elegantly)
}
else{
$dimensions += ,$coord #else just add the coord value (in an array) via comma operator
}
}
$dimensions #pass dimensions out dimensions is two dimensional array
}
"`/"{
$ranges = $in -split "`/" #split ORs apart (if theres not OR, the string is still added to $ranges[0])
foreach($range in $ranges){
if($range -match "`-"){#if theres a range to handle, do so
foreach ($val in (Respond $range "`-")){
$orVals += ,$val #append all values in returned range array to new array
}
}
else{# else just append the value to teh new array
$orVals += ,$range
}
}
,($orVals | get-random) #pass out single element array of random value from vals array
}
"`-"{
$vals = $in -split "`-" #split ranges apart
$vals[0]..$vals[1] # pass out array containing all values in range
}
}
}
$responses = (#Response Array
(##0-correct
"Right",
"Correct"
),
(##1-incorrect
"Wrong",
"Incorrect"
),
(##2-positive
"Yes",
"Aye",
"I'll give it a shot"
),
(##3-negative
"No",
"Negative",
"Not going to happen"
),
(##4-affirmation
"Sure",
"OK",
"Lets See"
),
(##5-retort
"your mom",
"your face"
),
(##6-insult
"You\'re dumb",
"you fail"
),
(##7-eager
"I'm ready",
"Lets check it out"
),
(##8-apprehensive
"I don't know",
"Just a seck"
),
(##9-neutral
"oh",
"Hum"
)
)
function Percentages {
#.Synopsis
# Specific speech command that reads back
# remaining percentages of year, month, week, and day
#.Description
# Pretty self explanitory, basic maths, elucidatory var names
#
#
$date = get-date #capture date object
$daysInYear = [int]$(if([datetime]::IsLeapYear($date.year)){366}else{365}) #if leap year, 366, else 365
$daysInMonth = [int]$([datetime]::DaysInMonth($date.year, $date.month)) #capture days in month
$dayOfYear = [int]$date.dayofyear #days past (including today)
$dayOfMonth = [int]$date.day #days past (including today)
$hoursOfDay = [int]$date.hour #hours past (including current)
$minutesOfHour = [int]$date.minute #minutes past (including current)
switch ($date.dayofweek.toString()){ #assumes start of week is sunday
Sunday { [int]$dayOfWeek="1"; break }
Monday { [int]$dayOfWeek="2"; break }
Tuesday { [int]$dayOfWeek="3"; break }
Wednesday { [int]$dayOfWeek="4"; break }
Thursday { [int]$dayOfWeek="5"; break }
Friday { [int]$dayOfWeek="6"; break }
Saturday { [int]$dayOfWeek="7"; break }
}
$percentYearGone = $dayOfYear/$daysInYear #days of this year (including today) divided by total days in this year
$percentMonthGone = ((($dayOfMonth*24)-24)+$hoursOfDay)/($daysInMonth*24) #hours of this month divided by total hours in this month
$percentWeekGone = ((($dayOfWeek*24)-24)+$hoursOfDay)/(7*24) #hours of this week divided by total hours in a week
$percentDayGone = ((($hoursOfDay*60)-60)+$minutesOfDay)/(24*60) #minutes of today divided by total minutes in a day
$percentYearLeft = [math]::round((1-$percentYearGone)*100,1) #opposite percentages rounded to one decimal place
$percentMonthLeft = [math]::round((1-$percentMonthGone)*100,1) #^
$percentWeekLeft = [math]::round((1-$percentWeekGone)*100,1) #^
$percentDayLeft = [math]::round((1-$percentDayGone)*100,1) #^
$str = ""
$str += "There's "
$str += $percentYearLeft
$str += "% of this year, "
$str += $percentMonthLeft
$str += "% of this month, "
$str += $percentWeekLeft
$str += "% of this week, and "
$str += $percentDayLeft
$str += "% of today remaining, what will you do with it?"
$str
}
#eof