[Checkins] SVN: grokapps/SmallELearningDemo/ Added a small e-learning demo application.

Yusei Tahara yusei at domen.cx
Mon Sep 15 18:30:29 EDT 2008


Log message for revision 91184:
  Added a small e-learning demo application.
  

Changed:
  A   grokapps/SmallELearningDemo/
  A   grokapps/SmallELearningDemo/README.txt
  A   grokapps/SmallELearningDemo/TODO.txt
  A   grokapps/SmallELearningDemo/buildout.cfg
  A   grokapps/SmallELearningDemo/setup.py
  A   grokapps/SmallELearningDemo/src/
  A   grokapps/SmallELearningDemo/src/smallelearningdemo/
  A   grokapps/SmallELearningDemo/src/smallelearningdemo/__init__.py
  A   grokapps/SmallELearningDemo/src/smallelearningdemo/answer.py
  A   grokapps/SmallELearningDemo/src/smallelearningdemo/answer_templates/
  A   grokapps/SmallELearningDemo/src/smallelearningdemo/answer_templates/index.pt
  A   grokapps/SmallELearningDemo/src/smallelearningdemo/answercontainer.py
  A   grokapps/SmallELearningDemo/src/smallelearningdemo/answercontainer_templates/
  A   grokapps/SmallELearningDemo/src/smallelearningdemo/answercontainer_templates/index.pt
  A   grokapps/SmallELearningDemo/src/smallelearningdemo/app.py
  A   grokapps/SmallELearningDemo/src/smallelearningdemo/app_templates/
  A   grokapps/SmallELearningDemo/src/smallelearningdemo/app_templates/index.pt
  A   grokapps/SmallELearningDemo/src/smallelearningdemo/app_templates/master.pt
  A   grokapps/SmallELearningDemo/src/smallelearningdemo/configure.zcml
  A   grokapps/SmallELearningDemo/src/smallelearningdemo/exercise.py
  A   grokapps/SmallELearningDemo/src/smallelearningdemo/exercise_templates/
  A   grokapps/SmallELearningDemo/src/smallelearningdemo/exercise_templates/index.pt
  A   grokapps/SmallELearningDemo/src/smallelearningdemo/filecontainer.py
  A   grokapps/SmallELearningDemo/src/smallelearningdemo/filecontainer_templates/
  A   grokapps/SmallELearningDemo/src/smallelearningdemo/filecontainer_templates/index.pt
  A   grokapps/SmallELearningDemo/src/smallelearningdemo/ftesting.zcml
  A   grokapps/SmallELearningDemo/src/smallelearningdemo/testing.py

-=-
Added: grokapps/SmallELearningDemo/README.txt
===================================================================
--- grokapps/SmallELearningDemo/README.txt	                        (rev 0)
+++ grokapps/SmallELearningDemo/README.txt	2008-09-15 22:30:28 UTC (rev 91184)
@@ -0,0 +1,7 @@
+This is a demo application of small e-learning system.
+There are two user types, one is a teacher and the other is a student.
+Teacher can upload exercise and student can upload answer,
+and also teacher can make a comments on student's answer.
+
+The purpose of this application is to show beginners how to make
+a real application by grok.


Property changes on: grokapps/SmallELearningDemo/README.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: grokapps/SmallELearningDemo/TODO.txt
===================================================================
--- grokapps/SmallELearningDemo/TODO.txt	                        (rev 0)
+++ grokapps/SmallELearningDemo/TODO.txt	2008-09-15 22:30:28 UTC (rev 91184)
@@ -0,0 +1,5 @@
+TODO
+
+ * Implement security.
+ * Implement user account management.
+ * Write tests.


