diff --git a/agent/ui/AgentJobView.html b/agent/ui/AgentJobView.html new file mode 100644 index 0000000..d514aa2 --- /dev/null +++ b/agent/ui/AgentJobView.html @@ -0,0 +1,140 @@ + + + + + + + + loops + + + + + + + + + + + + + + + + + + + + + +
+
+
+

loops agent.GUI

+
+
+ + + +
+
+
+ +
+
+

+
+
+

Agent Job overview

+ +
    +
  • Here you will get an overview of the current jobs registered in the agent system
  • +
+
+
+

Overview

+
    +
  • Current jobs
  • +
+
+
+ +

+
+
+
+
+
+ +
+
+ + + +
+ + + + \ No newline at end of file diff --git a/agent/ui/AgentJobViewDetail.html b/agent/ui/AgentJobViewDetail.html new file mode 100644 index 0000000..f04aaa5 --- /dev/null +++ b/agent/ui/AgentJobViewDetail.html @@ -0,0 +1,137 @@ + + + + + + + + loops + + + + + + + + + + + + + + + + + + + + + +
+
+
+

loops agent.GUI

+
+
+ + + +
+
+
+ +
+
+

+
+
+

Agent Job overview

+ +
    +
  • Here you will get an overview of the current jobs registered in the agent system
  • +
+
+
+

Overview

+
    +
  • Job details
  • +
+
+ +

+

+

+
+
+
+
+
+ +
+
+ + + +
+ + + + \ No newline at end of file diff --git a/agent/ui/AgentOutlookMailView.html b/agent/ui/AgentOutlookMailView.html new file mode 100644 index 0000000..18b4925 --- /dev/null +++ b/agent/ui/AgentOutlookMailView.html @@ -0,0 +1,137 @@ + + + + + + + + loops + + + + + + + + + + + + + + + + + + + + + +
+
+
+

loops agent.GUI

+
+
+ + + +
+
+
+ +
+
+

+
+
+

Agent: collected Outlook Mails

+ +
    +
  • All currently available Outlook Mails collected by the loops agent
  • +
+
+
+

Overview

+
    +
  • Mail Collection
  • +
+
+ +

+

+

+
+
+
+
+
+ +
+
+ + + +
+ + + + \ No newline at end of file diff --git a/agent/ui/AgentStart.html b/agent/ui/AgentStart.html new file mode 100644 index 0000000..ec9d95d --- /dev/null +++ b/agent/ui/AgentStart.html @@ -0,0 +1,133 @@ + + + + + + + + loops + + + + + + + + + + + + + + + + + + + + + +
+
+
+

loops agent.GUI

+
+
+ + + +
+
+
+ +
+
+

+
+
+

Startpage

+ +
    +
  • This page contains some information about the loops agent UI. On the left side you can find the + navigation panel where you can choose between a general job overview to be displayed, add a job or change the + logging options. Also below this navigation menue you will find a button which switches the User mode between + Professional and Simple Mode. This button is to be found on this start page only.
  • +
+
+
+

Version

+
    +
  • Agent:
  • +
