Beispiel #1
0
""" PIREP parser! """
import datetime
import os

from twisted.internet import reactor
from twisted.python import log
from pyldm import ldmbridge
from pyiem.nws.products.pirep import parser as pirepparser
import common

TABLESDIR = os.path.join(os.path.dirname(__file__), "../tables")

PIREPS = {}
DBPOOL = common.get_database("postgis")
JABBER = common.make_jabber_client("pirep")
# Load LOCS table
LOCS = {}


def cleandb():
    """To keep LSRDB from growing too big, we clean it out
    Lets hold 1 days of data!
    """
    thres = datetime.datetime.utcnow() - datetime.timedelta(hours=24 * 1)
    init_size = len(PIREPS.keys())
    for key in PIREPS:
        if PIREPS[key] < thres:
            del PIREPS[key]

    fin_size = len(PIREPS.keys())
    log.msg("cleandb() init_size: %s final_size: %s" % (init_size, fin_size))
Beispiel #2
0
        nwsli_dict[row['nwsli']] = nwsli.NWSLI(row['nwsli'], name=nm)

    log.msg("nwsli_dict loaded %s entries" % (len(nwsli_dict),))

    return None


def ready(dummy):
    ''' cb when our database work is done '''
    ldmbridge.LDMProductFactory(MyProductIngestor())


def dbload():
    ''' Load up database stuff '''
    df = PGCONN.runInteraction(load_ugc)
    df.addCallback(ready)

if __name__ == '__main__':

    MANUAL = False
    if len(sys.argv) == 2 and sys.argv[1] == 'manual':
        log.msg("Manual runtime (no jabber, 1 database connection) requested")
        MANUAL = True

    # Fire up!
    PGCONN = common.get_database("postgis", cp_max=(5 if not MANUAL else 1))
    dbload()
    jabber = common.make_jabber_client('generic_parser')

    reactor.run()
Beispiel #3
0
    if data['data'].get('precip_today'):
        val = data['data']['precip_today']
        if val != row['pday']:
            updatesql.append(' pday = %s' % (val,))
            logmsg.append('PDay O:%s N:%s' % (row['pday'], val))

    if data['data'].get('snow_today'):
        val = data['data']['snow_today']
        if row['snow'] is None or val != row['snow']:
            updatesql.append(' snow = %s' % (val,))
            logmsg.append('Snow O:%s N:%s' % (row['snow'], val))

    if len(updatesql) > 0:
        txn.execute("""UPDATE """+table+""" d SET
        """ + ','.join(updatesql) + """
         FROM stations t WHERE t.iemid = d.iemid and d.day = %s and t.id = %s
         and t.network ~* 'ASOS' """, (data['cli_valid'], station))
        log.msg(("%s rows for %s (%s) %s"
                 ) % (txn.rowcount, station,
                      data['cli_valid'].strftime("%y%m%d"), ','.join(logmsg)))

    save_data(txn, prod, station, data)


if __name__ == '__main__':
    # Do Stuff
    jabber = common.make_jabber_client('cli_parser')
    ldmbridge.LDMProductFactory(MyProductIngestor())

    reactor.run()
Beispiel #4
0
                hours=reference.offsets.get(prod.z,0) )).strftime("%-I:%M %p"),
                                      prod.z)

        mess = "%s: %s issues %s for %s %s %s?pid=%s" % (prod.source[1:], 
           prod.source[1:], headline, counties, expire, 
           config.get('urls', 'product'), product_id)
        htmlmess = "%s issues <a href='%s?pid=%s'>%s</a> for %s %s" % ( 
                                prod.source[1:], config.get('urls', 'product'), 
                                product_id, headline, counties, expire)
        
        jabber.sendMessage(mess, htmlmess, xtra)

        twt = "%s for %s %s" % (headline, counties, expire)
        url = "%s?pid=%s" % (config.get('urls', 'product'), product_id)
        common.tweet([prod.source[1:],], twt, url)

jabber = common.make_jabber_client('sps_parser')

def ready(bogus):
    ldmbridge.LDMProductFactory( myProductIngestor() )

def killer(err):
    log.err( err )
    reactor.stop()

df = POSTGIS.runInteraction(load_ugc)
df.addCallback(ready)
df.addErrback( killer )

