Stare, ale niestety wciąż prawdziwe.

Dodaj komentarz

http://www.youtube.com/watch?v=dfhFGA_7ZWs
Ostatnio nie mogę przestać słuchać tej piosenki. Najsmutniejsze w niej jest to, że choć ma 25 lat (jak nie lepiej) to wciąż jest w większości (jak nie we wszystkim) wciąż aktualna...

Dwa pozytywne kawałki.

3 komentarze

Dawno nic nie pisałem. Lipiec upłynął miło, bo z dala od zwykłego świata, do dziś sierpień mijał pod znakiem nudy. Dziś postanowiłem wyjebać Archa (zaczynał się sypać) i zainstalować Slackwarea. Od razu znalazło się zajęcie i jest fajnie. Do tego słucham właściwie dwóch kawałków na okrągło, którymi chciałbym się podzielić.

Pierwszym z nich jest utwór Dub Fxa (który urzekł mnie swoim występem na Przystanku Woodstock) pod tytułem "Time Will Tell". Nie jest to ta euforia co na Woodstocku (o którym, mimo, że był moim pierwszym i był świetny, nie chciało mi się napisać ;p), ale i tak jest nadzwyczajny (nie oszukujmy się, nie wiele rzeczy dorównują takiemu koncertowi). Można posłuchać na: http://dubfx.bandcamp.com/ . Tak na marginesie cała płyta jest warta przesłuchania, a nawet kupienia (choć 14 euro to trochę sporo). Warto również zaznaczyć, że wszystko oprócz wokalu i saksofonu na tej płycie to beatbox (oprócz saksofonu) posklejany cyfrowo w pętle i zmiksowany. Koleś zdołał to robić na żywo przed paroma setkami tysięcu ludu.

Drugi kawałek jest jednym z tych które mają świetny rerfren, który przesłania całą resztę. Właściwie jeszcze nie zdąrzyłem się wsłuchać w resztę utworu, ale cóż, takie życie. Utwór pochodzi z albumu pod tytułem "Propaganja - Diss na rząd" nosi tytuł "A ty nie!" i nie pozwala mi nie zacieszać słysząc go. Płytę można znaleźć do ściągnięcia za darmo, a posłuchać na Youtube : http://www.youtube.com/watch?v=0gkxkf_KXu4 . Warto zauważyć, że płyta, choć trochę nazbytyt hip-hopowa jak na mój gust (poprzednia była bardziej reggae), jest godna uwagi.

O wydajności MS Windows.

9 komentarzy

O tym, że Windows nie grzeszy wydajnością wiadomo od dawna. Widać to zwłaszcza na moim nieco starym sprzęcie, na którym nawet Windows XP z SP2 i antywirusem nie chodzi zbyt płynnie, na którym Linux pozwala oszczędzić bluzgania na sprzęt. Kolejną rzeczą która dostarczyła mi danych na temat wydajności obu systemów jest fajny FPS pod tytułem Nexuiz - Jak kiedyś próbowałem na Windowsie, niezależnie od ustawień grafiki, gra chodziła płynnie tylko do momentu w którym się pojawiał jakiś przeciwnik (czyli tak trochę kicha). Na każdym unix-like'u na którym próbowałem tej gry da się grać właściwie bez ścinania.

Dziś natomiast w newsletterze z gram.pl zauważyłem, że za 18 złotych można kupić World of Goo (swoją drogą, nie rozumiem ludzi, którzy kradną fajną taką grę mimo niskiej ceny). Patrzę na wymagania sprzętowe. Trochę kiepsko, bo one przewyższają mój sprzęt prawie dwukrotnie, na zalecane Pentium 4, 2GHz z 1GB RAM i kartą graficzną 128MB, AMD XP 1700+ (1GHz), 512 MB RAM i GeForce 2 to jednak trochę mało. Pomyślałem sobie, że i tak ściągnięcie demka nic mnie nie kosztuje. Tak też zrobiłem i się załamałem, bo gra chodzi wcale płynnie.

