#------------------------------------------------------
# AgentHome.py
# source file for agent UI
# author: Juergen Menzinger
# version: 0.1
#------------------------------------------------------

"""

$Id$
"""

import sys
import os
import tempfile
import cPickle
import traceback
import time
import email
try:
    import _winreg as winreg
    USE_WINDOWS = True
except ImportError:
    USE_WINDOWS = False

from nevow import loaders, rend, static, url, inevow, tags
from nevow.inevow import IRequest
from twisted.internet import defer

from loops.agent import core
if USE_WINDOWS:
    from loops.agent.crawl import outlook
    from loops.agent.crawl.outlook import OutlookResource
from loops.agent.crawl.filesystem import FileResource

# ---- global definitions and settings ---------------------------------
os.environ['HOME'] = os.path.dirname(core.__file__)
OUTLOOK2000 = 1
PICKLE_MAILS = 0
DEBUG = 1
resourcesDirectory = 'resources'
templatesDirectory = 'templates'

# some constatnts
_REG_KEY_CONST_ = "SOFTWARE\\Classes\\mailto\\shell\\open\\command"
_OUTLOOK_2007_ = "Office12"
_OUTLOOK_2003_ = "Office11"
_OUTLOOK_2000_ = "Office10"
_OUTLOOK_EXPRESS_ = "Office10"
#----------------------------------------------------------


def template(fn):
    return loaders.xmlfile(os.path.join(
                os.path.dirname(__file__), templatesDirectory, fn))


def getConfigIndex(agentobj, index_name, default_value, fn=None):
    """get the number of jobs currently in config file"""
    index = len(agentobj.config.crawl)
    return index


def getOutlookVersion():
    """
    checks what outlook version we have to handle

    Returns the standard email application on this machine.

    Therefor we have to read out the registry key
         "HKEY_LOCAL_MACHINE\SOFTWARE\Classes\mailto\shell\open\command"

    --ATTENTION--:
        This was tested with Outlook 2007 only.
        Therefor it is possible that there are problems
        with some constants defined on the beginning.

        TODO: -> check this function with some other
                 Outlook versions installed and modify,
                 if needed the defined constants and return
                 values of the getOutlookVersion function

    """
    # open registry key
    try:
        key = winreg.OpenKey(
                    winreg.HKEY_LOCAL_MACHINE,
                    _REG_KEY_CONST_ )

    except WindowsError:
        return None

    try:
        try:
            # read out current standard outlook version
            version = winreg.QueryValueEx(key, "")[0]
            # check what outlook we have
            if version:
                if _OUTLOOK_2007_ in version:
                    version = _OUTLOOK_2007_

                elif _OUTLOOK_2003_ in version:
                    version = _OUTLOOK_2003_

                elif _OUTLOOK_EXPRESS_ in version:
                    version = _OUTLOOK_EXPRESS_

        except WindowsError:
            version = ""
    finally:
        # close key
        winreg.CloseKey(key)

    #print '--> getOutlookVersion(): Outlook version found, version is: ', version
    # return key value
    return version


# AgentHome
# root page of the Agent UI

