Monday, March 09, 2009

Django-Notification Creating Notice Types issues

I was setting up Django-Notification for a project, and I was trying to create notice types like it mentions on their wiki . Their wiki says that you should add the following code to your management.py file in your app.

from django.conf import settings
from django.db.models import signals
from django.utils.translation import ugettext_noop as _

if "notification" in settings.INSTALLED_APPS:
from notification import models as notification

def create_notice_types(app, created_models, verbosity, **kwargs):
notification
.create_notice_type("friends_invite", _("Invitation Received"), _("you have received an invitation"))
notification
.create_notice_type("friends_accept", _("Acceptance Received"), _("an invitation you sent has been accepted"))

signals
.post_syncdb.connect(create_notice_types, sender=notification)
else:
print "Skipping creation of NoticeTypes as notification app not found"

After trying lots of different things (dropping database and re syncing,etc) the management file wasn't getting picked up and it was quite annoying.

It turns out that if you have written custom management extensions and you have a management directory under your application it will ignore the management.py file all together. So you need to add the code to the app/management/__init__.py file instead.

Once you have added the files you need to resync (make sure you remove notification_* tables first).

This makes total sense now, and I guess I shouldn't have taken the directions to literaly.

If you still can't get it to work, the other option is to just create a fixture and load the data that way.

Labels: , , ,

Thursday, February 26, 2009

Plesk 8.6 cgi-bin trouble

I recently worked on a project to quickly create a simple cgi-bin script to capture some data from a form on a mostly static website. The script was simple, take the data from the form, and send it via email. The script was written by a co-worker of mine using python. When we went to deploy the script on the server with Plesk 8.6, it was nothing but a pain in the butt.. I have documented some of the things we did below in order to get it working.

Here are the errors that we were getting during the process in no particular order.
  • "target uid/gid (10001/2524 or 2523) mismatch with directory (10001/2524) or program (48/48)"
  • "uid: (10001/cashstarftp) gid: (2524/2524) cmd: mail_script.cgi"
  • "cannot get docroot information (/var/www/vhosts)"
  • "failed to open log file /var/log/httpd/suexec_log"
  • "Premature end of script headers: mail_script.py"

Here are the different steps that we did to resolve the different errors:

SSH in and type the following: "chown root:apache /usr/sbin/suexec"

My permissions were also wrong for the following
/var/log/httpd, should be drwx------ root root

/var/log/httpd/suexec_log, should be -rw-r--r-- root root

/home/httpd/vhosts/your-domain-name.com/statistics, should be dr-xr-x--- root psaserv

/home/httpd/vhosts/your-domain-name.com/cgi-bin should be, drwxr-x--x ftpuser psaserv

As most of you know but just in case scripts in the cgi-bin directory need to be -rwxr-xr-x ftpuser psacln

Replace "ftpuser" with the ftp user name for that domain

And don't forget to restart Apache after making these changes.
There are probably more things that we ended up trying that I didn't document here, so feel free to post how you fixed your issue, so that others can benefit.

Labels: , ,

Wednesday, February 04, 2009

Google's Ajax Libary hosting, the New Web Tracker

A little while ago, I noticed that Google started hosting the most common JavaScript libraries on their CDN. The project is called AJAX Libraries API , and it allows websites to reference these libaries instead of hosting the files themselves. Using a CDN to host your static files isn't anything new, and it provides some nice side effects.
  • Less bandwidth
  • Less space (every little bit helps)
  • Global caching
    • If everyone uses the same file it is more likely they already have the file cached from another site.
  • Faster download
    • Clients get the file from the server closer to them
    • Different servers mean more asynchronous downloads
For more info check out the YSlow page.

At first this sounded great, Google was providing a nice service for free, and everyone benefits. But then I was thinking, what does Google get out of this? With a big company there is always something, even Google.

Then it hit me. How does Google Analytics work? If you don't know, it is pretty simple. All you need to do is insert a small little JavaScript snippet at the bottom of the pages you want to track, and that is it. How is Google analytics different then the new Google Ajax API? Not much, the major difference is that Analytics has a tracking code and the AJAX API doesn't. But that isn't a big deal for Google to get around, they can easily link all views back to the originatly server. So the tracking code isn't needed unless you want to link that back to a user, so that they can view the results.

AJAX API, isn't the only project where they could easily gather information. They also have Google Chart API where they will generate charts for you on the file to display on your website. The big one that most people see everyday is the Google Maps API which allow you to embed google maps onto any website.

If you combine the information they get from all the people visiting thier website, with the information they gather from Google Analytics and all of these free tools that they give away, it is really amazing how much data they have, and how easy it would be to track people.

I'm not a paranoid person, and I could care less if Google wanted to track me, but I can see how some people might be concerned. If they could only use all of this information to track down all of the bad people out there. I don't know if Osama bin laden even has power in his cave, no less internet access, but if he did, watch out. Google's Coming!

Sunday, February 01, 2009

100Boxes.com - Free Online Football Squares Pool Management

