Skip to content
Snippets Groups Projects
Commit eb21f8f5 authored by Brian Moe's avatar Brian Moe
Browse files

Initial Revision

parents
No related branches found
No related tags found
No related merge requests found
Showing with 696 additions and 0 deletions
*.swp
*~
*.pyc
import os
import sys
sys.path.append('/home/lars/django')
sys.path.append('/opt/lscsoft/glue/lib64/python2.4/site-packages')
sys.path.append('/opt/lscsoft/glue/lib/python2.4/site-packages')
os.environ['DJANGO_SETTINGS_MODULE'] = 'gracedb.settings'
#os.environ['PYTHON_EGG_CACHE'] = '/tmp/egg-trash'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
import sys
import time
from subprocess import Popen, PIPE, STDOUT
def issueAlert(event, location):
# XXX awful!
if event.analysisType != 'MBTA':
return
env = {}
pythonpath = ":".join(sys.path)
env["PYTHONPATH"] = pythonpath
null = open('/dev/null','w')
p = Popen(
["lvalert_send",
"--username=gracedb",
"--password=w4k3upal1ve",
"--file=-",
"--node=cbc_mbta_online"
],
executable="/opt/lscsoft/glue/bin/lvalert_send",
stdin=PIPE,
stdout=null,
stderr=STDOUT,
env=env)
msg = createPayload(event.uid, location)
p.stdin.write(msg)
p.stdin.close()
for i in range(1,10):
res = p.poll()
if res == None:
time.sleep(1)
else:
break
def issueAlertX(event, location):
username = "gracedb"
server = "lvalert.phys.uwm.edu"
resource = "sender"
password = "w4k3upal1ve"
node = "cbc_mbta_online"
voevent = createPayload(event.uid, location)
myjid=JID(username+"@"+server+"/"+resource)
recpt=JID("pubsub."+server)
s=MyClient(jid=myjid, password=password, recpt=recpt)
s.connect()
s.send_myevent(voevent, node)
s.loop(1)
def createPayload (uid, filename):
template = """<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE LIGO_LW SYSTEM "http://ldas-sw.ligo.caltech.edu/doc/ligolwAPI/html/ligolw_dtd.txt">
<LIGO_LW>
<Table Name="LVAlert:table">
<Column Type="lstring" Name="LVAlert:uid"/>
<Column Type="lstring" Name="LVAlert:file"/>
<Stream Name="LVAlert:table" Type="Local" Delimiter=",">
"%(uid)s","%(filename)s"
</Stream>
</Table>
</LIGO_LW>
"""
return template % { 'uid': uid, 'filename': filename }
# pubsub import must come first because it overloads part of the
# StanzaProcessor class
from glue.lvalert import pubsub
from pyxmpp.all import JID, TLSSettings
from pyxmpp.jabber.all import Client
class MyClient(Client):
def __init__(self, jid, password, recpt):
# if bare JID is provided add a resource -- it is required
if not jid.resource:
jid=JID(jid.node, jid.domain, "sender")
self.myrecpt = recpt
# we require a TLS connection
t=TLSSettings(require=True,verify_peer=False)
# setup client with provided connection information
# and identity data
Client.__init__(self, jid, password, \
auth_methods=["sasl:GSSAPI","sasl:PLAIN"], tls_settings=t)
def stream_state_changed(self,state,arg):
"""This one is called when the state of stream connecting the component
to a server changes. This will usually be used to let the user
know what is going on."""
pass
def session_started(self):
self.stream.set_response_handlers(self.pspl, \
self.pspl.generic_result,self.pspl.create_error,\
self.pspl.create_timeout)
self.stream.send(self.pspl)
def idle(self):
if self.stream and self.session_established:
self.disconnect()
time.sleep(2)
def post_disconnect(self):
raise Disconnected
def send_myevent(self, voevent, node):
self.pspl=pubsub.PubSub(from_jid = self.jid, to_jid = self.myrecpt, stream = self, stanza_type="get")
self.pspl.publish(voevent,node)
# vi: sts=4 et sw=4
def create(request):
pass
from django import forms
from models import Event, User, Group
class CreateEventForm(forms.Form):
groupChoices = [("","")]+[(g.name, g.name) for g in Group.objects.all()]
typeChoices= [("","")]+list(Event.ANALYSIS_TYPE_CHOICES)
eventFile = forms.FileField()
group = forms.ChoiceField(groupChoices)
type = forms.ChoiceField(choices=typeChoices)
class EventSearchForm(forms.Form):
groupChoices = [("","")]+[(g.name, g.name) for g in Group.objects.all()]
typeChoices= [("","")]+list(Event.ANALYSIS_TYPE_CHOICES)
submitterIds = Event.objects.values_list('submitter',flat=True).distinct()
submitterList = User.objects.filter(id__in=submitterIds).order_by('name')
submitterChoices = [("","")]+ [ (u.id, u.name) for u in submitterList]
uidStart = forms.CharField(required=False)
uidEnd = forms.CharField(required=False)
group = forms.ChoiceField(choices=groupChoices, required=False)
type = forms.ChoiceField(choices=typeChoices, required=False)
submitter = forms.ChoiceField(choices=submitterChoices, required=False)
from django.db import models
import datetime
import thread
import string
def lettersToInt( str ):
"""turn a string of letters into a base 26 number"""
return reduce( lambda x, y: 26*x + y, map( string.lowercase.index, str ))
def intToLetters( i, str='' ):
"""convert a number into a string of lowercase letters"""
if i == 0:
return str or 'a'
else:
return intToLetters( i/26, string.lowercase[i%26] + str )
class Genid:
# XXX dear heaven this is awful.
def __init__(self):
self.lastCalledDate = datetime.datetime.now().date()
# XXX Find latest suffix from Event table
self.next = 0
self.lock = thread.allocate_lock()
prefix = self.lastCalledDate.strftime('%y%m%d')
plen = len(prefix)
analyses = Event.objects.filter(uid__contains=prefix)
if len(analyses) >0:
self.next = 1 + max([lettersToInt(a.uid[plen:]) for a in analyses])
def __call__(self):
self.lock.acquire()
today = datetime.datetime.now().date()
assert (today >= self.lastCalledDate)
if today != self.lastCalledDate:
self.next = 0
self.lastCalledDate = today
prefix = datetime.datetime.now().strftime('%y%m%d')
rv = prefix + intToLetters(self.next)
self.next += 1
self.lock.release()
return rv
# XXX Yarg.
_genid = None
def genid():
global _genid
if not _genid: _genid = Genid()
return _genid()
class User(models.Model):
name = models.CharField(max_length=100)
email = models.EmailField()
principal = models.CharField(max_length=100)
dn = models.CharField(max_length=100)
unixid = models.CharField(max_length=25)
class Meta:
ordering = ["name"]
def __unicode__(self):
return self.name
class Group(models.Model):
name = models.CharField(max_length=20)
managers = models.ManyToManyField(User)
def __unicode__(self):
return self.name
class Event(models.Model):
ANALYSIS_TYPE_CHOICES = (
("LM", "LowMass"),
("HM", "HighMass"),
("GRB", "GRB"),
("RD", "Ringdown"),
("OM", "Omega"),
("Q", "Q"),
("X", "X"),
("CWB", "CWB"),
("MBTA", "MBTA Online"),
)
uid = models.CharField(max_length=20, unique=True, default=genid)
submitter = models.ForeignKey(User)
created = models.DateTimeField(auto_now_add=True)
group = models.ForeignKey(Group)
analysisType = models.CharField(max_length=20, choices=ANALYSIS_TYPE_CHOICES)
def weburl(self):
return "https://ldas-jobs.phys.uwm.edu/gracedb/data/%s" % self.uid
def wikiurl(self):
return "https://www.lsc-group.phys.uwm.edu/twiki/bin/view/Sandbox/%s" % self.uid
def clusterurl(self):
return "pcdev1.phys.uwm.edu:/archive/gracedb/data/%s" % self.uid
from django.conf.urls.defaults import *
#import django.views.generic.list_detail
urlpatterns = patterns('gracedb.gracedb.views',
(r'^$', 'index'),
url (r'^create/$', 'create', name="create"),
url (r'^search/$', 'search', name="search"),
# (r'^view/(?P<uid>[\w\d]+)', 'view'),
# (r'^edit/(?P<uid>[\w\d]+)', 'edit'),
# (r'^request_archive/(?P<uid>[\w\d]+)(?P<rescind>/rescind)?', 'request_archive'),
# (r'^approve_archive/(?P<uid>[\w\d]+)(?P<rescind>/rescind)?', 'approve_archive'),
# url (r'^query', 'query', name="search"),
# url (r'^mine/$', 'mine', name="mine"),
# url (r'^myapprovals/$', 'myapprovals', name="myapprovals"),
)
from django.http import HttpResponse, HttpResponseRedirect, HttpResponseNotFound
from django.template import RequestContext
from django.core.urlresolvers import reverse, get_script_prefix
from django.shortcuts import render_to_response
from django.views.generic.list_detail import object_detail, object_list
from models import Event, Group
from forms import CreateEventForm, EventSearchForm
from alert import issueAlert
import os
def index(request):
# assert request.ligouser
return render_to_response(
'gracedb/index.html',
# {'hi':request.ligouser},
{},
context_instance=RequestContext(request))
def create(request):
assert request.ligouser
if request.method == "GET":
form = CreateEventForm()
else:
form = CreateEventForm(request.POST, request.FILES)
if form.is_valid():
group = Group.objects.filter(name=form.cleaned_data['group'])
type = form.cleaned_data['type']
# Create Event
event = Event()
event.submitter = request.ligouser
event.group = group[0]
event.analysisType = type
# Create data directory/directories
# Save uploaded file.
dirPrefix = "/mnt/gracedb-web/data"
eventDir = os.path.join(dirPrefix, event.uid)
os.mkdir( eventDir )
os.mkdir( os.path.join(eventDir,"private") )
os.mkdir( os.path.join(eventDir,"general") )
#os.chmod( os.path.join(eventDir,"general"), int("041777",8) )
os.chmod( os.path.join(eventDir,"general"), 041777 )
f = request.FILES['eventFile']
uploadDestination = os.path.join(eventDir, "private", f.name)
fdest = open(uploadDestination, 'w')
# XXX probably want to check exit code
# Oh. and it doesn't work.
os.system("/usr/bin/sudo /usr/local/bin/fixgracedirs %s >/dev/null" % event.uid)
#fdest.write("[%s] %s bytes\n" % (f.name, f.size))
# Save uploaded file into user private area.
for chunk in f.chunks():
fdest.write(chunk)
fdest.close()
# Create WIKI page
createWikiPage(event.uid)
event.save() # if everything worked... save.
# Send an alert.
issueAlert(event, os.path.join(event.clusterurl(), "private", f.name))
#return HttpResponseRedirect(reverse(view, args=[event.uid]))
if 'cli' in request.POST:
msg = str(event.uid)
response = HttpResponse(mimetype='text/xml')
response.write(msg)
response['Content-length'] = len(msg)
return response
return HttpResponseRedirect(reverse(search))
else: # form not valid
if 'cli' in request.POST:
# Error occurred in command line client.
# Most likely group name is wrong.
# XXX the form should have info about what is wrong.
groupname = request.POST.get('group', None)
group = Group.objects.filter(name=groupname)
if not group:
validGroups = [group.name for group in Group.objects.all()]
msg = "ERROR: group must be one of: %s" % ", ".join(validGroups)
response = HttpResponse(mimetype='text/xml')
response.write(msg)
response['Content-length'] = len(msg)
return response
# if not a command line request, let it fall through
return render_to_response('gracedb/create.html',
{ 'form' : form },
context_instance=RequestContext(request))
def search(request):
assert request.ligouser
if request.method == 'GET':
form = EventSearchForm()
else:
form = EventSearchForm(request.POST)
if form.is_valid():
objects = Event.objects.all()
start = form.cleaned_data['uidStart']
end = form.cleaned_data['uidEnd']
submitter = form.cleaned_data['submitter']
groupname = form.cleaned_data['group']
typename = form.cleaned_data['type']
if start:
objects = objects.filter(uid__gte=start)
if end:
objects = objects.filter(uid__lte=end)
if submitter:
objects = objects.filter(submitter=submitter)
if groupname:
group = Group.objects.filter(name=groupname)[0]
objects = objects.filter(group=group)
if typename:
objects = objects.filter(analysisType=typename)
return object_list(request, objects, extra_context={'title':"Query Results"})
return render_to_response('gracedb/query.html',
{ 'form' : form },
context_instance=RequestContext(request))
#-----------------------------------------------------------------
# Things that aren't views and should really be elsewhere.
#-----------------------------------------------------------------
def createWikiPage(uid):
twikiroot = "/mnt/htdocs/uwmlsc/secure/twiki/data/Sandbox/"
plainFile = """
Initial Entry for %s
%%TOC{depth="2"}%%
""" % uid
rcsFile = """head 1.1;
access;
symbols;
locks
apache:1.1; strict;
comment @# @;
1.1
date 2009.06.13.00.09.15; author apache; state Exp;
branches;
next ;
desc
@Initial Revision
@
1.1
log
@Initial revision
@
text
@
Initial Entry for %s
%%TOC{depth="2"}%%
@
""" % uid
pname = os.path.join(twikiroot, uid+".txt")
rcsname = os.path.join(twikiroot, uid+".txt,r")
f = open(pname, "w")
f.write(plainFile)
f.close()
f = open(rcsname, "w")
f.write(rcsFile)
f.close()
os.chmod(pname, 0644)
os.chmod(rcsname, 0444)
# f=open(twikiroot+eventid+".txt","w")
# entry=[]
# entry.append('%TOC{depth="2"}%\n')
# entry.append('---+ Twiki page for candidate event ' + eventid)
# f.writelines(entry)
# f.close()
# os.chdir(twikiroot)
# command='echo "initial entry" | ci -l ' +eventid+".txt"
# os.popen(command)
#!/usr/bin/env python
from django.core.management import execute_manager
try:
import settings # Assumed to be in the same directory.
except ImportError:
import sys
sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__)
sys.exit(1)
if __name__ == "__main__":
execute_manager(settings)
# From http://www.djangosnippets.org/snippets/708/
# splits up request's accepted types for easy access.
#
# Added try/except to handle case of no HTTP_ACCEPT header
class AcceptMiddleware(object):
def process_request(self, request):
try:
acc = [a.split(';')[0] for a in request.META['HTTP_ACCEPT'].split(',')]
except:
acc = ['text/html']
setattr(request, 'accepted_types', acc )
request.accepts = lambda type: type in acc
return None
from django.contrib.auth import authenticate
from gracedb.gracedb.models import User
from django.contrib.auth.models import User as DjangoUser
import re
proxyPattern = re.compile(r'^(.*?)(/CN=\d+)*$')
def nameFromPrincipal(principal):
name = principal.split('@')[0]
first, last = name.split('.')
return first[0].upper() + first[1:] + " " + last[0].upper() + last[1:]
class LigoAuthMiddleware:
def process_request(self, request):
ligouser = None
user = None
principal = request.META.get('REMOTE_USER')
certdn = request.META.get('SSL_CLIENT_S_DN')
issuer = request.META.get('SSL_CLIENT_I_DN')
if not certdn:
try:
# mod_python is a little off...
# SSL info is in request._req
# Need to try/except because _req is
# not defined in WSGI request.
certdn = request._req.ssl_var_lookup ('SSL_CLIENT_S_DN')
issuer = request._req.ssl_var_lookup ('SSL_CLIENT_I_DN')
pass
except:
pass
queryResult = []
if principal:
# Kerberos.
queryResult = User.objects.filter(principal=principal)
elif certdn and certdn.startswith(issuer):
# proxy.
# Proxies can be signed by proxies.
# Each level of "proxification" causes the subject
# to have a '/CN=[0-9]+ appended to the signers subject.
# These must be removed to discover the original identity's
# subject DN.
issuer = proxyPattern.match(issuer).group(1)
queryResult = User.objects.filter(dn=issuer)
elif certdn:
# cert in browser.
queryResult = User.objects.filter(dn=certdn)
if queryResult:
ligouser = queryResult[0]
try:
user = DjangoUser.objects.get(username=ligouser.unixid)
except DjangoUser.DoesNotExist:
user = DjangoUser(username=ligouser.unixid, password="")
user.is_staff = False
user.is_superuser = False
user.save()
elif principal:
# There is no user ... what do we do?
# If auth was via cert... nothing, DNs need to be registered.
# If auth was via kerberos, we make sure it was a LIGO.ORG
# principal and make a new user and ligouser with no DN.
#assert (principal.split('@')[1] == 'LIGO.ORG')
ligouser = User(name = nameFromPrincipal(principal),
email = principal.lower(),
principal = principal,
dn = "NONE",
unixid = principal.split('@')[0])
ligouser.save()
try:
user = DjangoUser.objects.get(username=ligouser.unixid)
except DjangoUser.DoesNotExist:
user = DjangoUser(username=ligouser.unixid, password="")
user.is_staff = False
user.is_superuser = False
user.save()
request.user = authenticate(ssluser=user)
request.ligouser = ligouser
# Http404 doesn't check for user == None, just hasattr(x,'user')
# Why does this matter? I forget, but it does.
if not request.user: del request.user
return None
# def process_view(self, request, view_func, view_args, view_kwargs):
# return None
# def process_response(self, request, response):
# return None
# def process_exception(self, request, exception):
# return None
class LigoAuthBackend:
def authenticate(self, ssluser):
return ssluser
def get_user(self, user_id):
try:
return DjangoUser.get(id=user_id)
except Djangouser.UserDoesNotExist:
return None
def LigoAuthContext(request):
return { 'ligouser' : request.ligouser, 'user' : request.user }
# Django settings for gracedb project.
DEBUG = True
TEMPLATE_DEBUG = DEBUG
ADMINS = (
# ('Your Name', 'your_email@domain.com'),
)
MANAGERS = ADMINS
DATABASE_ENGINE = 'mysql'
DATABASE_NAME = 'gracedb'
DATABASE_USER = 'gracedb'
DATABASE_PASSWORD = 'redrum4x'
DATABASE_HOST = '' # Set to empty string for localhost.
DATABASE_PORT = '' # Set to empty string for default.
# Local time zone for this installation. Choices can be found here:
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
# although not all choices may be available on all operating systems.
# If running in a Windows environment this must be set to the same as your
# system time zone.
TIME_ZONE = 'America/Chicago'
# Language code for this installation. All choices can be found here:
# http://www.i18nguy.com/unicode/language-identifiers.html
LANGUAGE_CODE = 'en-us'
SITE_ID = 2
# If you set this to False, Django will make some optimizations so as not
# to load the internationalization machinery.
USE_I18N = True
# Absolute path to the directory that holds media.
# Example: "/home/media/media.lawrence.com/"
MEDIA_ROOT = ''
# URL that handles the media served from MEDIA_ROOT. Make sure to use a
# trailing slash if there is a path component (optional in other cases).
# Examples: "http://media.lawrence.com", "http://example.com/media/"
MEDIA_URL = ''
# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a
# trailing slash.
# Examples: "http://foo.com/media/", "/media/".
ADMIN_MEDIA_PREFIX = '/media/'
# Make this unique, and don't share it with anybody.
SECRET_KEY = '$$&hl%^_4&s0k7sbdr8ll_^gkz-j8oab0tz$t^^b-%$!83d(av'
# List of callables that know how to import templates from various sources.
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.load_template_source',
'django.template.loaders.app_directories.load_template_source',
# 'django.template.loaders.eggs.load_template_source',
)
TEMPLATE_CONTEXT_PROCESSORS = (
"django.core.context_processors.auth",
"django.core.context_processors.debug",
"django.core.context_processors.i18n",
"django.core.context_processors.media",
"lars.middleware.auth.LigoAuthContext",
)
MIDDLEWARE_CLASSES = (
'gracedb.middleware.accept.AcceptMiddleware',
'gracedb.middleware.auth.LigoAuthMiddleware',
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
)
ROOT_URLCONF = 'gracedb.urls'
TEMPLATE_DIRS = (
# Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
# Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths.
"/home/lars/django/gracedb/templates",
)
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.admin',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'gracedb.gracedb',
)
static/images/LIGO_logo.png

13.6 KiB

static/images/LIGO_logo50.png

4.08 KiB

static/images/LSC_logo.png

248 KiB

static/images/LSC_logo50.png

4.87 KiB

static/images/Virgo_logo.png

177 KiB

0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment