Ad ACTA – o prawie autorskim i prawach pokrewnych

„Nie istnieje człowiek, sprawa, zjawisko, a nawet żadna rzecz, dopóty, dopóki w sposób swoisty nie zostały nazwane. Władzą jest więc moc swoistego nazywania ludzi, spraw, zjawisk i rzeczy, tak aby te określenia przyjęły się powszechnie. Władza nazywa, co jest dobre, a co złe, co jest białe, a co czarne, co jest ładne, a co brzydkie, bohaterskie lub zdradzieckie; co służy ludowi i państwu, a co lud i państwo rujnuje; co jest po lewej ręce, a co po prawej, co jest z przodu, a co z tyłu. Władza określa nawet, który bóg jest silny, a który słaby, co należy wywyższać, a co poniżać.”

Tymi słowy rozpoczął Zbigniew Nienacki jedną ze swoich powieści będącą wizją powstania państwa polskiego. Wątki i postaci przedstawione w książkach z serii „Dagome iudex” są wyimaginowane choć tło historyczne oraz miejsca mają odniesienie do rzeczywistości. Celne są też spostrzeżenia, jak i przemyślenia przemycane czytelnikom pod postacią wypowiedzi bohaterów, czy też cytatów z rzekomych dzieł, jak choćby przytoczony wyżej fragment rozdziału „O sztuce rządzenia ludźmi” z Księgi Grzmotów i Błyskawic.

Zatem nazwano nas piratami.

Kiedy pewien rolnik wymyślił kosę pomyślał sobie – Będę teraz rżnął żyto dwa razy szybciej od mojego sąsiada, który używa sierpa, a do tego ominą mnie bóle krzyża. Jakież musiało być jego rozczarowanie, kiedy sąsiad zrobił sobie takie samo narzędzie. Rolnik poszedł do sąsiada i powiedział.

– Coś mi się chyba należy za to, że ułatwiłem Ci pracę?

– Bóg zapłać – usłyszał w odpowiedzi.

A gdyby chroniły go prawa własności intelektualnej to rolnik mógłby odpowiedzieć:

– Boga zostaw w spokoju. Zapłać sam.

I albo sąsiad musiałby dalej kosić w kucki, albo wynalazca żyłby z licencji jak Microsoft, który zarabia więcej na patentach niż na bieżącej „produkcji”. Nie wiem jak szybko rozwinęło by się rolnictwo ale najbogatszym darmozjadem na ziemi byłby spadkobierca wynalazcy koła.

Życie bardów nie było łatwe ale odmieniło się wraz z wynalazkiem pozwalającym utrwalić dźwięk. Wystarczyło raz zaśpiewać i można to było sprzedać wielokrotnie. Co za pech!!! Że też ten rozwój technologiczny nie zatrzymał się na etapie płyt gramofonowych? Kto potrafił takowe kopiować? Taśmy magnetofonowe to nieszczęście ale mp3 i internet to już dla muzyków prawdziwa katastrofa – o wytwórniach już nie wspomnę. Nie dość, że trzeba znowu zacząć dawać koncerty to jeszcze stale wymyślać nowe utwory bo w końcu ile można słuchać „Somebody That I Used To Know” (może dla odmiany cover)?

Ale niektórzy muzycy tak nie chcą.

Czyż nie byłoby to wspaniałe gdybym – będąc kierowcą – mógł raz przejechać trasę autobusem, a potem autobus sam już by jeździł z zaprogramowanym wirtualnym kierowcą, a organizacje typu MPK (Miejskie Przedsiębiorstwo Komunikacyjne) zajmowało by się ochroną moich praw i kasowało każdego, kto chciałby się ze mną przejechać? Na szczęście nie jestem kierowcą autobusu bo moje marzenie nigdy by się nie spełniło. Jestem za to programistą więc kto wie?

