Weź mi zrób procesor tekstu cz. 2 / 2

Zgod­nie z zapowiedzią, dzisiaj będziemy implemen­tować moduły, które coś z podanym tek­stem robią. Do tego celu głów­nie używać będziemy wyrażeń regularnych.

1. Na pierw­szy ogień pój­dzie poprawiacz spacji. Jak często trafiają się wam dokumenty for­matowane za pomocą 20 spacji? Za pomocą tego cuda wywalimy wszystko co ma powyżej dwóch za koleją.

class SpaceFixer implements TextJob {
   public function process($string) {
      $string = trim($string);
      $string = preg_replace('/\s{2,}/' , ' ' , $string);
      return $string;
   }
}

Zasada działania prosta: naj­pierw wyrzuć wszel­kie spacje przed i za strin­giem, a następ­nie poszukaj dwie lub więcej spacji za koleją i zamień je na pojedyncze.

2. Teraz coś sporo trud­niej­szego: dodawacz twar­dych spacji do spój­ników. Zasada działania taka: znajdź mi spację, pojedyn­czy znak, znowu spację i jeden lub więcej znaków (np. jedzenie_i_picie).

class AddNbsps implements TextJob {
   public function process($string) {
      $output = ''; // inicjalizujemy pustą zmienną, zostało mi to po Javie
      foreach ($this->splitStringsByTagChar($string) as $split) {
         $output .= substr($split , 0 , 1) == '<' ? $split : $this->fixLine($split);
      }
      return $output;
   }
   private function splitStringsByTagChar($string) {
      return preg_split('/(<.+?>)/', $string, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
   }
   private function fixLine($line) {
      return preg_replace('/(\s{1}[-\("\w]{1})\s{1}([-\)"\w]+)/' , '$1&nbsp;$2' , $line);
   }
}

Jak widać trochę się pokom­plikowało. Po co nam te dodat­kowe funk­cje? Ano po to żeby nie popsuły się nasze HTM­Lowe tagi. Funk­cja splitStringsByTagChar nie­zachłan­nie szuka czegoś co przy­pomina sekwen­cję <coś> i szat­kuje nam ciąg do tablicy.

Operator trój­ar­gumen­towy po foreach spraw­dza czy element tablicy zaczyna się od znaku < . Jeżeli tak, to zostawia go w spo­koju, a jak nie, to kieruje do prze­róbki do fixLine. Można zauważyć, że oprócz klasy znaków \w (alfanumeryczne i _) dodałem rów­nież ” ( ). Po przeanalizowaniu kilku tek­stów stwier­dziłem, że tak lepiej działa (a mogłoby pew­nie lepiej gdybym poświęcił na to jesz­cze trochę czasu).

3. Wyszukiwacz linków.

class AddLinks implements TextJob {
   public function process($string) {
      return preg_replace('`(?<!href="|src=")((https?://|www\.)[\w{1,}./?=#&]+)`i' , '<a href="$1">$1</a>' , $string);
   }
}

Tutaj można zauważyć dziwną kon­struk­cję (?<! Jest to aser­cja wsteczna. Działa tak: znajdź mi ciąg znaków zaczynający się od http:// lub www., a jak znaj­dziesz, to sprawdź czy czasami przed znalezionym ciągiem nie ma kon­struk­cji z aser­cji. Po co to? Do wykrycia, czy link znaj­duje się już w tagu <a href=” lub <img src=”, a więc czy nie popsujemy kodu html. Do tego mógł­bym rów­nie dobrze użyć funk­cji szat­kującej z poprzed­niego modułu, ale chciałem żeby było trud­niej :-)

Jak tego wszyst­kiego używać? Dosyć prosto: w atrybutach podajemy moduły, które nas interesują i podajemy tekst:

$jakisTekst = 'Ala ma kota, a kot ma HIV';
$txtProcesser = TextProcesser::getInstance(array('SpaceFixer','AddNbsps','AddLinks'));
$processedTxt = $txtProcesser->processJobs($jakisTekst);

Tekst będzie prze­twarzany w podanej kolej­no­ści. Fajne, co?
[czeka na oklaski]


Weź mi zrób procesor tekstu cz. 1 / 2

Dzisiaj będzie wpis o ułatwianiu życia użyt­kow­nikom paneli administracyj­nych. Chodzi tutaj o sytuację, gdy użyt­kow­nik naszej strony wkleja byle jak jakiś tekst z Worda do TinyMCE, a następ­nie dziwi się, że na stronie wychodzi kaszana.

Parę rzeczy da się poprawić z automatu poprzez prze­tworzenie przez procesor tek­stu. Skąd taki wziąć? A napiszemy sobie sami.

W tym wpisie stworzymy “rusz­towanie”, a w następ­nej czę­ści parę modułów robiących jakieś kon­kretne rzeczy.

Pierw­sze czego potrzebujemy to inter­fejs pojedyn­czego modułu prze­twarzającego tekst. Będzie banal­nie prosty: metoda process pobiera stringa i zwraca prze­tworzonego stringa.

interface TextJob {
   public function process($string);
}

Dalej piszemy klasę procesora tekstu.

class TextProcesser {
   private $jobsToDo = array();
   private function __construct() {}
   public static function getInstance($params = array()) {
      $textProcesser = new TextProcesser();
      foreach ($params as $param) {
         try {
            if (!class_exists($param)) throw new Exception('Klasa ' . $param . ' nie istnieje!');
            $param = new $param;
            if (!($param instanceof TextJob)) throw new Exception('Klasa ' . $param . ' nie obsluguje interfejsu TextJob!');
         } catch (Exception $e) {
            echo $e->getMessage();
            die();
         }
         $textProcesser->addJob($param);
      }
      return $textProcesser;
   }

   private function addJob(TextJob $tj) {
      $this->jobsToDo[] = $tj;
   }

   public function processJobs($string) {
      foreach ($this->jobsToDo as $job) {
         $string = $job->process($string);
      }
      return $string;
   }
}

Po kolei:

  1. Zmienna $jobsToDo trzyma tablicę prac do wykonania.
  2. Klasy nie będziemy tworzyć poprzez kon­struk­tor, dlatego został zmieniony na prywatny.
  3. Statyczna metoda getInstance tworzy obiekt procesora i przy okazji spraw­dza czy podana tablica $params zawiera ist­niejące klasy i czy implemen­tują one inter­fejs TextJob.
  4. Metoda addJob dodaje kolejną pracę do wykonania do kolejki.
  5. processJobs wykonuje wła­ściwą robotę — pobiera stringa do prze­tworzenia i w kolej­no­ści dodania prac prze­twarza go.

Co mamy do tej pory? Klasę, do której możemy dodawać tyle kon­kret­nych zadań ile chcemy, o ile tylko implemen­tują inter­fejs TextJob. W następ­nej czę­ści będziemy wyrzucać zbędne spacje, dodawać twarde spacje i szukać linków.


Całodzienna walka z wirusem Bagle

Wczoraj miałem okazję maj­strować przy lap­topie z ciekawymi objawami: po uruchomieniu jakiegoś exe Win­dows XP sam się zrestar­tował, po czym prze­stał działać Avast.

Próby odpalenia przez tryb awaryjny powodowały błysk nie­bieskiego ekranu z błędem i natych­miastowy restart. Przy­wrócić sys­tem rów­nież się nie dało.

To, że nie działał Avast to jesz­cze nic. Nawet nie dało się uruchomić programów do zbierania logów typu Com­boFix czy Gmer.

Postanowiłem, że spróbuję szkod­nika podejść z zewnątrz poprzez wypalenie na CD-RW jakiegoś antywirusa typu Live CD. Wybór padł na G Data AntiVirus. Dzięki niemu dowiedziałem się, że mam do czynienia z nie­bez­piecz­nym stworem: wirusem Bagle (dokładny typ Win32.Bagle.SUQ@mm). G Data wpraw­dzie usunął 64 miej­sca, w których wirus zdążył się zreplikować, problem jed­nak ist­niał nadal.

Idąc tą instruk­cją utknąłem nie­stety przy próbie przy­wrócenia trybu awaryj­nego. SafeBoot­KeyRepair nie umiał sobie poradzić. Szukając czegoś innego natknąłem się na Findy Kill — program dedykowany do usuwania Bagla. Program poradził sobie z infek­cją błyskawicz­nie (wykrył jesz­cze ponad 50 miejsc zadomowienia wirusa) i nawet przy­wrócił tryb awaryjny.

Rady na przyszłość?

  • nie ściągaj podej­rzanych programików z netu — to chyba oczywiste, ale widać ciągle nie dociera
  • odłącz kabel z netu w zain­fekowanym kom­pie jeżeli możesz — zapewne pusz­cza sporo spamu lub co gor­sza robi jako zombie
  • naj­lepiej nie używaj Win­dowsa — tu oczywi­ście żartuję ;-)

Śpiechu po delegacji w Warszawie

Dzisiaj wpis typu “flaki z olejem”. Żądnych kolej­nej dawki wiedzy programistycz­nej muszę ode­słać nie­stety z kwitkiem.

Od 2 do 7 lutego byłem sobie w War­szawie. Wysłano mnie na szkolenia trener­skie w ramach Programu Roz­woju Bibliotek. Biblioteki wojewódz­kie (a więc i Biblioteka Śląska) zobowiązały się do prze­szkolenia bibliotekarzy z bibliotek regionu, które otrzymają sprzęt kom­puterowy (prezen­tacja tutaj). Będę miał przyjem­ność brać udział w szkoleniach tych osób.

Jeżeli ktoś nie za bar­dzo wie o co chodzi to wyjaśniam kąśliwie w skrócie: Fun­dacja Melindy i Billa Gatesa dys­ponująca ułam­kiem sumy “skoszonej” od uzależ­nionej od Microsoftu pol­skiej administracji publicz­nej, “dobroczyn­nie” zdecydowała się podarować naj­bied­niej­szym bibliotekom w Pol­sce sprzęt, oprogramowanie (Win 7 + Office 2007) i dar­mowy inter­net przez kilka lat. Dodat­kowo, dla nie­po­znaki, szkolenia bibliotekarzy prze­prowadzą trenerzy prze­szkoleni w używaniu produk­tów Microsoftu (m.in. ja :-) ).

