from argparse import _SubParsersAction
from functools import partial
from typing import List
from lxml import etree
from lxml.objectify import SubElement, IntElement, StringElement, BoolElement
from q2_sdk.core.dynamic_imports import (
api_ExecuteStoredProcedure as ExecuteStoredProcedure,
)
from q2_sdk.hq.models.ui_text import UiText as UiTextModel
from q2_sdk.tools.decorators import dev_only
from .db_object import DbObject
from .language import Language
from .representation_row_base import RepresentationRowBase
from q2_sdk.hq.db.audit_record import AuditRecord
[docs]
class UiTextRow(RepresentationRowBase):
Description: StringElement = "Description"
Language: StringElement = "Language"
ShortName: StringElement = "ShortName"
TextValue: StringElement = "TextValue"
UiTextElementID: IntElement = "UiTextElementID"
UiTextID: IntElement = "UiTextID"
UiSelectionID: IntElement = "UiSelectionID"
ContainsMarkup: BoolElement = "ContainsMarkup"
[docs]
class UiText(DbObject):
GET_BY_NAME_KEY = "ShortName"
NAME = "UiText"
REPRESENTATION_ROW_CLASS = UiTextRow
[docs]
def add_arguments(self, parser: _SubParsersAction):
subparser = parser.add_parser("get_ui_text")
subparser.set_defaults(parser="get_ui_text")
subparser.set_defaults(func=partial(self.get, serialize_for_cli=True))
subparser.add_argument("prefix", help="Shortname prefix for Text Element")
subparser.add_argument(
"--ui-selection", help="Shortname of Q2_UiSelection.ShortName"
)
subparser.add_argument(
"--no-trunc",
action="store_true",
help="Do not truncate TextValue of results",
)
subparser = parser.add_parser("add_ui_text")
subparser.set_defaults(parser="add_ui_text")
subparser.set_defaults(func=partial(self.create, serialize_for_cli=True))
subparser.add_argument("short_name", help="Shortname for Text Element")
subparser.add_argument("description", help="Description for Text Element")
subparser.add_argument("text_value", help="UiText.TextValue")
subparser.add_argument(
"--language", "-l", default="USEnglish", help="English by default"
)
subparser.add_argument(
"--ui-selection", help="Shortname of Q2_UiSelection.ShortName"
)
subparser.add_argument("--contains-markup", default=0, help="0 by default")
subparser = parser.add_parser("update_ui_text")
subparser.set_defaults(parser="update_ui_text")
subparser.set_defaults(func=partial(self.update))
subparser.add_argument("short_name", help="Shortname for Text Element")
subparser.add_argument("text_value", help="UiText.TextValue")
subparser.add_argument(
"--language", default="USEnglish", help="English by default"
)
subparser.add_argument(
"--device_name", default="Browser", help="Browser by default"
)
subparser.add_argument(
"--ui-selection", help="Shortname of Q2_UiSelection.ShortName"
)
subparser.add_argument("--contains-markup", default=0, help="0 by default")
subparser = parser.add_parser("remove_ui_text")
subparser.set_defaults(parser="remove_ui_text")
subparser.set_defaults(func=partial(self.delete))
subparser.add_argument("short_name", help="Shortname for Text Element")
subparser.add_argument("--ui-selection-id", help="Q2_UiSelection.UiSelectionID")
[docs]
async def get(
self, prefix: str, no_trunc=False, serialize_for_cli=False, ui_selection=None
) -> List[UiTextRow]:
truncate = not no_trunc
parameters = [
ExecuteStoredProcedure.SqlParam(
ExecuteStoredProcedure.DataType.VarChar, "prefix", prefix
)
]
if ui_selection:
parameters.append(
ExecuteStoredProcedure.SqlParam(
ExecuteStoredProcedure.DataType.VarChar, "uiselection", ui_selection
)
)
response = await self.call_hq(
"sdk_GetUIText", ExecuteStoredProcedure.SqlParameters(parameters)
)
if serialize_for_cli:
fields_to_truncate = []
if truncate:
fields_to_truncate = ["TextValue"]
response = self.serialize_for_cli(
response,
fields_to_display=[
"ShortName",
"Description",
"TextValue",
"Language",
"UiSelectionID",
"ContainsMarkup",
],
fields_to_truncate=fields_to_truncate,
)
return response
[docs]
async def get_by_name(self, name: str, **kwargs) -> UiTextRow:
return await super().get_by_name(name, prefix=name)
async def _get_language_map(self, ui_text_objs: List[UiTextModel]) -> dict:
languages = set([x.language for x in ui_text_objs])
language_map = {}
all_languages = await Language(self.logger, self.hq_credentials).get()
for language in all_languages:
if language.ShortName.text in languages:
language_map[language.ShortName.text] = language.UiLanguageID.pyval
return language_map
[docs]
async def create_bulk(self, ui_text_objs: List[UiTextModel]):
language_map = await self._get_language_map(ui_text_objs)
root_node = etree.Element("Root")
for elem in ui_text_objs:
if elem.language in language_map:
SubElement(
root_node,
"UiText",
ShortName=elem.prefixed_short_name,
Description=elem.description,
TextValue=elem.text_value,
UIDeviceID=str(elem.device_id),
UILanguageID=str(language_map[elem.language]),
UISelectionID=str(elem.ui_selection_id)
if elem.ui_selection_id
else "",
ContainsMarkup=str(elem.contains_markup),
)
for child in root_node.findall("UiText"):
if child.attrib["UISelectionID"] == "":
del child.attrib["UISelectionID"]
xml_payload = etree.tostring(root_node).decode()
res = await self.call_hq(
"sdk_AddUITextBulk",
ExecuteStoredProcedure.SqlParameters([
ExecuteStoredProcedure.SqlParam(
ExecuteStoredProcedure.DataType.Xml, "xml_payload", xml_payload
)
]),
)
return res
[docs]
async def create(
self,
short_name,
description,
text_value,
device_id=1,
language="USEnglish",
ui_selection=None,
serialize_for_cli=False,
contains_markup=False,
) -> UiTextRow:
"""Adds UiText and related UiTextElement row"""
parameters = [
ExecuteStoredProcedure.SqlParam(
ExecuteStoredProcedure.DataType.VarChar, "short_name", short_name
),
ExecuteStoredProcedure.SqlParam(
ExecuteStoredProcedure.DataType.VarChar, "description", description
),
ExecuteStoredProcedure.SqlParam(
ExecuteStoredProcedure.DataType.VarChar, "text_value", text_value
),
ExecuteStoredProcedure.SqlParam(
ExecuteStoredProcedure.DataType.Int, "device_id", device_id
),
ExecuteStoredProcedure.SqlParam(
ExecuteStoredProcedure.DataType.VarChar, "language", language
),
ExecuteStoredProcedure.SqlParam(
ExecuteStoredProcedure.DataType.VarChar, "uiselection", ui_selection
),
]
if contains_markup:
parameters.append(
ExecuteStoredProcedure.SqlParam(
ExecuteStoredProcedure.DataType.Bit,
"contains_markup",
str(contains_markup).lower(),
)
)
await self.call_hq(
"sdk_AddUIText", ExecuteStoredProcedure.SqlParameters(parameters)
)
ui_text_row = await self.get(short_name)
if serialize_for_cli:
response = self.serialize_for_cli(
ui_text_row,
fields_to_display=[
"UiTextID",
"ShortName",
"Description",
"TextValue",
"Language",
"UiSelectionID",
"ContainsMarkup",
],
)
return response
return ui_text_row[0]
[docs]
async def create_per_language(
self,
short_name,
description,
text_value,
device_id=1,
exclude_language: list = None,
contains_markup=0,
):
languages = await Language(self.logger, self.hq_credentials).get()
for language in languages:
language_name = language.ShortName.text
if exclude_language and language_name in exclude_language:
continue
await self.create(
short_name,
description,
text_value,
device_id,
language=language_name,
contains_markup=contains_markup,
)
[docs]
async def create_central(
self, short_name, descrition, text_value, language="USEnglish"
):
parameters = ExecuteStoredProcedure.SqlParameters([
ExecuteStoredProcedure.SqlParam(
data_type=ExecuteStoredProcedure.DataType.VarChar,
name="short_name",
value=short_name,
),
ExecuteStoredProcedure.SqlParam(
data_type=ExecuteStoredProcedure.DataType.VarChar,
name="text_value",
value=text_value,
),
ExecuteStoredProcedure.SqlParam(
data_type=ExecuteStoredProcedure.DataType.VarChar,
name="language",
value=language,
),
ExecuteStoredProcedure.SqlParam(
data_type=ExecuteStoredProcedure.DataType.VarChar,
name="description",
value=descrition,
),
])
text_return = await self.call_hq("sdk_AddCentralText", parameters)
return text_return[0]
[docs]
async def update(
self,
short_name: str,
text_value: str,
language="USEnglish",
device_name="Browser",
ui_selection=None,
contains_markup: int = None,
):
parameters = [
ExecuteStoredProcedure.SqlParam(
data_type=ExecuteStoredProcedure.DataType.VarChar,
name="short_name",
value=short_name,
),
ExecuteStoredProcedure.SqlParam(
data_type=ExecuteStoredProcedure.DataType.VarChar,
name="text_value",
value=text_value,
),
ExecuteStoredProcedure.SqlParam(
data_type=ExecuteStoredProcedure.DataType.VarChar,
name="language",
value=language,
),
ExecuteStoredProcedure.SqlParam(
data_type=ExecuteStoredProcedure.DataType.VarChar,
name="device_name",
value=device_name,
),
ExecuteStoredProcedure.SqlParam(
data_type=ExecuteStoredProcedure.DataType.VarChar,
name="ui_selection",
value=ui_selection,
),
]
if contains_markup is not None:
parameters.append(
ExecuteStoredProcedure.SqlParam(
ExecuteStoredProcedure.DataType.Int,
"contains_markup",
contains_markup,
)
)
return await self.call_hq(
"sdk_UpdateUiText", ExecuteStoredProcedure.SqlParameters(parameters)
)
[docs]
async def delete(self, short_name, ui_selection_id=None):
result = await self.call_hq(
"sdk_RemoveUIText",
ExecuteStoredProcedure.SqlParameters([
ExecuteStoredProcedure.SqlParam(
ExecuteStoredProcedure.DataType.VarChar,
"short_name",
short_name,
),
ExecuteStoredProcedure.SqlParam(
ExecuteStoredProcedure.DataType.Int,
"ui_selection_id",
ui_selection_id,
),
]),
)
if self.hq_response.success:
audit = AuditRecord(self.logger, self.hq_credentials)
details = f"UiText delete successful. short_name: {short_name} ui_selection_id: {ui_selection_id}"
await audit.create(details, "SDK Session")
return result
[docs]
async def delete_central(self, short_name):
return await self.call_hq(
"sdk_RemoveAdminTextAndElement",
ExecuteStoredProcedure.SqlParameters([
ExecuteStoredProcedure.SqlParam(
ExecuteStoredProcedure.DataType.VarChar,
"short_name",
short_name,
)
]),
)
[docs]
@dev_only
async def delete_bulk(self, ui_text_objs: List[UiTextModel]):
"""Note: this only works in the dev environment"""
root_node = etree.Element("Root")
for elem in ui_text_objs:
SubElement(root_node, "UiText", ShortName=elem.prefixed_short_name)
xml_payload = etree.tostring(root_node).decode()
await self.call_hq(
"sdk_RemoveUITextBulk",
ExecuteStoredProcedure.SqlParameters([
ExecuteStoredProcedure.SqlParam(
ExecuteStoredProcedure.DataType.Xml, "xml_payload", xml_payload
)
]),
)