Skip to content

Commit

Permalink
update dqcParameters plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
hefischer committed Jul 2, 2015
1 parent fa3b1f5 commit 2b16299
Showing 1 changed file with 96 additions and 26 deletions.
122 changes: 96 additions & 26 deletions arelle/plugin/logging/dqcParameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,37 +7,106 @@
from arelle.ModelDtsObject import ModelConcept
from arelle.ModelInstanceObject import ModelFact
from arelle.XmlUtil import xmlstring
from arelle import XbrlConst, XmlUtil
import re
from collections import defaultDict
from collections import defaultdict

labelrole = None
lang = None

altParametersPattern = re.compile(r"\$\{([\w.]+)\}")
parametersPattern = re.compile(r"%\(([\w.]+)\)")
factNumberPattern = re.compile(r"fact(\n+)")
factNumberPattern = re.compile(r"fact(\d+)")

def measureFormat(measure):
if measure.namespaceURI in (XbrlConst.iso4217, XbrlConst.xbrli):
return measure.localName
return str(measure) # qname str

def loggingMessageParameters(messageCode, msg, modelObjectArgs, fmtArgs):
factsArray = []
factsByQname = defaultDict(list) # list of facts with the qname
for arg in modelObjectArgs:
# arg may be a ModelFact, or any other ModelObject
if isinstance(arg, ModelFact):
factArray.append(arg)
factsByQname[str(fact.qname)].append(arg)

# parse parameter names out of msg
for param in parametersPattern.findall(msg):
try:
def loggingMessageParameters(messageCode, msgIn, modelObjectArgs, fmtArgs):
if messageCode.startswith("DQC"):
# change ${...} in message into %(...)s
msg = altParametersPattern.sub(r"%(\1)s", msgIn)

# find qnamed fact references
qnamedFactReferences = set()
for param in parametersPattern.findall(msg):
paramParts = param.split('.')
if len(paramParts) > 2 and factNumberPattern.match(parmParts[0]):
modelFactNum = int(factNumberPattern.match(parmParts[0]).group(1))
if modelFactNum < len(factsArray):
modelFact = factsArray[modelFactNum]
if paramParts[2] == "value":
fmtArgs[param] = modelFact.value
elif len(paramParts) > 2 and paramParts[2] == "fact":
# take first matching fact ??
if paramParts[0] in factsByQname:
modelFact = factsByQname[paramParts[0]]
if paramParts[3] == "value":
fmtArgs[param] = modelFact.value
if len(paramParts) > 1 and not factNumberPattern.match(paramParts[0]):
qnamedFactReferences.add(paramParts[0])
factsArray = []
factsByQname = defaultdict(list) # list of facts with the qname
for arg in modelObjectArgs:
# Pargmeter may be a ModelFact, or any other ModelObject
if isinstance(arg, ModelFact):
if str(arg.qname) in qnamedFactReferences:
factsByQname[str(arg.qname)].append(arg)
else:
factsArray.append(arg)


def setArgForFactProperty(param, modelFact, propertyNameParts):
propVal = None
property = propertyNameParts[0]
if property == "value":
propVal = modelFact.value
elif property == "decimals":
propVal = modelFact.decimals
elif property == "label" and modelFact.concept is not None:
propVal = modelFact.concept.label(labelrole,
lang=lang,
linkroleHint=XbrlConst.defaultLinkRole)
else:
cntx = modelFact.context
unit = modelFact.unit
if cntx is not None:
if property == "period":
if cntx.isForeverPeriod:
propVal = "forever"
elif cntx.isInstantPeriod:
propVal = XmlUtil.dateunionValue(cntx.instantDatetime, subtractOneDay=True)
else:
propVal = "{} - {}".format(XmlUtil.dateunionValue(cntx.startDatetime),
XmlUtil.dateunionValue(cntx.endDatetime, subtractOneDay=True))
elif property == "dimensions":
propVal = "\n".join("{} = {}".format(d.dimensionQname,
d.memberQname if d.isExplicit else
XmlUtil.xmlstring( XmlUtil.child(d), stripXmlns=True, prettyPrint=True ))
for d in cntx.qnameDims.values())
if unit is not None and propVal is None and property == "unit":
measures = unit.measures
if measures[1]:
propVal = 'mul {}\ndiv {} '.format(
', '.join(measureFormat(m) for m in measures[0]),
', '.join(measureFormat(m) for m in measures[1]))
else:
propVal = ', '.join(measureFormat(m) for m in measures[0])
if propVal is not None:
fmtArgs[param] = propVal

# parse parameter names out of msg
for param in parametersPattern.findall(msg):
try:
paramParts = param.split('.')
if len(paramParts) >= 2 and factNumberPattern.match(paramParts[0]):
modelFactNum = int(factNumberPattern.match(paramParts[0]).group(1))
if 1 <= modelFactNum <= len(factsArray):
modelFact = factsArray[modelFactNum - 1]
setArgForFactProperty(param, modelFact, paramParts[1:])
elif len(paramParts) >= 3 and paramParts[1] == "fact":
# take first matching fact ??
if paramParts[0] in factsByQname:
modelFact = factsByQname[paramParts[0]]
setArgForFactProperty(param, modelFact, paramParts[2:])
except Exception:
pass
return msg
return None

def loggingCommandLineXbrlRun(cntlr, options, modelXbrl):
global labelrole, lang
labelrole=options.labelRole
lang=options.labelLang

__pluginInfo__ = {
# Do not use _( ) in pluginInfo itself (it is applied later, after loading
Expand All @@ -50,5 +119,6 @@ def loggingMessageParameters(messageCode, msg, modelObjectArgs, fmtArgs):
'author': 'Mark V Systems',
'copyright': '(c) Copyright 2014 Mark V Systems Limited, All rights reserved.',
# classes of mount points (required)
'CntlrCmdLine.Xbrl.Run': loggingCommandLineXbrlRun,
'Logging.Message.Parameters': loggingMessageParameters
}

0 comments on commit 2b16299

Please sign in to comment.