Monthly Archives: January 2011

Compiling Cheetah templates in code

In the application I’m working on we’re using Cheetah as the template infrastructure and I’ve been working with compiled templates built from the command line. A colleague suggested compiling them dynamically

source = Cheetah.Compiler.Compiler(file=config.templatePath(t), moduleName=os.path.splitext(outfile)[0]).moduleDef()
f = open(outpath + outfile, “w+t”)
f.write(source)
f.close()

Installing Google’s python client API and running samples on 2.4.6

At work I’m using Python 2.4.6 and wanted to play around with some of the Google API’s like Buzz and Moderator. Things didn’t quite work out-of-the-box so I thought I’d document my steps here for future reference and in the event anyone else might find it useful.

First, I read over the Python Google API page and found that in order to grab the code I’d first need to install Mercurial.

SteveT:cc strefethen$ sudo port install mercurial
--->  Computing dependencies for mercurial
--->  Dependencies to be installed: curl-ca-bundle python26 db46 gdbm sqlite3
--->  Fetching curl-ca-bundle
--->  Attempting to fetch curl-7.21.2.tar.bz2 from http://distfiles.macports.org/curl
--->  Attempting to fetch certdata-1.70.txt from http://distfiles.macports.org/curl
--->  Verifying checksum(s) for curl-ca-bundle
--->  Extracting curl-ca-bundle
--->  Applying patches to curl-ca-bundle
--->  Configuring curl-ca-bundle
--->  Building curl-ca-bundle
--->  Staging curl-ca-bundle into destroot
--->  Installing curl-ca-bundle @7.21.2_4
--->  Activating curl-ca-bundle @7.21.2_4
--->  Cleaning curl-ca-bundle
--->  Fetching db46
--->  Attempting to fetch patch.4.6.21.1 from http://distfiles.macports.org/db4/4.6.21_6
--->  Attempting to fetch patch.4.6.21.2 from http://distfiles.macports.org/db4/4.6.21_6
--->  Attempting to fetch patch.4.6.21.3 from http://distfiles.macports.org/db4/4.6.21_6
--->  Attempting to fetch patch.4.6.21.4 from http://distfiles.macports.org/db4/4.6.21_6
--->  Attempting to fetch db-4.6.21.tar.gz from http://distfiles.macports.org/db4/4.6.21_6
--->  Verifying checksum(s) for db46
--->  Extracting db46
--->  Applying patches to db46
--->  Configuring db46
--->  Building db46
--->  Staging db46 into destroot
--->  Installing db46 @4.6.21_6
--->  Activating db46 @4.6.21_6
--->  Cleaning db46
--->  Fetching gdbm
--->  Attempting to fetch gdbm-1.8.3.tar.gz from http://mirrors.kernel.org/gnu/gdbm
--->  Verifying checksum(s) for gdbm
--->  Extracting gdbm
--->  Configuring gdbm
--->  Building gdbm
--->  Staging gdbm into destroot
--->  Installing gdbm @1.8.3_3
--->  Activating gdbm @1.8.3_3
--->  Cleaning gdbm
--->  Fetching sqlite3
--->  Attempting to fetch sqlite-autoconf-3070400.tar.gz from http://distfiles.macports.org/sqlite3
--->  Attempting to fetch sqlite-autoconf-3070400.tar.gz from http://www.sqlite.org/
--->  Verifying checksum(s) for sqlite3
--->  Extracting sqlite3
--->  Applying patches to sqlite3
--->  Configuring sqlite3
--->  Building sqlite3
--->  Staging sqlite3 into destroot
--->  Installing sqlite3 @3.7.4_0
--->  Activating sqlite3 @3.7.4_0
--->  Cleaning sqlite3
--->  Fetching python26
--->  Attempting to fetch Python-2.6.6.tar.bz2 from http://distfiles.macports.org/python26
--->  Verifying checksum(s) for python26
--->  Extracting python26
--->  Applying patches to python26
--->  Configuring python26
--->  Building python26
--->  Staging python26 into destroot
--->  Installing python26 @2.6.6_1
--->  Activating python26 @2.6.6_1
To fully complete your installation and make python 2.6 the default,  please run:
 	sudo port install python_select
 	sudo python_select python26
--->  Cleaning python26
--->  Fetching mercurial
--->  Attempting to fetch mercurial-1.7.3.tar.gz from http://distfiles.macports.org/python
--->  Attempting to fetch mercurial-1.7.3.tar.gz from http://mercurial.selenic.com/release/
--->  Verifying checksum(s) for mercurial
--->  Extracting mercurial
--->  Configuring mercurial
--->  Building mercurial
--->  Staging mercurial into destroot
--->  Installing mercurial @1.7.3_0
--->  Activating mercurial @1.7.3_0
--->  Cleaning mercurial

As you can see after a fairly lengthy install I was ready to grab the API sources:

SteveT:work strefethen$ hg clone https://google-api-python-client.googlecode.com/hg/ google-api-python-client
requesting all changes
adding changesets
adding manifests
adding file changes
added 153 changesets with 468 changes to 204 files
updating to branch default
172 files updated, 0 files merged, 0 files removed, 0 files unresolved</pre>
<p>Next, was to setup the Google API python client</p>
<pre class="brush: bash;">SteveT:work strefethen$ cd google-api-python-client/
SteveT:google-api-python-client strefethen$ sudo python setup.py install
Password:
Installing the following packages:
'apiclient', 'apiclient.ext', 'uritemplate'
Loaded setuptools
running install
Checking .pth file support in /Users/strefethen/Library/Python2.4/site-packages/
/opt/local/bin/python -E -c pass
TEST PASSED: /Users/strefethen/Library/Python2.4/site-packages/ appears to support .pth files
running bdist_egg
running egg_info
creating google_api_python_client.egg-info
writing google_api_python_client.egg-info/PKG-INFO
writing top-level names to google_api_python_client.egg-info/top_level.txt
writing dependency_links to google_api_python_client.egg-info/dependency_links.txt
writing manifest file 'google_api_python_client.egg-info/SOURCES.txt'
reading manifest file 'google_api_python_client.egg-info/SOURCES.txt'
writing manifest file 'google_api_python_client.egg-info/SOURCES.txt'
installing library code to build/bdist.macosx-10.6-i386/egg
running install_lib
running build_py
creating build
creating build/lib
creating build/lib/apiclient
copying apiclient/__init__.py -&gt; build/lib/apiclient
copying apiclient/anyjson.py -&gt; build/lib/apiclient
copying apiclient/discovery.py -&gt; build/lib/apiclient
copying apiclient/errors.py -&gt; build/lib/apiclient
copying apiclient/http.py -&gt; build/lib/apiclient
copying apiclient/model.py -&gt; build/lib/apiclient
copying apiclient/oauth.py -&gt; build/lib/apiclient
creating build/lib/apiclient/ext
copying apiclient/ext/__init__.py -&gt; build/lib/apiclient/ext
copying apiclient/ext/appengine.py -&gt; build/lib/apiclient/ext
copying apiclient/ext/authtools.py -&gt; build/lib/apiclient/ext
copying apiclient/ext/django_orm.py -&gt; build/lib/apiclient/ext
creating build/lib/uritemplate
copying uritemplate/__init__.py -&gt; build/lib/uritemplate
creating build/lib/apiclient/contrib
creating build/lib/apiclient/contrib/buzz
copying apiclient/contrib/buzz/future.json -&gt; build/lib/apiclient/contrib/buzz
creating build/lib/apiclient/contrib/latitude
copying apiclient/contrib/latitude/future.json -&gt; build/lib/apiclient/contrib/latitude
creating build/lib/apiclient/contrib/moderator
copying apiclient/contrib/moderator/future.json -&gt; build/lib/apiclient/contrib/moderator
creating build/bdist.macosx-10.6-i386
creating build/bdist.macosx-10.6-i386/egg
creating build/bdist.macosx-10.6-i386/egg/apiclient
copying build/lib/apiclient/__init__.py -&gt; build/bdist.macosx-10.6-i386/egg/apiclient
copying build/lib/apiclient/anyjson.py -&gt; build/bdist.macosx-10.6-i386/egg/apiclient
creating build/bdist.macosx-10.6-i386/egg/apiclient/contrib
creating build/bdist.macosx-10.6-i386/egg/apiclient/contrib/buzz
copying build/lib/apiclient/contrib/buzz/future.json -&gt; build/bdist.macosx-10.6-i386/egg/apiclient/contrib/buzz
creating build/bdist.macosx-10.6-i386/egg/apiclient/contrib/latitude
copying build/lib/apiclient/contrib/latitude/future.json -&gt; build/bdist.macosx-10.6-i386/egg/apiclient/contrib/latitude
creating build/bdist.macosx-10.6-i386/egg/apiclient/contrib/moderator
copying build/lib/apiclient/contrib/moderator/future.json -&gt; build/bdist.macosx-10.6-i386/egg/apiclient/contrib/moderator
copying build/lib/apiclient/discovery.py -&gt; build/bdist.macosx-10.6-i386/egg/apiclient
copying build/lib/apiclient/errors.py -&gt; build/bdist.macosx-10.6-i386/egg/apiclient
creating build/bdist.macosx-10.6-i386/egg/apiclient/ext
copying build/lib/apiclient/ext/__init__.py -&gt; build/bdist.macosx-10.6-i386/egg/apiclient/ext
copying build/lib/apiclient/ext/appengine.py -&gt; build/bdist.macosx-10.6-i386/egg/apiclient/ext
copying build/lib/apiclient/ext/authtools.py -&gt; build/bdist.macosx-10.6-i386/egg/apiclient/ext
copying build/lib/apiclient/ext/django_orm.py -&gt; build/bdist.macosx-10.6-i386/egg/apiclient/ext
copying build/lib/apiclient/http.py -&gt; build/bdist.macosx-10.6-i386/egg/apiclient
copying build/lib/apiclient/model.py -&gt; build/bdist.macosx-10.6-i386/egg/apiclient
copying build/lib/apiclient/oauth.py -&gt; build/bdist.macosx-10.6-i386/egg/apiclient
creating build/bdist.macosx-10.6-i386/egg/uritemplate
copying build/lib/uritemplate/__init__.py -&gt; build/bdist.macosx-10.6-i386/egg/uritemplate
byte-compiling build/bdist.macosx-10.6-i386/egg/apiclient/__init__.py to __init__.pyc
byte-compiling build/bdist.macosx-10.6-i386/egg/apiclient/anyjson.py to anyjson.pyc
byte-compiling build/bdist.macosx-10.6-i386/egg/apiclient/discovery.py to discovery.pyc
byte-compiling build/bdist.macosx-10.6-i386/egg/apiclient/errors.py to errors.pyc
byte-compiling build/bdist.macosx-10.6-i386/egg/apiclient/ext/__init__.py to __init__.pyc
byte-compiling build/bdist.macosx-10.6-i386/egg/apiclient/ext/appengine.py to appengine.pyc
byte-compiling build/bdist.macosx-10.6-i386/egg/apiclient/ext/authtools.py to authtools.pyc
byte-compiling build/bdist.macosx-10.6-i386/egg/apiclient/ext/django_orm.py to django_orm.pyc
byte-compiling build/bdist.macosx-10.6-i386/egg/apiclient/http.py to http.pyc
byte-compiling build/bdist.macosx-10.6-i386/egg/apiclient/model.py to model.pyc
byte-compiling build/bdist.macosx-10.6-i386/egg/apiclient/oauth.py to oauth.pyc
byte-compiling build/bdist.macosx-10.6-i386/egg/uritemplate/__init__.py to __init__.pyc
creating build/bdist.macosx-10.6-i386/egg/EGG-INFO
copying google_api_python_client.egg-info/PKG-INFO -&gt; build/bdist.macosx-10.6-i386/egg/EGG-INFO
copying google_api_python_client.egg-info/SOURCES.txt -&gt; build/bdist.macosx-10.6-i386/egg/EGG-INFO
copying google_api_python_client.egg-info/dependency_links.txt -&gt; build/bdist.macosx-10.6-i386/egg/EGG-INFO
copying google_api_python_client.egg-info/top_level.txt -&gt; build/bdist.macosx-10.6-i386/egg/EGG-INFO
zip_safe flag not set; analyzing archive contents...
apiclient.discovery: module references __file__
creating dist
creating 'dist/google_api_python_client-0.1-py2.4.egg' and adding 'build/bdist.macosx-10.6-i386/egg' to it
removing 'build/bdist.macosx-10.6-i386/egg' (and everything under it)
Processing google_api_python_client-0.1-py2.4.egg
creating /Users/strefethen/Library/Python2.4/site-packages/google_api_python_client-0.1-py2.4.egg
Extracting google_api_python_client-0.1-py2.4.egg to /Users/strefethen/Library/Python2.4/site-packages
Adding google-api-python-client 0.1 to easy-install.pth file
Installed /Users/strefethen/Library/Python2.4/site-packages/google_api_python_client-0.1-py2.4.egg
Processing dependencies for google-api-python-client==0.1
Finished processing dependencies for google-api-python-client==0.1
Setup complete!