Property changes on: grokapps/SmallELearningDemo/TODO.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: grokapps/SmallELearningDemo/buildout.cfg
===================================================================
--- grokapps/SmallELearningDemo/buildout.cfg	                        (rev 0)
+++ grokapps/SmallELearningDemo/buildout.cfg	2008-09-15 22:30:28 UTC (rev 91184)
@@ -0,0 +1,86 @@
+[buildout]
+develop = .
+parts = app data zopectl i18n test
+find-links = http://download.zope.org/zope3.4
+newest = false
+extends= http://grok.zope.org/releaseinfo/grok-0.13.cfg
+versions = versions
+
+[versions]
+lovely.recipe = 0.3.1b5
+zc.recipe.testrunner = 1.0.0
+
+[data]
+recipe = zc.recipe.filestorage
+
+[app]
+recipe = zc.zope3recipes>=0.5.3:application
+eggs = SmallELearningDemo
+site.zcml = <include package="smallelearningdemo" />
+            <include package="zope.app.twisted" />
+
+            <configure i18n_domain="smallelearning">
+              <unauthenticatedPrincipal id="zope.anybody"
+                                        title="Unauthenticated User" />
+              <unauthenticatedGroup id="zope.Anybody"
+                                    title="Unauthenticated Users" />
+              <authenticatedGroup id="zope.Authenticated"
+                                title="Authenticated Users" />
+              <everybodyGroup id="zope.Everybody"
+                              title="All Users" />
+              <principal id="zope.manager"
+                         title="Manager"
+                         login="zope"
+                         password_manager="Plain Text"
+                         password="zope"
+                         />
+
+              <!-- Debugging -->
+              <include package="zope.app.zcmlfiles" file="meta.zcml" />
+              <include package="zope.app.preference" file="meta.zcml" />
+              <include package="zope.app.onlinehelp" file="meta.zcml" />
+              <include package="zope.app.apidoc" file="meta.zcml" />
+
+              <include package="zope.app.zcmlfiles" />
+              <include package="zope.app.tree" />
+              <include package="zope.app.onlinehelp" />
+              <include package="zope.app.renderer" />
+              <include package="zope.app.preference" />
+              <include package="zope.app.apidoc" />
+
+              <!-- Replace the following directive if you don't want
+                   public access -->
+              <grant permission="zope.View"
+                     principal="zope.Anybody" />
+              <grant permission="zope.app.dublincore.view"
+                     principal="zope.Anybody" />
+
+              <role id="zope.Manager" title="Site Manager" />
+              <role id="zope.Member" title="Site Member" />
+              <grantAll role="zope.Manager" />
+              <grant role="zope.Manager"
+                     principal="zope.manager" />
+           </configure>
+
+[data]
+recipe = zc.recipe.filestorage
+
+# this section named so that the start/stop script is called bin/zopectl
+[zopectl]
+recipe = zc.zope3recipes:instance
+application = app
+zope.conf = ${data:zconfig}
+            devmode on
+
+[test]
+recipe = zc.recipe.testrunner
+eggs = SmallELearningDemo
+defaults = ['--tests-pattern', '^f?tests$', '-v']
+
+# this section named so that the i18n scripts are called bin/i18n...
+[i18n]
+recipe = lovely.recipe:i18n
+package = smallelearningdemo
+domain = smallelearningdemo
+location = src/smallelearningdemo
+output = locales

Added: grokapps/SmallELearningDemo/setup.py
===================================================================
--- grokapps/SmallELearningDemo/setup.py	                        (rev 0)
+++ grokapps/SmallELearningDemo/setup.py	2008-09-15 22:30:28 UTC (rev 91184)
@@ -0,0 +1,28 @@
+from setuptools import setup, find_packages
+
+version = '0.0'
+
+setup(name='SmallELearningDemo',
+      version=version,
+      description="",
+      long_description="""\
+""",
+      # Get strings from http://www.python.org/pypi?%3Aaction=list_classifiers
+      classifiers=[], 
+      keywords="",
+      author="Yusei Tahara",
+      author_email="yusei at domen.cx",
+      url="http://qwik.jp/zope3study/",
+      license="ZPL2.1",
+      package_dir={'': 'src'},
+      packages=find_packages('src'),
+      include_package_data=True,
+      zip_safe=False,
+      install_requires=['setuptools',
+                        'grok',
+                        # Add extra requirements here
+                        ],
+      entry_points="""
+      # Add entry points here
+      """,
+      )