reactor.run()
Beispiel #5
0
def really_process_data(txn, data):
    ''' We are called with a hard coded AFOS PIL '''
    tp = TextProduct(data)
    if tp.afos is None:
        compute_afos(tp)
    utc = tp.valid
    table = "products_%s_0106" % (utc.year,)
    if utc.month > 6:
        table = "products_%s_0712" % (utc.year,)

    sql = """INSERT into """ + table + """
        (pil, data, source, wmo, entered) values(%s,%s,%s,%s,%s)"""

    sqlargs = (tp.afos, tp.text,
               tp.source, tp.wmo, utc.strftime("%Y-%m-%d %H:%M+00"))
    txn.execute(sql, sqlargs)

    if tp.afos[:3] == 'FRH':
        return
    jmsgs = tp.get_jabbers(
        common.SETTINGS.get('pywwa_product_url', 'pywwa_product_url'))
    for jmsg in jmsgs:
        JABBER.send_message(*jmsg)


if __name__ == '__main__':
    PGCONN = common.get_database("afos", cp_max=1)
    JABBER = common.make_jabber_client('fake_afos_dump')
    ldmbridge.LDMProductFactory(MyProductIngestor())
    reactor.run()
Beispiel #6
0
    """ load ugc"""
    sql = "SELECT name, ugc, wfo from nws_ugc WHERE name IS NOT Null"
    txn.execute(sql)
    for row in txn:
        ugc_dict[ row['ugc'] ] = (row["name"]).replace("\x92"," ").replace("\xc2"," ")
        ugc2wfo[ row['ugc'] ] = re.findall(r'([A-Z][A-Z][A-Z])',row['wfo'])

""" Load up H-VTEC NWSLI reference """
nwsli_dict = {}
def load_nwsli(txn):
    """ load_nwsli"""
    sql = """SELECT nwsli, 
     river_name || ' ' || proximity || ' ' || name || ' ['||state||']' as rname 
     from hvtec_nwsli"""
    txn.execute( sql )
    for row in txn:
        nwsli_dict[ row['nwsli'] ] = (row['rname']).replace("&"," and ")

    return None

def ready(res):
    ldmbridge.LDMProductFactory( MyProductIngestor() )

df = POSTGIS.runInteraction(load_ugc)
df = POSTGIS.runInteraction(load_nwsli)
df.addCallback( ready )
jabber = common.make_jabber_client('vtec_parser')

reactor.run()

Beispiel #7
0
"""SPC Geo Products Parser!"""

from twisted.python import log
from twisted.internet import reactor
from pyldm import ldmbridge
from pyiem.nws.products.spcpts import parser
import common  # @UnresolvedImport

DBPOOL = common.get_database("postgis")
WAITFOR = 20
JABBER = common.make_jabber_client("spc_parser")


# LDM Ingestor
class MyProductIngestor(ldmbridge.LDMProductReceiver):
    """ I receive products from ldmbridge and process them 1 by 1 :) """
    def connectionLost(self, reason):
        """shutdown"""
        log.msg("connectionLost")
        log.err(reason)
        reactor.callLater(5, self.shutdown)  # @UndefinedVariable

    def shutdown(self):
        """shutdown"""
        log.msg("shutdown() is called")
        reactor.callWhenRunning(reactor.stop)  # @UndefinedVariable

    def process_data(self, data):
        """ Process the product """
        df = DBPOOL.runInteraction(real_parser, data)
        df.addErrback(common.email_error, data)
Beispiel #8
0
    tokens = re.findall("ATTN (WFOS|RFCS)(.*)", raw)
    channels = []
    for tpair in tokens:
        for center in re.findall(r"([A-Z]+)\.\.\.", tpair[1]):
            channels.append("SPENES.%s" % (center, ))
    xtra = {"product_id": product_id}
    xtra["channels"] = ",".join(channels)
    xtra["twitter"] = ("NESDIS issues Satellite Precipitation "
                       "Estimates %s?pid=%s") % (PYWWA_PRODUCT_URL, product_id)

    body = ("NESDIS issues Satellite Precipitation Estimates %s?pid=%s") % (
        PYWWA_PRODUCT_URL,
        product_id,
    )
    htmlbody = ("<p>NESDIS issues "
                "<a href='%s?pid=%s'>Satellite Precipitation Estimates</a>"
                "</p>") % (PYWWA_PRODUCT_URL, product_id)
    jabber.send_message(body, htmlbody, xtra)