class AgentHome(rend.Page):

    """Main class that builds the root ressource for the loops agent ui.

    Instance variables:
    usermode -- can be 'Simple' or 'Advanced'
    agent -- agent object where config and tempdir attributes can be accessed

    Class methods:
    At the moment all methods of this class except the __init__ although
    public, are intended to be called directly or stand-alone.

    __init__ -- Load the initial start-up settings from config

    """

    child_resources = static.File(os.path.join(
                        os.path.dirname(__file__),resourcesDirectory))
    docFactory = template('agent.html')

    def __init__(self, agent=None, first_start=1):
        """ Initialize the AgentHome object.

        If first_start = 1 then the initalization procedure is run, which
        mainly loads the stored settings from the agent ini-file into instance
        variables of the class.

        Keyword arguments:
        first_start -- defaults to 1

        """
        print "[PAGECLASS] AgentHome"
        if first_start == 1:
            self.agent = core.Agent()
            self.usermode = self.agent.config.ui.web.setdefault('usermode', 'Simple')
            print "[AgentHome] setting self.usermode: ", self.agent.config.ui.web.usermode
        else:
            self.agent = agent

    """
    def locateChild(self, ctx, segments):
        return self, ()
    """

    # calls to child pages

    def child_joboverview(self, context):
        """ User requested page from menue: 'job overview' """
        return JobOverView(self.agent)

    def child_collectOutlookMails(self, context):
        """Display page for starting Outlook Crawler"""
        return AgentOutlookMailCrawl(self.agent)

    def child_collectFilesystem(self, context):
        """Display page for starting Filesystem Crawler"""
        return AgentFilesystemCrawl(self.agent)

    def child_viewRessources(self, context):
        """Display page that shows all currently collected Outlook Mails."""
        return RessourceView(self.agent)

    # "Startpage" methods (class AgentHome)

    def child_changeUserMode(self, context):
        """Change user mode.

        User has klicked the Change User Mode button, so
        change UserMode from Simple <-> Professional

        """
        if DEBUG:
            print "[child_changeUserMode] UserMode: ", self.agent.config.ui.web.usermode
        form = IRequest(context).args
        if form != {}:
            for elem in form:
                print "[child_changeUserMode] ", form[elem]
        if self.agent.config.ui.web.usermode == "Simple":
            self.agent.config.ui.web.usermode = "Advanced"
        else:
            self.agent.config.ui.web.usermode = "Simple"
        self.agent.config.save()
        if DEBUG:
            print "====> changed UserMode: ", self.agent.config.ui.web.usermode
        return AgentHome(self.agent, first_start=0)

    # "job overview" methods (class JobOverView)

    def child_ViewJobDetails(self, context):
        """Get details for the selected job.

        Reads all information about the selected job from file/ database.
        Returns page object which displays the available information.

        """
        selected_job = ((IRequest(context).uri).split("?"))[1]
        crawl_index = selected_job.split(".")[1]

        return JobOverViewDetails(self.agent, crawl_index)

    # "add outlook crawl job" methods (class AgentOutlookMailCrawl)

    def child_submitOutlookCrawlJob(self,context):
        """Initiate Outlook crawling job as requested by user."""
        ag = self.agent
        conf = ag.config
        crawlSubfolder = False
        form = IRequest(context).args
        if form != {}:
            index = getConfigIndex(self.agent, 'type', 'unused')
            #save job configuration
            if form['mailCrawlInterval'][0] == "oneTime":
                conf.crawl[index].state = 'completed'
            else:
                conf.crawl[index].state = 'active'
            conf.crawl[index].jobid = 'outlook.%i' %(index)
            conf.crawl[index].type = 'OutlookMail'
            if form.has_key('inbox'):
                conf.crawl[index].getinbox = '%s'%(str(form["inbox"][0]))
            else:
                conf.crawl[index].getinbox = 'False'
            if form.has_key('subfolders'):
                 conf.crawl[index].getsubfolder = '%s'%(str(form["subfolders"][0]))
            else:
                conf.crawl[index].getsubfolder = 'False'
            conf.crawl[index].subfolderpat = '%s'%(str(form["pattern"][0]))
            conf.crawl[index].latest = '%i'%(index)
            #TODO: how to find out what the most actual element is?
            conf.crawl[index].filter_criteria = '%s'%(form["selectFilterCriteria"][0])
            conf.crawl[index].filter_pattern =  '%s'%(form["filterPattern"][0])
            conf.crawl[index].content_format =  '%s'%(form["selectContentFormat"][0])
            conf.crawl[index].include_attachements = '%s'%(form["selectAttachements"][0])
            conf.crawl[index].interval = '%s'%(form["mailCrawlInterval"][0])
            conf.save()
            if form["mailCrawlInterval"][0] == 'oneTime':
                # get version of standard mail client
                outlookVersion = getOutlookVersion()
                # set properties depend on version
                if outlookVersion == _OUTLOOK_2000_:
                    fieldsMail = ['Body',
                                  'HTMLBody',
                                  'CC',
                                  'SenderName',
                                  'Recipients',
                                  'To',
                                  'Attachments',
                                  'Subject'
                                 ]
                elif outlookVersion == _OUTLOOK_2007_:
                    fieldsMail = ['Body',
                                  'BodyFormat',
                                  'HTMLBody',
                                  'CC',
                                  'SenderEmailAddress',
                                  'Recipients',
                                  'To',
                                  'Attachments',
                                  'Subject',
                                  'ReceivedTime'
                                 ]

                # all form fileds in the html template are named according to
                # the dictionary name if expected to be in params,
                # this way it is not necessary to alter the code if another
                # parameter is added
                params = {}
                for elem in form.items():
                    params[elem[0]] = elem[1][0]
                outlook_job = outlook.CrawlingJob()
                outlook_job.params = params
                deferred = outlook_job.collect()
                deferred.addCallback(self.defMailCrawl, index, params, context)
                deferred.addErrback(self.defMailCrawlError,context)
                return deferred
            else:
                #TODO implement forwarding to next form (scheduler)
                return AgentOutlookMailCrawl(self.agent, "Scheduled Mail Crawling not implemented yet.")

        else:
            return AgentOutlookMailCrawl(self.agent, "An error occurred: form data has been empty.")
        return AgentOutlookMailCrawl(self.agent, "Crawl Job settings have been saved.")

    def defMailCrawl(self, mail_collection, index, params, context):
        """Save and Forward the mail collection to a page view."""
        if DEBUG:
            print "====> seting and saving mails to disk"
            print "====> agent base dir: ",self.agent.tempdir
        tmpdir =  tempfile.mkdtemp(prefix='mailJob_%i_'%(index), dir=self.agent.tempdir)
        if DEBUG:
            print "====> outlook job dir: ", tmpdir
        files = os.listdir(tmpdir)
        filenum = len(files)
        for elem in mail_collection:
            tmpfile = tempfile.mkstemp(prefix='%i_mail_'%(filenum), dir=tmpdir)
            if PICKLE_MAILS == 0:
                # write data as MIME string into a text file
                os.write(tmpfile[0], elem.data.as_string())
            else:
                # alternatively also writing the list as a whole might be
                # more performant (less disc I/O) but how to store the
                # path so that the user can have a look at the mail view
                # page and the page knows in which directory to look?
                # Idea could be a object that stores all current paths and
                # their crawlIDs
                os.write(tmpfile[0], cPickle.dumps(elem))
            os.close(tmpfile[0])
            filenum = filenum + 1
        return RessourceView(self.agent, mail_collection, "The collected mails have been saved in %s"%(tmpdir), tmpdir)

    def defMailCrawlError(self, ErrorMessage, context):
        """Handles errors that ocurred in the MailCrawler."""
        #TODO: handle whole exception information
        return traceback.format_exc()

    # "view collected ressources" methods (class RessourceViewView)

    def child_viewRessourceDetails(self,context):
        """Get details for the selected ressource object.

        Reads all information about the selected ressource from file/ or the
        mail_collection list.
        Returns page object which displays the available information.

        """
        selected_item = ((IRequest(context).uri).split("?"))[1]
        form = IRequest(context).args
        if form != {}:
            requested_file=""
            if DEBUG:
                print "[child_viewRessourceDetails]"
                print "====> selected item: ", selected_item
                print "====> printing items in directory"
            fileslist = os.listdir(form['ressourceObjData'][0])
            for elem in fileslist:
                if DEBUG:
                    print elem
                if elem.startswith(("%i_mail_"%(int(selected_item))), 0):
                    requested_file = elem
            requested_file = os.path.join(form['ressourceObjData'][0], requested_file)
            if requested_file.find("mail") > 0:
                fp = open(requested_file, "rb")
                mail_parser = email.Parser.Parser()
                mailobj = OutlookResource(mail_parser.parse(fp))
                fp.close()
                mail = []
                for elem in mailobj.data.items():
                    if DEBUG:
                        print "====> building MIMEObject"
                        print "====> appending attribute: ", elem
                    mail.append(elem)
                if hasattr(mailobj.data, 'preamble'):
                    if DEBUG:
                        print "====> copying preamble contents"
                    mail.append(['Preamble', mailobj.data.preamble])
                else:
                    mail.append(['Preamble',''])
                if hasattr(mailobj.data,'epilogue'):
                    if DEBUG:
                        print "====> copying epilogue contents"
                    mail.append(['Epilogue', mailobj.data.epilogue])
                else:
                    mail.append(['Epilogue', ''])
                return OutlookMailDetail(agent=self.agent, pagemessage="", mail=mail, filename=requested_file)
            elif requested_file.find("file") > 0:
                #TODO implement file analyzing
                return FileObjectDetail(agent=self.agent, pagemessage="", fileobj=fileobj, filename=requested_file)
        if os.path.isdir(selected_item):
            # selected item is a folder -> change to that folder
            if DEBUG:
                print "====> selected item is a directory! changing into directory"
            return RessourceView(self.agent, ressource_collection=[], pagemessage="changed to folder %s" %(selected_item), tmpdir=selected_item)
        elif os.path.isfile(selected_item):
            if selected_item.find("mail") > 0:
                fp = open(selected_item, "rb")
                mail_parser = email.Parser.Parser()
                mailobj = OutlookResource(mail_parser.parse(fp))
                fp.close()
                mail = []
                for elem in mailobj.data.items():
                    mail.append(elem)
                if hasattr(mailobj.data,'preamble'):
                    mail.append(['Preamble', mailobj.data.preamble])
                else:
                    mail.append(['Preamble',''])
                if hasattr(mailobj.data,'epilogue'):
                    mail.append(['Epilogue',mailobj.data.epilogue])
                else:
                    mail.append(['Epilogue',''])
                requested_file = selected_item
                return OutlookMailDetail(agent=self.agent, pagemessage="", mail=mail, filename=requested_file)
            elif selected_item.find("file") > 0:
                #TODO implement file analyzing
                return FileObjectDetail(agent=self.agent, pagemessage="", fileobj=fileobj, filename=requested_file)

    # rendering methods of Startpage

    def render_getActiveUserMode(self, context, data):
        return self.agent.config.ui.web.usermode

    def render_getAgentVersion(self, context, data):
        return "0.1 alpha"

    def render_footer_fragment(self, context, data):
        return context.tag[FooterFragment(data)]

    def render_navigation_fragment(self, context, data):
        return context.tag[NavigationFragment(data)]

    def render_top_fragment(self, context, data):
        return context.tag[TopFragment(data)]

    def render_header_fragment(self, context, data):
        return context.tag[HeaderFragment(data)]


