Kadu i nowy system powiadomień w Ubuntu 9.04 — Jaunty Jackalope

Mark Shut­tleworth z Canonical jakiś czas temu pisał na swoim blogu na temat zamiaru wprowadzenia w Ubuntu 9.04 ujed­noliconych “dym­ków” aplikacji. Nowy sys­tem powiadomień nazywa się Notify-OSD (więcej można poczytać np. tu). Zasad­niczą rewolucją jest to, że na powiadomieniach nie może być wykonywana żadna akcja typu roz­poczęcie roz­mowy, uak­tyw­nienie programu czy coś takiego. Można jedynie sobie popatrzeć. Toczyła (i zresztą toczy się nadal) dys­kusja czy to dobry krok. Na pewno warte pochwalenia jest to, że następuje próba unifikacji powiadomień. Obec­nie mamy tak, że każda aplikacja powiadamia po swojemu, w dowol­nym miej­scu ekranu i z dowolną szatą graficzną.

Jedną z takich “opor­nych aplikacji” jest używane chyba przez każ­dego Kadu. Ktoś na forum nawet wrzucił im temat, ale deweloperzy nie są zbyt­nio zain­teresowani. Tłumaczyli to tym, że zapewne nie­bawem każda dys­trybucja linuk­sowa będzie miała swój sys­tem powiadomień i trzeba będzie dostosowywać Kadu do wszyst­kiego. Postanowiłem trochę “powęszyć w temacie”, pokom­binować i… udało się :-)

Chcecie mieć tak u siebie?

Jeżeli tak, to zarezer­wuj­cie sobie 10 min czasu i czytaj­cie poniżej receptę.

  1. W ter­minalu wpisujemy sudo apt-get install libnotify-bin
  2. Uak­tyw­niamy dwukrot­nym klik­nięciem moduł exec_notifyZarządcy modułów w Kadu.
  3. W Kon­figuracja Kadu -> Powiadomienia będziemy zaznaczać Wykonaj polecenie i odhaczać Dymki.
  4. W zakładce zdarzenie:
    • Nowa roz­mowa wpisujemy notify-send -u low -c im -i /usr/share/kadu/themes/icons/default/kadu/big_message.png "%n" "rozpoczął nową rozmowę"
    • Nowa wiadomość notify-send -u low -c im -i /usr/share/kadu/themes/icons/default/kadu/big_message.png "%n" "przesyła nową wiadomość"
    • Błąd połączenia notify-send -u low -c im -i /usr/share/kadu/themes/icons/default/kadu/dialog-warning.png Kadu "błąd połączenia"
    • Dostępny notify-send -u low -c im -i /usr/share/kadu/themes/icons/default/kadu/big_online.png "%n" "zmienił status na dostępny"
    • Zajęty notify-send -u low -c im -i /usr/share/kadu/themes/icons/default/kadu/big_busy.png "%n" "zmienił status na zajęty"
    • Ukryty notify-send -u low -c im -i /usr/share/kadu/themes/icons/default/kadu/big_invisible.png "%n" "zmienił status na ukryty"
    • Nie­do­stępny notify-send -u low -c im -i /usr/share/kadu/themes/icons/default/kadu/big_offline.png "%n" "zmienił status na niedostępny"
    • Przy­chodzący trans­fer notify-send -u low -c im -i /usr/share/kadu/themes/icons/default/kadu/kadu-transfer-receive.png "%n" "chce przesłać plik"
    • Trans­fer zakoń­czony notify-send -u low -c im -i /usr/share/kadu/themes/icons/default/kadu/kadu-transfer-receive.png "%n" "zakończył przesyłać plik"
  5. Nie zapominamy zatwier­dzić wszystkiego.

Garść uwag:

  • Ikony wykorzystujemy oryginalne z Kadu, u wszyst­kich powinny być w tym samym miejscu.
  • Od razu ostrzegam, że dwóch ostat­nich poleceń nie testowałem.
  • Polecenia wpisywane są trochę na wyrost z uwzgled­nieniem priorytetu (low) i kategorii powiadomienia (im) — więcej tutaj. Będzie rów­nież działało bez tych parametrów.
  • Jeżeli ktoś ma obiek­cje, że powiadomienie wyświetla się za wolno lub za szybko — może eks­perymen­tować z parametrem –t liczba_milisekund (zaj­rzeć do man notify-send).

