<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Talk Funnel &#187; python</title>
	<atom:link href="http://ramin.firoozye.com/tag/python/feed/" rel="self" type="application/rss+xml" />
	<link>http://ramin.firoozye.com</link>
	<description>Talk Funnel: Ramin Firoozye&#039;s (occasional) Public Whisperings</description>
	<lastBuildDate>Fri, 21 Oct 2011 14:14:22 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Push Notification and Python (Django)</title>
		<link>http://ramin.firoozye.com/2009/09/09/push-notification-and-python-django/</link>
		<comments>http://ramin.firoozye.com/2009/09/09/push-notification-and-python-django/#comments</comments>
		<pubDate>Wed, 09 Sep 2009 09:36:25 +0000</pubDate>
		<dc:creator>ramin</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[push]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://ramin.firoozye.com/?p=128</guid>
		<description><![CDATA[I&#8217;ve been trying to get the iPhone Push notification services introduced in OS 3.0 working with Python (specifically, Django). It took a while but I figured I&#8217;d post my notes so it&#8217;ll spare someone the suffering I had to go through. Other attempts at this (apns-python-wrapper (aka APNSWrapper) and Lee Packham&#8217;s code) both use the [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been trying to get the iPhone Push notification services introduced in OS 3.0 working with Python (specifically, <a href="http://www.djangoproject.com/" target="_blank">Django</a>). It took a while but I figured I&#8217;d post my notes so it&#8217;ll spare someone the suffering I had to go through.</p>
<p>Other attempts at this (<a href="http://code.google.com/p/apns-python-wrapper/" target="_blank">apns-python-wrapper</a> (aka <code>APNSWrapper</code>) and <a href="http://leenux.org.uk/2009/07/14/push-on-the-iphone/" target="_blank">Lee Packham&#8217;s</a> code) both use the standard <code>ssl</code> libraries which I couldn&#8217;t get to work under Snow Leopard and Python 2.6.</p>
<p>I eventually got it going with Django and <a href="http://sourceforge.net/projects/pyopenssl/" target="_blank">pyOpenSSL</a> libraries. The easiest way is to get the prebuilt <a href="http://www.egenix.com/products/python/pyOpenSSL/" target="_blank">pyOpenSSL binaries from eGenix</a>. If the test server is running on Snow Leopard the <em>Python 2.6 UCS2</em> version seems to work best.</p>
<p>The thing about <code>pyOpenSSL</code> is that it expects the certificate and private key to be in separate <code>.PEM</code> files so you have to export each one from <code>KeyChain Access</code> in <code>.P12</code> format then convert them to <code>.PEM</code> from the command line. For the development key it&#8217;s easier to specify the password during export then strip it out on the command line. In production you may not want to do that.</p>
<pre class="brush: bash">
   % openssl pkcs12 -clcerts -nokeys -out devcert.pem -in devcert.p12
   % openssl pkcs12 -nocerts -out devkey.pem -in devkeypw.p12
   % openssl rsa -in devkeypw.pem -out devkey.pem
</pre>
<p />
<p />
Now copy <code>devcert.pem</code> and <code>devkey.pem</code> (with no password) into the server directory.</p>
<p>The following bit of code is in a file called <code>PushSender.py</code> and does the actual talking to the push server (I heavily edited out project-specific bits and standard exception and error-handling stuff. Hopefully didn&#8217;t bork it too badly <img src='http://ramin.firoozye.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p>Also, in this example the actual communication runs in a thread. In some cases it might make more sense to run it as a main routine:</p>
<pre class="brush: python">
import os, sys
import struct, binascii, ssl, datetime
import threading
import simplejson as json
from socket import socket
from OpenSSL import SSL

class PushSender(threading.Thread):
def __init__(self, sandbox, token, message, badge, sound):
	super(PushSender, self).__init__()
    		self.token = token
    		self.sandbox = sandbox
    		self.message = message
    		self.badge = badge
    		self.sound = sound
    		self.ctx = SSL.Context(SSL.SSLv3_METHOD)
    		if sandbox:
    			self.apnHost = &quot;gateway.sandbox.push.apple.com&quot;
    			self.ctx.use_certificate_file(os.path.join(PROJECT_ROOT, &quot;devcert.pem&quot;))
    			self.ctx.use_privatekey_file(os.path.join(PROJECT_ROOT, &quot;devkey.pem&quot;))
    		else:
    			self.apnHost = &quot;gateway.push.apple.com&quot;
    			self.ctx.use_certificate_file(os.path.join(PROJECT_ROOT, &quot;prodcert.pem&quot;))
    			self.ctx.use_privatekey_file(os.path.join(PROJECT_ROOT, &quot;prodcert.pem&quot;))

    	def run(self):
    		payload = {}
    		aps = {}
    		if (self.message):
    			aps[&quot;alert&quot;] = str(self.message)
    		if (self.badge):
    			aps[&quot;badge&quot;] = self.badge
    		if (self.sound):
    			aps[&quot;sound&quot;] = str(self.sound)

    		payload[&quot;aps&quot;] = aps

    		token = binascii.unhexlify(self.token)
    		payloadstr = json.dumps(payload, separators=(&#039;,&#039;,&#039;:&#039;))
    		payloadLen = len(payloadstr)
    		fmt = &quot;!cH32sH%ds&quot; % payloadLen
    		command = &#039;\x00&#039;
    		msg = struct.pack(fmt, command, 32, token, payloadLen, payloadstr)
    		sock = socket()
    		s = SSL.Connection(self.ctx, sock)
    		s.connect((self.apnHost, 2195))
    		s.send(msg)
    		s.shutdown()
    		s.close()
</pre>
<p>[ <a href="http://www.firoozye.com/download/PushSender.txt" target="_blank">PushSender source</a> ]</p>
<p>To invoke it in a thread (the first param is <em>True</em> for sandbox and <em>False</em> for production server) from the main routine:</p>
<pre class="brush: python">
	from PushSender import PushSender
	...
	pushsender = PushSender(True, token, pushmessage, pushbadge, pushsound)
	pushsender.start()
</pre>
<p />
<p />
On the phone the token returned by the <code>didRegisterForRemoteNotificationsWithDeviceToken</code> method is in the form <code>&lt;xxxxxxxx xxxxxxxx ...&gt;</code>. To pass it along to the server you have to strip out the <code>&lt;&gt;</code> and spaces. The <code>unhexlify</code> method then converts this string into a 32-byte hex binary value. The easiest way to strip out the extraneous stuff is to just do it on the client-side:</p>
<pre class="brush: cpp">
    NSString *deviceToken = [[[[tokenString description]
			stringByReplacingOccurrencesOfString:@&quot;&lt; &quot; withString:@&quot;&quot;]
			stringByReplacingOccurrencesOfString:@&quot;&gt;&quot; withString:@&quot;&quot;]
			stringByReplacingOccurrencesOfString: @&quot; &quot; withString: @&quot;&quot;];
</pre>
<p />
<p />
One last thing: at least with the sandbox if the phone is running on WiFi sometimes push notices don&#8217;t come through. This may be due to router NAT or firewall configuration issues. One way to check is to go into XCode Organizer while the phone is tethered and run your app, then under the Organizer Console you can check for errors. To get around this you&#8217;ll want to turn off the WiFi on the phone and go with 3G. This usually makes push notices arrive as expected (and strangely enough the WiFi method goes back to working for a few minutes). </p>
<p>There&#8217;s more that needs to be done to make it production-ready but at least it&#8217;s good to know it&#8217;s doable:</p>
<div style="text-align:center;"><img src="http://ramin.firoozye.com/wp-content/uploads/2009/09/cp18s.png" alt="cp18.png" border="0" /></div>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://ramin.firoozye.com/2009/09/09/push-notification-and-python-django/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Django bash shell shortcuts</title>
		<link>http://ramin.firoozye.com/2008/03/03/django-bash-shell-shortcuts/</link>
		<comments>http://ramin.firoozye.com/2008/03/03/django-bash-shell-shortcuts/#comments</comments>
		<pubDate>Mon, 03 Mar 2008 20:45:08 +0000</pubDate>
		<dc:creator>ramin</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://ramin.firoozye.com/2008/03/03/django-bash-shell-shortcuts/</guid>
		<description><![CDATA[SmileyChris had a post up recently on setting up bash aliases for Django. He uses the classic alias command which works for one-line shortcuts. I got inspired to put mine up too, but if you want to do something more elaborate, bash gives you this handy scripting language along with &#8216;shell commands&#8217; so you can [...]]]></description>
			<content:encoded><![CDATA[<p>SmileyChris had <a href="http://smileychris.tactful.co.nz/ramblings/django-managepy-alias/" target="_blank">a post</a> up recently on setting up bash aliases for Django. He uses the classic <code>alias</code> command which works for one-line shortcuts. I got inspired to put mine up too, but if you want to do something more elaborate, <code>bash</code> gives you this handy scripting language along with &#8216;shell commands&#8217; so you can do something a bit more involved.</p>
<p>What I tried to do with these shortcuts was to create a set of mini-commands that quickly do what you need to do when developing Django. It might help someone out and squeeze an extra 2-3.5 microseconds each time you run a Django command. Hey, it all adds up.</p>
<p>In my case, I keep the directory for all my Django projects in a single &#8216;source&#8217; directory so I can quickly jump in and out of them. The shell commands makes that assumption too. If your projects are all over the place, you&#8217;ll have to tweak things &#8212; but I&#8217;d suggest doing some housekeeping and moving everything to a common directory to help keep things neat and tidy.</p>
<p>To use these, copy the lines to the bottom of your <code>~/.bashrc</code> or <code>~/.bash_profile</code>. If you don&#8217;t see one of these in your home directory, remember that most *nix shells ignore files starting with a &#8216;.&#8217; (period) so you&#8217;ll want to do something like:</p>
<p><code>% ls -al</code></p>
<p>To see all your files in the current directory. If you really don&#8217;t have one, then create a <code>.bash_profile</code> and put the following lines inside. You&#8217;ll want to customize the first four environment variables to point them to directories in your system. The ones there are samples, but once you set it up once, you&#8217;ll never have to worry about it again.</p>
<p>A minor caveat: These have been tested on a Mac OS-X Leopard. YM-will-most-likely-V. On with the code.<br />
<code><br />
<blockquote>
# Django shortcuts</p>
<p># CHANGE: to directory where you installed Django sources.<br />
DJANGOROOT=/dev/djangoproject <br />
export DJANGOROOT</p>
<p># CHANGE: to admin bin scripts directory under Django.<br />
# This should work for the svn version.<br />
DJANGOBIN=$DJANGOROOT/django/bin<br />
export DJANGOBIN<br />
PATH=$PATH:$DJANGOBIN:<br />
export PATH</p>
<p># CHANGE: to TCP port for testing.<br />
# You go to http://localhost:8008 to hit the test sever.<br />
DJANGOTESTPORT=8008<br />
export DJANGOTESTPORT</p>
<p># CHANGE: to base directory where you keep your Django projects.<br />
DJANGOPROJECTBASE=~/Work/django<br />
export DJANGOPROJCTBASE</p>
<p># ---------------- Django shell commands ------------------</p>
<p>function django() {<br />
&nbsp;&nbsp;echo "dadmin&nbsp;- Basic django-admin"<br />
&nbsp;&nbsp;echo "dproj&nbsp;&nbsp;- set up (show) default django project"<br />
&nbsp;&nbsp;echo "dsrc&nbsp;&nbsp;&nbsp;- jump to Django projects home directory"<br />
&nbsp;&nbsp;echo "dls&nbsp;&nbsp;&nbsp;&nbsp;- list current projects in Django projects home directory"<br />
&nbsp;&nbsp;echo "dcd&nbsp;&nbsp;&nbsp;&nbsp;- jump to current project directory"<br />
&nbsp;&nbsp;echo "dstart&nbsp;- start a new project in the home directory"<br />
&nbsp;&nbsp;echo "dapp&nbsp;&nbsp;&nbsp;- create a new application under the current project"<br />
&nbsp;&nbsp;echo "dsync&nbsp;&nbsp;- Run syncdb and synchronize model with DBMS"<br />
&nbsp;&nbsp;echo "drun&nbsp;&nbsp;&nbsp;- run current project in test server"<br />
}</p>
<p>function dsrc() {<br />
&nbsp;&nbsp;cd $DJANGOPROJECTBASE;<br />
}</p>
<p>function dls() {<br />
&nbsp;&nbsp;ls $DJANGOPROJECTBASE;<br />
}</p>
<p>function dadmin() {<br />
&nbsp;&nbsp;python django-admin.py $*;<br />
}</p>
<p>function dstart() {<br />
&nbsp;&nbsp;src;<br />
&nbsp;&nbsp;python django-admin.py startproject $*;<br />
}</p>
<p>function dproj() {<br />
&nbsp;&nbsp;if [ $# -eq 0 ]<br />
&nbsp;&nbsp;then<br />
&nbsp;&nbsp;&nbsp;&nbsp;if [ $DJANGOCURRENTPROJECT ]<br />
&nbsp;&nbsp;&nbsp;&nbsp;then<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo "Current project is: $DJANGOCURRENTPROJECT";<br />
&nbsp;&nbsp;&nbsp;&nbsp;else<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo "Run 'dproj
<projectname>' first";<br />
&nbsp;&nbsp;&nbsp;&nbsp;fi<br />
&nbsp;&nbsp;else<br />
&nbsp;&nbsp;&nbsp;&nbsp;if [ -d $DJANGOPROJECTBASE/$1 ]<br />
&nbsp;&nbsp;&nbsp;&nbsp;then<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DJANGOCURRENTPROJECT=$1;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;export DJANGOCURRENTPROJECT;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DJANGO_SETTINGS_MODULE="$DJANGOPROJECTBASE/$DJANGOCURRENTPROJECT";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;export DJANGO_SETTINGS_MODULE;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo "Current project set to: $1";<br />
&nbsp;&nbsp;&nbsp;&nbsp;else<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo "Project directory '$1' doesn't exist."<br />
&nbsp;&nbsp;&nbsp;&nbsp;fi<br />
&nbsp;&nbsp;fi<br />
}</p>
<p>function dcheck() {<br />
&nbsp;&nbsp;if [ $DJANGOCURRENTPROJECT ]<br />
&nbsp;&nbsp;then<br />
&nbsp;&nbsp;&nbsp;&nbsp;cd $DJANGO_SETTINGS_MODULE;<br />
&nbsp;&nbsp;&nbsp;&nbsp;return 0;<br />
&nbsp;&nbsp;else<br />
&nbsp;&nbsp;&nbsp;&nbsp;echo "Run 'dproj
<projectname>' first";<br />
&nbsp;&nbsp;&nbsp;&nbsp;return 1;<br />
&nbsp;&nbsp;fi<br />
}</p>
<p>function dapp() {<br />
&nbsp;&nbsp;if [ dcheck ]<br />
&nbsp;&nbsp;then<br />
&nbsp;&nbsp;&nbsp;&nbsp;python manage.py startapp $*;<br />
&nbsp;&nbsp;fi<br />
}</p>
<p>function dcd() {<br />
&nbsp;&nbsp;dcheck;<br />
}</p>
<p>function dsync() {<br />
&nbsp;&nbsp;if [ dcheck ]<br />
&nbsp;&nbsp;then<br />
&nbsp;&nbsp;&nbsp;&nbsp;python manage.py syncdb;<br />
&nbsp;&nbsp;fi<br />
}</p>
<p>function drun() {<br />
&nbsp;&nbsp;if [ dcheck ]<br />
&nbsp;&nbsp;then<br />
&nbsp;&nbsp;&nbsp;&nbsp;python manage.py runserver $DJANGOTESTPORT$*;<br />
&nbsp;&nbsp;fi<br />
}
</p></blockquote>
<p></code><br />
To get a reminder of how it all works, just type</p>
<blockquote><p><code>% django</code></p></blockquote>
<p>To see a list of current projects, use:</p>
<blockquote><p><code>% dls</code></p></blockquote>
<p>To start a new Django project, just go:</p>
<blockquote><p><code>% dstart <i>projectname</i></code></p></blockquote>
<p>To set the current active project:</p>
<blockquote><p><code>% dproj <i>projectname</i></code></p></blockquote>
<p>This checks to make sure the project exists under the base project directory. To quickly jump to the current project directory, you use:</p>
<blockquote><p><code>% dcd</code></p></blockquote>
<p>To create a new application under the current project use:</p>
<blockquote><p><code>% dapp <i>appname</i></code></p></blockquote>
<p>Then you add the <i>appname</i> to your project&#8217;s <code>settings.py</code> file and you&#8217;re good to go. Once you&#8217;ve defined your model, run this to sync up the database and the model:</p>
<blockquote><p><code>% dsync</code></p></blockquote>
<p>And every time you want to run the test server for the current project, just run:</p>
<blockquote><p><code>% drun</code></p></blockquote>
<p>And assuming you didn&#8217;t change the <code>DJANGOTESTPORT</code> variable above, in the browser you go to:</p>
<blockquote><p><code>http://localhost:8008/</code></p></blockquote>
<p>or if <code>localhost</code> isn&#8217;t defined in your <code>/etc/hosts</code> file, you can also use:</p>
<blockquote><p><code>http://127.0.0.1:8008</code></p></blockquote>
<p>Under Windows, the easiest way to run this is to install <a href="http://cygwin.com/" target="_blank">Cygwin</a> and then run <code>bash</code> from there.</p>
<p>Good luck.</p>
]]></content:encoded>
			<wfw:commentRss>http://ramin.firoozye.com/2008/03/03/django-bash-shell-shortcuts/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic
Page Caching using disk: enhanced

Served from: ramin.firoozye.com @ 2012-02-05 02:48:57 -->
