Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

new skel

  • Loading branch information...
commit 7895b154b9bda35440789687685929639b5b6481 1 parent 340ff4d
@fiorix authored
View
3  appskel/.gitignore
@@ -1,3 +0,0 @@
-*.swp
-*.pyc
-dropin.cache
View
115 appskel/README.md
@@ -1,115 +0,0 @@
-# cyclone-based project
-
- This is the source code of $project_name
- $name <$email>
-
-## About
-
-This file has been created automatically by cyclone-tool for $project_name.
-It contains the following files:
-
-- ``start.sh``: simple shell script to start the server
-- ``$modname.conf``: configuration file for the web server
-- ``$modname/__init__.py``: information such as author and version of this package
-- ``$modname/web.py``: map of url handlers and main class of the web server
-- ``$modname/config.py``: configuration parser for ``$modname.conf``
-- ``$modname/views.py``: code of url handlers for the web server
-- ``scripts/debian-init.d``: generic debian start/stop init script
-- ``scripts/debian-multicore-init.d``: run one instance per core on debian
-- ``scripts/localefix.py``: script to fix html text before running ``xgettext``
-- ``scripts/cookie_secret.py``: script for generating new secret key for the web server
-
-### Running
-
-For development and testing:
-
- twistd -n cyclone --help
- twistd -n cyclone -r $modname.web.Application [--help]
-
-For production:
-
- twistd cyclone \
- --logfile=/var/log/$project.log \
- --pidfile=/var/run/$project.pid \
- -r $modname.web.Application
-
-
-### Convert this document to HTML
-
-Well, since this is a web server, it might be a good idea to convert this document
-to HTML before getting into customization details.
-
-This can be done using [markdown](http://daringfireball.net/projects/markdown/).
-
- brew install markdown
- markdown README.md > frontend/static/readme.html
-
-And point your browser to <http://localhost:8888/static/readme.html> after this server
-is running.
-
-## Customization
-
-This section is dedicated to explaining how to customize your brand new package.
-
-### Databases
-
-cyclone provides built-in support for SQLite and Redis databases.
-It also supports any RDBM supported by the ``twisted.enterprise.adbapi`` module,
-like MySQL or PostgreSQL.
-
-The default configuration file ``$modname.conf`` ships with pre-configured
-settings for SQLite, Redis and MySQL.
-
-The code for loading all the database settings is in ``$modname/config.py``.
-Feel free to comment or even remove such code, and configuration entries. It
-shouldn't break the web server.
-
-Take a look at ``$modname/utils.py``, which is where persistent database
-connections are initialized.
-
-
-### Internationalization
-
-cyclone uses the standard ``gettext`` library for dealing with string
-translation.
-
-Make sure you have the ``gettext`` package installed. If you don't, you won't
-be able to translate your software.
-
-For installing the ``gettext`` package on Debian and Ubuntu systems, do this:
-
- apt-get install gettext
-
-For Mac OS X, I'd suggest using [HomeBrew](http://mxcl.github.com/homebrew>).
-If you already use HomeBrew, run:
-
- brew install gettext
- brew link gettext
-
-For generating translatable files for HTML and Python code of your software,
-run this:
-
- cat frontend/template/*.html $modname/*.py | python scripts/localefix.py | \
- xgettext - --language=Python --from-code=utf-8 --keyword=_:1,2 -d $modname
-
-Then translate $modname.po, compile and copy to the appropriate locale
-directory:
-
- (pt_BR is used as example here)
- vi $modname.po
- mkdir -p frontend/locale/pt_BR/LC_MESSAGES/
- msgfmt $modname.po -o frontend/locale/pt_BR/LC_MESSAGES/$modname.mo
-
-There are sample translations for both Spanish and Portuguese in this package,
-already compiled.
-
-
-### Cookie Secret
-
-The current cookie secret key in ``$modname.conf`` was generated during the
-creation of this package. However, if you need a new one, you may run the
-``scripts/cookie_secret.py`` script to generate a random key.
-
-## Credits
-
-- [cyclone](http://github.com/fiorix/cyclone) web server.
View
BIN  appskel/frontend/locale/es_ES/LC_MESSAGES/modname.mo
Binary file not shown
View
25 appskel/frontend/locale/es_ES/LC_MESSAGES/modname.po
@@ -1,25 +0,0 @@
-# cyclone-tools sample translation.
-# Copyright (C) 2011 Alexandre Fiori
-# This file is distributed under the same license as the cyclone package.
-# Alexandre Fiori <fiorix@gmail.com>, 2011.
-#
-#, fuzzy
-msgid ""
-msgstr ""
-"Project-Id-Version: 0.1\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2011-02-24 15:36-0300\n"
-"PO-Revision-Date: 2011-02-28 15:44+-0300\n"
-"Last-Translator: Alexandre Fiori <fiorix@gmail.com>\n"
-"Language-Team: Alexandre Fiori <fiorix@gmail.com>\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=utf-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-
-#: standard input:5
-msgid "cyclone web server"
-msgstr "servidor web cyclone"
-
-#: standard input:8
-msgid "It works!"
-msgstr "¡Funciona!"
View
BIN  appskel/frontend/locale/pt_BR/LC_MESSAGES/modname.mo
Binary file not shown
View
25 appskel/frontend/locale/pt_BR/LC_MESSAGES/modname.po
@@ -1,25 +0,0 @@
-# cyclone-tools sample translation.
-# Copyright (C) 2011 Alexandre Fiori
-# This file is distributed under the same license as the cyclone package.
-# Alexandre Fiori <fiorix@gmail.com>, 2011.
-#
-#, fuzzy
-msgid ""
-msgstr ""
-"Project-Id-Version: 0.1\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2011-02-24 15:36-0300\n"
-"PO-Revision-Date: 2011-02-28 15:44+-0300\n"
-"Last-Translator: Alexandre Fiori <fiorix@gmail.com>\n"
-"Language-Team: Alexandre Fiori <fiorix@gmail.com>\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=utf-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-
-#: standard input:5
-msgid "cyclone web server"
-msgstr "servidor web cyclone"
-
-#: standard input:8
-msgid "It works!"
-msgstr "Funciona!"
View
BIN  appskel/frontend/static/favicon.ico
Binary file not shown
View
26 appskel/frontend/template/base.html
@@ -1,26 +0,0 @@
-<!doctype html>
-<html lang="en">
- <head>
- <meta charset="utf-8">
- <title>{{_("cyclone web server")}}</title>
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
-
- <link href="http://twitter.github.com/bootstrap/assets/css/bootstrap.css" rel="stylesheet">
- <link href="http://twitter.github.com/bootstrap/assets/css/bootstrap-responsive.css" rel="stylesheet">
- <link rel="shortcut icon" type="image/ico" href="{{ static_url('favicon.ico') }}">
- <style>
- body {padding-top: 60px;}
- </style>
-
- </head>
-
- <body>
- <div class="container">
- <!--
- you can create multiple block entries per template
- ex: sidebar, menu, footer
- -->
- {% block page %}{% end %}
- </div> <!-- /container -->
- </body>
-</html>
View
14 appskel/frontend/template/index.html
@@ -1,14 +0,0 @@
-{% extends 'base.html' %}
-{% block page %}
-<h1>{{_("It works!")}}</h1>
-<p><small>
- <a href="/lang/en_US">English</a>&nbsp;
- <a href="/lang/es_ES">Español</a>&nbsp;
- <a href="/lang/pt_BR">Português</a>
-</small></p>
-<p>hello = {{hello}}</p>
-<p>awesome = {{awesome}}</p>
-<form class="well" method="post">
- <button type="submit" class="btn">Post example</button>
-</form>
-{% end %}
View
7 appskel/frontend/template/post.html
@@ -1,7 +0,0 @@
-{% extends 'base.html' %}
-{% block page %}
-<h1>POST example</h1>
-<p>This variable exists = {{fields.ip}}</p>
-<p>This variable does not exist = {{fields.something}}</p>
-<p>This one comes from .conf = {{fields.mysql_host}}</p>
-{% end %}
View
31 appskel/modname.conf
@@ -1,31 +0,0 @@
-[server]
-debug = true
-xheaders = false
-xsrf_cookies = false
-cookie_secret = $cookie_secret
-
-[frontend]
-locale_path = frontend/locale
-static_path = frontend/static
-template_path = frontend/template
-
-[sqlite]
-enabled = yes
-database = :memory:
-
-[redis]
-enabled = no
-host = 127.0.0.1
-port = 6379
-dbid = 0
-poolsize = 10
-
-[mysql]
-enabled = no
-host = 127.0.0.1
-port = 3306
-username = foo
-password = bar
-database = dummy
-poolsize = 10
-debug = no
View
6 appskel/modname/__init__.py
@@ -1,6 +0,0 @@
-# coding: utf-8
-#
-$license
-
-__author__ = "$name <$email>"
-__version__ = "$version"
View
71 appskel/modname/config.py
@@ -1,71 +0,0 @@
-# coding: utf-8
-#
-$license
-
-import os
-import ConfigParser
-from cyclone.util import ObjectDict
-
-
-def xget(func, section, option, default=None):
- try:
- return func(section, option)
- except:
- return default
-
-
-def parse_config(filename):
- cfg = ConfigParser.RawConfigParser()
- with open(filename) as fp:
- cfg.readfp(fp)
- fp.close()
-
- settings = {'raw': cfg}
-
- # web server settings
- settings["debug"] = xget(cfg.getboolean, "server", "debug", False)
- settings["xheaders"] = xget(cfg.getboolean, "server", "xheaders", False)
- settings["cookie_secret"] = cfg.get("server", "cookie_secret")
- settings["xsrf_cookies"] = xget(cfg.getboolean, "server", "xsrf_cookies",
- False)
-
- # get project's absolute path
- root = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
- getpath = lambda k, v: os.path.join(root, xget(cfg.get, k, v))
-
- # locale, template and static directories' path
- settings["locale_path"] = getpath("frontend", "locale_path")
- settings["static_path"] = getpath("frontend", "static_path")
- settings["template_path"] = getpath("frontend", "template_path")
-
- # sqlite support
- if xget(cfg.getboolean, "sqlite", "enabled", False):
- settings["sqlite_settings"] = ObjectDict(database=cfg.get("sqlite",
- "database"))
- else:
- settings["sqlite_settings"] = None
-
- # redis support
- if xget(cfg.getboolean, "redis", "enabled", False):
- settings["redis_settings"] = ObjectDict(
- host=cfg.get("redis", "host"),
- port=cfg.getint("redis", "port"),
- dbid=cfg.getint("redis", "dbid"),
- poolsize=cfg.getint("redis", "poolsize"))
- else:
- settings["redis_settings"] = None
-
- # mysql support
- if xget(cfg.getboolean, "mysql", "enabled", False):
- settings["mysql_settings"] = ObjectDict(
- host=cfg.get("mysql", "host"),
- port=cfg.getint("mysql", "port"),
- username=xget(cfg.get, "mysql", "username"),
- password=xget(cfg.get, "mysql", "password"),
- database=xget(cfg.get, "mysql", "database"),
- poolsize=xget(cfg.getint, "mysql", "poolsize", 10),
- debug=xget(cfg.getboolean, "mysql", "debug", False))
- else:
- settings["mysql_settings"] = None
-
- return settings
View
60 appskel/modname/utils.py
@@ -1,60 +0,0 @@
-# coding: utf-8
-#
-$license
-
-import cyclone.escape
-import cyclone.redis
-import cyclone.sqlite
-import cyclone.web
-
-from twisted.enterprise import adbapi
-
-
-class TemplateFields(dict):
- """Helper class to make sure our
- template doesn't fail due to an invalid key"""
- def __getattr__(self, name):
- try:
- return self[name]
- except KeyError:
- return None
-
- def __setattr__(self, name, value):
- self[name] = value
-
-
-class BaseHandler(cyclone.web.RequestHandler):
- #def get_current_user(self):
- # user_json = self.get_secure_cookie("user")
- # if user_json:
- # return cyclone.escape.json_decode(user_json)
-
- def get_user_locale(self):
- lang = self.get_secure_cookie("lang")
- if lang:
- return cyclone.locale.get(lang)
-
-
-class DatabaseMixin(object):
- mysql = None
- redis = None
- sqlite = None
-
- @classmethod
- def setup(self, settings):
- conf = settings.get("sqlite_settings")
- if conf:
- DatabaseMixin.sqlite = cyclone.sqlite.InlineSQLite(conf.database)
-
- conf = settings.get("redis_settings")
- if conf:
- DatabaseMixin.redis = cyclone.redis.lazyConnectionPool(
- conf.host, conf.port, conf.dbid, conf.poolsize)
-
- conf = settings.get("mysql_settings")
- if conf:
- DatabaseMixin.mysql = adbapi.ConnectionPool("MySQLdb",
- host=conf.host, port=conf.port, db=conf.database,
- user=conf.username, passwd=conf.password,
- cp_min=1, cp_max=conf.poolsize,
- cp_reconnect=True, cp_noisy=conf.debug)
View
80 appskel/modname/views.py
@@ -1,80 +0,0 @@
-# coding: utf-8
-#
-$license
-
-import cyclone.escape
-import cyclone.locale
-import cyclone.web
-
-from twisted.internet import defer
-from twisted.python import log
-
-from $modname.utils import BaseHandler
-from $modname.utils import DatabaseMixin
-from $modname.utils import TemplateFields
-
-
-class IndexHandler(BaseHandler):
- def get(self):
- self.render("index.html", hello='world', awesome='bacon')
- # another option would be
- # fields = {'hello': 'world', 'awesome': 'bacon'}
- # self.render('index.html', **fields)
-
- def post(self):
- tpl_fields = TemplateFields()
- tpl_fields['post'] = True
- tpl_fields['ip'] = self.request.remote_ip
- # you can also fetch your own config variables defined in
- # $modname.conf using
- # self.settings.raw.get('section', 'parameter')
- tpl_fields['mysql_host'] = self.settings.raw.get('mysql', 'host')
- self.render("post.html", fields=tpl_fields)
-
-
-class LangHandler(BaseHandler):
- def get(self, lang_code):
- if lang_code in cyclone.locale.get_supported_locales():
- self.set_secure_cookie("lang", lang_code)
-
- self.redirect(self.request.headers.get("Referer",
- self.get_argument("next", "/")))
-
-
-class SampleSQLiteHandler(BaseHandler, DatabaseMixin):
- def get(self):
- if self.sqlite:
- response = self.sqlite.runQuery("select strftime('%Y-%m-%d')")
- self.write({"response": response})
- else:
- self.write("SQLite is disabled\r\n")
-
-
-class SampleRedisHandler(BaseHandler, DatabaseMixin):
- @defer.inlineCallbacks
- def get(self):
- if self.redis:
- try:
- response = yield self.redis.get("foo")
- except Exception, e:
- log.msg("Redis query failed: %s" % str(e))
- raise cyclone.web.HTTPError(503) # Service Unavailable
- else:
- self.write({"response": response})
- else:
- self.write("Redis is disabled\r\n")
-
-
-class SampleMySQLHandler(BaseHandler, DatabaseMixin):
- @defer.inlineCallbacks
- def get(self):
- if self.mysql:
- try:
- response = yield self.mysql.runQuery("select now()")
- except Exception, e:
- log.msg("MySQL query failed: %s" % str(e))
- raise cyclone.web.HTTPError(503) # Service Unavailable
- else:
- self.write({"response": response})
- else:
- self.write("MySQL is disabled\r\n")
View
35 appskel/modname/web.py
@@ -1,35 +0,0 @@
-# coding: utf-8
-#
-$license
-
-import cyclone.locale
-import cyclone.web
-
-from $modname import views
-from $modname import config
-from $modname.utils import DatabaseMixin
-
-
-class Application(cyclone.web.Application):
- def __init__(self, config_file):
- handlers = [
- (r"/", views.IndexHandler),
- (r"/lang/(.+)", views.LangHandler),
- (r"/sample/mysql", views.SampleMySQLHandler),
- (r"/sample/redis", views.SampleRedisHandler),
- (r"/sample/sqlite", views.SampleSQLiteHandler),
- ]
-
- settings = config.parse_config(config_file)
-
- # Initialize locales
- locales = settings.get("locale_path")
- if locales:
- cyclone.locale.load_gettext_translations(locales, "$modname")
-
- # Set up database connections
- DatabaseMixin.setup(settings)
-
- #settings["login_url"] = "/auth/login"
- #settings["autoescape"] = None
- cyclone.web.Application.__init__(self, handlers, **settings)
View
10 appskel/scripts/cookie_secret.py
@@ -1,10 +0,0 @@
-#!/usr/bin/env python
-# coding: utf-8
-#
-$license
-
-import base64
-import uuid
-
-if __name__ == "__main__":
- print(base64.b64encode(uuid.uuid4().bytes + uuid.uuid4().bytes))
View
86 appskel/scripts/debian-init.d
@@ -1,86 +0,0 @@
-#!/bin/sh
-
-### BEGIN INIT INFO
-# Provides: cyclone
-# Required-Start: $all
-# Required-Stop: $all
-# Default-Start: 2 3 4 5
-# Default-Stop: 0 1 6
-# Short-Description: Starts a service on the cyclone web server
-# Description: Foobar
-### END INIT INFO
-
-PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
-DAEMON=/usr/bin/twistd
-
-SERVICE_DIR=/path/to/foobar
-SERVICE_NAME=foobar
-
-PORT=8888
-LISTEN="127.0.0.1"
-CONFIG=$SERVICE_DIR/$SERVICE_NAME.conf
-PIDFILE=/var/run/$SERVICE_NAME.pid
-LOGFILE=/var/log/$SERVICE_NAME.log
-APP=${SERVICE_NAME}.web.Application
-
-USER=www-data
-GROUP=www-data
-DAEMON_OPTS="-u $USER -g $GROUP --pidfile=$PIDFILE --logfile=$LOGFILE cyclone --port $PORT --listen $LISTEN --app $APP -c $CONFIG"
-
-if [ ! -x $DAEMON ]; then
- echo "ERROR: Can't execute $DAEMON."
- exit 1
-fi
-
-if [ ! -d $SERVICE_DIR ]; then
- echo "ERROR: Directory doesn't exist: $SERVICE_DIR"
- exit 1
-fi
-
-start_service() {
- echo -n " * Starting $SERVICE_NAME... "
- start-stop-daemon -Sq -p $PIDFILE -x $DAEMON -- $DAEMON_OPTS
- e=$?
- if [ $e -eq 1 ]; then
- echo "already running"
- return
- fi
-
- if [ $e -eq 255 ]; then
- echo "couldn't start"
- return
- fi
-
- echo "done"
-}
-
-stop_service() {
- echo -n " * Stopping $SERVICE_NAME... "
- start-stop-daemon -Kq -R 10 -p $PIDFILE
- e=$?
- if [ $e -eq 1 ]; then
- echo "not running"
- return
- fi
-
- echo "done"
-}
-
-case "$1" in
- start)
- start_service
- ;;
- stop)
- stop_service
- ;;
- restart)
- stop_service
- start_service
- ;;
- *)
- echo "Usage: /etc/init.d/$SERVICE_NAME {start|stop|restart}" >&2
- exit 1
- ;;
-esac
-
-exit 0
View
109 appskel/scripts/debian-multicore-init.d
@@ -1,109 +0,0 @@
-#!/bin/bash
-
-### BEGIN INIT INFO
-# Provides: cyclone
-# Required-Start: $all
-# Required-Stop: $all
-# Default-Start: 2 3 4 5
-# Default-Stop: 0 1 6
-# Short-Description: Starts a service on the cyclone web server
-# Description: Foobar
-### END INIT INFO
-
-PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
-DAEMON=/usr/bin/twistd
-
-SERVICE_DIR=/path/to/foobar
-SERVICE_NAME=foobar
-
-INSTANCES=4
-START_PORT=9901
-LISTEN="127.0.0.1"
-CONFIG=$SERVICE_DIR/$SERVICE_NAME.conf
-APP=${SERVICE_NAME}.web.Application
-
-USER=www-data
-GROUP=www-data
-
-# Check out the start_service function for other customization options
-# such as setting CPU affinity.
-
-if [ ! -x $DAEMON ]; then
- echo "ERROR: Can't execute $DAEMON."
- exit 1
-fi
-
-if [ ! -d $SERVICE_DIR ]; then
- echo "ERROR: Directory doesn't exist: $SERVICE_DIR"
- exit 1
-fi
-
-start_service() {
- echo -n " * Starting $SERVICE_NAME... "
- for n in `seq 1 $INSTANCES`
- do
- PORT=$[START_PORT]
- PIDFILE=/var/run/$SERVICE_NAME.$PORT.pid
- LOGFILE=/var/log/$SERVICE_NAME.$PORT.log
- DAEMON_OPTS="-u $USER -g $GROUP --pidfile=$PIDFILE --logfile=$LOGFILE cyclone --port $PORT --listen $LISTEN --app $APP -c $CONFIG"
- START_PORT=$[PORT+1]
-
- start-stop-daemon -Sq -p $PIDFILE -x $DAEMON -- $DAEMON_OPTS
- e=$?
- if [ $e -eq 1 ]; then
- echo "already running"
- return
- fi
-
- if [ $e -eq 255 ]; then
- echo "couldn't start"
- return
- fi
-
- # Set CPU affinity
- if [ -x /usr/bin/taskset ]; then
- sleep 1
- /usr/bin/taskset -pc $n `cat $PIDFILE` &> /dev/null
- fi
- done
- echo "done"
-}
-
-stop_service() {
- echo -n " * Stopping $SERVICE_NAME... "
- for n in `seq 1 $INSTANCES`
- do
- PORT=$[START_PORT]
- PIDFILE=/var/run/$SERVICE_NAME.$PORT.pid
- START_PORT=$[PORT+1]
- start-stop-daemon -Kq -R 10 -p $PIDFILE
- e=$?
- if [ $e -eq 1 ]; then
- echo "not running"
- return
- fi
- done
-
- echo "done"
-}
-
-case "$1" in
- start)
- start_service
- ;;
- stop)
- stop_service
- ;;
- restart)
- sp=$START_PORT
- stop_service
- START_PORT=$sp
- start_service
- ;;
- *)
- echo "Usage: /etc/init.d/$SERVICE_NAME {start|stop|restart}" >&2
- exit 1
- ;;
-esac
-
-exit 0
View
21 appskel/scripts/localefix.py
@@ -1,21 +0,0 @@
-#!/usr/bin/env python
-# coding: utf-8
-#
-$license
-
-import re
-import sys
-
-if __name__ == "__main__":
- try:
- filename = sys.argv[1]
- assert filename != "-"
- fd = open(filename)
- except:
- fd = sys.stdin
-
- line_re = re.compile(r'="([^"]+)"')
- for line in fd:
- line = line_re.sub(r"=\\1", line)
- sys.stdout.write(line)
- fd.close()
View
8 appskel/start.sh
@@ -1,8 +0,0 @@
-#!/bin/bash
-
-# check scripts/debian-init.d
-# for 'daemon' version
-
-export PYTHONPATH=`dirname $$0`
-twistd -n cyclone -p 8888 -l 0.0.0.0 \
- -r $modname.web.Application -c $modname.conf $$*
Please sign in to comment.
Something went wrong with that request. Please try again.