<commit_before>###########################################################################
#          (C) Vrije Universiteit, Amsterdam (the Netherlands)            #
#                                                                         #
# This file is part of AmCAT - The Amsterdam Content Analysis Toolkit     #
#                                                                         #
# AmCAT is free software: you can redistribute it and/or modify it under  #
# the terms of the GNU Affero General Public License as published by the  #
# Free Software Foundation, either version 3 of the License, or (at your  #
# option) any later version.                                              #
#                                                                         #
# AmCAT is distributed in the hope that it will be useful, but WITHOUT    #
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or   #
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public     #
# License for more details.                                               #
#                                                                         #
# You should have received a copy of the GNU Affero General Public        #
# License along with AmCAT.  If not, see <http://www.gnu.org/licenses/>.  #
###########################################################################

from __future__ import unicode_literals, print_function, absolute_import

import inspect, types
from amcat.tools import toolkit, idlabel
from amcat.tools.cachable.property import Property, UnknownTypeException
from amcat.tools.cachable.cachable import Cachable, _ensureTuple, _allowScalar
import logging; log = logging.getLogger(__name__)
from amcat.tools.logging import amcatlogging; amcatlogging.debugModule()
def _dereferenceTargetClass(targetclass):
    if not callable(targetclass):
        raise ValueError("targetclass (%s) should be callable" % (targetclass))
    if not inspect.isclass(targetclass):
        # assume targetklass is lambda or latebind.LB, so dereference
        targetclass = targetclass()
    return targetclass

class DBProperty(Property):
    """Property that retrieves its value from the database"""

    def __init__(self, targetclass=None, table=None, getcolumn=None, refcolumn=None, constructor=None,
                 distinct=False,orderby=False, tablehook=None, **kargs):
        """
        @param targetclass: an optional (tuple of) target class to be used as constructor and for default table and getcolumn
        @param table: which table to query for this property
        @param getcolumn: the column(s) the select to get the value of this property
        @param refcolumn: the column(s) to use in the where clause to filter on the object's id
        @param contstructor: an optional function of (obj, db, value) to return the property value
        @param distinct: if true, select distinct rows
        @param orderby: an optional column to sort on when querying (mainly useful for one-to-many)
        @param tablehook: if given, a function that returns the
        """
        Property.__init__(self, **kargs)
        self.targetclasses = targetclass
        self.table = table
        self.getcolumns = _ensureTuple(getcolumn)
        self.refcolumns = _ensureTuple(refcolumn)
        self.tablehook = tablehook # function obj -> table
        self.constructor = constructor # function(obj, db, values) -> child
        self.distinct = distinct
        self.orderby = orderby

    def _initialise(self, cls, propname):
        if self._initialised: return
        super(DBProperty, self)._initialise(cls, propname)
        if self.targetclasses:
            if type(self.targetclasses) in (list, tuple):
                self.targetclasses = tuple(_dereferenceTargetClass(tc) for tc in self.targetclasses)
            else:
                self.targetclasses = _ensureTuple(_dereferenceTargetClass(self.targetclasses))

    def dbrowToObject(self, obj, *dbvalues):
        """Convert a db row to an amcat object

        @param obj: the "parent object" of the new object
        @param dbvalues: the row tuple as returned from the db
        @return object: a single 'domain' object
        """
        #log.debug("Creating %r.%s object from %r, targetclass=%s, constructor=%s" % (obj, self, dbvalues, self.targetclass, self.constructor))
        if self.constructor:
            return self.constructor(obj, obj.db, *dbvalues)
        elif all(dbvalue is None for dbvalue in dbvalues):
            return None
        elif self.targetclasses:
            result = []
            for tc in self.targetclasses:
                if inspect.isclass(tc) and issubclass(tc, Cachable):
                    numcols = len(tc._getIDColumns())
                else:
                    numcols = 1

                vals, dbvalues = dbvalues[:numcols], dbvalues[numcols:]
                result.append(tc(obj.db, *vals))
            if dbvalues: raise ValueError("Mismatch between targetclasses (%r) ID columns and values, leftover: %r" %
                                          (self.targetclasses, dbvalues))
            return _allowScalar(tuple(result))
        else:
            return dbvalues[0]

    def objectToDbrow(self, obj):
        """Convert an amcat object to a db row

        @param obj: the "parent object" of the new object
        @param object: a single 'domain' object
        @return dbvalues: the row tuple as it was returned from the db
        """
        if isinstance(obj, Cachable):
            return obj._id

        if type(obj) not in (list, tuple): obj = (obj, )
        return obj

    def objectsToData(self, obj, objects):
        #log.debug("Serialising %s=%r" % (self, objects))
        return [self.objectToDbrow(objects)]

    def dataToObjects(self, obj, data):
        data = data[0] if data else [None]
        return self.dbrowToObject(obj, *data)

    def _getIDColumns(self):
        if self.refcolumns: return self.refcolumns
        return self.cls._getIDColumns()

    def _getTable(self, obj=None):
        #log.debug("getTable(%r), self.table=%s, self.tablehook=%s" % (obj, self.table, self.tablehook))
        if self.table: return self.table
        if self.tablehook: return self.tablehook(obj)
        if obj and getattr(obj,'__table__', None):
            return obj.__table__
        return self.cls.__table__

    def _getColumns(self):
        #log.debug("_getColumns, self=%r, getcolumns=%r, targetclasses=%r" % (self,self.getcolumns, self.targetclasses))
        if self.getcolumns: return self.getcolumns
        elif self.targetclasses:
            result =  toolkit.flatten(tc._getIDColumns() for tc in self.targetclasses)
            return result
        else:
            return (self.propname,)

    def retrieve(self, obj):
        """Use the database to retrieve the value of this property for obj
        """
        kargs = dict(orderby=self.orderby) if self.orderby else {}
        return obj.db.select(self._getTable(obj), self._getColumns(), obj._getWhere(self.refcolumns), alwaysReturnTable=True, distinct=self.distinct, **kargs)

    def getType(self, obj_or_db=None):
        # if we have targetclasses, return them/it
        if self.targetclasses:
            if len(self.targetclasses)==1: return self.targetclasses[0]
            return self.targetclasses
        try:
            return super(DBProperty, self).getType(obj_or_db)
        except UnknownTypeException:
            #unknown type, query db if available
            if not obj_or_db: raise
            if isinstance(obj_or_db, Cachable):
                db = obj_or_db.db
            else:
                db = obj_or_db
            self._observedType = db.getColumnType(self.cls.__table__, self.propname)
            return self._observedType

    def _update(self, db, obj, val):
        """Create and execute an SQL UPDATE statement to update the db"""
        #TODO: use serialisation method
        #log.debug("UPDATEing %r.%s -> %r" % (obj, self, val))
        if isinstance(val, idlabel.IDLabel): val = val.id
        cols = self._getColumns()
        vals = self.objectToDbrow(val)
        update = dict(toolkit.zipp(cols, vals))
        log.debug("UPDATEING %r.%s = %r -> cols=%r, vals=%r" % (obj, self, val, cols, vals))
        obj.db.update(self._getTable(obj), update, obj._getWhere(self.refcolumns))
        self.cache(obj, [vals], isData=True)

    def prepareCache(self, cacher):
        if self.tablehook: return # cannot cache as we don't know the table without getting the object!
        #log.info("%s: Adding %s.%s/%s to cacher" % (self, self._getTable(), self._getIDColumn(), self._getColumns()))
        cacher.addField(self._getColumns(), self._getTable(), self._getIDColumns(), self.orderby)

    def doCache(self, cacher, obj=None):
        if self.tablehook: return
        val = cacher.getFieldData(self._getColumns(), self._getTable(), obj, self.cls.__idcolumn__, self.orderby)
        #log.info("%s: Retrieved %s from cacher" % (self, val))
        self.cache(obj, val, isData=True)

    def isNullable(self):
        """Ask database whether this property is nullable"""
        if self._nullable is None:
            table = self._getTable(self.targetclasses)
            column = self._getColumns()
            self._nullable = db.isNullable(table, column)
        return self._nullable

class ForeignKey(DBProperty):
    def __init__(self, targetclass=None, sequencetype=None, constructor=None, includeOwnID=False, **kargs):
        """Create a 'foreign key' property

        Getting the property will create a sequence of domain objects

        @param targetclass: the class of the domain objects, or None for keeping
          the db-primitive intact
        @param sequencetype: the type of sequence to create (list, set, etc), or
          None for returning a generator
        @param includeOwnID: if True, create objects using childid=(ownid,retrieved)
        """
        DBProperty.__init__(self, targetclass, constructor=constructor, **kargs)
        self.sequencetype = sequencetype
        self.includeOwnID = includeOwnID

    def dataToObjects(self, obj, data):
        result = (self.dbrowToObject(obj, *row) for row in data)
        if self.sequencetype: result = self.sequencetype(result)
        return result

    def dbrowToObject(self, obj, *dbvalues):
        child = super(ForeignKey, self).dbrowToObject(obj, *dbvalues)
        # Try to set 'uplink', eg project1.articles[n].project = project1
        uplinkprop = obj.__class__.__name__.lower()
        uplink = getattr(child.__class__, uplinkprop, None)
        if isinstance(uplink, Property):
            uplink.cache(child, obj)

        return child

    def objectsToData(self, obj, objects):
        #log.debug("FKSerialising %s=%r" % (self, objects))
        return [self.objectToDbrow(o) for o in objects]

    def _getTable(self, obj=None):
        #log.debug("getTable(%r), self.table=%s, self.tablehook=%s" % (obj, self.table, self.tablehook))
        if self.table: return self.table
        if self.tablehook: return self.tablehook(obj)
        if self.targetclasses:
            if len(self.targetclasses) != 1:
                raise Exception("Cannot getTable from multiple targetclasses")
            return self.targetclasses[0].__table__
        return self.cls.__table__

    def isNullable(self, db):

        return True

    def getCardinality(self):
        if self.sequencetype is None:
            return types.GeneratorType
        return self.sequencetype

    def _update(self, db, obj, val):
        raise NotImplementedError()

    def addNewChild(self, db, obj, idvalues=None, **props):
        """Add a new child to this ForeignKey relation

        Note that the caller is responsible for maintaining the db transaction
        (i.e. for committing after an update).

        @param db: the database connection to use for updating/inserting
        @obj: the object (parent) to add the child to
        @props: **props to create a new instance (in addition to parent id)
        """
        if type(obj.__idcolumn__) in (list, tuple):
            props.update(dict(zip(obj.__idcolumn__, obj.id)))
        else:
            props[obj.__idcolumn__] = obj.id
        if len(self.targetclasses) > 1: raise Exception("Cannot create child with multiple targetclasses!")
        child = self.targetclasses[0].create(db, idvalues=idvalues, **props)
        #uncache to force retrieval, inefficient but for now easier than updating the cache?
        self.uncache(obj)
        return child

    def removeChild(self, db, obj, child):
        """Delete the child and remove it from this ForeignKey relation

        Note that the caller is responsible for maintaining the db transaction
        (i.e. for committing after an update).

        @param db: the database connection to use for updating/inserting
        @obj: the object (parent) to add the child to
        @child: the child to delete and remove
        """
        child.delete(db)
        #uncache to force retrieval, inefficient but for now easier than updating the cache?
        self.uncache(obj)

