def main():
    logging.basicConfig(
        filename=None,
        level=logging.DEBUG,
        format='%(asctime)s: %(levelname)7s: [%(name)s]: %(message)s',
        datefmt='%Y-%m-%d %H:%M:%S',
    )
    if not os.path.isfile(CERTIFICATE_PATH):
        _logger.error("Cannot find server certificate: %s", CERTIFICATE_PATH)
        return
    if not os.path.isfile(CERTIFICATE_KEY_PATH):
        _logger.error("Cannot find server certificate key: %s",
                      CERTIFICATE_KEY_PATH)
        return

    try:
        converterwebapp._MainHandler.app_data = helpers.config.items_as_dict(
            "APPLICATION")
        converterwebapp._MainHandler.app_data[
            "catrobat_language_version"] = helpers.catrobat_info(
                "catrobat_language_version")
    except:
        _logger.error("Error fetching application data", exc_info=True)
        sys.exit(helpers.ExitCode.FAILURE)
    jobmonitorserver_settings = helpers.config.items_as_dict(
        "JOBMONITOR_SERVER")
    helpers.make_dir_if_not_exists(jobmonitorserver_settings["download_dir"])

    try:
        tornado.options.parse_command_line()

        # set up converter server
        def start_http_server():
            _logger.info('Starting Converter Web Server...')
            temp = jobmonitorserver_settings.copy()
            del temp["allowed_auth_keys"]  # not used by web server
            settings = dict(debug=WEBSERVER_DEBUG_MODE_ENABLED,
                            cookie_secret=WEBSERVER_COOKIE_SECRET,
                            template_path=os.path.join(
                                os.path.dirname(__file__), "templates"),
                            static_path=os.path.join(os.path.dirname(__file__),
                                                     "static"),
                            xsrf_cookies=WEBSERVER_XSRF_COOKIES_ENABLED,
                            jobmonitorserver=temp)
            if WEBSERVER_DEBUG_MODE_ENABLED:
                _logger.warn("-" * 80)
                _logger.warn(" " * 10 + "!!! DEBUG MODE ENABLED !!!")
                _logger.warn("-" * 80)
            else:
                _logger.warn("-" * 80)
                _logger.warn(" " * 10 + "!!! PRODUCTION MODE ENABLED !!!")
                _logger.warn("-" * 80)

            webapp = converterwebapp.ConverterWebApp(**settings)
            global web_server
            web_server = converterhttpserver.ConverterHTTPServer(webapp)
            web_server.listen(WEBSERVER_PORT)

        # set up job monitor server
        def start_tcp_server():
            _logger.info('Starting Job Monitor Server...')
            global tcp_server
            global tcp_io_loop
            ssl_ctx = ssl.create_default_context(
                ssl.Purpose.CLIENT_AUTH)  #@UndefinedVariable
            ssl_ctx.load_cert_chain(certfile=CERTIFICATE_PATH,
                                    keyfile=CERTIFICATE_KEY_PATH)
            tcp_io_loop = tornado.ioloop.IOLoop()
            tcp_io_loop.make_current()
            tcp_server = jobmonitortcpserver.JobMonitorTCPServer(
                settings=jobmonitorserver_settings,
                io_loop=tcp_io_loop,
                ssl_options=ssl_ctx)
            tcp_server.listen(JOBMONITORSERVER_PORT)
            tcp_io_loop.start()

        from thread import start_new_thread
        start_new_thread(start_http_server, ())
        start_new_thread(start_tcp_server, ())

        # set up signal handler
        signal.signal(signal.SIGTERM, sig_handler)  #@UndefinedVariable
        signal.signal(signal.SIGINT, sig_handler)  #@UndefinedVariable

        # start IOLoop
        tornado.ioloop.IOLoop.instance().start()
        _logger.debug('bye')
    except:
        _logger.error("Server crashed or unable to start server",
                      exc_info=True)
        sys.exit(helpers.ExitCode.FAILURE)
#  You should have received a copy of the GNU Affero General Public License
#  along with this program.  If not, see <http://www.gnu.org/licenses/>.

import logging
import ast
from command import Command
from websocketserver.protocol.message.base.error_message import ErrorMessage
from websocketserver.protocol.message.base.info_message import InfoMessage
from websocketserver.protocol.job import Job
import helpers as webhelpers
from scratchtocatrobat.tools import helpers
from schedule_job_command import get_jobs_of_client

_logger = logging.getLogger(__name__)

CATROBAT_LANGUAGE_VERSION = float(helpers.catrobat_info("catrobat_language_version"))


class RetrieveInfoCommand(Command):

    def execute(self, ctxt, args):
        client_ID = ctxt.handler.get_client_ID()
        assert self.is_valid_client_ID(ctxt.redis_connection, client_ID)

        redis_conn = ctxt.redis_connection
        jobs = get_jobs_of_client(redis_conn, client_ID)
        assert isinstance(jobs, list)
        jobs_info = []
        for job in jobs:
            info = job.__dict__
            info["downloadURL"] = webhelpers.create_download_url(job.jobID, client_ID, job.title)
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#  GNU Affero General Public License for more details.
#
#  You should have received a copy of the GNU Affero General Public License
#  along with this program.  If not, see <http://www.gnu.org/licenses/>.

import logging
from command import Command
from websocketserver.protocol.message.base.info_message import InfoMessage
import helpers as webhelpers
from scratchtocatrobat.tools import helpers
from schedule_job_command import get_jobs_of_client

_logger = logging.getLogger(__name__)

CATROBAT_LANGUAGE_VERSION = float(helpers.catrobat_info("catrobat_language_version"))


