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