Exemple #1
0
def _durationFunction(node, sphinxContext, args):
    hasArg(node, sphinxContext, args, 1)
    startArg = args[0]
    if isinstance(startArg, str):
        startDateTime = Period(None, XmlUtil.datetimeValue(startArg, none=NONE))
    elif isinstance(startArg, datetime.datetime):
        startDateTime = startArg
    elif isinstance(arg, datetime.date):
        startDateTime = datetime.date(startArg.year, startArg.month, startArg.day)
    endArg = args[1]
    if isinstance(endArg, str):
        endDateTime = Period(None, XmlUtil.datetimeValue(startArg, addOneDay=True, none=NONE))
    elif isinstance(endArg, datetime.datetime):
        endDateTime = endArg
    elif isinstance(endArg, datetime.date):
        endDateTime = datetime.date(endArg.year, endArg.month, endArg.day) + datetime.timedelta(1)
    if startDateTime and endDateTime:
        return Period(startDateTime, endDateTime)
    raise SphinxException(
        node,
        "sphinx.functionArgumentsMismatch",
        _("Function %(name)s requires two argument that are a date or datetime string or value: %(start)s and %(end)s"),
        name=node.name,
        start=startArg,
        end=endArg,
    )
Exemple #2
0
def _durationFunction(node, sphinxContext, args):
    hasArg(node, sphinxContext, args, 1)
    startArg = args[0]
    if isinstance(startArg, str):
        startDateTime = Period(None, XmlUtil.datetimeValue(startArg,
                                                           none=NONE))
    elif isinstance(startArg, datetime.datetime):
        startDateTime = startArg
    elif isinstance(arg, datetime.date):
        startDateTime = datetime.date(startArg.year, startArg.month,
                                      startArg.day)
    endArg = args[1]
    if isinstance(endArg, str):
        endDateTime = Period(
            None, XmlUtil.datetimeValue(startArg, addOneDay=True, none=NONE))
    elif isinstance(endArg, datetime.datetime):
        endDateTime = endArg
    elif isinstance(endArg, datetime.date):
        endDateTime = datetime.date(endArg.year, endArg.month,
                                    endArg.day) + datetime.timedelta(1)
    if (startDateTime and endDateTime):
        return Period(startDateTime, endDateTime)
    raise SphinxException(
        node,
        "sphinx.functionArgumentsMismatch",
        _(
            "Function %(name)s requires two argument that are a date or datetime string or value: %(start)s and %(end)s",
        ),
        name=node.name,
        start=startArg,
        end=endArg)
Exemple #3
0
 def setOptions(self):
     # set formula options
     self.options.entityIdentScheme = self.cellEntityIdentScheme.value
     self.options.entityIdentValue = self.cellEntityIdentValue.value
     # need datetime.datetime base class for pickling, not ModelValue class (unpicklable)
     self.options.startDate = XmlUtil.datetimeValue(self.cellStartDate.value)
     self.options.endDate = XmlUtil.datetimeValue(self.cellEndDate.value, addOneDay=True)
     self.options.monetaryUnit = self.cellMonetaryUnit.value
     self.options.monetaryDecimals = self.cellMonetaryDecimals.value
     self.options.nonMonetaryDecimals = self.cellNonMonetaryDecimals.value
 def aspectValue(self, xpCtx, aspect, inherit=False):
     if aspect == Aspect.DIMENSIONS:
         dims = set(self.prefixedNameQname(e.get("dimension"))
                    for e in XmlUtil.children(self, XbrlConst.euRend, "explicitDimCoord"))
         if inherit and self.parentDefinitionNode is not None:
             dims |= self.parentDefinitionNode.aspectValue(None, aspect, inherit)
         return dims
     if inherit and not self.hasAspect(None, aspect):
         if self.parentDefinitionNode is not None:
             return self.parentDefinitionNode.aspectValue(None, aspect, inherit)
         return None
     if aspect == Aspect.CONCEPT:
         priItem = XmlUtil.childAttr(self, XbrlConst.euRend, "primaryItem", "name")
         if priItem is not None:
             return self.prefixedNameQname(priItem)
         return None
     elif aspect == Aspect.PERIOD_TYPE:
         if XmlUtil.hasChild(self, XbrlConst.euRend, "timeReference"):
             return "instant"
     elif aspect == Aspect.INSTANT:
         return XmlUtil.datetimeValue(XmlUtil.childAttr(self, XbrlConst.euRend, "timeReference", "instant"), 
                                      addOneDay=True)
     elif isinstance(aspect, QName):
         for e in XmlUtil.children(self, XbrlConst.euRend, "explicitDimCoord"):
             if self.prefixedNameQname(e.get("dimension")) == aspect:
                 return self.prefixedNameQname(e.get("value"))
     return None
 def instantDatetime(self):
     """(datetime) -- instant attribute, with adjustment to end-of-day midnight as needed"""
     try:
         return self._instantDatetime
     except AttributeError:
         self._instantDatetime = XmlUtil.datetimeValue(XmlUtil.child(self.period, XbrlConst.xbrli, "instant"), addOneDay=True)
         return self._instantDatetime