Artyści wmawiają nam, że ściągając plik z internetu okradamy ich. Jeśli ja ukradnę komuś rower to ten ktoś nie ma roweru, ale jeśli ja wysłucham płyty w internecie to czy grupa, która ją nagrała traci ją? Krawiec też chciałby uszyć koszulę sprzedać ją i mieć ją nadal aby móc znowu ją sprzedać. Jeżeli technologia sprzyja firmie fonograficznej – umożliwia powielanie utworów w nieskończoność w celu jego wielokrotnej sprzedaży – to takie działanie każe nam się postrzegać jako moralne, a jeśli ta sama technologia pozwala zaoszczędzić pieniądze przeciętnego użytkownika to wtedy piętnuje się go mianem złodzieja.

– Jaskier – westchnął wiedźmin, robiąc się naprawdę senny. – Jesteś cynik, świntuch, kurwiarz i kłamca. I nic, uwierz mi, nic nie ma w tym skomplikowanego.

Andrzej Sapkowski w sadze o Wiedźminie – „Miecz przeznaczenia”.

Cztery lata poświęcił Michał Anioł freskom plafonowym w Kaplicy Sykstyńskiej. Zapewne papież Juliusz II nieźle za to zapłacił, co się Michałowi niewątpliwie należało bo arcydzieło wielkie popełnił. Ja bym w każdym razie nie malował sufitu kościoła przez cztery lata za grosze. Produkcje Hollywood też kosztują majątek, a aktorstwo wielu gwiazd zasługuje by je docenić, ale czy trzeba od razu gażę liczyć w milionach? Czy pensja w wysokości nauczyciela lub pielęgniarki nie jest godziwa? Dobre filmy zwracają się błyskawicznie a najlepsze zarabiają krocie pomimo tego, albo może wręcz dlatego, że są powszechnie dostępne. Najwięcej zarabia się nie na emisji samego filmu ale na wszelkiego rodzaju związanych z nim gadżetach. Jeśli jesteś matką lub ojcem, a Twoje dziecko zakochało się w McQueenie albo jego ulubionym bohaterem jest Buzz Astral to policz ile Cię w sumie kosztowała przyjemność obejrzenia z dzieckiem „The Cars” lub „Toystory”.

W „Księciu” Niccolò Machiavelli napisał „Ludzie tak są prości i tak naginają się do chwilowych konieczności, że ten, kto oszukuje, znajdzie zawsze takiego, który da się oszukać.” Wielu jest takich, którzy bazując na ludzkiej ciekawości, naiwności i poczuciu winy nie dość, że namówią klienta do kupienia często kiepskiego (wirtualnego) produktu, to jeszcze przekonają go do tego, że jest on wart ceny, którą zapłacił. Z drugiej strony także Machiavelli stwierdził „Kto pragnie oszukać, zawsze spotka takiego, który oszukać w żaden sposób nie pozwoli.”

W czasach tak zwanej rewolucji przemysłowej miliony harowały na garstkę kapitalistów, którzy bogacili się, aż pewnego dnia do władzy doszedł lud i nazwał ich burżujami. Nie pragnę rewolucji bo jak pokazuje historia jedna patologia zmieniła się w drugą. Teraźniejszość jednak udowadnia, że trzeba być czujnym bo to co nas dziś niepokoi jutro będzie przerażać. Co was przeraża w tym artykule? Piractwo?

Nie podoba mi się pomysł podpisania ACTA bo nie służy ochronie naturalnych praw do godziwego wynagrodzenia tylko do utrwalenia wynaturzonych praw do wyzyskiwania innych. Prawo do nazywania siebie autorem przysługuje każdemu, kto jest faktycznym twórcą lub pomysłodawcą danego dzieła, jednak prawa pokrewne w tym wszelkiego rodzaju koncesje, licencje, patenty itp. muszą ulec przedefiniowaniu gdyż w obecnej formie służą jedynie produktywności prawników ścigających się z komornikami w ściąganiu haraczy.

I kto tu jest piratem?

Lepszy var_dump czyli przyjemniejsze debugowanie PHP

bigWeb/Debug/Dumper to narzędzie funkcjonalnie odpowiadające funkcji var_dump
Jego przewagą jest sposób prezentacji danych, a także dodatkowe informacje
ułatwiające debugowanie aplikacji.