<commit_msg>removed debug msg<commit_after>###########################################################################
#          (C) Vrije Universiteit, Amsterdam (the Netherlands)            #
#                                                                         #
# This file is part of AmCAT - The Amsterdam Content Analysis Toolkit     #
#                                                                         #
# AmCAT is free software: you can redistribute it and/or modify it under  #
# the terms of the GNU Affero General Public License as published by the  #
# Free Software Foundation, either version 3 of the License, or (at your  #
# option) any later version.                                              #
#                                                                         #
# AmCAT is distributed in the hope that it will be useful, but WITHOUT    #
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or   #
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public     #
# License for more details.                                               #
#                                                                         #
# You should have received a copy of the GNU Affero General Public        #
# License along with AmCAT.  If not, see <http://www.gnu.org/licenses/>.  #
###########################################################################

from __future__ import unicode_literals, print_function, absolute_import

import inspect, types
from amcat.tools import toolkit, idlabel
from amcat.tools.cachable.property import Property, UnknownTypeException
from amcat.tools.cachable.cachable import Cachable, _ensureTuple, _allowScalar
import logging; log = logging.getLogger(__name__)
#from amcat.tools.logging import amcatlogging; amcatlogging.debugModule()
def _dereferenceTargetClass(targetclass):
    if not callable(targetclass):
        raise ValueError("targetclass (%s) should be callable" % (targetclass))
    if not inspect.isclass(targetclass):
        # assume targetklass is lambda or latebind.LB, so dereference
        targetclass = targetclass()
    return targetclass

class DBProperty(Property):
    """Property that retrieves its value from the database"""

    def __init__(self, targetclass=None, table=None, getcolumn=None, refcolumn=None, constructor=None,
                 distinct=False,orderby=False, tablehook=None, **kargs):
        """
        @param targetclass: an optional (tuple of) target class to be used as constructor and for default table and getcolumn
        @param table: which table to query for this property
        @param getcolumn: the column(s) the select to get the value of this property
        @param refcolumn: the column(s) to use in the where clause to filter on the object's id
        @param contstructor: an optional function of (obj, db, value) to return the property value
        @param distinct: if true, select distinct rows
        @param orderby: an optional column to sort on when querying (mainly useful for one-to-many)
        @param tablehook: if given, a function that returns the
        """
        Property.__init__(self, **kargs)
        self.targetclasses = targetclass
        self.table = table
        self.getcolumns = _ensureTuple(getcolumn)
        self.refcolumns = _ensureTuple(refcolumn)
        self.tablehook = tablehook # function obj -> table
        self.constructor = constructor # function(obj, db, values) -> child
        self.distinct = distinct
        self.orderby = orderby

    def _initialise(self, cls, propname):
        if self._initialised: return
        super(DBProperty, self)._initialise(cls, propname)
        if self.targetclasses:
            if type(self.targetclasses) in (list, tuple):
                self.targetclasses = tuple(_dereferenceTargetClass(tc) for tc in self.targetclasses)
            else:
                self.targetclasses = _ensureTuple(_dereferenceTargetClass(self.targetclasses))

    def dbrowToObject(self, obj, *dbvalues):
        """Convert a db row to an amcat object

        @param obj: the "parent object" of the new object
        @param dbvalues: the row tuple as returned from the db
        @return object: a single 'domain' object
        """
        #log.debug("Creating %r.%s object from %r, targetclass=%s, constructor=%s" % (obj, self, dbvalues, self.targetclass, self.constructor))
        if self.constructor:
            return self.constructor(obj, obj.db, *dbvalues)
        elif all(dbvalue is None for dbvalue in dbvalues):
            return None
        elif self.targetclasses:
            result = []
            for tc in self.targetclasses:
                if inspect.isclass(tc) and issubclass(tc, Cachable):
                    numcols = len(tc._getIDColumns())
                else:
                    numcols = 1

                vals, dbvalues = dbvalues[:numcols], dbvalues[numcols:]
                result.append(tc(obj.db, *vals))
            if dbvalues: raise ValueError("Mismatch between targetclasses (%r) ID columns and values, leftover: %r" %
                                          (self.targetclasses, dbvalues))
            return _allowScalar(tuple(result))
        else:
            return dbvalues[0]

    def objectToDbrow(self, obj):
        """Convert an amcat object to a db row

        @param obj: the "parent object" of the new object
        @param object: a single 'domain' object
        @return dbvalues: the row tuple as it was returned from the db
        """
        if isinstance(obj, Cachable):
            return obj._id

        if type(obj) not in (list, tuple): obj = (obj, )
        return obj

    def objectsToData(self, obj, objects):
        #log.debug("Serialising %s=%r" % (self, objects))
        return [self.objectToDbrow(objects)]

    def dataToObjects(self, obj, data):
        data = data[0] if data else [None]
        return self.dbrowToObject(obj, *data)

    def _getIDColumns(self):
        if self.refcolumns: return self.refcolumns
        return self.cls._getIDColumns()

    def _getTable(self, obj=None):
        #log.debug("getTable(%r), self.table=%s, self.tablehook=%s" % (obj, self.table, self.tablehook))
        if self.table: return self.table
        if self.tablehook: return self.tablehook(obj)
        if obj and getattr(obj,'__table__', None):
            return obj.__table__
        return self.cls.__table__

    def _getColumns(self):
        #log.debug("_getColumns, self=%r, getcolumns=%r, targetclasses=%r" % (self,self.getcolumns, self.targetclasses))
        if self.getcolumns: return self.getcolumns
        elif self.targetclasses:
            result =  toolkit.flatten(tc._getIDColumns() for tc in self.targetclasses)
            return result
        else:
            return (self.propname,)

    def retrieve(self, obj):
        """Use the database to retrieve the value of this property for obj
        """
        kargs = dict(orderby=self.orderby) if self.orderby else {}
        return obj.db.select(self._getTable(obj), self._getColumns(), obj._getWhere(self.refcolumns), alwaysReturnTable=True, distinct=self.distinct, **kargs)

    def getType(self, obj_or_db=None):
        # if we have targetclasses, return them/it
        if self.targetclasses:
            if len(self.targetclasses)==1: return self.targetclasses[0]
            return self.targetclasses
        try:
            return super(DBProperty, self).getType(obj_or_db)
        except UnknownTypeException:
            #unknown type, query db if available
            if not obj_or_db: raise
            if isinstance(obj_or_db, Cachable):
                db = obj_or_db.db
            else:
                db = obj_or_db
            self._observedType = db.getColumnType(self.cls.__table__, self.propname)
            return self._observedType

    def _update(self, db, obj, val):
        """Create and execute an SQL UPDATE statement to update the db"""
        #TODO: use serialisation method
        #log.debug("UPDATEing %r.%s -> %r" % (obj, self, val))
        if isinstance(val, idlabel.IDLabel): val = val.id
        cols = self._getColumns()
        vals = self.objectToDbrow(val)
        update = dict(toolkit.zipp(cols, vals))
        log.debug("UPDATEING %r.%s = %r -> cols=%r, vals=%r" % (obj, self, val, cols, vals))
        obj.db.update(self._getTable(obj), update, obj._getWhere(self.refcolumns))
        self.cache(obj, [vals], isData=True)

    def prepareCache(self, cacher):
        if self.tablehook: return # cannot cache as we don't know the table without getting the object!
        #log.info("%s: Adding %s.%s/%s to cacher" % (self, self._getTable(), self._getIDColumn(), self._getColumns()))
        cacher.addField(self._getColumns(), self._getTable(), self._getIDColumns(), self.orderby)

    def doCache(self, cacher, obj=None):
        if self.tablehook: return
        val = cacher.getFieldData(self._getColumns(), self._getTable(), obj, self.cls.__idcolumn__, self.orderby)
        #log.info("%s: Retrieved %s from cacher" % (self, val))
        self.cache(obj, val, isData=True)

    def isNullable(self):
        """Ask database whether this property is nullable"""
        if self._nullable is None:
            table = self._getTable(self.targetclasses)
            column = self._getColumns()
            self._nullable = db.isNullable(table, column)
        return self._nullable

class ForeignKey(DBProperty):
    def __init__(self, targetclass=None, sequencetype=None, constructor=None, includeOwnID=False, **kargs):
        """Create a 'foreign key' property

        Getting the property will create a sequence of domain objects

        @param targetclass: the class of the domain objects, or None for keeping
          the db-primitive intact
        @param sequencetype: the type of sequence to create (list, set, etc), or
          None for returning a generator
        @param includeOwnID: if True, create objects using childid=(ownid,retrieved)
        """
        DBProperty.__init__(self, targetclass, constructor=constructor, **kargs)
        self.sequencetype = sequencetype
        self.includeOwnID = includeOwnID

    def dataToObjects(self, obj, data):
        result = (self.dbrowToObject(obj, *row) for row in data)
        if self.sequencetype: result = self.sequencetype(result)
        return result

    def dbrowToObject(self, obj, *dbvalues):
        child = super(ForeignKey, self).dbrowToObject(obj, *dbvalues)
        # Try to set 'uplink', eg project1.articles[n].project = project1
        uplinkprop = obj.__class__.__name__.lower()
        uplink = getattr(child.__class__, uplinkprop, None)
        if isinstance(uplink, Property):
            uplink.cache(child, obj)

        return child

    def objectsToData(self, obj, objects):
        #log.debug("FKSerialising %s=%r" % (self, objects))
        return [self.objectToDbrow(o) for o in objects]

    def _getTable(self, obj=None):
        #log.debug("getTable(%r), self.table=%s, self.tablehook=%s" % (obj, self.table, self.tablehook))
        if self.table: return self.table
        if self.tablehook: return self.tablehook(obj)
        if self.targetclasses:
            if len(self.targetclasses) != 1:
                raise Exception("Cannot getTable from multiple targetclasses")
            return self.targetclasses[0].__table__
        return self.cls.__table__

    def isNullable(self, db):

        return True

    def getCardinality(self):
        if self.sequencetype is None:
            return types.GeneratorType
        return self.sequencetype

    def _update(self, db, obj, val):
        raise NotImplementedError()

    def addNewChild(self, db, obj, idvalues=None, **props):
        """Add a new child to this ForeignKey relation

        Note that the caller is responsible for maintaining the db transaction
        (i.e. for committing after an update).

        @param db: the database connection to use for updating/inserting
        @obj: the object (parent) to add the child to
        @props: **props to create a new instance (in addition to parent id)
        """
        if type(obj.__idcolumn__) in (list, tuple):
            props.update(dict(zip(obj.__idcolumn__, obj.id)))
        else:
            props[obj.__idcolumn__] = obj.id
        if len(self.targetclasses) > 1: raise Exception("Cannot create child with multiple targetclasses!")
        child = self.targetclasses[0].create(db, idvalues=idvalues, **props)
        #uncache to force retrieval, inefficient but for now easier than updating the cache?
        self.uncache(obj)
        return child

    def removeChild(self, db, obj, child):
        """Delete the child and remove it from this ForeignKey relation

        Note that the caller is responsible for maintaining the db transaction
        (i.e. for committing after an update).

        @param db: the database connection to use for updating/inserting
        @obj: the object (parent) to add the child to
        @child: the child to delete and remove
        """
        child.delete(db)
        #uncache to force retrieval, inefficient but for now easier than updating the cache?
        self.uncache(obj)

<|endoftext|>


<commit_before>import settings
import time
import functions_general
import functions_db
import functions_help
import defines_global as global_defines
import session_mgr
import ansi
import os
"""
Generic command module. Pretty much every command should go here for
now.
"""
def cmd_idle(cdat):
   """
   Returns nothing, this lets the player set an idle timer without spamming
   his screen.
   """
   pass

