Podczas testowania jakiegoś projektu zapewne wielokrotnie zdarzało wam się wkurzać, że nie możecie szybko i sprawnie przetestować metod w projekcie. Jakaś nowa libka, algorytm i zaraz kombinowanie, wrzucanie do osobnego pliku lub pisanie testów tylko po to, żeby sprawdzić czy dobrze zrobiliśmy regexp.
A gdyby tak... mieć interfejs CLI do takich zabaw? Taki interaktywny? Hmm?
Podczas pracy nad jednym projektem dostałem zadanie - zrobić stronę w wielu językach. Ponieważ problem jest dość ciekawy, postanowiłem trochę o nim popisać[1]
W przypadku tworzenia mniej dynamicznej strony internetowej zawierającej jednak panel administracyjny, możemy mówić o tłumaczeniu dwóch najważniejszych elementów: tych w bazie danych i tych na stronie. Na początek skupmy się na tych na stronie, a później przejdziemy do bazy danych.
Gdyby to kogoś interesowało, od Freda Wu przejąłem niedawno moduł do obsługi PHamlP w Kohanie. Kod znajduje się na githubie i jest podzielony na dwie gałęzie - główna, gdzie skrypt będzie zawsze działał i testowa, gdzie prawie na pewno nie będzie działał :P
Oprócz tego rozwijam powolutku forka samego PHamlP, ponieważ projekt z tego co widzę na Google Code tak jakby umarł i zaczyna lekko śmierdzieć. Moja wersja to głównie poprawki, które wprowadziłem (typu dopisanie niedokończonych funkcjonalności), ale z tego co widzę na githubie są już bardziej rozwinięte forki, więc pewnie z czasem dropnę to co mam i "pożyczę" do projektu jeden z nich ;)
Z programistycznych spraw ostatnio siedzę głównie nad komercyjnymi projektami za pieniążki, a jeśli już coś rozwijam to głównie dlatego, że z tym pracuję. Głównie dlatego nie mam czasu na Joggera 3.0, ale dochodzi również brak chęci ze względu na podejście 'i tak będzie nie tak jak chcemy' ;) Chwilowo z półoficjalnego githubowego repozytorium Joggera dropnąłem cały kod, który był namazany do tego czasu - przez to, że zbyt miękko podchodziłem do wyboru konwencji programowania nie nadawał się do niczego - i mam zamiar jeśli już się zabiorę, oprzeć całość o Kohanę 3.1 (bo tak), sprząc to z ichnim ORM-em (bo tak) i keszować co trzeba po stronie serwera (bo tak).
Hej, nie umarłem, żyję nadal, prace nad Joggerem 3 chwilowo wstrzymane (przepraszam, praca + matura :( wrócę do niego jak mi się ustatkuje sytuacja materialna), ale ja dziś nie o tym.
Przez długi-długi okres czasu odtwarzając filmy we Flashu, można było równocześnie skorzystać z dobrodziejstw ich wygodnego cache'owania. Gdy odpalaliśmy coś w YouTube, Vimeo czy Pornhubie (już ja wiem co ludzie robią z szerokopasmowym internetem ;)), plik flv z filmem był zapisywany jako /tmp/Flash[id] gdzie [id] to były znaki z serii A-Z, a-z i 0-9.
Od jakiegoś czasu jednak, Flash zapisuje takie dane w nieco inny sposób, częściowo niejawnie. Wejście do katalogu /tmp udowodni nam, że plików tam nie ma, a jednak jakimś sposobem na dysku zapisywane są. Jak?
Otóż jakiś cwany developer postanowił wykorzystać linuksowe uchwyty do pliku. Polega to na tym, że Flash tworzy jakiś plik, a następnie go kasuje nie usuwając uchwytu. Miejsce jest dalej zaalokowane jak trzeba, dane nadal można tam zapisać i czytać, ale plik nie istnieje w formie pliku, a po zamknięciu uchwytu staje się po prostu wolną przestrzenią dyskową.
Ale zaraz, to w takim razie w jaki sposób można dobrać się do tych danych? Otóż bardzo prosto. Sposób wykorzystany przez sprytnego developera jest mieczem obosiecznym - uchwyty do plików muszą istnieć, więc są gdzieś zapisywane ;) Co ciekawe, żeby się do nich dobrać nie trzeba używać skomplikowanych procedur, strace czy zewnętrznych programów - lista uchwytów do plików danego procesu jest tworzona w /proc/ID/fd/ .
Czyli mamy prostą metodę. Zakładając, że korzystamy z Google Chrome, robimy:
$ ps -eo pid,command | grep flashplayer
I szukamy naszego flashplugina, który w Chrome jest - jak wszystko co tylko się dało - osobnym procesem. U mnie wyglądało to następująco:
12449 /opt/google/chrome/chrome --type=plugin --plugin-path=/opt/google/chrome/libgcflashplayer.so --lang=pl --plugin-data-dir=/home/d4rky/.config/google-chrome/Default --channel=5017.0x11a036c0.344273884
W przypadku przeglądarek nie rozbijających wszystko na części pierwsze, interesuje nas proces samej przeglądarki, czyli np:
$ ps -eo pid,command | grep firefox 26698 /usr/lib/iceweasel/firefox-bin
Mając już do dyspozycji ID procesu, wchodzimy do - w moim przypadku - /proc/12449/fd i zobaczmy co mamy tam za cuda:
$ ls -ltr | grep Flash lrwx------ 1 d4rky d4rky 64 02-26 18:32 23 -> /tmp/FlashXXQyI8lK (deleted)
A tuś mi bratku! Okazuje się, że pliki są nazywane po staremu, tylko stosowana jest sztuczka z uchwytami ;)
Co teraz zrobić, skoro mamy już uchwyt? Proste, wystarczy traktować go jak każdy inny plik. Wskazuje nadal na poprawne dane, więc nic nie stoi na przeszkodzie, żeby zrobić tak:
cp /proc/12449/fd/23 "/home/d4rky/Elvis Prestley - Love me tender.flv"
albo
mplayer /proc/12449/fd/23
I voila! Magicznie odzyskujemy zdolność warezo... tzn "tworzenia kopii zapasowych" filmików z sieci. Prawda, że łatwe? ;)
Sposób odnaleziony na jakimś klonie StackOverflow.
This function is based on phpion's code but with added PNG-24 alpha channel support. Took me a while to figure it out, but imagecopymerge doesn't support transparency (don't ask me) so I had to use imagecopy and turn on imageAlphaBlending (despite what people in PHP manual's comments say). Too bad it couldn't be done in application/ and I had to edit system/ files.