remove vendor
This commit is contained in:
@@ -20,27 +20,5 @@
|
|||||||
Get our vendor folders into the system path.
|
Get our vendor folders into the system path.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
print 'sorry, we cannot include vendor open source libraries... :('
|
||||||
import sys
|
|
||||||
|
|
||||||
# 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