~landscape/zope3/newer-from-ztk

« back to all changes in this revision

Viewing changes to src/twisted/scripts/mktap.py

  • Committer: Thomas Hervé
  • Date: 2009-07-08 13:52:04 UTC
  • Revision ID: thomas@canonical.com-20090708135204-df5eesrthifpylf8
Remove twisted copy

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (c) 2001-2004 Twisted Matrix Laboratories.
2
 
# See LICENSE for details.
3
 
 
4
 
import sys, os
5
 
 
6
 
from zope.interface import implements
7
 
 
8
 
from twisted.application import service, app
9
 
from twisted.persisted import sob
10
 
from twisted.python import usage, util, plugin as oldplugin
11
 
from twisted import plugin as newplugin
12
 
 
13
 
# API COMPATIBILITY
14
 
IServiceMaker = service.IServiceMaker
15
 
 
16
 
 
17
 
import warnings
18
 
 
19
 
warnings.warn(
20
 
    "mktap is obsolete as of Twisted 2.5, and will be officially deprecated "
21
 
    "in Twisted 2.6. Use Twisted Application Plugins with the "
22
 
    "'twistd' command  directly, as described in "
23
 
    "'Writing a Twisted Application Plugin for twistd' chapter of the "
24
 
    "Developer Guide.", PendingDeprecationWarning)
25
 
 
26
 
try:
27
 
    import pwd, grp
28
 
except ImportError:
29
 
    def getid(uid, gid):
30
 
        if uid is not None:
31
 
            uid = int(uid)
32
 
        if gid is not None:
33
 
            gid = int(gid)
34
 
        return uid, gid
35
 
else:
36
 
    def getid(uid, gid):
37
 
        if uid is not None:
38
 
            try:
39
 
                uid = int(uid)
40
 
            except ValueError:
41
 
                uid = pwd.getpwnam(uid)[2]
42
 
        if gid is not None:
43
 
            try:
44
 
                gid = int(gid)
45
 
            except ValueError:
46
 
                gid = grp.getgrnam(gid)[2]
47
 
        return uid, gid
48
 
 
49
 
 
50
 
def loadPlugins(debug = None, progress = None):
51
 
    tapLookup = {}
52
 
 
53
 
    plugins = oldplugin._getPlugIns("tap", debug, progress)
54
 
    for plug in plugins:
55
 
        if hasattr(plug, 'tapname'):
56
 
            shortTapName = plug.tapname
57
 
        else:
58
 
            shortTapName = plug.module.split('.')[-1]
59
 
        tapLookup[shortTapName] = plug
60
 
 
61
 
    plugins = newplugin.getPlugins(IServiceMaker)
62
 
    for plug in plugins:
63
 
        tapLookup[plug.tapname] = plug
64
 
 
65
 
    return tapLookup
66
 
 
67
 
def addToApplication(ser, name, append, procname, type, encrypted, uid, gid):
68
 
    if append and os.path.exists(append):
69
 
        a = service.loadApplication(append, 'pickle', None)
70
 
    else:
71
 
        a = service.Application(name, uid, gid)
72
 
    if procname:
73
 
        service.IProcess(a).processName = procname
74
 
    ser.setServiceParent(service.IServiceCollection(a))
75
 
    sob.IPersistable(a).setStyle(type)
76
 
    passphrase = app.getSavePassphrase(encrypted)
77
 
    if passphrase:
78
 
        append = None
79
 
    sob.IPersistable(a).save(filename=append, passphrase=passphrase)
80
 
 
81
 
class FirstPassOptions(usage.Options):
82
 
    synopsis = """Usage:    mktap [options] <command> [command options] """
83
 
 
84
 
    recursing = 0
85
 
    params = ()
86
 
 
87
 
    optParameters = [
88
 
        ['uid', 'u', None, "The uid to run as."],
89
 
        ['gid', 'g', None, "The gid to run as."],
90
 
        ['append', 'a', None,
91
 
         "An existing .tap file to append the plugin to, rather than "
92
 
         "creating a new one."],
93
 
        ['type', 't', 'pickle',
94
 
         "The output format to use; this can be 'pickle', 'xml', "
95
 
         "or 'source'."],
96
 
        ['appname', 'n', None, "The process name to use for this application."]
97
 
    ]
98
 
 
99
 
    optFlags = [
100
 
        ['encrypted', 'e', "Encrypt file before writing "
101
 
                           "(will make the extension of the resultant "
102
 
                           "file begin with 'e')"],
103
 
        ['debug', 'd',     "Show debug information for plugin loading"],
104
 
        ['progress', 'p',  "Show progress information for plugin loading"],
105
 
        ['help', 'h',  "Display this message"],
106
 
    ]
