예제 #1
0
class SLClient(object):
    """
    Basic class to create and use a connection to a SeedLink server using a
    SeedLinkConnection object.

    A new SeedLink application can be created by sub-classing SLClient and
    overriding at least the packetHandler method of SLClient.

    :var slconn: SeedLinkConnection object for communicating with the
        SeedLinkConnection over a socket.
    :type slconn: SeedLinkConnection
    :var verbose: Verbosity level, 0 is lowest.
    :type verbose: int
    :var ppackets: Flag to indicate show detailed packet information.
    :type  ppackets: boolean
    :var streamfile: Name of file containing stream list for multi-station
        mode.
    :type  streamfile: str
    :var selectors: Selectors for uni-station or default selectors for
        multi-station.
    :type  selectors: str
    :var multiselect: Selectors for multi-station.
    :type  multiselect: str
    :var statefile: Name of file for reading (if exists) and storing state.
    :type  statefile: str
    :var begin_time: Beginning of time window for read start in past.
    :type  begin_time :str
    :var end_time: End of time window for reading windowed data.
    :type  end_time: str
    :var infolevel: INFO LEVEL for info request only.
    :type  infolevel: str
    """
    VERSION = "1.2.0X00"
    VERSION_YEAR = "2011"
    VERSION_DATE = "24Nov" + VERSION_YEAR
    COPYRIGHT_YEAR = VERSION_YEAR
    PROGRAM_NAME = "SLClient v" + VERSION
    VERSION_INFO = PROGRAM_NAME + " (" + VERSION_DATE + ")"
    BANNER = ["SLClient comes with ABSOLUTELY NO WARRANTY"]

    def __init__(self, loglevel='DEBUG'):
        """
        Creates a new instance of SLClient with the specified logging object
        """
        numeric_level = getattr(logging, loglevel.upper(), None)
        if not isinstance(numeric_level, int):
            raise ValueError('Invalid log level: %s' % loglevel)
        logging.basicConfig(level=numeric_level)

        self.slconn = None
        self.verbose = 0
        self.ppackets = False
        self.streamfile = None
        self.selectors = None
        self.multiselect = None
        self.statefile = None
        self.begin_time = None
        self.end_time = None
        self.infolevel = None

        ## for-while
        for line in SLClient.BANNER:
            print line
        self.slconn = SeedLinkConnection()

    def parseCmdLineArgs(self, args):
        """
        Parses the commmand line arguments.

        :type args: list
        :param args: main method arguments.
        :return: -1 on error, 1 if version or help argument found, 0 otherwise.
        """
        if len(args) < 2:
            self.printUsage(False)
            return 1
        optind = 1
        while optind < len(args):
            if args[optind] == "-V":
                print(self.VERSION_INFO, sys.stderr)
                return 1
            elif args[optind] == "-h":
                self.printUsage(False)
                return 1
            elif args[optind].startswith("-v"):
                self.verbose += len(args[optind]) - 1
            elif args[optind] == "-p":
                self.ppackets = True
            elif args[optind] == "-nt":
                optind += 1
                self.slconn.setNetTimout(int(args[optind]))
            elif args[optind] == "-nd":
                optind += 1
                self.slconn.setNetDelay(int(args[optind]))
            elif args[optind] == "-k":
                optind += 1
                self.slconn.setKeepAlive(int(args[optind]))
            elif args[optind] == "-l":
                optind += 1
                self.streamfile = args[optind]
            elif args[optind] == "-s":
                optind += 1
                self.selectors = args[optind]
            elif args[optind] == "-S":
                optind += 1
                self.multiselect = args[optind]
            elif args[optind] == "-x":
                optind += 1
                self.statefile = args[optind]
            elif args[optind] == "-t":
                optind += 1
                self.begin_time = args[optind]
            elif args[optind] == "-e":
                optind += 1
                self.end_time = args[optind]
            elif args[optind] == "-i":
                optind += 1
                self.infolevel = args[optind]
            elif args[optind].startswith("-"):
                print("Unknown option: " + args[optind], sys.stderr)
                return -1
            elif self.slconn.getSLAddress() is None:
                self.slconn.setSLAddress(args[optind])
            else:
                print("Unknown option: " + args[optind], sys.stderr)
                return -1
            optind += 1
        return 0

    def initialize(self):
        """
        Initializes this SLClient.
        """
        if self.slconn.getSLAddress() is None:
            message = "no SeedLink server specified"
            raise SeedLinkException(message)

        if self.verbose >= 2:
            self.ppackets = True
        if self.slconn.getSLAddress().startswith(":"):
            self.slconn.setSLAddress("127.0.0.1" + self.slconn.getSLAddress())
        if self.streamfile is not None:
            self.slconn.readStreamList(self.streamfile, self.selectors)
        if self.multiselect is not None:
            self.slconn.parseStreamlist(self.multiselect, self.selectors)
        else:
            if self.streamfile is None:
                self.slconn.setUniParams(self.selectors, -1, None)
        if self.statefile is not None:
            self.slconn.setStateFile(self.statefile)
        else:
            if self.begin_time is not None:
                self.slconn.setBeginTime(self.begin_time)
            if self.end_time is not None:
                self.slconn.setEndTime(self.end_time)

    def run(self):
        """
        Start this SLClient.
        """
        if self.infolevel is not None:
            self.slconn.requestInfo(self.infolevel)
        # Loop with the connection manager
        count = 1
        slpack = self.slconn.collect()
        while slpack is not None:
            if (slpack == SLPacket.SLTERMINATE):
                break
            try:
                # do something with packet
                terminate = self.packetHandler(count, slpack)
                if terminate:
                    break
            except SeedLinkException as sle:
                print(self.__class__.__name__ + ": " + sle.value)
            if count >= sys.maxint:
                count = 1
                print "DEBUG INFO: " + self.__class__.__name__ + ":",
                print "Packet count reset to 1"
            else:
                count += 1
            slpack = self.slconn.collect()

        # Close the SeedLinkConnection
        self.slconn.close()

    def packetHandler(self, count, slpack):
        """
        Processes each packet received from the SeedLinkConnection.

        This method should be overridden when sub-classing SLClient.

        :type count: int
        :param count:  Packet counter.
        :type slpack: :class:`~obspy.seedlink.SLPacket`
        :param slpack: packet to process.
        :return: Boolean true if connection to SeedLink server should be
            closed and session terminated, false otherwise.
        """
        # check if not a complete packet
        if slpack is None or (slpack == SLPacket.SLNOPACKET) or \
                (slpack == SLPacket.SLERROR):
            return False

        # get basic packet info
        seqnum = slpack.getSequenceNumber()
        type = slpack.getType()

        # process INFO packets here
        if (type == SLPacket.TYPE_SLINF):
            return False
        if (type == SLPacket.TYPE_SLINFT):
            print "Complete INFO:\n" + self.slconn.getInfoString()
            if self.infolevel is not None:
                return True
            else:
                return False

        # can send an in-line INFO request here
        try:
            #if (count % 100 == 0 and not self.slconn.state.expect_info):
            if (count % 100 == 0):
                infostr = "ID"
                self.slconn.requestInfo(infostr)
        except SeedLinkException as sle:
            print(self.__class__.__name__ + ": " + sle.value)

        # if here, must be a data blockette
        print self.__class__.__name__ + ": packet seqnum:",
        print str(seqnum) + ": blockette type: " + str(type)
        if not self.ppackets:
            return False

        # process packet data
        trace = slpack.getTrace()
        if trace is not None:
            print self.__class__.__name__ + ": blockette contains a trace: "
            print trace.id, trace.stats['starttime'],
            print " dt:" + str(1.0 / trace.stats['sampling_rate']),
            print " npts:" + str(trace.stats['npts']),
            print " sampletype:" + str(trace.stats['sampletype']),
            print " dataquality:" + str(trace.stats['dataquality'])
            if self.verbose >= 3:
                print self.__class__.__name__ + ":"
                print "blockette contains a trace: " + str(trace.stats)
        else:
            print self.__class__.__name__ + ": blockette contains no trace"
        return False

    def printUsage(self, concise):
        """
        Prints the usage message for this class.
        """
        print("\nUsage: python %s [options] <[host]:port>" % \
              (self.__class__.__name__))
        if concise:
            print("Use '-h' for detailed help")
            return
        print
        print(" ## General program options ##")
        print(" -V             report program version")
        print(" -h             show this usage message")
        print(" -v             be more verbose, multiple flags can be used")
        print(" -p             print details of data packets")
        print(" -nd delay      network re-connect delay (seconds), default 30")
        print(
            " -nt timeout    network timeout (seconds), re-establish connection if no"
        )
        print(
            "                  data/keepalives are received in this time, default 600"
        )
        print(
            " -k interval    send keepalive (heartbeat) packets this often (seconds)"
        )
        print(
            " -x statefile   save/restore stream state information to this file"
        )
        print(
            " -t begintime   sets a beginning time for the initiation of data transmission (year,month,day,hour,minute,second)"
        )
        print(
            " -e endtime     sets an end time for windowed data transmission  (year,month,day,hour,minute,second)"
        )
        print(
            " -i infolevel   request this INFO level, write response to std out, and exit "
        )
        print(
            "                  infolevel is one of: ID, STATIONS, STREAMS, GAPS, CONNECTIONS, ALL "
        )
        print
        print(" ## Data stream selection ##")
        print(
            " -l listfile    read a stream list from this file for multi-station mode"
        )
        print(
            " -s selectors   selectors for uni-station or default for multi-station"
        )
        print(
            " -S streams     select streams for multi-station (requires SeedLink >= 2.5)"
        )
        print("   'streams' = 'stream1[:selectors1],stream2[:selectors2],...'")
        print("        'stream' is in NET_STA format, for example:")
        print("        -S \"IU_KONO:BHE BHN,GE_WLF,MN_AQU:HH?.D\"")
        print("")
        print(
            " <[host]:port>  Address of the SeedLink server in host:port format"
        )
        print(
            "                  if host is omitted (i.e. ':18000'), localhost is assumed"
        )

    @classmethod
    def main(cls, args):
        """
        Main method - creates and runs an SLClient using the specified
        command line arguments
        """
        slClient = None
        try:
            slClient = SLClient()
            rval = slClient.parseCmdLineArgs(args)
            if (rval != 0):
                sys.exit(rval)
            slClient.initialize()
            slClient.run()
        except Exception as e:
            logger.critical(e)
            traceback.print_exc()
