def diff(): if not request.query.fromDTS or not request.query.toDTS or not request.query.report: return _("From DTS, to DTS, and report must be specified") options = Options() setattr(options, "entrypointFile", request.query.fromDTS) setattr(options, "diffFile", request.query.toDTS) fh = FileNamedStringIO(request.query.report) setattr(options, "versReportFile", fh) cntlr.run(options) reportContents = fh.getvalue() fh.close() response.content_type = 'text/xml; charset=UTF-8' return reportContents
def validation(file=None): errors = [] flavor = request.query.flavor or 'standard' media = request.query.media or 'html' requestPathParts = request.urlparts[2].split('/') isValidation = 'validation' == requestPathParts[-1] or 'validation' == requestPathParts[-2] view = request.query.view if request.method == 'POST': sourceZipStream = request.body mimeType = request.get_header("Content-Type") if mimeType not in ('application/zip', 'application/x-zip', 'application/x-zip-compressed', 'multipart/x-zip'): errors.append(_("POST must provide a zip file, Content-Type '{0}' not recognized as a zip file.").format(mimeType)) else: sourceZipStream = None if not view: if requestPathParts[-1] in supportedViews: view = requestPathParts[-1] if isValidation: if view: errors.append(_("Only validation or one view can be specified in one requested.")) if media not in ('xml', 'xhtml', 'html', 'json', 'text'): errors.append(_("Media '{0}' is not supported for validation (please select xhtml, html, xml, json or text)").format(media)) elif view: if media not in ('xml', 'xhtml', 'html', 'csv', 'json'): errors.append(_("Media '{0}' is not supported for view (please select xhtml, html, xml, csv, or json)").format(media)) elif requestPathParts[-1] not in ("open", "close"): errors.append(_("Neither validation nor view requested, nothing to do.")) if flavor != 'standard' and not flavor.startswith('edgar') and not flavor.startswith('sec'): errors.append(_("Flavor '{0}' is not supported").format(flavor)) if view and view not in supportedViews: errors.append(_("View '{0}' is not supported").format(view)) if errors: errors.insert(0, _("URL: ") + file) return errorReport(errors, media) options = Options() # need named parameters to simulate options for key, value in request.query.items(): if key == "file": setattr(options, "entrypointFile", value) elif key == "flavor": if value.startswith("sec") or value.startswith("edgar"): setattr(options, "validateEFM", True) elif key in("media", "view"): pass elif key in validationOptions: optionKey, sep, optionValue = validationOptions[key].partition('=') setattr(options, optionKey, optionValue or value) elif not value: # convert plain str parameter present to True parameter setattr(options, key, True) else: setattr(options, key, value) if file: setattr(options, "entrypointFile", file.replace(';','/')) requestPathParts = set(request.urlparts[2].split('/')) viewFile = None if isValidation: setattr(options, "validate", True) elif view: viewFile = FileNamedStringIO(media) setattr(options, view + "File", viewFile) return runOptionsAndGetResult(options, media, viewFile, sourceZipStream)
def quickbooksGLresponse(): from arelle import CntlrQuickBooks ticket = request.query.ticket media = request.query.media viewRequested = request.query.view status = CntlrQuickBooks.qbRequestStatus.get(ticket) if not status: return htmlBody(tableRows([_("QuickBooks ticket not found, request canceled.")], header=_("Quickbooks Request"))) if status != "Done" or ticket not in CntlrQuickBooks.xbrlInstances: return htmlBody(tableRows([_("{0}, Waiting 20 seconds...").format(status)], header=_("Quickbooks Request")), script=''' <script type="text/javascript"> <!-- var timer = setInterval("autoRefresh()", 1000 * 20); function autoRefresh(){{clearInterval(timer);self.location.reload(true);}} //--> </script> ''') CntlrQuickBooks.qbRequestStatus.pop(ticket) instanceUuid = CntlrQuickBooks.xbrlInstances[ticket] CntlrQuickBooks.xbrlInstances.pop(ticket) options = Options() setattr(options, "entrypointFile", instanceUuid) viewFile = FileNamedStringIO(media) setattr(options, "factsFile", viewFile) return runOptionsAndGetResult(options, media, viewFile)
def quickbooksGLresponse(): """Poll for QuickBooks protocol responses for *get* requests to */rest/quickbooks/response*. :returns: html, xml, csv, text -- Return per media type argument and request arguments, if response is ready, otherwise javascript to requery this *get* request periodicially. """ from arelle import CntlrQuickBooks ticket = request.query.ticket media = request.query.media viewRequested = request.query.view status = CntlrQuickBooks.qbRequestStatus.get(ticket) if not status: return htmlBody(tableRows([_("QuickBooks ticket not found, request canceled.")], header=_("Quickbooks Request"))) if status.startswith("ConnectionErrorMessage: "): CntlrQuickBooks.qbRequestStatus.pop(ticket, None) return errorReport([status[24:]], media) if status != "Done" or ticket not in CntlrQuickBooks.xbrlInstances: return htmlBody(tableRows([_("{0}, Waiting 20 seconds...").format(status)], header=_("Quickbooks Request")), script=''' <script type="text/javascript"> <!-- var timer = setInterval("autoRefresh()", 1000 * 20); function autoRefresh(){{clearInterval(timer);self.location.reload(true);}} //--> </script> ''') CntlrQuickBooks.qbRequestStatus.pop(ticket) instanceUuid = CntlrQuickBooks.xbrlInstances[ticket] CntlrQuickBooks.xbrlInstances.pop(ticket) options = Options() setattr(options, "entrypointFile", instanceUuid) viewFile = FileNamedStringIO(media) setattr(options, "factsFile", viewFile) return runOptionsAndGetResult(options, media, viewFile)
def diff(): """Execute versioning diff request for *get* request to */rest/xbrl/diff*. :returns: xml -- Versioning report. """ if not request.query.fromDTS or not request.query.toDTS or not request.query.report: return _("From DTS, to DTS, and report must be specified") options = Options() setattr(options, "entrypointFile", request.query.fromDTS) setattr(options, "diffFile", request.query.toDTS) fh = FileNamedStringIO(request.query.report) setattr(options, "versReportFile", fh) cntlr.run(options) reportContents = fh.getvalue() fh.close() response.content_type = 'text/xml; charset=UTF-8' return reportContents
def validation(file=None): """REST request to validate, by *get* or *post*, to URL patterns including */rest/xbrl/<file:path>/{open|close|validation|DTS...}*, and */rest/xbrl/{view|open|close}*. Sets up CntrlCmdLine options for request, performed by runOptionsAndGetResult using CntlrCmdLine.run with get or post arguments. :returns: html, xhtml, xml, json, text -- Return per media type argument and request arguments """ errors = [] flavor = request.query.flavor or 'standard' media = request.query.media or 'html' requestPathParts = request.urlparts[2].split('/') isValidation = 'validation' == requestPathParts[ -1] or 'validation' == requestPathParts[-2] view = request.query.view viewArcrole = request.query.viewArcrole if request.method == 'POST': sourceZipStream = request.body mimeType = request.get_header("Content-Type") if mimeType not in ('application/zip', 'application/x-zip', 'application/x-zip-compressed', 'multipart/x-zip'): errors.append( _("POST must provide a zip file, Content-Type '{0}' not recognized as a zip file." ).format(mimeType)) else: sourceZipStream = None if not view and not viewArcrole: if requestPathParts[-1] in supportedViews: view = requestPathParts[-1] if isValidation: if view or viewArcrole: errors.append( _("Only validation or one view can be specified in one requested." )) if media not in ('xml', 'xhtml', 'html', 'json', 'text'): errors.append( _("Media '{0}' is not supported for validation (please select xhtml, html, xml, json or text)" ).format(media)) elif view or viewArcrole: if media not in ('xml', 'xhtml', 'html', 'csv', 'json'): errors.append( _("Media '{0}' is not supported for view (please select xhtml, html, xml, csv, or json)" ).format(media)) elif requestPathParts[-1] not in ("open", "close"): errors.append( _("Neither validation nor view requested, nothing to do.")) if (flavor not in ('standard', 'standard-except-formula', 'formula-compile-only', 'formula-compile-and-run') and not flavor.startswith('edgar') and not flavor.startswith('sec')): errors.append(_("Flavor '{0}' is not supported").format(flavor)) if view and view not in supportedViews: errors.append(_("View '{0}' is not supported").format(view)) if errors: errors.insert(0, _("URL: ") + (file or request.query.file or '(no file)')) return errorReport(errors, media) options = Options() # need named parameters to simulate options isFormulaOnly = False for key, value in request.query.items(): if key == "file": setattr(options, "entrypointFile", value) elif key == "flavor": if value.startswith("sec") or value.startswith("edgar"): setattr(options, "validateEFM", True) elif value == "formula-compile-only": isFormulaOnly = True setattr(options, "formulaAction", "validate") elif value == "formula-compile-and-run": isFormulaOnly = True setattr(options, "formulaAction", "run") elif value == "standard-except-formula": setattr(options, "formulaAction", "none") elif key in ("media", "view", "viewArcrole"): pass elif key in validationOptions: optionKey, optionValue = validationOptions[key] setattr(options, optionKey, optionValue if optionValue is not None else value) elif not value: # convert plain str parameter present to True parameter setattr(options, key, True) else: setattr(options, key, value) if file: setattr(options, "entrypointFile", file.replace(';', '/')) requestPathParts = set(request.urlparts[2].split('/')) viewFile = None if isValidation: if not isFormulaOnly: setattr(options, "validate", True) elif view: viewFile = FileNamedStringIO(media) setattr(options, view + "File", viewFile) elif viewArcrole: viewFile = FileNamedStringIO(media) setattr(options, "viewArcrole", viewArcrole) setattr(options, "viewFile", viewFile) return runOptionsAndGetResult(options, media, viewFile, sourceZipStream)