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