2008年12月29日 星期一

google blogger data api & app engine


get project code:
svn co http://google-app-engine-samples.googlecode.com/svn/trunk/gdata_feedfetcher

install:
1. get gdata library
2. copy gdata and atom directories of gdata-python-client library into project directory


get blogs updated at today:
ex: if today is 2008-12-30, want to get blogs with tag "apple command"
from url:
http://deeplyloveapple.blogspot.com/feeds/posts/default/-/apple%20command?updated-min=2008-12-30&orderby=updated



2008年9月4日 星期四

URL mapping in app engine

defined in app.yaml

app.yaml defines which handler script will  handle the request(URL)

2008年8月29日 星期五

using django with app engine

1. create django project
   django-admin.py startproject Test

2. add main.py in project:
# Google App Engine imports.
from google.appengine.ext.webapp import util

from django.core.management import setup_environ
import settings

setup_environ(settings)

# Force Django to reload its settings.
from django.conf import settings
settings._target = None

import django.core.handlers.wsgi
import django.core.signals
import django.db
import django.dispatch.dispatcher


# Unregister the rollback event handler.
django.dispatch.dispatcher.disconnect(
    django.db._rollback_on_exception,
    django.core.signals.got_request_exception)

def main():
  # Create a Django application for WSGI.
  application = django.core.handlers.wsgi.WSGIHandler()

  # Run the WSGI CGI handler with that application.
  util.run_wsgi_app(application)

if __name__ == '__main__':
  main()

3. add app.yaml in project
application: test
version: 1
runtime: python
api_version: 1

handlers:
- url: /.*
  script: main.py

4. dev_appserver.py  Test

2008年8月28日 星期四

webpage about django & app engine

http://www.42topics.com/dumps/django/docs.html

create application on app engine

1. create an application from http://appengine.google.com/
    application identifier must be the same as application in app.yaml

2. upload application
    appcfg.py  update helloworld

3. by default,
    the application url is  http://helloworld.appspot.com/

using static files

using css:
add  following lines in yaml
- url: /stylesheets
  static_dir: stylesheets

add a directory stylesheets under project directory 
css files are in this directory

add following lines in html
<head>
   <link type="text/css" rel="stylesheet" href="/stylesheets/main.css" />
 </head>

2008年8月26日 星期二

free svn server

assembla

template in webapp

helloworld.py
import cgi

from google.appengine.ext import db

import os
from google.appengine.ext.webapp import template

from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.api import users

class Greeting(db.Model):
  author = db.UserProperty()
  content = db.StringProperty(multiline=True)
  date = db.DateTimeProperty(auto_now_add=True)

class MainPage(webapp.RequestHandler):
def get(self):
greetings_query = Greeting.all().order('-date')
greetings = greetings_query.fetch(10)
if users.get_current_user():
url = users.create_logout_url(self.request.uri)
url_linktext = 'Logout'
else:
url = users.create_login_url(self.request.uri)
url_linktext = 'Login'
template_values = {
 'greetings': greetings,
     'url': url,
     'url_linktext': url_linktext,
}
path = os.path.join(os.path.dirname(__file__), 'index.html')
self.response.out.write(template.render(path, template_values))
class Guestbook(webapp.RequestHandler):
def post(self):
greeting = Greeting()
if users.get_current_user():
greeting.author = users.get_current_user()
greeting.content = self.request.get('content')
greeting.put()
self.redirect('/')
application = webapp.WSGIApplication( [('/', MainPage), ('/sign', Guestbook)], debug=True)

def main():
  run_wsgi_app(application)

if __name__ == "__main__":
  main()

index.html:
<html>
  <body>
    {% for greeting in greetings %}
      {% if greeting.author %}
        <b>{{ greeting.author.nickname }}</b> wrote:
      {% else %}
       An anonymous person wrote:
      {% endif %}
      <blockquote>{{ greeting.content|escape }}</blockquote>
    {% endfor %}

    <form action="/sign" method="post">
 <div><textarea name="content" rows="3" cols="60"></textarea></div>
      <div><input type="submit" value="Sign Guestbook"></div>
    </form>

    <a href="{{ url }}">{{ url_linktext }}</a>

  </body>