Added: grokapps/SmallELearningDemo/src/smallelearningdemo/__init__.py
===================================================================
--- grokapps/SmallELearningDemo/src/smallelearningdemo/__init__.py	                        (rev 0)
+++ grokapps/SmallELearningDemo/src/smallelearningdemo/__init__.py	2008-09-15 22:30:28 UTC (rev 91184)
@@ -0,0 +1 @@
+# this directory is a package

Added: grokapps/SmallELearningDemo/src/smallelearningdemo/answer.py
===================================================================
--- grokapps/SmallELearningDemo/src/smallelearningdemo/answer.py	                        (rev 0)
+++ grokapps/SmallELearningDemo/src/smallelearningdemo/answer.py	2008-09-15 22:30:28 UTC (rev 91184)
@@ -0,0 +1,69 @@
+import grok
+import answercontainer
+import filecontainer
+import zope.interface
+import zope.schema
+import zope.schema
+import zope.component
+
+
+class IAnswer(zope.interface.Interface):
+
+  name = zope.schema.ASCIILine(title=u'Name')
+
+  title = zope.schema.TextLine(title=u'Title')
+
+  comment = zope.schema.Text(title=u'Comment')
+
+
+class Answer(grok.Container):
+
+  grok.implements(IAnswer)
+
+  def __init__(self, name, title, comment):
+    super(Answer, self).__init__()
+
+    self.name = name
+    self.title = title
+    self.comment = comment
+
+    self['files'] = filecontainer.FileContainer()
+
+
+class Add(grok.AddForm):
+
+  grok.context(answercontainer.AnswerContainer)
+
+  form_fields = (grok.AutoFields(Answer) +
+                 grok.Fields(data=zope.schema.Bytes(title=u'Data',
+                                                    default=None,
+                                                    required=False))
+                 )
+
+  @grok.action('Add answer')
+  def add(self, name, title, comment, data):
+    answer = Answer(name=name, title=title, comment=comment)
+
+    # Use add view defined in filecontainer.Add.
+    addview = zope.component.getMultiAdapter((answer['files'], self.request),
+                                             name='add')
+    addview.upload(data=data)
+
+    self.context[answer.name] = answer
+    self.redirect(self.url(answer))
+
+
+class Index(grok.View):
+
+  def getFiles(self):
+    return self.context['files'].values()
+
+
+class Edit(grok.EditForm):
+
+  form_fields = grok.AutoFields(Answer).omit('name')
+
+  @grok.action('Save')
+  def save(self, **data):
+    self.applyData(self.context, **data)
+    self.redirect(self.url(self.context))

Added: grokapps/SmallELearningDemo/src/smallelearningdemo/answer_templates/index.pt
===================================================================
--- grokapps/SmallELearningDemo/src/smallelearningdemo/answer_templates/index.pt	                        (rev 0)
+++ grokapps/SmallELearningDemo/src/smallelearningdemo/answer_templates/index.pt	2008-09-15 22:30:28 UTC (rev 91184)
@@ -0,0 +1,31 @@
+<html metal:use-macro="context/@@master/macros/master">
+<div metal:fill-slot="content">
+
+<h1>Answer</h1>
+
+<div tal:content="context/title"></div>
+
+<pre tal:content="context/comment"></pre>
+
+<h2>Attachments</h2>
+
+<ul>
+<li tal:repeat="i view/getFiles">
+<a tal:attributes="href i/@@absolute_url" tal:content="i/zope:name"></a>
+</li>
+</ul>
+
+<div>
+<a href="answers/add" tal:attributes="href python:view.url('files/add')">Add File</a>
+</div>
+
+<div>
+<a href="edit" tal:attributes="href python:view.url('edit')">Edit</a>
+</div>
+
+<div>
+<a tal:attributes="href context/__parent__/@@absolute_url">Back</a>
+</div>
+
+</div>
+</html>

Added: grokapps/SmallELearningDemo/src/smallelearningdemo/answercontainer.py
===================================================================
--- grokapps/SmallELearningDemo/src/smallelearningdemo/answercontainer.py	                        (rev 0)
+++ grokapps/SmallELearningDemo/src/smallelearningdemo/answercontainer.py	2008-09-15 22:30:28 UTC (rev 91184)
@@ -0,0 +1,11 @@
+import grok
+
+
+class AnswerContainer(grok.Container):
+
+  pass
+
+
+class Index(grok.View):
+
+  pass

