From e7d150fd7ca22b01defd0c615000b6bfc367aacf Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Tue, 14 Jul 2009 15:18:07 -0400 Subject: Reorganized directory structure, mostly to put all the interfaces in one place and make things clearer to the uninitiated. Here's my current understanding: . |-- libbe (the guts of BE) |-- becommands (plugins for all "be *" commands) |-- doc (documentation, currently just the man page) |-- interfaces (non-commandline interface implementations) | |-- web | | |-- Bugs-Everywhere-Web (in Turbogears) | |-- gui | | |-- beg (in Tkinter) | | `-- wxbe (in WX) | |-- email | `-- xml (xml <-> whatever conversion) `-- misc (random odds and ends) `-- completion (shell completion scripts) Note that I haven't attempted to use the web or gui interfaces in a while, so I'm not sure how well they're holding vs the core development. --- .../Bugs-Everywhere-Web.egg-info/SOURCES.txt | 36 ++++ .../Bugs-Everywhere-Web.egg-info/not-zip-safe | 0 .../Bugs-Everywhere-Web.egg-info/requires.txt | 1 + .../Bugs-Everywhere-Web.egg-info/sqlobject.txt | 2 + .../Bugs-Everywhere-Web.egg-info/top_level.txt | 2 + .../Bugs_Everywhere_Web.egg-info/PKG-INFO | 15 ++ .../Bugs_Everywhere_Web.egg-info/SOURCES.txt | 44 ++++ .../dependency_links.txt | 1 + .../Bugs_Everywhere_Web.egg-info/not-zip-safe | 1 + .../paster_plugins.txt | 2 + .../Bugs_Everywhere_Web.egg-info/requires.txt | 1 + .../Bugs_Everywhere_Web.egg-info/sqlobject.txt | 2 + .../Bugs_Everywhere_Web.egg-info/top_level.txt | 1 + interfaces/web/Bugs-Everywhere-Web/README.txt | 42 ++++ .../web/Bugs-Everywhere-Web/beweb/__init__.py | 0 interfaces/web/Bugs-Everywhere-Web/beweb/app.cfg | 120 +++++++++++ .../Bugs-Everywhere-Web/beweb/config.py.example | 10 + .../web/Bugs-Everywhere-Web/beweb/config/app.cfg | 92 ++++++++ .../web/Bugs-Everywhere-Web/beweb/config/log.cfg | 29 +++ .../web/Bugs-Everywhere-Web/beweb/controllers.py | 240 +++++++++++++++++++++ .../web/Bugs-Everywhere-Web/beweb/formatting.py | 76 +++++++ interfaces/web/Bugs-Everywhere-Web/beweb/json.py | 13 ++ interfaces/web/Bugs-Everywhere-Web/beweb/model.py | 107 +++++++++ interfaces/web/Bugs-Everywhere-Web/beweb/prest.py | 168 +++++++++++++++ .../web/Bugs-Everywhere-Web/beweb/release.py | 14 ++ .../Bugs-Everywhere-Web/beweb/static/css/style.css | 116 ++++++++++ .../beweb/static/images/ds-b.png | Bin 0 -> 213 bytes .../beweb/static/images/ds-bl.png | Bin 0 -> 327 bytes .../beweb/static/images/ds-br.png | Bin 0 -> 365 bytes .../beweb/static/images/ds-l.png | Bin 0 -> 197 bytes .../beweb/static/images/ds-r.png | Bin 0 -> 214 bytes .../beweb/static/images/ds-t.png | Bin 0 -> 200 bytes .../beweb/static/images/ds-tl.png | Bin 0 -> 240 bytes .../beweb/static/images/ds-tr.png | Bin 0 -> 311 bytes .../beweb/static/images/ds2-b.png | Bin 0 -> 206 bytes .../beweb/static/images/ds2-r.png | Bin 0 -> 204 bytes .../beweb/static/images/favicon.ico | Bin 0 -> 318 bytes .../beweb/static/images/favicon.png | Bin 0 -> 267 bytes .../beweb/static/images/half-spiral.png | Bin 0 -> 1112 bytes .../beweb/static/images/header_inner.png | Bin 0 -> 37537 bytes .../beweb/static/images/info.png | Bin 0 -> 2889 bytes .../beweb/static/images/is-b.png | Bin 0 -> 200 bytes .../beweb/static/images/is-bl.png | Bin 0 -> 408 bytes .../beweb/static/images/is-br.png | Bin 0 -> 304 bytes .../beweb/static/images/is-l.png | Bin 0 -> 214 bytes .../beweb/static/images/is-r.png | Bin 0 -> 197 bytes .../beweb/static/images/is-t.png | Bin 0 -> 213 bytes .../beweb/static/images/is-tl.png | Bin 0 -> 413 bytes .../beweb/static/images/is-tr.png | Bin 0 -> 414 bytes .../Bugs-Everywhere-Web/beweb/static/images/ok.png | Bin 0 -> 25753 bytes .../beweb/static/images/shadows.png | Bin 0 -> 3960 bytes .../beweb/static/images/spiral.png | Bin 0 -> 2120 bytes .../beweb/static/images/tg_under_the_hood.png | Bin 0 -> 4010 bytes .../beweb/static/images/under_the_hood_blue.png | Bin 0 -> 2667 bytes .../beweb/templates/__init__.py | 0 .../Bugs-Everywhere-Web/beweb/templates/about.kid | 21 ++ .../Bugs-Everywhere-Web/beweb/templates/bugs.kid | 52 +++++ .../beweb/templates/edit_bug.kid | 52 +++++ .../beweb/templates/edit_comment.kid | 26 +++ .../Bugs-Everywhere-Web/beweb/templates/error.kid | 14 ++ .../Bugs-Everywhere-Web/beweb/templates/login.kid | 113 ++++++++++ .../Bugs-Everywhere-Web/beweb/templates/master.kid | 71 ++++++ .../beweb/templates/projects.kid | 32 +++ .../beweb/templates/welcome.kid | 50 +++++ .../Bugs-Everywhere-Web/beweb/tests/__init__.py | 0 .../beweb/tests/test_controllers.py | 16 ++ .../Bugs-Everywhere-Web/beweb/tests/test_model.py | 23 ++ interfaces/web/Bugs-Everywhere-Web/dev.cfg | 71 ++++++ interfaces/web/Bugs-Everywhere-Web/libbe | 1 + interfaces/web/Bugs-Everywhere-Web/prod.cfg | 41 ++++ interfaces/web/Bugs-Everywhere-Web/sample-prod.cfg | 71 ++++++ interfaces/web/Bugs-Everywhere-Web/server.log | 26 +++ interfaces/web/Bugs-Everywhere-Web/setup-tables.py | 34 +++ interfaces/web/Bugs-Everywhere-Web/setup.py | 62 ++++++ interfaces/web/Bugs-Everywhere-Web/start-beweb.py | 28 +++ 75 files changed, 1939 insertions(+) create mode 100644 interfaces/web/Bugs-Everywhere-Web/Bugs_Everywhere_Web.egg-info/Bugs-Everywhere-Web.egg-info/SOURCES.txt create mode 100644 interfaces/web/Bugs-Everywhere-Web/Bugs_Everywhere_Web.egg-info/Bugs-Everywhere-Web.egg-info/not-zip-safe create mode 100644 interfaces/web/Bugs-Everywhere-Web/Bugs_Everywhere_Web.egg-info/Bugs-Everywhere-Web.egg-info/requires.txt create mode 100644 interfaces/web/Bugs-Everywhere-Web/Bugs_Everywhere_Web.egg-info/Bugs-Everywhere-Web.egg-info/sqlobject.txt create mode 100644 interfaces/web/Bugs-Everywhere-Web/Bugs_Everywhere_Web.egg-info/Bugs-Everywhere-Web.egg-info/top_level.txt create mode 100644 interfaces/web/Bugs-Everywhere-Web/Bugs_Everywhere_Web.egg-info/PKG-INFO create mode 100644 interfaces/web/Bugs-Everywhere-Web/Bugs_Everywhere_Web.egg-info/SOURCES.txt create mode 100644 interfaces/web/Bugs-Everywhere-Web/Bugs_Everywhere_Web.egg-info/dependency_links.txt create mode 100644 interfaces/web/Bugs-Everywhere-Web/Bugs_Everywhere_Web.egg-info/not-zip-safe create mode 100644 interfaces/web/Bugs-Everywhere-Web/Bugs_Everywhere_Web.egg-info/paster_plugins.txt create mode 100644 interfaces/web/Bugs-Everywhere-Web/Bugs_Everywhere_Web.egg-info/requires.txt create mode 100644 interfaces/web/Bugs-Everywhere-Web/Bugs_Everywhere_Web.egg-info/sqlobject.txt create mode 100644 interfaces/web/Bugs-Everywhere-Web/Bugs_Everywhere_Web.egg-info/top_level.txt create mode 100644 interfaces/web/Bugs-Everywhere-Web/README.txt create mode 100644 interfaces/web/Bugs-Everywhere-Web/beweb/__init__.py create mode 100644 interfaces/web/Bugs-Everywhere-Web/beweb/app.cfg create mode 100644 interfaces/web/Bugs-Everywhere-Web/beweb/config.py.example create mode 100644 interfaces/web/Bugs-Everywhere-Web/beweb/config/app.cfg create mode 100644 interfaces/web/Bugs-Everywhere-Web/beweb/config/log.cfg create mode 100644 interfaces/web/Bugs-Everywhere-Web/beweb/controllers.py create mode 100644 interfaces/web/Bugs-Everywhere-Web/beweb/formatting.py create mode 100644 interfaces/web/Bugs-Everywhere-Web/beweb/json.py create mode 100644 interfaces/web/Bugs-Everywhere-Web/beweb/model.py create mode 100644 interfaces/web/Bugs-Everywhere-Web/beweb/prest.py create mode 100644 interfaces/web/Bugs-Everywhere-Web/beweb/release.py create mode 100644 interfaces/web/Bugs-Everywhere-Web/beweb/static/css/style.css create mode 100644 interfaces/web/Bugs-Everywhere-Web/beweb/static/images/ds-b.png create mode 100644 interfaces/web/Bugs-Everywhere-Web/beweb/static/images/ds-bl.png create mode 100644 interfaces/web/Bugs-Everywhere-Web/beweb/static/images/ds-br.png create mode 100644 interfaces/web/Bugs-Everywhere-Web/beweb/static/images/ds-l.png create mode 100644 interfaces/web/Bugs-Everywhere-Web/beweb/static/images/ds-r.png create mode 100644 interfaces/web/Bugs-Everywhere-Web/beweb/static/images/ds-t.png create mode 100644 interfaces/web/Bugs-Everywhere-Web/beweb/static/images/ds-tl.png create mode 100644 interfaces/web/Bugs-Everywhere-Web/beweb/static/images/ds-tr.png create mode 100644 interfaces/web/Bugs-Everywhere-Web/beweb/static/images/ds2-b.png create mode 100644 interfaces/web/Bugs-Everywhere-Web/beweb/static/images/ds2-r.png create mode 100644 interfaces/web/Bugs-Everywhere-Web/beweb/static/images/favicon.ico create mode 100644 interfaces/web/Bugs-Everywhere-Web/beweb/static/images/favicon.png create mode 100644 interfaces/web/Bugs-Everywhere-Web/beweb/static/images/half-spiral.png create mode 100644 interfaces/web/Bugs-Everywhere-Web/beweb/static/images/header_inner.png create mode 100644 interfaces/web/Bugs-Everywhere-Web/beweb/static/images/info.png create mode 100644 interfaces/web/Bugs-Everywhere-Web/beweb/static/images/is-b.png create mode 100644 interfaces/web/Bugs-Everywhere-Web/beweb/static/images/is-bl.png create mode 100644 interfaces/web/Bugs-Everywhere-Web/beweb/static/images/is-br.png create mode 100644 interfaces/web/Bugs-Everywhere-Web/beweb/static/images/is-l.png create mode 100644 interfaces/web/Bugs-Everywhere-Web/beweb/static/images/is-r.png create mode 100644 interfaces/web/Bugs-Everywhere-Web/beweb/static/images/is-t.png create mode 100644 interfaces/web/Bugs-Everywhere-Web/beweb/static/images/is-tl.png create mode 100644 interfaces/web/Bugs-Everywhere-Web/beweb/static/images/is-tr.png create mode 100644 interfaces/web/Bugs-Everywhere-Web/beweb/static/images/ok.png create mode 100644 interfaces/web/Bugs-Everywhere-Web/beweb/static/images/shadows.png create mode 100644 interfaces/web/Bugs-Everywhere-Web/beweb/static/images/spiral.png create mode 100644 interfaces/web/Bugs-Everywhere-Web/beweb/static/images/tg_under_the_hood.png create mode 100644 interfaces/web/Bugs-Everywhere-Web/beweb/static/images/under_the_hood_blue.png create mode 100644 interfaces/web/Bugs-Everywhere-Web/beweb/templates/__init__.py create mode 100644 interfaces/web/Bugs-Everywhere-Web/beweb/templates/about.kid create mode 100644 interfaces/web/Bugs-Everywhere-Web/beweb/templates/bugs.kid create mode 100644 interfaces/web/Bugs-Everywhere-Web/beweb/templates/edit_bug.kid create mode 100644 interfaces/web/Bugs-Everywhere-Web/beweb/templates/edit_comment.kid create mode 100644 interfaces/web/Bugs-Everywhere-Web/beweb/templates/error.kid create mode 100644 interfaces/web/Bugs-Everywhere-Web/beweb/templates/login.kid create mode 100644 interfaces/web/Bugs-Everywhere-Web/beweb/templates/master.kid create mode 100644 interfaces/web/Bugs-Everywhere-Web/beweb/templates/projects.kid create mode 100644 interfaces/web/Bugs-Everywhere-Web/beweb/templates/welcome.kid create mode 100644 interfaces/web/Bugs-Everywhere-Web/beweb/tests/__init__.py create mode 100644 interfaces/web/Bugs-Everywhere-Web/beweb/tests/test_controllers.py create mode 100644 interfaces/web/Bugs-Everywhere-Web/beweb/tests/test_model.py create mode 100644 interfaces/web/Bugs-Everywhere-Web/dev.cfg create mode 120000 interfaces/web/Bugs-Everywhere-Web/libbe create mode 100644 interfaces/web/Bugs-Everywhere-Web/prod.cfg create mode 100644 interfaces/web/Bugs-Everywhere-Web/sample-prod.cfg create mode 100644 interfaces/web/Bugs-Everywhere-Web/server.log create mode 100644 interfaces/web/Bugs-Everywhere-Web/setup-tables.py create mode 100644 interfaces/web/Bugs-Everywhere-Web/setup.py create mode 100755 interfaces/web/Bugs-Everywhere-Web/start-beweb.py (limited to 'interfaces/web') diff --git a/interfaces/web/Bugs-Everywhere-Web/Bugs_Everywhere_Web.egg-info/Bugs-Everywhere-Web.egg-info/SOURCES.txt b/interfaces/web/Bugs-Everywhere-Web/Bugs_Everywhere_Web.egg-info/Bugs-Everywhere-Web.egg-info/SOURCES.txt new file mode 100644 index 0000000..def18b1 --- /dev/null +++ b/interfaces/web/Bugs-Everywhere-Web/Bugs_Everywhere_Web.egg-info/Bugs-Everywhere-Web.egg-info/SOURCES.txt @@ -0,0 +1,36 @@ +README.txt +setup.py +start-beweb.py +Bugs-Everywhere-Web.egg-info/PKG-INFO +Bugs-Everywhere-Web.egg-info/SOURCES.txt +Bugs-Everywhere-Web.egg-info/not-zip-safe +Bugs-Everywhere-Web.egg-info/requires.txt +Bugs-Everywhere-Web.egg-info/sqlobject.txt +Bugs-Everywhere-Web.egg-info/top_level.txt +beweb/__init__.py +beweb/config.py +beweb/controllers.py +beweb/formatting.py +beweb/model.py +beweb/prest.py +beweb/release.py +beweb/config/__init__.py +beweb/templates/__init__.py +beweb/tests/__init__.py +beweb/tests/test_controllers.py +beweb/tests/test_model.py +libbe/__init__.py +libbe/arch.py +libbe/bugdir.py +libbe/bzr.py +libbe/cmdutil.py +libbe/config.py +libbe/diff.py +libbe/mapfile.py +libbe/names.py +libbe/no_rcs.py +libbe/plugin.py +libbe/rcs.py +libbe/restconvert.py +libbe/tests.py +libbe/utility.py diff --git a/interfaces/web/Bugs-Everywhere-Web/Bugs_Everywhere_Web.egg-info/Bugs-Everywhere-Web.egg-info/not-zip-safe b/interfaces/web/Bugs-Everywhere-Web/Bugs_Everywhere_Web.egg-info/Bugs-Everywhere-Web.egg-info/not-zip-safe new file mode 100644 index 0000000..e69de29 diff --git a/interfaces/web/Bugs-Everywhere-Web/Bugs_Everywhere_Web.egg-info/Bugs-Everywhere-Web.egg-info/requires.txt b/interfaces/web/Bugs-Everywhere-Web/Bugs_Everywhere_Web.egg-info/Bugs-Everywhere-Web.egg-info/requires.txt new file mode 100644 index 0000000..88b15cb --- /dev/null +++ b/interfaces/web/Bugs-Everywhere-Web/Bugs_Everywhere_Web.egg-info/Bugs-Everywhere-Web.egg-info/requires.txt @@ -0,0 +1 @@ +TurboGears >= 0.9a4 \ No newline at end of file diff --git a/interfaces/web/Bugs-Everywhere-Web/Bugs_Everywhere_Web.egg-info/Bugs-Everywhere-Web.egg-info/sqlobject.txt b/interfaces/web/Bugs-Everywhere-Web/Bugs_Everywhere_Web.egg-info/Bugs-Everywhere-Web.egg-info/sqlobject.txt new file mode 100644 index 0000000..7f7cbad --- /dev/null +++ b/interfaces/web/Bugs-Everywhere-Web/Bugs_Everywhere_Web.egg-info/Bugs-Everywhere-Web.egg-info/sqlobject.txt @@ -0,0 +1,2 @@ +db_module=beweb.model +history_dir=$base/beweb/sqlobject-history diff --git a/interfaces/web/Bugs-Everywhere-Web/Bugs_Everywhere_Web.egg-info/Bugs-Everywhere-Web.egg-info/top_level.txt b/interfaces/web/Bugs-Everywhere-Web/Bugs_Everywhere_Web.egg-info/Bugs-Everywhere-Web.egg-info/top_level.txt new file mode 100644 index 0000000..6455be9 --- /dev/null +++ b/interfaces/web/Bugs-Everywhere-Web/Bugs_Everywhere_Web.egg-info/Bugs-Everywhere-Web.egg-info/top_level.txt @@ -0,0 +1,2 @@ +beweb +libbe diff --git a/interfaces/web/Bugs-Everywhere-Web/Bugs_Everywhere_Web.egg-info/PKG-INFO b/interfaces/web/Bugs-Everywhere-Web/Bugs_Everywhere_Web.egg-info/PKG-INFO new file mode 100644 index 0000000..6cb6ad2 --- /dev/null +++ b/interfaces/web/Bugs-Everywhere-Web/Bugs_Everywhere_Web.egg-info/PKG-INFO @@ -0,0 +1,15 @@ +Metadata-Version: 1.0 +Name: Bugs-Everywhere-Web +Version: 1.0 +Summary: UNKNOWN +Home-page: UNKNOWN +Author: UNKNOWN +Author-email: UNKNOWN +License: UNKNOWN +Description: UNKNOWN +Platform: UNKNOWN +Classifier: Development Status :: 3 - Alpha +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Classifier: Framework :: TurboGears diff --git a/interfaces/web/Bugs-Everywhere-Web/Bugs_Everywhere_Web.egg-info/SOURCES.txt b/interfaces/web/Bugs-Everywhere-Web/Bugs_Everywhere_Web.egg-info/SOURCES.txt new file mode 100644 index 0000000..ab62ee4 --- /dev/null +++ b/interfaces/web/Bugs-Everywhere-Web/Bugs_Everywhere_Web.egg-info/SOURCES.txt @@ -0,0 +1,44 @@ +README.txt +setup.py +start-beweb.py +Bugs_Everywhere_Web.egg-info/PKG-INFO +Bugs_Everywhere_Web.egg-info/SOURCES.txt +Bugs_Everywhere_Web.egg-info/dependency_links.txt +Bugs_Everywhere_Web.egg-info/not-zip-safe +Bugs_Everywhere_Web.egg-info/paster_plugins.txt +Bugs_Everywhere_Web.egg-info/requires.txt +Bugs_Everywhere_Web.egg-info/sqlobject.txt +Bugs_Everywhere_Web.egg-info/top_level.txt +Bugs_Everywhere_Web.egg-info/Bugs-Everywhere-Web.egg-info/SOURCES.txt +Bugs_Everywhere_Web.egg-info/Bugs-Everywhere-Web.egg-info/not-zip-safe +Bugs_Everywhere_Web.egg-info/Bugs-Everywhere-Web.egg-info/requires.txt +Bugs_Everywhere_Web.egg-info/Bugs-Everywhere-Web.egg-info/sqlobject.txt +Bugs_Everywhere_Web.egg-info/Bugs-Everywhere-Web.egg-info/top_level.txt +beweb/__init__.py +beweb/config.py +beweb/controllers.py +beweb/formatting.py +beweb/json.py +beweb/model.py +beweb/prest.py +beweb/release.py +beweb/config/__init__.py +beweb/templates/__init__.py +beweb/tests/__init__.py +beweb/tests/test_controllers.py +beweb/tests/test_model.py +libbe/__init__.py +libbe/arch.py +libbe/bugdir.py +libbe/bzr.py +libbe/cmdutil.py +libbe/config.py +libbe/diff.py +libbe/mapfile.py +libbe/names.py +libbe/no_rcs.py +libbe/plugin.py +libbe/rcs.py +libbe/restconvert.py +libbe/tests.py +libbe/utility.py diff --git a/interfaces/web/Bugs-Everywhere-Web/Bugs_Everywhere_Web.egg-info/dependency_links.txt b/interfaces/web/Bugs-Everywhere-Web/Bugs_Everywhere_Web.egg-info/dependency_links.txt new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/interfaces/web/Bugs-Everywhere-Web/Bugs_Everywhere_Web.egg-info/dependency_links.txt @@ -0,0 +1 @@ + diff --git a/interfaces/web/Bugs-Everywhere-Web/Bugs_Everywhere_Web.egg-info/not-zip-safe b/interfaces/web/Bugs-Everywhere-Web/Bugs_Everywhere_Web.egg-info/not-zip-safe new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/interfaces/web/Bugs-Everywhere-Web/Bugs_Everywhere_Web.egg-info/not-zip-safe @@ -0,0 +1 @@ + diff --git a/interfaces/web/Bugs-Everywhere-Web/Bugs_Everywhere_Web.egg-info/paster_plugins.txt b/interfaces/web/Bugs-Everywhere-Web/Bugs_Everywhere_Web.egg-info/paster_plugins.txt new file mode 100644 index 0000000..14fec70 --- /dev/null +++ b/interfaces/web/Bugs-Everywhere-Web/Bugs_Everywhere_Web.egg-info/paster_plugins.txt @@ -0,0 +1,2 @@ +TurboGears +PasteScript diff --git a/interfaces/web/Bugs-Everywhere-Web/Bugs_Everywhere_Web.egg-info/requires.txt b/interfaces/web/Bugs-Everywhere-Web/Bugs_Everywhere_Web.egg-info/requires.txt new file mode 100644 index 0000000..5fd6f71 --- /dev/null +++ b/interfaces/web/Bugs-Everywhere-Web/Bugs_Everywhere_Web.egg-info/requires.txt @@ -0,0 +1 @@ +TurboGears >= 1.0b1 \ No newline at end of file diff --git a/interfaces/web/Bugs-Everywhere-Web/Bugs_Everywhere_Web.egg-info/sqlobject.txt b/interfaces/web/Bugs-Everywhere-Web/Bugs_Everywhere_Web.egg-info/sqlobject.txt new file mode 100644 index 0000000..7f7cbad --- /dev/null +++ b/interfaces/web/Bugs-Everywhere-Web/Bugs_Everywhere_Web.egg-info/sqlobject.txt @@ -0,0 +1,2 @@ +db_module=beweb.model +history_dir=$base/beweb/sqlobject-history diff --git a/interfaces/web/Bugs-Everywhere-Web/Bugs_Everywhere_Web.egg-info/top_level.txt b/interfaces/web/Bugs-Everywhere-Web/Bugs_Everywhere_Web.egg-info/top_level.txt new file mode 100644 index 0000000..74a8358 --- /dev/null +++ b/interfaces/web/Bugs-Everywhere-Web/Bugs_Everywhere_Web.egg-info/top_level.txt @@ -0,0 +1 @@ +beweb diff --git a/interfaces/web/Bugs-Everywhere-Web/README.txt b/interfaces/web/Bugs-Everywhere-Web/README.txt new file mode 100644 index 0000000..10774df --- /dev/null +++ b/interfaces/web/Bugs-Everywhere-Web/README.txt @@ -0,0 +1,42 @@ +Bugs-Everywhere-Web + +This is a TurboGears (http://www.turbogears.org) project. It can be +started by running the start-beweb.py script. + +Configure by creating an appropriate beweb/config.py from +beweb/config.py.example. The server will edit the repositories that +it manages, so you should probably have it running on a seperate +branch than your working repository. You can then merge/push +as you require to keep the branches in sync. + +See + http://docs.turbogears.org/1.0/Configuration +For standard turbogears configuration information. + +Currently, you need to login for any methods with a +@identity.require() decorator. The only group in the current +implementation is 'editbugs'. Basically, anyone can browse around, +but only registered 'editbugs' members can change things. + +Anonymous actions: + * See project tree + * See buglist + * See comments +Editbugs required actions: + * Create new comments + * Reply to comments + * Update comment info + + +All login attempts will fail unless you have added some valid users. See + http://docs.turbogears.org/1.0/GettingStartedWithIdentity +For a good intro. For the impatient, try something like + Bugs-Everywhere-Web$ tg-admin toolbox + browse to 'CatWalk' -> 'User' -> 'Add User+' +or + Bugs-Everywhere-Web$ tg-admin sholl + >>> u = User(user_name=u'jdoe', email_address=u'jdoe@example.com', + display_name=u'Jane Doe', password=u'xxx') + >>> g = Group(group_name=u'editbugs', display_name=u'Edit Bugs') + >>> g.addUser(u) # BE-Web uses SQLObject +Exit the tg-admin shell with Ctrl-Z on MS Windows, Ctrl-D on other systems. diff --git a/interfaces/web/Bugs-Everywhere-Web/beweb/__init__.py b/interfaces/web/Bugs-Everywhere-Web/beweb/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/interfaces/web/Bugs-Everywhere-Web/beweb/app.cfg b/interfaces/web/Bugs-Everywhere-Web/beweb/app.cfg new file mode 100644 index 0000000..024fa8a --- /dev/null +++ b/interfaces/web/Bugs-Everywhere-Web/beweb/app.cfg @@ -0,0 +1,120 @@ +[global] +# The settings in this file should not vary depending on the deployment +# environment. devcfg.py and prodcfg.py are the locations for +# the different deployment settings. Settings in this file will +# be overridden by settings in those other files. + +# The commented out values below are the defaults + +# VIEW + +# which view (template engine) to use if one is not specified in the +# template name +# tg.defaultview = "kid" + +# kid.outputformat="html" +# kid.encoding="utf-8" + +# The sitetemplate is used for overall styling of a site that +# includes multiple TurboGears applications +# tg.sitetemplate="" + +# Allow every exposed function to be called as json, +# tg.allow_json = False + +# Set to True if you'd like all of your pages to include MochiKit +# tg.mochikit_all = False + +# VISIT TRACKING +# Each visit to your application will be assigned a unique visit ID tracked via +# a cookie sent to the visitor's browser. +# -------------- + +# Enable Visit tracking +visit.on=True + +# Number of minutes a visit may be idle before it expires. +# visit.timeout=20 + +# The name of the cookie to transmit to the visitor's browser. +# visit.cookie.name="tg-visit" + +# Domain name to specify when setting the cookie (must begin with . according to +# RFC 2109). The default (None) should work for most cases and will default to +# the machine to which the request was made. NOTE: localhost is NEVER a valid +# value and will NOT WORK. +# visit.cookie.domain=None + +# Specific path for the cookie +# visit.cookie.path="/" + +# The name of the VisitManager plugin to use for visitor tracking. +# visit.manager="sqlobject" + + +# IDENTITY +# General configuration of the TurboGears Identity management module +# -------- + +# Switch to turn on or off the Identity management module +identity.on=True + +# [REQUIRED] URL to which CherryPy will internally redirect when an access +# control check fails. If Identity management is turned on, a value for this +# option must be specified. +identity.failure_url="/login" + +# The IdentityProvider to use -- defaults to the SqlObjectIdentityProvider which +# pulls User, Group, and Permission data out of your model database. +identity.provider="sqlobject" + +# The names of the fields on the login form containing the visitor's user ID +# and password. In addition, the submit button is specified simply so its +# existence may be stripped out prior to passing the form data to the target +# controller. +identity.form.user_name="user_name" +identity.form.password="password" +identity.form.submit="login" + +# What sources should the identity provider consider when determining the +# identity associated with a request? Comma separated list of identity sources. +# Valid sources: form, visit, http_auth +identity.source="form,http_auth,visit" + + +# SqlObjectIdentityProvider +# Configuration options for the default IdentityProvider +# ------------------------- + +# The classes you wish to use for your Identity model. Leave these commented out +# to use the default classes for SqlObjectIdentityProvider. Or set them to the +# classes in your model. NOTE: These aren't TG_* because the TG prefix is +# reserved for classes created by TurboGears. +# identity.soprovider.model.user="beweb.model.User" +# identity.soprovider.model.group="beweb.model.Group" +# identity.soprovider.model.permission="beweb.model.Permission" + +# The password encryption algorithm used when comparing passwords against what's +# stored in the database. Valid values are 'md5' or 'sha1'. If you do not +# specify an encryption algorithm, passwords are expected to be clear text. +# +# The SqlObjectProvider *will* encrypt passwords supplied as part of your login +# form. If you set the password through the password property, like: +# my_user.password = 'secret' +# the password will be encrypted in the database, provided identity is up and +# running, or you have loaded the configuration specifying what encryption to +# use (in situations where identity may not yet be running, like tests). + +# identity.soprovider.encryption_algorithm=None + +[/static] +static_filter.on = True +static_filter.dir = "." + +[/favicon.ico] +static_filter.on = True +static_filter.file = "images/favicon.ico" + +[/] +decodingFilter.on = True +static_filter.root = '%(package_dir)s/static' diff --git a/interfaces/web/Bugs-Everywhere-Web/beweb/config.py.example b/interfaces/web/Bugs-Everywhere-Web/beweb/config.py.example new file mode 100644 index 0000000..8745c6d --- /dev/null +++ b/interfaces/web/Bugs-Everywhere-Web/beweb/config.py.example @@ -0,0 +1,10 @@ +# This is an example beweb configuration file. + +# One thing we need is a map of projects. Projects have a beweb ID, a path, +# and a display name. + +# In this example, the 'be' beweb ID is assigned the display name "Bugs +# Everywhere" and the path "/home/abentley/be" + +projects = {"be": ("Bugs Everywhere","/home/abentley/be"), + } diff --git a/interfaces/web/Bugs-Everywhere-Web/beweb/config/app.cfg b/interfaces/web/Bugs-Everywhere-Web/beweb/config/app.cfg new file mode 100644 index 0000000..15555b7 --- /dev/null +++ b/interfaces/web/Bugs-Everywhere-Web/beweb/config/app.cfg @@ -0,0 +1,92 @@ +[global] +# The settings in this file should not vary depending on the deployment +# environment. dev.cfg and prod.cfg are the locations for +# the different deployment settings. Settings in this file will +# be overridden by settings in those other files. + +# The commented out values below are the defaults + +# VIEW + +# which view (template engine) to use if one is not specified in the +# template name +# tg.defaultview = "kid" + +# The following kid settings determine the settings used by the kid serializer. + +# One of (html|xml|json) +# kid.outputformat="html" + +# kid.encoding="utf-8" + +# The sitetemplate is used for overall styling of a site that +# includes multiple TurboGears applications +# tg.sitetemplate="" + +# Allow every exposed function to be called as json, +# tg.allow_json = False + +# List of Widgets to include on every page. +# for exemple ['turbogears.mochikit'] +# tg.include_widgets = [] + +# Set to True if the scheduler should be started +# tg.scheduler = False + +# IDENTITY +# General configuration of the TurboGears Identity management module +# -------- + +# Switch to turn on or off the Identity management module +identity.on=True + +# [REQUIRED] URL to which CherryPy will internally redirect when an access +# control check fails. If Identity management is turned on, a value for this +# option must be specified. +identity.failure_url="/login" + +# identity.provider='sqlobject' + +# The names of the fields on the login form containing the visitor's user ID +# and password. In addition, the submit button is specified simply so its +# existence may be stripped out prior to passing the form data to the target +# controller. +# identity.form.user_name="user_name" +# identity.form.password="password" +# identity.form.submit="login" + +# What sources should the identity provider consider when determining the +# identity associated with a request? Comma separated list of identity sources. +# Valid sources: form, visit, http_auth +# identity.source="form,http_auth,visit" + +# SqlObjectIdentityProvider +# Configuration options for the default IdentityProvider +# ------------------------- + +# The classes you wish to use for your Identity model. Remember to not use reserved +# SQL keywords for class names (at least unless you specify a different table +# name using sqlmeta). +identity.soprovider.model.user="stfa.model.User" +identity.soprovider.model.group="stfa.model.Group" +identity.soprovider.model.permission="stfa.model.Permission" + +# The password encryption algorithm used when comparing passwords against what's +# stored in the database. Valid values are 'md5' or 'sha1'. If you do not +# specify an encryption algorithm, passwords are expected to be clear text. +# The SqlObjectProvider *will* encrypt passwords supplied as part of your login +# form. If you set the password through the password property, like: +# my_user.password = 'secret' +# the password will be encrypted in the database, provided identity is up and +# running, or you have loaded the configuration specifying what encryption to +# use (in situations where identity may not yet be running, like tests). + +# identity.soprovider.encryption_algorithm=None + +[/static] +static_filter.on = True +static_filter.dir = "%(top_level_dir)s/static" + +[/favicon.ico] +static_filter.on = True +static_filter.file = "%(top_level_dir)s/static/images/favicon.ico" diff --git a/interfaces/web/Bugs-Everywhere-Web/beweb/config/log.cfg b/interfaces/web/Bugs-Everywhere-Web/beweb/config/log.cfg new file mode 100644 index 0000000..ce776f8 --- /dev/null +++ b/interfaces/web/Bugs-Everywhere-Web/beweb/config/log.cfg @@ -0,0 +1,29 @@ +# LOGGING +# Logging is often deployment specific, but some handlers and +# formatters can be defined here. + +[logging] +[[formatters]] +[[[message_only]]] +format='*(message)s' + +[[[full_content]]] +format='*(asctime)s *(name)s *(levelname)s *(message)s' + +[[handlers]] +[[[debug_out]]] +class='StreamHandler' +level='DEBUG' +args='(sys.stdout,)' +formatter='full_content' + +[[[access_out]]] +class='StreamHandler' +level='INFO' +args='(sys.stdout,)' +formatter='message_only' + +[[[error_out]]] +class='StreamHandler' +level='ERROR' +args='(sys.stdout,)' diff --git a/interfaces/web/Bugs-Everywhere-Web/beweb/controllers.py b/interfaces/web/Bugs-Everywhere-Web/beweb/controllers.py new file mode 100644 index 0000000..a0d0ff9 --- /dev/null +++ b/interfaces/web/Bugs-Everywhere-Web/beweb/controllers.py @@ -0,0 +1,240 @@ +import logging + +import cherrypy +import turbogears +from turbogears import controllers, expose, validate, redirect, identity + +from libbe.bugdir import tree_root, NoRootEntry +from config import projects +from prest import PrestHandler, provide_action + + +from beweb import json + +log = logging.getLogger("beweb.controllers") + +def project_tree(project): + try: + return tree_root(projects[project][1]) + except KeyError: + raise Exception("Unknown project %s" % project) + +def comment_url(project, bug, comment, **kwargs): + return turbogears.url("/project/%s/bug/%s/comment/%s" % + (project, bug, comment), kwargs) + +class Comment(PrestHandler): + @identity.require( identity.has_permission("editbugs")) + @provide_action("action", "New comment") + def new_comment(self, comment_data, comment, *args, **kwargs): + bug_tree = project_tree(comment_data['project']) + bug = bug_tree.get_bug(comment_data['bug']) + comment = new_comment(bug, "") + comment.From = identity.current.user.userId + comment.content_type = "text/restructured" + comment.save() + raise cherrypy.HTTPRedirect(comment_url(comment=comment.uuid, + **comment_data)) + + @identity.require( identity.has_permission("editbugs")) + @provide_action("action", "Reply") + def reply_comment(self, comment_data, comment, *args, **kwargs): + bug_tree = project_tree(comment_data['project']) + bug = bug_tree.get_bug(comment_data['bug']) + reply_comment = new_comment(bug, "") + reply_comment.From = identity.current.user.userId + reply_comment.in_reply_to = comment.uuid + reply_comment.save() + reply_data = dict(comment_data) + del reply_data["comment"] + raise cherrypy.HTTPRedirect(comment_url(comment=reply_comment.uuid, + **reply_data)) + + @identity.require( identity.has_permission("editbugs")) + @provide_action("action", "Update") + def update(self, comment_data, comment, comment_body, *args, **kwargs): + comment.body = comment_body + comment.save() + raise cherrypy.HTTPRedirect(bug_url(comment_data['project'], + comment_data['bug'])) + + def instantiate(self, project, bug, comment): + bug_tree = project_tree(project) + bug = bug_tree.get_bug(bug) + return bug.get_comment(comment) + + def dispatch(self, comment_data, comment, *args, **kwargs): + return self.edit_comment(comment_data['project'], comment) + + @turbogears.expose(html="beweb.templates.edit_comment") + def edit_comment(self, project, comment): + return {"comment": comment, "project_id": project} + +class Bug(PrestHandler): + comment = Comment() + @turbogears.expose(html="beweb.templates.edit_bug") + def index(self, project, bug): + return {"bug": bug, "project_id": project} + + def dispatch(self, bug_data, bug, *args, **kwargs): + if bug is None: + return self.list(bug_data['project'], **kwargs) + else: + return self.index(bug_data['project'], bug) + + @turbogears.expose(html="beweb.templates.bugs") + def list(self, project, sort_by=None, show_closed=False, action=None, + search=None): + if action == "New bug": + self.new_bug() + if show_closed == "False": + show_closed = False + bug_tree = project_tree(project) + bugs = list(bug_tree.list()) + if sort_by is None: + bugs.sort() + return {"project_id" : project, + "project_name" : projects[project][0], + "bugs" : bugs, + "show_closed" : show_closed, + "search" : search, + } + + @identity.require( identity.has_permission("editbugs")) + @provide_action("action", "New bug") + def new_bug(self, bug_data, bug, **kwargs): + bug = project_tree(bug_data['project']).new_bug() + bug.creator = identity.current.user.userId + bug.save() + raise cherrypy.HTTPRedirect(bug_url(bug_data['project'], bug.uuid)) + + @identity.require( identity.has_permission("editbugs")) + @provide_action("action", "Update") + def update(self, bug_data, bug, status, severity, summary, assigned, + action): + bug.status = status + bug.severity = severity + bug.summary = summary + if assigned == "": + assigned = None + bug.assigned = assigned + bug.save() +# bug.rcs.precommit(bug.path) +# bug.rcs.commit(bug.path, "Auto-commit") +# bug.rcs.postcommit(bug.path) + raise cherrypy.HTTPRedirect(bug_list_url(bug_data["project"])) + + def instantiate(self, project, bug): + return project_tree(project).get_bug(bug) + + @provide_action("action", "New comment") + def new_comment(self, bug_data, bug, *args, **kwargs): + try: + self.update(bug_data, bug, *args, **kwargs) + except cherrypy.HTTPRedirect: + pass + return self.comment.new_comment(bug_data, comment=None, *args, + **kwargs) + + +def project_url(project_id=None): + project_url = "/project/" + if project_id is not None: + project_url += "%s/" % project_id + return turbogears.url(project_url) + +def bug_url(project_id, bug_uuid=None): + bug_url = "/project/%s/bug/" % project_id + if bug_uuid is not None: + bug_url += "%s/" % bug_uuid + return turbogears.url(bug_url) + +def bug_list_url(project_id, show_closed=False, search=None): + bug_url = "/project/%s/bug/?show_closed=%s" % (project_id, + str(show_closed)) + if search is not None: + bug_url = "%s&search=%s" % (bug_url, search) + return turbogears.url(str(bug_url)) + + +class Project(PrestHandler): + bug = Bug() + @turbogears.expose(html="beweb.templates.projects") + def dispatch(self, project_data, project, *args, **kwargs): + if project is not None: + raise cherrypy.HTTPRedirect(bug_url(project)) + else: + return {"projects": projects} + + def instantiate(self, project): + return project + + +class Root(controllers.Root): + prest = PrestHandler() + prest.project = Project() + @turbogears.expose() + def index(self): + raise cherrypy.HTTPRedirect(project_url()) + + @expose(template="beweb.templates.login") + def login(self, forward_url=None, previous_url=None, *args, **kw): + + if not identity.current.anonymous and identity.was_login_attempted(): + raise redirect(forward_url) + + forward_url=None + previous_url= cherrypy.request.path + + if identity.was_login_attempted(): + msg=_("The credentials you supplied were not correct or "\ + "did not grant access to this resource.") + elif identity.get_identity_errors(): + msg=_("You must provide your credentials before accessing "\ + "this resource.") + else: + msg=_("Please log in.") + forward_url= cherrypy.request.headers.get("Referer", "/") + cherrypy.response.status=403 + return dict(message=msg, previous_url=previous_url, logging_in=True, + original_parameters=cherrypy.request.params, + forward_url=forward_url) + + @expose() + def logout(self): + identity.current.logout() + raise redirect("/") + + @turbogears.expose('beweb.templates.about') + def about(self, *paths, **kwargs): + return {} + + @turbogears.expose() + def default(self, *args, **kwargs): + return self.prest.default(*args, **kwargs) + + def _cp_on_error(self): + import traceback, StringIO + bodyFile = StringIO.StringIO() + traceback.print_exc(file = bodyFile) + trace_text = bodyFile.getvalue() + try: + raise + except cherrypy.NotFound: + self.handle_error('Not Found', str(e), trace_text, '404 Not Found') + + except NoRootEntry, e: + self.handle_error('Project Misconfiguration', str(e), trace_text) + + except Exception, e: + self.handle_error('Internal server error', str(e), trace_text) + + def handle_error(self, heading, body, traceback=None, + status='500 Internal Server Error'): + cherrypy.response.headerMap['Status'] = status + cherrypy.response.body = [self.errorpage(heading, body, traceback)] + + + @turbogears.expose(html='beweb.templates.error') + def errorpage(self, heading, body, traceback): + return {'heading': heading, 'body': body, 'traceback': traceback} diff --git a/interfaces/web/Bugs-Everywhere-Web/beweb/formatting.py b/interfaces/web/Bugs-Everywhere-Web/beweb/formatting.py new file mode 100644 index 0000000..1278414 --- /dev/null +++ b/interfaces/web/Bugs-Everywhere-Web/beweb/formatting.py @@ -0,0 +1,76 @@ +from StringIO import StringIO + +try : + from xml.etree.ElementTree import XML # Python 2.5 (and greater?) +except ImportError : + from elementtree.ElementTree import XML +from libbe.restconvert import rest_xml + +def to_unix(text): + skip_newline = False + for ch in text: + if ch not in ('\r', '\n'): + yield ch + else: + if ch == '\n': + if skip_newline: + continue + else: + skip_newline = True + yield '\n' + + +def soft_text(text): + first_space = False + translations = {'\n': '
\n', '&': '&', '\x3c': '<', + '\x3e': '>'} + for ch in to_unix(text): + if ch == ' ' and first_space is True: + yield ' ' + first_space = ch in (' ') + try: + yield translations[ch] + except KeyError: + yield ch + + +def soft_pre(text): + return XML('
'+ + ''.join(soft_text(text)).encode('utf-8')+'
') + + +def get_rest_body(rest): + xml, warnings = rest_xml(StringIO(rest)) + return xml.find('{http://www.w3.org/1999/xhtml}body'), warnings + + +def comment_body_xhtml(comment): + if comment.content_type == "text/restructured": + return get_rest_body(comment.body)[0] + else: + return soft_pre(comment.body) + + +def select_among(name, options, default, display_names=None): + output = ['") + return XML("".join(output)) diff --git a/interfaces/web/Bugs-Everywhere-Web/beweb/json.py b/interfaces/web/Bugs-Everywhere-Web/beweb/json.py new file mode 100644 index 0000000..6e100c3 --- /dev/null +++ b/interfaces/web/Bugs-Everywhere-Web/beweb/json.py @@ -0,0 +1,13 @@ +# This module provides helper functions for the JSON part of your +# view, if you are providing a JSON-based API for your app. + +# Here's what most rules would look like: +# @jsonify.when("isinstance(obj, YourClass)") +# def jsonify_yourclass(obj): +# return [obj.val1, obj.val2] +# +# The goal is to break your objects down into simple values: +# lists, dicts, numbers and strings + +from turbojson.jsonify import jsonify + diff --git a/interfaces/web/Bugs-Everywhere-Web/beweb/model.py b/interfaces/web/Bugs-Everywhere-Web/beweb/model.py new file mode 100644 index 0000000..aa4b6b6 --- /dev/null +++ b/interfaces/web/Bugs-Everywhere-Web/beweb/model.py @@ -0,0 +1,107 @@ +from datetime import datetime + +from sqlobject import * +from turbogears.database import PackageHub +from turbogears import identity + +hub = PackageHub("beweb") +__connection__ = hub + +class Visit(SQLObject): + class sqlmeta: + table = "visit" + + visit_key = StringCol(length=40, alternateID=True, + alternateMethodName="by_visit_key") + created = DateTimeCol(default=datetime.now) + expiry = DateTimeCol() + + def lookup_visit(cls, visit_key): + try: + return cls.by_visit_key(visit_key) + except SQLObjectNotFound: + return None + lookup_visit = classmethod(lookup_visit) + +class VisitIdentity(SQLObject): + visit_key = StringCol(length=40, alternateID=True, + alternateMethodName="by_visit_key") + user_id = IntCol() + + +class Group(SQLObject): + """ + An ultra-simple group definition. + """ + + # names like "Group", "Order" and "User" are reserved words in SQL + # so we set the name to something safe for SQL + class sqlmeta: + table = "tg_group" + + group_name = UnicodeCol(length=16, alternateID=True, + alternateMethodName="by_group_name") + display_name = UnicodeCol(length=255) + created = DateTimeCol(default=datetime.now) + + # collection of all users belonging to this group + users = RelatedJoin("User", intermediateTable="user_group", + joinColumn="group_id", otherColumn="user_id") + + # collection of all permissions for this group + permissions = RelatedJoin("Permission", joinColumn="group_id", + intermediateTable="group_permission", + otherColumn="permission_id") + + +class User(SQLObject): + """ + Reasonably basic User definition. Probably would want additional attributes. + """ + # names like "Group", "Order" and "User" are reserved words in SQL + # so we set the name to something safe for SQL + class sqlmeta: + table = "tg_user" + + child_name = UnicodeCol(length=255) + user_name = UnicodeCol(length=16, alternateID=True, + alternateMethodName="by_user_name") + email_address = UnicodeCol(length=255, alternateID=True, + alternateMethodName="by_email_address") + display_name = UnicodeCol(length=255) + password = UnicodeCol(length=40) + created = DateTimeCol(default=datetime.now) + + # groups this user belongs to + groups = RelatedJoin("Group", intermediateTable="user_group", + joinColumn="user_id", otherColumn="group_id") + + def _get_permissions(self): + perms = set() + for g in self.groups: + perms = perms | set(g.permissions) + return perms + + def _set_password(self, cleartext_password): + "Runs cleartext_password through the hash algorithm before saving." + hash = identity.encrypt_password(cleartext_password) + self._SO_set_password(hash) + + def set_password_raw(self, password): + "Saves the password as-is to the database." + self._SO_set_password(password) + + + +class Permission(SQLObject): + permission_name = UnicodeCol(length=16, alternateID=True, + alternateMethodName="by_permission_name") + description = UnicodeCol(length=255) + + groups = RelatedJoin("Group", + intermediateTable="group_permission", + joinColumn="permission_id", + otherColumn="group_id") + +def people_map(): + return dict((u.user_name, u.display_name) for u in User.select()) diff --git a/interfaces/web/Bugs-Everywhere-Web/beweb/prest.py b/interfaces/web/Bugs-Everywhere-Web/beweb/prest.py new file mode 100644 index 0000000..9a6505d --- /dev/null +++ b/interfaces/web/Bugs-Everywhere-Web/beweb/prest.py @@ -0,0 +1,168 @@ +from unittest import TestCase +import unittest +from cherrypy import NotFound +"""A pseudo-REST dispatching method in which only the noun comes from the path. +The action performed will depend on kwargs. +""" + +class AmbiguousAction(Exception): + def __init__(self, actions): + Exception.__init__(self, "Supplied action is ambiguous.") + self.actions = actions + + +def provide_action(name, value): + def provider(func): + func._action_desc = (name, value) + return func + return provider + +class PrestHandler(object): + def __init__(self): + object.__init__(self) + self.actions = {} + for member in (getattr(self, m) for m in dir(self)): + if not hasattr(member, '_action_desc'): + continue + name, value = member._action_desc + if name not in self.actions: + self.actions[name] = {} + self.actions[name][value] = member + + @classmethod + def add_action(klass, name, value, function): + if name not in klass.actions: + klass.actions[name] = {} + klass.actions[name][value] = function + + + def decode(self, path, data=None): + """Convert the path into a handler, a resource, data, and extra_path""" + if data is None: + data = {} + if len(path) < 2 or not (hasattr(self, path[1])): + if len(path) == 0: + resource = None + else: + try: + resource = self.instantiate(**data) + except NotImplementedError, e: + if e.args[0] is not PrestHandler.instantiate: + raise NotFound() + + return self, resource, data, path[1:] + if len(path) > 2: + data[path[1]] = path[2] + return getattr(self, path[1]).decode(path[2:], data) + + def instantiate(self, **date): + raise NotImplementedError(PrestHandler.instantiate) + + def default(self, *args, **kwargs): + child, resource, data, extra = self.decode([None,] + list(args)) + action = child.get_action(**kwargs) + new_args = ([data, resource]+extra) + if action is not None: + return action(*new_args, **kwargs) + else: + return child.dispatch(*new_args, **kwargs) + + def get_action(self, **kwargs): + """Return the action requested by kwargs, if any. + + Raises AmbiguousAction if more than one action matches. + """ + actions = [] + for key in kwargs: + if key in self.actions: + if kwargs[key] in self.actions[key]: + actions.append(self.actions[key][kwargs[key]]) + if len(actions) == 0: + return None + elif len(actions) == 1: + return actions[0] + else: + raise AmbiguousAction(actions) + + +class PrestTester(TestCase): + def test_decode(self): + class ProjectHandler(PrestHandler): + actions = {} + def dispatch(self, project_data, project, *args, **kwargs): + self.project_id = project_data['project'] + self.project_data = project_data + self.resource = project + self.args = args + self.kwargs = kwargs + + def instantiate(self, project): + return [project] + + @provide_action('action', 'Save') + def save(self, project_data, project, *args, **kwargs): + self.action = "save" + + @provide_action('behavior', 'Update') + def update(self, project_data, project, *args, **kwargs): + self.action = "update" + + foo = PrestHandler() + foo.project = ProjectHandler() + handler, resource, data, extra = foo.decode([None, 'project', '83', + 'bloop', 'yeah']) + assert handler is foo.project + self.assertEqual({'project': '83'}, data) + self.assertEqual(['bloop', 'yeah'], extra) + foo.default(*['project', '27', 'extra'], **{'a':'b', 'b':'97'}) + self.assertEqual(foo.project.args, ('extra',)) + self.assertEqual(foo.project.kwargs, {'a':'b', 'b':'97'}) + self.assertEqual(foo.project.project_data, {'project': '27'}) + self.assertEqual(foo.project.resource, ['27']) + foo.default(*['project', '27', 'extra'], **{'action':'Save', 'b':'97'}) + self.assertEqual(foo.project.action, 'save') + foo.default(*['project', '27', 'extra'], + **{'behavior':'Update', 'b':'97'}) + self.assertEqual(foo.project.action, 'update') + self.assertRaises(AmbiguousAction, foo.default, + *['project', '27', 'extra'], + **{'behavior':'Update', 'action':'Save', 'b':'97'}) + + class BugHandler(PrestHandler): + actions = {} + def dispatch(self, bug_data, bug, *args, **kwargs): + self.project_id = project_data['project'] + self.project_data = project_data + self.resource = project + self.args = args + self.kwargs = kwargs + + def instantiate(self, project, bug): + return [project, bug] + + @provide_action('action', 'Save') + def save(self, project_data, project, *args, **kwargs): + self.action = "save" + + @provide_action('behavior', 'Update') + def update(self, project_data, project, *args, **kwargs): + self.action = "update" + + foo.project.bug = BugHandler() + handler, resource, data, extra = foo.decode([None, 'project', '83', + 'bug', '92']) + assert handler is foo.project.bug + self.assertEqual(resource[0], '83') + self.assertEqual(resource[1], '92') + self.assertEqual([], extra) + self.assertEqual(data['project'], '83') + self.assertEqual(data['bug'], '92') + +def test(): + patchesTestSuite = unittest.makeSuite(PrestTester,'test') + runner = unittest.TextTestRunner(verbosity=0) + return runner.run(patchesTestSuite) + + +if __name__ == "__main__": + test() diff --git a/interfaces/web/Bugs-Everywhere-Web/beweb/release.py b/interfaces/web/Bugs-Everywhere-Web/beweb/release.py new file mode 100644 index 0000000..9d64bf7 --- /dev/null +++ b/interfaces/web/Bugs-Everywhere-Web/beweb/release.py @@ -0,0 +1,14 @@ +# Release information about Bugs-Everywhere-Web + +version = "1.0" + +# description = "Your plan to rule the world" +# long_description = "More description about your plan" +# author = "Your Name Here" +# email = "YourEmail@YourDomain" +# copyright = "Vintage 2006 - a good year indeed" + +# if it's open source, you might want to specify these +# url = "http://yourcool.site/" +# download_url = "http://yourcool.site/download" +# license = "MIT" diff --git a/interfaces/web/Bugs-Everywhere-Web/beweb/static/css/style.css b/interfaces/web/Bugs-Everywhere-Web/beweb/static/css/style.css new file mode 100644 index 0000000..6fe197f --- /dev/null +++ b/interfaces/web/Bugs-Everywhere-Web/beweb/static/css/style.css @@ -0,0 +1,116 @@ +table +{ + background-color: black; +} +td +{ + background-color: white; +} +h1 +{ + font-family: "Verdana"; + font-weight: bold; + font-size: 120%; + margin-bottom:0; + color: #990; +} + +tr.closed td +{ + background-color: #ccc; +} +tr.closedeven td +{ + background-color: #ccc; +} +tr.closedodd td +{ + background-color: #dda; +} + +a:visited, a:link +{ + color: #990; + text-decoration: None; +} +td a:visited, td a:link +{ + display: block; +} +a:visited:hover, a:link:hover +{ + text-decoration: underline; +} +td a:visited:hover, td a:link:hover +{ + color:black; + background-color:#dda; + text-decoration: None; + display: block; +} + +body +{ + font-family: "Verdana"; + font-size:11pt; + background-color: white; +} +.comment +{ +} +.comment table +{ + background-color: transparent; +} +.comment td +{ + background-color: transparent; +} +.comment pre +{ + font-family: "Verdana"; +} +#header +{ + color: black; + font-weight: bold; + background-image: url(/static/images/half-spiral.png); + background-position: right center; + background-repeat: no-repeat; + background-color: #ff0; +} +#header ul.navoption +{ + display: block; + float: right; + margin: 0; + padding-right: 30px; +} +#header li +{ + display: inline; + margin:0; + padding:0; +} +table.insetbox +{ + margin-top: 0.5em; + margin-bottom: 0.5em; +} +.insetbox tr, .insetbox td +{ + margin: 0; + padding: 0; +} +pre.traceback +{ + font-family: Verdana, Ariel, Helvetica, sanserif; +} +tr.even td +{ + background-color: #eee; +} +tr.odd td +{ + background-color: #ffe; +} diff --git a/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/ds-b.png b/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/ds-b.png new file mode 100644 index 0000000..790e438 Binary files /dev/null and b/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/ds-b.png differ diff --git a/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/ds-bl.png b/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/ds-bl.png new file mode 100644 index 0000000..5b43259 Binary files /dev/null and b/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/ds-bl.png differ diff --git a/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/ds-br.png b/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/ds-br.png new file mode 100644 index 0000000..6cfd62c Binary files /dev/null and b/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/ds-br.png differ diff --git a/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/ds-l.png b/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/ds-l.png new file mode 100644 index 0000000..a6ce3ce Binary files /dev/null and b/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/ds-l.png differ diff --git a/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/ds-r.png b/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/ds-r.png new file mode 100644 index 0000000..1ffd6f8 Binary files /dev/null and b/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/ds-r.png differ diff --git a/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/ds-t.png b/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/ds-t.png new file mode 100644 index 0000000..0129b0c Binary files /dev/null and b/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/ds-t.png differ diff --git a/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/ds-tl.png b/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/ds-tl.png new file mode 100644 index 0000000..d616b77 Binary files /dev/null and b/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/ds-tl.png differ diff --git a/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/ds-tr.png b/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/ds-tr.png new file mode 100644 index 0000000..18e542e Binary files /dev/null and b/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/ds-tr.png differ diff --git a/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/ds2-b.png b/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/ds2-b.png new file mode 100644 index 0000000..05a190e Binary files /dev/null and b/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/ds2-b.png differ diff --git a/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/ds2-r.png b/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/ds2-r.png new file mode 100644 index 0000000..0c3ea4c Binary files /dev/null and b/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/ds2-r.png differ diff --git a/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/favicon.ico b/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/favicon.ico new file mode 100644 index 0000000..339d09c Binary files /dev/null and b/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/favicon.ico differ diff --git a/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/favicon.png b/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/favicon.png new file mode 100644 index 0000000..6dc53ee Binary files /dev/null and b/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/favicon.png differ diff --git a/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/half-spiral.png b/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/half-spiral.png new file mode 100644 index 0000000..cb4b56c Binary files /dev/null and b/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/half-spiral.png differ diff --git a/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/header_inner.png b/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/header_inner.png new file mode 100644 index 0000000..2b2d87d Binary files /dev/null and b/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/header_inner.png differ diff --git a/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/info.png b/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/info.png new file mode 100644 index 0000000..329c523 Binary files /dev/null and b/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/info.png differ diff --git a/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/is-b.png b/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/is-b.png new file mode 100644 index 0000000..25d3cfa Binary files /dev/null and b/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/is-b.png differ diff --git a/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/is-bl.png b/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/is-bl.png new file mode 100644 index 0000000..f496223 Binary files /dev/null and b/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/is-bl.png differ diff --git a/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/is-br.png b/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/is-br.png new file mode 100644 index 0000000..74cbd91 Binary files /dev/null and b/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/is-br.png differ diff --git a/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/is-l.png b/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/is-l.png new file mode 100644 index 0000000..dd567fa Binary files /dev/null and b/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/is-l.png differ diff --git a/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/is-r.png b/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/is-r.png new file mode 100644 index 0000000..9ac4486 Binary files /dev/null and b/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/is-r.png differ diff --git a/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/is-t.png b/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/is-t.png new file mode 100644 index 0000000..fbb06c8 Binary files /dev/null and b/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/is-t.png differ diff --git a/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/is-tl.png b/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/is-tl.png new file mode 100644 index 0000000..9336290 Binary files /dev/null and b/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/is-tl.png differ diff --git a/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/is-tr.png b/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/is-tr.png new file mode 100644 index 0000000..de74808 Binary files /dev/null and b/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/is-tr.png differ diff --git a/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/ok.png b/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/ok.png new file mode 100644 index 0000000..fee6751 Binary files /dev/null and b/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/ok.png differ diff --git a/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/shadows.png b/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/shadows.png new file mode 100644 index 0000000..9ddc676 Binary files /dev/null and b/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/shadows.png differ diff --git a/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/spiral.png b/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/spiral.png new file mode 100644 index 0000000..b4bcb1e Binary files /dev/null and b/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/spiral.png differ diff --git a/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/tg_under_the_hood.png b/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/tg_under_the_hood.png new file mode 100644 index 0000000..bc9c79c Binary files /dev/null and b/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/tg_under_the_hood.png differ diff --git a/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/under_the_hood_blue.png b/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/under_the_hood_blue.png new file mode 100644 index 0000000..90e84b7 Binary files /dev/null and b/interfaces/web/Bugs-Everywhere-Web/beweb/static/images/under_the_hood_blue.png differ diff --git a/interfaces/web/Bugs-Everywhere-Web/beweb/templates/__init__.py b/interfaces/web/Bugs-Everywhere-Web/beweb/templates/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/interfaces/web/Bugs-Everywhere-Web/beweb/templates/about.kid b/interfaces/web/Bugs-Everywhere-Web/beweb/templates/about.kid new file mode 100644 index 0000000..fa3548a --- /dev/null +++ b/interfaces/web/Bugs-Everywhere-Web/beweb/templates/about.kid @@ -0,0 +1,21 @@ + + + + + About Bugs Everywhere + + + +

About Bugs Everywhere

+

Bugs Everywhere is a "distributed bugtracker", designed to complement distributed revision control systems. +

+

+Bugs Everywhere was conceived and written by developers at Panoramic Feedback, primarily Aaron Bentley. Panoramic Feedback is no longer developing BE, and the current maintainer is Chris Ball. +

+

+ Bugs Everywhere web site +

+Project List + + diff --git a/interfaces/web/Bugs-Everywhere-Web/beweb/templates/bugs.kid b/interfaces/web/Bugs-Everywhere-Web/beweb/templates/bugs.kid new file mode 100644 index 0000000..198aa94 --- /dev/null +++ b/interfaces/web/Bugs-Everywhere-Web/beweb/templates/bugs.kid @@ -0,0 +1,52 @@ + + + + + + + Bugs for $project_name + + + +

Bug list for ${project_name}

+ + +
+ +
IDStatusSeverityAssigned ToCommentsSummary
${unique_name(bug, bugs[:])}${bug.status}${bug.severity}${people.get(bug.assigned, bug.assigned)}${len(list(bug.iter_comment_ids()))}${bug.summary}
+Project list +Toggle closed +
+ +
+
+ + + +
+ + diff --git a/interfaces/web/Bugs-Everywhere-Web/beweb/templates/edit_bug.kid b/interfaces/web/Bugs-Everywhere-Web/beweb/templates/edit_bug.kid new file mode 100644 index 0000000..276f610 --- /dev/null +++ b/interfaces/web/Bugs-Everywhere-Web/beweb/templates/edit_bug.kid @@ -0,0 +1,52 @@ + + + + + + + Edit bug + + + +

Edit bug

+
+ + + + +
StatusSeverityAssigned ToSummary
${select_among("status", status_values, bug.status)}${select_among("severity", severity_values, bug.severity)}${select_among("assigned", people.keys()+[None], bug.assigned, people)}
+
+ + + + +
From${comment.From}
Date${time_to_str(comment.time)}
+
+ Edit + Reply +
+
+
+ ${show_comment(child, grandchildren)} +
+
+
+
+ ${show_comment(comment, children)} +
+

+

+
+Bug List + + diff --git a/interfaces/web/Bugs-Everywhere-Web/beweb/templates/edit_comment.kid b/interfaces/web/Bugs-Everywhere-Web/beweb/templates/edit_comment.kid new file mode 100644 index 0000000..2b522d4 --- /dev/null +++ b/interfaces/web/Bugs-Everywhere-Web/beweb/templates/edit_comment.kid @@ -0,0 +1,26 @@ + + + + + + + Edit comment + + + +

Edit comment

+
+ + + +
From${comment.From}
Date${time_to_str(comment.time)}
+