commit 2bb49ff965621646206db4defb0f96794bc259df Author: j <0x006A@0x2620.org> Date: Tue Mar 20 15:07:49 2007 +0000 import oilarchive diff --git a/README.txt b/README.txt new file mode 100644 index 0000000..03ba46c --- /dev/null +++ b/README.txt @@ -0,0 +1,4 @@ +oilarchive + +This is a TurboGears (http://www.turbogears.org) project. It can be +started by running the start-oilarchive.py script. \ No newline at end of file diff --git a/dev.cfg b/dev.cfg new file mode 100644 index 0000000..1991649 --- /dev/null +++ b/dev.cfg @@ -0,0 +1,65 @@ +[global] +# This is where all of your settings go for your development environment +# Settings that are the same for both development and production +# (such as template engine, encodings, etc.) all go in +# oilarchive/config/app.cfg + +# DATABASE + +# pick the form for your database +# sqlobject.dburi="postgres://username@hostname/databasename" +# sqlobject.dburi="mysql://username:password@hostname:port/databasename" +# sqlobject.dburi="sqlite:///file_name_and_path" + +# If you have sqlite, here's a simple default to get you started +# in development +sqlobject.dburi="sqlite://%(current_dir_uri)s/devdata.sqlite" + + +# if you are using a database or table type without transactions +# (MySQL default, for example), you should turn off transactions +# by prepending notrans_ on the uri +# sqlobject.dburi="notrans_mysql://username:password@hostname:port/databasename" + +# for Windows users, sqlite URIs look like: +# sqlobject.dburi="sqlite:///drive_letter:/path/to/file" + +# SERVER + +# Some server parameters that you may want to tweak +# server.socket_port=8080 + +# Enable the debug output at the end on pages. +# log_debug_info_filter.on = False + +server.environment="development" +autoreload.package="oilarchive" + +# session_filter.on = True + +# Set to True if you'd like to abort execution if a controller gets an +# unexpected parameter. False by default +tg.strict_parameters = True + +# LOGGING +# Logging configuration generally follows the style of the standard +# Python logging module configuration. Note that when specifying +# log format messages, you need to use *() for formatting variables. +# Deployment independent log configuration is in oilarchive/config/log.cfg +[logging] + +[[loggers]] +[[[oilarchive]]] +level='DEBUG' +qualname='oilarchive' +handlers=['debug_out'] + +[[[allinfo]]] +level='INFO' +handlers=['debug_out'] + +[[[access]]] +level='INFO' +qualname='turbogears.access' +handlers=['access_out'] +propagate=0 diff --git a/oilarchive.egg-info/PKG-INFO b/oilarchive.egg-info/PKG-INFO new file mode 100644 index 0000000..c73d670 --- /dev/null +++ b/oilarchive.egg-info/PKG-INFO @@ -0,0 +1,15 @@ +Metadata-Version: 1.0 +Name: oilarchive +Version: 1.0 +Summary: UNKNOWN +Home-page: UNKNOWN +Author: UNKNOWN +Author-email: UNKNOWN +License: UNKNOWN +Description: UNKNOWN +Platform: UNKNOWN +Classifier: Development Status :: 3 - Alpha +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Classifier: Framework :: TurboGears diff --git a/oilarchive.egg-info/SOURCES.txt b/oilarchive.egg-info/SOURCES.txt new file mode 100644 index 0000000..48e6015 --- /dev/null +++ b/oilarchive.egg-info/SOURCES.txt @@ -0,0 +1,21 @@ +README.txt +setup.py +start-oilarchive.py +oilarchive/__init__.py +oilarchive/controllers.py +oilarchive/json.py +oilarchive/model.py +oilarchive/release.py +oilarchive.egg-info/PKG-INFO +oilarchive.egg-info/SOURCES.txt +oilarchive.egg-info/dependency_links.txt +oilarchive.egg-info/not-zip-safe +oilarchive.egg-info/paster_plugins.txt +oilarchive.egg-info/requires.txt +oilarchive.egg-info/sqlobject.txt +oilarchive.egg-info/top_level.txt +oilarchive/config/__init__.py +oilarchive/templates/__init__.py +oilarchive/tests/__init__.py +oilarchive/tests/test_controllers.py +oilarchive/tests/test_model.py diff --git a/oilarchive.egg-info/dependency_links.txt b/oilarchive.egg-info/dependency_links.txt new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/oilarchive.egg-info/dependency_links.txt @@ -0,0 +1 @@ + diff --git a/oilarchive.egg-info/not-zip-safe b/oilarchive.egg-info/not-zip-safe new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/oilarchive.egg-info/not-zip-safe @@ -0,0 +1 @@ + diff --git a/oilarchive.egg-info/paster_plugins.txt b/oilarchive.egg-info/paster_plugins.txt new file mode 100644 index 0000000..14fec70 --- /dev/null +++ b/oilarchive.egg-info/paster_plugins.txt @@ -0,0 +1,2 @@ +TurboGears +PasteScript diff --git a/oilarchive.egg-info/requires.txt b/oilarchive.egg-info/requires.txt new file mode 100644 index 0000000..f06697f --- /dev/null +++ b/oilarchive.egg-info/requires.txt @@ -0,0 +1 @@ +TurboGears >= 1.0 \ No newline at end of file diff --git a/oilarchive.egg-info/sqlobject.txt b/oilarchive.egg-info/sqlobject.txt new file mode 100644 index 0000000..e5448bf --- /dev/null +++ b/oilarchive.egg-info/sqlobject.txt @@ -0,0 +1,2 @@ +db_module=oilarchive.model +history_dir=$base/oilarchive/sqlobject-history diff --git a/oilarchive.egg-info/top_level.txt b/oilarchive.egg-info/top_level.txt new file mode 100644 index 0000000..74d1097 --- /dev/null +++ b/oilarchive.egg-info/top_level.txt @@ -0,0 +1 @@ +oilarchive diff --git a/oilarchive/__init__.py b/oilarchive/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/oilarchive/config/__init__.py b/oilarchive/config/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/oilarchive/config/app.cfg b/oilarchive/config/app.cfg new file mode 100644 index 0000000..3e39cad --- /dev/null +++ b/oilarchive/config/app.cfg @@ -0,0 +1,127 @@ +[global] +# The settings in this file should not vary depending on the deployment +# environment. dev.cfg and prod.cfg are the locations for +# the different deployment settings. Settings in this file will +# be overridden by settings in those other files. + +# The commented out values below are the defaults + +# VIEW + +# which view (template engine) to use if one is not specified in the +# template name +# tg.defaultview = "kid" + +# The following kid settings determine the settings used by the kid serializer. + +# One of (html|html-strict|xhtml|xhtml-strict|xml|json) +# kid.outputformat="html" + +# kid.encoding="utf-8" + +# The sitetemplate is used for overall styling of a site that +# includes multiple TurboGears applications +# tg.sitetemplate="" + +# Allow every exposed function to be called as json, +# tg.allow_json = False + +# List of Widgets to include on every page. +# for exemple ['turbogears.mochikit'] +# tg.include_widgets = [] + +# Set to True if the scheduler should be started +# tg.scheduler = False + +# VISIT TRACKING +# Each visit to your application will be assigned a unique visit ID tracked via +# a cookie sent to the visitor's browser. +# -------------- + +# Enable Visit tracking +visit.on=True + +# Number of minutes a visit may be idle before it expires. +# visit.timeout=20 + +# The name of the cookie to transmit to the visitor's browser. +# visit.cookie.name="tg-visit" + +# Domain name to specify when setting the cookie (must begin with . according to +# RFC 2109). The default (None) should work for most cases and will default to +# the machine to which the request was made. NOTE: localhost is NEVER a valid +# value and will NOT WORK. +# visit.cookie.domain=None + +# Specific path for the cookie +# visit.cookie.path="/" + +# The name of the VisitManager plugin to use for visitor tracking. +visit.manager="sqlobject" + +# Database class to use for visit tracking +visit.soprovider.model = "oilarchive.model.Visit" + +# IDENTITY +# General configuration of the TurboGears Identity management module +# -------- + +# Switch to turn on or off the Identity management module +identity.on=True + +# [REQUIRED] URL to which CherryPy will internally redirect when an access +# control check fails. If Identity management is turned on, a value for this +# option must be specified. +identity.failure_url="/login" + +# identity.provider='sqlobject' + +# The names of the fields on the login form containing the visitor's user ID +# and password. In addition, the submit button is specified simply so its +# existence may be stripped out prior to passing the form data to the target +# controller. +# identity.form.user_name="user_name" +# identity.form.password="password" +# identity.form.submit="login" + +# What sources should the identity provider consider when determining the +# identity associated with a request? Comma separated list of identity sources. +# Valid sources: form, visit, http_auth +# identity.source="form,http_auth,visit" + +# SqlObjectIdentityProvider +# Configuration options for the default IdentityProvider +# ------------------------- + +# The classes you wish to use for your Identity model. Remember to not use reserved +# SQL keywords for class names (at least unless you specify a different table +# name using sqlmeta). +identity.soprovider.model.user="oilarchive.model.User" +identity.soprovider.model.group="oilarchive.model.Group" +identity.soprovider.model.permission="oilarchive.model.Permission" + +# The password encryption algorithm used when comparing passwords against what's +# stored in the database. Valid values are 'md5' or 'sha1'. If you do not +# specify an encryption algorithm, passwords are expected to be clear text. +# +# The SqlObjectProvider *will* encrypt passwords supplied as part of your login +# form. If you set the password through the password property, like: +# my_user.password = 'secret' +# the password will be encrypted in the database, provided identity is up and +# running, or you have loaded the configuration specifying what encryption to +# use (in situations where identity may not yet be running, like tests). + +# identity.soprovider.encryption_algorithm=None + +# compress the data sends to the web browser +# [/] +# gzip_filter.on = True +# gzip_filter.mime_types = ["application/x-javascript", "text/javascript", "text/html", "text/css", "text/plain"] + +[/static] +static_filter.on = True +static_filter.dir = "%(top_level_dir)s/static" + +[/favicon.ico] +static_filter.on = True +static_filter.file = "%(top_level_dir)s/static/images/favicon.ico" diff --git a/oilarchive/config/log.cfg b/oilarchive/config/log.cfg new file mode 100644 index 0000000..ce776f8 --- /dev/null +++ b/oilarchive/config/log.cfg @@ -0,0 +1,29 @@ +# LOGGING +# Logging is often deployment specific, but some handlers and +# formatters can be defined here. + +[logging] +[[formatters]] +[[[message_only]]] +format='*(message)s' + +[[[full_content]]] +format='*(asctime)s *(name)s *(levelname)s *(message)s' + +[[handlers]] +[[[debug_out]]] +class='StreamHandler' +level='DEBUG' +args='(sys.stdout,)' +formatter='full_content' + +[[[access_out]]] +class='StreamHandler' +level='INFO' +args='(sys.stdout,)' +formatter='message_only' + +[[[error_out]]] +class='StreamHandler' +level='ERROR' +args='(sys.stdout,)' diff --git a/oilarchive/controllers.py b/oilarchive/controllers.py new file mode 100644 index 0000000..9a3996b --- /dev/null +++ b/oilarchive/controllers.py @@ -0,0 +1,46 @@ +from turbogears import controllers, expose +# from model import * +from turbogears import identity, redirect +from cherrypy import request, response +# from oilarchive import json +# import logging +# log = logging.getLogger("oilarchive.controllers") + +class Root(controllers.RootController): + @expose(template="oilarchive.templates.welcome") + # @identity.require(identity.in_group("admin")) + def index(self): + import time + # log.debug("Happy TurboGears Controller Responding For Duty") + return dict(now=time.ctime()) + + @expose(template="oilarchive.templates.login") + def login(self, forward_url=None, previous_url=None, *args, **kw): + + if not identity.current.anonymous \ + and identity.was_login_attempted() \ + and not identity.get_identity_errors(): + raise redirect(forward_url) + + forward_url=None + previous_url= request.path + + if identity.was_login_attempted(): + msg=_("The credentials you supplied were not correct or " + "did not grant access to this resource.") + elif identity.get_identity_errors(): + msg=_("You must provide your credentials before accessing " + "this resource.") + else: + msg=_("Please log in.") + forward_url= request.headers.get("Referer", "/") + + response.status=403 + return dict(message=msg, previous_url=previous_url, logging_in=True, + original_parameters=request.params, + forward_url=forward_url) + + @expose() + def logout(self): + identity.current.logout() + raise redirect("/") diff --git a/oilarchive/json.py b/oilarchive/json.py new file mode 100644 index 0000000..d62d43d --- /dev/null +++ b/oilarchive/json.py @@ -0,0 +1,35 @@ +# A JSON-based API(view) for your app. +# Most rules would look like: +# +# @jsonify.when("isinstance(obj, YourClass)") +# def jsonify_yourclass(obj): +# return [obj.val1, obj.val2] +# +# @jsonify can convert your objects to following types: +# lists, dicts, numbers and strings + +from turbojson.jsonify import jsonify + +from turbojson.jsonify import jsonify_sqlobject +from oilarchive.model import User, Group, Permission + +@jsonify.when('isinstance(obj, Group)') +def jsonify_group(obj): + result = jsonify_sqlobject( obj ) + result["users"] = [u.user_name for u in obj.users] + result["permissions"] = [p.permission_name for p in obj.permissions] + return result + +@jsonify.when('isinstance(obj, User)') +def jsonify_user(obj): + result = jsonify_sqlobject( obj ) + del result['password'] + result["groups"] = [g.group_name for g in obj.groups] + result["permissions"] = [p.permission_name for p in obj.permissions] + return result + +@jsonify.when('isinstance(obj, Permission)') +def jsonify_permission(obj): + result = jsonify_sqlobject( obj ) + result["groups"] = [g.group_name for g in obj.groups] + return result diff --git a/oilarchive/model.py b/oilarchive/model.py new file mode 100644 index 0000000..16fdb70 --- /dev/null +++ b/oilarchive/model.py @@ -0,0 +1,105 @@ +from datetime import datetime +from turbogears.database import PackageHub +from sqlobject import * +from turbogears import identity + +hub = PackageHub("oilarchive") +__connection__ = hub + +# identity models. +class Visit(SQLObject): + class sqlmeta: + table = "visit" + + visit_key = StringCol(length=40, alternateID=True, + alternateMethodName="by_visit_key") + created = DateTimeCol(default=datetime.now) + expiry = DateTimeCol() + + def lookup_visit(cls, visit_key): + try: + return cls.by_visit_key(visit_key) + except SQLObjectNotFound: + return None + lookup_visit = classmethod(lookup_visit) + +class VisitIdentity(SQLObject): + visit_key = StringCol(length=40, alternateID=True, + alternateMethodName="by_visit_key") + user_id = IntCol() + + +class Group(SQLObject): + """ + An ultra-simple group definition. + """ + + # names like "Group", "Order" and "User" are reserved words in SQL + # so we set the name to something safe for SQL + class sqlmeta: + table = "tg_group" + + group_name = UnicodeCol(length=16, alternateID=True, + alternateMethodName="by_group_name") + display_name = UnicodeCol(length=255) + created = DateTimeCol(default=datetime.now) + + # collection of all users belonging to this group + users = RelatedJoin("User", intermediateTable="user_group", + joinColumn="group_id", otherColumn="user_id") + + # collection of all permissions for this group + permissions = RelatedJoin("Permission", joinColumn="group_id", + intermediateTable="group_permission", + otherColumn="permission_id") + + +class User(SQLObject): + """ + Reasonably basic User definition. Probably would want additional attributes. + """ + # names like "Group", "Order" and "User" are reserved words in SQL + # so we set the name to something safe for SQL + class sqlmeta: + table = "tg_user" + + user_name = UnicodeCol(length=16, alternateID=True, + alternateMethodName="by_user_name") + email_address = UnicodeCol(length=255, alternateID=True, + alternateMethodName="by_email_address") + display_name = UnicodeCol(length=255) + password = UnicodeCol(length=40) + created = DateTimeCol(default=datetime.now) + + # groups this user belongs to + groups = RelatedJoin("Group", intermediateTable="user_group", + joinColumn="user_id", otherColumn="group_id") + + def _get_permissions(self): + perms = set() + for g in self.groups: + perms = perms | set(g.permissions) + return perms + + def _set_password(self, cleartext_password): + "Runs cleartext_password through the hash algorithm before saving." + hash = identity.encrypt_password(cleartext_password) + self._SO_set_password(hash) + + def set_password_raw(self, password): + "Saves the password as-is to the database." + self._SO_set_password(password) + + + +class Permission(SQLObject): + permission_name = UnicodeCol(length=16, alternateID=True, + alternateMethodName="by_permission_name") + description = UnicodeCol(length=255) + + groups = RelatedJoin("Group", + intermediateTable="group_permission", + joinColumn="permission_id", + otherColumn="group_id") + + diff --git a/oilarchive/release.py b/oilarchive/release.py new file mode 100644 index 0000000..b735895 --- /dev/null +++ b/oilarchive/release.py @@ -0,0 +1,14 @@ +# Release information about oilarchive + +version = "1.0" + +# description = "Your plan to rule the world" +# long_description = "More description about your plan" +# author = "Your Name Here" +# email = "YourEmail@YourDomain" +# copyright = "Vintage 2006 - a good year indeed" + +# if it's open source, you might want to specify these +# url = "http://yourcool.site/" +# download_url = "http://yourcool.site/download" +# license = "MIT" diff --git a/oilarchive/static/css/style.css b/oilarchive/static/css/style.css new file mode 100644 index 0000000..1bc7d64 --- /dev/null +++ b/oilarchive/static/css/style.css @@ -0,0 +1,124 @@ +/* + * Quick mash-up of CSS for the TG quick start page. + */ + +html, body, th, td { + color: black; + background-color: #ddd; + font: x-small "Lucida Grande", "Lucida Sans Unicode", geneva, verdana, sans-serif; + margin: 0; + padding: 0; +} + +#header { + height: 80px; + width: 777px; + background: blue URL('../images/header_inner.png') no-repeat; + border-left: 1px solid #aaa; + border-right: 1px solid #aaa; + margin: 0 auto 0 auto; +} + +a.link, a, a.active { + color: #369; +} + + +#main_content { + color: black; + font-size: 127%; + background-color: white; + width: 757px; + margin: 0 auto 0 auto; + border-left: 1px solid #aaa; + border-right: 1px solid #aaa; + padding: 10px; +} + +#sidebar { + border: 1px solid #aaa; + background-color: #eee; + margin: 0.5em; + padding: 1em; + float: right; + width: 200px; + font-size: 88%; +} + +#sidebar h2 { + margin-top: 0; +} + +#sidebar ul { + margin-left: 1.5em; + padding-left: 0; +} + +h1,h2,h3,h4,h5,h6,#getting_started_steps { + font-family: "Century Schoolbook L", Georgia, serif; + font-weight: bold; +} + +h2 { + font-size: 150%; +} + +#getting_started_steps a { + text-decoration: none; +} + +#getting_started_steps a:hover { + text-decoration: underline; +} + +#getting_started_steps li { + font-size: 80%; + margin-bottom: 0.5em; +} + +#getting_started_steps h2 { + font-size: 120%; +} + +#getting_started_steps p { + font: 100% "Lucida Grande", "Lucida Sans Unicode", geneva, verdana, sans-serif; +} + +#footer { + border: 1px solid #aaa; + border-top: 0px none; + color: #999; + background-color: white; + padding: 10px; + font-size: 80%; + text-align: center; + width: 757px; + margin: 0 auto 1em auto; +} + +.code { + font-family: monospace; +} + +span.code { + font-weight: bold; + background: #eee; +} + +#status_block { + margin: 0 auto 0.5em auto; + padding: 15px 10px 15px 55px; + background: #cec URL('../images/ok.png') left center no-repeat; + border: 1px solid #9c9; + width: 450px; + font-size: 120%; + font-weight: bolder; +} + +.notice { + margin: 0.5em auto 0.5em auto; + padding: 15px 10px 15px 55px; + width: 450px; + background: #eef URL('../images/info.png') left center no-repeat; + border: 1px solid #cce; +} diff --git a/oilarchive/static/images/favicon.ico b/oilarchive/static/images/favicon.ico new file mode 100644 index 0000000..332557b Binary files /dev/null and b/oilarchive/static/images/favicon.ico differ diff --git a/oilarchive/static/images/header_inner.png b/oilarchive/static/images/header_inner.png new file mode 100644 index 0000000..2b2d87d Binary files /dev/null and b/oilarchive/static/images/header_inner.png differ diff --git a/oilarchive/static/images/info.png b/oilarchive/static/images/info.png new file mode 100644 index 0000000..329c523 Binary files /dev/null and b/oilarchive/static/images/info.png differ diff --git a/oilarchive/static/images/ok.png b/oilarchive/static/images/ok.png new file mode 100644 index 0000000..fee6751 Binary files /dev/null and b/oilarchive/static/images/ok.png differ diff --git a/oilarchive/static/images/tg_under_the_hood.png b/oilarchive/static/images/tg_under_the_hood.png new file mode 100644 index 0000000..bc9c79c Binary files /dev/null and b/oilarchive/static/images/tg_under_the_hood.png differ diff --git a/oilarchive/static/images/under_the_hood_blue.png b/oilarchive/static/images/under_the_hood_blue.png new file mode 100644 index 0000000..90e84b7 Binary files /dev/null and b/oilarchive/static/images/under_the_hood_blue.png differ diff --git a/oilarchive/templates/__init__.py b/oilarchive/templates/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/oilarchive/templates/login.kid b/oilarchive/templates/login.kid new file mode 100644 index 0000000..a819cfc --- /dev/null +++ b/oilarchive/templates/login.kid @@ -0,0 +1,112 @@ + + + + + + Login + + + + +
+

Login

+

${message}

+
+ + + + + + + + + + + + +
+ + + +
+ + + +
+ +
+ + + + +
+
+ + diff --git a/oilarchive/templates/master.kid b/oilarchive/templates/master.kid new file mode 100644 index 0000000..f13dad6 --- /dev/null +++ b/oilarchive/templates/master.kid @@ -0,0 +1,48 @@ + + + + + + + Your title goes here + + + + + + +
+ + Login + + + Welcome ${tg.identity.user.display_name}. + Logout + +
+ +
+
+ +
+ + +
+ + + + diff --git a/oilarchive/templates/welcome.kid b/oilarchive/templates/welcome.kid new file mode 100644 index 0000000..879afe7 --- /dev/null +++ b/oilarchive/templates/welcome.kid @@ -0,0 +1,48 @@ + + + + +Welcome to TurboGears + + + +
Your application is now running
+ +
+
    +
  1. +

    Model

    +

    Design models in the model.py.
    + Edit dev.cfg to use a different backend, or start with a pre-configured SQLite database.
    + Use script tg-admin sql create to create the database tables.

    +
  2. +
  3. +

    View

    +

    Edit html-like templates in the /templates folder;
    + Put all static contents in the /static folder.

    +
  4. +
  5. +

    Controller

    +

    Edit controllers.py and build your + website structure with the simplicity of Python objects.
    + TurboGears will automatically reload itself when you modify your project.

    +
  6. +
+
If you create something cool, please let people know, and consider contributing something back to the community.
+
+ + + diff --git a/oilarchive/tests/__init__.py b/oilarchive/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/oilarchive/tests/test_controllers.py b/oilarchive/tests/test_controllers.py new file mode 100644 index 0000000..0ff6816 --- /dev/null +++ b/oilarchive/tests/test_controllers.py @@ -0,0 +1,33 @@ +import turbogears +from nose import with_setup +from turbogears import testutil +from oilarchive.controllers import Root +import cherrypy + +def teardown_func(): + """Tests for apps using identity need to stop CP/TG after each test to + stop the VisitManager thread. See http://trac.turbogears.org/turbogears/ticket/1217 + for details. + """ + turbogears.startup.stopTurboGears() + +cherrypy.root = Root() + +def test_method(): + "the index method should return a string called now" + import types + result = testutil.call(cherrypy.root.index) + assert type(result["now"]) == types.StringType +test_method = with_setup(teardown=teardown_func)(test_method) + +def test_indextitle(): + "The indexpage should have the right title" + testutil.createRequest("/") + assert "Welcome to TurboGears" in cherrypy.response.body[0] +test_indextitle = with_setup(teardown=teardown_func)(test_indextitle) + +def test_logintitle(): + "login page should have the right title" + testutil.createRequest("/login") + assert "Login" in cherrypy.response.body[0] +test_logintitle = with_setup(teardown=teardown_func)(test_logintitle) diff --git a/oilarchive/tests/test_model.py b/oilarchive/tests/test_model.py new file mode 100644 index 0000000..2b8ec0e --- /dev/null +++ b/oilarchive/tests/test_model.py @@ -0,0 +1,23 @@ +# If your project uses a database, you can set up database tests +# similar to what you see below. Be sure to set the db_uri to +# an appropriate uri for your testing database. sqlite is a good +# choice for testing, because you can use an in-memory database +# which is very fast. + +from turbogears import testutil, database +# from oilarchive.model import YourDataClass, User + +# database.set_db_uri("sqlite:///:memory:") + +# class TestUser(testutil.DBTest): +# def get_model(self): +# return User +# +# def test_creation(self): +# "Object creation should set the name" +# obj = User(user_name = "creosote", +# email_address = "spam@python.not", +# display_name = "Mr Creosote", +# password = "Wafer-thin Mint") +# assert obj.display_name == "Mr Creosote" + diff --git a/sample-prod.cfg b/sample-prod.cfg new file mode 100644 index 0000000..18e267d --- /dev/null +++ b/sample-prod.cfg @@ -0,0 +1,78 @@ +[global] +# This is where all of your settings go for your production environment. +# You'll copy this file over to your production server and provide it +# as a command-line option to your start script. +# Settings that are the same for both development and production +# (such as template engine, encodings, etc.) all go in +# oilarchive/config/app.cfg + +# DATABASE + +# pick the form for your database +# sqlobject.dburi="postgres://username@hostname/databasename" +# sqlobject.dburi="mysql://username:password@hostname:port/databasename" +# sqlobject.dburi="sqlite:///file_name_and_path" + +# If you have sqlite, here's a simple default to get you started +# in development +sqlobject.dburi="sqlite://%(current_dir_uri)s/devdata.sqlite" + + +# if you are using a database or table type without transactions +# (MySQL default, for example), you should turn off transactions +# by prepending notrans_ on the uri +# sqlobject.dburi="notrans_mysql://username:password@hostname:port/databasename" + +# for Windows users, sqlite URIs look like: +# sqlobject.dburi="sqlite:///drive_letter:/path/to/file" + + +# SERVER + +server.environment="production" + +# Sets the number of threads the server uses +# server.thread_pool = 1 + +# if this is part of a larger site, you can set the path +# to the TurboGears instance here +# server.webpath="" + +# session_filter.on = True + +# Set to True if you'd like to abort execution if a controller gets an +# unexpected parameter. False by default +# tg.strict_parameters = False + +# Set the following to True if you are deploying your app using mod_proxy, +# mod_rewrite or any other mechanism that forwards requests to your app. +# base_url_filter.on = False +# base_url_filter.use_x_forwarded_host = False + +# LOGGING +# Logging configuration generally follows the style of the standard +# Python logging module configuration. Note that when specifying +# log format messages, you need to use *() for formatting variables. +# Deployment independent log configuration is in oilarchive/config/log.cfg +[logging] + +[[handlers]] + +[[[access_out]]] +# set the filename as the first argument below +args="('server.log',)" +class='FileHandler' +level='INFO' +formatter='message_only' + +[[loggers]] +[[[oilarchive]]] +level='ERROR' +qualname='oilarchive' +handlers=['error_out'] + +[[[access]]] +level='INFO' +qualname='turbogears.access' +handlers=['access_out'] +propagate=0 diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..f79ca11 --- /dev/null +++ b/setup.py @@ -0,0 +1,62 @@ +from setuptools import setup, find_packages +from turbogears.finddata import find_package_data + +import os +execfile(os.path.join("oilarchive", "release.py")) + +setup( + name="oilarchive", + version=version, + + # uncomment the following lines if you fill them out in release.py + #description=description, + #author=author, + #author_email=email, + #url=url, + #download_url=download_url, + #license=license, + + install_requires = [ + "TurboGears >= 1.0", + ], + scripts = ["start-oilarchive.py"], + zip_safe=False, + packages=find_packages(), + package_data = find_package_data(where='oilarchive', + package='oilarchive'), + keywords = [ + # Use keywords if you'll be adding your package to the + # Python Cheeseshop + + # if this has widgets, uncomment the next line + # 'turbogears.widgets', + + # if this has a tg-admin command, uncomment the next line + # 'turbogears.command', + + # if this has identity providers, uncomment the next line + # 'turbogears.identity.provider', + + # If this is a template plugin, uncomment the next line + # 'python.templating.engines', + + # If this is a full application, uncomment the next line + # 'turbogears.app', + ], + classifiers = [ + 'Development Status :: 3 - Alpha', + 'Operating System :: OS Independent', + 'Programming Language :: Python', + 'Topic :: Software Development :: Libraries :: Python Modules', + 'Framework :: TurboGears', + # if this is an application that you'll distribute through + # the Cheeseshop, uncomment the next line + # 'Framework :: TurboGears :: Applications', + + # if this is a package that includes widgets that you'll distribute + # through the Cheeseshop, uncomment the next line + # 'Framework :: TurboGears :: Widgets', + ], + test_suite = 'nose.collector', + ) + diff --git a/setup.pyc b/setup.pyc new file mode 100644 index 0000000..183c074 Binary files /dev/null and b/setup.pyc differ diff --git a/start-oilarchive.py b/start-oilarchive.py new file mode 100755 index 0000000..bc0c7de --- /dev/null +++ b/start-oilarchive.py @@ -0,0 +1,25 @@ +#!/Library/Frameworks/Python.framework/Versions/2.4/Resources/Python.app/Contents/MacOS/Python +import pkg_resources +pkg_resources.require("TurboGears") + +from turbogears import update_config, start_server +import cherrypy +cherrypy.lowercase_api = True +from os.path import * +import sys + +# first look on the command line for a desired config file, +# if it's not on the command line, then +# look for setup.py in this directory. If it's not there, this script is +# probably installed +if len(sys.argv) > 1: + update_config(configfile=sys.argv[1], + modulename="oilarchive.config") +elif exists(join(dirname(__file__), "setup.py")): + update_config(configfile="dev.cfg",modulename="oilarchive.config") +else: + update_config(configfile="prod.cfg",modulename="oilarchive.config") + +from oilarchive.controllers import Root + +start_server(Root()) diff --git a/test.cfg b/test.cfg new file mode 100644 index 0000000..8dbcf04 --- /dev/null +++ b/test.cfg @@ -0,0 +1,5 @@ +# You can place test-specific configuration options here (like test db uri, etc) +# + +sqlobject.dburi = "sqlite:///:memory:" +