Najpoważniejszą wadą Dumpera jest to, że jest on dość obciążający dla aplikacji
gdyż uzyskanie informacji o pliku i linii, w której dump został wywołany
wymaga każdorazowo rzucenia wyjątku. Dlatego też w wersji produkcyjnej
Dumper powinien być wyłączony

UWAGA! Biblioteka zaprezentowana w przykładach wymaga min PHP 5.3
z uwagi na użycie przestrzeni nazw.
Ponieważ jednak nie na wszystkich serwerach jest już PHP w wersji obsługującej
przestrzenie nazw przygotowałem także wersję Dumpera nie wymagającą ich użycia.
w takim przypadku wywołanie bigWeb\Debug\Dumper::factory(); należy zastąpić
poprzez wywołanie bigWeb_Debug_Dumper::factory(); i analogicznie w przypadku
innych klas. Wersja Dumpera dla PHP < 5.3 zawarta jest w archiwum zip bigWeb\Debug\Dumper do ściągnięcia.

Instalacja

include_once('./Debug.php');

Można też użyć autoloadera. Wszystkie klasy potrzebne do działania Dumpera
zdefiniowane są w pliku „Debug.php”. Wyjątkiem jest FirePHP, który należy
dodać osobno jeśli chcemy wyświetlać dane w konsoli javascript

include_once('./FirePHP.php');

Podstawowe użycie

dump('some data');

w wyniku otrzymamy:

TIME: 20:46:44 FILE: /home/www/bigWeb/Debug/example.php LINE: 37 ET: 0 MU: 1.44 mb MPU: 1.67 mb

‚some data’
string(9) "some data"

Dumpa można wywołać z wieloma parametrami o różnych wartościach równocześnie.

$str = 'text';
$int = 7;
$arr = array('foo', 'bar');
$ob = new ArrayObject();
$bool = FALSE;
 
dump($str, $int, $arr, $ob, $bool);
TIME: 20:46:44 FILE: /home/www/bigWeb/Debug/example.php LINE: 47 ET: 0.000904 MU: 1.47 mb MPU: 1.67 mb

$str
string(4) "text"
$int
int(7)
$arr
array(2) {
  [0]=>
  string(3) "foo"
  [1]=>
  string(3) "bar"
}
$ob
object(ArrayObject)#3 (1) {
  ["storage":"ArrayObject":private]=>
  array(0) {
  }
}
$bool
bool(false)

Ukrywanie komunikatów

Aby zapobiec wyświetlaniu jakichkolwiek komunikatów przez dumpera należy go wyłączyć.

bigWeb\Debug\Dumper::setEnabled(FALSE);
dump('it should not show');

Aby ponownie włączyć:

bigWeb\Debug\Dumper::setEnabled(TRUE);

Definiowanie alternatywnych logerów

Domyślnie dumper do zrzutu danych używa wbudowanej funkcji var_dump jednak
klasa Dumpera jest zbudowana w oparciu o wzorzec projektowy Obserwator, gdzie
obserwatorami są wyspecjalizowane klasy do logowania i prezentacji zrzucanych danych.
Dzięki temu możemy wybierać sposób logowania informacji.

Możemy zapisywać dane w pliku – przydatne np. przy testowaniu przekierowań

$d = bigWeb\Debug\Dumper::factory();
$o = new bigWeb\Debug\Dumper\FileDump();

Koniecznym jest wskazanie katalogu w którym będą zapisywane logi.
Katalog ten musi mieć oczywiście ustawione prawa do zapisu

$o->setDir(dirname(__FILE__));
$d->attach($o);
$d->notify('foo');

wynik zostanie zapisany w pliku /home/www/bigWeb/Debug/2012-01-12.log.php

TIME: 20:46:18 FILE: /home/zh/www/Debug/example.php LINE: 71 ET: 0.001143 MU: 1.55 mb MPU: 1.67 mb
----------| 'foo' |----------
foo
.----------------------------

