Triki z PowerShellem #11 – Ćwierkamy

2009-10-30 19:41

W ramach wyposażania nowozainstalowanego systemu w niezbędne programy, przypomniałem sobie o istnieniu PowerShella. Kiedy jednak chciałem go ściągnąć, spotkała mnie przyjemna niespodzianka: PSh w Windows 7 jest już od razu zainstalowany, więc można go od razu zacząć go używać. Jak sądzę, przyczyni do zwiększenia jego popularności, co jest z pewnością dobrą rzeczą.

Obrazek z TwitteraFakt sprawił rzecz jasna, że zaraz zachciało mi się wypróbować go w jakimś nowym zastosowaniu. Padło na wysyłanie update‘ów do Twittera, w którym to zresztą niedawno się zarejestrowałem (i wciąż nie wiem, dlaczego ;)). Sprawa na oko nie jest trudna, bo sprowadza się do wykonania jednego żądania HTTP POST. Ale jak wiadomo, diabeł zwykle tkwi w szczegółach. Oto skrypt:

  1. # tweet.ps1
  2. # Wysyłanie nowego statusu do Twittera
  3.  
  4. [Reflection.Assembly]::LoadWithPartialName("System.Web") | Out-Null
  5.  
  6. # Stałe
  7. $LOGIN = "login" # lub e-mail
  8. $PASS = "hasło"
  9.  
  10. # Pobranie statusu od użytkownika
  11. $tweet = Read-Host -Prompt "Status"
  12.  
  13. # Złożenie żądania HTTP POST
  14. $uri = [Uri]"http://twitter.com/statuses/update.xml"
  15. $http = [Net.HttpWebRequest]::Create($uri)
  16. $http.Credentials = New-Object Net.NetworkCredential @($LOGIN, $PASS)
  17. $http.Method = [Net.WebRequestMethods+Http]::Post
  18. $http.ServicePoint.Expect100Continue = $false # (*)
  19.  
  20. # Wysyłanie danych
  21. $data = "status=" + [Web.HttpUtility]::UrlEncode($tweet)
  22. $http.ContentLength = $data.Length
  23. $sw = New-Object IO.StreamWriter @($http.GetRequestStream())
  24.     $sw.Write($data)
  25. $sw.Close()
  26.  
  27. # Wyświetlamy ID nowego statusu
  28. $resp = $http.GetResponse().GetResponseStream()
  29. $sr = New-Object IO.StreamReader @($resp)
  30. $xml = [xml]$sr.ReadToEnd()
  31. "Status updated (ID: " + $xml.status.id + ")" | Out-Host
  32. $sr.Close()
  33.  
  34. # Obsługa błędów
  35. trap    { "Error: " + $_.Exception.Message; return }

Jednym z owych detali było kodowanie statusu algorytmem dla URL-i (zamieniającym spacje na %20 itd.), wykonywane poprzez System.Web.HttpUtility.UrlEncode – stąd konieczność importowania assembly System.Web. Ale to jest w sumie pikuś.
Znacznie większym “trikiem” jest linijka oznaczona gwiazdką (*). Powoduje ona obejście domyślnego zachowania .NET, który do każdego żądania HTTP typu POST dodaje nagłówek:

  1. Expect: 100-continue

Powoduje on wysłanie tak naprawdę dwóch requestów: w pierwszym serwer ma tylko sprawdzić poprawność nagłówków (logowania, na przykład) i zwrócić status 100 (Continue). Dopiero w drugim klient wysyła właściwe dane. Mechanizm ten jest w .NET opakowany przezroczyście i ma zapobiegać niepotrzebnemu przesyłaniu dużych ilości danych w żądaniu, które i tak byłoby odrzucone.
API Twittera jednak tego nie obsługuje i jest to właściwe. Trudno przecież nazwać status, mający maks. 160 znaków, “dużą ilością danych”. Lepiej więc przesyłać go od razu, a domyślne zachowanie .NET-a obejść. To właśnie robi zaznaczony wiersz.

Przypomnę jeszcze tylko – gdy ktoś zechciał powyższego skryptu używać do przesyłania tweetów – że uruchomienie skryptu PSh z poziomu zwykłej linii poleceń wymaga parametru -Command i kropki:

  1. powershell -Command . 'ścieżka\tweet.ps1'

Do takiej komendy można np. utworzyć skrót i przypisać mu kombinację klawiszy w celu szybkiego uruchamiania.

Tags: , ,
Author: Xion, posted under Internet, Programming »


One comment for post “Triki z PowerShellem #11 – Ćwierkamy”.
  1. Xion:
    September 2nd, 2010 o 10:50

    Niestety, od wczoraj Twitter nie wspiera już autentykacji przez zwykłe logowanie HTTP na rzecz OAuth. Nie da się więc już używać powyższego rozwiązania ;-/

Comments are disabled.
 


© 2017 Karol Kuczmarski "Xion". Layout by Urszulka. Powered by WordPress with QuickLaTeX.com.