def ok(self, event=None):
     if self.pluginConfigChanged:
         PluginManager.pluginConfig = self.pluginConfig
         PluginManager.pluginConfigChanged = True
         PluginManager.reset()  # force reloading of modules
     if self.uiClassMethodsChanged or self.modelClassesChanged or self.disclosureSystemTypesChanged or self.hostSystemFeaturesChanged:  # may require reloading UI
         affectedItems = ""
         if self.uiClassMethodsChanged:
             affectedItems += _("menus of the user interface")
         if self.modelClassesChanged:
             if affectedItems:
                 affectedItems += _(" and ")
             affectedItems += _("model objects of the processor")
         if self.disclosureSystemTypesChanged:
             if affectedItems:
                 affectedItems += _(" and ")
             affectedItems += _("disclosure system types")
         if self.hostSystemFeaturesChanged:
             if affectedItems:
                 affectedItems += _(" and ")
             affectedItems += _("host system features")
         if messagebox.askyesno(_("User interface plug-in change"),
                                _("A change in plug-in class methods may have affected {0}.  " 
                                  "Please restart Arelle to due to these changes.  \n\n"
                                  "Should Arelle restart itself now "
                                  "(if there are any unsaved changes they would be lost!)?"
                                  ).format(affectedItems),
                                parent=self):
             self.cntlr.uiThreadQueue.put((self.cntlr.quit, [None, True]))
     self.close()
Example #2
0
def get_test_data(args):
    """
    Produces a list of Pytest Params that can be fed into a parameterized pytest function

    :param args: The args to be parsed by arelle in order to correctly produce the desired result set
    :type args: list of strings
    :return: A list of PyTest Params that can be used to run a parameterized pytest function
    :rtype: list of ::class:: `~pytest.param`
    """
    cntlr = parseAndRun(args)
    results = []
    model_document = cntlr.modelManager.modelXbrl.modelDocument
    if model_document is not None:
        if model_document.type == ModelDocument.Type.TESTCASESINDEX:
            for tc in sorted(model_document.referencesDocument.keys(),
                             key=lambda doc: doc.uri):
                uri_dir_parts = os.path.dirname(tc.uri).split('/')
                test_case_dir = '/'.join(uri_dir_parts[-2:])
                if hasattr(tc, "testcaseVariations"):
                    for mv in tc.testcaseVariations:
                        param = pytest.param(
                            {
                                'status': mv.status,
                                'expected': mv.expected,
                                'actual': mv.actual
                            },
                            id='{}/{}'.format(test_case_dir,
                                              str(mv.id or mv.name)))
                        results.append(param)
    cntlr.modelManager.close()
    PackageManager.close()
    PluginManager.close()
    return results
Example #3
0
 def ok(self, event=None):
     if self.pluginConfigChanged:
         PluginManager.pluginConfig = self.pluginConfig
         PluginManager.pluginConfigChanged = True
         PluginManager.reset()  # force reloading of modules
     if self.uiClassMethodsChanged or self.modelClassesChanged or self.disclosureSystemTypesChanged:  # may require reloading UI
         affectedItems = ""
         if self.uiClassMethodsChanged:
             affectedItems += _("menus of the user interface")
         if self.modelClassesChanged:
             if self.uiClassMethodsChanged:
                 affectedItems += _(" and ")
             affectedItems += _("model objects of the processor")
         if (self.uiClassMethodsChanged or self.modelClassesChanged):
             affectedItems += _(" and ")
         if self.disclosureSystemTypesChanged:
             if (self.uiClassMethodsChanged or self.modelClassesChanged):
                 affectedItems += _(" and ")
             affectedItems += _("disclosure system types")
         if messagebox.askyesno(_("User interface plug-in change"),
                                _("A change in plug-in class methods may have affected {0}.  " 
                                  "Please restart Arelle to due to these changes.  \n\n"
                                  "Should Arelle restart itself now "
                                  "(if there are any unsaved changes they would be lost!)?"
                                  ).format(affectedItems),
                                parent=self):
             self.cntlr.uiThreadQueue.put((self.cntlr.quit, [None, True]))
     self.close()
Example #4
0
 def close(self, saveConfig=False):
     """.. method:: close(saveConfig=False)
        Close controller and its logger, optionally saaving the user preferences configuration
        :param saveConfig: save the user preferences configuration"""
     PluginManager.save(self)
     if saveConfig:
         self.saveConfig()
     if self.logger is not None:
         self.logHandler.close()
Example #5
0
 def ok(self, event=None):
     if self.pluginConfigChanged:
         PluginManager.pluginConfig = self.pluginConfig
         PluginManager.pluginConfigChanged = True
         PluginManager.reset()  # force reloading of modules
     if self.uiClassMethodsChanged:  # may require reloading UI
         messagebox.showwarning(_("User interface plug-in change"),
                                _("A change in plug-in class methods may have affected the menus "
                                  "of the user interface.  It may be necessary to restart Arelle to "
                                  "access the menu entries or the changes to their plug-in methods."),
                                parent=self)
     self.close()
Example #6
0
    def ok(self, event=None):
        # check for orphaned classes (for which there is no longer a corresponding module)
        _moduleNames = self.pluginConfig.get("modules", {}).keys()
        _orphanedClassNames = set()
        for className, moduleList in self.pluginConfig.get("classes",
                                                           {}).items():
            for _moduleName in moduleList.copy():
                if _moduleName not in _moduleNames:  # it's orphaned
                    moduleList.remove(_moduleName)
                    self.pluginConfigChanged = True
            if not moduleList:  # now orphaned
                _orphanedClassNames.add(className)
                self.pluginConfigChanged = True
        for _orphanedClassName in _orphanedClassNames:
            del self.pluginConfig["classes"][_orphanedClassName]

        if self.pluginConfigChanged:
            PluginManager.pluginConfig = self.pluginConfig
            PluginManager.pluginConfigChanged = True
            PluginManager.reset()  # force reloading of modules
        if self.uiClassMethodsChanged or self.modelClassesChanged or self.customTransformsChanged or self.disclosureSystemTypesChanged or self.hostSystemFeaturesChanged:  # may require reloading UI
            affectedItems = ""
            if self.uiClassMethodsChanged:
                affectedItems += _("menus of the user interface")
            if self.modelClassesChanged:
                if affectedItems:
                    affectedItems += _(" and ")
                affectedItems += _("model objects of the processor")
            if self.customTransformsChanged:
                if affectedItems:
                    affectedItems += _(" and ")
                affectedItems += _("custom transforms")
            if self.disclosureSystemTypesChanged:
                if affectedItems:
                    affectedItems += _(" and ")
                affectedItems += _("disclosure system types")
            if self.hostSystemFeaturesChanged:
                if affectedItems:
                    affectedItems += _(" and ")
                affectedItems += _("host system features")
            if messagebox.askyesno(
                    _("User interface plug-in change"),
                    _("A change in plug-in class methods may have affected {0}.  "
                      "Please restart Arelle to due to these changes.  \n\n"
                      "Should Arelle restart itself now "
                      "(if there are any unsaved changes they would be lost!)?"
                      ).format(affectedItems),
                    parent=self):
                self.cntlr.uiThreadQueue.put((self.cntlr.quit, [None, True]))
        self.close()
Example #7
0
 def close(self, saveConfig=False):
     """Closes the controller and its logger, optionally saving the user preferences configuration
        
        :param saveConfig: save the user preferences configuration
        :type saveConfig: bool
     """
     PluginManager.save(self)
     if saveConfig:
         self.saveConfig()
     if self.logger is not None:
         try:
             self.logHandler.close()
         except Exception: # fails on some earlier pythons (3.1)
             pass
Example #8
0
 def close(self, saveConfig=False):
     """Closes the controller and its logger, optionally saving the user preferences configuration
        
        :param saveConfig: save the user preferences configuration
        :type saveConfig: bool
     """
     PluginManager.save(self)
     if saveConfig:
         self.saveConfig()
     if self.logger is not None:
         try:
             self.logHandler.close()
         except Exception:  # fails on some earlier pythons (3.1)
             pass
Example #9
0
 def ok(self, event=None):
     if self.pluginConfigChanged:
         PluginManager.pluginConfig = self.pluginConfig
         PluginManager.pluginConfigChanged = True
         PluginManager.reset()  # force reloading of modules
     if self.uiClassMethodsChanged:  # may require reloading UI
         if messagebox.askyesno(_("User interface plug-in change"),
                                _("A change in plug-in class methods may have affected the menus "
                                  "of the user interface.  It may be necessary to restart Arelle to "
                                  "access the menu entries or the changes to their plug-in methods.  \n\n"
                                  "Should Arelle restart with changed user interface language, "
                                  "(if there are any unsaved changes they would be lost!)?"),
                                parent=self):
             self.cntlr.uiThreadQueue.put((self.cntlr.quit, [None, True]))
     self.close()
