[cig-commits] r11830 - in cs/portal/trunk/seismo/SeismoWebPortal: . templates/SeismoWebPortal
leif at geodynamics.org
leif at geodynamics.org
Fri Apr 18 14:51:28 PDT 2008
Author: leif
Date: 2008-04-18 14:51:28 -0700 (Fri, 18 Apr 2008)
New Revision: 11830
Modified:
cs/portal/trunk/seismo/SeismoWebPortal/gmt.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/source_detail.html
cs/portal/trunk/seismo/SeismoWebPortal/views.py
Log:
Cache images generated using GMT.
Modified: cs/portal/trunk/seismo/SeismoWebPortal/gmt.py
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/gmt.py 2008-04-18 19:26:37 UTC (rev 11829)
+++ cs/portal/trunk/seismo/SeismoWebPortal/gmt.py 2008-04-18 21:51:28 UTC (rev 11830)
@@ -3,16 +3,17 @@
import os
import shutil
-from os.path import join
+from os.path import join, isdir
from popen2 import Popen3
from tempfile import mkdtemp, TemporaryFile
-from django.http import Http404
+from django.http import HttpResponse, Http404
+from django.shortcuts import get_object_or_404
gmt_bin = "/home/leif/opt/gmt/bin"
-def psmeca(cmt):
+def psmeca(cmt, filename, args):
# Create a temporary directory and 'cd' there, so that '.gmt*'
# files get cleaned-up.
@@ -22,7 +23,7 @@
os.putenv("LD_LIBRARY_PATH", "/home/leif/opt/netCDF/lib")
# Spawn 'psmeca' to draw the beachball.
- child = Popen3([join(gmt_bin, "psmeca"), '-R0/10/0/10', '-Jx1', '-G255/0/0', '-M', '-Sm1.1', '-L2', '-K', '-V', '-P'])
+ child = Popen3([join(gmt_bin, "psmeca"), '-R0/10/0/10', '-Jx1', '-G255/0/0', '-L2', '-K', '-V', '-P'] + args)
print >>child.tochild, "3 5 0 %f %f %f %f %f %f 1 0 0" % (
cmt.Mrr, cmt.Mtt, cmt.Mpp, cmt.Mrt, cmt.Mrp, cmt.Mtp)
child.tochild.close()
@@ -39,20 +40,18 @@
raise Http404
# Convert the PostScript to a GIF file.
- gif = join(workdir, "beachball.gif")
spawn("/usr/bin/convert",
'+antialias',
'-fill', '#00F', '-draw', 'color 0,0 floodfill', '-transparent', '#00F',
'-trim', '+repage',
- ps, gif)
+ ps, filename)
- gif = open(gif, 'r')
shutil.rmtree(workdir)
- return gif
+ return
-def stationsMap(stationList):
+def stationsMap(stationList, filename):
# Based on:
# globe_fig_CIG.pl
# Carl Tape
@@ -155,16 +154,15 @@
os.chdir(owd)
# Convert the PostScript to a JPG file.
- jpg = join(workdir, "map.jpg")
- spawn("/usr/bin/convert", '-trim', '+repage', psfile, jpg)
+ spawn("/usr/bin/convert", '-trim', '+repage', psfile, filename)
- jpg = open(jpg, 'r')
shutil.rmtree(workdir)
- return jpg
+ return
def wiggleMap(cmt,
+ filename,
stationList = None,
opt_a=None,
opt_A=None,
@@ -280,7 +278,7 @@
# syndir,synsuff -- plot synthetics SYNDIR/*synsuff correpsonding to datafiles
if opt_S:
syn_dir, syn_suff = opt_S
- assert os.path.isdir(syn_dir), "No such directory: %s" % syn_dir
+ assert isdir(syn_dir), "No such directory: %s" % syn_dir
plot_syn = True
else:
syn_dir, syn_suff = None, None
@@ -360,13 +358,11 @@
os.chdir(owd)
# Convert the PostScript to a JPG file.
- jpg = join(workdir, "map.jpg")
- spawn("/usr/bin/convert", '-trim', '+repage', PS_OUT, jpg)
+ spawn("/usr/bin/convert", '-trim', '+repage', PS_OUT, filename)
- jpg = open(jpg, 'r')
shutil.rmtree(workdir)
- return jpg
+ return
def plotWiggleMap(plot_nr, nr_of_plots,
@@ -613,3 +609,133 @@
s = open("inFile", 'w')
s.write(text)
s.close()
+
+
+
+def serve(request, pathname, document_root):
+ from django.views.static import serve as staticServe
+ from os import makedirs
+ from views import intOr404
+ from models import Source, StationList
+
+ try:
+ return staticServe(request, pathname, document_root)
+ except Http404:
+ pass
+
+ path = pathname.split('/')
+ if not path: raise Http404
+ name = path.pop(0)
+
+ if name == "beachballs":
+ dirname = join(document_root, name)
+ if not path: raise Http404
+ name = path.pop(0)
+
+ objId = intOr404(name)
+ source = get_object_or_404(Source, id=objId)
+ dirname = join(dirname, name)
+
+ if not path: raise Http404
+ name = path.pop(0)
+ if path: raise Http404
+
+ if name == "icon_large.gif":
+ args = ['-M', '-Sm1.1']
+ elif name == "icon_small.gif":
+ args = ['-M', '-Sm0.5']
+ elif name == "detail.gif":
+ args = ['-M', '-Sm4.0']
+ elif name == "proportional.gif":
+ args = ['-Sm1.0']
+ else:
+ raise Http404
+
+ if not isdir(dirname):
+ makedirs(dirname)
+ filename = join(dirname, name)
+
+ psmeca(source, filename, args)
+
+ elif name == "maps":
+ dirname = join(document_root, name)
+ if not path: raise Http404
+ name = path.pop(0)
+
+ if name == "stations":
+ dirname = join(dirname, name)
+ if not path: raise Http404
+ name = path.pop(0)
+
+ objId = intOr404(name)
+ stationList = get_object_or_404(StationList, id=objId)
+ dirname = join(dirname, name)
+
+ if not path: raise Http404
+ name = path.pop(0)
+ if path: raise Http404
+
+ if name != "mercator.jpg":
+ raise Http404
+
+ if not isdir(dirname):
+ makedirs(dirname)
+ filename = join(dirname, name)
+
+ stationsMap(stationList, filename)
+
+ elif name == "events":
+ dirname = join(dirname, name)
+ if not path: raise Http404
+ name = path.pop(0)
+
+ objId = intOr404(name)
+ source = get_object_or_404(Source, id=objId)
+ dirname = join(dirname, name)
+
+ if not path: raise Http404
+ name = path.pop(0)
+
+ if name == "stations":
+ dirname = join(dirname, name)
+
+ if not path: raise Http404
+ name = path.pop(0)
+
+ objId = intOr404(name)
+ stationList = get_object_or_404(StationList, id=objId)
+ dirname = join(dirname, name)
+
+ if not path: raise Http404
+ name = path.pop(0)
+ if name != "global":
+ raise Http404
+ dirname = join(dirname, name)
+
+ if not path: raise Http404
+ name = path.pop(0)
+ if path: raise Http404
+
+ if name == "event.jpg":
+ opts = dict()
+ elif name == "antipode.jpg":
+ opts = dict(opt_A=True)
+ else:
+ raise Http404
+
+ if not isdir(dirname):
+ makedirs(dirname)
+ filename = join(dirname, name)
+
+ wiggleMap(source, filename, stationList, opt_m=True, **opts)
+
+ else:
+ raise Http404
+
+ else:
+ raise Http404
+
+ else:
+ raise Http404
+
+ return staticServe(request, pathname, document_root)
Modified: cs/portal/trunk/seismo/SeismoWebPortal/models.py
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/models.py 2008-04-18 19:26:37 UTC (rev 11829)
+++ cs/portal/trunk/seismo/SeismoWebPortal/models.py 2008-04-18 21:51:28 UTC (rev 11830)
@@ -160,12 +160,18 @@
def _getSingleSource(self):
if not hasattr(self, '_singleSource'):
if self.source_set.count() == 1:
- self._singleSource = self.source_set.all()[0]
+ self._singleSource = self.firstSource
else:
self._singleSource = None
return self._singleSource
singleSource = property(_getSingleSource)
+ def _getFirstSource(self):
+ if not hasattr(self, '_firstSource'):
+ self._firstSource = self.source_set.all()[0]
+ return self._firstSource
+ firstSource = property(_getFirstSource)
+
def sources(self):
return self.source_set.order_by('timeShift')
@@ -257,7 +263,7 @@
return 2.0 * (log10(self.scalarSeismicMoment()) - 16.1)/3.0
def beachball(self):
- src = "%s/beachballs/%d.gif" % (config.root, self.id)
+ src = "%s/beachballs/%d/icon_large.gif" % (config.root, self.id)
return '<img class="icon" src="%s">' % src
def cmtSolutionText(self):
Modified: cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/event_detail.html
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/event_detail.html 2008-04-18 19:26:37 UTC (rev 11829)
+++ cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/event_detail.html 2008-04-18 21:51:28 UTC (rev 11830)
@@ -1,5 +1,5 @@
-<h2>{{ object }}</h2>
+<h2>{{ title }}</h2>
<div class=toolbar>
<a href="gearth.kml"><img src="{{root}}/pics/kml.icon.gif" title="View in Google Earth" alt="View in Google Earth"></a>
@@ -8,7 +8,7 @@
{% if object.singleSource %}
-<p id=sourceBeachballMw>{{ object.singleSource.beachball }} M<sub>w</sub> ≅ {{ object.singleSource.momentMagnitude|stringformat:".2f" }}</p>
+<p id=sourceBeachballMw><img src="{{root}}/beachballs/{{object.singleSource.id}}/detail.gif"> M<sub>w</sub> ≅ {{ object.singleSource.momentMagnitude|stringformat:".2f" }}</p>
<div class=cmtsolution>
<h3><code>CMTSOLUTION</code></h3>
Modified: cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/source_detail.html
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/source_detail.html 2008-04-18 19:26:37 UTC (rev 11829)
+++ cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/source_detail.html 2008-04-18 21:51:28 UTC (rev 11830)
@@ -5,7 +5,7 @@
[<a href="CMTSOLUTION.txt">download as text</a>]
</div>
-<p id=sourceBeachballMw>{{ object.beachball }} M<sub>w</sub> ≅ {{ object.momentMagnitude|stringformat:".2f" }}</p>
+<p id=sourceBeachballMw><img src="{{root}}/beachballs/{{object.id}}/detail.gif"> M<sub>w</sub> ≅ {{ object.momentMagnitude|stringformat:".2f" }}</p>
<div class=cmtsolution>
<h3><code>CMTSOLUTION</code></h3>
Modified: cs/portal/trunk/seismo/SeismoWebPortal/views.py
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/views.py 2008-04-18 19:26:37 UTC (rev 11829)
+++ cs/portal/trunk/seismo/SeismoWebPortal/views.py 2008-04-18 21:51:28 UTC (rev 11830)
@@ -28,7 +28,9 @@
from StringIO import StringIO
-static_media_root = os.environ.get("WEBPORTAL_MEDIA_ROOT")+'/static'
+STATIC_ROOT = os.path.join(os.path.dirname(__file__), "static")
+OUTPUT_ROOT = os.path.join(settings.MEDIA_ROOT, 'SeismoWebPortal', 'output')
+GMT_ROOT = os.path.join(settings.MEDIA_ROOT, 'SeismoWebPortal', 'gmt')
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -59,6 +61,7 @@
def root(request, pathname):
from django.views.static import serve as staticServe
+ from gmt import serve as gmtServe
if config.root is None:
if pathname:
@@ -88,7 +91,7 @@
name = path.pop(0)
- static = lambda request, path, desktop: staticServe(request, pathname, document_root = static_media_root)
+ static = lambda request, path, desktop: staticServe(request, pathname, document_root = STATIC_ROOT)
index = Index({
"login": login,
@@ -97,7 +100,6 @@
"jobs": jobs, # accessed by daemon
"output": output, # accessed by daemon
"requests": requests, # accessed by daemon
- "beachballs": beachballs,
"designs": designs,
"doc": static,
"pics": static,
@@ -118,6 +120,8 @@
openPrivateApps(request, desktop)
+ gmt = lambda request, path, desktop: gmtServe(request, pathname, document_root = GMT_ROOT)
+
index = Index({
"home": homeFolder,
"shared": sharedFolder,
@@ -129,6 +133,8 @@
"help": help,
"readme": readme,
"admin": admin,
+ "beachballs": gmt,
+ "maps": gmt,
})
privateView = index.get(name)
if privateView:
@@ -213,9 +219,6 @@
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-OUTPUT_ROOT = os.path.join(settings.MEDIA_ROOT, 'SeismoWebPortal', 'output')
-
-
def desktopFolder(request, desktop):
url = config.root + "/"
child = gui.ChildWindow(url, "View")
@@ -1503,7 +1506,6 @@
def eventFiles(name, event, request):
index = Index({
"CMTSOLUTION.txt": (event_detail_cmtsolution_txt, (), dict(event = event)),
- "beachball.gif": (beachball_gif, (), dict(event_id = event.id)),
"gearth.kml": (event_detail_gearth, (), dict(object_id = event.id)),
})
call = index.get(name)
@@ -1530,6 +1532,7 @@
view,
object_id = event.id,
queryset = Event.objects.all(),
+ extra_context = {'title': workspace.fsNode.name }
)
name = path.pop(0)
@@ -1600,7 +1603,6 @@
index = Index({
"CMTSOLUTION.txt": (cmtsolution_txt, (), dict(object_id = objId)),
- "beachball.gif": (beachball_gif, (), dict(source_id = objId)),
})
view, args, kwds = index[name]
return view(request, *args, **kwds)
@@ -1613,37 +1615,28 @@
url += "maps/"
if not path:
- return HttpResponseRedirect(url + "event/")
+ return HttpResponseRedirect(url + "global/")
name = path.pop(0)
- if not name in ["event", "antipode"]:
+ if path or not name in ["global", "stations"]:
raise Http404
-
- if not path:
- title = name.capitalize()
- mapsFolder.appendNode(gui.File("event", "Event", url = url + "event/"))
- mapsFolder.appendNode(gui.File("antipode", "Antipode", url = url + "antipode/"))
- appWindow.path.append(mapsFolder.index[name])
- child = gui.ChildWindow(url, title)
- child.content = gui.StaticContent(img(url + "%s/%s.jpg" % (name, name), width=506, height=506))
- desktop.activeWindow.selectWindow(child)
- return desktop
- name = path.pop(0)
- if path or not name in ["event.jpg", "antipode.jpg"]: raise Http404
-
- from gmt import wiggleMap
- import shutil
+ mapsFolder.appendNode(gui.File("global", "Global", url = url + "global/"))
+ mapsFolder.appendNode(gui.File("stations", "Stations", url = url + "stations/"))
+ appWindow.path.append(mapsFolder.index[name])
+ child = gui.ChildWindow(url, "View")
- opts = {
- "event.jpg": dict(),
- "antipode.jpg": dict(opt_A=True),
- }[name]
- stream = wiggleMap(event.singleSource, workspace.stations, opt_m=True, **opts)
- response = HttpResponse(mimetype='image/jpeg')
- shutil.copyfileobj(stream, response)
- stream.close()
- return response
+ if name == "global":
+ mapRoot = "%s/maps/events/%d/stations/%d/global" % (config.root, event.firstSource.id, workspace.stations.id)
+ imgList = [img("%s/%s" % (mapRoot, jpg), width=506, height=506)
+ for jpg in ["event.jpg", "antipode.jpg"]]
+ else:
+ mapUrl = "%s/maps/stations/%s/mercator.jpg" % (config.root, workspace.stations.id)
+ imgList = [img(mapUrl, width=547, height=657)]
+
+ child.content = gui.StaticContent(' '.join(imgList))
+ desktop.activeWindow.selectWindow(child)
+ return desktop
def openEventFinder(desktop):
@@ -1822,30 +1815,6 @@
)
-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
-
- if event_id:
- event = get_object_or_404(Event, id=event_id)
- source = event.singleSource
- if not Source:
- raise Http404
- else:
- source = get_object_or_404(Source, id=source_id)
- stream = psmeca(source)
- response = HttpResponse(mimetype='image/gif')
- shutil.copyfileobj(stream, response)
- stream.close()
- return response
-
def cmtsolution_txt(request, object_id):
from models import Source
source = get_object_or_404(Source, id=object_id)
@@ -1920,8 +1889,8 @@
objId = stationList.id # Ouch!
- view = gui.ChildWindow(url, "View")
- map = gui.ChildWindow(url + "map/", "Map")
+ map = gui.ChildWindow(url, "Map")
+ list = gui.ChildWindow(url + "list/", "List")
properties = gui.ChildWindow(url + "properties/", "Properties")
menuBar = [
gui.Menu("actionMenu", "actions", "Actions",
@@ -1929,17 +1898,23 @@
]
),
]
- view.menuBar = properties.menuBar = menuBar
- desktop.activeWindow.insertWindow(view)
+ map.menuBar = list.menuBar = properties.menuBar = menuBar
desktop.activeWindow.insertWindow(map)
+ desktop.activeWindow.insertWindow(list)
desktop.activeWindow.insertWindow(properties)
if not path:
- return object_detail(request, desktop, view, StationList.objects.all(), object_id = objId)
+ mapUrl = "%s/maps/stations/%s/mercator.jpg" % (config.root, objId)
+ map.content = gui.StaticContent(img(mapUrl, width=547, height=657))
+ desktop.activeWindow.selectWindow(map)
+ return desktop
name = path.pop(0)
if path: raise Http404
+ if name == "list":
+ return object_detail(request, desktop, list, StationList.objects.all(), object_id = objId)
+
if name == "properties":
objId = stationList.fsNode.id # Ouch!
return update_object(request,
@@ -1951,18 +1926,10 @@
follow = FSNode.follow,
)
- if name == "map":
- map.content = gui.StaticContent(img(url + "map.jpg", width=547, height=657))
- desktop.activeWindow.selectWindow(map)
- return desktop
-
if name == "delete":
obj = get_object_or_404(StationList, id=objId)
return moveObjectToTrash(obj, request, config.root + "/home/")
- if name == "map.jpg":
- return stations_map_jpg(stationList)
-
index = Index({
"stations.txt": stationlist_detail_txt,
"gearth.kml": stationlist_detail_gearth,
@@ -2063,17 +2030,6 @@
**kwds)
-def stations_map_jpg(stationList):
- from gmt import stationsMap
- import shutil
-
- stream = stationsMap(stationList)
- response = HttpResponse(mimetype='image/jpeg')
- shutil.copyfileobj(stream, response)
- stream.close()
- return response
-
-
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Help
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
More information about the cig-commits
mailing list