107
 
    #zsh_altArgDescr = {"foo":"use this description for foo instead"}
108
 
    #zsh_multiUse = ["foo", "bar"]
109
 
    #zsh_mutuallyExclusive = [("foo", "bar"), ("bar", "baz")]
110
 
    zsh_actions = {"append":'_files -g "*.tap"',
111
 
                   "type":"(pickle xml source)"}
112
 
    zsh_actionDescr = {"append":"tap file to append to", "uid":"uid to run as",
113
 
                       "gid":"gid to run as", "type":"output format"}
114
 
 
115
 
    def init(self, tapLookup):
116
 
        sc = []
117
 
        for (name, module) in tapLookup.iteritems():
118
 
            if IServiceMaker.providedBy(module):
119
 
                sc.append((
120
 
                    name, None, lambda m=module: m.options(), module.description))
121
 
            else:
122
 
                sc.append((
123
 
                    name, None, lambda obj=module: obj.load().Options(),
124
 
                    getattr(module, 'description', '')))
125
 
 
126
 
        sc.sort()
127
 
        self.subCommands = sc
128
 
 
129
 
    def parseArgs(self, *rest):
130
 
        self.params += rest
131
 
 
132
 
    def _reportDebug(self, info):
133
 
        print 'Debug: ', info
134
 
 
135
 
    def _reportProgress(self, info):
136
 
        s = self.pb(info)
137
 
        if s:
138
 
            print '\rProgress: ', s,
139
 
        if info == 1.0:
140
 
            print '\r' + (' ' * 79) + '\r',
141
 
 
142
 
    def postOptions(self):
143
 
        if self.recursing:
144
 
            return
145
 
        debug = progress = None
146
 
        if self['debug']:
147
 
            debug = self._reportDebug
148
 
        if self['progress']:
149
 
            progress = self._reportProgress
150
 
            self.pb = util.makeStatBar(60, 1.0)
151
 
        try:
152
 
            self.tapLookup = loadPlugins(debug, progress)
153
 
        except IOError:
154
 
            raise usage.UsageError("Couldn't load the plugins file!")
155
 
        self.init(self.tapLookup)
156
 
        self.recursing = 1
157
 
        self.parseOptions(self.params)
158
 
        if not hasattr(self, 'subOptions') or self['help']:
159
 
            raise usage.UsageError(str(self))
160
 
        if hasattr(self, 'subOptions') and self.subOptions.get('help'):
161
 
            raise usage.UsageError(str(self.subOptions))
162
 
        if not self.tapLookup.has_key(self.subCommand):
163
 
            raise usage.UsageError("Please select one of: "+
164
 
                                   ' '.join(self.tapLookup))
165
 
 
166
 
 
167
 
def run():
168
 
    options = FirstPassOptions()
169
 
    try:
170
 
        options.parseOptions(sys.argv[1:])
171
 
    except usage.UsageError, e:
172
 
        print e
173
 
        sys.exit(2)
174
 
    except KeyboardInterrupt:
175
 
        sys.exit(1)
176
 
 
177
 
    plg = options.tapLookup[options.subCommand]
178
 
    if not IServiceMaker.providedBy(plg):
179
 
        plg = plg.load()
180
 
    ser = plg.makeService(options.subOptions)
181
 
    addToApplication(ser,
182
 
                     options.subCommand, options['append'], options['appname'],
183
 
                     options['type'], options['encrypted'],
184
 
                     *getid(options['uid'], options['gid']))
185
 
 
186
 
from twisted.python.reflect import namedAny
187
 
from twisted.plugin import IPlugin
188
 
 
189
 
class _tapHelper(object):
190
 
    """
191
 
    Internal utility class to simplify the definition of \"new-style\"
192
 
    mktap plugins based on existing, \"classic\" mktap plugins.
193
 
    """
194
 
 
195
 
    implements(IPlugin, IServiceMaker)
196
 
 
197
 
    def __init__(self, name, module, description, tapname):
198
 
        self.name = name
199
 
        self.module = module
200
 
        self.description = description
201
 
        self.tapname = tapname
202
 
 
203
 
    def options():
204
 
        def get(self):
205
 
            return namedAny(self.module).Options
206
 
        return get,
207
 
    options = property(*options())
208
 
 
209
 
    def makeService():
210
 
        def get(self):
211
 
            return namedAny(self.module).makeService
212
 
        return get,
213
 
    makeService = property(*makeService())