[cig-commits] r11604 - in cs/portal/trunk/seismo/SeismoWebPortal: . templates/SeismoWebPortal

leif at geodynamics.org leif at geodynamics.org
Wed Mar 26 19:31:24 PDT 2008


Author: leif
Date: 2008-03-26 19:31:24 -0700 (Wed, 26 Mar 2008)
New Revision: 11604

Added:
   cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/desktop.html
   cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/readme.html
   cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/trash.html
Removed:
   cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/event_confirm_delete.html
   cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/mesh_confirm_delete.html
   cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/model_confirm_delete.html
   cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/object_lists.html
   cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/specfem3dglobeparameters_confirm_delete.html
   cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/stationlist_confirm_delete.html
Modified:
   cs/portal/trunk/seismo/SeismoWebPortal/forms.py
   cs/portal/trunk/seismo/SeismoWebPortal/gui.py
   cs/portal/trunk/seismo/SeismoWebPortal/models.py
   cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/event_detail.html
   cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/home.html
   cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/mineosparameters_form.html
   cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/source_confirm_delete.html
   cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/source_form.html
   cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/specfem3dglobeparameters_form.html
   cs/portal/trunk/seismo/SeismoWebPortal/views.py
Log:
Implemented the home folder and the trash can.  Eliminated all delete
confirmation pages (except one), since the trash will have an "undo"
feature.

Now all objects live forever.  This fixes the domino/jenga/"smart
bomb" effect when the user deletes an object referenced by other
objects.  It also fixes about 1/2 of the logging problem.


Modified: cs/portal/trunk/seismo/SeismoWebPortal/forms.py
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/forms.py	2008-03-27 01:01:59 UTC (rev 11603)
+++ cs/portal/trunk/seismo/SeismoWebPortal/forms.py	2008-03-27 02:31:24 UTC (rev 11604)
@@ -187,7 +187,8 @@
             phone       = new_data['phone'],
             invite      = invite,
             approved    = approved,
-            home        = Folder.newFolder(user.username, user)
+            home        = Folder.newFolder("Home", user),
+            trash       = Folder.newFolder("Trash", user),
             )
         
         # Log-in the new user.
@@ -245,7 +246,8 @@
             userInfo = user.userinfo
         except UserInfo.DoesNotExist:
             userInfo = UserInfo()
-            userInfo.home = Folder.newFolder(user.username, user)
+            userInfo.home = Folder.newFolder("Home", user)
+            userInfo.trash = Folder.newFolder("Trash", user)
             user.userinfo = userInfo
         # Save the new user.
         user.first_name      = new_data['first_name']

Modified: cs/portal/trunk/seismo/SeismoWebPortal/gui.py
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/gui.py	2008-03-27 01:01:59 UTC (rev 11603)
+++ cs/portal/trunk/seismo/SeismoWebPortal/gui.py	2008-03-27 02:31:24 UTC (rev 11604)
@@ -83,11 +83,15 @@
 
 class Node(object):
 
-    def __init__(self, name, title):
+    def __init__(self, name, title, url = None):
         self.name = name
         self.title = title
+        self._url = url
 
-    def urlFragment(self): return self.name + '/'
+    def url(self, root):
+        if self._url:
+            return self._url
+        return root + self.name + '/'
 
     def renderNavTree(self, urlRoot, path, level, design):
         return ""
@@ -122,7 +126,7 @@
         return [self] + item.resolve(request, path)
 
     def renderNavTree(self, urlRoot, path, level, design):
-        url = urlRoot + self.urlFragment()
+        url = self.url(urlRoot)
         items = ""
         selected = False
         if len(path) > level and path[level] is self:
@@ -145,10 +149,13 @@
             raise Http404
         return [self]
 
-    def urlFragment(self): return self.name
+    def url(self, root):
+        if self._url:
+            return self._url
+        return root + self.name
 
     def renderNavTree(self, urlRoot, path, level, design):
-        url = urlRoot + self.urlFragment()
+        url = self.url(urlRoot)
         selected = len(path) > level and path[level] is self
         return design.renderNavTreeFile(self.title, url, selected)
 
@@ -172,7 +179,7 @@
         bc = [(self.url, self.title)]
         urlRoot = self.url
         for node in path:
-            url = urlRoot + node.urlFragment()
+            url = node.url(urlRoot)
             crumb = url, node.title
             bc.append(crumb)
         return bc

Modified: cs/portal/trunk/seismo/SeismoWebPortal/models.py
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/models.py	2008-03-27 01:01:59 UTC (rev 11603)
+++ cs/portal/trunk/seismo/SeismoWebPortal/models.py	2008-03-27 02:31:24 UTC (rev 11604)
@@ -51,7 +51,7 @@
             name = "untitled %d" % number
         fsNode = FSNode(name = name,
                         owner = owner,
-                        parent = Folder.homeFolder(owner),
+                        parent = Folder.homeFolder(owner).fsNode,
                         contents = contents)
         fsNode.save()
         return fsNode
@@ -66,6 +66,11 @@
         return userInfo.home
 
     @classmethod
+    def trashFolder(cls, user):
+        userInfo = UserInfo.getOrCreate(user)
+        return userInfo.trash
+
+    @classmethod
     def newFolder(cls, name, owner):
         folder = Folder()
         folder.save()
@@ -190,7 +195,7 @@
         return 2.0 * (log10(self.scalarSeismicMoment()) - 16.1)/3.0
 
     def beachball(self):
-        src = "/specfem3dglobe/config/events/sources/%d/beachball.gif" % self.id
+        src = "/specfem3dglobe/beachballs/%d.gif" % self.id
         return """<img class=beachball src="%s">""" % src
 
     def cmtSolution(self):
@@ -713,7 +718,8 @@
     approved = models.BooleanField(default=False)
     help_visible = models.BooleanField(default=True)
 
-    home = models.ForeignKey(Folder)
+    home = models.ForeignKey(Folder, related_name='userinfo_home_set')
+    trash = models.ForeignKey(Folder, related_name='userinfo_trash_set')
 
     def __str__(self): return self.user.username
 
@@ -733,8 +739,9 @@
         try:
             userInfo = user.userinfo
         except UserInfo.DoesNotExist:
-            newHome = Folder.newFolder(user.username, user)
-            userInfo = UserInfo(home = newHome)
+            newHome = Folder.newFolder("Home", user)
+            newTrash = Folder.newFolder("Trash", user)
+            userInfo = UserInfo(home = newHome, trash = newTrash)
             user.userinfo = userInfo
             user.save()
             userInfo.save()

Added: cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/desktop.html
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/desktop.html	                        (rev 0)
+++ cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/desktop.html	2008-03-27 02:31:24 UTC (rev 11604)
@@ -0,0 +1,2 @@
+
+<h2>desktop</h2>

Deleted: cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/event_confirm_delete.html
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/event_confirm_delete.html	2008-03-27 01:01:59 UTC (rev 11603)
+++ cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/event_confirm_delete.html	2008-03-27 02:31:24 UTC (rev 11604)
@@ -1,7 +0,0 @@
-
-<h2>delete event</h2>
-
-<form method="post" action="/specfem3dglobe/config/events/{{ object.id }}/delete/">
-    <p>Are you sure you want to delete the event "{{ object }}"?
-    <p><input type="submit" value="Delete" />
-</form>

