Trasa do Nowego Warpna przez Niemcy

04-13-2011 przez Michał Bielecki Brak komentarzy »

Poprawny język tłumaczeń w module admin w Symfony

04-02-2010 przez Michał Bielecki 1 komentarz »

Od kilku dni bawię się z Symfony. Cały framework wygląda naprawdę fajnie, tym bardziej, że od pewnego już czasu korzystałem z niektórych zawartch w nim elementów (np. Propel).

Jedną z fajnieszych rzeczy w Symfony jest możliwość automatycznego wygenerowania panelu administracyjnego dla przygotowanego wcześniej modelu. Można go później do woli modyfikować i ulepszać, ale na samym początku zdecydowanie oszczędza to wiele godzin/dni pracy.

Łatwo znaleźć można (na stronie Symfony, lub przez wyszukiwarki) informację jak zmienić większość rzeczy (etykiety przy inputach, nazwy nagłówków, pola z bazy danych które mają być edytowalne, itp). Cały dzień dziś jednak straciłem na poszukiwaniu rozwiązania dla możliwości przetłumaczenia całego panelu.

Na początku kombinowałem z plikiem apps/{aplikacja}/modules/{moduł}/config/generator.yml można w nim bowiem zmieniać wiele. Można na przyklad ustawić nazwy akcji:

config:
  actions:
    _list: {   label: Lista }
    _save: {   label: Zapisz }
    _delete: { label: Usuń }
    _new: {    label: Dodaj }
    _edit: {   label: Edytuj }

Po częsci pomaga to w tłumaczeniu panelu, ale tylko częściowo – bo tak na prawdę zmiany te są zupełnie niepotrzebne w tym wypadku. Okazuje się bowiem, że Symfony ma już gotowe tłumaczenia (między innymi) dla języka polskiego dla tych akcji, ale i nie tylko.

W wielu wątkach w Internecie znaleźć można informacje o potrzebie ustawienia opcji .settings.default_culture na pl_PL w pliku apps/{aplikacja}/config/settings.yml. To jednak nie wystarczy. Nie wiem jak wyglądało to w starszych wersjach Symfony, ale przynajmnie w Symfony 1.4 opcja .settings.i18n ustawioną jest standardowo na “off”. Tak więc, aby tłumaczenia zadziałały poprawnie potrzeba, aby plik settings.yml w sekcji settings wyglądał mniej więcej tak:

all:
  .settings:
    i18n:                 on
    default_culture:      pl_PL
    csrf_secret: .....

I to by było na tyle. Po ustawieniu tych opcji oraz po zresetowaniu cache’a symfony (poleceniem ./symfony cc) oraz plików cookie w przeglądarce cały panel administracyjny jest przetłumaczony na język polski.

bind9 inside of openvpn

12-22-2009 przez Michał Bielecki 2 komentarzy »

I was playing today a little with bind9. My goal was to resolve intranet and global domain names through one server that would be inside of openvpn intranet.

I configured all the necessary zones, and all was working fine directly from server (that is a server for both openvpn and bind9). After setting up the DNS to be vpn/bind server a  problem occured – I was not able to  resolve any domain name (neither intranet nor internet), from none of machines that were connected to vpn network.

In the /var/log/syslog I was getting

named[xxxx]: client 10.12.12.3#53461 query ’some.domain.name/A/IN’ denied

Long story short, if you encounter such problem there is one simple solution. In your bind/named configuration (it will probably be /etc/bind/named.conf.options) set up following:

listen-on { any; };
allow-query { any; };

Of course you can switch “any” to any other IP address.

Funny thing is that “any” should be the default values for both options. It was’t for me.

Co zrobić z Google Latitude

11-24-2009 przez Michał Bielecki Brak komentarzy »

