Permalink
Browse files

Optimizations and fixes:

  - Imports: do not even attempt to import pseudo-components (causes
    circular references, avoiding that makes some imports 4x faster)
  - S3Trackable: select only what is really needed
  - RMSAmericas/siglist: import RL only when needed
  • Loading branch information...
nursix committed Oct 19, 2018
1 parent 5973322 commit edf6fea144f9f509ee3454666e1160604df6a7e6
Showing with 116 additions and 53 deletions.
  1. +1 −1 VERSION
  2. +9 −1 modules/s3/s3import.py
  3. +33 −2 modules/s3/s3model.py
  4. +66 −44 modules/s3/s3track.py
  5. +5 −4 modules/s3db/hrm.py
  6. +2 −1 modules/templates/RMSAmericas/siglist.py
@@ -1 +1 @@
nursix-dev-2469-g1e62ca0 (2018-10-19 12:39:26)
nursix-dev-2470-g5973322 (2018-10-19 16:36:25)
@@ -3048,7 +3048,10 @@ def add_item(self,
else:
# Now parse the components
table = item.table
components = current.s3db.get_components(table, names=components)
s3db = current.s3db
components = s3db.get_components(table, names=components)
super_keys = s3db.get_super_keys(table)
cnames = Storage()
cinfos = Storage()
@@ -3063,6 +3066,11 @@ def add_item(self,
# Determine the keys
pkey = component.pkey
if pkey != table._id.name and pkey not in super_keys:
# Pseudo-component cannot be imported => skip
continue
if component.linktable:
ctable = component.linktable
fkey = component.lkey
@@ -1494,7 +1494,7 @@ def update_super(cls, table, record):
get_config = cls.get_config
# Get all super-entities of this table
tablename = table._tablename
tablename = original_tablename(table)
supertables = get_config(tablename, "super_entity")
if not supertables:
return False
@@ -1615,7 +1615,7 @@ def delete_super(cls, table, record):
# Get all super-tables
get_config = cls.get_config
supertables = get_config(table._tablename, "super_entity")
supertables = get_config(original_tablename(table), "super_entity")
# None? Ok - done!
if not supertables:
@@ -1668,6 +1668,37 @@ def delete_super(cls, table, record):
return True
# -------------------------------------------------------------------------
@classmethod
def get_super_keys(cls, table):
"""
Get the super-keys in an instance table
@param table: the instance table
@returns: list of field names
"""
tablename = original_tablename(table)
supertables = cls.get_config(tablename, "super_entity")
if not supertables:
return False
if not isinstance(supertables, (list, tuple)):
supertables = [supertables]
keys = []
append = keys.append
for s in supertables:
if type(s) is not Table:
s = cls.table(s)
if s is None:
continue
key = s._id.name
if key in table.fields:
append(key)
return keys
# -------------------------------------------------------------------------
@classmethod
def get_instance(cls, supertable, superid):
@@ -30,9 +30,8 @@
from datetime import datetime, timedelta
from gluon import current
from gluon import current, HTTP, FORM, INPUT, LABEL, TABLE
from gluon.storage import Storage
from gluon.html import *
from s3dal import Table, Rows, Row
from s3rest import S3Method
@@ -210,7 +209,8 @@ def __super_entity(trackable):
return "instance_type" in keys
# -------------------------------------------------------------------------
def __get_fields(self, trackable, super_entity=True):
@classmethod
def __get_fields(cls, trackable, super_entity=True):
"""
Check a trackable for presence of required fields
@@ -224,21 +224,19 @@ def __get_fields(self, trackable, super_entity=True):
else:
keys = trackable
try:
if super_entity and \
self.__super_entity(trackable) and UID in keys:
return ("instance_type", UID)
if LOCATION_ID in keys:
fields.append(LOCATION_ID)
if TRACK_ID in keys:
fields.append(TRACK_ID)
return fields
elif hasattr(trackable, "update_record") or \
isinstance(trackable, Table) or \
isinstance(trackable, Row):
return fields
except:
pass
if super_entity and \
cls.__super_entity(trackable) and UID in keys:
return ("instance_type", UID)
if LOCATION_ID in keys:
fields.append(LOCATION_ID)
if TRACK_ID in keys:
fields.append(TRACK_ID)
return fields
elif hasattr(trackable, "update_record") or \
isinstance(trackable, Table) or \
isinstance(trackable, Row):
return fields
return None
# -------------------------------------------------------------------------
@@ -247,7 +245,7 @@ def get_location(self,
_fields=None,
_filter=None,
as_rows=False,
exclude=[],
exclude=None,
empty = True):
"""
Get the current location of the instance(s) (at the given time)
@@ -264,6 +262,9 @@ def get_location(self,
@ToDo: Also show Timestamp of when seen there
"""
if exclude is None:
exclude = []
db = current.db
s3db = current.s3db
@@ -392,49 +393,72 @@ def check_in(self, table, record, timestmp=None):
if isinstance(table, str):
table = s3db[table]
fields = self.__get_fields(table)
if not fields:
raise SyntaxError("No location data in %s" % table._tablename)
interlock = None
if isinstance(record, Rows):
record = record.first()
if not isinstance(record, Row):
record = table[record]
if not self.__super_entity(table):
fields = (table._id,)
record = db(table._id == record).select(limitby=(0, 1), *fields).first()
if self.__super_entity(record):
# Get the instance table
table = s3db[record.instance_type]
fields = self.__get_fields(table, super_entity=False)
if not fields:
if not self.__get_fields(table, super_entity=False):
raise SyntaxError("No trackable type: %s" % table._tablename)
query = table[UID] == record[UID]
record = db(query).select(limitby=(0, 1)).first()
if record and table._id.name in record:
record = record[table._id.name]
if record:
interlock = "%s,%s" % (table, record)
# Get the instance record
query = (table[UID] == record[UID])
record = db(query).select(table._id, limitby=(0, 1), *fields).first()
try:
record_id = record[table._id] if record else None
except AttributeError:
record_id = None
if record_id:
interlock = "%s,%s" % (table, record_id)
else:
raise SyntaxError("No record specified for %s" % table._tablename)
if interlock:
if timestmp is None:
timestmp = datetime.utcnow()
data = dict(location_id=None,
timestmp=timestmp,
interlock=interlock)
q = ((ptable.deleted == False) & (ptable.timestmp <= timestmp))
data = {"location_id": None,
"timestmp": timestmp,
"interlock": interlock,
}
q = (ptable.timestmp <= timestmp) & \
(ptable.deleted == False)
for r in self.records:
if TRACK_ID not in r:
# Cannot check-in a non-trackable
continue
query = q & (ptable[TRACK_ID] == r[TRACK_ID])
presence = db(query).select(orderby=~ptable.timestmp,
limitby=(0, 1)).first()
track_id = r[TRACK_ID]
query = (ptable[TRACK_ID] == track_id) & q
presence = db(query).select(ptable.interlock,
orderby = ~ptable.timestmp,
limitby = (0, 1),
).first()
if presence and presence.interlock == interlock:
# already checked-in to the same instance
# Already checked-in to the same instance
continue
data.update({TRACK_ID:r[TRACK_ID]})
data[TRACK_ID] = track_id
ptable.insert(**data)
self.__update_timestamp(r[TRACK_ID], timestmp)
self.__update_timestamp(track_id, timestmp)
# -------------------------------------------------------------------------
def check_out(self, table=None, record=None, timestmp=None):
@@ -657,12 +681,10 @@ def __update_timestamp(self, track_id, timestamp):
@param timestamp: the timestamp
"""
if timestamp is None:
timestamp = datetime.utcnow()
if track_id:
trackable = self.table[track_id]
if trackable:
trackable.update_record(track_timestmp=timestamp)
if timestamp is None:
timestamp = datetime.utcnow()
current.db(self.table.track_id == track_id).update(track_timestmp=timestamp)
# =============================================================================
class S3Tracker(object):
@@ -856,7 +878,7 @@ def apply_method(r, **attr):
if r.representation == "html":
T = current.T
s3db = current.s3db
response = current.response
tracker = S3Trackable(r.table, record_id=r.id)
@@ -5756,11 +5756,12 @@ def hrm_human_resource_onaccept(form):
entity = entity,
force_update = True)
# Set person record to follow HR record
# (Person base location remains untouched)
tracker = S3Tracker()
pr_tracker = tracker(ptable, person_id)
pr_tracker.check_in(htable, record_id, timestmp = request.utcnow)
if person_id:
# Set person record to follow HR record
# (Person base location remains untouched)
pr_tracker = tracker(ptable, person_id)
pr_tracker.check_in(htable, record_id, timestmp = request.utcnow)
if record.type == 1:
# Staff
@@ -36,7 +36,6 @@
from gluon.contenttype import contenttype
from s3 import S3Method, s3_format_fullname
from s3.codecs.pdf import EdenDocTemplate, S3RL_PDF
# =============================================================================
class HRSignatureList(S3Method):
@@ -340,6 +339,8 @@ def pdf(self, r, **attr):
footer = DIV()
from s3.codecs.pdf import EdenDocTemplate, S3RL_PDF
doc = EdenDocTemplate(title=title)
printable_width = doc.printable_width

0 comments on commit edf6fea

Please sign in to comment.