def parse_datapacks(data): retval = [] while data[0] == '\n': #while the next thing is a message chunk, data = chunk_datapack(data) #get a chunk retval.append(parse_chunk(chunk)) num_messages = 0 type_, numbytes = u7i(data) #the thing after the last msg is usually num msgs data = data[numbytes:] if type_ == 136: #num_messages num_messages, numbytes = u7i(data) data = data[numbytes:] return retval, num_messages, data
def get_chunk(data): type_, numbytes = u7i(data) data = data[numbytes:] if type_ == 184: #number of participants, value is next number value, length_ = u7i(data) elif type_ == 152: #to me/me only, mailing list value, length_ = u7i(data) else: length_, numbytes = u7i(data) #else, assume it has a length + value data = data[numbytes:] #remove length number # if type_ == 146: # length_ += 3 return type_, data[:length_], data[length_:] #return type, value, remainder
def parse_datapacks(data): retval = [] while data[0] == '\n': #while the next thing is a message chunk, data = chunk_datapack(data) #get a chunk retval.append(parse_chunk(chunk)) num_messages = 0 type_, numbytes = u7i( data) #the thing after the last msg is usually num msgs data = data[numbytes:] if type_ == 136: #num_messages num_messages, numbytes = u7i(data) data = data[numbytes:] return retval, num_messages, data
def get_mid_date(data): orig_length = len(data) length_, numbytes = u7i(data) #length of chunk expected_length = (orig_length - length_) - numbytes data = data[numbytes:] msgid, numbytes = u7i(data) #msgid is first number data = data[numbytes:] _unknown, numbytes = u7i(data) #mystery byte data = data[numbytes:] time_in_ms, numbytes = u7i(data) #next is time in milliseconds data = data[numbytes:] # print "len is", len(data), "expected", expected_length assert len(data) == expected_length return msgid, time_in_ms, data #msgid, time, remainder
def chunk_datapack(data): assert data[0] == '\n' #first char is \n data = data[1:] num, numbytes = u7i(data) #next bit is utf7 number # print "numbytes", numbytes, repr(data[:numbytes]) data = data[numbytes:] #take off the number return data[:num], data[num:] #return value, remainder
def get_chunk(data): type_, numbytes = u7i(data) data = data[numbytes:] if type_ == 184: #number of participants, value is next number value, length_ = u7i(data) elif type_ == 152: #to me/me only, mailing list value, length_ = u7i(data) else: length_, numbytes = u7i(data) #else, assume it has a length + value data = data[numbytes:] #remove length number # if type_ == 146: # length_ += 3 return type_, data[:length_], data[ length_:] #return type, value, remainder
def parse_from(from_): retval = {} assert from_[0] == "\n" #first byte is \n from_ = from_[1:] retval['mystery_bytes1'], from_ = from_.split("\n", 1) #something, and then \n # retval['mystery_bytes1'] = ord(retval['mystery_bytes1']) #seems to be a number length_, numbytes = u7i(from_) #length of address from_ = from_[numbytes:] retval['email_addr'], from_ = from_[:length_], from_[length_:] #address is next type_, numbytes = u7i(from_) if type_ == 0x12: #text version of from, i.e. the name from_ = from_[numbytes:] length_, numbytes = u7i(from_) from_ = from_[numbytes:] retval['from_text'], from_ = from_[:length_], from_[length_:] retval['remainder_bytes'] = from_ return retval
def parse_from(from_): retval = {} assert from_[0] == "\n" #first byte is \n from_ = from_[1:] retval['mystery_bytes1'], from_ = from_.split("\n", 1) #something, and then \n # retval['mystery_bytes1'] = ord(retval['mystery_bytes1']) #seems to be a number length_, numbytes = u7i(from_) #length of address from_ = from_[numbytes:] retval['email_addr'], from_ = from_[:length_], from_[ length_:] #address is next type_, numbytes = u7i(from_) if type_ == 0x12: #text version of from, i.e. the name from_ = from_[numbytes:] length_, numbytes = u7i(from_) from_ = from_[numbytes:] retval['from_text'], from_ = from_[:length_], from_[length_:] retval['remainder_bytes'] = from_ return retval
def parse_chunk(chunk): retval = defaultdict(list) mid, time_in_ms, data = get_mid_date(chunk) retval["mid"] = mid retval["time"] = time_in_ms while data: t, v, data = get_chunk(data) if t == 146: #email v = parse_from(v) elif t in (152, 184): #personal level, conversation size # print repr(v) v = u7i(v)[0] retval[t].append(v) return retval