Można też skorzystać z dobrodziejstw FireBuga – dodatku do Firefoxa i
wyświetlać dane w konsoli javascript. W tym przypadku musimy najpierw
załadować bibliotekę FirePHP będącej „pomostem” pomiędzy PHP i FireBugiem.

include_once('./FirePHP.php');
 
$d = bigWeb\Debug\Dumper::factory();
$d->attach(new bigWeb\Debug\Dumper\FireDump());
$d->notify('bar');

wynik pokarze nam się w konsoli FireBug-a

Wynik Dumpera w konsoli FireBug

UWAGA! Ponieważ informacje do FireBuga są przesyłane za pomocą nagłówków HTTP
biblioteka FirePHP wymaga buforowania wyjścia (output bufering). Koniecznym
jest zatem użycie funkcji ob_start() w przeciwnym razie można się spotkać
z błędem „headers already sent error”

Łańcuch wywołań

Niekiedy chcemy wiedzieć jakie funkcje i metody zostały wywołane nim został
wykonany kod w danym miejscu. Aby zobaczyć cały łańcuch wywołań należy
ustawić flagę show_trace na TRUE.

function foo() {
    $d = bigWeb\Debug\Dumper::factory();
    $d->attach(new bigWeb\Debug\Dumper\VarDump());
    $d->setShowTrace(TRUE);
    $d->notify('Show chain requests');
}
 
function bar() {
    foo();
}
 
bar();
TIME: 20:46:44 FILE: /home/www/bigWeb/Debug/example.php LINE: 97 ET: 0.005149 MU: 1.57 mb MPU: 1.67 mb

$d->notify(‚Show chain requests’);
string(19) "Show chain requests"
Array
(
    [0] => Array
        (
            [file] => /home/www/bigWeb/Debug/example.php
            [line] => 97
            [function] => notify
            [class] => bigWeb\Debug\Dumper
            [type] => ->
            [args] => Array
                (
                    [0] => Show chain requests
                )

        )

    [1] => Array
        (
            [file] => /home/www/bigWeb/Debug/example.php
            [line] => 101
            [function] => foo
            [args] => Array
                (
                )

        )

    [2] => Array
        (
            [file] => /home/www/bigWeb/Debug/example.php
            [line] => 104
            [function] => bar
            [args] => Array
                (
                )

        )

)

Praca na serwerze produkcyjnym

W zasadzie Dumper powinien być wyłączony na serwerze produkcyjnym bo obciąża
aplikację, a ponadto może wyświetlać dane wrażliwe. Nie mniej w pewnych
wyjątkowych okolicznościach możemy chcieć go użyć. Musimy wcześniej przewidzieć
taką sytuację i dodatkowo skonfigurować przynajmniej jedną z instancji Dumpera
ustawiając tak zwany secret_key

$d = bigWeb\Debug\Dumper::factory();
$d->attach(new bigWeb\Debug\Dumper\FireDump());
$d->setSecretKey('verysicretkey');

Aby te dane były widoczne należy wywołać url metodą GET z parametrem
secret_key=1. W tym przypadku będzie to

example.php?verysicretkey=1
bigWeb\Debug\Dumper::setEnabled(FALSE);
$d->notify('Visible when set secret_key');

aby ponownie włączyć:

bigWeb\Debug\Dumper::setEnabled(TRUE);

Jeśli wywołamy url metodą GET z sekretnym kluczem, Dumper ustawia ciasteczko
debugcookie o wartości wywiedzionej z secret_key. Od tej pory nie trzeba już dodawać do
adresu żadnego specjalnego parametru. Jeśli jednak chcielibyśmy wyłączyć
debugowanie należy wywołać url z secret_key=0

example.php?verysicretkey=0

Tworzenie funkcji pomocniczych

Tworzenie obiektu i dodawanie obserwatorów nie jest zbyt wygodnym rozwiązaniem.
Narzędzie do debugowania powinno być extremalnie proste i szybkie w użyciu.
Dlatego warto sobie zdefiniować funkcję pomocniczą – podobną do „debug();”