I would like to announce the release of a new project I have been working on. 100Boxes.com FREE online Football Squares Pool . I basically took the classic superbowl squares game, that is usually played with paper and spreadsheets and I put it online. I tried to make it as simple as possible for someone to manage their pool, and for people to buy their squares. I started the project pretty late in the season, and unfortunately didn't release it in time for a good test group this year.

I will continue to work on it over the next few months and hopefully it will be 100% ready for the start of the next football season. I hope to add some cool new features that aren't available anywhere else, and should take the typical game, and bring it to the next level.

The game was written in python using the Django framework, and MySQL for a database.

Check it out if you have time, and let me know what you think.

Labels: , , ,

Friday, January 23, 2009

Installing mod_python on Mac OS X Leopard (10.5.x)

Apache2 comes pre installed on Mac OS X Leopard as does Python (2.5). But it doesn't come with mod_python. Here is what you need to do to get it to work.

download the latest file from http://www.apache.org/dist/httpd/modpython/ I downloaded (mod_python-3.3.1.tgz)
$ tar xvzf mod_python-3.3.1.tgz
$ cd mod_python-3.3.1
$ ./configure --with-apxs=/usr/sbin/apxs


Now we need to patch the make file so that it will work correctly. edit src/MakeFile


  • Add -arch x86_64 -arch ppc -arch i386 to the end of the LDFLAGS line.

  • Add -arch x86_64 -arch ppc -arch i386 to the end of the CFLAGS line.

  • Under the mod_python.so target add the following to the line after the -c -Wc,"-arch x86_64" -Wc,"-arch ppc" -Wc,"-arch i386" so my complete line looks like. $(APXS) $(INCLUDES) -c -Wc,"-arch x86_64" -Wc,"-arch ppc" -Wc,"-arch i386" $(SRCS) $(LDFLAGS) $(LIBS)



When that is done:
$ make
$ sudo make install

and then:

$ cd /etc/apache2
$ sudo cp httpd.conf httpd.conf.orig
$ sudo emacs /etc/apache2/httpd.conf

Add the following to the httpd.conf file.

LoadModule python_module libexec/apache2/mod_python.so

Restart apache
$ sudo /usr/sbin/apachectl restart


Test configuration
sudo /usr/sbin/apachectl -t


That is all, if there are no errors, it worked!

Labels: , ,

Wednesday, January 21, 2009

Django Query using value from another field in same table

I came across a query that seemed like it should be pretty easy, but it wasn't.

Suppose you have the following Model Class.
# pseudo code.
class Person(models.Model):
first_name = models.CharField()
last_name = models.CharField()
I would like the query to return all Person's who have the same first_name and last_name

My first guess was to do the following.

person_list = Person.objects.filter(first_name=last_name)

but that doesn't work because it wants to have last_name as a variable.

This is what I ended up doing.

person_list = Person.objects.extra(where=['first_name=last_name']

You could also do it using a models.Manager, if that is what you prefer.

Even though this is an edge case, I'm not sure why Django doesn't support this out of the box, but I am pretty sure there is a pretty good reason.

Labels: , , ,

Saturday, January 17, 2009

Managing Django settings across multiple environments

I don't know about you, but when I typically work on a Django application I have at least two environments (Local and Production), and a lot of times I am working on these projects with at least one other person.

The way that django currently supports project settings is to have all settings in a settings.py file. This works fine if you are working by yourself in one environment, but once you add something else, it makes managing the settings a pain. One solution, which isn't very flexible is to make all environments have the same settings. That solution doesn't usually fly, so I prefer another approach.

I take my settings file and only put settings that will be the same for every install in there. Then I create a local_settings.py file in the same directory and put only settings that are environment specific in that file. Each environment is responsible for providing their own file and setting their own settings.

One important thing to remember, NEVER put the local_settings.py file in source control or else it will just be a matter of time before someone accidentally checks in their file and breaks everyone else. I typically do a Subversion ignore on the file.

I also create a file called local_settings.py.template that has all required settings and examples, and stick that one in source control. When you are setting up a new environment all you need to do is copy the local_settings.py.template and change the values for your ENV. Make sure you keep the local_settings.py.template file up to date.

short example of settings.py and local_settings.py


>> settings.py

import local_settings

# there is more above that I removed

DATABASE_ENGINE = local_settings.DATABASE_ENGINE
DATABASE_NAME = local_settings.DATABASE_NAME
DATABASE_USER = local_settings.DATABASE_USER
DATABASE_PASSWORD = local_settings.DATABASE_PASSWORD
DATABASE_HOST = local_settings.DATABASE_HOST
DATABASE_PORT = local_settings.DATABASE_PORT

# there is more below that I removed



>> local_settings.py

# there is more above that I removed

DATABASE_ENGINE = 'mysql'
DATABASE_NAME = 'dbname'
DATABASE_USER = 'dbusername'
DATABASE_PASSWORD = 'dbpassword'
DATABASE_HOST = ''
DATABASE_PORT = ''

# there is more below that I removed

Labels: