def Scan(self, filename):
        f = file(filename)
        hdr = self.ReadHeader(f)
        pos, item = self.state.get(filename, (0, 0))

        cmop.debug("Scanning %s as RecordStream" % (filename, ), 8)

        if pos == 0:
            pos = f.tell()

        opos, oitem = pos, item

        f.seek(pos)
        for x in self.ReadBlock(hdr, f):
            x['row'] = item
            item += 1
            # add a column for filename
            x['file'] = filename
            self.Enqueue(x)

        pos = f.tell()
        if item != oitem:
            cmop.info("Scanned %s records (%s bytes) from %s" %
                      (item - oitem, pos - opos, filename))

        self.state[filename] = (pos, item)
    def process(self, fname):
        cmop.debug("Seabird file found: %s" % (fname, ))
        cast = seabird.SeabirdCast(fname)
        cast.GetConverted()
        cast.GetBottle()

        # uncomment for speedier testing
        #f = file('sample.cnv')
        #cast.datcnvoutput = f.read()
        cast.Parse()
        cast.ParseBottle()
        record = self.makeCast(cast)

        cmop.debug("Parsed Seabird File %s" % (fname, ))
        # yield {"sqlcommand":"begin"}
        try:
            yield record
            for o in cast.IterateBottle(self.mapping['depth']):
                yield self.makeBottle(record, o)
            for o in cast.Iterate():
                yield self.makeObservation(record, o)

        #  yield {"sqlcommand":"commit"}
        except:
            pass
        # yield {"sqlcommand":"rollback"}

        cmop.info("Processed %s observations for file %s" %
                  (len(cast.rows), fname))
    def Watch(self):
        time.sleep(1)
        currdirs = self.dirs.copy()
        cmop.debug("Watching directory: %s" % (currdirs, ))

        def PhonyEvent(event):
            cmop.debug("Triggering Phony Event %s" % (event, ), 6)
            for d in currdirs:
                dispatch = self.MakeDispatch(d)
                try:
                    cmop.debug("Checking directory %s" % (d, ), 6)
                    for f in os.listdir(d):
                        cmop.debug("Found file %s" % (os.path.join(d, f), ), 6)
                        dispatch(os.path.join(d, f), event)
                except:
                    cmop.error(
                        "Error watching directory: %s" %
                        ("".join(traceback.format_exception(*sys.exc_info()))))

        PhonyEvent(gamin.GAMExists)
        while True:
            #  while self.mon.event_pending():
            if ErrorRaised(): sys.exit()
            #    self.mon.handle_one_event()
            time.sleep(self.pollingdelay)

            PhonyEvent(gamin.GAMChanged)
    def run(self):

        uniquemessages = set([])

        while True:
            try:
                # consume an item, but throw an exception if queue is empty
                data = self.source.Dequeue(False)
                uniquemessages.add(data)

            except Queue.Empty:
                cmop.debug("Coalesced %s messages" % (len(uniquemessages), ),
                           8)
                for m in uniquemessages:
                    self.RunProcess(m)

                uniquemessages.clear()
                time.sleep(self.sleeptime)
    def process(self, data):
        tup = {}

        if 'sqlcommand' in data:
            cmd = data['sqlcommand']
            self.db.execCommand(cmd)
            return []

        table = data.pop('table')

        for k, v in data.items():
            tup[k] = db.quote(v)

        tup = self.clean(tup)
        try:
            yes = self.db.InsertTuple(table, tup.keys(), tup.values())
            cmop.debug("Inserted Tuple: %s" % (tup, ), 9)
        except cmop.db.DuplicateError:
            cmop.debug("Duplicate record: %s" % (tup, ), 8)

        return [tup]
    def WatchNew(self):
        time.sleep(1)
        currdirs = self.dirs.copy()
        cmop.debug("Watching new directory: %s" % (currdirs, ))

        def PhonyEvent(event):
            try:
                for d in currdirs:
                    dispatch = self.MakeDispatch(d)
                    for f in os.listdir(d):
                        path = os.path.join(d, f)
                        dispatch(path, event)
            except:
                cmop.error(
                    "Error watching new directories: %s" %
                    ("".join(traceback.format_exception(*sys.exc_info()))))

        while True:
            PhonyEvent(gamin.GAMExists)
            cmop.debug("sleeping %s seconds" % (self.pollingdelay, ))
            time.sleep(self.pollingdelay)
示例#7
0
    def ValuesClause(self, xfertable, extravals=[]):
        '''
Read all tuples from the given table and prepare a VALUES clause from the results
Returns a tuple of the values clause as a string and the number of tuples involved.
'''
        select = '''SELECT * FROM %s''' % (xfertable, )
        cmop.debug("Reading tuples to transfer.", 8)
        rs = self.fromdb.execQuery(select)
        cnt = len(rs)
        if not rs:
            cmop.info("No tuples to transfer.")
            return "()", 0

        def preprow(r):
            vals = ["%s" % (db.quote(a), ) for a in r]
            vals += extravals
            return "(%s)" % (", ".join(vals), )

        values = ", ".join([preprow(r) for r in rs])

        return values, cnt
    def process(self, data):
        try:
            tuple = {}

            self.GetLatLon(tuple, data)
            self.GetTime(tuple, data)

            tuple['table'] = "cruise.tsg"
            tuple['vessel'] = self.vessel
            tuple['cruise'] = self.cruise
            tuple['instrument'] = self.instrument
            tuple['instrumenttype'] = self.instrumenttype
            tuple['salinity'] = float(data['computed_salinity_flothru'])
            #tuple['temperature'] = float(data['water_temp_seabird_flothru'])
            tuple['temperature'] = float(data['surface_water_temp_seabird'])
            tuple['conductivity'] = float(data['conductivity_seabird_flothru'])
            tuple['winddirection'] = float(
                data.get('wind_heading_ultrasonic_true', -999999))
            tuple['windspeed'] = float(
                data.get('wind_speed_ultrasonic_true(knots)', -999999))
            tuple['atmosphericpressure'] = float(data['barometer'])
            tuple['atmospherictemperature'] = float(
                data['air_temp_rmyoung_doghouse'])

            for k, v in tuple.items():
                if str(v) == 'nan':
                    tuple[k] = None

            cmop.debug("WecomaTSGCleaner generated a tuple: %s" % (tuple, ), 8)
            return [tuple]

        except:
            msg = traceback.format_exc()
            s = ",".join(["(%s=%s)" % (k, v) for k, v in data.iteritems()])
            cmop.info("%s : Skipping bad TSG record: %s" % (msg, s))
            return []
示例#9
0
    def Parse(self):
        '''Parse the content of a datcnv output file. Expects datcnv file to have been read into datcnvoutput attribute.'''

        lines = self.datcnvoutput.split('\n')

        for line in lines:
            line = line.replace('\r', '')

            if re.match('^\*', line):
                # header line
                for key, expr in hdr.items():
                    d = re.search(expr, line)
                    if d:
                        self.__dict__[key] = d.group(1).strip()
                        cmop.debug("HDR: %s=%s" % (key, self.__dict__[key]))
                        break

            elif re.match('^\#', line):
                # metadata line

                col = re.search('# (.+) (\d+) = (.+)', line)
                if col:
                    cmop.debug("COL: %s" % (col.groups(), ))
                    self.__dict__.setdefault(col.group(1).strip(), {})
                    self.__dict__[col.group(1)][int(
                        col.group(2))] = col.group(3)

                else:
                    attr = re.search('# (.+) = (.+)', line)
                    if attr:
                        cmop.debug("ATTR: %s" % (attr.groups(), ))
                        self.__dict__[attr.group(1)] = attr.group(2).strip()
                    else:
                        #unrecognized line
                        cmop.debug("unrecognized line format: %s" % (line, ))

            else:
                # data line
                row = re.sub('^\s+', '', line)
                row = re.sub('\s+$', '', row)

                # make sure the line isn't blank
                if row:
                    row = [r for r in re.split('\s+', row)]
                    self.rows.append(row)
 def PhonyEvent(event):
     cmop.debug("Triggering Phony Event %s" % (event, ), 6)
     for d in currdirs:
         dispatch = self.MakeDispatch(d)
         try:
             cmop.debug("Checking directory %s" % (d, ), 6)
             for f in os.listdir(d):
                 cmop.debug("Found file %s" % (os.path.join(d, f), ), 6)
                 dispatch(os.path.join(d, f), event)
         except:
             cmop.error(
                 "Error watching directory: %s" %
                 ("".join(traceback.format_exception(*sys.exc_info()))))
