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