Fix some errors in the new twisted HTTP client's connectionLost() methods.
[quix0rs-apt-p2p.git] / apt_p2p_Khashmir / knode.py
1 ## Copyright 2002-2004 Andrew Loewenstern, All Rights Reserved
2 # see LICENSE.txt for license information
3
4 """Represents a khashmir node in the DHT."""
5
6 from twisted.python import log
7
8 from node import Node, NULL_ID
9
10 class KNodeError(Exception):
11     """An error occurred in contacting the node."""
12
13 class KNodeBase(Node):
14     """A basic node that can only be pinged and help find other nodes."""
15     
16     def checkSender(self, dict):
17         """Check the sender's info to make sure it meets expectations."""
18         try:
19             senderid = dict['id']
20         except KeyError:
21             log.msg("No peer id in response")
22             raise KNodeError, "No peer id in response."
23         else:
24             if self.id != NULL_ID and senderid != self.id:
25                 log.msg("Got response from different node than expected.")
26                 self.table.invalidateNode(self)
27                 raise KNodeError, "Node ID has changed"
28                 
29         return dict
30
31     def ping(self, id):
32         """Ping the node."""
33         df = self.conn.sendRequest('ping', {"id":id})
34         df.addCallback(self.checkSender)
35         return df
36     
37     def join(self, id):
38         """Use the node to bootstrap into the system."""
39         df = self.conn.sendRequest('join', {"id":id})
40         df.addCallback(self.checkSender)
41         return df
42     
43     def find_node(self, id, target):
44         """Request the nearest nodes to the target that the node knows about."""
45         df = self.conn.sendRequest('find_node', {"target" : target, "id": id})
46         df.addCallback(self.checkSender)
47         return df
48
49 class KNodeRead(KNodeBase):
50     """More advanced node that can also find and send values."""
51     
52     def find_value(self, id, key):
53         """Request the nearest nodes to the key that the node knows about."""
54         df =  self.conn.sendRequest('find_value', {"key" : key, "id" : id})
55         df.addCallback(self.checkSender)
56         return df
57
58     def get_value(self, id, key, num):
59         """Request the values that the node has for the key."""
60         df = self.conn.sendRequest('get_value', {"key" : key, "num": num, "id" : id})
61         df.addCallback(self.checkSender)
62         return df
63
64 class KNodeWrite(KNodeRead):
65     """Most advanced node that can also store values."""
66     
67     def store_value(self, id, key, value, token):
68         """Store a value in the node."""
69         df = self.conn.sendRequest('store_value', {"key" : key, "value" : value, "token" : token, "id": id})
70         df.addCallback(self.checkSender)
71         return df