To tyle na dzisiaj. Być może twórcy Kadu zrobią nam kiedyś porządny osobny moduł. Na razie pozostaje nam tylko ten sposób.


Nowy dysk :-]

Zmęczony ciągłym poszukiwaniem miej­sca na dysku twar­dym zdecydowałem się kupić sobie dysk zewnętrzny. Wybór padł na Western Digital My Book Essen­tial Edition o pojem­no­ści 1TB.  Zadecydowała marka firmy + przy­stępna cena 399 zł. Od razu zaznaczam, że nie jestem związany z żadnym producen­tem sprzętu ani nikt mi nie płacił za recen­zję. Sprzęt kupiłem za własne pieniądze i dlatego mogę swobod­nie pisać co myślę.

W pudełku mamy zasilacz sieciowy 100~240V z wymien­nymi wtycz­kami, kabel USB (ok. 1 m długo­ści) + dysk twardy 3,5 cala zamknięty w ładnej obudowie (fotki oglądać np. u producenta).

Po uruchomieniu w Win­dow­sie naszym oczom ukazuje się menu wyboru instalacji oprogramowania. Wśród dostęp­nych opcji mamy wykonanie kopii zapasowej softu na dysku. Zrobiłem to… a następ­nie sfor­matowałem cały dysk, bo domyślny sys­tem plików FAT32 wg mnie należało zmienić na NTFS. Pozostałe z dostęp­nych do instalacji aplikacji to demówki do wykonywania kopii zapasowych sys­temu. Nie instalowałem tego (bo i po co skoro na Linuk­sie nie będą działały? :-) )

W komen­tarzach dotyczących dysku znalazłem info, że pojem­ność tak naprawdę wynosi 935GB. Jest to prawda. Otwory wen­tylacyjne znaj­dują się u góry, z dołu i z tyłu. Na reklamach dysk stoi pionowo, ja wolałem jed­nak położyć go płasko. Dysk pracuje bar­dzo cicho. W porów­naniu z moim wysłużonym dys­kiem wewnętrz­nym to absolutna cisza :-D

Ubuntu nie ma żadnych problemów z odczytem i zapisem. U mnie pręd­kość zapisu wynosi ok 2,5–3.2 MB/s (stary, wysłużony Celeron 2.8 GHz + płyta główna Asus P4PE-X + dysk Szaj­sung ATA cholera wie jakiej pręd­ko­ści :-P ).

Stosując zasadę ograniczonego zaufania przez ok. miesiąc będę trzymał tam mało ważne rzeczy.

Na produkt mamy 2 lata gwarancji.

Póki co, mogę śmiało powiedzieć, że Taj­land­czycy zrobili kawał dobrego sprzętu :-)


3 wzorce projektowe w ok. 100 liniach kodu PHP

Ostat­nio sporo czytam na temat programowania obiek­towego. W nie­mal każ­dej książce, która wpadła mi w łapki, przy­kłady wzor­ców projek­towych podane są w języku Java. Wyjąt­kiem jest Programowanie obiek­towe w PHP 5 Hasina Haydera.

Do napisania postu skłoniły mnie pojawiające się gdzie­nie­gdzie narzekania programistów na PHP, że jakoby ten język to zabawka, że nie da się w nim tworzyć w pełni obiek­towego kodu itd. Dzisiaj zademon­struję działanie 3 wzor­ców projek­towych na raz (Strategia, Obser­wator, Łańcuch zobowiązań).

Chcemy zrobić coś takiego:

Mamy więc jeden obiekt, który zawiera w sobie dane na temat obiek­tów, które chce powiadamiać, że coś się u niego zmieniło. Tak działa typowy wzorzec obser­wator. Ja to jed­nak zmodyfikowałem tak, że pierw­szy obser­wator w łańcuchu otrzymuje infor­mację o zmianie stanu obiektu obser­wowanego. Jeżeli umie sobie poradzić z prze­kazanym komunikatem — reaguje. Jeżeli ta infor­macja go zbyt­nio nie interesuje — prze­kazuje następ­nemu obiek­towi w łańcuchu. Tak działa wzorzec łańcuch zobowiązań. Po co mi wzorzec strategia? Z czystego lenistwa :-) Po co pisać kilka rodzajów obser­watorów do testu, które reagują w inny spo­sób na komunikaty, skoro można implemen­tować inter­fejs reagujący na różne komunikaty. Jeżeli będę chciał testować inny rodzaj komunikatów to napiszę sobię nową implemen­tację inter­fejsu reagującego i tyle :-)

