ppf/new: Add util.py.
[cs-p2p-next.git] / ppf / new / util.py
1 """
2 Utility classes.
3
4 2011, Razvan Deaconescu, razvan.deaconescu@cs.pub.ro
5 """
6
7 class LiveLogStatus(object):
8     """
9     Status information regarding live log processing. Stored in the
10     '.lstatus' file.
11     """
12
13     def __init__(self, position=0):
14         self.position = 0
15
16
17 class LiveLogFile(object):
18     """
19     Encapsulate file that is currently updated/appended as it is used
20     by a log file.
21     A live status file is used for storing status information (such as
22     current position in log file processing). The live status file name is the
23     log file name with ".lstatus" appended to it.
24     """
25
26     def __init__(self, log_file_name):
27         self.log_file_name = log_file_name
28         self.status_file_name = log_file_name + ".lstatus"
29
30         self.log_file = open(self.log_file_name, "tt")
31         self.status_file = open(self.status_file_name, "ab+")
32         self.status_file.seek(0)
33
34         self.load_status()
35         self.log_file.seek(self.status.position)
36
37     def close(self):
38         self.log_file.close()
39         self.status_file.close()
40
41     def load_status(self):
42         self.status_file.seek(0)
43
44         # If line is empty (file is just created), position is 0
45         line = self.status_file.readline()
46         try:
47             position = int(line)
48         except TypeError, e:
49             position = 0
50         self.status = LiveLogStatus(position)
51
52         self.status_file.seek(0)
53
54     def store_status(self):
55         self.status_file.seek(0)
56         self.status.position = self.log_file.tell()
57         self.status_file.write(str(self.status.position) + "\n")
58         self.status_file.seek(0)
59
60     def readline(self):
61         current_position = self.log_file.tell()
62         line = self.log_file.readline()
63
64         # In case of complete line, update status and return it.
65         if "\n" in line:
66             self.store_status()
67             return line
68
69         # In case of incomplete line, rewind and return "".
70         self.log_file.seek(current_position)
71         return ""