📄 cap.c
字号:
purple_status_get_id(get_status_for(stats->buddy)); struct tm *current_time = localtime(&stats->last_message); int minute = current_time->tm_min + current_time->tm_hour * 60; insert_cap_msg_count_failed(buddy_name, account_id, protocol_id, minute); insert_cap_status_count_failed(buddy_name, account_id, protocol_id, status_id); stats->last_message = -1; stats->last_message_status_id = NULL;}static gboolean max_message_difference_cb(gpointer data) { CapStatistics *stats = data; purple_debug_info("cap", "Max Message Difference timeout occured\n"); insert_cap_failure(stats); stats->timeout_source_id = 0; return FALSE;}/* Purple Signal Handlers *//* sent-im-msg */static void sent_im_msg(PurpleAccount *account, const char *receiver, const char *message) { PurpleBuddy *buddy; guint interval, words; CapStatistics *stats = NULL; buddy = purple_find_buddy(account, receiver); if (buddy == NULL) return; interval = purple_prefs_get_int("/plugins/gtk/cap/max_msg_difference") * 1000 * 60; words = word_count(message); stats = get_stats_for(buddy); insert_word_count(purple_account_get_username(account), receiver, words); stats->last_message = time(NULL); stats->last_message_status_id = purple_status_get_id(get_status_for(buddy)); if(stats->timeout_source_id != 0) g_source_remove(stats->timeout_source_id); stats->timeout_source_id = g_timeout_add(interval, max_message_difference_cb, stats);}/* received-im-msg */static voidreceived_im_msg(PurpleAccount *account, char *sender, char *message, PurpleConversation *conv, PurpleMessageFlags flags) { PurpleBuddy *buddy; CapStatistics *stats; /* guint words = word_count(message); */ buddy = purple_find_buddy(account, sender); if (buddy == NULL) return; stats = get_stats_for(buddy); /* insert_word_count(sender, buddy_name, words); */ /* If we are waiting for a response from a prior message * then cancel the timeout callback. */ if(stats->timeout_source_id != 0) { purple_debug_info("cap", "Cancelling timeout callback\n"); g_source_remove(stats->timeout_source_id); stats->timeout_source_id = 0; } insert_cap_success(stats); /* Reset the last_message value */ stats->last_message = -1; /* Reset the last status id value */ stats->last_message_status_id = NULL;}/* buddy-status-changed */static void buddy_status_changed(PurpleBuddy *buddy, PurpleStatus *old_status, PurpleStatus *status) { CapStatistics *stats = get_stats_for(buddy); insert_status_change_from_purple_status(stats, status);}/* buddy-signed-on */static void buddy_signed_on(PurpleBuddy *buddy) { CapStatistics *stats = get_stats_for(buddy); /* If the statistic object existed but doesn't have a buddy pointer associated * with it then reassociate one with it. The pointer being null is a result * of a buddy with existing stats signing off and Purple sticking around. */ if(!stats->buddy) { stats->buddy = buddy; } insert_status_change(stats);}/* buddy-signed-off */static void buddy_signed_off(PurpleBuddy *buddy) { CapStatistics *stats = get_stats_for(buddy); /* We don't necessarily want to delete a buddies generated statistics every time they go offline. * Instead we just set the buddy pointer to null so that when they come back online we can look * them up again and continue using their statistics. */ insert_status_change(stats); /* stats->buddy = NULL; */ stats->last_seen = time(NULL);}static void buddy_idle(PurpleBuddy *buddy, gboolean old_idle, gboolean idle) {}static void blist_node_extended_menu(PurpleBlistNode *node, GList **menu) { PurpleBuddy *buddy; PurpleMenuAction *menu_action; purple_debug_info("cap", "got extended blist menu\n"); purple_debug_info("cap", "is buddy: %d\n", PURPLE_BLIST_NODE_IS_BUDDY(node)); purple_debug_info("cap", "is contact: %d\n", PURPLE_BLIST_NODE_IS_CONTACT(node)); purple_debug_info("cap", "is group: %d\n", PURPLE_BLIST_NODE_IS_GROUP(node)); /* Probably only concerned with buddy/contact types. Contacts = meta-buddies (grouped msn/jabber/etc.) */ g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node)); buddy = (PurpleBuddy *)node; menu_action = purple_menu_action_new(_("Display Statistics"), PURPLE_CALLBACK(display_statistics_action_cb), NULL, NULL); *menu = g_list_append(*menu, menu_action);}/* drawing-tooltip */static void drawing_tooltip(PurpleBlistNode *node, GString *text, gboolean full) { if(node->type == PURPLE_BLIST_BUDDY_NODE) { PurpleBuddy *buddy = (PurpleBuddy *)node; CapStatistics *stats = get_stats_for(buddy); /* get the probability that this buddy will respond and add to the tooltip */ if(stats->prediction->probability >= 0.0) { g_string_append_printf(text, "\n<b>%s</b> %3.0f %%", _("Response Probability:"), 100 * stats->prediction->probability); } else { g_string_append_printf(text, "\n<b>%s</b> ???", _("Response Probability:")); } }}/* signed-on */static void signed_on(PurpleConnection *gc) { PurpleAccount *account = purple_connection_get_account(gc); const char *my_purple_name = purple_account_get_username(account); gchar *my_name = g_strdup(my_purple_name); time_t *last_offline = g_hash_table_lookup(_my_offline_times, my_name); const gchar *account_id = purple_account_get_username(account); const gchar *protocol_id = purple_account_get_protocol_id(account); char *sql; sql = sqlite3_mprintf("insert into cap_my_usage values(%Q, %Q, %d, now());", account_id, protocol_id, 1); sqlite3_exec(_db, sql, NULL, NULL, NULL); sqlite3_free(sql); if(last_offline) { if(difftime(*last_offline, time(NULL)) > purple_prefs_get_int("/plugins/gtk/cap/max_seen_difference") * 60) { /* reset all of the last_message times to -1 */ g_hash_table_foreach(_my_offline_times, reset_all_last_message_times, NULL); } g_hash_table_remove(_my_offline_times, my_name); } g_free(my_name);}/* signed-off */static void signed_off(PurpleConnection *gc) { /* Here we record the time you (the user) sign off of an account. * The account username is the key in the hashtable and the sign off time_t * (equal to the sign off time) is the value. */ PurpleAccount *account = purple_connection_get_account(gc); const char *my_purple_name = purple_account_get_username(account); gchar *my_name = g_strdup(my_purple_name); time_t *offline_time = g_malloc(sizeof(time_t)); const gchar *account_id = purple_account_get_username(account); const gchar *protocol_id = purple_account_get_protocol_id(account); char *sql; sql = sqlite3_mprintf("insert into cap_my_usage values(%Q, %Q, %d, now());", account_id, protocol_id, 0); sqlite3_exec(_db, sql, NULL, NULL, NULL); sqlite3_free(sql); time(offline_time); g_hash_table_insert(_my_offline_times, my_name, offline_time);}static void reset_all_last_message_times(gpointer key, gpointer value, gpointer user_data) { CapStatistics *stats = value; stats->last_message = -1;}static PurpleStatus * get_status_for(PurpleBuddy *buddy) { PurplePresence *presence = purple_buddy_get_presence(buddy); PurpleStatus *status = purple_presence_get_active_status(presence); return status;}static void create_tables() { int rc; rc = sqlite3_exec(_db, "CREATE TABLE IF NOT EXISTS cap_status (" " buddy varchar(60) not null," " account varchar(60) not null," " protocol varchar(60) not null," " status varchar(60) not null," " event_time datetime not null," " primary key (buddy, account, protocol, event_time)" ");", NULL, NULL, NULL); rc = sqlite3_exec(_db, "create table if not exists cap_message (" " sender varchar(60) not null," " receiver varchar(60) not null," " account varchar(60) not null," " protocol varchar(60) not null," " word_count integer not null," " event_time datetime not null," " primary key (sender, account, protocol, receiver, event_time)" ");", NULL, NULL, NULL); rc = sqlite3_exec(_db, "create table if not exists cap_msg_count (" " buddy varchar(60) not null," " account varchar(60) not null," " protocol varchar(60) not null," " minute_val int not null," " success_count int not null," " failed_count int not null," " primary key (buddy, account, protocol, minute_val)" ");", NULL, NULL, NULL); rc = sqlite3_exec(_db, "create table if not exists cap_status_count (" " buddy varchar(60) not null," " account varchar(60) not null," " protocol varchar(60) not null," " status varchar(60) not null," " success_count int not null," " failed_count int not null," " primary key (buddy, account, protocol, status)" ");", NULL, NULL, NULL); rc = sqlite3_exec(_db, "create table if not exists cap_my_usage (" " account varchar(60) not null," " protocol varchar(60) not null," " online tinyint not null," " event_time datetime not null," " primary key(account, protocol, online, event_time)" ");", NULL, NULL, NULL);}static gboolean create_database_connection() { gchar *path; int rc; if(_db) return TRUE; /* build the path */ path = g_build_filename(purple_user_dir(), "cap.db", (gchar *)NULL); /* make database connection here */ rc = sqlite3_open(path, &_db); g_free(path); if(rc != SQLITE_OK) return FALSE; /* Add tables here */ create_tables(); purple_debug_info("cap", "Database connection successfully made.\n"); return TRUE;}static void destroy_database_connection() { if(_db) sqlite3_close(_db); _db = NULL;}static guint word_count(const gchar *string) { /*TODO: doesn't really work, should use regex instead (#include <regex.h>)*/ gchar **result = g_strsplit_set(string, " ", -1); guint count = g_strv_length(result); g_strfreev(result); return count;}static void insert_status_change(CapStatistics *statistics) { insert_status_change_from_purple_status(statistics, get_status_for(statistics->buddy));}static void insert_status_change_from_purple_status(CapStatistics *statistics, PurpleStatus *status) { char *sql; int rc; const gchar *status_id; const gchar *buddy_name; const gchar *protocol_id; const gchar *account_id; /* It would seem that some protocols receive periodic updates of the buddies status. * Check to make sure the last status is not the same as current status to prevent * to many duplicated useless database entries. */ if(strcmp(statistics->last_status_id, purple_status_get_id(status)) == 0) return; status_id = purple_status_get_id(status); buddy_name = statistics->buddy->name; protocol_id = purple_account_get_protocol_id(statistics->buddy->account); account_id = purple_account_get_username(statistics->buddy->account);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -