aboutsummaryrefslogtreecommitdiffstats
path: root/interfaces
diff options
context:
space:
mode:
authorAnand Aiyer <aaiyer@gmail.com>2016-10-31 16:27:01 +0530
committerMatěj Cepl <mcepl@cepl.eu>2024-01-18 19:01:59 +0100
commit4f7099d9c808fa646f24540039af4ee8e7f943ab (patch)
tree326e4a847a448791ae9c0f4ee0af89c1257adc94 /interfaces
parent5e1b5fe911d4805133357e329d009f998300867d (diff)
downloadbugseverywhere-4f7099d9c808fa646f24540039af4ee8e7f943ab.tar.gz
* Forked bugseverywhere -- so update the README
* Fix web interface issue with editing a bug * Integrate the web interface into the be command line, so it can be invoked easily using 'be web'
Diffstat (limited to 'interfaces')
-rw-r--r--interfaces/web/.hgignore6
-rw-r--r--interfaces/web/.hgtags2
-rw-r--r--interfaces/web/LICENSE24
-rw-r--r--interfaces/web/README20
-rw-r--r--interfaces/web/__init__.py0
-rwxr-xr-xinterfaces/web/cfbe.py42
-rw-r--r--interfaces/web/static/scripts/jquery.corners.min.js7
-rw-r--r--interfaces/web/static/style/aal.css99
-rw-r--r--interfaces/web/static/style/cfbe.css180
-rw-r--r--interfaces/web/templates/base.html123
-rw-r--r--interfaces/web/templates/bug.html160
-rw-r--r--interfaces/web/templates/empty-list.html11
-rw-r--r--interfaces/web/templates/list.html25
-rw-r--r--interfaces/web/web.py211
14 files changed, 0 insertions, 910 deletions
diff --git a/interfaces/web/.hgignore b/interfaces/web/.hgignore
deleted file mode 100644
index a0e81b7..0000000
--- a/interfaces/web/.hgignore
+++ /dev/null
@@ -1,6 +0,0 @@
-syntax: glob
-*.pyc
-.DS_Store
-*.log
-*.tmproj
-
diff --git a/interfaces/web/.hgtags b/interfaces/web/.hgtags
deleted file mode 100644
index eeea432..0000000
--- a/interfaces/web/.hgtags
+++ /dev/null
@@ -1,2 +0,0 @@
-8d8c7f52f3afb6026dd47d7303a7f6a734b3177d alpha
-abfe7aa4bdf3cd019ad1d51278c293a4e008b397 alpha
diff --git a/interfaces/web/LICENSE b/interfaces/web/LICENSE
deleted file mode 100644
index 44f0935..0000000
--- a/interfaces/web/LICENSE
+++ /dev/null
@@ -1,24 +0,0 @@
-
-copyrev: 566007698e1bb8a4f0bc4929a68ecc068ab28890
-copy: LICENSE.txt
-
-Copyright (c) 2009 Steve Losh
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-
diff --git a/interfaces/web/README b/interfaces/web/README
deleted file mode 100644
index 6bd04e5..0000000
--- a/interfaces/web/README
+++ /dev/null
@@ -1,20 +0,0 @@
--*- markdown -*-
-
-Cherry Flavored Bugs Everywhere
-===============================
-
-CFBE is a quick web interface to [BugsEverywhere](http://bugseverywhere.org/). It's still very much a work-in-progress.
-
-Installing
-----------
-
-I intend to streamline the installation once I'm satisfied with the interface itself. For now, the install process goes something like this:
-
-* Install [CherryPy](http://cherrypy.org/) if you don't have it.
-* Install [Jinja2](http://jinja.pocoo.org/2/) if you don't have it.
-* Install [BugsEverywhere](http://bugseverywhere.org/) if you don't have it.
-* Download a zip/tar of CFBE (or hg clone) from the [Mercurial repository](http://bitbucket.org/sjl/cherryflavoredbugseverywhere/).
-* Unzip (if you grabbed a zip) and put the folder in your Python site-packages directory (or put it anywhere and symlink it to site-packages).
-* Symlink `site-packages/cherryflavoredbugseverywhere/cfbe.py` to `/usr/local/bin/cfbe`
-* Use `cfbe [project_root]` to start up the web interface for that project.
-* Visit http://localhost:8080/ in a browser.
diff --git a/interfaces/web/__init__.py b/interfaces/web/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/interfaces/web/__init__.py
+++ /dev/null
diff --git a/interfaces/web/cfbe.py b/interfaces/web/cfbe.py
deleted file mode 100755
index 68c484d..0000000
--- a/interfaces/web/cfbe.py
+++ /dev/null
@@ -1,42 +0,0 @@
-#!/usr/bin/env python
-
-import cherrypy
-import web
-from optparse import OptionParser
-from os import path
-
-module_dir = path.dirname(path.abspath(web.__file__))
-template_dir = path.join(module_dir, 'templates')
-
-def build_parser():
- """Builds and returns the command line option parser."""
-
- usage = 'usage: %prog bug_directory'
- parser = OptionParser(usage)
- return parser
-
-def parse_arguments():
- """Parse the command line arguments."""
-
- parser = build_parser()
- (options, args) = parser.parse_args()
-
- if len(args) != 1:
- parser.error('You need to specify a bug directory.')
-
- return { 'bug_root': args[0], }
-
-
-config = path.join(module_dir, 'cfbe.config')
-options = parse_arguments()
-
-WebInterface = web.WebInterface(path.abspath(options['bug_root']), template_dir)
-
-cherrypy.config.update({
- 'tools.encode.on': True,
- 'tools.encode.encoding': 'utf8',
- 'tools.staticdir.root': path.join(module_dir, 'static'),
- })
-app_config = { '/static': { 'tools.staticdir.on': True,
- 'tools.staticdir.dir': '', } }
-cherrypy.quickstart(WebInterface, '/', app_config)
diff --git a/interfaces/web/static/scripts/jquery.corners.min.js b/interfaces/web/static/scripts/jquery.corners.min.js
deleted file mode 100644
index 0b2f979..0000000
--- a/interfaces/web/static/scripts/jquery.corners.min.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/*
- * jQuery Corners 0.3
- * Copyright (c) 2008 David Turnbull, Steven Wittens
- * Dual licensed under the MIT (MIT-LICENSE.txt)
- * and GPL (GPL-LICENSE.txt) licenses.
- */
-jQuery.fn.corners=function(C){var N="rounded_by_jQuery_corners";var V=B(C);var F=false;try{F=(document.body.style.WebkitBorderRadius!==undefined);var Y=navigator.userAgent.indexOf("Chrome");if(Y>=0){F=false}}catch(E){}var W=false;try{W=(document.body.style.MozBorderRadius!==undefined);var Y=navigator.userAgent.indexOf("Firefox");if(Y>=0&&parseInt(navigator.userAgent.substring(Y+8))<3){W=false}}catch(E){}return this.each(function(b,h){$e=jQuery(h);if($e.hasClass(N)){return }$e.addClass(N);var a=/{(.*)}/.exec(h.className);var c=a?B(a[1],V):V;var j=h.nodeName.toLowerCase();if(j=="input"){h=O(h)}if(F&&c.webkit){K(h,c)}else{if(W&&c.mozilla&&(c.sizex==c.sizey)){M(h,c)}else{var d=D(h.parentNode);var f=D(h);switch(j){case"a":case"input":Z(h,c,d,f);break;default:R(h,c,d,f);break}}}});function K(d,c){var a=""+c.sizex+"px "+c.sizey+"px";var b=jQuery(d);if(c.tl){b.css("WebkitBorderTopLeftRadius",a)}if(c.tr){b.css("WebkitBorderTopRightRadius",a)}if(c.bl){b.css("WebkitBorderBottomLeftRadius",a)}if(c.br){b.css("WebkitBorderBottomRightRadius",a)}}function M(d,c){var a=""+c.sizex+"px";var b=jQuery(d);if(c.tl){b.css("-moz-border-radius-topleft",a)}if(c.tr){b.css("-moz-border-radius-topright",a)}if(c.bl){b.css("-moz-border-radius-bottomleft",a)}if(c.br){b.css("-moz-border-radius-bottomright",a)}}function Z(k,n,l,a){var m=S("table");var i=S("tbody");m.appendChild(i);var j=S("tr");var d=S("td","top");j.appendChild(d);var h=S("tr");var c=T(k,n,S("td"));h.appendChild(c);var f=S("tr");var b=S("td","bottom");f.appendChild(b);if(n.tl||n.tr){i.appendChild(j);X(d,n,l,a,true)}i.appendChild(h);if(n.bl||n.br){i.appendChild(f);X(b,n,l,a,false)}k.appendChild(m);if(jQuery.browser.msie){m.onclick=Q}k.style.overflow="hidden"}function Q(){if(!this.parentNode.onclick){this.parentNode.click()}}function O(c){var b=document.createElement("a");b.id=c.id;b.className=c.className;if(c.onclick){b.href="javascript:";b.onclick=c.onclick}else{jQuery(c).parent("form").each(function(){b.href=this.action});b.onclick=I}var a=document.createTextNode(c.value);b.appendChild(a);c.parentNode.replaceChild(b,c);return b}function I(){jQuery(this).parent("form").each(function(){this.submit()});return false}function R(d,a,b,c){var f=T(d,a,document.createElement("div"));d.appendChild(f);if(a.tl||a.tr){X(d,a,b,c,true)}if(a.bl||a.br){X(d,a,b,c,false)}}function T(j,i,k){var b=jQuery(j);var l;while(l=j.firstChild){k.appendChild(l)}if(j.style.height){var f=parseInt(b.css("height"));k.style.height=f+"px";f+=parseInt(b.css("padding-top"))+parseInt(b.css("padding-bottom"));j.style.height=f+"px"}if(j.style.width){var a=parseInt(b.css("width"));k.style.width=a+"px";a+=parseInt(b.css("padding-left"))+parseInt(b.css("padding-right"));j.style.width=a+"px"}k.style.paddingLeft=b.css("padding-left");k.style.paddingRight=b.css("padding-right");if(i.tl||i.tr){k.style.paddingTop=U(j,i,b.css("padding-top"),true)}else{k.style.paddingTop=b.css("padding-top")}if(i.bl||i.br){k.style.paddingBottom=U(j,i,b.css("padding-bottom"),false)}else{k.style.paddingBottom=b.css("padding-bottom")}j.style.padding=0;return k}function U(f,a,d,c){if(d.indexOf("px")<0){try{console.error("%s padding not in pixels",(c?"top":"bottom"),f)}catch(b){}d=a.sizey+"px"}d=parseInt(d);if(d-a.sizey<0){try{console.error("%s padding is %ipx for %ipx corner:",(c?"top":"bottom"),d,a.sizey,f)}catch(b){}d=a.sizey}return d-a.sizey+"px"}function S(b,a){var c=document.createElement(b);c.style.border="none";c.style.borderCollapse="collapse";c.style.borderSpacing=0;c.style.padding=0;c.style.margin=0;if(a){c.style.verticalAlign=a}return c}function D(b){try{var d=jQuery.css(b,"background-color");if(d.match(/^(transparent|rgba\(0,\s*0,\s*0,\s*0\))$/i)&&b.parentNode){return D(b.parentNode)}if(d==null){return"#ffffff"}if(d.indexOf("rgb")>-1){d=A(d)}if(d.length==4){d=L(d)}return d}catch(a){return"#ffffff"}}function L(a){return"#"+a.substring(1,2)+a.substring(1,2)+a.substring(2,3)+a.substring(2,3)+a.substring(3,4)+a.substring(3,4)}function A(h){var a=255;var d="";var b;var e=/([0-9]+)[, ]+([0-9]+)[, ]+([0-9]+)/;var f=e.exec(h);for(b=1;b<4;b++){d+=("0"+parseInt(f[b]).toString(16)).slice(-2)}return"#"+d}function B(b,d){var b=b||"";var c={sizex:5,sizey:5,tl:false,tr:false,bl:false,br:false,webkit:true,mozilla:true,transparent:false};if(d){c.sizex=d.sizex;c.sizey=d.sizey;c.webkit=d.webkit;c.transparent=d.transparent;c.mozilla=d.mozilla}var a=false;var e=false;jQuery.each(b.split(" "),function(f,j){j=j.toLowerCase();var h=parseInt(j);if(h>0&&j==h+"px"){c.sizey=h;if(!a){c.sizex=h}a=true}else{switch(j){case"no-native":c.webkit=c.mozilla=false;break;case"webkit":c.webkit=true;break;case"no-webkit":c.webkit=false;break;case"mozilla":c.mozilla=true;break;case"no-mozilla":c.mozilla=false;break;case"anti-alias":c.transparent=false;break;case"transparent":c.transparent=true;break;case"top":e=c.tl=c.tr=true;break;case"right":e=c.tr=c.br=true;break;case"bottom":e=c.bl=c.br=true;break;case"left":e=c.tl=c.bl=true;break;case"top-left":e=c.tl=true;break;case"top-right":e=c.tr=true;break;case"bottom-left":e=c.bl=true;break;case"bottom-right":e=c.br=true;break}}});if(!e){if(!d){c.tl=c.tr=c.bl=c.br=true}else{c.tl=d.tl;c.tr=d.tr;c.bl=d.bl;c.br=d.br}}return c}function P(f,d,h){var e=Array(parseInt("0x"+f.substring(1,3)),parseInt("0x"+f.substring(3,5)),parseInt("0x"+f.substring(5,7)));var c=Array(parseInt("0x"+d.substring(1,3)),parseInt("0x"+d.substring(3,5)),parseInt("0x"+d.substring(5,7)));r="0"+Math.round(e[0]+(c[0]-e[0])*h).toString(16);g="0"+Math.round(e[1]+(c[1]-e[1])*h).toString(16);d="0"+Math.round(e[2]+(c[2]-e[2])*h).toString(16);return"#"+r.substring(r.length-2)+g.substring(g.length-2)+d.substring(d.length-2)}function X(f,a,b,d,c){if(a.transparent){G(f,a,b,c)}else{J(f,a,b,d,c)}}function J(k,z,p,a,n){var h,f;var l=document.createElement("div");l.style.fontSize="1px";l.style.backgroundColor=p;var b=0;for(h=1;h<=z.sizey;h++){var u,t,q;arc=Math.sqrt(1-Math.pow(1-h/z.sizey,2))*z.sizex;var c=z.sizex-Math.ceil(arc);var w=Math.floor(b);var v=z.sizex-c-w;var o=document.createElement("div");var m=l;o.style.margin="0px "+c+"px";o.style.height="1px";o.style.overflow="hidden";for(f=1;f<=v;f++){if(f==1){if(f==v){u=((arc+b)*0.5)-w}else{t=Math.sqrt(1-Math.pow(1-(c+1)/z.sizex,2))*z.sizey;u=(t-(z.sizey-h))*(arc-w-v+1)*0.5}}else{if(f==v){t=Math.sqrt(1-Math.pow((z.sizex-c-f+1)/z.sizex,2))*z.sizey;u=1-(1-(t-(z.sizey-h)))*(1-(b-w))*0.5}else{q=Math.sqrt(1-Math.pow((z.sizex-c-f)/z.sizex,2))*z.sizey;t=Math.sqrt(1-Math.pow((z.sizex-c-f+1)/z.sizex,2))*z.sizey;u=((t+q)*0.5)-(z.sizey-h)}}H(z,o,m,n,P(p,a,u));m=o;var o=m.cloneNode(false);o.style.margin="0px 1px"}H(z,o,m,n,a);b=arc}if(n){k.insertBefore(l,k.firstChild)}else{k.appendChild(l)}}function H(c,a,e,d,b){if(d&&!c.tl){a.style.marginLeft=0}if(d&&!c.tr){a.style.marginRight=0}if(!d&&!c.bl){a.style.marginLeft=0}if(!d&&!c.br){a.style.marginRight=0}a.style.backgroundColor=b;if(d){e.appendChild(a)}else{e.insertBefore(a,e.firstChild)}}function G(c,o,l,h){var f=document.createElement("div");f.style.fontSize="1px";var a=document.createElement("div");a.style.overflow="hidden";a.style.height="1px";a.style.borderColor=l;a.style.borderStyle="none solid";var m=o.sizex-1;var j=o.sizey-1;if(!j){j=1}for(var b=0;b<o.sizey;b++){var n=m-Math.floor(Math.sqrt(1-Math.pow(1-b/j,2))*m);if(b==2&&o.sizex==6&&o.sizey==6){n=2}var k=a.cloneNode(false);k.style.borderWidth="0 "+n+"px";if(h){k.style.borderWidth="0 "+(o.tr?n:0)+"px 0 "+(o.tl?n:0)+"px"}else{k.style.borderWidth="0 "+(o.br?n:0)+"px 0 "+(o.bl?n:0)+"px"}h?f.appendChild(k):f.insertBefore(k,f.firstChild)}if(h){c.insertBefore(f,c.firstChild)}else{c.appendChild(f)}}}; \ No newline at end of file
diff --git a/interfaces/web/static/style/aal.css b/interfaces/web/static/style/aal.css
deleted file mode 100644
index 9bad98f..0000000
--- a/interfaces/web/static/style/aal.css
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- aardvark.legs by Anatoli Papirovski - http://fecklessmind.com/
- Licensed under the MIT license. http://www.opensource.org/licenses/mit-license.php
-*/
-
-/*
- Reset first. Modified version of Eric Meyer and Paul Chaplin reset
- from http://meyerweb.com/eric/tools/css/reset/
-*/
-html, body, div, span, applet, object, iframe,
-h1, h2, h3, h4, h5, h6, p, blockquote, pre,
-a, abbr, acronym, address, big, cite, code,
-del, dfn, em, font, img, ins, kbd, q, s, samp,
-small, strike, strong, sub, sup, tt, var,
-b, u, i, center,
-dl, dt, dd, ol, ul, li,
-fieldset, form, label, legend,
-table, caption, tbody, tfoot, thead, tr, th, td,
-header, nav, section, article, aside, footer
-{border: 0; margin: 0; outline: 0; padding: 0; background: transparent; vertical-align: baseline;}
-
-blockquote, q {quotes: none;}
-blockquote:before,blockquote:after,q:before,q:after {content: ''; content: none;}
-
-header, nav, section, article, aside, footer {display: block;}
-
-/* Basic styles */
-body {background: #fff; color: #000; font: 0.875em/1.5em "Helvetica Neue", Helvetica, Arial, "Liberation Sans", "Bitstream Vera Sans", sans-serif;}
-html>body {font-size: 14px;}
-
-img {display: inline-block; vertical-align: bottom;}
-
-h1,h2,h3,h4,h5,h6,strong,b,dt,th {font-weight: 700;}
-address,cite,em,i,caption,dfn,var {font-style: italic;}
-
-h1 {margin: 0 0 0.75em; font-size: 2em;}
-h2 {margin: 0 0 1em; font-size: 1.5em;}
-h3 {margin: 0 0 1.286em; font-size: 1.167em;}
-h4 {margin: 0 0 1.5em; font-size: 1em;}
-h5 {margin: 0 0 1.8em; font-size: .834em;}
-h6 {margin: 0 0 2em; font-size: .75em;}
-
-p,ul,ol,dl,blockquote,pre {margin: 0 0 1.5em;}
-
-li ul,li ol {margin: 0;}
-ul {list-style: outside disc;}
-ol {list-style: outside decimal;}
-li {margin: 0 0 0 2em;}
-dd {padding-left: 1.5em;}
-blockquote {padding: 0 1.5em;}
-
-a {text-decoration: underline;}
-a:hover {text-decoration: none;}
-abbr,acronym {border-bottom: 1px dotted; cursor: help;}
-del {text-decoration: line-through;}
-ins {text-decoration: overline;}
-sub {font-size: .834em; line-height: 1em; vertical-align: sub;}
-sup {font-size: .834em; line-height: 1em; vertical-align: super;}
-
-tt,code,kbd,samp,pre {font-size: 1em; font-family: "Courier New", Courier, monospace;}
-
-/* Table styles */
-table {border-collapse: collapse; border-spacing: 0; margin: 0 0 1.5em;}
-caption {text-align: left;}
-th, td {padding: .25em .5em;}
-tbody td, tbody th {border: 1px solid #000;}
-tfoot {font-style: italic;}
-
-/* Form styles */
-fieldset {clear: both;}
-legend {padding: 0 0 1.286em; font-size: 1.167em; font-weight: 700;}
-fieldset fieldset legend {padding: 0 0 1.5em; font-size: 1em;}
-* html legend {margin-left: -7px;}
-*+html legend {margin-left: -7px;}
-
-form .field, form .buttons {clear: both; margin: 0 0 1.5em;}
-form .field label {display: block;}
-form ul.fields li {list-style-type: none; margin: 0;}
-form ul.inline li, form ul.inline label {display: inline;}
-form ul.inline li {padding: 0 .75em 0 0;}
-
-input.radio, input.checkbox {vertical-align: top;}
-label, button, input.submit, input.image {cursor: pointer;}
-* html input.radio, * html input.checkbox {vertical-align: middle;}
-*+html input.radio, *+html input.checkbox {vertical-align: middle;}
-
-textarea {overflow: auto;}
-input.text, input.password, textarea, select {margin: 0; font: 1em/1.3 Helvetica, Arial, "Liberation Sans", "Bitstream Vera Sans", sans-serif; vertical-align: bottom;}
-input.text, input.password, textarea {border: 1px solid #444; border-bottom-color: #666; border-right-color: #666; padding: 2px;}
-
-* html button {margin: 0 .34em 0 0;}
-*+html button {margin: 0 .34em 0 0;}
-
-form.horizontal .field {padding-left: 150px;}
-form.horizontal .field label {display: inline; float: left; width: 140px; margin-left: -150px;}
-
-/* Useful classes */
-img.left {display: inline; float: left; margin: 0 1.5em .75em 0;}
-img.right {display: inline; float: right; margin: 0 0 .75em .75em;} \ No newline at end of file
diff --git a/interfaces/web/static/style/cfbe.css b/interfaces/web/static/style/cfbe.css
deleted file mode 100644
index 2d7b90b..0000000
--- a/interfaces/web/static/style/cfbe.css
+++ /dev/null
@@ -1,180 +0,0 @@
-/* @override http://localhost:8080/static/style/cfbe.css */
-
-body {
- background-color: #eee;
-}
-
-div#main-pane {
- width: 960px;
- margin: 3em auto;
- border: 1px solid #888;
- background-color: #fcfcfc;
-}
-.inside-main-pane {
- padding: 0em 3em;
-}
-
-div#header {
- background-color: #D8004A;
- height: 6em;
-}
-div#header h1 {
- font-size: 4em;
- line-height: 1.5em;
- margin-bottom: 0em;
- color: #fff;
- font-weight: normal;
- font-family: "Helvetica Neue Ultra Light", "HelveticaNeue-UltraLight", "Helvetica", "Arial", sans-serif;
- letter-spacing: 1px;
-}
-
-div#navigation {
- height: 3em;
- line-height: 3em;
- border-bottom: 1px solid #888;
-}
-div#content-pane {
- margin: 1.5em 0em 3em;
-}
-
-div#filter-pane {
- display: none;
- border-bottom: 1px solid #888;
- line-height: 3em;
- text-align: right;
-}
-ul.filter-items {
- list-style-type: none;
- margin: 0em;
- padding: 0em;
-}
-ul.filter-items li {
- display: inline;
- margin-left: 1.5em;
-}
-
-div#footer {
- text-align: center;
- height: 3em;
- border-top: 1px solid #888;
-}
-div#footer p {
- font-size: 0.9em;
- line-height: 3.333em;
-}
-
-span#filters {
- float: right;
-}
-span#filters a {
- margin-left: 1.5em;
-}
-
-a:link, a:visited, a:active {
- color: #d03; text-decoration: none; font-weight: bold;
-}
-a:hover {
- color: #60b305;
-}
-
-.header-with-link {
- display: inline-block;
-}
-.header-link {
- margin-left: 1em;
-}
-
-table#bug-list {
- width: 100%; border-collapse: collapse; border: 0.084em solid #ccc;
-}
-table#bug-list td, table#bug-list th {
- border: 0em; border-bottom: 0.084em solid #ccc; text-align: left;
-}
-table tr td, table tr th {
- padding: 0px 5px;
-}
-table tr td {
- line-height: 2.832em; padding-bottom: 0.084em;
-}
-table tr th {
- line-height: 2.916em;
-}
-table {
- margin-bottom: 1.417em;
-}
-tr.stripe {
- background-color: #fcecf8;
-}
-
-div#assignees, div#targets, div#tags {
- display: none;
-}
-
-p.creation-info {
- color: #888;
-}
-span.detail-field-header {
- font-weight: 700;
- width: 7.5em;
- padding-right: 1em;
- display: inline-block;
- text-align: right;
-}
-
-div.bug-comment {
- margin-left: 2em;
-}
-p.bug-comment-body {
- white-space: pre;
- margin: 0em 0em 0em 0em;
-}
-p.bug-comment-footer {
- margin: 0em 0em; color: #888;
-}
-h4.bug-comment-header {
- margin: 1.5em 0em 0em;
-}
-
-#create-form {
- display: none;
-}
-#create-form fieldset {
- clear: none;
-}
-#create-form input#create-summary {
- width: 20em;
- border: 1px solid #888;
- margin-right: 1.5em;
-}
-#create-button {
- margin: 0em;
-}
-
-form#add-comment-form {
- display: none;
- margin-top: 1.5em;
-}
-p#add-comment-link {
- margin-top: 1.5em;
-}
-
-form#bug-details-edit-form {
- display: none;
-}
-form#bug-details-edit-form label {
- font-weight: 700;
- width: 7.5em;
- margin-left: 0em;
- margin-right: 1em;
- text-align: right;
-}
-form#bug-details-edit-form .field {
- padding-left: 0em;
-}
-
-form#bug-summary-edit-form {
- display: none;
-}
-input#bug-summary-edit-body {
- width: 95%;
-}
diff --git a/interfaces/web/templates/base.html b/interfaces/web/templates/base.html
deleted file mode 100644
index 5287470..0000000
--- a/interfaces/web/templates/base.html
+++ /dev/null
@@ -1,123 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-
-<html>
- <head>
- <title>Cherry Flavored Bugs Everywhere!</title>
-
- <link rel="stylesheet" type="text/css" media="screen"
- href="/static/style/aal.css" />
- <link rel="stylesheet" type="text/css" media="screen"
- href="/static/style/cfbe.css" />
-
- <script type="text/javascript"
- src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js">
- </script>
-
- <script type="text/javascript"
- src="/static/scripts/jquery.corners.min.js">
- </script>
-
- <script type="text/javascript">
- $(function() {
- $('#filter-assignee').click(function(e) {
- $('#filter-pane').html($('#assignees').html());
- $('#filter-pane').fadeIn('fast');
- e.preventDefault();
- });
-
- $('#filter-target').click(function(e) {
- $('#filter-pane').html($('#targets').html());
- $('#filter-pane').fadeIn('fast');
- e.preventDefault();
- });
-
- $('#filter-tag').click(function(e) {
- $('#filter-pane').html($('#tags').html());
- $('#filter-pane').fadeIn('fast');
- e.preventDefault();
- });
-
- $('#create-bug').click(function(e) {
- $('#create-bug').hide();
- $('#create-form').fadeIn('fast');
- e.preventDefault();
- });
-
- $('table tr:odd').addClass('stripe');
- });
- </script>
-
- {% block script %}{% endblock %}
- </head>
-
- <body>
- <div id="main-pane">
- <div id="header" class="inside-main-pane">
- <h1>{{ repository_name }}</h1>
- </div>
- <div id="navigation" class="inside-main-pane">
- <span id="filters">
- <a href="/">Open</a>
- <a href="/?status=closed">Closed</a>
- <a href="" id="filter-assignee">Assigned to...</a>
- <a href="" id="filter-target">Scheduled for...</a>
- <a href="" id="filter-tag">Tags...</a>
- </span>
- <span id="create">
- <a href="" id="create-bug">&#43; Create a new bug</a>
- </span>
- <span id="create-form">
- <form action="/create" method="post">
- <fieldset>
- <input type="text"
- id="create-summary" name="summary" />
- <button id="create-button"
- type="submit">Create</button>
- </fieldset>
- </form>
- </span>
- </div>
- <div id="filter-pane" class="inside-main-pane"></div>
- <div id="content-pane" class="inside-main-pane">
- <h2>{% block page_title %}&nbsp;{% endblock %}</h2>
- {% block content %}{% endblock %}
- </div>
- <div id="footer" class="inside-main-pane">
- <p>
- <a href="">Cherry Flavored Bugs Everywhere</a>
- was created by <a href="http://stevelosh.com">Steve Losh</a> and a very nice <a href="http://fecklessmind.com/2009/01/20/aardvark-css-framework/">aardvark</a>
- using <a href="http://cherrypy.org">CherryPy</a>,
- <a href="http://jinja.pocoo.org/2/">Jinja2</a>,
- and <a href="http://jquery.com">jQuery</a>.
- </p>
- </div>
- </div>
- <div id="assignees">
- <ul class="filter-items">
- <li><a href="/?assignee=None">Unassigned</a></li>
- {% for assignee in assignees %}
- {% if assignee != "None" %}
- <li><a href="/?assignee={{ assignee|e }}">{{ assignee|e }}</a></li>
- {% endif %}
- {% endfor %}
- </ul>
- </div>
- <div id="targets">
- <ul class="filter-items">
- <li><a href="/?target=None">Unscheduled</a></li>
- {% for target in targets %}
- <li><a href="/?target={{ target }}">{{ target }}</a></li>
- {% endfor %}
- </ul>
- </div>
- <div id="tags">
- <ul class="filter-items">
- <li><a href="/?tag=None">All</a></li>
- {% for tag in tags %}
- <li><a href="/?tag={{ tag }}">{{ tag }}</a></li>
- {% endfor %}
- </ul>
- </div>
- </body>
-</html>
diff --git a/interfaces/web/templates/bug.html b/interfaces/web/templates/bug.html
deleted file mode 100644
index b6986a9..0000000
--- a/interfaces/web/templates/bug.html
+++ /dev/null
@@ -1,160 +0,0 @@
-{% extends "base.html" %}
-
-{% block page_title %}
- Bug {{ bug.id.user() }} &ndash; {{ bug.summary|truncate(70) }}
-{% endblock %}
-
-{% block script %}
- <script type="text/javascript">
- $(function() {
- function set_current_detail_default_values() {
- $('#bug-details-edit-status option[value="{{ bug.status }}"]').attr('selected', 'yes');
- $('#bug-details-edit-target option[value="{{ bug.target|e }}"]').attr('selected', 'yes');
- $('#bug-details-edit-assignee option[value^="{{ bug.assigned|striptags }}"]').attr('selected', 'yes');
- $('#bug-details-edit-severity option[value="{{ bug.severity }}"]').attr('selected', 'yes');
- }
-
- $('#add-comment').click(function(e) {
- $('#add-comment-link').hide();
- $('#add-comment-form').fadeIn('fast');
- e.preventDefault();
- });
-
- $('#edit-bug-details').click(function(e) {
- $('#bug-details').hide();
- $('#bug-details-edit-form').fadeIn('fast');
- e.preventDefault();
- });
-
- $('#bug-details-edit-form button[type="reset"]').click(function(e) {
- $('#bug-details-edit-form').hide();
- $('#bug-details').fadeIn('fast', function() { set_current_detail_default_values(); } );
- });
-
- $('#edit-bug-summary').click(function(e) {
- $('#bug-summary').hide();
- $('#bug-summary-edit-form').fadeIn('fast');
- e.preventDefault();
- });
-
- $('#bug-summary-edit-form button[type="reset"]').click(function(e) {
- $('#bug-summary-edit-form').hide();
- $('#bug-summary').fadeIn('fast', function() { set_current_detail_default_values(); } );
- });
-
- set_current_detail_default_values();
- });
- </script>
-{% endblock %}
-
-{% block content %}
- <p class="creation-info">Created on {{ bug.time|datetimeformat }} by {{ bug.creator|e }}</p>
-
- <h3 class="header-with-link">Bug Details</h3>
- <span class="header-link">
- <a href="" id="edit-bug-details">edit</a>
- </span>
-
- <p id="bug-details">
- <span class="detail-field-header">Status:</span>
- <span class="detail-field-contents">{{ bug.status }}</span><br />
-
- <span class="detail-field-header">Severity:</span>
- <span class="detail-field-contents">{{ bug.severity }}</span><br />
-
- <span class="detail-field-header">Scheduled for:</span>
- <span class="detail-field-contents">{{ target }}</span><br />
-
- <span class="detail-field-header">Assigned to:</span>
- <span class="detail-field-contents">{{ assignee|e }}</span><br />
-
- <span class="detail-field-header">Permanent ID:</span>
- <span class="detail-field-contents">{{ bug.uuid }}</span><br />
- </p>
-
- <form id="bug-details-edit-form" class="horizontal" action="/edit" method="post">
- <fieldset>
- <input type="hidden" name="id" value="{{ bug.uuid }}" />
- <div class="field">
- <label for="bug-details-edit-status">Status:</label>
- <select id="bug-details-edit-status" name="status">
- {% for status in statuses %}
- <option value="{{ status }}">{{ status }}</option>
- {% endfor %}
- </select>
- </div>
- <div class="field">
- <label for="bug-details-edit-severity">Severity:</label>
- <select id="bug-details-edit-severity" name="severity">
- {% for severity in severities %}
- <option value="{{ severity }}">{{ severity }}</option>
- {% endfor %}
- </select>
- </div>
- <div class="field">
- <label for="bug-details-edit-target">Scheduled for:</label>
- <select id="bug-details-edit-target" name="target">
- <option value="None">Unscheduled</option>
- {% for target in targets %}
- <option value="{{ target|e }}">{{ target }}</option>
- {% endfor %}
- </select>
- </div>
- <div class="field">
- <label for="bug-details-edit-assignee">Assigned to:</label>
- <select id="bug-details-edit-assignee" name="assignee">
- <option value="None">Unassigned</option>
- {% for assignee in assignees %}
- <option value="{{ assignee|e }}">{{ assignee|e }}</option>
- {% endfor %}
- </select>
- </div>
- <div class="buttons">
- <button type="submit">Save Changes</button>
- <button type="reset">Discard Changes</button>
- </div>
- </fieldset>
- </form>
-
- <h3 class="header-with-link">Summary</h3>
- <span class="header-link">
- <a href="" id="edit-bug-summary">edit</a>
- </span>
- <p id="bug-summary">
- {{ bug.summary }}
- </p>
-
- <form id="bug-summary-edit-form" class="vertical" action="/edit" method="post">
- <fieldset>
- <input type="hidden" name="id" value="{{ bug.uuid }}" />
- <div class="field">
- <input type="text" class="text" id="bug-summary-edit-body" name="summary" value="{{ bug.summary }}" />
- </div>
- <div class="buttons">
- <button type="submit">Save Changes</button>
- <button type="reset">Discard Changes</button>
- </div>
- </fieldset>
- </form>
-
- <h3>Comments</h3>
- {% for comment in bug.comments() %}
- <div class="bug-comment">
- <h4 class="bug-comment-header">{{ comment.author|striptags|e }} said:</h4>
- <p class="bug-comment-body">{{ comment.body|trim|e }}</p>
- <p class="bug-comment-footer">on {{ comment.time|datetimeformat }}</p>
- </div>
- {% endfor %}
- <form id="add-comment-form" class="vertical" action="/comment" method="post">
- <fieldset>
- <input type="hidden" name="id" value="{{ bug.uuid }}" />
- <div class="field">
- <textarea cols="60" rows="6" id="add-comment-body" name="body"></textarea>
- </div>
- <div class="buttons">
- <button type="submit">Submit</button>
- </div>
- </fieldset>
- </form>
- <p id="add-comment-link"><a href="" id="add-comment">&#43; Add a comment</a></p>
-{% endblock %}
diff --git a/interfaces/web/templates/empty-list.html b/interfaces/web/templates/empty-list.html
deleted file mode 100644
index 4c01cb2..0000000
--- a/interfaces/web/templates/empty-list.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends "base.html" %}
-
-{% block page_title %}
- {{ label }}
-{% endblock %}
-
-{% block content %}
- <p>
- No matching bugs.
- </p>
-{% endblock %}
diff --git a/interfaces/web/templates/list.html b/interfaces/web/templates/list.html
deleted file mode 100644
index 65e6fe2..0000000
--- a/interfaces/web/templates/list.html
+++ /dev/null
@@ -1,25 +0,0 @@
-{% extends "base.html" %}
-
-{% block page_title %}
- {{ label }}
-{% endblock %}
-
-{% block content %}
- <table id="bug-list">
- <tr>
- <th>ID</th>
- <th>Summary</th>
- <th>Status</th>
- <th>Assigned To</th>
- </tr>
- {% for bug in bugs %}
- <tr>
- <td>{{ bug.id.user() }}</td>
- <td><a href="/bug?{{ urlencode({'id':bug.id.long_user()}) }}">
- {{ bug.summary|e|truncate(70) }}</a></td>
- <td>{{ bug.status }}</td>
- <td>{{ bug.assigned|striptags }}</td>
- </tr>
- {% endfor %}
- </table>
-{% endblock %}
diff --git a/interfaces/web/web.py b/interfaces/web/web.py
deleted file mode 100644
index 2907932..0000000
--- a/interfaces/web/web.py
+++ /dev/null
@@ -1,211 +0,0 @@
-from datetime import datetime
-from urllib import urlencode
-
-from jinja2 import Environment, FileSystemLoader
-import cherrypy
-
-from libbe import storage
-from libbe import bugdir
-from libbe.command.depend import get_blocked_by, get_blocks
-from libbe.command.target import add_target, remove_target
-from libbe.command.target import bug_from_target_summary, bug_target
-from libbe.command.util import bugdir_bug_comment_from_user_id
-from libbe.storage.util import settings_object
-import libbe.command.tag
-
-
-EMPTY = settings_object.EMPTY
-
-def datetimeformat(value, format='%B %d, %Y at %I:%M %p'):
- """Takes a timestamp and revormats it into a human-readable string."""
- return datetime.fromtimestamp(value).strftime(format)
-
-
-class WebInterface:
- """The web interface to CFBE."""
-
- def __init__(self, bug_root, template_root):
- """Initialize the bug repository for this web interface."""
- self.bug_root = bug_root
- store = storage.get_storage(self.bug_root)
- store.connect()
- version = store.storage_version()
- print version
- self.bd = bugdir.BugDir(store, from_storage=True)
- self.repository_name = self.bug_root.split('/')[-1]
- self.env = Environment(loader=FileSystemLoader(template_root))
- self.env.filters['datetimeformat'] = datetimeformat
-
- def get_common_information(self):
- """Returns a dict of common information that most pages will need."""
- possible_assignees = list(set(
- [unicode(bug.assigned) for bug in self.bd if bug.assigned != EMPTY]))
- possible_assignees.sort(key=unicode.lower)
-
- possible_targets = list(set(
- [unicode(bug.summary.rstrip("\n")) for bug in self.bd \
- if bug.severity == u"target"]))
-
- possible_targets.sort(key=unicode.lower)
-
- possible_statuses = [u'open', u'assigned', u'test', u'unconfirmed',
- u'closed', u'disabled', u'fixed', u'wontfix']
-
- possible_severities = [u'minor', u'serious', u'critical', u'fatal',
- u'wishlist']
-
- return {'possible_assignees': possible_assignees,
- 'possible_targets': possible_targets,
- 'possible_statuses': possible_statuses,
- 'possible_severities': possible_severities,
- 'tags': libbe.command.tag.get_all_tags(self.bd),
- 'repository_name': self.repository_name,}
-
- def filter_bugs(self, status, assignee, target, tag):
- """Filter the list of bugs to return only those desired."""
- bugs = [bug for bug in self.bd if bug.status in status]
-
- if assignee != '':
- assignee = None if assignee == 'None' else assignee
- bugs = [bug for bug in bugs if bug.assigned == assignee]
-
- if tag != '' and tag != 'None':
- bugs = [bug for bug in bugs
- if tag in libbe.command.tag.get_tags(bug)]
-
- if target != '':
- target = None if target == 'None' else target
- if target == None:
- # Return all bugs that don't block any targets.
- return [bug for bug in bugs if not bug_target(self.bd, bug)]
- else:
- # Return all bugs that block the supplied target.
- targetbug = bug_from_target_summary(self.bd, target)
- if targetbug == None:
- return []
- bugs = [bug for bug in get_blocked_by(self.bd, targetbug) if
- bug.active]
-
- return bugs
-
-
- @cherrypy.expose
- def index(self, status='open', assignee='', target='', tag=''):
- """The main bug page.
- Bugs can be filtered by assignee or target.
- The bug database will be reloaded on each visit."""
-
- self.bd.load_all_bugs()
-
- if status == 'open':
- status = ['open', 'assigned', 'test', 'unconfirmed', 'wishlist']
- label = 'All Open Bugs'
- elif status == 'closed':
- status = ['closed', 'disabled', 'fixed', 'wontfix']
- label = 'All Closed Bugs'
-
- if assignee != '':
- label += ' Currently Unassigned' if assignee == 'None' \
- else ' Assigned to %s' % (assignee,)
- if target != '':
- label += ' Currently Unscheduled' if target == 'None' \
- else ' Scheduled for %s' % (target,)
- if tag != '' and tag != 'None':
- label += ' Tagged %s' % (tag,)
-
- bugs = self.filter_bugs(status, assignee, target, tag)
- if len(bugs) == 0:
- template = self.env.get_template('empty-list.html')
- else:
- template = self.env.get_template('list.html')
-
- common_info = self.get_common_information()
- return template.render(bugs=bugs, bd=self.bd, label=label,
- assignees=common_info['possible_assignees'],
- targets=common_info['possible_targets'],
- statuses=common_info['possible_statuses'],
- severities=common_info['possible_severities'],
- repository_name=common_info['repository_name'],
- tags=common_info['tags'],
- urlencode=urlencode)
-
-
- @cherrypy.expose
- def bug(self, id=''):
- """The page for viewing a single bug."""
-
- self.bd.load_all_bugs()
-
- bugdir, bug, comment = bugdir_bug_comment_from_user_id(
- {self.bd.uuid: self.bd}, id)
-
- template = self.env.get_template('bug.html')
- common_info = self.get_common_information()
-
- # Determine which targets a bug has.
- # First, is this bug blocking any other bugs?
- targets = ''
- blocks = get_blocks(self.bd, bug)
- for targetbug in blocks:
- # Are any of those blocked bugs targets?
- blocker = self.bd.bug_from_uuid(targetbug.uuid)
- if blocker.severity == "target":
- targets += "%s " % blocker.summary
-
- return template.render(bug=bug, bd=self.bd,
- assignee='' if bug.assigned == EMPTY else bug.assigned,
- target=targets,
- assignees=common_info['possible_assignees'],
- targets=common_info['possible_targets'],
- statuses=common_info['possible_statuses'],
- severities=common_info['possible_severities'],
- repository_name=common_info['repository_name'])
-
-
- @cherrypy.expose
- def create(self, summary):
- """The view that handles the creation of a new bug."""
- if summary.strip() != '':
- self.bd.new_bug(summary=summary).save()
- raise cherrypy.HTTPRedirect('/', status=302)
-
-
- @cherrypy.expose
- def comment(self, id, body):
- """The view that handles adding a comment."""
- bug = self.bd.bug_from_uuid(id)
-
- if body.strip() != '':
- bug.comment_root.new_reply(body=body)
- bug.save()
-
- raise cherrypy.HTTPRedirect(
- '/bug?%s' % urlencode({'id':bug.id.long_user()}),
- status=302)
-
- @cherrypy.expose
- def edit(self, id, status=None, target=None, assignee=None, severity=None, summary=None):
- """The view that handles editing bug details."""
- bug = self.bd.bug_from_uuid(id)
-
- if summary != None:
- bug.summary = summary
- else:
- bug.status = status if status != 'None' else None
- bug.assigned = assignee if assignee != 'None' else None
- bug.severity = severity if severity != 'None' else None
-
- if target:
- current_target = bug_target(self.bd, bug)
- if current_target:
- remove_target(self.bd, bug)
- if target != "None":
- add_target(self.bd, bug, target)
- else:
- add_target(self.bd, bug, target)
-
- bug.save()
-
- raise cherrypy.HTTPRedirect(
- '/bug?%s' % urlencode({'id':bug.id.long_user()}),
- status=302)