示例#11
0
def MakeImage():
    # save the active figure to a tempfile
    # should be able to pass in a file object, but alas
    cmop.debug("Creating tempfile...", 5)
    (f, name) = tempfile.mkstemp(".png", dir=fullwritedir)
    os.close(f)
    cmop.debug("Saving image to tempfile %s" % (name, ), 5)
    savefig(name, format='png')

    # close the active figure
    close()

    f = file(name)
    img = f.read()
    f.close()
    os.remove(name)

    cmop.debug("Returning image...", 5)
    return img
示例#12
0
 def debug(self, s, level=10):
   cmop.debug(s, level)
    def GetTime(self, seacast, cast):
        ''' 
Deduce the time of the cast. 
Set the 'time' key on the cast dictionary to an 
expression that can be evaluated by Postgresql
'''

        if hasattr(seacast, 'NMEAtime'):
            # System UpLoad Time is in local time and comes
            # from the system clock of the machine running
            # seasave
            # NMEA time comes from the device, buit has no date
            # information.
            # must assume a bound on clock skew to guess the right date
            test_time1 = dateutil.parser.parse(seacast.NMEAtime,
                                               default=datetime.datetime(
                                                   year=1, month=2, day=3))
            test_time5 = dateutil.parser.parse(seacast.NMEAtime,
                                               default=datetime.datetime(
                                                   year=5, month=1, day=1))
            test = test_time1 - test_time5
            cmop.debug('NMEAtime %s' % seacast.NMEAtime)
            if test == datetime.timedelta(
                    0):  # NMEAtime parses as a full date/time
                cast['time'] = "%s %s" % (seacast.NMEAtime, 'UTC')
                cmop.debug('full NMEA %s' % cast['time'])
                return
            if hasattr(seacast, 'start_time'):
                cmop.debug('start time %s' % seacast.start_time)
                start_time = dateutil.parser.parse(seacast.start_time)
                NMEAtime = dateutil.parser.parse(seacast.NMEAtime)
                comb_time = datetime.datetime.combine(start_time.date(),
                                                      NMEAtime.time())
                if start_time > comb_time + datetime.timedelta(0, 43200):
                    comb_time += datetime.timedelta(1)
                elif comb_time > start_time + datetime.timedelta(0, 43200):
                    comb_time -= datetime.timedelta(1)
                cast['time'] = "%s %s" % (comb_time, 'UTC')
                cmop.debug('NMEA start %s' % cast['time'])
                return
            if hasattr(seacast, 'uploadtime'):
                cmop.debug('upload time %s' % seacast.uploadtime)
                uploadtime = dateutil.parser.parse(seacast.uploadtime)
                NMEAtime = dateutil.parser.parse(seacast.NMEAtime)
                comb_time = datetime.datetime.combine(uploadtime.date(),
                                                      NMEAtime.time())
                if uploadtime > comb_time + datetime.timedelta(0, 43200):
                    comb_time += datetime.timedelta(1)
                elif comb_time > uploadtime + datetime.timedelta(0, 43200):
                    comb_time -= datetime.timedelta(1)
                cast['time'] = "%s %s" % (comb_time, 'UTC')
                cmop.debug('NMEA upload %s' % cast['time'])
                return
        if hasattr(seacast, 'GMTtime') and hasattr(seacast, 'GMTdate'):
            time = seacast.GMTtime
            time.replace(' ', '')
            cmop.debug('trying to merge %s and %s' %
                       (seacast.GMTdate, seacast.GMTtime))
            if re.search('^\d{4}', seacast.GMTtime.strip()):
                time = datetime.time(int(time[0:2]), int(time[2:4]))
                date = seacast.GMTdate
                try:
                    date = int(date)
                    date = datetime.date.fromordinal(date)
                except:
                    date = dateutil.parser.parse(date)
                try:
                    cmop.debug('preparing to merge %s and %s' % (date, time))
                    date = datetime.datetime.combine(date, time)
                    cmop.debug('converted %s to %s' % (seacast.GMTdate, date))
                    if hasattr(seacast, 'start_time'):
                        cmop.debug('start time %s' % seacast.start_time)
                        altdate = dateutil.parser.parse(seacast.start_time)
                    elif hasattr(seacast, 'uploadtime'):
                        cmop.debug('upload time %s' % seacast.uploadtime)
                        altdate = dateutil.parser.parse(seacast.uploadtime)
                    date = date.replace(year=altdate.year)
                    if altdate > date + datetime.timedelta(100):
                        date.replace(year=date.year - 1)
                    elif date > altdate + datetime.timedelta(100):
                        date.replace(year=date.year + 1)
                    cast['time'] = "%s %s" % (date, 'UTC')
                    cmop.debug('GMT time %s' % cast['time'])
                    return
                except:
                    raise TypeError('could not convert %s' % seacast.GMTdate)
        if hasattr(seacast, 'uploadtime'):
            cast['time'] = "%s %s" % (seacast.uploadtime, self.timezone)
            cmop.debug('upload time %s' % cast['time'])
            return
        if hasattr(seacast, 'start_time'):
            cast['time'] = "%s %s" % (seacast.start_time, self.timezone)
            cmop.debug('start time %s' % cast['time'])
            return
        raise ValueError(
            "Cannot calculate cast date: Need either GMTdate and GMTtime, or System Upload Time and NMEA Time.  \n%s"
            % (seacast.__dict__.keys(), ))