def killer():
    """Stop Right Now!"""
    reactor.stop()


if __name__ == "__main__":
    jabber = common.make_jabber_client("spe_parser")
    ldmbridge.LDMProductFactory(MyProductIngestor(dedup=True))
    reactor.run()
Beispiel #9
0
    """ % (
        wkt,
        wkt,
    )
    txn.execute(sql)
    cwsus = []
    for row in txn.fetchall():
        cwsus.append(row["id"])
    return cwsus


def real_process(txn, raw):
    """ "
    Actually process a single MCD
    """
    prod = mcdparser(raw)
    prod.cwsus = find_cwsus(txn, prod)

    j = prod.get_jabbers(
        common.SETTINGS.get("pywwa_product_url", "pywwa_product_url"))
    if len(j) == 1:
        JABBER.send_message(j[0][0], j[0][1], j[0][2])

    prod.database_save(txn)


ldmbridge.LDMProductFactory(MyProductIngestor())
JABBER = common.make_jabber_client("mcd_parser")

reactor.run()
Beispiel #10
0
            common.email_error(myexp, buf)
            return
        defer = DBPOOL.runInteraction(prod.sql)
        defer.addCallback(final_step, prod)
        defer.addErrback(common.email_error, buf)


def final_step(_, prod):
    """

    """
    for j in prod.get_jabbers(
            common.settings.get('pywwa_product_url', 'pywwa_product_url'), ''):
        jabber.sendMessage(j[0], j[1], j[2])

MESOSITE = common.get_database('mesosite')


def onready(res):
    log.msg("onready() called...")
    ldmbridge.LDMProductFactory(MyProductIngestor())
    MESOSITE.close()

df = MESOSITE.runInteraction(load_database)
df.addCallback(onready)
df.addErrback(common.email_error, 'ERROR on load_database')
df.addErrback(log.err)

jabber = common.make_jabber_client("aviation")
reactor.run()
Beispiel #11
0
""" PIREP parser! """
import datetime
import os

from twisted.internet import reactor
from twisted.python import log
from pyldm import ldmbridge
from pyiem.nws.products.pirep import parser as pirepparser
import common

TABLESDIR = os.path.join(os.path.dirname(__file__), "../tables")

PIREPS = {}
DBPOOL = common.get_database("postgis")
JABBER = common.make_jabber_client('pirep')
# Load LOCS table
LOCS = {}


def cleandb():
    """ To keep LSRDB from growing too big, we clean it out
        Lets hold 1 days of data!
    """
    thres = datetime.datetime.utcnow() - datetime.timedelta(hours=24*1)
    init_size = len(PIREPS.keys())
    for key in PIREPS:
        if PIREPS[key] < thres:
            del PIREPS[key]

    fin_size = len(PIREPS.keys())
    log.msg("cleandb() init_size: %s final_size: %s" % (init_size, fin_size))
Beispiel #12
0
    prod = lsrparser(text)

    for lsr in prod.lsrs:
        if lsr.typetext.upper() not in reference.lsr_events:
            errmsg = "Unknown LSR typecode '%s'" % (lsr.typetext, )
            common.email_error(errmsg, text)
        uniquekey = hash(lsr.text)
        if uniquekey in LSRDB:
            prod.duplicates += 1
            lsr.duplicate = True
            continue
        LSRDB[uniquekey] = datetime.datetime.utcnow().replace(tzinfo=pytz.utc)
        lsr.sql(txn)

    j = prod.get_jabbers(common.SETTINGS.get("pywwa_lsr_url", "pywwa_lsr_url"))
    for i, (p, h, x) in enumerate(j):
        # delay some to perhaps stop triggering SPAM lock outs at twitter
        reactor.callLater(i, JABBER.send_message, p, h, x)

    if prod.warnings:
        common.email_error("\n\n".join(prod.warnings), text)
    elif not prod.lsrs:
        raise Exception("No LSRs parsed!", text)


reactor.callLater(0, loaddb)
JABBER = common.make_jabber_client("lsr_parser")
LDM = ldmbridge.LDMProductFactory(MyProductIngestor())
reactor.callLater(20, cleandb)
reactor.run()
Beispiel #13
0
                    mess = "%s: %s issues %s #%s for %s %s" % (wfo2, centertext.get(wfo, wfo), what, tnum, tt, myurl)
                    htmlmess = "%s issues <a href=\"%s\">%s #%s</a> for %s" % ( centertext.get(wfo, wfo), myurl, what, tnum, tt)
                #print htmlmess, mess
                jabber.sendMessage(mess, htmlmess, xtra)
                channels.append( wfo2 )
            twt = "%s issues %s %s for %s" % (centertext.get(wfo, wfo), what, tnum, tt)
            common.tweet(channels, twt, myurl)

""" Load up H-VTEC NWSLI reference """
nwsli_dict = {}
def load_nwsli(txn):
    """ Load up NWSLI Dict """
    sql = """SELECT nwsli, river_name as r, 
             proximity || ' ' || name || ' ['||state||']' as rname 
             from hvtec_nwsli"""
    txn.execute(sql)
    for row in txn:
        nwsli_dict[ row['nwsli'] ] = {
                                'rname': (row['r']).replace("&"," and "), 
                                'river': (row['rname']).replace("&"," and ") }

    log.msg("nwsli_dict is loaded...")

POSTGIS.runInteraction(load_nwsli)


jabber = common.make_jabber_client("gp")

ldm = ldmbridge.LDMProductFactory( myProductIngestor() )
reactor.run()
Beispiel #14
0
def ready(_dummy):
    """ cb when our database work is done """
    ldmbridge.LDMProductFactory(MyProductIngestor(dedup=True))


def bootstrap():
    """Things to do at startup"""
    df = PGCONN.runInteraction(load_ugc)
    df.addCallback(ready)
    df.addErrback(common.email_error, "load_ugc failure!")


if __name__ == "__main__":
    SMTPSenderFactory.noisy = False
    ugc_dict = {}
    nwsli_dict = {}

    MANUAL = False
    if len(sys.argv) == 2 and sys.argv[1].lower() == "manual":
        log.msg("Manual runtime (no jabber, 1 database connection) requested")
        MANUAL = True

    # Fire up!
    PGCONN = common.get_database(common.CONFIG["databaserw"]["postgis"],
                                 cp_max=(5 if not MANUAL else 1))
    bootstrap()
    jabber = common.make_jabber_client("vtec_parser")

    reactor.run()
Beispiel #15
0
    log.msg("nwsli_dict loaded %s entries" % (len(nwsli_dict), ))

    return None


def ready(_):
    """ cb when our database work is done """
    ldmbridge.LDMProductFactory(MyProductIngestor())


def dbload():
    """ Load up database stuff """
    df = PGCONN.runInteraction(load_ugc)
    df.addCallback(ready)


if __name__ == "__main__":

    MANUAL = False
    if len(sys.argv) == 2 and sys.argv[1] == "manual":
        log.msg("Manual runtime (no jabber, 1 database connection) requested")
        MANUAL = True

    # Fire up!
    PGCONN = common.get_database("postgis", cp_max=(5 if not MANUAL else 1))
    dbload()
    jabber = common.make_jabber_client("generic_parser")

    reactor.run()
Beispiel #16
0
    '''
    wkt = 'SRID=4326;%s' % (prod.geometry.wkt,)
    sql = """select distinct id from cwsu WHERE
           st_overlaps('%s', geom) or
           st_covers(geom, '%s') ORDER by id ASC""" % (wkt, wkt)
    txn.execute(sql)
    cwsus = []
    for row in txn:
        cwsus.append(row['id'])
    return cwsus


def real_process(txn, raw):
    """"
    Actually process a single MCD
    """
    prod = mcdparser(raw)
    prod.cwsus = find_cwsus(txn, prod)

    j = prod.get_jabbers(common.settings.get('pywwa_product_url',
                                             'pywwa_product_url'))
    if len(j) == 1:
        JABBER.sendMessage(j[0][0], j[0][1], j[0][2])

    prod.database_save(txn)

ldmbridge.LDMProductFactory(MyProductIngestor())
JABBER = common.make_jabber_client('mcd_parser')

reactor.run()
Beispiel #17
0
        myargs = (sqlraw, product_id)
        txn.execute(sql, myargs)

    tokens = re.findall("ATTN (WFOS|RFCS)(.*)", raw)
    channels = []
    for tpair in tokens:
        for center in re.findall("([A-Z]+)\.\.\.", tpair[1]):
            channels.append("SPENES.%s" % (center, ))
    xtra = {'product_id': product_id}
    xtra['channels'] = ','.join(channels)
    xtra['twitter'] = ("NESDIS issues Satellite Precipitation "
                       "Estimates %s?pid=%s") % (PYWWA_PRODUCT_URL,
                                                 product_id)

    body = ("NESDIS issues Satellite Precipitation Estimates %s?pid=%s"
            ) % (PYWWA_PRODUCT_URL, product_id)
    htmlbody = ("<p>NESDIS issues "
                "<a href='%s?pid=%s'>Satellite Precipitation Estimates</a>"
                "</p>"
                ) % (PYWWA_PRODUCT_URL, product_id)
    jabber.sendMessage(body, htmlbody, xtra)


def killer():
    reactor.stop()

if __name__ == '__main__':
    jabber = common.make_jabber_client("spe_parser")
    ldmbridge.LDMProductFactory(MyProductIngestor(dedup=True))
    reactor.run()
Beispiel #18
0
""" SPC Watch Ingestor """

from twisted.python import log
from twisted.internet import reactor
from pyiem.nws.products.saw import parser as sawparser
from pyldm import ldmbridge
import common  # @UnresolvedImport

DBPOOL = common.get_database("postgis", cp_max=1)
IEM_URL = common.SETTINGS.get("pywwa_watch_url", "pywwa_watch_url")
JABBER = common.make_jabber_client("new_watch")


def shutdown():
    """Shut things down, please"""
    reactor.callWhenRunning(reactor.stop)  # @UndefinedVariable


class MyProductIngestor(ldmbridge.LDMProductReceiver):
    """ I receive products from ldmbridge and process them 1 by 1 :) """
    def connectionLost(self, reason):
        """STDIN is shut, so lets shutdown"""
        log.msg("connectionLost")
        log.err(reason)
        reactor.callLater(7, shutdown)  # @UndefinedVariable

    def process_data(self, data):
        """Process the product!"""
        df = DBPOOL.runInteraction(real_process, data)
        df.addErrback(common.email_error, data)
Beispiel #19
0
def real_processor(txn, text):
    """ Lets actually process! """
    prod = lsrparser(text)

    if len(prod.lsrs) == 0:
        raise Exception("No LSRs parsed!", text)

    for lsr in prod.lsrs:
        if lsr.typetext not in reference.lsr_events:
            errmsg = "Unknown LSR typecode '%s'" % (lsr.typetext,)
            common.email_error(errmsg, text)
        uniquekey = hash(lsr.text)
        if uniquekey in LSRDB:
            prod.duplicates += 1
            lsr.duplicate = True
            continue
        LSRDB[uniquekey] = datetime.datetime.utcnow().replace(
            tzinfo=pytz.timezone("UTC"))
        lsr.sql(txn)

    j = prod.get_jabbers(common.settings.get('pywwa_lsr_url', 'pywwa_lsr_url'))
    for (p, h, x) in j:
        JABBER.sendMessage(p, h, x)

reactor.callLater(0, loaddb)
JABBER = common.make_jabber_client("lsr_parser")
LDM = ldmbridge.LDMProductFactory(MyProductIngestor())
reactor.callLater(20, cleandb)
reactor.run()
Beispiel #20
0
        log.msg("Unknown WFO for id: %s, skipping WindAlert" % (iemid,))
        return
    st = row['state']
    nm = row['name']
    network = row['network']

    extra = ""
    if (clean_metar.find("$") > 0):
        extra = "(Caution: Maintenance Check Indicator)"
    url = "http://mesonet.agron.iastate.edu/ASOS/current.phtml?network=%s" % (network,)
    jtxt = "%s: %s,%s (%s) ASOS %s reports gust of %s knots from %s @ %s\n%s"\
            % (wfo, nm, st, iemid, extra, v, drct2dirTxt(d), \
               t.strftime("%H%MZ"), clean_metar )
    jabber.sendMessage(jtxt, jtxt)

    twt = "%s,%s (%s) ASOS reports gust of %s knots from %s @ %s" % (nm, 
     st, iemid, v, drct2dirTxt(d), t.strftime("%H%MZ"))
    common.tweet([wfo], twt, url, {'lat': str(row['lat']), 'long': str(row['lon'])})


def ready(bogus):
    
    ingest = myProductIngestor()
    ldmbridge.LDMProductFactory( ingest )

jabber = common.make_jabber_client("metar_parser")

df = IEMDB.runInteraction(load_stations)
df.addCallback(ready)
reactor.run()
Beispiel #21
0
        ''' Process a chunk of data '''
        df = DBPOOL.runInteraction(real_process, raw)
        df.addErrback(common.email_error, raw)

def real_process(txn, raw):
    """"
    Actually process a single MCD
    """
    prod = mcdparser(raw)
        
    product_id = prod.get_product_id()

    channels = [prod.afos,]
    channels.extend( prod.attn_wfo )
    channels.extend( prod.attn_rfc )
    channels.extend( prod.find_cwsus(txn) )

    body, htmlbody = prod.get_jabbers(common.settings.get('pywwa_product_url', 
                                                      'pywwa_product_url'))
    JABBER.sendMessage(body, htmlbody, {
                        'channels': ",".join( channels ),
                        'product_id': product_id,
                        'twitter': prod.tweet()} )

    prod.database_save(txn)

ldmbridge.LDMProductFactory( MyProductIngestor() )
JABBER = common.make_jabber_client('mcdparse')

reactor.run()
Beispiel #22
0
        # Figure out who should get notification of the watch...
        sql = """SELECT distinct wfo from ugcs WHERE
         ST_Contains('SRID=4326;MULTIPOLYGON(((%s)))', geom)
         and end_ts is null""" % (wkt,)

        txn.execute(sql)
        rs = txn.fetchall()
        channels = ['SPC', ]
        for i in range(len(rs)):
            wfo = rs[i]['wfo']
            channels.append(wfo)
        xtra = {'channels': ','.join(channels)}
        jabber.sendMessage(jabberTxt, jabberTxtHTML, xtra)

        # Special message for SPC
        lines = raw.split("\n")
        twt = lines[5].replace("\r\r", "")
        twt += (" http://www.spc.noaa.gov/products/watch/ww%04i.html"
                ) % (int(ww_num), )
        xtra['channels'] = 'SPC'
        jabber.sendMessage(twt, twt, xtra)

    df = DBPOOL.runInteraction(runner2)
    df.addErrback(common.email_error, raw)

if __name__ == '__main__':
    jabber = common.make_jabber_client("new_watch")

    ldm = ldmbridge.LDMProductFactory(MyProductIngestor())
    reactor.run()
Beispiel #23
0
    """ We are called with a hard coded AFOS PIL """
    tp = TextProduct(data)
    if tp.afos is None:
        compute_afos(tp)

    sql = ("INSERT into products "
           "(pil, data, source, wmo, entered) values(%s,%s,%s,%s,%s)")

    sqlargs = (
        tp.afos,
        tp.text,
        tp.source,
        tp.wmo,
        tp.valid.strftime("%Y-%m-%d %H:%M+00"),
    )
    txn.execute(sql, sqlargs)

    if tp.afos[:3] == "FRH":
        return
    jmsgs = tp.get_jabbers(
        common.SETTINGS.get("pywwa_product_url", "pywwa_product_url"))
    for jmsg in jmsgs:
        JABBER.send_message(*jmsg)


if __name__ == "__main__":
    PGCONN = common.get_database("afos", cp_max=1)
    JABBER = common.make_jabber_client("fake_afos_dump")
    ldmbridge.LDMProductFactory(MyProductIngestor())
    reactor.run()
Beispiel #24
0
"""SPC Geo Products Parser!"""

from twisted.python import log
from twisted.internet import reactor
from pyldm import ldmbridge
from pyiem.nws.products.spcpts import parser
import common  # @UnresolvedImport

DBPOOL = common.get_database('postgis')
WAITFOR = 20
JABBER = common.make_jabber_client('spc_parser')


# LDM Ingestor
class MyProductIngestor(ldmbridge.LDMProductReceiver):
    """ I receive products from ldmbridge and process them 1 by 1 :) """

    def connectionLost(self, reason):
        """shutdown"""
        log.msg('connectionLost')
        log.err(reason)
        reactor.callLater(5, self.shutdown)  # @UndefinedVariable

    def shutdown(self):
        """shutdown"""
        log.msg("shutdown() is called")
        reactor.callWhenRunning(reactor.stop)  # @UndefinedVariable

    def process_data(self, data):
        """ Process the product """
        df = DBPOOL.runInteraction(real_parser, data)