Remove the unused steveholt entry from the bootstrap list.
[quix0rs-apt-p2p.git] / apt_p2p / apt_p2p_conf.py
1
2 """Loading of configuration files and parameters.
3
4 @type version: L{twisted.python.versions.Version}
5 @var version: the version of this program
6 @type DEFAULT_CONFIG_FILES: C{list} of C{string}
7 @var DEFAULT_CONFIG_FILES: the default config files to load (in order)
8 @var DEFAULTS: the default config parameter values for the main program
9 @var DHT_DEFAULTS: the default config parameter values for the default DHT
10
11 """
12
13 import os, sys
14 from ConfigParser import SafeConfigParser
15
16 from twisted.python import log, versions
17
18 class ConfigError(Exception):
19     """Errors that occur in the loading of configuration variables."""
20     def __init__(self, message):
21         self.message = message
22     def __str__(self):
23         return repr(self.message)
24
25 version = versions.Version('apt-p2p', 0, 0, 0)
26
27 # Set the home parameter
28 home = os.path.expandvars('${HOME}')
29 if home == '${HOME}' or not os.path.isdir(home):
30     home = os.path.expanduser('~')
31     if not os.path.isdir(home):
32         home = os.path.abspath(os.path.dirname(sys.argv[0]))
33
34 DEFAULT_CONFIG_FILES=['/etc/apt-p2p/apt-p2p.conf',
35                       home + '/.apt-p2p/apt-p2p.conf']
36
37 DEFAULTS = {
38
39     # Port to listen on for all requests (TCP and UDP)
40     'PORT': '9977',
41     
42     # Directory to store the downloaded files in
43     'CACHE_DIR': home + '/.apt-p2p/cache',
44     
45     # Other directories containing packages to share with others
46     # WARNING: all files in these directories will be hashed and available
47     #          for everybody to download
48     'OTHER_DIRS': """""",
49     
50     # User name to try and run as
51     'USERNAME': '',
52     
53     # Whether it's OK to use an IP addres from a known local/private range
54     'LOCAL_OK': 'no',
55
56     # Unload the packages cache after an interval of inactivity this long.
57     # The packages cache uses a lot of memory, and only takes a few seconds
58     # to reload when a new request arrives.
59     'UNLOAD_PACKAGES_CACHE': '5m',
60
61     # Refresh the DHT keys after this much time has passed.
62     # This should be a time slightly less than the DHT's KEY_EXPIRE value.
63     'KEY_REFRESH': '57m',
64
65     # Which DHT implementation to use.
66     # It must be possile to do "from <DHT>.DHT import DHT" to get a class that
67     # implements the IDHT interface.
68     'DHT': 'apt_p2p_Khashmir',
69
70     # Whether to only run the DHT (for providing only a bootstrap node)
71     'DHT-ONLY': 'no',
72 }
73
74 DHT_DEFAULTS = {
75     # bootstrap nodes to contact to join the DHT
76     'BOOTSTRAP': """www.camrdale.org:9977""",
77     
78     # whether this node is a bootstrap node
79     'BOOTSTRAP_NODE': "no",
80     
81     # Kademlia "K" constant, this should be an even number
82     'K': '8',
83     
84     # SHA1 is 160 bits long
85     'HASH_LENGTH': '160',
86     
87     # checkpoint every this many seconds
88     'CHECKPOINT_INTERVAL': '5m', # five minutes
89     
90     ### SEARCHING/STORING
91     # concurrent xmlrpc calls per find node/value request!
92     'CONCURRENT_REQS': '4',
93     
94     # how many hosts to post to
95     'STORE_REDUNDANCY': '3',
96     
97     # How many values to attempt to retrieve from the DHT.
98     # Setting this to 0 will try and get all values (which could take a while if
99     # a lot of nodes have values). Setting it negative will try to get that
100     # number of results from only the closest STORE_REDUNDANCY nodes to the hash.
101     # The default is a large negative number so all values from the closest
102     # STORE_REDUNDANCY nodes will be retrieved.
103     'RETRIEVE_VALUES': '-10000',
104
105     ###  ROUTING TABLE STUFF
106     # how many times in a row a node can fail to respond before it's booted from the routing table
107     'MAX_FAILURES': '3',
108     
109     # never ping a node more often than this
110     'MIN_PING_INTERVAL': '15m', # fifteen minutes
111     
112     # refresh buckets that haven't been touched in this long
113     'BUCKET_STALENESS': '1h', # one hour
114     
115     # expire entries older than this
116     'KEY_EXPIRE': '1h', # 60 minutes
117     
118     # whether to spew info about the requests/responses in the protocol
119     'SPEW': 'yes',
120 }
121
122 class AptP2PConfigParser(SafeConfigParser):
123     """Adds 'gettime' and 'getstringlist' to ConfigParser objects.
124     
125     @ivar time_multipliers: the 'gettime' suffixes and the multipliers needed
126         to convert them to seconds
127     """
128     
129     time_multipliers={
130         's': 1,    #seconds
131         'm': 60,   #minutes
132         'h': 3600, #hours
133         'd': 86400,#days
134         }
135
136     def gettime(self, section, option):
137         """Read the config parameter as a time value."""
138         mult = 1
139         value = self.get(section, option)
140         if len(value) == 0:
141             raise ConfigError("Configuration parse error: [%s] %s" % (section, option))
142         suffix = value[-1].lower()
143         if suffix in self.time_multipliers.keys():
144             mult = self.time_multipliers[suffix]
145             value = value[:-1]
146         return int(value)*mult
147     
148     def getstring(self, section, option):
149         """Read the config parameter as a string."""
150         return self.get(section,option)
151     
152     def getstringlist(self, section, option):
153         """Read the multi-line config parameter as a list of strings."""
154         return self.get(section,option).split()
155
156     def optionxform(self, option):
157         """Use all uppercase in the config parameters names."""
158         return option.upper()
159
160 # Initialize the default config parameters
161 config = AptP2PConfigParser(DEFAULTS)
162 config.add_section(config.get('DEFAULT', 'DHT'))
163 for k in DHT_DEFAULTS:
164     config.set(config.get('DEFAULT', 'DHT'), k, DHT_DEFAULTS[k])