news.py 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. # Copyright (c) Twisted Matrix Laboratories.
  2. # See LICENSE for details.
  3. """
  4. Maintainer: Jp Calderone
  5. """
  6. from __future__ import print_function
  7. from twisted.news import nntp
  8. from twisted.internet import protocol, reactor
  9. import time
  10. class NNTPFactory(protocol.ServerFactory):
  11. """A factory for NNTP server protocols."""
  12. protocol = nntp.NNTPServer
  13. def __init__(self, backend):
  14. self.backend = backend
  15. def buildProtocol(self, connection):
  16. p = self.protocol()
  17. p.factory = self
  18. return p
  19. class UsenetClientFactory(protocol.ClientFactory):
  20. def __init__(self, groups, storage):
  21. self.lastChecks = {}
  22. self.groups = groups
  23. self.storage = storage
  24. def clientConnectionLost(self, connector, reason):
  25. pass
  26. def clientConnectionFailed(self, connector, reason):
  27. print('Connection failed: ', reason)
  28. def updateChecks(self, addr):
  29. self.lastChecks[addr] = time.mktime(time.gmtime())
  30. def buildProtocol(self, addr):
  31. last = self.lastChecks.setdefault(addr, time.mktime(time.gmtime()) - (60 * 60 * 24 * 7))
  32. p = nntp.UsenetClientProtocol(self.groups, last, self.storage)
  33. p.factory = self
  34. return p
  35. # XXX - Maybe this inheritance doesn't make so much sense?
  36. class UsenetServerFactory(NNTPFactory):
  37. """A factory for NNTP Usenet server protocols."""
  38. protocol = nntp.NNTPServer
  39. def __init__(self, backend, remoteHosts = None, updatePeriod = 60):
  40. NNTPFactory.__init__(self, backend)
  41. self.updatePeriod = updatePeriod
  42. self.remoteHosts = remoteHosts or []
  43. self.clientFactory = UsenetClientFactory(self.remoteHosts, self.backend)
  44. def startFactory(self):
  45. self._updateCall = reactor.callLater(0, self.syncWithRemotes)
  46. def stopFactory(self):
  47. if self._updateCall:
  48. self._updateCall.cancel()
  49. self._updateCall = None
  50. def buildProtocol(self, connection):
  51. p = self.protocol()
  52. p.factory = self
  53. return p
  54. def syncWithRemotes(self):
  55. for remote in self.remoteHosts:
  56. reactor.connectTCP(remote, 119, self.clientFactory)
  57. self._updateCall = reactor.callLater(self.updatePeriod, self.syncWithRemotes)
  58. # backwards compatibility
  59. Factory = UsenetServerFactory