From bdd0a41aed7edf21ec2a65cfa17a86af2ef8c48a Mon Sep 17 00:00:00 2001 From: dims Date: Tue, 17 Jun 2008 00:23:01 +0000 Subject: Move Tuscany from Incubator to top level. git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@668359 13f79535-47bb-0310-9956-ffa450edef68 --- .../sample.alerter/AlertCheckerImpl.py | 116 ++++++++++++++ .../sample.alerter/AlertConfigImpl.py | 175 +++++++++++++++++++++ .../AlertAggregator/sample.alerter/Alerter.xsd | 73 +++++++++ .../sample.alerter/POPCheckerImpl.py | 104 ++++++++++++ .../sample.alerter/POPCheckerImpl.rb | 122 ++++++++++++++ .../sample.alerter/RSSCheckerImpl.py | 76 +++++++++ .../sample.alerter/sample.alerter.composite | 49 ++++++ 7 files changed, 715 insertions(+) create mode 100644 cpp/sca/samples/AlertAggregator/sample.alerter/AlertCheckerImpl.py create mode 100644 cpp/sca/samples/AlertAggregator/sample.alerter/AlertConfigImpl.py create mode 100644 cpp/sca/samples/AlertAggregator/sample.alerter/Alerter.xsd create mode 100644 cpp/sca/samples/AlertAggregator/sample.alerter/POPCheckerImpl.py create mode 100644 cpp/sca/samples/AlertAggregator/sample.alerter/POPCheckerImpl.rb create mode 100644 cpp/sca/samples/AlertAggregator/sample.alerter/RSSCheckerImpl.py create mode 100644 cpp/sca/samples/AlertAggregator/sample.alerter/sample.alerter.composite (limited to 'cpp/sca/samples/AlertAggregator/sample.alerter') diff --git a/cpp/sca/samples/AlertAggregator/sample.alerter/AlertCheckerImpl.py b/cpp/sca/samples/AlertAggregator/sample.alerter/AlertCheckerImpl.py new file mode 100644 index 0000000000..d9aab820ac --- /dev/null +++ b/cpp/sca/samples/AlertAggregator/sample.alerter/AlertCheckerImpl.py @@ -0,0 +1,116 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +import xml.etree.ElementTree, datetime + +def getAllNewAlerts (): + + returnXML = "\n" + returnElem = xml.etree.ElementTree.XML(returnXML) + + # Use the alertConfigService to get the configuration + configElem = alertConfigService.getAlertConfig() + + for sourceElem in configElem.findall("./{http://tuscany.apache.org/samples/alerter}source"): + + sourceid = sourceElem.attrib["id"] + + newAlerts = getAlerts(sourceElem) + if xml.etree.ElementTree.iselement(newAlerts): + # Add the sourceid to each alert and append to the entire list + for alert in newAlerts.findall("./{http://tuscany.apache.org/samples/alerter}alert"): + alert.attrib["sourceid"] = sourceid + returnElem.append(alert) + + return returnElem + +def getAlerts (sourceElem): + + lastcheckedElem = sourceElem.find("./{http://tuscany.apache.org/samples/alerter}lastChecked") + if not xml.etree.ElementTree.iselement(lastcheckedElem): + lastcheckedElem = xml.etree.ElementTree.SubElement(sourceElem, "lastChecked") + lastcheckedElem.text = "" + + if sourceElem.attrib["type"] == "rss": + + feedaddress = sourceElem.find("./{http://tuscany.apache.org/samples/alerter}feedAddress").text + + if feedaddress: + # Use the rssCheckerService to get new articles for this config + newAlerts = rssCheckerService.getNewAlerts(feedaddress, lastcheckedElem.text) + + lastcheckedElem.text = datetime.datetime.now().replace(microsecond=0).isoformat() + alertConfigService.updateSourceConfig(sourceElem) + return newAlerts + + elif sourceElem.attrib["type"] == "pop": + + popserver = sourceElem.find("./{http://tuscany.apache.org/samples/alerter}popServer").text + popusername = sourceElem.find("./{http://tuscany.apache.org/samples/alerter}popUsername").text + poppassword = sourceElem.find("./{http://tuscany.apache.org/samples/alerter}popPassword").text + + if popserver and popusername and poppassword: + # Use the popCheckerService to get new emails for this config + newAlerts = popCheckerService.getNewAlerts(popserver, popusername, poppassword, lastcheckedElem.text) + + lastcheckedElem.text = datetime.datetime.now().replace(microsecond=0).isoformat() + alertConfigService.updateSourceConfig(sourceElem) + return newAlerts + + else: + print "Source type not supported: ", sourceElem.attrib["type"] + + return None + + +def getNewAlerts (sourceId): + # Use the alertConfigService to get the configuration + sourceConfigElem = alertConfigService.getSourceConfig(sourceId) + + # Get the alerts + newAlerts = getAlerts(sourceConfigElem) + + if xml.etree.ElementTree.iselement(newAlerts): + # Add the sourceid to each alert + for alert in newAlerts.findall("./{http://tuscany.apache.org/samples/alerter}alert"): + alert.attrib["sourceid"] = sourceId + + return newAlerts + +def addAlertSource (sourceElem): + # Add the source directly to the configuration + return alertConfigService.addSourceConfig(sourceElem) + +def updateAlertSource (sourceElem): + # Update the source in the configuration + return alertConfigService.updateSourceConfig(sourceElem) + +def removeAlertSource (sourceId): + # Remove the source from the configuration + alertConfigService.removeSourceConfig(sourceId) + +def getAlertSources (): + # Get the config for all the sources + return alertConfigService.getAlertConfig() + +# # Testing +# import AlertConfigImpl as alertConfigService +# import RSSCheckerImpl as rssCheckerService +# import POPCheckerImpl as popCheckerService +# +# print xml.etree.ElementTree.tostring(getAlertSources()) +# print xml.etree.ElementTree.tostring(getAllNewAlerts()) diff --git a/cpp/sca/samples/AlertAggregator/sample.alerter/AlertConfigImpl.py b/cpp/sca/samples/AlertAggregator/sample.alerter/AlertConfigImpl.py new file mode 100644 index 0000000000..2800a940b4 --- /dev/null +++ b/cpp/sca/samples/AlertAggregator/sample.alerter/AlertConfigImpl.py @@ -0,0 +1,175 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +import xml.etree.ElementTree, os.path, os + +def getAlertConfig (): + + # Set up some default config data + configData = "\n" + + if os.path.isfile(os.environ['TUSCANY_SCACPP_ROOT']+"/config.xml"): + # Retrieve the configuration from a file + f = open(os.environ['TUSCANY_SCACPP_ROOT']+"/config.xml") + try: + configData = f.read() + finally: + f.close() + + configElem = xml.etree.ElementTree.XML(configData) + + return configElem + +def getSourceConfig (sourceId): + + configElem = getAlertConfig() + + for sourceElem in configElem.findall("./{http://tuscany.apache.org/samples/alerter}source"): + if sourceElem.attrib["id"] == sourceId: + return sourceElem + + print "Source with id matching",sourceId,"not found" + return + +def updateSourceConfig (alertSourceConfigElem): + + configElem = getAlertConfig() + sourceId = alertSourceConfigElem.attrib["id"] + + for sourceElem in configElem.findall("./{http://tuscany.apache.org/samples/alerter}source"): + if sourceElem.attrib["id"] == sourceId: + configElem.remove(sourceElem) + configElem.append(alertSourceConfigElem) + saveConfigData(configElem) + return + print "Source with id matching",sourceId,"not found" + return + +def addSourceConfig (alertSourceConfigElem): + configElem = getAlertConfig() + + #check for source ID, make sure it's not the same as others and create one if it's missing + if "id" in alertSourceConfigElem.attrib: + configId = alertSourceConfigElem.attrib["id"] + else: + configId = "0" + + gotConfigId = False + + while gotConfigId == False: + + config = getSourceConfig(configId) + if config: + configId = str( int(configId)+1 ) + else: + gotConfigId = True + + + alertSourceConfigElem.attrib["id"] = configId + + configElem.append(alertSourceConfigElem) + saveConfigData(configElem) + + return configId + +def saveConfigData (configElem): + configData = xml.etree.ElementTree.tostring(configElem) + + # Save the configuration to a file + f = open(os.environ['TUSCANY_SCACPP_ROOT']+"/config.xml", "w") + + if not f: + print "Failed to open config file for writing" + try: + f.write(configData) + finally: + f.close() + +def removeSourceConfig(sourceId): + configElem = getAlertConfig() + for sourceElem in configElem.findall("./{http://tuscany.apache.org/samples/alerter}source"): + if sourceElem.attrib["id"] == sourceId: + configElem.remove(sourceElem) + saveConfigData(configElem) + return + +# # Testing +# if os.path.isfile("config.xml"): +# os.remove("config.xml") +# data = getAlertConfig() +# print xml.etree.ElementTree.tostring(data), "\n" +# +# newsrcxml = "\n" +# newsrcxml += "PSP Updates\n" +# newsrcxml += "
http://pspupdates.qj.net
\n" +# newsrcxml += "http://pspupdates.qj.net/rss.xml" +# +# newsrc = xml.etree.ElementTree.XML(newsrcxml) +# ID = addSourceConfig(newsrc) +# print "Added src with ID:", ID, "\n" +# +# newsrcxml = "\n" +# newsrcxml += "PSP Updates\n" +# newsrcxml += "
http://pspupdates.qj.net!
\n" +# newsrcxml += "http://pspupdates.qj.net/atom.xml" +# +# newsrc = xml.etree.ElementTree.XML(newsrcxml) +# ID = addSourceConfig(newsrc) +# print "Added src with ID:", ID, "\n" +# +# data = getAlertConfig() +# print xml.etree.ElementTree.tostring(data), "\n" +# +# data = getSourceConfig("0") +# print xml.etree.ElementTree.tostring(data), "\n" +# print dir(data), "\n" +# +# name = data.find("./{http://tuscany.apache.org/samples/alerter}name") +# name.text = "Hello world!" +# +# updateSourceConfig(data) +# data = getSourceConfig("1") +# print xml.etree.ElementTree.tostring(data), "\n" +# +# removeSourceConfig("1") +# data = getAlertConfig() +# print xml.etree.ElementTree.tostring(data), "\n" +# +# ID = addSourceConfig(newsrc) +# print "Added src with ID:", ID, "\n" +# +# ID = addSourceConfig(newsrc) +# print "Added src with ID:", ID, "\n" +# +# data = getAlertConfig() +# print xml.etree.ElementTree.tostring(data), "\n" +# +# +# newsrcxml = "\n" +# newsrcxml += "PSP Updates\n" +# newsrcxml += "
http://pspupdates.qj.net!
\n" +# newsrcxml += "http://pspupdates.qj.net/atom.xml" +# +# newsrc = xml.etree.ElementTree.XML(newsrcxml) +# ID = addSourceConfig(newsrc) +# print "Added src with ID:", ID, "\n" +# +# data = getAlertConfig() +# print xml.etree.ElementTree.tostring(data), "\n" +# + diff --git a/cpp/sca/samples/AlertAggregator/sample.alerter/Alerter.xsd b/cpp/sca/samples/AlertAggregator/sample.alerter/Alerter.xsd new file mode 100644 index 0000000000..c59460995d --- /dev/null +++ b/cpp/sca/samples/AlertAggregator/sample.alerter/Alerter.xsd @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/cpp/sca/samples/AlertAggregator/sample.alerter/POPCheckerImpl.py b/cpp/sca/samples/AlertAggregator/sample.alerter/POPCheckerImpl.py new file mode 100644 index 0000000000..0ae115ac2e --- /dev/null +++ b/cpp/sca/samples/AlertAggregator/sample.alerter/POPCheckerImpl.py @@ -0,0 +1,104 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +import poplib, email, datetime, re, xml.etree.ElementTree + +def getNewAlerts(popserver, username, password, lastchecktimestamp): + + print "POPCheckerImpl getting new POP e-mail alerts\n" + + alertsXML = "\n" + + # initially set lastchecked to the epoch before trying to use the lastchecked string + lastcheckdate = datetime.datetime.min + if lastchecktimestamp: + lastcheckdate = datetime.datetime.strptime(lastchecktimestamp, "%Y-%m-%dT%H:%M:%S") + + numberOfNewEmails = 0 + + mail = poplib.POP3(popserver) + mail.user(username) + mail.pass_(password) + msgCount, inboxSize = mail.stat() + + for msgNum in range(msgCount): + + print "getting msg", msgNum+1, "of", msgCount + + data = "" + for line in mail.retr(msgNum+1)[1]: + data += str(line) + data += "\n" + + msg = email.message_from_string(data) + + # date is of form "Sun, 21 Jan 2007 13:51:53 -0500" + msgDateString = msg.get("Date") + msgDateString, tz = msgDateString.rsplit(None, 1) + + timezoneadjust = datetime.timedelta(0, (int(tz)/100)*60*60 + int(tz[3:5])*60) + + msgdate = datetime.datetime.strptime(msgDateString, "%a, %d %b %Y %H:%M:%S") + timezoneadjust + + if msgdate >= lastcheckdate: + msgTo = msg.get("To") + msgFrom = msg.get("From") + msgSubject = msg.get("Subject") + + msgBody = "" + if msg.is_multipart(): + for msgPart in msg.get_payload(): + if msgPart.get_content_type() == "text/plain" or (msgPart.get_content_type() == "text/html" and msgBody == ""): + msgBody = msgPart.get_payload() + else: + msgBody = msg.get_payload() + + alertsXML += "" + encodeXML(msgFrom) + " - "+encodeXML(msgSubject)+"\n" + alertsXML += "
\n" + alertsXML += "" + msgdate.isoformat() + "\n" + alertsXML += "From: " + encodeXML(msgFrom) + alertsXML += "\nTo: "+encodeXML(msgTo) + alertsXML += "\nSubject: "+encodeXML(msgSubject) + alertsXML += "\nDate: " + msgdate.isoformat() + alertsXML += "\n\n" + stripXML(msgBody) + "
\n" + + + mail.quit() + + alertsXML += "
" + + return xml.etree.ElementTree.XML(alertsXML) + + +def encodeXML(data): + data = re.sub("<","[", data) + data = re.sub(">","]", data) + return data + +def stripXML(data): + elementsRemoved = re.sub("<.*?>","", data) + entitiesRemoved = re.sub("&.*?;", " ", elementsRemoved) + asciiEncoded = entitiesRemoved.encode('ASCII', 'replace') + returnData = asciiEncoded.replace('&', 'and') + return returnData + + + +# Testing + +# print getNewAlerts("mail.eclipse.co.uk", "andrew@borley-hall.eclipse.co.uk", "app73sauc3", "2007-01-29T02:15:53") diff --git a/cpp/sca/samples/AlertAggregator/sample.alerter/POPCheckerImpl.rb b/cpp/sca/samples/AlertAggregator/sample.alerter/POPCheckerImpl.rb new file mode 100644 index 0000000000..e61046cb84 --- /dev/null +++ b/cpp/sca/samples/AlertAggregator/sample.alerter/POPCheckerImpl.rb @@ -0,0 +1,122 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +require 'net/pop' +require "rexml/document" +include REXML + +# class POPChecker +# +# def initialize() +# print "POPCheckerImpl.initialize\n" +# end + +def getNewAlerts(popserver, username, password, lastchecked) + + print "POPCheckerImpl getting new POP e-mail alerts\n" + + alertsXML = "\n" + + # initially set lastchecked to the epoch before trying to use the lastchecked string + lastcheckedtime = Time.at(0) + if lastchecked != '' + # lastchecked (if provided) is of form 2007-02-17T23:34:56 + year , month, day, hour, min, sec = lastchecked.split(/[-T:]/) + lastcheckedtime = Time.gm(year , month, day, hour, min, sec, nil) + end + + numberOfEmails = 0 + + Net::POP3.start(popserver, 110, username, password) do |pop| + + if !pop.mails.empty? + pop.each_mail do |m| + msg = m.pop + + header, body = msg.split("\r\n\r\n", 2) + date = getMessageField("Date", header) + # date is of form "Sun, 21 Jan 2007 13:51:53 -0500" + parts = date.split(' ') + timeparts = parts[4].split(':') + timezoneSecs = (parts[5].to_i()/100)*60*60 + (parts[5].slice(-2,0).to_i())*60 + + msgtime = Time.gm(timeparts[2], timeparts[1], timeparts[0], parts[1], parts[2], parts[3], nil, nil, nil, nil) + timezoneSecs + + + if msgtime >= lastcheckedtime + from = getMessageField("From", header) + subject = getMessageField("Subject", header) + + alertsXML += "From: " + encodeXML(from) + "\nSubject: "+encodeXML(subject)+"\n" + alertsXML += "
\n" + alertsXML += "" + msgtime.strftime("%Y-%m-%dT%H:%M:%S") + "\n" + alertsXML += "" + stripXML(body) + "
\n" + + numberOfEmails += 1 + end + + end + end + end + alertsXML += "
" + + # Print XML + # puts alertsXML + print "POPCheckerImpl retrieved "+numberOfEmails.to_s+" new POP e-mail alerts\n" + + # Return data as REXML document + result = Document.new(alertsXML) + + return result +end + + +def getMessageField(field, message) + + # Use a regex to get the field + pattern = '^'+field+': (.*?)$' + + re = Regexp.new(pattern) + re =~ message + + if $1 == nil + return '' + end + + return $1 +end + +def encodeXML(data) + data = data.gsub(//,'>') + return data +end + +def stripXML(data) + data = data.gsub(/<.*?>/m,'') + data = data.gsub(/&.*?;/, ' ') + data = data.gsub(/&/, 'and') + data = encodeXML(data) + return data +end + + + +# # Testing +# pop = POPChecker.new() +# print pop.getNewAlerts("mail.eclipse.co.uk", "andrew@borley-hall.eclipse.co.uk", "app73sauc3", "2007-01-29T02:15:53") diff --git a/cpp/sca/samples/AlertAggregator/sample.alerter/RSSCheckerImpl.py b/cpp/sca/samples/AlertAggregator/sample.alerter/RSSCheckerImpl.py new file mode 100644 index 0000000000..2e320c0b22 --- /dev/null +++ b/cpp/sca/samples/AlertAggregator/sample.alerter/RSSCheckerImpl.py @@ -0,0 +1,76 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +import feedparser, datetime, xml.etree.ElementTree, re + +def getNewAlerts(rssaddress, lastchecktimestamp): + + print "RSSCheckerImpl.getNewAlerts() called", rssaddress, lastchecktimestamp + + #Get and parse the RSS/Atom data + d = feedparser.parse(rssaddress) + + newalertsxml = "\n" + + lastcheckdate = datetime.datetime.min + if lastchecktimestamp: + lastcheckdate = datetime.datetime.strptime(lastchecktimestamp, "%Y-%m-%dT%H:%M:%S") + + defaultTitle = d.feed.get('title', 'RSS feed article') + defaultLink = d.feed.get('link', 'http://incubator.apache.org/tuscany') + defaultSummary = 'No information provided' + + for entry in d.entries: + + if entry.has_key('date'): + (year, month, day, hour, minute, second, millisecond, microsecond, tzinfo) = entry.date_parsed + entrydate = datetime.datetime(year, month, day, hour, minute, second) + else: + entrydate = datetime.datetime.now() + + + if (entrydate > lastcheckdate) : + + newalertsxml += "" + stripXML(entry.get('title', defaultTitle)) + "\n" + newalertsxml += "
" + entry.get('link', defaultLink) + "
\n" + newalertsxml += "" + entrydate.isoformat() + "\n" + newalertsxml += "" + stripXML(entry.get('description', defaultSummary)) + "
\n" + newalertsxml += "
" + + return xml.etree.ElementTree.XML(newalertsxml) + +def stripXML(data): + elementsRemoved = re.sub("<.*?>","", data) + entitiesRemoved = re.sub("&.*?;", " ", elementsRemoved) + asciiEncoded = entitiesRemoved.encode('ASCII', 'replace') + returnData = asciiEncoded.replace('&', 'and') + return returnData + + +# Testing +# print xml.etree.ElementTree.tostring(getNewAlerts("http://www.engadget.com/rss.xml", "2007-02-07T17:11:14")) +# +# +# today = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) +# data2 = getNewAlerts("http://newsrss.bbc.co.uk/rss/newsonline_uk_edition/front_page/rss.xml", today.isoformat()) +# print xml.etree.ElementTree.tostring(data2) +# +# print "1st call returned", len(data.findall("./{http://tuscany.apache.org/samples/alerter}alert")), "elements" +# print "2nd call returned", len(data2.findall("./{http://tuscany.apache.org/samples/alerter}alert")), "elements" + + diff --git a/cpp/sca/samples/AlertAggregator/sample.alerter/sample.alerter.composite b/cpp/sca/samples/AlertAggregator/sample.alerter/sample.alerter.composite new file mode 100644 index 0000000000..21c4ee1093 --- /dev/null +++ b/cpp/sca/samples/AlertAggregator/sample.alerter/sample.alerter.composite @@ -0,0 +1,49 @@ + + + + + + + + AlertCheckerComponent + + + + + AlertConfigComponent + RSSCheckerComponent + POPCheckerComponent + + + + + + + + + + + + + + + + -- cgit v1.2.3