Finally, attempt to run the Buzz sample which caused the following error

SteveT:buzz strefethen$ python three_legged_dance.py
Go to the following link in your browser:
https://www.google.com/buzz/api/auth/OAuthAuthorizeToken?scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fbuzz&domain=anonymous&oauth_token=4%2FetZ5lubFdHfPmrqf0pg9IRR_Nury
^CTraceback (most recent call last):
  File "three_legged_dance.py", line 40, in ?
    run(flow, 'buzz.dat')
  File "/Users/strefethen/Library/Python2.4/site-packages/google_api_python_client-0.1-py2.4.egg/apiclient/ext/authtools.py", line 121, in run
    httpd.handle_request()
  File "/opt/local/lib/python2.4/SocketServer.py", line 217, in handle_request
    request, client_address = self.get_request()
  File "/opt/local/lib/python2.4/SocketServer.py", line 373, in get_request
    return self.socket.accept()
  File "/opt/local/lib/python2.4/socket.py", line 161, in accept
    sock, addr = self._sock.accept():

I hadn’t reviewed the code (yeah, not necessarily the brightest idea but hey, it’s Google right?). The above error occurred because I had an application running on port 8080 and didn’t realize the demo was going to require that. After shutting down Hudson I was able to authenticate and move forward.

SteveT:buzz strefethen$ python three_legged_dance.py
Go to the following link in your browser:
https://www.google.com/buzz/api/auth/OAuthAuthorizeToken?scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fbuzz&domain=anonymous&oauth_token=4%2FyDtHZJcU8xD_XP023fUiaKC93wyE
You have successfully authenticated.

