9903b5a511e3097c69226ec93981e23b4f8983d5
[quix0rs-apt-p2p.git] / apt_dht_Khashmir / node.py
1 ## Copyright 2002-2003 Andrew Loewenstern, All Rights Reserved
2 # see LICENSE.txt for license information
3
4 from datetime import datetime, MINYEAR
5 from types import InstanceType
6
7 from twisted.trial import unittest
8 from twisted.python import log
9
10 import khash
11 from util import compact
12
13 # magic id to use before we know a peer's id
14 NULL_ID = 20 * '\0'
15
16 class Node:
17     """encapsulate contact info"""
18     def __init__(self, id, host = None, port = None):
19         log.msg('New node: id=%r, host=%r, port=%r' % (id, host, port))
20         self.fails = 0
21         self.lastSeen = datetime(MINYEAR, 1, 1)
22
23         # Alternate method, init Node from dictionary
24         if isinstance(id, dict):
25             host = id['host']
26             port = id['port']
27             id = id['id']
28
29         assert isinstance(id, str)
30         assert isinstance(host, str)
31         self.id = id
32         self.num = khash.intify(id)
33         self.host = host
34         self.port = int(port)
35         self._contactInfo = None
36     
37     def updateLastSeen(self):
38         self.lastSeen = datetime.now()
39         self.fails = 0
40     
41     def msgFailed(self):
42         self.fails = self.fails + 1
43         return self.fails
44     
45     def contactInfo(self):
46         if self._contactInfo is None:
47             self._contactInfo = compact(self.id, self.host, self.port)
48         return self._contactInfo
49     
50     def __repr__(self):
51         return `(self.id, self.host, self.port)`
52     
53     ## these comparators let us bisect/index a list full of nodes with either a node or an int/long
54     def __lt__(self, a):
55         if type(a) == InstanceType:
56             a = a.num
57         return self.num < a
58     def __le__(self, a):
59         if type(a) == InstanceType:
60             a = a.num
61         return self.num <= a
62     def __gt__(self, a):
63         if type(a) == InstanceType:
64             a = a.num
65         return self.num > a
66     def __ge__(self, a):
67         if type(a) == InstanceType:
68             a = a.num
69         return self.num >= a
70     def __eq__(self, a):
71         if type(a) == InstanceType:
72             a = a.num
73         return self.num == a
74     def __ne__(self, a):
75         if type(a) == InstanceType:
76             a = a.num
77         return self.num != a
78
79
80 class TestNode(unittest.TestCase):
81     def setUp(self):
82         self.node = Node(khash.newID(), '127.0.0.1', 2002)
83     def testUpdateLastSeen(self):
84         t = self.node.lastSeen
85         self.node.updateLastSeen()
86         self.failUnless(t < self.node.lastSeen)
87