def main(options, args): #logger = ssdlog.make_logger('checkstat', options) ro.init() st = ro.remoteObjectProxy(options.statussvc) insdata = INSdata() statusDict = {} lookupDict = {} # Get all the names of the 'ALIVE' status tables for the instruments for insname in insdata.getNames(): if insname == 'VGW': continue inscode = insdata.getCodeByName(insname) tblname = '%3.3sS0001' % inscode alias = 'GEN2.STATUS.TBLTIME.%s' % tblname statusDict[alias] = 0 lookupDict[alias] = insname # Additional tables to check for tblname in ('TSCS', 'TSCL', 'TSCV', 'VGWD', 'VGWQ'): alias = 'GEN2.STATUS.TBLTIME.%s' % tblname statusDict[alias] = 0 lookupDict[alias] = tblname fetchDict = st.fetch(statusDict) if options.sorttime: times = fetchDict.items() times.sort(_timecmp) keys = [(alias, lookupDict[alias]) for alias in \ map(lambda x: x[0], times)] else: keys = lookupDict.items() keys.sort(lambda x, y: cmp(x[1], y[1])) #print keys for alias, name in keys: timeval = fetchDict[alias] if timeval == '##NODATA##': time_s = 'No record' elif isinstance(timeval, float): time_s = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(timeval)) else: time_s = 'ERROR: %s' % str(timeval) print "%-8.8s %s" % (name, time_s)
def main(options, args): ro.init() insconfig = INSdata() archiver = ro.remoteObjectProxy('archiver') if options.infile: with open(options.infile, 'r') as in_f: buf = in_f.read() else: buf = sys.stdin.read() for line in buf.split('\n'): line = line.strip() # skip blank lines and comments if (len(line) == 0) or line.startswith('#'): continue (frameid, path) = line.split() if ':' in path: host, path = path.split(':') else: host = None finfo = frame.getFrameInfoFromPath(frameid) # TODO: we could do in groups, would be faster if there are # a lot of files to transfer framelist = [(finfo.frameid, path)] # Look up the instrument transfer info obcpinfo = insconfig.getOBCPInfoByCode(finfo.inscode) if not host: host = obcpinfo['obcphost'] transfermethod = obcpinfo['transfermethod'] # Make a call to the archiver to transfer this file print "Attempting to archive %s: %s" % (frameid, path) if not options.dry_run: res = archiver.archive_framelist(host, transfermethod, framelist) if res != ro.OK: print "Archiver returned error code %d" % (res) else: print "Archived file." time.sleep(options.interval) else: print "Host: %s Method: %s Framelist: %s" % (host, transfermethod, str(framelist))
def __init__(self, logger, cfg): self.logger = logger self.cfg = cfg self.fv = ro.remoteObjectProxy('fitsview') self.fv1 = ro.remoteObjectProxy('fitsview1') self.stars = ro.remoteObjectProxy('STARS') self.insconfig = INSconfig()
class MockFrameSource(object): def __init__(self): self.count = 1 self.insconfig = INSconfig() def get(self, *args): if len(args) == 3: (insname, frametype, count) = args count = int(count) inscode = self.insconfig.getCodeByName(insname) frameid = ('%-3.3s%1.1s%08.8d:%04.4d' % (inscode, frametype, self.count, count)) elif len(args) == 2: (insname, frametype) = args inscode = self.insconfig.getCodeByName(insname) frameid = ('%-3.3s%1.1s%08.8d' % (inscode, frametype, self.count)) count = 1 else: raise DecodeError("Bad arguments to get_f_no: %s" % str(args)) self.count += count return frameid
def __init__(self, summit_dir, base_dir, error=None, logger=None): self.error = error self.logger = logger self.stars = None # frames in STARS self.summit = {} # all frames @ summit self.base = {} # all frames @ base self.summit_a = {} # A-frames @ summit self.base_a = {} # A-frames @ base self.summit_q = {} # Q-frames @ summit self.base_q = {} # Q-frames @ base self.intersect = None # union of summit and base frames self.summit_dir = summit_dir # frame dir @summit self.base_dir = base_dir # frame dir @base self.obcp = INSdata() self.starsdb = STARSdb(logger)
def __init__(self, logger, host): """Constructor. """ self.logger = logger # Create SOSS DB object self.db = SOSSdb.SOSSdb(self.logger, host=host) # For looking up instruments self.ins_config = INSconfig() super(DbTool, self).__init__()
def __init__(self, svcname, logger, monitor=None, monchannels=[]): self.logger = logger self.monitor = monitor self.monchannels = monchannels # TODO: parameterize tag template (from svcname?) self.tag_template = 'mon.frame.%s.frameSvc' self.insconfig = INSconfig() # For updating status system with session info # TODO: parameterize object self.status = ro.remoteObjectProxy('status') # For mutual exclusion self.lock = threading.RLock()
def __init__(self, logger, ev_quit, monitor, view, queues, fits, soundsink, options, logtype='normal'): self.logger = logger self.ev_quit = ev_quit self.monitor = monitor self.gui = view self.queue = queues self.fits = fits # mutex on this instance self.lock = threading.RLock() self.soundsink = soundsink self.options = options self.logtype = logtype self.histidx = 0 # TODO: improve this self.valid_monlogs = valid_monlogs self.executingP = threading.Event() # For task inheritance: self.threadPool = monitor.get_threadPool() self.tag = 'IntegGUI' self.shares = ['logger', 'ev_quit', 'threadPool'] # Used for looking up instrument codes, etc. self.insconfig = INSdata() self.insname = 'SUKA' self.inscodes = [] self.propid = None # Used to strip out bogus characters from log buffers self.deletechars = ''.join(set(string.maketrans('', '')) - set(string.printable)) self.reset_conn()
def main(options, args): # Get an instrument configuration object insconfig = INSconfig() if options.check_stars: # Only import this if they are asking if file is in STARS import STARSquery for fitspath in args: # Separate leading directory res = fitsutils.getFrameInfoFromPath(fitspath) if not res: print "File name '%s' doesn't match a valid Subaru FITS name." % \ (fitspath) print "Please rename the file as 'XXX{A|Q}DDDDDDDD.fits'" print "Skipping this file..." continue (frameid, fitsfile, fitsdir, inscode, frametype, frameno) = res try: insname = insconfig.getNameByCode(inscode) except KeyError: print "File name '%s' doesn't match a valid Subaru instrument." % \ (fitsfile) print "Skipping this file..." continue if options.check_stars: print "Checking if frame %s is in STARS..." % frameid if STARSquery.GetStarsInfoForFitsID(frameid): print "Frame %s IS in STARS!" % frameid print "Skipping this file..." continue # Look up the instrument number and figure out the path where # the file should end up insnum = insconfig.getNumberByCode(inscode) obcInstrPath = '/mdata/fits/obcp%2d' % insnum obcIndexPath = '/mdata/index' indexfile = frameid + '.index' # Get some metadata by reading the file (if necessary) metadata = {} get_fits_metadata(metadata, fitspath=fitspath, use_mtime=not options.use_ctime) # Substitute path where file should end up metadata['fitspath'] = obcInstrPath + '/' + fitsfile metadata['indexpath'] = obcIndexPath + '/' + indexfile indexpath = options.indexdir + '/' + indexfile # Make the index file if options.create_index: print "Creating index file for %s fits file '%s'..." % \ (insname, fitsfile) create_index_file(metadata, indexpath=indexpath) if options.copy_mdata: # chmod 440 fitspath--what DAQ expects try: os.chmod(fitspath, 0440) except OSError, e: print "Error chmod on '%s': %s" % (fitsfile, str(e)) # FITS file dstpath = obcInstrPath + '/' + fitsfile sshcmd = "ssh [email protected] ls -ld %s" % dstpath res = os.system(sshcmd) if res != 512: print "File may already exist: %s" % dstpath print "Skipping file transfer..." else: scpcmd = "scp -p %s [email protected]:%s" % (fitspath, dstpath) print scpcmd res = 0 res = os.system(scpcmd) if res != 0: print "Error code transferring file: %d" % res # Index file dstpath = obcIndexPath + '/' + indexfile sshcmd = "ssh [email protected] ls -ld %s" % dstpath res = os.system(sshcmd) if res != 512: print "File may already exist: %s" % dstpath print "Skipping file transfer..." else: scpcmd = "scp -p %s [email protected]:%s" % (indexpath, dstpath) print scpcmd res = 0 res = os.system(scpcmd) if res != 0: print "Error code transferring file: %d" % res if options.insert_flowqueue: sshcmd = "ssh [email protected] /soss/SRC/TOOL/bin/DAQobcQueueInsert %s 10000000 -y" % frameid res = 0 print sshcmd res = os.system(sshcmd) if res != 0: print "May have been problem with DAQobcQueueInsert"
def __init__(self): self.count = 1 self.insconfig = INSconfig()
class Frame(object): def __init__(self, summit_dir, base_dir, error=None, logger=None): self.error = error self.logger = logger self.stars = None # frames in STARS self.summit = {} # all frames @ summit self.base = {} # all frames @ base self.summit_a = {} # A-frames @ summit self.base_a = {} # A-frames @ base self.summit_q = {} # Q-frames @ summit self.base_q = {} # Q-frames @ base self.intersect = None # union of summit and base frames self.summit_dir = summit_dir # frame dir @summit self.base_dir = base_dir # frame dir @base self.obcp = INSdata() self.starsdb = STARSdb(logger) def get_base(self): self.logger.debug('getting base frames...') sync_base = {} try: frames = set(self.summit.keys()).difference(self.base.keys()) for f in frames: sync_base[f] = self.summit[f] return sync_base except Exception as e: self.logger.error('error: getting base frames... %s' % e) if self.error: enditer = self.error.get_end_iter() self.error.insert(enditer, 'error: getting base frames... %s\n' % e) def get_summit(self): self.logger.debug('getting summit frames...') sync_summit = {} try: frames = set(self.base.keys()).difference(self.summit.keys()) for f in frames: sync_summit[f] = self.base[f] return sync_summit except Exception as e: self.logger.error('error: getting summit frames... %s' % e) if self.error: enditer = self.error.get_end_iter() self.error.insert(enditer, 'error: getting summit frames... %s\n' % e) def get_stars(self): self.logger.debug('getting stars frames...') frames = list(set(self.intersect).difference(self.stars)) try: stars = {} for frame in frames: stars[frame] = self.base[frame] return stars except Exception as e: self.logger.error('error: getting stars frames... %s' % e) if self.error: enditer = self.error.get_end_iter() self.error.insert(enditer, 'error: getting stars frames... %s\n' % e) def get_delete(self): self.logger.debug('getting delete frames...') try: frames = list(set(self.intersect).intersection(self.stars)) delete = {} for frame in frames: delete[frame] = self.base[frame] return delete except Exception as e: self.logger.error('error: getting summit frames... %s' % e) if self.error: enditer = self.error.get_end_iter() self.error.insert(enditer, 'error: getting delete frames... %s\n' % e) def __search_stars(self, frameid): self.logger.debug('querying stars...') # note: STARS somehow does not let me query both A/Q frames in parallel. # need to query one after other stars_q = self.__search_Q_frames(frameid) stars_a = self.__search_A_frames(frameid) self.stars = stars_a + stars_q def __search_Q_frames(self, frameid): intersect_q = list( set(self.base_q.keys()).intersection(self.summit_q.keys())) stars_q = [] if not len(intersect_q): return stars_q intersect_q.sort() sframe, e = os.path.splitext(intersect_q[0]) eframe, e = os.path.splitext(intersect_q[-1]) self.logger.debug('ins=%s Q between %s and %s' % (frameid, sframe, eframe)) stars = self.starsdb.are_frames_in_stars(frameid, sframe, eframe) stars_q.extend(map(lambda x: '%s.fits' % x, stars)) self.logger.debug('Q query done num=%d' % len(stars_q)) return stars_q def __search_A_frames(self, frameid): intersect_a = list( set(self.base_a.keys()).intersection(self.summit_a.keys())) stars_a = [] if not len(intersect_a): return stars_a intersect_a.sort() sframe, e = os.path.splitext(intersect_a[0]) eframe, e = os.path.splitext(intersect_a[-1]) self.logger.debug('ins=%s A between %s and %s' % (frameid, sframe, eframe)) stars = self.starsdb.are_frames_in_stars(frameid, sframe, eframe) stars_a.extend(map(lambda x: '%s.fits' % x, stars)) self.logger.debug('A query done num=%d' % len(stars_a)) return stars_a def collect_frames(self, ins): today = datetime.datetime.today() frameid = self.obcp.getCodeByName(ins) try: self.base_a, self.base_q = self.__collect_frames( self.base_dir, ins, frameid, today) self.summit_a, self.summit_q = self.__collect_frames( self.summit_dir, ins, frameid, today) self.summit.clear() self.base.clear() self.summit.update(self.summit_a) self.summit.update(self.summit_q) self.base.update(self.base_a) self.base.update(self.base_q) self.intersect = list( set(self.base.keys()).intersection(self.summit.keys())) self.logger.debug( 'base_a=%d base_q=%d base=%d' % (len(self.base_a), len(self.base_q), len(self.base))) self.logger.debug( 'summit_a=%d summit_q=%d summit=%d' % (len(self.summit_a), len(self.summit_q), len(self.summit))) self.logger.debug('intersect=%d' % (len(self.intersect))) # self.__search_stars(frameid) except Exception as e: self.logger.error('error: collecting frames. %s ' % e) if self.error: enditer = self.error.get_end_iter() self.error.insert(enditer, 'error: collecting frames.. %s\n' % e) def __collect_frames(self, path, ins, frameid, today): #print 'collecting base frame....' Afits = '%sA*.fits' % frameid Qfits = '%sQ*.fits' % frameid ins_dir = os.path.join(path, ins) os.chdir(ins_dir) Aframes = glob.glob(Afits) Qframes = glob.glob(Qfits) Aframes = self.__get_frame_info(Aframes, today) Qframes = self.__get_frame_info(Qframes, today) return (Aframes, Qframes) def __get_frame_info(self, frames, today): """ get time stamp, age, size of a file """ stat = os.stat fromtimestamp = datetime.datetime.fromtimestamp frame_info = {} #; append=frame_info.append for frame in frames: info = stat(frame) m_time = fromtimestamp(info.st_mtime) age = today - m_time frame_info[frame] = (m_time.strftime("%Y-%m-%d %H:%M:%S"), age.days, info.st_size) return frame_info
statvars_t = [(1, 'STATOBS.%s.OBSINFO1'), (2, 'STATOBS.%s.OBSINFO2'), (3, 'STATOBS.%s.OBSINFO3'), (4, 'STATOBS.%s.OBSINFO4'), (5, 'STATOBS.%s.OBSINFO5'), # 6 is error log string (7, 'STATOBS.%s.TIMER_SEC'), (8, 'FITS.%s.PROP-ID'), ] opefile_host = 'ana.sum.subaru.nao.ac.jp' valid_monlogs = set(['taskmgr0', 'TSC', 'status', 'sessions', 'frames', 'STARS', 'archiver', 'gen2base', 'integgui2', 'fitsview', 'fitsview1', ]) # add active instrument names valid_monlogs.update(INSdata().getNames()) typical_monlogs = set(['taskmgr0', 'TSC', 'status', 'integgui2', 'archiver' ]) typical_monlogs.update(INSdata().getNames()) class ControllerError(Exception): pass class IntegController(object): """ IMPORTANT NOTE: The GUI thread makes calls into this object, but these SHOULD NOT BLOCK or the GUI becomes unresponsive! ALL CALLS IN should create and start a task to do the work (which will be done on another
# Configuration file for the Gen2 Pub/Sub system (aka "monitor") # # Eric Jeschke # import Bunch from cfg.INS import INSdata channels = Bunch.Bunch() # -- infrastructure channels -- channels.frames = ['names'] # -- interface channels -- # instrument interfaces ins_data = INSdata() channels.ins = [] for obcpnum in ins_data.getNumbers(active=True): channels.ins.append('INSint%d' % obcpnum) # TSC simulator channels.ins.append('INSint%d' % 89) channels.stars = ['STARSint'] channels.tsc = ['TCSint0'] channels.guider = ['GuiderInt'] # -- service channels -- channels.frames = ['frames'] channels.bootmgr = ['bootmgr'] channels.sessmgr = ['sessions'] #channels.statint = ['statint']
class DbTool(object): """Simple class to manipulate the SOSS database. Uses the SOSSdb module access functions. """ def __init__(self, logger, host): """Constructor. """ self.logger = logger # Create SOSS DB object self.db = SOSSdb.SOSSdb(self.logger, host=host) # For looking up instruments self.ins_config = INSconfig() super(DbTool, self).__init__() def check_options(self, options, optionlist): """Check an options object (can be a Bunch, generic object, or as e.g. returned by optparse module) for a set of required attributes that must be NOT None. If any of the options are missing, an error message is generated to prompt for the missing ones. If the option name and the options attribute have different names, then they can be distinguished by a colon in the optionlist. Example: optionlist: ['starttime', 'endtime', 'inst:instruments', 'obsgrp:division'] The options object must contain the attributes starttime, endtime, instruments and division. Supposed endtime and division are None. Then the following error string is logged and an Error raised: 'Missing options: --endtime, --obsgrp """ missing = [] for varname in optionlist: option = varname if ':' in varname: (option, varname) = varname.split(':') try: val = getattr(options, varname) if val == None: missing.append('--%s' % option) except AttributeError: missing.append('--%s' % option) if len(missing) > 0: raise Error("Missing options: %s" % ', '.join(missing)) def set_inst(self, bnch, instruments): """Check a list of instrument names for correctness and set the instruments attribute in the bunch (bnch is a record from the SOSS usradmintbl). If an instrument using AO is specified, and AO is not present, then add AO to the list. """ for insname in instruments: insname = insname.upper() try: self.ins_config.getCodeByName(insname) except KeyError: errmsg = "'%s' is not a valid instrument name" % insname raise Error(errmsg) # Append AO if CIAO specified, but not AO as well if ('CIAO' in instruments) and not ('AO' in instruments): instruments.append('AO') bnch.instruments = instruments def _fillRecord(self, bnch, options): """Update a record (bnch) from the SOSS usradmintbl. bnch is just a Bunch object with fields set to python translated values from the table. Options is another Bunch or any object with matching attributes. If any of them are present and NOT None, then they are copied with the approriate checks and type conversions to the record and then the record is written to the database. May raise an Error. """ # Update start and end dates # TODO: parse variety of date formats, not just twin style if options.starttime: twin_starttime = options.starttime if not ':' in twin_starttime: twin_starttime += '-00:00:00' if not re.match(r'^\d{4}\-\d{2}\-\d{2}\-\d{2}:\d{2}:\d{2}$', twin_starttime): raise Error("Please specify dates in the form YYYY-MM-DD[-HH:MM:SS]") bnch.starttime = SOSSdb.datetime_fromSOSS2(twin_starttime) if options.endtime: twin_endtime = options.endtime if not ':' in twin_endtime: twin_endtime += '-00:00:00' if not re.match(r'^\d{4}\-\d{2}\-\d{2}\-\d{2}:\d{2}:\d{2}$', twin_endtime): raise Error("Please specify dates in the form YYYY-MM-DD[-HH:MM:SS]") bnch.endtime = SOSSdb.datetime_fromSOSS2(twin_endtime) # Update division/observation group (to 'purpose' field in db) if options.division: #bnch.purpose = ObsProposalToSOSSobsGrp(options.division) bnch.purpose = options.division # Update instrument list. options value is a comma-separated string of # isntrument names. If it begins with a + or - then those instruments # are added or removed to the set already in bnch.instruments if options.instruments: if options.instruments.startswith('+'): instruments = list(bnch.instruments) add_instruments = options.instruments[1:].split(',') for insname in add_instruments: insname = insname.upper() if not insname in instruments: instruments.append(insname) elif options.instruments.startswith('-'): instruments = list(bnch.instruments) sub_instruments = options.instruments[1:].split(',') for insname in sub_instruments: insname = insname.upper() if insname in instruments: instruments.remove(insname) else: instruments = options.instruments.split(',') self.set_inst(bnch, instruments) # Update "oplevel". This field is best left to default, unless you really # know what you are doing. if options.oplevel == 'default': bnch.oplevel = g_oplevel['default'].split(',') elif options.oplevel == 'advanced': bnch.oplevel = g_oplevel['advanced'].split(',') elif options.oplevel: bnch.oplevel = options.oplevel.split(',') self.logger.debug("Updated record is: %s" % str(bnch)) def getProp(self, propid): """Method to get a record from the usradmintbl. """ try: return self.db.getProp(propid) except SOSSdb.SOSSdbError, e: raise Error("Couldn't access proposal: %s" % str(e))
class frameSvc(object): """ Implements a frame number service compatible with the one provided by SOSS. """ def __init__(self, svcname, logger, monitor=None, monchannels=[]): self.logger = logger self.monitor = monitor self.monchannels = monchannels # TODO: parameterize tag template (from svcname?) self.tag_template = 'mon.frame.%s.frameSvc' self.insconfig = INSconfig() # For updating status system with session info # TODO: parameterize object self.status = ro.remoteObjectProxy('status') # For mutual exclusion self.lock = threading.RLock() # Need this because we don't inherit from ro.remoteObjectServer, # but are delegated to from it def ro_echo(self, arg): return arg def _set_necessary_status(self, insname, frameid, frametype): instcode = self.insconfig.getCodeByName(insname) statusDict = {} if frametype == 'A': statusDict['FITS.%s.FRAMEID' % instcode] = frameid elif frametype == 'Q': statusDict['FITS.%s.FRAMEIDQ' % instcode] = frameid self.logger.debug("Updating status: %s" % str(statusDict)) self.status.store(statusDict) def getFrameMap(self, insname, frametype): self.logger.info('getting frame map....') with self.lock: insname = insname.upper() frametype = frametype.upper() if len(frametype) > 1: prefix = frametype[1] frametype = frametype[0] else: prefix = '0' try: frameid = framedb.getFrameMap(insname, frametype, prefix=prefix) return (ro.OK, frameid) except Exception, e: raise frameError("Error obtaining framemap info: %s" % (str(e)))
class frame(object): def __init__(self, logger, cfg): self.logger = logger self.cfg = cfg self.fv = ro.remoteObjectProxy('fitsview') self.fv1 = ro.remoteObjectProxy('fitsview1') self.stars = ro.remoteObjectProxy('STARS') self.insconfig = INSconfig() def frames(self, sort=default_sort, fromdate=None, todate=None, noxfer=None, norecv=None, nostars=None, skip=None, allbox=None): """Produce the main Frames page. """ print "entered frames!" # Header string for the generated web page page_hdr = """ <html> <head> <TITLE>Frames</title> %(css)s <script language="javascript"> function checkAll() { for (var i=0; i<document.forms[0].elements.length; i++) { var e=document.forms[0].elements[i]; if ((e.name != 'allbox') && (e.type == 'checkbox')) { e.checked=document.forms[0].allbox.checked; } } } </script> </head> <body> """ # Row template for frames table tbl_row = """ <TR class=%(class)s> <TD>%(check)s</TD> <TD>%(frameid)s</TD> <TD>%(time_alloc)s</TD> <TD>%(time_xfer)s</TD> <TD>%(time_saved)s</TD> <TD>%(time_stars)s</TD> </TR> """ # -- PAGE HEADER --- base_url = self.cfg.my_url my_url = base_url + '/frames' reload_url = my_url + ('?sort=%s' % sort) #print "norecv=%s nostars=%s" % (norecv, nostars) res = [page_hdr % {'css': self.cfg.css}] now = datetime.datetime.now() if todate: todate = urllib.unquote_plus(todate) todate_t = datetime.datetime.strptime(todate, '%Y-%m-%d %H:%M:%S') else: todate_t = datetime.datetime.now() if fromdate: fromdate = urllib.unquote_plus(fromdate) fromdate_t = datetime.datetime.strptime(fromdate, '%Y-%m-%d %H:%M:%S') else: fromdate_t = datetime.datetime.fromtimestamp(time.time() - 86400) fromdate_s = fromdate_t.strftime('%Y-%m-%d %H:%M:%S') todate_s = todate_t.strftime('%Y-%m-%d %H:%M:%S') self.logger.debug("from %s to %s" % (fromdate_s, todate_s)) skip_cancel = (skip != None) norecv = (norecv != None) nostars = (nostars != None) # -- GLOBAL CONTROLS --- res.append("<h3>Controls</h3>") res.append('<a class=btn2 href="%s">Refresh</a>' % (reload_url)) res.append(" | ") res.append('<a class=btn2 href="/doc/help/index.html">Help</a>') res.append("<p>Page last refreshed: %s</p>" % time.ctime()) # -- FRAMES TABLE --- res.append("<h3>Frames from %s to %s</h3>" % (fromdate_s, todate_s)) self.logger.debug("getting framelist") framelist = framedb.getFramesByDate(fromdate_t, todate_t, no_time_xfer=noxfer, no_time_saved=norecv, no_time_hilo=nostars, skip_cancel=skip_cancel) # TODO: allow sorting options framelist.reverse() self.logger.debug("framelist=%s" % (str(framelist))) res.append("<table border=1 cellspacing=2 cellpadding=5>") res.append('<form action=%s/framectl method="get">' % (base_url)) res.append('<input type="hidden" name="fromdate" value="%s">' % fromdate_s) res.append('<input type="hidden" name="todate" value="%s">' % todate_s) d = { 'check': '<b>Select</b>', 'frameid': '<b>Frame ID</b>', 'time_alloc': '<b>Time Allocated</b>', 'time_xfer': '<b>Time Transfer</b>', 'time_saved': '<b>Time Saved</b>', 'time_stars': '<b>Sent to STARS</b>', 'class': 'header', } res.append(tbl_row % d) for data in framelist: d = {} d['check'] = '<input type="checkbox" name="frames" value="%s" />' % ( data['frameid']) frameid = data['frameid'] fitspath = self._get_fitspath(frameid) d['frameid'] = frameid d['class'] = 'none' if isinstance(data['time_alloc'], datetime.datetime): d['time_alloc'] = data['time_alloc'].strftime( '%Y-%m-%d %H:%M:%S') else: d['time_alloc'] = 'N/A' d['class'] = 'warn' if isinstance(data['time_xfer'], datetime.datetime): d['time_xfer'] = data['time_xfer'].strftime( '%Y-%m-%d %H:%M:%S') else: d['time_xfer'] = 'N/A' d['class'] = 'warn' if isinstance(data['time_stars'], datetime.datetime): d['time_stars'] = data['time_stars'].strftime( '%Y-%m-%d %H:%M:%S') else: d['time_stars'] = 'N/A' d['class'] = 'warn' if isinstance(data['time_saved'], datetime.datetime): d['time_saved'] = data['time_saved'].strftime( '%Y-%m-%d %H:%M:%S') d['frameid'] = '<a href="%s/getfitsheader/%s">%s</a>' % ( base_url, frameid, frameid) else: d['time_saved'] = 'N/A' if d['time_xfer'] == 'N/A': d['class'] = 'warn' else: d['class'] = 'error' res.append(tbl_row % d) res.append("</table>") res.append( '<p><input type="checkbox" value="on" name="allbox" onclick="checkAll();"/> Select all<br />' ) res.append( '<p><input class=btn2 type="submit" name="action" value="Show in FITS viewer" />' ) res.append( '<input class=btn2 type="submit" name="action" value="Retry STARS transfer" />' ) res.append('<p>') res.append( '<input class=btn2 type="submit" name="action" value="Get list" />' ) res.append( '<input type="text" name="path" size=20 value="/tmp/framelist.txt" />' ) res.append('</form>') res.append("""<p> <form action=%(formurl)s method="get"> Specify different date range (format YYYY-MM-DD HH:MM:SS): <p> <input type="text" name="fromdate" size=20 value="%(fromdate)s"> <input type="text" name="todate" size=20 value="%(todate)s"> <p> Skip cancelled <input type="checkbox" name="skip" value="true"> No transfer time <input type="checkbox" name="noxfer" value="true"> No saved time <input type="checkbox" name="norecv" value="true"> No STARS time <input type="checkbox" name="nostars" value="true"> <p> <input class=btn2 type="submit" value="Reload"> </form>""" % ({ 'formurl': my_url, 'fromdate': fromdate_s, 'todate': todate_s, })) res.append('<p><hr width="30%">') res.append('<a href="/default">Back to home</a>') res.append("</body>\n</html>") html = " ".join(res) #print html return html def _get_fitspath(self, frameid): match = re.match('^(\w{3})([AQ])(\d)(\d{7})$', frameid) if not match: raise IOError("Bad frameid '%s'" % frameid) (inscode, frtype, prefix, number) = match.groups() insname = self.insconfig.getNameByCode(inscode) fitspath = os.path.abspath( os.path.join(g2soss.datahome, insname, "%s.fits" % frameid)) return fitspath def getfitsheader(self, frameid): """Show the detail for a frame _frameid_. """ # Header string for the generated web page page_hdr = """ <html> <head> <TITLE>Frame: %(frameid)s</title> %(css)s </head> <body> """ # Row template for fits header tbl_row = """ <TR class=%(class)s> <TD>%(kwd)s</TD> <TD>%(val)s</TD> </TR> """ # -- PAGE HEADER --- base_url = self.cfg.my_url frameid = frameid.upper() res = [page_hdr % {'css': self.cfg.css, 'frameid': frameid}] # -- FRAMES TABLE --- res.append("<h3>%s</h3>" % frameid) res.append( '<a href="%s/framectl?frames=%s&action=show">View frame in FITS viewers</a>' % ((base_url, frameid))) try: fitspath = self._get_fitspath(frameid) fits_f = pyfits.open(fitspath, "readonly") try: res.append("<h4>FITS Header</h4>") res.append("<table border=1 cellspacing=2 cellpadding=5>") d = { 'kwd': '<b>Keyword</b>', 'val': '<b>Value</b>', 'class': 'header', } res.append(tbl_row % d) # this seems to be necessary now for some fits files... fits_f.verify('fix') header = fits_f[0].header keys = [] for key, val in header.items(): keys.append(key) keys.sort() for key in keys: d = {} ## d['check'] = '<input type="checkbox" name="frames" value="%s" />' % ( ## data['frameid']) d['kwd'] = '%-8.8s' % key d['val'] = str(header[key]) d['class'] = 'none' res.append(tbl_row % d) res.append("</table>") finally: fits_f.close() except Exception, e: res.append("Sorry, that frame is not available.<p><tt>%s</tt>" % (str(e))) res.append('<p><hr width="30%">') res.append('<a href="/default">Back to home</a>') res.append("</body>\n</html>") html = " ".join(res) #print html return html
# # Make data directories for active instruments. Expects env var # DATAHOME to be set. # import sys, os from cfg.INS import INSdata as INSconfig ic = INSconfig() for name in ic.getNames(active=True): dirpath = os.path.join(os.environ['DATAHOME'], name) if not os.path.isdir(dirpath): print "Making %s..." % dirpath os.mkdir(dirpath)
# For errors generated by configuration class Error(Exception): pass gen2home = ('%s/Svn/python/Gen2' % os.environ['HOME']) try: gen2home = os.environ['GEN2HOME'] except KeyError: # What should we do here? #raise Error("GEN2HOME environment variable is undefined") pass # For getting instrument information ins_data = INSdata() ############################################################################# # Log files configuration ############################################################################# def logdir(): try: logdir = os.environ['LOGHOME'] except KeyError: try: logdir = ('%s/Logs' % os.environ['GEN2HOME']) except KeyError: raise Error("LOGHOME and GEN2HOME env vars are undefined")