Example #10
0
def test_plugin_manager_reset():
    """
    Test that modulePluginInfos and pluginMethodsForClasses are cleared when close is called, pluginConfig remains unchanged
    """
    cntlr = Mock(pluginDir='some_dir')
    PluginManager.init(cntlr, loadPluginConfig=False)
    assert len(PluginManager.modulePluginInfos) == 0
    assert len(PluginManager.pluginMethodsForClasses) == 0
    PluginManager.modulePluginInfos['module'] = 'plugin_info'
    PluginManager.pluginMethodsForClasses['class'] = 'plugin_method'
    PluginManager.reset()
    assert len(PluginManager.pluginConfig) == 2
    assert len(PluginManager.modulePluginInfos) == 0
    assert len(PluginManager.pluginMethodsForClasses) == 0
    assert PluginManager._cntlr == cntlr
 def ok(self, event=None):
     if self.pluginConfigChanged:
         PluginManager.pluginConfig = self.pluginConfig
         PluginManager.pluginConfigChanged = True
         PluginManager.reset()  # force reloading of modules
     if self.uiClassMethodsChanged:  # may require reloading UI
         if messagebox.askyesno(_("User interface plug-in change"),
                                _("A change in plug-in class methods may have affected the menus "
                                  "of the user interface.  It may be necessary to restart Arelle to "
                                  "access the menu entries or the changes to their plug-in methods.  \n\n"
                                  "Should Arelle restart with changed user interface language, "
                                  "(if there are any unsaved changes they would be lost!)?"),
                                parent=self):
             self.cntlr.uiThreadQueue.put((self.cntlr.quit, [None, True]))
     self.close()
 def ok(self, event=None):
     # check for orphaned classes (for which there is no longer a corresponding module)
     _moduleNames = self.pluginConfig.get("modules", {}).keys()
     _orphanedClassNames = set()
     for className, moduleList in self.pluginConfig.get("classes", {}).items():
         for _moduleName in moduleList.copy():
             if _moduleName not in _moduleNames: # it's orphaned
                 moduleList.remove(_moduleName)
                 self.pluginConfigChanged = True
         if not moduleList: # now orphaned
             _orphanedClassNames.add(className)
             self.pluginConfigChanged = True
     for _orphanedClassName in _orphanedClassNames:
         del self.pluginConfig["classes"][_orphanedClassName]
     
     if self.pluginConfigChanged:
         PluginManager.pluginConfig = self.pluginConfig
         PluginManager.pluginConfigChanged = True
         PluginManager.reset()  # force reloading of modules
     if self.uiClassMethodsChanged or self.modelClassesChanged or self.customTransformsChanged or self.disclosureSystemTypesChanged or self.hostSystemFeaturesChanged:  # may require reloading UI
         affectedItems = ""
         if self.uiClassMethodsChanged:
             affectedItems += _("menus of the user interface")
         if self.modelClassesChanged:
             if affectedItems:
                 affectedItems += _(" and ")
             affectedItems += _("model objects of the processor")
         if self.customTransformsChanged:
             if affectedItems:
                 affectedItems += _(" and ")
             affectedItems += _("custom transforms")
         if self.disclosureSystemTypesChanged:
             if affectedItems:
                 affectedItems += _(" and ")
             affectedItems += _("disclosure system types")
         if self.hostSystemFeaturesChanged:
             if affectedItems:
                 affectedItems += _(" and ")
             affectedItems += _("host system features")
         if messagebox.askyesno(_("User interface plug-in change"),
                                _("A change in plug-in class methods may have affected {0}.  " 
                                  "Please restart Arelle to due to these changes.  \n\n"
                                  "Should Arelle restart itself now "
                                  "(if there are any unsaved changes they would be lost!)?"
                                  ).format(affectedItems),
                                parent=self):
             self.cntlr.uiThreadQueue.put((self.cntlr.quit, [None, True]))
     self.close()
Example #13
0
 def selectChoices(dir, indent=""):
     dirHasEntries = False
     for f in sorted(os.listdir(dir), key=sortOrder):
         if f not in (".", "..", "__pycache__", "__init__.py"):
             fPath = os.path.join(dir, f)
             fPkgInit = os.path.join(fPath, "__init__.py")
             dirInsertPoint = len(choices)
             moduleInfo = None
             if ((os.path.isdir(fPath) and os.path.exists(fPkgInit)) or
                 ((os.path.isfile(fPath) and f.endswith(".py")))):
                 moduleInfo = PluginManager.moduleModuleInfo(fPath)
                 if moduleInfo:
                     choices.append((
                         indent + f,
                         "name: {}\ndescription: {}\nversion: {}\nlicense: {}"
                         .format(moduleInfo["name"],
                                 moduleInfo.get("description"),
                                 moduleInfo.get("version"),
                                 moduleInfo.get("license")), fPath,
                         moduleInfo["name"], moduleInfo.get("version"),
                         moduleInfo.get("description"),
                         moduleInfo.get("license")))
                     dirHasEntries = True
             if os.path.isdir(fPath) and f not in ("DQC_US_Rules", ):
                 if selectChoices(fPath, indent=indent +
                                  "   ") and not moduleInfo:
                     choices.insert(dirInsertPoint,
                                    (indent + f, None, None, None, None,
                                     None, None))
     return dirHasEntries
Example #14
0
 def selectLocally(self):
     choices = [] # list of tuple of (file name, description)
     def sortOrder(key):
         return {"EdgarRenderer": "1",
                 "validate": "2",
                 "xbrlDB": "3"}.get(key, "4") + key.lower()
     def selectChoices(dir, indent=""):
         dirHasEntries = False
         for f in sorted(os.listdir(dir), key=sortOrder):
             if f not in (".", "..", "__pycache__", "__init__.py"):
                 fPath = os.path.join(dir, f)
                 fPkgInit = os.path.join(fPath, "__init__.py")
                 dirInsertPoint = len(choices)
                 moduleInfo = None
                 if ((os.path.isdir(fPath) and os.path.exists(fPkgInit)) or
                     ((os.path.isfile(fPath) and f.endswith(".py")))):
                     moduleInfo = PluginManager.moduleModuleInfo(fPath)
                     if moduleInfo:
                         choices.append((indent + f, 
                                         "name: {}\ndescription: {}\n version {}".format(
                                                     moduleInfo["name"],
                                                     moduleInfo["description"],
                                                     moduleInfo.get("version")), 
                                         fPath, moduleInfo["name"], moduleInfo.get("version"), moduleInfo["description"]))
                         dirHasEntries = True
                 if os.path.isdir(fPath) and f not in ("DQC_US_Rules",):
                     if selectChoices(fPath, indent=indent + "   ") and not moduleInfo:
                         choices.insert(dirInsertPoint, (indent + f,None,None,None,None,None))
         return dirHasEntries
     selectChoices(self.cntlr.pluginDir)
     selectedPath = DialogOpenArchive.selectPlugin(self, choices)
     if selectedPath:
         moduleInfo = PluginManager.moduleModuleInfo(selectedPath)
         self.loadFoundModuleInfo(moduleInfo, selectedPath)
Example #15
0
def test_plugin_manager_init_first_pass():
    """
    Test that pluginConfig is correctly setup during init on fresh pass
    """
    cntlr = Mock(pluginDir='some_dir')
    PluginManager.init(cntlr, loadPluginConfig=False)
    assert len(PluginManager.pluginConfig) == 2
    assert 'modules' in PluginManager.pluginConfig
    assert isinstance(PluginManager.pluginConfig.get('modules'), dict)
    assert len(PluginManager.pluginConfig.get('modules')) == 0
    assert 'classes' in PluginManager.pluginConfig
    assert isinstance(PluginManager.pluginConfig.get('classes'), dict)
    assert len(PluginManager.pluginConfig.get('classes')) == 0
    assert len(PluginManager.modulePluginInfos) == 0
    assert len(PluginManager.pluginMethodsForClasses) == 0
    assert PluginManager._cntlr == cntlr
Example #16
0
 def moduleReload(self):
     if self.selectedModule in self.pluginConfig["modules"]:
         url = self.pluginConfig["modules"][self.selectedModule].get("moduleURL")
         if url:
             moduleInfo = PluginManager.moduleModuleInfo(url, reload=True)
             if moduleInfo:
                 self.addPluginConfigModuleInfo(moduleInfo)
                 self.loadTreeViews()
             self.cntlr.showStatus(_("{0} reloaded").format(moduleInfo.get("name")), clearAfter=5000)
def backgroundCheckForUpdates(cntlr):
    cntlr.showStatus(_("Checking for updates to plug-ins")) # clear web loading status
    modulesWithNewerFileDates = PluginManager.modulesWithNewerFileDates()
    if modulesWithNewerFileDates:
        cntlr.showStatus(_("Updates are available for these plug-ins: {0}")
                              .format(', '.join(modulesWithNewerFileDates)), clearAfter=5000)
    else:
        cntlr.showStatus(_("No updates found for plug-ins."), clearAfter=5000)
    time.sleep(0.1) # Mac locks up without this, may be needed for empty ui queue? 
    cntlr.uiThreadQueue.put((DialogPluginManager, [cntlr, modulesWithNewerFileDates]))
Example #18
0
def backgroundCheckForUpdates(cntlr):
    cntlr.showStatus(_("Checking for updates to plug-ins")) # clear web loading status
    modulesWithNewerFileDates = PluginManager.modulesWithNewerFileDates()
    if modulesWithNewerFileDates:
        cntlr.showStatus(_("Updates are available for these plug-ins: {0}")
                              .format(', '.join(modulesWithNewerFileDates)), clearAfter=5000)
    else:
        cntlr.showStatus(_("No updates found for plug-ins."), clearAfter=5000)
    time.sleep(0.1) # Mac locks up without this, may be needed for empty ui queue? 
    cntlr.uiThreadQueue.put((DialogPluginManager, [cntlr, modulesWithNewerFileDates]))