</html>     

datastore api

define a model & create an entity

example :

# import db & users
from google.appengine.ext import db
from google.appengine.api import users

# define a model, inherit from db.Model
class Pet(db.Model):
  name = db.StringProperty(required=True)
  type = db.StringProperty(required=True, choices=set(["cat", "dog", "bird"]))
  birthdate = db.DateProperty()
  weight_in_pounds = db.IntegerProperty()
  spayed_or_neutered = db.BooleanProperty()
  owner = db.UserProperty()

# create an entity 
pet = Pet(name="Fluffy",
          type="cat",
          owner=users.get_current_user())
pet.weight_in_pounds = 24

# store the entity
pet.put()

_____________________________________________________________

get entity from datastore
1. using db.GqlQuery
ex:
user_pets = db.GqlQuery("SELECT * FROM Pet WHERE pet.owner = :1",
                          users.get_current_user())


db's property:
1. db.StringProperty
2.db.DateProperty



import cgi

from google.appengine.ext import db

from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.api import users

class Greeting(db.Model):
  author = db.UserProperty()
  content = db.StringProperty(multiline=True)
  date = db.DateTimeProperty(auto_now_add=True)

class MainPage(webapp.RequestHandler):
def get(self):
self.response.out.write('<html><body>')
greetings = db.GqlQuery("SELECT * FROM Greeting ORDER BY date DESC LIMIT 10")
for greeting in greetings:
if greeting.author:
self.response.out.write('<b>%s</b> wrote:' % greeting.author.nickname())
else:
self.response.out.write('An anonymous person wrote:')
self.response.out.write('<blockquote>%s</blockquote>' %
                             cgi.escape(greeting.content))

   # Write the submission form and the footer of the page
self.response.out.write("""
          <form action="/sign" method="post">
            <div><textarea name="content" rows="3" cols="60"></textarea></div>
            <div><input type="submit" value="Sign Guestbook"></div>
          </form> </body></html>
       
     """)
class Guestbook(webapp.RequestHandler):
def post(self):
greeting = Greeting()
if users.get_current_user():
greeting.author = users.get_current_user()
greeting.content = self.request.get('content')
greeting.put()
self.redirect('/')
application = webapp.WSGIApplication( [('/', MainPage), ('/sign', Guestbook)], debug=True)

def main():
  run_wsgi_app(application)

if __name__ == "__main__":
     main()

get data from datastore:
method 1:
db.GqlQuery("SELECT * FROM Greeting ORDER BY date DESC LIMIT 10")  

method 2:
Greeting.gql("ORDER BY date DESC LIMIT 10")

method 3:
Greeting.gql("WHERE author = :1 ORDER BY date DESC",
                               users.get_current_user())

method 4:
Greeting.gql("WHERE author = :author ORDER BY date DESC",
                               author=users.get_current_user())

method 5:
greetings = Greeting.all()
greetings.filter("author =", users.get_current_user())
greetings.order("-date")

Clearing the Development Server Datastore
ex:
dev_appserver.py --clear_datastore helloworld/

form in webapp

import cgi

from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.api import users

class MainPage(webapp.RequestHandler):
def get(self):
self.response.out.write("""
      <html>
        <body>
          <form action="/sign" method="post">
            <div><textarea name="content" rows="3" cols="60"></textarea></div>
<input type="submit" value="Sign Guestbook"></div>
          </form>
        </body>
      </html>""")
class Guestbook(webapp.RequestHandler):
def post(self):
self.response.out.write('<html><body>You wrote:<pre>')
self.response.out.write(cgi.escape(self.request.get('content')))
self.response.out.write('</pre></body></html>')
application = webapp.WSGIApplication( [('/', MainPage), ('/sign', Guestbook)], debug=True)