Stosunkowo niedawno Google uruchomiło usługę geolokalizacji o nazwie Latitude. Usługa nie jest szczególnie popularna w Polsce, być może ze względu na fakt iż do korzystania z niej potrzebny jest telefon z obsługą latitude oraz plan taryfowy na dostęp do Internetu w komórce. Ponadto nawet jeżeli spełnimy te wymagania to aplikacja zaczyna być przydatna dopiero, gdy korzystają z niej również nasi znajomi. Sami będziemy mogli co najwyżej bawić się w sprawdzanie czy Google dokładnie wykryło nasze położenie.

W tej chwili Latitude oferuje cztery podstawowe funkcjonalności, jest to informacja o położeniu w statusie google talk, publiczna plakietka z naszym położeniem (którą można np. umieścić na swoim blogu) oraz dwie niedawno dodane funkcjonalności historia lokalizacji oraz alerty.

Mnie najbardziej zainteresowała jednak funkcja w publicznej plakietce, umożliwiająca pobieranie danych o obecnej lokalizacji w formacie JSON lub KML. Mając te dane można w prosty sposób zapisywać historię lokalizacji. Oczywiście Google oferuje już dostęp do historii, ale jedyne co możemy z tymi danymi zrobić to wyświetlić je na mapce, nie da się ich użyć w żaden inny sposób.

Na szybko napisałem więc skrypt (w PHP – bo tak), który przy pomocy CURL’a pobiera dane w formacie JSON i wrzuca je do mojej bazy danych. Ustawiłem, aby skrypt był uruchamiany co 10 minut i mam już swoją bazę danych z historią lokalizacji. Idealnie nie jest – telefon wysyła informację o swoim położeniu średnio co 40 minut, w dodatku, gdy korzysta tylko z nadajników GSM często określa położenie z dokładnością do kilku kilometrów. O dziwo, gdy telefon ma włączony moduł wi-fi dokładność jest znacznie większa – kilkanaście metrów (jak słusznie zauważono tydzień temu).

Dobrze, mamy już dane ale po co nam one? A chociażby do geotagowania zdjęć. Jest to bardzo przydatna opcja wspierana przez coraz większą ilość programów, np. Google Picasa. Jedynym wymaganiem jest ustawienie poprawnego czasu w aparacie oraz posiadanie przy sobie komórki. Jestem w trakcie pisania aplikacji, która sprawdzi wszystkie zdjęcia z wybranego katalogu, pobierze z EXIF ich daty wykonania, odpyta bazę danych poprzez zapytanie http pobierając dla każdego pliku długość i szerokość geogr. a następnie doda je do zdjęcia.

Zastosowań tego typu danych oczywiście jest więcej. Mam już kilka innych pomysłów, o których być może napiszę już niebawem.

Poniżej skrypt do pobierania danych:

<?php

$googleId = 'XXXXXX';

$dbh = new PDO('mysql:host=localhost;dbname=***', '***', '***');
$url = "http://www.google.com/latitude/apps/badge/api?user=$googleId&type=json";
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_HTTPGET, true);
curl_setopt($curl, CURLOPT_POST, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$curl_result = curl_exec($curl);
curl_close($curl);

$res = json_decode($curl_result);
$lat = $res->features[0]->geometry->coordinates[0];
$lng = $res->features[0]->geometry->coordinates[1];
$name = $res->features[0]->properties->reverseGeocode;
$timestamp = $res->features[0]->properties->timeStamp;
$accuracy = $res->features[0]->properties->accuracyInMeters;

$date = date('Y-m-d H:i:s', $timestamp);

$sql = 'SELECT id FROM locations WHERE timestamp="'.$date.'"';
$stmt = $dbh->prepare($sql);
$stmt->execute();
$data = $stmt->fetch();
if( $data['id'] == '' ) {
$sql = 'INSERT INTO locations (lat, lng, name, timestamp, accuracy) VALUES ('.$lat.','.$lng.',"'.$name.'","'.$date.'",'.$accuracy.')';
$stmt = $dbh->prepare($sql);
$stmt->execute();
}

?>