Esempio n. 1
0
File: cks.py Progetto: vivi90/cks
    def addLayers(self) -> None:
        '''Adds detected vector layers to the prepared SVG export structure.'''

        defs = self.svg.find("./defs")
        self.layers.reverse()
        for layer in self.layers:
            if getsize(layer[1]) > 0:
                defMap = []
                root = ElementTree(ElementTree().parse(layer[1])).getroot()
                self.svg.set("width", root.get("width"))
                self.svg.set("height", root.get("height"))
                self.svg.set("viewBox", root.get("viewBox"))
                for defElement in root.find("./svg:defs", self.NAMESPACE_SVG):
                    newId = layer[0] + "-" + defElement.get("id")
                    defMap.append([defElement.get("id"), newId])
                    defElement.set("id", newId)
                    defs.append(defElement)
                group = Element("g")
                group.set("id", layer[0])
                for child in root:
                    if child.tag != "{" + self.NAMESPACE_SVG["svg"] + "}defs":
                        for attribute in child.attrib:
                            for defMapEntry in defMap:
                                child.set(attribute, child.get(attribute).replace(defMapEntry[0], defMapEntry[1]))
                        group.append(child)
                self.svg.append(group)
Esempio n. 2
0
 def __init__(self, dependency_tag: ElementTree):
     self._tree = dependency_tag
     self.name = dependency_tag.get("name")
     self.build_only = dependency_tag.get("build-only") == "true"
     self._dependencies = []
     self._flags = {}
     self._fetch_sources()
     self._fetch_subdependencies()
     self._fetch_flags()
Esempio n. 3
0
    def vm_read_config(self):
        """
        This method parses the libvirt xml config file and fills the 
        cfg_details dictionary. This method returns the dictionary or 
        raise exception if xml is not valid.
        """
        
        domain = ET().parse(self.cfg_file)
        vm_type = domain.get('type') 
        self.cfg_details['vm_type'] = HVM_LIBVIRT_NAMEMAP[vm_type]
        self.cfg_details['vm_type_str'] = vm_type
        self.cfg_details['displayName'] = domain.find('name').text
        self.cfg_details['memsize'] = int(domain.find('memory').text) >> 10

        primary_disk_list = []
        for disk in domain.findall('devices/disk'):
            disk_details = self.get_disk_details(disk)
            if disk.get('type') == 'file' and \
               disk.get('device') == 'disk' and \
               disk_details['dev'] in ('sda', 'hda', 'vda') and \
               disk_details['bus'] in ('ide', 'scsi', 'virtio'):
                primary_disk_list.append(os.path.basename(disk_details['file']))
                break

        self.cfg_details['primary_disk'] = primary_disk_list
        self.cfg_details['primary_disk_str'] = ','.join(primary_disk_list)

        if not self.cfg_details:
            raise config_file_invalid()
        else:
            return self.cfg_details
Esempio n. 4
0
    def vm_read_config(self):
        """
        This method parses the libvirt xml config file and fills the 
        cfg_details dictionary. This method returns the dictionary or 
        raise exception if xml is not valid.
        """

        domain = ET().parse(self.cfg_file)
        vm_type = domain.get('type')
        self.cfg_details['vm_type'] = HVM_LIBVIRT_NAMEMAP[vm_type]
        self.cfg_details['vm_type_str'] = vm_type
        self.cfg_details['displayName'] = domain.find('name').text
        self.cfg_details['memsize'] = int(domain.find('memory').text) >> 10

        primary_disk_list = []
        for disk in domain.findall('devices/disk'):
            disk_details = self.get_disk_details(disk)
            if disk.get('type') == 'file' and \
               disk.get('device') == 'disk' and \
               disk_details['dev'] in ('sda', 'hda', 'vda') and \
               disk_details['bus'] in ('ide', 'scsi', 'virtio'):
                primary_disk_list.append(os.path.basename(
                    disk_details['file']))
                break

        self.cfg_details['primary_disk'] = primary_disk_list
        self.cfg_details['primary_disk_str'] = ','.join(primary_disk_list)

        if not self.cfg_details:
            raise config_file_invalid()
        else:
            return self.cfg_details
