Mark Roddy avatar Mark Roddy committed 90cae9e

Implemented class PidginLog and added new class PidginLogRecord which represents a single entry in a Pidgin log file.

Comments (0)

Files changed (2)

larvotto/convsrc.py

 class PidginLog(object):
     _Open=open
 
+    _LogOwner=None
     _LogDate=None
-    _FileObj=None
+    _LogRecords=None
 
-    def __init__(self,FileObj,LogData):
-        assert isinstance(FileObj,file)
-        self._FileObj=FileObj
-        self._LogDate=LogData
+    log_date=property(lambda self: self._LogDate)
+    log_records=property(lambda self: iter(self._LogRecords))
+    
+    def __init__(self,LogRecords,LogDate):
+        self._LogRecords=LogRecords
+        self._LogDate=LogDate
 
     @classmethod
     def fromPath(cls,PathToLog):
+        """Create a PidginLog object from the path to a log file"""
+        doy=cls.pathToDate(PathToLog)
+        #owner=cls.pathToOwner(PathToLog)
+        #reciever=cls.pathToReciever(PathToLog)
         fobj=cls._Open(PathToLog,'r')
-        doy=cls.pathToDate(PathToLog)
-        return cls(fobj,doy)
+        log_obj=cls.fromFileObj(fobj,doy)
+        fobj.close()
+        return log_obj
 
+    @classmethod
+    def fromFileObj(cls,FileObj,DayOfYear):
+        FileObj.readline() #Dump top line which doesn't have a conversation record
+        records=[]
+        rcrd_lines=(l for l in FileObj.readlines() if l.strip())
+        records=map(lambda fline: PidginLogRecord.fromRawRecord(fline, DayOfYear), rcrd_lines)
+        return cls(records,DayOfYear)
+                    
     @staticmethod
     def pathToDateStr(LogPath):
         """Extract a date value from path to a pidgin log"""
         base_fname=os.path.basename(LogPath)
-        return base_fname.rsplit('.',1)[0]
+        fname,extenstion=base_fname.rsplit('.',1)
+        return fname.split('.')[0]
+
+    @staticmethod
+    def pathToOwner(LogPath):
+        dir_path=os.path.dirname(LogPath)
+        dir_path=os.path.dirname(dir_path)
+        fname=os.path.basename(dir_path)
+        return fname
+
+    @staticmethod
+    def pathToReciever(LogPath):
+        dir_path=os.path.dirname(LogPath)
+        fname=os.path.basename(dir_path)
+        return fname
+
+class PidginLogRecord(object):
+    """Container for a single entry/line in a pidgin log file"""
+    
+    _Msg=None
+    _SenderScrName=None
+    _MsgTime=None
+
+    def __init__(self,Message, SenderScrName, MsgTime):
+        self._Msg=Message
+        self._SenderScrName=SenderScrName
+        self._MsgTime=MsgTime
+
+    msg=property(lambda self: self._Msg)
+    sender=property(lambda self: self._SenderScrName)
+    msg_time=property(lambda self: self._MsgTime)
+
+    @classmethod
+    def fromRawRecord(cls,RawRecord,DayOfYearStr):
+        m=recordre.search(RawRecord.strip())
+        if not m:
+            raise Exception(RawRecord)
+        tod,isampm,scrnname,msg=m.groups()
+        if isampm:
+            dtime=datetime.strptime('%s %s'%(DayOfYearStr,tod), '%Y-%m-%d %I:%M:%S %p')	
+        else:
+            dtime=datetime.strptime('%s %s'%(DayOfYearStr,tod), '%Y-%m-%d %H:%M:%S')
+        return cls(msg,scrnname,dtime)
+
+    
         
 class PidginLogParser(object):
     """Acquires all conversations by parsing Pidgin log files"""
 
+    _LogItems=None
+
     def __init__(self,LogFiles):
         """
         LogFiles: Iterable of PidginLog objects
         """
-        pass
+        self._LogItems=LogFiles
    
     @classmethod
     def fromDirectory(cls,LogDir):

larvotto/tests/test_convsrc.py

 """Unit tests for the L{larvotto.convsrc} module"""
 
 import unittest
-import larvotto.convsrc
+import larvotto.convsrc as convsrc
 
