[cig-commits] r4102 - in cs/framework/trunk/cig: . web

leif at geodynamics.org leif at geodynamics.org
Tue Jul 25 12:30:41 PDT 2006


Author: leif
Date: 2006-07-25 12:30:41 -0700 (Tue, 25 Jul 2006)
New Revision: 4102

Added:
   cs/framework/trunk/cig/web/
   cs/framework/trunk/cig/web/__init__.py
   cs/framework/trunk/cig/web/django.py
Log:
Checked-in my Django-from-Pyre app generation script.
Under construction!  Use at your own risk.


Added: cs/framework/trunk/cig/web/__init__.py
===================================================================

Added: cs/framework/trunk/cig/web/django.py
===================================================================
--- cs/framework/trunk/cig/web/django.py	2006-07-25 00:23:33 UTC (rev 4101)
+++ cs/framework/trunk/cig/web/django.py	2006-07-25 19:30:41 UTC (rev 4102)
@@ -0,0 +1,417 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                              cig.web
+#
+# Copyright (c) 2006, Computational Infrastructure for Geodynamics
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+#
+#    * Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+#
+#    * Redistributions in binary form must reproduce the above
+#    copyright notice, this list of conditions and the following
+#    disclaimer in the documentation and/or other materials provided
+#    with the distribution.
+#
+#    * Neither the name of the Computational Infrastructure for
+#    Geodynamics nor the names of its contributors may be used to
+#    endorse or promote products derived from this software without
+#    specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+
+import os, sys
+from os.path import dirname, join
+
+import Specfem3DGlobe
+appTag = "Specfem3DGlobe"
+webDir = join(dirname(Specfem3DGlobe.__file__), "web")
+appDir = join(webDir, appTag)
+appUrl = appTag.lower()
+templateDir = join(appDir, "templates", appTag)
+
+
+class Generator(object):
+
+    def beginComponent(self, component): pass
+    def endComponent(self, component): pass
+    def onInventory(self, inventory): pass
+    def onProperty(self, prop): pass
+
+    def generate(self, components):
+        self.begin()
+        for component in components:
+            self.visitComponent(component)
+        self.end()
+
+    def begin(self): pass
+
+    def visitComponent(self, component):
+        from pyre.inventory.Facility import Facility
+
+        pyreInternalProps = ["help", "mode"]
+
+        self.beginComponent(component)
+
+        inventory = component.inventory
+        self.onInventory(inventory)
+
+        for prop in inventory._traitRegistry.itervalues():
+            if isinstance(prop, Facility):
+                continue
+            if prop.name in pyreInternalProps or prop.name.startswith("help-"):
+                continue
+            self.onProperty(prop)
+
+        self.endComponent(component)
+        
+        return
+
+    def end(self): pass
+
+
+
+
+class Debug(Generator):
+    def beginComponent(self, component): print component.name
+    def onProperty(self, prop): print "    ", prop.name, prop
+
+
+from pyre.inventory.properties.Bool import Bool
+from pyre.inventory.properties.Dimensional import Dimensional
+from pyre.inventory.properties.Float import Float
+from pyre.inventory.properties.Integer import Integer
+from pyre.inventory.properties.String import String
+
+propTypeMap = {
+    Bool:         ('BooleanField', ''),
+    Dimensional:  ('FloatField', 'max_digits=19, decimal_places=10'),
+    Float:        ('FloatField', 'max_digits=19, decimal_places=10'),
+    Integer:      ('IntegerField', ''),
+    String:       ('CharField', 'maxlength=255'),
+}
+
+class Models(Generator):
+
+    def __init__(self):
+        self.stream = None
+    
+    def begin(self):
+        self.stream = open(join(appDir, "models.py"), "w")
+        print >> self.stream
+        print >> self.stream, "from django.db import models"
+
+    def beginComponent(self, component):
+        print >> self.stream
+        print >> self.stream, "class %s(models.Model):" % component.__class__.__name__
+
+    def onProperty(self, prop):
+        if not propTypeMap.has_key(prop.__class__):
+            print >> self.stream, "    # skipped", prop.name, prop
+            return
+        varName = prop.name.replace('-', '_')
+        modelClass, args = propTypeMap[prop.__class__]
+        print >> self.stream, "    %s = models.%s(%s)" % (varName, modelClass, args)
+
+    def end(self):
+        self.stream.close()
+
+
+class FormTemplate(Generator):
+    
+    def __init__(self):
+        self.stream = None
+    
+    def beginComponent(self, component):
+        self.stream = open(join(templateDir, component.name.lower() + "_form.html"), "w")
+        print >> self.stream, '''
+{% extends "''' + appTag + '''/base.html" %}
+
+{% block content %}
+
+<h1>''' +  component.__class__.__name__ + '''</h1>
+
+{% if form.has_errors %}
+<h2>Please correct the following error{{ form.error_dict|pluralize }}:</h2>
+{% endif %}
+
+<form method="post" action=".">
+    <table border="0">
+'''
+        return
+
+    def onProperty(self, prop):
+        if not propTypeMap.has_key(prop.__class__):
+            return
+        varName = prop.name.replace('-', '_')
+        if prop.__class__ == Bool:
+            print >> self.stream, '''
+        <tr>
+            <td align="right" valign="top">{{ form.''' + varName + ''' }}</td>
+            <td valign="top"><label for="id_''' + varName + '''">''' + prop.name + '''</label></td>
+            <td valign="top">{% if form.''' + varName + '''.errors %}<span class=error>{{ form.''' + varName + '''.errors|join:", " }}</span>{% endif %}</td>
+        </tr>'''
+        else:
+            print >> self.stream, '''
+        <tr>
+            <td align=right valign="top"><label for="id_''' + varName + '''">''' + prop.name + ''':</label></td>
+            <td valign="top">{{ form.''' + varName + ''' }}</td>
+            <td valign="top">{% if form.''' + varName + '''.errors %}<span class=error>{{ form.''' + varName + '''.errors|join:", " }}</span>{% endif %}</td>
+        </tr>'''
+        return
+
+
+    def endComponent(self, component):
+        print >> self.stream, '''
+    </table>
+    <p><input type="submit" value="Save" />
+</form>
+{% endblock %}'''
+        return
+
+
+
+class ConfirmDeleteTemplate(Generator):
+    
+    def beginComponent(self, component):
+        stream = open(join(templateDir, component.name.lower() + "_confirm_delete.html"), "w")
+        print >> stream, '''
+{% extends "''' + appTag + '''/base.html" %}
+
+{% block content %}
+
+<h1>Delete ''' +  component.__class__.__name__ + '''</h1>
+
+<form method="post" action=".">
+    <p>Are you sure you want to delete ''' +  component.name.lower() + ''' {{ object.id }}?
+    <p><input type="submit" value="Delete" />
+</form>
+{% endblock %}
+'''
+        stream.close()
+        return
+
+
+class ListTemplate(Generator):
+    
+    def __init__(self):
+        self.stream = None
+        self.fieldTd = None
+    
+    def beginComponent(self, component):
+        self.stream = open(join(templateDir, component.name.lower() + "_list.html"), "w")
+        print >> self.stream, '''
+{% extends "''' + appTag + '''/base.html" %}
+
+{% block content %}
+
+<h1>''' +  component.__class__.__name__ + ''' List</h1>
+
+{% if object_list %}
+    <table border="0">
+        <tr>
+            <th align="left" valign="top">id</th>
+            <th align="left" valign="top">actions</th>'''
+        self.fieldTd = ""
+        return
+
+    def onProperty(self, prop):
+        if not propTypeMap.has_key(prop.__class__):
+            return
+        columnHeader = prop.name.replace('-', ' ')
+        varName = prop.name.replace('-', '_')
+        print >> self.stream, '''            <th align="left" valign="top">''' + columnHeader + '''</th>'''
+        self.fieldTd += '''
+            <td valign="top">{{ object.''' + varName + ''' }}</td>'''        
+        return
+
+
+    def endComponent(self, component):
+        print >> self.stream, '''
+        </tr>
+
+        {% for object in object_list %}
+        <tr>
+            <th valign="top">{{ object.id }}</th>
+            <td valign="top"><a href="{{ object.id }}/">Edit</a> <a href="{{ object.id }}/delete/">Delete</a></td>''' + self.fieldTd + '''
+        </tr>
+        {% endfor %}
+
+    </table>
+{% else %}
+    <p>You have no ''' + component.name.lower() + '''s.</p>
+{% endif %}
+
+<p><a href="create/">Create ''' + component.name.lower() + '''</a>
+
+{% endblock %}'''
+        return
+
+
+
+
+def startapp():
+    #from django.core.management import execute_manager
+    #import settings
+    #execute_manager(settings, ["manage.py", "startapp", appTag])
+    os.makedirs(appDir)
+    open(join(webDir, "__init__.py"), "w").close()
+    open(join(appDir, "__init__.py"), "w").close()
+    stream = open(join(appDir, "views.py"), "w")
+    print >> stream, "# Create your views here."
+    stream.close()
+
+
+def generateBaseHtml():
+    stream = open(join(templateDir, "base.html"), "w")
+    print >> stream, '''<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+    <link rel="stylesheet" href="style.css" />
+    <title>{% block title %}''' + appTag + '''{% endblock %}</title>
+</head>
+
+<body>
+    <div id="sidebar">
+        {% block sidebar %}
+        <ul>
+            <li><a href="/''' + appUrl + '''/">Home</a></li>
+        </ul>
+        {% endblock %}
+    </div>
+
+    <div id="content">
+        {% block content %}{% endblock %}
+    </div>
+</body>'''
+    stream.close()
+
+
+def generateHomeHtml(components):
+    stream = open(join(templateDir, "home.html"), "w")
+    print >> stream, '''
+{% extends "''' + appTag + '''/base.html" %}
+
+{% block content %}
+
+<h1>Home</h1>
+
+<ul>'''
+    for component in components:
+        print >> stream, '''
+    <li><a href="''' + component.name.lower() + '''/">''' + component.__class__.__name__ + '''</a>'''
+    print >> stream, '''
+</ul>
+
+{% endblock %}'''
+    stream.close()
+
+
+def generateUrlsPy(components):
+    stream = open(join(appDir, "urls.py"), "w")
+    print >> stream, '''
+
+from django.conf.urls.defaults import *
+from models import ''',
+    classNames = [component.__class__.__name__ for component in components]    
+    print >> stream, ', '.join(classNames)
+
+    for component in components:
+        className = component.__class__.__name__
+        componentName = component.name.lower()
+        url = '/' + appUrl + '/' + componentName + '/'
+        print >> stream, '''
+# %(className)s
+
+%(componentName)s_list_detail_args = {
+    'queryset': %(className)s.objects.all(),
+    'allow_empty': True,
+}
+
+%(componentName)s_create_update_args = {
+    'model': %(className)s,
+    'post_save_redirect': '%(url)s',
+    }
+
+%(componentName)s_delete_args = {
+    'model': %(className)s,
+    'post_delete_redirect': '%(url)s',
+    }
+
+''' % locals()
+
+    print >> stream, '''
+# URLs
+
+urlpatterns = patterns('',
+    (r'^$', 'django.views.generic.simple.direct_to_template', { 'template': '%(appTag)s/home.html' }),'''  % { 'appTag': appTag }
+
+    
+    for component in components:
+        componentName = component.name.lower()
+        print >> stream, r'''
+    (r'^%(componentName)s/$', 'django.views.generic.list_detail.object_list', %(componentName)s_list_detail_args),
+    (r'^%(componentName)s/create/$', 'django.views.generic.create_update.create_object', %(componentName)s_create_update_args),
+    (r'^%(componentName)s/(?P<object_id>\d+)/$', 'django.views.generic.create_update.update_object', %(componentName)s_create_update_args),
+    (r'^%(componentName)s/(?P<object_id>\d+)/delete/$', 'django.views.generic.create_update.delete_object', %(componentName)s_delete_args),
+''' % locals()
+    print >> stream, '''
+)'''
+    stream.close()
+
+
+def generate():
+    from Specfem3DGlobe.Mesher import Mesher
+    from Specfem3DGlobe.Model import Model as SpecfemModel
+    from Specfem3DGlobe.Solver import Solver
+
+    class Model(SpecfemModel): componentNames = [ "model" ]
+
+    os.makedirs(templateDir)
+
+    components = [Mesher('mesher'),
+                  Model('model'),
+                  Solver('solver'),
+                  ]
+    generatorClasses = [Models, FormTemplate, ConfirmDeleteTemplate, ListTemplate]
+
+    for cls in generatorClasses:
+        generator = cls()
+        generator.generate(components)
+
+    generateBaseHtml()
+    generateHomeHtml(components)
+    generateUrlsPy(components)
+
+
+def main():
+    startapp()
+    generate()
+
+
+main()
+
+# end of file



More information about the cig-commits mailing list