class FooterFragment(rend.Fragment):
    docFactory = template('footer.html')


class NavigationFragment(rend.Fragment):
    docFactory = template('navigation.html')


class TopFragment(rend.Fragment):
    docFactory = template('top.html')


class HeaderFragment(rend.Fragment):
    docFactory = template('header.html')


# subpages of AgentHome

class JobOverView(rend.Page):

    """Builds page that lists all currently registered jobs.

    Instance variables:
    agent -- agent object where config and tempdir attributes can be accessed

    Class methods:
    At the moment all methods of this class except the __init__
    although public, are intended to be called directly or stand-alone.

    __init__ -- Store the initial settings retrieved from AgentHome.

    """

    docFactory = template('joblisting.html')

    def __init__(self, agent=None):
        print "[PAGECLASS] JobOverView"
        self.agent = agent

    # rendering methods of job overview

    def data_displayViewForm(self, context, data):
        return "Overview of all running Crawling jobs"

    def render_getActiveUserMode(self, context, data):
        return self.agent.config.ui.web.usermode

    def render_fillJobTable(self, ctx, data):
        """Build table which displays all registered jobs."""

        #---- get the registered jobs from the jobfile ----
        joblist = []
        index = 0
        self.agent.config.load()
        while index < len(self.agent.config.crawl):
            joblist.append(dict(self.agent.config.crawl[index].items()))
            index = index + 1
        job_table = []
        for job_details in joblist:
            if job_details['jobid'].split(".")[0] == "outlook":
                job_table.append(tags.tr
                                  [
                                   tags.td
                                    [
                                     tags.a(href="ViewJobDetails?%s" %(job_details['jobid']))
                                       [
                                         tags.b
                                             [
                                                 "[" + job_details['jobid'] +"]"
                                             ]
                                       ]
                                    ],
                                    tags.td[job_details['state']],
                                    tags.td[job_details['interval']],
                                    tags.td[job_details['filter_criteria']],
                                    tags.td["Inbox: %s, Subfolders: %s" %(job_details['getinbox'], job_details['getsubfolder'])]
                                  ]
                                 )
            elif job_details['jobid'].split(".")[0] == "filesystem":
                    job_table.append(tags.tr
                                  [
                                   tags.td
                                    [
                                     tags.a(href="ViewJobDetails?%s" %(job_details['jobid']))
                                       [
                                         tags.b
                                             [
                                                "[" + job_details['jobid'] +"]"
                                             ]
                                       ]
                                    ],
                                    tags.td[job_details['state']],
                                    tags.td[job_details['interval']],
                                    tags.td[job_details['filter_criteria']],
                                    tags.td["directories"]
                                  ]
                                 )

        return job_table

    def render_footer_fragment(self, context, data):
        return context.tag[FooterFragment(data)]

    def render_navigation_fragment(self, context, data):
        return context.tag[NavigationFragment(data)]

    def render_top_fragment(self, context, data):
        return context.tag[TopFragment(data)]

    def render_header_fragment(self, context, data):
        return context.tag[HeaderFragment(data)]