Modified: cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/event_detail.html
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/event_detail.html	2008-03-27 01:01:59 UTC (rev 11603)
+++ cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/event_detail.html	2008-03-27 02:31:24 UTC (rev 11604)
@@ -40,7 +40,7 @@
         <tbody>
         {% for source in object.sources %}
         <tr>
-            <th><a href="../sources/{{ source.id }}/">{{ source.eventName }}</a></th>
+            <th><a href="{{ source.id }}/">{{ source.eventName }}</a></th>
             <td class=float>{{ source.timeShift|stringformat:".4f" }}</td>
             <td class=float>{{ source.halfDuration|stringformat:".4f" }}</td>
             <td class=float>{{ source.latitude|stringformat:".4f" }}&deg;</td>

Modified: cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/home.html
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/home.html	2008-03-27 01:01:59 UTC (rev 11603)
+++ cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/home.html	2008-03-27 02:31:24 UTC (rev 11604)
@@ -1,49 +1,8 @@
 
-<h2>home</h2>
+<h2>Home</h2>
 
-<h3>quick start</h3>
-
-<p>To set up a new simulation, proceed as follows:
-
-<ol>
-    <li>Click "Simulations".
-    <li>Click "New...".
-    <li>Enter the parameters for the simulation.
-    <li>Click "Save & Run".
-</ol>
-
-<p>A pair of example simulations are provided. To run one of the
-examples, click the simulation name on the "Simulations" page. Then
-click "Run".
-
-<h3>what next?</h3>
-
-<p>You can monitor your simulation by scanning the "status" column.
-When your simulation completes, there should be a download link titled
-<code>seismograms.tar.gz</code> in the "output" column of the
-simulation's information page. Click this link to download the output of
-the simulation: seismograms in ASCII and <a href="http://www.llnl.gov/sac/">SAC</a> format.
-Then, <a href="/specfem3dglobe/samples/UTILS.tar.gz">download the
-post-processing utilities</a> to process the data.  See
-<a href="/specfem3dglobe/doc/manual_SPECFEM3D_GLOBE.pdf">the manual</a>
-for further details.
-
-<p>As you become familiar with the code, feel free to explore this
-site, creating your own custom events, meshes, and models.
-
-<h3>tips</h3>
-
-<p><img src="/specfem3dglobe/pics/kml.icon.gif"> If you have
-<a href="http://earth.google.com/">Google Earth</a> installed on your
-computer, you can use it to map events and stations.  Just look for
-the KML icon and click it!</p>
-
-<h3>contact</h3>
-
-<p>Please send bug reports and suggestions to <a href="mailto:portal at geodynamics.org">portal at geodynamics.org</a>.
-
-
-<h3>additional documentation</h3>
-
-<p><a href="/specfem3dglobe/doc/manual_SPECFEM3D_GLOBE.pdf">
-   <img src="/specfem3dglobe/pics/adobe-pdf.icon.gif">SPECFEM 3D GLOBE User Manual</a>
+<ul>
+{% for item in folder %}
+    <li><a href="{{item.url}}">{{ item.icon }} {{ item.name }}</a></li>
+{% endfor %}
+</ul>

Deleted: cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/mesh_confirm_delete.html
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/mesh_confirm_delete.html	2008-03-27 01:01:59 UTC (rev 11603)
+++ cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/mesh_confirm_delete.html	2008-03-27 02:31:24 UTC (rev 11604)
@@ -1,7 +0,0 @@
-
-<h2>delete mesh</h2>
-
-<form method="post" action="/specfem3dglobe/config/specfem3dglobe/meshes/{{ object.id }}/delete/">
-    <p>Are you sure you want to delete the mesh "{{ object }}"?
-    <p><input type="submit" value="Delete" />
-</form>

Modified: cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/mineosparameters_form.html
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/mineosparameters_form.html	2008-03-27 01:01:59 UTC (rev 11603)
+++ cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/mineosparameters_form.html	2008-03-27 02:31:24 UTC (rev 11604)
@@ -1,5 +1,5 @@
 
-<h2>{% if object %}edit {{ object }}{% else %}new mineos parameters{% endif %}</h2>
+<h2>{% if object %}edit {{ object }}{% else %}new mineos parameter set{% endif %}</h2>
 
 <form method="post" action="{{ action }}">
 

Deleted: cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/model_confirm_delete.html
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/model_confirm_delete.html	2008-03-27 01:01:59 UTC (rev 11603)
+++ cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/model_confirm_delete.html	2008-03-27 02:31:24 UTC (rev 11604)
@@ -1,7 +0,0 @@
-
-<h2>delete model</h2>
-
-<form method="post" action="/specfem3dglobe/config/specfem3dglobe/models/{{ object.id }}/delete/">
-    <p>Are you sure you want to delete the model "{{ object }}"?
-    <p><input type="submit" value="Delete" />
-</form>

