diff --git a/samples/password_vault.py b/samples/password_vault.py new file mode 100644 index 00000000..718d4fa1 --- /dev/null +++ b/samples/password_vault.py @@ -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}") diff --git a/samples/pdf.py b/samples/pdf.py new file mode 100644 index 00000000..71b82499 --- /dev/null +++ b/samples/pdf.py @@ -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.") diff --git a/samples/pickers.py b/samples/pickers.py new file mode 100644 index 00000000..f179099f --- /dev/null +++ b/samples/pickers.py @@ -0,0 +1,42 @@ +import asyncio +import threading +from tkinter import Button, 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 + + 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) + hwnd = self.winfo_id() + folder_picker_button = Button( + self, + 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}") diff --git a/samples/rss.py b/samples/rss.py new file mode 100644 index 00000000..d617b4c1 --- /dev/null +++ b/samples/rss.py @@ -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) diff --git a/samples/toast_notification.md b/samples/toast_notification.md new file mode 100644 index 00000000..b1455710 --- /dev/null +++ b/samples/toast_notification.md @@ -0,0 +1,4 @@ +There are already packages available for Windows toast which uses python-winsdk: +- [Windows-Toasts](https://github.com/DatGuy1/Windows-Toasts) +- [winsdk_toast](https://github.com/Mo-Dabao/winsdk_toast) +- [maestral-cocoa's desktop notifier](https://github.com/samschott/maestral-cocoa/blob/master/macOS/Xcode/Maestral/Maestral/app_packages/desktop_notifier/winrt.py) \ No newline at end of file diff --git a/samples/wifi_connectivity.py b/samples/wifi_connectivity.py new file mode 100644 index 00000000..4e34fc26 --- /dev/null +++ b/samples/wifi_connectivity.py @@ -0,0 +1,129 @@ +import asyncio +from typing import Iterable, Optional + +from winsdk.windows.devices.wifi import ( + WiFiAdapter, + WiFiAvailableNetwork, + WiFiConnectionStatus, + WiFiPhyKind, + WiFiReconnectionKind, + WiFiNetworkKind +) +from winsdk.windows.networking.connectivity import ( + NetworkAuthenticationType, + NetworkEncryptionType, +) +from winsdk.windows.security.credentials import PasswordCredential + + +def log_network_details(network: WiFiAvailableNetwork) -> None: + print(f"SSID: {network.ssid}") + print(f"MAC address: {network.bssid}") + print(f"Frequency: {network.channel_center_frequency_in_kilohertz} kHz") + print(f"RSSI: {network.network_rssi_in_decibel_milliwatts} dBm (lower is better)") + # TODO: Need to update below three print statement, once issue #1 in pywinrt is closed + print( + f"Authentication: {NetworkAuthenticationType(network.security_settings.network_authentication_type).name}" + ) + print( + f"Encryption: {NetworkEncryptionType(network.security_settings.network_encryption_type).name}" + ) + print(f"PHY: {WiFiPhyKind(network.phy_kind).name}") + print(f"WiFi Kind: {WiFiNetworkKind(network.network_kind).name}") + print(f"Signal: {network.signal_bars} bars (higher is better)") + print(f"Uptime: {network.uptime.duration}") + + +async def get_wifi_networks() -> Iterable[WiFiAvailableNetwork]: + wifi_networks = [] + wifi_adapters = await WiFiAdapter.find_all_adapters_async() + for wifi_adapter in wifi_adapters: + await wifi_adapter.scan_async() + for network in wifi_adapter.network_report.available_networks: + wifi_networks.append(network) + return wifi_networks + + +async def get_connected_wifi_network() -> Optional[WiFiAvailableNetwork]: + wifi_adapters = await WiFiAdapter.find_all_adapters_async() + connected_ssid = None + + for wifi_adapter in wifi_adapters: + connected_profile = ( + await wifi_adapter.network_adapter.get_connected_profile_async() + ) + if ( + connected_profile is not None + and connected_profile.is_wlan_connection_profile + and connected_profile.wlan_connection_profile_details is not None + ): + connected_ssid = ( + connected_profile.wlan_connection_profile_details.get_connected_ssid() + ) + + await wifi_adapter.scan_async() + for network in wifi_adapter.network_report.available_networks: + if network.ssid == connected_ssid: + return network + return None + + +async def connect_to_network( + ssid: str, + password: str = "", + reconnection_type: WiFiReconnectionKind = WiFiReconnectionKind.MANUAL, +) -> bool: + wifi_adapters = await WiFiAdapter.find_all_adapters_async() + + for wifi_adapter in wifi_adapters: + await wifi_adapter.scan_async() + for network in wifi_adapter.network_report.available_networks: + if network.ssid == ssid: + if ( + network.security_settings.network_authentication_type + == NetworkAuthenticationType.OPEN80211 + and network.security_settings.network_encryption_type + == NetworkEncryptionType.NONE + ): + result = await wifi_adapter.connect_async( + network, reconnection_type + ) + else: + credential = PasswordCredential() + if password: + credential.password = password + result = await wifi_adapter.connect_async( + network, + reconnection_type, + credential, + ) + if result.connection_status == WiFiConnectionStatus.SUCCESS: + print(f"Successfully connected to {network.ssid}.") + return True + else: + print( + # TODO: Need to update once issue #1 in pywinrt is closed + f"Could not connect to {network.ssid}. Error: {WiFiConnectionStatus(result.connection_status).name}." + ) + return False + print(f"Could not find network with SSID: {ssid}!") + return False + + +if __name__ == "__main__": + # Scan example + wifi_networks = asyncio.run(get_wifi_networks()) + for network in wifi_networks: + print("=" * 30) + log_network_details(network) + + # Connect example + # Replace with correct network ssid and password + is_connected = asyncio.run(connect_to_network("network_ssid", "network_password")) + + # Scan connected example + connected_network = asyncio.run(get_connected_wifi_network()) + if connected_network is not None: + print("=" * 30) + print("Connected WiFi Network:") + log_network_details(connected_network) diff --git a/samples/xml.py b/samples/xml.py new file mode 100644 index 00000000..45737c7a --- /dev/null +++ b/samples/xml.py @@ -0,0 +1,10 @@ +from winsdk.windows.data.xml.dom import XmlDocument + +if __name__ == "__main__": + xml = """Hello world""" + + doc = XmlDocument() + doc.load_xml(xml) + root = doc.document_element + assert root.node_name == "html" + print(root.inner_text)