Warto by zastanowić się ile sprzętu dałoby się kupić za pieniądze wywalane na licen­cje za MS Win­dows i Office. W końcu utrwaliło się wszyst­kim, że sprzęt + oprogramowanie = PC + Win­dows. Mam rację?

Teraz przejdę do wrażeń z pobytu w Warszawie:

  1. Dworzec Cen­tralny — sporo więk­szy niż w Katowicach. W lep­szym stanie tech­nicz­nym (działające ruchome schody!), ale za to bar­dziej śmier­dzący. No cóż, nie można mieć wszystkiego…
  2. Chod­niki zdecydowanie słabiej odśnieżone niż w Katowicach. Czyżby War­szawiacy poruszali się wyłącz­nie samochodami?
  3. Liczba psich kup na metr chod­nika w cen­trum może śmiało kon­kurować z liczbą w Katowicach (zwanych czasem “Kupowicami”).
  4. Muzeum Woj­ska Pol­skiego — old fashion muzeum. W każ­dym pomiesz­czeniu siedzący na stołecz­kach cer­berzy patrzący na każdy ruch zwiedzających. Naj­lepiej byłoby zamknąć muzeum, wtedy muzeal­nicy spo­koj­nie mogliby czekać na koniec dniówki nieniepokojeni.
  5. Muzeum Powstania War­szaw­skiego — cał­kowite prze­ci­wień­stwo poprzed­niego. Wszyst­kiego możesz dotknąć, posłuchać i zobaczyć parę fil­mów. Pomysł przyj­ścia tam w dzień wolny (nie­dziela) był cał­kowicie chybiony. Czułem się jak w super­mar­kecie: masa ludzi z dziećmi zbierającymi kar­teczki z datami.

