I've been a Firefox user for a long time.
After Google Chrome has been published I decided to check it out.
After 1 day I had to switch back to Firefox.
The reason?
https://addons.mozilla.org/firefox/addon/10 (Firefox AdBlock plugin)
It's IMPOSSIBLE to watch the web without this plugin.
Flash plugins everywhere ... This is horrible.
People! Use this plugin, do not let manipulate and waste your time on
pages using this harmful type of advertising.
Boycote it! Let others know to not use it!
Admins, block ad hosts too!
I do not mean to fight with ads. I can watch ads, as long as it does not eat 100% of my CPU and some fuckin* flash poup appears! AARGH!!
THIS IS CRAZY!
Thursday, October 16, 2008
Thursday, October 9, 2008
django-tables generic way for displaying tables (pagination included)
In thnis short post I would like to let you know about the great projectdjango-tables.
You can read more about it at:
http://blog.elsdoerfer.name/2008/07/09/django-tables-a-queryset-renderer/
In a couple of words it lets you:
- display the table using one template which lets you sort & paginate easily (filtering in plans!)
By reading the text below you will find out how to create table with sort & pagination quickly.
In usage it's very similar do django newforms (forms as of 1.0)
Example: (views.py)
class MyTable(tables.ModelTable):
class Meta:
model = SomeModel
def view_something(request):
table = MyTable(queryset, order_by=request.GET.get('sort','some_field))
return render_to_response('templates/table.html', {'table': table, 'rows' : table.rows})
# we need to return table, and rows separately to use django-pagination (though django-tables provides its own pagination mechanism)
Now let's get to template:
{% load pagination_tags %}
{% autopaginate rows 10 %}
{% for column in table.columns %}
{% endfor %}
{% for row in rows %}
{% for value in row %}
{% endfor %}
{% if column.sortable %} {{ column }} {% if column.is_ordered_reverse %} ![]() {% else %} ![]() {% endif %} {% else %} {{ column }} {% endif %} | |
|---|---|
| {{ value }} | {% endfor %} |
That's it!
This way you get generic way of displaying tables + sorting ability.
By default, django-tables takes field names for table headers when using ModelTable (verbose_name is in plans as well).
You can exclude displaying fields too!
As for now, you can specify your own names in MyTable class.
Let's get back to our class:
class MyTable(tables.ModelTable):
class Meta:
model = SomeModel
field1 = tables.Column(name="Name")
field_we_want_to_exclude = tables.Column(visiable=Fale, sortable=False)
NOTE:
Django tables is also aware of ForeignKey relations.
Check it out!
Monday, March 3, 2008
Django ModelForm - replacement for form_for_model & form_for_instance
Each commit, Django gets more amazing.
I wrote about newforms library before. The library was a big step in Django form displaying and validating.
The first approach was to use forms.form_for_model() and forms.form_for_instance() respectively.
As Django programmer I found this a little confusing. Both were similar. The only difference was that form_for_instance() took an object instance for saving instead
of creating a new one. Recently django developers came up with a great idea - forms.ModelForm which combines both into one. It's great!
Just take a look at the example below.
Assume you want to create a new view function for creating & editing an object.
You only want to edit 3 fields (name, last_name, status). Also, you've created a
customized field type for "status", and want to use that.
Scenario #1: (forms.form_for_model && forms.form_for_instance)
You could create your own form_for_model & form_for_instance subclass (using forms.BaseForm for example), but it would be too complicated. Hope you don't use this form often :-)
Scenario #2 (ModelForm)
1. Longer version.
2. Shorter version.
We are using one form class for editing & creating objects.
We can also subclass CustomerModelForm and edit/change the way the form looks
and behave (by adding field clean() method.
Django forms library looks better each day :-)
I wrote about newforms library before. The library was a big step in Django form displaying and validating.
The first approach was to use forms.form_for_model() and forms.form_for_instance() respectively.
As Django programmer I found this a little confusing. Both were similar. The only difference was that form_for_instance() took an object instance for saving instead
of creating a new one. Recently django developers came up with a great idea - forms.ModelForm which combines both into one. It's great!
Just take a look at the example below.
Assume you want to create a new view function for creating & editing an object.
You only want to edit 3 fields (name, last_name, status). Also, you've created a
customized field type for "status", and want to use that.
Scenario #1: (forms.form_for_model && forms.form_for_instance)
def f_callback(field, **kwargs):
if field.name == "status":
return MyStatusField(**kwargs)
else:
return field.formfield(**kwargs)
def create_edit_customer(request, customer_id=None):
# check if object_id is None and if object exists
if object_id is None:
CustomerForm = forms.form_for_model(Customer,
formfield_callback=f_callback,
fields=('name','last_name','status')
else:
customer = get_object_or_404(Customer, id=customer_id)
CustomerForm = forms.form_for_instance(customer,
formfield_callback=f_callback,
fields=('name','last_name','status')
if request.method == "POST":
form = CustomerForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect('customer/added/')
else:
form = CustomerForm()
return render_to_response("customers/customer_form.html", {'form' : form })
You could create your own form_for_model & form_for_instance subclass (using forms.BaseForm for example), but it would be too complicated. Hope you don't use this form often :-)
Scenario #2 (ModelForm)
1. Longer version.
class CustomerModelForm(forms.ModelForm):
class Meta:
model = Customer
fields = ('name','last_name','status')
status = MyCustomerField()
def create_edit_customer(request, customer_id=None):
if customer_id is not None:
customer = get_object_or_404(Customer, id=customer_id)
else:
customer = None
if request.method == "POST":
form = CustomerModelForm(data=request.POST, instance=customer)
if form.is_valid():
form.save()
return HttpResponseRedirect("/customer/added/")
else:
form = CustomerModelForm(instance=customer)
return render_to_response("customers/customer_form.html", {'form' : form })
2. Shorter version.
class CustomerModelForm(forms.ModelForm):
class Meta:
model = Customer
fields = ('name','last_name','status')
status = MyCustomerField()
def create_edit_customer(request, customer_id=None):
if customer_id is not None:
customer = get_object_or_404(Customer, id=customer_id)
else:
customer = None
form = CustomerModelForm(data=request.POST or None, instance=customer)
if form.is_valid():
form.save()
return HttpResponseRedirect("/customer/added/")
return render_to_response("customers/customer_form.html", {'form' : form }
We are using one form class for editing & creating objects.
We can also subclass CustomerModelForm and edit/change the way the form looks
and behave (by adding field clean() method.
Django forms library looks better each day :-)
Sunday, March 2, 2008
Vote for Gdynia in Monopoly Game
I was born in Gdynia, I grew up in Gdynia.. and I am happy to live in Gdynia.
Now it's chance for anybody to vote for Gdynia in the Worldwide Monopoly
city competition.
Log in at:
http://www.monopolyworldvote.com/pl_PL/world and vote.
You can give your vote once a day.
Thanks!
---
Urodziłem się w Gdyni, dorastałem w Gdyni i nadal mieszkam w Gdyni.
To cudowne miasto ma teraz niepowtarzalną okazję zaistnieć w
ogólnoświatowej wersji gry Monopol, w którą grają miliony
ludzi na świecie.
To niepowtarzalna szansa dla promocji naszego miasta, ale też i kraju,
czy też rejonu.
Oddaj swój głos na stronie:
http://www.monopolyworldvote.com/pl_PL/world
Możesz głosować codziennie 1 raz!
Dzięki !
Now it's chance for anybody to vote for Gdynia in the Worldwide Monopoly
city competition.
Log in at:
http://www.monopolyworldvote.com/pl_PL/world and vote.
You can give your vote once a day.
Thanks!
---
Urodziłem się w Gdyni, dorastałem w Gdyni i nadal mieszkam w Gdyni.
To cudowne miasto ma teraz niepowtarzalną okazję zaistnieć w
ogólnoświatowej wersji gry Monopol, w którą grają miliony
ludzi na świecie.
To niepowtarzalna szansa dla promocji naszego miasta, ale też i kraju,
czy też rejonu.
Oddaj swój głos na stronie:
http://www.monopolyworldvote.com/pl_PL/world
Możesz głosować codziennie 1 raz!
Dzięki !
Friday, February 29, 2008
FreeBSD 7.0 arrived
FreeBSD 7.0 offers new great features. You can read about them all here
With this release we can see a huge performance
improvements. Just take a look at these MySQL tests! It looks very promising.
It would be great if ULE scheduler was stable enough to be included in 7.1 release.
During my work at the company where MySQL was widely used, I had to use linuxthreads
package to get similar to linux performance (well, that's because we used FreeBSD 4.X then). Linux (mostly 2.6) is treated as a better
Operating system for MySQL. Is it high time to change it? :-). Go FreeBSD!
Take a look at graphs at:
http://people.freebsd.org/~kris/scaling/mysql.html
With this release we can see a huge performance
improvements. Just take a look at these MySQL tests! It looks very promising.
It would be great if ULE scheduler was stable enough to be included in 7.1 release.
During my work at the company where MySQL was widely used, I had to use linuxthreads
package to get similar to linux performance (well, that's because we used FreeBSD 4.X then). Linux (mostly 2.6) is treated as a better
Operating system for MySQL. Is it high time to change it? :-). Go FreeBSD!
Take a look at graphs at:
http://people.freebsd.org/~kris/scaling/mysql.html
Monday, February 25, 2008
Some very usable django apps
I was looking for some easy to plug-in django apps
for my new service.
Here are some I decided to use:
django-tagging
django-registration
django-threadedcomments
django-voting
They seem to be rock stable, and easy to use.
Check back soon for more info about the new website.
for my new service.
Here are some I decided to use:
django-tagging
django-registration
django-threadedcomments
django-voting
They seem to be rock stable, and easy to use.
Check back soon for more info about the new website.
Friday, June 15, 2007
[EN] FreeBSD QOS with FreeBSD DUMMYNET
The latest released FreeBSD version 6.2 comes with 3 firewall systems:
- pf (ported from OpenBSD)
- ipfw
- ipfilter
All these three are stable as of this release. I've recently needed to run a QOS system, and chosen
ipfw "DUMMYNET" for this purpose.
My network is about couple hundreds computers and I needed limit bandwidth for each user.
I chose DUMMYNET because of it's simplicity, and "dynamic pipe" creation. I know "pf" (especially HFSC alghoritm) is a good solution too, but natively it supports up to 64 queues
per interface, and you need to patch the source in order to enable more. It's safe to use hundreds of queues, but I simply don't like patching.. (at least by now).
DUMMYNET provides FreeBSD users with dynamic pipe creation.
Suppose you want to create a new 256Kbit pipe for incoming, and 128Kbit pipe for outgoing traffic.
# ipfw pipe 1 config bw 256Kbit/s mask dst-addr 0xffffffff
# ipfw pipe 1 config bw 128Kbit/s mask src-addr 0xffffffff
Now, you need to put the traffic into these pipes.
# ipfw add pipe 1 ip from any to 192.168.0.0/24, 192.168.1.0/24
# ipfw add pipe 2 ip from 192.168.0.0/24, 192.168.1.0/24 to any
By these 4 lines of code you will get hunderds of pipes for each ip in the network for
both incoming and outgoing traffic.
You could write it this way as well:
# ipfw pipe 1 config bw 256Kbit/s
# ipfw pipe 2 config bw 256Kbit/s
...
# ipfw pipe 345 config bw 256Kbit/s
and appropriate rules:
# ipfw add pipe 1 ip from any to 192.168.0.2
# ipfw add pipe 2 ip from any to 192.168.0.3
....
# ipfw add pipe 345 ip from any t0 192.168.1.23
I think the first solution is better!
Now that we stand with another problem - some users have more bandwidth enabled, some less.
You could write pipes with mask-src (dynamic), and put hosts into these.. which would cause lots of rules written.
ipfw (ipfw2 for FreeBSD 4.X) comes with lookup tables, which are extremely fast!
There are 2 values stored in each record of the table:
ip address or network, integer
To create a new table and put the record you would:
# ipfw table 1 add 192.168.0.2 23
# ipfw table 1 add 192.168.0.3,345
These 2nd values lets filter by these in the rules.
# ipfw add allow ip from table\(1\,23) to any # ( = ipfw add allow ip from 192.168.0.2 to any)
Now, in order to create more complex ruleset for pipe assigning look at the example below:
# incoming traffic
# ipfw pipe 1 config bw 1024Kbit/s mask dst-addr 0xffffffff
# ipfw pipe 2 config bw 512Kbit/s mask dst-addr 0xffffffff
# ipfw pipe 3 config bw 256Kbit/s mask dst-addr 0xffffffff
# outgoing traffic
# ipfw pipe 11 config bw 1024Kbit/s mask src-addr 0xffffffff
# ipfw pipe 12 config bw 512Kbit/s mask src-addr 0xffffffff
# ipfw pipe 13 config bw 256Kbit/s mask src-addr 0xffffffff
# Create 2 lookup tables, one with values (IP,INCOMING_BANDWIDTH), second with (IP, OUTGOING_BANDWIDTH)
# TABLE 1 (incoming)
# ipfw table 1 add 192.168.0.2 1024
# ipfw table 1 add 192.168.0.3 1024
# ipfw table 1 add 192.168.1.0/24 512 # each host in network 192.168.1.0/24 gets 512 Kbit/s)
....
# ipfw table 1 add 192.168.2.23 256
# TABLE 2 (outgoing)
# ipfw table 2 add 192.168.0.2 512
# ipfw table 2 add 192.168.0.3 512
# ipfw table 2 add 192.168.1.0/24 256 # yeah, network 192.168.1.0 got too much traffic last month, now they will get less
# RULES
# rule for incoming pipe 1024kbit (pipe #1)
# ipfw add pipe 1 ip from any to table\(1,1024\)
# rule for incoming pipe 512 (pipe #2)
# ipfw add pipe 2 ip from any to table\(1,512\)
# rule for incoming pipe 256 (pipe #3)
# ipfw add pipe 3 ip from any to table\(1,256\)
# outgoing traffic
# fule for outgoing pipe 1024Kbit (pipe #11)
# ipw add pipe 11 ip from table\(2,1024\) to any
# rule for outgoing pipe 512Kbit (pipe #12)
# ipfw add pipe 12 ip from table\(2,512\) to any
# rule for outgoing pipe 256Kbit (pipe #13)
# ipfw add pipe 13 ip from table\(2,256\) to any
That's all! No more hundreds of static pipes, hundreds of rules.
Keep in mind, that this example is a strcitly pipe related.
Depending on the NAT you are using, make sure these rules are evaluated
before being nated (if using "natd") for outgoing traffic, and after being nated (if using "natd")
for incoming traffic.
You can get this by using rules like:
# ipfw add 100 divert natd ip from any to any in recv $OUTGOING_INTERFACE
Put all the pipe rules here
# ipfw add 4000 divert natd ip from any to any out xmit $OUTGOING_INTERFACE
NOTE:
1. Remember to set sysctl variable "net.inet.ip.fw.one_pass" to 0, which prevents packets from
not being reinjected into the firewall.
2. You may also want to put a "skipto" rule after ip to pipe assigning (if you are using lots of such rules).
3. Personally I'm using ipnat+dummynet, which works fine for bigger networks. natd is not
fast, as it works in userland. ipnat is entirely kernel attached, so it's faster.
4. If using FreeBSD 4.x make sure you apply the ipfw/ipfilter order patch (lookup for "ipfw ipnat order patch" in google)
5. Assign appropriate "queue" values for each pipe depending on the pipe bw parameter.
6. In FreeBSD 5.5? 6.X you can even simplify the ruleset, read about "tablearg" parameter for ipfw!
7. Tune all "net.inet.ip.dummynet.*" sysctls if there are lots of hosts in your network, and there's a danger of creating lots of dynamic pipes.
8. Some guys use pf+dummynet for FreeBSD 6.X nat. I think it's tricky too, as pf is a great firewall too!
Some useful links:
http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/firewalls-ipfw.html
http://info.iet.unipi.it/~luigi/ip_dummynet/
- pf (ported from OpenBSD)
- ipfw
- ipfilter
All these three are stable as of this release. I've recently needed to run a QOS system, and chosen
ipfw "DUMMYNET" for this purpose.
My network is about couple hundreds computers and I needed limit bandwidth for each user.
I chose DUMMYNET because of it's simplicity, and "dynamic pipe" creation. I know "pf" (especially HFSC alghoritm) is a good solution too, but natively it supports up to 64 queues
per interface, and you need to patch the source in order to enable more. It's safe to use hundreds of queues, but I simply don't like patching.. (at least by now).
DUMMYNET provides FreeBSD users with dynamic pipe creation.
Suppose you want to create a new 256Kbit pipe for incoming, and 128Kbit pipe for outgoing traffic.
# ipfw pipe 1 config bw 256Kbit/s mask dst-addr 0xffffffff
# ipfw pipe 1 config bw 128Kbit/s mask src-addr 0xffffffff
Now, you need to put the traffic into these pipes.
# ipfw add pipe 1 ip from any to 192.168.0.0/24, 192.168.1.0/24
# ipfw add pipe 2 ip from 192.168.0.0/24, 192.168.1.0/24 to any
By these 4 lines of code you will get hunderds of pipes for each ip in the network for
both incoming and outgoing traffic.
You could write it this way as well:
# ipfw pipe 1 config bw 256Kbit/s
# ipfw pipe 2 config bw 256Kbit/s
...
# ipfw pipe 345 config bw 256Kbit/s
and appropriate rules:
# ipfw add pipe 1 ip from any to 192.168.0.2
# ipfw add pipe 2 ip from any to 192.168.0.3
....
# ipfw add pipe 345 ip from any t0 192.168.1.23
I think the first solution is better!
Now that we stand with another problem - some users have more bandwidth enabled, some less.
You could write pipes with mask-src (dynamic), and put hosts into these.. which would cause lots of rules written.
ipfw (ipfw2 for FreeBSD 4.X) comes with lookup tables, which are extremely fast!
There are 2 values stored in each record of the table:
ip address or network, integer
To create a new table and put the record you would:
# ipfw table 1 add 192.168.0.2 23
# ipfw table 1 add 192.168.0.3,345
These 2nd values lets filter by these in the rules.
# ipfw add allow ip from table\(1\,23) to any # ( = ipfw add allow ip from 192.168.0.2 to any)
Now, in order to create more complex ruleset for pipe assigning look at the example below:
# incoming traffic
# ipfw pipe 1 config bw 1024Kbit/s mask dst-addr 0xffffffff
# ipfw pipe 2 config bw 512Kbit/s mask dst-addr 0xffffffff
# ipfw pipe 3 config bw 256Kbit/s mask dst-addr 0xffffffff
# outgoing traffic
# ipfw pipe 11 config bw 1024Kbit/s mask src-addr 0xffffffff
# ipfw pipe 12 config bw 512Kbit/s mask src-addr 0xffffffff
# ipfw pipe 13 config bw 256Kbit/s mask src-addr 0xffffffff
# Create 2 lookup tables, one with values (IP,INCOMING_BANDWIDTH), second with (IP, OUTGOING_BANDWIDTH)
# TABLE 1 (incoming)
# ipfw table 1 add 192.168.0.2 1024
# ipfw table 1 add 192.168.0.3 1024
# ipfw table 1 add 192.168.1.0/24 512 # each host in network 192.168.1.0/24 gets 512 Kbit/s)
....
# ipfw table 1 add 192.168.2.23 256
# TABLE 2 (outgoing)
# ipfw table 2 add 192.168.0.2 512
# ipfw table 2 add 192.168.0.3 512
# ipfw table 2 add 192.168.1.0/24 256 # yeah, network 192.168.1.0 got too much traffic last month, now they will get less
# RULES
# rule for incoming pipe 1024kbit (pipe #1)
# ipfw add pipe 1 ip from any to table\(1,1024\)
# rule for incoming pipe 512 (pipe #2)
# ipfw add pipe 2 ip from any to table\(1,512\)
# rule for incoming pipe 256 (pipe #3)
# ipfw add pipe 3 ip from any to table\(1,256\)
# outgoing traffic
# fule for outgoing pipe 1024Kbit (pipe #11)
# ipw add pipe 11 ip from table\(2,1024\) to any
# rule for outgoing pipe 512Kbit (pipe #12)
# ipfw add pipe 12 ip from table\(2,512\) to any
# rule for outgoing pipe 256Kbit (pipe #13)
# ipfw add pipe 13 ip from table\(2,256\) to any
That's all! No more hundreds of static pipes, hundreds of rules.
Keep in mind, that this example is a strcitly pipe related.
Depending on the NAT you are using, make sure these rules are evaluated
before being nated (if using "natd") for outgoing traffic, and after being nated (if using "natd")
for incoming traffic.
You can get this by using rules like:
# ipfw add 100 divert natd ip from any to any in recv $OUTGOING_INTERFACE
Put all the pipe rules here
# ipfw add 4000 divert natd ip from any to any out xmit $OUTGOING_INTERFACE
NOTE:
1. Remember to set sysctl variable "net.inet.ip.fw.one_pass" to 0, which prevents packets from
not being reinjected into the firewall.
2. You may also want to put a "skipto" rule after ip to pipe assigning (if you are using lots of such rules).
3. Personally I'm using ipnat+dummynet, which works fine for bigger networks. natd is not
fast, as it works in userland. ipnat is entirely kernel attached, so it's faster.
4. If using FreeBSD 4.x make sure you apply the ipfw/ipfilter order patch (lookup for "ipfw ipnat order patch" in google)
5. Assign appropriate "queue" values for each pipe depending on the pipe bw parameter.
6. In FreeBSD 5.5? 6.X you can even simplify the ruleset, read about "tablearg" parameter for ipfw!
7. Tune all "net.inet.ip.dummynet.*" sysctls if there are lots of hosts in your network, and there's a danger of creating lots of dynamic pipes.
8. Some guys use pf+dummynet for FreeBSD 6.X nat. I think it's tricky too, as pf is a great firewall too!
Some useful links:
http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/firewalls-ipfw.html
http://info.iet.unipi.it/~luigi/ip_dummynet/
Subscribe to:
Posts (Atom)

