├── .gitignore ├── .hgignore ├── LICENSE ├── MANIFEST.in ├── README ├── docs ├── CREDITS ├── Makefile ├── build │ └── html │ │ ├── .buildinfo │ │ ├── _images │ │ └── overview.png │ │ ├── _sources │ │ ├── channels.txt │ │ ├── configuration.txt │ │ ├── deployment.txt │ │ ├── index.txt │ │ ├── intro.txt │ │ ├── javascript.txt │ │ ├── json_rest.txt │ │ ├── tutorial.txt │ │ ├── web.txt │ │ └── webhooks.txt │ │ ├── _static │ │ ├── basic.css │ │ ├── default.css │ │ ├── docs.css │ │ ├── doctools.js │ │ ├── file.png │ │ ├── init.js │ │ ├── jquery.js │ │ ├── minus.png │ │ ├── plus.png │ │ ├── pygments.css │ │ ├── searchtools.js │ │ ├── sidebar.js │ │ └── underscore.js │ │ ├── channels.html │ │ ├── configuration.html │ │ ├── deployment.html │ │ ├── genindex.html │ │ ├── index.html │ │ ├── intro.html │ │ ├── javascript.html │ │ ├── json_rest.html │ │ ├── objects.inv │ │ ├── search.html │ │ ├── searchindex.js │ │ ├── tutorial.html │ │ ├── web.html │ │ └── webhooks.html ├── make.bat └── source │ ├── _static │ ├── docs.css │ └── init.js │ ├── _templates │ ├── genindex.mako │ ├── layout.mako │ ├── page.mako │ ├── search.mako │ ├── site_base.mako │ └── static_base.mako │ ├── builder │ ├── __init__.py │ ├── builders.py │ └── util.py │ ├── channels.rst │ ├── conf.py │ ├── configuration.rst │ ├── deployment.rst │ ├── diagrams │ ├── overview.graphml │ └── overview.png │ ├── index.rst │ ├── intro.rst │ ├── javascript.rst │ ├── json_rest.rst │ ├── tutorial.rst │ ├── web.rst │ └── webhooks.rst ├── examples ├── php_chat │ ├── Schema.sql │ ├── public_html │ │ ├── chat.css │ │ ├── connect.php │ │ ├── create_channel.php │ │ ├── database.inc │ │ ├── disconnect.php │ │ ├── index.html │ │ ├── login.php │ │ ├── publish.php │ │ ├── subscribe.php │ │ ├── test.php │ │ └── unsubscribe.php │ └── run_example.sh ├── php_graph │ ├── README │ └── graph.php ├── php_simple_chat │ ├── chat.php │ └── start ├── python_graphic_eq │ ├── README │ ├── index.html │ ├── producer.py │ └── webapp.py └── python_scope │ ├── README │ ├── index.html │ ├── producer.py │ ├── static │ └── jquery.flot.min.js │ └── webapp.py ├── hookbox ├── __init__.py ├── admin │ ├── __init__.py │ ├── admin.py │ ├── js_src │ │ ├── Makefile │ │ ├── admin.js │ │ └── admin.pkg │ └── static │ │ ├── admin.css │ │ ├── admin.js │ │ ├── admin2.js │ │ ├── highlighter.css │ │ ├── images │ │ ├── h1.png │ │ ├── h3.png │ │ └── logo.png │ │ ├── index.html │ │ └── lib │ │ ├── jqueryui │ │ ├── css │ │ │ └── overcast │ │ │ │ ├── images │ │ │ │ ├── ui-bg_flat_0_aaaaaa_40x100.png │ │ │ │ ├── ui-bg_flat_0_eeeeee_40x100.png │ │ │ │ ├── ui-bg_flat_55_c0402a_40x100.png │ │ │ │ ├── ui-bg_flat_55_eeeeee_40x100.png │ │ │ │ ├── ui-bg_glass_100_f8f8f8_1x400.png │ │ │ │ ├── ui-bg_glass_35_dddddd_1x400.png │ │ │ │ ├── ui-bg_glass_60_eeeeee_1x400.png │ │ │ │ ├── ui-bg_inset-hard_75_999999_1x100.png │ │ │ │ ├── ui-bg_inset-soft_50_c9c9c9_1x100.png │ │ │ │ ├── ui-icons_3383bb_256x240.png │ │ │ │ ├── ui-icons_454545_256x240.png │ │ │ │ ├── ui-icons_70b2e1_256x240.png │ │ │ │ ├── ui-icons_999999_256x240.png │ │ │ │ └── ui-icons_fbc856_256x240.png │ │ │ │ └── jquery-ui-1.8.custom.css │ │ └── js │ │ │ ├── jquery-1.4.2.min.js │ │ │ └── jquery-ui-1.8.custom.min.js │ │ └── oocss │ │ ├── content.css │ │ ├── grid │ │ ├── grids.css │ │ ├── grids_all.html │ │ ├── grids_debug.css │ │ └── grids_doc.html │ │ ├── libraries.css │ │ └── module │ │ ├── mod.css │ │ ├── mod_debug.css │ │ ├── mod_doc.html │ │ ├── mod_skins.css │ │ └── skin │ │ ├── about.png │ │ ├── author.png │ │ ├── even.png │ │ ├── even_borders.psd │ │ ├── even_lr.png │ │ ├── even_tb.png │ │ ├── excerpt.png │ │ ├── faq.png │ │ ├── gc.png │ │ ├── gc_header.png │ │ ├── gc_header2.png │ │ ├── glow.png │ │ ├── glow_7px.png │ │ ├── glow_test.png │ │ ├── glow_thin.png │ │ ├── grab.png │ │ ├── header.png │ │ ├── header_glossy.png │ │ ├── header_gradient_light.png │ │ ├── help.png │ │ ├── highlight.png │ │ ├── info.png │ │ ├── kakapo.png │ │ ├── me.png │ │ ├── noted.png │ │ ├── online.png │ │ ├── photo.png │ │ ├── round.png │ │ ├── simple_corners.png │ │ ├── simple_extended.png │ │ ├── store.png │ │ ├── talk.png │ │ ├── universe.png │ │ ├── universe_gray.png │ │ └── universe_login.png ├── api │ ├── __init__.py │ ├── internal.py │ └── web.py ├── channel.py ├── config.py ├── errors.py ├── js_src │ ├── Makefile │ ├── hookbox.js │ ├── hookbox.pkg │ ├── jsio-3.2 │ │ ├── base.js │ │ ├── index.js │ │ ├── jsio.js │ │ ├── lib │ │ │ ├── Enum.js │ │ │ ├── Hash.js │ │ │ └── PubSub.js │ │ ├── logging.js │ │ ├── net.js │ │ ├── net │ │ │ ├── buffer.js │ │ │ ├── csp │ │ │ │ ├── client.js │ │ │ │ └── transports.js │ │ │ ├── env.js │ │ │ ├── env │ │ │ │ ├── browser │ │ │ │ │ ├── csp.js │ │ │ │ │ ├── networkConsole.html │ │ │ │ │ ├── postmessage.js │ │ │ │ │ └── websocket.js │ │ │ │ └── node │ │ │ │ │ ├── csp.js │ │ │ │ │ ├── csp │ │ │ │ │ ├── proxy.js │ │ │ │ │ ├── server.js │ │ │ │ │ └── util.js │ │ │ │ │ └── tcp.js │ │ │ ├── errors.js │ │ │ ├── interfaces.js │ │ │ ├── later.js │ │ │ └── protocols │ │ │ │ ├── buffered.js │ │ │ │ ├── delimited.js │ │ │ │ ├── echo.js │ │ │ │ ├── mspp.js │ │ │ │ ├── rtjp.js │ │ │ │ └── stomp.js │ │ ├── std │ │ │ ├── JSON.js │ │ │ ├── base64.js │ │ │ ├── js.js │ │ │ ├── uri.js │ │ │ ├── utf8.js │ │ │ └── uuid.js │ │ └── util │ │ │ ├── browser.js │ │ │ ├── browser.js~ │ │ │ ├── browserdetect.js │ │ │ ├── sizzle.js │ │ │ ├── sprintf.js │ │ │ └── underscore.js │ └── test │ │ ├── Makefile │ │ ├── test.html │ │ └── test.js ├── log.py ├── output_wrapper.py ├── protocol.py ├── server.py ├── start.py ├── static │ ├── hookbox.js │ ├── hookbox.min.js │ ├── hookbox.min.js.gz │ ├── oldTest.html │ └── test.html ├── tests │ ├── __init__.py │ └── test_hookbox_config.py └── user.py ├── index.html ├── setup.cfg ├── setup.py └── web ├── docs ├── index.html └── sites.html /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | *.egg-info 3 | -------------------------------------------------------------------------------- /.hgignore: -------------------------------------------------------------------------------- 1 | ^bin/ 2 | ^include/ 3 | ^lib/ 4 | ^lib64 5 | \.pyc$ 6 | ~$ 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2010 Michael Carter 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | 21 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | recursive-include hookbox *.js 2 | recursive-include hookbox *.html 3 | recursive-include hookbox *.css 4 | recursive-include hookbox *.jpg 5 | recursive-include hookbox *.png 6 | recursive-include hookbox *.giff 7 | recursive-include hookbox/js_src * 8 | -------------------------------------------------------------------------------- /docs/CREDITS: -------------------------------------------------------------------------------- 1 | This documentation was adapted from the SQLALchemy documentation sources. 2 | 3 | Copyright (c) 2005, 2006, 2007, 2008, 2009, 2010 Michael Bayer and contributors. 4 | SQLAlchemy is a trademark of Michael Bayer. -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | PAPER = 8 | BUILDDIR = build 9 | 10 | # Internal variables. 11 | PAPEROPT_a4 = -D latex_paper_size=a4 12 | PAPEROPT_letter = -D latex_paper_size=letter 13 | ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source 14 | 15 | .PHONY: help clean html dirhtml pickle json htmlhelp qthelp latex changes linkcheck doctest 16 | 17 | help: 18 | @echo "Please use \`make ' where is one of" 19 | @echo " html to make standalone HTML files" 20 | @echo " dirhtml to make HTML files named index.html in directories" 21 | @echo " pickle to make pickle files" 22 | @echo " json to make JSON files" 23 | @echo " htmlhelp to make HTML files and a HTML help project" 24 | @echo " qthelp to make HTML files and a qthelp project" 25 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" 26 | @echo " changes to make an overview of all changed/added/deprecated items" 27 | @echo " linkcheck to check all external links for integrity" 28 | @echo " doctest to run all doctests embedded in the documentation (if enabled)" 29 | 30 | clean: 31 | -rm -rf $(BUILDDIR)/* 32 | 33 | html: 34 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html 35 | @echo 36 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." 37 | 38 | dirhtml: 39 | $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml 40 | @echo 41 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." 42 | 43 | pickle: 44 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle 45 | @echo 46 | @echo "Build finished; now you can process the pickle files." 47 | 48 | json: 49 | $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json 50 | @echo 51 | @echo "Build finished; now you can process the JSON files." 52 | 53 | htmlhelp: 54 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp 55 | @echo 56 | @echo "Build finished; now you can run HTML Help Workshop with the" \ 57 | ".hhp project file in $(BUILDDIR)/htmlhelp." 58 | 59 | qthelp: 60 | $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp 61 | @echo 62 | @echo "Build finished; now you can run "qcollectiongenerator" with the" \ 63 | ".qhcp project file in $(BUILDDIR)/qthelp, like this:" 64 | @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/hookbox.qhcp" 65 | @echo "To view the help file:" 66 | @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/hookbox.qhc" 67 | 68 | latex: 69 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 70 | @echo 71 | @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." 72 | @echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \ 73 | "run these through (pdf)latex." 74 | 75 | changes: 76 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes 77 | @echo 78 | @echo "The overview file is in $(BUILDDIR)/changes." 79 | 80 | linkcheck: 81 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck 82 | @echo 83 | @echo "Link check complete; look for any errors in the above output " \ 84 | "or in $(BUILDDIR)/linkcheck/output.txt." 85 | 86 | doctest: 87 | $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest 88 | @echo "Testing of doctests in the sources finished, look at the " \ 89 | "results in $(BUILDDIR)/doctest/output.txt." 90 | -------------------------------------------------------------------------------- /docs/build/html/.buildinfo: -------------------------------------------------------------------------------- 1 | # Sphinx build info version 1 2 | # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. 3 | config: ad647be28d7930f3b1720f27e84fae19 4 | tags: fbb0d17656682115ca4d033fb2f83ba1 5 | -------------------------------------------------------------------------------- /docs/build/html/_images/overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/play-co/hookbox/c0087632b8035a1bff5c8dc55a2b64ba44c2cfbb/docs/build/html/_images/overview.png -------------------------------------------------------------------------------- /docs/build/html/_sources/channels.txt: -------------------------------------------------------------------------------- 1 | .. _channels_toplevel: 2 | 3 | ======== 4 | Channels 5 | ======== 6 | 7 | Overview 8 | ======== 9 | 10 | Hookbox is built around the concept channels which can be used as an abstraction for routing real-time communication between browers and your web application. These channels have many options, making them suitable for a multitude of basic types of applications. You need to consider the features needed by the real-time portion of your application, and adjust the channel options appropriately. You can read about some :ref:`intro_common_patterns` to find a good starting point for your application. 11 | 12 | Ultimately, your web application has complete control over these channels. A user may perform three actions on a channel, subsribing, publishing, or unsubscribing. Whenever a user attempts to perform an action on a channel, Hookbox will make a :ref:`Webhook ` call back to your application to obtain permission for the action by that user, or simply to notify your web application that the action took place. 13 | 14 | The application may itself perform any of these actions on a channel by using the :ref:`REST API `; it may perform any action on behalf of any user, and it can even publish with arbitrary usernames. The application may additionally use the REST API to alter a channel's state or options at any time. 15 | 16 | Finally, the web application may sometimes perform actions on channels on behalf of a particular user when that user causes a webhook callback. For instance, a user might subscribe to the channel 'foo', which would result in a ``subscribe`` webhook to be issued. The web application may respond with the ``auto_subscribe`` directive in order to subscribe the user to another channel, such as 'bar'. 17 | 18 | You can think of channels as three parts: 19 | 20 | #) Unique name 21 | #) List of actively connected/subscribed users 22 | #) History/state 23 | 24 | And you can think of the operations you can perform on a channel in three categories: 25 | 26 | #) Putting data into a channel 27 | #) Getting data out of a channel 28 | #) Altering channel subscriptions 29 | 30 | 31 | 32 | 33 | 34 | Getting Data out of a Channel 35 | ============================= 36 | 37 | The most common way to get data out of a channel is to simply subscribe with the :ref:`Javascript API `. This method allows javascript code to attach a publish callback which will be invoked whenever a new message is published to the channel. 38 | 39 | Putting Data into Channels 40 | ============================= 41 | 42 | 43 | 44 | Channel Properties 45 | ============================= 46 | 47 | * ``history_size``: the maximum number of entries in the channel history. 48 | * ``history``: A list of events that have previously occurred on this channel. They may be Subscribe, Unsubscribe, or Publish events. 49 | * ``name``: The name of the channel. 50 | * ``presenceful``: A Boolean indicating whether presence information is shared with channel subscribers. 51 | * ``moderated``: If true, any action will cause a Webhook callback. 52 | * TODO: etc. 53 | 54 | -------------------------------------------------------------------------------- /docs/build/html/_sources/configuration.txt: -------------------------------------------------------------------------------- 1 | ============= 2 | Configuration 3 | ============= 4 | 5 | As of version 0.2, hookbox is completely configurable via command line options. While developing your application, you will want to create a startup script that contains all of the appropriate settings. 6 | 7 | A typical hookbox start command looks like this: 8 | 9 | .. sourcecode:: none 10 | 11 | # hookbox -a myadminpassword -r myapitoken -s mycallbacksecret 12 | 13 | Basic Options 14 | ============= 15 | 16 | Port (-p, --port) 17 | ----------------- 18 | The port hookbox binds to is specified by -p PORT or --port=PORT; the default is 8001. 19 | 20 | Interface (-i, --interface) 21 | --------------------------- 22 | The interface hookbox binds to is specified by -i INTERFACE or --interface=INTERFACE; the default is "0.0.0.0" 23 | 24 | Webhook Callback Options 25 | ======================== 26 | 27 | Callback Port (--cbport) 28 | ------------------------ 29 | The port of the web application which will handle webhook callbacks is specified by --cbport=PORT; the default is 80. 30 | 31 | Callback Hostname (--cbhost) 32 | ---------------------------- 33 | The hostname of the web application which will handle webhook callbacks is specified by --cbhost=HOSTNAME; the default is "localhost". 34 | 35 | Callback Path Prefix (--cbpath) 36 | ------------------------------- 37 | All callbacks will be prefixed with the value specified by --cbpath=PATH_PREFIX; the default is "/hookbox". 38 | 39 | Callback Secret Token (-s, --webhook-secret) 40 | -------------------------------------------- 41 | If a secret token is provided, all callbacks with include that token value as the form variable "secret"; this is useful for blocking unauthorized requests to the callback urls. The secret is specified by -s SECRET or --webhook-secret=SECRET; the default is null (no secret.) 42 | 43 | Extended Callback Options 44 | ========================= 45 | 46 | These options are typically left as default, except in cases where its helpful to point all callbacks at a single url, for instance a single PHP script. 47 | 48 | Connect Callback Path (--cb-connect) 49 | ------------------------------------ 50 | The subpath for the connect callback is specified by --cb-connect PATH; the default is "connect" 51 | 52 | 53 | Disconnect Callback Path (--cb-disconnect) 54 | ------------------------------------------ 55 | The subpath for the connect callback is specified by --cb-disconnect PATH; the default is "disconnect" 56 | 57 | 58 | Create Channel Callback Path (--cb-create_channel) 59 | -------------------------------------------------- 60 | The subpath for the create_channel callback is specified by --cb-create_channel PATH; the default is "create_channel" 61 | 62 | 63 | Destroy Channel Callback Path (--cb-destroy_channel) 64 | ---------------------------------------------------- 65 | The subpath for the destroy_channel callback is specified by --cb-destroy_channel PATH; the default is "destroy_channel" 66 | 67 | 68 | Subscribe Callback Path (--cb-subscribe) 69 | ---------------------------------------- 70 | The subpath for the subscribe callback is specified by --cb-subscribe PATH; the default is "subscribe" 71 | 72 | 73 | Unsubscribe Callback Path (--cb-unsubscribe) 74 | -------------------------------------------- 75 | The subpath for the unsubscribe callback is specified by --cb-unsubscribe PATH; the default is "unsubscribe" 76 | 77 | 78 | Publish Callback Path (--cb-publish) 79 | ------------------------------------ 80 | The subpath for the publish callback is specified by --cb-publish PATH; the default is "publish" 81 | 82 | Cookie Identifier (-c, --cookie-identifier) 83 | ------------------------------------------- 84 | Hookbox will include all user cookies in any user-triggered webhook callback. This option is purely an optimization that will cause hookbox to include only the cookie specified by -c COOKIE_NAME or --cookie-identifier COOKIE_NAME; the default is to include all cookies. 85 | 86 | API Options 87 | ============ 88 | 89 | API Secret (-r, --api-security-token) 90 | ------------------------------------- 91 | The external api interfaces are disabled by default and will only be enabled if an API secret is specified by -r SECRET or --api-security-token SECRET. The value specified must appear in the form as the value for the key "secret" when using the Web/HTTP Hookbox API. 92 | 93 | Admin Options 94 | ============= 95 | 96 | Admin Password (-a, --admin-password) 97 | ------------------------------------- 98 | 99 | Hookbox includes an admin console which can be found at the /admin relative url. (e.g. http://localhost:8001/admin) This console is disabled by default unless an admin password is specified by -a PASSWORD or --admin-password PASSWORD 100 | 101 | -------------------------------------------------------------------------------- /docs/build/html/_sources/deployment.txt: -------------------------------------------------------------------------------- 1 | ========== 2 | Deployment 3 | ========== 4 | 5 | -------------------------------------------------------------------------------- /docs/build/html/_sources/index.txt: -------------------------------------------------------------------------------- 1 | .. hookbox documentation master file, created by 2 | sphinx-quickstart on Tue Apr 27 06:40:43 2010. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Hookbox Documentation 7 | ===================== 8 | 9 | Contents: 10 | 11 | .. toctree:: 12 | :maxdepth: 2 13 | 14 | intro 15 | tutorial 16 | channels 17 | javascript 18 | webhooks 19 | web 20 | json_rest 21 | configuration 22 | deployment -------------------------------------------------------------------------------- /docs/build/html/_sources/json_rest.txt: -------------------------------------------------------------------------------- 1 | .. _rest_toplevel: 2 | 3 | =================== 4 | JSON Rest Interface 5 | =================== 6 | 7 | TODO 8 | 9 | -------------------------------------------------------------------------------- /docs/build/html/_sources/tutorial.txt: -------------------------------------------------------------------------------- 1 | Tutorial 2 | ======== 3 | 4 | -------------------------------------------------------------------------------- /docs/build/html/_sources/webhooks.txt: -------------------------------------------------------------------------------- 1 | .. _webhooks_toplevel: 2 | 3 | ================== 4 | Webhooks 5 | ================== 6 | 7 | message 8 | ======= 9 | 10 | Send a private message to a user. 11 | 12 | Webhook Form Variables: 13 | 14 | * ``sender``: The user name of the sending user. 15 | * ``recipient``: The user name of the receiving user. 16 | * ``recipient_exists``: True if the recipient name is that of a connected user, false otherwise. 17 | * ``payload``: The json payload to send to the receiving user. 18 | 19 | Webhook post includes sender cookies. 20 | 21 | Returns json: 22 | 23 | .. sourcecode:: javascript 24 | 25 | [ success (boolean) , details (object) ] 26 | 27 | 28 | Optional Webhook return details: 29 | 30 | * ``override_payload``: A new payload that will be sent instead of the original payload. 31 | * ``override_recipient_name``: The name of a user to send the message to instead of the original reciepient. 32 | 33 | 34 | Example: 35 | 36 | Client Calls: 37 | 38 | .. sourcecode:: javascript 39 | 40 | connection.message("mcarter", { title: "a message", body: "some text" }); 41 | 42 | 43 | Webhook Called With: 44 | 45 | .. sourcecode:: javascript 46 | 47 | { sender: "some_user", recipient: "mcarter", payload: { title: "a message", body: "some text" } } 48 | 49 | 50 | Webhook replies: 51 | 52 | .. sourcecode:: javascript 53 | 54 | [ true, { override_payload: { title: "a new title", body: "some text" } } ] 55 | 56 | 57 | And the following frame is published to the user 'mcarter': 58 | 59 | .. sourcecode:: javascript 60 | 61 | { sender: "some_user", recipient: "mcarter", "payload": { title: "a new title", body: "some text" } } 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /docs/build/html/_static/file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/play-co/hookbox/c0087632b8035a1bff5c8dc55a2b64ba44c2cfbb/docs/build/html/_static/file.png -------------------------------------------------------------------------------- /docs/build/html/_static/init.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function(){ 2 | $('div.popup_sql').hide(); 3 | $('a.sql_link').click(function() { 4 | $(this).nextAll('div.popup_sql:first').toggle(); 5 | return false; 6 | }) 7 | }); 8 | -------------------------------------------------------------------------------- /docs/build/html/_static/minus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/play-co/hookbox/c0087632b8035a1bff5c8dc55a2b64ba44c2cfbb/docs/build/html/_static/minus.png -------------------------------------------------------------------------------- /docs/build/html/_static/plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/play-co/hookbox/c0087632b8035a1bff5c8dc55a2b64ba44c2cfbb/docs/build/html/_static/plus.png -------------------------------------------------------------------------------- /docs/build/html/_static/pygments.css: -------------------------------------------------------------------------------- 1 | .hll { background-color: #ffffcc } 2 | .c { color: #408090; font-style: italic } /* Comment */ 3 | .err { border: 1px solid #FF0000 } /* Error */ 4 | .k { color: #007020; font-weight: bold } /* Keyword */ 5 | .o { color: #666666 } /* Operator */ 6 | .cm { color: #408090; font-style: italic } /* Comment.Multiline */ 7 | .cp { color: #007020 } /* Comment.Preproc */ 8 | .c1 { color: #408090; font-style: italic } /* Comment.Single */ 9 | .cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */ 10 | .gd { color: #A00000 } /* Generic.Deleted */ 11 | .ge { font-style: italic } /* Generic.Emph */ 12 | .gr { color: #FF0000 } /* Generic.Error */ 13 | .gh { color: #000080; font-weight: bold } /* Generic.Heading */ 14 | .gi { color: #00A000 } /* Generic.Inserted */ 15 | .go { color: #303030 } /* Generic.Output */ 16 | .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */ 17 | .gs { font-weight: bold } /* Generic.Strong */ 18 | .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ 19 | .gt { color: #0040D0 } /* Generic.Traceback */ 20 | .kc { color: #007020; font-weight: bold } /* Keyword.Constant */ 21 | .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */ 22 | .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */ 23 | .kp { color: #007020 } /* Keyword.Pseudo */ 24 | .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */ 25 | .kt { color: #902000 } /* Keyword.Type */ 26 | .m { color: #208050 } /* Literal.Number */ 27 | .s { color: #4070a0 } /* Literal.String */ 28 | .na { color: #4070a0 } /* Name.Attribute */ 29 | .nb { color: #007020 } /* Name.Builtin */ 30 | .nc { color: #0e84b5; font-weight: bold } /* Name.Class */ 31 | .no { color: #60add5 } /* Name.Constant */ 32 | .nd { color: #555555; font-weight: bold } /* Name.Decorator */ 33 | .ni { color: #d55537; font-weight: bold } /* Name.Entity */ 34 | .ne { color: #007020 } /* Name.Exception */ 35 | .nf { color: #06287e } /* Name.Function */ 36 | .nl { color: #002070; font-weight: bold } /* Name.Label */ 37 | .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */ 38 | .nt { color: #062873; font-weight: bold } /* Name.Tag */ 39 | .nv { color: #bb60d5 } /* Name.Variable */ 40 | .ow { color: #007020; font-weight: bold } /* Operator.Word */ 41 | .w { color: #bbbbbb } /* Text.Whitespace */ 42 | .mf { color: #208050 } /* Literal.Number.Float */ 43 | .mh { color: #208050 } /* Literal.Number.Hex */ 44 | .mi { color: #208050 } /* Literal.Number.Integer */ 45 | .mo { color: #208050 } /* Literal.Number.Oct */ 46 | .sb { color: #4070a0 } /* Literal.String.Backtick */ 47 | .sc { color: #4070a0 } /* Literal.String.Char */ 48 | .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */ 49 | .s2 { color: #4070a0 } /* Literal.String.Double */ 50 | .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */ 51 | .sh { color: #4070a0 } /* Literal.String.Heredoc */ 52 | .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */ 53 | .sx { color: #c65d09 } /* Literal.String.Other */ 54 | .sr { color: #235388 } /* Literal.String.Regex */ 55 | .s1 { color: #4070a0 } /* Literal.String.Single */ 56 | .ss { color: #517918 } /* Literal.String.Symbol */ 57 | .bp { color: #007020 } /* Name.Builtin.Pseudo */ 58 | .vc { color: #bb60d5 } /* Name.Variable.Class */ 59 | .vg { color: #bb60d5 } /* Name.Variable.Global */ 60 | .vi { color: #bb60d5 } /* Name.Variable.Instance */ 61 | .il { color: #208050 } /* Literal.Number.Integer.Long */ -------------------------------------------------------------------------------- /docs/build/html/_static/sidebar.js: -------------------------------------------------------------------------------- 1 | /* 2 | * sidebar.js 3 | * ~~~~~~~~~~ 4 | * 5 | * This script makes the Sphinx sidebar collapsible. 6 | * 7 | * .sphinxsidebar contains .sphinxsidebarwrapper. This script adds 8 | * in .sphixsidebar, after .sphinxsidebarwrapper, the #sidebarbutton 9 | * used to collapse and expand the sidebar. 10 | * 11 | * When the sidebar is collapsed the .sphinxsidebarwrapper is hidden 12 | * and the width of the sidebar and the margin-left of the document 13 | * are decreased. When the sidebar is expanded the opposite happens. 14 | * This script saves a per-browser/per-session cookie used to 15 | * remember the position of the sidebar among the pages. 16 | * Once the browser is closed the cookie is deleted and the position 17 | * reset to the default (expanded). 18 | * 19 | * :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. 20 | * :license: BSD, see LICENSE for details. 21 | * 22 | */ 23 | 24 | $(function() { 25 | // global elements used by the functions. 26 | // the 'sidebarbutton' element is defined as global after its 27 | // creation, in the add_sidebar_button function 28 | var bodywrapper = $('.bodywrapper'); 29 | var sidebar = $('.sphinxsidebar'); 30 | var sidebarwrapper = $('.sphinxsidebarwrapper'); 31 | 32 | // original margin-left of the bodywrapper and width of the sidebar 33 | // with the sidebar expanded 34 | var bw_margin_expanded = bodywrapper.css('margin-left'); 35 | var ssb_width_expanded = sidebar.width(); 36 | 37 | // margin-left of the bodywrapper and width of the sidebar 38 | // with the sidebar collapsed 39 | var bw_margin_collapsed = '.8em'; 40 | var ssb_width_collapsed = '.8em'; 41 | 42 | // colors used by the current theme 43 | var dark_color = $('.related').css('background-color'); 44 | var light_color = $('.document').css('background-color'); 45 | 46 | function sidebar_is_collapsed() { 47 | return sidebarwrapper.is(':not(:visible)'); 48 | } 49 | 50 | function toggle_sidebar() { 51 | if (sidebar_is_collapsed()) 52 | expand_sidebar(); 53 | else 54 | collapse_sidebar(); 55 | } 56 | 57 | function collapse_sidebar() { 58 | sidebarwrapper.hide(); 59 | sidebar.css('width', ssb_width_collapsed); 60 | bodywrapper.css('margin-left', bw_margin_collapsed); 61 | sidebarbutton.css({ 62 | 'margin-left': '0', 63 | 'height': bodywrapper.height() 64 | }); 65 | sidebarbutton.find('span').text('»'); 66 | sidebarbutton.attr('title', _('Expand sidebar')); 67 | document.cookie = 'sidebar=collapsed'; 68 | } 69 | 70 | function expand_sidebar() { 71 | bodywrapper.css('margin-left', bw_margin_expanded); 72 | sidebar.css('width', ssb_width_expanded); 73 | sidebarwrapper.show(); 74 | sidebarbutton.css({ 75 | 'margin-left': ssb_width_expanded-12, 76 | 'height': bodywrapper.height() 77 | }); 78 | sidebarbutton.find('span').text('«'); 79 | sidebarbutton.attr('title', _('Collapse sidebar')); 80 | document.cookie = 'sidebar=expanded'; 81 | } 82 | 83 | function add_sidebar_button() { 84 | sidebarwrapper.css({ 85 | 'float': 'left', 86 | 'margin-right': '0', 87 | 'width': ssb_width_expanded - 28 88 | }); 89 | // create the button 90 | sidebar.append( 91 | '
«
' 92 | ); 93 | var sidebarbutton = $('#sidebarbutton'); 94 | // find the height of the viewport to center the '<<' in the page 95 | var viewport_height; 96 | if (window.innerHeight) 97 | viewport_height = window.innerHeight; 98 | else 99 | viewport_height = $(window).height(); 100 | sidebarbutton.find('span').css({ 101 | 'display': 'block', 102 | 'margin-top': (viewport_height - sidebar.position().top - 20) / 2 103 | }); 104 | 105 | sidebarbutton.click(toggle_sidebar); 106 | sidebarbutton.attr('title', _('Collapse sidebar')); 107 | sidebarbutton.css({ 108 | 'color': '#FFFFFF', 109 | 'border-left': '1px solid ' + dark_color, 110 | 'font-size': '1.2em', 111 | 'cursor': 'pointer', 112 | 'height': bodywrapper.height(), 113 | 'padding-top': '1px', 114 | 'margin-left': ssb_width_expanded - 12 115 | }); 116 | 117 | sidebarbutton.hover( 118 | function () { 119 | $(this).css('background-color', dark_color); 120 | }, 121 | function () { 122 | $(this).css('background-color', light_color); 123 | } 124 | ); 125 | } 126 | 127 | function set_position_from_cookie() { 128 | if (!document.cookie) 129 | return; 130 | var items = document.cookie.split(';'); 131 | for(var k=0; k 3 | 4 | 5 | 6 | 7 | 8 | 9 | Deployment 10 | — hookbox v0.2.0 documentation 11 | 12 | 13 | 14 | 15 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 |

