diff --git a/wortschlucker/src/wortschlucker.py b/wortschlucker/src/wortschlucker.py index 42cd58f..2ca8bbd 100755 --- a/wortschlucker/src/wortschlucker.py +++ b/wortschlucker/src/wortschlucker.py @@ -96,6 +96,13 @@ class Poll(sqlobject.SQLObject): timestamp_creation = sqlobject.DateTimeCol() def get_related_polls(self): + """ get all directly and indirectly connected polls up to a certain + distance + """ + return PollMesh(self).get_related_polls() + + def get_related_polls_direct(self): + """ get all directly connected polls """ related = [] related.extend([poll.second for poll in PollRelation.selectBy(first=self.id)]) related.extend([poll.first for poll in PollRelation.selectBy(second=self.id)]) @@ -162,6 +169,32 @@ class Poll(sqlobject.SQLObject): return str(self.timestamp_creation) +class PollMesh: + """ generate a mesh of directly or indirectly related polls + + Basically this is just a recursive search for unique related polls that are + connected to the base poll with less than (e.g.) five nodes in between. + """ + + def __init__(self, poll, depth=5): + self.related = [] + # start to collect the related polls immediately + self.__collect_related_polls(poll, depth) + + def __collect_related_polls(self, current_poll, current_depth): + """ recursive scanning for unique related polls up to a certain distance + """ + related = current_poll.get_related_polls_direct() + new_queue = [poll for poll in related if not poll in self.related] + self.related.extend(new_queue) + if current_depth > 0: + for poll in new_queue: + self.__collect_related_polls(poll, current_depth - 1) + + def get_related_polls(self): + return self.related + + def validate_poll_setting(key, value): if not key in POLL_SETTINGS.keys(): return None