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
32 #include "sipe-common.h"
33 #include "sipe-backend.h"
35 #include "sipe-core.h"
36 #include "sipe-core-private.h"
38 #include "sipe-ocs2005.h"
39 #include "sipe-ocs2007.h"
40 #include "sipe-schedule.h"
41 #include "sipe-status.h"
42 #include "sipe-utils.h"
44 #define SIPE_IDLE_SET_DELAY 1 /* seconds */
50 } const sipe_activity_map
[SIPE_ACTIVITY_NUM_TYPES
] = {
52 * This has nothing to do with Availability numbers, like 3500 (online).
53 * Just a mapping of Communicator Activities to translations
55 /* @TODO: NULL means "default translation from Pidgin"?
56 * What about other backends? */
57 { SIPE_ACTIVITY_UNSET
, NULL
},
58 { SIPE_ACTIVITY_AVAILABLE
, NULL
},
59 { SIPE_ACTIVITY_ONLINE
, NULL
},
60 { SIPE_ACTIVITY_INACTIVE
, N_("Inactive") },
61 { SIPE_ACTIVITY_BUSY
, N_("Busy") },
62 { SIPE_ACTIVITY_BUSYIDLE
, N_("Busy-Idle") },
63 { SIPE_ACTIVITY_DND
, NULL
},
64 { SIPE_ACTIVITY_BRB
, N_("Be right back") },
65 { SIPE_ACTIVITY_AWAY
, NULL
},
66 { SIPE_ACTIVITY_LUNCH
, N_("Out to lunch") },
67 { SIPE_ACTIVITY_INVISIBLE
, NULL
},
68 { SIPE_ACTIVITY_OFFLINE
, NULL
},
69 { SIPE_ACTIVITY_ON_PHONE
, N_("In a call") },
70 { SIPE_ACTIVITY_IN_CONF
, N_("In a conference") },
71 { SIPE_ACTIVITY_IN_MEETING
, N_("In a meeting") },
72 { SIPE_ACTIVITY_OOF
, N_("Out of office") },
73 { SIPE_ACTIVITY_URGENT_ONLY
, N_("Urgent interruptions only") }
76 const gchar
*sipe_core_activity_description(guint type
)
78 return(gettext(sipe_activity_map
[type
].desc
));
81 void sipe_status_set_token(struct sipe_core_private
*sipe_private
,
82 const gchar
*status_id
)
84 g_free(sipe_private
->status
);
85 sipe_private
->status
= g_strdup(status_id
);
88 void sipe_status_set_activity(struct sipe_core_private
*sipe_private
,
91 sipe_status_set_token(sipe_private
,
92 sipe_backend_activity_to_token(activity
));
95 void sipe_core_reset_status(struct sipe_core_public
*sipe_public
)
97 struct sipe_core_private
*sipe_private
= SIPE_CORE_PRIVATE
;
98 if (SIPE_CORE_PRIVATE_FLAG_IS(OCS2007
))
99 sipe_ocs2007_reset_status(sipe_private
);
101 sipe_ocs2005_reset_status(sipe_private
);
104 void sipe_status_and_note(struct sipe_core_private
*sipe_private
,
105 const gchar
*status_id
)
108 status_id
= sipe_private
->status
;
110 SIPE_DEBUG_INFO("sipe_status_and_note: switch to '%s' for the account", status_id
);
112 if (sipe_backend_status_and_note(SIPE_CORE_PUBLIC
,
114 sipe_private
->note
)) {
115 /* status has changed */
116 guint activity
= sipe_backend_token_to_activity(status_id
);
118 sipe_private
->do_not_publish
[activity
] = time(NULL
);
119 SIPE_DEBUG_INFO("sipe_status_and_note: do_not_publish[%s]=%d [now]",
121 (int) sipe_private
->do_not_publish
[activity
]);
125 void sipe_status_update(struct sipe_core_private
*sipe_private
,
126 SIPE_UNUSED_PARAMETER gpointer unused
)
128 const gchar
*status
= sipe_backend_status(SIPE_CORE_PUBLIC
);
132 SIPE_DEBUG_INFO("sipe_status_update: status: %s (%s)", status
,
133 sipe_status_changed_by_user(sipe_private
) ? "USER" : "MACHINE");
135 sipe_cal_presence_publish(sipe_private
, FALSE
);
138 void sipe_core_status_set(struct sipe_core_public
*sipe_public
,
139 const gchar
*status_id
,
142 struct sipe_core_private
*sipe_private
= SIPE_CORE_PRIVATE
;
145 time_t now
= time(NULL
);
146 guint activity
= sipe_backend_token_to_activity(status_id
);
147 gboolean do_not_publish
= ((now
- sipe_private
->do_not_publish
[activity
]) <= 2);
149 /* when other point of presence clears note, but we are keeping
152 if (do_not_publish
&&
154 sipe_private
->calendar
&&
155 sipe_private
->calendar
->oof_note
) {
156 SIPE_DEBUG_INFO_NOFORMAT("sipe_core_status_set: enabling publication as OOF note keepers.");
157 do_not_publish
= FALSE
;
160 SIPE_DEBUG_INFO("sipe_core_status_set: was: sipe_private->do_not_publish[%s]=%d [?] now(time)=%d",
161 status_id
, (int)sipe_private
->do_not_publish
[activity
], (int)now
);
163 sipe_private
->do_not_publish
[activity
] = 0;
164 SIPE_DEBUG_INFO("sipe_core_status_set: set: sipe_private->do_not_publish[%s]=%d [0]",
165 status_id
, (int)sipe_private
->do_not_publish
[activity
]);
167 if (do_not_publish
) {
168 SIPE_DEBUG_INFO_NOFORMAT("sipe_core_status_set: publication was switched off, exiting.");
172 sipe_status_set_token(sipe_private
, status_id
);
174 /* hack to escape apostrof before comparison */
175 tmp
= note
? sipe_utils_str_replace(note
, "'", "'") : NULL
;
177 /* this will preserve OOF flag as well */
178 if (!sipe_strequal(tmp
, sipe_private
->note
)) {
179 SIPE_CORE_PRIVATE_FLAG_UNSET(OOF_NOTE
);
180 g_free(sipe_private
->note
);
181 sipe_private
->note
= g_strdup(note
);
182 sipe_private
->note_since
= time(NULL
);
186 /* schedule 2 sec to capture idle flag */
187 action_name
= g_strdup("<+set-status>");
188 sipe_schedule_seconds(sipe_private
,
198 * Whether user manually changed status or
199 * it was changed automatically due to user
200 * became inactive/active again
202 gboolean
sipe_status_changed_by_user(struct sipe_core_private
*sipe_private
)
205 time_t now
= time(NULL
);
207 SIPE_DEBUG_INFO("sipe_status_changed_by_user: sipe_private->idle_switch : %s",
208 asctime(localtime(&(sipe_private
->idle_switch
))));
209 SIPE_DEBUG_INFO("sipe_status_changed_by_user: now : %s",
210 asctime(localtime(&now
)));
212 res
= ((now
- SIPE_IDLE_SET_DELAY
* 2) >= sipe_private
->idle_switch
);
214 SIPE_DEBUG_INFO("sipe_status_changed_by_user: res = %s",
215 res
? "USER" : "MACHINE");
219 void sipe_core_status_idle(struct sipe_core_public
*sipe_public
)
221 struct sipe_core_private
*sipe_private
= SIPE_CORE_PRIVATE
;
223 sipe_private
->idle_switch
= time(NULL
);
224 SIPE_DEBUG_INFO("sipe_core_status_idle: sipe_private->idle_switch : %s",
225 asctime(localtime(&(sipe_private
->idle_switch
))));