+from StringIO import StringIO
+
+class TestPidginLog(unittest.TestCase):
+    """Test case for the larvotto.convsrc.PidginLog class"""
+
+    def testPathToDate(self):
+        """DateTime part extracted from path"""
+        log_path='~/.gaim/logs/aim/FromUser/ToUser/2008-10-23.215812-0400EDT.txt'
+        expected='2008-10-23'
+        actual=convsrc.PidginLog.pathToDateStr(log_path)
+        self.assertEquals(expected,actual)
+        
+    def testPathToOwner(self):
+        """Sending screen name extracted from file path"""
+        log_path='~/.gaim/logs/aim/FromUser/ToUser/2008-10-23.215812-0400EDT.txt'
+        expected='FromUser'
+        actual=convsrc.PidginLog.pathToOwner(log_path)
+        self.assertEquals(expected,actual)
+
+    def testPathToReciever(self):
+        """Receiving screen name extracted from file path"""
+        log_path='~/.gaim/logs/aim/FromUser/ToUser/2008-10-23.215812-0400EDT.txt'
+        expected='ToUser'
+        actual=convsrc.PidginLog.pathToReciever(log_path)
+        self.assertEquals(expected,actual)
+
+    def testFromFileObj_FirstLineIgorned(self):
+        """First line of meta-info is not processed as log record"""
+        fobj=StringIO("""Conversation with OtherUser at Thu 23 Oct 2008 09:58:12 PM EDT on SourceUser (aim)
+        (09:58:11 PM) OtherUser: so you wanna hang out tomorrow?
+        (09:58:26 PM) OtherUser: depends on how late I'm at work""")
+        log_obj=convsrc.PidginLog.fromFileObj(fobj,'2008-10-23')
+        log_records=list(log_obj.log_records)
+        self.assertEquals(2,len(log_records))
+
+    def testFromFileObj_EmptyLastLineIgnored(self):
+        """An empty last line at the end of the file not processed as log record"""
+        fobj=StringIO("""Conversation with OtherUser at Thu 23 Oct 2008 09:58:12 PM EDT on SourceUser (aim)
+        (09:58:11 PM) OtherUser: so you wanna hang out tomorrow?
+        (09:58:26 PM) OtherUser: depends on how late I'm at work
+        """) #<-- Extra new line
+        log_obj=convsrc.PidginLog.fromFileObj(fobj,'2008-10-23')
+        log_records=list(log_obj.log_records)
+        self.assertEquals(2,len(log_records))
+
+class TestPidginLogRecord(unittest.TestCase):
+    """Test case for the larvotto.convsrc.PidginLogRecord class"""
+
+    def testFromRawRecord_ValidRecord_ObjectCreated(self):
+        """PidginLogRecord object created via fromRawRecord()"""
+        valid_entry="(10:08:26 PM) sendername: okay"
+        result=convsrc.PidginLogRecord.fromRawRecord(valid_entry,'2008-10-23')
+        self.assertTrue(isinstance(result,convsrc.PidginLogRecord))
+
+    def testFromRawRecord_ValidRecord_ExpectedAttrValues(self):
+        """Attributes receive expected values from fromRawRecord()"""
+        valid_entry="(10:08:26 PM) sendername: okay"
+        result=convsrc.PidginLogRecord.fromRawRecord(valid_entry,'2008-10-23')
+        self.assertEquals('okay',result.msg)
+        self.assertEquals('sendername',result.sender)
+        #msg_time=property(lambda self: self._MsgTime)
 
 class TestPidginLogs(unittest.TestCase):
 	"""Test case for the L{larvotto.convsrc.PidginLogs} function"""
 
 	def testNonDirectoryPath(self):
 		if __debug__:
-			self.assertRaises(AssertionError, larvotto.convsrc.PidginLogs, '')
+			self.assertRaises(AssertionError, convsrc.PidginLogs, '')
 
 	def testSingleDigitHour(self):
 		record='(1:12:16 PM) MyScreenName: test'
 		d='2008-07-05'
-		larvotto.convsrc._ParsePidginRecord(record,d)
+		convsrc._ParsePidginRecord(record,d)
 
 	def testNoAMPM(self):
 		record='(22:20:45) MyScreeName: those are some tasty burgers'
 		d='2008-07-05'
-		larvotto.convsrc._ParsePidginRecord(record,d)
+		convsrc._ParsePidginRecord(record,d)
 
 	def testSignOffSystemMessage(self):
 		msg='(1:42:07 PM) AIMsweringMachin has signed off.'
-		self.assert_(larvotto.convsrc._IsSystemMessage(msg))
+		self.assert_(convsrc._IsSystemMessage(msg))
 
 	def testLoggedOffSystemMessage(self):
 		msg='(04:34:28) Ahs123 logged out.'
-		self.assert_(larvotto.convsrc._IsSystemMessage(msg))
+		self.assert_(convsrc._IsSystemMessage(msg))
 
 	def testSignOffSystemMessageWithWhiteSapce(self):
 		msg='(1:42:07 PM) AIMsweringMachin has signed off.   '
-		self.assert_(larvotto.convsrc._IsSystemMessage(msg))
+		self.assert_(convsrc._IsSystemMessage(msg))
 
 	def testLoggedInSystemMessage(self):
 		msg='(00:51:44) Ahs123 logged in.'
-		self.assert_(larvotto.convsrc._IsSystemMessage(msg))
+		self.assert_(convsrc._IsSystemMessage(msg))
 
 if __name__=='__main__':
 	unittest.main()
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.