Exemple #6
0
 def startDatetime(self):
     try:
         return self._startDatetime
     except AttributeError:
         self._startDatetime = XmlUtil.datetimeValue(
             XmlUtil.child(self.period, XbrlConst.xbrli, "startDate"))
         return self._startDatetime
 def startDatetime(self):
     """(datetime) -- startDate attribute"""
     try:
         return self._startDatetime
     except AttributeError:
         self._startDatetime = XmlUtil.datetimeValue(XmlUtil.child(self.period, XbrlConst.xbrli, "startDate"))
         return self._startDatetime
Exemple #8
0
 def instantDatetime(self):
     try:
         return self._instantDatetime
     except AttributeError:
         self._instantDatetime = XmlUtil.datetimeValue(XmlUtil.child(
             self.period, XbrlConst.xbrli, "instant"),
                                                       addOneDay=True)
         return self._instantDatetime
Exemple #9
0
 def characters(self, content):
     if self.currentNamespaceURI:
         elt = self.qnameStack[0]
         if self.currentNamespaceURI == XbrlConst.xbrli:
             s = content.strip()
             if s:
                 if self.currentLocalName == "identifier":
                     elt._entityIdentifier = (elt._entityIdentifier[0], elt._entityIdentifier[1] + content)
                 elif self.currentLocalName == "startDate":
                     elt._startDatetime = XmlUtil.datetimeValue(s)
                     elt._isStartEndPeriod = True
                 elif self.currentLocalName == "endDate":
                     elt._endDatetime = XmlUtil.datetimeValue(s, addOneDay=True)
                     elt._isStartEndPeriod = True
                 elif self.currentLocalName == "instant":
                     elt._endDatetime = elt._instantDatetime = XmlUtil.datetimeValue(s, addOneDay=True)
                     elt._isInstantPeriod = True
                 elif self.currentLocalName == "measure":
                     m = self.qname(content)
                     parentEltLocalName = self.qnameStack[1].localName
                     if parentEltLocalName == "unit":
                         self.qnameStack[1]._measures[0].append(m)
                     elif parentEltLocalName == "unitNumerator" and self.qnameStack[2].localName == "unit":
                         self.qnameStack[2]._measures[0].append(m)
                     elif parentEltLocalName == "unitDenominator" and self.qnameStack[2].localName == "unit":
                         self.qnameStack[2]._measures[1].append(m)
         elif self.currentNamespaceURI == XbrlConst.xbrldi:
             s = content.strip()
             if s:
                 if self.currentLocalName == "explicitMember" and self.dimensionPrefixedName:
                     dimQname = self.qname(self.currentLocalName)
                     memQname = self.qname(s)
                     dimConcept = self.modelXbrl.qnameConcepts.get(dimQname)
                     memConcept = self.modelXbrl.qnameConcepts.get(memQname)
         elif elt is not None:
             elt._elementText += content