Esempio n. 5
0
    def configure(self, config_tree: ElementTree):
        self.name = config_tree.get('name')
        config_pins = config_tree.find('pins')
        pins = config_pins.findall('pin')
        self.extra = config_tree.find('extra')
        logging.debug("Found %i pins for %s.", len(pins),
                      self.__class__.__name__)
        for cpin in pins:
            self.pins.append(Pin(cpin))

        self._post_config()
Esempio n. 6
0
def parResult(sourcepath,cscfilepath):
    if not os.path.isdir(sourcepath):
        print("ERROR dir")
        return
    firmware=constants.devicefirmware
    csvfile = open(cscfilepath, 'wb')
    writer = csv.writer(csvfile)  
    data=[("CaseName", "Status","Fail_message","Block_message","Firmware")]    
    writer.writerows(data)
    for xmlfile in os.listdir(sourcepath):
        sourcefile=os.path.join(sourcepath,xmlfile)
        if str(xmlfile).find("xml")!=-1:
            fail_message=''
            block_message='' 
            status=''
            result=ElementTree(file=sourcefile).getroot()
            testsuitname='TEST-'+result.get('name')
            failures=string.atoi(result.get('failures'))
            errors=string.atoi(result.get('errors'))
            if errors!=0:
                testcase=result.findall('testcase')
                for eachcase in testcase:
                    if eachcase.find('error')!=None:
                        error_message= eachcase[0].get("message") 
                        status="Block"  
                        block_message=error_message            
            elif failures!=0:
                status="Fail"
                testcase=result.findall('testcase')
                for eachcase in testcase:
                    if eachcase.find('failure')!=None:
                        fail_message= eachcase[0].get("message")
                        if  fail_message in constants.errorlist:
                            status="Fail"   
            else :
                status="OK"
            data=[(testsuitname, status,fail_message,block_message,firmware)]    
            writer.writerows(data)
    csvfile.close()  
Esempio n. 7
0
    addon = os.environ['ADDON']
else:
    addon = args.addon
if not args.version:
    args.version = 'version'

# Define paths
username = os.environ['GITHUB_REPOSITORY'].split("/")[0]
repo_slug = "{}/alfa-repo".format(username)
root_dir = os.path.dirname(os.path.abspath(__file__))
addon_dir = os.path.join(root_dir, addon)
docs_dir = os.path.join(root_dir, 'docs')
html_dir = os.path.join(docs_dir, '_build', 'html')
with open(os.path.join(root_dir, addon, 'addon.xml'), 'rb') as addon_xml:
    xml = ET().parse(addon_xml)
    version = xml.get("version")
zip_name = '{0}-{1}'.format(addon, version)
zip_path = os.path.join(root_dir, zip_name + '.zip')

# Define URLs
REPO_URL_MASK = 'https://{username}:{gh_token}@github.com/{repo_slug}.git'
gh_repo_url = REPO_URL_MASK.format(username=username.lower(),
                                   gh_token=gh_token,
                                   repo_slug=repo_slug)
kodi_repo_dir = os.path.join(root_dir, 'alfa-repo')
kodi_repo_url = REPO_URL_MASK.format(username=username.lower(),
                                     gh_token=gh_token,
                                     repo_slug=repo_slug)

# Start working
os.chdir(root_dir)
Esempio n. 8
0
 def unzip_theme(self, file_path, directory_path):
     """
     Unzip the theme, remove the preview file if stored. Generate a new preview file. Check the XML theme version
     and upgrade if necessary.
     :param Path file_path:
     :param Path directory_path:
     """
     self.log_debug('Unzipping theme {name}'.format(name=file_path))
     file_xml = None
     abort_import = True
     json_theme = False
     theme_name = ""
     try:
         with zipfile.ZipFile(file_path) as theme_zip:
             json_file = [
                 name for name in theme_zip.namelist()
                 if os.path.splitext(name)[1].lower() == '.json'
             ]
             if len(json_file) != 1:
                 # TODO: remove XML handling after once the upgrade path from 2.4 is no longer required
                 xml_file = [
                     name for name in theme_zip.namelist()
                     if os.path.splitext(name)[1].lower() == '.xml'
                 ]
                 if len(xml_file) != 1:
                     self.log_error(
                         'Theme contains "{val:d}" theme files'.format(
                             val=len(xml_file)))
                     raise ValidationError
                 xml_tree = ElementTree(
                     element=XML(theme_zip.read(xml_file[0]))).getroot()
                 theme_version = xml_tree.get('version', default=None)
                 if not theme_version or float(theme_version) < 2.0:
                     self.log_error('Theme version is less than 2.0')
                     raise ValidationError
                 theme_name = xml_tree.find('name').text.strip()
             else:
                 new_theme = Theme()
                 new_theme.load_theme(
                     theme_zip.read(json_file[0]).decode("utf-8"))
                 theme_name = new_theme.theme_name
                 json_theme = True
             theme_folder = directory_path / theme_name
             if theme_folder.exists(
             ) and not self.over_write_message_box(theme_name):
                 abort_import = True
                 return
             else:
                 abort_import = False
             for zipped_file in theme_zip.namelist():
                 zipped_file_rel_path = Path(zipped_file)
                 split_name = zipped_file_rel_path.parts
                 if split_name[-1] == '' or len(split_name) == 1:
                     # is directory or preview file
                     continue
                 full_name = directory_path / zipped_file_rel_path
                 create_paths(full_name.parent)
                 if zipped_file_rel_path.suffix.lower(
                 ) == '.xml' or zipped_file_rel_path.suffix.lower(
                 ) == '.json':
                     file_xml = str(theme_zip.read(zipped_file), 'utf-8')
                     with full_name.open('w', encoding='utf-8') as out_file:
                         out_file.write(file_xml)
                 else:
                     with full_name.open('wb') as out_file:
                         out_file.write(theme_zip.read(zipped_file))
     except (OSError, ValidationError, zipfile.BadZipFile):
         self.log_exception('Importing theme from zip failed {name}'.format(
             name=file_path))
         critical_error_message_box(
             translate('OpenLP.ThemeManager', 'Import Error'),
             translate(
                 'OpenLP.ThemeManager',
                 'There was a problem importing {file_name}.\n\nIt is corrupt, '
                 'inaccessible or not a valid theme.').format(
                     file_name=file_path))
     finally:
         if not abort_import:
             # As all files are closed, we can create the Theme.
             if file_xml:
                 if json_theme:
                     self._create_theme_from_json(file_xml, self.theme_path)
                 else:
                     self._create_theme_from_xml(file_xml, self.theme_path)
             return theme_name
         else:
             return None
Esempio n. 9
0
 def unzip_theme(self, file_name, directory):
     """
     Unzip the theme, remove the preview file if stored. Generate a new preview file. Check the XML theme version
     and upgrade if necessary.
     :param file_name:
     :param directory:
     """
     self.log_debug('Unzipping theme %s' % file_name)
     theme_zip = None
     out_file = None
     file_xml = None
     abort_import = True
     try:
         theme_zip = zipfile.ZipFile(file_name)
         xml_file = [
             name for name in theme_zip.namelist()
             if os.path.splitext(name)[1].lower() == '.xml'
         ]
         if len(xml_file) != 1:
             self.log_error('Theme contains "%s" XML files' % len(xml_file))
             raise ValidationError
         xml_tree = ElementTree(
             element=XML(theme_zip.read(xml_file[0]))).getroot()
         theme_version = xml_tree.get('version', default=None)
         if not theme_version or float(theme_version) < 2.0:
             self.log_error('Theme version is less than 2.0')
             raise ValidationError
         theme_name = xml_tree.find('name').text.strip()
         theme_folder = os.path.join(directory, theme_name)
         theme_exists = os.path.exists(theme_folder)
         if theme_exists and not self.over_write_message_box(theme_name):
             abort_import = True
             return
         else:
             abort_import = False
         for name in theme_zip.namelist():
             out_name = name.replace('/', os.path.sep)
             split_name = out_name.split(os.path.sep)
             if split_name[-1] == '' or len(split_name) == 1:
                 # is directory or preview file
                 continue
             full_name = os.path.join(directory, out_name)
             check_directory_exists(os.path.dirname(full_name))
             if os.path.splitext(name)[1].lower() == '.xml':
                 file_xml = str(theme_zip.read(name), 'utf-8')
                 out_file = open(full_name, 'w', encoding='utf-8')
                 out_file.write(file_xml)
             else:
                 out_file = open(full_name, 'wb')
                 out_file.write(theme_zip.read(name))
             out_file.close()
     except (IOError, zipfile.BadZipfile):
         self.log_exception('Importing theme from zip failed %s' %
                            file_name)
         raise ValidationError
     except ValidationError:
         critical_error_message_box(
             translate('OpenLP.ThemeManager', 'Validation Error'),
             translate('OpenLP.ThemeManager', 'File is not a valid theme.'))
     finally:
         # Close the files, to be able to continue creating the theme.
         if theme_zip:
             theme_zip.close()
         if out_file:
             out_file.close()
         if not abort_import:
             # As all files are closed, we can create the Theme.
             if file_xml:
                 theme = self._create_theme_from_xml(file_xml, self.path)
                 self.generate_and_save_image(theme_name, theme)
             # Only show the error message, when IOError was not raised (in
             # this case the error message has already been shown).
             elif theme_zip is not None:
                 critical_error_message_box(
                     translate('OpenLP.ThemeManager', 'Validation Error'),
                     translate('OpenLP.ThemeManager',
                               'File is not a valid theme.'))
                 self.log_error('Theme file does not contain XML data %s' %
                                file_name)
Esempio n. 10
0
 def unzip_theme(self, file_name, directory):
     """
     Unzip the theme, remove the preview file if stored. Generate a new preview file. Check the XML theme version
     and upgrade if necessary.
     :param file_name:
     :param directory:
     """
     self.log_debug('Unzipping theme {name}'.format(name=file_name))
     theme_zip = None
     out_file = None
     file_xml = None
     abort_import = True
     try:
         theme_zip = zipfile.ZipFile(file_name)
         xml_file = [name for name in theme_zip.namelist() if os.path.splitext(name)[1].lower() == '.xml']
         if len(xml_file) != 1:
             self.log_error('Theme contains "{val:d}" XML files'.format(val=len(xml_file)))
             raise ValidationError
         xml_tree = ElementTree(element=XML(theme_zip.read(xml_file[0]))).getroot()
         theme_version = xml_tree.get('version', default=None)
         if not theme_version or float(theme_version) < 2.0:
             self.log_error('Theme version is less than 2.0')
             raise ValidationError
         theme_name = xml_tree.find('name').text.strip()
         theme_folder = os.path.join(directory, theme_name)
         theme_exists = os.path.exists(theme_folder)
         if theme_exists and not self.over_write_message_box(theme_name):
             abort_import = True
             return
         else:
             abort_import = False
         for name in theme_zip.namelist():
             out_name = name.replace('/', os.path.sep)
             split_name = out_name.split(os.path.sep)
             if split_name[-1] == '' or len(split_name) == 1:
                 # is directory or preview file
                 continue
             full_name = os.path.join(directory, out_name)
             check_directory_exists(os.path.dirname(full_name))
             if os.path.splitext(name)[1].lower() == '.xml':
                 file_xml = str(theme_zip.read(name), 'utf-8')
                 out_file = open(full_name, 'w', encoding='utf-8')
                 out_file.write(file_xml)
             else:
                 out_file = open(full_name, 'wb')
                 out_file.write(theme_zip.read(name))
             out_file.close()
     except (IOError, zipfile.BadZipfile):
         self.log_exception('Importing theme from zip failed {name}'.format(name=file_name))
         raise ValidationError
     except ValidationError:
         critical_error_message_box(translate('OpenLP.ThemeManager', 'Validation Error'),
                                    translate('OpenLP.ThemeManager', 'File is not a valid theme.'))
     finally:
         # Close the files, to be able to continue creating the theme.
         if theme_zip:
             theme_zip.close()
         if out_file:
             out_file.close()
         if not abort_import:
             # As all files are closed, we can create the Theme.
             if file_xml:
                 theme = self._create_theme_from_xml(file_xml, self.path)
                 self.generate_and_save_image(theme_name, theme)
             # Only show the error message, when IOError was not raised (in
             # this case the error message has already been shown).
             elif theme_zip is not None:
                 critical_error_message_box(
                     translate('OpenLP.ThemeManager', 'Validation Error'),
                     translate('OpenLP.ThemeManager', 'File is not a valid theme.'))
                 self.log_error('Theme file does not contain XML data {name}'.format(name=file_name))