Deleted: cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/object_lists.html
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/object_lists.html	2008-03-27 01:01:59 UTC (rev 11603)
+++ cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/object_lists.html	2008-03-27 02:31:24 UTC (rev 11604)
@@ -1,324 +0,0 @@
-
-<h2>Configuration</h2>
-
-<p>
-{% if event_list %}
-    <table rules=groups class="cool">
-        <colgroup><col class=odd><col class=even><col class=odd><col class=even><col class=odd><col class=even><col class=odd><col class=even></colgroup>
-
-        <thead>
-        <tr>
-            <th>name</th>
-            <th>type</th>
-            <th>CMT</th>
-            <th>M<sub>w</sub></th>
-            <th>latitude</th>
-            <th>longitude</th>
-            <th>depth</th>
-            <th>downloads</th>
-        </tr>
-        </thead>
-
-        <tbody>
-        {% for object in event_list %}
-        <tr>
-            <th><a href="events/{{ object.id }}/">{{ object }}</a></th>
-            {% if object.singleSource %}
-            <td>point-source</td>
-            <td>{{ object.singleSource.beachball }}</td>
-            <td class=float>{{ object.singleSource.momentMagnitude|stringformat:".2f" }}</td>
-            <td class=float>{{ object.singleSource.latitude|stringformat:".4f" }}&deg;</td>
-            <td class=float>{{ object.singleSource.longitude|stringformat:".4f" }}&deg;</td>
-            <td class=float>{{ object.singleSource.depth|stringformat:".4f" }}</td>
-            {% else %}
-            <td>finite-source<br><span class=inlineInfo>N<sub>sources</sub> = {{ object.source_set.count }}</span></td>
-            <td class=notApplicable>-</td>
-            <td class=notApplicable>-</td>
-            <td class=notApplicable>-</td>
-            <td class=notApplicable>-</td>
-            <td class=notApplicable>-</td>
-            {% endif %}
-            <td>
-                <a href="events/{{ object.id }}/gearth.kml"><img src="/specfem3dglobe/pics/kml.icon.gif" title="View in Google Earth" alt="View in Google Earth"></a>
-                [<a href="events/{{ object.id }}/CMTSOLUTION.txt">text</a>]
-            </td>
-        </tr>
-        {% endfor %}
-        </tbody>
-
-    </table>
-{% else %}
-    <p>You have no events.
-{% endif %}
-
-<p>
-{% if specfem3dglobe_parameters_list %}
-    <table rules=groups class="cool">
-        <caption>Specfem 3D Globe Parameter Sets</caption>
-        
-        <colgroup><col class=odd><col class=even><col class=odd><col class=even><col class=odd></colgroup>
-
-        <thead>
-        <tr><th>name</th><th>mesh</th><th>model</th><th>station list</th><th>record length</th></tr>
-        </thead>
-        
-        <tbody>
-        {% for object in specfem3dglobe_parameters_list %}
-        <tr>
-            <th><a href="specfem3dglobe/parameters/{{ object.id }}/">{{ object }}</a></th>
-            <td><a href="specfem3dglobe/meshes/{{ object.mesh.id }}/">{{ object.mesh }}</a><br>
-                <span class=inlineInfo>shortest period &cong; {{ object.mesh.shortestPeriod|stringformat:".0f" }}s</span></td>
-            <td><a href="specfem3dglobe/models/{{ object.model.id }}/">{{ object.model }}</a></td>
-            <td><a href="stations/{{ object.stations.id }}/">{{ object.stations }}</a></td>
-            <td>{{ object.record_length }} minutes</td>
-        </tr>
-        {% endfor %}
-        </tbody>
-
-    </table>
-{% else %}
-    <p>You have no Specfem 3D Globe parameter sets.
-{% endif %}
-
-
-<p>
-{% if mesh_list %}
-    <table border=1 rules=groups class="cool">
-        <caption>meshes</caption>
-
-        <colgroup><col class=odd></colgroup>
-        <colgroup><col class=even></colgroup>
-        <colgroup><col class=odd><col class=even></colgroup>
-        <colgroup><col class=odd><col class=even></colgroup>
-        <colgroup><col class=odd><col class=even></colgroup>
-        <colgroup><col class=odd><col class=even></colgroup>
-        <colgroup><col class=odd></colgroup>
-        <colgroup><col class=even></colgroup>
-        <colgroup><col class=odd></colgroup>
-
-        <thead>
-        <tr>
-            <th></th>
-            <th></th>
-            <th colspan=2 class=colgroup>nproc</th>
-            <th colspan=2 class=colgroup>nex</th>
-            <th colspan=2 class=colgroup>angular width</th>
-            <th colspan=2 class=colgroup>center</th>
-            <th></th>
-            <th></th>
-        </tr>
-
-        <tr>
-            <th>name</th>
-            <th>nchunks</th>
-            <th>&eta;</th>
-            <th>&xi;</th>
-            <th>&eta;</th>
-            <th>&xi;</th>
-            <th>&eta;</th>
-            <th>&xi;</th>
-            <th>latitude</th>
-            <th>longitude</th>
-            <th>&gamma; rotation azimuth</th>
-            <th>shortest period (s)</th>
-        </tr>
-        </thead>
-
-        <tbody>
-        {% for object in mesh_list %}
-        <tr>
-            <th><a href="specfem3dglobe/meshes/{{ object.id }}/">{{ object }}</a></th>
-            <td class=int>{{ object.nchunks }}</td>
-            <td class=int>{{ object.nproc_eta }}</td>
-            <td class=int>{{ object.nproc_xi }}</td>
-            <td class=int>{{ object.nex_eta }}</td>
-            <td class=int>{{ object.nex_xi }}</td>
-            {% ifequal object.nchunks 6 %}
-            <td class=notApplicable>n/a</td>
-            <td class=notApplicable>n/a</td>
-            <td class=notApplicable>n/a</td>
-            <td class=notApplicable>n/a</td>
-            <td class=notApplicable>n/a</td>
-            {% else %}
-            <td class=float>{{ object.angular_width_eta }}&deg;</td>
-            <td class=float>{{ object.angular_width_xi }}&deg;</td>
-            <td class=float>{{ object.center_latitude }}&deg;</td>
-            <td class=float>{{ object.center_longitude }}&deg;</td>
-            <td class=float>{{ object.gamma_rotation_azimuth }}&deg;</td>
-            {% endifequal %}
-            <td class=int>{{ object.shortestPeriod|stringformat:".0f" }}</td>
-        </tr>
-        {% endfor %}
-        </tbody>
-
-    </table>
-{% else %}
-    <p>You have no meshes.
-{% endif %}
-
-
-<p>
-{% if model_list %}
-    <table rules=groups class="cool">
-        <caption>models</caption>
-
-        <colgroup><col class=odd></colgroup>
-        <colgroup><col class=even></colgroup>
-        <colgroup><col class=odd><col class=even><col class=odd><col class=even><col class=odd><col class=even></colgroup>
-
-        <thead>
-        <tr>
-            <th>name</th>
-            <th>type</th>
-            <th>oceans</th>
-            <th>gravity</th>
-            <th>attenuation</th>
-            <th>topography</th>
-            <th>rotation</th>
-            <th>ellipticity</th>
-        </tr>
-        </thead>
-
-        <tbody>
-        {% for object in model_list %}
-        <tr>
-            <th><a href="specfem3dglobe/models/{{ object.id }}/">{{ object }}</a></th>
-            <td>{{ object.get_type_display }}</td>
-            <td><span class={{ object.oceans }}>{{ object.oceans }}</span></td>
-            <td><span class={{ object.gravity }}>{{ object.gravity }}</span></td>
-            <td><span class={{ object.attenuation }}>{{ object.attenuation }}</span></td>
-            <td><span class={{ object.topography }}>{{ object.topography }}</span></td>
-            <td><span class={{ object.rotation }}>{{ object.rotation }}</span></td>
-            <td><span class={{ object.ellipticity }}>{{ object.ellipticity }}</span></td>
-        </tr>
-        {% endfor %}
-        </tbody>
-
-    </table>
-{% else %}
-    <p>You have no models.
-{% endif %}
-
-
-<p>
-{% if mode_catalog_list %}
-    <table rules=groups class="cool">
-        <caption>mode catalogs</caption>
-
-        <thead>
-        <tr>
-            <th>name</th>
-            <th>eps</th>
-            <th>wgrav</th>
-            <th>lmin</th>
-            <th>lmax</th>
-            <th>wmin</th>
-            <th>wmax</th>
-            <th>nmin</th>
-            <th>nmax</th>
-            <th>max_depth</th>
-        </tr>
-        </thead>
-
-        <tbody>
-        {% for object in mode_catalog_list %}
-        <tr>
-            <th><a href="mineos/modes/{{ object.id }}/">{{ object }}</a></th>
-            <td>{{ object.eps }}</td>
-            <td>{{ object.wgrav }}</td>
-            <td>{{ object.lmin }}</td>
-            <td>{{ object.lmax }}</td>
-            <td>{{ object.wmin }}</td>
-            <td>{{ object.wmax }}</td>
-            <td>{{ object.nmin }}</td>
-            <td>{{ object.nmax }}</td>
-            <td>{{ object.max_depth }}</td>
-        </tr>
-        {% endfor %}
-        </tbody>
-
-    </table>
-{% else %}
-    <p>You have no mode catalogs.
-{% endif %}
-
-
-<p>
-{% if mineos_parameters_list %}
-    <table rules=groups class="cool">
-        <caption>Mineos Parameter Sets</caption>
-
-        <thead>
-        <tr>
-            <th>name</th>
-            <th>catalog</th>
-            <th>radial</th>
-            <th>toroidal</th>
-            <th>spheroidal</th>
-            <th>ictoroidal</th>
-            <th>fmin</th>
-            <th>fmax</th>
-            <th>step</th>
-        </tr>
-        </thead>
-
-        <tbody>
-        {% for object in mineos_parameters_list %}
-        <tr>
-            <th><a href="mineos/parameters/{{ object.id }}/">{{ object }}</a></th>
-            <td>{{ object.catalog }}</td>
-            <td><span class={{ object.radial }}>{{ object.radial }}</span></td>
-            <td><span class={{ object.toroidal }}>{{ object.toroidal }}</span></td>
-            <td><span class={{ object.spheroidal }}>{{ object.spheroidal }}</span></td>
-            <td><span class={{ object.ictoroidal }}>{{ object.ictoroidal }}</span></td>
-            <td>{{ object.fmin }}</td>
-            <td>{{ object.fmax }}</td>
-            <td>{{ object.step }}</td>
-        </tr>
-        {% endfor %}
-        </tbody>
-
-    </table>
-{% else %}
-    <p>You have no Mineos parameter sets.
-{% endif %}
-
-
-<p>
-{% if station_lists %}
-    <table border=0 rules=groups class="cool">
-        <caption>stations</caption>
-
-        <colgroup><col class=odd><col class=even><col class=odd></colgroup>
-
-        <thead>
-        <tr>
-            <th>name</th>
-            <th>number of stations</th>
-            <th>downloads</th>
-        </tr>
-        </thead>
-
-        <tbody>
-        {% for station_list in station_lists %}
-        <tr>
-            <td><a href="stations/{{ station_list.id }}/">{{ station_list }}</a></td>
-            <td>{{ station_list.station_set.count }}</td>
-            <td>
-                <a href="stations/{{ station_list.id }}/gearth.kml"><img src="/specfem3dglobe/pics/kml.icon.gif" title="View in Google Earth" alt="View in Google Earth"></a>
-                [<a href="stations/{{ station_list.id }}/stations.txt">text</a>]
-            </td>
-        </tr>
-        {% endfor %}
-        </tbody>
-
-    </table>
-{% else %}
-    <p>You have no stations.
-{% endif %}
-
-<ul>
-{% for item in home %}
-    <li><a href="{{item.url}}">{{ item.icon }} {{ item.name }}</a></li>
-{% endfor %}
-</ul>