Exemple #10
0
def _instantFunction(node, sphinxContext, args):
    hasArg(node, sphinxContext, args, 0)
    arg = args[0]
    if isinstance(arg, str):
        instDateTime = Period(None, XmlUtil.datetimeValue(arg, addOneDay=True, none=NONE))
        if instDateTime:  # none if date is not valid
            return instDateTime
    elif isinstance(arg, datetime.datetime):
        return Period(None, arg)
    elif isinstance(arg, datetime.date):  # must be turned into midnight of the day reported
        return Period(None, datetime.date(arg.year, arg.month, arg.day) + datetime.timedelta(1))
    raise SphinxException(
        node,
        "sphinx.functionArgumentsMismatch",
        _("Function %(name)s argument is not a date or datetime string or value %(value)s"),
        name=node.name,
        value=arg,
    )
 def setOptions(self):
     # set formula options
     self.options["feedSource"] = self.cellFeed.value
     if self.cellFeed.value in rssFeeds:
         self.options["feedSourceUri"] = rssFeeds[self.cellFeed.value]
     else:
         self.options["feedSourceUri"] = self.cellFeed.value
     self.options["matchTextExpr"] = self.cellMatchText.value
     self.options["formulaFileUri"] = self.cellFormulaFile.value
     self.options["logFileUri"] = self.cellLogFile.value
     self.options["emailAddress"] = self.cellEmailAddress.value
     if self.cellLatestPubDate.value:
         # need datetime.datetime base class for pickling, not ModelValue class (unpicklable)
         self.options["latestPubDate"] = XmlUtil.datetimeValue(self.cellLatestPubDate.value)
     else:
         self.options["latestPubDate"] = None
     for checkbox in self.checkboxes:
         self.options[checkbox.attr] = checkbox.value
 def setOptions(self):
     # set formula options
     self.options["feedSource"] = self.cellFeed.value
     if self.cellFeed.value in rssFeeds:
         self.options["feedSourceUri"] = rssFeeds[self.cellFeed.value]
     else:
         self.options["feedSourceUri"] = self.cellFeed.value
     self.options["matchTextExpr"] = self.cellMatchText.value
     self.options["formulaFileUri"] = self.cellFormulaFile.value
     self.options["logFileUri"] = self.cellLogFile.value
     self.options["emailAddress"] = self.cellEmailAddress.value
     if self.cellLatestPubDate.value:
         # need datetime.datetime base class for pickling, not ModelValue class (unpicklable)
         self.options["latestPubDate"] = XmlUtil.datetimeValue(self.cellLatestPubDate.value)
     else:
         self.options["latestPubDate"] = None
     for checkbox in self.checkboxes:
         self.options[checkbox.attr] = checkbox.value
Exemple #13
0
def _instantFunction(node, sphinxContext, args):
    hasArg(node, sphinxContext, args, 0)
    arg = args[0]
    if isinstance(arg, str):
        instDateTime = Period(
            None, XmlUtil.datetimeValue(arg, addOneDay=True, none=NONE))
        if instDateTime:  # none if date is not valid
            return instDateTime
    elif isinstance(arg, datetime.datetime):
        return Period(None, arg)
    elif isinstance(
            arg,
            datetime.date):  # must be turned into midnight of the day reported
        return Period(
            None,
            datetime.date(arg.year, arg.month, arg.day) +
            datetime.timedelta(1))
    raise SphinxException(
        node,
        "sphinx.functionArgumentsMismatch",
        _("Function %(name)s argument is not a date or datetime string or value %(value)s"
          ),
        name=node.name,
        value=arg)
                         entryFile=dts.uri, instanceFile=dts.modelDocument.basename)

    if dts:
        dts.saveInstance(overrideFilepath=instanceFilename)
        dts.info("info:savedSampleInstance",
                 _("Instance file written for %(entryFile)s in file %(instanceFile)s."),
                 modelObject=dts,
                 entryFile=dts.uri, instanceFile=instanceFilename)
    elif not separateLinkroleFiles:
        dts.info("info:noSampleInstance",
                 _("Instance file not written (no presentation line items) for %(entryFile)s in file %(instanceFile)s."),
                 modelObject=dts,
                 entryFile=dts.uri, instanceFile=instanceFilename)