No nic, wracam do gry, bo zaczyna mnie wciągać. :)

Generator menu dla fluxboksa.

2 komentarze

Jakiś czas temu zaprezentowałem mój pierwszy skrypt PHP, przygoda z tym językiem szybko się zakończyła. Przyszedł czas na perla – aż wstyd się przyznać, że dopiero teraz. Tak czy inaczej, po dość oględnym przestudiowaniu języka przyszedł czas na chrzest bojowy - napisanie skryptu, który generowałby menu na podstawie /usr/share/applications/. Być może jest już coś takiego, ale jak wszystkim dobrze wiadomo, jestem bardzo leniwy. Zadanie może nie wydające się być trudnym (choć pisanie w tego C to niezbyt kusząca perspektywa), aczkolwiek dobrze zweryfikowało to co zrozumiałem z kursu.

Zacznijmy od tego, jak ten skrypt działa. Mianowicie, parsuje on plik z szablonem (~/.fluxbox/menu.templ) i pliki *.desktop z /usr/share/applications/ i na podstawie informacji w nich zawartych buduje menu. Skrypt nie jest jeszcze doskonały i będzie wymagał dość radykalnego przerobienia, tak by elementy mogły być sortowane alfabetycznie i obsługiwały lokalizacje. Niemniej jednak działa i dość dobrze i szybko (w moim przypadku 0,03s) wypełnia swoje zadanie.

Pliki szablonowe mają bardzo prostą budowę – są to zwyczajne pliki menu fluxboksa, wzbogacone o wtrącenia w nawiasach ostrych (muszą być w oddzielnych linijkach), informujących program, jak interpretować /usr/share/applications/. Mój plik szablonu wygląda następująco i wyczerpuje opcje, które można póki co wtrącić:

<setterm urxvt -font -*-fixed-medium-r-*-*-20-*-*-*-*-*-*-2 -fg white -bg black>
<show-groups Network,Utility,AudioVideo,Game,Application,Office,Graphics,Science,System>
[begin] (Fluxbox)
[encoding] {UTF-8}
  [exec] (uruchom) {fbrun}
  <addterm terminal>
  [exec] (WWW) {seamonkey}
  [exec] (e-mail) {seamonkey --mail}
  [exec] (vim) {gvim}
  <insert-here>
  [exec] (uaktualnij menu) {/home/bartek/fluxmenugen.pl}
  [restart]
  [exit]

jak widać, nie jest tego dużo:

  • Na samym początku polecenie setterm, ustawiające polecenie terminala, dla opcji addterm i do otwierania pozycji terminalowych (ewentualność jeszcze nie przetestowana, ale nie widzę powodu, dla którego miałaby nie działać ;p).
  • Potem rzecz najważniejsza - show-groups – wybiera, które grupy pokazać – za dużo tych grup się definiuje w plikach *.desktop, żeby je wszystkie wrzucić do menu. Póki co nie może być odstępu między nazwą, a przecinkiem.
  • Wspomniany już addterm, który wstawia polecenie terminala o opisie wpisanym dalej (w tym przypadku, "terminal").
  • insert-here w którego miejscu pojawią wygenerowane pozycje. Należy zwrócić uwagę na fakt, że można umieścić je w kilku miejscach, dla różnych konfiguracji show-groups. Należy również zaznaczyć, że grupy pojawią się w takiej samej kolejności jak podano w tej opcji.

Na sam koniec natomiast gotowy skrypt, który udostępniam do dowlonego użytku.

#! /usr/bin/perl -w
 
$sdir = "/usr/share/applications";
$sext = ".desktop";
$favterm = "urxvt";
 
$destdir = $ENV{'HOME'}."/.fluxbox/";
open (TEMPLATE, $destdir."menu.templ") || die "Failed to open template file.";
if(open (DESTINATION, $destdir."menu"))
{
  open (BACKUP, ">".$destdir."menu~");
  while ( <DESTINATION> )
  {
    print BACKUP;
  }
  close (BACKUP);
}
close ( DESTINATION );
 
