Creating RESTful Web Service is so simple using Django Tastypie. It's pretty much just about registering which model you want to expose. Even more amazing is that filtering feature. Read here to get more info about it.
I decided to create Java frontend to replace the existing, which uses Python Gtk. To keep with the existing look and feel I use java-gnome binding. The transition from python gtk to java-gnome is quite smooth. Java-gnome has such a good design, so the only thing that I need to for the transition is just adapting to the java paradigm, which is wonderful.
To get the JSON object from the web service, I chose Apache HTPClient, just to make things simple. I know that there are a lot of java REST client, such as restlet, jersey, etc. I stick with the simplest one.
The next thing is to figure out how to transform JSON result from the RESTful web service to POJO. Here comes GSON to the rescue. I did not want to use python attribute name convention in my java codes. So, this one I need to solve. Fortunately, GSON comes with clever and handy feature named FieldNamingPolicy. Obviously they have really good experience in different programming language hence this feature available.
To give example on how to use it, taken from the site:
SomeObject someObject = new SomeObject("first", "second");
Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create();
String jsonRepresentation = gson.toJson(someObject);
System.out.println(jsonRepresentation);
Awesome! That simple and you can keep the java attribute naming convention and make your java codes look good.
Saturday, August 4, 2012
Friday, July 6, 2012
Debian with Ubuntu Fonts
Here is how I configure my Debian system to use the same font config as Ubuntu.
Simply download, fontconfig-config_2.8.0-3ubuntu9_all.deb. The link will take you to Ubuntu 12.04 fontconfig-config deb package.
After you saved that deb file, extract it to get its contents:
$ dpkg-deb -x fontconfig-config_2.8.0-3ubuntu9_all.deb /tmp/extract/
then replace the content of Debian's /etc/fonts/* with data from /tmp/extract/etc/fonts/*
$ sudo cp -r /tmp/extract/etc/fonts/* /etc/fonts/
Simply download, fontconfig-config_2.8.0-3ubuntu9_all.deb. The link will take you to Ubuntu 12.04 fontconfig-config deb package.
After you saved that deb file, extract it to get its contents:
$ dpkg-deb -x fontconfig-config_2.8.0-3ubuntu9_all.deb /tmp/extract/
then replace the content of Debian's /etc/fonts/* with data from /tmp/extract/etc/fonts/*
$ sudo cp -r /tmp/extract/etc/fonts/* /etc/fonts/
Logout and log back in to see the change.
Thursday, May 3, 2012
Using CSS to Make Your HTML Page Printer Friendly
Besides for styling for regular media (such as screen / pc monitor), css can also be used to make the web layout suitable for printing.
Perhaps you have a web page which has logo, menu, navigation, videos, and other things on it. Also there is a table or other information which you actually need. You would not want those irrelevant elements cluttering all over when you print it, right?
To solve it, simple use specific stylesheet for printing purpose and define it for "print" media. Here is an example of using external stylesheet for "print" media:
Next step is to eliminate those unnecessary elements using display: none. Here's an example:
div#menu {
display: none;
}
Now, as a bonus, I found out a way to make the default printing orientation as landscape. Here's it is:
@page {
size: landscape;
}
Another interesting thing that I found during my work is that !important rule defined in other css for any other media other than "print" will also effects the "print" media layout. I did not expect that, since I assume that !important rules defined for "screen" media, for example, would only effect that particular media. So, make sure you override the !important rule in the "print" css.
Perhaps you have a web page which has logo, menu, navigation, videos, and other things on it. Also there is a table or other information which you actually need. You would not want those irrelevant elements cluttering all over when you print it, right?
To solve it, simple use specific stylesheet for printing purpose and define it for "print" media. Here is an example of using external stylesheet for "print" media:
Next step is to eliminate those unnecessary elements using display: none. Here's an example:
div#menu {
display: none;
}
Now, as a bonus, I found out a way to make the default printing orientation as landscape. Here's it is:
@page {
size: landscape;
}
Another interesting thing that I found during my work is that !important rule defined in other css for any other media other than "print" will also effects the "print" media layout. I did not expect that, since I assume that !important rules defined for "screen" media, for example, would only effect that particular media. So, make sure you override the !important rule in the "print" css.
Monday, April 9, 2012
Django Blog Zinnia Limit User to Own Entry/Post
I just need a simple yet flexible django based blog application, and found django-blog-zinnia. I really admire how simple it is. The only major adjustment that I need is to limit user to his/her own blog entry/post.
Combining basic django (admin) knowledge with soome info from django-blog-zinnia documentation, I found a simple solution. Of course this is related with django-blog-zinnia's admin interface, and there is a documentation about how to make some modification to the EntryAdmin. Read more from here.
The idea is to create a django application and create admin.py on that app's top level directory (the same location with models.py).
Here is how my admin.py codes look like:
############# admin.py #################
from django.contrib import admin
from zinnia.models import Entry
from zinnia.admin.entry import EntryAdmin
class FilteredEntryAdmin(EntryAdmin):
def queryset(self, request):
qs = super(FilteredEntryAdmin, self).queryset(request)
if request.user.is_superuser:
return qs
return qs.filter(authors=request.user)
admin.site.unregister(Entry)
admin.site.register(Entry, FilteredEntryAdmin)
############# end of admin.py #################
Remember to add the newly created app in settings.py INSTALLED_APPS, and make sure you put it below zinnia.
Django's documentation is quite complete and comprehensive. To get more information about ModelAdmin, queryset, etc, go to this link. From there I got the idea of overriding the queryset and use filter to limit the entry based on user.
Combining basic django (admin) knowledge with soome info from django-blog-zinnia documentation, I found a simple solution. Of course this is related with django-blog-zinnia's admin interface, and there is a documentation about how to make some modification to the EntryAdmin. Read more from here.
The idea is to create a django application and create admin.py on that app's top level directory (the same location with models.py).
Here is how my admin.py codes look like:
############# admin.py #################
from django.contrib import admin
from zinnia.models import Entry
from zinnia.admin.entry import EntryAdmin
class FilteredEntryAdmin(EntryAdmin):
def queryset(self, request):
qs = super(FilteredEntryAdmin, self).queryset(request)
if request.user.is_superuser:
return qs
return qs.filter(authors=request.user)
admin.site.unregister(Entry)
admin.site.register(Entry, FilteredEntryAdmin)
############# end of admin.py #################
Remember to add the newly created app in settings.py INSTALLED_APPS, and make sure you put it below zinnia.
Django's documentation is quite complete and comprehensive. To get more information about ModelAdmin, queryset, etc, go to this link. From there I got the idea of overriding the queryset and use filter to limit the entry based on user.
(pip) Install Python Imaging Library (PIL)
I had a problem when I tried installing Python Imaging Library (PIL) version 1.1.7, within virtualenv, using pip. Actually, there was not any errors raised during installation, but when I used it in Django for the ImageField, I kept getting 'Upload a valid image. The file you uploaded was either not an image or a corrupted image' error message.
I figured out that the problem is due to the manual installation of PIL using pip, instead of using Debian/Ubuntu's apt-get.
So, the simplest solution would be using the
$ sudo apt-get install python-imaging
The thing is, I need PIL installed in my virtualenv environment. Getting some info from this link, I figured out a way to install PIL within virtualenv. In order to do that, some changes need to be done inside the PIL's setup.py script.
Step 0: sudo apt-get install libjpeg62 libjpeg62-dev
Step 1: get PIL source kit (here).
Step 2: untar, unzip the file
Step 3: locate setup.py from Step 2, and open that file for editing
Step 4: around line 200 (you should see other paths around there), add the following
add_directory(library_dirs, "/usr/lib/i386-linux-gnu") # for 64 bit replace with /usr/lib/x86_64-linux-gnu
Step 5: tar and gzip the modified PIL source.
Step 6: activate your virtualenv, should you need it
Step 7: pip install
I made some test with my django-blog-zinnia project, by uploading some pictures and no more error messages.
I figured out that the problem is due to the manual installation of PIL using pip, instead of using Debian/Ubuntu's apt-get.
So, the simplest solution would be using the
$ sudo apt-get install python-imaging
The thing is, I need PIL installed in my virtualenv environment. Getting some info from this link, I figured out a way to install PIL within virtualenv. In order to do that, some changes need to be done inside the PIL's setup.py script.
Step 0: sudo apt-get install libjpeg62 libjpeg62-dev
Step 1: get PIL source kit (here).
Step 2: untar, unzip the file
Step 3: locate setup.py from Step 2, and open that file for editing
Step 4: around line 200 (you should see other paths around there), add the following
add_directory(library_dirs, "/usr/lib/i386-linux-gnu") # for 64 bit replace with /usr/lib/x86_64-linux-gnu
Step 5: tar and gzip the modified PIL source.
Step 6: activate your virtualenv, should you need it
Step 7: pip install
I made some test with my django-blog-zinnia project, by uploading some pictures and no more error messages.
Thursday, April 5, 2012
Disable Network Manager and Use Script to Connect to WPA2 Wireless Connection
I would like some of the computers at my work to be able to connect to a specific wireless access point with WPA2 encryption and keep trying to connect (indefinitely) if the Access Point (AP) is not on yet. When the AP is up and running, those computers should be able to connect without any human interaction. There is a possibility that the AP is turned off for a while or restarted, due to some reason, and those computers should be able to reconnect automatically when the AP is back online again.
The default behavior on Ubuntu and Fedora is a little bit different (but far from my need). When a computer is already connected to AP, and the AP suddenly becomes unavailable for a while, there will be a WEP/WPA password dialog. User has to click the connect button again and if the AP is not available yet it will keep showing password dialog. When the user click cancel button, it will stop trying to connect to that particular AP.
Finally I figured out how to set the computer to keep trying to connect indefinitely and no matter how many times the AP becomes unavailable, it will keep doing it until it is (re)connected.
Here is how I did it:
The main issue is with the default behavior of the NetworkManager. I have not found any NetworkManager configuration so I could set it the way I explained earlier. Please let me know if someone knows how to do the exact thing that I need using NetworkManager.
The first step is to disable NetworkManager:
To disable it temporarily, use the following command:
$ sudo service network-manager stop
To permanently disable NetworkManager, do the following:
edit /etc/init/network-manager.conf
comment "start on...", so it would be like the following:
# start on
Next step is to create a wpa supplicant configuration file, do the following:
Create "/etc/wpa_supplicant/wpa_supplicant.conf" file and make it executable.
Put the following configurations inside it:
########### wpa_supplicant.conf ############
ctrl_interface=/var/run/wpa_supplicant
network={
ssid="your_wlan_essid"
scan_ssid=1
key_mgmt=WPA-PSK
psk="your_wpa2_passphrase"
}
########### end of wpa_supplicant.conf ############
Now, I am not really comfortable to put my plain text wpa2 passphrase inside the config file. So, I use the following method:
$ wpa_passphrase your_wlan_essid your_plain_text_passphrase
Use the output of the command above for your encrypted passphrase
Third step is to edit the /etc/network/interfaces configuration file.
Here is how my config file looks:
############# /etc/network/interfaces ###########
auto lo
iface lo inet loopback
auto wlan0
iface wlan0 inet dhcp
wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf
wpa-action /etc/wpa_supplicant/action_wpa.sh
############# end of /etc/network/interfaces ###########
Notice that /etc/wpa_supplicant/wpa_supplicant.conf is the configuration file we just created previously, and /etc/wpa_supplicant/action_wpa.sh should exist from the default ubuntu (11.10) installation.
Now for the test:
Test #1
Make sure your AP is on.
Restart your computer, and after you logged in, you should be connected to AP.
Test #2
Make sure your AP is off.
Restart your computer, and after you logged in, you should not be connected to AP.
Turn on your AP.
Not long after that your computer should be connected to AP.
Test #2
Make sure your AP is on and your computer is connected to AP.
Turn off your AP.
Your computer should be disconnected from AP.
Wait for a while to be sure that your computer is not connected and the retry connection attempt failed.
Turn back your AP on.
Not long after that your computer should be reconnected to AP.
Now, this is exactly what I want for my setting at work.
The default behavior on Ubuntu and Fedora is a little bit different (but far from my need). When a computer is already connected to AP, and the AP suddenly becomes unavailable for a while, there will be a WEP/WPA password dialog. User has to click the connect button again and if the AP is not available yet it will keep showing password dialog. When the user click cancel button, it will stop trying to connect to that particular AP.
Finally I figured out how to set the computer to keep trying to connect indefinitely and no matter how many times the AP becomes unavailable, it will keep doing it until it is (re)connected.
Here is how I did it:
The main issue is with the default behavior of the NetworkManager. I have not found any NetworkManager configuration so I could set it the way I explained earlier. Please let me know if someone knows how to do the exact thing that I need using NetworkManager.
The first step is to disable NetworkManager:
To disable it temporarily, use the following command:
$ sudo service network-manager stop
To permanently disable NetworkManager, do the following:
edit /etc/init/network-manager.conf
comment "start on...", so it would be like the following:
# start on
Next step is to create a wpa supplicant configuration file, do the following:
Create "/etc/wpa_supplicant/wpa_supplicant.conf" file and make it executable.
Put the following configurations inside it:
########### wpa_supplicant.conf ############
ctrl_interface=/var/run/wpa_supplicant
network={
ssid="your_wlan_essid"
scan_ssid=1
key_mgmt=WPA-PSK
psk="your_wpa2_passphrase"
}
########### end of wpa_supplicant.conf ############
Now, I am not really comfortable to put my plain text wpa2 passphrase inside the config file. So, I use the following method:
$ wpa_passphrase your_wlan_essid your_plain_text_passphrase
Use the output of the command above for your encrypted passphrase
Third step is to edit the /etc/network/interfaces configuration file.
Here is how my config file looks:
############# /etc/network/interfaces ###########
auto lo
iface lo inet loopback
auto wlan0
iface wlan0 inet dhcp
wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf
wpa-action /etc/wpa_supplicant/action_wpa.sh
############# end of /etc/network/interfaces ###########
Notice that /etc/wpa_supplicant/wpa_supplicant.conf is the configuration file we just created previously, and /etc/wpa_supplicant/action_wpa.sh should exist from the default ubuntu (11.10) installation.
Now for the test:
Test #1
Make sure your AP is on.
Restart your computer, and after you logged in, you should be connected to AP.
Test #2
Make sure your AP is off.
Restart your computer, and after you logged in, you should not be connected to AP.
Turn on your AP.
Not long after that your computer should be connected to AP.
Test #2
Make sure your AP is on and your computer is connected to AP.
Turn off your AP.
Your computer should be disconnected from AP.
Wait for a while to be sure that your computer is not connected and the retry connection attempt failed.
Turn back your AP on.
Not long after that your computer should be reconnected to AP.
Now, this is exactly what I want for my setting at work.
Subscribe to:
Posts (Atom)