Virtual Communities

status: [source:abc/branches/ali/d080620-socialtribler-from-mainbranch-r7940 initial operational code]

[ToDo] list DONE:

  • Better friendship invite system: show new incoming & pending requested invites
    In order to send/receive friend's request, there are three possibilities:
    • Phase 1: If one's friend(s) is online, while she is adding her
    • Phase 2: If one's friend(s) is offline, while she is adding her
      (Re-try mechanism)
    • Phase 3: In case, both the parties are offline, then solution would be to save acceptance/rejection of friending at Taste Buddies/Friends
      (multiple 3rd party buffering)
  • Keep open TCP connection to friends
  • Send instant message to friend
    • Phase 1: both parties are online
    • Phase 2: Use re-try and 3rd party buffering mechanism

For next release Jan/Feb:

  • Add friend V2 after measurement feedback
  • SocioCast: Peer is now online at IPv4+port
  • Friends news feed; goal of fostering connectedness
    • new file/view
    • new rating
    • added friend
    • changed status message
  • Send private messages


  • CommentCast: attach comments to each swarm; easy message board by extending PEX within a swarm?
  • Easy import of friends; use easy approach with PermID attachment to Nickname at Server
    Every friend which uses Tribler already has their PermID already visible at their account info
    • MSN (msnlib?)
    • connect.facebook
    • OpenSocial or OpenID
  • Closed group swarms

Technical overview of mutual friendship

Logical Overview

On start [source:abc/branches/ali/d080620-socialtribler-from-mainbranch-r7940/Tribler/Core/SocialNetwork/] is registered as an Overlay Application. Its main purpose is to deal with friending requests, and its response. For peers, who want to add friends (other peers), either by selecting them from Tribler's "people found" section, or explicitly adding by their details in "add a friend" popup, this function friendRequestSend is called.

def friendRequestSend (self, parent, utility, editfriend = None):

        """ Called when user adds someone from the person found, or by explicitly adding someone with her credentials

        It establishes overlay connection with the target peer """

        #Connection with the target peer is established, with mentioning of call back function

        self.overlay_bridge.connect(editfriend['permid'], self.friendRequestConnectionEstablishmentCallBack)

For receiving acknowledgment of the connect routine, this function tries to re-connect if an exception arises. On successful connect, it tries to send a friending request to the target peer. The message contains requestee's details, like Nick, IP, Port and Permid.

def friendRequestConnectionEstablishmentCallBack(self, exc, dns, target_permid, selversion):

        """ Callback function for the overlay connect function, i.e., friendRequestSendWithOnlyID and

        friendRequestSend """


        if exc is not None:

            #Send connection request every five minutes

            self.overlay_bridge.add_task(lambda: self.friendRequestSendWithOnlyID(target_permid), 300)

        # send the message if there was no pending messages; This message contains peer's own information, i.e, nickname, ip and permid

        if self.lastSentMessage is None:

            msg = ':Hi:'    

            text = msg+str(self.mynickname)+':'+str(self.myip)+':'+str(self.myport)+':'+show_permid(self.mypermid)

        #In case of exception, save this message

            self.lastSentMessage = FRIENDREQUEST + text

            self.overlay_bridge.send(target_permid, FRIENDREQUEST + text, self.friendRequestConnectionEstablishedCallBack)

        # To see if the last message was successfully sent or not; if not, re-try


            self.overlay_bridge.send(target_permid, FRIENDREQUEST + self.lastSentMessage, self.friendRequestConnectionEstablishedCallBack)

        def friendRequestConnectionEstablishedCallBack(self, exc, peer_permid, other=0):

        # If an exception arises

        if exc is not None:

            #Send connection request every five minutes

            self.overlay_bridge.add_task(lambda: self.friendRequestSendWithOnlyID(peer_permid), 300)


            self.lastSentMessage = None # On successful connect, make lastMessage as none

For receiving overlay messages, overlay message handler has to be created and registered. The same class [source:abc/branches/ali/d080620-socialtribler-from-mainbranch-r7940/Tribler/Core/SocialNetwork/] is responsible for it.