Example #19
0
 def findLocally(self):
     filename = self.cntlr.uiFileDialog("open",
                                        owner=self,
                                        title=_("Choose plug-in module file"),
                                        initialdir=self.cntlr.config.setdefault("pluginOpenDir","."),
                                        filetypes=[(_("Python files"), "*.py")],
                                        defaultextension=".py")
     if filename:
         self.cntlr.config["pluginOpenDir"] = os.path.dirname(filename)
         moduleInfo = PluginManager.moduleModuleInfo(filename)
         self.loadFoundModuleInfo(moduleInfo, filename)
 def findLocally(self):
     filename = self.cntlr.uiFileDialog("open",
                                        owner=self,
                                        title=_("Choose plug-in module file"),
                                        initialdir=self.cntlr.config.setdefault("pluginOpenDir","."),
                                        filetypes=[(_("Python files"), "*.py")],
                                        defaultextension=".py")
     if filename:
         self.cntlr.config["pluginOpenDir"] = os.path.dirname(filename)
         moduleInfo = PluginManager.moduleModuleInfo(filename)
         self.loadFoundModuleInfo(moduleInfo, filename)
Example #21
0
 def moduleReload(self):
     if self.selectedModule in self.pluginConfig["modules"]:
         url = self.pluginConfig["modules"][self.selectedModule].get("moduleURL")
         if url:
             moduleInfo = PluginManager.moduleModuleInfo(url, reload=True)
             if moduleInfo:
                 self.addPluginConfigModuleInfo(moduleInfo)
                 self.loadTreeViews()
                 self.cntlr.showStatus(_("{0} reloaded").format(moduleInfo.get("name")), clearAfter=5000)
             else:
                 messagebox.showwarning(_("Module error"),
                                        _("File or module cannot be reloaded: \n\n{0}")
                                        .format(url),
                                        parent=self)
Example #22
0
 def findLocally(self):
     initialdir = self.cntlr.pluginDir # default plugin directory
     if not self.cntlr.isMac: # can't navigate within app easily, always start in default directory
         initialdir = self.cntlr.config.setdefault("pluginOpenDir", initialdir)
     filename = self.cntlr.uiFileDialog("open",
                                        parent=self,
                                        title=_("Choose plug-in module file"),
                                        initialdir=initialdir,
                                        filetypes=[(_("Python files"), "*.py")],
                                        defaultextension=".py")
     if filename:
         # check if a package is selected (any file in a directory containing an __init__.py
         if (os.path.isdir(os.path.dirname(filename)) and
             os.path.isfile(os.path.join(os.path.dirname(filename), "__init__.py"))):
             filename = os.path.dirname(filename) # refer to the package instead
         self.cntlr.config["pluginOpenDir"] = os.path.dirname(filename)
         moduleInfo = PluginManager.moduleModuleInfo(filename)
         self.loadFoundModuleInfo(moduleInfo, filename)
 def findLocally(self):
     initialdir = self.cntlr.pluginDir # default plugin directory
     if not self.cntlr.isMac: # can't navigate within app easily, always start in default directory
         initialdir = self.cntlr.config.setdefault("pluginOpenDir", initialdir)
     filename = self.cntlr.uiFileDialog("open",
                                        parent=self,
                                        title=_("Choose plug-in module file"),
                                        initialdir=initialdir,
                                        filetypes=[(_("Python files"), "*.py")],
                                        defaultextension=".py")
     if filename:
         # check if a package is selected (any file in a directory containing an __init__.py
         #if (os.path.basename(filename) == "__init__.py" and os.path.isdir(os.path.dirname(filename)) and
         #    os.path.isfile(filename)):
         #    filename = os.path.dirname(filename) # refer to the package instead
         self.cntlr.config["pluginOpenDir"] = os.path.dirname(filename)
         moduleInfo = PluginManager.moduleModuleInfo(filename)
         self.loadFoundModuleInfo(moduleInfo, filename)
Example #24
0
 def selectChoices(dir, indent=""):
     dirHasEntries = False
     for f in sorted(os.listdir(dir), key=sortOrder):
         if f not in (".", "..", "__pycache__", "__init__.py"):
             fPath = os.path.join(dir, f)
             fPkgInit = os.path.join(fPath, "__init__.py")
             dirInsertPoint = len(choices)
             moduleInfo = None
             if ((os.path.isdir(fPath) and os.path.exists(fPkgInit)) or
                 ((os.path.isfile(fPath) and f.endswith(".py")))):
                 moduleInfo = PluginManager.moduleModuleInfo(fPath)
                 if moduleInfo:
                     choices.append((indent + f, 
                                     "name: {}\ndescription: {}\n version {}".format(
                                                 moduleInfo["name"],
                                                 moduleInfo["description"],
                                                 moduleInfo.get("version")), 
                                     fPath, moduleInfo["name"], moduleInfo.get("version"), moduleInfo["description"]))
                     dirHasEntries = True
             if os.path.isdir(fPath) and f not in ("DQC_US_Rules",):
                 if selectChoices(fPath, indent=indent + "   ") and not moduleInfo:
                     choices.insert(dirInsertPoint, (indent + f,None,None,None,None,None))
     return dirHasEntries
                    help="URL to ixbrlviewer.js",
                    default="ixbrlviewer.js")
parser.add_argument("--out",
                    "-o",
                    help="File or directory to write output to",
                    default="viewer.html")
parser.add_argument('files',
                    metavar='FILES',
                    nargs='+',
                    help='Files to process')
args = parser.parse_args()

cntlr = CntlrCreateViewer()
cntlr.startLogging(logFileName='logToPrint',
                   logFormat="[%(messageCode)s] %(message)s - %(file)s",
                   logLevel="DEBUG",
                   logRefObjectProperties=True,
                   logToBuffer=True)
cntlr.modelManager.validateInferDecimals = True
cntlr.modelManager.validateCalcLB = True
cntlr.modelManager.formulaOptions = FormulaOptions()

PluginManager.addPluginModule("transforms/SEC")
PluginManager.addPluginModule("inlineXbrlDocumentSet")
cntlr.modelManager.loadCustomTransforms()
if args.package_dir:
    cntlr.loadPackagesFromDir(args.package_dir)

for f in args.files:
    cntlr.createViewer(f, outPath=args.out, scriptUrl=args.viewer_url)
Example #26
0
parser = argparse.ArgumentParser(description="Create iXBRL Viewer instances")
parser.add_argument("--package-dir",
                    "-p",
                    help="Path to directory containing taxonomy packages")
parser.add_argument("--viewer-url",
                    "-u",
                    help="URL to ixbrlviewer.js",
                    default="ixbrlviewer.js")
parser.add_argument("--out",
                    "-o",
                    help="File or directory to write output to",
                    default="viewer.html")
parser.add_argument('files',
                    metavar='FILES',
                    nargs='+',
                    help='Files to process')
args = parser.parse_args()

cntlr = CntlrCreateViewer()
cntlr.startLogging(logFileName='logToPrint',
                   logFormat="[%(messageCode)s] %(message)s - %(file)s",
                   logLevel="DEBUG",
                   logRefObjectProperties=True,
                   logToBuffer=False)
PluginManager.addPluginModule("inlineXbrlDocumentSet")
if args.package_dir:
    cntlr.loadPackagesFromDir(args.package_dir)

for f in args.files:
    cntlr.createViewer(f, outPath=args.out, scriptUrl=args.viewer_url)
Example #27
0
 def findOnWeb(self):
     url = DialogURL.askURL(self)
     if url:  # url is the in-cache or local file
         moduleInfo = PluginManager.moduleModuleInfo(url)
         self.cntlr.showStatus("") # clear web loading status
         self.loadFoundModuleInfo(moduleInfo, url)