Bierzemy się więc do roboty. Naj­pierw tworzymy sobie 2 inter­fejsy. 1 dla wzorca obser­wator, drugi dla łańcucha zobowiązań.

interface Obserwujacy {
    public function powiadomienie($komunikat);
}

interface Lancuch {
    public function zareaguj($komunikat);
}

Następ­nie tworzymy sobie jakiś obiekt obserwowany:

class Obserwowany {

    private $obserwatorzy = array();
    private $komunikat;

    public function addObserwujacy(Obserwujacy $o) {
        $this->obserwatorzy[] = $o;
    }

    public function setKomunikat($k) {
        $this->komunikat = $k;
        $this->powiadamiaj();
    }

    private function powiadamiaj() {
        foreach ($this->obserwatorzy as $obserwator) {
            $obserwator->powiadomienie($this->komunikat);
        }
    }
}

Obiekt ma zaled­wie 3 metody. Pierw­sza dodaje kolej­nego obser­watora do listy, druga zmienia stan obiektu (wysyła komunikat wszyst­kim), trzecia dla każ­dego obser­watora wywołuje metodę powiadamiającą o zmianie stanu.

Następ­nie tworzymy klasę Obser­wator, która reaguje na wszyst­kie komunikaty.

class Obserwator implements Obserwujacy , Lancuch {

    protected $reagujNa; // implements ReagujNa
    protected $nazwa;
    protected $lancuch;

    public function __construct($nazwa, Lancuch $l) {
        $this->reagujNa = new ReagujNaWszystko();
        $this->nazwa = $nazwa;
        $this->lancuch = $l;
    }

    public function powiadomienie($komunikat) {
        $this->zareaguj($komunikat);
    }

    public function zareaguj($komunikat) {
        if ($this->reagujNa->reaguj($komunikat)) {
            echo '<strong>' . $this->nazwa . '</strong> otrzymal komunikat ' . $komunikat . ' i zareagowal.<br />';
        }
        else {
            $this->lancuch->zareaguj($komunikat);
        }
    }
}

Zmienna $reagujNa implemen­tuje inter­fejs ReagujNa, który stworzymy poniżej. Nie­stety w PHP nie da się wymusić określonego typu zmien­nej — w tym lep­sza jest Java. Jeżeli ktoś koniecz­nie chce, to może sobie spraw­dzać czy dana zmienna rzeczywi­ście implemen­tuje inter­fejs przed wywołaniem.

interface ReagujNa {
    public function reaguj($komunikat);
}

class ReagujNaWszystko implements ReagujNa {
    public function reaguj($komunikat) {
            return true;
    }
}

class ReagujNaLiterki implements ReagujNa {
    public function reaguj($komunikat) {
        if (is_string($komunikat)) {
            return true;
        }
        else {
            return false;
        }
    }
}

class ReagujNaNumerki implements ReagujNa {
    public function reaguj($komunikat) {
        if (is_numeric($komunikat)) {
            return true;
        }
        else {
            return false;
        }
    }
}

Mamy tutaj trzy klasy posiadające po jed­nej metodzie, które zwracają prawdę lub fałsz w zależ­no­ści od podanego parametru. Dalej wypadałoby wykorzystać te klasy zmieniając zachowanie obiektu Obserwator.

class ObserwatorLiterek extends Obserwator {
    public function __construct($nazwa, Lancuch $l) {
        parent::__construct($nazwa,$l);
        $this->reagujNa = new ReagujNaLiterki();
    }
}

class ObserwatorNumerkow extends Obserwator {
    public function __construct($nazwa, Lancuch $l) {
        parent::__construct($nazwa,$l);
        $this->reagujNa = new ReagujNaNumerki();
    }
}

Na koniec potrzebne jest nam jesz­cze ostat­nie ogniwo łańcucha, nazwane przeze mnie Limiter. Cokol­wiek limiter dostaje — wyrzuca na wyj­ściu i tyle.

class Limiter implements Lancuch {

    private $nazwa;

