WvStream: in the destructor assert() statement, say the type of stream.
[versaplex.git] / veranda / Parser.py
blob106ab243c8376c14144785e84a219deef8fa352f
1 #!/usr/bin/python
3 #------------------------------------------------------------------------------
4 # Veranda
5 # *Parser
6 # *Iterator
7 # ~--------------~
9 # Original Author: Andrei "Garoth" Thorp <garoth@gmail.com>
11 # Description: This module takes in python-formatted DBus-SQL message and
12 # wraps it in an object for easy usage. One of the aims is for
13 # this then to be easily usable with gtk's TreeView table
14 # system.
16 # Notes:
17 # Indentation: I use tabs only, 4 spaces per tab.
18 #------------------------------------------------------------------------------
19 import time
20 import sys
21 #------------------------------------------------------------------------------
22 class Parser:
23 #------------------------------------------------------------------------------
24 """ An abstraction layer for DBus-SQL messages. This module makes it easy
25 to extract data from messages that Versaplex replies with over dbus."""
26 #---------------------------
27 def __init__(self, message):
28 #---------------------------
29 """Constructor: get the message, control the workflow"""
30 self.message = message # The original message
31 self.types = [] # The types of each column
32 self.titles = [] # The titles of each column
33 self.table = [] # The table (columns/rows for data)
35 self.__parseColumnTypes__()
36 self.__parseColumnTitles__()
37 self.__parseTableRows__()
39 #------------------------------
40 def __parseColumnTypes__(self):
41 #------------------------------
42 """Puts in as many strings into a list as there are columns"""
43 segmentZero = self.message[0]
45 for struct in segmentZero:
46 self.types.append(str(struct[2]))
48 #-------------------------------
49 def __parseColumnTitles__(self):
50 #-------------------------------
51 """Extracts the names of the columns from self.message and puts them
52 in as the first row of self.table"""
53 segmentZero = self.message[0]
54 for struct in segmentZero:
55 self.titles.append(str(struct[1]))
57 #----------------------------
58 def __parseTableRows__(self):
59 #----------------------------
60 """Extracts the table rows from self.message and puts them into
61 self.table"""
62 # NOTE: this will make a table of _rows_. Sometimes, there will be
63 # only one element in the row (see sidebar). However, this
64 # is the correct behavior. Do not "fix" it.
66 # Fill the table
67 segmentOne = self.message[1]
68 for struct in segmentOne:
69 row = []
70 for x in range(self.numColumns()):
71 colType = self.types[x]
72 if colType == "DateTime":
73 # If it's a tuple, try to convert to time format
74 row.append(str(time.strftime("%Y/%m/%d %H:%M:%S",
75 time.localtime(struct[x][0]))))
76 else:
77 row.append(str(struct[x]))
78 self.table.append(row)
80 # Remove any nulls by comparing against another table
81 segmentTwo = self.message[2]
82 y = 0
83 for struct in segmentTwo:
84 row = []
85 for x in range(self.numColumns()):
86 if struct[x]:
87 self.table[y][x] = ""
88 y += 1
90 #--------------------
91 def numColumns(self):
92 #--------------------
93 """Returns the number of columns in the data"""
94 return len(self.types)
96 #-----------------
97 def numRows(self):
98 #-----------------
99 """Returns the number of rows of data (not the title row)"""
100 return len(self.table)
102 #----------------------------
103 def getOriginalMessage(self):
104 #----------------------------
105 """Returns the original dbus message"""
106 return self.message
108 #-------------------------
109 def getColumnTitles(self):
110 #-------------------------
111 """Returns a list of the titles of the columns"""
112 return self.titles
114 #------------------------
115 def getColumnTypes(self):
116 #------------------------
117 """Returns the types of the columns (returns a list of types, like
118 "str" or "int")"""
119 return self.types
121 #---------------------------------
122 def getColumnTypesAsStrings(self):
123 #---------------------------------
124 """Returns the same amount of strings as there are types in the
125 self.types list. This is useful for displaying data in a table
126 with gtk.ListStore."""
127 builder = []
128 for type in self.types:
129 builder.append(str)
130 return builder
132 #------------------
133 def getTable(self):
134 #------------------
135 """Returns the body of the table"""
136 return self.table
138 #--------------------------
139 def getTableIterator(self):
140 #--------------------------
141 """Returns a simple iterator for self.table"""
142 return Iterator(self.table)
144 #------------------------------------------------------------------------------
145 class Iterator:
146 #------------------------------------------------------------------------------
147 """A simple iterator made for returning one table row at a time"""
148 #-------------------------
149 def __init__(self, table):
150 #-------------------------
151 """Starts up the instance variables"""
152 self.table = table # The data
153 self.currentRow = -1 # The location of the iterator by row number
155 #----------------------------
156 def setCurrent(self, number):
157 #----------------------------
158 """Lets you set the row that the iterator is currently on. Remember,
159 though that getNext() will return the next element, not the current"""
160 self.currentRow = number
162 #-----------------
163 def getNext(self):
164 #-----------------
165 """Returns the next row in the table"""
166 if self.hasNext():
167 self.currentRow += 1
168 return self.table[self.currentRow]
169 else:
170 raise IndexError, "Data table from Dbus has no next row"
172 #-----------------
173 def hasNext(self):
174 #-----------------
175 """Checks if there is a next row in the table"""
176 if self.currentRow+1 <= len(self.table)-1:
177 return True
178 else:
179 return False