Esempio n. 11
0
def update_torso(
    tree: ElementTree = None,
    torso_body: Element = None,
    new_torso_min: Pos = None,
    size_scaling_factor: float = 1.0,
    geom_suffix="torso_geom",
    **kwargs,
) -> None:
    """ 'move' the torso body and its endpoints, after another bodypart has been
    scaled.
    This moves all relevant geoms and
    joints and bodies,
    Normally, this can update the 
    (through possibly recursive calls to one of `update_torso`,
    `update_thigh`, `update_leg`, `update_foot`.)
    """
    assert size_scaling_factor != 0.0
    body_name = "torso"
    # Get the elements to be modified.
    if torso_body is None:
        assert tree is not None, "need the tree if torso_body is not given!"
        if isinstance(tree, Element) and tree.tag == "body" and tree.get(
                "name") == body_name:
            torso_body = tree
            tree = None
        else:
            torso_body = tree.find(f".//body[@name='{body_name}']")
    assert torso_body is not None, "can't find the torso body!"

    torso_geom = torso_body.find(f"./geom[@name='{body_name}']")
    if torso_geom is None:
        torso_geom = torso_body.find(f"./geom[@name='{body_name}_geom']")
    if torso_geom is None:
        raise RuntimeError(f"Can't find the geom for body part '{body_name}'!")

    rooty_joint = torso_body.find("./joint[@name='rooty']")
    rootz_joint = torso_body.find("./joint[@name='rootz']")

    torso_body_pos = Pos.of_element(torso_body)

    torso_geom_size = float(torso_geom.get("size"))
    torso_geom_fromto = FromTo.of_element(torso_geom)
    rootz_joint_ref = float(rootz_joint.get("ref"))
    rooty_joint_pos = Pos.of_element(rooty_joint)

    torso_max = torso_geom_fromto.start
    torso_min = torso_geom_fromto.end
    torso_length = torso_max - torso_min
    assert torso_body_pos == torso_geom_fromto.center
    # This happens to coincide with torso's pos.
    assert rootz_joint_ref == torso_body_pos.z
    assert rooty_joint_pos == torso_body_pos

    if new_torso_min is None:
        # Assume that the location of the base of the torso doesn't change, i.e. that
        # this was called in order to JUST scale the torso and nothing else.
        new_torso_min = torso_min
    # new_torso_min is already given, calculate the other two:
    new_torso_length = torso_length * (1 if size_scaling_factor is None else
                                       size_scaling_factor)
    new_torso_max = new_torso_min + new_torso_length

    # NOTE: fromto is from top to bottom here (maybe also everywhere else, not sure).
    new_torso_geom_size = torso_geom_size * size_scaling_factor
    new_torso_geom_fromto = FromTo(start=new_torso_max, end=new_torso_min)
    new_torso_pos = (new_torso_max + new_torso_min) / 2
    new_rootz_joint_ref = new_torso_pos.z
    new_rooty_joint_pos = new_torso_pos

    # Update the fields of the different elements.
    torso_body.set("pos", new_torso_pos.to_str())
    torso_geom.set("fromto", new_torso_geom_fromto.to_str())
    torso_geom.set("size", new_torso_geom_size)

    # TODO: Not sure if this makes sense: The rooty joint has a Pos that coincides
    # with the torso pos.
    new_torso_pos.set_in_element(rooty_joint)
    # TODO: rootz has a 'ref' which also coincides with the torso pos.
    rootz_joint.set("ref", str(new_rootz_joint_ref))
    rooty_joint.set("pos", new_rooty_joint_pos)

    new_torso_pos = new_torso_geom_fromto.center
    # TODO: Also move the camera?

    world_body: Optional[Element] = None
    if tree is not None:
        assert tree is not None, "need the tree if torso_body is not given!"
        world_body = get_parent(tree, torso_body)

    # Don't change the scaling of the parent, if this body part was scaled!
    parent_scale_factor = 1 if size_scaling_factor != 1 else size_scaling_factor

    update_world(
        tree=tree,
        world_body=world_body,
        new_torso_min=new_torso_min,
        new_torso_max=new_torso_max,
        size_scaling_factor=parent_scale_factor,
        **kwargs,
    )
 def getChildByName(self, root: ET.ElementTree,
                    node: str) -> ET.ElementTree:
     return root.get(node)