    public function __construct ($nazwa) {
        $this->nazwa = $nazwa;
    }
    public function zareaguj($komunikat) {
        echo '<strong>Limiter ' . $this->nazwa . '</strong> otrzymal komunikat ' . $komunikat . '<br />';
    }
}

Pora to wszystko prze­testować. Tworzymy obiekt obserwowany,

$obserwowany = new Obserwowany();

a następ­nie 4 ciągi obser­watorów. Tworzymy go od końca. Coś jak Matrioszki.

// ciag 1
$limiter1 = new Limiter('ciagu 1');
$obserwatorWszystkiego = new Obserwator('Obserwator Wszystkiego ciagu 1',$limiter1);
$obserwowany->addObserwujacy($obserwatorWszystkiego);
// ciag 2
$limiter2 = new Limiter('ciagu 2');
$obserwatorLiterek = new ObserwatorLiterek('Obserwator Literek ciagu 2',$limiter2);
$obserwowany->addObserwujacy($obserwatorLiterek);
// ciag 3
$limiter3 = new Limiter('ciagu 3');
$obserwatorNumerkow = new ObserwatorNumerkow('Obserwator Numerkow ciagu 3',$limiter3);
$obserwowany->addObserwujacy($obserwatorNumerkow);
// ciag 4
$limiter4 = new Limiter('ciagu 4');
$obsAll = new Obserwator('Obserwator Wszystkiego ciagu 4',$limiter4);
$obsNum = new ObserwatorNumerkow('Obserwator Numerkow ciagu 4',$obsAll);
$obsLit = new ObserwatorLiterek('Obserwator Literek ciagu 4',$obsNum);
$obserwowany->addObserwujacy($obsLit);

Ostat­nim krokiem jest spraw­dzenie jak to teraz działa.

$obserwowany->setKomunikat('abc');
echo '----------------------------------';
$obserwowany->setKomunikat(123);

Wynik:
Obserwator Wszystkiego ciagu 1 otrzymal komunikat abc i zareagowal.
Obserwator Literek ciagu 2 otrzymal komunikat abc i zareagowal.
Limiter ciagu 3 otrzymal komunikat abc
Obserwator Literek ciagu 4 otrzymal komunikat abc i zareagowal.
----------------------------------
Obserwator Wszystkiego ciagu 1 otrzymal komunikat 123 i zareagowal.
Limiter ciagu 2 otrzymal komunikat 123
Obserwator Numerkow ciagu 3 otrzymal komunikat 123 i zareagowal.
Obserwator Numerkow ciagu 4 otrzymal komunikat 123 i zareagowal.

A teraz wyjaśnienie jak to wszystko działa:

Ciąg 1 zawiera w sobie tylko obser­watora wszyst­kiego i limiter. Obser­wator każdy komunikat trak­tuje jako infor­mację dla siebie i nie prze­kazuje dalej do limitera (przez co komunikat nigdy do niego nie dojdzie).

Ciąg 2 ma tylko obser­watora literek i limiter. Na pierw­szy, słowny komunikat zareagował. Na komunikat zawierający liczbę nie zareagował i prze­kazał dalej do limitera.

Ciąg 3 ma w zamian obser­watora numer­ków i limiter. Zachował się dokład­nie odwrot­nie od poprzedniego.

Ciąg 4 ma kolejno obser­watorów literek, numer­ków, wszyst­kiego i limiter. Teraz dokład­nie widać jak to działa. Jeżeli dany obser­wator nie znalazł infor­macji przy­dat­nej dla siebie — po prostu prze­kazał następ­nemu obser­watorowi w ciągu. Warto zauważyć, że obser­wator wszyst­kiego i limiter w tym przy­padku nigdy nie zareaguje, gdyż komunikat zostanie roz­wiązany zanim do niego dojdzie.

Dla chęt­nych zamiesz­czam plik wzorce.php. Zachęcam do eks­perymen­tów i ewen­tual­nej prze­budowy obser­watorów tak, aby reagowały na kon­kretne słowa lub liczby.


Jeszcze żyję, spokojnie :-)

Ostat­nio nie miałem w ogóle czasu pisać. Blogasek trochę zdążył się zakurzyć. Od ostat­niego miesiąca sporo się wydarzyło. Zmieniłem sobie stan cywilny. Aktual­nie jestem w trak­cie prze­prowadzki. Nie ma nawet kiedy porząd­nie siąść za klawiaturę kompa, a co dopiero coś sen­sow­nego napisać…