Na koniec mam dla Was specjalny bonus z muzeum: MS Fail, czyli kolejny powód, dla którego Win­dows to sys­tem, któremu nie można zaufać.


Pierwszy projekt WWW zrealizowany :-)

Po długiej prze­rwie Śpiechu znowu nadaje… Mam nadzieję, że tym razem czę­ściej. Zwłoka wynikła z tego, że ponad miesiąc po godzinach pracy w bibliotece pracowałem nad projek­tem dla WRiTV Uniwer­sytetu Śląskiego.

Efekt można zobaczyć tutaj.

Można powiedzieć, że do tego typu roboty przy­gotowywałem się 2 lata. Co składa się na cało­kształt strony?

  • 3300 linii kodu PHP,
  • 600 linii kodu HTML,
  • 380 linii kodu CSS,
  • 80 linii kodu JavaScript

Zastosowane narzędzia “dobajerowujące”:

  • jQuery,
  • jQuery Uploadify,
  • jQuery Light­box,
  • Tiny MCE

Strona została napisana “od zera”, tzn. wszystko co składa się na stronę to mój autor­ski projekt. Mamy tutaj np.:

  • autor­ska galeria (tworzy miniaturki zadanego roz­miaru, skaluje zdjęcia, dodaje do bazy danych),
  • autor­ska captcha,
  • ajak­sowy uploader plików z nor­malizacją nazw,
  • procesor tek­stu dodający twarde spacje za spójnikami,
  • sys­tem new­sów dynamicz­nych (tzn. pobieranych z bazy),
  • sys­tem stron statycz­nych (tzn. z pliku),
  • obsługa “ładnych lin­ków” za pomocą mod_rewrite,
  • moż­liwość edycji tego wszyst­kiego w miarę prosty sposób