class JobOverViewDetails(rend.Page):

    """Builds page that displays detailed information about a selected job.

    Instance variables:
    jobdetails -- list that contains all available job information
    agent -- agent object where config and tempdir attributes can be accessed

    Class methods:
    At the moment all methods of this class except the __init__ although public,
    are intended to be called directly or stand-alone.

    __init__ -- Store the selected job in member variable.

    """

    docFactory = template('jobdetail.html')

    def __init__(self, agent=None, selected_jobindex=None):
        print "[PAGECLASS] JobOverViewDetails"
        self.selected_index = selected_jobindex
        self.agent = agent

    # rendering methods of job view details

    def data_displayViewForm(self, context, data):
        return "Detailed view of crawling job."

    def render_getActiveUserMode(self, context, data):
        return self.agent.config.ui.web.usermode

    def render_displayJobDetails(self, ctx, data):
        """Build the table containing information about the selected job."""

        print "*******************************************************"
        print "[render_displayJobDetails] received form: ", str(self.selected_index)
        print "[render_displayJobDetails] usermode: ", self.agent.config.ui.web.usermode
        print "*******************************************************"

        if self.selected_index != None:
            job_detailtable = [tags.tr
                                   [
                                     tags.td[tags.b[parameter[0]]],
                                     tags.td[parameter[1]]
                                    ]
                               for parameter in list(self.agent.config.crawl[int(self.selected_index)].items())
                              ]
        return job_detailtable

    def render_footer_fragment(self, context, data):
        return context.tag[FooterFragment(data)]

    def render_navigation_fragment(self, context, data):
        return context.tag[NavigationFragment(data)]

    def render_top_fragment(self, context, data):
        return context.tag[TopFragment(data)]

    def render_header_fragment(self, context, data):
        return context.tag[HeaderFragment(data)]