def main():
  run_wsgi_app(application)

if __name__ == "__main__":
  main()

users service

from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.api import users

class MainPage(webapp.RequestHandler):
def get(self):
user = users.get_current_user()

if user:
self.response.headers['Content-Type'] = 'text/plain'
self.response.out.write('Hello, ' + user.nickname())
else:
self.redirect(users.create_login_url(self.request.uri))
application = webapp.WSGIApplication( [('/', MainPage)], debug=True)

def main():
  run_wsgi_app(application)

if __name__ == "__main__":
  main()

self.request.uri is current uri. Hence, after successful login, user can back here

webapp framework

from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app

class MainPage(webapp.RequestHandler):
def get(self):
self.response.headers['Content-Type'] = 'text/plain'
self.response.out.write('Hello, webapp World!')
application = webapp.WSGIApplication( [('/', MainPage)], debug=True)

def main():
  run_wsgi_app(application)

if __name__ == "__main__":
  main()

a hello world page

1. create project directory:
helloworld

2. in the directory, create two files

(1)helloworld.py:
print 'Content-Type: text/plain'
print ''
print 'Hello, world!'

(2)app.yaml
application: helloworld
version: 1
runtime: python
api_version: 1

handlers:
- url: /.*
script: helloworld.py

url: /.*
script: helloworld.py means any url will be handled by helloworld.py

(3)run web server:
dev_appserver.py helloworld

(4) connect to server
127.0.0.1:8080

(5) update to google web server:
appcfg.py helloworld

2008年8月13日 星期三

2008年7月29日 星期二

python imaging library

If model in Django wants to use ImageField,  we must install python imaging library

2008年7月25日 星期五

template

 template object & context object:
ex:
from django.template import Template, Context
a=Template("<p>hello {{name}} </p>")
b=Context({ 'name': 'Peter' } )
a.render(b)
{{ }} in template define the variable
context is a dictionary that map variable to value
render function replace the value with value

call method in {{ }}:
no () & no arguments
ex:
{{ dog.bark }}

list in {{}}:
ex:
{{items.2}}

dictionary in {{}}:
ex:
{{ Person.name }}

define a method that can not be executed by template
ex:
def  test(self):
       hello
test.alters_data=true

template tag:
if & else:
ex:
{% if isHot %}
     {{isHot}}
{% else %}
     not Hot
{% endif %}

and ,  or, not,  can be used in if 

for:
ex:
{% for  name in nameList %}
       {{ name}}
{% endfor %}

for & reverse:
ex:
{% for name in nameList reversed %}
     {{name}}
{% endfor %}

forloop.counter:
the number of times the loop has been entered

forloop.first:
forloop.revcounter:
forloop.last:

forloop.parentloop:
reference to the forloop object for the parent loop

ifequal / ifnotequal:
ex:
{%  ifequal a b %}
     test
{%  endifequal %}

