403Webshell
Server IP : 185.208.173.17  /  Your IP : 87.236.161.98
Web Server : Microsoft-IIS/10.0
System : Windows NT SRV8576125506 10.0 build 26100 (Windows Server 2016) AMD64
User : IUSR ( 0)
PHP Version : 7.4.13
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : OFF  |  Perl : OFF  |  Python : OFF  |  Sudo : OFF  |  Pkexec : OFF
Directory :  /Program Files/MySQL/MySQL Workbench 8.0/swb/shell/lib/mysqlsh/plugins/mrs_plugin/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /Program Files/MySQL/MySQL Workbench 8.0/swb/shell/lib/mysqlsh/plugins/mrs_plugin/content_sets.py
# Copyright (c) 2021, 2025, Oracle and/or its affiliates.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License, version 2.0,
# as published by the Free Software Foundation.
#
# This program is designed to work with certain software (including
# but not limited to OpenSSL) that is licensed under separate terms, as
# designated in a particular file or component or in included license
# documentation.  The authors of MySQL hereby grant you an additional
# permission to link the program and your derivative works with the
# separately licensed software that they have either included with
# the program or referenced in the documentation.
#
# This program is distributed in the hope that it will be useful,  but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
# the GNU General Public License, version 2.0, for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

"""Sub-Module for managing MRS content sets"""

# cSpell:ignore mysqlsh, mrs

from mysqlsh.plugin_manager import plugin_function
import mrs_plugin.lib as lib
from .interactive import resolve_service, resolve_content_set, resolve_overwrite_file, resolve_file_path

import os
import mysqlsh
import json
import shutil
from pathlib import Path

# TODO (miguel): replace this with the one in interactive module


def resolve_content_set_id(**kwargs):
    request_path = kwargs.get("request_path")
    session = kwargs.get("session")
    content_set_id = kwargs.get("content_set_id")

    service_id = kwargs.pop("service_id", None)
    auto_select_single = kwargs.pop("auto_select_single", False)

    # if the supplied content set id is valid...
    if content_set_id:
        return kwargs

    # check if there is a current content set from the config
    mrs_config = lib.core.get_current_config()
    content_set_id = mrs_config.get('current_content_set_id')

    # if the current content set was found, return it
    if content_set_id:
        kwargs["content_set_id"] = content_set_id
        return kwargs

    # last choice is to use the request path
    lib.core.Validations.request_path(request_path)

    # get the service object specified by the service id or the default one
    service = lib.services.get_service(
        service_id=service_id, session=session, get_default=True)

    service_id = service.get("id")

    # get the list of existing content sets
    content_sets = lib.content_sets.get_content_sets(session=session,
                                                     service_id=service_id, request_path=request_path)

    # if no content sets were found, this will cancel the call
    if not content_sets:
        raise ValueError(
            "Unable to determine a unique content set for the operation.")

    # If there is exactly one service, set id to its id
    if len(content_sets) == 1 and auto_select_single:
        kwargs["content_set_id"] = content_sets[0]["id"]
        return kwargs

    if not lib.core.get_interactive_default():
        raise ValueError("Operation cancelled.")

    # allow the user to select from a list of content sets
    print(f"Content Set Listing for Service "
          f"{service.get('url_host_name')}"
          f"{service.get('url_context_root')}")

    selected_item = lib.core.prompt_for_list_item(
        item_list=content_sets,
        prompt_caption=("Please select an index or type "
                        "the content set name: "),
        item_name_property="request_path",
        given_value=None,
        print_list=True)

    if not selected_item:
        raise ValueError("Operation cancelled.")

    kwargs["content_set_id"] = selected_item
    return kwargs


