11.112011
13:26
Ciężko mi było dopasować do tego tematu tytuł, ale chciałem dzisiaj opisać małą sztuczkę polegająca na takiej podmianie docelowego adresu, że osoba odwiedzająca stronę, nie jest świadoma tak naprawdę na jaką stronę zostanie przeniesiona po kliknięciu w dany link. Zacznę od zaprezentowania demo, tego prostego skryptu.
Poniżej znajduje się kod JavaScript/HTML, który pozwala „ukryć” docelowy adres linku:
function LinkMonitor(links) {
this.monitorURL = 'http://test.com/?url=';
var scope = this;
for(var i=0; i<links.length; ++i) {
links[i].onmousedown = function(event) {
scope.changeLink(this);
}
links[i].onmouseup = function() {
scope.clearLink(this);
}
links[i].onmouseout = function() {
scope.clearLink(this);
}
}
if(LinkMonitor.prototype_initialized != 'undefined') {
LinkMonitor.prototype.changeLink = function(a) {
a.href = this.monitorURL + a.href;
}
LinkMonitor.prototype.clearLink = function(a) {
setTimeout(function(domLink) {
domLink.href = domLink.href.replace(scope.monitorURL,'');
}, 100, a
);
}
}
}
window.onload = function() {
new LinkMonitor(document.links);
}
Idea działania jest bardzo prosta. Po załadowaniu drzewa DOM przekazujemy tablicę z linkami, których kliknięcia mają być monitorowane. Obserwowane są zdarzenia wciśnięcia i puszczenia klawisza myszy. Aby obsłużyć prawy przycisk myszy (np. kopiowanie adresu linku) obserwowane jest również zdarzenie „wyjścia” poza obszar linku. Jeżeli kopiowany adres ma być jednak oryginalny, a nie ten podmieniony to można zrezygnować ze zdarzenia „mouseout” i przy „mousedown” wykrywać kliknięcia przycisków event.button==0 i event.button==1. Ze względu, że zdarzenie 'mouseup' jest wcześniej niż 'click' na którym następuje wywołanie linku, dodane jest opóźnienie (100ms) przed przywróceniem oryginalnego linku.
Jak to wykorzystać? Oprócz zwykłego oszukiwania można przede wszystkim wykorzystać to do monitorowania aktywności użytkowników – np. kliknięć w linki zewnętrzne na stronie (robi tak. m.in. Google i Facebook), tak żeby użytkownik nie widział że jest monitorowany.
13.102011
21:40
Rozproszona struktura systemu GIT umożliwia bardzo łatwe tworzenie zdalnych repozytoriów kodu, z którym można synchronizować swoje lokalne repozytoria. Nie ma nawet potrzeby w tym celu stawiania i konfiguracji serwera HTTP do komunikacji z repozytorium, czy wymogu jakiegoś dodatkowego specjalnego oprogramowania. Wystarczy serwer z zainstalowanym GITem, oraz dostęp do tego serwera przez protokół SSH.
Zdalne repozytorium komunikujące się przez protokół SSH można utworzyć na kilka sposobów. Jednym z nich jest utworzenie nowego czystego repozytorium na zdalnym serwerze posługując się komendą 'git init' (znajdując się w folderze gdzie będą przechowywane jego pliki). Innym rozwiązaniem jest skopiowanie na serwer istniejącego repozytorium nie tracąc przy tym historii jego aktualnych commitów. Skopiować można ręcznie – kopiując folder, lub posługując się komendą 'git clone'.
Nowe repozytorium trzeba przekształcić w repozytorium publiczne, czyli przechowujące tylko wysłane do niego obiekty – bez możliwości lokalnej modyfikacji plików. Zrobić to można za pomocą polecenia:
git config --bool core.bare true
lub, po prostu edytując plik konfiguracyjny w folderze repozytorium:
vim .git/config
i dodając flagę opcję bare = true w grupie [core].
Jeżeli w folderze z repozytorium zdalnego znajdują się jeszcze jakieś pliki, lub foldery poza samym '.git', można je usunąć – nie będą już potrzebne (właściwe repozytorium znajduje się właśnie w folderze '.git' i tam też są przechowywane wszystkie zatwierdzane do repozytorium zmiany).
Teraz pozostaje już tylko powiązanie lokalnego repozytorium ze zdalnym, czyli zapisanie informacji w tym lokalnym o ścieżce do zdalnego repozytorium. Służy do tego polecenie:
git remote add origin ssh://remote-srv.pl/home/my_repo
gdzie origin oznacza nazwę zdalnego repozytorium (oczywiście można wybrać dowolną).
Aby wysłać zatwierdzone zmiany z lokalnego repozytorium do zdalnego można to zrobić poleceniem:
git push origin master
Origin jest zapamiętaną nazwą zdalnego repozytorium, master to natomiast główna gałąź repozytorium.
Aby pobrać zmiany ze zdalnego repozytorium (co będzie nieraz konieczne, jeżeli ze zdalnego repozytorium korzysta wielu użytkowników) można użyć polecenia:
git pull origin master
Znaczenie parametrów takie samo jak w przypadku polecenia push.
01.102011
17:24
Zauważyłem, ze nie bardzo lubię się dzielić jakimiś newsami odnośnie mojego życia prywatnego i będzie to pierwsza (lub jedna z pierwszych) z takich notek na tej stronie/blogu.
Ostatnio dużo się pozmieniało w moim życiu: zmiana miejsca zamieszkania, zmiana pracy, zmiana stanu cywilnego. W międzyczasie zdarzały się i będą się zdarzać dłuższe podróże. Zauważyłem, że podróż np. pociągiem, jest dobrym momentem, żeby pomyśleć o nowym wpisie na stronę (w końcu w trakcie podroży mam kilka mało produktywnych godzin). Tak wiec powstało w moim telefonie kilka notek, które pewnie jak dopracuję, pojawią się na stronie.
Mimo małej aktywności we wpisach i tak chcę poinformować, ze strona moja ciągle istnieje i nie planuję jej likwidować, a notki mimo wszystko będą się pojawiać, choć za pewne jak to do tej pory było w nieregularnych odstępach czasu.
Z rzeczy bardziej technicznych - ostatnio przepisałem na nowo silnik bloga. W tej chwili oparty jest na ZendFramework, wcześniej był na Symfony (jeszcze w wersji 1.2). Z punku widzenia czytelnika zmian nie jest dużo - od strony technicznej otworzyłem sobie bramkę do wygodniejszej rozbudowy i testowania własnych rozwiązań. Zmieniłem również hosting na serwer VPS - utrzymanie jest trochę droższe, ale mam większe możliwości konfiguracji i uruchamiania usług.
Odnośnie mojego software'u, to tez mam trochę planów. Mam już od dłuższego czasu przygotowaną nowszą wersję odtwarzacza jMPD, choć jeszcze nie do końca sprawdzoną. Planuję też zmienić silnik w Calummie z Xine na inny (prawdopodobnie VLC), ale na to potrzebuje już większej ilości wolnego czasu.
01.052011
20:53
Dla programistów (głównie tych początkujących) operatory bitowe często stanowią problem ich zrozumienia i wykorzystania. Dlatego też postaram się tutaj w skrócie pokazać na czym to wszystko polega.
Operatory bitowe w większości języków wysokiego poziomu wyglądają raczej podobnie. Należą do nich: & (AND), | (OR), ~ (NOT), ^ (XOR), << (przesunięcie w lewo), >> (przesunięcie w prawo).
Jak nazwa wskazuje – w operatorach bitowych operuje się bezpośrednio na bitach, więc do ich wykorzystania niezbędna będzie umiejętność posługiwania się systemem binarnym.
Przesunięcia
Przesunięcia bitowe polegają po prostu na przesunięciu bitów o podaną liczbę pozycji. Dla przykładu wybierzmy liczbę 5. W systemie binarnym będzie ona zapisana jako (000101). W wyniku jej przesunięcia o wskazaną liczbę bitów otrzymamy wartości:
|
Liczba |
Postać binarna |
Operacja |
Postać binarna po operacji |
Wynik |
|
5 |
(000101) |
5 << 1 |
(001010) |
10 |
|
5 |
(000101) |
5 << 3 |
(101000) |
40 |
|
5 |
(000101) |
5 >> 1 |
(000010) |
2 |
Łączenie liczb
Przy pomocy operatorów &, |, ^ możemy połączyć ze sobą kilka liczb porównując ze sobą ich kolejne bity. Najłatwiej można to zrozumieć patrząc na poniższą tabelkę:
|
Liczby |
Wynik dla & (AND) |
Wynik dla | (OR) |
Wynik dla ^ (XOR) |
|
5 (0101) i 3 (0011) |
1 (0001) |
7 (0111) |
6 (0110) |
|
9 (1001) i 4 (0100) |
0 (0000) |
13 (1101) |
13 (1101) |
|
3 (0011) i 1 (0001) |
1 (0001) |
3 (0011) |
2 (0010) |
Jak to wykorzystać?
Operacje bitowe można wykorzystać np. w celu przekazania do funkcji, lub przechowania w bazie wielu informacji typu prawda/fałsz w jednej zmiennej, za pomocą wcześniej przygotowanych flag/mask. Flagi (zapisane np. w postaci binarnej, ósemkowej, heksadecymalnej) przekazujemy tworząc nową liczbę przy pomocy operatora |. Następnie sprawdzamy wystąpienie danej flagi w tej liczbie operatorem &. Sprawa jest dość prosta i żeby za dużo nie tłumaczyć wystarczy spojrzeć na krótki poniższy kod i zwrócone wyniki.
class BityTest {
final public static int FLAG1 = 0001;
final public static int FLAG2 = 0010;
final public static int FLAG3 = 0100;
public static void main(String[] args){
parametersTest(FLAG1);
parametersTest(FLAG1 | FLAG3);
parametersTest(FLAG1 | FLAG3 | FLAG2);
}
public static void parametersTest(int flags){
System.out.print("przekazane flagi: ");
if((flags & FLAG1) == FLAG1)
System.out.print("FLAG1 ");
if((flags & FLAG2) == FLAG2)
System.out.print("FLAG2 ");
if((flags & FLAG3) == FLAG3)
System.out.print("FLAG3 ");
}
}
Wynik:
przekazane flagi: FLAG1
przekazane flagi: FLAG1 FLAG3
przekazane flagi: FLAG1 FLAG2 FLAG3
26.022011
19:44
Jednym z głównych problemów pracy na wielu komputerach jest synchronizacja danych między nimi. Od jakiegoś czasu powstaje coraz więcej narzędzi pomagających w tym procesie. Korzystam w tej chwili z kilku tego typu narzędzi. Jednym z nich jest Dropbox, innym właśnie Xmarks.
Xmarks jest narzędziem do synchronizacji zakładek między komputerami i różnymi przeglądarkami. W tej chwili obsługuje synchronizację z Firefoxem, IE, Chromem i Safari. Wersja premium ułatwia również dostęp do zakładek na urządzeniach mobilnych.
Dodatki wydane przez Xmarks bardzo dobrze integrują się przeglądarkami – zakładki nie są wyświetlane na osobnej stronie (jak np. w przypadku Diigo), lub w osobnym specjalnym panelu (Delicious), tylko w menu/panelu zakładek danej przeglądarki. Jeżeli w danym momencie nie mamy dostępu do przeglądarki z zainstalowanym dodatkiem synchronizującym, możemy zawsze skorzystać z wersji online naszych zakładek, logując się na stronie producenta – przeglądanie zakładek jest niemal tak samo wygodne jak w przeglądarce (zgrupowane w utworzone przez nas kategorie, z poprzypisywanymi tagami).

Przeglądanie zakładek online.
Wszystkie gromadzone przez nas zakładki są prywatne – widoczne tylko dla nas, jeżeli istnieje potrzeba podzielenia się danym katalogiem zakładek, możemy go udostępnić w postaci kanału RSS, lub strony WWW.
Oprócz synchronizacji zakładek Xmarks pozwala również na synchronizację otwartych kart, czy haseł pamiętanych w przeglądarkach. Zachęcam do przetestowania.