Implement dependency system for CAPs
This commit is contained in:
parent
8a0d99f969
commit
90c90e5bbd
2 changed files with 50 additions and 3 deletions
|
@ -16,13 +16,58 @@ CAPABILITIES = [
|
||||||
utils.irc.Capability(None, "draft/setname", alias="setname")
|
utils.irc.Capability(None, "draft/setname", alias="setname")
|
||||||
]
|
]
|
||||||
|
|
||||||
|
def _cap_depend_sort(caps, server_caps):
|
||||||
|
sorted_caps = []
|
||||||
|
|
||||||
|
caps_copy = {alias: cap.copy() for alias, cap in caps.items()}
|
||||||
|
|
||||||
|
for cap in caps.values():
|
||||||
|
if not cap.available(server_caps):
|
||||||
|
del caps_copy[cap.alias]
|
||||||
|
|
||||||
|
while True:
|
||||||
|
remove = []
|
||||||
|
for alias, cap in caps_copy.items():
|
||||||
|
for depend_alias in cap.depends_on:
|
||||||
|
if not depend_alias in caps_copy:
|
||||||
|
remove.append(alias)
|
||||||
|
if remove:
|
||||||
|
for alias in remove:
|
||||||
|
del caps_copy[alias]
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
|
||||||
|
while caps_copy:
|
||||||
|
fulfilled = []
|
||||||
|
for cap in caps_copy.values():
|
||||||
|
remove = []
|
||||||
|
for depend_alias in cap.depends_on:
|
||||||
|
if depend_alias in sorted_caps:
|
||||||
|
remove.append(depend_alias)
|
||||||
|
for remove_cap in remove:
|
||||||
|
cap.depends_on.remove(remove_cap)
|
||||||
|
|
||||||
|
if not cap.depends_on:
|
||||||
|
fulfilled.append(cap.alias)
|
||||||
|
for fulfilled_cap in fulfilled:
|
||||||
|
del caps_copy[fulfilled_cap]
|
||||||
|
sorted_caps.append(fulfilled_cap)
|
||||||
|
return [caps[alias] for alias in sorted_caps]
|
||||||
|
|
||||||
def _cap_match(server, caps):
|
def _cap_match(server, caps):
|
||||||
matched_caps = {}
|
matched_caps = {}
|
||||||
blacklist = server.get_setting("blacklisted-caps", [])
|
blacklist = server.get_setting("blacklisted-caps", [])
|
||||||
|
|
||||||
|
cap_aliases = {}
|
||||||
for cap in caps:
|
for cap in caps:
|
||||||
|
if not cap.alias in blacklist:
|
||||||
|
cap_aliases[cap.alias] = cap
|
||||||
|
|
||||||
|
sorted_caps = _cap_depend_sort(cap_aliases, server.server_capabilities)
|
||||||
|
|
||||||
|
for cap in sorted_caps:
|
||||||
available = cap.available(server.server_capabilities)
|
available = cap.available(server.server_capabilities)
|
||||||
if (available and not server.has_capability(cap) and
|
if available and not server.has_capability(cap):
|
||||||
not available in blacklist):
|
|
||||||
matched_caps[available] = cap
|
matched_caps[available] = cap
|
||||||
return matched_caps
|
return matched_caps
|
||||||
|
|
||||||
|
|
|
@ -291,6 +291,7 @@ class Capability(object):
|
||||||
depends_on: typing.List[str]=None):
|
depends_on: typing.List[str]=None):
|
||||||
self.alias = alias or ratified_name
|
self.alias = alias or ratified_name
|
||||||
self._caps = set([ratified_name, draft_name])
|
self._caps = set([ratified_name, draft_name])
|
||||||
|
self.depends_on = depends_on or []
|
||||||
self._on_ack_callbacks = [
|
self._on_ack_callbacks = [
|
||||||
] # type: typing.List[typing.Callable[[], None]]
|
] # type: typing.List[typing.Callable[[], None]]
|
||||||
|
|
||||||
|
@ -304,7 +305,8 @@ class Capability(object):
|
||||||
return cap[0] if cap else None
|
return cap[0] if cap else None
|
||||||
|
|
||||||
def copy(self):
|
def copy(self):
|
||||||
return Capability(*self._caps)
|
return Capability(*self._caps, alias=self.alias,
|
||||||
|
depends_on=self.depends_on)
|
||||||
|
|
||||||
def on_ack(self, callback: typing.Callable[[], None]):
|
def on_ack(self, callback: typing.Callable[[], None]):
|
||||||
self._on_ack_callbacks.append(callback)
|
self._on_ack_callbacks.append(callback)
|
||||||
|
|
Loading…
Reference in a new issue