18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#!/usr/bin/python 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtimport dbus 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtimport sys, os 58d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtimport time 68d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtimport gobject 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtfrom dbus.mainloop.glib import DBusGMainLoop 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtWPAS_DBUS_SERVICE = "fi.w1.wpa_supplicant1" 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtWPAS_DBUS_INTERFACE = "fi.w1.wpa_supplicant1" 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtWPAS_DBUS_OPATH = "/fi/w1/wpa_supplicant1" 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtWPAS_DBUS_INTERFACES_INTERFACE = "fi.w1.wpa_supplicant1.Interface" 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtWPAS_DBUS_INTERFACES_OPATH = "/fi/w1/wpa_supplicant1/Interfaces" 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtWPAS_DBUS_BSS_INTERFACE = "fi.w1.wpa_supplicant1.BSS" 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtWPAS_DBUS_NETWORK_INTERFACE = "fi.w1.wpa_supplicant1.Network" 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtdef byte_array_to_string(s): 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt import urllib 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt r = "" 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for c in s: 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if c >= 32 and c < 127: 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt r += "%c" % c 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else: 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt r += urllib.quote(chr(c)) 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return r 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtdef list_interfaces(wpas_obj): 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ifaces = wpas_obj.Get(WPAS_DBUS_INTERFACE, 'Interfaces', 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dbus_interface=dbus.PROPERTIES_IFACE) 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for path in ifaces: 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if_obj = bus.get_object(WPAS_DBUS_SERVICE, path) 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ifname = if_obj.Get(WPAS_DBUS_INTERFACES_INTERFACE, 'Ifname', 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dbus_interface=dbus.PROPERTIES_IFACE) 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt print ifname 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtdef interfaceAdded(interface, properties): 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt print "InterfaceAdded(%s): Ifname=%s" % (interface, properties['Ifname']) 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtdef interfaceRemoved(interface): 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt print "InterfaceRemoved(%s)" % (interface) 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtdef propertiesChanged(properties): 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for i in properties: 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt print "PropertiesChanged: %s=%s" % (i, properties[i]) 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtdef showBss(bss): 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt net_obj = bus.get_object(WPAS_DBUS_SERVICE, bss) 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt net = dbus.Interface(net_obj, WPAS_DBUS_BSS_INTERFACE) 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt # Convert the byte-array for SSID and BSSID to printable strings 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt val = net_obj.Get(WPAS_DBUS_BSS_INTERFACE, 'BSSID', 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dbus_interface=dbus.PROPERTIES_IFACE) 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bssid = "" 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for item in val: 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bssid = bssid + ":%02x" % item 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bssid = bssid[1:] 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt val = net_obj.Get(WPAS_DBUS_BSS_INTERFACE, 'SSID', 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dbus_interface=dbus.PROPERTIES_IFACE) 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid = byte_array_to_string(val) 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 62c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt val = net_obj.Get(WPAS_DBUS_BSS_INTERFACE, 'WPA', 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dbus_interface=dbus.PROPERTIES_IFACE) 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa = "no" 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if val != None: 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa = "yes" 67c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt val = net_obj.Get(WPAS_DBUS_BSS_INTERFACE, 'RSN', 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dbus_interface=dbus.PROPERTIES_IFACE) 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa2 = "no" 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if val != None: 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa2 = "yes" 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq = net_obj.Get(WPAS_DBUS_BSS_INTERFACE, 'Frequency', 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dbus_interface=dbus.PROPERTIES_IFACE) 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt signal = net_obj.Get(WPAS_DBUS_BSS_INTERFACE, 'Signal', 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dbus_interface=dbus.PROPERTIES_IFACE) 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt val = net_obj.Get(WPAS_DBUS_BSS_INTERFACE, 'Rates', 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dbus_interface=dbus.PROPERTIES_IFACE) 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if len(val) > 0: 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt maxrate = val[0] / 1000000 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else: 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt maxrate = 0 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt print " %s :: ssid='%s' wpa=%s wpa2=%s signal=%d rate=%d freq=%d" % (bssid, ssid, wpa, wpa2, signal, maxrate, freq) 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtdef scanDone(success): 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gobject.MainLoop().quit() 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt print "Scan done: success=%s" % success 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtdef scanDone2(success, path=None): 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt print "Scan done: success=%s [path=%s]" % (success, path) 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtdef bssAdded(bss, properties): 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt print "BSS added: %s" % (bss) 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt showBss(bss) 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtdef bssRemoved(bss): 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt print "BSS removed: %s" % (bss) 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtdef blobAdded(blob): 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt print "BlobAdded(%s)" % (blob) 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtdef blobRemoved(blob): 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt print "BlobRemoved(%s)" % (blob) 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtdef networkAdded(network, properties): 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt print "NetworkAdded(%s)" % (network) 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtdef networkRemoved(network): 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt print "NetworkRemoved(%s)" % (network) 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtdef networkSelected(network): 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt print "NetworkSelected(%s)" % (network) 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtdef propertiesChangedInterface(properties): 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for i in properties: 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt print "PropertiesChanged(interface): %s=%s" % (i, properties[i]) 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtdef propertiesChangedBss(properties): 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for i in properties: 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt print "PropertiesChanged(BSS): %s=%s" % (i, properties[i]) 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtdef propertiesChangedNetwork(properties): 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for i in properties: 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt print "PropertiesChanged(Network): %s=%s" % (i, properties[i]) 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtdef main(): 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt global bus 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bus = dbus.SystemBus() 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_obj = bus.get_object(WPAS_DBUS_SERVICE, WPAS_DBUS_OPATH) 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if len(sys.argv) != 2: 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt list_interfaces(wpas_obj) 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os._exit(1) 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas = dbus.Interface(wpas_obj, WPAS_DBUS_INTERFACE) 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bus.add_signal_receiver(interfaceAdded, 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dbus_interface=WPAS_DBUS_INTERFACE, 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt signal_name="InterfaceAdded") 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bus.add_signal_receiver(interfaceRemoved, 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dbus_interface=WPAS_DBUS_INTERFACE, 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt signal_name="InterfaceRemoved") 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bus.add_signal_receiver(propertiesChanged, 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dbus_interface=WPAS_DBUS_INTERFACE, 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt signal_name="PropertiesChanged") 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ifname = sys.argv[1] 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt path = wpas.GetInterface(ifname) 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if_obj = bus.get_object(WPAS_DBUS_SERVICE, path) 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface = dbus.Interface(if_obj, WPAS_DBUS_INTERFACES_INTERFACE) 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface.connect_to_signal("ScanDone", scanDone2, 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt path_keyword='path') 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bus.add_signal_receiver(scanDone, 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dbus_interface=WPAS_DBUS_INTERFACES_INTERFACE, 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt signal_name="ScanDone", 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt path=path) 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bus.add_signal_receiver(bssAdded, 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dbus_interface=WPAS_DBUS_INTERFACES_INTERFACE, 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt signal_name="BSSAdded", 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt path=path) 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bus.add_signal_receiver(bssRemoved, 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dbus_interface=WPAS_DBUS_INTERFACES_INTERFACE, 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt signal_name="BSSRemoved", 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt path=path) 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bus.add_signal_receiver(blobAdded, 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dbus_interface=WPAS_DBUS_INTERFACES_INTERFACE, 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt signal_name="BlobAdded", 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt path=path) 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bus.add_signal_receiver(blobRemoved, 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dbus_interface=WPAS_DBUS_INTERFACES_INTERFACE, 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt signal_name="BlobRemoved", 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt path=path) 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bus.add_signal_receiver(networkAdded, 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dbus_interface=WPAS_DBUS_INTERFACES_INTERFACE, 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt signal_name="NetworkAdded", 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt path=path) 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bus.add_signal_receiver(networkRemoved, 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dbus_interface=WPAS_DBUS_INTERFACES_INTERFACE, 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt signal_name="NetworkRemoved", 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt path=path) 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bus.add_signal_receiver(networkSelected, 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dbus_interface=WPAS_DBUS_INTERFACES_INTERFACE, 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt signal_name="NetworkSelected", 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt path=path) 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bus.add_signal_receiver(propertiesChangedInterface, 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dbus_interface=WPAS_DBUS_INTERFACES_INTERFACE, 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt signal_name="PropertiesChanged", 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt path=path) 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bus.add_signal_receiver(propertiesChangedBss, 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dbus_interface=WPAS_DBUS_BSS_INTERFACE, 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt signal_name="PropertiesChanged") 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bus.add_signal_receiver(propertiesChangedNetwork, 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dbus_interface=WPAS_DBUS_NETWORK_INTERFACE, 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt signal_name="PropertiesChanged") 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gobject.MainLoop().run() 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtif __name__ == "__main__": 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt main() 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 204