However, I ran into another problem which is where the significance of python 2.4 comes in. Attempting to run the buzz.py example I got the following error:

SteveT:buzz strefethen$ python buzz.py
Traceback (most recent call last):
  File "buzz.py", line 75, in ?
    main()
  File "buzz.py", line 37, in main
    activitylist = activities.list(
  File "/Users/strefethen/Library/Python2.4/site-packages/google_api_python_client-0.1-py2.4.egg/apiclient/discovery.py", line 243, in method
    new_base_url = url_result.scheme + '://' + url_result.netloc
AttributeError: 'tuple' object has no attribute 'scheme'

After a few minutes of tangling with Google I found this page which gave me a clue. Specifically, it was dag’s post from 2008/12/9 relating to urlparse and a difference between python 2.4 and 2.5. I opened the above discovery.py file and searched for ‘scheme’ in order to change the reference to something that would work in 2.4. I had to repeat this for ‘netloc’ and ‘path’ with url_result[0], [1], [2] respectively. After saving the file the sample worked as expected.

Granted I’ve probably included a lot more information with respect to the console output above but there are are few things I’m interested in keeping so this is a great place to do just that.

Now, time to go off and have some fun with these Google API’s.

I’m particularly interested in the Moderator API and I’m curious if anyone has written apps to completely replace the Google Moderator UI with a custom design?

Scotts Valley School District Community Poll Results

Screen shot 2011-01-21 at 10.51.50 PMThe results of the recent poll authorized by the Scotts Valley School District were presented to the community on Wednesday January 19th. The district was advised to move forward though only after a sustained community outreach campaign to ensure passage of a parcel tax measure. I won’t rehash all the numbers as they’re covered well in the above link. The base level of support was found to be 68% with a 6% margin of error.

On the up side the survey provides a wealth of information regarding how to best shape a measure to yield the desired results that will be incorporated into all the work that’s already been done to this point.

Bottom Line

These results indicate there’s a lot of hard work yet to be done to reach a point where it’s worth asking the voters of Scotts Valley to support a parcel tax.

With Jerry Brown’s pending “fasten your seatbelts” budget things are likely to get very ugly sooner rather than later.

If you’re not already involved feel free to contact me for ways in which you can help.

How to handle Facebook friend requests?

photo_25250_20101224[1]If you use Facebook I’d guess you too probably have a backlog of friend requests. Having been on Facebook for several years and with 180 friends I’ve reached a point where I struggle to justify letting more people into my status stream. At 180 I already find myself looking back through older updates to find interesting things.

Most of my pending requests have been out-of-the-blue, old high school friends/acquaintances or people whom I’ve met online but never in person and the occasional complete stranger. In some instances I’ve probably been mistaken for one of my brother’s.

The whole notion of a “friend request” implies having to pass judgment on the relationship you have with the requestee which can feel awkward at times even though that awkwardness isn’t really shared. What’s the proper “etiquette” when you’ve been mistaken for a sibling especially for distance relationships?

I’ve noticed my wife and I both let requests we can’t decided immediately on sit in the queue for months at a time with no clear resolution in sight. I haven’t looked but I wonder if there is a way to simply turn off friend requests or perhaps better yet inform the requestee they should contact you directly first?

Personally, I prefer my Facebook social graph be more personal nature and less work/professional using LinkedIn for the latter.

Do you have the same problem? How do you handle friend requests?

[UPDATE] Interesting related article.

Photo credit: FreeDigitalPhotos.net

Setting up a new SVN repository

Since I rarely tend to setup new $g(SVN source repositories) I find myself googling for the syntax of the various commands so I’m writing this post to myself for future reference. I’m starting a new website project at work and needed a new repository created with a few external folder references to another project. After creating a bootstrap set of directories and files from pieces of another project then needed to create the new repository. My folder structure looks like this:

~/work/publishing <- location of new project files/folders

cd ~/work
svn import -m "Initial revision" publishing https://svn/repos/publishing/trunk

The project has two folders which will come from an existing project that won’t be modified in this new project so I’m using svn:externals to reference those folders. I’m not sure this was the best way to do it but since I have several other people who will be using the repository I decided to check it out locally:

cd ~/work
svn co https://svn/repos/publishing pub

Next, I changed to the subfolder where the two external folders are located:

cd ~/work/pub/trunk/application

Then using svn propedit I created two external links though the first time through I got it wrong. Note, the quotes are important here:

SteveT:application strefethen$ svn propset svn:externals 'model https://svn/repost/proj/trunk/application/lib' .
property 'svn:externals' set on '.'
SteveT:application strefethen$ svn up
svn: warning: Error handling externals definition for 'model':
svn: warning: OPTIONS of 'https://svn/repost/proj/trunk/application/model': 200 OK (https://svn)
At revision 24431.

The problem in this case was my mistyping “repos” adding a “t” (bolded above). Next, I made the mistake of using propset twice for two different externals (model and lib) which yielded the following when I tried to update:

SteveT:application strefethen$ svn up
svn: warning: Error handling externals definition for 'model':
svn: warning: URL 'https://web.merchantcircle.com/repos/proj/trunk/application/model' at revision 24431 doesn't exist
At revision 24431.

At this point, I needed to use svn propedit to create two external folder references but I didn’t have any editor set to make these changes which yielded:

SteveT:application strefethen$ svn propedit svn:externals .svn: None of the environment variables SVN_EDITOR, VISUAL or EDITOR are set, and no 'editor-cmd' run-time configuration option was found. I edited my .bash_profile adding an SVN_EDITOR environment variable
mate ~/.bash_profile

Adding:

export SVN_EDITOR="mate -w"

Save an close TextMate. Then source my .bash_profile to get the changes:

source ~/.bash_profile

Now I could finish editing the svn:externals as follows:

svn propedit svn:externals .

The lib external was already defined from my previous propset command so I just needed to the model external making my svn:externals look like this:

lib https://svn/repos/proj/trunk/application/lib
model https://svn/repos/proj/trunk/application/model

Now when I update both external folders are updated:

SteveT:application strefethen$ svn up
Fetching external item into 'model'
External at revision 24431.
Fetching external item into 'lib'
External at revision 24431.
At revision 24431.

Finally, I committed my changes to the application folder for these externals. 

SteveT:application strefethen$ svn commit
Log message unchanged or not specified
(a)bort, (c)ontinue, (e)dit:
c
Sending        application
Committed revision 24432.

Not sure this is going to be helpful for anyone else but I can certainly make use of it in the future.

EdSource Reports Explaining California School’s Financial Situation

As part of keeping abreast of the latest news on California’s public schools I subscribe to EdSource which recently emailed the following with links to various reports on the state of our public schools. 

EdSource logo
EdSource Reports Explain Schools’ Financial Situation

In an attempt to raise public awareness of the severe budget cuts California schools have experienced over the last three years and prevent further declines in school funding, Superintendent of Public Instruction Tom Torlakson today declared a "state of financial emergency in California schools."

EdSource has published three separate reports that explain much of the factual basis behind this declaration, with the most recent being released today.

 

All are free to download!

School Finance Highlights publication imageSchool Finance Highlights 2010-11 *New*

Discusses the budgetary decisions made in 2010-11 that will affect K-12 education this year and going forward. Provides important context for understanding Gov. Brown’s 2011-12 budget proposal and its potential impact on K-12 education.

Dollar being stretchedChallenging Times ~ December 2010 

Examines the financial circumstances of California’s school districts and their actions to cope with the demand to "do more with less." 

How California Ranks cover imageHow California Ranks ~ September 2010

Compares California’s education expenditures and other key indicators with those of other states.

Forum Brochure coverGet updates on the budget at the EdSource Forum

 

California‘s independent Legislative Analyst Mac Taylor will present the most current information on the state budget, including a timely analysis of the governor’s budget proposal and Sacramento budget decisions and actions. 


The Future for Public Education in California 

March 18, 2011  8:30 am – 3 p.m.
Hyatt Regency, Irvine

 

Register today!

EdSource is an independent not-for-profit research organization dedicated to clarifying complex education issues.

Join our listserv

Useful Facebook FQL queries

This is a post for me to aggregate various FQL queries.

Fetch the Facebook like count for a given URL

SELECT like_count FROM link_stat
WHERE url="http://www.stevetrefethen.com/blog/"

Facebook user’s connections

SELECT target_id,target_type,is_following
FROM connection WHERE source_id = facebook_userid

Facebook Share count on a page

SELECT share_count, like_count, comment_count, total_count
FROM link_stat
WHERE url="http://www.stevetrefethen.com/school/"

Fetch open graph id for a url:

SELECT id,type,site FROM object_url
WHERE url="http://www.stevetrefethen.com/school/"

View which groups a user belongs to

SELECT name,gid FROM group
WHERE gid IN (SELECT gid FROM group_member
WHERE uid = facebook_userid)

Fetch a “friend map”

Replace UID with logged in user id. Via this page.

SELECT uid1, uid2
FROM friend
WHERE uid1 IN (SELECT uid1 FROM friend WHERE uid2=UID)
AND uid2 IN (SELECT uid1 FROM friend WHERE uid2=UID)
AND uid1 < uid2

Names of the places you’ve checked in

SELECT name FROM page
WHERE page_id IN
(SELECT page_id FROM checkin WHERE author_uid = me())

Names of the Places your Friends have checked in

SELECT name FROM page
WHERE page_id IN (SELECT page_id FROM checkin WHERE author_uid IN
(SELECT uid2 FROM friend WHERE uid1 = me()))

You can play around with executing these here including your Facebook user id if you’re logged in.

Enabling Facebook Insights aka Social Analytics for your Domain

As a follow-up to my previous post Facebook allows you to tie your domain to an application, page or Facebook account allowing you to track usage through Insights which is Facebook’s version of Google Analytics on their platform.

Facebook Insights

The green button at the top right reads “Insights for your Domain” where you can specify where you want to track statistics. By tying your domain to one of the three choices you can gain insight into your visitors. When I went to setup my domain tied to an application I ran into a message indicating that I needed to have “Connect Base Domains” enabled. I recalled a Facebook application setting that mentioned connect so I used the Developer’s application to edit the Facebook application that I was trying to tie Insights too.

To set this correctly, you need to:

  1. Browse to /developers on Facebook
  2. Click on your application (or create a new app)
  3. Select Edit Settings
  4. Click the Web Site tab
  5. Set the Site URL and Site Domain fields accordingly for your domain
  6. Return to the /insights page and setup Insights for your domain