Zamiast pisać głupoty przejdę do kon­kretów. Nigdy nie przy­pusz­czałem, że organizacja ślubu i wesela aż tak wysysa życie z człowieka. Na każ­dym kroku telefony, umawianie się, spisywanie umów, zadat­ków, ter­minów i innych takich bzdur. Do tego jesz­cze dochodzą “ran­dom events”, czyli np. na 2 dni przed ślubem dzwoni do ciebie kierowca limuzyny i mówi, że maska limuzyny na skutek spo­tkania z drzewem skróciła się o 50 cm.

Następna kwestia to ceny, które ostat­nio poszybowały w górę. Dobrze, że naj­waż­niej­sze rzeczy związane z weselem były załatwiane na początku 2008 roku. Przed kryzysem, przed grypą i czym tam jesz­cze mamy w 2009 roku. Ceny usług obowiązywały oczywi­ście stare.

Obiecałem laurkę szefowi restauracji, w której odbyła się impreza. Przyjęcie weselne odbyło się w Restauracji “Club 99″ w sali tzw. afrykań­skiej na terenie Międzynarodowych Tar­gów Katowic­kich. Jedzenie smaczne, uroz­maicone (czę­ści nawet nie umiem nazwać :-) ). Szefostwo zna się na organizacji tego typu imprez. Podają roz­piskę przy­kładowego menu i roz­kład tego menu w czasie. Wszystko jest tak zaplanowane, że mamy jesz­cze miej­sce na główne posiłki. Mogą zor­ganizować ciasto i tort. Jeżeli mamy swoje — proszę bar­dzo. Żadnych opłat ukrytych typu “kor­kowe, prądowe, wodowe, kablowe, godzinowe” i inne takie. Płacimy od łebka ustaloną kwotę. Zabawa trwa do ostat­niego gościa bez limitu czasu. Są tak pewni jako­ści swoich usług, że po imprezie odbytej w sobotę płacimy dopiero w poniedziałek. Faj­nie, co? (z czymś takim się jesz­cze nie spo­tkałem). Szefostwo cały czas jest na miej­scu jakby co. Żeby nie było samego lukru napiszę jesz­cze, że obsługa od godz. 2 w nocy nieco przy­stopowała. Część pustych naczyń leżało sobie na stole. Z drugiej strony, to nie roboty obsługują. Ludzie mają prawo być nieco zmęczeni, nieprawdaż?

Z zadań na naj­bliż­szy czas wyznaczyłem sobie zain­stalować naj­now­sze Ubuntu, zobaczyć w kinie Ter­minatora :-P oraz jak zawsze pojawić się na kolej­nej edycji Spodka 2.0 9 czerwca.


Reklamowe gówno pod płaszczykiem artykułu

Jest mocny tytuł, będzie mocna treść. Nie wiem dlaczego artykułu o Star­bucks na Dziennik.pl nie oznaczono jako artykuł spon­sorowany. Może zapłacono odpowied­nio dużo pani Renacie i Oldze (oraz bliżej nie­ziden­tyfikowanym “ksk” i “kas” — zapewne od kasowania kasy).

Artykuł mamy pisany dokład­nie w stylu “noc­nych kolejek” przed salonami ze sprzedażą iPhone: “kup pan kawę/iPhone, będziesz należał do amerykań­skiej elyty” (nażryj się w jesz­cze w McDonal­dzie i zostań bez­mózgim otyłym kon­sumen­tem). Fakt, że coś jest reklamowane w amerykań­skich serialach nie oznacza jesz­cze, że jest to sym­bol luksusu.

15-letnia gim­nazjalistka Karolina chce należeć do śmietanki towarzyskiej. Mam tylko nadzieję, że zamiast pisać testu gim­nazjal­nego wczoraj i dzisiaj nie prze­siedziała na kawie. Poza tym, kto cię dziecko nauczył pić kawę? Jej kolega wstaje wcześniej by pochodzić po szkole z tek­turowym kub­kiem. Pozostawię bez komen­tarza.

20-letni student nie musi wyjeż­dżać za granicę by napić się kawy. Mam nadzieję, że po chleb nie jeź­dzi za daleko.

Przy­pad­ków w języku pol­skim jest tylko 7. Na potrzeby “lansu” to stanow­czo za mało. Poza tym praw­dziwi “lan­sjerzy” powinni posługiwać się językiem elyty — angiel­skim. Widzieli­ście jakiegoś Amerykanina gadającego po polsku?