Jed­nocześnie odcinam się od strony graficz­nej. Wykonała ją moja żona. Bez bicia przy­znaję się, że nie znam się na tym. Ja tylko dostałem obrazek w pdf i miałem prze­łożyć go na XHTML/CSS. Pod róż­nymi prze­glądar­kami trochę kuleje wygląd, ale ciągle nad tym pracuję :-)

Ogól­nie mówiąc, uniwer­sytet dostał “dużo za nie­dużo”. Nie powiem ile ich to kosz­towało, bo zostanę posądzony za “psucie rynku” (ta uwaga w kon­tek­ście ostat­niego wykopu).

Update 25.01.2010: Uznałem, że RSS warty był zaim­plemen­towania. Tym spo­sobem dochodzi do witryny jesz­cze autor­ski generator RSS ;-)


Informatyczne lektury do poduchy

Od ponad roku wszel­kimi spo­sobami (Allegro, biblioteka) staram się zdobywać książki z serii Head First. Muszę przy­znać, że to chyba naj­lep­sza seria książek infor­matycz­nych jaka powstała. W żartobliwy spo­sób, prawie od zera jesteśmy stop­niowo wprowadzani w dane zagad­nienie. Czytając, podążamy praw­dopodobną (złą) ścieżką wtajem­niczenia, a następ­nie otrzymujemy wytłumaczenie dlaczego jest zła :-) Do znudzenia czasem wał­kuje się ten sam temat z róż­nych stron. Mal­kon­tenci marudzą na zbyt­nie mar­notraw­stwo miej­sca na mar­ginalia i duże obrazki, ale moim zdaniem to właśnie to odróż­nia serię od konkurencji.

Ja swoją przy­godę z Head First za namową wykładowcy zacząłem od “Object-Oriented Analysis&Design”. Potem było “Design Pat­terns” i nagle okazało się, że programować w PHP można w zupeł­nie inny spo­sób niż “ciur­kiem”. Patrząc z per­spek­tywy czasu, należało PHP rów­nież roz­począć od HF. SQL i Java tak samo. Błędem w moim przy­padku było zażyczenie sobie na urodziny “Thin­king in Java” do nauki Javy od zera. Skutecz­nie na jakiś czas dałem sobie spo­kój z Javą (ale całe szczę­ście zacząłem od nowa po prze­czyteniu “Head First Java”). Nie mam oczywi­ście nic do “TiJ”, ale poziom trud­no­ści dla nowicjusza jest po prostu za duży.

