tap.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. # Copyright (c) Twisted Matrix Laboratories.
  2. # See LICENSE for details.
  3. from __future__ import print_function
  4. from twisted.news import news, database
  5. from twisted.application import strports
  6. from twisted.python import usage, log
  7. class DBOptions(usage.Options):
  8. optParameters = [
  9. ['module', None, 'pyPgSQL.PgSQL', "DB-API 2.0 module to use"],
  10. ['dbhost', None, 'localhost', "Host where database manager is listening"],
  11. ['dbuser', None, 'news', "Username with which to connect to database"],
  12. ['database', None, 'news', "Database name to use"],
  13. ['schema', None, 'schema.sql', "File to which to write SQL schema initialisation"],
  14. # XXX - Hrm.
  15. ["groups", "g", "groups.list", "File containing group list"],
  16. ["servers", "s", "servers.list", "File containing server list"]
  17. ]
  18. def postOptions(self):
  19. # XXX - Hmmm.
  20. with open(self['groups']) as f:
  21. self['groups'] = [g.strip() for g in f.readlines() if not g.startswith('#')]
  22. with open(self['servers']) as f:
  23. self['servers'] = [s.strip() for s in f.readlines() if not s.startswith('#')]
  24. try:
  25. __import__(self['module'])
  26. except ImportError:
  27. log.msg("Warning: Cannot import %s" % (self['module'],))
  28. with open(self['schema'], 'w') as f:
  29. f.write(
  30. database.NewsStorageAugmentation.schema + '\n' +
  31. database.makeGroupSQL(self['groups']) + '\n' +
  32. database.makeOverviewSQL()
  33. )
  34. info = {
  35. 'host': self['dbhost'], 'user': self['dbuser'],
  36. 'database': self['database'], 'dbapiName': self['module']
  37. }
  38. self.db = database.NewsStorageAugmentation(info)
  39. class PickleOptions(usage.Options):
  40. optParameters = [
  41. ['file', None, 'news.pickle', "File to which to save pickle"],
  42. # XXX - Hrm.
  43. ["groups", "g", "groups.list", "File containing group list"],
  44. ["servers", "s", "servers.list", "File containing server list"],
  45. ["moderators", "m", "moderators.list",
  46. "File containing moderators list"],
  47. ]
  48. subCommands = None
  49. def postOptions(self):
  50. # XXX - Hmmm.
  51. filename = self['file']
  52. with open(self['groups']) as f:
  53. self['groups'] = [g.strip() for g in f.readlines()
  54. if not g.startswith('#')]
  55. with open(self['servers']) as f:
  56. self['servers'] = [s.strip() for s in f.readlines()
  57. if not s.startswith('#')]
  58. with open(self['moderators']) as f:
  59. self['moderators'] = [s.split() for s in f.readlines()
  60. if not s.startswith('#')]
  61. self.db = database.PickleStorage(filename, self['groups'],
  62. self['moderators'])
  63. class Options(usage.Options):
  64. synopsis = "[options]"
  65. groups = None
  66. servers = None
  67. subscriptions = None
  68. optParameters = [
  69. ["port", "p", "119", "Listen port"],
  70. ["interface", "i", "", "Interface to which to bind"],
  71. ["datadir", "d", "news.db", "Root data storage path"],
  72. ["mailhost", "m", "localhost", "Host of SMTP server to use"]
  73. ]
  74. compData = usage.Completions(
  75. optActions={"datadir" : usage.CompleteDirs(),
  76. "mailhost" : usage.CompleteHostnames(),
  77. "interface" : usage.CompleteNetInterfaces()}
  78. )
  79. def __init__(self):
  80. usage.Options.__init__(self)
  81. self.groups = []
  82. self.servers = []
  83. self.subscriptions = []
  84. def opt_group(self, group):
  85. """The name of a newsgroup to carry."""
  86. self.groups.append([group, None])
  87. def opt_moderator(self, moderator):
  88. """The email of the moderator for the most recently passed group."""
  89. self.groups[-1][1] = moderator
  90. def opt_subscription(self, group):
  91. """A newsgroup to list as a recommended subscription."""
  92. self.subscriptions.append(group)
  93. def opt_server(self, server):
  94. """The address of a Usenet server to pass messages to and receive messages from."""
  95. self.servers.append(server)
  96. def makeService(config):
  97. if not len(config.groups):
  98. raise usage.UsageError("No newsgroups specified")
  99. db = database.NewsShelf(config['mailhost'], config['datadir'])
  100. for (g, m) in config.groups:
  101. if m:
  102. db.addGroup(g, 'm')
  103. db.addModerator(g, m)
  104. else:
  105. db.addGroup(g, 'y')
  106. for s in config.subscriptions:
  107. print(s)
  108. db.addSubscription(s)
  109. s = config['port']
  110. if config['interface']:
  111. # Add a warning here
  112. s += ':interface='+config['interface']
  113. return strports.service(s, news.UsenetServerFactory(db, config.servers))