def cmd_inventory(cdat):
   """
   Shows a player's inventory.
   """
   session = cdat['session']
   pobject = session.get_pobject()
   session.msg("You are carrying:")

   for item in pobject.get_contents():
      session.msg(" %s" % (item.get_name(),))

   money = int(pobject.get_attribute_value("MONEY", default=0))
   if money == 1:
      money_name = functions_db.get_server_config("MONEY_NAME_SINGULAR")
   else:
      money_name = functions_db.get_server_config("MONEY_NAME_PLURAL")

   session.msg("You have %d %s." % (money,money_name))

def cmd_look(cdat):
   """
   Handle looking at objects.
   """
   session = cdat['session']
   pobject = session.get_pobject()
   args = cdat['uinput']['splitted'][1:]

   if len(args) == 0:
      target_obj = pobject.get_location()
   else:
      results = functions_db.local_and_global_search(pobject, ' '.join(args))

      if len(results) > 1:
         session.msg("More than one match found (please narrow target):")
         for result in results:
            session.msg(" %s" % (result.get_name(),))
         return
      elif len(results) == 0:
         session.msg("I don't see that here.")
         return
      else:
         target_obj = results[0]

   retval = "%s\r\n%s" % (
      target_obj.get_name(),
      target_obj.get_description(),
   )
   session.msg(retval)

   con_players = []
   con_things = []
   con_exits = []

   for obj in target_obj.get_contents():
      if obj.is_player():
         if obj != pobject and obj.is_connected_plr():
            con_players.append(obj)
      elif obj.is_exit():
         con_exits.append(obj)
      else:
         con_things.append(obj)

   if con_players:
      session.msg("%sPlayers:%s" % (ansi.ansi["hilite"], ansi.ansi["normal"],))
      for player in con_players:
         session.msg('%s' %(player.get_name(),))
   if con_things:
      session.msg("%sContents:%s" % (ansi.ansi["hilite"], ansi.ansi["normal"],))
      for thing in con_things:
         session.msg('%s' %(thing.get_name(),))
   if con_exits:
      session.msg("%sExits:%s" % (ansi.ansi["hilite"], ansi.ansi["normal"],))
      for exit in con_exits:
         session.msg('%s' %(exit.get_name(),))

def cmd_get(cdat):
   """
   Get an object and put it in a player's inventory.
   """
   session = cdat['session']
   pobject = session.get_pobject()
   args = cdat['uinput']['splitted'][1:]
   plr_is_staff = pobject.is_staff()

   if len(args) == 0:
      session.msg("Get what?")
      return
   else:
      results = functions_db.local_and_global_search(pobject, ' '.join(args), search_contents=False)

      if len(results) > 1:
         session.msg("More than one match found (please narrow target):")
         for result in results:
            session.msg(" %s" % (result.get_name(),))
         return
      elif len(results) == 0:
         session.msg("I don't see that here.")
         return
      else:
         # We've got a victim to get now.
         target_obj = results[0]

   if pobject == target_obj:
      session.msg("You can't get yourself.")
      return

   if not plr_is_staff and (target_obj.is_player() or target_obj.is_exit()):
      session.msg("You can't get that.")
      return

   if target_obj.is_room() or target_obj.is_garbage() or target_obj.is_going():
      session.msg("You can't get that.")
      return

   target_obj.move_to(pobject, quiet=True)
   session.msg("You pick up %s." % (target_obj.get_name(),))
   pobject.get_location().emit_to_contents("%s picks up %s." % (pobject.get_name(), target_obj.get_name()), exclude=pobject)

def cmd_drop(cdat):
   """
   Drop an object from a player's inventory into their current location.
   """
   session = cdat['session']
   pobject = session.get_pobject()
   args = cdat['uinput']['splitted'][1:]
   plr_is_staff = pobject.is_staff()

   if len(args) == 0:
      session.msg("Drop what?")
      return
   else:
      results = functions_db.local_and_global_search(pobject, ' '.join(args), search_location=False)

      if len(results) > 1:
         session.msg("More than one match found (please narrow target):")
         for result in results:
            session.msg(" %s" % (result.get_name(),))
         return
      elif len(results) == 0:
         session.msg("You don't appear to be carrying that.")
         return
      else:
         # We've got a victim to get now.
         target_obj = results[0]

   if not pobject == target_obj.get_location():
      session.msg("You don't appear to be carrying that.")
      return

   target_obj.move_to(pobject.get_location(), quiet=True)
   session.msg("You drop %s." % (target_obj.get_name(),))
   pobject.get_location().emit_to_contents("%s drops %s." % (pobject.get_name(), target_obj.get_name()), exclude=pobject)

def cmd_examine(cdat):
   """
   Detailed object examine command
   """
   session = cdat['session']
   pobject = session.get_pobject()
   args = cdat['uinput']['splitted'][1:]

   if len(args) == 0:
      target_obj = pobject.get_location()
   else:
      results = functions_db.local_and_global_search(pobject, ' '.join(args))

      if len(results) > 1:
         session.msg("More than one match found (please narrow target):")
         for result in results:
            session.msg(" %s" % (result.get_name(),))
         return
      elif len(results) == 0:
         session.msg("I don't see that here.")
         return
      else:
         target_obj = results[0]
   session.msg("%s\r\n%s" % (
      target_obj.get_name(fullname=True),
      target_obj.get_description(no_parsing=True),
   ))
   session.msg("Type: %s Flags: %s" % (target_obj.get_type(), target_obj.get_flags()))
   session.msg("Owner: %s " % (target_obj.get_owner(),))
   session.msg("Zone: %s" % (target_obj.get_zone(),))

   for attribute in target_obj.get_all_attributes():
      session.msg("%s%s%s: %s" % (ansi.ansi["hilite"], attribute.get_name(), ansi.ansi["normal"], attribute.value))

   con_players = []
   con_things = []
   con_exits = []

   for obj in target_obj.get_contents():
      if obj.is_player():
         con_players.append(obj)
      elif obj.is_exit():
         con_exits.append(obj)
      elif obj.is_thing():
         con_things.append(obj)

   if con_players or con_things:
      session.msg("%sContents:%s" % (ansi.ansi["hilite"], ansi.ansi["normal"],))
      for player in con_players:
         session.msg('%s' % (player.get_name(fullname=True),))
      for thing in con_things:
         session.msg('%s' % (thing.get_name(fullname=True),))

   if con_exits:
      session.msg("%sExits:%s" % (ansi.ansi["hilite"], ansi.ansi["normal"],))
      for exit in con_exits:
         session.msg('%s' %(exit.get_name(fullname=True),))

   if not target_obj.is_room():
      if target_obj.is_exit():
         session.msg("Destination: %s" % (target_obj.get_home(),))
      else:
         session.msg("Home: %s" % (target_obj.get_home(),))

      session.msg("Location: %s" % (target_obj.get_location(),))

def cmd_page(cdat):
   """
   Send a message to target user (if online).
   """
   from apps.objects.models import Object
   session = cdat['session']
   # discard command name
   cdat['uinput']['splitted'].pop(0)
   target_name = cdat['uinput']['splitted'].pop(0)
   message = ' '.join(cdat['uinput']['splitted'])
   try:
      target = Object.objects.get(name__iexact=target_name)
      if target.is_connected_plr():
         target.emit_to("%s pages you with: %s" % (session.get_pobject().get_name(), message))
         session.msg("Page sent.")
      else:
         session.msg("User %s is not logged on." % (target_name.capitalize(),))
   except:
      session.msg("User %s not found." % (target_name,))

def cmd_quit(cdat):
   """
   Gracefully disconnect the user as per his own request.
   """
   session = cdat['session']
   session.msg("Quitting!")
   session.handle_close()

def cmd_who(cdat):
   """
   Generic WHO command.
   """
   session_list = session_mgr.get_session_list()
   session = cdat['session']
   pobject = session.get_pobject()

   retval = "Player Name        On For Idle   Room    Cmds   Host\n\r"
   for player in session_list:
      if not player.logged_in:
         continue
      delta_cmd = time.time() - player.cmd_last
      delta_conn = time.time() - player.conn_time
      plr_pobject = player.get_pobject()

      retval += '%-16s%9s %4s%-3s#%-6d%5d%3s%-25s\r\n' % \
         (plr_pobject.get_name(), \
         # On-time
         functions_general.time_format(delta_conn,0), \
         # Idle time
         functions_general.time_format(delta_cmd,1), \
         # Flags
         '', \
         # Location
         plr_pobject.get_location().id, \
         player.cmd_total, \
         # More flags?
         '', \
         player.address[0])
   retval += '%d Players logged in.' % (len(session_list),)

   session.msg(retval)

def cmd_say(cdat):
   """
   Room-based speech command.
   """
   session = cdat['session']

   if not functions_general.cmd_check_num_args(session, cdat['uinput']['splitted'], 1, errortext="Say what?"):
      return

   session_list = session_mgr.get_session_list()
   pobject = session.get_pobject()
   speech = ' '.join(cdat['uinput']['splitted'][1:])

   players_present = [player for player in session_list if player.get_pobject().get_location() == session.get_pobject().get_location() and player != session]

   retval = "You say, '%s'" % (speech,)
   for player in players_present:
      player.msg("%s says, '%s'" % (pobject.get_name(show_dbref=False), speech,))

   session.msg(retval)

def cmd_pose(cdat):
   """
   Pose/emote command.
   """
   session = cdat['session']

   if not functions_general.cmd_check_num_args(session, cdat['uinput']['splitted'], 1, errortext="Do what?"):
      return

   session_list = session_mgr.get_session_list()
   pobject = session.get_pobject()
   speech = ' '.join(cdat['uinput']['splitted'][1:])

   players_present = [player for player in session_list if player.get_pobject().get_location() == session.get_pobject().get_location()]

   for player in players_present:
      player.msg("%s %s" % (pobject.get_name(show_dbref=False), speech))

def cmd_help(cdat):
   """
   Help system commands.
   """
   session = cdat['session']
   pobject = session.get_pobject()
   topicstr = ' '.join(cdat['uinput']['splitted'][1:])

   if len(topicstr) == 0:
      topicstr = "Help Index"
   elif len(topicstr) < 2 and not topicstr.isdigit():
      session.msg("Your search query is too short. It must be at least three letters long.")
      return

   topics = functions_help.find_topicmatch(pobject, topicstr)

   if len(topics) == 0:
      session.msg("No matching topics found, please refine your search.")
      suggestions = functions_help.find_topicsuggestions(pobject, topicstr)
      if len(suggestions) > 0:
         session.msg("Matching similarly named topics:")
         for result in suggestions:
            session.msg(" %s" % (result,))
            session.msg("You may type 'help <#>' to see any of these topics.")
   elif len(topics) > 1:
      session.msg("More than one match found:")
      for result in topics:
         session.msg("%3d. %s" % (result.id, result.get_topicname()))
      session.msg("You may type 'help <#>' to see any of these topics.")
   else:
      topic = topics[0]
      session.msg("\r\n%s%s%s" % (ansi.ansi["hilite"], topic.get_topicname(), ansi.ansi["normal"]))
      session.msg(topic.get_entrytext_ingame())

def cmd_version(cdat):
   """
   Version info command.
   """
   session = cdat['session']
   retval = "-"*50 +"\n\r"
   retval += "Evennia %s\n\r" % (global_defines.EVENNIA_VERSION,)
   retval += "-"*50
   session.msg(retval)

def cmd_time(cdat):
   """
   Server local time.
   """
   session = cdat['session']
   session.msg('Current server time : %s' % (time.strftime('%a %b %d %H:%M %Y (%Z)', time.localtime(),)))