comment:
ex:
{#  this is a comment #}

filter:
change variable,  use | with filter name
ex:
date filter:
{{ tempDate | date: "F j, Y" }}




2008年7月18日 星期五

exception

ex:
ckass Bad(Exception):
          pass

def test():
      raise  Bad(), "test bad"

try:
    test()
except  Bad, info:
     print "bad", info
else:
    print "else"
finally:
     print "finally"

assert:
raise AssertionError when test evaluates to false
ex:
assert  x<=3, 'x must be larger than 3'

raise:
ex1: raise object
class A:
     pass
def  test():
     raise A()

ex2:  raise string
message="Error"
def test():
      raise  message

2008年7月14日 星期一

debug in django

use assert False:
trigger debug page

change type

int:
string to int

str:
int to string

view function

first parameter must be HttpRequest
the other parameters are the string matched by ( ) of urlpatterns

ex:
def hours_ahead(request, offset):
offset=int(offset)
dt= datetime.datetime.now()+ datetime.timedelta(hours=offset)
html="<html><body>In %s hours(s), it will be %s.</body></html>"% (offset,dt)
return HttpResponse(html)

2008年7月13日 星期日

class method & static method

class method:
ex:
def  test(cls):
       print('class method')
test=classmethod(test)

static method:
ex:
def  test()
      print('static method')
test=staticmethod(test)



url mapping

settings.py has a variable  ROOT_URLCONF

ROOT_URLCONF  decides the python file for routing

ROOT_URLCONF is urls.py by default

when a request comes in, Django loads ROOT_URLCONF and find the match between request url & urlpatterns 

when pattern found, the associated view function is called( the function is passed HttpRequest object as first parameter) 

the view function will return an HttpResponse object

define urlpatterns
ex:
urlpatterns = patterns( '', ( r'^test/$',  testFunction) )
match  /test/ ,  if request is /test/,  testFunction is called

define view function:
ex:
def test(request):
now=datetime.datetime.now()
html= "<html><body>It is now %s.</body></html>" % now
return HttpResponse(html)

raw string

using r:
turn off escpate
ex:
tempStr=  r'C:\test'

python path

print python path:
import sys
print  sys.path

create a project, create an app, run the server, path, timezone

create a projct
django-admin.py  startproject  newSite

create an app in the project:
python manage.py   startapp books
create  __init__.py, models.py,  views.py in books directory 

run the server:
python manage.py   runserver
running at 127.0.0.0.1:8000

python manage.py  runserver  0.0.0.0  8888
listen on any network interface,  on port 8888

set path for django project
add django_site.pth  under /Library/Python/2.5/site-packages
ex:
django_site.pth:
/Volumes/Data/django_project/

time zone
in settings.py
TIME_ZONE = 'Asia/Taipei'

install django

sudo python setup.py install

__name__ & __main__

when the file is run as a top-level program,  __name__ is set as __main__

when the file is imported,  __name__ is set to the module's name

Hence, we can use __name__ to do unit test.
If  __name__ == __main__,   we execute unit test
if __name__ != __main__,  unit test is not executed 


2008年6月26日 星期四

module

a python file is a module

use import to import module:
ex:
import  test
this will import test.py

a module is imported only once per process by default. Further imports reuse loaded modules in memory
use sys.modules.keys() to find loaded module

when module is imported, the module is executed

module search path:
import modules in other directories:
set PHTYONPATH

import and from:
1. only use import:
ex:
import test
test.run()

2. use import and from
ex:
from test import run
run()
now we can reference run() without test
ex:
from test import *
now we can reference any attribute of module test

show module's attribute
ex:
test.__dict__.keys()

reload:
ex:
import test
reload(test)

module packages:
import  dir1.dir2.test
dir1 and dir2 are directories,  the file imported is test.py
dir1 and dir2 must both contain  __init__.py
dir1 must under the directory of python search path

2008年6月23日 星期一

loop

while  ... else...
the else is executed if break is not excuted in the while
ex:
while  x> 1:
          if  x>10
              break
else
        print  x

for ...  else  is the same as while ...  else ...

for applies to list, string , tuple

lambda

ex:
f= lambda x, y: x+y
f(1,2)
--->  3

2008年6月20日 星期五

define class

ex:
class Test:
     def  __init__(self, name):
     self.name=name

      def  hello(self):
             return  "hello"

t= Test("peter")
t.name
---> "peter"
t.hello
---> "hello"

set

a=set('abcd')
b=set('cdef')
a | b
---> set(['a', 'b', 'c', 'd', 'e',  'f'] )
a & b
--->   set( [ 'c', 'd' ] )
a - b
--->  set( [ 'a', 'b' ] )


file methods

open:
ex:
open('test.txt', 'w')

read:
return entire file into string

sorted, type

sorted
ex:
sorted([2,1])
--->  [1,2]

type:
know the object's type
ex:
type("test")
--->  <type , 'str'> 

check type methods:
(1) if type(a) ==type([]):
(2) if type(a)== list:
(3) if  isinstance(a, list):


for

ex:
for a in [1,2,3]:
    print  a

dictionary

use  {  }
ex:
test= { "a":"peter",  "b":"andy" }
---> test["a"]="peter"

keys:

has_key:

delete an element in dictionary:
ex:
a={ 'age':3  }
del  a['age']

regular expression

match
ex:
import re
match= re.match( '/(.*)/(.*)', 'abc/def/' )
match.groups()
---> ( 'abc', 'def' )

^:
match the start of  the string

$:
match the end of the string

{ }:
ex:
\d{1,2}
one or two numbers

string method

find:
return the offset of argument
ex:
'test'.find('es')
--->  1

replace:
a='test'
a.replace('t' , 'b')
--->  a is 'best'

split:
'aaa,bbb'.split(',')
--> [ 'aaa', 'bbb' ]

upper:
'test'.upper()
--->  'TEST'

isalpha(),  isdigit()

rstripe()
remove whitespace on the right side

ord
ex:
ord('a')
--> 97

""":
ex:
a= """
b
  ""
c
"""
print a
--->   b 
             ""
          c

format string:
ex:
n1=1
n2=2
print (" num1 %d num2 %d"  %(n1, n2) )



immutable object & mutable object

immutable object:
number,  string, tuple

mutable object:
list , dictionary 

slicing

apply to string, list
return a new string or list
ex:
a="test"
a[1:3]
--->  es
( offset 1 to 2, not including 3)

a[1:]
-->  est
( left offset defaults to the length of a)

a[:3]
--> tes
(right offset defaults to 0)

== & is

==:
compare value of  two object

is:
compare if two variables point to the same object
ex:
if a is b

in-place changes & non in-place changes

non in-place change:
for immutable object, such as number & string
ex:
a=3
b=a
b=2
--->  a=3 ,  b=2

in-place  changes:
for list , dictionary , etc
ex:
a=[1,2,3]
b=a
b[0]=5
--->  a=[5,2,3],  b=[5,2,3]


note:
a=[1,2]
b=a
b=[3,4]
--->  a is still [1,2]  because now  b & a point to different objects

the parameter of the function is passed by assignment 
Hence, it is the same.
If parameter is mutable, it can be changed
If parameter is not mutable, it can not be changed

how to change non-mutable argument for caller:
using return value
def  test(x, y)
     x=3
     y= 3
     return x, y
a=2
b=2
a, b= test(a, b)


list and tuple

list:
using []
ex:
a=[1,2,3]

+:
[1,2] +[3,4]
--> [1,2,3,4]

sort()

reverse()

get column from list:
ex:
a=[ [1,2], [3,4] ]
b=[ row[1] for row in a]
--> b= [2,4]
row[1] means second column
Hence, second column for each row

append:

tuple:
use ()
ex:
a= (1,2,3)
It is like list , but it is immutable 


dir & help

dir( module_name):
return all attributes inside that module

dir( "test")
--> string's attribute, such as string's methods

help:
find info about API
ex:
help("test".index)

define method

def  test( arg1 ):
        print "hello"

variable in the function

when assign a name A in a function, it will create a local variable a
In the function, we can read the value of global variable A
However, if you want to modify global variable A, you must using following methods:

global:
use global to modify global variable
ex:
x=1
def  test():
      global  x
      x=3

access attribute in other module:
using import
ex:
import  test
test.var = 2

nested function:
ex:
def test:
    x=3
    def  test2:
        print x
test2 can access x defined in test 

keyword parameter
ex:
def  test(a, b):
        print  a, b

test( a=3, b=2)

default parameter:
ex:
def  test(a, b=3):
       printf  a, b

test( 2)

arbitrary argument:
ex:
def  test(*args):
       print args

test( 1,2,3)

** is for keyboard argument
ex:
def  test(**args):
      print  args

test(a=1,b=2)

use * in caller:
unpack a collection of arguments
ex:
a= (1,2,3,4)
test( *a)

use ** in caller:
unpack a dictionary of key/value pairs