<|file_name|>read_job.py<|end_file_name|><｜fim▁begin｜># JoeTraffic - Web-Log Analysis Application utilizing the JoeAgent Framework.
# Copyright (C) 2004 Rhett Garber

# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.

# This library 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
# Lesser General Public License for more details.
# 
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

from JoeAgent import job, event

import db_interface

import os, os.path
import logging
import log_parser

LINEINCR = 30 

log = logging.getLogger("agent.LogReader")

class ReadLogCompleteEvent(event.Event):
    """Event to indicate the file is completely read. This event will
       be caught by the FindLogJob that is watching it. The file will
       continue to be checked for modifications"""
    pass

class ReadLogContinueEvent(event.Event):
    """Event to indicate we should continue reading the file. Log file
       processing will be done in chunks so as not to block the agent for
       too long."""
    pass

class ReadLogJob(job.Job):
    def __init__(self, agent_obj, logfile):
        job.Job.__init__(self, agent_obj)
        assert os.path.isfile(logfile), "Not a file: %s" % str(logfile)
        self._log_size = os.stat(logfile).st_size
        log.debug("Log size is %d" % self._log_size)

        self._logfile_path = logfile
        self._logfile_hndl = open(logfile, 'r')

        self._progress = 0  # Data read from file
        self._db = db_interface.getDB()

    def getFilePath(self):
        return self._logfile_path

    def getBytesRead(self):
        return self._progress
    def getBytesTotal(self):
        return self._log_size

    def run(self):
        <|fim_middle|>


    def notify(self, evt):
        job.Job.notify(self, evt)
        if isinstance(evt, ReadLogContinueEvent) and evt.getSource() == self:
            log.debug("Continuing read of file")
            # Continue to read the log
            try:
                self._progress += log_parser.read_log(
                                      self._logfile_hndl, self._db, LINEINCR)
                log.debug("Read %d %% of file (%d / %d)" % (self.getProgress(),
                                                            self._progress,
                                                            self._log_size))

            except log_parser.EndOfLogException, e:

                self._progress = self._log_size

                # Log file is complete, updated the db entry
                self._mark_complete()

                # Add an event to notify that the file is complete
                self._logfile_hndl.close()
                new_evt = ReadLogCompleteEvent(self)
                self.getAgent().addEvent(new_evt)
            except log_parser.InvalidLogException, e:
                log.warning("Invalid log file: %s" % str(e))
                self._logfile_hndl.close()
                new_evt = ReadLogCompleteEvent(self)
                self.getAgent().addEvent(new_evt)

            else:
                # Add an event to continue reading
                new_evt = ReadLogContinueEvent(self)
                self.getAgent().addEvent(new_evt)

    def _update_db(self):
        """Update the entry in the database for this logfile"""
        log.debug("Updating file %s" % self._logfile_path)
        pass

    def _mark_invalid(self):
        """Update the database to indicate that this is not a valid log file"""
        log.debug("Marking file %s invalid" % self._logfile_path)
        pass

    def _mark_complete(self):
        log.debug("Marking file %s complete" % self._logfile_path)
        pass

    def getProgress(self):
        """Return a percentage complete value"""
        if self._log_size == 0:
            return 0
        return int((float(self._progress) / self._log_size) * 100)
<｜fim▁end｜>
        evt = ReadLogContinueEvent(self)
        self.getAgent().addEvent(evt)