PowerShell在NuGet在進階一點的應用中,扮演蠻重要的角色。例如: 要用Scaffolding自動產生特定Model物件的對應模版時,使用NuGet Package Manager Console下指令,是非常簡便有效率的做法。許多複雜不易歸納操作方式流程的需求,要寫出好用順手且兼顧各種情境的UI頗具難度,但寫個能接受參數提供足夠彈性的功能函數,顯然簡單許多。在實務上,先有SDK、API,累積一堆應用需求後,再依常見操作情境,將複雜的API呼叫包裝成易用的操作介面,也是軟體常採用的發展策略。

Phil HaackMIX11中露了一手,用PowerShell寫一個神奇八號球(就是一種小機器裝置,隨便問個問題,它會隨機跳出模稜兩可幾乎可以回答任何問題的答案。有玩噗浪的人,可以把它想成像掰噗一樣的東西,只是沒有任何AI,完全靠隨機出現模糊回答造製笑果)。我也依樣照葫蘆,結合Google的氣象查詢API,做了一個"天氣查詢"的NuGet PowerShell Command。

關NuGet PowerShell Command製作方法,Phil的文章介紹得挺仔細,這裡簡單帶過:

先寫一個init.ps1,它會在程式包首次安裝在Solution(*.sln),或是每次VS2010開啟Solution時被執行。(可參考這篇NuGet文件中Automatically Running PowerShell Scripts During Package Installation and Removal一節的說明)

這裡寫的init.ps1只是個空殼,由NuGet Package Manager接入$installPath, $toolsPath, $package三個參數,接著用$toolsPath找到"GoogleWeather.psm1"這個PowerShell Module並載入。

param($installPath, $toolsPath, $package)
Import-Module (Join-Path $toolsPath GoogleWeather.psm1)

GoogleWeather.psm1裡則是程式的主要邏輯,主要有三部分:

  • Get-Weather
    接入$city城市名稱當參數,使用.NET WebClient類別向Google天氣API(參考)取得$city的天氣資料XML,並解析出天氣資訊並顯示出來。
  • Register-TabExpansion
    想在Console中輸入Get-Weather後按下Tab鍵可自動帶出"台北市"、”台中市"、”高雄市”等預設參數,可使用Register-TabExpansion註冊預設選項。
  • Export-ModuleMember
    將Get-Weather註冊成NuGet Console指令

以下是GoogleWeather.psm1的程式碼:

#加上自動完成之提示項目
Register-TabExpansion "Get-Weather" @{ 
    'city' = { "台北市", "台中市", "高雄市" }
}    
#由XML節點取出data Attribute的小函數
function GetData($node, [string]$name) 
{
    $data = $node.SelectSingleNode($name)
    if ($data) {
        return $data.GetAttribute("data")
    } else {
        return "N/A"
    }
}
#天氣資訊查詢函數
function Get-Weather($city) {
    #建立WebClient物件
    $wc = New-Object System.Net.WebClient
    #帶入城市組成URL取得XML
    $url = "http://www.google.com/ig/api?hl=zh-TW&weather=" + $city
    $result = $wc.DownloadString($url)
    $xml = ([Xml]$result).xml_api_reply
    $info = $xml.weather.forecast_information
    #解析XML取出天氣資訊,進行簡單的排版
    if ($info -eq $null) 
    {
        "目前沒有" + $city + "的氣象資訊"
        return
    }
    $display = "=== " + $(GetData $info "forecast_date") 
    $display +=  " " + $(GetData $info "city") + "氣象資訊 ============`n"
    $curr = $xml.weather.current_conditions
    $display += "現在天氣:" + $(GetData $curr "condition") + "`n"
    $display += "氣溫:" + $(GetData $curr "temp_c") + "   "
    $display += $(GetData $curr "humidity") + "`n"
    $wind = GetData $curr "wind_condition"
    if ($wind -ne "N/A") { $display += $wind + "`n" }
    $display += "============================================`n"
    $xml.weather.SelectNodes("//forecast_conditions") | ForEach-Object {
        $display += $(GetData $_ "day_of_week") + " "
        $display += $(GetData $_ "low") + " - " + $(GetData $_ "high")
        $display += "  /  " + $(GetData $_ "condition") + "`n"
    }
    $display                
}
#註冊Get-Weather,以便在NuGet Console中呼叫
Export-ModuleMember Get-Weather

用NuGet Package Explorer,將GoogleWeather.psm1及init.ps1放入tools目錄,產生NuGet程式包。

利用自製NuGet程式包架設私房NuGet Server提過的方式設定程式包來源並安裝程式包,就可以在Visual Studio 2010的Package Manager Console裡查詢天氣狀況囉~~

(這... 真的會有人一邊寫程式一邊關心氣象嗎? 好吧! 我承認它只是我用來練習寫NuGet命令模組的自嗨作品,嚴禁任何人討論它的實用價值,呵!)


Comments

# by Ike

哇~ 可以邊寫程式邊看氣象耶,真是實用~~ (就是挺黑大!!)

Post a comment