Skip to content

Commit

Permalink
merged idle_presence branch. r302 to r312. When idle for more than X …
Browse files Browse the repository at this point in the history
…hours, buddy is set to offline
  • Loading branch information
neaveru committed Feb 5, 2010
1 parent 67d3c0c commit 5f398e2
Show file tree
Hide file tree
Showing 7 changed files with 161 additions and 34 deletions.
4 changes: 3 additions & 1 deletion config.h
Expand Up @@ -24,6 +24,9 @@
#define TWITTER_HOME_TIMELINE_INITIAL_COUNT 20
#define TWITTER_HOME_TIMELINE_PAGE_COUNT 100

//timer (mins) to check to see who hasn't said anything in X hours
#define TWITTER_UPDATE_PRESENCE_TIMEOUT 5

#define TWITTER_PROTOCOL_ID "prpl-twitter"

#define TWITTER_OAUTH_KEY "hrL4RlfT8MVOWbDdeY0EQ"
Expand All @@ -36,4 +39,3 @@

#define TWITTER_STATUS_ONLINE "online"
#define TWITTER_STATUS_OFFLINE "offline"

84 changes: 54 additions & 30 deletions twitter.c
Expand Up @@ -220,6 +220,27 @@ static gboolean twitter_get_friends_verify_error_cb(TwitterRequestor *r,
/******************************************************
* Twitter friends
******************************************************/
static gboolean twitter_update_presence_timeout(gpointer _account)
{
/* If someone is bored and wants to do this the right way,
* they would have a list of buddies sorted by time
* so we don't have to go through all buddies.
* Of course, then you'd have to have each PurpleBuddy point to
* the position in the list, so when a status gets updated
* we push the buddy back to the end of the list
*
* Additionally, we would want the timer to be reset to run
* at the time when the next buddy should go offline
* (min(last_tweet_time) - current_time)
*
* However, this should be good enough. If we find that this
* drains a lot of batteries on mobile phones (doubt it), then we can
* look back into it.
*/
PurpleAccount *account = _account;
twitter_buddy_touch_state_all(account);
return TRUE;
}

static void twitter_buddy_datas_set_all(PurpleAccount *account, GList *buddy_datas)
{
Expand All @@ -231,7 +252,7 @@ static void twitter_buddy_datas_set_all(PurpleAccount *account, GList *buddy_dat
TwitterTweet *status = twitter_user_tweet_take_tweet(data);

if (user)
twitter_buddy_set_user_data(account, user, TRUE);
twitter_buddy_set_user_data(account, user, twitter_option_get_following(account));
if (status)
twitter_buddy_set_status_data(account, data->screen_name, status);

Expand Down Expand Up @@ -450,6 +471,7 @@ static void twitter_endpoint_im_start_foreach(TwitterConnectionData *twitter, Tw
twitter_endpoint_im_start(im);
}


static void twitter_connected(PurpleAccount *account)
{
PurpleConnection *gc = purple_account_get_connection(account);
Expand Down Expand Up @@ -500,18 +522,21 @@ static void twitter_connected(PurpleAccount *account)
/* Immediately retrieve replies */

int get_friends_timer_timeout = twitter_option_user_status_timeout(account);
gboolean get_following = twitter_option_get_following(account);

/* Only update the buddy list if the user set the timeout to a positive number
* and the user wants to retrieve his following list */
if (get_friends_timer_timeout > 0 && get_following)
//We will try to get all our friends' statuses, whether they're in the buddylist or not
if (get_friends_timer_timeout > 0)
{
twitter->get_friends_timer = purple_timeout_add_seconds(
60 * get_friends_timer_timeout,
twitter_get_friends_timeout, account);
if (!twitter_option_get_following(account) && twitter_option_cutoff_time(account) > 0)
twitter_get_friends_timeout(account);
} else {
twitter->get_friends_timer = 0;
}
if (twitter_option_cutoff_time(account) > 0)
twitter->update_presence_timer = purple_timeout_add_seconds(
TWITTER_UPDATE_PRESENCE_TIMEOUT * 60, twitter_update_presence_timeout, account);
twitter_init_auto_open_contexts(account);
}
static void twitter_get_friends_verify_connection_cb(TwitterRequestor *r,
Expand Down Expand Up @@ -601,25 +626,27 @@ static char *twitter_status_text(PurpleBuddy *buddy) {

static void twitter_tooltip_text(PurpleBuddy *buddy,
PurpleNotifyUserInfo *info,
gboolean full) {
gboolean full)
{

if (PURPLE_BUDDY_IS_ONLINE(buddy))
PurplePresence *presence = purple_buddy_get_presence(buddy);
PurpleStatus *status = purple_presence_get_active_status(presence);
char *msg;

purple_debug_info(TWITTER_PROTOCOL_ID, "showing %s tooltip for %s\n",
(full) ? "full" : "short", buddy->name);

if ((msg = twitter_status_text(buddy)))
{
PurplePresence *presence = purple_buddy_get_presence(buddy);
PurpleStatus *status = purple_presence_get_active_status(presence);
char *msg = twitter_status_text(buddy);
purple_notify_user_info_add_pair(info, purple_status_get_name(status),
msg);
g_free(msg);
}

if (full) {
/*const char *user_info = purple_account_get_user_info(gc->account);
if (user_info)
purple_notify_user_info_add_pair(info, _("User info"), user_info);*/
}

purple_debug_info(TWITTER_PROTOCOL_ID, "showing %s tooltip for %s\n",
(full) ? "full" : "short", buddy->name);
if (full) {
/*const char *user_info = purple_account_get_user_info(gc->account);
if (user_info)
purple_notify_user_info_add_pair(info, _("User info"), user_info);*/
}
}

Expand Down Expand Up @@ -658,6 +685,8 @@ static GList *twitter_status_types(PurpleAccount *account)

type = purple_status_type_new(PURPLE_STATUS_OFFLINE, TWITTER_STATUS_OFFLINE,
TWITTER_STATUS_OFFLINE, TRUE);
purple_status_type_add_attr(type, "message", ("Offline"),
purple_value_new(PURPLE_TYPE_STRING));
types = g_list_prepend(types, type);

return g_list_reverse(types);
Expand Down Expand Up @@ -773,7 +802,8 @@ static void twitter_verify_connection(PurpleAccount *account)
NULL);
} else {
twitter_connected(account);
twitter_set_all_buddies_online(account);
if (twitter_option_cutoff_time(account) <= 0)
twitter_set_all_buddies_online(account);
}
}

Expand Down Expand Up @@ -1134,6 +1164,9 @@ static void twitter_close(PurpleConnection *gc)
g_hash_table_destroy(twitter->chat_contexts);
twitter->chat_contexts = NULL;

if (twitter->update_presence_timer)
purple_timeout_remove(twitter->update_presence_timer);

if (twitter->user_reply_id_table)
g_hash_table_destroy (twitter->user_reply_id_table);
twitter->user_reply_id_table = NULL;
Expand Down Expand Up @@ -1280,17 +1313,8 @@ static void twitter_set_status(PurpleAccount *account, PurpleStatus *status) {
static void twitter_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy,
PurpleGroup *group)
{
//TODO
//For the time being, if the user doesn't want to automatically download all their
//friends (people they follow), just assume the friend is valid and set them online
PurpleAccount *account = purple_connection_get_account(gc);
if (!twitter_option_get_following(account))
{
purple_prpl_got_user_status(account,
purple_buddy_get_name(buddy),
TWITTER_STATUS_ONLINE,
NULL);
}
//Perform the logic to decide whether this buddy will be online/offline
twitter_buddy_touch_state(buddy);
}

static void twitter_add_buddies(PurpleConnection *gc, GList *buddies,
Expand Down
81 changes: 80 additions & 1 deletion twitter_buddy.c
Expand Up @@ -11,11 +11,89 @@ TwitterUserTweet *twitter_buddy_get_buddy_data(PurpleBuddy *b)
return b->proto_data;
}

static time_t twitter_account_get_online_cutoff(PurpleAccount *account)
{
int cutoff_hours = twitter_option_cutoff_time(account);
if (cutoff_hours == 0)
return 0;
else
return time(NULL) - 60 * 60 * cutoff_hours;
}

static void twitter_buddy_change_state(PurpleBuddy *buddy, gboolean online, const gchar *message)
{
if (online == PURPLE_BUDDY_IS_ONLINE(buddy))
return;
purple_prpl_got_user_status(purple_buddy_get_account(buddy), buddy->name,
online ? TWITTER_STATUS_ONLINE : TWITTER_STATUS_OFFLINE,
"message", message,
NULL);
}

void twitter_buddy_touch_state_with_cutoff(PurpleBuddy *buddy, time_t cutoff)
{
PurpleAccount *account = purple_buddy_get_account(buddy);
TwitterUserTweet *user_tweet = twitter_buddy_get_buddy_data(buddy);
TwitterTweet *tweet = user_tweet ? user_tweet->status : NULL;
gchar *tweet_message = tweet ? tweet->text : NULL;

//Yes, I know this could be 'shorter'. But this is (somewhat) clearer
if (!cutoff) //Always set buddies to online
{
if (twitter_option_get_following(account) && !user_tweet)
{
//This user was added to the buddy list, but we aren't following them
//set the user offline
twitter_buddy_change_state(buddy, FALSE, tweet_message);
} else {
//Either get_following is true and the user_tweet has been seen, or
//get_following is false, so we just set them to online
twitter_buddy_change_state(buddy, TRUE, tweet_message);
}
} else {
if (!tweet || tweet->created_at < cutoff)
{
//No tweet or the tweet was created before the cutoff, set offline
twitter_buddy_change_state(buddy, FALSE, tweet_message);
} else {
//Tweet after the cutoff, set to online
twitter_buddy_change_state(buddy, TRUE, tweet_message);
}
}
}

void twitter_buddy_touch_state(PurpleBuddy *buddy)
{
PurpleAccount *account = purple_buddy_get_account(buddy);
time_t cutoff = twitter_account_get_online_cutoff(account);
twitter_buddy_touch_state_with_cutoff(buddy, cutoff);
}

void twitter_buddy_touch_state_all(PurpleAccount *account)
{
GSList *buddies;
GSList *b_node;
time_t cutoff = twitter_account_get_online_cutoff(account);

if (!cutoff)
return;

buddies = purple_find_buddies(account, NULL);

for (b_node = buddies; b_node; b_node = g_slist_next(b_node))
{
twitter_buddy_touch_state_with_cutoff((PurpleBuddy *) b_node->data, cutoff);
}

g_slist_free(buddies);
}

void twitter_buddy_set_status_data(PurpleAccount *account, const char *src_user, TwitterTweet *s)
{
PurpleBuddy *b;
TwitterUserTweet *buddy_data;
gboolean status_text_same = FALSE;
time_t cutoff = twitter_account_get_online_cutoff(account);

if (!s)
return;
Expand Down Expand Up @@ -52,7 +130,8 @@ void twitter_buddy_set_status_data(PurpleAccount *account, const char *src_user,

if (!status_text_same)
{
purple_prpl_got_user_status(b->account, b->name, TWITTER_STATUS_ONLINE,
purple_prpl_got_user_status(b->account, b->name,
cutoff && s && s->created_at < cutoff ? TWITTER_STATUS_OFFLINE : TWITTER_STATUS_ONLINE,
"message", s ? s->text : NULL, NULL);
}
}
Expand Down
3 changes: 3 additions & 0 deletions twitter_buddy.h
Expand Up @@ -11,4 +11,7 @@ void twitter_buddy_set_user_data(PurpleAccount *account, TwitterUserData *u, gbo
void twitter_buddy_update_icon_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data, const gchar *url_text, gsize len, const gchar *error_message);
void twitter_buddy_update_icon(PurpleBuddy *buddy);

void twitter_buddy_touch_state(PurpleBuddy *buddy);
void twitter_buddy_touch_state_all(PurpleAccount *account);

#endif
1 change: 1 addition & 0 deletions twitter_conn.h
Expand Up @@ -12,6 +12,7 @@ typedef struct
long long failed_get_replies_count;

guint get_friends_timer;
guint update_presence_timer;

long long last_home_timeline_id;

Expand Down
18 changes: 16 additions & 2 deletions twitter_prefs.c
Expand Up @@ -37,7 +37,7 @@ GList *twitter_get_protocol_options()
options = g_list_append(NULL, option);

option = purple_account_option_bool_new(
("Enable OAuth (more secure)"),
("Enable OAuth (more secure, higher rate limit)"),
TWITTER_PREF_USE_OAUTH,
TWITTER_PREF_USE_OAUTH_DEFAULT);
options = g_list_append(options, option);
Expand Down Expand Up @@ -65,7 +65,7 @@ GList *twitter_get_protocol_options()

/* Automatically generate a buddylist based on followers */
option = purple_account_option_bool_new (
("Add followers as friends (NOT recommended for large follower list)"),
("Add following as friends (NOT recommended for large follower list)"),
TWITTER_PREF_GET_FRIENDS,
TWITTER_PREF_GET_FRIENDS_DEFAULT);
options = g_list_append (options, option);
Expand All @@ -77,6 +77,14 @@ GList *twitter_get_protocol_options()
TWITTER_PREF_ADD_URL_TO_TWEET_DEFAULT);
options = g_list_append (options, option);

/* Idle cutoff time */
option = purple_account_option_int_new(
("Buddy last tweet hours before set offline (0: Always online)"), /* text shown to user */
TWITTER_ONLINE_CUTOFF_TIME_HOURS, /* pref name */
TWITTER_ONLINE_CUTOFF_TIME_HOURS_DEFAULT); /* default value */
options = g_list_append(options, option);


/* Max tweets to retrieve when retrieving timeline data */
option = purple_account_option_int_new(
("Max historical timeline tweets to retrieve (0: infinite)"), /* text shown to user */
Expand Down Expand Up @@ -275,3 +283,9 @@ const gchar *twitter_option_search_api_subdir(PurpleAccount *account)
TWITTER_PREF_SEARCH_API_BASE,
TWITTER_PREF_SEARCH_API_BASE_DEFAULT));
}
int twitter_option_cutoff_time(PurpleAccount *account)
{
return purple_account_get_int(account,
TWITTER_ONLINE_CUTOFF_TIME_HOURS,
TWITTER_ONLINE_CUTOFF_TIME_HOURS_DEFAULT);
}
4 changes: 4 additions & 0 deletions twitter_prefs.h
Expand Up @@ -74,6 +74,9 @@
#define TWITTER_PREF_SEARCH_API_BASE "twitter_search_api_base_url"
#define TWITTER_PREF_SEARCH_API_BASE_DEFAULT "search.twitter.com/"

#define TWITTER_ONLINE_CUTOFF_TIME_HOURS "online_cutoff_time_hours"
#define TWITTER_ONLINE_CUTOFF_TIME_HOURS_DEFAULT 24

/***** START URLS *****/
#define TWITTER_PREF_URL_GET_RATE_LIMIT_STATUS "/account/rate_limit_status.xml"
#define TWITTER_PREF_URL_GET_FRIENDS "/statuses/friends.xml"
Expand Down Expand Up @@ -109,4 +112,5 @@ const gchar *twitter_option_api_host(PurpleAccount *account);
const gchar *twitter_option_api_subdir(PurpleAccount *account);
const gchar *twitter_option_search_api_host(PurpleAccount *account);
const gchar *twitter_option_search_api_subdir(PurpleAccount *account);
int twitter_option_cutoff_time(PurpleAccount *account);
#endif

0 comments on commit 5f398e2

Please sign in to comment.