Exemplo n.º 1
0
def get_document_data_file(file_id, file_ext, add_cmd_name=False):
    """Return filename to be used by a user script to store data.

    File name is generated in this format:
    ``pyRevit_{Revit Version}_{file_id}_{Project Name}.{file_ext}``

    Example:
        >>> script.get_document_data_file('mydata', 'data')
        '.../pyRevit_2018_mydata_Project1.data'
        >>> script.get_document_data_file('mydata', 'data', add_cmd_name=True)
        '.../pyRevit_2018_Command Name_mydata_Project1.data'

    Document data files are not cleaned up at pyRevit startup.
    Script should manage cleaning up these files.

    Args:
        file_id (str): unique id for the filename
        file_ext (str): file extension
        add_cmd_name (bool, optional): add command name to file name

    Returns:
        str: full file path
    """
    proj_info = revit.get_project_info()  #pylint: disable=E1101

    if add_cmd_name:
        script_file_id = '{}_{}_{}'.format(
            EXEC_PARAMS.command_name, file_id, proj_info.filename
            or proj_info.name)
    else:
        script_file_id = '{}_{}'.format(file_id, proj_info.filename
                                        or proj_info.name)

    return appdata.get_data_file(script_file_id, file_ext)
Exemplo n.º 2
0
def _produce_asm_file(extension):
    # unique assembly filename for this package
    ext_asm_fileid = _make_ext_asm_fileid(extension)
    ext_asm_file_path = appdata.get_data_file(file_id=ext_asm_fileid,
                                              file_ext=ASSEMBLY_FILE_TYPE)
    # make unique assembly name for this package
    ext_asm_file_name = get_file_name(ext_asm_file_path)

    if _is_pyrevit_ext_already_loaded(ext_asm_file_name):
        logger.debug('Extension assembly is already loaded: {}'.format(ext_asm_file_name))
        _update_component_cmd_types(extension)
        return ExtensionAssemblyInfo(ext_asm_file_name, ext_asm_file_path, True)
    elif appdata.is_data_file_available(file_id=ext_asm_fileid, file_ext=ASSEMBLY_FILE_TYPE):
        logger.debug('Extension assembly file already exists: {}'.format(ext_asm_file_path))
        try:
            loaded_assm = load_asm_file(ext_asm_file_path)
            for asm_name in loaded_assm.GetReferencedAssemblies():
                logger.debug('Checking referenced assembly: {}'.format(asm_name))
                ref_asm_file_path = appdata.is_file_available(file_name=asm_name.Name, file_ext=ASSEMBLY_FILE_TYPE)
                if ref_asm_file_path:
                    logger.debug('Loading referenced assembly: {}'.format(ref_asm_file_path))
                    try:
                        load_asm_file(ref_asm_file_path)
                    except Exception as load_err:
                        logger.error('Error loading referenced assembly: {} | {}'.format(ref_asm_file_path, load_err))

            _update_component_cmd_types(extension)
            return ExtensionAssemblyInfo(ext_asm_file_name, ext_asm_file_path, False)
        except Exception as ext_asm_load_err:
            logger.error('Error loading extension assembly: {} | {}'.format(ext_asm_file_path, ext_asm_load_err))
    else:
        return _create_asm_file(extension, ext_asm_file_name, ext_asm_file_path)
Exemplo n.º 3
0
 def get_data_file(file_id, file_ext):
     """Returns a filename to be used by a user script to store data.
     Data files are saved in app directory and are NOT cleaned up at Revit restart.
     Script should manage cleaning up these data files.
     """
     from pyrevit.coreutils.appdata import get_data_file
     script_file_id = '{}_{}'.format(COMMAND_NAME, file_id)
     return get_data_file(script_file_id, file_ext)
Exemplo n.º 4
0
def _get_csharp_cmd_asm(cmd_component):
    """

    Args:
        cmd_component (pyrevit.extensions.genericcomps.GenericUICommand):

    Returns:

    """
    script_path = cmd_component.get_full_script_address()
    source = read_source_file(script_path)
    script_hash = get_str_hash(source)[:HASH_CUTOFF_LENGTH]

    command_assm_file_id = '{}_{}'\
        .format(script_hash, cmd_component.unique_name)

    # check to see if compiled c# command assembly is already loaded
    compiled_assm_list = find_loaded_asm(command_assm_file_id,
                                         by_partial_name=True)
    if len(compiled_assm_list) > 0:
        return compiled_assm_list[0]

    # if not already loaded, check to see if the assembly file exits
    compiled_assm_path = \
        appdata.is_data_file_available(file_id=command_assm_file_id,
                                       file_ext=ASSEMBLY_FILE_TYPE)
    if compiled_assm_path:
        return load_asm_file(compiled_assm_path)

    # else, let's compile the script and make the types
    command_assm_file = \
        appdata.get_data_file(file_id=command_assm_file_id,
                              file_ext=ASSEMBLY_FILE_TYPE)
    logger.debug('Compiling script {} to {}'.format(cmd_component,
                                                    command_assm_file))
    compiled_assm_path = compile_csharp([script_path],
                                        command_assm_file,
                                        reference_list=_get_references())
    return load_asm_file(compiled_assm_path)