Copied: cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/readme.html (from rev 11539, cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/home.html)
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/readme.html	                        (rev 0)
+++ cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/readme.html	2008-03-27 02:31:24 UTC (rev 11604)
@@ -0,0 +1,49 @@
+
+<h2>Read Me</h2>
+
+<h3>quick start</h3>
+
+<p>To set up a new simulation, proceed as follows:
+
+<ol>
+    <li>Click "Simulations".
+    <li>Click "New...".
+    <li>Enter the parameters for the simulation.
+    <li>Click "Save & Run".
+</ol>
+
+<p>A pair of example simulations are provided. To run one of the
+examples, click the simulation name on the "Simulations" page. Then
+click "Run".
+
+<h3>what next?</h3>
+
+<p>You can monitor your simulation by scanning the "status" column.
+When your simulation completes, there should be a download link titled
+<code>seismograms.tar.gz</code> in the "output" column of the
+simulation's information page. Click this link to download the output of
+the simulation: seismograms in ASCII and <a href="http://www.llnl.gov/sac/">SAC</a> format.
+Then, <a href="/specfem3dglobe/samples/UTILS.tar.gz">download the
+post-processing utilities</a> to process the data.  See
+<a href="/specfem3dglobe/doc/manual_SPECFEM3D_GLOBE.pdf">the manual</a>
+for further details.
+
+<p>As you become familiar with the code, feel free to explore this
+site, creating your own custom events, meshes, and models.
+
+<h3>tips</h3>
+
+<p><img src="/specfem3dglobe/pics/kml.icon.gif"> If you have
+<a href="http://earth.google.com/">Google Earth</a> installed on your
+computer, you can use it to map events and stations.  Just look for
+the KML icon and click it!</p>
+
+<h3>contact</h3>
+
+<p>Please send bug reports and suggestions to <a href="mailto:portal at geodynamics.org">portal at geodynamics.org</a>.
+
+
+<h3>additional documentation</h3>
+
+<p><a href="/specfem3dglobe/doc/manual_SPECFEM3D_GLOBE.pdf">
+   <img src="/specfem3dglobe/pics/adobe-pdf.icon.gif">SPECFEM 3D GLOBE User Manual</a>

Modified: cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/source_confirm_delete.html
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/source_confirm_delete.html	2008-03-27 01:01:59 UTC (rev 11603)
+++ cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/source_confirm_delete.html	2008-03-27 02:31:24 UTC (rev 11604)
@@ -1,7 +1,7 @@
 
 <h2>delete source</h2>
 
-<form method="post" action="/specfem3dglobe/config/events/sources/{{ object.id }}/delete/">
+<form method="post" action="{{ action }}">
     <p>Are you sure you want to delete the source "{{ object }}"?
     <p><input type="submit" value="Delete" />
 </form>

Modified: cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/source_form.html
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/source_form.html	2008-03-27 01:01:59 UTC (rev 11603)
+++ cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/source_form.html	2008-03-27 02:31:24 UTC (rev 11604)
@@ -5,7 +5,7 @@
 <p><span class=error>Please correct the following error{{ form.error_dict|pluralize }}.</span>
 {% endif %}
 
-<form method="post" action="/specfem3dglobe/config/events/sources/{{ object.id }}/edit/">
+<form method="post" action="{{ action }}">
 
     <div class=tab30ex>
 

Deleted: cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/specfem3dglobeparameters_confirm_delete.html
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/specfem3dglobeparameters_confirm_delete.html	2008-03-27 01:01:59 UTC (rev 11603)
+++ cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/specfem3dglobeparameters_confirm_delete.html	2008-03-27 02:31:24 UTC (rev 11604)
@@ -1,7 +0,0 @@
-
-<h2>delete simulation</h2>
-
-<form method="post" action="/specfem3dglobe/config/specfem3dglobe/parameters/{{ object.id }}/delete/">
-    <p>Are you sure you want to delete the simulation "{{ object }}"?
-    <p><input type="submit" value="Delete" />
-</form>

Modified: cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/specfem3dglobeparameters_form.html
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/specfem3dglobeparameters_form.html	2008-03-27 01:01:59 UTC (rev 11603)
+++ cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/specfem3dglobeparameters_form.html	2008-03-27 02:31:24 UTC (rev 11604)
@@ -1,5 +1,5 @@
 
-<h2>{% if object %}edit {{ object }}{% else %}new simulation{% endif %}</h2>
+<h2>{% if object %}edit {{ object }}{% else %}new specfem 3d globe parameter set{% endif %}</h2>
 
 <form method="post" action="{{ action }}">
 