class RetrieveInfoCommand(Command):

    def execute(self, ctxt, args):
        client_ID = ctxt.handler.get_client_ID()
        assert self.is_valid_client_ID(ctxt.redis_connection, client_ID)

        redis_conn = ctxt.redis_connection
        jobs = get_jobs_of_client(redis_conn, client_ID)
        assert isinstance(jobs, list)
        jobs_info = []
        for job in jobs:
            info = job.__dict__
            info["downloadURL"] = webhelpers.create_download_url(job.jobID, client_ID, job.title)
Exemple #4
0
#  along with this program.  If not, see <http://www.gnu.org/licenses/>.

import logging
import ast
from command import Command
from websocketserver.protocol.message.base.error_message import ErrorMessage
from websocketserver.protocol.message.base.info_message import InfoMessage
from websocketserver.protocol.job import Job
import helpers as webhelpers
from scratchtocatrobat.tools import helpers
from schedule_job_command import get_jobs_of_client

_logger = logging.getLogger(__name__)

CATROBAT_LANGUAGE_VERSION = float(
    helpers.catrobat_info("catrobat_language_version"))


class RetrieveInfoCommand(Command):
    def execute(self, ctxt, args):
        client_ID = ctxt.handler.get_client_ID()
        assert self.is_valid_client_ID(ctxt.redis_connection, client_ID)

        redis_conn = ctxt.redis_connection
        jobs = get_jobs_of_client(redis_conn, client_ID)
        assert isinstance(jobs, list)
        jobs_info = []
        for job in jobs:
            info = job.__dict__
            info["downloadURL"] = webhelpers.create_download_url(
                job.jobID, client_ID, job.title)
Exemple #5
0
def main():
    logging.basicConfig(
        filename=None,
        level=logging.DEBUG,
        format='%(asctime)s: %(levelname)7s: [%(name)s]: %(message)s',
        datefmt='%Y-%m-%d %H:%M:%S',
    )
    if not os.path.isfile(CERTIFICATE_PATH):
        _logger.error("Cannot find server certificate: %s", CERTIFICATE_PATH)
        return
    if not os.path.isfile(CERTIFICATE_KEY_PATH):
        _logger.error("Cannot find server certificate key: %s", CERTIFICATE_KEY_PATH)
        return

    try:
        converterwebapp._MainHandler.app_data = helpers.config.items_as_dict("APPLICATION")
        converterwebapp._MainHandler.app_data["catrobat_language_version"] = helpers.catrobat_info("catrobat_language_version")
    except:
        _logger.error("Error fetching application data", exc_info=True)
        sys.exit(helpers.ExitCode.FAILURE)
    jobmonitorserver_settings = helpers.config.items_as_dict("JOBMONITOR_SERVER")
    helpers.make_dir_if_not_exists(jobmonitorserver_settings["download_dir"])

    try:
        tornado.options.parse_command_line()

        # set up converter server
        def start_http_server():
            _logger.info('Starting Converter Web Server...')
            temp = jobmonitorserver_settings.copy()
            del temp["allowed_auth_keys"] # not used by web server
            settings = dict(
                debug=WEBSERVER_DEBUG_MODE_ENABLED,
                cookie_secret=WEBSERVER_COOKIE_SECRET,
                template_path=os.path.join(os.path.dirname(__file__), "templates"),
                static_path=os.path.join(os.path.dirname(__file__), "static"),
                xsrf_cookies=WEBSERVER_XSRF_COOKIES_ENABLED,
                jobmonitorserver=temp
            )
            if WEBSERVER_DEBUG_MODE_ENABLED:
                _logger.warn("-"*80)
                _logger.warn(" "*10 + "!!! DEBUG MODE ENABLED !!!")
                _logger.warn("-"*80)

            webapp = converterwebapp.ConverterWebApp(**settings)
            global web_server
            web_server = converterhttpserver.ConverterHTTPServer(webapp)
            web_server.listen(WEBSERVER_PORT)

        # set up job monitor server
        def start_tcp_server():
            _logger.info('Starting Job Monitor Server...')
            global tcp_server
            global tcp_io_loop
            ssl_ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) #@UndefinedVariable
            ssl_ctx.load_cert_chain(certfile=CERTIFICATE_PATH, keyfile=CERTIFICATE_KEY_PATH)
            tcp_io_loop = tornado.ioloop.IOLoop()
            tcp_io_loop.make_current()
            tcp_server = jobmonitortcpserver.JobMonitorTCPServer(
                             settings=jobmonitorserver_settings,
                             io_loop=tcp_io_loop,
                             ssl_options=ssl_ctx)
            tcp_server.listen(JOBMONITORSERVER_PORT)
            tcp_io_loop.start()

        from thread import start_new_thread
        start_new_thread(start_http_server,())
        start_new_thread(start_tcp_server,())

        # set up signal handler
        signal.signal(signal.SIGTERM, sig_handler) #@UndefinedVariable
        signal.signal(signal.SIGINT, sig_handler) #@UndefinedVariable

        # start IOLoop
        tornado.ioloop.IOLoop.instance().start()
        _logger.debug('bye')
    except:
        _logger.error("Server crashed or unable to start server", exc_info=True)
        sys.exit(helpers.ExitCode.FAILURE)
Exemple #6
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
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:
            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)

        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
            if scratch_project_file_or_url.startswith("https://"):
                is_local_project = False
                if not scratchwebapi.is_valid_project_url(scratch_project_file_or_url):
                    raise common.ScratchtobatError("Invalid URL for Scratch-project given: %s" %
                                                   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)
                if scratchwebapi.request_project_visibility_state_for(project_ID) != 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)

            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

            if is_local_project:
                project = scratch.RawProject.from_project_folder_path(scratch_project_dir)
                progress_bar.expected_progress = project.expected_progress_of_local_project(progress_bar)

            project = scratch.Project(scratch_project_dir, progress_bar=progress_bar)
            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