def cmd_uptime(cdat):
   """
   Server uptime and stats.
   """
   session = cdat['session']
   server = cdat['server']
   start_delta = time.time() - server.start_time
   loadavg = os.getloadavg()
   session.msg('Current server time : %s' % (time.strftime('%a %b %d %H:%M %Y (%Z)', time.localtime(),)))
   session.msg('Server start time   : %s' % (time.strftime('%a %b %d %H:%M %Y', time.localtime(server.start_time),)))
   session.msg('Server uptime       : %s' % functions_general.time_format(start_delta, style=2))
   session.msg('Server load (1 min) : %.2f' % loadavg[0])
<commit_msg>* Re-implemented page using @teleport's protocol.  Still can't get spaces in names working out of the box, but I'm looking into squashing that. (tsal)<commit_after>import settings
import time
import functions_general
import functions_db
import functions_help
import defines_global as global_defines
import session_mgr
import ansi
import os
"""
Generic command module. Pretty much every command should go here for
now.
"""
def cmd_idle(cdat):
   """
   Returns nothing, this lets the player set an idle timer without spamming
   his screen.
   """
   pass

def cmd_inventory(cdat):
   """
   Shows a player's inventory.
   """
   session = cdat['session']
   pobject = session.get_pobject()
   session.msg("You are carrying:")

   for item in pobject.get_contents():
      session.msg(" %s" % (item.get_name(),))

   money = int(pobject.get_attribute_value("MONEY", default=0))
   if money == 1:
      money_name = functions_db.get_server_config("MONEY_NAME_SINGULAR")
   else:
      money_name = functions_db.get_server_config("MONEY_NAME_PLURAL")

   session.msg("You have %d %s." % (money,money_name))

def cmd_look(cdat):
   """
   Handle looking at objects.
   """
   session = cdat['session']
   pobject = session.get_pobject()
   args = cdat['uinput']['splitted'][1:]

   if len(args) == 0:
      target_obj = pobject.get_location()
   else:
      results = functions_db.local_and_global_search(pobject, ' '.join(args))

      if len(results) > 1:
         session.msg("More than one match found (please narrow target):")
         for result in results:
            session.msg(" %s" % (result.get_name(),))
         return
      elif len(results) == 0:
         session.msg("I don't see that here.")
         return
      else:
         target_obj = results[0]

   retval = "%s\r\n%s" % (
      target_obj.get_name(),
      target_obj.get_description(),
   )
   session.msg(retval)

   con_players = []
   con_things = []
   con_exits = []

   for obj in target_obj.get_contents():
      if obj.is_player():
         if obj != pobject and obj.is_connected_plr():
            con_players.append(obj)
      elif obj.is_exit():
         con_exits.append(obj)
      else:
         con_things.append(obj)

   if con_players:
      session.msg("%sPlayers:%s" % (ansi.ansi["hilite"], ansi.ansi["normal"],))
      for player in con_players:
         session.msg('%s' %(player.get_name(),))
   if con_things:
      session.msg("%sContents:%s" % (ansi.ansi["hilite"], ansi.ansi["normal"],))
      for thing in con_things:
         session.msg('%s' %(thing.get_name(),))
   if con_exits:
      session.msg("%sExits:%s" % (ansi.ansi["hilite"], ansi.ansi["normal"],))
      for exit in con_exits:
         session.msg('%s' %(exit.get_name(),))

def cmd_get(cdat):
   """
   Get an object and put it in a player's inventory.
   """
   session = cdat['session']
   pobject = session.get_pobject()
   args = cdat['uinput']['splitted'][1:]
   plr_is_staff = pobject.is_staff()

   if len(args) == 0:
      session.msg("Get what?")
      return
   else:
      results = functions_db.local_and_global_search(pobject, ' '.join(args), search_contents=False)

      if len(results) > 1:
         session.msg("More than one match found (please narrow target):")
         for result in results:
            session.msg(" %s" % (result.get_name(),))
         return
      elif len(results) == 0:
         session.msg("I don't see that here.")
         return
      else:
         # We've got a victim to get now.
         target_obj = results[0]

   if pobject == target_obj:
      session.msg("You can't get yourself.")
      return

   if not plr_is_staff and (target_obj.is_player() or target_obj.is_exit()):
      session.msg("You can't get that.")
      return

   if target_obj.is_room() or target_obj.is_garbage() or target_obj.is_going():
      session.msg("You can't get that.")
      return

   target_obj.move_to(pobject, quiet=True)
   session.msg("You pick up %s." % (target_obj.get_name(),))
   pobject.get_location().emit_to_contents("%s picks up %s." % (pobject.get_name(), target_obj.get_name()), exclude=pobject)

def cmd_drop(cdat):
   """
   Drop an object from a player's inventory into their current location.
   """
   session = cdat['session']
   pobject = session.get_pobject()
   args = cdat['uinput']['splitted'][1:]
   plr_is_staff = pobject.is_staff()

   if len(args) == 0:
      session.msg("Drop what?")
      return
   else:
      results = functions_db.local_and_global_search(pobject, ' '.join(args), search_location=False)

      if len(results) > 1:
         session.msg("More than one match found (please narrow target):")
         for result in results:
            session.msg(" %s" % (result.get_name(),))
         return
      elif len(results) == 0:
         session.msg("You don't appear to be carrying that.")
         return
      else:
         # We've got a victim to get now.
         target_obj = results[0]

   if not pobject == target_obj.get_location():
      session.msg("You don't appear to be carrying that.")
      return

   target_obj.move_to(pobject.get_location(), quiet=True)
   session.msg("You drop %s." % (target_obj.get_name(),))
   pobject.get_location().emit_to_contents("%s drops %s." % (pobject.get_name(), target_obj.get_name()), exclude=pobject)

def cmd_examine(cdat):
   """
   Detailed object examine command
   """
   session = cdat['session']
   pobject = session.get_pobject()
   args = cdat['uinput']['splitted'][1:]

   if len(args) == 0:
      target_obj = pobject.get_location()
   else:
      results = functions_db.local_and_global_search(pobject, ' '.join(args))

      if len(results) > 1:
         session.msg("More than one match found (please narrow target):")
         for result in results:
            session.msg(" %s" % (result.get_name(),))
         return
      elif len(results) == 0:
         session.msg("I don't see that here.")
         return
      else:
         target_obj = results[0]
   session.msg("%s\r\n%s" % (
      target_obj.get_name(fullname=True),
      target_obj.get_description(no_parsing=True),
   ))
   session.msg("Type: %s Flags: %s" % (target_obj.get_type(), target_obj.get_flags()))
   session.msg("Owner: %s " % (target_obj.get_owner(),))
   session.msg("Zone: %s" % (target_obj.get_zone(),))

   for attribute in target_obj.get_all_attributes():
      session.msg("%s%s%s: %s" % (ansi.ansi["hilite"], attribute.get_name(), ansi.ansi["normal"], attribute.value))

   con_players = []
   con_things = []
   con_exits = []

   for obj in target_obj.get_contents():
      if obj.is_player():
         con_players.append(obj)
      elif obj.is_exit():
         con_exits.append(obj)
      elif obj.is_thing():
         con_things.append(obj)

   if con_players or con_things:
      session.msg("%sContents:%s" % (ansi.ansi["hilite"], ansi.ansi["normal"],))
      for player in con_players:
         session.msg('%s' % (player.get_name(fullname=True),))
      for thing in con_things:
         session.msg('%s' % (thing.get_name(fullname=True),))

   if con_exits:
      session.msg("%sExits:%s" % (ansi.ansi["hilite"], ansi.ansi["normal"],))
      for exit in con_exits:
         session.msg('%s' %(exit.get_name(fullname=True),))

   if not target_obj.is_room():
      if target_obj.is_exit():
         session.msg("Destination: %s" % (target_obj.get_home(),))
      else:
         session.msg("Home: %s" % (target_obj.get_home(),))

      session.msg("Location: %s" % (target_obj.get_location(),))

def cmd_page(cdat):
   """
   Send a message to target user (if online).
   """
   try:
      session = cdat['session']
      pobject = session.get_pobject()
      server = cdat['server']
      args = cdat['uinput']['splitted'][1:]

      if len(args) == 0:
         session.msg("Page who/what?")
         return

      eq_args = args[0].split('=')
      if len(eq_args) > 1:
         target = functions_db.local_and_global_search(pobject, eq_args[0])
         message = eq_args[1]

         if len(target) == 0:
            session.msg("I can't find the user %s." % (eq_args[0].capitalize(),))
            return
         elif len(message) == 0:
            session.msg("I need a message to deliver.")
            return
         elif len(target) > 1:
            session.msg("Try a more unique spelling of their name.")
            return
         else:
           if target[0].is_connected_plr():
              target[0].emit_to("%s pages you with: %s" %
                  (pobject.get_name(), message))
              session.msg("Page sent.")
           else:
              session.msg("Player %s does not exist or is not online." %
                  (target[0].name.capitalize(),))
   except:
      from traceback import format_exc
      session.msg("Untrapped error: %s" % (format_exc(),))

def cmd_quit(cdat):
   """
   Gracefully disconnect the user as per his own request.
   """
   session = cdat['session']
   session.msg("Quitting!")
   session.handle_close()

def cmd_who(cdat):
   """
   Generic WHO command.
   """
   session_list = session_mgr.get_session_list()
   session = cdat['session']
   pobject = session.get_pobject()

   retval = "Player Name        On For Idle   Room    Cmds   Host\n\r"
   for player in session_list:
      if not player.logged_in:
         continue
      delta_cmd = time.time() - player.cmd_last
      delta_conn = time.time() - player.conn_time
      plr_pobject = player.get_pobject()

      retval += '%-16s%9s %4s%-3s#%-6d%5d%3s%-25s\r\n' % \
         (plr_pobject.get_name(), \
         # On-time
         functions_general.time_format(delta_conn,0), \
         # Idle time
         functions_general.time_format(delta_cmd,1), \
         # Flags
         '', \
         # Location
         plr_pobject.get_location().id, \
         player.cmd_total, \
         # More flags?
         '', \
         player.address[0])
   retval += '%d Players logged in.' % (len(session_list),)

   session.msg(retval)

def cmd_say(cdat):
   """
   Room-based speech command.
   """
   session = cdat['session']

   if not functions_general.cmd_check_num_args(session, cdat['uinput']['splitted'], 1, errortext="Say what?"):
      return

   session_list = session_mgr.get_session_list()
   pobject = session.get_pobject()
   speech = ' '.join(cdat['uinput']['splitted'][1:])

   players_present = [player for player in session_list if player.get_pobject().get_location() == session.get_pobject().get_location() and player != session]

   retval = "You say, '%s'" % (speech,)
   for player in players_present:
      player.msg("%s says, '%s'" % (pobject.get_name(show_dbref=False), speech,))

   session.msg(retval)

def cmd_pose(cdat):
   """
   Pose/emote command.
   """
   session = cdat['session']

   if not functions_general.cmd_check_num_args(session, cdat['uinput']['splitted'], 1, errortext="Do what?"):
      return

   session_list = session_mgr.get_session_list()
   pobject = session.get_pobject()
   speech = ' '.join(cdat['uinput']['splitted'][1:])

   players_present = [player for player in session_list if player.get_pobject().get_location() == session.get_pobject().get_location()]

   for player in players_present:
      player.msg("%s %s" % (pobject.get_name(show_dbref=False), speech))

