diff --git a/agent/.loops.agent.cfg b/agent/.loops.agent.cfg deleted file mode 100644 index d8a7e23..0000000 --- a/agent/.loops.agent.cfg +++ /dev/null @@ -1,232 +0,0 @@ -crawl[0].content_format = 'text' -crawl[0].filter_criteria = 'sender' -crawl[0].filter_pattern = 'MAIL1' -crawl[0].folder = 'Inbox' -crawl[0].getsubfolder = 'No' -crawl[0].include_attachements = 'Yes' -crawl[0].interval = 'oneTime' -crawl[0].jobid = 'outlook0' -crawl[0].latest = '' -crawl[0].state = 'completed' -crawl[0].type = 'OutlookMail' -crawl[10].content_format = 'text' -crawl[10].filter_criteria = 'sender' -crawl[10].filter_pattern = '' -crawl[10].folder = 'Inbox' -crawl[10].getsubfolder = 'Yes' -crawl[10].include_attachements = 'Yes' -crawl[10].interval = 'oneTime' -crawl[10].jobid = 'outlook10' -crawl[10].latest = '' -crawl[10].state = 'completed' -crawl[10].type = 'OutlookMail' -crawl[11].content_format = 'text' -crawl[11].filter_criteria = 'sender' -crawl[11].filter_pattern = '' -crawl[11].folder = 'Inbox' -crawl[11].getsubfolder = 'Yes' -crawl[11].include_attachements = 'Yes' -crawl[11].interval = 'oneTime' -crawl[11].jobid = 'outlook11' -crawl[11].latest = '' -crawl[11].state = 'completed' -crawl[11].type = 'OutlookMail' -crawl[12].content_format = 'text' -crawl[12].filter_criteria = 'sender' -crawl[12].filter_pattern = '' -crawl[12].folder = 'Inbox' -crawl[12].getsubfolder = 'Yes' -crawl[12].include_attachements = 'Yes' -crawl[12].interval = 'oneTime' -crawl[12].jobid = 'outlook12' -crawl[12].latest = '' -crawl[12].state = 'completed' -crawl[12].type = 'OutlookMail' -crawl[13].content_format = 'text' -crawl[13].filter_criteria = 'sender' -crawl[13].filter_pattern = '' -crawl[13].folder = 'Inbox' -crawl[13].getsubfolder = 'Yes' -crawl[13].include_attachements = 'Yes' -crawl[13].interval = 'oneTime' -crawl[13].jobid = 'outlook13' -crawl[13].latest = '' -crawl[13].state = 'completed' -crawl[13].type = 'OutlookMail' -crawl[14].content_format = 'text' -crawl[14].filter_criteria = 'sender' -crawl[14].filter_pattern = '' -crawl[14].folder = 'Inbox' -crawl[14].getsubfolder = 'Yes' -crawl[14].include_attachements = 'Yes' -crawl[14].interval = 'oneTime' -crawl[14].jobid = 'outlook14' -crawl[14].latest = '' -crawl[14].state = 'completed' -crawl[14].type = 'OutlookMail' -crawl[15].content_format = 'text' -crawl[15].filter_criteria = 'sender' -crawl[15].filter_pattern = '' -crawl[15].folder = 'Inbox' -crawl[15].getsubfolder = 'Yes' -crawl[15].include_attachements = 'Yes' -crawl[15].interval = 'oneTime' -crawl[15].jobid = 'outlook15' -crawl[15].latest = '' -crawl[15].state = 'completed' -crawl[15].type = 'OutlookMail' -crawl[16].content_format = 'text' -crawl[16].filter_criteria = 'sender' -crawl[16].filter_pattern = '' -crawl[16].folder = 'Inbox' -crawl[16].getsubfolder = 'Yes' -crawl[16].include_attachements = 'Yes' -crawl[16].interval = 'oneTime' -crawl[16].jobid = 'outlook16' -crawl[16].latest = '' -crawl[16].state = 'completed' -crawl[16].type = 'OutlookMail' -crawl[17].content_format = 'text' -crawl[17].filter_criteria = 'sender' -crawl[17].filter_pattern = '' -crawl[17].folder = 'Inbox' -crawl[17].getsubfolder = 'Yes' -crawl[17].include_attachements = 'Yes' -crawl[17].interval = 'oneTime' -crawl[17].jobid = 'outlook17' -crawl[17].latest = '' -crawl[17].state = 'completed' -crawl[17].type = 'OutlookMail' -crawl[18].content_format = 'text' -crawl[18].filter_criteria = 'sender' -crawl[18].filter_pattern = '' -crawl[18].folder = 'Inbox' -crawl[18].getsubfolder = 'Yes' -crawl[18].include_attachements = 'Yes' -crawl[18].interval = 'oneTime' -crawl[18].jobid = 'outlook18' -crawl[18].latest = '' -crawl[18].state = 'completed' -crawl[18].type = 'OutlookMail' -crawl[19].content_format = 'text' -crawl[19].filter_criteria = 'sender' -crawl[19].filter_pattern = '' -crawl[19].folder = 'Inbox' -crawl[19].getsubfolder = 'Yes' -crawl[19].include_attachements = 'Yes' -crawl[19].interval = 'oneTime' -crawl[19].jobid = 'outlook19' -crawl[19].latest = '' -crawl[19].state = 'completed' -crawl[19].type = 'OutlookMail' -crawl[1].content_format = 'text' -crawl[1].filter_criteria = 'subject' -crawl[1].filter_pattern = 'MAIL2' -crawl[1].folder = 'Inbox' -crawl[1].getsubfolder = 'No' -crawl[1].include_attachements = 'Yes' -crawl[1].interval = 'oneTime' -crawl[1].jobid = 'outlook1' -crawl[1].latest = '' -crawl[1].state = 'completed' -crawl[1].type = 'OutlookMail' -crawl[20].content_format = 'text' -crawl[20].filter_criteria = 'sender' -crawl[20].filter_pattern = '' -crawl[20].folder = 'Inbox' -crawl[20].getsubfolder = 'Yes' -crawl[20].include_attachements = 'Yes' -crawl[20].interval = 'oneTime' -crawl[20].jobid = 'outlook20' -crawl[20].latest = '' -crawl[20].state = 'completed' -crawl[20].type = 'OutlookMail' -crawl[2].content_format = 'text' -crawl[2].filter_criteria = 'receiver' -crawl[2].filter_pattern = 'Project' -crawl[2].folder = 'Inbox' -crawl[2].getsubfolder = 'No' -crawl[2].include_attachements = 'Yes' -crawl[2].interval = 'oneTime' -crawl[2].jobid = 'outlook2' -crawl[2].latest = '' -crawl[2].state = 'completed' -crawl[2].type = 'OutlookMail' -crawl[3].content_format = 'text' -crawl[3].filter_criteria = 'sender' -crawl[3].filter_pattern = 'Test' -crawl[3].folder = 'Inbox' -crawl[3].getsubfolder = 'Yes' -crawl[3].include_attachements = 'Yes' -crawl[3].interval = 'oneTime' -crawl[3].jobid = 'outlook3' -crawl[3].latest = '' -crawl[3].state = 'completed' -crawl[3].type = 'OutlookMail' -crawl[4].content_format = 'text' -crawl[4].filter_criteria = 'subject' -crawl[4].filter_pattern = 'savetoFile' -crawl[4].folder = 'Inbox' -crawl[4].getsubfolder = 'No' -crawl[4].include_attachements = 'Yes' -crawl[4].interval = 'oneTime' -crawl[4].jobid = 'outlook4' -crawl[4].latest = '' -crawl[4].state = 'completed' -crawl[4].type = 'OutlookMail' -crawl[5].content_format = 'text' -crawl[5].filter_criteria = 'subject' -crawl[5].filter_pattern = 'savetoFile' -crawl[5].folder = 'Inbox' -crawl[5].getsubfolder = 'No' -crawl[5].include_attachements = 'Yes' -crawl[5].interval = 'oneTime' -crawl[5].jobid = 'outlook5' -crawl[5].latest = '' -crawl[5].state = 'completed' -crawl[5].type = 'OutlookMail' -crawl[6].content_format = 'text' -crawl[6].filter_criteria = 'subject' -crawl[6].filter_pattern = '' -crawl[6].folder = 'Inbox' -crawl[6].getsubfolder = 'No' -crawl[6].include_attachements = 'Yes' -crawl[6].interval = 'oneTime' -crawl[6].jobid = 'outlook6' -crawl[6].latest = '' -crawl[6].state = 'completed' -crawl[6].type = 'OutlookMail' -crawl[7].content_format = 'text' -crawl[7].filter_criteria = 'sender' -crawl[7].filter_pattern = '' -crawl[7].folder = 'Inbox' -crawl[7].getsubfolder = 'No' -crawl[7].include_attachements = 'Yes' -crawl[7].interval = 'oneTime' -crawl[7].jobid = 'outlook7' -crawl[7].latest = '' -crawl[7].state = 'completed' -crawl[7].type = 'OutlookMail' -crawl[8].content_format = 'text' -crawl[8].filter_criteria = 'sender' -crawl[8].filter_pattern = '' -crawl[8].folder = 'Inbox' -crawl[8].getsubfolder = 'Yes' -crawl[8].include_attachements = 'Yes' -crawl[8].interval = 'oneTime' -crawl[8].jobid = 'outlook8' -crawl[8].latest = '' -crawl[8].state = 'completed' -crawl[8].type = 'OutlookMail' -crawl[9].content_format = 'text' -crawl[9].filter_criteria = 'subject' -crawl[9].filter_pattern = 'MailCrawler' -crawl[9].folder = 'Inbox' -crawl[9].getsubfolder = 'Yes' -crawl[9].include_attachements = 'Yes' -crawl[9].interval = 'oneTime' -crawl[9].jobid = 'outlook9' -crawl[9].latest = '' -crawl[9].state = 'completed' -crawl[9].type = 'OutlookMail' -ui.web.usermode = 'Simple' \ No newline at end of file diff --git a/agent/README.txt b/agent/README.txt index 39b9219..36e6727 100644 --- a/agent/README.txt +++ b/agent/README.txt @@ -130,8 +130,8 @@ How does this work? >>> from loops.agent.schedule import Job >>> class TestJob(Job): - ... def execute(self, **kw): - ... d = super(TestJob, self).execute(**kw) + ... def execute(self): + ... d = super(TestJob, self).execute() ... print 'executing' ... return d @@ -149,7 +149,7 @@ classes from the testing package. >>> from loops.agent.testing import transport >>> crawlJob = crawl.CrawlingJob() - >>> transporter = transport.Transporter() + >>> transporter = transport.Transporter(agent) >>> transportJob = transporter.jobFactory(transporter) >>> crawlJob.successors.append(transportJob) >>> scheduler.schedule(crawlJob, int(time())) @@ -243,11 +243,12 @@ Transport Configuration -- URL of the target loops site, e.g. http://z3.loops.cy55.de/bwp/d5 -- username, password for logging in to loops -- machine name: name under which the client computer is know to the - loops server -- Transfer method, e.g. PUT +- ``transport.url``: URL of the target loops site, e.g. + "http://z3.loops.cy55.de/bwp/d5" +- ``transport.user``, ``transport.password`` for logging in to loops +- ``transport.machine: name under which the client computer is + known to the loops server +- ``transport.method``, e.g. "put" The following information is intended for the default transfer protocol/method HTTP PUT but probably also pertains to other protocols @@ -257,9 +258,9 @@ Format/Information structure ---------------------------- - Metadata URL (for storing or accessing metadata sets - optional, see below): - ``$loopsSiteURL/resource_meta/$machine_name/$service/$path.xml`` + ``$loopsSiteURL/resource_meta/$machine_name/$user/$service/$path.xml`` - Resource URL (for storing or accessing the real resources): - ``$loopsSiteURL/resource_data/$machine_name/$service/$path`` + ``$loopsSiteURL/resource_data/$machine_name//$user/$service/$path`` - ``$service`` names the crawler service, e.g. "filesystem" or "outlook" - ``$path`` represents the full path, possibly with drive specification in front (for filesystem resources on Windows), with special characters URL-escaped diff --git a/agent/core.py b/agent/core.py index 508a915..c43309a 100644 --- a/agent/core.py +++ b/agent/core.py @@ -55,18 +55,18 @@ class Agent(object): def scheduleJobsFromConfig(self): config = self.config scheduler = self.scheduler - for info in config.crawl: + for idx, info in enumerate(config.crawl): crawlType = info.type factory = self.crawlTypes.get(crawlType) if factory is not None: job = factory() job.params = dict((name, value) - for name, value in info.items() - if name not in ('starttime',)) + for name, value in info.items() + if name not in job.baseProperties) transportType = info.transport or 'httpput' factory = self.transportTypes.get(transportType) if factory is not None: - transporter = factory() + transporter = factory(self) # TODO: configure transporter or - better - # set up transporter(s) just once job.successors.append(transporter.jobFactory(transporter)) diff --git a/agent/crawl/base.py b/agent/crawl/base.py index 1f1ec0b..baa7944 100644 --- a/agent/crawl/base.py +++ b/agent/crawl/base.py @@ -24,7 +24,7 @@ $Id$ from zope.interface import implements -from loops.agent.interfaces import ICrawlingJob +from loops.agent.interfaces import ICrawlingJob, IMetadataSet from loops.agent.schedule import Job @@ -32,10 +32,21 @@ class CrawlingJob(Job): implements(ICrawlingJob) - def __init__(self): + baseProperties = ('starttime', 'type', 'repeat', 'transportType',) + + def __init__(self, **params): self.predefinedMetadata = {} - super(CrawlingJob, self).__init__() + super(CrawlingJob, self).__init__(**params) + + def execute(self): + return self.collect() + + +class Metadata(object): + + implements(IMetadataSet) + + def __init__(self, data=dict()): + self.data = data - def execute(self, **kw): - return self.collect(**kw) diff --git a/agent/crawl/filesystem.py b/agent/crawl/filesystem.py index 33c2c41..0b4b6f1 100644 --- a/agent/crawl/filesystem.py +++ b/agent/crawl/filesystem.py @@ -22,26 +22,32 @@ Filesystem crawler. $Id$ """ -import os -import re -import stat +import os, re, stat +from datetime import datetime from twisted.internet.defer import Deferred +from twisted.internet.task import coiterate from zope.interface import implements -from loops.agent.interfaces import ICrawlingJob, IResource, IMetadataSet +from loops.agent.interfaces import IResource from loops.agent.crawl.base import CrawlingJob as BaseCrawlingJob +from loops.agent.crawl.base import Metadata class CrawlingJob(BaseCrawlingJob): - def collect(self, **criteria): - deferred = reactor.deferToThread(self.crawlFilesystem, dataAvailable) + def collect(self): + self.data = [] + #deferred = reactor.deferToThread(self.crawlFilesystem, dataAvailable) + deferred = self.deferred = Deferred() + self.internalDeferred = coiterate(self.crawlFilesystem()) + self.internalDeferred.addCallback(self.finished) return deferred - def dataAvailable(self): - self.deferred.callback([(FileResource(), Metadata())]) + def finished(self, result): + self.deferred.callback(self.data) - def crawlFilesystem(self, **criteria): + def crawlFilesystem(self): + criteria = self.params directory = criteria.get('directory') pattern = re.compile(criteria.get('pattern') or '.*') for path, dirs, files in os.walk(directory): @@ -49,18 +55,23 @@ class CrawlingJob(BaseCrawlingJob): del dirs[dirs.index('.svn')] for f in files: if pattern.match(f): - mtime = os.stat(os.path.join(path, f))[stat.ST_MTIME] - yield (os.path.join(path[len(directory)+1:], f), - datetime.fromtimestamp(mtime)) - - -class Metadata(object): - - implements(IMetadataSet) + filename = os.path.join(path, f) + mtime = datetime.fromtimestamp( + os.stat(filename)[stat.ST_MTIME]) + # TODO: check modification time + self.data.append((FileResource(filename), + Metadata(dict()))) + yield None class FileResource(object): implements(IResource) - data = 'Dummy resource data for testing purposes.' + def __init__(self, path): + self.path = path + + @property + def data(self): + return open(self.path, 'r') + diff --git a/agent/crawl/filesystem.txt b/agent/crawl/filesystem.txt index c5538dd..e569a03 100644 --- a/agent/crawl/filesystem.txt +++ b/agent/crawl/filesystem.txt @@ -4,14 +4,37 @@ loops.agent.crawl.filesystem - The Filesystem Crawler ($Id$) - >>> from loops.agent.tests import tester - >>> from loops.agent.core import Agent + >>> import os + >>> from time import time - >>> agent = Agent() + >>> from loops.agent.tests import tester, baseDir + >>> from loops.agent.core import Agent >>> from loops.agent.crawl.filesystem import CrawlingJob - >>> from time import time + >>> agent = Agent() >>> scheduler = agent.scheduler - >>> scheduler.schedule(CrawlingJob(), int(time())) + +We create a crawling job that should scan the data subdirectory +of the testing directory in the loops.agent package. + + >>> dirname = os.path.join(baseDir, 'testing', 'data') + >>> crawlJob = CrawlingJob(directory=dirname) + +The result of the crawling process should be transferred using +the dummy transporter from the testing package; this just prints +an informative message with the contents of the files to be +transferred. + + >>> from loops.agent.testing import transport + >>> transporter = transport.Transporter(agent) + >>> transportJob = transporter.jobFactory(transporter) + >>> crawlJob.successors.append(transportJob) + +We are now ready to schedule the job and let the reactor execute it. + + >>> scheduler.schedule(crawlJob, int(time())) >>> tester.iterate() + Transferring: Data from file1.txt + Transferring: Data from file2.txt + diff --git a/agent/interfaces.py b/agent/interfaces.py index 19b3f0c..7c30acf 100644 --- a/agent/interfaces.py +++ b/agent/interfaces.py @@ -60,12 +60,12 @@ class IScheduledJob(Interface): """ startTime = Attribute('Date/time at which the job should be executed.') - params = Attribute('Mapping with key/value pairs to be passed to the ' - 'execute method call as keyword parameters.') + params = Attribute('Mapping with key/value pairs to be used by ' + 'the ``execute()`` method.') successors = Attribute('Jobs to execute immediately after this ' 'one has been finished.') - def execute(**kw): + def execute(): """ Execute the job. Store log information about job execution in a log record. @@ -94,7 +94,7 @@ class ICrawlingJob(IScheduledJob): predefinedMetadata = Attribute('A mapping with metadata to be used ' 'for all resources found.') - def collect(**criteria): + def collect(): """ Return a deferred that upon callback will provide a collection of resource/metadata pairs that should be transferred to the server. @@ -145,7 +145,7 @@ class ITransporter(Interface): userName = Attribute('User name for logging in to the server.') password = Attribute('Password for logging in to the server.') - def transfer(resource, metadata=None, resourceType=file): + def transfer(resource, metadata=None): """ Transfer the resource (typically just a file that may be read) to the server. diff --git a/agent/mails/Mail0 b/agent/mails/Mail0 deleted file mode 100644 index af79140..0000000 --- a/agent/mails/Mail0 +++ /dev/null @@ -1,79 +0,0 @@ -From nobody Wed Aug 08 17:38:02 2007 -Content-Type: multipart/mixed; boundary="===============1611091771==" -MIME-Version: 1.0 -Subject: Willkommen bei Microsoft Outlook 2000! -From: Microsoft Outlook 2000 -To: - - - - -Willkommen bei -Microsoft Outlook 2000 -Das Fenster zu Ihrer Informationswelt -  Microsoft(R) Outlook(R) 2000  ist die führende Clientsoftware für Kommunikation und Zusammenarbeit, mit der Sie Ihre Arbeitsabläufe optimieren können. Outlook kombiniert auf führendem Leistungsniveau -E-Mail-Funktionen (Internet- und Microsoft Exchange Server-Standards) mit integrierten Managementfunktionen für Aufgaben, Kontakte und den Kalender. -In Outlook werden Informationen in Ordnern organisiert. Beim Starten von Outlook wird der Ordner “Posteingang” geöffnet. Verwenden Sie den Posteingang, um E-Mail-Nachrichten sowie Besprechungs- und Aufgabenanfragen zu lesen und zu senden. - -Um eine neue Nachricht zu erstellen, zeigen Sie im Menü "Datei" auf "Neu", und klicken Sie dann auf "Nachricht". Tragen Sie in den Feldern "An" und "Cc" die Namen der Empfänger ein, im Feld "Betreff" das Thema der Nachricht, und verfassen Sie die Nachricht anschließend im Textfeld. Wenn Sie die Nachricht zum Senden fertig gestellt haben, klicken Sie auf "Senden". - -Um schnell zu einer anderen Outlook-Komponente zu wechseln, klicken Sie auf die entsprechende Verknüpfung auf der Outlook-Leiste, die sich links neben dem Posteingang befindet. Klicken Sie z.B. auf Kalender, um den Kalenderordner zu öffnen. Die Ordnerleiste (die horizontale Leiste oberhalb des Informationsbereichs) zeigt den Namen des geöffneten Ordners an. Um eine vollständige Liste mit allen Ordnern anzuzeigen, klicken Sie in der Ordnerleiste auf den Ordnernamen. - -Hier sind einige der neuen Funktionen in Outlook 2000: - -Outlook(R) Heute stellt Ihre E-Mail-, Kalender- und Aufgaben-Information in einem Fenster übersichtlich dar. Outlook Heute kann mit einem Klick auf das entsprechende Symbol auf der Outlook-Leiste gestartet werden. Sie können Outlook Heute auch als Ihr Standardfenster beim Starten von Outlook einstellen, damit Sie die Prioritäten für Ihren Arbeitstag mit einem Blick festlegen können. - -In der Outlook-Leiste können Sie Verknüpfungen zu Dateien, Ordnern oder Webseiten erstellen. Sie können auf der Outlook-Leiste auf eine Verknüpfung zu einer Webseite klicken, und diese Seite dann im Outlook-Fenster auf der rechten Seite ansehen. - -Senden und empfangen Sie Ihre E-Mail im HTML-Format, um Ihre Nachrichten so eindrucksvoll zu gestalten wie Webinhalt. - -Nutzen Sie die Vorteile, die sich aus der Internet-Protokollunterstützung von Outlook 2000 für POP3/SMTP, IMAP4, LDAP, NNTP, S/MIME, HTML Mail, vCard, vCalendar und iCalendar ergeben.  - -Das innovative Suchprogramm verwendet eine Suche im Webstil: Sie geben die Information ein, nach der gesucht wird. Auf diese Weise finden Sie schnell Nachrichten, Termine und Aufgaben. - -Gestalten Sie Ihre Arbeit übersichtlicher, indem Sie die Schaltfläche "Organisieren" auf der Symbolleiste verwenden, um auf einfache Weise den Inhalt eines Ordners zu organisieren, Regeln zu erstellen und Junk-E-Mail herauszufiltern. - -Mit einem einzigen Befehl können Sie nun Ihren persönlichen oder den Team-Kalender als Webseite veröffentlichen. - -Erstellen und speichern Sie Ihre persönlichen Verteilerlisten zusammen mit Ihren Kontakten im Kontakteordner. - -Mit der Serienbrieffunktion für E-Mail-, Fax- oder Briefversand können Sie Ihre Massenpost verwalten, wobei Sie selber entscheiden können, welche Kontakte und Kontaktfelder für die Serienbrieferstellung verwendet werden sollen. - -Verwenden Sie die Registerkarte "Aktivitäten" eines Kontaktelements, um unter anderem die Nachrichten, Termine und Aufgaben eines bestimmten Kontakts dynamisch zu verfolgen und anzuzeigen. - -Für weitere Informationen: - -Besuchen Sie die Office Update-Website unter http://officeupdate.microsoft.com/germany/outlook . Hier lernen Sie, wie Sie das Beste aus Microsoft(R) Outlook(R) 2000 herausholen können. - -Erweitern Sie die Nützlichkeit von Outlook 2000 mit neuen Add-Ins, Dienstprogrammen und anderen Downloads. - - - -Vereinfachen Sie die Verwendung von Outlook 2000 noch weiter mithilfe von zeitsparenden Tipps und Ratschlägen zur Problemlösung. - - - -Feedback, Antworten auf häufig gestellte Fragen (FAQs) und Tipps finden Sie in unseren öffentlichen Newsgroups für Outlook 2000. - - - -Lernen Sie, wie Sie mit Spezialangeboten und einer Vielzahl von Add-On-Produkten von Drittanbietern die Funktionalität von Outlook 2000 erweitern. - - - -Beschaffen Sie sich eine Liste der häufigsten Support-Fragen zu Outlook 2000. - - - -Hier finden Sie auch die aktuellsten Softwareupdates für Outlook 2000. - -Wir hoffen, dass Ihnen die Arbeit mit Microsoft Outlook, einem der vollständigsten, zurzeit  -erhältlichen E-Mail-Programme, Vergnügen bereiten wird!  - -- Ihr Microsoft Outlook-Team - -  -Microsoft Internet Explorer Microsoft Office Microsoft Exchange Server Microsoft NetMeeting Microsoft Windows Media Technologies ---===============1611091771== - ---===============1611091771==-- \ No newline at end of file diff --git a/agent/mails/Mail1 b/agent/mails/Mail1 deleted file mode 100644 index 8c9dd55..0000000 --- a/agent/mails/Mail1 +++ /dev/null @@ -1,79 +0,0 @@ -From nobody Wed Aug 08 17:38:39 2007 -Content-Type: multipart/mixed; boundary="===============1084757079==" -MIME-Version: 1.0 -Subject: Willkommen bei Microsoft Outlook 2000! -From: Microsoft Outlook 2000 -To: - - - - -Willkommen bei -Microsoft Outlook 2000 -Das Fenster zu Ihrer Informationswelt -  Microsoft(R) Outlook(R) 2000  ist die führende Clientsoftware für Kommunikation und Zusammenarbeit, mit der Sie Ihre Arbeitsabläufe optimieren können. Outlook kombiniert auf führendem Leistungsniveau -E-Mail-Funktionen (Internet- und Microsoft Exchange Server-Standards) mit integrierten Managementfunktionen für Aufgaben, Kontakte und den Kalender. -In Outlook werden Informationen in Ordnern organisiert. Beim Starten von Outlook wird der Ordner “Posteingang” geöffnet. Verwenden Sie den Posteingang, um E-Mail-Nachrichten sowie Besprechungs- und Aufgabenanfragen zu lesen und zu senden. - -Um eine neue Nachricht zu erstellen, zeigen Sie im Menü "Datei" auf "Neu", und klicken Sie dann auf "Nachricht". Tragen Sie in den Feldern "An" und "Cc" die Namen der Empfänger ein, im Feld "Betreff" das Thema der Nachricht, und verfassen Sie die Nachricht anschließend im Textfeld. Wenn Sie die Nachricht zum Senden fertig gestellt haben, klicken Sie auf "Senden". - -Um schnell zu einer anderen Outlook-Komponente zu wechseln, klicken Sie auf die entsprechende Verknüpfung auf der Outlook-Leiste, die sich links neben dem Posteingang befindet. Klicken Sie z.B. auf Kalender, um den Kalenderordner zu öffnen. Die Ordnerleiste (die horizontale Leiste oberhalb des Informationsbereichs) zeigt den Namen des geöffneten Ordners an. Um eine vollständige Liste mit allen Ordnern anzuzeigen, klicken Sie in der Ordnerleiste auf den Ordnernamen. - -Hier sind einige der neuen Funktionen in Outlook 2000: - -Outlook(R) Heute stellt Ihre E-Mail-, Kalender- und Aufgaben-Information in einem Fenster übersichtlich dar. Outlook Heute kann mit einem Klick auf das entsprechende Symbol auf der Outlook-Leiste gestartet werden. Sie können Outlook Heute auch als Ihr Standardfenster beim Starten von Outlook einstellen, damit Sie die Prioritäten für Ihren Arbeitstag mit einem Blick festlegen können. - -In der Outlook-Leiste können Sie Verknüpfungen zu Dateien, Ordnern oder Webseiten erstellen. Sie können auf der Outlook-Leiste auf eine Verknüpfung zu einer Webseite klicken, und diese Seite dann im Outlook-Fenster auf der rechten Seite ansehen. - -Senden und empfangen Sie Ihre E-Mail im HTML-Format, um Ihre Nachrichten so eindrucksvoll zu gestalten wie Webinhalt. - -Nutzen Sie die Vorteile, die sich aus der Internet-Protokollunterstützung von Outlook 2000 für POP3/SMTP, IMAP4, LDAP, NNTP, S/MIME, HTML Mail, vCard, vCalendar und iCalendar ergeben.  - -Das innovative Suchprogramm verwendet eine Suche im Webstil: Sie geben die Information ein, nach der gesucht wird. Auf diese Weise finden Sie schnell Nachrichten, Termine und Aufgaben. - -Gestalten Sie Ihre Arbeit übersichtlicher, indem Sie die Schaltfläche "Organisieren" auf der Symbolleiste verwenden, um auf einfache Weise den Inhalt eines Ordners zu organisieren, Regeln zu erstellen und Junk-E-Mail herauszufiltern. - -Mit einem einzigen Befehl können Sie nun Ihren persönlichen oder den Team-Kalender als Webseite veröffentlichen. - -Erstellen und speichern Sie Ihre persönlichen Verteilerlisten zusammen mit Ihren Kontakten im Kontakteordner. - -Mit der Serienbrieffunktion für E-Mail-, Fax- oder Briefversand können Sie Ihre Massenpost verwalten, wobei Sie selber entscheiden können, welche Kontakte und Kontaktfelder für die Serienbrieferstellung verwendet werden sollen. - -Verwenden Sie die Registerkarte "Aktivitäten" eines Kontaktelements, um unter anderem die Nachrichten, Termine und Aufgaben eines bestimmten Kontakts dynamisch zu verfolgen und anzuzeigen. - -Für weitere Informationen: - -Besuchen Sie die Office Update-Website unter http://officeupdate.microsoft.com/germany/outlook . Hier lernen Sie, wie Sie das Beste aus Microsoft(R) Outlook(R) 2000 herausholen können. - -Erweitern Sie die Nützlichkeit von Outlook 2000 mit neuen Add-Ins, Dienstprogrammen und anderen Downloads. - - - -Vereinfachen Sie die Verwendung von Outlook 2000 noch weiter mithilfe von zeitsparenden Tipps und Ratschlägen zur Problemlösung. - - - -Feedback, Antworten auf häufig gestellte Fragen (FAQs) und Tipps finden Sie in unseren öffentlichen Newsgroups für Outlook 2000. - - - -Lernen Sie, wie Sie mit Spezialangeboten und einer Vielzahl von Add-On-Produkten von Drittanbietern die Funktionalität von Outlook 2000 erweitern. - - - -Beschaffen Sie sich eine Liste der häufigsten Support-Fragen zu Outlook 2000. - - - -Hier finden Sie auch die aktuellsten Softwareupdates für Outlook 2000. - -Wir hoffen, dass Ihnen die Arbeit mit Microsoft Outlook, einem der vollständigsten, zurzeit  -erhältlichen E-Mail-Programme, Vergnügen bereiten wird!  - -- Ihr Microsoft Outlook-Team - -  -Microsoft Internet Explorer Microsoft Office Microsoft Exchange Server Microsoft NetMeeting Microsoft Windows Media Technologies ---===============1084757079== - ---===============1084757079==-- \ No newline at end of file diff --git a/agent/mails/Mail10 b/agent/mails/Mail10 deleted file mode 100644 index 9ed29f1..0000000 --- a/agent/mails/Mail10 +++ /dev/null @@ -1,13 +0,0 @@ -From nobody Wed Aug 08 19:33:53 2007 -Content-Type: multipart/mixed; boundary="===============0462019246==" -MIME-Version: 1.0 -Subject: Just a test for subfolder mails -From: -To: , - -This mail is a plain simple text mail, stored in the subfolder. - -Greetings, the programmer ---===============0462019246== - ---===============0462019246==-- \ No newline at end of file diff --git a/agent/mails/Mail11 b/agent/mails/Mail11 deleted file mode 100644 index eac7cb2..0000000 --- a/agent/mails/Mail11 +++ /dev/null @@ -1,13 +0,0 @@ -From nobody Wed Aug 08 19:37:00 2007 -Content-Type: multipart/mixed; boundary="===============0845798496==" -MIME-Version: 1.0 -Subject: Just a test for subfolder mails -From: -To: , - -This mail is a plain simple text mail, stored in the subfolder. - -Greetings, the programmer ---===============0845798496== - ---===============0845798496==-- \ No newline at end of file diff --git a/agent/mails/Mail12 b/agent/mails/Mail12 deleted file mode 100644 index 01a40da..0000000 --- a/agent/mails/Mail12 +++ /dev/null @@ -1,13 +0,0 @@ -From nobody Wed Aug 08 19:41:41 2007 -Content-Type: multipart/mixed; boundary="===============0256854354==" -MIME-Version: 1.0 -Subject: Just a test for subfolder mails -From: -To: , - -This mail is a plain simple text mail, stored in the subfolder. - -Greetings, the programmer ---===============0256854354== - ---===============0256854354==-- \ No newline at end of file diff --git a/agent/mails/Mail13 b/agent/mails/Mail13 deleted file mode 100644 index 63f245a..0000000 --- a/agent/mails/Mail13 +++ /dev/null @@ -1,13 +0,0 @@ -From nobody Wed Aug 08 19:43:21 2007 -Content-Type: multipart/mixed; boundary="===============0997011639==" -MIME-Version: 1.0 -Subject: Just a test for subfolder mails -From: -To: , - -This mail is a plain simple text mail, stored in the subfolder. - -Greetings, the programmer ---===============0997011639== - ---===============0997011639==-- \ No newline at end of file diff --git a/agent/mails/Mail14 b/agent/mails/Mail14 deleted file mode 100644 index 8fef9e8..0000000 --- a/agent/mails/Mail14 +++ /dev/null @@ -1,13 +0,0 @@ -From nobody Wed Aug 08 19:44:50 2007 -Content-Type: multipart/mixed; boundary="===============2082887985==" -MIME-Version: 1.0 -Subject: Just a test for subfolder mails -From: -To: , - -This mail is a plain simple text mail, stored in the subfolder. - -Greetings, the programmer ---===============2082887985== - ---===============2082887985==-- \ No newline at end of file diff --git a/agent/mails/Mail2 b/agent/mails/Mail2 deleted file mode 100644 index 3961503..0000000 --- a/agent/mails/Mail2 +++ /dev/null @@ -1,13 +0,0 @@ -From nobody Wed Aug 08 18:54:16 2007 -Content-Type: multipart/mixed; boundary="===============0880114339==" -MIME-Version: 1.0 -Subject: Just a test for subfolder mails -From: -To: , - -This mail is a plain simple text mail, stored in the subfolder. - -Greetings, the programmer ---===============0880114339== - ---===============0880114339==-- \ No newline at end of file diff --git a/agent/mails/Mail3 b/agent/mails/Mail3 deleted file mode 100644 index 57da6e2..0000000 --- a/agent/mails/Mail3 +++ /dev/null @@ -1,13 +0,0 @@ -From nobody Wed Aug 08 19:05:34 2007 -Content-Type: multipart/mixed; boundary="===============1328191004==" -MIME-Version: 1.0 -Subject: Just a test for subfolder mails -From: -To: , - -This mail is a plain simple text mail, stored in the subfolder. - -Greetings, the programmer ---===============1328191004== - ---===============1328191004==-- \ No newline at end of file diff --git a/agent/mails/Mail4 b/agent/mails/Mail4 deleted file mode 100644 index 4aa6ce8..0000000 --- a/agent/mails/Mail4 +++ /dev/null @@ -1,13 +0,0 @@ -From nobody Wed Aug 08 19:24:11 2007 -Content-Type: multipart/mixed; boundary="===============1905543225==" -MIME-Version: 1.0 -Subject: Just a test for subfolder mails -From: -To: , - -This mail is a plain simple text mail, stored in the subfolder. - -Greetings, the programmer ---===============1905543225== - ---===============1905543225==-- \ No newline at end of file diff --git a/agent/mails/Mail5 b/agent/mails/Mail5 deleted file mode 100644 index e82cfa9..0000000 --- a/agent/mails/Mail5 +++ /dev/null @@ -1,13 +0,0 @@ -From nobody Wed Aug 08 19:25:53 2007 -Content-Type: multipart/mixed; boundary="===============1877812021==" -MIME-Version: 1.0 -Subject: Just a test for subfolder mails -From: -To: , - -This mail is a plain simple text mail, stored in the subfolder. - -Greetings, the programmer ---===============1877812021== - ---===============1877812021==-- \ No newline at end of file diff --git a/agent/mails/Mail6 b/agent/mails/Mail6 deleted file mode 100644 index 838d18a..0000000 --- a/agent/mails/Mail6 +++ /dev/null @@ -1,13 +0,0 @@ -From nobody Wed Aug 08 19:26:37 2007 -Content-Type: multipart/mixed; boundary="===============1606767652==" -MIME-Version: 1.0 -Subject: Just a test for subfolder mails -From: -To: , - -This mail is a plain simple text mail, stored in the subfolder. - -Greetings, the programmer ---===============1606767652== - ---===============1606767652==-- \ No newline at end of file diff --git a/agent/mails/Mail7 b/agent/mails/Mail7 deleted file mode 100644 index fdb6508..0000000 --- a/agent/mails/Mail7 +++ /dev/null @@ -1,13 +0,0 @@ -From nobody Wed Aug 08 19:30:38 2007 -Content-Type: multipart/mixed; boundary="===============0772292689==" -MIME-Version: 1.0 -Subject: Just a test for subfolder mails -From: -To: , - -This mail is a plain simple text mail, stored in the subfolder. - -Greetings, the programmer ---===============0772292689== - ---===============0772292689==-- \ No newline at end of file diff --git a/agent/mails/Mail8 b/agent/mails/Mail8 deleted file mode 100644 index 9c40436..0000000 --- a/agent/mails/Mail8 +++ /dev/null @@ -1,13 +0,0 @@ -From nobody Wed Aug 08 19:31:07 2007 -Content-Type: multipart/mixed; boundary="===============0682061220==" -MIME-Version: 1.0 -Subject: Just a test for subfolder mails -From: -To: , - -This mail is a plain simple text mail, stored in the subfolder. - -Greetings, the programmer ---===============0682061220== - ---===============0682061220==-- \ No newline at end of file diff --git a/agent/mails/Mail9 b/agent/mails/Mail9 deleted file mode 100644 index d7bdfc0..0000000 --- a/agent/mails/Mail9 +++ /dev/null @@ -1,13 +0,0 @@ -From nobody Wed Aug 08 19:32:06 2007 -Content-Type: multipart/mixed; boundary="===============1096091158==" -MIME-Version: 1.0 -Subject: Just a test for subfolder mails -From: -To: , - -This mail is a plain simple text mail, stored in the subfolder. - -Greetings, the programmer ---===============1096091158== - ---===============1096091158==-- \ No newline at end of file diff --git a/agent/schedule.py b/agent/schedule.py index 19aea08..21bb948 100644 --- a/agent/schedule.py +++ b/agent/schedule.py @@ -43,7 +43,7 @@ class Scheduler(object): job.startTime = startTime job.scheduler = self self.queue[startTime] = job - reactor.callLater(startTime-int(time()), job.run, **job.params) + reactor.callLater(startTime-int(time()), job.run) def getJobsToExecute(startTime=None): return [j for j in self.queue.values() if (startTime or 0) <= j.startTime] @@ -53,21 +53,21 @@ class Job(object): implements(IScheduledJob) - def __init__(self): + def __init__(self, **params): self.startTime = 0 - self.params = {} + self.params = params self.successors = [] self.repeat = 0 - def execute(self, **kw): + def execute(self): d = Deferred() return d def reschedule(self, startTime): self.scheduler.schedule(self.copy(), startTime) - def run(self, **kw): - d = self.execute(**kw) + def run(self): + d = self.execute() d.addCallback(self.finishRun) # TODO: logging @@ -75,7 +75,7 @@ class Job(object): # run successors for job in self.successors: job.params['result'] = result - job.run(**job.params) + job.run() # remove from queue del self.scheduler.queue[self.startTime] # TODO: logging diff --git a/agent/testing/crawl.py b/agent/testing/crawl.py index f4b1bca..110f3ef 100644 --- a/agent/testing/crawl.py +++ b/agent/testing/crawl.py @@ -32,7 +32,7 @@ from loops.agent.crawl.base import CrawlingJob as BaseCrawlingJob class CrawlingJob(BaseCrawlingJob): - def collect(self, **criteria): + def collect(self): deferred = self.deferred = Deferred() # replace this with the real stuff: reactor.callLater(0, self.dataAvailable) diff --git a/agent/testing/data/file1.txt b/agent/testing/data/file1.txt new file mode 100644 index 0000000..02c267f --- /dev/null +++ b/agent/testing/data/file1.txt @@ -0,0 +1 @@ +Data from file1.txt \ No newline at end of file diff --git a/agent/testing/data/subdir/file2.txt b/agent/testing/data/subdir/file2.txt new file mode 100644 index 0000000..493d31b --- /dev/null +++ b/agent/testing/data/subdir/file2.txt @@ -0,0 +1 @@ +Data from file2.txt \ No newline at end of file diff --git a/agent/testing/transport.py b/agent/testing/transport.py index cee30ff..ae1dad4 100644 --- a/agent/testing/transport.py +++ b/agent/testing/transport.py @@ -28,45 +28,33 @@ from zope.interface import implements from loops.agent.interfaces import ITransportJob, ITransporter from loops.agent.schedule import Job +from loops.agent.transport.base import TransportJob as BaseJob +from loops.agent.transport.base import Transporter as BaseTransporter -class TransportJob(Job): +class TransportJob(BaseJob): - implements(ITransportJob) - - def __init__(self, transporter): - super(TransportJob, self).__init__() - self.transporter = transporter - - def execute(self, **kw): + def execute(self): + kw = self.params result = kw.get('result') if result is None: print 'No data available.' else: - for r in result: - d = self.transporter.transfer(r[0].data, r[1], str) + for res, meta in result: + d = self.transporter.transfer(res.data, meta) return Deferred() -class Transporter(object): - - implements(ITransporter) +class Transporter(BaseTransporter): jobFactory = TransportJob - serverURL = None - method = None - machineName = None - userName = None - password = None - - def transfer(self, resource, metadata=None, resourceType=file): - if resourceType is file: - data = resource.read() - resource.close() - elif resourceType is str: - data = resource - print 'Transferring:', data + def transfer(self, data, metadata=None): + if type(data) is file: + text = data.read() + data.close() + else: + text = data + print 'Transferring:', text return Deferred() - diff --git a/agent/tests.py b/agent/tests.py index 7feff39..296d9be 100755 --- a/agent/tests.py +++ b/agent/tests.py @@ -8,7 +8,7 @@ import unittest as standard_unittest import doctest -import time +import os, time from twisted.internet import reactor from twisted.internet.defer import Deferred from twisted.trial import unittest @@ -17,6 +17,9 @@ from loops.agent.core import Agent from loops.agent.schedule import Job +baseDir = os.path.dirname(__file__) + + class Tester(object): def iterate(self, n=10, delays={}): @@ -58,6 +61,7 @@ def test_suite(): return standard_unittest.TestSuite(( #standard_unittest.makeSuite(Test), doctest.DocFileSuite('README.txt', optionflags=flags), + doctest.DocFileSuite('crawl/filesystem.txt', optionflags=flags), )) if __name__ == '__main__': diff --git a/agent/transport/base.py b/agent/transport/base.py new file mode 100644 index 0000000..fcd86d7 --- /dev/null +++ b/agent/transport/base.py @@ -0,0 +1,59 @@ +# +# 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 +# + +""" +Transporter base classes. + +$Id$ +""" + +from twisted.internet import reactor +from twisted.internet.defer import Deferred +from zope.interface import implements + +from loops.agent.interfaces import ITransporter, ITransportJob +from loops.agent.schedule import Job + + +class TransportJob(Job): + + implements(ITransportJob) + + def __init__(self, transporter): + super(TransportJob, self).__init__() + self.transporter = transporter + + +class Transporter(object): + + implements(ITransporter) + + jobFactory = TransportJob + + def __init__(self, agent): + self.agent = agent + + def transfer(self, data, metadata=None): + if type(data) is file: + data = text.read() + data.close() + else: + text = data + return Deferred() + +