Exemplo n.º 5
0
    def get_document_data_file(file_id, file_ext, doc=None, command_name=None):
        """Returns a filename to be used by a user script to store data under
        current Revit version and for the current document.
        Script should manage cleaning up these data files.
        If datafile will be used by different commands, override it using command_name parameter
        """
        from pyrevit.coreutils.appdata import get_data_file
        if not command_name:
            command_name = COMMAND_NAME

        if not doc:
            from revitutils import project
        else:
            from revitutils._project import CurrentProject
            project = CurrentProject(doc)

        if not project.filename:  # Remove special characters from project name
            project_name = project.name.translate(None, '\\/:*"<>|')
        else:
            project_name = project.filename

        script_file_id = '{}_{}_{}'.format(command_name, file_id, project_name)

        return get_data_file(script_file_id, file_ext)
Exemplo n.º 6
0
# template python command availability class
CMD_AVAIL_TYPE_NAME = make_canonical_name(LOADER_BASE_NAMESPACE,
                                          'PyRevitCommandDefaultAvail')
CMD_AVAIL_TYPE_NAME_CATEGORY = make_canonical_name(
    LOADER_BASE_NAMESPACE, 'PyRevitCommandCategoryAvail')
CMD_AVAIL_TYPE_NAME_SELECTION = make_canonical_name(
    LOADER_BASE_NAMESPACE, 'PyRevitCommandSelectionAvail')

source_file_filter = '(\.cs)'

if not EXEC_PARAMS.doc_mode:
    BASE_TYPES_DIR_HASH = calculate_dir_hash(
        INTERFACE_TYPES_DIR, '', source_file_filter)[:HASH_CUTOFF_LENGTH]
    BASE_TYPES_ASM_FILE_ID = '{}_{}'.format(BASE_TYPES_DIR_HASH,
                                            LOADER_BASE_NAMESPACE)
    BASE_TYPES_ASM_FILE = appdata.get_data_file(BASE_TYPES_ASM_FILE_ID,
                                                ASSEMBLY_FILE_TYPE)
    # taking the name of the generated data file and use it as assembly name
    BASE_TYPES_ASM_NAME = op.splitext(op.basename(BASE_TYPES_ASM_FILE))[0]
    logger.debug(
        'Interface types assembly file is: {}'.format(BASE_TYPES_ASM_NAME))
else:
    BASE_TYPES_DIR_HASH = BASE_TYPES_ASM_FILE_ID = None
    BASE_TYPES_ASM_FILE = BASE_TYPES_ASM_NAME = None


def _get_asm_attr_source():
    asm_att_source = """
    using System.Reflection;
    using System.Runtime.CompilerServices;
    using System.Runtime.InteropServices;
    using PyRevitBaseClasses;
Exemplo n.º 7
0
def _get_cache_file(cached_ext):
    return appdata.get_data_file(file_id='cache_{}'.format(cached_ext.name),
                                 file_ext='pickle')
Exemplo n.º 8
0
    # create a hash for the loader assembly
    # this hash is calculated based on:
    # - runtime csharp files
    # - runtime engine version
    # - cpython engine version
    BASE_TYPES_DIR_HASH = \
        coreutils.get_str_hash(
            coreutils.calculate_dir_hash(INTERFACE_TYPES_DIR, '', SOURCE_FILE_FILTER)
            + EXEC_PARAMS.engine_ver
            + str(CPYTHON_ENGINE.Version)
            )[:HASH_CUTOFF_LENGTH]
    RUNTIME_ASSM_FILE_ID = '{}_{}'\
        .format(BASE_TYPES_DIR_HASH, RUNTIME_NAMESPACE)
    RUNTIME_ASSM_FILE = \
        appdata.get_data_file(RUNTIME_ASSM_FILE_ID,
                              framework.ASSEMBLY_FILE_TYPE)
    # taking the name of the generated data file and use it as assembly name
    RUNTIME_ASSM_NAME = op.splitext(op.basename(RUNTIME_ASSM_FILE))[0]
    mlogger.debug('Interface types assembly file is: %s', RUNTIME_ASSM_NAME)
else:
    BASE_TYPES_DIR_HASH = RUNTIME_ASSM_FILE_ID = None
    RUNTIME_ASSM_FILE = RUNTIME_ASSM_NAME = None


def _get_source_files_in(source_files_path):
    source_files = {}
    for source_file in os.listdir(source_files_path):
        if op.splitext(source_file)[1].lower() == SOURCE_FILE_EXT:
            source_filepath = op.join(source_files_path, source_file)
            mlogger.debug('Source file found: %s', source_filepath)
            source_files[source_file] = source_filepath