Ostat­nio w moje łapki trafiła pozycja wydaw­nic­twa Packt Publishing “Programowanie obiek­towe w PHP 5″ autora obco brzmiącego nazwiska Hasina Haydera. Helion wydaje książki tego wydaw­nic­twa w sporo niż­szych cenach niż zwykle (pew­nie biorą mniej­szą marżę od O’Reilly i oczywi­ście śred­nia liczba stron jest mniej­sza). Po prze­czytaniu rów­nież muszę stwier­dzić, że książka “daje radę”. Autor wprowadza nas w rzeczy, które naj­praw­dopodob­niej nam się mogą przy­dać, w razie czego odsyłając do dokumen­tacji ;-) Łatwo serię roz­poznać po ujed­noliconej szacie graficznej.

Eh, jakie życie byłoby piękne gdyby Helion prze­kazywał egzem­plarz obowiąz­kowy bibliotekom tak jak mówi ustawa… (myślę to w czasie kiedy myślę o “Myśleniu obiek­towym w programowaniu” Matta Weis­felda, które stanie się moim następ­nym celem).


O pehapowcu, który chciał zostać javowcem

Znowu zleciał prawie miesiąc od ostat­niego wpisu… Nie ozanacza to oczywi­ście, że przez ten czas nic się nie działo. Wręcz prze­ciw­nie, a to za sprawą próby “wgryzienia się” w Javę.

Na róż­nych mądrych forach wyczytałem, że PHP to wła­ściwie zabawka, a praw­dziwe programowanie zaczyna się dopiero od Javy. Szkoda tylko, że nie­którzy nie zauważają, że “zabawki” typu Allegro napisane są w PHP. Dodat­kowo zachęcony hasłem “write once, use everywhere” zain­stalowałem sobie Net­Beans na Ubuntu i “ruszyłem z tym koksem”.

Co nowego zauważyłem w Javie z punktu widzenia znajomo­ści wyłącz­nie PHP (nie liczę Logo, Basic a potem Turbo Pas­cal za dzieciaka):

  • Nie ma w Javie zmien­nych bez wcześniej­szego zadeklarowania ich typu. Koniec ze zmienną będącą raz integerem, a innym razem stringiem.
  • Koniec z funk­cjami zwracającymi war­to­ści ładnie w PHP­Doc nazwane mixed, czyli jak wszystko faj­nie poszło, to return true, jak nie­faj­nie to false, a jak trochę faj­nie to stringa.
  • Prze­ciążanie metod to jest to czego mi brakuje w PHP. Wiele zadań programistycz­nych dałoby się łatwo i szybko roz­wiązać gdyby można było prze­ciążać metody (np. różne warianty konstruktora).
  • Tablice mają z góry ustaloną liczbę elemen­tów. Z drugiej strony mamy roz­budowane implemen­tacje kolek­cji typu List, SetMap (w których słabo się jesz­cze poruszam na dzień dzisiejszy).
  • Cała nowa grupa zagad­nień (i angiel­skiego słow­nic­twa) w ogóle nie występujących w PHP, czyli współ­bież­ność (problem dostępu wielu wąt­ków do tych samych danych, zaklesz­czenia, wzorzec producent-konsument itd.)
  • Ciekawe roz­wiązanie “niuan­sików OSowych”, np. w win­dow­sach ścieżki dostępu tworzy się znakiem \ , a w unik­sach / . Wpisując File.pathSeparatorChar Java sama dobierze sobie odpowiedni znak.
  • Budowa inter­fejsu graficz­nego i jego oprogramowywanie (nie­źle roz­wiązane w NetBeans).
  • Wszystko jest obiek­tem i dziedziczy po Object!
  • Nie da się nie­chluj­nie pisać kodu :-) Towarzysz kom­pilator (to rów­nież nowość) od razu zgłosi, że mu się coś nie podoba.