hookbox v0.2.0 documentation

40 | 41 | 49 | 50 |
51 | Version: 0.2.0 Last Updated: None 52 |
53 |
54 | 55 |
56 |
57 | API Reference 58 | | 59 | Index 60 | 61 | 62 |
63 | 64 | 82 |
83 |
84 | 85 |
86 |
87 | 88 |
89 |

Deployment

90 |
91 | 92 |
93 |
94 | 95 | 96 | 97 |
98 | 99 |
100 | Previous: 101 | Configuration 102 |
103 | 104 | 108 |
109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | -------------------------------------------------------------------------------- /docs/build/html/genindex.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | Index — hookbox v0.2.0 documentation 9 | 10 | 11 | 12 | 13 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 |

hookbox v0.2.0 documentation

37 | 38 | 46 | 47 |
48 | Version: 0.2.0 Last Updated: None 49 |
50 |
51 | 52 |
53 |
54 | API Reference 55 | | 56 | Index 57 | 58 |
59 | 60 | 72 |
73 |
74 | 75 |
76 |
77 | 78 | 79 | 80 | 81 |

Index

82 | 83 | 84 |
85 | 86 | 87 | 88 | 89 |
90 |
91 | 92 | 93 | 94 |
95 | 96 |
97 |
98 | 99 | 103 |
104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /docs/build/html/json_rest.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | JSON Rest Interface 10 | — hookbox v0.2.0 documentation 11 | 12 | 13 | 14 | 15 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 |

hookbox v0.2.0 documentation

41 | 42 | 50 | 51 |
52 | Version: 0.2.0 Last Updated: None 53 |
54 |
55 | 56 |
57 |
58 | API Reference 59 | | 60 | Index 61 | 62 | 63 |
64 | 65 | 85 |
86 |
87 | 88 |
89 |
90 | 91 |
92 |

JSON Rest Interface

93 |

TODO

94 |
95 | 96 |
97 |
98 | 99 | 100 | 101 |
102 | 103 |
104 | Previous: 105 | Web/HTTP Interface 106 | Next: 107 | Configuration 108 |
109 | 110 | 114 |
115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | -------------------------------------------------------------------------------- /docs/build/html/objects.inv: -------------------------------------------------------------------------------- 1 | # Sphinx inventory version 1 2 | # Project: hookbox 3 | # Version: 0.2 4 | -------------------------------------------------------------------------------- /docs/build/html/search.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | Search — hookbox v0.2.0 documentation 9 | 10 | 11 | 12 | 13 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 |

hookbox v0.2.0 documentation

38 | 39 | 47 | 48 |
49 | Version: 0.2.0 Last Updated: None 50 |
51 |
52 | 53 |
54 |
55 | API Reference 56 | | 57 | Index 58 | 59 |
60 | 61 | 73 |
74 |
75 | 76 |
77 |
78 | 79 | 80 | 81 | 82 | 83 |
84 |

Enter Search Terms:

85 | 90 |
91 | 92 |
93 | 94 | 95 | 96 |
97 |
98 | 99 | 100 | 101 | 102 |
103 | 104 |
105 |
106 | 107 | 111 |
112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | -------------------------------------------------------------------------------- /docs/build/html/tutorial.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Tutorial 10 | — hookbox v0.2.0 documentation 11 | 12 | 13 | 14 | 15 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 |

hookbox v0.2.0 documentation

41 | 42 | 50 | 51 |
52 | Version: 0.2.0 Last Updated: None 53 |
54 |
55 | 56 |
57 |
58 | API Reference 59 | | 60 | Index 61 | 62 | 63 |
64 | 65 | 85 |
86 |
87 | 88 |
89 |
90 | 91 |
92 |

Tutorial

93 |
94 | 95 |
96 |
97 | 98 | 99 | 100 |
101 | 102 |
103 | Previous: 104 | Introduction 105 | Next: 106 | Channels 107 |
108 | 109 | 113 |
114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | -------------------------------------------------------------------------------- /docs/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | REM Command file for Sphinx documentation 4 | 5 | set SPHINXBUILD=sphinx-build 6 | set BUILDDIR=build 7 | set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% source 8 | if NOT "%PAPER%" == "" ( 9 | set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% 10 | ) 11 | 12 | if "%1" == "" goto help 13 | 14 | if "%1" == "help" ( 15 | :help 16 | echo.Please use `make ^` where ^ is one of 17 | echo. html to make standalone HTML files 18 | echo. dirhtml to make HTML files named index.html in directories 19 | echo. pickle to make pickle files 20 | echo. json to make JSON files 21 | echo. htmlhelp to make HTML files and a HTML help project 22 | echo. qthelp to make HTML files and a qthelp project 23 | echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter 24 | echo. changes to make an overview over all changed/added/deprecated items 25 | echo. linkcheck to check all external links for integrity 26 | echo. doctest to run all doctests embedded in the documentation if enabled 27 | goto end 28 | ) 29 | 30 | if "%1" == "clean" ( 31 | for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i 32 | del /q /s %BUILDDIR%\* 33 | goto end 34 | ) 35 | 36 | if "%1" == "html" ( 37 | %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html 38 | echo. 39 | echo.Build finished. The HTML pages are in %BUILDDIR%/html. 40 | goto end 41 | ) 42 | 43 | if "%1" == "dirhtml" ( 44 | %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml 45 | echo. 46 | echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. 47 | goto end 48 | ) 49 | 50 | if "%1" == "pickle" ( 51 | %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle 52 | echo. 53 | echo.Build finished; now you can process the pickle files. 54 | goto end 55 | ) 56 | 57 | if "%1" == "json" ( 58 | %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json 59 | echo. 60 | echo.Build finished; now you can process the JSON files. 61 | goto end 62 | ) 63 | 64 | if "%1" == "htmlhelp" ( 65 | %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp 66 | echo. 67 | echo.Build finished; now you can run HTML Help Workshop with the ^ 68 | .hhp project file in %BUILDDIR%/htmlhelp. 69 | goto end 70 | ) 71 | 72 | if "%1" == "qthelp" ( 73 | %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp 74 | echo. 75 | echo.Build finished; now you can run "qcollectiongenerator" with the ^ 76 | .qhcp project file in %BUILDDIR%/qthelp, like this: 77 | echo.^> qcollectiongenerator %BUILDDIR%\qthelp\hookbox.qhcp 78 | echo.To view the help file: 79 | echo.^> assistant -collectionFile %BUILDDIR%\qthelp\hookbox.ghc 80 | goto end 81 | ) 82 | 83 | if "%1" == "latex" ( 84 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex 85 | echo. 86 | echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. 87 | goto end 88 | ) 89 | 90 | if "%1" == "changes" ( 91 | %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes 92 | echo. 93 | echo.The overview file is in %BUILDDIR%/changes. 94 | goto end 95 | ) 96 | 97 | if "%1" == "linkcheck" ( 98 | %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck 99 | echo. 100 | echo.Link check complete; look for any errors in the above output ^ 101 | or in %BUILDDIR%/linkcheck/output.txt. 102 | goto end 103 | ) 104 | 105 | if "%1" == "doctest" ( 106 | %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest 107 | echo. 108 | echo.Testing of doctests in the sources finished, look at the ^ 109 | results in %BUILDDIR%/doctest/output.txt. 110 | goto end 111 | ) 112 | 113 | :end 114 | -------------------------------------------------------------------------------- /docs/source/_static/init.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function(){ 2 | $('div.popup_sql').hide(); 3 | $('a.sql_link').click(function() { 4 | $(this).nextAll('div.popup_sql:first').toggle(); 5 | return false; 6 | }) 7 | }); 8 | -------------------------------------------------------------------------------- /docs/source/_templates/genindex.mako: -------------------------------------------------------------------------------- 1 | <%inherit file="layout.mako"/> 2 | 3 | <%def name="show_title()">${_('Index')} 4 | 5 |

${_('Index')}

6 | 7 | % for i, (key, dummy) in enumerate(genindexentries): 8 | ${i != 0 and '| ' or ''}${key} 9 | % endfor 10 | 11 |
12 | 13 | % for i, (key, entries) in enumerate(genindexentries): 14 |

${key}

15 |
16 |
17 | <% 18 | breakat = genindexcounts[i] // 2 19 | numcols = 1 20 | numitems = 0 21 | %> 22 | % for entryname, (links, subitems) in entries: 23 | 24 |
25 | % if links: 26 | ${entryname|h} 27 | % for link in links[1:]: 28 | , [${i}] 29 | % endfor 30 | % else: 31 | ${entryname|h} 32 | % endif 33 | 34 | % if subitems: 35 |
36 | % for subentryname, subentrylinks in subitems: 37 |
${subentryname|h} 38 | % for j, link in enumerate(subentrylinks[1:]): 39 | [${j}] 40 | % endfor 41 |
42 | % endfor 43 |
44 | % endif 45 | <% 46 | numitems = numitems + 1 + len(subitems) 47 | %> 48 | % if numcols <2 and numitems > breakat: 49 | <% 50 | numcols = numcols + 1 51 | %> 52 |
53 | % endif 54 | 55 | % endfor 56 |
57 | % endfor 58 | 59 | <%def name="sidebarrel()"> 60 | % if split_index: 61 |

${_('Index')}

62 |

63 | % for i, (key, dummy) in enumerate(genindexentries): 64 | ${i > 0 and '| ' or ''} 65 | ${key} 66 | % endfor 67 |

68 | 69 |

${_('Full index on one page')}

70 | % endif 71 | ${parent.sidebarrel()} 72 | 73 | -------------------------------------------------------------------------------- /docs/source/_templates/page.mako: -------------------------------------------------------------------------------- 1 | <%inherit file="layout.mako"/> 2 | ${body| util.strip_toplevel_anchors} -------------------------------------------------------------------------------- /docs/source/_templates/search.mako: -------------------------------------------------------------------------------- 1 | <%inherit file="layout.mako"/> 2 | 3 | <%! 4 | local_script_files = ['_static/searchtools.js'] 5 | %> 6 | <%def name="show_title()">${_('Search')} 7 | 8 |
9 |

Enter Search Terms:

