work in progress: filesystem crawler

git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@1891 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
helmutm 2007-08-09 14:30:14 +00:00
parent 874d96c94b
commit 913054b697
29 changed files with 182 additions and 642 deletions

View file

@ -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'

View file

@ -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

View file

@ -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))

View file

@ -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)

View file

@ -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')

View file

@ -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

View file

@ -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.

View file

@ -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:
<http://outlook/outlook9/specs/welcomemsg/icons.gif>
<http://outlook/outlook9/specs/welcomemsg/yellowbg.gif>
<http://outlook/outlook9/specs/welcomemsg/olicon.GIF>
Willkommen bei
Microsoft Outlook 2000
Das Fenster zu Ihrer Informationswelt
  Microsoft(R) Outlook(R) 2000  <http://www.microsoft.com/germany/office/outlook>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 <http://officeupdate.microsoft.com/office/redirect/fromOffice9/OutlookWelcome.htm?HelpLCID=1031>. 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 <http://www.microsoft.com/windows/ie_intl/de/> Microsoft Office <http://www.microsoft.com/germany/office/> Microsoft Exchange Server <http://www.microsoft.com/germany/backoffice/exchange/> Microsoft NetMeeting <http://www.microsoft.com/windows/ie_intl/de/netmeeting/> Microsoft Windows Media Technologies <http://www.microsoft.com/windows/windowsmedia>
--===============1611091771==
--===============1611091771==--

View file

@ -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:
<http://outlook/outlook9/specs/welcomemsg/icons.gif>
<http://outlook/outlook9/specs/welcomemsg/yellowbg.gif>
<http://outlook/outlook9/specs/welcomemsg/olicon.GIF>
Willkommen bei
Microsoft Outlook 2000
Das Fenster zu Ihrer Informationswelt
  Microsoft(R) Outlook(R) 2000  <http://www.microsoft.com/germany/office/outlook>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 <http://officeupdate.microsoft.com/office/redirect/fromOffice9/OutlookWelcome.htm?HelpLCID=1031>. 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 <http://www.microsoft.com/windows/ie_intl/de/> Microsoft Office <http://www.microsoft.com/germany/office/> Microsoft Exchange Server <http://www.microsoft.com/germany/backoffice/exchange/> Microsoft NetMeeting <http://www.microsoft.com/windows/ie_intl/de/netmeeting/> Microsoft Windows Media Technologies <http://www.microsoft.com/windows/windowsmedia>
--===============1084757079==
--===============1084757079==--

View file

@ -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==--

View file

@ -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==--

View file

@ -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==--

View file

@ -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==--

View file

@ -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==--

View file

@ -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==--

View file

@ -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==--

View file

@ -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==--

View file

@ -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==--

View file

@ -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==--

View file

@ -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==--

View file

@ -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==--

View file

@ -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==--

View file

@ -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

View file

@ -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)

View file

@ -0,0 +1 @@
Data from file1.txt

View file

@ -0,0 +1 @@
Data from file2.txt

View file

@ -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()

View file

@ -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__':

59
agent/transport/base.py Normal file
View file

@ -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()