Beispiel #1
0
def begin_event(conn):
    """An event to be executed when a transaction is opened.
        
        See SQLAlchemy for details about event triggers.
    """
    notify.print_debug("Opening database transaction.", 'database',
                       stepsback=7)
Beispiel #2
0
def run_manipulator(prepped_manipfunc, infns, outname=None,
                    tmpdir=None):
    """Set up a temporary directory to run the manipulator
        method in, load the archives, run the manipulator,
        get the result of the manipulator, break down the
        temporary directory and return the result of the
        manipulation.

        Inputs:
            prepped_manipfunc: A prepared manipulator function to use. 
            infns: Names of the input files to be passed to the
                manipulator
            outname: File name of the manipulated archive.
            tmpdir: Location of the temporary directory.
                (Default: let python's 'tempfile' module
                    put the temp dir in a standard location.)

        Outputs:
            None
    """
    workdir = tempfile.mkdtemp(dir=tmpdir, prefix='toaster_tmp',
                               suffix='_workdir')
    newfns = []
    for fn in infns:
        newfn = os.path.join(workdir, os.path.split(fn)[-1])
        shutil.copy(fn, newfn)
        newfns.append(newfn)
    try:
        prepped_manipfunc(newfns, outname)
    finally:
        if debug.is_on('MANIPULATOR'):
            notify.print_debug("Manipulator worked in %s. Not removing it.",
                               'manipulator')
        else:
            shutil.rmtree(workdir)
Beispiel #3
0
def rollback_event(conn):
    """An event to be executed when a transaction is rolled back.
        
        See SQLAlchemy for details about event triggers.
    """
    notify.print_debug("Rolling back database transaction.", 'database',
                       stepsback=7)
Beispiel #4
0
    def rollback(self):
        """Roll back the most recently opened transaction.
            
            Inputs:
                None

            Outputs:
                None
        """
        notify.print_debug("Attempting to roll back a transaction via "
                           "database object", 'database', stepsback=2)
        trans = self.open_transactions.pop()
        trans.rollback()
Beispiel #5
0
def before_cursor_execute(conn, cursor, statement, parameters,
                          context, executemany):
    """An event to be executed before execution of SQL queries.

        See SQLAlchemy for details about event triggers.
    """
    # Step back 7 levels through the call stack to find
    # the function that called 'execute'
    msg = str(statement)
    if executemany and len(parameters) > 1:
        msg += "\n    Executing %d statements" % len(parameters)
    elif parameters:
        msg += "\n    Params: %s" % str(parameters)
    notify.print_debug(msg, "queries", stepsback=7)
Beispiel #6
0
def parkes_reader(line, get_telescope_id=True):
    """Parse line, assuming it is a TOA in parkes format.
        Return a dictionary of information.

        Input:
            line: A single TOA line in parkes format.
            get_telescope_id: Query the database to get the telescope
                ID number. (Default: True)

        Output:
            toainfo: A dictionary of TOA information.
    """
    parkes_toa_re = re.compile(r'^ *?(?P<bad>(#|(C ))(?P<comment1>.*?))?'
                               r' (?P<info>.{24})(?P<freq>.{9})(?P<imjd>.{7})(?P<fmjd>\..{12}) '
                               r'(?P<phaseoffset>.{8}) (?P<err>.{7})(?P<info2>.{7}) '
                               r'(?P<site>.)(?P<dmcorr>[^#]*)')
    comment_re = re.compile(r'#(?P<comment>.*)$')
    
    match = parkes_toa_re.search(line.rstrip())
    if match is None:
        toainfo = None
        notify.print_debug("Line is not a Parkes-format TOA:\n    %s" % line, 'toaparse')
    else:
        grp = match.groupdict()
        toainfo = {}
        toainfo['is_bad'] = (grp['bad'] is not None)
        toainfo['freq'] = float(grp['freq'])
        toainfo['imjd'] = int(grp['imjd'])
        toainfo['fmjd'] = float(grp['fmjd'])
        toainfo['toa_unc_us'] = float(grp['err'])
        toainfo['telescope'] = grp['site']
        if get_telescope_id:
            toainfo['telescope_id'] = cache.get_telescope_info(grp['site'])['telescope_id']
        toainfo['extras'] = {'phaseoffset': float(grp['phaseoffset']),
                             'infostr': grp['info'].strip() + ' -- ' + grp['info2'].strip()}
        if grp['dmcorr']:
            toainfo['extras']['dmcorr'] = float(grp['dmcorr'])

        comments = []
        if grp['comment1']:
            comments.append(grp['comment1'].strip())
        match2 = comment_re.search(line[match.end():])
        if match2:
            grp2 = match2.groupdict()
            if grp2['comment']:
                comments.append(grp2['comment'].strip())
        toainfo['comment'] = " -- ".join(comments)
            
    return toainfo
