Updated and added a lot of unittests.
[quix0rs-apt-p2p.git] / apt-p2p.py
1 #!/usr/bin/env python
2
3 # Load apt-p2p application
4 #
5 # There are two ways apt-p2p can be started:
6 #  1. twistd -y apt-p2p
7 #     - twistd will load this file and execute the app
8 #       in 'application' variable
9 #  2. from command line
10 #     - __name__ will be '__main__'
11
12 import pwd,sys
13
14 from twisted.application import service, internet, app, strports
15 from twisted.internet import reactor
16 from twisted.python import usage, log
17
18 from apt_p2p.apt_p2p_conf import config, version, DEFAULT_CONFIG_FILES
19 from apt_p2p.interfaces import IDHT, IDHTStatsFactory
20
21 config_file = ''
22
23 if __name__ == '__main__':
24     # Parse command line parameters when started on command line
25     class AptP2POptions(usage.Options):
26         optFlags = [
27             ['help', 'h', 'Print this help message'],
28             ]
29         optParameters = [
30             ['config-file', 'c', '', "Configuration file"],
31             ['log-file', 'l', '-', "File to log to, - for stdout"],
32             ]
33         longdesc="apt-p2p is a peer-to-peer downloader for apt users"
34         def opt_version(self):
35             print "apt-p2p %s" % version.short()
36             sys.exit(0)
37
38     opts = AptP2POptions()
39     try:
40         opts.parseOptions()
41     except usage.UsageError, ue:
42         print '%s: %s' % (sys.argv[0], ue)
43         sys.exit(1)
44
45     config_file = opts.opts['config-file']
46     log_file = opts.opts['log-file']
47     if log_file == '-':
48         f = sys.stdout
49     else:
50         f = open(log_file, 'w')
51     log.startLogging(f, setStdout=1)
52
53 log.msg("Loading config files: '%s'" % "', '".join(DEFAULT_CONFIG_FILES + [config_file]))
54 config_read = config.read(DEFAULT_CONFIG_FILES + [config_file])
55 log.msg("Successfully loaded config files: '%s'" % "', '".join(config_read))
56 if config.has_option('DEFAULT', 'username') and config.get('DEFAULT', 'username'):
57     uid,gid = pwd.getpwnam(config.get('DEFAULT', 'username'))[2:4]
58 else:
59     uid,gid = None,None
60
61 log.msg('Starting application')
62 application = service.Application("apt-p2p", uid, gid)
63 #print service.IProcess(application).processName
64 #service.IProcess(application).processName = 'apt-p2p'
65
66 log.msg('Starting DHT')
67 DHT = __import__(config.get('DEFAULT', 'DHT')+'.DHT', globals(), locals(), ['DHT'])
68 assert IDHT.implementedBy(DHT.DHT), "You must provide a DHT implementation that implements the IDHT interface."
69
70 if not config.getboolean('DEFAULT', 'DHT-only'):
71     log.msg('Starting main application server')
72     from apt_p2p.apt_p2p import AptP2P
73     myapp = AptP2P(DHT.DHT)
74     factory = myapp.getHTTPFactory()
75     s = strports.service('tcp:'+config.get('DEFAULT', 'port'), factory)
76     s.setServiceParent(application)
77 else:
78     myDHT = DHT.DHT()
79     if IDHTStatsFactory.implementedBy(DHT.DHT):
80         log.msg("Starting the DHT's HTTP stats displayer")
81         factory = myDHT.getStatsFactory()
82         s = strports.service('tcp:'+config.get('DEFAULT', 'port'), factory)
83         s.setServiceParent(application)
84         
85     myDHT.loadConfig(config, config.get('DEFAULT', 'DHT'))
86     myDHT.join()
87
88 if __name__ == '__main__':
89     # Run on command line
90     service.IServiceCollection(application).privilegedStartService()
91     service.IServiceCollection(application).startService()
92     reactor.run()