open (DESTINATION, ">".$destdir."menu");
 
opendir ( SHORTCUTS, $sdir ) || die ("failed to open $sdir.");
@shortcuts = grep { m/$sext$/ } readdir ( SHORTCUTS );
closedir ( SHORTCUTS );
 
%groups = ();
$ungrupped = "";
 
foreach $shortcut ( @shortcuts )
{
  open ( SHORTCUT, $sdir."/".$shortcut);
  while ( <SHORTCUT> )
  {
    if ( m/^Name=(.+)(\s*)$/ )
    {
      $name = $1;
    }
    elsif ( m/^Exec=(.+)(\s*)$/ )
    {
      $cmd = $1;
    }
    elsif ( m/^Terminal=(.+)(\s*)$/ )
    {
      $term = $1;
    }
    elsif ( m/^Categories=(.+)(\s*)$/ )
    {
      @cats = split ( /;/, $1 );
    }
  }
  if ( !defined ( $name ) || !defined ( $cmd ) )
  {
    print "Failed to find essentional values for $shortcut\n";
  }
  else
  {
    if ( defined ( $term ) && $term eq "true" )
    {
      $cmd = $favterm." -e \"".$cmd."\"";
    }
    $stext = "[exec] ($name) {$cmd}\n";
 
    if ( !defined ( @cats ) )
    {
      $ungrupped .= $stext;
    }
    else
    {
      foreach $cat ( @cats )
      {
        $groups{$cat} .= $stext;
      }
    }              
  }
}
 
while ( <TEMPLATE> )
{
  if ( @tags = m/<(.+)>/g )
  {
    foreach $tag (@tags)
    {
      if ( $tag eq "insert-here" )
      {
        if ( defined ( @tagWhitelist ) )
        {
          foreach $group ( @tagWhitelist )
          {
            print DESTINATION "[submenu] ($group)\n";
            print DESTINATION $groups{$group};
            print DESTINATION "[end]\n"
          }
        }
        else
        {
          foreach $group ( keys %groups )
          {
            print DESTINATION "[submenu] ($group)\n";
            print DESTINATION $groups{$group};
            print DESTINATION "[end]\n"
          }
        }
        print DESTINATION $ungrupped;
      }
      elsif ( $tag =~ /^setterm (.+)/ )
      {
        $favterm = $1;
      }
      elsif ( $tag =~ /^addterm (.+)/ )
      {
        print DESTINATION "[exec] ($1) {$favterm}\n";
      }
      elsif ( $tag =~ /^show-groups (.+)$/ )
      {
        if ( defined ( @tagWhitelist ) )
        {
          push ( @tagWhitelist, split ( /,/, $1 ) );
        }
        else
        {
          @tagWhitelist = split ( /,/, $1 );
        }
      }
      elsif ( $tag =~ /^show-all/ )
      {
        undef ( @tagWhitelist );
      }
    }
  }
  else
  {
      print DESTINATION;
  }
}

i efekt:
Free Image Hosting at www.ImageShack.us

Ameryka...

2 komentarze

Absolutnie zdaję sobie sprawę, że w Stanach Zjednoczonych wszystko podpina się pod Zen, ale to już jest przegięcie:
Free Image Hosting at www.ImageShack.us

Pierwszy skrypt PHP - zdalne drukowanie.

6 komentarzy

