Virtual Communitiesstatus: [source:abc/branches/ali/d080620-socialtribler-from-mainbranch-r7940 initial operational code] [ToDo] list DONE:
For next release Jan/Feb:
March+
Technical overview of mutual friendship
Logical Overview On start [source:abc/branches/ali/d080620-socialtribler-from-mainbranch-r7940/Tribler/Core/SocialNetwork/FriendsRequestHandler.py FriendsRequestHandler.py] 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
else:
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)
else:
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/FriendsRequestHandler.py FriendsRequestHandler.py] is responsible for it. HandleMessage is called by the [source:abc/branches/ali/d080620-socialtribler-from-mainbranch-r7940/Tribler/Core/Overlay/OverlayThreadingBridge.py 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:
pdb.deletePeer(permid)
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
else:
# 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)
dial.ShowModal()
# Now the status of Friend from 1 to 2 has to be changed, i.e., approved friend
pdb.updatePeer(permid, commit=True, friend = 2)
else:
dial = wx.MessageDialog(None, 'Sorry, your request to add has been denied :( ', 'Information',
wx.OK | wx.ICON_INFORMATION)
dial.ShowModal()
#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)
else:
if DEBUG:
print >> sys.stderr,"FRIENDREQUEST: UNKNOWN REQUEST MESSAGE", ord(t)
return False
Database Overview
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/FriendsItemPanel.py FriendsItemPanel.py], 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.SetBackgroundColour(wx.WHITE)
self.friendstatus.SetFont(wx.Font(FS_STATUS,FONTFAMILY,FONTWEIGHT,wx.NORMAL,False,FONTFACE))
self.friendstatus.SetForegroundColour(self.triblerGrey)
self.friendstatus.SetMinSize((165,12))
self.friendstatus.SetLabel("")
self.friendstatus.value = None
self.hSizer.Add(self.friendstatus,0,wx.TOP|wx.EXPAND,4)
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.SetLabel('unapproved')
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.SetLabel('approved')
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
Web resources
Related work
Scholar link Related literature
Social peer-to-peer for social people
Social Networks in Peer-to-Peer Systems link
The EigenTrust Algorithm for Reputation Management in P2P Networks link
The Dangers of Poorly Connected Peers in Structured P2P Networks and a Solution Based on Incentives
Evaluating similarity measures: a large-scale study in the orkut social network
Social Peer-to-Peer for Resource Discovery
Limited reputation sharing in P2P systems
Foreseer: a novel, locality-aware peer-to-peer system architecture for keyword searches
Ostra: Leveraging trust to thwart unwanted communication
An internet-deployed epidemic protocol stack Attachments
|