+
+
+
+ +
+
+ + + +
+ + + + \ No newline at end of file diff --git a/agent/ui/StartUpAgentUI.tac.py b/agent/ui/StartUpAgentUI.tac.py new file mode 100644 index 0000000..82117ff --- /dev/null +++ b/agent/ui/StartUpAgentUI.tac.py @@ -0,0 +1,26 @@ +#------------------------------------------------- +# StartUpAgentUI.tac.py +# start the twisted webserver and initialize the +# nevow framework/application +# author: Juergen Menzinger +# version: 01.alpha +# start with twistd.py -noy StartUpAgentUI.tac.py +# requires AgentStart.html +# AgentJobView.html +# AgentJobViewDetail.html +# AgentOutlookMailView.html +#------------------------------------------------- + + +from twisted.application import internet +from twisted.application import service +from nevow import appserver +import web +import sys, os, socket + + +application = service.Application('loops agent') +site = appserver.NevowSite(web.AgentHome()) +webServer = internet.TCPServer(8080, site) +webServer.setServiceParent(application) + diff --git a/agent/ui/css/base.css b/agent/ui/css/base.css new file mode 100644 index 0000000..ff50e70 --- /dev/null +++ b/agent/ui/css/base.css @@ -0,0 +1,99 @@ +/* + $Id: base.css 1779 2007-06-07 19:37:44Z helmutm $ + + based on http://www.tjkdesign.com/articles/liquid/4.asp + +*/ + +body { + min-width:640px; + margin: 0; + padding: 0; + font: 9pt Verdana, Tahoma, Arial, Helvetica, sans-serif; + background-color: white; + color: #000040; +} + +#global,#menu,#sub-section,#footer { + overflow: hidden; + display: inline-block; +} + +#content { + display: inline-block; +} + +#global,#footer {width:100%} +#menu,#content,#sub-section {float:left} +#menu {width:20%} +#content {width:62%} +#sub-section {width:17%} +#footer {clear:left} + +/* more general stuff */ + +.top image { + margin-top: -1px; +} + +div.box { + margin: 12px 12px 8px 10px; + border: 1px solid #ccc; + border-bottom: none; +} + +div.box h4 { + font: 110% Verdana, Tahoma, Arial, Helvetica, sans-serif; + color: #000040; + border: none; + border-bottom: 1px solid #ccc; + padding: 4px; + padding-top: 1px; + padding-bottom: 3px; + background-color: #ddd; + height: auto; +} + +table.listing { + margin: 1px; + margin-top: 6px; + +} + +table.listing th { + font-family: Verdana, Tahoma, Arial, Helvetica, sans-serif; + color: #000040; +} + +.footer { + text-align: center; + border-top: 1px solid #ccc; + border-bottom: none; + margin-top: 12px; + padding-top: 6px; +} + +.itemViews { + border-bottom-width: 2px; +} + +.button { + margin: 1em 0 1em 0; +} + +.button a { + padding: 2px 4px 2px 4px; + background-color: #e8e8e8; + text-decoration: None; + color: Black; + border-width: 2px; + border-style: solid; + border-color: #f4f4f4 #989898 #989898 #f4f4f4; +} + +pre { + background-color: #f4f4f4; +} + +#footer { border-bottom: none; } + diff --git a/agent/ui/css/custom.css b/agent/ui/css/custom.css new file mode 100644 index 0000000..15b15c1 --- /dev/null +++ b/agent/ui/css/custom.css @@ -0,0 +1,24 @@ +/* + $Id: custom.css 1302 2006-08-17 15:21:10Z helmutm $ + + cyberconcepts specialties + +*/ + +body { + color: #242424; +} + +a { + text-decoration: none; + color: #344080; + background-color: transparent; +} + +.top { + border-bottom: 1px solid #d0d0d0; + margin-bottom: 2px; + /*background-image: url('bg_cyberview.gif') + height: 75px;*/ +} + diff --git a/agent/ui/css/loops.css b/agent/ui/css/loops.css new file mode 100644 index 0000000..5535bbd --- /dev/null +++ b/agent/ui/css/loops.css @@ -0,0 +1,138 @@ +/* + $Id: loops.css 1729 2007-05-13 08:56:47Z helmutm $ + + settings specific for view / node objects + +*/ + +a[href]:hover { + text-decoration: none; + color: #803000; +} + +pre { + overflow: scroll; + max-height: 35em; +} + +.box div.body div.even { + background-color: #f4f4f4; +} + +.box { + margin: 12px; +} + +#body { + margin-left: 5px; +} + +/*.content-1 h1 { */ +h1 { + font-size: 160%; + font-weight: bold; +} + +.content-2 h1, h2 { + font-size: 140%; +} + +.content-3 h1, .content-2 h2, h3 { + font-size: 130%; + font-weight: bold; +} + +.content-4 h1, .content-3 h2, .content-2 h3, .content-1 h4 { + font-size: 120%; +} + +.content-5 h1, .content-4 h2, .content-3 h3, content-2 h4 { + font-size: 100%; + border: none; +} + +.subcolumn { + display: inline; + float: left; +} + +.box { + margin: 5px; + padding: 6px; + padding-top: 0; +} + +.box h1, .box h2, .box h3 { + border-bottom: None; +} + +div.menu-1, div.menu-2 { + border-top: 1px solid #eeeeee; + font-weight: bold; +} + +.box div.body div.menu-3 { + border-top: none; + padding-left: 1.5em; +} + +.box div.body div.menu-4 { + padding-left: 3em; + font-size: 90% +} + +.flow-left { + float: left; +} + +.flow-right { + float: right; +} + +div.image { + margin-top: 10px; + margin-right: 5px; +} + + +/* search stuff */ + +.searchForm input.button, input.submit { + padding: 2px; +} + +.searchForm input.submit { + font-weight: bold; +} + +/* dojo stuff */ + +/*.dojoComboBox { + width: 200px; +}*/ + +.dojoDialog { + background: #eee; + border: 1px solid #999; + -moz-border-radius: 5px; + padding: 4px; +} + +.dojoDialog th { + font-size: 120%; + padding: 0 5px 8px 5px; +} + +.dojoDialog .headline { + font-weight: bold; +} + +.dojoDialog input.text { + width: 100%; + margin-right: 10px; +} + +.dojoDialog input.submit { + font-weight: bold; +} + diff --git a/agent/ui/css/print.css b/agent/ui/css/print.css new file mode 100644 index 0000000..6232184 --- /dev/null +++ b/agent/ui/css/print.css @@ -0,0 +1,13 @@ +/* + $Id: print.css 1340 2006-09-12 08:39:40Z helmutm $ + +*/ + +.top, #header, #menu, #sub-section, #footer { + display: none; +} + +#content { + width: 100%; + color: Black; +} diff --git a/agent/ui/css/zope3_tablelayout.css b/agent/ui/css/zope3_tablelayout.css new file mode 100644 index 0000000..70aceb6 --- /dev/null +++ b/agent/ui/css/zope3_tablelayout.css @@ -0,0 +1,662 @@ +/* +** Zope3 style sheet for CSS2-capable browsers. +** For future skin see zope.app.boston. +*/ + +/* +* { border: 1px dotted red } +*/ + + +/* Basic Elements */ + +body { + font: 85% Helvetica, Arial, sans-serif; + background: White; + color: Black; + margin: 0; + padding: 0; +/* These work in IE only, changes the look of the scrollbar + textareas */ + scrollbar-base-color: White; + scrollbar-highlight-color: White; + scrollbar-track-color: #F8F8F8; + scrollbar-darkshadow-color: #F8F8F8; + scrollbar-3dlight-color: #369; + scrollbar-shadow-color: #369; + scrollbar-arrow-color: Black; +} + +table { + border-collapse: collapse; + font-size: 100%; +} + +a { + text-decoration: none; + color: #369; + background-color: transparent; +} + +a[href]:active { + text-decoration: underline; +} + +img { + border: none; + vertical-align: middle; +} + +p { + margin: 0.5em 0em 1em 0em; + line-height: 1.5em; +} + +p a:visited { + color: Purple; + background-color: transparent; +} + +p a:active { + color: Red; + background-color: transparent; +} + +p img { + border: 0; + margin: 0; +} + + +hr { + clear: both; + height: 1px; + color: #369; + background-color: transparent; +} + + +h1, h2, h3, h4, h5, h6 { + color: Black; + clear: left; + font: 100% bold Verdana, Helvetica, Arial, sans-serif; + margin: 0; + padding-top: 0.5em; + border-bottom: 1px solid #369; +} + +h1 { + font-size: 160%; +} + +h2 { + font-size: 150%; +} + +h3 { + font-size: 140%; +} + +h4 { + font-size: 120%; +} + +h5 { + font-size: 100%; +} + +h6 { + font-size: 80%; +} + +ul { + line-height: 1.5em; + /* list-style-image: url("bullet.gif"); */ + margin-left: 2em; + padding:0; +} + +ol { + line-height: 1.5em; + margin-left: 2em; + padding:0; +} + +dl { +} + +dt { + font-weight: bold; +} + +dd { + line-height: 1.5em; + margin-bottom: 1em; +} + + +fieldset { + border: 1px solid #A0A0A0; + /* + margin: 2em 0em 1em 0em; + padding: 1em 0em; + */ + margin: 0em 0em 2em 0em; + padding: 0 1em 1em 1em; +} + +legend { + background: White; + padding: 0.5em; +} + + +form { + border: none; + margin: 0; +} + +textarea { + color: Black; + width: 88%; + padding: 0.1em; +} + +input { + font: normal 100% Verdana, Helvetica, Arial, sans-serif; + color: Black; + vertical-align: middle; + margin-bottom: 1px; /* IE bug fix */ + padding: 0.1em; +} + +select { + font: normal 100% Verdana, Helvetica, Arial, sans-serif; + vertical-align: top; +} + +abbr, acronym, .explain { + border-bottom: 1px dotted Black; + color: Black; + background-color: transparent; + cursor: help; +} + +q { + font-family: Times, "Times New Roman", serif; + font-style: italic; + font-size: 120%; +} + +blockquote { + font-family: Times, "Times New Roman", serif; + font-style: italic; + font-size: 120%; +} + +code { + font-size: 120%; + color: Black; + background-color: #CCCCCC; +} + +pre { + font-size: 120%; + padding: 1em; + border: 1px solid #A0A0A0; + color: Black; + background-color: #CCCCCC; +} + +.netscape4 { + display: none; +} + +/* layout table +*/ + +#layout { + width: 100%; + table-layout: auto; + font-size: 100%; + border-collapse: collapse; + padding: 0px; + margin: 0px; +} + +#layout td { + vertical-align: top; +} + +#layout td.global { + width: 100%; +} + +#layout td.navigators { + width: 200px; +} + +#layout td.workspace { +} + + +/* Styles for xmltree +*/ + +#navtreecontents { + padding-right: 35px; +} + +#navtreecontents a { + cursor: pointer; + height: 20px; +} + +#navtreecontents loading { + display: block; + padding-left: 31px; + height: 18px; +} + +#navtreecontents expand { + background-repeat: no-repeat; + padding-left: 14px; + display: inline; + cursor: pointer; +} + +#navtreecontents icon { + background-repeat: no-repeat; + padding-left: 20px; + display: inline; + cursor: auto; +} + +#navtreecontents collection { + display: block; + margin-left: 10px; +/* border: red solid 1pt; */ + height: auto; +} + + +/* Structural elements +*/ + +#top { + border-bottom: 0.1em solid black; +} + +#top #userDetails { + float:right; + margin-top: 1.2em; + padding-right: 0.5em; +} + +div#action { + height: 24px; + width: 100%; + background-color: #336699; +} + +div#action ul { + line-height: 24px; + color: #FFF; + white-space: nowrap; + float: right; + margin: 0px; + padding: 0px 5px 0px 0px; +} + +div#action li { + list-style-type: none; + display: inline; +} + +div#action li a { + color: #FFF; + text-decoration: none; + border-left: 1px dashed white; + padding: 0px 5px; +} + +div#action li a:link { + color: #FFF; +} + +div#action li a:hover { + color: black; + background-color: white; +} + +#breadcrumbs { + margin: 0; + padding: 5px 5px 5px 5px; +} + +#navigation { + width: 200px; + vertical-align: top; + padding: 0px; + margin: 0px; +} + +#navigators { + padding: 10px 20px 0px 5px; +} + +/* slot boxes +*/ + +div.box { + background: #CCCCCC; + border-right: 1px solid #CCCCCC; + border-left: 1px solid #CCCCCC; + margin-bottom: 10px; + padding: 0px; +} + +div.box h4 { + background: #CCCCCC; + border: 1px solid #CCCCCC; + border-style: solid solid none solid; + color: #808080; + padding: 0px 5px; + display: block; + height: 22px; +} + +.box div.body { + background: white; + border-bottom: 1px solid #CCCCCC; +} + +.box div.body div { + color: #777777; + padding: 2px 0px 5px 5px; + margin: 0px; +} + +.box div.treebody { + background: white; + border-bottom: 1px solid #CCCCCC; +} + +.box div.treebody table { + margin: 2px; +} + +.box div.body div.tip { + color: #B30000; + padding: 2px 0px 5px 5px; +} + +.box div.body div.even { + background: #EBEBE2; + padding: 4px; +} + +.box div.body div.odd { + padding: 4px; +} + +.box .content { + padding: 0.5em; +} + +.box h1, +.box h2, +.box h3, +.box h4 { + margin: 0; +} + + +#content { +} + +#context_information { + padding-top: 1em; + width: 15%; + float: left; + padding-left: 0.5em; +} + +#workspace { + width: 100%; +} + +#helpers { +} + +#inspectors { +} + +#footer { + border-bottom: 1px solid black; + float: left; + clear: both; +} + +input.textType { + width: 88%; /* Same as textarea */ +} + +input.editcheck { + float:left; + position:relative; + top:1em; +} + +div.row { + padding-top: 1em; +} + +/* +div.label { + #clear: both; + padding-top: 10px; +} +*/ + +/* div.row div.field doesn't appear to be selecting. div.row div + is a workaround */ +/* This seems to work in Firefox 1.0 and IE6. */ + +div.row div.field { + clear: left; + padding-top: 1px; +} + +div.row div.label { + background: #369; + color: #fff; + padding: 0.1em 0.5em 0.1em 0.5em; /* Same as .itemViews */ + border: 1px solid #369; /* Same as .itemViews */ + margin: 0; + float: left; + clear: both; +} + +div.row span.error { + background: red; + color: white; + padding: 0.1em 0.5em 0.1em 0.5em; /* Same as .itemViews */ + border: 1px solid red; /* Same as .itemViews */ + margin: 0; + float: left; + clear: both; +} +/* +div.row div.error:before { + content: "\2190 "; +} +*/ + +#metadata .label { + font-size: 80%; +} + +.itemViews { + background: transparent; + border-collapse: collapse; + border-bottom: 1px solid #369; + padding-top: 1px; + padding-bottom: 1px; + padding-left: 1em; + margin-top: 0.8em; + white-space: nowrap; +} + +.itemViews a { + background: transparent; + border: 1px solid #369; + color: Black; + font-weight: normal; + margin-right: 0.5em; + padding: 0.1em 0.5em 0.1em 0.5em; +} + +.itemViews a.selected { + background: #369; + border-bottom: #369 1px solid; + color: White; + font-weight: normal; +} + + +.itemViews a:hover { + background-color: #369; + color: White; +} + +#viewspace { + border-collapse: collapse; + margin: 0; +} + +table.listingdescription, table.listing { + /* The default table for document listings. Contains name, document types, modification times etc in a file-browser-like fashion */ + border-collapse: collapse; + border-left: 1px solid #CCCCCC; + border-bottom: 1px solid #CCCCCC; + margin: 1em 0em 1em 0em; +/* clear: both; */ +} + +table.listingdescription { + width: 100%; +} + +table.listingdescription th, table.listing th { + background: #CCCCCC; + border-top: 1px solid #CCCCCC; + border-bottom: 1px solid #CCCCCC; + border-right: 1px solid #CCCCCC; + color: #808080; + font-weight: normal; + padding: 0em 1em 0em 1em; + white-space: nowrap; +} + +table.listingdescription td.top, table.listing td.top { + border-left: 1px solid White; + border-top: 1px solid White ! important; + border-right: 1px solid White ! important; + text-align: right ! important; + padding: 0em 0em 1em 0em; + /* insane IE row bug workaround */ + position: relative; + left: -1px; + top: -1px; +} + +table.listingdescription tr.odd, table.listing tr.odd { + /*every second line should be shaded */ + background: White; +} + +table.listingdescription tr.even, table.listing tr.even { + background: #F8F8F8; +} + +table.listing td { + border-right: 1px solid #CCCCCC; + padding: 0em 0.3em; + text-align: left; + white-space: nowrap; +} + + +table.listingdescription img, table.listing img { + vertical-align: middle; +} + +table.listingdescription td { + border-right: 1px solid #CCCCCC; + padding: 5px; + text-align: left; +} + + +/*colorize the matrix table used in grant.html*/ +table.matrix td.default { + background: green; +} + + +table.matrix td.changed { + background: red; +} + + +div.spacer { + clear: both; +} + + +.registrationSummary { + margin-left: 2em; + margin-bottom: 1em; +} +.registrationSummary .usageSummary { + font-weight: bold; +} +.registrationSummary .modificationLink { + display: block; +} + + +div.message { + background: #FFCE7B; + border: 1px solid #FFA500; + color: Black; + font: bold 80% Verdana, Helvetica, Arial, sans-serif; + margin: 2em 0em 1em 0em; + padding: 0.5em 1em; + vertical-align: middle; +} + +div.message a { + color: Black; +} + +/* Style for page error divs. Use this for displaying errors for a + page as a whole. + */ +div.page_error { + background: #FFCE7B; + font: bold 80% Verdana, Helvetica, Arial, sans-serif; + padding: 0.5em 1em; + vertical-align: middle; +} + +div.bug { + background: #FFCE7B; + border: 1px solid #FFA500; + color: Black; + font: bold 80% Verdana, Helvetica, Arial, sans-serif; + margin: 2em 1em 1em 0em; + padding: 0.5em 1em; + vertical-align: middle; +} + diff --git a/agent/ui/images/favicon.png b/agent/ui/images/favicon.png new file mode 100644 index 0000000..1fc7485 Binary files /dev/null and b/agent/ui/images/favicon.png differ diff --git a/agent/ui/images/loops_logo2.png b/agent/ui/images/loops_logo2.png new file mode 100644 index 0000000..2c0af50 Binary files /dev/null and b/agent/ui/images/loops_logo2.png differ diff --git a/agent/ui/joblist.txt b/agent/ui/joblist.txt new file mode 100644 index 0000000..ae42774 --- /dev/null +++ b/agent/ui/joblist.txt @@ -0,0 +1,4 @@ +FileSysCont_1234;C:\Documents;*.doc;daily;transfer(http:loops.sampleserver.de) +MailCrawl_2121;Outlook(Account_Root);daily;transfer(http:loops.sampleserver.de) +MailCrawl_4040;Outlook(Subj:Update);20s;transfer(http:loops.sampleserver.de) +FileSysCont_8797;C:\Tmp;size<100kByte;transfer(http:loops.sampleserver.de) \ No newline at end of file diff --git a/agent/ui/loops.js b/agent/ui/loops.js new file mode 100644 index 0000000..bb7751e --- /dev/null +++ b/agent/ui/loops.js @@ -0,0 +1,126 @@ +/* $Id: loops.js 1667 2007-03-26 10:43:15Z helmutm $ */ + +function openEditWindow(url) { + zmi = window.open(url, 'zmi'); + zmi.focus(); + return false; +} + +function focusOpener() { + if (typeof(opener) != 'undefined' && opener != null) { + opener.location.reload(); + opener.focus(); + } +} + +function replaceFieldsNode(targetId, typeId, url) { + token = dojo.byId(typeId).value; + uri = url + '?form.type=' + token; + dojo.io.updateNode(targetId, uri); +} + +function submitReplacing(targetId, formId, actionUrl) { + dojo.io.updateNode(targetId, { + url: actionUrl, + formNode: dojo.byId(formId), + method: 'post' + }); + return false; +} + +function inlineEdit(id, saveUrl) { + var iconNode = dojo.byId('inlineedit_icon'); + iconNode.style.visibility = 'hidden'; + editor = dojo.widget.createWidget('Editor', + {items: ['save', '|', 'formatblock', '|', + 'insertunorderedlist', 'insertorderedlist', '|', + 'bold', 'italic', '|', 'createLink', 'insertimage'], + saveUrl: saveUrl, + //closeOnSave: true, + htmlEditing: true + //onClose: function() { + /* onSave: function() { + this.disableToolbar(true); + iconNode.style.visibility = 'visible'; + //window.location.reload(); + }*/ + }, dojo.byId(id)); + editor._save = function (e) { + if (!this._richText.isClosed) { + if (this.saveUrl.length) { + var content = {}; + this._richText.contentFilters = []; + content[this.saveArgName] = this.getHtml(); + content['version'] = 'this'; + dojo.io.bind({method:this.saveMethod, + url:this.saveUrl, + content:content, + handle:function(type, data, ti, kwargs) { + location.reload(false); + } + }); //alert('save'); + } else { + dojo.debug("please set a saveUrl for the editor"); + } + if (this.closeOnSave) { + this._richText.close(e.getName().toLowerCase() == "save"); + } + } + } + return false; +} + +function setConceptTypeForComboBox(typeId, cbId) { + var t = dojo.byId(typeId).value; + var cb = dojo.widget.manager.getWidgetById(cbId) + var dp = cb.dataProvider; + var baseUrl = dp.searchUrl.split('&')[0]; + var newUrl = baseUrl + '&searchType=' + t; + dp.searchUrl = newUrl; + cb.setValue(''); +} + +var dialogs = {} + +function objectDialog(dlgName, url) { + dojo.require('dojo.widget.Dialog'); + dojo.require('dojo.widget.ComboBox'); + dlg = dialogs[dlgName]; + if (!dlg) { + //dlg = dojo.widget.fromScript('Dialog', + dlg = dojo.widget.createWidget('Dialog', + {bgColor: 'white', bgOpacity: 0.5, toggle: 'fade', toggleDuration: 250, + executeScripts: true, + href: url + }, dojo.byId('dialog.' + dlgName)); + dialogs[dlgName] = dlg; + } + dlg.show(); +} + +function addConceptAssignment() { + dojo.require('dojo.html') + node = dojo.byId('form.assignments'); + els = document.forms[0].elements; + for (var i=0; i' + title + ''; + var tr = document.createElement('tr'); + tr.appendChild(td); + node.appendChild(tr); +} + diff --git a/agent/ui/twistd.py b/agent/ui/twistd.py new file mode 100644 index 0000000..3be2802 --- /dev/null +++ b/agent/ui/twistd.py @@ -0,0 +1,21 @@ +#!C:\Python25\python.exe + +# Twisted, the Framework of Your Internet +# Copyright (c) 2001-2004 Twisted Matrix Laboratories. +# See LICENSE for details. + + + +### Twisted Preamble +# This makes sure that users don't have to set up their environment +# specially in order to run these programs from bin/. +import sys, os, string +if string.find(os.path.abspath(sys.argv[0]), os.sep+'Twisted') != -1: + sys.path.insert(0, os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]), os.pardir, os.pardir))) +if hasattr(os, "getuid") and os.getuid() != 0: + sys.path.insert(0, os.path.abspath(os.getcwd())) +### end of preamble + + +from twisted.scripts.twistd import run +run() diff --git a/agent/ui/usermode.ini b/agent/ui/usermode.ini new file mode 100644 index 0000000..c6aee86 --- /dev/null +++ b/agent/ui/usermode.ini @@ -0,0 +1 @@ +UserMode:Simple \ No newline at end of file diff --git a/agent/ui/web.py b/agent/ui/web.py index 9bdeeb0..d70b9df 100644 --- a/agent/ui/web.py +++ b/agent/ui/web.py @@ -1,32 +1,283 @@ -# -# Copyright (c) 2007 Helmut Merz helmutm@cy55.de -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# +#------------------------------------------------------ +# AgentHome.py +# source file for agent UI +# author: Juergen Menzinger +# version: 0.1 +#------------------------------------------------------ + +# one possibility is to always stay in the same class by calling its object instance as +# a return value when returning from a methodCall'. But this would require to change the current +# __init__ procedure so that the changes concerning the ini file are always directly written +# to the file or there is a routine which starts one time to initialize (maybe for example reading the +# whole ini File into the self.IniDict if it is not already filled and for each setting just chnaging the +# self.IniDict + +from nevow import loaders, rend, static, url, inevow +from nevow.inevow import IRequest +from twisted.internet import defer """ -Web interfaces for the loops agent. - -$Id$ +Import could look like this: +from loops.agent.crawl.MailCrawler import MailCrawler """ -from nevow import loaders, rend +# ---- global definitions --------------------------------- +# THIS SECTION IS USED FOR PROJECT INTERNAL DEBUG ONLY +INIFILE = "usermode.ini" +JOBFILE = "joblist.txt" +#---------------------------------------------------------- + + +#///////////////////////////////////////////////////////////////////////////////////////////// +#---------------------------- AgentHome -------------------------------------------------- +# root page of the Agent UI +# every method called on the agent ui has it s child +# method inside here class AgentHome(rend.Page): - addSlash = True - docFactory = loaders.xmlfile('ui/agent.html') + child_css = static.File('css') + child_images = static.File('images') + docFactory = loaders.xmlfile('AgentStart.html') + + def __init__(self,IniDict={}): + + #TODO: implement automatic reading of default ini file, or one passed via constructor + #-------- ini settings ------------------------ + # THIS SECTION IS USED FOR PROJECT INTERNAL DEBUG ONLY + self.iniFile = INIFILE + self.IniDict = IniDict + #----------------------------------------------- + + #-------- get ini settings from file -------- + # stores IniFile settings in self.IniDict + + if self.IniDict == {}: + + fPointer = open(self.iniFile,"r") + IniSettings = fPointer.readlines() + + for iniLine in IniSettings: + elem = iniLine.split(":") + self.IniDict[elem[0]] = elem[1] + + fPointer.close() + + print "[AgentHome] self.UserMode: ", self.IniDict["UserMode"] + + + """ + def locateChild(self, ctx, segments): + return self, () + """ + # see nevow.url.py ? + + #/////////////////////////////////////////////////////////////////// + #----------AgentHome: CHILD PAGES SECTION-------------------------------------- + # this code section contains all child methods that load + # a new (html-) page + + def child_joboverview(self,context): + + """ User requested page from menue: "job overview" """ + return JobOverView(self.IniDict) + + #////////////////////////////////////////////////////////////////// + #--------AgentHome: CHILD METHODS SECTION------------------------------------- + # this code section contains all form methods invoked in AgentHome + # including their callback methods + + #---- page "Startpage" methods (class AgentHome) ---- + + def child_ChangeUserMode(self,context): + + """User has klicked the Change User Mode button + change UserMode from Simple <-> Professional""" + + print "[child_ChangeUserMode] UserMode: ", self.IniDict["UserMode"] + print "[child_ChangeUserMode] ----retrieving form values----" + + form = IRequest(context).args + + if form != {}: + + for elem in form: + print "[child_ChangeUserMode] ", form[elem] + + if self.IniDict["UserMode"] == "Simple": + self.IniDict["UserMode"] = "Advanced" + + else: + self.IniDict["UserMode"] = "Simple" + print "[child_ChangeUserMode] : ", self.IniDict["UserMode"] + + """ + Write changed setting back to the iniFile ? + filePointer = open(self.iniFile,"rw") + """ + + return AgentHome(self.IniDict) + + + def child_collectOutlookMails(self,context): + + """User requested page from menue: "Collect Outlook Mails" """ + + """ + deferred = MailCrawler.getOutlookMails() + deferred.addCallback(self.defMailCrawl,context) + deferred.addErrback(self.defMailCrawlError,context) + + return deferred + """ + + return AgentOutlookMailView(self.IniDict) + + + + def defMailCrawl(self,MailCollection,context): + + """here the returned collection is forwared to the page + that is displaying it""" + + return AgentOutlookMailView(self.IniDict,MailCollection) + + + def defMailCrawlError(self,ErrorMessage,context): + + """handles errors that ocurred in the MailCrawler""" + + return AgentHome(self.IniDict) + + + #---- page "job overview" methods (class JobOverView)---- + + def child_ViewJobDetails(self,context): + + form = IRequest(context).args + selectedJob = form['jobList'][0] + + return JobOverViewDetails(self.IniDict, selectedJob) + + + #//////////////////////////////////////////////////////////// + #-------------AgentHome: RENDER SECTION------------------------ + # this code section contains the Nevow Rendering Methods + # for building the page element tree + + def render_getActiveUserMode(self,context,data): + return self.IniDict["UserMode"] + + + def render_getAgentVersion(self,context,data): + return "0.1 alpha" + + + + +#/////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#----------------- PAGES SECTION ------------------------------------------------------------------------- +# all classes in this section are pages called via the navigation menue of AgentHome + +class JobOverView(rend.Page): + + docFactory = loaders.xmlfile('AgentJobView.html') + + def __init__(self, IniDict): + + self.IniSettings = IniDict + + #-------------RENDER SECTION--------------------------------- + # this code section contains the Nevow Rendering Methods + # for building the page element tree + + def data_displayViewForm(self,context,data): + return "Overview of all running Crawling jobs" + + def render_getActiveUserMode(self,context,data): + return self.IniSettings["UserMode"] + + def render_fillJobList(self,ctx,data): + + #---- get the registered jobs from the jobfile ---- + # + fpJobFile = open(JOBFILE,"r") + lines = fpJobFile.readlines() + fpJobFile.close() + patternList = [] + gen_pattern = inevow.IQ(ctx).patternGenerator('optionsJobList') + + for elem in lines: + patternList.append(gen_pattern(data=elem)) + + return patternList + + + + +class JobOverViewDetails(rend.Page): + + docFactory = loaders.xmlfile('AgentJobViewDetail.html') + + def __init__(self, IniDict={}, selectedJob=""): + + self.IniSettings = IniDict + self.jobdetails = selectedJob + + + #-------------RENDER SECTION--------------------------------- + # this code section contains the Nevow Rendering Methods + # for building the page element tree + + def data_displayViewForm(self,context,data): + return "Detailed view of crawling job." + + def render_getActiveUserMode(self,context,data): + return self.IniSettings["UserMode"] + + def render_displayJobDetails(self,ctx,data): + + print "*******************************************************" + print "[render_displayJobDetails] received form: ", str(self.jobdetails) + print "[render_displayJobDetails] received IniForm: ", str(self.IniSettings) + print "*******************************************************" + + patternList = [] + gen_pattern = inevow.IQ(ctx).patternGenerator('jobDetails') + + for elem in self.jobdetails: + patternList.append(gen_pattern(data=elem)) + + return patternList + + +class AgentOutlookMailView(rend.Page): + + docFactory = loaders.xmlfile('AgentOutlookMailView.html') + + def __init__(self, IniDict={}, MailCollection=[]): + + self.IniDict = IniDict + self.MailCollection = MailCollection + + #-------------RENDER SECTION--------------------------------- + # this code section contains the Nevow Rendering Methods + # for building the page element tree + + def data_displayViewForm(self,context,data): + return "Detailed view of all collected Outlook Mails. [DEMO]" + + def render_getActiveUserMode(self,context,data): + return self.IniDict["UserMode"] + + def render_displayOutlookMails(self,ctx,data): + + patternList = [] + gen_pattern = inevow.IQ(ctx).patternGenerator('OutlookMails') + + for elem in self.MailCollection: + patternList.append(gen_pattern(data=elem)) + + return patternList