Z punktu widzenia czytel­nika tego bloga zapewne wygląda to tak jak­bym zabierał się za wszystko tylko po łebkach. Może i trochę tak jest, że szybko się czymś nudzę, ale w tym przy­padku chodzi o czystą ciekawość czy rzeczywi­ście “poważna Java” jest aż tak trudna do zro­zumienia. Po miesiącu nauki stwier­dzam, że nie jest to takie trudne. Oczywi­ście mam tutaj na myśli same pod­stawy języka (bez tych tysięcy bibliotek). Samo czytanie dokumen­tacji to już wyzwanie :-)


Atak klonów w PHP

Dzisiaj wieczor­kiem roz­pracowywałem sobie klonowanie obiek­tów w PHP. Dokład­nie zain­teresowała mnie metoda __clone(). W manualu PHP za dużo nie napisali, więc naskrobałem sobie krótki kod do prze­prowadzenia testów. Chodziło mi o to czy pod­czas wykonywania klonowania obiektu uruchamiany jest kon­struk­tor oraz czy można jakoś numerować klony (a co za tym idzie — “na gorąco” przy­pisywać polom sklonowanego obiektu jakieś war­to­ści). Poniżej podaję kod z komentarzem.

<?php
class Klon {

   // Ogolna liczba klonow
   private static $liczbaKlonow = 0;
   // Nr konkretnego klona
   private $klonNr;

   public function __construct() {
      // Na etapie konstruktora przypisujemy polu klonNr wartość 0,
      // jako iż nie jest żadnym klonem
      $this->klonNr = 0;
      // Dodatkowo wywalamy na ekran komunikat upewniający nas, że uruchomiono konstruktor
      echo 'Uruchomiono konstruktor i stworzono obiekt Klon!<br />';
   }

   public function __clone() {
      // Zwiększamy licznik liczby wszystkich klonów
      self::$liczbaKlonow += 1;
      // Przypisujemy aktualną wartość licznika nowo utworzonemu klonowi
      $this->klonNr = self::$liczbaKlonow;
   }

   // Proste sprawdzenie czy obiekt jest klonem, a jeżeli tak to którym
   public function getKlonNr() {
      if ($this->klonNr == 0) return 'nie jest klonem';
      return 'jest ' . $this->klonNr . ' klonem';
   }

   // Zwrócenie liczby wszystkich klonów obiektu
   public function getLiczbaKlonow() {
      return self::$liczbaKlonow;
   }
}

$oryg = new Klon();
// Klonujemy "oryginalny" obiekt
$klon1 = clone $oryg;
$klon2 = clone $oryg;
// Klonujemy klon
$klon3 = clone $klon2;

// Wypisujemy "kto jest kim"
echo 'Zmienna $oryg ' . $oryg->getKlonNr() . '<br />';
echo 'Zmienna $klon1 ' . $klon1->getKlonNr() . '<br />';
echo 'Zmienna $klon2 ' . $klon2->getKlonNr() . '<br />';
echo 'Zmienna $klon3 ' . $klon3->getKlonNr() . '<br />';

echo 'Wszystkich klonow: ' . $oryg->getLiczbaKlonow() . '<br />';
?>

Uruchomienie kodu wyświetli:
Uruchomiono konstruktor i stworzono obiekt Klon!
Zmienna $oryg nie jest klonem
Zmienna $klon1 jest 1 klonem
Zmienna $klon2 jest 2 klonem
Zmienna $klon3 jest 3 klonem
Wszystkich klonow: 3

Wnioski:

  • pod­czas klonowania nie jest uruchamiany konstruktor,
  • metoda __clone() wywoływana jest po sklonowaniu obiektu, a zmieniając coś poprzez $this->cośTam operujemy już na klonie!
  • prywatne zmienne statyczne to fajna zabawa :-)

O konsumpcji śledzia i szerzącej się głupocie

Na początku września nasz “ulubiony” ser­wis spo­łecz­no­ściowy, czyli Nasza-Klasa.pl dodała nowy bajer: Śledzik. W skrócie jest to prost­sza kopia takich ser­wisów microblog­gin­gowych jak Twit­ter czy rodzimy Blip. Wg mnie może być bar­dzo przy­datna, ale…