Może postawią przy wej­ściu jakiegoś selek­cjonującego “miśka” — będzie chociaż namiastka tego, czego nie mogą mieć wszyscy. Bo co to za elita, którą może zostać każdy?

Inter­nauci moim zdaniem stanęli na wysoko­ści zadania. Nie zostawili na artykule suchej nitki. To dobrze, że są jesz­cze ludzie mający zdol­ność samodziel­nego myślenia. Polecam rów­nież dys­kusję na Wykop.pl.

Na nie­szczę­ście artykuł osiągnął zamierzony cel — wywołał hałas.


Powstaje wolny Last.fm!

Jak podaje Linux News, powstaje open source’owa wer­sja Last.fm nazwana Libre.fm. To dobra wiadomość dla miłośników wol­nego oprogramowania (nie tych w znaczeniu powol­no­ści działania, hehe).

Póki co, mamy do czynienia z wczesną wer­sją alpha. Na dzień dzisiej­szy Libre.fm liczy sobie nieco ponad 1500 użyt­kow­ników. Samo zmuszenie do współ­pracy programów scrob­blujących (w Libre gob­blujących) polega na cham­skim prze­kierowaniu w /etc/hosts adresu post.audioscrobbler.com na 89.16.177.55 (wtyczka Last.fm w odtwarzaczu Ban­shee daje się nabrać — sprawdzałem).

Aktual­nie nie możemy za dużo zrobić w ser­wisie. Ot, prze­syłać dane nt. prze­słuchanych utworów. Warty wzmianki jest pomysł zmiany podej­ścia do określania ulubionych artystów. Miałoby to być liczone na pod­stawie czasu słuchania danego artysty a nie liczby prze­słuchanych utworów.

Pozostają kwestie roz­róż­niania róż­nych artystów o tej samej nazwie oraz porząd­kowania “baj­zlu” w nazew­nic­twie utworów. Wg mnie twórcy powinni rów­nież powrócić do roz­ważenia momentu zakwalifikowania utworu jako prze­słuchanego. Kiedyś wyglądało to ina­czej (pisałem o tym), a teraz musimy prze­słuchać cały utwór.

Powstała nawet grupa zrzeszająca entuzjastów Libre.fm na Last.fm (jesz­cze nie zlikwidowana? :-P )


Literowka.pl — lekka przesada?

Czego to ludzie nie wymyślą. Dzisiaj przy próbie wej­ścia na Wykop.pl wpisałem nie dość dokład­nie adres strony (wykp.pl zdaje się) i zostałem prze­rzucony na stronę literowka.pl. Nigdy bym nie pomyślał, że cel ist­nienia witryny można oprzeć na czyichś błędach ładnie po angiel­sku zwanych typos — typographical errors. Co prawda już od dawna ist­nieje witryna osiolki.net, ale dotyczy raczej (nie)świadomych błędów przy wykonaniu stron internetowych.

Co mnie zaskoczyło? Cham­stwo. Na wstępie zostałem przy­rów­nany m.in. do “[…] nie­do­kład­nych blon­dynek z IQ na poziomie komara, uzależ­nionych od fil­mów porno i mastur­bacji […]”. To oczywi­ście potrak­towałem jako moc­niej­szy żart. Dalej prze­konałem się, że admini strony raczej swoje “motto” biorą na serio. Na cham­skie komen­tarze odpowiadają cham­sko zamiast po prostu wywalać takie wypowiedzi.

Przy próbie opusz­czenia strony włącza się javascrip­towy skrypt, który każe nam wpisywać różne wyrazy w celu nauki pisania na klawiaturze. Po wpisaniu oczywi­ście musimy wpisać następny itd. bez końca. Naj­lep­szym spo­sobem jest ctrl+alt+del / monitor sys­temu i ręczne wyłączenie przeglądarki.

