diff --git a/.gitignore b/.gitignore
index b6e4761..872c981 100644
--- a/.gitignore
+++ b/.gitignore
@@ -127,3 +127,5 @@ dmypy.json
# Pyre type checker
.pyre/
+
+.idea
diff --git a/README.md b/README.md
index 4914828..524f831 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,163 @@
# winsdk_toast
-A simple module for displaying Windows Toast Notification based on winsdk
+
+A simple package for displaying Windows Toast Notification based on [winsdk].
+
+Sometimes, after starting my data processing python script, I may surf the Internet.
+It chokes my happiness that to frequently check whether the script stops,
+or suddenly realize the script has stopped for a long while.
+
+It'll be reassuring that the script can stop with a friendly gesture.
+
+
+## Usage
+
+```python
+from os.path import abspath
+from winsdk_toast import Notifier, Toast
+
+path_pic = abspath('./example/resource/python.ico')
+
+notifier = Notifier('程序名 applicationId')
+
+# %% minimal example
+toast = Toast()
+toast.add_text('第一行 1st line')
+notifier.show(toast)
+# %% which is equivalent to
+xml = """
+
+
+
+ 第一行 1st line
+
+
+
+"""
+toast = Toast(xml)
+notifier.show(toast)
+
+
+# %% simple example
+toast = Toast()
+toast.add_text('第一行 1st line', hint_align='center', hint_style='caption')
+toast.add_text('第二行 2nd line')
+toast.add_text('第三行 3rd line', placement='attribution')
+toast.add_image(path_pic, placement='appLogoOverride')
+toast.add_action('关闭 Close')
+toast.set_audio(silent='true')
+notifier.show(toast)
+# %% which is equivalent to
+xml = f"""
+
+
+
+ 第一行 1st line
+ 第二行 2nd line
+ 第三行 3rd line
+
+
+
+
+
+
+
+"""
+toast = Toast(xml)
+notifier.show(toast)
+
+# %% example for control freak
+toast = Toast()
+element_toast = toast.set_toast(
+ launch='blah', duration='long', displayTimeStamp='2022-04-01T12:00:00Z', scenario='default',
+ useButtonStyle='false', activationType='background'
+)
+element_visual = toast.set_visual(
+ version='1', lang='zh-CN', baseUri='ms-appx:///', branding='none', addImageQuery='false'
+)
+element_binding = toast.set_binding(
+ template='ToastGeneric', fallback='2ndtemplate', lang='zh-CN', addImageQuery='false',
+ baseUri='ms-appx:///', branding='none'
+)
+element_text = toast.add_text(
+ text='第一行 1st line for control freak', id_='1', lang='zh-CN', placement=None,
+ hint_maxLines='1', hint_style='title', hint_align='center', hint_wrap='false',
+ element_parent=element_binding
+)
+element_group = toast.add_group()
+element_subgroup_left = toast.add_subgroup(element_parent=element_group)
+element_text = toast.add_text(
+ text='第二行 2nd line for control freak', id_='2', lang='zh-CN', placement=None,
+ hint_maxLines='1', hint_style='captionSubtle ', hint_align='left', hint_wrap='false',
+ element_parent=element_subgroup_left
+)
+element_subgroup_right = toast.add_subgroup(element_parent=element_group)
+element_text = toast.add_text(
+ text='第三行 3rd line for control freak', id_='3', lang='zh-CN', placement='attribution',
+ hint_maxLines='1', hint_style='captionSubtle', hint_align='left', hint_wrap='false',
+ element_parent=element_subgroup_right
+)
+toast.add_image(
+ path_pic, id_=None, alt='', addImageQuery='false',
+ placement='appLogoOverride', hint_crop='circle'
+)
+toast.set_actions()
+toast.add_action(
+ '关闭 Close', arguments='dismiss', activationType='system', placement=None,
+ imageUri=None, hint_inputId=None, hint_buttonStyle=None, hint_toolTip='tip close'
+)
+notifier.show(toast)
+# %% which is equivalent to
+xml = f"""
+
+
+
+ 第一行 1st line for control freak
+
+
+ 第二行 2nd line for control freak
+
+
+ 第三行 3rd line for control freak
+
+
+
+
+
+
+
+
+
+"""
+toast = Toast(xml)
+notifier.show(toast)
+```
+The corresponding effects are like:
+
+![minimal_example.gif](doc/pic/minimal_example.gif)
+
+![simple_example.gif](doc/pic/simple_example.gif)
+
+![example_for_control_freak.gif](doc/pic/example_for_control_freak.gif)
+
+
+## Todo
+
+- Events and callbacks.
+- Documentation.
+- Costume audio. According to [Microsoft Docs], this might be tricky.
+- ...
+
+[Microsoft Docs]: https://docs.microsoft.com/en-us/windows/apps/design/shell/tiles-and-notifications/custom-audio-on-toasts
+
+## else
+
+When I almost make it work, I found another package [windows_toast]
+which has the same dependency and more features.
+Luckily our 'styles' are quite different, and I'm on vacation,
+so I decide to finish it any way.
+
+If you need more features now, please use [windows_toast] instead,
+maybe give this one a try later.
+
+[winsdk]: https://pypi.org/project/winsdk
+[windows_toast]: https://github.com/DatGuy1/Windows-Toasts
diff --git a/doc/pic/example_for_control_freak.gif b/doc/pic/example_for_control_freak.gif
new file mode 100644
index 0000000..0a4de46
Binary files /dev/null and b/doc/pic/example_for_control_freak.gif differ
diff --git a/doc/pic/minimal_example.gif b/doc/pic/minimal_example.gif
new file mode 100644
index 0000000..2dedefc
Binary files /dev/null and b/doc/pic/minimal_example.gif differ
diff --git a/doc/pic/simple_example.gif b/doc/pic/simple_example.gif
new file mode 100644
index 0000000..19453b7
Binary files /dev/null and b/doc/pic/simple_example.gif differ
diff --git a/example/complex.py b/example/complex.py
new file mode 100644
index 0000000..6327039
--- /dev/null
+++ b/example/complex.py
@@ -0,0 +1,83 @@
+# -*- coding: utf-8 -*-
+"""
+example for control freak
+
+@Author: modabao
+@Time: 2022/5/3 10:33
+"""
+
+from os.path import abspath
+
+from winsdk_toast import Notifier, Toast
+
+path_pic = abspath('./resource/python.ico')
+
+notifier = Notifier('程序名 applicationId')
+
+
+# %% example for control freak
+toast = Toast()
+element_toast = toast.set_toast(
+ launch='blah', duration='long', displayTimeStamp='2022-04-01T12:00:00Z', scenario='default',
+ useButtonStyle='false', activationType='background'
+)
+element_visual = toast.set_visual(
+ version='1', lang='zh-CN', baseUri='ms-appx:///', branding='none', addImageQuery='false'
+)
+element_binding = toast.set_binding(
+ template='ToastGeneric', fallback='2ndtemplate', lang='zh-CN', addImageQuery='false',
+ baseUri='ms-appx:///', branding='none'
+)
+element_text = toast.add_text(
+ text='第一行 1st line for control freak', id_='1', lang='zh-CN', placement=None,
+ hint_maxLines='1', hint_style='title', hint_align='center', hint_wrap='false',
+ element_parent=element_binding
+)
+element_group = toast.add_group()
+element_subgroup_left = toast.add_subgroup(element_parent=element_group)
+element_text = toast.add_text(
+ text='第二行 2nd line for control freak', id_='2', lang='zh-CN', placement=None,
+ hint_maxLines='1', hint_style='captionSubtle ', hint_align='left', hint_wrap='false',
+ element_parent=element_subgroup_left
+)
+element_subgroup_right = toast.add_subgroup(element_parent=element_group)
+element_text = toast.add_text(
+ text='第三行 3rd line for control freak', id_='3', lang='zh-CN', placement='attribution',
+ hint_maxLines='1', hint_style='captionSubtle', hint_align='left', hint_wrap='false',
+ element_parent=element_subgroup_right
+)
+toast.add_image(
+ path_pic, id_=None, alt='', addImageQuery='false',
+ placement='appLogoOverride', hint_crop='circle'
+)
+toast.set_actions()
+toast.add_action(
+ '关闭 Close', arguments='dismiss', activationType='system', placement=None,
+ imageUri=None, hint_inputId=None, hint_buttonStyle=None, hint_toolTip='tip close'
+)
+notifier.show(toast)
+
+# %% which is equivalent to
+xml = f"""
+
+
+
+ 第一行 1st line for control freak
+
+
+ 第二行 2nd line for control freak
+
+
+ 第三行 3rd line for control freak
+
+
+
+
+
+
+
+
+
+"""
+toast = Toast(xml)
+notifier.show(toast)
diff --git a/example/minimal.py b/example/minimal.py
new file mode 100644
index 0000000..da593ce
--- /dev/null
+++ b/example/minimal.py
@@ -0,0 +1,30 @@
+# -*- coding: utf-8 -*-
+"""
+minimal example
+
+@Author: modabao
+@Time: 2022/5/3 10:33
+"""
+
+from winsdk_toast import Notifier, Toast
+
+
+notifier = Notifier('程序名 applicationId')
+
+# %% minimal example
+toast = Toast()
+toast.add_text('第一行 1st line')
+notifier.show(toast)
+
+# %% which is equivalent to
+xml = """
+
+
+
+ 第一行 1st line
+
+
+
+"""
+toast = Toast(xml)
+notifier.show(toast)
diff --git a/example/resource/python.ico b/example/resource/python.ico
new file mode 100644
index 0000000..3cf51c6
Binary files /dev/null and b/example/resource/python.ico differ
diff --git a/example/simple.py b/example/simple.py
new file mode 100644
index 0000000..a997feb
--- /dev/null
+++ b/example/simple.py
@@ -0,0 +1,44 @@
+# -*- coding: utf-8 -*-
+"""
+simple example
+
+@Author: modabao
+@Time: 2022/5/3 10:33
+"""
+
+from os.path import abspath
+
+from winsdk_toast import Notifier, Toast
+
+path_pic = abspath('./resource/python.ico')
+
+notifier = Notifier('程序名 applicationId')
+
+# %% simple example
+toast = Toast()
+toast.add_text('第一行 1st line', hint_align='center', hint_style='caption')
+toast.add_text('第二行 2nd line')
+toast.add_text('第三行 3rd line', placement='attribution')
+toast.add_image(path_pic, placement='appLogoOverride')
+toast.add_action('关闭 Close')
+toast.set_audio(silent='true')
+notifier.show(toast)
+
+# %% which is equivalent to
+xml = f"""
+
+
+
+ 第一行 1st line
+ 第二行 2nd line
+ 第三行 3rd line
+
+
+
+
+
+
+
+"""
+toast = Toast(xml)
+notifier.show(toast)
diff --git a/pyproject.toml b/pyproject.toml
new file mode 100644
index 0000000..fed528d
--- /dev/null
+++ b/pyproject.toml
@@ -0,0 +1,3 @@
+[build-system]
+requires = ["setuptools"]
+build-backend = "setuptools.build_meta"
diff --git a/setup.cfg b/setup.cfg
new file mode 100644
index 0000000..43badb0
--- /dev/null
+++ b/setup.cfg
@@ -0,0 +1,23 @@
+[metadata]
+name = winsdk_toast
+version = attr: winsdk_toast.__version__
+description = A simple package for displaying Windows Toast Notification based on winsdk
+author = modabao
+author_email = mo_dabao@qq.com
+long_description = file: README.md
+long_description_content_type = text/markdown
+url = https://github.com/Mo-Dabao/winsdk_toast
+license = MIT
+
+[options]
+package_dir =
+ = src
+packages = find:
+install_requires = winsdk
+include_package_data = True
+
+[options.packages.find]
+where = src
+
+[options.package_data]
+* = LICENSE
diff --git a/src/winsdk_toast/__init__.py b/src/winsdk_toast/__init__.py
new file mode 100644
index 0000000..13e59b8
--- /dev/null
+++ b/src/winsdk_toast/__init__.py
@@ -0,0 +1,12 @@
+# -*- coding: utf-8 -*-
+"""
+
+@Author: modabao
+@Time: 2022/5/1 11:05
+"""
+
+from winsdk_toast.toast import Toast
+from winsdk_toast.notifier import Notifier
+
+__all__ = ['Toast', 'Notifier']
+__version__ = '0.0.1'
diff --git a/src/winsdk_toast/notifier.py b/src/winsdk_toast/notifier.py
new file mode 100644
index 0000000..72e8d8a
--- /dev/null
+++ b/src/winsdk_toast/notifier.py
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+"""
+
+@Author: modabao
+@Time: 2022/5/1 11:52
+"""
+
+from winsdk.windows.ui.notifications import ToastNotificationManager
+
+from winsdk_toast.toast import Toast
+
+
+class Notifier(object):
+ def __init__(self, applicationId):
+ """
+ https://docs.microsoft.com/en-us/uwp/api/windows.ui.notifications.toastnotificationmanager.createtoastnotifier
+ Args:
+ applicationId:
+ """
+ self.toast_notifier = ToastNotificationManager.create_toast_notifier(applicationId)
+
+ def show(self, toast: Toast):
+ self.toast_notifier.show(toast.suit_up())
diff --git a/src/winsdk_toast/toast.py b/src/winsdk_toast/toast.py
new file mode 100644
index 0000000..85770ff
--- /dev/null
+++ b/src/winsdk_toast/toast.py
@@ -0,0 +1,364 @@
+# -*- coding: utf-8 -*-
+"""
+Handle or create XmlDocument toast.
+
+@Author: modabao
+@Time: 2022/5/1 11:09
+"""
+
+from winsdk.windows.data.xml.dom import XmlDocument
+from winsdk.windows.ui.notifications import ToastNotification
+
+
+def set_attributes(element, attributes: dict):
+ for name, value in attributes.items():
+ if value is None:
+ continue
+ element.set_attribute(name, value)
+
+
+class Toast(object):
+ def __init__(self, xml: [str | None] = None):
+ self.xml_document = XmlDocument()
+ if xml is not None:
+ self.xml_document.load_xml(xml)
+
+ def suit_up(self):
+ """Suit up to face notifier
+
+ Returns:
+ toast_notification
+ """
+ return ToastNotification(self.xml_document)
+
+ def set_toast(
+ self, launch=None, duration=None, displayTimeStamp=None, scenario=None, useButtonStyle=None,
+ activationType='background'
+ ):
+ """
+ https://docs.microsoft.com/en-us/uwp/schemas/tiles/toastschema/element-toast
+ Args:
+ launch:
+ duration: 'long' | 'short'
+ displayTimeStamp:
+ scenario: 'default' | 'reminder' | 'alarm' | 'incomingCall' | 'urgent'
+ useButtonStyle: 'false' | 'true'
+ activationType: 'background' | 'protocol'
+
+ Returns:
+ element_toast
+ """
+ xml_document = self.xml_document
+ element_toast = xml_document.create_element('toast')
+ xml_document.append_child(element_toast)
+ attributes = {
+ 'launch': launch,
+ 'duration': duration,
+ 'displayTimeStamp': displayTimeStamp,
+ 'scenario': scenario,
+ 'useButtonStyle': useButtonStyle,
+ 'activationType': activationType
+ }
+ set_attributes(element_toast, attributes)
+ return element_toast
+
+ def set_visual(self, version=None, lang=None, baseUri=None, branding=None, addImageQuery=None):
+ """
+ https://docs.microsoft.com/en-us/uwp/schemas/tiles/toastschema/element-visual
+ Args:
+ version: '1'
+ lang:
+ baseUri: 'ms-appx:///'
+ branding: Not used. 'none' | 'logo' | 'name'
+ addImageQuery: 'false' | 'true'
+
+ Returns:
+ None
+ """
+ xml_document = self.xml_document
+ element_toast = xml_document.select_single_node('/toast') or self.set_toast()
+ element_visual = xml_document.create_element('visual')
+ element_toast.append_child(element_visual)
+ attributes = {
+ 'version': version,
+ 'lang': lang,
+ 'baseUri': baseUri,
+ 'branding': branding,
+ 'addImageQuery': addImageQuery
+ }
+ set_attributes(element_visual, attributes)
+ return element_visual
+
+ def set_binding(
+ self, template='ToastGeneric', fallback=None, lang=None, addImageQuery=None, baseUri=None, branding=None
+ ):
+ """
+ https://docs.microsoft.com/en-us/uwp/schemas/tiles/toastschema/element-binding
+ Args:
+ template: 'ToastGeneric'
+ fallback:
+ lang:
+ addImageQuery: 'false' | 'true'
+ baseUri: 'ms-appx:///'
+ branding: Not used. 'none' | 'logo' | 'name'
+
+ Returns:
+ element_binding
+ """
+ xml_document = self.xml_document
+ element_visual = xml_document.select_single_node('//visual') or self.set_visual()
+ element_binding = xml_document.create_element('binding')
+ element_visual.append_child(element_binding)
+ attributes = {
+ 'template': template,
+ 'fallback': fallback,
+ 'lang': lang,
+ 'addImageQuery': addImageQuery,
+ 'baseUri': baseUri,
+ 'branding': branding
+ }
+ set_attributes(element_binding, attributes)
+ return element_binding
+
+ def add_text(
+ self, text, id_=None, lang=None, placement=None, hint_maxLines=None, hint_style=None, hint_align=None,
+ hint_wrap=None, element_parent=None
+ ):
+ """
+ https://docs.microsoft.com/en-us/uwp/schemas/tiles/toastschema/element-text
+ https://docs.microsoft.com/en-us/windows/apps/design/shell/tiles-and-notifications/adaptive-interactive-toasts
+ https://docs.microsoft.com/en-us/windows/apps/design/shell/tiles-and-notifications/adaptive-tiles-schema
+ Args:
+ text:
+ id_:
+ lang:
+ placement: 'attribution' ...
+ hint_maxLines: '1'-'4'
+ hint_style: 'base' | 'captionSubtle' ...
+ hint_align: 'left' | 'center' | 'right'
+ hint_wrap: 'false' | 'true'
+ element_parent:
+
+ Returns:
+ element_text
+ """
+ xml_document = self.xml_document
+ element_parent = element_parent or xml_document.select_single_node('//binding') or self.set_binding()
+ element_text = xml_document.create_element('text')
+ element_parent.append_child(element_text)
+ element_text.inner_text = text
+ attributes = {
+ 'id': id_,
+ 'lang': lang,
+ 'placement': placement,
+ 'hint-maxLines': hint_maxLines,
+ 'hint-style': hint_style,
+ 'hint-align': hint_align,
+ 'hint-wrap': hint_wrap
+ }
+ set_attributes(element_text, attributes)
+ return element_text
+
+ def add_image(
+ self, src, id_=None, alt=None, addImageQuery=None, placement=None, hint_crop=None, element_parent=None
+ ):
+ """
+ https://docs.microsoft.com/en-us/uwp/schemas/tiles/toastschema/element-image
+ https://docs.microsoft.com/en-us/windows/apps/design/shell/tiles-and-notifications/adaptive-interactive-toasts
+ Args:
+ src: (<3MB)
+ id_:
+ alt:
+ addImageQuery: 'false' | 'true'
+ placement: 'appLogoOverride' | 'hero'
+ hint_crop: 'circle' | ''
+ element_parent:
+
+ Returns:
+ None
+ """
+ xml_document = self.xml_document
+ element_parent = element_parent or xml_document.select_single_node('//binding') or self.set_binding()
+ element_image = xml_document.create_element('image')
+ element_parent.append_child(element_image)
+ attributes = {
+ 'src': src,
+ 'id': id_,
+ 'alt': alt,
+ 'addImageQuery': addImageQuery,
+ 'placement': placement,
+ 'hint-crop': hint_crop
+ }
+ set_attributes(element_image, attributes)
+ return element_image
+
+ def add_progress(self, title=None, status='Progress', value='0.5', valueStringOverride=None, element_parent=None):
+ """
+ https://docs.microsoft.com/en-us/windows/apps/design/shell/tiles-and-notifications/toast-progress-bar
+ Args:
+ title:
+ status:
+ value: '0.0' - '1.0'
+ valueStringOverride:
+ element_parent:
+
+ Returns:
+
+ """
+ xml_document = self.xml_document
+ element_parent = element_parent or xml_document.select_single_node('//binding') or self.set_binding()
+ element_progress = xml_document.create_element('progress')
+ element_parent.append_child(element_progress)
+ attributes = {
+ 'title': title,
+ 'status': status,
+ 'value': value,
+ 'valueStringOverride': valueStringOverride
+ }
+ set_attributes(element_parent, attributes)
+ return element_progress
+
+ def add_group(self):
+ """
+ https://docs.microsoft.com/en-us/windows/apps/design/shell/tiles-and-notifications/adaptive-interactive-toasts
+ Returns:
+ element_group
+ """
+ xml_document = self.xml_document
+ element_binding = xml_document.select_single_node('//binding') or self.set_binding()
+ element_group = xml_document.create_element('group')
+ element_binding.append_child(element_group)
+ return element_group
+
+ def add_subgroup(self, element_parent=None):
+ """
+ https://docs.microsoft.com/en-us/windows/apps/design/shell/tiles-and-notifications/adaptive-interactive-toasts
+ Returns:
+ element_group
+ """
+ xml_document = self.xml_document
+ element_parent = element_parent or xml_document.select_single_node('//group') or self.add_group()
+ element_subgroup = xml_document.create_element('subgroup')
+ element_parent.append_child(element_subgroup)
+ return element_subgroup
+
+ def set_actions(self):
+ """
+ https://docs.microsoft.com/en-us/uwp/schemas/tiles/toastschema/element-actions
+ Returns:
+ None
+ """
+ xml_document = self.xml_document
+ element_toast = xml_document.select_single_node('/toast') or self.set_toast()
+ element_actions = xml_document.create_element('actions')
+ element_toast.append_child(element_actions)
+ return element_actions
+
+ def add_action(
+ self, content, arguments='dismiss', activationType='system', placement=None, imageUri=None,
+ hint_inputId=None, hint_buttonStyle=None, hint_toolTip=None
+ ):
+ """
+ https://docs.microsoft.com/en-us/uwp/schemas/tiles/toastschema/element-action
+ https://docs.microsoft.com/en-us/windows/apps/design/shell/tiles-and-notifications/adaptive-interactive-toasts
+ type?
+ Args:
+ content:
+ arguments: ('dismiss' | 'snooze') for activationType='system'
+ activationType: 'system' | 'foreground' | 'background' | 'protocol'
+ placement: 'contextMenu' | ''
+ imageUri:
+ hint_inputId:
+ hint_buttonStyle: 'success' | 'citical'
+ hint_toolTip:
+
+ Returns:
+
+ """
+ xml_document = self.xml_document
+ element_actions = xml_document.select_single_node('//actions') or self.set_actions()
+ element_action = xml_document.create_element('action')
+ element_actions.append_child(element_action)
+ attributes = {
+ 'content': content,
+ 'arguments': arguments,
+ 'activationType': activationType,
+ 'placement': placement,
+ 'imageUri': imageUri,
+ 'hint-inputId': hint_inputId,
+ 'hint-buttonStyle': hint_buttonStyle,
+ 'hint-toolTip': hint_toolTip
+ }
+ set_attributes(element_action, attributes)
+ return element_action
+
+ def add_input(self, type_, id_=None, placeHolderContent=None, element_parent=None):
+ """
+ https://docs.microsoft.com/en-us/uwp/schemas/tiles/toastschema/element-input
+ https://docs.microsoft.com/en-us/windows/apps/design/shell/tiles-and-notifications/adaptive-interactive-toasts
+ Args:
+ id_:
+ type_: 'text' | 'selection'
+ placeHolderContent:
+
+ Returns:
+
+ """
+ xml_document = self.xml_document
+ element_parent = element_parent or xml_document.select_single_node('//actions') or self.set_actions()
+ element_input = xml_document.create_element('input')
+ element_parent.append_child(element_input)
+ attributes = {
+ 'type': type_,
+ 'id': id_,
+ 'placeHolderContent': placeHolderContent
+ }
+ set_attributes(element_input, attributes)
+ return element_input
+
+ def add_selection(self, id_=None, content=None, element_parent=None):
+ """
+ https://docs.microsoft.com/en-us/windows/apps/design/shell/tiles-and-notifications/adaptive-interactive-toasts
+ Args:
+ id_:
+ content:
+ element_parent:
+
+ Returns:
+ element_selection
+ """
+ pass
+ xml_document = self.xml_document
+ element_parent = element_parent or xml_document.select_single_node('//input') or self.add_input()
+ element_selection = xml_document.create_element('selection')
+ element_parent.append_child(element_selection)
+ attributes = {
+ 'id': id_,
+ 'content': content
+ }
+ set_attributes(element_selection, attributes)
+ return element_selection
+
+ def set_audio(self, src=None, loop='false', silent='false'):
+ """
+ https://docs.microsoft.com/en-us/uwp/schemas/tiles/toastschema/element-audio
+ https://docs.microsoft.com/en-us/windows/apps/design/shell/tiles-and-notifications/custom-audio-on-toasts
+ Args:
+ src:
+ loop:
+ silent:
+
+ Returns:
+
+ """
+ xml_document = self.xml_document
+ element_toast = xml_document.select_single_node('/toast') or self.set_toast()
+ element_audio = xml_document.create_element('audio')
+ element_toast.append_child(element_audio)
+ attributes = {
+ 'src': src,
+ 'loop': loop,
+ 'silent': silent
+ }
+ set_attributes(element_audio, attributes)
+ return element_audio