Example #28
0
    def __init__(self, hasGui=False, logFileName=None, logFileMode=None, logFileEncoding=None, logFormat=None):
        self.hasWin32gui = False
        self.hasGui = hasGui
        self.hasFileSystem = True # no file system on Google App Engine servers
        self.isGAE = False
        self.systemWordSize = int(round(math.log(sys.maxsize, 2)) + 1) # e.g., 32 or 64

        self.moduleDir = os.path.dirname(__file__)
        # for python 3.2 remove __pycache__
        if self.moduleDir.endswith("__pycache__"):
            self.moduleDir = os.path.dirname(self.moduleDir)
        if self.moduleDir.endswith("python32.zip/arelle"):
            '''
            distZipFile = os.path.dirname(self.moduleDir)
            d = os.path.join(self.userAppDir, "arelle")
            self.configDir = os.path.join(d, "config")
            self.imagesDir = os.path.join(d, "images")
            import zipfile
            distZip = zipfile.ZipFile(distZipFile, mode="r")
            distNames = distZip.namelist()
            distZip.extractall(path=self.userAppDir,
                               members=[f for f in distNames if "/config/" in f or "/images/" in f]
                               )
            distZip.close()
            '''
            resources = os.path.dirname(os.path.dirname(os.path.dirname(self.moduleDir)))
            self.configDir = os.path.join(resources, "config")
            self.imagesDir = os.path.join(resources, "images")
            self.localeDir = os.path.join(resources, "locale")
            self.pluginDir = os.path.join(resources, "plugin")
        elif self.moduleDir.endswith("library.zip\\arelle") or self.moduleDir.endswith("library.zip/arelle"): # cx_Freexe
            resources = os.path.dirname(os.path.dirname(self.moduleDir))
            self.configDir = os.path.join(resources, "config")
            self.imagesDir = os.path.join(resources, "images")
            self.localeDir = os.path.join(resources, "locale")
            self.pluginDir = os.path.join(resources, "plugin")
        else:
            self.configDir = os.path.join(self.moduleDir, "config")
            self.imagesDir = os.path.join(self.moduleDir, "images")
            self.localeDir = os.path.join(self.moduleDir, "locale")
            self.pluginDir = os.path.join(self.moduleDir, "plugin")
        
        serverSoftware = os.getenv("SERVER_SOFTWARE", "")
        if serverSoftware.startswith("Google App Engine/") or serverSoftware.startswith("Development/"):
            self.hasFileSystem = False # no file system, userAppDir does not exist
            self.isGAE = True
            
        configHomeDir = None  # look for path configDir/CONFIG_HOME in argv and environment parameters
        for i, arg in enumerate(sys.argv):  # check if config specified in a argv 
            if arg.startswith("--xdgConfigHome="):
                configHomeDir = arg[16:]
                break
            elif arg == "--xdgConfigHome" and i + 1 < len(sys.argv):
                configHomeDir = sys.argv[i + 1]
                break
        if not configHomeDir: # not in argv, may be an environment parameter
            configHomeDir = os.getenv('XDG_CONFIG_HOME')
        if not configHomeDir:  # look for path configDir/CONFIG_HOME
            configHomeDirFile = os.path.join(self.configDir, "XDG_CONFIG_HOME")
            if os.path.exists(configHomeDirFile):
                try:
                    with io.open(configHomeDirFile, 'rt', encoding='utf-8') as f:
                        configHomeDir = f.read().strip()
                    if configHomeDir and not os.path.isabs(configHomeDir):
                        configHomeDir = os.path.abspath(configHomeDir)  # make into a full path if relative
                except EnvironmentError:
                    configHomeDir = None
        if self.hasFileSystem and configHomeDir and os.path.exists(configHomeDir):
            # check if a cache exists in this directory (e.g. from XPE or other tool)
            impliedAppDir = os.path.join(configHomeDir, "arelle")
            if os.path.exists(impliedAppDir):
                self.userAppDir = impliedAppDir
            elif os.path.exists(os.path.join(configHomeDir, "cache")):
                self.userAppDir = configHomeDir # use the XDG_CONFIG_HOME because cache is already a subdirectory
            else:
                self.userAppDir = impliedAppDir
        if sys.platform == "darwin":
            self.isMac = True
            self.isMSW = False
            if self.hasFileSystem and not configHomeDir:
                self.userAppDir = os.path.expanduser("~") + "/Library/Application Support/Arelle"
            # note that cache is in ~/Library/Caches/Arelle
            self.contextMenuClick = "<Button-2>"
            self.hasClipboard = hasGui  # clipboard always only if Gui (not command line mode)
            self.updateURL = "http://arelle.org/downloads/8"
        elif sys.platform.startswith("win"):
            self.isMac = False
            self.isMSW = True
            if self.hasFileSystem and not configHomeDir:
                tempDir = tempfile.gettempdir()
                if tempDir.endswith('local\\temp'):
                    impliedAppDir = tempDir[:-10] + 'local'
                else:
                    impliedAppDir = tempDir
                self.userAppDir = os.path.join( impliedAppDir, "Arelle")
            if hasGui:
                try:
                    import win32clipboard
                    self.hasClipboard = True
                except ImportError:
                    self.hasClipboard = False
                try:
                    import win32gui
                    self.hasWin32gui = True # active state for open file dialogs
                except ImportError:
                    pass
            else:
                self.hasClipboard = False
            self.contextMenuClick = "<Button-3>"
            if "64 bit" in sys.version:
                self.updateURL = "http://arelle.org/downloads/9"
            else: # 32 bit
                self.updateURL = "http://arelle.org/downloads/10"
        else: # Unix/Linux
            self.isMac = False
            self.isMSW = False
            if self.hasFileSystem and not configHomeDir:
                    self.userAppDir = os.path.join( os.path.expanduser("~/.config"), "arelle")
            if hasGui:
                try:
                    import gtk
                    self.hasClipboard = True
                except ImportError:
                    self.hasClipboard = False
            else:
                self.hasClipboard = False
            self.contextMenuClick = "<Button-3>"
        try:
            from arelle import webserver
            self.hasWebServer = True
        except ImportError:
            self.hasWebServer = False
        # assert that app dir must exist
        self.config = None
        if self.hasFileSystem:
            if not os.path.exists(self.userAppDir):
                os.makedirs(self.userAppDir)
            # load config if it exists
            self.configJsonFile = self.userAppDir + os.sep + "config.json"
            if os.path.exists(self.configJsonFile):
                try:
                    with io.open(self.configJsonFile, 'rt', encoding='utf-8') as f:
                        self.config = json.load(f)
                except Exception as ex:
                    self.config = None # restart with a new config
        if not self.config:
            self.config = {
                'fileHistory': [],
                'windowGeometry': "{0}x{1}+{2}+{3}".format(800, 500, 200, 100),                
            }
            
        # start language translation for domain
        self.setUiLanguage(self.config.get("userInterfaceLangOverride",None), fallbackToDefault=True)
            
        from arelle.WebCache import WebCache
        self.webCache = WebCache(self, self.config.get("proxySettings"))
        self.modelManager = ModelManager.initialize(self)
        
        # start plug in server (requres web cache initialized, but not logger)
        PluginManager.init(self)
 
        # start taxonomy package server (requres web cache initialized, but not logger)
        PackageManager.init(self)
 
        self.startLogging(logFileName, logFileMode, logFileEncoding, logFormat)
        
        # Cntlr.Init after logging started
        for pluginMethod in PluginManager.pluginClassMethods("Cntlr.Init"):
            pluginMethod(self)