class RessourceView(rend.Page):

    """Builds page that displays an overview of all collected mails.

    Instance variables:
    page_message -- string that is displayed on the page
    ressource_collection -- collection containing all currently collected ressources.
    temp_dir -- actual directory whose ressources have to be displayed
    agent -- the agent object which holds the config data and temp directory

    Class methods:
    At the moment all methods of this class except the __init__ although public,
    are intended to be called directly or stand-alone.

    __init__ -- Store the mail collection object and the pagemessage

    """

    mail_collection = None
    docFactory = template('ressourceview.html')

    def __init__(self, agent=None, ressource_collection=[], pagemessage="", tmpdir=""):
        print "[PAGECLASS] RessourceView"
        self.ressource_collection = ressource_collection
        self.page_message = pagemessage
        self.temp_dir = tmpdir
        self.agent = agent

    # rendering methods of view collected ressources

    def data_displayViewForm(self, context, data):
        return "View of all collected ressources."

    def render_getActiveUserMode(self, context, data):
        return self.agent.config.ui.web.usermode

    def render_systemMessage(self, context, data):
        """Displays messages from the system to the user."""
        message = tags.b[self.page_message]
        return message

    def render_displayRessourceHeaders(self, context, data):
        """Displays the column headings according to the ressource type"""
        #TODO: switch between different objecttypes
        if DEBUG:
            print "====> creating html columns for Ressource table"
        current_dir=""
        if self.temp_dir == "":
            current_dir = self.agent.tempdir
        else:
            current_dir = self.temp_dir
        if self.ressource_collection == []:
            files_found = 0
            for elem in os.listdir(current_dir):
                if os.path.isfile(os.path.join(current_dir,elem)):
                    files_found = 1
                    break
            if files_found == 0:
                if current_dir.find("mail"):
                    if DEBUG:
                        print "====> just mail subdirs in current directory"
                    return [tags.tr
                              [
                                tags.th["Directory Name"],
                                tags.th["Created"],
                                tags.th["Modified"],
                                tags.th["Mails inside"],
                               ]
                             ]
                elif current_dir.find("file"):
                    if DEBUG:
                        print "====> just file subdirs in current directory"
                    return [tags.tr
                              [
                                tags.th["Directory Name"],
                                tags.th["Created"],
                                tags.th["Modified"],
                                tags.th["Files inside"],
                               ]
                             ]
            if files_found >= 1:
                if current_dir.find("mail"):
                    if DEBUG:
                        print "====> current directory has mails"
                    return [tags.tr
                               [
                                   tags.th["From"],
                                   tags.th["CC"],
                                   tags.th["Subject"],
                                   tags.th["Recipient"],
                                   tags.th["Date"]
                                 ]
                              ]
                elif current_dir.find("file"):
                    if DEBUG:
                        print "====> current directory has files"
                    return [tags.tr
                               [
                                tags.th["Filename"],
                                tags.th["Filesize"],
                                tags.th["Date created"],
                                tags.th["Date modified"],
                                tags.th["Filetype"]
                              ]
                            ]
        elif isinstance(self.ressource_collection[0], FileResource):
            if DEBUG:
                print "====> instance is a FileResource"
            return [tags.tr
                   [
                       tags.th["Filename"],
                       tags.th["Filesize"],
                       tags.th["Date created"],
                       tags.th["Date modified"],
                       tags.th["Filetype"]
                     ]
                  ]
        elif isinstance(self.ressource_collection[0], OutlookResource):
            if DEBUG:
                print "====> instance is a OutlookResource"
            return [tags.tr
                   [
                       tags.th["From"],
                       tags.th["CC"],
                       tags.th["Subject"],
                       tags.th["Recipient"],
                       tags.th["Date"]
                     ]
                  ]
        # raise exception here?
        return "could not find a matching object type"

    def render_displayRessources(self, ctx, data):
        """Builds table containing all currently collected ressources."""
        if self.ressource_collection != []:
            if DEBUG:
                print "====> building ressource with ressource_collection"
            index = 0
            ressource_table = []
            if isinstance(self.ressource_collection[0],OutlookResource):
                for ressourceObject in self.ressource_collection:
                    ressource_table.append(tags.form(name="ressourceEntry%i"%(index), action="viewRessourceDetails?%i"%(index), method="POST")[
                                       tags.input(name="ressourceObjData", type="hidden", value="%s"%(self.temp_dir)),
                                       tags.tr[
                                       tags.td[
                                           tags.a(href="javascript:document.getElementsByName('ressourceEntry%i')[0].submit()"%(index))[
                                               tags.b[
                                                   "[" + str(ressourceObject.data.get('From')) +"]" #SenderName
                                                   ]
                                               ]
                                           ],
                                       tags.td[
                                           str(ressourceObject.data.get('CC'))
                                           ],
                                       tags.td[
                                           str(ressourceObject.data.get('Subject'))
                                           ],
                                       tags.td[
                                           #TODO: proper handling of unicode characters
                                           ressourceObject.data.get('To').encode('utf-8')
                                           ],
                                       tags.td['SourceFolder']]])
                    index = index + 1
                return ressource_table

            if isinstance(self.ressource_collection[0],FileResource):
                #TODO: implement building the table for file objects
                return ressource_table

        else:
            if DEBUG:
                print "====> building ressource by analyzing submitted dir"
            if self.temp_dir == "":
                current_dir = self.agent.tempdir
            else:
                current_dir = self.temp_dir
            ressource_files= os.listdir(current_dir)
            ressource_table = []
            #check whether there are directories, files or both in the actual directory
            for elem in ressource_files:
                element = os.path.join(current_dir,elem)
                if os.path.isdir(element):
                    files_in_subdir = len(os.listdir(element))
                    ressource_table.append(tags.tr
                                            [
                                             tags.td
                                              [
                                               tags.a(href="viewRessourceDetails?%s" %(element))
                                                  [
                                                   tags.b
                                                     [
                                                       "[" + str(elem) +"]"
                                                     ]
                                                   ]
                                                  ],
                                                  tags.td[time.asctime(time.localtime(os.path.getctime(element)))],
                                                  tags.td[time.asctime(time.localtime(os.path.getmtime(element)))],
                                                  tags.td[files_in_subdir]
                                                 ]
                                           )

                elif os.path.isfile(element):
                    if elem.find("file") > 0:
                        if DEBUG:
                            print "====> %s is of type crawl file" %(elem)
                        ressource_table.append(tags.tr
                                                [
                                                 tags.td
                                                  [
                                                   tags.a(href="viewRessourceDetails?%s" %(element))
                                                      [
                                                       tags.b
                                                         [
                                                           "[" + str(elem) +"]"
                                                         ]
                                                       ]
                                                      ],
                                                      tags.td[os.path.getsize(element)],
                                                      tags.td[time.asctime(time.localtime(os.path.getctime(element)))],
                                                      tags.td[time.asctime(time.localtime(os.path.getmtime(element)))],
                                                      tags.td[str(elem.split(".")[-1])]
                                                ]
                                            )
                    elif elem.find("mail") > 0:
                        if DEBUG:
                            print "====> %s is of type mail" %(elem)
                        fp = open(element,"rb")
                        mail_parser = email.Parser.Parser()
                        mail = OutlookResource(mail_parser.parse(fp))
                        fp.close()
                        mail_from = mail.data.get('From', "not available")
                        mail_cc = mail.data.get('CC', "not available")
                        mail_subject = mail.data.get('Subject', "not available")
                        mail_recipient = mail.data.get('TO', "not available")
                        mail_date = mail.data.get('SENT', "not available")
                        ressource_table.append(tags.tr
                                                    [
                                                     tags.td
                                                      [
                                                       tags.a(href="viewRessourceDetails?%s" %(element))
                                                          [
                                                           tags.b
                                                             [
                                                               "[" + mail_from +"]"
                                                             ]
                                                           ]
                                                          ],
                                                          tags.td[mail_cc],
                                                          tags.td[mail_subject],
                                                          tags.td[mail_recipient],
                                                          tags.td[mail_date]
                                                    ]
                                                )
            return ressource_table

    def render_footer_fragment(self, context, data):
        return context.tag[FooterFragment(data)]

    def render_navigation_fragment(self, context, data):
        return context.tag[NavigationFragment(data)]

    def render_top_fragment(self, context, data):
        return context.tag[TopFragment(data)]

    def render_header_fragment(self, context, data):
        return context.tag[HeaderFragment(data)]


