remove vendor

This commit is contained in:
Todd Willey
2010-07-15 01:31:16 -04:00
parent 9acf115024
commit 63d545d9f3
1765 changed files with 1 additions and 420366 deletions

View File

@@ -20,27 +20,5 @@
Get our vendor folders into the system path.
"""
import os
import sys
print 'sorry, we cannot include vendor open source libraries... :('
# abspath/__file__/../vendor
VENDOR_PATH = os.path.abspath(
os.path.join(os.path.dirname(os.path.dirname(__file__)), 'vendor'))
if not os.path.exists(VENDOR_PATH):
print 'warning: no vendor libraries included'
else:
paths = [VENDOR_PATH,
os.path.join(VENDOR_PATH, 'pymox'),
os.path.join(VENDOR_PATH, 'tornado'),
os.path.join(VENDOR_PATH, 'python-gflags'),
os.path.join(VENDOR_PATH, 'python-daemon'),
os.path.join(VENDOR_PATH, 'lockfile'),
os.path.join(VENDOR_PATH, 'boto'),
os.path.join(VENDOR_PATH, 'Twisted-10.0.0'),
os.path.join(VENDOR_PATH, 'redis-py'),
]
for p in paths:
if p not in sys.path:
sys.path.insert(0, p)

1304
vendor/IPy.py vendored

File diff suppressed because it is too large Load Diff

View File

@@ -1,32 +0,0 @@
Requirements
Python 2.4, 2.5 or 2.6.
Zope Interfaces 3.0.1 (http://zope.org/Products/ZopeInterface) - if
you have ZopeX3 (at least version 3.0.0c1) installed that should
work too.
On Windows pywin32 is recommended (this is built in to ActivePython,
so no need to reinstall if you use it instead of standard Python)
http://sourceforge.net/project/showfiles.php?group_id=78018
The Windows IOCP reactor requires pywin32 build 205 or later.
If you would like to use Trial's subunit reporter, then you will need to
install Subunit 0.0.2 or later (https://launchpad.net/subunit).
Installation
* Debian and Ubuntu
Packages are included in the main distribution.
* FreeBSD, Gentoo
Twisted is in their package repositories.
* Win32
EXEs are available from http://twistedmatrix.com/
* Other
As with other Python packages, the standard way of installing from source
is:
python setup.py install

View File

@@ -1,57 +0,0 @@
Copyright (c) 2001-2010
Allen Short
Andy Gayton
Andrew Bennetts
Antoine Pitrou
Apple Computer, Inc.
Benjamin Bruheim
Bob Ippolito
Canonical Limited
Christopher Armstrong
David Reid
Donovan Preston
Eric Mangold
Eyal Lotem
Itamar Shtull-Trauring
James Knight
Jason A. Mobarak
Jean-Paul Calderone
Jessica McKellar
Jonathan Jacobs
Jonathan Lange
Jonathan D. Simms
Jürgen Hermann
Kevin Horn
Kevin Turner
Mary Gardiner
Matthew Lefkowitz
Massachusetts Institute of Technology
Moshe Zadka
Paul Swartz
Pavel Pergamenshchik
Ralph Meijer
Sean Riley
Software Freedom Conservancy
Travis B. Hartwell
Thijs Triemstra
Thomas Herve
Timothy Allen
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

File diff suppressed because it is too large Load Diff

View File

@@ -1,118 +0,0 @@
Twisted 10.0.0
Quote of the Release:
[on picking the quote of the release]
<glyph> Man, we're going to have to get a lot funnier if we're going
to do time-based releases
For information on what's new in Twisted 10.0.0, see the NEWS file that comes
with the distribution.
What is this?
=============
Twisted is an event-based framework for internet applications which works on
Python 2.4 through 2.6. The following are some of the modules included
with Twisted::
- twisted.application
A "Service" system that allows you to organize your application in
hierarchies with well-defined startup and dependency semantics,
- twisted.cred
A general credentials and authentication system that facilitates
pluggable authentication backends,
- twisted.enterprise
Asynchronous database access, compatible with any Python DBAPI2.0
modules,
- twisted.internet
Low-level asynchronous networking APIs that allow you to define
your own protocols that run over certain transports,
- twisted.manhole
A tool for remote debugging of your services which gives you a
Python interactive interpreter,
- twisted.protocols
Basic protocol implementations and helpers for your own protocol
implementations,
- twisted.python
A large set of utilities for Python tricks, reflection, text
processing, and anything else,
- twisted.spread
A secure, fast remote object system,
- twisted.trial
A unit testing framework that integrates well with Twisted-based code.
Twisted supports integration of the Tk, GTK+, GTK+ 2, Qt, Mac OS X,
or wxPython event loop with its main event loop. The Win32 event
loop is also supported.
For more information, visit http://www.twistedmatrix.com, or join the list
at http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python
There are many official Twisted subprojects, including clients and
servers for web, mail, DNS, and more. You can find out more about
these projects at http://twistedmatrix.com/trac/wiki/TwistedProjects
Installing
==========
Instructions for installing this software are in INSTALL.
Unit Tests
==========
See our unit tests run proving that the software is BugFree(TM)::
% trial twisted
Some of these tests may fail if you
* don't have the dependancies required for a particular subsystem installed,
* have a firewall blocking some ports (or things like Multicast, which Linux
NAT has shown itself to do), or
* run them as root.
Documentation and Support
=========================
Examples on how to use Twisted APIs are located in doc/examples;
this might ease the learning curve a little bit, since all these
files are kept as short as possible. The file doc/howto/index.xhtml
contains an index of all the HOWTOs: this should be your starting
point when looking for documentation.
Help is available on the Twisted mailing list::
http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python
There is also a very lively IRC channel, #twisted, on
irc.freenode.net.
Copyright
=========
All of the code in this distribution is Copyright (c) 2001-2010
Twisted Matrix Laboratories.
Twisted is made available under the MIT license. The included
LICENSE file describes this in detail.
Warranty
========
THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE USE OF THIS SOFTWARE IS WITH YOU.
IN NO EVENT WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY, BE LIABLE TO YOU FOR ANY DAMAGES, EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
Again, see the included LICENSE file for specific legal details.

Binary file not shown.

View File

@@ -1,20 +0,0 @@
#!/usr/bin/env python
# Copyright (c) 2001-2009 Twisted Matrix Laboratories.
# See LICENSE for details.
### Twisted Preamble
# This makes sure that users don't have to set up their environment
# specially in order to run these programs from bin/.
import sys, os
path = os.path.abspath(sys.argv[0])
while os.path.dirname(path) != path:
if os.path.basename(path).startswith('Twisted'):
sys.path.insert(0, path)
break
path = os.path.dirname(path)
### end of preamble
from twisted.conch.scripts.cftp import run
run()

View File

@@ -1,20 +0,0 @@
#!/usr/bin/env python
# Copyright (c) 2001-2009 Twisted Matrix Laboratories.
# See LICENSE for details.
### Twisted Preamble
# This makes sure that users don't have to set up their environment
# specially in order to run these programs from bin/.
import sys, os
path = os.path.abspath(sys.argv[0])
while os.path.dirname(path) != path:
if os.path.basename(path).startswith('Twisted'):
sys.path.insert(0, path)
break
path = os.path.dirname(path)
### end of preamble
from twisted.conch.scripts.ckeygen import run
run()

View File

@@ -1,20 +0,0 @@
#!/usr/bin/env python
# Copyright (c) 2001-2009 Twisted Matrix Laboratories.
# See LICENSE for details.
### Twisted Preamble
# This makes sure that users don't have to set up their environment
# specially in order to run these programs from bin/.
import sys, os
path = os.path.abspath(sys.argv[0])
while os.path.dirname(path) != path:
if os.path.basename(path).startswith('Twisted'):
sys.path.insert(0, path)
break
path = os.path.dirname(path)
### end of preamble
from twisted.conch.scripts.conch import run
run()

View File

@@ -1,20 +0,0 @@
#!/usr/bin/env python
# Copyright (c) 2001-2009 Twisted Matrix Laboratories.
# See LICENSE for details.
### Twisted Preamble
# This makes sure that users don't have to set up their environment
# specially in order to run these programs from bin/.
import sys, os
path = os.path.abspath(sys.argv[0])
while os.path.dirname(path) != path:
if os.path.basename(path).startswith('Twisted'):
sys.path.insert(0, path)
break
path = os.path.dirname(path)
### end of preamble
from twisted.conch.scripts.tkconch import run
run()

View File

@@ -1,21 +0,0 @@
#!/usr/bin/env python
# Copyright (c) 2001-2009 Twisted Matrix Laboratories.
# See LICENSE for details.
### Twisted Preamble
# This makes sure that users don't have to set up their environment
# specially in order to run these programs from bin/.
import sys, os
path = os.path.abspath(sys.argv[0])
while os.path.dirname(path) != path:
if os.path.basename(path).startswith('Twisted'):
sys.path.insert(0, path)
break
path = os.path.dirname(path)
### end of preamble
from twisted.lore.scripts.lore import run
run()

View File

@@ -1,25 +0,0 @@
#!/usr/bin/env python
# Copyright (c) 2001-2009 Twisted Matrix Laboratories.
# See LICENSE for details.
"""
This script attempts to send some email.
"""
### Twisted Preamble
# This makes sure that users don't have to set up their environment
# specially in order to run these programs from bin/.
import sys, os
path = os.path.abspath(sys.argv[0])
while os.path.dirname(path) != path:
if os.path.basename(path).startswith('Twisted'):
sys.path.insert(0, path)
break
path = os.path.dirname(path)
### end of preamble
from twisted.mail.scripts import mailmail
mailmail.run()

View File

@@ -1,21 +0,0 @@
#!/usr/bin/env python
# Copyright (c) 2001-2009 Twisted Matrix Laboratories.
# See LICENSE for details.
"""
This script runs GtkManhole, a client for Twisted.Manhole
"""
### Twisted Preamble
# This makes sure that users don't have to set up their environment
# specially in order to run these programs from bin/.
import sys, os, string
if string.find(os.path.abspath(sys.argv[0]), os.sep+'Twisted') != -1:
sys.path.insert(0, os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]), os.pardir, os.pardir)))
### end of preamble
from twisted.scripts import manhole
manhole.run()

View File

@@ -1,18 +0,0 @@
#!/usr/bin/env python
# Copyright (c) 2001-2009 Twisted Matrix Laboratories.
# See LICENSE for details.
### Twisted Preamble
# This makes sure that users don't have to set up their environment
# specially in order to run these programs from bin/.
import sys, os, string
if string.find(os.path.abspath(sys.argv[0]), os.sep+'Twisted') != -1:
sys.path.insert(0, os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]), os.pardir, os.pardir)))
if not hasattr(os, "getuid") or os.getuid() != 0:
sys.path.insert(0, os.getcwd())
### end of preamble
from twisted.scripts.mktap import run
run()

View File

@@ -1,17 +0,0 @@
#!/usr/bin/env python
# Copyright (c) 2001-2009 Twisted Matrix Laboratories.
# See LICENSE for details.
### Twisted Preamble
# This makes sure that users don't have to set up their environment
# specially in order to run these programs from bin/.
import sys, os, string
if string.find(os.path.abspath(sys.argv[0]), os.sep+'Twisted') != -1:
sys.path.insert(0, os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]), os.pardir, os.pardir)))
sys.path.insert(0, os.curdir)
### end of preamble
from twisted.scripts.htmlizer import run
run()

View File

@@ -1,20 +0,0 @@
#!/usr/bin/env python
# Copyright (c) 2001-2009 Twisted Matrix Laboratories.
# See LICENSE for details.
"""
tap2deb
"""
### Twisted Preamble
# This makes sure that users don't have to set up their environment
# specially in order to run these programs from bin/.
import sys, os, string
if string.find(os.path.abspath(sys.argv[0]), os.sep+'Twisted') != -1:
sys.path.insert(0, os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]), os.pardir, os.pardir)))
### end of preamble
from twisted.scripts import tap2deb
tap2deb.run()

View File

@@ -1,22 +0,0 @@
#!/usr/bin/env python
# Copyright (c) 2001-2009 Twisted Matrix Laboratories.
# See LICENSE for details.
# based off the tap2deb code
# tap2rpm built by Sean Reifschneider, <jafo@tummy.com>
"""
tap2rpm
"""
### Twisted Preamble
# This makes sure that users don't have to set up their environment
# specially in order to run these programs from bin/.
import sys, os, string
if string.find(os.path.abspath(sys.argv[0]), os.sep+'Twisted') != -1:
sys.path.insert(0, os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]), os.pardir, os.pardir)))
### end of preamble
from twisted.scripts import tap2rpm
tap2rpm.run()

View File

@@ -1,18 +0,0 @@
#!/usr/bin/env python
# Copyright (c) 2001-2009 Twisted Matrix Laboratories.
# See LICENSE for details.
### Twisted Preamble
# This makes sure that users don't have to set up their environment
# specially in order to run these programs from bin/.
import sys, os, string
if string.find(os.path.abspath(sys.argv[0]), os.sep+'Twisted') != -1:
sys.path.insert(0, os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]), os.pardir, os.pardir)))
if not hasattr(os, "getuid") or os.getuid() != 0:
sys.path.insert(0, os.getcwd())
### end of preamble
from twisted.scripts.tapconvert import run
run()

View File

@@ -1,22 +0,0 @@
#!/usr/bin/env python
# Copyright (c) 2001-2009 Twisted Matrix Laboratories.
# See LICENSE for details.
### Twisted Preamble
# This makes sure that users don't have to set up their environment
# specially in order to run these programs from bin/.
import sys, os, string
if string.find(os.path.abspath(sys.argv[0]), os.sep+'Twisted') != -1:
sys.path.insert(0, os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]), os.pardir, os.pardir)))
if hasattr(os, "getuid") and os.getuid() != 0:
sys.path.insert(0, os.curdir)
### end of preamble
# begin chdir armor
sys.path[:] = map(os.path.abspath, sys.path)
# end chdir armor
from twisted.scripts.trial import run
run()

View File

@@ -1,19 +0,0 @@
#!/usr/bin/env python
# Copyright (c) 2001-2009 Twisted Matrix Laboratories.
# See LICENSE for details.
### Twisted Preamble
# This makes sure that users don't have to set up their environment
# specially in order to run these programs from bin/.
import sys, os, string
if string.find(os.path.abspath(sys.argv[0]), os.sep+'Twisted') != -1:
sys.path.insert(0, os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]), os.pardir, os.pardir)))
if hasattr(os, "getuid") and os.getuid() != 0:
sys.path.insert(0, os.path.abspath(os.getcwd()))
### end of preamble
from twisted.scripts.twistd import run
run()

View File

@@ -1,15 +0,0 @@
This directory contains various simple programs intended to exercise various
features of Twisted Conch as a way to learn about and track their
performance characteristics. As there is currently no record of past
benchmark results, the tracking aspect of this is currently somewhat
fantastic. However, the intent is for this to change at some future point.
All (one) of the programs in this directory are currently intended to be
invoked directly and to report some timing information on standard out.
The following benchmarks are currently available:
buffering_mixin.py:
This deals with twisted.conch.mixin.BufferingMixin which provides
Nagle-like write coalescing for Protocol classes.

View File

@@ -1,182 +0,0 @@
# Copyright (c) 2006 Twisted Matrix Laboratories.
# See LICENSE for details.
"""
Benchmarks comparing the write performance of a "normal" Protocol instance
and an instance of a Protocol class which has had L{twisted.conch.mixin}'s
L{BufferingMixin<twisted.conch.mixin.BufferingMixin>} mixed in to perform
Nagle-like write coalescing.
"""
from sys import stdout
from pprint import pprint
from time import time
from twisted.python.usage import Options
from twisted.python.log import startLogging
from twisted.internet.protocol import ServerFactory, Protocol, ClientCreator
from twisted.internet.defer import Deferred
from twisted.internet import reactor
from twisted.conch.mixin import BufferingMixin
class BufferingBenchmark(Options):
"""
Options for configuring the execution parameters of a benchmark run.
"""
optParameters = [
('scale', 's', '1',
'Work multiplier (bigger takes longer, might resist noise better)')]
def postOptions(self):
self['scale'] = int(self['scale'])
class ServerProtocol(Protocol):
"""
A silent protocol which only waits for a particular amount of input and
then fires a Deferred.
"""
def __init__(self, expected, finished):
self.expected = expected
self.finished = finished
def dataReceived(self, bytes):
self.expected -= len(bytes)
if self.expected == 0:
finished, self.finished = self.finished, None
finished.callback(None)
class BufferingProtocol(Protocol, BufferingMixin):
"""
A protocol which uses the buffering mixin to provide a write method.
"""
class UnbufferingProtocol(Protocol):
"""
A protocol which provides a naive write method which simply passes through
to the transport.
"""
def connectionMade(self):
"""
Bind write to the transport's write method and flush to a no-op
function in order to provide the same API as is provided by
BufferingProtocol.
"""
self.write = self.transport.write
self.flush = lambda: None
def _write(proto, byteCount):
write = proto.write
flush = proto.flush
for i in range(byteCount):
write('x')
flush()
def _benchmark(byteCount, clientProtocol):
result = {}
finished = Deferred()
def cbFinished(ignored):
result[u'disconnected'] = time()
result[u'duration'] = result[u'disconnected'] - result[u'connected']
return result
finished.addCallback(cbFinished)
f = ServerFactory()
f.protocol = lambda: ServerProtocol(byteCount, finished)
server = reactor.listenTCP(0, f)
f2 = ClientCreator(reactor, clientProtocol)
proto = f2.connectTCP('127.0.0.1', server.getHost().port)
def connected(proto):
result[u'connected'] = time()
return proto
proto.addCallback(connected)
proto.addCallback(_write, byteCount)
return finished
def _benchmarkBuffered(byteCount):
return _benchmark(byteCount, BufferingProtocol)
def _benchmarkUnbuffered(byteCount):
return _benchmark(byteCount, UnbufferingProtocol)
def benchmark(scale=1):
"""
Benchmark and return information regarding the relative performance of a
protocol which does not use the buffering mixin and a protocol which
does.
@type scale: C{int}
@param scale: A multipler to the amount of work to perform
@return: A Deferred which will fire with a dictionary mapping each of
the two unicode strings C{u'buffered'} and C{u'unbuffered'} to
dictionaries describing the performance of a protocol of each type.
These value dictionaries will map the unicode strings C{u'connected'}
and C{u'disconnected'} to the times at which each of those events
occurred and C{u'duration'} two the difference between these two values.
"""
overallResult = {}
byteCount = 1024
bufferedDeferred = _benchmarkBuffered(byteCount * scale)
def didBuffered(bufferedResult):
overallResult[u'buffered'] = bufferedResult
unbufferedDeferred = _benchmarkUnbuffered(byteCount * scale)
def didUnbuffered(unbufferedResult):
overallResult[u'unbuffered'] = unbufferedResult
return overallResult
unbufferedDeferred.addCallback(didUnbuffered)
return unbufferedDeferred
bufferedDeferred.addCallback(didBuffered)
return bufferedDeferred
def main(args=None):
"""
Perform a single benchmark run, starting and stopping the reactor and
logging system as necessary.
"""
startLogging(stdout)
options = BufferingBenchmark()
options.parseOptions(args)
d = benchmark(options['scale'])
def cbBenchmark(result):
pprint(result)
def ebBenchmark(err):
print err.getTraceback()
d.addCallbacks(cbBenchmark, ebBenchmark)
def stopReactor(ign):
reactor.stop()
d.addBoth(stopReactor)
reactor.run()
if __name__ == '__main__':
main()

View File

@@ -1,25 +0,0 @@
# Copyright (c) 2001-2004 Twisted Matrix Laboratories.
# See LICENSE for details.
# You can run this .tac file directly with:
# twistd -ny demo.tac
"""Nearly pointless demonstration of the manhole interactive interpreter.
This does about the same thing as demo_manhole, but uses the tap
module's makeService method instead. The only interesting difference
is that in this version, the telnet server also requires
authentication.
Note, you will have to create a file named \"passwd\" and populate it
with credentials (in the format of passwd(5)) to use this demo.
"""
from twisted.application import service
application = service.Application("TAC Demo")
from twisted.conch import manhole_tap
manhole_tap.makeService({"telnetPort": "tcp:6023",
"sshPort": "tcp:6022",
"namespace": {"foo": "bar"},
"passwd": "passwd"}).setServiceParent(application)

View File

@@ -1,80 +0,0 @@
# Copyright (c) 2001-2004 Twisted Matrix Laboratories.
# See LICENSE for details.
# You can run this .tac file directly with:
# twistd -ny demo_draw.tac
"""A trivial drawing application.
Clients are allowed to connect and spew various characters out over
the terminal. Spacebar changes the drawing character, while the arrow
keys move the cursor.
"""
from twisted.conch.insults import insults
from twisted.conch.telnet import TelnetTransport, TelnetBootstrapProtocol
from twisted.conch.manhole_ssh import ConchFactory, TerminalRealm
from twisted.internet import protocol
from twisted.application import internet, service
from twisted.cred import checkers, portal
class Draw(insults.TerminalProtocol):
"""Protocol which accepts arrow key and spacebar input and places
the requested characters onto the terminal.
"""
cursors = list('!@#$%^&*()_+-=')
def connectionMade(self):
self.terminal.eraseDisplay()
self.terminal.resetModes([insults.IRM])
self.cursor = self.cursors[0]
def keystrokeReceived(self, keyID, modifier):
if keyID == self.terminal.UP_ARROW:
self.terminal.cursorUp()
elif keyID == self.terminal.DOWN_ARROW:
self.terminal.cursorDown()
elif keyID == self.terminal.LEFT_ARROW:
self.terminal.cursorBackward()
elif keyID == self.terminal.RIGHT_ARROW:
self.terminal.cursorForward()
elif keyID == ' ':
self.cursor = self.cursors[(self.cursors.index(self.cursor) + 1) % len(self.cursors)]
else:
return
self.terminal.write(self.cursor)
self.terminal.cursorBackward()
def makeService(args):
checker = checkers.InMemoryUsernamePasswordDatabaseDontUse(username="password")
f = protocol.ServerFactory()
f.protocol = lambda: TelnetTransport(TelnetBootstrapProtocol,
insults.ServerProtocol,
args['protocolFactory'],
*args.get('protocolArgs', ()),
**args.get('protocolKwArgs', {}))
tsvc = internet.TCPServer(args['telnet'], f)
def chainProtocolFactory():
return insults.ServerProtocol(
args['protocolFactory'],
*args.get('protocolArgs', ()),
**args.get('protocolKwArgs', {}))
rlm = TerminalRealm()
rlm.chainedProtocolFactory = chainProtocolFactory
ptl = portal.Portal(rlm, [checker])
f = ConchFactory(ptl)
csvc = internet.TCPServer(args['ssh'], f)
m = service.MultiService()
tsvc.setServiceParent(m)
csvc.setServiceParent(m)
return m
application = service.Application("Insults Demo App")
makeService({'protocolFactory': Draw,
'telnet': 6023,
'ssh': 6022}).setServiceParent(application)

View File

@@ -1,252 +0,0 @@
# Copyright (c) 2001-2004 Twisted Matrix Laboratories.
# See LICENSE for details.
# You can run this .tac file directly with:
# twistd -ny demo_insults.tac
"""Various simple terminal manipulations using the insults module.
This demo sets up two listening ports: one on 6022 which accepts ssh
connections; one on 6023 which accepts telnet connections. No login
for the telnet server is required; for the ssh server, \"username\" is
the username and \"password\" is the password.
The TerminalProtocol subclass defined here ignores most user input
(except to print it out to the server log) and spends the duration of
the connection drawing (the author's humble approximation of)
raindrops at random locations on the client's terminal. +, -, *, and
/ are respected and each adjusts an aspect of the timing of the
animation process.
"""
import random, string
from twisted.python import log
from twisted.internet import protocol, task
from twisted.application import internet, service
from twisted.cred import checkers, portal
from twisted.conch.insults import insults
from twisted.conch.telnet import TelnetTransport, TelnetBootstrapProtocol
from twisted.conch.manhole_ssh import ConchFactory, TerminalRealm
class DrawingFinished(Exception):
"""Sentinel exception, raised when no \"frames\" for a particular
\"animation\" remain to be drawn.
"""
class Drawable:
"""Representation of an animation.
Constructed with a protocol instance and a coordinate on the
screen, waits for invocations of iterate() at which point it
erases the previous frame of the animation and draws the next one,
using its protocol instance and always placing the upper left hand
corner of the frame at the given coordinates.
Frames are defined with draw_ prefixed methods. Erasure is
performed by erase_ prefixed methods.
"""
n = 0
def __init__(self, proto, col, line):
self.proto = proto
self.col = col
self.line = line
def drawLines(self, s):
lines = s.splitlines()
c = self.col
line = self.line
for l in lines:
self.proto.cursorPosition(c - len(lines) / 2, line)
self.proto.write(l)
line += 1
def iterate(self):
getattr(self, 'erase_' + str(self.n))()
self.n += 1
f = getattr(self, 'draw_' + str(self.n), None)
if f is None:
raise DrawingFinished()
f()
def erase_0(self):
pass
class Splat(Drawable):
HEIGHT = 5
WIDTH = 11
def draw_1(self):
# . .
#. . .
# . .
self.drawLines(' . .\n. . .\n . .')
def erase_1(self):
self.drawLines(' \n \n ')
def draw_2(self):
# . . . .
# . o o o .
#. o o o o .
# . o o o .
# . . . .
self.drawLines(' . . . .\n . o o o .\n. o o o o .\n . o o o .\n . . . .')
def erase_2(self):
self.drawLines(' \n \n \n \n ')
def draw_3(self):
# o o o o
# o O O O o
#o O O O O o
# o O O O o
# o o o o
self.drawLines(' o o o o\n o O O O o\no O O O O o\n o O O O o\n o o o o')
erase_3 = erase_2
def draw_4(self):
# O O O O
# O . . . O
#O . . . . O
# O . . . O
# O O O O
self.drawLines(' O O O O\n O . . . O\nO . . . . O\n O . . . O\n O O O O')
erase_4 = erase_3
def draw_5(self):
# . . . .
# . .
#. .
# . .
# . . . .
self.drawLines(' . . . .\n . .\n. .\n . .\n . . . .')
erase_5 = erase_4
class Drop(Drawable):
WIDTH = 3
HEIGHT = 4
def draw_1(self):
# o
self.drawLines(' o')
def erase_1(self):
self.drawLines(' ')
def draw_2(self):
# _
#/ \
#\./
self.drawLines(' _ \n/ \\\n\\./')
def erase_2(self):
self.drawLines(' \n \n ')
def draw_3(self):
# O
self.drawLines(' O')
def erase_3(self):
self.drawLines(' ')
class DemoProtocol(insults.TerminalProtocol):
"""Draws random things at random places on the screen.
"""
width = 80
height = 24
interval = 0.1
rate = 0.05
def connectionMade(self):
self.run()
def connectionLost(self, reason):
self._call.stop()
del self._call
def run(self):
# Clear the screen, matey
self.terminal.eraseDisplay()
self._call = task.LoopingCall(self._iterate)
self._call.start(self.interval)
def _iterate(self):
cls = random.choice((Splat, Drop))
# Move to a random location on the screen
col = random.randrange(self.width - cls.WIDTH) + cls.WIDTH
line = random.randrange(self.height - cls.HEIGHT) + cls.HEIGHT
s = cls(self.terminal, col, line)
c = task.LoopingCall(s.iterate)
c.start(self.rate).addErrback(lambda f: f.trap(DrawingFinished)).addErrback(log.err)
# ITerminalListener
def terminalSize(self, width, height):
self.width = width
self.height = height
def unhandledControlSequence(self, seq):
log.msg("Client sent something weird: %r" % (seq,))
def keystrokeReceived(self, keyID, modifier):
if keyID == '+':
self.interval /= 1.1
elif keyID == '-':
self.interval *= 1.1
elif keyID == '*':
self.rate /= 1.1
elif keyID == '/':
self.rate *= 1.1
else:
log.msg("Client sent: %r" % (keyID,))
return
self._call.stop()
self._call = task.LoopingCall(self._iterate)
self._call.start(self.interval)
def makeService(args):
checker = checkers.InMemoryUsernamePasswordDatabaseDontUse(username="password")
f = protocol.ServerFactory()
f.protocol = lambda: TelnetTransport(TelnetBootstrapProtocol,
insults.ServerProtocol,
args['protocolFactory'],
*args.get('protocolArgs', ()),
**args.get('protocolKwArgs', {}))
tsvc = internet.TCPServer(args['telnet'], f)
def chainProtocolFactory():
return insults.ServerProtocol(
args['protocolFactory'],
*args.get('protocolArgs', ()),
**args.get('protocolKwArgs', {}))
rlm = TerminalRealm()
rlm.chainedProtocolFactory = chainProtocolFactory
ptl = portal.Portal(rlm, [checker])
f = ConchFactory(ptl)
csvc = internet.TCPServer(args['ssh'], f)
m = service.MultiService()
tsvc.setServiceParent(m)
csvc.setServiceParent(m)
return m
application = service.Application("Insults Demo App")
makeService({'protocolFactory': DemoProtocol,
'telnet': 6023,
'ssh': 6022}).setServiceParent(application)

View File

@@ -1,56 +0,0 @@
# Copyright (c) 2001-2004 Twisted Matrix Laboratories.
# See LICENSE for details.
# You can run this .tac file directly with:
# twistd -ny demo_manhole.tac
"""An interactive Python interpreter with syntax coloring.
Nothing interesting is actually defined here. Two listening ports are
set up and attached to protocols which know how to properly set up a
ColoredManhole instance.
"""
from twisted.conch.manhole import ColoredManhole
from twisted.conch.insults import insults
from twisted.conch.telnet import TelnetTransport, TelnetBootstrapProtocol
from twisted.conch.manhole_ssh import ConchFactory, TerminalRealm
from twisted.internet import protocol
from twisted.application import internet, service
from twisted.cred import checkers, portal
def makeService(args):
checker = checkers.InMemoryUsernamePasswordDatabaseDontUse(username="password")
f = protocol.ServerFactory()
f.protocol = lambda: TelnetTransport(TelnetBootstrapProtocol,
insults.ServerProtocol,
args['protocolFactory'],
*args.get('protocolArgs', ()),
**args.get('protocolKwArgs', {}))
tsvc = internet.TCPServer(args['telnet'], f)
def chainProtocolFactory():
return insults.ServerProtocol(
args['protocolFactory'],
*args.get('protocolArgs', ()),
**args.get('protocolKwArgs', {}))
rlm = TerminalRealm()
rlm.chainedProtocolFactory = chainProtocolFactory
ptl = portal.Portal(rlm, [checker])
f = ConchFactory(ptl)
csvc = internet.TCPServer(args['ssh'], f)
m = service.MultiService()
tsvc.setServiceParent(m)
csvc.setServiceParent(m)
return m
application = service.Application("Interactive Python Interpreter")
makeService({'protocolFactory': ColoredManhole,
'protocolArgs': (None,),
'telnet': 6023,
'ssh': 6022}).setServiceParent(application)

View File

@@ -1,77 +0,0 @@
# Copyright (c) 2001-2004 Twisted Matrix Laboratories.
# See LICENSE for details.
# You can run this .tac file directly with:
# twistd -ny demo_recvline.tac
"""Demonstrates line-at-a-time handling with basic line-editing support.
This is a variation on the echo server. It sets up two listening
ports: one on 6022 which accepts ssh connections; one on 6023 which
accepts telnet connections. No login for the telnet server is
required; for the ssh server, \"username\" is the username and
\"password\" is the password.
The demo protocol defined in this module is handed a line of input at
a time, which it simply writes back to the connection.
HistoricRecvline, which the demo protocol subclasses, provides basic
line editing and input history features.
"""
from twisted.conch import recvline
from twisted.conch.insults import insults
from twisted.conch.telnet import TelnetTransport, TelnetBootstrapProtocol
from twisted.conch.manhole_ssh import ConchFactory, TerminalRealm
from twisted.internet import protocol
from twisted.application import internet, service
from twisted.cred import checkers, portal
class DemoRecvLine(recvline.HistoricRecvLine):
"""Simple echo protocol.
Accepts lines of input and writes them back to its connection. If
a line consisting solely of \"quit\" is received, the connection
is dropped.
"""
def lineReceived(self, line):
if line == "quit":
self.terminal.loseConnection()
self.terminal.write(line)
self.terminal.nextLine()
self.terminal.write(self.ps[self.pn])
def makeService(args):
checker = checkers.InMemoryUsernamePasswordDatabaseDontUse(username="password")
f = protocol.ServerFactory()
f.protocol = lambda: TelnetTransport(TelnetBootstrapProtocol,
insults.ServerProtocol,
args['protocolFactory'],
*args.get('protocolArgs', ()),
**args.get('protocolKwArgs', {}))
tsvc = internet.TCPServer(args['telnet'], f)
def chainProtocolFactory():
return insults.ServerProtocol(
args['protocolFactory'],
*args.get('protocolArgs', ()),
**args.get('protocolKwArgs', {}))
rlm = TerminalRealm()
rlm.chainedProtocolFactory = chainProtocolFactory
ptl = portal.Portal(rlm, [checker])
f = ConchFactory(ptl)
csvc = internet.TCPServer(args['ssh'], f)
m = service.MultiService()
tsvc.setServiceParent(m)
csvc.setServiceParent(m)
return m
application = service.Application("Insults RecvLine Demo")
makeService({'protocolFactory': DemoRecvLine,
'telnet': 6023,
'ssh': 6022}).setServiceParent(application)

View File

@@ -1,100 +0,0 @@
# Copyright (c) 2001-2004 Twisted Matrix Laboratories.
# See LICENSE for details.
# You can run this .tac file directly with:
# twistd -ny demo_scroll.tac
"""Simple echo-ish server that uses the scroll-region.
This demo sets up two listening ports: one on 6022 which accepts ssh
connections; one on 6023 which accepts telnet connections. No login
for the telnet server is required; for the ssh server, \"username\" is
the username and \"password\" is the password.
The TerminalProtocol subclass defined here sets up a scroll-region occupying
most of the screen. It positions the cursor at the bottom of the screen and
then echos back printable input. When return is received, the line is
copied to the upper area of the screen (scrolling anything older up) and
clears the input line.
"""
import string
from twisted.python import log
from twisted.internet import protocol
from twisted.application import internet, service
from twisted.cred import checkers, portal
from twisted.conch.insults import insults
from twisted.conch.telnet import TelnetTransport, TelnetBootstrapProtocol
from twisted.conch.manhole_ssh import ConchFactory, TerminalRealm
class DemoProtocol(insults.TerminalProtocol):
"""Copies input to an upwards scrolling region.
"""
width = 80
height = 24
def connectionMade(self):
self.buffer = []
self.terminalSize(self.width, self.height)
# ITerminalListener
def terminalSize(self, width, height):
self.width = width
self.height = height
self.terminal.setScrollRegion(0, height - 1)
self.terminal.cursorPosition(0, height)
self.terminal.write('> ')
def unhandledControlSequence(self, seq):
log.msg("Client sent something weird: %r" % (seq,))
def keystrokeReceived(self, keyID, modifier):
if keyID == '\r':
self.terminal.cursorPosition(0, self.height - 2)
self.terminal.nextLine()
self.terminal.write(''.join(self.buffer))
self.terminal.cursorPosition(0, self.height - 1)
self.terminal.eraseToLineEnd()
self.terminal.write('> ')
self.buffer = []
elif keyID in list(string.printable):
self.terminal.write(keyID)
self.buffer.append(keyID)
def makeService(args):
checker = checkers.InMemoryUsernamePasswordDatabaseDontUse(username="password")
f = protocol.ServerFactory()
f.protocol = lambda: TelnetTransport(TelnetBootstrapProtocol,
insults.ServerProtocol,
args['protocolFactory'],
*args.get('protocolArgs', ()),
**args.get('protocolKwArgs', {}))
tsvc = internet.TCPServer(args['telnet'], f)
def chainProtocolFactory():
return insults.ServerProtocol(
args['protocolFactory'],
*args.get('protocolArgs', ()),
**args.get('protocolKwArgs', {}))
rlm = TerminalRealm()
rlm.chainedProtocolFactory = chainProtocolFactory
ptl = portal.Portal(rlm, [checker])
f = ConchFactory(ptl)
csvc = internet.TCPServer(args['ssh'], f)
m = service.MultiService()
tsvc.setServiceParent(m)
csvc.setServiceParent(m)
return m
application = service.Application("Scroll Region Demo App")
makeService({'protocolFactory': DemoProtocol,
'telnet': 6023,
'ssh': 6022}).setServiceParent(application)

View File

@@ -1,40 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Twisted Documentation: Twisted.Conch code examples</title>
<link href="../howto/stylesheet.css" rel="stylesheet" type="text/css"/>
</head>
<body bgcolor="white">
<h1 class="title">Twisted.Conch code examples</h1>
<div class="toc"><ol><li><a href="#auto0">Simple SSH server and client</a></li><li><a href="#auto1">Simple telnet server</a></li><li><a href="#auto2">twisted.conch.insults examples</a></li></ol></div>
<div class="content">
<span/>
<h2>Simple SSH server and client<a name="auto0"/></h2>
<ul>
<li><a href="sshsimpleclient.py" shape="rect">sshsimpleclient.py</a></li>
<li><a href="sshsimpleserver.py" shape="rect">sshsimpleserver.py</a></li>
</ul>
<h2>Simple telnet server<a name="auto1"/></h2>
<ul>
<li><a href="telnet_echo.tac" shape="rect">A telnet server which echoes data and events back to the client</a></li>
</ul>
<h2>twisted.conch.insults examples<a name="auto2"/></h2>
<ul>
<li><a href="demo.tac" shape="rect">demo.tac</a> Nearly pointless demonstration of the manhole interactive interpreter</li>
<li><a href="demo_draw.tac" shape="rect">demo_draw.tac</a> A trivial drawing application</li>
<li><a href="demo_insults.tac" shape="rect">demo_insults.tac</a> Various simple terminal manipulations using the insults module</li>
<li><a href="demo_recvline.tac" shape="rect">demo_recvline.tac</a> Demonstrates line-at-a-time handling with basic line-editing support</li>
<li><a href="demo_scroll.tac" shape="rect">demo_scroll.tac</a> Simple echo-ish server that uses the scroll-region</li>
<li><a href="demo_manhole.tac" shape="rect">demo_manhole.tac</a> An interactive Python interpreter with syntax coloring</li>
<li><a href="window.tac" shape="rect">window.tac</a> An example of various widgets</li>
</ul>
</div>
<p><a href="../howto/index.html">Index</a></p>
<span class="version">Version: 10.0.0</span>
</body>
</html>

View File

@@ -1,111 +0,0 @@
#!/usr/bin/env python
# Copyright (c) 2009 Twisted Matrix Laboratories.
# See LICENSE for details.
from twisted.conch.ssh import transport, userauth, connection, common, keys, channel
from twisted.internet import defer, protocol, reactor
from twisted.python import log
import struct, sys, getpass, os
USER = 'z3p' # replace this with a valid username
HOST = 'localhost' # and a valid host
class SimpleTransport(transport.SSHClientTransport):
def verifyHostKey(self, hostKey, fingerprint):
print 'host key fingerprint: %s' % fingerprint
return defer.succeed(1)
def connectionSecure(self):
self.requestService(
SimpleUserAuth(USER,
SimpleConnection()))
class SimpleUserAuth(userauth.SSHUserAuthClient):
def getPassword(self):
return defer.succeed(getpass.getpass("%s@%s's password: " % (USER, HOST)))
def getGenericAnswers(self, name, instruction, questions):
print name
print instruction
answers = []
for prompt, echo in questions:
if echo:
answer = raw_input(prompt)
else:
answer = getpass.getpass(prompt)
answers.append(answer)
return defer.succeed(answers)
def getPublicKey(self):
path = os.path.expanduser('~/.ssh/id_dsa')
# this works with rsa too
# just change the name here and in getPrivateKey
if not os.path.exists(path) or self.lastPublicKey:
# the file doesn't exist, or we've tried a public key
return
return keys.getPublicKeyString(path+'.pub')
def getPrivateKey(self):
path = os.path.expanduser('~/.ssh/id_dsa')
return defer.succeed(keys.getPrivateKeyObject(path))
class SimpleConnection(connection.SSHConnection):
def serviceStarted(self):
self.openChannel(TrueChannel(2**16, 2**15, self))
self.openChannel(FalseChannel(2**16, 2**15, self))
self.openChannel(CatChannel(2**16, 2**15, self))
class TrueChannel(channel.SSHChannel):
name = 'session' # needed for commands
def openFailed(self, reason):
print 'true failed', reason
def channelOpen(self, ignoredData):
self.conn.sendRequest(self, 'exec', common.NS('true'))
def request_exit_status(self, data):
status = struct.unpack('>L', data)[0]
print 'true status was: %s' % status
self.loseConnection()
class FalseChannel(channel.SSHChannel):
name = 'session'
def openFailed(self, reason):
print 'false failed', reason
def channelOpen(self, ignoredData):
self.conn.sendRequest(self, 'exec', common.NS('false'))
def request_exit_status(self, data):
status = struct.unpack('>L', data)[0]
print 'false status was: %s' % status
self.loseConnection()
class CatChannel(channel.SSHChannel):
name = 'session'
def openFailed(self, reason):
print 'echo failed', reason
def channelOpen(self, ignoredData):
self.data = ''
d = self.conn.sendRequest(self, 'exec', common.NS('cat'), wantReply = 1)
d.addCallback(self._cbRequest)
def _cbRequest(self, ignored):
self.write('hello conch\n')
self.conn.sendEOF(self)
def dataReceived(self, data):
self.data += data
def closed(self):
print 'got data from cat: %s' % repr(self.data)
self.loseConnection()
reactor.stop()
protocol.ClientCreator(reactor, SimpleTransport).connectTCP(HOST, 22)
reactor.run()

View File

@@ -1,117 +0,0 @@
#!/usr/bin/env python
# Copyright (c) 2009 Twisted Matrix Laboratories.
# See LICENSE for details.
from twisted.cred import portal, checkers
from twisted.conch import error, avatar
from twisted.conch.checkers import SSHPublicKeyDatabase
from twisted.conch.ssh import factory, userauth, connection, keys, session
from twisted.internet import reactor, protocol, defer
from twisted.python import log
from zope.interface import implements
import sys
log.startLogging(sys.stderr)
"""
Example of running another protocol over an SSH channel.
log in with username "user" and password "password".
"""
class ExampleAvatar(avatar.ConchUser):
def __init__(self, username):
avatar.ConchUser.__init__(self)
self.username = username
self.channelLookup.update({'session':session.SSHSession})
class ExampleRealm:
implements(portal.IRealm)
def requestAvatar(self, avatarId, mind, *interfaces):
return interfaces[0], ExampleAvatar(avatarId), lambda: None
class EchoProtocol(protocol.Protocol):
"""this is our example protocol that we will run over SSH
"""
def dataReceived(self, data):
if data == '\r':
data = '\r\n'
elif data == '\x03': #^C
self.transport.loseConnection()
return
self.transport.write(data)
publicKey = 'ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAGEArzJx8OYOnJmzf4tfBEvLi8DVPrJ3/c9k2I/Az64fxjHf9imyRJbixtQhlH9lfNjUIx+4LmrJH5QNRsFporcHDKOTwTTYLh5KmRpslkYHRivcJSkbh/C+BR3utDS555mV'
privateKey = """-----BEGIN RSA PRIVATE KEY-----
MIIByAIBAAJhAK8ycfDmDpyZs3+LXwRLy4vA1T6yd/3PZNiPwM+uH8Yx3/YpskSW
4sbUIZR/ZXzY1CMfuC5qyR+UDUbBaaK3Bwyjk8E02C4eSpkabJZGB0Yr3CUpG4fw
vgUd7rQ0ueeZlQIBIwJgbh+1VZfr7WftK5lu7MHtqE1S1vPWZQYE3+VUn8yJADyb
Z4fsZaCrzW9lkIqXkE3GIY+ojdhZhkO1gbG0118sIgphwSWKRxK0mvh6ERxKqIt1
xJEJO74EykXZV4oNJ8sjAjEA3J9r2ZghVhGN6V8DnQrTk24Td0E8hU8AcP0FVP+8
PQm/g/aXf2QQkQT+omdHVEJrAjEAy0pL0EBH6EVS98evDCBtQw22OZT52qXlAwZ2
gyTriKFVoqjeEjt3SZKKqXHSApP/AjBLpF99zcJJZRq2abgYlf9lv1chkrWqDHUu
DZttmYJeEfiFBBavVYIF1dOlZT0G8jMCMBc7sOSZodFnAiryP+Qg9otSBjJ3bQML
pSTqy7c3a2AScC/YyOwkDaICHnnD3XyjMwIxALRzl0tQEKMXs6hH8ToUdlLROCrP
EhQ0wahUTCk1gKA4uPD6TMTChavbh4K63OvbKg==
-----END RSA PRIVATE KEY-----"""
class InMemoryPublicKeyChecker(SSHPublicKeyDatabase):
def checkKey(self, credentials):
return credentials.username == 'user' and \
keys.getPublicKeyString(data=publicKey) == credentials.blob
class ExampleSession:
def __init__(self, avatar):
"""
We don't use it, but the adapter is passed the avatar as its first
argument.
"""
def getPty(self, term, windowSize, attrs):
pass
def execCommand(self, proto, cmd):
raise Exception("no executing commands")
def openShell(self, trans):
ep = EchoProtocol()
ep.makeConnection(trans)
trans.makeConnection(session.wrapProtocol(ep))
def eofReceived(self):
pass
def closed(self):
pass
from twisted.python import components
components.registerAdapter(ExampleSession, ExampleAvatar, session.ISession)
class ExampleFactory(factory.SSHFactory):
publicKeys = {
'ssh-rsa': keys.Key.fromString(data=publicKey)
}
privateKeys = {
'ssh-rsa': keys.Key.fromString(data=privateKey)
}
services = {
'ssh-userauth': userauth.SSHUserAuthServer,
'ssh-connection': connection.SSHConnection
}
portal = portal.Portal(ExampleRealm())
passwdDB = checkers.InMemoryUsernamePasswordDatabaseDontUse()
passwdDB.addUser('user', 'password')
portal.registerChecker(passwdDB)
portal.registerChecker(InMemoryPublicKeyChecker())
ExampleFactory.portal = portal
if __name__ == '__main__':
reactor.listenTCP(5022, ExampleFactory())
reactor.run()

View File

@@ -1,37 +0,0 @@
# Copyright (c) 2009 Twisted Matrix Laboratories.
# See LICENSE for details.
from twisted.conch.telnet import TelnetTransport, TelnetProtocol
from twisted.internet.protocol import ServerFactory
from twisted.application.internet import TCPServer
from twisted.application.service import Application
class TelnetEcho(TelnetProtocol):
def enableRemote(self, option):
self.transport.write("You tried to enable %r (I rejected it)\r\n" % (option,))
return False
def disableRemote(self, option):
self.transport.write("You disabled %r\r\n" % (option,))
def enableLocal(self, option):
self.transport.write("You tried to make me enable %r (I rejected it)\r\n" % (option,))
return False
def disableLocal(self, option):
self.transport.write("You asked me to disable %r\r\n" % (option,))
def dataReceived(self, data):
self.transport.write("I received %r from you\r\n" % (data,))
factory = ServerFactory()
factory.protocol = lambda: TelnetTransport(TelnetEcho)
service = TCPServer(8023, factory)
application = Application("Telnet Echo Server")
service.setServiceParent(application)

View File

@@ -1,190 +0,0 @@
# Copyright (c) 2001-2008 Twisted Matrix Laboratories.
# See LICENSE for details.
# You can run this .tac file directly with:
# twistd -ny window.tac
from __future__ import division
import string, random
from twisted.python import log
from twisted.internet import protocol, task
from twisted.application import internet, service
from twisted.cred import checkers, portal
from twisted.conch.insults import insults, window
from twisted.conch.telnet import TelnetTransport, TelnetBootstrapProtocol
from twisted.conch.manhole_ssh import ConchFactory, TerminalRealm
from twisted.internet import reactor
class DrawableCanvas(window.Canvas):
x = 0
y = 0
def func_LEFT_ARROW(self, modifier):
self.x -= 1
self.repaint()
def func_RIGHT_ARROW(self, modifier):
self.x += 1
self.repaint()
def func_UP_ARROW(self, modifier):
self.y -= 1
self.repaint()
def func_DOWN_ARROW(self, modifier):
self.y += 1
self.repaint()
def characterReceived(self, keyID, modifier):
self[self.x, self.y] = keyID
self.x += 1
self.repaint()
def keystrokeReceived(self, keyID, modifier):
if keyID == '\r' or keyID == '\v':
return
window.Canvas.keystrokeReceived(self, keyID, modifier)
if self.x >= self.width:
self.x = 0
elif self.x < 0:
self.x = self.width - 1
if self.y >= self.height:
self.y = 0
elif self.y < 0:
self.y = self.height - 1
self.repaint()
def render(self, width, height, terminal):
window.Canvas.render(self, width, height, terminal)
if self.focused:
terminal.cursorPosition(self.x, self.y)
window.cursor(terminal, self[self.x, self.y])
class ButtonDemo(insults.TerminalProtocol):
width = 80
height = 24
def _draw(self):
self.window.draw(self.width, self.height, self.terminal)
def _redraw(self):
self.window.filthy()
self._draw()
def _schedule(self, f):
reactor.callLater(0, f)
def connectionMade(self):
self.terminal.eraseDisplay()
self.terminal.resetPrivateModes([insults.privateModes.CURSOR_MODE])
self.window = window.TopWindow(self._draw, self._schedule)
self.output = window.TextOutput((15, 1))
self.input = window.TextInput(15, self._setText)
self.select1 = window.Selection(map(str, range(100)), self._setText, 10)
self.select2 = window.Selection(map(str, range(200, 300)), self._setText, 10)
self.button = window.Button("Clear", self._clear)
self.canvas = DrawableCanvas()
hbox = window.HBox()
hbox.addChild(self.input)
hbox.addChild(self.output)
hbox.addChild(window.Border(self.button))
hbox.addChild(window.Border(self.select1))
hbox.addChild(window.Border(self.select2))
t1 = window.TextOutputArea(longLines=window.TextOutputArea.WRAP)
t2 = window.TextOutputArea(longLines=window.TextOutputArea.TRUNCATE)
t3 = window.TextOutputArea(longLines=window.TextOutputArea.TRUNCATE)
t4 = window.TextOutputArea(longLines=window.TextOutputArea.TRUNCATE)
for _t in t1, t2, t3, t4:
_t.setText((('This is a very long string. ' * 3) + '\n') * 3)
vp = window.Viewport(t3)
d = [1]
def spin():
vp.xOffset += d[0]
if vp.xOffset == 0 or vp.xOffset == 25:
d[0] *= -1
self.call = task.LoopingCall(spin)
self.call.start(0.25, now=False)
hbox.addChild(window.Border(vp))
vp2 = window.ScrolledArea(t4)
hbox.addChild(vp2)
texts = window.VBox()
texts.addChild(window.Border(t1))
texts.addChild(window.Border(t2))
areas = window.HBox()
areas.addChild(window.Border(self.canvas))
areas.addChild(texts)
vbox = window.VBox()
vbox.addChild(hbox)
vbox.addChild(areas)
self.window.addChild(vbox)
self.terminalSize(self.width, self.height)
def connectionLost(self, reason):
self.call.stop()
insults.TerminalProtocol.connectionLost(self, reason)
def terminalSize(self, width, height):
self.width = width
self.height = height
self.terminal.eraseDisplay()
self._redraw()
def keystrokeReceived(self, keyID, modifier):
self.window.keystrokeReceived(keyID, modifier)
def _clear(self):
self.canvas.clear()
def _setText(self, text):
self.input.setText('')
self.output.setText(text)
def makeService(args):
checker = checkers.InMemoryUsernamePasswordDatabaseDontUse(username="password")
f = protocol.ServerFactory()
f.protocol = lambda: TelnetTransport(TelnetBootstrapProtocol,
insults.ServerProtocol,
args['protocolFactory'],
*args.get('protocolArgs', ()),
**args.get('protocolKwArgs', {}))
tsvc = internet.TCPServer(args['telnet'], f)
def chainProtocolFactory():
return insults.ServerProtocol(
args['protocolFactory'],
*args.get('protocolArgs', ()),
**args.get('protocolKwArgs', {}))
rlm = TerminalRealm()
rlm.chainedProtocolFactory = chainProtocolFactory
ptl = portal.Portal(rlm, [checker])
f = ConchFactory(ptl)
csvc = internet.TCPServer(args['ssh'], f)
m = service.MultiService()
tsvc.setServiceParent(m)
csvc.setServiceParent(m)
return m
application = service.Application("Window Demo")
makeService({'protocolFactory': ButtonDemo,
'telnet': 6023,
'ssh': 6022}).setServiceParent(application)

View File

@@ -1,318 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Twisted Documentation: Writing a client with Twisted.Conch</title>
<link href="stylesheet.css" rel="stylesheet" type="text/css"/>
</head>
<body bgcolor="white">
<h1 class="title">Writing a client with Twisted.Conch</h1>
<div class="toc"><ol><li><a href="#auto0">Introduction</a></li><li><a href="#auto1">Writing a client</a></li><li><a href="#auto2">The Transport</a></li><li><a href="#auto3">The Authorization Client</a></li><li><a href="#auto4">The Connection</a></li><li><a href="#auto5">The Channel</a></li><li><a href="#auto6">The main() function</a></li></ol></div>
<div class="content">
<span/>
<h2>Introduction<a name="auto0"/></h2>
<p>In the original days of computing, rsh/rlogin were used to connect to
remote computers and execute commands. These commands had the problem
that the passwords and commands were sent in the clear. To solve this
problem, the SSH protocol was created. Twisted.Conch implements the
second version of this protocol.</p>
<h2>Writing a client<a name="auto1"/></h2>
<p>Writing a client with Conch involves sub-classing 4 classes: <code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.conch.ssh.transport.SSHClientTransport.html" title="twisted.conch.ssh.transport.SSHClientTransport">twisted.conch.ssh.transport.SSHClientTransport</a></code>, <code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.conch.ssh.userauth.SSHUserAuthClient.html" title="twisted.conch.ssh.userauth.SSHUserAuthClient">twisted.conch.ssh.userauth.SSHUserAuthClient</a></code>, <code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.conch.ssh.connection.SSHConnection.html" title="twisted.conch.ssh.connection.SSHConnection">twisted.conch.ssh.connection.SSHConnection</a></code>, and <code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.conch.ssh.channel.SSHChannel.html" title="twisted.conch.ssh.channel.SSHChannel">twisted.conch.ssh.channel.SSHChannel</a></code>. We'll start out
with <code class="python">SSHClientTransport</code> because it's the base
of the client.</p>
<h2>The Transport<a name="auto2"/></h2>
<pre class="python"><p class="py-linenumber"> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">conch</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">error</span>
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">conch</span>.<span class="py-src-variable">ssh</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">transport</span>
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">defer</span>
<span class="py-src-keyword">class</span> <span class="py-src-identifier">ClientTransport</span>(<span class="py-src-parameter">transport</span>.<span class="py-src-parameter">SSHClientTransport</span>):
<span class="py-src-keyword">def</span> <span class="py-src-identifier">verifyHostKey</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">pubKey</span>, <span class="py-src-parameter">fingerprint</span>):
<span class="py-src-keyword">if</span> <span class="py-src-variable">fingerprint</span> != <span class="py-src-string">'b1:94:6a:c9:24:92:d2:34:7c:62:35:b4:d2:61:11:84'</span>:
<span class="py-src-keyword">return</span> <span class="py-src-variable">defer</span>.<span class="py-src-variable">fail</span>(<span class="py-src-variable">error</span>.<span class="py-src-variable">ConchError</span>(<span class="py-src-string">'bad key'</span>))
<span class="py-src-keyword">else</span>:
<span class="py-src-keyword">return</span> <span class="py-src-variable">defer</span>.<span class="py-src-variable">succeed</span>(<span class="py-src-number">1</span>)
<span class="py-src-keyword">def</span> <span class="py-src-identifier">connectionSecure</span>(<span class="py-src-parameter">self</span>):
<span class="py-src-variable">self</span>.<span class="py-src-variable">requestService</span>(<span class="py-src-variable">ClientUserAuth</span>(<span class="py-src-string">'user'</span>, <span class="py-src-variable">ClientConnection</span>()))
</pre>
<p>See how easy it is? <code class="python">SSHClientTransport</code>
handles the negotiation of encryption and the verification of keys
for you. The one security element that you as a client writer need to
implement is <code class="python">verifyHostKey()</code>. This method
is called with two strings: the public key sent by the server and its
fingerprint. You should verify the host key the server sends, either
by checking against a hard-coded value as in the example, or by asking
the user. <code class="python">verifyHostKey</code> returns a <code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.internet.defer.Deferred.html" title="twisted.internet.defer.Deferred">twisted.internet.defer.Deferred</a></code> which gets a callback
if the host key is valid, or an errback if it is not. Note that in the
above, replace 'user' with the username you're attempting to ssh with,
for instance a call to <code class="python">os.getlogin()</code> for the
current user.</p>
<p>The second method you need to implement is <code class="python">connectionSecure()</code>. It is called when the
encryption is set up and other services can be run. The example requests
that the <code class="python">ClientUserAuth</code> service be started.
This service will be discussed next.</p>
<h2>The Authorization Client<a name="auto3"/></h2>
<pre class="python"><p class="py-linenumber"> 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
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">conch</span>.<span class="py-src-variable">ssh</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">keys</span>, <span class="py-src-variable">userauth</span>
<span class="py-src-comment"># these are the public/private keys from test_conch</span>
<span class="py-src-variable">publicKey</span> = <span class="py-src-string">'ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAGEArzJx8OYOnJmzf4tfBEvLi8DVPrJ3\
/c9k2I/Az64fxjHf9imyRJbixtQhlH9lfNjUIx+4LmrJH5QNRsFporcHDKOTwTTYLh5KmRpslkYHR\
ivcJSkbh/C+BR3utDS555mV'</span>
<span class="py-src-variable">privateKey</span> = <span class="py-src-string">&quot;&quot;&quot;-----BEGIN RSA PRIVATE KEY-----
MIIByAIBAAJhAK8ycfDmDpyZs3+LXwRLy4vA1T6yd/3PZNiPwM+uH8Yx3/YpskSW
4sbUIZR/ZXzY1CMfuC5qyR+UDUbBaaK3Bwyjk8E02C4eSpkabJZGB0Yr3CUpG4fw
vgUd7rQ0ueeZlQIBIwJgbh+1VZfr7WftK5lu7MHtqE1S1vPWZQYE3+VUn8yJADyb
Z4fsZaCrzW9lkIqXkE3GIY+ojdhZhkO1gbG0118sIgphwSWKRxK0mvh6ERxKqIt1
xJEJO74EykXZV4oNJ8sjAjEA3J9r2ZghVhGN6V8DnQrTk24Td0E8hU8AcP0FVP+8
PQm/g/aXf2QQkQT+omdHVEJrAjEAy0pL0EBH6EVS98evDCBtQw22OZT52qXlAwZ2
gyTriKFVoqjeEjt3SZKKqXHSApP/AjBLpF99zcJJZRq2abgYlf9lv1chkrWqDHUu
DZttmYJeEfiFBBavVYIF1dOlZT0G8jMCMBc7sOSZodFnAiryP+Qg9otSBjJ3bQML
pSTqy7c3a2AScC/YyOwkDaICHnnD3XyjMwIxALRzl0tQEKMXs6hH8ToUdlLROCrP
EhQ0wahUTCk1gKA4uPD6TMTChavbh4K63OvbKg==
-----END RSA PRIVATE KEY-----&quot;&quot;&quot;</span>
<span class="py-src-keyword">class</span> <span class="py-src-identifier">ClientUserAuth</span>(<span class="py-src-parameter">userauth</span>.<span class="py-src-parameter">SSHUserAuthClient</span>):
<span class="py-src-keyword">def</span> <span class="py-src-identifier">getPassword</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">prompt</span> = <span class="py-src-parameter">None</span>):
<span class="py-src-keyword">return</span>
<span class="py-src-comment"># this says we won't do password authentication</span>
<span class="py-src-keyword">def</span> <span class="py-src-identifier">getPublicKey</span>(<span class="py-src-parameter">self</span>):
<span class="py-src-keyword">return</span> <span class="py-src-variable">keys</span>.<span class="py-src-variable">getPublicKeyString</span>(<span class="py-src-variable">data</span> = <span class="py-src-variable">publicKey</span>)
<span class="py-src-keyword">def</span> <span class="py-src-identifier">getPrivateKey</span>(<span class="py-src-parameter">self</span>):
<span class="py-src-keyword">return</span> <span class="py-src-variable">defer</span>.<span class="py-src-variable">succeed</span>(<span class="py-src-variable">keys</span>.<span class="py-src-variable">getPrivateKeyObject</span>(<span class="py-src-variable">data</span> = <span class="py-src-variable">privateKey</span>))
</pre>
<p>Again, fairly simple. The <code class="python">SSHUserAuthClient</code> takes care of most
of the work, but the actual authentication data needs to be
supplied. <code class="python">getPassword()</code> asks for a
password, <code class="python">getPublicKey()</code> and <code class="python">getPrivateKey()</code> get public and private keys,
respectively. <code class="python">getPassword()</code> returns
a <code class="python">Deferred</code> that is called back with
the password to use. <code class="python">getPublicKey()</code>
returns the SSH key data for the public key to use. <code class="python">keys.getPublicKeyString()</code> will take
keys in OpenSSH and LSH format, and convert them to the
required format. <code class="python">getPrivateKey()</code>
returns a <code class="python">Deferred</code> which is
called back with the key object (as used in PyCrypto) for
the private key. <code class="python">getPassword()</code>
and <code class="python">getPrivateKey()</code> return <code class="python">Deferreds</code> because they may need to ask the user
for input.</p>
<p>Once the authentication is complete, <code class="python">SSHUserAuthClient</code> takes care of starting the code
<code class="python">SSHConnection</code> object given to it. Next, we'll
look at how to use the <code class="python">SSHConnection</code></p>
<h2>The Connection<a name="auto4"/></h2>
<pre class="python"><p class="py-linenumber">1
2
3
4
5
6
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">conch</span>.<span class="py-src-variable">ssh</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">connection</span>
<span class="py-src-keyword">class</span> <span class="py-src-identifier">ClientConnection</span>(<span class="py-src-parameter">connection</span>.<span class="py-src-parameter">SSHConnection</span>):
<span class="py-src-keyword">def</span> <span class="py-src-identifier">serviceStarted</span>(<span class="py-src-parameter">self</span>):
<span class="py-src-variable">self</span>.<span class="py-src-variable">openChannel</span>(<span class="py-src-variable">CatChannel</span>(<span class="py-src-variable">conn</span> = <span class="py-src-variable">self</span>))
</pre>
<p><code class="python">SSHConnection</code> is the easiest,
as it's only responsible for starting the channels. It has
other methods, those will be examined when we look at <code class="python">SSHChannel</code>.</p>
<h2>The Channel<a name="auto5"/></h2>
<pre class="python"><p class="py-linenumber"> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">conch</span>.<span class="py-src-variable">ssh</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">channel</span>, <span class="py-src-variable">common</span>
<span class="py-src-keyword">class</span> <span class="py-src-identifier">CatChannel</span>(<span class="py-src-parameter">channel</span>.<span class="py-src-parameter">SSHChannel</span>):
<span class="py-src-variable">name</span> = <span class="py-src-string">'session'</span>
<span class="py-src-keyword">def</span> <span class="py-src-identifier">channelOpen</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">data</span>):
<span class="py-src-variable">d</span> = <span class="py-src-variable">self</span>.<span class="py-src-variable">conn</span>.<span class="py-src-variable">sendRequest</span>(<span class="py-src-variable">self</span>, <span class="py-src-string">'exec'</span>, <span class="py-src-variable">common</span>.<span class="py-src-variable">NS</span>(<span class="py-src-string">'cat'</span>),
<span class="py-src-variable">wantReply</span> = <span class="py-src-number">1</span>)
<span class="py-src-variable">d</span>.<span class="py-src-variable">addCallback</span>(<span class="py-src-variable">self</span>.<span class="py-src-variable">_cbSendRequest</span>)
<span class="py-src-variable">self</span>.<span class="py-src-variable">catData</span> = <span class="py-src-string">''</span>
<span class="py-src-keyword">def</span> <span class="py-src-identifier">_cbSendRequest</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">ignored</span>):
<span class="py-src-variable">self</span>.<span class="py-src-variable">write</span>(<span class="py-src-string">'This data will be echoed back to us by &quot;cat.&quot;\r\n'</span>)
<span class="py-src-variable">self</span>.<span class="py-src-variable">conn</span>.<span class="py-src-variable">sendEOF</span>(<span class="py-src-variable">self</span>)
<span class="py-src-variable">self</span>.<span class="py-src-variable">loseConnection</span>()
<span class="py-src-keyword">def</span> <span class="py-src-identifier">dataReceived</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">data</span>):
<span class="py-src-variable">self</span>.<span class="py-src-variable">catData</span> += <span class="py-src-variable">data</span>
<span class="py-src-keyword">def</span> <span class="py-src-identifier">closed</span>(<span class="py-src-parameter">self</span>):
<span class="py-src-keyword">print</span> <span class="py-src-string">'We got this from &quot;cat&quot;:'</span>, <span class="py-src-variable">self</span>.<span class="py-src-variable">catData</span>
</pre>
<p>Now that we've spent all this time getting the server and
client connected, here is where that work pays off. <code class="python">SSHChannel</code> is the interface between you and the
other side. This particular channel opens a session and plays with the
'cat' program, but your channel can implement anything, so long as the
server supports it.</p>
<p>The <code class="python">channelOpen()</code> method is
where everything gets started. It gets passed a chunk of data;
however, this chunk is usually nothing and can be ignored.
Our <code class="python">channelOpen()</code> initializes our
channel, and sends a request to the other side, using the
<code class="python">sendRequest()</code> method of the <code class="python">SSHConnection</code> object. Requests are used to send
events to the other side. We pass the method self so that it knows to
send the request for this channel. The 2nd argument of 'exec' tells the
server that we want to execute a command. The third argument is the data
that accompanies the request. <code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/common.NS.html" title="common.NS">common.NS</a></code> encodes
the data as a length-prefixed string, which is how the server expects
the data. We also say that we want a reply saying that the process has a
been started. <code class="python">sendRequest()</code> then returns a
<code class="python">Deferred</code> which we add a callback for.</p>
<p>Once the callback fires, we send the data. <code class="python">SSHChannel</code> supports the <code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/
.html" title="
">
twisted.internet.interface.Transport</a></code> interface, so
it can be given to Protocols to run them over the secure
connection. In our case, we just write the data directly. <code class="python">sendEOF()</code> does not follow the interface,
but Conch uses it to tell the other side that we will write no
more data. <code class="python">loseConnection()</code> shuts
down our side of the connection, but we will still receive data
through <code class="python">dataReceived()</code>. The <code class="python">closed()</code> method is called when both sides of the
connection are closed, and we use it to display the data we received
(which should be the same as the data we sent.)</p>
<p>Finally, let's actually invoke the code we've set up.</p>
<h2>The main() function<a name="auto6"/></h2>
<pre class="python"><p class="py-linenumber"> 1
2
3
4
5
6
7
8
9
10
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">protocol</span>, <span class="py-src-variable">reactor</span>
<span class="py-src-keyword">def</span> <span class="py-src-identifier">main</span>():
<span class="py-src-variable">factory</span> = <span class="py-src-variable">protocol</span>.<span class="py-src-variable">ClientFactory</span>()
<span class="py-src-variable">factory</span>.<span class="py-src-variable">protocol</span> = <span class="py-src-variable">ClientTransport</span>
<span class="py-src-variable">reactor</span>.<span class="py-src-variable">connectTCP</span>(<span class="py-src-string">'localhost'</span>, <span class="py-src-number">22</span>, <span class="py-src-variable">factory</span>)
<span class="py-src-variable">reactor</span>.<span class="py-src-variable">run</span>()
<span class="py-src-keyword">if</span> <span class="py-src-variable">__name__</span> == <span class="py-src-string">&quot;__main__&quot;</span>:
<span class="py-src-variable">main</span>()
</pre>
<P>We call <code class="python">connectTCP()</code> to connect to
localhost, port 22 (the standard port for ssh), and pass it an instance
of <code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.internet.protocol.ClientFactory.html" title="twisted.internet.protocol.ClientFactory">twisted.internet.protocol.ClientFactory</a></code>.
This instance has the attribute <code class="python">protocol</code>
set to our earlier <code class="python">ClientTransport</code>
class. Note that the protocol attribute is set to the class <code class="python">ClientTransport</code>, not an instance of
<code class="python">ClientTransport</code>! When the <code class="python">connectTCP</code> call completes, the protocol will be
called to create a <code class="python">ClientTransport()</code> object
- this then invokes all our previous work.</P>
<P>It's worth noting that in the example <code class="python">main()</code>
routine, the <code class="python">reactor.run()</code> call never returns.
If you want to make the program exit, call
<code class="python">reactor.stop()</code> in the earlier
<code class="python">closed()</code> method.</P>
<P>If you wish to observe the interactions in more detail, adding a call
to <code class="python">log.startLogging(sys.stdout, setStdout=0)</code>
before the <code class="python">reactor.run()</code> call will send all
logging to stdout.</P>
</div>
<p><a href="index.html">Index</a></p>
<span class="version">Version: 10.0.0</span>
</body>
</html>

View File

@@ -1,28 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Twisted Documentation: Twisted Documentation</title>
<link href="stylesheet.css" rel="stylesheet" type="text/css"/>
</head>
<body bgcolor="white">
<h1 class="title">Twisted Documentation</h1>
<div class="toc"><ol/></div>
<div class="content">
<span/>
<ul class="toc">
<li>Tutorial
<ul>
<li>
<a href="conch_client.html" shape="rect">Writing an SSH client with Conch</a>
</li>
</ul>
</li>
</ul>
</div>
<p><a href="index.html">Index</a></p>
<span class="version">Version: 10.0.0</span>
</body>
</html>

View File

@@ -1,25 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Twisted Documentation: Twisted Conch Documentation</title>
<link href="howto/stylesheet.css" rel="stylesheet" type="text/css"/>
</head>
<body bgcolor="white">
<h1 class="title">Twisted Conch Documentation</h1>
<div class="toc"><ol/></div>
<div class="content">
<span/>
<ul>
<li><a href="howto/index.html" shape="rect">Developer guides</a>: documentation on using
Twisted Conch to develop your own applications</li>
<li><a href="examples/index.html" shape="rect">Examples</a>: short code examples using
Twisted Conch</li>
</ul>
</div>
<p><a href="howto/index.html">Index</a></p>
<span class="version">Version: 10.0.0</span>
</body>
</html>

View File

@@ -1,87 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Twisted Documentation: CFTP.1</title>
<link href="../howto/stylesheet.css" rel="stylesheet" type="text/css"/>
</head>
<body bgcolor="white">
<h1 class="title">CFTP.1</h1>
<div class="toc"><ol><li><a href="#auto0">NAME</a></li><li><a href="#auto1">SYNOPSIS</a></li><li><a href="#auto2">DESCRIPTION</a></li><li><a href="#auto3">AUTHOR</a></li><li><a href="#auto4">REPORTING BUGS</a></li><li><a href="#auto5">COPYRIGHT</a></li></ol></div>
<div class="content">
<span/>
<h2>NAME<a name="auto0"/></h2>
<p>cftp </p>
<h2>SYNOPSIS<a name="auto1"/></h2>
<p>cftp [<strong>-B</strong><em> buffer_size</em>][<strong>-b</strong><em> command_file</em>][<strong>-R</strong><em> num_requests</em>][<strong>-s</strong><em> subsystem</em>]</p>
<h2>DESCRIPTION<a name="auto2"/></h2>
<p>cftp is a client for logging into a remote machine and executing commands to send and receive file information. It can wrap a number of file transfer subsystems
</p>
<p>The options are as follows:
<dl><dt><strong>-B</strong></dt><dd>Specifies the default size of the buffer to use for sending and receiving. (Default value: 32768 bytes.)
</dd><dt><strong>-b</strong></dt><dd>File to read commands from, '-' for stdin. (Default value: interactive/stdin.)
</dd><dt><strong>-R</strong></dt><dd>Number of requests to make before waiting for a reply.
</dd><dt><strong>-s</strong></dt><dd>Subsystem/server program to connect to.
</dd></dl>
</p>
<p>The following commands are recognised by
cftp :
<dl><dt>cd <u>path</u></dt><dd>Change the remote directory to 'path'.
</dd><dt>chgrp <u>gid</u> <u>path</u></dt><dd>Change the gid of 'path' to 'gid'.
</dd><dt>chmod <u>mode</u> <u>path</u></dt><dd>Change mode of 'path' to 'mode'.
</dd><dt>chown <u>uid</u> <u>path</u></dt><dd>Change uid of 'path' to 'uid'.
</dd><dt>exit</dt><dd>Disconnect from the server.
</dd><dt>get <u>remote-path</u> [<u>local-path</u>]</dt><dd>Get remote file and optionally store it at specified local path.
</dd><dt>help</dt><dd>Get a list of available commands.
</dd><dt>lcd <u>path</u></dt><dd>Change local directory to 'path'.
</dd><dt>lls [<u>ls-options</u>] [<u>path</u>]</dt><dd>Display local directory listing.
</dd><dt>lmkdir <u>path</u></dt><dd>Create local directory.
</dd><dt>ln <u>linkpath</u> <u>targetpath</u></dt><dd>Symlink remote file.
</dd><dt>lpwd</dt><dd>Print the local working directory.
</dd><dt>ls [<u>-l</u>] [<u>path</u>]</dt><dd>Display remote directory listing.
</dd><dt>mkdir <u>path</u></dt><dd>Create remote directory.
</dd><dt>progress</dt><dd>Toggle progress bar.
</dd><dt>put <u>local-path</u> [<u>remote-path</u>]</dt><dd>Transfer local file to remote location
</dd><dt>pwd</dt><dd>Print the remote working directory.
</dd><dt>quit</dt><dd>Disconnect from the server.
</dd><dt>rename <u>oldpath</u> <u>newpath</u></dt><dd>Rename remote file.
</dd><dt>rmdir <u>path</u></dt><dd>Remove remote directory.
</dd><dt>rm <u>path</u></dt><dd>Remove remote file.
</dd><dt>version</dt><dd>Print the SFTP version.
</dd><dt>?</dt><dd>Synonym for 'help'.
</dd></dl>
</p>
<h2>AUTHOR<a name="auto3"/></h2>
<p>cftp by Paul Swartz &lt;z3p@twistedmatrix.com&gt;. Man page by Mary Gardiner &lt;mary@twistedmatrix.com&gt;.
</p>
<h2>REPORTING BUGS<a name="auto4"/></h2>
<p>Report bugs to <em>http://twistedmatrix.com/bugs/</em>
</p>
<h2>COPYRIGHT<a name="auto5"/></h2>
<p>Copyright © 2005-2008 Twisted Matrix Laboratories
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
</p>
</div>
<p><a href="../howto/index.html">Index</a></p>
<span class="version">Version: 10.0.0</span>
</body>
</html>

View File

@@ -1,89 +0,0 @@
.Dd October 8, 2005
.Dt CFTP 1
.Os
.Sh NAME
.Nm cftp
.Nd Conch command-line SFTP client
.Sh SYNOPSIS
.Nm cftp
.Op Fl B Ar buffer_size
.Op Fl b Ar command_file
.Op Fl R Ar num_requests
.Op Fl s Ar subsystem
.Os
.Sh DESCRIPTION
.Nm
is a client for logging into a remote machine and executing commands to send and receive file information. It can wrap a number of file transfer subsystems
.Pp
The options are as follows:
.Bl -tag -width Ds
.It Fl B
Specifies the default size of the buffer to use for sending and receiving. (Default value: 32768 bytes.)
.It Fl b
File to read commands from, '-' for stdin. (Default value: interactive/stdin.)
.It Fl R
Number of requests to make before waiting for a reply.
.It Fl s
Subsystem/server program to connect to.
.El
.Pp
The following commands are recognised by
.Nm
:
.Bl -tag -width Ds
.It Ic cd Ar path
Change the remote directory to 'path'.
.It Ic chgrp Ar gid Ar path
Change the gid of 'path' to 'gid'.
.It Ic chmod Ar mode Ar path
Change mode of 'path' to 'mode'.
.It Ic chown Ar uid Ar path
Change uid of 'path' to 'uid'.
.It Ic exit
Disconnect from the server.
.It Ic get Ar remote-path Op Ar local-path
Get remote file and optionally store it at specified local path.
.It Ic help
Get a list of available commands.
.It Ic lcd Ar path
Change local directory to 'path'.
.It Ic lls Op Ar ls-options Op Ar path
Display local directory listing.
.It Ic lmkdir Ar path
Create local directory.
.It Ic ln Ar linkpath Ar targetpath
Symlink remote file.
.It Ic lpwd
Print the local working directory.
.It Ic ls Op Ar -l Op Ar path
Display remote directory listing.
.It Ic mkdir Ar path
Create remote directory.
.It Ic progress
Toggle progress bar.
.It Ic put Ar local-path Op Ar remote-path
Transfer local file to remote location
.It Ic pwd
Print the remote working directory.
.It Ic quit
Disconnect from the server.
.It Ic rename Ar oldpath Ar newpath
Rename remote file.
.It Ic rmdir Ar path
Remove remote directory.
.It Ic rm Ar path
Remove remote file.
.It Ic version
Print the SFTP version.
.It Ic ?
Synonym for 'help'.
.El
.Sh AUTHOR
cftp by Paul Swartz <z3p@twistedmatrix.com>. Man page by Mary Gardiner <mary@twistedmatrix.com>.
.Sh "REPORTING BUGS"
Report bugs to \fIhttp://twistedmatrix.com/bugs/\fR
.Sh COPYRIGHT
Copyright \(co 2005-2008 Twisted Matrix Laboratories
.br
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

View File

@@ -1,107 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Twisted Documentation: CKEYGEN.1</title>
<link href="../howto/stylesheet.css" rel="stylesheet" type="text/css"/>
</head>
<body bgcolor="white">
<h1 class="title">CKEYGEN.1</h1>
<div class="toc"><ol><li><a href="#auto0">NAME</a></li><li><a href="#auto1">SYNOPSIS</a></li><li><a href="#auto2">DESCRIPTION</a></li><li><a href="#auto3">DESCRIPTION</a></li><li><a href="#auto4">AUTHOR</a></li><li><a href="#auto5">REPORTING BUGS</a></li><li><a href="#auto6">COPYRIGHT</a></li><li><a href="#auto7">SEE ALSO</a></li></ol></div>
<div class="content">
<span/>
<h2>NAME<a name="auto0"/></h2>
<p>ckeygen - connect to SSH servers
</p>
<h2>SYNOPSIS<a name="auto1"/></h2>
<p><strong>ckeygen</strong> [-b <em>bits</em>] [-f <em>filename</em>] [-t <em>type</em>]<strong>[-C</strong> <em>comment</em>] [-N <em>new passphrase</em>] [-P <em>old passphrase</em>]<strong>[-l]</strong> [-p] [-q] [-y]<strong>ckeygen</strong> --help</p>
<h2>DESCRIPTION<a name="auto2"/></h2>
<p>The <strong>--help</strong> prints out a usage message to standard output.
<dl><dt><strong>-b</strong>, <strong>--bits</strong> &lt;bits&gt;
</dt><dd>Number of bits in the key to create (default: 1024)
</dd>
<dt><strong>-f</strong>, <strong>--filename</strong> &lt;file name&gt;
</dt><dd>Filename of the key file.
</dd>
<dt><strong>-t</strong>, <strong>--type</strong> &lt;type&gt;
</dt><dd>Type of key (rsa or dsa).
</dd>
<dt><strong>-C</strong>, <strong>--comment</strong> &lt;comment&gt;
</dt><dd>Provide a new comment.
</dd>
<dt><strong>-N</strong>, <strong>--newpass</strong> &lt;pass phrase&gt;
</dt><dd>Provide new passphrase.
</dd>
<dt><strong>-P</strong>, <strong>--pass</strong> &lt;pass phrase&gt;
</dt><dd>Provide old passphrase.
</dd>
<dt><strong>-l</strong>, <strong>--fingerprint</strong>
</dt><dd>Show fingerprint of key file.
</dd>
<dt><strong>-p</strong>, <strong>--changepass</strong>
</dt><dd>Change passphrase of private key file.
</dd>
<dt><strong>-q</strong>, <strong>--quiet</strong>
</dt><dd>Be quiet.
</dd>
<dt><strong>-y</strong>, <strong>--showpub</strong>
</dt><dd>Read private key file and print public key.
</dd>
<dt><strong>--version</strong>
</dt><dd>Display version number only.
</dd>
</dl>
</p>
<h2>DESCRIPTION<a name="auto3"/></h2>
<p>Manipulate public/private keys in various ways.
If no filename is given, a file name will be requested interactively.
</p>
<h2>AUTHOR<a name="auto4"/></h2>
<p>Written by Moshe Zadka, based on ckeygen's help messages
</p>
<h2>REPORTING BUGS<a name="auto5"/></h2>
<p>To report a bug, visit <em>http://twistedmatrix.com/bugs/</em>
</p>
<h2>COPYRIGHT<a name="auto6"/></h2>
<p>Copyright © 2002-2008 Twisted Matrix Laboratories.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
</p>
<h2>SEE ALSO<a name="auto7"/></h2>
<p>ssh(1), conch(1)
</p>
</div>
<p><a href="../howto/index.html">Index</a></p>
<span class="version">Version: 10.0.0</span>
</body>
</html>

View File

@@ -1,58 +0,0 @@
.TH CKEYGEN "1" "October 2002" "" ""
.SH NAME
ckeygen \- connect to SSH servers
.SH SYNOPSIS
.B ckeygen [-b \fIbits\fR] [-f \fIfilename\fR] [-t \fItype\fR]
.B [-C \fIcomment\fR] [-N \fInew passphrase\fR] [-P \fIold passphrase\fR]
.B [-l] [-p] [-q] [-y]
.B ckeygen --help
.SH DESCRIPTION
.PP
The \fB\--help\fR prints out a usage message to standard output.
.TP
\fB-b\fR, \fB--bits\fR <bits>
Number of bits in the key to create (default: 1024)
.TP
\fB-f\fR, \fB--filename\fR <file name>
Filename of the key file.
.TP
\fB-t\fR, \fB--type\fR <type>
Type of key (rsa or dsa).
.TP
\fB-C\fR, \fB--comment\fR <comment>
Provide a new comment.
.TP
\fB-N\fR, \fB--newpass\fR <pass phrase>
Provide new passphrase.
.TP
\fB-P\fR, \fB--pass\fR <pass phrase>
Provide old passphrase.
.TP
\fB-l\fR, \fB--fingerprint\fR
Show fingerprint of key file.
.TP
\fB-p\fR, \fB--changepass\fR
Change passphrase of private key file.
.TP
\fB-q\fR, \fB--quiet\fR
Be quiet.
.TP
\fB-y\fR, \fB--showpub\fR
Read private key file and print public key.
.TP
\fB--version\fR
Display version number only.
.SH DESCRIPTION
Manipulate public/private keys in various ways.
If no filename is given, a file name will be requested interactively.
.SH AUTHOR
Written by Moshe Zadka, based on ckeygen's help messages
.SH "REPORTING BUGS"
To report a bug, visit \fIhttp://twistedmatrix.com/bugs/\fR
.SH COPYRIGHT
Copyright \(co 2002-2008 Twisted Matrix Laboratories.
.br
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
.SH "SEE ALSO"
ssh(1), conch(1)

View File

@@ -1,148 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Twisted Documentation: CONCH.1</title>
<link href="../howto/stylesheet.css" rel="stylesheet" type="text/css"/>
</head>
<body bgcolor="white">
<h1 class="title">CONCH.1</h1>
<div class="toc"><ol><li><a href="#auto0">NAME</a></li><li><a href="#auto1">SYNOPSIS</a></li><li><a href="#auto2">DESCRIPTION</a></li><li><a href="#auto3">AUTHOR</a></li><li><a href="#auto4">REPORTING BUGS</a></li><li><a href="#auto5">COPYRIGHT</a></li><li><a href="#auto6">SEE ALSO</a></li></ol></div>
<div class="content">
<span/>
<h2>NAME<a name="auto0"/></h2>
<p>conch </p>
<h2>SYNOPSIS<a name="auto1"/></h2>
<p>conch [<strong>-AaCfINnrsTtVvx</strong>][<strong>-c</strong><em> cipher_spec</em>][<strong>-e</strong><em> escape_char</em>][<strong>-i</strong><em> identity_file</em>][<strong>-K</strong><em> connection_spec</em>][<strong>-L</strong><em> port</em>:<em> host</em>:<em> hostport</em>][<strong>-l</strong><em> user</em>][<strong>-m</strong><em> mac_spec</em>][<strong>-o</strong><em> openssh_option</em>][<strong>-p</strong><em> port</em>][<strong>-R</strong><em> port</em>:<em> host</em>:<em> hostport</em>][<em> user</em>@]<em> hostname</em>[<em> command</em>]</p>
<h2>DESCRIPTION<a name="auto2"/></h2>
<p>conch is a SSHv2 client for logging into a remote machine and executing commands. It provides encrypted and secure communications across a possibly insecure network. Arbitrary TCP/IP ports can also be forwarded over the secure connection.
</p>
<p>conch connects and logs into
<em> hostname</em>(as
<em> user</em>or the current username). The user must prove her/his identity through a public-key or a password. Alternatively, if a connection is already open to a server, a new shell can be opened over the connection without having to reauthenticate.
</p>
<p>If
<em> command</em>is specified,
<em> command</em>is executed instead of a shell. If the
<strong>-s</strong>option is given,
<em> command</em>is treated as an SSHv2 subsystem name.
Conch supports the public-key, keyboard-interactive, and password authentications.
</p>
<p>The public-key method allows the RSA or DSA algorithm to be used. The client uses his/her private key,
or
to sign the session identifier, known only by the client and server. The server checks that the matching public key is valid for the user, and that the signature is correct.
</p>
<p>If public-key authentication fails,
conch can authenticate by sending an encrypted password over the connection.
conch has the ability to multiplex multiple shells, commands and TCP/IP ports over the same secure connection. To disable multiplexing for a connection, use the
<strong>-I</strong>flag.
</p>
<p>The
<strong>-K</strong>option determines how the client connects to the remote host. It is a comma-separated list of the methods to use, in order of preference. The two connection methods are
(for connecting over a multiplexed connection) and
(to connect directly).
To disable connecting over a multiplexed connection, do not include
in the preference list.
</p>
<p>As an example of how connection sharing works, to speed up CVS over SSH:
</p>
<p>conch --noshell --fork -l cvs_user cvs_host
set CVS_RSH=<strong>conch</strong>
</p>
<p>Now, when CVS connects to cvs_host as cvs_user, instead of making a new connection to the server,
conch will add a new channel to the existing connection. This saves the cost of repeatedly negotiating the cryptography and authentication.
</p>
<p>The options are as follows:
<dl><dt><strong>-A</strong></dt><dd>Enables authentication agent forwarding.
</dd><dt><strong>-a</strong></dt><dd>Disables authentication agent forwarding (default).
</dd><dt><strong>-C</strong></dt><dd>Enable compression.
</dd><dt><strong>-c</strong></dt><dd><em> cipher_spec</em>Selects encryption algorithms to be used for this connection, as a comma-separated list of ciphers in order of preference. The list that
conch supports is (in order of default preference): aes256-ctr, aes256-cbc, aes192-ctr, aes192-cbc, aes128-ctr, aes128-cbc, cast128-ctr, cast128-cbc, blowfish-ctr, blowfish, idea-ctr, idea-cbc, 3des-ctr, 3des-cbc.
</dd><dt><strong>-e</strong></dt><dd><em> ch</em>| ^ch | noneSets the escape character for sessions with a PTY (default:
The escape character is only recognized at the beginning of a line (after a newline).
The escape character followed by a dot
closes the connection;
followed by ^Z suspends the connection;
and followed by the escape character sends the escape character once.
Setting the character to
disables any escapes.
</dd><dt><strong>-f</strong></dt><dd>Fork to background after authentication.
</dd><dt><strong>-I</strong></dt><dd>Do not allow connection sharing over this connection.
</dd><dt><strong>-i</strong></dt><dd><em> identity_spec</em>The file from which the identity (private key) for RSA or DSA authentication is read.
The defaults are
and
It is possible to use this option more than once to use more than one private key.
</dd><dt><strong>-K</strong></dt><dd><em> connection_spec</em>Selects methods for connection to the server, as a comma-separated list of methods in order of preference. See
for more information.
</dd><dt><strong>-L</strong></dt><dd><em> port</em>: host : hostportSpecifies that the given port on the client host is to be forwarded to the given host and port on the remote side. This allocates a socket to listen to
<em> port</em>on the local side, and when connections are made to that socket, they are forwarded over the secure channel and a connection is made to
<em> host</em>port
<em> hostport</em>from the remote machine.
Only root can forward privieged ports.
</dd><dt><strong>-l</strong></dt><dd><em> user</em>Log in using this username.
</dd><dt><strong>-m</strong></dt><dd><em> mac_spec</em>Selects MAC (message authentication code) algorithms, as a comma-separated list in order of preference. The list that
conch supports is (in order of preference): hmac-sha1, hmac-md5.
</dd><dt><strong>-N</strong></dt><dd>Do not execute a shell or command.
</dd><dt><strong>-n</strong></dt><dd>Redirect input from /dev/null.
</dd><dt><strong>-o</strong></dt><dd><em> openssh_option</em>Ignored OpenSSH options.
</dd><dt><strong>-p</strong></dt><dd><em> port</em>The port to connect to on the server.
</dd><dt><strong>-R</strong></dt><dd><em> port</em>: host : hostportSpecifies that the given port on the remote host is to be forwarded to the given host and port on the local side. This allocates a socket to listen to
<em> port</em>on the remote side, and when connections are made to that socket, they are forwarded over the secure channel and a connection is made to
<em> host</em>port
<em> hostport</em>from the client host.
Only root can forward privieged ports.
</dd><dt><strong>-s</strong></dt><dd>Reconnect to the server if the connection is lost.
</dd><dt><strong>-s</strong></dt><dd>Invoke
<em> command</em>(mandatory) as a SSHv2 subsystem.
</dd><dt><strong>-T</strong></dt><dd>Do not allocate a TTY.
</dd><dt><strong>-t</strong></dt><dd>Allocate a TTY even if command is given.
</dd><dt><strong>-V</strong></dt><dd>Display version number only.
</dd><dt><strong>-v</strong></dt><dd>Log to stderr.
</dd><dt><strong>-x</strong></dt><dd>Disable X11 connection forwarding (default).
</dd></dl>
</p>
<h2>AUTHOR<a name="auto3"/></h2>
<p>Written by Paul Swartz &lt;z3p@twistedmatrix.com&gt;.
</p>
<h2>REPORTING BUGS<a name="auto4"/></h2>
<p>To report a bug, visit <em>http://twistedmatrix.com/bugs/</em>
</p>
<h2>COPYRIGHT<a name="auto5"/></h2>
<p>Copyright © 2002-2008 Twisted Matrix Laboratories.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
</p>
<h2>SEE ALSO<a name="auto6"/></h2>
<p>ssh(1)
</p>
</div>
<p><a href="../howto/index.html">Index</a></p>
<span class="version">Version: 10.0.0</span>
</body>
</html>

View File

@@ -1,206 +0,0 @@
.Dd May 22, 2004
.Dt CONCH 1
.Os
.Sh NAME
.Nm conch
.Nd Conch SSH client
.Sh SYNOPSIS
.Nm conch
.Op Fl AaCfINnrsTtVvx
.Op Fl c Ar cipher_spec
.Op Fl e Ar escape_char
.Op Fl i Ar identity_file
.Op Fl K Ar connection_spec
.Bk -words
.Oo Fl L Xo
.Sm off
.Ar port :
.Ar host :
.Ar hostport
.Sm on
.Xc
.Oc
.Ek
.Op Fl l Ar user
.Op Fl m Ar mac_spec
.Op Fl o Ar openssh_option
.Op Fl p Ar port
.Bk -words
.Oo Fl R Xo
.Sm off
.Ar port :
.Ar host :
.Ar hostport
.Sm on
.Xc
.Oc
.Ek
.Oo Ar user Ns @ Ns Oc Ar hostname
.Op Ar command
.Sh DESCRIPTION
.Nm
is a SSHv2 client for logging into a remote machine and executing commands. It provides encrypted and secure communications across a possibly insecure network. Arbitrary TCP/IP ports can also be forwarded over the secure connection.
.Pp
.Nm
connects and logs into
.Ar hostname
(as
.Ar user
or the current username). The user must prove her/his identity through a public\-key or a password. Alternatively, if a connection is already open to a server, a new shell can be opened over the connection without having to reauthenticate.
.Pp
If
.Ar command
is specified,
.Ar command
is executed instead of a shell. If the
.Fl s
option is given,
.Ar command
is treated as an SSHv2 subsystem name.
.Ss Authentication
Conch supports the public-key, keyboard-interactive, and password authentications.
.Pp
The public-key method allows the RSA or DSA algorithm to be used. The client uses his/her private key,
.Pa $HOME/.ssh/id_rsa
or
.Pa $HOME/.ssh/id_dsa
to sign the session identifier, known only by the client and server. The server checks that the matching public key is valid for the user, and that the signature is correct.
.Pp
If public-key authentication fails,
.Nm
can authenticate by sending an encrypted password over the connection.
.Ss Connection sharing
.Nm
has the ability to multiplex multiple shells, commands and TCP/IP ports over the same secure connection. To disable multiplexing for a connection, use the
.Fl I
flag.
.Pp
The
.Fl K
option determines how the client connects to the remote host. It is a comma-separated list of the methods to use, in order of preference. The two connection methods are
.Ql unix
(for connecting over a multiplexed connection) and
.Ql direct
(to connect directly).
To disable connecting over a multiplexed connection, do not include
.Ql unix
in the preference list.
.Pp
As an example of how connection sharing works, to speed up CVS over SSH:
.Pp
.Nm
--noshell --fork -l cvs_user cvs_host
.br
set CVS_RSH=\fBconch\fR
.Pp
Now, when CVS connects to cvs_host as cvs_user, instead of making a new connection to the server,
.Nm
will add a new channel to the existing connection. This saves the cost of repeatedly negotiating the cryptography and authentication.
.Pp
The options are as follows:
.Bl -tag -width Ds
.It Fl A
Enables authentication agent forwarding.
.It Fl a
Disables authentication agent forwarding (default).
.It Fl C
Enable compression.
.It Fl c Ar cipher_spec
Selects encryption algorithms to be used for this connection, as a comma-separated list of ciphers in order of preference. The list that
.Nm
supports is (in order of default preference): aes256-ctr, aes256-cbc, aes192-ctr, aes192-cbc, aes128-ctr, aes128-cbc, cast128-ctr, cast128-cbc, blowfish-ctr, blowfish, idea-ctr, idea-cbc, 3des-ctr, 3des-cbc.
.It Fl e Ar ch | ^ch | none
Sets the escape character for sessions with a PTY (default:
.Ql ~ ) .
The escape character is only recognized at the beginning of a line (after a newline).
The escape character followed by a dot
.Pq Ql \&.
closes the connection;
followed by ^Z suspends the connection;
and followed by the escape character sends the escape character once.
Setting the character to
.Dq none
disables any escapes.
.It Fl f
Fork to background after authentication.
.It Fl I
Do not allow connection sharing over this connection.
.It Fl i Ar identity_spec
The file from which the identity (private key) for RSA or DSA authentication is read.
The defaults are
.Pa $HOME/.ssh/id_rsa
and
.Pa $HOME/.ssh/id_dsa .
It is possible to use this option more than once to use more than one private key.
.It Fl K Ar connection_spec
Selects methods for connection to the server, as a comma-separated list of methods in order of preference. See
.Cm Connection sharing
for more information.
.It Fl L Xo
.Sm off
.Ar port : host : hostport
.Sm on
.Xc
Specifies that the given port on the client host is to be forwarded to the given host and port on the remote side. This allocates a socket to listen to
.Ar port
on the local side, and when connections are made to that socket, they are forwarded over the secure channel and a connection is made to
.Ar host
port
.Ar hostport
from the remote machine.
Only root can forward privieged ports.
.It Fl l Ar user
Log in using this username.
.It Fl m Ar mac_spec
Selects MAC (message authentication code) algorithms, as a comma-separated list in order of preference. The list that
.Nm
supports is (in order of preference): hmac-sha1, hmac-md5.
.It Fl N
Do not execute a shell or command.
.It Fl n
Redirect input from /dev/null.
.It Fl o Ar openssh_option
Ignored OpenSSH options.
.It Fl p Ar port
The port to connect to on the server.
.It Fl R Xo
.Sm off
.Ar port : host : hostport
.Sm on
.Xc
Specifies that the given port on the remote host is to be forwarded to the given host and port on the local side. This allocates a socket to listen to
.Ar port
on the remote side, and when connections are made to that socket, they are forwarded over the secure channel and a connection is made to
.Ar host
port
.Ar hostport
from the client host.
Only root can forward privieged ports.
.It Fl s
Reconnect to the server if the connection is lost.
.It Fl s
Invoke
.Ar command
(mandatory) as a SSHv2 subsystem.
.It Fl T
Do not allocate a TTY.
.It Fl t
Allocate a TTY even if command is given.
.It Fl V
Display version number only.
.It Fl v
Log to stderr.
.It Fl x
Disable X11 connection forwarding (default).
.El
.Sh AUTHOR
Written by Paul Swartz <z3p@twistedmatrix.com>.
.Sh "REPORTING BUGS"
To report a bug, visit \fIhttp://twistedmatrix.com/bugs/\fR
.Sh COPYRIGHT
Copyright \(co 2002-2008 Twisted Matrix Laboratories.
.br
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
.Sh SEE ALSO
ssh(1)

View File

@@ -1,129 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Twisted Documentation: CONCH.1</title>
<link href="../howto/stylesheet.css" rel="stylesheet" type="text/css"/>
</head>
<body bgcolor="white">
<h1 class="title">CONCH.1</h1>
<div class="toc"><ol><li><a href="#auto0">NAME</a></li><li><a href="#auto1">SYNOPSIS</a></li><li><a href="#auto2">DESCRIPTION</a></li><li><a href="#auto3">DESCRIPTION</a></li><li><a href="#auto4">AUTHOR</a></li><li><a href="#auto5">REPORTING BUGS</a></li><li><a href="#auto6">COPYRIGHT</a></li><li><a href="#auto7">SEE ALSO</a></li></ol></div>
<div class="content">
<span/>
<h2>NAME<a name="auto0"/></h2>
<p>tkconch - connect to SSH servers graphically
</p>
<h2>SYNOPSIS<a name="auto1"/></h2>
<p><strong>conch</strong> [-l <em>user</em>] [-i <em>identity</em> [ -i <em>identity</em> ... ]] [-c <em>cipher</em>] [-m <em>MAC</em>] [-p <em>port</em>] [-n] [-t] [-T] [-V] [-C] [-N] [-s] [arg [...]]</p>
<p><strong>conch</strong> --help</p>
<h2>DESCRIPTION<a name="auto2"/></h2>
<p>The <strong>--help</strong> prints out a usage message to standard output.
<dl><dt><strong>-l</strong>, <strong>--user</strong> &lt;user&gt;
</dt><dd>Log in using this user name.
</dd>
<dt><strong>-e</strong>, <strong>--escape</strong> &lt;escape character&gt;
</dt><dd>Set escape character; 'none' = disable (default: ~)
</dd>
<dt><strong>-i</strong>, <strong>--identity</strong> &lt;identity&gt;
</dt><dd>Add an identity file for public key authentication (default: ~/.ssh/identity)
</dd>
<dt><strong>-c</strong>, <strong>--cipher</strong> &lt;cipher&gt;
</dt><dd>Cipher algorithm to use.
</dd>
<dt><strong>-m</strong>, <strong>--macs</strong> &lt;mac&gt;
</dt><dd>Specify MAC algorithms for protocol version 2.
</dd>
<dt><strong>-p</strong>, <strong>--port</strong> &lt;port&gt;
</dt><dd>Port to connect to.
</dd>
<dt><strong>-L</strong>, <strong>--localforward</strong> &lt;listen-port:host:port&gt;
</dt><dd>Forward local port to remote address.
</dd>
<dt><strong>-R</strong>, <strong>--remoteforward</strong> &lt;listen-port:host:port&gt;
</dt><dd>Forward remote port to local address.
</dd>
<dt><strong>-t</strong>, <strong>--tty</strong>
</dt><dd>Allocate a tty even if command is given.
</dd>
<dt><strong>-n</strong>, <strong>--notty</strong>
</dt><dd>Do not allocate a tty.
</dd>
<dt><strong>-V</strong>, <strong>--version</strong>
</dt><dd>Display version number only.
</dd>
<dt><strong>-C</strong>, <strong>--compress</strong>
</dt><dd>Enable compression.
</dd>
<dt><strong>-a</strong>, <strong>--ansilog</strong>
</dt><dd>Print the received data to stdout.
</dd>
<dt><strong>-N</strong>, <strong>--noshell</strong>
</dt><dd>Do not execute a shell or command.
</dd>
<dt><strong>-s</strong>, <strong>--subsystem</strong>
</dt><dd>Invoke command (mandatory) as SSH2 subsystem.
</dd>
<dt><strong>--log</strong>
</dt><dd>Print the receieved data to stderr.
</dd>
</dl>
</p>
<h2>DESCRIPTION<a name="auto3"/></h2>
<p>Open an SSH connection to specified server, and either run the command
given there or open a remote interactive shell.
</p>
<h2>AUTHOR<a name="auto4"/></h2>
<p>Written by Moshe Zadka, based on conch's help messages
</p>
<h2>REPORTING BUGS<a name="auto5"/></h2>
<p>To report a bug, visit <em>http://twistedmatrix.com/bugs/</em>
</p>
<h2>COPYRIGHT<a name="auto6"/></h2>
<p>Copyright © 2002-2008 Twisted Matrix Laboratories.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
</p>
<h2>SEE ALSO<a name="auto7"/></h2>
<p>ssh(1)
</p>
</div>
<p><a href="../howto/index.html">Index</a></p>
<span class="version">Version: 10.0.0</span>
</body>
</html>

View File

@@ -1,72 +0,0 @@
.TH CONCH "1" "October 2002" "" ""
.SH NAME
tkconch \- connect to SSH servers graphically
.SH SYNOPSIS
.B conch [-l \fIuser\fR] [-i \fIidentity\fR [ -i \fIidentity\fR ... ]] [-c \fIcipher\fR] [-m \fIMAC\fR] [-p \fIport\fR] [-n] [-t] [-T] [-V] [-C] [-N] [-s] [arg [...]]
.PP
.B conch --help
.SH DESCRIPTION
.PP
The \fB\--help\fR prints out a usage message to standard output.
.TP
\fB-l\fR, \fB--user\fR <user>
Log in using this user name.
.TP
\fB-e\fR, \fB--escape\fR <escape character>
Set escape character; 'none' = disable (default: ~)
.TP
\fB-i\fR, \fB--identity\fR <identity>
Add an identity file for public key authentication (default: ~/.ssh/identity)
.TP
\fB-c\fR, \fB--cipher\fR <cipher>
Cipher algorithm to use.
.TP
\fB-m\fR, \fB--macs\fR <mac>
Specify MAC algorithms for protocol version 2.
.TP
\fB-p\fR, \fB--port\fR <port>
Port to connect to.
.TP
\fB-L\fR, \fB--localforward\fR <listen-port:host:port>
Forward local port to remote address.
.TP
\fB-R\fR, \fB--remoteforward\fR <listen-port:host:port>
Forward remote port to local address.
.TP
\fB-t\fR, \fB--tty\fR
Allocate a tty even if command is given.
.TP
\fB-n\fR, \fB--notty\fR
Do not allocate a tty.
.TP
\fB-V\fR, \fB--version\fR
Display version number only.
.TP
\fB-C\fR, \fB--compress\fR
Enable compression.
.TP
\fB-a\fR, \fB--ansilog\fR
Print the received data to stdout.
.TP
\fB-N\fR, \fB--noshell\fR
Do not execute a shell or command.
.TP
\fB-s\fR, \fB--subsystem\fR
Invoke command (mandatory) as SSH2 subsystem.
.TP
\fB--log\fR
Print the receieved data to stderr.
.SH DESCRIPTION
Open an SSH connection to specified server, and either run the command
given there or open a remote interactive shell.
.SH AUTHOR
Written by Moshe Zadka, based on conch's help messages
.SH "REPORTING BUGS"
To report a bug, visit \fIhttp://twistedmatrix.com/bugs/\fR
.SH COPYRIGHT
Copyright \(co 2002-2008 Twisted Matrix Laboratories.
.br
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
.SH "SEE ALSO"
ssh(1)

View File

@@ -1,10 +0,0 @@
#!/usr/bin/python
from timer import timeit
from twisted.spread.banana import b1282int
ITERATIONS = 100000
for length in (1, 5, 10, 50, 100):
elapsed = timeit(b1282int, ITERATIONS, "\xff" * length)
print "b1282int %3d byte string: %10d cps" % (length, ITERATIONS / elapsed)

View File

@@ -1,145 +0,0 @@
# Copyright (c) 2007-2009 Twisted Matrix Laboratories.
# See LICENSE for details.
"""
See how fast deferreds are.
This is mainly useful to compare cdefer.Deferred to defer.Deferred
"""
from twisted.internet import defer
from timer import timeit
benchmarkFuncs = []
def benchmarkFunc(iter, args=()):
"""
A decorator for benchmark functions that measure a single iteration
count. Registers the function with the given iteration count to the global
benchmarkFuncs list
"""
def decorator(func):
benchmarkFuncs.append((func, args, iter))
return func
return decorator
def benchmarkNFunc(iter, ns):
"""
A decorator for benchmark functions that measure multiple iteration
counts. Registers the function with the given iteration count to the global
benchmarkFuncs list.
"""
def decorator(func):
for n in ns:
benchmarkFuncs.append((func, (n,), iter))
return func
return decorator
def instantiate():
"""
Only create a deferred
"""
d = defer.Deferred()
instantiate = benchmarkFunc(100000)(instantiate)
def instantiateShootCallback():
"""
Create a deferred and give it a normal result
"""
d = defer.Deferred()
d.callback(1)
instantiateShootCallback = benchmarkFunc(100000)(instantiateShootCallback)
def instantiateShootErrback():
"""
Create a deferred and give it an exception result. To avoid Unhandled
Errors, also register an errback that eats the error
"""
d = defer.Deferred()
try:
1/0
except:
d.errback()
d.addErrback(lambda x: None)
instantiateShootErrback = benchmarkFunc(200)(instantiateShootErrback)
ns = [10, 1000, 10000]
def instantiateAddCallbacksNoResult(n):
"""
Creates a deferred and adds a trivial callback/errback/both to it the given
number of times.
"""
d = defer.Deferred()
def f(result):
return result
for i in xrange(n):
d.addCallback(f)
d.addErrback(f)
d.addBoth(f)
d.addCallbacks(f, f)
instantiateAddCallbacksNoResult = benchmarkNFunc(20, ns)(instantiateAddCallbacksNoResult)
def instantiateAddCallbacksBeforeResult(n):
"""
Create a deferred and adds a trivial callback/errback/both to it the given
number of times, and then shoots a result through all of the callbacks.
"""
d = defer.Deferred()
def f(result):
return result
for i in xrange(n):
d.addCallback(f)
d.addErrback(f)
d.addBoth(f)
d.addCallbacks(f)
d.callback(1)
instantiateAddCallbacksBeforeResult = benchmarkNFunc(20, ns)(instantiateAddCallbacksBeforeResult)
def instantiateAddCallbacksAfterResult(n):
"""
Create a deferred, shoots it and then adds a trivial callback/errback/both
to it the given number of times. The result is processed through the
callbacks as they are added.
"""
d = defer.Deferred()
def f(result):
return result
d.callback(1)
for i in xrange(n):
d.addCallback(f)
d.addErrback(f)
d.addBoth(f)
d.addCallbacks(f)
instantiateAddCallbacksAfterResult = benchmarkNFunc(20, ns)(instantiateAddCallbacksAfterResult)
def pauseUnpause(n):
"""
Adds the given number of callbacks/errbacks/both to a deferred while it is
paused, and unpauses it, trigerring the processing of the value through the
callbacks.
"""
d = defer.Deferred()
def f(result):
return result
d.callback(1)
d.pause()
for i in xrange(n):
d.addCallback(f)
d.addErrback(f)
d.addBoth(f)
d.addCallbacks(f)
d.unpause()
pauseUnpause = benchmarkNFunc(20, ns)(pauseUnpause)
def benchmark():
"""
Run all of the benchmarks registered in the benchmarkFuncs list
"""
print defer.Deferred.__module__
for func, args, iter in benchmarkFuncs:
print func.__name__, args, timeit(func, iter, *args)
if __name__ == '__main__':
benchmark()

View File

@@ -1,66 +0,0 @@
"""See how slow failure creation is"""
import random
from twisted.python import failure
random.seed(10050)
O = [0, 20, 40, 60, 80, 10, 30, 50, 70, 90]
DEPTH = 30
def pickVal():
return random.choice([None, 1, 'Hello', [], {1: 1}, (1, 2, 3)])
def makeLocals(n):
return ';'.join(['x%d = %s' % (i, pickVal()) for i in range(n)])
for nLocals in O:
for i in range(DEPTH):
s = """
def deepFailure%d_%d():
%s
deepFailure%d_%d()
""" % (nLocals, i, makeLocals(nLocals), nLocals, i + 1)
exec s
exec """
def deepFailure%d_%d():
1 / 0
""" % (nLocals, DEPTH)
R = range(5000)
def fail(n):
for i in R:
try:
eval('deepFailure%d_0' % n)()
except:
failure.Failure()
def fail_str(n):
for i in R:
try:
eval('deepFailure%d_0' % n)()
except:
str(failure.Failure())
class PythonException(Exception): pass
def fail_easy(n):
for i in R:
try:
failure.Failure(PythonException())
except:
pass
from timer import timeit
# for i in O:
# timeit(fail, 1, i)
# for i in O:
# print 'easy failing', i, timeit(fail_easy, 1, i)
for i in O:
print 'failing', i, timeit(fail, 1, i)
# for i in O:
# print 'string failing', i, timeit(fail_str, 1, i)

View File

@@ -1,47 +0,0 @@
import math, time
from twisted.protocols import basic
class CollectingLineReceiver(basic.LineReceiver):
def __init__(self):
self.lines = []
self.lineReceived = self.lines.append
def deliver(proto, chunks):
map(proto.dataReceived, chunks)
def benchmark(chunkSize, lineLength, numLines):
bytes = ('x' * lineLength + '\r\n') * numLines
chunkCount = len(bytes) / chunkSize + 1
chunks = []
for n in xrange(chunkCount):
chunks.append(bytes[n*chunkSize:(n+1)*chunkSize])
assert ''.join(chunks) == bytes, (chunks, bytes)
p = CollectingLineReceiver()
before = time.clock()
deliver(p, chunks)
after = time.clock()
assert bytes.splitlines() == p.lines, (bytes.splitlines(), p.lines)
print 'chunkSize:', chunkSize,
print 'lineLength:', lineLength,
print 'numLines:', numLines,
print 'CPU Time: ', after - before
def main():
for numLines in 100, 1000:
for lineLength in (10, 100, 1000):
for chunkSize in (1, 500, 5000):
benchmark(chunkSize, lineLength, numLines)
for numLines in 10000, 50000:
for lineLength in (1000, 2000):
for chunkSize in (51, 500, 5000):
benchmark(chunkSize, lineLength, numLines)
if __name__ == '__main__':
main()

View File

@@ -1,26 +0,0 @@
"""
Benchmarks for L{twisted.internet.task}.
"""
from timer import timeit
from twisted.internet import task
def test_performance():
"""
L{LoopingCall} should not take long to skip a lot of iterations.
"""
clock = task.Clock()
call = task.LoopingCall(lambda: None)
call.clock = clock
call.start(0.1)
clock.advance(1000000)
def main():
print "LoopingCall large advance takes", timeit(test_performance, iter=1)
if __name__ == '__main__':
main()

View File

@@ -1,24 +0,0 @@
# Copyright (c) 2007-2009 Twisted Matrix Laboratories.
# See LICENSE for details.
"""
Helper stuff for benchmarks.
"""
import gc
gc.disable()
print 'Disabled GC'
def timeit(func, iter = 1000, *args, **kwargs):
"""
timeit(func, iter = 1000 *args, **kwargs) -> elapsed time
calls func iter times with args and kwargs, returns time elapsed
"""
from time import time as currentTime
r = range(iter)
t = currentTime()
for i in r:
func(*args, **kwargs)
return currentTime() - t

View File

@@ -1,60 +0,0 @@
"""Throughput test."""
import time, sys
from twisted.internet import reactor, protocol
from twisted.python import log
TIMES = 10000
S = "0123456789" * 1240
toReceive = len(S) * TIMES
class Sender(protocol.Protocol):
def connectionMade(self):
start()
self.numSent = 0
self.received = 0
self.transport.registerProducer(self, 0)
def stopProducing(self):
pass
def pauseProducing(self):
pass
def resumeProducing(self):
self.numSent += 1
self.transport.write(S)
if self.numSent == TIMES:
self.transport.unregisterProducer()
self.transport.loseConnection()
def connectionLost(self, reason):
shutdown(self.numSent == TIMES)
started = None
def start():
global started
started = time.time()
def shutdown(success):
if not success:
raise SystemExit, "failure or something"
passed = time.time() - started
print "Throughput (send): %s kbytes/sec" % ((toReceive / passed) / 1024)
reactor.stop()
def main():
f = protocol.ClientFactory()
f.protocol = Sender
reactor.connectTCP(sys.argv[1], int(sys.argv[2]), f)
reactor.run()
if __name__ == '__main__':
#log.startLogging(sys.stdout)
main()

View File

@@ -1,22 +0,0 @@
"""Non-twisted throughput client."""
import socket, time, sys
TIMES = 50000
S = "0123456789" * 1024
sent = len(S) * TIMES
def main():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((sys.argv[1], int(sys.argv[2])))
start = time.time()
i = 0
while i < TIMES:
i += 1
s.sendall(S)
passed = time.time() - start
print "Throughput: %s kbytes/sec" % ((sent / passed) / 1024)
s.close()
if __name__ == '__main__':
main()

View File

@@ -1,19 +0,0 @@
"""Throughput server."""
import sys
from twisted.protocols.wire import Discard
from twisted.internet import protocol, reactor
from twisted.python import log
def main():
f = protocol.ServerFactory()
f.protocol = Discard
reactor.listenTCP(8000, f)
reactor.run()
if __name__ == '__main__':
main()

View File

@@ -1,22 +0,0 @@
"""Non-twisted throughput server."""
import socket, signal, sys
def signalhandler(*args):
print "alarm!"
sys.stdout.flush()
signal.signal(signal.SIGALRM, signalhandler)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('', 8001))
s.listen(1)
while 1:
c, (h, p) = s.accept()
c.settimeout(30)
signal.alarm(5)
while 1:
d = c.recv(16384)
if not d:
break
c.close()

View File

@@ -1,27 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Twisted Documentation: Development of Twisted</title>
<link href="../howto/stylesheet.css" rel="stylesheet" type="text/css"/>
</head>
<body bgcolor="white">
<h1 class="title">Development of Twisted</h1>
<div class="toc"><ol/></div>
<div class="content">
<span/>
<p>This documentation is for people who work on the Twisted codebase itself,
rather than for people who want to use Twisted in their own projects.</p>
<ul>
<li><a href="naming.html" shape="rect">Naming</a></li>
<li><a href="philosophy.html" shape="rect">Philosophy</a></li>
<li><a href="security.html" shape="rect">Security</a></li>
<li><a href="policy/" shape="rect">Twisted development policy</a></li>
<li><a href="pb/" shape="rect">Twisted development for the pb modules</a></li>
</ul>
</div>
<p><a href="../howto/index.html">Index</a></p>
<span class="version">Version: 10.0.0</span>
</body>
</html>

View File

@@ -1,12 +0,0 @@
# -*- test-case-name: <test module> -*-
# Copyright (c) 2008 Twisted Matrix Laboratories.
# See LICENSE for details.
"""
Docstring goes here.
"""
__all__ = []

View File

@@ -1,38 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Twisted Documentation: Naming Conventions</title>
<link href="../howto/stylesheet.css" rel="stylesheet" type="text/css"/>
</head>
<body bgcolor="white">
<h1 class="title">Naming Conventions</h1>
<div class="toc"><ol/></div>
<div class="content">
<span/>
<p>While this may sound like a small detail, clear method naming is important to provide an API that developers familiar with event-based programming can pick up quickly.</p>
<p>Since the idea of a method call maps very neatly onto that of a received event, all event handlers are simply methods named after past-tense verbs. All class names are descriptive nouns, designed to mirror the is-a relationship of the abstractions they implement. All requests for notification or transmission are present-tense imperative verbs.</p>
<p>Here are some examples of this naming scheme:</p>
<ul>
<li>An event notification of data received from peer:
<code class="python">dataReceived(data)</code></li>
<li>A request to send data: <code class="python">write(data)</code></li>
<li>A class that implements a protocol: <code class="python">Protocol</code></li>
</ul>
<p>The naming is platform neutral. This means that the names are equally appropriate in a wide variety of environments, as long as they can publish the required events.</p>
<p>It is self-consistent. Things that deal with TCP use the acronym TCP, and it is always capitalized. Dropping, losing, terminating, and closing the connection are all referred to as <q>losing</q> the connection. This symmetrical naming allows developers to easily locate other API calls if they have learned a few related to what they want to do.</p>
<p>It is semantically clear. The semantics of dataReceived are simple: there are some bytes available for processing. This remains true even if the lower-level machinery to get the data is highly complex.</p>
</div>
<p><a href="../howto/index.html">Index</a></p>
<span class="version">Version: 10.0.0</span>
</body>
</html>

View File

@@ -1,58 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Twisted Documentation: Philosophy</title>
<link href="../howto/stylesheet.css" rel="stylesheet" type="text/css"/>
</head>
<body bgcolor="white">
<h1 class="title">Philosophy</h1>
<div class="toc"><ol><li><a href="#auto0">Abstraction Levels</a></li><li><a href="#auto1">Learning Curves</a></li></ol></div>
<div class="content">
<span/>
<h2>Abstraction Levels<a name="auto0"/></h2>
<p>When implementing interfaces to the operating system or
the network, provide two interfaces:</p>
<ul>
<li>One that doesn't hide platform specific or library specific
functionality.
For example, you can use file descriptors on Unix, and Win32 events on
Windows.
</li>
<li>One that provides a high level interface hiding platform specific
details.
E.g. process running uses same API on Unix and Windows, although
the implementation is very different.
</li>
</ul>
<p>Restated in a more general way:</p>
<ul>
<li>Provide all low level functionality for your specific domain,
without limiting the policies and decisions the user can make.</li>
<li>Provide a high level abstraction on top of the low level
implementation (or implementations) which implements the
common use cases and functionality that is used in most cases.</li>
</ul>
<h2>Learning Curves<a name="auto1"/></h2>
<p>Require the minimal amount of work and learning on part of the
user to get started. If this means they have less functionality,
that's OK, when they need it they can learn a bit more. This
will also lead to a cleaner, easier to test design.</p>
<p>For example - using twistd is a great way to deploy applications.
But to get started you don't need to know about it. Later on you can
start using twistd, but its usage is optional.</p>
</div>
<p><a href="../howto/index.html">Index</a></p>
<span class="version">Version: 10.0.0</span>
</body>
</html>

View File

@@ -1,809 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Twisted Documentation: Twisted Coding Standard</title>
<link href="../../howto/stylesheet.css" rel="stylesheet" type="text/css"/>
</head>
<body bgcolor="white">
<h1 class="title">Twisted Coding Standard</h1>
<div class="toc"><ol><li><a href="#auto0">Naming</a></li><li><a href="#auto1">Testing</a></li><ul><li><a href="#auto2">Overview</a></li><li><a href="#auto3">Test Suite</a></li></ul><li><a href="#auto4">Copyright Header</a></li><li><a href="#auto5">Whitespace</a></li><li><a href="#auto6">Modules</a></li><li><a href="#auto7">Packages</a></li><li><a href="#auto8">String Formatting Operations</a></li><li><a href="#auto9">Docstrings</a></li><li><a href="#auto10">Comments</a></li><li><a href="#auto11">Versioning</a></li><li><a href="#auto12">Scripts</a></li><li><a href="#auto13">Examples</a></li><li><a href="#auto14">Standard Library Extension Modules</a></li><li><a href="#auto15">Classes</a></li><ul><li><a href="#auto16">New-style Classes</a></li></ul><li><a href="#auto17">Methods</a></li><li><a href="#auto18">Callback Arguments</a></li><li><a href="#auto19">Special Methods</a></li><li><a href="#auto20">Functions</a></li><li><a href="#auto21">Attributes</a></li><li><a href="#auto22">Database</a></li><li><a href="#auto23">C Code</a></li><li><a href="#auto24">Commit Messages</a></li><li><a href="#auto25">Source Control</a></li><li><a href="#auto26">Fallback</a></li><li><a href="#auto27">Recommendations</a></li></ol></div>
<div class="content">
<span/>
<h2>Naming<a name="auto0"/></h2>
<p>Try to choose names which are both easy to remember and
meaningful. Some silliness is OK at the module naming level
(see <code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.spread.html" title="twisted.spread">twisted.spread</a></code>...) but when
choosing class names, be as precise as possible.</p>
<p>Try to avoid overloaded terms. This rule is often broken,
since it is incredibly difficult, as most normal words have
already been taken by some other software. More importantly,
try to avoid meaningless words. In particular, words like
<q>handler</q>, <q>processor</q>, <q>engine</q>, <q>manager</q>
and <q>component</q> don't really indicate what something does,
only that it does <em>something</em>.</p>
<p>Use American spelling in both names and docstrings. For compound
technical terms such as 'filesystem', use a non-hyphenated spelling in
both docstrings and code in order to avoid unnecessary
capitalization.</p>
<h2>Testing<a name="auto1"/></h2>
<h3>Overview<a name="auto2"/></h3>
<p>Twisted development should always be
<a href="http://en.wikipedia.org/wiki/Test-driven_development" shape="rect">
test-driven</a>. The complete test suite in trunk@HEAD is required to
be passing on <a href="http://buildbot.twistedmatrix.com/supported" shape="rect">
supported platforms</a> at all times. Regressions in the test suite
are addressed by reverting whatever revisions introduced them. For
complete documentation about testing Twisted itself, refer to the
<a href="test-standard.html" shape="rect">Test Standard</a>. What follows is
intended to be a synopsis of the most important points.</p>
<h3>Test Suite<a name="auto3"/></h3>
<p>The Twisted test suite is spread across many subpackages of the
<code>twisted</code> package. Many tests are in
<code>twisted.test</code>. Others can be found at places such as
<code>twisted.web.test</code> or <code>twisted.internet.test</code>.
Parts of the Twisted test suite may serve as good examples of how to
write tests for Twisted or for Twisted-based libraries (newer parts of
the test suite are generally better examples than older parts - check
when the code you are looking at was written before you use it as an
example of what you should write). The names of test modules should
begin with <q>test_</q> so that they are automatically discoverable by
test runners such as Trial. Twisted's unit tests are written using
<code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.trial.html" title="twisted.trial">twisted.trial</a></code>, an xUnit library which has been
extensively customized for use in testing Twisted and Twisted-based
libraries.</p>
<p>Implementation (ie, non-test) source files should begin with a
<code>test-case-name</code> tag which gives the name of any test
modules or packages which exercise them. This lets tools discover a
subset of the entire test suite which they can run first to find tests
which might be broken by a particular change.</p>
<p>It is strongly suggested that developers learn to use Emacs, and use
the <code>twisted-dev.el</code> file included in the TwistedEmacs
package to bind the F9 key to <q>run unit tests</q> and bang on it
frequently. Support for other editors is unavailable at this time but
we would love to provide it.</p>
<p>To run the whole Twisted test without using emacs, use trial:</p>
<pre class="shell" xml:space="preserve">
$ bin/trial twisted
</pre>
<p>To run an individual test module, such as
<code>twisted/mail/test/test_pop3.py</code>, specify the module
name:</p>
<pre class="shell" xml:space="preserve">
$ bin/trial twisted.mail.test.test_pop3
</pre>
<p>To run the tests associated with a particular implementation file,
such as <code>twisted/mail/pop3.py</code>, use the
<code>testmodule</code> option:</p>
<pre class="shell" xml:space="preserve">
$ bin/trial twisted/mail/pop3.py
</pre>
<p>All unit test methods should have docstrings specifying at a high
level the intent of the test. That is, a description that users of the
method would understand.</p>
<p>If you modify, or write a new, HOWTO, please read the <a href="http://twistedmatrix.com/trac/wiki/TwistedLore" shape="rect">Lore</a>
documentation to learn how to format the docs.</p>
<h2>Copyright Header<a name="auto4"/></h2>
<p>Whenever a new file is added to the repository, add the following
license header at the top of the file, including the year the file was
added. For example:</p>
<pre class="python"><p class="py-linenumber">1
2
</p><span class="py-src-comment"># Copyright (c) 2009 Twisted Matrix Laboratories.</span>
<span class="py-src-comment"># See LICENSE for details.</span>
</pre>
<p>When you update existing files, make sure the year in the copyright
header is up to date as well. You should add a new copyright header when
it's completely missing in the file that is being edited.</p>
<h2>Whitespace<a name="auto5"/></h2>
<p>Indentation is 4 spaces per indent. Tabs are not allowed. It
is preferred that every block appear on a new line, so that
control structure indentation is always visible.</p>
<p>Lines are flowed at 79 columns. They must not have trailing
whitespace. Long lines must be wrapped using implied line continuation
inside parentheses; backslashes aren't allowed. To handle long import
lines, please repeat the import like this:</p>
<pre class="python"><p class="py-linenumber">1
2
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">very</span>.<span class="py-src-variable">long</span>.<span class="py-src-variable">package</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">foo</span>, <span class="py-src-variable">bar</span>, <span class="py-src-variable">baz</span>
<span class="py-src-keyword">from</span> <span class="py-src-variable">very</span>.<span class="py-src-variable">long</span>.<span class="py-src-variable">package</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">qux</span>, <span class="py-src-variable">quux</span>, <span class="py-src-variable">quuux</span>
</pre>
<p>Top-level classes and functions must be separated with 3 blank lines,
and class-level functions with 2 blank lines. The control-L (i.e. ^L) form
feed character must not be used.</p>
<h2>Modules<a name="auto6"/></h2>
<p>Modules must be named in all lower-case, preferably short,
single words. If a module name contains multiple words, they
may be separated by underscores or not separated at all.</p>
<p>Modules must have a copyright message, a docstring and a
reference to a test module that contains the bulk of its tests.
Use this template:</p>
<div class="py-listing"><pre><p class="py-linenumber"> 1
2
3
4
5
6
7
8
9
10
11
12
</p><span class="py-src-comment"># -*- test-case-name: &lt;test module&gt; -*-</span>
<span class="py-src-comment"># Copyright (c) 2008 Twisted Matrix Laboratories.</span>
<span class="py-src-comment"># See LICENSE for details.</span>
<span class="py-src-string">&quot;&quot;&quot;
Docstring goes here.
&quot;&quot;&quot;</span>
<span class="py-src-variable">__all__</span> = []
</pre><div class="caption">Source listing - <a href="../listings/new_module_template.py"><span class="filename">../listings/new_module_template.py</span></a></div></div>
<p>In most cases, modules should contain more than one class,
function, or method; if a module contains only one object,
consider refactoring to include more related functionality in
that module.</p>
<p>Depending on the situation, it is acceptable to have imports that
look like this:
<pre class="python"><p class="py-linenumber">1
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span>.<span class="py-src-variable">defer</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">Deferred</span>
</pre>
or like this:
<pre class="python"><p class="py-linenumber">1
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">defer</span>
</pre>
That is, modules should import <em>modules</em> or <em>classes and
functions</em>, but not <em>packages</em>.</p>
<p>Wildcard import syntax may not be used by code in Twisted. These
imports lead to code which is difficult to read and maintain by
introducing complexity which strains human readers and automated tools
alike. If you find yourself with many imports to make from a single
module and wish to save typing, consider importing the module itself,
rather than its attributes.</p>
<p><em>Relative imports</em> (or <em>sibling imports</em>) may not be
used by code in Twisted. Relative imports allow certain circularities
to be introduced which can ultimately lead to unimportable modules or
duplicate instances of a single module. Relative imports also make the
task of refactoring more difficult.</p>
<p>In case of local names conflicts due to import, use the <code>as</code>
syntax, for example:
<pre class="python"><p class="py-linenumber">1
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">trial</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">util</span> <span class="py-src-keyword">as</span> <span class="py-src-variable">trial_util</span>
</pre></p>
<p>The encoding must always be ASCII, so no coding cookie is necessary.</p>
<h2>Packages<a name="auto7"/></h2>
<p>Package names should follow the same conventions as module
names. All modules must be encapsulated in some package. Nested
packages may be used to further organize related modules.</p>
<p><code>__init__.py</code> must never contain anything other than a
docstring and (optionally) an <code>__all__</code> attribute. Packages are
not modules and should be treated differently. This rule may be
broken to preserve backwards compatibility if a module is made
into a nested package as part of a refactoring.</p>
<p>If you wish to promote code from a module to a package, for
example, to break a large module out into several smaller
files, the accepted way to do this is to promote from within
the module. For example,</p>
<pre class="python"><p class="py-linenumber">1
2
3
4
5
6
7
8
9
</p><span class="py-src-comment"># parent/</span>
<span class="py-src-comment"># --- __init__.py ---</span>
<span class="py-src-keyword">import</span> <span class="py-src-variable">child</span>
<span class="py-src-comment"># --- child.py ---</span>
<span class="py-src-keyword">import</span> <span class="py-src-variable">parent</span>
<span class="py-src-keyword">class</span> <span class="py-src-identifier">Foo</span>:
<span class="py-src-keyword">pass</span>
<span class="py-src-variable">parent</span>.<span class="py-src-variable">Foo</span> = <span class="py-src-variable">Foo</span>
</pre>
<p>Every package should be added to the list in
<code class="shell">setup.py</code>.</p>
<p>Packages must not depend circularly upon each other. To simplify
maintaining this state, packages must also not import each other
circularly. While this applies to all packages within Twisted, one
<code>twisted.python</code> deserves particular attention, as it may
not depend on any other Twisted package.</p>
<h2>String Formatting Operations<a name="auto8"/></h2>
<p>When using <a href="http://docs.python.org/lib/typesseq-strings.html" shape="rect">string formatting
operations</a> like <code>formatString % values</code> you should always
use a tuple if you're using non-mapping <code>values</code>. This is to
avoid unexpected behavior when you think you're passing in a single value,
but the value is unexpectedly a tuple, e.g.:</p>
<pre class="python"><p class="py-linenumber">1
2
</p><span class="py-src-keyword">def</span> <span class="py-src-identifier">foo</span>(<span class="py-src-parameter">x</span>):
<span class="py-src-keyword">return</span> <span class="py-src-string">&quot;Hi %s\n&quot;</span> % <span class="py-src-variable">x</span>
</pre>
<p>The example shows you can pass in <code>foo(&quot;foo&quot;)</code> or
<code>foo(3)</code> fine, but if you pass in <code>foo((1,2))</code>,
it raises a <code>TypeError</code>. You should use this instead:</p>
<pre class="python"><p class="py-linenumber">1
2
</p><span class="py-src-keyword">def</span> <span class="py-src-identifier">foo</span>(<span class="py-src-parameter">x</span>):
<span class="py-src-keyword">return</span> <span class="py-src-string">&quot;Hi %s\n&quot;</span> % (<span class="py-src-variable">x</span>,)
</pre>
<h2>Docstrings<a name="auto9"/></h2>
<p>Docstrings should always be used to describe the
purpose of methods, functions, classes, and modules.</p>
<p>Docstrings are <em>never</em> to be used to provide semantic
information about an object; this rule may be violated if the
code in question is to be used in a system where this is a
requirement (such as Zope).</p>
<p>Docstrings should be indented to the level of the code they
are documenting.</p>
<p>Docstrings should be triple-quoted. The opening and the closing of the
docstrings should be on a line by themselves. For example:
<pre class="python"><p class="py-linenumber">1
2
3
4
5
6
7
8
</p><span class="py-src-keyword">class</span> <span class="py-src-identifier">Ninja</span>(<span class="py-src-parameter">object</span>):
<span class="py-src-string">&quot;&quot;&quot;
A L{Ninja} is a warrior specializing in various unorthodox arts of war.
&quot;&quot;&quot;</span>
<span class="py-src-keyword">def</span> <span class="py-src-identifier">attack</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">someone</span>):
<span class="py-src-string">&quot;&quot;&quot;
Attack C{someone} with this L{Ninja}'s shuriken.
&quot;&quot;&quot;</span>
</pre>
</p>
<p>Docstrings should be written in epytext format; more
documentation is available in the
<a href="http://epydoc.sourceforge.net/epytext.html" shape="rect">Epytext Markup Language documentation</a>.</p>
<p>Additionally, to accommodate emacs users:</p>
<ul>
<li>Single quotes of the type of the docstring's triple-quote
should be escaped. This will prevent font-lock from
accidentally fontifying large portions of the file as a
string.</li>
<li>Code examples in docstrings should be prefixed by the |
character. This will prevent IM-Python from regarding sample
code as real functions, methods, and classes.</li>
</ul>
<p>For example,</p>
<pre class="python"><p class="py-linenumber"> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
</p><span class="py-src-keyword">def</span> <span class="py-src-identifier">foo2bar</span>(<span class="py-src-parameter">f</span>):
<span class="py-src-string">&quot;&quot;&quot;
Convert L{foo}s to L{bar}s.
A function that should be used when you have a C{foo} but you want a
C{bar}; note that this is a non-destructive operation. If this method
can't convert the C{foo} to a C{bar} it will raise a L{FooException}.
@param f: C{foo}
@type f: str
For example::
| import wombat
| def sample(something):
| f = something.getFoo()
| f.doFooThing()
| b = wombat.foo2bar(f)
| b.doBarThing()
| return b
&quot;&quot;&quot;</span>
<span class="py-src-comment"># Optionally, actual code can go here.</span>
</pre>
<h2>Comments<a name="auto10"/></h2>
<p>Comments marked with XXX or TODO must contain a reference to the
associated ticket.</p>
<h2>Versioning<a name="auto11"/></h2>
<p>The API documentation should be marked up with version information.
When a new API is added the class should be marked with the epytext
<code class="shell">@since:</code> field including the version number when
the change was introduced, eg. <code class="shell">@since: 8.1</code>.</p>
<h2>Scripts<a name="auto12"/></h2>
<p>For each <q>script</q>, that is, a program you expect a Twisted user
to run from the command-line, the following things must be done:</p>
<ol>
<li>Write a module in <code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.scripts.html" title="twisted.scripts">twisted.scripts</a></code>
which contains a callable global named <code>run</code>. This
will be called by the command line part with no arguments (it
will usually read <code>sys.argv</code>). Feel free to write more
functions or classes in this module, if you feel they are useful
to others.</li>
<li>Create a file which contains a shebang line for Python. For Twisted
Core, this file should be placed in the <code>bin/</code> directory; for
example, <code>bin/twistd</code>. For sub-projects, it should be placed
in <code>bin/&lt;subproject&gt;</code>; for example, the key-generation tool
for the Conch sub-project is in <code>bin/conch/ckeygen</code>.
<pre class="python"><p class="py-linenumber">1
</p><span class="py-src-comment">#!/usr/bin/env python</span>
</pre></li>
<p>To make sure that the script is portable across different UNIX like
operating systems we use the <code>/usr/bin/env</code> command. The env
command allows you to run a program in a modified environment. That way
you don't have to search for a program via the <code>PATH</code> environment
variable. This makes the script more portable but note that it is not a
foolproof method. Always make sure that <code>/usr/bin/env</code> exists or
use a softlink/symbolic link to point it to the correct path. Python's
distutils will rewrite the shebang line upon installation so this policy
only covers the source files in version control.</p>
<li>Add the Twisted running-from-SVN header:
<pre class="python"><p class="py-linenumber">1
2
3
4
5
6
7
8
9
</p><span class="py-src-comment">### Twisted Preamble</span>
<span class="py-src-comment"># This makes sure that users don't have to set up their environment</span>
<span class="py-src-comment"># specially in order to run these programs from bin/.</span>
<span class="py-src-keyword">import</span> <span class="py-src-variable">sys</span>, <span class="py-src-variable">os</span>, <span class="py-src-variable">string</span>
<span class="py-src-keyword">if</span> <span class="py-src-variable">string</span>.<span class="py-src-variable">find</span>(<span class="py-src-variable">os</span>.<span class="py-src-variable">path</span>.<span class="py-src-variable">abspath</span>(<span class="py-src-variable">sys</span>.<span class="py-src-variable">argv</span>[<span class="py-src-number">0</span>]), <span class="py-src-variable">os</span>.<span class="py-src-variable">sep</span>+<span class="py-src-string">'Twisted'</span>) != -<span class="py-src-number">1</span>:
<span class="py-src-variable">sys</span>.<span class="py-src-variable">path</span>.<span class="py-src-variable">insert</span>(<span class="py-src-number">0</span>, <span class="py-src-variable">os</span>.<span class="py-src-variable">path</span>.<span class="py-src-variable">normpath</span>(<span class="py-src-variable">os</span>.<span class="py-src-variable">path</span>.<span class="py-src-variable">join</span>(<span class="py-src-variable">os</span>.<span class="py-src-variable">path</span>.<span class="py-src-variable">abspath</span>(<span class="py-src-variable">sys</span>.<span class="py-src-variable">argv</span>[<span class="py-src-number">0</span>]), <span class="py-src-variable">os</span>.<span class="py-src-variable">pardir</span>, <span class="py-src-variable">os</span>.<span class="py-src-variable">pardir</span>)))
<span class="py-src-keyword">if</span> <span class="py-src-keyword">not</span> <span class="py-src-variable">hasattr</span>(<span class="py-src-variable">os</span>, <span class="py-src-string">&quot;getuid&quot;</span>) <span class="py-src-keyword">or</span> <span class="py-src-variable">os</span>.<span class="py-src-variable">getuid</span>() != <span class="py-src-number">0</span>:
<span class="py-src-variable">sys</span>.<span class="py-src-variable">path</span>.<span class="py-src-variable">insert</span>(<span class="py-src-number">0</span>, <span class="py-src-variable">os</span>.<span class="py-src-variable">getcwd</span>())
<span class="py-src-comment">### end of preamble</span>
</pre></li>
<li>And end with:
<pre class="python"><p class="py-linenumber">1
2
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">scripts</span>.<span class="py-src-variable">yourmodule</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">run</span>
<span class="py-src-variable">run</span>()
</pre></li>
<li>Write a manpage and add it to the <code class="shell">man</code> folder
of a subproject's <code class="shell">doc</code> folder. On Debian systems
you can find a skeleton example of a manpage in
<code>/usr/share/doc/man-db/examples/manpage.example</code>.</li>
</ol>
<p>This will insure your program will work correctly for users of SVN,
Windows releases and Debian packages.</p>
<h2>Examples<a name="auto13"/></h2>
<p>For example scripts you expect a Twisted user
to run from the command-line, add this Python shebang line at the top
of the file:</p>
<pre class="python"><p class="py-linenumber">1
</p><span class="py-src-comment">#!/usr/bin/env python</span>
</pre>
<h2>Standard Library Extension Modules<a name="auto14"/></h2>
<p>When using the extension version of a module for which there is also
a Python version, place the import statement inside a try/except block,
and import the Python version if the import fails. This allows code to
work on platforms where the extension version is not available. For
example:
<pre class="python"><p class="py-linenumber">1
2
3
4
</p><span class="py-src-keyword">try</span>:
<span class="py-src-keyword">import</span> <span class="py-src-variable">cPickle</span> <span class="py-src-keyword">as</span> <span class="py-src-variable">pickle</span>
<span class="py-src-keyword">except</span> <span class="py-src-variable">ImportError</span>:
<span class="py-src-keyword">import</span> <span class="py-src-variable">pickle</span>
</pre>
Use the &quot;as&quot; syntax of the import statement as well, to set
the name of the extension module to the name of the Python module.</p>
<p>Some modules don't exist across all supported Python versions. For
example, Python 2.3's <code>sets</code> module was deprecated in Python 2.6
in favor of the <code>set</code> and <code>frozenset</code> builtins. When
you need to use sets or frozensets in your code, please use
<code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.python.compat.set.html" title="twisted.python.compat.set">twisted.python.compat.set</a></code> and
<code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.python.compat.frozenset.html" title="twisted.python.compat.frozenset">twisted.python.compat.frozenset</a></code>. There are some
differences between <code>sets.Set</code> and <code>set</code>, that are
explained in the
<a href="http://www.python.org/dev/peps/pep-0218/" shape="rect">set PEP</a>. Please be
sure to not rely on the behavior of one or the other implementation.
</p>
<h2>Classes<a name="auto15"/></h2>
<p>Classes are to be named in mixed case, with the first letter
capitalized; each word separated by having its first letter
capitalized. Acronyms should be capitalized in their entirety.
Class names should not be prefixed with the name of the module they are
in. Examples of classes meeting this criteria:</p>
<ul>
<li>twisted.spread.pb.ViewPoint</li>
<li>twisted.parser.patterns.Pattern</li>
</ul>
<p>Examples of classes <strong>not</strong> meeting this criteria:</p>
<ul>
<li>event.EventHandler</li>
<li>main.MainGadget</li>
</ul>
<p>An effort should be made to prevent class names from clashing
with each other between modules, to reduce the need for
qualification when importing. For example, a Service subclass
for Forums might be named twisted.forum.service.ForumService,
and a Service subclass for Words might be
twisted.words.service.WordsService. Since neither of these
modules are volatile <em>(see above)</em> the classes may be
imported directly into the user's namespace and not cause
confusion.</p>
<h3>New-style Classes<a name="auto16"/></h3>
<p>Classes and instances in Python come in two flavors: old-style or
classic, and new-style. Up to Python 2.1, old-style classes were the
only flavour available to the user, new-style classes were introduced
in Python 2.2 to unify classes and types. All classes added to Twisted
should be written as new-style classes. If <code class="python">x</code>
is an instance of a new-style class, then <code class="python">type(x)</code>
is the same as <code class="python">x.__class__</code>.</p>
<h2>Methods<a name="auto17"/></h2>
<p>Methods should be in mixed case, with the first letter lower
case, each word separated by having its first letter
capitalized. For example, <code>someMethodName</code>,
<code>method</code>.</p>
<p>Sometimes, a class will dispatch to a specialized sort of
method using its name; for example, twisted.reflect.Accessor.
In those cases, the type of method should be a prefix in all
lower-case with a trailing underscore, so method names will
have an underscore in them. For example, <code>get_someAttribute</code>.
Underscores in method names in twisted code are therefore
expected to have some semantic associated with them.</p>
<p>Some methods, in particular <code>addCallback</code> and its
cousins return self to allow for chaining calls. In this case,
wrap the chain in parenthesis, and start each chained call on
a separate line, for example:</p>
<pre class="python"><p class="py-linenumber">1
2
3
4
</p><span class="py-src-keyword">return</span> (<span class="py-src-variable">foo</span>()
.<span class="py-src-variable">addCallback</span>(<span class="py-src-variable">bar</span>)
.<span class="py-src-variable">addCallback</span>(<span class="py-src-variable">thud</span>)
.<span class="py-src-variable">addCallback</span>(<span class="py-src-variable">wozers</span>))
</pre>
<h2>Callback Arguments<a name="auto18"/></h2>
<p>There are several methods whose purpose is to help the user set up
callback functions, for example <code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.internet.defer.Deferred.addCallback.html" title="twisted.internet.defer.Deferred.addCallback">Deferred.addCallback</a></code> or the
reactor's <code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.internet.base.ReactorBase.callLater.html" title="twisted.internet.base.ReactorBase.callLater">callLater</a></code> method. To make
access to the callback as transparent as possible, most of these methods
use <code class="python">**kwargs</code> to capture arbitrary arguments
that are destined for the user's callback. This allows the call to the
setup function to look very much like the eventual call to the target
callback function.</p>
<p>In these methods, take care to not have other argument names that will
<q>steal</q> the user's callback's arguments. When sensible, prefix these
<q>internal</q> argument names with an underscore. For example, <code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.spread.pb.RemoteReference.callRemote.html" title="twisted.spread.pb.RemoteReference.callRemote">RemoteReference.callRemote</a></code> is
meant to be called like this:</p>
<pre class="python"><p class="py-linenumber">1
2
3
4
5
</p><span class="py-src-variable">myref</span>.<span class="py-src-variable">callRemote</span>(<span class="py-src-string">&quot;addUser&quot;</span>, <span class="py-src-string">&quot;bob&quot;</span>, <span class="py-src-string">&quot;555-1212&quot;</span>)
<span class="py-src-comment"># on the remote end, the following method is invoked:</span>
<span class="py-src-keyword">def</span> <span class="py-src-identifier">addUser</span>(<span class="py-src-parameter">name</span>, <span class="py-src-parameter">phone</span>):
...
</pre>
<p>where <q>addUser</q> is the remote method name. The user might also
choose to call it with named parameters like this:</p>
<pre class="python"><p class="py-linenumber">1
</p><span class="py-src-variable">myref</span>.<span class="py-src-variable">callRemote</span>(<span class="py-src-string">&quot;addUser&quot;</span>, <span class="py-src-variable">name</span>=<span class="py-src-string">&quot;bob&quot;</span>, <span class="py-src-variable">phone</span>=<span class="py-src-string">&quot;555-1212&quot;</span>)
</pre>
<p>In this case, <code>callRemote</code> (and any code that uses the
**kwargs syntax) must be careful to not use <q>name</q>, <q>phone</q>, or
any other name that might overlap with a user-provided named parameter.
Therefore, <code>callRemote</code> is implemented with the following
signature:</p>
<pre class="python"><p class="py-linenumber">1
2
</p><span class="py-src-keyword">def</span> <span class="py-src-identifier">callRemote</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">_name</span>, *<span class="py-src-parameter">args</span>, **<span class="py-src-parameter">kw</span>):
...
</pre>
<p>Do whatever you can to reduce user confusion. It may also be
appropriate to <code class="python">assert</code> that the kwargs
dictionary does not contain parameters with names that will eventually
cause problems.</p>
<h2>Special Methods<a name="auto19"/></h2>
<p>The augmented assignment protocol, defined by __iadd__ and other
similarly named methods, can be used to allow objects to be modified in
place or to rebind names if an object is immutable -- both through use
of the same operator. This can lead to confusing code, which in turn
leads to buggy code. For this reason, methods of the augmented
assignment protocol should not be used in Twisted.</p>
<h2>Functions<a name="auto20"/></h2>
<p>Functions should be named similiarly to methods.</p>
<p>Functions or methods which are responding to events to
complete a callback or errback should be named <code>_cbMethodName</code> or
<code>_ebMethodName</code>, in order to distinguish them from normal
methods.</p>
<h2>Attributes<a name="auto21"/></h2>
<p>Attributes should be named similarly to functions and
methods. Attributes should be named descriptively; attribute
names like <code>mode</code>, <code>type</code>, and
<code>buf</code> are generally discouraged. Instead, use
<code>displayMode</code>, <code>playerType</code>, or
<code>inputBuffer</code>.</p>
<p>Do not use Python's <q>private</q> attribute syntax; prefix
non-public attributes with a single leading underscore. Since
several classes have the same name in Twisted, and they are
distinguished by which package they come from, Python's
double-underscore name mangling will not work reliably in some
cases. Also, name-mangled private variables are more difficult
to address when unit testing or persisting a class.</p>
<p>An attribute (or function, method or class) should be
considered private when one or more of the following conditions
are true:</p>
<ul>
<li>The attribute represents intermediate state which is not
always kept up-to-date.</li>
<li>Referring to the contents of the attribute or otherwise
maintaining a reference to it may cause resources to
leak.</li>
<li>Assigning to the attribute will break internal
assumptions.</li>
<li>The attribute is part of a known-to-be-sub-optimal
interface and will certainly be removed in a future
release.</li>
</ul>
<h2>Database<a name="auto22"/></h2>
<p>Database tables will be named with plural nouns.</p>
<p>Database columns will be named with underscores between
words, all lower case, since most databases do not distinguish
between case.</p>
<p>Any attribute, method argument, or method name that
corresponds <em>directly</em> to a column in the database will
be named exactly the same as that column, regardless of other
coding conventions surrounding that circumstance.</p>
<p>All SQL keywords should be in upper case.</p>
<h2>C Code<a name="auto23"/></h2>
<p>Wherever possible, C code should be optional, and the
default python implementation should be maintained in tandem
with it. C code should be strict ANSI C, and
<strong>must</strong> build using GCC as well as Visual Studio
for Windows, and really shouldn't have any problems with other
compilers either. Don't do anything tricky.</p>
<p>C code should only be used for efficiency, not for binding
to external libraries. If your particular code is not
frequently run, write it in Python. If you require the use of
an external library, develop a separate, external bindings
package and make your twisted code depend on it.</p>
<h2 id="commits">Commit Messages<a name="auto24"/></h2>
<p>The commit messages are being distributed in a myriad of ways. Because
of that, you need to observe a few simple rules when writing a commit
message.</p>
<p>The first line of the message is being used as both the subject of
the commit email and the announcement on #twisted. Therefore, it should
be short (aim for &lt; 80 characters) and descriptive -- and must be
able to stand alone (it is best if it is a complete sentence). The rest
of the e-mail should be separated with <em>hard line breaks</em> into
short lines (&lt; 70 characters). This is free-format, so you can do
whatever you like here.</p>
<p>Commit messages should be about <em>what</em>, not <em>how</em>: we can
get how from SVN diff. Explain reasons for commits, and what they
affect.</p>
<p>Each commit should be a single logical change, which is internally
consistent. If you can't summarize your changes in one short line, this
is probably a sign that they should be broken into multiple checkins.</p>
<h2>Source Control<a name="auto25"/></h2>
<p>Twisted currently uses Subversion for source control. All
development <strong>should</strong> occur using branches; when a task is
considered complete another Twisted developer may review it and if no
problems are found, it may be merged into trunk. The Twisted wiki has <a href="http://twistedmatrix.com/trac/wiki/TwistedDevelopment" shape="rect">a start</a>.
Branches <strong>must</strong> be used for major development. Branches
should be managed using <a href="http://divmod.org/trac/wiki/DivmodCombinator" shape="rect">Combinator</a> (but
if you can manage them in some other way without anyone noticing, knock
yourself out).</p>
<p>Certain features of Subversion should be avoided.</p>
<ul>
<li>
<p>Do not set the <code class="shell">svn:ignore</code> property on any
file or directory. What you wish to ignore, others may wish to examine.
What others may wish you ignore, <em>you</em> may wish you examine.
<code class="shell"> svn:ignore </code> will affect everyone who uses
the repository, and so it is not the right mechanism to express personal
preferences.</p>
<p>If you wish to ignore certain files use the <code class="shell">
global-ignores </code> feature of <code class="shell">
~/.subversion/config </code>, for example:</p>
<pre class="shell" xml:space="preserve">
[miscellany]
global-ignores = dropin.cache *.pyc *.pyo *.o *.lo *.la #*# .*.rej *.rej .*~
</pre>
</li>
</ul>
<h2>Fallback<a name="auto26"/></h2>
<p>In case of conventions not enforced in this document, the reference
documents to use in fallback is
<a href="http://www.python.org/dev/peps/pep-0008/" shape="rect">PEP 8</a> for Python
code and <a href="http://www.python.org/dev/peps/pep-0007/" shape="rect">PEP 7</a> for
C code. For example, the paragraph <strong>Whitespace in Expressions and
Statements</strong> in PEP 8 describes what should be done in Twisted
code.</p>
<h2>Recommendations<a name="auto27"/></h2>
<p>These things aren't necessarily standardizeable (in that
code can't be easily checked for compliance) but are a good
idea to keep in mind while working on Twisted.</p>
<p>If you're going to work on a fragment of the Twisted
codebase, please consider finding a way that you would <em>use</em>
such a fragment in daily life. Using a Twisted Web server on your
website encourages you to actively maintain and improve your code,
as the little everyday issues with using it become apparent.</p>
<p>Twisted is a <strong>big</strong> codebase! If you're
refactoring something, please make sure to recursively grep for
the names of functions you're changing. You may be surprised to
learn where something is called. Especially if you are moving
or renaming a function, class, method, or module, make sure
that it won't instantly break other code.</p>
</div>
<p><a href="../../howto/index.html">Index</a></p>
<span class="version">Version: 10.0.0</span>
</body>
</html>

View File

@@ -1,188 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Twisted Documentation: HTML Documentation Standard for Twisted</title>
<link href="../../howto/stylesheet.css" rel="stylesheet" type="text/css"/>
</head>
<body bgcolor="white">
<h1 class="title">HTML Documentation Standard for Twisted</h1>
<div class="toc"><ol><li><a href="#auto0">Allowable Tags</a></li><li><a href="#auto1">Multi-line Code Snippets</a></li><ul><li><a href="#auto2">python</a></li><li><a href="#auto3">python-interpreter</a></li><li><a href="#auto4">shell</a></li></ul><li><a href="#auto5">Code inside paragraph text</a></li><li><a href="#auto6">Headers</a></li><li><a href="#auto7">XHTML</a></li><li><a href="#auto8">Tag Case</a></li><li><a href="#auto9">Footnotes</a></li><li><a href="#auto10">Suggestions</a></li><li><a href="#auto11">__all__</a></li></ol></div>
<div class="content">
<span/>
<h2>Allowable Tags<a name="auto0"/></h2>
<p>Please try to restrict your HTML usage to the following tags (all only for the original logical purpose, and not whatever visual effect you see): <code>&lt;html&gt;</code>, <code>&lt;title&gt;</code>, <code>&lt;head&gt;</code>, <code>&lt;body&gt;</code>, <code>&lt;h1&gt;</code>, <code>&lt;h2</code>, <code>&lt;h3&gt;</code>, <code>&lt;ol&gt;</code>, <code>&lt;ul&gt;</code>, <code>&lt;dl&gt;</code>, <code>&lt;li&gt;</code>, <code>&lt;dt&gt;</code>, <code>&lt;dd&gt;</code>, <code>&lt;p&gt;</code>, <code>&lt;code&gt;</code>, <code>&lt;img&gt;</code>, <code>&lt;blockquote&gt;</code>, <code>&lt;a&gt;</code>, <code>&lt;cite&gt;</code>, <code>&lt;div&gt;</code>, <code>&lt;span&gt;</code>, <code>&lt;strong&gt;</code>, <code>&lt;em&gt;</code>, <code>&lt;pre&gt;</code>, <code>&lt;q&gt;</code>, <code>&lt;table&gt;</code>,<code>&lt;tr&gt;</code>, <code>&lt;td&gt;</code> and <code>&lt;th&gt;</code>.</p>
<p>Please avoid using the quote sign (<code>&quot;</code>) for quoting, and use the relevant html tags (<code>&lt;q&gt;&lt;/q&gt;</code>) -- it is impossible to distinguish right and left quotes with the quote sign, and some more sophisticated output methods work better with that distinction.</p>
<h2>Multi-line Code Snippets<a name="auto1"/></h2>
<p>Multi-line code snippets should be delimited with a
&lt;pre&gt; tag, with a mandatory <q>class</q> attribute. The
conventionalized classes are <q>python</q>, <q>python-interpreter</q>,
and <q>shell</q>. For example:</p>
<h3><q>python</q><a name="auto2"/></h3>
<pre xml:space="preserve">
&lt;p&gt;
For example, this is how one defines a Resource:
&lt;/p&gt;
&lt;pre class=&quot;python&quot;&gt;
from twisted.web import resource
class MyResource(resource.Resource):
def render_GET(self, request):
return &quot;Hello, world!&quot;
&lt;/pre&gt;
</pre>
<p>For example, this is how one defines a Resource:</p>
<pre class="python"><p class="py-linenumber">1
2
3
4
5
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">web</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">resource</span>
<span class="py-src-keyword">class</span> <span class="py-src-identifier">MyResource</span>(<span class="py-src-parameter">resource</span>.<span class="py-src-parameter">Resource</span>):
<span class="py-src-keyword">def</span> <span class="py-src-identifier">render_GET</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">request</span>):
<span class="py-src-keyword">return</span> <span class="py-src-string">&quot;Hello, world!&quot;</span>
</pre>
<p>Note that you should never have leading indentation inside a
&lt;pre&gt; block -- this makes it hard for readers to
copy/paste the code.</p>
<h3><q>python-interpreter</q><a name="auto3"/></h3>
<pre xml:space="preserve">
&lt;pre class=&quot;python-interpreter&quot;&gt;
&amp;gt;&amp;gt;&amp;gt; from twisted.web import resource
&amp;gt;&amp;gt;&amp;gt; class MyResource(resource.Resource):
... def render_GET(self, request):
... return &quot;Hello, world!&quot;
...
&amp;gt;&amp;gt;&amp;gt; MyResource().render_GET(None)
&quot;Hello, world!&quot;
&lt;/pre&gt;
</pre>
<pre class="python-interpreter" xml:space="preserve">
&gt;&gt;&gt; from twisted.web import resource
&gt;&gt;&gt; class MyResource(resource.Resource):
... def render_GET(self, request):
... return &quot;Hello, world!&quot;
...
&gt;&gt;&gt; MyResource().render_GET(None)
&quot;Hello, world!&quot;
</pre>
<h3><q>shell</q><a name="auto4"/></h3>
<pre xml:space="preserve">
&lt;pre class=&quot;shell&quot;&gt;
$ twistd web --path /var/www
&lt;/pre&gt;
</pre>
<pre class="shell" xml:space="preserve">
$ twistd web --path /var/www
</pre>
<h2>Code inside paragraph text<a name="auto5"/></h2>
<p>For single-line code-snippets and attribute, method, class,
and module names, use the &lt;code&gt; tag, with a class of
<q>API</q> or <q>python</q>. During processing, module or class-names
with class <q>API</q> will automatically be looked up in the API
reference and have a link placed around it referencing the
actual API documents for that module/classname. If you wish to
reference an API document, then make sure you at least have a
single module-name so that the processing code will be able to
figure out which module or class you're referring to.</p>
<p>You may also use the <code>base</code> attribute in conjuction
with a class of <q>API</q> to indicate the module that should be prepended
to the module or classname. This is to help keep the documentation
clearer and less cluttered by allowing links to API docs that don't
need the module name.</p>
<pre xml:space="preserve">
&lt;p&gt;
To add a &lt;code class=&quot;API&quot;&gt;twisted.web.widgets.Widget&lt;/code&gt;
instance to a &lt;code class=&quot;API&quot;
base=&quot;twisted.web.widgets&quot;&gt;Gadget&lt;/code&gt; instance, do
&lt;code class=&quot;python&quot;&gt;myGadget.putWidget(&quot;widgetPath&quot;,
MyWidget())&lt;/code&gt;.
&lt;/p&gt;
&lt;p&gt;
(implementation note: the widgets are stored in the &lt;code
class=&quot;python&quot;&gt;gadgetInstance.widgets&lt;/code&gt; attribute,
which is a
list.)
&lt;/p&gt;
</pre>
<div class="boxed">
<p>
To add a <code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.web.widgets.Widget.html" title="twisted.web.widgets.Widget">twisted.web.widgets.Widget</a></code>
instance to a <code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.web.widgets.Gadget.html" title="twisted.web.widgets.Gadget">Gadget</a></code>
instance, do
<code class="python">myGadget.putWidget(&quot;widgetPath&quot;, MyWidget())</code>.
</p>
<p>
(implementation note: the widgets are stored in the <code class="python">gadgetInstance.widgets</code> attribute,
which is a
list.)
</p>
</div>
<h2>Headers<a name="auto6"/></h2>
<p>It goes without mentioning that you should use &lt;hN&gt; in
a sane way -- &lt;h1&gt; should only appear once in the
document, to specify the title. Sections of the document should
use &lt;h2&gt;, sub-headers &lt;h3&gt;, and so on.</p>
<h2>XHTML<a name="auto7"/></h2>
<p>XHTML is mandatory. That means tags that don't have a
closing tag need a <q>/</q>; for example, <code>&lt;hr /&gt;</code>
. Also, tags which have <q>optional</q> closing tags in HTML
<em>need</em> to be closed in XHTML; for example,
<code>&lt;li&gt;foo&lt;/li&gt;</code></p>
<h2>Tag Case<a name="auto8"/></h2>
<p>All tags will be done in lower-case. XHTML demands this, and
so do I. :-)</p>
<h2>Footnotes<a name="auto9"/></h2>
<p>Footnotes are enclosed inside
<code>&lt;span class=&quot;footnote&quot;&gt;&lt;/span&gt;</code>. They must not
contain any markup.</p>
<h2>Suggestions<a name="auto10"/></h2>
<p>Use <code class="shell">lore -o lint</code> to check your documentation
is not broken. <code class="shell">lore -o lint</code> will never change
your HTML, but it will complain if it doesn't like it.</p>
<p>Don't use tables for formatting. 'nuff said.</p>
<h2>__all__<a name="auto11"/></h2>
<p><code class="python">__all__</code> is a module level list of strings, naming
objects in the module that are public. Make sure publically exported classes,
functions and constants are listed here.</p>
</div>
<p><a href="../../howto/index.html">Index</a></p>
<span class="version">Version: 10.0.0</span>
</body>
</html>

View File

@@ -1,33 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Twisted Documentation: Twisted Development Policy</title>
<link href="../../howto/stylesheet.css" rel="stylesheet" type="text/css"/>
</head>
<body bgcolor="white">
<h1 class="title">Twisted Development Policy</h1>
<div class="toc"><ol/></div>
<div class="content">
<span/>
<p>
This series of documents is designed for people who wish to contribute to the
Twisted codebase.
</p>
<ul>
<li><a href="coding-standard.html" shape="rect">Coding standard</a></li>
<li><a href="doc-standard.html" shape="rect">Documentation standard</a></li>
<li><a href="writing-standard.html" shape="rect">Documentation writing standard</a></li>
<li><a href="test-standard.html" shape="rect">Testing standard</a></li>
<li><a href="svn-dev.html" shape="rect">Working from Twisted's Subversion
repository</a></li>
</ul>
</div>
<p><a href="../../howto/index.html">Index</a></p>
<span class="version">Version: 10.0.0</span>
</body>
</html>

View File

@@ -1,227 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Twisted Documentation: Working from Twisted's Subversion repository</title>
<link href="../../howto/stylesheet.css" rel="stylesheet" type="text/css"/>
</head>
<body bgcolor="white">
<h1 class="title">Working from Twisted's Subversion repository</h1>
<div class="toc"><ol><li><a href="#auto0">Checkout</a></li><li><a href="#auto1">Alternate tree names</a></li><li><a href="#auto2">Combinator</a></li><li><a href="#auto3">Compiling C extensions</a></li><li><a href="#auto4">Running tests</a></li><li><a href="#auto5">Building docs</a></li><li><a href="#auto6">Committing and Post-commit Hooks</a></li><li><a href="#auto7">Emacs</a></li><li><a href="#auto8">Building Debian packages</a></li></ol></div>
<div class="content">
<span/>
<p>If you're going to be doing development on Twisted itself, or if you want
to take advantage of bleeding-edge features (or bug fixes) that are not yet
available in a numbered release, you'll probably want to check out a tree from
the Twisted Subversion repository. The Trunk is where all current development
takes place.</p>
<p>This document lists some useful tips for working on this cutting
edge.</p>
<h2>Checkout<a name="auto0"/></h2>
<p>Subversion tutorials can be found elsewhere, see in particular <a href="http://subversion.tigris.org/" shape="rect">the Subversion homepage</a>. The relevant
data you need to check out a copy of the Twisted tree is available on the <a href="http://twistedmatrix.com/trac/wiki/TwistedDevelopment" shape="rect">development page
</a>, and is as follows:</p>
<pre class="shell" xml:space="preserve">
$ svn co svn://svn.twistedmatrix.com/svn/Twisted/trunk Twisted
</pre>
<h2>Alternate tree names<a name="auto1"/></h2>
<p>By using <code>svn co svn://svn.twistedmatrix.com/svn/Twisted/trunk
otherdir</code>, you can put the workspace tree in a directory other than
<q>Twisted</q>. I do this (with a name like <q>Twisted-Subversion</q>) to
remind myself that this tree comes from Subversion and not from a released
version (like <q>Twisted-1.0.5</q>). This practice can cause a few problems,
because there are a few places in the Twisted tree that need to know where
the tree starts, so they can add it to <code>sys.path</code> without
requiring the user manually set their PYTHONPATH. These functions walk the
current directory up to the root, looking for a directory named
<q>Twisted</q> (sometimes exactly that, sometimes with a
<code>.startswith</code> test). Generally these are test scripts or other
administrative tools which expect to be launched from somewhere inside the
tree (but not necessarily from the top).</p>
<p>If you rename the tree to something other than <code>Twisted</code>, these
tools may wind up trying to use Twisted source files from /usr/lib/python2.5
or elsewhere on the default <code>sys.path</code>. Normally this won't
matter, but it is good to be aware of the issue in case you run into
problems.</p>
<p><code>twisted/test/process_twisted.py</code> is one of these programs.</p>
<h2>Combinator<a name="auto2"/></h2>
<p>In order to simplify the use of Subversion, we typically use
<a href="http://divmod.org/trac/wiki/DivmodCombinator" shape="rect">Divmod Combinator</a>.
You may find it to be useful, too. In particular, because Twisted uses
branches for almost all feature development, if you plan to contribute to
Twisted you will probably find Combinator very useful. For more details,
see the Combinator website, as well as the
<a href="http://divmod.org/trac/wiki/UltimateQualityDevelopmentSystem" shape="rect">
UQDS</a> page.</p>
<h2>Compiling C extensions<a name="auto3"/></h2>
<p>
There are currently several C extension modules in Twisted:
twisted.protocols._c_urlarg, twisted.internet.cfsupport,
twisted.internet.iocpreactor._iocp, and twisted.python._epoll. These modules
are optional, but you'll have to compile them if you want to experience their
features, performance improvements, or bugs. There are two approaches.
</p>
<p>The first is to do a regular distutils <code>./setup.py build</code>, which
will create a directory under <code>build/</code> to hold both the generated
<code>.so</code> files as well as a copy of the 600-odd <code>.py</code> files
that make up Twisted. If you do this, you will need to set your PYTHONPATH to
something like <code>MyDir/Twisted/build/lib.linux-i686-2.5</code> in order to
run code against the Subversion twisted (as opposed to whatever's installed in
<code>/usr/lib/python2.5</code> or wherever python usually looks). In
addition, you will need to re-run the <code>build</code> command <em>every
time</em> you change a <code>.py</code> file. The <code>build/lib.foo</code>
directory is a copy of the main tree, and that copy is only updated when you
re-run <code>setup.py build</code>. It is easy to forget this and then wonder
why your code changes aren't being expressed.</p>
<p>The second technique is to build the C modules in place, and point your
PYTHONPATH at the top of the tree, like <code>MyDir/Twisted</code>. This way
you're using the .py files in place too, removing the confusion a forgotten
rebuild could cause with the separate build/ directory above. To build the C
modules in place, do <code>./setup.py build_ext -i</code>. You only need to
re-run this command when you change the C files. Note that
<code>setup.py</code> is not Make, it does not always get the dependencies
right (<code>.h</code> files in particular), so if you are hacking on the
cReactor you may need to manually delete the <code>.o</code> files before
doing a rebuild. Also note that doing a <code>setup.py clean</code> will
remove the <code>.o</code> files but not the final <code>.so</code> files,
they must be deleted by hand.</p>
<h2>Running tests<a name="auto4"/></h2>
<p>To run the full unit-test suite, do:</p>
<pre class="shell" xml:space="preserve">./bin/trial twisted</pre>
<p>To run a single test file (like <code>twisted/test/test_defer.py</code>),
do one of:</p>
<pre class="shell" xml:space="preserve">./bin/trial twisted.test.test_defer</pre>
<p>or</p>
<pre class="shell" xml:space="preserve">./bin/trial twisted/test/test_defer.py</pre>
<p>To run any tests that are related to a code file, like
<code>twisted/protocols/imap4.py</code>, do:</p>
<pre class="shell" xml:space="preserve">./bin/trial --testmodule twisted/mail/imap4.py</pre>
<p>This depends upon the <code>.py</code> file having an appropriate
<q>test-case-name</q> tag that indicates which test cases provide coverage.
See the <a href="test-standard.html" shape="rect">Test Standards</a> document for
details about using <q>test-case-name</q>. In this example, the
<code>twisted.mail.test.test_imap</code> test will be run.</p>
<p>Many tests create temporary files in /tmp or ./_trial_temp, but
everything in /tmp should be deleted when the test finishes. Sometimes these
cleanup calls are commented out by mistake, so if you see a stray
/tmp/@12345.1 directory, it is probably from test_dirdbm or test_popsicle.
Look for an <code>rmtree</code> that has been commented out and complain to
the last developer who touched that file.</p>
<h2>Building docs<a name="auto5"/></h2>
<p>Twisted documentation (not including the automatically-generated API docs)
is in <a href="http://twistedmatrix.com/trac/wiki/TwistedLore" shape="rect">Lore Format</a>.
These <code>.xhtml</code> files are translated into <code>.html</code> files by
the <q>bin/lore/lore</q> script, which can check the files for syntax problems
(hlint), process multiple files at once, insert the files into a template
before processing, and can also translate the files into LaTeX or PostScript
instead.</p>
<p>To build the HTML form of the howto/ docs, do the following. Note that
the index file will be placed in <code>doc/howto/index.html</code>.</p>
<pre class="shell" xml:space="preserve">
./bin/lore/lore -p --config template=doc/howto/template.tpl doc/howto/*.xhtml
</pre>
<p>To run hlint over a single Lore document, such as
<code>doc/development/policy/svn-dev.xhtml</code>, do the following. This is
useful because the HTML conversion may bail without a useful explanation if
it sees mismatched tags.</p>
<pre class="shell" xml:space="preserve">
./bin/lore/lore -n --output lint doc/development/policy/svn-dev.xhtml
</pre>
<p>To convert it to HTML (including markup, interpolation of examples,
footnote processing, etc), do the following. The results will be placed in
<code>doc/development/policy/svn-dev.html</code>:</p>
<pre class="shell" xml:space="preserve">
./bin/lore/lore -p --config template=doc/howto/template.tpl \
doc/development/policy/svn-dev.xhtml
</pre>
<p>Note that hyperlinks to other documents may not be quite right unless you
include a <q>-l</q> argument to <code>bin/lore/lore</code>. Links in the
.xhtml file are to .xhtml targets: when the .xhtml is turned into .html, the
link targets are supposed to be turned into .html also. In addition to this,
Lore markup of the form &lt;code class=&quot;API&quot;&gt; is supposed to
turn into a link to the corresponding API reference page. These links will
probably be wrong unless the correct base URL is provided to Lore.</p>
<h2>Committing and Post-commit Hooks<a name="auto6"/></h2>
<p>Twisted uses a customized
<a href="http://bazaar.launchpad.net/~exarkun/twisted-trac-integration/trunk/annotate/head%3A/trac-hooks/trac-post-commit-hook" shape="rect">
trac-post-commit-hook</a> to enable ticket updates based on svn commit
logs. When making a branch for a ticket, the branch name should end
in <code>-&lt;ticket number&gt;</code>, for
example <code>my-branch-9999</code>. This will add a ticket comment containing a
changeset link and branch name. To make your commit message show up as a comment
on a Trac ticket, add a <code>refs #&lt;ticket number&gt;</code> line at the
bottom of your commit message. To automatically close a ticket on Trac
as <code>Fixed</code> and add a comment with the closing commit message, add
a <code>Fixes: #&lt;ticket number&gt;</code> line to your commit message. In
general, a commit message closing a ticket looks like this:</p>
<pre xml:space="preserve">
Merge my-branch-9999: A single-line summary.
Author: jesstess
Reviewers: exarkun, glyph
Fixes: #9999
My longer description of the changes made.
</pre>
<p>The <a href="coding-standard.html#commits" shape="rect">Twisted Coding Standard</a>
elaborates on commit messages and source control.</p>
<h2>Emacs<a name="auto7"/></h2>
<p>A minor mode for development with Twisted using Emacs is available. See
<code>emacs/twisted-dev.el</code> for several utility functions which make
it easier to grep for methods, run test cases, etc.</p>
<h2>Building Debian packages<a name="auto8"/></h2>
<p>Our support for building Debian packages has fallen into disrepair. We
would very much like to restore this functionality, but until we do so, if
you are interested in this, you are on your own. See
<a href="http://stdeb.python-hosting.com/" shape="rect">stdeb</a> for one possible approach
to this.</p>
</div>
<p><a href="../../howto/index.html">Index</a></p>
<span class="version">Version: 10.0.0</span>
</body>
</html>

View File

@@ -1,362 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Twisted Documentation: Unit Tests in Twisted</title>
<link href="../../howto/stylesheet.css" rel="stylesheet" type="text/css"/>
</head>
<body bgcolor="white">
<h1 class="title">Unit Tests in Twisted</h1>
<div class="toc"><ol><li><a href="#auto0">Unit Tests in the Twisted Philosophy</a></li><li><a href="#auto1">What to Test, What Not to Test</a></li><li><a href="#auto2">Running the Tests</a></li><ul><li><a href="#auto3">How</a></li><li><a href="#auto4">When</a></li></ul><li><a href="#auto5">Adding a Test</a></li><li><a href="#auto6">Skipping tests, TODO items</a></li><ul><li><a href="#auto7">.todo and Testing New Functionality </a></li><li><a href="#auto8">Line Coverage Information</a></li></ul><li><a href="#auto9">Associating Test Cases With Source Files</a></li><li><a href="#auto10">Links</a></li></ol></div>
<div class="content">
<span/>
<p>Each <em>unit test</em> tests one bit of functionality in the
software. Unit tests are entirely automated and complete quickly.
Unit tests for the entire system are gathered into one test suite,
and may all be run in a single batch. The result of a unit test
is simple: either it passes, or it doesn't. All this means you
can test the entire system at any time without inconvenience, and
quickly see what passes and what fails.</p>
<h2>Unit Tests in the Twisted Philosophy<a name="auto0"/></h2>
<p>The Twisted development team
adheres to the practice of <a href="http://c2.com/cgi/wiki?ExtremeProgramming" shape="rect">Extreme
Programming</a> (XP), and the usage of unit tests is a cornerstone
XP practice. Unit tests are a tool to give you increased
confidence. You changed an algorithm -- did you break something?
Run the unit tests. If a test fails, you know where to look,
because each test covers only a small amount of code, and you know
it has something to do with the changes you just made. If all the
tests pass, you're good to go, and you don't need to second-guess
yourself or worry that you just accidently broke someone else's
program.</p>
<h2>What to Test, What Not to Test<a name="auto1"/></h2>
<blockquote><p>You don't have to write a test for every single
method you write, only production methods that could possibly break.</p>
</blockquote>
<p>-- Kent Beck, <cite>Extreme Programming Explained</cite>, p. 58.</p>
<h2>Running the Tests<a name="auto2"/></h2>
<h3>How<a name="auto3"/></h3>
<p>From the root of the Twisted source tree, run
<a href="http://twistedmatrix.com/trac/wiki/TwistedTrial" shape="rect">Trial</a>:
</p>
<pre class="shell" xml:space="preserve">
$ bin/trial twisted
</pre>
<p>You'll find that having something like this in your emacs init
files is quite handy:</p>
<pre class="elisp" xml:space="preserve">
(defun runtests () (interactive)
(compile &quot;python /somepath/Twisted/bin/trial /somepath/Twisted&quot;))
(global-set-key [(alt t)] 'runtests)
</pre>
<h3>When<a name="auto4"/></h3>
<p>Always, always, <em>always</em> be sure <a href="http://www.xprogramming.com/xpmag/expUnitTestsAt100.htm" shape="rect">all the
tests pass</a> before committing any code. If someone else
checks out code at the start of a development session and finds
failing tests, they will not be happy and may decide to <em>hunt
you down</em>.</p>
<p>Since this is a geographically dispersed team, the person who
can help you get your code working probably isn't in the room with
you. You may want to share your work in progress over the
network, but you want to leave the main Subversion tree in good working
order. So <a href="http://svnbook.red-bean.com/en/1.0/ch04.html" shape="rect">use a branch</a>,
and merge your changes back in only after your problem is solved
and all the unit tests pass again.</p>
<h2>Adding a Test<a name="auto5"/></h2>
<p>Please don't add new modules to Twisted without adding tests
for them too. Otherwise we could change something which breaks
your module and not find out until later, making it hard to know
exactly what the change that broke it was, or until after a
release, and nobody wants broken code in a release.</p>
<p>Tests go into dedicated test packages such as
<code>twisted/test/</code> or <code>twisted/conch/test/</code>,
and are named <code>test_foo.py</code>, where <code>foo</code> is the name
of the module or package being tested. Extensive documentation on using
the PyUnit framework for writing unit tests can be found in the
<a href="#links" shape="rect">links section</a> below.
</p>
<p>One deviation from the standard PyUnit documentation: To ensure
that any variations in test results are due to variations in the
code or environment and not the test process itself, Twisted ships
with its own, compatible, testing framework. That just
means that when you import the unittest module, you will <code class="python">from twisted.trial import unittest</code> instead of the
standard <code class="python">import unittest</code>.</p>
<p>As long as you have followed the module naming and placement
conventions, <code class="shell">trial</code> will be smart
enough to pick up any new tests you write.</p>
<p>PyUnit provides a large number of assertion methods to be used when
writing tests. Many of these are redundant. For consistency, Twisted
unit tests should use the <code>assert</code> forms rather than the
<code>fail</code> forms. Also, use <code>assertEquals</code>,
<code>assertNotEquals</code>, and <code>assertAlmostEquals</code> rather
than <code>assertEqual</code>, <code>assertNotEqual</code>, and
<code>assertAlmostEqual</code>. <code>assertTrue</code> is also
preferred over <code>assert_</code>. You may notice this convention is
not followed everywhere in the Twisted codebase. If you are changing
some test code and notice the wrong method being used in nearby code,
feel free to adjust it.</p>
<p>When you add a unit test, make sure all methods have docstrings
specifying at a high level the intent of the test. That is, a description
that users of the method would understand.</p>
<h2>Skipping tests, TODO items<a name="auto6"/></h2>
<p>Trial, the Twisted unit test framework, has some extensions which are
designed to encourage developers to add new tests. One common situation is
that a test exercises some optional functionality: maybe it depends upon
certain external libraries being available, maybe it only works on certain
operating systems. The important common factor is that nobody considers
these limitations to be a bug.</p>
<p>To make it easy to test as much as possible, some tests may be skipped in
certain situations. Individual test cases can raise the
<code>SkipTest</code> exception to indicate that they should be skipped, and
the remainder of the test is not run. In the summary (the very last thing
printed, at the bottom of the test output) the test is counted as a
<q>skip</q> instead of a <q>success</q> or <q>fail</q>. This should be used
inside a conditional which looks for the necessary prerequisites:</p>
<pre class="python"><p class="py-linenumber">1
2
3
4
</p><span class="py-src-keyword">def</span> <span class="py-src-identifier">test_sshClient</span>(<span class="py-src-parameter">self</span>):
<span class="py-src-keyword">if</span> <span class="py-src-keyword">not</span> <span class="py-src-variable">ssh_path</span>:
<span class="py-src-keyword">raise</span> <span class="py-src-variable">unittest</span>.<span class="py-src-variable">SkipTest</span>(<span class="py-src-string">&quot;cannot find ssh, nothing to test&quot;</span>)
<span class="py-src-variable">foo</span>() <span class="py-src-comment"># do actual test after the SkipTest</span>
</pre>
<p>You can also set the <code>.skip</code> attribute on the method, with a string to
indicate why the test is being skipped. This is convenient for temporarily
turning off a test case, but it can also be set conditionally (by
manipulating the class attributes after they've been defined):</p>
<pre class="python"><p class="py-linenumber">1
2
3
</p><span class="py-src-keyword">def</span> <span class="py-src-identifier">test_thing</span>(<span class="py-src-parameter">self</span>):
<span class="py-src-variable">dotest</span>()
<span class="py-src-variable">test_thing</span>.<span class="py-src-variable">skip</span> = <span class="py-src-string">&quot;disabled locally&quot;</span>
</pre>
<pre class="python"><p class="py-linenumber">1
2
3
4
5
6
7
8
9
</p><span class="py-src-keyword">class</span> <span class="py-src-identifier">MyTestCase</span>(<span class="py-src-parameter">unittest</span>.<span class="py-src-parameter">TestCase</span>):
<span class="py-src-keyword">def</span> <span class="py-src-identifier">test_one</span>(<span class="py-src-parameter">self</span>):
...
<span class="py-src-keyword">def</span> <span class="py-src-identifier">test_thing</span>(<span class="py-src-parameter">self</span>):
<span class="py-src-variable">dotest</span>()
<span class="py-src-keyword">if</span> <span class="py-src-keyword">not</span> <span class="py-src-variable">haveThing</span>:
<span class="py-src-variable">MyTestCase</span>.<span class="py-src-variable">test_thing</span>.<span class="py-src-variable">im_func</span>.<span class="py-src-variable">skip</span> = <span class="py-src-string">&quot;cannot test without Thing&quot;</span>
<span class="py-src-comment"># but test_one() will still run</span>
</pre>
<p>Finally, you can turn off an entire TestCase at once by setting the .skip
attribute on the class. If you organize your tests by the functionality they
depend upon, this is a convenient way to disable just the tests which cannot
be run.</p>
<pre class="python"><p class="py-linenumber">1
2
3
4
5
6
7
</p><span class="py-src-keyword">class</span> <span class="py-src-identifier">TCPTestCase</span>(<span class="py-src-parameter">unittest</span>.<span class="py-src-parameter">TestCase</span>):
...
<span class="py-src-keyword">class</span> <span class="py-src-identifier">SSLTestCase</span>(<span class="py-src-parameter">unittest</span>.<span class="py-src-parameter">TestCase</span>):
<span class="py-src-keyword">if</span> <span class="py-src-keyword">not</span> <span class="py-src-variable">haveSSL</span>:
<span class="py-src-variable">skip</span> = <span class="py-src-string">&quot;cannot test without SSL support&quot;</span>
<span class="py-src-comment"># but TCPTestCase will still run</span>
...
</pre>
<h3>.todo and Testing New Functionality <a name="auto7"/></h3>
<p>Two good practices which arise from the <q>XP</q> development process are
sometimes at odds with each other:</p>
<ul>
<li>Unit tests are a good thing. Good developers recoil in horror when
they see a failing unit test. They should drop everything until the test
has been fixed.</li>
<li>Good developers write the unit tests first. Once tests are done, they
write implementation code until the unit tests pass. Then they stop.</li>
</ul>
<p>These two goals will sometimes conflict. The unit tests that are written
first, before any implementation has been done, are certain to fail. We want
developers to commit their code frequently, for reliability and to improve
coordination between multiple people working on the same problem together.
While the code is being written, other developers (those not involved in the
new feature) should not have to pay attention to failures in the new code.
We should not dilute our well-indoctrinated Failing Test Horror Syndrome by
crying wolf when an incomplete module has not yet started passing its unit
tests. To do so would either teach the module author to put off writing or
committing their unit tests until <em>after</em> all the functionality is
working, or it would teach the other developers to ignore failing test
cases. Both are bad things.</p>
<p><q>.todo</q> is intended to solve this problem. When a developer first
starts writing the unit tests for functionality that has not yet been
implemented, they can set the <code>.todo</code> attribute on the test
methods that are expected to fail. These methods will still be run, but
their failure will not be counted the same as normal failures: they will go
into an <q>expected failures</q> category. Developers should learn to treat
this category as a second-priority queue, behind actual test failures.</p>
<p>As the developer implements the feature, the tests will eventually start
passing. This is surprising: after all those tests are marked as being
expected to fail. The .todo tests which nevertheless pass are put into a
<q>unexpected success</q> category. The developer should remove the .todo
tag from these tests. At that point, they become normal tests, and their
failure is once again cause for immediate action by the entire development
team.</p>
<p>The life cycle of a test is thus:</p>
<ol>
<li>Test is created, marked <code>.todo</code>. Test fails: <q>expected
failure</q>.</li>
<li>Code is written, test starts to pass. <q>unexpected success</q>.</li>
<li><code>.todo</code> tag is removed. Test passes. <q>success</q>.</li>
<li>Code is broken, test starts to fail. <q>failure</q>. Developers spring
into action.</li>
<li>Code is fixed, test passes once more. <q>success</q>.</li>
</ol>
<p>Any test which remains marked with <code>.todo</code> for too long should
be examined. Either it represents functionality which nobody is working on,
or the test is broken in some fashion and needs to be fixed. Generally,
<code>.todo</code> may be of use while you are developing a feature, but
by the time you are ready to commit anything, all the tests you have written
should be passing. In other words, you should rarely, if ever, feel the need
to add a test marked todo to trunk. When you do, consider whether a ticket
in the issue tracker would be more useful.</p>
<h3>Line Coverage Information<a name="auto8"/></h3>
<p>Trial provides line coverage information, which is very useful to ensure
old code has decent coverage. Passing the <code>--coverage</code> option to
to Trial will generate the coverage information in a file called
<code>coverage</code> which can be found in the <code>_trial_temp</code>
folder. This option requires Python 2.3.3 or newer.</p>
<h2>Associating Test Cases With Source Files<a name="auto9"/></h2>
<p>Please add a <code>test-case-name</code> tag to the source file that is
covered by your new test. This is a comment at the beginning of the file
which looks like one of the following:</p>
<pre class="python"><p class="py-linenumber">1
</p><span class="py-src-comment"># -*- test-case-name: twisted.test.test_defer -*-</span>
</pre>
<p>or</p>
<pre class="python"><p class="py-linenumber">1
2
</p><span class="py-src-comment">#!/usr/bin/env python</span>
<span class="py-src-comment"># -*- test-case-name: twisted.test.test_defer -*-</span>
</pre>
<p>This format is understood by emacs to mark <q>File Variables</q>. The
intention is to accept <code>test-case-name</code> anywhere emacs would on
the first or second line of the file (but not in the <code>File
Variables:</code> block that emacs accepts at the end of the file). If you
need to define other emacs file variables, you can either put them in the
<code>File Variables:</code> block or use a semicolon-separated list of
variable definitions:</p>
<pre class="python"><p class="py-linenumber">1
</p><span class="py-src-comment"># -*- test-case-name: twisted.test.test_defer; fill-column: 75; -*-</span>
</pre>
<p>If the code is exercised by multiple test cases, those may be marked by
using a comma-separated list of tests, as follows: (NOTE: not all tools can
handle this yet.. <code>trial --testmodule</code> does, though)</p>
<pre class="python"><p class="py-linenumber">1
</p><span class="py-src-comment"># -*- test-case-name: twisted.test.test_defer,twisted.test.test_tcp -*-</span>
</pre>
<p>The <code>test-case-name</code> tag will allow <code class="shell">trial
--testmodule twisted/dir/myfile.py</code> to determine which test cases need
to be run to exercise the code in <code>myfile.py</code>. Several tools (as
well as <code>twisted-dev.el</code>'s F9 command) use this to automatically
run the right tests.</p>
<h2 id="links">Links<a name="auto10"/></h2><a name="links" shape="rect"/>
<ul>
<li>A chapter on <a href="http://diveintopython.org/unit_testing/index.html" shape="rect">Unit Testing</a>
in Mark Pilgrim's <a href="http://diveintopython.org" shape="rect">Dive Into
Python</a>.</li>
<li><a href="http://docs.python.org/lib/module-unittest.html" shape="rect"><code>unittest</code></a> module documentation, in the <a href="http://docs.python.org/library" shape="rect">Python Library
Reference</a>.</li>
<li><a href="http://c2.com/cgi/wiki?UnitTests" shape="rect">UnitTests</a> on
the <a href="http://c2.com/cgi/wiki" shape="rect">PortlandPatternRepository
Wiki</a>, where all the cool <a href="http://c2.com/cgi/wiki?ExtremeProgramming" shape="rect">ExtremeProgramming</a> kids hang out.</li>
<li><a href="http://www.extremeprogramming.org/rules/unittests.html" shape="rect">Unit
Tests</a> in <a href="http://www.extremeprogramming.org" shape="rect">Extreme Programming: A Gentle Introduction</a>.</li>
<li>Ron Jeffries expounds on the importance of <a href="http://www.xprogramming.com/xpmag/expUnitTestsAt100.htm" shape="rect">Unit
Tests at 100%</a>.</li>
<li>Ron Jeffries writes about the <a href="http://www.xprogramming.com/Practices/PracUnitTest.html" shape="rect">Unit
Test</a> in the <a href="http://www.xprogramming.com/Practices/xpractices.htm" shape="rect">Extreme
Programming practices of C3</a>.</li>
<li><a href="http://pyunit.sourceforge.net" shape="rect">PyUnit's homepage</a>.</li>
<li>The <a href="http://svn.twistedmatrix.com/cvs/trunk/twisted/?root=Twisted" shape="rect">twisted/test directory</a> in Subversion.</li>
</ul>
<p>See also <a href="../../howto/testing.html" shape="rect">Tips for writing tests for Twisted
code</a>.</p>
</div>
<p><a href="../../howto/index.html">Index</a></p>
<span class="version">Version: 10.0.0</span>
</body>
</html>

View File

@@ -1,313 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Twisted Documentation: Twisted Writing Standard</title>
<link href="../../howto/stylesheet.css" rel="stylesheet" type="text/css"/>
</head>
<body bgcolor="white">
<h1 class="title">Twisted Writing Standard</h1>
<div class="toc"><ol><li><a href="#auto0">General style</a></li><li><a href="#auto1">Evangelism and usage documents</a></li><li><a href="#auto2">Descriptions of features</a></li><li><a href="#auto3">Linking</a></li><li><a href="#auto4">Introductions</a></li><ul><li><a href="#auto5">Introductory paragraph</a></li><li><a href="#auto6">Description of target audience</a></li><li><a href="#auto7">Goals of document</a></li></ul><li><a href="#auto8">Example code</a></li><li><a href="#auto9">Conclusions</a></li></ol></div>
<div class="content">
<span/>
<p>The Twisted writing standard describes the documentation writing
styles we prefer in our documentation. This standard applies particularly
to howtos and other descriptive documentation.</p>
<p>This document should be read with the <a href="doc-standard.html" shape="rect">documentation standard</a>, which describes
markup style for the documentation.</p>
<p>This document is meant to help Twisted documentation authors produce
documentation that does not have the following problems:</p>
<ul>
<li>misleads users about what is good Twisted style;</li>
<li>misleads users into thinking that an advanced howto is an introduction
to writing their first Twisted server; and</li>
<li>misleads users about whether they fit the document's target audience:
for example, that they are able to use enterprise without knowing how to
write SQL queries.</li>
</ul>
<h2>General style<a name="auto0"/></h2>
<p>Documents should aim to be clear and concise, allowing the API
documentation and the example code to tell as much of the story as they
can. Demonstrations and where necessary supported arguments should always
preferred to simple statements (&quot;here is how you would simplify this
code with Deferreds&quot; rather than &quot;Deferreds make code
simpler&quot;).</p>
<p>Documents should be clearly delineated into sections and subsections.
Each of these sections, like the overall document, should have a single
clear purpose. This is most easily tested by trying to have meaningful
headings: a section which is headed by &quot;More details&quot; or
&quot;Advanced stuff&quot; is not purposeful enough. There should be
fairly obvious ways to split a document. The two most common are task
based sectioning and sectioning which follows module and class
separations.</p>
<p>Documentation must use American English spelling, and where possible
avoid any local variants of either vocabulary or grammar. Grammatically
complex sentences should ideally be avoided: these make reading
unnecessarily difficult, particularly for non-native speakers.</p>
<h2>Evangelism and usage documents<a name="auto1"/></h2>
<p>The Twisted documentation should maintain a reasonable distinction
between &quot;evangelism&quot; documentation, which compares the Twisted
design or Twisted best practice with other approaches and argues for the
Twisted approach, and &quot;usage&quot; documentation, which describes the
Twisted approach in detail without comparison to other possible
approaches.</p>
<p>While both kinds of documentation are useful, they have different
audiences. The first kind of document, evangelical documents, is useful to
a reader who is researching and comparing approaches and seeking to
understand the Twisted approach or Twisted functionality in order to
decide whether it is useful to them. The second kind of document, usage
documents, are useful to a reader who has decided to use Twisted and
simply wants further information about available functions and
architectures they can use to accomplish their goal.</p>
<p>Since they have distinct audiences, evangelism and detailed usage
documentation belongs in separate files. There should be links between
them in 'Further reading' or similar sections.</p>
<h2>Descriptions of features<a name="auto2"/></h2>
<p>Descriptions of any feature added since release 2.0 of Twisted core
must have a note describing which release of which Twisted project they
were added in at the first mention in each document. If they are not yet
released, give them the number of the next minor release.</p>
<p>For example, a substantial change might have a version number added in
the introduction:</p>
<blockquote>
This document describes the Application infrastructure for deploying
Twisted applications <em>(added in Twisted 1.3)</em>.
</blockquote>
<p>The version does not need to be mentioned elsewhere in the document
except for specific features which were added in subsequent releases,
which might should be mentioned separately.</p>
<blockquote>
The simplest way to create a <code>.tac</code> file, SuperTac <em>(added
in Twisted Core 99.7)</em>...</blockquote>
<p>In the case where the usage of a feature has substantially changed, the
number should be that of the release in which the current usage became
available. For example:</p>
<blockquote> This document describes the Application infrastructure for
deploying Twisted applications <em>(updated[/substantially updated] in Twisted
2.7)</em>. </blockquote>
<h2>Linking<a name="auto3"/></h2>
<p>The first occurrence of the name of any module, class or function should
always link to the API documents. Subsequent mentions may or may not link
at the author's discretion: discussions which are very closely bound to a
particular API should probably link in the first mention in the given
section.</p>
<p>Links between howtos are encouraged. Overview documents and tutorials
should always link to reference documents and in depth documents. These
documents should link among themselves wherever it's needed: if you're
tempted to re-describe the functionality of another module, you should
certainly link instead.</p>
<h2>Introductions<a name="auto4"/></h2>
<p>The introductory section of a Twisted howto should immediately follow
the top-level heading and precede any subheadings.</p>
<p>The following items should be present in the introduction to Twisted
howtos: the introductory paragraph and the description of the target
audience.</p>
<h3>Introductory paragraph<a name="auto5"/></h3>
<p>The introductory paragraph of a document should summarize what the
document is designed to present. It should use the both proper names for
the Twisted technologies and simple non-Twisted descriptions of the
technologies. For example, in this paragraph both the name of the technology
(&quot;Conch&quot;) and a description (&quot;SSH server&quot;) are used:</p>
<blockquote>
This document describes setting up a SSH server to serve data from the
file system using Conch, the Twisted SSH implementation.
</blockquote>
<p>The introductory paragraph should be relatively short, but should, like
the above, somewhere define the document's objective: what the reader
should be able to do using instructions in the document.</p>
<h3>Description of target audience<a name="auto6"/></h3>
<p>Subsequent paragraphs in the introduction should describe the target
audience of the document: who would want to read it, and what they should
know before they can expect to use your document. For example:</p>
<blockquote>
<p>
The target audience of this document is a Twisted user who has a set of
filesystem like data objects that they would like to make available to
authenticated users over SFTP.
</p>
<p>
Following the directions in this document will require that you are
familiar with managing authentication via the Twisted Cred system.
</p>
</blockquote>
<p>Use your discretion about the extent to which you list assumed
knowledge. Very introductory documents that are going to be among a
reader's first exposure to Twisted will even need to specify that they
rely on knowledge of Python and of certain networking concepts (ports,
servers, clients, connections) but documents that are going to be sought
out by existing Twisted users for particular purposes only need to specify
other Twisted knowledge that is assumed.</p>
<p>Any knowledge of technologies that wouldn't be considered &quot;core
Python&quot; and/or &quot;simple networking&quot; need to be explicitly
specified, no matter how obvious they seem to someone familiar with the
technology. For example, it needs to be stated that someone using
enterprise should know SQL and should know how to set up and populate
databases for testing purposes.</p>
<p>Where possible, link to other documents that will fill in missing
knowledge for the reader. Linking to documents in the Twisted repository
is preferred but not essential.</p>
<h3>Goals of document<a name="auto7"/></h3>
<p>The introduction should finish with a list of tasks that the user can
expect to see the document accomplish. These tasks should be concrete
rather than abstract, so rather than telling the user that they will
&quot;understand Twisted Conch&quot;, you would list the specific tasks
that they will see the document do. For example:</p>
<blockquote>
<p>
This document will demonstrate the following tasks using Twisted Conch:
</p>
<ul>
<li>creating an anonymous access read-only SFTP server using a filesystem
backend;</li>
<li>creating an anonymous access read-only SFTP server using a proxy
backend connecting to an HTTP server; and</li>
<li>creating a anonymous access read and write SFTP server using a
filesystem backend.</li>
</ul>
</blockquote>
<p>In many cases this will essentially be a list of your code examples,
but it need not be. If large sections of your code are devoted to design
discussions, your goals might resemble the following:</p>
<blockquote>
<p>
This document will discuss the following design aspects of writing Conch
servers:
</p>
<ul>
<li>authentication of users; and</li>
<li>choice of data backends.</li>
</ul>
</blockquote>
<h2>Example code<a name="auto8"/></h2>
<p>Wherever possible, example code should be provided to illustrate a
certain technique or piece of functionality.</p>
<p>Example code should try and meet as many of the following requirements
as possible:</p>
<ul>
<li>example code should be a complete working example suitable for copying
and pasting and running by the reader (where possible, provide a link to a
file to download);</li>
<li>example code should be short;</li>
<li>example code should be commented very extensively, with the assumption
that this code may be read by a Twisted newcomer;</li>
<li>example code should conform to the <a href="coding-standard.html" shape="rect">coding standard</a>; and</li>
<li>example code should exhibit 'best practice', not only for dealing with
the target functionality, but also for use of the application framework
and so on.</li>
</ul>
<p>The requirement to have a complete working example will occasionally
impose upon authors the need to have a few dummy functions: in Twisted
documentation the most common example is where a function is needed to
generate a Deferred and fire it after some time has passed. An example
might be this, where <code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.internet.task.deferLater.html" title="twisted.internet.task.deferLater">deferLater</a></code> is used to fire a callback
after a period of time:</p>
<pre class="python"><p class="py-linenumber">1
2
3
4
5
6
7
8
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">task</span>, <span class="py-src-variable">reactor</span>
<span class="py-src-keyword">def</span> <span class="py-src-identifier">getDummyDeferred</span>():
<span class="py-src-string">&quot;&quot;&quot;
Dummy method which returns a deferred that will fire in 5 seconds with
a result
&quot;&quot;&quot;</span>
<span class="py-src-keyword">return</span> <span class="py-src-variable">task</span>.<span class="py-src-variable">deferLater</span>(<span class="py-src-variable">reactor</span>, <span class="py-src-number">5</span>, <span class="py-src-keyword">lambda</span> <span class="py-src-variable">x</span>: <span class="py-src-string">&quot;RESULT&quot;</span>)
</pre>
<p>As in the above example, it is imperative to clearly mark that the
function is a dummy in as many ways as you can: using <code>Dummy</code> in
the function name, explaining that it is a dummy in the docstring, and
marking particular lines as being required to create an effect for the
purposes of demonstration. In most cases, this will save the reader from
mistaking this dummy method for an idiom they should use in their Twisted
code.</p>
<h2>Conclusions<a name="auto9"/></h2>
<p>The conclusion of a howto should follow the very last section heading
in a file. This heading would usually be called &quot;Conclusion&quot;.</p>
<p>The conclusion of a howto should remind the reader of the tasks that
they have done while reading the document. For example:</p>
<blockquote>
<p>
In this document, you have seen how to:
</p>
<ol>
<li>set up an anonymous read-only SFTP server;</li>
<li>set up a SFTP server where users authenticate;</li>
<li>set up a SFTP server where users are restricted to some parts of the
filesystem based on authentication; and</li>
<li>set up a SFTP server where users have write access to some parts of
the filesystem based on authentication.</li>
</ol>
</blockquote>
<p>If appropriate, the howto could follow this description with links to
other documents that might be of interest to the reader with their
newfound knowledge. However, these links should be limited to fairly
obvious extensions of at least one of the listed tasks.</p>
</div>
<p><a href="../../howto/index.html">Index</a></p>
<span class="version">Version: 10.0.0</span>
</body>
</html>

View File

@@ -1,43 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Twisted Documentation: Security</title>
<link href="../howto/stylesheet.css" rel="stylesheet" type="text/css"/>
</head>
<body bgcolor="white">
<h1 class="title">Security</h1>
<div class="toc"><ol><li><a href="#auto0">Bad input</a></li><li><a href="#auto1">Resource Exhaustion and DoS</a></li></ol></div>
<div class="content">
<span/>
<p>We need to do a full audit of Twisted, module by module.
This document list the sort of things you want to look for
when doing this, or when writing your own code.</p>
<h2>Bad input<a name="auto0"/></h2>
<p>Any place we receive untrusted data, we need to be careful.
In some cases we are not careful enough. For example, in HTTP
there are many places where strings need to be converted to
ints, so we use <code class="python">int()</code>. The problem
is that this well accept negative numbers as well, whereas
the protocol should only be accepting positive numbers.</p>
<h2>Resource Exhaustion and DoS<a name="auto1"/></h2>
<p>Make sure we never allow users to create arbitarily large
strings or files. Some of the protocols still have issues
like this. Place a limit which allows reasonable use but
will cut off huge requests, and allow changing of this limit.
</p>
<p>Another operation to look out for are exceptions. They can fill
up logs and take a lot of CPU time to render in web pages.</p>
</div>
<p><a href="../howto/index.html">Index</a></p>
<span class="version">Version: 10.0.0</span>
</body>
</html>

View File

@@ -1,26 +0,0 @@
from twisted.internet import reactor, defer
from twisted.internet.protocol import ClientCreator
from twisted.protocols import amp
from ampserver import Sum, Divide
def doMath():
d1 = ClientCreator(reactor, amp.AMP).connectTCP(
'127.0.0.1', 1234).addCallback(
lambda p: p.callRemote(Sum, a=13, b=81)).addCallback(
lambda result: result['total'])
def trapZero(result):
result.trap(ZeroDivisionError)
print "Divided by zero: returning INF"
return 1e1000
d2 = ClientCreator(reactor, amp.AMP).connectTCP(
'127.0.0.1', 1234).addCallback(
lambda p: p.callRemote(Divide, numerator=1234,
denominator=0)).addErrback(trapZero)
def done(result):
print 'Done with math:', result
defer.DeferredList([d1, d2]).addCallback(done)
if __name__ == '__main__':
doMath()
reactor.run()

View File

@@ -1,40 +0,0 @@
from twisted.protocols import amp
class Sum(amp.Command):
arguments = [('a', amp.Integer()),
('b', amp.Integer())]
response = [('total', amp.Integer())]
class Divide(amp.Command):
arguments = [('numerator', amp.Integer()),
('denominator', amp.Integer())]
response = [('result', amp.Float())]
errors = {ZeroDivisionError: 'ZERO_DIVISION'}
class Math(amp.AMP):
def sum(self, a, b):
total = a + b
print 'Did a sum: %d + %d = %d' % (a, b, total)
return {'total': total}
Sum.responder(sum)
def divide(self, numerator, denominator):
result = float(numerator) / denominator
print 'Divided: %d / %d = %f' % (numerator, denominator, result)
return {'result': result}
Divide.responder(divide)
def main():
from twisted.internet import reactor
from twisted.internet.protocol import Factory
pf = Factory()
pf.protocol = Math
reactor.listenTCP(1234, pf)
print 'started'
reactor.run()
if __name__ == '__main__':
main()

View File

@@ -1,79 +0,0 @@
# Copyright (c) 2001-2004 Twisted Matrix Laboratories.
# See LICENSE for details.
import sys
import time
try:
import cStringIO as StringIO
except ImportError:
import StringIO
# Twisted Imports
from twisted.spread import banana
from twisted.internet import protocol
iterationCount = 10000
class BananaBench:
r = range( iterationCount )
def setUp(self, encClass):
self.io = StringIO.StringIO()
self.enc = encClass()
self.enc.makeConnection(protocol.FileWrapper(self.io))
self.enc._selectDialect("none")
self.enc.expressionReceived = self.putResult
def putResult(self, result):
self.result = result
def tearDown(self):
self.enc.connectionLost()
del self.enc
def testEncode(self, value):
starttime = time.time()
for i in self.r:
self.enc.sendEncoded(value)
self.io.truncate(0)
endtime = time.time()
print ' Encode took %s seconds' % (endtime - starttime)
return endtime - starttime
def testDecode(self, value):
self.enc.sendEncoded(value)
encoded = self.io.getvalue()
starttime = time.time()
for i in self.r:
self.enc.dataReceived(encoded)
endtime = time.time()
print ' Decode took %s seconds' % (endtime - starttime)
return endtime - starttime
def performTest(self, method, data, encClass):
self.setUp(encClass)
method(data)
self.tearDown()
def runTests(self, testData):
print 'Test data is: %s' % testData
print ' Using Pure Python Banana:'
self.performTest(self.testEncode, testData, banana.Banana)
self.performTest(self.testDecode, testData, banana.Banana)
bench = BananaBench()
print 'Doing %s iterations of each test.' % iterationCount
print ''
testData = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
bench.runTests(testData)
testData = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0]
bench.runTests(testData)
testData = [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]]
bench.runTests(testData)
testData = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"]
bench.runTests(testData)
testData = [1l, 2l, 3l, 4l, 5l, 6l, 7l, 8l, 9l, 10l]
bench.runTests(testData)
testData = [1, 2, [3, 4], [30.5, 40.2], 5, ["six", "seven", ["eight", 9]], [10], []]
bench.runTests(testData)

View File

@@ -1,37 +0,0 @@
"""The most basic chat protocol possible.
run me with twistd -y chatserver.py, and then connect with multiple
telnet clients to port 1025
"""
from twisted.protocols import basic
class MyChat(basic.LineReceiver):
def connectionMade(self):
print "Got new client!"
self.factory.clients.append(self)
def connectionLost(self, reason):
print "Lost a client!"
self.factory.clients.remove(self)
def lineReceived(self, line):
print "received", repr(line)
for c in self.factory.clients:
c.message(line)
def message(self, message):
self.transport.write(message + '\n')
from twisted.internet import protocol
from twisted.application import service, internet
factory = protocol.ServerFactory()
factory.protocol = MyChat
factory.clients = []
application = service.Application("chatserver")
internet.TCPServer(1025, factory).setServiceParent(application)

View File

@@ -1,111 +0,0 @@
#!/usr/bin/env python
# Copyright (c) 2009 Twisted Matrix Laboratories.
# See LICENSE for details.
"""
Example of a interfacing to Courier's mail filter interface.
"""
LOGFILE = '/tmp/filter.log'
# Setup log file
from twisted.python import log
log.startLogging(open(LOGFILE, 'a'))
import sys
sys.stderr = log.logfile
# Twisted imports
from twisted.internet import reactor, stdio
from twisted.internet.protocol import Protocol, Factory
from twisted.protocols import basic
FILTERS='/var/lib/courier/filters'
ALLFILTERS='/var/lib/courier/allfilters'
FILTERNAME='twistedfilter'
import os, os.path
from syslog import syslog, openlog, LOG_MAIL
from rfc822 import Message
def trace_dump():
t,v,tb = sys.exc_info()
openlog(FILTERNAME, 0, LOG_MAIL)
syslog('Unhandled exception: %s - %s' % (v, t))
while tb:
syslog('Trace: %s:%s %s' % (tb.tb_frame.f_code.co_filename,tb.tb_frame.f_code.co_name,tb.tb_lineno))
tb = tb.tb_next
# just to be safe
del tb
def safe_del(file):
try:
if os.path.isdir(file):
os.removedirs(file)
else:
os.remove(file)
except OSError:
pass
class DieWhenLost(Protocol):
def connectionLost(self, reason=None):
reactor.stop()
class MailProcessor(basic.LineReceiver):
"""I process a mail message.
Override filterMessage to do any filtering you want."""
messageFilename = None
delimiter = '\n'
def connectionMade(self):
log.msg('Connection from %r' % self.transport)
self.state = 'connected'
self.metaInfo = []
def lineReceived(self, line):
if self.state == 'connected':
self.messageFilename = line
self.state = 'gotMessageFilename'
if self.state == 'gotMessageFilename':
if line:
self.metaInfo.append(line)
else:
if not self.metaInfo:
self.transport.loseConnection()
return
self.filterMessage()
def filterMessage(self):
"""Override this.
A trivial example is included.
"""
try:
m = Message(open(self.messageFilename))
self.sendLine('200 Ok')
except:
trace_dump()
self.sendLine('435 %s processing error' % FILTERNAME)
def main():
# Listen on the UNIX socket
f = Factory()
f.protocol = MailProcessor
safe_del('%s/%s' % (ALLFILTERS, FILTERNAME))
reactor.listenUNIX('%s/%s' % (ALLFILTERS, FILTERNAME), f, 10)
# Once started, close fd 3 to let Courier know we're ready
reactor.callLater(0, os.close, 3)
# When stdin is closed, it's time to exit.
s = stdio.StandardIO(DieWhenLost())
# Go!
reactor.run()
if __name__ == '__main__':
main()

View File

@@ -1,163 +0,0 @@
# Copyright (c) 2001-2004 Twisted Matrix Laboratories.
# See LICENSE for details.
import sys
from zope.interface import implements, Interface
from twisted.protocols import basic
from twisted.internet import protocol
from twisted.python import log
from twisted.cred import error
from twisted.cred import portal
from twisted.cred import checkers
from twisted.cred import credentials
class IProtocolUser(Interface):
def getPrivileges():
"""Return a list of privileges this user has."""
def logout():
"""Cleanup per-login resources allocated to this avatar"""
class AnonymousUser:
implements(IProtocolUser)
def getPrivileges(self):
return [1, 2, 3]
def logout(self):
print "Cleaning up anonymous user resources"
class RegularUser:
implements(IProtocolUser)
def getPrivileges(self):
return [1, 2, 3, 5, 6]
def logout(self):
print "Cleaning up regular user resources"
class Administrator:
implements(IProtocolUser)
def getPrivileges(self):
return range(50)
def logout(self):
print "Cleaning up administrator resources"
class Protocol(basic.LineReceiver):
user = None
portal = None
avatar = None
logout = None
def connectionMade(self):
self.sendLine("Login with USER <name> followed by PASS <password> or ANON")
self.sendLine("Check privileges with PRIVS")
def connectionLost(self, reason):
if self.logout:
self.logout()
self.avatar = None
self.logout = None
def lineReceived(self, line):
f = getattr(self, 'cmd_' + line.upper().split()[0])
if f:
try:
f(*line.split()[1:])
except TypeError:
self.sendLine("Wrong number of arguments.")
except:
self.sendLine("Server error (probably your fault)")
def cmd_ANON(self):
if self.portal:
self.portal.login(credentials.Anonymous(), None, IProtocolUser
).addCallbacks(self._cbLogin, self._ebLogin
)
else:
self.sendLine("DENIED")
def cmd_USER(self, name):
self.user = name
self.sendLine("Alright. Now PASS?")
def cmd_PASS(self, password):
if not self.user:
self.sendLine("USER required before PASS")
else:
if self.portal:
self.portal.login(
credentials.UsernamePassword(self.user, password),
None,
IProtocolUser
).addCallbacks(self._cbLogin, self._ebLogin
)
else:
self.sendLine("DENIED")
def cmd_PRIVS(self):
self.sendLine("You have the following privileges: ")
self.sendLine(" ".join(map(str, self.avatar.getPrivileges())))
def _cbLogin(self, (interface, avatar, logout)):
assert interface is IProtocolUser
self.avatar = avatar
self.logout = logout
self.sendLine("Login successful. Available commands: PRIVS")
def _ebLogin(self, failure):
failure.trap(error.UnauthorizedLogin)
self.sendLine("Login denied! Go away.")
class ServerFactory(protocol.ServerFactory):
protocol = Protocol
def __init__(self, portal):
self.portal = portal
def buildProtocol(self, addr):
p = protocol.ServerFactory.buildProtocol(self, addr)
p.portal = self.portal
return p
class Realm:
implements(portal.IRealm)
def requestAvatar(self, avatarId, mind, *interfaces):
if IProtocolUser in interfaces:
if avatarId == checkers.ANONYMOUS:
av = AnonymousUser()
elif avatarId.isupper():
# Capitalized usernames are administrators.
av = Administrator()
else:
av = RegularUser()
return IProtocolUser, av, av.logout
raise NotImplementedError("Only IProtocolUser interface is supported by this realm")
def main():
r = Realm()
p = portal.Portal(r)
c = checkers.InMemoryUsernamePasswordDatabaseDontUse()
c.addUser("auser", "thepass")
c.addUser("SECONDUSER", "secret")
p.registerChecker(c)
p.registerChecker(checkers.AllowAnonymousAccess())
f = ServerFactory(p)
log.startLogging(sys.stdout)
from twisted.internet import reactor
reactor.listenTCP(4738, f)
reactor.run()
if __name__ == '__main__':
main()

View File

@@ -1,179 +0,0 @@
#!/usr/bin/env python
# Copyright (c) 2001-2009 Twisted Matrix Laboratories.
# See LICENSE for details.
"""
Simple example of a db checker: define a L{ICredentialsChecker} implementation
that deals with a database backend to authenticate a user.
"""
from twisted.cred import error
from twisted.cred.credentials import IUsernameHashedPassword, IUsernamePassword
from twisted.cred.checkers import ICredentialsChecker
from twisted.internet.defer import Deferred
from zope.interface import implements
class DBCredentialsChecker(object):
"""
This class checks the credentials of incoming connections
against a user table in a database.
"""
implements(ICredentialsChecker)
def __init__(self, runQuery,
query="SELECT username, password FROM user WHERE username = %s",
customCheckFunc=None, caseSensitivePasswords=True):
"""
@param runQuery: This will be called to get the info from the db.
Generally you'd want to create a
L{twisted.enterprice.adbapi.ConnectionPool} and pass it's runQuery
method here. Otherwise pass a function with the same prototype.
@type runQuery: C{callable}
@type query: query used to authenticate user.
@param query: C{str}
@param customCheckFunc: Use this if the passwords in the db are stored
as hashes. We'll just call this, so you can do the checking
yourself. It takes the following params:
(username, suppliedPass, dbPass) and must return a boolean.
@type customCheckFunc: C{callable}
@param caseSensitivePasswords: If true requires that every letter in
C{credentials.password} is exactly the same case as the it's
counterpart letter in the database.
This is only relevant if C{customCheckFunc} is not used.
@type caseSensitivePasswords: C{bool}
"""
self.runQuery = runQuery
self.caseSensitivePasswords = caseSensitivePasswords
self.customCheckFunc = customCheckFunc
# We can't support hashed password credentials if we only have a hash
# in the DB
if customCheckFunc:
self.credentialInterfaces = (IUsernamePassword,)
else:
self.credentialInterfaces = (
IUsernamePassword, IUsernameHashedPassword,)
self.sql = query
def requestAvatarId(self, credentials):
"""
Authenticates the kiosk against the database.
"""
# Check that the credentials instance implements at least one of our
# interfaces
for interface in self.credentialInterfaces:
if interface.providedBy(credentials):
break
else:
raise error.UnhandledCredentials()
# Ask the database for the username and password
dbDeferred = self.runQuery(self.sql, (credentials.username,))
# Setup our deferred result
deferred = Deferred()
dbDeferred.addCallbacks(self._cbAuthenticate, self._ebAuthenticate,
callbackArgs=(credentials, deferred),
errbackArgs=(credentials, deferred))
return deferred
def _cbAuthenticate(self, result, credentials, deferred):
"""
Checks to see if authentication was good. Called once the info has
been retrieved from the DB.
"""
if len(result) == 0:
# Username not found in db
deferred.errback(error.UnauthorizedLogin('Username unknown'))
else:
username, password = result[0]
if self.customCheckFunc:
# Let the owner do the checking
if self.customCheckFunc(
username, credentials.password, password):
deferred.callback(credentials.username)
else:
deferred.errback(
error.UnauthorizedLogin('Password mismatch'))
else:
# It's up to us or the credentials object to do the checking
# now
if IUsernameHashedPassword.providedBy(credentials):
# Let the hashed password checker do the checking
if credentials.checkPassword(password):
deferred.callback(credentials.username)
else:
deferred.errback(
error.UnauthorizedLogin('Password mismatch'))
elif IUsernamePassword.providedBy(credentials):
# Compare the passwords, deciging whether or not to use
# case sensitivity
if self.caseSensitivePasswords:
passOk = (
password.lower() == credentials.password.lower())
else:
passOk = password == credentials.password
# See if they match
if passOk:
deferred.callback(credentials.username)
else:
deferred.errback(
error.UnauthorizedLogin('Password mismatch'))
else:
# OK, we don't know how to check this
deferred.errback(error.UnhandledCredentials())
def _ebAuthenticate(self, message, credentials, deferred):
"""
The database lookup failed for some reason.
"""
deferred.errback(error.LoginFailed(message))
def main():
"""
Run a simple echo pb server to test the checker. It defines a custom query
for dealing with sqlite special quoting, but otherwise it's a
straightforward use of the object.
You can test it running C{pbechoclient.py}.
"""
import sys
from twisted.python import log
log.startLogging(sys.stdout)
import os
if os.path.isfile('testcred'):
os.remove('testcred')
from twisted.enterprise import adbapi
pool = adbapi.ConnectionPool('pysqlite2.dbapi2', 'testcred')
# Create the table that will be used
query1 = """CREATE TABLE user (
username string,
password string
)"""
# Insert a test user
query2 = """INSERT INTO user VALUES ('guest', 'guest')"""
def cb(res):
pool.runQuery(query2)
pool.runQuery(query1).addCallback(cb)
checker = DBCredentialsChecker(pool.runQuery,
query="SELECT username, password FROM user WHERE username = ?")
from twisted.cred.portal import Portal
import pbecho
from twisted.spread import pb
portal = Portal(pbecho.SimpleRealm())
portal.registerChecker(checker)
reactor.listenTCP(pb.portno, pb.PBServerFactory(portal))
if __name__ == "__main__":
from twisted.internet import reactor
reactor.callWhenRunning(main)
reactor.run()

View File

@@ -1,41 +0,0 @@
#!/usr/bin/env python
# Copyright (c) 2001-2009 Twisted Matrix Laboratories.
# See LICENSE for details.
from twisted.internet.protocol import ClientFactory
from twisted.protocols.basic import LineReceiver
from twisted.internet import reactor
import sys
class EchoClient(LineReceiver):
end="Bye-bye!"
def connectionMade(self):
self.sendLine("Hello, world!")
self.sendLine("What a fine day it is.")
self.sendLine(self.end)
def lineReceived(self, line):
print "receive:", line
if line==self.end:
self.transport.loseConnection()
class EchoClientFactory(ClientFactory):
protocol = EchoClient
def clientConnectionFailed(self, connector, reason):
print 'connection failed:', reason.getErrorMessage()
reactor.stop()
def clientConnectionLost(self, connector, reason):
print 'connection lost:', reason.getErrorMessage()
reactor.stop()
def main():
factory = EchoClientFactory()
reactor.connectTCP('localhost', 8000, factory)
reactor.run()
if __name__ == '__main__':
main()

View File

@@ -1,46 +0,0 @@
#!/usr/bin/env python
# Copyright (c) 2001-2009 Twisted Matrix Laboratories.
# See LICENSE for details.
from OpenSSL import SSL
import sys
from twisted.internet.protocol import ClientFactory
from twisted.protocols.basic import LineReceiver
from twisted.internet import ssl, reactor
class EchoClient(LineReceiver):
end="Bye-bye!"
def connectionMade(self):
self.sendLine("Hello, world!")
self.sendLine("What a fine day it is.")
self.sendLine(self.end)
def connectionLost(self, reason):
print 'connection lost (protocol)'
def lineReceived(self, line):
print "receive:", line
if line==self.end:
self.transport.loseConnection()
class EchoClientFactory(ClientFactory):
protocol = EchoClient
def clientConnectionFailed(self, connector, reason):
print 'connection failed:', reason.getErrorMessage()
reactor.stop()
def clientConnectionLost(self, connector, reason):
print 'connection lost:', reason.getErrorMessage()
reactor.stop()
def main():
factory = EchoClientFactory()
reactor.connectSSL('localhost', 8000, factory, ssl.ClientContextFactory())
reactor.run()
if __name__ == '__main__':
main()

View File

@@ -1,38 +0,0 @@
#!/usr/bin/env python
# Copyright (c) 2001-2009 Twisted Matrix Laboratories.
# See LICENSE for details.
from twisted.internet.protocol import DatagramProtocol
from twisted.internet import reactor
class EchoClientDatagramProtocol(DatagramProtocol):
strings = [
"Hello, world!",
"What a fine day it is.",
"Bye-bye!"
]
def startProtocol(self):
self.transport.connect('127.0.0.1', 8000)
self.sendDatagram()
def sendDatagram(self):
if len(self.strings):
datagram = self.strings.pop(0)
self.transport.write(datagram)
else:
reactor.stop()
def datagramReceived(self, datagram, host):
print 'Datagram received: ', repr(datagram)
self.sendDatagram()
def main():
protocol = EchoClientDatagramProtocol()
t = reactor.listenUDP(0, protocol)
reactor.run()
if __name__ == '__main__':
main()

View File

@@ -1,27 +0,0 @@
#!/usr/bin/env python
# Copyright (c) 2001-2009 Twisted Matrix Laboratories.
# See LICENSE for details.
from twisted.internet.protocol import Protocol, Factory
from twisted.internet import reactor
### Protocol Implementation
# This is just about the simplest possible protocol
class Echo(Protocol):
def dataReceived(self, data):
"""
As soon as any data is received, write it back.
"""
self.transport.write(data)
def main():
f = Factory()
f.protocol = Echo
reactor.listenTCP(8000, f)
reactor.run()
if __name__ == '__main__':
main()

View File

@@ -1,30 +0,0 @@
# Copyright (c) 2001-2004 Twisted Matrix Laboratories.
# See LICENSE for details.
from OpenSSL import SSL
class ServerContextFactory:
def getContext(self):
"""Create an SSL context.
This is a sample implementation that loads a certificate from a file
called 'server.pem'."""
ctx = SSL.Context(SSL.SSLv23_METHOD)
ctx.use_certificate_file('server.pem')
ctx.use_privatekey_file('server.pem')
return ctx
if __name__ == '__main__':
import echoserv, sys
from twisted.internet.protocol import Factory
from twisted.internet import ssl, reactor
from twisted.python import log
log.startLogging(sys.stdout)
factory = Factory()
factory.protocol = echoserv.Echo
reactor.listenSSL(8000, factory, ServerContextFactory())
reactor.run()

View File

@@ -1,19 +0,0 @@
#!/usr/bin/env python
# Copyright (c) 2001-2009 Twisted Matrix Laboratories.
# See LICENSE for details.
from twisted.internet.protocol import DatagramProtocol
from twisted.internet import reactor
# Here's a UDP version of the simplest possible protocol
class EchoUDP(DatagramProtocol):
def datagramReceived(self, datagram, address):
self.transport.write(datagram, address)
def main():
reactor.listenUDP(8000, EchoUDP())
reactor.run()
if __name__ == '__main__':
main()

View File

@@ -1,17 +0,0 @@
# Copyright (c) 2001-2004 Twisted Matrix Laboratories.
# See LICENSE for details.
#
from twisted.application import internet
def watch(fp):
fp.seek(fp.tell())
for line in fp.readlines():
sys.stdout.write(line)
import sys
from twisted.internet import reactor
s = internet.TimerService(0.1, watch, file(sys.argv[1]))
s.startService()
reactor.run()
s.stopService()

View File

@@ -1,113 +0,0 @@
# Copyright (c) 2001-2004 Twisted Matrix Laboratories.
# See LICENSE for details.
"""
An example of using the FTP client
"""
# Twisted imports
from twisted.protocols.ftp import FTPClient, FTPFileListProtocol
from twisted.internet.protocol import Protocol, ClientCreator
from twisted.python import usage
from twisted.internet import reactor
# Standard library imports
import string
import sys
try:
from cStringIO import StringIO
except ImportError:
from StringIO import StringIO
class BufferingProtocol(Protocol):
"""Simple utility class that holds all data written to it in a buffer."""
def __init__(self):
self.buffer = StringIO()
def dataReceived(self, data):
self.buffer.write(data)
# Define some callbacks
def success(response):
print 'Success! Got response:'
print '---'
if response is None:
print None
else:
print string.join(response, '\n')
print '---'
def fail(error):
print 'Failed. Error was:'
print error
def showFiles(result, fileListProtocol):
print 'Processed file listing:'
for file in fileListProtocol.files:
print ' %s: %d bytes, %s' \
% (file['filename'], file['size'], file['date'])
print 'Total: %d files' % (len(fileListProtocol.files))
def showBuffer(result, bufferProtocol):
print 'Got data:'
print bufferProtocol.buffer.getvalue()
class Options(usage.Options):
optParameters = [['host', 'h', 'localhost'],
['port', 'p', 21],
['username', 'u', 'anonymous'],
['password', None, 'twisted@'],
['passive', None, 0],
['debug', 'd', 1],
]
def run():
# Get config
config = Options()
config.parseOptions()
config.opts['port'] = int(config.opts['port'])
config.opts['passive'] = int(config.opts['passive'])
config.opts['debug'] = int(config.opts['debug'])
# Create the client
FTPClient.debug = config.opts['debug']
creator = ClientCreator(reactor, FTPClient, config.opts['username'],
config.opts['password'], passive=config.opts['passive'])
creator.connectTCP(config.opts['host'], config.opts['port']).addCallback(connectionMade).addErrback(connectionFailed)
reactor.run()
def connectionFailed(f):
print "Connection Failed:", f
reactor.stop()
def connectionMade(ftpClient):
# Get the current working directory
ftpClient.pwd().addCallbacks(success, fail)
# Get a detailed listing of the current directory
fileList = FTPFileListProtocol()
d = ftpClient.list('.', fileList)
d.addCallbacks(showFiles, fail, callbackArgs=(fileList,))
# Change to the parent directory
ftpClient.cdup().addCallbacks(success, fail)
# Create a buffer
proto = BufferingProtocol()
# Get short listing of current directory, and quit when done
d = ftpClient.nlst('.', proto)
d.addCallbacks(showBuffer, fail, callbackArgs=(proto,))
d.addCallback(lambda result: reactor.stop())
# this only runs if the module was *not* imported
if __name__ == '__main__':
run()

View File

@@ -1,55 +0,0 @@
# Copyright (c) 2008 Twisted Matrix Laboratories.
# See LICENSE for details.
"""
An example FTP server with minimal user authentication.
"""
from twisted.protocols.ftp import FTPFactory, FTPRealm
from twisted.cred.portal import Portal
from twisted.cred.checkers import AllowAnonymousAccess, FilePasswordDB
from twisted.internet import reactor
#
# First, set up a portal (twisted.cred.portal.Portal). This will be used
# to authenticate user logins, including anonymous logins.
#
# Part of this will be to establish the "realm" of the server - the most
# important task in this case is to establish where anonymous users will
# have default access to. In a real world scenario this would typically
# point to something like '/pub' but for this example it is pointed at the
# current working directory.
#
# The other important part of the portal setup is to point it to a list of
# credential checkers. In this case, the first of these is used to grant
# access to anonymous users and is relatively simple; the second is a very
# primitive password checker. This example uses a plain text password file
# that has one username:password pair per line. This checker *does* provide
# a hashing interface, and one would normally want to use it instead of
# plain text storage for anything remotely resembling a 'live' network. In
# this case, the file "pass.dat" is used, and stored in the same directory
# as the server. BAD.
#
# Create a pass.dat file which looks like this:
#
# =====================
# jeff:bozo
# grimmtooth:bozo2
# =====================
#
p = Portal(FTPRealm('./'),
[AllowAnonymousAccess(), FilePasswordDB("pass.dat")])
#
# Once the portal is set up, start up the FTPFactory and pass the portal to
# it on startup. FTPFactory will start up a twisted.protocols.ftp.FTP()
# handler for each incoming OPEN request. Business as usual in Twisted land.
#
f = FTPFactory(p)
#
# You know this part. Point the reactor to port 21 coupled with the above factory,
# and start the event loop.
#
reactor.listenTCP(21, f)
reactor.run()

View File

@@ -1,78 +0,0 @@
#!/usr/bin/env python
# Copyright (c) 2001-2009 Twisted Matrix Laboratories.
# See LICENSE for details.
"""
GPSTest is a simple example using the SerialPort transport and the NMEA 0183
and Rockwell Zodiac GPS protocols to display fix data as it is received from
the device.
"""
from twisted.python import log, usage
import sys
if sys.platform == 'win32':
from twisted.internet import win32eventreactor
win32eventreactor.install()
class GPSFixLogger:
def handle_fix(self, *args):
"""
handle_fix gets called whenever either rockwell.Zodiac or nmea.NMEAReceiver
receives and decodes fix data. Generally, GPS receivers will report a
fix at 1hz. Implementing only this method is sufficient for most purposes
unless tracking of ground speed, course, utc date, or detailed satellite
information is necessary.
For example, plotting a map from MapQuest or a similar service only
requires longitude and latitude.
"""
log.msg('fix:\n' +
'\n'.join(map(lambda n: ' %s = %s' % tuple(n), zip(('utc', 'lon', 'lat', 'fix', 'sat', 'hdp', 'alt', 'geo', 'dgp'), map(repr, args)))))
class GPSOptions(usage.Options):
optFlags = [
['zodiac', 'z', 'Use Rockwell Zodiac (DeLorme Earthmate) [default: NMEA 0183]'],
]
optParameters = [
['outfile', 'o', None, 'Logfile [default: sys.stdout]'],
['baudrate', 'b', None, 'Serial baudrate [default: 4800 for NMEA, 9600 for Zodiac]'],
['port', 'p', '/dev/ttyS0', 'Serial Port device'],
]
if __name__ == '__main__':
from twisted.internet import reactor
from twisted.internet.serialport import SerialPort
o = GPSOptions()
try:
o.parseOptions()
except usage.UsageError, errortext:
print '%s: %s' % (sys.argv[0], errortext)
print '%s: Try --help for usage details.' % (sys.argv[0])
raise SystemExit, 1
logFile = o.opts['outfile']
if logFile is None:
logFile = sys.stdout
log.startLogging(logFile)
if o.opts['zodiac']:
from twisted.protocols.gps.rockwell import Zodiac as GPSProtocolBase
baudrate = 9600
else:
from twisted.protocols.gps.nmea import NMEAReceiver as GPSProtocolBase
baudrate = 4800
class GPSTest(GPSProtocolBase, GPSFixLogger):
pass
if o.opts['baudrate']:
baudrate = int(o.opts['baudrate'])
port = o.opts['port']
log.msg('Attempting to open %s at %dbps as a %s device' % (port, baudrate, GPSProtocolBase.__name__))
s = SerialPort(GPSTest(), o.opts['port'], reactor, baudrate=baudrate)
reactor.run()

View File

@@ -1,127 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Twisted Documentation: Twisted code examples</title>
<link href="../howto/stylesheet.css" rel="stylesheet" type="text/css"/>
</head>
<body bgcolor="white">
<h1 class="title">Twisted code examples</h1>
<div class="toc"><ol><li><a href="#auto0">Simple Echo server and client</a></li><li><a href="#auto1">Chat</a></li><li><a href="#auto2">Echo server &amp; client variants</a></li><li><a href="#auto3">AMP server &amp; client variants</a></li><li><a href="#auto4">Perspective Broker</a></li><li><a href="#auto5">ROW (Twisted Enterprise)</a></li><li><a href="#auto6">Cred</a></li><li><a href="#auto7">GUI</a></li><li><a href="#auto8">FTP examples</a></li><li><a href="#auto9">Logging</a></li><li><a href="#auto10">Miscellaneous</a></li></ol></div>
<div class="content">
<span/>
<h2>Simple Echo server and client<a name="auto0"/></h2>
<ul>
<li><a href="simpleclient.py" shape="rect">simpleclient.py</a> - simple TCP client</li>
<li><a href="simpleserv.py" shape="rect">simpleserv.py</a> - simple TCP echo server</li>
</ul>
<h2>Chat<a name="auto1"/></h2>
<ul>
<li><a href="chatserver.py" shape="rect">chatserver.py</a> - shows how to communicate between clients</li>
</ul>
<h2>Echo server &amp; client variants<a name="auto2"/></h2>
<ul>
<li><a href="echoserv.py" shape="rect">echoserv.py</a> - variant on a simple TCP echo server</li>
<li><a href="echoclient.py" shape="rect">echoclient.py</a> - variant on a simple TCP client</li>
<li><a href="echoserv_udp.py" shape="rect">echoserv_udp.py</a> - simplest possible
UDP server</li>
<li><a href="echoclient_udp.py" shape="rect">echoclient_udp.py</a> - simple UDP
client</li>
<li><a href="echoserv_ssl.py" shape="rect">echoserv_ssl.py</a> - simple SSL server</li>
<li><a href="echoclient_ssl.py" shape="rect">echoclient_ssl.py</a> - simple SSL client</li>
</ul>
<h2>AMP server &amp; client variants<a name="auto3"/></h2>
<ul>
<li><a href="ampserver.py" shape="rect">ampserver.py</a> - do math using AMP</li>
<li><a href="ampclient.py" shape="rect">ampclient.py</a> - do math using AMP</li>
</ul>
<h2>Perspective Broker<a name="auto4"/></h2>
<ul>
<li><a href="pbsimple.py" shape="rect">pbsimple.py</a> - simplest possible PB server</li>
<li><a href="pbsimpleclient.py" shape="rect">pbsimpleclient.py</a> - simplest possible PB
client</li>
<li><a href="pbbenchclient.py" shape="rect">pbbenchclient.py</a> - benchmarking client</li>
<li><a href="pbbenchserver.py" shape="rect">pbbenchserver.py</a> - benchmarking server</li>
<li><a href="pbecho.py" shape="rect">pbecho.py</a> - echo server that uses login</li>
<li><a href="pbechoclient.py" shape="rect">pbechoclient.py</a> - echo client using login</li>
<li><a href="pb_exceptions.py" shape="rect">pb_exceptions.py</a> - example of exceptions over PB</li>
<li><a href="pbgtk2.py" shape="rect">pbgtk2.py</a> - example of using GTK2 with PB</li>
<li><a href="pbinterop.py" shape="rect">pbinterop.py</a> - shows off various types supported by PB</li>
<li><a href="bananabench.py" shape="rect">bananabench.py</a> - benchmark for banana</li>
</ul>
<h2>ROW (Twisted Enterprise)<a name="auto5"/></h2>
<ul>
<li><a href="row_example.py" shape="rect">row_example.py</a> - using twisted.enterpise.row to load objects
from a database and manipulate them.</li>
<li><a href="row_schema.sql" shape="rect">row_schema.sql</a> - sample statements to populate tables for
row_example.py</li>
<li><a href="row_util.py" shape="rect">row_util.py</a> - definitions of row classes for
row_example.py</li>
</ul>
<h2>Cred<a name="auto6"/></h2>
<ul>
<li><a href="cred.py" shape="rect">cred.py</a> - Authenticate a user with an in-memory username/password
database</li>
<li><a href="dbcred.py" shape="rect">dbcred.py</a> - Using a database backend to authenticate a user</li>
</ul>
<h2>GUI<a name="auto7"/></h2>
<ul>
<li><a href="wxdemo.py" shape="rect">wxdemo.py</a> - demo of wxPython integration with Twisted</li>
<li><a href="pbgtk2.py" shape="rect">pbgtk2.py</a> - example of using GTK2 with PB</li>
<li><a href="pyuidemo.py" shape="rect">pyuidemo.py</a> - PyUI</li>
</ul>
<h2>FTP examples<a name="auto8"/></h2>
<ul>
<li><a href="ftpclient.py" shape="rect">ftpclient.py</a> - example of using the FTP client</li>
<li><a href="ftpserver.py" shape="rect">ftpserver.py</a> - create an FTP server which
serves files for anonymous users from the working directory and serves
files for authenticated users from <code class="shell">/home</code>.</li>
</ul>
<h2>Logging<a name="auto9"/></h2>
<ul>
<li><a href="twistd-logging.tac" shape="rect">twistd-logging.tac</a> - logging example using
ILogObserver</li>
<li><a href="testlogging.py" shape="rect">testlogging.py</a> - use twisted.python.log to log errors to
standard out</li>
<li><a href="rotatinglog.py" shape="rect">rotatinglog.py</a> - example of log file rotation</li>
</ul>
<h2>Miscellaneous<a name="auto10"/></h2>
<ul>
<li><a href="shaper.py" shape="rect">shaper.py</a> - example of rate-limiting your web server</li>
<li><a href="stdiodemo.py" shape="rect">stdiodemo.py</a> - example using stdio, Deferreds, LineReceiver
and twisted.web.client.</li>
<li><a href="mouse.py" shape="rect">mouse.py</a> - example using MouseMan protocol with the SerialPort
transport</li>
<li><a href="ptyserv.py" shape="rect">ptyserv.py</a> - serve shells in pseudo-terminals over TCP</li>
<li><a href="courier.py" shape="rect">courier.py</a> - example of interfacing to Courier's mail filter
interface</li>
<li><a href="longex.py" shape="rect">longex.py</a> - example of doing arbitarily long calculations nicely
in Twisted</li>
<li><a href="longex2.py" shape="rect">longex2.py</a> - using generators to do long calculations</li>
<li><a href="stdin.py" shape="rect">stdin.py</a> - reading a line at a time from standard input
without blocking the reactor.</li>
<li><a href="filewatch.py" shape="rect">filewatch.py</a> - write the content of a file to standard out
one line at a time</li>
<li><a href="shoutcast.py" shape="rect">shoutcast.py</a> - example Shoutcast client</li>
<li><a href="gpsfix.py" shape="rect">gpsfix.py</a> - example using the SerialPort transport and GPS
protocols to display fix data as it is received from the device</li>
<li><a href="wxacceptance.py" shape="rect">wxacceptance.py</a> - acceptance tests for wxreactor</li>
<li><a href="postfix.py" shape="rect">postfix.py</a> - test application for PostfixTCPMapServer</li>
</ul>
</div>
<p><a href="../howto/index.html">Index</a></p>
<span class="version">Version: 10.0.0</span>
</body>
</html>

View File

@@ -1,66 +0,0 @@
"""Simple example of doing arbitarily long calculations nicely in Twisted.
This is also a simple demonstration of twisted.protocols.basic.LineReceiver.
"""
from twisted.protocols import basic
from twisted.internet import reactor
from twisted.internet.protocol import ServerFactory
class LongMultiplicationProtocol(basic.LineReceiver):
"""A protocol for doing long multiplications.
It receives a list of numbers (seperated by whitespace) on a line, and
writes back the answer. The answer is calculated in chunks, so no one
calculation should block for long enough to matter.
"""
def connectionMade(self):
self.workQueue = []
def lineReceived(self, line):
try:
numbers = map(long, line.split())
except ValueError:
self.sendLine('Error.')
return
if len(numbers) <= 1:
self.sendLine('Error.')
return
self.workQueue.append(numbers)
reactor.callLater(0, self.calcChunk)
def calcChunk(self):
# Make sure there's some work left; when multiple lines are received
# while processing is going on, multiple calls to reactor.callLater()
# can happen between calls to calcChunk().
if self.workQueue:
# Get the first bit of work off the queue
work = self.workQueue[0]
# Do a chunk of work: [a, b, c, ...] -> [a*b, c, ...]
work[:2] = [work[0] * work[1]]
# If this piece of work now has only one element, send it.
if len(work) == 1:
self.sendLine(str(work[0]))
del self.workQueue[0]
# Schedule this function to do more work, if there's still work
# to be done.
if self.workQueue:
reactor.callLater(0, self.calcChunk)
class LongMultiplicationFactory(ServerFactory):
protocol = LongMultiplicationProtocol
if __name__ == '__main__':
from twisted.python import log
import sys
log.startLogging(sys.stdout)
reactor.listenTCP(1234, LongMultiplicationFactory())
reactor.run()

View File

@@ -1,101 +0,0 @@
"""Example of doing arbitarily long calculations nicely in Twisted.
This is also a simple demonstration of twisted.protocols.basic.LineReceiver.
This example uses generators to do the calculation. It also tries to be
a good example in division of responsibilities:
- The protocol handles the wire layer, reading in lists of numbers
and writing out the result.
- The factory decides on policy, and has relatively little knowledge
of the details of the protocol. Other protocols can use the same
factory class by intantiating and setting .protocol
- The factory does little job itself: it is mostly a policy maker.
The 'smarts' are in free-standing functions which are written
for flexibility.
The goal is for minimal dependencies:
- You can use runIterator to run any iterator inside the Twisted
main loop.
- You can use multiply whenever you need some way of multiplying
numbers such that the multiplications will happen asynchronously,
but it is your responsibility to schedule the multiplications.
- You can use the protocol with other factories to implement other
functions that apply to arbitrary lists of longs.
- You can use the factory with other protocols for support of legacy
protocols. In fact, the factory does not even have to be used as
a protocol factory. Here are easy ways to support the operation
over XML-RPC and PB.
class Multiply(xmlrpc.XMLRPC):
def __init__(self): self.factory = Multiplication()
def xmlrpc_multiply(self, *numbers):
return self.factory.calc(map(long, numbers))
class Multiply(pb.Referencable):
def __init__(self): self.factory = Multiplication()
def remote_multiply(self, *numbers):
return self.factory.calc(map(long, numbers))
Note:
Multiplying zero numbers is a perfectly sensible operation, and the
result is 1. In that, this example departs from doc/examples/longex.py,
which errors out when trying to do this.
"""
from __future__ import generators
from twisted.protocols import basic
from twisted.internet import defer, protocol
def runIterator(reactor, iterator):
try:
iterator.next()
except StopIteration:
pass
else:
reactor.callLater(0, runIterator, reactor, iterator)
def multiply(numbers):
d = defer.Deferred()
def _():
acc = 1
while numbers:
acc *= numbers.pop()
yield None
d.callback(acc)
return d, _()
class Numbers(basic.LineReceiver):
"""Protocol for reading lists of numbers and manipulating them.
It receives a list of numbers (seperated by whitespace) on a line, and
writes back the answer. The exact algorithm to use depends on the
factory. It should return an str-able Deferred.
"""
def lineReceived(self, line):
try:
numbers = map(long, line.split())
except ValueError:
self.sendLine('Error.')
return
deferred = self.factory.calc(numbers)
deferred.addCallback(str)
deferred.addCallback(self.sendLine)
class Multiplication(protocol.ServerFactory):
"""Factory for multiplying numbers.
It provides a function which calculates the multiplication
of a list of numbers. The function destroys its input.
Note that instances of this factory can use other formats
for transmitting the number lists, as long as they set
correct protoocl values.
"""
protocol = Numbers
def calc(self, numbers):
deferred, iterator = multiply(numbers)
from twisted.internet import reactor
runIterator(reactor, iterator)
return deferred
if __name__ == '__main__':
from twisted.internet import reactor
reactor.listenTCP(1234, Multiplication())
reactor.run()

View File

@@ -1,80 +0,0 @@
#!/usr/bin/env python
# Copyright (c) 2009 Twisted Matrix Laboratories.
# See LICENSE for details.
"""
Example using MouseMan protocol with the SerialPort transport.
"""
# TODO set tty modes, etc.
# This works for me:
# speed 1200 baud; rows 0; columns 0; line = 0;
# intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D;
# eol = <undef>; eol2 = <undef>; start = ^Q; stop = ^S; susp = ^Z;
# rprnt = ^R; werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0;
# -parenb -parodd cs7 hupcl -cstopb cread clocal -crtscts ignbrk
# -brkint ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl -ixon
# -ixoff -iuclc -ixany -imaxbel -opost -olcuc -ocrnl -onlcr -onocr
# -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0 -isig -icanon -iexten
# -echo -echoe -echok -echonl -noflsh -xcase -tostop -echoprt -echoctl
# -echoke
import sys
from twisted.python import usage, log
from twisted.protocols.mice import mouseman
if sys.platform == 'win32':
# win32 serial does not work yet!
raise NotImplementedError, "The SerialPort transport does not currently support Win32"
from twisted.internet import win32eventreactor
win32eventreactor.install()
class Options(usage.Options):
optParameters = [
['port', 'p', '/dev/mouse', 'Device for serial mouse'],
['baudrate', 'b', '1200', 'Baudrate for serial mouse'],
['outfile', 'o', None, 'Logfile [default: sys.stdout]'],
]
class McFooMouse(mouseman.MouseMan):
def down_left(self):
log.msg("LEFT")
def up_left(self):
log.msg("left")
def down_middle(self):
log.msg("MIDDLE")
def up_middle(self):
log.msg("middle")
def down_right(self):
log.msg("RIGHT")
def up_right(self):
log.msg("right")
def move(self, x, y):
log.msg("(%d,%d)" % (x, y))
if __name__ == '__main__':
from twisted.internet import reactor
from twisted.internet.serialport import SerialPort
o = Options()
try:
o.parseOptions()
except usage.UsageError, errortext:
print "%s: %s" % (sys.argv[0], errortext)
print "%s: Try --help for usage details." % (sys.argv[0])
raise SystemExit, 1
logFile = sys.stdout
if o.opts['outfile']:
logFile = o.opts['outfile']
log.startLogging(logFile)
SerialPort(McFooMouse(), o.opts['port'], reactor, baudrate=int(o.opts['baudrate']))
reactor.run()

View File

@@ -1,36 +0,0 @@
from twisted.python import util
from twisted.spread import pb
from twisted.cred import portal, checkers, credentials
class Avatar(pb.Avatar):
def perspective_exception(self, x):
return x / 0
class Realm:
def requestAvatar(self, interface, mind, *interfaces):
if pb.IPerspective in interfaces:
return pb.IPerspective, Avatar(), lambda: None
def cbLogin(avatar):
avatar.callRemote("exception", 10).addCallback(str).addCallback(util.println)
def ebLogin(failure):
print failure
def main():
c = checkers.InMemoryUsernamePasswordDatabaseDontUse(user="pass")
p = portal.Portal(Realm(), [c])
server = pb.PBServerFactory(p)
server.unsafeTracebacks = True
client = pb.PBClientFactory()
login = client.login(credentials.UsernamePassword("user", "pass"))
login.addCallback(cbLogin).addErrback(ebLogin).addBoth(lambda: reactor.stop())
from twisted.internet import reactor
p = reactor.listenTCP(0, server)
c = reactor.connectTCP('127.0.0.1', p.getHost().port, client)
reactor.run()
if __name__ == '__main__':
main()

View File

@@ -1,42 +0,0 @@
from twisted.spread import pb
from twisted.internet import defer, reactor
from twisted.cred.credentials import UsernamePassword
import time
class PBBenchClient:
hostname = 'localhost'
portno = pb.portno
calledThisSecond = 0
def callLoop(self, ignored):
d1 = self.persp.callRemote("simple")
d2 = self.persp.callRemote("complexTypes")
defer.DeferredList([d1, d2]).addCallback(self.callLoop)
self.calledThisSecond += 1
thisSecond = int(time.time())
if thisSecond != self.lastSecond:
if thisSecond - self.lastSecond > 1:
print "WARNING it took more than one second"
print 'cps:', self.calledThisSecond
self.calledThisSecond = 0
self.lastSecond = thisSecond
def _cbPerspective(self, persp):
self.persp = persp
self.lastSecond = int(time.time())
self.callLoop(None)
def runTest(self):
factory = pb.PBClientFactory()
reactor.connectTCP(self.hostname, self.portno, factory)
factory.login(UsernamePassword("benchmark", "benchmark")).addCallback(self._cbPerspective)
def main():
PBBenchClient().runTest()
from twisted.internet import reactor
reactor.run()
if __name__ == '__main__':
main()

View File

@@ -1,54 +0,0 @@
# Copyright (c) 2001-2006 Twisted Matrix Laboratories.
# See LICENSE for details.
"""Server for PB benchmark."""
from zope.interface import implements
from twisted.spread import pb
from twisted.internet import reactor
from twisted.cred.portal import IRealm
class PBBenchPerspective(pb.Avatar):
callsPerSec = 0
def __init__(self):
pass
def perspective_simple(self):
self.callsPerSec = self.callsPerSec + 1
return None
def printCallsPerSec(self):
print '(s) cps:', self.callsPerSec
self.callsPerSec = 0
reactor.callLater(1, self.printCallsPerSec)
def perspective_complexTypes(self):
return ['a', 1, 1l, 1.0, [], ()]
class SimpleRealm:
implements(IRealm)
def requestAvatar(self, avatarId, mind, *interfaces):
if pb.IPerspective in interfaces:
p = PBBenchPerspective()
p.printCallsPerSec()
return pb.IPerspective, p, lambda : None
else:
raise NotImplementedError("no interface")
def main():
from twisted.cred.portal import Portal
from twisted.cred.checkers import InMemoryUsernamePasswordDatabaseDontUse
portal = Portal(SimpleRealm())
checker = InMemoryUsernamePasswordDatabaseDontUse()
checker.addUser("benchmark", "benchmark")
portal.registerChecker(checker)
reactor.listenTCP(8787, pb.PBServerFactory(portal))
reactor.run()
if __name__ == '__main__':
main()

View File

@@ -1,51 +0,0 @@
# Copyright (c) 2001-2006 Twisted Matrix Laboratories.
# See LICENSE for details.
if __name__ == '__main__':
# Avoid using any names defined in the "__main__" module.
from pbecho import main
raise SystemExit(main())
from zope.interface import implements
from twisted.spread import pb
from twisted.cred.portal import IRealm
class DefinedError(pb.Error):
pass
class SimplePerspective(pb.Avatar):
def perspective_echo(self, text):
print 'echoing',text
return text
def perspective_error(self):
raise DefinedError("exception!")
def logout(self):
print self, "logged out"
class SimpleRealm:
implements(IRealm)
def requestAvatar(self, avatarId, mind, *interfaces):
if pb.IPerspective in interfaces:
avatar = SimplePerspective()
return pb.IPerspective, avatar, avatar.logout
else:
raise NotImplementedError("no interface")
def main():
from twisted.internet import reactor
from twisted.cred.portal import Portal
from twisted.cred.checkers import InMemoryUsernamePasswordDatabaseDontUse
portal = Portal(SimpleRealm())
checker = InMemoryUsernamePasswordDatabaseDontUse()
checker.addUser("guest", "guest")
portal.registerChecker(checker)
reactor.listenTCP(pb.portno, pb.PBServerFactory(portal))
reactor.run()

View File

@@ -1,32 +0,0 @@
# Copyright (c) 2001-2004 Twisted Matrix Laboratories.
# See LICENSE for details.
from twisted.internet import reactor
from twisted.spread import pb
from twisted.cred.credentials import UsernamePassword
from pbecho import DefinedError
def success(message):
print "Message received:",message
# reactor.stop()
def failure(error):
t = error.trap(DefinedError)
print "error received:", t
reactor.stop()
def connected(perspective):
perspective.callRemote('echo', "hello world").addCallbacks(success, failure)
perspective.callRemote('error').addCallbacks(success, failure)
print "connected."
factory = pb.PBClientFactory()
reactor.connectTCP("localhost", pb.portno, factory)
factory.login(
UsernamePassword("guest", "guest")).addCallbacks(connected, failure)
reactor.run()

View File

@@ -1,122 +0,0 @@
# Copyright (c) 2001-2009 Twisted Matrix Laboratories.
# See LICENSE for details.
from __future__ import nested_scopes
from twisted.internet import gtk2reactor
gtk2reactor.install()
import gtk
from gtk import glade
from twisted import copyright
from twisted.internet import reactor, defer
from twisted.python import failure, log, util
from twisted.spread import pb
from twisted.cred.credentials import UsernamePassword
from twisted.internet import error as netError
class LoginDialog:
def __init__(self, deferred):
self.deferredResult = deferred
gladefile = util.sibpath(__file__, "pbgtk2login.glade")
self.glade = glade.XML(gladefile)
self.glade.signal_autoconnect(self)
self.setWidgetsFromGladefile()
self._loginDialog.show()
def setWidgetsFromGladefile(self):
widgets = ("hostEntry", "portEntry", "userNameEntry", "passwordEntry",
"statusBar", "loginDialog")
gw = self.glade.get_widget
for widgetName in widgets:
setattr(self, "_" + widgetName, gw(widgetName))
self._statusContext = self._statusBar.get_context_id("Login dialog.")
def on_loginDialog_response(self, widget, response):
handlers = {gtk.RESPONSE_NONE: self.windowClosed,
gtk.RESPONSE_DELETE_EVENT: self.windowClosed,
gtk.RESPONSE_OK: self.doLogin,
gtk.RESPONSE_CANCEL: self.cancelled}
handlers.get(response)()
def on_loginDialog_close(self, widget, userdata=None):
self.windowClosed()
def cancelled(self):
if not self.deferredResult.called:
self.deferredResult.errback()
self._loginDialog.destroy()
def windowClosed(self, reason=None):
if not self.deferredResult.called:
self.deferredResult.errback()
def doLogin(self):
host = self._hostEntry.get_text()
port = int(self._portEntry.get_text())
userName = self._userNameEntry.get_text()
password = self._passwordEntry.get_text()
client_factory = pb.PBClientFactory()
reactor.connectTCP(host, port, client_factory)
creds = UsernamePassword(userName, password)
client_factory.login(creds).addCallbacks(self._cbGotPerspective, self._ebFailedLogin)
self.statusMsg("Contacting server...")
def _cbGotPerspective(self, perspective):
self.statusMsg("Connected to server.")
self.deferredResult.callback(perspective)
self._loginDialog.destroy()
def _ebFailedLogin(self, reason):
if isinstance(reason, failure.Failure):
text = str(reason.value)
else:
text = str(reason)
self.statusMsg(text)
msg = gtk.MessageDialog(self._loginDialog,
gtk.DIALOG_DESTROY_WITH_PARENT,
gtk.MESSAGE_ERROR,
gtk.BUTTONS_CLOSE,
text)
msg.show_all()
msg.connect("response", lambda *a: msg.destroy())
def statusMsg(self, text):
self._statusBar.push(self._statusContext, text)
class EchoClient:
def __init__(self, echoer):
self.echoer = echoer
w = gtk.Window(gtk.WINDOW_TOPLEVEL)
vb = gtk.VBox(); b = gtk.Button("Echo:")
self.entry = gtk.Entry(); self.outry = gtk.Entry()
w.add(vb)
map(vb.add, [b, self.entry, self.outry])
b.connect('clicked', self.clicked)
w.connect('destroy', self.stop)
w.show_all()
def clicked(self, b):
txt = self.entry.get_text()
self.entry.set_text("")
self.echoer.callRemote('echo',txt).addCallback(self.outry.set_text)
def stop(self, b):
reactor.stop()
d = defer.Deferred()
LoginDialog(d)
d.addCallbacks(EchoClient,
lambda _: reactor.stop())
reactor.run()

View File

@@ -1,330 +0,0 @@
<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
<glade-interface>
<widget class="GtkDialog" id="loginDialog">
<property name="title" translatable="yes">Login</property>
<property name="type">GTK_WINDOW_TOPLEVEL</property>
<property name="window_position">GTK_WIN_POS_NONE</property>
<property name="modal">False</property>
<property name="resizable">True</property>
<property name="destroy_with_parent">True</property>
<property name="has_separator">True</property>
<signal name="response" handler="on_loginDialog_response" last_modification_time="Sun, 21 Sep 2003 05:27:45 GMT"/>
<signal name="close" handler="on_loginDialog_close" last_modification_time="Sun, 21 Sep 2003 05:27:49 GMT"/>
<child internal-child="vbox">
<widget class="GtkVBox" id="dialog-vbox1">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child internal-child="action_area">
<widget class="GtkHButtonBox" id="dialog-action_area1">
<property name="visible">True</property>
<property name="layout_style">GTK_BUTTONBOX_END</property>
<child>
<widget class="GtkButton" id="cancelbutton1">
<property name="visible">True</property>
<property name="can_default">True</property>
<property name="can_focus">True</property>
<property name="label">gtk-cancel</property>
<property name="use_stock">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="response_id">-6</property>
</widget>
</child>
<child>
<widget class="GtkButton" id="loginButton">
<property name="visible">True</property>
<property name="can_default">True</property>
<property name="has_default">True</property>
<property name="can_focus">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="response_id">-5</property>
<child>
<widget class="GtkAlignment" id="alignment1">
<property name="visible">True</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xscale">0</property>
<property name="yscale">0</property>
<child>
<widget class="GtkHBox" id="hbox2">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">2</property>
<child>
<widget class="GtkImage" id="image1">
<property name="visible">True</property>
<property name="stock">gtk-ok</property>
<property name="icon_size">4</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label9">
<property name="visible">True</property>
<property name="label" translatable="yes">_Login</property>
<property name="use_underline">True</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</widget>
</child>
</widget>
</child>
</widget>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">GTK_PACK_END</property>
</packing>
</child>
<child>
<widget class="GtkStatusbar" id="statusBar">
<property name="visible">True</property>
<property name="has_resize_grip">False</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="pack_type">GTK_PACK_END</property>
</packing>
</child>
<child>
<widget class="GtkTable" id="table1">
<property name="visible">True</property>
<property name="n_rows">3</property>
<property name="n_columns">2</property>
<property name="homogeneous">False</property>
<property name="row_spacing">0</property>
<property name="column_spacing">0</property>
<child>
<widget class="GtkLabel" id="hostLabel">
<property name="visible">True</property>
<property name="label" translatable="yes">_Host:</property>
<property name="use_underline">True</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0.9</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="mnemonic_widget">hostEntry</property>
<accessibility>
<atkrelation target="hostEntry" type="label-for"/>
<atkrelation target="portEntry" type="label-for"/>
</accessibility>
</widget>
<packing>
<property name="left_attach">0</property>
<property name="right_attach">1</property>
<property name="top_attach">0</property>
<property name="bottom_attach">1</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkHBox" id="hbox1">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkEntry" id="hostEntry">
<property name="visible">True</property>
<property name="tooltip" translatable="yes">The name of a host to connect to.</property>
<property name="can_focus">True</property>
<property name="has_focus">True</property>
<property name="editable">True</property>
<property name="visibility">True</property>
<property name="max_length">0</property>
<property name="text" translatable="yes">localhost</property>
<property name="has_frame">True</property>
<property name="invisible_char" translatable="yes">*</property>
<property name="activates_default">True</property>
<accessibility>
<atkrelation target="hostLabel" type="labelled-by"/>
</accessibility>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="portEntry">
<property name="visible">True</property>
<property name="tooltip" translatable="yes">The number of a port to connect on.</property>
<property name="can_focus">True</property>
<property name="editable">True</property>
<property name="visibility">True</property>
<property name="max_length">0</property>
<property name="text" translatable="yes">8787</property>
<property name="has_frame">True</property>
<property name="invisible_char" translatable="yes">*</property>
<property name="activates_default">True</property>
<property name="width_chars">5</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">0</property>
<property name="bottom_attach">1</property>
<property name="y_options">fill</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="nameLabel">
<property name="visible">True</property>
<property name="label" translatable="yes">_Name:</property>
<property name="use_underline">True</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0.9</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="mnemonic_widget">userNameEntry</property>
</widget>
<packing>
<property name="left_attach">0</property>
<property name="right_attach">1</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="userNameEntry">
<property name="visible">True</property>
<property name="tooltip" translatable="yes">An identity to log in as.</property>
<property name="can_focus">True</property>
<property name="editable">True</property>
<property name="visibility">True</property>
<property name="max_length">0</property>
<property name="text" translatable="yes">guest</property>
<property name="has_frame">True</property>
<property name="invisible_char" translatable="yes">*</property>
<property name="activates_default">True</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="passwordEntry">
<property name="visible">True</property>
<property name="tooltip" translatable="yes">The Identity's log-in password.</property>
<property name="can_focus">True</property>
<property name="editable">True</property>
<property name="visibility">False</property>
<property name="max_length">0</property>
<property name="text" translatable="yes">guest</property>
<property name="has_frame">True</property>
<property name="invisible_char" translatable="yes">*</property>
<property name="activates_default">True</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="passwordLabel">
<property name="visible">True</property>
<property name="label" translatable="yes">_Password:</property>
<property name="use_underline">True</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0.9</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="mnemonic_widget">passwordEntry</property>
</widget>
<packing>
<property name="left_attach">0</property>
<property name="right_attach">1</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</widget>
</child>
</widget>
</glade-interface>

View File

@@ -1,71 +0,0 @@
# Copyright (c) 2001-2004 Twisted Matrix Laboratories.
# See LICENSE for details.
"""PB interop server."""
from twisted.spread import pb, jelly, flavors
from twisted.internet import reactor
class Interop(pb.Root):
"""Test object for PB interop tests."""
def __init__(self):
self.o = pb.Referenceable()
def remote_int(self):
return 1
def remote_string(self):
return "string"
def remote_unicode(self):
return u"string"
def remote_float(self):
return 1.5
def remote_list(self):
return [1, 2, 3]
def remote_recursive(self):
l = []
l.append(l)
return l
def remote_dict(self):
return {1 : 2}
def remote_reference(self):
return self.o
def remote_local(self, obj):
d = obj.callRemote("hello")
d.addCallback(self._local_success)
def _local_success(self, result):
if result != "hello, world":
raise ValueError, "%r != %r" % (result, "hello, world")
def remote_receive(self, obj):
expected = [1, 1.5, "hi", u"hi", {1 : 2}]
if obj != expected:
raise ValueError, "%r != %r" % (obj, expected)
def remote_self(self, obj):
if obj != self:
raise ValueError, "%r != %r" % (obj, self)
def remote_copy(self, x):
o = flavors.Copyable()
o.x = x
return o
if __name__ == '__main__':
reactor.listenTCP(8789, pb.PBServerFactory(Interop()))
reactor.run()

View File

@@ -1,16 +0,0 @@
# Copyright (c) 2001-2004 Twisted Matrix Laboratories.
# See LICENSE for details.
from twisted.spread import pb
from twisted.internet import reactor
class Echoer(pb.Root):
def remote_echo(self, st):
print 'echoing:', st
return st
if __name__ == '__main__':
reactor.listenTCP(8789, pb.PBServerFactory(Echoer()))
reactor.run()

View File

@@ -1,18 +0,0 @@
# Copyright (c) 2001-2004 Twisted Matrix Laboratories.
# See LICENSE for details.
from twisted.spread import pb
from twisted.internet import reactor
from twisted.python import util
factory = pb.PBClientFactory()
reactor.connectTCP("localhost", 8789, factory)
d = factory.getRootObject()
d.addCallback(lambda object: object.callRemote("echo", "hello network"))
d.addCallback(lambda echo: 'server echoed: '+echo)
d.addErrback(lambda reason: 'error: '+str(reason.value))
d.addCallback(util.println)
d.addCallback(lambda _: reactor.stop())
reactor.run()

View File

@@ -1,29 +0,0 @@
# Copyright (c) 2009 Twisted Matrix Laboratories.
# See LICENSE for details.
"""
Test app for PostfixTCPMapServer.
Call with parameters KEY1=VAL1 KEY2=VAL2 ...
"""
import sys
from twisted.internet import reactor
from twisted.protocols import postfix
from twisted.python import log
log.startLogging(sys.stdout)
d = {}
for arg in sys.argv[1:]:
try:
k,v = arg.split('=', 1)
except ValueError:
k = arg
v = ''
d[k] = v
f = postfix.PostfixTCPMapDictServerFactory(d)
port = reactor.listenTCP(4242, f, interface='127.0.0.1')
reactor.run()

View File

@@ -1,32 +0,0 @@
from twisted.internet import reactor, protocol
class FakeTelnet(protocol.Protocol):
commandToRun = ['/bin/sh'] # could have args too
dirToRunIn = '/tmp'
def connectionMade(self):
print 'connection made'
self.propro = ProcessProtocol(self)
reactor.spawnProcess(self.propro, self.commandToRun[0], self.commandToRun, {},
self.dirToRunIn, usePTY=1)
def dataReceived(self, data):
self.propro.transport.write(data)
def conectionLost(self):
print 'connection lost'
self.propro.tranport.loseConnection()
class ProcessProtocol(protocol.ProcessProtocol):
def __init__(self, pr):
self.pr = pr
def outReceived(self, data):
self.pr.transport.write(data)
def processEnded(self, reason):
print 'protocol conection lost'
self.pr.transport.loseConnection()
f = protocol.Factory()
f.protocol = FakeTelnet
reactor.listenTCP(5823, f)
reactor.run()

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

Some files were not shown because too many files have changed in this diff Show More