Added: grokapps/SmallELearningDemo/src/smallelearningdemo/answercontainer_templates/index.pt
===================================================================
--- grokapps/SmallELearningDemo/src/smallelearningdemo/answercontainer_templates/index.pt	                        (rev 0)
+++ grokapps/SmallELearningDemo/src/smallelearningdemo/answercontainer_templates/index.pt	2008-09-15 22:30:28 UTC (rev 91184)
@@ -0,0 +1,15 @@
+<html metal:use-macro="context/@@master/macros/master">
+<div metal:fill-slot="content">
+
+<h1>Answers</h1>
+
+<ul>
+<li tal:repeat="i context/values">
+<a tal:attributes="href i/@@absolute_url" tal:content="i/zope:name"></a>
+</li>
+</ul>
+
+<a tal:attributes="href python:view.url(context.__parent__)">Back</a>
+
+</div>
+</html>

Added: grokapps/SmallELearningDemo/src/smallelearningdemo/app.py
===================================================================
--- grokapps/SmallELearningDemo/src/smallelearningdemo/app.py	                        (rev 0)
+++ grokapps/SmallELearningDemo/src/smallelearningdemo/app.py	2008-09-15 22:30:28 UTC (rev 91184)
@@ -0,0 +1,18 @@
+import grok
+import zope.interface
+
+
+class SmallELearningDemo(grok.Application, grok.Container):
+
+    pass
+        
+
+class Index(grok.View):
+
+    pass
+
+
+class Master(grok.View):
+    """A view class provides page template macro."""
+
+    grok.context(zope.interface.Interface)

Added: grokapps/SmallELearningDemo/src/smallelearningdemo/app_templates/index.pt
===================================================================
--- grokapps/SmallELearningDemo/src/smallelearningdemo/app_templates/index.pt	                        (rev 0)
+++ grokapps/SmallELearningDemo/src/smallelearningdemo/app_templates/index.pt	2008-09-15 22:30:28 UTC (rev 91184)
@@ -0,0 +1,23 @@
+<html metal:use-macro="context/@@master/macros/master">
+<div metal:fill-slot="content">
+
+<h1>Exercise List</h1>
+
+
+<form action="delete" tal:attributes="action python:view.url('delete')">
+<ul>
+  <li tal:repeat="i context/values">
+    <input type="checkbox" name="names:list" tal:attributes="value i/__name__">
+    <a tal:attributes="href i/@@absolute_url" tal:content="i/title"></a>
+  </li>
+</ul>
+<input tal:condition="python:len(context)" type="submit" value="Delete">
+</form>
+
+
+<div>
+<a href="add" tal:attributes="href python:view.url(name='add')">Add new exercise</a>
+</div>
+
+</div>
+</html>

Added: grokapps/SmallELearningDemo/src/smallelearningdemo/app_templates/master.pt
===================================================================
--- grokapps/SmallELearningDemo/src/smallelearningdemo/app_templates/master.pt	                        (rev 0)
+++ grokapps/SmallELearningDemo/src/smallelearningdemo/app_templates/master.pt	2008-09-15 22:30:28 UTC (rev 91184)
@@ -0,0 +1,15 @@
+<html metal:define-macro="master">
+<head>
+<title>Simple e-Learning Demo</title>
+</head>
+<body style="padding:0;">
+<div style="margin:0; padding:0; height:50px; font-size:24pt; background-color:#bbf">
+Simple e-Learning Demo
+</div>
+
+<div metal:define-slot="content">
+
+</div>
+
+</body>
+</html>

Added: grokapps/SmallELearningDemo/src/smallelearningdemo/configure.zcml
===================================================================
--- grokapps/SmallELearningDemo/src/smallelearningdemo/configure.zcml	                        (rev 0)
+++ grokapps/SmallELearningDemo/src/smallelearningdemo/configure.zcml	2008-09-15 22:30:28 UTC (rev 91184)
@@ -0,0 +1,6 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           xmlns:grok="http://namespaces.zope.org/grok">
+  <include package="grok" />
+  <grok:grok package="." />
+  <include package="zope.app.file" />
+</configure>

