Internet, UNIX, Video, Leisure…
Dev
Syslog LogAnalyzer with LDAP authentication
19/01/12

Adiscon is the company responsible for developping LogAnalyzer, a syslog (rsyslog, syslog-ng…) and/or flat file « analyzer ».
By analyzer, understand that it enables you to display the log in a meaningful way, splitting it depending on « views » and enabling real search filters.
If you don’t have the money for things liks Splunk and you are not convinces by other new projects using Rails, NoSQL and other tools that are a pain in the ass to install, you may fallback to LogAnalyzer.
Lire la suite de l’article »
WordPress NextGEN Gallery and GPS data
18/01/11
NextGen(eration) Gallery is a WordPress plugin from Alex Rabe. It provides image galleries, albums with great ease of administration.
As said by the author, it fills a gap in WordPress gallery systems.
It can handle « display » templates, which can be added to the plugin Views or simply in your theme. That’s what I’m working on right now for the Photo Theme I’m using in my new Photo Blog.
This way you don’t have to install another plugin and use hooks.
While it’s working well, it still have some features missing.
One of the missing stuffs is beeing able to display GPS data.
My photo blog have Geo-Tagged pictures. I want to be able to display them along with a google map image so my readers can see where it was taken. I also want to display some of the EXIF informations, like lense type, aperture, shutter speed and so on…
While some of them (most) are already handeled by the NextGen gallery, some of them are not.
NextGen Gallery is using the exif_read_data function to get the data from the file like :
Then, the RAW exif datas are separated in arrays. When trying to access the EXIF tags (using get_EXIF), only the part of the array under [EXIF] will be used. In fact this is partly false, as the get_EXIF function also dig under IFD0 and WINXP.
As the GPS data from my Nikon D700 are under the [GPS] array, there is no chance that NextGen gallery sees them even if you use the wordpress filter to add some new EXIF tags.
Then you only have one solution : check in the RAW meta-data or… change NextGen so it can handle them in the EXIF tags stored in the database.
So, my solution is divided in few parts :
- Hardcode some new EXIF tags
- get the GPS data inside get_EXIF
- add a function to parse the GPS data and make them readable/usable by Google Map
Let’s do it :
Hardcode some new EXIF tags
In the file lib/meta.php, change the get_common_meta function so it look like :
-
function get_common_meta() {
-
global $wpdb;
-
-
‘aperture’ => 0,
-
‘credit’ => »,
-
‘camera’ => »,
-
‘caption’ => »,
-
‘created_timestamp’ => 0,
-
‘copyright’ => »,
-
‘focal_length’ => 0,
-
‘iso’ => 0,
-
‘shutter_speed’ => 0,
-
‘flash’ => 0,
-
‘title’ => »,
-
‘altitude’ => »,
-
‘longitude’ => »,
-
‘latitude’ => »,
-
‘timestamp’ => »,
-
‘datestamp’ => »,
-
‘satellites’ => »,
-
‘direction’ => »,
-
‘lense’ => »,
-
‘keywords’ => »
-
);
As you can see, I add all the GPS data, plus « lense », which is just a hook as the EXIF tag for the lense is actualy « UndefinedTag:0xA434″
You can also add the new tags in the i8n translation function
-
function i8n_name($key) {
-
-
‘aperture’ => __(‘Aperture’,‘nggallery’),
-
‘credit’ => __(‘Credit’,‘nggallery’),
-
‘camera’ => __(‘Camera’,‘nggallery’),
-
‘caption’ => __(‘Caption’,‘nggallery’),
-
‘created_timestamp’ => __(‘Date/Time’,‘nggallery’),
-
‘copyright’ => __(‘Copyright’,‘nggallery’),
-
‘focal_length’ => __(‘Focal length’,‘nggallery’),
-
‘iso’ => __(‘ISO’,‘nggallery’),
-
‘shutter_speed’ => __(‘Shutter speed’,‘nggallery’),
-
‘title’ => __(‘Title’,‘nggallery’),
-
‘author’ => __(‘Author’,‘nggallery’),
-
‘tags’ => __(‘Tags’,‘nggallery’),
-
‘subject’ => __(‘Subject’,‘nggallery’),
-
‘make’ => __(‘Make’,‘nggallery’),
-
‘status’ => __(‘Edit Status’,‘nggallery’),
-
‘category’ => __(‘Category’,‘nggallery’),
-
‘keywords’ => __(‘Keywords’,‘nggallery’),
-
‘created_date’ => __(‘Date Created’,‘nggallery’),
-
‘created_time’ => __(‘Time Created’,‘nggallery’),
-
‘position’ => __(‘Author Position’,‘nggallery’),
-
‘city’ => __(‘City’,‘nggallery’),
-
‘location’ => __(‘Location’,‘nggallery’),
-
‘state’ => __(‘Province/State’,‘nggallery’),
-
‘country_code’ => __(‘Country code’,‘nggallery’),
-
‘country’ => __(‘Country’,‘nggallery’),
-
‘headline’ => __(‘Headline’,‘nggallery’),
-
‘credit’ => __(‘Credit’,‘nggallery’),
-
‘source’ => __(‘Source’,‘nggallery’),
-
‘copyright’ => __(‘Copyright Notice’,‘nggallery’),
-
‘contact’ => __(‘Contact’,‘nggallery’),
-
‘last_modfied’ => __(‘Last modified’,‘nggallery’),
-
‘tool’ => __(‘Program tool’,‘nggallery’),
-
‘format’ => __(‘Format’,‘nggallery’),
-
‘width’ => __(‘Image Width’,‘nggallery’),
-
‘height’ => __(‘Image Height’,‘nggallery’),
-
‘flash’ => __(‘Flash’,‘nggallery’),
-
‘latitude’ => __(‘Latitude’,‘nggallery’),
-
‘longitude’ => __(‘Longitude’,‘nggallery’),
-
‘altitude’ => __(‘Altitude’,‘nggallery’),
-
‘lense’ => __(‘Lense’,‘nggallery’),
-
);
get the GPS data inside get_EXIF
Now, every time you insert a new image or re-import the meta-data, the new tags will be asked. We need to change the get_EXIF function so it can find them.
Still in lib/meta.php, go down to the get_EXIF function and change it to :
-
function get_EXIF($object = false) {
-
-
if ( !$this->exif_data )
-
return false;
-
-
-
-
$exif = $this->exif_data[‘EXIF’];
-
-
$meta[‘created_timestamp’] = date_i18n(get_option(‘date_format’) . ‘ ‘ . get_option(‘time_format’), $this->exif_date2ts($exif[‘DateTimeDigitized’]));
-
$meta[‘focal_length’] = $this->exif_frac2dec( $exif[‘FocalLength’] ) . __(‘ mm’,‘nggallery’);
-
$meta[‘iso’] = $exif[‘ISOSpeedRatings’];
-
$meta[‘shutter_speed’] = $this->exif_frac2dec ($exif[‘ExposureTime’]);
-
$meta[‘shutter_speed’] =($meta[‘shutter_speed’] > 0.0 and $meta[‘shutter_speed’] < 1.0) ? ( ’1/’ . round( 1 / $meta[‘shutter_speed’], -1) ) : ($meta[‘shutter_speed’]);
-
$meta[‘shutter_speed’] .= __(‘ sec’,‘nggallery’);
-
}
-
//Bit 0 indicates the flash firing status
-
$meta[‘flash’] = ( $exif[‘Flash’] & 1 ) ? __(‘Fired’, ‘nggallery’) : __(‘Not fired’,‘ nggallery’);
-
-
$meta[‘lense’] = $exif[‘UndefinedTag:0xA434′];
-
}
-
-
// additional information
-
$exif = $this->exif_data[‘IFD0′];
-
-
$meta[‘camera’] = $exif[‘Model’];
-
$meta[‘make’] = $exif[‘Make’];
-
$meta[‘Orientation’] = $exif[‘Orientation’];
-
}
-
// additional GPS information
-
$exif = $this->exif_data[‘GPS’];
-
// send exif data to the function to get GPS on one line
-
$GPS=self::get_Exif_GPS($exif, 1);
-
$meta[‘latitude’] = $GPS[‘latitude’];
-
$meta[‘longitude’] = $GPS[‘longitude’];
-
$meta[‘altitude’] = $GPS[‘altitude’]." metres";
-
$meta[‘timestamp’] = $GPS[‘timestamp’];
-
$meta[‘direction’] = $GPS[‘direction’];
-
$meta[‘satellites’] = $exif[‘GPSSatellites’];
-
$meta[‘datestamp’] = $exif[‘GPSDateStamp’];
-
}
-
}
You can see two things here :
- if the meta asked is « lense », we look for the un-named attribute
- when we are done with EXIF and IFD0, we check in the GPS array
add a function to parse the GPS data and make them readable/usable by Google Map
Now we create the function to re-calculate the GPS coords. Create a function somewhere in the class. A good place is at the end of the lib/meta.php file, just before the last closing bracket.
-
function get_Exif_GPS($exif, $assoc = false) {
-
//get the Hemisphere multiplier
-
$LatM = 1; $LongM = 1;
-
if($exif["GPSLatitudeRef"] == ‘S’) {
-
$LatM = -1;
-
}
-
if($exif["GPSLongitudeRef"] == ‘W’) {
-
$LongM = -1;
-
}
-
-
//get the GPS data
-
$gps[‘LatDegree’]=$exif["GPSLatitude"][0];
-
$gps[‘LatMinute’]=$exif["GPSLatitude"][1];
-
$gps[‘LatgSeconds’]=$exif["GPSLatitude"][2];
-
$gps[‘LongDegree’]=$exif["GPSLongitude"][0];
-
$gps[‘LongMinute’]=$exif["GPSLongitude"][1];
-
$gps[‘LongSeconds’]=$exif["GPSLongitude"][2];
-
$gps[‘Altitude’]=$exif["GPSAltitude"];
-
$gps[‘TimeHour’]=$exif["GPSTimeStamp"][0];
-
$gps[‘TimeMin’]=$exif["GPSTimeStamp"][1];
-
$gps[‘TimeSec’]=$exif["GPSTimeStamp"][2];
-
$gps[‘direction’]=$exif["GPSImgDirection"];
-
-
//convert strings to numbers
-
foreach($gps as $key => $value) {
-
if($pos !== false) {
-
$gps[$key] = $temp[0] / $temp[1];
-
}
-
}
-
-
//calculate the decimal degree
-
$result[‘latitude’] = $LatM * ($gps[‘LatDegree’] + ($gps[‘LatMinute’] / 60) + ($gps[‘LatgSeconds’] / 3600));
-
$result[‘longitude’] = $LongM * ($gps[‘LongDegree’] + ($gps[‘LongMinute’] / 60) + ($gps[‘LongSeconds’] / 3600));
-
$result[‘altitude’] = $gps[‘Altitude’];
-
$result[‘timestamp’] = $gps[‘TimeHour’].‘:’.$gps[‘TimeMin’].‘:’.$gps[‘TimeSec’];
-
$result[‘direction’] = $gps[‘direction’];
-
-
if($assoc) {
-
return $result;
-
}
-
-
}
Conclusion
Re-importing the meta-data of all your pictures should add the new stuffs.
I’v posted in the WordPress forum and asked for this to be added to the NextGen Gallery dev tree. Still have no answer for now. Maybe someone will come with a better code or better idea ?
I also asked for someone to check how GPS data are included in files from other brands as I can only tell for the Nikon’s D700.
jQuery tricks and notes
4/01/11
jQuery is a well known JavaScript « framework ». It have unique features for DOM manipulation and web page animations. Another one is MooTools, said to be better in animations.
When you’re on a webpage with sliding images (orbit, novo slider…), growing windows or overlays… you can be pretty sure they are using one of these frameworks. The latest versions of WordPress bundle jQuery. As I wanted a special theme for my photo-blog (not yet finished but can be seen here), I had to dig in jQuery.
While the jQuery basis is really simple, somehow well documented on their website and full of examples on the net, you still have tricks to know so your code is 100% efficient, bug free and more important cross browser compatible (I mean, compatible with IE 6/7).
I will reference here the pages/people talking of such hints, tricks and notes, and maybe give my own recommendations and discoveries.
First one is actualy mine, even if it’s obvious : install Firebug or enable Safari Developper options in your browser. This way, just right-clic on a part of a webpage and « Inspect » it.
Most of jQuery scripts are in « full text », not minified or obfuscated. Or, at least, you will find clues of the author, the licence… and be able to use it, copy/modify it or just be insipred.
Second one is a must-read when you already know the basis of jQuery. It’s a 14 point tricks/notes from Jeffrey Way and located at http://net.tutsplus.com
They also have two other interresting articles about Hidden Features and Animation.
I would also like to add two blogs/website of people providing great examples and tutorials for free :
More will come
Sending SMS from Nagios
17/12/09