Od momentu wprowadzenia nowej funk­cjonal­no­ści dzieje się coś dziw­nego. Wszyscy użyt­kow­nicy jed­noczą się w celu “zatopienia śledzia”. To jed­noczenie polega na cał­kowicie bez­myśl­nym wklejaniu róż­nego rodzaju kodów wyłączających. Hiciorem wg mnie jest 5P13RD4L4J-5L3D21U wklejane przez wykształ­conych znajomych. Jest to tak zabawne (i żenujące), że stało się pożywką dla JoeMon­stera. Okazuje się, że nie tylko moich znajomych opanowała jakaś dziwna fala “antyśledzikowa”, ale jest to działanie ogól­nopol­skie. Powstał nawet “blog antyśledziowy”.

Skoro nie podoba się Śledzik, to po prostu nie używaj­cie. Spamując głupimi lin­kami uniemoż­liwiacie korzystanie z nowej funk­cjonal­no­ści zain­teresowanym. Prak­tycz­nie od początku ist­nieją co naj­mniej dwa spo­soby wyłączenia “śledzia”:

  • legalna” — poprzez klik­nięcie przy­cisku “nie śledź” przy każ­dym znajomym
  • nie­legalna” — poprzez skorzystanie z instruk­cji zawar­tych np. tutaj lub jeżeli macie Firefoksa i Adblock Plusa do reguł blokowania dodajecie nasza-klasa.pl#DIV(id=sledzik_box)

W ten co teraz spo­sób kom­promitujecie się coraz bar­dziej. Wklejaj­cie dalej różne głupoty, a ich twórcy będą się nie­źle bawić.

Źródło: demotywatory.pl

Aktualizacja z 30.09.2009, pojawił się nowy kan­dydat na hicior śledzikowy:

J3273M-D38113M <– Wklej cala ta wiadomosc, razem z tym kodem na sledzika, a on znik­nie NATYCHMIAST! Potwier­dzone przez administratora por­talu Nasza-Klasa.pl!


Nowa Opera 10 i blokowanie reklam

Dzisiaj ukazała się naj­now­sza stabilna wer­sja Opery, opatrzona numer­kiem 10. Przy­znam się, że ostat­nio Operę używałem w czasie, gdy jesz­cze miała u góry nie­znośny ban­ner reklamowy. Jak tylko pojawił się Firefox, ma się rozumieć bez żadnych reklam, po jakimś czasie w Operze zlikwidowano reklamy. Ja tym­czasem już na stałe zadomowiłem “ognistego liska” u siebie na kom­pie i tak już zostało do dzisiaj. No ale nie o tym miała być dzisiaj mowa.

Na stronie www.opera.com mamy ładną paczkę deb przy­gotowaną specjal­nie pod Ubuntu. Nie­stety wszyst­kie prze­glądane strony wyglądają hmm… zbyt “ruchomo i kolorowo” (a to za sprawą wszech­obec­nych reklam, od których odwykłem). Spróbowałem tego ustroj­stwa się pozbyć. Poniżej recepta:

Wyłączamy Operę.

W naszym katalogu domowym znaj­dujemy ukryty katalog .opera i tworzymy tam pusty plik o nazwie urlfilter.ini

Do pustego pliku wklejamy ten tekst:

Opera Preferences version 2.1
; Do not edit this file while Opera is running
; This file is stored in UTF-8 encoding

[prefs]
prioritize excludelist=1

[include]
*

[exclude]

Następ­nie ze strony http://niecko.pl/adblock/adblock.txt wklejamy całą zawar­tość począw­szy od *ad2.* aż do whitelist. Dodat­kowo możemy wkleić adresy stąd. Ostrzegają jed­nak, że im więcej wpisów tym wol­niej uruchomi się Opera. Zapisujemy plik.

Odpalamy Operę i w razie napo­tkania reklam używamy prawego przy­cisku na wol­nym polu i opcji zablokuj zawar­tość… w celu uzupeł­nienia fil­trów (dodadzą się na koniec urlfilter.ini).