Example #29
0
    def run(self, options, sourceZipStream=None):
        """Process command line arguments or web service request, such as to load and validate an XBRL document, or start web server.
        
        When a web server has been requested, this method may be called multiple times, once for each web service (REST) request that requires processing.
        Otherwise (when called for a command line request) this method is called only once for the command line arguments request.
           
        :param options: OptionParser options from parse_args of main argv arguments (when called from command line) or corresponding arguments from web service (REST) request.
        :type options: optparse.Values
        """
        if options.showOptions: # debug options
            for optName, optValue in sorted(options.__dict__.items(), key=lambda optItem: optItem[0]):
                self.addToLog("Option {0}={1}".format(optName, optValue), messageCode="info")
            self.addToLog("sys.argv {0}".format(sys.argv), messageCode="info")
        if options.uiLang: # set current UI Lang (but not config setting)
            self.setUiLanguage(options.uiLang)
        if options.proxy:
            if options.proxy != "show":
                proxySettings = proxyTuple(options.proxy)
                self.webCache.resetProxies(proxySettings)
                self.config["proxySettings"] = proxySettings
                self.saveConfig()
                self.addToLog(_("Proxy configuration has been set."), messageCode="info")
            useOsProxy, urlAddr, urlPort, user, password = self.config.get("proxySettings", proxyTuple("none"))
            if useOsProxy:
                self.addToLog(_("Proxy configured to use {0}.").format(
                    _('Microsoft Windows Internet Settings') if sys.platform.startswith("win")
                    else (_('Mac OS X System Configuration') if sys.platform in ("darwin", "macos")
                          else _('environment variables'))), messageCode="info")
            elif urlAddr:
                self.addToLog(_("Proxy setting: http://{0}{1}{2}{3}{4}").format(
                    user if user else "",
                    ":****" if password else "",
                    "@" if (user or password) else "",
                    urlAddr,
                    ":{0}".format(urlPort) if urlPort else ""), messageCode="info")
            else:
                self.addToLog(_("Proxy is disabled."), messageCode="info")
        if options.plugins:
            from arelle import PluginManager
            resetPlugins = False
            savePluginChanges = True
            showPluginModules = False
            for pluginCmd in options.plugins.split('|'):
                cmd = pluginCmd.strip()
                if cmd == "show":
                    showPluginModules = True
                elif cmd == "temp":
                    savePluginChanges = False
                elif cmd.startswith("+"):
                    moduleInfo = PluginManager.addPluginModule(cmd[1:])
                    if moduleInfo:
                        self.addToLog(_("Addition of plug-in {0} successful.").format(moduleInfo.get("name")), 
                                      messageCode="info", file=moduleInfo.get("moduleURL"))
                        resetPlugins = True
                    else:
                        self.addToLog(_("Unable to load plug-in."), messageCode="info", file=cmd[1:])
                elif cmd.startswith("~"):
                    if PluginManager.reloadPluginModule(cmd[1:]):
                        self.addToLog(_("Reload of plug-in successful."), messageCode="info", file=cmd[1:])
                        resetPlugins = True
                    else:
                        self.addToLog(_("Unable to reload plug-in."), messageCode="info", file=cmd[1:])
                elif cmd.startswith("-"):
                    if PluginManager.removePluginModule(cmd[1:]):
                        self.addToLog(_("Deletion of plug-in successful."), messageCode="info", file=cmd[1:])
                        resetPlugins = True
                    else:
                        self.addToLog(_("Unable to delete plug-in."), messageCode="info", file=cmd[1:])
                else: # assume it is a module or package
                    savePluginChanges = False
                    moduleInfo = PluginManager.addPluginModule(cmd)
                    if moduleInfo:
                        self.addToLog(_("Activation of plug-in {0} successful.").format(moduleInfo.get("name")), 
                                      messageCode="info", file=moduleInfo.get("moduleURL"))
                        resetPlugins = True
                    else:
                        self.addToLog(_("Unable to load {0} as a plug-in or {0} is not recognized as a command. ").format(cmd), messageCode="info", file=cmd)
                if resetPlugins:
                    PluginManager.reset()
                    if savePluginChanges:
                        PluginManager.save(self)
            if showPluginModules:
                self.addToLog(_("Plug-in modules:"), messageCode="info")
                for i, moduleItem in enumerate(sorted(PluginManager.pluginConfig.get("modules", {}).items())):
                    moduleInfo = moduleItem[1]
                    self.addToLog(_("Plug-in: {0}; author: {1}; version: {2}; status: {3}; date: {4}; description: {5}; license {6}.").format(
                                  moduleItem[0], moduleInfo.get("author"), moduleInfo.get("version"), moduleInfo.get("status"),
                                  moduleInfo.get("fileDate"), moduleInfo.get("description"), moduleInfo.get("license")),
                                  messageCode="info", file=moduleInfo.get("moduleURL"))
                
        # run utility command line options that don't depend on entrypoint Files
        hasUtilityPlugin = False
        for pluginXbrlMethod in pluginClassMethods("CntlrCmdLine.Utility.Run"):
            hasUtilityPlugin = True
            pluginXbrlMethod(self, options)
            
        # if no entrypointFile is applicable, quit now
        if options.proxy or options.plugins or hasUtilityPlugin:
            if not options.entrypointFile:
                return True # success
        self.username = options.username
        self.password = options.password
        self.entrypointFile = options.entrypointFile
        if self.entrypointFile:
            filesource = FileSource.openFileSource(self.entrypointFile, self, sourceZipStream)
        else:
            filesource = None
        if options.validateEFM:
            if options.disclosureSystemName:
                self.addToLog(_("both --efm and --disclosureSystem validation are requested, proceeding with --efm only"),
                              messageCode="info", file=self.entrypointFile)
            self.modelManager.validateDisclosureSystem = True
            self.modelManager.disclosureSystem.select("efm")
        elif options.disclosureSystemName:
            self.modelManager.validateDisclosureSystem = True
            self.modelManager.disclosureSystem.select(options.disclosureSystemName)
        elif options.validateHMRC:
            self.modelManager.validateDisclosureSystem = True
            self.modelManager.disclosureSystem.select("hmrc")
        else:
            self.modelManager.disclosureSystem.select(None) # just load ordinary mappings
            self.modelManager.validateDisclosureSystem = False
        if options.utrUrl:  # override disclosureSystem utrUrl
            self.modelManager.disclosureSystem.utrUrl = options.utrUrl
            # can be set now because the utr is first loaded at validation time 
            
        # disclosure system sets logging filters, override disclosure filters, if specified by command line
        if options.logLevelFilter:
            self.setLogLevelFilter(options.logLevelFilter)
        if options.logCodeFilter:
            self.setLogCodeFilter(options.logCodeFilter)
        if options.calcDecimals:
            if options.calcPrecision:
                self.addToLog(_("both --calcDecimals and --calcPrecision validation are requested, proceeding with --calcDecimals only"),
                              messageCode="info", file=self.entrypointFile)
            self.modelManager.validateInferDecimals = True
            self.modelManager.validateCalcLB = True
        elif options.calcPrecision:
            self.modelManager.validateInferDecimals = False
            self.modelManager.validateCalcLB = True
        if options.utrValidate:
            self.modelManager.validateUtr = True
        if options.infosetValidate:
            self.modelManager.validateInfoset = True
        if options.abortOnMajorError:
            self.modelManager.abortOnMajorError = True
        if options.collectProfileStats:
            self.modelManager.collectProfileStats = True
        if options.internetConnectivity == "offline":
            self.webCache.workOffline = True
        elif options.internetConnectivity == "online":
            self.webCache.workOffline = False
        if options.internetTimeout is not None:
            self.webCache.timeout = (options.internetTimeout or None)  # use None if zero specified to disable timeout
        fo = FormulaOptions()
        if options.parameters:
            parameterSeparator = (options.parameterSeparator or ',')
            fo.parameterValues = dict(((qname(key, noPrefixIsNoNamespace=True),(None,value)) 
                                       for param in options.parameters.split(parameterSeparator) 
                                       for key,sep,value in (param.partition('='),) ) )   
        if options.formulaParamExprResult:
            fo.traceParameterExpressionResult = True
        if options.formulaParamInputValue:
            fo.traceParameterInputValue = True
        if options.formulaCallExprSource:
            fo.traceCallExpressionSource = True
        if options.formulaCallExprCode:
            fo.traceCallExpressionCode = True
        if options.formulaCallExprEval:
            fo.traceCallExpressionEvaluation = True
        if options.formulaCallExprResult:
            fo.traceCallExpressionResult = True
        if options.formulaVarSetExprEval:
            fo.traceVariableSetExpressionEvaluation = True
        if options.formulaVarSetExprResult:
            fo.traceVariableSetExpressionResult = True
        if options.formulaAsserResultCounts:
            fo.traceAssertionResultCounts = True
        if options.formulaFormulaRules:
            fo.traceFormulaRules = True
        if options.formulaVarsOrder:
            fo.traceVariablesOrder = True
        if options.formulaVarExpressionSource:
            fo.traceVariableExpressionSource = True
        if options.formulaVarExpressionCode:
            fo.traceVariableExpressionCode = True
        if options.formulaVarExpressionEvaluation:
            fo.traceVariableExpressionEvaluation = True
        if options.formulaVarExpressionResult:
            fo.traceVariableExpressionResult = True
        if options.timeVariableSetEvaluation:
            fo.timeVariableSetEvaluation = True
        if options.formulaVarFilterWinnowing:
            fo.traceVariableFilterWinnowing = True
        if options.formulaVarFiltersResult:
            fo.traceVariableFiltersResult = True
        if options.formulaVarFiltersResult:
            fo.traceVariableFiltersResult = True
        self.modelManager.formulaOptions = fo
        timeNow = XmlUtil.dateunionValue(datetime.datetime.now())
        firstStartedAt = startedAt = time.time()
        modelDiffReport = None
        success = True
        modelXbrl = None
        try:
            if filesource:
                modelXbrl = self.modelManager.load(filesource, _("views loading"))
        except ModelDocument.LoadingException:
            pass
        except Exception as err:
            self.addToLog(_("[Exception] Failed to complete request: \n{0} \n{1}").format(
                        err,
                        traceback.format_tb(sys.exc_info()[2])))
            success = False    # loading errors, don't attempt to utilize loaded DTS
        if modelXbrl and modelXbrl.modelDocument:
            loadTime = time.time() - startedAt
            modelXbrl.profileStat(_("load"), loadTime)
            self.addToLog(format_string(self.modelManager.locale, 
                                        _("loaded in %.2f secs at %s"), 
                                        (loadTime, timeNow)), 
                                        messageCode="info", file=self.entrypointFile)
            if options.importFiles:
                for importFile in options.importFiles.split("|"):
                    fileName = importFile.strip()
                    if sourceZipStream is not None and not (fileName.startswith('http://') or os.path.isabs(fileName)):
                        fileName = os.path.dirname(modelXbrl.uri) + os.sep + fileName # make relative to sourceZipStream
                    ModelDocument.load(modelXbrl, fileName)
                    loadTime = time.time() - startedAt
                    self.addToLog(format_string(self.modelManager.locale, 
                                                _("import in %.2f secs at %s"), 
                                                (loadTime, timeNow)), 
                                                messageCode="info", file=importFile)
                    modelXbrl.profileStat(_("import"), loadTime)
                if modelXbrl.errors:
                    success = False    # loading errors, don't attempt to utilize loaded DTS
            if modelXbrl.modelDocument.type in ModelDocument.Type.TESTCASETYPES:
                for pluginXbrlMethod in pluginClassMethods("Testcases.Start"):
                    pluginXbrlMethod(self, options, modelXbrl)
            else: # not a test case, probably instance or DTS
                for pluginXbrlMethod in pluginClassMethods("CntlrCmdLine.Xbrl.Loaded"):
                    pluginXbrlMethod(self, options, modelXbrl)
        else:
            success = False
        if success and options.diffFile and options.versReportFile:
            try:
                diffFilesource = FileSource.FileSource(options.diffFile,self)
                startedAt = time.time()
                modelXbrl2 = self.modelManager.load(diffFilesource, _("views loading"))
                if modelXbrl2.errors:
                    if not options.keepOpen:
                        modelXbrl2.close()
                    success = False
                else:
                    loadTime = time.time() - startedAt
                    modelXbrl.profileStat(_("load"), loadTime)
                    self.addToLog(format_string(self.modelManager.locale, 
                                                _("diff comparison DTS loaded in %.2f secs"), 
                                                loadTime), 
                                                messageCode="info", file=self.entrypointFile)
                    startedAt = time.time()
                    modelDiffReport = self.modelManager.compareDTSes(options.versReportFile)
                    diffTime = time.time() - startedAt
                    modelXbrl.profileStat(_("diff"), diffTime)
                    self.addToLog(format_string(self.modelManager.locale, 
                                                _("compared in %.2f secs"), 
                                                diffTime), 
                                                messageCode="info", file=self.entrypointFile)
            except ModelDocument.LoadingException:
                success = False
            except Exception as err:
                success = False
                self.addToLog(_("[Exception] Failed to doad diff file: \n{0} \n{1}").format(
                            err,
                            traceback.format_tb(sys.exc_info()[2])))
        if success:
            try:
                modelXbrl = self.modelManager.modelXbrl
                hasFormulae = modelXbrl.hasFormulae
                if options.validate:
                    startedAt = time.time()
                    if options.formulaAction: # don't automatically run formulas
                        modelXbrl.hasFormulae = False
                    self.modelManager.validate()
                    if options.formulaAction: # restore setting
                        modelXbrl.hasFormulae = hasFormulae
                    self.addToLog(format_string(self.modelManager.locale, 
                                                _("validated in %.2f secs"), 
                                                time.time() - startedAt),
                                                messageCode="info", file=self.entrypointFile)
                if options.formulaAction in ("validate", "run"):  # do nothing here if "none"
                    from arelle import ValidateXbrlDimensions, ValidateFormula
                    startedAt = time.time()
                    if not options.validate:
                        ValidateXbrlDimensions.loadDimensionDefaults(modelXbrl)
                    # setup fresh parameters from formula optoins
                    modelXbrl.parameters = fo.typedParameters()
                    ValidateFormula.validate(modelXbrl, compileOnly=(options.formulaAction != "run"))
                    self.addToLog(format_string(self.modelManager.locale, 
                                                _("formula validation and execution in %.2f secs")
                                                if options.formulaAction == "run"
                                                else _("formula validation only in %.2f secs"), 
                                                time.time() - startedAt),
                                                messageCode="info", file=self.entrypointFile)
                    

                if options.testReport:
                    ViewFileTests.viewTests(self.modelManager.modelXbrl, options.testReport, options.testReportCols)
                    
                if options.rssReport:
                    ViewFileRssFeed.viewRssFeed(self.modelManager.modelXbrl, options.rssReport, options.rssReportCols)
                    
                if options.DTSFile:
                    ViewFileDTS.viewDTS(modelXbrl, options.DTSFile)
                if options.factsFile:
                    ViewFileFactList.viewFacts(modelXbrl, options.factsFile, labelrole=options.labelRole, lang=options.labelLang, cols=options.factListCols)
                if options.factTableFile:
                    ViewFileFactTable.viewFacts(modelXbrl, options.factTableFile, labelrole=options.labelRole, lang=options.labelLang)
                if options.conceptsFile:
                    ViewFileConcepts.viewConcepts(modelXbrl, options.conceptsFile, labelrole=options.labelRole, lang=options.labelLang)
                if options.preFile:
                    ViewFileRelationshipSet.viewRelationshipSet(modelXbrl, options.preFile, "Presentation Linkbase", "http://www.xbrl.org/2003/arcrole/parent-child", labelrole=options.labelRole, lang=options.labelLang)
                if options.calFile:
                    ViewFileRelationshipSet.viewRelationshipSet(modelXbrl, options.calFile, "Calculation Linkbase", "http://www.xbrl.org/2003/arcrole/summation-item", labelrole=options.labelRole, lang=options.labelLang)
                if options.dimFile:
                    ViewFileRelationshipSet.viewRelationshipSet(modelXbrl, options.dimFile, "Dimensions", "XBRL-dimensions", labelrole=options.labelRole, lang=options.labelLang)
                if options.formulaeFile:
                    ViewFileFormulae.viewFormulae(modelXbrl, options.formulaeFile, "Formulae", lang=options.labelLang)
                if options.viewArcrole and options.viewFile:
                    ViewFileRelationshipSet.viewRelationshipSet(modelXbrl, options.viewFile, os.path.basename(options.viewArcrole), options.viewArcrole, labelrole=options.labelRole, lang=options.labelLang)
                for pluginXbrlMethod in pluginClassMethods("CntlrCmdLine.Xbrl.Run"):
                    pluginXbrlMethod(self, options, modelXbrl)
                                        
            except (IOError, EnvironmentError) as err:
                self.addToLog(_("[IOError] Failed to save output:\n {0}").format(err))
                success = False
            except Exception as err:
                self.addToLog(_("[Exception] Failed to complete request: \n{0} \n{1}").format(
                            err,
                            traceback.format_tb(sys.exc_info()[2])))
                success = False
        if modelXbrl:
            modelXbrl.profileStat(_("total"), time.time() - firstStartedAt)
            if options.collectProfileStats and modelXbrl:
                modelXbrl.logProfileStats()
            if not options.keepOpen:
                if modelDiffReport:
                    self.modelManager.close(modelDiffReport)
                elif modelXbrl:
                    self.modelManager.close(modelXbrl)
        self.username = self.password = None #dereference password
        return success