Esempio n. 13
0
class Project(Process):
    """API to create signal chain projects"""

    ELEMENTNAME = 'Project'

    def __init__(self, name=''):

        Process.__init__(self)
        self.id = '1'
        if name:
            self.name = '{} ({})'.format(Process.__name__, name)
        self.filename = None
        self.description = None
        self.email = None
        self.alarm = []
        self.configurations = {}
        # self.err_queue = Queue()
        self.err_queue = None
        self.started = False

    def getNewId(self):

        idList = list(self.configurations.keys())
        id = int(self.id) * 10

        while True:
            id += 1

            if str(id) in idList:
                continue

            break

        return str(id)

    def updateId(self, new_id):

        self.id = str(new_id)

        keyList = list(self.configurations.keys())
        keyList.sort()

        n = 1
        new_confs = {}

        for procKey in keyList:

            conf = self.configurations[procKey]
            idProcUnit = str(int(self.id) * 10 + n)
            conf.updateId(idProcUnit)
            new_confs[idProcUnit] = conf
            n += 1

        self.configurations = new_confs

    def setup(self, id=1, name='', description='', email=None, alarm=[]):

        self.id = str(id)
        self.description = description
        self.email = email
        self.alarm = alarm
        if name:
            self.name = '{} ({})'.format(Process.__name__, name)

    def update(self, **kwargs):

        for key, value in kwargs.items():
            setattr(self, key, value)

    def clone(self):

        p = Project()
        p.id = self.id
        p.name = self.name
        p.description = self.description
        p.configurations = self.configurations.copy()

        return p

    def addReadUnit(self, id=None, datatype=None, name=None, **kwargs):
        '''
        '''

        if id is None:
            idReadUnit = self.getNewId()
        else:
            idReadUnit = str(id)

        conf = ReadUnitConf()
        conf.setup(self.id, idReadUnit, name, datatype, self.err_queue,
                   **kwargs)
        self.configurations[conf.id] = conf

        return conf

    def addProcUnit(self, id=None, inputId='0', datatype=None, name=None):
        '''
        '''

        if id is None:
            idProcUnit = self.getNewId()
        else:
            idProcUnit = id

        conf = ProcUnitConf()
        conf.setup(self.id, idProcUnit, name, datatype, inputId,
                   self.err_queue)
        self.configurations[conf.id] = conf

        return conf

    def removeProcUnit(self, id):

        if id in self.configurations:
            self.configurations.pop(id)

    def getReadUnit(self):

        for obj in list(self.configurations.values()):
            if obj.ELEMENTNAME == 'ReadUnit':
                return obj

        return None

    def getProcUnit(self, id):

        return self.configurations[id]

    def getUnits(self):

        keys = list(self.configurations)
        keys.sort()

        for key in keys:
            yield self.configurations[key]

    def updateUnit(self, id, **kwargs):

        conf = self.configurations[id].update(**kwargs)

    def makeXml(self):

        xml = Element('Project')
        xml.set('id', str(self.id))
        xml.set('name', self.name)
        xml.set('description', self.description)

        for conf in self.configurations.values():
            conf.makeXml(xml)

        self.xml = xml

    def writeXml(self, filename=None):

        if filename == None:
            if self.filename:
                filename = self.filename
            else:
                filename = 'schain.xml'

        if not filename:
            print(
                'filename has not been defined. Use setFilename(filename) for do it.'
            )
            return 0

        abs_file = os.path.abspath(filename)

        if not os.access(os.path.dirname(abs_file), os.W_OK):
            print('No write permission on %s' % os.path.dirname(abs_file))
            return 0

        if os.path.isfile(abs_file) and not (os.access(abs_file, os.W_OK)):
            print('File %s already exists and it could not be overwriten' %
                  abs_file)
            return 0

        self.makeXml()

        ElementTree(self.xml).write(abs_file, method='xml')

        self.filename = abs_file

        return 1

    def readXml(self, filename):

        abs_file = os.path.abspath(filename)

        self.configurations = {}

        try:
            self.xml = ElementTree().parse(abs_file)
        except:
            log.error('Error reading %s, verify file format' % filename)
            return 0

        self.id = self.xml.get('id')
        self.name = self.xml.get('name')
        self.description = self.xml.get('description')

        for element in self.xml:
            if element.tag == 'ReadUnit':
                conf = ReadUnitConf()
                conf.readXml(element, self.id, self.err_queue)
                self.configurations[conf.id] = conf
            elif element.tag == 'ProcUnit':
                conf = ProcUnitConf()
                input_proc = self.configurations[element.get('inputId')]
                conf.readXml(element, self.id, self.err_queue)
                self.configurations[conf.id] = conf

        self.filename = abs_file

        return 1

    def __str__(self):

        text = '\nProject[id=%s, name=%s, description=%s]\n\n' % (
            self.id,
            self.name,
            self.description,
        )

        for conf in self.configurations.values():
            text += '{}'.format(conf)

        return text

    def createObjects(self):

        keys = list(self.configurations.keys())
        keys.sort()
        for key in keys:
            conf = self.configurations[key]
            conf.createObjects()
            if conf.inputId is not None:
                conf.object.setInput(self.configurations[conf.inputId].object)

    def monitor(self):

        t = Thread(target=self._monitor, args=(self.err_queue, self.ctx))
        t.start()

    def _monitor(self, queue, ctx):

        import socket

        procs = 0
        err_msg = ''

        while True:
            msg = queue.get()
            if '#_start_#' in msg:
                procs += 1
            elif '#_end_#' in msg:
                procs -= 1
            else:
                err_msg = msg

            if procs == 0 or 'Traceback' in err_msg:
                break
            time.sleep(0.1)

        if '|' in err_msg:
            name, err = err_msg.split('|')
            if 'SchainWarning' in err:
                log.warning(
                    err.split('SchainWarning:')[-1].split('\n')[0].strip(),
                    name)
            elif 'SchainError' in err:
                log.error(
                    err.split('SchainError:')[-1].split('\n')[0].strip(), name)
            else:
                log.error(err, name)
        else:
            name, err = self.name, err_msg

        time.sleep(1)

        ctx.term()

        message = ''.join(err)

        if err_msg:
            subject = 'SChain v%s: Error running %s\n' % (schainpy.__version__,
                                                          self.name)

            subtitle = 'Hostname: %s\n' % socket.gethostbyname(
                socket.gethostname())
            subtitle += 'Working directory: %s\n' % os.path.abspath('./')
            subtitle += 'Configuration file: %s\n' % self.filename
            subtitle += 'Time: %s\n' % str(datetime.datetime.now())

            readUnitConfObj = self.getReadUnit()
            if readUnitConfObj:
                subtitle += '\nInput parameters:\n'
                subtitle += '[Data path = %s]\n' % readUnitConfObj.parameters[
                    'path']
                subtitle += '[Start date = %s]\n' % readUnitConfObj.parameters[
                    'startDate']
                subtitle += '[End date = %s]\n' % readUnitConfObj.parameters[
                    'endDate']
                subtitle += '[Start time = %s]\n' % readUnitConfObj.parameters[
                    'startTime']
                subtitle += '[End time = %s]\n' % readUnitConfObj.parameters[
                    'endTime']

            a = Alarm(modes=self.alarm,
                      email=self.email,
                      message=message,
                      subject=subject,
                      subtitle=subtitle,
                      filename=self.filename)

            a.start()

    def setFilename(self, filename):

        self.filename = filename

    def runProcs(self):

        err = False
        n = len(self.configurations)

        while not err:
            for conf in self.getUnits():
                ok = conf.run()
                if ok == 'Error':
                    n -= 1
                    continue
                elif not ok:
                    break
            if n == 0:
                err = True

    def run(self):

        log.success('\nStarting Project {} [id={}]'.format(self.name, self.id),
                    tag='')
        self.started = True
        self.start_time = time.time()
        self.createObjects()
        self.runProcs()
        log.success(
            '{} Done (Time: {:4.2f}s)'.format(self.name,
                                              time.time() - self.start_time),
            '')