function dump_all() {
    $_args = func_get_args();
    static $d = null;
    if ( $d === null )
    {
        // Proszę zwrócić uwagę na wywołanie metody factory z parametrem $level = 3
        $d = bigWeb\Debug\Dumper::factory(3);
        $o = new bigWeb\Debug\Dumper\FileDump();
        $o->setDir(dirname(__FILE__));
        $d->attach($o);
        $d->attach(new bigWeb\Debug\Dumper\FireDump());
        $d->attach(new bigWeb\Debug\Dumper\VarDump());
 
    }
    call_user_func_array(array($d, 'notify'), $_args);
}
 
dump_all('foo bar');

wynik zostanie zapisany w pliku

TIME: 20:46:44 FILE: /home/zh/Praca/bigWeb/Debug/example.php LINE: 155 ET: 0.006137 MU: 1.59 mb MPU: 1.67 mb
----------| 'foo bar' |----------
foo bar
.--------------------------------

w konsoli FireBug-a

Wynik Dumpera w konsoli FireBug

oraz wyświetlony w przeglądarce:

TIME: 20:46:44 FILE: /home/www/bigWeb/Debug/example.php LINE: 155 ET: 0.006137 MU: 1.59 mb MPU: 1.67 mb

‚foo bar’
string(7) "foo bar"

UWAGA! Od wartości level zależy prawidłowe wskazanie linii oraz pliku, w którym
wywołano dumpa. Domyślnie level = 1. Jeżeli metoda „notify” jest zagnieżdżona
w funkcji pomocniczej to wartość level powinna być inkrementowana (level = 2).
Jeśli dodatkowo metoda „notify” jest wywoływana za pośrednictwem funkcji
„call_user_func_array” to należy ustawić level = 3

$d = bigWeb\Debug\Dumper::factory(1);
 
function d1($param) {
    $d = bigWeb\Debug\Dumper::factory(2);
    // ...
    $d->notify($param);
}
 
function d2($param) {
    $_args = func_get_args();
    $d = bigWeb\Debug\Dumper::factory(3);
    // ...
    call_user_func_array(array($d, 'notify'), $_args);
}

UWAGA! Jeśli masz już zdefiniowaną funkcję „dump” w swojej aplikacji
to po dołączeniu kodu Dumpera otrzymasz wszystkomówiący wyjątek. Poinformuje
Cię on, że musisz zdefiniować sobie funkcję pomocniczą o innej nazwie.
Należy zakomentować kod wywołujący wyjątek lub też dołączyć kod Dumpera
w sposób umożliwiający przechwycenie wyjątka i utworzyć funkcję pomocniczą
np. o nazwie „d”.

try { include_once("Debug.php"); } catch (bigWeb\Debug\Exception $e) {
    function d() {
        $_args = func_get_args();
        static $d = null;
        if ( $d === null )
        {
            $d = bigWeb\Debug\Dumper::factory(3);
            $d->attach(new bigWeb\Debug\Dumper\VarDump());
 
        }
        call_user_func_array(array($d, "notify"), $_args);
    }
}

Napisana przeze mnie klasa nie zastąpi zaawansowanych i rozbudowanych narzędzi debugowania i profilowania aplikacji jednak jest prosta w użyciu nie związana stricte z żadnym frameworkiem, przez co łatwo ją zaadaptować zarówno do pracy z Zend Frameworkiem, Symfony, Kohaną czy jakimkolwiek innym – napisanym w PHP – skryptem. Biblioteka zwraca wyniki w postaci pokolorowanego kodu przy okazji pokazując czas wykonania oraz wielkość użytych zasobów. Zapomniany var_dump potrafi zmusić programistę do przeszukiwania plików projektu. W przypadku Dumpera nie ma takiego zagrożenia gdyż każdorazowo wskazuje on ścieżkę do pliku oraz nr linii, w której funkcja robiąca zrzut danych została wywołana.

Serdecznie zapraszam wszystkich do wypróbowania Dumpera oraz wszelkich uwag na temat wdrożeń i ewentualnych błędów.

