Esempio n. 1
0
    def get_base_location(self, _fields=None, _filter=None, as_rows=False):
        """
            Get the base location of the instance(s)

            @param _fields: fields to retrieve from the location records (None for ALL)
            @param _filter: filter for the locations
            @param as_rows: return the result as Rows object

            @returns: the base location(s) of the current instance
        """

        db = current.db
        s3db = current.s3db

        ltable = s3db[LOCATION]
        rtable = self.rtable

        locations = []
        for r in self.records:
            location = None
            query = None
            if LOCATION_ID in r:
                query = (ltable.id == r[LOCATION_ID])
                if rtable:
                    query = query & (rtable[LOCATION_ID] == ltable.id)
                    if TRACK_ID in r:
                        query = query & (rtable[TRACK_ID] == r[TRACK_ID])
            elif TRACK_ID in r:
                q = (self.table[TRACK_ID] == r[TRACK_ID])
                trackable = db(q).select(limitby=(0, 1)).first()
                table = s3db[trackable.instance_type]
                if LOCATION_ID in table.fields:
                    query = ((table[TRACK_ID] == r[TRACK_ID]) &
                             (table[LOCATION_ID] == ltable.id))
            if query:
                if _filter is not None:
                    query = query & _filter
                if not _fields:
                    location = db(query).select(ltable.ALL,
                                                limitby=(0, 1)).first()
                else:
                    location = db(query).select(limitby=(0, 1),
                                                *_fields).first()
            if location:
                locations.append(location)
            else:
                # Ensure we return an entry so that indexes match
                locations.append(Row({"lat": None, "lon": None}))

        if as_rows:
            return Rows(records=locations, compact=False)

        if not locations:
            return None
        elif len(locations) == 1:
            return locations[0]
        else:
            return locations
Esempio n. 2
0
    def __init__(self, show, table_name, question, validator=None):  # constructor
        # argument
        self.table_name = table_name
        self.table = db[table_name]
        self.question = XML(question)
        self.validator = validator
        self.show = show
        # generate
        self.form = None
        self.row = None
        self.rows = Rows()
        self.warnings = []  #
        self.form_buttons = []

        self.reuse_form_for_errors()
Esempio n. 3
0
    def __init__(self, trackable, record_id=None, uid=None, rtable=None):
        """
            Constructor:

            @param trackable: the trackable object
            @param record_id: the record ID(s) (if object is a table or tablename)
            @param uid: the record UID(s) (if object is a table or tablename)
            @param rtable: the resource table (for the recursive calls)
        """

        db = current.db
        s3db = current.s3db

        self.records = []

        self.table = s3db.sit_trackable
        self.rtable = rtable

        if isinstance(trackable, (Table, str)):
            if hasattr(trackable, "_tablename"):
                table = trackable
                tablename = table._tablename
            else:
                table = s3db[trackable]
                tablename = trackable
            fields = self.__get_fields(table)
            if not fields:
                raise SyntaxError("Not a trackable type: %s" % tablename)
            query = (table._id > 0)
            if uid is None:
                if record_id is not None:
                    if isinstance(record_id, (list, tuple)):
                        query = (table._id.belongs(record_id))
                    else:
                        query = (table._id == record_id)
            elif UID in table.fields:
                if not isinstance(uid, (list, tuple)):
                    query = (table[UID].belongs(uid))
                else:
                    query = (table[UID] == uid)
            fields = [table[f] for f in fields]
            rows = db(query).select(*fields)

        elif isinstance(trackable, Row):
            fields = self.__get_fields(trackable)
            if not fields:
                raise SyntaxError("Required fields not present in the row")
            rows = Rows(records=[trackable], compact=False)

        elif isinstance(trackable, Rows):
            rows = [r for r in trackable if self.__get_fields(r)]
            fail = len(trackable) - len(rows)
            if fail:
                raise SyntaxError(
                    "Required fields not present in %d of the rows" % fail)
            rows = Rows(records=rows, compact=False)

        elif isinstance(trackable, (Query, Expression)):
            tablename = db._adapter.get_table(trackable)
            self.rtable = s3db[tablename]
            fields = self.__get_fields(self.rtable)
            if not fields:
                raise SyntaxError("Not a trackable type: %s" % tablename)
            query = trackable
            fields = [self.rtable[f] for f in fields]
            rows = db(query).select(*fields)

        elif isinstance(trackable, Set):
            query = trackable.query
            tablename = db._adapter.get_table(query)
            table = s3db[tablename]
            fields = self.__get_fields(table)
            if not fields:
                raise SyntaxError("Not a trackable type: %s" % tablename)
            fields = [table[f] for f in fields]
            rows = trackable.select(*fields)

        else:
            raise SyntaxError("Invalid parameter type %s" % type(trackable))

        records = []
        for r in rows:
            if self.__super_entity(r):
                table = s3db[r.instance_type]
                fields = self.__get_fields(table, super_entity=False)
                if not fields:
                    raise SyntaxError("No trackable type: %s" %
                                      table._tablename)
                fields = [table[f] for f in fields]
                query = table[UID] == r[UID]
                row = db(query).select(limitby=(0, 1), *fields).first()
                if row:
                    records.append(row)
            else:
                records.append(r)

        self.records = Rows(records=records, compact=False)
