remove vendor
This commit is contained in:
@@ -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
1304
vendor/IPy.py
vendored
File diff suppressed because it is too large
Load Diff
32
vendor/Twisted-10.0.0/INSTALL
vendored
32
vendor/Twisted-10.0.0/INSTALL
vendored
@@ -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
|
||||
57
vendor/Twisted-10.0.0/LICENSE
vendored
57
vendor/Twisted-10.0.0/LICENSE
vendored
@@ -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.
|
||||
1416
vendor/Twisted-10.0.0/NEWS
vendored
1416
vendor/Twisted-10.0.0/NEWS
vendored
File diff suppressed because it is too large
Load Diff
118
vendor/Twisted-10.0.0/README
vendored
118
vendor/Twisted-10.0.0/README
vendored
@@ -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.
|
||||
BIN
vendor/Twisted-10.0.0/bin/.twistd.swp
vendored
BIN
vendor/Twisted-10.0.0/bin/.twistd.swp
vendored
Binary file not shown.
20
vendor/Twisted-10.0.0/bin/conch/cftp
vendored
20
vendor/Twisted-10.0.0/bin/conch/cftp
vendored
@@ -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()
|
||||
20
vendor/Twisted-10.0.0/bin/conch/ckeygen
vendored
20
vendor/Twisted-10.0.0/bin/conch/ckeygen
vendored
@@ -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()
|
||||
20
vendor/Twisted-10.0.0/bin/conch/conch
vendored
20
vendor/Twisted-10.0.0/bin/conch/conch
vendored
@@ -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()
|
||||
20
vendor/Twisted-10.0.0/bin/conch/tkconch
vendored
20
vendor/Twisted-10.0.0/bin/conch/tkconch
vendored
@@ -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()
|
||||
21
vendor/Twisted-10.0.0/bin/lore/lore
vendored
21
vendor/Twisted-10.0.0/bin/lore/lore
vendored
@@ -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()
|
||||
|
||||
25
vendor/Twisted-10.0.0/bin/mail/mailmail
vendored
25
vendor/Twisted-10.0.0/bin/mail/mailmail
vendored
@@ -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()
|
||||
|
||||
21
vendor/Twisted-10.0.0/bin/manhole
vendored
21
vendor/Twisted-10.0.0/bin/manhole
vendored
@@ -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()
|
||||
18
vendor/Twisted-10.0.0/bin/mktap
vendored
18
vendor/Twisted-10.0.0/bin/mktap
vendored
@@ -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()
|
||||
|
||||
17
vendor/Twisted-10.0.0/bin/pyhtmlizer
vendored
17
vendor/Twisted-10.0.0/bin/pyhtmlizer
vendored
@@ -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()
|
||||
20
vendor/Twisted-10.0.0/bin/tap2deb
vendored
20
vendor/Twisted-10.0.0/bin/tap2deb
vendored
@@ -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()
|
||||
22
vendor/Twisted-10.0.0/bin/tap2rpm
vendored
22
vendor/Twisted-10.0.0/bin/tap2rpm
vendored
@@ -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()
|
||||
18
vendor/Twisted-10.0.0/bin/tapconvert
vendored
18
vendor/Twisted-10.0.0/bin/tapconvert
vendored
@@ -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()
|
||||
22
vendor/Twisted-10.0.0/bin/trial
vendored
22
vendor/Twisted-10.0.0/bin/trial
vendored
@@ -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()
|
||||
19
vendor/Twisted-10.0.0/bin/twistd
vendored
19
vendor/Twisted-10.0.0/bin/twistd
vendored
@@ -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()
|
||||
@@ -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.
|
||||
@@ -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()
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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>
|
||||
@@ -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()
|
||||
@@ -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()
|
||||
@@ -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)
|
||||
190
vendor/Twisted-10.0.0/doc/conch/examples/window.tac
vendored
190
vendor/Twisted-10.0.0/doc/conch/examples/window.tac
vendored
@@ -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)
|
||||
@@ -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">"""-----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-----"""</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 "cat."\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 "cat":'</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">"__main__"</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>
|
||||
28
vendor/Twisted-10.0.0/doc/conch/howto/index.html
vendored
28
vendor/Twisted-10.0.0/doc/conch/howto/index.html
vendored
@@ -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>
|
||||
25
vendor/Twisted-10.0.0/doc/conch/index.html
vendored
25
vendor/Twisted-10.0.0/doc/conch/index.html
vendored
@@ -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>
|
||||
@@ -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 <z3p@twistedmatrix.com>. Man page by Mary Gardiner <mary@twistedmatrix.com>.
|
||||
</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>
|
||||
89
vendor/Twisted-10.0.0/doc/conch/man/cftp.1
vendored
89
vendor/Twisted-10.0.0/doc/conch/man/cftp.1
vendored
@@ -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.
|
||||
107
vendor/Twisted-10.0.0/doc/conch/man/ckeygen-man.html
vendored
107
vendor/Twisted-10.0.0/doc/conch/man/ckeygen-man.html
vendored
@@ -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> <bits>
|
||||
</dt><dd>Number of bits in the key to create (default: 1024)
|
||||
</dd>
|
||||
|
||||
<dt><strong>-f</strong>, <strong>--filename</strong> <file name>
|
||||
</dt><dd>Filename of the key file.
|
||||
</dd>
|
||||
|
||||
<dt><strong>-t</strong>, <strong>--type</strong> <type>
|
||||
</dt><dd>Type of key (rsa or dsa).
|
||||
</dd>
|
||||
|
||||
<dt><strong>-C</strong>, <strong>--comment</strong> <comment>
|
||||
</dt><dd>Provide a new comment.
|
||||
</dd>
|
||||
|
||||
<dt><strong>-N</strong>, <strong>--newpass</strong> <pass phrase>
|
||||
</dt><dd>Provide new passphrase.
|
||||
</dd>
|
||||
|
||||
<dt><strong>-P</strong>, <strong>--pass</strong> <pass phrase>
|
||||
</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>
|
||||
58
vendor/Twisted-10.0.0/doc/conch/man/ckeygen.1
vendored
58
vendor/Twisted-10.0.0/doc/conch/man/ckeygen.1
vendored
@@ -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)
|
||||
148
vendor/Twisted-10.0.0/doc/conch/man/conch-man.html
vendored
148
vendor/Twisted-10.0.0/doc/conch/man/conch-man.html
vendored
@@ -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 <z3p@twistedmatrix.com>.
|
||||
</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>
|
||||
206
vendor/Twisted-10.0.0/doc/conch/man/conch.1
vendored
206
vendor/Twisted-10.0.0/doc/conch/man/conch.1
vendored
@@ -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)
|
||||
129
vendor/Twisted-10.0.0/doc/conch/man/tkconch-man.html
vendored
129
vendor/Twisted-10.0.0/doc/conch/man/tkconch-man.html
vendored
@@ -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> <user>
|
||||
</dt><dd>Log in using this user name.
|
||||
</dd>
|
||||
|
||||
<dt><strong>-e</strong>, <strong>--escape</strong> <escape character>
|
||||
</dt><dd>Set escape character; 'none' = disable (default: ~)
|
||||
</dd>
|
||||
|
||||
<dt><strong>-i</strong>, <strong>--identity</strong> <identity>
|
||||
</dt><dd>Add an identity file for public key authentication (default: ~/.ssh/identity)
|
||||
</dd>
|
||||
|
||||
<dt><strong>-c</strong>, <strong>--cipher</strong> <cipher>
|
||||
</dt><dd>Cipher algorithm to use.
|
||||
</dd>
|
||||
|
||||
<dt><strong>-m</strong>, <strong>--macs</strong> <mac>
|
||||
</dt><dd>Specify MAC algorithms for protocol version 2.
|
||||
</dd>
|
||||
|
||||
<dt><strong>-p</strong>, <strong>--port</strong> <port>
|
||||
</dt><dd>Port to connect to.
|
||||
</dd>
|
||||
|
||||
<dt><strong>-L</strong>, <strong>--localforward</strong> <listen-port:host:port>
|
||||
</dt><dd>Forward local port to remote address.
|
||||
</dd>
|
||||
|
||||
<dt><strong>-R</strong>, <strong>--remoteforward</strong> <listen-port:host:port>
|
||||
</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>
|
||||
72
vendor/Twisted-10.0.0/doc/conch/man/tkconch.1
vendored
72
vendor/Twisted-10.0.0/doc/conch/man/tkconch.1
vendored
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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()
|
||||
@@ -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)
|
||||
@@ -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()
|
||||
@@ -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()
|
||||
@@ -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
|
||||
@@ -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()
|
||||
@@ -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()
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
@@ -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>
|
||||
@@ -1,12 +0,0 @@
|
||||
# -*- test-case-name: <test module> -*-
|
||||
|
||||
# Copyright (c) 2008 Twisted Matrix Laboratories.
|
||||
# See LICENSE for details.
|
||||
|
||||
|
||||
"""
|
||||
Docstring goes here.
|
||||
"""
|
||||
|
||||
|
||||
__all__ = []
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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: <test module> -*-</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">"""
|
||||
Docstring goes here.
|
||||
"""</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">"Hi %s\n"</span> % <span class="py-src-variable">x</span>
|
||||
</pre>
|
||||
|
||||
<p>The example shows you can pass in <code>foo("foo")</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">"Hi %s\n"</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">"""
|
||||
A L{Ninja} is a warrior specializing in various unorthodox arts of war.
|
||||
"""</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">"""
|
||||
Attack C{someone} with this L{Ninja}'s shuriken.
|
||||
"""</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">"""
|
||||
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
|
||||
|
||||
"""</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/<subproject></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">"getuid"</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 "as" 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">"addUser"</span>, <span class="py-src-string">"bob"</span>, <span class="py-src-string">"555-1212"</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">"addUser"</span>, <span class="py-src-variable">name</span>=<span class="py-src-string">"bob"</span>, <span class="py-src-variable">phone</span>=<span class="py-src-string">"555-1212"</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 < 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 (< 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>
|
||||
@@ -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><html></code>, <code><title></code>, <code><head></code>, <code><body></code>, <code><h1></code>, <code><h2</code>, <code><h3></code>, <code><ol></code>, <code><ul></code>, <code><dl></code>, <code><li></code>, <code><dt></code>, <code><dd></code>, <code><p></code>, <code><code></code>, <code><img></code>, <code><blockquote></code>, <code><a></code>, <code><cite></code>, <code><div></code>, <code><span></code>, <code><strong></code>, <code><em></code>, <code><pre></code>, <code><q></code>, <code><table></code>,<code><tr></code>, <code><td></code> and <code><th></code>.</p>
|
||||
|
||||
<p>Please avoid using the quote sign (<code>"</code>) for quoting, and use the relevant html tags (<code><q></q></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
|
||||
<pre> 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">
|
||||
<p>
|
||||
For example, this is how one defines a Resource:
|
||||
</p>
|
||||
|
||||
<pre class="python">
|
||||
from twisted.web import resource
|
||||
|
||||
class MyResource(resource.Resource):
|
||||
def render_GET(self, request):
|
||||
return "Hello, world!"
|
||||
</pre>
|
||||
</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">"Hello, world!"</span>
|
||||
</pre>
|
||||
|
||||
<p>Note that you should never have leading indentation inside a
|
||||
<pre> 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">
|
||||
<pre class="python-interpreter">
|
||||
&gt;&gt;&gt; from twisted.web import resource
|
||||
&gt;&gt;&gt; class MyResource(resource.Resource):
|
||||
... def render_GET(self, request):
|
||||
... return "Hello, world!"
|
||||
...
|
||||
&gt;&gt;&gt; MyResource().render_GET(None)
|
||||
"Hello, world!"
|
||||
</pre>
|
||||
</pre>
|
||||
|
||||
<pre class="python-interpreter" xml:space="preserve">
|
||||
>>> from twisted.web import resource
|
||||
>>> class MyResource(resource.Resource):
|
||||
... def render_GET(self, request):
|
||||
... return "Hello, world!"
|
||||
...
|
||||
>>> MyResource().render_GET(None)
|
||||
"Hello, world!"
|
||||
</pre>
|
||||
|
||||
<h3><q>shell</q><a name="auto4"/></h3>
|
||||
<pre xml:space="preserve">
|
||||
<pre class="shell">
|
||||
$ twistd web --path /var/www
|
||||
</pre>
|
||||
</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 <code> 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">
|
||||
<p>
|
||||
To add a <code class="API">twisted.web.widgets.Widget</code>
|
||||
instance to a <code class="API"
|
||||
base="twisted.web.widgets">Gadget</code> instance, do
|
||||
<code class="python">myGadget.putWidget("widgetPath",
|
||||
MyWidget())</code>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
(implementation note: the widgets are stored in the <code
|
||||
class="python">gadgetInstance.widgets</code> attribute,
|
||||
which is a
|
||||
list.)
|
||||
</p>
|
||||
|
||||
</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("widgetPath", 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 <hN> in
|
||||
a sane way -- <h1> should only appear once in the
|
||||
document, to specify the title. Sections of the document should
|
||||
use <h2>, sub-headers <h3>, 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><hr /></code>
|
||||
. Also, tags which have <q>optional</q> closing tags in HTML
|
||||
<em>need</em> to be closed in XHTML; for example,
|
||||
<code><li>foo</li></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><span class="footnote"></span></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>
|
||||
@@ -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>
|
||||
@@ -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 <code class="API"> 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>-<ticket number></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 #<ticket number></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: #<ticket number></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>
|
||||
@@ -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 "python /somepath/Twisted/bin/trial /somepath/Twisted"))
|
||||
|
||||
(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">"cannot find ssh, nothing to test"</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">"disabled locally"</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">"cannot test without Thing"</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">"cannot test without SSL support"</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>
|
||||
@@ -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 ("here is how you would simplify this
|
||||
code with Deferreds" rather than "Deferreds make code
|
||||
simpler").</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 "More details" or
|
||||
"Advanced stuff" 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 "evangelism" documentation, which compares the Twisted
|
||||
design or Twisted best practice with other approaches and argues for the
|
||||
Twisted approach, and "usage" 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
|
||||
("Conch") and a description ("SSH server") 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 "core
|
||||
Python" and/or "simple networking" 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
|
||||
"understand Twisted Conch", 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">"""
|
||||
Dummy method which returns a deferred that will fire in 5 seconds with
|
||||
a result
|
||||
"""</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">"RESULT"</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 "Conclusion".</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>
|
||||
@@ -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>
|
||||
@@ -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()
|
||||
@@ -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()
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
111
vendor/Twisted-10.0.0/doc/core/examples/courier.py
vendored
111
vendor/Twisted-10.0.0/doc/core/examples/courier.py
vendored
@@ -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()
|
||||
163
vendor/Twisted-10.0.0/doc/core/examples/cred.py
vendored
163
vendor/Twisted-10.0.0/doc/core/examples/cred.py
vendored
@@ -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()
|
||||
179
vendor/Twisted-10.0.0/doc/core/examples/dbcred.py
vendored
179
vendor/Twisted-10.0.0/doc/core/examples/dbcred.py
vendored
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
@@ -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()
|
||||
@@ -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()
|
||||
@@ -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()
|
||||
@@ -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()
|
||||
@@ -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()
|
||||
@@ -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()
|
||||
113
vendor/Twisted-10.0.0/doc/core/examples/ftpclient.py
vendored
113
vendor/Twisted-10.0.0/doc/core/examples/ftpclient.py
vendored
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
@@ -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()
|
||||
127
vendor/Twisted-10.0.0/doc/core/examples/index.html
vendored
127
vendor/Twisted-10.0.0/doc/core/examples/index.html
vendored
@@ -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 & client variants</a></li><li><a href="#auto3">AMP server & 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 & 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 & 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>
|
||||
@@ -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()
|
||||
|
||||
101
vendor/Twisted-10.0.0/doc/core/examples/longex2.py
vendored
101
vendor/Twisted-10.0.0/doc/core/examples/longex2.py
vendored
@@ -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()
|
||||
80
vendor/Twisted-10.0.0/doc/core/examples/mouse.py
vendored
80
vendor/Twisted-10.0.0/doc/core/examples/mouse.py
vendored
@@ -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()
|
||||
@@ -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()
|
||||
@@ -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()
|
||||
@@ -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()
|
||||
@@ -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()
|
||||
@@ -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()
|
||||
122
vendor/Twisted-10.0.0/doc/core/examples/pbgtk2.py
vendored
122
vendor/Twisted-10.0.0/doc/core/examples/pbgtk2.py
vendored
@@ -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()
|
||||
@@ -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>
|
||||
@@ -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()
|
||||
|
||||
|
||||
|
||||
@@ -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()
|
||||
@@ -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()
|
||||
@@ -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()
|
||||
@@ -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()
|
||||
BIN
vendor/Twisted-10.0.0/doc/core/examples/pyui_bg.png
vendored
BIN
vendor/Twisted-10.0.0/doc/core/examples/pyui_bg.png
vendored
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
Reference in New Issue
Block a user