10 | 15 |
16 | 17 |
18 | 19 | <%def name="footer()"> 20 | ${parent.footer()} 21 | 22 | 23 | -------------------------------------------------------------------------------- /docs/source/_templates/site_base.mako: -------------------------------------------------------------------------------- 1 | <%text>#coding:utf-8 2 | <%inherit file="/base.html"/> 3 | <%page cache_type="file" cached="True"/> 4 | <%! 5 | in_docs=True 6 | %> 7 | 8 | 9 |
10 | Quick Select: 0.6 | 0.5 | 0.4
11 | PDF Download: download 12 |
13 | 14 | ${'<%text>'} 15 | ${next.body()} 16 | ${''} 17 | 18 | <%text><%def name="style()"> 19 | ${self.headers()} 20 | <%text>${parent.style()} 21 | 22 | <%text> 23 | 24 | <%text><%def name="title()">${capture(self.show_title)|util.striptags} — ${docstitle|h}<%text> 25 | 26 | <%! 27 | local_script_files = [] 28 | %> 29 | -------------------------------------------------------------------------------- /docs/source/_templates/static_base.mako: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | ${metatags and metatags or ''} 8 | ${capture(self.show_title)|util.striptags} — ${docstitle|h} 9 | ${self.headers()} 10 | 11 | 12 | ${next.body()} 13 | 14 | 15 | 16 | 17 | <%! 18 | local_script_files = [] 19 | %> 20 | -------------------------------------------------------------------------------- /docs/source/builder/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/play-co/hookbox/c0087632b8035a1bff5c8dc55a2b64ba44c2cfbb/docs/source/builder/__init__.py -------------------------------------------------------------------------------- /docs/source/builder/util.py: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | def striptags(text): 4 | return re.compile(r'<[^>]*>').sub('', text) 5 | 6 | def strip_toplevel_anchors(text): 7 | return re.compile(r'\.html#\w+-toplevel').sub('.html', text) 8 | 9 | -------------------------------------------------------------------------------- /docs/source/channels.rst: -------------------------------------------------------------------------------- 1 | .. _channels_toplevel: 2 | 3 | ======== 4 | Channels 5 | ======== 6 | 7 | Overview 8 | ======== 9 | 10 | Hookbox is built around the concept channels which can be used as an abstraction for routing real-time communication between browers and your web application. These channels have many options, making them suitable for a multitude of basic types of applications. You need to consider the features needed by the real-time portion of your application, and adjust the channel options appropriately. You can read about some :ref:`intro_common_patterns` to find a good starting point for your application. 11 | 12 | Ultimately, your web application has complete control over these channels. A user may perform three actions on a channel, subsribing, publishing, or unsubscribing. Whenever a user attempts to perform an action on a channel, Hookbox will make a :ref:`Webhook ` call back to your application to obtain permission for the action by that user, or simply to notify your web application that the action took place. 13 | 14 | The application may itself perform any of these actions on a channel by using the :ref:`REST API `; it may perform any action on behalf of any user, and it can even publish with arbitrary usernames. The application may additionally use the REST API to alter a channel's state or options at any time. 15 | 16 | Finally, the web application may sometimes perform actions on channels on behalf of a particular user when that user causes a webhook callback. For instance, a user might subscribe to the channel 'foo', which would result in a ``subscribe`` webhook to be issued. The web application may respond with the ``auto_subscribe`` directive in order to subscribe the user to another channel, such as 'bar'. 17 | 18 | You can think of channels as three parts: 19 | 20 | #) Unique name 21 | #) List of actively connected/subscribed users 22 | #) History/state 23 | 24 | And you can think of the operations you can perform on a channel in three categories: 25 | 26 | #) Putting data into a channel 27 | #) Getting data out of a channel 28 | #) Altering channel subscriptions 29 | 30 | 31 | 32 | 33 | 34 | Getting Data out of a Channel 35 | ============================= 36 | 37 | The most common way to get data out of a channel is to simply subscribe with the :ref:`Javascript API `. This method allows javascript code to attach a publish callback which will be invoked whenever a new message is published to the channel. 38 | 39 | Putting Data into Channels 40 | ============================= 41 | 42 | 43 | 44 | Channel Properties 45 | ============================= 46 | 47 | * ``history_size``: the maximum number of entries in the channel history. 48 | * ``history``: A list of events that have previously occurred on this channel. They may be Subscribe, Unsubscribe, or Publish events. 49 | * ``name``: The name of the channel. 50 | * ``presenceful``: A Boolean indicating whether presence information is shared with channel subscribers. 51 | * ``moderated``: If true, any action will cause a Webhook callback. 52 | * TODO: etc. 53 | 54 | -------------------------------------------------------------------------------- /docs/source/configuration.rst: -------------------------------------------------------------------------------- 1 | ============= 2 | Configuration 3 | ============= 4 | 5 | As of version 0.2, hookbox is completely configurable via command line options. While developing your application, you will want to create a startup script that contains all of the appropriate settings. 6 | 7 | A typical hookbox start command looks like this: 8 | 9 | .. sourcecode:: none 10 | 11 | # hookbox -a myadminpassword -r myapitoken -s mycallbacksecret 12 | 13 | Basic Options 14 | ============= 15 | 16 | Port (-p, --port) 17 | ----------------- 18 | The port hookbox binds to is specified by -p PORT or --port=PORT; the default is 8001. 19 | 20 | Interface (-i, --interface) 21 | --------------------------- 22 | The interface hookbox binds to is specified by -i INTERFACE or --interface=INTERFACE; the default is "0.0.0.0" 23 | 24 | Webhook Callback Options 25 | ======================== 26 | 27 | Callback Port (--cbport) 28 | ------------------------ 29 | The port of the web application which will handle webhook callbacks is specified by --cbport=PORT; the default is 80. 30 | 31 | Callback Hostname (--cbhost) 32 | ---------------------------- 33 | The hostname of the web application which will handle webhook callbacks is specified by --cbhost=HOSTNAME; the default is "localhost". 34 | 35 | Callback Path Prefix (--cbpath) 36 | ------------------------------- 37 | All callbacks will be prefixed with the value specified by --cbpath=PATH_PREFIX; the default is "/hookbox". 38 | 39 | Callback Secret Token (-s, --webhook-secret) 40 | -------------------------------------------- 41 | If a secret token is provided, all callbacks with include that token value as the form variable "secret"; this is useful for blocking unauthorized requests to the callback urls. The secret is specified by -s SECRET or --webhook-secret=SECRET; the default is null (no secret.) 42 | 43 | Extended Callback Options 44 | ========================= 45 | 46 | These options are typically left as default, except in cases where its helpful to point all callbacks at a single url, for instance a single PHP script. 47 | 48 | Connect Callback Path (--cb-connect) 49 | ------------------------------------ 50 | The subpath for the connect callback is specified by --cb-connect PATH; the default is "connect" 51 | 52 | 53 | Disconnect Callback Path (--cb-disconnect) 54 | ------------------------------------------ 55 | The subpath for the connect callback is specified by --cb-disconnect PATH; the default is "disconnect" 56 | 57 | 58 | Create Channel Callback Path (--cb-create_channel) 59 | -------------------------------------------------- 60 | The subpath for the create_channel callback is specified by --cb-create_channel PATH; the default is "create_channel" 61 | 62 | 63 | Destroy Channel Callback Path (--cb-destroy_channel) 64 | ---------------------------------------------------- 65 | The subpath for the destroy_channel callback is specified by --cb-destroy_channel PATH; the default is "destroy_channel" 66 | 67 | 68 | Subscribe Callback Path (--cb-subscribe) 69 | ---------------------------------------- 70 | The subpath for the subscribe callback is specified by --cb-subscribe PATH; the default is "subscribe" 71 | 72 | 73 | Unsubscribe Callback Path (--cb-unsubscribe) 74 | -------------------------------------------- 75 | The subpath for the unsubscribe callback is specified by --cb-unsubscribe PATH; the default is "unsubscribe" 76 | 77 | 78 | Publish Callback Path (--cb-publish) 79 | ------------------------------------ 80 | The subpath for the publish callback is specified by --cb-publish PATH; the default is "publish" 81 | 82 | Cookie Identifier (-c, --cookie-identifier) 83 | ------------------------------------------- 84 | Hookbox will include all user cookies in any user-triggered webhook callback. This option is purely an optimization that will cause hookbox to include only the cookie specified by -c COOKIE_NAME or --cookie-identifier COOKIE_NAME; the default is to include all cookies. 85 | 86 | API Options 87 | ============ 88 | 89 | API Secret (-r, --api-security-token) 90 | ------------------------------------- 91 | The external api interfaces are disabled by default and will only be enabled if an API secret is specified by -r SECRET or --api-security-token SECRET. The value specified must appear in the form as the value for the key "secret" when using the Web/HTTP Hookbox API. 92 | 93 | Admin Options 94 | ============= 95 | 96 | Admin Password (-a, --admin-password) 97 | ------------------------------------- 98 | 99 | Hookbox includes an admin console which can be found at the /admin relative url. (e.g. http://localhost:8001/admin) This console is disabled by default unless an admin password is specified by -a PASSWORD or --admin-password PASSWORD 100 | 101 | -------------------------------------------------------------------------------- /docs/source/deployment.rst: -------------------------------------------------------------------------------- 1 | ========== 2 | Deployment 3 | ========== 4 | 5 | -------------------------------------------------------------------------------- /docs/source/diagrams/overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/play-co/hookbox/c0087632b8035a1bff5c8dc55a2b64ba44c2cfbb/docs/source/diagrams/overview.png -------------------------------------------------------------------------------- /docs/source/index.rst: -------------------------------------------------------------------------------- 1 | .. hookbox documentation master file, created by 2 | sphinx-quickstart on Tue Apr 27 06:40:43 2010. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Hookbox Documentation 7 | ===================== 8 | 9 | Contents: 10 | 11 | .. toctree:: 12 | :maxdepth: 2 13 | 14 | intro 15 | tutorial 16 | channels 17 | javascript 18 | webhooks 19 | web 20 | json_rest 21 | configuration 22 | deployment -------------------------------------------------------------------------------- /docs/source/json_rest.rst: -------------------------------------------------------------------------------- 1 | .. _rest_toplevel: 2 | 3 | =================== 4 | JSON Rest Interface 5 | =================== 6 | 7 | TODO 8 | 9 | -------------------------------------------------------------------------------- /docs/source/tutorial.rst: -------------------------------------------------------------------------------- 1 | Tutorial 2 | ======== 3 | 4 | -------------------------------------------------------------------------------- /docs/source/webhooks.rst: -------------------------------------------------------------------------------- 1 | .. _webhooks_toplevel: 2 | 3 | ================== 4 | Webhooks 5 | ================== 6 | 7 | message 8 | ======= 9 | 10 | Send a private message to a user. 11 | 12 | Webhook Form Variables: 13 | 14 | * ``sender``: The user name of the sending user. 15 | * ``recipient``: The user name of the receiving user. 16 | * ``recipient_exists``: True if the recipient name is that of a connected user, false otherwise. 17 | * ``payload``: The json payload to send to the receiving user. 18 | 19 | Webhook post includes sender cookies. 20 | 21 | Returns json: 22 | 23 | .. sourcecode:: javascript 24 | 25 | [ success (boolean) , details (object) ] 26 | 27 | 28 | Optional Webhook return details: 29 | 30 | * ``override_payload``: A new payload that will be sent instead of the original payload. 31 | * ``override_recipient_name``: The name of a user to send the message to instead of the original reciepient. 32 | 33 | 34 | Example: 35 | 36 | Client Calls: 37 | 38 | .. sourcecode:: javascript 39 | 40 | connection.message("mcarter", { title: "a message", body: "some text" }); 41 | 42 | 43 | Webhook Called With: 44 | 45 | .. sourcecode:: javascript 46 | 47 | { sender: "some_user", recipient: "mcarter", payload: { title: "a message", body: "some text" } } 48 | 49 | 50 | Webhook replies: 51 | 52 | .. sourcecode:: javascript 53 | 54 | [ true, { override_payload: { title: "a new title", body: "some text" } } ] 55 | 56 | 57 | And the following frame is published to the user 'mcarter': 58 | 59 | .. sourcecode:: javascript 60 | 61 | { sender: "some_user", recipient: "mcarter", "payload": { title: "a new title", body: "some text" } } 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /examples/php_chat/Schema.sql: -------------------------------------------------------------------------------- 1 | DROP TABLE IF EXISTS logs; 2 | DROP TABLE IF EXISTS users; 3 | DROP TABLE IF EXISTS channels; 4 | 5 | CREATE TABLE users ( 6 | id int(11) not null auto_increment, 7 | username varchar(100) not null, 8 | 9 | unique key (username), 10 | primary key (id) 11 | ) engine=InnoDB default charset=utf8; 12 | 13 | CREATE TABLE channels ( 14 | id int(11) not null auto_increment, 15 | channel_name varchar(100) not null, 16 | 17 | unique key (channel_name), 18 | primary key (id) 19 | ) engine=InnoDB default charset=utf8; 20 | 21 | CREATE TABLE logs ( 22 | id int(11) not null auto_increment, 23 | channel_name varchar(100) not null, 24 | username varchar(100) not null, 25 | payload text not null, 26 | 27 | primary key (id), 28 | foreign key (channel_name) references channels(channel_name) 29 | on delete cascade 30 | on update cascade, 31 | foreign key (username) references users(username) 32 | on delete cascade 33 | on update cascade 34 | ) engine=InnoDB default charset=utf8; 35 | 36 | INSERT INTO channels VALUES (NULL, 'testing'); -------------------------------------------------------------------------------- /examples/php_chat/public_html/chat.css: -------------------------------------------------------------------------------- 1 | html, body { margin: 0px; padding: 0px; } 2 | 3 | body, div, td { font: 11px Helvetica, Arial, sans-serif; } 4 | 5 | .inset { 6 | border: 1px solid #DDD; 7 | -moz-border-radius: 3px; 8 | -webkit-border-radius: 3px; 9 | border-radius: 3px; 10 | } 11 | 12 | h1 { margin: 0px 0px 10px 0px; } 13 | 14 | #wrapper { 15 | margin: 20px auto; 16 | padding: 10px; 17 | background: #F6F5F4; 18 | width: 350px; 19 | } 20 | 21 | #history { 22 | padding: 5px; 23 | background: #FFF; 24 | height: 200px; 25 | width: 338px; 26 | overflow-y: scroll; 27 | } 28 | 29 | #chat_input { 30 | width: 260px; 31 | margin-top: 10px; 32 | margin-right: 10px; 33 | } 34 | 35 | #chat_send { 36 | width: 60px; 37 | } -------------------------------------------------------------------------------- /examples/php_chat/public_html/connect.php: -------------------------------------------------------------------------------- 1 | 15 | -------------------------------------------------------------------------------- /examples/php_chat/public_html/create_channel.php: -------------------------------------------------------------------------------- 1 | 27 | -------------------------------------------------------------------------------- /examples/php_chat/public_html/database.inc: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/php_chat/public_html/disconnect.php: -------------------------------------------------------------------------------- 1 | [true,{}] 2 | -------------------------------------------------------------------------------- /examples/php_chat/public_html/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | PHP Chat Demo 4 | 5 | 6 |
7 | Username: 8 | 9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /examples/php_chat/public_html/login.php: -------------------------------------------------------------------------------- 1 | 15 | -------------------------------------------------------------------------------- /examples/php_chat/public_html/publish.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/php_chat/public_html/subscribe.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/php_chat/public_html/test.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 70 | 71 | 72 | 73 | 74 |
75 |

PHP Hookbox Chat

76 |
77 |
78 | 79 | 80 |
81 |
82 | 83 | -------------------------------------------------------------------------------- /examples/php_chat/public_html/unsubscribe.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/php_chat/run_example.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | hookbox --admin-password=hookboxdemo --cb-connect=connect.php --cb-create_channel=create_channel.php --cb-subscribe=subscribe.php --cb-unsubscribe=unsubscribe.php --cb-publish=publish.php --cb-disconnect=disconnect.php --debug 4 | -------------------------------------------------------------------------------- /examples/php_graph/README: -------------------------------------------------------------------------------- 1 | To deploy the php graph example, 2 | 1) put graph.php somewhere where it can be served by apache and found at http://localhost/graph.php. 3 | 2) run hookbox: hookbox -s secret --cb-single-url="http://localhost/graph.php" 4 | 3) visit http://localhost/graph.php 5 | 6 | NOTE: If you want to run this on another domain, then edit the constants at the top of graph.php, and change the --cb-single-url option when starting hookbox. -------------------------------------------------------------------------------- /examples/php_graph/graph.php: -------------------------------------------------------------------------------- 1 | "PUBLISH", 1=>array("payload" => 0)); 51 | } 52 | // returning json: [true, { "polling": { ... }, "history": [ .. ], ... } ] 53 | print_r(json_encode($output)); 54 | } else { 55 | $chan = $form["channel_name"]; 56 | echo "[ false, {\"error\": \"Cannot create channel $chan\"} ]"; 57 | } 58 | break; 59 | // Let anyone subscribe to that one channel 60 | case "subscribe": 61 | echo "[ true, {} ]"; 62 | break; 63 | // If the server is polling then print out the server load; 64 | case "poll": 65 | // NOTE: If you aren't on a system with an uptime command then 66 | // try replacing this with some other integer. Perhaps 67 | // something random... 68 | $cpu_usage = explode(',', substr(exec('uptime'), -14)); 69 | print($cpu_usage[0]); 70 | break; 71 | case "destroy_channel": 72 | // By allowing destroy channel we prevent hookbox from polling this 73 | // script when their are no users watching. On the other hand, we lose 74 | // the graph's history of the last 30 values... 75 | echo "[ true, {} ]"; 76 | break; 77 | // Don't allow any other actions, such as publish 78 | default: 79 | echo "[ false, {} ]"; 80 | break; 81 | 82 | } 83 | } 84 | 85 | function static_page() { 86 | global $HOOKBOX_URL; 87 | global $CHANNEL_NAME; 88 | print << 90 | 91 | 123 | 133 | 134 |

Real-time PHP CPU Graph!

