def test_can_request_project_code_for_id(self):
     with common.TemporaryDirectory(remove_on_exit=True) as temp_dir:
         for _project_url, project_id in common_testing.TEST_PROJECT_URL_TO_ID_MAP.iteritems(
         ):
             scratchwebapi.download_project_code(project_id, temp_dir)
             project_file_path = os.path.join(temp_dir,
                                              scratch._PROJECT_FILE_NAME)
             with open(project_file_path, 'r') as project_code_file:
                 project_code_content = project_code_file.read()
                 raw_project = scratch.RawProject.from_project_code_content(
                     project_code_content)
                 assert raw_project is not None
Example #2
0
def run_converter(scratch_project_file_or_url, output_dir,
                  extract_resulting_catrobat=False, temp_rm=True,
                  show_version_only=False, show_info_only=False,
                  archive_name=None,
                  web_mode=False):
    def check_base_environment():
        if "java" not in sys.platform:
            raise EnvironmentError("Must be called with Jython interpreter.")
        if System.getProperty(helpers.JYTHON_RESPECT_JAVA_ACCESSIBILITY_PROPERTY) != 'false':
            raise EnvironmentError("Jython registry property '%s' must be set to 'false'." % helpers.JYTHON_RESPECT_JAVA_ACCESSIBILITY_PROPERTY)

    def check_converter_environment():
        # TODO: refactor to combined class with explicit environment check method
        tools.svgtopng._checked_batik_jar_path()
        tools.wavconverter._checked_sox_path()

    try:
        from java.io import IOError
        from java.lang import System
    except ImportError:
        log.error("Must be called with Jython interpreter.")
        return helpers.ExitCode.FAILURE

    # nested import to be able to check for Jython interpreter first
    from scratchtocatrobat import tools
    from scratchtocatrobat.tools import common
    from scratchtocatrobat.converter import converter, catrobat
    from scratchtocatrobat.scratch import scratchwebapi, scratch

    try:
        check_base_environment()
        check_converter_environment()

        catrobat_language_version_from_config = float(helpers.catrobat_info("catrobat_language_version"))
        if catrobat_language_version_from_config != catrobat.CATROBAT_LANGUAGE_VERSION:
            raise RuntimeError("Wrong Catrobat Language version set in config-file! " \
                               "Catrobat language version is %.3f but should be %.3f! Please update!"
                               % (catrobat_language_version_from_config, catrobat.CATROBAT_LANGUAGE_VERSION))

        tag_name = helpers.tag_name_of_used_catroid_hierarchy()
        latest_release_data = helpers.latest_catroid_repository_release_data()
        if show_version_only or show_info_only:
            helpers.print_info_or_version_screen(show_version_only, catrobat.CATROBAT_LANGUAGE_VERSION)
            return helpers.ExitCode.SUCCESS
        elif latest_release_data and not web_mode: # suppress release-reminder in web-mode
            current_release_version = helpers.extract_version_number(tag_name)
            latest_release_version = helpers.extract_version_number(latest_release_data["tag_name"])
            if current_release_version < latest_release_version:
                print("Latest Catroid release: %s (%s)" % (latest_release_data["tag_name"],
                                                           latest_release_data["published_at"]))
                print("%sA NEW CATROID RELEASE IS AVAILABLE!\nPLEASE UPDATE THE CLASS HIERARCHY " \
                      "OF THE CONVERTER FROM CATROID VERSION %s TO VERSION %s%s" % (
                            helpers.cli_colors.FAIL, tag_name, latest_release_data["tag_name"],
                            helpers.cli_colors.ENDC
                ))

        log.info("calling converter")
        if not os.path.isdir(output_dir):
            raise EnvironmentError("Output folder must be a directory, but is %s" % output_dir)
        scratch3ProjectName = "Untitled"
        progress_bar = helpers.ProgressBar(None, web_mode, sys.stdout)
        with common.TemporaryDirectory(remove_on_exit=temp_rm) as scratch_project_dir:
            is_local_project = True
            project_id = None
            if scratch_project_file_or_url.startswith("https://"):
                is_local_project = False
                validate_scratch_url(scratch_project_file_or_url)

                project_id = scratchwebapi.extract_project_id_from_url(scratch_project_file_or_url)
                if not scratchwebapi.request_is_project_available(project_id):
                    raise common.ScratchtobatError("Project with ID %s not available" % project_id)
                visibility = scratchwebapi.getMetaDataEntry(project_id, "visibility")
                if visibility != scratchwebapi.ScratchProjectVisibiltyState.PUBLIC:
                    log.warn('-'*80)
                    log.warn("CAVE: Project with ID %s is NOT a public project!! Trying to " \
                             "continue the conversion-process anyway, but expecting the " \
                             "conversion to fail or to be incomplete...", project_id)
                    log.warn('-'*80)
                log.info("Downloading project from URL: '{}' to temp dir {} ...".format(
                                                scratch_project_file_or_url, scratch_project_dir))
                scratchwebapi.download_project(scratch_project_file_or_url, scratch_project_dir, progress_bar)
                scratch3ProjectName = scratchwebapi.getMetaDataEntry(project_id, "title")

            elif os.path.isfile(scratch_project_file_or_url):
                log.info("Extracting project from path: '{}' ...".format(scratch_project_file_or_url))
                common.extract(scratch_project_file_or_url, scratch_project_dir)

            else:
                if not os.path.isdir(scratch_project_file_or_url):
                    raise common.ScratchtobatError("Directory of local project not found in %s" %
                                                   scratch_project_file_or_url)
                log.info("Loading project from path: '{}' ...".format(scratch_project_file_or_url))
                scratch_project_dir = scratch_project_file_or_url

            isScratch3Project = scratch3.is_scratch3_project(scratch_project_dir)

            if isScratch3Project:
                scratch3.convert_to_scratch2_data(scratch_project_dir, project_id)

            project = scratch.Project(scratch_project_dir, progress_bar=progress_bar, is_local_project = is_local_project)
            if isScratch3Project:
                project.name = scratch3ProjectName
            log.info("Converting scratch project '%s' into output folder: %s", project.name, output_dir)
            context = converter.Context()
            converted_project = converter.converted(project, progress_bar, context)
            catrobat_program_path = converted_project.save_as_catrobat_package_to(output_dir, archive_name, progress_bar, context)
            if extract_resulting_catrobat:
                extraction_path = os.path.join(output_dir, os.path.splitext(os.path.basename(catrobat_program_path))[0])
                common.rm_dir(extraction_path)
                common.makedirs(extraction_path)
                scratch_output_path = os.path.join(extraction_path, "scratch")
                common.copy_dir(scratch_project_dir, scratch_output_path, overwrite=True)
                common.extract(catrobat_program_path, extraction_path)

        progress_bar.finish()
    except (common.ScratchtobatError, EnvironmentError, IOError) as e:
        log.error(e)
        return helpers.ExitCode.FAILURE
    except Exception as e:
        log.exception(e)
        return helpers.ExitCode.FAILURE
    return helpers.ExitCode.SUCCESS