Esempio n. 4
0
    def get_location(self,
                     timestmp=None,
                     _fields=None,
                     _filter=None,
                     as_rows=False,
                     exclude=[]):
        """
            Get the current location of the instance(s) (at the given time)

            @param timestmp: last datetime for presence (defaults to current time)
            @param _fields: fields to retrieve from the location records (None for ALL)
            @param _filter: filter for the locations
            @param as_rows: return the result as Rows object
            @param exclude: interlocks to break at (avoids circular check-ins)

            @returns: a location record, or a list of location records (if multiple)
        """

        db = current.db
        s3db = current.s3db

        ptable = s3db[PRESENCE]
        ltable = s3db[LOCATION]

        if timestmp is None:
            timestmp = datetime.utcnow()

        locations = []
        for r in self.records:
            location = None
            if TRACK_ID in r:
                query = ((ptable.deleted == False) & \
                         (ptable[TRACK_ID] == r[TRACK_ID]) & \
                         (ptable.timestmp <= timestmp))
                presence = db(query).select(orderby=~ptable.timestmp,
                                            limitby=(0, 1)).first()
                if presence:
                    if presence.interlock:
                        exclude = [r[TRACK_ID]] + exclude
                        tablename, record = presence.interlock.split(",", 1)
                        trackable = S3Trackable(tablename, record)
                        record = trackable.records.first()
                        if TRACK_ID not in record or \
                           record[TRACK_ID] not in exclude:
                            location = trackable.get_location(
                                timestmp=timestmp,
                                exclude=exclude,
                                _fields=_fields).first()
                    elif presence.location_id:
                        query = (ltable.id == presence.location_id)
                        if _filter is not None:
                            query = query & _filter
                        if _fields is None:
                            location = db(query).select(ltable.ALL,
                                                        limitby=(0,
                                                                 1)).first()
                        else:
                            location = db(query).select(limitby=(0, 1),
                                                        *_fields).first()

            if not location:
                if len(self.records) > 1:
                    trackable = S3Trackable(r, rtable=self.rtable)
                else:
                    trackable = self
                location = trackable.get_base_location(_fields=_fields)

            if location:
                locations.append(location)
            else:
                # Ensure we return an entry so that indexes match
                locations.append(Row({"lat": None, "lon": None}))

        if as_rows:
            return Rows(records=locations, compact=False)

        if not locations:
            return None
        else:
            return locations