Example #30
0
    def __init__(self, logFileName=None, logFileMode=None, logFileEncoding=None, logFormat=None):
        self.hasWin32gui = False
        self.hasGui = False
        if sys.platform == "darwin":
            self.isMac = True
            self.isMSW = False
            self.userAppDir = os.path.expanduser("~") + "/Library/Application Support/Arelle"
            self.contextMenuClick = "<Button-2>"
            self.hasClipboard = True
            self.updateURL = "http://arelle.org/downloads/8"
        elif sys.platform.startswith("win"):
            self.isMac = False
            self.isMSW = True
            tempDir = tempfile.gettempdir()
            if tempDir.endswith('local\\temp'):
                self.userAppDir = tempDir[:-10] + 'local\\Arelle'
            else:
                self.userAppDir = tempDir + os.sep + 'arelle'
            try:
                import win32clipboard
                self.hasClipboard = True
            except ImportError:
                self.hasClipboard = False
            try:
                import win32gui
                self.hasWin32gui = True # active state for open file dialogs
            except ImportError:
                pass
            self.contextMenuClick = "<Button-3>"
            if "64 bit" in sys.version:
                self.updateURL = "http://arelle.org/downloads/9"
            else: # 32 bit
                self.updateURL = "http://arelle.org/downloads/10"
        else: # Unix/Linux
            self.isMac = False
            self.isMSW = False
            self.userAppDir = os.path.join(
                   os.getenv('XDG_CONFIG_HOME', os.path.expanduser("~/.config")),
                   "arelle")
            try:
                import gtk
                self.hasClipboard = True
            except ImportError:
                self.hasClipboard = False
            self.contextMenuClick = "<Button-3>"
        self.moduleDir = os.path.dirname(__file__)
        # for python 3.2 remove __pycache__
        if self.moduleDir.endswith("__pycache__"):
            self.moduleDir = os.path.dirname(self.moduleDir)
        if self.moduleDir.endswith("python32.zip/arelle"):
            '''
            distZipFile = os.path.dirname(self.moduleDir)
            d = os.path.join(self.userAppDir, "arelle")
            self.configDir = os.path.join(d, "config")
            self.imagesDir = os.path.join(d, "images")
            import zipfile
            distZip = zipfile.ZipFile(distZipFile, mode="r")
            distNames = distZip.namelist()
            distZip.extractall(path=self.userAppDir,
                               members=[f for f in distNames if "/config/" in f or "/images/" in f]
                               )
            distZip.close()
            '''
            resources = os.path.dirname(os.path.dirname(os.path.dirname(self.moduleDir)))
            self.configDir = os.path.join(resources, "config")
            self.imagesDir = os.path.join(resources, "images")
            self.localeDir = os.path.join(resources, "locale")
        elif self.moduleDir.endswith("library.zip\\arelle") or self.moduleDir.endswith("library.zip/arelle"): # cx_Freexe
            resources = os.path.dirname(os.path.dirname(self.moduleDir))
            self.configDir = os.path.join(resources, "config")
            self.imagesDir = os.path.join(resources, "images")
            self.localeDir = os.path.join(resources, "locale")
        else:
            self.configDir = os.path.join(self.moduleDir, "config")
            self.imagesDir = os.path.join(self.moduleDir, "images")
            self.localeDir = os.path.join(self.moduleDir, "locale")
        try:
            from arelle import webserver
            self.hasWebServer = True
        except ImportError:
            self.hasWebServer = False
        # assert that app dir must exist
        if not os.path.exists(self.userAppDir):
            os.makedirs(self.userAppDir)
        # load config if it exists
        self.configJsonFile = self.userAppDir + os.sep + "config.json"
        self.config = None
        if os.path.exists(self.configJsonFile):
            try:
                with io.open(self.configJsonFile, 'rt', encoding='utf-8') as f:
                    self.config = json.load(f)
            except Exception as ex:
                self.config = None # restart with a new config
        if not self.config:
            self.config = {
                'fileHistory': [],
                'windowGeometry': "{0}x{1}+{2}+{3}".format(800, 500, 200, 100),                
            }
            
        # start language translation for domain
        try:
            gettext.translation("arelle", 
                                self.localeDir, 
                                getLanguageCodes(self.config.get("userInterfaceLangOverride",None))).install()
        except Exception as msg:
            gettext.install("arelle", 
                            self.localeDir)
            
        from arelle.WebCache import WebCache
        self.webCache = WebCache(self, self.config.get("proxySettings"))
        self.modelManager = ModelManager.initialize(self)
        
        # start plug in server (requres web cache initialized
        PluginManager.init(self)
 
        self.startLogging(logFileName, logFileMode, logFileEncoding, logFormat)
