pidgin/purple-plugin-pack
Apparently okcupid has been broke for awhile, so lets remove it instead
Testing Done:
ran ninja and ninja plugin_pack-pot
Reviewed at https://reviews.imfreedom.org/r/2407/
--- a/meson.build Thu Mar 30 22:35:56 2023 -0500
+++ b/meson.build Thu Mar 30 22:53:31 2023 -0500
@@ -180,7 +180,6 @@
Binary file okcupid/16/okcupid.png has changed
Binary file okcupid/22/okcupid.png has changed
Binary file okcupid/48/okcupid.png has changed
--- a/okcupid/README.md Thu Mar 30 22:35:56 2023 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-# OkCupid Protocol Plugin
-dependencies: libpurplem, json-glib
-Protocol plugin for the OkCupid social networking site framework
--- a/okcupid/meson.build Thu Mar 30 22:35:56 2023 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,23 +0,0 @@
-if TYPES.contains('default') and PURPLE.found() and JSON_GLIB.found() and ZLIB.found()
- okcupid = shared_library('okcupid',
- dependencies : [PURPLE, JSON_GLIB, GLIB, ZLIB],
- install_dir : PURPLE_LIBDIR)
- PP_PURPLE_BUILD += 'okcupid'
- foreach size : [16, 22, 48]
- install_data('@0@/okcupid.png'.format(size),
- install_dir : join_paths(PIDGIN_PIXMAPSDIR, 'protocols/@0@'.format(size)))
--- a/okcupid/okc_blist.c Thu Mar 30 22:35:56 2023 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,267 +0,0 @@
- * libokcupid is the property of its developers. See the COPYRIGHT file
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "okc_connection.h"
-#include "okc_messages.h"
-void okc_blist_wink_buddy(PurpleBlistNode *node, gpointer data)
- if(!PURPLE_BLIST_NODE_IS_BUDDY(node))
- buddy = (PurpleBuddy *) node;
- if (!buddy || !buddy->account)
- pc = purple_account_get_connection(buddy->account);
- if (!pc || !pc->proto_data)
- postdata = g_strdup_printf("woo=1&u=%s&ajax=1", purple_url_encode(buddy->name));
- okc_post_or_get(oca, OKC_METHOD_POST, NULL, "/profile", postdata, NULL, NULL, FALSE);
-void okc_got_info(OkCupidAccount *oca, gchar *data,
- gsize data_len, gpointer userdata)
- gchar *username = userdata;
- PurpleNotifyUserInfo *user_info;
- if (!data || !data_len)
- purple_debug_info("okcupid", "okc_got_info: %s\n", data);
- user_info = purple_notify_user_info_new();
- /* Insert link to profile at top */
- value_tmp = g_strdup_printf("<a href=\"http://www.okcupid.com/profile/%s\">%s</a>",
- username, _("View web profile"));
- purple_notify_user_info_add_pair(user_info, NULL, value_tmp);
- purple_notify_user_info_add_section_break(user_info);
- parser = json_parser_new();
- if(!json_parser_load_from_data(parser, data, data_len, &error))
- purple_debug_error("okcupid", "got_info error: %s\n", error->message);
- purple_notify_userinfo(oca->pc, username, user_info, NULL, NULL);
- purple_notify_user_info_destroy(user_info);
- root = json_parser_get_root(parser);
- info = json_node_get_object(root);
- if (json_object_get_member(info, "error"))
- purple_debug_error("okcupid", "got_info error\n");
- purple_notify_userinfo(oca->pc, username, user_info, NULL, NULL);
- purple_notify_user_info_destroy(user_info);
- value_tmp = g_strdup_printf("%" G_GINT64_FORMAT " years", json_node_get_int(json_object_get_member(info, "age")));
- purple_notify_user_info_add_pair(user_info, _("Age"), value_tmp);
- purple_notify_user_info_add_pair(user_info, _("Gender"), json_node_get_string(json_object_get_member(info, "sex")));
- purple_notify_user_info_add_pair(user_info, _("Sexual Preference"), json_node_get_string(json_object_get_member(info, "orientation")));
- purple_notify_user_info_add_pair(user_info, _("Relationship Status"), json_node_get_string(json_object_get_member(info, "status")));
- purple_notify_user_info_add_pair(user_info, _("Location"), json_node_get_string(json_object_get_member(info, "location")));
- value_tmp = g_strdup_printf("%" G_GINT64_FORMAT "%%", json_node_get_int(json_object_get_member(info, "matchpercentage")));
- purple_notify_user_info_add_pair(user_info, _("Match"), value_tmp);
- value_tmp = g_strdup_printf("%" G_GINT64_FORMAT "%%", json_node_get_int(json_object_get_member(info, "friendpercentage")));
- purple_notify_user_info_add_pair(user_info, _("Friend"), value_tmp);
- value_tmp = g_strdup_printf("%" G_GINT64_FORMAT "%%", json_node_get_int(json_object_get_member(info, "enemypercentage")));
- purple_notify_user_info_add_pair(user_info, _("Enemy"), value_tmp);
- const gchar *buddy_icon = json_node_get_string(json_object_get_member(info, "thumbnail"));
- PurpleBuddy *buddy = purple_find_buddy(oca->account, username);
- OkCupidBuddy *obuddy = buddy->proto_data;
- obuddy = g_new0(OkCupidBuddy, 1);
- // load the old buddy icon url from the icon 'checksum'
- const gchar *buddy_icon_url = purple_buddy_icons_get_checksum_for_user(buddy);
- if (buddy_icon_url != NULL)
- obuddy->thumb_url = g_strdup(buddy_icon_url);
- buddy->proto_data = obuddy;
- if (!obuddy->thumb_url || !g_str_equal(obuddy->thumb_url, buddy_icon))
- gchar *host, *path, *path2;
- gchar *large_image_url;
- g_free(obuddy->thumb_url);
- obuddy->thumb_url = g_strdup(buddy_icon);
- large_image_url = purple_strreplace(buddy_icon, "/60x60/", "/256x256/");
- purple_url_parse(large_image_url, &host, NULL, &path, NULL, NULL);
- g_free(large_image_url);
- path2 = g_strdup_printf("/%s", path);
- path2 = g_strdup(path);
- okc_post_or_get(oca, OKC_METHOD_GET, host, path2, NULL, okc_buddy_icon_cb, g_strdup(username), FALSE);
- purple_notify_user_info_add_section_break(user_info);
- purple_notify_user_info_add_section_header(user_info, _("The Skinny"));
- info = json_node_get_object(json_object_get_member(info, "skinny"));
- purple_notify_user_info_add_pair(user_info, _("Last Online"), json_node_get_string(json_object_get_member(info, "last_online")));
- purple_notify_user_info_add_pair(user_info, _("Join Date"), json_node_get_string(json_object_get_member(info, "join_date")));
- purple_notify_user_info_add_pair(user_info, _("Ethnicity"), json_node_get_string(json_object_get_member(info, "ethnicities")));
- purple_notify_user_info_add_pair(user_info, _("Height"), json_node_get_string(json_object_get_member(info, "height")));
- purple_notify_user_info_add_pair(user_info, _("Body Type"), json_node_get_string(json_object_get_member(info, "bodytype")));
- purple_notify_user_info_add_pair(user_info, _("Looking For"), json_node_get_string(json_object_get_member(info, "lookingfor")));
- purple_notify_user_info_add_pair(user_info, _("Smokes"), json_node_get_string(json_object_get_member(info, "smoker")));
- purple_notify_user_info_add_pair(user_info, _("Drinks"), json_node_get_string(json_object_get_member(info, "drinker")));
- purple_notify_user_info_add_pair(user_info, _("Drugs"), json_node_get_string(json_object_get_member(info, "drugs")));
- if (json_object_has_member(info, "religion"))
- value_tmp = g_strdup_printf("%s %s", json_node_get_string(json_object_get_member(info, "religion")),
- json_node_get_string(json_object_get_member(info, "religionserious")));
- purple_notify_user_info_add_pair(user_info, _("Religion"), value_tmp);
- value_tmp = g_strdup_printf("%s %s", json_node_get_string(json_object_get_member(info, "sign")),
- json_node_get_string(json_object_get_member(info, "sign_status")));
- purple_notify_user_info_add_pair(user_info, _("Star sign"), value_tmp);
- value_tmp = g_strdup_printf("%s %s", json_node_get_string(json_object_get_member(info, "education_status")),
- json_node_get_string(json_object_get_member(info, "education")));
- purple_notify_user_info_add_pair(user_info, _("Education"), value_tmp);
- purple_notify_user_info_add_pair(user_info, _("Job"), json_node_get_string(json_object_get_member(info, "job")));
- purple_notify_user_info_add_pair(user_info, _("Income"), json_node_get_string(json_object_get_member(info, "income")));
- purple_notify_user_info_add_pair(user_info, _("Kids"), json_node_get_string(json_object_get_member(info, "children")));
- value_tmp = g_strdup_printf("%s and %s", json_node_get_string(json_object_get_member(info, "dogs")),
- json_node_get_string(json_object_get_member(info, "cats")));
- purple_notify_user_info_add_pair(user_info, _("Pets"), value_tmp);
- purple_notify_user_info_add_pair(user_info, _("Languages"), json_node_get_string(json_object_get_member(info, "languagestr")));
- purple_notify_userinfo(oca->pc, username, user_info, NULL, NULL);
- purple_notify_user_info_destroy(user_info);
- g_object_unref(parser);
-void okc_get_info(PurpleConnection *pc, const gchar *uid)
- profile_url = g_strdup_printf("/profile/%s?json=2", purple_url_encode(uid));
- okc_post_or_get(pc->proto_data, OKC_METHOD_GET, NULL, profile_url, NULL, okc_got_info, g_strdup(uid), FALSE);
-void okc_add_buddy(PurpleConnection *pc, PurpleBuddy *buddy, PurpleGroup *group)
- postdata = g_strdup_printf("addbuddy=1&u=%s&ajax=1", purple_url_encode(buddy->name));
- okc_post_or_get(pc->proto_data, OKC_METHOD_POST, NULL, "/profile", postdata, NULL, NULL, FALSE);
-void okc_remove_buddy(PurpleConnection *pc, PurpleBuddy *buddy, PurpleGroup *group)
- postdata = g_strdup_printf("removebuddy=1&u=%s&ajax=1", purple_url_encode(buddy->name));
- okc_post_or_get(pc->proto_data, OKC_METHOD_POST, NULL, "/profile", postdata, NULL, NULL, FALSE);
-void okc_block_buddy(PurpleConnection *pc, const char *name)
- block_url = g_strdup_printf("/instantevents?im_block=1&target_screenname=%s", purple_url_encode(name));
- okc_post_or_get(pc->proto_data, OKC_METHOD_GET, NULL, block_url, NULL, NULL, NULL, FALSE);
-GList *okc_blist_node_menu(PurpleBlistNode *node)
- if(PURPLE_BLIST_NODE_IS_BUDDY(node))
- act = purple_menu_action_new(_("_Wink"),
- PURPLE_CALLBACK(okc_blist_wink_buddy),
- m = g_list_append(m, act);
- } else if (PURPLE_BLIST_NODE_IS_CHAT(node))
- } else if (PURPLE_BLIST_NODE_IS_GROUP(node))
--- a/okcupid/okc_blist.h Thu Mar 30 22:35:56 2023 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
- * libokcupid is the property of its developers. See the COPYRIGHT file
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
-void okc_blist_wink_buddy(PurpleBlistNode *node, gpointer data);
-void okc_get_info(PurpleConnection *pc, const gchar *uid);
-void okc_add_buddy(PurpleConnection *pc, PurpleBuddy *buddy, PurpleGroup *group);
-void okc_remove_buddy(PurpleConnection *pc, PurpleBuddy *buddy, PurpleGroup *group);
-void okc_block_buddy(PurpleConnection *, const char *name);
-GList *okc_blist_node_menu(PurpleBlistNode *node);
-#endif /* OKCUPID_BLIST_H */
--- a/okcupid/okc_connection.c Thu Mar 30 22:35:56 2023 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,659 +0,0 @@
- * libokcupid is the property of its developers. See the COPYRIGHT file
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "okc_connection.h"
-static void okc_attempt_connection(OkCupidConnection *);
-static void okc_next_connection(OkCupidAccount *oca);
-static gchar *okc_gunzip(const guchar *gzip_data, ssize_t *len_ptr)
- gsize gzip_data_len = *len_ptr;
- gulong gzip_len = G_MAXUINT16;
- GString *output_string = NULL;
- data_buffer = g_new0(gchar, gzip_len);
- gzip_err = inflateInit2(&zstr, MAX_WBITS+32);
- purple_debug_error("okcupid", "no built-in gzip support in zlib\n");
- zstr.next_in = (Bytef *)gzip_data;
- zstr.avail_in = gzip_data_len;
- zstr.next_out = (Bytef *)data_buffer;
- zstr.avail_out = gzip_len;
- gzip_err = inflate(&zstr, Z_SYNC_FLUSH);
- if (gzip_err == Z_DATA_ERROR)
- inflateInit2(&zstr, -MAX_WBITS);
- purple_debug_error("okcupid", "Cannot decode gzip header\n");
- zstr.next_in = (Bytef *)gzip_data;
- zstr.avail_in = gzip_data_len;
- zstr.next_out = (Bytef *)data_buffer;
- zstr.avail_out = gzip_len;
- gzip_err = inflate(&zstr, Z_SYNC_FLUSH);
- output_string = g_string_new("");
- while (gzip_err == Z_OK)
- //append data to buffer
- output_string = g_string_append_len(output_string, data_buffer, gzip_len - zstr.avail_out);
- zstr.next_out = (Bytef *)data_buffer;
- zstr.avail_out = gzip_len;
- gzip_err = inflate(&zstr, Z_SYNC_FLUSH);
- if (gzip_err == Z_STREAM_END)
- output_string = g_string_append_len(output_string, data_buffer, gzip_len - zstr.avail_out);
- purple_debug_error("okcupid", "gzip inflate error\n");
- gchar *output_data = g_strdup(output_string->str);
- *len_ptr = output_string->len;
- g_string_free(output_string, TRUE);
-void okc_connection_destroy(OkCupidConnection *okconn)
- okconn->oca->conns = g_slist_remove(okconn->oca->conns, okconn);
- if (okconn->request != NULL)
- g_string_free(okconn->request, TRUE);
- g_free(okconn->rx_buf);
- if (okconn->connect_data != NULL)
- purple_proxy_connect_cancel(okconn->connect_data);
- if (okconn->ssl_conn != NULL)
- purple_ssl_close(okconn->ssl_conn);
- if (okconn->input_watcher > 0)
- purple_input_remove(okconn->input_watcher);
- g_free(okconn->hostname);
-static void okc_update_cookies(OkCupidAccount *oca, const gchar *headers)
- const gchar *cookie_start;
- const gchar *cookie_end;
- g_return_if_fail(headers != NULL);
- header_len = strlen(headers);
- /* look for the next "Set-Cookie: " */
- /* grab the data up until ';' */
- cookie_start = headers;
- while ((cookie_start = strstr(cookie_start, "\r\nSet-Cookie: ")) &&
- (headers-cookie_start) < header_len)
- cookie_end = strchr(cookie_start, '=');
- cookie_name = g_strndup(cookie_start, cookie_end-cookie_start);
- cookie_start = cookie_end + 1;
- cookie_end = strchr(cookie_start, ';');
- cookie_value= g_strndup(cookie_start, cookie_end-cookie_start);
- cookie_start = cookie_end;
- purple_debug_info("okcupid", "got cookie %s=%s\n",
- cookie_name, cookie_value);
- g_hash_table_replace(oca->cookie_table, cookie_name,
-static void okc_connection_process_data(OkCupidConnection *okconn)
- tmp = g_strstr_len(okconn->rx_buf, len, "\r\n\r\n");
- /* This is a corner case that occurs when the connection is
- * prematurely closed either on the client or the server.
- * This can either be no data at all or a partial set of
- * headers. We pass along the data to be good, but don't
- * do any fancy massaging. In all likelihood the result will
- * be tossed by the connection callback func anyways
- tmp = g_strndup(okconn->rx_buf, len);
- len -= g_strstr_len(okconn->rx_buf, len, "\r\n\r\n") -
- tmp = g_memdup(tmp, len + 1);
- okconn->rx_buf[okconn->rx_len - len] = '\0';
- //purple_debug_misc("okcupid", "response headers\n%s\n",
- okc_update_cookies(okconn->oca, okconn->rx_buf);
- if (strstr(okconn->rx_buf, "Content-Encoding: gzip"))
- /* we've received compressed gzip data, decompress */
- gunzipped = okc_gunzip((const guchar *)tmp, &len);
- g_free(okconn->rx_buf);
- if (okconn->callback != NULL)
- okconn->callback(okconn->oca, tmp, len, okconn->user_data);
-static void okc_fatal_connection_cb(OkCupidConnection *okconn)
- PurpleConnection *pc = okconn->oca->pc;
- purple_debug_error("okcupid", "fatal connection error\n");
- okc_connection_destroy(okconn);
- /* We died. Do not pass Go. Do not collect $200 */
- /* In all seriousness, don't attempt to call the normal callback here.
- * That may lead to the wrong error message being displayed */
- purple_connection_error_reason(pc,
- PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
- _("Server closed the connection."));
-static void okc_post_or_get_readdata_cb(gpointer data, gint source,
- PurpleInputCondition cond)
- OkCupidConnection *okconn;
- if (okconn->method & OKC_METHOD_SSL) {
- len = purple_ssl_read(okconn->ssl_conn,
- len = recv(okconn->fd, buf, sizeof(buf) - 1, 0);
- if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) {
- if (okconn->method & OKC_METHOD_SSL && okconn->rx_len > 0) {
- * This is a slightly hacky workaround for a bug in either
- * GNU TLS or in the SSL implementation on Facebook's web
- * servers. The sequence of events is:
- * 1. We attempt to read the first time and successfully read
- * the server's response.
- * 2. We attempt to read a second time and libpurple's call
- * to gnutls_record_recv() returns the error
- * GNUTLS_E_UNEXPECTED_PACKET_LENGTH, or
- * "A TLS packet with unexpected length was received."
- * Normally the server would have closed the connection
- * cleanly and this second read() request would have returned
- * 0. Or maybe it's normal for SSL connections to be severed
- * in this manner? In any case, this differs from the behavior
- * of the standard recv() system call.
- purple_debug_warning("okcupid",
- "ssl error, but data received. attempting to continue\n");
- /* TODO: Is this a regular occurrence? If so then maybe resend the request? */
- okc_fatal_connection_cb(okconn);
- okconn->rx_buf = g_realloc(okconn->rx_buf,
- okconn->rx_len + len + 1);
- memcpy(okconn->rx_buf + okconn->rx_len, buf, len + 1);
- /* Wait for more data before processing */
- /* The server closed the connection, let's parse the data */
- okc_connection_process_data(okconn);
- okc_connection_destroy(okconn);
- okc_next_connection(oca);
-static void okc_post_or_get_ssl_readdata_cb (gpointer data,
- PurpleSslConnection *ssl, PurpleInputCondition cond)
- okc_post_or_get_readdata_cb(data, -1, cond);
-static void okc_post_or_get_connect_cb(gpointer data, gint source,
- const gchar *error_message)
- OkCupidConnection *okconn;
- okconn->connect_data = NULL;
- purple_debug_error("okcupid", "post_or_get_connect_cb %s\n",
- okc_fatal_connection_cb(okconn);
- purple_debug_info("okcupid", "post_or_get_connect_cb\n");
- len = write(okconn->fd, okconn->request->str,
- if(len != okconn->request->len) {
- purple_debug_error("okcupid", "post_or_get_connect_cb failed to write request\n");
- okc_fatal_connection_cb(okconn);
- okconn->input_watcher = purple_input_add(okconn->fd,
- okc_post_or_get_readdata_cb, okconn);
-static void okc_post_or_get_ssl_connect_cb(gpointer data,
- PurpleSslConnection *ssl, PurpleInputCondition cond)
- OkCupidConnection *okconn;
- purple_debug_info("okcupid", "post_or_get_ssl_connect_cb\n");
- len = purple_ssl_write(okconn->ssl_conn,
- okconn->request->str, okconn->request->len);
- if(len != okconn->request->len) {
- purple_debug_error("okcupid", "post_or_get_ssl_connect_cb failed to write request\n");
- okc_fatal_connection_cb(okconn);
- purple_ssl_input_add(okconn->ssl_conn,
- okc_post_or_get_ssl_readdata_cb, okconn);
-static void okc_host_lookup_cb(GSList *hosts, gpointer data,
- const char *error_message)
- GSList *host_lookup_list;
- struct sockaddr_in *addr;
- PurpleDnsQueryData *query;
- purple_debug_info("okcupid", "updating cache of dns addresses\n");
- /* Extract variables */
- host_lookup_list = data;
- oca = host_lookup_list->data;
- g_slist_delete_link(host_lookup_list, host_lookup_list);
- hostname = host_lookup_list->data;
- g_slist_delete_link(host_lookup_list, host_lookup_list);
- query = host_lookup_list->data;
- g_slist_delete_link(host_lookup_list, host_lookup_list);
- /* The callback has executed, so we no longer need to keep track of
- * the original query. This always needs to run when the cb is
- oca->dns_queries = g_slist_remove(oca->dns_queries, query);
- /* Any problems, capt'n? */
- if (error_message != NULL)
- purple_debug_warning("okcupid",
- "Error doing host lookup: %s\n", error_message);
- purple_debug_warning("okcupid",
- "Could not resolve host name\n");
- /* Discard the length... */
- hosts = g_slist_delete_link(hosts, hosts);
- /* Copy the address then free it... */
- ip_address = g_strdup(inet_ntoa(addr->sin_addr));
- hosts = g_slist_delete_link(hosts, hosts);
- * DNS lookups can return a list of IP addresses, but we only cache
- * the first one. So free the rest.
- /* Discard the length... */
- hosts = g_slist_delete_link(hosts, hosts);
- /* Free the address... */
- hosts = g_slist_delete_link(hosts, hosts);
- purple_debug_info("okcupid", "Host %s has IP %s\n",
- g_hash_table_insert(oca->hostname_ip_cache, hostname, ip_address);
-static void okc_cookie_foreach_cb(gchar *cookie_name,
- gchar *cookie_value, GString *str)
- /* TODO: Need to escape name and value? */
- g_string_append_printf(str, "%s=%s;", cookie_name, cookie_value);
-static gchar *okc_cookies_to_string(OkCupidAccount *oca)
- str = g_string_new(NULL);
- g_hash_table_foreach(oca->cookie_table,
- (GHFunc)okc_cookie_foreach_cb, str);
- return g_string_free(str, FALSE);
-static void okc_ssl_connection_error(PurpleSslConnection *ssl,
- PurpleSslErrorType errortype, gpointer data)
- OkCupidConnection *okconn = data;
- PurpleConnection *pc = okconn->oca->pc;
- okconn->ssl_conn = NULL;
- okc_connection_destroy(okconn);
- purple_connection_ssl_error(pc, errortype);
-void okc_post_or_get(OkCupidAccount *oca, OkCupidMethod method,
- const gchar *host, const gchar *url, const gchar *postdata,
- OkCupidProxyCallbackFunc callback_func, gpointer user_data,
- OkCupidConnection *okconn;
- gboolean is_proxy = FALSE;
- const gchar* const *languages;
- PurpleProxyInfo *proxy_info = NULL;
- gchar *proxy_auth_base64;
- /* TODO: Fix keepalive and use it as much as possible */
- if (purple_account_get_bool(oca->account, "force_https", TRUE) && !(method & OKC_METHOD_SSL) &&
- (!host || g_str_equal(host, "www.okcupid.com") || g_str_equal(host, "api.okcupid.com")))
- method |= OKC_METHOD_SSL;
- if (method & OKC_METHOD_SSL)
- host = "www.okcupid.com";
- if (host == NULL && oca && oca->account)
- host = purple_account_get_string(oca->account, "host", "api.okcupid.com");
- host = "api.okcupid.com";
- if (oca && oca->account && !(method & OKC_METHOD_SSL))
- proxy_info = purple_proxy_get_setup(oca->account);
- if (purple_proxy_info_get_type(proxy_info) == PURPLE_PROXY_USE_GLOBAL)
- proxy_info = purple_global_proxy_get_info();
- if (purple_proxy_info_get_type(proxy_info) == PURPLE_PROXY_HTTP)
- real_url = g_strdup_printf("http://%s%s", host, url);
- real_url = g_strdup(url);
- cookies = okc_cookies_to_string(oca);
- if (method & OKC_METHOD_POST && !postdata)
- /* Build the request */
- request = g_string_new(NULL);
- g_string_append_printf(request, "%s %s HTTP/1.0\r\n",
- (method & OKC_METHOD_POST) ? "POST" : "GET",
- g_string_append_printf(request, "Host: %s\r\n", host);
- g_string_append_printf(request, "Connection: %s\r\n",
- (keepalive ? "Keep-Alive" : "close"));
- g_string_append_printf(request, "User-Agent: %s (libpurple %s)\r\n", purple_core_get_ui(), purple_core_get_version());
- if (method & OKC_METHOD_POST) {
- g_string_append_printf(request,
- "Content-Type: application/x-www-form-urlencoded\r\n");
- g_string_append_printf(request,
- "Content-length: %zu\r\n", strlen(postdata));
- g_string_append_printf(request, "Accept: */*\r\n");
- g_string_append_printf(request, "Cookie: %s\r\n", cookies);
- g_string_append_printf(request, "Accept-Encoding: gzip\r\n");
- g_string_append_printf(request, "X-OkCupid-Api-Version: 1\r\n");
- if (purple_proxy_info_get_username(proxy_info) &&
- purple_proxy_info_get_password(proxy_info))
- proxy_auth = g_strdup_printf("%s:%s", purple_proxy_info_get_username(proxy_info), purple_proxy_info_get_password(proxy_info));
- proxy_auth_base64 = purple_base64_encode((guchar *)proxy_auth, strlen(proxy_auth));
- g_string_append_printf(request, "Proxy-Authorization: Basic %s\r\n", proxy_auth_base64);
- g_free(proxy_auth_base64);
- /* Tell the server what language we accept, so that we get error messages in our language (rather than our IP's) */
- languages = g_get_language_names();
- language_names = g_strjoinv(", ", (gchar **)languages);
- purple_util_chrreplace(language_names, '_', '-');
- g_string_append_printf(request, "Accept-Language: %s\r\n", language_names);
- g_free(language_names);
- purple_debug_misc("okcupid", "requesting url %s\n", url);
- g_string_append_printf(request, "\r\n");
- if (method & OKC_METHOD_POST)
- g_string_append_printf(request, "%s", postdata);
- /* If it needs to go over a SSL connection, we probably shouldn't print
- * it in the debug log. Without this condition a user's password is
- * printed in the debug log */
- if (method == OKC_METHOD_POST)
- purple_debug_misc("okcupid", "sending request data:\n%s\n",
- * Do a separate DNS lookup for the given host name and cache it
- * TODO: It would be better if we did this before we call
- * purple_proxy_connect(), so we could re-use the result.
- * Or even better: Use persistent HTTP connections for servers
- * that we access continually.
- * TODO: This cache of the hostname<-->IP address does not respect
- * the TTL returned by the DNS server. We should expire things
- * from the cache after some amount of time.
- if (!is_proxy && !g_hostname_is_ip_address(host) && !(method & OKC_METHOD_SSL))
- /* Don't do this for proxy connections, since proxies do the DNS lookup */
- host_ip = g_hash_table_lookup(oca->hostname_ip_cache, host);
- purple_debug_info("okcupid",
- "swapping original host %s with cached value of %s\n",
- } else if (oca->account && !oca->account->disconnecting) {
- GSList *host_lookup_list = NULL;
- PurpleDnsQueryData *query;
- host_lookup_list = g_slist_prepend(
- host_lookup_list, g_strdup(host));
- host_lookup_list = g_slist_prepend(
- host_lookup_list, oca);
- query = purple_dnsquery_a(host, 80,
- okc_host_lookup_cb, host_lookup_list);
- oca->dns_queries = g_slist_prepend(oca->dns_queries, query);
- host_lookup_list = g_slist_append(host_lookup_list, query);
- okconn = g_new0(OkCupidConnection, 1);
- okconn->method = method;
- okconn->hostname = g_strdup(host);
- okconn->request = request;
- okconn->callback = callback_func;
- okconn->user_data = user_data;
- okconn->connection_keepalive = keepalive;
- okconn->request_time = time(NULL);
- g_queue_push_head(oca->waiting_conns, okconn);
- okc_next_connection(oca);
-static void okc_next_connection(OkCupidAccount *oca)
- OkCupidConnection *okconn;
- g_return_if_fail(oca != NULL);
- if (!g_queue_is_empty(oca->waiting_conns))
- if(g_slist_length(oca->conns) < OKC_MAX_CONNECTIONS)
- okconn = g_queue_pop_tail(oca->waiting_conns);
- okc_attempt_connection(okconn);
-static void okc_attempt_connection(OkCupidConnection *okconn)
- OkCupidAccount *oca = okconn->oca;
- oca->conns = g_slist_prepend(oca->conns, okconn);
- if (okconn->method & OKC_METHOD_SSL) {
- okconn->ssl_conn = purple_ssl_connect(oca->account, okconn->hostname,
- 443, okc_post_or_get_ssl_connect_cb,
- okc_ssl_connection_error, okconn);
- okconn->connect_data = purple_proxy_connect(NULL, oca->account,
- okconn->hostname, 80, okc_post_or_get_connect_cb, okconn);
--- a/okcupid/okc_connection.h Thu Mar 30 22:35:56 2023 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
- * libokcupid is the property of its developers. See the COPYRIGHT file
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef OKCUPID_CONNECTION_H
-#define OKCUPID_CONNECTION_H
- OKC_METHOD_GET = 0x0001,
- OKC_METHOD_POST = 0x0002,
- OKC_METHOD_SSL = 0x0004
-typedef struct _OkCupidConnection OkCupidConnection;
-struct _OkCupidConnection {
- OkCupidProxyCallbackFunc callback;
- PurpleProxyConnectData *connect_data;
- PurpleSslConnection *ssl_conn;
- gboolean connection_keepalive;
-void okc_connection_destroy(OkCupidConnection *okcconn);
-void okc_post_or_get(OkCupidAccount *oca, OkCupidMethod method,
- const gchar *host, const gchar *url, const gchar *postdata,
- OkCupidProxyCallbackFunc callback_func, gpointer user_data,
-#endif /* OKCUPID_CONNECTION_H */
--- a/okcupid/okc_messages.c Thu Mar 30 22:35:56 2023 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,546 +0,0 @@
- * libokcupid is the property of its developers. See the COPYRIGHT file
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "okc_messages.h"
-#include "okc_connection.h"
-typedef struct _OkCupidOutgoingMessage OkCupidOutgoingMessage;
-struct _OkCupidOutgoingMessage {
-gboolean okc_send_im_fom(OkCupidOutgoingMessage *msg);
-void okc_check_inbox_cb(OkCupidAccount *oca, gchar *data, gsize data_len, gpointer user_data);
-void okc_buddy_icon_cb(OkCupidAccount *oca, gchar *data, gsize data_len,
- gpointer buddy_icon_data;
- purple_debug_info("okcupid",
- "buddy icon for buddy %s %" G_GSIZE_FORMAT "\n",
- buddy = purple_find_buddy(oca->account, buddyname);
- if (buddy == NULL || buddy->proto_data == NULL)
- obuddy = buddy->proto_data;
- buddy_icon_data = g_memdup(data, data_len);
- purple_buddy_icons_set_for_user(oca->account, buddy->name,
- buddy_icon_data, data_len, obuddy->thumb_url);
-void got_new_messages(OkCupidAccount *oca, gchar *data,
- gsize data_len, gpointer userdata)
- PurpleConnection *pc = userdata;
- /* NULL data will crash on Windows */
- purple_debug_misc("okcupid", "got new messages: %s\n", data);
- /* Process incomming messages here */
- gchar *start_of_json = strchr(data, '{');
- gchar *end_of_json = strrchr(data, '}');
- if (!start_of_json || !end_of_json || start_of_json >= end_of_json)
- okc_get_new_messages(oca);
- gchar *json_string = g_strndup(start_of_json, end_of_json-start_of_json+1);
- parser = json_parser_new();
- if(!json_parser_load_from_data(parser, json_string, -1, NULL))
- okc_get_new_messages(oca);
- root = json_parser_get_root(parser);
- objnode = json_node_get_object(root);
- JsonArray *events = NULL;
- JsonArray *people = NULL;
- int unread_message_count = 0;
- if(json_object_has_member(objnode, "people"))
- people = json_node_get_array(json_object_get_member(objnode, "people"));
- if(json_object_has_member(objnode, "events"))
- events = json_node_get_array(json_object_get_member(objnode, "events"));
- if(json_object_has_member(objnode, "num_unread"))
- unread_message_count = json_node_get_int(json_object_get_member(objnode, "num_unread"));
- // Look through the buddy list for people to add first
- GList *people_list = json_array_get_elements(people);
- for (current = people_list; current; current = g_list_next(current))
- JsonNode *currentNode = current->data;
- JsonObject *person = json_node_get_object(currentNode);
- if (!json_node_get_int(json_object_get_member(person, "is_buddy")) &&
- !purple_account_get_bool(oca->account, "show_stalkers", TRUE))
- const gchar *buddy_name = json_node_get_string(json_object_get_member(person, "screenname"));
- const gchar *buddy_icon = json_node_get_string(json_object_get_member(person, "thumbnail"));
- gint is_online = json_node_get_int(json_object_get_member(person, "im_ok"));
- if (!json_object_has_member(person, "im_ok"))
- PurpleBuddy *pbuddy = purple_find_buddy(oca->account, buddy_name);
- //Not everyone we talk to will be on our buddylist
- pbuddy = purple_buddy_new(oca->account, buddy_name, NULL);
- purple_blist_add_buddy(pbuddy, NULL, NULL, NULL);
- if (!json_node_get_int(json_object_get_member(person, "is_buddy")))
- purple_blist_node_set_flags(&(pbuddy->node), PURPLE_BLIST_NODE_FLAG_NO_SAVE);
- purple_blist_node_set_flags(&(pbuddy->node), 0);
- if (is_online && !PURPLE_BUDDY_IS_ONLINE(pbuddy))
- purple_prpl_got_user_status(oca->account, buddy_name, purple_primitive_get_id_from_type(PURPLE_STATUS_AVAILABLE), NULL);
- } else if (!is_online && PURPLE_BUDDY_IS_ONLINE(pbuddy))
- purple_prpl_got_user_status(oca->account, buddy_name, purple_primitive_get_id_from_type(PURPLE_STATUS_OFFLINE), NULL);
- OkCupidBuddy *obuddy = pbuddy->proto_data;
- const gchar *buddy_icon_url;
- obuddy = g_new0(OkCupidBuddy, 1);
- obuddy->buddy = pbuddy;
- // load the old buddy icon url from the icon 'checksum'
- buddy_icon_url = purple_buddy_icons_get_checksum_for_user(pbuddy);
- if (buddy_icon_url != NULL)
- obuddy->thumb_url = g_strdup(buddy_icon_url);
- pbuddy->proto_data = obuddy;
- if (!obuddy->thumb_url || !g_str_equal(obuddy->thumb_url, buddy_icon))
- gchar *host, *path, *path2;
- gchar *large_image_url;
- g_free(obuddy->thumb_url);
- obuddy->thumb_url = g_strdup(buddy_icon);
- large_image_url = purple_strreplace(buddy_icon, "/60x60/", "/256x256/");
- purple_url_parse(large_image_url, &host, NULL, &path, NULL, NULL);
- g_free(large_image_url);
- path2 = g_strdup_printf("/%s", path);
- path2 = g_strdup(path);
- okc_post_or_get(oca, OKC_METHOD_GET, host, path2, NULL, okc_buddy_icon_cb, g_strdup(buddy_name), FALSE);
- if (obuddy->status_cache == NULL && json_object_has_member(person, "age"))
- gint age = json_node_get_int(json_object_get_member(person, "age"));
- const gchar *gender = json_node_get_string(json_object_get_member(person, "gender"));
- const gchar *location = json_node_get_string(json_object_get_member(person, "location"));
- obuddy->status_cache = g_strdup_printf("%d / %s / %s", age, gender, location );
- g_list_free(people_list);
- //loop through events looking for messages
- GList *event_list = json_array_get_elements(events);
- for (current = event_list; current; current = g_list_next(current))
- JsonNode *currentNode = current->data;
- JsonObject *event = json_node_get_object(currentNode);
- const gchar *event_type;
- event_type = json_node_get_string(json_object_get_member(event, "type"));
- if (g_str_equal(event_type, "im"))
- const gchar *message = json_node_get_string(json_object_get_member(event, "contents"));
- gchar *message_html = okc_strdup_withhtml(message);
- const gchar *who = NULL;
- PurpleMessageFlags flags;
- if (json_object_has_member(event, "to"))
- who = json_node_get_string(json_object_get_member(event, "to"));
- flags = PURPLE_MESSAGE_SEND;
- } else if (json_object_has_member(event, "from"))
- who = json_node_get_string(json_object_get_member(event, "from"));
- flags = PURPLE_MESSAGE_RECV;
- if (who && (flags != PURPLE_MESSAGE_SEND || purple_account_get_bool(oca->account, "show_sent_messages", FALSE)))
- serv_got_im (pc, who, message_html, flags, time(NULL));
- } else if (g_str_equal(event_type, "orbit_user_signoff"))
- const gchar *buddy_name = json_node_get_string(json_object_get_member(event, "from"));
- PurpleBuddy *pbuddy = purple_find_buddy(oca->account, buddy_name);
- if (pbuddy && PURPLE_BUDDY_IS_ONLINE(pbuddy))
- purple_prpl_got_user_status(oca->account, buddy_name, purple_primitive_get_id_from_type(PURPLE_STATUS_OFFLINE), NULL);
- } else if (g_str_equal(event_type, "stalk") && purple_account_get_bool(oca->account, "show_stalkers", TRUE))
- //someone looked at the profile page (ie 'stalked' the user)
- const gchar *buddy_name = json_node_get_string(json_object_get_member(event, "from"));
- gchar *stalk_message = g_strdup_printf("%s just viewed your profile", buddy_name);
- serv_got_im(oca->pc, buddy_name, stalk_message, PURPLE_MESSAGE_SYSTEM, time(NULL));
- g_list_free(event_list);
- if (unread_message_count != oca->last_message_count && purple_account_get_check_mail(pc->account))
- oca->last_message_count = unread_message_count;
- if (unread_message_count > 0)
- okc_post_or_get(oca, OKC_METHOD_GET, NULL, "/mailbox?folderid=1&low=1", NULL, okc_check_inbox_cb, NULL, FALSE);
- if (json_object_has_member(objnode, "server_seqid"))
- oca->server_seqid = json_node_get_int(json_object_get_member(objnode, "server_seqid"));
- if (json_object_has_member(objnode, "server_gmt"))
- oca->server_gmt = json_node_get_int(json_object_get_member(objnode, "server_gmt"));
- g_object_unref(parser);
- /* Continue looping, waiting for more messages */
- okc_get_new_messages(oca);
-okc_get_stalkers(OkCupidAccount *oca)
- buddies = purple_find_buddies(oca->account, NULL);
- stalkers = g_string_new(NULL);
- for(l = buddies; l; l = l->next)
- if (buddy->node.flags & PURPLE_BLIST_NODE_FLAG_NO_SAVE)
- // A temp buddy? They're a stalker!
- g_string_append_printf(stalkers, "%s,", buddy->name);
- return g_string_free(stalkers, FALSE);
-void okc_get_new_messages_now(OkCupidAccount *oca)
- purple_debug_info("okcupid", "getting new messages now\n");
- stalkers = okc_get_stalkers(oca);
- fetch_url = g_strdup_printf("/instantevents?rand=0.%u&server_seqid=%u&server_gmt=%u&"
- "load_thumbnails=1&buddylist=1&"
- "show_offline=1&num_unread=1&im_status=1&"
- g_random_int(), oca->server_seqid, oca->server_gmt,
- okc_post_or_get(oca, OKC_METHOD_GET, NULL, fetch_url, NULL, got_new_messages, oca->pc, FALSE);
-gboolean okc_get_new_messages(OkCupidAccount *oca)
- oca->new_messages_check_timer = 0;
- if (oca->last_messages_download_time > now - 3) {
- * Wait a bit before fetching more messages, to make sure we
- * never hammer their servers.
- * TODO: This could be smarter. Like, allow 3 requests per
- * 10 seconds or something.
- oca->new_messages_check_timer = purple_timeout_add_seconds(
- 3 - (now - oca->last_messages_download_time),
- (GSourceFunc)okc_get_new_messages, oca);
- purple_debug_info("okcupid", "getting new messages\n");
- stalkers = okc_get_stalkers(oca);
- fetch_url = g_strdup_printf("/instantevents?rand=0.%u&server_seqid=%u&server_gmt=%u&"
- "load_thumbnails=1&do_event_poll=1&buddylist=1&"
- "show_offline=1&num_unread=1&im_status=1&"
- "do_post_read=1&usernames=%s",
- g_random_int(), oca->server_seqid, oca->server_gmt,
- okc_post_or_get(oca, OKC_METHOD_GET, NULL, fetch_url, NULL, got_new_messages, oca->pc, TRUE);
- oca->last_messages_download_time = now;
-void okc_msg_destroy(OkCupidOutgoingMessage *msg)
-void okc_send_im_cb(OkCupidAccount *oca, gchar *data, gsize data_len, gpointer user_data)
- OkCupidOutgoingMessage *msg = user_data;
- if (data == NULL || data_len == 0)
- //No response, resend message
- purple_debug_misc("okcupid", "sent im response: %s\n", data);
- "reason" : "recip_not_online"
- parser = json_parser_new();
- if(!json_parser_load_from_data(parser, data, data_len, NULL))
- root = json_parser_get_root(parser);
- response = json_node_get_object(root);
- gint message_sent = json_node_get_int(json_object_get_member(response, "status"));
- if (message_sent < 100)
- //Save the message we sent
- purple_debug_info("okcupid", "putting message into hashtable: '%s'\n", msg->message);
- g_object_unref(parser);
- const gchar *reason = json_node_get_string(json_object_get_member(response, "status_str"));
- if (g_str_equal(reason, "recip_not_online"))
- serv_got_im(oca->pc, msg->who, _("Recipient not online"), PURPLE_MESSAGE_ERROR, time(NULL));
- } else if (g_str_equal(reason, "im_self"))
- serv_got_im(oca->pc, msg->who, _("You cannot send an IM to yourself"), PURPLE_MESSAGE_ERROR, time(NULL));
- } else if (g_str_equal(reason, "im_not_ok"))
- serv_got_im(oca->pc, msg->who, _("Recipient is 'missing'"), PURPLE_MESSAGE_ERROR, time(NULL));
- } else if (g_str_equal(reason, "recip_im_off"))
- serv_got_im(oca->pc, msg->who, _("Recipient turned IM off"), PURPLE_MESSAGE_ERROR, time(NULL));
- g_object_unref(parser);
-gboolean okc_send_im_fom(OkCupidOutgoingMessage *msg)
- gchar *encoded_message;
- gchar *encoded_recipient;
- encoded_message = g_strdup(purple_url_encode(msg->message));
- encoded_recipient = g_strdup(purple_url_encode(msg->who));
- postdata = g_strdup_printf("send=1&attempt=%d&rid=%d&recipient=%s&topic=false&body=%s",
- g_free(encoded_message);
- g_free(encoded_recipient);
- okc_post_or_get(msg->oca, OKC_METHOD_POST, NULL, "/instantevents", postdata, okc_send_im_cb, msg, FALSE);
-int okc_send_im(PurpleConnection *pc, const gchar *who, const gchar *message, PurpleMessageFlags flags)
- OkCupidOutgoingMessage *msg;
- msg = g_new0(OkCupidOutgoingMessage, 1);
- msg->oca = pc->proto_data;
- /* convert html to plaintext, removing trailing spaces */
- msg->message = purple_markup_strip_html(message);
- msg->rid = g_random_int_range(0, 2000000000); /* just fits inside a 32bit int */
- msg->who = g_strdup(who);
- msg->time = time(NULL);
- if (purple_account_get_bool(pc->account, "show_sent_messages", FALSE))
- return strlen(message);
-void okc_check_inbox_cb(OkCupidAccount *oca, gchar *data, gsize data_len, gpointer user_data)
- purple_debug_misc("okcupid", "check_inbox_cb\n%s", (data?data:"(null)"));
- parser = json_parser_new();
- if(!json_parser_load_from_data(parser, data, data_len, NULL))
- purple_debug_warning("okcupid", "Could not parse mailbox data\n");
- root = json_parser_get_root(parser);
- mailbox = json_node_get_object(root);
- if (json_object_has_member(mailbox, "messages"))
- messages = json_node_get_array(json_object_get_member(mailbox, "messages"));
- GList *message_list = json_array_get_elements(messages);
- for (current = message_list; current; current = g_list_next(current))
- JsonNode *currentNode = current->data;
- JsonObject *message = json_node_get_object(currentNode);
- gboolean is_new = (gboolean) json_node_get_int(json_object_get_member(message, "is_new"));
- const gchar *subject = json_node_get_string(json_object_get_member(message, "subject"));
- const gchar *from = json_node_get_string(json_object_get_member(message, "person"));
- const gchar *to = oca->account->username;
- const gchar *thread_id = json_node_get_string(json_object_get_member(message, "thread_id"));
- gchar *url = g_strdup_printf("http://www.okcupid.com/messages?readmsg=true&threadid=%s&folder=1", thread_id);
- purple_notify_email(oca->pc, subject, from, to, url, NULL, NULL);
- g_list_free(message_list);
- g_object_unref(parser);
--- a/okcupid/okc_messages.h Thu Mar 30 22:35:56 2023 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
- * libokcupid is the property of its developers. See the COPYRIGHT file
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef OKCUPID_MESSAGES_H
-#define OKCUPID_MESSAGES_H
-int okc_send_im(PurpleConnection *pc, const gchar *who, const gchar *message,
- PurpleMessageFlags flags);
-gboolean okc_get_new_messages(OkCupidAccount *oca);
-void okc_get_new_messages_now(OkCupidAccount *oca);
-void okc_buddy_icon_cb(OkCupidAccount *oca, gchar *data, gsize data_len,
-#endif /* OKCUPID_MESSAGES_H */
--- a/okcupid/okcupid.c Thu Mar 30 22:35:56 2023 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,461 +0,0 @@
- * libokcupid is the property of its developers. See the COPYRIGHT file
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "okc_connection.h"
-#include "okc_messages.h"
-/******************************************************************************/
-/******************************************************************************/
-gchar *okc_convert_unicode(const gchar *input)
- gchar unicode_char_str[6];
- next_pos = input_string = g_strdup(input);
- while ((next_pos = strstr(next_pos, "\\u")))
- sscanf(next_pos, "\\u%4x", &unicode_char);
- /* turn it to a char* */
- unicode_char_len = g_unichar_to_utf8(unicode_char, unicode_char_str);
- /* shove it back into the string */
- g_memmove(next_pos, unicode_char_str, unicode_char_len);
- /* move all the data after the \u0000 along */
- g_stpcpy(next_pos + unicode_char_len, next_pos + 6);
- output_string = g_strcompress(input_string);
-/* Like purple_strdup_withhtml, but escapes htmlentities too */
-gchar *okc_strdup_withhtml(const gchar *src)
- g_return_val_if_fail(src != NULL, NULL);
- /* New length is (length of src) + (number of \n's * 3) + (number of &'s * 5) +
- (number of <'s * 4) + (number of >'s *4) + (number of "'s * 6) -
- (number of \r's) + 1 */
- for (i = 0; src[i] != '\0'; i++)
- if (src[i] == '\n' || src[i] == '<' || src[i] == '>')
- else if (src[i] == '&')
- else if (src[i] == '"')
- else if (src[i] != '\r')
- dest = g_malloc(destsize);
- /* Copy stuff, ignoring \r's, because they are dumb */
- for (i = 0, j = 0; src[i] != '\0'; i++) {
- strcpy(&dest[j], "<BR>");
- } else if (src[i] == '<') {
- strcpy(&dest[j], "<");
- } else if (src[i] == '>') {
- strcpy(&dest[j], ">");
- } else if (src[i] == '&') {
- strcpy(&dest[j], "&");
- } else if (src[i] == '"') {
- strcpy(&dest[j], """);
- } else if (src[i] != '\r')
- dest[destsize-1] = '\0';
-/******************************************************************************/
-/******************************************************************************/
-static const char *okc_list_icon(PurpleAccount *account, PurpleBuddy *buddy)
-static GList *okc_statuses(PurpleAccount *account)
- PurpleStatusType *status;
- purple_debug_info("okcupid", "statuses\n");
- /* OkCupid people are either online, online with no IM, offline */
- status = purple_status_type_new_full(PURPLE_STATUS_AVAILABLE, NULL, NULL, TRUE, TRUE, FALSE);
- types = g_list_append(types, status);
- status = purple_status_type_new_full(PURPLE_STATUS_OFFLINE, NULL, NULL, TRUE, TRUE, FALSE);
- types = g_list_append(types, status);
- purple_debug_info("okcupid", "statuses return\n");
-static gboolean okc_get_messages_failsafe(OkCupidAccount *oca)
- if (oca->last_messages_download_time < (time(NULL) - (60*5))) {
- /* Messages haven't been downloaded in a while-
- * something is probably wrong */
- purple_debug_warning("okcupid",
- "executing message check failsafe\n");
- okc_get_new_messages(oca);
-static void okc_login_cb(OkCupidAccount *oca, gchar *response, gsize len,
- purple_connection_update_progress(oca->pc, _("Authenticating"), 2, 3);
- purple_connection_error(oca->pc, "No login response");
- parser = json_parser_new();
- if (!json_parser_load_from_data(parser, response, len, NULL))
- purple_connection_error(oca->pc, "Error parsing login response");
- root = json_parser_get_root(parser);
- message = json_node_get_object(root);
- status = json_node_get_int(json_object_get_member(message, "status"));
- purple_connection_error(oca->pc, "Bad username or password");
- /* ok, we're logged in now! */
- purple_connection_set_state(oca->pc, PURPLE_CONNECTED);
- /* This will kick off our long-poll message retrieval loop */
- okc_get_new_messages_now(oca);
- oca->perpetual_messages_timer = purple_timeout_add_seconds(15,
- (GSourceFunc)okc_get_messages_failsafe, oca);
-static void okc_login(PurpleAccount *account)
- gchar *postdata, *encoded_username, *encoded_password;
- purple_debug_info("okcupid", "login\n");
- /* Create account and initialize state */
- oca = g_new0(OkCupidAccount, 1);
- oca->account = account;
- oca->pc = purple_account_get_connection(account);
- oca->last_messages_download_time = time(NULL) - 60; /* 60 secs is a safe buffer */
- oca->server_seqid = purple_account_get_int(oca->account, "server_seqid", 0);
- oca->server_gmt = purple_account_get_int(oca->account, "server_gmt", 0);
- oca->cookie_table = g_hash_table_new_full(g_str_hash, g_str_equal,
- oca->hostname_ip_cache = g_hash_table_new_full(g_str_hash, g_str_equal,
- oca->waiting_conns = g_queue_new();
- account->gc->proto_data = oca;
- purple_connection_set_state(oca->pc, PURPLE_CONNECTING);
- purple_connection_update_progress(oca->pc, _("Connecting"), 1, 3);
- encoded_username = g_strdup(purple_url_encode(
- purple_account_get_username(account)));
- encoded_password = g_strdup(purple_url_encode(
- purple_account_get_password(account)));
- postdata = g_strdup_printf("username=%s&password=%s",
- encoded_username, encoded_password);
- g_free(encoded_username);
- g_free(encoded_password);
- okc_post_or_get(oca, OKC_METHOD_POST | OKC_METHOD_SSL, "www.okcupid.com",
- "/login", postdata, okc_login_cb, NULL, FALSE);
-static void okc_close(PurpleConnection *pc)
- purple_debug_info("okcupid", "disconnecting account\n");
- okc_post_or_get(oca, OKC_METHOD_POST, NULL, "/logout",
- "ajax=1", NULL, NULL, FALSE);
- if (oca->new_messages_check_timer)
- purple_timeout_remove(oca->new_messages_check_timer);
- if (oca->buddy_presence_timer)
- purple_timeout_remove(oca->buddy_presence_timer);
- if (oca->perpetual_messages_timer)
- purple_timeout_remove(oca->perpetual_messages_timer);
- purple_debug_info("okcupid", "destroying %d waiting connections\n",
- g_queue_get_length(oca->waiting_conns));
- while (!g_queue_is_empty(oca->waiting_conns))
- okc_connection_destroy(g_queue_pop_tail(oca->waiting_conns));
- g_queue_free(oca->waiting_conns);
- purple_debug_info("okcupid", "destroying %d incomplete connections\n",
- g_slist_length(oca->conns));
- while (oca->conns != NULL)
- okc_connection_destroy(oca->conns->data);
- while (oca->dns_queries != NULL) {
- PurpleDnsQueryData *dns_query = oca->dns_queries->data;
- purple_debug_info("okcupid", "canceling dns query for %s\n",
- purple_dnsquery_get_host(dns_query));
- oca->dns_queries = g_slist_remove(oca->dns_queries, dns_query);
- purple_dnsquery_destroy(dns_query);
- g_hash_table_destroy(oca->cookie_table);
- g_hash_table_destroy(oca->hostname_ip_cache);
- //Store server_seqid and server_gmt so that we dont download all the messages on startup
- purple_account_set_int(oca->account, "server_seqid", oca->server_seqid);
- purple_account_set_int(oca->account, "server_gmt", oca->server_gmt);
-static void okc_buddy_free(PurpleBuddy *buddy)
- OkCupidBuddy *obuddy = buddy->proto_data;
- buddy->proto_data = NULL;
- g_free(obuddy->status_cache);
- g_free(obuddy->thumb_url);
-void okc_fake_group_buddy(PurpleConnection *pc, const char *who, const char *old_group, const char *new_group)
- /* Do nuffink, so that buddies aren't deleted! */
-gchar *okc_status_text(PurpleBuddy *buddy)
- OkCupidBuddy *obuddy = buddy->proto_data;
- if (obuddy != NULL && obuddy->status_cache != NULL)
- return g_strdup(obuddy->status_cache);
-void okc_tooltip_text(PurpleBuddy *buddy, PurpleNotifyUserInfo *user_info, gboolean full)
- OkCupidBuddy *obuddy = buddy->proto_data;
- if (obuddy != NULL && obuddy->status_cache != NULL)
- purple_notify_user_info_add_pair(user_info, NULL, obuddy->status_cache);
-/******************************************************************************/
-/******************************************************************************/
-static gboolean plugin_load(PurplePlugin *plugin)
-static gboolean plugin_unload(PurplePlugin *plugin)
-static void plugin_init(PurplePlugin *plugin)
- PurpleAccountOption *option;
- PurplePluginInfo *info = plugin->info;
- PurplePluginProtocolInfo *prpl_info = info->extra_info;
- option = purple_account_option_string_new("Host", "host", "api.okcupid.com");
- prpl_info->protocol_options = g_list_append(prpl_info->protocol_options, option);
- option = purple_account_option_bool_new("Show messages sent from website", "show_sent_messages", FALSE);
- prpl_info->protocol_options = g_list_append(prpl_info->protocol_options, option);
- option = purple_account_option_bool_new("Show people who visit your profile", "show_stalkers", TRUE);
- prpl_info->protocol_options = g_list_append(prpl_info->protocol_options, option);
- option = purple_account_option_bool_new("Always use HTTPS", "force_https", TRUE);
- prpl_info->protocol_options = g_list_append(prpl_info->protocol_options, option);
-static PurplePluginProtocolInfo prpl_info = {
- NULL, /* user_splits */
- NULL, /* protocol_options */
- NO_BUDDY_ICONS /* icon_spec */
- /*{"jpg", 0, 0, 50, 50, -1, PURPLE_ICON_SCALE_SEND}*/, /* icon_spec */
- okc_list_icon, /* list_icon */
- NULL, /* list_emblems */
- okc_status_text, /* status_text */
- okc_tooltip_text, /* tooltip_text */
- okc_statuses, /* status_types */
- okc_blist_node_menu, /* blist_node_menu */
- NULL, /* chat_info_defaults */
- okc_send_im, /* send_im */
- NULL, /* send_typing */
- okc_get_info, /* get_info */
- NULL, /* change_passwd */
- okc_add_buddy, /* add_buddy */
- NULL, /* add_buddies */
- okc_remove_buddy, /* remove_buddy */
- NULL, /* remove_buddies */
- okc_block_buddy, /* add_deny */
- NULL, /* set_permit_deny */
- NULL, /* reject chat invite */
- NULL, /* get_chat_name */
- NULL, /* chat_invite */
- NULL, /* chat_whisper */
- NULL, /* register_user */
- NULL, /* get_cb_info */
- NULL, /* get_cb_away */
- NULL, /* alias_buddy */
- okc_fake_group_buddy, /* group_buddy */
- NULL, /* rename_group */
- okc_buddy_free, /* buddy_free */
- NULL, /* convo_closed */
- purple_normalize_nocase,/* normalize */
- NULL, /* set_buddy_icon */
- NULL, /* remove_group */
- NULL, /* get_cb_real_name */
- NULL, /* set_chat_topic */
- NULL, /* find_blist_chat */
- NULL, /* roomlist_get_list */
- NULL, /* roomlist_cancel */
- NULL, /* roomlist_expand_category */
- NULL, /* can_receive_file */
- NULL, /* offline_message */
- NULL, /* whiteboard_prpl_ops */
- NULL, /* roomlist_room_serialize */
- NULL, /* unregister_user */
- NULL, /* send_attention */
- NULL, /* attention_types */
- sizeof(PurplePluginProtocolInfo), /* struct_size */
- NULL, /* get_account_text_table */
-static PurplePluginInfo info = {
- PURPLE_PLUGIN_PROTOCOL, /* type */
- NULL, /* ui_requirement */
- NULL, /* dependencies */
- PURPLE_PRIORITY_DEFAULT, /* priority */
- "prpl-bigbrownchunx-okcupid", /* id */
- PP_VERSION, /* version */
- N_("OkCupid Protocol Plugin"), /* summary */
- N_("OkCupid Protocol Plugin"), /* description */
- "Eion Robb <eionrobb@gmail.com>", /* author */
- PP_WEBSITE, /* homepage */
- plugin_load, /* load */
- plugin_unload, /* unload */
- &prpl_info, /* extra_info */
-PURPLE_INIT_PLUGIN(okcupid, plugin_init, info);
--- a/okcupid/okcupid.h Thu Mar 30 22:35:56 2023 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,104 +0,0 @@
- * libokcupid is the property of its developers. See the COPYRIGHT file
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "../common/pp_internal.h"
-#define OKC_MAX_CONNECTIONS 16
-#include <json-glib/json-glib.h>
-#ifndef G_GNUC_NULL_TERMINATED
-# define G_GNUC_NULL_TERMINATED __attribute__((__sentinel__))
-# define G_GNUC_NULL_TERMINATED
-# endif /* __GNUC__ >= 4 */
-#endif /* G_GNUC_NULL_TERMINATED */
-# define dlopen(a,b) LoadLibrary(a)
-# define dlsym(a,b) GetProcAddress(a,b)
-# define dlclose(a) FreeLibrary(a)
-# include <netinet/in.h>
-# include <sys/socket.h>
-typedef struct _OkCupidAccount OkCupidAccount;
-typedef struct _OkCupidBuddy OkCupidBuddy;
-typedef void (*OkCupidProxyCallbackFunc)(OkCupidAccount *oca, gchar *data, gsize data_len, gpointer user_data);
-struct _OkCupidAccount {
- PurpleAccount *account;
- GHashTable *hostname_ip_cache;
- GSList *conns; /**< A list of all active OkCupidConnections */
- GQueue *waiting_conns; /**< A list of all OkCupidConnections waiting to process */
- GHashTable *cookie_table;
- time_t last_messages_download_time;
- guint new_messages_check_timer;
- guint perpetual_messages_timer;
- guint buddy_presence_timer;
- guint last_message_count;
-gchar *okc_strdup_withhtml(const gchar *src);
-gchar *okc_convert_unicode(const gchar *input);
-#endif /* LIBOKCUPID_H */
--- a/po/POTFILES Thu Mar 30 22:35:56 2023 -0500
+++ b/po/POTFILES Thu Mar 30 22:53:31 2023 -0500
@@ -39,10 +39,6 @@
-okcupid/okc_connection.c