Sometimes you need to be able to send SMS from a computer. This is obvious when you’re talking of monitoring your servers. Email alerts are good, but what if you’re sleeping ?
I used to set up a SMS modem, with it’s own SIM card and subscription. This is really easy, using smsd daemon, to send SMS. Just put a formated file in a directory and bam!, you SMS is fired.
But what when you can’t set a SMS Modem in a datacenter ?
Then you have to use an online SMS provider.
you just have to call an API to send a SMS
it’s not free (you pay per SMS when the modem can have an unlimited SMS sending subscription
it is network dependant ; if you have a network failure, you will never be informed
computer stuffs…
19/10/09
The main purpose of this blog is to act as a reminder, a todo. Here are things i’ve just found and needs a second look at, or more, a testing.
This is a shell (sh) script that should made things easier when having a look or doing a « tail -f » at Glassfish error logs.
This is a blog, lately talking about Glassfish V3 REST api implementation. As far as I know this is (still) not working with GF v2, which already have JMX and, if you’re a registered Sun user, SNMP. But worth having a look.
It seems to me that most of developpers are using Spring framework nowadays. This tool should enable them (or force them ?) to have a deeper look of what the framework is actualy doing. Seriously, comments welcome. May be the weapon of choice for sysadmins like me, dealing with developpers who hide behing their framework (like if the framework was an excuse… huhuhu).
Another monitoring software… well… to be tested.
An interesting thing you can do with Google’s API… It should with any database, but hey, a free software working with Oracle is worth beeing mentioned
This is a PDF file dealing with TimesTen Database. This is a product newly (2 or 3 years) bought by Oracle, and well integrated. Embed the database close to the application, in the application server. Data are replicated at startup. You can choose which database, which table, which data using a filter, or even do transformations to the data. You select the synchronization frequency and there you go. I had a session OOW 2009 about that and how it was used to break a CDN application in two parts : one for slow data change (read/write to the DB) and one for massive fast queries on the delivery side. Ok, this use a lot of RAM… but RAM is cheap isn’t it ?
Now we have some cool things to read and test, don’t we ?
Un peu de lecture…
27/02/08
Tutoriel sur l’injection SQL : http://st-curriculum.oracle.com/tutorial/SQLInjection/index.htm
Oracle Performance Tuning Guide
Un bon blog sur Oracle : http://sysdba.wordpress.com/
A lire sur Python / Django :
VirtuelEnv, qui permet de gerer des « package d’installation » de Python, et garder la distrib de base « propre »
Un exemple d’utilisation de VirtualEnv
Un autre blogger qui parle de VirtualEnv (lire les commentaires)
Et n’oubliez pas d’installer easy_install
Building MacPorts Py-Mysql on Leopard
15/02/08
If you installed over your old Tiger or if you are new user, you may have experienced errors when trying to build py-mysql.Py-mysql is a Python module to connect to Mysql.I’m using it to have Django, the Python Web Framework, to connect to Mysql database. This is what I got when trying to install :
# port install py-mysql
---> Building py-mysql with target build
Error: Target org.macports.build returned: shell command " cd "/opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_ports_python_py-mysql/work/MySQL-python-1.2.2" && /opt/local/bin/python2.4 setup.py build " returned error 1
Command output: running build
running build_py
copying MySQLdb/release.py -> build/lib.macosx-10.3-ppc-2.4/MySQLdb
running build_ext
building '_mysql' extension
/usr/bin/gcc-4.0 -fno-strict-aliasing -Wno-long-double -no-cpp-precomp -mno-fused-madd -fno-common -fno-common -dynamic -DNDEBUG -g -O3 -Wall -Wstrict-prototypes -Dversion_info=(1,2,2,'final',0) -D__version__=1.2.2 -I/opt/local/include/mysql5/mysql -I/opt/local/Library/Frameworks/Python.framework/Versions/2.4/include/python2.4 -c _mysql.c -o build/temp.macosx-10.3-ppc-2.4/_mysql.o
In file included from /opt/local/include/mysql5/mysql/mysql.h:47,
from _mysql.c:40:
/usr/include/sys/types.h:92: error: duplicate 'unsigned'
/usr/include/sys/types.h:92: error: two or more data types in declaration specifiers
error: command '/usr/bin/gcc-4.0' failed with exit status 1
Error: Status 1 encountered during processing.
I tried to upgrade MacPorts… but I already had the latest.
# port selfupdate
MacPorts base version 1.600 installed
Downloaded MacPorts base version 1.600
The MacPorts installation is not outdated and so was not updated
selfupdate done!
I finaly found the solution on http://rob.cogit8.org/blog/2007/Nov/14/installing-django-leopard-mac-os-105/
Google is everywhere
28/12/07

One new API from Google. This one allow you to create charts (graphiques, pour les francophones).
Philippe Mougin is our guest and comes with a clean example with integration to Apple’s Cocoa programming. Check this here.
Faire du python dans automator (Leopard)
28/12/07

Voila le site d’une personne qui a une solution. Cela interessera particulierement mon ami Akhen, qui fete son anniversaire demain. Tiens, c’est pour toi : http://toxicsoftware.com/run-python-script/
une fiche memo pour Django
9/06/07
C’est pas nouveau mais je viens de tomber la dessus. Ca peut etre pratique, surtout que je vais essayer de m’y remettre un peu…
bref, c’est ici