def resolve_content_set_ids(**kwargs):
    include_enable_state = None
    session = kwargs.get("session")

    content_set_id = kwargs.pop("content_set_id", None)
    request_path = kwargs.pop("request_path", None)
    service_id = kwargs.pop("service_id", None)

    kwargs["content_set_ids"] = [content_set_id] if content_set_id else []

    if not content_set_id:
        # Check if given service_id exists or use the current service
        service = lib.services.get_service(
            service_id=service_id, session=session)

        if not request_path and lib.core.get_interactive_default():
            content_sets = lib.content_sets.get_content_sets(
                service_id=service.get("id"),
                include_enable_state=include_enable_state,
                session=session)
            caption = ("Please select an index, type "
                       "the request_path or type '*' "
                       "to select all: ")
            selection = lib.core.prompt_for_list_item(
                item_list=content_sets,
                prompt_caption=caption,
                item_name_property="request_path",
                given_value=None,
                print_list=True,
                allow_multi_select=True)
            if not selection:
                raise ValueError("Operation cancelled.")

            kwargs["content_set_ids"] = [item["id"] for item in selection]

        if request_path:
            # Lookup the content_set name
            res = session.run_sql(
                """
                SELECT id FROM `mysql_rest_service_metadata`.`content_set`
                WHERE request_path = ? AND service_id = ?
                """,
                [request_path, service.get("id")])
            row = res.fetch_one()
            if row:
                kwargs["content_set_ids"].append(row.get_field("id"))

    return kwargs


def generate_create_statement(**kwargs) -> str:
    lib.core.convert_ids_to_binary(["service_id", "content_set_id"], kwargs)
    service_id = kwargs.get("service_id")
    content_set_id = kwargs.get("content_set_id")
    allow_load_scripts = kwargs.get("allow_load_scripts", False)

    with lib.core.MrsDbSession(exception_handler=lib.core.print_exception, **kwargs) as session:
        content_set = resolve_content_set(session, content_set_id, service_id)

        return lib.content_sets.get_content_set_create_statement(session, content_set, allow_load_scripts)


@plugin_function('mrs.add.contentSet', shell=True, cli=True, web=True)
def add_content_set(service_id=None, content_dir=None, **kwargs):
    """Adds content to the given MRS service

    Args:
        service_id (str): The id of the service the schema should be added to
        content_dir (str): The path to the content directory
        **kwargs: Additional options

    Keyword Args:
        request_path (str): The request_path
        requires_auth (bool): Whether authentication is required to access
            the content
        comments (str): Comments about the content
        enabled (int): Whether to enable the content set after all files are uploaded
        options (dict): The options as JSON string
        replace_existing (bool): Whether to replace a content set that uses the same request_path
        ignore_list (str): List of files and directories to ignore, separated by comma
        session (object): The database session to use.
        send_gui_message (object): The function to send a message to he GUI.

    Returns:
        None in interactive mode, a dict with content_set_id and
            number_of_files_uploaded
    """
    if service_id is not None:
        service_id = lib.core.id_to_binary(service_id, "service_id")

    request_path = kwargs.get("request_path")
    requires_auth = kwargs.get("requires_auth")
    comments = kwargs.get("comments")
    enabled = kwargs.get("enabled", 1)
    options = lib.core.convert_json(kwargs.get("options", {}))
    replace_existing = kwargs.get("replace_existing", False)
    ignore_list = kwargs.get("ignore_list")

    interactive = lib.core.get_interactive_default()

    send_gui_message = kwargs.get("send_gui_message")

    with lib.core.MrsDbSession(exception_handler=lib.core.print_exception, **kwargs) as session:
        kwargs["session"] = session
        kwargs["service_id"] = service_id
        service = resolve_service(session, service_id)

        # Get request_path
        if not request_path and interactive:
            request_path = lib.core.prompt(
                "Please enter the request path for this content set ["
                f"/content]: ",
                {'defaultValue': '/content'}).strip()

        lib.core.Validations.request_path(request_path, session=session)

        # Get the content_dir
        if not content_dir and interactive:
            content_dir = lib.core.prompt(
                message=('Please enter the file path to the directory '
                         'that contains the static content: '))


        # Get requires_auth
        if requires_auth is None:
            if interactive:
                requires_auth = lib.core.prompt(
                    "Should the content require authentication [y/N]: ",
                    {'defaultValue': 'n'}).strip().lower() == 'y'
            else:
                requires_auth = False

        # Get comments
        if not comments and interactive:
            comments = lib.core.prompt_for_comments()

        with lib.core.MrsDbTransaction(session):
            if replace_existing:
                content_set = lib.content_sets.get_content_set(session,
                                                               service.get("id"), request_path)
                if content_set:
                    lib.core.delete(table="content_set",
                                    where="id=?").exec(session, [content_set.get("id")])

            # Create the content_set
            content_set_id, files_added = lib.content_sets.add_content_set(
                session, service.get("id"),
                request_path,
                requires_auth,
                comments, options,
                enabled=enabled,
                content_dir=content_dir,
                service=service,
                send_gui_message=send_gui_message,
                ignore_list=ignore_list)

        if lib.core.get_interactive_result():
            return f"\nThe REST content set was added successfully."
        else:
            return {
                "content_set_id": content_set_id,
                "number_of_files_uploaded": files_added
            }