Programuję już od kilku lat, ale jakoś się złożyło, że nie pisałem jeszcze aplikacji opartych o HTTP. Postanowiłem to zmienić i odejść na trochę od programowania w Rubim(zdaję sobie sprawę, że istnieje RoR, lecz chciałem zacząć od czegoś klasycznego i chyba jednak trochę łatwiejszego, jak PHP. Dlatego też postawiłem sobie serwer Apache(swoją drogą też bardzo przydatne doświadczenie) i zacząłem próbować.

Szybko też znalazł się problem, którego rozwiązanie przez prostą aplikację PHP wydawało się całkiem rozsądne. Mianowicie w domu mam dwa komputery(jeden mój i jeden brata) i tylko jedną drukarkę. W prawdzie mógłbym udostępnić serwer CUPS, ale po pierwsze brat musiałby instalować sterowniki do drukarki(tak przynajmniej mi się wydaje ;p), a ponadto zdarza mu się używać (sic!) Windows, co jeszcze bardziej komplikuje sprawę.

Oczywiście móglibyśmy użyć Samby, ale jesteśmy zbyt leniwi, żeby konfigurować Sambę na obu komputerach tylko po to, żeby od czasu do czasu coś wydrukować. Dlatego stanęło na wysyłaniu plików do druku pocztą. To upierdliwa sprawa, stąd ten skrypt(może się komuś przyda :)):

 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="pl">
  <head>
    <title>Stronka!</title>
    <META http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    <?php
      $uf = $_FILES['upfile'];
      if(isset($uf['name']))
      {
        if('php' == ($wynik = substr($uf['name'],-3,3)))
        {
          echo '<p>Wybacz, nie odbieram plików PHP</p>';
        }
        else
        {
          rename($uf['tmp_name'], 'udload/'.$uf['name']);
        }
      }
      if(isset($_GET['delete']))
      {
        unlink('udload/'.$_GET['delete']);
        echo '<p>Usunięto plik "'.$_GET['delete'].'"!</p>';
      }
 
      echo '<p>Cześć! Dzięki tej stronie możesz wysyłać mi dowolne pliki, 
ściągać te, które Ci udostępniam, a także wysyłać pliki do drukowania przez 
moją drukarkę.</p>';
 
      if(isset($_GET['print']))
      {
        if('.ps' !== ($wynik = substr($_GET['print'],-3,3)) && 
                                      ! isset($_GET['sure']))
        {
          echo 'Wybrany plik ma rozszerzenie inne niż *.ps. Jeśli jesteś
pewien, że zawiera dane PostScript,
<a href="index.php?print='.$_GET['print'].'&sure=1">kliknij tutaj</a>';
        }
        else
        {
          $out = array();
          $ret = 0;
          exec('lp /srv/http/udload/'.$_GET['print'], $out, $ret);
          if($ret == 0)
          {
            echo '<p>Drukowanie powiodło się.</p>';
          }
          else
          {
            echo '<p>Drukowanie nie powiodło się. Zawartość stdout:
<br/>'.$out.'</p>';
          }
        }
      }
      $cdir = dir('udload');
      if($cdir !== false)
      {
        $n = 0;
        while(false !== ($file = $cdir->read()))
        {
          if($file != '.' && $file != '..')
          {
            if($n == 0)
            {
              echo "<h1>Pliki na serwerze:</h1><p><ol>";
              $n = 1; 
            }
            echo '<li><a href="udload/'.$file.'">'.$file.'</a>
<a href="index.php?delete='.$file.'"><sup>[usuń plik]</sup></a>
<a href="index.php?print='.$file.'"><sup>[drukuj plik]</sup></a></li>';
          }
        }
        if($n == 1)
        {
          echo "</ol></p>";
        }
        $cdir->close();
        echo '<h1>Wyślij plik</h1><p>Możesz wysłać plik o dowolnym
rozszerzeniu, oprócz *php o wielkości nie przekraczjącej 10<sup>6</sup>
bajtów:<br/><form enctype="multipart/form-data" method="post" 
action="index.php"><input type="file" name="upfile" value=""/>
<input type="hidden" name="MAX_FILE_SIZE" value="1000000"/><br/>
<input type="submit" name="send"/></form>';
      }
    ?>
  </body>
</html>
 

