1# This file is part of Gajim. 2# 3# Gajim is free software; you can redistribute it and/or modify 4# it under the terms of the GNU General Public License as published 5# by the Free Software Foundation; version 3 only. 6# 7# Gajim is distributed in the hope that it will be useful, 8# but WITHOUT ANY WARRANTY; without even the implied warranty of 9# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10# GNU General Public License for more details. 11# 12# You should have received a copy of the GNU General Public License 13# along with Gajim. If not, see <http://www.gnu.org/licenses/>. 14 15import time 16from collections import namedtuple 17 18from nbxmpp.protocol import JID 19 20from gajim.common.const import MUCJoinedState 21from gajim.common.const import KindConstant 22 23URI = namedtuple('URI', 'type action data') 24URI.__new__.__defaults__ = (None, None) # type: ignore 25 26 27class MUCData: 28 def __init__(self, room_jid, nick, password, config=None): 29 self._room_jid = JID.from_string(room_jid) 30 self._config = config 31 self.nick = nick 32 self.password = password 33 self.state = MUCJoinedState.NOT_JOINED 34 # Message id of the captcha challenge 35 self.captcha_id = None 36 37 @property 38 def jid(self): 39 return self._room_jid 40 41 @property 42 def occupant_jid(self): 43 return self._room_jid.new_with(resource=self.nick) 44 45 @property 46 def config(self): 47 return self._config 48 49 50class OutgoingMessage: 51 def __init__(self, 52 account, 53 contact, 54 message, 55 type_, 56 subject=None, 57 chatstate=None, 58 marker=None, 59 resource=None, 60 user_nick=None, 61 label=None, 62 control=None, 63 attention=None, 64 correct_id=None, 65 oob_url=None, 66 xhtml=None, 67 nodes=None, 68 play_sound=True): 69 70 if type_ not in ('chat', 'groupchat', 'normal', 'headline'): 71 raise ValueError('Unknown message type: %s' % type_) 72 73 if not message and chatstate is None and marker is None: 74 raise ValueError('Trying to send message without content') 75 76 self.account = account 77 self.contact = contact 78 self.message = message 79 self.type_ = type_ 80 81 if type_ == 'chat': 82 self.kind = KindConstant.CHAT_MSG_SENT 83 elif type_ == 'groupchat': 84 self.kind = KindConstant.GC_MSG 85 elif type_ == 'normal': 86 self.kind = KindConstant.SINGLE_MSG_SENT 87 else: 88 raise ValueError('Unknown message type') 89 90 from gajim.common.helpers import AdditionalDataDict 91 self.additional_data = AdditionalDataDict() 92 93 self.subject = subject 94 self.chatstate = chatstate 95 self.marker = marker 96 self.resource = resource 97 self.user_nick = user_nick 98 self.label = label 99 self.control = control 100 self.attention = attention 101 self.correct_id = correct_id 102 103 self.oob_url = oob_url 104 105 if oob_url is not None: 106 self.additional_data.set_value('gajim', 'oob_url', oob_url) 107 108 self.xhtml = xhtml 109 110 if xhtml is not None: 111 self.additional_data.set_value('gajim', 'xhtml', xhtml) 112 113 self.nodes = nodes 114 self.play_sound = play_sound 115 116 self.timestamp = None 117 self.message_id = None 118 self.stanza = None 119 self.session = None 120 self.delayed = None # TODO never set 121 122 self.is_loggable = True 123 124 def copy(self): 125 message = OutgoingMessage(self.account, 126 self.contact, 127 self.message, 128 self.type_) 129 for name, value in vars(self).items(): 130 setattr(message, name, value) 131 message.additional_data = self.additional_data.copy() 132 return message 133 134 @property 135 def jid(self): 136 return self.contact.jid 137 138 @property 139 def is_groupchat(self): 140 return self.type_ == 'groupchat' 141 142 @property 143 def is_chat(self): 144 return self.type_ == 'chat' 145 146 @property 147 def is_normal(self): 148 return self.type_ == 'normal' 149 150 def set_sent_timestamp(self): 151 if self.is_groupchat: 152 return 153 self.timestamp = time.time() 154 155 @property 156 def is_encrypted(self): 157 return bool(self.additional_data.get_value('encrypted', 'name', False)) 158 159 @property 160 def msg_iq(self): 161 # Backwards compatibility for plugins 162 return self.stanza 163 164 @msg_iq.setter 165 def msg_iq(self, value): 166 # Backwards compatibility for plugins 167 self.stanza = value 168