Always return the result at the end of a callback function.
[quix0rs-apt-p2p.git] / apt-p2p.py
1 #!/usr/bin/python
2
3 """Load the 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
13 import pwd,sys
14
15 from twisted.application import service, internet, app, strports
16 from twisted.internet import reactor
17 from twisted.python import usage, log
18
19 from apt_p2p.apt_p2p_conf import config, version, DEFAULT_CONFIG_FILES
20 from apt_p2p.interfaces import IDHT, IDHTStatsFactory
21
22 config_file = ''
23
24 if __name__ == '__main__':
25     # Parse command line parameters when started on command line
26     class AptP2POptions(usage.Options):
27         optFlags = [
28             ['help', 'h', 'Print this help message'],
29             ]
30         optParameters = [
31             ['config-file', 'c', '', "Configuration file"],
32             ['log-file', 'l', '-', "File to log to, - for stdout"],
33             ]
34         longdesc="apt-p2p is a peer-to-peer downloader for apt users"
35         def opt_version(self):
36             print "apt-p2p %s" % version.short()
37             sys.exit(0)
38
39     opts = AptP2POptions()
40     try:
41         opts.parseOptions()
42     except usage.UsageError, ue:
43         print '%s: %s' % (sys.argv[0], ue)
44         sys.exit(1)
45
46     config_file = opts.opts['config-file']
47     log_file = opts.opts['log-file']
48     if log_file == '-':
49         f = sys.stdout
50     else:
51         f = open(log_file, 'w')
52     log.startLogging(f, setStdout=1)
53
54 log.msg("Loading config files: '%s'" % "', '".join(DEFAULT_CONFIG_FILES + [config_file]))
55 config_read = config.read(DEFAULT_CONFIG_FILES + [config_file])
56 log.msg("Successfully loaded config files: '%s'" % "', '".join(config_read))
57 try:
58     uid,gid = pwd.getpwnam(config.get('DEFAULT', 'USERNAME'))[2:4]
59 except:
60     uid,gid = None,None
61
62 log.msg('Starting application with uid/gid %r/%r' % (uid, gid))
63 application = service.Application("apt-p2p", uid, gid)
64 #print service.IProcess(application).processName
65 #service.IProcess(application).processName = 'apt-p2p'
66
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     factory = AptP2P(DHT.DHT)
74     s = strports.service('tcp:'+config.get('DEFAULT', 'port'), factory)
75     s.setServiceParent(application)
76 else:
77     log.msg('Starting the DHT')
78     myDHT = DHT.DHT()
79     
80     if IDHTStatsFactory.implementedBy(DHT.DHT):
81         log.msg("Starting the DHT's HTTP stats displayer")
82         factory = myDHT.getStatsFactory()
83         s = strports.service('tcp:'+config.get('DEFAULT', 'port'), factory)
84         s.setServiceParent(application)
85         
86     reactor.callLater(0, myDHT.loadConfig, config, config.get('DEFAULT', 'DHT'))
87     reactor.callLater(0, myDHT.join)
88
89 if __name__ == '__main__':
90     # Run on command line
91     service.IServiceCollection(application).privilegedStartService()
92     service.IServiceCollection(application).startService()
93     reactor.run()