def cmd_help(cdat):
   """
   Help system commands.
   """
   session = cdat['session']
   pobject = session.get_pobject()
   topicstr = ' '.join(cdat['uinput']['splitted'][1:])

   if len(topicstr) == 0:
      topicstr = "Help Index"
   elif len(topicstr) < 2 and not topicstr.isdigit():
      session.msg("Your search query is too short. It must be at least three letters long.")
      return

   topics = functions_help.find_topicmatch(pobject, topicstr)

   if len(topics) == 0:
      session.msg("No matching topics found, please refine your search.")
      suggestions = functions_help.find_topicsuggestions(pobject, topicstr)
      if len(suggestions) > 0:
         session.msg("Matching similarly named topics:")
         for result in suggestions:
            session.msg(" %s" % (result,))
            session.msg("You may type 'help <#>' to see any of these topics.")
   elif len(topics) > 1:
      session.msg("More than one match found:")
      for result in topics:
         session.msg("%3d. %s" % (result.id, result.get_topicname()))
      session.msg("You may type 'help <#>' to see any of these topics.")
   else:
      topic = topics[0]
      session.msg("\r\n%s%s%s" % (ansi.ansi["hilite"], topic.get_topicname(), ansi.ansi["normal"]))
      session.msg(topic.get_entrytext_ingame())

def cmd_version(cdat):
   """
   Version info command.
   """
   session = cdat['session']
   retval = "-"*50 +"\n\r"
   retval += "Evennia %s\n\r" % (global_defines.EVENNIA_VERSION,)
   retval += "-"*50
   session.msg(retval)

def cmd_time(cdat):
   """
   Server local time.
   """
   session = cdat['session']
   session.msg('Current server time : %s' % (time.strftime('%a %b %d %H:%M %Y (%Z)', time.localtime(),)))

def cmd_uptime(cdat):
   """
   Server uptime and stats.
   """
   session = cdat['session']
   server = cdat['server']
   start_delta = time.time() - server.start_time
   loadavg = os.getloadavg()
   session.msg('Current server time : %s' % (time.strftime('%a %b %d %H:%M %Y (%Z)', time.localtime(),)))
   session.msg('Server start time   : %s' % (time.strftime('%a %b %d %H:%M %Y', time.localtime(server.start_time),)))
   session.msg('Server uptime       : %s' % functions_general.time_format(start_delta, style=2))
   session.msg('Server load (1 min) : %.2f' % loadavg[0])
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-

"""
I/O routines.

io.py
(c) Will Roberts  23 June, 2017
"""

from __future__ import absolute_import

import codecs
import gzip
import sys
import zipfile
from collections import Counter

from .compat import basestring

try:
    import lzma
except ImportError:
    try:
        import backports.lzma as lzma
    except ImportError:
        pass

def open_file(filename, mode='rb'):
    """
    Open a file for access with the given mode.

    This function transparently wraps gzip and xz files as well as
    normal files.  You can also open zip files using syntax like::

        f = utils.open_file('../semcor-parsed.zip:semcor000.txt')

    :param str filename: The name of the file to open
    :param str mode: The mode to open the file in (defaults to 'rb')
    """
    if (('r' not in mode or hasattr(filename, 'read')) and
        (('a' not in mode and 'w' not in mode) or
         hasattr(filename, 'write')) and hasattr(filename, '__iter__')):
        return filename
    elif isinstance(filename, basestring):
        if filename == '-' and 'r' in mode:
            return sys.stdin
        elif filename == '-' and ('w' in mode or 'a' in mode):
            return sys.stdout
        if filename.lower().count('.zip:'):
            if 'r' not in mode:
                raise ValueError(
                    'zip file syntax only supports reading from files')
            mode = mode.replace('b', '')
            assert filename.count(':') == 1
            zipped_file = zipfile.ZipFile(filename.split(':')[0])
            unzipped_file = zipped_file.open(filename.split(':')[1], 'r')
            zipped_file.close()
            return unzipped_file
        elif filename.lower().endswith('.gz'):
            return gzip.open(filename, mode)
        elif filename.lower().endswith('.xz'):
            tmp = lzma.LZMAFile(filename, mode)
            dir(tmp)
            return tmp
        else:
            return open(filename, mode)
    else:
        raise TypeError('Unknown type for argument filename')

def lines(filename, encoding='utf-8'):
    """
    Open the named file and yield the lines inside it.

    :param str filename: The name of the file to open
    :param str encoding: The encoding of the file (defaults to utf-8)
    """
    with open_file(filename, 'rb') as input_file:
        if encoding is not None:
            stream = codecs.getreader(encoding)(input_file)
        else:
            stream = input_file
        for line in stream:
            yield line

def count_lines(filename):
    """
    Count the number of lines in the given text file.

    :param str filename:
    """
    num_lines = 0
    for _ in lines(filename, encoding=None):
        num_lines += 1
    return num_lines

def load_counter(filename, encoding='utf-8'):
    """
    Load a tab-separated count file into a Counter structure.

    The file contains zero or more lines, which begin with an integer
    count and follow with zero or more tab-separated string value
    fields in UTF-8 encoding.  This function stores these value fields
    in a tuple.

    The counts of repeated value lines will be summed together.

    :param str filename: The name of the file to open
    :param str encoding: The encoding of the file (defaults to utf-8)
    """
    counter = Counter()
    for line in lines(filename, encoding):
        line = line.strip().split('\t')
        cnt = int(line[0])
        value = tuple(line[1:])
        if len(value) == 1:
            counter[value[0]] += cnt
        else:
            counter[value] += cnt
    return counter
<commit_msg>wkr/io.py: fix docstring<commit_after># -*- coding: utf-8 -*-

"""
I/O routines.

io.py
(c) Will Roberts  23 June, 2017
"""

from __future__ import absolute_import

import codecs
import gzip
import sys
import zipfile
from collections import Counter

from .compat import basestring

try:
    import lzma
except ImportError:
    try:
        import backports.lzma as lzma
    except ImportError:
        pass

def open_file(filename, mode='rb'):
    """
    Open a file for access with the given mode.

    This function transparently wraps gzip and xz files as well as
    normal files.  You can also open zip files using syntax like::

        f = wkr.io.open_file('../semcor-parsed.zip:semcor000.txt')

    :param str filename: The name of the file to open
    :param str mode: The mode to open the file in (defaults to 'rb')
    """
    if (('r' not in mode or hasattr(filename, 'read')) and
        (('a' not in mode and 'w' not in mode) or
         hasattr(filename, 'write')) and hasattr(filename, '__iter__')):
        return filename
    elif isinstance(filename, basestring):
        if filename == '-' and 'r' in mode:
            return sys.stdin
        elif filename == '-' and ('w' in mode or 'a' in mode):
            return sys.stdout
        if filename.lower().count('.zip:'):
            if 'r' not in mode:
                raise ValueError(
                    'zip file syntax only supports reading from files')
            mode = mode.replace('b', '')
            assert filename.count(':') == 1
            zipped_file = zipfile.ZipFile(filename.split(':')[0])
            unzipped_file = zipped_file.open(filename.split(':')[1], 'r')
            zipped_file.close()
            return unzipped_file
        elif filename.lower().endswith('.gz'):
            return gzip.open(filename, mode)
        elif filename.lower().endswith('.xz'):
            tmp = lzma.LZMAFile(filename, mode)
            dir(tmp)
            return tmp
        else:
            return open(filename, mode)
    else:
        raise TypeError('Unknown type for argument filename')

def lines(filename, encoding='utf-8'):
    """
    Open the named file and yield the lines inside it.

    :param str filename: The name of the file to open
    :param str encoding: The encoding of the file (defaults to utf-8)
    """
    with open_file(filename, 'rb') as input_file:
        if encoding is not None:
            stream = codecs.getreader(encoding)(input_file)
        else:
            stream = input_file
        for line in stream:
            yield line

def count_lines(filename):
    """
    Count the number of lines in the given text file.

    :param str filename:
    """
    num_lines = 0
    for _ in lines(filename, encoding=None):
        num_lines += 1
    return num_lines

def load_counter(filename, encoding='utf-8'):
    """
    Load a tab-separated count file into a Counter structure.

    The file contains zero or more lines, which begin with an integer
    count and follow with zero or more tab-separated string value
    fields in UTF-8 encoding.  This function stores these value fields
    in a tuple.

    The counts of repeated value lines will be summed together.

    :param str filename: The name of the file to open
    :param str encoding: The encoding of the file (defaults to utf-8)
    """
    counter = Counter()
    for line in lines(filename, encoding):
        line = line.strip().split('\t')
        cnt = int(line[0])
        value = tuple(line[1:])
        if len(value) == 1:
            counter[value[0]] += cnt
        else:
            counter[value] += cnt
    return counter
<|endoftext|>


<commit_before>##############################################################################
# Copyright (c) 2013-2016, Lawrence Livermore National Security, LLC.
# Produced at the Lawrence Livermore National Laboratory.
#
# This file is part of Spack.
# Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
# LLNL-CODE-647188
#
# For details, see https://github.com/llnl/spack
# Please also see the LICENSE file for our notice and the LGPL.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License (as
# published by the Free Software Foundation) version 2.1, February 1999.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
# conditions of the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##############################################################################
from spack import *

class Binutils(AutotoolsPackage):
    """GNU binutils, which contain the linker, assembler, objdump and others"""

    homepage = "http://www.gnu.org/software/binutils/"
    url      = "https://ftp.gnu.org/gnu/binutils/binutils-2.28.tar.bz2"

    version('2.28', '9e8340c96626b469a603c15c9d843727')
    version('2.27', '2869c9bf3e60ee97c74ac2a6bf4e9d68')
    version('2.26', '64146a0faa3b411ba774f47d41de239f')
    version('2.25', 'd9f3303f802a5b6b0bb73a335ab89d66')
    version('2.24', 'e0f71a7b2ddab0f8612336ac81d9636b')
    version('2.23.2', '4f8fa651e35ef262edc01d60fb45702e')
    version('2.20.1', '2b9dc8f2b7dbd5ec5992c6e29de0b764')

    depends_on('m4', type='build')
    depends_on('flex', type='build')
    depends_on('bison', type='build')
    depends_on('gettext')

    # Add a patch that creates binutils libiberty_pic.a which is preferred by
    # OpenSpeedShop and cbtf-krell
    variant('krellpatch', default=False,
            description="build with openspeedshop based patch.")
    variant('plugins', default=False,
            description="enable plugins, needed for gold linker")
    variant('gold', default=True, description="build the gold linker")

    patch('binutilskrell-2.24.patch', when='@2.24+krellpatch')
    patch('cr16.patch')
    patch('update_symbol-2.26.patch', when='@2.26')

    variant('libiberty', default=False, description='Also install libiberty.')

    def configure_args(self):
        spec = self.spec

        configure_args = [
            '--disable-dependency-tracking',
            '--disable-werror',
            '--enable-interwork',
            '--enable-multilib',
            '--enable-shared',
            '--enable-64-bit-bfd',
            '--enable-targets=all',
            '--with-sysroot=/']

        if '+gold' in spec:
            configure_args.append('--enable-gold')

        if '+plugins' in spec:
            configure_args.append('--enable-plugins')

        if '+libiberty' in spec:
            configure_args.append('--enable-install-libiberty')

        return configure_args
