aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/python/Twisted/py2/twisted/news/tap.py
blob: d6b8293414270d2068efd1da3d974b3b47a10411 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# Copyright (c) Twisted Matrix Laboratories.
# See LICENSE for details.


from __future__ import print_function

from twisted.news import news, database
from twisted.application import strports
from twisted.python import usage, log

class DBOptions(usage.Options):
    optParameters = [
        ['module',   None, 'pyPgSQL.PgSQL', "DB-API 2.0 module to use"],
        ['dbhost',   None, 'localhost',     "Host where database manager is listening"],
        ['dbuser',   None, 'news',          "Username with which to connect to database"],
        ['database', None, 'news',          "Database name to use"],
        ['schema',   None, 'schema.sql',    "File to which to write SQL schema initialisation"],

        # XXX - Hrm.
        ["groups",     "g", "groups.list",   "File containing group list"],
        ["servers",    "s", "servers.list",  "File containing server list"]
    ]
    
    def postOptions(self):
        # XXX - Hmmm.
        with open(self['groups']) as f:
            self['groups'] = [g.strip() for g in f.readlines() if not g.startswith('#')]
        with open(self['servers']) as f:
            self['servers'] = [s.strip() for s in f.readlines() if not s.startswith('#')]

        try:
            __import__(self['module'])
        except ImportError:
            log.msg("Warning: Cannot import %s" % (self['module'],))
        
        with open(self['schema'], 'w') as f:
            f.write(
                database.NewsStorageAugmentation.schema + '\n' +
                database.makeGroupSQL(self['groups']) + '\n' +
                database.makeOverviewSQL()
            )
        
        info = {
            'host': self['dbhost'], 'user': self['dbuser'],
            'database': self['database'], 'dbapiName': self['module']
        }
        self.db = database.NewsStorageAugmentation(info)


class PickleOptions(usage.Options):
    optParameters = [
        ['file', None, 'news.pickle', "File to which to save pickle"],

        # XXX - Hrm.
        ["groups",     "g", "groups.list",   "File containing group list"],
        ["servers",    "s", "servers.list",  "File containing server list"],
        ["moderators", "m", "moderators.list",
         "File containing moderators list"],
    ]
    
    subCommands = None

    def postOptions(self):
        # XXX - Hmmm.
        filename = self['file']
        with open(self['groups']) as f:
            self['groups'] = [g.strip() for g in f.readlines()
                              if not g.startswith('#')]
        with open(self['servers']) as f:
            self['servers'] = [s.strip() for s in f.readlines()
                               if not s.startswith('#')]
        with open(self['moderators']) as f:
            self['moderators'] = [s.split() for s in f.readlines()
                                  if not s.startswith('#')]
        self.db = database.PickleStorage(filename, self['groups'],
                                         self['moderators'])


class Options(usage.Options):
    synopsis = "[options]"
    
    groups = None
    servers = None
    subscriptions = None

    optParameters = [
        ["port",       "p", "119",           "Listen port"],
        ["interface",  "i", "",              "Interface to which to bind"],
        ["datadir",    "d", "news.db",       "Root data storage path"],
        ["mailhost",   "m", "localhost",     "Host of SMTP server to use"]
    ]
    compData = usage.Completions(
                   optActions={"datadir" : usage.CompleteDirs(),
                               "mailhost" : usage.CompleteHostnames(),
                               "interface" : usage.CompleteNetInterfaces()}
                   )

    def __init__(self):
        usage.Options.__init__(self)
        self.groups = []
        self.servers = []
        self.subscriptions = []


    def opt_group(self, group):
        """The name of a newsgroup to carry."""
        self.groups.append([group, None])


    def opt_moderator(self, moderator):
        """The email of the moderator for the most recently passed group."""
        self.groups[-1][1] = moderator


    def opt_subscription(self, group):
        """A newsgroup to list as a recommended subscription."""
        self.subscriptions.append(group)


    def opt_server(self, server):
        """The address of a Usenet server to pass messages to and receive messages from."""
        self.servers.append(server)


def makeService(config):
    if not len(config.groups):
        raise usage.UsageError("No newsgroups specified")
    
    db = database.NewsShelf(config['mailhost'], config['datadir'])
    for (g, m) in config.groups:
        if m:
            db.addGroup(g, 'm')
            db.addModerator(g, m)
        else:
            db.addGroup(g, 'y')
    for s in config.subscriptions:
        print(s)
        db.addSubscription(s)
    s = config['port']
    if config['interface']:
        # Add a warning here
        s += ':interface='+config['interface']
    return strports.service(s, news.UsenetServerFactory(db, config.servers))