Added: grokapps/SmallELearningDemo/src/smallelearningdemo/exercise.py
===================================================================
--- grokapps/SmallELearningDemo/src/smallelearningdemo/exercise.py	                        (rev 0)
+++ grokapps/SmallELearningDemo/src/smallelearningdemo/exercise.py	2008-09-15 22:30:28 UTC (rev 91184)
@@ -0,0 +1,80 @@
+import grok
+import app
+import answercontainer
+import filecontainer
+import zope.interface
+import zope.schema
+import zope.component
+
+
+class IExercise(zope.interface.Interface):
+
+  name = zope.schema.ASCIILine(title=u'Name')
+
+  title = zope.schema.TextLine(title=u'Title')
+
+  description = zope.schema.Text(title=u'Description')
+
+
+class Exercise(grok.Container):
+
+  grok.implements(IExercise)
+
+  def __init__(self, name, title, description):
+    super(Exercise, self).__init__()
+    self.name = name
+    self.title = title
+    self.description = description
+
+    self['answers'] = answercontainer.AnswerContainer()
+    self['files'] = filecontainer.FileContainer()
+
+
+class Add(grok.AddForm):
+
+  grok.context(app.SmallELearningDemo)
+
+  form_fields = (grok.AutoFields(Exercise) +
+                 grok.Fields(data=zope.schema.Bytes(title=u'Data',
+                                                    default=None,
+                                                    required=False))
+                 )
+
+  @grok.action('Add exercise')
+  def add(self, name, title, description, data):
+    exercise = Exercise(name=name, title=title, description=description)
+
+    # Use add view defined in filecontainer.Add.
+    addview = zope.component.getMultiAdapter((exercise['files'], self.request),
+                                             name='add')
+    addview.upload(data=data)
+
+    self.context[exercise.name] = exercise
+    self.redirect(self.url(exercise))
+
+
+class Index(grok.View):
+
+  def getFiles(self):
+    return self.context['files'].values()
+
+
+class Edit(grok.EditForm):
+
+  form_fields = grok.AutoFields(Exercise).omit('name')
+
+  @grok.action('Save')
+  def save(self, **data):
+    self.applyData(self.context, **data)
+    self.redirect(self.url(self.context))
+
+
+class Delete(grok.View):
+
+  grok.context(app.SmallELearningDemo)
+
+  def render(self):
+    for name in self.request.form.get('names', ()):
+      if name in self.context:
+        del self.context[name]
+    self.redirect(self.url(self.context))

Added: grokapps/SmallELearningDemo/src/smallelearningdemo/exercise_templates/index.pt
===================================================================
--- grokapps/SmallELearningDemo/src/smallelearningdemo/exercise_templates/index.pt	                        (rev 0)
+++ grokapps/SmallELearningDemo/src/smallelearningdemo/exercise_templates/index.pt	2008-09-15 22:30:28 UTC (rev 91184)
@@ -0,0 +1,34 @@
+<html metal:use-macro="context/@@master/macros/master">
+<div metal:fill-slot="content">
+
+<h1 tal:content="context/title"></h1>
+
+<pre tal:content="context/description"></pre>
+
+<div>
+  <a href="edit" tal:attributes="href python:view.url(name='edit')">Edit</a>
+</div>
+
+<h2><a href="files" tal:attributes="href python:view.url(name='files')">Attachments</a></h2>
+
+
+<ul>
+  <li tal:repeat="i view/getFiles">
+    <a tal:attributes="href i/@@absolute_url" tal:content="i/zope:name"></a>
+  </li>
+</ul>
+
+<div>
+  <a href="answers" tal:attributes="href python:view.url('answers')">Answer List</a>
+</div>
+
+<div>
+  <a href="answers/add" tal:attributes="href python:view.url('answers/add')">Add Answer</a>
+</div>
+
+<div>
+<a tal:attributes="href python:view.url(context.__parent__)">Back</a>
+</div>
+
+</div>
+</html>