Deleted: cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/stationlist_confirm_delete.html
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/stationlist_confirm_delete.html	2008-03-27 01:01:59 UTC (rev 11603)
+++ cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/stationlist_confirm_delete.html	2008-03-27 02:31:24 UTC (rev 11604)
@@ -1,7 +0,0 @@
-
-<h2>delete station list</h2>
-
-<form method="post" action="/specfem3dglobe/config/stations/{{ object.id }}/delete/">
-    <p>Are you sure you want to delete the station list "{{ object }}"?
-    <p><input type="submit" value="Delete" />
-</form>

Added: cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/trash.html
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/trash.html	                        (rev 0)
+++ cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/trash.html	2008-03-27 02:31:24 UTC (rev 11604)
@@ -0,0 +1,8 @@
+
+<h2>Trash</h2>
+
+<ul>
+{% for item in folder %}
+    <li><a href="{{item.url}}">{{ item.icon }} {{ item.name }}</a></li>
+{% endfor %}
+</ul>

Modified: cs/portal/trunk/seismo/SeismoWebPortal/views.py
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/views.py	2008-03-27 01:01:59 UTC (rev 11603)
+++ cs/portal/trunk/seismo/SeismoWebPortal/views.py	2008-03-27 02:31:24 UTC (rev 11604)
@@ -58,13 +58,12 @@
     desktop = gui.Desktop("/specfem3dglobe", "CIG Seismology Web Portal")
     if not request.user.is_anonymous():
         desktop.user = request.user