Example #31
0
    def __init__(self, logFileName=None, logFileMode=None, logFileEncoding=None, logFormat=None):
        self.hasWin32gui = False
        self.hasGui = False
        if sys.platform == "darwin":
            self.isMac = True
            self.isMSW = False
            self.userAppDir = os.path.expanduser("~") + "/Library/Application Support/Arelle"
            self.contextMenuClick = "<Button-2>"
            self.hasClipboard = True
            self.updateURL = "http://arelle.org/downloads/8"
        elif sys.platform.startswith("win"):
            self.isMac = False
            self.isMSW = True
            tempDir = tempfile.gettempdir()
            if tempDir.endswith('local\\temp'):
                impliedAppDir = tempDir[:-10] + 'local'
            else:
                impliedAppDir = tempDir
            self.userAppDir = os.path.join(
                   os.getenv('XDG_CONFIG_HOME', impliedAppDir),
                   "Arelle")
            try:
                import win32clipboard
                self.hasClipboard = True
            except ImportError:
                self.hasClipboard = False
            try:
                import win32gui
                self.hasWin32gui = True # active state for open file dialogs
            except ImportError:
                pass
            self.contextMenuClick = "<Button-3>"
            if "64 bit" in sys.version:
                self.updateURL = "http://arelle.org/downloads/9"
            else: # 32 bit
                self.updateURL = "http://arelle.org/downloads/10"
        else: # Unix/Linux
            self.isMac = False
            self.isMSW = False
            self.userAppDir = os.path.join(
                   os.getenv('XDG_CONFIG_HOME', os.path.expanduser("~/.config")),
                   "arelle")
            try:
                import gtk
                self.hasClipboard = True
            except ImportError:
                self.hasClipboard = False
            self.contextMenuClick = "<Button-3>"
        self.moduleDir = os.path.dirname(__file__)
        # for python 3.2 remove __pycache__
        if self.moduleDir.endswith("__pycache__"):
            self.moduleDir = os.path.dirname(self.moduleDir)
        if self.moduleDir.endswith("python32.zip/arelle"):
            '''
            distZipFile = os.path.dirname(self.moduleDir)
            d = os.path.join(self.userAppDir, "arelle")
            self.configDir = os.path.join(d, "config")
            self.imagesDir = os.path.join(d, "images")
            import zipfile
            distZip = zipfile.ZipFile(distZipFile, mode="r")
            distNames = distZip.namelist()
            distZip.extractall(path=self.userAppDir,
                               members=[f for f in distNames if "/config/" in f or "/images/" in f]
                               )
            distZip.close()
            '''
            resources = os.path.dirname(os.path.dirname(os.path.dirname(self.moduleDir)))
            self.configDir = os.path.join(resources, "config")
            self.imagesDir = os.path.join(resources, "images")
            self.localeDir = os.path.join(resources, "locale")
        elif self.moduleDir.endswith("library.zip\\arelle") or self.moduleDir.endswith("library.zip/arelle"): # cx_Freexe
            resources = os.path.dirname(os.path.dirname(self.moduleDir))
            self.configDir = os.path.join(resources, "config")
            self.imagesDir = os.path.join(resources, "images")
            self.localeDir = os.path.join(resources, "locale")
        else:
            self.configDir = os.path.join(self.moduleDir, "config")
            self.imagesDir = os.path.join(self.moduleDir, "images")
            self.localeDir = os.path.join(self.moduleDir, "locale")
        try:
            from arelle import webserver
            self.hasWebServer = True
        except ImportError:
            self.hasWebServer = False
        # assert that app dir must exist
        if not os.path.exists(self.userAppDir):
            os.makedirs(self.userAppDir)
        # load config if it exists
        self.configJsonFile = self.userAppDir + os.sep + "config.json"
        self.config = None
        if os.path.exists(self.configJsonFile):
            try:
                with io.open(self.configJsonFile, 'rt', encoding='utf-8') as f:
                    self.config = json.load(f)
            except Exception as ex:
                self.config = None # restart with a new config
        if not self.config:
            self.config = {
                'fileHistory': [],
                'windowGeometry': "{0}x{1}+{2}+{3}".format(800, 500, 200, 100),                
            }
            
        # start language translation for domain
        self.setUiLanguage(self.config.get("userInterfaceLangOverride",None), fallbackToDefault=True)
            
        from arelle.WebCache import WebCache
        self.webCache = WebCache(self, self.config.get("proxySettings"))
        self.modelManager = ModelManager.initialize(self)
        
        # start plug in server (requres web cache initialized
        PluginManager.init(self)
 
        self.startLogging(logFileName, logFileMode, logFileEncoding, logFormat)
Example #32
0
    def __init__(self,
                 hasGui=False,
                 logFileName=None,
                 logFileMode=None,
                 logFileEncoding=None,
                 logFormat=None):
        self.hasWin32gui = False
        self.hasGui = hasGui
        self.hasFileSystem = True  # no file system on Google App Engine servers

        self.moduleDir = os.path.dirname(__file__)
        # for python 3.2 remove __pycache__
        if self.moduleDir.endswith("__pycache__"):
            self.moduleDir = os.path.dirname(self.moduleDir)
        if self.moduleDir.endswith("python32.zip/arelle"):
            '''
            distZipFile = os.path.dirname(self.moduleDir)
            d = os.path.join(self.userAppDir, "arelle")
            self.configDir = os.path.join(d, "config")
            self.imagesDir = os.path.join(d, "images")
            import zipfile
            distZip = zipfile.ZipFile(distZipFile, mode="r")
            distNames = distZip.namelist()
            distZip.extractall(path=self.userAppDir,
                               members=[f for f in distNames if "/config/" in f or "/images/" in f]
                               )
            distZip.close()
            '''
            resources = os.path.dirname(
                os.path.dirname(os.path.dirname(self.moduleDir)))
            self.configDir = os.path.join(resources, "config")
            self.imagesDir = os.path.join(resources, "images")
            self.localeDir = os.path.join(resources, "locale")
            self.pluginDir = os.path.join(resources, "plugin")
        elif self.moduleDir.endswith(
                "library.zip\\arelle") or self.moduleDir.endswith(
                    "library.zip/arelle"):  # cx_Freexe
            resources = os.path.dirname(os.path.dirname(self.moduleDir))
            self.configDir = os.path.join(resources, "config")
            self.imagesDir = os.path.join(resources, "images")
            self.localeDir = os.path.join(resources, "locale")
            self.pluginDir = os.path.join(resources, "plugin")
        else:
            self.configDir = os.path.join(self.moduleDir, "config")
            self.imagesDir = os.path.join(self.moduleDir, "images")
            self.localeDir = os.path.join(self.moduleDir, "locale")
            self.pluginDir = os.path.join(self.moduleDir, "plugin")

        configHomeDir = os.getenv('XDG_CONFIG_HOME')
        if not configHomeDir:  # look for path configDir/CONFIG_HOME
            configHomeDirFile = os.path.join(self.configDir, "XDG_CONFIG_HOME")
            if os.path.exists(configHomeDirFile):
                try:
                    with io.open(configHomeDirFile, 'rt',
                                 encoding='utf-8') as f:
                        configHomeDir = f.read().strip()
                    if configHomeDir and not os.path.isabs(configHomeDir):
                        configHomeDir = os.path.abspath(
                            configHomeDir)  # make into a full path if relative
                except EnvironmentError:
                    configHomeDir = None
        if configHomeDir and os.path.exists(configHomeDir):
            # check if a cache exists in this directory (e.g. from XPE or other tool)
            impliedAppDir = os.path.join(configHomeDir, "arelle")
            if os.path.exists(impliedAppDir):
                self.userAppDir = impliedAppDir
            elif os.path.exists(os.path.join(configHomeDir, "cache")):
                self.userAppDir = configHomeDir  # use the XDG_CONFIG_HOME because cache is already a subdirectory
            else:
                self.userAppDir = impliedAppDir
        if sys.platform == "darwin":
            self.isMac = True
            self.isMSW = False
            self.isGAE = False
            if not configHomeDir:
                self.userAppDir = os.path.expanduser(
                    "~") + "/Library/Application Support/Arelle"
            # note that cache is in ~/Library/Caches/Arelle
            self.contextMenuClick = "<Button-2>"
            self.hasClipboard = hasGui  # clipboard always only if Gui (not command line mode)
            self.updateURL = "http://arelle.org/downloads/8"
        elif sys.platform.startswith("win"):
            self.isMac = False
            self.isMSW = True
            self.isGAE = False
            if not configHomeDir:
                tempDir = tempfile.gettempdir()
                if tempDir.endswith('local\\temp'):
                    impliedAppDir = tempDir[:-10] + 'local'
                else:
                    impliedAppDir = tempDir
                self.userAppDir = os.path.join(impliedAppDir, "Arelle")
            if hasGui:
                try:
                    import win32clipboard
                    self.hasClipboard = True
                except ImportError:
                    self.hasClipboard = False
                try:
                    import win32gui
                    self.hasWin32gui = True  # active state for open file dialogs
                except ImportError:
                    pass
            else:
                self.hasClipboard = False
            self.contextMenuClick = "<Button-3>"
            if "64 bit" in sys.version:
                self.updateURL = "http://arelle.org/downloads/9"
            else:  # 32 bit
                self.updateURL = "http://arelle.org/downloads/10"
        else:  # Unix/Linux
            self.isMac = False
            self.isMSW = False
            serverSoftware = os.getenv("SERVER_SOFTWARE", "")
            if serverSoftware.startswith(
                    "Google App Engine/") or serverSoftware.startswith(
                        "Development/"):
                self.hasFileSystem = False  # no file system, userAppDir does not exist
                self.isGAE = True
            elif not configHomeDir:
                self.userAppDir = os.path.join(os.path.expanduser("~/.config"),
                                               "arelle")
                self.isGAE = False
            if hasGui:
                try:
                    import gtk
                    self.hasClipboard = True
                except ImportError:
                    self.hasClipboard = False
            else:
                self.hasClipboard = False
            self.contextMenuClick = "<Button-3>"
        try:
            from arelle import webserver
            self.hasWebServer = True
        except ImportError:
            self.hasWebServer = False
        # assert that app dir must exist
        self.config = None
        if self.hasFileSystem:
            if not os.path.exists(self.userAppDir):
                os.makedirs(self.userAppDir)
            # load config if it exists
            self.configJsonFile = self.userAppDir + os.sep + "config.json"
            if os.path.exists(self.configJsonFile):
                try:
                    with io.open(self.configJsonFile, 'rt',
                                 encoding='utf-8') as f:
                        self.config = json.load(f)
                except Exception as ex:
                    self.config = None  # restart with a new config
        if not self.config:
            self.config = {
                'fileHistory': [],
                'windowGeometry': "{0}x{1}+{2}+{3}".format(800, 500, 200, 100),
            }

        # start language translation for domain
        self.setUiLanguage(self.config.get("userInterfaceLangOverride", None),
                           fallbackToDefault=True)

        from arelle.WebCache import WebCache
        self.webCache = WebCache(self, self.config.get("proxySettings"))
        self.modelManager = ModelManager.initialize(self)

        # start plug in server (requres web cache initialized, but not logger)
        PluginManager.init(self)

        self.startLogging(logFileName, logFileMode, logFileEncoding, logFormat)

        # Cntlr.Init after logging started
        for pluginMethod in PluginManager.pluginClassMethods("Cntlr.Init"):
            pluginMethod(self)
 def findOnWeb(self):
     url = DialogURL.askURL(self)
     if url:  # url is the in-cache or local file
         moduleInfo = PluginManager.moduleModuleInfo(url)
         self.cntlr.showStatus("") # clear web loading status
         self.loadFoundModuleInfo(moduleInfo, url)
