1
# -*- coding: utf-8 -*-
3
# pymsn - a python client library for Msn
5
# Copyright (C) 2005-2006 Ali Sabil <ali.sabil@gmail.com>
7
# This program is free software; you can redistribute it and/or modify
8
# it under the terms of the GNU General Public License as published by
9
# the Free Software Foundation; either version 2 of the License, or
10
# (at your option) any later version.
12
# This program is distributed in the hope that it will be useful,
13
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU General Public License for more details.
17
# You should have received a copy of the GNU General Public License
18
# along with this program; if not, write to the Free Software
19
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21
"""MSN protocol special command : MSG"""
23
from pymsn.gnet.message.HTTP import HTTPMessage
24
import pymsn.util.debug as debug
26
from urllib import quote, unquote
29
__all__ = ['MessageAcknowledgement', 'Message']
32
class MessageAcknowledgement(object):
33
"""Message Acknowledgement"""
35
"""Acknowledgement required for both delivery success and failure"""
37
"""Direct connection, no acknowledgment required from the server"""
39
"""Acknowledgment on delivery failures"""
41
"""No Acknowledgment"""
43
class Message(HTTPMessage):
44
"""Base Messages class.
47
@type sender: profile.Contact
49
@ivar body: message body
52
@ivar headers: message headers
53
@type headers: {header_name: string => header_value:string}
55
@ivar content_type: the message content type
56
@type content_type: tuple(mime_type, encoding)"""
58
def __init__(self, sender=None, message=""):
61
@param body: The body of the message, it is put after the headers
63
HTTPMessage.__init__(self)
69
"""Represents the payload of the message"""
71
for header_name, header_value in self.headers.iteritems():
72
message += '\t%s: %s\\r\\n\n' % (header_name, header_value)
73
message += '\t\\r\\n\n'
74
if self.headers['Content-Type'] != "application/x-msnmsgrp2p":
75
message += '\t' + debug.escape_string(self.body).\
76
replace("\r\n", "\\r\\n\n\t")
78
tlp_header = self.body[:48]
79
tlp_footer = self.body[-4:]
80
tlp_flags = struct.unpack("<L", self.body[28:32])[0]
81
body = self.body[48:-4]
83
message += "\t" + debug.hexify_string(tlp_header).replace("\r\n", "\n\t")
86
message += "\n\t" + debug.escape_string(body).\
87
replace("\r\n", "\\r\\n\n\t")
89
message += "\n\t" + "[%d bytes of data]" % len(body)
90
message += "\n\t" + debug.hexify_string(tlp_footer)
92
return message.rstrip("\n\t")
94
def __get_content_type(self):
95
if 'Content-Type' in self.headers:
96
content_type = self.headers['Content-Type'].split(';', 1)
97
if len(content_type) == 1:
98
return (content_type[0].strip(), 'UTF-8')
99
mime_type = content_type[0].strip()
100
encoding = content_type[1].split('=', 1)[1].strip()
101
return (mime_type, encoding)
102
return ('text/plain', 'UTF-8')
104
def __set_content_type(self, content_type):
105
if not isinstance(content_type, str):
106
content_type = '; charset='.join(content_type)
107
self.headers['Content-Type'] = content_type
109
content_type = property(__get_content_type, __set_content_type,
110
doc="a tuple specifying the content type")