Added: grokapps/SmallELearningDemo/src/smallelearningdemo/filecontainer.py
===================================================================
--- grokapps/SmallELearningDemo/src/smallelearningdemo/filecontainer.py	                        (rev 0)
+++ grokapps/SmallELearningDemo/src/smallelearningdemo/filecontainer.py	2008-09-15 22:30:28 UTC (rev 91184)
@@ -0,0 +1,31 @@
+import grok
+import zope.app.file
+
+
+class FileContainer(grok.Container):
+
+  pass
+
+
+class Add(grok.AddForm):
+
+  grok.context(FileContainer)
+
+  form_fields = grok.AutoFields(zope.app.file.interfaces.IFile).select('data')
+
+  @grok.action('Add file')
+  def add(self, **data):
+    self.upload(**data)
+    self.redirect(self.url(self.context.__parent__))
+
+  def upload(self, **data):
+    fileupload = self.request['form.data']
+    if fileupload and fileupload.filename:
+      contenttype = fileupload.headers.get('Content-Type')
+      file_ = zope.app.file.File(data['data'], contenttype)
+      self.context[fileupload.filename] = file_
+
+
+class Index(grok.View):
+
+  pass

Added: grokapps/SmallELearningDemo/src/smallelearningdemo/filecontainer_templates/index.pt
===================================================================
--- grokapps/SmallELearningDemo/src/smallelearningdemo/filecontainer_templates/index.pt	                        (rev 0)
+++ grokapps/SmallELearningDemo/src/smallelearningdemo/filecontainer_templates/index.pt	2008-09-15 22:30:28 UTC (rev 91184)
@@ -0,0 +1,13 @@
+<html metal:use-macro="context/@@master/macros/master">
+<div metal:fill-slot="content">
+
+<ul>
+<li tal:repeat="i context/values">
+<a tal:attributes="href i/@@absolute_url" tal:content="i/zope:name"></a>
+</li>
+</ul>
+
+<a href="add" tal:attributes="href python:view.url(name='add')">Add File</a>
+
+</div>
+</html>

Added: grokapps/SmallELearningDemo/src/smallelearningdemo/ftesting.zcml
===================================================================
--- grokapps/SmallELearningDemo/src/smallelearningdemo/ftesting.zcml	                        (rev 0)
+++ grokapps/SmallELearningDemo/src/smallelearningdemo/ftesting.zcml	2008-09-15 22:30:28 UTC (rev 91184)
@@ -0,0 +1,35 @@
+<configure
+   xmlns="http://namespaces.zope.org/zope"
+   i18n_domain="smallelearningdemo"
+   package="smallelearningdemo"
+   >
+
+  <include package="grok" />
+  <include package="smallelearningdemo" />
+
+  <!-- Typical functional testing security setup -->
+  <securityPolicy
+      component="zope.app.securitypolicy.zopepolicy.ZopeSecurityPolicy"
+      />
+
+  <unauthenticatedPrincipal
+      id="zope.anybody"
+      title="Unauthenticated User"
+      />
+  <grant
+      permission="zope.View"
+      principal="zope.anybody"
+      />
+
+  <principal
+      id="zope.mgr"
+      title="Manager"
+      login="mgr"
+      password="mgrpw"
+      />
+
+  <role id="zope.Manager" title="Site Manager" />
+  <grantAll role="zope.Manager" />
+  <grant role="zope.Manager" principal="zope.mgr" />
+
+</configure>

Added: grokapps/SmallELearningDemo/src/smallelearningdemo/testing.py
===================================================================
--- grokapps/SmallELearningDemo/src/smallelearningdemo/testing.py	                        (rev 0)
+++ grokapps/SmallELearningDemo/src/smallelearningdemo/testing.py	2008-09-15 22:30:28 UTC (rev 91184)
@@ -0,0 +1,7 @@
+import os.path
+import smallelearningdemo
+from zope.app.testing.functional import ZCMLLayer
+
+ftesting_zcml = os.path.join(
+    os.path.dirname(smallelearningdemo.__file__), 'ftesting.zcml')
+FunctionalLayer = ZCMLLayer(ftesting_zcml, __name__, 'FunctionalLayer')



More information about the Checkins mailing list