What powered sites? We are always curious about that when we navigating exciting sites. PoweredSites is an open site to share with others about a project or service powered sites, eg. jQuery powered sites, Python powered sites etc. PoweredSites is also a good place to show your project's power if you are project owners.

Power is a micro framework which wraps Tornado to make it easy to write a web application using Tornado.
Power is refined from the common components of http://poweredsites.org which is an open source web site
to show a project(eg.Python, Tornado) powered sites.

Charset(UTF-8) and storage engine(INNODB)

# modify default settings
nano /etc/mysql/my.cnf
# add below settings to my.cnf
[client]
default-character-set=utf8
[mysqld]
# The default character set that will be used when a new schema or table is
# created and no character set is defined
default-character-set=utf8
# The default storage engine that will be used when create new tables
default-storage-engine=INNODB

Remote access(Optional)

Access issue

Some guys may get ERROR 1045 (28000) when they try to login MySQL as root at first time,
Error message like "Access denied for user 'root'@'localhost' (using password: YES)".
You can use reserved debian-sys-maint user to login in ubuntu or debian:

Server

Proxy poweredsites.org requests to localhost:8888(Apache or Nginx as your wish)
Here is a Nginx exmaple, please refer to How to setup Nginx to setup nginx. The default port 80 will be conflict with apache2 if you already install apache2. If so, stop your apache2 or change apache2 listened port to another one.

Project

Yes, I hardcode something :(, I will refine that later.

put a symbol link or copy poweredsites/poweredsites/poweredsites.conf
to /mnt/ebs/conf/sites/poweredsites.conf

Sync project root to /mnt/ebs/sites/poweredsites, then the layout of those files will like below.

Run the app:

# setup mongodb index at the first time
python /mnt/ebs/sites/poweredsites/poweredsites/app.py --setup_db=1
# Run this one in normal, or run the upper one always.
python /mnt/ebs/sites/poweredsites/poweredsites/app.py
# for short
cd /mnt/ebs/sites/poweredsites/poweredsites/
python app.py

Then the app will be run at port 8888, type http://poweredsites.org in your browser to play with it.
Use CONTROL + C to Quit the app.

PoweredSites' in-house caching system has been enabled, generally, the performance is boosted
over 50 times in the server side.For example, it will only take 2ms to render the homepage from cache if cache is enabled and is not expired, or it need do more database queries and templates rendering, so it will take about 170ms.

The caching system can be used to cache

A whole web page

An UIModule

A normal functional in handler or UIModule.

There are three cache decorators:

cache.page, cache a whole web page to MonogoDB. It is just used to decorate SUPPORTED_METHODS (eg. get and post) in a handler.

cache.cache, cache a functional or UIModule(render functional in a UIModule) to MonogoDB.

cache.mem, cache a functional or UIModule to Python dict in memory. It just be used for caching some data which are seldom changed but the data are used frequently.

How to use them, let's see the cache arguments at first.

def cache(expire=7200, condition="", key="", anonymous=False):
"""Decorator which caches the value of a method in a handler or a module.
expire: Cache will be expired time from now in seconds.
condition: If the result of sql condition has changed, then cache expired.
key: The unique key of the cache identify in the DB, it will auto generate
one if it not be set
cache_pre: A method which is defined in self(handler or module),
it always be executed before cache or get from cache.
cache_condition: A property which is defined in self(handler or module), it
is used to construct a complex condition.
"""
def wrapper(func, self, *args, **kwargs):
# caching

class IndexHandler(BaseHandler):
# The cache will expired immediately if the count(*) has changed,
# for example a new blog is posted, so the cache is very dynamic.
@cache.page(condition="select count(*) from entries")
def get(self):
self.render("index.html")

cache with a complex condition and do some cache_pre operations

class IndexHandler(BaseHandler):
@property
def cache_condition(self):
# It will try to use this property as cache condition if no condition
# argument. You can construct a complex condition here as your wish.
return str("select updated from entry where id = %s" % self.entry_id)
def cache_pre(self, entry_id):
# It always will be executed before `get` or `post` and cache_condition,
# it has the same arguments as `get` or `post`.
# You can do something here before try to get the cache.
self.entry_id = entry_id
# Do cache_pre operations
# eg. update the click count of this entry
@cache.page()
def get(self, entry_id):
self.render("entry.html")

We are always curious about that when we navigating exciting sites.
PoweredSites is a good site to share with others about a project or service powered sites,
eg. jQuery powered sites, Torando powered sites.
PoweredSites is also a good place to show your project's power if you are a project owner.

PoweredSites source code is opened to the community under Apache License V2,
the source code is available at http://www.bitbucket.org/felinx/poweredsites, it's develop by python and tornado.
I opened everything except the OpenID API key:), so you can setup a web site using the code easily.

Currently, twitter,facebook,friendfeed openid login are no well tested because those web sites are blocked in China.
And some of features are still under developing, eg. re-edit a project or site and wiki for every project.

I hope that you will enjoy the site and the source code.I hope some guys can join me to make the site better.