@plugin_function('mrs.get.contentSetCount', shell=False, cli=False, web=True)
def get_content_set_count(service_id=None, **kwargs):
    """Returns all content sets for the given MRS service

    Args:
        service_id (str): The id of the service to list the content sets from
        **kwargs: Additional options

    Keyword Args:
        session (object): The database session to use.

    Returns:
        The number of content sets of the given service
    """
    with lib.core.MrsDbSession(exception_handler=lib.core.print_exception, **kwargs) as session:
        # Check the given service_id or get the default if none was given
        service = lib.services.get_service(
            service_id=service_id, session=session)

@plugin_function('mrs.list.contentSets', shell=True, cli=True, web=True)
def get_content_sets(service_id=None, **kwargs):
    """Returns all content sets for the given MRS service

    Args:
        service_id (str): The id of the service to list the content sets from
        **kwargs: Additional options

    Keyword Args:
        include_enable_state (bool): Only include items with the given
            enabled state
        request_path (str): The request_path of the content_set
        session (object): The database session to use.

    Returns:
        Either a string listing the content sets when interactive is set or list
        of dicts representing the content sets
    """
    if service_id is not None:
        service_id = lib.core.id_to_binary(service_id, "service_id")

    include_enable_state = kwargs.get("include_enable_state")

    with lib.core.MrsDbSession(exception_handler=lib.core.print_exception, **kwargs) as session:
        # Check the given service_id or get the default if none was given
        service = lib.services.get_service(
            service_id=service_id, session=session)
        content_sets = lib.content_sets.get_content_sets(session=session,
                                                         service_id=service.get(
                                                             "id"),
                                                         include_enable_state=include_enable_state)

        if lib.core.get_interactive_result():
            return lib.content_sets.format_content_set_listing(
                content_sets=content_sets, print_header=True)

        return content_sets


@plugin_function('mrs.get.contentSet', shell=True, cli=True, web=True)
def get_content_set(**kwargs):
    """Gets a specific MRS content_set

    Args:
        **kwargs: Additional options

    Keyword Args:
        content_set_id (str): The id of the content_set
        service_id (str): The id of the service
        request_path (str): The request_path of the content_set
        auto_select_single (bool): If there is a single service only, use that
        session (object): The database session to use.

    Returns:
        The schema as dict or None on error in interactive mode
    """
    lib.core.convert_ids_to_binary(["content_set_id", "service_id"], kwargs)

    with lib.core.MrsDbSession(exception_handler=lib.core.print_exception, **kwargs) as session:
        kwargs["session"] = session
        return lib.content_sets.get_content_set(**resolve_content_set_id(**kwargs))


@plugin_function('mrs.enable.contentSet', shell=True, cli=True, web=True)
def enable_content_set(**kwargs):
    """Enables a content set of the given service

    Args:
        **kwargs: Additional options

    Keyword Args:
        service_id (str): The id of the service
        content_set_id (str): The id of the content_set
        session (object): The database session to use.

    Returns:
        The result message as string
    """

    lib.core.convert_ids_to_binary(["content_set_id", "service_id"], kwargs)

    kwargs["value"] = True

    with lib.core.MrsDbSession(exception_handler=lib.core.print_exception, **kwargs) as session:
        kwargs["session"] = session
        kwargs = resolve_content_set_ids(**kwargs)
        with lib.core.MrsDbTransaction(session):
            lib.content_sets.enable_content_set(**kwargs)

        if len(kwargs['content_set_ids']) == 1:
            return f"The content set has been enabled."

        return f"The content sets have been enabled."


@plugin_function('mrs.disable.contentSet', shell=True, cli=True, web=True)
def disable_content_set(**kwargs):
    """Enables a content_set of the given service

    Args:
        **kwargs: Additional options

    Keyword Args:
        service_id (str): The id of the service
        content_set_id (str): The id of the content_set
        session (object): The database session to use.

    Returns:
        The result message as string
    """
    lib.core.convert_ids_to_binary(["content_set_id", "service_id"], kwargs)

    kwargs["value"] = False

    with lib.core.MrsDbSession(exception_handler=lib.core.print_exception, **kwargs) as session:
        kwargs["session"] = session
        kwargs = resolve_content_set_ids(**kwargs)
        with lib.core.MrsDbTransaction(session):
            lib.content_sets.enable_content_set(**kwargs)

        if len(kwargs['content_set_ids']) == 1:
            return f"The content set has been disabled."

        return f"The content sets have been disabled."


@plugin_function('mrs.delete.contentSet', shell=True, cli=True, web=True)
def delete_content_set(**kwargs):
    """Delete a content_set of the given service

    Args:
        **kwargs: Additional options

    Keyword Args:
        content_set_id (str): The id of the content_set
        service_id (str): The id of the service
        request_path (str): The request_path of the content_set
        session (object): The database session to use.

    Returns:
        The result message as string
    """
    lib.core.convert_ids_to_binary(["content_set_id", "service_id"], kwargs)

    with lib.core.MrsDbSession(exception_handler=lib.core.print_exception, **kwargs) as session:
        kwargs["session"] = session
        kwargs = resolve_content_set_ids(**kwargs)
        with lib.core.MrsDbTransaction(session):
            lib.content_sets.delete_content_set(**kwargs)

        if len(kwargs['content_set_ids']) == 1:
            return f"The content set has been deleted."

        return f"The content sets have been deleted."


@plugin_function('mrs.get.fileMrsScriptDefinitions', shell=True, cli=True, web=True)
def get_file_mrs_script_definitions(path, **kwargs):
    """Returns the MRS Scripts definitions for the given file

    Args:
        path (str): The path to check
        **kwargs: Additional options

    Keyword Args:
        language (str): The language the MRS Scripts are written in

    Returns:
        A Dict with the MRS Scripts definitions or None if the lastModification matches the one of the file
    """

    language = kwargs.get("language")
    if language is None:
        raise ValueError("No language given.")

    script_def = lib.content_sets.get_file_mrs_script_definitions(
        path=path, language=language)

    return script_def


@plugin_function('mrs.get.folderMrsScriptLanguage', shell=True, cli=True, web=True)
def get_folder_mrs_scripts_language(path, **kwargs):
    """Checks if the given path contains MRS Scripts

    Args:
        path (str): The path to check
        **kwargs: Additional options

    Keyword Args:
        ignore_list (str): The list of file patterns to ignore, separated by comma

    Returns:
        "TypeScript" or None
    """

    ignore_list = kwargs.get("ignore_list", "*node_modules/*")

    mrs_scripts_language = lib.content_sets.get_folder_mrs_scripts_language(
        path, ignore_list)

    if lib.core.get_interactive_default():
        if mrs_scripts_language is not None:
            print(f"This folder contains MRS Scripts written in {mrs_scripts_language}.")
        else:
            print("This folder does not contain MRS Scripts.")
    else:
        return mrs_scripts_language


