diff -Nru circuits-2.1.0/bin/circuits.bench circuits-3.1.0+ds1/bin/circuits.bench --- circuits-2.1.0/bin/circuits.bench 1970-01-01 00:00:00.000000000 +0000 +++ circuits-3.1.0+ds1/bin/circuits.bench 2014-09-04 10:32:30.000000000 +0000 @@ -0,0 +1,250 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + + +"""(Tool) Bench Marking Tool + +THis tool does some simple benchmaking of the circuits library. +""" + + +import sys +import math +import optparse +from time import sleep + +if sys.platform == "win32": + from time import clock as time +else: + from time import time # NOQA + +try: + import hotshot + import hotshot.stats +except ImportError: + hotshot = None # NOQA + + +try: + import psyco +except ImportError: + psyco = None # NOQA + + +from circuits import __version__ as systemVersion +from circuits import handler, Event, Component, Manager, Debugger + + +USAGE = "%prog [options]" +VERSION = "%prog v" + systemVersion + + +def duration(seconds): + days = int(seconds / 60 / 60 / 24) + seconds = (seconds) % (60 * 60 * 24) + hours = int((seconds / 60 / 60)) + seconds = (seconds) % (60 * 60) + mins = int((seconds / 60)) + seconds = int((seconds) % (60)) + return (days, hours, mins, seconds) + + +def parse_options(): + parser = optparse.OptionParser(usage=USAGE, version=VERSION) + + parser.add_option( + "-t", "--time", + action="store", type="int", default=0, dest="time", + help="Stop after specified elapsed seconds" + ) + + parser.add_option( + "-e", "--events", + action="store", type="int", default=0, dest="events", + help="Stop after specified number of events" + ) + + parser.add_option( + "-p", "--profile", + action="store_true", default=False, dest="profile", + help="Enable execution profiling support" + ) + + parser.add_option( + "-d", "--debug", + action="store_true", default=False, dest="debug", + help="Enable debug mode" + ) + + parser.add_option( + "-m", "--mode", + action="store", type="choice", default="speed", dest="mode", + choices=["sync", "speed", "latency"], + help="Operation mode" + ) + + parser.add_option( + "-s", "--speed", + action="store_true", default=False, dest="speed", + help="Enable psyco (circuits on speed!)" + ) + + parser.add_option( + "-q", "--quiet", + action="store_false", default=True, dest="verbose", + help="Suppress output" + ) + + opts, args = parser.parse_args() + + return opts, args + + +class stop(Event): + """stop Event""" + + +class term(Event): + """term Event""" + + +class hello(Event): + """hello Event""" + + +class received(Event): + """received Event""" + + +class Base(Component): + + def __init__(self, opts, *args, **kwargs): + super(Base, self).__init__(*args, **kwargs) + + self.opts = opts + + +class SpeedTest(Base): + + def received(self, message=""): + self.fire(hello("hello")) + + def hello(self, message): + self.fire(received(message)) + + +class LatencyTest(Base): + + t = None + + def received(self, message=""): + print("Latency: %0.9f us" % ((time() - self.t) * 1e6)) + sleep(1) + self.fire(hello("hello")) + + def hello(self, message=""): + self.t = time() + self.fire(received(message)) + + +class State(Base): + + done = False + + def stop(self): + self.fire(term()) + + def term(self): + self.done = True + + +class Monitor(Base): + + sTime = sys.maxsize + events = 0 + state = 0 + + @handler(filter=True) + def event(self, *args, **kwargs): + self.events += 1 + + if self.events > self.opts.events: + self.stop() + + +def main(): + opts, args = parse_options() + + if opts.speed and psyco: + psyco.full() + + manager = Manager() + + monitor = Monitor(opts) + manager += monitor + + state = State(opts) + manager += state + + if opts.debug: + manager += Debugger() + + if opts.mode.lower() == "speed": + if opts.verbose: + print("Setting up Speed Test...") + manager += SpeedTest(opts) + monitor.sTime = time() + elif opts.mode.lower() == "latency": + if opts.verbose: + print("Setting up Latency Test...") + manager += LatencyTest(opts) + monitor.sTime = time() + + if opts.verbose: + print("Setting up Sender...") + print("Setting up Receiver...") + + monitor.sTime = time() + + if opts.profile: + if hotshot: + profiler = hotshot.Profile("bench.prof") + profiler.start() + + manager.fire(hello("hello")) + + while not state.done: + try: + manager.tick() + + if opts.events > 0 and monitor.events > opts.events: + manager.fire(stop()) + if opts.time > 0 and (time() - monitor.sTime) > opts.time: + manager.fire(stop()) + except KeyboardInterrupt: + manager.fire(stop()) + + if opts.verbose: + print() + + eTime = time() + + tTime = eTime - monitor.sTime + + events = monitor.events + speed = int(math.ceil(float(monitor.events) / tTime)) + + print("Total Events: %d (%d/s after %0.2fs)" % (events, speed, tTime)) + + if opts.profile and hotshot: + profiler.stop() + profiler.close() + + stats = hotshot.stats.load("bench.prof") + stats.strip_dirs() + stats.sort_stats("time", "calls") + stats.print_stats(20) + + +if __name__ == "__main__": + main() diff -Nru circuits-2.1.0/bin/htpasswd circuits-3.1.0+ds1/bin/htpasswd --- circuits-2.1.0/bin/htpasswd 1970-01-01 00:00:00.000000000 +0000 +++ circuits-3.1.0+ds1/bin/htpasswd 2014-09-04 10:32:30.000000000 +0000 @@ -0,0 +1,161 @@ +#!/usr/bin/env python + +"""Pure Python replacement for Apache's htpasswd + +Borrowed from: https://gist.github.com/eculver/1420227 + +Modifications by James Mills, prologic at shortcircuit dot net dot au + +- Added support for MD5 and SHA1 hashing. +""" + + +# Original author: Eli Carter + + +import os +import sys +import random +from hashlib import md5, sha1 +from optparse import OptionParser + +try: + from crypt import crypt +except ImportError: + try: + from fcrypt import crypt + except ImportError: + crypt = None + + +def salt(): + """Returns a string of 2 randome letters""" + letters = 'abcdefghijklmnopqrstuvwxyz' \ + 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' \ + '0123456789/.' + return random.choice(letters) + random.choice(letters) + + +class HtpasswdFile: + """A class for manipulating htpasswd files.""" + + def __init__(self, filename, create=False, encryption=None): + self.filename = filename + + if encryption is None: + self.encryption = lambda p: md5(p).hexdigest() + else: + self.encryption = encryption + + self.entries = [] + + if not create: + if os.path.exists(self.filename): + self.load() + else: + raise Exception("%s does not exist" % self.filename) + + def load(self): + """Read the htpasswd file into memory.""" + lines = open(self.filename, 'r').readlines() + self.entries = [] + for line in lines: + username, pwhash = line.split(':') + entry = [username, pwhash.rstrip()] + self.entries.append(entry) + + def save(self): + """Write the htpasswd file to disk""" + open(self.filename, 'w').writelines(["%s:%s\n" % (entry[0], entry[1]) + for entry in self.entries]) + + def update(self, username, password): + """Replace the entry for the given user, or add it if new.""" + pwhash = self.encryption(password) + matching_entries = [entry for entry in self.entries + if entry[0] == username] + if matching_entries: + matching_entries[0][1] = pwhash + else: + self.entries.append([username, pwhash]) + + def delete(self, username): + """Remove the entry for the given user.""" + self.entries = [entry for entry in self.entries + if entry[0] != username] + + +def main(): + """%prog [-c] -b filename username password + Create or update an htpasswd file""" + # For now, we only care about the use cases that affect tests/functional.py + parser = OptionParser(usage=main.__doc__) + parser.add_option('-b', action='store_true', dest='batch', default=False, + help='Batch mode; password is passed on the command line IN THE CLEAR.' + ) + parser.add_option('-c', action='store_true', dest='create', default=False, + help='Create a new htpasswd file, overwriting any existing file.') + parser.add_option('-D', action='store_true', dest='delete_user', + default=False, help='Remove the given user from the password file.') + + if crypt is not None: + parser.add_option('-d', action='store_true', dest='crypt', + default=False, help='Use crypt() encryption for passwords.') + + parser.add_option('-m', action='store_true', dest='md5', + default=False, help='Use MD5 encryption for passwords. (Default)') + + parser.add_option('-s', action='store_true', dest='sha', + default=False, help='Use SHA encryption for passwords.') + + options, args = parser.parse_args() + + def syntax_error(msg): + """Utility function for displaying fatal error messages with usage + help. + """ + sys.stderr.write("Syntax error: " + msg) + sys.stderr.write(parser.get_usage()) + sys.exit(1) + + if not options.batch: + syntax_error("Only batch mode is supported\n") + + # Non-option arguments + if len(args) < 2: + syntax_error("Insufficient number of arguments.\n") + filename, username = args[:2] + if options.delete_user: + if len(args) != 2: + syntax_error("Incorrect number of arguments.\n") + password = None + else: + if len(args) != 3: + syntax_error("Incorrect number of arguments.\n") + password = args[2] + + if options.crypt: + encryption = lambda p: crypt(p, salt()) + elif options.md5: + encryption = lambda p: md5(p).hexdigest() + elif options.sha: + encryption = lambda p: sha1(p).hexdigest() + else: + encryption = lambda p: md5(p).hexdigest() + + passwdfile = HtpasswdFile( + filename, + create=options.create, + encryption=encryption + ) + + if options.delete_user: + passwdfile.delete(username) + else: + passwdfile.update(username, password) + + passwdfile.save() + + +if __name__ == '__main__': + main() diff -Nru circuits-2.1.0/CHANGES.rst circuits-3.1.0+ds1/CHANGES.rst --- circuits-2.1.0/CHANGES.rst 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/CHANGES.rst 2014-10-31 23:12:37.000000000 +0000 @@ -1,482 +1,90 @@ -circuits-2.1.0 20130224 () ------------------------------------ +:orphan: -Features -........ - - -- Added IPv6 Support [#39987887] -- Document and Comment all Examples [#40112459] -- Update WebSockets dispatcher in circuits.web [40064247] -- Component Event Handlers Property [#41573841] -- Component targeting performance [#41644031] -- Multi-App WSGI Gateway [#40071339] -- More efficient timer implementation [#43700669] - - -Bugs -.... - - -- Fix the broken links in the Users page [#40063597] -- circuits.tools.inspect shows incorrect ticks [#41650961] -- Race Condition with call/wait primitives [#41643711] -- RESTful Dispatcher [#41643773] -- Fix Component instance targeting [#41644025] -- Worker Processes [#41643831] -- Make examples/web/sslserver.py work again [42007509] -- Value instance in body [43287263] - - -Chores -...... - - -- Import shadowing in manager.py [#41644023] -- Run the codebase through flake8 [#41651093] -- URL Quoting Unit Test [#41882655] -- SSL Unit Test [#42849393] -- Python 3.x Support [43027337] -- Fill out FAQ in Docs [#43389199] -- Write Developer Docs [#43389193] - -Other Changes -............. - - -A list of other changes we forgot to track :) - -- Fixed latency timing for circuits.bench on win32 -- Updated the URL for ReadTheDocs -- Updated the Getting Started / Downloading documentation to - say something about the Tags tab for downloading archives. -- Removed unused import in ``circuits.app.env`` -- Added some documentation about how HTTP requests are handled. -- Removed unused code -- A simple chat server implementation (Examples) -- Fixed a bug with Manager.processTasks and Error event firing. - handler was not being set correctly -- Fixes wrong variable names in sockets.py -- Fixed an UnboundLocalError bug -- Expect the original method to be passed as input to ``Manager.removeHandler`` - ``Manager.addHandler`` now returns a reference to the original method. -- Guard against a None _sock or non-existent _sock object. -- Allow a custom host, port and secure option to be passed - to the connect event handler of circuits.web.client.Client -- Redesigned tests/web/conftest.py with newer pytest APIs using - ``@pytest.fixture(...)`` -- Experimental new Watcher/Manager fixtures -- Docs for Fallback generator -- Removing the concept of _ticks, @tick and friends -- Fixes timers -- Reimplemented circuits.io.File as per circuits.net.sockets -- Re-implemented Notify Component and fixed test -- Reworked Notifier Component to be more async friendly -- Fixed a bug with the repr of Manager and thus Components with non-str channels. eg: (1, 1) -- Added a unit test for generate_events handler -- Fixed terminal example demonstrating Streaming with circuits.web -- Fixed index page for terminal web example -- Added an Open event to File -- Fixed a bug with the static dispatcher for circuits.web whereby - the path was not being unquoted -- Fixed a bug with the static circuits.web dispatcher whereby directory - listing did not quote urls -- Added simple examples demonstrating circuits' primitives -- Added example of .fire(...) primitive -- Restructured circuits.io and implemented circuits.io.Process with unit test -- Added Hello World example -- Made components started in process mode not link by default. - Have to explicitly set the kwarg ``link=component_instance``. -- Fixed raising of ``SystemExit`` or ``KeyboardInterrupt``. -- Modified the way caching works with the Static dispatcher - -- Brought back the ``circuits.core.bridge.Bridge``. - With it better inter-process communications via high-speed full duplex pipes - using ``circuits.net.sockets.Pipe`` (UNIX Only), a much simpler API. - - In addition, a change to the way Value Notification works. .notify of an - event instance can either be True or a channel to send the ValueChanged - event to. - -- Added timers examples resurrected from old circuits - -- Global handlers and component targeting - Global handlers would be ignored when using component targeting. - - This patch considers them. To do this, we have added an extra property - to managers. - - You can use traverse_children_handlers to increase performance when you have - a huge number of components. Put the components that are only meant to be - used with component targeting under a single component. The hierarchy - looks like this: - - .. code-block:: python - - Root -> Umbrella Component -> Component 1, Component 2, Component 3, ... - -> Debugger() - -> etc - -- Set Umbrella Component traverse_children_handlers to false to prevent - traversing the huge number of children components. -- Fixed Connection header interpretation. -- Updated documentation for WebSocket. -- Removed pool - covered by worker -- Fixed dispatchers return value. -- Firing Connect event when a web socket connection is established to make - behavior look even more like ordinary sockets. -- Nuked ``@future`` decorator due to pickling problems for processes. -- Allow coroutine-style tasks to terminate the system via raise - of ``SystemExit`` or ``KeyboardInterrupt`` -- Dropping events unnoticed when waiting is definitely a bad idea. Fixed. -- Clarification on implementing a GenerateEvents handler. -- Optimized GenerateEvents handling. -- Optimized management of FallbackGenerator. -- Fixed a problem with events being out of sequence when _fire - is called recursively. The fix exposes a problem with conftest.Waiter - (events getting lost because they are produced too fast, therefore queue - is increased). Reducing production rate will be in next commit. -- Small fix for new event queue handling. -- Fixed problem with handler cache update and concurrent event - handling/structure changes. This happens e.g. in unit tests when the - app is started and the test program adds or removes components concurrently. -- Optimized/clarified GenerateEvents implementation. -- One more concurrency problem fixed. -- Fixed generate events handler. -- Fixed bug with handler cache being always invalidated. - Avoid ``stop()`` acting as concurrent thread on ``_dispatcher()`` -- Fixed payload length calculation in web sockets protocol. -- Some very small - but measurable - performance improvements. - Checking them in mainly because now no one else needs to think about - whether they have an effect. -- Fixed IPv6 socket tests for OSX and badly configured IPv6 networks -- Fixed ready handler for test_node -- Re-added an old revived example of an IRC Client integrating - the urwid curses library for the interface -- Added an example of using yield to perform cooperative multi-tasking - inside a request event handler -- Uses echo for test_process - -- Fixes process stdout/stderr handling - Process was not waiting for all output from a process to have been - processed and resulted sometimes some of the process output being lost - while stopping. - -- Added a fall back error handler, so problems aren't discarded silently - any more. -- Fixed a TypeError being raised in the request handler for WebSockets - dispatcher -- Prevent the underlying TCPClient connect handler from inadvertently being - triggered by connect events being fired to the web client -- Added tox configuration file. Just run: ``tox`` -- Configure tox to output junitxml -- Fixed the logic of path -> wsgi dispatching in Gateway -- Fixed an awful bug with wrappers.Response whereby a default Content-Type was - always set regardless and didn't allow anything else to set this. -- Fixed test_disps so it doesn't use an existing port that's in use. -- Added a missing piece of WSGI 1.0 functionality for wsgi.Gateway. - The ``write()`` callable -- Rewrite test_filer unit test. - Ensured EOF event is not triggered for files opened in a or + modes. -- Added simple examples demonstrating circuits' primitives -- Added example of .fire(...) primitive -- Restructured circuits.io and implemented circuits.io.Process with unit test -- Forgot to add test_process unit test -- Added Hello World example -- Fixed event handler for generate_events -- Implemented multiprocessing support with communication via full duplex pipes. - Fixed worker processes and added unit test -- Made components started in process mode not link by default. - Have to explicitly set the kwarg link=True -- Fixed process pools and added unit test -- Fixed name of method for handling inotify events - - conflicting with ._process of Manager/Component -- Renamed ._process to .__process so as to not conflict with Worker -- Fixed raising of SystemExit or KeyboardInterrupt -- Trying to fix sending/receiving of events and their values -- Fixed IPv6 address evaluation. -- WebSockets reimplemented as specified by RFC 6455. -- Modified the way caching works with the Statis dispatcher - and serve_file(...) function. Set Last-Modified instead of a - large Expires header. -- Marked as a Missing Feature - still being worked on. -- Brought back the ``circuits.core.bridge.Bridge``. - With it better inter-process communications via high-speed full duplex pipes - using ``circuits.net.sockets.Pipe`` (UNIX Only), a much simpler API. - - In addition, a chnage to the way Value Notification works. .notify of an - event instance can either be True or a channel to send the ValueChanged - event to. -- Causes errors. Wrong thing to do here. -- Use uuid4 for worker channels. -- Removed left over debugging code -- Added capability of components started in proces mode to - link to artbritrary managers other than themselves (if link=True) -- Added unit test for testing a component in process mode linked with - another parent system separately -- Added timers examples ressurected from old circuits -- Thread safety for watcher -- Reverts test_component_targeting.py -- Fixed Connection header interpretation. -- Updated documentation for WebSocket. -- Changed the way process linking works by not starting the parent in - thread mode. -- Fixes watcher test fixture -- Implemented .handlers() and re-implemented .handles(). [Delivers #41573841] -- Removed superfluous bridge test -- Fixed usage of .start starting Workers in process mode -- Better internal variable name -- Start worked either when the system starts or we are - regsitered to an already started system -- Implemented .handlers() correctly -- Set unique channels for the Pipe and Bridge when briding processes -- Removed. Going to reimplement all this -- Don't cause a nastry fork bomb\! -- Marked test_process_pool as skipping XXX: Broken Functionality -- Fixed sleeping when nothing to do adding needs_resume logic to the pollers -- Proposed new Worker Component -- wrapping multiprocessing.Process -- Accidentla commit -- Trying to re-implement Pool... -- Marked some tests as broken -- Added support for both Process and Thread in Worker component with same API. -- Reverted changes to the task handler for Worker -- Removed .resume() -- Fixed some brokeness in future -- Trying to make @future work with Worker in process mode -- Lock bench -- Switches worker to apply_async -- Allow the poller to sleep when tasks are running -- Use ThreadPool for worker threads -- Cleaned up Worker -- benchmark only branch -- Removed pool - covered by worker -- Workaround for Threadpool bug started from secondary threads -- Fixed dispatchers return value. -- Firing Connect event when a web socket connection is established to make - behavior look even more like ordinary sockets. -- Restored 2.0.1 GenerateEvents handling with minor enhancements to get - things working again. -- Nuked @future decotator due to pickling problems for processes. -- Unmarked test as failing. Test now passes prefectly -- Allow coroutine-style tasks to terminate the system - via raise of SystemExit or KeyboardINterrupt -- Fixed SSL support for circuits.web [Delivers #42007509] -- Dropping events unnoticed when waiting is definitely a bad idea. Fixed. -- Clarification on implementing a GenerateEvents handler. -- Added missing import (timed wait with FallBackGenerator cannot have - worked for some time). -- Optimized GenerateEvents handling. -- Backed out of changeset 3413:98d0056ef18a -- Optimized management of FallbackGenerator. -- Fixed a problem with events being out of sequence when _fire is called - recursively. The fix exposes a problem with conftest.Waiter - (events getting lost because they are produced too fast, - therefore queue is increased). Reducing production rate will be in - next commit. -- Small fix for new event queue handling. -- Fixed problem with handler cache update and concurrent event - handling/structure changes. This happens e.g. in unit tests when the - app is started and the test program adds or removes components concurrently. -- Optimized/clarified GenerateEvents implementation. -- One more concurrency problem fixed. -- Fixed generate events handler. -- Fixed bug with handler cache being always invalidated. - Avoid stop() acting as concurrent thread on _dispatcher(). -- Added unit test for url quoting of static files for the static - circuits.web dispatcher. [Delivers #41882655] -- Added unit test for secure circutis.web server. [Delivers #42849393] -- Fixed creation/registration/location of poller upon startup or registration -- Skip test_secure_server if ssl is not available -- Fixed payload length calculation in web sockets protocol. -- Some very small - but measurable - performance improvements. - Checking them in mainly because now no one else needs to think - about whether they have an effect. -- Fixed conflicting attribute. -- Added new .pid property to Manager fixing tests.core.test_bridge - - Broken by 70677b69bf05 -- Fixed ipv6 socket tests for OSX and badly configured IPv6 networks -- Ugly fix for this test -- Fixed ready handler for test_node -- For some reason removing max_events in the Watcher fixture for esting - purposes fixes some tests on OSX -- Small sample to hopefully test for memory leaks :) -- Improved .handlers() to recursively return handlers of it's subclasses - whilst filtering out private handlers (_.*) -- Use BaseComponent for convenience for non-handler methods -- Return a list of all handlers except handlers listneing to private events -- Left over print - oops :) -- Moved to examples/ -- Re-added an old revived example of an IRC Client integrating the urwid - curses library for the interface -- Improved comment. -- Added multi-add support for Gateway web compnoent [Delivers #40071339] -- Fixed Python 3 compatibility for retrieving the .resumse() method. - Fixes Issue #35 -- Removed unused StringIO import -- A bunch of Python 3.1 compatibility fixes (mostly import fixes) -- Added an example of using yield to perform cooperative multi-tasking - inside a request event handler -- Uses echo for test_process -- Fixes process stdout/stderr handling - Process was not waiting for all output from a process to have been - processed and resulted sometimes some of the process output being lost - while stopping. -- A bunch more Python 3 fixes. Using the six module here. -- Added a fall back error handler, so problems aren't discarded - silently any more. -- Ooops accidently committed this -- Fixed some Python 3 import issues -- More Python 3 fixes -- Fixed Python 3 issue with iterators -- Use range for Python 3 compatibility -- Fixed assertions for Python 3 compat -- Accidently commited a test with Debugger -- Fixed value_changed handler to check correctly for binary types - (Python 3 fixes) -- Python 3 fixes for string type checks -- Refactored for Python 3 -- More Python 3 fixes. Marked the rest as Broken on Python 3 -- Fixed broken web tests for Python 3 by wrapping the request - body in a TextIOWrapper for FieldStorage -- Fixed XML and JSON RPC Dispatchers for Python 3 -- Replace .has_key() with in for Python 3 compatibility -- Fixed a TypeError being raised in the request handler for websockets - dispatcher -- Prevent the underlying TCPClient connect handler from inadvertently - being triggered by connec events being fired to the web client -- Unmarked as skipping. No longer broken on Python 3 -- Finished cleaning up my code base. -- Removed some debugging junk I had forgotten to get rid of. -- Fixed File for Python 3 support adding optional encoding support -- Fixed Process for Python 3 -- Ooops :/ -- Fixed test_logger_Error for Python 3 -- Fixed Bridge for Python 3 -- Fixed Node for Python 3 -- Added pytest.PYVER and Marked test_secure_server web test as Broken - on Python 3.2 (needs fixing) -- Marked a bunch of 3.2 and 3.3 specific tests that are broken with - these versions (needs looking into) -- Removed Broken on Python 3 marked - these tests now pass on 3.1 3.2 and 3.3 -- Fixed SSL Sockets for Python 3.2/3.3 (Should do_handshake() - be executed in a thread?) -- Added tox configuration file. Just run: run -- Configure tox to output junitxml -- Fixed tox configuration -- Assuming localhost was incorrect. Sorry Mark :/ -- Fixed test_logger for pypy -- Backed out changeset 7be64d8b6f7c -- Reconfigured tox settings -- Hopefully fixed tox.ini to detect jenkins -- Fixed tox.ini to work on jenkins (can't seem to auto detect jenkins :/) -- Added tox config for checking documetnation -- Changed the output filename of xml resutls for docs env (tox) -- Added pytest-cov as a dep to the docs env (tox) -- Configured coverage to output xml output -- Removed ptest-cov dep from docs env (tox) -- Trying to fix the randomly failing test_node test. -- Ooops broke wait_for - fixed hopefully -- Backed out changeset 795712654602 -- Backed out changeset 1ee04d5fb657 -- Added ignore for generated junitxml output files -- Hopefully an improved unit test for node using the manager and watcher - fixtures. -- Updated with supported version of Python -- Fixed the logic of path -> wsgi dispatching in Gateway -- Fixed an awful bug with wrappers.Response whereby - a default Content-Type was always set regardless and didn't allow - anything else to set this. -- Fixed test_disps so it doesn't use an existing port that's in use. -- Added a missing piece of WSGI 1.0 functionality for wsgi.Gateway - -- The write() callable -- Write bytes in this test -- Correctly handle unicode (I think) -- Fixed a bug with null responses from WSGI Applications - hosted by wsgi.Gateway. Empty class did not implement __nonzero__ - for Python 2.x [Delivers #43287263] -- Remvoed pyinotify dep from tox config so Windows tests can run -- Skip test_unixserver for Windows -- Skip this test on Windows -- Skip these tests on Windows -- Skip this test on Windows -- Fixed test_tcp_bind for Windows -- Updated docs and re-added FAQ from old wiki - (updated slightly) [Delivers #43389199] -- Fixed bottom of FAQ -- Updated Change Log [#42945315] -- Updated Release Notes [#42945315] -- Fixed list of new changes for 2.1.0 release notes -- Updated Developet Docs -- Bumped version to 2.1.0 -- More resource efficient timer implementation [Delivers #43700669]. -- Fixed a problem with cLength being unknown if self.body == False. -- Test fails on shining panda py32 only. May be a race condition - (wait_for using same loop interval as timer interval). - Checking in for testing. -- Fixed problem with "Content-Length: 0" header not being generated for - empty responses. -- Backed out of changeset 3575:ece3ee5472ef, makes CI hang for unknown reason. -- Hopefully finally fixed problems with timer test on CI platform. -- Updated pypi classifier for circuits -- Fixed random problems with opening SSL socket. -- Fixed concurrence problem (doing reset() in event loop and calling unregister() concurrently). -- Modified test a bit to find out what happens in CI environment - (problem not reproducible in local py32). -- Calling headers.setdefault twice for the same name doesn't make sense. -- Adapted test case to previous fix. -- Fixed problem with "Content-Length: 0" header not being generated - for empty responses. -- Fixed insecure usage of class variable. -- Reverted to old timer implementation. Cannot find bug in new version - that only occurs in CI/py32 environment (cannot be reproduced locally). -- Make sure that check runs faster than timer increments. -- Added missing Content-Length header (must be present according to RFC 2616). -- Provide a more informative representation. -- Fixed a docstring typo -- Just re-raise the exception here rather than hide it with - an InternalServer exception -- Potential failing test for [#43885227] -- Fixed problem with receiving incomplete header data (first chunk doesn't - already include empty line that separates headers and body). -- Fixed problem with header not being detected if a chunk ends exactly after - \r\n of last header line and next chunk starts with empty line (\r\n) - before body. -- Fixes inconsisent semantic behavior in channel selection. -- Fixed expression for _handler_channel in Manager.getHandlers(...) -- Fixed (and simplified) handler_channel evaluation. -- Fixed channel representation for cases where channel is a component. -- Adapted prepare_unregister_complete handling to fixed semantics for - using managers as channels. -- Notifications are to be signaled to the given manager. - Now that using managers as channels works properly, it showed that hey - never were. -- Value change notifications are fired using Value's manager as channel, - so mke sure to listen on that. -- Value's notifications are fired on its manager component - -- by default the component that fired the event the value belongs to. - Moved handler to proper place (is better place anyway). -- Encoding is necessary for this to succeed on py3.2 - (urllib2 there doesn't accept body of type str). -- Added missing files to manifest. [Delivers #44650895] (Closes Issue #36) -- Fixing encoding problems. -- Fixing py2/py3 problem by using bytearray as abviously the only - common denominator. -- multipart/form-data is binary. Boundaries are ASCII, - but data between boundaries may be anything (depending on part's header) -- Trying to fix unicode issues -- Marked test_node as Broken on Windows - Pickling Error with thread.lock -- Trying to fix broken unit test on Windows -- Setup docs with Google Analyitics -- Marked test_tcp_connect_closed_port(...) as Broken on Windows - -- Need to fix this; this test is a bit weird :/ -- Marked test_tcp_reconnect(...) test as Broken on Windows -- Updated state of test_tcp_reconnect(...) test on Windows - -- Apparently only Broken on Windows on Python 3.2 (odd) -- Fixed TypeError -- Marked as Broken on pypy - -- For some reason we're getting \x00 (null bytes) - in the stream when using the Python std lib logger. -- Marked tests.core.test_debugger.test_filename(...) as Broken on pypy - -- Need to investigate this -- Updated support platforms to include pypy +========== +Change Log +========== + + +- :release:`3.1 <2014-11-01>` +- :bug:`-` Bridge waits for event processing on the other side before proxy handler ends. Now it is possible to collect values from remote handlers in %_success event. +- :bug:`-` Rename the FallbackErrorHandler to FallbackExceptionHandler and the event it listens to to exception +- :bug:`-` Fixes optional parameters handling (client / server). +- :bug:`-` Node: add peer node: return channel name. +- :bug:`-` Node: add event firewall (client / server). +- :bug:`-` Node: fixes the event value issue. +- :bug:`-` Node: fixes event response flood. +- :bug:`-` Node: Add node examples. +- :bug:`-` Fixed import of FallBackExceptionHandler +- :bug:`-` Fixed exception handing in circuits.web +- :bug:`-` Fixed issue in brige with ommiting all but the first events sent at once +- :bug:`-` Bridge: Do not propagate no results via bridge +- :bug:`-` Bridge: Send exceptions via brige before change the exceptions weren't propagated via bridge because traceback object is not pickable, now traceback object is replaced by corresponding traceback list +- :bug:`113` Fixed bug with forced shutdown of subprocesses in Windows. +- :bug:`115` Fixed FallbackErrorHandler API Change + +- :release:`3.0.1 <2014-11-01>` +- :support:`117` Fixed inconsistent top-level examples. +- :support:`96` Link to ChangeLog from README + +- :release:`3.0 <2014-08-31>` +- :bug:`111 major` Fixed broken Digest Auth Test for circuits.web +- :feature:`112` Improved Signal Handling +- :bug:`109 major` Fixed ``Event.create()`` factory and metaclass. +- :feature:`108` Improved server support for the IRC Protocol. +- :bug:`107 major` Added ``__le__`` and ``__ge__`` methods to ``circuits.web.wrappers.HTTPStatus`` +- :bug:`106 major` Added ``__format__`` method to circuits.web.wrappers.HTTPStatus. +- :bug:`104 major` Prevent other websockets sessions from closing. +- :feature:`103` Added the firing of a ``disconnect`` event for the WebSocketsDispatcher. +- :bug:`102 major` Fixed minor bug with WebSocketsDispatcher causing superflusous ``connect()`` events from being fired. +- :bug:`100 major` Fixed returned Content-Type in JSON-RPC Dispatcher. +- :feature:`99` Added Digest Auth support to the ``circuits.web`` CLI Tool +- :feature:`98` Dockerized circuits. See: https://docker.io/ +- :bug:`97 major` Fixed ``tests.net.test_tcp.test_lookup_failure`` test for Windows +- :support:`95` Updated Developer Documentation with corrections and a new workflow. +- :feature:`94` Modified the :class:`circuits.web.Logger` to use the ``response_success`` event. +- :support:`86` Telnet Tutorial +- :bug:`47 major` Dispatcher does not fully respect optional arguments. web +- :support:`61` circuits.web documentation enhancements docs +- :support:`85` Migrate away from ShiningPanda +- :support:`87` A rendered example of ``circuits.tools.graph()``. docs +- :support:`88` Document the implicit registration of components attached as class attributes docs +- :bug:`89 major` Class attribtues that reference methods cause duplicate event handlers core +- :support:`92` Update circuitsframework.com content docs +- :support:`71` Document the value_changed event docs +- :support:`78` Migrate Change Log maintenance and build to Releases +- :bug:`91 major` Call/Wait and specific instances of events +- :bug:`59 major` circuits.web DoS in serve_file (remote denial of service) web +- :bug:`66 major` web examples jsonserializer broken web +- :support:`73` Fix duplication in auto generated API Docs. docs +- :support:`72` Update Event Filtering section of Users Manual docs +- :bug:`76 major` Missing unit test for DNS lookup failures net +- :support:`70` Convention around method names of event handlers +- :support:`75` Document and show examples of using circuits.tools docs +- :bug:`81 major` "index" method not serving / web +- :bug:`77 major` Uncaught exceptions Event collides with sockets and others core +- :support:`69` Merge #circuits-dev FreeNode Channel into #circuits +- :support:`65` Update tutorial to match circuits 3.0 API(s) and Semantics docs +- :support:`60` meantion @handler decorator in tutorial docs +- :bug:`67 major` web example jsontool is broken on python3 web +- :support:`63` typos in documentation docs +- :bug:`53 major` WebSocketClient treating WebSocket data in same TCP segment as HTTP response as part the HTTP response. web +- :bug:`62 major` Fix packaging and bump circuits 1.5.1 for @dsuch (*Dariusz Suchojad*) for `Zato `_ +- :bug:`56 major` circuits.web HEAD request send response body web +- :bug:`45 major` Fixed use of ``cmp()`` and ``__cmp__()`` for Python 3 compatibility. +- :bug:`48 major` Allow ``event`` to be passed to the decorated function (*the request handler*) for circuits.web +- :bug:`46 major` Set ``Content-Type`` header on response for errors. (circuits.web) +- :bug:`38 major` Guard against invalid headers. (circuits.web) +- :bug:`37 major` Fixed a typo in :class:`~circuits.io.file.File` + + +Older Change Logs +================= + +For older Change Logs of previous versions of circuits please see the respective `PyPi `_ page(s): + +- `circuits-2.1.0 `_ +- `circuits-2.0.1 `_ +- `circuits-2.0.0 `_ +- `circuits-1.6 `_ +- `circuits-1.5 `_ diff -Nru circuits-2.1.0/circuits/app/config.py circuits-3.1.0+ds1/circuits/app/config.py --- circuits-2.1.0/circuits/app/config.py 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/app/config.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,96 +0,0 @@ -# Module: config -# Date: 13th August 2008 -# Author: James Mills, prologic at shortcircuit dot net dot au - -"""Config - -Configuration Component. This component uses the standard -ConfigParser.ConfigParser class and adds support for saving -the configuration to a file. -""" - - -try: - from configparser import ConfigParser -except ImportError: - from ConfigParser import ConfigParser # NOQA - -from circuits import handler, BaseComponent, Event - - -class ConfigEvent(Event): - """Config Event""" - - channels = ("config",) - - success = True - failure = True - - -class Load(ConfigEvent): - """Load Config Event""" - - -class Save(ConfigEvent): - """Save Config Event""" - - -class Config(BaseComponent): - - channel = "config" - - def __init__(self, filename, defaults=None, channel=channel): - super(Config, self).__init__(channel=channel) - - self._config = ConfigParser(defaults=defaults) - self._filename = filename - - @handler("load") - def load(self, filename=None): - self._filename = filename or self._filename - self._config.read([self._filename]) - - @handler("save") - def save(self, filename=None): - self._filename = filename or self._filename - with open(self._filename, "w") as f: - self._config.write(f) - - def add_section(self, section): - return self._config.add_section(section) - - def items(self, section, raw=False, vars=None): - return self._config.items(section, raw=False, vars=None) - - def get(self, section, option, default=None, raw=False, vars=None): - if self._config.has_option(section, option): - return self._config.get(section, option, raw=raw, vars=vars) - else: - return default - - def getint(self, section, option, default=0): - if self._config.has_option(section, option): - return self._config.getint(section, option) - else: - return default - - def getfloat(self, section, option, default=0.0): - if self._config.has_option(section, option): - return self._config.getfloat(section, option) - else: - return default - - def getboolean(self, section, option, default=False): - if self._config.has_option(section, option): - return self._config.getboolean(section, option) - else: - return default - - def has_section(self, section): - return self._config.has_section(section) - - def has_option(self, section, option): - return self._config.has_option(section, option) - - def set(self, section, option, value): - return self._config.set(section, option, value) diff -Nru circuits-2.1.0/circuits/app/daemon.py circuits-3.1.0+ds1/circuits/app/daemon.py --- circuits-2.1.0/circuits/app/daemon.py 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/app/daemon.py 2014-09-04 10:32:30.000000000 +0000 @@ -2,44 +2,36 @@ # Date: 20th June 2009 # Author: James Mills, prologic at shortcircuit dot net dot au + """Daemon Component -Component to daemonizae a system into the background and detach it from its +Component to daemonize a system into the background and detach it from its controlling PTY. Supports PID file writing, logging stdin, stdout and stderr and changing the current working directory. """ -import os -import sys -import errno -from circuits.core import handler, BaseComponent, Event +from os.path import isabs +from sys import stderr, stdin, stdout +from os import _exit, chdir, dup2, setsid, fork, getpid, remove, umask -class Daemonize(Event): - """Daemonize Event +from circuits.core import handler, Component, Event - This event can be fired to notify the `Daemon` Component to begin the - "daemonization" process. This event is (*by default*) used - automatically by the `Daemon` Component in its "started" Event - Handler (*This behavior can be overridden*). - Arguments: *None* - """ +class daemonize(Event): + """daemonize Event""" -class WritePID(Event): - """"WritePID Event +class deletepid(Event): + """"deletepid Event""" - This event can be fired to notify the `Daemon` Component that is should - retrive the current process's id (pid) and write it out to the - configured path in the `Daemon` Component. This event (*by default*) - is used automatically by the `Daemon` Component after the - :class:`Daemonize`. - """ +class writepid(Event): + """"writepid Event""" -class Daemon(BaseComponent): + +class Daemon(Component): """Daemon Component :param pidfile: .pid filename @@ -57,81 +49,87 @@ channel = "daemon" - def __init__(self, pidfile, path="/", stdin=None, stdout=None, - stderr=None, channel=channel): - "x.__init__(...) initializes x; see x.__class__.__doc__ for signature" - - super(Daemon, self).__init__(channel=channel) - - assert os.path.isabs(path), "path must be absolute" - - if os.path.isabs(pidfile): - self._pidfile = pidfile - else: - self._pidfile = os.path.join(path, pidfile) - - self._path = path - - stdio_attrs = ["_stdin", "_stdout", "_stderr"] - for i, stdio in enumerate([stdin, stdout, stderr]): - if stdio and os.path.isabs(stdio): - setattr(self, stdio_attrs[i], stdio) - elif stdio: - setattr(self, stdio_attrs[i], os.path.join(path, stdio)) - else: - setattr(self, stdio_attrs[i], "/dev/null") - - @handler("write_pid") - def _on_writepid(self): - f = open(self._pidfile, "w") - f.write(str(os.getpid())) - f.close() - - @handler("daemonize") - def _on_daemonize(self): - # Do first fork. + def init(self, pidfile, path="/", stdin=None, stdout=None, + stderr=None, channel=channel): + + assert isabs(path), "path must be absolute" + + self.pidfile = pidfile + self.path = path + + self.stdin = ( + stdin if stdin is not None and isabs(stdin) else "/dev/null" + ) + + self.stdout = ( + stdout if stdout is not None and isabs(stdout) else "/dev/null" + ) + + self.stderr = ( + stderr if stderr is not None and isabs(stderr) else "/dev/null" + ) + + def deletepid(self): + remove(self.pidfile) + + def writepid(self): + with open(self.pidfile, "w") as fd: + fd.write(str(getpid())) + + def daemonize(self): try: - pid = os.fork() + pid = fork() if pid > 0: - # Exit first parent - os._exit(0) + # exit first parent + _exit(0) except OSError as e: - print >> sys.stderr, "fork #1 failed: (%d) %s\n" % (errno, str(e)) + stderr.write( + "fork #1 failed: {0:d} ({0:s})\n".format( + e.errno, str(e) + ) + ) + raise SystemExit(1) - # Decouple from parent environment. - os.chdir(self._path) - os.umask(0o077) - os.setsid() + # decouple from parent environment + chdir(self.path) + setsid() + umask(0) - # Do second fork. + # do second fork try: - pid = os.fork() + pid = fork() if pid > 0: - # Exit second parent - os._exit(0) + # exit from second parent + _exit(0) except OSError as e: - print >> sys.stderr, "fork #2 failed: (%d) %s\n" % (e, str(e)) + stderr.write( + "fork #2 failed: {0:d} ({0:s})\n".format( + e.errno, str(e) + ) + ) + raise SystemExit(1) - # Now I am a daemon! + # redirect standard file descriptors + stdout.flush() + stderr.flush() - # Redirect standard file descriptors. - si = open(self._stdin, "r") - so = open(self._stdout, "a+") - se = open(self._stderr, "a+") - os.dup2(si.fileno(), sys.stdin.fileno()) - os.dup2(so.fileno(), sys.stdout.fileno()) - os.dup2(se.fileno(), sys.stderr.fileno()) + si = open(self.stdin, "r") + so = open(self.stdout, "a+") + se = open(self.stderr, "a+") - self.fire(WritePID()) + dup2(si.fileno(), stdin.fileno()) + dup2(so.fileno(), stdout.fileno()) + dup2(se.fileno(), stderr.fileno()) - @handler("started", filter=True, priority=100.0, channel="*") - def _on_started(self, component): - if component is not self: - self.fire(Daemonize()) + self.fire(writepid()) - @handler("registered") - def _on_registered(self, component, manager): + def registered(self, component, manager): if component == self and manager.root.running: - self.fire(Daemonize()) + self.fire(daemonize()) + + @handler("started", priority=100.0, channel="*") + def on_started(self, component): + if component is not self: + self.fire(daemonize()) diff -Nru circuits-2.1.0/circuits/app/env.py circuits-3.1.0+ds1/circuits/app/env.py --- circuits-2.1.0/circuits/app/env.py 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/app/env.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,188 +0,0 @@ -# Module: env -# Date: 10th June 2006 -# Author: James Mills, prologic at shortcircuit dot net dot au - -"""Environment Component - -An Environment Component that by default sets up a Config and Logger -components and is used to create, load and manage system/application -environments. -""" - -from os import mkdir -from os import makedirs -from os.path import abspath, isabs, join as joinpath - -from circuits import handler, BaseComponent, Event - -from . import config -from .config import Config - -from .log import Logger - - -VERSION = 1 - -CONFIG = { - "general": { - "pidfile": joinpath("%(path)s", "log", "%(name)s.pid"), - }, - "logging": { - "debug": "True", - "type": "file", - "verbose": "True", - "level": "DEBUG", - "file": joinpath("%(path)s", "log", "%(name)s.log"), - } -} - -ERRORS = ( - (0, "No Environment version information",), - (1, "Environment needs upgrading",), -) - - -def createFile(filename, data=None): - fd = open(filename, "w") - if data: - fd.write(data) - fd.close() - - -class EnvironmentError(Exception): - """Environment Error""" - - -class EnvironmentEvent(Event): - """Environment Event""" - - channels = ("env",) - - -class Ready(EnvironmentEvent): - """Ready Environment Event""" - - -class Create(EnvironmentEvent): - """Create Environment Event""" - - success = True - failure = True - - -class Load(EnvironmentEvent): - """Load Environment Event""" - - success = True - failure = True - - -class Verify(EnvironmentEvent): - """Verify Environment Event""" - - success = True - failure = True - - -class Upgrade(EnvironmentEvent): - """Upgrade Environment Event""" - - success = True - failure = True - - -class Environment(BaseComponent): - """Base Environment Component - - Creates a new environment component that by default only - holds configuration and logger components. - - This component can be extended to provide more complex - system and application environments. - """ - - channel = "env" - - version = VERSION - - def __init__(self, path, envname, channel=channel): - super(Environment, self).__init__(channel=channel) - - self.path = abspath(path) - self.envname = envname - - @handler("create", priority=1.0) - def create(self): - return self._create() - - @handler("load", priority=1.0) - def load(self, verify=False): - if verify: - return self.fire(Verify()) - else: - return self._load() - - @handler("verify", priority=1.0) - def _on_verify(self): - f = open(joinpath(self.path, "VERSION"), "r") - version = f.read().strip() - f.close() - - if not version: - raise EnvironmentError(*ERRORS[0]) - else: - if self.version > int(version): - raise EnvironmentError(*ERRORS[1]) - - @handler("verify_success", filter=True) - def _on_verify_success(self, evt, retval): - return self._load() - - @handler("load_success", channel="config") - def _on_config_load_success(self, evt, retval): - # Create Logger Component - logname = self.envname - logtype = self.config.get("logging", "type", "file") - loglevel = self.config.get("logging", "level", "INFO") - logfile = self.config.get("logging", "file", "/dev/null") - logfile = logfile % {"name": self.envname} - if not isabs(logfile): - logfile = joinpath(self.path, logfile) - self.log = Logger(logfile, logname, logtype, loglevel).register(self) - self.fire(Ready()) - - def _create(self): - # Create the directory structure - makedirs(self.path) - mkdir(joinpath(self.path, "log")) - mkdir(joinpath(self.path, "conf")) - - # Create a few files - createFile(joinpath(self.path, "VERSION"), "%d" % self.version) - createFile( - joinpath(self.path, "README"), - "This directory contains a %s Environment." % self.envname - ) - - # Setup the default configuration - configfile = joinpath(self.path, "conf", "%s.ini" % self.envname) - createFile(configfile) - self.config = Config(configfile).register(self) - for section in CONFIG: - if not self.config.has_section(section): - self.config.add_section(section) - for option, value in CONFIG[section].items(): - if type(value) == str: - value = value % { - "name": self.envname, - "path": self.path, - } - self.config.set(section, option, value) - return self.fire(config.Save(), self.config) - - def _load(self): - # Create Config Component - configfile = joinpath(self.path, "conf", "%s.ini" % self.envname) - self.config = Config(configfile).register(self) - self.fire(config.Load()) - return True diff -Nru circuits-2.1.0/circuits/app/__init__.py circuits-3.1.0+ds1/circuits/app/__init__.py --- circuits-2.1.0/circuits/app/__init__.py 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/app/__init__.py 2014-09-04 10:32:30.000000000 +0000 @@ -7,16 +7,12 @@ Contains various components useful for application development and tasks common to applications. -:copyright: CopyRight (C) 2004-2012 by James Mills +:copyright: CopyRight (C) 2004-2013 by James Mills :license: MIT (See: LICENSE) """ -from .log import Logger -from .config import Config from .daemon import Daemon -from .env import Environment -from .startup import Startup -__all__ = ("Logger", "Config", "Daemon", "Environment", "Startup",) +__all__ = ("Daemon",) # flake8: noqa diff -Nru circuits-2.1.0/circuits/app/log.py circuits-3.1.0+ds1/circuits/app/log.py --- circuits-2.1.0/circuits/app/log.py 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/app/log.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,92 +0,0 @@ -# Module: logging -# Date: 11th June 2006 -# Author: James Mills - -"""Logging Components""" - - -import sys -import logging -from logging import DEBUG, INFO, WARNING, WARN, ERROR, CRITICAL - -from circuits.core import handler, Event, BaseComponent - - -class Log(Event): - """Log Event""" - - channels = ("logger",) - - -class Logger(BaseComponent): - - channel = "logger" - - LEVELS = { - "debug": DEBUG, "info": INFO, "warning": WARNING, - "warn": WARN, "error": ERROR, "exception": ERROR, - "critical": CRITICAL - } - - def __init__(self, filename, name, type, level, channel=channel): - super(Logger, self).__init__(channel=channel) - - self.logger = logging.getLogger(name) - - type = type.lower() - if type == "file": - hdlr = logging.FileHandler(filename) - elif type in ["winlog", "eventlog", "nteventlog"]: - # Requires win32 extensions - hdlr = logging.handlers.NTEventLogHandler(name, type="Application") - elif type in ["syslog", "unix"]: - hdlr = logging.handlers.SysLogHandler("/dev/log") - elif type in ["stderr"]: - hdlr = logging.StreamHandler(sys.stderr) - else: - raise ValueError - - format = name + "[%(module)s] %(levelname)s: %(message)s" - if type == "file": - format = "%(asctime)s " + format - dateFormat = "" - level = level.upper() - if level in ["DEBUG", "ALL"]: - self.logger.setLevel(logging.DEBUG) - dateFormat = "%X" - elif level == "INFO": - self.logger.setLevel(logging.INFO) - elif level == "ERROR": - self.logger.setLevel(logging.ERROR) - elif level == "CRITICAL": - self.logger.setLevel(logging.CRITICAL) - else: - self.logger.setLevel(logging.WARNING) - - formatter = logging.Formatter(format, dateFormat) - hdlr.setFormatter(formatter) - self.logger.addHandler(hdlr) - - @handler("log") - def _on_log(self, level, msg, *args, **kwargs): - self.logger.log(self.LEVELS[level.lower()], msg, *args, **kwargs) - - def debug(self, msg, *args, **kwargs): - self.logger.debug(msg, *args, **kwargs) - - def info(self, msg, *args, **kwargs): - self.logger.info(msg, *args, **kwargs) - - def warning(self, msg, *args, **kwargs): - self.logger.warning(msg, *args, **kwargs) - - warn = warning - - def error(self, msg, *args, **kwargs): - self.logger.error(msg, *args, **kwargs) - - def exception(self, msg, *args, **kwargs): - self.logger.exception(msg, *args) - - def critical(self, msg, *args, **kwargs): - self.logger.critical(msg, *args, **kwargs) diff -Nru circuits-2.1.0/circuits/app/startup.py circuits-3.1.0+ds1/circuits/app/startup.py --- circuits-2.1.0/circuits/app/startup.py 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/app/startup.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,126 +0,0 @@ -# Module: startup -# Date: 21st March 2011 -# Author: James Mills, jamesmills at comops dot com dot au - -"""Startup Component - -This module implements a ``Startup`` Component that create a unified -way of creating, managing and running an application in conjunction with -an environment (``circuits.app.env``). The ``Startup`` Component provides -five verbs that can be passed as command-line arguments: -- start -- Start the application -- stop -- Stop the application -- init -- Create the application environment -- rehash -- Reload the application's environment -- upgrade -- Upgrade the application's environment -""" - -import os -import errno -from time import sleep -from signal import SIGINT, SIGTERM -try: - from signal import SIGHUP -except ImportError: - SIGHUP = None - -from circuits import handler, Event, BaseComponent - -from .daemon import Daemon -from .env import Environment -from .env import Create, Load, Upgrade - - -class Error(Exception): - """Error Exception""" - - -class Command(Event): - """Command Event""" - - -class Terminate(Event): - """Terminate Event""" - - -class Startup(BaseComponent): - - channel = "startup" - - def __init__(self, path, opts, command, env=Environment, - channel=channel): - super(Startup, self).__init__(channel=channel) - - self.path = path - self.opts = opts - self.command = command - - self.env = env(path).register(self) - - def _getpid(self): - with open(self.config.get("general", "pidfile"), "r") as f: - return int(f.read().strip()) - - def __tick__(self): - if not self.command == "start" and not self: - self.stop() - - @handler("signal", channel="*") - def _on_signal(self, signal, track): - if signal in (SIGINT, SIGTERM): - self.fire(Terminate()) - - @handler("environment_loaded", channel="env") - def _on_environment_loaded(self, *args): - self.fire(Command(), self.command, self) - - @handler("started") - def _on_started(self, component): - if not self.command == "init": - if not os.path.exists(self.env.path): - raise Error("Environment does not exist!") - else: - self.fire(Load(), self.env) - else: - if os.path.exists(self.env.path): - raise Error("Environment already exists!") - else: - self.fire(Command(), self.command, self) - - @handler("start") - def _on_start(self): - if self.opts.daemon: - pidfile = self.env.config.get("general", "pidfile", "app.pid") - Daemon(pidfile, self.env.path).register(self) - - @handler("stop") - def _on_stop(self): - pid = self._getpid() - - try: - os.kill(pid, SIGTERM) - os.waitpid(pid, os.WTERMSIG(0)) - except OSError as e: - if not e.args[0] == errno.ECHILD: - raise - - @handler("restart") - def _on_restart(self): - self.fire(Command(), "stop", self.channel) - sleep(1) - self.fire(Command(), "start", self.channel) - - if SIGHUP is not None: - @handler("rehash") - def _on_rehash(self): - pid = self._getpid() - - os.kill(pid, SIGHUP) - - @handler("init") - def _on_init(self): - self.fire(Create(), self.env) - - @handler("upgrade") - def _on_upgrade(self): - self.fire(Upgrade(), self.env) diff -Nru circuits-2.1.0/circuits/core/bridge.py circuits-3.1.0+ds1/circuits/core/bridge.py --- circuits-2.1.0/circuits/core/bridge.py 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/core/bridge.py 2014-10-22 08:37:49.000000000 +0000 @@ -4,20 +4,14 @@ """Bridge -Bridge Component to Bridge one or more components in a single System. -That is, events in System A bridged to System B are shared. For example: +The Bridge Component is used for inter-process communications between +processes. Bridge is used internally when a Component is started in +"process mode" via :meth:`circuits.core.manager.start`. Typically a +Pipe is used as the socket transport between two sides of a Bridge +(*there must be a :class:`~Bridge` instnace on both sides*). -A <--> Bridge <--> B - -Events that propagate in A, will propagate to B across the Bridge. -Events that propagate in B, will propagate to A across the Bridge. - -When the Bridge is created, it will automatically attempt to send a -Helo Event to any configured nodes or on a broadcast address if no -nodes are initially configured. The default Bridge implementation -uses the UDP protocol and as such events cannot be guaranteed of their -order or delivery. """ +import traceback try: from cPickle import dumps, loads @@ -25,9 +19,13 @@ from pickle import dumps, loads # NOQA from .values import Value -from .events import Event +from .events import Event, exception from .handlers import handler from .components import BaseComponent +from ..six import b + + +_sentinel = b('~~~') class Bridge(BaseComponent): @@ -38,7 +36,7 @@ "registered", "unregistered", "started", "stopped", "error", "value_changed", "generate_events", "read", "write", "close", "connected", "connect", "disconnect", "disconnected", "_read", - "_write" + "_write", "ready", "read_value_changed", "prepare_unregister" ] def init(self, socket, channel=channel): @@ -47,45 +45,69 @@ if self._socket is not None: self._socket.register(self) - self.addHandler( - handler("read", channel=self._socket.channel)( - self.__class__._on_read - ) - ) def _process_packet(self, eid, obj): if isinstance(obj, Event): obj.remote = True - obj.notify = "ValueChanged" + obj.notify = "value_changed" + obj.waitingHandlers = 0 value = self.fire(obj) self._values[value] = eid elif isinstance(obj, Value): - self._values[eid].value = obj.value + if obj.result: + if isinstance(obj.value, list): + for item in obj.value: + self._values[eid].value = item + else: + self._values[eid].value = obj.value + event = Event.create(Bridge.__waiting_event(eid)) + event.remote = True + self.fire(event, self.channel) + @handler("value_changed", channel="*") def _on_value_changed(self, value): try: eid = self._values[value] - self._socket.write(dumps((eid, value))) + self.__write(eid, value) except: pass - @staticmethod + @handler("read") def _on_read(self, data): - self._process_packet(*loads(data)) + data = data.split(_sentinel) + for item in data[:-1]: + self._process_packet(*loads(item)) - def send(self, event): + def send(self, eid, event): try: - eid = hash(event) + if isinstance(event, exception): + Bridge.__adapt_exception(event) self._values[eid] = event.value - self._socket.write(dumps((eid, event))) + self.__write(eid, event) except: pass + def __write(self, eid, data): + self._socket.write(dumps((eid, data))+_sentinel) + @handler(channel="*", priority=100.0) def _on_event(self, event, *args, **kwargs): - if event.name in self.ignore or getattr(event, "remote", False): + if event.name in self.ignore or getattr(event, "remote", False) \ + or event.name.endswith('_done') \ + or event.name.endswith('_success') \ + or event.name.endswith('_complete'): return - event.notify = "ValueChanged" - self.send(event) + eid = hash(event) + self.send(eid, event) + yield self.wait(Bridge.__waiting_event(eid)) + + @staticmethod + def __waiting_event(eid): + return '%s_done' % eid + + @staticmethod + def __adapt_exception(ex): + fevent_value = ex.kwargs['fevent'].value + fevent_value._value = (fevent_value[0], fevent_value[1], traceback.extract_tb(fevent_value[2])) diff -Nru circuits-2.1.0/circuits/core/components.py circuits-3.1.0+ds1/circuits/core/components.py --- circuits-2.1.0/circuits/core/components.py 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/core/components.py 2014-09-04 10:32:30.000000000 +0000 @@ -1,44 +1,22 @@ # Package: components # Date: 11th April 2010 # Author: James Mills, prologic at shortcircuit dot net dot au + """ This module defines the BaseComponent and its subclass Component. """ from itertools import chain from types import MethodType +from inspect import getmembers from collections import Callable -from inspect import getmembers, isclass from .manager import Manager -from .utils import flatten, findroot -from .events import Event, Registered, Unregistered from .handlers import handler, HandlerMetaClass +from .events import Event, registered, unregistered -def check_singleton(x, y): - """Return True if x contains a singleton that is already a member of y""" - - singletons = [i for i in flatten(x) if getattr(i, "singleton", False)] - - for component in singletons: - singleton = getattr(component, "singleton", False) - if isclass(singleton) and issubclass(singleton, Manager): - if any([isinstance(c, singleton) for c in flatten(findroot(y))]): - return True - elif singleton: - if any([type(component) in c for c in flatten(findroot(y))]): - return True - - return False - - -class SingletonError(Exception): - """Raised if a Component with the `singleton` class attribute is True. - """ - - -class PrepareUnregister(Event): +class prepare_unregister(Event): """ This event is fired when a component is about to be unregistered from the component tree. Unregistering a component actually @@ -56,7 +34,7 @@ complete = True def __init__(self, *args, **kwargs): - super(PrepareUnregister, self).__init__(*args, **kwargs) + super(prepare_unregister, self).__init__(*args, **kwargs) def in_subtree(self, component): """ @@ -104,7 +82,6 @@ """ channel = "*" - singleton = False def __new__(cls, *args, **kwargs): self = super(BaseComponent, cls).__new__(cls) @@ -139,16 +116,17 @@ for k, v in getmembers(self): if getattr(v, "handler", False) is True: self.addHandler(v) + # TODO: Document this feature. See Issue #88 if v is not self and isinstance(v, BaseComponent) \ and v not in ('parent', 'root'): v.register(self) if hasattr(self, "init") and isinstance(self.init, Callable): self.init(*args, **kwargs) - + @handler("prepare_unregister_complete", channel=self) - def _on_prepare_unregister_complete(self, e, value): - self._do_prepare_unregister_complete(e, value) + def _on_prepare_unregister_complete(self, event, e, value): + self._do_prepare_unregister_complete(event.parent, value) self.addHandler(_on_prepare_unregister_complete) def register(self, parent): @@ -162,8 +140,6 @@ This method fires a :class:`~.events.Registered` event to inform other components in the tree about the new member. """ - if check_singleton(self, parent): - raise SingletonError(self) self.parent = parent self.root = parent.root @@ -173,18 +149,12 @@ if parent is not self: parent.registerChild(self) self._updateRoot(parent.root) - self.fire(Registered(self, self.parent)) + self.fire(registered(self, self.parent)) else: self._updateRoot(parent.root) return self - @handler('unregister') - def _on_unregister(self, component): - if component is not self: - return - return self.unregister() - def unregister(self): """ Removes this component from the component tree. @@ -192,13 +162,13 @@ Removing a component from the component tree is a two stage process. First, the component is marked as to be removed, which prevents it from receiving further events, and a - :class:`~.components.PrepareUnregister` event is fired. This + :class:`~.components.prepare_unregister` event is fired. This allows other components to e.g. release references to the component to be removed before it is actually removed from the component tree. - After the processing of the ``PrepareUnregister`` event has completed, + After the processing of the ``prepare_unregister`` event has completed, the component is removed from the tree and an - :class:`~.events.Unregistered` event is fired. + :class:`~.events.unregistered` event is fired. """ if self.unregister_pending or self.parent == self: @@ -209,7 +179,7 @@ self.root._cache_needs_refresh = True # Give components a chance to prepare for unregister - evt = PrepareUnregister(self) + evt = prepare_unregister(self) evt.complete_channels = (self,) self.fire(evt) @@ -222,7 +192,7 @@ def _do_prepare_unregister_complete(self, e, value): # Remove component from tree now delattr(self, "_unregister_pending") - self.fire(Unregistered(self, self.parent)) + self.fire(unregistered(self, self.parent)) if self.parent is not self: self.parent.unregisterChild(self) @@ -240,21 +210,30 @@ def handlers(cls): """Returns a list of all event handlers for this Component""" + return list(set( + getattr(cls, k) for k in dir(cls) + if getattr(getattr(cls, k), "handler", False) + )) + + @classmethod + def events(cls): + """Returns a list of all events this Component listens to""" + handlers = ( getattr(cls, k).names for k in dir(cls) if getattr(getattr(cls, k), "handler", False) ) - return list( + return list(set( name for name in chain(*handlers) if not name.startswith("_") - ) + )) @classmethod def handles(cls, *names): """Returns True if all names are event handlers of this Component""" - return all(name in cls.handlers() for name in names) + return all(name in cls.events() for name in names) Component = HandlerMetaClass("Component", (BaseComponent,), {}) diff -Nru circuits-2.1.0/circuits/core/debugger.py circuits-3.1.0+ds1/circuits/core/debugger.py --- circuits-2.1.0/circuits/core/debugger.py 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/core/debugger.py 2014-09-04 10:32:30.000000000 +0000 @@ -2,13 +2,18 @@ # Date: 2nd April 2006 # Author: James Mills, prologic at shortcircuit dot net dot au + """ Debugger component used to debug each event in a system by printing each event to sys.stderr or to a Logger Component instance. """ + import os import sys +from traceback import format_exc +from signal import SIGINT, SIGTERM + from .components import BaseComponent from .handlers import handler, reprhandler @@ -17,7 +22,7 @@ class Debugger(BaseComponent): """Create a new Debugger Component - Creates a new Debugger Component that filters all events in the system + Creates a new Debugger Component that listens to all events in the system printing each event to sys.stderr or a Logger Component. :var IgnoreEvents: list of events (str) to ignore @@ -36,12 +41,12 @@ super(Debugger, self).__init__() - self.errors = errors - self.events = events + self._errors = errors + self._events = events - if type(file) is str: + if isinstance(file, str): self.file = open(os.path.abspath(os.path.expanduser(file)), "a") - elif type(file) is file or hasattr(file, "write"): + elif hasattr(file, "write"): self.file = file else: self.file = sys.stderr @@ -53,9 +58,16 @@ self.IgnoreEvents.extend(kwargs.get("IgnoreEvents", [])) self.IgnoreChannels.extend(kwargs.get("IgnoreChannels", [])) - @handler("error", channel="*", priority=100.0) - def _on_error(self, error_type, value, traceback, handler=None): - if not self.errors: + @handler("signal", channel="*") + def _on_signal(self, signo, stack): + if signo in [SIGINT, SIGTERM]: + raise SystemExit(0) + + @handler("exception", channel="*", priority=100.0) + def _on_exception(self, error_type, value, traceback, + handler=None, fevent=None): + + if not self._errors: return s = [] @@ -65,7 +77,10 @@ else: handler = reprhandler(handler) - msg = "ERROR %s (%s): %s\n" % (handler, error_type, value) + msg = "ERROR {0:s} ({1:s}) ({2:s}): {3:s}\n".format( + handler, repr(fevent), repr(error_type), repr(value) + ) + s.append(msg) s.extend(traceback) s.append("\n") @@ -79,40 +94,41 @@ except IOError: pass - @handler(channel="*", priority=101.0) + @handler(priority=101.0) def _on_event(self, event, *args, **kwargs): """Global Event Handler - Event handler to listen and filter all events printing + Event handler to listen to all events printing each event to self.file or a Logger Component instance by calling self.logger.debug """ - if not self.events: - return + try: + if not self._events: + return - channels = event.channels + channels = event.channels - if event.name in self.IgnoreEvents: - return + if event.name in self.IgnoreEvents: + return - if all(channel in self.IgnoreChannels for channel in channels): - return + if all(channel in self.IgnoreChannels for channel in channels): + return - s = repr(event) + s = repr(event) - if self.prefix: - s = "%s: %s" % (self.prefix, s) + if self.prefix: + s = "%s: %s" % (self.prefix, s) - if self.trim: - s = "%s ...>" % s[:self.trim] + if self.trim: + s = "%s ...>" % s[:self.trim] - if self.logger is not None: - self.logger.debug(s) - else: - try: + if self.logger is not None: + self.logger.debug(s) + else: self.file.write(s) self.file.write("\n") self.file.flush() - except IOError: - pass + except Exception as e: + sys.stderr.write("ERROR (Debugger): {}".format(e)) + sys.stderr.write("{}".format(format_exc())) diff -Nru circuits-2.1.0/circuits/core/events.py circuits-3.1.0+ds1/circuits/core/events.py --- circuits-2.1.0/circuits/core/events.py 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/core/events.py 2014-09-24 09:45:33.000000000 +0000 @@ -2,27 +2,40 @@ # Date: 11th April 2010 # Author: James Mills, prologic at shortcircuit dot net dot au + """ -This module defines the basic Event class and common events. +This module defines the basic event class and common events. """ -from .utils import uncamel + from inspect import ismethod -class EventMetaClass(type): +class EventType(type): + + __cache__ = {} + + def __new__(cls, name, bases, ns): + key = (cls, name, bases) - def __init__(cls, name, bases, ns): - super(EventMetaClass, cls).__init__(name, bases, ns) + try: + return cls.__cache__[key] + except KeyError: + cls = type.__new__(cls, name, bases, ns) - setattr(cls, "name", ns.get("name", uncamel(cls.__name__))) + setattr(cls, "name", ns.get("name", cls.__name__)) + return cls -class BaseEvent(object): + +class Event(object): + + __metaclass__ = EventType channels = () "The channels this message is sent to." + parent = None notify = False success = False failure = False @@ -34,10 +47,17 @@ def create(cls, name, *args, **kwargs): return type(cls)(name, (cls,), {})(*args, **kwargs) + def child(self, name, *args, **kwargs): + e = Event.create( + "{0:s}_{1:s}".format(self.name, name), *args, **kwargs + ) + e.parent = self + return e + def __init__(self, *args, **kwargs): - """An Event is a message send to one or more channels. It is eventually - dispatched to all components that have handlers for one - of the channels and the event type. + """An event is a message send to one or more channels. + It is eventually dispatched to all components + that have handlers for one of the channels and the event type. All normal arguments and keyword arguments passed to the constructor of an event are passed on to the handler. When declaring a @@ -45,8 +65,7 @@ used for creating the event. Every event has a :attr:`name` attribute that is used for matching - the event with the handlers. By default, the name is the uncameled - class name of the event. + the event with the handlers. :cvar channels: an optional attribute that may be set before firing the event. If defined (usually as a class variable), the attribute @@ -64,8 +83,8 @@ for the event. :var success: if this optional attribute is set to - ``True``, an associated event ``EventSuccess`` (original name - with "Success" appended) will automatically be fired when all + ``True``, an associated event ``success`` (original name + with "_success" appended) will automatically be fired when all handlers for the event have been invoked successfully. :var success_channels: the success event is, by default, delivered @@ -74,12 +93,12 @@ destinations using this attribute. :var complete: if this optional attribute is set to - ``True``, an associated event ``EventComplete`` (original name - with "Complete" appended) will automatically be fired when all + ``True``, an associated event ``complete`` (original name + with "_complete" appended) will automatically be fired when all handlers for the event and all events fired by these handlers (recursively) have been invoked successfully. - :var success_channels: the complete event is, by default, delivered + :var complete_channels: the complete event is, by default, delivered to same channels as the initially dispatched event itself. This may be overridden by specifying an alternative list of destinations using this attribute. @@ -91,6 +110,10 @@ self.uid = None self.value = None self.handler = None + self.stopped = False + self.cancelled = False + if not hasattr(self, 'name'): + self.name = self.__class__.__name__ def __getstate__(self): odict = self.__dict__.copy() @@ -100,11 +123,15 @@ def __setstate__(self, dict): self.__dict__.update(dict) + def __le__(self, other): + return False + + def __gt__(self, other): + return False + def __repr__(self): "x.__repr__() <==> repr(x)" - name = self.name - type = self.__class__.__name__ if len(self.channels) > 1: channels = repr(self.channels) elif len(self.channels) == 1: @@ -117,21 +144,21 @@ ", ".join("%s=%s" % (k, repr(v)) for k, v in self.kwargs.items()) ) - return "<%s[%s.%s] (%s)>" % (type, channels, name, data) + return "<%s[%s] (%s)>" % (self.name, channels, data) def __getitem__(self, x): """x.__getitem__(y) <==> x[y] - Get and return data from the Event object requested by "x". + Get and return data from the event object requested by "x". If an int is passed to x, the requested argument from self.args is returned index by x. If a str is passed to x, the requested keyword argument from self.kwargs is returned keyed by x. Otherwise a TypeError is raised as nothing else is valid. """ - if type(x) is int: + if isinstance(x, int): return self.args[x] - elif type(x) is str: + elif isinstance(x, str): return self.kwargs[x] else: raise TypeError("Expected int or str, got %r" % type(x)) @@ -139,56 +166,36 @@ def __setitem__(self, i, y): """x.__setitem__(i, y) <==> x[i] = y - Modify the data in the Event object requested by "x". + Modify the data in the event object requested by "x". If i is an int, the ith requested argument from self.args shall be changed to y. If i is a str, the requested value keyed by i from self.kwargs, shall by changed to y. Otherwise a TypeError is raised as nothing else is valid. """ - if type(i) is int: + if isinstance(i, int): self.args[i] = y - elif type(i) is str: + elif isinstance(i, str): self.kwargs[i] = y else: raise TypeError("Expected int or str, got %r" % type(i)) -Event = EventMetaClass("Event", (BaseEvent,), {}) - - -class LiteralEvent(Event): - """ - An event whose name is not uncameled when looking for a handler. - """ - @staticmethod - def create(cls, name, *args, **kwargs): - """ - Utility method to create an event that inherits from - a base event class (passed in as *cls*) and from - LiteralEvent. - """ - return type(cls)(name, (cls, LiteralEvent), - {"name": name})(*args, **kwargs) + def cancel(self): + """Cancel the event from being processed (if not already)""" + self.cancelled = True -class DerivedEvent(Event): + def stop(self): + """Stop further processing of this event""" - @classmethod - def create(cls, topic, event, *args, **kwargs): - if isinstance(event, LiteralEvent): - name = "%s%s" % (event.__class__.__name__, uncamel("_%s" % topic)) - return type(cls)(name, (cls,), - {"name": name})(event, *args, **kwargs) - else: - name = "%s_%s" % (event.__class__.__name__, topic) - return type(cls)(name, (cls,), {})(event, *args, **kwargs) + self.stopped = True -class Error(Event): - """Error Event +class exception(Event): + """exception Event - This Event is sent for any exceptions that occur during the execution - of an Event Handler that is not SystemExit or KeyboardInterrupt. + This event is sent for any exceptions that occur during the execution + of an event Handler that is not SystemExit or KeyboardInterrupt. :param type: type of exception :type type: type @@ -199,113 +206,66 @@ :param traceback: traceback of exception :type traceback: traceback - :param kwargs: (Optional) Additional Information - :type kwargs: dict - """ - - def __init__(self, type, value, traceback, handler=None): - super(Error, self).__init__(type, value, traceback, handler) + :param handler: handler that raised the exception + :type handler: @handler() - -class Done(DerivedEvent): - """Done Event - - This Event is sent when an event is done. It is used by the wait and call - primitives to know when to stop waiting. Don't use this for application - development, use :class:`Success` instead. + :param fevent: event that failed + :type fevent: event """ - def __init__(self, *args, **kwargs): - super(Done, self).__init__(*args, **kwargs) - -class Success(DerivedEvent): - """Success Event + def __init__(self, type, value, traceback, handler=None, fevent=None): + super(exception, self).__init__(type, value, traceback, + handler=handler, fevent=fevent) - This Event is sent when all handlers (for a particular event) have been - executed successfully, see :class:`~.manager.Manager`. - - :param event: The event that has completed. - :type event: Event - """ - def __init__(self, *args, **kwargs): - super(Success, self).__init__(*args, **kwargs) +class started(Event): + """started Event -class Complete(DerivedEvent): - """Complete Event + This Event is sent when a Component or Manager has started running. - This Event is sent when all handlers (for a particular event) have been - executed and (recursively) all handlers for all events fired by those - handlers etc., see :class:`~.manager.Manager`. - - :param event: The event that has completed. - :type event: Event - """ - def __init__(self, *args, **kwargs): - super(Complete, self).__init__(*args, **kwargs) - - -class Failure(DerivedEvent): - """Failure Event - - This Event is sent when an error has occurred with the execution of an - Event Handlers. - - :param event: The event that failed - :type event: Event - """ - def __init__(self, *args, **kwargs): - super(DerivedEvent, self).__init__(*args, **kwargs) - - -class Started(Event): - """Started Event - - This Event is sent when a Component has started running. - - :param component: The component that was started - :type component: Component or Manager + :param manager: The component or manager that was started + :type manager: Component or Manager """ - def __init__(self, component): - super(Started, self).__init__(component) + def __init__(self, manager): + super(started, self).__init__(manager) -class Stopped(Event): - """Stopped Event +class stopped(Event): + """stopped Event - This Event is sent when a Component has stopped running. + This Event is sent when a Component or Manager has stopped running. - :param component: The component that has stopped - :type component: Component or Manager + :param manager: The component or manager that has stopped + :type manager: Component or Manager """ - def __init__(self, component): - super(Stopped, self).__init__(component) + def __init__(self, manager): + super(stopped, self).__init__(manager) -class Signal(Event): - """Signal Event +class signal(Event): + """signal Event This Event is sent when a Component receives a signal. - :param signal: The signal number received. - :type int: An int value for the signal + :param signo: The signal number received. + :type int: An int value for the signal :param stack: The interrupted stack frame. :type object: A stack frame """ - def __init__(self, signal, stack): - super(Signal, self).__init__(signal, stack) + def __init__(self, signo, stack): + super(signal, self).__init__(signo, stack) -class Registered(Event): - """Registered Event +class registered(Event): + """registered Event This Event is sent when a Component has registered with another Component - or Manager. This Event is only sent iif the Component or Manager being - registered with is not itself. + or Manager. This Event is only sent if the Component or Manager being + registered which is not itself. :param component: The Component being registered :type component: Component @@ -315,40 +275,28 @@ """ def __init__(self, component, manager): - super(Registered, self).__init__(component, manager) - - -class Unregister(Event): - """Unregister Event - - This Event ask for a Component to unregister from its - Component or Manager. - """ - - def __init__(self, component=None): - super(Unregister, self).__init__(component) + super(registered, self).__init__(component, manager) -class Unregistered(Event): - """Unregistered Event +class unregistered(Event): + """unregistered Event This Event is sent when a Component has been unregistered from its Component or Manager. """ - def __init__(self, component, manager): - super(Unregistered, self).__init__(component, manager) - -class GenerateEvents(Event): - """Generate events event +class generate_events(Event): + """generate_events Event - This event is sent by the circuits core. All components that generate + This Event is sent by the circuits core. All components that generate timed events or events from external sources (e.g. data becoming available) should fire any pending events in their "generate_events" - handler. The handler must either be a filter (preventing other - handler from being called in the same iteration) or must invoke - :meth:`~.reduce_time_left` with parameter 0. + handler. + + The handler must either call :meth:`~stop` (*preventing other handlers + from being called in the same iteration) + or must invoke :meth:`~.reduce_time_left` with parameter 0. :param max_wait: maximum time available for generating events. :type time_left: float @@ -359,7 +307,8 @@ """ def __init__(self, lock, max_wait): - super(GenerateEvents, self).__init__() + super(generate_events, self).__init__() + self._time_left = max_wait self._lock = lock @@ -371,6 +320,7 @@ one component in your system (usually a poller component) that spends up to "time left" until it generates an event. """ + return self._time_left def reduce_time_left(self, time_left): @@ -388,6 +338,7 @@ If the time left is reduced to 0 and the event is currently being handled, the handler's *resume* method is invoked. """ + with self._lock: if time_left >= 0 and (self._time_left < 0 or self._time_left > time_left): diff -Nru circuits-2.1.0/circuits/core/handlers.py circuits-3.1.0+ds1/circuits/core/handlers.py --- circuits-2.1.0/circuits/core/handlers.py 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/core/handlers.py 2014-09-04 10:32:30.000000000 +0000 @@ -33,13 +33,6 @@ for a specific event are invoked. The higher the priority, the earlier the handler is executed. - A handler may also be specified as a filter by adding - the keyword argument ``filter=True`` to the decorator. - If such a handler returns a value different from ``None``, no more - handlers are invoked for the handled event. Filtering handlers are - invoked before normal handlers with the same priority (but after any - handlers with higher priority). - If you want to override a handler defined in a base class of your component, you must specify ``override=True``, else your method becomes an additional handler for the event. @@ -74,7 +67,7 @@ """ def wrapper(f): - if names and type(names[0]) is bool and not names[0]: + if names and isinstance(names[0], bool) and not names[0]: f.handler = False return f @@ -82,7 +75,6 @@ f.names = names f.priority = kwargs.get("priority", 0) - f.filter = kwargs.get("filter", False) f.channel = kwargs.get("channel", None) f.override = kwargs.get("override", False) @@ -102,14 +94,17 @@ def reprhandler(handler): - format = "<%s[%s.%s] (%s.%s)>" + format = "" + + channel = getattr(handler, "channel", "*") + if channel is None: + channel = "*" - channel = handler.channel if handler.channel is not None else "*" from circuits.core.manager import Manager if isinstance(channel, Manager): channel = "" + names = ".".join(handler.names) - type = "filter" if handler.filter else "listener" instance = getattr( handler, "im_self", getattr( @@ -119,7 +114,7 @@ method = handler.__name__ - return format % (type, channel, names, instance, method) + return format % (channel, names, instance, method) class HandlerMetaClass(type): diff -Nru circuits-2.1.0/circuits/core/helpers.py circuits-3.1.0+ds1/circuits/core/helpers.py --- circuits-2.1.0/circuits/core/helpers.py 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/core/helpers.py 2014-10-05 02:23:20.000000000 +0000 @@ -2,11 +2,14 @@ .. codeauthor: mnl """ + +from sys import stderr from threading import Event +from signal import SIGINT, SIGTERM + from .handlers import handler from .components import BaseComponent -import sys from circuits.core.handlers import reprhandler @@ -16,7 +19,7 @@ super(FallBackGenerator, self).__init__(*args, **kwargs) self._continue = Event() - @handler("generate_events", priority=-100, filter=True) + @handler("generate_events", priority=-100) def _on_generate_events(self, event): """ Fall back handler for the :class:`~.events.GenerateEvents` event. @@ -24,13 +27,14 @@ When the queue is empty a GenerateEvents event is fired, here we sleep for as long as possible to avoid using extra cpu cycles. - A poller would overwrite with with a higher priority filter, e.g. - @handler("generate_events", priority=0, filter=True) + A poller would override this with a higher priority handler. + e.g: ``@handler("generate_events", priority=0)`` and provide a different way to idle when the queue is empty. """ + with event.lock: if event.time_left == 0: - return True + event.stop() self._continue.clear() if event.time_left > 0: @@ -43,7 +47,7 @@ # reduce_time_left(0) has been called. So calling this # here is OK in any case. event.reduce_time_left(0) - return True + event.stop() while event.time_left < 0: # If we get here, there was no work left to do when creating @@ -55,7 +59,7 @@ # Python ignores signals when waiting without timeout. self._continue.wait(10000) - return True + event.stop() def resume(self): """ @@ -65,15 +69,16 @@ self._continue.set() -class FallBackErrorHandler(BaseComponent): +class FallBackExceptionHandler(BaseComponent): """ - If ther is no handler for error events in the component hierarchy, this + If there is no handler for error events in the component hierarchy, this component's handler is added automatically. It simply prints the error information on stderr. """ - @handler("error", channel="*") - def _on_error(self, error_type, value, traceback, handler=None): + @handler("exception", channel="*") + def _on_exception(self, error_type, value, traceback, + handler=None, fevent=None): s = [] if handler is None: @@ -81,8 +86,24 @@ else: handler = reprhandler(handler) - msg = "ERROR %s (%s): %s\n" % (handler, error_type, value) + msg = "ERROR {0:s} ({1:s}) ({2:s}): {3:s}\n".format( + handler, repr(fevent), repr(error_type), repr(value) + ) + s.append(msg) s.extend(traceback) s.append("\n") - sys.stderr.write("".join(s)) + stderr.write("".join(s)) + + +class FallBackSignalHandler(BaseComponent): + """ + If there is no handler for signal events in the component hierarchy, this + component's handler is added automatically. It simply terminates the + system if the signal is SIGINT or SIGTERM. + """ + + @handler("signal", channel="*") + def _on_signal(self, signo, stack): + if signo in [SIGINT, SIGTERM]: + raise SystemExit(0) diff -Nru circuits-2.1.0/circuits/core/__init__.py circuits-3.1.0+ds1/circuits/core/__init__.py --- circuits-2.1.0/circuits/core/__init__.py 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/core/__init__.py 2014-09-04 10:32:30.000000000 +0000 @@ -8,24 +8,24 @@ """ +from .events import Event from .bridge import Bridge from .loader import Loader -from .manager import Manager +from .manager import Manager, TimeoutError from .handlers import handler, reprhandler from .components import BaseComponent, Component -from .events import BaseEvent, DerivedEvent, Event, LiteralEvent from .values import Value from .timers import Timer -from .workers import Task, Worker +from .workers import task, Worker from .debugger import Debugger __all__ = ( - "handler", "BaseComponent", "Component", "Event", "Map", "Pool", "Task", - "Worker", "Bridge", "Debugger", "Timer", "Manager", + "handler", "BaseComponent", "Component", "Event", "task", + "Worker", "Bridge", "Debugger", "Timer", "Manager", "TimeoutError", ) # flake8: noqa diff -Nru circuits-2.1.0/circuits/core/manager.py circuits-3.1.0+ds1/circuits/core/manager.py --- circuits-2.1.0/circuits/core/manager.py 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/core/manager.py 2014-10-05 06:28:12.000000000 +0000 @@ -2,43 +2,54 @@ # Date: 11th April 2010 # Author: James Mills, prologic at shortcircuit dot net dot au + """ This module defines the Manager class. """ + import atexit -from os import getpid -from itertools import chain -from collections import deque +from os import getpid, kill from inspect import isfunction from uuid import uuid4 as uuid +from operator import attrgetter from types import GeneratorType -from sys import exc_info as _exc_info +from itertools import chain, count +from signal import SIGINT, SIGTERM +from heapq import heappush, heappop from weakref import WeakValueDictionary -from signal import signal, SIGINT, SIGTERM from traceback import format_exc, format_tb +from sys import exc_info as _exc_info, stderr +from signal import signal as set_signal_handler from threading import current_thread, Thread, RLock from multiprocessing import current_process, Process + +try: + from signal import SIGKILL +except ImportError: + SIGKILL = SIGTERM + + from .values import Value from ..tools import tryimport from .handlers import handler from ..six import create_bound_method, next -from .events import Done, Success, Failure, Complete -from .events import Error, Started, Stopped, Signal, GenerateEvents +from .events import exception, generate_events, signal, started, stopped, Event + thread = tryimport(("thread", "_thread")) + TIMEOUT = 0.1 # 100ms timeout when idle class UnregistrableError(Exception): - """Raised if a component cannot be registered as child. - """ + """Raised if a component cannot be registered as child.""" -def _sortkey(handler): - return (handler.priority, handler.filter) +class TimeoutError(Exception): + """Raised if wait event timeout occurred""" class CallValue(object): @@ -46,6 +57,14 @@ self.value = value +class ExceptionWrapper(object): + def __init__(self, exception): + self.exception = exception + + def extract(self): + return self.exception + + class Dummy(object): channel = None @@ -99,7 +118,7 @@ event. This event is generated by the manager if :class:`~.events.Event` has its :attr:`complete` attribute set to True. - Apart from the event queue, the root manager also maintains a list of + Apart from the event queue, the root manager also maintains a list of tasks, actually Python generators, that are updated when the event queue has been flushed. """ @@ -112,13 +131,17 @@ def __init__(self, *args, **kwargs): "initializes x; see x.__class__.__doc__ for signature" + self._queue = [] + self._counter = count() + self._tasks = set() self._cache = dict() - self._cache_needs_refresh = False - self._queue = deque() - self._flush_batch = 0 self._globals = set() self._handlers = dict() + + self._flush_batch = 0 + self._cache_needs_refresh = False + self._values = WeakValueDictionary() self._executing_thread = None @@ -136,7 +159,7 @@ name = self.__class__.__name__ - channel = "/{0:s}".format(getattr(self, "channel", "")) + channel = "/{0:s}".format(str(getattr(self, "channel", ""))) q = len(self._queue) state = "R" if self.running else "S" @@ -244,13 +267,16 @@ name = event.name handlers = set() - handlers_chain = [self._handlers.get("*", [])] - - handlers_chain.append(self._handlers.get(name, [])) + _handlers = set() + _handlers.update(self._handlers.get("*", [])) + _handlers.update(self._handlers.get(name, [])) - for _handler in chain(*handlers_chain): - handler_channel = _handler.channel + for _handler in _handlers: + handler_channel = _handler.channel if handler_channel is None: + # XXX: Why do we care about the event handler's channel? + # This probably costs us performance for what? + # I've not ever had to rely on this in practice... handler_channel = getattr( getattr( _handler, "im_self", getattr( @@ -258,7 +284,7 @@ ) ), "channel", None - ) + ) if channel == "*" or handler_channel in ("*", channel,) \ or channel is self: @@ -315,27 +341,33 @@ component._executing_thread = None self.components.add(component) self.root._queue.extend(list(component._queue)) - component._queue.clear() + component._queue = [] self.root._cache_needs_refresh = True def unregisterChild(self, component): self.components.remove(component) self.root._cache_needs_refresh = True - def _fire(self, event, channel): + def _fire(self, event, channel, priority=0): # check if event is fired while handling an event - if thread.get_ident() \ - == (self._executing_thread or self._flushing_thread) \ - and not isinstance(event, Signal): - if self._currently_handling is not None \ - and getattr(self._currently_handling, "cause", None): + if thread.get_ident() == (self._executing_thread or \ + self._flushing_thread) and not isinstance(event, signal): + if self._currently_handling is not None and \ + getattr(self._currently_handling, "cause", None): # if the currently handled event wants to track the # events generated by it, do the tracking now event.cause = self._currently_handling event.effects = 1 self._currently_handling.effects += 1 - self._queue.append((event, channel)) + heappush( + self._queue, + ( + priority, + next(self._counter), + (event, channel) + ) + ) # the event comes from another thread else: @@ -352,13 +384,28 @@ # it to a local variable here before performing a sequence of # operations that assume its value to remain unchanged. handling = self._currently_handling - if isinstance(handling, GenerateEvents): - self._queue.append((event, channel)) + + if isinstance(handling, generate_events): + heappush( + self._queue, + ( + priority, + next(self._counter), + (event, channel) + ) + ) handling.reduce_time_left(0) else: - self._queue.append((event, channel)) + heappush( + self._queue, + ( + priority, + next(self._counter), + (event, channel) + ) + ) - def fireEvent(self, event, *channels): + def fireEvent(self, event, *channels, **kwargs): """Fire an event into the system. :param event: The event that is to be fired. @@ -379,55 +426,92 @@ event.channels = channels event.value = Value(event, self) - self.root._fire(event, channels) + self.root._fire(event, channels, **kwargs) return event.value fire = fireEvent def registerTask(self, g): - self._tasks.add(g) + self.root._tasks.add(g) def unregisterTask(self, g): - if g in self._tasks: - self._tasks.remove(g) + if g in self.root._tasks: + self.root._tasks.remove(g) + + def waitEvent(self, event, *channels, **kwargs): + if isinstance(event, Event): + event_object = event + event_name = event.name + else: + event_object = None + event_name = event - def waitEvent(self, event, *channels): state = { 'run': False, 'flag': False, 'event': None, + 'timeout': kwargs.get("timeout", -1) } - _event = event def _on_event(self, event, *args, **kwargs): - if not state['run']: - self.removeHandler(_on_event_handler, _event) + if not state['run'] and ( + event_object is None or event is event_object + ): + self.removeHandler(_on_event_handler, event_name) event.alert_done = True state['run'] = True state['event'] = event - def _on_done(self, event, source, *args, **kwargs): - if state['event'] == source: + def _on_done(self, event, *args, **kwargs): + if state['event'] == event.parent: state['flag'] = True + self.registerTask((state['task_event'], + state['task'], + state['parent'])) + if state['timeout'] > 0: + self.removeHandler( + state['tick_handler'], + "generate_events" + ) + + def _on_tick(self): + if state['timeout'] == 0: + self.registerTask( + ( + state['task_event'], + (e for e in (ExceptionWrapper(TimeoutError()),)), + state['parent'] + ) + ) + self.removeHandler(_on_done_handler, "%s_done" % event_name) + self.removeHandler(_on_tick_handler, "generate_events") + elif state['timeout'] > 0: + state['timeout'] -= 1 if not channels: - channels = (None, ) + channels = (None,) for channel in channels: _on_event_handler = self.addHandler( - handler(event, channel=channel)(_on_event)) + handler(event_name, channel=channel)(_on_event)) _on_done_handler = self.addHandler( - handler("%s_done" % event, channel=channel)(_on_done)) + handler("%s_done" % event_name, channel=channel)(_on_done)) + if state['timeout'] >= 0: + _on_tick_handler = state['tick_handler'] = self.addHandler( + handler("generate_events", channel=channel)(_on_tick)) + + yield state - while not state['flag']: - yield None + if not state['timeout']: + self.removeHandler(_on_done_handler, "%s_done" % event_name) - self.removeHandler(_on_done_handler, "%s_done" % event) + if state["event"] is not None: + yield CallValue(state["event"].value) wait = waitEvent - def callEvent(self, event, *channels): + def callEvent(self, event, *channels, **kwargs): """ Fire the given event to the specified channels and suspend execution until it has been dispatched. This method may only @@ -438,7 +522,7 @@ been dispatched (see :func:`circuits.core.handlers.handler`). """ value = self.fire(event, *channels) - for r in self.waitEvent(event.name, event.channels): + for r in self.waitEvent(event, *event.channels, **kwargs): yield r yield CallValue(value) @@ -454,7 +538,7 @@ self._flush_batch = len(self._queue) while self._flush_batch > 0: self._flush_batch -= 1 # Decrement first! - event, channels = self._queue.popleft() + priority, count, (event, channels) = heappop(self._queue) self._dispatcher(event, channels, self._flush_batch) finally: self._flushing_thread = old_flushing @@ -471,6 +555,9 @@ flush = flushEvents def _dispatcher(self, event, channels, remaining): + if event.cancelled: + return + if event.complete: if not getattr(event, "cause", None): event.cause = event @@ -487,21 +574,31 @@ handlers = self._cache[(event.name, channels)] except KeyError: h = (self.getHandlers(event, channel) for channel in channels) - handlers = sorted(chain(*h), key=_sortkey, reverse=True) - if isinstance(event, GenerateEvents): + + handlers = sorted( + chain(*h), + key=attrgetter("priority"), + reverse=True + ) + + if isinstance(event, generate_events): from .helpers import FallBackGenerator handlers.append(FallBackGenerator()._on_generate_events) - elif isinstance(event, Error) and len(handlers) == 0: - from .helpers import FallBackErrorHandler - handlers.append(FallBackErrorHandler()._on_error) + elif isinstance(event, exception) and len(handlers) == 0: + from .helpers import FallBackExceptionHandler + handlers.append(FallBackExceptionHandler()._on_exception) + elif isinstance(event, signal) and len(handlers) == 0: + from .helpers import FallBackSignalHandler + handlers.append(FallBackSignalHandler()._on_signal) + self._cache[(event.name, channels)] = handlers - if isinstance(event, GenerateEvents): + if isinstance(event, generate_events): with self._lock: self._currently_handling = event if remaining > 0 or len(self._queue) or not self._running: event.reduce_time_left(0) - elif len(self._tasks): + elif self._tasks: event.reduce_time_left(TIMEOUT) # From now on, firing an event will reduce time left # to 0, which prevents handlers from waiting (or wakes @@ -510,7 +607,7 @@ self._currently_handling = event value = None - error = None + err = None for handler in handlers: event.handler = handler @@ -524,35 +621,45 @@ except: etype, evalue, etraceback = _exc_info() traceback = format_tb(etraceback) - error = (etype, evalue, traceback) + err = (etype, evalue, traceback) event.value.errors = True - value = error + value = err if event.failure: self.fire( - Failure.create("Failure", event, error), + event.child("failure", event, err), *event.channels ) - self.fire(Error(etype, evalue, traceback, handler)) + self.fire( + exception( + etype, evalue, traceback, + handler=handler, fevent=event + ) + ) if value is not None: if isinstance(value, GeneratorType): event.waitingHandlers += 1 event.value.promise = True - self.registerTask((event, value)) + self.registerTask((event, value, None)) else: event.value.value = value - # None is false, but not None may still be True or False - if handler.filter and value: - break + + # it is kind of a temporal hack to allow processing + # of tasks, added in one of handlers here + if isinstance(event, generate_events) and self._tasks: + event.reduce_time_left(TIMEOUT) + + if event.stopped: + break # Stop further event processing self._currently_handling = None - self._eventDone(event, error) + self._eventDone(event, err) - def _eventDone(self, event, error=None): + def _eventDone(self, event, err=None): if event.waitingHandlers: return @@ -561,16 +668,12 @@ # interested in being notified about the last handler for # an event having been invoked. if event.alert_done: - self.fire( - Done.create("Done", event, event.value.value), - *event.channels - ) + self.fire(event.child("done", event.value.value), *event.channels) - if error is None and event.success: + if err is None and event.success: channels = getattr(event, "success_channels", event.channels) self.fire( - Success.create("Success", event, event.value.value), - *channels + event.child("success", event, event.value.value), *channels ) while True: @@ -584,19 +687,18 @@ break # some nested events remain to be completed if event.complete: # does this event want signaling? self.fire( - Complete.create("Complete", event, event.value.value), + event.child("complete", event, event.value.value), *getattr(event, "complete_channels", event.channels) ) + # this event and nested events are done now delattr(event, "cause") delattr(event, "effects") # cause has one of its nested events done, decrement and check event = cause - def _signalHandler(self, signal, stack): - self.fire(Signal(signal, stack)) - if signal in [SIGINT, SIGTERM]: - self.stop() + def _signal_handler(self, signo, stack): + self.fire(signal(signo, stack)) def start(self, process=False, link=None): """ @@ -613,22 +715,27 @@ channels = (uuid(),) * 2 parent, child = Pipe(*channels) - Bridge(parent, channel=channels[0]).register(link) + bridge = Bridge(parent, channel=channels[0]).register(link) args = (child,) else: args = () + bridge = None self.__process = Process( target=self.run, args=args, name=self.name ) self.__process.daemon = True self.__process.start() + + return self.__process, bridge else: self.__thread = Thread(target=self.run, name=self.name) self.__thread.daemon = True self.__thread.start() + return self.__thread, None + def join(self): if getattr(self, "_thread", None) is not None: return self.__thread.join() @@ -641,12 +748,21 @@ Stop this manager. Invoking this method causes an invocation of ``run()`` to return. """ + + if self.__process is not None and self.__process.is_alive(): + self.__process.terminate() + self.__process.join(TIMEOUT) + + if self.__process.is_alive(): + kill(self.__process.pid, SIGKILL) + if not self.running: return self._running = False - self.fire(Stopped(self)) + self.fire(stopped(self)) + if self.root._executing_thread is None: for _ in range(3): self.tick() @@ -661,55 +777,74 @@ # We are in a callEvent value = parent.send(value.value) if isinstance(value, GeneratorType): - # We loose a yield but we gain one, we don't need to change + # We loose a yield but we gain one, + # we don't need to change # event.waitingHandlers - self.registerTask((event, value, parent)) - self.processTask(event, value, parent) + # The below code is delegated to handlers + # in the waitEvent generator + # self.registerTask((event, value, parent)) + task_state = next(value) + task_state['task_event'] = event + task_state['task'] = value + task_state['parent'] = parent else: event.waitingHandlers -= 1 if value is not None: event.value.value = value - self.registerTask((event, parent)) + self.registerTask((event, parent, None)) elif isinstance(value, GeneratorType): event.waitingHandlers += 1 - self.registerTask((event, value, task)) - self.unregisterTask((event, task)) - # We want to process all the tasks because - # we bind handlers in there - self.processTask(event, value, task) + self.unregisterTask((event, task, None)) + # First yielded value is always the task state + task_state = next(value) + task_state['task_event'] = event + task_state['task'] = value + task_state['parent'] = task + # The below code is delegated to handlers + # in the waitEvent generator + # self.registerTask((event, value, task)) + # XXX: ^^^ Why is this commented out anyway? + elif isinstance(value, ExceptionWrapper): + self.unregisterTask((event, task, parent)) + if parent: + value = parent.throw(value.extract()) + if value is not None: + value_generator = (val for val in (value,)) + self.registerTask((event, value_generator, parent)) + else: + raise value.extract() elif value is not None: event.value.value = value except StopIteration: event.waitingHandlers -= 1 + self.unregisterTask((event, task, parent)) if parent: - self.unregisterTask((event, task, parent)) - else: - self.unregisterTask((event, task)) - if parent: - self.registerTask((event, parent)) + self.registerTask((event, parent, None)) elif event.waitingHandlers == 0: event.value.inform(True) self._eventDone(event) except (KeyboardInterrupt, SystemExit): self.stop() except: - self.unregisterTask((event, task)) + self.unregisterTask((event, task, parent)) etype, evalue, etraceback = _exc_info() traceback = format_tb(etraceback) - error = (etype, evalue, traceback) + err = (etype, evalue, etraceback) - event.value.value = error + event.value.value = err event.value.errors = True event.value.inform(True) if event.failure: - self.fire( - Failure.create("Failure", event, error), - *event.channels - ) + self.fire(event.child("failure", event, err), *event.channels) - self.fire(Error(etype, evalue, traceback, event.handler)) + self.fire( + exception( + etype, evalue, traceback, + handler=None, fevent=event + ) + ) def tick(self, timeout=-1): """ @@ -726,14 +861,14 @@ :type timeout: float, measuring seconds """ # process tasks - for task in self._tasks.copy(): - self.processTask(*task) + if self._tasks: + for task in self._tasks.copy(): + self.processTask(*task) if self._running: - self.fire(GenerateEvents(self._lock, timeout), "*") + self.fire(generate_events(self._lock, timeout), "*") - if len(self._queue): - self.flush() + self._queue and self.flush() def run(self, socket=None): """ @@ -741,7 +876,8 @@ :class:`~.events.Started` event and then continuously calls :meth:`~.tick`. - The method returns when the manager's :meth:`~.stop` method is invoked. + The method returns when the manager's + :meth:`~.stop` method is invoked. If invoked by a programs main thread, a signal handler for the ``INT`` and ``TERM`` signals is installed. This handler @@ -753,8 +889,8 @@ if current_thread().getName() == "MainThread": try: - signal(SIGINT, self._signalHandler) - signal(SIGTERM, self._signalHandler) + set_signal_handler(SIGINT, self._signal_handler) + set_signal_handler(SIGTERM, self._signal_handler) except ValueError: # Ignore if we can't install signal handlers pass @@ -768,7 +904,7 @@ from circuits.core.bridge import Bridge Bridge(socket, channel=socket.channel).register(self) - self.fire(Started(self)) + self.fire(started(self)) try: while self.running or len(self._queue): @@ -777,8 +913,8 @@ for _ in range(3): self.tick() except Exception as e: - print("ERROR: {0:s}".format(e)) - print(format_exc()) + stderr.write("Unhandled ERROR: {0:s}\n".format(str(e))) + stderr.write(format_exc()) finally: try: self.tick() diff -Nru circuits-2.1.0/circuits/core/pollers.py circuits-3.1.0+ds1/circuits/core/pollers.py --- circuits-2.1.0/circuits/core/pollers.py 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/core/pollers.py 2014-09-04 10:32:30.000000000 +0000 @@ -24,42 +24,30 @@ from .events import Event from .components import BaseComponent -TIMEOUT = 0.01 # 10ms timeout +class _read(Event): + """_read Event""" -class Read(Event): - """Read Event""" - name = "_read" +class _write(Event): + """_write Event""" -class Write(Event): - """Write Event""" +class _error(Event): + """_error Event""" - name = "_write" - -class Error(Event): - """Error Event""" - - name = "_error" - - -class Disconnect(Event): - """Disconnect Event""" - - name = "_disconnect" +class _disconnect(Event): + """_disconnect Event""" class BasePoller(BaseComponent): channel = None - def __init__(self, timeout=TIMEOUT, channel=channel): + def __init__(self, channel=channel): super(BasePoller, self).__init__(channel=channel) - self.timeout = timeout - self._read = [] self._write = [] self._targets = {} @@ -84,17 +72,18 @@ at.join() return (res_list[0], clnt_sock) - @handler("generate_events", priority=-9, filter=True) + @handler("generate_events", priority=-9) def _on_generate_events(self, event): """ Pollers have slightly higher priority than the default handler from Manager to ensure that they are invoked before the - default handler. They act as filters to avoid the additional + default handler. They act as event filters to avoid the additional invocation of the default handler which would be unnecessary overhead. """ + + event.stop() self._generate_events(event) - return True def resume(self): if isinstance(self._ctrl_send, socket): @@ -105,7 +94,7 @@ def _read_ctrl(self): try: if isinstance(self._ctrl_recv, socket): - return socket.recv(1) + return self._ctrl_recv.recv(1) else: return os.read(self._ctrl_recv, 1) except: @@ -124,13 +113,13 @@ def removeReader(self, fd): if fd in self._read: self._read.remove(fd) - if fd in self._targets: + if not (fd in self._read or fd in self._write) and fd in self._targets: del self._targets[fd] def removeWriter(self, fd): if fd in self._write: self._write.remove(fd) - if not (fd in self._read or fd in self._write): + if not (fd in self._read or fd in self._write) and fd in self._targets: del self._targets[fd] def isReading(self, fd): @@ -162,8 +151,8 @@ channel = "select" - def __init__(self, timeout=TIMEOUT, channel=channel): - super(Select, self).__init__(timeout, channel=channel) + def __init__(self, channel=channel): + super(Select, self).__init__(channel=channel) self._read.append(self._ctrl_recv) @@ -209,14 +198,14 @@ for sock in w: if self.isWriting(sock): - self.fire(Write(sock), self.getTarget(sock)) + self.fire(_write(sock), self.getTarget(sock)) for sock in r: if sock == self._ctrl_recv: self._read_ctrl() continue if self.isReading(sock): - self.fire(Read(sock), self.getTarget(sock)) + self.fire(_read(sock), self.getTarget(sock)) class Poll(BasePoller): @@ -228,8 +217,8 @@ channel = "poll" - def __init__(self, timeout=TIMEOUT, channel=channel): - super(Poll, self).__init__(timeout, channel=channel) + def __init__(self, channel=channel): + super(Poll, self).__init__(channel=channel) self._map = {} self._poller = select.poll() @@ -244,11 +233,11 @@ self._updateRegistration(self._ctrl_recv) def _updateRegistration(self, fd): - fileno = fd.fileno() + fileno = fd.fileno() if not isinstance(fd, int) else fd try: self._poller.unregister(fileno) - except KeyError: + except (KeyError, ValueError): pass mask = 0 @@ -263,7 +252,10 @@ self._map[fileno] = fd else: super(Poll, self).discard(fd) - del self._map[fileno] + try: + del self._map[fileno] + except KeyError: + pass def addReader(self, source, fd): super(Poll, self).addReader(source, fd) @@ -311,19 +303,19 @@ return if event & self._disconnected_flag and not (event & select.POLLIN): - self.fire(Disconnect(fd), self.getTarget(fd)) + self.fire(_disconnect(fd), self.getTarget(fd)) self._poller.unregister(fileno) super(Poll, self).discard(fd) del self._map[fileno] else: try: if event & select.POLLIN: - self.fire(Read(fd), self.getTarget(fd)) + self.fire(_read(fd), self.getTarget(fd)) if event & select.POLLOUT: - self.fire(Write(fd), self.getTarget(fd)) + self.fire(_write(fd), self.getTarget(fd)) except Exception as e: - self.fire(Error(fd, e), self.getTarget(fd)) - self.fire(Disconnect(fd), self.getTarget(fd)) + self.fire(_error(fd, e), self.getTarget(fd)) + self.fire(_disconnect(fd), self.getTarget(fd)) self._poller.unregister(fileno) super(Poll, self).discard(fd) del self._map[fileno] @@ -338,8 +330,8 @@ channel = "epoll" - def __init__(self, timeout=TIMEOUT, channel=channel): - super(EPoll, self).__init__(timeout, channel=channel) + def __init__(self, channel=channel): + super(EPoll, self).__init__(channel=channel) self._map = {} self._poller = select.epoll() @@ -351,9 +343,9 @@ def _updateRegistration(self, fd): try: - fileno = fd.fileno() + fileno = fd.fileno() if not isinstance(fd, int) else fd self._poller.unregister(fileno) - except (SocketError, IOError) as e: + except (SocketError, IOError, ValueError) as e: if e.args[0] == EBADF: keys = [k for k, v in list(self._map.items()) if v == fd] for key in keys: @@ -421,19 +413,19 @@ return if event & self._disconnected_flag and not (event & select.POLLIN): - self.fire(Disconnect(fd), self.getTarget(fd)) + self.fire(_disconnect(fd), self.getTarget(fd)) self._poller.unregister(fileno) super(EPoll, self).discard(fd) del self._map[fileno] else: try: if event & select.EPOLLIN: - self.fire(Read(fd), self.getTarget(fd)) + self.fire(_read(fd), self.getTarget(fd)) if event & select.EPOLLOUT: - self.fire(Write(fd), self.getTarget(fd)) + self.fire(_write(fd), self.getTarget(fd)) except Exception as e: - self.fire(Error(fd, e), self.getTarget(fd)) - self.fire(Disconnect(fd), self.getTarget(fd)) + self.fire(_error(fd, e), self.getTarget(fd)) + self.fire(_disconnect(fd), self.getTarget(fd)) self._poller.unregister(fileno) super(EPoll, self).discard(fd) del self._map[fileno] @@ -448,8 +440,8 @@ channel = "kqueue" - def __init__(self, timeout=0.00001, channel=channel): - super(KQueue, self).__init__(timeout, channel=channel) + def __init__(self, channel=channel): + super(KQueue, self).__init__(channel=channel) self._map = {} self._poller = select.kqueue() @@ -544,13 +536,13 @@ return if event.flags & select.KQ_EV_ERROR: - self.fire(Error(sock, "error"), self.getTarget(sock)) + self.fire(_error(sock, "error"), self.getTarget(sock)) elif event.flags & select.KQ_EV_EOF: - self.fire(Disconnect(sock), self.getTarget(sock)) + self.fire(_disconnect(sock), self.getTarget(sock)) elif event.filter == select.KQ_FILTER_WRITE: - self.fire(Write(sock), self.getTarget(sock)) + self.fire(_write(sock), self.getTarget(sock)) elif event.filter == select.KQ_FILTER_READ: - self.fire(Read(sock), self.getTarget(sock)) + self.fire(_read(sock), self.getTarget(sock)) Poller = Select diff -Nru circuits-2.1.0/circuits/core/timers.py circuits-3.1.0+ds1/circuits/core/timers.py --- circuits-2.1.0/circuits/core/timers.py 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/core/timers.py 2014-09-04 10:32:30.000000000 +0000 @@ -1,9 +1,8 @@ # Module: timers # Date: 04th August 2004 # Author: James Mills -""" -Timer component to facilitate timed events. -""" + +"""Timer component to facilitate timed events.""" from circuits.core.handlers import handler @@ -14,7 +13,8 @@ class Timer(BaseComponent): - """ + """Timer Component + A timer is a component that fires an event once after a certain delay or periodically at a regular interval. """ @@ -22,36 +22,39 @@ def __init__(self, interval, event, *channels, **kwargs): """ :param interval: the delay or interval to wait for until - the event is fired. If interval is specified as - datetime, the interval is recalculated as the time span from - now to the given datetime. - :type interval: datetime or float number - - :param event: the event to fire. - :type event: :class:`~.events.Event` - - If the optional keyword argument *persist* is set to ``True``, - the event will be fired repeatedly. Else the timer fires the - event once and then unregisters itself. + the event is fired. If interval is specified as + datetime, the interval is recalculated as the + time span from now to the given datetime. + :type interval: ``datetime`` or number of seconds as a ``float`` + + :param event: the event to fire. + :type event: :class:`~.events.Event` + + :param persist: An optional keyword argument which if ``True`` + will cause the event to be fired repeatedly + once per configured interval until the timer + is unregistered. **Default:** ``False`` + :type persist: ``bool`` """ - super(Timer, self).__init__() - if isinstance(interval, datetime): - self.interval = mktime(interval.timetuple()) - time() - else: - self.interval = interval + super(Timer, self).__init__() + self.expiry = None + self.interval = None self.event = event self.channels = channels - self.persist = kwargs.get("persist", False) - self.reset() + self.reset(interval) @handler("generate_events") def _on_generate_events(self, event): + if self.expiry is None: + return + now = time() - if now >= self._eTime: + + if now >= self.expiry: if self.unregister_pending: return self.fire(self.event, *self.channels) @@ -62,16 +65,25 @@ self.unregister() event.reduce_time_left(0) else: - event.reduce_time_left(self._eTime - now) + event.reduce_time_left(self.expiry - now) - def reset(self): + def reset(self, interval=None): """ Reset the timer, i.e. clear the amount of time already waited for. """ - self._eTime = time() + self.interval + if interval is not None and isinstance(interval, datetime): + self.interval = mktime(interval.timetuple()) - time() + elif interval is not None: + self.interval = interval + + self.expiry = time() + self.interval @property def expiry(self): - return getattr(self, "_eTime", None) + return getattr(self, "_expiry", None) + + @expiry.setter + def expiry(self, seconds): + self._expiry = seconds diff -Nru circuits-2.1.0/circuits/core/utils.py circuits-3.1.0+ds1/circuits/core/utils.py --- circuits-2.1.0/circuits/core/utils.py 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/core/utils.py 2014-09-04 10:32:30.000000000 +0000 @@ -7,17 +7,10 @@ This module defines utilities used by circuits. """ -import re import sys from imp import reload -UNCAMELRE = re.compile("([a-z0-9])([A-Z])") - - -def uncamel(s): - return UNCAMELRE.sub("\g<1>_\g<2>", s).lower() - def flatten(root, visited=None): if not visited: diff -Nru circuits-2.1.0/circuits/core/values.py circuits-3.1.0+ds1/circuits/core/values.py --- circuits-2.1.0/circuits/core/values.py 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/core/values.py 2014-09-04 10:32:30.000000000 +0000 @@ -11,19 +11,6 @@ from ..six import string_types -class ValueChanged(Event): - """Value Changed Event - - This Event is triggered when the return Value of an Event Handler has - changed its value. - """ - - def __init__(self, value): - "x.__init__(...) initializes x; see x.__class__.__doc__ for signature" - - super(ValueChanged, self).__init__(value) - - class Value(object): """Create a new future Value Object @@ -103,10 +90,7 @@ if isinstance(notify, string_types): e = Event.create(notify, self) else: - e = ValueChanged.create( - "{0:s}ValueChanged".format(self.event.__class__.__name__), - self - ) + e = self.event.child("value_changed", self) self.manager.fire(e, self.manager) diff -Nru circuits-2.1.0/circuits/core/workers.py circuits-3.1.0+ds1/circuits/core/workers.py --- circuits-2.1.0/circuits/core/workers.py 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/core/workers.py 2014-09-04 10:32:30.000000000 +0000 @@ -26,8 +26,8 @@ DEFAULT_WORKERS = 10 -class Task(Event): - """Task Event +class task(Event): + """task Event This Event is used to initiate a new task to be performed by a Worker or a Pool of Worker(s). @@ -42,10 +42,13 @@ :type kwargs: dict """ + success = True + failure = True + def __init__(self, f, *args, **kwargs): "x.__init__(...) initializes x; see x.__class__.__doc__ for signature" - super(Task, self).__init__(f, *args, **kwargs) + super(task, self).__init__(f, *args, **kwargs) class Worker(BaseComponent): @@ -61,7 +64,7 @@ channel = "worker" - def init(self, process=False, workers=DEFAULT_WORKERS, channel=channel): + def init(self, process=False, workers=None, channel=channel): if not hasattr(current_thread(), "_children"): current_thread()._children = WeakKeyDictionary() diff -Nru circuits-2.1.0/circuits/__init__.py circuits-3.1.0+ds1/circuits/__init__.py --- circuits-2.1.0/circuits/__init__.py 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/__init__.py 2014-09-04 10:32:30.000000000 +0000 @@ -8,7 +8,7 @@ **Application Framework** for the `Python Programming Language`_ with a strong **Component** Architecture. -:copyright: CopyRight (C) 2004-2012 by James Mills +:copyright: CopyRight (C) 2004-2013 by James Mills :license: MIT (See: LICENSE) .. _Python Programming Language: http://www.python.org/ @@ -16,11 +16,12 @@ __author__ = "James Mills" __date__ = "24th February 2013" -__version__ = "2.1.0" -from circuits.core import Task, Worker -from circuits.core import Debugger, Bridge, Loader, Manager, Timer -from circuits.core import BaseEvent, DerivedEvent, Event, LiteralEvent -from circuits.core import handler, reprhandler, BaseComponent, Component +from .version import version as __version__ + +from .core import Event +from .core import task, Worker +from .core import handler, reprhandler, BaseComponent, Component +from .core import Debugger, Bridge, Loader, Manager, Timer, TimeoutError # flake8: noqa diff -Nru circuits-2.1.0/circuits/io/events.py circuits-3.1.0+ds1/circuits/io/events.py --- circuits-2.1.0/circuits/io/events.py 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/io/events.py 2014-09-04 10:32:30.000000000 +0000 @@ -10,41 +10,73 @@ from circuits.core import Event -class EOF(Event): - """EOF Event""" +class eof(Event): + """eof Event""" -class Seek(Event): - """Seek Event""" +class seek(Event): + """seek Event""" -class Read(Event): - """Read Event""" +class read(Event): + """read Event""" -class Close(Event): - """Close Event""" +class close(Event): + """close Event""" -class Write(Event): - """Write Event""" +class write(Event): + """write Event""" -class Error(Event): - """Error Event""" +class error(Event): + """error Event""" -class Open(Event): - """Open Event""" +class open(Event): + """open Event""" -class Opened(Event): - """Opened Event""" +class opened(Event): + """opened Event""" -class Closed(Event): - """Closed Event""" +class closed(Event): + """closed Event""" -class Ready(Event): - """Ready Event""" +class ready(Event): + """ready Event""" + + +class started(Event): + """started Event""" + + +class stopped(Event): + """stopped Event""" + + +class moved(Event): + """moved Event""" + + +class created(Event): + """created Event""" + + +class deleted(Event): + """deleted Event""" + + +class accessed(Event): + """accessed Event""" + + +class modified(Event): + """modified Event""" + + +class unmounted(Event): + """unmounted Event""" diff -Nru circuits-2.1.0/circuits/io/file.py circuits-3.1.0+ds1/circuits/io/file.py --- circuits-2.1.0/circuits/io/file.py 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/io/file.py 2014-09-04 10:32:30.000000000 +0000 @@ -10,27 +10,23 @@ try: from os import O_NONBLOCK except ImportError: - #If it fails, that's fine. the fcntl import - #will fail anyway. + # If it fails, that's fine. the fcntl import + # will fail anyway. pass -from os import write from collections import deque +from os import read as fd_read +from os import write as fd_write from sys import getdefaultencoding -from socket import error as SocketError -from errno import ENOTCONN, EPIPE, EWOULDBLOCK +from errno import EINTR, EWOULDBLOCK from circuits.tools import tryimport from circuits.core.utils import findcmp -from circuits.six import binary_type, PY3 from circuits.core import handler, Component, Event from circuits.core.pollers import BasePoller, Poller +from circuits.six import binary_type, string_types, PY3 -if PY3: - from io import FileIO - FileType = FileIO -else: - FileType = file +from .events import close, closed, eof, error, opened, read, ready fcntl = tryimport("fcntl") @@ -38,44 +34,8 @@ BUFSIZE = 4096 -class EOF(Event): - """EOF Event""" - - -class Seek(Event): - """Seek Event""" - - -class Read(Event): - """Read Event""" - - -class Close(Event): - """Close Event""" - - -class Write(Event): - """Write Event""" - - -class Error(Event): - """Error Event""" - - -class Open(Event): - """Open Event""" - - -class Opened(Event): - """Opened Event""" - - -class Closed(Event): - """Closed Event""" - - -class Ready(Event): - """Ready Event""" +class _open(Event): + """_open Event""" class File(Component): @@ -109,22 +69,22 @@ @handler("ready") def _on_ready(self, component): - self.fire(Open(), self.channel) + self.fire(_open(), self.channel) - @handler("open") + @handler("_open") def _on_open(self, filename=None, mode=None, bufsize=None): self._filename = filename or self._filename self._bufsize = bufsize or self._bufsize self._mode = mode or self._mode - if isinstance(self._filename, FileType): + if isinstance(self._filename, string_types[0]): + kwargs = {"encoding": self._encoding} if PY3 else {} + self._fd = open(self.filename, self.mode, **kwargs) + else: self._fd = self._filename self._mode = self._fd.mode self._filename = self._fd.name self._encoding = getattr(self._fd, "encoding", self._encoding) - else: - kwargs = {"encoding": self._encoding} if PY3 else {} - self._fd = open(self.filename, self.mode, **kwargs) if fcntl is not None: # Set non-blocking file descriptor (non-portable) @@ -135,28 +95,28 @@ if "r" in self.mode or "+" in self.mode: self._poller.addReader(self, self._fd) - self.fire(Opened(self.filename, self.mode)) + self.fire(opened(self.filename, self.mode)) - @handler("registered", channel="*") - def _on_registered(self, component, manager): + @handler("registered", "started", channel="*") + def _on_registered_or_started(self, component, manager=None): if self._poller is None: if isinstance(component, BasePoller): self._poller = component - self.fire(Ready(self)) + self.fire(ready(self)) else: if component is not self: return component = findcmp(self.root, BasePoller) if component is not None: self._poller = component - self.fire(Ready(self)) + self.fire(ready(self)) else: self._poller = Poller().register(self) - self.fire(Ready(self)) + self.fire(ready(self)) @handler("stopped", channel="*") def _on_stopped(self, component): - self.fire(Close()) + self.fire(close()) @handler("prepare_unregister", channel="*") def _on_prepare_unregister(self, event, c): @@ -174,11 +134,11 @@ self._connected = False try: - self._fd.cllse() + self._fd.close() except: pass - self.fire(Closed()) + self.fire(closed()) def close(self): if not self._buffer: @@ -188,23 +148,23 @@ def _read(self): try: - data = self._fd.read(self._bufsize) + data = fd_read(self._fd.fileno(), self._bufsize) if not isinstance(data, binary_type): data = data.encode(self._encoding) if data: - self.fire(Read(data)).notify = True + self.fire(read(data)).notify = True else: - self.fire(EOF()) + self.fire(eof()) if not any(m in self.mode for m in ("a", "+")): self.close() else: self._poller.discard(self._fd) - except SocketError as e: - if e.args[0] == EWOULDBLOCK: + except (OSError, IOError) as e: + if e.args[0] in (EWOULDBLOCK, EINTR): return else: - self.fire(Error(e)) + self.fire(error(e)) self._close() def seek(self, offset, whence=0): @@ -215,30 +175,31 @@ if not isinstance(data, binary_type): data = data.encode(self._encoding) - nbytes = write(self._fd.fileno(), data) + nbytes = fd_write(self._fd.fileno(), data) if nbytes < len(data): self._buffer.appendleft(data[nbytes:]) - except SocketError as e: - if e.args[0] in (EPIPE, ENOTCONN): - self._close() + except (OSError, IOError) as e: + if e.args[0] in (EWOULDBLOCK, EINTR): + return else: - self.fire(Error(e)) + self.fire(error(e)) + self._close() def write(self, data): if self._poller is not None and not self._poller.isWriting(self._fd): self._poller.addWriter(self, self._fd) self._buffer.append(data) - @handler("_disconnect", filter=True) + @handler("_disconnect") def __on_disconnect(self, sock): self._close() - @handler("_read", filter=True) + @handler("_read") def __on_read(self, sock): self._read() - @handler("_write", filter=True) + @handler("_write") def __on_write(self, sock): if self._buffer: data = self._buffer.popleft() diff -Nru circuits-2.1.0/circuits/io/__init__.py circuits-3.1.0+ds1/circuits/io/__init__.py --- circuits-2.1.0/circuits/io/__init__.py 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/io/__init__.py 2014-09-04 10:32:30.000000000 +0000 @@ -4,18 +4,16 @@ """I/O Support -This package contains various I/O Components. Provided are a a generic File -Component, StdIn, StdOut and StdErr components. Instances of StdIn, StdOUt +This package contains various I/O Components. Provided are a generic File +Component, StdIn, StdOut and StdErr components. Instances of StdIn, StdOut and StdErr are also created by importing this package. """ import sys from .file import File -from .file import Close, Open, Seek, Write - from .process import Process -from .process import Start, Stop, Signal, Kill, Wait +from .events import close, open, seek, write try: from .notify import Notify diff -Nru circuits-2.1.0/circuits/io/notify.py circuits-3.1.0+ds1/circuits/io/notify.py --- circuits-2.1.0/circuits/io/notify.py 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/io/notify.py 2014-09-04 10:32:30.000000000 +0000 @@ -17,74 +17,31 @@ raise Exception("No pyinotify support available. Is pyinotify installed?") from circuits.core.utils import findcmp -from circuits.core import handler, Component, Event +from circuits.core import handler, BaseComponent from circuits.core.pollers import BasePoller, Poller -MASK = ALL_EVENTS - - -class Ready(Event): - """Ready Event""" - - -class AddPath(Event): - """Add path to watch""" - - -class RemovePath(Event): - """Remove path from watch""" - - -class Moved(Event): - """Moved Event""" - - -class Opened(Event): - """Opened Event""" - - -class Closed(Event): - """Closed Event""" - - -class Created(Event): - """Created Event""" - - -class Deleted(Event): - """Deleted Event""" - - -class Accessed(Event): - """Accessed Event""" - - -class Modified(Event): - """Modified Event""" - - -class Unmounted(Event): - """Unmounted Event""" +from .events import accessed, closed, created, deleted, modified, moved, opened, ready, unmounted +MASK = ALL_EVENTS EVENT_MAP = { - IN_MOVED_TO: Moved, - IN_MOVE_SELF: Moved, - IN_MOVED_FROM: Moved, - IN_CLOSE_WRITE: Closed, - IN_CLOSE_NOWRITE: Closed, - IN_OPEN: Opened, - IN_DELETE_SELF: Deleted, - IN_DELETE: Deleted, - IN_CREATE: Created, - IN_ACCESS: Accessed, - IN_MODIFY: Modified, - IN_ATTRIB: Modified, - IN_UNMOUNT: Unmounted, + IN_MOVED_TO: moved, + IN_MOVE_SELF: moved, + IN_MOVED_FROM: moved, + IN_CLOSE_WRITE: closed, + IN_CLOSE_NOWRITE: closed, + IN_OPEN: opened, + IN_DELETE_SELF: deleted, + IN_DELETE: deleted, + IN_CREATE: created, + IN_ACCESS: accessed, + IN_MODIFY: modified, + IN_ATTRIB: modified, + IN_UNMOUNT: unmounted, } -class Notify(Component): +class Notify(BaseComponent): channel = "notify" @@ -124,27 +81,26 @@ if self._poller is None: if isinstance(component, BasePoller): self._poller = component - self.fire(Ready(self)) + self.fire(ready(self)) else: if component is not self: return component = findcmp(self.root, BasePoller) if component is not None: self._poller = component - self.fire(Ready(self)) + self.fire(ready(self)) else: self._poller = Poller().register(self) - self.fire(Ready(self)) + self.fire(ready(self)) - @handler("started", filter=True, channel="*") - def _on_started(self, component): + @handler("started", channel="*", priority=1) + def _on_started(self, event, component): if self._poller is None: self._poller = Poller().register(self) - self.fire(Ready(self)) - - return True + self.fire(ready(self)) + event.stop() - @handler("_read", filter=True) + @handler("_read", priority=1) def __on_read(self, fd): self._notifier.read_events() self._notifier.process_events() diff -Nru circuits-2.1.0/circuits/io/process.py circuits-3.1.0+ds1/circuits/io/process.py --- circuits-2.1.0/circuits/io/process.py 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/io/process.py 2014-09-04 10:32:30.000000000 +0000 @@ -1,42 +1,23 @@ -#!/usr/bin/python -i - -from io import BytesIO -from subprocess import Popen, PIPE -from circuits.core.manager import TIMEOUT - -from circuits.io import File, Write -from circuits import handler, Component, Event - - -class Started(Event): - """Started Event""" - - -class Stopped(Event): - """Stopped Event""" +# Module: process +# Date: 4th January 2013 +# Author: James Mills +"""Process -class Start(Event): - """Start Event""" +This module implements a wrapper for basic ``subprocess.Popen`` functionality. +""" +from io import BytesIO +from subprocess import Popen, PIPE -class Stop(Event): - """Stop Event""" - - -class Signal(Event): - """Signal Event""" - - -class Kill(Event): - """Kill Event""" - +from circuits.core.manager import TIMEOUT +from circuits import handler, BaseComponent -class Wait(Event): - """Wait Event""" +from .file import File +from .events import started, stopped, write -class Process(Component): +class Process(BaseComponent): channel = "process" @@ -119,7 +100,7 @@ ) ) - self.fire(Started(self)) + self.fire(started(self)) @staticmethod def _on_stdout_closed(self): @@ -143,7 +124,7 @@ return self.p.wait() def write(self, data): - self.fire(Write(data), "{0:d}.stdin".format(self.p.pid)) + self.fire(write(data), "{0:d}.stdin".format(self.p.pid)) @property def status(self): @@ -170,8 +151,8 @@ self.removeHandler(self._stdout_read_handler) self.removeHandler(self._stderr_closed_handler) self.removeHandler(self._stdout_closed_handler) - self.fire(Stopped(self)) + self.fire(stopped(self)) event.reduce_time_left(0) - return True + event.stop() else: event.reduce_time_left(TIMEOUT) diff -Nru circuits-2.1.0/circuits/io/serial.py circuits-3.1.0+ds1/circuits/io/serial.py --- circuits-2.1.0/circuits/io/serial.py 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/io/serial.py 2014-09-04 10:32:30.000000000 +0000 @@ -11,10 +11,13 @@ import select from collections import deque -from circuits.core import Component +from circuits.core import Component, handler, Event +from circuits.core.pollers import BasePoller, Poller +from circuits.core.utils import findcmp from circuits.tools import tryimport +from circuits.six import binary_type, string_types -from .events import Closed, Error, Opened, Read +from .events import closed, error, opened, read, ready, close serial = tryimport("serial") @@ -22,6 +25,10 @@ BUFSIZE = 4096 +class _open(Event): + """_open Event""" + + class Serial(Component): channel = "serial" @@ -33,60 +40,129 @@ if serial is None: raise RuntimeError("No serial support available") - self.port = port - self.baudrate = baudrate - - self._serial = serial.Serial() - self._serial.port = port - self._serial.baudrate = baudrate - - if os.name == "posix": - self._serial.timeout = 0 # non-blocking (POSIX) - else: - self._serial.timeout = timeout + self._port = port + self._baudrate = baudrate + self._bufsize = bufsize + self._serial = None + self._poller = None self._buffer = deque() - self._bufsize = bufsize - self._timeout = timeout + self._closeflag = False - self._read = [] - self._write = [] + @handler("ready") + def _on_ready(self, component): + self.fire(_open(), self.channel) + + @handler("_open") + def _on_open(self, port=None, baudrate=None, bufsize=None): + self._port = port or self._port + self._baudrate = baudrate or self._baudrate + self._bufsize = bufsize or self._bufsize + + self._serial = serial.Serial(port=self._port, baudrate=self._baudrate, timeout=0) + self._fd = self._serial.fileno() # not portable! + + self._poller.addReader(self, self._fd) + + self.fire(opened(self._port, self._baudrate)) + + @handler("registered", "started", channel="*") + def _on_registered_or_started(self, component, manager=None): + if self._poller is None: + if isinstance(component, BasePoller): + self._poller = component + self.fire(ready(self)) + else: + if component is not self: + return + component = findcmp(self.root, BasePoller) + if component is not None: + self._poller = component + self.fire(ready(self)) + else: + self._poller = Poller().register(self) + self.fire(ready(self)) - self._serial.open() - self._fd = self._serial.fileno() + @handler("stopped", channel="*") + def _on_stopped(self, component): + self.fire(close()) + + @handler("prepare_unregister", channel="*") + def _on_prepare_unregister(self, event, c): + if event.in_subtree(self): + self._close() + + def _close(self): + if self._closeflag: + return + + self._poller.discard(self._fd) + + self._buffer.clear() + self._closeflag = False + self._connected = False + + try: + self._serial.close() + except: + pass - self._read.append(self._fd) + self.fire(closed()) - self.fire(Opened(self.port)) + def close(self): + if not self._buffer: + self._close() + elif not self._closeflag: + self._closeflag = True + + def _read(self): + try: + data = self._serial.read(self._bufsize) + if not isinstance(data, binary_type): + data = data.encode(self._encoding) - def __tick__(self): - r, w, e = select.select(self._read, self._write, [], self._timeout) + if data: + self.fire(read(data)).notify = True + except (OSError, IOError) as e: + self.fire(error(e)) + self._close() + + def _write(self, data): + try: + if not isinstance(data, binary_type): + data = data.encode(self._encoding) - if w and self._buffer: - data = self._buffer.popleft() try: - bytes = os.write(self._fd, data) - if bytes < len(data): - self._buffer.append(data[bytes:]) - else: - if not self._buffer and self._fd in self._write: - self._write.remove(self._fd) - except OSError as error: - self.fire(Error(error)) - - if r: - data = os.read(self._fd, self._bufsize) - if data: - self.fire(Read(data)) + nbytes = self._serial.write(data) + except (serial.SerialTimeoutException) as e: + nbytes = 0 + if nbytes < len(data): + self._buffer.appendleft(data[nbytes:]) + except (OSError, IOError) as e: + self.fire(error(e)) + self._close() def write(self, data): - if self._fd not in self._write: - self._write.append(self._fd) + if self._poller is not None and not self._poller.isWriting(self._fd): + self._poller.addWriter(self, self._fd) self._buffer.append(data) - def close(self): - self._fd = None - self._read = [] - self._write = [] - self._serial.close() - self.fire(Closed(self.port)) + @handler("_disconnect") + def __on_disconnect(self, sock): + self._close() + + @handler("_read") + def __on_read(self, sock): + self._read() + + @handler("_write") + def __on_write(self, sock): + if self._buffer: + data = self._buffer.popleft() + self._write(data) + + if not self._buffer: + if self._closeflag: + self._close() + elif self._poller.isWriting(self._fd): + self._poller.removeWriter(self._fd) diff -Nru circuits-2.1.0/circuits/net/events.py circuits-3.1.0+ds1/circuits/net/events.py --- circuits-2.1.0/circuits/net/events.py 1970-01-01 00:00:00.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/net/events.py 2014-09-04 10:32:30.000000000 +0000 @@ -0,0 +1,220 @@ +# Module: events +# Date: 21st September 2013 +# Author: James Mills + +"""Networking Events + +This module implements commonly used Networking events used by socket components. +""" + +from circuits.core import Event + + +class connect(Event): + """connect Event + + This Event is sent when a new client connection has arrived on a server. + This event is also used for client's to initiate a new connection to + a remote host. + + .. note :: + This event is used for both Client and Server Components. + + :param args: Client: (host, port) Server: (sock, host, port) + :type args: tuple + + :param kwargs: Client: (ssl) + :type kwargs: dict + """ + + def __init__(self, *args, **kwargs): + "x.__init__(...) initializes x; see x.__class__.__doc__ for signature" + + super(connect, self).__init__(*args, **kwargs) + + +class disconnect(Event): + """disconnect Event + + This Event is sent when a client connection has closed on a server. + This event is also used for client's to disconnect from a remote host. + + .. note:: + This event is used for both Client and Server Components. + + :param args: Client: () Server: (sock) + :type tuple: tuple + """ + + def __init__(self, *args): + "x.__init__(...) initializes x; see x.__class__.__doc__ for signature" + + super(disconnect, self).__init__(*args) + + +class connected(Event): + """connected Event + + This Event is sent when a client has successfully connected. + + .. note:: + This event is for Client Components. + + :param host: The hostname connected to. + :type str: str + + :param port: The port connected to + :type int: int + """ + + def __init__(self, host, port): + "x.__init__(...) initializes x; see x.__class__.__doc__ for signature" + + super(connected, self).__init__(host, port) + + +class disconnected(Event): + """disconnected Event + + This Event is sent when a client has disconnected + + .. note:: + This event is for Client Components. + """ + + def __init__(self): + "x.__init__(...) initializes x; see x.__class__.__doc__ for signature" + + super(disconnected, self).__init__() + + +class read(Event): + """read Event + + This Event is sent when a client or server connection has read any data. + + .. note:: + This event is used for both Client and Server Components. + + :param args: Client: (data) Server: (sock, data) + :type tuple: tuple + """ + + def __init__(self, *args): + "x.__init__(...) initializes x; see x.__class__.__doc__ for signature" + + super(read, self).__init__(*args) + + +class error(Event): + """error Event + + This Event is sent when a client or server connection has an error. + + .. note:: + This event is used for both Client and Server Components. + + :param args: Client: (error) Server: (sock, error) + :type tuple: tuple + """ + + def __init__(self, *args): + "x.__init__(...) initializes x; see x.__class__.__doc__ for signature" + + super(error, self).__init__(*args) + + +class broadcast(Event): + """broadcast Event + + This Event is used by the UDPServer/UDPClient sockets to send a message on the ```` + network. + + .. note:: + - This event is never sent, it is used to send data. + - This event is used for both Client and Server UDP Components. + + :param args: (data, port) + :type tuple: tuple + """ + + def __init__(self, *args): + "x.__init__(...) initializes x; see x.__class__.__doc__ for signature" + + super(broadcast, self).__init__(*args) + + +class write(Event): + """write Event + + This Event is used to notify a client, client connection or server that + we have data to be written. + + .. note:: + - This event is never sent, it is used to send data. + - This event is used for both Client and Server Components. + + :param args: Client: (data) Server: (sock, data) + :type tuple: tuple + """ + + def __init__(self, *args): + "x.__init__(...) initializes x; see x.__class__.__doc__ for signature" + + super(write, self).__init__(*args) + + +class close(Event): + """close Event + + This Event is used to notify a client, client connection or server that + we want to close. + + .. note:: + - This event is never sent, it is used to close. + - This event is used for both Client and Server Components. + + :param args: Client: () Server: (sock) + :type tuple: tuple + """ + + def __init__(self, *args): + "x.__init__(...) initializes x; see x.__class__.__doc__ for signature" + + super(close, self).__init__(*args) + + +class ready(Event): + """ready Event + + This Event is used to notify the rest of the system that the underlying + Client or Server Component is ready to begin processing connections or + incoming/outgoing data. (This is triggered as a direct result of having + the capability to support multiple client/server components with a single + poller component instance in a system). + + .. note:: + This event is used for both Client and Server Components. + + :param component: The Client/Server Component that is ready. + :type tuple: Component (Client/Server) + + :param bind: The (host, port) the server has bound to. + :type tuple: (host, port) + """ + + def __init__(self, component, bind=None): + "x.__init__(...) initializes x; see x.__class__.__doc__ for signature" + + args = (component, bind) if bind is not None else (component,) + super(ready, self).__init__(*args) + + +class closed(Event): + """closed Event + + This Event is sent when a server has closed its listening socket. + + .. note:: + This event is for Server components. + """ diff -Nru circuits-2.1.0/circuits/net/__init__.py circuits-3.1.0+ds1/circuits/net/__init__.py --- circuits-2.1.0/circuits/net/__init__.py 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/net/__init__.py 2014-09-04 10:32:30.000000000 +0000 @@ -7,6 +7,6 @@ This package contains components that implement network sockets and protocols for implementing client and server network applications. -:copyright: CopyRight (C) 2004-2012 by James Mills +:copyright: CopyRight (C) 2004-2013 by James Mills :license: MIT (See: LICENSE) """ diff -Nru circuits-2.1.0/circuits/net/protocols/http.py circuits-3.1.0+ds1/circuits/net/protocols/http.py --- circuits-2.1.0/circuits/net/protocols/http.py 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/net/protocols/http.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,94 +0,0 @@ - -from io import BytesIO - -from circuits.web.headers import parse_headers -from circuits.core import handler, BaseComponent, Event - - -class Request(Event): - """Request Event""" - - -class Response(Event): - """Response Event""" - - -class ResponseObject(object): - - def __init__(self, status, message, protocol=None): - self.status = status - self.message = message - self.protocol = protocol - - self._headers = None - self._body = BytesIO() - - def __repr__(self): - return "" % ( - self.status, - self.headers["Content-Type"], - len(self._body.getvalue()) - ) - - @property - def headers(self): - return self._headers - - def read(self): - return self._body.read() - - -class HTTP(BaseComponent): - - channel = "web" - - def __init__(self, encoding="utf-8", channel=channel): - super(HTTP, self).__init__(channel=channel) - - self._encoding = encoding - - self._header_head = None - self._response = None - self._buffer = BytesIO() - - @handler("read") - def _on_client_read(self, data): - if self._response is not None: - self._response._body.write(data) - cLen = int(self._response.headers.get("Content-Length", "0")) - if cLen and self._response._body.tell() == cLen: - self._response._body.seek(0) - self.fire(Response(self._response)) - self._response = None - else: - if self._header_head is not None: - data = self._header_head + data - self._header_head = None - if data.find(b"\r\n\r\n") < 0: - # Header not received completely yet - self._header_head = data - return - statusline, data = data.split(b"\r\n", 1) - statusline = statusline.strip().decode(self._encoding, "replace") - protocol, status, message = statusline.split(" ", 2) - - status = int(status) - protocol = tuple(map(int, protocol[5:].split("."))) - - response = ResponseObject(status, message, protocol) - - end_of_headers = data.find(b"\r\n\r\n") - header_data = data[:end_of_headers].decode( - self._encoding, "replace" - ) - headers = response._headers = parse_headers(header_data) - - response._body.write(data[(end_of_headers + 4):]) - - cLen = int(headers.get("Content-Length", "0")) - if cLen and response._body.tell() < cLen: - self._response = response - return - - response._body.seek(0) - self.fire(Response(response)) diff -Nru circuits-2.1.0/circuits/net/protocols/__init__.py circuits-3.1.0+ds1/circuits/net/protocols/__init__.py --- circuits-2.1.0/circuits/net/protocols/__init__.py 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/net/protocols/__init__.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,13 +0,0 @@ -# Package: protocols -# Date: 13th March 2009 -# Author: James Mills, prologic at shortcircuit dot net dot au - -"""Networking Protocols - -This package contains components that implement various networking protocols. -""" - -from .line import LP -from .irc import IRC - -# flake8: noqa diff -Nru circuits-2.1.0/circuits/net/protocols/irc.py circuits-3.1.0+ds1/circuits/net/protocols/irc.py --- circuits-2.1.0/circuits/net/protocols/irc.py 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/net/protocols/irc.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,522 +0,0 @@ -# Module: irc -# Date: 04th August 2004 -# Author: James Mills - -"""Internet Relay Chat Protocol - -This module implements the Internet Relay Chat Protocol -or commonly known as IRC. - -This module can be used in both server and client -implementations. -""" - -import re - -from circuits.net.sockets import Write -from circuits.core import handler, Event, Component - -from .line import LP - -### -### Supporting Functions -### - - -def strip(s, color=False): - """strip(s, color=False) -> str - - Strips the : from the start of a string - and optionally also strips all colors if - color is True. - """ - - if len(s) > 0: - if s[0] == ":": - s = s[1:] - if color: - s = s.replace("\x01", "") - s = s.replace("\x02", "") - return s - - -def sourceJoin(nick, ident, host): - """sourceJoin(nick, ident, host) -> str - - Join a source previously split by sourceSplit - and join it back together inserting the ! and @ - appropiately. - """ - - return "%s!%s@%s" % (nick, ident, host) - - -def sourceSplit(source): - """sourceSplit(source) -> str, str, str - - Split the given source into its parts. - - source must be of the form: nick!ident@host - - Example: - >>> nick, ident, host, = sourceSplit("Joe!Blogs@localhost") - """ - - m = re.match( - "(?P[^!].*)!(?P.*)@(?P.*)", - source - ) - - if m is not None: - d = m.groupdict() - return d["nick"], d["ident"], d["host"] - else: - return source, None, None - -### -### IRC Commands -### - - -class Command(Event): - """Command Event""" - - def __init__(self, *args, **kwargs): - super(Command, self).__init__(*args, **kwargs) - - self.name = "command_{0}".format(self.__class__.__name__.lower()) - - -class RAW(Command): - """RAW command""" - - -class PASS(Command): - """PASS command""" - - -class USER(Command): - """USER command""" - - -class NICK(Command): - """NICK command""" - - -class PING(Command): - """PING command""" - - -class PONG(Command): - """PONG command""" - - -class QUIT(Command): - """QUIT command""" - - -class JOIN(Command): - """JOIN command""" - - -class PART(Command): - """PART command""" - - -class PRIVMSG(Command): - """PRIVMSG command""" - - -class NOTICE(Command): - """NOTICE command""" - - -class CTCP(Command): - """CTCP command""" - - -class CTCPREPLY(Command): - """CTCPREPLY command""" - - -class KICK(Command): - """KICK command""" - - -class TOPIC(Command): - """TOPIC command""" - - -class MODE(Command): - """MODE command""" - - -class INVITE(Command): - """INVITE command""" - - -class NAMES(Command): - """NAMES command""" - -### -### IRC Responses -### - - -class Response(Event): - """Response (Event)""" - - -class Numeric(Response): - """Numeric response""" - - -class Ping(Response): - """Ping response""" - - -class Ctcp(Response): - """Ctcp response""" - - -class Message(Response): - """Message response""" - - -class Notice(Response): - """Notice response""" - - -class Join(Response): - """Join response""" - - -class Part(Response): - """Part response""" - - -class Quit(Response): - """Quit response""" - - -class Nick(Response): - """Nick response""" - - -class Mode(Response): - """Mode response""" - -### -### Protocol Component(s) -### - - -class IRC(Component): - """IRC Protocol Component - - Creates a new IRC Component instance that implements the IRC Protocol. - Incoming messages are handled by the "read" Event Handler, parsed and - processed with appropriate Events created and exposed to the rest of - te system to listen to and handle. - - @note: This Component must be used in conjunction with a Component that - exposes Read Events on a "read" Channel. - """ - - def __init__(self, *args, **kwargs): - super(IRC, self).__init__(*args, **kwargs) - LP(**kwargs).register(self) - - ### - ### IRC Command Event Handlers - ### - - def command_raw(self, data): - self.fire(Write("%s\r\n" % data)) - - @handler("command_pass") - def _on_command_pass(self, password): - self.fire(RAW("PASS %s" % password)) - - def command_user(self, ident, host, server, name): - self.fire(RAW("USER %s \"%s\" \"%s\" :%s" % ( - ident, host, server, name))) - - def command_nick(self, nick): - self.fire(RAW("NICK %s" % nick)) - - def command_ping(self, server): - self.fire(RAW("PING :%s" % server)) - - def command_pong(self, server): - self.fire(RAW("PONG :%s" % server)) - - def command_quit(self, message="Leaving"): - self.fire(RAW("QUIT :%s" % message)) - - def command_join(self, channel, key=None): - if key is None: - self.fire(RAW("JOIN %s" % channel)) - else: - self.fire(RAW("JOIN %s %s" % (channel, key))) - - def command_part(self, channel, message="Leaving"): - self.fire(RAW("PART %s :%s" % (channel, message))) - - def command_privmsg(self, target, message): - self.fire(RAW("PRIVMSG %s :%s" % (target, message))) - - def command_notice(self, target, message): - self.fire(RAW("NOTICE %s :%s" % (target, message))) - - def command_ctcp(self, target, type, message): - self.fire(PRIVMSG(target, "%s %s" % (type, message))) - - def command_ctcpreply(self, target, type, message): - self.fire(NOTICE(target, "%s %s" % (type, message))) - - def command_kick(self, channel, target, message=""): - self.fire(RAW("KICK %s %s :%s" % (channel, target, message))) - - def command_topic(self, channel, topic): - self.fire(RAW("TOPIC %s :%s" % (channel, topic))) - - def command_mode(self, modes, channel=None): - if channel is None: - self.fire(RAW("MODE :%s" % modes)) - else: - self.fire(RAW("MODE %s :%s" % (channel, modes))) - - def command_invite(self, target, channel): - self.fire(RAW("INVITE %s %s" % (target, channel))) - - def command_names(self, channel=None): - if channel: - self.fire(RAW("NAMES %s" % channel)) - else: - self.fire(RAW("NAMES")) - - ### - ### Event Processing - ### - - def line(self, line): - """Line Event Handler - - Process a line of text and generate the appropiate - event. This must not be overridden by sub-classes, - if it is, this must be explitetly called by the - sub-class. Other Components may however listen to - this event and process custom IRC events. - """ - - tokens = line.split(" ") - - if tokens[0] == "PING": - self.fire(Ping(strip(tokens[1]))) - - elif re.match("[0-9]+", tokens[1]): - source = strip(tokens[0]) - target = tokens[2] - - numeric = int(tokens[1]) - if tokens[3].startswith(":"): - arg = None - message = strip(" ".join(tokens[3:])) - else: - arg = tokens[3] - message = strip(" ".join(tokens[4:])) - - self.fire(Numeric(source, target, numeric, arg, message)) - - elif tokens[1] == "PRIVMSG": - source = sourceSplit(strip(tokens[0])) - target = tokens[2] - message = strip(" ".join(tokens[3:])) - - if message and message[0] == "": - tokens = strip(message, color=True).split(" ") - type = tokens[0] - message = " ".join(tokens[1:]) - self.fire(Ctcp(source, target, type, message)) - else: - self.fire(Message(source, target, message)) - - elif tokens[1] == "NOTICE": - source = sourceSplit(strip(tokens[0])) - target = tokens[2] - message = strip(" ".join(tokens[3:])) - self.fire(Notice(source, target, message)) - - elif tokens[1] == "JOIN": - source = sourceSplit(strip(tokens[0])) - channel = strip(tokens[2]) - self.fire(Join(source, channel)) - - elif tokens[1] == "PART": - source = sourceSplit(strip(tokens[0])) - channel = strip(tokens[2]) - message = strip(" ".join(tokens[3:])) - self.fire(Part(source, channel, message)) - - elif tokens[1] == "QUIT": - source = sourceSplit(strip(tokens[0])) - message = strip(" ".join(tokens[2:])) - self.fire(Quit(source, message)) - - elif tokens[1] == "NICK": - source = sourceSplit(strip(tokens[0])) - newNick = strip(tokens[2]) - - self.fire(Nick(source, newNick)) - - elif tokens[1] == "MODE": - source = sourceSplit(strip(tokens[0])) - target = tokens[2] - modes = strip(" ".join(tokens[3:])) - self.fire(Mode(source, target, modes)) - - ### - ### Default Events - ### - - @handler("ping", filter=True) - def _on_ping(self, event, server): - """Ping Event - - This is a default event ro respond to Ping Events - by sending out a Pong in response. Sub-classes - may override this, but be sure to respond to - Ping Events by either explitetly calling this method - or sending your own Pong reponse. - """ - - if isinstance(event, Ping): - self.fire(PONG(server)) - return True - -### -### Errors and Numeric Replies -### - -RPL_WELCOME = 1 -RPL_YOURHOST = 2 - -RPL_TRACELINK = 200 -RPL_TRACECONNECTING = 201 -RPL_TRACEHANDSHAKE = 202 -RPL_TRACEUNKNOWN = 203 -RPL_TRACEOPERATOR = 204 -RPL_TRACEUSER = 205 -RPL_TRACESERVER = 206 -RPL_TRACENEWTYPE = 208 -RPL_TRACELOG = 261 -RPL_STATSLINKINFO = 211 -RPL_STATSCOMMANDS = 212 -RPL_STATSCLINE = 213 -RPL_STATSNLINE = 214 -RPL_STATSILINE = 215 -RPL_STATSKLINE = 216 -RPL_STATSYLINE = 218 -RPL_ENDOFSTATS = 219 -RPL_STATSLLINE = 241 -RPL_STATSUPTIME = 242 -RPL_STATSOLINE = 243 -RPL_STATSHLINE = 244 -RPL_UMODEIS = 221 -RPL_LUSERCLIENT = 251 -RPL_LUSEROP = 252 -RPL_LUSERUNKNOWN = 253 -RPL_LUSERCHANNELS = 254 -RPL_LUSERME = 255 -RPL_ADMINME = 256 -RPL_ADMINLOC1 = 257 -RPL_ADMINLOC2 = 258 -RPL_ADMINEMAIL = 259 - -RPL_NONE = 300 -RPL_USERHOST = 302 -RPL_ISON = 303 -RPL_AWAY = 301 -RPL_UNAWAY = 305 -RPL_NOWAWAY = 306 -RPL_WHOISUSER = 311 -RPL_WHOISSERVER = 312 -RPL_WHOISOPERATOR = 313 -RPL_WHOISIDLE = 317 -RPL_ENDOFWHOIS = 318 -RPL_WHOISCHANNELS = 319 -RPL_WHOWASUSER = 314 -RPL_ENDOFWHOWAS = 369 -RPL_LIST = 322 -RPL_LISTEND = 323 -RPL_CHANNELMODEIS = 324 -RPL_NOTOPIC = 331 -RPL_TOPIC = 332 -RPL_INVITING = 341 -RPL_SUMMONING = 342 -RPL_VERSION = 351 -RPL_WHOREPLY = 352 -RPL_ENDOFWHO = 315 -RPL_NAMREPLY = 353 -RPL_ENDOFNAMES = 366 -RPL_LINKS = 364 -RPL_ENDOFLINKS = 365 -RPL_BANLIST = 367 -RPL_ENDOFBANLIST = 368 -RPL_INFO = 371 -RPL_ENDOFINFO = 374 -RPL_MOTDSTART = 375 -RPL_MOTD = 372 -RPL_ENDOFMOTD = 376 -RPL_YOUREOPER = 381 -RPL_REHASHING = 382 -RPL_TIME = 391 -RPL_USERSSTART = 392 -RPL_USERS = 393 -RPL_ENDOFUSERS = 394 -RPL_NOUSERS = 395 - -ERR_NOSUCHNICK = 401 -ERR_NOSUCHSERVER = 402 -ERR_NOSUCHCHANNEL = 403 -ERR_CANNOTSENDTOCHAN = 404 -ERR_TOOMANYCHANNELS = 405 -ERR_WASNOSUCHNICK = 406 -ERR_TOOMANYTARGETS = 407 -ERR_NOORIGIN = 409 -ERR_NORECIPIENT = 411 -ERR_NOTEXTTOSEND = 412 -ERR_NOTOPLEVEL = 413 -ERR_WILDTOPLEVEL = 414 -ERR_UNKNOWNCOMMAND = 421 -ERR_NOMOTD = 422 -ERR_NOADMININFO = 423 -ERR_FILEERROR = 424 -ERR_NONICKNAMEGIVEN = 431 -ERR_ERRONEUSNICKNAME = 432 -ERR_NICKNAMEINUSE = 433 -ERR_NICKCOLLISION = 436 -ERR_NOTONCHANNEL = 442 -ERR_USERONCHANNEL = 443 -ERR_NOLOGIN = 444 -ERR_SUMMONDISABLED = 445 -ERR_USERSDISABLED = 446 -ERR_NOTREGISTERED = 451 -ERR_NEEDMOREPARAMS = 461 -ERR_ALREADYREGISTRED = 462 -ERR_PASSWDMISMATCH = 464 -ERR_YOUREBANNEDCREEP = 465 -ERR_KEYSET = 467 -ERR_CHANNELISFULL = 471 -ERR_UNKNOWNMODE = 472 -ERR_INVITEONLYCHAN = 473 -ERR_BANNEDFROMCHAN = 474 -ERR_BADCHANNELKEY = 475 -ERR_NOPRIVILEGES = 481 -ERR_CHANOPRIVSNEEDED = 482 -ERR_CANTKILLSERVER = 483 -ERR_NOOPERHOST = 491 - -ERR_UMODEUNKNOWNFLAG = 501 -ERR_USERSDONTMATCH = 502 diff -Nru circuits-2.1.0/circuits/net/protocols/line.py circuits-3.1.0+ds1/circuits/net/protocols/line.py --- circuits-2.1.0/circuits/net/protocols/line.py 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/net/protocols/line.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,112 +0,0 @@ -# Module: line -# Date: 04th February 2010 -# Author: James Mills - -"""Line Protocol - -This module implements the basic Line protocol. - -This module can be used in both server and client implementations. -""" - -import re - -from circuits.core import handler, Event, BaseComponent - -LINESEP = re.compile(b"\r?\n") - - -def splitLines(s, buffer): - """splitLines(s, buffer) -> lines, buffer - - Append s to buffer and find any new lines of text in the - string splitting at the standard IRC delimiter CRLF. Any - new lines found, return them as a list and the remaining - buffer for further processing. - """ - - lines = LINESEP.split(buffer + s) - return lines[:-1], lines[-1] - - -class Line(Event): - """Line Event""" - - -class LP(BaseComponent): - """Line Protocol - - Implements the Line Protocol. - - Incoming data is split into lines with a splitter function. For each - line of data processed a Line Event is created. Any unfinished lines - are appended into an internal buffer. - - A custom line splitter function can be passed to customize how data - is split into lines. This function must accept two arguments, the data - to process and any left over data from a previous invocation of the - splitter function. The function must also return a tiple of two items, - a list of lines and any left over data. - - :param splitter: a line splitter function - :type splitter: function - - This Component operates in two modes. In normal operation it's expected - to be used in conjunction with components that expose a Read Event on - a "read" channel with only one argument (data). Some builtin components - that expose such events are: - - circuits.net.sockets.TCPClient - - circuits.io.File - - The second mode of operation works with circuits.net.sockets.Server - components such as TCPServer, UNIXServer, etc. It's expected that - two arguments exist in the Read Event, sock and data. The following - two arguments can be passed to affect how unfinished data is stored - and retrieved for such components: - - :param getBuffer: function to retrieve the buffer for a client sock - :type getBuffer: function - - This function must accept one argument (sock,) the client socket - whoose buffer is to be retrieved. - - :param updateBuffer: function to update the buffer for a client sock - :type updateBuffer: function - - This function must accept two arguments (sock, buffer,) the client - socket and the left over buffer to be updated. - - @note: This Component must be used in conjunction with a Component that - exposes Read events on a "read" Channel. - """ - - def __init__(self, *args, **kwargs): - "initializes x; see x.__class__.__doc__ for signature" - - super(LP, self).__init__(*args, **kwargs) - - self.encoding = kwargs.get('encoding', 'utf-8') - - # Used for Servers - self.getBuffer = kwargs.get("getBuffer") - self.updateBuffer = kwargs.get("updateBuffer") - - self.splitter = kwargs.get("splitter", splitLines) - - self.buffer = b"" - - @handler("read") - def _on_read(self, *args): - if len(args) == 1: - # Client read - data, = args - lines, self.buffer = self.splitter(data, self.buffer) - for line in lines: - self.fire(Line(line.decode(self.encoding, "replace"))) - else: - # Server read - sock, data = args - lines, buffer = self.splitter(data, self.getBuffer(sock)) - self.updateBuffer(sock, buffer) - for line in lines: - self.fire(Line(sock, line.decode(self.encoding, "replace"))) diff -Nru circuits-2.1.0/circuits/net/protocols/websocket.py circuits-3.1.0+ds1/circuits/net/protocols/websocket.py --- circuits-2.1.0/circuits/net/protocols/websocket.py 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/net/protocols/websocket.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,211 +0,0 @@ -""" -.. codeauthor: mnl -""" - -import os -import random - -from circuits.six import string_types -from circuits.core.handlers import handler -from circuits.core.components import BaseComponent -from circuits.net.sockets import Write, Read, Close - - -class WebSocketCodec(BaseComponent): - """WebSocket Protocol - - Implements the Data Framing protocol for WebSocket. - - This component is used in conjunction with a parent component that - receives Read events on its channel. When created (after a successful - WebSocket setup handshake), the codec registers - a handler on the parent's channel that filters out these Read - events for a given socket (if used in a server) or all Read events - (if used in a client). The data is decoded and the contained payload - is emitted as Read events on the codec's channel. - - The data from Write events sent to the codec's channel - (with socket argument if used in a server) is - encoded according to the WebSocket Data Framing protocol. The - encoded data is then forwarded as Write events on the parents channel. - """ - - channel = "ws" - - def __init__(self, sock=None, *args, **kwargs): - """ - Creates a new codec. - - :param sock: the socket used in Read and Write events - (if used in a server, else None) - """ - super(WebSocketCodec, self).__init__(*args, **kwargs) - - self._sock = sock - self._buffer = bytearray() - self._pending_payload = bytearray() - self._pending_type = None - self._close_received = False - self._close_sent = False - - @handler("registered") - def _on_registered(self, component, parent): - if component == self: - @handler("read", priority=10, filter=True, channel=parent.channel) - def _on_read_raw(self, *args): - if self._sock is not None: - if args[0] != self._sock: - return - data = args[1] - else: - data = args[0] - self._buffer += data - messages = self._parse_messages() - for message in messages: - if self._sock is not None: - self.fire(Read(self._sock, message)) - else: - self.fire(Read(message)) - return True - - self.addHandler(_on_read_raw) - - @handler("disconnect", channel=parent.channel) - def _on_disconnect(self, *args): - if self._sock is not None: - if args[0] != self._sock: - return - self.unregister() - self.addHandler(_on_disconnect) - - def _parse_messages(self): - msgs = [] # one chunk of bytes may result in several messages - if self._close_received: - return msgs - while self._buffer: - # extract final flag, opcode and masking - final = True if self._buffer[0] & 0x80 != 0 else False - opcode = self._buffer[0] & 0xf - masking = True if self._buffer[1] & 0x80 != 0 else False - # evaluate payload length - payload_length = self._buffer[1] & 0x7f - offset = 2 - if payload_length >= 126: - payload_bytes = 2 if payload_length == 126 else 8 - payload_length = 0 - for _ in range(payload_bytes): - payload_length = payload_length * 256 \ - + self._buffer[offset] - offset += 1 - # retrieve optional masking key - if masking: - masking_key = self._buffer[offset:offset + 4] - offset += 4 - # if not enough bytes available yet, retry after next read - if len(self._buffer) - offset < payload_length: - break - # rest of _buffer is payload - msg = self._buffer[offset:offset + payload_length] - if masking: # unmask - msg = list(msg) - for i, c in enumerate(msg): - msg[i] = c ^ masking_key[i % 4] - msg = bytearray(msg) - # remove bytes of processed frame from byte _buffer - offset += payload_length - self._buffer = self._buffer[offset:] - # if there have been parts already, combine - msg = self._pending_payload + msg - if final: - if opcode < 8: - # if text or continuation of text, convert - if opcode == 1 \ - or opcode == 0 and self._pending_type == 1: - msg = msg.decode("utf-8", "replace") - msgs.append(msg) - # check for client closing the connection - elif opcode == 8: - self._close_received = True - if self._sock: - self.fire(Close(self._sock)) - else: - self.fire(Close()) - break - # check for Ping - elif opcode == 9: - if self._close_sent: - return - frame = bytearray(b'\x8a') - frame += self._encode_tail(msg, self._sock is None) - self._write(frame) - else: - self._pending_payload = msg - if opcode != 0: - self._pending_type = opcode - return msgs - - @handler("write") - def _on_write(self, *args): - if self._close_sent: - return - if self._sock is not None: - data = args[1] - else: - data = args[0] - frame = bytearray() - first = 0x80 # set FIN flag, we never fragment - if isinstance(data, string_types): - first += 1 # text - data = bytearray(data, "utf-8") - else: - first += 2 # binary - frame.append(first) - frame += self._encode_tail(data, self._sock is None) - self._write(frame) - - def _encode_tail(self, data, mask=False): - tail = bytearray() - data_length = len(data) - if data_length <= 125: - len_byte = data_length - lbytes = 0 - elif data_length <= 0xffff: - len_byte = 126 - lbytes = 2 - else: - len_byte = 127 - lbytes = 8 - if mask: - len_byte = len_byte | 0x80 - tail.append(len_byte) - for i in range(lbytes - 1, 0, -1): - tail.append(data_length >> (i * 8) & 0xff) - if mask: - try: - masking_key = bytearray([ord(x) for x in list(os.urandom(4))]) - except NotImplementedError: - masking_key \ - = bytearray([random.randint(0, 255) for i in range(4)]) - tail += masking_key - for i, c in enumerate(data): - tail.append(c ^ masking_key[i % 4]) - else: - tail += data - return tail - - def _write(self, data): - if self._sock is not None: - self.fire(Write(self._sock, data), self.parent.channel) - else: - self.fire(Write(data), self.parent.channel) - - @handler("close") - def _on_close(self, *args): - if not self._close_sent: - self._write(b"\x88\x00") - self._close_sent = True - if self._close_received and self._close_sent: - if self._sock: - self.fire(Close(self._sock), self.parent.channel) - else: - self.fire(Close(), self.parent.channel) diff -Nru circuits-2.1.0/circuits/net/sockets.py circuits-3.1.0+ds1/circuits/net/sockets.py --- circuits-2.1.0/circuits/net/sockets.py 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/net/sockets.py 2014-09-20 22:36:35.000000000 +0000 @@ -1,7 +1,6 @@ # Module: sockets # Date: 04th August 2004 # Author: James Mills -import select """Socket Components @@ -9,6 +8,7 @@ """ import os +import select from collections import defaultdict, deque from errno import EAGAIN, EALREADY, EBADF @@ -17,7 +17,8 @@ from _socket import socket as SocketType -from socket import gaierror, error +from socket import gaierror +from socket import error as SocketError from socket import getfqdn, gethostbyname, socket, getaddrinfo, gethostname from socket import AF_INET, AF_INET6, IPPROTO_TCP, SOCK_STREAM, SOCK_DGRAM @@ -25,8 +26,9 @@ try: from ssl import wrap_socket as ssl_socket - from ssl import CERT_NONE, PROTOCOL_SSLv23, SSLError, SSL_ERROR_WANT_READ, \ - SSL_ERROR_WANT_WRITE + from ssl import CERT_NONE, PROTOCOL_SSLv23 + from ssl import SSLError, SSL_ERROR_WANT_WRITE, SSL_ERROR_WANT_READ + HAS_SSL = 1 except ImportError: import warnings @@ -36,202 +38,14 @@ from circuits.six import binary_type from circuits.core.utils import findcmp +from circuits.core import handler, BaseComponent from circuits.core.pollers import BasePoller, Poller -from circuits.core import handler, Event, BaseComponent - -BUFSIZE = 4096 # 4KB Buffer -BACKLOG = 5000 # 5K Concurrent Connections - -### -### Event Objects -### - - -class Connect(Event): - """Connect Event - - This Event is sent when a new client connection has arrived on a server. - This event is also used for client's to initiate a new connection to - a remote host. - - .. note :: - - This event is used for both Client and Server Components. - - :param args: Client: (host, port) Server: (sock, host, port) - :type args: tuple - - :param kwargs: Client: (ssl) - :type kwargs: dict - """ - - def __init__(self, *args, **kwargs): - "x.__init__(...) initializes x; see x.__class__.__doc__ for signature" - - super(Connect, self).__init__(*args, **kwargs) - - -class Disconnect(Event): - """Disconnect Event - - This Event is sent when a client connection has closed on a server. - This event is also used for client's to disconnect from a remote host. - - @note: This event is used for both Client and Server Components. - - :param args: Client: () Server: (sock) - :type tuple: tuple - """ - - def __init__(self, *args): - "x.__init__(...) initializes x; see x.__class__.__doc__ for signature" - - super(Disconnect, self).__init__(*args) - - -class Connected(Event): - """Connected Event - - This Event is sent when a client has successfully connected. - - @note: This event is for Client Components. - - :param host: The hostname connected to. - :type str: str - - :param port: The port connected to - :type int: int - """ - - def __init__(self, host, port): - "x.__init__(...) initializes x; see x.__class__.__doc__ for signature" - - super(Connected, self).__init__(host, port) - - -class Disconnected(Event): - """Disconnected Event - - This Event is sent when a client has disconnected - - @note: This event is for Client Components. - """ - - def __init__(self): - "x.__init__(...) initializes x; see x.__class__.__doc__ for signature" - - super(Disconnected, self).__init__() - - -class Read(Event): - """Read Event - - This Event is sent when a client or server connection has read any data. - - @note: This event is used for both Client and Server Components. - - :param args: Client: (data) Server: (sock, data) - :type tuple: tuple - """ - - def __init__(self, *args): - "x.__init__(...) initializes x; see x.__class__.__doc__ for signature" - - super(Read, self).__init__(*args) - -class SocketError(Event): - """SocketError Event +from .events import close, closed, connect, connected, disconnect, disconnected, error, read, ready, write - This Event is sent when a client or server connection has an error. - @note: This event is used for both Client and Server Components. - - :param args: Client: (error) Server: (sock, error) - :type tuple: tuple - """ - - def __init__(self, *args): - "x.__init__(...) initializes x; see x.__class__.__doc__ for signature" - - super(SocketError, self).__init__(*args) - - -class Write(Event): - """Write Event - - This Event is used to notify a client, client connection or server that - we have data to be written. - - @note: This event is never sent, it is used to send data. - @note: This event is used for both Client and Server Components. - - :param args: Client: (data) Server: (sock, data) - :type tuple: tuple - """ - - def __init__(self, *args): - "x.__init__(...) initializes x; see x.__class__.__doc__ for signature" - - super(Write, self).__init__(*args) - - -class Close(Event): - """Close Event - - This Event is used to notify a client, client connection or server that - we want to close. - - @note: This event is never sent, it is used to close. - @note: This event is used for both Client and Server Components. - - :param args: Client: () Server: (sock) - :type tuple: tuple - """ - - def __init__(self, *args): - "x.__init__(...) initializes x; see x.__class__.__doc__ for signature" - - super(Close, self).__init__(*args) - - -class Ready(Event): - """Ready Event - - This Event is used to notify the rest of the system that the underlying - Client or Server Component is ready to begin processing connections or - incoming/outgoing data. (This is triggered as a direct result of having - the capability to support multiple client/server components with a single - poller component instance in a system). - - @note: This event is used for both Client and Server Components. - - :param component: The Client/Server Component that is ready. - :type tuple: Component (Client/Server) - - :param bind: The (host, port) the server has bound to. - :type tuple: (host, port) - """ - - def __init__(self, component, bind=None): - "x.__init__(...) initializes x; see x.__class__.__doc__ for signature" - - args = (component, bind) if bind is not None else (component,) - super(Ready, self).__init__(*args) - - -class Closed(Event): - """Closed Event - - This Event is sent when a server has closed its listening socket. - - @note: This event is for Server components. - """ - - def __init__(self): - "x.__init__(...) initializes x; see x.__class__.__doc__ for signature" - - super(Closed, self).__init__() +BUFSIZE = 4096 # 4KB Buffer +BACKLOG = 5000 # 5K Concurrent Connections class Client(BaseComponent): @@ -275,26 +89,26 @@ if self._poller is None: if isinstance(component, BasePoller): self._poller = component - self.fire(Ready(self)) + self.fire(ready(self)) else: if component is not self: return component = findcmp(self.root, BasePoller) if component is not None: self._poller = component - self.fire(Ready(self)) + self.fire(ready(self)) else: self._poller = Poller().register(self) - self.fire(Ready(self)) + self.fire(ready(self)) @handler("stopped", channel="*") def _on_stopped(self, component): - self.fire(Close()) + self.fire(close()) @handler("read_value_changed") def _on_read_value_changed(self, value): if isinstance(value, binary_type): - self.fire(Write(value)) + self.fire(write(value)) @handler("prepare_unregister", channel="*") def _on_prepare_unregister(self, event, c): @@ -314,10 +128,10 @@ try: self._sock.shutdown(2) self._sock.close() - except error: + except SocketError: pass - self.fire(Disconnected()) + self.fire(disconnected()) @handler("close") def close(self): @@ -334,14 +148,14 @@ data = self._sock.recv(self._bufsize) if data: - self.fire(Read(data)).notify = True + self.fire(read(data)).notify = True else: self.close() - except error as e: + except SocketError as e: if e.args[0] == EWOULDBLOCK: return else: - self.fire(SocketError(e)) + self.fire(error(e)) self._close() def _write(self, data): @@ -353,11 +167,11 @@ if nbytes < len(data): self._buffer.appendleft(data[nbytes:]) - except error as e: + except SocketError as e: if e.args[0] in (EPIPE, ENOTCONN): self._close() else: - self.fire(SocketError(e)) + self.fire(error(e)) @handler("write") def write(self, data): @@ -365,15 +179,15 @@ self._poller.addWriter(self, self._sock) self._buffer.append(data) - @handler("_disconnect", filter=True) + @handler("_disconnect", priority=1) def __on_disconnect(self, sock): self._close() - @handler("_read", filter=True) + @handler("_read", priority=1) def __on_read(self, sock): self._read() - @handler("_write", filter=True) + @handler("_write", priority=1) def __on_write(self, sock): if self._buffer: data = self._buffer.popleft() @@ -388,7 +202,7 @@ def _do_handshake_for_non_blocking(ssock): """ - This is how to do handshake for an ssl socket with underlying + This is how to do handshake for an ssl socket with underlying non-blocking socket (according to the Python doc). """ while True: @@ -405,6 +219,7 @@ class TCPClient(Client): + socket_family = AF_INET def _create_socket(self): @@ -429,7 +244,7 @@ try: r = self._sock.connect((host, port)) - except error as e: + except SocketError as e: if e.args[0] in (EBADF, EINVAL,): self._sock = self._create_socket() r = self._sock.connect_ex((host, port)) @@ -439,7 +254,9 @@ if r in (EISCONN, EWOULDBLOCK, EINPROGRESS, EALREADY): self._connected = True else: - raise + self.fire(error(e)) + self._close() + return self._connected = True @@ -452,10 +269,11 @@ ) _do_handshake_for_non_blocking(self._ssock) - self.fire(Connected(host, port)) + self.fire(connected(host, port)) class TCP6Client(TCPClient): + socket_family = AF_INET6 def parse_bind_parameter(self, bind_parameter): @@ -491,14 +309,14 @@ try: r = self._sock.connect_ex(path) - except error as e: + except SocketError as e: r = e.args[0] if r: if r in (EISCONN, EWOULDBLOCK, EINPROGRESS, EALREADY): self._connected = True else: - self.fire(SocketError(r)) + self.fire(error(r)) return self._connected = True @@ -512,7 +330,7 @@ ) _do_handshake_for_non_blocking(self._ssock) - self.fire(Connected(gethostname(), path)) + self.fire(connected(gethostname(), path)) class Server(BaseComponent): @@ -563,7 +381,7 @@ return sockname[0] else: return sockname - except error: + except SocketError: return None @property @@ -573,7 +391,7 @@ sockname = self._sock.getsockname() if isinstance(sockname, tuple): return sockname[1] - except error: + except SocketError: return None @handler("registered", "started", channel="*") @@ -582,7 +400,7 @@ if isinstance(component, BasePoller): self._poller = component self._poller.addReader(self, self._sock) - self.fire(Ready(self, (self.host, self.port))) + self.fire(ready(self, (self.host, self.port))) else: if component is not self: return @@ -590,26 +408,26 @@ if component is not None: self._poller = component self._poller.addReader(self, self._sock) - self.fire(Ready(self, (self.host, self.port))) + self.fire(ready(self, (self.host, self.port))) else: self._poller = Poller().register(self) self._poller.addReader(self, self._sock) - self.fire(Ready(self, (self.host, self.port))) + self.fire(ready(self, (self.host, self.port))) @handler("stopped", channel="*") def _on_stopped(self, component): - self.fire(Close()) + self.fire(close()) @handler("read_value_changed") def _on_read_value_changed(self, value): if isinstance(value.value, binary_type): sock = value.event.args[0] - self.fire(Write(sock, value.value)) + self.fire(write(sock, value.value)) def _close(self, sock): if sock is None: return - if not sock == self._sock and sock not in self._clients: + if sock != self._sock and sock not in self._clients: return self._poller.discard(sock) @@ -625,14 +443,14 @@ try: sock.shutdown(2) sock.close() - except error: + except SocketError: pass - self.fire(Disconnect(sock)) + self.fire(disconnect(sock)) @handler("close") def close(self, sock=None): - closed = sock is None + is_closed = sock is None if sock is None: socks = [self._sock] @@ -646,8 +464,8 @@ elif sock not in self._closeq: self._closeq.append(sock) - if closed: - self.fire(Closed()) + if is_closed: + self.fire(closed()) def _read(self, sock): if sock not in self._clients: @@ -656,14 +474,14 @@ try: data = sock.recv(self._bufsize) if data: - self.fire(Read(sock, data)).notify = True + self.fire(read(sock, data)).notify = True else: self.close(sock) - except error as e: + except SocketError as e: if e.args[0] == EWOULDBLOCK: return else: - self.fire(SocketError(sock, e)) + self.fire(error(sock, e)) self._close(sock) def _write(self, sock, data): @@ -674,9 +492,9 @@ nbytes = sock.send(data) if nbytes < len(data): self._buffers[sock].appendleft(data[nbytes:]) - except error as e: + except SocketError as e: if e.args[0] not in (EINTR, EWOULDBLOCK, ENOBUFS): - self.fire(SocketError(sock, e)) + self.fire(error(sock, e)) self._close(sock) else: self._buffers[sock].appendleft(data) @@ -691,7 +509,7 @@ try: newsock, host = self._sock.accept() if self.secure and HAS_SSL: - newsock = ssl_socket( + sslsock = ssl_socket( newsock, server_side=True, keyfile=self.keyfile, @@ -701,12 +519,17 @@ ssl_version=self.ssl_version, do_handshake_on_connect=False ) - _do_handshake_for_non_blocking(newsock) - - except SSLError as e: - raise - - except error as e: + try: + _do_handshake_for_non_blocking(sslsock) + newsock = sslsock + except SSLError as e: + self.fire(error(self._sock, e)) + newsock.shutdown(2) + newsock.close() + return + else: + newsock = sslsock + except SocketError as e: if e.args[0] in (EWOULDBLOCK, EAGAIN): return elif e.args[0] == EPERM: @@ -735,20 +558,20 @@ newsock.setblocking(False) self._poller.addReader(self, newsock) self._clients.append(newsock) - self.fire(Connect(newsock, *host)) + self.fire(connect(newsock, *host)) - @handler("_disconnect", filter=True) + @handler("_disconnect", priority=1) def _on_disconnect(self, sock): self._close(sock) - @handler("_read", filter=True) + @handler("_read", priority=1) def _on_read(self, sock): if sock == self._sock: self._accept() else: self._read(sock) - @handler("_write", filter=True) + @handler("_write", priority=1) def _on_write(self, sock): if self._buffers[sock]: data = self._buffers[sock].popleft() @@ -763,6 +586,7 @@ class TCPServer(Server): + socket_family = AF_INET def _create_socket(self): @@ -781,12 +605,12 @@ def parse_ipv4_parameter(bind_parameter): - if type(bind_parameter) is int: + if isinstance(bind_parameter, int): try: bind = (gethostbyname(gethostname()), bind_parameter) except gaierror: bind = ("0.0.0.0", bind_parameter) - elif type(bind_parameter) is str and ":" in bind_parameter: + elif isinstance(bind_parameter, str) and ":" in bind_parameter: host, port = bind_parameter.split(":") port = int(port) bind = (host, port) @@ -797,7 +621,7 @@ def parse_ipv6_parameter(bind_parameter): - if type(bind_parameter) is int: + if isinstance(bind_parameter, int): try: _, _, _, _, bind \ = getaddrinfo(getfqdn(), bind_parameter, AF_INET6)[0] @@ -810,6 +634,7 @@ class TCP6Server(TCPServer): + socket_family = AF_INET6 def parse_bind_parameter(self, bind_parameter): @@ -835,6 +660,7 @@ class UDPServer(Server): + socket_family = AF_INET def _create_socket(self): @@ -857,18 +683,18 @@ try: sock.shutdown(2) - except error: + except SocketError: pass try: sock.close() - except error: + except SocketError: pass - self.fire(Disconnect(sock)) + self.fire(disconnect(sock)) @handler("close", override=True) def close(self): - self.fire(Closed()) + self.fire(closed()) if self._buffers[self._sock] and self._sock not in self._closeq: self._closeq.append(self._sock) @@ -879,11 +705,11 @@ try: data, address = self._sock.recvfrom(self._bufsize) if data: - self.fire(Read(address, data)).notify = True - except error as e: + self.fire(read(address, data)).notify = True + except SocketError as e: if e.args[0] in (EWOULDBLOCK, EAGAIN): return - self.fire(SocketError(self._sock, e)) + self.fire(error(self._sock, e)) self._close(self._sock) def _write(self, address, data): @@ -891,11 +717,11 @@ bytes = self._sock.sendto(data, address) if bytes < len(data): self._buffers[self._sock].appendleft(data[bytes:]) - except error as e: + except SocketError as e: if e.args[0] in (EPIPE, ENOTCONN): self._close(self._sock) else: - self.fire(SocketError(self._sock, e)) + self.fire(error(self._sock, e)) @handler("write", override=True) def write(self, address, data): @@ -907,15 +733,15 @@ def broadcast(self, data, port): self.write(("", port), data) - @handler("_disconnect", filter=True, override=True) + @handler("_disconnect", priority=1, override=True) def _on_disconnect(self, sock): self._close(sock) - @handler("_read", filter=True, override=True) + @handler("_read", priority=1, override=True) def _on_read(self, sock): self._read() - @handler("_write", filter=True, override=True) + @handler("_write", priority=1, override=True) def _on_write(self, sock): if self._buffers[self._sock]: address, data = self._buffers[self._sock].popleft() diff -Nru circuits-2.1.0/circuits/node/client.py circuits-3.1.0+ds1/circuits/node/client.py --- circuits-2.1.0/circuits/node/client.py 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/node/client.py 2014-09-24 09:54:43.000000000 +0000 @@ -9,8 +9,9 @@ from weakref import WeakValueDictionary +from circuits.net.sockets import TCPClient from circuits import handler, BaseComponent -from circuits.net.sockets import Close, Connect, TCPClient, Write +from circuits.net.events import close, connect, write from .utils import dump_event, load_value @@ -25,32 +26,34 @@ channel = "node" - def __init__(self, host, port, channel=channel): - super(Client, self).__init__(channel=channel) + def __init__(self, host, port, channel=channel, **kwargs): + super(Client, self).__init__(channel=channel, **kwargs) self._host = host self._port = port self._nid = 0 self._buffer = b"" - self._values = WeakValueDictionary() + self._values = {} - TCPClient(channel=self.channel).register(self) - self.fire(Connect(self._host, self._port)) + TCPClient(channel=self.channel, **kwargs).register(self) - def process(self, packet): - v, id, errors = load_value(packet) + @handler("ready") + def _on_ready(self, component): + self.fire(connect(self._host, self._port)) + + def _process_packet(self, packet): + value, id, errors = load_value(packet) if id in self._values: - value = self._values[id] - value.value = v - value.errors = errors + self._values[id].value = value + self._values[id].errors = errors def close(self): - self.fire(Close()) + self.fire(close()) def connect(self, host, port): - self.fire(Connect(host, port)) + self.fire(connect(host, port)) def send(self, event, e): id = self._nid @@ -60,7 +63,12 @@ data = dump_event(e, id) packet = data.encode("utf-8") + DELIMITER - self.fire(Write(packet)) + self.fire(write(packet)) + + while not self._values[id].result: + yield + + del(self._values[id]) @handler("read") def _on_read(self, data): @@ -70,4 +78,4 @@ if delimiter > 0: packet = self._buffer[:delimiter].decode("utf-8") self._buffer = self._buffer[(delimiter + len(DELIMITER)):] - self.process(packet) + self._process_packet(packet) diff -Nru circuits-2.1.0/circuits/node/events.py circuits-3.1.0+ds1/circuits/node/events.py --- circuits-2.1.0/circuits/node/events.py 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/node/events.py 2014-09-04 10:32:30.000000000 +0000 @@ -10,15 +10,15 @@ from circuits import Event -class Packet(Event): - """Packet Event""" +class packet(Event): + """packet Event""" -class Remote(Event): - """Remote Event +class remote(Event): + """remote Event ... """ def __init__(self, event, node, channel=None): - super(Remote, self).__init__(event, node, channel=None) + super(remote, self).__init__(event, node, channel=None) diff -Nru circuits-2.1.0/circuits/node/__init__.py circuits-3.1.0+ds1/circuits/node/__init__.py --- circuits-2.1.0/circuits/node/__init__.py 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/node/__init__.py 2014-09-04 10:32:30.000000000 +0000 @@ -8,6 +8,6 @@ """ from .node import Node -from .events import Remote +from .events import remote # flake8: noqa diff -Nru circuits-2.1.0/circuits/node/node.py circuits-3.1.0+ds1/circuits/node/node.py --- circuits-2.1.0/circuits/node/node.py 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/node/node.py 2014-09-24 09:54:43.000000000 +0000 @@ -7,8 +7,6 @@ ... """ -from hashlib import sha256 - from .client import Client from .server import Server @@ -23,28 +21,41 @@ channel = "node" - def __init__(self, bind=None, channel=channel): - super(Node, self).__init__(channel=channel) - - self._bind = bind - - self._nodes = {} + def __init__(self, bind=None, channel=channel, **kwargs): + super(Node, self).__init__(channel=channel, **kwargs) - if self._bind is not None: - Server(self._bind).register(self) - - def add(self, name, host, port): - channel = sha256( - "{0:s}:{1:d}".format(host, port).encode("utf-8") - ).hexdigest() - node = Client(host, port, channel=channel) + self.bind = bind + self.nodes = {} + self.__client_event_firewall = kwargs.get( + 'client_event_firewall', + None + ) + + if self.bind is not None: + self.server = Server( + self.bind, + channel=channel, + **kwargs + ).register(self) + else: + self.server = None + + def add(self, name, host, port, **kwargs): + channel = kwargs['channel'] if 'channel' in kwargs else \ + '%s_client_%s' % (self.channel, name) + node = Client(host, port, channel=channel, **kwargs) node.register(self) - self._nodes[name] = node + self.nodes[name] = node + return channel @handler("remote") - def _on_remote(self, event, e, name, channel=None): - node = self._nodes[name] + def _on_remote(self, event, e, client_name, channel=None): + if self.__client_event_firewall and \ + not self.__client_event_firewall(event, client_name, channel): + return + + node = self.nodes[client_name] if channel is not None: e.channels = (channel,) return node.send(event, e) diff -Nru circuits-2.1.0/circuits/node/server.py circuits-3.1.0+ds1/circuits/node/server.py --- circuits-2.1.0/circuits/node/server.py 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/node/server.py 2014-09-24 09:54:43.000000000 +0000 @@ -7,8 +7,11 @@ ... """ -from circuits import handler, BaseComponent -from circuits.net.sockets import TCPServer, Write +from circuits.core import Value + +from circuits.net.events import write +from circuits.net.sockets import TCPServer +from circuits import handler, BaseComponent, Event from .utils import load_event, dump_value @@ -23,34 +26,37 @@ channel = "node" - def __init__(self, bind, channel=channel): - super(Server, self).__init__(channel=channel) + def __init__(self, bind, channel=channel, **kwargs): + super(Server, self).__init__(channel=channel, **kwargs) self._buffers = {} - - TCPServer(bind, channel=self.channel).register(self) - - def process(self, sock, packet): - e, id = load_event(packet) - - name = "%s_value_changed" % e.name - channel = e.channels[0] if e.channels else self - - @handler(name, channel=self) - def on_value_changed(self, event, value): - self.send(value) - - self.addHandler(on_value_changed) - - v = self.fire(e, *e.channels) - v.notify = True - v.node_trn = id - v.node_sock = sock + self.__server_event_firewall = kwargs.get( + 'server_event_firewall', + None + ) + + self.transport = TCPServer(bind, channel=self.channel, **kwargs).register(self) + + @handler('_process_packet') + def _process_packet(self, sock, packet): + event, id = load_event(packet) + + if self.__server_event_firewall and \ + not self.__server_event_firewall(event, sock): + value = Value(event, self) + + else: + value = yield self.call(event, *event.channels) + + value.notify = True + value.node_trn = id + value.node_sock = sock + self.send(value) def send(self, v): data = dump_value(v) packet = data.encode("utf-8") + DELIMITER - self.fire(Write(v.node_sock, packet)) + self.fire(write(v.node_sock, packet)) @handler("read") def _on_read(self, sock, data): @@ -62,4 +68,14 @@ if delimiter > 0: packet = buffer[:delimiter].decode("utf-8") self._buffers[sock] = buffer[(delimiter + len(DELIMITER)):] - self.process(sock, packet) + self.fire(Event.create('_process_packet', sock, packet)) + + @property + def host(self): + if hasattr(self, "transport"): + return self.transport.host + + @property + def port(self): + if hasattr(self, "transport"): + return self.transport.port diff -Nru circuits-2.1.0/circuits/node/utils.py circuits-3.1.0+ds1/circuits/node/utils.py --- circuits-2.1.0/circuits/node/utils.py 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/node/utils.py 2014-09-04 10:32:30.000000000 +0000 @@ -11,13 +11,13 @@ import json from circuits.core import Event -from circuits.six import text_type +from circuits.six import bytes_to_str, text_type def load_event(s): data = json.loads(s) - name = "".join(x.title() for x in str(data["name"]).split("_")) + name = bytes_to_str(data["name"].encode("utf-8")) args = [] for arg in data["args"]: diff -Nru circuits-2.1.0/circuits/protocols/http.py circuits-3.1.0+ds1/circuits/protocols/http.py --- circuits-2.1.0/circuits/protocols/http.py 1970-01-01 00:00:00.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/protocols/http.py 2014-09-04 10:32:30.000000000 +0000 @@ -0,0 +1,71 @@ + +from io import BytesIO + +from circuits.core import handler, BaseComponent, Event + + +class request(Event): + """request Event""" + + +class response(Event): + """response Event""" + + +class ResponseObject(object): + + def __init__(self, headers, status, version): + self.headers = headers + self.status = status + self.version = version + + self.body = BytesIO() + + # XXX: This sucks :/ Avoiding the circuit import here :/ + from circuits.web.constants import HTTP_STATUS_CODES + self.reason = HTTP_STATUS_CODES[self.status] + + def __repr__(self): + return "".format( + self.status, + self.reason, + self.headers.get("Content-Type"), + len(self.body.getvalue()) + ) + + def read(self): + return self.body.read() + + +class HTTP(BaseComponent): + + channel = "web" + + def __init__(self, encoding="utf-8", channel=channel): + super(HTTP, self).__init__(channel=channel) + + self._encoding = encoding + + # XXX: This sucks :/ Avoiding the circuit import here :/ + from circuits.web.parsers import HttpParser + self._parser = HttpParser(1, True) + + @handler("read") + def _on_client_read(self, data): + self._parser.execute(data, len(data)) + if self._parser.is_message_complete() or \ + self._parser.is_upgrade() or \ + (self._parser.is_headers_complete() and + self._parser._clen == 0): + status = self._parser.get_status_code() + version = self._parser.get_version() + headers = self._parser.get_headers() + + res = ResponseObject(headers, status, version) + res.body.write(self._parser.recv_body()) + res.body.seek(0) + self.fire(response(res)) + + # XXX: This sucks :/ Avoiding the circuit import here :/ + from circuits.web.parsers import HttpParser + self._parser = HttpParser(1, True) diff -Nru circuits-2.1.0/circuits/protocols/__init__.py circuits-3.1.0+ds1/circuits/protocols/__init__.py --- circuits-2.1.0/circuits/protocols/__init__.py 1970-01-01 00:00:00.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/protocols/__init__.py 2014-09-04 10:32:30.000000000 +0000 @@ -0,0 +1,13 @@ +# Package: protocols +# Date: 13th March 2009 +# Author: James Mills, prologic at shortcircuit dot net dot au + + +"""Networking Protocols + +This package contains components that implement various networking protocols. +""" + + +from .irc import IRC # noqa +from .line import Line # noqa diff -Nru circuits-2.1.0/circuits/protocols/irc/commands.py circuits-3.1.0+ds1/circuits/protocols/irc/commands.py --- circuits-2.1.0/circuits/protocols/irc/commands.py 1970-01-01 00:00:00.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/protocols/irc/commands.py 2014-09-04 10:32:30.000000000 +0000 @@ -0,0 +1,78 @@ +# Module: commands +# Date: 11th August 2014 +# Author: James Mills + + +"""Internet Relay Chat Protocol commands""" + + +from .events import request +from .message import Message + + +def AWAY(message=None): + return request(Message("AWAY", message)) + + +def NICK(nickname, hopcount=None): + return request(Message("NICK", nickname, hopcount)) + + +def USER(user, host, server, name): + return request(Message("USER", user, host, server, name)) + + +def PASS(password): + return request(Message("PASS", password)) + + +def PONG(daemon1, daemon2=None): + return request(Message("PONG", daemon1, daemon2)) + + +def QUIT(message=None): + return request(Message("QUIT", message)) + + +def JOIN(channels, keys=None): + return request(Message("JOIN", channels, keys)) + + +def PART(channels): + return request(Message("PART", channels)) + + +def PRIVMSG(receivers, message): + return request(Message("PRIVMSG", receivers, message)) + + +def NOTICE(receivers, message): + return request(Message("NOTICE", receivers, message)) + + +def KICK(channel, user, comment=None): + return request(Message("KICK", channel, user, comment)) + + +def TOPIC(channel, topic=None): + return request(Message("TOPIC", channel, topic)) + + +def MODE(target, *args): + return request(Message("MODE", target, *args)) + + +def INVITE(nickname, channel): + return request(Message("INVITE", nickname, channel)) + + +def NAMES(channels=None): + return request(Message("NAMES", channels)) + + +def WHOIS(nickmasks, server=None): + return request(Message(server, nickmasks)) + + +def WHO(name=None, o=None): + return request(Message("WHO", name, o)) diff -Nru circuits-2.1.0/circuits/protocols/irc/events.py circuits-3.1.0+ds1/circuits/protocols/irc/events.py --- circuits-2.1.0/circuits/protocols/irc/events.py 1970-01-01 00:00:00.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/protocols/irc/events.py 2014-09-04 10:32:30.000000000 +0000 @@ -0,0 +1,21 @@ +# Module: events +# Date: 11th August 2014 +# Author: James Mills + + +"""Internet Relay Chat Protocol events""" + + +from circuits import Event + + +class response(Event): + """response Event (Server and Client)""" + + +class reply(Event): + """reply Event (Server)""" + + +class request(Event): + """request Event (Client)""" diff -Nru circuits-2.1.0/circuits/protocols/irc/__init__.py circuits-3.1.0+ds1/circuits/protocols/irc/__init__.py --- circuits-2.1.0/circuits/protocols/irc/__init__.py 1970-01-01 00:00:00.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/protocols/irc/__init__.py 2014-09-04 10:32:30.000000000 +0000 @@ -0,0 +1,26 @@ +# Package: irc +# Date: 04th August 2004 +# Author: James Mills + + +"""Internet Relay Chat Protocol + +This package implements the Internet Relay Chat Protocol +or commonly known as IRC. Support for both server and client +is implemented. +""" + + +from .commands import * +from .numerics import * +from .protocol import IRC +from .message import Message +from .events import response, reply +from .utils import joinprefix, parsemsg, parseprefix, strip + + +sourceJoin = joinprefix +sourceSplit = parseprefix + + +# pylama:skip=1 diff -Nru circuits-2.1.0/circuits/protocols/irc/message.py circuits-3.1.0+ds1/circuits/protocols/irc/message.py --- circuits-2.1.0/circuits/protocols/irc/message.py 1970-01-01 00:00:00.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/protocols/irc/message.py 2014-09-04 10:32:30.000000000 +0000 @@ -0,0 +1,68 @@ +# Module: message +# Date: 11th August 2014 +# Author: James Mills + + +"""Internet Relay Chat message""" + + +from .utils import parsemsg + + +class Error(Exception): + """Error Exception""" + + +class Message(object): + + def __init__(self, command, *args, **kwargs): + for arg in args[:-1]: + if " " in arg: + raise Error("Space can only appear in the very last arg") + + self.command = command + self.args = list(filter(lambda x: x is not None, list(args))) + self.prefix = str(kwargs["prefix"]) if "prefix" in kwargs else None + + self.encoding = kwargs.get("encoding", "utf-8") + self.add_nick = kwargs.get("add_nick", False) + + @staticmethod + def from_string(s): + if len(s) > 512: + raise Error("Message must not be longer than 512 characters") + + prefix, command, args = parsemsg(s) + + return Message(command, *args, prefix=prefix) + + def __bytes__(self): + return str(self).encode(self.encoding) + + def __str__(self): + args = self.args[:] + for arg in args[:-1]: + if arg is not None and " " in arg: + raise Error("Space can only appear in the very last arg") + + if len(args) > 0 and " " in args[-1]: + args[-1] = ":{0:s}".format(args[-1]) + + return "{prefix:s}{command:s} {args:s}\r\n".format( + prefix=( + ":{0:s} ".format(self.prefix) + if self.prefix is not None + else "" + ), + command=str(self.command), + args=" ".join(args) + ) + + def __repr__(self): + return "\"{0:s}\"".format(str(self)[:-2]) + + def __eq__(self, other): + return isinstance(other, Message) \ + and self.prefix == other.prefix \ + and self.command == other.command \ + and self.args == other.args diff -Nru circuits-2.1.0/circuits/protocols/irc/numerics.py circuits-3.1.0+ds1/circuits/protocols/irc/numerics.py --- circuits-2.1.0/circuits/protocols/irc/numerics.py 1970-01-01 00:00:00.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/protocols/irc/numerics.py 2014-09-04 10:32:30.000000000 +0000 @@ -0,0 +1,129 @@ +# Module: numerics +# Date: 11 August 2014 +# Author: James Mills + + +"""Internet Relay Chat Protocol numerics""" + + +RPL_WELCOME = 1 +RPL_YOURHOST = 2 + +RPL_TRACELINK = 200 +RPL_TRACECONNECTING = 201 +RPL_TRACEHANDSHAKE = 202 +RPL_TRACEUNKNOWN = 203 +RPL_TRACEOPERATOR = 204 +RPL_TRACEUSER = 205 +RPL_TRACESERVER = 206 +RPL_TRACENEWTYPE = 208 +RPL_TRACELOG = 261 +RPL_STATSLINKINFO = 211 +RPL_STATSCOMMANDS = 212 +RPL_STATSCLINE = 213 +RPL_STATSNLINE = 214 +RPL_STATSILINE = 215 +RPL_STATSKLINE = 216 +RPL_STATSYLINE = 218 +RPL_ENDOFSTATS = 219 +RPL_STATSLLINE = 241 +RPL_STATSUPTIME = 242 +RPL_STATSOLINE = 243 +RPL_STATSHLINE = 244 +RPL_UMODEIS = 221 +RPL_LUSERCLIENT = 251 +RPL_LUSEROP = 252 +RPL_LUSERUNKNOWN = 253 +RPL_LUSERCHANNELS = 254 +RPL_LUSERME = 255 +RPL_ADMINME = 256 +RPL_ADMINLOC1 = 257 +RPL_ADMINLOC2 = 258 +RPL_ADMINEMAIL = 259 + +RPL_NONE = 300 +RPL_USERHOST = 302 +RPL_ISON = 303 +RPL_AWAY = 301 +RPL_UNAWAY = 305 +RPL_NOWAWAY = 306 +RPL_WHOISUSER = 311 +RPL_WHOISSERVER = 312 +RPL_WHOISOPERATOR = 313 +RPL_WHOISIDLE = 317 +RPL_ENDOFWHOIS = 318 +RPL_WHOISCHANNELS = 319 +RPL_WHOWASUSER = 314 +RPL_ENDOFWHOWAS = 369 +RPL_LIST = 322 +RPL_LISTEND = 323 +RPL_CHANNELMODEIS = 324 +RPL_NOTOPIC = 331 +RPL_TOPIC = 332 +RPL_INVITING = 341 +RPL_SUMMONING = 342 +RPL_VERSION = 351 +RPL_WHOREPLY = 352 +RPL_ENDOFWHO = 315 +RPL_NAMEREPLY = 353 +RPL_ENDOFNAMES = 366 +RPL_LINKS = 364 +RPL_ENDOFLINKS = 365 +RPL_BANLIST = 367 +RPL_ENDOFBANLIST = 368 +RPL_INFO = 371 +RPL_ENDOFINFO = 374 +RPL_MOTDSTART = 375 +RPL_MOTD = 372 +RPL_ENDOFMOTD = 376 +RPL_YOUREOPER = 381 +RPL_REHASHING = 382 +RPL_TIME = 391 +RPL_USERSSTART = 392 +RPL_USERS = 393 +RPL_ENDOFUSERS = 394 +RPL_NOUSERS = 395 + +ERR_NOSUCHNICK = 401 +ERR_NOSUCHSERVER = 402 +ERR_NOSUCHCHANNEL = 403 +ERR_CANNOTSENDTOCHAN = 404 +ERR_TOOMANYCHANNELS = 405 +ERR_WASNOSUCHNICK = 406 +ERR_TOOMANYTARGETS = 407 +ERR_NOORIGIN = 409 +ERR_NORECIPIENT = 411 +ERR_NOTEXTTOSEND = 412 +ERR_NOTOPLEVEL = 413 +ERR_WILDTOPLEVEL = 414 +ERR_UNKNOWNCOMMAND = 421 +ERR_NOMOTD = 422 +ERR_NOADMININFO = 423 +ERR_FILEERROR = 424 +ERR_NONICKNAMEGIVEN = 431 +ERR_ERRONEUSNICKNAME = 432 +ERR_NICKNAMEINUSE = 433 +ERR_NICKCOLLISION = 436 +ERR_NOTONCHANNEL = 442 +ERR_USERONCHANNEL = 443 +ERR_NOLOGIN = 444 +ERR_SUMMONDISABLED = 445 +ERR_USERSDISABLED = 446 +ERR_NOTREGISTERED = 451 +ERR_NEEDMOREPARAMS = 461 +ERR_ALREADYREGISTRED = 462 +ERR_PASSWDMISMATCH = 464 +ERR_YOUREBANNEDCREEP = 465 +ERR_KEYSET = 467 +ERR_CHANNELISFULL = 471 +ERR_UNKNOWNMODE = 472 +ERR_INVITEONLYCHAN = 473 +ERR_BANNEDFROMCHAN = 474 +ERR_BADCHANNELKEY = 475 +ERR_NOPRIVILEGES = 481 +ERR_CHANOPRIVSNEEDED = 482 +ERR_CANTKILLSERVER = 483 +ERR_NOOPERHOST = 491 + +ERR_UMODEUNKNOWNFLAG = 501 +ERR_USERSDONTMATCH = 502 diff -Nru circuits-2.1.0/circuits/protocols/irc/protocol.py circuits-3.1.0+ds1/circuits/protocols/irc/protocol.py --- circuits-2.1.0/circuits/protocols/irc/protocol.py 1970-01-01 00:00:00.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/protocols/irc/protocol.py 2014-09-04 10:32:30.000000000 +0000 @@ -0,0 +1,105 @@ +# Module: protocol +# Date: 11th August 2014 +# Author: James Mills + + +"""Internet Relay Chat Protocol""" + + +from re import compile as compile_regex + + +from circuits import Component + +from circuits.net.events import write +from circuits.protocols.line import Line + + +from .commands import PONG +from .utils import parsemsg +from .message import Message +from .events import reply, response + + +NUMERIC = compile_regex("[0-9]+") + + +class IRC(Component): + """IRC Protocol Component + + Creates a new IRC Component instance that implements the IRC Protocol. + Incoming messages are handled by the "read" Event Handler, parsed and + processed with appropriate Events created and exposed to the rest of + the system to listen to and handle. + """ + + def __init__(self, *args, **kwargs): + super(IRC, self).__init__(*args, **kwargs) + + self.encoding = kwargs.get("encoding", "utf-8") + + Line(**kwargs).register(self) + + def line(self, *args): + """line Event Handler + + Process a line of text and generate the appropriate + event. This must not be overridden by subclasses, + if it is, this must be explicitly called by the + subclass. Other Components may however listen to + this event and process custom IRC events. + """ + + if len(args) == 1: + # Client read + sock, line = None, args[0] + else: + # Server read + sock, line = args + + prefix, command, args = parsemsg(line, encoding=self.encoding) + + command = command.lower() + + if NUMERIC.match(command): + args.insert(0, int(command)) + command = "numeric" + + if sock is not None: + self.fire(response.create(command, sock, prefix, *args)) + else: + self.fire(response.create(command, prefix, *args)) + + def request(self, event, message): + """request Event Handler (Default) + + This is a default event handler to respond to ``request`` events + by converting the given message to bytes and firing a ``write`` + event to a hopefully connected client socket. + Components may override this, but be sure to respond to + ``request`` events by either explicitly calling this method + or sending your own ``write`` events as the client socket. + """ + + event.stop() + message.encoding = self.encoding + self.fire(write(bytes(message))) + + def ping(self, event, *args): + """ping Event Handler (Default) + + This is a default event to respond to ``ping`` events + by sending a ``PONG`` in response. Subclasses or + components may override this, but be sure to respond to + ``ping`` events by either explicitly calling this method + or sending your own ``PONG`` response. + """ + + if len(args) == 2: + # Client read + self.fire(PONG(args[1])) + else: + # Server read + self.fire(reply(args[0], Message("PONG", args[2]))) + + event.stop() diff -Nru circuits-2.1.0/circuits/protocols/irc/replies.py circuits-3.1.0+ds1/circuits/protocols/irc/replies.py --- circuits-2.1.0/circuits/protocols/irc/replies.py 1970-01-01 00:00:00.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/protocols/irc/replies.py 2014-09-04 10:32:30.000000000 +0000 @@ -0,0 +1,79 @@ +# Module: replies +# Date: 11th August 2014 +# Author: James Mills + + +"""Internet Relay Chat Protocol replies""" + + +from operator import attrgetter + + +from .message import Message + + +def _M(*args, **kwargs): + kwargs["add_nick"] = True + return Message(*args, **kwargs) + + +def RPL_WELCOME(network): + return _M("001", "Welcome to the {0:s} IRC Network".format(network)) + + +def RPL_YOURHOST(host, version): + return _M("002", "Your host is {0:s} running {1:s}".format(host, version)) + + +def ERR_NOMOTD(): + return _M("422", "MOTD file is missing") + + +def ERR_NOSUCHNICK(nick): + return _M("401", nick, "No such nick") + + +def ERR_NOSUCHCHANNEL(channel): + return _M("403", channel, "No such channel") + + +def RPL_WHOREPLY(user, mask, server): + # H = Here + # G = Away + # * = IRCOp + # @ = Channel Op + # + = Voiced + + return _M( + "352", mask, + user.userinfo.user, user.userinfo.host, + server, user.nick, + "G" if user.away else "H", + "0 " + user.userinfo.name + ) + + +def RPL_ENDOFWHO(mask): + return _M("315", mask, "End of WHO list") + + +def RPL_NOTOPIC(channel): + return _M("331", channel, "No topic is set") + + +def RPL_NAMEREPLY(channel): + prefix = "=" + nicks = " ".join(map(attrgetter("nick"), channel.users)) + return _M("353", prefix, channel.name, nicks) + + +def RPL_ENDOFNAMES(): + return _M("366", "End of NAMES list") + + +def ERR_UNKNOWNCOMMAND(command): + return _M("421", command, "Unknown command") + + +def ERR_NICKNAMEINUSE(nick): + return _M("433", nick, "Nickname is already in use") diff -Nru circuits-2.1.0/circuits/protocols/irc/utils.py circuits-3.1.0+ds1/circuits/protocols/irc/utils.py --- circuits-2.1.0/circuits/protocols/irc/utils.py 1970-01-01 00:00:00.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/protocols/irc/utils.py 2014-10-31 09:22:22.000000000 +0000 @@ -0,0 +1,98 @@ +# Module: utils +# Date: 11th August 2014 +# Author: James Mills + + +"""Internet Relay Chat Utilities""" + + +from re import compile as compile_regex + + +PREFIX = compile_regex("([^!].*)!(.*)@(.*)") + + +class Error(Exception): + """Error Exception""" + + +def strip(s, color=False): + """strip(s, color=False) -> str + + Strips the : from the start of a string + and optionally also strips all colors if + color is True. + + :param s str: string to process + :param color bool: whether to strip colors + + :returns str: returns processes string + """ + + if len(s) > 0: + if s[0] == ":": + s = s[1:] + if color: + s = s.replace("\x01", "") + s = s.replace("\x02", "") + return s + + +def joinprefix(nick, user, host): + """Join the parts of a prefix + + :param nick str: nickname + :param user str: username + :param host str: hostname + + :returns str: a string in the form of !@ + """ + + return "{0:s}!{1:s}@{2:s}".format(nick or "", user or "", host or "") + + +def parseprefix(prefix): + """Parse a prefix into it's parts + + :param prefix str: prefix to parse + + :returns tuple: tuple of strings in the form of (nick, user, host) + """ + + m = PREFIX.match(prefix) + + if m is not None: + return m.groups() + else: + return prefix, None, None + + +def parsemsg(s, encoding="utf-8"): + """Parse an IRC Message from s + + :param s bytes: bytes to parse + :param encoding str: encoding to use (Default: utf-8) + + :returns tuple: parsed message in the form of (prefix, command, args) + """ + + s = s.decode(encoding) + + prefix = "" + trailing = [] + + if s[0] == ":": + prefix, s = s[1:].split(" ", 1) + + prefix = parseprefix(prefix) + + if s.find(" :") != -1: + s, trailing = s.split(" :", 1) + args = s.split() + args.append(trailing) + else: + args = s.split() + + command = str(args.pop(0)) + + return prefix, command, args diff -Nru circuits-2.1.0/circuits/protocols/line.py circuits-3.1.0+ds1/circuits/protocols/line.py --- circuits-2.1.0/circuits/protocols/line.py 1970-01-01 00:00:00.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/protocols/line.py 2014-09-04 10:32:30.000000000 +0000 @@ -0,0 +1,113 @@ +# Module: line +# Date: 04th February 2010 +# Author: James Mills + +"""Line Protocol + +This module implements the basic Line protocol. + +This module can be used in both server and client implementations. +""" + +import re + +from circuits.core import handler, Event, BaseComponent + +from circuits.six import b + + +LINESEP = re.compile(b("\r?\n")) + + +def splitLines(s, buffer): + """splitLines(s, buffer) -> lines, buffer + + Append s to buffer and find any new lines of text in the + string splitting at the standard IRC delimiter CRLF. Any + new lines found, return them as a list and the remaining + buffer for further processing. + """ + + lines = LINESEP.split(buffer + s) + return lines[:-1], lines[-1] + + +class line(Event): + """line Event""" + + +class Line(BaseComponent): + """Line Protocol + + Implements the Line Protocol. + + Incoming data is split into lines with a splitter function. For each + line of data processed a Line Event is created. Any unfinished lines + are appended into an internal buffer. + + A custom line splitter function can be passed to customize how data + is split into lines. This function must accept two arguments, the data + to process and any left over data from a previous invocation of the + splitter function. The function must also return a tuple of two items, + a list of lines and any left over data. + + :param splitter: a line splitter function + :type splitter: function + + This Component operates in two modes. In normal operation it's expected + to be used in conjunction with components that expose a Read Event on + a "read" channel with only one argument (data). Some builtin components + that expose such events are: + - circuits.net.sockets.TCPClient + - circuits.io.File + + The second mode of operation works with circuits.net.sockets.Server + components such as TCPServer, UNIXServer, etc. It's expected that + two arguments exist in the Read Event, sock and data. The following + two arguments can be passed to affect how unfinished data is stored + and retrieved for such components: + + :param getBuffer: function to retrieve the buffer for a client sock + :type getBuffer: function + + This function must accept one argument (sock,) the client socket + whoose buffer is to be retrieved. + + :param updateBuffer: function to update the buffer for a client sock + :type updateBuffer: function + + This function must accept two arguments (sock, buffer,) the client + socket and the left over buffer to be updated. + + @note: This Component must be used in conjunction with a Component that + exposes Read events on a "read" Channel. + """ + + def __init__(self, *args, **kwargs): + "initializes x; see x.__class__.__doc__ for signature" + + super(Line, self).__init__(*args, **kwargs) + + self.encoding = kwargs.get('encoding', 'utf-8') + + # Used for Servers + self.getBuffer = kwargs.get("getBuffer") + self.updateBuffer = kwargs.get("updateBuffer") + + self.splitter = kwargs.get("splitter", splitLines) + + self.buffer = b"" + + @handler("read") + def _on_read(self, *args): + if len(args) == 1: + # Client read + data, = args + lines, self.buffer = self.splitter(data, self.buffer) + [self.fire(line(x)) for x in lines] + else: + # Server read + sock, data = args + lines, buffer = self.splitter(data, self.getBuffer(sock)) + self.updateBuffer(sock, buffer) + [self.fire(line(sock, x)) for x in lines] diff -Nru circuits-2.1.0/circuits/protocols/websocket.py circuits-3.1.0+ds1/circuits/protocols/websocket.py --- circuits-2.1.0/circuits/protocols/websocket.py 1970-01-01 00:00:00.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/protocols/websocket.py 2014-09-04 10:32:30.000000000 +0000 @@ -0,0 +1,227 @@ +""" + +.. codeauthor: mnl +""" + +import os +import random + +from circuits.six import string_types +from circuits.core.handlers import handler +from circuits.core.components import BaseComponent +from circuits.net.events import write, read, close + + +class WebSocketCodec(BaseComponent): + """WebSocket Protocol + + Implements the Data Framing protocol for WebSocket. + + This component is used in conjunction with a parent component that + receives Read events on its channel. When created (after a successful + WebSocket setup handshake), the codec registers + a handler on the parent's channel that filters out these Read + events for a given socket (if used in a server) or all Read events + (if used in a client). The data is decoded and the contained payload + is emitted as Read events on the codec's channel. + + The data from write events sent to the codec's channel + (with socket argument if used in a server) is + encoded according to the WebSocket Data Framing protocol. The + encoded data is then forwarded as write events on the parents channel. + """ + + channel = "ws" + + def __init__(self, sock=None, data=bytearray(), *args, **kwargs): + """ + Creates a new codec. + + :param sock: the socket used in Read and write events + (if used in a server, else None) + """ + super(WebSocketCodec, self).__init__(*args, **kwargs) + + self._sock = sock + + self._pending_payload = bytearray() + self._pending_type = None + self._close_received = False + self._close_sent = False + + messages = self._parse_messages(bytearray(data)) + for message in messages: + if self._sock is not None: + self.fire(read(self._sock, message)) + else: + self.fire(read(message)) + + @handler("registered") + def _on_registered(self, component, parent): + if component == self: + @handler("read", priority=10, channel=parent.channel) + def _on_read_raw(self, event, *args): + if self._sock is not None: + if args[0] != self._sock: + return + data = args[1] + else: + data = args[0] + messages = self._parse_messages(bytearray(data)) + for message in messages: + if self._sock is not None: + self.fire(read(self._sock, message)) + else: + self.fire(read(message)) + event.stop() + + self.addHandler(_on_read_raw) + + @handler("disconnect", channel=parent.channel) + def _on_disconnect(self, *args): + if self._sock is not None: + if args[0] != self._sock: + return + self.unregister() + self.addHandler(_on_disconnect) + + def _parse_messages(self, data): + msgs = [] # one chunk of bytes may result in several messages + if self._close_received: + return msgs + while data: + # extract final flag, opcode and masking + final = bool(data[0] & 0x80 != 0) + opcode = data[0] & 0xf + masking = bool(data[1] & 0x80 != 0) + # evaluate payload length + payload_length = data[1] & 0x7f + offset = 2 + if payload_length >= 126: + payload_bytes = 2 if payload_length == 126 else 8 + payload_length = 0 + for _ in range(payload_bytes): + payload_length = payload_length * 256 \ + + data[offset] + offset += 1 + # retrieve optional masking key + if masking: + masking_key = data[offset:offset + 4] + offset += 4 + # if not enough bytes available yet, retry after next read + if len(data) - offset < payload_length: + break + # rest of _buffer is payload + msg = data[offset:offset + payload_length] + if masking: # unmask + msg = list(msg) + for i, c in enumerate(msg): + msg[i] = c ^ masking_key[i % 4] + msg = bytearray(msg) + # remove bytes of processed frame from byte _buffer + offset += payload_length + data = data[offset:] + # if there have been parts already, combine + msg = self._pending_payload + msg + if final: + if opcode < 8: + # if text or continuation of text, convert + if opcode == 1 \ + or opcode == 0 and self._pending_type == 1: + msg = msg.decode("utf-8", "replace") + self._pending_type = None + self._pending_payload = bytearray() + msgs.append(msg) + # check for client closing the connection + elif opcode == 8: + self._close_received = True + if self._sock: + self.fire(close(self._sock)) + else: + self.fire(close()) + break + # check for Ping + elif opcode == 9: + if self._close_sent: + return + frame = bytearray(b'\x8a') + frame += self._encode_tail(msg, self._sock is None) + self._write(frame) + else: + self._pending_payload = msg + if opcode != 0: + self._pending_type = opcode + return msgs + + @handler("write") + def _on_write(self, *args): + if self._close_sent: + return + + if self._sock is not None: + if args[0] != self._sock: + return + data = args[1] + else: + data = args[0] + + frame = bytearray() + first = 0x80 # set FIN flag, we never fragment + if isinstance(data, string_types): + first += 1 # text + data = bytearray(data, "utf-8") + else: + first += 2 # binary + frame.append(first) + frame += self._encode_tail(data, self._sock is None) + self._write(frame) + + def _encode_tail(self, data, mask=False): + tail = bytearray() + data_length = len(data) + if data_length <= 125: + len_byte = data_length + lbytes = 0 + elif data_length <= 0xffff: + len_byte = 126 + lbytes = 2 + else: + len_byte = 127 + lbytes = 8 + if mask: + len_byte = len_byte | 0x80 + tail.append(len_byte) + for i in range(lbytes - 1, -1, -1): + tail.append(data_length >> (i * 8) & 0xff) + if mask: + try: + masking_key = bytearray(list(os.urandom(4))) + except NotImplementedError: + masking_key \ + = bytearray([random.randint(0, 255) for i in range(4)]) + tail += masking_key + for i, c in enumerate(data): + tail.append(c ^ masking_key[i % 4]) + else: + tail += data + return tail + + def _write(self, data): + if self._sock is not None: + self.fire(write(self._sock, data), self.parent.channel) + else: + self.fire(write(data), self.parent.channel) + + @handler("close") + def _on_close(self, *args): + if self._sock is not None: + if args and (args[0] != self._sock): + return + if not self._close_sent: + self._write(b"\x88\x00") + self._close_sent = True + if self._close_received and self._close_sent: + if self._sock: + self.fire(close(self._sock), self.parent.channel) + else: + self.fire(close(), self.parent.channel) diff -Nru circuits-2.1.0/circuits/six.py circuits-3.1.0+ds1/circuits/six.py --- circuits-2.1.0/circuits/six.py 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/six.py 2014-09-04 10:32:30.000000000 +0000 @@ -17,7 +17,8 @@ class_types = type, text_type = str binary_type = bytes - + byteindex = lambda x, i: x[i] + iterbytes = lambda x: iter(x) MAXSIZE = sys.maxsize else: string_types = basestring, @@ -44,6 +45,12 @@ MAXSIZE = int((1 << 63) - 1) del X + def byteindex(data, index): + return ord(data[index]) + + def iterbytes(data): + return (ord (char) for char in data) + def _add_doc(func, doc): """Add documentation to a function.""" @@ -260,10 +267,12 @@ if PY3: - def b(s): - return s.encode("latin-1") - def u(s): + def b(s, encoding='utf-8'): + return s.encode(encoding) + def u(s, encoding='utf-8'): return s + def bytes_to_str(b): + return str(b, "unicode_escape") if sys.version_info[1] <= 1: def int2byte(i): return bytes((i,)) @@ -274,10 +283,12 @@ StringIO = io.StringIO BytesIO = io.BytesIO else: - def b(s): + def b(s, encoding='utf-8'): + return s + def u(s, encoding='utf-8'): + return unicode(s, encoding) + def bytes_to_str(s): return s - def u(s): - return unicode(s, "unicode_escape") int2byte = chr import StringIO StringIO = BytesIO = StringIO.StringIO diff -Nru circuits-2.1.0/circuits/tools/__init__.py circuits-3.1.0+ds1/circuits/tools/__init__.py --- circuits-2.1.0/circuits/tools/__init__.py 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/tools/__init__.py 2014-09-04 10:32:30.000000000 +0000 @@ -8,8 +8,10 @@ tools are installed as executables with a prefix of "circuits." """ -from hashlib import md5 -from warnings import warn +from functools import wraps +from warnings import warn, warn_explicit + +from circuits.six import _func_code def tryimport(modules, obj=None, message=None): @@ -37,14 +39,15 @@ yield r -def edges(x, e=None, v=None): +def edges(x, e=None, v=None, d=0): if not e: e = set() if not v: v = [] + d += 1 for c in x.components.copy(): - e.add((x, c)) - edges(c, e, v) + e.add((x, c, d)) + edges(c, e, v, d) return e @@ -71,27 +74,50 @@ :param name: A name for the graph (defaults to x's name) :type name: str - @return: A directed graph representing x's Component sturcture. + @return: A directed graph representing x's Component structure. @rtype: str """ - def getname(c): - s = "%d" % id(c) - h = md5(s.encode("utf-8")).hexdigest()[-4:] - return "%s-%s" % (c.name, h) + networkx = tryimport("networkx") + pygraphviz = tryimport("pygraphviz") + plt = tryimport("matplotlib.pyplot", "pyplot") - pydot = tryimport("pydot") - if pydot is not None: + if networkx is not None and pygraphviz is not None and plt is not None: graph_edges = [] - for (u, v) in edges(x): - graph_edges.append(("\"%s\"" % getname(u), "\"%s\"" % getname(v))) + for (u, v, d) in edges(x): + graph_edges.append((u.name, v.name, float(d))) - g = pydot.graph_from_edges(graph_edges, directed=True) - g.write("%s.dot" % (name or x.name)) - try: - g.write("%s.png" % (name or x.name), format="png") - except pydot.InvocationException: - pass + g = networkx.DiGraph() + g.add_weighted_edges_from(graph_edges) + + elarge = [(u, v) for (u, v, d) in g.edges(data=True) + if d["weight"] > 3.0] + esmall = [(u, v) for (u, v, d) in g.edges(data=True) + if d["weight"] <= 3.0] + + pos = networkx.spring_layout(g) # positions for all nodes + + # nodes + networkx.draw_networkx_nodes(g, pos, node_size=700) + + # edges + networkx.draw_networkx_edges(g, pos, edgelist=elarge, width=1) + networkx.draw_networkx_edges( + g, pos, edgelist=esmall, width=1, + alpha=0.5, edge_color="b", style="dashed" + ) + + # labels + networkx.draw_networkx_labels( + g, pos, font_size=10, font_family="sans-serif" + ) + + plt.axis("off") + + plt.savefig("{0:s}.png".format(name or x.name)) + networkx.write_dot(g, "{0:s}.dot".format(name or x.name)) + + plt.clf() def printer(d, x): return "%s* %s" % (" " * d, x) @@ -126,3 +152,16 @@ write(" %s\n" % reprhandler(handler)) return "".join(s) + + +def deprecated(f): + @wraps(f) + def wrapper(*args, **kwargs): + warn_explicit( + "Call to deprecated function {0:s}".format(f.__name__), + category=DeprecationWarning, + filename=getattr(f, _func_code).co_filename, + lineno=getattr(f, _func_code).co_firstlineno + 1 + ) + return f(*args, **kwargs) + return wrapper diff -Nru circuits-2.1.0/circuits/version.py circuits-3.1.0+ds1/circuits/version.py --- circuits-2.1.0/circuits/version.py 1970-01-01 00:00:00.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/version.py 2014-10-31 23:12:23.000000000 +0000 @@ -0,0 +1,11 @@ +# Package: version +# Date: 12th October 2013 +# Author: James Mills, j dot mills at griffith dot edu dot au + +"""Version Module + +So we only have to maintain version information in one place! +""" + +version_info = (3, 1, 0) # (major, minor, patch, dev?) +version = ".".join(map(str, version_info)) diff -Nru circuits-2.1.0/circuits/web/apps/__init__.py circuits-3.1.0+ds1/circuits/web/apps/__init__.py --- circuits-2.1.0/circuits/web/apps/__init__.py 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/web/apps/__init__.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,19 +0,0 @@ -# Package: apps -# Date: 3rd February 2011 -# Author: James Mills, prologic at shortcircuit dot net dot au - -"""Apps - -This package contains self-contained small packaged apps that come shipped -with circuits.web that can be used within a circuits.web application. -""" - -from circuits.web.apps.webconsole import WebConsole -from circuits.web.apps.memorymonitor import MemoryMonitor - -__all__ = ( - "WebConsole", - "MemoryMonitor", -) - -# flake8: noqa diff -Nru circuits-2.1.0/circuits/web/apps/memorymonitor/htdocs/graphs.html circuits-3.1.0+ds1/circuits/web/apps/memorymonitor/htdocs/graphs.html --- circuits-2.1.0/circuits/web/apps/memorymonitor/htdocs/graphs.html 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/web/apps/memorymonitor/htdocs/graphs.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,40 +0,0 @@ - - - - Dowser: Types - - - - - - - - -
-%(output)s -
- - - \ No newline at end of file diff -Nru circuits-2.1.0/circuits/web/apps/memorymonitor/htdocs/main.css circuits-3.1.0+ds1/circuits/web/apps/memorymonitor/htdocs/main.css --- circuits-2.1.0/circuits/web/apps/memorymonitor/htdocs/main.css 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/web/apps/memorymonitor/htdocs/main.css 1970-01-01 00:00:00.000000000 +0000 @@ -1,54 +0,0 @@ -body { - margin: 0; - padding: 0; -} - -#header { - text-align: center; - background-color: #CCCCCC; - margin: 0; - padding: 0.25em; -} - -#header p { - margin: 0; - padding: 0.25em; -} - -#header h1 a { - text-decoration: none; -} - -#header h1 a:visited { - color: black; -} - -h1 { - font: 900 20pt Verdana, sans-serif; - text-align: center; - margin: 0; - padding: 0.25em; -} - -h2 { - text-align: center; -} - -.obj { - border: 1px dashed #CCCCCC; - padding: 0.5em; - margin: 2px; - font: 10pt Arial, sans-serif; - vertical-align: middle; -} - -.typename { - font-weight: bold; -} - -.refs { - border: 1px solid #CCCCCC; - padding: 0.25em; - margin: 0; -} - diff -Nru circuits-2.1.0/circuits/web/apps/memorymonitor/htdocs/trace.html circuits-3.1.0+ds1/circuits/web/apps/memorymonitor/htdocs/trace.html --- circuits-2.1.0/circuits/web/apps/memorymonitor/htdocs/trace.html 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/web/apps/memorymonitor/htdocs/trace.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,39 +0,0 @@ - - - - Dowser: Trace - - - - - - - - -

%(typename)s %(objid)s

- -
-%(output)s -
- - - \ No newline at end of file diff -Nru circuits-2.1.0/circuits/web/apps/memorymonitor/htdocs/tree.html circuits-3.1.0+ds1/circuits/web/apps/memorymonitor/htdocs/tree.html --- circuits-2.1.0/circuits/web/apps/memorymonitor/htdocs/tree.html 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/web/apps/memorymonitor/htdocs/tree.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,31 +0,0 @@ - - - - Dowser: Tree - - - - - - - - -

%(typename)s %(objid)s

- -
-%(output)s -
- - - \ No newline at end of file diff -Nru circuits-2.1.0/circuits/web/apps/memorymonitor/__init__.py circuits-3.1.0+ds1/circuits/web/apps/memorymonitor/__init__.py --- circuits-2.1.0/circuits/web/apps/memorymonitor/__init__.py 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/web/apps/memorymonitor/__init__.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,324 +0,0 @@ -import gc -import os -import cgi -import sys -import time -import threading -from types import FrameType, ModuleType - -import Image -import ImageDraw - -from circuits import handler -from circuits.web import Controller -from circuits.tools import tryimport - -StringIO = tryimport(("cStringIO", "StringIO", "io"), "StringIO") - -import reftree - -docroot = os.path.abspath(os.path.join(os.path.dirname(__file__), "htdocs")) - - -def get_repr(obj, limit=250): - return cgi.escape(reftree.get_repr(obj, limit)) - - -class _(object): - pass -dictproxy = type(_.__dict__) - -method_types = [ - type(tuple.__le__), # 'wrapper_descriptor' - type([1].__le__), # 'method-wrapper' - type(sys.getcheckinterval), # 'builtin_function_or_method' - type(cgi.FieldStorage.getfirst), # 'instancemethod' -] - - -class MemoryMonitor(Controller): - - period = 5 - maxhistory = 300 - - def __init__(self, *args, **kwargs): - super(MemoryMonitor, self).__init__(*args, **kwargs) - - self.history = {} - self.samples = 0 - self.runthread = threading.Thread(target=self._start) - self.runthread.start() - - def _render(self, name, **params): - p = {'maincss': self.url("/main.css"), - 'home': self.url("/"), - } - p.update(params) - return open(os.path.join(docroot, name)).read() % p - - def _start(self): - self._running = True - while self._running: - self._tick() - time.sleep(self.period) - - def _tick(self): - gc.collect() - - typecounts = {} - for obj in gc.get_objects(): - objtype = type(obj) - if objtype in typecounts: - typecounts[objtype] += 1 - else: - typecounts[objtype] = 1 - - for objtype, count in typecounts.iteritems(): - typename = objtype.__module__ + "." + objtype.__name__ - if typename not in self.history: - self.history[typename] = [0] * self.samples - self.history[typename].append(count) - - samples = self.samples + 1 - - # Add dummy entries for any types which no longer exist - for typename, hist in self.history.iteritems(): - diff = samples - len(hist) - if diff > 0: - hist.extend([0] * diff) - - # Truncate history to self.maxhistory - if samples > self.maxhistory: - for typename, hist in self.history.iteritems(): - hist.pop(0) - else: - self.samples = samples - - @handler("stopped", channel="*") - def stop(self, component): - self._running = False - - def index(self, floor=0): - rows = [] - typenames = self.history.keys() - typenames.sort() - for typename in typenames: - hist = self.history[typename] - maxhist = max(hist) - if maxhist > int(floor): - row = ('
%s
' - '
' - 'Min: %s Cur: %s Max: %s TRACE
' - % (cgi.escape(typename), - self.url("chart/%s" % typename), - min(hist), hist[-1], maxhist, - self.url("trace/%s" % typename), - ) - ) - rows.append(row) - return self._render("graphs.html", output="\n".join(rows)) - - def chart(self, typename): - """Return a sparkline chart of the given type.""" - data = self.history[typename] - height = 20.0 - scale = height / max(data) - im = Image.new("RGB", (len(data), int(height)), 'white') - draw = ImageDraw.Draw(im) - draw.line([(i, int(height - (v * scale))) for i, v in enumerate(data)], - fill="#009900") - del draw - - f = StringIO() - im.save(f, "PNG") - result = f.getvalue() - - self.response.headers["Content-Type"] = "image/png" - return result - - def trace(self, typename, objid=None): - gc.collect() - - if objid is None: - rows = self.trace_all(typename) - else: - rows = self.trace_one(typename, objid) - - return self._render( - "trace.html", output="\n".join(rows), - typename=cgi.escape(typename), - objid=str(objid or '') - ) - - def trace_all(self, typename): - rows = [] - for obj in gc.get_objects(): - objtype = type(obj) - if objtype.__module__ + "." + objtype.__name__ == typename: - rows.append("

%s

" - % ReferrerTree(obj).get_repr(obj)) - if not rows: - rows = ["

The type you requested was not found.

"] - return rows - - def trace_one(self, typename, objid): - rows = [] - objid = int(objid) - all_objs = gc.get_objects() - for obj in all_objs: - if id(obj) == objid: - objtype = type(obj) - if objtype.__module__ + "." + objtype.__name__ != typename: - rows = ["

The object you requested is no longer " - "of the correct type.

"] - else: - # Attributes - rows.append('

Attributes

') - for k in dir(obj): - v = getattr(obj, k) - if type(v) not in method_types: - rows.append('

%s: %s

' % - (k, get_repr(v))) - del v - rows.append('
') - - # Referrers - rows.append( - '

Referrers (Parents)

' - ) - rows.append('

Show the ' - 'entire tree of reachable objects

' - % self.url("/tree/%s/%s" % (typename, objid))) - tree = ReferrerTree(obj) - tree.ignore(all_objs) - for depth, parentid, parentrepr in tree.walk(maxdepth=1): - if parentid: - rows.append("

%s

" % parentrepr) - rows.append('
') - - # Referents - rows.append( - '

Referents (Children)

' - ) - for child in gc.get_referents(obj): - rows.append( - "

%s

" % tree.get_repr(child) - ) - rows.append('
') - break - if not rows: - rows = ["

The object you requested was not found.

"] - return rows - - def tree(self, typename, objid): - gc.collect() - - rows = [] - objid = int(objid) - all_objs = gc.get_objects() - for obj in all_objs: - if id(obj) == objid: - objtype = type(obj) - if objtype.__module__ + "." + objtype.__name__ != typename: - rows = ["

The object you requested is no longer " - "of the correct type.

"] - else: - rows.append('
') - - tree = ReferrerTree(obj) - tree.ignore(all_objs) - for depth, parentid, parentrepr in tree.walk( - maxresults=1000): - rows.append(parentrepr) - - rows.append('
') - break - if not rows: - rows = ["

The object you requested was not found.

"] - - params = {'output': "\n".join(rows), - 'typename': cgi.escape(typename), - 'objid': str(objid), - } - return self._render("tree.html", **params) - - -class ReferrerTree(reftree.Tree): - - ignore_modules = True - - def _gen(self, obj, depth=0): - if self.maxdepth and depth >= self.maxdepth: - yield depth, 0, "---- Max depth reached ----" - raise StopIteration - - if isinstance(obj, ModuleType) and self.ignore_modules: - raise StopIteration - - refs = gc.get_referrers(obj) - refiter = iter(refs) - self.ignore(refs, refiter) - thisfile = sys._getframe().f_code.co_filename - for ref in refiter: - # Exclude all frames that are from this module or reftree. - if (isinstance(ref, FrameType) - and ref.f_code.co_filename in (thisfile, self.filename)): - continue - - # Exclude all functions and classes from this module or reftree. - mod = getattr(ref, "__module__", "") - if "dowser" in mod or "reftree" in mod or mod == '__main__': - continue - - # Exclude all parents in our ignore list. - if id(ref) in self._ignore: - continue - - # Yield the (depth, id, repr) of our object. - yield depth, 0, '%s
' % (" " * depth) - if id(ref) in self.seen: - yield depth, id(ref), "see %s above" % id(ref) - else: - self.seen[id(ref)] = None - yield depth, id(ref), self.get_repr(ref, obj) - - for parent in self._gen(ref, depth + 1): - yield parent - yield depth, 0, '%s
' % (" " * depth) - - def get_repr(self, obj, referent=None): - """Return an HTML tree block describing the given object.""" - objtype = type(obj) - typename = objtype.__module__ + "." + objtype.__name__ - prettytype = typename.replace("__builtin__.", "") - - name = getattr(obj, "__name__", "") - if name: - prettytype = "%s %r" % (prettytype, name) - - key = "" - if referent: - key = self.get_refkey(obj, referent) - return ('%s ' - '%s%s
' - '%s' - % (self.url("/trace/%s/%s" % (typename, id(obj))), - id(obj), prettytype, key, get_repr(obj, 100)) - ) - - def get_refkey(self, obj, referent): - """ - Return the dict key or attribute name of obj which refers to referent. - """ - - if isinstance(obj, dict): - for k, v in obj.iteritems(): - if v is referent: - return " (via its %r key)" % k - - for k in dir(obj) + ['__dict__']: - if getattr(obj, k, None) is referent: - return " (via its %r attribute)" % k - return "" - -__all__ = ("MemoryMonitor",) diff -Nru circuits-2.1.0/circuits/web/apps/memorymonitor/reftree.py circuits-3.1.0+ds1/circuits/web/apps/memorymonitor/reftree.py --- circuits-2.1.0/circuits/web/apps/memorymonitor/reftree.py 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/web/apps/memorymonitor/reftree.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,190 +0,0 @@ -import gc -import sys - -from types import FrameType - - -class Tree: - - def __init__(self, obj): - self.obj = obj - self.filename = sys._getframe().f_code.co_filename - self._ignore = {} - - def ignore(self, *objects): - for obj in objects: - self._ignore[id(obj)] = None - - def ignore_caller(self): - f = sys._getframe() # = this function - cur = f.f_back # = the function that called us (probably 'walk') - self.ignore(cur, cur.f_builtins, cur.f_locals, cur.f_globals) - caller = f.f_back # = the 'real' caller - self.ignore(caller, caller.f_builtins, caller.f_locals, caller.f_globals) - - def walk(self, maxresults=100, maxdepth=None): - """Walk the object tree, ignoring duplicates and circular refs.""" - self.seen = {} - self.ignore(self, self.__dict__, self.obj, self.seen, self._ignore) - - # Ignore the calling frame, its builtins, globals and locals - self.ignore_caller() - - self.maxdepth = maxdepth - count = 0 - for result in self._gen(self.obj): - yield result - count += 1 - if maxresults and count >= maxresults: - yield 0, 0, "==== Max results reached ====" - raise StopIteration - - def print_tree(self, maxresults=100, maxdepth=None): - """Walk the object tree, pretty-printing each branch.""" - self.ignore_caller() - for depth, refid, rep in self.walk(maxresults, maxdepth): - print ("%9d" % refid), (" " * depth * 2), rep - - -def _repr_container(obj): - return "%s of len %s: %r" % (type(obj).__name__, len(obj), obj) -repr_dict = _repr_container -repr_set = _repr_container -repr_list = _repr_container -repr_tuple = _repr_container - - -def repr_str(obj): - return "%s of len %s: %r" % (type(obj).__name__, len(obj), obj) -repr_unicode = repr_str - - -def repr_frame(obj): - return "frame from %s line %s" % (obj.f_code.co_filename, obj.f_lineno) - - -def get_repr(obj, limit=250): - typename = getattr(type(obj), "__name__", None) - handler = globals().get("repr_%s" % typename, repr) - - try: - result = handler(obj) - except: - result = "unrepresentable object: %r" % sys.exc_info()[1] - - if len(result) > limit: - result = result[:limit] + "..." - - return result - - -class ReferentTree(Tree): - - def _gen(self, obj, depth=0): - if self.maxdepth and depth >= self.maxdepth: - yield depth, 0, "---- Max depth reached ----" - raise StopIteration - - for ref in gc.get_referents(obj): - if id(ref) in self._ignore: - continue - elif id(ref) in self.seen: - yield depth, id(ref), "!" + get_repr(ref) - continue - else: - self.seen[id(ref)] = None - yield depth, id(ref), get_repr(ref) - - for child in self._gen(ref, depth + 1): - yield child - - -class ReferrerTree(Tree): - - def _gen(self, obj, depth=0): - if self.maxdepth and depth >= self.maxdepth: - yield depth, 0, "---- Max depth reached ----" - raise StopIteration - - refs = gc.get_referrers(obj) - refiter = iter(refs) - self.ignore(refs, refiter) - for ref in refiter: - # Exclude all frames that are from this module. - if isinstance(ref, FrameType): - if ref.f_code.co_filename == self.filename: - continue - - if id(ref) in self._ignore: - continue - elif id(ref) in self.seen: - yield depth, id(ref), "!" + get_repr(ref) - continue - else: - self.seen[id(ref)] = None - yield depth, id(ref), get_repr(ref) - - for parent in self._gen(ref, depth + 1): - yield parent - - -class CircularReferents(Tree): - - def walk(self, maxresults=100, maxdepth=None): - """Walk the object tree, showing circular referents.""" - self.stops = 0 - self.seen = {} - self.ignore(self, self.__dict__, self.seen, self._ignore) - - # Ignore the calling frame, its builtins, globals and locals - self.ignore_caller() - - self.maxdepth = maxdepth - count = 0 - for result in self._gen(self.obj): - yield result - count += 1 - if maxresults and count >= maxresults: - yield 0, 0, "==== Max results reached ====" - raise StopIteration - - def _gen(self, obj, depth=0, trail=None): - if self.maxdepth and depth >= self.maxdepth: - self.stops += 1 - raise StopIteration - - if trail is None: - trail = [] - - for ref in gc.get_referents(obj): - if id(ref) in self._ignore: - continue - elif id(ref) in self.seen: - continue - else: - self.seen[id(ref)] = None - - refrepr = get_repr(ref) - if id(ref) == id(self.obj): - yield trail + [refrepr,] - - for child in self._gen(ref, depth + 1, trail + [refrepr,]): - yield child - - def print_tree(self, maxresults=100, maxdepth=None): - """Walk the object tree, pretty-printing each branch.""" - self.ignore_caller() - for trail in self.walk(maxresults, maxdepth): - print trail - if self.stops: - print "%s paths stopped because max depth reached" % self.stops - - -def count_objects(): - d = {} - for obj in gc.get_objects(): - objtype = type(obj) - d[objtype] = d.get(objtype, 0) + 1 - d = [(v, k) for k, v in d.iteritems()] - d.sort() - return d diff -Nru circuits-2.1.0/circuits/web/apps/webconsole/htdocs/index.html circuits-3.1.0+ds1/circuits/web/apps/webconsole/htdocs/index.html --- circuits-2.1.0/circuits/web/apps/webconsole/htdocs/index.html 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/web/apps/webconsole/htdocs/index.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,468 +0,0 @@ - - - - - circuits.web Terminal - - - - - - - -

circuits.web Terminal

- -
-
- -
-
->>> -
- - - diff -Nru circuits-2.1.0/circuits/web/apps/webconsole/__init__.py circuits-3.1.0+ds1/circuits/web/apps/webconsole/__init__.py --- circuits-2.1.0/circuits/web/apps/webconsole/__init__.py 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/web/apps/webconsole/__init__.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,160 +0,0 @@ -import os -import re -import sys -import codeop -import inspect -import traceback - -from circuits import handler -from circuits.web import Controller -from circuits.tools import tryimport - -StringIO = tryimport(("cStringIO", "StringIO", "io"), "StringIO") - -docroot = os.path.abspath(os.path.join(os.path.dirname(__file__), "htdocs")) - - -class HTTPREPL(object): - - def __init__(self, locals=None): - super(HTTPREPL, self).__init__() - - self.locals = {} - if locals: - self.locals.update(locals) - self.buffer = [] - - def push(self, line): - """Push 'line' and return exec results (None if more input needed).""" - if line == "help": - return "Type help(object) for help about object." - if line == "help()": - return "You cannot call help() without an argument." - - self.buffer.append(line) - source = "\n".join(self.buffer) - - try: - code = codeop.compile_command(source, "", 'single') - except (OverflowError, SyntaxError, ValueError): - self.buffer = [] - return traceback.format_exc() - - if code is None: - # More lines needed. - return None - - self.buffer = [] - return self.execute(code) - - def execute(self, code): - """ - Execute the given code in self.locals and return any stdout/sterr. - """ - - out = StringIO() - oldout = sys.stdout - olderr = sys.stderr - sys.stdout = sys.stderr = out - try: - try: - exec code in self.locals - except: - result = traceback.format_exc() - else: - result = out.getvalue() - finally: - sys.stdout = oldout - sys.stderr = olderr - out.close() - return result - - def dir(self, line): - """Examine a partial line and provide attr list of final expr.""" - line = re.split(r"\s", line)[-1].strip() - # Support lines like "thing.attr" as "thing.", because the browser - # may not finish calculating the partial line until after the user - # has clicked on a few more keys. - line = ".".join(line.split(".")[:-1]) - try: - result = eval("dir(%s)" % line, {}, self.locals) - except: - return "" - return result - - def doc(self, line): - """Examine a partial line and provide sig+doc of final expr.""" - line = re.split(r"\s", line)[-1].strip() - # Support lines like "func(text" as "func(", because the browser - # may not finish calculating the partial line until after the user - # has clicked on a few more keys. - line = "(".join(line.split("(")[:-1]) - try: - result = eval(line, {}, self.locals) - try: - if isinstance(result, type): - func = result.__init__ - else: - func = result - args, varargs, varkw, defaults = inspect.getargspec(func) - except TypeError: - if callable(result): - doc = getattr(result, "__doc__", "") or "" - return "%s\n\n%s" % (line, doc) - return None - except: - return None - - if args and args[0] == 'self': - args.pop(0) - missing = object() - defaults = defaults or [] - defaults = ([missing] * (len(args) - len(defaults))) + list(defaults) - arglist = [] - for a, d in zip(args, defaults): - if d is missing: - arglist.append(a) - else: - arglist.append("%s=%s" % (a, d)) - if varargs: - arglist.append("*%s" % varargs) - if varkw: - arglist.append("**%s" % varkw) - doc = getattr(result, "__doc__", "") or "" - return "%s(%s)\n%s" % (line, ", ".join(arglist), doc) - - -class WebConsole(Controller): - - @handler("started", channel="*") - def _on_started(self, component): - self.repl = HTTPREPL(locals={"root": self.root}) - - def index(self): - """Return an HTTP-based Read-Eval-Print-Loop terminal.""" - return open(os.path.join(docroot, "index.html")).read() - - def push(self, line): - """Push 'line' and return exec results as a bare response.""" - result = self.repl.push(line) - if result is None: - # More input lines needed. - self.response.code = 204 - return result - - def dir(self, line): - """Push 'line' and return result of eval on the final expr.""" - result = self.repl.dir(line) - if not result: - self.response.code = 204 - return - return repr(result) - - def doc(self, line): - """Push 'line' and return result of getargspec on the final expr.""" - result = self.repl.doc(line) - if not result: - self.response.code = 204 - return result - -__all__ = ("WebConsole",) diff -Nru circuits-2.1.0/circuits/web/client.py circuits-3.1.0+ds1/circuits/web/client.py --- circuits-2.1.0/circuits/web/client.py 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/web/client.py 2014-09-04 10:32:30.000000000 +0000 @@ -4,11 +4,11 @@ except ImportError: from urlparse import urlparse # NOQA +from circuits.protocols.http import HTTP from circuits.web.headers import Headers +from circuits.net.sockets import TCPClient +from circuits.net.events import close, connect, write from circuits.core import handler, BaseComponent, Event -from circuits.net.sockets import TCPClient, Connect, Write, Close - -from circuits.net.protocols.http import HTTP def parse_url(url): @@ -28,12 +28,12 @@ else: raise ValueError("Invalid URL scheme") - resource = p.path or "/" + path = p.path or "/" if p.query: - resource += "?" + p.query + path += "?" + p.query - return (host, port, resource, secure) + return (host, port, path, secure) class HTTPException(Exception): @@ -44,32 +44,30 @@ pass -class Request(Event): - """Request Event +class request(Event): + """request Event This Event is used to initiate a new request. :param method: HTTP Method (PUT, GET, POST, DELETE) :type method: str - :param path: Path to resource - :type path: str + :param url: Request URL + :type url: str """ def __init__(self, method, path, body=None, headers={}): "x.__init__(...) initializes x; see x.__class__.__doc__ for signature" - super(Request, self).__init__(method, path, body, headers) + super(request, self).__init__(method, path, body, headers) class Client(BaseComponent): channel = "client" - def __init__(self, url, channel=channel): + def __init__(self, channel=channel): super(Client, self).__init__(channel=channel) - self._host, self._port, self._resource, self._secure = parse_url(url) - self._response = None self._transport = TCPClient(channel=channel).register(self) @@ -79,47 +77,53 @@ @handler("write") def write(self, data): if self._transport.connected: - self.fire(Write(data), self._transport) + self.fire(write(data), self._transport) @handler("close") def close(self): if self._transport.connected: - self.fire(Close(), self._transport) - - @handler("connect", filter=True) - def connect(self, host=None, port=None, secure=None): - host = host or self._host - port = port or self._port - secure = secure or self._secure + self.fire(close(), self._transport) + @handler("connect", priority=1) + def connect(self, event, host=None, port=None, secure=None): if not self._transport.connected: - self.fire(Connect(host, port, secure), self._transport) + self.fire(connect(host, port, secure), self._transport) - return True + event.stop() @handler("request") - def request(self, method, path, body=None, headers={}): - if self._transport.connected: - headers = Headers([(k, v) for k, v in headers.items()]) - # Clients MUST include Host header in HTTP/1.1 requests (RFC 2616) - if "Host" not in headers: - headers["Host"] = self._host \ - + (":" + str(self._port)) if self._port else "" - if body is not None: - headers["Content-Length"] = len(body) - command = "%s %s HTTP/1.1" % (method, path) - message = "%s\r\n%s" % (command, headers) - self.fire(Write(message.encode('utf-8')), self._transport) - if body is not None: - self.fire(Write(body), self._transport) - else: - raise NotConnected() + def request(self, method, url, body=None, headers={}): + host, port, path, secure = parse_url(url) + + if not self._transport.connected: + self.fire(connect(host, port, secure)) + yield self.wait("connected", self._transport.channel) + + headers = Headers([(k, v) for k, v in headers.items()]) + + # Clients MUST include Host header in HTTP/1.1 requests (RFC 2616) + if "Host" not in headers: + headers["Host"] = "{0:s}{1:s}".format( + host, "" if port in (80, 443) else ":{0:d}".format(port) + ) + + if body is not None: + headers["Content-Length"] = len(body) + + command = "%s %s HTTP/1.1" % (method, path) + message = "%s\r\n%s" % (command, headers) + self.fire(write(message.encode('utf-8')), self._transport) + if body is not None: + self.fire(write(body), self._transport) + + yield (yield self.wait("response")) @handler("response") def _on_response(self, response): self._response = response - if response.headers.get("Connection") == "Close": - self.fire(Close(), self._transport) + if response.headers.get("Connection") == "close": + self.fire(close(), self._transport) + return response @property def connected(self): diff -Nru circuits-2.1.0/circuits/web/constants.py circuits-3.1.0+ds1/circuits/web/constants.py --- circuits-2.1.0/circuits/web/constants.py 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/web/constants.py 2014-09-04 10:32:30.000000000 +0000 @@ -10,8 +10,8 @@ from circuits import __version__ SERVER_PROTOCOL = (1, 1) -SERVER_VERSION = "circuits/%s" % __version__ -SERVER_URL = "http://bitbucket.org/prologic/circuits/" +SERVER_VERSION = "circuits.web/%s" % __version__ +SERVER_URL = "http://circuitsweb.com/" DEFAULT_ERROR_MESSAGE = """\ 399: + if self.code != 201 and not (299 < self.code < 400): if "Location" in self.response.headers: del self.response.headers["Location"] @@ -87,27 +88,26 @@ ) -class Forbidden(HTTPError): - """An event for signaling the HTTP Forbidden error - """ +class forbidden(httperror): + """An event for signaling the HTTP Forbidden error""" + code = 403 -class Unauthorized(HTTPError): - """An event for signaling the HTTP Unauthorized error - """ +class unauthorized(httperror): + """An event for signaling the HTTP Unauthorized error""" + code = 401 -class NotFound(HTTPError): - """An event for signaling the HTTP Not Fouond error - """ +class notfound(httperror): + """An event for signaling the HTTP Not Fouond error""" + code = 404 -class Redirect(HTTPError): - """An event for signaling the HTTP Redirect response - """ +class redirect(httperror): + """An event for signaling the HTTP Redirect response""" def __init__(self, request, response, urls, code=None): """ @@ -115,6 +115,7 @@ *response* argument to reflect a redirect response to the given *url*. """ + if isinstance(urls, string_types): urls = [urls] @@ -125,7 +126,7 @@ # 2. a URL relative to root (e.g. "/dummy") # 3. a URL relative to the current path # Note that any query string in request is discarded. - url = _urljoin(utils.url(request), url) + url = request.uri.relative(url).unicode() abs_urls.append(url) self.urls = urls = abs_urls @@ -141,7 +142,7 @@ if code < 300 or code > 399: raise ValueError("status code must be between 300 and 399.") - super(Redirect, self).__init__(request, response, code) + super(redirect, self).__init__(request, response, code) if code in (300, 301, 302, 303, 307): response.headers["Content-Type"] = "text/html" diff -Nru circuits-2.1.0/circuits/web/events.py circuits-3.1.0+ds1/circuits/web/events.py --- circuits-2.1.0/circuits/web/events.py 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/web/events.py 2014-09-04 10:32:30.000000000 +0000 @@ -1,48 +1,49 @@ # Module: events # Date: 3rd February 2009 # Author: James Mills, prologic at shortcircuit dot net dot au -from circuits.core.events import LiteralEvent + """Events This module implements the necessary Events needed. """ + from circuits import Event -class WebEvent(Event): - """ - WebEvents have both their ``success`` and ``failure`` attributes set to - True. So event processing generates the derived events - ``...Success`` or ``...Failure`` events. +class request(Event): + """request(Event) -> request Event + + args: request, response """ + success = True failure = True + complete = True -class Request(WebEvent): - """Request(WebEvent) -> Request WebEvent +class response(Event): + """response(Event) -> response Event args: request, response """ - @classmethod - def create(cls, name, *args, **kwargs): - """ - All classes derived dynamically from Request are LiteralEvents. - """ - return LiteralEvent.create(cls, name, *args, **kwargs) + + success = True + failure = True + complete = True -class Response(WebEvent): - """Response(WebEvent) -> Response WebEvent +class stream(Event): + """stream(Event) -> stream Event args: request, response """ + success = True + failure = True + complete = True -class Stream(WebEvent): - """Stream(WebEvent) -> Stream WebEvent - args: request, response - """ +class terminate(Event): + """terminate Event""" diff -Nru circuits-2.1.0/circuits/web/exceptions.py circuits-3.1.0+ds1/circuits/web/exceptions.py --- circuits-2.1.0/circuits/web/exceptions.py 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/web/exceptions.py 2014-09-04 10:32:30.000000000 +0000 @@ -35,7 +35,7 @@ @property def name(self): """The status name.""" - return HTTP_STATUS_CODES[self.code] + return HTTP_STATUS_CODES.get(self.code, '') def __repr__(self): return '<%s \'%s\'>' % (self.__class__.__name__, self) @@ -229,6 +229,18 @@ ) +class RangeUnsatisfiable(HTTPException): + """*416* `Range Unsatisfiable` + + The status code returned if the server is unable to satisfy the request range + """ + + code = 416 + description = ( + '

The server cannot satisfy the request range(s).

' + ) + + class InternalServerError(HTTPException): """*500* `Internal Server Error` diff -Nru circuits-2.1.0/circuits/web/headers.py circuits-3.1.0+ds1/circuits/web/headers.py --- circuits-2.1.0/circuits/web/headers.py 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/web/headers.py 2014-09-04 10:32:30.000000000 +0000 @@ -8,6 +8,7 @@ """ import re +from circuits.six import iteritems, u, b # Regular expression that matches `special' characters in parameters, the # existance of which force quoting of the parameter value. @@ -32,22 +33,24 @@ def header_elements(fieldname, fieldvalue): - """Return a HeaderElement list from a comma-separated header str.""" + """Return a sorted HeaderElement list. + + Returns a sorted HeaderElement list + from a comma-separated header string. + """ if not fieldvalue: - return None - headername = fieldname.lower() + return [] result = [] for element in fieldvalue.split(","): - if headername.startswith("accept") or headername == 'te': + if fieldname.startswith("Accept") or fieldname == 'TE': hv = AcceptElement.from_str(element) else: hv = HeaderElement.from_str(element) result.append(hv) - result.sort() - return result + return list(reversed(sorted(result))) class HeaderElement(object): @@ -59,19 +62,31 @@ params = {} self.params = params - def __unicode__(self): - p = [";%s=%s" % (k, v) for k, v in self.params.items()] - return "%s%s" % (self.value, "".join(p)) + def __eq__(self, other): + return self.value == other.value + + def __lt__(self, other): + return self.value < other.value def __str__(self): - return str(self.__unicode__()) + p = [";%s=%s" % (k, v) for k, v in iteritems(self.params)] + return "%s%s" % (self.value, "".join(p)) + + def __bytes__(self): + return b(self.__str__()) + + def __unicode__(self): + return u(self.__str__()) def parse(elementstr): """Transform 'token;key=val' to ('token', {'key': 'val'}).""" # Split the element into a value and parameters. The 'value' may # be of the form, "token=token", but we don't split that here. atoms = [x.strip() for x in elementstr.split(";") if x.strip()] - initial_value = atoms.pop(0).strip() + if not atoms: + initial_value = '' + else: + initial_value = atoms.pop(0).strip() params = {} for atom in atoms: atom = [x.strip() for x in atom.split("=", 1) if x.strip()] @@ -84,11 +99,11 @@ return initial_value, params parse = staticmethod(parse) + @classmethod def from_str(cls, elementstr): """Construct an instance from a string of the form 'token;key=val'.""" ival, params = cls.parse(elementstr) return cls(ival, params) - from_str = classmethod(from_str) class AcceptElement(HeaderElement): @@ -101,6 +116,7 @@ have been the other way around, but it's too late to fix now. """ + @classmethod def from_str(cls, elementstr): qvalue = None # The first "q" parameter (if any) separates the initial @@ -116,7 +132,6 @@ if qvalue is not None: params["q"] = qvalue return cls(media_type, params) - from_str = classmethod(from_str) def qvalue(self): val = self.params.get("q", "1") @@ -125,132 +140,91 @@ return float(val) qvalue = property(qvalue, doc="The qvalue, or priority, of this value.") - def __cmp__(self, other): - diff = cmp(other.qvalue, self.qvalue) - if diff == 0: - diff = cmp(str(other), str(self)) - return diff - - -class Headers(dict): - """Manage a collection of HTTP response headers""" - - def __init__(self, headers=[]): - if not isinstance(headers, list): - raise TypeError("Headers must be a list of name/value tuples") - self._headers = headers - - def __len__(self): - """Return the total number of headers, including duplicates.""" - return len(self._headers) - - def __setitem__(self, name, val): - """Set the value of a header.""" - del self[name] - self._headers.append((name, val)) - - def __delitem__(self, name): - """Delete all occurrences of a header, if present. + def __eq__(self, other): + return self.qvalue == other.qvalue - Does *not* raise an exception if the header is missing. - """ - name = name.lower() - self._headers[:] = [ - kv for kv in self._headers - if kv[0].lower() != name - ] - - def __getitem__(self, name): - """Get the first header value for 'name' - - Return None if the header is missing instead of raising an exception. - - Note that if the header appeared multiple times, the first exactly - which occurrance gets returned is undefined. Use getall() to get all - the values matching a header field name. - """ - return self.get(name) + def __lt__(self, other): + if self.qvalue == other.qvalue: + return str(self) < str(other) + else: + return self.qvalue < other.qvalue - def pop(self, name, default=None): - value = self.get(name, default) - del self[name] - return value - - def has_key(self, name): - """Return true if the message contains the header.""" - return self.get(name) is not None - __contains__ = has_key +class CaseInsensitiveDict(dict): + """A case-insensitive dict subclass. - def get_all(self, name): - """Return a list of all the values for the named field. + Each key is changed on entry to str(key).title(). + """ - These will be sorted in the order they appeared in the original header - list or were added to this instance, and may contain duplicates. Any - fields deleted and re-inserted are always appended to the header list. - If no fields exist with the given name, returns an empty list. - """ - name = name.lower() - return [kv[1] for kv in self._headers if kv[0].lower() == name] + def __init__(self, *args, **kwargs): + d = dict(*args, **kwargs) + for key, value in iteritems(d): + dict.__setitem__(self, str(key).title(), value) + dict.__init__(self) + + def __getitem__(self, key): + return dict.__getitem__(self, str(key).title()) + + def __setitem__(self, key, value): + dict.__setitem__(self, str(key).title(), value) + + def __delitem__(self, key): + dict.__delitem__(self, str(key).title()) + + def __contains__(self, key): + return dict.__contains__(self, str(key).title()) + + def get(self, key, default=None): + return dict.get(self, str(key).title(), default) + + def update(self, E): + for k in E.keys(): + self[str(k).title()] = E[k] + + @classmethod + def fromkeys(cls, seq, value=None): + newdict = cls() + for k in seq: + newdict[k] = value + return newdict - def get(self, name, default=None): - """Get the first header value for 'name', or return 'default'""" + def setdefault(self, key, x=None): + key = str(key).title() + try: + return dict.__getitem__(self, key) + except KeyError: + self[key] = x + return x - name = name.lower() - for k, v in self._headers: - if k.lower() == name: - return v - return default - - def keys(self): - """Return a list of all the header field names. - - These will be sorted in the order they appeared in the original header - list, or were added to this instance, and may contain duplicates. - Any fields deleted and re-inserted are always appended to the header - list. - """ - return [k for k, v in self._headers] + def pop(self, key, default=None): + return dict.pop(self, str(key).title(), default) - def values(self): - """Return a list of all header values. - These will be sorted in the order they appeared in the original header - list, or were added to this instance, and may contain duplicates. - Any fields deleted and re-inserted are always appended to the header - list. - """ - return [v for k, v in self._headers] +class Headers(CaseInsensitiveDict): - def items(self): - """Get all the header fields and values. + def elements(self, key): + """Return a sorted list of HeaderElements for the given header.""" + return header_elements(key, self.get(key)) - These will be sorted in the order they were in the original header - list, or were added to this instance, and may contain duplicates. - Any fields deleted and re-inserted are always appended to the header - list. - """ - return self._headers[:] + def get_all(self, name): + """Return a list of all the values for the named field.""" + return [val.strip() for val in self.get(name, '').split(',')] def __repr__(self): - return "Headers(%s)" % repr(self._headers) + return "Headers(%s)" % repr(list(self.items())) def __str__(self): - """str() returns the formatted headers, complete with end line, - suitable for direct HTTP transmission.""" - return '\r\n'.join(["%s: %s" % kv for kv in self._headers] + ["", ""]) - - def setdefault(self, name, value): - """Return first matching header value for 'name', or 'value' - - If there is no header named 'name', add a new header with name 'name' - and value 'value'.""" - result = self.get(name) - if result is None: - self._headers.append((name, value)) - return value + headers = ["%s: %s\r\n" % (k, v) for k, v in self.items()] + return "".join(headers) + '\r\n' + + def __bytes__(self): + return str(self).encode("latin1") + + def append(self, key, value): + if not key in self: + self[key] = value else: - return result + self[key] = ", ".join([self[key], value]) def add_header(self, _name, _value, **_params): """Extended header setting. @@ -272,32 +246,9 @@ if _value is not None: parts.append(_value) for k, v in list(_params.items()): + k = k.replace('_', '-') if v is None: - parts.append(k.replace('_', '-')) + parts.append(k) else: - parts.append(_formatparam(k.replace('_', '-'), v)) - self._headers.append((_name, "; ".join(parts))) - - def elements(self, key): - """Return a list of HeaderElements for the given header (or None).""" - key = str(key).title() - h = self.get(key) - if h is None: - return [] - return header_elements(key, h) - - -def parse_headers(data): - headers = Headers([]) - - for line in data.split("\r\n"): - if line[0] in " \t": - # It's a continuation line. - v = line.strip() - else: - k, v = line.split(":", 1) - k, v = k.strip(), v.strip() - - headers.add_header(k, v) - - return headers + parts.append(_formatparam(k, v)) + self.append(_name, "; ".join(parts)) diff -Nru circuits-2.1.0/circuits/web/http.py circuits-3.1.0+ds1/circuits/web/http.py --- circuits-2.1.0/circuits/web/http.py 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/web/http.py 2014-10-05 23:16:30.000000000 +0000 @@ -2,6 +2,7 @@ # Date: 13th September 2007 # Author: James Mills, prologic at shortcircuit dot net dot au + """Hyper Text Transfer Protocol This module implements the server side Hyper Text Transfer Protocol @@ -9,23 +10,29 @@ """ +from io import BytesIO + try: - from urllib.parse import unquote - from urllib.parse import urlparse + from urllib.parse import quote + from urllib.parse import urlparse, urlunparse except ImportError: - from urllib import unquote # NOQA - from urlparse import urlparse # NOQA + from urllib import quote # NOQA + from urlparse import urlparse, urlunparse # NOQA + -from circuits.net.sockets import Close, Write +from circuits.six import text_type +from circuits.net.events import close, write from circuits.core import handler, BaseComponent, Value from . import wrappers -from .utils import quoted_slash +from .url import parse_url +from .utils import is_ssl_handshake from .exceptions import HTTPException -from .headers import parse_headers, Headers -from .events import Request, Response, Stream -from .errors import HTTPError, NotFound, Redirect +from .events import request, response, stream +from .parsers import HttpParser, BAD_FIRST_LINE +from .errors import httperror, notfound, redirect from .exceptions import Redirect as RedirectException +from .constants import SERVER_VERSION, SERVER_PROTOCOL MAX_HEADER_FRAGENTS = 20 HTTP_ENCODING = 'utf-8' @@ -56,40 +63,85 @@ channel = "web" - def __init__(self, encoding="utf-8", channel=channel): + def __init__(self, server, encoding=HTTP_ENCODING, channel=channel): super(HTTP, self).__init__(channel=channel) + self._server = server self._encoding = encoding + url = "{0:s}://{1:s}{2:s}".format( + (server.secure and "https") or "http", + server.host or "0.0.0.0", + ":{0:d}".format(server.port or 80) + if server.port not in (80, 443) + else "" + ) + self.uri = parse_url(url) + self._clients = {} self._buffers = {} - @handler("stream") - def _on_stream(self, response, data): + @property + def version(self): + return SERVER_VERSION + + @property + def protocol(self): + return SERVER_PROTOCOL + + @property + def scheme(self): + if not hasattr(self, "_server"): + return + return "https" if self._server.secure else "http" + + @property + def base(self): + if not hasattr(self, "uri"): + return + return self.uri.utf8().rstrip(b"/").decode(self._encoding) + + @handler("stream") # noqa + def _on_stream(self, res, data): + sock = res.request.sock + if data is not None: - if data: - if response.chunked: - data = "{0:s}\r\n{1:s}\r\n".format( - hex(len(data))[2:], data - ).encode(self._encoding) - self.fire(Write(response.request.sock, data)) - if response.body and not response.done: + if isinstance(data, text_type): + data = data.encode(self._encoding) + + if res.chunked: + buf = [ + hex(len(data))[2:].encode(self._encoding), + b"\r\n", + data, + b"\r\n" + ] + data = b"".join(buf) + + self.fire(write(sock, data)) + + if res.body and not res.done: try: - data = next(response.body) + data = next(res.body) + while not data: # Skip over any null byte sequences + data = next(res.body) except StopIteration: data = None - self.fire(Stream(response, data)) + self.fire(stream(res, data)) else: - if response.body: - response.body.close() - if response.chunked: - self.fire(Write(response.request.sock, b"0\r\n\r\n")) - if response.close: - self.fire(Close(response.request.sock)) - response.done = True + if res.body: + res.body.close() + if res.chunked: + self.fire(write(sock, b"0\r\n\r\n")) + if res.close: + self.fire(close(sock)) + if sock in self._clients: + del self._clients[sock] + + res.done = True - @handler("response") - def _on_response(self, response): + @handler("response") # noqa + def _on_response(self, res): """``Response`` Event Handler :param response: the ``Response`` object created when the @@ -98,51 +150,70 @@ This handler builds an HTTP response data stream from the information contained in the *response* object and - sends it to the client (firing ``Write`` events). + sends it to the client (firing ``write`` events). """ - self.fire( - Write(response.request.sock, str(response).encode(HTTP_ENCODING)) - ) + # send HTTP response status line and headers - if response.stream and response.body: + req = res.request + headers = res.headers + sock = req.sock + + if req.method == "HEAD": + self.fire(write(sock, bytes(res))) + self.fire(write(sock, bytes(headers))) + elif res.stream and res.body: try: - data = next(response.body) + data = next(res.body) except StopIteration: data = None - self.fire(Stream(response, data)) + self.fire(write(sock, bytes(res))) + self.fire(write(sock, bytes(headers))) + self.fire(stream(res, data)) else: - if isinstance(response.body, bytes): - body = response.body - elif isinstance(response.body, unicode): - body = response.body.encode(self._encoding) + self.fire(write(sock, bytes(res))) + self.fire(write(sock, bytes(headers))) + + if isinstance(res.body, bytes): + body = res.body + elif isinstance(res.body, text_type): + body = res.body.encode(self._encoding) else: parts = ( s if isinstance(s, bytes) else s.encode(self._encoding) - for s in response.body if s is not None + for s in res.body if s is not None ) body = b"".join(parts) if body: - if response.chunked: - buf = [hex(len(body))[2:].encode(), b"\r\n", body, b"\r\n"] + if res.chunked: + buf = [ + hex(len(body))[2:].encode(self._encoding), + b"\r\n", + body, + b"\r\n" + ] body = b"".join(buf) - self.fire(Write(response.request.sock, body)) - if response.chunked: - self.fire(Write(response.request.sock, b"0\r\n\r\n")) + self.fire(write(sock, body)) + + if res.chunked: + self.fire(write(sock, b"0\r\n\r\n")) - if not response.stream: - if response.close: - self.fire(Close(response.request.sock)) - response.done = True + if not res.stream: + if res.close: + self.fire(close(sock)) + # Delete the request/response objects if present + if sock in self._clients: + del self._clients[sock] + res.done = True @handler("disconnect") def _on_disconnect(self, sock): if sock in self._clients: del self._clients[sock] - @handler("read") + @handler("read") # noqa def _on_read(self, sock, data): """Read Event Handler @@ -151,134 +222,101 @@ Raw Event per line. Any unfinished lines of text, leave in the buffer. """ - if sock in self._clients: - request, response = self._clients[sock] - if response.done: - del self._clients[sock] - - if sock in self._clients: - request, response = self._clients[sock] - request.body.write(data) - contentLength = int(request.headers.get("Content-Length", "0")) - if not request.body.tell() == contentLength: - return + if sock in self._buffers: + parser = self._buffers[sock] else: - if sock in self._buffers: - # header fragments have been received before - self._buffers[sock].append(data) - data = b"".join(self._buffers[sock]) - if data.find(b'\r\n\r\n') == -1: - # still not all headers received - return - # all headers received, use combined data and remove buffer + self._buffers[sock] = parser = HttpParser(0, True) + + # If we receive an SSL handshake at the start of a request + # and we're not a secure server, then immediately close the + # client connection since we can't respond to it anyway. + + if is_ssl_handshake(data) and not self._server.secure: + if sock in self._buffers: + del self._buffers[sock] + if sock in self._clients: + del self._clients[sock] + return self.fire(close(sock)) + + _scheme = "https" if self._server.secure else "http" + parser.execute(data, len(data)) + if not parser.is_headers_complete(): + if parser.errno is not None: + if parser.errno == BAD_FIRST_LINE: + req = wrappers.Request(sock, server=self._server) + else: + req = wrappers.Request( + sock, + parser.get_method(), + parser.get_scheme() or _scheme, + parser.get_path(), + parser.get_version(), + parser.get_query_string(), + server=self._server + ) + req.server = self._server + res = wrappers.Response(req, encoding=self._encoding) del self._buffers[sock] - else: - # no pending header fragments for this socket - if data.find(b'\r\n\r\n') == -1: - # this first chunk doesn't contain all headers yet, buffer - buf = self._buffers.setdefault(sock, []) - buf.append(data) - if len(buf) > MAX_HEADER_FRAGENTS: - del self._buffers[sock] - raise ValueError("Too many HTTP Headers Fragments.") - return - - requestline, data = data.split(b"\r\n", 1) - requestline = requestline.strip().decode( - HTTP_ENCODING, "replace" - ) - method, path, protocol = requestline.split(" ", 2) - scheme, location, path, params, qs, frag = urlparse(path) + return self.fire(httperror(req, res, 400)) + return - protocol = tuple(map(int, protocol[5:].split("."))) - request = wrappers.Request( - sock, method, scheme, path, protocol, qs + if sock in self._clients: + req, res = self._clients[sock] + else: + method = parser.get_method() + scheme = parser.get_scheme() or _scheme + path = parser.get_path() + version = parser.get_version() + query_string = parser.get_query_string() + + req = wrappers.Request( + sock, method, scheme, path, version, query_string, + headers=parser.get_headers(), server=self._server ) - response = wrappers.Response(request, encoding=self._encoding) - self._clients[sock] = request, response - if frag: - return self.fire(HTTPError(request, response, 400)) + res = wrappers.Response(req, encoding=self._encoding) - if params: - path = "%s;%s" % (path, params) + self._clients[sock] = (req, res) - # Unquote the path+params (e.g. "/this%20path" -> "this path"). - # http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html#sec5.1.2 - # - # But note that "...a URI must be separated into its components - # before the escaped characters within those components can be - # safely decoded." http://www.ietf.org/rfc/rfc2396.txt, sec 2.4.2 - path = "%2F".join(map(unquote, quoted_slash.split(path))) - - # Compare request and server HTTP protocol versions, in case our - # server does not support the requested protocol. Limit our output - # to min(req, server). We want the following output: - # request server actual written supported response - # protocol protocol response protocol feature set - # a 1.0 1.0 1.0 1.0 - # b 1.0 1.1 1.1 1.0 - # c 1.1 1.0 1.0 1.0 - # d 1.1 1.1 1.1 1.1 - # Notice that, in (b), the response will be "HTTP/1.1" even though - # the client only understands 1.0. RFC 2616 10.5.6 says we should - # only return 505 if the _major_ version is different. - if not request.protocol[0] == request.server_protocol[0]: - return self.fire(HTTPError(request, response, 505)) - - rp = request.protocol - sp = request.server_protocol - response.protocol = "HTTP/%s.%s" % min(rp, sp) - - end_of_headers = data.find(b"\r\n\r\n") - if end_of_headers > -1: - header_data = data[:end_of_headers].decode( - HTTP_ENCODING, "replace" - ) - headers = request.headers = parse_headers(header_data) - else: - headers = request.headers = Headers([]) + rp = req.protocol + sp = self.protocol - request.body.write(data[(end_of_headers + 4):]) + if rp[0] != sp[0]: + # the major HTTP version differs + return self.fire(httperror(req, res, 505)) - if headers.get("Expect", "") == "100-continue": - return self.fire( - Response( - wrappers.Response( - request, code=100, encoding=self._encoding - ) - ) - ) - - contentLength = int(headers.get("Content-Length", "0")) - if request.body.tell() < contentLength: - return - - # Persistent connection support - if request.protocol == (1, 1): - # Both server and client are HTTP/1.1 - if request.headers.get("Connection", "").lower() == "close": - response.close = True - else: - # Either the server or client (or both) are HTTP/1.0 - if request.headers.get("Connection", "").lower() != "keep-alive": - response.close = True + res.protocol = "HTTP/{0:d}.{1:d}".format(*min(rp, sp)) + res.close = not parser.should_keep_alive() - request.body.seek(0) + clen = int(req.headers.get("Content-Length", "0")) + if clen and not parser.is_message_complete(): + return if hasattr(sock, "getpeercert"): peer_cert = sock.getpeercert() if peer_cert: - req = Request(request, response, peer_cert) + e = request(req, res, peer_cert) else: - req = Request(request, response) + e = request(req, res) else: - req = Request(request, response) + e = request(req, res) + + # Guard against unwanted request paths (SECURITY). + path = req.path + _path = req.uri._path + if (path.encode(self._encoding) != _path) and ( + quote(path).encode(self._encoding) != _path): + return self.fire( + redirect(req, res, [req.uri.utf8()], 301) + ) - self.fire(req) + req.body = BytesIO(parser.recv_body()) + del self._buffers[sock] + + self.fire(e) @handler("httperror") - def _on_httperror(self, event, request, response, code, **kwargs): + def _on_httperror(self, event, req, res, code, **kwargs): """Default HTTP Error Handler Default Error Handler that by default just fires a ``Response`` @@ -286,10 +324,11 @@ modified by a :class:`~circuits.web.errors.HTTPError` instance or a subclass thereof. """ - response.body = str(event) - self.fire(Response(response)) - @handler("request_success") + res.body = str(event) + self.fire(response(res)) + + @handler("request_success") # noqa def _on_request_success(self, e, value): """ Handler for the ``RequestSuccess`` event that is automatically @@ -318,115 +357,164 @@ if isinstance(value, Value) and not value.promise: value = value.getValue(recursive=False) - request, response = e.args[:2] + req, res = e.args[:2] if value is None: - self.fire(NotFound(request, response)) - elif isinstance(value, HTTPError): - response.body = str(value) - self.fire(Response(response)) + self.fire(notfound(req, res)) + elif isinstance(value, httperror): + res.body = str(value) + self.fire(response(res)) elif isinstance(value, wrappers.Response): - self.fire(Response(value)) + self.fire(response(value)) elif isinstance(value, Value): if value.result and not value.errors: - response.body = value.value - self.fire(Response(response)) + res.body = value.value + self.fire(response(res)) elif value.errors: error = value.value etype, evalue, traceback = error if isinstance(evalue, RedirectException): self.fire( - Redirect(request, response, evalue.urls, evalue.status) + redirect(req, res, evalue.urls, evalue.code) ) elif isinstance(evalue, HTTPException): if evalue.traceback: self.fire( - HTTPError( - request, response, evalue.code, + httperror( + req, res, evalue.code, description=evalue.description, error=error ) ) else: self.fire( - HTTPError( - request, response, evalue.code, + httperror( + req, res, evalue.code, description=evalue.description ) ) else: - self.fire(HTTPError(request, response, error=error)) + self.fire(httperror(req, res, error=error)) else: # We want to be notified of changes to the value value = e.value.getValue(recursive=False) value.event = e value.notify = True - elif type(value) is tuple: + elif isinstance(value, tuple): etype, evalue, traceback = error = value if isinstance(evalue, RedirectException): self.fire( - Redirect(request, response, evalue.urls, evalue.status) + redirect(req, res, evalue.urls, evalue.code) ) elif isinstance(evalue, HTTPException): if evalue.traceback: self.fire( - HTTPError( - request, response, evalue.code, + httperror( + req, res, evalue.code, description=evalue.description, error=error ) ) else: self.fire( - HTTPError( - request, response, evalue.code, + httperror( + req, res, evalue.code, description=evalue.description ) ) else: - self.fire(HTTPError(request, response, error=error)) - elif type(value) is not bool: - response.body = value - self.fire(Response(response)) - - @handler("request_failure", "response_failure") - def _on_request_or_response_failure(self, evt, err): - if len(evt.args) == 1: - response = evt.args[0] - request = response.request + self.fire(httperror(req, res, error=error)) + elif not isinstance(value, bool): + res.body = value + self.fire(response(res)) + + @handler("exception") + def _on_exception(self, *args, **kwargs): + if not len(args) == 3: + return + + etype, evalue, etraceback = args + fevent = kwargs["fevent"] + + if isinstance(fevent, response): + res = fevent.args[0] + req = res.request + elif isinstance(fevent.value.parent.event, request): + req, res = fevent.value.parent.event.args[:2] + else: + req, res = fevent.args[2:] + + if isinstance(evalue, HTTPException): + code = evalue.code else: - request, response = evt.args[:2] + code = None + + self.fire( + httperror( + req, res, code=code, error=(etype, evalue, etraceback) + ) + ) + + @handler("request_failure") + def _on_request_failure(self, erequest, error): + req, res = erequest.args # Ignore filtered requests already handled (eg: HTTPException(s)). - # Ignore failed "response" handlers (eg: Loggers or Tools) - if request.handled or response.done: + if req.handled: return - if not request.handled: - request.handled = True + req.handled = True - etype, evalue, traceback = err + etype, evalue, traceback = error if isinstance(evalue, RedirectException): self.fire( - Redirect(request, response, evalue.urls, evalue.status) + redirect(req, res, evalue.urls, evalue.code) ) elif isinstance(evalue, HTTPException): - if evalue.traceback: - self.fire( - HTTPError( - request, response, evalue.code, - description=evalue.description, - error=err - ) - ) - else: - self.fire( - HTTPError( - request, response, evalue.code, - description=evalue.description - ) + self.fire( + httperror( + req, res, evalue.code, + description=evalue.description, + error=error ) + ) else: - self.fire(HTTPError(request, response, error=err)) + self.fire(httperror(req, res, error=error)) + + @handler("response_failure") + def _on_response_failure(self, eresponse, error): + res = eresponse.args[0] + req = res.request + + # Ignore failed "response" handlers (eg: Loggers or Tools) + if res.done: + return + + res = wrappers.Response(req, self._encoding, 500) + self.fire(httperror(req, res, error=error)) + + @handler("request_complete") + def _on_request_complete(self, *args, **kwargs): + """Dummy Event Handler for request events + + - request_complete + """ + + @handler("response_success", "response_complete") + def _on_response_feedback(self, *args, **kwargs): + """Dummy Event Handler for response events + + - response_success + - response_complete + """ + + @handler("stream_success", "stream_failure", "stream_complete") + def _on_stream_feedback(self, *args, **kwargs): + """Dummy Event Handler for stream events + + - stream_success + - stream_failure + - stream_complete + """ diff -Nru circuits-2.1.0/circuits/web/__init__.py circuits-3.1.0+ds1/circuits/web/__init__.py --- circuits-2.1.0/circuits/web/__init__.py 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/web/__init__.py 2014-09-04 10:32:30.000000000 +0000 @@ -8,13 +8,13 @@ and WSGI compliant. """ -from .utils import url from .loggers import Logger from .sessions import Sessions -from .controllers import expose, Controller -from .events import Request, Response +from .url import parse_url, URL from .servers import BaseServer, Server -from .errors import HTTPError, Forbidden, NotFound, Redirect +from .controllers import expose, Controller +from .events import request, response, stream +from .errors import httperror, forbidden, notfound, redirect from .dispatchers import Static, Dispatcher, VirtualHosts, XMLRPC try: diff -Nru circuits-2.1.0/circuits/web/loggers.py circuits-3.1.0+ds1/circuits/web/loggers.py --- circuits-2.1.0/circuits/web/loggers.py 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/web/loggers.py 2014-09-04 10:32:30.000000000 +0000 @@ -43,29 +43,27 @@ self.logger = logger - @handler("response", priority=-0.1) - def response(self, response): + @handler("response_success") + def log_response(self, response_event, value): + response = response_event.args[0] self.log(response) def log(self, response): request = response.request remote = request.remote outheaders = response.headers - inheaders = request.headers + inheaders = request.headers or {} protocol = "HTTP/%d.%d" % request.protocol - if "X-Forwarded-For" in inheaders: - host = inheaders["X-Forwarded-For"] - else: - host = remote.name or remote.ip + host = inheaders.get("X-Forwarded-For", (remote.name or remote.ip)) atoms = {"h": host, "l": "-", "u": getattr(request, "login", None) or "-", "t": formattime(), "r": "%s %s %s" % (request.method, request.path, protocol), - "s": str(response.code), + "s": int(response.status), "b": outheaders.get("Content-Length", "") or "-", "f": inheaders.get("Referer", ""), "a": inheaders.get("User-Agent", ""), diff -Nru circuits-2.1.0/circuits/web/main.py circuits-3.1.0+ds1/circuits/web/main.py --- circuits-2.1.0/circuits/web/main.py 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/web/main.py 2014-09-04 10:32:30.000000000 +0000 @@ -7,7 +7,10 @@ circutis.web Web Server and Testing Tool. """ + import os +from sys import stderr +from hashlib import md5 from optparse import OptionParser from wsgiref.validate import validator from wsgiref.simple_server import make_server @@ -18,16 +21,16 @@ except ImportError: hostshot = None -try: - import psyco -except: - psyco = None # NOQA + +import circuits +from circuits import handler, Component, Manager, Debugger from circuits.core.pollers import Select from circuits.tools import inspect, graph -from circuits import Component, Manager, Debugger -from circuits import __version__ as systemVersion -from circuits.web import BaseServer, Server, Controller, Static, wsgi + +from circuits.web.wsgi import Application +from circuits.web.tools import check_auth, digest_auth +from circuits.web import BaseServer, Controller, Logger, Server, Static try: from circuits.core.pollers import Poll @@ -41,7 +44,7 @@ USAGE = "%prog [options] [docroot]" -VERSION = "%prog v" + systemVersion +VERSION = "%prog v" + circuits.__version__ def parse_options(): @@ -53,45 +56,50 @@ help="Bind to address:[port]" ) - if psyco is not None: - parser.add_option( - "-j", "--jit", - action="store_true", default=False, dest="jit", - help="Use python HIT (psyco)" - ) + parser.add_option( + "-l", "--logging", + action="store_true", default=False, dest="logging", + help="Enable logging of requests" + ) + + parser.add_option( + "-p", "--passwd", + action="store", default=None, dest="passwd", + help="Location to passwd file for Digest Auth" + ) parser.add_option( - "-m", "--multiprocessing", - action="store", type="int", default=0, dest="mp", - help="Specify no. of processes to start (multiprocessing)" + "-j", "--jobs", + action="store", type="int", default=0, dest="jobs", + help="Specify no. of jobs/processes to start" ) parser.add_option( - "-t", "--type", - action="store", type="string", default="select", dest="type", + "", "--poller", + action="store", type="string", default="select", dest="poller", help="Specify type of poller to use" ) parser.add_option( - "-s", "--server", + "", "--server", action="store", type="string", default="server", dest="server", help="Specify server to use" ) parser.add_option( - "-p", "--profile", + "", "--profile", action="store_true", default=False, dest="profile", help="Enable execution profiling support" ) parser.add_option( - "-d", "--debug", + "", "--debug", action="store_true", default=False, dest="debug", help="Enable debug mode" ) parser.add_option( - "-v", "--validate", + "", "--validate", action="store_true", default=False, dest="validate", help="Enable WSGI validation mode" ) @@ -101,6 +109,31 @@ return opts, args +class Authentication(Component): + + channel = "web" + + realm = "Secure Area" + users = {"admin": md5("admin").hexdigest()} + + def __init__(self, channel=channel, realm=None, passwd=None): + super(Authentication, self).__init__(self, channel=channel) + + if realm is not None: + self.realm = realm + + if passwd is not None: + with open(passwd, "r") as f: + lines = (line.strip() for line in f) + self.users = dict((line.split(":", 1) for line in lines)) + + @handler("request", priority=10) + def request(self, event, request, response): + if not check_auth(request, response, self.realm, self.users): + event.stop() + return digest_auth(request, response, self.realm, self.users) + + class HelloWorld(Component): channel = "web" @@ -115,50 +148,58 @@ return "Hello World!" -def main(): - opts, args = parse_options() +def select_poller(poller): + if poller == "poll": + if Poll is None: + stderr.write( + "No poll support available - defaulting to Select..." + ) + Poller = Select + else: + Poller = Poll + elif poller == "epoll": + if EPoll is None: + stderr.write( + "No epoll support available - defaulting to Select..." + ) + Poller = Select + else: + Poller = EPoll + else: + Poller = Select - if psyco and opts.jit: - psyco.full() + return Poller - if ":" in opts.bind: - address, port = opts.bind.split(":") + +def parse_bind(bind): + if ":" in bind: + address, port = bind.split(":") port = int(port) else: - address, port = opts.bind, 8000 + address, port = bind, 8000 + + return (address, port) - bind = (address, port) + +def main(): + opts, args = parse_options() + + bind = parse_bind(opts.bind) if opts.validate: - application = (wsgi.Application() + Root()) + application = (Application() + Root()) app = validator(application) - httpd = make_server(address, port, app) + httpd = make_server(bind[0], bind[1], app) httpd.serve_forever() raise SystemExit(0) manager = Manager() - if opts.debug: - manager += Debugger() - - poller = opts.type.lower() - if poller == "poll": - if Poll is None: - print("No poll support available - defaulting to Select...") - Poller = Select - else: - Poller = Poll - elif poller == "epoll": - if EPoll is None: - print("No epoll support available - defaulting to Select...") - Poller = Select - else: - Poller = EPoll - else: - Poller = Select + opts.debug and Debugger().register(manager) + Poller = select_poller(opts.poller.lower()) Poller().register(manager) if opts.server.lower() == "base": @@ -172,17 +213,20 @@ Static(docroot=docroot, dirlisting=True).register(manager) - if opts.profile: - if hotshot: - profiler = hotshot.Profile(".profile") - profiler.start() + opts.passwd and Authentication(passwd=opts.passwd).register(manager) + + opts.logging and Logger().register(manager) + + if opts.profile and hotshot: + profiler = hotshot.Profile(".profile") + profiler.start() if opts.debug: print(graph(manager, name="circuits.web")) print() print(inspect(manager)) - for i in range(opts.mp): + for i in range(opts.jobs): manager.start(process=True) manager.run() diff -Nru circuits-2.1.0/circuits/web/parsers/http.py circuits-3.1.0+ds1/circuits/web/parsers/http.py --- circuits-2.1.0/circuits/web/parsers/http.py 1970-01-01 00:00:00.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/web/parsers/http.py 2014-09-20 22:36:35.000000000 +0000 @@ -0,0 +1,435 @@ +# -*- coding: utf-8 - +# +# This file is part of http-parser released under the MIT license. +# See the NOTICE for more information. +# +# This module is liberally borrowed (with modifications) from: https://raw.githubusercontent.com/benoitc/http-parser/master/http_parser/pyparser.py + + +import re +import zlib + + +try: + import urlparse + from urllib import unquote +except ImportError: + import urllib.parse as urlparse # NOQA + from urllib.parse import unquote # NOQA + + +from circuits.six import b, bytes_to_str, MAXSIZE + + +from ..headers import Headers + + +METHOD_RE = re.compile("^[A-Z0-9$-_.]{1,20}$") +VERSION_RE = re.compile("^HTTP/(\d+).(\d+)$") +STATUS_RE = re.compile("^(\d{3})(?:\s+([\s\w]*))$") +HEADER_RE = re.compile("[\x00-\x1F\x7F()<>@,;:/\[\]={} \t\\\\\"]") + +# errors +BAD_FIRST_LINE = 0 +INVALID_HEADER = 1 +INVALID_CHUNK = 2 + + +class InvalidRequestLine(Exception): + """ error raised when first line is invalid """ + + +class InvalidHeader(Exception): + """ error raised on invalid header """ + + +class InvalidChunkSize(Exception): + """ error raised when we parse an invalid chunk size """ + + +class HttpParser(object): + + def __init__(self, kind=2, decompress=False): + self.kind = kind + self.decompress = decompress + + # errors vars + self.errno = None + self.errstr = "" + + # protected variables + self._buf = [] + self._version = None + self._method = None + self._status_code = None + self._status = None + self._reason = None + self._url = None + self._path = None + self._query_string = None + self._headers = Headers([]) + self._environ = dict() + self._chunked = False + self._body = [] + self._trailers = None + self._partial_body = False + self._clen = None + self._clen_rest = None + + # private events + self.__on_firstline = False + self.__on_headers_complete = False + self.__on_message_begin = False + self.__on_message_complete = False + + self.__decompress_obj = None + + def get_version(self): + return self._version + + def get_method(self): + return self._method + + def get_status_code(self): + return self._status_code + + def get_url(self): + return self._url + + def get_scheme(self): + return self._scheme + + def get_path(self): + return self._path + + def get_query_string(self): + return self._query_string + + def get_headers(self): + return self._headers + + def recv_body(self): + """ return last chunk of the parsed body""" + body = b("").join(self._body) + self._body = [] + self._partial_body = False + return body + + def recv_body_into(self, barray): + """ Receive the last chunk of the parsed bodyand store the data + in a buffer rather than creating a new string. """ + l = len(barray) + body = b("").join(self._body) + m = min(len(body), l) + data, rest = body[:m], body[m:] + barray[0:m] = data + if not rest: + self._body = [] + self._partial_body = False + else: + self._body = [rest] + return m + + def is_upgrade(self): + """ Do we get upgrade header in the request. Useful for + websockets """ + return self._headers.get('connection', "").lower() == "upgrade" + + def is_headers_complete(self): + """ return True if all headers have been parsed. """ + return self.__on_headers_complete + + def is_partial_body(self): + """ return True if a chunk of body have been parsed """ + return self._partial_body + + def is_message_begin(self): + """ return True if the parsing start """ + return self.__on_message_begin + + def is_message_complete(self): + """ return True if the parsing is done (we get EOF) """ + return self.__on_message_complete + + def is_chunked(self): + """ return True if Transfer-Encoding header value is chunked""" + return self._chunked + + def should_keep_alive(self): + """ return True if the connection should be kept alive + """ + hconn = self._headers.get('connection', "").lower() + if hconn == "close": + return False + elif hconn == "keep-alive": + return True + return self._version == (1, 1) + + def execute(self, data, length): + # end of body can be passed manually by putting a length of 0 + + if length == 0: + self.on_message_complete = True + return length + + # start to parse + nb_parsed = 0 + while True: + if not self.__on_firstline: + idx = data.find(b("\r\n")) + if idx < 0: + self._buf.append(data) + return len(data) + else: + self.__on_firstline = True + self._buf.append(data[:idx]) + first_line = bytes_to_str(b("").join(self._buf)) + nb_parsed = nb_parsed + idx + 2 + + rest = data[idx+2:] + data = b("") + if self._parse_firstline(first_line): + self._buf = [rest] + else: + return nb_parsed + elif not self.__on_headers_complete: + if data: + self._buf.append(data) + data = b("") + + try: + to_parse = b("").join(self._buf) + ret = self._parse_headers(to_parse) + if not ret: + return length + nb_parsed = nb_parsed + (len(to_parse) - ret) + except InvalidHeader as e: + self.errno = INVALID_HEADER + self.errstr = str(e) + return nb_parsed + elif not self.__on_message_complete: + if not self.__on_message_begin: + self.__on_message_begin = True + + if data: + self._buf.append(data) + data = b("") + + ret = self._parse_body() + if ret is None: + return length + + elif ret < 0: + return ret + elif ret == 0: + self.__on_message_complete = True + return length + else: + nb_parsed = max(length, ret) + + else: + return 0 + + def _parse_firstline(self, line): + try: + if self.kind == 2: # auto detect + try: + self._parse_request_line(line) + except InvalidRequestLine: + self._parse_response_line(line) + elif self.kind == 1: + self._parse_response_line(line) + elif self.kind == 0: + self._parse_request_line(line) + except InvalidRequestLine as e: + self.errno = BAD_FIRST_LINE + self.errstr = str(e) + return False + return True + + def _parse_response_line(self, line): + bits = line.split(None, 1) + if len(bits) != 2: + raise InvalidRequestLine(line) + + # version + matchv = VERSION_RE.match(bits[0]) + if matchv is None: + raise InvalidRequestLine("Invalid HTTP version: %s" % bits[0]) + self._version = (int(matchv.group(1)), int(matchv.group(2))) + + # status + matchs = STATUS_RE.match(bits[1]) + if matchs is None: + raise InvalidRequestLine("Invalid status %" % bits[1]) + + self._status = bits[1] + self._status_code = int(matchs.group(1)) + self._reason = matchs.group(2) + + def _parse_request_line(self, line): + bits = line.split(None, 2) + if len(bits) != 3: + raise InvalidRequestLine(line) + + # Method + if not METHOD_RE.match(bits[0]): + raise InvalidRequestLine("invalid Method: %s" % bits[0]) + self._method = bits[0].upper() + + # URI + self._url = bits[1] + parts = urlparse.urlsplit(bits[1]) + self._scheme = parts.scheme or None + self._path = parts.path or "" + self._query_string = parts.query or "" + if parts.fragment: + raise InvalidRequestLine( + "HTTP requests may not contain fragment(s)" + ) + + # Version + match = VERSION_RE.match(bits[2]) + if match is None: + raise InvalidRequestLine("Invalid HTTP version: %s" % bits[2]) + self._version = (int(match.group(1)), int(match.group(2))) + + # update environ + if hasattr(self, 'environ'): + self._environ.update({ + "PATH_INFO": self._path, + "QUERY_STRING": self._query_string, + "RAW_URI": self._url, + "REQUEST_METHOD": self._method, + "SERVER_PROTOCOL": bits[2]}) + + def _parse_headers(self, data): + idx = data.find(b("\r\n\r\n")) + if idx < 0: # we don't have all headers + return False + + # Split lines on \r\n keeping the \r\n on each line + lines = [bytes_to_str(line) + "\r\n" + for line in data[:idx].split(b("\r\n"))] + + # Parse headers into key/value pairs paying attention + # to continuation lines. + while len(lines): + # Parse initial header name : value pair. + curr = lines.pop(0) + if curr.find(":") < 0: + raise InvalidHeader("invalid line %s" % curr.strip()) + name, value = curr.split(":", 1) + name = name.rstrip(" \t").upper() + if HEADER_RE.search(name): + raise InvalidHeader("invalid header name %s" % name) + name, value = name.strip(), [value.lstrip()] + + # Consume value continuation lines + while len(lines) and lines[0].startswith((" ", "\t")): + value.append(lines.pop(0)) + value = ''.join(value).rstrip() + + # store new header value + self._headers.add_header(name, value) + + # update WSGI environ + key = 'HTTP_%s' % name.upper().replace('-', '_') + self._environ[key] = value + + # detect now if body is sent by chunks. + clen = self._headers.get('content-length') + te = self._headers.get('transfer-encoding', '').lower() + + if clen is not None: + try: + self._clen_rest = self._clen = int(clen) + except ValueError: + pass + else: + self._chunked = (te == 'chunked') + if not self._chunked: + self._clen_rest = MAXSIZE + + # detect encoding and set decompress object + encoding = self._headers.get('content-encoding') + if self.decompress: + if encoding == "gzip": + self.__decompress_obj = zlib.decompressobj(16+zlib.MAX_WBITS) + elif encoding == "deflate": + self.__decompress_obj = zlib.decompressobj() + + rest = data[idx+4:] + self._buf = [rest] + self.__on_headers_complete = True + return len(rest) + + def _parse_body(self): + if not self._chunked: + body_part = b("").join(self._buf) + self._clen_rest -= len(body_part) + + # maybe decompress + if self.__decompress_obj is not None: + body_part = self.__decompress_obj.decompress(body_part) + + self._partial_body = True + self._body.append(body_part) + self._buf = [] + + if self._clen_rest <= 0: + self.__on_message_complete = True + return + else: + data = b("").join(self._buf) + try: + + size, rest = self._parse_chunk_size(data) + except InvalidChunkSize as e: + self.errno = INVALID_CHUNK + self.errstr = "invalid chunk size [%s]" % str(e) + return -1 + + if size == 0: + return size + + if size is None or len(rest) < size: + return None + + body_part, rest = rest[:size], rest[size:] + if len(rest) < 2: + self.errno = INVALID_CHUNK + self.errstr = "chunk missing terminator [%s]" % data + return -1 + + # maybe decompress + if self.__decompress_obj is not None: + body_part = self.__decompress_obj.decompress(body_part) + + self._partial_body = True + self._body.append(body_part) + + self._buf = [rest[2:]] + return len(rest) + + def _parse_chunk_size(self, data): + idx = data.find(b("\r\n")) + if idx < 0: + return None, None + line, rest_chunk = data[:idx], data[idx+2:] + chunk_size = line.split(b(";"), 1)[0].strip() + try: + chunk_size = int(chunk_size, 16) + except ValueError: + raise InvalidChunkSize(chunk_size) + + if chunk_size == 0: + self._parse_trailers(rest_chunk) + return 0, None + return chunk_size, rest_chunk + + def _parse_trailers(self, data): + idx = data.find(b("\r\n\r\n")) + + if data[:2] == b("\r\n"): + self._trailers = self._parse_headers(data[:idx]) diff -Nru circuits-2.1.0/circuits/web/parsers/__init__.py circuits-3.1.0+ds1/circuits/web/parsers/__init__.py --- circuits-2.1.0/circuits/web/parsers/__init__.py 1970-01-01 00:00:00.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/web/parsers/__init__.py 2014-09-04 10:32:30.000000000 +0000 @@ -0,0 +1,11 @@ +# Package: parsers +# Date: 26th March 2013 +# Author: James Mills, prologic at shortcircuit dot net dot au + +"""circuits.web parsers""" + +from .multipart import MultipartParser +from .querystring import QueryStringParser +from .http import HttpParser, BAD_FIRST_LINE + +# flake8: noqa diff -Nru circuits-2.1.0/circuits/web/parsers/multipart.py circuits-3.1.0+ds1/circuits/web/parsers/multipart.py --- circuits-2.1.0/circuits/web/parsers/multipart.py 1970-01-01 00:00:00.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/web/parsers/multipart.py 2014-09-04 10:32:30.000000000 +0000 @@ -0,0 +1,415 @@ +# -*- coding: utf-8 -*- +''' +Parser for multipart/form-data +============================== + +This module provides a parser for the multipart/form-data format. It can read +from a file, a socket or a WSGI environment. The parser can be used to replace +cgi.FieldStorage (without the bugs) and works with Python 2.5+ and 3.x (2to3). + +Licence (MIT) +------------- + + Copyright (c) 2010, Marcel Hellkamp. + Inspired by the Werkzeug library: http://werkzeug.pocoo.org/ + + 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. + +''' + +__author__ = 'Marcel Hellkamp' +__version__ = '0.1' +__license__ = 'MIT' + +from tempfile import TemporaryFile +from wsgiref.headers import Headers +import re, sys +try: + from urlparse import parse_qs +except ImportError: # pragma: no cover (fallback for Python 2.5) + from cgi import parse_qs +try: + from io import BytesIO +except ImportError: # pragma: no cover (fallback for Python 2.5) + from StringIO import StringIO as BytesIO + +from circuits.six import text_type + +############################################################################## +################################ Helper & Misc ################################ +############################################################################## +# Some of these were copied from bottle: http://bottle.paws.de/ + +try: + from collections import MutableMapping as DictMixin +except ImportError: # pragma: no cover (fallback for Python 2.5) + from UserDict import DictMixin + +class MultiDict(DictMixin): + """ A dict that remembers old values for each key """ + def __init__(self, *a, **k): + self.dict = dict() + for k, v in dict(*a, **k).iteritems(): + self[k] = v + + def __len__(self): return len(self.dict) + def __iter__(self): return iter(self.dict) + def __contains__(self, key): return key in self.dict + def __delitem__(self, key): del self.dict[key] + def keys(self): return self.dict.keys() + def __getitem__(self, key): return self.get(key, KeyError, -1) + def __setitem__(self, key, value): self.append(key, value) + + def append(self, key, value): self.dict.setdefault(key, []).append(value) + def replace(self, key, value): self.dict[key] = [value] + def getall(self, key): return self.dict.get(key) or [] + + def get(self, key, default=None, index=-1): + if key not in self.dict and default != KeyError: + return [default][index] + return self.dict[key][index] + + def iterallitems(self): + for key, values in self.dict.iteritems(): + for value in values: + yield key, value + +def tob(data, enc='utf8'): # Convert strings to bytes (py2 and py3) + return data.encode(enc) if isinstance(data, text_type) else data + +def copy_file(stream, target, maxread=-1, buffer_size=2*16): + ''' Read from :stream and write to :target until :maxread or EOF. ''' + size, read = 0, stream.read + while 1: + to_read = buffer_size if maxread < 0 else min(buffer_size, maxread-size) + part = read(to_read) + if not part: return size + target.write(part) + size += len(part) + +############################################################################## +################################ Header Parser ################################ +############################################################################## + +_special = re.escape('()<>@,;:\\"/[]?={} \t') +_re_special = re.compile('[%s]' % _special) +_qstr = '"(?:\\\\.|[^"])*"' # Quoted string +_value = '(?:[^%s]+|%s)' % (_special, _qstr) # Save or quoted string +_option = '(?:;|^)\s*([^%s]+)\s*=\s*(%s)' % (_special, _value) +_re_option = re.compile(_option) # key=value part of an Content-Type like header + +def header_quote(val): + if not _re_special.search(val): + return val + return '"' + val.replace('\\','\\\\').replace('"','\\"') + '"' + +def header_unquote(val, filename=False): + if val[0] == val[-1] == '"': + val = val[1:-1] + if val[1:3] == ':\\' or val[:2] == '\\\\': + val = val.split('\\')[-1] # fix ie6 bug: full path --> filename + return val.replace('\\\\','\\').replace('\\"','"') + return val + +def parse_options_header(header, options=None): + if ';' not in header: + return header.lower().strip(), {} + ctype, tail = header.split(';', 1) + options = options or {} + for match in _re_option.finditer(tail): + key = match.group(1).lower() + value = header_unquote(match.group(2), key=='filename') + options[key] = value + return ctype, options + +############################################################################## +################################## Multipart ################################## +############################################################################## + + +class MultipartError(ValueError): pass + + +class MultipartParser(object): + + def __init__(self, stream, boundary, content_length=-1, + disk_limit=2**30, mem_limit=2**20, memfile_limit=2**18, + buffer_size=2**16, charset='latin1'): + ''' Parse a multipart/form-data byte stream. This object is an iterator + over the parts of the message. + + :param stream: A file-like stream. Must implement ``.read(size)``. + :param boundary: The multipart boundary as a byte string. + :param content_length: The maximum number of bytes to read. + ''' + self.stream, self.boundary = stream, boundary + self.content_length = content_length + self.disk_limit = disk_limit + self.memfile_limit = memfile_limit + self.mem_limit = min(mem_limit, self.disk_limit) + self.buffer_size = min(buffer_size, self.mem_limit) + self.charset = charset + if self.buffer_size - 6 < len(boundary): # "--boundary--\r\n" + raise MultipartError('Boundary does not fit into buffer_size.') + self._done = [] + self._part_iter = None + + def __iter__(self): + ''' Iterate over the parts of the multipart message. ''' + if not self._part_iter: + self._part_iter = self._iterparse() + for part in self._done: + yield part + for part in self._part_iter: + self._done.append(part) + yield part + + def parts(self): + ''' Returns a list with all parts of the multipart message. ''' + return list(iter(self)) + + def get(self, name, default=None): + ''' Return the first part with that name or a default value (None). ''' + for part in self: + if name == part.name: + return part + return default + + def get_all(self, name): + ''' Return a list of parts with that name. ''' + return [p for p in self if p.name == name] + + def _lineiter(self): + ''' Iterate over a binary file-like object line by line. Each line is + returned as a (line, line_ending) tuple. If the line does not fit + into self.buffer_size, line_ending is empty and the rest of the line + is returned with the next iteration. + ''' + read = self.stream.read + maxread, maxbuf = self.content_length, self.buffer_size + _bcrnl = tob('\r\n') + _bcr = _bcrnl[:1] + _bnl = _bcrnl[1:] + _bempty = _bcrnl[:0] # b'rn'[:0] -> b'' + buffer = _bempty # buffer for the last (partial) line + while 1: + data = read(maxbuf if maxread < 0 else min(maxbuf, maxread)) + maxread -= len(data) + lines = (buffer+data).splitlines(True) + len_first_line = len(lines[0]) + # be sure that the first line does not become too big + if len_first_line > self.buffer_size: + # at the same time don't split a '\r\n' accidentally + if (len_first_line == self.buffer_size+1 and + lines[0].endswith(_bcrnl)): + splitpos = self.buffer_size - 1 + else: + splitpos = self.buffer_size + lines[:1] = [lines[0][:splitpos], + lines[0][splitpos:]] + if data: + buffer = lines[-1] + lines = lines[:-1] + for line in lines: + if line.endswith(_bcrnl): yield line[:-2], _bcrnl + elif line.endswith(_bnl): yield line[:-1], _bnl + elif line.endswith(_bcr): yield line[:-1], _bcr + else: yield line, _bempty + if not data: + break + + def _iterparse(self): + lines, line = self._lineiter(), '' + separator = tob('--') + tob(self.boundary) + terminator = tob('--') + tob(self.boundary) + tob('--') + # Consume first boundary. Ignore leading blank lines + for line, nl in lines: + if line: break + if line != separator: + raise MultipartError("Stream does not start with boundary") + # For each part in stream... + mem_used, disk_used = 0, 0 # Track used resources to prevent DoS + is_tail = False # True if the last line was incomplete (cutted) + opts = {'buffer_size': self.buffer_size, + 'memfile_limit': self.memfile_limit, + 'charset': self.charset} + part = MultipartPart(**opts) + for line, nl in lines: + if line == terminator and not is_tail: + part.file.seek(0) + yield part + break + elif line == separator and not is_tail: + if part.is_buffered(): mem_used += part.size + else: disk_used += part.size + part.file.seek(0) + yield part + part = MultipartPart(**opts) + else: + is_tail = not nl # The next line continues this one + part.feed(line, nl) + if part.is_buffered(): + if part.size + mem_used > self.mem_limit: + raise MultipartError("Memory limit reached.") + elif part.size + disk_used > self.disk_limit: + raise MultipartError("Disk limit reached.") + if line != terminator: + raise MultipartError("Unexpected end of multipart stream.") + + +class MultipartPart(object): + + def __init__(self, buffer_size=2**16, memfile_limit=2**18, charset='latin1'): + self.headerlist = [] + self.headers = None + self.file = False + self.size = 0 + self._buf = tob('') + self.disposition, self.name, self.filename = None, None, None + self.content_type, self.charset = None, charset + self.memfile_limit = memfile_limit + self.buffer_size = buffer_size + + def feed(self, line, nl=''): + if self.file: + return self.write_body(line, nl) + return self.write_header(line, nl) + + def write_header(self, line, nl): + line = line.decode(self.charset or 'latin1') + if not nl: raise MultipartError('Unexpected end of line in header.') + if not line.strip(): # blank line -> end of header segment + self.finish_header() + elif line[0] in ' \t' and self.headerlist: + name, value = self.headerlist.pop() + self.headerlist.append((name, value+line.strip())) + else: + if ':' not in line: + raise MultipartError("Syntax error in header: No colon.") + name, value = line.split(':', 1) + self.headerlist.append((name.strip(), value.strip())) + + def write_body(self, line, nl): + if not line and not nl: return # This does not even flush the buffer + self.size += len(line) + len(self._buf) + self.file.write(self._buf + line) + self._buf = nl + if self.content_length > 0 and self.size > self.content_length: + raise MultipartError('Size of body exceeds Content-Length header.') + if self.size > self.memfile_limit and isinstance(self.file, BytesIO): + # TODO: What about non-file uploads that exceed the memfile_limit? + self.file, old = TemporaryFile(mode='w+b'), self.file + old.seek(0) + copy_file(old, self.file, self.size, self.buffer_size) + + def finish_header(self): + self.file = BytesIO() + self.headers = Headers(self.headerlist) + cdis = self.headers.get('Content-Disposition','') + ctype = self.headers.get('Content-Type','') + clen = self.headers.get('Content-Length','-1') + if not cdis: + raise MultipartError('Content-Disposition header is missing.') + self.disposition, self.options = parse_options_header(cdis) + self.name = self.options.get('name') + self.filename = self.options.get('filename') + self.content_type, options = parse_options_header(ctype) + self.charset = options.get('charset') or self.charset + self.content_length = int(self.headers.get('Content-Length','-1')) + + def is_buffered(self): + ''' Return true if the data is fully buffered in memory.''' + return isinstance(self.file, BytesIO) + + @property + def value(self): + ''' Data decoded with the specified charset ''' + pos = self.file.tell() + self.file.seek(0) + val = self.file.read() + self.file.seek(pos) + return val.decode(self.charset) + + def save_as(self, path): + fp = open(path, 'wb') + pos = self.file.tell() + try: + self.file.seek(0) + size = copy_file(self.file, fp) + finally: + self.file.seek(pos) + return size + +############################################################################## +#################################### WSGI #################################### +############################################################################## + +def parse_form_data(environ, charset='utf8', strict=False, **kw): + ''' Parse form data from an environ dict and return a (forms, files) tuple. + Both tuple values are dictionaries with the form-field name as a key + (text_type) and lists as values (multiple values per key are possible). + The forms-dictionary contains form-field values as text_type strings. + The files-dictionary contains :class:`MultipartPart` instances, either + because the form-field was a file-upload or the value is to big to fit + into memory limits. + + :param environ: An WSGI environment dict. + :param charset: The charset to use if unsure. (default: utf8) + :param strict: If True, raise :exc:`MultipartError` on any parsing + errors. These are silently ignored by default. + ''' + + forms, files = MultiDict(), MultiDict() + try: + if environ.get('REQUEST_METHOD','GET').upper() not in ('POST', 'PUT'): + raise MultipartError("Request method other than POST or PUT.") + content_length = int(environ.get('CONTENT_LENGTH', '-1')) + content_type = environ.get('CONTENT_TYPE', '') + if not content_type: + raise MultipartError("Missing Content-Type header.") + content_type, options = parse_options_header(content_type) + stream = environ.get('wsgi.input') or BytesIO() + kw['charset'] = charset = options.get('charset', charset) + if content_type == 'multipart/form-data': + boundary = options.get('boundary','') + if not boundary: + raise MultipartError("No boundary for multipart/form-data.") + for part in MultipartParser(stream, boundary, content_length, **kw): + if part.filename or not part.is_buffered(): + files[part.name] = part + else: # TODO: Big form-fields are in the files dict. really? + forms[part.name] = part.value + elif content_type in ('application/x-www-form-urlencoded', + 'application/x-url-encoded'): + mem_limit = kw.get('mem_limit', 2**20) + if content_length > mem_limit: + raise MultipartError("Request to big. Increase MAXMEM.") + data = stream.read(mem_limit).decode(charset) + if stream.read(1): # These is more that does not fit mem_limit + raise MultipartError("Request to big. Increase MAXMEM.") + data = parse_qs(data, keep_blank_values=True) + for key, values in data.iteritems(): + for value in values: + forms[key] = value + else: + raise MultipartError("Unsupported content type.") + except MultipartError: + if strict: raise + return forms, files + diff -Nru circuits-2.1.0/circuits/web/parsers/querystring.py circuits-3.1.0+ds1/circuits/web/parsers/querystring.py --- circuits-2.1.0/circuits/web/parsers/querystring.py 1970-01-01 00:00:00.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/web/parsers/querystring.py 2014-09-04 10:32:30.000000000 +0000 @@ -0,0 +1,147 @@ +# -*- coding: utf-8 -*- + + +try: + from urlparse import parse_qsl +except ImportError: + from urllib.parse import parse_qsl # NOQA + + +from circuits.six import iteritems, string_types + + +class QueryStringToken(object): + + ARRAY = "ARRAY" + OBJECT = "OBJECT" + KEY = "KEY" + + +class QueryStringParser(object): + + def __init__(self, data): + self.result = {} + + if isinstance(data, string_types[0]): + sorted_pairs = self._sorted_from_string(data) + else: + sorted_pairs = self._sorted_from_obj(data) + + [self.process(x) for x in sorted_pairs] + + def _sorted_from_string(self, data): + stage1 = parse_qsl(data, keep_blank_values=True) + stage2 = [(x[0].strip(), x[1].strip()) for x in stage1] + return sorted(stage2, key=lambda p: p[0]) + + def _sorted_from_obj(self, data): + # data is a list of the type generated by parse_qsl + if isinstance(data, list): + items = data + else: + # complex objects: + try: + # django.http.QueryDict, + items = [(i[0], j) for i in data.lists() for j in i[1]] + except AttributeError: + # webob.multidict.MultiDict + # werkzeug.datastructures.MultiDict + items = iteritems(data) + + return sorted(items, key=lambda p: p[0]) + + def process(self, pair): + key = pair[0] + value = pair[1] + + #faster than invoking a regex + try: + key.index("[") + self.parse(key, value) + return + except ValueError: + pass + + try: + key.index(".") + self.parse(key, value) + return + except ValueError: + pass + + self.result[key] = value + + def parse(self, key, value): + ref = self.result + tokens = self.tokens(key) + + for token in tokens: + token_type, key = token + + if token_type == QueryStringToken.ARRAY: + if key not in ref: + ref[key] = [] + ref = ref[key] + + elif token_type == QueryStringToken.OBJECT: + if key not in ref: + ref[key] = {} + ref = ref[key] + + elif token_type == QueryStringToken.KEY: + try: + ref = ref[key] + next(tokens) + # TypeError is for pet[]=lucy&pet[]=ollie + # if the array key is empty a type error will be raised + except (IndexError, KeyError, TypeError): + # the index didn't exist + # so we look ahead to see what we are setting + # there is not a next token + # set the value + try: + + next_token = next(tokens) + + if next_token[0] == QueryStringToken.ARRAY: + ref.append([]) + ref = ref[key] + elif next_token[0] == QueryStringToken.OBJECT: + + try: + ref[key] = {} + except IndexError: + ref.append({}) + + ref = ref[key] + except StopIteration: + try: + ref.append(value) + except AttributeError: + ref[key] = value + return + + def tokens(self, key): + buf = "" + for char in key: + if char == "[": + yield QueryStringToken.ARRAY, buf + buf = "" + + elif char == ".": + yield QueryStringToken.OBJECT, buf + buf = "" + + elif char == "]": + try: + yield QueryStringToken.KEY, int(buf) + buf = "" + except ValueError: + yield QueryStringToken.KEY, None + else: + buf = buf + char + + if len(buf) > 0: + yield QueryStringToken.KEY, buf + else: + raise StopIteration() diff -Nru circuits-2.1.0/circuits/web/processors.py circuits-3.1.0+ds1/circuits/web/processors.py --- circuits-2.1.0/circuits/web/processors.py 1970-01-01 00:00:00.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/web/processors.py 2014-09-04 10:32:30.000000000 +0000 @@ -0,0 +1,56 @@ +import re +from cgi import parse_header + +from .headers import HeaderElement +from .parsers import MultipartParser +from .parsers import QueryStringParser + + +def process_multipart(request, params): + headers = request.headers + + ctype = headers.elements("Content-Type") + if ctype: + ctype = ctype[0] + else: + ctype = HeaderElement.from_str("application/x-www-form-urlencoded") + + ib = "" + if "boundary" in ctype.params: + # http://tools.ietf.org/html/rfc2046#section-5.1.1 + # "The grammar for parameters on the Content-type field is such that it + # is often necessary to enclose the boundary parameter values in quotes + # on the Content-type line" + ib = ctype.params["boundary"].strip("\"") + + if not re.match("^[ -~]{0,200}[!-~]$", ib): + raise ValueError("Invalid boundary in multipart form: %r" % (ib,)) + + parser = MultipartParser(request.body, ib) + for part in parser: + if part.filename or not part.is_buffered(): + params[part.name] = part + else: + params[part.name] = part.value + + +def process_urlencoded(request, params, encoding="utf-8"): + params.update(QueryStringParser(request.qs).result) + body = request.body.getvalue().decode(encoding) + params.update(QueryStringParser(body).result) + + +def process(request, params): + ctype = request.headers.get("Content-Type") + if not ctype: + return + + mtype, mencoding = ctype.split("/", 1) if "/" in ctype else (ctype, None) + mencoding, extra = parse_header(mencoding) + + charset = extra.get("charset", "utf-8") + + if mtype == "multipart": + process_multipart(request, params) + elif mtype == "application" and mencoding == "x-www-form-urlencoded": + process_urlencoded(request, params, encoding=charset) diff -Nru circuits-2.1.0/circuits/web/servers.py circuits-3.1.0+ds1/circuits/web/servers.py --- circuits-2.1.0/circuits/web/servers.py 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/web/servers.py 2014-09-04 10:32:30.000000000 +0000 @@ -2,22 +2,23 @@ # Date: 6th November 2008 # Author: James Mills, prologic at shortcircuit dot net dot au + """Web Servers This module implements the several Web Server components. """ -from circuits.core import handler, BaseComponent -from circuits import io +from sys import stderr -from circuits.net.sockets import Read, Write + +from circuits import io +from circuits.net.events import close, read, write from circuits.net.sockets import TCPServer, UNIXServer +from circuits.core import handler, BaseComponent, Timer from .http import HTTP -from .events import WebEvent -from .wrappers import Request, Host -from .constants import SERVER_VERSION +from .events import terminate from .dispatchers import Dispatcher @@ -60,13 +61,10 @@ super(BaseServer, self).__init__(channel=channel) - if type(bind) in (int, list, tuple): + if isinstance(bind, (int, list, tuple,)): SocketType = TCPServer else: - if ":" in bind: - SocketType = TCPServer - else: - SocketType = UNIXServer + SocketType = TCPServer if ":" in bind else UNIXServer self.server = SocketType( bind, @@ -75,21 +73,9 @@ channel=channel ).register(self) - HTTP(encoding=encoding, channel=channel).register(self) - - Request.server = self - if isinstance(self.server._bind, tuple): - Request.local = Host( - self.server._bind[0], self.server._bind[1] - ) - else: - Request.local = Host(self.server._bind, None) - Request.host = self.host - Request.scheme = "https" if self.server.secure else "http" - - @property - def version(self): - return SERVER_VERSION + self.http = HTTP( + self, encoding=encoding, channel=channel + ).register(self) @property def host(self): @@ -106,25 +92,32 @@ if hasattr(self, "server"): return self.server.secure - @property - def scheme(self): - return "https" if self.secure else "http" - - @property - def base(self): - host = self.host or "0.0.0.0" - port = self.port or 80 - scheme = self.scheme - secure = self.secure - - tpl = "%s://%s%s" - - if (port == 80 and not secure) or (port == 443 and secure): - port = "" - else: - port = ":%d" % port - - return tpl % (scheme, host, port) + @handler("connect") + def _on_connect(self, *args, **kwargs): + """Dummy Event Handler for connect""" + + @handler("closed") + def _on_closed(self, *args, **kwargs): + """Dummy Event Handler for closed""" + + @handler("signal") + def _on_signal(self, *args, **kwargs): + """signal Event Handler""" + + self.fire(close()) + Timer(3, terminate()).register(self) + + @handler("terminate") + def _on_terminate(self): + raise SystemExit(0) + + @handler("ready") + def _on_ready(self, server, bind): + stderr.write( + "{0:s} ready! Listening on: {1:s}\n".format( + self.http.version, self.http.base + ) + ) class Server(BaseServer): @@ -142,7 +135,7 @@ super(Server, self).__init__(bind, **kwargs) - Dispatcher(channel=self.channel).register(self) + Dispatcher(channel=self.channel).register(self.http) class FakeSock(): @@ -157,23 +150,29 @@ def __init__(self, encoding="utf-8", channel=channel): super(StdinServer, self).__init__(channel=channel) - WebEvent.channels = (channel,) + self.server = (io.stdin + io.stdout).register(self) + self.http = HTTP( + self, encoding=encoding, channel=channel + ).register(self) - self.server = ( - io.stdin - + io.stdout - + HTTP(encoding=encoding, channel=channel) - ) + Dispatcher(channel=self.channel).register(self) - self += self.server + @property + def host(self): + return io.stdin.filename - Request.server = self - Dispatcher(channel=self.channel).register(self) + @property + def port(self): + return 0 + + @property + def secure(self): + return False @handler("read", channel="stdin") def read(self, data): - self.fire(Read(FakeSock(), data)) + self.fire(read(FakeSock(), data)) @handler("write") def write(self, sock, data): - self.fire(Write(data)) + self.fire(write(data)) diff -Nru circuits-2.1.0/circuits/web/sessions.py circuits-3.1.0+ds1/circuits/web/sessions.py --- circuits-2.1.0/circuits/web/sessions.py 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/web/sessions.py 2014-09-04 10:32:30.000000000 +0000 @@ -2,41 +2,84 @@ # Date: 22nd February 2009 # Author: James Mills, prologic at shortcircuit dot net dot au + """Session Components This module implements Session Components that can be used to store and access persistent information. """ + from uuid import uuid4 as uuid +from hashlib import sha1 as sha from collections import defaultdict + from circuits import handler, Component +def who(request, encoding="utf-8"): + """Create a SHA1 Hash of the User's IP Address and User-Agent""" + + ip = request.remote.ip + agent = request.headers.get("User-Agent", "") + + return sha("{0:s}{1:s}".format(ip, agent).encode(encoding)).hexdigest() + + +def create_session(request): + """Create a unique session id from the request + + Returns a unique session using ``uuid4()`` and a ``sha1()`` hash + of the users IP Address and User Agent in the form of ``sid/who``. + """ + + return "{0:s}/{1:s}".format(uuid().hex, who(request)) + + +def verify_session(request, sid): + """Verify a User's Session + + This verifies the User's Session by verifying the SHA1 Hash + of the User's IP Address and User-Agent match the provided + Session ID. + """ + + if "/" not in sid: + return create_session(request) + + user = sid.split("/", 1)[1] + + if user != who(request): + return create_session(request) + + return sid + + class Sessions(Component): channel = "web" - def __init__(self, name="circuits.session", *args, **kwargs): - super(Sessions, self).__init__(*args, **kwargs) + def __init__(self, name="circuits.session", channel=channel): + super(Sessions, self).__init__(channel=channel) self._name = name self._data = defaultdict(dict) - def _load(self, id): - return self._data[id] + def load(self, sid): + return self._data[sid] - def _save(self, id, data): - self._data[id] = data + def save(self, sid, data): + """Save User Session Data for sid""" @handler("request", priority=10) def request(self, request, response): if self._name in request.cookie: - id = request.cookie[self._name].value + sid = request.cookie[self._name].value + sid = verify_session(request, sid) else: - id = str(uuid()) + sid = create_session(request) - request.sid = id - request.session = self._load(id) - response.cookie[self._name] = id + request.sid = sid + request.session = self.load(sid) + response.cookie[self._name] = sid diff -Nru circuits-2.1.0/circuits/web/tools.py circuits-3.1.0+ds1/circuits/web/tools.py --- circuits-2.1.0/circuits/web/tools.py 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/web/tools.py 2014-09-04 10:32:30.000000000 +0000 @@ -12,20 +12,21 @@ import stat import hashlib import mimetypes +import collections from time import mktime from email.utils import formatdate from datetime import datetime, timedelta from email.generator import _make_boundary -import collections mimetypes.init() mimetypes.add_type("image/x-dwg", ".dwg") mimetypes.add_type("image/x-icon", ".ico") +mimetypes.add_type("text/javascript", ".js") mimetypes.add_type("application/xhtml+xml", ".xhtml") from . import _httpauth from .utils import get_ranges, compress -from .errors import HTTPError, NotFound, Redirect, Unauthorized +from .errors import httperror, notfound, redirect, unauthorized def expires(request, response, secs=0, force=False): @@ -97,12 +98,12 @@ try: st = os.stat(path) except OSError: - return NotFound(request, response) + return notfound(request, response) # Check if path is a directory. if stat.S_ISDIR(st.st_mode): # Let the caller deal with it as they like. - return NotFound(request, response) + return notfound(request, response) # Set the Last-Modified response header, so that # modified-since validation code can work. @@ -140,13 +141,13 @@ r = get_ranges(request.headers.get('Range'), c_len) if r == []: response.headers['Content-Range'] = "bytes */%s" % c_len - return HTTPError(request, response, 416) + return httperror(request, response, 416) if r: if len(r) == 1: # Return a single-part response. start, stop = r[0] r_len = stop - start - response.code = 206 + response.status = 206 response.headers['Content-Range'] = ( "bytes %s-%s/%s" % (start, stop - 1, c_len) ) @@ -155,7 +156,7 @@ response.body = bodyfile.read(r_len) else: # Return a multipart/byteranges response. - response.code = 206 + response.status = 206 boundary = _make_boundary() ct = "multipart/byteranges; boundary=%s" % boundary response.headers['Content-Type'] = ct @@ -221,13 +222,13 @@ if hasattr(response, "ETag"): return - code = response.code + status = response.status etag = response.headers.get('ETag') # Automatic ETag generation. See warning in docstring. if (not etag) and autotags: - if code == 200: + if status == 200: etag = response.collapse_body() etag = '"%s"' % hashlib.md5.new(etag).hexdigest() response.headers['ETag'] = etag @@ -237,11 +238,11 @@ # "If the request would, without the If-Match header field, result in # anything other than a 2xx or 412 status, then the If-Match header # MUST be ignored." - if code >= 200 and code <= 299: + if status >= 200 and status <= 299: conditions = request.headers.elements('If-Match') or [] conditions = [str(x) for x in conditions] if conditions and not (conditions == ["*"] or etag in conditions): - return HTTPError( + return httperror( request, response, 412, description="If-Match failed: ETag %r did not match %r" % ( etag, conditions @@ -252,9 +253,9 @@ conditions = [str(x) for x in conditions] if conditions == ["*"] or etag in conditions: if request.method in ("GET", "HEAD"): - return Redirect(request, response, [], code=304) + return redirect(request, response, [], code=304) else: - return HTTPError( + return httperror( request, response, 412, description=( "If-None-Match failed: ETag %r matched %r" % ( @@ -273,26 +274,26 @@ lastmod = response.headers.get('Last-Modified') if lastmod: - code = response.code + status = response.status since = request.headers.get('If-Unmodified-Since') if since and since != lastmod: - if (code >= 200 and code <= 299) or code == 412: - return HTTPError(request, response, 412) + if (status >= 200 and status <= 299) or status == 412: + return httperror(request, response, 412) since = request.headers.get('If-Modified-Since') if since and since == lastmod: - if (code >= 200 and code <= 299) or code == 304: + if (status >= 200 and status <= 299) or status == 304: if request.method in ("GET", "HEAD"): - return Redirect(request, response, [], code=304) + return redirect(request, response, [], code=304) else: - return HTTPError(request, response, 412) + return httperror(request, response, 412) def check_auth(request, response, realm, users, encrypt=None): """Check Authentication - If an authorization header contains credentials, return True, else False. + If an Authorization header contains credentials, return True, else False. :param realm: The authentication realm. :type realm: str @@ -306,11 +307,11 @@ :type encrypt: callable """ - if 'authorization' in request.headers: + if "Authorization" in request.headers: # make sure the provided credentials are correctly set - ah = _httpauth.parseAuthorization(request.headers['authorization']) + ah = _httpauth.parseAuthorization(request.headers.get("Authorization")) if ah is None: - return HTTPError(request, response, 400) + return httperror(request, response, 400) if not encrypt: encrypt = _httpauth.DIGEST_AUTH_ENCODERS[_httpauth.MD5] @@ -335,7 +336,7 @@ # fetch the user password password = users.get(ah["username"], None) - # validate the authorization by re-computing it here + # validate the Authorization by re-computing it here # and compare it with what the user-agent provided if _httpauth.checkResponse(ah, password, method=request.method, encrypt=encrypt, realm=realm): @@ -370,7 +371,7 @@ # inform the user-agent this path is protected response.headers["WWW-Authenticate"] = _httpauth.basicAuth(realm) - return Unauthorized(request, response) + return unauthorized(request, response) def digest_auth(request, response, realm, users): @@ -392,7 +393,7 @@ # inform the user-agent this path is protected response.headers["WWW-Authenticate"] = _httpauth.digestAuth(realm) - return Unauthorized(request, response) + return unauthorized(request, response) def gzip(response, level=4, mime_types=['text/html', 'text/plain']): @@ -449,6 +450,6 @@ # Delete Content-Length header so finalize() recalcs it. del response.headers["Content-Length"] return response - return HTTPError( + return httperror( response.request, response, 406, description="identity, gzip" ) diff -Nru circuits-2.1.0/circuits/web/url.py circuits-3.1.0+ds1/circuits/web/url.py --- circuits-2.1.0/circuits/web/url.py 1970-01-01 00:00:00.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/web/url.py 2014-09-04 10:32:30.000000000 +0000 @@ -0,0 +1,280 @@ +#!/usr/bin/env python +# +# Copyright (c) 2012 SEOmoz +# +# 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. + +'''This is a module for dealing with urls. In particular, sanitizing them.''' + +import re +import codecs + +try: + from urllib.parse import quote, unquote + from urllib.parse import urljoin, urlparse, urlunparse +except ImportError: + from urllib import quote, unquote # NOQA + from urlparse import urljoin, urlparse, urlunparse # NOQA + +from circuits.six import b, string_types, text_type + +# Come codes that we'll need +IDNA = codecs.lookup('idna') +UTF8 = codecs.lookup('utf-8') +ASCII = codecs.lookup('ascii') +W1252 = codecs.lookup('windows-1252') + +# The default ports associated with each scheme +PORTS = { + 'http': 80, + 'https': 443 +} + + +def parse_url(url, encoding='utf-8'): + '''Parse the provided url string and return an URL object''' + return URL.parse(url, encoding) + + +class URL(object): + ''' + For more information on how and what we parse / sanitize: + http://tools.ietf.org/html/rfc1808.html + The more up-to-date RFC is this one: + http://www.ietf.org/rfc/rfc3986.txt + ''' + + @classmethod + def parse(cls, url, encoding): + '''Parse the provided url, and return a URL instance''' + + if isinstance(url, text_type): + parsed = urlparse(url.encode('utf-8')) + else: + parsed = urlparse(url.decode(encoding).encode('utf-8')) + + try: + port = str(parsed.port).encode("utf-8") + except ValueError: + port = None + + return cls( + parsed.scheme, parsed.hostname, + port, parsed.path, parsed.params, + parsed.query, parsed.fragment + ) + + def __init__(self, scheme, host, port, path, + params=b"", query=b"", fragment=b""): + assert not type(port) is int + self._scheme = scheme + self._host = host + self._port = port + self._path = path or b('/') + self._params = re.sub(b('^;+'), b(''), params) + self._params = re.sub( + b('^;|;$'), b(''), re.sub(b(';{2,}'), b(';'), self._params) + ) + # Strip off extra leading ?'s + self._query = query.lstrip(b('?')) + self._query = re.sub( + b('^&|&$'), b(''), re.sub(b('&{2,}'), b('&'), self._query) + ) + self._fragment = fragment + + def __call__(self, path, encoding="utf-8"): + return self.relative(path, encoding=encoding).unicode() + + def equiv(self, other): + '''Return true if this url is equivalent to another''' + if isinstance(other, string_types[0]): + _other = self.parse(other, 'utf-8') + else: + _other = self.parse(other.utf8(), 'utf-8') + + _self = self.parse(self.utf8(), 'utf-8') + _self.lower().canonical().defrag().abspath().escape().punycode() + _other.lower().canonical().defrag().abspath().escape().punycode() + + result = ( + _self._scheme == _other._scheme and + _self._host == _other._host and + _self._path == _other._path and + _self._params == _other._params and + _self._query == _other._query) + + if result: + if _self._port and not _other._port: + # Make sure _self._port is the default for the scheme + return _self._port == PORTS.get(_self._scheme, None) + elif _other._port and not _self._port: + # Make sure _other._port is the default for the scheme + return _other._port == PORTS.get(_other._scheme, None) + else: + return _self._port == _other._port + else: + return False + + def __eq__(self, other): + '''Return true if this url is /exactly/ equal to another''' + if isinstance(other, basestring): + return self.__eq__(self.parse(other, 'utf-8')) + return ( + self._scheme == other._scheme and + self._host == other._host and + self._path == other._path and + self._port == other._port and + self._params == other._params and + self._query == other._query and + self._fragment == other._fragment) + + def __ne__(self, other): + return not self.__eq__(other) + + def __str__(self): + return self.utf8() + + def __repr__(self): + return '' % self.utf8() + + def canonical(self): + '''Canonicalize this url. This includes reordering parameters and args + to have a consistent ordering''' + self._query = b('&').join( + sorted([q for q in self._query.split(b('&'))]) + ) + self._params = b(';').join( + sorted([q for q in self._params.split(b(';'))]) + ) + return self + + def defrag(self): + '''Remove the fragment from this url''' + self._fragment = None + return self + + def deparam(self, params=None): + '''Strip any of the provided parameters out of the url''' + # And remove all the black-listed query parameters + self._query = '&'.join(q for q in self._query.split('&') + if q.partition('=')[0].lower() not in params) + # And remove all the black-listed param parameters + self._params = ';'.join(q for q in self._params.split(';') if + q.partition('=')[0].lower() not in params) + return self + + def abspath(self): + '''Clear out any '..' and excessive slashes from the path''' + # Remove double forward-slashes from the path + path = re.sub(b('\/{2,}'), b('/'), self._path) + # With that done, go through and remove all the relative references + unsplit = [] + for part in path.split(b('/')): + # If we encounter the parent directory, and there's + # a segment to pop off, then we should pop it off. + if part == b('..') and (not unsplit or unsplit.pop() is not None): + pass + elif part != b('.'): + unsplit.append(part) + + # With all these pieces, assemble! + if self._path.endswith(b('.')): + # If the path ends with a period, then it refers to a directory, + # not a file path + self._path = b('/').join(unsplit) + b('/') + else: + self._path = b('/').join(unsplit) + return self + + def lower(self): + '''Lowercase the hostname''' + self._host = self._host.lower() + return self + + def sanitize(self): + '''A shortcut to abspath, escape and lowercase''' + return self.abspath().escape().lower() + + def escape(self): + '''Make sure that the path is correctly escaped''' + self._path = quote(unquote(self._path.decode("utf-8"))).encode("utf-8") + return self + + def unescape(self): + '''Unescape the path''' + self._path = unquote(self._path) + return self + + def encode(self, encoding): + '''Return the url in an arbitrary encoding''' + netloc = self._host + if self._port: + netloc += (b(':') + bytes(self._port)) + + result = urlunparse(( + self._scheme, netloc, self._path, + self._params, self._query, self._fragment + )) + return result.decode('utf-8').encode(encoding) + + def relative(self, path, encoding='utf-8'): + '''Evaluate the new path relative to the current url''' + if isinstance(path, text_type): + newurl = urljoin(self.utf8(), path.encode('utf-8')) + else: + newurl = urljoin( + self.utf8(), path.decode(encoding).encode('utf-8') + ) + return URL.parse(newurl, 'utf-8') + + def punycode(self): + '''Convert to punycode hostname''' + if self._host: + self._host = IDNA.encode(self._host.decode('utf-8'))[0] + return self + raise TypeError('Cannot punycode a relative url') + + def unpunycode(self): + '''Convert to an unpunycoded hostname''' + if self._host: + self._host = IDNA.decode( + self._host.decode('utf-8'))[0].encode('utf-8') + return self + raise TypeError('Cannot unpunycode a relative url') + + ########################################################################### + # Information about the type of url it is + ########################################################################### + def absolute(self): + '''Return True if this is a fully-qualified URL with a hostname and + everything''' + return bool(self._host) + + ########################################################################### + # Get a string representation. These methods can't be chained, as they + # return strings + ########################################################################### + def unicode(self): + '''Return a unicode version of this url''' + return self.encode('utf-8').decode('utf-8') + + def utf8(self): + '''Return a utf-8 version of this url''' + return self.encode('utf-8') diff -Nru circuits-2.1.0/circuits/web/utils.py circuits-3.1.0+ds1/circuits/web/utils.py --- circuits-2.1.0/circuits/web/utils.py 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/web/utils.py 2014-09-04 10:32:30.000000000 +0000 @@ -11,8 +11,10 @@ import zlib import time import struct +from math import sqrt from io import TextIOWrapper from cgi import FieldStorage +from collections import MutableMapping try: from urllib.parse import urljoin as _urljoin @@ -24,10 +26,25 @@ except ImportError: from cgi import parse_qs as _parse_qs # NOQA -from .exceptions import RequestEntityTooLarge +from circuits.six import iterbytes + +from .exceptions import RangeUnsatisfiable, RequestEntityTooLarge quoted_slash = re.compile("(?i)%2F") -image_map_pattern = re.compile("[0-9]+,[0-9]+") +image_map_pattern = re.compile("^[0-9]+,[0-9]+$") + + +def average(xs): + return sum(xs) * 1.0 / len(xs) + + +def variance(xs): + avg = average(xs) + return list(map(lambda x: (x - avg)**2, xs)) + + +def stddev(xs): + return sqrt(average(variance(xs))) def parse_body(request, response, params): @@ -37,7 +54,7 @@ try: form = FieldStorage( environ={"REQUEST_METHOD": "POST"}, - fp=request.body, + fp=TextIOWrapper(request.body), headers=request.headers, keep_blank_values=True ) @@ -124,95 +141,6 @@ + struct.pack("..." - # This is also sometimes called "server-relative". - newurl = '/' + '/'.join(newurl.split('/', 3)[3:]) - elif relative: - # "A relative reference that does not begin with a scheme name - # or a slash character is termed a relative-path reference." - old = url().split('/')[:-1] - new = newurl.split('/') - while old and new: - a, b = old[0], new[0] - if a != b: - break - old.pop(0) - new.pop(0) - new = (['..'] * len(old)) + new - newurl = '/'.join(new) - - return newurl - - def get_ranges(headervalue, content_length): """Return a list of (start, stop) indices from a Range header, or None. @@ -253,12 +181,206 @@ # did not exist. (Normally, this means return a 200 # response containing the full entity)." return None - result.append((start, stop + 1)) + # Prevent duplicate ranges. See Issue #59 + if (start, stop + 1) not in result: + result.append((start, stop + 1)) else: if not stop: # See rfc quote above. return None # Negative subscript (last N bytes) - result.append((content_length - int(stop), content_length)) + # Prevent duplicate ranges. See Issue #59 + if (content_length - int(stop), content_length) not in result: + result.append((content_length - int(stop), content_length)) + + # Can we satisfy the requested Range? + # If we have an exceedingly high standard deviation + # of Range(s) we reject the request. + # See Issue #59 + + if len(result) > 1 and stddev([x[1] - x[0] for x in result]) > 2.0: + raise RangeUnsatisfiable() return result + + +class IOrderedDict(dict, MutableMapping): + 'Dictionary that remembers insertion order with insensitive key' + # An inherited dict maps keys to values. + # The inherited dict provides __getitem__, __len__, __contains__, and get. + # The remaining methods are order-aware. + # Big-O running times for all methods are the same as for regular dictionaries. + + # The internal self.__map dictionary maps keys to links in a doubly linked list. + # The circular doubly linked list starts and ends with a sentinel element. + # The sentinel element never gets deleted (this simplifies the algorithm). + # Each link is stored as a list of length three: [PREV, NEXT, KEY]. + + def __init__(self, *args, **kwds): + '''Initialize an ordered dictionary. Signature is the same as for + regular dictionaries, but keyword arguments are not recommended + because their insertion order is arbitrary. + + ''' + if len(args) > 1: + raise TypeError('expected at most 1 arguments, got %d' % len(args)) + try: + self.__root + except AttributeError: + self.__root = root = [None, None, None] # sentinel node + PREV = 0 + NEXT = 1 + root[PREV] = root[NEXT] = root + self.__map = {} + self.__lower = {} + self.update(*args, **kwds) + + def __setitem__(self, key, value, PREV=0, NEXT=1, dict_setitem=dict.__setitem__): + 'od.__setitem__(i, y) <==> od[i]=y' + # Setting a new item creates a new link which goes at the end of the linked + # list, and the inherited dictionary is updated with the new key/value pair. + if key not in self: + root = self.__root + last = root[PREV] + last[NEXT] = root[PREV] = self.__map[key] = [last, root, key] + self.__lower[key.lower()] = key + key = self.__lower[key.lower()] + dict_setitem(self, key, value) + + def __delitem__(self, key, PREV=0, NEXT=1, dict_delitem=dict.__delitem__): + 'od.__delitem__(y) <==> del od[y]' + # Deleting an existing item uses self.__map to find the link which is + # then removed by updating the links in the predecessor and successor nodes. + if key in self: + key = self.__lower.pop(key.lower()) + + dict_delitem(self, key) + link = self.__map.pop(key) + link_prev = link[PREV] + link_next = link[NEXT] + link_prev[NEXT] = link_next + link_next[PREV] = link_prev + + def __getitem__(self, key, dict_getitem=dict.__getitem__): + if key in self: + key = self.__lower.get(key.lower()) + return dict_getitem(self, key) + + def __contains__(self, key): + return key.lower() in self.__lower + + def __iter__(self, NEXT=1, KEY=2): + 'od.__iter__() <==> iter(od)' + # Traverse the linked list in order. + root = self.__root + curr = root[NEXT] + while curr is not root: + yield curr[KEY] + curr = curr[NEXT] + + def __reversed__(self, PREV=0, KEY=2): + 'od.__reversed__() <==> reversed(od)' + # Traverse the linked list in reverse order. + root = self.__root + curr = root[PREV] + while curr is not root: + yield curr[KEY] + curr = curr[PREV] + + def __reduce__(self): + 'Return state information for pickling' + items = [[k, self[k]] for k in self] + tmp = self.__map, self.__root + del self.__map, self.__root + inst_dict = vars(self).copy() + self.__map, self.__root = tmp + if inst_dict: + return (self.__class__, (items,), inst_dict) + return self.__class__, (items,) + + def clear(self): + 'od.clear() -> None. Remove all items from od.' + try: + for node in self.__map.values(): + del node[:] + self.__root[:] = [self.__root, self.__root, None] + self.__map.clear() + except AttributeError: + pass + dict.clear(self) + + def get(self, key, default=None): + if key in self: + return self[key] + return default + + setdefault = MutableMapping.setdefault + update = MutableMapping.update + pop = MutableMapping.pop + keys = MutableMapping.keys + values = MutableMapping.values + items = MutableMapping.items + __ne__ = MutableMapping.__ne__ + + def popitem(self, last=True): + '''od.popitem() -> (k, v), return and remove a (key, value) pair. + Pairs are returned in LIFO order if last is true or FIFO order if false. + + ''' + if not self: + raise KeyError('dictionary is empty') + key = next(reversed(self) if last else iter(self)) + value = self.pop(key) + return key, value + + def __repr__(self): + 'od.__repr__() <==> repr(od)' + if not self: + return '%s()' % (self.__class__.__name__,) + return '%s(%r)' % (self.__class__.__name__, list(self.items())) + + def copy(self): + 'od.copy() -> a shallow copy of od' + return self.__class__(self) + + @classmethod + def fromkeys(cls, iterable, value=None): + '''OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S + and values equal to v (which defaults to None). + + ''' + d = cls() + for key in iterable: + d[key] = value + return d + + def __eq__(self, other): + '''od.__eq__(y) <==> od==y. Comparison to another OD is order-sensitive + while comparison to a regular mapping is order-insensitive. + + ''' + if isinstance(other, IOrderedDict): + return ( + len(self) == len(other) + and set(self.items()) == set(other.items()) + ) + return dict.__eq__(self, other) + + def __del__(self): + self.clear() # eliminate cyclical references + + +def is_ssl_handshake(buf): + """Detect an SSLv2 or SSLv3 handshake""" + + # SSLv3 + + v = buf[:3] + if v in ["\x16\x03\x00", "\x16\x03\x01", "\x16\x03\x02"]: + return True + + # SSLv2 + + v = list(iterbytes(buf))[:2] + if (v[0] & 0x80 == 0x80) and ((v[0] & 0x7f) << 8 | v[1]) > 9: + return True diff -Nru circuits-2.1.0/circuits/web/websocket.py circuits-3.1.0+ds1/circuits/web/websocket.py --- circuits-2.1.0/circuits/web/websocket.py 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/web/websocket.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,134 +0,0 @@ -""" -.. codeauthor: mnl -""" -from circuits.web.headers import Headers -from circuits.core.handlers import handler -import os -import random -import base64 -from circuits.web import client -from circuits.net.protocols.websocket import WebSocketCodec -try: - from urllib.parse import urlparse -except ImportError: - from urlparse import urlparse -from circuits.core.components import BaseComponent -from circuits.web.client import NotConnected -from circuits.net.sockets import TCPClient, Connect, Write, Close -from circuits.net.protocols.http import HTTP -from socket import error as SocketError -from errno import ECONNRESET - -class WebSocketClient(BaseComponent): - """ - An RFC 6455 compliant WebSocket client component. Upon receiving a - :class:`circuits.web.client.Connect` event, the component tries to - establish the connection to the server in a two stage process. First, a - :class:`circuits.net.sockets.Connect` event is sent to a child - :class:`~.sockets.TCPClient`. When the TCP connection has been established, - the HTTP request for opening the WebSocket is sent to the server. - A failure in this setup process is signaled by a - :class:`~.client.NotConnected` event. - - When the server accepts the request, the WebSocket connection is - established and can be used very much like an ordinary socket - by handling :class:`~.sockets.Read` events on and sending - :class:`~.sockets.Write` events to the channel - specified as the ``wschannel`` parameter of the constructor. Firing - a :class:`~.sockets.Close` event on that channel closes the - connection in an orderly fashion (i.e. as specified by the - WebSocket protocol). - """ - - channel = "wsclient" - - def __init__(self, url, channel=channel, wschannel="ws", headers={}): - """ - :param url: the URL to connect to. - :param channel: the channel used by this component - :param wschannel: the channel used for the actual WebSocket - communication (read, write, close events) - :param headers: additional headers to be passed with the - WebSocket setup HTTP request - """ - super(WebSocketClient, self).__init__(channel=channel) - - self._url = url - self._headers = headers - self._response = None - self._pending = 0 - self._wschannel = wschannel - - self._transport = TCPClient(channel=self.channel).register(self) - HTTP(channel=self.channel).register(self._transport) - - @handler("connect", priority=0.1, filter=True) - def _on_connect(self, event, *args, **kwargs): - if not isinstance(event, client.Connect): - return - p = urlparse(self._url) - if not p.hostname: - raise ValueError("URL must be absolute") - self._host = p.hostname - if p.scheme == "ws": - self._secure = False - self._port = p.port or 80 - elif p.scheme == "wss": - self._secure = True - self._port = p.port or 443 - else: - self.fire(NotConnected()) - return - self._resource = p.path or "/" - if p.query: - self._resource += "?" + p.query - self.fire(Connect(self._host, self._port, self._secure), - self._transport) - - @handler("connected") - def _on_connected(self, host, port): - headers = Headers([(k, v) for k, v in self._headers.items()]) - # Clients MUST include Host header in HTTP/1.1 requests (RFC 2616) - if not "Host" in headers: - headers["Host"] = self._host \ - + (":" + str(self._port)) if self._port else "" - headers["Upgrade"] = "websocket" - headers["Connection"] = "Upgrade" - try: - sec_key = os.urandom(16) - except NotImplementedError: - sec_key = "".join([chr(random.randint(0,255)) for i in range(16)]) - headers["Sec-WebSocket-Key"] = base64.b64encode(sec_key) - headers["Sec-WebSocket-Version"] = "13" - command = "GET %s HTTP/1.1" % self._resource - message = "%s\r\n%s" % (command, headers) - self._pending += 1 - self.fire(Write(message.encode('utf-8')), self._transport) - return True - - @handler("response") - def _on_response(self, response): - self._response = response - self._pending -= 1 - if response.headers.get("Connection") == "Close" \ - or response.status != 101: - self.fire(Close(), self._transport) - self.fire(NotConnected()) - WebSocketCodec(channel=self._wschannel).register(self) - - @handler("error", filter=True, priority=10) - def _on_error(self, error, *args, **kwargs): - # For HTTP 1.1 we leave the connection open. If the peer closes - # it after some time and we have no pending request, that's OK. - if isinstance(error, SocketError) and error.args[0] == ECONNRESET \ - and self._pending == 0: - return True - - def close(self): - if self._transport != None: - self._transport.close() - - @property - def connected(self): - return getattr(self._transport, "connected", False) \ - if hasattr(self, "_transport") else False diff -Nru circuits-2.1.0/circuits/web/websockets/client.py circuits-3.1.0+ds1/circuits/web/websockets/client.py --- circuits-2.1.0/circuits/web/websockets/client.py 1970-01-01 00:00:00.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/web/websockets/client.py 2014-09-04 10:32:30.000000000 +0000 @@ -0,0 +1,135 @@ +# Module: client +# Date: 4th January 2013 +# Author: mnl + +import os +import random +import base64 +from errno import ECONNRESET +from socket import error as SocketError + +try: + from urllib.parse import urlparse +except ImportError: + from urlparse import urlparse # NOQA + +from circuits.web.headers import Headers +from circuits.protocols.http import HTTP +from circuits.core.handlers import handler +from circuits.net.sockets import TCPClient +from circuits.web.client import NotConnected +from circuits.core.components import BaseComponent +from circuits.net.events import connect, write, close +from circuits.protocols.websocket import WebSocketCodec + + +class WebSocketClient(BaseComponent): + """ + An RFC 6455 compliant WebSocket client component. Upon receiving a + :class:`circuits.web.client.Connect` event, the component tries to + establish the connection to the server in a two stage process. First, a + :class:`circuits.net.events.connect` event is sent to a child + :class:`~.sockets.TCPClient`. When the TCP connection has been established, + the HTTP request for opening the WebSocket is sent to the server. + A failure in this setup process is signaled by raising an + :class:`~.client.NotConnected` exception. + + When the server accepts the request, the WebSocket connection is + established and can be used very much like an ordinary socket + by handling :class:`~.net.events.read` events on and sending + :class:`~.net.events.write` events to the channel + specified as the ``wschannel`` parameter of the constructor. Firing + a :class:`~.net.events.close` event on that channel closes the + connection in an orderly fashion (i.e. as specified by the + WebSocket protocol). + """ + + channel = "wsclient" + + def __init__(self, url, channel=channel, wschannel="ws", headers={}): + """ + :param url: the URL to connect to. + :param channel: the channel used by this component + :param wschannel: the channel used for the actual WebSocket + communication (read, write, close events) + :param headers: additional headers to be passed with the + WebSocket setup HTTP request + """ + super(WebSocketClient, self).__init__(channel=channel) + + self._url = url + self._headers = headers + self._response = None + self._pending = 0 + self._wschannel = wschannel + + self._transport = TCPClient(channel=self.channel).register(self) + HTTP(channel=self.channel).register(self._transport) + + @handler("ready") + def _on_ready(self, event, *args, **kwargs): + p = urlparse(self._url) + if not p.hostname: + raise ValueError("URL must be absolute") + self._host = p.hostname + if p.scheme == "ws": + self._secure = False + self._port = p.port or 80 + elif p.scheme == "wss": + self._secure = True + self._port = p.port or 443 + else: + raise NotConnected() + self._resource = p.path or "/" + if p.query: + self._resource += "?" + p.query + self.fire(connect(self._host, self._port, self._secure), + self._transport) + + @handler("connected") + def _on_connected(self, host, port): + headers = Headers([(k, v) for k, v in self._headers.items()]) + # Clients MUST include Host header in HTTP/1.1 requests (RFC 2616) + if not "Host" in headers: + headers["Host"] = self._host \ + + (":" + str(self._port)) if self._port else "" + headers["Upgrade"] = "websocket" + headers["Connection"] = "Upgrade" + try: + sec_key = os.urandom(16) + except NotImplementedError: + sec_key = "".join([chr(random.randint(0, 255)) for i in range(16)]) + headers["Sec-WebSocket-Key"] = base64.b64encode(sec_key).decode("latin1") + headers["Sec-WebSocket-Version"] = "13" + command = "GET %s HTTP/1.1" % self._resource + message = "%s\r\n%s" % (command, headers) + self._pending += 1 + self.fire(write(message.encode('utf-8')), self._transport) + return True + + @handler("response") + def _on_response(self, response): + self._response = response + self._pending -= 1 + if response.headers.get("Connection") == "Close" \ + or response.status != 101: + self.fire(close(), self._transport) + raise NotConnected() + WebSocketCodec(data=response.body.read(), channel=self._wschannel).register(self) + + @handler("error", priority=10) + def _on_error(self, event, error, *args, **kwargs): + # For HTTP 1.1 we leave the connection open. If the peer closes + # it after some time and we have no pending request, that's OK. + if isinstance(error, SocketError) and error.args[0] == ECONNRESET \ + and self._pending == 0: + event.stop() + + def close(self): + if self._transport is not None: + self._transport.close() + + @property + def connected(self): + return getattr(self._transport, "connected", False) \ + if hasattr(self, "_transport") else False diff -Nru circuits-2.1.0/circuits/web/websockets/dispatcher.py circuits-3.1.0+ds1/circuits/web/websockets/dispatcher.py --- circuits-2.1.0/circuits/web/websockets/dispatcher.py 1970-01-01 00:00:00.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/web/websockets/dispatcher.py 2014-09-04 10:32:30.000000000 +0000 @@ -0,0 +1,119 @@ +# Module: dispatcher +# Date: 26th February 2011 +# Author: James Mills, prologic at shortcircuit dot net dot au + + +import base64 +import hashlib + + +from circuits.six import b +from circuits.web.errors import httperror +from circuits import handler, BaseComponent +from circuits.net.events import connect, disconnect +from circuits.protocols.websocket import WebSocketCodec + + +class WebSocketsDispatcher(BaseComponent): + """ + This class implements an RFC 6455 compliant WebSockets dispatcher + that handles the WebSockets handshake and upgrades the connection. + + The dispatcher listens on its channel for :class:`~.web.events.Request` + events and tries to match them with a given path. Upon a match, + the request is checked for the proper Opening Handshake information. + If successful, the dispatcher confirms the establishment of the + connection to the client. Any subsequent data from the client is + handled as a WebSocket data frame, decoded and fired as + a :class:`~.sockets.Read` event on the ``wschannel`` passed to + the constructor. The data from :class:`~.net.events.write` events on + that channel is encoded as data frames and forwarded to the client. + + Firing a :class:`~.sockets.Close` event on the ``wschannel`` closes the + connection in an orderly fashion (i.e. as specified by the + WebSocket protocol). + """ + + channel = "web" + + def __init__(self, path=None, wschannel="wsserver", *args, **kwargs): + """ + :param path: the path to handle. Requests that start with this + path are considered to be WebSocket Opening Handshakes. + + :param wschannel: the channel on which :class:`~.sockets.read` + events from the client will be delivered and where + :class:`~.net.events.write` events to the client will be + sent to. + """ + + super(WebSocketsDispatcher, self).__init__(*args, **kwargs) + + self._path = path + self._wschannel = wschannel + self._codecs = dict() + + @handler("request", priority=0.2) + def _on_request(self, event, request, response): + if self._path is not None and not request.path.startswith(self._path): + return + + self._protocol_version = 13 + headers = request.headers + sec_key = headers.get("Sec-WebSocket-Key", "").encode("utf-8") + + connection_tokens = [s.strip() for s in + headers.get("Connection", "").lower().split(",")] + + try: + if ("Host" not in headers + or headers.get("Upgrade", "").lower() != "websocket" + or "upgrade" not in connection_tokens + or sec_key is None + or len(base64.b64decode(sec_key)) != 16): + return httperror(request, response, code=400) + if headers.get("Sec-WebSocket-Version", "") != "13": + response.headers["Sec-WebSocket-Version"] = "13" + return httperror(request, response, code=400) + + # Generate accept header information + msg = sec_key + b("258EAFA5-E914-47DA-95CA-C5AB0DC85B11") + hasher = hashlib.sha1() + hasher.update(msg) + accept = base64.b64encode(hasher.digest()) + + # Successful completion + response.status = 101 + response.close = False + try: + del response.headers["Content-Type"] + except KeyError: + pass + response.headers["Upgrade"] = "WebSocket" + response.headers["Connection"] = "Upgrade" + response.headers["Sec-WebSocket-Accept"] = accept.decode() + codec = WebSocketCodec(request.sock, channel=self._wschannel) + self._codecs[request.sock] = codec + codec.register(self) + return response + finally: + event.stop() + + @handler("response_complete") + def _on_response_complete(self, e, value): + response = e.args[0] + request = response.request + if request.sock in self._codecs: + self.fire( + connect( + request.sock, + *request.sock.getpeername() + ), + self._wschannel + ) + + @handler("disconnect") + def _on_disconnect(self, sock): + if sock in self._codecs: + self.fire(disconnect(sock), self._wschannel) + del self._codecs[sock] diff -Nru circuits-2.1.0/circuits/web/websockets/__init__.py circuits-3.1.0+ds1/circuits/web/websockets/__init__.py --- circuits-2.1.0/circuits/web/websockets/__init__.py 1970-01-01 00:00:00.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/web/websockets/__init__.py 2014-09-04 10:32:30.000000000 +0000 @@ -0,0 +1,10 @@ +# Package: websockets +# Date: 26th March 2013 +# Author: James Mills, prologic at shortcircuit dot net dot au + +"""circuits.web websockets""" + +from .client import WebSocketClient +from .dispatcher import WebSocketsDispatcher + +# flake8: noqa diff -Nru circuits-2.1.0/circuits/web/wrappers.py circuits-3.1.0+ds1/circuits/web/wrappers.py --- circuits-2.1.0/circuits/web/wrappers.py 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/web/wrappers.py 2014-09-04 10:32:30.000000000 +0000 @@ -8,26 +8,33 @@ """ -from io import BytesIO, IOBase -from time import strftime, time +from time import time +from io import BytesIO +from functools import partial try: from Cookie import SimpleCookie except ImportError: from http.cookies import SimpleCookie # NOQA -from .utils import url +from .url import parse_url from .headers import Headers from ..six import binary_type -from .errors import HTTPError +from .errors import httperror from circuits.net.sockets import BUFSIZE -from .constants import HTTP_STATUS_CODES, SERVER_PROTOCOL, SERVER_VERSION +from .constants import HTTP_STATUS_CODES, SERVER_VERSION try: unicode except NameError: unicode = str +try: + from email.utils import formatdate + formatdate = partial(formatdate, usegmt=True) +except ImportError: + from rfc822 import formatdate as HTTPDate # NOQA + def file_generator(input, chunkSize=BUFSIZE): chunk = input.read(chunkSize) @@ -53,28 +60,84 @@ self.port = port if name is None: name = ip - self.name = name + self.name = name def __repr__(self): return "Host(%r, %r, %r)" % (self.ip, self.port, self.name) +class HTTPStatus(object): + + __slots__ = ("_reason", "_status",) + + def __init__(self, status=200, reason=None): + self._status = status + self._reason = reason or HTTP_STATUS_CODES.get(status, "") + + def __int__(self): + return self._status + + def __lt__(self, other): + if isinstance(other, int): + return self._status < other + return super(HTTPStatus, self).__lt__(other) + + def __gt__(self, other): + if isinstance(other, int): + return self._status > other + return super(HTTPStatus, self).__gt__(other) + + def __le__(self, other): + if isinstance(other, int): + return self._status <= other + return super(HTTPStatus, self).__le__(other) + + def __ge__(self, other): + if isinstance(other, int): + return self._status >= other + return super(HTTPStatus, self).__ge__(other) + + def __eq__(self, other): + if isinstance(other, int): + return self._status == other + return super(HTTPStatus, self).__eq__(other) + + def __str__(self): + return "{0:d} {1:s}".format(self._status, self._reason) + + def __repr__(self): + return "".format( + self._status, self._reason + ) + + def __format__(self, format_spec): + return format(str(self), format_spec) + + @property + def status(self): + return self._status + + @property + def reason(self): + return self._reason + + class Request(object): """Creates a new Request object to hold information about a request. :param sock: The socket object of the request. :type sock: socket.socket - :param method: The requsted method. + :param method: The requested method. :type method: str - :param scheme: The requsted scheme. + :param scheme: The requested scheme. :type scheme: str - :param path: The requsted path. + :param path: The requested path. :type path: str - :param protocol: The requsted protocol. + :param protocol: The requested protocol. :type protocol: str :param qs: The query string of the request. @@ -82,27 +145,22 @@ """ server = None - """@cvar: A reference to the underlying server""" + """:cvar: A reference to the underlying server""" scheme = "http" protocol = (1, 1) - server_protocol = (1, 1) host = "" local = Host("127.0.0.1", 80) remote = Host("", 0) - xhr = False - index = None script_name = "" login = None handled = False - args = None - kwargs = None - - def __init__(self, sock, method, scheme, path, protocol, qs): + def __init__(self, sock, method="GET", scheme="http", path="/", + protocol=(1, 1), qs="", headers=None, server=None): "initializes x; see x.__class__.__doc__ for signature" self.sock = sock @@ -111,49 +169,63 @@ self.path = path self.protocol = protocol self.qs = qs - self.cookie = SimpleCookie() - self._headers = None + self.headers = headers or Headers() + self.server = server - if sock: + self.cookie = SimpleCookie() + + if sock is not None: name = sock.getpeername() - if name: + if name is not None: self.remote = Host(*name) else: name = sock.getsockname() self.remote = Host(name, "", name) - self.body = BytesIO() - - def _getHeaders(self): - return self._headers + cookie = self.headers.get("Cookie") + if cookie is not None: + self.cookie.load(cookie) - def _setHeaders(self, headers): - self._headers = headers + self.body = BytesIO() - if "Cookie" in self.headers: - rawcookies = self.headers["Cookie"] - if not isinstance(rawcookies, str): - rawcookies = rawcookies.encode('utf-8') - self.cookie.load(rawcookies) + if self.server is not None: + self.local = Host(self.server.host, self.server.port) - host = self.headers.get("Host", None) - if not host: + try: + host = self.headers["Host"] + if ":" in host: + parts = host.split(":", 1) + host = parts[0] + port = int(parts[1]) + else: + port = 443 if self.scheme == "https" else 80 + except KeyError: host = self.local.name or self.local.ip - self.base = "%s://%s" % (self.scheme, host) + port = getattr(self.server, "port") - self.xhr = self.headers.get( - "X-Requested-With", "").lower() == "xmlhttprequest" + self.host = host + self.port = port + + base = "{0:s}://{1:s}{2:s}/".format( + self.scheme, + self.host, + ":{0:d}".format(self.port) if self.port not in (80, 443) else "" + ) + self.base = parse_url(base) - headers = property(_getHeaders, _setHeaders) + url = "{0:s}{1:s}{2:s}".format( + base, + self.path, + "?{0:s}".format(self.qs) if self.qs else "" + ) + self.uri = parse_url(url) + self.uri.sanitize() def __repr__(self): protocol = "HTTP/%d.%d" % self.protocol return "" % (self.method, self.path, protocol) - def url(self, *args, **kwargs): - return url(self, *args, **kwargs) - class Body(object): """Response Body""" @@ -173,10 +245,10 @@ value = [value] else: value = [] - elif isinstance(value, IOBase): + elif hasattr(value, "read"): response.stream = True value = file_generator(value) - elif isinstance(value, HTTPError): + elif isinstance(value, httperror): value = [str(value)] elif value is None: value = [] @@ -184,6 +256,21 @@ response._body = value +class Status(object): + """Response Status""" + + def __get__(self, response, cls=None): + if response is None: + return self + else: + return response._status + + def __set__(self, response, value): + value = HTTPStatus(value) if isinstance(value, int) else value + + response._status = value + + class Response(object): """Response(sock, request) -> new Response object @@ -192,70 +279,57 @@ is sent in the correct order. """ - code = 200 - message = None - body = Body() + status = Status() + done = False close = False stream = False chunked = False - protocol = "HTTP/%d.%d" % SERVER_PROTOCOL - - def __init__(self, request, encoding='utf-8', code=None, message=None): + def __init__(self, request, encoding='utf-8', status=None): "initializes x; see x.__class__.__doc__ for signature" self.request = request self.encoding = encoding - if code is not None: - self.code = code - - if message is not None: - self.message = message - self._body = [] + self._status = HTTPStatus(status if status is not None else 200) + self.time = time() - self.headers = Headers([]) - self.headers.add_header("Date", strftime("%a, %d %b %Y %H:%M:%S %Z")) + self.headers = Headers() + self.headers["Date"] = formatdate() - if self.request.server: - self.headers.add_header("Server", self.request.server.version) + if self.request.server is not None: + self.headers.add_header("Server", self.request.server.http.version) else: self.headers.add_header("X-Powered-By", SERVER_VERSION) self.cookie = self.request.cookie - self.protocol = "HTTP/%d.%d" % self.request.server_protocol - - self._encoding = encoding + self.protocol = "HTTP/%d.%d" % self.request.protocol def __repr__(self): return "" % ( self.status, - self.headers["Content-Type"], - (len(self.body) if type(self.body) == str else 0) + self.headers.get("Content-Type"), + (len(self.body) if isinstance(self.body, str) else 0) ) def __str__(self): self.prepare() protocol = self.protocol - status = self.status - headers = self.headers - return "%s %s\r\n%s" % (protocol, status, headers) + status = "{0:s}".format(self.status) + return "{0:s} {1:s}\r\n".format(protocol, status) - @property - def status(self): - return "%d %s" % ( - self.code, self.message or HTTP_STATUS_CODES[self.code] - ) + def __bytes__(self): + return str(self).encode(self.encoding) def prepare(self): # Set a default content-Type if we don't have one. - self.headers.setdefault("Content-Type", - "text/html; charset={0:s}".format(self.encoding) + self.headers.setdefault( + "Content-Type", "text/html; charset={0:s}".format(self.encoding) ) cLength = None @@ -263,11 +337,11 @@ if isinstance(self.body, bytes): cLength = len(self.body) elif isinstance(self.body, unicode): - cLength = len(self.body.encode(self._encoding)) + cLength = len(self.body.encode(self.encoding)) elif isinstance(self.body, list): cLength = sum( [ - len(s.encode(self._encoding)) + len(s.encode(self.encoding)) if not isinstance(s, bytes) else len(s) for s in self.body if s is not None @@ -280,7 +354,7 @@ for k, v in self.cookie.items(): self.headers.add_header("Set-Cookie", v.OutputString()) - status = self.code + status = self.status if status == 413: self.close = True diff -Nru circuits-2.1.0/circuits/web/wsgi.py circuits-3.1.0+ds1/circuits/web/wsgi.py --- circuits-2.1.0/circuits/web/wsgi.py 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/circuits/web/wsgi.py 2014-09-04 10:32:30.000000000 +0000 @@ -14,6 +14,7 @@ from operator import itemgetter from traceback import format_tb +from types import GeneratorType from sys import exc_info as _exc_info from circuits.tools import tryimport @@ -21,11 +22,11 @@ StringIO = tryimport(("cStringIO", "StringIO", "io"), "StringIO") -from . import wrappers from .http import HTTP -from .events import Request +from .events import request from .headers import Headers -from .errors import HTTPError +from .errors import httperror +from circuits.web import wrappers from .dispatchers import Dispatcher @@ -36,7 +37,7 @@ env("REQUEST_METHOD", req.method) env("SERVER_NAME", req.host.split(":", 1)[0]) env("SERVER_PORT", "%i" % (req.server.port or 0)) - env("SERVER_PROTOCOL", "HTTP/%d.%d" % req.server_protocol) + env("SERVER_PROTOCOL", "HTTP/%d.%d" % req.server.http.protocol) env("QUERY_STRING", req.qs) env("SCRIPT_NAME", req.script_name) env("CONTENT_TYPE", req.headers.get("Content-Type", "")) @@ -78,7 +79,7 @@ def init(self): self._finished = False - HTTP().register(self) + HTTP(self).register(self) Dispatcher().register(self) def translateHeaders(self, environ): @@ -97,38 +98,36 @@ headers = Headers(list(self.translateHeaders(environ))) protocol = tuple(map(int, env("SERVER_PROTOCOL")[5:].split("."))) - request = wrappers.Request( + req = wrappers.Request( None, env("REQUEST_METHOD"), env("wsgi.url_scheme"), env("PATH_INFO", ""), protocol, - env("QUERY_STRING", "") + env("QUERY_STRING", ""), + headers=headers ) - request.server = None - request.remote = wrappers.Host(env("REMOTE_ADDR"), env("REMTOE_PORT")) - - request.headers = headers - request.script_name = env("SCRIPT_NAME") - request.wsgi_environ = environ + req.remote = wrappers.Host(env("REMOTE_ADDR"), env("REMTOE_PORT")) + req.script_name = env("SCRIPT_NAME") + req.wsgi_environ = environ try: cl = int(headers.get("Content-Length", "0")) except: cl = 0 - request.body.write(env("wsgi.input").read(cl)) - request.body.seek(0) + req.body.write(env("wsgi.input").read(cl)) + req.body.seek(0) - response = wrappers.Response(request) - response.gzip = "gzip" in request.headers.get("Accept-Encoding", "") + res = wrappers.Response(req) + res.gzip = "gzip" in req.headers.get("Accept-Encoding", "") - return request, response + return req, res def __call__(self, environ, start_response, exc_info=None): self.request, self.response = self.getRequestResponse(environ) - self.fire(Request(self.request, self.response)) + self.fire(request(self.request, self.response)) self._finished = False while self or not self._finished: @@ -139,13 +138,25 @@ status = self.response.status headers = list(self.response.headers.items()) - start_response(status, headers, exc_info) + start_response(str(status), headers, exc_info) return body - @handler("response", filter=True, channel="web") - def response(self, response): + @handler("response", channel="web") + def response(self, event, response): self._finished = True - return True + event.stop() + + @property + def host(self): + return "" + + @property + def port(self): + return 0 + + @property + def secure(self): + return False class _Empty(str): @@ -168,12 +179,12 @@ self.errors = dict((k, StringIO()) for k in self.apps.keys()) - @handler("request", filter=True, priority=0.2) - def _on_request(self, event, request, response): + @handler("request", priority=0.2) + def _on_request(self, event, req, res): if not self.apps: return - parts = request.path.split("/") + parts = req.path.split("/") candidates = [] for i in range(len(parts)): @@ -190,19 +201,23 @@ buffer = StringIO() def start_response(status, headers, exc_info=None): - response.code = int(status.split(" ", 1)[0]) + res.status = int(status.split(" ", 1)[0]) for header in headers: - response.headers.add_header(*header) + res.headers.add_header(*header) return buffer.write errors = self.errors[path] - environ = create_environ(errors, path, request) + environ = create_environ(errors, path, req) try: body = app(environ, start_response) if isinstance(body, list): body = "".join(body) + elif isinstance(body, GeneratorType): + res.body = body + res.stream = True + return res if not body: if not buffer.tell(): @@ -215,4 +230,6 @@ except Exception as error: etype, evalue, etraceback = _exc_info() error = (etype, evalue, format_tb(etraceback)) - return HTTPError(request, response, 500, error=error) + return httperror(req, res, 500, error=error) + finally: + event.stop() diff -Nru circuits-2.1.0/circuits.egg-info/entry_points.txt circuits-3.1.0+ds1/circuits.egg-info/entry_points.txt --- circuits-2.1.0/circuits.egg-info/entry_points.txt 2013-02-27 11:28:31.000000000 +0000 +++ circuits-3.1.0+ds1/circuits.egg-info/entry_points.txt 2014-10-31 23:13:39.000000000 +0000 @@ -1,4 +1,3 @@ +[console_scripts] +circuits.web = circuits.web.main:main - [console_scripts] - circuits.web = circuits.web.main:main - \ No newline at end of file diff -Nru circuits-2.1.0/circuits.egg-info/not-zip-safe circuits-3.1.0+ds1/circuits.egg-info/not-zip-safe --- circuits-2.1.0/circuits.egg-info/not-zip-safe 2013-02-27 11:13:14.000000000 +0000 +++ circuits-3.1.0+ds1/circuits.egg-info/not-zip-safe 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ - diff -Nru circuits-2.1.0/circuits.egg-info/PKG-INFO circuits-3.1.0+ds1/circuits.egg-info/PKG-INFO --- circuits-2.1.0/circuits.egg-info/PKG-INFO 2013-02-27 11:28:31.000000000 +0000 +++ circuits-3.1.0+ds1/circuits.egg-info/PKG-INFO 2014-10-31 23:13:39.000000000 +0000 @@ -1,28 +1,26 @@ -Metadata-Version: 1.0 +Metadata-Version: 1.1 Name: circuits -Version: 2.1.0 +Version: 3.1.0 Summary: Asynchronous Component based Event Application Framework -Home-page: http://bitbucket.org/prologic/circuits/ +Home-page: http://circuitsframework.com/ Author: James Mills -Author-email: James Mills, prologic at shortcircuit dot net dot au +Author-email: prologic@shortcircuit.net.au License: MIT -Download-URL: http://bitbucket.org/prologic/circuits/downloads/ +Download-URL: http://bitbucket.org/circuits/circuits/downloads/ Description: .. _Python Programming Language: http://www.python.org/ .. _#circuits IRC Channel: http://webchat.freenode.net/?randomnick=1&channels=circuits&uio=d4 .. _FreeNode IRC Network: http://freenode.net .. _Python Standard Library: http://docs.python.org/library/ - .. _Website: https://bitbucket.org/prologic/circuits/ - .. _PyPi Page: http://pypi.python.org/pypi/circuits - .. _Read the Docs: http://circuits.readthedocs.org/ .. _MIT License: http://www.opensource.org/licenses/mit-license.php - .. _Create an Issue: https://bitbucket.org/prologic/circuits/issue/new + .. _Create an Issue: https://bitbucket.org/circuits/circuits/issue/new .. _Mailing List: http://groups.google.com/group/circuits-users - .. _Downloads page: https://bitbucket.org/prologic/circuits/downloads + .. _Project Website: http://circuitsframework.com/ + .. _PyPi Page: http://pypi.python.org/pypi/circuits + .. _Read the Docs: http://circuits.readthedocs.org/en/latest/ + .. _View the ChangeLog: http://circuits.readthedocs.org/en/latest/changes.html + .. _Downloads Page: https://bitbucket.org/circuits/circuits/downloads - Overview - -------- - circuits is a **Lightweight** **Event** driven and **Asynchronous** **Application Framework** for the `Python Programming Language`_ with a strong **Component** Architecture. @@ -31,22 +29,158 @@ HTTP/WSGI compliant web server as well as various I/O and Networking components. - To take full advantage of circuits and its architecture, circuits - encourages you to design your application in terms of loosely coupled - components. Circuits has a very powerful message passing system that - enables components to interact with each other via events. Applications - written this way tend to be more maintainable, easier to develop and - scale to complex systems. - - circuits' **Loosely Coupled** **Component Architecture** allows for a - high level of **Reuse** and **Scalability**. Simpler components can be - combined together to form Complex Components and provide higher level - functionality and abstraction. Much of the circuits component library is - designed and built this way. - - - **Documentation**: http://packages.python.org/circuits or `Read the Docs`_. - - **Project website**: https://bitbucket.org/prologic/circuits/ - - **PyPI page**: http://pypi.python.org/pypi/circuits + - Visit the `Project Website`_ + - `Read the Docs`_ + - Download it from the `Downloads Page`_ + - `View the ChangeLog`_ + + .. image:: https://pypip.in/v/circuits/badge.png?text=version + :target: https://pypi.python.org/pypi/circuits + :alt: Latest Version + + .. image:: https://pypip.in/py_versions/circuits/badge.svg + :target: https://pypi.python.org/pypi/circuits + :alt: Supported Python Versions + + .. image:: https://pypip.in/implementation/circuits/badge.svg + :target: https://pypi.python.org/pypi/circuits + :alt: Supported Python implementations + + .. image:: https://pypip.in/status/circuits/badge.svg + :target: https://pypi.python.org/pypi/circuits + :alt: Development Status + + .. image:: https://pypip.in/d/circuits/badge.png + :target: https://pypi.python.org/pypi/circuits + :alt: Number of Downloads + + .. image:: https://pypip.in/format/circuits/badge.svg + :target: https://pypi.python.org/pypi/circuits + :alt: Format + + .. image:: https://pypip.in/license/circuits/badge.svg + :target: https://pypi.python.org/pypi/circuits + :alt: License + + .. image:: https://requires.io/bitbucket/circuits/circuits/requirements.png?branch=default + :target: https://requires.io/bitbucket/circuits/circuits/requirements?branch=default + :alt: Requirements Status + + + Examples + -------- + + + Hello + ..... + + + .. code:: python + + #!/usr/bin/env python + + """circuits Hello World""" + + from circuits import Component, Event + + + class hello(Event): + """hello Event""" + + + class App(Component): + + def hello(self): + """Hello Event Handler""" + + print("Hello World!") + + def started(self, component): + """Started Event Handler + + This is fired internally when your application starts up and can be used to + trigger events that only occur once during startup. + """ + + self.fire(hello()) # Fire hello Event + + raise SystemExit(0) # Terminate the Application + + App().run() + + + Echo Server + ........... + + + .. code:: python + + #!/usr/bin/env python + + """Simple TCP Echo Server + + This example shows how you can create a simple TCP Server (an Echo Service) + utilizing the builtin Socket Components that the circuits library ships with. + """ + + from circuits import handler, Debugger + from circuits.net.sockets import TCPServer + + + class EchoServer(TCPServer): + + @handler("read") + def on_read(self, sock, data): + """Read Event Handler + + This is fired by the underlying Socket Component when there has been + new data read from the connected client. + + ..note :: By simply returning, client/server socket components listen + to ValueChagned events (feedback) to determine if a handler + returned some data and fires a subsequent Write event with + the value returned. + """ + + return data + + # Start and "run" the system. + # Bind to port 0.0.0.0:9000 + app = EchoServer(9000) + Debugger().register(app) + app.run() + + + Hello Web + ......... + + + .. code:: python + + #!/usr/bin/env python + + from circuits.web import Server, Controller + + + class Root(Controller): + + def index(self): + """Index Request Handler + + Controller(s) expose implicitly methods as request handlers. + Request Handlers can still be customized by using the ``@expose`` + decorator. For example exposing as a different path. + """ + + return "Hello World!" + + app = Server(("0.0.0.0", 9000)) + Root().register(app) + app.run() + + + More `examples `_... + Features @@ -70,15 +204,9 @@ Supported Platforms ------------------- - - Linux, FreeBSD, Mac OS X - - Python 2.6, 2.7, 3.2, 3.3 - - pypy 2.0 - - **Windows**: We acknowledge that Windows exists and make reasonable efforts - to maintain compatibility. Unfortunately we cannot guarantee - support at this time. - - **NB**: We are working toward getting Windows supported. + - Linux, FreeBSD, Mac OS X, Windows + - Python 2.6, 2.7, 3.2, 3.3, 3.4 + - pypy 2.0, 2.1, 2.2 Installation @@ -94,12 +222,17 @@ > easy_install circuits Alternatively, you may download the source package from the - `PyPi Page`_ or the `Downloads page`_ on the - `Website`_; extract it and install using:: + `PyPi Page`_ or the `Downloads Page`_ extract it and install using:: > python setup.py install + .. note:: + You can install the `development version + `_ + via ``pip install circuits==dev``. + + License ------- @@ -124,29 +257,6 @@ find on the `#circuits IRC Channel`_ on the `FreeNode IRC Network`_ and the `Mailing List`_. - - .. raw:: html - - - - - - Release Notes - circuits-2.1.0 () - ------------------------------------------ - - - This release adds the following new features to circuits: - - - Python 3 support. - - Windows support. - - PyPy support. - - IPv6 support. - - Better WSGI support. - - Fully documented examples. - - Component Interface querying. - - And many bug fixes! - Keywords: event framework distributed concurrent component asynchronous Platform: POSIX Classifier: Development Status :: 5 - Production/Stable diff -Nru circuits-2.1.0/circuits.egg-info/SOURCES.txt circuits-3.1.0+ds1/circuits.egg-info/SOURCES.txt --- circuits-2.1.0/circuits.egg-info/SOURCES.txt 2013-02-27 11:28:32.000000000 +0000 +++ circuits-3.1.0+ds1/circuits.egg-info/SOURCES.txt 2014-10-31 23:13:39.000000000 +0000 @@ -1,30 +1,26 @@ -.coveragerc -.hgchurn -.hgignore -.hgtags CHANGES.rst LICENSE MANIFEST.in Makefile README.rst -RELEASE.rst +requirements-dev.txt +requirements.txt setup.cfg setup.py tox.ini +bin/circuits.bench +bin/htpasswd circuits/__init__.py circuits/six.py +circuits/version.py circuits.egg-info/PKG-INFO circuits.egg-info/SOURCES.txt circuits.egg-info/dependency_links.txt circuits.egg-info/entry_points.txt -circuits.egg-info/not-zip-safe circuits.egg-info/top_level.txt +circuits.egg-info/zip-safe circuits/app/__init__.py -circuits/app/config.py circuits/app/daemon.py -circuits/app/env.py -circuits/app/log.py -circuits/app/startup.py circuits/core/__init__.py circuits/core/bridge.py circuits/core/components.py @@ -46,18 +42,26 @@ circuits/io/process.py circuits/io/serial.py circuits/net/__init__.py +circuits/net/events.py circuits/net/sockets.py -circuits/net/protocols/__init__.py -circuits/net/protocols/http.py -circuits/net/protocols/irc.py -circuits/net/protocols/line.py -circuits/net/protocols/websocket.py circuits/node/__init__.py circuits/node/client.py circuits/node/events.py circuits/node/node.py circuits/node/server.py circuits/node/utils.py +circuits/protocols/__init__.py +circuits/protocols/http.py +circuits/protocols/line.py +circuits/protocols/websocket.py +circuits/protocols/irc/__init__.py +circuits/protocols/irc/commands.py +circuits/protocols/irc/events.py +circuits/protocols/irc/message.py +circuits/protocols/irc/numerics.py +circuits/protocols/irc/protocol.py +circuits/protocols/irc/replies.py +circuits/protocols/irc/utils.py circuits/tools/__init__.py circuits/web/__init__.py circuits/web/_httpauth.py @@ -71,126 +75,145 @@ circuits/web/http.py circuits/web/loggers.py circuits/web/main.py +circuits/web/processors.py circuits/web/servers.py circuits/web/sessions.py circuits/web/tools.py +circuits/web/url.py circuits/web/utils.py -circuits/web/websocket.py circuits/web/wrappers.py circuits/web/wsgi.py -circuits/web/apps/__init__.py -circuits/web/apps/memorymonitor/__init__.py -circuits/web/apps/memorymonitor/reftree.py -circuits/web/apps/memorymonitor/htdocs/graphs.html -circuits/web/apps/memorymonitor/htdocs/main.css -circuits/web/apps/memorymonitor/htdocs/trace.html -circuits/web/apps/memorymonitor/htdocs/tree.html -circuits/web/apps/webconsole/__init__.py -circuits/web/apps/webconsole/htdocs/index.html circuits/web/dispatchers/__init__.py circuits/web/dispatchers/dispatcher.py circuits/web/dispatchers/jsonrpc.py circuits/web/dispatchers/static.py circuits/web/dispatchers/virtualhosts.py -circuits/web/dispatchers/websockets.py circuits/web/dispatchers/xmlrpc.py +circuits/web/parsers/__init__.py +circuits/web/parsers/http.py +circuits/web/parsers/multipart.py +circuits/web/parsers/querystring.py +circuits/web/websockets/__init__.py +circuits/web/websockets/client.py +circuits/web/websockets/dispatcher.py +docs/.requirements.txt.un~ docs/Makefile docs/check_docs.py docs/circuits-docs.xml +docs/logo.png +docs/logo_small.png docs/make.bat +docs/requirements.txt docs/build/doctrees/changes.doctree docs/build/doctrees/contributors.doctree docs/build/doctrees/environment.pickle docs/build/doctrees/faq.doctree docs/build/doctrees/glossary.doctree docs/build/doctrees/index.doctree -docs/build/doctrees/pypitest.doctree +docs/build/doctrees/readme.doctree +docs/build/doctrees/roadmap.doctree docs/build/doctrees/todo.doctree -docs/build/doctrees/users.doctree -docs/build/doctrees/api/circuits_app.doctree -docs/build/doctrees/api/circuits_app_config.doctree -docs/build/doctrees/api/circuits_app_daemon.doctree -docs/build/doctrees/api/circuits_app_env.doctree -docs/build/doctrees/api/circuits_app_log.doctree -docs/build/doctrees/api/circuits_core.doctree -docs/build/doctrees/api/circuits_core_components.doctree -docs/build/doctrees/api/circuits_core_debugger.doctree -docs/build/doctrees/api/circuits_core_events.doctree -docs/build/doctrees/api/circuits_core_handlers.doctree -docs/build/doctrees/api/circuits_core_loader.doctree -docs/build/doctrees/api/circuits_core_manager.doctree -docs/build/doctrees/api/circuits_core_pollers.doctree -docs/build/doctrees/api/circuits_core_timers.doctree -docs/build/doctrees/api/circuits_core_utils.doctree -docs/build/doctrees/api/circuits_core_values.doctree -docs/build/doctrees/api/circuits_core_workers.doctree -docs/build/doctrees/api/circuits_io.doctree -docs/build/doctrees/api/circuits_io_events.doctree -docs/build/doctrees/api/circuits_io_file.doctree -docs/build/doctrees/api/circuits_io_notify.doctree -docs/build/doctrees/api/circuits_io_serial.doctree -docs/build/doctrees/api/circuits_net.doctree -docs/build/doctrees/api/circuits_net_protocols.doctree -docs/build/doctrees/api/circuits_net_protocols_http.doctree -docs/build/doctrees/api/circuits_net_protocols_irc.doctree -docs/build/doctrees/api/circuits_net_protocols_line.doctree -docs/build/doctrees/api/circuits_net_sockets.doctree -docs/build/doctrees/api/circuits_node.doctree -docs/build/doctrees/api/circuits_node_client.doctree -docs/build/doctrees/api/circuits_node_events.doctree -docs/build/doctrees/api/circuits_node_node.doctree -docs/build/doctrees/api/circuits_node_server.doctree -docs/build/doctrees/api/circuits_node_utils.doctree -docs/build/doctrees/api/circuits_tools.doctree -docs/build/doctrees/api/circuits_web.doctree -docs/build/doctrees/api/circuits_web_client.doctree -docs/build/doctrees/api/circuits_web_constants.doctree -docs/build/doctrees/api/circuits_web_controllers.doctree -docs/build/doctrees/api/circuits_web_dispatchers_dispatcher.doctree -docs/build/doctrees/api/circuits_web_dispatchers_jsonrpc.doctree -docs/build/doctrees/api/circuits_web_dispatchers_static.doctree -docs/build/doctrees/api/circuits_web_dispatchers_virtualhosts.doctree -docs/build/doctrees/api/circuits_web_dispatchers_websockets.doctree -docs/build/doctrees/api/circuits_web_dispatchers_xmlrpc.doctree -docs/build/doctrees/api/circuits_web_errors.doctree -docs/build/doctrees/api/circuits_web_events.doctree -docs/build/doctrees/api/circuits_web_exceptions.doctree -docs/build/doctrees/api/circuits_web_headers.doctree -docs/build/doctrees/api/circuits_web_http.doctree -docs/build/doctrees/api/circuits_web_loggers.doctree -docs/build/doctrees/api/circuits_web_main.doctree -docs/build/doctrees/api/circuits_web_servers.doctree -docs/build/doctrees/api/circuits_web_sessions.doctree -docs/build/doctrees/api/circuits_web_tools.doctree -docs/build/doctrees/api/circuits_web_utils.doctree -docs/build/doctrees/api/circuits_web_websocket.doctree -docs/build/doctrees/api/circuits_web_wrappers.doctree -docs/build/doctrees/api/circuits_web_wsgi.doctree +docs/build/doctrees/api/circuits.app.daemon.doctree +docs/build/doctrees/api/circuits.app.doctree +docs/build/doctrees/api/circuits.core.bridge.doctree +docs/build/doctrees/api/circuits.core.components.doctree +docs/build/doctrees/api/circuits.core.debugger.doctree +docs/build/doctrees/api/circuits.core.doctree +docs/build/doctrees/api/circuits.core.events.doctree +docs/build/doctrees/api/circuits.core.handlers.doctree +docs/build/doctrees/api/circuits.core.helpers.doctree +docs/build/doctrees/api/circuits.core.loader.doctree +docs/build/doctrees/api/circuits.core.manager.doctree +docs/build/doctrees/api/circuits.core.pollers.doctree +docs/build/doctrees/api/circuits.core.timers.doctree +docs/build/doctrees/api/circuits.core.utils.doctree +docs/build/doctrees/api/circuits.core.values.doctree +docs/build/doctrees/api/circuits.core.workers.doctree +docs/build/doctrees/api/circuits.doctree +docs/build/doctrees/api/circuits.io.doctree +docs/build/doctrees/api/circuits.io.events.doctree +docs/build/doctrees/api/circuits.io.file.doctree +docs/build/doctrees/api/circuits.io.notify.doctree +docs/build/doctrees/api/circuits.io.process.doctree +docs/build/doctrees/api/circuits.io.serial.doctree +docs/build/doctrees/api/circuits.net.doctree +docs/build/doctrees/api/circuits.net.events.doctree +docs/build/doctrees/api/circuits.net.sockets.doctree +docs/build/doctrees/api/circuits.node.client.doctree +docs/build/doctrees/api/circuits.node.doctree +docs/build/doctrees/api/circuits.node.events.doctree +docs/build/doctrees/api/circuits.node.node.doctree +docs/build/doctrees/api/circuits.node.server.doctree +docs/build/doctrees/api/circuits.node.utils.doctree +docs/build/doctrees/api/circuits.protocols.doctree +docs/build/doctrees/api/circuits.protocols.http.doctree +docs/build/doctrees/api/circuits.protocols.irc.doctree +docs/build/doctrees/api/circuits.protocols.line.doctree +docs/build/doctrees/api/circuits.protocols.websocket.doctree +docs/build/doctrees/api/circuits.six.doctree +docs/build/doctrees/api/circuits.tools.doctree +docs/build/doctrees/api/circuits.version.doctree +docs/build/doctrees/api/circuits.web.client.doctree +docs/build/doctrees/api/circuits.web.constants.doctree +docs/build/doctrees/api/circuits.web.controllers.doctree +docs/build/doctrees/api/circuits.web.dispatchers.dispatcher.doctree +docs/build/doctrees/api/circuits.web.dispatchers.doctree +docs/build/doctrees/api/circuits.web.dispatchers.jsonrpc.doctree +docs/build/doctrees/api/circuits.web.dispatchers.static.doctree +docs/build/doctrees/api/circuits.web.dispatchers.virtualhosts.doctree +docs/build/doctrees/api/circuits.web.dispatchers.xmlrpc.doctree +docs/build/doctrees/api/circuits.web.doctree +docs/build/doctrees/api/circuits.web.errors.doctree +docs/build/doctrees/api/circuits.web.events.doctree +docs/build/doctrees/api/circuits.web.exceptions.doctree +docs/build/doctrees/api/circuits.web.headers.doctree +docs/build/doctrees/api/circuits.web.http.doctree +docs/build/doctrees/api/circuits.web.loggers.doctree +docs/build/doctrees/api/circuits.web.main.doctree +docs/build/doctrees/api/circuits.web.parsers.doctree +docs/build/doctrees/api/circuits.web.parsers.http.doctree +docs/build/doctrees/api/circuits.web.parsers.multipart.doctree +docs/build/doctrees/api/circuits.web.parsers.querystring.doctree +docs/build/doctrees/api/circuits.web.processors.doctree +docs/build/doctrees/api/circuits.web.servers.doctree +docs/build/doctrees/api/circuits.web.sessions.doctree +docs/build/doctrees/api/circuits.web.tools.doctree +docs/build/doctrees/api/circuits.web.url.doctree +docs/build/doctrees/api/circuits.web.utils.doctree +docs/build/doctrees/api/circuits.web.websockets.client.doctree +docs/build/doctrees/api/circuits.web.websockets.dispatcher.doctree +docs/build/doctrees/api/circuits.web.websockets.doctree +docs/build/doctrees/api/circuits.web.wrappers.doctree +docs/build/doctrees/api/circuits.web.wsgi.doctree docs/build/doctrees/api/index.doctree docs/build/doctrees/dev/contributing.doctree docs/build/doctrees/dev/index.doctree docs/build/doctrees/dev/introduction.doctree docs/build/doctrees/dev/processes.doctree -docs/build/doctrees/howtos/index.doctree -docs/build/doctrees/howtos/simple_server.doctree +docs/build/doctrees/dev/standards.doctree +docs/build/doctrees/examples/index.doctree docs/build/doctrees/man/components.doctree -docs/build/doctrees/man/debugging.doctree +docs/build/doctrees/man/debugger.doctree docs/build/doctrees/man/events.doctree docs/build/doctrees/man/handlers.doctree docs/build/doctrees/man/index.doctree docs/build/doctrees/man/manager.doctree -docs/build/doctrees/man/tools.doctree docs/build/doctrees/man/values.doctree +docs/build/doctrees/man/misc/tools.doctree docs/build/doctrees/start/downloading.doctree docs/build/doctrees/start/index.doctree docs/build/doctrees/start/installing.doctree docs/build/doctrees/start/quick.doctree docs/build/doctrees/start/requirements.doctree -docs/build/doctrees/tutorial/index.doctree -docs/build/doctrees/web/basics.doctree +docs/build/doctrees/tutorials/index.doctree +docs/build/doctrees/tutorials/telnet/index.doctree +docs/build/doctrees/tutorials/woof/index.doctree +docs/build/doctrees/web/features.doctree docs/build/doctrees/web/gettingstarted.doctree +docs/build/doctrees/web/howtos.doctree docs/build/doctrees/web/index.doctree docs/build/doctrees/web/introduction.doctree +docs/build/doctrees/web/miscellaneous.doctree docs/build/html/.buildinfo docs/build/html/changes.html docs/build/html/contributors.html @@ -200,11 +223,11 @@ docs/build/html/index.html docs/build/html/objects.inv docs/build/html/py-modindex.html -docs/build/html/pypitest.html +docs/build/html/readme.html +docs/build/html/roadmap.html docs/build/html/search.html docs/build/html/searchindex.js docs/build/html/todo.html -docs/build/html/users.html docs/build/html/_downloads/001.py docs/build/html/_downloads/002.py docs/build/html/_downloads/003.py @@ -214,227 +237,265 @@ docs/build/html/_downloads/007.py docs/build/html/_downloads/008.py docs/build/html/_downloads/009.py +docs/build/html/_downloads/echoserver.py docs/build/html/_downloads/handler_annotation.py docs/build/html/_downloads/handler_returns.py -docs/build/html/_downloads/simple_server.py +docs/build/html/_downloads/hello.py +docs/build/html/_downloads/helloweb.py +docs/build/html/_downloads/telnet.py +docs/build/html/_images/CircuitsWebServer.png +docs/build/html/_images/Telnet.png +docs/build/html/_images/graphviz-b83b24d47415abeb6163e2ff753b8a7fed644c3e.png +docs/build/html/_images/graphviz-b83b24d47415abeb6163e2ff753b8a7fed644c3e.png.map docs/build/html/_images/graphviz-fa9bbccfbcc0c44bc0636e85a3c610dc406600cf.png docs/build/html/_images/graphviz-fa9bbccfbcc0c44bc0636e85a3c610dc406600cf.png.map -docs/build/html/_images/web.png docs/build/html/_sources/changes.txt docs/build/html/_sources/contributors.txt docs/build/html/_sources/faq.txt docs/build/html/_sources/glossary.txt docs/build/html/_sources/index.txt -docs/build/html/_sources/pypitest.txt +docs/build/html/_sources/readme.txt +docs/build/html/_sources/roadmap.txt docs/build/html/_sources/todo.txt -docs/build/html/_sources/users.txt -docs/build/html/_sources/api/circuits_app.txt -docs/build/html/_sources/api/circuits_app_config.txt -docs/build/html/_sources/api/circuits_app_daemon.txt -docs/build/html/_sources/api/circuits_app_env.txt -docs/build/html/_sources/api/circuits_app_log.txt -docs/build/html/_sources/api/circuits_core.txt -docs/build/html/_sources/api/circuits_core_components.txt -docs/build/html/_sources/api/circuits_core_debugger.txt -docs/build/html/_sources/api/circuits_core_events.txt -docs/build/html/_sources/api/circuits_core_handlers.txt -docs/build/html/_sources/api/circuits_core_loader.txt -docs/build/html/_sources/api/circuits_core_manager.txt -docs/build/html/_sources/api/circuits_core_pollers.txt -docs/build/html/_sources/api/circuits_core_timers.txt -docs/build/html/_sources/api/circuits_core_utils.txt -docs/build/html/_sources/api/circuits_core_values.txt -docs/build/html/_sources/api/circuits_core_workers.txt -docs/build/html/_sources/api/circuits_io.txt -docs/build/html/_sources/api/circuits_io_events.txt -docs/build/html/_sources/api/circuits_io_file.txt -docs/build/html/_sources/api/circuits_io_notify.txt -docs/build/html/_sources/api/circuits_io_serial.txt -docs/build/html/_sources/api/circuits_net.txt -docs/build/html/_sources/api/circuits_net_protocols.txt -docs/build/html/_sources/api/circuits_net_protocols_http.txt -docs/build/html/_sources/api/circuits_net_protocols_irc.txt -docs/build/html/_sources/api/circuits_net_protocols_line.txt -docs/build/html/_sources/api/circuits_net_sockets.txt -docs/build/html/_sources/api/circuits_node.txt -docs/build/html/_sources/api/circuits_node_client.txt -docs/build/html/_sources/api/circuits_node_events.txt -docs/build/html/_sources/api/circuits_node_node.txt -docs/build/html/_sources/api/circuits_node_server.txt -docs/build/html/_sources/api/circuits_node_utils.txt -docs/build/html/_sources/api/circuits_tools.txt -docs/build/html/_sources/api/circuits_web.txt -docs/build/html/_sources/api/circuits_web_client.txt -docs/build/html/_sources/api/circuits_web_constants.txt -docs/build/html/_sources/api/circuits_web_controllers.txt -docs/build/html/_sources/api/circuits_web_dispatchers_dispatcher.txt -docs/build/html/_sources/api/circuits_web_dispatchers_jsonrpc.txt -docs/build/html/_sources/api/circuits_web_dispatchers_static.txt -docs/build/html/_sources/api/circuits_web_dispatchers_virtualhosts.txt -docs/build/html/_sources/api/circuits_web_dispatchers_websockets.txt -docs/build/html/_sources/api/circuits_web_dispatchers_xmlrpc.txt -docs/build/html/_sources/api/circuits_web_errors.txt -docs/build/html/_sources/api/circuits_web_events.txt -docs/build/html/_sources/api/circuits_web_exceptions.txt -docs/build/html/_sources/api/circuits_web_headers.txt -docs/build/html/_sources/api/circuits_web_http.txt -docs/build/html/_sources/api/circuits_web_loggers.txt -docs/build/html/_sources/api/circuits_web_main.txt -docs/build/html/_sources/api/circuits_web_servers.txt -docs/build/html/_sources/api/circuits_web_sessions.txt -docs/build/html/_sources/api/circuits_web_tools.txt -docs/build/html/_sources/api/circuits_web_utils.txt -docs/build/html/_sources/api/circuits_web_websocket.txt -docs/build/html/_sources/api/circuits_web_wrappers.txt -docs/build/html/_sources/api/circuits_web_wsgi.txt +docs/build/html/_sources/api/circuits.app.daemon.txt +docs/build/html/_sources/api/circuits.app.txt +docs/build/html/_sources/api/circuits.core.bridge.txt +docs/build/html/_sources/api/circuits.core.components.txt +docs/build/html/_sources/api/circuits.core.debugger.txt +docs/build/html/_sources/api/circuits.core.events.txt +docs/build/html/_sources/api/circuits.core.handlers.txt +docs/build/html/_sources/api/circuits.core.helpers.txt +docs/build/html/_sources/api/circuits.core.loader.txt +docs/build/html/_sources/api/circuits.core.manager.txt +docs/build/html/_sources/api/circuits.core.pollers.txt +docs/build/html/_sources/api/circuits.core.timers.txt +docs/build/html/_sources/api/circuits.core.txt +docs/build/html/_sources/api/circuits.core.utils.txt +docs/build/html/_sources/api/circuits.core.values.txt +docs/build/html/_sources/api/circuits.core.workers.txt +docs/build/html/_sources/api/circuits.io.events.txt +docs/build/html/_sources/api/circuits.io.file.txt +docs/build/html/_sources/api/circuits.io.notify.txt +docs/build/html/_sources/api/circuits.io.process.txt +docs/build/html/_sources/api/circuits.io.serial.txt +docs/build/html/_sources/api/circuits.io.txt +docs/build/html/_sources/api/circuits.net.events.txt +docs/build/html/_sources/api/circuits.net.sockets.txt +docs/build/html/_sources/api/circuits.net.txt +docs/build/html/_sources/api/circuits.node.client.txt +docs/build/html/_sources/api/circuits.node.events.txt +docs/build/html/_sources/api/circuits.node.node.txt +docs/build/html/_sources/api/circuits.node.server.txt +docs/build/html/_sources/api/circuits.node.txt +docs/build/html/_sources/api/circuits.node.utils.txt +docs/build/html/_sources/api/circuits.protocols.http.txt +docs/build/html/_sources/api/circuits.protocols.irc.txt +docs/build/html/_sources/api/circuits.protocols.line.txt +docs/build/html/_sources/api/circuits.protocols.txt +docs/build/html/_sources/api/circuits.protocols.websocket.txt +docs/build/html/_sources/api/circuits.six.txt +docs/build/html/_sources/api/circuits.tools.txt +docs/build/html/_sources/api/circuits.txt +docs/build/html/_sources/api/circuits.version.txt +docs/build/html/_sources/api/circuits.web.client.txt +docs/build/html/_sources/api/circuits.web.constants.txt +docs/build/html/_sources/api/circuits.web.controllers.txt +docs/build/html/_sources/api/circuits.web.dispatchers.dispatcher.txt +docs/build/html/_sources/api/circuits.web.dispatchers.jsonrpc.txt +docs/build/html/_sources/api/circuits.web.dispatchers.static.txt +docs/build/html/_sources/api/circuits.web.dispatchers.txt +docs/build/html/_sources/api/circuits.web.dispatchers.virtualhosts.txt +docs/build/html/_sources/api/circuits.web.dispatchers.xmlrpc.txt +docs/build/html/_sources/api/circuits.web.errors.txt +docs/build/html/_sources/api/circuits.web.events.txt +docs/build/html/_sources/api/circuits.web.exceptions.txt +docs/build/html/_sources/api/circuits.web.headers.txt +docs/build/html/_sources/api/circuits.web.http.txt +docs/build/html/_sources/api/circuits.web.loggers.txt +docs/build/html/_sources/api/circuits.web.main.txt +docs/build/html/_sources/api/circuits.web.parsers.http.txt +docs/build/html/_sources/api/circuits.web.parsers.multipart.txt +docs/build/html/_sources/api/circuits.web.parsers.querystring.txt +docs/build/html/_sources/api/circuits.web.parsers.txt +docs/build/html/_sources/api/circuits.web.processors.txt +docs/build/html/_sources/api/circuits.web.servers.txt +docs/build/html/_sources/api/circuits.web.sessions.txt +docs/build/html/_sources/api/circuits.web.tools.txt +docs/build/html/_sources/api/circuits.web.txt +docs/build/html/_sources/api/circuits.web.url.txt +docs/build/html/_sources/api/circuits.web.utils.txt +docs/build/html/_sources/api/circuits.web.websockets.client.txt +docs/build/html/_sources/api/circuits.web.websockets.dispatcher.txt +docs/build/html/_sources/api/circuits.web.websockets.txt +docs/build/html/_sources/api/circuits.web.wrappers.txt +docs/build/html/_sources/api/circuits.web.wsgi.txt docs/build/html/_sources/api/index.txt docs/build/html/_sources/dev/contributing.txt docs/build/html/_sources/dev/index.txt docs/build/html/_sources/dev/introduction.txt docs/build/html/_sources/dev/processes.txt -docs/build/html/_sources/howtos/index.txt -docs/build/html/_sources/howtos/simple_server.txt +docs/build/html/_sources/dev/standards.txt +docs/build/html/_sources/examples/index.txt docs/build/html/_sources/man/components.txt -docs/build/html/_sources/man/debugging.txt +docs/build/html/_sources/man/debugger.txt docs/build/html/_sources/man/events.txt docs/build/html/_sources/man/handlers.txt docs/build/html/_sources/man/index.txt docs/build/html/_sources/man/manager.txt -docs/build/html/_sources/man/tools.txt docs/build/html/_sources/man/values.txt +docs/build/html/_sources/man/misc/tools.txt docs/build/html/_sources/start/downloading.txt docs/build/html/_sources/start/index.txt docs/build/html/_sources/start/installing.txt docs/build/html/_sources/start/quick.txt docs/build/html/_sources/start/requirements.txt -docs/build/html/_sources/tutorial/index.txt -docs/build/html/_sources/web/basics.txt +docs/build/html/_sources/tutorials/index.txt +docs/build/html/_sources/tutorials/telnet/index.txt +docs/build/html/_sources/tutorials/woof/index.txt +docs/build/html/_sources/web/features.txt docs/build/html/_sources/web/gettingstarted.txt +docs/build/html/_sources/web/howtos.txt docs/build/html/_sources/web/index.txt docs/build/html/_sources/web/introduction.txt +docs/build/html/_sources/web/miscellaneous.txt docs/build/html/_static/ajax-loader.gif docs/build/html/_static/basic.css docs/build/html/_static/comment-bright.png docs/build/html/_static/comment-close.png docs/build/html/_static/comment.png docs/build/html/_static/default.css -docs/build/html/_static/djangodocs.css -docs/build/html/_static/docicons-behindscenes.png -docs/build/html/_static/docicons-note.png -docs/build/html/_static/docicons-philosophy.png docs/build/html/_static/doctools.js docs/build/html/_static/down-pressed.png docs/build/html/_static/down.png docs/build/html/_static/file.png -docs/build/html/_static/homepage.css docs/build/html/_static/jquery.js docs/build/html/_static/logo.png docs/build/html/_static/minus.png docs/build/html/_static/plus.png docs/build/html/_static/pygments.css -docs/build/html/_static/reset-fonts-grids.css +docs/build/html/_static/rtd.css docs/build/html/_static/searchtools.js +docs/build/html/_static/sidebar.js docs/build/html/_static/tracsphinx.css docs/build/html/_static/underscore.js docs/build/html/_static/up-pressed.png docs/build/html/_static/up.png docs/build/html/_static/websupport.js -docs/build/html/api/circuits_app.html -docs/build/html/api/circuits_app_config.html -docs/build/html/api/circuits_app_daemon.html -docs/build/html/api/circuits_app_env.html -docs/build/html/api/circuits_app_log.html -docs/build/html/api/circuits_core.html -docs/build/html/api/circuits_core_components.html -docs/build/html/api/circuits_core_debugger.html -docs/build/html/api/circuits_core_events.html -docs/build/html/api/circuits_core_handlers.html -docs/build/html/api/circuits_core_loader.html -docs/build/html/api/circuits_core_manager.html -docs/build/html/api/circuits_core_pollers.html -docs/build/html/api/circuits_core_timers.html -docs/build/html/api/circuits_core_utils.html -docs/build/html/api/circuits_core_values.html -docs/build/html/api/circuits_core_workers.html -docs/build/html/api/circuits_io.html -docs/build/html/api/circuits_io_events.html -docs/build/html/api/circuits_io_file.html -docs/build/html/api/circuits_io_notify.html -docs/build/html/api/circuits_io_serial.html -docs/build/html/api/circuits_net.html -docs/build/html/api/circuits_net_protocols.html -docs/build/html/api/circuits_net_protocols_http.html -docs/build/html/api/circuits_net_protocols_irc.html -docs/build/html/api/circuits_net_protocols_line.html -docs/build/html/api/circuits_net_sockets.html -docs/build/html/api/circuits_node.html -docs/build/html/api/circuits_node_client.html -docs/build/html/api/circuits_node_events.html -docs/build/html/api/circuits_node_node.html -docs/build/html/api/circuits_node_server.html -docs/build/html/api/circuits_node_utils.html -docs/build/html/api/circuits_tools.html -docs/build/html/api/circuits_web.html -docs/build/html/api/circuits_web_client.html -docs/build/html/api/circuits_web_constants.html -docs/build/html/api/circuits_web_controllers.html -docs/build/html/api/circuits_web_dispatchers_dispatcher.html -docs/build/html/api/circuits_web_dispatchers_jsonrpc.html -docs/build/html/api/circuits_web_dispatchers_static.html -docs/build/html/api/circuits_web_dispatchers_virtualhosts.html -docs/build/html/api/circuits_web_dispatchers_websockets.html -docs/build/html/api/circuits_web_dispatchers_xmlrpc.html -docs/build/html/api/circuits_web_errors.html -docs/build/html/api/circuits_web_events.html -docs/build/html/api/circuits_web_exceptions.html -docs/build/html/api/circuits_web_headers.html -docs/build/html/api/circuits_web_http.html -docs/build/html/api/circuits_web_loggers.html -docs/build/html/api/circuits_web_main.html -docs/build/html/api/circuits_web_servers.html -docs/build/html/api/circuits_web_sessions.html -docs/build/html/api/circuits_web_tools.html -docs/build/html/api/circuits_web_utils.html -docs/build/html/api/circuits_web_websocket.html -docs/build/html/api/circuits_web_wrappers.html -docs/build/html/api/circuits_web_wsgi.html +docs/build/html/api/circuits.app.daemon.html +docs/build/html/api/circuits.app.html +docs/build/html/api/circuits.core.bridge.html +docs/build/html/api/circuits.core.components.html +docs/build/html/api/circuits.core.debugger.html +docs/build/html/api/circuits.core.events.html +docs/build/html/api/circuits.core.handlers.html +docs/build/html/api/circuits.core.helpers.html +docs/build/html/api/circuits.core.html +docs/build/html/api/circuits.core.loader.html +docs/build/html/api/circuits.core.manager.html +docs/build/html/api/circuits.core.pollers.html +docs/build/html/api/circuits.core.timers.html +docs/build/html/api/circuits.core.utils.html +docs/build/html/api/circuits.core.values.html +docs/build/html/api/circuits.core.workers.html +docs/build/html/api/circuits.html +docs/build/html/api/circuits.io.events.html +docs/build/html/api/circuits.io.file.html +docs/build/html/api/circuits.io.html +docs/build/html/api/circuits.io.notify.html +docs/build/html/api/circuits.io.process.html +docs/build/html/api/circuits.io.serial.html +docs/build/html/api/circuits.net.events.html +docs/build/html/api/circuits.net.html +docs/build/html/api/circuits.net.sockets.html +docs/build/html/api/circuits.node.client.html +docs/build/html/api/circuits.node.events.html +docs/build/html/api/circuits.node.html +docs/build/html/api/circuits.node.node.html +docs/build/html/api/circuits.node.server.html +docs/build/html/api/circuits.node.utils.html +docs/build/html/api/circuits.protocols.html +docs/build/html/api/circuits.protocols.http.html +docs/build/html/api/circuits.protocols.irc.html +docs/build/html/api/circuits.protocols.line.html +docs/build/html/api/circuits.protocols.websocket.html +docs/build/html/api/circuits.six.html +docs/build/html/api/circuits.tools.html +docs/build/html/api/circuits.version.html +docs/build/html/api/circuits.web.client.html +docs/build/html/api/circuits.web.constants.html +docs/build/html/api/circuits.web.controllers.html +docs/build/html/api/circuits.web.dispatchers.dispatcher.html +docs/build/html/api/circuits.web.dispatchers.html +docs/build/html/api/circuits.web.dispatchers.jsonrpc.html +docs/build/html/api/circuits.web.dispatchers.static.html +docs/build/html/api/circuits.web.dispatchers.virtualhosts.html +docs/build/html/api/circuits.web.dispatchers.xmlrpc.html +docs/build/html/api/circuits.web.errors.html +docs/build/html/api/circuits.web.events.html +docs/build/html/api/circuits.web.exceptions.html +docs/build/html/api/circuits.web.headers.html +docs/build/html/api/circuits.web.html +docs/build/html/api/circuits.web.http.html +docs/build/html/api/circuits.web.loggers.html +docs/build/html/api/circuits.web.main.html +docs/build/html/api/circuits.web.parsers.html +docs/build/html/api/circuits.web.parsers.http.html +docs/build/html/api/circuits.web.parsers.multipart.html +docs/build/html/api/circuits.web.parsers.querystring.html +docs/build/html/api/circuits.web.processors.html +docs/build/html/api/circuits.web.servers.html +docs/build/html/api/circuits.web.sessions.html +docs/build/html/api/circuits.web.tools.html +docs/build/html/api/circuits.web.url.html +docs/build/html/api/circuits.web.utils.html +docs/build/html/api/circuits.web.websockets.client.html +docs/build/html/api/circuits.web.websockets.dispatcher.html +docs/build/html/api/circuits.web.websockets.html +docs/build/html/api/circuits.web.wrappers.html +docs/build/html/api/circuits.web.wsgi.html docs/build/html/api/index.html docs/build/html/dev/contributing.html docs/build/html/dev/index.html docs/build/html/dev/introduction.html docs/build/html/dev/processes.html -docs/build/html/howtos/index.html -docs/build/html/howtos/simple_server.html +docs/build/html/dev/standards.html +docs/build/html/examples/index.html docs/build/html/man/components.html -docs/build/html/man/debugging.html +docs/build/html/man/debugger.html docs/build/html/man/events.html docs/build/html/man/handlers.html docs/build/html/man/index.html docs/build/html/man/manager.html -docs/build/html/man/tools.html docs/build/html/man/values.html +docs/build/html/man/misc/tools.html docs/build/html/start/downloading.html docs/build/html/start/index.html docs/build/html/start/installing.html docs/build/html/start/quick.html docs/build/html/start/requirements.html -docs/build/html/tutorial/index.html -docs/build/html/web/basics.html +docs/build/html/tutorials/index.html +docs/build/html/tutorials/telnet/index.html +docs/build/html/tutorials/woof/index.html +docs/build/html/web/features.html docs/build/html/web/gettingstarted.html +docs/build/html/web/howtos.html docs/build/html/web/index.html docs/build/html/web/introduction.html +docs/build/html/web/miscellaneous.html +docs/source/.conf.py.un~ docs/source/changes.rst docs/source/conf.py docs/source/contributors.rst docs/source/faq.rst docs/source/glossary.rst docs/source/index.rst -docs/source/pypitest.rst -docs/source/requirements.txt +docs/source/readme.rst +docs/source/roadmap.rst docs/source/todo.rst -docs/source/users.rst docs/source/_static/logo.png +docs/source/_static/rtd.css docs/source/_static/tracsphinx.css +docs/source/_templates/layout.html docs/source/_themes/om/genindex.html docs/source/_themes/om/layout.html docs/source/_themes/om/modindex.html @@ -447,122 +508,168 @@ docs/source/_themes/om/static/docicons-philosophy.png docs/source/_themes/om/static/homepage.css docs/source/_themes/om/static/reset-fonts-grids.css -docs/source/api/circuits_app.rst -docs/source/api/circuits_app_config.rst -docs/source/api/circuits_app_daemon.rst -docs/source/api/circuits_app_env.rst -docs/source/api/circuits_app_log.rst -docs/source/api/circuits_core.rst -docs/source/api/circuits_core_components.rst -docs/source/api/circuits_core_debugger.rst -docs/source/api/circuits_core_events.rst -docs/source/api/circuits_core_handlers.rst -docs/source/api/circuits_core_loader.rst -docs/source/api/circuits_core_manager.rst -docs/source/api/circuits_core_pollers.rst -docs/source/api/circuits_core_timers.rst -docs/source/api/circuits_core_utils.rst -docs/source/api/circuits_core_values.rst -docs/source/api/circuits_core_workers.rst -docs/source/api/circuits_io.rst -docs/source/api/circuits_io_events.rst -docs/source/api/circuits_io_file.rst -docs/source/api/circuits_io_notify.rst -docs/source/api/circuits_io_serial.rst -docs/source/api/circuits_net.rst -docs/source/api/circuits_net_protocols.rst -docs/source/api/circuits_net_protocols_http.rst -docs/source/api/circuits_net_protocols_irc.rst -docs/source/api/circuits_net_protocols_line.rst -docs/source/api/circuits_net_sockets.rst -docs/source/api/circuits_node.rst -docs/source/api/circuits_node_client.rst -docs/source/api/circuits_node_events.rst -docs/source/api/circuits_node_node.rst -docs/source/api/circuits_node_server.rst -docs/source/api/circuits_node_utils.rst -docs/source/api/circuits_tools.rst -docs/source/api/circuits_web.rst -docs/source/api/circuits_web_client.rst -docs/source/api/circuits_web_constants.rst -docs/source/api/circuits_web_controllers.rst -docs/source/api/circuits_web_dispatchers_dispatcher.rst -docs/source/api/circuits_web_dispatchers_jsonrpc.rst -docs/source/api/circuits_web_dispatchers_static.rst -docs/source/api/circuits_web_dispatchers_virtualhosts.rst -docs/source/api/circuits_web_dispatchers_websockets.rst -docs/source/api/circuits_web_dispatchers_xmlrpc.rst -docs/source/api/circuits_web_errors.rst -docs/source/api/circuits_web_events.rst -docs/source/api/circuits_web_exceptions.rst -docs/source/api/circuits_web_headers.rst -docs/source/api/circuits_web_http.rst -docs/source/api/circuits_web_loggers.rst -docs/source/api/circuits_web_main.rst -docs/source/api/circuits_web_servers.rst -docs/source/api/circuits_web_sessions.rst -docs/source/api/circuits_web_tools.rst -docs/source/api/circuits_web_utils.rst -docs/source/api/circuits_web_websocket.rst -docs/source/api/circuits_web_wrappers.rst -docs/source/api/circuits_web_wsgi.rst +docs/source/api/circuits.app.daemon.rst +docs/source/api/circuits.app.rst +docs/source/api/circuits.core.bridge.rst +docs/source/api/circuits.core.components.rst +docs/source/api/circuits.core.debugger.rst +docs/source/api/circuits.core.events.rst +docs/source/api/circuits.core.handlers.rst +docs/source/api/circuits.core.helpers.rst +docs/source/api/circuits.core.loader.rst +docs/source/api/circuits.core.manager.rst +docs/source/api/circuits.core.pollers.rst +docs/source/api/circuits.core.rst +docs/source/api/circuits.core.timers.rst +docs/source/api/circuits.core.utils.rst +docs/source/api/circuits.core.values.rst +docs/source/api/circuits.core.workers.rst +docs/source/api/circuits.io.events.rst +docs/source/api/circuits.io.file.rst +docs/source/api/circuits.io.notify.rst +docs/source/api/circuits.io.process.rst +docs/source/api/circuits.io.rst +docs/source/api/circuits.io.serial.rst +docs/source/api/circuits.net.events.rst +docs/source/api/circuits.net.rst +docs/source/api/circuits.net.sockets.rst +docs/source/api/circuits.node.client.rst +docs/source/api/circuits.node.events.rst +docs/source/api/circuits.node.node.rst +docs/source/api/circuits.node.rst +docs/source/api/circuits.node.server.rst +docs/source/api/circuits.node.utils.rst +docs/source/api/circuits.protocols.http.rst +docs/source/api/circuits.protocols.irc.rst +docs/source/api/circuits.protocols.line.rst +docs/source/api/circuits.protocols.rst +docs/source/api/circuits.protocols.websocket.rst +docs/source/api/circuits.rst +docs/source/api/circuits.six.rst +docs/source/api/circuits.tools.rst +docs/source/api/circuits.version.rst +docs/source/api/circuits.web.client.rst +docs/source/api/circuits.web.constants.rst +docs/source/api/circuits.web.controllers.rst +docs/source/api/circuits.web.dispatchers.dispatcher.rst +docs/source/api/circuits.web.dispatchers.jsonrpc.rst +docs/source/api/circuits.web.dispatchers.rst +docs/source/api/circuits.web.dispatchers.static.rst +docs/source/api/circuits.web.dispatchers.virtualhosts.rst +docs/source/api/circuits.web.dispatchers.xmlrpc.rst +docs/source/api/circuits.web.errors.rst +docs/source/api/circuits.web.events.rst +docs/source/api/circuits.web.exceptions.rst +docs/source/api/circuits.web.headers.rst +docs/source/api/circuits.web.http.rst +docs/source/api/circuits.web.loggers.rst +docs/source/api/circuits.web.main.rst +docs/source/api/circuits.web.parsers.http.rst +docs/source/api/circuits.web.parsers.multipart.rst +docs/source/api/circuits.web.parsers.querystring.rst +docs/source/api/circuits.web.parsers.rst +docs/source/api/circuits.web.processors.rst +docs/source/api/circuits.web.rst +docs/source/api/circuits.web.servers.rst +docs/source/api/circuits.web.sessions.rst +docs/source/api/circuits.web.tools.rst +docs/source/api/circuits.web.url.rst +docs/source/api/circuits.web.utils.rst +docs/source/api/circuits.web.websockets.client.rst +docs/source/api/circuits.web.websockets.dispatcher.rst +docs/source/api/circuits.web.websockets.rst +docs/source/api/circuits.web.wrappers.rst +docs/source/api/circuits.web.wsgi.rst docs/source/api/index.rst docs/source/dev/contributing.rst docs/source/dev/index.rst docs/source/dev/introduction.rst docs/source/dev/processes.rst -docs/source/howtos/index.rst -docs/source/howtos/simple_server.py -docs/source/howtos/simple_server.rst -docs/source/images/web.png +docs/source/dev/standards.rst +docs/source/examples/.echoserver.py.un~ +docs/source/examples/.helloweb.py.un~ +docs/source/examples/echoserver.py +docs/source/examples/hello.py +docs/source/examples/helloweb.py +docs/source/examples/index.rst +docs/source/images/CircuitsWebServer.png docs/source/man/components.rst -docs/source/man/debugging.rst +docs/source/man/debugger.rst docs/source/man/events.rst docs/source/man/handlers.rst docs/source/man/index.rst docs/source/man/manager.rst -docs/source/man/tools.rst docs/source/man/values.rst +docs/source/man/examples/Telnet.dot +docs/source/man/examples/Telnet.png docs/source/man/examples/handler_annotation.py docs/source/man/examples/handler_returns.py +docs/source/man/misc/tools.rst docs/source/start/downloading.rst docs/source/start/index.rst docs/source/start/installing.rst docs/source/start/quick.rst docs/source/start/requirements.rst -docs/source/tutorial/001.py -docs/source/tutorial/002.py -docs/source/tutorial/003.py -docs/source/tutorial/004.py -docs/source/tutorial/005.py -docs/source/tutorial/006.py -docs/source/tutorial/007.py -docs/source/tutorial/008.py -docs/source/tutorial/009.py -docs/source/tutorial/index.rst -docs/source/web/basics.rst +docs/source/tutorials/index.rst +docs/source/tutorials/telnet/Telnet.dot +docs/source/tutorials/telnet/index.rst +docs/source/tutorials/telnet/index.rst.bak +docs/source/tutorials/telnet/telnet.py +docs/source/tutorials/woof/.007.py.un~ +docs/source/tutorials/woof/001.py +docs/source/tutorials/woof/002.py +docs/source/tutorials/woof/003.py +docs/source/tutorials/woof/004.py +docs/source/tutorials/woof/005.py +docs/source/tutorials/woof/006.py +docs/source/tutorials/woof/007.py +docs/source/tutorials/woof/008.py +docs/source/tutorials/woof/009.py +docs/source/tutorials/woof/index.rst +docs/source/web/features.rst docs/source/web/gettingstarted.rst +docs/source/web/howtos.rst docs/source/web/index.rst docs/source/web/introduction.rst +docs/source/web/miscellaneous.rst +examples/.wget.py.un~ examples/99bottles.py examples/cat.py examples/chatserver.py examples/circ.py examples/dirwatch.py +examples/dnsclient.py +examples/dnsserver.py +examples/echoserial.py examples/echoserver.py +examples/echoserverunix.py +examples/factorial.py +examples/filter.py examples/hello.py examples/hello_bridge.py +examples/index.rst examples/ircbot.py examples/ircclient.py +examples/ircd.py +examples/ping.py examples/portforward.py +examples/proxy.py +examples/signals.py examples/tail.py examples/telnet.py -examples/test_memory_leaks.py -examples/test_worker.py examples/timers.py +examples/wget.py +examples/node/hello_node.py +examples/node/nodeserver.py +examples/node/increment/client.py +examples/node/increment/server.py examples/primitives/call.py examples/primitives/fire.py examples/primitives/wait.py +examples/testing/pytest/README.rst +examples/testing/pytest/conftest.py +examples/testing/pytest/hello.py +examples/testing/pytest/test_hello.py examples/web/acldemo.py examples/web/authdemo.py examples/web/basecontrollers.py @@ -570,8 +677,7 @@ examples/web/ca-chain.pem examples/web/cert.pem examples/web/controllers.py -examples/web/counter.py -examples/web/counter.txt +examples/web/crud.py examples/web/fileupload.py examples/web/filtering.py examples/web/forms.py @@ -594,7 +700,7 @@ examples/web/wiki.zip examples/web/wsgi.py examples/web/wsgiapp.py -examples/web/xmlrpc.py +examples/web/xmlrpc_demo.py examples/web/static/css/base.css examples/web/static/img/rss.gif examples/web/static/img/valid-xhtml10.png @@ -636,24 +742,50 @@ examples/web/wiki/static/images/header_bg.png examples/web/wiki/tpl/edit.html examples/web/wiki/tpl/view.html -man/circuits.bench.1 -man/circuits.web.1 -scripts/circuits.bench -scripts/circuits.web +fabfile/__init__.py +fabfile/docker.py +fabfile/docs.py +fabfile/help.py +fabfile/utils.py tests/__init__.py +tests/__init__.pyc tests/conftest.py +tests/conftest.pyc tests/main.py +tests/main.pyc +tests/__pycache__/__init__.cpython-32.pyc +tests/__pycache__/__init__.cpython-33.pyc +tests/__pycache__/__init__.cpython-34.pyc +tests/__pycache__/conftest.cpython-32.pyc +tests/__pycache__/conftest.cpython-33.pyc +tests/__pycache__/conftest.cpython-34.pyc tests/app/__init__.py +tests/app/__init__.pyc tests/app/app.py -tests/app/test_config.py +tests/app/app.pyc tests/app/test_daemon.py -tests/app/test_env.py -tests/app/test_logger.py +tests/app/__pycache__/__init__.cpython-32.pyc +tests/app/__pycache__/__init__.cpython-33.pyc +tests/app/__pycache__/__init__.cpython-34.pyc +tests/app/__pycache__/app.cpython-32.pyc +tests/app/__pycache__/app.cpython-33.pyc +tests/app/__pycache__/app.cpython-34.pyc +tests/app/__pycache__/test_daemon.cpython-26-PYTEST.pyc +tests/app/__pycache__/test_daemon.cpython-27-PYTEST.pyc +tests/app/__pycache__/test_daemon.cpython-32-PYTEST.pyc +tests/app/__pycache__/test_daemon.cpython-33-PYTEST.pyc +tests/app/__pycache__/test_daemon.cpython-34-PYTEST.pyc +tests/core/.test_bridge.py.un~ tests/core/__init__.py +tests/core/__init__.pyc tests/core/app.py +tests/core/app.pyc tests/core/signalapp.py +tests/core/signalapp.pyc tests/core/test_bridge.py tests/core/test_call_wait.py +tests/core/test_call_wait_order.py +tests/core/test_call_wait_timeout.py tests/core/test_channel_selection.py tests/core/test_complete.py tests/core/test_component_repr.py @@ -664,8 +796,8 @@ tests/core/test_dynamic_handlers.py tests/core/test_errors.py tests/core/test_event.py +tests/core/test_event_priority.py tests/core/test_feedback.py -tests/core/test_filter_order.py tests/core/test_filters.py tests/core/test_generate_events.py tests/core/test_generator_value.py @@ -675,42 +807,317 @@ tests/core/test_interface_query.py tests/core/test_loader.py tests/core/test_manager_repr.py +tests/core/test_new_filter.py tests/core/test_priority.py tests/core/test_signals.py -tests/core/test_singleton.py tests/core/test_timers.py tests/core/test_utils.py tests/core/test_value.py tests/core/test_worker_process.py tests/core/test_worker_thread.py +tests/core/__pycache__/__init__.cpython-32.pyc +tests/core/__pycache__/__init__.cpython-33.pyc +tests/core/__pycache__/__init__.cpython-34.pyc +tests/core/__pycache__/app.cpython-32.pyc +tests/core/__pycache__/app.cpython-33.pyc +tests/core/__pycache__/app.cpython-34.pyc +tests/core/__pycache__/signalapp.cpython-32.pyc +tests/core/__pycache__/signalapp.cpython-33.pyc +tests/core/__pycache__/signalapp.cpython-34.pyc +tests/core/__pycache__/test_bridge.cpython-26-PYTEST.pyc +tests/core/__pycache__/test_bridge.cpython-27-PYTEST.pyc +tests/core/__pycache__/test_bridge.cpython-32-PYTEST.pyc +tests/core/__pycache__/test_bridge.cpython-33-PYTEST.pyc +tests/core/__pycache__/test_bridge.cpython-34-PYTEST.pyc +tests/core/__pycache__/test_call_wait.cpython-26-PYTEST.pyc +tests/core/__pycache__/test_call_wait.cpython-27-PYTEST.pyc +tests/core/__pycache__/test_call_wait.cpython-32-PYTEST.pyc +tests/core/__pycache__/test_call_wait.cpython-33-PYTEST.pyc +tests/core/__pycache__/test_call_wait.cpython-34-PYTEST.pyc +tests/core/__pycache__/test_call_wait_order.cpython-26-PYTEST.pyc +tests/core/__pycache__/test_call_wait_order.cpython-27-PYTEST.pyc +tests/core/__pycache__/test_call_wait_order.cpython-32-PYTEST.pyc +tests/core/__pycache__/test_call_wait_order.cpython-33-PYTEST.pyc +tests/core/__pycache__/test_call_wait_order.cpython-34-PYTEST.pyc +tests/core/__pycache__/test_call_wait_timeout.cpython-26-PYTEST.pyc +tests/core/__pycache__/test_call_wait_timeout.cpython-27-PYTEST.pyc +tests/core/__pycache__/test_call_wait_timeout.cpython-32-PYTEST.pyc +tests/core/__pycache__/test_call_wait_timeout.cpython-33-PYTEST.pyc +tests/core/__pycache__/test_call_wait_timeout.cpython-34-PYTEST.pyc +tests/core/__pycache__/test_channel_selection.cpython-26-PYTEST.pyc +tests/core/__pycache__/test_channel_selection.cpython-27-PYTEST.pyc +tests/core/__pycache__/test_channel_selection.cpython-32-PYTEST.pyc +tests/core/__pycache__/test_channel_selection.cpython-33-PYTEST.pyc +tests/core/__pycache__/test_channel_selection.cpython-34-PYTEST.pyc +tests/core/__pycache__/test_complete.cpython-26-PYTEST.pyc +tests/core/__pycache__/test_complete.cpython-27-PYTEST.pyc +tests/core/__pycache__/test_complete.cpython-32-PYTEST.pyc +tests/core/__pycache__/test_complete.cpython-33-PYTEST.pyc +tests/core/__pycache__/test_complete.cpython-34-PYTEST.pyc +tests/core/__pycache__/test_component_repr.cpython-26-PYTEST.pyc +tests/core/__pycache__/test_component_repr.cpython-27-PYTEST.pyc +tests/core/__pycache__/test_component_repr.cpython-32-PYTEST.pyc +tests/core/__pycache__/test_component_repr.cpython-33-PYTEST.pyc +tests/core/__pycache__/test_component_repr.cpython-34-PYTEST.pyc +tests/core/__pycache__/test_component_setup.cpython-26-PYTEST.pyc +tests/core/__pycache__/test_component_setup.cpython-27-PYTEST.pyc +tests/core/__pycache__/test_component_setup.cpython-32-PYTEST.pyc +tests/core/__pycache__/test_component_setup.cpython-33-PYTEST.pyc +tests/core/__pycache__/test_component_setup.cpython-34-PYTEST.pyc +tests/core/__pycache__/test_component_targeting.cpython-26-PYTEST.pyc +tests/core/__pycache__/test_component_targeting.cpython-27-PYTEST.pyc +tests/core/__pycache__/test_component_targeting.cpython-32-PYTEST.pyc +tests/core/__pycache__/test_component_targeting.cpython-33-PYTEST.pyc +tests/core/__pycache__/test_component_targeting.cpython-34-PYTEST.pyc +tests/core/__pycache__/test_core.cpython-26-PYTEST.pyc +tests/core/__pycache__/test_core.cpython-27-PYTEST.pyc +tests/core/__pycache__/test_core.cpython-32-PYTEST.pyc +tests/core/__pycache__/test_core.cpython-33-PYTEST.pyc +tests/core/__pycache__/test_core.cpython-34-PYTEST.pyc +tests/core/__pycache__/test_debugger.cpython-26-PYTEST.pyc +tests/core/__pycache__/test_debugger.cpython-27-PYTEST.pyc +tests/core/__pycache__/test_debugger.cpython-32-PYTEST.pyc +tests/core/__pycache__/test_debugger.cpython-33-PYTEST.pyc +tests/core/__pycache__/test_debugger.cpython-34-PYTEST.pyc +tests/core/__pycache__/test_dynamic_handlers.cpython-26-PYTEST.pyc +tests/core/__pycache__/test_dynamic_handlers.cpython-27-PYTEST.pyc +tests/core/__pycache__/test_dynamic_handlers.cpython-32-PYTEST.pyc +tests/core/__pycache__/test_dynamic_handlers.cpython-33-PYTEST.pyc +tests/core/__pycache__/test_dynamic_handlers.cpython-34-PYTEST.pyc +tests/core/__pycache__/test_errors.cpython-26-PYTEST.pyc +tests/core/__pycache__/test_errors.cpython-27-PYTEST.pyc +tests/core/__pycache__/test_errors.cpython-32-PYTEST.pyc +tests/core/__pycache__/test_errors.cpython-33-PYTEST.pyc +tests/core/__pycache__/test_errors.cpython-34-PYTEST.pyc +tests/core/__pycache__/test_event.cpython-26-PYTEST.pyc +tests/core/__pycache__/test_event.cpython-27-PYTEST.pyc +tests/core/__pycache__/test_event.cpython-32-PYTEST.pyc +tests/core/__pycache__/test_event.cpython-33-PYTEST.pyc +tests/core/__pycache__/test_event.cpython-34-PYTEST.pyc +tests/core/__pycache__/test_event_priority.cpython-26-PYTEST.pyc +tests/core/__pycache__/test_event_priority.cpython-27-PYTEST.pyc +tests/core/__pycache__/test_event_priority.cpython-32-PYTEST.pyc +tests/core/__pycache__/test_event_priority.cpython-33-PYTEST.pyc +tests/core/__pycache__/test_event_priority.cpython-34-PYTEST.pyc +tests/core/__pycache__/test_feedback.cpython-26-PYTEST.pyc +tests/core/__pycache__/test_feedback.cpython-27-PYTEST.pyc +tests/core/__pycache__/test_feedback.cpython-32-PYTEST.pyc +tests/core/__pycache__/test_feedback.cpython-33-PYTEST.pyc +tests/core/__pycache__/test_feedback.cpython-34-PYTEST.pyc +tests/core/__pycache__/test_filters.cpython-26-PYTEST.pyc +tests/core/__pycache__/test_filters.cpython-27-PYTEST.pyc +tests/core/__pycache__/test_filters.cpython-32-PYTEST.pyc +tests/core/__pycache__/test_filters.cpython-33-PYTEST.pyc +tests/core/__pycache__/test_filters.cpython-34-PYTEST.pyc +tests/core/__pycache__/test_generate_events.cpython-26-PYTEST.pyc +tests/core/__pycache__/test_generate_events.cpython-27-PYTEST.pyc +tests/core/__pycache__/test_generate_events.cpython-32-PYTEST.pyc +tests/core/__pycache__/test_generate_events.cpython-33-PYTEST.pyc +tests/core/__pycache__/test_generate_events.cpython-34-PYTEST.pyc +tests/core/__pycache__/test_generator_value.cpython-26-PYTEST.pyc +tests/core/__pycache__/test_generator_value.cpython-27-PYTEST.pyc +tests/core/__pycache__/test_generator_value.cpython-32-PYTEST.pyc +tests/core/__pycache__/test_generator_value.cpython-33-PYTEST.pyc +tests/core/__pycache__/test_generator_value.cpython-34-PYTEST.pyc +tests/core/__pycache__/test_globals.cpython-26-PYTEST.pyc +tests/core/__pycache__/test_globals.cpython-27-PYTEST.pyc +tests/core/__pycache__/test_globals.cpython-32-PYTEST.pyc +tests/core/__pycache__/test_globals.cpython-33-PYTEST.pyc +tests/core/__pycache__/test_globals.cpython-34-PYTEST.pyc +tests/core/__pycache__/test_imports.cpython-26-PYTEST.pyc +tests/core/__pycache__/test_imports.cpython-27-PYTEST.pyc +tests/core/__pycache__/test_imports.cpython-32-PYTEST.pyc +tests/core/__pycache__/test_imports.cpython-33-PYTEST.pyc +tests/core/__pycache__/test_imports.cpython-34-PYTEST.pyc +tests/core/__pycache__/test_inheritence.cpython-26-PYTEST.pyc +tests/core/__pycache__/test_inheritence.cpython-27-PYTEST.pyc +tests/core/__pycache__/test_inheritence.cpython-32-PYTEST.pyc +tests/core/__pycache__/test_inheritence.cpython-33-PYTEST.pyc +tests/core/__pycache__/test_inheritence.cpython-34-PYTEST.pyc +tests/core/__pycache__/test_interface_query.cpython-26-PYTEST.pyc +tests/core/__pycache__/test_interface_query.cpython-27-PYTEST.pyc +tests/core/__pycache__/test_interface_query.cpython-32-PYTEST.pyc +tests/core/__pycache__/test_interface_query.cpython-33-PYTEST.pyc +tests/core/__pycache__/test_interface_query.cpython-34-PYTEST.pyc +tests/core/__pycache__/test_loader.cpython-26-PYTEST.pyc +tests/core/__pycache__/test_loader.cpython-27-PYTEST.pyc +tests/core/__pycache__/test_loader.cpython-32-PYTEST.pyc +tests/core/__pycache__/test_loader.cpython-33-PYTEST.pyc +tests/core/__pycache__/test_loader.cpython-34-PYTEST.pyc +tests/core/__pycache__/test_manager_repr.cpython-26-PYTEST.pyc +tests/core/__pycache__/test_manager_repr.cpython-27-PYTEST.pyc +tests/core/__pycache__/test_manager_repr.cpython-32-PYTEST.pyc +tests/core/__pycache__/test_manager_repr.cpython-33-PYTEST.pyc +tests/core/__pycache__/test_manager_repr.cpython-34-PYTEST.pyc +tests/core/__pycache__/test_new_filter.cpython-26-PYTEST.pyc +tests/core/__pycache__/test_new_filter.cpython-27-PYTEST.pyc +tests/core/__pycache__/test_new_filter.cpython-32-PYTEST.pyc +tests/core/__pycache__/test_new_filter.cpython-33-PYTEST.pyc +tests/core/__pycache__/test_new_filter.cpython-34-PYTEST.pyc +tests/core/__pycache__/test_priority.cpython-26-PYTEST.pyc +tests/core/__pycache__/test_priority.cpython-27-PYTEST.pyc +tests/core/__pycache__/test_priority.cpython-32-PYTEST.pyc +tests/core/__pycache__/test_priority.cpython-33-PYTEST.pyc +tests/core/__pycache__/test_priority.cpython-34-PYTEST.pyc +tests/core/__pycache__/test_signals.cpython-26-PYTEST.pyc +tests/core/__pycache__/test_signals.cpython-27-PYTEST.pyc +tests/core/__pycache__/test_signals.cpython-32-PYTEST.pyc +tests/core/__pycache__/test_signals.cpython-33-PYTEST.pyc +tests/core/__pycache__/test_signals.cpython-34-PYTEST.pyc +tests/core/__pycache__/test_timers.cpython-26-PYTEST.pyc +tests/core/__pycache__/test_timers.cpython-27-PYTEST.pyc +tests/core/__pycache__/test_timers.cpython-32-PYTEST.pyc +tests/core/__pycache__/test_timers.cpython-33-PYTEST.pyc +tests/core/__pycache__/test_timers.cpython-34-PYTEST.pyc +tests/core/__pycache__/test_utils.cpython-26-PYTEST.pyc +tests/core/__pycache__/test_utils.cpython-27-PYTEST.pyc +tests/core/__pycache__/test_utils.cpython-32-PYTEST.pyc +tests/core/__pycache__/test_utils.cpython-33-PYTEST.pyc +tests/core/__pycache__/test_utils.cpython-34-PYTEST.pyc +tests/core/__pycache__/test_value.cpython-26-PYTEST.pyc +tests/core/__pycache__/test_value.cpython-27-PYTEST.pyc +tests/core/__pycache__/test_value.cpython-32-PYTEST.pyc +tests/core/__pycache__/test_value.cpython-33-PYTEST.pyc +tests/core/__pycache__/test_value.cpython-34-PYTEST.pyc +tests/core/__pycache__/test_worker_process.cpython-26-PYTEST.pyc +tests/core/__pycache__/test_worker_process.cpython-27-PYTEST.pyc +tests/core/__pycache__/test_worker_process.cpython-32-PYTEST.pyc +tests/core/__pycache__/test_worker_process.cpython-33-PYTEST.pyc +tests/core/__pycache__/test_worker_process.cpython-34-PYTEST.pyc +tests/core/__pycache__/test_worker_thread.cpython-26-PYTEST.pyc +tests/core/__pycache__/test_worker_thread.cpython-27-PYTEST.pyc +tests/core/__pycache__/test_worker_thread.cpython-32-PYTEST.pyc +tests/core/__pycache__/test_worker_thread.cpython-33-PYTEST.pyc +tests/core/__pycache__/test_worker_thread.cpython-34-PYTEST.pyc tests/io/__init__.py +tests/io/__init__.pyc tests/io/test_file.py tests/io/test_notify.py tests/io/test_process.py +tests/io/__pycache__/__init__.cpython-32.pyc +tests/io/__pycache__/__init__.cpython-33.pyc +tests/io/__pycache__/__init__.cpython-34.pyc +tests/io/__pycache__/test_file.cpython-26-PYTEST.pyc +tests/io/__pycache__/test_file.cpython-27-PYTEST.pyc +tests/io/__pycache__/test_file.cpython-32-PYTEST.pyc +tests/io/__pycache__/test_file.cpython-33-PYTEST.pyc +tests/io/__pycache__/test_file.cpython-34-PYTEST.pyc +tests/io/__pycache__/test_notify.cpython-26-PYTEST.pyc +tests/io/__pycache__/test_notify.cpython-27-PYTEST.pyc +tests/io/__pycache__/test_notify.cpython-32-PYTEST.pyc +tests/io/__pycache__/test_notify.cpython-33-PYTEST.pyc +tests/io/__pycache__/test_notify.cpython-34-PYTEST.pyc +tests/io/__pycache__/test_process.cpython-26-PYTEST.pyc +tests/io/__pycache__/test_process.cpython-27-PYTEST.pyc +tests/io/__pycache__/test_process.cpython-32-PYTEST.pyc +tests/io/__pycache__/test_process.cpython-33-PYTEST.pyc +tests/io/__pycache__/test_process.cpython-34-PYTEST.pyc tests/net/__init__.py +tests/net/__init__.pyc tests/net/client.py +tests/net/client.pyc tests/net/server.py +tests/net/server.pyc tests/net/test_client.py tests/net/test_pipe.py tests/net/test_poller_reuse.py tests/net/test_tcp.py tests/net/test_udp.py tests/net/test_unix.py -tests/net/protocols/__init__.py -tests/net/protocols/test_irc.py -tests/net/protocols/test_line.py +tests/net/__pycache__/__init__.cpython-32.pyc +tests/net/__pycache__/__init__.cpython-33.pyc +tests/net/__pycache__/__init__.cpython-34.pyc +tests/net/__pycache__/client.cpython-32.pyc +tests/net/__pycache__/client.cpython-33.pyc +tests/net/__pycache__/client.cpython-34.pyc +tests/net/__pycache__/server.cpython-32.pyc +tests/net/__pycache__/server.cpython-33.pyc +tests/net/__pycache__/server.cpython-34.pyc +tests/net/__pycache__/test_client.cpython-26-PYTEST.pyc +tests/net/__pycache__/test_client.cpython-27-PYTEST.pyc +tests/net/__pycache__/test_client.cpython-32-PYTEST.pyc +tests/net/__pycache__/test_client.cpython-33-PYTEST.pyc +tests/net/__pycache__/test_client.cpython-34-PYTEST.pyc +tests/net/__pycache__/test_pipe.cpython-26-PYTEST.pyc +tests/net/__pycache__/test_pipe.cpython-27-PYTEST.pyc +tests/net/__pycache__/test_pipe.cpython-32-PYTEST.pyc +tests/net/__pycache__/test_pipe.cpython-33-PYTEST.pyc +tests/net/__pycache__/test_pipe.cpython-34-PYTEST.pyc +tests/net/__pycache__/test_poller_reuse.cpython-26-PYTEST.pyc +tests/net/__pycache__/test_poller_reuse.cpython-27-PYTEST.pyc +tests/net/__pycache__/test_poller_reuse.cpython-32-PYTEST.pyc +tests/net/__pycache__/test_poller_reuse.cpython-33-PYTEST.pyc +tests/net/__pycache__/test_poller_reuse.cpython-34-PYTEST.pyc +tests/net/__pycache__/test_tcp.cpython-26-PYTEST.pyc +tests/net/__pycache__/test_tcp.cpython-27-PYTEST.pyc +tests/net/__pycache__/test_tcp.cpython-32-PYTEST.pyc +tests/net/__pycache__/test_tcp.cpython-33-PYTEST.pyc +tests/net/__pycache__/test_tcp.cpython-34-PYTEST.pyc +tests/net/__pycache__/test_udp.cpython-26-PYTEST.pyc +tests/net/__pycache__/test_udp.cpython-27-PYTEST.pyc +tests/net/__pycache__/test_udp.cpython-32-PYTEST.pyc +tests/net/__pycache__/test_udp.cpython-33-PYTEST.pyc +tests/net/__pycache__/test_udp.cpython-34-PYTEST.pyc +tests/net/__pycache__/test_unix.cpython-26-PYTEST.pyc +tests/net/__pycache__/test_unix.cpython-27-PYTEST.pyc +tests/net/__pycache__/test_unix.cpython-32-PYTEST.pyc +tests/net/__pycache__/test_unix.cpython-33-PYTEST.pyc +tests/net/__pycache__/test_unix.cpython-34-PYTEST.pyc tests/node/test_node.py tests/node/test_utils.py +tests/node/__pycache__/test_node.cpython-26-PYTEST.pyc +tests/node/__pycache__/test_node.cpython-27-PYTEST.pyc +tests/node/__pycache__/test_node.cpython-32-PYTEST.pyc +tests/node/__pycache__/test_node.cpython-33-PYTEST.pyc +tests/node/__pycache__/test_node.cpython-34-PYTEST.pyc +tests/node/__pycache__/test_utils.cpython-26-PYTEST.pyc +tests/node/__pycache__/test_utils.cpython-27-PYTEST.pyc +tests/node/__pycache__/test_utils.cpython-32-PYTEST.pyc +tests/node/__pycache__/test_utils.cpython-33-PYTEST.pyc +tests/node/__pycache__/test_utils.cpython-34-PYTEST.pyc +tests/protocols/.test_irc.py.un~ +tests/protocols/__init__.py +tests/protocols/__init__.pyc +tests/protocols/test_irc.py +tests/protocols/test_line.py +tests/protocols/__pycache__/__init__.cpython-32.pyc +tests/protocols/__pycache__/__init__.cpython-33.pyc +tests/protocols/__pycache__/__init__.cpython-34.pyc +tests/protocols/__pycache__/test_irc.cpython-26-PYTEST.pyc +tests/protocols/__pycache__/test_irc.cpython-27-PYTEST.pyc +tests/protocols/__pycache__/test_irc.cpython-32-PYTEST.pyc +tests/protocols/__pycache__/test_irc.cpython-33-PYTEST.pyc +tests/protocols/__pycache__/test_irc.cpython-34-PYTEST.pyc +tests/protocols/__pycache__/test_line.cpython-26-PYTEST.pyc +tests/protocols/__pycache__/test_line.cpython-27-PYTEST.pyc +tests/protocols/__pycache__/test_line.cpython-32-PYTEST.pyc +tests/protocols/__pycache__/test_line.cpython-33-PYTEST.pyc +tests/protocols/__pycache__/test_line.cpython-34-PYTEST.pyc tests/tools/__init__.py +tests/tools/__init__.pyc tests/tools/test_tools.py +tests/tools/__pycache__/__init__.cpython-32.pyc +tests/tools/__pycache__/__init__.cpython-33.pyc +tests/tools/__pycache__/__init__.cpython-34.pyc +tests/tools/__pycache__/test_tools.cpython-26-PYTEST.pyc +tests/tools/__pycache__/test_tools.cpython-27-PYTEST.pyc +tests/tools/__pycache__/test_tools.cpython-32-PYTEST.pyc +tests/tools/__pycache__/test_tools.cpython-33-PYTEST.pyc +tests/tools/__pycache__/test_tools.cpython-34-PYTEST.pyc tests/web/__init__.py +tests/web/__init__.pyc tests/web/cert.pem tests/web/conftest.py +tests/web/conftest.pyc tests/web/helpers.py +tests/web/helpers.pyc tests/web/jsonrpclib.py +tests/web/jsonrpclib.pyc tests/web/multipartform.py -tests/web/test_100_continue.py +tests/web/multipartform.pyc +tests/web/test_bad_requests.py tests/web/test_basicauth.py +tests/web/test_call_wait.py tests/web/test_client.py tests/web/test_conn.py tests/web/test_cookies.py @@ -720,7 +1127,6 @@ tests/web/test_dispatcher2.py tests/web/test_dispatcher3.py tests/web/test_disps.py -tests/web/test_encodings.py tests/web/test_exceptions.py tests/web/test_expires.py tests/web/test_expose.py @@ -732,9 +1138,11 @@ tests/web/test_jsonrpc.py tests/web/test_large_post.py tests/web/test_logger.py +tests/web/test_methods.py tests/web/test_multipartformdata.py tests/web/test_null_response.py tests/web/test_request_failure.py +tests/web/test_security.py tests/web/test_serve_download.py tests/web/test_serve_file.py tests/web/test_servers.py @@ -758,8 +1166,273 @@ tests/web/test_xmlrpc.py tests/web/test_yield.py tests/web/websocket.py +tests/web/__pycache__/__init__.cpython-32.pyc +tests/web/__pycache__/__init__.cpython-33.pyc +tests/web/__pycache__/__init__.cpython-34.pyc +tests/web/__pycache__/conftest.cpython-32.pyc +tests/web/__pycache__/conftest.cpython-33.pyc +tests/web/__pycache__/conftest.cpython-34.pyc +tests/web/__pycache__/helpers.cpython-32.pyc +tests/web/__pycache__/helpers.cpython-33.pyc +tests/web/__pycache__/helpers.cpython-34.pyc +tests/web/__pycache__/jsonrpclib.cpython-32.pyc +tests/web/__pycache__/jsonrpclib.cpython-33.pyc +tests/web/__pycache__/jsonrpclib.cpython-34.pyc +tests/web/__pycache__/multipartform.cpython-32.pyc +tests/web/__pycache__/multipartform.cpython-33.pyc +tests/web/__pycache__/multipartform.cpython-34.pyc +tests/web/__pycache__/test_bad_requests.cpython-26-PYTEST.pyc +tests/web/__pycache__/test_bad_requests.cpython-27-PYTEST.pyc +tests/web/__pycache__/test_bad_requests.cpython-32-PYTEST.pyc +tests/web/__pycache__/test_bad_requests.cpython-33-PYTEST.pyc +tests/web/__pycache__/test_bad_requests.cpython-34-PYTEST.pyc +tests/web/__pycache__/test_basicauth.cpython-26-PYTEST.pyc +tests/web/__pycache__/test_basicauth.cpython-27-PYTEST.pyc +tests/web/__pycache__/test_basicauth.cpython-32-PYTEST.pyc +tests/web/__pycache__/test_basicauth.cpython-33-PYTEST.pyc +tests/web/__pycache__/test_basicauth.cpython-34-PYTEST.pyc +tests/web/__pycache__/test_call_wait.cpython-26-PYTEST.pyc +tests/web/__pycache__/test_call_wait.cpython-27-PYTEST.pyc +tests/web/__pycache__/test_call_wait.cpython-32-PYTEST.pyc +tests/web/__pycache__/test_call_wait.cpython-33-PYTEST.pyc +tests/web/__pycache__/test_call_wait.cpython-34-PYTEST.pyc +tests/web/__pycache__/test_client.cpython-26-PYTEST.pyc +tests/web/__pycache__/test_client.cpython-27-PYTEST.pyc +tests/web/__pycache__/test_client.cpython-32-PYTEST.pyc +tests/web/__pycache__/test_client.cpython-33-PYTEST.pyc +tests/web/__pycache__/test_client.cpython-34-PYTEST.pyc +tests/web/__pycache__/test_conn.cpython-26-PYTEST.pyc +tests/web/__pycache__/test_conn.cpython-27-PYTEST.pyc +tests/web/__pycache__/test_conn.cpython-32-PYTEST.pyc +tests/web/__pycache__/test_conn.cpython-33-PYTEST.pyc +tests/web/__pycache__/test_conn.cpython-34-PYTEST.pyc +tests/web/__pycache__/test_cookies.cpython-26-PYTEST.pyc +tests/web/__pycache__/test_cookies.cpython-27-PYTEST.pyc +tests/web/__pycache__/test_cookies.cpython-32-PYTEST.pyc +tests/web/__pycache__/test_cookies.cpython-33-PYTEST.pyc +tests/web/__pycache__/test_cookies.cpython-34-PYTEST.pyc +tests/web/__pycache__/test_core.cpython-26-PYTEST.pyc +tests/web/__pycache__/test_core.cpython-27-PYTEST.pyc +tests/web/__pycache__/test_core.cpython-32-PYTEST.pyc +tests/web/__pycache__/test_core.cpython-33-PYTEST.pyc +tests/web/__pycache__/test_core.cpython-34-PYTEST.pyc +tests/web/__pycache__/test_digestauth.cpython-26-PYTEST.pyc +tests/web/__pycache__/test_digestauth.cpython-27-PYTEST.pyc +tests/web/__pycache__/test_digestauth.cpython-32-PYTEST.pyc +tests/web/__pycache__/test_digestauth.cpython-33-PYTEST.pyc +tests/web/__pycache__/test_digestauth.cpython-34-PYTEST.pyc +tests/web/__pycache__/test_dispatcher.cpython-26-PYTEST.pyc +tests/web/__pycache__/test_dispatcher.cpython-27-PYTEST.pyc +tests/web/__pycache__/test_dispatcher.cpython-32-PYTEST.pyc +tests/web/__pycache__/test_dispatcher.cpython-33-PYTEST.pyc +tests/web/__pycache__/test_dispatcher.cpython-34-PYTEST.pyc +tests/web/__pycache__/test_dispatcher2.cpython-26-PYTEST.pyc +tests/web/__pycache__/test_dispatcher2.cpython-27-PYTEST.pyc +tests/web/__pycache__/test_dispatcher2.cpython-32-PYTEST.pyc +tests/web/__pycache__/test_dispatcher2.cpython-33-PYTEST.pyc +tests/web/__pycache__/test_dispatcher2.cpython-34-PYTEST.pyc +tests/web/__pycache__/test_dispatcher3.cpython-26-PYTEST.pyc +tests/web/__pycache__/test_dispatcher3.cpython-27-PYTEST.pyc +tests/web/__pycache__/test_dispatcher3.cpython-32-PYTEST.pyc +tests/web/__pycache__/test_dispatcher3.cpython-33-PYTEST.pyc +tests/web/__pycache__/test_dispatcher3.cpython-34-PYTEST.pyc +tests/web/__pycache__/test_disps.cpython-26-PYTEST.pyc +tests/web/__pycache__/test_disps.cpython-27-PYTEST.pyc +tests/web/__pycache__/test_disps.cpython-32-PYTEST.pyc +tests/web/__pycache__/test_disps.cpython-33-PYTEST.pyc +tests/web/__pycache__/test_disps.cpython-34-PYTEST.pyc +tests/web/__pycache__/test_exceptions.cpython-26-PYTEST.pyc +tests/web/__pycache__/test_exceptions.cpython-27-PYTEST.pyc +tests/web/__pycache__/test_exceptions.cpython-32-PYTEST.pyc +tests/web/__pycache__/test_exceptions.cpython-33-PYTEST.pyc +tests/web/__pycache__/test_exceptions.cpython-34-PYTEST.pyc +tests/web/__pycache__/test_expires.cpython-26-PYTEST.pyc +tests/web/__pycache__/test_expires.cpython-27-PYTEST.pyc +tests/web/__pycache__/test_expires.cpython-32-PYTEST.pyc +tests/web/__pycache__/test_expires.cpython-33-PYTEST.pyc +tests/web/__pycache__/test_expires.cpython-34-PYTEST.pyc +tests/web/__pycache__/test_expose.cpython-26-PYTEST.pyc +tests/web/__pycache__/test_expose.cpython-27-PYTEST.pyc +tests/web/__pycache__/test_expose.cpython-32-PYTEST.pyc +tests/web/__pycache__/test_expose.cpython-33-PYTEST.pyc +tests/web/__pycache__/test_expose.cpython-34-PYTEST.pyc +tests/web/__pycache__/test_generator.cpython-26-PYTEST.pyc +tests/web/__pycache__/test_generator.cpython-27-PYTEST.pyc +tests/web/__pycache__/test_generator.cpython-32-PYTEST.pyc +tests/web/__pycache__/test_generator.cpython-33-PYTEST.pyc +tests/web/__pycache__/test_generator.cpython-34-PYTEST.pyc +tests/web/__pycache__/test_gzip.cpython-26-PYTEST.pyc +tests/web/__pycache__/test_gzip.cpython-27-PYTEST.pyc +tests/web/__pycache__/test_gzip.cpython-32-PYTEST.pyc +tests/web/__pycache__/test_gzip.cpython-33-PYTEST.pyc +tests/web/__pycache__/test_gzip.cpython-34-PYTEST.pyc +tests/web/__pycache__/test_headers.cpython-26-PYTEST.pyc +tests/web/__pycache__/test_headers.cpython-27-PYTEST.pyc +tests/web/__pycache__/test_headers.cpython-32-PYTEST.pyc +tests/web/__pycache__/test_headers.cpython-33-PYTEST.pyc +tests/web/__pycache__/test_headers.cpython-34-PYTEST.pyc +tests/web/__pycache__/test_http.cpython-26-PYTEST.pyc +tests/web/__pycache__/test_http.cpython-27-PYTEST.pyc +tests/web/__pycache__/test_http.cpython-32-PYTEST.pyc +tests/web/__pycache__/test_http.cpython-33-PYTEST.pyc +tests/web/__pycache__/test_http.cpython-34-PYTEST.pyc +tests/web/__pycache__/test_json.cpython-26-PYTEST.pyc +tests/web/__pycache__/test_json.cpython-27-PYTEST.pyc +tests/web/__pycache__/test_json.cpython-32-PYTEST.pyc +tests/web/__pycache__/test_json.cpython-33-PYTEST.pyc +tests/web/__pycache__/test_json.cpython-34-PYTEST.pyc +tests/web/__pycache__/test_jsonrpc.cpython-26-PYTEST.pyc +tests/web/__pycache__/test_jsonrpc.cpython-27-PYTEST.pyc +tests/web/__pycache__/test_jsonrpc.cpython-32-PYTEST.pyc +tests/web/__pycache__/test_jsonrpc.cpython-33-PYTEST.pyc +tests/web/__pycache__/test_jsonrpc.cpython-34-PYTEST.pyc +tests/web/__pycache__/test_large_post.cpython-26-PYTEST.pyc +tests/web/__pycache__/test_large_post.cpython-27-PYTEST.pyc +tests/web/__pycache__/test_large_post.cpython-32-PYTEST.pyc +tests/web/__pycache__/test_large_post.cpython-33-PYTEST.pyc +tests/web/__pycache__/test_large_post.cpython-34-PYTEST.pyc +tests/web/__pycache__/test_logger.cpython-26-PYTEST.pyc +tests/web/__pycache__/test_logger.cpython-27-PYTEST.pyc +tests/web/__pycache__/test_logger.cpython-32-PYTEST.pyc +tests/web/__pycache__/test_logger.cpython-33-PYTEST.pyc +tests/web/__pycache__/test_logger.cpython-34-PYTEST.pyc +tests/web/__pycache__/test_methods.cpython-26-PYTEST.pyc +tests/web/__pycache__/test_methods.cpython-27-PYTEST.pyc +tests/web/__pycache__/test_methods.cpython-32-PYTEST.pyc +tests/web/__pycache__/test_methods.cpython-33-PYTEST.pyc +tests/web/__pycache__/test_methods.cpython-34-PYTEST.pyc +tests/web/__pycache__/test_multipartformdata.cpython-26-PYTEST.pyc +tests/web/__pycache__/test_multipartformdata.cpython-27-PYTEST.pyc +tests/web/__pycache__/test_multipartformdata.cpython-32-PYTEST.pyc +tests/web/__pycache__/test_multipartformdata.cpython-33-PYTEST.pyc +tests/web/__pycache__/test_multipartformdata.cpython-34-PYTEST.pyc +tests/web/__pycache__/test_null_response.cpython-26-PYTEST.pyc +tests/web/__pycache__/test_null_response.cpython-27-PYTEST.pyc +tests/web/__pycache__/test_null_response.cpython-32-PYTEST.pyc +tests/web/__pycache__/test_null_response.cpython-33-PYTEST.pyc +tests/web/__pycache__/test_null_response.cpython-34-PYTEST.pyc +tests/web/__pycache__/test_request_failure.cpython-26-PYTEST.pyc +tests/web/__pycache__/test_request_failure.cpython-27-PYTEST.pyc +tests/web/__pycache__/test_request_failure.cpython-32-PYTEST.pyc +tests/web/__pycache__/test_request_failure.cpython-33-PYTEST.pyc +tests/web/__pycache__/test_request_failure.cpython-34-PYTEST.pyc +tests/web/__pycache__/test_security.cpython-26-PYTEST.pyc +tests/web/__pycache__/test_security.cpython-27-PYTEST.pyc +tests/web/__pycache__/test_security.cpython-32-PYTEST.pyc +tests/web/__pycache__/test_security.cpython-33-PYTEST.pyc +tests/web/__pycache__/test_security.cpython-34-PYTEST.pyc +tests/web/__pycache__/test_serve_download.cpython-26-PYTEST.pyc +tests/web/__pycache__/test_serve_download.cpython-27-PYTEST.pyc +tests/web/__pycache__/test_serve_download.cpython-32-PYTEST.pyc +tests/web/__pycache__/test_serve_download.cpython-33-PYTEST.pyc +tests/web/__pycache__/test_serve_download.cpython-34-PYTEST.pyc +tests/web/__pycache__/test_serve_file.cpython-26-PYTEST.pyc +tests/web/__pycache__/test_serve_file.cpython-27-PYTEST.pyc +tests/web/__pycache__/test_serve_file.cpython-32-PYTEST.pyc +tests/web/__pycache__/test_serve_file.cpython-33-PYTEST.pyc +tests/web/__pycache__/test_serve_file.cpython-34-PYTEST.pyc +tests/web/__pycache__/test_servers.cpython-26-PYTEST.pyc +tests/web/__pycache__/test_servers.cpython-27-PYTEST.pyc +tests/web/__pycache__/test_servers.cpython-32-PYTEST.pyc +tests/web/__pycache__/test_servers.cpython-33-PYTEST.pyc +tests/web/__pycache__/test_servers.cpython-34-PYTEST.pyc +tests/web/__pycache__/test_sessions.cpython-26-PYTEST.pyc +tests/web/__pycache__/test_sessions.cpython-27-PYTEST.pyc +tests/web/__pycache__/test_sessions.cpython-32-PYTEST.pyc +tests/web/__pycache__/test_sessions.cpython-33-PYTEST.pyc +tests/web/__pycache__/test_sessions.cpython-34-PYTEST.pyc +tests/web/__pycache__/test_static.cpython-26-PYTEST.pyc +tests/web/__pycache__/test_static.cpython-27-PYTEST.pyc +tests/web/__pycache__/test_static.cpython-32-PYTEST.pyc +tests/web/__pycache__/test_static.cpython-33-PYTEST.pyc +tests/web/__pycache__/test_static.cpython-34-PYTEST.pyc +tests/web/__pycache__/test_unicode.cpython-26-PYTEST.pyc +tests/web/__pycache__/test_unicode.cpython-27-PYTEST.pyc +tests/web/__pycache__/test_unicode.cpython-32-PYTEST.pyc +tests/web/__pycache__/test_unicode.cpython-33-PYTEST.pyc +tests/web/__pycache__/test_unicode.cpython-34-PYTEST.pyc +tests/web/__pycache__/test_utils.cpython-26-PYTEST.pyc +tests/web/__pycache__/test_utils.cpython-27-PYTEST.pyc +tests/web/__pycache__/test_utils.cpython-32-PYTEST.pyc +tests/web/__pycache__/test_utils.cpython-33-PYTEST.pyc +tests/web/__pycache__/test_utils.cpython-34-PYTEST.pyc +tests/web/__pycache__/test_value.cpython-26-PYTEST.pyc +tests/web/__pycache__/test_value.cpython-27-PYTEST.pyc +tests/web/__pycache__/test_value.cpython-32-PYTEST.pyc +tests/web/__pycache__/test_value.cpython-33-PYTEST.pyc +tests/web/__pycache__/test_value.cpython-34-PYTEST.pyc +tests/web/__pycache__/test_vpath_args.cpython-26-PYTEST.pyc +tests/web/__pycache__/test_vpath_args.cpython-27-PYTEST.pyc +tests/web/__pycache__/test_vpath_args.cpython-32-PYTEST.pyc +tests/web/__pycache__/test_vpath_args.cpython-33-PYTEST.pyc +tests/web/__pycache__/test_vpath_args.cpython-34-PYTEST.pyc +tests/web/__pycache__/test_websockets.cpython-26-PYTEST.pyc +tests/web/__pycache__/test_websockets.cpython-27-PYTEST.pyc +tests/web/__pycache__/test_websockets.cpython-32-PYTEST.pyc +tests/web/__pycache__/test_websockets.cpython-33-PYTEST.pyc +tests/web/__pycache__/test_websockets.cpython-34-PYTEST.pyc +tests/web/__pycache__/test_wsgi_application.cpython-26-PYTEST.pyc +tests/web/__pycache__/test_wsgi_application.cpython-27-PYTEST.pyc +tests/web/__pycache__/test_wsgi_application.cpython-32-PYTEST.pyc +tests/web/__pycache__/test_wsgi_application.cpython-33-PYTEST.pyc +tests/web/__pycache__/test_wsgi_application.cpython-34-PYTEST.pyc +tests/web/__pycache__/test_wsgi_application_generator.cpython-26-PYTEST.pyc +tests/web/__pycache__/test_wsgi_application_generator.cpython-27-PYTEST.pyc +tests/web/__pycache__/test_wsgi_application_generator.cpython-32-PYTEST.pyc +tests/web/__pycache__/test_wsgi_application_generator.cpython-33-PYTEST.pyc +tests/web/__pycache__/test_wsgi_application_generator.cpython-34-PYTEST.pyc +tests/web/__pycache__/test_wsgi_application_yield.cpython-26-PYTEST.pyc +tests/web/__pycache__/test_wsgi_application_yield.cpython-27-PYTEST.pyc +tests/web/__pycache__/test_wsgi_application_yield.cpython-32-PYTEST.pyc +tests/web/__pycache__/test_wsgi_application_yield.cpython-33-PYTEST.pyc +tests/web/__pycache__/test_wsgi_application_yield.cpython-34-PYTEST.pyc +tests/web/__pycache__/test_wsgi_gateway.cpython-26-PYTEST.pyc +tests/web/__pycache__/test_wsgi_gateway.cpython-27-PYTEST.pyc +tests/web/__pycache__/test_wsgi_gateway.cpython-32-PYTEST.pyc +tests/web/__pycache__/test_wsgi_gateway.cpython-33-PYTEST.pyc +tests/web/__pycache__/test_wsgi_gateway.cpython-34-PYTEST.pyc +tests/web/__pycache__/test_wsgi_gateway_errors.cpython-26-PYTEST.pyc +tests/web/__pycache__/test_wsgi_gateway_errors.cpython-27-PYTEST.pyc +tests/web/__pycache__/test_wsgi_gateway_errors.cpython-32-PYTEST.pyc +tests/web/__pycache__/test_wsgi_gateway_errors.cpython-33-PYTEST.pyc +tests/web/__pycache__/test_wsgi_gateway_errors.cpython-34-PYTEST.pyc +tests/web/__pycache__/test_wsgi_gateway_generator.cpython-26-PYTEST.pyc +tests/web/__pycache__/test_wsgi_gateway_generator.cpython-27-PYTEST.pyc +tests/web/__pycache__/test_wsgi_gateway_generator.cpython-32-PYTEST.pyc +tests/web/__pycache__/test_wsgi_gateway_generator.cpython-33-PYTEST.pyc +tests/web/__pycache__/test_wsgi_gateway_generator.cpython-34-PYTEST.pyc +tests/web/__pycache__/test_wsgi_gateway_multiple_apps.cpython-26-PYTEST.pyc +tests/web/__pycache__/test_wsgi_gateway_multiple_apps.cpython-27-PYTEST.pyc +tests/web/__pycache__/test_wsgi_gateway_multiple_apps.cpython-32-PYTEST.pyc +tests/web/__pycache__/test_wsgi_gateway_multiple_apps.cpython-33-PYTEST.pyc +tests/web/__pycache__/test_wsgi_gateway_multiple_apps.cpython-34-PYTEST.pyc +tests/web/__pycache__/test_wsgi_gateway_null_response.cpython-26-PYTEST.pyc +tests/web/__pycache__/test_wsgi_gateway_null_response.cpython-27-PYTEST.pyc +tests/web/__pycache__/test_wsgi_gateway_null_response.cpython-32-PYTEST.pyc +tests/web/__pycache__/test_wsgi_gateway_null_response.cpython-33-PYTEST.pyc +tests/web/__pycache__/test_wsgi_gateway_null_response.cpython-34-PYTEST.pyc +tests/web/__pycache__/test_wsgi_gateway_write.cpython-26-PYTEST.pyc +tests/web/__pycache__/test_wsgi_gateway_write.cpython-27-PYTEST.pyc +tests/web/__pycache__/test_wsgi_gateway_write.cpython-32-PYTEST.pyc +tests/web/__pycache__/test_wsgi_gateway_write.cpython-33-PYTEST.pyc +tests/web/__pycache__/test_wsgi_gateway_write.cpython-34-PYTEST.pyc +tests/web/__pycache__/test_wsgi_gateway_yield.cpython-26-PYTEST.pyc +tests/web/__pycache__/test_wsgi_gateway_yield.cpython-27-PYTEST.pyc +tests/web/__pycache__/test_wsgi_gateway_yield.cpython-32-PYTEST.pyc +tests/web/__pycache__/test_wsgi_gateway_yield.cpython-33-PYTEST.pyc +tests/web/__pycache__/test_wsgi_gateway_yield.cpython-34-PYTEST.pyc +tests/web/__pycache__/test_xmlrpc.cpython-26-PYTEST.pyc +tests/web/__pycache__/test_xmlrpc.cpython-27-PYTEST.pyc +tests/web/__pycache__/test_xmlrpc.cpython-32-PYTEST.pyc +tests/web/__pycache__/test_xmlrpc.cpython-33-PYTEST.pyc +tests/web/__pycache__/test_xmlrpc.cpython-34-PYTEST.pyc +tests/web/__pycache__/test_yield.cpython-26-PYTEST.pyc +tests/web/__pycache__/test_yield.cpython-27-PYTEST.pyc +tests/web/__pycache__/test_yield.cpython-32-PYTEST.pyc +tests/web/__pycache__/test_yield.cpython-33-PYTEST.pyc +tests/web/__pycache__/test_yield.cpython-34-PYTEST.pyc tests/web/static/#foobar.txt tests/web/static/helloworld.txt +tests/web/static/largefile.txt tests/web/static/test.css -tests/web/static/unicode.txt -tools/mkpkgs \ No newline at end of file +tests/web/static/unicode.txt \ No newline at end of file diff -Nru circuits-2.1.0/circuits.egg-info/top_level.txt circuits-3.1.0+ds1/circuits.egg-info/top_level.txt --- circuits-2.1.0/circuits.egg-info/top_level.txt 2013-02-27 11:28:31.000000000 +0000 +++ circuits-3.1.0+ds1/circuits.egg-info/top_level.txt 2014-10-31 23:13:39.000000000 +0000 @@ -1,2 +1,3 @@ circuits +fabfile tests diff -Nru circuits-2.1.0/circuits.egg-info/zip-safe circuits-3.1.0+ds1/circuits.egg-info/zip-safe --- circuits-2.1.0/circuits.egg-info/zip-safe 1970-01-01 00:00:00.000000000 +0000 +++ circuits-3.1.0+ds1/circuits.egg-info/zip-safe 2014-09-04 10:33:48.000000000 +0000 @@ -0,0 +1 @@ + diff -Nru circuits-2.1.0/.coveragerc circuits-3.1.0+ds1/.coveragerc --- circuits-2.1.0/.coveragerc 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/.coveragerc 1970-01-01 00:00:00.000000000 +0000 @@ -1,19 +0,0 @@ -[run] -omit = circuits/__init__.py - circuits/app/__init__.py - circuits/io/__init__.py - circuits/core/__init__.py - circuits/net/__init__.py - circuits/net/protocols/__init__.py - circuits/node/__init__.py - circuits/web/__init__.py - circuits/web/main.py - circuits/web/dispatchers/__init__.py - circuits/web/apps/* - tests/* - -[html] -directory = coverage - -[xml] -output = coverage.xml diff -Nru circuits-2.1.0/debian/changelog circuits-3.1.0+ds1/debian/changelog --- circuits-2.1.0/debian/changelog 2013-07-10 18:13:41.000000000 +0000 +++ circuits-3.1.0+ds1/debian/changelog 2015-07-20 18:26:50.000000000 +0000 @@ -1,3 +1,52 @@ +circuits (3.1.0+ds1-1) unstable; urgency=medium + + [ Daniele Tricoli ] + * New upstream release. + * Switch to pybuild. + - Build-Depends on dh-python. + - Simplify debian/rules. + * Ship manpages inside debian/manpages since they are no more included in + sdist. + * Disable running tests at build time since they are also failing upstream. + (Closes: #792062) + - Use export PYBUILD_DISABLE=test in debian/rules. + - Remove python-coverage and python{,3}-pytest from Build-Depends. + * debian/control + - Remove python{,3}-pyinotify from Build-Depends and Depends. + - Remove python-imaging, python-multiprocessing and python-routes from + Recommends. + - Remove python{,3}-six from Depends since the embedded copy is modified + by upstream. + - Move python{,3}-serial from Recommends to Suggests. + - Bump Standards-Version to 3.9.6 (no changes needed). + - Update Homepage field. + * debian/copyright + - Update copyright year. + - Add new stanzas. + * debian/watch + - Use pypi.debian.net redirector. + * debian/patches/01_disable_sphinxcontrib_extensions.patch + - Refresh. + * debian/patches/02_remove_templatebuiltins_js.patch + - Refresh. + * debian/patches/04_fix-python3-sintax-error.patch + - Remove since it is not needed anymore. + * debian/patches/05_fix-pil-import.patch + - Remove since it is not needed anymore. + * debian/patches/04_remove-google-adsense.patch + - Remove Google AdSense tracking code. + * debian/patches/05_remove-privacy-breach-badges.patch + - Remove badges fetched from external websites. + * debian/rules + - Remove fabric scripts to not pollute namespace. + - Remove Python implementation of htpasswd. + + [ Piotr Ożarowski ] + * Remove HTML docs from upstream tarball (via Files-Excluded in + debian/copyright) + + -- Daniele Tricoli Sun, 19 Jul 2015 20:21:25 +0200 + circuits (2.1.0-2) unstable; urgency=low * Upload to unstable diff -Nru circuits-2.1.0/debian/control circuits-3.1.0+ds1/debian/control --- circuits-2.1.0/debian/control 2013-07-10 18:13:41.000000000 +0000 +++ circuits-3.1.0+ds1/debian/control 2015-07-20 17:59:19.000000000 +0000 @@ -5,18 +5,14 @@ Uploaders: Daniele Tricoli Build-Depends: debhelper (>= 9), + dh-python, python-all (>= 2.6.6-3~), - python-coverage, - python-pyinotify, - python-pytest (>= 2.3), python-setuptools, python-sphinx (>= 1.0.7+dfsg), python3-all (>= 3.1.2-7~), - python3-pyinotify, - python3-pytest (>= 2.3), python3-setuptools, -Standards-Version: 3.9.4 -Homepage: http://bitbucket.org/prologic/circuits/ +Standards-Version: 3.9.6 +Homepage: http://circuitsframework.com X-Python-Version: >= 2.6 X-Python3-Version: >= 3.0 Vcs-Svn: svn://anonscm.debian.org/python-modules/packages/circuits/trunk/ @@ -28,13 +24,7 @@ ${misc:Depends}, ${python:Depends}, python-pkg-resources, - python-pyinotify, - python-six, -Recommends: - python-imaging, - python-multiprocessing | python (>= 2.6), - python-routes, - python-serial +Suggests: python-serial Description: event-driven framework with a component architecture circuits is an event-driven framework with a focus on Component Software Architectures where System Functionality is defined in @@ -56,9 +46,7 @@ ${misc:Depends}, ${python3:Depends}, python3-pkg-resources, - python3-pyinotify, - python3-six, -Recommends: python3-serial +Suggests: python3-serial Description: event-driven framework with a component architecture (Python3 version) circuits is an event-driven framework with a focus on Component Software Architectures where System Functionality is defined in diff -Nru circuits-2.1.0/debian/copyright circuits-3.1.0+ds1/debian/copyright --- circuits-2.1.0/debian/copyright 2013-07-10 18:13:41.000000000 +0000 +++ circuits-3.1.0+ds1/debian/copyright 2015-07-20 18:24:28.000000000 +0000 @@ -2,24 +2,53 @@ Upstream-Name: circuits Upstream-Contact: James Mills Source: http://pypi.python.org/pypi/circuits +Files-Excluded: docs/build/html/* *.un~ Files: * -Copyright: 2004-2013, James Mills +Copyright: 2004-2015, James Mills License: Expat Files: debian/* Copyright: 2008-2010, Sandro Tosi - 2011-2013, Daniele Tricoli + 2011-2015, Daniele Tricoli License: Expat +Files: bin/htpasswd +Copyright: 2008, Eli Carter +License: BSD-3-clause + Files: circuits/six.py Copyright: 2010-2011, Benjamin Peterson License: Expat +Files: circuits/core/helpers.py +Copyright: 2012, Michael N. Lipp +License: Expat + +Files: circuits/protocols/websocket.py +Copyright: 2013, Michael N. Lipp +License: Expat + Files: circuits/web/_httpauth.py Copyright: 2005, Tiago Cogumbreiro License: BSD-3-clause +Files: circuits/web/parsers/http.py +Copyright: 2011-2013, Benoît Chesneau +License: Expat + +Files: circuits/web/parsers/multipart.py +Copyright: 2010, Marcel Hellkamp +License: Expat + +Files: circuits/web/url.py +Copyright: 2012, SEOmoz +License: Expat + +Files: examples/web/terminal/static/js/jquery.js +Copyright: 2009, John Resig +License: Expat + Files: examples/web/terminal/static/js/jquery.terminal.js Copyright: 2009, Sagie Maoz License: GPL-3 diff -Nru circuits-2.1.0/debian/manpages/circuits.bench.1 circuits-3.1.0+ds1/debian/manpages/circuits.bench.1 --- circuits-2.1.0/debian/manpages/circuits.bench.1 1970-01-01 00:00:00.000000000 +0000 +++ circuits-3.1.0+ds1/debian/manpages/circuits.bench.1 2015-07-12 19:45:41.000000000 +0000 @@ -0,0 +1,58 @@ +.TH circuits.bench 1 "Jun 2011" "circuits 2.0.2" "User Commands" +.SH NAME +circuits.bench \- simple benchmaking of the circuits library +.SH SYNOPSIS +.B circuits.bench +[\fIoptions\fR] +.SH DESCRIPTION +circuits.bench does some simple benchmaking of the circuits library. +.SH OPTIONS +.TP +\fB-b\fR \fIaddress:[port]\fR +Bind to address:[port] (UDP) to test remote events. Default address is 0.0.0.0. +.TP +\fB-c\fR \fIinteger\fR +Set concurrency level to \fIinteger\fR. Default is 1. +.TP +\fB-d\fR +Enable debug mode. +.TP +\fB-e\fR \fInumber\fR +Stop after specified \fInumber\fR of events. Default is 0. +.TP +\fB-f\fR \fInumber\fR +\fInumber\fR of dummy events to fill queue with. Default is 0. +.TP +\fB-l\fR +Listen on 0.0.0.0:8000 (UDP) to test remote events. +.TP +\fB-m\fR \fImode\fR +Set operation mode. \fImode\fR can be \fIlatency\fR, \fIspeed\fR or \fIsync\fR. +Default \fImode\fR is \fIspeed\fR. +.TP +\fB-o\fR \fIformat\fR +Specify output format. +For example \fIformat\fR can be:"cicuits.bench: events:%s, speed:%s, time:%s" +.TP +\fB-p\fR +Enable execution profiling support. +.TP +\fB-q\fR +Suppress output. +.TP +\fB-s\fR +Enable psyco (circuits on speed!) if it is available. +.TP +\fB-t\fR \fIseconds\fR +Stop after specified elapsed \fIseconds\fR. +.TP +\fB-w\fR +Wait for remote nodes to connect. +.TP +\fB--version\fR +Output version information and exit. +.SH AUTHOR +James Mills +.PP +This manual page was written by Daniele Tricoli , for the +Debian project (but may be used by others). diff -Nru circuits-2.1.0/debian/manpages/circuits.web.1 circuits-3.1.0+ds1/debian/manpages/circuits.web.1 --- circuits-2.1.0/debian/manpages/circuits.web.1 1970-01-01 00:00:00.000000000 +0000 +++ circuits-3.1.0+ds1/debian/manpages/circuits.web.1 2015-07-12 19:45:41.000000000 +0000 @@ -0,0 +1,44 @@ +.TH circuits.web 1 "Jun 2011" "circuits 2.0.2" "User Commands" +.SH NAME +circuits.web \- Web Server and testing tool +.SH SYNOPSIS +.B circuits.web +[\fIoptions\fR] [\fIdocroot\fR] +.SH DESCRIPTION +circuits.web is a component based, event-driven light weight and high +performance HTTP/WSGI framework. circuits.web applications are stand-alone +applications with a high performance, multi-process web server with great +concurrent scalability with full support for WSGI and deployment with other web +servers. +.SH OPTIONS +.TP +\fB-b\fR \fIaddress:[port]\fR +Bind to address:[port]. Default address is 0.0.0.0:8000. +.TP +\fB-d\fR +Enable debug mode. +.TP +\fB-j\fR +Use python JIT (psyco) if it is available. +.TP +\fB-m\fR \fInumber\fR +Specify \fInumber\fR of processes to start (multiprocessing). +.TP +\fB-p\fR +Enable execution profiling support. +.TP +\fB-s\fR \fIserver\fR +Specify server to use. +.TP +\fB-t\fR \fItype\fR +Specify type of poller to use. \fItype\fR can be \fIepoll\fR, \fIpoll\fR or +\fIselect\fR. +Default \fItype\fR is \fIselect\fR. +.TP +\fB-v\fR +Enable WSGI validation mode. +.SH AUTHOR +James Mills +.PP +This manual page was written by Daniele Tricoli , for the +Debian project (but may be used by others). diff -Nru circuits-2.1.0/debian/patches/01_disable_sphinxcontrib_extensions.patch circuits-3.1.0+ds1/debian/patches/01_disable_sphinxcontrib_extensions.patch --- circuits-2.1.0/debian/patches/01_disable_sphinxcontrib_extensions.patch 2013-07-10 18:13:41.000000000 +0000 +++ circuits-3.1.0+ds1/debian/patches/01_disable_sphinxcontrib_extensions.patch 2015-07-12 19:45:41.000000000 +0000 @@ -1,25 +1,26 @@ -Description: Disable sphinxcontrib-bitbucket and sphinxcontrib-googleanalytics - because they are not packaged for Debian. Also sphinxcontrib-googleanalytics is - used to track generated html files with Google Analytics web service. +Description: Disable sphinxcontrib-releases because it's not packaged for + Debian. Author: Daniele Tricoli -Last-Update: 2013-03-19 +Last-Update: 2015-07-11 Forwarded: not-needed --- a/docs/source/conf.py +++ b/docs/source/conf.py -@@ -85,13 +85,13 @@ - - # -- link to bitbucket issues - --extensions.append('sphinxcontrib.bitbucket') -+#extensions.append('sphinxcontrib.bitbucket') - - # -- track statistics with google analytics - --extensions.append("sphinxcontrib.googleanalytics") -+#extensions.append("sphinxcontrib.googleanalytics") - --googleanalytics_id = "UA-38618352-3" -+#googleanalytics_id = "UA-38618352-3" - +@@ -105,13 +105,13 @@ + + # -- release and issues + +-extensions.append("releases") ++# extensions.append("releases") + + # 'releases' (changelog) settings +-releases_debug = True +-releases_issue_uri = "https://bitbucket.org/circuits/circuits/issue/%s" +-releases_release_uri = "https://bitbucket.org/circuits/circuits/src/tip/?at=%s" +-releases_document_name = "changes" ++# releases_debug = True ++# releases_issue_uri = "https://bitbucket.org/circuits/circuits/issue/%s" ++# releases_release_uri = "https://bitbucket.org/circuits/circuits/src/tip/?at=%s" ++# releases_document_name = "changes" + # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff -Nru circuits-2.1.0/debian/patches/02_remove_templatebuiltins_js.patch circuits-3.1.0+ds1/debian/patches/02_remove_templatebuiltins_js.patch --- circuits-2.1.0/debian/patches/02_remove_templatebuiltins_js.patch 2013-07-10 18:13:41.000000000 +0000 +++ circuits-3.1.0+ds1/debian/patches/02_remove_templatebuiltins_js.patch 2015-07-12 19:45:41.000000000 +0000 @@ -1,14 +1,48 @@ Description: Remove templatebuiltins.js because it contains names of Django builtin tags and filters not used in circuits documentation. Author: Daniele Tricoli +Forwarded: https://github.com/circuits/circuits/pull/106 +Last-Update: 2015-07-12 + --- a/docs/source/_themes/om/layout.html +++ b/docs/source/_themes/om/layout.html -@@ -18,7 +18,7 @@ +@@ -18,39 +18,6 @@ {% block extrahead %} {{ super() }} - -+ - + {% endblock %} + + {% block document %} diff -Nru circuits-2.1.0/debian/patches/04_fix-python3-sintax-error.patch circuits-3.1.0+ds1/debian/patches/04_fix-python3-sintax-error.patch --- circuits-2.1.0/debian/patches/04_fix-python3-sintax-error.patch 2013-07-10 18:13:41.000000000 +0000 +++ circuits-3.1.0+ds1/debian/patches/04_fix-python3-sintax-error.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,27 +0,0 @@ -Description: Fix sintax errors since print and exec are not keywords in Python3 -Author: Daniele Tricoli ---- a/circuits/web/apps/memorymonitor/reftree.py -+++ b/circuits/web/apps/memorymonitor/reftree.py -@@ -172,9 +172,9 @@ - """Walk the object tree, pretty-printing each branch.""" - self.ignore_caller() - for trail in self.walk(maxresults, maxdepth): -- print trail -+ print (trail) - if self.stops: -- print "%s paths stopped because max depth reached" % self.stops -+ print ("%s paths stopped because max depth reached" % self.stops) - - - def count_objects(): ---- a/circuits/web/apps/webconsole/__init__.py -+++ b/circuits/web/apps/webconsole/__init__.py -@@ -56,7 +56,7 @@ - sys.stdout = sys.stderr = out - try: - try: -- exec code in self.locals -+ exec (code in self.locals) - except: - result = traceback.format_exc() - else: diff -Nru circuits-2.1.0/debian/patches/04_remove-google-adsense.patch circuits-3.1.0+ds1/debian/patches/04_remove-google-adsense.patch --- circuits-2.1.0/debian/patches/04_remove-google-adsense.patch 1970-01-01 00:00:00.000000000 +0000 +++ circuits-3.1.0+ds1/debian/patches/04_remove-google-adsense.patch 2015-07-14 19:49:02.000000000 +0000 @@ -0,0 +1,27 @@ +Description: Remove Google AdSense tracking code. +Author: Daniele Tricoli +Last-Update: 2015-07-12 +Forwarded: not-needed + +--- a/docs/source/_templates/layout.html ++++ b/docs/source/_templates/layout.html +@@ -2,19 +2,6 @@ + + {%- block extrahead %} + {{ super() }} +- +- + {% endblock %} + + diff -Nru circuits-2.1.0/debian/patches/05_fix-pil-import.patch circuits-3.1.0+ds1/debian/patches/05_fix-pil-import.patch --- circuits-2.1.0/debian/patches/05_fix-pil-import.patch 2013-07-10 18:13:41.000000000 +0000 +++ circuits-3.1.0+ds1/debian/patches/05_fix-pil-import.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,21 +0,0 @@ -Description: Fix PIL import - see http://lists.debian.org/debian-python/2013/02/msg00017.html for details. -Author: Daniele Tricoli -Last-Update: 2013-07-09 - ---- a/circuits/web/apps/memorymonitor/__init__.py -+++ b/circuits/web/apps/memorymonitor/__init__.py -@@ -6,8 +6,11 @@ - import threading - from types import FrameType, ModuleType - --import Image --import ImageDraw -+try: -+ from PIL import Image, ImageDraw -+except ImportError: -+ import Image -+ import ImageDraw - - from circuits import handler - from circuits.web import Controller diff -Nru circuits-2.1.0/debian/patches/05_remove-privacy-breach-badges.patch circuits-3.1.0+ds1/debian/patches/05_remove-privacy-breach-badges.patch --- circuits-2.1.0/debian/patches/05_remove-privacy-breach-badges.patch 1970-01-01 00:00:00.000000000 +0000 +++ circuits-3.1.0+ds1/debian/patches/05_remove-privacy-breach-badges.patch 2015-07-14 19:49:02.000000000 +0000 @@ -0,0 +1,46 @@ +Description: Remove badges fetched from external websites. +Author: Daniele Tricoli +Last-Update: 2015-07-13 +Forwarded: not-needed + +--- a/README.rst ++++ b/README.rst +@@ -25,38 +25,6 @@ + - Download it from the `Downloads Page`_ + - `View the ChangeLog`_ + +-.. image:: https://pypip.in/v/circuits/badge.png?text=version +- :target: https://pypi.python.org/pypi/circuits +- :alt: Latest Version +- +-.. image:: https://pypip.in/py_versions/circuits/badge.svg +- :target: https://pypi.python.org/pypi/circuits +- :alt: Supported Python Versions +- +-.. image:: https://pypip.in/implementation/circuits/badge.svg +- :target: https://pypi.python.org/pypi/circuits +- :alt: Supported Python implementations +- +-.. image:: https://pypip.in/status/circuits/badge.svg +- :target: https://pypi.python.org/pypi/circuits +- :alt: Development Status +- +-.. image:: https://pypip.in/d/circuits/badge.png +- :target: https://pypi.python.org/pypi/circuits +- :alt: Number of Downloads +- +-.. image:: https://pypip.in/format/circuits/badge.svg +- :target: https://pypi.python.org/pypi/circuits +- :alt: Format +- +-.. image:: https://pypip.in/license/circuits/badge.svg +- :target: https://pypi.python.org/pypi/circuits +- :alt: License +- +-.. image:: https://requires.io/bitbucket/circuits/circuits/requirements.png?branch=default +- :target: https://requires.io/bitbucket/circuits/circuits/requirements?branch=default +- :alt: Requirements Status +- + + Examples + -------- diff -Nru circuits-2.1.0/debian/patches/series circuits-3.1.0+ds1/debian/patches/series --- circuits-2.1.0/debian/patches/series 2013-07-10 18:13:41.000000000 +0000 +++ circuits-3.1.0+ds1/debian/patches/series 2015-07-19 13:12:15.000000000 +0000 @@ -1,5 +1,5 @@ 01_disable_sphinxcontrib_extensions.patch 02_remove_templatebuiltins_js.patch 03_disable-address-check.patch -04_fix-python3-sintax-error.patch -05_fix-pil-import.patch +04_remove-google-adsense.patch +05_remove-privacy-breach-badges.patch diff -Nru circuits-2.1.0/debian/python3-circuits.manpages circuits-3.1.0+ds1/debian/python3-circuits.manpages --- circuits-2.1.0/debian/python3-circuits.manpages 2013-07-10 18:13:41.000000000 +0000 +++ circuits-3.1.0+ds1/debian/python3-circuits.manpages 2015-07-12 19:45:41.000000000 +0000 @@ -1,2 +1,2 @@ -man/circuits.bench3.1 -man/circuits.web3.1 +debian/manpages/circuits.bench3.1 +debian/manpages/circuits.web3.1 diff -Nru circuits-2.1.0/debian/python-circuits.manpages circuits-3.1.0+ds1/debian/python-circuits.manpages --- circuits-2.1.0/debian/python-circuits.manpages 2013-07-10 18:13:41.000000000 +0000 +++ circuits-3.1.0+ds1/debian/python-circuits.manpages 2015-07-12 19:45:41.000000000 +0000 @@ -1,2 +1,2 @@ -man/circuits.bench.1 -man/circuits.web.1 +debian/manpages/circuits.bench.1 +debian/manpages/circuits.web.1 diff -Nru circuits-2.1.0/debian/rules circuits-3.1.0+ds1/debian/rules --- circuits-2.1.0/debian/rules 2013-07-10 18:13:41.000000000 +0000 +++ circuits-3.1.0+ds1/debian/rules 2015-07-14 19:49:02.000000000 +0000 @@ -1,68 +1,44 @@ #!/usr/bin/make -f -PY2VERS := $(shell pyversions -r) -PY3VERS := $(shell py3versions -r) +export PYBUILD_NAME=circuits +export PYBUILD_DISABLE=test %: - dh $(@) --with python2,python3,sphinxdoc -Spython_distutils + dh $(@) --with python2,python3,sphinxdoc --buildsystem=pybuild override_dh_auto_clean: rm -rf build rm -rf docs/build/html rm -rf *.egg-info find . -name *.coverage.* -delete - rm -f man/circuits.*3.1 + rm -f debian/manpages/circuits.*3.1 dh_auto_clean override_dh_auto_build: - set -e -x; \ - for python in $(PY2VERS); do \ - $$python setup.py build -e /usr/bin/python; \ - done - for python in $(PY3VERS); do \ - $$python setup.py build -e /usr/bin/python3; \ - done - + dh_auto_build PYTHONPATH=. sphinx-build -N -bhtml docs/source docs/build/html - - # Copy manpages for Python3 scripts - cp man/circuits.bench.1 man/circuits.bench3.1 - cp man/circuits.web.1 man/circuits.web3.1 - sed -i 's/circuits.bench/circuits.bench3/g' man/circuits.bench3.1 - sed -i 's/circuits.web/circuits.web3/g' man/circuits.web3.1 + # Copy manpages for Python3 scripts. + cp debian/manpages/circuits.bench.1 debian/manpages/circuits.bench3.1 + cp debian/manpages/circuits.web.1 debian/manpages/circuits.web3.1 + sed -i 's/circuits.bench/circuits.bench3/g' debian/manpages/circuits.bench3.1 + sed -i 's/circuits.web/circuits.web3/g' debian/manpages/circuits.web3.1 override_dh_auto_install: - set -e -x; \ - for python2 in $(PY2VERS); do \ - $$python2 setup.py install --skip-build --root debian/python-circuits \ - --install-layout deb; \ - done - - set -e -x; \ - for python3 in $(PY3VERS); do \ - $$python3 setup.py install --skip-build --root debian/python3-circuits \ - --install-layout deb; \ - done - + dh_auto_install # Remove tests to not pollute namespace. rm -rf debian/python*-circuits/usr/lib/python*/dist-packages/tests - - # Rename scripts for Python3 + # Remove fabric scripts to not pollute namespace. + rm -rf debian/python*-circuits/usr/lib/python*/dist-packages/fabfile + # Remove Python implementation of htpasswd. + rm -rf debian/python*-circuits/usr/bin/htpasswd + # Rename scripts for Python3. mv debian/python3-circuits/usr/bin/circuits.bench \ debian/python3-circuits/usr/bin/circuits.bench3 mv debian/python3-circuits/usr/bin/circuits.web \ debian/python3-circuits/usr/bin/circuits.web3 - # --excutable option in build has no effect for circuits.web's entrypoint sed -i '1c#!/usr/bin/python' debian/python-circuits/usr/bin/circuits.web sed -i '1c#!/usr/bin/python3' debian/python3-circuits/usr/bin/circuits.web3 -override_dh_auto_test: -ifeq ($(filter nocheck,$(DEB_BUILD_OPTIONS)),) - # Upstream is calling directly py.test inside a Popen so, for now, tests - # are run only for the default version - set -e; python setup.py test; -endif - override_dh_installchangelogs: dh_installchangelogs CHANGES.rst diff -Nru circuits-2.1.0/debian/watch circuits-3.1.0+ds1/debian/watch --- circuits-2.1.0/debian/watch 2013-07-10 18:13:41.000000000 +0000 +++ circuits-3.1.0+ds1/debian/watch 2015-07-20 18:13:22.000000000 +0000 @@ -1,2 +1,3 @@ version=3 -http://pypi.python.org/packages/source/c/circuits/circuits-(.*)\.tar\.gz +opts=uversionmangle=s/(rc|a|b|c)/~$1/,dversionmangle=s/\+ds\d*$//,repacksuffix=+ds1 \ +http://pypi.debian.net/circuits/circuits-(.+)\.(?:zip|tgz|tbz|txz|(?:tar\.(?:gz|bz2|xz))) Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits_app_config.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits_app_config.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits_app_daemon.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits_app_daemon.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.app.daemon.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.app.daemon.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits_app.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits_app.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.app.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.app.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits_app_env.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits_app_env.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits_app_log.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits_app_log.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.core.bridge.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.core.bridge.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits_core_components.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits_core_components.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.core.components.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.core.components.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits_core_debugger.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits_core_debugger.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.core.debugger.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.core.debugger.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits_core.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits_core.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.core.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.core.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits_core_events.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits_core_events.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.core.events.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.core.events.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits_core_handlers.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits_core_handlers.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.core.handlers.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.core.handlers.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.core.helpers.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.core.helpers.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits_core_loader.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits_core_loader.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.core.loader.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.core.loader.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits_core_manager.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits_core_manager.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.core.manager.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.core.manager.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits_core_pollers.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits_core_pollers.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.core.pollers.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.core.pollers.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits_core_timers.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits_core_timers.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.core.timers.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.core.timers.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits_core_utils.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits_core_utils.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.core.utils.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.core.utils.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits_core_values.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits_core_values.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.core.values.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.core.values.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits_core_workers.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits_core_workers.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.core.workers.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.core.workers.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits_io.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits_io.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.io.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.io.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits_io_events.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits_io_events.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.io.events.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.io.events.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits_io_file.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits_io_file.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.io.file.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.io.file.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits_io_notify.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits_io_notify.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.io.notify.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.io.notify.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.io.process.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.io.process.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits_io_serial.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits_io_serial.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.io.serial.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.io.serial.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits_net.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits_net.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.net.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.net.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.net.events.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.net.events.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits_net_protocols.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits_net_protocols.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits_net_protocols_http.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits_net_protocols_http.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits_net_protocols_irc.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits_net_protocols_irc.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits_net_protocols_line.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits_net_protocols_line.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits_net_sockets.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits_net_sockets.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.net.sockets.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.net.sockets.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits_node_client.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits_node_client.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.node.client.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.node.client.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits_node.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits_node.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.node.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.node.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits_node_events.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits_node_events.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.node.events.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.node.events.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits_node_node.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits_node_node.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.node.node.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.node.node.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits_node_server.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits_node_server.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.node.server.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.node.server.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits_node_utils.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits_node_utils.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.node.utils.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.node.utils.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.protocols.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.protocols.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.protocols.http.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.protocols.http.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.protocols.irc.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.protocols.irc.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.protocols.line.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.protocols.line.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.protocols.websocket.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.protocols.websocket.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.six.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.six.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits_tools.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits_tools.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.tools.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.tools.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.version.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.version.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits_web_client.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits_web_client.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.web.client.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.web.client.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits_web_constants.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits_web_constants.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.web.constants.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.web.constants.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits_web_controllers.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits_web_controllers.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.web.controllers.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.web.controllers.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits_web_dispatchers_dispatcher.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits_web_dispatchers_dispatcher.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.web.dispatchers.dispatcher.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.web.dispatchers.dispatcher.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.web.dispatchers.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.web.dispatchers.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits_web_dispatchers_jsonrpc.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits_web_dispatchers_jsonrpc.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.web.dispatchers.jsonrpc.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.web.dispatchers.jsonrpc.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits_web_dispatchers_static.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits_web_dispatchers_static.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.web.dispatchers.static.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.web.dispatchers.static.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits_web_dispatchers_virtualhosts.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits_web_dispatchers_virtualhosts.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.web.dispatchers.virtualhosts.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.web.dispatchers.virtualhosts.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits_web_dispatchers_websockets.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits_web_dispatchers_websockets.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits_web_dispatchers_xmlrpc.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits_web_dispatchers_xmlrpc.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.web.dispatchers.xmlrpc.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.web.dispatchers.xmlrpc.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits_web.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits_web.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.web.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.web.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits_web_errors.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits_web_errors.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.web.errors.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.web.errors.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits_web_events.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits_web_events.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.web.events.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.web.events.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits_web_exceptions.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits_web_exceptions.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.web.exceptions.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.web.exceptions.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits_web_headers.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits_web_headers.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.web.headers.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.web.headers.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits_web_http.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits_web_http.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.web.http.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.web.http.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits_web_loggers.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits_web_loggers.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.web.loggers.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.web.loggers.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits_web_main.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits_web_main.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.web.main.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.web.main.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.web.parsers.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.web.parsers.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.web.parsers.http.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.web.parsers.http.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.web.parsers.multipart.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.web.parsers.multipart.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.web.parsers.querystring.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.web.parsers.querystring.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.web.processors.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.web.processors.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits_web_servers.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits_web_servers.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.web.servers.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.web.servers.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits_web_sessions.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits_web_sessions.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.web.sessions.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.web.sessions.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits_web_tools.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits_web_tools.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.web.tools.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.web.tools.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.web.url.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.web.url.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits_web_utils.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits_web_utils.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.web.utils.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.web.utils.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits_web_websocket.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits_web_websocket.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.web.websockets.client.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.web.websockets.client.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.web.websockets.dispatcher.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.web.websockets.dispatcher.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.web.websockets.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.web.websockets.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits_web_wrappers.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits_web_wrappers.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.web.wrappers.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.web.wrappers.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits_web_wsgi.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits_web_wsgi.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/circuits.web.wsgi.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/circuits.web.wsgi.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/api/index.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/api/index.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/changes.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/changes.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/contributors.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/contributors.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/dev/contributing.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/dev/contributing.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/dev/index.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/dev/index.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/dev/introduction.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/dev/introduction.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/dev/processes.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/dev/processes.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/dev/standards.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/dev/standards.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/environment.pickle and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/environment.pickle differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/examples/index.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/examples/index.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/faq.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/faq.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/glossary.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/glossary.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/howtos/index.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/howtos/index.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/howtos/simple_server.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/howtos/simple_server.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/index.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/index.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/man/components.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/man/components.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/man/debugger.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/man/debugger.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/man/debugging.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/man/debugging.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/man/events.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/man/events.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/man/handlers.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/man/handlers.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/man/index.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/man/index.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/man/manager.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/man/manager.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/man/misc/tools.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/man/misc/tools.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/man/tools.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/man/tools.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/man/values.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/man/values.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/pypitest.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/pypitest.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/readme.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/readme.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/roadmap.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/roadmap.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/start/downloading.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/start/downloading.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/start/index.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/start/index.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/start/installing.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/start/installing.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/start/quick.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/start/quick.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/start/requirements.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/start/requirements.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/todo.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/todo.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/tutorial/index.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/tutorial/index.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/tutorials/index.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/tutorials/index.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/tutorials/telnet/index.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/tutorials/telnet/index.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/tutorials/woof/index.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/tutorials/woof/index.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/users.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/users.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/web/basics.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/web/basics.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/web/features.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/web/features.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/web/gettingstarted.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/web/gettingstarted.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/web/howtos.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/web/howtos.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/web/index.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/web/index.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/web/introduction.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/web/introduction.doctree differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/doctrees/web/miscellaneous.doctree and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/doctrees/web/miscellaneous.doctree differ diff -Nru circuits-2.1.0/docs/build/html/api/circuits_app_config.html circuits-3.1.0+ds1/docs/build/html/api/circuits_app_config.html --- circuits-2.1.0/docs/build/html/api/circuits_app_config.html 2013-02-27 11:27:54.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/api/circuits_app_config.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,319 +0,0 @@ - - - - - - - - - circuits.app.config – Application Config — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

circuits.app.config – Application Config

-
-

Events

-
-
-class circuits.app.config.Load(*args, **kwargs)
-

Bases: circuits.app.config.ConfigEvent

-

Load Config Event

-

An Event is a message send to one or more channels. It is eventually -dispatched to all components that have handlers for one -of the channels and the event type.

-

All normal arguments and keyword arguments passed to the constructor -of an event are passed on to the handler. When declaring a -handler, its argument list must therefore match the arguments -used for creating the event.

-

Every event has a name attribute that is used for matching -the event with the handlers. By default, the name is the uncameled -class name of the event.

- --- - - - -
Variables:
    -
  • channels

    an optional attribute that may be set before firing -the event. If defined (usually as a class variable), the attribute -specifies the channels that the event should be delivered -to as a tuple. This overrides the default behavior -of sending the event to the firing component’s channel.

    -

    When an event is fired, the value in this attribute -is replaced for the instance with the channels that -the event is actually sent to. This information may be used -e.g. when the event is passed as a parameter to a handler.

    -
  • -
  • value – this is a circuits.core.values.Value -object that holds the results returned by the handlers invoked -for the event.
  • -
  • success – if this optional attribute is set to -True, an associated event EventSuccess (original name -with “Success” appended) will automatically be fired when all -handlers for the event have been invoked successfully.
  • -
  • success_channels – the success event is, by default, delivered -to same channels as the successfully dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
  • complete – if this optional attribute is set to -True, an associated event EventComplete (original name -with “Complete” appended) will automatically be fired when all -handlers for the event and all events fired by these handlers -(recursively) have been invoked successfully.
  • -
  • success_channels – the complete event is, by default, delivered -to same channels as the initially dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
-
-
- -
-
-class circuits.app.config.Save(*args, **kwargs)
-

Bases: circuits.app.config.ConfigEvent

-

Save Config Event

-

An Event is a message send to one or more channels. It is eventually -dispatched to all components that have handlers for one -of the channels and the event type.

-

All normal arguments and keyword arguments passed to the constructor -of an event are passed on to the handler. When declaring a -handler, its argument list must therefore match the arguments -used for creating the event.

-

Every event has a name attribute that is used for matching -the event with the handlers. By default, the name is the uncameled -class name of the event.

- --- - - - -
Variables:
    -
  • channels

    an optional attribute that may be set before firing -the event. If defined (usually as a class variable), the attribute -specifies the channels that the event should be delivered -to as a tuple. This overrides the default behavior -of sending the event to the firing component’s channel.

    -

    When an event is fired, the value in this attribute -is replaced for the instance with the channels that -the event is actually sent to. This information may be used -e.g. when the event is passed as a parameter to a handler.

    -
  • -
  • value – this is a circuits.core.values.Value -object that holds the results returned by the handlers invoked -for the event.
  • -
  • success – if this optional attribute is set to -True, an associated event EventSuccess (original name -with “Success” appended) will automatically be fired when all -handlers for the event have been invoked successfully.
  • -
  • success_channels – the success event is, by default, delivered -to same channels as the successfully dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
  • complete – if this optional attribute is set to -True, an associated event EventComplete (original name -with “Complete” appended) will automatically be fired when all -handlers for the event and all events fired by these handlers -(recursively) have been invoked successfully.
  • -
  • success_channels – the complete event is, by default, delivered -to same channels as the initially dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
-
-
- -
-
-

Components

-
-
-class circuits.app.config.Config(filename, defaults=None, channel='config')
-

Bases: circuits.core.components.BaseComponent

-
- -
-
-

Functions

-
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/api/circuits_app_daemon.html circuits-3.1.0+ds1/docs/build/html/api/circuits_app_daemon.html --- circuits-2.1.0/docs/build/html/api/circuits_app_daemon.html 2013-02-27 11:27:55.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/api/circuits_app_daemon.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,344 +0,0 @@ - - - - - - - - - circuits.app.daemon – Application Daemon — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

circuits.app.daemon – Application Daemon

-
-

Events

-
-
-class circuits.app.daemon.Daemonize(*args, **kwargs)
-

Bases: circuits.core.events.Event

-

Daemonize Event

-

This event can be fired to notify the Daemon Component to begin the -“daemonization” process. This event is (by default) used -automatically by the Daemon Component in its “started” Event -Handler (This behavior can be overridden).

-

Arguments: None

-

An Event is a message send to one or more channels. It is eventually -dispatched to all components that have handlers for one -of the channels and the event type.

-

All normal arguments and keyword arguments passed to the constructor -of an event are passed on to the handler. When declaring a -handler, its argument list must therefore match the arguments -used for creating the event.

-

Every event has a name attribute that is used for matching -the event with the handlers. By default, the name is the uncameled -class name of the event.

- --- - - - -
Variables:
    -
  • channels

    an optional attribute that may be set before firing -the event. If defined (usually as a class variable), the attribute -specifies the channels that the event should be delivered -to as a tuple. This overrides the default behavior -of sending the event to the firing component’s channel.

    -

    When an event is fired, the value in this attribute -is replaced for the instance with the channels that -the event is actually sent to. This information may be used -e.g. when the event is passed as a parameter to a handler.

    -
  • -
  • value – this is a circuits.core.values.Value -object that holds the results returned by the handlers invoked -for the event.
  • -
  • success – if this optional attribute is set to -True, an associated event EventSuccess (original name -with “Success” appended) will automatically be fired when all -handlers for the event have been invoked successfully.
  • -
  • success_channels – the success event is, by default, delivered -to same channels as the successfully dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
  • complete – if this optional attribute is set to -True, an associated event EventComplete (original name -with “Complete” appended) will automatically be fired when all -handlers for the event and all events fired by these handlers -(recursively) have been invoked successfully.
  • -
  • success_channels – the complete event is, by default, delivered -to same channels as the initially dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
-
-
- -
-
-class circuits.app.daemon.WritePID(*args, **kwargs)
-

Bases: circuits.core.events.Event

-

“WritePID Event

-

This event can be fired to notify the Daemon Component that is should -retrive the current process’s id (pid) and write it out to the -configured path in the Daemon Component. This event (by default) -is used automatically by the Daemon Component after the -Daemonize.

-

An Event is a message send to one or more channels. It is eventually -dispatched to all components that have handlers for one -of the channels and the event type.

-

All normal arguments and keyword arguments passed to the constructor -of an event are passed on to the handler. When declaring a -handler, its argument list must therefore match the arguments -used for creating the event.

-

Every event has a name attribute that is used for matching -the event with the handlers. By default, the name is the uncameled -class name of the event.

- --- - - - -
Variables:
    -
  • channels

    an optional attribute that may be set before firing -the event. If defined (usually as a class variable), the attribute -specifies the channels that the event should be delivered -to as a tuple. This overrides the default behavior -of sending the event to the firing component’s channel.

    -

    When an event is fired, the value in this attribute -is replaced for the instance with the channels that -the event is actually sent to. This information may be used -e.g. when the event is passed as a parameter to a handler.

    -
  • -
  • value – this is a circuits.core.values.Value -object that holds the results returned by the handlers invoked -for the event.
  • -
  • success – if this optional attribute is set to -True, an associated event EventSuccess (original name -with “Success” appended) will automatically be fired when all -handlers for the event have been invoked successfully.
  • -
  • success_channels – the success event is, by default, delivered -to same channels as the successfully dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
  • complete – if this optional attribute is set to -True, an associated event EventComplete (original name -with “Complete” appended) will automatically be fired when all -handlers for the event and all events fired by these handlers -(recursively) have been invoked successfully.
  • -
  • success_channels – the complete event is, by default, delivered -to same channels as the initially dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
-
-
- -
-
-

Components

-
-
-class circuits.app.daemon.Daemon(pidfile, path='/', stdin=None, stdout=None, stderr=None, channel='daemon')
-

Bases: circuits.core.components.BaseComponent

-

Daemon Component

- --- - - - -
Parameters:
    -
  • pidfile (str or unicode) – .pid filename
  • -
  • stdin (str or unicode) – filename to log stdin
  • -
  • stdout (str or unicode) – filename to log stdout
  • -
  • stderr (str or unicode) – filename to log stderr
  • -
-
-
- -
-
-

Functions

-
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/api/circuits_app_env.html circuits-3.1.0+ds1/docs/build/html/api/circuits_app_env.html --- circuits-2.1.0/docs/build/html/api/circuits_app_env.html 2013-02-27 11:27:55.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/api/circuits_app_env.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,324 +0,0 @@ - - - - - - - - - circuits.app.env – Application Environment — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

circuits.app.env – Application Environment

-
-

Events

-
-
-class circuits.app.env.Create(*args, **kwargs)
-

Bases: circuits.app.env.EnvironmentEvent

-

Create Environment Event

-

An Event is a message send to one or more channels. It is eventually -dispatched to all components that have handlers for one -of the channels and the event type.

-

All normal arguments and keyword arguments passed to the constructor -of an event are passed on to the handler. When declaring a -handler, its argument list must therefore match the arguments -used for creating the event.

-

Every event has a name attribute that is used for matching -the event with the handlers. By default, the name is the uncameled -class name of the event.

- --- - - - -
Variables:
    -
  • channels

    an optional attribute that may be set before firing -the event. If defined (usually as a class variable), the attribute -specifies the channels that the event should be delivered -to as a tuple. This overrides the default behavior -of sending the event to the firing component’s channel.

    -

    When an event is fired, the value in this attribute -is replaced for the instance with the channels that -the event is actually sent to. This information may be used -e.g. when the event is passed as a parameter to a handler.

    -
  • -
  • value – this is a circuits.core.values.Value -object that holds the results returned by the handlers invoked -for the event.
  • -
  • success – if this optional attribute is set to -True, an associated event EventSuccess (original name -with “Success” appended) will automatically be fired when all -handlers for the event have been invoked successfully.
  • -
  • success_channels – the success event is, by default, delivered -to same channels as the successfully dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
  • complete – if this optional attribute is set to -True, an associated event EventComplete (original name -with “Complete” appended) will automatically be fired when all -handlers for the event and all events fired by these handlers -(recursively) have been invoked successfully.
  • -
  • success_channels – the complete event is, by default, delivered -to same channels as the initially dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
-
-
- -
-
-class circuits.app.env.Load(*args, **kwargs)
-

Bases: circuits.app.env.EnvironmentEvent

-

Load Environment Event

-

An Event is a message send to one or more channels. It is eventually -dispatched to all components that have handlers for one -of the channels and the event type.

-

All normal arguments and keyword arguments passed to the constructor -of an event are passed on to the handler. When declaring a -handler, its argument list must therefore match the arguments -used for creating the event.

-

Every event has a name attribute that is used for matching -the event with the handlers. By default, the name is the uncameled -class name of the event.

- --- - - - -
Variables:
    -
  • channels

    an optional attribute that may be set before firing -the event. If defined (usually as a class variable), the attribute -specifies the channels that the event should be delivered -to as a tuple. This overrides the default behavior -of sending the event to the firing component’s channel.

    -

    When an event is fired, the value in this attribute -is replaced for the instance with the channels that -the event is actually sent to. This information may be used -e.g. when the event is passed as a parameter to a handler.

    -
  • -
  • value – this is a circuits.core.values.Value -object that holds the results returned by the handlers invoked -for the event.
  • -
  • success – if this optional attribute is set to -True, an associated event EventSuccess (original name -with “Success” appended) will automatically be fired when all -handlers for the event have been invoked successfully.
  • -
  • success_channels – the success event is, by default, delivered -to same channels as the successfully dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
  • complete – if this optional attribute is set to -True, an associated event EventComplete (original name -with “Complete” appended) will automatically be fired when all -handlers for the event and all events fired by these handlers -(recursively) have been invoked successfully.
  • -
  • success_channels – the complete event is, by default, delivered -to same channels as the initially dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
-
-
- -
-
-

Components

-
-
-class circuits.app.env.Environment(path, envname, channel='env')
-

Bases: circuits.core.components.BaseComponent

-

Base Environment Component

-

Creates a new environment component that by default only -holds configuration and logger components.

-

This component can be extended to provide more complex -system and application environments.

-
- -
-
-

Functions

-
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/api/circuits_app.html circuits-3.1.0+ds1/docs/build/html/api/circuits_app.html --- circuits-2.1.0/docs/build/html/api/circuits_app.html 2013-02-27 11:27:54.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/api/circuits_app.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,199 +0,0 @@ - - - - - - - - - circuits.app – Application Support — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

circuits.app – Application Support

-

Application Components

-

Contains various components useful for application development and tasks -common to applications.

- --- - - - - - -
copyright:CopyRight (C) 2004-2012 by James Mills
license:MIT (See: LICENSE)
- -
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/api/circuits_app_log.html circuits-3.1.0+ds1/docs/build/html/api/circuits_app_log.html --- circuits-2.1.0/docs/build/html/api/circuits_app_log.html 2013-02-27 11:27:55.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/api/circuits_app_log.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,262 +0,0 @@ - - - - - - - - - circuits.app.log – Application Logging — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

circuits.app.log – Application Logging

-
-

Events

-
-
-class circuits.app.log.Log(*args, **kwargs)
-

Bases: circuits.core.events.Event

-

Log Event

-

An Event is a message send to one or more channels. It is eventually -dispatched to all components that have handlers for one -of the channels and the event type.

-

All normal arguments and keyword arguments passed to the constructor -of an event are passed on to the handler. When declaring a -handler, its argument list must therefore match the arguments -used for creating the event.

-

Every event has a name attribute that is used for matching -the event with the handlers. By default, the name is the uncameled -class name of the event.

- --- - - - -
Variables:
    -
  • channels

    an optional attribute that may be set before firing -the event. If defined (usually as a class variable), the attribute -specifies the channels that the event should be delivered -to as a tuple. This overrides the default behavior -of sending the event to the firing component’s channel.

    -

    When an event is fired, the value in this attribute -is replaced for the instance with the channels that -the event is actually sent to. This information may be used -e.g. when the event is passed as a parameter to a handler.

    -
  • -
  • value – this is a circuits.core.values.Value -object that holds the results returned by the handlers invoked -for the event.
  • -
  • success – if this optional attribute is set to -True, an associated event EventSuccess (original name -with “Success” appended) will automatically be fired when all -handlers for the event have been invoked successfully.
  • -
  • success_channels – the success event is, by default, delivered -to same channels as the successfully dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
  • complete – if this optional attribute is set to -True, an associated event EventComplete (original name -with “Complete” appended) will automatically be fired when all -handlers for the event and all events fired by these handlers -(recursively) have been invoked successfully.
  • -
  • success_channels – the complete event is, by default, delivered -to same channels as the initially dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
-
-
- -
-
-

Components

-
-
-class circuits.app.log.Logger(filename, name, type, level, channel='logger')
-

Bases: circuits.core.components.BaseComponent

-
- -
-
-

Functions

-
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/api/circuits_core_components.html circuits-3.1.0+ds1/docs/build/html/api/circuits_core_components.html --- circuits-2.1.0/docs/build/html/api/circuits_core_components.html 2013-02-27 11:27:55.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/api/circuits_core_components.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,335 +0,0 @@ - - - - - - - - - circuits.core.components – Components — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

circuits.core.components – Components

-

This module defines the BaseComponent and its subclass Component.

-
-

Classes

-
-
-class circuits.core.components.BaseComponent(*args, **kwargs)
-

Bases: circuits.core.manager.Manager

-

This is the base class for all components in a circuits based application. -Components can (and should, except for root components) be registered -with a parent component.

-

BaseComponents can declare methods as event handlers using the -handler decoration (see circuits.core.handlers.handler()). The -handlers are invoked for matching events from the -component’s channel (specified as the component’s channel attribute).

-

BaseComponents inherit from circuits.core.manager.Manager. -This provides components with the -circuits.core.manager.Manager.fireEvent() method that can -be used to fire events as the result of some computation.

-

Apart from the fireEvent() method, the Manager nature is important -for root components that are started or run.

- --- - - - -
Variables:channel – a component can be associated with a specific channel -by setting this attribute. This should either be done by -specifying a class attribute channel in the derived class or by -passing a keyword parameter channel=”...” to __init__. -If specified, the component’s handlers receive events on the -specified channel only, and events fired by the component will -be sent on the specified channel (this behavior may be overridden, -see Event, fireEvent() and -handler()). By default, the channel -attribute is set to “*”, meaning that events are fired on all -channels and received from all channels.
-

initializes x; see x.__class__.__doc__ for signature

-
-
-register(parent)
-

Inserts this component in the component tree as a child -of the given parent node.

- --- - - - -
Parameters:parent (Manager) – the parent component after registration has completed.
-

This method fires a Registered event to inform -other components in the tree about the new member.

-
- -
-
-unregister()
-

Removes this component from the component tree.

-

Removing a component from the component tree is a two stage process. -First, the component is marked as to be removed, which prevents it -from receiving further events, and a -PrepareUnregister event is fired. This -allows other components to e.g. release references to the component -to be removed before it is actually removed from the component tree.

-

After the processing of the PrepareUnregister event has completed, -the component is removed from the tree and an -Unregistered event is fired.

-
- -
-
-classmethod handlers()
-

Returns a list of all event handlers for this Component

-
- -
-
-classmethod handles(*names)
-

Returns True if all names are event handlers of this Component

-
- -
- -
-
-class circuits.core.components.Component(*args, **kwargs)
-

Bases: circuits.core.components.BaseComponent

-

If you use Component instead of BaseComponent as base class for your own -component class, then all methods that are not marked as private -(i.e: start with an underscore) are automatically decorated as handlers.

-

The methods are invoked for all events from the component’s channel -where the event’s name matches the method’s name.

-
- -
-
-

Components

-

none

-
-
-

Events

-
-
-class circuits.core.components.PrepareUnregister(*args, **kwargs)
-

Bases: circuits.core.events.Event

-

This event is fired when a component is about to be unregistered -from the component tree. Unregistering a component actually -detaches the complete subtree that the unregistered component -is the root of. Components that need to know if they -are removed from the main tree (e.g. because they maintain -relationships to other components in the tree) handle this -event, check if the component being unregistered is one -of their ancestors and act accordingly.

- --- - - - -
Parameters:component – the component that will be unregistered
-
-
-in_subtree(component)
-

Convenience method that checks if the given component -is in the subtree that is about to be detached.

-
- -
- -
-
-class circuits.core.components.SingletonError
-

Bases: exceptions.Exception

-

Raised if a Component with the singleton class attribute is True.

-
- -
-
-

Functions

-

none

-
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/api/circuits_core_debugger.html circuits-3.1.0+ds1/docs/build/html/api/circuits_core_debugger.html --- circuits-2.1.0/docs/build/html/api/circuits_core_debugger.html 2013-02-27 11:27:55.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/api/circuits_core_debugger.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,234 +0,0 @@ - - - - - - - - - circuits.core.debugger – Debugger — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

circuits.core.debugger – Debugger

-

Debugger component used to debug each event in a system by printing -each event to sys.stderr or to a Logger Component instance.

-
-

Classes

-

none

-
-
-

Components

-
-
-class circuits.core.debugger.Debugger(errors=True, events=True, file=None, logger=None, prefix=None, trim=None, **kwargs)
-

Bases: circuits.core.components.BaseComponent

-

Create a new Debugger Component

-

Creates a new Debugger Component that filters all events in the system -printing each event to sys.stderr or a Logger Component.

- --- - - - - - -
Variables:
    -
  • IgnoreEvents – list of events (str) to ignore
  • -
  • IgnoreChannels – list of channels (str) to ignore
  • -
  • enabled – Enabled/Disabled flag
  • -
-
Parameters:

log – Logger Component instance or None (default)

-
-

initializes x; see x.__class__.__doc__ for signature

-
- -
-
-

Events

-

none

-
-
-

Functions

-

none

-
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/api/circuits_core_events.html circuits-3.1.0+ds1/docs/build/html/api/circuits_core_events.html --- circuits-2.1.0/docs/build/html/api/circuits_core_events.html 2013-02-27 11:27:55.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/api/circuits_core_events.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,459 +0,0 @@ - - - - - - - - - circuits.core.events – Events — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

circuits.core.events – Events

-

This module defines the basic Event class and common events.

-
-

Classes

-
-
-class circuits.core.events.Event(*args, **kwargs)
-

Bases: circuits.core.events.BaseEvent

-

An Event is a message send to one or more channels. It is eventually -dispatched to all components that have handlers for one -of the channels and the event type.

-

All normal arguments and keyword arguments passed to the constructor -of an event are passed on to the handler. When declaring a -handler, its argument list must therefore match the arguments -used for creating the event.

-

Every event has a name attribute that is used for matching -the event with the handlers. By default, the name is the uncameled -class name of the event.

- --- - - - -
Variables:
    -
  • channels

    an optional attribute that may be set before firing -the event. If defined (usually as a class variable), the attribute -specifies the channels that the event should be delivered -to as a tuple. This overrides the default behavior -of sending the event to the firing component’s channel.

    -

    When an event is fired, the value in this attribute -is replaced for the instance with the channels that -the event is actually sent to. This information may be used -e.g. when the event is passed as a parameter to a handler.

    -
  • -
  • value – this is a circuits.core.values.Value -object that holds the results returned by the handlers invoked -for the event.
  • -
  • success – if this optional attribute is set to -True, an associated event EventSuccess (original name -with “Success” appended) will automatically be fired when all -handlers for the event have been invoked successfully.
  • -
  • success_channels – the success event is, by default, delivered -to same channels as the successfully dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
  • complete – if this optional attribute is set to -True, an associated event EventComplete (original name -with “Complete” appended) will automatically be fired when all -handlers for the event and all events fired by these handlers -(recursively) have been invoked successfully.
  • -
  • success_channels – the complete event is, by default, delivered -to same channels as the initially dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
-
-
- -
-
-

Components

-

none

-
-
-

Events

-
-
-class circuits.core.events.Error(type, value, traceback, handler=None)
-

Bases: circuits.core.events.Event

-

Error Event

-

This Event is sent for any exceptions that occur during the execution -of an Event Handler that is not SystemExit or KeyboardInterrupt.

- --- - - - -
Parameters:
    -
  • type (type) – type of exception
  • -
  • value (exceptions.TypeError) – exception object
  • -
  • traceback (traceback) – traceback of exception
  • -
  • kwargs (dict) – (Optional) Additional Information
  • -
-
-
- -
-
-class circuits.core.events.Failure(*args, **kwargs)
-

Bases: circuits.core.events.DerivedEvent

-

Failure Event

-

This Event is sent when an error has occurred with the execution of an -Event Handlers.

- --- - - - -
Parameters:event (Event) – The event that failed
-
- -
-
-class circuits.core.events.Registered(component, manager)
-

Bases: circuits.core.events.Event

-

Registered Event

-

This Event is sent when a Component has registered with another Component -or Manager. This Event is only sent iif the Component or Manager being -registered with is not itself.

- --- - - - -
Parameters:
    -
  • component (Component) – The Component being registered
  • -
  • manager (Component or Manager) – The Component or Manager being registered with
  • -
-
-
- -
-
-class circuits.core.events.Signal(signal, stack)
-

Bases: circuits.core.events.Event

-

Signal Event

-

This Event is sent when a Component receives a signal.

- --- - - - -
Parameters:
    -
  • signal – The signal number received.
  • -
  • stack – The interrupted stack frame.
  • -
-
-
- -
-
-class circuits.core.events.Started(component)
-

Bases: circuits.core.events.Event

-

Started Event

-

This Event is sent when a Component has started running.

- --- - - - -
Parameters:component (Component or Manager) – The component that was started
-
- -
-
-class circuits.core.events.Stopped(component)
-

Bases: circuits.core.events.Event

-

Stopped Event

-

This Event is sent when a Component has stopped running.

- --- - - - -
Parameters:component (Component or Manager) – The component that has stopped
-
- -
-
-class circuits.core.events.Success(*args, **kwargs)
-

Bases: circuits.core.events.DerivedEvent

-

Success Event

-

This Event is sent when all handlers (for a particular event) have been -executed successfully, see Manager.

- --- - - - -
Parameters:event (Event) – The event that has completed.
-
- -
-
-class circuits.core.events.Unregister(component=None)
-

Bases: circuits.core.events.Event

-

Unregister Event

-

This Event ask for a Component to unregister from its -Component or Manager.

-
- -
-
-class circuits.core.events.Unregistered(component, manager)
-

Bases: circuits.core.events.Event

-

Unregistered Event

-

This Event is sent when a Component has been unregistered from its -Component or Manager.

-
- -
-
-class circuits.core.events.GenerateEvents(lock, max_wait)
-

Bases: circuits.core.events.Event

-

Generate events event

-

This event is sent by the circuits core. All components that generate -timed events or events from external sources (e.g. data becoming -available) should fire any pending events in their “generate_events” -handler. The handler must either be a filter (preventing other -handler from being called in the same iteration) or must invoke -reduce_time_left() with parameter 0.

- --- - - - -
Parameters:max_wait – maximum time available for generating events.
-

Components that actually consume time waiting for events to be generated, -thus suspending normal execution, must provide a method resume -that interrupts waiting for events.

-
-
-time_left
-

The time left for generating events. A value less than 0 -indicates unlimited time. You should have only -one component in your system (usually a poller component) that -spends up to “time left” until it generates an event.

-
- -
-
-reduce_time_left(time_left)
-

Update the time left for generating events. This is typically -used by event generators that currently don’t want to generate -an event but know that they will within a certain time. By -reducing the time left, they make sure that they are reinvoked -when the time for generating the event has come (at the latest).

-

This method can only be used to reduce the time left. If the -parameter is larger than the current value of time left, it is -ignored.

-

If the time left is reduced to 0 and the event is currently -being handled, the handler’s resume method is invoked.

-
- -
- -
-
-

Functions

-

none

-
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/api/circuits_core_handlers.html circuits-3.1.0+ds1/docs/build/html/api/circuits_core_handlers.html --- circuits-2.1.0/docs/build/html/api/circuits_core_handlers.html 2013-02-27 11:27:56.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/api/circuits_core_handlers.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,271 +0,0 @@ - - - - - - - - - circuits.core.handlers – Handlers — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

circuits.core.handlers – Handlers

-

This module define the @handler decorator/function and the HandlesType type.

-
-

Classes

-
-
-class circuits.core.handlers.HandlerMetaClass(name, bases, ns)
-

Bases: type

-
- -
-
-

Components

-

none

-
-
-

Events

-

none

-
-
-

Functions

-
-
-circuits.core.handlers.handler(*names, **kwargs)
-

Creates an Event Handler

-

This decorator can be applied to methods of classes derived from -circuits.core.components.BaseComponent. It marks the method as a -handler for the events passed as arguments to the @handler decorator. -The events are specified by their name.

-

The decorated method’s arguments must match the arguments passed to the -circuits.core.events.Event on creation. Optionally, the -method may have an additional first argument named event. If declared, -the event object that caused the handler to be invoked is assigned to it.

-

By default, the handler is invoked by the component’s root -Manager for events that are propagated on the channel -determined by the BaseComponent’s channel attribute. -This may be overridden by specifying a different channel as a keyword -parameter of the decorator (channel=...).

-

Keyword argument priority influences the order in which handlers -for a specific event are invoked. The higher the priority, the earlier -the handler is executed.

-

A handler may also be specified as a filter by adding -the keyword argument filter=True to the decorator. -If such a handler returns a value different from None, no more -handlers are invoked for the handled event. Filtering handlers are -invoked before normal handlers with the same priority (but after any -handlers with higher priority).

-

If you want to override a handler defined in a base class of your -component, you must specify override=True, else your method becomes -an additional handler for the event.

-

Return value

-

Normally, the results returned by the handlers for an event are simply -collected in the circuits.core.events.Event‘s value -attribute. As a special case, a handler may return a -types.GeneratorType. This signals to the dispatcher that the -handler isn’t ready to deliver a result yet. -Rather, it has interrupted it’s execution with a yield None -statement, thus preserving its current execution state.

-

The dispatcher saves the returned generator object as a task. -All tasks are reexamined (i.e. their next() method is invoked) -when the pending events have been executed.

-

This feature avoids an unnecessarily complicated chaining of event -handlers. Imagine a handler A that needs the results from firing an -event E in order to complete. Then without this feature, the final -action of A would be to fire event E, and another handler for -an event SuccessE would be required to complete handler A’s -operation, now having the result from invoking E available -(actually it’s even a bit more complicated).

-

Using this “suspend” feature, the handler simply fires event E and -then yields None until e.g. it finds a result in E’s value -attribute. For the simplest scenario, there even is a utility -method circuits.core.manager.Manager.callEvent() that combines -firing and waiting.

-
- -
-
-circuits.core.handlers.reprhandler(handler)
-
- -
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/api/circuits_core.html circuits-3.1.0+ds1/docs/build/html/api/circuits_core.html --- circuits-2.1.0/docs/build/html/api/circuits_core.html 2013-02-27 11:27:55.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/api/circuits_core.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,195 +0,0 @@ - - - - - - - - - circuits.core – Core Functionality — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
- - - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/api/circuits_core_loader.html circuits-3.1.0+ds1/docs/build/html/api/circuits_core_loader.html --- circuits-2.1.0/docs/build/html/api/circuits_core_loader.html 2013-02-27 11:27:56.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/api/circuits_core_loader.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,219 +0,0 @@ - - - - - - - - - circuits.core.loader – Loader — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

circuits.core.loader – Loader

-

This module implements a generic Loader suitable for dynamically loading -components from other modules. This supports loading from local paths, -eggs and zip archives. Both setuptools and distribute are fully supported.

-
-

Classes

-

none

-
-
-

Components

-
-
-class circuits.core.loader.Loader(auto_register=True, init_args=None, init_kwargs=None, paths=None, channel='loader')
-

Bases: circuits.core.components.BaseComponent

-

Create a new Loader Component

-

Creates a new Loader Component that enables dynamic loading of -components from modules either in local paths, eggs or zip archives.

-

initializes x; see x.__class__.__doc__ for signature

-
- -
-
-

Events

-

none

-
-
-

Functions

-

none

-
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/api/circuits_core_manager.html circuits-3.1.0+ds1/docs/build/html/api/circuits_core_manager.html --- circuits-2.1.0/docs/build/html/api/circuits_core_manager.html 2013-02-27 11:27:56.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/api/circuits_core_manager.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,408 +0,0 @@ - - - - - - - - - circuits.core.manager – Manager — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

circuits.core.manager – Manager

-

This module defines the Manager class.

-
-

Classes

-
-
-class circuits.core.manager.Manager(*args, **kwargs)
-

Bases: object

-

The manager class has two roles. As a base class for component -implementation, it provides methods for event and handler management. -The method fireEvent() appends a new event at the end of the event -queue for later execution. waitEvent() suspends the execution -of a handler until all handlers for a given event have been invoked. -callEvent() combines the last two methods in a single method.

-

The methods addHandler() and removeHandler() allow handlers -for events to be added and removed dynamically. (The more common way to -register a handler is to use the handler() decorator -or derive the class from Component.)

-

In its second role, the Manager takes the role of the -event executor. Every component hierarchy has a root component that -maintains a queue of events. Firing an event effectively means -appending it to the event queue maintained by the root manager. -The flush() method removes all pending events from the -queue and, for each event, invokes all the handlers. Usually, -flush() is indirectly invoked by run().

-

The manager optionally provides information about the execution of -events as automatically generated events. If an Event -has its success attribute set to True, the manager fires -a Success event if all handlers have been -executed without error. Note that this event will be -enqueued (and dispatched) immediately after the events that have been -fired by the event’s handlers. So the success event indicates both -the successful invocation of all handlers for the event and the -processing of the immediate follow-up events fired by those handlers.

-

Sometimes it is not sufficient to know that an event and its -immediate follow-up events have been processed. Rather, it is -important to know when all state changes triggered by an event, -directly or indirectly, have been performed. This also includes -the processing of events that have been fired when invoking -the handlers for the follow-up events and the processing of events -that have again been fired by those handlers and so on. The completion -of the processing of an event and all its direct or indirect -follow-up events may be indicated by a Complete -event. This event is generated by the manager if Event -has its complete attribute set to True.

-

Apart from the event queue, the root manager also maintains a list of -tasks, actually Python generators, that are updated when the event queue -has been flushed.

-

initializes x; see x.__class__.__doc__ for signature

-
-
-name
-

Return the name of this Component/Manager

-
- -
-
-running
-

Return the running state of this Component/Manager

-
- -
-
-pid
-

Return the process id of this Component/Manager

-
- -
-
-fireEvent(event, *channels)
-

Fire an event into the system.

- --- - - - -
Parameters:
    -
  • event – The event that is to be fired.
  • -
  • channels – The channels that this event is delivered on. -If no channels are specified, the event is delivered to the -channels found in the event’s channel attribute. -If this attribute is not set, the event is delivered to -the firing component’s channel. And eventually, -when set neither, the event is delivered on all -channels (“*”).
  • -
-
-
- -
-
-fire(event, *channels)
-

Fire an event into the system.

- --- - - - -
Parameters:
    -
  • event – The event that is to be fired.
  • -
  • channels – The channels that this event is delivered on. -If no channels are specified, the event is delivered to the -channels found in the event’s channel attribute. -If this attribute is not set, the event is delivered to -the firing component’s channel. And eventually, -when set neither, the event is delivered on all -channels (“*”).
  • -
-
-
- -
-
-callEvent(event, *channels)
-

Fire the given event to the specified channels and suspend -execution until it has been dispatched. This method may only -be invoked as argument to a yield on the top execution level -of a handler (e.g. “yield self.callEvent(event)”). -It effectively creates and returns a generator -that will be invoked by the main loop until the event has -been dispatched (see circuits.core.handlers.handler()).

-
- -
-
-call(event, *channels)
-

Fire the given event to the specified channels and suspend -execution until it has been dispatched. This method may only -be invoked as argument to a yield on the top execution level -of a handler (e.g. “yield self.callEvent(event)”). -It effectively creates and returns a generator -that will be invoked by the main loop until the event has -been dispatched (see circuits.core.handlers.handler()).

-
- -
-
-flushEvents()
-

Flush all Events in the Event Queue. If called on a manager -that is not the root of an object hierarchy, the invocation -is delegated to the root manager.

-
- -
-
-flush()
-

Flush all Events in the Event Queue. If called on a manager -that is not the root of an object hierarchy, the invocation -is delegated to the root manager.

-
- -
-
-start(process=False, link=None)
-

Start a new thread or process that invokes this manager’s -run() method. The invocation of this method returns -immediately after the task or process has been started.

-
- -
-
-stop()
-

Stop this manager. Invoking this method causes -an invocation of run() to return.

-
- -
-
-tick(timeout=-1)
-

Execute all possible actions once. Process all registered tasks -and flush the event queue. If the application is running fire a -GenerateEvents to get new events from sources.

-

This method is usually invoked from run(). It may also be -used to build an application specific main loop.

- --- - - - -
Parameters:timeout (float, measuring seconds) – the maximum waiting time spent in this method. If -negative, the method may block until at least one action -has been taken.
-
- -
-
-run(socket=None)
-

Run this manager. The method fires the -Started event and then continuously -calls tick().

-

The method returns when the manager’s stop() method is invoked.

-

If invoked by a programs main thread, a signal handler for -the INT and TERM signals is installed. This handler -fires the corresponding Signal -events and then calls stop() for the manager.

-
- -
- -
-
-

Components

-

none

-
-
-

Events

-

none

-
-
-

Functions

-

none

-
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/api/circuits_core_pollers.html circuits-3.1.0+ds1/docs/build/html/api/circuits_core_pollers.html --- circuits-2.1.0/docs/build/html/api/circuits_core_pollers.html 2013-02-27 11:27:56.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/api/circuits_core_pollers.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,247 +0,0 @@ - - - - - - - - - circuits.core.pollers – I/O Pollers — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

circuits.core.pollers – I/O Pollers

-

Poller Components for asynchronous file and socket I/O.

-

This module contains Poller components that enable polling of file or socket -descriptors for read/write events. Pollers: -- Select -- Poll -- EPoll

-
-

Classes

-

none

-
-
-

Components

-
-
-class circuits.core.pollers.BasePoller(timeout=0.01, channel=None)
-

Bases: circuits.core.components.BaseComponent

-
- -
-
-class circuits.core.pollers.Select(timeout=0.01, channel='select')
-

Bases: circuits.core.pollers.BasePoller

-

Select(...) -> new Select Poller Component

-

Creates a new Select Poller Component that uses the select poller -implementation. This poller is not recommended but is available for legacy -reasons as most systems implement select-based polling for backwards -compatibility.

-
- -
-
-class circuits.core.pollers.Poll(timeout=0.01, channel='poll')
-

Bases: circuits.core.pollers.BasePoller

-

Poll(...) -> new Poll Poller Component

-

Creates a new Poll Poller Component that uses the poll poller -implementation.

-
- -
-
-class circuits.core.pollers.EPoll(timeout=0.01, channel='epoll')
-

Bases: circuits.core.pollers.BasePoller

-

EPoll(...) -> new EPoll Poller Component

-

Creates a new EPoll Poller Component that uses the epoll poller -implementation.

-
- -
-
-

Events

-

none

-
-
-

Functions

-

none

-
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/api/circuits_core_timers.html circuits-3.1.0+ds1/docs/build/html/api/circuits_core_timers.html --- circuits-2.1.0/docs/build/html/api/circuits_core_timers.html 2013-02-27 11:27:56.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/api/circuits_core_timers.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,240 +0,0 @@ - - - - - - - - - circuits.core.timers – Timers — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

circuits.core.timers – Timers

-

Timer component to facilitate timed events.

-
-

Classes

-

none

-
-
-

Components

-
-
-class circuits.core.timers.Timer(interval, event, *channels, **kwargs)
-

Bases: circuits.core.components.BaseComponent

-

A timer is a component that fires an event once after a certain -delay or periodically at a regular interval.

- --- - - - -
Parameters:
    -
  • interval (datetime or float number) – the delay or interval to wait for until -the event is fired. If interval is specified as -datetime, the interval is recalculated as the time span from -now to the given datetime.
  • -
  • event (Event) – the event to fire.
  • -
-
-

If the optional keyword argument persist is set to True, -the event will be fired repeatedly. Else the timer fires the -event once and then unregisters itself.

-
-
-reset()
-

Reset the timer, i.e. clear the amount of time already waited -for.

-
- -
- -
-
-

Events

-

none

-
-
-

Functions

-

none

-
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/api/circuits_core_utils.html circuits-3.1.0+ds1/docs/build/html/api/circuits_core_utils.html --- circuits-2.1.0/docs/build/html/api/circuits_core_utils.html 2013-02-27 11:27:56.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/api/circuits_core_utils.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,238 +0,0 @@ - - - - - - - - - circuits.core.utils – Utilities — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

circuits.core.utils – Utilities

-

Utils

-

This module defines utilities used by circuits.

-
-

Classes

-

none

-
-
-

Components

-

none

-
-
-

Events

-

none

-
-
-

Functions

-
-
-circuits.core.utils.findchannel(root, channel, all=False)
-
- -
-
-circuits.core.utils.findcmp(root, component, all=False)
-
- -
-
-circuits.core.utils.findroot(component)
-
- -
-
-circuits.core.utils.findtype(root, component, all=False)
-
- -
-
-circuits.core.utils.flatten(root, visited=None)
-
- -
-
-circuits.core.utils.safeimport(name)
-
- -
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/api/circuits_core_values.html circuits-3.1.0+ds1/docs/build/html/api/circuits_core_values.html --- circuits-2.1.0/docs/build/html/api/circuits_core_values.html 2013-02-27 11:27:56.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/api/circuits_core_values.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,237 +0,0 @@ - - - - - - - - - circuits.core.values – Value — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

circuits.core.values – Value

-

This defines the Value object used by components and events.

-
-

Classes

-
-
-class circuits.core.values.Value(event=None, manager=None)
-

Bases: object

-

Create a new future Value Object

-

Creates a new future Value Object which is used by Event Objects and the -Manager to store the result(s) of an Event Handler’s exeuction of some -Event in the system.

- --- - - - - - -
Parameters:
    -
  • event (Event instance) – The Event this Value is associated with.
  • -
  • manager (A Manager/Component instance.) – The Manager/Component used to trigger notifications.
  • -
-
Variables:
    -
  • result – True if this value has been changed.
  • -
  • errors – True if while setting this value an exception occured.
  • -
  • notify – True or an event name to notify of changes to this value
  • -
-
-

This is a Future/Promise implementation.

-
- -
-
-

Components

-

none

-
-
-

Events

-

none

-
-
-

Functions

-

none

-
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/api/circuits_core_workers.html circuits-3.1.0+ds1/docs/build/html/api/circuits_core_workers.html --- circuits-2.1.0/docs/build/html/api/circuits_core_workers.html 2013-02-27 11:27:56.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/api/circuits_core_workers.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,253 +0,0 @@ - - - - - - - - - circuits.core.workers – Workers — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

circuits.core.workers – Workers

-

Workers

-

Worker components used to perform “work” in independent threads or -processes. Worker(s) are typically used by a Pool (circuits.core.pools) -to create a pool of workers. Worker(s) are not registered with a Manager -or another Component - instead they are managed by the Pool. If a Worker -is used independently it should not be registered as it causes its -main event handler _on_task to execute in the other thread blocking it.

-
-

Classes

-

none

-
-
-

Components

-
-
-class circuits.core.workers.Worker(*args, **kwargs)
-

Bases: circuits.core.components.BaseComponent

-

A thread/process Worker Component

-

This Component creates a Worker (either a thread or process) which -when given a Task, will execute the given function in the task -in the background in its thread/process.

- --- - - - -
Parameters:process (bool) – True to start this Worker as a process (Thread otherwise)
-

initializes x; see x.__class__.__doc__ for signature

-
- -
-
-

Events

-
-
-class circuits.core.workers.Task(f, *args, **kwargs)
-

Bases: circuits.core.events.Event

-

Task Event

-

This Event is used to initiate a new task to be performed by a Worker -or a Pool of Worker(s).

- --- - - - -
Parameters:
    -
  • f (function) – The function to be executed.
  • -
  • args (tuple) – Arguments to pass to the function
  • -
  • kwargs (dict) – Keyword Arguments to pass to the function
  • -
-
-
- -
-
-

Functions

-

none

-
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/api/circuits_io_events.html circuits-3.1.0+ds1/docs/build/html/api/circuits_io_events.html --- circuits-2.1.0/docs/build/html/api/circuits_io_events.html 2013-02-27 11:27:57.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/api/circuits_io_events.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,657 +0,0 @@ - - - - - - - - - circuits.io.events – I/O Events — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

circuits.io.events – I/O Events

-
-

Events

-
-
-class circuits.io.events.Close(*args, **kwargs)
-

Bases: circuits.core.events.Event

-

Close Event

-

An Event is a message send to one or more channels. It is eventually -dispatched to all components that have handlers for one -of the channels and the event type.

-

All normal arguments and keyword arguments passed to the constructor -of an event are passed on to the handler. When declaring a -handler, its argument list must therefore match the arguments -used for creating the event.

-

Every event has a name attribute that is used for matching -the event with the handlers. By default, the name is the uncameled -class name of the event.

- --- - - - -
Variables:
    -
  • channels

    an optional attribute that may be set before firing -the event. If defined (usually as a class variable), the attribute -specifies the channels that the event should be delivered -to as a tuple. This overrides the default behavior -of sending the event to the firing component’s channel.

    -

    When an event is fired, the value in this attribute -is replaced for the instance with the channels that -the event is actually sent to. This information may be used -e.g. when the event is passed as a parameter to a handler.

    -
  • -
  • value – this is a circuits.core.values.Value -object that holds the results returned by the handlers invoked -for the event.
  • -
  • success – if this optional attribute is set to -True, an associated event EventSuccess (original name -with “Success” appended) will automatically be fired when all -handlers for the event have been invoked successfully.
  • -
  • success_channels – the success event is, by default, delivered -to same channels as the successfully dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
  • complete – if this optional attribute is set to -True, an associated event EventComplete (original name -with “Complete” appended) will automatically be fired when all -handlers for the event and all events fired by these handlers -(recursively) have been invoked successfully.
  • -
  • success_channels – the complete event is, by default, delivered -to same channels as the initially dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
-
-
- -
-
-class circuits.io.events.Closed(*args, **kwargs)
-

Bases: circuits.core.events.Event

-

Closed Event

-

An Event is a message send to one or more channels. It is eventually -dispatched to all components that have handlers for one -of the channels and the event type.

-

All normal arguments and keyword arguments passed to the constructor -of an event are passed on to the handler. When declaring a -handler, its argument list must therefore match the arguments -used for creating the event.

-

Every event has a name attribute that is used for matching -the event with the handlers. By default, the name is the uncameled -class name of the event.

- --- - - - -
Variables:
    -
  • channels

    an optional attribute that may be set before firing -the event. If defined (usually as a class variable), the attribute -specifies the channels that the event should be delivered -to as a tuple. This overrides the default behavior -of sending the event to the firing component’s channel.

    -

    When an event is fired, the value in this attribute -is replaced for the instance with the channels that -the event is actually sent to. This information may be used -e.g. when the event is passed as a parameter to a handler.

    -
  • -
  • value – this is a circuits.core.values.Value -object that holds the results returned by the handlers invoked -for the event.
  • -
  • success – if this optional attribute is set to -True, an associated event EventSuccess (original name -with “Success” appended) will automatically be fired when all -handlers for the event have been invoked successfully.
  • -
  • success_channels – the success event is, by default, delivered -to same channels as the successfully dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
  • complete – if this optional attribute is set to -True, an associated event EventComplete (original name -with “Complete” appended) will automatically be fired when all -handlers for the event and all events fired by these handlers -(recursively) have been invoked successfully.
  • -
  • success_channels – the complete event is, by default, delivered -to same channels as the initially dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
-
-
- -
-
-class circuits.io.events.EOF(*args, **kwargs)
-

Bases: circuits.core.events.Event

-

EOF Event

-

An Event is a message send to one or more channels. It is eventually -dispatched to all components that have handlers for one -of the channels and the event type.

-

All normal arguments and keyword arguments passed to the constructor -of an event are passed on to the handler. When declaring a -handler, its argument list must therefore match the arguments -used for creating the event.

-

Every event has a name attribute that is used for matching -the event with the handlers. By default, the name is the uncameled -class name of the event.

- --- - - - -
Variables:
    -
  • channels

    an optional attribute that may be set before firing -the event. If defined (usually as a class variable), the attribute -specifies the channels that the event should be delivered -to as a tuple. This overrides the default behavior -of sending the event to the firing component’s channel.

    -

    When an event is fired, the value in this attribute -is replaced for the instance with the channels that -the event is actually sent to. This information may be used -e.g. when the event is passed as a parameter to a handler.

    -
  • -
  • value – this is a circuits.core.values.Value -object that holds the results returned by the handlers invoked -for the event.
  • -
  • success – if this optional attribute is set to -True, an associated event EventSuccess (original name -with “Success” appended) will automatically be fired when all -handlers for the event have been invoked successfully.
  • -
  • success_channels – the success event is, by default, delivered -to same channels as the successfully dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
  • complete – if this optional attribute is set to -True, an associated event EventComplete (original name -with “Complete” appended) will automatically be fired when all -handlers for the event and all events fired by these handlers -(recursively) have been invoked successfully.
  • -
  • success_channels – the complete event is, by default, delivered -to same channels as the initially dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
-
-
- -
-
-class circuits.io.events.Error(*args, **kwargs)
-

Bases: circuits.core.events.Event

-

Error Event

-

An Event is a message send to one or more channels. It is eventually -dispatched to all components that have handlers for one -of the channels and the event type.

-

All normal arguments and keyword arguments passed to the constructor -of an event are passed on to the handler. When declaring a -handler, its argument list must therefore match the arguments -used for creating the event.

-

Every event has a name attribute that is used for matching -the event with the handlers. By default, the name is the uncameled -class name of the event.

- --- - - - -
Variables:
    -
  • channels

    an optional attribute that may be set before firing -the event. If defined (usually as a class variable), the attribute -specifies the channels that the event should be delivered -to as a tuple. This overrides the default behavior -of sending the event to the firing component’s channel.

    -

    When an event is fired, the value in this attribute -is replaced for the instance with the channels that -the event is actually sent to. This information may be used -e.g. when the event is passed as a parameter to a handler.

    -
  • -
  • value – this is a circuits.core.values.Value -object that holds the results returned by the handlers invoked -for the event.
  • -
  • success – if this optional attribute is set to -True, an associated event EventSuccess (original name -with “Success” appended) will automatically be fired when all -handlers for the event have been invoked successfully.
  • -
  • success_channels – the success event is, by default, delivered -to same channels as the successfully dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
  • complete – if this optional attribute is set to -True, an associated event EventComplete (original name -with “Complete” appended) will automatically be fired when all -handlers for the event and all events fired by these handlers -(recursively) have been invoked successfully.
  • -
  • success_channels – the complete event is, by default, delivered -to same channels as the initially dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
-
-
- -
-
-class circuits.io.events.Opened(*args, **kwargs)
-

Bases: circuits.core.events.Event

-

Opened Event

-

An Event is a message send to one or more channels. It is eventually -dispatched to all components that have handlers for one -of the channels and the event type.

-

All normal arguments and keyword arguments passed to the constructor -of an event are passed on to the handler. When declaring a -handler, its argument list must therefore match the arguments -used for creating the event.

-

Every event has a name attribute that is used for matching -the event with the handlers. By default, the name is the uncameled -class name of the event.

- --- - - - -
Variables:
    -
  • channels

    an optional attribute that may be set before firing -the event. If defined (usually as a class variable), the attribute -specifies the channels that the event should be delivered -to as a tuple. This overrides the default behavior -of sending the event to the firing component’s channel.

    -

    When an event is fired, the value in this attribute -is replaced for the instance with the channels that -the event is actually sent to. This information may be used -e.g. when the event is passed as a parameter to a handler.

    -
  • -
  • value – this is a circuits.core.values.Value -object that holds the results returned by the handlers invoked -for the event.
  • -
  • success – if this optional attribute is set to -True, an associated event EventSuccess (original name -with “Success” appended) will automatically be fired when all -handlers for the event have been invoked successfully.
  • -
  • success_channels – the success event is, by default, delivered -to same channels as the successfully dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
  • complete – if this optional attribute is set to -True, an associated event EventComplete (original name -with “Complete” appended) will automatically be fired when all -handlers for the event and all events fired by these handlers -(recursively) have been invoked successfully.
  • -
  • success_channels – the complete event is, by default, delivered -to same channels as the initially dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
-
-
- -
-
-class circuits.io.events.Read(*args, **kwargs)
-

Bases: circuits.core.events.Event

-

Read Event

-

An Event is a message send to one or more channels. It is eventually -dispatched to all components that have handlers for one -of the channels and the event type.

-

All normal arguments and keyword arguments passed to the constructor -of an event are passed on to the handler. When declaring a -handler, its argument list must therefore match the arguments -used for creating the event.

-

Every event has a name attribute that is used for matching -the event with the handlers. By default, the name is the uncameled -class name of the event.

- --- - - - -
Variables:
    -
  • channels

    an optional attribute that may be set before firing -the event. If defined (usually as a class variable), the attribute -specifies the channels that the event should be delivered -to as a tuple. This overrides the default behavior -of sending the event to the firing component’s channel.

    -

    When an event is fired, the value in this attribute -is replaced for the instance with the channels that -the event is actually sent to. This information may be used -e.g. when the event is passed as a parameter to a handler.

    -
  • -
  • value – this is a circuits.core.values.Value -object that holds the results returned by the handlers invoked -for the event.
  • -
  • success – if this optional attribute is set to -True, an associated event EventSuccess (original name -with “Success” appended) will automatically be fired when all -handlers for the event have been invoked successfully.
  • -
  • success_channels – the success event is, by default, delivered -to same channels as the successfully dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
  • complete – if this optional attribute is set to -True, an associated event EventComplete (original name -with “Complete” appended) will automatically be fired when all -handlers for the event and all events fired by these handlers -(recursively) have been invoked successfully.
  • -
  • success_channels – the complete event is, by default, delivered -to same channels as the initially dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
-
-
- -
-
-class circuits.io.events.Seek(*args, **kwargs)
-

Bases: circuits.core.events.Event

-

Seek Event

-

An Event is a message send to one or more channels. It is eventually -dispatched to all components that have handlers for one -of the channels and the event type.

-

All normal arguments and keyword arguments passed to the constructor -of an event are passed on to the handler. When declaring a -handler, its argument list must therefore match the arguments -used for creating the event.

-

Every event has a name attribute that is used for matching -the event with the handlers. By default, the name is the uncameled -class name of the event.

- --- - - - -
Variables:
    -
  • channels

    an optional attribute that may be set before firing -the event. If defined (usually as a class variable), the attribute -specifies the channels that the event should be delivered -to as a tuple. This overrides the default behavior -of sending the event to the firing component’s channel.

    -

    When an event is fired, the value in this attribute -is replaced for the instance with the channels that -the event is actually sent to. This information may be used -e.g. when the event is passed as a parameter to a handler.

    -
  • -
  • value – this is a circuits.core.values.Value -object that holds the results returned by the handlers invoked -for the event.
  • -
  • success – if this optional attribute is set to -True, an associated event EventSuccess (original name -with “Success” appended) will automatically be fired when all -handlers for the event have been invoked successfully.
  • -
  • success_channels – the success event is, by default, delivered -to same channels as the successfully dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
  • complete – if this optional attribute is set to -True, an associated event EventComplete (original name -with “Complete” appended) will automatically be fired when all -handlers for the event and all events fired by these handlers -(recursively) have been invoked successfully.
  • -
  • success_channels – the complete event is, by default, delivered -to same channels as the initially dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
-
-
- -
-
-class circuits.io.events.Write(*args, **kwargs)
-

Bases: circuits.core.events.Event

-

Write Event

-

An Event is a message send to one or more channels. It is eventually -dispatched to all components that have handlers for one -of the channels and the event type.

-

All normal arguments and keyword arguments passed to the constructor -of an event are passed on to the handler. When declaring a -handler, its argument list must therefore match the arguments -used for creating the event.

-

Every event has a name attribute that is used for matching -the event with the handlers. By default, the name is the uncameled -class name of the event.

- --- - - - -
Variables:
    -
  • channels

    an optional attribute that may be set before firing -the event. If defined (usually as a class variable), the attribute -specifies the channels that the event should be delivered -to as a tuple. This overrides the default behavior -of sending the event to the firing component’s channel.

    -

    When an event is fired, the value in this attribute -is replaced for the instance with the channels that -the event is actually sent to. This information may be used -e.g. when the event is passed as a parameter to a handler.

    -
  • -
  • value – this is a circuits.core.values.Value -object that holds the results returned by the handlers invoked -for the event.
  • -
  • success – if this optional attribute is set to -True, an associated event EventSuccess (original name -with “Success” appended) will automatically be fired when all -handlers for the event have been invoked successfully.
  • -
  • success_channels – the success event is, by default, delivered -to same channels as the successfully dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
  • complete – if this optional attribute is set to -True, an associated event EventComplete (original name -with “Complete” appended) will automatically be fired when all -handlers for the event and all events fired by these handlers -(recursively) have been invoked successfully.
  • -
  • success_channels – the complete event is, by default, delivered -to same channels as the initially dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
-
-
- -
-
-

Components

-

none

-
-
-

Functions

-

none

-
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/api/circuits_io_file.html circuits-3.1.0+ds1/docs/build/html/api/circuits_io_file.html --- circuits-2.1.0/docs/build/html/api/circuits_io_file.html 2013-02-27 11:27:57.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/api/circuits_io_file.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,208 +0,0 @@ - - - - - - - - - circuits.io.file – File I/O — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

circuits.io.file – File I/O

-
-

Events

-

none

-
-
-

Components

-
-
-class circuits.io.file.File(*args, **kwargs)
-

Bases: circuits.core.components.Component

-

initializes x; see x.__class__.__doc__ for signature

-
- -
-
-

Functions

-

none

-
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/api/circuits_io.html circuits-3.1.0+ds1/docs/build/html/api/circuits_io.html --- circuits-2.1.0/docs/build/html/api/circuits_io.html 2013-02-27 11:27:56.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/api/circuits_io.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,190 +0,0 @@ - - - - - - - - - circuits.io – I/O Support — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

circuits.io – I/O Support

-

I/O Support

-

This package contains various I/O Components. Provided are a a generic File -Component, StdIn, StdOut and StdErr components. Instances of StdIn, StdOUt -and StdErr are also created by importing this package.

- -
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/api/circuits_io_notify.html circuits-3.1.0+ds1/docs/build/html/api/circuits_io_notify.html --- circuits-2.1.0/docs/build/html/api/circuits_io_notify.html 2013-02-27 11:27:57.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/api/circuits_io_notify.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,661 +0,0 @@ - - - - - - - - - circuits.io.notify – File System Notification — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

circuits.io.notify – File System Notification

-
-

Events

-
-
-class circuits.io.notify.Accessed(*args, **kwargs)
-

Bases: circuits.core.events.Event

-

Accessed Event

-

An Event is a message send to one or more channels. It is eventually -dispatched to all components that have handlers for one -of the channels and the event type.

-

All normal arguments and keyword arguments passed to the constructor -of an event are passed on to the handler. When declaring a -handler, its argument list must therefore match the arguments -used for creating the event.

-

Every event has a name attribute that is used for matching -the event with the handlers. By default, the name is the uncameled -class name of the event.

- --- - - - -
Variables:
    -
  • channels

    an optional attribute that may be set before firing -the event. If defined (usually as a class variable), the attribute -specifies the channels that the event should be delivered -to as a tuple. This overrides the default behavior -of sending the event to the firing component’s channel.

    -

    When an event is fired, the value in this attribute -is replaced for the instance with the channels that -the event is actually sent to. This information may be used -e.g. when the event is passed as a parameter to a handler.

    -
  • -
  • value – this is a circuits.core.values.Value -object that holds the results returned by the handlers invoked -for the event.
  • -
  • success – if this optional attribute is set to -True, an associated event EventSuccess (original name -with “Success” appended) will automatically be fired when all -handlers for the event have been invoked successfully.
  • -
  • success_channels – the success event is, by default, delivered -to same channels as the successfully dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
  • complete – if this optional attribute is set to -True, an associated event EventComplete (original name -with “Complete” appended) will automatically be fired when all -handlers for the event and all events fired by these handlers -(recursively) have been invoked successfully.
  • -
  • success_channels – the complete event is, by default, delivered -to same channels as the initially dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
-
-
- -
-
-class circuits.io.notify.Closed(*args, **kwargs)
-

Bases: circuits.core.events.Event

-

Closed Event

-

An Event is a message send to one or more channels. It is eventually -dispatched to all components that have handlers for one -of the channels and the event type.

-

All normal arguments and keyword arguments passed to the constructor -of an event are passed on to the handler. When declaring a -handler, its argument list must therefore match the arguments -used for creating the event.

-

Every event has a name attribute that is used for matching -the event with the handlers. By default, the name is the uncameled -class name of the event.

- --- - - - -
Variables:
    -
  • channels

    an optional attribute that may be set before firing -the event. If defined (usually as a class variable), the attribute -specifies the channels that the event should be delivered -to as a tuple. This overrides the default behavior -of sending the event to the firing component’s channel.

    -

    When an event is fired, the value in this attribute -is replaced for the instance with the channels that -the event is actually sent to. This information may be used -e.g. when the event is passed as a parameter to a handler.

    -
  • -
  • value – this is a circuits.core.values.Value -object that holds the results returned by the handlers invoked -for the event.
  • -
  • success – if this optional attribute is set to -True, an associated event EventSuccess (original name -with “Success” appended) will automatically be fired when all -handlers for the event have been invoked successfully.
  • -
  • success_channels – the success event is, by default, delivered -to same channels as the successfully dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
  • complete – if this optional attribute is set to -True, an associated event EventComplete (original name -with “Complete” appended) will automatically be fired when all -handlers for the event and all events fired by these handlers -(recursively) have been invoked successfully.
  • -
  • success_channels – the complete event is, by default, delivered -to same channels as the initially dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
-
-
- -
-
-class circuits.io.notify.Created(*args, **kwargs)
-

Bases: circuits.core.events.Event

-

Created Event

-

An Event is a message send to one or more channels. It is eventually -dispatched to all components that have handlers for one -of the channels and the event type.

-

All normal arguments and keyword arguments passed to the constructor -of an event are passed on to the handler. When declaring a -handler, its argument list must therefore match the arguments -used for creating the event.

-

Every event has a name attribute that is used for matching -the event with the handlers. By default, the name is the uncameled -class name of the event.

- --- - - - -
Variables:
    -
  • channels

    an optional attribute that may be set before firing -the event. If defined (usually as a class variable), the attribute -specifies the channels that the event should be delivered -to as a tuple. This overrides the default behavior -of sending the event to the firing component’s channel.

    -

    When an event is fired, the value in this attribute -is replaced for the instance with the channels that -the event is actually sent to. This information may be used -e.g. when the event is passed as a parameter to a handler.

    -
  • -
  • value – this is a circuits.core.values.Value -object that holds the results returned by the handlers invoked -for the event.
  • -
  • success – if this optional attribute is set to -True, an associated event EventSuccess (original name -with “Success” appended) will automatically be fired when all -handlers for the event have been invoked successfully.
  • -
  • success_channels – the success event is, by default, delivered -to same channels as the successfully dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
  • complete – if this optional attribute is set to -True, an associated event EventComplete (original name -with “Complete” appended) will automatically be fired when all -handlers for the event and all events fired by these handlers -(recursively) have been invoked successfully.
  • -
  • success_channels – the complete event is, by default, delivered -to same channels as the initially dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
-
-
- -
-
-class circuits.io.notify.Deleted(*args, **kwargs)
-

Bases: circuits.core.events.Event

-

Deleted Event

-

An Event is a message send to one or more channels. It is eventually -dispatched to all components that have handlers for one -of the channels and the event type.

-

All normal arguments and keyword arguments passed to the constructor -of an event are passed on to the handler. When declaring a -handler, its argument list must therefore match the arguments -used for creating the event.

-

Every event has a name attribute that is used for matching -the event with the handlers. By default, the name is the uncameled -class name of the event.

- --- - - - -
Variables:
    -
  • channels

    an optional attribute that may be set before firing -the event. If defined (usually as a class variable), the attribute -specifies the channels that the event should be delivered -to as a tuple. This overrides the default behavior -of sending the event to the firing component’s channel.

    -

    When an event is fired, the value in this attribute -is replaced for the instance with the channels that -the event is actually sent to. This information may be used -e.g. when the event is passed as a parameter to a handler.

    -
  • -
  • value – this is a circuits.core.values.Value -object that holds the results returned by the handlers invoked -for the event.
  • -
  • success – if this optional attribute is set to -True, an associated event EventSuccess (original name -with “Success” appended) will automatically be fired when all -handlers for the event have been invoked successfully.
  • -
  • success_channels – the success event is, by default, delivered -to same channels as the successfully dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
  • complete – if this optional attribute is set to -True, an associated event EventComplete (original name -with “Complete” appended) will automatically be fired when all -handlers for the event and all events fired by these handlers -(recursively) have been invoked successfully.
  • -
  • success_channels – the complete event is, by default, delivered -to same channels as the initially dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
-
-
- -
-
-class circuits.io.notify.Modified(*args, **kwargs)
-

Bases: circuits.core.events.Event

-

Modified Event

-

An Event is a message send to one or more channels. It is eventually -dispatched to all components that have handlers for one -of the channels and the event type.

-

All normal arguments and keyword arguments passed to the constructor -of an event are passed on to the handler. When declaring a -handler, its argument list must therefore match the arguments -used for creating the event.

-

Every event has a name attribute that is used for matching -the event with the handlers. By default, the name is the uncameled -class name of the event.

- --- - - - -
Variables:
    -
  • channels

    an optional attribute that may be set before firing -the event. If defined (usually as a class variable), the attribute -specifies the channels that the event should be delivered -to as a tuple. This overrides the default behavior -of sending the event to the firing component’s channel.

    -

    When an event is fired, the value in this attribute -is replaced for the instance with the channels that -the event is actually sent to. This information may be used -e.g. when the event is passed as a parameter to a handler.

    -
  • -
  • value – this is a circuits.core.values.Value -object that holds the results returned by the handlers invoked -for the event.
  • -
  • success – if this optional attribute is set to -True, an associated event EventSuccess (original name -with “Success” appended) will automatically be fired when all -handlers for the event have been invoked successfully.
  • -
  • success_channels – the success event is, by default, delivered -to same channels as the successfully dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
  • complete – if this optional attribute is set to -True, an associated event EventComplete (original name -with “Complete” appended) will automatically be fired when all -handlers for the event and all events fired by these handlers -(recursively) have been invoked successfully.
  • -
  • success_channels – the complete event is, by default, delivered -to same channels as the initially dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
-
-
- -
-
-class circuits.io.notify.Moved(*args, **kwargs)
-

Bases: circuits.core.events.Event

-

Moved Event

-

An Event is a message send to one or more channels. It is eventually -dispatched to all components that have handlers for one -of the channels and the event type.

-

All normal arguments and keyword arguments passed to the constructor -of an event are passed on to the handler. When declaring a -handler, its argument list must therefore match the arguments -used for creating the event.

-

Every event has a name attribute that is used for matching -the event with the handlers. By default, the name is the uncameled -class name of the event.

- --- - - - -
Variables:
    -
  • channels

    an optional attribute that may be set before firing -the event. If defined (usually as a class variable), the attribute -specifies the channels that the event should be delivered -to as a tuple. This overrides the default behavior -of sending the event to the firing component’s channel.

    -

    When an event is fired, the value in this attribute -is replaced for the instance with the channels that -the event is actually sent to. This information may be used -e.g. when the event is passed as a parameter to a handler.

    -
  • -
  • value – this is a circuits.core.values.Value -object that holds the results returned by the handlers invoked -for the event.
  • -
  • success – if this optional attribute is set to -True, an associated event EventSuccess (original name -with “Success” appended) will automatically be fired when all -handlers for the event have been invoked successfully.
  • -
  • success_channels – the success event is, by default, delivered -to same channels as the successfully dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
  • complete – if this optional attribute is set to -True, an associated event EventComplete (original name -with “Complete” appended) will automatically be fired when all -handlers for the event and all events fired by these handlers -(recursively) have been invoked successfully.
  • -
  • success_channels – the complete event is, by default, delivered -to same channels as the initially dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
-
-
- -
-
-class circuits.io.notify.Opened(*args, **kwargs)
-

Bases: circuits.core.events.Event

-

Opened Event

-

An Event is a message send to one or more channels. It is eventually -dispatched to all components that have handlers for one -of the channels and the event type.

-

All normal arguments and keyword arguments passed to the constructor -of an event are passed on to the handler. When declaring a -handler, its argument list must therefore match the arguments -used for creating the event.

-

Every event has a name attribute that is used for matching -the event with the handlers. By default, the name is the uncameled -class name of the event.

- --- - - - -
Variables:
    -
  • channels

    an optional attribute that may be set before firing -the event. If defined (usually as a class variable), the attribute -specifies the channels that the event should be delivered -to as a tuple. This overrides the default behavior -of sending the event to the firing component’s channel.

    -

    When an event is fired, the value in this attribute -is replaced for the instance with the channels that -the event is actually sent to. This information may be used -e.g. when the event is passed as a parameter to a handler.

    -
  • -
  • value – this is a circuits.core.values.Value -object that holds the results returned by the handlers invoked -for the event.
  • -
  • success – if this optional attribute is set to -True, an associated event EventSuccess (original name -with “Success” appended) will automatically be fired when all -handlers for the event have been invoked successfully.
  • -
  • success_channels – the success event is, by default, delivered -to same channels as the successfully dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
  • complete – if this optional attribute is set to -True, an associated event EventComplete (original name -with “Complete” appended) will automatically be fired when all -handlers for the event and all events fired by these handlers -(recursively) have been invoked successfully.
  • -
  • success_channels – the complete event is, by default, delivered -to same channels as the initially dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
-
-
- -
-
-class circuits.io.notify.Unmounted(*args, **kwargs)
-

Bases: circuits.core.events.Event

-

Unmounted Event

-

An Event is a message send to one or more channels. It is eventually -dispatched to all components that have handlers for one -of the channels and the event type.

-

All normal arguments and keyword arguments passed to the constructor -of an event are passed on to the handler. When declaring a -handler, its argument list must therefore match the arguments -used for creating the event.

-

Every event has a name attribute that is used for matching -the event with the handlers. By default, the name is the uncameled -class name of the event.

- --- - - - -
Variables:
    -
  • channels

    an optional attribute that may be set before firing -the event. If defined (usually as a class variable), the attribute -specifies the channels that the event should be delivered -to as a tuple. This overrides the default behavior -of sending the event to the firing component’s channel.

    -

    When an event is fired, the value in this attribute -is replaced for the instance with the channels that -the event is actually sent to. This information may be used -e.g. when the event is passed as a parameter to a handler.

    -
  • -
  • value – this is a circuits.core.values.Value -object that holds the results returned by the handlers invoked -for the event.
  • -
  • success – if this optional attribute is set to -True, an associated event EventSuccess (original name -with “Success” appended) will automatically be fired when all -handlers for the event have been invoked successfully.
  • -
  • success_channels – the success event is, by default, delivered -to same channels as the successfully dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
  • complete – if this optional attribute is set to -True, an associated event EventComplete (original name -with “Complete” appended) will automatically be fired when all -handlers for the event and all events fired by these handlers -(recursively) have been invoked successfully.
  • -
  • success_channels – the complete event is, by default, delivered -to same channels as the initially dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
-
-
- -
-
-

Components

-
-
-class circuits.io.notify.Notify(channel='notify')
-

Bases: circuits.core.components.Component

-
- -
-
-

Functions

-
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/api/circuits_io_serial.html circuits-3.1.0+ds1/docs/build/html/api/circuits_io_serial.html --- circuits-2.1.0/docs/build/html/api/circuits_io_serial.html 2013-02-27 11:27:57.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/api/circuits_io_serial.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,207 +0,0 @@ - - - - - - - - - circuits.io.serial – Serial I/O — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

circuits.io.serial – Serial I/O

-
-

Events

-

none

-
-
-

Components

-
-
-class circuits.io.serial.Serial(port, baudrate=115200, bufsize=4096, timeout=0.20000000000000001, channel='serial')
-

Bases: circuits.core.components.Component

-
- -
-
-

Functions

-

none

-
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/api/circuits_net.html circuits-3.1.0+ds1/docs/build/html/api/circuits_net.html --- circuits-2.1.0/docs/build/html/api/circuits_net.html 2013-02-27 11:27:57.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/api/circuits_net.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,200 +0,0 @@ - - - - - - - - - circuits.net – Networking — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

circuits.net – Networking

-

Networking Components

-

This package contains components that implement network sockets and -protocols for implementing client and server network applications.

- --- - - - - - -
copyright:CopyRight (C) 2004-2012 by James Mills
license:MIT (See: LICENSE)
- -
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/api/circuits_net_protocols.html circuits-3.1.0+ds1/docs/build/html/api/circuits_net_protocols.html --- circuits-2.1.0/docs/build/html/api/circuits_net_protocols.html 2013-02-27 11:27:57.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/api/circuits_net_protocols.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,189 +0,0 @@ - - - - - - - - - circuits.net.protocols – Networking Protocols — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

circuits.net.protocols – Networking Protocols

-

Networking Protocols

-

This package contains components that implement various networking protocols.

- -
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/api/circuits_net_protocols_http.html circuits-3.1.0+ds1/docs/build/html/api/circuits_net_protocols_http.html --- circuits-2.1.0/docs/build/html/api/circuits_net_protocols_http.html 2013-02-27 11:27:57.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/api/circuits_net_protocols_http.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,319 +0,0 @@ - - - - - - - - - circuits.net.protocols.http – HTTP Protocol — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

circuits.net.protocols.http – HTTP Protocol

-
-

Events

-
-
-class circuits.net.protocols.http.Request(*args, **kwargs)
-

Bases: circuits.core.events.Event

-

Request Event

-

An Event is a message send to one or more channels. It is eventually -dispatched to all components that have handlers for one -of the channels and the event type.

-

All normal arguments and keyword arguments passed to the constructor -of an event are passed on to the handler. When declaring a -handler, its argument list must therefore match the arguments -used for creating the event.

-

Every event has a name attribute that is used for matching -the event with the handlers. By default, the name is the uncameled -class name of the event.

- --- - - - -
Variables:
    -
  • channels

    an optional attribute that may be set before firing -the event. If defined (usually as a class variable), the attribute -specifies the channels that the event should be delivered -to as a tuple. This overrides the default behavior -of sending the event to the firing component’s channel.

    -

    When an event is fired, the value in this attribute -is replaced for the instance with the channels that -the event is actually sent to. This information may be used -e.g. when the event is passed as a parameter to a handler.

    -
  • -
  • value – this is a circuits.core.values.Value -object that holds the results returned by the handlers invoked -for the event.
  • -
  • success – if this optional attribute is set to -True, an associated event EventSuccess (original name -with “Success” appended) will automatically be fired when all -handlers for the event have been invoked successfully.
  • -
  • success_channels – the success event is, by default, delivered -to same channels as the successfully dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
  • complete – if this optional attribute is set to -True, an associated event EventComplete (original name -with “Complete” appended) will automatically be fired when all -handlers for the event and all events fired by these handlers -(recursively) have been invoked successfully.
  • -
  • success_channels – the complete event is, by default, delivered -to same channels as the initially dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
-
-
- -
-
-class circuits.net.protocols.http.Response(*args, **kwargs)
-

Bases: circuits.core.events.Event

-

Response Event

-

An Event is a message send to one or more channels. It is eventually -dispatched to all components that have handlers for one -of the channels and the event type.

-

All normal arguments and keyword arguments passed to the constructor -of an event are passed on to the handler. When declaring a -handler, its argument list must therefore match the arguments -used for creating the event.

-

Every event has a name attribute that is used for matching -the event with the handlers. By default, the name is the uncameled -class name of the event.

- --- - - - -
Variables:
    -
  • channels

    an optional attribute that may be set before firing -the event. If defined (usually as a class variable), the attribute -specifies the channels that the event should be delivered -to as a tuple. This overrides the default behavior -of sending the event to the firing component’s channel.

    -

    When an event is fired, the value in this attribute -is replaced for the instance with the channels that -the event is actually sent to. This information may be used -e.g. when the event is passed as a parameter to a handler.

    -
  • -
  • value – this is a circuits.core.values.Value -object that holds the results returned by the handlers invoked -for the event.
  • -
  • success – if this optional attribute is set to -True, an associated event EventSuccess (original name -with “Success” appended) will automatically be fired when all -handlers for the event have been invoked successfully.
  • -
  • success_channels – the success event is, by default, delivered -to same channels as the successfully dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
  • complete – if this optional attribute is set to -True, an associated event EventComplete (original name -with “Complete” appended) will automatically be fired when all -handlers for the event and all events fired by these handlers -(recursively) have been invoked successfully.
  • -
  • success_channels – the complete event is, by default, delivered -to same channels as the initially dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
-
-
- -
-
-

Components

-
-
-class circuits.net.protocols.http.HTTP(encoding='utf-8', channel='web')
-

Bases: circuits.core.components.BaseComponent

-
- -
-
-

Functions

-
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/api/circuits_net_protocols_irc.html circuits-3.1.0+ds1/docs/build/html/api/circuits_net_protocols_irc.html --- circuits-2.1.0/docs/build/html/api/circuits_net_protocols_irc.html 2013-02-27 11:27:57.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/api/circuits_net_protocols_irc.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,232 +0,0 @@ - - - - - - - - - circuits.net.protocols.irc – IRC Protocol — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

circuits.net.protocols.irc – IRC Protocol

-
-

Events

-
-
-class circuits.net.protocols.irc.RAW(*args, **kwargs)
-

Bases: circuits.net.protocols.irc.Command

-

RAW command

-
- -
-
-

Components

-
-
-class circuits.net.protocols.irc.IRC(*args, **kwargs)
-

Bases: circuits.core.components.Component

-

IRC Protocol Component

-

Creates a new IRC Component instance that implements the IRC Protocol. -Incoming messages are handled by the “read” Event Handler, parsed and -processed with appropriate Events created and exposed to the rest of -te system to listen to and handle.

-
-
@note: This Component must be used in conjunction with a Component that
-
exposes Read Events on a “read” Channel.
-
-
-
-line(line)
-

Line Event Handler

-

Process a line of text and generate the appropiate -event. This must not be overridden by sub-classes, -if it is, this must be explitetly called by the -sub-class. Other Components may however listen to -this event and process custom IRC events.

-
- -
- -
-
-

Functions

-
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/api/circuits_net_protocols_line.html circuits-3.1.0+ds1/docs/build/html/api/circuits_net_protocols_line.html --- circuits-2.1.0/docs/build/html/api/circuits_net_protocols_line.html 2013-02-27 11:27:57.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/api/circuits_net_protocols_line.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,316 +0,0 @@ - - - - - - - - - circuits.net.protocols.line – Line Protocol — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

circuits.net.protocols.line – Line Protocol

-
-

Events

-
-
-class circuits.net.protocols.line.Line(*args, **kwargs)
-

Bases: circuits.core.events.Event

-

Line Event

-

An Event is a message send to one or more channels. It is eventually -dispatched to all components that have handlers for one -of the channels and the event type.

-

All normal arguments and keyword arguments passed to the constructor -of an event are passed on to the handler. When declaring a -handler, its argument list must therefore match the arguments -used for creating the event.

-

Every event has a name attribute that is used for matching -the event with the handlers. By default, the name is the uncameled -class name of the event.

- --- - - - -
Variables:
    -
  • channels

    an optional attribute that may be set before firing -the event. If defined (usually as a class variable), the attribute -specifies the channels that the event should be delivered -to as a tuple. This overrides the default behavior -of sending the event to the firing component’s channel.

    -

    When an event is fired, the value in this attribute -is replaced for the instance with the channels that -the event is actually sent to. This information may be used -e.g. when the event is passed as a parameter to a handler.

    -
  • -
  • value – this is a circuits.core.values.Value -object that holds the results returned by the handlers invoked -for the event.
  • -
  • success – if this optional attribute is set to -True, an associated event EventSuccess (original name -with “Success” appended) will automatically be fired when all -handlers for the event have been invoked successfully.
  • -
  • success_channels – the success event is, by default, delivered -to same channels as the successfully dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
  • complete – if this optional attribute is set to -True, an associated event EventComplete (original name -with “Complete” appended) will automatically be fired when all -handlers for the event and all events fired by these handlers -(recursively) have been invoked successfully.
  • -
  • success_channels – the complete event is, by default, delivered -to same channels as the initially dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
-
-
- -
-
-

Components

-
-
-class circuits.net.protocols.line.LP(*args, **kwargs)
-

Bases: circuits.core.components.BaseComponent

-

Line Protocol

-

Implements the Line Protocol.

-

Incoming data is split into lines with a splitter function. For each -line of data processed a Line Event is created. Any unfinished lines -are appended into an internal buffer.

-

A custom line splitter function can be passed to customize how data -is split into lines. This function must accept two arguments, the data -to process and any left over data from a previous invocation of the -splitter function. The function must also return a tiple of two items, -a list of lines and any left over data.

- --- - - - -
Parameters:splitter (function) – a line splitter function
-

This Component operates in two modes. In normal operation it’s expected -to be used in conjunction with components that expose a Read Event on -a “read” channel with only one argument (data). Some builtin components -that expose such events are: -- circuits.net.sockets.TCPClient -- circuits.io.File

-

The second mode of operation works with circuits.net.sockets.Server -components such as TCPServer, UNIXServer, etc. It’s expected that -two arguments exist in the Read Event, sock and data. The following -two arguments can be passed to affect how unfinished data is stored -and retrieved for such components:

- --- - - - -
Parameters:getBuffer (function) – function to retrieve the buffer for a client sock
-

This function must accept one argument (sock,) the client socket -whoose buffer is to be retrieved.

- --- - - - -
Parameters:updateBuffer (function) – function to update the buffer for a client sock
-

This function must accept two arguments (sock, buffer,) the client -socket and the left over buffer to be updated.

-
-
@note: This Component must be used in conjunction with a Component that
-
exposes Read events on a “read” Channel.
-
-

initializes x; see x.__class__.__doc__ for signature

-
- -
-
-

Functions

-
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/api/circuits_net_sockets.html circuits-3.1.0+ds1/docs/build/html/api/circuits_net_sockets.html --- circuits-2.1.0/docs/build/html/api/circuits_net_sockets.html 2013-02-27 11:27:58.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/api/circuits_net_sockets.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,520 +0,0 @@ - - - - - - - - - circuits.net.sockets – Socket Components — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

circuits.net.sockets – Socket Components

-
-

Events

-
-
-class circuits.net.sockets.Connect(*args, **kwargs)
-

Bases: circuits.core.events.Event

-

Connect Event

-

This Event is sent when a new client connection has arrived on a server. -This event is also used for client’s to initiate a new connection to -a remote host.

-
-

Note

-

This event is used for both Client and Server Components.

-
- --- - - - -
Parameters:
    -
  • args (tuple) – Client: (host, port) Server: (sock, host, port)
  • -
  • kwargs (dict) – Client: (ssl)
  • -
-
-
- -
-
-class circuits.net.sockets.Connected(host, port)
-

Bases: circuits.core.events.Event

-

Connected Event

-

This Event is sent when a client has successfully connected.

-

@note: This event is for Client Components.

- --- - - - -
Parameters:
    -
  • host – The hostname connected to.
  • -
  • port – The port connected to
  • -
-
-
- -
-
-class circuits.net.sockets.Close(*args)
-

Bases: circuits.core.events.Event

-

Close Event

-

This Event is used to notify a client, client connection or server that -we want to close.

-

@note: This event is never sent, it is used to close. -@note: This event is used for both Client and Server Components.

- --- - - - -
Parameters:args – Client: () Server: (sock)
-
- -
-
-class circuits.net.sockets.Closed
-

Bases: circuits.core.events.Event

-

Closed Event

-

This Event is sent when a server has closed its listening socket.

-

@note: This event is for Server components.

-
- -
-
-class circuits.net.sockets.Read(*args)
-

Bases: circuits.core.events.Event

-

Read Event

-

This Event is sent when a client or server connection has read any data.

-

@note: This event is used for both Client and Server Components.

- --- - - - -
Parameters:args – Client: (data) Server: (sock, data)
-
- -
-
-class circuits.net.sockets.Write(*args)
-

Bases: circuits.core.events.Event

-

Write Event

-

This Event is used to notify a client, client connection or server that -we have data to be written.

-

@note: This event is never sent, it is used to send data. -@note: This event is used for both Client and Server Components.

- --- - - - -
Parameters:args – Client: (data) Server: (sock, data)
-
- -
-
-class circuits.net.sockets.SocketError(*args)
-

Bases: circuits.core.events.Event

-

SocketError Event

-

This Event is sent when a client or server connection has an error.

-

@note: This event is used for both Client and Server Components.

- --- - - - -
Parameters:args – Client: (error) Server: (sock, error)
-
- -
-
-class circuits.net.sockets.Disconnect(*args)
-

Bases: circuits.core.events.Event

-

Disconnect Event

-

This Event is sent when a client connection has closed on a server. -This event is also used for client’s to disconnect from a remote host.

-

@note: This event is used for both Client and Server Components.

- --- - - - -
Parameters:args – Client: () Server: (sock)
-
- -
-
-class circuits.net.sockets.Disconnected
-

Bases: circuits.core.events.Event

-

Disconnected Event

-

This Event is sent when a client has disconnected

-

@note: This event is for Client Components.

-
- -
-
-

Components

-
-
-class circuits.net.sockets.Client(bind=None, bufsize=4096, channel='client')
-

Bases: circuits.core.components.BaseComponent

-
-
-channel = 'client'
-
- -
-
-parse_bind_parameter(bind_parameter)
-
- -
-
-connected
-
- -
-
-close()
-
- -
-
-write(data)
-
- -
- -
-
-class circuits.net.sockets.TCPClient(bind=None, bufsize=4096, channel='client')
-

Bases: circuits.net.sockets.Client

-
-
-socket_family = 2
-
- -
-
-connect(host, port, secure=False, **kwargs)
-
- -
- -
-
-circuits.net.sockets.UDPClient
-

alias of UDPServer

-
- -
-
-class circuits.net.sockets.UNIXClient(bind=None, bufsize=4096, channel='client')
-

Bases: circuits.net.sockets.Client

-
-
-ready(component)
-
- -
-
-connect(path, secure=False, **kwargs)
-
- -
- -
-
-class circuits.net.sockets.Server(bind, secure=False, backlog=5000, bufsize=4096, channel='server', **kwargs)
-

Bases: circuits.core.components.BaseComponent

-
-
-channel = 'server'
-
- -
-
-parse_bind_parameter(bind_parameter)
-
- -
-
-connected
-
- -
-
-host
-
- -
-
-port
-
- -
-
-close(sock=None)
-
- -
-
-write(sock, data)
-
- -
- -
-
-class circuits.net.sockets.TCPServer(bind, secure=False, backlog=5000, bufsize=4096, channel='server', **kwargs)
-

Bases: circuits.net.sockets.Server

-
-
-socket_family = 2
-
- -
-
-parse_bind_parameter(bind_parameter)
-
- -
- -
-
-class circuits.net.sockets.UDPServer(bind, secure=False, backlog=5000, bufsize=4096, channel='server', **kwargs)
-

Bases: circuits.net.sockets.Server

-
-
-socket_family = 2
-
- -
-
-close()
-
- -
-
-write(address, data)
-
- -
-
-broadcast(data, port)
-
- -
- -
-
-class circuits.net.sockets.UNIXServer(bind, secure=False, backlog=5000, bufsize=4096, channel='server', **kwargs)
-

Bases: circuits.net.sockets.Server

-
- -
-
-

Functions

-
-
-circuits.net.sockets.Pipe(*channels, **kwargs)
-

Create a new full duplex Pipe

-

Returns a pair of UNIXClient instances connected on either side of -the pipe.

-
- -
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/api/circuits_node_client.html circuits-3.1.0+ds1/docs/build/html/api/circuits_node_client.html --- circuits-2.1.0/docs/build/html/api/circuits_node_client.html 2013-02-27 11:27:58.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/api/circuits_node_client.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,211 +0,0 @@ - - - - - - - - - circuits.node.client – Client — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

circuits.node.client – Client

-

Client

-

...

-
-

Events

-

none

-
-
-

Components

-
-
-class circuits.node.client.Client(host, port, channel='node')
-

Bases: circuits.core.components.BaseComponent

-

Client

-

...

-
- -
-
-

Functions

-

none

-
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/api/circuits_node_events.html circuits-3.1.0+ds1/docs/build/html/api/circuits_node_events.html --- circuits-2.1.0/docs/build/html/api/circuits_node_events.html 2013-02-27 11:27:58.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/api/circuits_node_events.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,268 +0,0 @@ - - - - - - - - - circuits.node.events – Events — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

circuits.node.events – Events

-

Events

-

...

-
-

Events

-
-
-class circuits.node.events.Packet(*args, **kwargs)
-

Bases: circuits.core.events.Event

-

Packet Event

-

An Event is a message send to one or more channels. It is eventually -dispatched to all components that have handlers for one -of the channels and the event type.

-

All normal arguments and keyword arguments passed to the constructor -of an event are passed on to the handler. When declaring a -handler, its argument list must therefore match the arguments -used for creating the event.

-

Every event has a name attribute that is used for matching -the event with the handlers. By default, the name is the uncameled -class name of the event.

- --- - - - -
Variables:
    -
  • channels

    an optional attribute that may be set before firing -the event. If defined (usually as a class variable), the attribute -specifies the channels that the event should be delivered -to as a tuple. This overrides the default behavior -of sending the event to the firing component’s channel.

    -

    When an event is fired, the value in this attribute -is replaced for the instance with the channels that -the event is actually sent to. This information may be used -e.g. when the event is passed as a parameter to a handler.

    -
  • -
  • value – this is a circuits.core.values.Value -object that holds the results returned by the handlers invoked -for the event.
  • -
  • success – if this optional attribute is set to -True, an associated event EventSuccess (original name -with “Success” appended) will automatically be fired when all -handlers for the event have been invoked successfully.
  • -
  • success_channels – the success event is, by default, delivered -to same channels as the successfully dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
  • complete – if this optional attribute is set to -True, an associated event EventComplete (original name -with “Complete” appended) will automatically be fired when all -handlers for the event and all events fired by these handlers -(recursively) have been invoked successfully.
  • -
  • success_channels – the complete event is, by default, delivered -to same channels as the initially dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
-
-
- -
-
-class circuits.node.events.Remote(event, node, channel=None)
-

Bases: circuits.core.events.Event

-

Remote Event

-

...

-
- -
-
-

Components

-

none

-
-
-

Functions

-

none

-
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/api/circuits_node.html circuits-3.1.0+ds1/docs/build/html/api/circuits_node.html --- circuits-2.1.0/docs/build/html/api/circuits_node.html 2013-02-27 11:27:58.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/api/circuits_node.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,189 +0,0 @@ - - - - - - - - - circuits.node – Node — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
- - - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/api/circuits_node_node.html circuits-3.1.0+ds1/docs/build/html/api/circuits_node_node.html --- circuits-2.1.0/docs/build/html/api/circuits_node_node.html 2013-02-27 11:27:58.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/api/circuits_node_node.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,211 +0,0 @@ - - - - - - - - - circuits.node.node – Node — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

circuits.node.node – Node

-

Node

-

...

-
-

Events

-

none

-
-
-

Components

-
-
-class circuits.node.node.Node(bind=None, channel='node')
-

Bases: circuits.core.components.BaseComponent

-

Node

-

...

-
- -
-
-

Functions

-

none

-
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/api/circuits_node_server.html circuits-3.1.0+ds1/docs/build/html/api/circuits_node_server.html --- circuits-2.1.0/docs/build/html/api/circuits_node_server.html 2013-02-27 11:27:58.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/api/circuits_node_server.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,211 +0,0 @@ - - - - - - - - - circuits.node.server – Server — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

circuits.node.server – Server

-

Server

-

...

-
-

Events

-

none

-
-
-

Components

-
-
-class circuits.node.server.Server(bind, channel='node')
-

Bases: circuits.core.components.BaseComponent

-

Server

-

...

-
- -
-
-

Functions

-

none

-
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/api/circuits_node_utils.html circuits-3.1.0+ds1/docs/build/html/api/circuits_node_utils.html --- circuits-2.1.0/docs/build/html/api/circuits_node_utils.html 2013-02-27 11:27:58.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/api/circuits_node_utils.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,223 +0,0 @@ - - - - - - - - - circuits.node.utils – Node Utilities — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

circuits.node.utils – Node Utilities

-

Utils

-

...

-
-

Events

-

none

-
-
-

Components

-

none

-
-
-

Functions

-
-
-circuits.node.utils.dump_event(e, id)
-
- -
-
-circuits.node.utils.dump_value(v)
-
- -
-
-circuits.node.utils.load_event(s)
-
- -
-
-circuits.node.utils.load_value(v)
-
- -
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/api/circuits_tools.html circuits-3.1.0+ds1/docs/build/html/api/circuits_tools.html --- circuits-2.1.0/docs/build/html/api/circuits_tools.html 2013-02-27 11:27:58.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/api/circuits_tools.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,201 +0,0 @@ - - - - - - - - - circuits.tools – Development Tools — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

circuits.tools – Development Tools

-

Often you will end up needing to do some debugging or inspection of -your system. The circuits.tools package provides a set of development -tools for debugging, inspection and analysis.

-
-
-circuits.tools.graph(x, name=None)
-

Display a directed graph of the Component structure of x

- --- - - - -
Parameters:
    -
  • x (Component or Manager) – A Component or Manager to graph
  • -
  • name (str) – A name for the graph (defaults to x’s name)
  • -
-
-

@return: A directed graph representing x’s Component sturcture. -@rtype: str

-
- -
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/api/circuits_web_client.html circuits-3.1.0+ds1/docs/build/html/api/circuits_web_client.html --- circuits-2.1.0/docs/build/html/api/circuits_web_client.html 2013-02-27 11:27:58.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/api/circuits_web_client.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,260 +0,0 @@ - - - - - - - - - circuits.web.client – Client — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

circuits.web.client – Client

-
-

Events

-
-
-class circuits.web.client.Request(method, path, body=None, headers={})
-

Bases: circuits.core.events.Event

-

Request Event

-

This Event is used to initiate a new request.

- --- - - - -
Parameters:
    -
  • method (str) – HTTP Method (PUT, GET, POST, DELETE)
  • -
  • path (str) – Path to resource
  • -
-
-
- -
-
-

Components

-
-
-class circuits.web.client.Client(url, channel='client')
-

Bases: circuits.core.components.BaseComponent

-
-
-channel = 'client'
-
- -
-
-write(data)
-
- -
-
-close()
-
- -
-
-connect(host=None, port=None, secure=None)
-
- -
-
-request(method, path, body=None, headers={})
-
- -
-
-connected
-
- -
-
-response
-
- -
- -
-
-

Functions

-
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/api/circuits_web_constants.html circuits-3.1.0+ds1/docs/build/html/api/circuits_web_constants.html --- circuits-2.1.0/docs/build/html/api/circuits_web_constants.html 2013-02-27 11:27:58.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/api/circuits_web_constants.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,182 +0,0 @@ - - - - - - - - - circuits.web.constants – Global Constants — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

circuits.web.constants – Global Constants

-

Global Constants

-

This module implements required shared global constants.

-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/api/circuits_web_controllers.html circuits-3.1.0+ds1/docs/build/html/api/circuits_web_controllers.html --- circuits-2.1.0/docs/build/html/api/circuits_web_controllers.html 2013-02-27 11:27:58.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/api/circuits_web_controllers.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,226 +0,0 @@ - - - - - - - - - circuits.web.controllers – Controllers — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

circuits.web.controllers – Controllers

-

Controllers

-

This module implements ...

-
-

Events

-

none

-
-
-

Components

-
-
-class circuits.web.controllers.Controller(*args, **kwargs)
-

Bases: circuits.web.controllers.BaseController

-

initializes x; see x.__class__.__doc__ for signature

-
- -
-
-class circuits.web.controllers.JSONController(*args, **kwargs)
-

Bases: circuits.web.controllers.BaseController

-

initializes x; see x.__class__.__doc__ for signature

-
- -
-
-

Functions

-
-
-circuits.web.controllers.expose(*channels, **config)
-
- -
-
-circuits.web.controllers.exposeJSON(*channels, **config)
-
- -
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/api/circuits_web_dispatchers_dispatcher.html circuits-3.1.0+ds1/docs/build/html/api/circuits_web_dispatchers_dispatcher.html --- circuits-2.1.0/docs/build/html/api/circuits_web_dispatchers_dispatcher.html 2013-02-27 11:27:58.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/api/circuits_web_dispatchers_dispatcher.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,207 +0,0 @@ - - - - - - - - - circuits.web.dispatchers.dispatcher – Default Dispatcher — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

circuits.web.dispatchers.dispatcher – Default Dispatcher

-
-

Events

-

none

-
-
-

Components

-
-
-class circuits.web.dispatchers.dispatcher.Dispatcher(**kwargs)
-

Bases: circuits.core.components.BaseComponent

-
- -
-
-

Functions

-

none

-
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/api/circuits_web_dispatchers_jsonrpc.html circuits-3.1.0+ds1/docs/build/html/api/circuits_web_dispatchers_jsonrpc.html --- circuits-2.1.0/docs/build/html/api/circuits_web_dispatchers_jsonrpc.html 2013-02-27 11:27:59.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/api/circuits_web_dispatchers_jsonrpc.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,266 +0,0 @@ - - - - - - - - - circuits.web.dispatchers.jsonrpc – JSON-RPC — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

circuits.web.dispatchers.jsonrpc – JSON-RPC

-

JSON RPC

-

This module implements a JSON RPC dispatcher that translates incoming -RPC calls over JSON into RPC events.

-
-

Events

-
-
-class circuits.web.dispatchers.jsonrpc.RPC(*args, **kwargs)
-

Bases: circuits.core.events.Event

-

RPC Event

-

An Event is a message send to one or more channels. It is eventually -dispatched to all components that have handlers for one -of the channels and the event type.

-

All normal arguments and keyword arguments passed to the constructor -of an event are passed on to the handler. When declaring a -handler, its argument list must therefore match the arguments -used for creating the event.

-

Every event has a name attribute that is used for matching -the event with the handlers. By default, the name is the uncameled -class name of the event.

- --- - - - -
Variables:
    -
  • channels

    an optional attribute that may be set before firing -the event. If defined (usually as a class variable), the attribute -specifies the channels that the event should be delivered -to as a tuple. This overrides the default behavior -of sending the event to the firing component’s channel.

    -

    When an event is fired, the value in this attribute -is replaced for the instance with the channels that -the event is actually sent to. This information may be used -e.g. when the event is passed as a parameter to a handler.

    -
  • -
  • value – this is a circuits.core.values.Value -object that holds the results returned by the handlers invoked -for the event.
  • -
  • success – if this optional attribute is set to -True, an associated event EventSuccess (original name -with “Success” appended) will automatically be fired when all -handlers for the event have been invoked successfully.
  • -
  • success_channels – the success event is, by default, delivered -to same channels as the successfully dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
  • complete – if this optional attribute is set to -True, an associated event EventComplete (original name -with “Complete” appended) will automatically be fired when all -handlers for the event and all events fired by these handlers -(recursively) have been invoked successfully.
  • -
  • success_channels – the complete event is, by default, delivered -to same channels as the initially dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
-
-
- -
-
-

Components

-
-
-class circuits.web.dispatchers.jsonrpc.JSONRPC(path=None, encoding='utf-8', rpc_channel='*')
-

Bases: circuits.core.components.BaseComponent

-
- -
-
-

Functions

-

none

-
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/api/circuits_web_dispatchers_static.html circuits-3.1.0+ds1/docs/build/html/api/circuits_web_dispatchers_static.html --- circuits-2.1.0/docs/build/html/api/circuits_web_dispatchers_static.html 2013-02-27 11:27:59.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/api/circuits_web_dispatchers_static.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,210 +0,0 @@ - - - - - - - - - circuits.web.dispatchers.static – Static — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

circuits.web.dispatchers.static – Static

-

Static

-

This modStatic implements a Static dispatcher used to serve up static -resources and an optional apache-style directory listing.

-
-

Events

-

none

-
-
-

Components

-
-
-class circuits.web.dispatchers.static.Static(path=None, docroot=None, defaults=('index.html', 'index.xhtml'), dirlisting=False)
-

Bases: circuits.core.components.BaseComponent

-
- -
-
-

Functions

-

none

-
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/api/circuits_web_dispatchers_virtualhosts.html circuits-3.1.0+ds1/docs/build/html/api/circuits_web_dispatchers_virtualhosts.html --- circuits-2.1.0/docs/build/html/api/circuits_web_dispatchers_virtualhosts.html 2013-02-27 11:27:59.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/api/circuits_web_dispatchers_virtualhosts.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,232 +0,0 @@ - - - - - - - - - circuits.web.dispatchers.virtualhosts – Virtual Hosts — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

circuits.web.dispatchers.virtualhosts – Virtual Hosts

-

VirtualHost

-

This module implements a virtual host dispatcher that sends requests -for configured virtual hosts to different dispatchers.

-
-

Events

-

none

-
-
-

Components

-
-
-class circuits.web.dispatchers.virtualhosts.VirtualHosts(domains)
-

Bases: circuits.core.components.BaseComponent

-

Forward to anotehr Dispatcher based on the Host header.

-

This can be useful when running multiple sites within one server. -It allows several domains to point to different parts of a single -website structure. For example: -- http://www.domain.example -> / -- http://www.domain2.example -> /domain2 -- http://www.domain2.example:443 -> /secure

- --- - - - -
Parameters:domains (dict) – a dict of {host header value: virtual prefix} pairs.
-

The incoming “Host” request header is looked up in this dict, -and, if a match is found, the corresponding “virtual prefix” -value will be prepended to the URL path before passing the -request onto the next dispatcher.

-

Note that you often need separate entries for “example.com” -and “www.example.com”. In addition, “Host” headers may contain -the port number.

-
- -
-
-

Functions

-

none

-
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/api/circuits_web_dispatchers_websockets.html circuits-3.1.0+ds1/docs/build/html/api/circuits_web_dispatchers_websockets.html --- circuits-2.1.0/docs/build/html/api/circuits_web_dispatchers_websockets.html 2013-02-27 11:27:59.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/api/circuits_web_dispatchers_websockets.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,236 +0,0 @@ - - - - - - - - - circuits.web.dispatchers.websockets – WebSockets — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

circuits.web.dispatchers.websockets – WebSockets

-
-

Events

-
-
-

Components

-
-
-class circuits.web.dispatchers.websockets.WebSockets(path=None, wschannel='ws', *args, **kwargs)
-

Bases: circuits.core.components.BaseComponent

-

This class implements an RFC 6455 compliant WebSockets dispatcher -that handles the WebSockets handshake and upgrades the connection.

-

The dispatcher listens on its channel for Request -events and tries to match them with a given path. Upon a match, -the request is checked for the proper Opening Handshake information. -If successful, the dispatcher confirms the establishment of the -connection to the client. Any subsequent data from the client is -handled as a WebSocket data frame, decoded and fired as -a Read event on the wschannel passed to -the constructor. The data from Write events on -that channel is encoded as data frames and forwarded to the client.

-

Firing a Close event on the wschannel closes the -connection in an orderly fashion (i.e. as specified by the -WebSocket protocol).

- --- - - - -
Parameters:
    -
  • path – the path to handle. Requests that start with this -path are considered to be WebSocket Opening Handshakes.
  • -
  • wschannel – the channel on which Read -events from the client will be delivered and where -Write events to the client will be -sent to.
  • -
-
-
- -
-
-

Functions

-

none

-
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/api/circuits_web_dispatchers_xmlrpc.html circuits-3.1.0+ds1/docs/build/html/api/circuits_web_dispatchers_xmlrpc.html --- circuits-2.1.0/docs/build/html/api/circuits_web_dispatchers_xmlrpc.html 2013-02-27 11:27:59.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/api/circuits_web_dispatchers_xmlrpc.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,266 +0,0 @@ - - - - - - - - - circuits.web.dispatchers.xmlrpc – XML-RPC — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

circuits.web.dispatchers.xmlrpc – XML-RPC

-

XML RPC

-

This module implements a XML RPC dispatcher that translates incoming -RPC calls over XML into RPC events.

-
-

Events

-
-
-class circuits.web.dispatchers.xmlrpc.RPC(*args, **kwargs)
-

Bases: circuits.core.events.Event

-

RPC Event

-

An Event is a message send to one or more channels. It is eventually -dispatched to all components that have handlers for one -of the channels and the event type.

-

All normal arguments and keyword arguments passed to the constructor -of an event are passed on to the handler. When declaring a -handler, its argument list must therefore match the arguments -used for creating the event.

-

Every event has a name attribute that is used for matching -the event with the handlers. By default, the name is the uncameled -class name of the event.

- --- - - - -
Variables:
    -
  • channels

    an optional attribute that may be set before firing -the event. If defined (usually as a class variable), the attribute -specifies the channels that the event should be delivered -to as a tuple. This overrides the default behavior -of sending the event to the firing component’s channel.

    -

    When an event is fired, the value in this attribute -is replaced for the instance with the channels that -the event is actually sent to. This information may be used -e.g. when the event is passed as a parameter to a handler.

    -
  • -
  • value – this is a circuits.core.values.Value -object that holds the results returned by the handlers invoked -for the event.
  • -
  • success – if this optional attribute is set to -True, an associated event EventSuccess (original name -with “Success” appended) will automatically be fired when all -handlers for the event have been invoked successfully.
  • -
  • success_channels – the success event is, by default, delivered -to same channels as the successfully dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
  • complete – if this optional attribute is set to -True, an associated event EventComplete (original name -with “Complete” appended) will automatically be fired when all -handlers for the event and all events fired by these handlers -(recursively) have been invoked successfully.
  • -
  • success_channels – the complete event is, by default, delivered -to same channels as the initially dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
-
-
- -
-
-

Components

-
-
-class circuits.web.dispatchers.xmlrpc.XMLRPC(path=None, encoding='utf-8', rpc_channel='*')
-

Bases: circuits.core.components.BaseComponent

-
- -
-
-

Functions

-

none

-
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/api/circuits_web_errors.html circuits-3.1.0+ds1/docs/build/html/api/circuits_web_errors.html --- circuits-2.1.0/docs/build/html/api/circuits_web_errors.html 2013-02-27 11:27:59.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/api/circuits_web_errors.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,249 +0,0 @@ - - - - - - - - - circuits.web.errors – Errors — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

circuits.web.errors – Errors

-

Errors

-

This module implements a set of standard HTTP Errors.

-
-

Components

-

none

-
-
-

Events

-
-
-class circuits.web.errors.HTTPError(request, response, code=None, **kwargs)
-

Bases: circuits.core.events.Event

-

An event for signaling an HTTP error

-

The constructor creates a new instance and modifies the response -argument to reflect the error.

-
- -
-
-class circuits.web.errors.Forbidden(request, response, code=None, **kwargs)
-

Bases: circuits.web.errors.HTTPError

-

An event for signaling the HTTP Forbidden error

-

The constructor creates a new instance and modifies the response -argument to reflect the error.

-
- -
-
-class circuits.web.errors.NotFound(request, response, code=None, **kwargs)
-

Bases: circuits.web.errors.HTTPError

-

An event for signaling the HTTP Not Fouond error

-

The constructor creates a new instance and modifies the response -argument to reflect the error.

-
- -
-
-class circuits.web.errors.Redirect(request, response, urls, code=None)
-

Bases: circuits.web.errors.HTTPError

-

An event for signaling the HTTP Redirect response

-

The constructor creates a new instance and modifies the -response argument to reflect a redirect response to the -given url.

-
- -
-
-class circuits.web.errors.Unauthorized(request, response, code=None, **kwargs)
-

Bases: circuits.web.errors.HTTPError

-

An event for signaling the HTTP Unauthorized error

-

The constructor creates a new instance and modifies the response -argument to reflect the error.

-
- -
-
-

Functions

-

none

-
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/api/circuits_web_events.html circuits-3.1.0+ds1/docs/build/html/api/circuits_web_events.html --- circuits-2.1.0/docs/build/html/api/circuits_web_events.html 2013-02-27 11:27:59.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/api/circuits_web_events.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,440 +0,0 @@ - - - - - - - - - circuits.web.events – Events — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

circuits.web.events – Events

-
-

Events

-
-
-class circuits.web.events.WebEvent(*args, **kwargs)
-

Bases: circuits.core.events.Event

-

WebEvents have both their success and failure attributes set to -True. So event processing generates the derived events -...Success or ...Failure events.

-

An Event is a message send to one or more channels. It is eventually -dispatched to all components that have handlers for one -of the channels and the event type.

-

All normal arguments and keyword arguments passed to the constructor -of an event are passed on to the handler. When declaring a -handler, its argument list must therefore match the arguments -used for creating the event.

-

Every event has a name attribute that is used for matching -the event with the handlers. By default, the name is the uncameled -class name of the event.

- --- - - - -
Variables:
    -
  • channels

    an optional attribute that may be set before firing -the event. If defined (usually as a class variable), the attribute -specifies the channels that the event should be delivered -to as a tuple. This overrides the default behavior -of sending the event to the firing component’s channel.

    -

    When an event is fired, the value in this attribute -is replaced for the instance with the channels that -the event is actually sent to. This information may be used -e.g. when the event is passed as a parameter to a handler.

    -
  • -
  • value – this is a circuits.core.values.Value -object that holds the results returned by the handlers invoked -for the event.
  • -
  • success – if this optional attribute is set to -True, an associated event EventSuccess (original name -with “Success” appended) will automatically be fired when all -handlers for the event have been invoked successfully.
  • -
  • success_channels – the success event is, by default, delivered -to same channels as the successfully dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
  • complete – if this optional attribute is set to -True, an associated event EventComplete (original name -with “Complete” appended) will automatically be fired when all -handlers for the event and all events fired by these handlers -(recursively) have been invoked successfully.
  • -
  • success_channels – the complete event is, by default, delivered -to same channels as the initially dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
-
-
- -
-
-class circuits.web.events.Request(*args, **kwargs)
-

Bases: circuits.web.events.WebEvent

-

Request(WebEvent) -> Request WebEvent

-

args: request, response

-

An Event is a message send to one or more channels. It is eventually -dispatched to all components that have handlers for one -of the channels and the event type.

-

All normal arguments and keyword arguments passed to the constructor -of an event are passed on to the handler. When declaring a -handler, its argument list must therefore match the arguments -used for creating the event.

-

Every event has a name attribute that is used for matching -the event with the handlers. By default, the name is the uncameled -class name of the event.

- --- - - - -
Variables:
    -
  • channels

    an optional attribute that may be set before firing -the event. If defined (usually as a class variable), the attribute -specifies the channels that the event should be delivered -to as a tuple. This overrides the default behavior -of sending the event to the firing component’s channel.

    -

    When an event is fired, the value in this attribute -is replaced for the instance with the channels that -the event is actually sent to. This information may be used -e.g. when the event is passed as a parameter to a handler.

    -
  • -
  • value – this is a circuits.core.values.Value -object that holds the results returned by the handlers invoked -for the event.
  • -
  • success – if this optional attribute is set to -True, an associated event EventSuccess (original name -with “Success” appended) will automatically be fired when all -handlers for the event have been invoked successfully.
  • -
  • success_channels – the success event is, by default, delivered -to same channels as the successfully dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
  • complete – if this optional attribute is set to -True, an associated event EventComplete (original name -with “Complete” appended) will automatically be fired when all -handlers for the event and all events fired by these handlers -(recursively) have been invoked successfully.
  • -
  • success_channels – the complete event is, by default, delivered -to same channels as the initially dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
-
-
-
-classmethod create(name, *args, **kwargs)
-

All classes derived dynamically from Request are LiteralEvents.

-
- -
- -
-
-class circuits.web.events.Response(*args, **kwargs)
-

Bases: circuits.web.events.WebEvent

-

Response(WebEvent) -> Response WebEvent

-

args: request, response

-

An Event is a message send to one or more channels. It is eventually -dispatched to all components that have handlers for one -of the channels and the event type.

-

All normal arguments and keyword arguments passed to the constructor -of an event are passed on to the handler. When declaring a -handler, its argument list must therefore match the arguments -used for creating the event.

-

Every event has a name attribute that is used for matching -the event with the handlers. By default, the name is the uncameled -class name of the event.

- --- - - - -
Variables:
    -
  • channels

    an optional attribute that may be set before firing -the event. If defined (usually as a class variable), the attribute -specifies the channels that the event should be delivered -to as a tuple. This overrides the default behavior -of sending the event to the firing component’s channel.

    -

    When an event is fired, the value in this attribute -is replaced for the instance with the channels that -the event is actually sent to. This information may be used -e.g. when the event is passed as a parameter to a handler.

    -
  • -
  • value – this is a circuits.core.values.Value -object that holds the results returned by the handlers invoked -for the event.
  • -
  • success – if this optional attribute is set to -True, an associated event EventSuccess (original name -with “Success” appended) will automatically be fired when all -handlers for the event have been invoked successfully.
  • -
  • success_channels – the success event is, by default, delivered -to same channels as the successfully dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
  • complete – if this optional attribute is set to -True, an associated event EventComplete (original name -with “Complete” appended) will automatically be fired when all -handlers for the event and all events fired by these handlers -(recursively) have been invoked successfully.
  • -
  • success_channels – the complete event is, by default, delivered -to same channels as the initially dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
-
-
- -
-
-class circuits.web.events.Stream(*args, **kwargs)
-

Bases: circuits.web.events.WebEvent

-

Stream(WebEvent) -> Stream WebEvent

-

args: request, response

-

An Event is a message send to one or more channels. It is eventually -dispatched to all components that have handlers for one -of the channels and the event type.

-

All normal arguments and keyword arguments passed to the constructor -of an event are passed on to the handler. When declaring a -handler, its argument list must therefore match the arguments -used for creating the event.

-

Every event has a name attribute that is used for matching -the event with the handlers. By default, the name is the uncameled -class name of the event.

- --- - - - -
Variables:
    -
  • channels

    an optional attribute that may be set before firing -the event. If defined (usually as a class variable), the attribute -specifies the channels that the event should be delivered -to as a tuple. This overrides the default behavior -of sending the event to the firing component’s channel.

    -

    When an event is fired, the value in this attribute -is replaced for the instance with the channels that -the event is actually sent to. This information may be used -e.g. when the event is passed as a parameter to a handler.

    -
  • -
  • value – this is a circuits.core.values.Value -object that holds the results returned by the handlers invoked -for the event.
  • -
  • success – if this optional attribute is set to -True, an associated event EventSuccess (original name -with “Success” appended) will automatically be fired when all -handlers for the event have been invoked successfully.
  • -
  • success_channels – the success event is, by default, delivered -to same channels as the successfully dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
  • complete – if this optional attribute is set to -True, an associated event EventComplete (original name -with “Complete” appended) will automatically be fired when all -handlers for the event and all events fired by these handlers -(recursively) have been invoked successfully.
  • -
  • success_channels – the complete event is, by default, delivered -to same channels as the initially dispatched event itself. -This may be overridden by specifying an alternative list of -destinations using this attribute.
  • -
-
-
- -
-
-

Components

-

none

-
-
-

Functions

-

none

-
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/api/circuits_web_exceptions.html circuits-3.1.0+ds1/docs/build/html/api/circuits_web_exceptions.html --- circuits-2.1.0/docs/build/html/api/circuits_web_exceptions.html 2013-02-27 11:27:59.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/api/circuits_web_exceptions.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,384 +0,0 @@ - - - - - - - - - circuits.web.exceptions – Exceptions — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

circuits.web.exceptions – Exceptions

-

Exceptions

-

This module implements a set of standard HTTP Errors as Python Exceptions.

-

Note: This code is mostly borrowed from werkzeug and adapted for circuits.web

-
-

Exceptions

-
-
-exception circuits.web.exceptions.HTTPException(description=None, traceback=None)
-

Bases: exceptions.Exception

-

Baseclass for all HTTP exceptions. This exception can be called by WSGI -applications to render a default error page or you can catch the subclasses -of it independently and render nicer error messages.

-
- -
-
-exception circuits.web.exceptions.BadGateway(description=None, traceback=None)
-

Bases: circuits.web.exceptions.HTTPException

-

502 Bad Gateway

-

If you do proxying in your application you should return this status code -if you received an invalid response from the upstream server it accessed -in attempting to fulfill the request.

-
- -
-
-exception circuits.web.exceptions.BadRequest(description=None, traceback=None)
-

Bases: circuits.web.exceptions.HTTPException

-

400 Bad Request

-

Raise if the browser sends something to the application the application -or server cannot handle.

-
- -
-
-exception circuits.web.exceptions.Forbidden(description=None, traceback=None)
-

Bases: circuits.web.exceptions.HTTPException

-

403 Forbidden

-

Raise if the user doesn’t have the permission for the requested resource -but was authenticated.

-
- -
-
-exception circuits.web.exceptions.Gone(description=None, traceback=None)
-

Bases: circuits.web.exceptions.HTTPException

-

410 Gone

-

Raise if a resource existed previously and went away without new location.

-
- -
-
-exception circuits.web.exceptions.InternalServerError(description=None, traceback=None)
-

Bases: circuits.web.exceptions.HTTPException

-

500 Internal Server Error

-

Raise if an internal server error occurred. This is a good fallback if an -unknown error occurred in the dispatcher.

-
- -
-
-exception circuits.web.exceptions.LengthRequired(description=None, traceback=None)
-

Bases: circuits.web.exceptions.HTTPException

-

411 Length Required

-

Raise if the browser submitted data but no Content-Length header which -is required for the kind of processing the server does.

-
- -
-
-exception circuits.web.exceptions.MethodNotAllowed(method, description=None)
-

Bases: circuits.web.exceptions.HTTPException

-

405 Method Not Allowed

-

Raise if the server used a method the resource does not handle. For -example POST if the resource is view only. Especially useful for REST.

-

The first argument for this exception should be a list of allowed methods. -Strictly speaking the response would be invalid if you don’t provide valid -methods in the header which you can do with that list.

-
- -
-
-exception circuits.web.exceptions.NotAcceptable(description=None, traceback=None)
-

Bases: circuits.web.exceptions.HTTPException

-

406 Not Acceptable

-

Raise if the server can’t return any content conforming to the -Accept headers of the client.

-
- -
-
-exception circuits.web.exceptions.NotFound(description=None, traceback=None)
-

Bases: circuits.web.exceptions.HTTPException

-

404 Not Found

-

Raise if a resource does not exist and never existed.

-
- -
-
-exception circuits.web.exceptions.NotImplemented(description=None, traceback=None)
-

Bases: circuits.web.exceptions.HTTPException

-

501 Not Implemented

-

Raise if the application does not support the action requested by the -browser.

-
- -
-
-exception circuits.web.exceptions.PreconditionFailed(description=None, traceback=None)
-

Bases: circuits.web.exceptions.HTTPException

-

412 Precondition Failed

-

Status code used in combination with If-Match, If-None-Match, or -If-Unmodified-Since.

-
- -
-
-exception circuits.web.exceptions.Redirect(urls, status=None)
-

Bases: circuits.web.exceptions.HTTPException

-
- -
-
-exception circuits.web.exceptions.RequestEntityTooLarge(description=None, traceback=None)
-

Bases: circuits.web.exceptions.HTTPException

-

413 Request Entity Too Large

-

The status code one should return if the data submitted exceeded a given -limit.

-
- -
-
-exception circuits.web.exceptions.RequestTimeout(description=None, traceback=None)
-

Bases: circuits.web.exceptions.HTTPException

-

408 Request Timeout

-

Raise to signalize a timeout.

-
- -
-
-exception circuits.web.exceptions.RequestURITooLarge(description=None, traceback=None)
-

Bases: circuits.web.exceptions.HTTPException

-

414 Request URI Too Large

-

Like 413 but for too long URLs.

-
- -
-
-exception circuits.web.exceptions.ServiceUnavailable(description=None, traceback=None)
-

Bases: circuits.web.exceptions.HTTPException

-

503 Service Unavailable

-

Status code you should return if a service is temporarily unavailable.

-
- -
-
-exception circuits.web.exceptions.Unauthorized(description=None, traceback=None)
-

Bases: circuits.web.exceptions.HTTPException

-

401 Unauthorized

-

Raise if the user is not authorized. Also used if you want to use HTTP -basic auth.

-
- -
-
-exception circuits.web.exceptions.UnicodeError(description=None, traceback=None)
-

Bases: circuits.web.exceptions.HTTPException

-

raised by the request functions if they were unable to decode the -incoming data properly.

-
- -
-
-exception circuits.web.exceptions.UnsupportedMediaType(description=None, traceback=None)
-

Bases: circuits.web.exceptions.HTTPException

-

415 Unsupported Media Type

-

The status code returned if the server is unable to handle the media type -the client transmitted.

-
- -
-
-

Events

-

none

-
-
-

Components

-

none

-
-
-

Functions

-

none

-
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/api/circuits_web_headers.html circuits-3.1.0+ds1/docs/build/html/api/circuits_web_headers.html --- circuits-2.1.0/docs/build/html/api/circuits_web_headers.html 2013-02-27 11:28:00.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/api/circuits_web_headers.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,343 +0,0 @@ - - - - - - - - - circuits.web.headers – Headers — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

circuits.web.headers – Headers

-

Headers Support

-

This module implements support for parsing and handling headers.

-
-

Events

-

none

-
-
-

Classes

-
-
-class circuits.web.headers.Headers(headers=[])
-

Bases: dict

-

Manage a collection of HTTP response headers

-
-
-has_key(name)
-

Return true if the message contains the header.

-
- -
-
-get_all(name)
-

Return a list of all the values for the named field.

-

These will be sorted in the order they appeared in the original header -list or were added to this instance, and may contain duplicates. Any -fields deleted and re-inserted are always appended to the header list. -If no fields exist with the given name, returns an empty list.

-
- -
-
-get(name, default=None)
-

Get the first header value for ‘name’, or return ‘default’

-
- -
-
-keys()
-

Return a list of all the header field names.

-

These will be sorted in the order they appeared in the original header -list, or were added to this instance, and may contain duplicates. -Any fields deleted and re-inserted are always appended to the header -list.

-
- -
-
-values()
-

Return a list of all header values.

-

These will be sorted in the order they appeared in the original header -list, or were added to this instance, and may contain duplicates. -Any fields deleted and re-inserted are always appended to the header -list.

-
- -
-
-items()
-

Get all the header fields and values.

-

These will be sorted in the order they were in the original header -list, or were added to this instance, and may contain duplicates. -Any fields deleted and re-inserted are always appended to the header -list.

-
- -
-
-setdefault(name, value)
-

Return first matching header value for ‘name’, or ‘value’

-

If there is no header named ‘name’, add a new header with name ‘name’ -and value ‘value’.

-
- -
-
-add_header(_name, _value, **_params)
-

Extended header setting.

-

_name is the header field to add. keyword arguments can be used to set -additional parameters for the header field, with underscores converted -to dashes. Normally the parameter will be added as key=”value” unless -value is None, in which case only the key will be added.

-

Example:

-

h.add_header(‘content-disposition’, ‘attachment’, filename=’bud.gif’)

-

Note that unlike the corresponding ‘email.Message’ method, this does -not handle ‘(charset, language, value)’ tuples: all values must be -strings or None.

-
- -
-
-elements(key)
-

Return a list of HeaderElements for the given header (or None).

-
- -
- -
-
-class circuits.web.headers.HeaderElement(value, params=None)
-

Bases: object

-

An element (with parameters) from an HTTP header’s element list.

-
-
-static parse(elementstr)
-

Transform ‘token;key=val’ to (‘token’, {‘key’: ‘val’}).

-
- -
-
-classmethod from_str(elementstr)
-

Construct an instance from a string of the form ‘token;key=val’.

-
- -
- -
-
-class circuits.web.headers.AcceptElement(value, params=None)
-

Bases: circuits.web.headers.HeaderElement

-

An element (with parameters) from an Accept* header’s element list.

-

AcceptElement objects are comparable; the more-preferred object will be -“less than” the less-preferred object. They are also therefore sortable; -if you sort a list of AcceptElement objects, they will be listed in -priority order; the most preferred value will be first. Yes, it should -have been the other way around, but it’s too late to fix now.

-
-
-qvalue
-

The qvalue, or priority, of this value.

-
- -
- -
-
-

Components

-

none

-
-
-

Functions

-
-
-circuits.web.headers.header_elements(fieldname, fieldvalue)
-

Return a HeaderElement list from a comma-separated header str.

-
- -
-
-circuits.web.headers.parse_headers(data)
-
- -
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/api/circuits_web.html circuits-3.1.0+ds1/docs/build/html/api/circuits_web.html --- circuits-2.1.0/docs/build/html/api/circuits_web.html 2013-02-27 11:27:58.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/api/circuits_web.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,208 +0,0 @@ - - - - - - - - - circuits.web – Web Framework — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
- - - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/api/circuits_web_http.html circuits-3.1.0+ds1/docs/build/html/api/circuits_web_http.html --- circuits-2.1.0/docs/build/html/api/circuits_web_http.html 2013-02-27 11:28:00.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/api/circuits_web_http.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,289 +0,0 @@ - - - - - - - - - circuits.web.http – HTTP Protocol — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

circuits.web.http – HTTP Protocol

-

Hyper Text Transfer Protocol

-

This module implements the server side Hyper Text Transfer Protocol -or commonly known as HTTP.

-
-

Components

-
-
-class circuits.web.http.HTTP(encoding='utf-8', channel='web')
-

Bases: circuits.core.components.BaseComponent

-

HTTP Protocol Component

-

Implements the HTTP server protocol and parses and processes incoming -HTTP messages, creating and sending an appropriate response.

-

The component handles Read events -on its channel and collects the associated data until a complete -HTTP request has been received. It parses the request’s content -and puts it in a Request object and -creates a corresponding Response -object. Then it emits a Request -event with these objects as arguments.

-

The component defines several handlers that send a response back to -the client.

-
-
-_on_response(response)
-

Response Event Handler

- --- - - - -
Parameters:response (Response) – the Response object created when the -HTTP request was initially received.
-

This handler builds an HTTP response data stream from -the information contained in the response object and -sends it to the client (firing Write events).

-
- -
-
-_on_read(sock, data)
-

Read Event Handler

-

Process any incoming data appending it to an internal buffer. -Split the buffer by the standard HTTP delimiter CRLF and create -Raw Event per line. Any unfinished lines of text, leave in the buffer.

-
- -
-
-_on_httperror(event, request, response, code, **kwargs)
-

Default HTTP Error Handler

-

Default Error Handler that by default just fires a Response -event with the response as argument. The response is normally -modified by a HTTPError instance -or a subclass thereof.

-
- -
-
-_on_request_success(e, value)
-

Handler for the RequestSuccess event that is automatically -generated after all handlers for a -Request event have been invoked -successfully.

- --- - - - -
Parameters:
    -
  • e – the successfully handled Request event (having -as attributes the associated -Request and -Response objects).
  • -
  • value – the value(s) returned by the invoked handler(s).
  • -
-
-

This handler converts the value(s) returned by the -(successfully invoked) handlers for the initial Request -event to a body and assigns it to the Response object’s -body attribute. It then fires a -Response event with the -Response object as argument.

-
- -
- -
- -
-

Functions

-

none

-
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/api/circuits_web_loggers.html circuits-3.1.0+ds1/docs/build/html/api/circuits_web_loggers.html --- circuits-2.1.0/docs/build/html/api/circuits_web_loggers.html 2013-02-27 11:28:00.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/api/circuits_web_loggers.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,213 +0,0 @@ - - - - - - - - - circuits.web.loggers – Loggers — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

circuits.web.loggers – Loggers

-

Logger Component

-

This module implements Logger Components.

-
-

Events

-

none

-
-
-

Components

-
-
-class circuits.web.loggers.Logger(file=None, logger=None, **kwargs)
-

Bases: circuits.core.components.BaseComponent

-
- -
-
-

Functions

-
-
-circuits.web.loggers.formattime()
-
- -
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/api/circuits_web_main.html circuits-3.1.0+ds1/docs/build/html/api/circuits_web_main.html --- circuits-2.1.0/docs/build/html/api/circuits_web_main.html 2013-02-27 11:28:00.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/api/circuits_web_main.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,184 +0,0 @@ - - - - - - - - - circuits.web.main – circuits.web — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

circuits.web.main – circuits.web

-

Main

-

circutis.web Web Server and Testing Tool.

-

Shipped application with static and directory index support suitable for -quickly serving up simple web pages.

-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/api/circuits_web_servers.html circuits-3.1.0+ds1/docs/build/html/api/circuits_web_servers.html --- circuits-2.1.0/docs/build/html/api/circuits_web_servers.html 2013-02-27 11:28:00.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/api/circuits_web_servers.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,247 +0,0 @@ - - - - - - - - - circuits.web.servers – Servers — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

circuits.web.servers – Servers

-

Web Servers

-

This module implements the several Web Server components.

-
-

Events

-

none

-
-
-

Components

-
-
-class circuits.web.servers.BaseServer(bind, encoding='utf-8', secure=False, certfile=None, channel='web')
-

Bases: circuits.core.components.BaseComponent

-

Create a Base Web Server

-

Create a Base Web Server (HTTP) bound to the IP Address / Port or -UNIX Socket specified by the ‘bind’ parameter.

- --- - - - - - -
Variables:server – Reference to underlying Server Component
Parameters:bind (Instance of int, list, tuple or str) – IP Address / Port or UNIX Socket to bind to.
-

The ‘bind’ parameter is quite flexible with what valid values it accepts.

-

If an int is passed, a TCPServer will be created. The Server will be -bound to the Port given by the ‘bind’ argument and the bound interface -will default (normally to “0.0.0.0”).

-

If a list or tuple is passed, a TCPServer will be created. The -Server will be bound to the Port given by the 2nd item in the ‘bind’ -argument and the bound interface will be the 1st item.

-

If a str is passed and it contains the ‘:’ character, this is -assumed to be a request to bind to an IP Address / Port. A TCpServer -will thus be created and the IP Address and Port will be determined -by splitting the string given by the ‘bind’ argument.

-

Otherwise if a str is passed and it does not contain the ‘:’ -character, a file path is assumed and a UNIXServer is created and -bound to the file given by the ‘bind’ argument.

-
- -
-
-class circuits.web.servers.Server(bind, **kwargs)
-

Bases: circuits.web.servers.BaseServer

-

Create a Web Server

-

Create a Web Server (HTTP) complete with the default Dispatcher to -parse requests and posted form data dispatching to appropriate -Controller(s).

-

See: circuits.web.servers.BaseServer

-
- -
-
-

Functions

-

none

-
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/api/circuits_web_sessions.html circuits-3.1.0+ds1/docs/build/html/api/circuits_web_sessions.html --- circuits-2.1.0/docs/build/html/api/circuits_web_sessions.html 2013-02-27 11:28:00.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/api/circuits_web_sessions.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,210 +0,0 @@ - - - - - - - - - circuits.web.sessions – Sessions — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

circuits.web.sessions – Sessions

-

Session Components

-

This module implements Session Components that can be used to store -and access persistent information.

-
-

Events

-

none

-
-
-

Components

-
-
-class circuits.web.sessions.Sessions(name='circuits.session', *args, **kwargs)
-

Bases: circuits.core.components.Component

-
- -
-
-

Functions

-

none

-
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/api/circuits_web_tools.html circuits-3.1.0+ds1/docs/build/html/api/circuits_web_tools.html --- circuits-2.1.0/docs/build/html/api/circuits_web_tools.html 2013-02-27 11:28:00.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/api/circuits_web_tools.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,347 +0,0 @@ - - - - - - - - - circuits.web.tools – Tools — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

circuits.web.tools – Tools

-

Tools

-

This module implements tools used throughout circuits.web. -These tools can also be used within Controlelrs and request handlers.

-
-

Events

-

none

-
-
-

Components

-

none

-
-
-

Functions

-
-
-circuits.web.tools.basic_auth(request, response, realm, users, encrypt=None)
-

Perform Basic Authentication

-

If auth fails, returns an Unauthorized error with a -basic authentication header.

- --- - - - -
Parameters:
    -
  • realm (str) – The authentication realm.
  • -
  • users (dict or callable) – A dict of the form: {username: password} or a callable -returning a dict.
  • -
  • encrypt (callable) – Callable used to encrypt the password returned from -the user-agent. if None it defaults to a md5 encryption.
  • -
-
-
- -
-
-circuits.web.tools.check_auth(request, response, realm, users, encrypt=None)
-

Check Authentication

-

If an authorization header contains credentials, return True, else False.

- --- - - - -
Parameters:
    -
  • realm (str) – The authentication realm.
  • -
  • users (dict or callable) – A dict of the form: {username: password} or a callable -returning a dict.
  • -
  • encrypt (callable) – Callable used to encrypt the password returned from -the user-agent. if None it defaults to a md5 encryption.
  • -
-
-
- -
-
-circuits.web.tools.digest_auth(request, response, realm, users)
-

Perform Digest Authentication

-

If auth fails, raise 401 with a digest authentication header.

- --- - - - -
Parameters:
    -
  • realm (str) – The authentication realm.
  • -
  • users (dict or callable) – A dict of the form: {username: password} or a callable -returning a dict.
  • -
-
-
- -
-
-circuits.web.tools.expires(request, response, secs=0, force=False)
-

Tool for influencing cache mechanisms using the ‘Expires’ header.

-

‘secs’ must be either an int or a datetime.timedelta, and indicates the -number of seconds between response.time and when the response should -expire. The ‘Expires’ header will be set to (response.time + secs).

-

If ‘secs’ is zero, the ‘Expires’ header is set one year in the past, and -the following “cache prevention” headers are also set: -- ‘Pragma’: ‘no-cache’ -- ‘Cache-Control’: ‘no-cache, must-revalidate’

-

If ‘force’ is False (the default), the following headers are checked: -‘Etag’, ‘Last-Modified’, ‘Age’, ‘Expires’. If any are already present, -none of the above response headers are set.

-
- -
-
-circuits.web.tools.gzip(response, level=4, mime_types=['text/html', 'text/plain'])
-

Try to gzip the response body if Content-Type in mime_types.

-

response.headers[‘Content-Type’] must be set to one of the -values in the mime_types arg before calling this function.

-
-
No compression is performed if any of the following hold:
-
    -
  • The client sends no Accept-Encoding request header
  • -
  • No ‘gzip’ or ‘x-gzip’ is present in the Accept-Encoding header
  • -
  • No ‘gzip’ or ‘x-gzip’ with a qvalue > 0 is present
  • -
  • The ‘identity’ value is given with a qvalue > 0.
  • -
-
-
-
- -
-
-circuits.web.tools.serve_download(request, response, path, name=None)
-

Serve ‘path’ as an application/x-download attachment.

-
- -
-
-circuits.web.tools.serve_file(request, response, path, type=None, disposition=None, name=None)
-

Set status, headers, and body in order to serve the given file.

-

The Content-Type header will be set to the type arg, if provided. -If not provided, the Content-Type will be guessed by the file extension -of the ‘path’ argument.

-

If disposition is not None, the Content-Disposition header will be set -to “<disposition>; filename=<name>”. If name is None, it will be set -to the basename of path. If disposition is None, no Content-Disposition -header will be written.

-
- -
-
-circuits.web.tools.validate_etags(request, response, autotags=False)
-

Validate the current ETag against If-Match, If-None-Match headers.

-

If autotags is True, an ETag response-header value will be provided -from an MD5 hash of the response body (unless some other code has -already provided an ETag header). If False (the default), the ETag -will not be automatic.

-

WARNING: the autotags feature is not designed for URL’s which allow -methods other than GET. For example, if a POST to the same URL returns -no content, the automatic ETag will be incorrect, breaking a fundamental -use for entity tags in a possibly destructive fashion. Likewise, if you -raise 304 Not Modified, the response body will be empty, the ETag hash -will be incorrect, and your application will break. -See http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.24

-
- -
-
-circuits.web.tools.validate_since(request, response)
-

Validate the current Last-Modified against If-Modified-Since headers.

-

If no code has set the Last-Modified response header, then no validation -will be performed.

-
- -
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/api/circuits_web_utils.html circuits-3.1.0+ds1/docs/build/html/api/circuits_web_utils.html --- circuits-2.1.0/docs/build/html/api/circuits_web_utils.html 2013-02-27 11:28:00.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/api/circuits_web_utils.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,269 +0,0 @@ - - - - - - - - - circuits.web.utils – Utilities — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

circuits.web.utils – Utilities

-

Utilities

-

This module implements utility functions.

-
-

Events

-

none

-
-
-

Components

-

none

-
-
-

Functions

-
-
-circuits.web.utils.compress(body, compress_level)
-

Compress ‘body’ at the given compress_level.

-
- -
-
-circuits.web.utils.dictform(form)
-
- -
-
-circuits.web.utils.get_ranges(headervalue, content_length)
-

Return a list of (start, stop) indices from a Range header, or None.

-

Each (start, stop) tuple will be composed of two ints, which are suitable -for use in a slicing operation. That is, the header “Range: bytes=3-6”, -if applied against a Python string, is requesting resource[3:7]. This -function will return the list [(3, 7)].

-

If this function returns an empty list, you should return HTTP 416.

-
- -
-
-circuits.web.utils.parse_body(request, response, params)
-
- -
-
-circuits.web.utils.parse_qs(query_string) → dict
-

Build a params dictionary from a query_string. -If keep_blank_values is True (the default), keep -values that are blank.

-
- -
-
-circuits.web.utils.url(request, path='', qs='', script_name=None, base=None, relative=None)
-

Create an absolute URL for the given path.

-
-
If ‘path’ starts with a slash (‘/’), this will return
-
    -
  • (base + script_name + path + qs).
  • -
-
-
If it does not start with a slash, this returns
-
    -
  • (base + script_name [+ request.path] + path + qs).
  • -
-
-
-

If script_name is None, request will be used -to find a script_name, if available.

-

If base is None, request.base will be used (if available).

-

Finally, note that this function can be used to obtain an absolute URL -for the current request path (minus the querystring) by passing no args. -If you call url(qs=request.qs), you should get the -original browser URL (assuming no internal redirections).

-

If relative is False the output will be an absolute URL -(including the scheme, host, vhost, and script_name). -If True, the output will instead be a URL that is relative to the -current request path, perhaps including ‘..’ atoms. If relative is -the string ‘server’, the output will instead be a URL that is -relative to the server root; i.e., it will start with a slash.

-
- -
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/api/circuits_web_websocket.html circuits-3.1.0+ds1/docs/build/html/api/circuits_web_websocket.html --- circuits-2.1.0/docs/build/html/api/circuits_web_websocket.html 2013-02-27 11:28:00.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/api/circuits_web_websocket.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,252 +0,0 @@ - - - - - - - - - circuits.web.websocket – WebSocket Client — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

circuits.web.websocket – WebSocket Client

-
-

Events

-
-
-

Components

-
-
-class circuits.web.websocket.WebSocketClient(url, channel='wsclient', wschannel='ws', headers={})
-

Bases: circuits.core.components.BaseComponent

-

An RFC 6455 compliant WebSocket client component. Upon receiving a -circuits.web.client.Connect event, the component tries to -establish the connection to the server in a two stage process. First, a -circuits.net.sockets.Connect event is sent to a child -TCPClient. When the TCP connection has been established, -the HTTP request for opening the WebSocket is sent to the server. -A failure in this setup process is signaled by a -NotConnected event.

-

When the server accepts the request, the WebSocket connection is -established and can be used very much like an ordinary socket -by handling Read events on and sending -Write events to the channel -specified as the wschannel parameter of the constructor. Firing -a Close event on that channel closes the -connection in an orderly fashion (i.e. as specified by the -WebSocket protocol).

- --- - - - -
Parameters:
    -
  • url – the URL to connect to.
  • -
  • channel – the channel used by this component
  • -
  • wschannel – the channel used for the actual WebSocket -communication (read, write, close events)
  • -
  • headers – additional headers to be passed with the -WebSocket setup HTTP request
  • -
-
-
-
-channel = 'wsclient'
-
- -
-
-close()
-
- -
-
-connected
-
- -
- -
-
-

Functions

-
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/api/circuits_web_wrappers.html circuits-3.1.0+ds1/docs/build/html/api/circuits_web_wrappers.html --- circuits-2.1.0/docs/build/html/api/circuits_web_wrappers.html 2013-02-27 11:28:00.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/api/circuits_web_wrappers.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,267 +0,0 @@ - - - - - - - - - circuits.web.wrappers – Request/Response Objects — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

circuits.web.wrappers – Request/Response Objects

-
-

Events

-

none

-
-
-

Classes

-
-
-class circuits.web.wrappers.Body
-

Bases: object

-

Response Body

-
- -
-
-class circuits.web.wrappers.Host(ip, port, name=None)
-

Bases: object

-

An internet address.

-

name should be the client’s host name. If not available (because no DNS -lookup is performed), the IP address should be used instead.

-
- -
-
-class circuits.web.wrappers.Request(sock, method, scheme, path, protocol, qs)
-

Bases: object

-

Creates a new Request object to hold information about a request.

- --- - - - -
Parameters:
    -
  • sock (socket.socket) – The socket object of the request.
  • -
  • method (str) – The requsted method.
  • -
  • scheme (str) – The requsted scheme.
  • -
  • path (str) – The requsted path.
  • -
  • protocol (str) – The requsted protocol.
  • -
  • qs (str) – The query string of the request.
  • -
-
-

initializes x; see x.__class__.__doc__ for signature

-
-
-server = None
-

@cvar: A reference to the underlying server

-
- -
- -
-
-class circuits.web.wrappers.Response(request, encoding='utf-8', code=None, message=None)
-

Bases: object

-

Response(sock, request) -> new Response object

-

A Response object that holds the response to -send back to the client. This ensure that the correct data -is sent in the correct order.

-

initializes x; see x.__class__.__doc__ for signature

-
- -
-
-

Components

-

none

-
-
-

Functions

-
-
-circuits.web.wrappers.file_generator(input, chunkSize=4096)
-
- -
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/api/circuits_web_wsgi.html circuits-3.1.0+ds1/docs/build/html/api/circuits_web_wsgi.html --- circuits-2.1.0/docs/build/html/api/circuits_web_wsgi.html 2013-02-27 11:28:00.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/api/circuits_web_wsgi.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,217 +0,0 @@ - - - - - - - - - circuits.web.wsgi – WSGI Support — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

circuits.web.wsgi – WSGI Support

-

WSGI Components

-

This module implements WSGI Components.

-
-

Events

-

none

-
-
-

Components

-
-
-class circuits.web.wsgi.Application(*args, **kwargs)
-

Bases: circuits.core.components.BaseComponent

-

initializes x; see x.__class__.__doc__ for signature

-
- -
-
-class circuits.web.wsgi.Gateway(*args, **kwargs)
-

Bases: circuits.core.components.BaseComponent

-

initializes x; see x.__class__.__doc__ for signature

-
- -
-
-

Functions

-

none

-
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/api/index.html circuits-3.1.0+ds1/docs/build/html/api/index.html --- circuits-2.1.0/docs/build/html/api/index.html 2013-02-27 11:28:00.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/api/index.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,186 +0,0 @@ - - - - - - - - - API Reference — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
- - - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/.buildinfo circuits-3.1.0+ds1/docs/build/html/.buildinfo --- circuits-2.1.0/docs/build/html/.buildinfo 2013-02-27 11:28:04.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/.buildinfo 1970-01-01 00:00:00.000000000 +0000 @@ -1,4 +0,0 @@ -# Sphinx build info version 1 -# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. -config: -tags: diff -Nru circuits-2.1.0/docs/build/html/changes.html circuits-3.1.0+ds1/docs/build/html/changes.html --- circuits-2.1.0/docs/build/html/changes.html 2013-02-27 11:28:01.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/changes.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,1138 +0,0 @@ - - - - - - - - - ChangeLog — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

ChangeLog

-
-

circuits-2.1.0 20130224 (<release>)

-
-

Features

-
    -
  • Added IPv6 Support [#39987887]
  • -
  • Document and Comment all Examples [#40112459]
  • -
  • Update WebSockets dispatcher in circuits.web [40064247]
  • -
  • Component Event Handlers Property [#41573841]
  • -
  • Component targeting performance [#41644031]
  • -
  • Multi-App WSGI Gateway [#40071339]
  • -
  • More efficient timer implementation [#43700669]
  • -
-
-
-

Bugs

-
    -
  • Fix the broken links in the Users page [#40063597]
  • -
  • circuits.tools.inspect shows incorrect ticks [#41650961]
  • -
  • Race Condition with call/wait primitives [#41643711]
  • -
  • RESTful Dispatcher [#41643773]
  • -
  • Fix Component instance targeting [#41644025]
  • -
  • Worker Processes [#41643831]
  • -
  • Make examples/web/sslserver.py work again [42007509]
  • -
  • Value instance in body [43287263]
  • -
-
-
-

Chores

-
    -
  • Import shadowing in manager.py [#41644023]
  • -
  • Run the codebase through flake8 [#41651093]
  • -
  • URL Quoting Unit Test [#41882655]
  • -
  • SSL Unit Test [#42849393]
  • -
  • Python 3.x Support [43027337]
  • -
  • Fill out FAQ in Docs [#43389199]
  • -
  • Write Developer Docs [#43389193]
  • -
-
-
-

Other Changes

-

A list of other changes we forgot to track :)

-
    -
  • Fixed latency timing for circuits.bench on win32

    -
  • -
  • Updated the URL for ReadTheDocs

    -
  • -
  • Updated the Getting Started / Downloading documentation to -say something about the Tags tab for downloading archives.

    -
  • -
  • Removed unused import in circuits.app.env

    -
  • -
  • Added some documentation about how HTTP requests are handled.

    -
  • -
  • Removed unused code

    -
  • -
  • A simple chat server implementation (Examples)

    -
  • -
  • Fixed a bug with Manager.processTasks and Error event firing. -handler was not being set correctly

    -
  • -
  • Fixes wrong variable names in sockets.py

    -
  • -
  • Fixed an UnboundLocalError bug

    -
  • -
  • Expect the original method to be passed as input to Manager.removeHandler -Manager.addHandler now returns a reference to the original method.

    -
  • -
  • Guard against a None _sock or non-existent _sock object.

    -
  • -
  • Allow a custom host, port and secure option to be passed -to the connect event handler of circuits.web.client.Client

    -
  • -
  • Redesigned tests/web/conftest.py with newer pytest APIs using -@pytest.fixture(...)

    -
  • -
  • Experimental new Watcher/Manager fixtures

    -
  • -
  • Docs for Fallback generator

    -
  • -
  • Removing the concept of _ticks, @tick and friends

    -
  • -
  • Fixes timers

    -
  • -
  • Reimplemented circuits.io.File as per circuits.net.sockets

    -
  • -
  • Re-implemented Notify Component and fixed test

    -
  • -
  • Reworked Notifier Component to be more async friendly

    -
  • -
  • Fixed a bug with the repr of Manager and thus Components with non-str channels. eg: (1, 1)

    -
  • -
  • Added a unit test for generate_events handler

    -
  • -
  • Fixed terminal example demonstrating Streaming with circuits.web

    -
  • -
  • Fixed index page for terminal web example

    -
  • -
  • Added an Open event to File

    -
  • -
  • Fixed a bug with the static dispatcher for circuits.web whereby -the path was not being unquoted

    -
  • -
  • Fixed a bug with the static circuits.web dispatcher whereby directory -listing did not quote urls

    -
  • -
  • Added simple examples demonstrating circuits’ primitives

    -
  • -
  • Added example of .fire(...) primitive

    -
  • -
  • Restructured circuits.io and implemented circuits.io.Process with unit test

    -
  • -
  • Added Hello World example

    -
  • -
  • Made components started in process mode not link by default. -Have to explicitly set the kwarg link=component_instance.

    -
  • -
  • Fixed raising of SystemExit or KeyboardInterrupt.

    -
  • -
  • Modified the way caching works with the Static dispatcher

    -
  • -
  • Brought back the circuits.core.bridge.Bridge. -With it better inter-process communications via high-speed full duplex pipes -using circuits.net.sockets.Pipe (UNIX Only), a much simpler API.

    -

    In addition, a change to the way Value Notification works. .notify of an -event instance can either be True or a channel to send the ValueChanged -event to.

    -
  • -
  • Added timers examples resurrected from old circuits

    -
  • -
  • Global handlers and component targeting -Global handlers would be ignored when using component targeting.

    -

    This patch considers them. To do this, we have added an extra property -to managers.

    -

    You can use traverse_children_handlers to increase performance when you have -a huge number of components. Put the components that are only meant to be -used with component targeting under a single component. The hierarchy -looks like this:

    -
    Root -> Umbrella Component -> Component 1, Component 2, Component 3, ...
    -     -> Debugger()
    -     -> etc
    -
    -
    -
  • -
  • Set Umbrella Component traverse_children_handlers to false to prevent -traversing the huge number of children components.

    -
  • -
  • Fixed Connection header interpretation.

    -
  • -
  • Updated documentation for WebSocket.

    -
  • -
  • Removed pool - covered by worker

    -
  • -
  • Fixed dispatchers return value.

    -
  • -
  • Firing Connect event when a web socket connection is established to make -behavior look even more like ordinary sockets.

    -
  • -
  • Nuked @future decorator due to pickling problems for processes.

    -
  • -
  • Allow coroutine-style tasks to terminate the system via raise -of SystemExit or KeyboardInterrupt

    -
  • -
  • Dropping events unnoticed when waiting is definitely a bad idea. Fixed.

    -
  • -
  • Clarification on implementing a GenerateEvents handler.

    -
  • -
  • Optimized GenerateEvents handling.

    -
  • -
  • Optimized management of FallbackGenerator.

    -
  • -
  • Fixed a problem with events being out of sequence when _fire -is called recursively. The fix exposes a problem with conftest.Waiter -(events getting lost because they are produced too fast, therefore queue -is increased). Reducing production rate will be in next commit.

    -
  • -
  • Small fix for new event queue handling.

    -
  • -
  • Fixed problem with handler cache update and concurrent event -handling/structure changes. This happens e.g. in unit tests when the -app is started and the test program adds or removes components concurrently.

    -
  • -
  • Optimized/clarified GenerateEvents implementation.

    -
  • -
  • One more concurrency problem fixed.

    -
  • -
  • Fixed generate events handler.

    -
  • -
  • Fixed bug with handler cache being always invalidated. -Avoid stop() acting as concurrent thread on _dispatcher()

    -
  • -
  • Fixed payload length calculation in web sockets protocol.

    -
  • -
  • Some very small - but measurable - performance improvements. -Checking them in mainly because now no one else needs to think about -whether they have an effect.

    -
  • -
  • Fixed IPv6 socket tests for OSX and badly configured IPv6 networks

    -
  • -
  • Fixed ready handler for test_node

    -
  • -
  • Re-added an old revived example of an IRC Client integrating -the urwid curses library for the interface

    -
  • -
  • Added an example of using yield to perform cooperative multi-tasking -inside a request event handler

    -
  • -
  • Uses echo for test_process

    -
  • -
  • Fixes process stdout/stderr handling -Process was not waiting for all output from a process to have been -processed and resulted sometimes some of the process output being lost -while stopping.

    -
  • -
  • Added a fall back error handler, so problems aren’t discarded silently -any more.

    -
  • -
  • Fixed a TypeError being raised in the request handler for WebSockets -dispatcher

    -
  • -
  • Prevent the underlying TCPClient connect handler from inadvertently being -triggered by connect events being fired to the web client

    -
  • -
  • Added tox configuration file. Just run: tox

    -
  • -
  • Configure tox to output junitxml

    -
  • -
  • Fixed the logic of path -> wsgi dispatching in Gateway

    -
  • -
  • Fixed an awful bug with wrappers.Response whereby a default Content-Type was -always set regardless and didn’t allow anything else to set this.

    -
  • -
  • Fixed test_disps so it doesn’t use an existing port that’s in use.

    -
  • -
  • Added a missing piece of WSGI 1.0 functionality for wsgi.Gateway. -The write() callable

    -
  • -
  • Rewrite test_filer unit test. -Ensured EOF event is not triggered for files opened in a or + modes.

    -
  • -
  • Added simple examples demonstrating circuits’ primitives

    -
  • -
  • Added example of .fire(...) primitive

    -
  • -
  • Restructured circuits.io and implemented circuits.io.Process with unit test

    -
  • -
  • Forgot to add test_process unit test

    -
  • -
  • Added Hello World example

    -
  • -
  • Fixed event handler for generate_events

    -
  • -
  • Implemented multiprocessing support with communication via full duplex pipes. -Fixed worker processes and added unit test

    -
  • -
  • Made components started in process mode not link by default. -Have to explicitly set the kwarg link=True

    -
  • -
  • Fixed process pools and added unit test

    -
  • -
  • Fixed name of method for handling inotify events - -conflicting with ._process of Manager/Component

    -
  • -
  • Renamed ._process to .__process so as to not conflict with Worker

    -
  • -
  • Fixed raising of SystemExit or KeyboardInterrupt

    -
  • -
  • Trying to fix sending/receiving of events and their values

    -
  • -
  • Fixed IPv6 address evaluation.

    -
  • -
  • WebSockets reimplemented as specified by RFC 6455.

    -
  • -
  • Modified the way caching works with the Statis dispatcher -and serve_file(...) function. Set Last-Modified instead of a -large Expires header.

    -
  • -
  • Marked as a Missing Feature - still being worked on.

    -
  • -
  • Brought back the circuits.core.bridge.Bridge. -With it better inter-process communications via high-speed full duplex pipes -using circuits.net.sockets.Pipe (UNIX Only), a much simpler API.

    -

    In addition, a chnage to the way Value Notification works. .notify of an -event instance can either be True or a channel to send the ValueChanged -event to.

    -
  • -
  • Causes errors. Wrong thing to do here.

    -
  • -
  • Use uuid4 for worker channels.

    -
  • -
  • Removed left over debugging code

    -
  • -
  • Added capability of components started in proces mode to -link to artbritrary managers other than themselves (if link=True)

    -
  • -
  • Added unit test for testing a component in process mode linked with -another parent system separately

    -
  • -
  • Added timers examples ressurected from old circuits

    -
  • -
  • Thread safety for watcher

    -
  • -
  • Reverts test_component_targeting.py

    -
  • -
  • Fixed Connection header interpretation.

    -
  • -
  • Updated documentation for WebSocket.

    -
  • -
  • Changed the way process linking works by not starting the parent in -thread mode.

    -
  • -
  • Fixes watcher test fixture

    -
  • -
  • Implemented .handlers() and re-implemented .handles(). [Delivers #41573841]

    -
  • -
  • Removed superfluous bridge test

    -
  • -
  • Fixed usage of .start starting Workers in process mode

    -
  • -
  • Better internal variable name

    -
  • -
  • Start worked either when the system starts or we are -regsitered to an already started system

    -
  • -
  • Implemented .handlers() correctly

    -
  • -
  • Set unique channels for the Pipe and Bridge when briding processes

    -
  • -
  • Removed. Going to reimplement all this

    -
  • -
  • Don’t cause a nastry fork bomb!

    -
  • -
  • Marked test_process_pool as skipping XXX: Broken Functionality

    -
  • -
  • Fixed sleeping when nothing to do adding needs_resume logic to the pollers

    -
  • -
  • Proposed new Worker Component – wrapping multiprocessing.Process

    -
  • -
  • Accidentla commit

    -
  • -
  • Trying to re-implement Pool...

    -
  • -
  • Marked some tests as broken

    -
  • -
  • Added support for both Process and Thread in Worker component with same API.

    -
  • -
  • Reverted changes to the task handler for Worker

    -
  • -
  • Removed .resume()

    -
  • -
  • Fixed some brokeness in future

    -
  • -
  • Trying to make @future work with Worker in process mode

    -
  • -
  • Lock bench

    -
  • -
  • Switches worker to apply_async

    -
  • -
  • Allow the poller to sleep when tasks are running

    -
  • -
  • Use ThreadPool for worker threads

    -
  • -
  • Cleaned up Worker

    -
  • -
  • benchmark only branch

    -
  • -
  • Removed pool - covered by worker

    -
  • -
  • Workaround for Threadpool bug started from secondary threads

    -
  • -
  • Fixed dispatchers return value.

    -
  • -
  • Firing Connect event when a web socket connection is established to make -behavior look even more like ordinary sockets.

    -
  • -
  • Restored 2.0.1 GenerateEvents handling with minor enhancements to get -things working again.

    -
  • -
  • Nuked @future decotator due to pickling problems for processes.

    -
  • -
  • Unmarked test as failing. Test now passes prefectly

    -
  • -
  • Allow coroutine-style tasks to terminate the system -via raise of SystemExit or KeyboardINterrupt

    -
  • -
  • Fixed SSL support for circuits.web [Delivers #42007509]

    -
  • -
  • Dropping events unnoticed when waiting is definitely a bad idea. Fixed.

    -
  • -
  • Clarification on implementing a GenerateEvents handler.

    -
  • -
  • Added missing import (timed wait with FallBackGenerator cannot have -worked for some time).

    -
  • -
  • Optimized GenerateEvents handling.

    -
  • -
  • Backed out of changeset 3413:98d0056ef18a

    -
  • -
  • Optimized management of FallbackGenerator.

    -
  • -
  • Fixed a problem with events being out of sequence when _fire is called -recursively. The fix exposes a problem with conftest.Waiter -(events getting lost because they are produced too fast, -therefore queue is increased). Reducing production rate will be in -next commit.

    -
  • -
  • Small fix for new event queue handling.

    -
  • -
  • Fixed problem with handler cache update and concurrent event -handling/structure changes. This happens e.g. in unit tests when the -app is started and the test program adds or removes components concurrently.

    -
  • -
  • Optimized/clarified GenerateEvents implementation.

    -
  • -
  • One more concurrency problem fixed.

    -
  • -
  • Fixed generate events handler.

    -
  • -
  • Fixed bug with handler cache being always invalidated. -Avoid stop() acting as concurrent thread on _dispatcher().

    -
  • -
  • Added unit test for url quoting of static files for the static -circuits.web dispatcher. [Delivers #41882655]

    -
  • -
  • Added unit test for secure circutis.web server. [Delivers #42849393]

    -
  • -
  • Fixed creation/registration/location of poller upon startup or registration

    -
  • -
  • Skip test_secure_server if ssl is not available

    -
  • -
  • Fixed payload length calculation in web sockets protocol.

    -
  • -
  • Some very small - but measurable - performance improvements. -Checking them in mainly because now no one else needs to think -about whether they have an effect.

    -
  • -
  • Fixed conflicting attribute.

    -
  • -
  • Added new .pid property to Manager fixing tests.core.test_bridge -- Broken by 70677b69bf05

    -
  • -
  • Fixed ipv6 socket tests for OSX and badly configured IPv6 networks

    -
  • -
  • Ugly fix for this test

    -
  • -
  • Fixed ready handler for test_node

    -
  • -
  • For some reason removing max_events in the Watcher fixture for esting -purposes fixes some tests on OSX

    -
  • -
  • Small sample to hopefully test for memory leaks :)

    -
  • -
  • Improved .handlers() to recursively return handlers of it’s subclasses -whilst filtering out private handlers (_.*)

    -
  • -
  • Use BaseComponent for convenience for non-handler methods

    -
  • -
  • Return a list of all handlers except handlers listneing to private events

    -
  • -
  • Left over print - oops :)

    -
  • -
  • Moved to examples/

    -
  • -
  • Re-added an old revived example of an IRC Client integrating the urwid -curses library for the interface

    -
  • -
  • Improved comment.

    -
  • -
  • Added multi-add support for Gateway web compnoent [Delivers #40071339]

    -
  • -
  • Fixed Python 3 compatibility for retrieving the .resumse() method. -Fixes Issue #35

    -
  • -
  • Removed unused StringIO import

    -
  • -
  • A bunch of Python 3.1 compatibility fixes (mostly import fixes)

    -
  • -
  • Added an example of using yield to perform cooperative multi-tasking -inside a request event handler

    -
  • -
  • Uses echo for test_process

    -
  • -
  • Fixes process stdout/stderr handling -Process was not waiting for all output from a process to have been -processed and resulted sometimes some of the process output being lost -while stopping.

    -
  • -
  • A bunch more Python 3 fixes. Using the six module here.

    -
  • -
  • Added a fall back error handler, so problems aren’t discarded -silently any more.

    -
  • -
  • Ooops accidently committed this

    -
  • -
  • Fixed some Python 3 import issues

    -
  • -
  • More Python 3 fixes

    -
  • -
  • Fixed Python 3 issue with iterators

    -
  • -
  • Use range for Python 3 compatibility

    -
  • -
  • Fixed assertions for Python 3 compat

    -
  • -
  • Accidently commited a test with Debugger

    -
  • -
  • Fixed value_changed handler to check correctly for binary types -(Python 3 fixes)

    -
  • -
  • Python 3 fixes for string type checks

    -
  • -
  • Refactored for Python 3

    -
  • -
  • More Python 3 fixes. Marked the rest as Broken on Python 3

    -
  • -
  • Fixed broken web tests for Python 3 by wrapping the request -body in a TextIOWrapper for FieldStorage

    -
  • -
  • Fixed XML and JSON RPC Dispatchers for Python 3

    -
  • -
  • Replace .has_key() with in for Python 3 compatibility

    -
  • -
  • Fixed a TypeError being raised in the request handler for websockets -dispatcher

    -
  • -
  • Prevent the underlying TCPClient connect handler from inadvertently -being triggered by connec events being fired to the web client

    -
  • -
  • Unmarked as skipping. No longer broken on Python 3

    -
  • -
  • Finished cleaning up my code base.

    -
  • -
  • Removed some debugging junk I had forgotten to get rid of.

    -
  • -
  • Fixed File for Python 3 support adding optional encoding support

    -
  • -
  • Fixed Process for Python 3

    -
  • -
  • Ooops :/

    -
  • -
  • Fixed test_logger_Error for Python 3

    -
  • -
  • Fixed Bridge for Python 3

    -
  • -
  • Fixed Node for Python 3

    -
  • -
  • Added pytest.PYVER and Marked test_secure_server web test as Broken -on Python 3.2 (needs fixing)

    -
  • -
  • Marked a bunch of 3.2 and 3.3 specific tests that are broken with -these versions (needs looking into)

    -
  • -
  • Removed Broken on Python 3 marked - these tests now pass on 3.1 3.2 and 3.3

    -
  • -
  • Fixed SSL Sockets for Python 3.2/3.3 (Should do_handshake() -be executed in a thread?)

    -
  • -
  • Added tox configuration file. Just run: run

    -
  • -
  • Configure tox to output junitxml

    -
  • -
  • Fixed tox configuration

    -
  • -
  • Assuming localhost was incorrect. Sorry Mark :/

    -
  • -
  • Fixed test_logger for pypy

    -
  • -
  • Backed out changeset 7be64d8b6f7c

    -
  • -
  • Reconfigured tox settings

    -
  • -
  • Hopefully fixed tox.ini to detect jenkins

    -
  • -
  • Fixed tox.ini to work on jenkins (can’t seem to auto detect jenkins :/)

    -
  • -
  • Added tox config for checking documetnation

    -
  • -
  • Changed the output filename of xml resutls for docs env (tox)

    -
  • -
  • Added pytest-cov as a dep to the docs env (tox)

    -
  • -
  • Configured coverage to output xml output

    -
  • -
  • Removed ptest-cov dep from docs env (tox)

    -
  • -
  • Trying to fix the randomly failing test_node test.

    -
  • -
  • Ooops broke wait_for - fixed hopefully

    -
  • -
  • Backed out changeset 795712654602

    -
  • -
  • Backed out changeset 1ee04d5fb657

    -
  • -
  • Added ignore for generated junitxml output files

    -
  • -
  • Hopefully an improved unit test for node using the manager and watcher -fixtures.

    -
  • -
  • Updated with supported version of Python

    -
  • -
  • Fixed the logic of path -> wsgi dispatching in Gateway

    -
  • -
  • Fixed an awful bug with wrappers.Response whereby -a default Content-Type was always set regardless and didn’t allow -anything else to set this.

    -
  • -
  • Fixed test_disps so it doesn’t use an existing port that’s in use.

    -
  • -
  • Added a missing piece of WSGI 1.0 functionality for wsgi.Gateway -– The write() callable

    -
  • -
  • Write bytes in this test

    -
  • -
  • Correctly handle unicode (I think)

    -
  • -
  • Fixed a bug with null responses from WSGI Applications -hosted by wsgi.Gateway. Empty class did not implement __nonzero__ -for Python 2.x [Delivers #43287263]

    -
  • -
  • Remvoed pyinotify dep from tox config so Windows tests can run

    -
  • -
  • Skip test_unixserver for Windows

    -
  • -
  • Skip this test on Windows

    -
  • -
  • Skip these tests on Windows

    -
  • -
  • Skip this test on Windows

    -
  • -
  • Fixed test_tcp_bind for Windows

    -
  • -
  • Updated docs and re-added FAQ from old wiki -(updated slightly) [Delivers #43389199]

    -
  • -
  • Fixed bottom of FAQ

    -
  • -
  • Updated Change Log [#42945315]

    -
  • -
  • Updated Release Notes [#42945315]

    -
  • -
  • Fixed list of new changes for 2.1.0 release notes

    -
  • -
  • Updated Developet Docs

    -
  • -
  • Bumped version to 2.1.0

    -
  • -
  • More resource efficient timer implementation [Delivers #43700669].

    -
  • -
  • Fixed a problem with cLength being unknown if self.body == False.

    -
  • -
  • Test fails on shining panda py32 only. May be a race condition -(wait_for using same loop interval as timer interval). -Checking in for testing.

    -
  • -
  • Fixed problem with “Content-Length: 0” header not being generated for -empty responses.

    -
  • -
  • Backed out of changeset 3575:ece3ee5472ef, makes CI hang for unknown reason.

    -
  • -
  • Hopefully finally fixed problems with timer test on CI platform.

    -
  • -
  • Updated pypi classifier for circuits

    -
  • -
  • Fixed random problems with opening SSL socket.

    -
  • -
  • Fixed concurrence problem (doing reset() in event loop and calling unregister() concurrently).

    -
  • -
  • Modified test a bit to find out what happens in CI environment -(problem not reproducible in local py32).

    -
  • -
  • Calling headers.setdefault twice for the same name doesn’t make sense.

    -
  • -
  • Adapted test case to previous fix.

    -
  • -
  • Fixed problem with “Content-Length: 0” header not being generated -for empty responses.

    -
  • -
  • Fixed insecure usage of class variable.

    -
  • -
  • Reverted to old timer implementation. Cannot find bug in new version -that only occurs in CI/py32 environment (cannot be reproduced locally).

    -
  • -
  • Make sure that check runs faster than timer increments.

    -
  • -
  • Added missing Content-Length header (must be present according to RFC 2616).

    -
  • -
  • Provide a more informative representation.

    -
  • -
  • Fixed a docstring typo

    -
  • -
  • Just re-raise the exception here rather than hide it with -an InternalServer exception

    -
  • -
  • Potential failing test for [#43885227]

    -
  • -
  • Fixed problem with receiving incomplete header data (first chunk doesn’t -already include empty line that separates headers and body).

    -
  • -
  • Fixed problem with header not being detected if a chunk ends exactly after -rn of last header line and next chunk starts with empty line (rn) -before body.

    -
  • -
  • Fixes inconsisent semantic behavior in channel selection.

    -
  • -
  • Fixed expression for _handler_channel in Manager.getHandlers(...)

    -
  • -
  • Fixed (and simplified) handler_channel evaluation.

    -
  • -
  • Fixed channel representation for cases where channel is a component.

    -
  • -
  • Adapted prepare_unregister_complete handling to fixed semantics for -using managers as channels.

    -
  • -
  • Notifications are to be signaled to the given manager. -Now that using managers as channels works properly, it showed that hey -never were.

    -
  • -
  • Value change notifications are fired using Value’s manager as channel, -so mke sure to listen on that.

    -
  • -
  • Value’s notifications are fired on its manager component -– by default the component that fired the event the value belongs to. -Moved handler to proper place (is better place anyway).

    -
  • -
  • Encoding is necessary for this to succeed on py3.2 -(urllib2 there doesn’t accept body of type str).

    -
  • -
  • Added missing files to manifest. [Delivers #44650895] (Closes Issue #36)

    -
  • -
  • Fixing encoding problems.

    -
  • -
  • Fixing py2/py3 problem by using bytearray as abviously the only -common denominator.

    -
  • -
  • multipart/form-data is binary. Boundaries are ASCII, -but data between boundaries may be anything (depending on part’s header)

    -
  • -
  • Trying to fix unicode issues

    -
  • -
  • Marked test_node as Broken on Windows - Pickling Error with thread.lock

    -
  • -
  • Trying to fix broken unit test on Windows

    -
  • -
  • Setup docs with Google Analyitics

    -
  • -
  • Marked test_tcp_connect_closed_port(...) as Broken on Windows -– Need to fix this; this test is a bit weird :/

    -
  • -
  • Marked test_tcp_reconnect(...) test as Broken on Windows

    -
  • -
  • Updated state of test_tcp_reconnect(...) test on Windows -– Apparently only Broken on Windows on Python 3.2 (odd)

    -
  • -
  • Fixed TypeError

    -
  • -
  • Marked as Broken on pypy -– For some reason we’re getting x00 (null bytes) -in the stream when using the Python std lib logger.

    -
  • -
  • Marked tests.core.test_debugger.test_filename(...) as Broken on pypy -– Need to investigate this

    -
  • -
  • Updated support platforms to include pypy

    -
  • -
-
-
-
-

circuits-2.0.1 20121124

-
    -
  • Fixed tests/web/test_main.py which was badly written.
  • -
  • Fixed a regression test testing the Debugger component
  • -
-
-
-

circuits-2.0.0 20121122 (cheetah)

-
    -
  • Fixed circuits.web entry point
  • -
  • Fixed tools.reprhandler() for compatibility with Python-3.3
  • -
  • Added *channels support to waitEvent
  • -
  • Added example of using .call
  • -
  • Fixed logic around firing the Daemonize event when registering this component during run-time and after start-up
  • -
  • Fixed use of reprhandler
  • -
  • Fixed listening channel for exceptions/errors.
  • -
  • Fixed channels for Log event.
  • -
  • Fixed config loading. Fire a Ready event when the Environment is completely ready.
  • -
  • Added .items(...) method to Config component.
  • -
  • Added BaseEvent, LiteralEvent, DerivedEvent to the core and circuits name-spaces
  • -
  • Fixed IRC protocol
  • -
  • Added has_option to Config component
  • -
  • Avoid error if user un-registers a component twice.
  • -
  • Fixed base_url for WebConsole
  • -
  • Fixed bug with sending Response for a Expect: 100-continue (Closes issue #32)
  • -
  • Added a new circuits.web test that ensures that large posts > 1024 bytes work
  • -
  • Updated conf so that doc can be built even if circuits isn’t installed
  • -
  • Updated reference of guide to howtos
  • -
  • Updated man headers so that they weren’t all “Components”
  • -
  • Fixed all web dispatcher tests
  • -
  • Fixed XMLRPC dispatcher. Must have a higher priority than the “default” dispatcher in order to coexist with it.
  • -
  • Fixed unit test for failure response from web component (component’s handler must have higher priority than default dispatcher if default dispatcher exists).
  • -
  • Added failure test for web controller.
  • -
  • Fixed JSON dispatcher. Must have a higher priority than the “default” dispatcher in order to coexist with it.
  • -
  • Fixed vpath traversal. vpath created in reverse (“test_args/1/2/3” became “3/2/1/test_args”).
  • -
  • Fixed evaluation of the Complete event: exclude events fired by other threads during event processing from the set of events to be tracked.
  • -
  • Don’t call tick on components that are waiting to be unregistered.
  • -
  • Using new PrepareUnregister event to reliably remove sockets from poller.
  • -
  • Fixes for PrepareUnregister and added test case.
  • -
  • Added event that informs components about going to be removed from the tree.
  • -
  • Fixed client request generation (MUST include Host header).
  • -
  • Fixed channel naming in web.Client to allow several clients (i.e. connections to web sites) to coexist in an application.
  • -
  • Prevented uncameling of event names that represent web requests. Handlers can now use the last path segment unmodified as handled event’s name.
  • -
  • Fixed the new dispatcher with new tests
  • -
  • Fixed bug in complete event generation.
  • -
  • Added optional event signaling the completion of an event and everything that has been caused by it.
  • -
  • Added the possibility to redirect the success events to other channels.
  • -
  • Updated documentation to reflect the new “handler suspend” feature.
  • -
  • Replaced web dispatcher with simpler version
  • -
  • Added support for x = yield self.callEvent(...)
  • -
  • Made test_main more reliable
  • -
  • Removed old BaseManager from playing with GreenletManager. Fixed test_manager_repr
  • -
  • Fixed the exceptions being thrown for test_eval, but the test still fails
  • -
  • Added a new failing test - evaluation of promised values
  • -
  • Removed superfluous .value in test_longwait
  • -
  • Added support for alllowing future handlers to have a “special” event parameter just like ordinary handlers.
  • -
  • Fixed test_success
  • -
  • Fixed test_removeHandler
  • -
  • Added support for firing Done() and Success() after all done executing.
  • -
  • Fixed callEvent
  • -
  • Added 2 failing tests for yield
  • -
  • Implemented promises which we detect for in circuits.web in cases where an event handler yields. Also only fire _success events after an event is well and truly finished (in the case of yielding event handlers)
  • -
  • Fixed a bug with value not being set
  • -
  • Fixed Issue #26
  • -
  • Added capability of waiting for a specific event name on a specific channel.
  • -
  • Fixed bug guarding against tasks already removed.
  • -
  • Implemented Component.init() support whereby one can define an alternative init() without needing to remember to call super(...)
  • -
  • Fixed Python 3 compatibility with Unicode strings
  • -
  • Added 99bottles as an example of concurrency. See: http://wiki.python.org/moin/Concurrency/99Bottles
  • -
  • Removed old-style channel targeting
  • -
  • Fixed and tested UDP forwarding
  • -
  • Simplified udpclient example
  • -
  • Implemented new version of port forwarded. TCP tested.
  • -
  • Fixed Read events for UDPServer by setting .notify to True.
  • -
  • Restructured the only How To Guide - Building a Simple Server
  • -
  • Renamed _get_request_handler to just find_handler
  • -
  • Removed channels attribute from WebEvents (fix for issue #29).
  • -
  • Added Eclipse configuration files.
  • -
  • Fixed uses of deprecated syntax in app.config
  • -
  • Modified the defaults for channels. Set channels to event.channels, otherwise self.channel defaulting to *
  • -
  • Fixed uses of deprecated syntax in env
  • -
  • Fixed a bug with the Redirect event/error in circuits.web where it didn’t handle Unicode strings
  • -
  • fixed the web dispatcher
  • -
  • Fixed test_poller_reuse test by using the now findtype() utility function
  • -
  • fixed and adds tests for the web dispatcher
  • -
  • Moved parseBody out into circuits.web.utils. Other code cleanup
  • -
  • Added a test for a bug with the dispatcher mehere found.
  • -
  • Removed itercmp() function. Added findtype() findchannel() and used better variable names. findcmp is an alias of findtype.
  • -
  • Implemented optional singleton support for components
  • -
  • Removed the circuits.web routes dispatcher as there are no tests for this and Routes dispatcher is broken - re implement at a later stage
  • -
  • Removal of End feedback event
  • -
  • Fixed web/test_value.py
  • -
  • Fixed web futures test
  • -
  • Simplified and fixed a lot of issues the circuits.bench
  • -
  • Fixed circuits.web’s exceptions tests and handling of exceptions.
  • -
  • Fixed a potential bug with circuits.web.wsgi.Application.
  • -
  • Modified Manager to only assign a handler return value if it is not None.
  • -
  • Fixed *_success and *_failure events fire on *event.channels so they go to the right place as expected. Fixed Issue #21
  • -
  • Removed event equality test and related tests. Seems rather useless and inconsistently used
  • -
  • Fixed test_gzip circuits.web test. We no longer have a Started event feedback so have to use a filter
  • -
  • Fixed a corner case where one might be trying to compare an event object with a non-event object
  • -
  • Fixed the event handling for circuits.web WebSockets Component by separating out the WebSockets handling from the HTTP handling (WebSocketsMediator).
  • -
  • Fixed use of Value notification in circuits.web for requests.
  • -
  • Fixed a bunch of examples and tests using deprecated features.
  • -
  • Fixed the notify io driver and removed Debugger() from test_notify.
  • -
  • Added man pages for circuits.bench, circuits.sniff and circuits.web
  • -
  • Wrapped UNIX-specific calls in try/except
  • -
  • Tidied up examples and removed unused imports
  • -
  • removed use of coverage module in daemon test
  • -
  • removed use of coverage module in signals test
  • -
  • updated .push calls to .fire calls
  • -
  • Fixed some deprecations warnings
  • -
  • Added support for multiple webserver with different channels + tests for it
  • -
  • Added support for silently ignoring errors when writing to stderr from debugger
  • -
  • Added requirements.txt file containing requirements for building docs on readthedocs.org
  • -
  • Added link to Read the Docs for circuits
  • -
  • Updated doc message for success event
  • -
  • Fixed interrupt handler to allow ^C to be used to quit sample keyecho app
  • -
  • Removed deprecated modules and functions that were deprecated 1.6
  • -
  • Deleted old style event success/failure notifiers
  • -
  • Fixed handling of components being added/removed when looking for ticks
  • -
  • Fixed bug with net.Server .host and .port attributes.
  • -
  • Deprecated __tick__. Event handlers can now be specified as tick functions.
  • -
  • Fixed handler priority inheritance to make sure we get the results in the right harder
  • -
  • Fixed missing import of sys in circuits.io
  • -
-
-
-

circuits-1.6 (oceans) - 20110626

-
    -
  • Added Python 3 support
  • -
  • 80% Code Coverage
  • -
  • Added optional greenlet support adding two new primitives. -.waitEvent(...) and .callEvent(...).
  • -
  • Added an example WebSockets server using circuits.web
  • -
  • Added support for specifying a Poll instance to use when using the -@future decorator to create “future” event handlers.
  • -
  • Added add_section, has_section and set methods to -app.config.Config Component.
  • -
  • Added support for running test suite with distutils python setup.py -test.
  • -
  • Added a _on_signal event handler on the BaseEnvironment Component -so that environments can be reloaded by listening to SIGHUP signals.
  • -
  • Added support for using absolute paths in app.env.Environment.
  • -
  • Added support in circuits.web HTTP protocol to limit the no. of -header fragments. This prevents OOM exploits.
  • -
  • Added a ticks limit to waitEvent
  • -
  • Added deprecation warnings for .push .add and .remove methods
  • -
  • NEW Loader Component in circuits.core for simple plugin support.
  • -
  • NEW app.env and app.config modules including a new app.startup -modules integrating a common startup for applications.
  • -
  • NEW KQueue poller
  • -
  • Fixed issue 17
  • -
  • Renamed circuits.web.main module to circuits.web.__main__ so that -python -m circuits.web just works.
  • -
  • Fixed Server.host and Server.port properties in -circuits.net.sockets.
  • -
  • Fixed issue 10
  • -
  • Fixed app.Daemon Component to correctly open the stderr file.
  • -
  • Fixed triggering of Success events.
  • -
  • Fixed duplicate broadcast handler in UDPServer
  • -
  • Fixed duplicate Disconnect event from being triggered twice on -Client socket components.
  • -
  • Removed dynamic timeout code from Select poller.
  • -
  • Fixed a bug in the circuits.web HTTP protocol where headers were -not being buffered per client.
  • -
  • Fixes a missing Event Closed() not being triggered for UDPServer.
  • -
  • Make underlying UDPServer socket reusable by setting SO_REUSEADDR
  • -
  • Fixes Server socket being discarded twice on close + disconnect
  • -
  • Socket.write now expects bytes (bytes for python3 and str for python2)
  • -
  • Better handling of encoding in HTTP Component (allow non utf-8 encoding)
  • -
  • Always encode HTTP headers in utf-8
  • -
  • Fixes error after getting socket.ERRCONNREFUSED
  • -
  • Allows TCPClient to bind to a specific port
  • -
  • Improved docs
  • -
  • Handles closing of UDPServer socket when no client is connected
  • -
  • Adds an un-register handler for components
  • -
  • Allows utils.kill to work from a different thread
  • -
  • Fixes bug when handling “*” in channels and targets
  • -
  • Fixes a bug that could occur when un-registering components
  • -
  • Fixes for CPU usage problems when using circuits with no I/O pollers -and using a Timer for timed events
  • -
-
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/contributors.html circuits-3.1.0+ds1/docs/build/html/contributors.html --- circuits-2.1.0/docs/build/html/contributors.html 2013-02-27 11:28:01.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/contributors.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,192 +0,0 @@ - - - - - - - - - Contributors — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

Contributors

-

circuits was originally designed, written and primarily maintained by James -Mills (http://prologic.shortcircuit.net.au/).

-

The following users and developers have contributed to circuits:

-
    -
  • Alessio Deiana
  • -
  • Dariusz Suchojad
  • -
  • Tim Miller
  • -
  • Holger Krekel
  • -
  • Justin Giorgi
  • -
  • Edwin Marshall
  • -
  • Alex Mayfield
  • -
  • Toni Alatalo
  • -
  • Michael Lipp
  • -
-

Anyone not listed here (apologies as this list is taken directly from -Mercurial’s churn command and output). We appreciate any and all -contributions to circuits.

-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/dev/contributing.html circuits-3.1.0+ds1/docs/build/html/dev/contributing.html --- circuits-2.1.0/docs/build/html/dev/contributing.html 2013-02-27 11:28:01.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/dev/contributing.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,227 +0,0 @@ - - - - - - - - - Contributing to circuits — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

Contributing to circuits

-

Here’s how you can contribute to circuits

-
-

Share your story

-

One of the best ways you can contribute to circuits is by using circuits. -Share with us your story of how you’ve used circuits to solve a problem -or create a new software solution using the circuits framework and library -of components. See our Users Page.

-
-
-

Submitting Bug Reports

-

We welcome all bug reports. We do however prefer bug reports in a clear -and concise form with repeatable steps. One of the best ways you can report -a bug to us is by writing a unit test (//similar to the ones in our tests//) -so that we can verify the bug, fix it and commit the fix along with the test.

-
-
To submit a bug report, please use:
-
http://bitbucket.org/prologic/circuits/issues
-
-
-
-

Writing new tests

-

We’re not perfect, and we’re still writing more tests to ensure quality code. -If you’d like to help, please Fork circuits-dev, write more tests that cover more of our code base and -submit a Pull Request. Many Thanks!

-
-
-

Adding New Features

-

If you’d like to see a new feature added to circutis, then we’d like to hear -about it~ We would like to see some discussion around any new features as well -as valid use-cases. To start the discussions off, please either:

- -
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/dev/index.html circuits-3.1.0+ds1/docs/build/html/dev/index.html --- circuits-2.1.0/docs/build/html/dev/index.html 2013-02-27 11:28:01.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/dev/index.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,203 +0,0 @@ - - - - - - - - - Developer Docs — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

Developer Docs

-

So, you’d like to contribute to circuits in some way? Got a bug report? -Having problems running the examples? Having problems getting circuits -working in your environment/platform?

-

Excellent. Here’s what you need to know.

- -
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/dev/introduction.html circuits-3.1.0+ds1/docs/build/html/dev/introduction.html --- circuits-2.1.0/docs/build/html/dev/introduction.html 2013-02-27 11:28:01.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/dev/introduction.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,211 +0,0 @@ - - - - - - - - - Development Introduction — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

Development Introduction

-

Here’s how we do things in circuits...

-
-

Standards

-

We use the following coding standard:

- -
-
-

Tools

-

We use the following tools to develop circuits and share code:

- -
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/dev/processes.html circuits-3.1.0+ds1/docs/build/html/dev/processes.html --- circuits-2.1.0/docs/build/html/dev/processes.html 2013-02-27 11:28:02.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/dev/processes.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,249 +0,0 @@ - - - - - - - - - Development Processes — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

Development Processes

-

We document all our internal development processes here so you know exactly -how we work and what to expect. If you find any issues or problems please -let us know!

-
-

Software Development Life Cycle (SDLC)

-

We employ the use of the SCRUM Agile Process and use Pivotal Tracker to track -our stories, bugs, chores and releases. If you wish to contribute -to circuits, please famiilarize yourself with SCRUM and Pivotal Tracker.

-
-
-

Bug Reports

- -
-
-

Feature Requests

- -
-
-

Writing new Code

-
    -
  • Write your code.

    -
  • -
  • Use flake8 to ensure code quality.

    -
  • -
  • Run the tests:

    -
    $ tox
    -
    -
  • -
  • Ensure any new or modified code does not break existing unit tests.

    -
  • -
  • Updated any relevant docstrings or documentatino.

    -
  • -
-
-
-

Running the Tests

-

To run the tests you will need the following installed:

- -

All of these can be instaleld via easy_isntall or pip.

-

Please also ensure that you you have all supported versions of Python -that circuits supports installed in your local environment.

-

To run the tests:

-
$ tox
-
-
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/_downloads/001.py circuits-3.1.0+ds1/docs/build/html/_downloads/001.py --- circuits-2.1.0/docs/build/html/_downloads/001.py 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_downloads/001.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,5 +0,0 @@ -#!/usr/bin/env python - -from circuits import Component - -Component().run() diff -Nru circuits-2.1.0/docs/build/html/_downloads/002.py circuits-3.1.0+ds1/docs/build/html/_downloads/002.py --- circuits-2.1.0/docs/build/html/_downloads/002.py 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_downloads/002.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,8 +0,0 @@ -#!/usr/bin/env python - -from circuits import Component - -class MyComponent(Component): - """My Component""" - -MyComponent().run() diff -Nru circuits-2.1.0/docs/build/html/_downloads/003.py circuits-3.1.0+ds1/docs/build/html/_downloads/003.py --- circuits-2.1.0/docs/build/html/_downloads/003.py 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_downloads/003.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -#!/usr/bin/env python - -from circuits import Component - -class MyComponent(Component): - - def started(self, *args): - print("Hello World!") - -MyComponent().run() diff -Nru circuits-2.1.0/docs/build/html/_downloads/004.py circuits-3.1.0+ds1/docs/build/html/_downloads/004.py --- circuits-2.1.0/docs/build/html/_downloads/004.py 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_downloads/004.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,15 +0,0 @@ -#!/usr/bin/env python - -from circuits import Component - -class Bob(Component): - - def started(self, *args): - print("Hello I'm Bob!") - -class Fred(Component): - - def started(self, *args): - print("Hello I'm Fred!") - -(Bob() + Fred()).run() diff -Nru circuits-2.1.0/docs/build/html/_downloads/005.py circuits-3.1.0+ds1/docs/build/html/_downloads/005.py --- circuits-2.1.0/docs/build/html/_downloads/005.py 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_downloads/005.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,27 +0,0 @@ -#!/usr/bin/env python - -from circuits import Component -from circuits.tools import graph - -class Pound(Component): - - def __init__(self): - super(Pound, self).__init__() - - self.bob = Bob().register(self) - self.fred = Fred().register(self) - - def started(self, *args): - print(graph(self.root)) - -class Bob(Component): - - def started(self, *args): - print("Hello I'm Bob!") - -class Fred(Component): - - def started(self, *args): - print("Hello I'm Fred!") - -Pound().run() diff -Nru circuits-2.1.0/docs/build/html/_downloads/006.py circuits-3.1.0+ds1/docs/build/html/_downloads/006.py --- circuits-2.1.0/docs/build/html/_downloads/006.py 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_downloads/006.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,35 +0,0 @@ -#!/usr/bin/env python - -from circuits import Component, Event - - -class Woof(Event): - """Woof Event""" - - -class Pound(Component): - - def __init__(self): - super(Pound, self).__init__() - - self.bob = Bob().register(self) - self.fred = Fred().register(self) - - def started(self, *args): - self.fire(Woof()) - - -class Dog(Component): - - def woof(self): - print("Woof! I'm %s!" % self.name) - - -class Bob(Dog): - """Bob""" - - -class Fred(Dog): - """Fred""" - -Pound().run() diff -Nru circuits-2.1.0/docs/build/html/_downloads/007.py circuits-3.1.0+ds1/docs/build/html/_downloads/007.py --- circuits-2.1.0/docs/build/html/_downloads/007.py 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_downloads/007.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,39 +0,0 @@ -#!/usr/bin/env python - -from circuits import Component, Event - - -class Woof(Event): - """Woof Event""" - - -class Pound(Component): - - def __init__(self): - super(Pound, self).__init__() - - self.bob = Bob().register(self) - self.fred = Fred().register(self) - - def started(self, *args): - self.fire(Woof(), self.bob) - - -class Dog(Component): - - def woof(self): - print("Woof! I'm %s!" % self.name) - - -class Bob(Dog): - """Bob""" - - channel = "bob" - - -class Fred(Dog): - """Fred""" - - channel = "fred" - -Pound().run() diff -Nru circuits-2.1.0/docs/build/html/_downloads/008.py circuits-3.1.0+ds1/docs/build/html/_downloads/008.py --- circuits-2.1.0/docs/build/html/_downloads/008.py 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_downloads/008.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,34 +0,0 @@ -#!/usr/bin/env python - -from circuits import Component, Event - -class Bark(Event): - """Bark Event""" - -class Pound(Component): - - def __init__(self): - super(Pound, self).__init__() - - self.bob = Bob().register(self) - self.fred = Fred().register(self) - -class Dog(Component): - - def started(self, *args): - self.fire(Bark()) - - def bark(self): - print("Woof! I'm %s!" % self.name) - -class Bob(Dog): - """Bob""" - - channel = "bob" - -class Fred(Dog): - """Fred""" - - channel = "fred" - -Pound().run() diff -Nru circuits-2.1.0/docs/build/html/_downloads/009.py circuits-3.1.0+ds1/docs/build/html/_downloads/009.py --- circuits-2.1.0/docs/build/html/_downloads/009.py 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_downloads/009.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,34 +0,0 @@ -#!/usr/bin/env python - -from circuits import Component, Event - -class Bark(Event): - """Bark Event""" - -class Pound(Component): - - def __init__(self): - super(Pound, self).__init__() - - self.bob = Bob().register(self) - self.fred = Fred().register(self) - -class Dog(Component): - - def started(self, *args): - self.fire(Bark()) - - def bark(self): - print("Woof! I'm %s!" % name) - -class Bob(Dog): - """Bob""" - - channel = "bob" - -class Fred(Dog): - """Fred""" - - channel = "fred" - -Pound().run() diff -Nru circuits-2.1.0/docs/build/html/_downloads/handler_annotation.py circuits-3.1.0+ds1/docs/build/html/_downloads/handler_annotation.py --- circuits-2.1.0/docs/build/html/_downloads/handler_annotation.py 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_downloads/handler_annotation.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,18 +0,0 @@ -#!/usr/bin/env python - -from circuits.core.debugger import Debugger -from circuits.core.components import BaseComponent -from circuits.core.handlers import handler - -class MyComponent(BaseComponent): - - def __init__(self): - super(MyComponent, self).__init__() - - Debugger().register(self) - - @handler("started", channel="*") - def _on_started(self, component): - print "Start event detected" - -MyComponent().run() diff -Nru circuits-2.1.0/docs/build/html/_downloads/handler_returns.py circuits-3.1.0+ds1/docs/build/html/_downloads/handler_returns.py --- circuits-2.1.0/docs/build/html/_downloads/handler_returns.py 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_downloads/handler_returns.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,40 +0,0 @@ -#!/usr/bin/env python - -from circuits import Component, Event -from circuits.core.debugger import Debugger - -class Identify(Event): - """Identify Event""" - success = True - -class Pound(Component): - - def __init__(self): - super(Pound, self).__init__() - - Debugger().register(self) - Bob().register(self) - Fred().register(self) - - def started(self, *args): - self.fire(Identify()) - - def identify_success(self, evt, result): - if not isinstance(result, list): - result = [result] - print "In pound:" - for name in result: - print name - -class Dog(Component): - - def identify(self): - return self.__class__.__name__ - -class Bob(Dog): - """Bob""" - -class Fred(Dog): - """Fred""" - -Pound().run() diff -Nru circuits-2.1.0/docs/build/html/_downloads/simple_server.py circuits-3.1.0+ds1/docs/build/html/_downloads/simple_server.py --- circuits-2.1.0/docs/build/html/_downloads/simple_server.py 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_downloads/simple_server.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ -#!/usr/bin/env python - -from circuits import Component -from circuits.net.sockets import TCPServer, Write - -class Server(Component): - - def __init__(self, host, port=8000): - super(Server, self).__init__() - - self._clients = [] - - TCPServer((host, port)).register(self) - - def connect(self, sock, host, port): - self._clients.append(sock) - - def disconnect(self, sock): - self._clients.remove(sock) - - def read(self, sock, data): - for client in self._clients: - if not client == sock: - self.fire(Write(client, data.strip())) - -Server("localhost").run() diff -Nru circuits-2.1.0/docs/build/html/faq.html circuits-3.1.0+ds1/docs/build/html/faq.html --- circuits-2.1.0/docs/build/html/faq.html 2013-02-27 11:28:02.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/faq.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,221 +0,0 @@ - - - - - - - - - Frequently Asked Questions — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

Frequently Asked Questions

-
-

General

-
-
... What is circuits?
-
circuits is an event-driven framework with a high focus on Component -architectures making your life as a software developer much easier. -circuits allows you to write maintainable and scalable systems easily
-
... Can I write networking applications with circuits?
-
Yes absolutely. circuits comes with socket I/O components for tcp, udp -and unix sockets with asynchronous polling implementations for select, -poll, epoll and kqueue.
-
... Can I integrate circuits with a GUI library?
-
This is entirely possible. You will have to hook into the GUI’s main loop.
-
... What are the core concepts in circuits?
-
Components and Events. Components are maintainable reusable units of -behavior that communicate with other components via a powerful message -passing system.
-
... How would you compare circuits to Twisted?
-
Others have said that circuits is very elegant in terms of it’s usage. -circuits’ component architecture allows you to define clear interfaces -between components while maintaining a high level of scalability and -maintainability.
-
... Can Components communicate with other processes?
-
Yes. circuits implements currently component bridging and nodes
-
... What platforms does circuits support?
-
circuits currently supports Linux, FreeBSD, OSX and Windows and is -currently continually tested against Linux and Windows against Python -versions 2.6, 2.7, 3.1 and 3.2
-
... Can circuits be used for concurrent or distributed programming?
-
Yes. We also have plans to build more distributed components into circuits -making distributing computing with circuits very trivial.
-
-

Got more questions?

- -
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/genindex.html circuits-3.1.0+ds1/docs/build/html/genindex.html --- circuits-2.1.0/docs/build/html/genindex.html 2013-02-27 11:28:03.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/genindex.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,1623 +0,0 @@ - - - - - - - - - - - Index — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - -
-
- - -
-
-
-
- - -

Index

- -
- _ - | A - | B - | C - | D - | E - | F - | G - | H - | I - | J - | K - | L - | M - | N - | O - | P - | Q - | R - | S - | T - | U - | V - | W - | X - -
-

_

- - - -
- -
_on_httperror() (circuits.web.http.HTTP method) -
- - -
_on_read() (circuits.web.http.HTTP method) -
- -
- -
_on_request_success() (circuits.web.http.HTTP method) -
- - -
_on_response() (circuits.web.http.HTTP method) -
- -
- -

A

- - - -
- -
AcceptElement (class in circuits.web.headers) -
- - -
Accessed (class in circuits.io.notify) -
- -
- -
add_header() (circuits.web.headers.Headers method) -
- - -
Application (class in circuits.web.wsgi) -
- -
- -

B

- - - -
- -
BadGateway -
- - -
BadRequest -
- - -
BaseComponent (class in circuits.core.components) -
- - -
BasePoller (class in circuits.core.pollers) -
- -
- -
BaseServer (class in circuits.web.servers) -
- - -
basic_auth() (in module circuits.web.tools) -
- - -
Body (class in circuits.web.wrappers) -
- - -
broadcast() (circuits.net.sockets.UDPServer method) -
- -
- -

C

- - - -
- -
call() (circuits.core.manager.Manager method) -
- - -
callEvent() (circuits.core.manager.Manager method) -
- - -
channel (circuits.net.sockets.Client attribute) -
- -
- -
(circuits.net.sockets.Server attribute) -
- - -
(circuits.web.client.Client attribute) -
- - -
(circuits.web.websocket.WebSocketClient attribute) -
- -
- -
check_auth() (in module circuits.web.tools) -
- - -
circuits.app (module) -
- - -
circuits.app.config (module) -
- - -
circuits.app.daemon (module) -
- - -
circuits.app.env (module) -
- - -
circuits.app.log (module) -
- - -
circuits.core (module) -
- - -
circuits.core.components (module) -
- - -
circuits.core.debugger (module) -
- - -
circuits.core.events (module) -
- - -
circuits.core.handlers (module) -
- - -
circuits.core.loader (module) -
- - -
circuits.core.manager (module) -
- - -
circuits.core.pollers (module) -
- - -
circuits.core.timers (module) -
- - -
circuits.core.utils (module) -
- - -
circuits.core.values (module) -
- - -
circuits.core.workers (module) -
- - -
circuits.io (module) -
- - -
circuits.io.events (module) -
- - -
circuits.io.file (module) -
- - -
circuits.io.notify (module) -
- - -
circuits.io.serial (module) -
- - -
circuits.net (module) -
- - -
circuits.net.protocols (module) -
- - -
circuits.net.protocols.http (module) -
- - -
circuits.net.protocols.irc (module) -
- - -
circuits.net.protocols.line (module) -
- - -
circuits.net.sockets (module) -
- - -
circuits.node (module) -
- - -
circuits.node.client (module) -
- - -
circuits.node.events (module) -
- - -
circuits.node.node (module) -
- - -
circuits.node.server (module) -
- - -
circuits.node.utils (module) -
- - -
circuits.tools (module) -
- -
- -
circuits.web (module) -
- - -
circuits.web.client (module) -
- - -
circuits.web.constants (module) -
- - -
circuits.web.controllers (module) -
- - -
circuits.web.dispatchers.dispatcher (module) -
- - -
circuits.web.dispatchers.jsonrpc (module) -
- - -
circuits.web.dispatchers.static (module) -
- - -
circuits.web.dispatchers.virtualhosts (module) -
- - -
circuits.web.dispatchers.websockets (module) -
- - -
circuits.web.dispatchers.xmlrpc (module) -
- - -
circuits.web.errors (module) -
- - -
circuits.web.events (module) -
- - -
circuits.web.exceptions (module) -
- - -
circuits.web.headers (module) -
- - -
circuits.web.http (module) -
- - -
circuits.web.loggers (module) -
- - -
circuits.web.main (module) -
- - -
circuits.web.servers (module) -
- - -
circuits.web.sessions (module) -
- - -
circuits.web.tools (module) -
- - -
circuits.web.utils (module) -
- - -
circuits.web.websocket (module) -
- - -
circuits.web.wrappers (module) -
- - -
circuits.web.wsgi (module) -
- - -
Client (class in circuits.net.sockets) -
- -
- -
(class in circuits.node.client) -
- - -
(class in circuits.web.client) -
- -
- -
Close (class in circuits.io.events) -
- -
- -
(class in circuits.net.sockets) -
- -
- -
close() (circuits.net.sockets.Client method) -
- -
- -
(circuits.net.sockets.Server method) -
- - -
(circuits.net.sockets.UDPServer method) -
- - -
(circuits.web.client.Client method) -
- - -
(circuits.web.websocket.WebSocketClient method) -
- -
- -
Closed (class in circuits.io.events) -
- -
- -
(class in circuits.io.notify) -
- - -
(class in circuits.net.sockets) -
- -
- -
Component (class in circuits.core.components) -
- - -
compress() (in module circuits.web.utils) -
- - -
Config (class in circuits.app.config) -
- - -
Connect (class in circuits.net.sockets) -
- - -
connect() (circuits.net.sockets.TCPClient method) -
- -
- -
(circuits.net.sockets.UNIXClient method) -
- - -
(circuits.web.client.Client method) -
- -
- -
connected (circuits.net.sockets.Client attribute) -
- -
- -
(circuits.net.sockets.Server attribute) -
- - -
(circuits.web.client.Client attribute) -
- - -
(circuits.web.websocket.WebSocketClient attribute) -
- -
- -
Connected (class in circuits.net.sockets) -
- - -
Controller (class in circuits.web.controllers) -
- - -
Create (class in circuits.app.env) -
- - -
create() (circuits.web.events.Request class method) -
- - -
Created (class in circuits.io.notify) -
- -
- -

D

- - - -
- -
Daemon (class in circuits.app.daemon) -
- - -
Daemonize (class in circuits.app.daemon) -
- - -
Debugger (class in circuits.core.debugger) -
- - -
Deleted (class in circuits.io.notify) -
- - -
dictform() (in module circuits.web.utils) -
- - -
digest_auth() (in module circuits.web.tools) -
- -
- -
Disconnect (class in circuits.net.sockets) -
- - -
Disconnected (class in circuits.net.sockets) -
- - -
Dispatcher (class in circuits.web.dispatchers.dispatcher) -
- - -
dump_event() (in module circuits.node.utils) -
- - -
dump_value() (in module circuits.node.utils) -
- -
- -

E

- - - -
- -
elements() (circuits.web.headers.Headers method) -
- - -
Environment (class in circuits.app.env) -
- - -
EOF (class in circuits.io.events) -
- - -
EPoll (class in circuits.core.pollers) -
- - -
Error (class in circuits.core.events) -
- -
- -
(class in circuits.io.events) -
- -
-
- -
Event (class in circuits.core.events) -
- - -
expires() (in module circuits.web.tools) -
- - -
expose() (in module circuits.web.controllers) -
- - -
exposeJSON() (in module circuits.web.controllers) -
- -
- -

F

- - - -
- -
Failure (class in circuits.core.events) -
- - -
File (class in circuits.io.file) -
- - -
file_generator() (in module circuits.web.wrappers) -
- - -
findchannel() (in module circuits.core.utils) -
- - -
findcmp() (in module circuits.core.utils) -
- - -
findroot() (in module circuits.core.utils) -
- - -
findtype() (in module circuits.core.utils) -
- - -
fire() (circuits.core.manager.Manager method) -
- -
- -
fireEvent() (circuits.core.manager.Manager method) -
- - -
flatten() (in module circuits.core.utils) -
- - -
flush() (circuits.core.manager.Manager method) -
- - -
flushEvents() (circuits.core.manager.Manager method) -
- - -
Forbidden -
- -
- -
(class in circuits.web.errors) -
- -
- -
formattime() (in module circuits.web.loggers) -
- - -
from_str() (circuits.web.headers.HeaderElement class method) -
- -
- -

G

- - - -
- -
Gateway (class in circuits.web.wsgi) -
- - -
GenerateEvents (class in circuits.core.events) -
- - -
get() (circuits.web.headers.Headers method) -
- - -
get_all() (circuits.web.headers.Headers method) -
- -
- -
get_ranges() (in module circuits.web.utils) -
- - -
Gone -
- - -
graph() (in module circuits.tools) -
- - -
gzip() (in module circuits.web.tools) -
- -
- -

H

- - - -
- -
handler() (in module circuits.core.handlers) -
- - -
HandlerMetaClass (class in circuits.core.handlers) -
- - -
handlers() (circuits.core.components.BaseComponent class method) -
- - -
handles() (circuits.core.components.BaseComponent class method) -
- - -
has_key() (circuits.web.headers.Headers method) -
- - -
header_elements() (in module circuits.web.headers) -
- - -
HeaderElement (class in circuits.web.headers) -
- -
- -
Headers (class in circuits.web.headers) -
- - -
host (circuits.net.sockets.Server attribute) -
- - -
Host (class in circuits.web.wrappers) -
- - -
HTTP (class in circuits.net.protocols.http) -
- -
- -
(class in circuits.web.http) -
- -
- -
HTTPError (class in circuits.web.errors) -
- - -
HTTPException -
- -
- -

I

- - - -
- -
in_subtree() (circuits.core.components.PrepareUnregister method) -
- - -
InternalServerError -
- -
- -
IRC (class in circuits.net.protocols.irc) -
- - -
items() (circuits.web.headers.Headers method) -
- -
- -

J

- - - -
- -
JSONController (class in circuits.web.controllers) -
- -
- -
JSONRPC (class in circuits.web.dispatchers.jsonrpc) -
- -
- -

K

- - -
- -
keys() (circuits.web.headers.Headers method) -
- -
- -

L

- - - -
- -
LengthRequired -
- - -
Line (class in circuits.net.protocols.line) -
- - -
line() (circuits.net.protocols.irc.IRC method) -
- - -
Load (class in circuits.app.config) -
- -
- -
(class in circuits.app.env) -
- -
- -
load_event() (in module circuits.node.utils) -
- -
- -
load_value() (in module circuits.node.utils) -
- - -
Loader (class in circuits.core.loader) -
- - -
Log (class in circuits.app.log) -
- - -
Logger (class in circuits.app.log) -
- -
- -
(class in circuits.web.loggers) -
- -
- -
LP (class in circuits.net.protocols.line) -
- -
- -

M

- - - -
- -
Manager (class in circuits.core.manager) -
- - -
MethodNotAllowed -
- -
- -
Modified (class in circuits.io.notify) -
- - -
Moved (class in circuits.io.notify) -
- -
- -

N

- - - -
- -
name (circuits.core.manager.Manager attribute) -
- - -
Node (class in circuits.node.node) -
- - -
NotAcceptable -
- -
- -
NotFound -
- -
- -
(class in circuits.web.errors) -
- -
- -
Notify (class in circuits.io.notify) -
- - -
NotImplemented -
- -
- -

O

- - -
- -
Opened (class in circuits.io.events) -
- -
- -
(class in circuits.io.notify) -
- -
-
- -

P

- - - -
- -
Packet (class in circuits.node.events) -
- - -
parse() (circuits.web.headers.HeaderElement static method) -
- - -
parse_bind_parameter() (circuits.net.sockets.Client method) -
- -
- -
(circuits.net.sockets.Server method) -
- - -
(circuits.net.sockets.TCPServer method) -
- -
- -
parse_body() (in module circuits.web.utils) -
- - -
parse_headers() (in module circuits.web.headers) -
- - -
parse_qs() (in module circuits.web.utils) -
- -
- -
pid (circuits.core.manager.Manager attribute) -
- - -
Pipe() (in module circuits.net.sockets) -
- - -
Poll (class in circuits.core.pollers) -
- - -
port (circuits.net.sockets.Server attribute) -
- - -
PreconditionFailed -
- - -
PrepareUnregister (class in circuits.core.components) -
- -
- -

Q

- - -
- -
qvalue (circuits.web.headers.AcceptElement attribute) -
- -
- -

R

- - - -
- -
RAW (class in circuits.net.protocols.irc) -
- - -
Read (class in circuits.io.events) -
- -
- -
(class in circuits.net.sockets) -
- -
- -
ready() (circuits.net.sockets.UNIXClient method) -
- - -
Redirect -
- -
- -
(class in circuits.web.errors) -
- -
- -
reduce_time_left() (circuits.core.events.GenerateEvents method) -
- - -
register() (circuits.core.components.BaseComponent method) -
- - -
Registered (class in circuits.core.events) -
- - -
Remote (class in circuits.node.events) -
- - -
reprhandler() (in module circuits.core.handlers) -
- - -
Request (class in circuits.net.protocols.http) -
- -
- -
(class in circuits.web.client) -
- - -
(class in circuits.web.events) -
- - -
(class in circuits.web.wrappers) -
- -
-
- -
request() (circuits.web.client.Client method) -
- - -
RequestEntityTooLarge -
- - -
RequestTimeout -
- - -
RequestURITooLarge -
- - -
reset() (circuits.core.timers.Timer method) -
- - -
response (circuits.web.client.Client attribute) -
- - -
Response (class in circuits.net.protocols.http) -
- -
- -
(class in circuits.web.events) -
- - -
(class in circuits.web.wrappers) -
- -
- -
RPC (class in circuits.web.dispatchers.jsonrpc) -
- -
- -
(class in circuits.web.dispatchers.xmlrpc) -
- -
- -
run() (circuits.core.manager.Manager method) -
- - -
running (circuits.core.manager.Manager attribute) -
- -
- -

S

- - - -
- -
safeimport() (in module circuits.core.utils) -
- - -
Save (class in circuits.app.config) -
- - -
Seek (class in circuits.io.events) -
- - -
Select (class in circuits.core.pollers) -
- - -
Serial (class in circuits.io.serial) -
- - -
serve_download() (in module circuits.web.tools) -
- - -
serve_file() (in module circuits.web.tools) -
- - -
server (circuits.web.wrappers.Request attribute) -
- - -
Server (class in circuits.net.sockets) -
- -
- -
(class in circuits.node.server) -
- - -
(class in circuits.web.servers) -
- -
- -
ServiceUnavailable -
- - -
Sessions (class in circuits.web.sessions) -
- - -
setdefault() (circuits.web.headers.Headers method) -
- -
- -
Signal (class in circuits.core.events) -
- - -
SingletonError (class in circuits.core.components) -
- - -
socket_family (circuits.net.sockets.TCPClient attribute) -
- -
- -
(circuits.net.sockets.TCPServer attribute) -
- - -
(circuits.net.sockets.UDPServer attribute) -
- -
- -
SocketError (class in circuits.net.sockets) -
- - -
start() (circuits.core.manager.Manager method) -
- - -
Started (class in circuits.core.events) -
- - -
Static (class in circuits.web.dispatchers.static) -
- - -
stop() (circuits.core.manager.Manager method) -
- - -
Stopped (class in circuits.core.events) -
- - -
Stream (class in circuits.web.events) -
- - -
Success (class in circuits.core.events) -
- -
- -

T

- - - -
- -
Task (class in circuits.core.workers) -
- - -
TCPClient (class in circuits.net.sockets) -
- - -
TCPServer (class in circuits.net.sockets) -
- -
- -
tick() (circuits.core.manager.Manager method) -
- - -
time_left (circuits.core.events.GenerateEvents attribute) -
- - -
Timer (class in circuits.core.timers) -
- -
- -

U

- - - -
- -
UDPClient (in module circuits.net.sockets) -
- - -
UDPServer (class in circuits.net.sockets) -
- - -
Unauthorized -
- -
- -
(class in circuits.web.errors) -
- -
- -
UnicodeError -
- - -
UNIXClient (class in circuits.net.sockets) -
- - -
UNIXServer (class in circuits.net.sockets) -
- -
- -
Unmounted (class in circuits.io.notify) -
- - -
Unregister (class in circuits.core.events) -
- - -
unregister() (circuits.core.components.BaseComponent method) -
- - -
Unregistered (class in circuits.core.events) -
- - -
UnsupportedMediaType -
- - -
url() (in module circuits.web.utils) -
- -
- -

V

- - - -
- -
validate_etags() (in module circuits.web.tools) -
- - -
validate_since() (in module circuits.web.tools) -
- - -
Value (class in circuits.core.values) -
- -
- -
values() (circuits.web.headers.Headers method) -
- - -
VCS -
- - -
VirtualHosts (class in circuits.web.dispatchers.virtualhosts) -
- -
- -

W

- - - -
- -
WebEvent (class in circuits.web.events) -
- - -
WebSocketClient (class in circuits.web.websocket) -
- - -
WebSockets (class in circuits.web.dispatchers.websockets) -
- - -
Worker (class in circuits.core.workers) -
- -
- -
Write (class in circuits.io.events) -
- -
- -
(class in circuits.net.sockets) -
- -
- -
write() (circuits.net.sockets.Client method) -
- -
- -
(circuits.net.sockets.Server method) -
- - -
(circuits.net.sockets.UDPServer method) -
- - -
(circuits.web.client.Client method) -
- -
- -
WritePID (class in circuits.app.daemon) -
- -
- -

X

- - -
- -
XMLRPC (class in circuits.web.dispatchers.xmlrpc) -
- -
- - - -
-
-
- -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/glossary.html circuits-3.1.0+ds1/docs/build/html/glossary.html --- circuits-2.1.0/docs/build/html/glossary.html 2013-02-27 11:28:02.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/glossary.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,179 +0,0 @@ - - - - - - - - - Glossary — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

Glossary

-
-
VCS
-
Version Control System, what you use for versioning your source code
-
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/howtos/index.html circuits-3.1.0+ds1/docs/build/html/howtos/index.html --- circuits-2.1.0/docs/build/html/howtos/index.html 2013-02-27 11:28:02.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/howtos/index.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,180 +0,0 @@ - - - - - - - - - HowTos — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- - - - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/howtos/simple_server.html circuits-3.1.0+ds1/docs/build/html/howtos/simple_server.html --- circuits-2.1.0/docs/build/html/howtos/simple_server.html 2013-02-27 11:28:02.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/howtos/simple_server.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,353 +0,0 @@ - - - - - - - - - How To: Build a Simple Server — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

How To: Build a Simple Server

-
-

Overview

-

In this guide we’re going to walk through the steps required to build a -simple chat server. Users will connect using a standard telnet client and -start chatting with other users that are connected.

-
-

Prerequisites

- -
-

Components Used

- -
-
-

Events Used

- -
-
-
-
-

Step 1 - Setting up

-

Let’s start off by importing the components and events we’ll need.

-
#!/usr/bin/env python
-
-from circuits import Component
-from circuits.net.sockets import TCPServer, Write
-
-
-
-
-

Step 2 - Building the Server

-

Next let’s define our Server Component with a simple event handler that -broadcasts all incoming messages to every connected client. We’ll keep a list -of clients connected to our server in self._clients.

-

We need to define three event handlers.

-
    -
  1. An event handler to update our list of connected clients when a new client -connects.
  2. -
  3. An event handler to update our list of connected clients when a client has -disconnected.
  4. -
  5. An event handler to handle messages from connected clients and broadcast -them to every other connected client.
  6. -
-
class Server(Component):
-
-    def __init__(self, host, port=8000):
-        super(Server, self).__init__()
-
-        self._clients = []
-
-        TCPServer((host, port)).register(self)
-
-    def connect(self, sock, host, port):
-        self._clients.append(sock)
-
-    def disconnect(self, sock):
-        self._clients.remove(sock)
-
-    def read(self, sock, data):
-        for client in self._clients:
-            if not client == sock:
-                self.fire(Write(client, data.strip()))
-
-
-

Let’s walk through this in details:

-
    -
  1. Create a new Component called Server
  2. -
  3. Define its initialization arguments as (host, port=8000)
  4. -
  5. Call the super constructor of the underlying Component -(This is important as all components need to be initialized properly)
  6. -
  7. Register a TCPServer Component and configure it.
  8. -
  9. Create Event Handlers for:
      -
    • Dealing with new connecting clients.
    • -
    • Dealing with clients whom have disconnected.
    • -
    • Dealing with messages from connected clients.
    • -
    -
  10. -
-
-
-

Step 3 - Running the Server

-

The last step is simply to create an instance of the Server Component -and run it (making sure to configure it with a host and port).

-
Server("localhost").run()
-
-
-

That’s it!

-

Using a standard telnet client try connecting to localhost on port 8000. -Try connecting a second client and watch what happens in the 2nd client -when you type text into the 1st.

-

Enjoy!

-
-
-

Source Code

-
 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
#!/usr/bin/env python
-
-from circuits import Component
-from circuits.net.sockets import TCPServer, Write
-
-class Server(Component):
-
-    def __init__(self, host, port=8000):
-        super(Server, self).__init__()
-
-        self._clients = []
-
-        TCPServer((host, port)).register(self)
-
-    def connect(self, sock, host, port):
-        self._clients.append(sock)
-
-    def disconnect(self, sock):
-        self._clients.remove(sock)
-
-    def read(self, sock, data):
-        for client in self._clients:
-            if not client == sock:
-                self.fire(Write(client, data.strip()))
-
-Server("localhost").run()
-
-
-

Download simple_server.py

-
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/html/_images/graphviz-fa9bbccfbcc0c44bc0636e85a3c610dc406600cf.png and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/html/_images/graphviz-fa9bbccfbcc0c44bc0636e85a3c610dc406600cf.png differ diff -Nru circuits-2.1.0/docs/build/html/_images/graphviz-fa9bbccfbcc0c44bc0636e85a3c610dc406600cf.png.map circuits-3.1.0+ds1/docs/build/html/_images/graphviz-fa9bbccfbcc0c44bc0636e85a3c610dc406600cf.png.map --- circuits-2.1.0/docs/build/html/_images/graphviz-fa9bbccfbcc0c44bc0636e85a3c610dc406600cf.png.map 2013-02-27 11:15:10.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_images/graphviz-fa9bbccfbcc0c44bc0636e85a3c610dc406600cf.png.map 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ - - Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/html/_images/web.png and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/html/_images/web.png differ diff -Nru circuits-2.1.0/docs/build/html/index.html circuits-3.1.0+ds1/docs/build/html/index.html --- circuits-2.1.0/docs/build/html/index.html 2013-02-27 11:28:02.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/index.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,251 +0,0 @@ - - - - - - - - - circuits 2.1.0 Documentation — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

circuits 2.1.0 Documentation

- --- - - - - - -
Release:2.1.0
Date:February 27, 2013
-
-

Overview

-

circuits is a Lightweight Event driven and Asynchronous -Application Framework for the Python Programming Language -with a strong Component Architecture.

-

circuits also includes a lightweight, high performance and scalable -HTTP/WSGI compliant web server as well as various I/O and Networking -components.

-

To take full advantage of circuits and its architecture, circuits -encourages you to design your application in terms of loosely coupled -components. Circuits has a very powerful message passing system that -enables components to interact with each other via events. Applications -written this way tend to be more maintainable, easier to develop and -scale to complex systems.

-

circuits’ Loosely Coupled Component Architecture allows for a -high level of Reuse and Scalability. Simpler components can be -combined together to form Complex Components and provide higher level -functionality and abstraction. Much of the circuits component library is -designed and built this way.

- -
-
-

Features

-
    -
  • event driven
  • -
  • concurrency support
  • -
  • component architecture
  • -
  • asynchronous I/O components
  • -
  • no required external dependencies
  • -
  • full featured web framework (circuits.web)
  • -
  • coroutine based synchronization primitives
  • -
-
-
-

Requirements

- -
-
-

Supported Platforms

-
    -
  • Linux, FreeBSD, Mac OS X
  • -
  • Python 2.6, 2.7, 3.2, 3.3
  • -
  • pypy 2.0
  • -
-
-
Windows: We acknowledge that Windows exists and make reasonable efforts
-
to maintain compatibility. Unfortunately we cannot guarantee -support at this time.
-
-

NB: We are working toward getting Windows supported.

-
-
-

Installation

-

The simplest and recommended way to install circuits is with pip. -You may install the latest stable release from PyPI with pip:

-
> pip install circuits
-
-

If you do not have pip, you may use easy_install:

-
> easy_install circuits
-
-

Alternatively, you may download the source package from the -PyPi Page or the Downloads page on the -Website; extract it and install using:

-
> python setup.py install
-
-
-
-

License

-

circuits is licensed under the MIT License.

-
-
-

Feedback

-

We welcome any questions or feedback about bugs and suggestions on how to -improve circuits. Let us know what you think about circuits. @pythoncircuits.

-

Do you have suggestions for improvement? Then please Create an Issue -with details of what you would like to see. I’ll take a look at it and -work with you to either incorporate the idea or find a better solution.

-
-
-

Community

-

There is also a small community of circuits enthusiasts that you may -find on the #circuits IRC Channel on the FreeNode IRC Network -and the Mailing List.

- -
-

Indices and tables

- -
-
-
- - -
-
-
- - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/man/components.html circuits-3.1.0+ds1/docs/build/html/man/components.html --- circuits-2.1.0/docs/build/html/man/components.html 2013-02-27 11:28:02.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/man/components.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,204 +0,0 @@ - - - - - - - - - Components — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

Components

-

The architectural concept of circuits is to encapsulate system -functionality into discrete manageable and reusable units, called Components, -that interact by sending and handling events that flow throughout the system.

-

Technically, a circuits Component is a Python class that inherits -(directly or indirectly) from -BaseComponent.

-

Components can be sub-classed like any other normal Python class, however -components can also be composed of other components and it is natural -to do so. These are called Complex Components. An example of a Complex -Component within the circuits library is the -circuits.web.servers.Server Component which is comprised of:

- -

Note that there is no class or other technical means to mark a component -as a complex component. Rather, all component instances in a circuits -based application belong to some component tree (there may be several), -with Complex Components being a subtree within that structure.

-

A Component is attached to the tree by registering with the parent and -detached by un-registering itself (methods -register() and -unregister() of -BaseComponent).

-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/man/debugging.html circuits-3.1.0+ds1/docs/build/html/man/debugging.html --- circuits-2.1.0/docs/build/html/man/debugging.html 2013-02-27 11:28:02.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/man/debugging.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,178 +0,0 @@ - - - - - - - - - Debugging — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

Debugging

-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/man/events.html circuits-3.1.0+ds1/docs/build/html/man/events.html --- circuits-2.1.0/docs/build/html/man/events.html 2013-02-27 11:28:02.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/man/events.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,336 +0,0 @@ - - - - - - - - - Events — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

Events

-
-

Basic usage

-

Events are objects that are fired by the circuits framework implicitly -(like the Started event used in the tutorial) -or explicitly by components while handling some other event. Once fired, -events are dispatched to the components that are interested in these events, -i.e. that have registered themselves as handlers for these events.

-

Events are usually fired on one or more channels, allowing components -to gather in “interest groups”. This is especially useful if you want to -reuse basic components such as a TCP server. A TCP server component -fires a Read event for every package of data that it receives. If we -hadn’t the channels, it would be very difficult to separate the data from -two different TCP connections. But using the channels, we can put one TCP -server and all components interested in its events on one channel, and -another TCP server and the components interested in this other TCP server’s -events on another channel. Components are associated with a channel by -setting their channel attribute (see API description for -Component).

-

Besides having a name, events carry additional arbitrary information. -This information is passed as arguments or keyword arguments to the -constructor. It is then delivered to the handler function that must have -exactly the same number of arguments and keyword arguments. Of course, -as is usual in Python, you can also pass additional information by setting -attributes of the event object, though this usage pattern is discouraged -for events.

-
-
-

Events as result collectors

-

Apart from delivering information to handlers, event objects may also collect -information. If a handler returns something that is not None, it is -stored in the event’s value attribute. If a second (or any subsequent) -handler invocation also returns a value, the values are stored as a list. -Note that the value attribute is of type Value and you -must access its property value to access the data stored -(collected_information = event.value.value).

-

The collected information can be accessed by handlers in order to find out -about any return values from the previously invoked handlers. More useful -though, is the possibility to access the information after all handlers -have been invoked. After all handlers have run successfully (i.e. no -handler has thrown an error) circuits may generate an event that indicates -the successful handling. This event has the name of the event -just handled with “Success” appended. So if the event is called Identify -then the success event is called IdentifySuccess. Success events aren’t -delivered by default. If you want successful handling to be indicated -for an event, you have to set the optional attribute success of this -event to True.

-

The handler for a success event must be defined with two arguments. When -invoked, the first argument is the event just having been handled -successfully and the second argument is (as a convenience) what has been -collected in event.value.value (note that the first argument may not -be called event, for an explanation of this restriction as well as -for an explanation why the method is called identify_success -see the section on handlers).

-
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
-40
#!/usr/bin/env python
-
-from circuits import Component, Event
-from circuits.core.debugger import Debugger
-
-class Identify(Event):
-    """Identify Event"""
-    success = True
-
-class Pound(Component):
-
-    def __init__(self):
-        super(Pound, self).__init__()
-
-        Debugger().register(self)
-        Bob().register(self)
-        Fred().register(self)
-
-    def started(self, *args):
-        self.fire(Identify())
-        
-    def identify_success(self, evt, result):
-        if not isinstance(result, list):
-            result = [result]
-        print "In pound:"
-        for name in result:
-            print name
-
-class Dog(Component):
-
-    def identify(self):
-        return self.__class__.__name__
-
-class Bob(Dog):
-    """Bob"""
-
-class Fred(Dog):
-    """Fred"""
-
-Pound().run()
-
-
-

Download handler_returns.py

-
-
-

Advanced usage

-

Sometimes it may be necessary to take some action when all state changes -triggered by an event are in effect. In this case it is not sufficient -to wait for the completion of all handlers for this particular event. -Rather, we also have to wait until all events that have been fired by -those handlers have been processed (and again wait for the events fired by -those events’ handlers, and so on). To support this scenario, circuits -can fire a Complete event. The usage is similar to the previously -described success event. Details can be found in the API description of -circuits.core.events.Event.

-
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/man/handlers.html circuits-3.1.0+ds1/docs/build/html/man/handlers.html --- circuits-2.1.0/docs/build/html/man/handlers.html 2013-02-27 11:28:02.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/man/handlers.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,280 +0,0 @@ - - - - - - - - - Handlers — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

Handlers

-
-

Explicit Event Handlers

-

Event Handlers are methods of components that are invoked when a matching -event is dispatched. These can be declared explicitly on a -BaseComponent or -Component or by using the -handler() decorator.

-
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
#!/usr/bin/env python
-
-from circuits.core.debugger import Debugger
-from circuits.core.components import BaseComponent
-from circuits.core.handlers import handler
-
-class MyComponent(BaseComponent):
-
-    def __init__(self):
-        super(MyComponent, self).__init__()
-
-        Debugger().register(self)
-
-    @handler("started", channel="*")
-    def _on_started(self, component):
-        print "Start event detected"
-
-MyComponent().run()
-
-
-

Download handler_annotation.py

-

The handler decorator on line 14 turned the method _on_started into an -event handler for the event Started. Event names used to define -handlers are the uncameled class names of the event. An event with a class -name MySpecialEvent becomes “my_special_event” when referred to -in a handler definition.

-

When defining explicit event handlers in this way, it’s convention to -use the following pattern:

-
@handler("foo")
-def _on_foo(self, ...):
-   ...
-
-
-

This makes reading code clear and concise and obvious to the reader -that the method is not part of the class’s public API -(leading underscore as per Python convention) and that it is invoked -for events of type SomeEvent.

-

The optional keyword argument “channel” can be used to attach the -handler to a different channel than the component’s channel -(as specified by the component’s channel attribute).

-

Handler methods must be declared with arguments and keyword arguments that -match the arguments passed to the event upon its creation. Looking at the -API for Started you’ll find that the -component that has been started is passed as an argument to its constructor. -Therefore, our handler method must declare one argument (Line 15).

-

The @handler(...) decorator accepts other keyword arguments that -influence the behavior of the event handler and its invocation. Details can -be found in the API description of handler().

-
-
-

Implicit Event Handlers

-

To make things easier for the developer when creating many event handlers -and thus save on some typing, the Component -can be used and subclassed instead which provides an implicit mechanism for -creating event handlers.

-

Basically every method in the component is automatically and implicitly -marked as an event handler with @handler(<name)) where <name>> is -the name of each method applied.

-

The only exceptions are:

-
    -
  • Methods are start with an underscore _.
  • -
  • Methods already marked explicitly with the @handler(...) decorator.
  • -
-
-

Note

-

You can specify that a method not be an event handler by marking it with -@handler(False).

-
-
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/man/index.html circuits-3.1.0+ds1/docs/build/html/man/index.html --- circuits-2.1.0/docs/build/html/man/index.html 2013-02-27 11:28:02.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/man/index.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,193 +0,0 @@ - - - - - - - - - The circuits Framework — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
- - - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/man/manager.html circuits-3.1.0+ds1/docs/build/html/man/manager.html --- circuits-2.1.0/docs/build/html/man/manager.html 2013-02-27 11:28:02.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/man/manager.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,178 +0,0 @@ - - - - - - - - - Manager — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

Manager

-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/man/tools.html circuits-3.1.0+ds1/docs/build/html/man/tools.html --- circuits-2.1.0/docs/build/html/man/tools.html 2013-02-27 11:28:02.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/man/tools.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,178 +0,0 @@ - - - - - - - - - Tools — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

Tools

-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/man/values.html circuits-3.1.0+ds1/docs/build/html/man/values.html --- circuits-2.1.0/docs/build/html/man/values.html 2013-02-27 11:28:02.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/man/values.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,178 +0,0 @@ - - - - - - - - - Values — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

Values

-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/html/objects.inv and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/html/objects.inv differ diff -Nru circuits-2.1.0/docs/build/html/py-modindex.html circuits-3.1.0+ds1/docs/build/html/py-modindex.html --- circuits-2.1.0/docs/build/html/py-modindex.html 2013-02-27 11:28:04.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/py-modindex.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,469 +0,0 @@ - - - - - - - - - Python Module Index — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
- - -
-
-
-
- - -

Python Module Index

- -
- c -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
- c
- circuits -
    - circuits.app -
    - circuits.app.config -
    - circuits.app.daemon -
    - circuits.app.env -
    - circuits.app.log -
    - circuits.core -
    - circuits.core.components -
    - circuits.core.debugger -
    - circuits.core.events -
    - circuits.core.handlers -
    - circuits.core.loader -
    - circuits.core.manager -
    - circuits.core.pollers -
    - circuits.core.timers -
    - circuits.core.utils -
    - circuits.core.values -
    - circuits.core.workers -
    - circuits.io -
    - circuits.io.events -
    - circuits.io.file -
    - circuits.io.notify -
    - circuits.io.serial -
    - circuits.net -
    - circuits.net.protocols -
    - circuits.net.protocols.http -
    - circuits.net.protocols.irc -
    - circuits.net.protocols.line -
    - circuits.net.sockets -
    - circuits.node -
    - circuits.node.client -
    - circuits.node.events -
    - circuits.node.node -
    - circuits.node.server -
    - circuits.node.utils -
    - circuits.tools -
    - circuits.web -
    - circuits.web.client -
    - circuits.web.constants -
    - circuits.web.controllers -
    - circuits.web.dispatchers.dispatcher -
    - circuits.web.dispatchers.jsonrpc -
    - circuits.web.dispatchers.static -
    - circuits.web.dispatchers.virtualhosts -
    - circuits.web.dispatchers.websockets -
    - circuits.web.dispatchers.xmlrpc -
    - circuits.web.errors -
    - circuits.web.events -
    - circuits.web.exceptions -
    - circuits.web.headers -
    - circuits.web.http -
    - circuits.web.loggers -
    - circuits.web.main -
    - circuits.web.servers -
    - circuits.web.sessions -
    - circuits.web.tools -
    - circuits.web.utils -
    - circuits.web.websocket -
    - circuits.web.wrappers -
    - circuits.web.wsgi -
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/pypitest.html circuits-3.1.0+ds1/docs/build/html/pypitest.html --- circuits-2.1.0/docs/build/html/pypitest.html 2013-02-27 11:28:02.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/pypitest.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,295 +0,0 @@ - - - - - - - - - PyPi Test Page - Tentative Release — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

PyPi Test Page - Tentative Release

-
-

Overview

-

circuits is a Lightweight Event driven and Asynchronous -Application Framework for the Python Programming Language -with a strong Component Architecture.

-

circuits also includes a lightweight, high performance and scalable -HTTP/WSGI compliant web server as well as various I/O and Networking -components.

-

To take full advantage of circuits and its architecture, circuits -encourages you to design your application in terms of loosely coupled -components. Circuits has a very powerful message passing system that -enables components to interact with each other via events. Applications -written this way tend to be more maintainable, easier to develop and -scale to complex systems.

-

circuits’ Loosely Coupled Component Architecture allows for a -high level of Reuse and Scalability. Simpler components can be -combined together to form Complex Components and provide higher level -functionality and abstraction. Much of the circuits component library is -designed and built this way.

- -
-
-

Features

-
    -
  • event driven
  • -
  • concurrency support
  • -
  • component architecture
  • -
  • asynchronous I/O components
  • -
  • no required external dependencies
  • -
  • full featured web framework (circuits.web)
  • -
  • coroutine based synchronization primitives
  • -
-
-
-

Requirements

- -
-
-

Supported Platforms

-
    -
  • Linux, FreeBSD, Mac OS X
  • -
  • Python 2.6, 2.7, 3.2, 3.3
  • -
  • pypy 2.0
  • -
-
-
Windows: We acknowledge that Windows exists and make reasonable efforts
-
to maintain compatibility. Unfortunately we cannot guarantee -support at this time.
-
-

NB: We are working toward getting Windows supported.

-
-
-

Installation

-

The simplest and recommended way to install circuits is with pip. -You may install the latest stable release from PyPI with pip:

-
> pip install circuits
-
-

If you do not have pip, you may use easy_install:

-
> easy_install circuits
-
-

Alternatively, you may download the source package from the -PyPi Page or the Downloads page on the -Website; extract it and install using:

-
> python setup.py install
-
-
-
-

License

-

circuits is licensed under the MIT License.

-
-
-

Feedback

-

We welcome any questions or feedback about bugs and suggestions on how to -improve circuits. Let us know what you think about circuits. @pythoncircuits.

-

Do you have suggestions for improvement? Then please Create an Issue -with details of what you would like to see. I’ll take a look at it and -work with you to either incorporate the idea or find a better solution.

-
-
-

Community

-

There is also a small community of circuits enthusiasts that you may -find on the #circuits IRC Channel on the FreeNode IRC Network -and the Mailing List.

-
-
-

Release Notes - circuits-2.1.0 (<release>)

-

This release adds the following new features to circuits:

-
    -
  • Python 3 support.
  • -
  • Windows support.
  • -
  • PyPy support.
  • -
  • IPv6 support.
  • -
  • Better WSGI support.
  • -
  • Fully documented examples.
  • -
  • Component Interface querying.
  • -
-

And many bug fixes!

-
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/search.html circuits-3.1.0+ds1/docs/build/html/search.html --- circuits-2.1.0/docs/build/html/search.html 2013-02-27 11:28:04.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/search.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,140 +0,0 @@ - - - - - - - - - Search — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - - -
-
- - -
-
-
- -
-
- -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/searchindex.js circuits-3.1.0+ds1/docs/build/html/searchindex.js --- circuits-2.1.0/docs/build/html/searchindex.js 2013-02-27 11:28:04.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/searchindex.js 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -Search.setIndex({objects:{"circuits.web.headers":{HeaderElement:[63,1,1,""],Headers:[63,1,1,""],header_elements:[63,4,1,""],parse_headers:[63,4,1,""],AcceptElement:[63,1,1,""]},"circuits.core.debugger":{Debugger:[17,1,1,""]},"circuits.net.sockets.UDPServer":{write:[68,2,1,""],close:[68,2,1,""],broadcast:[68,2,1,""],socket_family:[68,3,1,""]},"circuits.web.websocket":{WebSocketClient:[51,1,1,""]},"circuits.core.components.PrepareUnregister":{in_subtree:[48,2,1,""]},"circuits.web.exceptions":{Redirect:[84,5,1,""],NotFound:[84,5,1,""],RequestURITooLarge:[84,5,1,""],HTTPException:[84,5,1,""],Unauthorized:[84,5,1,""],Gone:[84,5,1,""],LengthRequired:[84,5,1,""],RequestTimeout:[84,5,1,""],PreconditionFailed:[84,5,1,""],RequestEntityTooLarge:[84,5,1,""],NotAcceptable:[84,5,1,""],ServiceUnavailable:[84,5,1,""],BadRequest:[84,5,1,""],InternalServerError:[84,5,1,""],UnicodeError:[84,5,1,""],UnsupportedMediaType:[84,5,1,""],BadGateway:[84,5,1,""],Forbidden:[84,5,1,""],MethodNotAllowed:[84,5,1,""],NotImplemented:[84,5,1,""]},"circuits.app.config":{Load:[89,1,1,""],Save:[89,1,1,""],Config:[89,1,1,""]},"circuits.io.notify":{Unmounted:[61,1,1,""],Created:[61,1,1,""],Deleted:[61,1,1,""],Moved:[61,1,1,""],Modified:[61,1,1,""],Notify:[61,1,1,""],Closed:[61,1,1,""],Accessed:[61,1,1,""],Opened:[61,1,1,""]},"circuits.web.errors":{Redirect:[44,1,1,""],NotFound:[44,1,1,""],Forbidden:[44,1,1,""],HTTPError:[44,1,1,""],Unauthorized:[44,1,1,""]},"circuits.core.values":{Value:[36,1,1,""]},"circuits.app":{daemon:[29,0,1,""],config:[89,0,1,""],log:[5,0,1,""],env:[79,0,1,""]},"circuits.net.sockets.TCPClient":{connect:[68,2,1,""],socket_family:[68,3,1,""]},"circuits.core.events.GenerateEvents":{reduce_time_left:[69,2,1,""],time_left:[69,3,1,""]},"circuits.web.headers.AcceptElement":{qvalue:[63,3,1,""]},"circuits.node.client":{Client:[77,1,1,""]},"circuits.app.log":{Logger:[5,1,1,""],Log:[5,1,1,""]},"circuits.node.node":{Node:[15,1,1,""]},"circuits.core.components":{SingletonError:[48,1,1,""],Component:[48,1,1,""],BaseComponent:[48,1,1,""],PrepareUnregister:[48,1,1,""]},"circuits.web.headers.HeaderElement":{parse:[63,6,1,""],from_str:[63,7,1,""]},"circuits.web.websocket.WebSocketClient":{close:[51,2,1,""],connected:[51,3,1,""],channel:[51,3,1,""]},"circuits.net.protocols":{line:[16,0,1,""],irc:[4,0,1,""],http:[45,0,1,""]},"circuits.node.server":{Server:[25,1,1,""]},"circuits.web.http.HTTP":{"_on_httperror":[24,2,1,""],"_on_request_success":[24,2,1,""],"_on_response":[24,2,1,""],"_on_read":[24,2,1,""]},"circuits.node.events":{Remote:[35,1,1,""],Packet:[35,1,1,""]},"circuits.web.dispatchers.virtualhosts":{VirtualHosts:[3,1,1,""]},"circuits.web.dispatchers":{jsonrpc:[59,0,1,""],xmlrpc:[66,0,1,""],virtualhosts:[3,0,1,""],"static":[14,0,1,""],dispatcher:[26,0,1,""],websockets:[67,0,1,""]},"circuits.web.controllers":{JSONController:[81,1,1,""],exposeJSON:[81,4,1,""],expose:[81,4,1,""],Controller:[81,1,1,""]},"circuits.core.components.BaseComponent":{unregister:[48,2,1,""],handles:[48,7,1,""],register:[48,2,1,""],handlers:[48,7,1,""]},"circuits.web.tools":{expires:[90,4,1,""],basic_auth:[90,4,1,""],validate_etags:[90,4,1,""],serve_download:[90,4,1,""],serve_file:[90,4,1,""],validate_since:[90,4,1,""],gzip:[90,4,1,""],digest_auth:[90,4,1,""],check_auth:[90,4,1,""]},"circuits.web.dispatchers.static":{Static:[14,1,1,""]},"circuits.core.events":{Unregistered:[69,1,1,""],Registered:[69,1,1,""],Success:[69,1,1,""],Started:[69,1,1,""],Signal:[69,1,1,""],Unregister:[69,1,1,""],GenerateEvents:[69,1,1,""],Failure:[69,1,1,""],Stopped:[69,1,1,""],Error:[69,1,1,""],Event:[69,1,1,""]},"circuits.web.wrappers.Request":{server:[41,3,1,""]},"circuits.web.client":{Client:[49,1,1,""],Request:[49,1,1,""]},"circuits.net.protocols.irc.IRC":{line:[4,2,1,""]},"circuits.node.utils":{load_value:[56,4,1,""],dump_event:[56,4,1,""],dump_value:[56,4,1,""],load_event:[56,4,1,""]},"circuits.io.serial":{Serial:[83,1,1,""]},"circuits.web.http":{HTTP:[24,1,1,""]},"circuits.app.env":{Environment:[79,1,1,""],Load:[79,1,1,""],Create:[79,1,1,""]},"circuits.core.manager":{Manager:[32,1,1,""]},"circuits.net.sockets.TCPServer":{parse_bind_parameter:[68,2,1,""],socket_family:[68,3,1,""]},"circuits.web.events":{Stream:[54,1,1,""],Request:[54,1,1,""],Response:[54,1,1,""],WebEvent:[54,1,1,""]},"circuits.net":{sockets:[68,0,1,""],protocols:[10,0,1,""]},"circuits.app.daemon":{WritePID:[29,1,1,""],Daemon:[29,1,1,""],Daemonize:[29,1,1,""]},"circuits.core.utils":{findcmp:[30,4,1,""],findchannel:[30,4,1,""],safeimport:[30,4,1,""],findroot:[30,4,1,""],findtype:[30,4,1,""],flatten:[30,4,1,""]},"circuits.io.file":{File:[80,1,1,""]},"circuits.web.headers.Headers":{elements:[63,2,1,""],setdefault:[63,2,1,""],get_all:[63,2,1,""],keys:[63,2,1,""],items:[63,2,1,""],get:[63,2,1,""],add_header:[63,2,1,""],has_key:[63,2,1,""],values:[63,2,1,""]},"circuits.web.events.Request":{create:[54,7,1,""]},"circuits.io.events":{EOF:[19,1,1,""],Read:[19,1,1,""],Write:[19,1,1,""],Closed:[19,1,1,""],Error:[19,1,1,""],Close:[19,1,1,""],Seek:[19,1,1,""],Opened:[19,1,1,""]},"circuits.web.dispatchers.dispatcher":{Dispatcher:[26,1,1,""]},"circuits.net.sockets":{SocketError:[68,1,1,""],TCPClient:[68,1,1,""],Disconnect:[68,1,1,""],UDPClient:[68,3,1,""],UNIXClient:[68,1,1,""],Read:[68,1,1,""],TCPServer:[68,1,1,""],Server:[68,1,1,""],Write:[68,1,1,""],Pipe:[68,4,1,""],Client:[68,1,1,""],Connected:[68,1,1,""],Connect:[68,1,1,""],Closed:[68,1,1,""],UDPServer:[68,1,1,""],Close:[68,1,1,""],UNIXServer:[68,1,1,""],Disconnected:[68,1,1,""]},"circuits.core.timers":{Timer:[40,1,1,""]},"circuits.core.timers.Timer":{reset:[40,2,1,""]},"circuits.net.protocols.http":{Request:[45,1,1,""],HTTP:[45,1,1,""],Response:[45,1,1,""]},"circuits.core.pollers":{Poll:[8,1,1,""],EPoll:[8,1,1,""],Select:[8,1,1,""],BasePoller:[8,1,1,""]},"circuits.core.loader":{Loader:[23,1,1,""]},"circuits.web.wrappers":{Body:[41,1,1,""],Host:[41,1,1,""],Request:[41,1,1,""],Response:[41,1,1,""],file_generator:[41,4,1,""]},"circuits.node":{node:[15,0,1,""],utils:[56,0,1,""],client:[77,0,1,""],events:[35,0,1,""],server:[25,0,1,""]},"circuits.web.sessions":{Sessions:[39,1,1,""]},"circuits.web.loggers":{Logger:[1,1,1,""],formattime:[1,4,1,""]},"circuits.core":{workers:[50,0,1,""],"debugger":[17,0,1,""],handlers:[22,0,1,""],utils:[30,0,1,""],loader:[23,0,1,""],manager:[32,0,1,""],values:[36,0,1,""],components:[48,0,1,""],timers:[40,0,1,""],pollers:[8,0,1,""],events:[69,0,1,""]},"circuits.web.utils":{parse_qs:[55,4,1,""],compress:[55,4,1,""],parse_body:[55,4,1,""],url:[55,4,1,""],dictform:[55,4,1,""],get_ranges:[55,4,1,""]},"circuits.web.servers":{BaseServer:[70,1,1,""],Server:[70,1,1,""]},"circuits.net.sockets.Server":{write:[68,2,1,""],host:[68,3,1,""],connected:[68,3,1,""],close:[68,2,1,""],parse_bind_parameter:[68,2,1,""],port:[68,3,1,""],channel:[68,3,1,""]},circuits:{node:[58,0,1,""],core:[18,0,1,""],web:[87,0,1,""],app:[21,0,1,""],io:[7,0,1,""],net:[91,0,1,""],tools:[53,0,1,""]},"circuits.net.sockets.Client":{write:[68,2,1,""],close:[68,2,1,""],connected:[68,3,1,""],channel:[68,3,1,""],parse_bind_parameter:[68,2,1,""]},"circuits.net.protocols.irc":{RAW:[4,1,1,""],IRC:[4,1,1,""]},"circuits.net.sockets.UNIXClient":{ready:[68,2,1,""],connect:[68,2,1,""]},"circuits.io":{serial:[83,0,1,""],events:[19,0,1,""],file:[80,0,1,""],notify:[61,0,1,""]},"circuits.core.manager.Manager":{callEvent:[32,2,1,""],run:[32,2,1,""],name:[32,3,1,""],fire:[32,2,1,""],pid:[32,3,1,""],stop:[32,2,1,""],start:[32,2,1,""],running:[32,3,1,""],call:[32,2,1,""],flush:[32,2,1,""],flushEvents:[32,2,1,""],tick:[32,2,1,""],fireEvent:[32,2,1,""]},"circuits.web.wsgi":{Application:[72,1,1,""],Gateway:[72,1,1,""]},"circuits.tools":{graph:[53,4,1,""]},"circuits.web.dispatchers.jsonrpc":{RPC:[59,1,1,""],JSONRPC:[59,1,1,""]},"circuits.web.client.Client":{request:[49,2,1,""],write:[49,2,1,""],connected:[49,3,1,""],connect:[49,2,1,""],close:[49,2,1,""],response:[49,3,1,""],channel:[49,3,1,""]},"circuits.web.dispatchers.websockets":{WebSockets:[67,1,1,""]},"circuits.web":{wrappers:[41,0,1,""],loggers:[1,0,1,""],wsgi:[72,0,1,""],errors:[44,0,1,""],websocket:[51,0,1,""],sessions:[39,0,1,""],utils:[55,0,1,""],servers:[70,0,1,""],controllers:[81,0,1,""],headers:[63,0,1,""],client:[49,0,1,""],exceptions:[84,0,1,""],http:[24,0,1,""],main:[46,0,1,""],tools:[90,0,1,""],events:[54,0,1,""],constants:[88,0,1,""]},"circuits.core.handlers":{HandlerMetaClass:[22,1,1,""],handler:[22,4,1,""],reprhandler:[22,4,1,""]},"circuits.web.dispatchers.xmlrpc":{RPC:[66,1,1,""],XMLRPC:[66,1,1,""]},"circuits.net.protocols.line":{Line:[16,1,1,""],LP:[16,1,1,""]},"circuits.core.workers":{Task:[50,1,1,""],Worker:[50,1,1,""]}},terms:{content_length:55,abvious:52,prefix:[3,17],sleep:52,artbritrari:52,kqueue:[12,52],typeerror:[52,69],sorri:52,under:[37,13,52],everi:[5,74,54,61,69,89,19,47,29,45,66,79,78,59,32,16,35],mime_typ:90,upstream:84,affect:16,configev:89,"__nonzero__":52,ooop:52,readthedoc:52,miller:75,direct:[53,32],preconditionfail:84,enjoi:47,second:[90,32,16,74,47],follow:[90,42,28,75,2,13,76,11,78,32,65,16,60],panda:52,even:[22,52],hide:52,tipl:16,neg:32,weren:52,petri:86,"new":[0,4,79,32,60,36,38,8,63,41,42,84,13,44,47,48,68,17,49,50,23,52],net:[68,37,86,75,85,82,91,13,51,47,4,45,10,52,16],tcpclient:[68,51,52,16],widget:[37,13],subtre:[85,48],behavior:[5,42,54,61,69,12,19,29,45,48,89,79,78,59,52,16,35,66],never:[68,42,52,84],here:[42,38,0,75,2,65,52,60],debugg:[17,18,42,74,78,52],path:[68,67,55,49,70,3,79,29,14,66,41,23,59,90,52],interpret:52,datetim:[40,90],sturctur:53,time_left:69,brought:52,unix:[70,12,52],"_on_foo":78,txt:52,unit:[52,12,38,60,85],describ:74,would:[37,74,38,12,13,22,84,52],call:[90,42,74,55,69,85,4,66,84,59,32,52,47],typo:52,recommend:[28,8,42,13,37],type:[74,54,29,79,78,59,35,5,37,61,16,66,84,42,13,45,89,90,47,69,19,22,52],until:[27,69,40,74,22,24,32],init_arg:23,notif:[36,61,52,7,20],notic:42,warn:[90,52],test_process:52,moin:52,hold:[5,54,61,69,89,19,29,45,66,41,79,59,90,16,35],must:[5,27,54,61,69,79,19,74,89,29,4,22,66,45,63,78,59,90,52,16,35],accid:52,restor:52,setup:[28,51,13,52,37],work:[42,28,0,50,37,13,76,73,52,16,60,86],rework:52,root:[42,55,2,76,30,22,32,52,48],overrid:[5,54,61,69,89,19,29,22,66,45,79,59,16,35],give:42,synchron:[37,13],indic:[37,74,55,69,90,32],liter:[53,54,55,1,56,3,79,67,77,29,30,45,58,59,32,35,5,80,61,39,81,40,7,91,8,63,66,41,10,72,36,84,44,83,87,14,88,46,89,90,15,16,48,69,68,17,18,49,50,70,19,4,21,51,22,23,24,25,26],unavail:84,want:[68,42,74,69,22,84],end:[53,32,52],coroutin:[37,13,52],ordinari:[51,52],length:[52,84],classifi:52,how:[37,38,42,11,65,12,13,47,64,52,16,60],fireev:[42,32,48],env:[42,74,21,79,78,52,47],cheetah:52,ancestor:48,config:[89,52,81,21],updat:[28,69,47,32,52,16,60],timedelta:90,after:[27,40,74,29,22,24,52,32,48],lab:86,diagram:42,badli:52,wrong:52,demonstr:[2,52],attempt:84,classmethod:[63,54,48],credenti:90,exclud:52,perform:[37,28,50,13,76,41,32,52,90],maintain:[37,75,12,13,32,48],environ:[79,52,0,60,21],incorpor:[37,13],order:[74,22,63,41,90,52],origin:[5,54,55,69,75,79,19,63,29,45,66,89,61,59,52,16,35],sslserver:52,feedback:[37,13,52],over:[59,52,16,66],failur:[51,54,52,69],findchannel:[30,52],appar:52,dictform:55,flexibl:[70,27],digest:90,connec:52,fix:[38,63,13,52],"__class__":[17,74,80,81,50,41,23,32,72,16,48],inadvert:52,better:[37,13,52],"__handleev":42,persist:[40,39],easier:[78,37,12,13,42],them:[42,52,47,67],basemanag:52,thei:[69,50,63,84,52,48],proce:52,"break":[90,60],promis:[36,52],interrupt:[22,52,69],alex:75,changelog:[37,52],timeout:[8,83,52,32,84],each:[17,27,55,37,42,13,78,32,16],debug:[31,17,52,53],went:84,famiilar:60,side:[68,24],mean:[42,32,48,85],resum:[52,69],forgot:52,extract:[37,13],network:[37,38,82,12,13,91,10,52],content:[37,63,84,24,52,90],rewrit:52,adapt:[52,84],reader:78,got:[12,0],navig:2,situat:42,standard:[37,0,2,13,20,44,84,24,65,47],resums:52,findroot:30,md5:90,reconfigur:52,workaround:52,traceback:[69,84],filter:[17,22,52,69],unabl:84,regress:52,onto:3,writepid:29,rang:[55,52],render:[20,84],independ:[84,50],thereof:24,restrict:74,hook:12,instruct:11,alreadi:[40,42,78,52,90],wrapper:[87,52,41],payload:52,badrequest:84,tox:[52,60],top:32,sometim:[32,52,74],mercuri:[11,65,75],too:[63,52,84],listen:[68,42,4,52,67],namespac:76,tool:[42,27,0,53,2,65,87,82,46,9,90,52],setuptool:[28,23],technic:85,target:[42,52],keyword:[5,74,54,61,69,50,40,79,19,89,29,22,48,45,63,78,59,16,35,66],provid:[37,27,69,53,13,7,84,79,78,32,52,90,48],tree:[85,52,48],zero:90,project:[37,86,13,65,42],minut:42,fashion:[2,67,51,90],websocket:[87,67,51,52],add_head:63,raw:[4,24],increment:[42,52],"__main__":52,seen:42,seem:52,churn:75,seek:19,minu:55,realm:90,transmit:84,simplifi:52,though:74,usernam:90,object:[74,54,42,29,79,59,32,35,5,61,63,66,41,36,87,45,89,16,69,19,22,24,52],deleg:32,regular:40,bind_paramet:68,orderli:[67,51],don:[42,52,69,84],doc:[37,52,13,0,65],flow:85,dog:[42,74],doe:[42,27,55,12,70,63,84,60],mayfield:75,declar:[5,54,61,69,89,19,29,22,48,45,79,78,59,16,35,66],changeset:52,has_kei:[63,52],bomb:52,mostli:[52,84],random:52,syntax:52,identifi:74,chnage:52,absolut:[55,12,52],configur:[3,79,52,47,29],apach:14,latenc:52,rich:76,ptest:52,fallbackgener:52,test_main:52,environmentev:79,likewis:90,stop:[42,32,52,69,55],report:[65,38,0,60,86],updatebuff:16,recalcul:40,earg:42,"public":78,twice:52,requestsuccess:[24,27],respond:[2,42],test_filenam:52,result:[5,36,74,54,43,69,42,2,79,19,89,29,22,48,45,61,59,52,16,35,66],respons:[27,54,55,49,84,2,44,76,87,45,41,63,24,52,90],fail:[42,90,52,69,84],themselv:[74,52],best:38,said:12,hopefulli:[42,52],databas:27,py32:52,test_fil:52,simplest:[37,22,13],awai:84,irc:[37,38,86,12,13,4,91,10,52],attribut:[5,45,74,54,61,69,89,19,29,22,48,32,79,78,59,24,52,16,35,66],accord:52,extend:[42,63,79],extens:90,expos:[4,52,16,81],cov:[52,60],howev:[85,4,38],against:[55,90,12,52],logic:52,com:[3,86],deiana:75,toni:[86,75],"_on_request_success":24,loader:[18,52,23],guid:[42,73,52,47,57],assum:[55,52,70],speak:84,question:[37,12,13,42],jsoncontrol:81,three:47,been:[27,54,42,74,29,79,78,59,32,35,5,61,63,66,36,45,89,16,69,19,51,22,24,52],much:[37,42,12,13,51,52],interest:[42,74],basic:[42,27,43,69,2,74,62,84,78,90],"__doc__":[17,80,81,50,41,23,32,72,16,48],vpath:52,quickli:[42,27,46],life:[12,0,60],"_sock":52,xxx:52,worker:[18,52,50],telnet:47,ani:[68,37,74,38,69,75,42,2,13,76,67,85,90,22,84,63,24,52,16,60],child:[51,48],"catch":84,emploi:60,ugli:52,ident:[42,90],servic:84,properti:[42,74,52],calcul:52,suffici:[32,74],systemexit:[52,69],kwarg:[54,1,29,4,79,59,32,35,5,80,61,39,81,40,66,72,67,44,45,89,16,48,68,17,69,50,70,19,22,24,52,26],conf:52,sever:[85,86,3,70,24,52],jame:[91,86,75,21],receiv:[27,69,74,51,84,24,52,48],suggest:[37,13],make:[37,27,69,42,12,13,76,78,52,47],complex:[37,85,79,13,42],split:[70,24,16],complet:[27,54,2,74,70,79,59,32,35,5,61,66,45,89,16,48,69,29,19,22,24,52],test_tcp_reconnect:52,hang:52,action:[32,22,74,84],rais:[90,52,60,48,84],giorgi:75,scenario:[74,22],thu:[27,69,70,22,78,52],in_subtre:48,inherit:[42,52,48,85],ocean:52,client:[68,67,27,87,49,90,84,16,77,51,91,41,58,24,52,47],wherebi:[2,52],thi:[27,54,28,1,42,2,3,75,79,74,67,29,4,45,59,78,55,32,35,5,37,61,39,81,91,7,47,8,63,66,41,10,72,36,84,12,13,44,14,88,89,90,16,48,69,68,18,49,50,70,19,30,51,22,23,24,52],gzip:90,everyth:52,inheria:42,left:[52,16,69],lengthrequir:84,protocol:[90,67,27,51,91,87,4,45,41,24,10,52,16],just:[2,24,52,74],webconsol:52,yet:22,languag:[37,63,13,42],previous:[74,84],get_rang:55,easi:[42,27,76],had:52,keep_blank_valu:55,test_logg:52,board:42,els:[40,90,22,52],save:[78,22,89],test_tcp_connect_closed_port:52,applic:[27,42,2,76,29,79,32,5,37,82,84,72,85,86,12,13,46,89,90,48,20,21,91,73,52],preserv:22,disposit:[90,63],background:50,shadow:52,test_ev:52,apart:[32,74,48],measur:[32,52],daemon:[29,52,21],specif:[11,32,22,52,48],deprec:52,arbitrari:74,html:[90,14],underli:[70,52,47,41],www:[3,90,13,86,37],right:[42,52],old:52,deal:47,interv:[40,52],intern:[55,86,84,24,52,16,60],flatten:30,validate_sinc:90,indirect:32,successfulli:[5,68,27,54,61,69,89,19,74,29,45,66,79,59,24,73,16,35],cooper:52,bottom:52,subclass:[42,84,78,24,52,48],track:[42,52,60],tracker:[65,60],condit:52,foo:78,fieldstorag:52,localhost:[52,47],core:[74,54,1,42,3,67,77,29,4,45,79,78,59,32,35,5,80,61,39,40,8,83,66,72,36,12,44,14,89,15,16,48,69,68,17,18,49,50,70,52,19,30,82,51,22,23,24,25,26],naali:86,insecur:52,anotehr:3,repositori:[28,57],post:[70,90,52,49,84],"super":[78,42,74,52,47],plug:42,prepareunregist:[52,48],slightli:[42,52],unfortun:[37,13],commit:[52,38],marshal:75,"30x":76,basenam:90,"float":[40,32],encod:[67,27,70,45,66,41,59,24,52,90],bound:[42,70],werkzeug:84,bufsiz:[68,83],wrap:52,accordingli:48,wai:[37,38,0,42,2,13,63,78,32,73,52],support:[37,74,87,20,82,72,12,13,7,21,58,63,46,84,23,52,60],transform:63,"_process":52,"class":[53,27,54,55,1,42,2,3,79,74,67,77,29,4,45,58,78,59,32,83,35,5,85,80,61,39,81,40,91,56,7,47,8,63,66,41,10,72,36,84,44,76,87,14,88,46,89,90,15,16,48,69,68,17,18,49,50,70,52,19,30,21,51,22,23,24,25,26],avail:[55,69,8,22,41,52],gif:63,setdefault:[63,52],fork:[52,38],head:42,form:[37,38,13,70,63,55,90,52],offer:27,forc:90,some:[36,42,74,38,0,53,85,78,90,73,52,16,48],hear:38,methodnotallow:84,"true":[74,54,55,29,79,59,32,35,5,61,40,63,66,36,45,89,90,16,48,17,69,50,19,22,23,52],freenod:[37,38,13],reset:[40,52],maximum:[32,69],tell:42,dump_valu:56,fundament:90,emit:[24,27],trim:17,featur:[37,27,38,0,13,20,22,90,52,60],classic:2,parse_head:63,"abstract":[37,13],reexamin:22,exist:[37,13,63,84,52,16,60],ship:[73,46],bore:42,concurr:[37,12,13,52],pipe:[68,52],encrypt:90,excel:0,refactor:52,tim:75,role:32,test:[42,38,0,12,13,46,73,52,60],"1ee04d5fb657":52,unlimit:69,node:[56,82,25,12,77,35,58,15,52,48],relat:[42,52],stringio:52,flushev:32,urllib2:52,consid:[67,52],sql:86,bitbucket:[37,38,11,13,65,60],longer:52,ignor:[17,52,69],time:[37,69,42,40,13,32,52,90,86],push:52,backward:8,osx:[12,52],concept:[42,12,52,85],chain:22,skip:52,consum:69,component_inst:52,mill:[91,86,75,21],regsit:52,graph:[42,20,53],x00:52,query_str:55,isinst:74,sourc:[42,28,69,37,11,13,57,71,32,47],string:[55,63,52,41,70],"_fire":52,revalid:90,handlestyp:22,cool:42,level:[5,37,12,13,32,90],did:52,gui:12,iter:[52,69],item:[70,63,52,16],unsupport:84,greenlet:52,quick:[73,57],prevent:[90,52,69,48],"_handler_channel":52,port:[68,49,3,77,70,83,41,52,47],appear:63,current:[55,69,12,29,22,90],domain2:3,ascii:[42,52],enthusiast:[37,13],deriv:[54,32,22,48],gener:[27,54,69,12,7,74,76,4,22,23,24,52,32,86],unauthor:[90,44,84],sahriswiki:86,address:[68,70,52,41],along:38,wait:[74,69,40,22,32,52],bot:86,"_success":52,inotifi:52,bob:[42,74],commonli:[24,27],semant:52,regardless:52,extra:[42,52],modul:[55,1,3,76,70,30,59,32,37,39,81,8,63,66,84,72,44,88,90,48,69,20,22,23,24,52],prefer:[63,38],"1st":[70,47],instal:[37,28,13,57,32,73,52,60],memori:52,visit:30,mangahelp:86,handler:[27,54,42,2,74,29,4,79,78,59,32,35,5,61,16,66,36,43,76,45,89,90,47,48,18,69,50,19,22,24,52],scope:42,eventsuccess:[5,54,61,69,89,19,29,45,66,79,59,16,35],oom:52,enhanc:52,prototyp:86,effort:[37,13,76],easiest:73,pyinotifi:[52,20],focu:12,descriptor:8,can:[27,55,85,3,74,29,79,78,60,37,38,39,63,84,42,11,12,13,90,16,48,69,51,22,52],purpos:52,encapsul:[2,85],stream:[24,54,52,76],fragment:52,playsign:86,agent:90,nastri:52,occur:[36,42,52,69,84],alwai:[63,52],multipl:[3,52],charset:63,fieldvalu:63,write:[68,42,27,38,0,67,12,19,51,29,8,24,52,47,60,49],anyon:[2,75],xhtml:14,product:52,clone:[11,28],"_get_request_handl":52,mac:[37,13,20],mai:[74,54,3,29,4,79,59,32,35,5,37,61,63,66,85,13,45,89,16,48,69,19,22,52],underscor:[78,63,48],data:[68,67,74,49,84,47,70,63,41,24,52,16,69],man:52,load_valu:56,stdin:[29,7],explicit:[78,43],produc:[42,52],inform:[27,54,74,29,79,59,32,35,5,61,39,66,41,67,76,45,89,16,48,69,19,24,52],"switch":52,combin:[37,32,22,13,84],callabl:[90,52],talk:12,notaccept:84,graphviz:42,rpc_channel:[59,66],still:[42,38,52],mainli:52,dynam:[32,54,52,23],entiti:[90,84],conjunct:[4,16],disconnect:[68,52,47],thank:38,concis:[78,38],duplex:[68,52],sec14:90,platform:[37,0,12,13,20,52],window:[37,52,12,13,20],load_ev:56,mail:[37,12,13],main:[50,12,87,46,32,52,48],non:52,initi:[54,29,79,59,32,35,5,80,61,81,16,66,41,72,42,45,89,47,48,49,68,17,69,50,19,23,24],verifi:38,now:[42,2,40,22,63,73,52],discuss:[38,60],introduct:[62,65,0,76],term:[37,32,12,13],name:[53,74,54,42,29,30,79,78,59,32,35,5,61,39,63,66,41,36,45,89,90,16,48,69,19,22,52],serviceunavail:84,didn:52,revert:52,separ:[3,74,63,52,42],domain:3,wsclient:51,agil:60,replac:[5,54,61,69,89,19,29,45,66,79,59,52,16,35],receipt:27,continu:[27,12,52,32],contributor:[37,75],alessio:75,year:90,happen:[42,52,47],shown:27,space:52,prefectli:52,safeimport:30,profil:86,internet:41,correct:[42,41],unixcli:68,orm:27,org:[37,38,86,11,13,90,52,60],"byte":[55,27,52],cough:42,reusabl:[85,12,52],keyecho:52,befor:[5,42,54,61,69,3,89,19,29,22,48,45,79,59,90,52,16,35,66],waiter:52,waitev:[32,52],recov:42,thing:[78,42,52,65],place:52,think:[37,13,52,42],frequent:[37,12,42],first:[42,74,2,51,22,84,63,73,52,48],oper:[22,55,16],suspend:[32,22,52,69],reimplement:52,directli:[85,32,75],carri:74,onc:[40,32,74,60],yourself:60,fast:52,open:[52,51,19,67,61],given:[67,55,50,40,44,70,63,84,32,52,90,48],silent:[42,52],convent:78,caught:42,conveni:[74,52,76,48],friend:52,especi:[74,84],copi:28,specifi:[54,70,79,78,59,32,35,5,61,40,66,67,45,89,16,48,69,29,19,51,22,52],broadcast:[68,52,47],inconsis:52,packet:35,pragma:90,than:[78,90,63,52,69],serv:[90,14,46],were:[63,52,84],browser:[55,84],pre:[53,54,55,1,56,3,79,67,77,29,30,45,58,59,32,35,5,80,61,39,81,40,7,91,8,63,66,41,10,72,36,84,44,83,87,14,88,46,89,90,15,16,48,69,68,17,18,49,50,70,19,4,21,51,22,23,24,25,26],basecontrol:81,sai:[42,52],nicer:84,argument:[27,54,74,70,79,78,59,32,35,5,61,40,16,63,66,84,44,45,89,90,47,69,50,29,19,22,24],dash:63,deliv:[5,67,74,54,61,69,89,19,29,22,66,45,79,59,32,52,16,35],test_disp:52,check_auth:90,engin:86,note:[68,42,74,28,85,3,13,4,63,84,78,55,32,52,16],denomin:52,take:[37,32,13,74,42],noth:[42,52],channel:[27,54,67,74,77,29,30,79,78,59,32,35,5,37,61,81,40,8,83,66,42,12,13,45,89,15,16,48,69,68,17,49,70,52,19,4,51,22,23,24,25],explitetli:4,begin:29,sure:[52,47,69],normal:[5,42,85,54,61,69,70,79,19,76,89,29,22,66,45,63,59,24,16,35],buffer:[24,52,16],test_bridg:52,compress:[90,55],pair:[68,3],renam:52,later:[32,52],boundari:52,handler_return:74,show:[42,52],analyit:52,permiss:84,corner:52,unfinish:[24,16],xml:[87,52,66,76],onli:[42,69,20,76,63,84,79,78,32,52,16,48],explicitli:[78,74,52],written:[68,37,86,75,42,13,90,52],woof:42,dict:[68,55,69,50,3,63,90],test_unixserv:52,icebox:60,sighup:52,variou:[37,10,13,7,21],get:[37,27,55,0,42,2,13,57,62,63,32,52,90,49],repr:52,secondari:52,ssl:[68,52],cannot:[37,13,52,84],ignorechannel:17,requir:[37,27,13,20,57,22,88,84,52,47],truli:52,mapper:76,consist:[42,27],pydot:[42,20],borrow:[76,84],yield:[32,22,52],where:[78,42,52,48,67],wiki:[52,86],errconnrefus:52,alllow:52,detect:[78,52],enough:27,between:[90,12,52],"import":[42,74,2,7,76,78,32,73,52,47,48],sortabl:63,parent:[85,52,48],screen:42,cycl:[0,60],auto_regist:23,come:[42,12,69],tutori:[37,74,42],aura:86,improv:[37,13,52],overview:[76,37,13,47,42],period:40,dispatch:[27,54,85,3,74,70,45,79,78,59,32,35,5,61,66,84,67,76,87,14,89,16,69,29,19,22,52,26],exploit:52,itercmp:52,typic:[69,50],poll:[8,12,52],clarif:52,coupl:[37,13],mark:[78,85,22,52,48],those:[27,32,74],"case":[27,38,74,22,63,52],superflu:52,rtype:53,invok:[5,45,27,54,61,69,89,19,74,29,22,48,32,79,78,59,24,16,35,66],invoc:[78,32,16,74],advantag:[37,13,42],stdout:[29,52,7],reduce_time_left:69,worri:42,destin:[5,54,61,69,89,19,29,45,66,79,59,16,35],"return":[53,27,54,55,2,74,29,79,59,32,35,5,61,63,66,84,76,45,89,90,16,48,68,69,19,22,24,52],eventcomplet:[5,54,61,69,89,19,29,45,66,79,59,16,35],"__init__":[78,42,74,47,48],develop:[37,27,82,28,0,75,53,2,65,12,13,76,57,21,11,78,52,60,86],author:[90,84],media:[86,84],edwin:75,same:[5,74,54,61,69,89,19,29,22,66,45,79,59,90,52,16,35],check:[67,86,90,73,52,48],binari:52,inconsist:52,document:[42,65,37,52,13,76,34,60],flake8:[52,60],finish:[42,52],webserv:52,driver:52,driven:[37,12,13],capabl:52,mani:[78,38,13,42],extern:[37,13,69],appropri:[70,4,24],ekwarg:42,pep8:65,without:[42,32,22,52,84],roughli:42,execut:[32,22,52,69,50],when:[74,54,2,3,29,79,78,59,32,35,5,61,16,66,42,45,89,90,47,48,68,69,50,19,51,22,24,52],rest:[4,52,84],kill:52,speed:52,except:[36,42,69,87,84,78,52,48],param:[63,55],blog:86,around:[52,63,38],read:[68,37,27,65,42,13,19,8,67,47,4,78,51,24,52,16,74],rfc2616:90,acceptel:63,world:[2,42,52,76,86],server:[27,55,2,3,74,70,58,37,16,64,84,85,41,13,76,87,46,47,68,25,51,91,24,52],either:[68,37,38,69,50,42,13,23,90,52,48],output:[42,52,75,55],inter:[52,58],manag:[36,42,18,69,50,53,65,22,85,63,32,33,52,48],fulfil:84,unixserv:[68,70,16],handshak:67,parse_q:55,slice:55,confirm:[67,60],definit:[78,52],generateev:[32,52,69],exit:42,complic:22,refer:[37,82,42,11,76,70,41,78,52,48],power:[2,37,12,13],inspect:[53,52],broken:52,found:[27,3,74,76,84,78,32,52],"__name__":74,earlier:22,src:[37,13],stand:27,act:[52,48],other:[74,28,85,2,76,57,4,78,37,63,42,86,12,13,90,47,48,69,50,20,23,52],cvar:41,effici:52,exposejson:81,urwid:52,find_handl:52,unregist:[40,85,52,69,48],shortcircuit:75,strip:47,pivot:[65,60],your:[37,27,28,0,42,2,12,13,71,22,60,84,38,90,53,48,69],log:[5,17,42,21,29,52],aren:[74,52],getbuff:16,start:[37,27,38,69,50,42,2,74,57,67,29,62,78,76,55,32,73,52,47,48],compliant:[37,27,67,13,76,87,51],interfac:[52,12,13,70],lot:52,ipv6:[52,13],strictli:[20,84],findtyp:[30,52],hei:52,tupl:[5,68,54,55,69,50,70,79,19,63,29,45,66,89,61,59,16,35],regard:[42,76],reinvok:69,faster:52,serve_fil:[90,52],pull:[38,28],possibl:[27,12,74,90,52,32],"default":[53,27,54,55,74,29,45,79,59,35,5,61,63,66,84,42,76,87,14,89,90,16,48,17,69,70,19,22,24,52,26],"_dispatch":52,basepol:8,connect:[68,67,74,49,51,52,47],formattim:1,gone:84,creat:[54,55,29,4,79,78,59,32,35,5,37,38,7,16,8,66,41,42,13,44,45,89,61,47,68,17,69,50,70,19,22,23,24,36,52],certain:[40,69],watcher:52,file:[17,80,61,1,42,20,7,70,8,76,90,52,16],gethandl:52,fill:52,incorrect:[90,52],again:[42,32,52,74],googl:52,collector:[74,43],tcpserver:[68,85,27,47,70,16],event:[27,54,55,1,42,3,79,74,67,77,29,4,45,58,78,59,32,83,35,5,37,85,80,61,39,81,40,56,7,47,50,8,63,66,41,72,36,43,84,12,13,44,76,87,14,89,90,15,16,48,69,68,17,18,49,30,70,52,19,20,51,22,23,24,25,26],field:63,cleanup:52,you:[53,27,28,0,3,74,78,55,60,37,38,63,84,42,12,13,90,47,48,69,71,22,73,52],architectur:[37,12,13,85],sequenc:52,docstr:[52,60],unsupportedmediatyp:84,pool:[52,50],reduc:[52,69],directori:[52,73,14,28,46],descript:[78,74,76,84],potenti:52,alright:42,has_opt:52,cpu:52,represent:[42,52],all:[27,54,75,85,74,29,30,79,59,32,60,5,38,16,63,35,84,66,42,45,89,61,47,48,17,69,19,22,24,52],illustr:[2,42],forbidden:[44,84,76],bytearrai:52,test_arg:52,children:52,hmmm:42,script_nam:55,init:52,program:[37,42,12,13,32,52],scratch:42,introduc:42,baseserv:[70,76,85],parsebodi:52,elementstr:63,fals:[68,55,70,30,14,78,32,52,90],faq:52,util:[18,55,56,87,30,22,58,52],mechan:[78,90],fall:52,veri:[37,74,42,2,12,13,51,52],splitter:16,list:[74,54,55,75,29,79,59,32,35,5,37,61,16,63,66,84,12,13,14,89,47,48,17,69,70,19,45,52],stderr:[17,52,7,29],small:[37,13,52],valuechang:52,krekel:75,unmark:52,past:90,"_tick":52,uuid4:52,design:[2,37,90,13,75],pass:[74,54,55,3,29,79,78,59,35,5,37,61,66,67,12,13,45,89,16,48,69,50,70,19,51,22,52],further:[11,76,48],what:[37,74,0,42,71,12,13,70,52,47,60],sub:[85,4],section:[27,74],abl:42,delet:[61,63,52,49],version:[71,12,20,73,52,60],add_sect:52,method:[42,74,49,84,85,22,41,78,63,32,52,90,48,69],full:[68,37,27,13,76,87,52],hash:90,unmodifi:[52,84],depend:[37,52,13,20,57],strong:[37,13],modifi:[42,61,44,24,52,90,60],valu:[74,54,55,3,70,79,59,35,5,61,6,63,66,36,45,89,90,16,18,69,29,19,22,24,52],search:37,amount:40,codebas:52,via:[37,28,12,13,52,60],primit:[37,13,52],friendli:52,filenam:[5,29,63,89,90,52],establish:[67,51,52],select:[8,12,52],ctrl:42,regist:[42,74,69,50,85,78,32,52,47,48],two:[42,74,55,51,32,52,16,48],coverag:52,taken:[32,75],minor:52,more:[27,54,74,29,79,59,32,35,5,37,38,63,66,42,12,13,45,89,61,16,69,19,22,52],flag:17,broke:52,particular:[74,69],known:24,suchojad:75,cach:[90,52,86],none:[53,74,54,55,1,56,3,67,77,29,30,59,32,35,36,80,39,81,40,8,63,66,41,72,42,84,44,83,14,89,90,15,48,69,68,17,49,50,70,52,19,22,23,24,25,26],dep:52,dev:38,"__tick__":52,learn:42,identifysuccess:74,def:[42,74,2,76,78,47],traverse_children_handl:52,registr:[52,48],share:[27,38,0,11,88,65],basic_auth:90,accept:[70,51,63,84,78,90,52,16],huge:52,cours:74,goal:42,secur:[68,3,52,49,70],rather:[85,27,74,22,32,52],anoth:[74,22,52,69,50],test_manager_repr:52,simpl:[42,2,64,52,47,46],isn:[42,22,52],resourc:[55,14,52,49,84],pricewaterhousecoop:86,reflect:[52,44],init_kwarg:23,okai:42,associ:[5,36,74,54,61,69,89,19,29,45,48,79,59,24,16,35,66],caus:[42,32,22,52,50],test_secure_serv:52,egg:23,prepare_unregister_complet:52,help:[38,28,42],mainthread:42,through:[42,52,47],hierarchi:[32,52],developet:52,paramet:[53,54,67,3,29,79,59,32,35,5,61,40,63,66,41,36,45,89,90,16,48,69,68,17,49,50,70,19,51,22,24,52],style:[14,52],late:63,"_param":63,pend:[32,22,69],rapidli:76,might:52,epol:[8,12],good:[42,84],headerel:63,"98d0056ef18a":52,framework:[37,18,38,86,42,82,12,13,27,74,87,62,43],"_valu":63,detach:[85,48],from_str:63,eventu:[5,54,61,69,89,19,29,45,66,79,59,32,16,35],unlik:63,authent:[90,84],easili:[42,12],token:63,compris:85,fulli:[27,13,23],unicod:[29,52],idea:[37,13,52],test_longwait:52,expect:[42,52,16,60],stabl:[11,37,13,57],beyond:[37,13,20],todo:34,orient:42,socket_famili:68,"try":[42,90,73,52,47],safeti:52,serve_download:90,etag:90,"_client":47,sdlc:[0,60],print:[17,74,42,78,73,52],proxi:84,advanc:[74,43],differ:[42,74,3,22,78,52],reason:[37,8,13,52],base:[54,55,1,42,2,3,76,67,77,29,4,45,79,59,32,35,5,37,85,80,38,39,81,40,8,63,66,41,72,36,84,13,44,83,14,89,61,15,16,48,69,68,17,49,50,70,52,19,51,22,23,24,25,26],fieldnam:63,ask:[37,12,69,42],thrown:[74,52],thread:[32,52,50],perhap:55,circuit:[53,27,54,28,0,1,42,2,3,75,79,74,67,77,29,4,45,58,78,55,32,72,35,86,5,37,85,80,38,39,81,40,91,56,7,47,50,8,63,60,41,10,59,66,36,43,84,65,11,12,13,44,76,87,14,88,46,89,61,90,15,16,48,69,68,17,18,62,49,30,70,52,83,19,20,21,82,51,22,23,24,73,25,26],assign:[24,22,52],singleton:[52,48],certfil:70,notifi:[36,68,61,7,20,29,52],obviou:78,feel:42,number:[42,74,69,40,3,90,52],done:[27,52,48],construct:63,blank:55,horribl:42,miss:52,digest_auth:90,guess:90,script:[37,13],interact:[37,13,85],least:[42,32],stori:[38,0,60],statement:22,scheme:[55,41],store:[36,74,16,39],option:[74,54,28,57,29,45,79,78,59,32,35,5,61,40,66,14,89,16,69,19,20,22,52],relationship:48,processtask:52,part:[78,3,18,52,42],pars:[70,4,63,24],fred:[42,74],std:[52,76],notfound:[44,84,76],kind:84,test_tcp_bind:52,remot:[68,35],remov:[32,52,47,48],bride:52,reus:[37,74,13],str:[53,49,17,70,29,63,41,90,52],toward:[37,13],randomli:52,comput:[12,48],unboundlocalerror:52,packag:[37,18,28,53,13,7,57,91,10,65,74],expir:[90,52],"null":52,imagin:22,built:[2,37,13,52],lib:[52,76],documentatino:60,self:[42,74,2,76,78,32,52,47],also:[68,37,74,90,85,12,13,7,22,84,63,32,52,16,60],derivedev:[52,69],append:[5,74,54,61,69,89,79,19,47,29,45,66,32,63,59,24,16,35],fouond:44,success_channel:[5,54,61,69,89,19,29,45,66,79,59,16,35],distribut:[58,73,12,23],my_special_ev:78,previou:[42,52,16],most:[8,63],plai:[2,52],plan:12,clear:[40,78,12,38],cover:[52,38],"_on_respons":24,"2nd":[70,47],clean:52,usual:[5,27,54,61,69,89,19,74,29,45,66,79,59,32,16,35],baseclass:84,wsgi:[37,27,72,13,76,87,84,52],hyper:24,session:[87,39,76],find:[37,74,55,42,13,22,78,52,60],copyright:[91,21],solut:[37,38,13],queu:42,templat:27,reinstal:28,unus:52,express:52,rfc:[67,51,52],common:[32,52,69,21],set:[53,74,54,76,29,79,59,32,35,5,61,40,16,63,66,84,36,44,45,89,90,47,48,69,19,52],startup:52,see:[74,28,2,70,32,37,80,38,81,41,72,42,13,90,16,48,17,69,50,21,91,23,24,52],sec:90,arg:[74,54,55,67,29,4,79,59,32,35,5,80,61,39,81,66,72,42,45,89,90,16,48,68,69,50,19],close:[68,67,27,61,49,19,51,52],bark:42,ohloh:[37,13],qvalu:[90,63],jenkin:52,test_gzip:52,bridg:[12,52],httperror:[76,24,27,44],altern:[5,37,54,61,69,13,89,19,29,45,66,79,59,52,16,35],signatur:[17,80,81,50,41,23,32,72,16,48],appreci:75,javascript:[37,13],incident:42,test_notifi:52,solv:38,both:[68,42,54,23,32,52],last:[90,32,52,47],delimit:24,alon:27,forgotten:52,load:[79,52,89,23],simpli:[2,42,22,28,47],point:[3,52,42],header:[55,49,3,87,51,63,84,90,52],littl:42,linux:[37,12,13,20],throughout:[85,90],ignoreev:17,due:52,empti:[55,90,63,52],sinc:[42,90,84],whom:47,compnoent:52,wschannel:[67,51],fire:[27,54,67,74,29,79,59,32,35,5,61,40,16,66,42,45,89,47,48,69,19,51,22,24,52],unnecessarili:22,understand:42,look:[42,37,2,3,13,78,52],accidentla:52,circuti:[2,52,27,38,46],"while":[36,74,12,52],abov:[42,90],error:[36,17,74,68,69,90,42,19,44,76,87,84,24,52,32],fun:[2,73],dump_ev:56,fixtur:52,loos:[37,13],loop:[32,12,52],prolog:[37,38,75,42,11,13,60],propag:22,pound:[42,74],readi:[68,22,52],test_component_target:52,itself:[5,85,27,54,61,69,2,40,19,29,45,66,89,79,59,16,35],rid:52,addhandl:[32,52],queue:[32,52],decor:[78,32,22,52,48],unmount:61,decot:52,minim:76,belong:[85,52],pytest:[52,60],decod:[67,84],pwc:86,handler_annot:78,conflict:52,higher:[37,22,13,52],itch:42,optim:52,wherea:42,user:[37,38,86,75,84,90,52,47],baseenviron:52,stack:[87,27,69],travers:52,task:[32,22,52,50,21],discourag:74,eleg:12,autotag:90,entri:[3,52],spent:32,pickl:52,spend:69,propos:52,explan:74,chore:[52,60],collabor:86,meher:52,poller:[8,52,18,69],dirlist:14,tick:[32,52],input:[52,41],subsequ:[67,74],useless:52,bin:[78,42,74,47],ece3ee5472ef:52,bit:[42,22,52],httpexcept:84,lost:52,docutil:[53,54,55,1,56,3,79,67,77,29,30,45,58,59,32,35,5,80,61,39,81,40,7,91,8,63,66,41,10,72,36,84,44,83,87,14,88,46,89,90,15,16,48,69,68,17,18,49,50,70,19,4,21,51,22,23,24,25,26],signal:[42,69,44,51,22,84,32,52],manifest:52,collect:[63,24,22,27,74],admittedli:2,test_debugg:52,often:[3,53],acknowledg:[37,13],creation:[78,22,52],textiowrapp:52,back:[24,52,41],global:[87,42,52,88],lipp:75,sampl:52,resutl:52,compress_level:55,scale:[37,13],chunksiz:41,per:[78,24,52],pyver:52,internalservererror:84,larg:[52,84],myevent:42,slash:55,reproduc:52,requestentitytoolarg:84,run:[42,74,0,2,3,76,60,78,32,52,47,48,69],do_handshak:52,simple_serv:47,myspecialev:78,step:[2,38,47],crlf:24,prerequisit:47,shine:52,jsonrpc:[87,59,76],unicodeerror:84,coexist:52,internalserv:52,block:[32,50],precondit:84,primarili:75,needs_resum:52,within:[3,90,69,85],"_on_httperror":24,ensur:[52,27,38,60,41],mke:52,span:[53,54,55,1,56,3,79,67,77,29,30,45,58,59,32,35,5,80,61,39,81,40,7,91,8,63,66,41,10,72,36,84,44,83,87,14,88,46,89,90,15,16,48,69,68,17,18,49,50,70,19,4,21,51,22,23,24,25,26],sock:[68,24,16,41,47],submit:[38,0,60,84],custom:[42,4,52,16],includ:[37,32,13,52,55],suit:52,forward:[3,52,67],properli:[73,52,47,84],repeatedli:40,"_on_start":78,link:[32,52],translat:[59,66],newer:52,atom:55,line:[42,4,91,78,24,10,52,16],utf:[70,45,66,41,59,24,52],max_wait:69,value_chang:52,callev:[32,22,52],similar:[74,38],constant:[87,88],curs:52,"_on_task":50,doesn:[42,52,84],repres:[53,52],incomplet:52,destruct:90,chat:[52,38,47],guarante:[37,13],pythoncircuit:[37,13],udpclient:[68,52],invalid:[52,84],nice:2,websocketcli:51,scrum:60,virtualhost:[87,3,76],far:42,hello:[2,42,52,76],oop:[42,52],pluggabl:86,code:[90,42,38,0,84,2,65,44,57,11,71,41,78,28,24,52,47,60],queri:[13,86,41],documetn:52,privat:[52,48],base_url:52,send:[54,3,29,79,59,35,5,61,66,84,85,41,12,45,89,90,16,68,69,19,51,24,52],becam:52,sens:[42,52],sent:[5,67,27,54,61,69,68,89,19,29,51,45,48,41,79,59,16,35,66],"99bottl":52,implicitli:[78,74],relev:60,tri:[67,51],michael:[86,75],unquot:52,race:52,dealt:42,evt:74,pleas:[11,37,38,13,60],smaller:42,fortun:42,natur:[42,48,85],uniqu:52,download:[42,74,28,37,11,13,57,78,90,73,52,47],odd:52,folk:42,compat:[37,8,13,52],index:[37,2,65,14,46,52],compar:[63,12,52],anton:86,access:[2,74,61,39,84],experiment:52,uncamel:[5,54,61,69,89,19,29,45,66,79,78,59,52,16,35],wait_for:52,bodi:[55,49,41,90,52,24],let:[37,42,13,73,47,60],becom:[78,22,69],implicit:[78,43],convert:[42,24,63,27],pretti:42,holger:75,larger:69,"_name":63,resurrect:52,conftest:52,chang:[36,42,32,52,74],envnam:79,appli:[78,55,22,28],app:[5,82,89,21,29,79,52],gatewai:[72,52,84],api:[37,74,42,82,76,78,52],docroot:14,from:[27,54,28,75,67,2,74,57,78,55,32,37,85,40,16,63,84,42,11,13,76,90,47,48,68,69,22,23,24,52],zip:23,commun:[37,51,12,13,52],upgrad:67,next:[42,86,2,3,22,52,47],websit:[3,27,13,86,37],requesturitoolarg:84,doubt:42,usr:[78,42,74,47],simpler:[37,13,52,42],has_sect:52,sort:63,appropi:4,benchmark:52,iif:69,socket:[68,85,12,51,16,70,8,91,41,32,52,47],retriev:[27,52,16],scalabl:[37,12,13,76],alia:[68,52],"__process":52,executor:32,control:[71,81,70,2,76,87,11,90,52],realxtend:86,process:[27,54,0,50,84,12,51,74,29,4,60,32,58,24,52,16,48],lock:[52,69],controlelr:90,high:[37,12,13,52,76],tag:[11,90,52],tab:[11,52],onlin:12,tam:86,serial:[83,7],delai:40,six:52,instead:[27,55,50,41,78,52,48],clength:52,overridden:[5,54,61,69,89,19,29,4,22,48,45,79,59,16,35,66],findcmp:[30,52],watch:47,requst:41,essenti:[18,27],bind:[68,52,15,25,70],correspond:[3,24,63,32],element:63,issu:[37,38,13,52,60],junitxml:52,alatalo:[86,75],allow:[37,74,28,42,3,12,13,84,32,52,90,48],fallback:[52,84],retval:42,move:[42,52,61],whilst:52,comma:63,bunch:52,perfect:38,threadpool:52,webev:[54,52],therefor:[5,54,61,69,79,19,29,45,66,89,63,78,59,52,16,35],lastli:42,crash:42,handl:[67,27,69,85,51,74,4,22,84,63,24,52,47,48],auto:52,auth:[90,84],facilit:40,project_thin_badg:[37,13],multiprocess:52,anyth:52,"_on_read":24,nameerror:42,februari:37,mode:[52,28,16],querystr:55,dariusz:75,bump:52,requesttimeout:84,"static":[14,76,87,63,46,52],our:[42,38,86,2,12,78,47,60],patch:52,special:[42,22,52],out:[29,74,73,52,42],variabl:[5,17,54,61,69,42,70,89,19,29,45,48,79,59,36,52,16,35,66],reload:52,influenc:[78,90,22],bad:[52,84],suitabl:[55,46,23],rel:55,clarifi:52,umbrella:52,insid:52,test_nod:52,dictionari:55,releas:[37,11,13,57,60,52,48],unwant:42,could:52,put:[42,24,52,49,74],timer:[40,18,52],keep:[42,55,47],test_removehandl:52,generate_ev:[52,69],softwar:[12,38,0,60],max_ev:52,qualiti:[38,60],echo:52,date:37,whoos:16,"0dev":[],prioriti:[42,22,52,63],"long":84,unknown:[52,84],licens:[37,91,13,21],system:[36,17,85,61,69,20,37,2,42,12,13,8,7,71,4,79,53,32,52],messag:[54,29,4,79,59,35,5,37,61,16,63,66,41,42,84,12,13,45,89,47,69,19,24,52],attach:[78,85,90,63],termin:52,"final":[55,22,52],udp:[12,52],someev:78,listn:52,enqueu:32,rst:[],exactli:[74,52,60],notconnect:51,structur:[2,3,85,52,53],charact:70,headervalu:55,singletonerror:48,rate:52,viewer:86,py2:52,py3:52,clearli:42,have:[27,54,28,0,75,2,74,29,79,59,32,60,5,37,61,16,63,35,84,66,42,12,13,45,89,47,68,69,19,22,24,73,52],tabl:37,need:[53,27,28,0,2,3,76,22,60,52,47,48],turn:78,tidi:52,rout:52,builtin:[42,27,16],discret:85,which:[36,42,27,55,50,67,2,85,22,84,78,63,90,52,48],basecompon:[1,85,3,77,29,45,79,78,59,5,40,8,66,72,67,14,89,15,16,48,68,17,49,50,70,25,51,22,23,24,52,26],mit:[37,91,13,86,21],singl:[2,3,32,52],analysi:53,unless:[90,63],freebsd:[37,12,13,20],discov:42,stupidli:2,websocketsmedi:52,segment:52,why:[42,74],url:[55,49,3,44,51,84,90,52],gather:74,request:[67,27,54,38,0,84,2,3,44,76,87,70,51,45,41,55,24,52,90,60,49],uri:84,inde:42,pidfil:29,determin:[70,22],someth:[42,74,52,84],text:[37,13,47,4,90,24],identify_success:74,baseev:[52,69],trivial:12,anywai:52,redirect:[55,52,44,84,76],locat:[52,84],launchpad:86,hadn:74,should:[27,54,55,29,79,59,35,5,61,63,66,84,42,41,45,89,90,16,48,69,50,19,52],restructur:52,test_poller_reus:52,local:[42,52,60,23],meant:52,contribut:[75,38,0,60],pypi:[37,52,13,20,65],regularli:28,notimpl:84,increas:52,handler_channel:52,enabl:[17,8,13,37,23],whoohoo:42,integr:[12,52,86],contain:[18,91,3,7,21,87,70,8,63,76,24,10,52,90],view:84,conform:84,legaci:8,frame:[42,69,67],apolog:75,"0x808e8ec":42,temporarili:84,multipart:52,greenletmanag:52,"7be64d8b6f7c":52,becaus:[52,48,41],"70677b69bf05":52,statu:[90,84],correctli:[42,52],pattern:[78,74],test_process_pool:52,tend:[37,13],state:[42,32,22,52,74],weird:[42,52],neither:32,email:[63,12],stati:52,tent:13,kei:63,entir:[42,12],unnot:52,group:74,eclips:52,addit:[74,69,3,20,51,22,63,52],handlermetaclass:22,revers:52,sniff:52,plugin:52,equal:52,wsgiref:76,etc:[27,52,16],instanc:[27,54,85,29,4,79,59,35,5,61,7,16,63,66,36,44,45,89,47,68,17,69,70,19,24,52],comment:52,badgatewai:84,arriv:68,walk:[42,47],rpc:[87,59,52,66,76],modstat:14,quit:[70,52],compos:[85,55],compon:[53,27,54,55,1,42,2,3,74,67,77,29,4,45,79,78,59,32,83,35,86,5,37,85,80,38,39,81,40,91,56,7,47,50,8,63,66,41,10,72,36,43,84,12,13,44,76,14,89,61,90,15,16,48,69,68,17,18,49,30,70,52,19,20,21,51,22,23,24,25,26],json:[87,59,52,76],besid:74,udpserv:[68,52],immedi:32,assert:52,togeth:[37,13,42],present:[90,52],multi:52,plain:90,align:27,harder:[42,52],defin:[74,54,42,2,29,30,79,78,59,32,35,5,61,16,66,36,12,45,89,47,48,69,19,22,24,52],glossari:[71,37],parse_bodi:55,apply_async:52,site:[3,52],archiv:[52,28,23],cherrypi:[27,76],lightweight:[37,13],incom:[3,47,4,66,84,59,24,16],so_reuseaddr:52,reviv:52,parse_bind_paramet:68,welcom:[37,38,13,42],easy_isntal:60,member:48,python:[37,74,28,86,42,65,12,13,20,76,85,84,78,55,32,52,47,60],test_valu:52,"__version__":73,difficult:74,http:[27,55,75,2,3,76,70,60,37,38,63,84,10,85,86,11,13,44,87,45,90,49,51,91,24,52],hostnam:68,upon:[78,67,27,52,51],effect:[32,52,74],retriv:29,build:[27,55,12,76,47,64,24,52,32],distutil:52,off:[38,47],keyboardinterrupt:[52,69],well:[37,74,38,42,13,52,60],exampl:[42,0,85,2,3,13,76,63,84,90,73,52],command:[11,4,73,28,75],latest:[11,37,13,69,57],less:[63,69],obtain:55,tcp:[51,12,52,74],"_on_sign":52,prepend:3,web:[27,54,55,1,85,2,3,76,70,59,37,39,81,82,62,63,66,41,72,67,84,13,44,87,14,88,46,90,49,51,45,24,52,26],baudrat:83,validate_etag:90,bench:52,add:[52,63,13,20],valid:[70,90,38,84],lookup:41,logger:[5,17,1,76,87,79,52],match:[5,67,54,61,69,84,3,79,19,89,29,22,48,45,63,78,59,90,16,35,66],branch:[11,52],xmlrpc:[87,52,66,76],webpag:86,generatortyp:22,howto:[37,52,64,42],piec:52,know:[37,0,13,48,32,60,69],press:42,redesign:52,password:90,recurs:[5,54,61,69,89,19,29,45,66,79,59,52,16,35],python3:52,python2:52,insert:[63,48],like:[37,74,38,0,42,2,13,85,51,84,52],success:[5,67,74,54,61,69,89,19,29,22,66,45,79,59,32,52,16,35],basehttpserv:76,necessari:[2,74,52],async:52,page:[37,38,86,11,13,46,84,52],backlog:68,exceed:84,drop:52,mycompon:[78,42],kdb:86,collected_inform:74,"export":76,flush:32,proper:[67,52],home:42,librari:[37,38,85,12,13,20,87,52],win32:52,est:52,lead:78,leak:52,avoid:[22,52],leav:[42,24],duplic:[63,52],"_failur":52,encourag:[37,13],investig:52,usag:[52,74,12,43],file_gener:41,vhost:55,host:[68,87,55,49,65,3,76,77,41,52,47],remvo:52,test_logger_error:52,stage:[51,52,48],about:[37,74,38,42,13,41,32,52,48],actual:[5,54,61,69,89,19,29,51,22,48,45,79,59,32,16,35,66],justin:75,ressurect:52,constructor:[5,67,74,54,61,69,89,19,44,47,29,51,45,66,79,78,59,16,35],discard:52,disabl:17,own:[42,48],reprhandl:[22,52],easy_instal:[37,13],automat:[5,42,27,54,61,69,90,89,19,29,45,48,32,79,78,59,24,16,35,66],guard:52,get_al:63,nuke:52,val:63,transfer:24,trigger:[36,32,52,74],chunk:[27,52],"function":[27,54,55,1,56,2,3,74,67,77,29,4,45,79,59,32,83,35,5,37,85,80,61,39,81,40,8,63,66,41,72,36,84,13,44,76,14,89,90,15,16,48,69,68,17,18,49,50,70,52,19,30,82,51,22,23,24,25,26],bug:[37,38,0,65,13,52,60],bud:63,instaleld:60,succe:52,made:[42,52],whether:52,wish:60,displai:[42,53],asynchron:[37,42,12,13,20,8],limit:[52,84],otherwis:[70,52,50],problem:[42,27,38,0,52,60],removehandl:[32,52],socketerror:68,evalu:52,"int":[70,32,55,90],dure:[42,52,69],pid:[29,32,52],twist:12,implement:[55,1,3,70,4,59,32,36,39,81,8,63,66,84,10,72,67,12,44,14,88,90,16,91,23,24,52],ini:52,pip:[37,73,13,60],quot:52,detail:[37,27,42,13,74,78,47],virtual:[87,3,76,86],book:11,bool:50,futur:[36,52],rememb:52,junk:52,repeat:38,header_el:63,eof:[52,19],exeuct:36,reliabl:52,indirectli:[85,32],test_success:52,literalev:[54,52]},objtypes:{"0":"py:module","1":"py:class","2":"py:method","3":"py:attribute","4":"py:function","5":"py:exception","6":"py:staticmethod","7":"py:classmethod"},titles:["Developer Docs","circuits.web.loggers – Loggers","Getting Started","circuits.web.dispatchers.virtualhosts – Virtual Hosts","circuits.net.protocols.irc – IRC Protocol","circuits.app.log – Application Logging","Values","circuits.io – I/O Support","circuits.core.pollers – I/O Pollers","Tools","circuits.net.protocols – Networking Protocols","Downloading","Frequently Asked Questions","PyPi Test Page - Tentative Release","circuits.web.dispatchers.static – Static","circuits.node.node – Node","circuits.net.protocols.line – Line Protocol","circuits.core.debugger – Debugger","circuits.core – Core Functionality","circuits.io.events – I/O Events","Requirements and Dependencies","circuits.app – Application Support","circuits.core.handlers – Handlers","circuits.core.loader – Loader","circuits.web.http – HTTP Protocol","circuits.node.server – Server","circuits.web.dispatchers.dispatcher – Default Dispatcher","The Basics","Installing","circuits.app.daemon – Application Daemon","circuits.core.utils – Utilities","Debugging","circuits.core.manager – Manager","Manager","Documentation TODO","circuits.node.events – Events","circuits.core.values – Value","circuits 2.1.0 Documentation","Contributing to circuits","circuits.web.sessions – Sessions","circuits.core.timers – Timers","circuits.web.wrappers – Request/Response Objects","Tutorial","The circuits Framework","circuits.web.errors – Errors","circuits.net.protocols.http – HTTP Protocol","circuits.web.main – circuits.web","How To: Build a Simple Server","circuits.core.components – Components","circuits.web.client – Client","circuits.core.workers – Workers","circuits.web.websocket – WebSocket Client","ChangeLog","circuits.tools – Development Tools","circuits.web.events – Events","circuits.web.utils – Utilities","circuits.node.utils – Node Utilities","Getting Started","circuits.node – Node","circuits.web.dispatchers.jsonrpc – JSON-RPC","Development Processes","circuits.io.notify – File System Notification","The circuits.web Framework","circuits.web.headers – Headers","HowTos","Development Introduction","circuits.web.dispatchers.xmlrpc – XML-RPC","circuits.web.dispatchers.websockets – WebSockets","circuits.net.sockets – Socket Components","circuits.core.events – Events","circuits.web.servers – Servers","Glossary","circuits.web.wsgi – WSGI Support","Quick Start Guide","Events","Contributors","Introduction","circuits.node.client – Client","Handlers","circuits.app.env – Application Environment","circuits.io.file – File I/O","circuits.web.controllers – Controllers","API Reference","circuits.io.serial – Serial I/O","circuits.web.exceptions – Exceptions","Components","Users","circuits.web – Web Framework","circuits.web.constants – Global Constants","circuits.app.config – Application Config","circuits.web.tools – Tools","circuits.net – Networking"],objnames:{"0":["py","module","Python module"],"1":["py","class","Python class"],"2":["py","method","Python method"],"3":["py","attribute","Python attribute"],"4":["py","function","Python function"],"5":["py","exception","Python exception"],"6":["py","staticmethod","Python static method"],"7":["py","classmethod","Python class method"]},filenames:["dev/index","api/circuits_web_loggers","web/gettingstarted","api/circuits_web_dispatchers_virtualhosts","api/circuits_net_protocols_irc","api/circuits_app_log","man/values","api/circuits_io","api/circuits_core_pollers","man/tools","api/circuits_net_protocols","start/downloading","faq","pypitest","api/circuits_web_dispatchers_static","api/circuits_node_node","api/circuits_net_protocols_line","api/circuits_core_debugger","api/circuits_core","api/circuits_io_events","start/requirements","api/circuits_app","api/circuits_core_handlers","api/circuits_core_loader","api/circuits_web_http","api/circuits_node_server","api/circuits_web_dispatchers_dispatcher","web/basics","start/installing","api/circuits_app_daemon","api/circuits_core_utils","man/debugging","api/circuits_core_manager","man/manager","todo","api/circuits_node_events","api/circuits_core_values","index","dev/contributing","api/circuits_web_sessions","api/circuits_core_timers","api/circuits_web_wrappers","tutorial/index","man/index","api/circuits_web_errors","api/circuits_net_protocols_http","api/circuits_web_main","howtos/simple_server","api/circuits_core_components","api/circuits_web_client","api/circuits_core_workers","api/circuits_web_websocket","changes","api/circuits_tools","api/circuits_web_events","api/circuits_web_utils","api/circuits_node_utils","start/index","api/circuits_node","api/circuits_web_dispatchers_jsonrpc","dev/processes","api/circuits_io_notify","web/index","api/circuits_web_headers","howtos/index","dev/introduction","api/circuits_web_dispatchers_xmlrpc","api/circuits_web_dispatchers_websockets","api/circuits_net_sockets","api/circuits_core_events","api/circuits_web_servers","glossary","api/circuits_web_wsgi","start/quick","man/events","contributors","web/introduction","api/circuits_node_client","man/handlers","api/circuits_app_env","api/circuits_io_file","api/circuits_web_controllers","api/index","api/circuits_io_serial","api/circuits_web_exceptions","man/components","users","api/circuits_web","api/circuits_web_constants","api/circuits_app_config","api/circuits_web_tools","api/circuits_net"]}) \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/_sources/api/circuits_app_config.txt circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_app_config.txt --- circuits-2.1.0/docs/build/html/_sources/api/circuits_app_config.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_app_config.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,24 +0,0 @@ -:mod:`circuits.app.config` -- Application Config -================================================ - -.. module :: circuits.app.config - -Events ------- - -.. autoclass :: circuits.app.config.Load - :members: - -.. autoclass :: circuits.app.config.Save - :members: - -Components ----------- - -.. autoclass :: circuits.app.config.Config - :members: - -Functions ---------- - - diff -Nru circuits-2.1.0/docs/build/html/_sources/api/circuits_app_daemon.txt circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_app_daemon.txt --- circuits-2.1.0/docs/build/html/_sources/api/circuits_app_daemon.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_app_daemon.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,24 +0,0 @@ -:mod:`circuits.app.daemon` -- Application Daemon -================================================ - -.. module :: circuits.app.daemon - -Events ------- - -.. autoclass :: circuits.app.daemon.Daemonize - :members: - -.. autoclass :: circuits.app.daemon.WritePID - :members: - -Components ----------- - -.. autoclass :: circuits.app.daemon.Daemon - :members: - -Functions ---------- - - diff -Nru circuits-2.1.0/docs/build/html/_sources/api/circuits_app_env.txt circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_app_env.txt --- circuits-2.1.0/docs/build/html/_sources/api/circuits_app_env.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_app_env.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,24 +0,0 @@ -:mod:`circuits.app.env` -- Application Environment -================================================== - -.. module :: circuits.app.env - -Events ------- - -.. autoclass :: circuits.app.env.Create - :members: - -.. autoclass :: circuits.app.env.Load - :members: - -Components ----------- - -.. autoclass :: circuits.app.env.Environment - :members: - -Functions ---------- - - diff -Nru circuits-2.1.0/docs/build/html/_sources/api/circuits_app_log.txt circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_app_log.txt --- circuits-2.1.0/docs/build/html/_sources/api/circuits_app_log.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_app_log.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,21 +0,0 @@ -:mod:`circuits.app.log` -- Application Logging -============================================== - -.. module :: circuits.app.log - -Events ------- - -.. autoclass :: circuits.app.log.Log - :members: - -Components ----------- - -.. autoclass :: circuits.app.log.Logger - :members: - -Functions ---------- - - diff -Nru circuits-2.1.0/docs/build/html/_sources/api/circuits_app.txt circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_app.txt --- circuits-2.1.0/docs/build/html/_sources/api/circuits_app.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_app.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -:mod:`circuits.app` -- Application Support -========================================== - -.. automodule :: circuits.app - -.. toctree:: - :maxdepth: 1 - :glob: - - circuits_app* diff -Nru circuits-2.1.0/docs/build/html/_sources/api/circuits_core_components.txt circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_core_components.txt --- circuits-2.1.0/docs/build/html/_sources/api/circuits_core_components.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_core_components.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,36 +0,0 @@ -:mod:`circuits.core.components` -- Components -============================================= - -.. automodule :: circuits.core.components - - -Classes -------- - -.. autoclass :: BaseComponent - :members: - -.. autoclass :: Component - :members: - - -Components ----------- - -**none** - - -Events ------- - -.. autoclass :: PrepareUnregister - :members: - -.. autoclass :: SingletonError - :members: - -Functions ---------- - -**none** - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/_sources/api/circuits_core_debugger.txt circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_core_debugger.txt --- circuits-2.1.0/docs/build/html/_sources/api/circuits_core_debugger.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_core_debugger.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,29 +0,0 @@ -:mod:`circuits.core.debugger` -- Debugger -========================================= - -.. automodule :: circuits.core.debugger - - -Classes -------- - -**none** - - -Components ----------- - -.. autoclass :: Debugger - :members: - - -Events ------- - -**none** - - -Functions ---------- - -**none** diff -Nru circuits-2.1.0/docs/build/html/_sources/api/circuits_core_events.txt circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_core_events.txt --- circuits-2.1.0/docs/build/html/_sources/api/circuits_core_events.txt 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_core_events.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,40 +0,0 @@ -:mod:`circuits.core.events` -- Events -===================================== - -.. automodule :: circuits.core.events - - -Classes -------- - -.. autoclass :: Event - :members: - - -Components ----------- - -**none** - - -Events ------- - -.. autoclass :: Error -.. autoclass :: Failure -.. autoclass :: Registered -.. autoclass :: Signal -.. autoclass :: Started -.. autoclass :: Stopped -.. autoclass :: Success -.. autoclass :: Unregister -.. autoclass :: Unregistered -.. autoclass :: GenerateEvents - :members: - - -Functions ---------- - -**none** - diff -Nru circuits-2.1.0/docs/build/html/_sources/api/circuits_core_handlers.txt circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_core_handlers.txt --- circuits-2.1.0/docs/build/html/_sources/api/circuits_core_handlers.txt 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_core_handlers.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,30 +0,0 @@ -:mod:`circuits.core.handlers` -- Handlers -========================================= - -.. automodule :: circuits.core.handlers - - -Classes -------- - -.. autoclass :: HandlerMetaClass - :members: - - -Components ----------- - -**none** - - -Events ------- - -**none** - - -Functions ---------- - -.. autofunction :: handler -.. autofunction :: reprhandler diff -Nru circuits-2.1.0/docs/build/html/_sources/api/circuits_core_loader.txt circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_core_loader.txt --- circuits-2.1.0/docs/build/html/_sources/api/circuits_core_loader.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_core_loader.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,28 +0,0 @@ -:mod:`circuits.core.loader` -- Loader -===================================== - -.. automodule :: circuits.core.loader - - -Classes -------- - -**none** - - -Components ----------- - -.. autoclass :: Loader - :members: - -Events ------- - -**none** - - -Functions ---------- - -**none** diff -Nru circuits-2.1.0/docs/build/html/_sources/api/circuits_core_manager.txt circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_core_manager.txt --- circuits-2.1.0/docs/build/html/_sources/api/circuits_core_manager.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_core_manager.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,29 +0,0 @@ -:mod:`circuits.core.manager` -- Manager -======================================= - -.. automodule :: circuits.core.manager - - -Classes -------- - -.. autoclass :: Manager - :members: - - -Components ----------- - -**none** - - -Events ------- - -**none** - - -Functions ---------- - -**none** diff -Nru circuits-2.1.0/docs/build/html/_sources/api/circuits_core_pollers.txt circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_core_pollers.txt --- circuits-2.1.0/docs/build/html/_sources/api/circuits_core_pollers.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_core_pollers.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,38 +0,0 @@ -:mod:`circuits.core.pollers` -- I/O Pollers -=========================================== - -.. automodule :: circuits.core.pollers - - -Classes -------- - -**none** - - -Components ----------- - -.. autoclass :: BasePoller - :members: - -.. autoclass :: Select - :members: - -.. autoclass :: Poll - :members: - -.. autoclass :: EPoll - :members: - - -Events ------- - -**none** - - -Functions ---------- - -**none** diff -Nru circuits-2.1.0/docs/build/html/_sources/api/circuits_core_timers.txt circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_core_timers.txt --- circuits-2.1.0/docs/build/html/_sources/api/circuits_core_timers.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_core_timers.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,29 +0,0 @@ -:mod:`circuits.core.timers` -- Timers -===================================== - -.. automodule :: circuits.core.timers - - -Classes -------- - -**none** - - -Components ----------- - -.. autoclass :: Timer - :members: - - -Events ------- - -**none** - - -Functions ---------- - -**none** diff -Nru circuits-2.1.0/docs/build/html/_sources/api/circuits_core.txt circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_core.txt --- circuits-2.1.0/docs/build/html/_sources/api/circuits_core.txt 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_core.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,21 +0,0 @@ -:mod:`circuits.core` -- Core Functionality -========================================== - -.. automodule :: circuits.core - -.. toctree:: - :maxdepth: 1 - :glob: - - circuits_core_components - circuits_core_events - circuits_core_handlers - circuits_core_manager - circuits_core_values - circuits_core_pollers - circuits_core_timers - circuits_core_loader - circuits_core_utils - circuits_core_workers - circuits_core_debugger - diff -Nru circuits-2.1.0/docs/build/html/_sources/api/circuits_core_utils.txt circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_core_utils.txt --- circuits-2.1.0/docs/build/html/_sources/api/circuits_core_utils.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_core_utils.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,33 +0,0 @@ -:mod:`circuits.core.utils` -- Utilities -======================================= - -.. automodule :: circuits.core.utils - - -Classes -------- - -**none** - - -Components ----------- - -**none** - - -Events ------- - -**none** - - -Functions ---------- - -.. autofunction :: findchannel -.. autofunction :: findcmp -.. autofunction :: findroot -.. autofunction :: findtype -.. autofunction :: flatten -.. autofunction :: safeimport diff -Nru circuits-2.1.0/docs/build/html/_sources/api/circuits_core_values.txt circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_core_values.txt --- circuits-2.1.0/docs/build/html/_sources/api/circuits_core_values.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_core_values.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,30 +0,0 @@ -:mod:`circuits.core.values` -- Value -==================================== - -.. automodule :: circuits.core.values - - -Classes -------- - -.. autoclass :: Value - - -Components ----------- - -**none** - - -Events ------- - -**none** - - -Functions ---------- - -**none** - - diff -Nru circuits-2.1.0/docs/build/html/_sources/api/circuits_core_workers.txt circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_core_workers.txt --- circuits-2.1.0/docs/build/html/_sources/api/circuits_core_workers.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_core_workers.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,29 +0,0 @@ -:mod:`circuits.core.workers` -- Workers -======================================= - -.. automodule :: circuits.core.workers - -Classes -------- - -**none** - - -Components ----------- - -.. autoclass :: Worker - :members: - - -Events ------- - -.. autoclass :: Task - :members: - - -Functions ---------- - -**none** diff -Nru circuits-2.1.0/docs/build/html/_sources/api/circuits_io_events.txt circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_io_events.txt --- circuits-2.1.0/docs/build/html/_sources/api/circuits_io_events.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_io_events.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,42 +0,0 @@ -:mod:`circuits.io.events` -- I/O Events -======================================= - -.. module :: circuits.io.events - -Events ------- - -.. autoclass :: Close - :members: - -.. autoclass :: Closed - :members: - -.. autoclass :: EOF - :members: - -.. autoclass :: Error - :members: - -.. autoclass :: Opened - :members: - -.. autoclass :: Read - :members: - -.. autoclass :: Seek - :members: - -.. autoclass :: Write - :members: - - -Components ----------- - -**none** - -Functions ---------- - -**none** diff -Nru circuits-2.1.0/docs/build/html/_sources/api/circuits_io_file.txt circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_io_file.txt --- circuits-2.1.0/docs/build/html/_sources/api/circuits_io_file.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_io_file.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,21 +0,0 @@ -:mod:`circuits.io.file` -- File I/O -=================================== - -.. module :: circuits.io.file - -Events ------- - -**none** - - -Components ----------- - -.. autoclass :: File - :members: - -Functions ---------- - -**none** diff -Nru circuits-2.1.0/docs/build/html/_sources/api/circuits_io_notify.txt circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_io_notify.txt --- circuits-2.1.0/docs/build/html/_sources/api/circuits_io_notify.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_io_notify.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,44 +0,0 @@ -:mod:`circuits.io.notify` -- File System Notification -===================================================== - -.. module :: circuits.io.notify - - -Events ------- - -.. autoclass :: Accessed - :members: - -.. autoclass :: Closed - :members: - -.. autoclass :: Created - :members: - -.. autoclass :: Deleted - :members: - -.. autoclass :: Modified - :members: - -.. autoclass :: Moved - :members: - -.. autoclass :: Opened - :members: - -.. autoclass :: Unmounted - :members: - - -Components ----------- - -.. autoclass :: Notify - :members: - - -Functions ---------- - diff -Nru circuits-2.1.0/docs/build/html/_sources/api/circuits_io_serial.txt circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_io_serial.txt --- circuits-2.1.0/docs/build/html/_sources/api/circuits_io_serial.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_io_serial.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,21 +0,0 @@ -:mod:`circuits.io.serial` -- Serial I/O -======================================= - -.. module :: circuits.io.serial - -Events ------- - -**none** - - -Components ----------- - -.. autoclass :: Serial - :members: - -Functions ---------- - -**none** diff -Nru circuits-2.1.0/docs/build/html/_sources/api/circuits_io.txt circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_io.txt --- circuits-2.1.0/docs/build/html/_sources/api/circuits_io.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_io.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -:mod:`circuits.io` -- I/O Support -================================= - -.. automodule :: circuits.io - -.. toctree:: - :maxdepth: 1 - :glob: - - circuits_io* diff -Nru circuits-2.1.0/docs/build/html/_sources/api/circuits_net_protocols_http.txt circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_net_protocols_http.txt --- circuits-2.1.0/docs/build/html/_sources/api/circuits_net_protocols_http.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_net_protocols_http.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,24 +0,0 @@ -:mod:`circuits.net.protocols.http` -- HTTP Protocol -=================================================== - -.. module :: circuits.net.protocols.http - -Events ------- - -.. autoclass :: circuits.net.protocols.http.Request - :members: - -.. autoclass :: circuits.net.protocols.http.Response - :members: - -Components ----------- - -.. autoclass :: circuits.net.protocols.http.HTTP - :members: - -Functions ---------- - - diff -Nru circuits-2.1.0/docs/build/html/_sources/api/circuits_net_protocols_irc.txt circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_net_protocols_irc.txt --- circuits-2.1.0/docs/build/html/_sources/api/circuits_net_protocols_irc.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_net_protocols_irc.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,21 +0,0 @@ -:mod:`circuits.net.protocols.irc` -- IRC Protocol -================================================= - -.. module :: circuits.net.protocols.irc - -Events ------- - -.. autoclass :: circuits.net.protocols.irc.RAW - :members: - -Components ----------- - -.. autoclass :: circuits.net.protocols.irc.IRC - :members: - -Functions ---------- - - diff -Nru circuits-2.1.0/docs/build/html/_sources/api/circuits_net_protocols_line.txt circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_net_protocols_line.txt --- circuits-2.1.0/docs/build/html/_sources/api/circuits_net_protocols_line.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_net_protocols_line.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,21 +0,0 @@ -:mod:`circuits.net.protocols.line` -- Line Protocol -=================================================== - -.. module :: circuits.net.protocols.line - -Events ------- - -.. autoclass :: Line - :members: - -Components ----------- - -.. autoclass :: LP - :members: - -Functions ---------- - - diff -Nru circuits-2.1.0/docs/build/html/_sources/api/circuits_net_protocols.txt circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_net_protocols.txt --- circuits-2.1.0/docs/build/html/_sources/api/circuits_net_protocols.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_net_protocols.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -:mod:`circuits.net.protocols` -- Networking Protocols -===================================================== - -.. automodule :: circuits.net.protocols - -.. toctree:: - :maxdepth: 1 - :glob: - - circuits_net_protocols* diff -Nru circuits-2.1.0/docs/build/html/_sources/api/circuits_net_sockets.txt circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_net_sockets.txt --- circuits-2.1.0/docs/build/html/_sources/api/circuits_net_sockets.txt 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_net_sockets.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,64 +0,0 @@ -:mod:`circuits.net.sockets` -- Socket Components -================================================ - -.. module :: circuits.net.sockets - -Events ------- - -.. autoclass :: Connect -.. autoclass :: Connected -.. autoclass :: Close -.. autoclass :: Closed -.. autoclass :: Read -.. autoclass :: Write -.. autoclass :: SocketError -.. autoclass :: Disconnect -.. autoclass :: Disconnected - -Components ----------- - -.. autoclass :: Client - :members: - :undoc-members: - - -.. autoclass :: circuits.net.sockets.TCPClient - :members: - :undoc-members: - - -.. autoclass :: circuits.net.sockets.UDPClient - :members: - :undoc-members: - -.. autoclass :: circuits.net.sockets.UNIXClient - :members: - :undoc-members: - - -.. autoclass :: circuits.net.sockets.Server - :members: - :undoc-members: - - -.. autoclass :: circuits.net.sockets.TCPServer - :members: - :undoc-members: - - -.. autoclass :: circuits.net.sockets.UDPServer - :members: - :undoc-members: - - -.. autoclass :: circuits.net.sockets.UNIXServer - :members: - :undoc-members: - - -Functions ---------- - -.. autofunction :: circuits.net.sockets.Pipe diff -Nru circuits-2.1.0/docs/build/html/_sources/api/circuits_net.txt circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_net.txt --- circuits-2.1.0/docs/build/html/_sources/api/circuits_net.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_net.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -:mod:`circuits.net` -- Networking -================================= - -.. automodule :: circuits.net - -.. toctree:: - :maxdepth: 1 - :glob: - - circuits_net* diff -Nru circuits-2.1.0/docs/build/html/_sources/api/circuits_node_client.txt circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_node_client.txt --- circuits-2.1.0/docs/build/html/_sources/api/circuits_node_client.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_node_client.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -:mod:`circuits.node.client` -- Client -===================================== - -.. automodule :: circuits.node.client - - -Events ------- - -**none** - - -Components ----------- - -.. autoclass :: Client - :members: - - -Functions ---------- - -**none** diff -Nru circuits-2.1.0/docs/build/html/_sources/api/circuits_node_events.txt circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_node_events.txt --- circuits-2.1.0/docs/build/html/_sources/api/circuits_node_events.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_node_events.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ -:mod:`circuits.node.events` -- Events -===================================== - -.. automodule :: circuits.node.events - - -Events ------- - -.. autoclass :: Packet - :members: - -.. autoclass :: Remote - :members: - - -Components ----------- - -**none** - - -Functions ---------- - -**none** diff -Nru circuits-2.1.0/docs/build/html/_sources/api/circuits_node_node.txt circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_node_node.txt --- circuits-2.1.0/docs/build/html/_sources/api/circuits_node_node.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_node_node.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -:mod:`circuits.node.node` -- Node -================================= - -.. automodule :: circuits.node.node - - -Events ------- - -**none** - - -Components ----------- - -.. autoclass :: Node - :members: - - -Functions ---------- - -**none** diff -Nru circuits-2.1.0/docs/build/html/_sources/api/circuits_node_server.txt circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_node_server.txt --- circuits-2.1.0/docs/build/html/_sources/api/circuits_node_server.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_node_server.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -:mod:`circuits.node.server` -- Server -===================================== - -.. automodule :: circuits.node.server - - -Events ------- - -**none** - - -Components ----------- - -.. autoclass :: Server - :members: - - -Functions ---------- - -**none** diff -Nru circuits-2.1.0/docs/build/html/_sources/api/circuits_node.txt circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_node.txt --- circuits-2.1.0/docs/build/html/_sources/api/circuits_node.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_node.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -:mod:`circuits.node` -- Node -============================ - -.. automodule :: circuits.node - -.. toctree:: - :maxdepth: 1 - :glob: - - circuits_node* diff -Nru circuits-2.1.0/docs/build/html/_sources/api/circuits_node_utils.txt circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_node_utils.txt --- circuits-2.1.0/docs/build/html/_sources/api/circuits_node_utils.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_node_utils.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ -:mod:`circuits.node.utils` -- Node Utilities -============================================ - -.. automodule :: circuits.node.utils - - -Events ------- - -**none** - - -Components ----------- - -**none** - - -Functions ---------- - -.. autofunction :: dump_event -.. autofunction :: dump_value -.. autofunction :: load_event -.. autofunction :: load_value diff -Nru circuits-2.1.0/docs/build/html/_sources/api/circuits_tools.txt circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_tools.txt --- circuits-2.1.0/docs/build/html/_sources/api/circuits_tools.txt 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_tools.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -:mod:`circuits.tools` -- Development Tools -========================================== - -.. module :: circuits.tools - -Often you will end up needing to do some debugging or inspection of -your system. The `circuits.tools` package provides a set of development -tools for debugging, inspection and analysis. - -.. autofunction :: graph diff -Nru circuits-2.1.0/docs/build/html/_sources/api/circuits_web_client.txt circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_web_client.txt --- circuits-2.1.0/docs/build/html/_sources/api/circuits_web_client.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_web_client.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ -:mod:`circuits.web.client` -- Client -==================================== - -.. module :: circuits.web.client - - -Events ------- - -.. autoclass :: Request - :members: - - -Components ----------- - -.. autoclass :: Client - :members: - :undoc-members: - - -Functions ---------- - - diff -Nru circuits-2.1.0/docs/build/html/_sources/api/circuits_web_constants.txt circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_web_constants.txt --- circuits-2.1.0/docs/build/html/_sources/api/circuits_web_constants.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_web_constants.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,5 +0,0 @@ -:mod:`circuits.web.constants` -- Global Constants -================================================= - -.. automodule :: circuits.web.constants - diff -Nru circuits-2.1.0/docs/build/html/_sources/api/circuits_web_controllers.txt circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_web_controllers.txt --- circuits-2.1.0/docs/build/html/_sources/api/circuits_web_controllers.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_web_controllers.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,27 +0,0 @@ -:mod:`circuits.web.controllers` -- Controllers -============================================== - -.. automodule :: circuits.web.controllers - - -Events ------- - -**none** - - -Components ----------- - -.. autoclass :: Controller - :members: - -.. autoclass :: JSONController - :members: - - -Functions ---------- - -.. autofunction :: expose -.. autofunction :: exposeJSON diff -Nru circuits-2.1.0/docs/build/html/_sources/api/circuits_web_dispatchers_dispatcher.txt circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_web_dispatchers_dispatcher.txt --- circuits-2.1.0/docs/build/html/_sources/api/circuits_web_dispatchers_dispatcher.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_web_dispatchers_dispatcher.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,20 +0,0 @@ -:mod:`circuits.web.dispatchers.dispatcher` -- Default Dispatcher -================================================================ - -.. module :: circuits.web.dispatchers.dispatcher - -Events ------- - -**none** - -Components ----------- - -.. autoclass :: Dispatcher - :members: - -Functions ---------- - -**none** diff -Nru circuits-2.1.0/docs/build/html/_sources/api/circuits_web_dispatchers_jsonrpc.txt circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_web_dispatchers_jsonrpc.txt --- circuits-2.1.0/docs/build/html/_sources/api/circuits_web_dispatchers_jsonrpc.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_web_dispatchers_jsonrpc.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,21 +0,0 @@ -:mod:`circuits.web.dispatchers.jsonrpc` -- JSON-RPC -=================================================== - -.. automodule :: circuits.web.dispatchers.jsonrpc - -Events ------- - -.. autoclass :: RPC - :members: - -Components ----------- - -.. autoclass :: JSONRPC - :members: - -Functions ---------- - -**none** diff -Nru circuits-2.1.0/docs/build/html/_sources/api/circuits_web_dispatchers_static.txt circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_web_dispatchers_static.txt --- circuits-2.1.0/docs/build/html/_sources/api/circuits_web_dispatchers_static.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_web_dispatchers_static.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -:mod:`circuits.web.dispatchers.static` -- Static -================================================ - -.. automodule :: circuits.web.dispatchers.static - - -Events ------- - -**none** - - -Components ----------- - -.. autoclass :: Static - :members: - - -Functions ---------- - -**none** diff -Nru circuits-2.1.0/docs/build/html/_sources/api/circuits_web_dispatchers_virtualhosts.txt circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_web_dispatchers_virtualhosts.txt --- circuits-2.1.0/docs/build/html/_sources/api/circuits_web_dispatchers_virtualhosts.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_web_dispatchers_virtualhosts.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -:mod:`circuits.web.dispatchers.virtualhosts` -- Virtual Hosts -============================================================= - -.. automodule :: circuits.web.dispatchers.virtualhosts - - -Events ------- - -**none** - - -Components ----------- - -.. autoclass :: VirtualHosts - :members: - - -Functions ---------- - -**none** diff -Nru circuits-2.1.0/docs/build/html/_sources/api/circuits_web_dispatchers_websockets.txt circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_web_dispatchers_websockets.txt --- circuits-2.1.0/docs/build/html/_sources/api/circuits_web_dispatchers_websockets.txt 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_web_dispatchers_websockets.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,21 +0,0 @@ -:mod:`circuits.web.dispatchers.websockets` -- WebSockets -========================================================= - -.. automodule :: circuits.web.dispatchers.websockets - - -Events ------- - - -Components ----------- - -.. autoclass :: WebSockets - :members: - - -Functions ---------- - -**none** diff -Nru circuits-2.1.0/docs/build/html/_sources/api/circuits_web_dispatchers_xmlrpc.txt circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_web_dispatchers_xmlrpc.txt --- circuits-2.1.0/docs/build/html/_sources/api/circuits_web_dispatchers_xmlrpc.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_web_dispatchers_xmlrpc.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,24 +0,0 @@ -:mod:`circuits.web.dispatchers.xmlrpc` -- XML-RPC -================================================= - -.. automodule :: circuits.web.dispatchers.xmlrpc - - -Events ------- - -.. autoclass :: RPC - :members: - - -Components ----------- - -.. autoclass :: XMLRPC - :members: - - -Functions ---------- - -**none** diff -Nru circuits-2.1.0/docs/build/html/_sources/api/circuits_web_errors.txt circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_web_errors.txt --- circuits-2.1.0/docs/build/html/_sources/api/circuits_web_errors.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_web_errors.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,35 +0,0 @@ -:mod:`circuits.web.errors` -- Errors -==================================== - -.. automodule :: circuits.web.errors - - -Components ----------- - -**none** - - -Events ------- - -.. autoclass :: HTTPError - :members: - -.. autoclass :: Forbidden - :members: - -.. autoclass :: NotFound - :members: - -.. autoclass :: Redirect - :members: - -.. autoclass :: Unauthorized - :members: - - -Functions ---------- - -**none** diff -Nru circuits-2.1.0/docs/build/html/_sources/api/circuits_web_events.txt circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_web_events.txt --- circuits-2.1.0/docs/build/html/_sources/api/circuits_web_events.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_web_events.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,33 +0,0 @@ -.. _circuits_web_events: - -:mod:`circuits.web.events` -- Events -==================================== - -.. automodule :: circuits.web.events - -Events ------- - -.. autoclass :: WebEvent - :members: - -.. autoclass :: Request - :members: - -.. autoclass :: Response - :members: - -.. autoclass :: Stream - :members: - - -Components ----------- - -**none** - - -Functions ---------- - -**none** diff -Nru circuits-2.1.0/docs/build/html/_sources/api/circuits_web_exceptions.txt circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_web_exceptions.txt --- circuits-2.1.0/docs/build/html/_sources/api/circuits_web_exceptions.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_web_exceptions.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,44 +0,0 @@ -:mod:`circuits.web.exceptions` -- Exceptions -============================================ - -.. automodule :: circuits.web.exceptions - -Exceptions ----------- - -.. autoexception :: HTTPException -.. autoexception :: BadGateway -.. autoexception :: BadRequest -.. autoexception :: Forbidden -.. autoexception :: Gone -.. autoexception :: InternalServerError -.. autoexception :: LengthRequired -.. autoexception :: MethodNotAllowed -.. autoexception :: NotAcceptable -.. autoexception :: NotFound -.. autoexception :: NotImplemented -.. autoexception :: PreconditionFailed -.. autoexception :: Redirect -.. autoexception :: RequestEntityTooLarge -.. autoexception :: RequestTimeout -.. autoexception :: RequestURITooLarge -.. autoexception :: ServiceUnavailable -.. autoexception :: Unauthorized -.. autoexception :: UnicodeError -.. autoexception :: UnsupportedMediaType - - -Events ------- - -**none** - -Components ----------- - -**none** - -Functions ---------- - -**none** diff -Nru circuits-2.1.0/docs/build/html/_sources/api/circuits_web_headers.txt circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_web_headers.txt --- circuits-2.1.0/docs/build/html/_sources/api/circuits_web_headers.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_web_headers.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,36 +0,0 @@ -:mod:`circuits.web.headers` -- Headers -====================================== - -.. automodule :: circuits.web.headers - - -Events ------- - -**none** - - -Classes -------- - -.. autoclass :: Headers - :members: - -.. autoclass :: HeaderElement - :members: - -.. autoclass :: AcceptElement - :members: - - -Components ----------- - -**none** - - -Functions ---------- - -.. autofunction :: header_elements -.. autofunction :: parse_headers diff -Nru circuits-2.1.0/docs/build/html/_sources/api/circuits_web_http.txt circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_web_http.txt --- circuits-2.1.0/docs/build/html/_sources/api/circuits_web_http.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_web_http.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ -.. _circuits_web_http: - -:mod:`circuits.web.http` -- HTTP Protocol -========================================= - -.. automodule :: circuits.web.http - - -Components ----------- - -.. autoclass :: HTTP - :members: - :private-members: - - -Events ------- - -See :class:`circuits.web.events.Request` in :ref:`circuits_web_events`. - -Functions ---------- - -**none** - diff -Nru circuits-2.1.0/docs/build/html/_sources/api/circuits_web_loggers.txt circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_web_loggers.txt --- circuits-2.1.0/docs/build/html/_sources/api/circuits_web_loggers.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_web_loggers.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -:mod:`circuits.web.loggers` -- Loggers -====================================== - -.. automodule :: circuits.web.loggers - - -Events ------- - -**none** - - -Components ----------- - -.. autoclass :: Logger - :members: - - -Functions ---------- - -.. autofunction :: formattime diff -Nru circuits-2.1.0/docs/build/html/_sources/api/circuits_web_main.txt circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_web_main.txt --- circuits-2.1.0/docs/build/html/_sources/api/circuits_web_main.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_web_main.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,7 +0,0 @@ -:mod:`circuits.web.main` -- circuits.web -======================================== - -.. automodule :: circuits.web.main - -Shipped application with static and directory index support suitable for -quickly serving up simple web pages. diff -Nru circuits-2.1.0/docs/build/html/_sources/api/circuits_web_servers.txt circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_web_servers.txt --- circuits-2.1.0/docs/build/html/_sources/api/circuits_web_servers.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_web_servers.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ -:mod:`circuits.web.servers` -- Servers -====================================== - -.. automodule :: circuits.web.servers - - -Events ------- - -**none** - - -Components ----------- - -.. autoclass :: BaseServer - :members: - -.. autoclass :: Server - :members: - -Functions ---------- - -**none** diff -Nru circuits-2.1.0/docs/build/html/_sources/api/circuits_web_sessions.txt circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_web_sessions.txt --- circuits-2.1.0/docs/build/html/_sources/api/circuits_web_sessions.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_web_sessions.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -:mod:`circuits.web.sessions` -- Sessions -======================================== - -.. automodule :: circuits.web.sessions - - -Events ------- - -**none** - - -Components ----------- - -.. autoclass :: Sessions - :members: - - -Functions ---------- - -**none** diff -Nru circuits-2.1.0/docs/build/html/_sources/api/circuits_web_tools.txt circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_web_tools.txt --- circuits-2.1.0/docs/build/html/_sources/api/circuits_web_tools.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_web_tools.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,31 +0,0 @@ -:mod:`circuits.web.tools` -- Tools -================================== - -.. automodule :: circuits.web.tools - - -Events ------- - -**none** - - -Components ----------- - -**none** - - -Functions ---------- - -.. autofunction :: basic_auth -.. autofunction :: check_auth -.. autofunction :: digest_auth -.. autofunction :: expires -.. autofunction :: gzip -.. autofunction :: serve_download -.. autofunction :: serve_file -.. autofunction :: validate_etags -.. autofunction :: validate_since - diff -Nru circuits-2.1.0/docs/build/html/_sources/api/circuits_web.txt circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_web.txt --- circuits-2.1.0/docs/build/html/_sources/api/circuits_web.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_web.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -:mod:`circuits.web` -- Web Framework -==================================== - -.. automodule :: circuits.web - -.. toctree:: - :maxdepth: 1 - :glob: - - circuits_web_* diff -Nru circuits-2.1.0/docs/build/html/_sources/api/circuits_web_utils.txt circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_web_utils.txt --- circuits-2.1.0/docs/build/html/_sources/api/circuits_web_utils.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_web_utils.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ -:mod:`circuits.web.utils` -- Utilities -====================================== - -.. automodule :: circuits.web.utils - -Events ------- - -**none** - - -Components ----------- - -**none** - - -Functions ---------- - -.. autofunction :: compress -.. autofunction :: dictform -.. autofunction :: get_ranges -.. autofunction :: parse_body -.. autofunction :: parse_qs -.. autofunction :: url diff -Nru circuits-2.1.0/docs/build/html/_sources/api/circuits_web_websocket.txt circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_web_websocket.txt --- circuits-2.1.0/docs/build/html/_sources/api/circuits_web_websocket.txt 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_web_websocket.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,22 +0,0 @@ -:mod:`circuits.web.websocket` -- WebSocket Client -================================================= - -.. module :: circuits.web.websocket - - -Events ------- - - -Components ----------- - -.. autoclass :: WebSocketClient - :members: - :undoc-members: - - -Functions ---------- - - diff -Nru circuits-2.1.0/docs/build/html/_sources/api/circuits_web_wrappers.txt circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_web_wrappers.txt --- circuits-2.1.0/docs/build/html/_sources/api/circuits_web_wrappers.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_web_wrappers.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,38 +0,0 @@ -:mod:`circuits.web.wrappers` -- Request/Response Objects -======================================================== - -.. module :: circuits.web.wrappers - - -Events ------- - -**none** - - -Classes -------- - -.. autoclass :: Body - :members: - -.. autoclass :: Host - :members: - -.. autoclass :: Request - :members: - -.. autoclass :: Response - :members: - - -Components ----------- - -**none** - - -Functions ---------- - -.. autofunction :: file_generator diff -Nru circuits-2.1.0/docs/build/html/_sources/api/circuits_web_wsgi.txt circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_web_wsgi.txt --- circuits-2.1.0/docs/build/html/_sources/api/circuits_web_wsgi.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/api/circuits_web_wsgi.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ -:mod:`circuits.web.wsgi` -- WSGI Support -======================================== - -.. automodule :: circuits.web.wsgi - - -Events ------- - -**none** - - -Components ----------- - -.. autoclass :: Application - :members: - -.. autoclass :: Gateway - :members: - - -Functions ---------- - -**none** diff -Nru circuits-2.1.0/docs/build/html/_sources/api/index.txt circuits-3.1.0+ds1/docs/build/html/_sources/api/index.txt --- circuits-2.1.0/docs/build/html/_sources/api/index.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/api/index.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,15 +0,0 @@ -============= -API Reference -============= - -.. toctree:: - :maxdepth: 1 - - circuits_core - circuits_io - circuits_net - circuits_node - circuits_tools - circuits_web - circuits_app - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/_sources/changes.txt circuits-3.1.0+ds1/docs/build/html/_sources/changes.txt --- circuits-2.1.0/docs/build/html/_sources/changes.txt 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/changes.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,195 +0,0 @@ -:tocdepth: 2 - -.. _changes: - - -ChangeLog -========= - - -.. include:: ../../CHANGES.rst - - -circuits-2.0.1 20121124 ------------------------ - -- Fixed ``tests/web/test_main.py`` which was badly written. -- Fixed a regression test testing the Debugger component - - -circuits-2.0.0 20121122 (cheetah) ---------------------------------- - -- Fixed circuits.web entry point -- Fixed `tools.reprhandler()` for compatibility with Python-3.3 -- Added ``*channels`` support to waitEvent -- Added example of using .call -- Fixed logic around firing the Daemonize event when registering this component during run-time and after start-up -- Fixed use of reprhandler -- Fixed listening channel for exceptions/errors. -- Fixed channels for Log event. -- Fixed config loading. Fire a Ready event when the Environment is completely ready. -- Added .items(...) method to Config component. -- Added BaseEvent, LiteralEvent, DerivedEvent to the core and circuits name-spaces -- Fixed IRC protocol -- Added has_option to Config component -- Avoid error if user un-registers a component twice. -- Fixed base_url for WebConsole -- Fixed bug with sending Response for a Expect: 100-continue (Closes issue #32) -- Added a new circuits.web test that ensures that large posts > 1024 bytes work -- Updated conf so that doc can be built even if circuits isn't installed -- Updated reference of guide to howtos -- Updated man headers so that they weren't all "Components" -- Fixed all web dispatcher tests -- Fixed XMLRPC dispatcher. Must have a higher priority than the "default" dispatcher in order to coexist with it. -- Fixed unit test for failure response from web *component* (component's handler must have higher priority than default dispatcher if default dispatcher exists). -- Added failure test for web *controller*. -- Fixed JSON dispatcher. Must have a higher priority than the "default" dispatcher in order to coexist with it. -- Fixed vpath traversal. vpath created in reverse ("test_args/1/2/3" became "3/2/1/test_args"). -- Fixed evaluation of the Complete event: exclude events fired by other threads during event processing from the set of events to be tracked. -- Don't call tick on components that are waiting to be unregistered. -- Using new PrepareUnregister event to reliably remove sockets from poller. -- Fixes for PrepareUnregister and added test case. -- Added event that informs components about going to be removed from the tree. -- Fixed client request generation (MUST include Host header). -- Fixed channel naming in web.Client to allow several clients (i.e. connections to web sites) to coexist in an application. -- Prevented uncameling of event names that represent web requests. Handlers can now use the last path segment unmodified as handled event's name. -- Fixed the new dispatcher with new tests -- Fixed bug in complete event generation. -- Added optional event signaling the completion of an event and everything that has been caused by it. -- Added the possibility to redirect the success events to other channels. -- Updated documentation to reflect the new "handler suspend" feature. -- Replaced web dispatcher with simpler version -- Added support for x = yield self.callEvent(...) -- Made test_main more reliable -- Removed old BaseManager from playing with GreenletManager. Fixed test_manager_repr -- Fixed the exceptions being thrown for test_eval, but the test still fails -- Added a new failing test - evaluation of promised values -- Removed superfluous .value in test_longwait -- Added support for alllowing future handlers to have a "special" event parameter just like ordinary handlers. -- Fixed test_success -- Fixed test_removeHandler -- Added support for firing Done() and Success() after all done executing. -- Fixed callEvent -- Added 2 failing tests for yield -- Implemented promises which we detect for in circuits.web in cases where an event handler yields. Also only fire _success events after an event is well and truly finished (in the case of yielding event handlers) -- Fixed a bug with value not being set -- Fixed Issue #26 -- Added capability of waiting for a specific event name on a specific channel. -- Fixed bug guarding against tasks already removed. -- Implemented Component.init() support whereby one can define an alternative init() without needing to remember to call super(...) -- Fixed Python 3 compatibility with Unicode strings -- Added 99bottles as an example of concurrency. See: http://wiki.python.org/moin/Concurrency/99Bottles -- Removed old-style channel targeting -- Fixed and tested UDP forwarding -- Simplified udpclient example -- Implemented new version of port forwarded. TCP tested. -- Fixed Read events for UDPServer by setting .notify to True. -- Restructured the only How To Guide - Building a Simple Server -- Renamed _get_request_handler to just find_handler -- Removed channels attribute from WebEvents (fix for issue #29). -- Added Eclipse configuration files. -- Fixed uses of deprecated syntax in app.config -- Modified the defaults for channels. Set channels to event.channels, otherwise self.channel defaulting to * -- Fixed uses of deprecated syntax in env -- Fixed a bug with the Redirect event/error in circuits.web where it didn't handle Unicode strings -- fixed the web dispatcher -- Fixed test_poller_reuse test by using the now findtype() utility function -- fixed and adds tests for the web dispatcher -- Moved parseBody out into circuits.web.utils. Other code cleanup -- Added a test for a bug with the dispatcher mehere found. -- Removed itercmp() function. Added findtype() findchannel() and used better variable names. findcmp is an alias of findtype. -- Implemented optional singleton support for components -- Removed the circuits.web `routes` dispatcher as there are no tests for this and Routes dispatcher is broken - re implement at a later stage -- Removal of End feedback event -- Fixed web/test_value.py -- Fixed web futures test -- Simplified and fixed a lot of issues the circuits.bench -- Fixed circuits.web's exceptions tests and handling of exceptions. -- Fixed a potential bug with ``circuits.web.wsgi.Application``. -- Modified Manager to only assign a handler return value if it is not None. -- Fixed ``*_success`` and ``*_failure`` events fire on ``*event.channels`` so they go to the right place as expected. Fixed Issue #21 -- Removed event equality test and related tests. Seems rather useless and inconsistently used -- Fixed test_gzip circuits.web test. We no longer have a Started event feedback so have to use a filter -- Fixed a corner case where one might be trying to compare an event object with a non-event object -- Fixed the event handling for circuits.web WebSockets Component by separating out the WebSockets handling from the HTTP handling (WebSocketsMediator). -- Fixed use of Value notification in circuits.web for requests. -- Fixed a bunch of examples and tests using deprecated features. -- Fixed the notify io driver and removed Debugger() from test_notify. -- Added man pages for circuits.bench, circuits.sniff and circuits.web -- Wrapped UNIX-specific calls in try/except -- Tidied up examples and removed unused imports -- removed use of coverage module in daemon test -- removed use of coverage module in signals test -- updated .push calls to .fire calls -- Fixed some deprecations warnings -- Added support for multiple webserver with different channels + tests for it -- Added support for silently ignoring errors when writing to stderr from debugger -- Added requirements.txt file containing requirements for building docs on readthedocs.org -- Added link to Read the Docs for circuits -- Updated doc message for success event -- Fixed interrupt handler to allow ^C to be used to quit sample keyecho app -- Removed deprecated modules and functions that were deprecated 1.6 -- Deleted old style event success/failure notifiers -- Fixed handling of components being added/removed when looking for ticks -- Fixed bug with ``net.Server`` .host and .port attributes. -- Deprecated ``__tick__``. Event handlers can now be specified as **tick** functions. -- Fixed handler priority inheritance to make sure we get the results in the right harder -- Fixed missing import of sys in circuits.io - - -circuits-1.6 (oceans) - 20110626 --------------------------------- - -- Added Python 3 support -- 80% Code Coverage -- Added optional greenlet support adding two new primitives. - ``.waitEvent(...)`` and ``.callEvent(...)``. -- Added an example WebSockets server using circuits.web -- Added support for specifying a ``Poll`` instance to use when using the - ``@future`` decorator to create "future" event handlers. -- Added ``add_section``, ``has_section`` and ``set`` methods to - ``app.config.Config`` Component. -- Added support for running test suite with distutils ``python setup.py - test``. -- Added a ``_on_signal`` event handler on the ``BaseEnvironment`` Component - so that environments can be reloaded by listening to ``SIGHUP`` signals. -- Added support for using absolute paths in ``app.env.Environment``. -- Added support in circuits.web ``HTTP`` protocol to limit the no. of - header fragments. This prevents OOM exploits. -- Added a ticks limit to waitEvent -- Added deprecation warnings for .push .add and .remove methods -- NEW ``Loader`` Component in ``circuits.core`` for simple plugin support. -- NEW ``app.env`` and ``app.config`` modules including a new ``app.startup`` - modules integrating a common startup for applications. -- NEW ``KQueue`` poller -- Fixed :bbissue:`17` -- Renamed ``circuits.web.main`` module to ``circuits.web.__main__`` so that - ``python -m circuits.web`` just works. -- Fixed ``Server.host`` and ``Server.port`` properties in - ``circuits.net.sockets``. -- Fixed :bbissue:`10` -- Fixed ``app.Daemon`` Component to correctly open the stderr file. -- Fixed triggering of ``Success`` events. -- Fixed duplicate broadcast handler in ``UDPServer`` -- Fixed duplicate ``Disconnect`` event from being triggered twice on - ``Client`` socket components. -- Removed dynamic timeout code from ``Select`` poller. -- Fixed a bug in the circuits.web ``HTTP`` protocol where headers were - not being buffered per client. -- Fixes a missing Event ``Closed()`` not being triggered for ``UDPServer``. -- Make underlying ``UDPServer`` socket reusable by setting ``SO_REUSEADDR`` -- Fixes Server socket being discarded twice on close + disconnect -- Socket.write now expects bytes (bytes for python3 and str for python2) -- Better handling of encoding in HTTP Component (allow non utf-8 encoding) -- Always encode HTTP headers in utf-8 -- Fixes error after getting socket.ERRCONNREFUSED -- Allows TCPClient to bind to a specific port -- Improved docs -- Handles closing of UDPServer socket when no client is connected -- Adds an un-register handler for components -- Allows utils.kill to work from a different thread -- Fixes bug when handling "*" in channels and targets -- Fixes a bug that could occur when un-registering components -- Fixes for CPU usage problems when using circuits with no I/O pollers - and using a Timer for timed events diff -Nru circuits-2.1.0/docs/build/html/_sources/contributors.txt circuits-3.1.0+ds1/docs/build/html/_sources/contributors.txt --- circuits-2.1.0/docs/build/html/_sources/contributors.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/contributors.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,21 +0,0 @@ -Contributors -============ - -circuits was originally designed, written and primarily maintained by James -Mills (http://prologic.shortcircuit.net.au/). - -The following users and developers have contributed to circuits: - -- Alessio Deiana -- Dariusz Suchojad -- Tim Miller -- Holger Krekel -- Justin Giorgi -- Edwin Marshall -- Alex Mayfield -- Toni Alatalo -- Michael Lipp - -Anyone not listed here (*apologies as this list is taken directly from -Mercurial's churn command and output*). We appreciate any and all -contributions to circuits. diff -Nru circuits-2.1.0/docs/build/html/_sources/dev/contributing.txt circuits-3.1.0+ds1/docs/build/html/_sources/dev/contributing.txt --- circuits-2.1.0/docs/build/html/_sources/dev/contributing.txt 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/dev/contributing.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,51 +0,0 @@ -Contributing to circuits -======================== - -Here's how you can contribute to circuits - - -Share your story ----------------- - - -One of the best ways you can contribute to circuits is by using circuits. -Share with us your story of how you've used circuits to solve a problem -or create a new software solution using the circuits framework and library -of components. See our :doc:`Users Page `. - - -Submitting Bug Reports ----------------------- - - -We welcome all bug reports. We do however prefer bug reports in a clear -and concise form with repeatable steps. One of the best ways you can report -a bug to us is by writing a unit test (//similar to the ones in our tests//) -so that we can verify the bug, fix it and commit the fix along with the test. - -To submit a bug report, please use: - http://bitbucket.org/prologic/circuits/issues - - -Writing new tests ------------------ - - -We're not perfect, and we're still writing more tests to ensure quality code. -If you'd like to help, please `Fork circuits-dev `_, write more tests that cover more of our code base and -submit a `Pull Request `_. Many Thanks! - - -Adding New Features -------------------- - - -If you'd like to see a new feature added to circutis, then we'd like to hear -about it~ We would like to see some discussion around any new features as well -as valid use-cases. To start the discussions off, please either: - -- `Chat to us on #circuits on the FreeNode IRC Network `_ - - or - -- `Submit a NEW Issue `_ diff -Nru circuits-2.1.0/docs/build/html/_sources/dev/index.txt circuits-3.1.0+ds1/docs/build/html/_sources/dev/index.txt --- circuits-2.1.0/docs/build/html/_sources/dev/index.txt 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/dev/index.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,15 +0,0 @@ -Developer Docs -============== - -So, you'd like to contribute to circuits in some way? Got a bug report? -Having problems running the examples? Having problems getting circuits -working in your environment/platform? - -Excellent. Here's what you need to know. - -.. toctree:: - :maxdepth: 2 - - introduction - contributing - processes diff -Nru circuits-2.1.0/docs/build/html/_sources/dev/introduction.txt circuits-3.1.0+ds1/docs/build/html/_sources/dev/introduction.txt --- circuits-2.1.0/docs/build/html/_sources/dev/introduction.txt 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/dev/introduction.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,30 +0,0 @@ -Development Introduction -======================== - - -Here's how we do things in circuits... - - -Standards ---------- - -We use the following coding standard: - -- `pep8 `_ - - -Tools ------ - -We use the following tools to develop circuits and share code: - -- **Code Sharing:** - `Mercurial `_ -- **Code Hosting and Bug Reporting:** - `BitBucket `_ -- **Project Management:** - `Pivotal Tracker `_ -- **Documentation Hosting:** - `Read the Docs `_ -- **Package Hosting:** - `Python Package Index (PyPi) `_ diff -Nru circuits-2.1.0/docs/build/html/_sources/dev/processes.txt circuits-3.1.0+ds1/docs/build/html/_sources/dev/processes.txt --- circuits-2.1.0/docs/build/html/_sources/dev/processes.txt 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/dev/processes.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,74 +0,0 @@ -.. _Pivotal Tracker: http://pivotaltracker.com/projects/695621 - -Development Processes -===================== - - -We document all our internal development processes here so you know exactly -how we work and what to expect. If you find any issues or problems please -let us know! - - -Software Development Life Cycle (SDLC) --------------------------------------- - - -We employ the use of the `SCRUM Agile Process `_ and use `Pivotal Tracker`_ to track -our stories, bugs, chores and releases. If you wish to contribute -to circuits, please famiilarize yourself with SCRUM and Pivotal Tracker. - - -Bug Reports ------------ - - -- New Bug Reports are submitted via: - http://bitbucket.org/prologic/circuits/issues -- Confirmation and Discussion of all New Bug Reports. -- Once confirmed, a new Bug is raised in `Pivotal Tracker`_ into the IceBox. - - -Feature Requests ----------------- - - -- New Feature Requests are submitted via: - http://bitbucket.org/prologic/circuits/issues -- Confirmation and Discussion of all New Feature Requests. -- Once confirmed, a new Feature is raised in `Pivotal Tracker`_ into the IceBox. - - -Writing new Code ----------------- - - -- Write your code. -- Use `flake8 `_ to ensure code quality. -- Run the tests:: - - $ tox - -- Ensure any new or modified code does not break existing unit tests. -- Updated any relevant docstrings or documentatino. - - -Running the Tests ------------------ - - -To run the tests you will need the following installed: - -- `tox `_ instaleld as well as -- `pytest-cov `_ -- `pytest `_ - -All of these can be instaleld via ``easy_isntall`` or ``pip``. - -Please also ensure that you you have all supported versions of Python -that circuits supports installed in your local environment. - -To run the tests:: - - $ tox - - diff -Nru circuits-2.1.0/docs/build/html/_sources/faq.txt circuits-3.1.0+ds1/docs/build/html/_sources/faq.txt --- circuits-2.1.0/docs/build/html/_sources/faq.txt 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/faq.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,54 +0,0 @@ -.. _#circuits IRC Channel: http://webchat.freenode.net/?randomnick=1&channels=circuits&uio=d4 -.. _Mailing List: http://groups.google.com/group/circuits-users - -.. faq: - -Frequently Asked Questions -========================== - - -.. general: - -General -------- - -... What is circuits? - circuits is an event-driven framework with a high focus on Component - architectures making your life as a software developer much easier. - circuits allows you to write maintainable and scalable systems easily - -... Can I write networking applications with circuits? - Yes absolutely. circuits comes with socket I/O components for tcp, udp - and unix sockets with asynchronous polling implementations for select, - poll, epoll and kqueue. - -... Can I integrate circuits with a GUI library? - This is entirely possible. You will have to hook into the GUI's main loop. - -... What are the core concepts in circuits? - Components and Events. Components are maintainable reusable units of - behavior that communicate with other components via a powerful message - passing system. - -... How would you compare circuits to Twisted? - Others have said that circuits is very elegant in terms of it's usage. - circuits' component architecture allows you to define clear interfaces - between components while maintaining a high level of scalability and - maintainability. - -... Can Components communicate with other processes? - Yes. circuits implements currently component bridging and nodes - -... What platforms does circuits support? - circuits currently supports Linux, FreeBSD, OSX and Windows and is - currently continually tested against Linux and Windows against Python - versions 2.6, 2.7, 3.1 and 3.2 - -... Can circuits be used for concurrent or distributed programming? - Yes. We also have plans to build more distributed components into circuits - making distributing computing with circuits very trivial. - -Got more questions? - -* Send an email to our `Mailing List`_. -* Talk to us online on the `#circuits IRC Channel`_ diff -Nru circuits-2.1.0/docs/build/html/_sources/glossary.txt circuits-3.1.0+ds1/docs/build/html/_sources/glossary.txt --- circuits-2.1.0/docs/build/html/_sources/glossary.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/glossary.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,9 +0,0 @@ -======== -Glossary -======== - -.. glossary:: - :sorted: - - VCS - Version Control System, what you use for versioning your source code diff -Nru circuits-2.1.0/docs/build/html/_sources/howtos/index.txt circuits-3.1.0+ds1/docs/build/html/_sources/howtos/index.txt --- circuits-2.1.0/docs/build/html/_sources/howtos/index.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/howtos/index.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,8 +0,0 @@ -====== -HowTos -====== - -.. toctree:: - :maxdepth: 1 - - simple_server diff -Nru circuits-2.1.0/docs/build/html/_sources/howtos/simple_server.txt circuits-3.1.0+ds1/docs/build/html/_sources/howtos/simple_server.txt --- circuits-2.1.0/docs/build/html/_sources/howtos/simple_server.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/howtos/simple_server.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,126 +0,0 @@ -How To: Build a Simple Server -============================= - - -Overview --------- - -In this guide we're going to walk through the steps required to build a -simple chat server. Users will connect using a standard telnet client and -start chatting with other users that are connected. - - -Prerequisites -^^^^^^^^^^^^^ - -- `Python `_ -- `circuits `_ - - -Components Used -""""""""""""""" - -- :py:class:`~circuits.core.components.Component` -- :py:class:`~circuits.net.sockets.TCPServer` - - -Events Used -""""""""""" - -- :py:class:`~circuits.net.sockets.Write` - - -Step 1 - Setting up -------------------- - -Let's start off by importing the components and events we'll need. - -.. code-block:: python - - #!/usr/bin/env python - - from circuits import Component - from circuits.net.sockets import TCPServer, Write - - -Step 2 - Building the Server ----------------------------- - -Next let's define our ``Server`` Component with a simple event handler that -broadcasts all incoming messages to every connected client. We'll keep a list -of clients connected to our server in ``self._clients``. - -We need to define three event handlers. - -#. An event handler to update our list of connected clients when a new client - connects. -#. An event handler to update our list of connected clients when a client has - disconnected. -#. An event handler to handle messages from connected clients and broadcast - them to every other connected client. - - -.. code-block:: python - - class Server(Component): - - def __init__(self, host, port=8000): - super(Server, self).__init__() - - self._clients = [] - - TCPServer((host, port)).register(self) - - def connect(self, sock, host, port): - self._clients.append(sock) - - def disconnect(self, sock): - self._clients.remove(sock) - - def read(self, sock, data): - for client in self._clients: - if not client == sock: - self.fire(Write(client, data.strip())) - - -Let's walk through this in details: - -1. Create a new Component called ``Server`` -2. Define its initialization arguments as ``(host, port=8000)`` -3. Call the super constructor of the underlying Component - (*This is important as all components need to be initialized properly*) -4. Register a ``TCPServer`` Component and configure it. -5. Create Event Handlers for: - - - Dealing with new connecting clients. - - Dealing with clients whom have disconnected. - - Dealing with messages from connected clients. - - -Step 3 - Running the Server ---------------------------- - -The last step is simply to create an instance of the ``Server`` Component -and run it (*making sure to configure it with a host and port*). - -.. code-block:: python - - Server("localhost").run() - -That's it! - -Using a standard telnet client try connecting to localhost on port 8000. -Try connecting a second client and watch what happens in the 2nd client -when you type text into the 1st. - -Enjoy! - - -Source Code ------------ - -.. literalinclude:: simple_server.py - :language: python - :linenos: - -:download:`Download simple_server.py ` diff -Nru circuits-2.1.0/docs/build/html/_sources/index.txt circuits-3.1.0+ds1/docs/build/html/_sources/index.txt --- circuits-2.1.0/docs/build/html/_sources/index.txt 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/index.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,59 +0,0 @@ -================================ -circuits |version| Documentation -================================ - - -:Release: |release| -:Date: |today| - - -.. include:: ../../README.rst - - -Contents -======== - - -.. toctree:: - :maxdepth: 1 - - start/index - tutorial/index - man/index - web/index - howtos/index - api/index - dev/index - changes - users - contributors - faq - -.. toctree:: - :hidden: - - glossary - users - -.. ifconfig:: devel - - .. toctree:: - :hidden: - - pypitest - todo - - -Indices and tables -================== - - -* :ref:`Index ` -* :ref:`modindex` -* :ref:`search` -* :doc:`glossary` - -.. ifconfig:: devel - - * :doc:`pypitest` - * :doc:`todo` diff -Nru circuits-2.1.0/docs/build/html/_sources/man/components.txt circuits-3.1.0+ds1/docs/build/html/_sources/man/components.txt --- circuits-2.1.0/docs/build/html/_sources/man/components.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/man/components.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,32 +0,0 @@ -Components -========== - -The architectural concept of circuits is to encapsulate system -functionality into discrete manageable and reusable units, called *Components*, -that interact by sending and handling events that flow throughout the system. - -Technically, a circuits *Component* is a Python class that inherits -(directly or indirectly) from -:class:`~circuits.core.components.BaseComponent`. - -Components can be sub-classed like any other normal Python class, however -components can also be composed of other components and it is natural -to do so. These are called *Complex Components*. An example of a Complex -Component within the circuits library is the -:class:`circuits.web.servers.Server` Component which is comprised of: - -- :class:`circuits.net.sockets.TCPServer` -- :class:`circuits.web.servers.BaseServer` -- :class:`circuits.web.http.HTTP` -- :class:`circuits.web.dispatchers.dispatcher.Dispatcher` - -Note that there is no class or other technical means to mark a component -as a complex component. Rather, all component instances in a circuits -based application belong to some component tree (there may be several), -with Complex Components being a subtree within that structure. - -A Component is attached to the tree by registering with the parent and -detached by un-registering itself (methods -:meth:`~circuits.core.components.BaseComponent.register` and -:meth:`~circuits.core.components.BaseComponent.unregister` of -``BaseComponent``). \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/_sources/man/debugging.txt circuits-3.1.0+ds1/docs/build/html/_sources/man/debugging.txt --- circuits-2.1.0/docs/build/html/_sources/man/debugging.txt 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/man/debugging.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,5 +0,0 @@ -Debugging -========= - - -.. todo:: Write about this ... diff -Nru circuits-2.1.0/docs/build/html/_sources/man/events.txt circuits-3.1.0+ds1/docs/build/html/_sources/man/events.txt --- circuits-2.1.0/docs/build/html/_sources/man/events.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/man/events.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,84 +0,0 @@ -Events -====== - -Basic usage ------------ - -Events are objects that are fired by the circuits framework implicitly -(like the :class:`~circuits.core.events.Started` event used in the tutorial) -or explicitly by components while handling some other event. Once fired, -events are dispatched to the components that are interested in these events, -i.e. that have registered themselves as handlers for these events. - -Events are usually fired on one or more channels, allowing components -to gather in "interest groups". This is especially useful if you want to -reuse basic components such as a TCP server. A TCP server component -fires a ``Read`` event for every package of data that it receives. If we -hadn't the channels, it would be very difficult to separate the data from -two different TCP connections. But using the channels, we can put one TCP -server and all components interested in its events on one channel, and -another TCP server and the components interested in this other TCP server's -events on another channel. Components are associated with a channel by -setting their ``channel`` attribute (see API description for -:class:`~.components.Component`). - -Besides having a name, events carry additional arbitrary information. -This information is passed as arguments or keyword arguments to the -constructor. It is then delivered to the handler function that must have -exactly the same number of arguments and keyword arguments. Of course, -as is usual in Python, you can also pass additional information by setting -attributes of the event object, though this usage pattern is discouraged -for events. - -Events as result collectors ---------------------------- - -Apart from delivering information to handlers, event objects may also collect -information. If a handler returns something that is not ``None``, it is -stored in the event's ``value`` attribute. If a second (or any subsequent) -handler invocation also returns a value, the values are stored as a list. -Note that the value attribute is of type :class:`~.values.Value` and you -must access its property ``value`` to access the data stored -(``collected_information = event.value.value``). - -The collected information can be accessed by handlers in order to find out -about any return values from the previously invoked handlers. More useful -though, is the possibility to access the information after all handlers -have been invoked. After all handlers have run successfully (i.e. no -handler has thrown an error) circuits may generate an event that indicates -the successful handling. This event has the name of the event -just handled with "Success" appended. So if the event is called ``Identify`` -then the success event is called ``IdentifySuccess``. Success events aren't -delivered by default. If you want successful handling to be indicated -for an event, you have to set the optional attribute ``success`` of this -event to ``True``. - -The handler for a success event must be defined with two arguments. When -invoked, the first argument is the event just having been handled -successfully and the second argument is (as a convenience) what has been -collected in ``event.value.value`` (note that the first argument may not -be called ``event``, for an explanation of this restriction as well as -for an explanation why the method is called ``identify_success`` -see the section on handlers). - -.. literalinclude:: examples/handler_returns.py - :language: python - :linenos: - -:download:`Download handler_returns.py ` - - -Advanced usage --------------- - -Sometimes it may be necessary to take some action when all state changes -triggered by an event are in effect. In this case it is not sufficient -to wait for the completion of all handlers for this particular event. -Rather, we also have to wait until all events that have been fired by -those handlers have been processed (and again wait for the events fired by -those events' handlers, and so on). To support this scenario, circuits -can fire a ``Complete`` event. The usage is similar to the previously -described success event. Details can be found in the API description of -:class:`circuits.core.events.Event`. - - diff -Nru circuits-2.1.0/docs/build/html/_sources/man/handlers.txt circuits-3.1.0+ds1/docs/build/html/_sources/man/handlers.txt --- circuits-2.1.0/docs/build/html/_sources/man/handlers.txt 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/man/handlers.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,74 +0,0 @@ -Handlers -======== - - -Explicit Event Handlers ------------------------ - - -Event Handlers are methods of components that are invoked when a matching -event is dispatched. These can be declared explicitly on a -:class:`~circuits.core.components.BaseComponent` or -:class:`~circuits.core.components.Component` or by using the -:func:`~circuits.core.handlers.handler` decorator. - -.. literalinclude:: examples/handler_annotation.py - :language: python - :linenos: - -:download:`Download handler_annotation.py ` - -The handler decorator on line 14 turned the method ``_on_started`` into an -event handler for the event ``Started``. Event names used to define -handlers are the uncameled class names of the event. An event with a class -name ``MySpecialEvent`` becomes "``my_special_event``" when referred to -in a handler definition. - -When defining explicit event handlers in this way, it's convention to -use the following pattern:: - - @handler("foo") - def _on_foo(self, ...): - ... - -This makes reading code clear and concise and obvious to the reader -that the method is not part of the class's public API -(*leading underscore as per Python convention*) and that it is invoked -for events of type ``SomeEvent``. - -The optional keyword argument "``channel``" can be used to attach the -handler to a different channel than the component's channel -(*as specified by the component's channel attribute*). - -Handler methods must be declared with arguments and keyword arguments that -match the arguments passed to the event upon its creation. Looking at the -API for :class:`~circuits.core.events.Started` you'll find that the -component that has been started is passed as an argument to its constructor. -Therefore, our handler method must declare one argument (*Line 15*). - -The ``@handler(...)`` decorator accepts other keyword arguments that -influence the behavior of the event handler and its invocation. Details can -be found in the API description of :func:`~circuits.core.handlers.handler`. - - -Implicit Event Handlers ------------------------ - - -To make things easier for the developer when creating many event handlers -and thus save on some typing, the :class:`~circuits.core.components.Component` -can be used and subclassed instead which provides an implicit mechanism for -creating event handlers. - -Basically every method in the component is automatically and implicitly -marked as an event handler with ``@handler(>`` is -the name of each method applied. - -The only exceptions are: - -- Methods are start with an underscore ``_``. -- Methods already marked explicitly with the ``@handler(...)`` decorator. - -.. note:: - You can specify that a method not be an event handler by marking it with - ``@handler(False)``. diff -Nru circuits-2.1.0/docs/build/html/_sources/man/index.txt circuits-3.1.0+ds1/docs/build/html/_sources/man/index.txt --- circuits-2.1.0/docs/build/html/_sources/man/index.txt 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/man/index.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,18 +0,0 @@ -====================== -The circuits Framework -====================== - -.. toctree:: - :maxdepth: 2 - - components - events - handlers - -.. toctree:: - :hidden: - - values - debugging - tools - manager diff -Nru circuits-2.1.0/docs/build/html/_sources/man/manager.txt circuits-3.1.0+ds1/docs/build/html/_sources/man/manager.txt --- circuits-2.1.0/docs/build/html/_sources/man/manager.txt 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/man/manager.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,5 +0,0 @@ -Manager -======= - - -.. todo:: Write about this... diff -Nru circuits-2.1.0/docs/build/html/_sources/man/tools.txt circuits-3.1.0+ds1/docs/build/html/_sources/man/tools.txt --- circuits-2.1.0/docs/build/html/_sources/man/tools.txt 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/man/tools.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,5 +0,0 @@ -Tools -===== - - -.. todo:: Write about this ... diff -Nru circuits-2.1.0/docs/build/html/_sources/man/values.txt circuits-3.1.0+ds1/docs/build/html/_sources/man/values.txt --- circuits-2.1.0/docs/build/html/_sources/man/values.txt 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/man/values.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,5 +0,0 @@ -Values -====== - - -.. todo:: Write about this... diff -Nru circuits-2.1.0/docs/build/html/_sources/pypitest.txt circuits-3.1.0+ds1/docs/build/html/_sources/pypitest.txt --- circuits-2.1.0/docs/build/html/_sources/pypitest.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/pypitest.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,8 +0,0 @@ -PyPi Test Page - Tentative Release -================================== - - -.. include:: ../../README.rst - - -.. include:: ../../RELEASE.rst diff -Nru circuits-2.1.0/docs/build/html/_sources/start/downloading.txt circuits-3.1.0+ds1/docs/build/html/_sources/start/downloading.txt --- circuits-2.1.0/docs/build/html/_sources/start/downloading.txt 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/start/downloading.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ -Downloading -=========== - - -Latest Stable Release ---------------------- - -The latest stable releases can be downloaded from the -`Downloads `_ page -(*specifically the Tags tab*). - - -Latest Development Source Code ------------------------------- - -We use `Mercurial `_ for source control -and code sharing. - -The latest development branch can be cloned using the following command: - -.. code-block:: sh - - $ hg clone https://bitbucket.org/prologic/circuits/ - -For further instructions on how to use Mercurial, please refer to the -`Mercurial Book `_. diff -Nru circuits-2.1.0/docs/build/html/_sources/start/index.txt circuits-3.1.0+ds1/docs/build/html/_sources/start/index.txt --- circuits-2.1.0/docs/build/html/_sources/start/index.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/start/index.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -Getting Started -=============== - -.. toctree:: - :maxdepth: 2 - - quick - downloading - installing - requirements diff -Nru circuits-2.1.0/docs/build/html/_sources/start/installing.txt circuits-3.1.0+ds1/docs/build/html/_sources/start/installing.txt --- circuits-2.1.0/docs/build/html/_sources/start/installing.txt 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/start/installing.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,42 +0,0 @@ -Installing -========== - - -Installing from a Source Package --------------------------------- -*If you have downloaded a source archive, this applies to you.* - - -.. code-block:: sh - - $ python setup.py install - -For other installation options see: - -.. code-block:: sh - - $ python setup.py --help install - - -Installing from the Development Repository ------------------------------------------- -*If you have cloned the source code repository, this applies to you.* - - -If you have cloned the development repository, it is recommended that you -use setuptools and use the following command: - -.. code-block:: sh - - $ python setup.py develop - -This will allow you to regularly update your copy of the circuits development -repository by simply performing the following in the circuits working directory: - -.. code-block:: sh - - $ hg pull -u - -.. note:: - You do not need to reinstall if you have installed with setuptools via - the circuits repository and used setuptools to install in "develop" mode. diff -Nru circuits-2.1.0/docs/build/html/_sources/start/quick.txt circuits-3.1.0+ds1/docs/build/html/_sources/start/quick.txt --- circuits-2.1.0/docs/build/html/_sources/start/quick.txt 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/start/quick.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,30 +0,0 @@ -.. _pip: http://pypi.python.org/pypi/pip - - -Quick Start Guide -================= - - -The easiest way to download and install circuits is to use the -`pip`_ command: - -.. code-block:: sh - - $ pip install circuits - - -Now that you have successfully downloaded and installed circuits, let's -test that circuits is properly installed and working. - -First, let's check the installed version: - -.. code-block:: python - - >>> import circuits - >>> print circuits.__version__ - 2.1.0 - -Try some of the examples in the examples/ directory shipped with the -distribution or check out some :doc:`Applications using circuits <../users>` - -Have fun :) diff -Nru circuits-2.1.0/docs/build/html/_sources/start/requirements.txt circuits-3.1.0+ds1/docs/build/html/_sources/start/requirements.txt --- circuits-2.1.0/docs/build/html/_sources/start/requirements.txt 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/start/requirements.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,28 +0,0 @@ -.. _Python Standard Library: http://docs.python.org/library/ - - -Requirements and Dependencies -============================= - - -- circuits has no **required** dependencies beyond the `Python Standard Library`_. -- Python: >= 2.6 or pypy >= 2.0 - -:Supported Platforms: Linux, FreeBSD, Mac OS X, Windows - -:Supported Python Versions: 2.6, 2.7, 3.2, 3.3 - -:Supported pypy Versions: 2.0 - - -Other Optional Dependencies ---------------------------- - -These dependencies are not strictly required and only add additional -features. - -- `pydot `_ - -- For rendering component graphs of an application. -- `pyinotify `_ - -- For asynchronous file system event notifications - and the :mod:`circuits.io.notify` module. diff -Nru circuits-2.1.0/docs/build/html/_sources/todo.txt circuits-3.1.0+ds1/docs/build/html/_sources/todo.txt --- circuits-2.1.0/docs/build/html/_sources/todo.txt 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/todo.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,5 +0,0 @@ -Documentation TODO -================== - - -.. todolist:: diff -Nru circuits-2.1.0/docs/build/html/_sources/tutorial/index.txt circuits-3.1.0+ds1/docs/build/html/_sources/tutorial/index.txt --- circuits-2.1.0/docs/build/html/_sources/tutorial/index.txt 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/tutorial/index.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,348 +0,0 @@ -.. _Python Programming Language: http://www.python.org/ - - -Tutorial -======== - - -Overview --------- - -Welcome to the circuits tutorial. This 5-minute tutorial will guide you -through the basic concepts of circuits. The goal is to introduce -new concepts incrementally with walk-through examples that you can try out! -By the time you've finished, you should have a good basic understanding -of circuits, how it feels and where to go from there. - - -The Component -------------- - -First up, let's show how you can use the ``Component`` and run it in a very -simple application. - -.. literalinclude:: 001.py - :language: python - :linenos: - -:download:`Download 001.py <001.py>` - -Okay so that's pretty boring as it doesn't do very much! But that's okay... -Read on! - -Let's try to create our own custom Component called ``MyComponent``. - -.. literalinclude:: 002.py - :language: python - :linenos: - -:download:`Download 002.py <002.py>` - -Okay, so this still isn't very useful! But at least we can create -components with the behavior we want. - -Let's move on to something more interesting... - - -Event Handlers --------------- - -Let's now extend our little example to say "Hello World!" when its started. - -.. literalinclude:: 003.py - :language: python - :linenos: - -:download:`Download 003.py <003.py>` - -Here we've created a simple **Event Handler** that listens for events on -the "started" channel. Methods defined in a Component are converted into -Event Handlers. - -Running this we get:: - - Hello World! - - -Alright! We have something slightly more useful! Whoohoo it says hello! - -.. note:: Press ^C (*CTRL + C*) to exit. - - -Registering Components ----------------------- - -So now that we've learned how to use a Component, create a custom Component -and create simple Event Handlers, let's try something a bit more complex -by creating a complex component made up of two simpler ones. - -Let's create two components: - -- ``Bob`` -- ``Fred`` - -.. literalinclude:: 004.py - :language: python - :linenos: - -:download:`Download 004.py <004.py>` - -Notice the way we register the two components ``Bob`` and ``Fred`` together -? Don't worry if this doesn't make sense right now. Think of it as putting -two components together and plugging them into a circuits board. - -Running this example produces the following result:: - - Hello I'm Bob! - Hello I'm Fred! - -Cool! We have two components that each do something and print a simple -message on the screen! - - -Complex Components ------------------- - -Now, what if we wanted to create a Complex Component? Let's say we wanted -to create a new Component made up of two other smaller components? - -We can do this by simply registering components to a Complex Component -during initialization. - -.. literalinclude:: 005.py - :language: python - :linenos: - -:download:`Download 005.py <005.py>` - -So now ``Pound`` is a Component that consists of two other components -registered to it: ``Bob`` and ``Fred`` - -The output of this is identical to the previous:: - - * - * - * - Hello I'm Bob! - Hello I'm Fred! - -The only difference is that ``Bob`` and ``Fred`` are now part of a more -Complex Component called ``Pound``. This can be illustrated by the -following diagram: - -.. graphviz:: - - digraph G { - "Pound-1344" -> "Bob-9b0c"; - "Pound-1344" -> "Fred-e98a"; - } - -.. note:: - The extra lines in the above output are an ASCII representation of the - above graph (*produced by pydot + graphviz*). - -Cool :-) - - -Component Inheritance ---------------------- - -Since circuits is a framework written for the `Python Programming -Language`_ it naturally inherits properties of Object Orientated -Programming (OOP) -- such as inheriaence. - -So let's take our ``Bob`` and ``Fred`` components and create a Base -Component called ``Dog`` and modify our two dogs (``Bob`` and ``Fred``) to -subclass this. - -.. literalinclude:: 006.py - :language: python - :linenos: - -:download:`Download 006.py <006.py>` - -Now let's try to run this and see what happens:: - - Woof! I'm Bob! - Woof! I'm Fred! - -So both dogs barked! Hmmm - - -Component Channels ------------------- - -What if we only want one of our dogs to bark? How do we do this without -causing the other one to bark as well? - -Easy! Use a separate ``channel`` like so: - -.. literalinclude:: 007.py - :language: python - :linenos: - -:download:`Download 007.py <007.py>` - -.. note:: - Events can be fired with either the ``.fire(...)`` or ``.fireEvent(...)`` - method. - -If you run this, you'll get:: - - Woof! I'm Bob! - - -Event Objects -------------- - -So far in our tutorial we have been defining an Event Handler for a builtin -Event called ``Started`` (*which incidentally gets fired on a channel called -"started"*). What if we wanted to define our own Event Handlers and our own -Events? You've already seen how easy it is to create a new Event Handler -by simply defining a normal Python method on a Component. - -Defining your own Events helps with documentation and testing and makes -things a little easier. - -Example:: - - class MyEvent(Event): - """MyEvent""" - -So here's our example where we'll define a new Event called ``Bark`` -and make our ``Dog`` fire a ``Bark`` event when our application starts up. - -.. literalinclude:: 008.py - :language: python - :linenos: - -:download:`Download 008.py <008.py>` - -If you run this, you'll get:: - - Woof! I'm Bob! - Woof! I'm Fred! - - -The Debugger ------------- - -Lastly... - -Asynchronous programming has many advantages but can be a little harder to -write and follow. A silently caught exception in an Event Handler, or an Event -that never gets fired, or any number of other weird things can cause your -application to fail and leave you scratching your head. - -Fortunately circuits comes with a ``Debugger`` Component to help you keep -track of what's going on in your application, and allows you to tell what -your application is doing. - -Let's say that we defined out ``bark`` Event Handler in our ``Dog`` -Component as follows:: - - def bark(self): - print("Woof! I'm %s!" % name) - -Now clearly there is no such variable as ``name`` in the local scope. - -For reference here's the entire example... - -.. literalinclude:: 009.py - :language: python - :linenos: - -:download:`Download 009.py <009.py>` - -If you run this, you'll get: - -That's right! You get nothing! Why? Well in circuits any error or -exception that occurs in a running application is automatically caught and -dealt with in a way that lets your application "keep on going". Crashing is -unwanted behavior in a system so we expect to be able to recover from -horrible situations. - -SO what do we do? Well that's easy. circuits comes with a ``Debugger`` -that lets you log all events as well as all errors so you can quickly and -easily discover which Event is causing a problem and which Event Handler to -look at. - -If you change Line 34 of our example... - -From: - -.. literalinclude:: 009.py - :language: python - :lines: 34 - -To: - -.. code-block:: python - - from circuits import Debugger - - (Pound() + Debugger()).run() - -Then run this, you'll get the following:: - - , ] {}> - , ] {}> - , ] {}> - , None] {}> - - - , NameError("global name 'name' is not defined",), [' File "/home/prologic/work/circuits/circuits/core/manager.py", line 459, in __handleEvent\n retval = handler(*eargs, **ekwargs)\n', ' File "source/tutorial/009.py", line 22, in bark\n print("Woof! I\'m %s!" % name)\n'], >] {}> - ERROR (): global name 'name' is not defined - File "/home/prologic/work/circuits/circuits/core/manager.py", line 459, in __handleEvent - retval = handler(*eargs, **ekwargs) - File "source/tutorial/009.py", line 22, in bark - print("Woof! I'm %s!" % name) - - , NameError("global name 'name' is not defined",), [' File "/home/prologic/work/circuits/circuits/core/manager.py", line 459, in __handleEvent\n retval = handler(*eargs, **ekwargs)\n', ' File "source/tutorial/009.py", line 22, in bark\n print("Woof! I\'m %s!" % name)\n'], >] {}> - ERROR (): global name 'name' is not defined - File "/home/prologic/work/circuits/circuits/core/manager.py", line 459, in __handleEvent - retval = handler(*eargs, **ekwargs) - File "source/tutorial/009.py", line 22, in bark - print("Woof! I'm %s!" % name) - - ^C] {}> - ] {}> - ] {}> - -You'll notice whereas there was no output before there is now a pretty -detailed output with the ``Debugger`` added to the application. Looking -through the output, we find that the application does indeed start -correctly, but when we fire our ``Bark`` Event it coughs up two exceptions, -one for each of our dogs (``Bob`` and ``Fred``). - -From the error we can tell where the error is and roughly where to look in -the code. - -.. note:: - You'll notice many other events that are displayed in the above output. - These are all default events that circuits has builtin which your - application can respond to. Each builtin Event has a special meaning - with relation to the state of the application at that point. - - See: :py:mod:`circuits.core.events` for detailed documentation regarding - these events. - -The correct code for the ``bark`` Event Handler should be:: - - def bark(self): - print("Woof! I'm %s!" % self.name) - -Running again with our correction results in the expected output:: - - Woof! I'm Bob! - Woof! I'm Fred! - -That's it folks! - -Hopefully this gives you a feel of what circuits is all about and an easy -tutorial on some of the basic concepts. As you're no doubt itching to get -started on your next circuits project, here's some recommended reading: - -- :doc:`../faq` -- :doc:`../howtos/index` -- :doc:`../api/index` diff -Nru circuits-2.1.0/docs/build/html/_sources/users.txt circuits-3.1.0+ds1/docs/build/html/_sources/users.txt --- circuits-2.1.0/docs/build/html/_sources/users.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/users.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,33 +0,0 @@ -Users -===== - - -Applications written in circuits --------------------------------- - -- `SahrisWiki `_ - a Wiki / CMS / Blogging Engine. -- `kdb `_ - a pluggable IRC Bot Framework. - - -Applications integrating circuits ---------------------------------- - -- `realXtend `) - Next generation virtual worlds viewer; Naali, for Python components. - Worked on by Toni Alatalo and Petri Aura at `Playsign - ` in collaboration with other realXtend developers. -- `PriceWaterHouseCoopers `) - `TAMS `_ Report Generator written by James Mills - and Michael Anton. -- `Mangahelpers `_ - Profiler for checking our webpages generation times, SQL and cache queries - times, project page on - - -Other Users ------------ - -- `MIT Media Lab, `_ - Uses circuits for several internal prototypes diff -Nru circuits-2.1.0/docs/build/html/_sources/web/basics.txt circuits-3.1.0+ds1/docs/build/html/_sources/web/basics.txt --- circuits-2.1.0/docs/build/html/_sources/web/basics.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/web/basics.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,50 +0,0 @@ -The Basics -========== - -circuits.web is not a **full stack** web framework, rather -it is more closely aligned with `CherryPy `_ -and offers enough functionality to make quickly developing web applications -easy and as flexible as possible. circuits.web does not provide features such -as: - -* builtin Templating -* builtin Database or ORM tools -* **etc** - -The functionality that circutis.web *does* provide ensures that circuits.web -is fully HTTP/1.1 and WSGI/1.0 compliant and offers all the essential tools -you need to build your web application or website. - -A Stand Alone Server --------------------- - -A stand alone server consist of the components shown in section -:ref:`web_getting_started`. The process of handling an HTTP request starts -with the :class:`~circuits.net.sockets.TCPServer` receiving a chunk -of bytes. It emits those bytes as a :class:`~circuits.net.sockets.Read` -event on the channel shared by the Server, HTTP, TCPServer and -Dispatcher components ("web" by default). - -The Read events are handled by the -:class:`~circuits.web.http.HTTP` component. It collects the chunks until -a complete HTTP request has been received. The request is then emitted as -a :class:`~circuits.web.events.Request` event with an instance of -classes :class:`~circuits.web.wrappers.Request` and -:class:`~circuits.web.wrappers.Response` each as arguments. To complete -the client's request, a :class:`~circuits.web.events.Response` event must be -fired. This is usually done by the HTTP component itself upon the -receipt of a ``RequestSuccess`` event (automatically generated -after all handlers for the ``Request`` event have been invoked -successfully). In case of a problem, the ``Request`` event's handlers should -fire or return a :class:`~circuits.web.errors.HTTPError` which is instead -converted by the HTTP component to a ``Response`` event. - -HTTP's handler for the :class:`~circuits.web.events.Response` -event retrieves the response information from the -event and encodes it as required by HTTP (the protocol). It then -fires one or more :class:`~circuits.net.sockets.Write` events -which are handled by the TCPServer (and the response is thus sent to -the client). More details can be found in :ref:`circuits_web_http`. - -A commonly used component for handling :class:`~circuits.web.events.Request` -events is a dispatcher. [To be continued] \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/_sources/web/gettingstarted.txt circuits-3.1.0+ds1/docs/build/html/_sources/web/gettingstarted.txt --- circuits-2.1.0/docs/build/html/_sources/web/gettingstarted.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/web/gettingstarted.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,67 +0,0 @@ -.. _web_getting_started: - -Getting Started -=============== - -Just like any application or system built with circuits, a circuits.web -application follows the standard Component based design and structure -whereby functionality is encapsulated in components. circuits.web -itself is designed and built in this fashion. For example a circuits.web -Server's structure looks like this: - -.. image:: ../images/web.png - -To illustrate the basic steps, we will demonstrate developing -your classical "Hello World!" applications in a web-based way -with circuits.web - -To get started, we first import the necessary components: - -.. code-block:: python - - from circutis.web import Server, Controller - - -Next we define our first Controller with a single Request Handler -defined as our index. We simply return "Hello World!" as the response -for our Request Handler. - -.. code-block:: python - - class Root(Controller): - - def index(self): - return "Hello World!" - - -This completes our simple web application which will respond with -"Hello World!" when anyone accesses it. - -*Admittedly this is a stupidly simple web application! But circuits.web is -very powerful and plays nice with other tools.* - -Now we need to run the application: - -.. code-block:: python - - (Server(8000) + Root()).run() - - -That's it! Navigate to: http://127.0.0.1:8000/ and see the result. - -Here's the complete code: - -.. code-block:: python - :linenos: - - from circuits.web import Server, Controller - - class Root(Controller): - - def index(self): - return "Hello World!" - - (Server(8000) + Root()).run() - - -Have fun! diff -Nru circuits-2.1.0/docs/build/html/_sources/web/index.txt circuits-3.1.0+ds1/docs/build/html/_sources/web/index.txt --- circuits-2.1.0/docs/build/html/_sources/web/index.txt 2013-02-27 08:46:33.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/web/index.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -========================== -The circuits.web Framework -========================== - -.. toctree:: - :maxdepth: 1 - - introduction - gettingstarted - basics diff -Nru circuits-2.1.0/docs/build/html/_sources/web/introduction.txt circuits-3.1.0+ds1/docs/build/html/_sources/web/introduction.txt --- circuits-2.1.0/docs/build/html/_sources/web/introduction.txt 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_sources/web/introduction.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,106 +0,0 @@ -Introduction -============ - -circuits.web is a set of components for building high performance HTTP/1.1 -and WSGI/1.0 compliant web applications. These components make it easy to -rapidly develop rich, scalable web applications with minimal effort. - -circuits.web borrows from - -* `CherryPy `_ -* BaseHTTPServer (*Python std. lib*) -* wsgiref (*Python std. lib*) - -Overview --------- - -The ``circuits.web`` namespace contains the following exported components -and events for convenience: - -Events -~~~~~~ - -+---------------+-----------------------------------+ -| Event | Description | -+===============+===================================+ -| Request | The Request Event | -+---------------+-----------------------------------+ -| Response | The Response Event | -+---------------+-----------------------------------+ -| Stream | The Stream Event | -+---------------+-----------------------------------+ - -Servers -~~~~~~~ - -+---------------+-----------------------------------+ -| Server | Description | -+===============+===================================+ -| BaseServer | The Base Server (no Dispatcher) | -+---------------+-----------------------------------+ -| Server | The **full** Server + Dispatcher | -+---------------+-----------------------------------+ - -Error Events -~~~~~~~~~~~~ - -+---------------+-----------------------------------+ -| Error | Description | -+===============+===================================+ -| HTTPError | A generic HTTP Error Event | -+---------------+-----------------------------------+ -| Forbidden | A Forbidden (403) Event | -+---------------+-----------------------------------+ -| NotFound | A Not Found (404) Event | -+---------------+-----------------------------------+ -| Redirect | A Redirect (30x) Event | -+---------------+-----------------------------------+ - -Dispatchers -~~~~~~~~~~~ - -+---------------+-----------------------------------+ -| Dispatcher | Description | -+===============+===================================+ -| Static | A Static File Dispatcher | -+---------------+-----------------------------------+ -| Dispatcher | The Default Dispatcher | -+---------------+-----------------------------------+ -| VirtualHosts | Virtual Hosts Dispatcher | -+---------------+-----------------------------------+ -| XMLRPC | XML-RPC Dispatcher | -+---------------+-----------------------------------+ -| JSONRPC | JSON-RPC Dispatcher | -+---------------+-----------------------------------+ - -Other Components -~~~~~~~~~~~~~~~~ - -+---------------+-----------------------------------+ -| Component | Description | -+===============+===================================+ -| Logger | Default Logger | -+---------------+-----------------------------------+ -| Controller | Request Handler Mapper | -+---------------+-----------------------------------+ -| Sessions | Default Sessions Handler | -+---------------+-----------------------------------+ - -To start working with circuits.web one normally only needs to import -from circuits.web, for example: - -.. code-block:: python - :linenos: - - from circuits import Component - from circuits.web import BaseServer - - class Root(Component): - - def request(self, request, response): - return "Hello World!" - - (BaseServer(8000) + Root()).run() - -For further information regarding any of circuits.web's components, -events or other modules and functions refer to the API Documentation. diff -Nru circuits-2.1.0/docs/build/html/start/downloading.html circuits-3.1.0+ds1/docs/build/html/start/downloading.html --- circuits-2.1.0/docs/build/html/start/downloading.html 2013-02-27 11:28:03.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/start/downloading.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,204 +0,0 @@ - - - - - - - - - Downloading — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

Downloading

-
-

Latest Stable Release

-

The latest stable releases can be downloaded from the -Downloads page -(specifically the Tags tab).

-
-
-

Latest Development Source Code

-

We use Mercurial for source control -and code sharing.

-

The latest development branch can be cloned using the following command:

-
$ hg clone https://bitbucket.org/prologic/circuits/
-
-
-

For further instructions on how to use Mercurial, please refer to the -Mercurial Book.

-
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/start/index.html circuits-3.1.0+ds1/docs/build/html/start/index.html --- circuits-2.1.0/docs/build/html/start/index.html 2013-02-27 11:28:03.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/start/index.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,194 +0,0 @@ - - - - - - - - - Getting Started — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
- - - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/start/installing.html circuits-3.1.0+ds1/docs/build/html/start/installing.html --- circuits-2.1.0/docs/build/html/start/installing.html 2013-02-27 11:28:03.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/start/installing.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,217 +0,0 @@ - - - - - - - - - Installing — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

Installing

-
-

Installing from a Source Package

-

If you have downloaded a source archive, this applies to you.

-
$ python setup.py install
-
-
-

For other installation options see:

-
$ python setup.py --help install
-
-
-
-
-

Installing from the Development Repository

-

If you have cloned the source code repository, this applies to you.

-

If you have cloned the development repository, it is recommended that you -use setuptools and use the following command:

-
$ python setup.py develop
-
-
-

This will allow you to regularly update your copy of the circuits development -repository by simply performing the following in the circuits working directory:

-
$ hg pull -u
-
-
-
-

Note

-

You do not need to reinstall if you have installed with setuptools via -the circuits repository and used setuptools to install in “develop” mode.

-
-
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/start/quick.html circuits-3.1.0+ds1/docs/build/html/start/quick.html --- circuits-2.1.0/docs/build/html/start/quick.html 2013-02-27 11:28:03.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/start/quick.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,194 +0,0 @@ - - - - - - - - - Quick Start Guide — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

Quick Start Guide

-

The easiest way to download and install circuits is to use the -pip command:

-
$ pip install circuits
-
-
-

Now that you have successfully downloaded and installed circuits, let’s -test that circuits is properly installed and working.

-

First, let’s check the installed version:

-
>>> import circuits
->>> print circuits.__version__
-2.1.0
-
-
-

Try some of the examples in the examples/ directory shipped with the -distribution or check out some Applications using circuits

-

Have fun :)

-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/start/requirements.html circuits-3.1.0+ds1/docs/build/html/start/requirements.html --- circuits-2.1.0/docs/build/html/start/requirements.html 2013-02-27 11:28:03.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/start/requirements.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,217 +0,0 @@ - - - - - - - - - Requirements and Dependencies — circuits 2.1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-

circuits 2.1.0 documentation

- - -
- -
-
-
-
- -
-

Requirements and Dependencies

- - --- - - - - - - - - - - -
Supported Platforms:
 Linux, FreeBSD, Mac OS X, Windows
Supported Python Versions:
 2.6, 2.7, 3.2, 3.3
Supported pypy Versions:
 2.0
-
-

Other Optional Dependencies

-

These dependencies are not strictly required and only add additional -features.

-
    -
  • pydot -– For rendering component graphs of an application.
  • -
  • pyinotify -– For asynchronous file system event notifications -and the circuits.io.notify module.
  • -
-
-
- - -
-
-
- - - - - -
- -
- -
-
- -
-
- - \ No newline at end of file Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/html/_static/ajax-loader.gif and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/html/_static/ajax-loader.gif differ diff -Nru circuits-2.1.0/docs/build/html/_static/basic.css circuits-3.1.0+ds1/docs/build/html/_static/basic.css --- circuits-2.1.0/docs/build/html/_static/basic.css 2013-02-27 11:28:04.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_static/basic.css 1970-01-01 00:00:00.000000000 +0000 @@ -1,540 +0,0 @@ -/* - * basic.css - * ~~~~~~~~~ - * - * Sphinx stylesheet -- basic theme. - * - * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. - * :license: BSD, see LICENSE for details. - * - */ - -/* -- main layout ----------------------------------------------------------- */ - -div.clearer { - clear: both; -} - -/* -- relbar ---------------------------------------------------------------- */ - -div.related { - width: 100%; - font-size: 90%; -} - -div.related h3 { - display: none; -} - -div.related ul { - margin: 0; - padding: 0 0 0 10px; - list-style: none; -} - -div.related li { - display: inline; -} - -div.related li.right { - float: right; - margin-right: 5px; -} - -/* -- sidebar --------------------------------------------------------------- */ - -div.sphinxsidebarwrapper { - padding: 10px 5px 0 10px; -} - -div.sphinxsidebar { - float: left; - width: 230px; - margin-left: -100%; - font-size: 90%; -} - -div.sphinxsidebar ul { - list-style: none; -} - -div.sphinxsidebar ul ul, -div.sphinxsidebar ul.want-points { - margin-left: 20px; - list-style: square; -} - -div.sphinxsidebar ul ul { - margin-top: 0; - margin-bottom: 0; -} - -div.sphinxsidebar form { - margin-top: 10px; -} - -div.sphinxsidebar input { - border: 1px solid #98dbcc; - font-family: sans-serif; - font-size: 1em; -} - -div.sphinxsidebar #searchbox input[type="text"] { - width: 170px; -} - -div.sphinxsidebar #searchbox input[type="submit"] { - width: 30px; -} - -img { - border: 0; -} - -/* -- search page ----------------------------------------------------------- */ - -ul.search { - margin: 10px 0 0 20px; - padding: 0; -} - -ul.search li { - padding: 5px 0 5px 20px; - background-image: url(file.png); - background-repeat: no-repeat; - background-position: 0 7px; -} - -ul.search li a { - font-weight: bold; -} - -ul.search li div.context { - color: #888; - margin: 2px 0 0 30px; - text-align: left; -} - -ul.keywordmatches li.goodmatch a { - font-weight: bold; -} - -/* -- index page ------------------------------------------------------------ */ - -table.contentstable { - width: 90%; -} - -table.contentstable p.biglink { - line-height: 150%; -} - -a.biglink { - font-size: 1.3em; -} - -span.linkdescr { - font-style: italic; - padding-top: 5px; - font-size: 90%; -} - -/* -- general index --------------------------------------------------------- */ - -table.indextable { - width: 100%; -} - -table.indextable td { - text-align: left; - vertical-align: top; -} - -table.indextable dl, table.indextable dd { - margin-top: 0; - margin-bottom: 0; -} - -table.indextable tr.pcap { - height: 10px; -} - -table.indextable tr.cap { - margin-top: 10px; - background-color: #f2f2f2; -} - -img.toggler { - margin-right: 3px; - margin-top: 3px; - cursor: pointer; -} - -div.modindex-jumpbox { - border-top: 1px solid #ddd; - border-bottom: 1px solid #ddd; - margin: 1em 0 1em 0; - padding: 0.4em; -} - -div.genindex-jumpbox { - border-top: 1px solid #ddd; - border-bottom: 1px solid #ddd; - margin: 1em 0 1em 0; - padding: 0.4em; -} - -/* -- general body styles --------------------------------------------------- */ - -a.headerlink { - visibility: hidden; -} - -h1:hover > a.headerlink, -h2:hover > a.headerlink, -h3:hover > a.headerlink, -h4:hover > a.headerlink, -h5:hover > a.headerlink, -h6:hover > a.headerlink, -dt:hover > a.headerlink { - visibility: visible; -} - -div.body p.caption { - text-align: inherit; -} - -div.body td { - text-align: left; -} - -.field-list ul { - padding-left: 1em; -} - -.first { - margin-top: 0 !important; -} - -p.rubric { - margin-top: 30px; - font-weight: bold; -} - -img.align-left, .figure.align-left, object.align-left { - clear: left; - float: left; - margin-right: 1em; -} - -img.align-right, .figure.align-right, object.align-right { - clear: right; - float: right; - margin-left: 1em; -} - -img.align-center, .figure.align-center, object.align-center { - display: block; - margin-left: auto; - margin-right: auto; -} - -.align-left { - text-align: left; -} - -.align-center { - text-align: center; -} - -.align-right { - text-align: right; -} - -/* -- sidebars -------------------------------------------------------------- */ - -div.sidebar { - margin: 0 0 0.5em 1em; - border: 1px solid #ddb; - padding: 7px 7px 0 7px; - background-color: #ffe; - width: 40%; - float: right; -} - -p.sidebar-title { - font-weight: bold; -} - -/* -- topics ---------------------------------------------------------------- */ - -div.topic { - border: 1px solid #ccc; - padding: 7px 7px 0 7px; - margin: 10px 0 10px 0; -} - -p.topic-title { - font-size: 1.1em; - font-weight: bold; - margin-top: 10px; -} - -/* -- admonitions ----------------------------------------------------------- */ - -div.admonition { - margin-top: 10px; - margin-bottom: 10px; - padding: 7px; -} - -div.admonition dt { - font-weight: bold; -} - -div.admonition dl { - margin-bottom: 0; -} - -p.admonition-title { - margin: 0px 10px 5px 0px; - font-weight: bold; -} - -div.body p.centered { - text-align: center; - margin-top: 25px; -} - -/* -- tables ---------------------------------------------------------------- */ - -table.docutils { - border: 0; - border-collapse: collapse; -} - -table.docutils td, table.docutils th { - padding: 1px 8px 1px 5px; - border-top: 0; - border-left: 0; - border-right: 0; - border-bottom: 1px solid #aaa; -} - -table.field-list td, table.field-list th { - border: 0 !important; -} - -table.footnote td, table.footnote th { - border: 0 !important; -} - -th { - text-align: left; - padding-right: 5px; -} - -table.citation { - border-left: solid 1px gray; - margin-left: 1px; -} - -table.citation td { - border-bottom: none; -} - -/* -- other body styles ----------------------------------------------------- */ - -ol.arabic { - list-style: decimal; -} - -ol.loweralpha { - list-style: lower-alpha; -} - -ol.upperalpha { - list-style: upper-alpha; -} - -ol.lowerroman { - list-style: lower-roman; -} - -ol.upperroman { - list-style: upper-roman; -} - -dl { - margin-bottom: 15px; -} - -dd p { - margin-top: 0px; -} - -dd ul, dd table { - margin-bottom: 10px; -} - -dd { - margin-top: 3px; - margin-bottom: 10px; - margin-left: 30px; -} - -dt:target, .highlighted { - background-color: #fbe54e; -} - -dl.glossary dt { - font-weight: bold; - font-size: 1.1em; -} - -.field-list ul { - margin: 0; - padding-left: 1em; -} - -.field-list p { - margin: 0; -} - -.refcount { - color: #060; -} - -.optional { - font-size: 1.3em; -} - -.versionmodified { - font-style: italic; -} - -.system-message { - background-color: #fda; - padding: 5px; - border: 3px solid red; -} - -.footnote:target { - background-color: #ffa; -} - -.line-block { - display: block; - margin-top: 1em; - margin-bottom: 1em; -} - -.line-block .line-block { - margin-top: 0; - margin-bottom: 0; - margin-left: 1.5em; -} - -.guilabel, .menuselection { - font-family: sans-serif; -} - -.accelerator { - text-decoration: underline; -} - -.classifier { - font-style: oblique; -} - -abbr, acronym { - border-bottom: dotted 1px; - cursor: help; -} - -/* -- code displays --------------------------------------------------------- */ - -pre { - overflow: auto; - overflow-y: hidden; /* fixes display issues on Chrome browsers */ -} - -td.linenos pre { - padding: 5px 0px; - border: 0; - background-color: transparent; - color: #aaa; -} - -table.highlighttable { - margin-left: 0.5em; -} - -table.highlighttable td { - padding: 0 0.5em 0 0.5em; -} - -tt.descname { - background-color: transparent; - font-weight: bold; - font-size: 1.2em; -} - -tt.descclassname { - background-color: transparent; -} - -tt.xref, a tt { - background-color: transparent; - font-weight: bold; -} - -h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt { - background-color: transparent; -} - -.viewcode-link { - float: right; -} - -.viewcode-back { - float: right; - font-family: sans-serif; -} - -div.viewcode-block:target { - margin: -1px -10px; - padding: 0 10px; -} - -/* -- math display ---------------------------------------------------------- */ - -img.math { - vertical-align: middle; -} - -div.body div.math p { - text-align: center; -} - -span.eqno { - float: right; -} - -/* -- printout stylesheet --------------------------------------------------- */ - -@media print { - div.document, - div.documentwrapper, - div.bodywrapper { - margin: 0 !important; - width: 100%; - } - - div.sphinxsidebar, - div.related, - div.footer, - #top-link { - display: none; - } -} \ No newline at end of file Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/html/_static/comment-bright.png and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/html/_static/comment-bright.png differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/html/_static/comment-close.png and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/html/_static/comment-close.png differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/html/_static/comment.png and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/html/_static/comment.png differ diff -Nru circuits-2.1.0/docs/build/html/_static/default.css circuits-3.1.0+ds1/docs/build/html/_static/default.css --- circuits-2.1.0/docs/build/html/_static/default.css 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_static/default.css 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -@import url(reset-fonts-grids.css); -@import url(djangodocs.css); -@import url(homepage.css); \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/_static/djangodocs.css circuits-3.1.0+ds1/docs/build/html/_static/djangodocs.css --- circuits-2.1.0/docs/build/html/_static/djangodocs.css 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_static/djangodocs.css 1970-01-01 00:00:00.000000000 +0000 @@ -1,135 +0,0 @@ -/*** setup ***/ -html { background:#092e20;} -body { font:12px/1.5 Verdana,sans-serif; background:#092e20; color: white;} -#custom-doc { width:76.54em;*width:74.69em;min-width:995px; max-width:100em; margin:auto; text-align:left; padding-top:16px; margin-top:0;} -#hd { padding: 4px 0 12px 0; } -#bd { background:#234F32; } -#ft { color:#487858; font-size:90%; padding-bottom: 2em; } - -/*** links ***/ -a {text-decoration: none;} -a img {border: none;} -a:link, a:visited { color:#ffc757; } -#bd a:link, #bd a:visited { color:#ab5603; text-decoration:underline; } -#bd #sidebar a:link, #bd #sidebar a:visited { color:#ffc757; text-decoration:none; } -a:hover { color:#ffe761; } -#bd a:hover { background-color:#E0FFB8; color:#234f32; text-decoration:none; } -#bd #sidebar a:hover { color:#ffe761; background:none; } -h2 a, h3 a, h4 a { text-decoration:none !important; } -a.reference em { font-style: normal; } - -/*** sidebar ***/ -#sidebar div.sphinxsidebarwrapper { font-size:92%; margin-right: 14px; } -#sidebar h3, #sidebar h4 { color: white; font-size: 125%; } -#sidebar a { color: white; } -#sidebar ul ul { margin-top:0; margin-bottom:0; } -#sidebar li { margin-top: 0.2em; margin-bottom: 0.2em; } - -/*** nav ***/ -div.nav { margin: 0; font-size: 11px; text-align: right; color: #487858;} -#hd div.nav { margin-top: -27px; } -#ft div.nav { margin-bottom: -18px; } -#hd h1 a { color: white; } -#global-nav { position:absolute; top:5px; margin-left: -5px; padding:7px 0; color:#263E2B; } -#global-nav a:link, #global-nav a:visited {color:#487858;} -#global-nav a {padding:0 4px;} -#global-nav a.about {padding-left:0;} -#global-nav:hover {color:#fff;} -#global-nav:hover a:link, #global-nav:hover a:visited { color:#ffc757; } - -/*** content ***/ -#yui-main div.yui-b { position: relative; } -#yui-main div.yui-b { margin: 0 0 0 20px; background: white; color: black; padding: 0.3em 2em 1em 2em; } - -/*** basic styles ***/ -dd { margin-left:15px; } -h1,h2,h3,h4 { margin-top:1em; font-family:"Trebuchet MS",sans-serif; font-weight:normal; } -h1 { font-size:218%; margin-top:0.6em; margin-bottom:.4em; line-height:1.1em; } -h2 { font-size:175%; margin-bottom:.6em; line-height:1.2em; color:#092e20; } -h3 { font-size:150%; font-weight:bold; margin-bottom:.2em; color:#487858; } -h4 { font-size:125%; font-weight:bold; margin-top:1.5em; margin-bottom:3px; } -div.figure { text-align: center; } -div.figure p.caption { font-size:1em; margin-top:0; margin-bottom:1.5em; color: #555;} -hr { color:#ccc; background-color:#ccc; height:1px; border:0; } -p, ul, dl { margin-top:.6em; margin-bottom:1em; padding-bottom: 0.1em;} -#yui-main div.yui-b img { max-width: 50em; margin-left: auto; margin-right: auto; display: block; } -caption { font-size:1em; font-weight:bold; margin-top:0.5em; margin-bottom:0.5em; margin-left: 2px; text-align: center; } -blockquote { padding: 0 1em; margin: 1em 0; font:125%/1.2em "Trebuchet MS", sans-serif; color:#234f32; border-left:2px solid #94da3a; } -strong { font-weight: bold; } -em { font-style: italic; } -ins { font-weight: bold; text-decoration: none; } - -/*** lists ***/ -ul { padding-left:30px; } -ol { padding-left:30px; } -ol.arabic li { list-style-type: decimal; } -ul li { list-style-type:square; margin-bottom:.4em; } -ol li { margin-bottom: .4em; } -ul ul { padding-left:1.2em; } -ul ul ul { padding-left:1em; } -ul.linklist, ul.toc { padding-left:0; } -ul.toc ul { margin-left:.6em; } -ul.toc ul li { list-style-type:square; } -ul.toc ul ul li { list-style-type:disc; } -ul.linklist li, ul.toc li { list-style-type:none; } -dt { font-weight:bold; margin-top:.5em; font-size:1.1em; } -dd { margin-bottom:.8em; } -ol.toc { margin-bottom: 2em; } -ol.toc li { font-size:125%; padding: .5em; line-height:1.2em; clear: right; } -ol.toc li.b { background-color: #E0FFB8; } -ol.toc li a:hover { background-color: transparent !important; text-decoration: underline !important; } -ol.toc span.release-date { color:#487858; float: right; font-size: 85%; padding-right: .5em; } -ol.toc span.comment-count { font-size: 75%; color: #999; } - -/*** tables ***/ -table { color:#000; margin-bottom: 1em; width: 100%; } -table.docutils td p { margin-top:0; margin-bottom:.5em; } -table.docutils td, table.docutils th { border-bottom:1px solid #dfdfdf; padding:4px 2px;} -table.docutils thead th { border-bottom:2px solid #dfdfdf; text-align:left; font-weight: bold; white-space: nowrap; } -table.docutils thead th p { margin: 0; padding: 0; } -table.docutils { border-collapse:collapse; } - -/*** code blocks ***/ -.literal { white-space:nowrap; } -.literal { color:#234f32; } -#sidebar .literal { color:white; background:transparent; font-size:11px; } -h4 .literal { color: #234f32; font-size: 13px; } -pre { font-size:small; background:#E0FFB8; border:1px solid #94da3a; border-width:1px 0; margin: 1em 0; padding: .3em .4em; overflow: hidden; line-height: 1.3em;} -dt .literal, table .literal { background:none; } -#bd a.reference { text-decoration: none; } -#bd a.reference tt.literal { border-bottom: 1px #234f32 dotted; } - -/* Restore colors of pygments hyperlinked code */ -#bd .highlight .k a:link, #bd .highlight .k a:visited { color: #000000; text-decoration: none; border-bottom: 1px dotted #000000; } -#bd .highlight .nf a:link, #bd .highlight .nf a:visited { color: #990000; text-decoration: none; border-bottom: 1px dotted #990000; } - - -/*** notes & admonitions ***/ -.note, .admonition { padding:.8em 1em .8em; margin: 1em 0; border:1px solid #94da3a; } -.admonition-title { font-weight:bold; margin-top:0 !important; margin-bottom:0 !important;} -.admonition .last { margin-bottom:0 !important; } -.note, .admonition { padding-left:65px; background:url(docicons-note.png) .8em .8em no-repeat;} -div.admonition-philosophy { padding-left:65px; background:url(docicons-philosophy.png) .8em .8em no-repeat;} -div.admonition-behind-the-scenes { padding-left:65px; background:url(docicons-behindscenes.png) .8em .8em no-repeat;} - -/*** versoinadded/changes ***/ -div.versionadded, div.versionchanged { } -div.versionadded span.title, div.versionchanged span.title { font-weight: bold; } - -/*** p-links ***/ -a.headerlink { color: #c60f0f; font-size: 0.8em; padding: 0 4px 0 4px; text-decoration: none; visibility: hidden; } -h1:hover > a.headerlink, h2:hover > a.headerlink, h3:hover > a.headerlink, h4:hover > a.headerlink, h5:hover > a.headerlink, h6:hover > a.headerlink, dt:hover > a.headerlink { visibility: visible; } - -/*** index ***/ -table.indextable td { text-align: left; vertical-align: top;} -table.indextable dl, table.indextable dd { margin-top: 0; margin-bottom: 0; } -table.indextable tr.pcap { height: 10px; } -table.indextable tr.cap { margin-top: 10px; background-color: #f2f2f2;} - -/*** page-specific overrides ***/ -div#contents ul { margin-bottom: 0;} -div#contents ul li { margin-bottom: 0;} -div#contents ul ul li { margin-top: 0.3em;} - -/*** IE hacks ***/ -* pre { width: 100%; } Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/html/_static/docicons-behindscenes.png and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/html/_static/docicons-behindscenes.png differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/html/_static/docicons-note.png and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/html/_static/docicons-note.png differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/html/_static/docicons-philosophy.png and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/html/_static/docicons-philosophy.png differ diff -Nru circuits-2.1.0/docs/build/html/_static/doctools.js circuits-3.1.0+ds1/docs/build/html/_static/doctools.js --- circuits-2.1.0/docs/build/html/_static/doctools.js 2012-12-14 11:01:23.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_static/doctools.js 1970-01-01 00:00:00.000000000 +0000 @@ -1,247 +0,0 @@ -/* - * doctools.js - * ~~~~~~~~~~~ - * - * Sphinx JavaScript utilities for all documentation. - * - * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. - * :license: BSD, see LICENSE for details. - * - */ - -/** - * select a different prefix for underscore - */ -$u = _.noConflict(); - -/** - * make the code below compatible with browsers without - * an installed firebug like debugger -if (!window.console || !console.firebug) { - var names = ["log", "debug", "info", "warn", "error", "assert", "dir", - "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", - "profile", "profileEnd"]; - window.console = {}; - for (var i = 0; i < names.length; ++i) - window.console[names[i]] = function() {}; -} - */ - -/** - * small helper function to urldecode strings - */ -jQuery.urldecode = function(x) { - return decodeURIComponent(x).replace(/\+/g, ' '); -} - -/** - * small helper function to urlencode strings - */ -jQuery.urlencode = encodeURIComponent; - -/** - * This function returns the parsed url parameters of the - * current request. Multiple values per key are supported, - * it will always return arrays of strings for the value parts. - */ -jQuery.getQueryParameters = function(s) { - if (typeof s == 'undefined') - s = document.location.search; - var parts = s.substr(s.indexOf('?') + 1).split('&'); - var result = {}; - for (var i = 0; i < parts.length; i++) { - var tmp = parts[i].split('=', 2); - var key = jQuery.urldecode(tmp[0]); - var value = jQuery.urldecode(tmp[1]); - if (key in result) - result[key].push(value); - else - result[key] = [value]; - } - return result; -}; - -/** - * small function to check if an array contains - * a given item. - */ -jQuery.contains = function(arr, item) { - for (var i = 0; i < arr.length; i++) { - if (arr[i] == item) - return true; - } - return false; -}; - -/** - * highlight a given string on a jquery object by wrapping it in - * span elements with the given class name. - */ -jQuery.fn.highlightText = function(text, className) { - function highlight(node) { - if (node.nodeType == 3) { - var val = node.nodeValue; - var pos = val.toLowerCase().indexOf(text); - if (pos >= 0 && !jQuery(node.parentNode).hasClass(className)) { - var span = document.createElement("span"); - span.className = className; - span.appendChild(document.createTextNode(val.substr(pos, text.length))); - node.parentNode.insertBefore(span, node.parentNode.insertBefore( - document.createTextNode(val.substr(pos + text.length)), - node.nextSibling)); - node.nodeValue = val.substr(0, pos); - } - } - else if (!jQuery(node).is("button, select, textarea")) { - jQuery.each(node.childNodes, function() { - highlight(this); - }); - } - } - return this.each(function() { - highlight(this); - }); -}; - -/** - * Small JavaScript module for the documentation. - */ -var Documentation = { - - init : function() { - this.fixFirefoxAnchorBug(); - this.highlightSearchWords(); - this.initIndexTable(); - }, - - /** - * i18n support - */ - TRANSLATIONS : {}, - PLURAL_EXPR : function(n) { return n == 1 ? 0 : 1; }, - LOCALE : 'unknown', - - // gettext and ngettext don't access this so that the functions - // can safely bound to a different name (_ = Documentation.gettext) - gettext : function(string) { - var translated = Documentation.TRANSLATIONS[string]; - if (typeof translated == 'undefined') - return string; - return (typeof translated == 'string') ? translated : translated[0]; - }, - - ngettext : function(singular, plural, n) { - var translated = Documentation.TRANSLATIONS[singular]; - if (typeof translated == 'undefined') - return (n == 1) ? singular : plural; - return translated[Documentation.PLURALEXPR(n)]; - }, - - addTranslations : function(catalog) { - for (var key in catalog.messages) - this.TRANSLATIONS[key] = catalog.messages[key]; - this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')'); - this.LOCALE = catalog.locale; - }, - - /** - * add context elements like header anchor links - */ - addContextElements : function() { - $('div[id] > :header:first').each(function() { - $('\u00B6'). - attr('href', '#' + this.id). - attr('title', _('Permalink to this headline')). - appendTo(this); - }); - $('dt[id]').each(function() { - $('\u00B6'). - attr('href', '#' + this.id). - attr('title', _('Permalink to this definition')). - appendTo(this); - }); - }, - - /** - * workaround a firefox stupidity - */ - fixFirefoxAnchorBug : function() { - if (document.location.hash && $.browser.mozilla) - window.setTimeout(function() { - document.location.href += ''; - }, 10); - }, - - /** - * highlight the search words provided in the url in the text - */ - highlightSearchWords : function() { - var params = $.getQueryParameters(); - var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : []; - if (terms.length) { - var body = $('div.body'); - window.setTimeout(function() { - $.each(terms, function() { - body.highlightText(this.toLowerCase(), 'highlighted'); - }); - }, 10); - $('') - .appendTo($('#searchbox')); - } - }, - - /** - * init the domain index toggle buttons - */ - initIndexTable : function() { - var togglers = $('img.toggler').click(function() { - var src = $(this).attr('src'); - var idnum = $(this).attr('id').substr(7); - $('tr.cg-' + idnum).toggle(); - if (src.substr(-9) == 'minus.png') - $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); - else - $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); - }).css('display', ''); - if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) { - togglers.click(); - } - }, - - /** - * helper function to hide the search marks again - */ - hideSearchWords : function() { - $('#searchbox .highlight-link').fadeOut(300); - $('span.highlighted').removeClass('highlighted'); - }, - - /** - * make the url absolute - */ - makeURL : function(relativeURL) { - return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; - }, - - /** - * get the current relative url - */ - getCurrentURL : function() { - var path = document.location.pathname; - var parts = path.split(/\//); - $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { - if (this == '..') - parts.pop(); - }); - var url = parts.join('/'); - return path.substring(url.lastIndexOf('/') + 1, path.length - 1); - } -}; - -// quick alias for translations -_ = Documentation.gettext; - -$(document).ready(function() { - Documentation.init(); -}); Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/html/_static/down.png and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/html/_static/down.png differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/html/_static/down-pressed.png and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/html/_static/down-pressed.png differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/html/_static/file.png and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/html/_static/file.png differ diff -Nru circuits-2.1.0/docs/build/html/_static/homepage.css circuits-3.1.0+ds1/docs/build/html/_static/homepage.css --- circuits-2.1.0/docs/build/html/_static/homepage.css 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_static/homepage.css 1970-01-01 00:00:00.000000000 +0000 @@ -1,22 +0,0 @@ -#index p.rubric { font-size:150%; font-weight:normal; margin-bottom:.2em; color:#487858; } - -#index div.section dt { font-weight: normal; } - -#index #s-getting-help { float: right; width: 35em; background: #E1ECE2; padding: 1em; margin: 2em 0 2em 2em; } -#index #s-getting-help h2 { margin: 0; } - -#index #s-django-documentation div.section div.section h3 { margin: 0; } -#index #s-django-documentation div.section div.section { background: #E1ECE2; padding: 1em; margin: 2em 0 2em 40.3em; } -#index #s-django-documentation div.section div.section a.reference { white-space: nowrap; } - -#index #s-using-django dl, -#index #s-add-on-contrib-applications dl, -#index #s-solving-specific-problems dl, -#index #s-reference dl - { float: left; width: 41em; } - -#index #s-add-on-contrib-applications, -#index #s-solving-specific-problems, -#index #s-reference, -#index #s-and-all-the-rest - { clear: left; } \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/_static/jquery.js circuits-3.1.0+ds1/docs/build/html/_static/jquery.js --- circuits-2.1.0/docs/build/html/_static/jquery.js 2012-12-14 11:01:23.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_static/jquery.js 1970-01-01 00:00:00.000000000 +0000 @@ -1,154 +0,0 @@ -/*! - * jQuery JavaScript Library v1.4.2 - * http://jquery.com/ - * - * Copyright 2010, John Resig - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * Includes Sizzle.js - * http://sizzlejs.com/ - * Copyright 2010, The Dojo Foundation - * Released under the MIT, BSD, and GPL Licenses. - * - * Date: Sat Feb 13 22:33:48 2010 -0500 - */ -(function(A,w){function ma(){if(!c.isReady){try{s.documentElement.doScroll("left")}catch(a){setTimeout(ma,1);return}c.ready()}}function Qa(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function X(a,b,d,f,e,j){var i=a.length;if(typeof b==="object"){for(var o in b)X(a,o,b[o],f,e,d);return a}if(d!==w){f=!j&&f&&c.isFunction(d);for(o=0;o)[^>]*$|^#([\w-]+)$/,Ua=/^.[^:#\[\.,]*$/,Va=/\S/, -Wa=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,Xa=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,P=navigator.userAgent,xa=false,Q=[],L,$=Object.prototype.toString,aa=Object.prototype.hasOwnProperty,ba=Array.prototype.push,R=Array.prototype.slice,ya=Array.prototype.indexOf;c.fn=c.prototype={init:function(a,b){var d,f;if(!a)return this;if(a.nodeType){this.context=this[0]=a;this.length=1;return this}if(a==="body"&&!b){this.context=s;this[0]=s.body;this.selector="body";this.length=1;return this}if(typeof a==="string")if((d=Ta.exec(a))&& -(d[1]||!b))if(d[1]){f=b?b.ownerDocument||b:s;if(a=Xa.exec(a))if(c.isPlainObject(b)){a=[s.createElement(a[1])];c.fn.attr.call(a,b,true)}else a=[f.createElement(a[1])];else{a=sa([d[1]],[f]);a=(a.cacheable?a.fragment.cloneNode(true):a.fragment).childNodes}return c.merge(this,a)}else{if(b=s.getElementById(d[2])){if(b.id!==d[2])return T.find(a);this.length=1;this[0]=b}this.context=s;this.selector=a;return this}else if(!b&&/^\w+$/.test(a)){this.selector=a;this.context=s;a=s.getElementsByTagName(a);return c.merge(this, -a)}else return!b||b.jquery?(b||T).find(a):c(b).find(a);else if(c.isFunction(a))return T.ready(a);if(a.selector!==w){this.selector=a.selector;this.context=a.context}return c.makeArray(a,this)},selector:"",jquery:"1.4.2",length:0,size:function(){return this.length},toArray:function(){return R.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this.slice(a)[0]:this[a]},pushStack:function(a,b,d){var f=c();c.isArray(a)?ba.apply(f,a):c.merge(f,a);f.prevObject=this;f.context=this.context;if(b=== -"find")f.selector=this.selector+(this.selector?" ":"")+d;else if(b)f.selector=this.selector+"."+b+"("+d+")";return f},each:function(a,b){return c.each(this,a,b)},ready:function(a){c.bindReady();if(c.isReady)a.call(s,c);else Q&&Q.push(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(R.apply(this,arguments),"slice",R.call(arguments).join(","))},map:function(a){return this.pushStack(c.map(this, -function(b,d){return a.call(b,d,b)}))},end:function(){return this.prevObject||c(null)},push:ba,sort:[].sort,splice:[].splice};c.fn.init.prototype=c.fn;c.extend=c.fn.extend=function(){var a=arguments[0]||{},b=1,d=arguments.length,f=false,e,j,i,o;if(typeof a==="boolean"){f=a;a=arguments[1]||{};b=2}if(typeof a!=="object"&&!c.isFunction(a))a={};if(d===b){a=this;--b}for(;b
a"; -var e=d.getElementsByTagName("*"),j=d.getElementsByTagName("a")[0];if(!(!e||!e.length||!j)){c.support={leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(j.getAttribute("style")),hrefNormalized:j.getAttribute("href")==="/a",opacity:/^0.55$/.test(j.style.opacity),cssFloat:!!j.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:s.createElement("select").appendChild(s.createElement("option")).selected, -parentNode:d.removeChild(d.appendChild(s.createElement("div"))).parentNode===null,deleteExpando:true,checkClone:false,scriptEval:false,noCloneEvent:true,boxModel:null};b.type="text/javascript";try{b.appendChild(s.createTextNode("window."+f+"=1;"))}catch(i){}a.insertBefore(b,a.firstChild);if(A[f]){c.support.scriptEval=true;delete A[f]}try{delete b.test}catch(o){c.support.deleteExpando=false}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function k(){c.support.noCloneEvent= -false;d.detachEvent("onclick",k)});d.cloneNode(true).fireEvent("onclick")}d=s.createElement("div");d.innerHTML="";a=s.createDocumentFragment();a.appendChild(d.firstChild);c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var k=s.createElement("div");k.style.width=k.style.paddingLeft="1px";s.body.appendChild(k);c.boxModel=c.support.boxModel=k.offsetWidth===2;s.body.removeChild(k).style.display="none"});a=function(k){var n= -s.createElement("div");k="on"+k;var r=k in n;if(!r){n.setAttribute(k,"return;");r=typeof n[k]==="function"}return r};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=e=j=null}})();c.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var G="jQuery"+J(),Ya=0,za={};c.extend({cache:{},expando:G,noData:{embed:true,object:true, -applet:true},data:function(a,b,d){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var f=a[G],e=c.cache;if(!f&&typeof b==="string"&&d===w)return null;f||(f=++Ya);if(typeof b==="object"){a[G]=f;e[f]=c.extend(true,{},b)}else if(!e[f]){a[G]=f;e[f]={}}a=e[f];if(d!==w)a[b]=d;return typeof b==="string"?a[b]:a}},removeData:function(a,b){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var d=a[G],f=c.cache,e=f[d];if(b){if(e){delete e[b];c.isEmptyObject(e)&&c.removeData(a)}}else{if(c.support.deleteExpando)delete a[c.expando]; -else a.removeAttribute&&a.removeAttribute(c.expando);delete f[d]}}}});c.fn.extend({data:function(a,b){if(typeof a==="undefined"&&this.length)return c.data(this[0]);else if(typeof a==="object")return this.each(function(){c.data(this,a)});var d=a.split(".");d[1]=d[1]?"."+d[1]:"";if(b===w){var f=this.triggerHandler("getData"+d[1]+"!",[d[0]]);if(f===w&&this.length)f=c.data(this[0],a);return f===w&&d[1]?this.data(d[0]):f}else return this.trigger("setData"+d[1]+"!",[d[0],b]).each(function(){c.data(this, -a,b)})},removeData:function(a){return this.each(function(){c.removeData(this,a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var f=c.data(a,b);if(!d)return f||[];if(!f||c.isArray(d))f=c.data(a,b,c.makeArray(d));else f.push(d);return f}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),f=d.shift();if(f==="inprogress")f=d.shift();if(f){b==="fx"&&d.unshift("inprogress");f.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b=== -w)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var Aa=/[\n\t]/g,ca=/\s+/,Za=/\r/g,$a=/href|src|style/,ab=/(button|input)/i,bb=/(button|input|object|select|textarea)/i, -cb=/^(a|area)$/i,Ba=/radio|checkbox/;c.fn.extend({attr:function(a,b){return X(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(n){var r=c(this);r.addClass(a.call(this,n,r.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(ca),d=0,f=this.length;d-1)return true;return false},val:function(a){if(a===w){var b=this[0];if(b){if(c.nodeName(b,"option"))return(b.attributes.value||{}).specified?b.value:b.text;if(c.nodeName(b,"select")){var d=b.selectedIndex,f=[],e=b.options;b=b.type==="select-one";if(d<0)return null;var j=b?d:0;for(d=b?d+1:e.length;j=0;else if(c.nodeName(this,"select")){var u=c.makeArray(r);c("option",this).each(function(){this.selected= -c.inArray(c(this).val(),u)>=0});if(!u.length)this.selectedIndex=-1}else this.value=r}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(a,b,d,f){if(!a||a.nodeType===3||a.nodeType===8)return w;if(f&&b in c.attrFn)return c(a)[b](d);f=a.nodeType!==1||!c.isXMLDoc(a);var e=d!==w;b=f&&c.props[b]||b;if(a.nodeType===1){var j=$a.test(b);if(b in a&&f&&!j){if(e){b==="type"&&ab.test(a.nodeName)&&a.parentNode&&c.error("type property can't be changed"); -a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&b.specified?b.value:bb.test(a.nodeName)||cb.test(a.nodeName)&&a.href?0:w;return a[b]}if(!c.support.style&&f&&b==="style"){if(e)a.style.cssText=""+d;return a.style.cssText}e&&a.setAttribute(b,""+d);a=!c.support.hrefNormalized&&f&&j?a.getAttribute(b,2):a.getAttribute(b);return a===null?w:a}return c.style(a,b,d)}});var O=/\.(.*)$/,db=function(a){return a.replace(/[^\w\s\.\|`]/g, -function(b){return"\\"+b})};c.event={add:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){if(a.setInterval&&a!==A&&!a.frameElement)a=A;var e,j;if(d.handler){e=d;d=e.handler}if(!d.guid)d.guid=c.guid++;if(j=c.data(a)){var i=j.events=j.events||{},o=j.handle;if(!o)j.handle=o=function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(o.elem,arguments):w};o.elem=a;b=b.split(" ");for(var k,n=0,r;k=b[n++];){j=e?c.extend({},e):{handler:d,data:f};if(k.indexOf(".")>-1){r=k.split("."); -k=r.shift();j.namespace=r.slice(0).sort().join(".")}else{r=[];j.namespace=""}j.type=k;j.guid=d.guid;var u=i[k],z=c.event.special[k]||{};if(!u){u=i[k]=[];if(!z.setup||z.setup.call(a,f,r,o)===false)if(a.addEventListener)a.addEventListener(k,o,false);else a.attachEvent&&a.attachEvent("on"+k,o)}if(z.add){z.add.call(a,j);if(!j.handler.guid)j.handler.guid=d.guid}u.push(j);c.event.global[k]=true}a=null}}},global:{},remove:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){var e,j=0,i,o,k,n,r,u,z=c.data(a), -C=z&&z.events;if(z&&C){if(b&&b.type){d=b.handler;b=b.type}if(!b||typeof b==="string"&&b.charAt(0)==="."){b=b||"";for(e in C)c.event.remove(a,e+b)}else{for(b=b.split(" ");e=b[j++];){n=e;i=e.indexOf(".")<0;o=[];if(!i){o=e.split(".");e=o.shift();k=new RegExp("(^|\\.)"+c.map(o.slice(0).sort(),db).join("\\.(?:.*\\.)?")+"(\\.|$)")}if(r=C[e])if(d){n=c.event.special[e]||{};for(B=f||0;B=0){a.type= -e=e.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();c.event.global[e]&&c.each(c.cache,function(){this.events&&this.events[e]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===8)return w;a.result=w;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(f=c.data(d,"handle"))&&f.apply(d,b);f=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+e]&&d["on"+e].apply(d,b)===false)a.result=false}catch(j){}if(!a.isPropagationStopped()&& -f)c.event.trigger(a,b,f,true);else if(!a.isDefaultPrevented()){f=a.target;var i,o=c.nodeName(f,"a")&&e==="click",k=c.event.special[e]||{};if((!k._default||k._default.call(d,a)===false)&&!o&&!(f&&f.nodeName&&c.noData[f.nodeName.toLowerCase()])){try{if(f[e]){if(i=f["on"+e])f["on"+e]=null;c.event.triggered=true;f[e]()}}catch(n){}if(i)f["on"+e]=i;c.event.triggered=false}}},handle:function(a){var b,d,f,e;a=arguments[0]=c.event.fix(a||A.event);a.currentTarget=this;b=a.type.indexOf(".")<0&&!a.exclusive; -if(!b){d=a.type.split(".");a.type=d.shift();f=new RegExp("(^|\\.)"+d.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)")}e=c.data(this,"events");d=e[a.type];if(e&&d){d=d.slice(0);e=0;for(var j=d.length;e-1?c.map(a.options,function(f){return f.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d},fa=function(a,b){var d=a.target,f,e;if(!(!da.test(d.nodeName)||d.readOnly)){f=c.data(d,"_change_data");e=Fa(d);if(a.type!=="focusout"||d.type!=="radio")c.data(d,"_change_data", -e);if(!(f===w||e===f))if(f!=null||e){a.type="change";return c.event.trigger(a,b,d)}}};c.event.special.change={filters:{focusout:fa,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return fa.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return fa.call(this,a)},beforeactivate:function(a){a=a.target;c.data(a, -"_change_data",Fa(a))}},setup:function(){if(this.type==="file")return false;for(var a in ea)c.event.add(this,a+".specialChange",ea[a]);return da.test(this.nodeName)},teardown:function(){c.event.remove(this,".specialChange");return da.test(this.nodeName)}};ea=c.event.special.change.filters}s.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(f){f=c.event.fix(f);f.type=b;return c.event.handle.call(this,f)}c.event.special[b]={setup:function(){this.addEventListener(a, -d,true)},teardown:function(){this.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,f,e){if(typeof d==="object"){for(var j in d)this[b](j,f,d[j],e);return this}if(c.isFunction(f)){e=f;f=w}var i=b==="one"?c.proxy(e,function(k){c(this).unbind(k,i);return e.apply(this,arguments)}):e;if(d==="unload"&&b!=="one")this.one(d,f,e);else{j=0;for(var o=this.length;j0){y=t;break}}t=t[g]}m[q]=y}}}var f=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, -e=0,j=Object.prototype.toString,i=false,o=true;[0,0].sort(function(){o=false;return 0});var k=function(g,h,l,m){l=l||[];var q=h=h||s;if(h.nodeType!==1&&h.nodeType!==9)return[];if(!g||typeof g!=="string")return l;for(var p=[],v,t,y,S,H=true,M=x(h),I=g;(f.exec(""),v=f.exec(I))!==null;){I=v[3];p.push(v[1]);if(v[2]){S=v[3];break}}if(p.length>1&&r.exec(g))if(p.length===2&&n.relative[p[0]])t=ga(p[0]+p[1],h);else for(t=n.relative[p[0]]?[h]:k(p.shift(),h);p.length;){g=p.shift();if(n.relative[g])g+=p.shift(); -t=ga(g,t)}else{if(!m&&p.length>1&&h.nodeType===9&&!M&&n.match.ID.test(p[0])&&!n.match.ID.test(p[p.length-1])){v=k.find(p.shift(),h,M);h=v.expr?k.filter(v.expr,v.set)[0]:v.set[0]}if(h){v=m?{expr:p.pop(),set:z(m)}:k.find(p.pop(),p.length===1&&(p[0]==="~"||p[0]==="+")&&h.parentNode?h.parentNode:h,M);t=v.expr?k.filter(v.expr,v.set):v.set;if(p.length>0)y=z(t);else H=false;for(;p.length;){var D=p.pop();v=D;if(n.relative[D])v=p.pop();else D="";if(v==null)v=h;n.relative[D](y,v,M)}}else y=[]}y||(y=t);y||k.error(D|| -g);if(j.call(y)==="[object Array]")if(H)if(h&&h.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&E(h,y[g])))l.push(t[g])}else for(g=0;y[g]!=null;g++)y[g]&&y[g].nodeType===1&&l.push(t[g]);else l.push.apply(l,y);else z(y,l);if(S){k(S,q,l,m);k.uniqueSort(l)}return l};k.uniqueSort=function(g){if(B){i=o;g.sort(B);if(i)for(var h=1;h":function(g,h){var l=typeof h==="string";if(l&&!/\W/.test(h)){h=h.toLowerCase();for(var m=0,q=g.length;m=0))l||m.push(v);else if(l)h[p]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()}, -CHILD:function(g){if(g[1]==="nth"){var h=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=h[1]+(h[2]||1)-0;g[3]=h[3]-0}g[0]=e++;return g},ATTR:function(g,h,l,m,q,p){h=g[1].replace(/\\/g,"");if(!p&&n.attrMap[h])g[1]=n.attrMap[h];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,h,l,m,q){if(g[1]==="not")if((f.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=k(g[3],null,null,h);else{g=k.filter(g[3],h,l,true^q);l||m.push.apply(m, -g);return false}else if(n.match.POS.test(g[0])||n.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,h,l){return!!k(l[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)}, -text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}}, -setFilters:{first:function(g,h){return h===0},last:function(g,h,l,m){return h===m.length-1},even:function(g,h){return h%2===0},odd:function(g,h){return h%2===1},lt:function(g,h,l){return hl[3]-0},nth:function(g,h,l){return l[3]-0===h},eq:function(g,h,l){return l[3]-0===h}},filter:{PSEUDO:function(g,h,l,m){var q=h[1],p=n.filters[q];if(p)return p(g,l,h,m);else if(q==="contains")return(g.textContent||g.innerText||a([g])||"").indexOf(h[3])>=0;else if(q==="not"){h= -h[3];l=0;for(m=h.length;l=0}},ID:function(g,h){return g.nodeType===1&&g.getAttribute("id")===h},TAG:function(g,h){return h==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===h},CLASS:function(g,h){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(h)>-1},ATTR:function(g,h){var l=h[1];g=n.attrHandle[l]?n.attrHandle[l](g):g[l]!=null?g[l]:g.getAttribute(l);l=g+"";var m=h[2];h=h[4];return g==null?m==="!=":m=== -"="?l===h:m==="*="?l.indexOf(h)>=0:m==="~="?(" "+l+" ").indexOf(h)>=0:!h?l&&g!==false:m==="!="?l!==h:m==="^="?l.indexOf(h)===0:m==="$="?l.substr(l.length-h.length)===h:m==="|="?l===h||l.substr(0,h.length+1)===h+"-":false},POS:function(g,h,l,m){var q=n.setFilters[h[2]];if(q)return q(g,l,h,m)}}},r=n.match.POS;for(var u in n.match){n.match[u]=new RegExp(n.match[u].source+/(?![^\[]*\])(?![^\(]*\))/.source);n.leftMatch[u]=new RegExp(/(^(?:.|\r|\n)*?)/.source+n.match[u].source.replace(/\\(\d+)/g,function(g, -h){return"\\"+(h-0+1)}))}var z=function(g,h){g=Array.prototype.slice.call(g,0);if(h){h.push.apply(h,g);return h}return g};try{Array.prototype.slice.call(s.documentElement.childNodes,0)}catch(C){z=function(g,h){h=h||[];if(j.call(g)==="[object Array]")Array.prototype.push.apply(h,g);else if(typeof g.length==="number")for(var l=0,m=g.length;l";var l=s.documentElement;l.insertBefore(g,l.firstChild);if(s.getElementById(h)){n.find.ID=function(m,q,p){if(typeof q.getElementById!=="undefined"&&!p)return(q=q.getElementById(m[1]))?q.id===m[1]||typeof q.getAttributeNode!=="undefined"&& -q.getAttributeNode("id").nodeValue===m[1]?[q]:w:[]};n.filter.ID=function(m,q){var p=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&p&&p.nodeValue===q}}l.removeChild(g);l=g=null})();(function(){var g=s.createElement("div");g.appendChild(s.createComment(""));if(g.getElementsByTagName("*").length>0)n.find.TAG=function(h,l){l=l.getElementsByTagName(h[1]);if(h[1]==="*"){h=[];for(var m=0;l[m];m++)l[m].nodeType===1&&h.push(l[m]);l=h}return l};g.innerHTML=""; -if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")n.attrHandle.href=function(h){return h.getAttribute("href",2)};g=null})();s.querySelectorAll&&function(){var g=k,h=s.createElement("div");h.innerHTML="

";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){k=function(m,q,p,v){q=q||s;if(!v&&q.nodeType===9&&!x(q))try{return z(q.querySelectorAll(m),p)}catch(t){}return g(m,q,p,v)};for(var l in g)k[l]=g[l];h=null}}(); -(function(){var g=s.createElement("div");g.innerHTML="
";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){n.order.splice(1,0,"CLASS");n.find.CLASS=function(h,l,m){if(typeof l.getElementsByClassName!=="undefined"&&!m)return l.getElementsByClassName(h[1])};g=null}}})();var E=s.compareDocumentPosition?function(g,h){return!!(g.compareDocumentPosition(h)&16)}: -function(g,h){return g!==h&&(g.contains?g.contains(h):true)},x=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false},ga=function(g,h){var l=[],m="",q;for(h=h.nodeType?[h]:h;q=n.match.PSEUDO.exec(g);){m+=q[0];g=g.replace(n.match.PSEUDO,"")}g=n.relative[g]?g+"*":g;q=0;for(var p=h.length;q=0===d})};c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,f=0,e=this.length;f0)for(var j=d;j0},closest:function(a,b){if(c.isArray(a)){var d=[],f=this[0],e,j= -{},i;if(f&&a.length){e=0;for(var o=a.length;e-1:c(f).is(e)){d.push({selector:i,elem:f});delete j[i]}}f=f.parentNode}}return d}var k=c.expr.match.POS.test(a)?c(a,b||this.context):null;return this.map(function(n,r){for(;r&&r.ownerDocument&&r!==b;){if(k?k.index(r)>-1:c(r).is(a))return r;r=r.parentNode}return null})},index:function(a){if(!a||typeof a=== -"string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){a=typeof a==="string"?c(a,b||this.context):c.makeArray(a);b=c.merge(this.get(),a);return this.pushStack(qa(a[0])||qa(b[0])?b:c.unique(b))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode", -d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")? -a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,f){var e=c.map(this,b,d);eb.test(a)||(f=d);if(f&&typeof f==="string")e=c.filter(f,e);e=this.length>1?c.unique(e):e;if((this.length>1||gb.test(f))&&fb.test(a))e=e.reverse();return this.pushStack(e,a,R.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return c.find.matches(a,b)},dir:function(a,b,d){var f=[];for(a=a[b];a&&a.nodeType!==9&&(d===w||a.nodeType!==1||!c(a).is(d));){a.nodeType=== -1&&f.push(a);a=a[b]}return f},nth:function(a,b,d){b=b||1;for(var f=0;a;a=a[d])if(a.nodeType===1&&++f===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var Ja=/ jQuery\d+="(?:\d+|null)"/g,V=/^\s+/,Ka=/(<([\w:]+)[^>]*?)\/>/g,hb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,La=/<([\w:]+)/,ib=/"},F={option:[1,""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]};F.optgroup=F.option;F.tbody=F.tfoot=F.colgroup=F.caption=F.thead;F.th=F.td;if(!c.support.htmlSerialize)F._default=[1,"div
","
"];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d= -c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==w)return this.empty().append((this[0]&&this[0].ownerDocument||s).createTextNode(a));return c.text(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this}, -wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})}, -prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b, -this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},remove:function(a,b){for(var d=0,f;(f=this[d])!=null;d++)if(!a||c.filter(a,[f]).length){if(!b&&f.nodeType===1){c.cleanData(f.getElementsByTagName("*"));c.cleanData([f])}f.parentNode&&f.parentNode.removeChild(f)}return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++)for(b.nodeType===1&&c.cleanData(b.getElementsByTagName("*"));b.firstChild;)b.removeChild(b.firstChild); -return this},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,f=this.ownerDocument;if(!d){d=f.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(Ja,"").replace(/=([^="'>\s]+\/)>/g,'="$1">').replace(V,"")],f)[0]}else return this.cloneNode(true)});if(a===true){ra(this,b);ra(this.find("*"),b.find("*"))}return b},html:function(a){if(a===w)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Ja, -""):null;else if(typeof a==="string"&&!ta.test(a)&&(c.support.leadingWhitespace||!V.test(a))&&!F[(La.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Ka,Ma);try{for(var b=0,d=this.length;b0||e.cacheable||this.length>1?k.cloneNode(true):k)}o.length&&c.each(o,Qa)}return this}});c.fragments={};c.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var f=[];d=c(d);var e=this.length===1&&this[0].parentNode;if(e&&e.nodeType===11&&e.childNodes.length===1&&d.length===1){d[b](this[0]); -return this}else{e=0;for(var j=d.length;e0?this.clone(true):this).get();c.fn[b].apply(c(d[e]),i);f=f.concat(i)}return this.pushStack(f,a,d.selector)}}});c.extend({clean:function(a,b,d,f){b=b||s;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||s;for(var e=[],j=0,i;(i=a[j])!=null;j++){if(typeof i==="number")i+="";if(i){if(typeof i==="string"&&!jb.test(i))i=b.createTextNode(i);else if(typeof i==="string"){i=i.replace(Ka,Ma);var o=(La.exec(i)||["", -""])[1].toLowerCase(),k=F[o]||F._default,n=k[0],r=b.createElement("div");for(r.innerHTML=k[1]+i+k[2];n--;)r=r.lastChild;if(!c.support.tbody){n=ib.test(i);o=o==="table"&&!n?r.firstChild&&r.firstChild.childNodes:k[1]===""&&!n?r.childNodes:[];for(k=o.length-1;k>=0;--k)c.nodeName(o[k],"tbody")&&!o[k].childNodes.length&&o[k].parentNode.removeChild(o[k])}!c.support.leadingWhitespace&&V.test(i)&&r.insertBefore(b.createTextNode(V.exec(i)[0]),r.firstChild);i=r.childNodes}if(i.nodeType)e.push(i);else e= -c.merge(e,i)}}if(d)for(j=0;e[j];j++)if(f&&c.nodeName(e[j],"script")&&(!e[j].type||e[j].type.toLowerCase()==="text/javascript"))f.push(e[j].parentNode?e[j].parentNode.removeChild(e[j]):e[j]);else{e[j].nodeType===1&&e.splice.apply(e,[j+1,0].concat(c.makeArray(e[j].getElementsByTagName("script"))));d.appendChild(e[j])}return e},cleanData:function(a){for(var b,d,f=c.cache,e=c.event.special,j=c.support.deleteExpando,i=0,o;(o=a[i])!=null;i++)if(d=o[c.expando]){b=f[d];if(b.events)for(var k in b.events)e[k]? -c.event.remove(o,k):Ca(o,k,b.handle);if(j)delete o[c.expando];else o.removeAttribute&&o.removeAttribute(c.expando);delete f[d]}}});var kb=/z-?index|font-?weight|opacity|zoom|line-?height/i,Na=/alpha\([^)]*\)/,Oa=/opacity=([^)]*)/,ha=/float/i,ia=/-([a-z])/ig,lb=/([A-Z])/g,mb=/^-?\d+(?:px)?$/i,nb=/^-?\d/,ob={position:"absolute",visibility:"hidden",display:"block"},pb=["Left","Right"],qb=["Top","Bottom"],rb=s.defaultView&&s.defaultView.getComputedStyle,Pa=c.support.cssFloat?"cssFloat":"styleFloat",ja= -function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){return X(this,a,b,true,function(d,f,e){if(e===w)return c.curCSS(d,f);if(typeof e==="number"&&!kb.test(f))e+="px";c.style(d,f,e)})};c.extend({style:function(a,b,d){if(!a||a.nodeType===3||a.nodeType===8)return w;if((b==="width"||b==="height")&&parseFloat(d)<0)d=w;var f=a.style||a,e=d!==w;if(!c.support.opacity&&b==="opacity"){if(e){f.zoom=1;b=parseInt(d,10)+""==="NaN"?"":"alpha(opacity="+d*100+")";a=f.filter||c.curCSS(a,"filter")||"";f.filter= -Na.test(a)?a.replace(Na,b):b}return f.filter&&f.filter.indexOf("opacity=")>=0?parseFloat(Oa.exec(f.filter)[1])/100+"":""}if(ha.test(b))b=Pa;b=b.replace(ia,ja);if(e)f[b]=d;return f[b]},css:function(a,b,d,f){if(b==="width"||b==="height"){var e,j=b==="width"?pb:qb;function i(){e=b==="width"?a.offsetWidth:a.offsetHeight;f!=="border"&&c.each(j,function(){f||(e-=parseFloat(c.curCSS(a,"padding"+this,true))||0);if(f==="margin")e+=parseFloat(c.curCSS(a,"margin"+this,true))||0;else e-=parseFloat(c.curCSS(a, -"border"+this+"Width",true))||0})}a.offsetWidth!==0?i():c.swap(a,ob,i);return Math.max(0,Math.round(e))}return c.curCSS(a,b,d)},curCSS:function(a,b,d){var f,e=a.style;if(!c.support.opacity&&b==="opacity"&&a.currentStyle){f=Oa.test(a.currentStyle.filter||"")?parseFloat(RegExp.$1)/100+"":"";return f===""?"1":f}if(ha.test(b))b=Pa;if(!d&&e&&e[b])f=e[b];else if(rb){if(ha.test(b))b="float";b=b.replace(lb,"-$1").toLowerCase();e=a.ownerDocument.defaultView;if(!e)return null;if(a=e.getComputedStyle(a,null))f= -a.getPropertyValue(b);if(b==="opacity"&&f==="")f="1"}else if(a.currentStyle){d=b.replace(ia,ja);f=a.currentStyle[b]||a.currentStyle[d];if(!mb.test(f)&&nb.test(f)){b=e.left;var j=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;e.left=d==="fontSize"?"1em":f||0;f=e.pixelLeft+"px";e.left=b;a.runtimeStyle.left=j}}return f},swap:function(a,b,d){var f={};for(var e in b){f[e]=a.style[e];a.style[e]=b[e]}d.call(a);for(e in b)a.style[e]=f[e]}});if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b= -a.offsetWidth,d=a.offsetHeight,f=a.nodeName.toLowerCase()==="tr";return b===0&&d===0&&!f?true:b>0&&d>0&&!f?false:c.curCSS(a,"display")==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var sb=J(),tb=//gi,ub=/select|textarea/i,vb=/color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,N=/=\?(&|$)/,ka=/\?/,wb=/(\?|&)_=.*?(&|$)/,xb=/^(\w+:)?\/\/([^\/?#]+)/,yb=/%20/g,zb=c.fn.load;c.fn.extend({load:function(a,b,d){if(typeof a!== -"string")return zb.call(this,a);else if(!this.length)return this;var f=a.indexOf(" ");if(f>=0){var e=a.slice(f,a.length);a=a.slice(0,f)}f="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b==="object"){b=c.param(b,c.ajaxSettings.traditional);f="POST"}var j=this;c.ajax({url:a,type:f,dataType:"html",data:b,complete:function(i,o){if(o==="success"||o==="notmodified")j.html(e?c("
").append(i.responseText.replace(tb,"")).find(e):i.responseText);d&&j.each(d,[i.responseText,o,i])}});return this}, -serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||ub.test(this.nodeName)||vb.test(this.type))}).map(function(a,b){a=c(this).val();return a==null?null:c.isArray(a)?c.map(a,function(d){return{name:b.name,value:d}}):{name:b.name,value:a}}).get()}});c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "), -function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:f})},getScript:function(a,b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:f})},ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href, -global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:A.XMLHttpRequest&&(A.location.protocol!=="file:"||!A.ActiveXObject)?function(){return new A.XMLHttpRequest}:function(){try{return new A.ActiveXObject("Microsoft.XMLHTTP")}catch(a){}},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},etag:{},ajax:function(a){function b(){e.success&& -e.success.call(k,o,i,x);e.global&&f("ajaxSuccess",[x,e])}function d(){e.complete&&e.complete.call(k,x,i);e.global&&f("ajaxComplete",[x,e]);e.global&&!--c.active&&c.event.trigger("ajaxStop")}function f(q,p){(e.context?c(e.context):c.event).trigger(q,p)}var e=c.extend(true,{},c.ajaxSettings,a),j,i,o,k=a&&a.context||e,n=e.type.toUpperCase();if(e.data&&e.processData&&typeof e.data!=="string")e.data=c.param(e.data,e.traditional);if(e.dataType==="jsonp"){if(n==="GET")N.test(e.url)||(e.url+=(ka.test(e.url)? -"&":"?")+(e.jsonp||"callback")+"=?");else if(!e.data||!N.test(e.data))e.data=(e.data?e.data+"&":"")+(e.jsonp||"callback")+"=?";e.dataType="json"}if(e.dataType==="json"&&(e.data&&N.test(e.data)||N.test(e.url))){j=e.jsonpCallback||"jsonp"+sb++;if(e.data)e.data=(e.data+"").replace(N,"="+j+"$1");e.url=e.url.replace(N,"="+j+"$1");e.dataType="script";A[j]=A[j]||function(q){o=q;b();d();A[j]=w;try{delete A[j]}catch(p){}z&&z.removeChild(C)}}if(e.dataType==="script"&&e.cache===null)e.cache=false;if(e.cache=== -false&&n==="GET"){var r=J(),u=e.url.replace(wb,"$1_="+r+"$2");e.url=u+(u===e.url?(ka.test(e.url)?"&":"?")+"_="+r:"")}if(e.data&&n==="GET")e.url+=(ka.test(e.url)?"&":"?")+e.data;e.global&&!c.active++&&c.event.trigger("ajaxStart");r=(r=xb.exec(e.url))&&(r[1]&&r[1]!==location.protocol||r[2]!==location.host);if(e.dataType==="script"&&n==="GET"&&r){var z=s.getElementsByTagName("head")[0]||s.documentElement,C=s.createElement("script");C.src=e.url;if(e.scriptCharset)C.charset=e.scriptCharset;if(!j){var B= -false;C.onload=C.onreadystatechange=function(){if(!B&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){B=true;b();d();C.onload=C.onreadystatechange=null;z&&C.parentNode&&z.removeChild(C)}}}z.insertBefore(C,z.firstChild);return w}var E=false,x=e.xhr();if(x){e.username?x.open(n,e.url,e.async,e.username,e.password):x.open(n,e.url,e.async);try{if(e.data||a&&a.contentType)x.setRequestHeader("Content-Type",e.contentType);if(e.ifModified){c.lastModified[e.url]&&x.setRequestHeader("If-Modified-Since", -c.lastModified[e.url]);c.etag[e.url]&&x.setRequestHeader("If-None-Match",c.etag[e.url])}r||x.setRequestHeader("X-Requested-With","XMLHttpRequest");x.setRequestHeader("Accept",e.dataType&&e.accepts[e.dataType]?e.accepts[e.dataType]+", */*":e.accepts._default)}catch(ga){}if(e.beforeSend&&e.beforeSend.call(k,x,e)===false){e.global&&!--c.active&&c.event.trigger("ajaxStop");x.abort();return false}e.global&&f("ajaxSend",[x,e]);var g=x.onreadystatechange=function(q){if(!x||x.readyState===0||q==="abort"){E|| -d();E=true;if(x)x.onreadystatechange=c.noop}else if(!E&&x&&(x.readyState===4||q==="timeout")){E=true;x.onreadystatechange=c.noop;i=q==="timeout"?"timeout":!c.httpSuccess(x)?"error":e.ifModified&&c.httpNotModified(x,e.url)?"notmodified":"success";var p;if(i==="success")try{o=c.httpData(x,e.dataType,e)}catch(v){i="parsererror";p=v}if(i==="success"||i==="notmodified")j||b();else c.handleError(e,x,i,p);d();q==="timeout"&&x.abort();if(e.async)x=null}};try{var h=x.abort;x.abort=function(){x&&h.call(x); -g("abort")}}catch(l){}e.async&&e.timeout>0&&setTimeout(function(){x&&!E&&g("timeout")},e.timeout);try{x.send(n==="POST"||n==="PUT"||n==="DELETE"?e.data:null)}catch(m){c.handleError(e,x,null,m);d()}e.async||g();return x}},handleError:function(a,b,d,f){if(a.error)a.error.call(a.context||a,b,d,f);if(a.global)(a.context?c(a.context):c.event).trigger("ajaxError",[b,a,f])},active:0,httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status===304||a.status=== -1223||a.status===0}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),f=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(f)c.etag[b]=f;return a.status===304||a.status===0},httpData:function(a,b,d){var f=a.getResponseHeader("content-type")||"",e=b==="xml"||!b&&f.indexOf("xml")>=0;a=e?a.responseXML:a.responseText;e&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b=== -"json"||!b&&f.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&f.indexOf("javascript")>=0)c.globalEval(a);return a},param:function(a,b){function d(i,o){if(c.isArray(o))c.each(o,function(k,n){b||/\[\]$/.test(i)?f(i,n):d(i+"["+(typeof n==="object"||c.isArray(n)?k:"")+"]",n)});else!b&&o!=null&&typeof o==="object"?c.each(o,function(k,n){d(i+"["+k+"]",n)}):f(i,o)}function f(i,o){o=c.isFunction(o)?o():o;e[e.length]=encodeURIComponent(i)+"="+encodeURIComponent(o)}var e=[];if(b===w)b=c.ajaxSettings.traditional; -if(c.isArray(a)||a.jquery)c.each(a,function(){f(this.name,this.value)});else for(var j in a)d(j,a[j]);return e.join("&").replace(yb,"+")}});var la={},Ab=/toggle|show|hide/,Bb=/^([+-]=)?([\d+-.]+)(.*)$/,W,va=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b){if(a||a===0)return this.animate(K("show",3),a,b);else{a=0;for(b=this.length;a").appendTo("body");f=e.css("display");if(f==="none")f="block";e.remove();la[d]=f}c.data(this[a],"olddisplay",f)}}a=0;for(b=this.length;a=0;f--)if(d[f].elem===this){b&&d[f](true);d.splice(f,1)}});b||this.dequeue();return this}});c.each({slideDown:K("show",1),slideUp:K("hide",1),slideToggle:K("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(a,b){c.fn[a]=function(d,f){return this.animate(b,d,f)}});c.extend({speed:function(a,b,d){var f=a&&typeof a==="object"?a:{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};f.duration=c.fx.off?0:typeof f.duration=== -"number"?f.duration:c.fx.speeds[f.duration]||c.fx.speeds._default;f.old=f.complete;f.complete=function(){f.queue!==false&&c(this).dequeue();c.isFunction(f.old)&&f.old.call(this)};return f},easing:{linear:function(a,b,d,f){return d+f*a},swing:function(a,b,d,f){return(-Math.cos(a*Math.PI)/2+0.5)*f+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]|| -c.fx.step._default)(this);if((this.prop==="height"||this.prop==="width")&&this.elem.style)this.elem.style.display="block"},cur:function(a){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];return(a=parseFloat(c.css(this.elem,this.prop,a)))&&a>-10000?a:parseFloat(c.curCSS(this.elem,this.prop))||0},custom:function(a,b,d){function f(j){return e.step(j)}this.startTime=J();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start; -this.pos=this.state=0;var e=this;f.elem=this.elem;if(f()&&c.timers.push(f)&&!W)W=setInterval(c.fx.tick,13)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(a){var b=J(),d=true;if(a||b>=this.options.duration+this.startTime){this.now= -this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var f in this.options.curAnim)if(this.options.curAnim[f]!==true)d=false;if(d){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;a=c.data(this.elem,"olddisplay");this.elem.style.display=a?a:this.options.display;if(c.css(this.elem,"display")==="none")this.elem.style.display="block"}this.options.hide&&c(this.elem).hide();if(this.options.hide||this.options.show)for(var e in this.options.curAnim)c.style(this.elem, -e,this.options.orig[e]);this.options.complete.call(this.elem)}return false}else{e=b-this.startTime;this.state=e/this.options.duration;a=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||a](this.state,e,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a=c.timers,b=0;b
"; -a.insertBefore(b,a.firstChild);d=b.firstChild;f=d.firstChild;e=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=f.offsetTop!==5;this.doesAddBorderForTableAndCells=e.offsetTop===5;f.style.position="fixed";f.style.top="20px";this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15;f.style.position=f.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==j;a.removeChild(b); -c.offset.initialize=c.noop},bodyOffset:function(a){var b=a.offsetTop,d=a.offsetLeft;c.offset.initialize();if(c.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(c.curCSS(a,"marginTop",true))||0;d+=parseFloat(c.curCSS(a,"marginLeft",true))||0}return{top:b,left:d}},setOffset:function(a,b,d){if(/static/.test(c.curCSS(a,"position")))a.style.position="relative";var f=c(a),e=f.offset(),j=parseInt(c.curCSS(a,"top",true),10)||0,i=parseInt(c.curCSS(a,"left",true),10)||0;if(c.isFunction(b))b=b.call(a, -d,e);d={top:b.top-e.top+j,left:b.left-e.left+i};"using"in b?b.using.call(a,d):f.css(d)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),f=/^body|html$/i.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.curCSS(a,"marginTop",true))||0;d.left-=parseFloat(c.curCSS(a,"marginLeft",true))||0;f.top+=parseFloat(c.curCSS(b[0],"borderTopWidth",true))||0;f.left+=parseFloat(c.curCSS(b[0],"borderLeftWidth",true))||0;return{top:d.top- -f.top,left:d.left-f.left}},offsetParent:function(){return this.map(function(){for(var a=this.offsetParent||s.body;a&&!/^body|html$/i.test(a.nodeName)&&c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(f){var e=this[0],j;if(!e)return null;if(f!==w)return this.each(function(){if(j=wa(this))j.scrollTo(!a?f:c(j).scrollLeft(),a?f:c(j).scrollTop());else this[d]=f});else return(j=wa(e))?"pageXOffset"in j?j[a?"pageYOffset": -"pageXOffset"]:c.support.boxModel&&j.document.documentElement[d]||j.document.body[d]:e[d]}});c.each(["Height","Width"],function(a,b){var d=b.toLowerCase();c.fn["inner"+b]=function(){return this[0]?c.css(this[0],d,false,"padding"):null};c.fn["outer"+b]=function(f){return this[0]?c.css(this[0],d,false,f?"margin":"border"):null};c.fn[d]=function(f){var e=this[0];if(!e)return f==null?null:this;if(c.isFunction(f))return this.each(function(j){var i=c(this);i[d](f.call(this,j,i[d]()))});return"scrollTo"in -e&&e.document?e.document.compatMode==="CSS1Compat"&&e.document.documentElement["client"+b]||e.document.body["client"+b]:e.nodeType===9?Math.max(e.documentElement["client"+b],e.body["scroll"+b],e.documentElement["scroll"+b],e.body["offset"+b],e.documentElement["offset"+b]):f===w?c.css(e,d):this.css(d,typeof f==="string"?f:f+"px")}});A.jQuery=A.$=c})(window); Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/html/_static/logo.png and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/html/_static/logo.png differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/html/_static/minus.png and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/html/_static/minus.png differ Binary files /tmp/aVl_jWE6wM/circuits-2.1.0/docs/build/html/_static/plus.png and /tmp/MCOKeAgJHK/circuits-3.1.0+ds1/docs/build/html/_static/plus.png differ diff -Nru circuits-2.1.0/docs/build/html/_static/pygments.css circuits-3.1.0+ds1/docs/build/html/_static/pygments.css --- circuits-2.1.0/docs/build/html/_static/pygments.css 2013-02-27 11:28:04.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_static/pygments.css 1970-01-01 00:00:00.000000000 +0000 @@ -1,60 +0,0 @@ -.highlight .hll { background-color: #ffffcc } -.highlight { background: #ffffff; } -.highlight .c { color: #999988; font-style: italic } /* Comment */ -.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ -.highlight .k { font-weight: bold } /* Keyword */ -.highlight .o { font-weight: bold } /* Operator */ -.highlight .cm { color: #999988; font-style: italic } /* Comment.Multiline */ -.highlight .cp { color: #999999; font-weight: bold } /* Comment.Preproc */ -.highlight .c1 { color: #999988; font-style: italic } /* Comment.Single */ -.highlight .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */ -.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ -.highlight .ge { font-style: italic } /* Generic.Emph */ -.highlight .gr { color: #aa0000 } /* Generic.Error */ -.highlight .gh { color: #999999 } /* Generic.Heading */ -.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ -.highlight .go { color: #888888 } /* Generic.Output */ -.highlight .gp { color: #555555 } /* Generic.Prompt */ -.highlight .gs { font-weight: bold } /* Generic.Strong */ -.highlight .gu { color: #aaaaaa } /* Generic.Subheading */ -.highlight .gt { color: #aa0000 } /* Generic.Traceback */ -.highlight .kc { font-weight: bold } /* Keyword.Constant */ -.highlight .kd { font-weight: bold } /* Keyword.Declaration */ -.highlight .kn { font-weight: bold } /* Keyword.Namespace */ -.highlight .kp { font-weight: bold } /* Keyword.Pseudo */ -.highlight .kr { font-weight: bold } /* Keyword.Reserved */ -.highlight .kt { color: #445588; font-weight: bold } /* Keyword.Type */ -.highlight .m { color: #009999 } /* Literal.Number */ -.highlight .s { color: #bb8844 } /* Literal.String */ -.highlight .na { color: #008080 } /* Name.Attribute */ -.highlight .nb { color: #999999 } /* Name.Builtin */ -.highlight .nc { color: #445588; font-weight: bold } /* Name.Class */ -.highlight .no { color: #008080 } /* Name.Constant */ -.highlight .ni { color: #800080 } /* Name.Entity */ -.highlight .ne { color: #990000; font-weight: bold } /* Name.Exception */ -.highlight .nf { color: #990000; font-weight: bold } /* Name.Function */ -.highlight .nn { color: #555555 } /* Name.Namespace */ -.highlight .nt { color: #000080 } /* Name.Tag */ -.highlight .nv { color: #008080 } /* Name.Variable */ -.highlight .ow { font-weight: bold } /* Operator.Word */ -.highlight .w { color: #bbbbbb } /* Text.Whitespace */ -.highlight .mf { color: #009999 } /* Literal.Number.Float */ -.highlight .mh { color: #009999 } /* Literal.Number.Hex */ -.highlight .mi { color: #009999 } /* Literal.Number.Integer */ -.highlight .mo { color: #009999 } /* Literal.Number.Oct */ -.highlight .sb { color: #bb8844 } /* Literal.String.Backtick */ -.highlight .sc { color: #bb8844 } /* Literal.String.Char */ -.highlight .sd { color: #bb8844 } /* Literal.String.Doc */ -.highlight .s2 { color: #bb8844 } /* Literal.String.Double */ -.highlight .se { color: #bb8844 } /* Literal.String.Escape */ -.highlight .sh { color: #bb8844 } /* Literal.String.Heredoc */ -.highlight .si { color: #bb8844 } /* Literal.String.Interpol */ -.highlight .sx { color: #bb8844 } /* Literal.String.Other */ -.highlight .sr { color: #808000 } /* Literal.String.Regex */ -.highlight .s1 { color: #bb8844 } /* Literal.String.Single */ -.highlight .ss { color: #bb8844 } /* Literal.String.Symbol */ -.highlight .bp { color: #999999 } /* Name.Builtin.Pseudo */ -.highlight .vc { color: #008080 } /* Name.Variable.Class */ -.highlight .vg { color: #008080 } /* Name.Variable.Global */ -.highlight .vi { color: #008080 } /* Name.Variable.Instance */ -.highlight .il { color: #009999 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/_static/reset-fonts-grids.css circuits-3.1.0+ds1/docs/build/html/_static/reset-fonts-grids.css --- circuits-2.1.0/docs/build/html/_static/reset-fonts-grids.css 2013-01-05 14:31:19.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_static/reset-fonts-grids.css 1970-01-01 00:00:00.000000000 +0000 @@ -1,8 +0,0 @@ -/* -Copyright (c) 2008, Yahoo! Inc. All rights reserved. -Code licensed under the BSD License: -http://developer.yahoo.net/yui/license.txt -version: 2.5.1 -*/ -html{color:#000;background:#FFF;}body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td{margin:0;padding:0;}table{border-collapse:collapse;border-spacing:0;}fieldset,img{border:0;}address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;font-weight:normal;}li{list-style:none;}caption,th{text-align:left;}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal;}q:before,q:after{content:'';}abbr,acronym {border:0;font-variant:normal;}sup {vertical-align:text-top;}sub {vertical-align:text-bottom;}input,textarea,select{font-family:inherit;font-size:inherit;font-weight:inherit;}input,textarea,select{*font-size:100%;}legend{color:#000;}body {font:13px/1.231 arial,helvetica,clean,sans-serif;*font-size:small;*font:x-small;}table {font-size:inherit;font:100%;}pre,code,kbd,samp,tt{font-family:monospace;*font-size:108%;line-height:100%;} -body{text-align:center;}#ft{clear:both;}#doc,#doc2,#doc3,#doc4,.yui-t1,.yui-t2,.yui-t3,.yui-t4,.yui-t5,.yui-t6,.yui-t7{margin:auto;text-align:left;width:57.69em;*width:56.25em;min-width:750px;}#doc2{width:73.076em;*width:71.25em;}#doc3{margin:auto 10px;width:auto;}#doc4{width:74.923em;*width:73.05em;}.yui-b{position:relative;}.yui-b{_position:static;}#yui-main .yui-b{position:static;}#yui-main{width:100%;}.yui-t1 #yui-main,.yui-t2 #yui-main,.yui-t3 #yui-main{float:right;margin-left:-25em;}.yui-t4 #yui-main,.yui-t5 #yui-main,.yui-t6 #yui-main{float:left;margin-right:-25em;}.yui-t1 .yui-b{float:left;width:12.30769em;*width:12.00em;}.yui-t1 #yui-main .yui-b{margin-left:13.30769em;*margin-left:13.05em;}.yui-t2 .yui-b{float:left;width:13.8461em;*width:13.50em;}.yui-t2 #yui-main .yui-b{margin-left:14.8461em;*margin-left:14.55em;}.yui-t3 .yui-b{float:left;width:23.0769em;*width:22.50em;}.yui-t3 #yui-main .yui-b{margin-left:24.0769em;*margin-left:23.62em;}.yui-t4 .yui-b{float:right;width:13.8456em;*width:13.50em;}.yui-t4 #yui-main .yui-b{margin-right:14.8456em;*margin-right:14.55em;}.yui-t5 .yui-b{float:right;width:18.4615em;*width:18.00em;}.yui-t5 #yui-main .yui-b{margin-right:19.4615em;*margin-right:19.125em;}.yui-t6 .yui-b{float:right;width:23.0769em;*width:22.50em;}.yui-t6 #yui-main .yui-b{margin-right:24.0769em;*margin-right:23.62em;}.yui-t7 #yui-main .yui-b{display:block;margin:0 0 1em 0;}#yui-main .yui-b{float:none;width:auto;}.yui-gb .yui-u,.yui-g .yui-gb .yui-u,.yui-gb .yui-g,.yui-gb .yui-gb,.yui-gb .yui-gc,.yui-gb .yui-gd,.yui-gb .yui-ge,.yui-gb .yui-gf,.yui-gc .yui-u,.yui-gc .yui-g,.yui-gd .yui-u{float:left;}.yui-g .yui-u,.yui-g .yui-g,.yui-g .yui-gb,.yui-g .yui-gc,.yui-g .yui-gd,.yui-g .yui-ge,.yui-g .yui-gf,.yui-gc .yui-u,.yui-gd .yui-g,.yui-g .yui-gc .yui-u,.yui-ge .yui-u,.yui-ge .yui-g,.yui-gf .yui-g,.yui-gf .yui-u{float:right;}.yui-g div.first,.yui-gb div.first,.yui-gc div.first,.yui-gd div.first,.yui-ge div.first,.yui-gf div.first,.yui-g .yui-gc div.first,.yui-g .yui-ge div.first,.yui-gc div.first div.first{float:left;}.yui-g .yui-u,.yui-g .yui-g,.yui-g .yui-gb,.yui-g .yui-gc,.yui-g .yui-gd,.yui-g .yui-ge,.yui-g .yui-gf{width:49.1%;}.yui-gb .yui-u,.yui-g .yui-gb .yui-u,.yui-gb .yui-g,.yui-gb .yui-gb,.yui-gb .yui-gc,.yui-gb .yui-gd,.yui-gb .yui-ge,.yui-gb .yui-gf,.yui-gc .yui-u,.yui-gc .yui-g,.yui-gd .yui-u{width:32%;margin-left:1.99%;}.yui-gb .yui-u{*margin-left:1.9%;*width:31.9%;}.yui-gc div.first,.yui-gd .yui-u{width:66%;}.yui-gd div.first{width:32%;}.yui-ge div.first,.yui-gf .yui-u{width:74.2%;}.yui-ge .yui-u,.yui-gf div.first{width:24%;}.yui-g .yui-gb div.first,.yui-gb div.first,.yui-gc div.first,.yui-gd div.first{margin-left:0;}.yui-g .yui-g .yui-u,.yui-gb .yui-g .yui-u,.yui-gc .yui-g .yui-u,.yui-gd .yui-g .yui-u,.yui-ge .yui-g .yui-u,.yui-gf .yui-g .yui-u{width:49%;*width:48.1%;*margin-left:0;}.yui-g .yui-gb div.first,.yui-gb .yui-gb div.first{*margin-right:0;*width:32%;_width:31.7%;}.yui-g .yui-gc div.first,.yui-gd .yui-g{width:66%;}.yui-gb .yui-g div.first{*margin-right:4%;_margin-right:1.3%;}.yui-gb .yui-gc div.first,.yui-gb .yui-gd div.first{*margin-right:0;}.yui-gb .yui-gb .yui-u,.yui-gb .yui-gc .yui-u{*margin-left:1.8%;_margin-left:4%;}.yui-g .yui-gb .yui-u{_margin-left:1.0%;}.yui-gb .yui-gd .yui-u{*width:66%;_width:61.2%;}.yui-gb .yui-gd div.first{*width:31%;_width:29.5%;}.yui-g .yui-gc .yui-u,.yui-gb .yui-gc .yui-u{width:32%;_float:right;margin-right:0;_margin-left:0;}.yui-gb .yui-gc div.first{width:66%;*float:left;*margin-left:0;}.yui-gb .yui-ge .yui-u,.yui-gb .yui-gf .yui-u{margin:0;}.yui-gb .yui-gb .yui-u{_margin-left:.7%;}.yui-gb .yui-g div.first,.yui-gb .yui-gb div.first{*margin-left:0;}.yui-gc .yui-g .yui-u,.yui-gd .yui-g .yui-u{*width:48.1%;*margin-left:0;}s .yui-gb .yui-gd div.first{width:32%;}.yui-g .yui-gd div.first{_width:29.9%;}.yui-ge .yui-g{width:24%;}.yui-gf .yui-g{width:74.2%;}.yui-gb .yui-ge div.yui-u,.yui-gb .yui-gf div.yui-u{float:right;}.yui-gb .yui-ge div.first,.yui-gb .yui-gf div.first{float:left;}.yui-gb .yui-ge .yui-u,.yui-gb .yui-gf div.first{*width:24%;_width:20%;}.yui-gb .yui-ge div.first,.yui-gb .yui-gf .yui-u{*width:73.5%;_width:65.5%;}.yui-ge div.first .yui-gd .yui-u{width:65%;}.yui-ge div.first .yui-gd div.first{width:32%;}#bd:after,.yui-g:after,.yui-gb:after,.yui-gc:after,.yui-gd:after,.yui-ge:after,.yui-gf:after{content:".";display:block;height:0;clear:both;visibility:hidden;}#bd,.yui-g,.yui-gb,.yui-gc,.yui-gd,.yui-ge,.yui-gf{zoom:1;} \ No newline at end of file diff -Nru circuits-2.1.0/docs/build/html/_static/searchtools.js circuits-3.1.0+ds1/docs/build/html/_static/searchtools.js --- circuits-2.1.0/docs/build/html/_static/searchtools.js 2013-02-27 11:28:04.000000000 +0000 +++ circuits-3.1.0+ds1/docs/build/html/_static/searchtools.js 1970-01-01 00:00:00.000000000 +0000 @@ -1,560 +0,0 @@ -/* - * searchtools.js_t - * ~~~~~~~~~~~~~~~~ - * - * Sphinx JavaScript utilties for the full-text search. - * - * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. - * :license: BSD, see LICENSE for details. - * - */ - -/** - * helper function to return a node containing the - * search summary for a given text. keywords is a list - * of stemmed words, hlwords is the list of normal, unstemmed - * words. the first one is used to find the occurance, the - * latter for highlighting it. - */ - -jQuery.makeSearchSummary = function(text, keywords, hlwords) { - var textLower = text.toLowerCase(); - var start = 0; - $.each(keywords, function() { - var i = textLower.indexOf(this.toLowerCase()); - if (i > -1) - start = i; - }); - start = Math.max(start - 120, 0); - var excerpt = ((start > 0) ? '...' : '') + - $.trim(text.substr(start, 240)) + - ((start + 240 - text.length) ? '...' : ''); - var rv = $('
').text(excerpt); - $.each(hlwords, function() { - rv = rv.highlightText(this, 'highlighted'); - }); - return rv; -} - - -/** - * Porter Stemmer - */ -var Stemmer = function() { - - var step2list = { - ational: 'ate', - tional: 'tion', - enci: 'ence', - anci: 'ance', - izer: 'ize', - bli: 'ble', - alli: 'al', - entli: 'ent', - eli: 'e', - ousli: 'ous', - ization: 'ize', - ation: 'ate', - ator: 'ate', - alism: 'al', - iveness: 'ive', - fulness: 'ful', - ousness: 'ous', - aliti: 'al', - iviti: 'ive', - biliti: 'ble', - logi: 'log' - }; - - var step3list = { - icate: 'ic', - ative: '', - alize: 'al', - iciti: 'ic', - ical: 'ic', - ful: '', - ness: '' - }; - - var c = "[^aeiou]"; // consonant - var v = "[aeiouy]"; // vowel - var C = c + "[^aeiouy]*"; // consonant sequence - var V = v + "[aeiou]*"; // vowel sequence - - var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0 - var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 - var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 - var s_v = "^(" + C + ")?" + v; // vowel in stem - - this.stemWord = function (w) { - var stem; - var suffix; - var firstch; - var origword = w; - - if (w.length < 3) - return w; - - var re; - var re2; - var re3; - var re4; - - firstch = w.substr(0,1); - if (firstch == "y") - w = firstch.toUpperCase() + w.substr(1); - - // Step 1a - re = /^(.+?)(ss|i)es$/; - re2 = /^(.+?)([^s])s$/; - - if (re.test(w)) - w = w.replace(re,"$1$2"); - else if (re2.test(w)) - w = w.replace(re2,"$1$2"); - - // Step 1b - re = /^(.+?)eed$/; - re2 = /^(.+?)(ed|ing)$/; - if (re.test(w)) { - var fp = re.exec(w); - re = new RegExp(mgr0); - if (re.test(fp[1])) { - re = /.$/; - w = w.replace(re,""); - } - } - else if (re2.test(w)) { - var fp = re2.exec(w); - stem = fp[1]; - re2 = new RegExp(s_v); - if (re2.test(stem)) { - w = stem; - re2 = /(at|bl|iz)$/; - re3 = new RegExp("([^aeiouylsz])\\1$"); - re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); - if (re2.test(w)) - w = w + "e"; - else if (re3.test(w)) { - re = /.$/; - w = w.replace(re,""); - } - else if (re4.test(w)) - w = w + "e"; - } - } - - // Step 1c - re = /^(.+?)y$/; - if (re.test(w)) { - var fp = re.exec(w); - stem = fp[1]; - re = new RegExp(s_v); - if (re.test(stem)) - w = stem + "i"; - } - - // Step 2 - re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; - if (re.test(w)) { - var fp = re.exec(w); - stem = fp[1]; - suffix = fp[2]; - re = new RegExp(mgr0); - if (re.test(stem)) - w = stem + step2list[suffix]; - } - - // Step 3 - re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; - if (re.test(w)) { - var fp = re.exec(w); - stem = fp[1]; - suffix = fp[2]; - re = new RegExp(mgr0); - if (re.test(stem)) - w = stem + step3list[suffix]; - } - - // Step 4 - re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; - re2 = /^(.+?)(s|t)(ion)$/; - if (re.test(w)) { - var fp = re.exec(w); - stem = fp[1]; - re = new RegExp(mgr1); - if (re.test(stem)) - w = stem; - } - else if (re2.test(w)) { - var fp = re2.exec(w); - stem = fp[1] + fp[2]; - re2 = new RegExp(mgr1); - if (re2.test(stem)) - w = stem; - } - - // Step 5 - re = /^(.+?)e$/; - if (re.test(w)) { - var fp = re.exec(w); - stem = fp[1]; - re = new RegExp(mgr1); - re2 = new RegExp(meq1); - re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); - if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) - w = stem; - } - re = /ll$/; - re2 = new RegExp(mgr1); - if (re.test(w) && re2.test(w)) { - re = /.$/; - w = w.replace(re,""); - } - - // and turn initial Y back to y - if (firstch == "y") - w = firstch.toLowerCase() + w.substr(1); - return w; - } -} - - -/** - * Search Module - */ -var Search = { - - _index : null, - _queued_query : null, - _pulse_status : -1, - - init : function() { - var params = $.getQueryParameters(); - if (params.q) { - var query = params.q[0]; - $('input[name="q"]')[0].value = query; - this.performSearch(query); - } - }, - - loadIndex : function(url) { - $.ajax({type: "GET", url: url, data: null, success: null, - dataType: "script", cache: true}); - }, - - setIndex : function(index) { - var q; - this._index = index; - if ((q = this._queued_query) !== null) { - this._queued_query = null; - Search.query(q); - } - }, - - hasIndex : function() { - return this._index !== null; - }, - - deferQuery : function(query) { - this._queued_query = query; - }, - - stopPulse : function() { - this._pulse_status = 0; - }, - - startPulse : function() { - if (this._pulse_status >= 0) - return; - function pulse() { - Search._pulse_status = (Search._pulse_status + 1) % 4; - var dotString = ''; - for (var i = 0; i < Search._pulse_status; i++) - dotString += '.'; - Search.dots.text(dotString); - if (Search._pulse_status > -1) - window.setTimeout(pulse, 500); - }; - pulse(); - }, - - /** - * perform a search for something - */ - performSearch : function(query) { - // create the required interface elements - this.out = $('#search-results'); - this.title = $('

' + _('Searching') + '

').appendTo(this.out); - this.dots = $('').appendTo(this.title); - this.status = $('

').appendTo(this.out); - this.output = $('