sampleDataValues = {
    1: {"periodStart": XmlUtil.datetimeValue("2016-01-01"),
        "periodEnd": XmlUtil.datetimeValue("2016-03-31", addOneDay=True),
        "date": "2016-03-03",
        "dateTime": "2016-03-03T12:00:00",
        "gYear": "2016",
        "gMonth": "--03",
        "str": "abc"},
    2: {"periodStart": XmlUtil.datetimeValue("2016-04-01"),
        "periodEnd": XmlUtil.datetimeValue("2016-06-30", addOneDay=True),
        "date": "2016-06-04",
        "dateTime": "2016-06-04T13:00:00",
        "gMonth": "--06",
        "gYear": "2016",
        "str": "def"},
    3: {"periodStart": XmlUtil.datetimeValue("2016-07-01"),
        "periodEnd": XmlUtil.datetimeValue("2016-09-30", addOneDay=True),
Exemple #15
0
 def endDateDate(self):  # return a date-typed date
     """(datetime) -- date-typed date value of endDate (which is persisted in str form)"""
     return XmlUtil.datetimeValue(self.endDate, addOneDay=True)
Exemple #16
0
 def startDateDate(self):
     """(datetime) -- date-typed date value of startDate (which is persisted in str form)"""
     return XmlUtil.datetimeValue(self.startDate)
Exemple #17
0
 def watchCycle(self):
     while not self.stopRequested:
         rssWatchOptions = self.rssModelXbrl.modelManager.rssWatchOptions
         
         # check rss expiration
         rssHeaders = self.cntlr.webCache.getheaders(self.rssModelXbrl.modelManager.rssWatchOptions.get("feedSourceUri"))
         expires = parseRfcDatetime(rssHeaders.get("expires"))
         reloadNow = True # texpires and expires > datetime.datetime.now()
         
         # reload rss feed
         self.rssModelXbrl.reload('checking RSS items', reloadCache=reloadNow)
         if self.stopRequested: break
         # setup validator
         postLoadActions = []
         if rssWatchOptions.get("validateDisclosureSystemRules"):
             self.instValidator = ValidateFiling.ValidateFiling(self.rssModelXbrl)
             postLoadActions.append(_("validating"))
         elif rssWatchOptions.get("validateXbrlRules") or rssWatchOptions.get("validateFormulaAssertions"):
             self.instValidator = ValidateXbrl.ValidateXbrl(self.rssModelXbrl)
             postLoadActions.append(_("validating"))
             if (rssWatchOptions.get("validateFormulaAssertions")):
                 postLoadActions.append(_("running formulas"))
         else:
             self.instValidator = None
            
         matchTextExpr = rssWatchOptions.get("matchTextExpr") 
         if matchTextExpr:
             matchPattern = re.compile(matchTextExpr)
             postLoadActions.append(_("matching text"))
         else:
             matchPattern= None
         postLoadAction = ', '.join(postLoadActions)
         
         # anything to check new filings for
         if (rssWatchOptions.get("validateDisclosureSystemRules") or
             rssWatchOptions.get("validateXbrlRules") or
             rssWatchOptions.get("validateCalcLinkbase") or
             rssWatchOptions.get("validateFormulaAssertions") or
             rssWatchOptions.get("alertMatchedFactText") or
             any(pluginXbrlMethod(rssWatchOptions)
                 for pluginXbrlMethod in pluginClassMethods("RssWatch.HasWatchAction"))
             ):
             # form keys in ascending order of pubdate
             pubDateRssItems = []
             for rssItem in self.rssModelXbrl.modelDocument.rssItems:
                 pubDateRssItems.append((rssItem.pubDate,rssItem.objectId()))
             
             for pubDate, rssItemObjectId in sorted(pubDateRssItems):
                 rssItem = self.rssModelXbrl.modelObject(rssItemObjectId)
                 # update ui thread via modelManager (running in background here)
                 self.rssModelXbrl.modelManager.viewModelObject(self.rssModelXbrl, rssItem.objectId())
                 if self.stopRequested:
                     break
                 latestPubDate = XmlUtil.datetimeValue(rssWatchOptions.get("latestPubDate"))
                 if (latestPubDate and 
                     rssItem.pubDate < latestPubDate):
                     continue
                 try:
                     # try zipped URL if possible, else expanded instance document
                     modelXbrl = ModelXbrl.load(self.rssModelXbrl.modelManager, 
                                                openFileSource(rssItem.zippedUrl, self.cntlr),
                                                postLoadAction)
                     if self.stopRequested:
                         modelXbrl.close()
                         break
                     
                     emailAlert = False
                     if modelXbrl.modelDocument is None:
                         modelXbrl.error("arelle.rssWatch",
                                         _("RSS item %(company)s %(form)s document not loaded: %(date)s"),
                                         modelXbrl=modelXbrl, company=rssItem.companyName, 
                                         form=rssItem.formType, date=rssItem.filingDate)
                         rssItem.status = "not loadable"
                     else:
                         # validate schema, linkbase, or instance
                         if self.stopRequested:
                             modelXbrl.close()
                             break
                         if self.instValidator:
                             self.instValidator.validate(modelXbrl)
                             if modelXbrl.errors and rssWatchOptions.get("alertValiditionError"):
                                 emailAlert = True
                         for pluginXbrlMethod in pluginClassMethods("RssWatch.DoWatchAction"):  
                             pluginXbrlMethod(modelXbrl, rssWatchOptions, rssItem)      
                         # check match expression
                         if matchPattern:
                             for fact in modelXbrl.factsInInstance:
                                 v = fact.value
                                 if v is not None:
                                     m = matchPattern.search(v)
                                     if m:
                                         fr, to = m.span()
                                         msg = _("Fact Variable {0}\n context {1}\n matched text: {2}").format( 
                                                 fact.qname, fact.contextID, v[max(0,fr-20):to+20])
                                         modelXbrl.info("arelle.rssInfo",
                                                        msg,
                                                        modelXbrl=modelXbrl) # msg as code passes it through to the status
                                         if rssWatchOptions.get("alertMatchedFactText"):
                                             emailAlert = True
                                     
                         if (rssWatchOptions.get("formulaFileUri") and rssWatchOptions.get("validateFormulaAssertions") and
                             self.instValidator): 
                             # attach formulas
                             ModelDocument.load(modelXbrl, rssWatchOptions["formulaFileUri"])
                             ValidateFormula.validate(self.instValidator)
                             
                     rssItem.setResults(modelXbrl)
                     modelXbrl.close()
                     del modelXbrl  # completely dereference
                     self.rssModelXbrl.modelManager.viewModelObject(self.rssModelXbrl, rssItem.objectId())
                     if rssItem.assertionUnsuccessful and rssWatchOptions.get("alertAssertionUnsuccessful"):
                         emailAlert = True
                     
                     msg = _("Filing CIK {0}\n "
                              "company {1}\n "
                              "published {2}\n "
                              "form type {3}\n "
                              "filing date {4}\n "
                              "period {5}\n "
                              "year end {6}\n "
                              "results: {7}").format(
                              rssItem.cikNumber,
                              rssItem.companyName,
                              rssItem.pubDate,
                              rssItem.formType,
                              rssItem.filingDate,
                              rssItem.period,
                              rssItem.fiscalYearEnd,
                              rssItem.status)
                     self.rssModelXbrl.info("arelle:rssWatch", msg, modelXbrl=self.rssModelXbrl)
                     emailAddress = rssWatchOptions.get("emailAddress")
                     if emailAlert and emailAddress:
                         self.rssModelXbrl.modelManager.showStatus(_("sending e-mail alert"))
                         import smtplib
                         from email.mime.text import MIMEText
                         emailMsg = MIMEText(msg)
                         emailMsg["Subject"] = _("Arelle RSS Watch alert on {0}").format(rssItem.companyName)
                         emailMsg["From"] = emailAddress
                         emailMsg["To"] = emailAddress
                         smtp = smtplib.SMTP()
                         smtp.sendmail(emailAddress, [emailAddress], emailMsg.as_string())
                         smtp.quit()
                     self.rssModelXbrl.modelManager.showStatus(_("RSS item {0}, {1} completed, status {2}").format(rssItem.companyName, rssItem.formType, rssItem.status), 3500)
                     self.rssModelXbrl.modelManager.cntlr.rssWatchUpdateOption(rssItem.pubDate.strftime('%Y-%m-%dT%H:%M:%S'))
                 except Exception as err:
                     self.rssModelXbrl.error("arelle.rssError",
                                             _("RSS item %(company)s, %(form)s, %(date)s, exception: %(error)s"),
                                             modelXbrl=self.rssModelXbrl, company=rssItem.companyName, 
                                             form=rssItem.formType, date=rssItem.filingDate, error=err,
                                             exc_info=True)
                 if self.stopRequested: break
         if self.stopRequested: 
             self.cntlr.showStatus(_("RSS watch, stop requested"), 10000)
         else:
             import time
             time.sleep(600)
         
     self.thread = None  # close thread
     self.stopRequested = False
     
             
Exemple #18
0
        if not separateLinkroleFiles:
            dts.saveInstance(overrideFilepath=instanceFilename)
            dts.info("info:savedSampleInstance",
                     _("Instance file written for %(entryFile)s in file %(instanceFile)s."),
                     modelObject=dts,
                     entryFile=dts.uri, instanceFile=instanceFilename)
    elif not separateLinkroleFiles:
        dts.info("info:noSampleInstance",
                 _("Instance file not written (no presentation line items) for %(entryFile)s in file %(instanceFile)s."),
                 modelObject=dts,
                 entryFile=dts.uri, instanceFile=instanceFilename)
        
    del dts.conceptSampleValue, conceptSampleUnit, conceptSampleScheme

sampleDataValues = {
    1: {"periodStart": XmlUtil.datetimeValue("2016-01-01"),
        "periodEnd": XmlUtil.datetimeValue("2016-03-31", addOneDay=True),
        "date": "2016-03-03",
        "dateTime": "2016-03-03T12:00:00",
        "duration": "P1D",
        "gYear": "2016",
        "gMonth": "--03",
        "str": "abc"},
    2: {"periodStart": XmlUtil.datetimeValue("2016-04-01"),
        "periodEnd": XmlUtil.datetimeValue("2016-06-30", addOneDay=True),
        "date": "2016-06-04",
        "dateTime": "2016-06-04T13:00:00",
        "duration": "P1D",
        "gMonth": "--06",
        "gYear": "2016",
        "str": "def"},
 def instantDatetime(self):
     try:
         return self._instantDatetime
     except AttributeError:
         self._instantDatetime = XmlUtil.datetimeValue(XmlUtil.child(self.period, XbrlConst.xbrli, "instant"), addOneDay=True)
         return self._instantDatetime