Beispiel #7
0
    def close(self):
        """Close the established connection. 
            Also, close any result set that may be present.

            Inputs:
                None

            Outputs:
                None
        """
        if self.is_connected():
            notify.print_debug("Database connection closed.", 'database',
                               stepsback=2)
            self.conn.close()
            if self.result is not None:
                self.result.close()
Beispiel #8
0
    def commit(self):
        """Commit the most recently opened transaction.
            
            Inputs:
                None

            Outputs:
                None
        """
        notify.print_debug("Attempting to commit a transaction via "
                           "database object", 'database', stepsback=2)
        if self.open_transactions:
            trans = self.open_transactions.pop()
        else:
            raise errors.DatabaseError("Cannot commit. No open database transactions.")
        trans.commit()
Beispiel #9
0
    def begin(self):
        """Begin a transaction.

            Inputs:
                None

            Outputs:
                None
        """
        notify.print_debug("Attempting to begin a transaction via "
                           "database object", 'database', stepsback=2)
        if not self.is_connected():
            raise errors.DatabaseError("Connection to database not "
                                       "established. Be sure "
                                       "self.connect(...) is called "
                                       "before attempting to execute "
                                       "queries.")
        if self.open_transactions:
            warnings.warn("A transaction already appears to be in progress.",
                          errors.ToasterWarning)
        trans = self.conn.begin()
        self.open_transactions.append(trans)
        return trans
Beispiel #10
0
    def connect(self):
        """Connect to the database, setting self.conn.
            
            Inputs:
                None

            Output:
                conn: The established SQLAlchemy Connection object, 
                    which is also available as self.conn.
        """
        # Only open a connection if not already connected
        if not self.is_connected():
            # Establish a connection
            self.conn = self.engine.connect()
            self.conn.execution_options(autocommit=self.autocommit)
            self.open_transactions = []
            self.result = None
            if self.engine.dialect.name == 'sqlite':
                result = self.execute("PRAGMA foreign_keys=ON")
                result.close()
            notify.print_debug("Database connection established.",
                               'database',
                               stepsback=2)
        return self.conn