class AgentOutlookMailCrawl(rend.Page):

    """Builds page where an Outlook Mail Crawler can be configured and run.

    Instance variables:
    page_message -- string that is displayed on the page

    Class methods:
    At the moment all methods of this class except the __init__ although public,
    are intended to be called directly or stand-alone.

    __init__ -- store pagemessage in member variable

    """

    docFactory = template('mailcrawl.html')

    def __init__(self, agent=None, pagemessage=""):
        print "[PAGECLASS] AgentOutlookMailCrawl"
        self.page_message = pagemessage
        self.agent  = agent

    # rendering methods of add outlook crawl job

    def data_displayViewForm(self, context, data):
        return "Configure your MailCrawl Job in the form below.\
                 You then can either choose to start it as a\
                 single job, or as scheduled job (further input\
                 for scheduler necessary). For each new collect\
                 procedure a filter will be added, so that just\
                 mails received in Outlook after the recent Crawl\
                 Job has been run, will be collected."

    def render_getActiveUserMode(self, context, data):
        return self.agent.config.ui.web.usermode

    def render_displayOutlookMails(self, ctx, data):
        """Currently no implementation"""
        return ""

    def render_systemMessage(self, context, data):
        """Displays messages from the system to the user."""
        message = tags.b[self.page_message]
        return message

    def render_footer_fragment(self, context, data):
        return context.tag[FooterFragment(data)]

    def render_navigation_fragment(self, context, data):
        return context.tag[NavigationFragment(data)]

    def render_top_fragment(self, context, data):
        return context.tag[TopFragment(data)]

    def render_header_fragment(self, context, data):
        return context.tag[HeaderFragment(data)]


