circuits-3.1.0/ 0000755 0000144 0000144 00000000000 12425013644 014332 5 ustar prologic users 0000000 0000000 circuits-3.1.0/CHANGES.rst 0000644 0000144 0000144 00000012465 12425013545 016144 0 ustar prologic users 0000000 0000000 :orphan:
==========
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 `_
circuits-3.1.0/fabfile/ 0000755 0000144 0000144 00000000000 12425013643 015721 5 ustar prologic users 0000000 0000000 circuits-3.1.0/fabfile/__init__.py 0000644 0000144 0000144 00000006531 12402037676 020046 0 ustar prologic users 0000000 0000000 # Package: fabfile
# Date: 18th June 2013
# Author: James Mills, j dot mills at griffith dot edu dot au
"""Development Task"""
from __future__ import print_function
from os import getcwd
from fabric.api import (
abort, cd, execute, hide, hosts,
local, prefix, prompt, run, settings, task
)
import help # noqa
import docs # noqa
import docker # noqa
from .utils import msg, pip, requires, tobool
@task()
@requires("pip")
def build(**options):
"""Build and install required dependencies
Options can be provided to customize the build.
The following options are supported:
- dev -> Whether to install in development mode (Default: Fase)
"""
dev = tobool(options.get("dev", False))
if dev:
pip(requirements="requirements-dev.txt")
with settings(hide("stdout", "stderr"), warn_only=True):
local("python setup.py {0:s}".format("develop" if dev else "install"))
@task()
def clean():
"""Clean up build files and directories"""
files = ["build", ".coverage", "coverage", "dist", "docs/build"]
local("rm -rf {0:s}".format(" ".join(files)))
local("find . -type f -name '*~' -delete")
local("find . -type f -name '*.pyo' -delete")
local("find . -type f -name '*.pyc' -delete")
local("find . -type d -name '__pycache__' -delete")
local("find . -type d -name '*egg-info' -exec rm -rf {} +")
@task()
def develop():
"""Build and Install in Development Mode"""
return execute(build, dev=True)
@task()
@requires("py.test")
def test():
"""Run all unit tests and doctests."""
local("python setup.py test")
@task()
@hosts("localhost")
def release():
"""Performs a full release"""
with cd(getcwd()):
with msg("Creating env"):
run("mkvirtualenv test")
with msg("Bootstrapping"):
with prefix("workon test"):
run("./bootstrap.sh")
with msg("Building"):
with prefix("workon test"):
run("fab develop")
with msg("Running tests"):
with prefix("workon test"):
run("fab test")
with msg("Building docs"):
with prefix("workon test"):
run("pip install -r docs/requirements.txt")
run("fab docs")
version = run("python setup.py --version")
if "dev" in version:
abort("Detected Development Version!")
print("Release version: {0:s}".format(version))
if prompt("Is this ok?", default="Y", validate=r"^[YyNn]?$") in "yY":
run("hg tag {0:s}".format(version))
run("python setup.py egg_info sdist bdist_egg register upload")
run("python setup.py build_sphinx upload_sphinx")
with msg("Destroying env"):
run("rmvirtualenv test")
@task()
def sync(*args):
"""Synchronouse Local Repository with Remote(s)"""
status = local("hg status", capture=True)
if status:
abort(
(
"Repository is not in a clean state! "
"Please commit, revert or shelve!"
)
)
with settings(warn_only=True):
local("hg pull --update")
local("hg pull --update github")
local("hg pull --update upstream")
local("hg bookmark -r tip master")
local("hg push")
local("hg push github")
local("hg push upstream")
circuits-3.1.0/fabfile/docs.py 0000644 0000144 0000144 00000001767 12402037676 017245 0 ustar prologic users 0000000 0000000 # Module: docs
# Date: 03rd April 2013
# Author: James Mills, j dot mills at griffith dot edu dot au
"""Documentation Tasks"""
from fabric.api import lcd, local, task
from .utils import pip, requires
PACKAGE = "circuits"
@task()
def api():
"""Generate the API Documentation"""
if PACKAGE is not None:
pip(requirements="docs/requirements.txt")
local("sphinx-apidoc -f -e -T -o docs/source/api {0:s}".format(PACKAGE))
@task()
@requires("make")
def clean():
"""Delete Generated Documentation"""
with lcd("docs"):
pip(requirements="requirements.txt")
local("make clean")
@task(default=True)
@requires("make")
def build(**options):
"""Build the Documentation"""
pip(requirements="docs/requirements.txt")
with lcd("docs"):
local("make html")
@task()
@requires("open")
def view(**options):
"""View the Documentation"""
with lcd("docs"):
import webbrowser
webbrowser.open_new_tab("build/html/index.html")
circuits-3.1.0/fabfile/help.py 0000644 0000144 0000144 00000002024 12402037676 017230 0 ustar prologic users 0000000 0000000 # Module: help
# Date: 28th November 2013
# Author: James Mills, j dot mills at griffith dot edu dot au
"""Help Tasks"""
from __future__ import print_function
from fabric import state
from fabric.api import task
from fabric.tasks import Task
from fabric.task_utils import crawl
@task(default=True)
def help(name=None):
"""Display help for a given task
Options:
name - The task to display help on.
To display a list of available tasks type:
$ fab -l
To display help on a specific task type:
$ fab help:
"""
if name is None:
name = "help"
task = crawl(name, state.commands)
if isinstance(task, Task):
doc = getattr(task, "__doc__", None)
if doc is not None:
print("Help on {0:s}:".format(name))
print()
print(doc)
else:
print("No help available for {0;s}".format(name))
else:
print("No such task {0:s}".format(name))
print("For a list of tasks type: fab -l")
circuits-3.1.0/fabfile/docker.py 0000644 0000144 0000144 00000002255 12402037676 017555 0 ustar prologic users 0000000 0000000 # Module: docker
# Date: 24th May 2014
# Author: James Mills, j dot mills at griffith dot edu dot au
"""Docker Tasks"""
from fabric.api import local, task
from .utils import msg, requires, tobool
TAG = "prologic/circuits"
@task(default=True)
@requires("docker")
def build(**options):
"""Build Docker Image
Options can be provided to customize the build.
The following options are supported:
- rebuild -> Whether to rebuild without a cache.
- version -> Specific version to tag the image with (Default: latest)
"""
rebuild = tobool(options.get("rebuild", False))
version = options.get("version", "latest")
tag = "{0:s}:{1:s}".format(TAG, version)
args = ["docker", "build", "-t", tag, "."]
if rebuild:
args.insert(-1, "--no-cache")
with msg("Building Image"):
local(" ".join(args))
@task()
@requires("docker")
def publish():
"""Publish Docker Image"""
args = ["docker", "push", TAG]
with msg("Pushing Image"):
local(" ".join(args))
@task()
@requires("docker")
def run():
"""Run Docker Container"""
args = ["docker", "run", "-i", "-t", "--rm", TAG]
local(" ".join(args))
circuits-3.1.0/fabfile/utils.py 0000644 0000144 0000144 00000004113 12402037676 017441 0 ustar prologic users 0000000 0000000 # Module: utils
# Date: 03rd April 2013
# Author: James Mills, j dot mills at griffith dot edu dot au
"""Utilities"""
from functools import wraps
from imp import find_module
from contextlib import contextmanager
from fabric.api import abort, hide, local, puts, quiet, settings, warn
def tobool(s):
if isinstance(s, bool):
return s
return s.lower() in ["yes", "y"]
def toint(s):
if isinstance(s, int):
return s
return int(s)
@contextmanager
def msg(s):
"""Print message given as ``s`` in a context manager
Prints "{s} ... OK"
"""
puts("{0:s} ... ".format(s), end="", flush=True)
with settings(hide("everything")):
yield
puts("OK", show_prefix=False, flush=True)
def pip(*args, **kwargs):
requirements = kwargs.get("requirements", None)
if requirements is not None:
local("pip install -U -r {0:s}".format(kwargs["requirements"]))
else:
args = list(arg for arg in args if not has_module(arg))
if args:
local("pip install {0:s}".format(" ".join(args)))
def has_module(name):
try:
return find_module(name)
except ImportError:
return False
def has_binary(name):
with quiet():
return local("which {0:s}".format(name)).succeeded
def requires(*names, **kwargs):
"""Decorator/Wrapper that aborts if not all requirements are met.
Aborts if not all requirements are met given a test function
(defaulting to :func:`~has_binary`).
:param kwargs: Optional kwargs. e.g: ``test=has_module``
:type kwargs: dict
:returns: None or aborts
:rtype: None
"""
test = kwargs.get("test", has_binary)
def decorator(f):
@wraps(f)
def wrapper(*args, **kwds):
if all(test(name) for name in names):
return f(*args, **kwds)
else:
for name in names:
if not test(name):
warn("{0:s} not found".format(name))
abort("requires({0:s}) failed".format(repr(names)))
return wrapper
return decorator
circuits-3.1.0/tests/ 0000755 0000144 0000144 00000000000 12425013643 015473 5 ustar prologic users 0000000 0000000 circuits-3.1.0/tests/conftest.pyc 0000644 0000144 0000144 00000013005 12420400435 020026 0 ustar prologic users 0000000 0000000
?Tc @ s% d Z d d l Z d d l Z d d l Z d d l Z d d l m Z d d l m Z d d l m Z d d l
m Z m Z m
Z
m Z d e f d YZ d e f d
YZ d Z d Z d
e f d YZ e d d Z e j d d d Z e j d Z d Z d S( s py.test configiN( t sleep( t deque( t TIMEOUT( t handlert
BaseComponentt Debuggert Managert Watcherc B sG e Z d Z e d d d d d Z d Z d d d Z RS(
c C s t j | _ t | _ d S( N( t threadingt Lockt _lockR t events( t self( ( s. /home/prologic/work/circuits/tests/conftest.pyt init s t channelt *t priorityg33333?@c O s$ | j | j j | Wd QXd S( N( R
R t append( R t eventt argst kwargs( ( s. /home/prologic/work/circuits/tests/conftest.pyt _on_event s
c C s | j j d S( N( R t clear( R ( ( s. /home/prologic/work/circuits/tests/conftest.pyR s g @c C s z x t t | t D] } | d k rf | j , x$ | j D] } | j | k r@ t Sq@ WWd QXnF | j ; x3 | j D]( } | j | k rz | | j k rz t Sqz WWd QXt t q WWd Xd S( N(
t ranget intR t NoneR
R t namet Truet channelsR ( R R R t timeoutt iR ( ( s. /home/prologic/work/circuits/tests/conftest.pyt wait! s
N( t __name__t
__module__R
R R R R R ( ( ( s. /home/prologic/work/circuits/tests/conftest.pyR s t Flagc B s e Z e Z RS( ( R R! t Falset status( ( ( s. /home/prologic/work/circuits/tests/conftest.pyR" 6 s c G sU t } d } xB | j | D]1 } | sC t } | j | | } n t d q W| S( Ng?( R# R t waitEventR t fireR ( t managerR t
event_nameR t firedt valuet r( ( s. /home/prologic/work/circuits/tests/conftest.pyt call_event_from_name: s c G s t | | | j | S( N( R, R ( R' R R ( ( s. /home/prologic/work/circuits/tests/conftest.pyt
call_eventE s t WaitEventc B s e Z d d d Z d Z RS( g @c s | d k r! t | d d } n | | _ | | _ t t | d | f d } | j j | | _ | _ d S( NR c s
t _ d S( N( R R$ ( R R R ( t flag( s. /home/prologic/work/circuits/tests/conftest.pyt on_eventT s ( R t getattrR R' R" R t
addHandlerR/ ( R R' R R R R0 ( ( R/ s. /home/prologic/work/circuits/tests/conftest.pyt __init__K s !c C s] zB x; t t | j t D] } | j j r3 t St t q WWd | j j | j
Xd S( N( R R R R R/ R$ R R R' t
removeHandlerR ( R R ( ( s. /home/prologic/work/circuits/tests/conftest.pyR [ s N( R R! R R3 R ( ( ( s. /home/prologic/work/circuits/tests/conftest.pyR. I s g @c C s d d l m } xi t t | | D]Q } t | t j rU | | | rn t Sn t | | | k rn t St | q' Wd S( Ni( R (
t circuits.core.managerR R R t
isinstancet collectionst CallableR R1 R ( t objt attrR* R R R ( ( s. /home/prologic/work/circuits/tests/conftest.pyt wait_fore s t scopet sessionc s t f d } | j | t d } j | j sP t | j j j rh t } n t
} t d | j S( Nc s j d S( N( t stop( ( R' ( s. /home/prologic/work/circuits/tests/conftest.pyt finalizert s t startedR (
R t addfinalizerR. t startR t AssertionErrort configt optiont verboseR R# R t register( t requestR? t waiterRF ( ( R' s. /home/prologic/work/circuits/tests/conftest.pyR' p s
c s5 t j f d } | j | S( Nc s' t d } j | j d S( Nt unregistered( R. t
unregisterR ( RI ( R' t watcher( s. /home/prologic/work/circuits/tests/conftest.pyR? s
( R RG RA ( RH R' R? ( ( R' RL s. /home/prologic/work/circuits/tests/conftest.pyRL s
c C sJ t d t f d t f d t f d t j f d t j d f d t f f S( NR. R; R- t PLATFORMt PYVERi R, ( t dictR. R; R- t syst platformt version_infoR, ( ( ( s. /home/prologic/work/circuits/tests/conftest.pyt pytest_namespace s ( t __doc__t pytestRP R R7 t timeR R R5 R t circuitsR R R R R t objectR" R, R- R. R R; t fixtureR' RL RS ( ( ( s. /home/prologic/work/circuits/tests/conftest.pyt s" "# circuits-3.1.0/tests/protocols/ 0000755 0000144 0000144 00000000000 12425013643 017517 5 ustar prologic users 0000000 0000000 circuits-3.1.0/tests/protocols/__init__.py 0000644 0000144 0000144 00000000000 12402037676 021625 0 ustar prologic users 0000000 0000000 circuits-3.1.0/tests/protocols/test_irc.py 0000644 0000144 0000144 00000007146 12406033230 021706 0 ustar prologic users 0000000 0000000 #!/usr/bin/env python
import pytest
from pytest import fixture
from circuits import handler, Event, Component
from circuits.net.events import read, write
from circuits.protocols.irc import IRC
from circuits.protocols.irc import strip, joinprefix, parseprefix
from circuits.protocols.irc import (
PASS, USER, NICK, PONG, QUIT,
JOIN, PART, PRIVMSG, NOTICE, AWAY,
KICK, TOPIC, MODE, INVITE, NAMES, WHOIS
)
from circuits.six import u
class App(Component):
def init(self):
IRC().register(self)
self.data = []
self.events = []
@handler(False)
def reset(self):
self.data = []
self.events = []
@handler()
def _on_event(self, event, *args, **kwargs):
self.events.append(event)
def request(self, message):
self.fire(write(bytes(message)))
def write(self, data):
self.data.append(data)
@fixture(scope="function")
def app(request):
app = App()
while app:
app.flush()
return app
def test_strip():
s = ":\x01\x02test\x02\x01"
s = strip(s)
assert s == "\x01\x02test\x02\x01"
s = ":\x01\x02test\x02\x01"
s = strip(s, color=True)
assert s == "test"
def test_joinprefix():
nick, ident, host = "test", "foo", "localhost"
s = joinprefix(nick, ident, host)
assert s == "test!foo@localhost"
def test_parseprefix():
s = "test!foo@localhost"
nick, ident, host = parseprefix(s)
assert nick == "test"
assert ident == "foo"
assert host == "localhost"
s = "test"
nick, ident, host = parseprefix(s)
assert nick == "test"
assert ident is None
assert host is None
@pytest.mark.parametrize("event,data", [
(PASS("secret"), b"PASS secret\r\n"),
(
USER("foo", "localhost", "localhost", "Test Client"),
b"USER foo localhost localhost :Test Client\r\n"
),
(NICK("test"), b"NICK test\r\n"),
(PONG("localhost"), b"PONG :localhost\r\n"),
(QUIT(), b"QUIT Leaving\r\n"),
(QUIT("Test"), b"QUIT Test\r\n"),
(QUIT("Test Message"), b"QUIT :Test Message\r\n"),
(JOIN("#test"), b"JOIN #test\r\n"),
(JOIN("#test", "secret"), b"JOIN #test secret\r\n"),
(PART("#test"), b"PART #test\r\n"),
(PRIVMSG("test", "Hello"), b"PRIVMSG test Hello\r\n"),
(PRIVMSG("test", "Hello World"), b"PRIVMSG test :Hello World\r\n"),
(NOTICE("test", "Hello"), b"NOTICE test Hello\r\n"),
(NOTICE("test", "Hello World"), b"NOTICE test :Hello World\r\n"),
(KICK("#test", "test"), b"KICK #test test :\r\n"),
(KICK("#test", "test", "Bye"), b"KICK #test test Bye\r\n"),
(KICK("#test", "test", "Good Bye!"), b"KICK #test test :Good Bye!\r\n"),
(TOPIC("#test", "Hello World!"), b"TOPIC #test :Hello World!\r\n"),
(MODE("+i"), b"MODE +i\r\n"),
(MODE("#test", "+o", "test"), b"MODE #test +o test\r\n"),
(INVITE("test", "#test"), b"INVITE test #test\r\n"),
(NAMES(), b"NAMES\r\n"),
(NAMES("#test"), b"NAMES #test\r\n"),
(AWAY("I am away."), b"AWAY :I am away.\r\n"),
(WHOIS("somenick"), b"WHOIS :somenick\r\n"),
])
def test_commands(event, data):
message = event.args[0]
return bytes(message) == data
@pytest.mark.parametrize("data,event", [
(
b":localhost NOTICE * :*** Looking up your hostname...\r\n",
Event.create(
"notice", (u("localhost"), None, None), u("*"),
u("*** Looking up your hostname..."),
)
),
])
def test_responses(app, data, event):
app.reset()
app.fire(read(data))
while app:
app.flush()
e = app.events[-1]
assert event.name == e.name
assert event.args == e.args
assert event.kwargs == e.kwargs
circuits-3.1.0/tests/protocols/__pycache__/ 0000755 0000144 0000144 00000000000 12425013643 021727 5 ustar prologic users 0000000 0000000 circuits-3.1.0/tests/protocols/__pycache__/test_irc.cpython-33-PYTEST.pyc 0000644 0000144 0000144 00000026333 12414363411 027222 0 ustar prologic users 0000000 0000000
6Tf c @ s d d l Z d d l j j Z d d l Z d d l m Z d d l m Z m
Z
m Z d d l m
Z
m Z d d l m Z d d l m Z m Z m Z d d l m Z m Z m Z m Z m Z m Z m Z m Z m Z m Z m Z m Z m Z m! Z! m" Z" m# Z# d d l$ m% Z% Gd d
d
e Z&