HandleMessage is called by the [source:abc/branches/ali/d080620-socialtribler-from-mainbranch-r7940/Tribler/Core/Overlay/ OverlayThreadingBridge] on receiving a message for a particular protocol. In this case, it is FRIENDREQUEST protocol. This function does two main things -- Display a popup message to a peer to accept/reject a friending request -- This response is received by the requestee, and then based on the response, either friend is "approved", or deleted from the friends' list

Peers are notified by a pop-up whether their friending request has been approved, or not.

    def handleMessage(self,permid,selversion,message):

        ''' This is called by the OverlayThreadingBridge to receive incoming messages, which were sent by

        Overlay Bridge'''

        pdb = PeerDBHandler.getInstance() # instance of peer db

        fdb = FriendDBHandler.getInstance() # instance of friend db

        temp = message.split(':') # split the message into array of string; separated by ':'

        isFriend = fdb.isFriend(permid) # to see that the following peer is already a friend, or not

        #variable to store peer's response on friending request

        approved = ''

        # Hi being the first element shows that friending request is being received

        if temp[1] == 'Hi':

            # See the database if it contains any information of this peer

            if pdb.hasPeer(permid):

                if not isFriend: # And if that peer is not already added as a friend, either approved, or unapproved

                    dial = wx.MessageDialog(None, 'DB YES: Do you want to add 

'  + temp[2]+ '

 as you friend?  ', 'Question', 

                                        wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION)

                    returnValue = dial.ShowModal()

                    approved = ":NO:" 

                    if returnValue == wx.ID_YES:

                        approved = ":YES:"

                        pdb.updatePeer(permid, commit=True, friend = 2)

                    elif returnValue == wx.ID_NO:


                else: # In case, requestee is already added as friend, just make this requestee as an approved friend

                    pdb.updatePeer(permid, commit=True, friend = 2)

                    approved = ":YES:" 

            # Now this peer had to be locally saved as well, since database doesn't have any record of it


                # Dialogue for asking wheter to approve, or deny the request

                dial = wx.MessageDialog(None, 'DB NO: Do you want to add 

'  + temp[2]+ '

 as you friend?  ', 'Question', 

                                        wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION)

                returnValue = dial.ShowModal()

                approved = ":NO:"  # By default, set the value to 'No' to friending request

                # In case of acceptance, save 'YES'

                if returnValue == wx.ID_YES:

                    approved = ":YES:"

                    # text = msg+str(self.mynickname)+':'+str(self.myip)+':'+str(self.myport)+':'+show_permid(self.mypermid)

                    friend = {'ip':temp[3], 'port':temp[4], 'name':temp[2]}

                    # Add that peer into the database

                    pdb.addPeer(permid, friend)

                    # Update its status to an approved friend

                    pdb.updatePeer(permid, commit=True, friend = 2)

                elif returnValue == wx.ID_NO:

                    # Do nothing when denying a request to the database

                    print "Do nothing"

            # Save the last message, i.e., approved to lastSentMessage, so that in case of error, this message

            # could be resend

            self.lastSentMessage = approved

            # send the peer's response to the requestee 

            self.overlay_bridge.send(permid, FRIENDREQUEST + approved, self.friendRequestConnectionEstablishedCallBack)

        # On receiving response from a peer of friending request    

        elif temp[1] == 'YES' or temp[1] == 'NO':

            approved = temp[1]

            if approved == "YES":

                # update this friend's status in the database as "confirmed friend", or "approved friend"

                dial = wx.MessageDialog(None, 'Hurray! Your request to add has been approved ', 'Information', 

                                   wx.OK | wx.ICON_INFORMATION)


                # Now the status of Friend from 1 to 2 has to be changed, i.e., approved friend

                pdb.updatePeer(permid, commit=True, friend = 2)


                dial = wx.MessageDialog(None, 'Sorry, your request to add has been denied :( ', 'Information', 

                                   wx.OK | wx.ICON_INFORMATION)


                #Remove this peer as a friend, and then update the database

                pdb.updatePeer(permid, commit=True, friend = 0)

        if DEBUG:

            print >> sys.stderr,"FRIENDREQUEST : Got FRIEND REQUEST",len(message)


            if DEBUG:

                print >> sys.stderr,"FRIENDREQUEST: UNKNOWN REQUEST MESSAGE", ord(t)

            return False