예제 #2
0
class SLClient(object):
    """
    Basic class to create and use a connection to a SeedLink server using a
    SeedLinkConnection object.

    A new SeedLink application can be created by sub-classing SLClient and
    overriding at least the packetHandler method of SLClient.

    :var slconn: SeedLinkConnection object for communicating with the
        SeedLinkConnection over a socket.
    :type slconn: SeedLinkConnection
    :var verbose: Verbosity level, 0 is lowest.
    :type verbose: int
    :var ppackets: Flag to indicate show detailed packet information.
    :type  ppackets: boolean
    :var streamfile: Name of file containing stream list for multi-station
        mode.
    :type  streamfile: str
    :var selectors: Selectors for uni-station or default selectors for
        multi-station.
    :type  selectors: str
    :var multiselect: Selectors for multi-station.
    :type  multiselect: str
    :var statefile: Name of file for reading (if exists) and storing state.
    :type  statefile: str
    :var begin_time: Beginning of time window for read start in past.
    :type  begin_time :str
    :var end_time: End of time window for reading windowed data.
    :type  end_time: str
    :var infolevel: INFO LEVEL for info request only.
    :type  infolevel: str
    """
    VERSION = "1.2.0X00"
    VERSION_YEAR = "2011"
    VERSION_DATE = "24Nov" + VERSION_YEAR
    COPYRIGHT_YEAR = VERSION_YEAR
    PROGRAM_NAME = "SLClient v" + VERSION
    VERSION_INFO = PROGRAM_NAME + " (" + VERSION_DATE + ")"
    BANNER = ["SLClient comes with ABSOLUTELY NO WARRANTY"]

    def __init__(self, loglevel='DEBUG'):
        """
        Creates a new instance of SLClient with the specified logging object
        """
        numeric_level = getattr(logging, loglevel.upper(), None)
        if not isinstance(numeric_level, int):
            raise ValueError('Invalid log level: %s' % loglevel)
        logging.basicConfig(level=numeric_level)

        self.slconn = None
        self.verbose = 0
        self.ppackets = False
        self.streamfile = None
        self.selectors = None
        self.multiselect = None
        self.statefile = None
        self.begin_time = None
        self.end_time = None
        self.infolevel = None

        ## for-while
        for line in SLClient.BANNER:
            print line
        self.slconn = SeedLinkConnection()

    def parseCmdLineArgs(self, args):
        """
        Parses the commmand line arguments.

        :type args: list
        :param args: main method arguments.
        :return: -1 on error, 1 if version or help argument found, 0 otherwise.
        """
        if len(args) < 2:
            self.printUsage(False)
            return 1
        optind = 1
        while optind < len(args):
            if args[optind] == "-V":
                print(self.VERSION_INFO, sys.stderr)
                return 1
            elif args[optind] == "-h":
                self.printUsage(False)
                return 1
            elif args[optind].startswith("-v"):
                self.verbose += len(args[optind]) - 1
            elif args[optind] == "-p":
                self.ppackets = True
            elif args[optind] == "-nt":
                optind += 1
                self.slconn.setNetTimout(int(args[optind]))
            elif args[optind] == "-nd":
                optind += 1
                self.slconn.setNetDelay(int(args[optind]))
            elif args[optind] == "-k":
                optind += 1
                self.slconn.setKeepAlive(int(args[optind]))
            elif args[optind] == "-l":
                optind += 1
                self.streamfile = args[optind]
            elif args[optind] == "-s":
                optind += 1
                self.selectors = args[optind]
            elif args[optind] == "-S":
                optind += 1
                self.multiselect = args[optind]
            elif args[optind] == "-x":
                optind += 1
                self.statefile = args[optind]
            elif args[optind] == "-t":
                optind += 1
                self.begin_time = args[optind]
            elif args[optind] == "-e":
                optind += 1
                self.end_time = args[optind]
            elif args[optind] == "-i":
                optind += 1
                self.infolevel = args[optind]
            elif args[optind].startswith("-"):
                print("Unknown option: " + args[optind], sys.stderr)
                return -1
            elif self.slconn.getSLAddress() is None:
                self.slconn.setSLAddress(args[optind])
            else:
                print("Unknown option: " + args[optind], sys.stderr)
                return -1
            optind += 1
        return 0

    def initialize(self):
        """
        Initializes this SLClient.
        """
        if self.slconn.getSLAddress() is None:
            message = "no SeedLink server specified"
            raise SeedLinkException(message)

        if self.verbose >= 2:
            self.ppackets = True
        if self.slconn.getSLAddress().startswith(":"):
            self.slconn.setSLAddress("127.0.0.1" + self.slconn.getSLAddress())
        if self.streamfile is not None:
            self.slconn.readStreamList(self.streamfile, self.selectors)
        if self.multiselect is not None:
            self.slconn.parseStreamlist(self.multiselect, self.selectors)
        else:
            if self.streamfile is None:
                self.slconn.setUniParams(self.selectors, -1, None)
        if self.statefile is not None:
            self.slconn.setStateFile(self.statefile)
        else:
            if self.begin_time is not None:
                self.slconn.setBeginTime(self.begin_time)
            if self.end_time is not None:
                self.slconn.setEndTime(self.end_time)

    def run(self):
        """
        Start this SLClient.
        """
        if self.infolevel is not None:
            self.slconn.requestInfo(self.infolevel)
        # Loop with the connection manager
        count = 1
        slpack = self.slconn.collect()
        while slpack is not None:
            if (slpack == SLPacket.SLTERMINATE):
                break
            try:
                # do something with packet
                terminate = self.packetHandler(count, slpack)
                if terminate:
                    break
            except SeedLinkException as sle:
                print(self.__class__.__name__ + ": " + sle.value)
            if count >= sys.maxint:
                count = 1
                print "DEBUG INFO: " + self.__class__.__name__ + ":",
                print "Packet count reset to 1"
            else:
                count += 1
            slpack = self.slconn.collect()

        # Close the SeedLinkConnection
        self.slconn.close()

    def packetHandler(self, count, slpack):
        """
        Processes each packet received from the SeedLinkConnection.

        This method should be overridden when sub-classing SLClient.

        :type count: int
        :param count:  Packet counter.
        :type slpack: :class:`~obspy.seedlink.SLPacket`
        :param slpack: packet to process.
        :return: Boolean true if connection to SeedLink server should be
            closed and session terminated, false otherwise.
        """
        # check if not a complete packet
        if slpack is None or (slpack == SLPacket.SLNOPACKET) or \
                (slpack == SLPacket.SLERROR):
            return False

        # get basic packet info
        seqnum = slpack.getSequenceNumber()
        type = slpack.getType()

        # process INFO packets here
        if (type == SLPacket.TYPE_SLINF):
            return False
        if (type == SLPacket.TYPE_SLINFT):
            print "Complete INFO:\n" + self.slconn.getInfoString()
            if self.infolevel is not None:
                return True
            else:
                return False

        # can send an in-line INFO request here
        try:
            #if (count % 100 == 0 and not self.slconn.state.expect_info):
            if (count % 100 == 0):
                infostr = "ID"
                self.slconn.requestInfo(infostr)
        except SeedLinkException as sle:
            print(self.__class__.__name__ + ": " + sle.value)

        # if here, must be a data blockette
        print self.__class__.__name__ + ": packet seqnum:",
        print str(seqnum) + ": blockette type: " + str(type)
        if not self.ppackets:
            return False

        # process packet data
        trace = slpack.getTrace()
        if trace is not None:
            print self.__class__.__name__ + ": blockette contains a trace: "
            print trace.id, trace.stats['starttime'],
            print " dt:" + str(1.0 / trace.stats['sampling_rate']),
            print " npts:" + str(trace.stats['npts']),
            print " sampletype:" + str(trace.stats['sampletype']),
            print " dataquality:" + str(trace.stats['dataquality'])
            if self.verbose >= 3:
                print self.__class__.__name__ + ":"
                print "blockette contains a trace: " + str(trace.stats)
        else:
            print self.__class__.__name__ + ": blockette contains no trace"
        return False

    def printUsage(self, concise=True):
        """
        Prints the usage message for this class.
        """
        print("\nUsage: python %s [options] <[host]:port>" % \
              (self.__class__.__name__))
        if concise:
            usage = "Use '-h' for detailed help"
        else:
            usage = USAGE
        print(usage)

    @classmethod
    def main(cls, args):
        """
        Main method - creates and runs an SLClient using the specified
        command line arguments
        """
        slClient = None
        try:
            slClient = SLClient()
            rval = slClient.parseCmdLineArgs(args)
            if (rval != 0):
                sys.exit(rval)
            slClient.initialize()
            slClient.run()
        except Exception as e:
            logger.critical(e)
            traceback.print_exc()
예제 #3
0
class SLClient(object):
    """
    Basic class to create and use a connection to a SeedLink server using a
    SeedLinkConnection object.

    A new SeedLink application can be created by sub-classing SLClient and
    overriding at least the packetHandler method of SLClient.

    :var slconn: SeedLinkConnection object for communicating with the
        SeedLinkConnection over a socket.
    :type slconn: SeedLinkConnection
    :var verbose: Verbosity level, 0 is lowest.
    :type verbose: int
    :var ppackets: Flag to indicate show detailed packet information.
    :type  ppackets: boolean
    :var streamfile: Name of file containing stream list for multi-station
        mode.
    :type  streamfile: str
    :var selectors: Selectors for uni-station or default selectors for
        multi-station.
    :type  selectors: str
    :var multiselect: Selectors for multi-station.
    :type  multiselect: str
    :var statefile: Name of file for reading (if exists) and storing state.
    :type  statefile: str
    :var begin_time: Beginning of time window for read start in past.
    :type  begin_time :str
    :var end_time: End of time window for reading windowed data.
    :type  end_time: str
    :var infolevel: INFO LEVEL for info request only.
    :type  infolevel: str
    """
    VERSION = "1.2.0X00"
    VERSION_YEAR = "2011"
    VERSION_DATE = "24Nov" + VERSION_YEAR
    COPYRIGHT_YEAR = VERSION_YEAR
    PROGRAM_NAME = "SLClient v" + VERSION
    VERSION_INFO = PROGRAM_NAME + " (" + VERSION_DATE + ")"

    def __init__(self, loglevel='DEBUG'):
        """
        Creates a new instance of SLClient with the specified logging object
        """
        numeric_level = getattr(logging, loglevel.upper(), None)
        if not isinstance(numeric_level, int):
            raise ValueError('Invalid log level: %s' % loglevel)
        logging.basicConfig(level=numeric_level)

        self.slconn = None
        self.verbose = 0
        self.ppackets = False
        self.streamfile = None
        self.selectors = None
        self.multiselect = None
        self.statefile = None
        self.begin_time = None
        self.end_time = None
        self.infolevel = None
        self.slconn = SeedLinkConnection()

    def parseCmdLineArgs(self, args):
        """
        Parses the commmand line arguments.

        :type args: list
        :param args: main method arguments.
        :return: -1 on error, 1 if version or help argument found, 0 otherwise.
        """
        if len(args) < 2:
            self.printUsage(False)
            return 1
        optind = 1
        while optind < len(args):
            if args[optind] == "-V":
                print(self.VERSION_INFO, sys.stderr)
                return 1
            elif args[optind] == "-h":
                self.printUsage(False)
                return 1
            elif args[optind].startswith("-v"):
                self.verbose += len(args[optind]) - 1
            elif args[optind] == "-p":
                self.ppackets = True
            elif args[optind] == "-nt":
                optind += 1
                self.slconn.setNetTimout(int(args[optind]))
            elif args[optind] == "-nd":
                optind += 1
                self.slconn.setNetDelay(int(args[optind]))
            elif args[optind] == "-k":
                optind += 1
                self.slconn.setKeepAlive(int(args[optind]))
            elif args[optind] == "-l":
                optind += 1
                self.streamfile = args[optind]
            elif args[optind] == "-s":
                optind += 1
                self.selectors = args[optind]
            elif args[optind] == "-S":
                optind += 1
                self.multiselect = args[optind]
            elif args[optind] == "-x":
                optind += 1
                self.statefile = args[optind]
            elif args[optind] == "-t":
                optind += 1
                self.begin_time = args[optind]
            elif args[optind] == "-e":
                optind += 1
                self.end_time = args[optind]
            elif args[optind] == "-i":
                optind += 1
                self.infolevel = args[optind]
            elif args[optind].startswith("-"):
                print("Unknown option: " + args[optind], sys.stderr)
                return -1
            elif self.slconn.getSLAddress() is None:
                self.slconn.setSLAddress(args[optind])
            else:
                print("Unknown option: " + args[optind], sys.stderr)
                return -1
            optind += 1
        return 0

    def initialize(self):
        """
        Initializes this SLClient.
        """
        if self.slconn.getSLAddress() is None:
            message = "no SeedLink server specified"
            raise SeedLinkException(message)

        if self.verbose >= 2:
            self.ppackets = True
        if self.slconn.getSLAddress().startswith(":"):
            self.slconn.setSLAddress("127.0.0.1" + self.slconn.getSLAddress())
        if self.streamfile is not None:
            self.slconn.readStreamList(self.streamfile, self.selectors)
        if self.multiselect is not None:
            self.slconn.parseStreamlist(self.multiselect, self.selectors)
        else:
            if self.streamfile is None:
                self.slconn.setUniParams(self.selectors, -1, None)
        if self.statefile is not None:
            self.slconn.setStateFile(self.statefile)
        else:
            if self.begin_time is not None:
                self.slconn.setBeginTime(self.begin_time)
            if self.end_time is not None:
                self.slconn.setEndTime(self.end_time)

    def run(self):
        """
        Start this SLClient.
        """
        if self.infolevel is not None:
            self.slconn.requestInfo(self.infolevel)
        # Loop with the connection manager
        count = 1
        slpack = self.slconn.collect()
        while slpack is not None:
            if (slpack == SLPacket.SLTERMINATE):
                break
            try:
                # do something with packet
                terminate = self.packetHandler(count, slpack)
                if terminate:
                    break
            except SeedLinkException as sle:
                print(self.__class__.__name__ + ": " + sle.value)
            if count >= sys.maxint:
                count = 1
                print "DEBUG INFO: " + self.__class__.__name__ + ":",
                print "Packet count reset to 1"
            else:
                count += 1
            slpack = self.slconn.collect()

        # Close the SeedLinkConnection
        self.slconn.close()

    def packetHandler(self, count, slpack):
        """
        Processes each packet received from the SeedLinkConnection.

        This method should be overridden when sub-classing SLClient.

        :type count: int
        :param count:  Packet counter.
        :type slpack: :class:`~obspy.seedlink.SLPacket`
        :param slpack: packet to process.
        :return: Boolean true if connection to SeedLink server should be
            closed and session terminated, false otherwise.
        """
        # check if not a complete packet
        if slpack is None or (slpack == SLPacket.SLNOPACKET) or \
                (slpack == SLPacket.SLERROR):
            return False

        # get basic packet info
        seqnum = slpack.getSequenceNumber()
        type = slpack.getType()

        # process INFO packets here
        if (type == SLPacket.TYPE_SLINF):
            return False
        if (type == SLPacket.TYPE_SLINFT):
            print "Complete INFO:\n" + self.slconn.getInfoString()
            if self.infolevel is not None:
                return True
            else:
                return False

        # can send an in-line INFO request here
        try:
            #if (count % 100 == 0 and not self.slconn.state.expect_info):
            if (count % 100 == 0):
                infostr = "ID"
                self.slconn.requestInfo(infostr)
        except SeedLinkException as sle:
            print(self.__class__.__name__ + ": " + sle.value)

        # if here, must be a data blockette
        print self.__class__.__name__ + ": packet seqnum:",
        print str(seqnum) + ": blockette type: " + str(type)
        if not self.ppackets:
            return False

        # process packet data
        trace = slpack.getTrace()
        if trace is not None:
            print self.__class__.__name__ + ": blockette contains a trace: "
            print trace.id, trace.stats['starttime'],
            print " dt:" + str(1.0 / trace.stats['sampling_rate']),
            print " npts:" + str(trace.stats['npts']),
            print " sampletype:" + str(trace.stats['sampletype']),
            print " dataquality:" + str(trace.stats['dataquality'])
            if self.verbose >= 3:
                print self.__class__.__name__ + ":"
                print "blockette contains a trace: " + str(trace.stats)
        else:
            print self.__class__.__name__ + ": blockette contains no trace"
        return False

    def printUsage(self, concise=True):
        """
        Prints the usage message for this class.
        """
        print("\nUsage: python %s [options] <[host]:port>" %
              (self.__class__.__name__))
        if concise:
            usage = "Use '-h' for detailed help"
        else:
            usage = USAGE
        print(usage)

    @classmethod
    def main(cls, args):
        """
        Main method - creates and runs an SLClient using the specified
        command line arguments
        """
        slClient = None
        try:
            slClient = SLClient()
            rval = slClient.parseCmdLineArgs(args)
            if (rval != 0):
                sys.exit(rval)
            slClient.initialize()
            slClient.run()
        except Exception as e:
            logger.critical(e)
            traceback.print_exc()