Jakie wrażenia z zabaw PHP? Zdecydowanie przechodzę do RoRa, zwłaszcza po obejrzeniu filmów, które można zobaczyć na stronie projektu.

Zenwalk 5.2

3 komentarze

Ostatnio sporo eksperymentowałem z różnymi środowiskami - najpierw GNOME, a potem ciut za ciężkie na mój sprzęt(Athlon XP 1700+, 512MB RAM) KDE4, którego jedyną zaletą, moim skromnym zdaniem , jest Amarok. Trochę się poinstalowało śmiecia, więc stwierdziłem, że to dobry moment, żeby spróbować czegoś nowego. Postanowiłem wybrać Zenwalka. Przede wszystkim, że bazuje na slackware i korzysta z niesprawdzonego jeszcze przeze mnie XFCE, ale też hasło "Ever tried zen computing?" nie pozostało bez znaczenia. :)

Na początek instalacja. Tu nie ma się zbytnio nad czym rozpisywać. Instalator jak instalator. Tekstowy, a jednak w ładnej oprawie(framebuffer jak sądzę). Na tym etapie zdziwił mnie fakt iż system ten, podobnie jak poprzednio przeze mnie używany Arch, traktuje wszystkie dyski jako SCSI, co objawia się się nietypowymi nazwami urządzeń(/dev/sdxn i /dev/srn). Dalej jedyną ciekawostką jest ciekawie pomyślana konfiguracja LILO, przypominająca nieco tą z PLD, ale ta jednak jest trochę bardziej rozbudowana.

Potem przyszedł czas na pierwsze bootowanie. Co ciekawe na samym wstępie poczęstował mnie porcją kilku licencji do zaakceptowania(GNU/GPL, Adobe, Intel), a następnie uruchomił alsaconf i całkiem fajny, stworzony w ncurses menedżer użytkowników. Dalej już standard - gdm.

Całkiem ładny wygląd XFCE. Po małym przekonfigurowaniu, bardzo mi odpowiada.

W oczy też się rzuca bardzo dobra szybkość(mniej więcej na równi z Archem). W standardowym zestawie programów niestety nie ma kilku ważnych programów, więc zacząłem od netpkg, menedżera pakietów Zenwalka, a właściwie jego graficznej nakładki. Program wcale przyzwoity, prosty do bólu, nic dodać nic ująć. Szybko wyszukałem seamonkeya(niestety bez polskiej lokalizacji, którą trzeba było doinstalować w klasyczny sposób), następnie mpd, mpc i z braku gmpc, ario, którego wcześniej nie znałem(a szkoda). Mpdscribble niestety musiałem zainstalować ze źródeł, jak również samodzielnie musiałem napisać skrypt startowy dla mpd/mpdscribble, a takze konfigurację. W gruncie rzeczy nic trudnego. Gdy z głośników zaczęła się sączyć muzyka mogłem przejść do konfiguracji. Najpierw XFCE. Wszystko w porządku, tylko szkoda, że nie ma edytora motywów dla GTK. No nic, nauczę się je pisać przynajmniej. :)

Dalej zaskoczył mnie zestaw konfiguratorów zenwalka. Całkiem przyjemnie się ich używa. Szkoda, że kosztem braku /etc/rc.conf. Nie można mieć wszystkiego.

Następnie przyszedł czas na sterowniki NVIDIA. Tu pozytywne zaskoczenie, bo są źródła kernela (Archu jakoś nie mogłem ich znaleźć).

Podsumowując, Zenwalk to bardzo przyjemna, szybka dystrybucja, jak najbardziej pasująca do swojego motta. Większość konfiguracji da się załatwić konfiguratorami(oprócz mpd, cupsa, konfigurowanego przez przeglądarkę; sane, sudo i nvidia). Bardzo duży plus za menedżer pakietów. W jednym zdaniu, jeśli lubisz XFCE, chcesz szybkiego i prostego, a przy okazji całkiem łatwego, systemu to Zenwalk jest zdecydowanie dobrym pomysłem.