Co mnie zastanawia? Koszty. Strona praw­dopodob­nie generuje duży ruch. Dopóki ludzie używają klawiatur, dopóty będą sadzić błędy. Na stronie jest co prawda reklama, ale wąt­pie, że ktoś w nią klika będąc w drodze do nie­for­tun­nie wpisanej witryny. Administratorzy musieli wykupić sporo domen z błędami. Ciekawi mnie “materiał porów­naw­czy” jakie błędy ludzie naj­czę­ściej popeł­niają. Odwiedzający trafiają na Literówkę wpisując m.in. Onet, Wykop, Wrzuta, Nasza-Klasa, a nawet Google. Ciekawe czy do każ­dej z tych witryn ist­nieje kilka warian­tów błędów czy tylko jeden naj­popular­niej­szy :-)

Pod­sumowując, nie polecam wchodzić na literowka.pl, bo trudno się z niej wydostać :-)


Popraw hurtem spacje na _ w DOS[!]

Ostat­nio nie mam za dużo czasu na pisanie (praca i studia podyplomowe). Mam za to mały rarytasek dla “dosowych old­schoolow­ców”. Na potrzeby ułatwienia sobie pracy napisałem mały skrypt w DOS (czy raczej w tym co jest w zamian w Win XP). Wiedzę czer­pałem oczywi­ście z Google i polecenia cośtam /?

Co to robi? Zamienia nazwy wszyst­kich pod­katalogów zastępując spacje pod­kreśl­nikami _. Dodat­kowo pomija podane przez nas pod­katalogi. Miej­cie świadomość, że skrypt należy dostosować do swoich wymagań. To co tu jest działa u mnie, a u Was niekoniecznie.

Zawar­tość pliku szukaj_spacji.bat:

@ECHO OFF
CLS
ECHO. Tworzenie listy plikow z podkatalogami...

c:
CD \katalog

:spacje
REM pobierz liste katalogow pomijajac te podane w nawiasach
DIR /AD /B /S | FINDSTR /V "skrypty rozdzielone" > katalogi.txt

REM sprawdzam czy sa spacje w nazwach
FOR /F "delims=" %%k IN (katalogi.txt) DO (
ECHO %%k|FINDSTR /R /C:" ">nul
IF NOT ERRORLEVEL 1 CALL .\skrypty\popraw_spacje.bat "%%~pk%%~nk"&GOTO spacje
)

ERASE c:\katalog\katalogi.txt

Zawar­tość pliku popraw_spacje.bat:

@ECHO OFF

IF (%1) == () (
ECHO Mowilem nie uruchamiac samemu!
PAUSE
GOTO :EOF
)

FOR /F "tokens=1*" %%a IN (%1) DO rename %1 "%%a_%%b"

Jak to działa:

  1. kasuj wyświetlanie komunikatów,
  2. czyść ekran,
  3. wyświetl komunikat na ekranie,
  4. przejdź do miej­sca, w którym będą szukane pod­katalogi do zmiany nazwy,
  5. utworzórz etykietę spacje, do której możemy wykonać póź­niej skok,
  6. poleceniem DIR wyświetlamy nazwy pod­katalogów w for­mie uprosz­czonej (bez podawania ich wiel­ko­ści itp.), następ­nie jedziemy na “oszukanej paj­pie” Billa G.: DIR prze­kazuje swoje wyj­ście na wej­ście FINDSTR z parametrem /V, dzięki temu zapisuje do pliku katalogi.txt nazwy wszyst­kich pod­katalogów oprócz tych podanych w cudzysłowach (FINDSTR nie jest potrzebny jeżeli nie chcemy pomijać jakichś podkatalogów),
  7. pętla FOR z parametrem delims wymusza iteracje wraz z koń­cem linii, a nie tak jak domyśl­nie każ­dej spacji,
  8. znowu pipe: ECHO prze­kazuje swoje wyj­ście na wej­ście FINDSTR, które tym razem szuka spacji w nazwie; jeżeli coś znaj­dzie i tak wywalane jest do nul (chodzi nam o wygenerowanie ERRORLEVEL czy znalazł spacje czy nie),
  9. jeżeli znalazł spacje (działa jedynie knif NOT ERRORLEVEL 1), to wywołuje plik popraw_spacje.bat prze­kazując mu jako parametr ścieżkę dostępu i nazwę katalogu do zmiany nazwy,
  10. po poprawieniu spacji wymuszany jest skok do kolej­nego wygenerowania listy katalogów i tak aż do poprawienia ostat­niej spacji w drzewie katalogów,
  11. kasuje plik txt z nazwami katalogów

