Monmonja Programming Blog

November 9, 2008

Debian OS in Android

Filed under: android — admin @ 4:38 pm

Last week or so, it was Gameboy emulator on andriod, now its a Debian, a linux operating system. Jay Freeman has written a post on how to install it on your gphone http://www.saurik.com/id/10. And btw i had saw a g1 here on Hong Kong for 570USD, and i still have no plans to buy it since its too expensive.

November 3, 2008

Get Total count from datastore in app engine

Filed under: App Engine,Google,Programming — Tags: , , , — admin @ 2:45 am

Before you continue to read the post, i have to warn you that this is not the best way of getting the total count and there would be a possible inaccuracy and may not be scalable (http://groups.google.com/group/google-appengine/browse_thread/thread/3abb2868ab5fc304?pli=1), please use shared counter as what david suggested.

Here is a way on how to get the total count from a datastore in app engine, this uses memcache to cache the count for one minute (you can change this by passing an argument), i’m not sure but this seems to be better coz it doesn’t need you to do some writing on datastore.

from google.appengine.api import memcache
def get_total_count(self,model,cacheTime = 60,maxNumber = 10):
cacheName = model.kind() + "_totalCount"
total = memcache.get(cacheName)
if total == None:
index = 0
currentTotal = total = len(model.all().fetch(maxNumber,0 ))
while currentTotal == maxNumber:
index += 1
currentTotal = len(model.all().fetch(maxNumber,maxNumber * index))
total += currentTotal
memcache.add(cacheName, total, cacheTime)
return total

To call it on your get function:
self.response.out.write(str(get_total_count(self,<your model>))
or
self.response.out.write(str(get_total_count(self,<your model>,3600,1000))

* Remember that the maxNumber argument can only support upto 1000 and i encourage you to set it to 1000 if your datastore is big

Explanation to the codes:
cacheName = model.kind() + "_totalCount"
Create a variable and name it as our model’s name with an underscore totalCount (you can change this one)

total = memcache.get(cacheName)
if total == None:
index = 0

Change if there is already a cached value, if not set a index variable to 0 and ….

currentTotal = total = len(model.all().fetch(maxNumber,0 ))
Set the currentTotal and total variable to the len of a fetched row limit by maxNumber starting with the row 0

while currentTotal == maxNumber:
index += 1
currentTotal = len(model.all().fetch(maxNumber,maxNumber * index))
total += currentTotal

Loop until the currentTotal is not equal to the maxNumber and add the currentTotal to the total variable and add one to the index. Why do a while loop on currentTotal == maxNumber? Since we set a upper limit on the maximum number of rows we could fetch, it logically means that if we loop with the upper limit it would come to a point where it would never be equal to that limit.

memcache.add(cacheName, total, cacheTime)
Cache our total

Hope i’m right and it helps :)

October 30, 2008

CamelCase in Python / Django

Filed under: App Engine,Programming — Tags: , , — admin @ 8:01 am

Here is a small script for making CamelCase string in python

import re
from string import capitalize
def camelcase(value):
return "".join([capitalize(w) for w in re.split(re.compile("[\W_]*"), value)])

in django just add
@register.filter

making it
import re
from string import capitalize
@register.filter
def camelcase(value):
return "".join([capitalize(w) for w in re.split(re.compile("[\W_]*"), value)])

Hope it help.

October 23, 2008

Auto Increment in App Engine

Filed under: App Engine,Google — Tags: — admin @ 10:43 am

So you want to implement auto increment on your datastore? Here is a simple tutorial of how to do it on App Engine. This auto increment will use integers, this does not cover more advance auto increments one like UUID.

For our example we would use this datastore model:
class Post(db.Model):
title = db.StringProperty()
body = db.StringProperty()

Then you would save records like with something like
post = Post()
post.title = "Example"
post.body = "This is the body"
post.put()

Then you shall see this saved on the datastore. But where did i declared the id? App engine by default will give each record a Key, having said that each row by default will have an auto incremented integer. To retrive a row by the id you would do something like
currentPost = Post.get_by_id(<id of the post>)

What if i fetch from the model, how can i get the id?
query = datamodel.Post().all()
for result in query:
self.response.out.write(result.key().id())

How can i get my auto generated id on templates?
{% for post in posts %}
{{ post.key.id }}
{% endfor %}

October 22, 2008

Use HTML on App Engine

Filed under: App Engine,Google — Tags: — admin @ 9:37 am

App Engine by default uses django, a Python web framework that’s a bit like Rails or CakePHP, most of the tutorial on the App Engine Documentation would not teach you to use Templates except the main Using Templates part. While this tutorial is good, it would not teach you how have a more optimized version. Here is how i did, i suggest you to read the App Engine Using Templates Tutorial:

import os
from google.appengine.ext import webapp
from google.appengine.ext.webapp import template
def page_display(page,file,values={}):
template_values = {}
template_values.update(values)
try:
template_values.update(page.template_values)
except:
pass
path = os.path.join(os.path.dirname(__file__),file)
page.response.out.write(template.render(path,template_values))
class MainPage(webapp.RequestHandler):
def get(self,page):
self.template_values = {
"message" : "Hello World",
"message2" : "Hello"
}
page_display(self,"templates/index.html")
def main():
application = webapp.WSGIApplication(
[
('/', MainPage)
],
debug = True)
wsgiref.handlers.CGIHandler().run(application)
if __name__ == "__main__":
main()

As you can see if you have a lot of classes it would be a easier to remember and use
page_display(self,"templates/index.html")
then
path = os.path.join(os.path.dirname(__file__), 'index.html')
self.response.out.write(template.render(path, template_values))

October 20, 2008

Alternate row colors in App Engine

Filed under: App Engine,Google,Programming — Tags: — admin @ 1:00 pm

You have a senario where you need to have alternating colors in each rows of data in app engine or django, how can you achieve this? Here is a simple solution on doing it (This took me more than 30 mins to find out the solution coz most of the time they will give you php’s solution on alternating rows)
{% for video in videos %}
<div class="row {% cycle odd,even %}">
{{ video.title }}
<div class="youtubeLink">
<a href="{{ video.youtube_id }}">
{{ video.youtube_id }}
</a>
</div>
</div>
{% endfor %}

The main solution is this code
{% cycle odd,even %}

What this do is that it cycles around each row and returns the right index (odd or even). And with this function you are not bound to just 2 selections, if you want more you could just do something like
{% cycle one,two,three,four %}

Hope this helps.

October 18, 2008

Getting Server Information in Templatetags

Filed under: App Engine,Google — Tags: , — admin @ 4:20 am

In app engine you might want to get the server information like the hostname, current url and so on, currently you can do this by passing the self.request to the template values, and from template to your filter. What if you don’t want to pass the request variable everytime? Here is a how i did it (i’m not a python guy so if i did something wrong do comment thanks) (Here is the Tutorial on templatetags)

In your templatetags:def get_server_information(all,info = 1):
if info == 1:
return wsgiref.handlers.BaseHandler().os_environ
else:
return wsgiref.handlers.BaseHandler().os_environ.get(info)

Now in your templates if you want to get the whole server information
{{ 1|get_server_information }}

would print something like:
{'HTTP_COOKIE': 'SESSION_ID=randomstring; dev_appserver_login="test@example.com:False"',
'SERVER_SOFTWARE': 'Development/1.0',
'SCRIPT_NAME': '',
'REQUEST_METHOD': 'GET',
'HTTP_KEEP_ALIVE': '300',
'SERVER_PROTOCOL': 'HTTP/1.0',
'QUERY_STRING': '',
'CONTENT_LENGTH': '',
'HTTP_ACCEPT_CHARSET': 'ISO-8859-1,utf-8;q=0.7,*;q=0.7',
'HTTP_USER_AGENT': 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.3) Gecko/2008092510 Ubuntu/8.04 (hardy) Firefox/3.0.3 FirePHP/0.1.2',
'HTTP_CONNECTION': 'keep-alive',
'SERVER_NAME': 'localhost',
'REMOTE_ADDR': '127.0.0.1',
'PATH_TRANSLATED': '/path/to/your/current/python/code',
'SERVER_PORT': '8080',
'CONTENT_TYPE': 'application/x-www-form-urlencoded',
'CURRENT_VERSION_ID': '1.1',
'HTTP_HOST': 'localhost:8080',
'TZ': 'UTC',
'USER_EMAIL': 'test@example.com',
'HTTP_ACCEPT': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'APPLICATION_ID': 'yourapplicationid',
'GATEWAY_INTERFACE': 'CGI/1.1',
'HTTP_ACCEPT_LANGUAGE': 'en-us,en;q=0.5',
'AUTH_DOMAIN': 'gmail.com',
'HTTP_ACCEPT_ENCODING': 'gzip,deflate',
'PATH_INFO': '/examples/home'}

So you have guessed if you want only the path info then you do
{{ 1|get_server_information:”PATH_INFO” }}

Hope this helps :)

Older Posts »

Powered by WordPress

Monmonja Programming Blog is Digg proof thanks to caching by WP Super Cache