Notki oznaczone tagiem ‘Twitter’

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:

# tweet.ps1
# Wysyłanie nowego statusu do Twittera

[Reflection.Assembly]::LoadWithPartialName("System.Web") | Out-Null

# Stałe
$LOGIN = "login" # lub e-mail
$PASS = "hasło"

# Pobranie statusu od użytkownika
$tweet = Read-Host -Prompt "Status"

# Złożenie żądania HTTP POST
$uri = [Uri]"http://twitter.com/statuses/update.xml"
$http = [Net.HttpWebRequest]::Create($uri)
$http.Credentials = New-Object Net.NetworkCredential @($LOGIN, $PASS)
$http.Method = [Net.WebRequestMethods+Http]::Post
$http.ServicePoint.Expect100Continue = $false # (*)

# Wysyłanie danych
$data = "status=" + [Web.HttpUtility]::UrlEncode($tweet)
$http.ContentLength = $data.Length
$sw = New-Object IO.StreamWriter @($http.GetRequestStream())
    $sw.Write($data)
$sw.Close()

# Wyświetlamy ID nowego statusu
$resp = $http.GetResponse().GetResponseStream()
$sr = New-Object IO.StreamReader @($resp)
$xml = [xml]$sr.ReadToEnd()
"Status updated (ID: " + $xml.status.id + ")" | Out-Host
$sr.Close()

# Obsługa błędów
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:

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:

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

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

  • RSS
  • Facebook
  • Twitter
  • Wykop
  • Reddit
  • del.icio.us
  • Google Bookmarks
 



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