]> git.ipfire.org Git - ipfire.org.git/blame - src/backend/talk.py
Introduce autotools
[ipfire.org.git] / src / backend / talk.py
CommitLineData
66862195
MT
1#!/usr/bin/python
2
77431b9c
MT
3import re
4
5ac74b02
MT
5from . import asterisk
6from . import database
66862195
MT
7
8from misc import Object
9
10class Talk(Object):
11 def init(self):
12 db_args = self.backend.db._db_args
13 db_args.update({
77431b9c 14 "database" : "kamailio",
66862195
MT
15 })
16
17 self._db = database.Connection(**db_args)
18
19 @property
20 def db(self):
21 return self._db
22
5ac74b02
MT
23 def connect_to_asterisk(self):
24 hostname = self.settings.get("asterisk_hostname")
25 username = self.settings.get("asterisk_username")
26 password = self.settings.get("asterisk_password")
27
28 return asterisk.AsteriskManager(
29 hostname, username=username, password=password
30 )
31
66862195
MT
32 def get_phonebook(self, account=None):
33 accounts = []
34 for a in self.accounts.list():
35 if account and a == account:
36 continue
37
38 if not a.is_talk_enabled():
39 continue
40
41 accounts.append(a)
42
43 return accounts
44
45 def user_is_online(self, sip_id):
77431b9c 46 res = self.db.get("SELECT 1 FROM location WHERE username = %s \
66862195
MT
47 AND expires >= NOW() LIMIT 1", sip_id)
48
49 if res:
50 return True
51
52 return False
53
77431b9c
MT
54 def get_lines(self, account=None):
55 accounts_cache = {}
66862195 56
77431b9c 57 if account and not account.is_talk_enabled():
66862195
MT
58 return []
59
77431b9c
MT
60 if account:
61 res = self.db.query("SELECT contact AS location, expires, user_agent, socket \
62 FROM location WHERE domain = %s AND username = %s ORDER BY expires DESC",
63 "ipfire.org", account.sip_id)
64 else:
65 res = self.db.query("SELECT username, domain, contact AS location, \
66 expires, user_agent, socket FROM location ORDER BY username, expires DESC")
66862195
MT
67
68 result = []
69 for row in res:
77431b9c
MT
70 if account:
71 row.account = account
72 elif row.username:
73 try:
74 row.account = accounts_cache[row.username]
75 except KeyError:
76 row.account = accounts_cache[row.username] = \
77 self.accounts.get_by_sip_id(row.username)
78 else:
79 row.account = None
66862195 80
77431b9c
MT
81 # Check if TLS is used
82 row.tls_enabled = row.socket.startswith("tls:")
66862195
MT
83
84 # Cut off everything after ;
85 row.location, sep, rest = row.location.partition(";")
86
87 result.append(row)
88
89 return result
90
77431b9c
MT
91 def _process_sip_uri(self, sip_uri):
92 sip_uri, delimiter, rest = sip_uri.partition(";")
93
94 m = re.match(r"^sip:([0-9]{4})@ipfire\.org", sip_uri)
95 if m:
96 return m.group(1)
97
98 # Remove trailing default port
99 if sip_uri.endswith(":5060"):
100 sip_uri = sip_uri.replace(":5060", "")
101
102 return sip_uri
103
104 def _process_cdr(self, entries, replace_sip_uris=False):
66862195
MT
105 accounts_cache = {}
106
107 result = []
108 for row in entries:
77431b9c
MT
109 if replace_sip_uris:
110 row["caller"] = self._process_sip_uri(row.caller)
111
66862195 112 try:
77431b9c 113 row["caller_account"] = accounts_cache[row.caller]
66862195 114 except KeyError:
77431b9c 115 row["caller_account"] = accounts_cache[row.caller] = \
66862195
MT
116 self.accounts.get_by_sip_id(row.caller)
117
77431b9c
MT
118 if replace_sip_uris:
119 row["called"] = self._process_sip_uri(row.called)
120
66862195 121 try:
77431b9c 122 row["called_account"] = accounts_cache[row.called]
66862195 123 except KeyError:
77431b9c 124 row["called_account"] = accounts_cache[row.called] = \
66862195
MT
125 self.accounts.get_by_sip_id(row.called)
126
127 if not row.called_account:
77431b9c 128 row["called_conference"] = self.get_conference(row.called)
66862195 129 else:
77431b9c
MT
130 row["called_conference"] = None
131
132 try:
133 row["time"] = datetime.datetime.fromutctimestamp(row.time)
134 except:
135 pass
66862195
MT
136
137 result.append(row)
138
139 return result
140
141 def get_call_log(self, account, limit=25):
77431b9c
MT
142 if account:
143 res = self.db.query("SELECT * FROM cdr WHERE (caller = %s OR called = %s) \
144 ORDER BY time DESC LIMIT %s", account.sip_id, account.sip_id, limit)
145 else:
146 res = self.db.query("SELECT * FROM cdr ORDER BY time DESC LIMIT %s", limit)
66862195
MT
147
148 return self._process_cdr(res)
149
5ac74b02
MT
150 def get_channels(self, account=None):
151 a = self.connect_to_asterisk()
152
153 channels = []
154 for c in a.list_channels():
155 if account and not account.sip_id in (c.caller, c.callee):
156 continue
157
158 channels.append(c)
159
160 return sorted(channels)
161
40818cf2
MT
162 def get_channel(self, channel_id, account=None):
163 channels = self.get_channels(account=account)
164
165 for channel in channels:
166 if channel.id == channel_id:
167 return channel
168
66862195
MT
169 def get_ongoing_calls(self, account=None, sip_id=None):
170 if account and sip_id is None:
171 sip_id = account.sip_id
172
77431b9c
MT
173 # If the given account does not have a SIP ID,
174 # we not need to search for any active sessions
175 if sip_id is None:
176 return []
177
66862195 178 if sip_id:
77431b9c
MT
179 sip_id = "sip:%s@%%" % sip_id
180
181 res = self.db.query("SELECT from_uri AS caller, \
182 to_uri AS called, start_time AS time FROM dialog \
183 WHERE from_uri LIKE %s OR to_uri LIKE %s ORDER BY time",
184 sip_id, sip_id)
66862195 185 else:
77431b9c
MT
186 res = self.db.query("SELECT from_uri AS caller, to_uri AS called, \
187 start_time AS time FROM dialog ORDER BY time")
66862195 188
77431b9c 189 return self._process_cdr(res, replace_sip_uris=True)
66862195 190
66862195
MT
191 # Favourites
192
193 def get_favourite_contacts(self, account, limit=6):
77431b9c
MT
194 res = self.db.query("SELECT src_user AS caller, dst_ouser AS called, \
195 COUNT(*) AS count FROM acc WHERE method = %s AND src_user = %s AND \
196 dst_ouser BETWEEN %s AND %s AND time >= NOW() - INTERVAL '1 year' \
197 GROUP BY caller, called ORDER BY count DESC LIMIT %s",
198 "INVITE", account.sip_id, "1000", "1999", limit)
66862195
MT
199
200 return self._process_cdr(res)
201
202 # Conferences
203
204 @property
205 def conferences(self):
206 conferences = []
207
208 for no in range(1, 10):
209 conference = Conference(self.backend, no)
210 conferences.append(conference)
211
212 return conferences
213
214 def get_conference(self, id):
215 for c in self.conferences:
216 if not c.sip_id == id:
217 continue
218
219 return c
220
221
222class Conference(Object):
223 def __init__(self, backend, no):
224 Object.__init__(self, backend)
225 self.no = no
226
227 def __cmp__(self, other):
228 return cmp(self.no, other.no)
229
230 @property
231 def name(self):
232 return "IPFire Conference Room %s" % self.no
233
234 @property
235 def sip_id(self):
236 return "%s" % (9000 + self.no)
237
238 @property
239 def sip_url(self):
240 return "%s@ipfire.org" % self.sip_id
241
242 @property
243 def participants(self):
244 if not hasattr(self, "_participants"):
245 self._participants = self.backend.talk.get_ongoing_calls(sip_id=self.sip_id)
246
247 return self._participants