135 |
136 |
137 | 138 | 139 | END; 140 | 141 | } 142 | 143 | main(); 144 | 145 | ?> 146 | -------------------------------------------------------------------------------- /examples/php_simple_chat/chat.php: -------------------------------------------------------------------------------- 1 | "; 17 | exit(0); 18 | } 19 | } 20 | $username = $_SESSION['username']; 21 | 22 | $form = array_merge($_GET, $_POST); 23 | if (!empty($form["action"])) { 24 | switch($form["action"]) { 25 | case "connect": 26 | echo '[true, {"name":"'.$username.'"}]'; 27 | break; 28 | case "create_channel": 29 | if ($form['channel_name'] == 'chat') { 30 | echo '[true, {"history_size": 30, ' 31 | .'"history": [], ' 32 | .'"presenceful": true, ' 33 | .'"reflective": true}]'; 34 | } else { 35 | echo '[false, {}]'; 36 | } 37 | break; 38 | case "subscribe": 39 | case "publish": 40 | case "unsubscribe": 41 | case "disconnect": 42 | echo "[true, {}]"; 43 | break; 44 | default: 45 | echo "[false, {}]"; 46 | break; 47 | } 48 | exit(0); 49 | } 50 | 51 | ?> 52 | 53 | 54 | 62 | 63 | 64 |
65 | 66 | 67 | 68 | 101 | -------------------------------------------------------------------------------- /examples/php_simple_chat/start: -------------------------------------------------------------------------------- 1 | hookbox --admin-password=abc --cb-single-url="http://localhost/~martin/dev/hookbox/examples/chat/chat.php" -------------------------------------------------------------------------------- /examples/python_graphic_eq/README: -------------------------------------------------------------------------------- 1 | README 2 | ------ 3 | 4 | This demo displays a Graphic EQ that is dynamically updated based 5 | on data published by the server on channel "chan1". 6 | 7 | A producer process (producer.py) generates random data and uses 8 | Hookbox's REST api to publish the data on the channel mentioned above. 9 | 10 | A Quixote based web application (webapp.py) serves the main page and also 11 | handles call backs from the Hookbox process. 12 | 13 | jQuery and jQuery-ui are used on the web page to render the sliders 14 | which make up our EQ widget. 15 | 16 | How To Run 17 | ---------- 18 | 19 | 0. Install hookbox and Quixote using some or all of the following steps 20 | - easy_install hookbox 21 | - easy_install quixote 22 | - easy_install pyjsiocompile (hookbox depends on this). 23 | 1. In terminal 1: `sudo ./webapp.py` 24 | 2. In terminal 2: `sudo hookbox -d -r altoids -p 2974 --cbhost=127.0.0.1 --cbport=8080 --cbpath=` 25 | 3. In terminal 3: `sudo ./producer.py` 26 | 4. In Firefox: goto http://localhost:8080 27 | 28 | 29 | Author 30 | ------ 31 | Salman Haq 32 | salman.haq@asti-usa.com 33 | http://bitshaq.com 34 | 35 | License 36 | ------- 37 | MIT License 38 | -------------------------------------------------------------------------------- /examples/python_graphic_eq/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 11 | 12 | 13 | 14 | 15 | 21 | 22 | 61 | Equalizer Demo 62 |
63 |
64 | 88 65 | 77 66 | 55 67 | 33 68 | 40 69 | 45 70 | 70 71 |
72 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /examples/python_graphic_eq/producer.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | """ producer.py 3 | Produces random data samples for the EQ sliders. 4 | Uses the Hookbox REST api for publishing the data 5 | on channel "chan1". 6 | 7 | --- License: MIT --- 8 | 9 | Copyright (c) 2010 Hookbox 10 | 11 | Permission is hereby granted, free of charge, to any person obtaining a copy 12 | of this software and associated documentation files (the "Software"), to deal 13 | in the Software without restriction, including without limitation the rights 14 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | copies of the Software, and to permit persons to whom the Software is 16 | furnished to do so, subject to the following conditions: 17 | 18 | The above copyright notice and this permission notice shall be included in 19 | all copies or substantial portions of the Software. 20 | 21 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | THE SOFTWARE. 28 | 29 | """ 30 | 31 | import time, urllib, urllib2, json, random 32 | 33 | def main (): 34 | 35 | # assume the hookbox server is on localhost:2974 36 | url = "http://127.0.0.1:2974/rest/publish" 37 | 38 | values = { "secret" : "altoids", 39 | "channel_name" : "chan1", 40 | "payload" : [] 41 | } 42 | 43 | # data samples from 0 - 99 inclusive 44 | pop = range(0,100) 45 | 46 | while True: 47 | # generate seven random data points every 0.5 seconds 48 | # and publish them via the HTTP/REST api. 49 | values["payload"] = random.sample(pop, 7) 50 | data = urllib.urlencode(values) 51 | req = urllib2.Request(url, data) 52 | resp = urllib2.urlopen(req) 53 | # the hookbox response can be useful for debugging, 54 | # but i'm commenting it out. 55 | #page = resp.read() 56 | #print page 57 | print values["payload"] 58 | time.sleep(0.5) 59 | 60 | 61 | 62 | if __name__ == "__main__": 63 | main() 64 | -------------------------------------------------------------------------------- /examples/python_graphic_eq/webapp.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | """ 3 | -- License: MIT --- 4 | 5 | Copyright (c) 2010 Hookbox 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in 15 | all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | THE SOFTWARE. 24 | 25 | """ 26 | import os 27 | from quixote.directory import Directory 28 | from quixote.publish import Publisher 29 | from quixote.util import StaticFile 30 | from quixote.server.simple_server import run 31 | 32 | import json 33 | 34 | class Root (Directory): 35 | """ This is the application root. 36 | """ 37 | _q_exports = ['', 'connect', 'disconnect', 'create_channel', 'subscribe', 'unsubscribe', 'publish'] 38 | 39 | def _q_index (self): 40 | # serve the index.html at / 41 | p = os.path.join(os.getcwd(), 'index.html') 42 | index = StaticFile(path=p, mime_type="text/html") 43 | return index() 44 | 45 | def connect (self): 46 | # accept all connect requests and assume they are from 'guest' 47 | return json.dumps([ True, {"name":"guest"} ]) 48 | 49 | def disconnect (self): 50 | return [ True, {} ] 51 | 52 | def create_channel (self): 53 | # accept all create channel requests. in this example, 54 | # only one channel is ever created: 'chan1' 55 | return json.dumps([ True, { "history_size" : 0, 56 | "reflective" : True, 57 | "presenceful" : True } ]) 58 | 59 | def subscribe (self): 60 | return json.dumps([ True, {} ]) 61 | 62 | def unsubscribe (self): 63 | return json.dumps([ True, {} ]) 64 | 65 | def publish (self): 66 | return json.dumps([ True, {} ]) 67 | 68 | 69 | def create_publisher(): 70 | return Publisher(Root(), display_exceptions='plain') 71 | 72 | def main (): 73 | # create an http server bound to the host and port specified 74 | # and publish the Root instance. 75 | run(create_publisher, host="127.0.0.1", port=8080) 76 | 77 | if __name__ == '__main__': 78 | main() 79 | 80 | -------------------------------------------------------------------------------- /examples/python_scope/README: -------------------------------------------------------------------------------- 1 | README 2 | ------ 3 | 4 | This demo displays a scope that is dynamically updated based 5 | on data published by the server on channel "chan1". 6 | 7 | A producer process (producer.py) generates random data and uses 8 | Hookbox's REST api to publish the data on the channel mentioned above. 9 | 10 | A Quixote based web application (webapp.py) serves the main page and also 11 | handles call backs from the Hookbox process. 12 | 13 | jQuery and jQuery-ui are used on the web page to render the sliders 14 | which make up our EQ widget. 15 | 16 | How To Run 17 | ---------- 18 | 19 | 0. Install hookbox and Quixote using some or all of the following steps 20 | - easy_install hookbox 21 | - easy_install quixote 22 | - easy_install pyjsiocompile (hookbox depends on this). 23 | 1. In terminal 1: `sudo ./webapp.py` 24 | 2. In terminal 2: `sudo hookbox -d -r altoids -p 2974 -w 2975 --cbhost=127.0.0.1 --cbport=8080 --cbpath=` 25 | 3. In terminal 3: `sudo ./producer.py` 26 | 4. In Firefox: goto http://localhost:8080 27 | 28 | 29 | Author 30 | ------ 31 | Salman Haq 32 | salman.haq@asti-usa.com 33 | http://bitshaq.com 34 | 35 | License 36 | ------- 37 | MIT License 38 | -------------------------------------------------------------------------------- /examples/python_scope/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 11 | 12 | 13 | 14 | 15 | 16 | 21 | 22 | 23 | 83 | Scope Demo 84 |
85 |
86 |
87 | 88 |
Frames Per Second: 89 |
90 | 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /examples/python_scope/producer.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | """ producer.py 3 | Publishes data from a 120 Hz sine wave sampled at 48 KHz 4 | and published at 750Hz. 5 | 6 | --- License: MIT --- 7 | 8 | Copyright (c) 2010 Hookbox 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in 18 | all copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | THE SOFTWARE. 27 | 28 | """ 29 | 30 | import time, urllib, urllib2, json, random 31 | import math 32 | 33 | # Publish at 750 Hz 34 | PUB_RATE = 750.0 35 | # Sample rate 48 KHz 36 | SAMPLE_RATE = 48000.0 37 | 38 | def main (): 39 | 40 | # assume the hookbox server is on localhost:2975 41 | url = "http://127.0.0.1:2975/web/publish" 42 | 43 | values = { "security_token" : "altoids", 44 | "channel_name" : "chan1", 45 | "payload" : [] 46 | } 47 | 48 | pub_count = 0 49 | pub_delta = 1/PUB_RATE 50 | samp_delta = 1/SAMPLE_RATE 51 | num_samples = int(pub_delta / samp_delta) # no. of samples per publication 52 | samples = [math.sin(120*(i*samp_delta)) for i in range(0, 48000)] # a second's worth of samples from a 120 Hz sine wave 53 | 54 | while True: 55 | # offset in the samples array for this iteration 56 | x = int((pub_count % PUB_RATE) * num_samples) 57 | # time samples for this iteration (for plotting on the x-axis) 58 | tv = [(pub_count*pub_delta)+(i*samp_delta) for i in range(0,num_samples)] 59 | # create the payload 60 | payload = zip(tv, samples[x:x+num_samples]) 61 | payload = map(list, payload) 62 | # publish this iterations samples 63 | values["payload"] = payload 64 | data = urllib.urlencode(values) 65 | req = urllib2.Request(url, data) 66 | resp = urllib2.urlopen(req) 67 | # increment publication counter 68 | pub_count += 1 69 | # sleep until it is time to publish the next set of samples 70 | time.sleep(pub_delta) 71 | 72 | 73 | 74 | if __name__ == "__main__": 75 | main() 76 | -------------------------------------------------------------------------------- /examples/python_scope/webapp.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | """ 3 | -- License: MIT --- 4 | 5 | Copyright (c) 2010 Hookbox 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in 15 | all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | THE SOFTWARE. 24 | 25 | """ 26 | import os 27 | from quixote.directory import Directory 28 | from quixote.publish import Publisher 29 | from quixote.util import StaticFile, StaticDirectory 30 | from quixote.server.simple_server import run 31 | 32 | import json 33 | 34 | class Root (Directory): 35 | """ This is the application root. 36 | """ 37 | _q_exports = ['', 'static', 'connect', 'disconnect', 'create_channel', 'subscribe', 'unsubscribe', 'publish'] 38 | 39 | static = StaticDirectory(os.path.join(os.getcwd(), 'static')) 40 | 41 | def _q_index (self): 42 | # serve the index.html at / 43 | p = os.path.join(os.getcwd(), 'index.html') 44 | index = StaticFile(path=p, mime_type="text/html") 45 | return index() 46 | 47 | def connect (self): 48 | # accept all connect requests and assume they are from 'guest' 49 | return json.dumps([ True, {"name":"guest"} ]) 50 | 51 | def disconnect (self): 52 | return [ True, {} ] 53 | 54 | def create_channel (self): 55 | # accept all create channel requests. in this example, 56 | # only one channel is ever created: 'chan1' 57 | return json.dumps([ True, { "history_size" : 0, 58 | "reflective" : True, 59 | "presenceful" : True } ]) 60 | 61 | def subscribe (self): 62 | return json.dumps([ True, {} ]) 63 | 64 | def unsubscribe (self): 65 | return json.dumps([ True, {} ]) 66 | 67 | def publish (self): 68 | return json.dumps([ True, {} ]) 69 | 70 | 71 | def create_publisher(): 72 | return Publisher(Root(), display_exceptions='plain') 73 | 74 | def main (): 75 | # create an http server bound to the host and port specified 76 | # and publish the Root instance. 77 | run(create_publisher, host="0.0.0.0", port=8080) 78 | 79 | if __name__ == '__main__': 80 | main() 81 | 82 | -------------------------------------------------------------------------------- /hookbox/__init__.py: -------------------------------------------------------------------------------- 1 | __version__ = '0.3.4dev' 2 | -------------------------------------------------------------------------------- /hookbox/admin/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/play-co/hookbox/c0087632b8035a1bff5c8dc55a2b64ba44c2cfbb/hookbox/admin/__init__.py -------------------------------------------------------------------------------- /hookbox/admin/js_src/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | jsio_compile -j ../../js_src/jsio-3.2 -g -o ../static/admin.js admin.pkg -------------------------------------------------------------------------------- /hookbox/admin/js_src/admin.pkg: -------------------------------------------------------------------------------- 1 | { 2 | "root": "admin", 3 | "transports": ["csp"], 4 | "environments": ["browser"], 5 | "additional_dependancies": [ ] 6 | } 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /hookbox/admin/static/admin.css: -------------------------------------------------------------------------------- 1 | html, body { background: #2E282E; margin: 0px; padding: 0px;} 2 | body { height: 100%; } 3 | 4 | body, div, td { font-family: Frutiger, "Frutiger Linotype", Univers, Calibri, "Gill Sans", "Gill Sans MT", "Myriad Pro", Myriad, "DejaVu Sans Condensed", "Liberation Sans", "Nimbus Sans L", Tahoma, Geneva, "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 13px; font-weight: bold; } 5 | a { outline: none; } 6 | h1, h2, h3 { margin: 0px 0px 10px 0px; } 7 | h1 { font-size: 22px; } 8 | h2 { font-size: 18px; } 9 | h3 { font-size: 14px; } 10 | 11 | .hidden { 12 | display: none; 13 | } 14 | 15 | #login { 16 | position: absolute; 17 | background: #EEE; 18 | font-weight: bold; 19 | width: 180px; 20 | -moz-border-radius: 5px; 21 | -webkit-border-radius: 5px; 22 | border-radius: 5px; 23 | padding: 20px; 24 | } 25 | 26 | #login input { width: 100px; } 27 | #login button { margin-left: 10px; } 28 | 29 | #app { 30 | position: absolute; 31 | width: 800px; 32 | margin-bottom: 10px; 33 | } 34 | 35 | #side_menu { position: absolute; top: 30px; left: 20px; padding: 10px 0px; background: #d3c68a; width: 140px; -moz-border-radius: 5px; -webkit-border-radius: 5px; } 36 | 37 | #side_menu a { display: block; padding: 2px 8px 3px 10px; text-decoration: none; outline:none; text-align: right; color: #12141F;} 38 | #side_menu a:hover { background: #ffffc0; color: #338; } 39 | #side_menu a.selected { background: #f0e3a5; font-weight: bold; color: #000; } 40 | 41 | #logo { 42 | width: 109px; 43 | height: 81px; 44 | background: url(images/logo.png) no-repeat; 45 | position: fixed; 46 | bottom: 10px; 47 | left: 32px; 48 | } 49 | 50 | #body { 51 | background: #EEE; 52 | position: absolute; 53 | left: 170px; 54 | -moz-border-radius: 5px; 55 | -webkit-border-radius: 5px; 56 | margin-bottom: 10px; 57 | border: 2px solid #5a9af8; 58 | } 59 | 60 | #bodyContent { padding: 10px 0px 10px 10px; } 61 | 62 | ul { 63 | list-style-type: none; 64 | padding: 0px; 65 | margin: 0px; 66 | } 67 | 68 | li { 69 | margin: 0px; 70 | } 71 | 72 | #body h1 { margin: -10px 0px 10px -10px; background: #5a9af8 url('images/h1.png') repeat-x; -moz-border-radius: 4px 4px 0px 0px; padding: 0px 5px 2px 8px; } 73 | #body h1, #body h1 a { color: #324a6d; } 74 | 75 | .block { float: left; width: 250px; border: 1px solid #464f51; padding: 0px; margin-right: 5px; margin-bottom: 5px; -moz-border-radius: 6px 6px 3px 3px; -webkit-border-radius: 3px; background: #FFF; } 76 | .wideBlock { width: 507px; } 77 | .block h3 { margin: 1px; background: #6E7C7F url('images/h3.png') 0px -2px repeat-x; color: #EEE; -moz-border-radius: 5px 5px 0px 0px; -webkit-border-radius-topleft: 2px; -webkit-border-radius-topright: 2px; padding: 3px 2px 4px 5px;} 78 | 79 | .blockContent { margin: 10px; max-height: 250px; overflow: auto; } 80 | .tallBlock .blockContent { height: 250px; } 81 | .shortBlock .blockContent { height: 100px; } 82 | 83 | .channelOptionsTable { margin: 0px auto; } 84 | .channelOptionsButtons { text-align: center; margin-top: 10px;} 85 | 86 | .overviewLabel { float: left; text-align: left; font-size: 20px; display: block; padding: 3px; padding-left: 15px; padding-right: 5px; text-decoration: none; width: 200px;} 87 | .overviewNum { width: 80px; text-align: left; float: right; margin-top: -12px; margin-left: 20px; font-family: Georgia, serif; font-size: 36px; padding: 2px; } 88 | 89 | tr td:first-child { text-align: right; } 90 | .inputNumber { width: 60px; } -------------------------------------------------------------------------------- /hookbox/admin/static/highlighter.css: -------------------------------------------------------------------------------- 1 | .highlight .hll { background-color: #ffffcc } 2 | .highlight .c { color: #408080; font-style: italic } /* Comment */ 3 | .highlight .err { border: 1px solid #FF0000 } /* Error */ 4 | .highlight .k { color: #008000; font-weight: bold } /* Keyword */ 5 | .highlight .o { color: #666666 } /* Operator */ 6 | .highlight .cm { color: #408080; font-style: italic } /* Comment.Multiline */ 7 | .highlight .cp { color: #BC7A00 } /* Comment.Preproc */ 8 | .highlight .c1 { color: #408080; font-style: italic } /* Comment.Single */ 9 | .highlight .cs { color: #408080; font-style: italic } /* Comment.Special */ 10 | .highlight .gd { color: #A00000 } /* Generic.Deleted */ 11 | .highlight .ge { font-style: italic } /* Generic.Emph */ 12 | .highlight .gr { color: #FF0000 } /* Generic.Error */ 13 | .highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ 14 | .highlight .gi { color: #00A000 } /* Generic.Inserted */ 15 | .highlight .go { color: #808080 } /* Generic.Output */ 16 | .highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ 17 | .highlight .gs { font-weight: bold } /* Generic.Strong */ 18 | .highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ 19 | .highlight .gt { color: #0040D0 } /* Generic.Traceback */ 20 | .highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */ 21 | .highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ 22 | .highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ 23 | .highlight .kp { color: #008000 } /* Keyword.Pseudo */ 24 | .highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ 25 | .highlight .kt { color: #B00040 } /* Keyword.Type */ 26 | .highlight .m { color: #666666 } /* Literal.Number */ 27 | .highlight .s { color: #BA2121 } /* Literal.String */ 28 | .highlight .na { color: #7D9029 } /* Name.Attribute */ 29 | .highlight .nb { color: #008000 } /* Name.Builtin */ 30 | .highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */ 31 | .highlight .no { color: #880000 } /* Name.Constant */ 32 | .highlight .nd { color: #AA22FF } /* Name.Decorator */ 33 | .highlight .ni { color: #999999; font-weight: bold } /* Name.Entity */ 34 | .highlight .ne { color: #D2413A; font-weight: bold } /* Name.Exception */ 35 | .highlight .nf { color: #0000FF } /* Name.Function */ 36 | .highlight .nl { color: #A0A000 } /* Name.Label */ 37 | .highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ 38 | .highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */ 39 | .highlight .nv { color: #19177C } /* Name.Variable */ 40 | .highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ 41 | .highlight .w { color: #bbbbbb } /* Text.Whitespace */ 42 | .highlight .mf { color: #666666 } /* Literal.Number.Float */ 43 | .highlight .mh { color: #666666 } /* Literal.Number.Hex */ 44 | .highlight .mi { color: #666666 } /* Literal.Number.Integer */ 45 | .highlight .mo { color: #666666 } /* Literal.Number.Oct */ 46 | .highlight .sb { color: #BA2121 } /* Literal.String.Backtick */ 47 | .highlight .sc { color: #BA2121 } /* Literal.String.Char */ 48 | .highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ 49 | .highlight .s2 { color: #BA2121 } /* Literal.String.Double */ 50 | .highlight .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */ 51 | .highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */ 52 | .highlight .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */ 53 | .highlight .sx { color: #008000 } /* Literal.String.Other */ 54 | .highlight .sr { color: #BB6688 } /* Literal.String.Regex */ 55 | .highlight .s1 { color: #BA2121 } /* Literal.String.Single */ 56 | .highlight .ss { color: #19177C } /* Literal.String.Symbol */ 57 | .highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */ 58 | .highlight .vc { color: #19177C } /* Name.Variable.Class */ 59 | .highlight .vg { color: #19177C } /* Name.Variable.Global */ 60 | .highlight .vi { color: #19177C } /* Name.Variable.Instance */ 61 | .highlight .il { color: #666666 } /* Literal.Number.Integer.Long */ 62 | -------------------------------------------------------------------------------- /hookbox/admin/static/images/h1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/play-co/hookbox/c0087632b8035a1bff5c8dc55a2b64ba44c2cfbb/hookbox/admin/static/images/h1.png -------------------------------------------------------------------------------- /hookbox/admin/static/images/h3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/play-co/hookbox/c0087632b8035a1bff5c8dc55a2b64ba44c2cfbb/hookbox/admin/static/images/h3.png -------------------------------------------------------------------------------- /hookbox/admin/static/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/play-co/hookbox/c0087632b8035a1bff5c8dc55a2b64ba44c2cfbb/hookbox/admin/static/images/logo.png -------------------------------------------------------------------------------- /hookbox/admin/static/lib/jqueryui/css/overcast/images/ui-bg_flat_0_aaaaaa_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/play-co/hookbox/c0087632b8035a1bff5c8dc55a2b64ba44c2cfbb/hookbox/admin/static/lib/jqueryui/css/overcast/images/ui-bg_flat_0_aaaaaa_40x100.png -------------------------------------------------------------------------------- /hookbox/admin/static/lib/jqueryui/css/overcast/images/ui-bg_flat_0_eeeeee_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/play-co/hookbox/c0087632b8035a1bff5c8dc55a2b64ba44c2cfbb/hookbox/admin/static/lib/jqueryui/css/overcast/images/ui-bg_flat_0_eeeeee_40x100.png -------------------------------------------------------------------------------- /hookbox/admin/static/lib/jqueryui/css/overcast/images/ui-bg_flat_55_c0402a_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/play-co/hookbox/c0087632b8035a1bff5c8dc55a2b64ba44c2cfbb/hookbox/admin/static/lib/jqueryui/css/overcast/images/ui-bg_flat_55_c0402a_40x100.png -------------------------------------------------------------------------------- /hookbox/admin/static/lib/jqueryui/css/overcast/images/ui-bg_flat_55_eeeeee_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/play-co/hookbox/c0087632b8035a1bff5c8dc55a2b64ba44c2cfbb/hookbox/admin/static/lib/jqueryui/css/overcast/images/ui-bg_flat_55_eeeeee_40x100.png -------------------------------------------------------------------------------- /hookbox/admin/static/lib/jqueryui/css/overcast/images/ui-bg_glass_100_f8f8f8_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/play-co/hookbox/c0087632b8035a1bff5c8dc55a2b64ba44c2cfbb/hookbox/admin/static/lib/jqueryui/css/overcast/images/ui-bg_glass_100_f8f8f8_1x400.png -------------------------------------------------------------------------------- /hookbox/admin/static/lib/jqueryui/css/overcast/images/ui-bg_glass_35_dddddd_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/play-co/hookbox/c0087632b8035a1bff5c8dc55a2b64ba44c2cfbb/hookbox/admin/static/lib/jqueryui/css/overcast/images/ui-bg_glass_35_dddddd_1x400.png -------------------------------------------------------------------------------- /hookbox/admin/static/lib/jqueryui/css/overcast/images/ui-bg_glass_60_eeeeee_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/play-co/hookbox/c0087632b8035a1bff5c8dc55a2b64ba44c2cfbb/hookbox/admin/static/lib/jqueryui/css/overcast/images/ui-bg_glass_60_eeeeee_1x400.png -------------------------------------------------------------------------------- /hookbox/admin/static/lib/jqueryui/css/overcast/images/ui-bg_inset-hard_75_999999_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/play-co/hookbox/c0087632b8035a1bff5c8dc55a2b64ba44c2cfbb/hookbox/admin/static/lib/jqueryui/css/overcast/images/ui-bg_inset-hard_75_999999_1x100.png -------------------------------------------------------------------------------- /hookbox/admin/static/lib/jqueryui/css/overcast/images/ui-bg_inset-soft_50_c9c9c9_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/play-co/hookbox/c0087632b8035a1bff5c8dc55a2b64ba44c2cfbb/hookbox/admin/static/lib/jqueryui/css/overcast/images/ui-bg_inset-soft_50_c9c9c9_1x100.png -------------------------------------------------------------------------------- /hookbox/admin/static/lib/jqueryui/css/overcast/images/ui-icons_3383bb_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/play-co/hookbox/c0087632b8035a1bff5c8dc55a2b64ba44c2cfbb/hookbox/admin/static/lib/jqueryui/css/overcast/images/ui-icons_3383bb_256x240.png -------------------------------------------------------------------------------- /hookbox/admin/static/lib/jqueryui/css/overcast/images/ui-icons_454545_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/play-co/hookbox/c0087632b8035a1bff5c8dc55a2b64ba44c2cfbb/hookbox/admin/static/lib/jqueryui/css/overcast/images/ui-icons_454545_256x240.png -------------------------------------------------------------------------------- /hookbox/admin/static/lib/jqueryui/css/overcast/images/ui-icons_70b2e1_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/play-co/hookbox/c0087632b8035a1bff5c8dc55a2b64ba44c2cfbb/hookbox/admin/static/lib/jqueryui/css/overcast/images/ui-icons_70b2e1_256x240.png -------------------------------------------------------------------------------- /hookbox/admin/static/lib/jqueryui/css/overcast/images/ui-icons_999999_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/play-co/hookbox/c0087632b8035a1bff5c8dc55a2b64ba44c2cfbb/hookbox/admin/static/lib/jqueryui/css/overcast/images/ui-icons_999999_256x240.png -------------------------------------------------------------------------------- /hookbox/admin/static/lib/jqueryui/css/overcast/images/ui-icons_fbc856_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/play-co/hookbox/c0087632b8035a1bff5c8dc55a2b64ba44c2cfbb/hookbox/admin/static/lib/jqueryui/css/overcast/images/ui-icons_fbc856_256x240.png -------------------------------------------------------------------------------- /hookbox/admin/static/lib/oocss/content.css: -------------------------------------------------------------------------------- 1 | body{font-family:"Myriad Pro","Segoe UI",Helvetica, Arial, sans-serif;} 2 | /* **************** CONTENT OBJECTS ***************** */ 3 | /* ====== Default spacing ====== */ 4 | h1, h2, h3, h4, h5, h6, ul, ol,dl, p,blockquote {padding:10px;} 5 | h1, h2, h3, h4, h5, h6,img{padding-bottom:0px;} 6 | pre{margin: 10px;} 7 | table h1,table h2,table h3, table h4, table h5, table h6, table p, table ul, table ol, table dl{padding:0;} 8 | /* ====== Elements ====== */ 9 | img{display:block;} 10 | em{font-style: italic;} 11 | strong{font-weight:bold;} 12 | hr{border: 5px solid #e2e2e2; border-width: 0 0 5px 0; margin: 20px 10px 10px 10px;} 13 | code{color:#0B8C8F;} 14 | /* ====== Headings ====== */ 15 | /* .h1-.h6 classes should be used to maintain the semantically appropriate heading levels - NOT for use on non-headings */ 16 | h1, .h1{font-size:196%; font-weight:normal; font-style: normal; color:#AE0345;} 17 | h2, .h2{font-size:167%; font-weight:normal; font-style: normal; color:#AE0345;} 18 | h3, .h3{font-size:146.5%; font-weight:normal; font-style: normal; color:#DF2B72;} 19 | h4, .h4{font-size:123.1%; font-weight:normal; font-style: normal; color: #333;} 20 | h5, .h5{font-size:108%; font-weight:bold; font-style: normal; color:#AE0345;} 21 | h6, .h6{font-size:108%; font-weight:normal; font-style: italic; color:#333;} 22 | /* if additional headings are needed they should be created via additional classes, never via location dependant styling */ 23 | .category{font-size:108%; font-weight:normal; font-style: normal; text-transform:uppercase; color: #333;} 24 | .category a{color: #333;} 25 | .important a{font-weight:bold;} 26 | /* links */ 27 | a {color: #2c4460; text-decoration: none;} 28 | a:focus, a:hover {text-decoration: underline;} 29 | a:focus{background-color:#FFFFCC;} 30 | a:visited { color:#005a9c; } 31 | /* ====== Lists ======*/ 32 | /* numbered list */ 33 | ol.simpleList li{list-style-type: decimal; margin-left:40px;} 34 | /* standard list */ 35 | ul.simpleList li{list-style-type:disc; margin-left:40px;} 36 | /* ====== Tables ====== */ 37 | .data{padding: 20px; position:relative; zoom:1;vertical-align: top;border-right:solid 1px transparent;/* border fixes a FF2 bug which causes the data table to overlay its borders*/} 38 | .data table {width:100%;border:1px solid #AE0345;} 39 | th, td{vertical-align:top;border:1px solid #AE0345;} 40 | .txtC, .data .txtC td, .data .txtC th{text-align:center;} 41 | .txtL, .data .txtL td, .data .txtL th{text-align:left;} 42 | .txtR, .data .txtR td, .data .txtR th{text-align:right;} 43 | .txtT, .data .txtT td, .data .txtT th{vertical-align:top;} 44 | .txtB, .data .txtB td, .data .txtB th{vertical-align:bottom;} 45 | .txtM, .data .txtM td, .data .txtM th{vertical-align:middle;} 46 | .data th,.data td{padding:3px 20px} 47 | .data thead tr{background-color: #fff0f8;} 48 | .data th{color: #000; font-weight:bold} 49 | /* specification table - extends data table */ 50 | .spec{padding:10px;} 51 | .spec table{border-top: 1px solid #e2e2e2; border-bottom-color:#fff; border-left:none; border-right:none;} 52 | .spec th, .spec td{border:1px solid #e2e2e2; border-width: 1px 0; padding-left:0;} 53 | .spec .odd, .spec .even{background-color: #fff;} 54 | /* ====== blockquote ====== */ 55 | cite{display:block; text-align:right; padding-top: 10px;} 56 | /* ====== callout ====== */ 57 | .callout{font-size:189%;color:#999999; font-style:italic;} 58 | .callout cite{display:block; text-align:right;padding-top: 30px; font-size:69.25%;} 59 | .callout span.quot{font-size: 500%; vertical-align: sub; color:#e2e2e2; line-height:25px; font-weight:bold;} 60 | .callout span.quotLast{vertical-align:middle;} 61 | /* ====== image treatments (get more from jason santa maria) ====== */ 62 | .caption{font-size:13px; color:#666666; font-style:italic;padding-top:0;} 63 | /* will need to either 64 | 1. find a way to capture the width of the caption in the width of the image or flash 65 | 2. Set some default widths, mby use flickr widths? 66 | */ 67 | /* ====== media ====== */ 68 | .media{overflow:hidden; overflow:visible; zoom:1;margin:10px;} 69 | .media .img{float:left;margin-right: 10px;} 70 | .media .img img{display:block;} 71 | .media .imgExt{float:right; margin-left: 10px;} 72 | /* ====== special formatting classes ====== */ 73 | .detail{color: #777; font-size:11px;display:block;} 74 | -------------------------------------------------------------------------------- /hookbox/admin/static/lib/oocss/grid/grids.css: -------------------------------------------------------------------------------- 1 | @media screen and (max-width: 319px) {.unit{float: none !important; width: auto !important;}} 2 | .line:after,.lastUnit:after{clear:both;display:block;visibility:hidden;overflow:hidden;height:0 !important;line-height:0;font-size:xx-large;content:" x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x ";} 3 | .line{*zoom:1;} 4 | .unit{float:left;} 5 | .size1of1{float:none;} 6 | .size1of2{width:50%;} 7 | .size1of3{width:33.33333%;} 8 | .size2of3{width:66.66666%;} 9 | .size1of4{width:25%;} 10 | .size3of4{width:75%;} 11 | .size1of5{width:20%;} 12 | .size2of5{width:40%;} 13 | .size3of5{width:60%;} 14 | .size4of5{width:80%;} 15 | .lastUnit{display:table-cell;float:none;width:auto;*display:block;*zoom:1;_position:relative;_left:-3px;_margin-right:-3px;} 16 | -------------------------------------------------------------------------------- /hookbox/admin/static/lib/oocss/grid/grids_debug.css: -------------------------------------------------------------------------------- 1 | /* grids debug */ 2 | .line{background-color:#e2e2e2;} 3 | .size1of1{background-color:pink;} 4 | .size1of2{background-color:red;} 5 | .size1of3{background-color:orange;} 6 | .size2of3{background-color: yellow;} 7 | .size1of4{background-color:lime;} 8 | .size3of4{background-color:green;} 9 | .size1of5{background-color:aqua;} 10 | .size2of5{background-color:blue;} 11 | .size3of5{background-color:purple;} 12 | .size4of5{background-color:magenta;} -------------------------------------------------------------------------------- /hookbox/admin/static/lib/oocss/libraries.css: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2008, Yahoo! Inc. All rights reserved. 3 | Code licensed under the BSD License: 4 | http://developer.yahoo.net/yui/license.txt 5 | version: 3.0.0pr2 6 | */ 7 | /* reset */ 8 | 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;} 9 | /* fonts */ 10 | body{font:13px/1.231 arial,helvetica,clean,sans-serif;*font-size:small;*font:x-small;}select,input,button,textarea{font:99% arial,helvetica,clean,sans-serif;}table{font-size:inherit;font:100%;}pre,code,kbd,samp,tt{font-family:monospace;*font-size:108%;line-height:100%;} -------------------------------------------------------------------------------- /hookbox/admin/static/lib/oocss/module/mod.css: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2009, Nicole Sullivan. All rights reserved. 3 | Code licensed under the BSD License: 4 | version: 0.2 5 | */ 6 | /* **************** BLOCK STRUCTURES ***************** */ 7 | /* mod */ 8 | .mod{margin:10px;} 9 | .mod .inner{/*background: url(skin/transparent.png) repeat left top;*/} 10 | .hd,.bd,.ft{overflow:hidden;_overflow:visible; _zoom:1;} 11 | .inner{position:relative;} 12 | b{display:block;background-repeat:no-repeat;font-size:1%;position:relative;z-index:10;} 13 | .tl, .tr, .bl, .br{height:10px; width:10px;float:left;} 14 | .tl{background-position: left top;} 15 | .tr{background-position: right top;} 16 | .bl{background-position: left bottom;} 17 | .br{background-position: right bottom;} 18 | .br,.tr{float:right;} 19 | .tr, .tl{overflow:hidden;margin-bottom:-32000px;}/* margin bottom needs to be < -9px */ 20 | .bl,.br{margin-top:-10px;} 21 | .top{background-position:center top;} 22 | .bottom{background-position:center bottom;_zoom:1;}/* this zoom required for IE5.5 only*/ 23 | /* complex */ 24 | .complex{overflow:hidden;*position:relative;*zoom:1;}/* position/zoom required for IE7, 6, 5.5 */ 25 | .complex .tl, .complex .tr{height:32000px; margin-bottom:-32000px;width:10px;} 26 | .complex .bl, .complex .br{/*margin-top:0;*/} 27 | .complex .top{height:5px;} 28 | .complex .bottom{height:5px;/*margin-top:-10px;*/} 29 | /* pop */ 30 | .pop{overflow:visible;margin: 10px 20px 20px 10px; background-position:left top;} 31 | .pop .inner{right:-10px; bottom:-10px; background-position:right bottom;padding:0 10px 10px 0;} 32 | .pop .tl, .pop .br{display:none;} 33 | .pop .bl{bottom:-10px;} 34 | .pop .tr{right:-10px;} -------------------------------------------------------------------------------- /hookbox/admin/static/lib/oocss/module/mod_debug.css: -------------------------------------------------------------------------------- 1 | /* debug modules */ 2 | .top, .bottom{background-color:#e2e2e2;} 3 | .tl{background-color:red;} 4 | .tr{background-color:orange;} 5 | .bl{background-color:yellow;} 6 | .br{background-color:lime;} 7 | /*.hd{background-color: green;} 8 | .bd{background-color: teal;} 9 | .ft{background-color: blue;}*/ 10 | .mod{background-color:purple;} 11 | .inner{background-color:#E20074;} 12 | -------------------------------------------------------------------------------- /hookbox/admin/static/lib/oocss/module/skin/about.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/play-co/hookbox/c0087632b8035a1bff5c8dc55a2b64ba44c2cfbb/hookbox/admin/static/lib/oocss/module/skin/about.png -------------------------------------------------------------------------------- /hookbox/admin/static/lib/oocss/module/skin/author.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/play-co/hookbox/c0087632b8035a1bff5c8dc55a2b64ba44c2cfbb/hookbox/admin/static/lib/oocss/module/skin/author.png -------------------------------------------------------------------------------- /hookbox/admin/static/lib/oocss/module/skin/even.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/play-co/hookbox/c0087632b8035a1bff5c8dc55a2b64ba44c2cfbb/hookbox/admin/static/lib/oocss/module/skin/even.png -------------------------------------------------------------------------------- /hookbox/admin/static/lib/oocss/module/skin/even_borders.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/play-co/hookbox/c0087632b8035a1bff5c8dc55a2b64ba44c2cfbb/hookbox/admin/static/lib/oocss/module/skin/even_borders.psd -------------------------------------------------------------------------------- /hookbox/admin/static/lib/oocss/module/skin/even_lr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/play-co/hookbox/c0087632b8035a1bff5c8dc55a2b64ba44c2cfbb/hookbox/admin/static/lib/oocss/module/skin/even_lr.png -------------------------------------------------------------------------------- /hookbox/admin/static/lib/oocss/module/skin/even_tb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/play-co/hookbox/c0087632b8035a1bff5c8dc55a2b64ba44c2cfbb/hookbox/admin/static/lib/oocss/module/skin/even_tb.png -------------------------------------------------------------------------------- /hookbox/admin/static/lib/oocss/module/skin/excerpt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/play-co/hookbox/c0087632b8035a1bff5c8dc55a2b64ba44c2cfbb/hookbox/admin/static/lib/oocss/module/skin/excerpt.png -------------------------------------------------------------------------------- /hookbox/admin/static/lib/oocss/module/skin/faq.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/play-co/hookbox/c0087632b8035a1bff5c8dc55a2b64ba44c2cfbb/hookbox/admin/static/lib/oocss/module/skin/faq.png -------------------------------------------------------------------------------- /hookbox/admin/static/lib/oocss/module/skin/gc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/play-co/hookbox/c0087632b8035a1bff5c8dc55a2b64ba44c2cfbb/hookbox/admin/static/lib/oocss/module/skin/gc.png -------------------------------------------------------------------------------- /hookbox/admin/static/lib/oocss/module/skin/gc_header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/play-co/hookbox/c0087632b8035a1bff5c8dc55a2b64ba44c2cfbb/hookbox/admin/static/lib/oocss/module/skin/gc_header.png -------------------------------------------------------------------------------- /hookbox/admin/static/lib/oocss/module/skin/gc_header2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/play-co/hookbox/c0087632b8035a1bff5c8dc55a2b64ba44c2cfbb/hookbox/admin/static/lib/oocss/module/skin/gc_header2.png -------------------------------------------------------------------------------- /hookbox/admin/static/lib/oocss/module/skin/glow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/play-co/hookbox/c0087632b8035a1bff5c8dc55a2b64ba44c2cfbb/hookbox/admin/static/lib/oocss/module/skin/glow.png -------------------------------------------------------------------------------- /hookbox/admin/static/lib/oocss/module/skin/glow_7px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/play-co/hookbox/c0087632b8035a1bff5c8dc55a2b64ba44c2cfbb/hookbox/admin/static/lib/oocss/module/skin/glow_7px.png -------------------------------------------------------------------------------- /hookbox/admin/static/lib/oocss/module/skin/glow_test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/play-co/hookbox/c0087632b8035a1bff5c8dc55a2b64ba44c2cfbb/hookbox/admin/static/lib/oocss/module/skin/glow_test.png -------------------------------------------------------------------------------- /hookbox/admin/static/lib/oocss/module/skin/glow_thin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/play-co/hookbox/c0087632b8035a1bff5c8dc55a2b64ba44c2cfbb/hookbox/admin/static/lib/oocss/module/skin/glow_thin.png -------------------------------------------------------------------------------- /hookbox/admin/static/lib/oocss/module/skin/grab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/play-co/hookbox/c0087632b8035a1bff5c8dc55a2b64ba44c2cfbb/hookbox/admin/static/lib/oocss/module/skin/grab.png -------------------------------------------------------------------------------- /hookbox/admin/static/lib/oocss/module/skin/header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/play-co/hookbox/c0087632b8035a1bff5c8dc55a2b64ba44c2cfbb/hookbox/admin/static/lib/oocss/module/skin/header.png -------------------------------------------------------------------------------- /hookbox/admin/static/lib/oocss/module/skin/header_glossy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/play-co/hookbox/c0087632b8035a1bff5c8dc55a2b64ba44c2cfbb/hookbox/admin/static/lib/oocss/module/skin/header_glossy.png -------------------------------------------------------------------------------- /hookbox/admin/static/lib/oocss/module/skin/header_gradient_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/play-co/hookbox/c0087632b8035a1bff5c8dc55a2b64ba44c2cfbb/hookbox/admin/static/lib/oocss/module/skin/header_gradient_light.png -------------------------------------------------------------------------------- /hookbox/admin/static/lib/oocss/module/skin/help.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/play-co/hookbox/c0087632b8035a1bff5c8dc55a2b64ba44c2cfbb/hookbox/admin/static/lib/oocss/module/skin/help.png -------------------------------------------------------------------------------- /hookbox/admin/static/lib/oocss/module/skin/highlight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/play-co/hookbox/c0087632b8035a1bff5c8dc55a2b64ba44c2cfbb/hookbox/admin/static/lib/oocss/module/skin/highlight.png -------------------------------------------------------------------------------- /hookbox/admin/static/lib/oocss/module/skin/info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/play-co/hookbox/c0087632b8035a1bff5c8dc55a2b64ba44c2cfbb/hookbox/admin/static/lib/oocss/module/skin/info.png -------------------------------------------------------------------------------- /hookbox/admin/static/lib/oocss/module/skin/kakapo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/play-co/hookbox/c0087632b8035a1bff5c8dc55a2b64ba44c2cfbb/hookbox/admin/static/lib/oocss/module/skin/kakapo.png -------------------------------------------------------------------------------- /hookbox/admin/static/lib/oocss/module/skin/me.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/play-co/hookbox/c0087632b8035a1bff5c8dc55a2b64ba44c2cfbb/hookbox/admin/static/lib/oocss/module/skin/me.png -------------------------------------------------------------------------------- /hookbox/admin/static/lib/oocss/module/skin/noted.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/play-co/hookbox/c0087632b8035a1bff5c8dc55a2b64ba44c2cfbb/hookbox/admin/static/lib/oocss/module/skin/noted.png -------------------------------------------------------------------------------- /hookbox/admin/static/lib/oocss/module/skin/online.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/play-co/hookbox/c0087632b8035a1bff5c8dc55a2b64ba44c2cfbb/hookbox/admin/static/lib/oocss/module/skin/online.png -------------------------------------------------------------------------------- /hookbox/admin/static/lib/oocss/module/skin/photo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/play-co/hookbox/c0087632b8035a1bff5c8dc55a2b64ba44c2cfbb/hookbox/admin/static/lib/oocss/module/skin/photo.png -------------------------------------------------------------------------------- /hookbox/admin/static/lib/oocss/module/skin/round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/play-co/hookbox/c0087632b8035a1bff5c8dc55a2b64ba44c2cfbb/hookbox/admin/static/lib/oocss/module/skin/round.png -------------------------------------------------------------------------------- /hookbox/admin/static/lib/oocss/module/skin/simple_corners.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/play-co/hookbox/c0087632b8035a1bff5c8dc55a2b64ba44c2cfbb/hookbox/admin/static/lib/oocss/module/skin/simple_corners.png -------------------------------------------------------------------------------- /hookbox/admin/static/lib/oocss/module/skin/simple_extended.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/play-co/hookbox/c0087632b8035a1bff5c8dc55a2b64ba44c2cfbb/hookbox/admin/static/lib/oocss/module/skin/simple_extended.png -------------------------------------------------------------------------------- /hookbox/admin/static/lib/oocss/module/skin/store.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/play-co/hookbox/c0087632b8035a1bff5c8dc55a2b64ba44c2cfbb/hookbox/admin/static/lib/oocss/module/skin/store.png -------------------------------------------------------------------------------- /hookbox/admin/static/lib/oocss/module/skin/talk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/play-co/hookbox/c0087632b8035a1bff5c8dc55a2b64ba44c2cfbb/hookbox/admin/static/lib/oocss/module/skin/talk.png -------------------------------------------------------------------------------- /hookbox/admin/static/lib/oocss/module/skin/universe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/play-co/hookbox/c0087632b8035a1bff5c8dc55a2b64ba44c2cfbb/hookbox/admin/static/lib/oocss/module/skin/universe.png -------------------------------------------------------------------------------- /hookbox/admin/static/lib/oocss/module/skin/universe_gray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/play-co/hookbox/c0087632b8035a1bff5c8dc55a2b64ba44c2cfbb/hookbox/admin/static/lib/oocss/module/skin/universe_gray.png -------------------------------------------------------------------------------- /hookbox/admin/static/lib/oocss/module/skin/universe_login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/play-co/hookbox/c0087632b8035a1bff5c8dc55a2b64ba44c2cfbb/hookbox/admin/static/lib/oocss/module/skin/universe_login.png -------------------------------------------------------------------------------- /hookbox/api/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/play-co/hookbox/c0087632b8035a1bff5c8dc55a2b64ba44c2cfbb/hookbox/api/__init__.py -------------------------------------------------------------------------------- /hookbox/errors.py: -------------------------------------------------------------------------------- 1 | class ExpectedException(Exception): 2 | pass -------------------------------------------------------------------------------- /hookbox/js_src/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | jsio_compile hookbox.pkg -j jsio-3.2 -o ../static/hookbox.js -d 3 | jsio_compile hookbox.pkg -j jsio-3.2 -o ../static/hookbox.min.js -g --v 4 | cp ../static/hookbox.min.js ../static/hookbox.min.js.bak 5 | rm ../static/hookbox.min.js.gz 6 | gzip ../static/hookbox.min.js 7 | mv ../static/hookbox.min.js.bak ../static/hookbox.min.js 8 | clean: 9 | rm ../static/*.js 10 | rm ../static/*.js.gz 11 | -------------------------------------------------------------------------------- /hookbox/js_src/hookbox.pkg: -------------------------------------------------------------------------------- 1 | { 2 | "root": "hookbox", 3 | "transports": ["csp", "websocket"], 4 | "environments": ["browser"], 5 | "additional_dependancies": [ ] 6 | } 7 | -------------------------------------------------------------------------------- /hookbox/js_src/jsio-3.2/base.js: -------------------------------------------------------------------------------- 1 | exports.log = jsio.__env.log; 2 | exports.GLOBAL = jsio.__env.global; 3 | 4 | exports.bind = function(context, method /*, VARGS*/) { 5 | if(arguments.length > 2) { 6 | var args = Array.prototype.slice.call(arguments, 2); 7 | return typeof method == 'string' 8 | ? function() { 9 | if (context[method]) { 10 | return context[method].apply(context, args.concat(Array.prototype.slice.call(arguments, 0))); 11 | } else { 12 | throw logger.error('No method:', method, 'for context', context); 13 | } 14 | } 15 | : function() { return method.apply(context, args.concat(Array.prototype.slice.call(arguments, 0))); } 16 | } else { 17 | return typeof method == 'string' 18 | ? function() { 19 | if (context[method]) { 20 | return context[method].apply(context, arguments); 21 | } else { 22 | throw logger.error('No method:', method, 'for context', context); 23 | } 24 | } 25 | : function() { return method.apply(context, arguments); } 26 | } 27 | } 28 | 29 | exports.Class = function(parent, proto) { 30 | if(!parent) { throw new Error('parent or prototype not provided'); } 31 | if(!proto) { proto = parent; parent = null; } 32 | else if(parent instanceof Array) { // multiple inheritance, use at your own risk =) 33 | proto.prototype = {}; 34 | for(var i = 0, p; p = parent[i]; ++i) { 35 | for(var item in p.prototype) { 36 | if(!(item in proto.prototype)) { 37 | proto.prototype[item] = p.prototype[item]; 38 | } 39 | } 40 | } 41 | parent = parent[0]; 42 | } else { 43 | proto.prototype = parent.prototype; 44 | } 45 | 46 | var cls = function() { if(this.init) { return this.init.apply(this, arguments); }} 47 | cls.prototype = new proto(parent ? function(context, method, args) { 48 | var args = args || []; 49 | var target = proto; 50 | while(target = target.prototype) { 51 | if(target[method]) { 52 | return target[method].apply(context, args); 53 | } 54 | } 55 | throw new Error('method ' + method + ' does not exist'); 56 | } : null); 57 | cls.prototype.constructor = cls; 58 | return cls; 59 | } 60 | 61 | exports.$setTimeout = function(f, t/*, VARGS */) { 62 | var args = Array.prototype.slice.call(arguments, 2); 63 | return setTimeout(function() { 64 | try { 65 | f.apply(this, args); 66 | } catch(e) { 67 | // log? 68 | } 69 | }, t) 70 | } 71 | 72 | exports.$setInterval = function(f, t/*, VARGS */) { 73 | var args = Array.prototype.slice.call(arguments, 2); 74 | return setInterval(function() { 75 | try { 76 | f.apply(this, args); 77 | } catch(e) { 78 | // log? 79 | } 80 | }, t) 81 | } 82 | 83 | // node doesn't let you call clearTimeout(null) 84 | exports.$clearTimeout = function (timer) { return timer ? clearTimeout(timer) : null; }; 85 | exports.$clearInterval = function (timer) { return timer ? clearInterval(timer) : null; }; 86 | 87 | // keep logging local variables out of other closures in this file! 88 | exports.logging = (function() { 89 | 90 | // logging namespace, this is what is exported 91 | var logging = { 92 | DEBUG: 1, 93 | LOG: 2, 94 | INFO: 3, 95 | WARN: 4, 96 | ERROR: 5 97 | }, 98 | loggers = {}, // effectively globals - all loggers and a global production state 99 | production = false; 100 | 101 | logging.setProduction = function(prod) { production = !!prod; } 102 | logging.get = function(name) { 103 | return loggers.hasOwnProperty(name) ? loggers[name] 104 | : (loggers[name] = new Logger(name)); 105 | } 106 | logging.set = function(name, _logger) { 107 | loggers[name] = _logger; 108 | } 109 | 110 | logging.getAll = function() { return loggers; } 111 | 112 | logging.__create = function(pkg, ctx) { ctx.logger = logging.get(pkg); } 113 | 114 | var Logger = exports.Class(function() { 115 | this.init = function(name, level) { 116 | this._name = name; 117 | this._level = level || logging.LOG; 118 | this._listener = exports.log; 119 | } 120 | 121 | this.setLevel = function(level) { this._level = level; } 122 | 123 | var SLICE = Array.prototype.slice; 124 | 125 | function makeLogFunction(level, type) { 126 | return function() { 127 | if (!production && level >= this._level) { 128 | return this._listener.apply(this._listener, [type, this._name].concat(SLICE.call(arguments))); 129 | } 130 | return arguments[0]; 131 | } 132 | } 133 | 134 | this.setListener = function(listener) { log = listener; } 135 | this.debug = makeLogFunction(logging.DEBUG, "DEBUG"); 136 | this.log = makeLogFunction(logging.LOG, "LOG"); 137 | this.info = makeLogFunction(logging.INFO, "INFO"); 138 | this.warn = makeLogFunction(logging.WARN, "WARN"); 139 | this.error = makeLogFunction(logging.ERROR, "ERROR"); 140 | }); 141 | 142 | return logging; 143 | })(); 144 | 145 | var logger = exports.logging.get('jsiocore'); 146 | -------------------------------------------------------------------------------- /hookbox/js_src/jsio-3.2/index.js: -------------------------------------------------------------------------------- 1 | // This is strictly for nodejs, not browsers. 2 | require('./jsio'); 3 | 4 | -------------------------------------------------------------------------------- /hookbox/js_src/jsio-3.2/lib/Enum.js: -------------------------------------------------------------------------------- 1 | exports = function() { 2 | if (arguments.length == 1) { 3 | if (typeof arguments[0] == 'object') { 4 | var obj = arguments[0]; 5 | for (var i in obj) { 6 | if (!(obj[i] in obj)) { 7 | obj[obj[i]] = i; 8 | } 9 | } 10 | return obj; 11 | } else if (typeof arguments[0] != 'string') { 12 | keys = arguments[0]; 13 | } 14 | } 15 | 16 | if (!keys) { var keys = arguments; } 17 | var obj = {}; 18 | for(var i = 0, len = keys.length; i < len; ++i) { 19 | if (keys[i]) { 20 | obj[keys[i]] = i + 1; 21 | } 22 | obj[i + 1] = keys[i]; 23 | } 24 | return obj; 25 | } -------------------------------------------------------------------------------- /hookbox/js_src/jsio-3.2/lib/Hash.js: -------------------------------------------------------------------------------- 1 | /** 2 | * basic Hash/Set class 3 | * var h = new Hash('a', 'b', 'c'); 4 | * h.contains('a') ==> true 5 | * 6 | * var h = new Hash({a: '1', b: '2', c: '3'}); 7 | * h.contains('1') ==> true 8 | * h.hasKey('a') ==> true 9 | */ 10 | exports = Class(function() { 11 | this.init = function() { 12 | this.m_keys = {}; 13 | this.m_dict = {}; 14 | this.m_values = {}; 15 | if (arguments.length == 1 && typeof arguments == 'object') { 16 | var dict = arguments[0]; 17 | for (var i in dict) { 18 | if (dict.hasOwnProperty(i)) { 19 | this.m_keys[i] = true; 20 | this.m_values[i] = dict[i]; 21 | } 22 | } 23 | } else { 24 | for (var i = 0, len = arguments.length; i < len; i++) { 25 | this.m_keys[arguments[i]] = true; 26 | this.m_values[arguments[i]] = true; 27 | }; 28 | } 29 | } 30 | 31 | this.contains = function(val) { return this.m_values.hasOwnProperty(val); } 32 | this.hasKey = this.containsKey = function(key) { return this.m_keys.hasOwnProperty(key); } 33 | this.each = function(f, ctx) { 34 | for (var i in keys) { 35 | if (this.m_keys.hasOwnProperty(i)) { 36 | f.call(ctx || GLOBAL, i, this.m_values[i], this); 37 | } 38 | } 39 | } 40 | }); 41 | -------------------------------------------------------------------------------- /hookbox/js_src/jsio-3.2/lib/PubSub.js: -------------------------------------------------------------------------------- 1 | var ctx = jsio.__env.global; 2 | 3 | exports = Class(function() { 4 | this.publish = function(signal) { 5 | if(this._subscribers) { 6 | var args = Array.prototype.slice.call(arguments, 1); 7 | if(this._subscribers.__any) { 8 | var anyArgs = [signal].concat(args); 9 | for(var i = 0, sub; sub = this._subscribers.__any[i]; ++i) { 10 | sub.apply(ctx, args); 11 | } 12 | } 13 | 14 | if(!this._subscribers[signal]) { return; } 15 | for(var i = 0, sub; sub = this._subscribers[signal][i]; ++i) { 16 | sub.apply(ctx, args); 17 | } 18 | } 19 | return this; 20 | } 21 | 22 | this.subscribe = function(signal, ctx, method) { 23 | if(!this._subscribers) { this._subscribers = {}; } 24 | if(!this._subscribers[signal]) { this._subscribers[signal] = []; } 25 | var cb = bind.apply(ctx, Array.prototype.slice.call(arguments, 1)); 26 | cb._ctx = ctx; // references for unsubscription 27 | cb._method = method; 28 | this._subscribers[signal].push(cb); 29 | return this; 30 | } 31 | 32 | // if no method is specified, all subscriptions with a callback context of ctx will be removed 33 | this.unsubscribe = function(signal, ctx, method) { 34 | var subs = this._subscribers[signal]; 35 | for (var i = 0, c; c = subs[i]; ++i) { 36 | if (c._ctx == ctx && (!method || c._method == method)) { 37 | subs.splice(i--, 1); 38 | } 39 | } 40 | return this; 41 | } 42 | }); 43 | 44 | -------------------------------------------------------------------------------- /hookbox/js_src/jsio-3.2/logging.js: -------------------------------------------------------------------------------- 1 | exports.UIWatcher = Class(function() { 2 | 3 | }); -------------------------------------------------------------------------------- /hookbox/js_src/jsio-3.2/net.js: -------------------------------------------------------------------------------- 1 | jsio('import net.env'); 2 | jsio('import std.JSON as JSON'); 3 | 4 | JSON.createGlobal(); // create the global JSON object if it doesn't already exist 5 | 6 | exports.listen = function(server, transportName, opts) { 7 | if (!transportName) { 8 | throw logger.error('No transport provided for net.listen'); 9 | } 10 | var listenerClass = net.env.getListener(transportName); 11 | var listener = new listenerClass(server, opts); 12 | listener.listen(); 13 | return listener; 14 | } 15 | 16 | exports.connect = function(protocolInstance, transportName, opts) { 17 | var ctor = net.env.getConnector(transportName), 18 | connector = new ctor(protocolInstance, opts); 19 | 20 | connector.connect(); 21 | return connector; 22 | } 23 | 24 | exports.quickServer = function(protocolClass) { 25 | jsio('import net.interfaces'); 26 | return new net.interfaces.Server(protocolClass); 27 | } 28 | -------------------------------------------------------------------------------- /hookbox/js_src/jsio-3.2/net/buffer.js: -------------------------------------------------------------------------------- 1 | jsio('from net.interfaces import Protocol'); 2 | 3 | var EmptyBufferError = exports.EmptyBufferError = Class(function () { 4 | this.init = function(message) { this.message = message; } 5 | }) 6 | 7 | exports.Buffer = Class(function(supr) { 8 | 9 | this.init = function(rawBuffer) { 10 | 11 | this._rawBuffer = !!rawBuffer ? rawBuffer : ""; 12 | } 13 | 14 | this.getLength = function() { 15 | return this._rawBuffer.length; 16 | } 17 | 18 | this.append = function(data) { 19 | logger.debug('append', JSON.stringify(data)); 20 | this._rawBuffer += data; 21 | } 22 | 23 | this.peekBytes = function(num) { 24 | if (!!num) 25 | return this._rawBuffer.slice(0, num); 26 | else 27 | return this._rawBuffer; 28 | } 29 | 30 | this.peekToDelimiter = function(delimiter) { 31 | delimiter = delimiter ? delimiter : '\n'; 32 | var i = this._rawBuffer.indexOf(delimiter); 33 | if (i == -1) 34 | throw new EmptyBufferError("delimiter " + delimiter + "not present in buffer"); 35 | else 36 | return this._rawBuffer.slice(0, i); 37 | } 38 | 39 | this.consumeBytes = function(num) { 40 | var output = this.peekBytes(num); 41 | this._rawBuffer = this._rawBuffer.slice(output.length); 42 | return output; 43 | } 44 | this.consumeMaxBytes = function(num) { 45 | var output = this._rawBuffer.slice(0, num); 46 | this._rawBuffer = this._rawBuffer(num); 47 | return output; 48 | } 49 | this.consumeAllBytes = function() { 50 | var temp = this._rawBuffer; 51 | this._rawBuffer = ""; 52 | return temp; 53 | } 54 | 55 | this.consumeThroughDelimiter = function(delimiter) { 56 | return this.consumeToDelimiter(delimiter) + this.consumeBytes(delimiter.length); 57 | } 58 | 59 | this.consumeToDelimiter = function(delimiter) { 60 | delimiter = !!delimiter ? delimiter : "\n" 61 | var output = this.peekToDelimiter(delimiter); 62 | this._rawBuffer = this._rawBuffer.slice(output.length); 63 | return output; 64 | } 65 | 66 | this.hasBytes = function(num) { 67 | num = num ? num : 0; 68 | return this._rawBuffer.length >= num; 69 | } 70 | 71 | this.hasDelimiter = function(delimiter) { 72 | delimiter = !!delimiter ? delimiter : '\n'; 73 | return (this._rawBuffer.indexOf(delimiter) != -1); 74 | } 75 | 76 | }) 77 | -------------------------------------------------------------------------------- /hookbox/js_src/jsio-3.2/net/env.js: -------------------------------------------------------------------------------- 1 | function getObj(objectName, transportName, envName) { 2 | try { 3 | jsio('from .env.' + (envName || jsio.__env.name) + '.' + transportName + ' import ' + objectName + ' as result'); 4 | } catch(e) { 5 | throw logger.error('Invalid transport (', transportName, ') or environment (', envName, ')'); 6 | } 7 | return result; 8 | } 9 | 10 | exports.getListener = bind(this, getObj, 'Listener'); 11 | exports.getConnector = bind(this, getObj, 'Connector'); 12 | -------------------------------------------------------------------------------- /hookbox/js_src/jsio-3.2/net/env/browser/csp.js: -------------------------------------------------------------------------------- 1 | jsio('import net.interfaces'); 2 | jsio('from net.csp.client import CometSession'); 3 | jsio('import std.utf8 as utf8'); 4 | 5 | exports.Connector = Class(net.interfaces.Connector, function() { 6 | this.connect = function() { 7 | this._state = net.interfaces.STATE.CONNECTING; 8 | 9 | var conn = new CometSession(); 10 | conn.onconnect = bind(this, 'cometSessionOnConnect', conn); 11 | conn.ondisconnect = bind(this, 'onDisconnect'); 12 | 13 | logger.debug('opening the connection'); 14 | this._opts.encoding = 'plain'; 15 | var url = this._opts.url; 16 | delete this._opts.url; 17 | conn.connect(url, this._opts);//{encoding: 'plain'}); 18 | } 19 | 20 | this.cometSessionOnConnect = function(conn) { 21 | logger.debug('conn has opened'); 22 | this.onConnect(new Transport(conn)); 23 | } 24 | }); 25 | 26 | var Transport = Class(net.interfaces.Transport, function() { 27 | this.init = function(conn) { 28 | this._conn = conn; 29 | } 30 | 31 | this.makeConnection = function(protocol) { 32 | this._conn.onread = bind(protocol, 'dataReceived'); 33 | } 34 | 35 | this.write = function(data) { 36 | this._conn.write(this._encoding == 'utf8' ? utf8.encode(data) : data); 37 | } 38 | 39 | this.loseConnection = function(protocol) { 40 | this._conn.close(); 41 | } 42 | }); 43 | -------------------------------------------------------------------------------- /hookbox/js_src/jsio-3.2/net/env/browser/networkConsole.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 28 | 36 | 37 | 38 |
39 | 40 | 41 |
42 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /hookbox/js_src/jsio-3.2/net/env/browser/postmessage.js: -------------------------------------------------------------------------------- 1 | jsio('import net.interfaces'); 2 | jsio('from util.browser import $'); 3 | 4 | exports.Listener = Class(net.interfaces.Listener, function(supr) { 5 | var ID = 0; 6 | 7 | this.init = function() { 8 | supr(this, 'init', arguments); 9 | this._clients = {}; 10 | if (!this._opts.clientUrl) { 11 | this._opts.clientUrl = jsio.__dir + '/networkConsole.html'; 12 | } 13 | } 14 | 15 | this.listen = function() { 16 | $.onEvent(window, 'message', bind(this, '_onMessage')); 17 | } 18 | 19 | this.getButton = function(url, text) { 20 | var button = document.createElement('button'); 21 | button.className = 'clientButton'; 22 | button.innerHTML = text || 'launch client'; 23 | $.onEvent(button, 'click', bind(this, '_openWindow', url)); 24 | return button; 25 | } 26 | 27 | var uniqueId = 1; 28 | this._openWindow = function(url) { 29 | var options = { menubar: 'no', location: 'no', toolbar: 'no', 30 | width: 550, height: 350, // left: 200, top: 200, 31 | scrollbars: 'yes', status: 'yes', resizable: 'yes' }; 32 | 33 | var arr = []; 34 | for (var i in options) { arr.push(i + '=' + options[i]) } 35 | var win = window.open(url, 'W' + uniqueId++, arr.join(',')); 36 | win.focus(); 37 | } 38 | 39 | this._onMessage = function(evt) { 40 | var name = evt.source.name; 41 | var target = this._clients[name]; 42 | var data = eval('(' + evt.data + ')'); 43 | switch (data.type) { 44 | case 'open': 45 | this._clients[name] = new exports.Transport(evt.source); 46 | evt.source.postMessage('{type:"open"}','*'); 47 | this.onConnect(this._clients[name]); 48 | break; 49 | case 'data': 50 | target.onData(data.payload); 51 | break; 52 | case 'close': 53 | target.onClose(); 54 | evt.source.postMessage('{type:"close"}','*'); 55 | delete this._clients[name]; 56 | break; 57 | } 58 | } 59 | }); 60 | 61 | exports.Connector = Class(net.interfaces.Connector, function() { 62 | this.connect = function() { 63 | $.onEvent(window, 'message', bind(this, '_onMessage')); 64 | window.opener.postMessage(JSON.stringify({type:"open"}), '*'); 65 | } 66 | 67 | this._onMessage = function(evt) { 68 | var data = eval('(' + evt.data + ')'); 69 | switch(data.type) { 70 | case 'open': 71 | this._transport = new exports.Transport(evt.source); 72 | this.onConnect(this._transport); 73 | break; 74 | case 'close': 75 | this._transport.onClose(); 76 | break; 77 | case 'data': 78 | this._transport.onData(data.payload); 79 | break; 80 | } 81 | } 82 | }); 83 | 84 | exports.Transport = Class(net.interfaces.Transport, function() { 85 | this.init = function(win) { 86 | this._win = win; 87 | } 88 | 89 | this.makeConnection = function(protocol) { 90 | this._protocol = protocol; 91 | } 92 | 93 | this.write = function(data, encoding) { 94 | if (this.encoding == 'utf8') { 95 | this._win.postMessage(JSON.stringify({type: 'data', payload: utf8.encode(data)}), '*'); 96 | } else { 97 | this._win.postMessage(JSON.stringify({type: 'data', payload: data}), '*'); 98 | } 99 | } 100 | 101 | this.loseConnection = function(protocol) { 102 | this._win.postMessage(JSON.stringify({type: 'close', code: 301}), '*'); 103 | } 104 | 105 | this.onData = function() { this._protocol.dataReceived.apply(this._protocol, arguments); } 106 | this.onClose = function() { this._protocol.connectionLost.apply(this._protocol, arguments); } 107 | }); 108 | -------------------------------------------------------------------------------- /hookbox/js_src/jsio-3.2/net/env/browser/websocket.js: -------------------------------------------------------------------------------- 1 | jsio('import net.interfaces'); 2 | jsio('import std.utf8 as utf8'); 3 | jsio('import net.errors as Errors'); 4 | 5 | exports.Connector = Class(net.interfaces.Connector, function() { 6 | this.connect = function() { 7 | this._state = net.interfaces.STATE.CONNECTING; 8 | 9 | var url = this._opts.url, 10 | ctor = this._opts.wsConstructor || window.WebSocket; 11 | 12 | logger.info('this._opts', this._opts); 13 | 14 | var ws = new ctor(url); 15 | ws.onopen = bind(this, 'webSocketOnOpen', ws); 16 | ws.onclose = bind(this, 'webSocketOnClose', ws); 17 | } 18 | 19 | this.webSocketOnOpen = function(ws) { 20 | this.onConnect(new Transport(ws)); 21 | } 22 | 23 | this.webSocketOnClose = function(ws, e) { 24 | var err, 25 | data = {rawError: e, webSocket: ws}; 26 | if (e.wasClean) { 27 | err = new Errors.ServerClosedConnection('WebSocket Connection Closed', data); 28 | } else { 29 | if (this._state == net.interfaces.STATE.CONNECTED) { 30 | err = new Errors.ConnectionTimeout('WebSocket Connection Timed Out', data); 31 | } else { 32 | err = new Errors.ServerUnreachable('WebSocket Connection Failed', data); 33 | } 34 | } 35 | 36 | logger.debug('conn closed', err); 37 | this.onDisconnect(err); 38 | } 39 | }); 40 | 41 | var Transport = Class(net.interfaces.Transport, function() { 42 | 43 | this.init = function(ws) { 44 | this._ws = ws; 45 | } 46 | 47 | this.makeConnection = function(protocol) { 48 | this._ws.onmessage = function(data) { 49 | var payload = utf8.encode(data.data); 50 | protocol.dataReceived(payload); 51 | } 52 | } 53 | 54 | this.write = function(data, encoding) { 55 | if (this._encoding == 'plain') { 56 | result = utf8.decode(data); 57 | data = result[0]; 58 | } 59 | this._ws.send(data); 60 | } 61 | 62 | this.loseConnection = function(protocol) { 63 | this._ws.close(); 64 | } 65 | }); 66 | -------------------------------------------------------------------------------- /hookbox/js_src/jsio-3.2/net/env/node/csp.js: -------------------------------------------------------------------------------- 1 | jsio('import net.interfaces'); 2 | jsio('from .csp.server import createServer'); 3 | 4 | var Transport = Class(net.interfaces.Transport, function() { 5 | this.init = function(socket) { 6 | this._socket = socket; 7 | logger.debug('init', socket); 8 | } 9 | 10 | this.makeConnection = function(protocol) { 11 | logger.debug('makeConnection:', protocol); 12 | this._socket.addListener("receive", bind(protocol, 'dataReceived')); 13 | 14 | this._socket.addListener("eof", this._socket.close); 15 | this._socket.addListener("close", bind(protocol, 'connectionLost')); // TODO: map error codes 16 | } 17 | 18 | this.write = function(data) { 19 | this._socket.send(data); 20 | } 21 | 22 | this.loseConnection = function() { 23 | this._socket.forceClose(); 24 | } 25 | }); 26 | 27 | exports.Listener = Class(net.interfaces.Listener, function(supr) { 28 | this.listen = function() { 29 | var s = createServer(bind(this, function(socket) { 30 | logger.info("Incoming connection"); 31 | socket.setEncoding("utf8"); 32 | socket.addListener("connect", bind(this, function() { 33 | this.onConnect(new Transport(socket)); 34 | })); 35 | })); 36 | this._cspServer = s; 37 | var listenString = (this._opts.interface || "" ) + ":" + this._opts.port; 38 | // TODO: Show class name 39 | if (!this._opts.skipListen) { 40 | logger.info("Listening csp@" + listenString); 41 | s.listen(this._opts.port, this._opts.interface || ""); 42 | } 43 | } 44 | }); 45 | -------------------------------------------------------------------------------- /hookbox/js_src/jsio-3.2/net/env/node/csp/util.js: -------------------------------------------------------------------------------- 1 | /* 2 | Helper functions, &c., for a comet server by Jacob Rus. 3 | 4 | -------------------- 5 | 6 | Copyright (c) 2009 Jacob Rus 7 | 8 | Permission is hereby granted, free of charge, to any person 9 | obtaining a copy of this software and associated documentation 10 | files (the "Software"), to deal in the Software without 11 | restriction, including without limitation the rights to use, 12 | copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | copies of the Software, and to permit persons to whom the 14 | Software is furnished to do so, subject to the following 15 | conditions: 16 | 17 | The above copyright notice and this permission notice shall be 18 | included in all copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 21 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 22 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 23 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 24 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 25 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 26 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 27 | OTHER DEALINGS IN THE SOFTWARE. 28 | */ 29 | 30 | // helper to test if string 2 is at the beginning of string 1 31 | exports.startswith = function (str1, str2) { 32 | return str1.substring(0, str2.length) == str2; 33 | }; 34 | 35 | exports.JSIOError = Class(Error, function () { 36 | this.name = 'JSIOError'; 37 | this.toString = Error.prototype.toString; 38 | this.init = function (message, fileName, lineNumber) { 39 | this.name = this.name; // promote class property to instance 40 | this.message = message || ''; 41 | this.fileName = fileName || '«filename»'; // location.href; // XXX what should go here? 42 | this.lineNumber = isNaN(+lineNumber) ? 0 : +lineNumber 43 | }; 44 | }); 45 | 46 | exports.AssertionError = Class(exports.JSIOError, function (supr) { 47 | this.name = 'AssertionError' 48 | this.init = function () {supr(this, 'init', arguments)} 49 | }); 50 | 51 | exports.assert = function (exp, message) { 52 | if (!exp) { 53 | throw new exports.AssertionError(message) 54 | }; 55 | }; 56 | 57 | // schedule a callback to run at the next available moment, 58 | // equivalent to setTimeout(callback, 0) 59 | exports.reschedule = function (callback) { 60 | return $setTimeout(callback, 0); 61 | }; 62 | 63 | // cached static files 64 | exports.staticFile = (function(){ 65 | var cache = {} // static file content indexed by filename 66 | var getfile = function(path, callback) { 67 | cacheContent = cache[path]; 68 | if (cacheContent !== undefined) { 69 | // the file is in the cache, return it 70 | exports.reschedule(function(){ 71 | callback(null, [cacheContent]); 72 | }); 73 | } else { 74 | // load file from disk, save it in the cache, and return it 75 | process.fs.readFile(path, 'utf8', function(err, fileContent){ 76 | if (err) { 77 | callback('staticFile readFile error ' + err) 78 | } else { 79 | cache[path] = fileContent; 80 | callback(null, [fileContent]); 81 | } 82 | }) 83 | }; 84 | return promise; 85 | }; 86 | return getfile; 87 | })(); 88 | -------------------------------------------------------------------------------- /hookbox/js_src/jsio-3.2/net/env/node/tcp.js: -------------------------------------------------------------------------------- 1 | jsio('import net.interfaces'); 2 | 3 | var nodeTcp = jsio.__env.require('net'); 4 | 5 | var Transport = Class(net.interfaces.Transport, function() { 6 | this.init = function(socket) { 7 | this._socket = socket; 8 | } 9 | 10 | this.makeConnection = function(protocol) { 11 | this._socket.addListener("data", bind(protocol, 'dataReceived')); 12 | this._socket.addListener("close", bind(protocol, 'connectionLost')); // TODO: map error codes 13 | this._socket.addListener("end", this._socket.close); 14 | } 15 | 16 | this.write = function(data) { 17 | this._socket.write(data); 18 | } 19 | 20 | this.loseConnection = function() { 21 | this._socket.forceClose(); 22 | } 23 | }); 24 | 25 | 26 | exports.Connector = Class(net.interfaces.Connector, function() { 27 | this.connect = function() { 28 | 29 | var conn = nodeTcp.createConnection(this._opts.port, this._opts.host); 30 | conn.addListener("connect", bind(this, function() { 31 | this.onConnect(new Transport(conn)); 32 | })) 33 | // conn.addListener("close", bind(this, function() { 34 | // this.onDisconnect(); 35 | // })) 36 | // conn.addListener("receive", bind(this._protocol, 'dataReceived')); 37 | this._opts.encoding = 'plain'; 38 | conn.setEncoding("binary"); 39 | if (typeof this._opts.timeout == 'number') { conn.setTimeout(this._opts.timeout); } 40 | } 41 | }); 42 | 43 | exports.Listener = Class(net.interfaces.Listener, function(supr) { 44 | this.listen = function() { 45 | var s = nodeTcp.createServer(bind(this, function(socket) { 46 | if (typeof this._opts.timeout == 'number') { socket.setTimeout(this._opts.timeout) } 47 | socket.setEncoding("utf8"); 48 | socket.addListener("connect", bind(this, function() { 49 | this.onConnect(new Transport(socket)); 50 | })); 51 | })); 52 | var listenString = (this._opts.interface || "" ) + ":" + this._opts.port; 53 | // TODO: Show class name 54 | logger.info("Listening tcp@" + listenString); 55 | s.listen(this._opts.port, this._opts.interface || ""); 56 | } 57 | }); 58 | -------------------------------------------------------------------------------- /hookbox/js_src/jsio-3.2/net/errors.js: -------------------------------------------------------------------------------- 1 | var makeErrorClass = function(name, _code) { 2 | var toString = function() { 3 | return name + (this.message ? ': ' + this.message : ''); 4 | } 5 | 6 | var ctor = function(data) { 7 | if (typeof data == 'string') { 8 | this.message = data; 9 | } else { 10 | this.data = data; 11 | } 12 | } 13 | 14 | ctor.prototype = { 15 | type: name, 16 | toString: toString 17 | }; 18 | 19 | return ctor; 20 | } 21 | 22 | exports.ReadyStateError = makeErrorClass("ReadyStateError"); 23 | exports.InvalidEncodingError = makeErrorClass("InvalidEncodingError"); 24 | exports.ExpiredSession = makeErrorClass("ExpiredSession"); 25 | 26 | exports.ServerUnreachable = makeErrorClass("ServerUnreachable", 100); 27 | exports.ConnectionTimeout = makeErrorClass("ConnectionTimeout", 101); 28 | 29 | exports.ServerProtocolError = makeErrorClass("ServerProtocolError", 200); 30 | 31 | exports.ServerClosedConnection = makeErrorClass("ServerClosedConnection", 301); 32 | exports.ConnectionClosedCleanly = makeErrorClass("ConnectionClosedCleanly", 300); -------------------------------------------------------------------------------- /hookbox/js_src/jsio-3.2/net/interfaces.js: -------------------------------------------------------------------------------- 1 | // Sort of like a twisted protocol 2 | jsio('import net'); 3 | jsio('import lib.Enum as Enum'); 4 | 5 | var ctx = jsio.__env.global; 6 | 7 | exports.Protocol = Class(function() { 8 | this.connectionMade = function(isReconnect) {} 9 | this.dataReceived = function(data) {} 10 | this.connectionLost = function(reason) {} 11 | }); 12 | 13 | exports.Client = Class(function() { 14 | this.init = function(protocol) { 15 | this._protocol = protocol; 16 | } 17 | 18 | this.connect = function(transportName, opts) { 19 | this._remote = new this._protocol(); 20 | this._remote._client = this; 21 | net.connect(this._remote, transportName, opts); 22 | } 23 | }); 24 | 25 | // Sort of like a twisted factory 26 | exports.Server = Class(function() { 27 | this.init = function(protocolClass) { 28 | this._protocolClass = protocolClass; 29 | } 30 | 31 | this.buildProtocol = function() { 32 | return new this._protocolClass(); 33 | } 34 | 35 | this.listen = function(how, port) { 36 | return net.listen(this, how, port); 37 | } 38 | }); 39 | 40 | exports.Transport = Class(function() { 41 | this._encoding = 'plain' 42 | this.write = function(data, encoding) { 43 | throw new Error("Not implemented"); 44 | } 45 | this.getPeer = function() { 46 | throw new Error("Not implemented"); 47 | } 48 | this.setEncoding = function(encoding) { 49 | this._encoding = encoding; 50 | } 51 | this.getEncoding = function() { 52 | return this._encoding; 53 | } 54 | }); 55 | 56 | exports.Listener = Class(function() { 57 | this.init = function(server, opts) { 58 | this._server = server; 59 | this._opts = opts || {}; 60 | } 61 | 62 | this.onConnect = function(transport) { 63 | // try { 64 | var p = this._server.buildProtocol(); 65 | p.transport = transport; 66 | p.server = this._server; 67 | transport.protocol = p; 68 | transport.makeConnection(p); 69 | p.connectionMade(); 70 | // } catch(e) { 71 | // logger.error(e); 72 | // } 73 | } 74 | 75 | this.listen = function() { throw new Error('Abstract class'); } 76 | this.stop = function() {} 77 | }); 78 | 79 | exports.STATE = Enum('INITIAL', 'DISCONNECTED', 'CONNECTING', 'CONNECTED'); 80 | exports.Connector = Class(function() { 81 | this.init = function(protocol, opts) { 82 | this._protocol = protocol; 83 | this._opts = opts; 84 | this._state = exports.STATE.INITIAL; 85 | } 86 | 87 | this.onConnect = function(transport) { 88 | this._state = exports.STATE.CONNECTED; 89 | 90 | transport.makeConnection(this._protocol); 91 | this._protocol.transport = transport; 92 | try { 93 | this._protocol.connectionMade(); 94 | } catch(e) { 95 | throw logger.error(e); 96 | } 97 | } 98 | 99 | this.onDisconnect = function(err) { 100 | var wasConnected = this._state == exports.STATE.CONNECTED; 101 | this._state = exports.STATE.DISCONNECTED; 102 | 103 | try { 104 | this._protocol.connectionLost(err, wasConnected); 105 | } catch(e) { 106 | throw logger.error(e); 107 | } 108 | } 109 | 110 | this.getProtocol = function() { return this._protocol; } 111 | }); 112 | -------------------------------------------------------------------------------- /hookbox/js_src/jsio-3.2/net/later.js: -------------------------------------------------------------------------------- 1 | exports.Later = Class(function() { 2 | this.init = function() { 3 | this.cb = null 4 | this.eb = null 5 | this.values = [] 6 | this.errors = [] 7 | this.cancelback = null; 8 | } 9 | 10 | this.succeed = function(data) { 11 | this.callback(data); 12 | } 13 | 14 | this.callback = function() { 15 | logger.debug('callback', [].slice.call(arguments, 0)); 16 | if (this.cb) { 17 | var result = this.cb.apply(this, arguments); 18 | if (result == false) { 19 | this.cancel(); 20 | } 21 | } else { 22 | this.values.push(arguments); 23 | } 24 | } 25 | 26 | this.errback = function() { 27 | logger.debug('eb', [].slice.call(arguments, 0)); 28 | if (this.eb) { 29 | this.eb.apply(this, arguments); 30 | } 31 | else { 32 | this.errors.push(arguments); 33 | } 34 | } 35 | 36 | this.cancel = function() { 37 | if (this.cancelback) { 38 | var cb = this.cancelback; 39 | this.cancelback = null; 40 | cb.call(this); 41 | } 42 | } 43 | this.setCallback = function(cb) { 44 | this.cb = cb; 45 | for (var i = 0, v; v=this.values[i]; ++i) { 46 | this.cb.apply(this, v); 47 | } 48 | this.values = []; 49 | return this; 50 | } 51 | this.setErrback = function(eb) { 52 | this.eb = eb; 53 | for (var i = 0, v; e=this.errors[i]; ++i) { 54 | this.eb.apply(this, e); 55 | } 56 | this.errors = []; 57 | return this; 58 | } 59 | this.setCancelback = function(cancelback) { 60 | this.cancelback = cancelback; 61 | return this; 62 | } 63 | }) 64 | -------------------------------------------------------------------------------- /hookbox/js_src/jsio-3.2/net/protocols/buffered.js: -------------------------------------------------------------------------------- 1 | jsio('from net.interfaces import Protocol'); 2 | jsio('from net.buffer import Buffer'); 3 | 4 | exports.BufferedProtocol = Class(Protocol, function(supr) { 5 | 6 | this.init = function() { 7 | this.buffer = new Buffer(); 8 | } 9 | 10 | // Overwrite this instead of dataReceived in base classes 11 | this.bufferUpdated = function() {} 12 | 13 | this.dataReceived = function(data) { 14 | this.buffer.append(data); 15 | this.bufferUpdated(); 16 | } 17 | 18 | }) -------------------------------------------------------------------------------- /hookbox/js_src/jsio-3.2/net/protocols/delimited.js: -------------------------------------------------------------------------------- 1 | jsio('import net.interfaces'); 2 | 3 | exports.DelimitedProtocol = Class(net.interfaces.Protocol, function(supr) { 4 | 5 | this.init = function(delimiter) { 6 | if (!delimiter) { 7 | delimiter = '\r\n' 8 | } 9 | this.delimiter = delimiter; 10 | this.buffer = "" 11 | } 12 | 13 | this.connectionMade = function() { 14 | logger.debug('connectionMade'); 15 | } 16 | 17 | this.dataReceived = function(data) { 18 | if (!data) { return; } 19 | logger.debug('dataReceived:(' + data.length + ')', data); 20 | logger.debug('last 2:', data.slice(data.length-2)); 21 | this.buffer += data; 22 | logger.debug('index', this.buffer.indexOf(this.delimiter)); 23 | var i; 24 | while ((i = this.buffer.indexOf(this.delimiter)) != -1) { 25 | var line = this.buffer.slice(0, i); 26 | this.buffer = this.buffer.slice(i + this.delimiter.length); 27 | this.lineReceived(line); 28 | } 29 | } 30 | 31 | this.lineReceived = function(line) { 32 | logger.debug('Not implemented, lineReceived:', line); 33 | } 34 | this.sendLine = function(line) { 35 | logger.debug('WRITE:', line + this.delimiter); 36 | this.transport.write(line + this.delimiter); 37 | } 38 | this.connectionLost = function() { 39 | logger.debug('connectionLost'); 40 | } 41 | }); 42 | 43 | -------------------------------------------------------------------------------- /hookbox/js_src/jsio-3.2/net/protocols/echo.js: -------------------------------------------------------------------------------- 1 | jsio('import net.interfaces'); 2 | 3 | exports.Protocol = Class(net.interfaces.Protocol, function() { 4 | this.connectionMade = function() { 5 | logger.debug('in connectionMade'); 6 | this.transport.write('Welcome') 7 | } 8 | 9 | this.dataReceived = function(data) { 10 | logger.debug('dataReceived:', data); 11 | this.transport.write('Echo: ' + data); 12 | } 13 | this.connectionLost = function() { 14 | logger.debug('conn lost'); 15 | } 16 | }); 17 | 18 | exports.Server = Class(net.interfaces.Server, function(supr) { 19 | this.init = function() { 20 | supr(this, 'init', [exports.Protocol]); 21 | } 22 | }); 23 | 24 | -------------------------------------------------------------------------------- /hookbox/js_src/jsio-3.2/net/protocols/rtjp.js: -------------------------------------------------------------------------------- 1 | jsio('import net.interfaces'); 2 | jsio('from net.protocols.delimited import DelimitedProtocol'); 3 | 4 | exports.RTJPProtocol = Class(DelimitedProtocol, function(supr) { 5 | this.init = function() { 6 | var delimiter = '\r\n'; 7 | supr(this, 'init', [delimiter]); 8 | this.frameId = 0; 9 | } 10 | 11 | this.connectionMade = function() { 12 | logger.debug("connectionMade"); 13 | } 14 | 15 | var error = function(e) { 16 | logger.error(e); 17 | } 18 | 19 | // Inherit and overwrite 20 | this.frameReceived = function(id, name, args) { 21 | } 22 | 23 | // Public 24 | this.sendFrame = function(name, args) { 25 | if (!args) { 26 | args = {} 27 | } 28 | logger.debug('sendFrame', name, args); 29 | this.sendLine(JSON.stringify([++this.frameId, name, args])); 30 | return this.frameId; 31 | } 32 | 33 | this.lineReceived = function(line) { 34 | try { 35 | var frame = JSON.parse(line); 36 | if (frame.length != 3) { 37 | return error.call(this, "Invalid frame length"); 38 | } 39 | if (typeof(frame[0]) != "number") { 40 | return error.call(this, "Invalid frame id"); 41 | } 42 | if (typeof(frame[1]) != "string") { 43 | return error.call(this, "Invalid frame name"); 44 | } 45 | logger.debug("frameReceived:", frame[0], frame[1], frame[2]); 46 | this.frameReceived(frame[0], frame[1], frame[2]); 47 | } catch(e) { 48 | error.call(this, e); 49 | } 50 | } 51 | 52 | this.connectionLost = function() { 53 | logger.debug('conn lost'); 54 | } 55 | }); 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /hookbox/js_src/jsio-3.2/std/base64.js: -------------------------------------------------------------------------------- 1 | /* 2 | "URL-safe" Base64 Codec, by Jacob Rus 3 | 4 | This library happily strips off as many trailing '=' as are included in the 5 | input to 'decode', and doesn't worry whether its length is an even multiple 6 | of 4. It does not include trailing '=' in its own output. It uses the 7 | 'URL safe' base64 alphabet, where the last two characters are '-' and '_'. 8 | 9 | -------------------- 10 | 11 | Copyright (c) 2009 Jacob Rus 12 | 13 | Permission is hereby granted, free of charge, to any person 14 | obtaining a copy of this software and associated documentation 15 | files (the "Software"), to deal in the Software without 16 | restriction, including without limitation the rights to use, 17 | copy, modify, merge, publish, distribute, sublicense, and/or sell 18 | copies of the Software, and to permit persons to whom the 19 | Software is furnished to do so, subject to the following 20 | conditions: 21 | 22 | The above copyright notice and this permission notice shall be 23 | included in all copies or substantial portions of the Software. 24 | 25 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 27 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 28 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 29 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 30 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 31 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 32 | OTHER DEALINGS IN THE SOFTWARE. 33 | */ 34 | 35 | var alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'; 36 | var pad = '='; 37 | var padChar = alphabet.charAt(alphabet.length - 1); 38 | 39 | var shorten = function (array, number) { 40 | // remove 'number' characters from the end of 'array', in place (no return) 41 | for (var i = number; i > 0; i--){ array.pop(); }; 42 | }; 43 | 44 | var decode_map = {}; 45 | for (var i=0, n=alphabet.length; i < n; i++) { 46 | decode_map[alphabet.charAt(i)] = i; 47 | }; 48 | 49 | 50 | // use this regexp in the decode function to sniff out invalid characters. 51 | var alphabet_inverse = new RegExp('[^' + alphabet.replace('-', '\\-') + ']'); 52 | 53 | 54 | 55 | var Base64CodecError = exports.Base64CodecError = function (message) { 56 | this.message = message; 57 | }; 58 | Base64CodecError.prototype.toString = function () { 59 | return 'Base64CodecError' + (this.message ? ': ' + this.message : ''); 60 | }; 61 | 62 | var assertOrBadInput = function (exp, message) { 63 | if (!exp) { throw new Base64CodecError(message) }; 64 | }; 65 | 66 | exports.encode = function (bytes) { 67 | assertOrBadInput(!(/[^\x00-\xFF]/.test(bytes)), // disallow two-byte chars 68 | 'Input contains out-of-range characters.'); 69 | var padding = '\x00\x00\x00'.slice((bytes.length % 3) || 3); 70 | bytes += padding; // pad with null bytes 71 | var out_array = []; 72 | for (var i=0, n=bytes.length; i < n; i+=3) { 73 | var newchars = ( 74 | (bytes.charCodeAt(i) << 020) + 75 | (bytes.charCodeAt(i+1) << 010) + 76 | (bytes.charCodeAt(i+2))); 77 | out_array.push( 78 | alphabet.charAt((newchars >> 18) & 077), 79 | alphabet.charAt((newchars >> 12) & 077), 80 | alphabet.charAt((newchars >> 6) & 077), 81 | alphabet.charAt((newchars) & 077)); 82 | }; 83 | shorten(out_array, padding.length); 84 | return out_array.join(''); 85 | }; 86 | 87 | exports.decode = function (b64text) { 88 | logger.debug('decode', b64text); 89 | b64text = b64text.replace(/\s/g, '') // kill whitespace 90 | // strip trailing pad characters from input; // XXX maybe some better way? 91 | var i = b64text.length; while (b64text.charAt(--i) === pad) {}; b64text = b64text.slice(0, i + 1); 92 | assertOrBadInput(!alphabet_inverse.test(b64text), 'Input contains out-of-range characters.'); 93 | var padding = Array(5 - ((b64text.length % 4) || 4)).join(padChar); 94 | b64text += padding; // pad with last letter of alphabet 95 | var out_array = []; 96 | for (var i=0, n=b64text.length; i < n; i+=4) { 97 | newchars = ( 98 | (decode_map[b64text.charAt(i)] << 18) + 99 | (decode_map[b64text.charAt(i+1)] << 12) + 100 | (decode_map[b64text.charAt(i+2)] << 6) + 101 | (decode_map[b64text.charAt(i+3)])); 102 | out_array.push( 103 | (newchars >> 020) & 0xFF, 104 | (newchars >> 010) & 0xFF, 105 | (newchars) & 0xFF); 106 | }; 107 | shorten(out_array, padding.length); 108 | var result = String.fromCharCode.apply(String, out_array); 109 | logger.debug('decoded', result); 110 | return result; 111 | }; 112 | -------------------------------------------------------------------------------- /hookbox/js_src/jsio-3.2/std/js.js: -------------------------------------------------------------------------------- 1 | exports.vargs = function(args, n) { return Array.prototype.slice.call(args, n || 0); } 2 | exports.isArray = function(input) { return Object.prototype.toString.call(input) === '[object Array]'; } 3 | 4 | exports.shallowCopy = function(input) { 5 | if (exports.isArray(input)) { 6 | return input.slice(0); 7 | } else { 8 | var out = {}; 9 | for (var key in input) { 10 | if (input.hasOwnProperty(key)) { 11 | out[key] = input[key]; 12 | } 13 | } 14 | } 15 | 16 | return out; 17 | } 18 | 19 | exports.merge = function(base, extra) { 20 | base = base || {}; 21 | 22 | for (var key in extra) { 23 | if (extra.hasOwnProperty(key) && !base.hasOwnProperty(key)) { 24 | base[key] = extra[key]; 25 | } 26 | } 27 | 28 | return base; 29 | } -------------------------------------------------------------------------------- /hookbox/js_src/jsio-3.2/std/uri.js: -------------------------------------------------------------------------------- 1 | var attrs = [ 2 | "source", 3 | "protocol", 4 | "authority", 5 | "userInfo", 6 | "user", 7 | "password", 8 | "host", 9 | "port", 10 | "relative", 11 | "path", 12 | "directory", 13 | "file", 14 | "query", 15 | "anchor" 16 | ]; 17 | 18 | exports.Uri = Class(function(supr) { 19 | this.init = function(url, isStrict) { 20 | var uriData = exports.parse(url, isStrict) 21 | for (attr in uriData) { 22 | this['_' + attr] = uriData[attr]; 23 | }; 24 | }; 25 | 26 | for (var i = 0, attr; attr = attrs[i]; ++i) { 27 | (function(attr) { 28 | var fNameSuffix = attr.charAt(0).toUpperCase() + attr.slice(1); 29 | this['get' + fNameSuffix] = function() { 30 | return this['_' + attr]; 31 | }; 32 | this['set' + fNameSuffix] = function(val) { 33 | this['_' + attr] = val; 34 | }; 35 | }).call(this, attr); 36 | }; 37 | 38 | this.toString = this.render = function() { 39 | // XXX TODO: This is vaguely reasonable, but not complete. fix it... 40 | var a = this._protocol ? this._protocol + "://" : "" 41 | var b = this._host ? this._host + ((this._port || 80) == 80 ? "" : ":" + this._port) : ""; 42 | var c = this._path; 43 | var d = this._query ? '?' + this._query : ''; 44 | var e = this._anchor ? '#' + this._anchor : ''; 45 | return a + b + c + d + e; 46 | }; 47 | }); 48 | 49 | exports.buildQuery = function(kvp) { 50 | var pairs = []; 51 | for (key in kvp) { 52 | pairs.push(encodeURIComponent(key) + '=' + encodeURIComponent(kvp[key])); 53 | } 54 | return pairs.join('&'); 55 | } 56 | 57 | exports.parseQuery = function(str) { 58 | var pairs = str.split('&'), 59 | n = pairs.length, 60 | data = {}; 61 | for (var i = 0; i < n; ++i) { 62 | var pair = pairs[i].split('='), 63 | key = decodeURIComponent(pair[0]); 64 | if (key) { data[key] = decodeURIComponent(pair[1]); } 65 | } 66 | return data; 67 | } 68 | 69 | // Regexs are based on parseUri 1.2.2 70 | // Original: (c) Steven Levithan 71 | // Original: MIT License 72 | 73 | var strictRegex = /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/; 74 | var looseRegex = /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/; 75 | var queryStringRegex = /(?:^|&)([^&=]*)=?([^&]*)/g; 76 | 77 | exports.parse = function(str, isStrict) { 78 | var regex = isStrict ? strictRegex : looseRegex; 79 | var result = {}; 80 | var match = regex.exec(str); 81 | for (var i = 0, attr; attr = attrs[i]; ++i) { 82 | result[attr] = match[i] || ""; 83 | } 84 | 85 | var qs = result['queryKey'] = {}; 86 | result['query'].replace(queryStringRegex, function(check, key, val) { 87 | if (check) { 88 | qs[key] = val; 89 | } 90 | }); 91 | 92 | return result; 93 | } 94 | 95 | exports.isSameDomain = function(urlA, urlB) { 96 | var a = exports.parse(urlA); 97 | var b = exports.parse(urlB); 98 | return ((a.port == b.port ) && (a.host == b.host) && (a.protocol == b.protocol)); 99 | }; 100 | -------------------------------------------------------------------------------- /hookbox/js_src/jsio-3.2/std/utf8.js: -------------------------------------------------------------------------------- 1 | /* 2 | Fast incremental JavaScript UTF-8 encoder/decoder, by Jacob Rus. 3 | 4 | API for decode from Orbited: as far as I know, the first incremental 5 | JavaScript UTF-8 decoder. 6 | 7 | Inspired by the observation by Johan Sundström published at: 8 | http://ecmanaut.blogspot.com/2006/07/encoding-decoding-utf8-in-javascript.html 9 | 10 | Note that this code throws an error for invalid UTF-8. Because it is so much 11 | faster than previous implementations, the recommended way to do lenient 12 | parsing is to first try this decoder, and then fall back on a slower lenient 13 | decoder if necessary for the particular use case. 14 | 15 | -------------------- 16 | 17 | Copyright (c) 2009 Jacob Rus 18 | 19 | Permission is hereby granted, free of charge, to any person 20 | obtaining a copy of this software and associated documentation 21 | files (the "Software"), to deal in the Software without 22 | restriction, including without limitation the rights to use, 23 | copy, modify, merge, publish, distribute, sublicense, and/or sell 24 | copies of the Software, and to permit persons to whom the 25 | Software is furnished to do so, subject to the following 26 | conditions: 27 | 28 | The above copyright notice and this permission notice shall be 29 | included in all copies or substantial portions of the Software. 30 | 31 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 32 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 33 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 34 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 35 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 36 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 37 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 38 | OTHER DEALINGS IN THE SOFTWARE. 39 | */ 40 | //var utf8 = this.utf8 = exports; 41 | 42 | exports.UnicodeCodecError = function (message) { 43 | this.message = message; 44 | }; 45 | 46 | var UnicodeCodecError = exports.UnicodeCodecError; 47 | 48 | UnicodeCodecError.prototype.toString = function () { 49 | return 'UnicodeCodecError' + (this.message ? ': ' + this.message : ''); 50 | }; 51 | 52 | exports.encode = function (unicode_string) { 53 | // Unicode encoder: Given an arbitrary unicode string, returns a string 54 | // of characters with code points in range 0x00 - 0xFF corresponding to 55 | // the bytes of the utf-8 representation of those characters. 56 | try { 57 | return unescape(encodeURIComponent(unicode_string)); 58 | } 59 | catch (err) { 60 | throw new UnicodeCodecError('invalid input string'); 61 | }; 62 | }; 63 | exports.decode = function (bytes) { 64 | // Unicode decoder: Given a string of characters with code points in 65 | // range 0x00 - 0xFF, which, when interpreted as bytes, are valid UTF-8, 66 | // returns the corresponding Unicode string, along with the number of 67 | // bytes in the input string which were successfully parsed. 68 | // 69 | // Unlike most JavaScript utf-8 encode/decode implementations, properly 70 | // deals with partial multi-byte characters at the end of the byte string. 71 | if (/[^\x00-\xFF]/.test(bytes)) { 72 | throw new UnicodeCodecError('invalid utf-8 bytes'); 73 | }; 74 | var len, len_parsed; 75 | len = len_parsed = bytes.length; 76 | var last = len - 1; 77 | // test for non-ascii final byte. if last byte is ascii (00-7F) we're done. 78 | if (bytes.charCodeAt(last) >= 0x80) { 79 | // loop through last 3 bytes looking for first initial byte of unicode 80 | // multi-byte character. If the initial byte is 4th from the end, we'll 81 | // parse the whole string. 82 | for (var i = 1; i <= 3; i++) { 83 | // initial bytes are in range C0-FF 84 | if (bytes.charCodeAt(len - i) >= 0xC0) { 85 | len_parsed = len - i; 86 | break; 87 | }; 88 | }; 89 | try { 90 | // if the last few bytes are a complete multi-byte character, parse 91 | // everything (by setting len_parsed) 92 | decodeURIComponent(escape(bytes.slice(len_parsed))); 93 | len_parsed = len; 94 | } 95 | catch (err) { /* pass */ }; 96 | }; 97 | try { 98 | return [ 99 | decodeURIComponent(escape(bytes.slice(0, len_parsed))), 100 | len_parsed 101 | ]; 102 | } 103 | catch (err) { 104 | throw new UnicodeCodecError('invalid utf-8 bytes'); 105 | }; 106 | }; 107 | -------------------------------------------------------------------------------- /hookbox/js_src/jsio-3.2/std/uuid.js: -------------------------------------------------------------------------------- 1 | /* 2 | Based on Math.uuid.js 1.4 by Robert Kieffer 3 | 4 | ---- 5 | Copyright (c) 2008, Robert Kieffer 6 | All rights reserved. 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are met: 10 | 11 | * Redistributions of source code must retain the above copyright notice, 12 | this list of conditions and the following disclaimer. 13 | * Redistributions in binary form must reproduce the above copyright 14 | notice, this list of conditions and the following disclaimer in the 15 | documentation and/or other materials provided with the distribution. 16 | * Neither the name of Robert Kieffer nor the names of its contributors 17 | may be used to endorse or promote products derived from this software 18 | without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 24 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 | POSSIBILITY OF SUCH DAMAGE. 31 | 32 | */ 33 | 34 | 35 | 36 | /* 37 | * Generate a random uuid. 38 | * 39 | * USAGE: uuid.uuid(length, radix) 40 | * length - the desired number of characters 41 | * radix - the number of allowable values for each character. 42 | * 43 | * EXAMPLES: 44 | * // No arguments - returns RFC4122, version 4 ID 45 | * >>> Math.uuid() 46 | * "92329D39-6F5C-4520-ABFC-AAB64544E172" 47 | * 48 | * // One argument - returns ID of the specified length 49 | * >>> Math.uuid(15) // 15 character ID (default base=62) 50 | * "VcydxgltxrVZSTV" 51 | * 52 | * // Two arguments - returns ID of the specified length, and radix. (Radix must be <= 62) 53 | * >>> Math.uuid(8, 2) // 8 character ID (base=2) 54 | * "01001010" 55 | * >>> Math.uuid(8, 10) // 8 character ID (base=10) 56 | * "47473046" 57 | * >>> Math.uuid(8, 16) // 8 character ID (base=16) 58 | * "098F4D35" 59 | */ 60 | 61 | 62 | var CHARS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split(''); 63 | exports.uuid = function (len, radix) { 64 | var chars = CHARS, uuid = [], rnd = Math.random; 65 | radix = radix || chars.length; 66 | 67 | if (len) { 68 | // Compact form 69 | for (var i = 0; i < len; i++) uuid[i] = chars[0 | rnd()*radix]; 70 | } else { 71 | // rfc4122, version 4 form 72 | var r; 73 | 74 | // rfc4122 requires these characters 75 | uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-'; 76 | uuid[14] = '4'; 77 | 78 | // Fill in random data. At i==19 set the high bits of clock sequence as 79 | // per rfc4122, sec. 4.1.5 80 | for (var i = 0; i < 36; i++) { 81 | if (!uuid[i]) { 82 | r = 0 | rnd()*16; 83 | uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r & 0xf]; 84 | } 85 | } 86 | } 87 | return uuid.join(''); 88 | }; 89 | 90 | -------------------------------------------------------------------------------- /hookbox/js_src/jsio-3.2/util/browserdetect.js: -------------------------------------------------------------------------------- 1 | exports.BrowserDetect = new function() { 2 | var versionSearchString; 3 | var dataBrowser = [ 4 | { 5 | string: navigator.userAgent, 6 | subString: "Chrome" 7 | }, 8 | { 9 | string: navigator.userAgent, 10 | subString: "OmniWeb", 11 | versionSearch: "OmniWeb/" 12 | }, 13 | { 14 | string: navigator.vendor, 15 | subString: "Apple", 16 | identity: "Safari", 17 | versionSearch: "Version" 18 | }, 19 | { 20 | prop: window.opera, 21 | identity: "Opera" 22 | }, 23 | { 24 | string: navigator.vendor, 25 | subString: "iCab" 26 | }, 27 | { 28 | string: navigator.vendor, 29 | subString: "KDE", 30 | identity: "Konqueror" 31 | }, 32 | { 33 | string: navigator.userAgent, 34 | subString: "Firefox" 35 | }, 36 | { 37 | string: navigator.vendor, 38 | subString: "Camino" 39 | }, 40 | { // for newer Netscapes (6+) 41 | string: navigator.userAgent, 42 | subString: "Netscape" 43 | }, 44 | { 45 | string: navigator.userAgent, 46 | subString: "MSIE", 47 | identity: "IE", 48 | versionSearch: "MSIE" 49 | }, 50 | { 51 | string: navigator.userAgent, 52 | subString: "Gecko", 53 | identity: "Mozilla", 54 | versionSearch: "rv" 55 | }, 56 | { // for older Netscapes (4-) 57 | string: navigator.userAgent, 58 | subString: "Mozilla", 59 | identity: "Netscape", 60 | versionSearch: "Mozilla" 61 | } 62 | ]; 63 | 64 | var dataOS = [ 65 | { 66 | string: navigator.platform, 67 | subString: "Win", 68 | identity: "Windows" 69 | }, 70 | { 71 | string: navigator.platform, 72 | subString: "Mac" 73 | }, 74 | { 75 | string: navigator.userAgent, 76 | subString: "iPhone", 77 | identity: "iPhone/iPod" 78 | }, 79 | { 80 | string: navigator.platform, 81 | subString: "Linux" 82 | } 83 | ]; 84 | 85 | function searchString(data) { 86 | for (var i=0,item;item=data[i];i++) { 87 | var dataString = item.string; 88 | var dataProp = item.prop; 89 | item.identity = item.identity || item.subString; 90 | versionSearchString = item.versionSearch || item.identity; 91 | if (dataString) { 92 | if (dataString.indexOf(item.subString) != -1) 93 | return item.identity; 94 | } else if (dataProp) 95 | return item.identity; 96 | } 97 | } 98 | 99 | function searchVersion(dataString) { 100 | var index = dataString.indexOf(versionSearchString); 101 | if (index == -1) return; 102 | return parseFloat(dataString.substring(index+versionSearchString.length+1)); 103 | } 104 | 105 | this.browser = searchString(dataBrowser) || "unknown"; 106 | this.version = searchVersion(navigator.userAgent) 107 | || searchVersion(navigator.appVersion) 108 | || "unknown"; 109 | this.OS = searchString(dataOS) || "unknown"; 110 | this.isWebKit = RegExp(" AppleWebKit/").test(navigator.userAgent); 111 | this['is'+this.browser] = this.version; 112 | }; -------------------------------------------------------------------------------- /hookbox/js_src/jsio-3.2/util/sprintf.js: -------------------------------------------------------------------------------- 1 | // XXX: Lets have a reasonable implementation of this fucntion 2 | // -mcarter 9/18/09 3 | 4 | // Code from http://www.webtoolkit.info/javascript-sprintf.html 5 | // Seems to be an MIT-like license, with linking in source code required 6 | // License: 7 | // As long as you leave the copyright notice of the original script, or link 8 | // back to this website, you can use any of the content published on this 9 | // website free of charge for any use: commercial or noncommercial. 10 | // (http://www.webtoolkit.info/licence.html 9/18/09) 11 | 12 | // there was no original copyright notice in the code. just a link to: 13 | // http://www.webtoolkit.info 14 | 15 | 16 | var sprintfWrapper = { 17 | 18 | init : function () { 19 | 20 | if (typeof arguments == "undefined") { return null; } 21 | if (arguments.length < 1) { return null; } 22 | if (typeof arguments[0] != "string") { return null; } 23 | if (typeof RegExp == "undefined") { return null; } 24 | 25 | var string = arguments[0]; 26 | var exp = new RegExp(/(%([%]|(\-)?(\+|\x20)?(0)?(\d+)?(\.(\d)?)?([bcdfosxX])))/g); 27 | var matches = new Array(); 28 | var strings = new Array(); 29 | var convCount = 0; 30 | var stringPosStart = 0; 31 | var stringPosEnd = 0; 32 | var matchPosEnd = 0; 33 | var newString = ''; 34 | var match = null; 35 | 36 | while (match = exp.exec(string)) { 37 | if (match[9]) { convCount += 1; } 38 | 39 | stringPosStart = matchPosEnd; 40 | stringPosEnd = exp.lastIndex - match[0].length; 41 | strings[strings.length] = string.substring(stringPosStart, stringPosEnd); 42 | 43 | matchPosEnd = exp.lastIndex; 44 | matches[matches.length] = { 45 | match: match[0], 46 | left: match[3] ? true : false, 47 | sign: match[4] || '', 48 | pad: match[5] || ' ', 49 | min: match[6] || 0, 50 | precision: match[8], 51 | code: match[9] || '%', 52 | negative: parseInt(arguments[convCount]) < 0 ? true : false, 53 | argument: typeof(arguments[convCount]) == 'object' ? JSON.stringify(arguments[convCount]) : String(arguments[convCount]) 54 | }; 55 | } 56 | strings[strings.length] = string.substring(matchPosEnd); 57 | 58 | if (matches.length == 0) { return string; } 59 | if ((arguments.length - 1) < convCount) { return null; } 60 | 61 | var code = null; 62 | var match = null; 63 | var i = null; 64 | 65 | for (i=0; i 2 | 3 | 4 | 22 | 23 | 24 |

Test eventlet csp

25 | 26 | 27 | -------------------------------------------------------------------------------- /hookbox/tests/__init__.py: -------------------------------------------------------------------------------- 1 | # load all modules to get them into the coverage report 2 | import hookbox 3 | from hookbox import admin 4 | from hookbox import channel 5 | from hookbox import config 6 | from hookbox import errors 7 | from hookbox import protocol 8 | from hookbox import rest 9 | from hookbox import server 10 | from hookbox import start 11 | from hookbox import user 12 | 13 | -------------------------------------------------------------------------------- /hookbox/tests/test_hookbox_config.py: -------------------------------------------------------------------------------- 1 | from hookbox.config import HookboxConfig 2 | from hookbox.config import HookboxOptionParser 3 | from hookbox.config import NoDefault 4 | 5 | class TestHookboxOptionParser(object): 6 | 7 | def setup(self): 8 | self.parser = HookboxOptionParser(HookboxConfig.defaults) 9 | 10 | def test_create_parser_smoketest(self): 11 | HookboxOptionParser(HookboxConfig.defaults) 12 | 13 | def test_update_from_commandline_arguments__interface(self): 14 | args = ['--interface', 'beano.com'] 15 | options, args = self.parser.parse_arguments(args) 16 | assert 'beano.com' == options['interface'] 17 | 18 | class TestHookboxConfig(object): 19 | 20 | def test_create_config_smoketest(self): 21 | HookboxConfig() 22 | 23 | def _assert_default(self, config, attr, expected): 24 | actual = getattr(config, attr) 25 | assert expected == actual, \ 26 | (expected, actual) 27 | 28 | def test_defaults(self): 29 | default_config = HookboxConfig() 30 | expected_defaults = [('interface', '127.0.0.1'), 31 | ('port', 8001), 32 | ('cbport', 80), 33 | ('cbhost', '127.0.0.1'), 34 | ('cbpath', '/hookbox'), 35 | ('cookie_identifier', NoDefault), 36 | ('secret', NoDefault), 37 | ('cb_connect', 'connect'), 38 | ('cb_disconnect', 'disconnect'), 39 | ('cb_create_channel', 'create_channel'), 40 | ('cb_destroy_channel', 'destroy_channel'), 41 | ('cb_subscribe', 'subscribe'), 42 | ('cb_unsubscribe', 'unsubscribe'), 43 | ('cb_publish', 'publish'), 44 | ('rest_secret', NoDefault), 45 | ('admin_password', NoDefault), 46 | ('debug', False), 47 | ('objgraph', 0), 48 | ] 49 | for attr, default in expected_defaults: 50 | yield '_assert_default', default_config, attr, default 51 | 52 | def test_update_from_commandline_arguments(self): 53 | args = ['--interface', 'beano.com'] 54 | config = HookboxConfig() 55 | config.update_from_commandline_arguments(args) 56 | assert 'beano.com' == config.interface 57 | 58 | def test_update_from_commandline_arguments_with_defaults(self): 59 | args = ['--interface', 'beano.com'] 60 | config = HookboxConfig() 61 | config.update_from_commandline_arguments(args) 62 | assert 8001 == config.port 63 | 64 | def test_config_acts_like_a_dict(self): 65 | config = HookboxConfig() 66 | assert '127.0.0.1' == config['interface'] 67 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |

Hookbox

5 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [nosetests] 2 | with-coverage = True 3 | cover-package = hookbox 4 | cover-erase = True -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | import os, sys 3 | import hookbox 4 | 5 | static_types = [ 6 | '*.js', 7 | '*.html', 8 | '*.css', 9 | '*.ico', 10 | '*.gif', 11 | '*.jpg', 12 | '*.png', 13 | '*.txt*', 14 | '*.py', 15 | '*.template', 16 | '*.pkg' 17 | ] 18 | 19 | #if sys.platform != "win32": 20 | # _install_requires.append("Twisted") 21 | 22 | _install_requires = [ 23 | 'eventlet>=0.9.10', 24 | 'paste', 25 | 'csp_eventlet>=0.5.1', 26 | 'rtjp_eventlet>=0.3.2', 27 | 'pygments', 28 | 'restkit>=2.2.3', 29 | # 'nose==0.11.1', 30 | # 'coverage', 31 | ] 32 | 33 | # python <= 2.5 34 | if sys.version_info[1] <= 5: 35 | _install_requires.append('simplejson') 36 | 37 | 38 | def find_package_data(): 39 | targets = [ 40 | os.path.join('hookbox', 'static'), 41 | os.path.join('hookbox', 'admin', 'static'), 42 | os.path.join('hookbox', 'js_src') 43 | ] 44 | package_data = {'': reduce(list.__add__, [ '.git' not in d and [ os.path.join(d[len('hookbox/'):], e) for e in 45 | static_types ] or [] for (d, s, f) in reduce(list.__add__, [ [ i for i in os.walk(target) ] for target in targets ]) 46 | ]) } 47 | return package_data 48 | 49 | def main(): 50 | setup( 51 | name='hookbox', 52 | version=hookbox.__version__, 53 | author='Michael Carter', 54 | author_email='CarterMichael@gmail.com', 55 | url='http://hookbox.org', 56 | license='MIT License', 57 | description='HookBox is a Comet server and message queue that tightly integrates with your existing web application via web hooks and a REST interface.', 58 | long_description='', 59 | packages= find_packages(), 60 | package_data = find_package_data(), 61 | zip_safe = False, 62 | install_requires = _install_requires, 63 | entry_points = ''' 64 | [console_scripts] 65 | hookbox = hookbox.start:main 66 | ''', 67 | 68 | classifiers = [ 69 | 'Development Status :: 4 - Beta', 70 | 'Environment :: Console', 71 | 'Intended Audience :: Developers', 72 | 'License :: OSI Approved :: MIT License', 73 | 'Operating System :: OS Independent', 74 | 'Programming Language :: Python', 75 | 'Topic :: Software Development :: Libraries :: Python Modules' 76 | ], 77 | ) 78 | 79 | 80 | if __name__ == '__main__': 81 | main() 82 | -------------------------------------------------------------------------------- /web/docs: -------------------------------------------------------------------------------- 1 | ../docs/build/html/ -------------------------------------------------------------------------------- /web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Hookbox 5 | 26 | 27 |
28 | 29 | 30 | 31 |
32 |

Hookbox

33 |
34 |

Hookbox is a Comet server and message queue that tightly integrates with your existing web application via web hooks and a REST interface.

35 | 44 |
45 | 46 | 47 | 60 | 61 | 62 | --------------------------------------------------------------------------------