class AgentFilesystemCrawl(rend.Page):

    """Builds page where an Filesystem Crawler can be configured and run.

    Instance variables:
    page_message -- string that is displayed on the page

    Class methods:
    At the moment all methods of this class except the __init__ although public,
    are intended to be called directly or stand-alone.

    __init__ -- store pagemessage in member variable

    """

    docFactory = template('filecrawl.html')

    def __init__(self, agent=None, pagemessage=""):
        print "[PAGECLASS] AgentFilesystemCrawl"
        self.page_message = pagemessage
        self.agent  = agent

    # rendering methods of ad filesystem crawl job

    def data_displayViewForm(self, context, data):
        return "Configure your FileCrawl Job in the form below.\
                 You then can either choose to start it as a\
                 single job, or as scheduled job (further input\
                 for scheduler necessary). For each new collect\
                 procedure a filter will be applied, so that just\
                 new objects will be collected."

    def render_getActiveUserMode(self, context, data):
        return self.agent.config.ui.web.usermode

    def render_displayFiles(self, ctx, data):
        """Currently no implementation"""
        return ""

    def render_systemMessage(self, context, data):
        """Displays messages from the system to the user."""
        message = tags.b[self.page_message]
        return message

    def render_footer_fragment(self, context, data):
        return context.tag[FooterFragment(data)]

    def render_navigation_fragment(self, context, data):
        return context.tag[NavigationFragment(data)]

    def render_top_fragment(self, context, data):
        return context.tag[TopFragment(data)]

    def render_header_fragment(self, context, data):
        return context.tag[HeaderFragment(data)]


