<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>xion.log &#187; Internet</title>
	<atom:link href="http://xion.org.pl/category/it/internet/feed/" rel="self" type="application/rss+xml" />
	<link>http://xion.org.pl</link>
	<description>Blog Xiona o programowaniu i innych ciekawych rzeczach :)</description>
	<lastBuildDate>Tue, 27 Jul 2010 16:54:20 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Znak wodny w polu tekstowym</title>
		<link>http://xion.org.pl/2010/07/10/znak-wodny-w-polu-tekstowym/</link>
		<comments>http://xion.org.pl/2010/07/10/znak-wodny-w-polu-tekstowym/#comments</comments>
		<pubDate>Sat, 10 Jul 2010 11:16:53 +0000</pubDate>
		<dc:creator>Xion</dc:creator>
				<category><![CDATA[Internet]]></category>
		<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[pole tekstowe]]></category>
		<category><![CDATA[znak wodny]]></category>

		<guid isPermaLink="false">http://xion.org.pl/?p=1971</guid>
		<description><![CDATA[Panuje obecnie moda na to, aby strony WWW jak najskuteczniejszej udawały, że nimi nie są i zamiast tego mieniły się 'aplikacjami internetowymi'. Duża w tym zasługa możliwości JavaScriptu w nowoczesnych przeglądarkach. Jeśli potrafimy przeboleć pisanie w nim, to możemy osiągnąć całkiem efektowne rezultaty. Albo takie nieco mniej imponujące, ale też zgrabne :) Do tej drugiej [...]]]></description>
			<content:encoded><![CDATA[<p>Panuje obecnie moda na to, aby strony WWW jak najskuteczniejszej udawały, że nimi nie są i zamiast tego mieniły się 'aplikacjami internetowymi'. Duża w tym zasługa możliwości JavaScriptu w nowoczesnych przeglądarkach. Jeśli potrafimy przeboleć pisanie w nim, to możemy osiągnąć całkiem efektowne rezultaty. Albo takie nieco mniej imponujące, ale też zgrabne :)<br />
<img style="float:left; margin:5px; margin-top:7px; margin-bottom:10px" src="http://xion.org.pl/wp-content/uploads/2010/07/watermark-textbox.png" alt="" title="Pole tekstowe ze znakiem wodnym" />Do tej drugiej kategorii należy efekt znany jako <em>watermark textbox</em>, niemający wbrew pozorom żadnego związku ze znakami wodnymi w obrazkach. Trik ten - z którym zapewne tutejsza większość się zetknęła - polega na wyświetlaniu nieco przyszarzonego komunikatu <strong>w</strong> polu tekstowym, który następnie znika, gdy użytkownik umieści w nim kursor. Oprócz sprawiania wrażenia, że "strona żyje", ta prosta sztuczka ma też wymiar praktyczny: pozwala oszczędzić na zbędnej etykiecie <em>textboxa</em>.</p>
<p>Chcąc "wodne" pole tekstowe umieścić na swojej stronie, możemy skorzystać z <a href="http://code.google.com/p/jquery-watermark/"> jednego z gotowych rozwiązań</a>. Wiele z nich używa <a href="http://jquery.com">jQuery</a> - darmowej biblioteki ułatwiającej pisanie w JS. Jeśli jednak nie korzystamy z niej w innych miejscach strony, to wymaganie jej obecności nie musi się nam podobać. A ponieważ <em>watermark textbox</em> jest efektem łatwym do zakodowania, spokojnie możemy napisać go własnoręcznie. Prześledźmy zatem, jak da się to zrobić.<br />
<span id="more-1971"></span><br />
Definiujemy najpierw styl naszego pola tekstowego, określający jego wygląd podczas wyświetlania wskazówki-znaku wodnego:</p>
<div class="syntax_hilite">
<div id="css-5">
<div class="css">input<span style="color: #6666ff;">.watermarkTextBox </span><span style="color: #66cc66;">&#123;</span> <span style="color: #000000; font-weight: bold;">color</span>: #808080; <span style="color: #66cc66;">&#125;</span></div>
</div>
</div>
<p>
Szary kolor jest oczywiście tylko propozycją. Potrzebujemy w każdym razie osobnej klasy CSS, by oznaczać nią te <em>textboksy</em>, które mają wyświetlać znak wodny. Jako wskazówkę będziemy pokazywali początkową wartość pola tekstowego, czyli to co zostało fabrycznie przypisane atrybutowi <code>value</code> elementu <code>input</code>:</p>
<div class="syntax_hilite">
<div id="html-6">
<div class="html"><span style="color: #009900;"><a href="http://december.com/html/4/element/input.html"><span style="color: #000000; font-weight: bold;">&lt;input</span></a> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">"text"</span> <span style="color: #000066;">size</span>=<span style="color: #ff0000;">"20"</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">"Szukaj..."</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">"watermarkTextBox"</span>/<span style="color: #000000; font-weight: bold;">&gt;</span></a></span></div>
</div>
</div>
<p>
To właściwie tyle, jeśli chodzi o statyczny HTML; resztę musimy załatwić JavaScriptem. Interesują nas dwa zdarzenia: zyskania oraz utraty <strong>fokusu</strong> przez kontrolkę. Są to odpowiednio: <code>onfocus</code> i <code>onblur</code>. (Właśnie za takie nieintuicyjne nazwy "kochamy" JavaScript ;P). W reakcji na pierwsze z nich powinniśmy ukryć nasz szary tekst i pozwolić użytkownikowi na wpisanie nowego. Jeśli jednak tego nie zrobi, to w drugim zdarzeniu wykrywamy, że <em>textbox</em> jest wciąż pusty i ponawiamy wyświetlanie znaku wodnego. Oto procedury zdarzeniowe, które wykonują te czynności:</p>
<div class="syntax_hilite">
<div id="javascript-7">
<div class="javascript"><span style="color: #003366; font-weight: bold;">function</span> onWatermarkTextBoxFocus<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><br />
<span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #006600;">value</span> == <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #006600;">watermark</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #006600;">value</span> = <span style="color: #3366CC;">""</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #006600;">className</span> = <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #006600;">className</span>.<span style="color: #006600;">replace</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">"watermarkTextBox"</span>, <span style="color: #3366CC;">""</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
<span style="color: #66cc66;">&#125;</span></p>
<p><span style="color: #003366; font-weight: bold;">function</span> onWatermarkTextBoxBlur<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><br />
<span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #006600;">value</span>.<span style="color: #006600;">length</span> == <span style="color: #CC0000;">0</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #006600;">value</span> = <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #006600;">watermark</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #006600;">className</span> += <span style="color: #3366CC;">" watermarkTextBox"</span>;<br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
<span style="color: #66cc66;">&#125;</span></div>
</div>
</div>
<p>
Jak można zauważyć, rzecz polega na dodaniu lub usunięciu nazwy uprzednio zdefiniowanej klasy CSS z listy klas pola tekstowego. Zakładamy tutaj, że atrybut <code>watermark</code> zawiera jego etykietę, czyli znak wodny. Żeby jednak tak było, musimy go ustawić, przy okazji <del>podpinając</del> (fuj, nie lubię tego słowa) przypisując powyższe funkcje do zdarzeń kontrolki. Czynimy to podczas wczytywania strony:</p>
<div class="syntax_hilite">
<div id="javascript-8">
<div class="javascript"><span style="color: #003366; font-weight: bold;">function</span> initWatermarkTextBoxes<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><br />
<span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> inputs = document.<span style="color: #006600;">getElementsByTagName</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">"input"</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #66cc66;">&#40;</span>i = <span style="color: #CC0000;">0</span>; i &lt;inputs.<span style="color: #006600;">length</span>; ++i<span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #66cc66;">&#40;</span>inputs<span style="color: #66cc66;">&#91;</span>i<span style="color: #66cc66;">&#93;</span>.<span style="color: #006600;">type</span> == <span style="color: #3366CC;">"text"</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &amp;&amp; inputs<span style="color: #66cc66;">&#91;</span>i<span style="color: #66cc66;">&#93;</span>.<span style="color: #006600;">className</span>.<span style="color: #006600;">indexOf</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">"watermarkTextBox"</span><span style="color: #66cc66;">&#41;</span> != -<span style="color: #CC0000;">1</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; inputs<span style="color: #66cc66;">&#91;</span>i<span style="color: #66cc66;">&#93;</span>.<span style="color: #006600;">watermark</span> = inputs<span style="color: #66cc66;">&#91;</span>i<span style="color: #66cc66;">&#93;</span>.<span style="color: #006600;">value</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; inputs<span style="color: #66cc66;">&#91;</span>i<span style="color: #66cc66;">&#93;</span>.<span style="color: #000066;">onfocus</span> = onWatermarkTextBoxFocus;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; inputs<span style="color: #66cc66;">&#91;</span>i<span style="color: #66cc66;">&#93;</span>.<span style="color: #000066;">onblur</span> = onWatermarkTextBoxBlur;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
<span style="color: #66cc66;">&#125;</span><br />
window.<span style="color: #000066;">onload</span> = initWatermarkTextBoxes;</div>
</div>
</div>
<p>
Przechodzimy po prostu po wszystkich tagach <code>input</code>, szukając zwykłych pól tekstowych (<code>type</code> równe </code>"text"</code>), które mają przypisaną "wodną" klasę CSS. Ustawiamy im następnie m.in. <code>watermark</code> na ich aktualną zawartość.</p>
<p>I właściwie to już wszystko. Okazuje się więc, że czasami JavaScript nie jest taki straszny ;) A jeśli chodzi o działający przykład praktyczny, to można go oglądać gdzieś nieopodal w postaci długo oczekiwanego formularza wyszukiwarki :)</p>
<p><small><em>Disclaimer</em>: rozwiązanie testowane na najnowszych wersjach dwóch najsensowniejszych przeglądarek, czyli FF3.6 i IE8. Za Opery, Safari i inne chromy nie ręczę ;P</small></p>
]]></content:encoded>
			<wfw:commentRss>http://xion.org.pl/2010/07/10/znak-wodny-w-polu-tekstowym/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Zamiast szumu wiatraczka</title>
		<link>http://xion.org.pl/2010/05/07/zamiast-szumu-wiatraczka/</link>
		<comments>http://xion.org.pl/2010/05/07/zamiast-szumu-wiatraczka/#comments</comments>
		<pubDate>Fri, 07 May 2010 13:53:34 +0000</pubDate>
		<dc:creator>Xion</dc:creator>
				<category><![CDATA[Internet]]></category>
		<category><![CDATA[Kultura]]></category>
		<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[Jango]]></category>
		<category><![CDATA[Last.fm]]></category>
		<category><![CDATA[muzyka]]></category>

		<guid isPermaLink="false">http://xion.org.pl/?p=1775</guid>
		<description><![CDATA[Dzisiaj chcę napisać o ważnej kwestii okołokoderskiej, przed którą chyba każdy prędzej czy później stanął. Pisząc kod, nie zawsze potrzebujemy wielkiego skupienia i absolutnej ciszy; przeciwnie, wiele osób lubi programować przy dźwiękach muzyki. Zazwyczaj jest to jakaś własna kolekcja utworów, zorganizowana w playlisty. Ma to swoje wady. Jedną z nich jest to, że wymaga sporo [...]]]></description>
			<content:encoded><![CDATA[<p>Dzisiaj chcę napisać o ważnej kwestii okołokoderskiej, przed którą chyba każdy prędzej czy później stanął. Pisząc kod, nie zawsze potrzebujemy wielkiego skupienia i absolutnej ciszy; przeciwnie, wiele osób lubi programować przy dźwiękach muzyki. Zazwyczaj jest to jakaś własna kolekcja utworów, zorganizowana w <em>playlisty</em>.<br />
Ma to swoje wady. Jedną z nich jest to, że wymaga sporo manualnej obsługi; jeśli jej zabraknie, to zawartość list(y) może nam się znudzić nawet w przypadku losowej kolejności odtwarzania (no, chyba że nasza kolekcja jest wystarczająco gigantyczna ;P). Poza tym w ten sposób nie usłyszymy nigdy niczego nowego, a być może wartego usłyszenia.<br />
Z drugiej strony włączenie radia zwykle nie jest sensowną opcją - nawet jeśli chodzi o radia internetowe. Nie da się bowiem znaleźć takiego, które idealnie w wpasuje się w nasz muzyczny gust. A gdyby tak można było stworzyć własne?... Eh, pomarzyć dobra rzecz :)</p>
<p><a href="http://www.jango.com"><img style="float:right; margin:5px" src="http://xion.org.pl/wp-content/uploads/2010/05/jango-logo.gif" alt=""/></a>Okazuje się jednak, że to zupełnie wykonalne. Istnieją serwisy, które właśnie na coś takiego pozwalają. Jednym z najstarszych i najbardziej znanych jest <a href="http://last.fm">Last.fm</a>, zawierający chyba wszystkie <em>feature</em>'y, jakich można oczekiwać (łącznie ze stacjonarnym klientem), Niestety, jest on płatny.<br />
Osobiście polecam darmowe <a href="http://www.jango.com">Jango</a>. Potrafi on dokładnie tyle, ile potrzeba - tj. tworzy wirtualne stacje radiowe (w dowolnej ilości, o ile mi wiadomo) grające muzykę wybranych wykonawców (z możliwością określenia preferencji do pojedynczych utworów) oraz artystów zbliżonych gatunkowo. To wyszukiwanie podobieństw działa przy tym całkiem dobrze, więc mamy spore szanse na odkrycie ciekawych, nieznanych wcześniej wykonawców. Wady?... Jak to bywa w przypadku takich serwisów, może to być niewystarczająco bogata biblioteka zarówno utworów, jak i artystów. Brakuje też <em>desktopowego</em> klienta, co może niektórym przeszkadzać; można wówczas spróbować zewnętrznego programu <a href="http://samuelhaddad.com/software-projects/jango-desktop/">Jango Desktop</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://xion.org.pl/2010/05/07/zamiast-szumu-wiatraczka/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Facebook, gry webowe i problem inwestycji</title>
		<link>http://xion.org.pl/2010/04/01/facebook-gry-webowe-i-problem-inwestycji/</link>
		<comments>http://xion.org.pl/2010/04/01/facebook-gry-webowe-i-problem-inwestycji/#comments</comments>
		<pubDate>Thu, 01 Apr 2010 16:12:03 +0000</pubDate>
		<dc:creator>Xion</dc:creator>
				<category><![CDATA[Gry]]></category>
		<category><![CDATA[Internet]]></category>
		<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[algorytmy]]></category>
		<category><![CDATA[Facebook]]></category>
		<category><![CDATA[Web 2.0]]></category>

		<guid isPermaLink="false">http://xion.org.pl/?p=1671</guid>
		<description><![CDATA[No i stało się - kierowany zapewne diabelskimi podszeptami, zarejestrowałem się na Facebooku. Zło (a nawet Zuo) w najczystszej postaci żem uczynił i oprócz formułowania próśb o przebaczenie mogę jedynie usprawiedliwiać się, co mnie do tego zgubnego w skutkach czynu popchnęło. A owym skutkiem (a "zupełnie przypadkiem" również przyczyną) było to, że przyjrzałem się największemu [...]]]></description>
			<content:encoded><![CDATA[<p><img style="float:right; margin:5px" src="http://xion.org.pl/wp-content/uploads/2010/04/facebook-top.png" alt="" title="Fejsbuk ;P" />No i stało się - kierowany zapewne diabelskimi podszeptami, zarejestrowałem się na <a href="http://www.facebook.com">Facebooku</a>. Zło (a nawet Zuo) w najczystszej postaci żem uczynił i oprócz formułowania próśb o przebaczenie mogę jedynie usprawiedliwiać się, co mnie do tego zgubnego w skutkach czynu popchnęło. A owym skutkiem (a "zupełnie przypadkiem" również przyczyną) było to, że przyjrzałem się największemu bogactwu tego serwisu, czyli... grom, rzecz jasna :)<br />
Gry na Facebooku dzielą się w sumie na dwie kategorie. Pierwsza z nich to wyewoluowana forma małych, szybkich gier flashowych, które służą do zabijania tych krótkich odcinków czasu, gdy akurat nie chce się nam robić czegoś pożytecznego. Ewolucja polegała tutaj na wykształceniu możliwości porównywania wyników ze znajomymi, co oczywiście natychmiast podnosi grywalność przynajmniej o 120% i jednocześnie uspokaja nas, że nie jesteśmy jedynymi osobami, które się obijają :)<br />
<a href="http://www.facebook.com/apps/application.php?id=46755028429"><img style="float:left; margin:5px" src="http://xion.org.pl/wp-content/uploads/2010/04/castle-age-logo.png" alt="" title="Castle Age" /></a>Drugi typ to zabawa w systematyczne klikanie: należy mniej więcej raz na kilkanaście godzin zalogować się i coś zrobić, by posunąć rozgrywkę do przodu. Cokolwiek to jest, nie możemy tego zrobić częściej, bo nie pozwala na to mechanika gry pod postacią regenerującej się w czasie energii/many/itp. (jak choćby w <a href="http://www.facebook.com/MafiaWars"><em>Mafia Wars</em></a>) czy też nierealistycznie krótkiego okresu wegetacyjnego truskawek (tak, mam tu na myśli oczywiście <a href="http://www.facebook.com/FarmVille"><em>Farmville</em></a>).</p>
<p>Jak widać w obu przypadkach nie jest to specjalnie absorbujące zajęcie. Z gier pierwszego typu do gustu przypadła mi <a href="http://www.facebook.com/WordChallenge"><em>Word Challenge</em></a>, dzięki której wydatnie (czyli o jakieś 5%) poszerzył się mój zasób angielskich słówek (niestety jedynie takich, które mają co najwyżej sześć liter). Wybraną przeze mnie pozycją z kategorii drugiej jest z kolei <a href="http://www.facebook.com/apps/application.php?id=46755028429"><em>Castle Age</em></a> - coś w rodzaju MMORPG-a przez przeglądarkę, całkiem zresztą udanego. I właśnie z tym związany jest pewien ciekawy problem...</p>
<p><img style="float:right; margin:5px" src="http://xion.org.pl/wp-content/uploads/2010/04/castle-age-buildings.png" alt="" title="" />W rzeczonej grze oprócz niewątpliwie ekscytującego odklikiwania kolejnych <em>questów</em> mamy też - że powiem nieco na wyrost - wątek ekonomiczny. Należy tam bowiem kupować nieruchomości, które później co godzinę generują nam przypływ świeżej gotówki. Budynki różnią się ceną i uzyskiwanym z nich przychodem, a ponadto możemy kupować je nie tylko pojedynczego, ale i w pakietach (po 5 lub 10).<br />
Jak pewnie nietrudno się domyślić, nasuwającym się tu od razu pytaniem jest to o optymalną strategię nabywania kolejnych budynków, skutkującą największym zyskiem w dłuższej perspektywie czasowej. Tak naszkicowany <strong>problem inwestycji</strong> (nazwa brzmi cokolwiek poważnie!) miałby więc następujące założenia:</p>
<ul>
<li>Istnieje <img src="http://xion.org.pl/wp-content/ql-cache/quicklatex-d20de1fa124517c91ebb375b63ec56ee.gif" alt="n \in \mathbb{N}" title="n \in \mathbb{N}" style="vertical-align: -1px; border: none;"/> rodzajów budynków z przypisanymi cenami początkowymi <img src="http://xion.org.pl/wp-content/ql-cache/quicklatex-cdb05f5f2831f506a2bface7d9a7397b.gif" alt="c_1, \ldots, c_n" title="c_1, \ldots, c_n" style="vertical-align: -4px; border: none;"/> i zyskiem generowanym na jednostkę czasu: <img src="http://xion.org.pl/wp-content/ql-cache/quicklatex-ea06843442afdf518370f9ab77d6b643.gif" alt="z_1, \ldots, z_n" title="z_1, \ldots, z_n" style="vertical-align: -4px; border: none;"/>. Początkowo posiadamy <img src="http://xion.org.pl/wp-content/ql-cache/quicklatex-668e329aba8876c2de195d28f44755f0.gif" alt="k_1 = \ldots = k_n = 0" title="k_1 = \ldots = k_n = 0" style="vertical-align: -4px; border: none;"/> budynków i <img src="http://xion.org.pl/wp-content/ql-cache/quicklatex-83878c91171338902e0fe0fb97a8c47a.gif" alt="p" title="p" style="vertical-align: -4px; border: none;"/> pieniędzy, ale w każdej jednostce czasu możemy dokonać dowolnej liczby zakupów, o ile posiadane środki na to wystarczają.</li>
<li>Każdorazowo po dokonaniu zakupu budynku danego rodzaju, jego cena wzrasta o ustaloną wartość <img src="http://xion.org.pl/wp-content/ql-cache/quicklatex-d247f594c78d0d2be10fc6d82512cc4e.gif" alt="d_i" title="d_i" style="vertical-align: -3px; border: none;"/> dla <img src="http://xion.org.pl/wp-content/ql-cache/quicklatex-2bfd219d69b4d61b2dd70c680cf11603.gif" alt="i \in {1, \ldots, n}" title="i \in {1, \ldots, n}" style="vertical-align: -4px; border: none;"/>. Zakupu możemy dokonywać pojedynczo lub też w ilościach określonych przez zbiór <img src="http://xion.org.pl/wp-content/ql-cache/quicklatex-fd8e312d30b490b0d5b0bd5b64bb1607.gif" alt="L \subset \mathbb{N}" title="L \subset \mathbb{N}" style="vertical-align: -1px; border: none;"/> (w <em>Castle Age</em> mamy <img src="http://xion.org.pl/wp-content/ql-cache/quicklatex-86b8a23d070508ede6e8523de4c6c736.gif" alt="L = \{ 5, 10 \}" title="L = \{ 5, 10 \}" style="vertical-align: -5px; border: none;"/>), jednak zawsze tylko jednego rodzaju budynków naraz.</li>
<li>Istnieje ograniczenie <img src="http://xion.org.pl/wp-content/ql-cache/quicklatex-a2525bdf0ce3b16207fa33eacbcec038.gif" alt="k \in \mathbb{N}" title="k \in \mathbb{N}" style="vertical-align: -1px; border: none;"/> na maksymalną posiadaną liczbę budynków jednego rodzaju - zatem zawsze zachodzi: <img src="http://xion.org.pl/wp-content/ql-cache/quicklatex-2bbdfbf094d71e43862c50e86a54823e.gif" alt="\forall i \le n, i \in \mathbb{N} \quad k_i \le k" title="\forall i \le n, i \in \mathbb{N} \quad k_i \le k" style="vertical-align: -4px; border: none;"/>. Dla ułatwienia możemy przyjąć, że ograniczenie to jest stałe (w <em>Castle Age</em> jest ono związane z poziomem doświadczenia).</li>
</ul>
<p>Pytamy tutaj o to, kiedy, ile i jakie budynki powinniśmy kupować, aby zmaksymalizować swój zysk w długim (najlepiej dowolnie długim) przedziale czasu. W szczególności zastanawiamy się, czy działa tu prosta strategia zachłanna - podobna do rozwiązania <a href="http://pl.wikipedia.org/wiki/Problem_plecakowy">ciągłego problemu plecakowego</a> - polegająca na zbieraniu zawsze takiej ilości gotówki, aby kupować maksymalną ilość najbardziej "efektywnych" budynków, tj. tych o największym ilorazie zysku do bieżącej ceny. Intuicja podpowiadałaby, że nie dla wszystkich zestawów danych musi tak być...</p>
<p>Zostawiam więc to zadanie jako materiał do przemyśleń na wolne dni. Nagroda za jego rozwiązanie będzie wielka: udowodni się w ten sposób, że gry z Facebooka mogą się do czegoś przydać!</p>
]]></content:encoded>
			<wfw:commentRss>http://xion.org.pl/2010/04/01/facebook-gry-webowe-i-problem-inwestycji/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Aby nie śmiecić</title>
		<link>http://xion.org.pl/2010/03/20/aby-nie-smiecic/</link>
		<comments>http://xion.org.pl/2010/03/20/aby-nie-smiecic/#comments</comments>
		<pubDate>Sat, 20 Mar 2010 18:32:23 +0000</pubDate>
		<dc:creator>Xion</dc:creator>
				<category><![CDATA[Internet]]></category>
		<category><![CDATA[Przemyślenia]]></category>
		<category><![CDATA[forum Warsztatu]]></category>

		<guid isPermaLink="false">http://xion.org.pl/?p=1650</guid>
		<description><![CDATA[Jako moderator forum Warsztatu mam wątpliwą przyjemność kontaktu z różnymi przejawami - nazwijmy to eufemistycznie - niepożądanych zachowań. A to mamy jakieś pytanie, na które odpowiedzią jest pierwszy rezultat, jaki wyszukiwarka wyrzuca w reakcji na prostą kwerendę. Innym razem może to być klasyczne "No i co tu jest źle?!", opatrzone wysokim na kilka ekranów kawałkiem [...]]]></description>
			<content:encoded><![CDATA[<p>Jako moderator <a href="http://forum.gamedev.pl">forum Warsztatu</a> mam wątpliwą przyjemność kontaktu z różnymi przejawami - nazwijmy to eufemistycznie - niepożądanych zachowań. A to mamy jakieś pytanie, na które odpowiedzią jest pierwszy rezultat, jaki wyszukiwarka wyrzuca w reakcji na prostą kwerendę. Innym razem może to być klasyczne "No i co tu jest źle?!", opatrzone wysokim na kilka ekranów kawałkiem kodu, dla którego właściwym miejscem jest <em>/dev/null</em>. Kiedy indziej będzie to pojawiający się po raz 2<sup>512</sup>. problem w rodzaju <em>unresolved external</em>... I tak dalej, i tak dalej. Ot, zwyczajne przypadki, gdy napisanie posta poprzedza (lub zastępuje) myślenie.</p>
<div style="float:right; margin:5px; text-align:center"><img src="http://xion.org.pl/wp-content/uploads/2010/03/picard-facepalm.jpg" alt="" title="*facepalm*" /><br/><small>Stuprocentowo uzasadnione.</small></div>
<p>Może nie jestem w stanie tego zrozumieć, ale przynajmniej potrafię się z tym pogodzić - po części pewnie dlatego, że sprzątanie po tego rodzaju twórczości nie jest specjalnie kłopotliwe. Jest jednak przynajmniej jedna rzecz, która skłania mnie do poważnych rozważań na temat intelektualnej kondycji rodzaju ludzkiego - a przynajmniej tej jego części, która się na <a href="http://forum.gamedev.pl">forum</a> pojawia - połączonych z co najmniej jednokrotnym wykonaniem znanego i lubianego gestu kapitana Picarda.</p>
<p>O co chodzi?... O dołączanie nowych pytań do istniejących wątków, z uzasadnieniem, że czyni się tak po to, aby nie zaśmiecać forum nowymi tematami. Czy jest to dobra praktyka? Czy ma to jakikolwiek sens? I wreszcie, czy skutkiem jej stosowania jest faktycznie większy porządek forum?<br />
Otóż nie - i to po trzykroć nie. Paradoks tu występujący polega właśnie na tym, że - dokładnie przeciwnie do intencji osób tak postępujących - podczepianie się pod istniejące tematy skutkuje tylko i wyłącznie <em>jeszcze większym</em> bałaganem! Dzieje się tak co najmniej z kilku powodów:</p>
<ul>
<li>Wprowadzanie nowego pytania w istniejący wątek odcina możliwość dodania czegokolwiek do oryginalnego tematu dyskusji. Jeśli ktoś mimo wszystko będzie próbował to robić, najprawdopodobniejszym rezultatem jest przeplatanka odpowiedzi na stare i nowe pytanie. Czytanie czegoś takiego to czysta przyjemność, nieprawdaż? 8-)</li>
<li>Jeśli jeden wątek zawiera więcej niż jeden temat/dyskusję/pytanie, to jego tytuł staje się mylący. Po niedługim czasie podczepione posty mogą być już zupełnie niezwiązane z tym, o czym wątek był oryginalnie. Istny synonim porządku, co nie? :)</li>
<li>Podczepione pytanie jest o wiele trudniejsze do znalezienia przez forumową wyszukiwarkę - jeśli to w ogóle jest możliwe. Co więcej, utrudnia ono też wyszukanie wszystkich informacji z oryginalnej dyskusji - choćby dlatego, że trzeba wpierw ustalić, gdzie się ona kończy...</li>
<li>Przywrócenie radośnie zepsutego wątku do stanu używalności jest pracochłonne: wymaga zlokalizowania wszystkich postów odnoszących się do nowego pytania (które mogą się przeplatać z tymi od pierwotnego), wydzielenia ich do nowego wątku i nadania mu sensownego tytułu. To wszystko da się zresztą zrobić tylko przy założeniu, że nie istnieją już posty, które odwołują się do obu pytań <em>naraz</em>. Jeszcze bardziej daleko idące jest przypuszczenie, że istnieje jakikolwiek moderator, któremu chciałoby się takich podziałów dokonywać :)</li>
</ul>
<p>Widać zatem wyraźnie, że skutek doczepiania się do istniejących wątków jest dokładnie odwrotny do zamierzonego. Nie ma to najmniejszego sensu i jest wybitnie niepożądane. Wciąż jednak nie mogę się nadziwić, jakaż to dziwna logika podsuwa ludziom pomysły, że może być inaczej...</p>
]]></content:encoded>
			<wfw:commentRss>http://xion.org.pl/2010/03/20/aby-nie-smiecic/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>AI na Warsztacie</title>
		<link>http://xion.org.pl/2010/02/28/ai-na-warsztacie/</link>
		<comments>http://xion.org.pl/2010/02/28/ai-na-warsztacie/#comments</comments>
		<pubDate>Sun, 28 Feb 2010 11:03:25 +0000</pubDate>
		<dc:creator>Xion</dc:creator>
				<category><![CDATA[Internet]]></category>
		<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[forum Warsztatu]]></category>
		<category><![CDATA[Warsztat]]></category>

		<guid isPermaLink="false">http://xion.org.pl/?p=1604</guid>
		<description><![CDATA[O niezadowalającym poziomie forum Warsztatu słyszałem już wielokrotnie. Że pytania dotyczą głównie podstaw programowania, że wiele z nich to mniej lub bardziej zakamuflowane "No i co tu jest źle?", że odpowiedzi na większość z nich znajdują się na drugim końcu wyszukiwarki - i tym podobne. A jeśli już jakiś wątek nie podpada pod którąś z [...]]]></description>
			<content:encoded><![CDATA[<p>O niezadowalającym poziomie <a href="http://forum.gamedev.pl">forum Warsztatu</a> słyszałem już wielokrotnie. Że pytania dotyczą głównie podstaw programowania, że wiele z nich to mniej lub bardziej zakamuflowane "No i co tu jest źle?", że odpowiedzi na większość z nich znajdują się na drugim końcu wyszukiwarki - i tym podobne. A jeśli już jakiś wątek nie podpada pod którąś z tych kategorii, to albo jest kolejnym "genialnym" pomysłem na grę, albo <em>off-topikiem</em>, albo w najlepszym razie dotyczy jakiegoś zagadnienia z zakresu programowania grafiki.</p>
<p>Pewnie coś w tym jest. Jednak ostatnio ku mojemu zaskoczeniu (i pełnej aprobacie) pojawiło się też kilka dyskusji na tematy związane ze sztuczną inteligencją. Niby <a href="http://forum.gamedev.pl/index.php/board,13.0.html"> taki dział też jest</a>, ale jakoś dotąd nie zauważyłem, by był zanadto aktywny.<br />
A tu proszę: kilka ciekawych wątków w ciągu paru dni. Może to nic wielkiego i może niespecjalnie nawet jest tu o czym pisać, bo ich tematyka jest dość ograniczona (głównie sieci neuronowe), a dziedzina raczej akademicka i pewnie nawet niekoniecznie związana z <em>gamedevem</em>. Ale...</p>
<p>Ale myślę, że jednak warto o tym wspomnieć :) Przede wszystkim po to, by nikt nie zapomniał, że gry to nie tylko ładna grafika i że w dzisiejszych czasach powinny one być choć trochę - z braku lepszego słowa - 'inteligentne'.<br />
A poza tym miałem też ochotę zwrócić uwagę na istnienie tego właśnie <a href="http://forum.gamedev.pl/index.php/board,13.0.html">działu forum Warsztatu</a> - więc niniejszym właśnie to czynię :]</p>
]]></content:encoded>
			<wfw:commentRss>http://xion.org.pl/2010/02/28/ai-na-warsztacie/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>10 lat w sieci</title>
		<link>http://xion.org.pl/2009/12/25/10-lat-w-sieci/</link>
		<comments>http://xion.org.pl/2009/12/25/10-lat-w-sieci/#comments</comments>
		<pubDate>Fri, 25 Dec 2009 19:46:04 +0000</pubDate>
		<dc:creator>Xion</dc:creator>
				<category><![CDATA[Internet]]></category>
		<category><![CDATA[Przemyślenia]]></category>
		<category><![CDATA[Życie]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Web 2.0]]></category>

		<guid isPermaLink="false">http://xion.org.pl/?p=1537</guid>
		<description><![CDATA[Tegoroczny koniec grudnia to czas podsumowań tego, co działo się nie tylko w ciągu ostatnich 12 miesięcy, ale i całej ostatniej dekady. A przypadkiem właśnie dekadę temu zyskałem dostęp do globalnej sieci zwanej Internetem... Jest to więc ciekawa okazja na podzielenie się paroma moimi obserwacjami tego, jak na przestrzeni ostatnich 10 lat Internet się zmieniał. [...]]]></description>
			<content:encoded><![CDATA[<p>Tegoroczny koniec grudnia to czas podsumowań tego, co działo się nie tylko w ciągu ostatnich 12 miesięcy, ale i całej ostatniej dekady. A przypadkiem właśnie dekadę temu zyskałem dostęp do globalnej sieci zwanej Internetem... Jest to więc ciekawa okazja na podzielenie się paroma moimi obserwacjami tego, jak na przestrzeni ostatnich 10 lat Internet się zmieniał.</p>
<p><img style="float:right; margin:5px" src="http://xion.org.pl/wp-content/uploads/2009/12/at.png" alt="" title="" />Rok 1999 to nie były jakieś zamierzchłe czasy sieci w Polsce (nie wspominając już o sieci w ogóle), lecz mimo to podejrzewam, że niezbyt duża część obecnych jej użytkowników dobrze je pamięta. Cechą wyróżniającą Internetu w tamtym okresie była przede wszystkim oszczędność. Szerokopasmowe łącza nikomu się wtedy nie śniło, a część internautów musiała płacić za sam czas spędzony w sieci (sławetny numer 0202122). Dlatego też podstawową zasadą netykiety było możliwie najskuteczniejsze zmniejszanie rozmiarów przesyłanych danych. Objawiało się to dość spartańskim wyglądem ówczesnych stron, z rzadka składającym się z większej ilości obrazków, a często wykorzystującym takie niefortunne wynalazki HTML jak choćby ramki.<br />
Jak nietrudno zauważyć dzisiaj jest zupełnie inaczej. Główna strona typowego portalu może spokojnie ważyć kilka megabajtów i być okraszona kilkoma reklamowymi animacjami typu Flash, często zresztą niczym nie różniących się od spotów telewizyjnych. Wymaga ona więc znacznie większej przepustowości łącza, a także o wiele lepszej i efektywniejszej przeglądarki.</p>
<p>To też zresztą znak rozpoznawczy Internetu końca dekady: jest on niemal tożsamy z WWW, a inne protokoły komunikacji są w głębokim odwrocie. Kilka lat wcześniej było pod tym względem inaczej. Przeglądanie stron było tylko jedną z wielu sieciowych aktywności, do których należało też korzystanie z e-maila, ściąganie plików przez FTP, czytanie grup dyskusyjnych (Usenet) czy pogaduszki za pośrednictwem IRC. Dzisiaj prawie każdy z tych kanałów komunikacji został pochłonięty lub zastąpiony przez tzw. aplikacje webowe, czyli po prostu trochę bardziej interaktywne wersje stron WWW.</p>
<p>I wreszcie trzeci aspekt zmian, jakie w sieci się dokonały: jej umasowienie. Nie chodzi tu tylko o sam wzrost liczby osób korzystających z sieci, który w ciągu ostatnich 10 lat był <a href="http://www.internetworldstats.com/stats.htm">prawie czterokrotny</a>. Chodzi o pewne zmiany w samej "strukturze" sieci, które są przynajmniej częściowo jego wynikiem.<br />
Kiedyś w <em>Przekroju</em> czytałem <a href="http://przekroj.pl/cywilizacja_spoleczenstwo_artykul,1596.html">artykuł</a> reklamowany na okładce wiele mówiącą frazą: "Jak idioci zepsuli nam Internet". Dotyczy ona oczywiście całego sieciowego trendu znanego pod ogólnym określeniem Web 2.0, nad którym zresztą pastwiłem się już <a href="http://xion.org.pl/2008/01/05/cale-to-web-2-0/">przy innej okazji</a>. W skrócie chodzi mniej więcej o to, że połączenie masowości dostępu do Internetu (w krajach rozwiniętych to już przynajmniej połowa populacji) z łatwością umieszczania w nim nowych treści (coraz mniejsza konieczność znajomości takich "technikaliów" jak choćby HTML) powoduje zalanie sieci <em>contentem</em> bez żadnej wartości, czyli jej zwyczajne zaśmiecenie.<br />
W sumie jednak jest to nic nowego; już przed 10 laty mówiło się, że zawartością Internetu są w większości bzdury. Różnica między stanem z tego czasu a dniem dzisiejszym jest jednak taka, że mimo bezwzględnego (a pewnie i względnego) wzrostu ilości treściowych odpadów znalezienie poszukiwanych informacji jest paradoksalnie łatwiejsze niż kiedykolwiek wcześniej. Zawdzięczamy to jednak tylko i wyłącznie gwałtownemu rozwojowi internetowych wyszukiwarek.</p>
<p>Ogólny bilans tej dekady w sieci nie jest więc jednoznaczny. Z jednej strony stoją rzecz jasna <a href="http://www.myspace.com/">MySpace</a>, <a href="http://www.facebook.com/">Facebooka</a>, <a href="http://www.4chan.org/">4chana</a> czy inne sieciowe szkodniki, ale z drugiej jest przecież <a href="http://www.google.com/">Google</a>, <a href="http://www.wikipedia.org/">Wikipedia</a> i całe mnóstwo wartościowych serwisów tematycznych, z których część nie powstałaby pewnie w warunkach "elitarnego" Internetu sprzed dekady.<br />
Jesteśmy więc w innym miejscu - lecz niekoniecznie gorszym. Trzeba się do niego po prostu przyzwyczaić :)</p>
]]></content:encoded>
			<wfw:commentRss>http://xion.org.pl/2009/12/25/10-lat-w-sieci/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Triki z PowerShellem #12 &#8211; Rozpakowywanie</title>
		<link>http://xion.org.pl/2009/12/07/triki-z-powershellem-12-rozpakowywanie/</link>
		<comments>http://xion.org.pl/2009/12/07/triki-z-powershellem-12-rozpakowywanie/#comments</comments>
		<pubDate>Mon, 07 Dec 2009 22:18:05 +0000</pubDate>
		<dc:creator>Xion</dc:creator>
				<category><![CDATA[Aplikacje]]></category>
		<category><![CDATA[Internet]]></category>
		<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[kompresja]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://xion.org.pl/?p=1500</guid>
		<description><![CDATA[Wiele programów z sieci wciąż jeszcze ściąga się w postaci archiwów do samodzielnego wypakowania, jak choćby w formacie .zip. Ma to swoje zalety i wady - do tych drugich należy fakt, że nie bardzo wiadomo, jak wygląda wewnętrzna struktura katalogów takiej paczki. Używając opcji typu Wypakuj tutaj ryzykujemy zaśmiecenie folderu Downloads plikami programu. Dlatego osobiście [...]]]></description>
			<content:encoded><![CDATA[<p><img style="float:left; margin:5px" src="http://xion.org.pl/wp-content/uploads/2009/12/redundant-path.png" alt="Powtarzające się katalogi" title="Powtarzające się katalogi" />Wiele programów z sieci wciąż jeszcze ściąga się w postaci archiwów do samodzielnego wypakowania, jak choćby w formacie .<em>zip</em>. Ma to swoje zalety i wady - do tych drugich należy fakt, że nie bardzo wiadomo, jak wygląda wewnętrzna struktura katalogów takiej paczki. Używając opcji typu <em>Wypakuj tutaj</em> ryzykujemy zaśmiecenie folderu <em>Downloads</em> plikami programu. Dlatego osobiście zawsze stosuję polecenie <em>Wypakuj do nowego katalogu</em>.<br />
I tu czasem jest mały zonk, gdy twórca archiwum zdecydował się na spakowanie całego folderu, a nie tylko zawartych w nim plików. Powstają wtedy nadmiarowe katalogi, wydłużające ścieżki do plików (co widać obok - w wersji trochę przesadzonej ;)).</p>
<p>Ponieważ podobne sytuacje zdarzają mi się dość często, postanowiłem im zaradzić przy pomocy najlepszego narzędzia na takie okazje, czyli PowerShella rzecz jasna :) Wynikiem jest poniższy skrypt do sprytniejszego rozpakowywania archiwów:</p>
<div class="syntax_hilite">
<div id="csharp-10">
<div class="csharp"><span style="color: #008080;"># unpack.ps1</span><br />
<span style="color: #008080;"># Sprytne rozpakowywanie archiwów</span><br />
param <span style="color: #000000;">&#40;</span><span style="color: #000000;">&#91;</span><span style="color: #FF0000;">string</span><span style="color: #000000;">&#93;</span>$archive = $<span style="color: #000000;">&#40;</span><span style="color: #0600FF;">throw</span> <span style="color: #808080;">"No archive specified"</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span></p>
<p><span style="color: #008080;"># Bierzemy nazwę archiwum i tworzymy odpowiadający mu katalog</span><br />
$name = <span style="color: #000000;">&#91;</span>IO.<span style="color: #0000FF;">Path</span><span style="color: #000000;">&#93;</span>::<span style="color: #0000FF;">GetFileNameWithoutExtension</span><span style="color: #000000;">&#40;</span>$archive<span style="color: #000000;">&#41;</span><br />
Set-Location -Path <span style="color: #000000;">&#40;</span>New-<span style="color: #FF0000;">Object</span> IO.<span style="color: #0000FF;">FileInfo</span> @<span style="color: #000000;">&#40;</span>$name<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>.<span style="color: #0000FF;">DirectoryName</span><br />
$dir = <span style="color: #000000;">&#91;</span>IO.<span style="color: #0000FF;">Directory</span><span style="color: #000000;">&#93;</span>::<span style="color: #0000FF;">CreateDirectory</span><span style="color: #000000;">&#40;</span>$name<span style="color: #000000;">&#41;</span></p>
<p><span style="color: #008080;"># Rozpakowujemy archiwum do tego katalogu</span><br />
$shell = New-<span style="color: #FF0000;">Object</span> -ComObject Shell.<span style="color: #0000FF;">Application</span><br />
$src = $shell.<span style="color: #0600FF;">Namespace</span><span style="color: #000000;">&#40;</span>$archive<span style="color: #000000;">&#41;</span><br />
$dest = $shell.<span style="color: #0600FF;">Namespace</span><span style="color: #000000;">&#40;</span>$name<span style="color: #000000;">&#41;</span><br />
$dest.<span style="color: #0000FF;">CopyHere</span><span style="color: #000000;">&#40;</span>$src.<span style="color: #0000FF;">items</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span></p>
<p><span style="color: #008080;"># Rekurencyjnie badamy zawartość rozpakowanego archiwum</span><br />
<span style="color: #0600FF;">while</span> <span style="color: #000000;">&#40;</span><span style="color: #000000;">&#40;</span>$items = $dir.<span style="color: #0000FF;">GetFileSystemInfos</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span> -eq <span style="color: #FF0000;">1</span><span style="color: #000000;">&#41;</span><br />
<span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #008080;"># Sprawdzamy, czy jego pierwszy i jedyny element jest katalogiem</span><br />
&nbsp; &nbsp; $fsi = $items<span style="color: #000000;">&#91;</span><span style="color: #FF0000;">0</span><span style="color: #000000;">&#93;</span><br />
&nbsp; &nbsp; <span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span><span style="color: #000000;">&#40;</span>$fsi.<span style="color: #0000FF;">Attributes</span> -band <span style="color: #000000;">&#91;</span>IO.<span style="color: #0000FF;">FileAttributes</span><span style="color: #000000;">&#93;</span>::<span style="color: #0000FF;">Directory</span><span style="color: #000000;">&#41;</span> -eq <span style="color: #FF0000;">0</span><span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#123;</span> <span style="color: #0600FF;">break</span> <span style="color: #000000;">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #008080;"># Jest - dokonujemy skrócenia ścieżki</span><br />
&nbsp; &nbsp; $fsi.<span style="color: #0000FF;">MoveTo</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#91;</span>IO.<span style="color: #0000FF;">Path</span><span style="color: #000000;">&#93;</span>::<span style="color: #0000FF;">GetRandomFileName</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp; $dir.<span style="color: #0000FF;">Delete</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp; $dir = $fsi<br />
&nbsp; &nbsp; $dir.<span style="color: #0000FF;">MoveTo</span><span style="color: #000000;">&#40;</span>$name<span style="color: #000000;">&#41;</span><br />
<span style="color: #000000;">&#125;</span></div>
</div>
</div>
<p>
Jego działanie polega wpierw na zwykłej dekompresji archiwum. Jak można zauważyć, używa do tego obiektu COM-owskiego <code>Shell.Application</code>. To sprawia, że skrypt ma pod tym względem te same możliwości co zwykły windowsowy Eksplorator (dla większych plików pokaże nawet pasek postępu ;]).<br />
Później wypakowana zawartość jest poddawana operacji, którą nazywam tutaj 'skróceniem ścieżki'. Polega ona wyrzuceniu jednego poziomu drzewa folderów, o ile tylko pewien katalog jest jedynym elementem swojego katalogu nadrzędnego. Takie właśnie sytuacje powstają przy dekompresji do nowego folderu archiwów źle zapakowanych (przynajmniej z mojego punktu widzenia ;P). Wynikiem działania skryptu będzie więc w sumie jeden nowy podkatalog zawierający bezpośrednio całą interesującą zawartość archiwum.</p>
<p>Oczywiście używanie powyższego skryptu tylko z poziomu linii komend PowerShella nie jest specjalnie wygodne; lepiej jest dodać go do menu kontekstowego archiwów, czyli np. plików .<em.zip</em>. O tym, jak można tego dokonać, napisałem dość obszernie przy okazji prezentacji <a href="http://xion.org.pl/2008/05/24/triki-z-powershellem-2-szybki-upload/">skryptu do wysyłania przez FTP</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://xion.org.pl/2009/12/07/triki-z-powershellem-12-rozpakowywanie/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Triki z PowerShellem #11 &#8211; Ćwierkamy</title>
		<link>http://xion.org.pl/2009/10/30/triki-z-powershellem-11-cwierkamy/</link>
		<comments>http://xion.org.pl/2009/10/30/triki-z-powershellem-11-cwierkamy/#comments</comments>
		<pubDate>Fri, 30 Oct 2009 18:41:33 +0000</pubDate>
		<dc:creator>Xion</dc:creator>
				<category><![CDATA[Internet]]></category>
		<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[HTTP]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Twitter]]></category>

		<guid isPermaLink="false">http://xion.org.pl/?p=1416</guid>
		<description><![CDATA[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ą. Fakt sprawił rzecz [...]]]></description>
			<content:encoded><![CDATA[<p>W ramach wyposażania nowozainstalowanego systemu w niezbędne programy, przypomniałem sobie o istnieniu <a href="http://www.microsoft.com/windowsserver2003/technologies/management/powershell/default.mspx">PowerShella</a>. 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ą.</p>
<p><a href="http://twitter.com"><img style="float:right; margin:5px" src="http://xion.org.pl/wp-content/uploads/2009/10/twitter-image.png" alt="Obrazek z Twittera" title="Obrazek z Twittera" /></a>Fakt sprawił rzecz jasna, że zaraz zachciało mi się wypróbować go w jakimś nowym zastosowaniu. Padło na wysyłanie <em>update</em>'ów do <a href="http://twitter.com">Twittera</a>, 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:</p>
<div class="syntax_hilite">
<div id="csharp-14">
<div class="csharp"><span style="color: #008080;"># tweet.ps1</span><br />
<span style="color: #008080;"># Wysyłanie nowego statusu do Twittera</span></p>
<p><span style="color: #000000;">&#91;</span>Reflection.<span style="color: #0000FF;">Assembly</span><span style="color: #000000;">&#93;</span>::<span style="color: #0000FF;">LoadWithPartialName</span><span style="color: #000000;">&#40;</span><span style="color: #808080;">"System.Web"</span><span style="color: #000000;">&#41;</span> | Out-<span style="color: #0600FF;">Null</span></p>
<p><span style="color: #008080;"># Stałe</span><br />
$LOGIN = <span style="color: #808080;">"login"</span> <span style="color: #008080;"># lub e-mail</span><br />
$PASS = <span style="color: #808080;">"hasło"</span></p>
<p><span style="color: #008080;"># Pobranie statusu od użytkownika</span><br />
$tweet = Read-Host -Prompt <span style="color: #808080;">"Status"</span></p>
<p><span style="color: #008080;"># Złożenie żądania HTTP POST</span><br />
$uri = <span style="color: #000000;">&#91;</span>Uri<span style="color: #000000;">&#93;</span><span style="color: #808080;">"http://twitter.com/statuses/update.xml"</span><br />
$http = <span style="color: #000000;">&#91;</span>Net.<span style="color: #0000FF;">HttpWebRequest</span><span style="color: #000000;">&#93;</span>::<span style="color: #0000FF;">Create</span><span style="color: #000000;">&#40;</span>$uri<span style="color: #000000;">&#41;</span><br />
$http.<span style="color: #0000FF;">Credentials</span> = New-<span style="color: #FF0000;">Object</span> Net.<span style="color: #0000FF;">NetworkCredential</span> @<span style="color: #000000;">&#40;</span>$LOGIN, $PASS<span style="color: #000000;">&#41;</span><br />
$http.<span style="color: #0000FF;">Method</span> = <span style="color: #000000;">&#91;</span>Net.<span style="color: #0000FF;">WebRequestMethods</span>+Http<span style="color: #000000;">&#93;</span>::<span style="color: #0000FF;">Post</span><br />
$http.<span style="color: #0000FF;">ServicePoint</span>.<span style="color: #0000FF;">Expect100Continue</span> = $false <span style="color: #008080;"># (*)</span></p>
<p><span style="color: #008080;"># Wysyłanie danych</span><br />
$data = <span style="color: #808080;">"status="</span> + <span style="color: #000000;">&#91;</span>Web.<span style="color: #0000FF;">HttpUtility</span><span style="color: #000000;">&#93;</span>::<span style="color: #0000FF;">UrlEncode</span><span style="color: #000000;">&#40;</span>$tweet<span style="color: #000000;">&#41;</span><br />
$http.<span style="color: #0000FF;">ContentLength</span> = $data.<span style="color: #0000FF;">Length</span><br />
$sw = New-<span style="color: #FF0000;">Object</span> IO.<span style="color: #0000FF;">StreamWriter</span> @<span style="color: #000000;">&#40;</span>$http.<span style="color: #0000FF;">GetRequestStream</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp; $sw.<span style="color: #0000FF;">Write</span><span style="color: #000000;">&#40;</span>$data<span style="color: #000000;">&#41;</span><br />
$sw.<span style="color: #0000FF;">Close</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span></p>
<p><span style="color: #008080;"># Wyświetlamy ID nowego statusu</span><br />
$resp = $http.<span style="color: #0000FF;">GetResponse</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>.<span style="color: #0000FF;">GetResponseStream</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><br />
$sr = New-<span style="color: #FF0000;">Object</span> IO.<span style="color: #0000FF;">StreamReader</span> @<span style="color: #000000;">&#40;</span>$resp<span style="color: #000000;">&#41;</span><br />
$xml = <span style="color: #000000;">&#91;</span>xml<span style="color: #000000;">&#93;</span>$sr.<span style="color: #0000FF;">ReadToEnd</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><br />
<span style="color: #808080;">"Status updated (ID: "</span> + $xml.<span style="color: #0000FF;">status</span>.<span style="color: #0000FF;">id</span> + <span style="color: #808080;">")"</span> | Out-Host<br />
$sr.<span style="color: #0000FF;">Close</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span></p>
<p><span style="color: #008080;"># Obsługa błędów</span><br />
trap&nbsp; &nbsp; <span style="color: #000000;">&#123;</span> <span style="color: #808080;">"Error: "</span> + $_.<span style="color: #0000FF;">Exception</span>.<span style="color: #0000FF;">Message</span>; <span style="color: #0600FF;">return</span> <span style="color: #000000;">&#125;</span></div>
</div>
</div>
<p>
Jednym z owych detali było kodowanie statusu algorytmem dla URL-i (zamieniającym spacje na %20 itd.), wykonywane poprzez <code>System.Web.HttpUtility.UrlEncode</code> - stąd konieczność importowania <em>assembly</em> <code>System.Web</code>. Ale to jest w sumie pikuś.<br />
Znacznie większym "trikiem" jest linijka oznaczona gwiazdką <code>(*)</code>. Powoduje ona obejście domyślnego zachowania .NET, który do każdego żądania HTTP typu POST dodaje nagłówek:</p>
<div class="syntax_hilite">
<div id="code-15">
<div class="code">Expect: <span style="color:#800000;">100</span>-continue</div>
</div>
</div>
<p>
Powoduje on wysłanie tak naprawdę dwóch <em>requestów</em>: 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.<br />
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.</p>
<p>Przypomnę jeszcze tylko - gdy ktoś zechciał powyższego skryptu używać do przesyłania <em>tweetów</em> - że uruchomienie skryptu PSh z poziomu zwykłej linii poleceń wymaga parametru <code>-Command</code> i kropki:</p>
<div class="syntax_hilite">
<div id="code-16">
<div class="code">powershell -Command . <span style="color:#CC0000;">'ścieżka<span style="color:#000099; font-weight:bold;">\t</span>weet.ps1'</span></div>
</div>
</div>
<p>
Do takiej komendy można np. utworzyć skrót i przypisać mu kombinację klawiszy w celu szybkiego uruchamiania.</p>
]]></content:encoded>
			<wfw:commentRss>http://xion.org.pl/2009/10/30/triki-z-powershellem-11-cwierkamy/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Co to jest przeglądarka?</title>
		<link>http://xion.org.pl/2009/10/08/co-to-jest-przegladarka/</link>
		<comments>http://xion.org.pl/2009/10/08/co-to-jest-przegladarka/#comments</comments>
		<pubDate>Thu, 08 Oct 2009 20:31:23 +0000</pubDate>
		<dc:creator>Xion</dc:creator>
				<category><![CDATA[Internet]]></category>
		<category><![CDATA[przeglądarki WWW]]></category>

		<guid isPermaLink="false">http://xion.org.pl/?p=935</guid>
		<description><![CDATA[Prawie dokładnie dwa lata temu pisałem o tym, że przeglądarki WWW wpisują w dziwny trend przyswajania sobie coraz to nowych funkcjonalności. Część z nich nie musi być zresztą w jakikolwiek sposób związana z przeglądaniem stron. Aż chciałoby się jeszcze dodać, iż wkrótce użytkownicy zapomną, do czego ich przeglądarki tak naprawdę służą oraz gdzie się "kończą". [...]]]></description>
			<content:encoded><![CDATA[<p>Prawie dokładnie dwa lata temu <a href="http://xion.org.pl/2007/09/23/caly-swiat-w-przegladarce/">pisałem o tym</a>, że przeglądarki WWW wpisują w dziwny trend przyswajania sobie coraz to nowych funkcjonalności. Część z nich nie musi być zresztą w jakikolwiek sposób związana z przeglądaniem stron. Aż chciałoby się jeszcze dodać, iż wkrótce użytkownicy zapomną, do czego ich przeglądarki tak naprawdę służą oraz gdzie się "kończą".</p>
<p><img style="float:right; margin:5px" src="http://xion.org.pl/wp-content/uploads/2009/10/tree-browser-logos.png" alt="Loga trzech przeglądarek" />No i <em>voila</em> - to już się dzieje. Oto powstała <a href="http://www.whatbrowser.org/">strona internetowa</a>, z której można się dowiedzieć... czym są przeglądarki, dlaczego nie są tym samym co internetowe wyszukiwarki i czym różnią się od reszty systemu operacyjnego. Tę wiedzę możemy posiąść między innymi poprzez oglądnięcie wielce interesującego filmiku. Żeby było jeszcze zabawniej, wspomnę, że tę edukacyjną witrynę przygotował nie kto inny, jak tylko sam... Google!<br />
W rzeczywistości jednak nie ma się z czego śmiać. Skoro już nawet tam dostrzegana jest potrzeba szerszego informowania o tym, że Firefox jest czym innym niż Windows, a pasek adresu to nie to samo co pole zapytań wyszukiwarki, to ze stanem tej wiedzy wśród tzw. przeciętnych użytkowników musi być naprawdę źle. A skoro granica między <em>online</em> i <em>offline</em> tak bardzo się zatarła, to ani się obejrzymy i zawód programisty zostanie zastąpiony przez <em>web developera</em>...Brr! Chciałbym, żeby tym razem moje przewidywania w tej dziedzinie się nie sprawdziły :P</p>
]]></content:encoded>
			<wfw:commentRss>http://xion.org.pl/2009/10/08/co-to-jest-przegladarka/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Przekierowanie z POST-em</title>
		<link>http://xion.org.pl/2009/09/19/przekierowanie-z-post-em/</link>
		<comments>http://xion.org.pl/2009/09/19/przekierowanie-z-post-em/#comments</comments>
		<pubDate>Sat, 19 Sep 2009 13:45:06 +0000</pubDate>
		<dc:creator>Xion</dc:creator>
				<category><![CDATA[Internet]]></category>
		<category><![CDATA[HTTP]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[POST]]></category>
		<category><![CDATA[przekierowanie]]></category>

		<guid isPermaLink="false">http://xion.org.pl/?p=917</guid>
		<description><![CDATA[Oprócz ciasteczek (cookies) dwoma podstawowymi sposobami przekazywania parametrów na wejście serwera HTTP są metody znane jako GET i POST. Ta pierwsza wykorzystuje do tego sam adres URL, umieszczając dodatkowe dane po znaku zapytania, np.: /forum/showthread.php?id=12345&#038;filter=none. W przypadku tej drugiej parametry są przekazywane poprzez treść samego żądania HTTP; z punktu widzenia użytkownika są więc one niewidoczne. [...]]]></description>
			<content:encoded><![CDATA[<p>Oprócz ciasteczek (<em>cookies</em>) dwoma podstawowymi sposobami przekazywania parametrów na wejście serwera HTTP są metody znane jako GET i POST. Ta pierwsza wykorzystuje do tego sam adres URL, umieszczając dodatkowe dane po znaku zapytania, np.: <kbd>/forum/showthread.php?id=12345&#038;filter=none</kbd>. W przypadku tej drugiej parametry są przekazywane poprzez treść samego żądania HTTP; z punktu widzenia użytkownika są więc one niewidoczne.<br />
Metoda GET zwykle służy do wymiany danych między stronami połączonymi za pomocą zwykłych linków. POST z kolei wykorzystuje się do wysyłania informacji wprowadzanych przez użytkownika w różnego rodzaju formularzach. Przekierowanie następuje wówczas po jego wysłaniu, co zwykle czyni się odpowiednim przyciskiem (<em>submit</em>).</p>
<p>Bywa jednak tak, że chcemy dokonać takiego przekierowania - z ustalonymi parametrami - po zwykłym kliknięciu na link, z pominięciem wypełniania formularza przez użytkownika. Dobrym przykładem jest sytuacja, gdy nasza strona korzysta w jakiś sposób z innego serwisu, do którego przejście wymaga logowania. Jeśli chcielibyśmy, by odbywało się ono automatycznie - po kliknięciu jakiegoś linku - to musimy wysłać odpowiednie żądanie HTTP z parametrami przesłanymi metodą POST. Do tego nie wystarczy niestety sam znacznik <code>&lt;a&gt;</code>.</p>
<p>Rozwiązaniem jest wtedy użycie <strong>dodatkowej strony</strong> przekierowującej, na której umieścimy już odpowiednio "wypełniony" formularz:</p>
<div class="syntax_hilite">
<div id="html-21">
<div class="html"><span style="color: #009900;"><a href="http://december.com/html/4/element/form.html"><span style="color: #000000; font-weight: bold;">&lt;form</span></a> <span style="color: #000066;">method</span>=<span style="color: #ff0000;">"POST"</span> <span style="color: #000066;">action</span>=<span style="color: #ff0000;">"http://someusefulwebsite.com/login"</span><span style="color: #000000; font-weight: bold;">&gt;</span></a></span><br />
&nbsp; &nbsp; &nbsp;<span style="color: #009900;"><span style="color: #808080; font-style: italic;">&lt;!-- parametry i ich wartości --&gt;</span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><a href="http://december.com/html/4/element/input.html"><span style="color: #000000; font-weight: bold;">&lt;input</span></a> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">"hidden"</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">"user"</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">"qwerty"</span>/<span style="color: #000000; font-weight: bold;">&gt;</span></a></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><a href="http://december.com/html/4/element/input.html"><span style="color: #000000; font-weight: bold;">&lt;input</span></a> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">"hidden"</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">"pass"</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">"uiop"</span>/<span style="color: #000000; font-weight: bold;">&gt;</span></a></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/form&gt;</span></span></div>
</div>
</div>
<p>
Oczywiście nazwy i wartości parametrów (zapewne generowane dynamicznie po stronie serwera) zależą ściśle od tego, dokąd chcemy nasz wyrób formularzopodobny wysłać. Wszystkie je deklarujemy jednak jako <code>&lt;input type="hidden" /&gt;</code>, bo w założeniu użytkownik nie powinien ich (łatwo) zobaczyć. Ponadto, jeśli - tak jak wyżej - mówimy o loginie/haśle czy innych danych, które powinno się chronić przed niepowołanym dostępem, to powinniśmy jeszcze wysyłać razem z naszą stroną nagłówki HTTP zabraniające <em>cache</em>'owania:</p>
<div class="syntax_hilite">
<div id="code-22">
<div class="code"><span style="color:#FF9933; font-style:italic;">// HTTP/1.1</span><br />
Cache-Control: no-store, no-cache, must-revalidate</div>
</div>
</div>
<p></p>
<div class="syntax_hilite">
<div id="code-23">
<div class="code"><span style="color:#FF9933; font-style:italic;">// HTTP/1.0</span><br />
Cache-Control: post-check=<span style="color:#800000;">0</span>, pre-check=<span style="color:#800000;">0</span><br />
Pragma: no-cache</div>
</div>
</div>
<p>
W końcu, skoro mamy już gotowy "formularz", to trzeba jeszcze zadbać o to, by wysłał się on sam natychmiast po załadowaniu strony przekierowującej. Do tego już trzeba wykorzystać skrypt uruchamiany w przeglądarce:</p>
<div class="syntax_hilite">
<div id="html-24">
<div class="html"><span style="color: #009900;"><a href="http://december.com/html/4/element/script.html"><span style="color: #000000; font-weight: bold;">&lt;script</span></a> <span style="color: #000066;">language</span>=<span style="color: #ff0000;">"javascript"</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">"text/javascript"</span><span style="color: #000000; font-weight: bold;">&gt;</span></a></span><br />
&nbsp; &nbsp; document.forms[0].submit();<br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/script&gt;</span></span></div>
</div>
</div>
<p>
Tak przygotowaną stronę możemy podlinkować pod nasz serwis. Jak widać trochę z tym zabawy, ale tak to jest, gdy chcemy zrobić coś niestandardowego :)</p>
]]></content:encoded>
			<wfw:commentRss>http://xion.org.pl/2009/09/19/przekierowanie-z-post-em/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