-    homeFile = gui.File("", "Home")
-    navtree = gui.Directory("home", "Home", [
-        homeFile, 
+    navtree = gui.Directory("desktop", "Desktop", [
+        gui.Directory("home", "Home", []), 
+        gui.Directory("trash", "Trash", []), 
         gui.Directory("events", "Events", []),
-        gui.Directory("config", "Configuration", []),
         ])
-    fileBrowser = gui.FileBrowser("/specfem3dglobe/", "Home", navtree)
+    fileBrowser = gui.FileBrowser("/specfem3dglobe/", "Desktop", navtree)
     desktop.insertWindow(fileBrowser)
     desktop.selectWindow(fileBrowser)
 
@@ -73,8 +72,10 @@
         path.pop()
 
     if not path:
-        fileBrowser.path.append(homeFile)
-        return httpResponse(home(request, desktop))
+        if request.user.is_anonymous():
+            return render_to_response('SeismoWebPortal/splash.html', {},
+                                      RequestContext(request, {}))
+        return httpResponse(desktopFolder(request, desktop))
 
     name = path.pop(0)
 
@@ -87,6 +88,7 @@
         "runs": runs, # accessed by daemon
         "jobs": jobs, # accessed by daemon
         "output": output, # accessed by daemon
+        "beachballs": beachballs,
         "css": static,
         "doc": static,
         "pics": static,
@@ -105,14 +107,20 @@
                                     (REDIRECT_FIELD_NAME, quote(request.get_full_path())))
 
     index = Index({
+        "home": homeFolder,
+        "trash": trashFolder,
         "config": config,
         "events": event_search,
         "profile": registration,
         "logout": logout,
         "help": help,
+        "readme": readme,
         })
+    privateView = index.get(name)
+    if privateView:
+        return httpResponse(privateView(request, path, desktop))
 
-    return httpResponse(index[name](request, path, desktop))
+    return httpResponse(configObject(name, request, path, desktop))
 
 
 def httpResponse(response):
@@ -137,140 +145,178 @@
 OUTPUT_ROOT = os.path.join(settings.MEDIA_ROOT, 'SeismoWebPortal', 'output')
 
 
-def home(request, desktop):
-    if request.user.is_anonymous():
-        return render_to_response('SeismoWebPortal/splash.html', {},
-                                  RequestContext(request, {}))
-
+def desktopFolder(request, desktop):
     child = gui.ChildWindow("/specfem3dglobe/", "View")
-    child.content = gui.StaticContent(loader.render_to_string('SeismoWebPortal/home.html'))
+    child.content = gui.StaticContent(loader.render_to_string('SeismoWebPortal/desktop.html'))
     desktop.activeWindow.selectWindow(child)
     return desktop
 
 
+def trashFolder(request, path, desktop):
+    fileBrowser = desktop.windowList[0]
+    trashFolder = fileBrowser.root.index["trash"]
+    fileBrowser.path.append(trashFolder)
+    trash = Folder.trashFolder(request.user)
+    child = gui.ChildWindow("/specfem3dglobe/trash/", "View")
+    child.content = gui.StaticContent(loader.render_to_string('SeismoWebPortal/trash.html',
+                                                              {'folder': FSNode.objects.filter(parent=trash.fsNode)}))
+    desktop.activeWindow.selectWindow(child)
+    return desktop
+
+
+def readme(request, path, desktop):
+    if path: raise Http404
+    child = gui.ChildWindow("/specfem3dglobe/readme/", "View")
+    child.content = gui.StaticContent(loader.render_to_string('SeismoWebPortal/readme.html'))
+    desktop.activeWindow.selectWindow(child)
+    return desktop
+
+
 def config(request, path, desktop):
-    from create_update import delete_object
 
-    fileBrowser = desktop.windowList[0]
-    configDir = fileBrowser.root.index["config"]
-    fileBrowser.path.append(configDir)
+    if not path: raise Http404
+    
+    name = path.pop(0)
+    if name == "events":
+        return config_events(request, path, desktop)
+    if name == "stations":
+        return config_stations(request, path, desktop)
+    index = Index({
+        "specfem3dglobe": Index({"models": Specfem3DGlobeModel,
+                                 "meshes": [config_specfem3dglobe_meshes],
+                                 "parameters": [config_specfem3dglobe_parameters] }),
+        "mineos": Index({"modes": MineosModeCatalog,
+                         "parameters": MineosParameters}),
+        })
+    index = index[name]
+    url = name
+    name = path.pop(0)
+    handler = index[name]
+    if isinstance(handler, list):
+        return handler[0](request, path, desktop)
+    else:
+        ModelClass = handler
+    url += "/" + name
+    name = path.pop(0)
+    if name == "new":
+        if path: raise Http404
+        url = "/specfem3dglobe/config/%s/new/" % url
+        window = gui.ChildWindow(url, "New")
+        window.buttons.append(helpButton(request))
+        return create(request, desktop, window, ModelClass)
 
-    if path:
-        name = path.pop(0)
-        if name == "events":
-            return config_events(request, path, desktop)
-        if name == "stations":
-            return config_stations(request, path, desktop)
-        index = Index({
-            "specfem3dglobe": Index({"models": Specfem3DGlobeModel,
-                                     "meshes": [config_specfem3dglobe_meshes],
-                                     "parameters": [config_specfem3dglobe_parameters] }),
-            "mineos": Index({"modes": MineosModeCatalog,
-                             "parameters": MineosParameters}),
-            })
-        index = index[name]
-        url = name
-        name = path.pop(0)
-        handler = index[name]
-        if isinstance(handler, list):
-            return handler[0](request, path, desktop)
-        else:
-            ModelClass = handler
-        url += "/" + name
-        name = path.pop(0)
-        if name == "new":
-            if path: raise Http404
-            url = "/specfem3dglobe/config/%s/new/" % url
-            window = gui.ChildWindow(url, "New")
-            window.buttons.append(helpButton(request))
-            return create(request, desktop, window, ModelClass)
+    raise Http404
         
-        objId = intOr404(name)
-        url = "/specfem3dglobe/config/%s/%d/" % (url, objId)
 
-        view = gui.ChildWindow(url, "View")
-        edit = gui.ChildWindow(url + "edit/", "Edit")
-        properties = gui.ChildWindow(url + "properties/", "Properties")
-        menuBar = [
-            gui.Menu("actionMenu", "actions", "Actions",
-                     [gui.MenuItem(url + "duplicate/", "Duplicate"),
-                      gui.MenuItem(url + "delete/", "Delete"),
-                      ]
-                     ),
-            ]
-        view.menuBar = edit.menuBar = properties.menuBar = menuBar
-        edit.buttons.append(helpButton(request))
-        desktop.activeWindow.insertWindow(view)
-        desktop.activeWindow.insertWindow(edit)
-        desktop.activeWindow.insertWindow(properties)
+def configObject(name, request, path, desktop):
+    objId = intOr404(name)
+    url = "/specfem3dglobe/%d/" % objId
     
-        if not path:
-            return update(request, desktop, view, object_id = objId, ModelClass = ModelClass)
-        name = path.pop(0)
-        if path: raise Http404
-        if name == "edit":
-            return update(request, desktop, edit, object_id = objId, ModelClass = ModelClass)
-        if name == "properties":
-            objId = get_object_or_404(ModelClass, id=objId).fsNode.id # Ouch!
-            return update_object(request,
-                                 desktop,
-                                 properties,
-                                 FSNode,
-                                 objId,
-                                 post_save_redirect = '/specfem3dglobe/config/',
-                                 follow = FSNode.follow,
-                                 )
-        if name == "delete":
-            return delete_object(request,
-                                 desktop,
-                                 ModelClass,
-                                 "/specfem3dglobe/config/",
-                                 object_id = objId,
-                                 )
-        raise Http404
+    fsNode = get_object_or_404(FSNode, id=objId)
+    
+    fileBrowser = desktop.windowList[0]
+    if fsNode.inTrash:
+        folderName = "trash"
+    else:
+        folderName = "home"
+    folder = fileBrowser.root.index[folderName]
+    fileBrowser.path.append(folder)
+    item = gui.File(name, fsNode.name, url = url)
+    folder.appendNode(item)
+    fileBrowser.path.append(item)
+    
+    objId = fsNode.objectId
+    obj = fsNode.contents
+    ModelClass = obj.__class__
 
-    child = gui.ChildWindow("/specfem3dglobe/config/", "View")
+    specialClasses = {
+        Event: configEvent,
+        StationList: configStationList,
+        Specfem3DGlobeMesh: configSpecfem3DGlobeMesh,
+        Specfem3DGlobeParameters: configSpecfem3DGlobeParameters,
+        }
+    specialView = specialClasses.get(ModelClass)
+    if specialView:
+        return specialView(obj, url, request, path, desktop)
+
+    view = gui.ChildWindow(url, "View")
+    edit = gui.ChildWindow(url + "edit/", "Edit")
+    properties = gui.ChildWindow(url + "properties/", "Properties")
+    menuBar = [
+        gui.Menu("actionMenu", "actions", "Actions",
+                 [gui.MenuItem(url + "duplicate/", "Duplicate"),
+                  gui.MenuItem(url + "delete/", "Delete"),
+                ]
+                ),
+        ]
+    view.menuBar = edit.menuBar = properties.menuBar = menuBar
+    edit.buttons.append(helpButton(request))
+    desktop.activeWindow.insertWindow(view)
+    desktop.activeWindow.insertWindow(edit)
+    desktop.activeWindow.insertWindow(properties)
+    
+    if not path:
+        return update(request, desktop, view, object_id = objId, ModelClass = ModelClass)
+    name = path.pop(0)
+    if path: raise Http404
+    if name == "edit":
+        return update(request, desktop, edit, object_id = objId, ModelClass = ModelClass)
+    if name == "properties":
+        objId = get_object_or_404(ModelClass, id=objId).fsNode.id # Ouch!
+        return update_object(request,
+                             desktop,
+                             properties,
+                             FSNode,
+                             objId,
+                             post_save_redirect = url,
+                             follow = FSNode.follow,
+                             )
+    if name == "delete":
+        obj = get_object_or_404(ModelClass, id=objId)
+        return moveObjectToTrash(obj, request, "/specfem3dglobe/home/")
+    raise Http404
+
+
+def homeFolder(request, path, desktop):
+    if path: raise Http404
+    
+    fileBrowser = desktop.windowList[0]
+    homeFolder = fileBrowser.root.index["home"]
+    fileBrowser.path.append(homeFolder)
+    
+    home = Folder.homeFolder(request.user)
+    
+    child = gui.ChildWindow("/specfem3dglobe/home/", "View")
+    config = "/specfem3dglobe/config/"
     child.menuBar = [
         gui.Menu("newMenu", "new", "New",
-                 [gui.MenuItem("events/new/", "Event"),
-                  gui.MenuItem("specfem3dglobe/models/new/", "Specfem 3D Globe Model"),
-                  gui.MenuItem("specfem3dglobe/meshes/new/1/", "Specfem 3D Globe 1-chunk Regional Mesh"),
-                  gui.MenuItem("specfem3dglobe/meshes/new/2/", "Specfem 3D Globe 2-chunk Regional Mesh"),
-                  gui.MenuItem("specfem3dglobe/meshes/new/3/", "Specfem 3D Globe 3-chunk Regional Mesh"),
-                  gui.MenuItem("specfem3dglobe/meshes/new/6/", "Specfem 3D Globe Global Mesh"),
-                  gui.MenuItem("specfem3dglobe/parameters/new/", "Specfem 3D Globe Parameter Set"),
-                  gui.MenuItem("mineos/modes/new/", "Mineos Mode Catalog"),
-                  gui.MenuItem("mineos/parameters/new/", "Mineos Parameter Set"),
+                 [gui.MenuItem(config + "events/new/", "Event"),
+                  gui.MenuItem(config + "specfem3dglobe/models/new/", "Specfem 3D Globe Model"),
+                  gui.MenuItem(config + "specfem3dglobe/meshes/new/1/", "Specfem 3D Globe 1-chunk Regional Mesh"),
+                  gui.MenuItem(config + "specfem3dglobe/meshes/new/2/", "Specfem 3D Globe 2-chunk Regional Mesh"),
+                  gui.MenuItem(config + "specfem3dglobe/meshes/new/3/", "Specfem 3D Globe 3-chunk Regional Mesh"),
+                  gui.MenuItem(config + "specfem3dglobe/meshes/new/6/", "Specfem 3D Globe Global Mesh"),
+                  gui.MenuItem(config + "specfem3dglobe/parameters/new/", "Specfem 3D Globe Parameter Set"),
+                  gui.MenuItem(config + "mineos/modes/new/", "Mineos Mode Catalog"),
+                  gui.MenuItem(config + "mineos/parameters/new/", "Mineos Parameter Set"),
                   ]
                  ),
         gui.Menu("uploadMenu", "upload", "Upload",
-                 [gui.MenuItem("events/upload/", "Event"),
-                  gui.MenuItem("stations/upload/", "Station List"),
+                 [gui.MenuItem(config + "events/upload/", "Event"),
+                  gui.MenuItem(config + "stations/upload/", "Station List"),
                  ]
                  )
         ]
     home = Folder.homeFolder(request.user)
-    html = loader.render_to_string('SeismoWebPortal/object_lists.html',
-                                   {'event_list': Event.objects.filter(fsNode__owner=request.user),
-                                    'specfem3dglobe_parameters_list': Specfem3DGlobeParameters.objects.filter(fsNode__owner=request.user),
-                                    'mesh_list': Specfem3DGlobeMesh.objects.filter(fsNode__owner=request.user),
-                                    'model_list': Specfem3DGlobeModel.objects.filter(fsNode__owner=request.user),
-                                    'mode_catalog_list': MineosModeCatalog.objects.filter(fsNode__owner=request.user),
-                                    'mineos_parameters_list': MineosParameters.objects.filter(fsNode__owner=request.user),
-                                    'station_lists': StationList.objects.filter(fsNode__owner=request.user),
-                                    'home': FSNode.objects.filter(parent=home.fsNode),
-                                    }
-                                   )
-    child.content = gui.StaticContent(html)
+    trash = Folder.trashFolder(request.user)
+    child.content = gui.StaticContent(loader.render_to_string('SeismoWebPortal/home.html',
+                                                              {'folder': FSNode.objects.filter(parent=home.fsNode)}))
     desktop.activeWindow.selectWindow(child)
     return desktop
     
 
 
 def config_specfem3dglobe_parameters(request, path, desktop):
-    from create_update import delete_object
-    from list_detail import object_detail
-    
     name = path.pop(0)
     if name == "new":
         window = gui.ChildWindow("/specfem3dglobe/config/specfem3dglobe/parameters/new/", "New")
@@ -279,13 +325,17 @@
                              desktop,
                              window,
                              Specfem3DGlobeParameters,
-                             post_save_redirect = '/specfem3dglobe/config/specfem3dglobe/parameters/%(id)d/',
+                             post_save_redirect = '/specfem3dglobe/home/',
                              follow = { 'fsNode': False },
                              )
+    raise Http404
     
-    objId = intOr404(name)
-    url = "/specfem3dglobe/config/specfem3dglobe/parameters/%d/" % objId
+
+def configSpecfem3DGlobeParameters(parameters, url, request, path, desktop):
+    from list_detail import object_detail
     
+    objId = parameters.id # Ouch!
+    
     view = gui.ChildWindow(url, "View")
     edit = gui.ChildWindow(url + "edit/", "Edit")
     properties = gui.ChildWindow(url + "properties/", "Properties")
@@ -328,7 +378,7 @@
                              follow = { 'fsNode': False },
                              )
     if name == "properties":
-        objId = get_object_or_404(Specfem3DGlobeParameters, id=objId).fsNode.id # Ouch!
+        objId = parameters.fsNode.id # Ouch!
         return update_object(request,
                              desktop,
                              properties,
@@ -338,11 +388,8 @@
                              follow = FSNode.follow,
                              )
     if name == "delete":
-        return delete_object(request,
-                             desktop,
-                             Specfem3DGlobeParameters,
-                             post_delete_redirect = "/specfem3dglobe/config/",
-                             object_id = objId)
+        obj = get_object_or_404(Specfem3DGlobeParameters, id=objId)
+        return moveObjectToTrash(obj, request, "/specfem3dglobe/home/")
     
     index = Index({
         "par_file.txt": par_file,
@@ -783,8 +830,6 @@
 
 
 def config_specfem3dglobe_meshes(request, path, desktop):
-    from create_update import delete_object
-    
     if not path:
         raise Http404
     
@@ -798,8 +843,11 @@
         window = gui.ChildWindow("/specfem3dglobe/config/specfem3dglobe/meshes/new/%d/" % nchunks, "New")
         return manipulate_mesh(request, desktop, window, nchunks = nchunks, action='new')
     
-    objId = intOr404(name)
-    url = "/specfem3dglobe/config/specfem3dglobe/meshes/%d/" % objId
+    raise Http404
+
+
+def configSpecfem3DGlobeMesh(mesh, url, request, path, desktop):
+    objId = mesh.id # Ouch!
     
     view = gui.ChildWindow(url, "View")
     edit = gui.ChildWindow(url + "edit/", "Edit")
@@ -822,22 +870,18 @@
     if name == "edit":
         return manipulate_mesh(request, desktop, edit, object_id = objId, action='edit')
     if name == "properties":
-        objId = get_object_or_404(Specfem3DGlobeMesh, id=objId).fsNode.id # Ouch!
+        objId = mesh.fsNode.id # Ouch!
         return update_object(request,
                              desktop,
                              properties,
                              FSNode,
                              objId,
-                             post_save_redirect = '/specfem3dglobe/config/',
+                             post_save_redirect = '/specfem3dglobe/home/',
                              follow = FSNode.follow,
                              )
     if name == "delete":
         if path: raise Http404
-        return delete_object(request,
-                             desktop,
-                             Specfem3DGlobeMesh,
-                             "/specfem3dglobe/config/",
-                             object_id = objId)
+        return moveObjectToTrash(mesh, request, "/specfem3dglobe/home/")
 
     raise Http404
 
@@ -887,7 +931,7 @@
                 manipulator.do_html2python(new_data)
                 manipulator.save(new_data)
                 if not errors:
-                    return HttpResponseRedirect('/specfem3dglobe/config/')
+                    return HttpResponseRedirect('/specfem3dglobe/home/')
     else:
         # Populate new_data with a 'flattened' version of the current data.
         new_data = manipulator.flatten_data()
@@ -919,7 +963,7 @@
                          desktop,
                          window,
                          ModelClass,
-                         post_save_redirect = '/specfem3dglobe/config/',
+                         post_save_redirect = '/specfem3dglobe/home/',
                          follow = { 'fsNode': False },
                          )
 
@@ -930,42 +974,43 @@
                          window,
                          ModelClass,
                          object_id,
-                         post_save_redirect = '/specfem3dglobe/config/',
+                         post_save_redirect = '/specfem3dglobe/home/',
                          follow = { 'fsNode': False },
                          )
 
 
+def moveObjectToTrash(object, request, postTrashRedirect):
+    fsNode = object.fsNode
+    if not fsNode.inTrash:
+        fsNode.inTrash = True
+        fsNode.oldParent = fsNode.parent
+        fsNode.parent = Folder.trashFolder(request.user).fsNode
+        fsNode.save()
+    return HttpResponseRedirect(postTrashRedirect)
+    
+
 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 # Events
 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 
-def junk():
-    node = gui.File(name, event.fsNode.name)
-    eventsDir.appendNode(node)
-    fileBrowser.path.append(node)
-
-
 def config_events(request, path, desktop):
-    from list_detail import object_detail
-    from create_update import delete_object
-
     if not path: raise Http404
     name = path.pop(0)
 
     index = Index({
         "new": lambda request, path, desktop: manipulate_event(request, path, desktop, action='new'),
         "upload": upload_event,
-        "sources": config_events_sources,
         })
     view = index.get(name)
     if view:
         return view(request, path, desktop)
 
-    objId = intOr404(name)
-    url = "/specfem3dglobe/config/events/%d/" % objId
-    event = get_object_or_404(Event, id=objId) # Ouch!
-    
+    raise Http404
+
+
+
+def eventWindows(event, url, desktop):
     view = gui.ChildWindow(url, "View")
     edit = gui.ChildWindow(url + "edit/", "Edit")
     properties = gui.ChildWindow(url + "properties/", "Properties")
@@ -980,8 +1025,16 @@
     if event.singleSource:
         desktop.activeWindow.insertWindow(edit)
     desktop.activeWindow.insertWindow(properties)
+    return view, edit, properties
+
+
+def configEvent(event, url, request, path, desktop):
+    from list_detail import object_detail
+
+    objId = event.id # Ouch!
     
     if not path:
+        view, edit, properties = eventWindows(event, url, desktop)
         return object_detail(
             request,
             desktop,
@@ -992,36 +1045,35 @@
 
     name = path.pop(0)
     if name == "edit":
+        view, edit, properties = eventWindows(event, url, desktop)
         return manipulate_event(request, path, desktop, object_id = objId, action = 'edit', window = edit)
     if name == "properties":
+        view, edit, properties = eventWindows(event, url, desktop)
         return manipulate_event(request, path, desktop, object_id = objId, action = 'properties', window = properties)
     if name == "delete":
-        return delete_object(request,
-                             desktop,
-                             Event,
-                             "/specfem3dglobe/config/",
-                             object_id = objId,
-                             )
+        view, edit, properties = eventWindows(event, url, desktop)
+        return moveObjectToTrash(event, request, "/specfem3dglobe/home/")
+
     index = Index({
         "CMTSOLUTION.txt": (event_detail_cmtsolution_txt, (), dict(object_id = objId)),
         "beachball.gif": (beachball_gif, (), dict(event_id = objId)),
         "gearth.kml": (event_detail_gearth, (), dict(object_id = objId)),
         })
-    view, args, kwds = index[name]
-    return view(request, *args, **kwds)
+    call = index.get(name)
+    if call:
+        view, args, kwds = call
+        return view(request, *args, **kwds)
 
+    return configSource(name, event, url, request, path, desktop)
 
-def config_events_sources(request, path, desktop):
+
+def configSource(name, event, eventUrl, request, path, desktop):
     from models import Source
     from list_detail import object_detail
     from create_update import update_object, delete_object
 
-    if not path:
-        raise Http404
-
-    name = path.pop(0)
     objId = intOr404(name)
-    url = "/specfem3dglobe/config/events/sources/%d/" % objId
+    url = eventUrl + "%d/" % objId
     
     view = gui.ChildWindow(url, "View")
     edit = gui.ChildWindow(url + "edit/", "Edit")
@@ -1057,7 +1109,7 @@
             desktop,
             Source,
             object_id = objId,
-            post_delete_redirect = "/specfem3dglobe/config/",
+            post_delete_redirect = eventUrl,
             )
 
     index = Index({
@@ -1142,7 +1194,7 @@
                              window,
                              FSNode,
                              objId,
-                             post_save_redirect = '/specfem3dglobe/config/',
+                             post_save_redirect = '/specfem3dglobe/home/',
                              follow = FSNode.follow,
                              )
     else:
@@ -1160,7 +1212,7 @@
             if name:
                 new_event.fsNode.name = name
                 new_event.fsNode.save()
-            url = "/specfem3dglobe/config/events/%i/" % new_event.id
+            url = "/specfem3dglobe/%i/" % new_event.fsNode.id
             return HttpResponseRedirect(url)
     else:
         new_data = manipulator.flatten_data()
@@ -1179,7 +1231,6 @@
 
 def upload_event(request, path, desktop):
     from forms import UploadEventManipulator
-    from os.path import dirname
 
     if path: raise Http404
 
@@ -1201,8 +1252,7 @@
             if not errors:
                 manipulator.do_html2python(new_data)
                 new_event = manipulator.save(new_data, request.user)
-                url = "%s/%i/" % (dirname(dirname(request.path)), new_event.id)
-                return HttpResponseRedirect(url)
+                return HttpResponseRedirect("/specfem3dglobe/%i/" % new_event.fsNode.id)
     else:
         errors = new_data = {}
 
@@ -1224,6 +1274,14 @@
                               extra_context = {'name': event.fsNode.name},
                               )
 
+
+def beachballs(request, path, desktop):
+    name = path.pop(0)
+    source_id = intOr404(os.path.splitext(name)[0])
+    if path: raise Http404
+    return beachball_gif(request, source_id = source_id)
+
+
 def beachball_gif(request, event_id=None, source_id=None):
     from gmt import psmeca
     import shutil
@@ -1304,19 +1362,22 @@
 
 
 def config_stations(request, path, desktop):
-    from list_detail import object_detail
-    from create_update import update_object, delete_object
-    
     if not path: raise Http404
     name = path.pop(0)
 
     if name == "upload":
         if path: raise Http404
         return upload_station_list(request, desktop)
+
+    raise Http404
     
-    objId = intOr404(name)
-    url = "/specfem3dglobe/config/stations/%d/" % objId
 
+def configStationList(stationList, url, request, path, desktop):
+    from list_detail import object_detail
+    from create_update import update_object
+
+    objId = stationList.id # Ouch!
+
     view = gui.ChildWindow(url, "View")
     properties = gui.ChildWindow(url + "properties/", "Properties")
     menuBar = [
@@ -1336,7 +1397,7 @@
     if path: raise Http404
 
     if name == "properties":
-        objId = get_object_or_404(StationList, id=objId).fsNode.id # Ouch!
+        objId = stationList.fsNode.id # Ouch!
         return update_object(request,
                              desktop,
                              properties,
@@ -1347,12 +1408,8 @@
                              )
     
     if name == "delete":
-        return delete_object(request,
-                             desktop,
-                             StationList,
-                             object_id = objId,
-                             post_delete_redirect = "/specfem3dglobe/config/",
-                             )
+        obj = get_object_or_404(StationList, id=objId)
+        return moveObjectToTrash(obj, request, "/specfem3dglobe/home/")
 
     index = Index({
         "stations.txt": stationlist_detail_txt,
@@ -1363,7 +1420,6 @@
 
 
 def upload_station_list(request, desktop):
-    from os.path import dirname
     
     manipulator = UploadStationListManipulator()
     help_visible = get_help_visible(request)
@@ -1383,8 +1439,7 @@
             if not errors:
                 manipulator.do_html2python(new_data)
                 stationList = manipulator.save(new_data, request.user)
-                url = "%s/%i/" % (dirname(dirname(request.path)), stationList.id)
-                return HttpResponseRedirect(url)
+                return HttpResponseRedirect("/specfem3dglobe/%i/" % stationList.fsNode.id)
     else:
         errors = new_data = {}
 



More information about the cig-commits mailing list