<commit_msg>binutils should link to Spack zlib installation (#3914)<commit_after>##############################################################################
# Copyright (c) 2013-2016, Lawrence Livermore National Security, LLC.
# Produced at the Lawrence Livermore National Laboratory.
#
# This file is part of Spack.
# Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
# LLNL-CODE-647188
#
# For details, see https://github.com/llnl/spack
# Please also see the LICENSE file for our notice and the LGPL.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License (as
# published by the Free Software Foundation) version 2.1, February 1999.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
# conditions of the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##############################################################################
from spack import *

class Binutils(AutotoolsPackage):
    """GNU binutils, which contain the linker, assembler, objdump and others"""

    homepage = "http://www.gnu.org/software/binutils/"
    url      = "https://ftp.gnu.org/gnu/binutils/binutils-2.28.tar.bz2"

    version('2.28', '9e8340c96626b469a603c15c9d843727')
    version('2.27', '2869c9bf3e60ee97c74ac2a6bf4e9d68')
    version('2.26', '64146a0faa3b411ba774f47d41de239f')
    version('2.25', 'd9f3303f802a5b6b0bb73a335ab89d66')
    version('2.24', 'e0f71a7b2ddab0f8612336ac81d9636b')
    version('2.23.2', '4f8fa651e35ef262edc01d60fb45702e')
    version('2.20.1', '2b9dc8f2b7dbd5ec5992c6e29de0b764')

    # Add a patch that creates binutils libiberty_pic.a which is preferred by
    # OpenSpeedShop and cbtf-krell
    variant('krellpatch', default=False,
            description="build with openspeedshop based patch.")
    variant('plugins', default=False,
            description="enable plugins, needed for gold linker")
    variant('gold', default=True, description="build the gold linker")
    variant('libiberty', default=False, description='Also install libiberty.')

    patch('binutilskrell-2.24.patch', when='@2.24+krellpatch')
    patch('cr16.patch')
    patch('update_symbol-2.26.patch', when='@2.26')

    depends_on('zlib')

    depends_on('m4', type='build')
    depends_on('flex', type='build')
    depends_on('bison', type='build')
    depends_on('gettext')

    def configure_args(self):
        spec = self.spec

        configure_args = [
            '--with-system-zlib',
            '--disable-dependency-tracking',
            '--disable-werror',
            '--enable-interwork',
            '--enable-multilib',
            '--enable-shared',
            '--enable-64-bit-bfd',
            '--enable-targets=all',
            '--with-sysroot=/',
        ]

        if '+gold' in spec:
            configure_args.append('--enable-gold')

        if '+plugins' in spec:
            configure_args.append('--enable-plugins')

        if '+libiberty' in spec:
            configure_args.append('--enable-install-libiberty')

        return configure_args
<|endoftext|>


<commit_before># Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""AppDynamics Extension

Downloads, installs and configures the AppDynamics agent for PHP
"""
import os
import os.path
import logging

_log = logging.getLogger('appdynamics')

DEFAULTS = {
    'APPDYNAMICS_HOST': 's3-us-west-2.amazonaws.com/niksappd',
    'APPDYNAMICS_VERSION': '4.1.1.0',
    'APPDYNAMICS_PACKAGE': 'appdynamics-php-agent-x64-linux-{APPDYNAMICS_VERSION}.tar.gz',
    'APPDYNAMICS_DOWNLOAD_URL': 'https://{APPDYNAMICS_HOST}/php_agent/'
                             'archive/{APPDYNAMICS_VERSION}/{APPDYNAMICS_PACKAGE}',
}

class AppDynamicsInstaller(object):
    def __init__(self, ctx):
        self._log = _log
        self._ctx = ctx
        self._detected = False
        self.app_name = None
        self.account_access_key = None
        try:
            self._log.info("Initializing")
            if ctx['PHP_VM'] == 'php':
                self._merge_defaults()
                self._load_service_info()
                self._load_php_info()
                self._load_appdynamics_info()
        except Exception:
            self._log.exception("Error installing AppDynamics! "
                                "AppDynamics will not be available.")

    def _merge_defaults(self):
        for key, val in DEFAULTS.iteritems():
            if key not in self._ctx:
                self._ctx[key] = val

    def _load_service_info(self):
        self._log.info("Loading AppDynamics service info.")
        services = self._ctx.get('VCAP_SERVICES', {})
        service_defs = services.get('appdynamics', [])
        if len(service_defs) == 0:
            self._log.info("AppDynamics services with tag appdynamics not detected.")
            self._log.info("Looking for tag app-dynamics service.")
            service_defs = services.get('app-dynamics', [])
            if len(service_defs) == 0:
               self._log.info("AppDynamics services with tag app-dynamics not detected.")
               self._log.info("Looking for Appdynamics user-provided service.")
               service_defs = services.get('user-provided', [])
               if len(service_defs) == 0:
                   self._log.info("AppDynamics services not detected.")
        if len(service_defs) > 1:
            self._log.warn("Multiple AppDynamics services found, "
                           "credentials from first one.")
        if len(service_defs) > 0:
            service = service_defs[0]
            creds = service.get('credentials', {})
            self.account_access_key = creds.get('account-access-key', None)
            if self.account_access_key:
                self._log.debug("AppDynamics service detected.")
                self._detected = True

    def _load_appdynamics_info(self):
        vcap_app = self._ctx.get('VCAP_APPLICATION', {})
        self.app_name = vcap_app.get('name', None)
        self._log.debug("App Name [%s]", self.app_name)

        if 'APPDYNAMICS_LICENSE' in self._ctx.keys():
            if self._detected:
                self._log.warn("Detected a AppDynamics Service & Manual Key,"
                               " using the manual key.")
            self.license_key = self._ctx['APPDYNAMICS_LICENSE']
            self._detected = True

        if self._detected:
            appdynamics_so_name = 'appdynamics-%s%s.so' % (
                self._php_api, (self._php_zts and 'zts' or ''))
            self.appdynamics_so = os.path.join('@{HOME}', 'appdynamics',
                                            'agent', self._php_arch,
                                            appdynamics_so_name)
            self._log.debug("PHP Extension [%s]", self.appdynamics_so)
            self.log_path = os.path.join('@{HOME}', 'logs',
                                         'appdynamics-daemon.log')
            self._log.debug("Log Path [%s]", self.log_path)
            self.daemon_path = os.path.join(
                '@{HOME}', 'appdynamics', 'daemon',
                'appdynamics-daemon.%s' % self._php_arch)
            self._log.debug("Daemon [%s]", self.daemon_path)
            self.socket_path = os.path.join('@{HOME}', 'appdynamics',
                                            'daemon.sock')
            self._log.debug("Socket [%s]", self.socket_path)
            self.pid_path = os.path.join('@{HOME}', 'appdynamics',
                                         'daemon.pid')
            self._log.debug("Pid File [%s]", self.pid_path)

    def _load_php_info(self):
        self.php_ini_path = os.path.join(self._ctx['BUILD_DIR'],
                                         'php', 'etc', 'php.ini')
        self._php_extn_dir = self._find_php_extn_dir()
        self._php_api, self._php_zts = self._parse_php_api()
        self._php_arch = self._ctx.get('APPDYNAMICS_ARCH', 'x64')
        self._log.debug("PHP API [%s] Arch [%s]",
                        self._php_api, self._php_arch)

    def _find_php_extn_dir(self):
        with open(self.php_ini_path, 'rt') as php_ini:
            for line in php_ini.readlines():
                if line.startswith('extension_dir'):
                    (key, val) = line.strip().split(' = ')
                    return val.strip('"')

    def _parse_php_api(self):
        tmp = os.path.basename(self._php_extn_dir)
        php_api = tmp.split('-')[-1]
        php_zts = (tmp.find('non-zts') == -1)
        return php_api, php_zts

    def should_install(self):
        return self._detected

    def modify_php_ini(self):
#        with open(self.php_ini_path, 'rt') as php_ini:
#            lines = php_ini.readlines()
#        extns = [line for line in lines if line.startswith('extension=')]
#        if len(extns) > 0:
#            pos = lines.index(extns[-1]) + 1
#        else:
#            pos = lines.index('#{PHP_EXTENSIONS}\n') + 1
#        lines.insert(pos, 'extension=%s\n' % self.appdynamics_so)
#        lines.append('\n')
#        lines.append('[appdynamics]\n')
#        lines.append('appdynamics.license=%s\n' % self.license_key)
#        lines.append('appdynamics.appname=%s\n' % self.app_name)
#        lines.append('appdynamics.daemon.logfile=%s\n' % self.log_path)
#        lines.append('appdynamics.daemon.location=%s\n' % self.daemon_path)
#        lines.append('appdynamics.daemon.port=%s\n' % self.socket_path)
#        lines.append('appdynamics.daemon.pidfile=%s\n' % self.pid_path)
#        with open(self.php_ini_path, 'wt') as php_ini:
#            for line in lines:
#                php_ini.write(line)
#
#    	exit_code = os.system("echo calling out env; env")
#    	exit_code = os.system("echo ${VCAP_APPLICATION} |  sed -e 's/.*instance_id\":\"//g;s/,\"host.*//g;s/\",.*\"//g'")
#    	exit_code = os.system("echo $HOSTNAME")
#    	exit_code = os.system("ps -auxw; cd /home/vcap; chmod -R 755 ./app; chmod 777 ./app/appdynamics/logs; export APP_HOSTNAME=`echo $VCAP_APPLICATION | sed -e 's/.*instance_id\":\"//g;s/,\"host.*//g;s/\",.*\"//g'`; export APP_TIERNAME=`echo $VCAP_APPLICATION | sed -e 's/.*application_name.:.//g;s/\".*application_uri.*//g' `; PATH=$PATH:./app/php/bin/ ./app/appdynamics/install.sh -s -i ./app/appdynamics/phpini -a=appdynamics@bb6604c1-fbe0-400a-a76b-87c26254fe5e 54.245.245.19 443 ENV['application_name'] $APP_TIERNAME $APP_HOSTNAME ; cat /home/vcap/app/appdynamics/phpini/appdynamics_agent.ini >> /home/vcap/app/php/etc/php.ini")
#    	exit_code = os.system("echo sleep 5; sleep 5; ps -auxw; php -i")
#    	exit_code = os.system("echo adding to phpini; cat /home/vcap/app/appdynamics/phpini/appdynamics_agent.ini >> /home/vcap/app/php/etc/php.ini")
    	exit_code = os.system("echo adding to phpini")

# Extension Methods
def preprocess_commands(ctx):
    exit_code = os.system("echo !!! preprocess_commands")
    #ctx['ADDITIONAL_PREPROCESS_CMDS'] = "export APPDYNAMICS_NODENAME=$(expr \"$VCAP_APPLICATION\" : ''.*instance_index[\": ]*\([[:digit:]]*\).*'') ; echo HI ; echo $APPDYNAMICS_NODENAME"
    #ctx['ADDITIONAL_PREPROCESS_CMDS'] = "echo $VCAP_APPLICATION | sed -e 's/.*instance_id\":\"//g;s/,\"host.*//g;s/\",.*\"//g'"
    #ctx['ADDITIONAL_PREPROCESS_CMDS'] = "echo $VCAP_APPLICATION | sed -e 's/.*instance_id\":\"//g;s/,\"host.*//g;s/\",.*\"//g' && echo Hello"
    #ctx['ADDITIONAL_PREPROCESS_CMDS'] = "chmod -R 755 /home/vcap/app ; chmod 777 ./app/appdynamics/logs; export APP_HOSTNAME=`echo $VCAP_APPLICATION | sed -e 's/.*instance_id\":\"//g;s/,\"host.*//g;s/\",.*\"//g'`; export APP_TIERNAME=`echo $VCAP_APPLICATION | sed -e 's/.*application_name.:.//g;s/\".*application_uri.*//g' `; env; echo print appname; export APP_NAME=$application_name; echo APP_NAME $APP_NAME; echo APP_TIERNAME $APP_TIERNAME; echo APP_HOSTNAME $APP_HOSTNAME; PATH=$PATH:./app/php/bin/ ./app/appdynamics/install.sh -s -i ./app/appdynamics/phpini -a=appdynamics@bb6604c1-fbe0-400a-a76b-87c26254fe5e 54.245.245.19 443 $APP_NAME $APP_TIERNAME $APP_HOSTNAME ; cat /home/vcap/app/appdynamics/phpini/appdynamics_agent.ini >> /home/vcap/app/php/etc/php.ini"
    #ctx['ADDITIONAL_PREPROCESS_CMDS'] = "chmod -R 755 /home/vcap/app ; chmod 777 ./app/appdynamics/logs; export APP_HOSTNAME=`echo $VCAP_APPLICATION | sed -e 's/.*instance_id\":\"//g;s/,\"host.*//g;s/\",.*\"//g'`; export APP_TIERNAME=`echo $VCAP_APPLICATION | sed -e 's/.*application_name.:.//g;s/\".*application_uri.*//g' `; env; echo print appname; export APP_NAME=$application_name; echo APP_NAME $APP_NAME; echo APP_TIERNAME $APP_TIERNAME; echo APP_HOSTNAME $APP_HOSTNAME; PATH=$PATH:./app/php/bin/ ./app/appdynamics/install.sh -i ./app/appdynamics/phpini -a=appdynamics@bb6604c1-fbe0-400a-a76b-87c26254fe5e 54.245.245.19 443 $APP_NAME $APP_TIERNAME $APP_HOSTNAME ; cat /home/vcap/app/appdynamics/phpini/appdynamics_agent.ini >> /home/vcap/app/php/etc/php.ini; echo \"agent.proxy_output = /home/vcap/app/appdynamics/proxy.out\" >> /home/vcap/app/php/etc/php.ini"
    ctx['ADDITIONAL_PREPROCESS_CMDS'] = "chmod -R 755 /home/vcap/app ; chmod 777 ./app/appdynamics/logs; export APP_HOSTNAME=`echo $VCAP_APPLICATION | sed -e 's/.*instance_id\":\"//g;s/,\"host.*//g;s/\",.*\"//g'`; export APP_TIERNAME=`echo $VCAP_APPLICATION | sed -e 's/.*application_name.:.//g;s/\".*application_uri.*//g' `; env; echo print appname; export APP_NAME=$application_name; echo APP_NAME $APP_NAME; echo APP_TIERNAME $APP_TIERNAME; echo APP_HOSTNAME $APP_HOSTNAME; pwd ; ls -al ; PATH=$PATH:./app/php/bin/ ./app/appdynamics/install.sh -s -i ./app/appdynamics/phpini -a=appdynamics@bb6604c1-fbe0-400a-a76b-87c26254fe5e 54.245.245.19 443 $APP_NAME $APP_TIERNAME $APP_HOSTNAME ; cat /home/vcap/app/appdynamics/phpini/appdynamics_agent.ini >> /home/vcap/app/php/etc/php.ini"

    return ()

def service_commands(ctx):
    return {}

def service_environment(ctx):
    return {}

def compile(install):
    exit_code = os.system("echo !!!! compile ")
    appdynamics = AppDynamicsInstaller(install.builder._ctx)
    if appdynamics.should_install():
        _log.info("Installing AppDynamics")
        install.package('APPDYNAMICS')
        _log.info("Configuring AppDynamics in php.ini")
        appdynamics.modify_php_ini()
        _log.info("AppDynamics Installed.")
    return 0
<commit_msg>hostname<commit_after># Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""AppDynamics Extension

Downloads, installs and configures the AppDynamics agent for PHP
"""
import os
import os.path
import logging

_log = logging.getLogger('appdynamics')

DEFAULTS = {
    'APPDYNAMICS_HOST': 's3-us-west-2.amazonaws.com/niksappd',
    'APPDYNAMICS_VERSION': '4.1.1.0',
    'APPDYNAMICS_PACKAGE': 'appdynamics-php-agent-x64-linux-{APPDYNAMICS_VERSION}.tar.gz',
    'APPDYNAMICS_DOWNLOAD_URL': 'https://{APPDYNAMICS_HOST}/php_agent/'
                             'archive/{APPDYNAMICS_VERSION}/{APPDYNAMICS_PACKAGE}',
}

class AppDynamicsInstaller(object):
    def __init__(self, ctx):
        self._log = _log
        self._ctx = ctx
        self._detected = False
        self.app_name = None
        self.account_access_key = None
        try:
            self._log.info("Initializing")
            if ctx['PHP_VM'] == 'php':
                self._merge_defaults()
                self._load_service_info()
                self._load_php_info()
                self._load_appdynamics_info()
        except Exception:
            self._log.exception("Error installing AppDynamics! "
                                "AppDynamics will not be available.")

    def _merge_defaults(self):
        for key, val in DEFAULTS.iteritems():
            if key not in self._ctx:
                self._ctx[key] = val

    def _load_service_info(self):
        self._log.info("Loading AppDynamics service info.")
        services = self._ctx.get('VCAP_SERVICES', {})
        service_defs = services.get('appdynamics', [])
        if len(service_defs) == 0:
            self._log.info("AppDynamics services with tag appdynamics not detected.")
            self._log.info("Looking for tag app-dynamics service.")
            service_defs = services.get('app-dynamics', [])
            if len(service_defs) == 0:
               self._log.info("AppDynamics services with tag app-dynamics not detected.")
               self._log.info("Looking for Appdynamics user-provided service.")
               service_defs = services.get('user-provided', [])
               if len(service_defs) == 0:
                   self._log.info("AppDynamics services not detected.")
        if len(service_defs) > 1:
            self._log.warn("Multiple AppDynamics services found, "
                           "credentials from first one.")
        if len(service_defs) > 0:
            service = service_defs[0]
            creds = service.get('credentials', {})
            self.account_access_key = creds.get('account-access-key', None)
            if self.account_access_key:
                self._log.debug("AppDynamics service detected.")
                self._detected = True

    def _load_appdynamics_info(self):
        vcap_app = self._ctx.get('VCAP_APPLICATION', {})
        self.app_name = vcap_app.get('name', None)
        self._log.debug("App Name [%s]", self.app_name)

        if 'APPDYNAMICS_LICENSE' in self._ctx.keys():
            if self._detected:
                self._log.warn("Detected a AppDynamics Service & Manual Key,"
                               " using the manual key.")
            self.license_key = self._ctx['APPDYNAMICS_LICENSE']
            self._detected = True

        if self._detected:
            appdynamics_so_name = 'appdynamics-%s%s.so' % (
                self._php_api, (self._php_zts and 'zts' or ''))
            self.appdynamics_so = os.path.join('@{HOME}', 'appdynamics',
                                            'agent', self._php_arch,
                                            appdynamics_so_name)
            self._log.debug("PHP Extension [%s]", self.appdynamics_so)
            self.log_path = os.path.join('@{HOME}', 'logs',
                                         'appdynamics-daemon.log')
            self._log.debug("Log Path [%s]", self.log_path)
            self.daemon_path = os.path.join(
                '@{HOME}', 'appdynamics', 'daemon',
                'appdynamics-daemon.%s' % self._php_arch)
            self._log.debug("Daemon [%s]", self.daemon_path)
            self.socket_path = os.path.join('@{HOME}', 'appdynamics',
                                            'daemon.sock')
            self._log.debug("Socket [%s]", self.socket_path)
            self.pid_path = os.path.join('@{HOME}', 'appdynamics',
                                         'daemon.pid')
            self._log.debug("Pid File [%s]", self.pid_path)

    def _load_php_info(self):
        self.php_ini_path = os.path.join(self._ctx['BUILD_DIR'],
                                         'php', 'etc', 'php.ini')
        self._php_extn_dir = self._find_php_extn_dir()
        self._php_api, self._php_zts = self._parse_php_api()
        self._php_arch = self._ctx.get('APPDYNAMICS_ARCH', 'x64')
        self._log.debug("PHP API [%s] Arch [%s]",
                        self._php_api, self._php_arch)

    def _find_php_extn_dir(self):
        with open(self.php_ini_path, 'rt') as php_ini:
            for line in php_ini.readlines():
                if line.startswith('extension_dir'):
                    (key, val) = line.strip().split(' = ')
                    return val.strip('"')

    def _parse_php_api(self):
        tmp = os.path.basename(self._php_extn_dir)
        php_api = tmp.split('-')[-1]
        php_zts = (tmp.find('non-zts') == -1)
        return php_api, php_zts

    def should_install(self):
        return self._detected

    def modify_php_ini(self):
#        with open(self.php_ini_path, 'rt') as php_ini:
#            lines = php_ini.readlines()
#        extns = [line for line in lines if line.startswith('extension=')]
#        if len(extns) > 0:
#            pos = lines.index(extns[-1]) + 1
#        else:
#            pos = lines.index('#{PHP_EXTENSIONS}\n') + 1
#        lines.insert(pos, 'extension=%s\n' % self.appdynamics_so)
#        lines.append('\n')
#        lines.append('[appdynamics]\n')
#        lines.append('appdynamics.license=%s\n' % self.license_key)
#        lines.append('appdynamics.appname=%s\n' % self.app_name)
#        lines.append('appdynamics.daemon.logfile=%s\n' % self.log_path)
#        lines.append('appdynamics.daemon.location=%s\n' % self.daemon_path)
#        lines.append('appdynamics.daemon.port=%s\n' % self.socket_path)
#        lines.append('appdynamics.daemon.pidfile=%s\n' % self.pid_path)
#        with open(self.php_ini_path, 'wt') as php_ini:
#            for line in lines:
#                php_ini.write(line)
#
#    	exit_code = os.system("echo calling out env; env")
#    	exit_code = os.system("echo ${VCAP_APPLICATION} |  sed -e 's/.*instance_id\":\"//g;s/,\"host.*//g;s/\",.*\"//g'")
#    	exit_code = os.system("echo $HOSTNAME")
#    	exit_code = os.system("ps -auxw; cd /home/vcap; chmod -R 755 ./app; chmod 777 ./app/appdynamics/logs; export APP_HOSTNAME=`echo $VCAP_APPLICATION | sed -e 's/.*instance_id\":\"//g;s/,\"host.*//g;s/\",.*\"//g'`; export APP_TIERNAME=`echo $VCAP_APPLICATION | sed -e 's/.*application_name.:.//g;s/\".*application_uri.*//g' `; PATH=$PATH:./app/php/bin/ ./app/appdynamics/install.sh -s -i ./app/appdynamics/phpini -a=appdynamics@bb6604c1-fbe0-400a-a76b-87c26254fe5e 54.245.245.19 443 ENV['application_name'] $APP_TIERNAME $APP_HOSTNAME ; cat /home/vcap/app/appdynamics/phpini/appdynamics_agent.ini >> /home/vcap/app/php/etc/php.ini")
#    	exit_code = os.system("echo sleep 5; sleep 5; ps -auxw; php -i")
#    	exit_code = os.system("echo adding to phpini; cat /home/vcap/app/appdynamics/phpini/appdynamics_agent.ini >> /home/vcap/app/php/etc/php.ini")
    	exit_code = os.system("echo adding to phpini")

# Extension Methods
def preprocess_commands(ctx):
    exit_code = os.system("echo !!! preprocess_commands")
    #ctx['ADDITIONAL_PREPROCESS_CMDS'] = "export APPDYNAMICS_NODENAME=$(expr \"$VCAP_APPLICATION\" : ''.*instance_index[\": ]*\([[:digit:]]*\).*'') ; echo HI ; echo $APPDYNAMICS_NODENAME"
    #ctx['ADDITIONAL_PREPROCESS_CMDS'] = "echo $VCAP_APPLICATION | sed -e 's/.*instance_id\":\"//g;s/,\"host.*//g;s/\",.*\"//g'"
    #ctx['ADDITIONAL_PREPROCESS_CMDS'] = "echo $VCAP_APPLICATION | sed -e 's/.*instance_id\":\"//g;s/,\"host.*//g;s/\",.*\"//g' && echo Hello"
    #ctx['ADDITIONAL_PREPROCESS_CMDS'] = "chmod -R 755 /home/vcap/app ; chmod 777 ./app/appdynamics/logs; export APP_HOSTNAME=`echo $VCAP_APPLICATION | sed -e 's/.*instance_id\":\"//g;s/,\"host.*//g;s/\",.*\"//g'`; export APP_TIERNAME=`echo $VCAP_APPLICATION | sed -e 's/.*application_name.:.//g;s/\".*application_uri.*//g' `; env; echo print appname; export APP_NAME=$application_name; echo APP_NAME $APP_NAME; echo APP_TIERNAME $APP_TIERNAME; echo APP_HOSTNAME $APP_HOSTNAME; PATH=$PATH:./app/php/bin/ ./app/appdynamics/install.sh -s -i ./app/appdynamics/phpini -a=appdynamics@bb6604c1-fbe0-400a-a76b-87c26254fe5e 54.245.245.19 443 $APP_NAME $APP_TIERNAME $APP_HOSTNAME ; cat /home/vcap/app/appdynamics/phpini/appdynamics_agent.ini >> /home/vcap/app/php/etc/php.ini"
    #ctx['ADDITIONAL_PREPROCESS_CMDS'] = "chmod -R 755 /home/vcap/app ; chmod 777 ./app/appdynamics/logs; export APP_HOSTNAME=`echo $VCAP_APPLICATION | sed -e 's/.*instance_id\":\"//g;s/,\"host.*//g;s/\",.*\"//g'`; export APP_TIERNAME=`echo $VCAP_APPLICATION | sed -e 's/.*application_name.:.//g;s/\".*application_uri.*//g' `; env; echo print appname; export APP_NAME=$application_name; echo APP_NAME $APP_NAME; echo APP_TIERNAME $APP_TIERNAME; echo APP_HOSTNAME $APP_HOSTNAME; PATH=$PATH:./app/php/bin/ ./app/appdynamics/install.sh -i ./app/appdynamics/phpini -a=appdynamics@bb6604c1-fbe0-400a-a76b-87c26254fe5e 54.245.245.19 443 $APP_NAME $APP_TIERNAME $APP_HOSTNAME ; cat /home/vcap/app/appdynamics/phpini/appdynamics_agent.ini >> /home/vcap/app/php/etc/php.ini; echo \"agent.proxy_output = /home/vcap/app/appdynamics/proxy.out\" >> /home/vcap/app/php/etc/php.ini"
    ctx['ADDITIONAL_PREPROCESS_CMDS'] = "chmod -R 755 /home/vcap/app ; chmod 777 ./app/appdynamics/logs; export APP_HOSTNAME=`echo $VCAP_APPLICATION | sed -e 's/.*instance_id\":\"//g;s/,\"host.*//g;s/\",.*\"//g'`; export APP_TIERNAME=`echo $VCAP_APPLICATION | sed -e 's/.*application_name.:.//g;s/\".*application_uri.*//g' `; env; echo print appname; export APP_NAME=$application_name; echo APP_NAME $APP_NAME; echo APP_TIERNAME $APP_TIERNAME; echo APP_HOSTNAME $APP_HOSTNAME; export AD_CONTROLLER=`echo $VCAP_SERVICES | sed -e 's/.*host_name.:.//g;s/\".*ssl-enabled.*//g' ` ; echo $AD_CONTROLLER; PATH=$PATH:./app/php/bin/ ./app/appdynamics/install.sh -s -i ./app/appdynamics/phpini -a=appdynamics@bb6604c1-fbe0-400a-a76b-87c26254fe5e 54.245.245.19 443 $APP_NAME $APP_TIERNAME $APP_HOSTNAME ; cat /home/vcap/app/appdynamics/phpini/appdynamics_agent.ini >> /home/vcap/app/php/etc/php.ini"

    return ()

def service_commands(ctx):
    return {}

def service_environment(ctx):
    return {}

def compile(install):
    exit_code = os.system("echo !!!! compile ")
    appdynamics = AppDynamicsInstaller(install.builder._ctx)
    if appdynamics.should_install():
        _log.info("Installing AppDynamics")
        install.package('APPDYNAMICS')
        _log.info("Configuring AppDynamics in php.ini")
        appdynamics.modify_php_ini()
        _log.info("AppDynamics Installed.")
    return 0
<|endoftext|>


<commit_before>#!/usr/bin/env python
# -*- encoding: utf-8 -*-
'''Tag task transformers'''

import numpy as np
from sklearn.preprocessing import MultiLabelBinarizer

import jams

from .base import BaseTaskTransformer

__all__ = ['DynamicLabelTransformer', 'StaticLabelTransformer']

class DynamicLabelTransformer(BaseTaskTransformer):

    def __init__(self, namespace, name, labels=None, sr=22050, hop_length=512):
        '''Initialize a time-series label transformer

        Parameters
        ----------
        jam : jams.JAMS
            The JAMS object container

        n_samples : int > 0
            The number of samples in the audio frame

        label_encoder : sklearn.preprocessing.MultiLabelBinarizer
            The (pre-constructed) label encoder
        '''

        super(DynamicLabelTransformer, self).__init__(name=name,
                                                      namespace=namespace,
                                                      sr=sr,
                                                      hop_length=hop_length)

        if labels is None:
            labels = jams.schema.values(namespace)

        self.encoder = MultiLabelBinarizer()
        self.encoder.fit([labels])
        self._classes = set(self.encoder.classes_)

        self.register('tags', [None, len(self._classes)], np.bool)

    def empty(self, duration):
        ann = super(DynamicLabelTransformer, self).empty(duration)
        ann.append(time=0, duration=duration, value=None)
        return ann

    def transform_annotation(self, ann, duration):

        intervals, values = ann.data.to_interval_values()

        # Suppress all intervals not in the encoder
        tags = []
        for v in values:
            if v in self._classes:
                tags.extend(self.encoder.transform([[v]]))
            else:
                tags.extend(self.encoder.transform([[]]))

        tags = np.asarray(tags)
        target = self.encode_intervals(duration, intervals, tags)

        return {'tags': target}

class StaticLabelTransformer(BaseTaskTransformer):

    def __init__(self, namespace, name, labels=None):
        '''Initialize a global label transformer

        Parameters
        ----------
        jam : jams.JAMS
            The JAMS object container
        '''

        super(StaticLabelTransformer, self).__init__(name=name,
                                                     namespace=namespace,
                                                     sr=1, hop_length=1)

        if labels is None:
            labels = jams.schema.values(namespace)

        self.encoder = MultiLabelBinarizer()
        self.encoder.fit([labels])
        self._classes = set(self.encoder.classes_)
        self.register('tags', [len(self._classes)], np.bool)

    def transform_annotation(self, ann, duration):

        intervals = np.asarray([[0, 1]])
        values = list(ann.data.value)
        intervals = np.tile(intervals, [len(values), 1])

        # Suppress all intervals not in the encoder
        tags = [v for v in values if v in self._classes]
        if len(tags):
            target = self.encoder.transform([tags]).astype(np.bool).max(axis=0)
        else:
            target = np.zeros(len(self._classes), dtype=np.bool)

        return {'tags': target}
<commit_msg>docstringed tag transformers<commit_after>#!/usr/bin/env python
# -*- encoding: utf-8 -*-
'''Tag task transformers'''

import numpy as np
from sklearn.preprocessing import MultiLabelBinarizer

import jams

from .base import BaseTaskTransformer

__all__ = ['DynamicLabelTransformer', 'StaticLabelTransformer']

class DynamicLabelTransformer(BaseTaskTransformer):
    '''Time-series label transformer.

    Attributes
    ----------
    namespace : str
        The JAMS namespace for this task

    name : str
        The name of this transformer object

    labels : list of str [optional]
        The list of labels for this task.

        If not provided, it will attempt to infer the label set from the
        namespace definition.

    sr : number > 0
        The audio sampling rate

    hop_length : int > 0
        The hop length for annotation frames

    See Also
    --------
    StaticLabelTransformer
    '''
    def __init__(self, namespace, name, labels=None, sr=22050, hop_length=512):
        super(DynamicLabelTransformer, self).__init__(name=name,
                                                      namespace=namespace,
                                                      sr=sr,
                                                      hop_length=hop_length)

        if labels is None:
            labels = jams.schema.values(namespace)

        self.encoder = MultiLabelBinarizer()
        self.encoder.fit([labels])
        self._classes = set(self.encoder.classes_)

        self.register('tags', [None, len(self._classes)], np.bool)

    def empty(self, duration):
        '''Empty label annotations.

        Constructs a single observation with an empty value (None).

        Parameters
        ----------
        duration : number > 0
            The duration of the annotation
        '''
        ann = super(DynamicLabelTransformer, self).empty(duration)
        ann.append(time=0, duration=duration, value=None)
        return ann

    def transform_annotation(self, ann, duration):
        '''Transform an annotation to dynamic label encoding.

        Parameters
        ----------
        ann : jams.Annotation
            The annotation to convert

        duration : number > 0
            The duration of the track

        Returns
        -------
        data : dict
            data['tags'] : np.ndarray, shape=(n, n_labels)
                A time-varying binary encoding of the labels
        '''
        intervals, values = ann.data.to_interval_values()

        # Suppress all intervals not in the encoder
        tags = []
        for v in values:
            if v in self._classes:
                tags.extend(self.encoder.transform([[v]]))
            else:
                tags.extend(self.encoder.transform([[]]))

        tags = np.asarray(tags)
        target = self.encode_intervals(duration, intervals, tags)

        return {'tags': target}

class StaticLabelTransformer(BaseTaskTransformer):
    '''Static label transformer.

    Attributes
    ----------
    namespace : str
        The JAMS namespace for this task

    name : str
        The name of this transformer object

    labels : list of str [optional]
        The list of labels for this task.

        If not provided, it will attempt to infer the label set from the
        namespace definition.

    See Also
    --------
    DynamicLabelTransformer
    '''

    def __init__(self, namespace, name, labels=None):
        super(StaticLabelTransformer, self).__init__(name=name,
                                                     namespace=namespace,
                                                     sr=1, hop_length=1)

        if labels is None:
            labels = jams.schema.values(namespace)

        self.encoder = MultiLabelBinarizer()
        self.encoder.fit([labels])
        self._classes = set(self.encoder.classes_)
        self.register('tags', [len(self._classes)], np.bool)

    def transform_annotation(self, ann, duration):
        '''Transform an annotation to static label encoding.

        Parameters
        ----------
        ann : jams.Annotation
            The annotation to convert

        duration : number > 0
            The duration of the track

        Returns
        -------
        data : dict
            data['tags'] : np.ndarray, shape=(n_labels,)
                A static binary encoding of the labels
        '''
        intervals = np.asarray([[0, 1]])
        values = list(ann.data.value)
        intervals = np.tile(intervals, [len(values), 1])

        # Suppress all intervals not in the encoder
        tags = [v for v in values if v in self._classes]
        if len(tags):
            target = self.encoder.transform([tags]).astype(np.bool).max(axis=0)
        else:
            target = np.zeros(len(self._classes), dtype=np.bool)

        return {'tags': target}
<|endoftext|>