Co robi wywoływany plik popraw_spacje.bat:

  1. Spraw­dza czy są podane jakieś argumenty, jeżeli nie, to wyświetla komunikat i za pomocą GOTO :EOF skacze na koniec pliku nie robiąc nic.
  2. Podany ciąg znaków zostaje roz­dzielony na 2 kawałki w miej­scu spacji, którye “skleja” znakiem _.

Wnioski z całej tej zabawy:

  • DOS jest strasz­nie toporny. Rolę funk­cji naj­lepiej speł­niają osobne pliki bat, które coś tam wykonują i wracają w miej­sce wywołania. Stosując etykiety i GOTO często narażasz się na nie­skoń­czone pętle (a wtedy pomaga tylko CTRL + C).
  • Na każ­dym kroku trzeba stosować knify wynalezione metodą prób i błędów lub żmud­nego prze­szukiwania forów inter­netowych. Czy Bill G. od początku tak to sobie wykombinował?
  • Dlaczego “oszukana pajpa”? W sys­temach unik­sopodob­nych kolejne wier­sze z wyj­ścia prze­kazywane na wej­ście następ­nego polecenia uruchamiają rów­noległy proces. W DOS wszyst­kie wier­sze są naj­pierw zapisywane do pliku tym­czasowego, a dopiero potem prze­kazywane do następ­nego polecenia.
  • Nigdy więcej DOSa :-)

Przekierowanie wyjścia z terminala do… innego terminala

Ostat­nio na zajęciach z Uniksa mieliśmy różne mniej lub bar­dziej przy­datne rzeczy z powłoki Bash. Z tych mniej przy­dat­nych można zaliczyć pisanie w jed­nym ter­minalu i pokazywanie kopii napisów w drugim. Niby prosta rzecz, a na Win­dow­sie nie da rady. Oto co musimy zrobić:

  1. Odpalić 2 terminale.
  2. W każ­dym z nich wpisać polecenie ps.
  3. Tam, gdzie wyświetliło pts/1 wpisać cat > /dev/pts/2 , a tam gdzie pts/2 cat > /dev/pts/1.

Od tej pory wszystko to co wpiszemy w 1 ter­minalu i zatwier­dzimy Enterem będzie wyświetlało się na drugim i vice versa. Prawda, że głupie? :-) Gdy nam się znudzi naciskamy Ctrl + C. Wykładowca wspominał, że da się takie numery robić zdal­nie. Aż strach pomyśleć gdyby w trak­cie pracy ni stąd, ni zowąd ukazało nam się na ekranie fol­low the white rab­bit. :-)


Do kawalerii wstąpić chciałem… ale wolałem do rezerwy :-)

Korzystając z ostat­nich dni zwol­nienia lekar­skiego postanowiłem for­mal­nie załatwić sprawę prze­niesienia do rezerwy. Pani w WKU ładnie wbiła pieczątkę i poczyniła odpowiedni wpis do książeczki wojskowej.

W WKU pustki. Żadnych wystraszonych poborowych… Co oni bez nas bidoków poczną? :-P Tłumu chęt­nych na żołnierzy zawodowych rów­nież nie zanotowałem.

Jakoś specjal­nie nie unikałem woj­ska. W czasie rekrutacji na studia jedynie nie miałem pew­no­ści czy zostanę przyjęty, dlatego trzeba było sobie załatwić studium policealne. Pochodziłem 2 tyg. września i tyle. Od razu nasuwa się pytanie, co stanie się ze szkołami policeal­nymi? Prak­tycz­nie wszyscy kamuflowali się tam przed woj­skiem. W czę­ści prywat­nych uczelni wyż­szych zapewne też.

Znajomi, którzy byli w woj­sku trochę pod­śmiewują się z tych, którzy nie byli. “Idź do woj­ska, życia się nauczysz, zostaniesz męż­czyzną”. Potem taki “męż­czyzna” zakłada rodzinę, zostaje jej głową (dowódcą) i tresuje kijem żonę i dzieci. Bo w woj­sku nauczyli się tylko krzyczeć na innych i wydawać polecenia. Takie jest moje zdanie o woj­sku i tyle.

Na YouTube polecam wpisać hasło kawaleria powietrzna. W tym dokumen­cie można sobie pooglądać jak wygląda życie w woj­sku. Mnie po obej­rzeniu się ode­chciało. A Wam?

Pozdrawiam wszyst­kich rezer­wistów :-D