core cleanup: the big status/activity revamp
[siplcs.git] / src / core / sipe-status.c
blobe86ccd46a7397f8d31326c12a3729d3f7ad9bfda
1 /**
2 * @file sipe-status.c
4 * pidgin-sipe
6 * Copyright (C) 2011 SIPE Project <http://sipe.sourceforge.net/>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
28 #include <time.h>
30 #include <glib.h>
32 #include "sipe-common.h"
33 #include "http-conn.h" /* sipe-cal.h requires this */
34 #include "sipe-backend.h"
35 #include "sipe-cal.h"
36 #include "sipe-core.h"
37 #include "sipe-core-private.h"
38 #include "sipe-nls.h"
39 #include "sipe-ocs2005.h"
40 #include "sipe-ocs2007.h"
41 #include "sipe-schedule.h"
42 #include "sipe-status.h"
43 #include "sipe-utils.h"
44 #include "sipe.h"
46 #define SIPE_IDLE_SET_DELAY 1 /* seconds */
48 static struct
50 guint type;
51 const gchar *desc;
52 } const sipe_activity_map[SIPE_ACTIVITY_NUM_TYPES] = {
54 * This has nothing to do with Availability numbers, like 3500 (online).
55 * Just a mapping of Communicator Activities to translations
57 /* @TODO: NULL means "default translation from Pidgin"?
58 * What about other backends? */
59 { SIPE_ACTIVITY_UNSET, NULL },
60 { SIPE_ACTIVITY_AVAILABLE, NULL },
61 { SIPE_ACTIVITY_ONLINE, NULL },
62 { SIPE_ACTIVITY_INACTIVE, N_("Inactive") },
63 { SIPE_ACTIVITY_BUSY, N_("Busy") },
64 { SIPE_ACTIVITY_BUSYIDLE, N_("Busy-Idle") },
65 { SIPE_ACTIVITY_DND, NULL },
66 { SIPE_ACTIVITY_BRB, N_("Be right back") },
67 { SIPE_ACTIVITY_AWAY, NULL },
68 { SIPE_ACTIVITY_LUNCH, N_("Out to lunch") },
69 { SIPE_ACTIVITY_INVISIBLE, NULL },
70 { SIPE_ACTIVITY_OFFLINE, NULL },
71 { SIPE_ACTIVITY_ON_PHONE, N_("In a call") },
72 { SIPE_ACTIVITY_IN_CONF, N_("In a conference") },
73 { SIPE_ACTIVITY_IN_MEETING, N_("In a meeting") },
74 { SIPE_ACTIVITY_OOF, N_("Out of office") },
75 { SIPE_ACTIVITY_URGENT_ONLY, N_("Urgent interruptions only") }
78 const gchar *sipe_core_activity_description(guint type)
80 return(gettext(sipe_activity_map[type].desc));
83 void sipe_status_set_token(struct sipe_core_private *sipe_private,
84 const gchar *status_id)
86 struct sipe_account_data *sip = SIPE_ACCOUNT_DATA_PRIVATE;
87 g_free(sip->status);
88 sip->status = g_strdup(status_id);
91 void sipe_status_set_activity(struct sipe_core_private *sipe_private,
92 guint activity)
94 sipe_status_set_token(sipe_private,
95 sipe_backend_activity_to_token(activity));
98 void sipe_core_reset_status(struct sipe_core_public *sipe_public)
100 struct sipe_core_private *sipe_private = SIPE_CORE_PRIVATE;
101 if (SIPE_CORE_PRIVATE_FLAG_IS(OCS2007))
102 sipe_ocs2007_reset_status(sipe_private);
103 else
104 sipe_ocs2005_reset_status(sipe_private);
107 void sipe_status_and_note(struct sipe_core_private *sipe_private,
108 const gchar *status_id)
110 struct sipe_account_data *sip = SIPE_ACCOUNT_DATA_PRIVATE;
112 if (!status_id)
113 status_id = sip->status;
115 SIPE_DEBUG_INFO("sipe_status_and_note: switch to '%s' for the account", status_id);
117 if (sipe_backend_status_and_note(SIPE_CORE_PUBLIC,
118 status_id,
119 sip->note)) {
120 /* status has changed */
121 guint activity = sipe_backend_token_to_activity(status_id);
123 sip->do_not_publish[activity] = time(NULL);
124 SIPE_DEBUG_INFO("sipe_status_and_note: do_not_publish[%s]=%d [now]",
125 status_id,
126 (int) sip->do_not_publish[activity]);
130 void sipe_core_status_set(struct sipe_core_public *sipe_public,
131 const gchar *status_id,
132 const gchar *note)
134 struct sipe_core_private *sipe_private = SIPE_CORE_PRIVATE;
135 struct sipe_account_data *sip = SIPE_ACCOUNT_DATA_PRIVATE;
137 if (sip) {
138 gchar *action_name;
139 gchar *tmp;
140 time_t now = time(NULL);
141 guint activity = sipe_backend_token_to_activity(status_id);
142 gboolean do_not_publish = ((now - sip->do_not_publish[activity]) <= 2);
144 /* when other point of presence clears note, but we are keeping
145 * state if OOF note.
147 if (do_not_publish && !note && sip->cal && sip->cal->oof_note) {
148 SIPE_DEBUG_INFO_NOFORMAT("sipe_core_status_set: enabling publication as OOF note keepers.");
149 do_not_publish = FALSE;
152 SIPE_DEBUG_INFO("sipe_core_status_set: was: sip->do_not_publish[%s]=%d [?] now(time)=%d",
153 status_id, (int)sip->do_not_publish[activity], (int)now);
155 sip->do_not_publish[activity] = 0;
156 SIPE_DEBUG_INFO("sipe_core_status_set: set: sip->do_not_publish[%s]=%d [0]",
157 status_id, (int)sip->do_not_publish[activity]);
159 if (do_not_publish) {
160 SIPE_DEBUG_INFO_NOFORMAT("sipe_core_status_set: publication was switched off, exiting.");
161 return;
164 sipe_status_set_token(sipe_private, status_id);
166 /* hack to escape apostrof before comparison */
167 tmp = note ? sipe_utils_str_replace(note, "'", "&apos;") : NULL;
169 /* this will preserve OOF flag as well */
170 if (!sipe_strequal(tmp, sip->note)) {
171 sip->is_oof_note = FALSE;
172 g_free(sip->note);
173 sip->note = g_strdup(note);
174 sip->note_since = time(NULL);
176 g_free(tmp);
178 /* schedule 2 sec to capture idle flag */
179 action_name = g_strdup("<+set-status>");
180 sipe_schedule_seconds(sipe_private,
181 action_name,
182 NULL,
183 SIPE_IDLE_SET_DELAY,
184 send_presence_status,
185 NULL);
186 g_free(action_name);
191 * Whether user manually changed status or
192 * it was changed automatically due to user
193 * became inactive/active again
195 gboolean sipe_status_changed_by_user(struct sipe_core_private *sipe_private)
197 struct sipe_account_data *sip = SIPE_ACCOUNT_DATA_PRIVATE;
198 gboolean res;
199 time_t now = time(NULL);
201 SIPE_DEBUG_INFO("sipe_status_changed_by_user: sip->idle_switch : %s",
202 asctime(localtime(&(sip->idle_switch))));
203 SIPE_DEBUG_INFO("sipe_status_changed_by_user: now : %s",
204 asctime(localtime(&now)));
206 res = ((now - SIPE_IDLE_SET_DELAY * 2) >= sip->idle_switch);
208 SIPE_DEBUG_INFO("sipe_status_changed_by_user: res = %s",
209 res ? "USER" : "MACHINE");
210 return res;
213 void sipe_core_status_idle(struct sipe_core_public *sipe_public)
215 struct sipe_core_private *sipe_private = SIPE_CORE_PRIVATE;
216 struct sipe_account_data *sip = SIPE_ACCOUNT_DATA_PRIVATE;
218 if (sip) {
219 sip->idle_switch = time(NULL);
220 SIPE_DEBUG_INFO("sipe_core_status_idle: sip->idle_switch : %s",
221 asctime(localtime(&(sip->idle_switch))));
226 Local Variables:
227 mode: c
228 c-file-style: "bsd"
229 indent-tabs-mode: t
230 tab-width: 8
231 End: