Skip to content

Commit

Permalink
feat(src): Allow listing devices of concrete types
Browse files Browse the repository at this point in the history
Currently, the "list" command returns all discovered devices. This
includes also devices without host services like printers. That is a
problem for some API clients (i.e. gvfs). Let's add an optional
argument to specify concrete type.

Fixes: #178
  • Loading branch information
ondrejholy committed Dec 12, 2023
1 parent 55fe3e6 commit d77e0bb
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 9 deletions.
10 changes: 6 additions & 4 deletions man/wsdd.8
Original file line number Diff line number Diff line change
Expand Up @@ -162,10 +162,12 @@ only. The following commands can be issued:
Clears the list of all discovered devices. Use the \fBprobe\fR command to
search for devices again. This command does not return any data and is only
available in discover mode.
.SS \fBlist\fR - List discovered devices
Returns a tab-separated list of discovered devices with the following information.
The possibly empty list of detected hosts is always terminated with a single
dot ('.') in an otherwise empty line. This command is only available in discover mode.
.SS \fBlist \fI[TYPE]\fR - List discovered devices
Returns a tab-separated list of discovered devices of the provided TYPE (e.g.
"pub:Computer") with the following information. If no type is provided, all
discovered devices are listed. The possibly empty list of detected hosts is
always terminated with a single dot ('.') in an otherwise empty line. This
command is only available in discover mode.
.TP
UUID
UUID of the discovered device. Note that a multi-homed device should appear
Expand Down
15 changes: 10 additions & 5 deletions src/wsdd.py
Original file line number Diff line number Diff line change
Expand Up @@ -617,12 +617,14 @@ class WSDDiscoveredDevice:
props: Dict[str, str]
display_name: str
last_seen: float
types: Set[str]

def __init__(self, xml_str: str, xaddr: str, interface: NetworkInterface) -> None:
self.last_seen = 0.0
self.addresses = {}
self.props = {}
self.display_name = ''
self.types = set()

self.update(xml_str, xaddr, interface)

Expand Down Expand Up @@ -679,9 +681,8 @@ def extract_wsdp_props(self, root: ElementTree.Element, dialect: str) -> None:
self.props[tag_name] = str(node.text)

def extract_host_props(self, root: ElementTree.Element) -> None:
types = root.findtext('wsdp:Types', '', namespaces)
self.props['types'] = types.split(' ')[0]
if types != PUB_COMPUTER:
self.types = set(root.findtext('wsdp:Types', '', namespaces).split(' '))
if PUB_COMPUTER not in self.types:
return

comp = root.findtext(PUB_COMPUTER, '', namespaces)
Expand Down Expand Up @@ -1162,7 +1163,8 @@ def handle_command(self, line: str, write_stream: asyncio.StreamWriter) -> None:
logger.debug('clearing list of known devices')
WSDDiscoveredDevice.instances.clear()
elif command == 'list' and args.discovery:
write_stream.write(bytes(self.get_list_reply(), 'utf-8'))
wsd_type = command_args[0] if command_args else None
write_stream.write(bytes(self.get_list_reply(wsd_type), 'utf-8'))
elif command == 'quit':
write_stream.close()
elif command == 'start':
Expand All @@ -1175,9 +1177,12 @@ def handle_command(self, line: str, write_stream: asyncio.StreamWriter) -> None:
def get_clients_by_interface(self, interface: Optional[str]) -> List[WSDClient]:
return [c for c in WSDClient.instances if c.mch.address.interface.name == interface or not interface]

def get_list_reply(self) -> str:
def get_list_reply(self, wsd_type: Optional[str]) -> str:
retval = ''
for dev_uuid, dev in WSDDiscoveredDevice.instances.items():
if wsd_type and (wsd_type not in dev.types):
continue

addrs_str = []
for addrs in dev.addresses.items():
addrs_str.append(', '.join(['{}'.format(a) for a in addrs]))
Expand Down

0 comments on commit d77e0bb

Please sign in to comment.