class OutlookMailDetail(rend.Page):

    """Builds page that displays the selected mail in detail.

    Instance variables:
    page_message -- string that is displayed on the page
    mail_elements -- received mailobject as a list.
    agent -- agent object that holds the config data
    mail_file -- filename of the selected mail to view

    Class methods:
    At the moment all methods of this class except the __init__ although public,
    are intended to be called directly or stand-alone.

    __init__ -- Store the mail collection object and the pagemessage

    """

    docFactory = template('mail_detailed.html')

    def __init__(self, agent=None, pagemessage="", mail=[], filename=""):
        print "[PAGECLASS] OutlookMailDetail"
        self.mail_elements = mail
        self.page_message = pagemessage
        self.agent = agent
        self.mail_file = filename

    # rendering methods of Collect Outlook Mails

    def data_displayViewForm(self, context, data):
        return (tags.b["Filename of the selected mail: "], tags.i[self.mail_file])

    def render_getActiveUserMode(self, context, data):
        return self.agent.config.ui.web.usermode

    def render_systemMessage(self, context, data):
        """Displays messages from the system to the user."""
        message = tags.b[self.page_message]
        return message

    def render_displayOutlookMail(self, ctx, data):
        """Builds the layout for the mail."""

        if self.mail_elements != []:
            mail_view = []
            for elem in self.mail_elements:
                mail_view.append(tags.tr[
                                  tags.td[elem[0]],
                                  tags.td[elem[1]]
                                 ]
                                )
            return mail_view

    def render_footer_fragment(self, context, data):
        return context.tag[FooterFragment(data)]

    def render_navigation_fragment(self, context, data):
        return context.tag[NavigationFragment(data)]

    def render_top_fragment(self, context, data):
        return context.tag[TopFragment(data)]

    def render_header_fragment(self, context, data):
        return context.tag[HeaderFragment(data)]