Esempio n. 5
0
    def __init__(self,
                 table=None,
                 tablename=None,
                 record=None,
                 query=None,
                 record_id=None,
                 record_ids=None,
                 rtable=None):
        """
            Constructor:

            @param table: a Table object
            @param tablename: a Str tablename
            @param record: a Row object
            @param query: a Query object
            @param record_id: a record ID (if object is a Table)
            @param record_ids: a list of record IDs (if object is a Table)
                               - these should be in ascending order
            @param rtable: the resource table (for the recursive calls)
        """

        db = current.db
        s3db = current.s3db

        self.records = []

        self.table = s3db.sit_trackable
        self.rtable = rtable

        # if isinstance(trackable, (Table, str)):
        # if hasattr(trackable, "_tablename"):
        # table = trackable
        # tablename = table._tablename
        # else:
        # table = s3db[trackable]
        # tablename = trackable
        # fields = self.__get_fields(table)
        # if not fields:
        # raise SyntaxError("Not a trackable type: %s" % tablename)
        # query = (table._id > 0)
        # if uid is None:
        # if record_id is not None:
        # if isinstance(record_id, (list, tuple)):
        # query = (table._id.belongs(record_id))
        # else:
        # query = (table._id == record_id)
        # elif UID in table.fields:
        # if not isinstance(uid, (list, tuple)):
        # query = (table[UID].belongs(uid))
        # else:
        # query = (table[UID] == uid)
        # fields = [table[f] for f in fields]
        # rows = db(query).select(*fields)
        if table or tablename:
            if table:
                tablename = table._tablename
            else:
                table = s3db[tablename]
            fields = self.__get_fields(table)
            if not fields:
                raise SyntaxError("Not a trackable type: %s" % tablename)
            if record_ids:
                query = (table._id.belongs(record_ids))
                limitby = (0, len(record_ids))
                orderby = table._id
            elif record_id:
                query = (table._id == record_id)
                limitby = (0, 1)
                orderby = None
            else:
                query = (table._id > 0)
                limitby = None
                orderby = table._id
            fields = [table[f] for f in fields]
            rows = db(query).select(limitby=limitby, orderby=orderby, *fields)

        # elif isinstance(trackable, Row):
        # fields = self.__get_fields(trackable)
        # if not fields:
        # raise SyntaxError("Required fields not present in the row")
        # rows = Rows(records=[trackable], compact=False)
        elif record:
            fields = self.__get_fields(record)
            if not fields:
                raise SyntaxError("Required fields not present in the row")
            rows = Rows(records=[record], compact=False)

        # elif isinstance(trackable, Rows):
        # rows = [r for r in trackable if self.__get_fields(r)]
        # fail = len(trackable) - len(rows)
        # if fail:
        # raise SyntaxError("Required fields not present in %d of the rows" % fail)
        # rows = Rows(records=rows, compact=False)

        # elif isinstance(trackable, (Query, Expression)):
        # tablename = db._adapter.get_table(trackable)
        # self.rtable = s3db[tablename]
        # fields = self.__get_fields(self.rtable)
        # if not fields:
        # raise SyntaxError("Not a trackable type: %s" % tablename)
        # query = trackable
        # fields = [self.rtable[f] for f in fields]
        # rows = db(query).select(*fields)
        elif query:
            tablename = db._adapter.get_table(query)
            self.rtable = s3db[tablename]
            fields = self.__get_fields(self.rtable)
            if not fields:
                raise SyntaxError("Not a trackable type: %s" % tablename)
            fields = [self.rtable[f] for f in fields]
            rows = db(query).select(*fields)

        # elif isinstance(trackable, Set):
        # query = trackable.query
        # tablename = db._adapter.get_table(query)
        # table = s3db[tablename]
        # fields = self.__get_fields(table)
        # if not fields:
        # raise SyntaxError("Not a trackable type: %s" % tablename)
        # fields = [table[f] for f in fields]
        # rows = trackable.select(*fields)

        else:
            raise SyntaxError("Invalid parameters")

        records = []
        for r in rows:
            if self.__super_entity(r):
                table = s3db[r.instance_type]
                fields = self.__get_fields(table, super_entity=False)
                if not fields:
                    raise SyntaxError("No trackable type: %s" %
                                      table._tablename)
                fields = [table[f] for f in fields]
                query = table[UID] == r[UID]
                row = db(query).select(limitby=(0, 1), *fields).first()
                if row:
                    records.append(row)
            else:
                records.append(r)

        self.records = Rows(records=records, compact=False)