Stan baterii w laptopie – linux

Zaniepokoił mnie wskaźnik stanu naładowania baterii. Kilka godzin pracy na laptopie z podpiętym zasilaczem a 48% jak było tak było i nic nie chciało się ruszyć.

Polecenie:

cat /proc/acpi/battery/BAT1/info

Dało wynik:

present:                 yes
design capacity:         39960 mWh
last full capacity:      46320 mWh
battery technology:      rechargeable
design voltage:          11100 mV
design capacity warning: 420 mWh
design capacity low:     156 mWh
cycle count:              0
capacity granularity 1:  264 mWh
capacity granularity 2:  3780 mWh
model number:            PABAS024
serial number:           3658Q
battery type:            LION
OEM info:                LG

Czy to jest w ogóle możliwe aby projektowana pojemność baterii (design capacity) była mniejsza od ostatnio odnotowanej pełnej pojemności (last full capacity)? Mój laptop ma zaledwie dwa miesiące licząc od daty zakupu. Czy wartość pojemności projektowanej jest specjalnie zaniżana przez producentów, abym w przypadku sprawdzenia parametrów baterii – dajmy na to po roku użytkowania – czuł się bardziej komfortowo z powodu teoretycznie mniejszego zużycia baterii? A może te parametry są po prostu źle odczytywane?

Tak czy inaczej nie zmienia to faktu, że pomimo podłączonego zasilacza moja bateria zwyczajnie się nie ładowała. Pod Windowsem dostałem przynajmniej czytelny komunikat, natomiast widżet w KDE zwyczajnie mnie okłamywał. Jak już jesteśmy przy KDE to przy okazji zakupu nowego laptopa zdecydowałem się powrócić do KDE po zawodzie jaki mi sprawiło Unity. Znajomy zapewniał mnie, że Plasma została już dopracowana – NIE ZOSTAŁA.

Wracając jednak do baterii. Wykonałem kilkakrotnie polecenie:

cat /proc/acpi/battery/BAT1/state

Dało wynik:

present:                 yes
capacity state:          ok
charging state:          charged
present rate:            0 mW
remaining capacity:      22230 mWh
present voltage:         10924 mV

Wartość remaining capacity nie ulegała zmianie. Postanowiłem rozładować całkowicie baterię, a później spróbować ją naładować od zera. Czekając na rozładowanie baterii znalazłem i trochę zmodyfikowałem skrypcik w bash-u pokazujący stan baterii – (może się komuś przyda).

#!/bin/sh
 
CUR=`cat /proc/acpi/battery/BAT*/state | grep remaining | awk {'print $3'}`
STATE=`cat /proc/acpi/battery/BAT*/state | grep charging | awk {'print $3'}` 
MAX=`cat /proc/acpi/battery/BAT*/info | grep full | awk {'print $4'}`
DESIGN=`cat /proc/acpi/battery/BAT*/info | grep 'design capacity:' | awk {'print $3'}`
PRC=0
 
REAL_CAP=$(($MAX*100/$DESIGN))
PRC=$(($CUR*100/$MAX))
if [ $PRC -gt 100 ]; then
    PRC=100
fi 
 
echo 'State : '$STATE
echo 'Design Battery Capacity : '$DESIGN' (100%)'
echo 'Real Battery Capacity : '$MAX' ('$REAL_CAP'%)'
echo 'Current Battery capacity : '$CUR' ('$PRC'%)'

Po całkowitym rozładowaniu, przy wyłączonym komputerze podłączyłem zasilacz. Dioda zaczęła pokazywać, że bateria się ładuje. I rzeczywiście bateria naładowała mi się całkowicie. Nie jestem sprzętowcem i nie czytam fachowej prasy dlatego nie wiem czy to prawidłowe działanie – jakieś zabezpieczenie przed przedwczesnym zużyciem baterii czy też objaw uszkodzenia sprzętu? W innych laptopach, z którymi się spotkałem mogłem w każdej chwili doładować baterię.