示例#14
0
    def Convert(self, cfg="cmop.cfg"):
        '''Use dosemu to run Seabird data conversion.
       datcnv must run in the seabird directory, apparently
       datcnv is slow; prepare for about 260 scans per second
    '''

        dat = self.dat
        con = self.con

        cmop.info("Converting Seabird cast %s, %s" % (dat, con))

        root, base, ext = parsepath(self.dat)

        # file names must be short
        newname = "cast"

        # temp dir
        d = tempfile.mkdtemp('X', 'X')
        cmop.debug("tempdir: \n" + d)

        # dat file
        datpath = link(d, dat, newname)
        dosdat = dosabspath(datpath, self.drive)

        # con file
        conpath = link(d, con, newname)
        doscon = dosabspath(conpath, self.drive)

        # cfg file. cfg file path needs to
        #be relative to seabird directory, inexplicably

        #cfgpath = self.makeconfig(cfg, d)
        #doscfg = dosabspath(cfgpath, self.drive)

        # output file
        out = '%s.cnv' % (newname, )
        outpath = os.path.join(d, out)
        dosout = dosabspath(outpath, self.drive)

        # batch file
        bat = '''
%s:
cd %s 
datcnv.exe -ax -o%s -i%s -c%s -s -e%s
exitemu
'''
        batfile = os.path.join(d, 'seabird.bat')
        f = file(batfile, 'w+')
        dosseabirddir = dosabspath(self.seabirddir, self.drive)
        content = bat % (self.drive, dosseabirddir, dosout, dosdat, doscon,
                         cfg)
        cmop.debug("Batchfile: \n" + content)
        f.write(content)
        f.close()

        # dosemu command
        cmd = 'dosemu -t -quiet -5 -E "%s"' % (batfile, )

        sout, sin = popen2.popen2(cmd)
        response = sout.read()

        try:
            f = file(outpath)
            results = f.read()

            os.remove(datpath)
            os.remove(conpath)
            os.remove(outpath)
            os.remove(batfile)
            os.rmdir(d)

            self.datcnvoutput = results
            return results

        except:
            f = file(os.path.join(d, 'terminal.log'), 'w+')
            f.write(response)
            raise ValueError(
                "Error running datcnv.exe.  See terminal.log in %s" % (d, ))