Database Overview
In the database, Friend field of the Peer table is 3 valued now.

  • 0 being not friend
  • 1 being unapproved friend
  • 2 being approved friend

GUI Overview

Also, now the "Friends" section contains another column "Approved/Unapproved friend"; more specifically, in the [source:abc/branches/ali/d080620-socialtribler-from-mainbranch-r7940/Tribler/Main/vwxGUI/], a new column "Is approved friend" is added. Now, the reason is why it's added, actually, all friends are added right away, but only those become "approved" ones which are mutually agreed by the target peers. Here is the code snippet of that column

        # Add friend's status

        self.friendstatus = wx.StaticText(self,-1,"",wx.Point(0,0),wx.Size(130,12), wx.ALIGN_RIGHT | wx.ST_NO_AUTORESIZE )        






        self.friendstatus.value = None 


For visual feedback, apart from setting this column for each peer, each approved friend looks different toopltip wise as well.

            # To show that the current friend hasn't approved friending request

            if friendStatusValue == 1:


                self.friendstatus.SetToolTipString('Friending request has not been approved')

                self.friendstatus.value = 1

            # To show that the current friend has approved friending request

            elif friendStatusValue == 2:


                self.friendstatus.SetToolTipString('Friending request has been approved')

                self.friendstatus.value = 2

Also, the colour of the row is different for approved friends

      # For approved friends, make this row as light grey

      elif self.friendstatus.value == 2:

                colour = wx.LIGHT_GREY

Future Ideas

  • internal use at Amnesty?
  • exchange of video material/files in general- group message exchange/boards
  • Community management
    • group management architecture
    • group leaders
    • white list?
    • membership list discovery/management
    • inject/download/delete rights
  • users always online?

Web resources

Related work

Scholar link
P2P links..
Social Network link

Related literature

Social peer-to-peer for social people
Borch, N.
05: The Int’l Conf. on Internet Technologies and Applications

Social Networks in Peer-to-Peer Systems link
Upadrashta, Y. and Vassileva, J. and Grassmann, W.
05: System Sciences, 2005. HICSS'05. Proceedings of the 38th Annual Hawaii International Conference on

The EigenTrust Algorithm for Reputation Management in P2P Networks link
Kamvar, S.D. and Schlosser, M.T. and Garcia-Molina, H.
Proceedings of the 12th international conference on World Wide Web
03: ACM Press New York, NY, USA

The Dangers of Poorly Connected Peers in Structured P2P Networks and a Solution Based on Incentives
Hartmann, B.O. and Bohm, K. and Khachatryan, A. and Schosser, S.
07: Web Intelligence, IEEE/WIC/ACM International Conference

Evaluating similarity measures: a large-scale study in the orkut social network
Spertus, E. and Sahami, M. and Buyukkokten, O.
05: Conference on Knowledge Discovery in Data, ACM Press New York, NY, USA

Social Peer-to-Peer for Resource Discovery
Liu, L. and Antonopoulos, N. and Mackin, S.
07: Parallel, Distributed and Network-Based Processing, 2007. PDP'07. 15th EUROMICRO

Limited reputation sharing in P2P systems
Marti, S. and Garcia-Molina, H.
04: Proceedings of the 5th ACM conference on Electronic commerce, ACM Press New York, NY, USA

Foreseer: a novel, locality-aware peer-to-peer system architecture for keyword searches
Cai, H. and Wang, J.
04: Proceedings of the 5th ACM/IFIP/USENIX international conference on Middleware, Springer

Ostra: Leveraging trust to thwart unwanted communication
Cai, H. and Wang, J.
04: Proceedings of the 5th ACM/IFIP/USENIX international conference on Middleware, Springer

An internet-deployed epidemic protocol stack
J.A. Pouwelse, J. Yang, M. Meuploder, D.H.J. Epema, H.J. Sips