Beispiel #11
0
def tempo2_reader(line, get_telescope_id=True):
    """Parse line, assuming it is a TOA in tempo2 format.
        Return a dictionary of information.

        Input:
            line: A single TOA line in Tempo2 format.
            get_telescope_id: Query the database to get the telescope
                ID number. (Default: True)

        Output:
            toainfo: A dictionary of TOA information.
    """
    tempo2_toa_re = re.compile(r'^ *(?P<bad>(#|(C )|(c ))(?P<comment1>.*?))? *'
                               r'(?P<file>[^ ]+) +'
                               r'(?P<freq>\d+(\.\d+)?) +(?P<imjd>\d+)(?P<fmjd>\.\d+) +'
                               r'(?P<err>\d+(\.\d+)?) +(?P<site>[^ ]+)')
    comment_re = re.compile(r'#(?P<comment>.*)$')
    tempo2_flag_re = re.compile(r'-(?P<flagkey>[^ ]+) +(?P<flagval>[^ ]+)')
    match = tempo2_toa_re.search(line)
    if match is None:
        toainfo = None
        notify.print_debug("Line is not a Tempo2 TOA:\n    %s" % line, 'toaparse')
    else:
        grp = match.groupdict()
     
        toainfo = {}
        toainfo['grp'] = grp
        toainfo['is_bad'] = (line.strip().startswith('#') or line.strip().lower().startswith('c ')) #(grp['bad'] is not None)
        toainfo['file'] = grp['file']
        toainfo['freq'] = float(grp['freq'])
        toainfo['imjd'] = int(grp['imjd'])
        toainfo['fmjd'] = float(grp['fmjd'])
        toainfo['toa_unc_us'] = float(grp['err'])
        toainfo['telescope'] = grp['site']
        toainfo['line'] = line
        if get_telescope_id:
            toainfo['telescope_id'] = cache.get_telescope_info(grp['site'])['telescope_id']
        comments = []
        if grp['comment1']:
            comments.append(grp['comment1'].strip())
        match2 = comment_re.search(line[match.end():])
        if match2:
            grp2 = match2.groupdict()
            if grp2['comment']:
                comments.append(grp2['comment'].strip())
        toainfo['comment'] = " -- ".join(comments)
            
        toainfo['extras'] = {}
        for key, val in tempo2_flag_re.findall(line[match.end():]):
            key = key.lower()
            key = KNOWN_FLAG_ALIASES.get(key, key)
            caster = KNOWN_FLAG_TYPES.get(key, str)
            try:
                toainfo['extras'][key] = caster(val.strip())
            except:
                notify.print_info("Couldn't cast %s:%s" % (key, val), 2)

    notify.print_debug("TOA line: %s\nParsed info: %s" % (line, toainfo),
                    'toaparse')

    return toainfo
Beispiel #12
0
def execute(cmd, stdout=subprocess.PIPE, stderr=sys.stderr,
            execdir=None, stdinstr=None):
    """Execute the command 'cmd' after logging the command
        to STDOUT. Execute the command in the directory 'execdir',
        which defaults to the current directory is not provided.

        Output standard output to 'stdout' and standard
        error to 'stderr'. Both are strings containing filenames.
        If values are None, the out/err streams are not recorded.
        By default stdout is subprocess.PIPE and stderr is sent 
        to sys.stderr.

        If stdinstr is not None, send the string to the command as
        data in the stdin stream.

        Returns (stdoutdata, stderrdata). These will both be None, 
        unless subprocess.PIPE is provided.
    """
    # Log command to stdout
    if execdir is not None:
        msg = "(In %s)\n%s" % (execdir, str(cmd))
    else:
        msg = str(cmd)
    notify.print_debug(msg, "syscalls", stepsback=2)

    stdoutfile = False
    stderrfile = False
    if isinstance(stdout, str):
        stdout = open(stdout, 'w')
        stdoutfile = True
    if isinstance(stderr, str):
        stderr = open(stderr, 'w')
        stderrfile = True

    if stdinstr is not None:
        notify.print_debug("Sending the following to cmd's stdin: %s" % stdinstr, \
                           "syscalls")
        # Run (and time) the command. Check for errors.
        pipe = subprocess.Popen(cmd, shell=False, cwd=execdir,
                                stdin=subprocess.PIPE,
                                stdout=stdout, stderr=stderr)
        (stdoutdata, stderrdata) = pipe.communicate(stdinstr)
    else:
        # Run (and time) the command. Check for errors.
        pipe = subprocess.Popen(cmd, shell=False, cwd=execdir,
                                stdout=stdout)#, stderr=stderr)
        (stdoutdata, stderrdata) = pipe.communicate()
    retcode = pipe.returncode
    if retcode < 0:
        raise errors.SystemCallError("Execution of command (%s) terminated by signal (%s)!" % \
                                     (cmd, -retcode))
    elif retcode > 0:
        raise errors.SystemCallError("Execution of command (%s) failed with status (%s)!" % \
                                     (cmd, retcode))
    else:
        # Exit code is 0, which is "Success". Do nothing.
        pass

    # Close file objects, if any
    if stdoutfile:
        stdout.close()
    if stderrfile:
        stderr.close()

    return stdoutdata, stderrdata