Example #34
0
    def __init__(self,
                 hasGui=False,
                 logFileName=None,
                 logFileMode=None,
                 logFileEncoding=None,
                 logFormat=None):
        self.hasWin32gui = False
        self.hasGui = hasGui
        self.hasFileSystem = True  # no file system on Google App Engine servers
        self.isGAE = False
        self.isCGI = False
        self.systemWordSize = int(round(math.log(sys.maxsize, 2)) +
                                  1)  # e.g., 32 or 64

        _resourcesDir = resourcesDir()
        self.configDir = os.path.join(_resourcesDir, "config")
        self.imagesDir = os.path.join(_resourcesDir, "images")
        self.localeDir = os.path.join(_resourcesDir, "locale")
        self.pluginDir = os.path.join(_resourcesDir, "plugin")
        _mplDir = os.path.join(_resourcesDir, "mpl-data")
        if os.path.exists(
                _mplDir
        ):  # set matplotlibdata for cx_Freeze with local directory
            os.environ["MATPLOTLIBDATA"] = _mplDir

        serverSoftware = os.getenv("SERVER_SOFTWARE", "")
        if serverSoftware.startswith(
                "Google App Engine/") or serverSoftware.startswith(
                    "Development/"):
            self.hasFileSystem = False  # no file system, userAppDir does not exist
            self.isGAE = True
        else:
            gatewayInterface = os.getenv("GATEWAY_INTERFACE", "")
            if gatewayInterface.startswith("CGI/"):
                self.isCGI = True

        configHomeDir = None  # look for path configDir/CONFIG_HOME in argv and environment parameters
        for i, arg in enumerate(
                sys.argv):  # check if config specified in a argv
            if arg.startswith("--xdgConfigHome="):
                configHomeDir = arg[16:]
                break
            elif arg == "--xdgConfigHome" and i + 1 < len(sys.argv):
                configHomeDir = sys.argv[i + 1]
                break
        if not configHomeDir:  # not in argv, may be an environment parameter
            configHomeDir = os.getenv('XDG_CONFIG_HOME')
        if not configHomeDir:  # look for path configDir/CONFIG_HOME
            configHomeDirFile = os.path.join(self.configDir, "XDG_CONFIG_HOME")
            if os.path.exists(configHomeDirFile):
                try:
                    with io.open(configHomeDirFile, 'rt',
                                 encoding='utf-8') as f:
                        configHomeDir = f.read().strip()
                    if configHomeDir and not os.path.isabs(configHomeDir):
                        configHomeDir = os.path.abspath(
                            configHomeDir)  # make into a full path if relative
                except EnvironmentError:
                    configHomeDir = None
        if self.hasFileSystem and configHomeDir and os.path.exists(
                configHomeDir):
            # check if a cache exists in this directory (e.g. from XPE or other tool)
            impliedAppDir = os.path.join(configHomeDir, "arelle")
            if os.path.exists(impliedAppDir):
                self.userAppDir = impliedAppDir
            elif os.path.exists(os.path.join(configHomeDir, "cache")):
                self.userAppDir = configHomeDir  # use the XDG_CONFIG_HOME because cache is already a subdirectory
            else:
                self.userAppDir = impliedAppDir
        if sys.platform == "darwin":
            self.isMac = True
            self.isMSW = False
            if self.hasFileSystem and not configHomeDir:
                self.userAppDir = os.path.expanduser(
                    "~") + "/Library/Application Support/Arelle"
            # note that cache is in ~/Library/Caches/Arelle
            self.contextMenuClick = "<Button-2>"
            self.hasClipboard = hasGui  # clipboard always only if Gui (not command line mode)
            self.updateURL = "http://arelle.org/downloads/8"
        elif sys.platform.startswith("win"):
            self.isMac = False
            self.isMSW = True
            if self.hasFileSystem and not configHomeDir:
                tempDir = tempfile.gettempdir()
                if tempDir.lower().endswith('local\\temp'):
                    impliedAppDir = tempDir[:-10] + 'local'
                else:
                    impliedAppDir = tempDir
                self.userAppDir = os.path.join(impliedAppDir, "Arelle")
            if hasGui:
                try:
                    import win32clipboard
                    self.hasClipboard = True
                except ImportError:
                    self.hasClipboard = False
                try:
                    import win32gui
                    self.hasWin32gui = True  # active state for open file dialogs
                except ImportError:
                    pass
            else:
                self.hasClipboard = False
            self.contextMenuClick = "<Button-3>"
            if "64 bit" in sys.version:
                self.updateURL = "http://arelle.org/downloads/9"
            else:  # 32 bit
                self.updateURL = "http://arelle.org/downloads/10"
        else:  # Unix/Linux
            self.isMac = False
            self.isMSW = False
            if self.hasFileSystem and not configHomeDir:
                self.userAppDir = os.path.join(os.path.expanduser("~/.config"),
                                               "arelle")
            if hasGui:
                try:
                    import gtk
                    self.hasClipboard = True
                except ImportError:
                    self.hasClipboard = False
            else:
                self.hasClipboard = False
            self.contextMenuClick = "<Button-3>"
        try:
            from arelle import webserver
            self.hasWebServer = True
        except ImportError:
            self.hasWebServer = False
        # assert that app dir must exist
        self.config = None
        if self.hasFileSystem:
            if not os.path.exists(self.userAppDir):
                os.makedirs(self.userAppDir)
            # load config if it exists
            self.configJsonFile = self.userAppDir + os.sep + "config.json"
            if os.path.exists(self.configJsonFile):
                try:
                    with io.open(self.configJsonFile, 'rt',
                                 encoding='utf-8') as f:
                        self.config = json.load(f)
                except Exception as ex:
                    self.config = None  # restart with a new config
        if not self.config:
            self.config = {
                'fileHistory': [],
                'windowGeometry': "{0}x{1}+{2}+{3}".format(800, 500, 200, 100),
            }

        # start language translation for domain
        self.setUiLanguage(self.config.get("userInterfaceLangOverride", None),
                           fallbackToDefault=True)

        from arelle.WebCache import WebCache
        self.webCache = WebCache(self, self.config.get("proxySettings"))

        # start plug in server (requres web cache initialized, but not logger)
        PluginManager.init(self, loadPluginConfig=hasGui)

        # requires plug ins initialized
        self.modelManager = ModelManager.initialize(self)

        # start taxonomy package server (requres web cache initialized, but not logger)
        PackageManager.init(self, loadPackagesConfig=hasGui)

        self.startLogging(logFileName, logFileMode, logFileEncoding, logFormat)

        # Cntlr.Init after logging started
        for pluginMethod in PluginManager.pluginClassMethods("Cntlr.Init"):
            pluginMethod(self)