Skip to content
This repository was archived by the owner on Oct 7, 2024. It is now read-only.
Open
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions samples/password_vault.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
from winsdk.windows.security.credentials import PasswordCredential, PasswordVault


def save_credential_to_resource(resource: str, username: str, password: str) -> None:
vault = PasswordVault()
cred = PasswordCredential(resource, username, password)
vault.add(cred)


if __name__ == "__main__":
VAULT_RESOURCE = "WinSDK Sample"
# Uncomment this line to save a credential in resource
# save_credential_to_resource(VAULT_RESOURCE, "dummy_username", "dummy_password")

vault = PasswordVault()

try:
creds = vault.find_all_by_resource(VAULT_RESOURCE)
if creds is not None:
for cred in creds:
print(
f"Username: {cred.user_name}, Password: {vault.retrieve(VAULT_RESOURCE, cred.user_name).password}"
)
except OSError as ex:
print(f"Could not find any resource for {VAULT_RESOURCE}")
24 changes: 24 additions & 0 deletions samples/pdf.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import asyncio
from pathlib import Path
from typing import Optional

from winsdk.windows.data.pdf import PdfDocument
from winsdk.windows.storage import StorageFile


async def load_pdf(file: Path, password: Optional[str] = None) -> PdfDocument:
pdf_file = await StorageFile.get_file_from_path_async(str(file))
if password is not None:
document = await PdfDocument.load_from_file_async(pdf_file, password)
else:
document = await PdfDocument.load_from_file_async(pdf_file)

return document


if __name__ == "__main__":
file = Path(input("Provide the pdf file path: ").strip())
if not file.exists():
raise FileNotFoundError(f"{str(file)} does not exist!")
document = asyncio.run(load_pdf(file))
print(f"{file} contains {document.page_count} pages.")
44 changes: 44 additions & 0 deletions samples/pickers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import asyncio
import threading
from tkinter import Button, Frame, Tk

from winsdk._winrt import initialize_with_window
from winsdk.windows.storage.pickers import FolderPicker


class Pickers:
def __init__(self) -> None:
self.last_folder_picked = None
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is one way to save the value which is obtained in a callback method


async def store_folder(self, hwnd: int):
folder_picker = FolderPicker()
initialize_with_window(folder_picker, hwnd)
folder_picker.file_type_filter.append("*")
folder = await folder_picker.pick_single_folder_async()
print(f"User picked the following folder: {folder.path}")
self.last_folder_picked = folder


class App(Tk):
def __init__(self, pickers: Pickers, async_loop: asyncio.ProactorEventLoop) -> None:
super(App, self).__init__()
self.minsize(100, 40)
frame = Frame(self)
frame.pack()
hwnd = self.winfo_id()
folder_picker_button = Button(
frame,
text="Folder Picker",
command=lambda: asyncio.run_coroutine_threadsafe(
loop=async_loop, coro=pickers.store_folder(hwnd)
),
)
folder_picker_button.pack()

if __name__ == "__main__":
async_loop = asyncio.get_event_loop()
threading.Thread(daemon=True, target=async_loop.run_forever).start()
pickers = Pickers()
app = App(pickers=pickers, async_loop=async_loop)
app.mainloop()
print(f"Last folder picked: {pickers.last_folder_picked}")
17 changes: 17 additions & 0 deletions samples/rss.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import asyncio

from winsdk.windows.foundation import Uri
from winsdk.windows.web.syndication import SyndicationClient, SyndicationFeed


async def get_feed(uri: Uri) -> SyndicationFeed:
client = SyndicationClient()
feed = await client.retrieve_feed_async(uri)
return feed


if __name__ == "__main__":
uri = Uri("https://blogs.windows.com/feed")
result = asyncio.run(get_feed(uri))
for item in result.items:
print(item.title.text)
162 changes: 162 additions & 0 deletions samples/toast_notification.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
import asyncio

from winsdk.windows.data.xml.dom import XmlDocument
from winsdk.windows.foundation import IPropertyValue
from winsdk.windows.ui.notifications import (
ToastActivatedEventArgs,
ToastNotification,
ToastNotificationManager,
)


def get_text_only_toast_dom() -> XmlDocument:
toast_dom = XmlDocument()
toast_xml_string = """<toast>
<visual>
<binding template="ToastGeneric">
<text>Hello World</text>
<text>This is a simple toast message</text>
</binding>
</visual>
</toast>"""
toast_dom.load_xml(toast_xml_string)
return toast_dom


def get_text_with_image_toast_dom() -> XmlDocument:
toast_dom = XmlDocument()
toast_xml_string = f"""<toast>
<visual>
<binding template='ToastGeneric'>
<image placement="appLogoOverride" hint-crop="circle" src="https://i.pinimg.com/474x/50/70/10/5070101ae7cc267a1ba03d30abdd38e9.jpg"/>
<text>Expedition completed</text>
<text>An expedition has completed, don't forget to stop by the Adventures' Guild.</text>
<image src="https://images.wallpapersden.com/image/download/genshin-impact-2019_a2prbGyUmZqaraWkpJRmbmdlrWZlbWU.jpg" />
</binding>
</visual>
</toast>"""
toast_dom.load_xml(toast_xml_string)
return toast_dom


def get_alarm_toast_dom() -> XmlDocument:
toast_dom = XmlDocument()
toast_xml_string = """<toast launch="action=viewAlarm&amp;alarmId=3" scenario="alarm">
<visual>
<binding template="ToastGeneric">
<text>Time to wake up!</text>
<text>To prove you're awake, select which of the following fruits is yellow...</text>
</binding>
</visual>
<actions>
<input id="answer" type="selection" defaultInput="wrongDefault">
<selection id="wrong" content="Orange"/>
<selection id="wrongDefault" content="Blueberry"/>
<selection id="right" content="Banana"/>
<selection id="wrong" content="Avacado"/>
<selection id="wrong" content="Cherry"/>
</input>
<action
activationType="system"
arguments="snooze"
content=""/>
<action
activationType="background"
arguments="dismiss"
content="Dismiss"/>
</actions>
</toast>"""
toast_dom.load_xml(toast_xml_string)
return toast_dom


def get_action_toast_dom() -> XmlDocument:
toast_dom = XmlDocument()
toast_xml_string = f"""<toast>
<visual>
<binding template='ToastGeneric'>
<text>Another Message from Tim!</text>
<text>Hi there!</text>
</binding>
</visual>
<actions>
<input id="textBox1" type="text" placeHolderContent="Type a reply"/>
<input id="textBox2" type="text" placeHolderContent="Type a comment"/>
<action
content="Send"
arguments="action=reply&amp;convId=01"
activationType="background"
hint-inputId="textBox1"/>
<action
content="Button 1"
arguments="action=viewdetails&amp;contentId=02"
activationType="foreground"/>
<action
content="Comment"
arguments="action=comment&amp;convId=03"
activationType="background"
hint-inputId="textBox2"/>
</actions>
</toast>"""
toast_dom.load_xml(toast_xml_string)
return toast_dom


def main() -> None:
# For desktip apps it is mendatory to send an AppUserModelID to create_toast_notifier.
# We can use Get-StartApps powershell command to get list of all app with thier AppUserModelID
notifier = ToastNotificationManager.create_toast_notifier(
r"Microsoft.Windows.Photos_8wekyb3d8bbwe!App"
)

# We can use existing template from winsdk.windows.ui.notifications: https://docs.microsoft.com/en-us/uwp/api/windows.ui.notifications.toastnotification?view=winrt-22621
# We can use Notifications Visualizer to design your own toast template: https://docs.microsoft.com/en-us/windows/apps/design/shell/tiles-and-notifications/notifications-visualizer
# toast_dom = get_text_only_toast_dom()
toast_dom = get_text_with_image_toast_dom()

toast = ToastNotification(toast_dom)
notifier.show(toast)


async def async_main() -> None:
notifier = ToastNotificationManager.create_toast_notifier(
r"Microsoft.Windows.Photos_8wekyb3d8bbwe!App"
)
# toast_dom = get_alarm_toast_dom()
toast_dom = get_action_toast_dom()

toast = ToastNotification(toast_dom)

event_loop = asyncio.get_running_loop()
activated_future = event_loop.create_future()

def handle_activated(sender, event_args):
activated_future.set_result(event_args)

activated_token = toast.add_activated(
lambda s, e: event_loop.call_soon_threadsafe(handle_activated, s, e)
)

try:
notifier.show(toast)

async def print_received():
event_args = await activated_future
activated_event_args = ToastActivatedEventArgs._from(event_args)
if hasattr(activated_event_args.user_input, "items"):
for key, value in activated_event_args.user_input.items():
value = IPropertyValue._from(value).get_string()
print(f"{key}: {value}")
print(f"event argument: {activated_event_args.arguments}")

printer_task = asyncio.create_task(print_received())
await asyncio.wait(
[printer_task], timeout=10, return_when=asyncio.FIRST_COMPLETED
)
finally:
toast.remove_activated(activated_token)


if __name__ == "__main__":
main()
asyncio.run(async_main())
Loading