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
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()
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)
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
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)