示例#15
0
    def Transfer(self, table, filter="True", orderby=None, limit=None):
        cmop.debug("Transferring %s" % (table, ))

        if not self.SubscriptionColumnExists(table):
            cmop.debug(
                "Subscription does not appear to be active; no subscription column found on %s"
                % (table, ))
            return

        # get the data attributes
        keys = self.fromdb.PrimaryKey(table)
        if not keys:
            raise TypeError(
                "Table %s does not have a primary key defined; cannot transfer."
                % (table, ))

        keyattrsstr = ", ".join(keys)
        getattrs = self.fromdb.Attributes(table, self.prefix)
        setattrs = getattrs[:]

        # if the reverse subscription is set, mark the new tuple as sent
        if self.AttributeExists(self.todb, table, self.column(self.fromhost)):
            setattrs.append('"%s"' % (self.column(self.fromhost), ))
            val = ['False']
        else:
            val = []

        getattrsstr = ", ".join(getattrs)
        setattrsstr = ", ".join(setattrs)

        get = '''SELECT %s FROM %s WHERE "%s" AND %s'''
        if orderby: get += " ORDER BY %s" % (orderby, )
        if limit: get += " LIMIT %s" % (limit, )
        get = get % (getattrsstr, table, self.dirtycolumn, filter)

        xfertable = table.replace(".", "_") + "_xfer"

        create = '''CREATE TEMP TABLE %s AS  (%s)''' % (xfertable, get)

        insert = '''INSERT INTO %s (%s) VALUES %s''' % (xfertable, setattrsstr,
                                                        "%s")

        drop = "DROP TABLE %s" % (xfertable, )

        def equal(col):
            return "%s.%s = %s.%s" % (table, col, xfertable, col)

        joincond = " AND ".join([equal(col) for col in keys])
        update = '''
UPDATE %s SET %s = False
  FROM %s
 WHERE %s
''' % (table, self.column(self.tohost), xfertable, joincond)

        createremote = '''
CREATE TEMP TABLE %s AS (
SELECT * FROM %s LIMIT 0
)''' % (xfertable, table)

        qualattrs = ", ".join(["%s.%s" % (xfertable, a) for a in setattrs])
        merge = '''
INSERT INTO %s (%s) ( 
  SELECT %s
    FROM %s LEFT JOIN %s
         ON (%s) 
   WHERE %s.%s IS NULL
)
''' % (table, setattrsstr, qualattrs, xfertable, table, joincond, table,
        keys[0])

        try:
            self.fromdb.begin()
            self.todb.begin()

            cmop.debug("Creating xfer table %s on %s" %
                       (xfertable, self.fromhost))
            self.fromdb.execCommand(create)

            cmop.debug("Creating xfer table %s on %s" %
                       (xfertable, self.tohost))
            self.todb.execCommand(createremote)

            cmop.debug("Extracting values from %s on %s" %
                       (xfertable, self.fromhost))
            values, cnt = self.ValuesClause(xfertable, val)

            if cnt > 0:
                cmop.debug("Inserting tuples on %s to %s" %
                           (self.tohost, xfertable))
                self.todb.execCommand(insert % (values, ))

                cmop.debug("Merging tuples on %s into %s" %
                           (self.tohost, table))
                self.todb.execCommand(merge)

                cmop.debug("Marking tuples as sent on %s for %s" %
                           (self.fromhost, table))
                self.fromdb.execCommand(update)

                cmop.debug("Dropping temp tables")
                self.fromdb.execCommand(drop)
                self.todb.execCommand(drop)

                cmop.debug("Committing on %s" % (self.tohost, ))
                self.todb.commit()

                cmop.debug("Committing on %s" % (self.fromhost, ))
                self.fromdb.commit()

        except:
            self.todb.rollback()
            self.fromdb.rollback()
            raise

        cmop.info(
            "Transferred %s %s tuples from %s to %s (may include dupes)" %
            (cnt, table, self.fromhost, self.tohost))