@plugin_function('mrs.get.folderMrsScriptDefinitions', shell=True, cli=True, web=True)
def get_folder_mrs_script_definitions(path, **kwargs):
    """Returns the MRS Scripts definitions for the given folder

    Args:
        path (str): The path to check
        **kwargs: Additional options

    Keyword Args:
        ignore_list (str): The list of file patterns to ignore, separated by comma
        language (str): The language the MRS Scripts are written in
        send_gui_message (object): The function to send a message to he GUI.

    Returns:
        A Dict with the MRS Scripts definitions
    """

    ignore_list = kwargs.get("ignore_list", "*node_modules/*")
    language = kwargs.get(
        "language", lib.content_sets.get_folder_mrs_scripts_language(path, ignore_list))
    send_gui_message = kwargs.get("send_gui_message")

    if language is None:
        raise ValueError(
            "The given file path does not contain any MRS Scripts.")

    script_def = lib.content_sets.get_folder_mrs_script_definitions(
        path=path, ignore_list=ignore_list, language=language, send_gui_message=send_gui_message)

    if lib.core.get_interactive_default():
        print(json.dumps(script_def, indent=4))
    else:
        return script_def


@plugin_function('mrs.update.mrsScriptsFromContentSet', shell=True, cli=True, web=True)
def update_scripts_from_content_set(**kwargs):
    """Updates db_schemas and db_objects based on script definitions of the content set

    Args:
        **kwargs: Additional options

    Keyword Args:
        content_set_id (str): The id of the content_set
        ignore_list (str): The list of file patterns to ignore, separated by comma
        language (str): The MRS Scripting language used
        session (object): The database session to use.
        send_gui_message (object): The function to send a message to he GUI.

    Returns:
        The result message as string
    """
    lib.core.convert_ids_to_binary(["content_set_id"], kwargs)

    language = kwargs.get("language")
    send_gui_message = kwargs.get("send_gui_message")

    with lib.core.MrsDbSession(exception_handler=lib.core.print_exception, **kwargs) as session:
        kwargs["session"] = session
        kwargs = resolve_content_set_ids(**kwargs)

        if len(kwargs['content_set_ids']) >= 1:
            content_set_id = kwargs['content_set_ids'][0]

        with lib.core.MrsDbTransaction(session):
            lib.content_sets.update_scripts_from_content_set(
                session=session, content_set_id=content_set_id, language=language,
                send_gui_message=send_gui_message)


@plugin_function('mrs.get.contentSetCreateStatement', shell=True, cli=True, web=True)
def get_create_statement(**kwargs):
    """Returns the corresponding CREATE REST CONTENT SET SQL statement of the given MRS service object.

    Args:
        **kwargs: Options to determine what should be generated.

    Keyword Args:
        service_id (str): The ID of the service where the schema belongs.
        content_set_id (str): The ID of the content set to generate.
        allow_load_scripts (bool): If the LOAD SCRIPTS is to be used when applicable
        session (object): The database session to use.

    Returns:
        The SQL that represents the create statement for the MRS content set
    """
    return generate_create_statement(**kwargs)


@plugin_function('mrs.dump.contentSetCreateStatement', shell=True, cli=True, web=True)
def store_create_statement(**kwargs):
    """Stores the corresponding CREATE REST CONTENT SET SQL statement of the given MRS service
    into a file.

    Args:
        **kwargs: Options to determine what should be generated.

    Keyword Args:
        service_id (str): The ID of the service where the schema belongs.
        content_set_id (str): The ID of the content set to dump.
        allow_load_scripts (bool): If the LOAD SCRIPTS is to be used when applicable
        file_path (str): The path where to store the file.
        overwrite (bool): Overwrite the file, if already exists.
        session (object): The database session to use.

    Returns:
        True if the file was saved.
    """
    file_path = kwargs.get("file_path")
    overwrite = kwargs.get("overwrite")

    file_path = resolve_file_path(file_path)
    resolve_overwrite_file(file_path, overwrite)

    sql = generate_create_statement(**kwargs)

    with open(file_path, "w") as f:
        f.write(sql)

    if lib.core.get_interactive_result():
        return f"File created in {file_path}."

    return True

Youez - 2016 - github.com/yon3zu
LinuXploit