Nagrywanie systemów plików złożonych z dużej ilości katalogów przy użyciu growisofs jest nieco kłopotliwe, bo jest dużo pisania, głównie przez ustawianie graft pointów. GNOME baker natomiast nie oferuje mi zbyt wielkiego pola do popisu, jeśli chodzi o konfigurację (jestem ślepy, czy naprawdę nie można wybrać, czy użyć Jolieta czy Rock Ridge?). Dlatego też, powodowany wrodzonym lenistwem, postanowiłem coś z tym zrobić.

Mianowicie napisałem prosty skrypt, który za nas załatwi graft pointy, a nawet sprawdzi, czy należy użyć opcji -Z czy -M. Powodowany wspomnianym lenistwem zmiana opcji odbywa się poprzez edycję skryptu (w przedstawionej wersji instaluje tylko rock-ridge). Składnia natomiast jest prosta. W argumentach wpisujemy nazwy katalogów(można spokojnie używać gwiazdki). Natomiast parametry "-f" i "-d" odpowiednio informują program, czy dane dalej parametry oznaczają pliki, czy katalogi(domyślnie katalogi). Jeśli podamy nazwę katalogu wśród plików, zostanie nagrana jego zawartość. Po wprowadzeniu polecenia program wydrukuje linię poleceń i poprosi o zatwierdzenie. Skrypt wymaga growisofsa i cdrdao, jest napisany dla archa (więc może być konieczność zmiany /dev/sr0 na odpowiednią dla twojego systemu ścieżkę). Kto chce, niech bierze:

#! /bin/bash

if [ -n "$1" ]
then
  echo Burner, enter with names of wanted directories to burn on /dev/sr0 with rock-ridge, and with no joliet
else
  isempty=`cdrdao disk-info --device /dev/sr0 | grep "CD-R empty" | grep "no"`
  if [ "$isempty" == "" ]
  then
    echo -n "growisofs -Z=/dev/sr0 -R --graft-points " > .burnertmp
  else
    echo -n "growisofs -M=/dev/sr0 -R --graft-points " > .burnertmp
  fi
  isfile=0      
  for x in "$@"
  do
    case $x in
      "-f") isfile=1 ;;
      "-d") isfile=0 ;;
      *) if [ "$isfile" == 1 ]
           then
             echo -n "\"`echo $x`\" " >> .burnertmp
             else
             echo -n "\"`echo $x`\"=\"`echo $x`\" " >> .burnertmp
            fi ;;
    esac
  done

  cat .burnertmp
  echo
  echo "Is that ok? If so press ENTER, CTRL+C to cancel"
  read
  chmod +x .burnertmp
  ./.burnertmp
  rm .burnertmp
fi

Niepokojący symptom

9 komentarzy

Ostatnio pisałem o odkryciu walorów emacsa. Wczoraj po raz kolejny przyłapałem się na próbie zapisania gry w Fallout Tactics kombinacją C-x C-s. Całe szczęście, że C-x nic nie robi, a C-s zapisuje grę ;p

Stare, ale jare po raz n-ty :)

3 komentarze

Ostatnio więcej gram. Możliwe, że między innymi przez ferie. Ostatnio pykałem w Baldur's Gate( ale niestety zaciąłem się puki co ;p). Toteż zmieniłem grę. Wybrałem grę do której nigdy nie parałem szczególną miłością, chociaż znam ją od baaardzo dawna.

Mam na myśli The Settlers 2. Wreszcie doceniłem tę grę. Aż nie chce się wierzyć, jak bardzo mnie to wciągnęło. Gra się odznacza bardzo fajną grafiką, niekiedy bywa bardzo zabawna( zwłaszcza podczas walk ;p). Przede wszystkim jednak czas płynie bardzo szybko. Aż sam byłem zaskoczony, za każdym razem, gdy dostawałem wiadomość, że nie zapisałem gry przez 30 minut :)