Design tips requested for OOP forum system (using pickle)

Max M maxm at normik.dk
Fri Nov 30 04:18:05 EST 2001


"Simon Willison" <cs1spw at bath.ac.uk> wrote in message
news:eb8b2b6e.0111291359.64a1ee62 at posting.google.com...

Here's an example that isn't persistent. I cannot remember if this one was
the absolute last version i made, but it should give the general idea. Also
the message class ony contains id and title, yu would probably want to add a
few more parameters than that ;-)

It  was a quick prototype, done in an hour or two, for a discussionboard I
have later done in Zope. I changed quite a few things in the final version
but anyhoo ....

Regards Max M

#####################################################

class message:

    def __init__(self, id, title, _parent=None):
        self.id         = id
        self.title      = title
        self._parent    = _parent
        self._children  = []
        self.hidden     = 0
        self.indent     = 0

class msgList:

    def __init__(self):
        self.msgDict = {}
        self._newId  = 0

    def _getNewId(self):
        # generates a new unique id for a message
        # get new id and make a zero-padded string
        idString = str(self._newId)
        newID = (4*'0')[:-len(idString)] + idString
        self._newId += 1
        return '%s' % newID

    def addMessage(self, title, _parentId=None):
        id = self._getNewId()
        if _parentId != None:
            parent = self.getMessageById(_parentId)
            msg = message(id, title, parent)
            # add as child to parent
            parent._children.append(msg)
        else:
            msg = message(id, title, None)
        # indent doesn't change so set it here once and for all
        if _parentId != None:
            msg.indent = len(self.parents(msg))
        else:
            msg.indent = 0
        # add to messages
        self.msgDict[id] = msg

    def delMessage(self, id):
        # let parent take over this the messages children
        self.msgDict[id].parent._children += self.msgDict[id]._children
        # let children have this messages parent as their parents
        for child in self.msgDict[id]._children:
            child._parent = self.msgDict[id].parent.id
        # delete the bugger
        del(self.msgDict[id])

    def hideMessage(self, id):
        self.msgDict[id].hidden = 1

    def getMessageById(self, id):
        return self.msgDict[id]

    def getChildren(self, msg):
        # evil recursive function to get all children of a message
        # (recursion is evil by default!)
        grandChildren = []
        for child in msg._children:
            grandChildren += self.getChildren(child)
        return msg._children + grandChildren

    def parents(self, msg):
        # another evil recursive function to get all parents of a message
        # mostly used for calculating the indent level
        if msg._parent:
            return [msg._parent] + self.parents(msg._parent)
        else:
            return []

    def msgSort(self, msgs, sortAttrib='id', forward=1):
        # Sorts a list of objects in accordance to an attribute of choice
        # I assume that Pythons built in sort() is blistering fast
        # So I run around hoops to use that.
        sortValues = [(getattr(msg, sortAttrib), msg.id) for msg in msgs]
        sortValues.sort()
        if not forward:
            sortValues.reverse()
        return [self.msgDict[sortVal[1]] for sortVal in sortValues]

    def messages(self, threaded=1, sortAttrib='id', forward=1):
        """
        Returns a list with all the messages sorted and/or grouped.
        This is the most important method here.
        If threaded == 1 the messages are grouped by threads,
        else they are just sorted by the value of 'sortAttrib'
        If forward = 1 the value of sortAttrib is ascending
        If forward = 0 the value of sortAttrib is descending
        """
        if threaded:
            result = []
            threads = [
                msg for msg in self.msgDict.values() if msg._parent==None
                ]
            threads = self.msgSort(threads, sortAttrib, forward)
            for thread in threads:
                # REMEMBER!!!! still needs to sort in self.getChildren()
                result += [thread] + self.getChildren(thread)
            return result
        else:
            return self.msgSort(self.msgDict.values(), sortAttrib, forward)



msgs = msgList()
msgs.addMessage('msg10')
msgs.addMessage('msg02')
msgs.addMessage('msg13', '0000')
msgs.addMessage('msg4', '0001')
msgs.addMessage('msg5', '0001')
msgs.addMessage('msg6', '0002')
msgs.addMessage('msg7', '0005')
msgs.addMessage('msg8', '0005')

#print msgs.parents(msgs.getMessageById(7))[-1].title

print '-------------'
for msg in msgs.messages(threaded=1, sortAttrib='title', forward=1):
    print msg.id, msg.indent*'   '+msg.title






More information about the Python-list mailing list