Ejemplo n.º 1
0
Contact *QuetzalContactsFactory::addContact(const QString &id, const QVariantMap &data)
{
	QByteArray group = data.value(QLatin1String("group")).toString().toUtf8();
	if (group.isEmpty()) {
		// For compatibility with other implementations
		// Looks like libpurple doesn't support multiple groups
		// Or does it at some unknown way
		group = data.value(QLatin1String("tags")).toStringList().value(0).toUtf8();
	}
	QString name = data.value(QLatin1String("name")).toString();
	
	const char *groupName = group.isEmpty() ? "Buddies" : group.constData();
	PurpleGroup *pg = purple_find_group(groupName);
	if (!pg) {
		pg = purple_group_new(groupName);
		purple_blist_add_group(pg, quetzal_blist_get_last_sibling(purple_blist_get_root()));
	}
	PurpleContact *pc = purple_contact_new();
	purple_blist_add_contact(pc, pg, quetzal_blist_get_last_child(PURPLE_BLIST_NODE(pg)));
	PurpleBuddy *buddy = purple_buddy_new(m_account->purple(), id.toUtf8().constData(),
										  name.toUtf8().constData());
	PurpleBlistNode *node = PURPLE_BLIST_NODE(buddy);
	purple_blist_add_buddy(buddy, pc, pg, quetzal_blist_get_last_child(PURPLE_BLIST_NODE(pc)));
	QMapIterator<QString, QVariant> it(data.value(QLatin1String("quetzal_settings")).toMap());
	while (it.hasNext()) {
		it.next();
		QByteArray key = it.key().toUtf8();
		QVariant::Type type = it.value().type();
		if (type == QVariant::Bool) {
			purple_blist_node_set_bool(node, key.constData(), it.value().toBool());
		} else if (type == QVariant::Int || type == QVariant::UInt
				 || type == QVariant::LongLong || type == QVariant::ULongLong) {
			purple_blist_node_set_int(node, key.constData(), it.value().toInt());
		} else {
			purple_blist_node_set_string(node, key.constData(), it.value().toString().toUtf8());
		}
	}
	QuetzalContact *contact = reinterpret_cast<QuetzalContact*>(node->ui_data);
	contact->update(buddy);
	return contact;
}
Ejemplo n.º 2
0
static PurpleBuddy* spin_sync_buddy(SpinData* spin,
				    GSList* buddies,const gchar* id,
				    const gchar* name,guint online,
				    const gchar* away,const gchar* photo)
{
  PurpleAccount* account = purple_connection_get_account(spin->gc);
  /* gchar* lower_name = g_utf8_strdown(name,-1); */
  PurpleBuddy* buddy = spin_find_buddy_in_list(buddies,id);
  if(!buddy)
    {
      purple_debug_info("spin","adding buddy: %s\n",/*lower_*/name);
      buddy = purple_buddy_new(account,/*lower_*/name,NULL);
      purple_blist_add_buddy(buddy,NULL,NULL,NULL);
      purple_blist_node_set_string(&buddy->node,"spin-id",id);
    }
  /* purple_normalize here? */
  if(g_strcmp0(purple_buddy_get_name(buddy),name) != 0)
    {
      spin_notify_nick_changed(spin,purple_buddy_get_name(buddy),name);
      purple_blist_rename_buddy(buddy,name);
    }

  spin_sync_photo(spin,buddy,photo);

  /* do not set status if we got a status after the HTTP request */
  if(g_hash_table_lookup(spin->updated_status_list,
			 purple_normalize(account,name)))
    return buddy;

  if(online && *away)
    purple_prpl_got_user_status(account,/*lower_*/name,"away",
				"message",away,NULL);
  else if(online)
    purple_prpl_got_user_status(account,/*lower_*/name,"available",NULL);
  else
    purple_prpl_got_user_status(account,/*lower_*/name,"offline",NULL);

  return buddy;
  /* g_free(lower_name); */
}
Ejemplo n.º 3
0
/*add group id to User object*/
void
msn_user_add_group_id(MsnUser *user, const char* group_id)
{
	MsnUserList *userlist;
	PurpleAccount *account;
	PurpleBuddy *b;
	PurpleGroup *g;
	const char *passport;
	const char *group_name;

	g_return_if_fail(user != NULL);
	g_return_if_fail(group_id != NULL);

	user->group_ids = g_list_append(user->group_ids, g_strdup(group_id));

	userlist = user->userlist;
	account = userlist->session->account;
	passport = msn_user_get_passport(user);

	group_name = msn_userlist_find_group_name(userlist, group_id);

	purple_debug_info("msn", "User: group id:%s,name:%s,user:%s\n", group_id, group_name, passport);

	g = purple_find_group(group_name);

	if ((group_id == NULL) && (g == NULL))
	{
		g = purple_group_new(group_name);
		purple_blist_add_group(g, NULL);
	}

	b = purple_find_buddy_in_group(account, passport, g);
	if (b == NULL)
	{
		b = purple_buddy_new(account, passport, NULL);
		purple_blist_add_buddy(b, NULL, g, NULL);
	}
	purple_buddy_set_protocol_data(b, user);
	/*Update the blist Node info*/
}
Ejemplo n.º 4
0
gboolean jidgin_worker_send_im(PurpleAccount *account, PurpleConversation *conv, pJidginMsg pmsg) {
  PurpleBuddy *buddy;
  char *reply;
  pJidginSetting setting = jidgin_core_get_purple_settings();

  if (!account) {
    account = jidgin_core_get_primary_account();
  }

  if (purple_account_is_disconnected(account)) {
    jidgin_log(LOG_INFO, "[jidgin_worker_send_im]%s disconnected\n",
        purple_account_get_username(account));
    jidgin_worker_cb_retry(account);
    return FALSE;
  }

  if (!conv) {
    buddy = purple_find_buddy(account, pmsg->from);
    if (!buddy) {
      if (setting && setting->is_force_mt)
        buddy = purple_buddy_new(account, pmsg->from, pmsg->from);
      else
        return FALSE;
    }
    conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, buddy->account, pmsg->from);
  }

  jidgin_log(LOG_INFO, "[jidgin_worker_send_im]%s %s\n",
      purple_account_get_username(account), pmsg->from);

  if (jidgin_intercept_postrouting(pmsg->msg, &reply)) {
    g_free(pmsg->msg);
    pmsg->msg = reply;
  }
  purple_conv_im_send(PURPLE_CONV_IM(conv), pmsg->msg);

  return TRUE;
}
Ejemplo n.º 5
0
static PurpleBuddy *add_buddy(FacebookAccount *fba,
	const gchar *friend_list_id, const gchar *uid, GHashTable *cur_groups)
{
	const gchar *group_name;
	PurpleGroup *fb_group;
	PurpleBuddy *buddy;

	group_name = g_hash_table_lookup(fba->friend_lists, purple_normalize_nocase(NULL, friend_list_id));
	if (!group_name || group_name[0] == '\0') {
		purple_debug_info("facebook",
				"did not find name of list %s\n",
				friend_list_id);
		group_name = DEFAULT_GROUP_NAME;
	}

	// Initialize group as necessary.
	fb_group = purple_find_group(group_name);
	if (fb_group == NULL)
	{
		purple_debug_info("facebook", "adding friend list %s\n",
				group_name);
		fb_group = purple_group_new(group_name);
		purple_blist_add_group(fb_group, NULL);
	} 

	buddy = (PurpleBuddy *)g_hash_table_lookup(cur_groups, purple_normalize_nocase(NULL, group_name));
	if (!buddy) {
		purple_debug_info("facebook", "adding %s to %s\n",
				uid, group_name);
		buddy = purple_buddy_new(fba->account, uid, NULL);
		purple_blist_add_buddy(buddy, NULL, fb_group, NULL);
		g_hash_table_remove(cur_groups, purple_normalize_nocase(NULL, group_name));
	}

	return buddy;
}
Ejemplo n.º 6
0
static VALUE add_buddy(VALUE self, VALUE buddy)
{
  PurpleAccount *account = NULL;
  PurpleConnection *gc = NULL;
  
  Data_Get_Struct(self, PurpleAccount, account);
  gc = purple_account_get_connection( account );
  
	PurpleBuddy* pb = purple_buddy_new(account, RSTRING_PTR(buddy), NULL);
  
  char* group = _("Buddies");
  PurpleGroup* grp = purple_find_group(group);
	if (!grp)
	{
		grp = purple_group_new(group);
		purple_blist_add_group(grp, NULL);
	}
  
  purple_blist_add_buddy(pb, NULL, grp, NULL);
  purple_account_add_buddy(account, pb);
  serv_add_permit( gc, RSTRING_PTR(buddy) );
  
  return Qtrue;
}
Ejemplo n.º 7
0
void
AddMobileBuddy(struct fetion_account_data *sip, struct sipmsg *msg,
	       struct transaction *tc)
{
	gint xml_len;
	xmlnode *root, *son, *item;
	gchar *body;
	const gchar *uri, *name, *group_id;
	struct group_attr *g_attr = NULL;
	gchar *buddy_name;
	PurpleBuddy *b;
	PurpleGroup *g = NULL;
	struct fetion_buddy *bs;
	struct sipmsg *old = NULL;
	const gchar *real_name;

	real_name =
	    purple_account_get_string(sip->account, "realname", sip->username);

	if (!real_name || strlen(real_name) < 1) {
		real_name = sip->username;
	}

	g_return_if_fail(tc->msg != NULL);
	old = tc->msg;
	g_return_if_fail(old != NULL);
	purple_debug_info("fetion:", "AddMobileBuddy:oldmsg[%s]", old->body);
	root = xmlnode_from_str(old->body, old->bodylen);
	item = xmlnode_get_child(root, "contacts/buddies/buddy");
	g_return_if_fail(item != NULL);

	uri = xmlnode_get_attrib(item, "uri");
	name = xmlnode_get_attrib(item, "local-name");
	group_id = xmlnode_get_attrib(item, "buddy-lists");
	buddy_name = g_strdup_printf("%s", uri);
	g_attr = g_hash_table_lookup(sip->group, group_id);
	g_return_if_fail(g_attr != NULL);
	g = purple_find_group(g_attr->name);
	if (!g)
		g = purple_group_new(g_attr->name);

	b = purple_find_buddy(sip->account, buddy_name);
	if (!b) {
		b = purple_buddy_new(sip->account, buddy_name, NULL);
	}

	purple_blist_add_buddy(b, NULL, g, NULL);
	if (name != NULL && *name != '\0')
		purple_blist_alias_buddy(b, name);
	bs = g_new0(struct fetion_buddy, 1);
	bs->name = g_strdup(b->name);
	g_hash_table_insert(sip->buddies, bs->name, bs);

	xmlnode_free(root);

	root = xmlnode_new("args");
	g_return_if_fail(root != NULL);
	son = xmlnode_new_child(root, "contacts");
	g_return_if_fail(son != NULL);
	son = xmlnode_new_child(son, "mobile-buddies");
	g_return_if_fail(son != NULL);
	item = xmlnode_new_child(son, "mobile-buddy");
	g_return_if_fail(item != NULL);

	xmlnode_set_attrib(item, "expose-mobile-no", "1");
	xmlnode_set_attrib(item, "expose-name", "1");
	xmlnode_set_attrib(item, "invite", "1");

	xmlnode_set_attrib(item, "uri", buddy_name);
	xmlnode_set_attrib(item, "buddy-lists", "1");
	//xmlnode_set_attrib(item,"desc",sip->mobileno);
	xmlnode_set_attrib(item, "desc", real_name);

	body = g_strdup_printf("%s",xmlnode_to_str(root, &xml_len));
	purple_debug_info("fetion:", "add_buddy:body=[%s]", body);

	send_sip_request(sip->gc, "S", "", "", "N: AddMobileBuddy\r\n", body,
			 NULL, (TransCallback) AddMobileBuddy_cb);

	g_free(buddy_name);
	xmlnode_free(root);
	g_free(body);

}
Ejemplo n.º 8
0
static void add_purple_buddy_to_groups(JabberStream *js, const char *jid,
		const char *alias, GSList *groups)
{
	GSList *buddies, *l;
	PurpleAccount *account = purple_connection_get_account(js->gc);

	buddies = purple_find_buddies(js->gc->account, jid);

	if(!groups) {
		if(!buddies)
			groups = g_slist_append(groups, g_strdup(_("Buddies")));
		else {
			/* TODO: What should we do here? Removing the local buddies
			 * is wrong, but so is letting the group state get out of sync with
			 * the server.
			 */
			g_slist_free(buddies);
			return;
		}
	}

	while(buddies) {
		PurpleBuddy *b = buddies->data;
		PurpleGroup *g = purple_buddy_get_group(b);

		buddies = g_slist_delete_link(buddies, buddies);

		/* XMPP groups are case-sensitive, but libpurple groups are
		 * case-insensitive. We treat a buddy in both "Friends" and "friends"
		 * as only being in one group, but if we push changes about the buddy
		 * to the server, the buddy will be dropped from one of the groups.
		 * Not optimal, but better than the alternative, I think.
		 */
		if((l = g_slist_find_custom(groups, purple_group_get_name(g), (GCompareFunc)purple_utf8_strcasecmp))) {
			/* The buddy is already on the local list. Update info. */
			const char *servernick, *balias;

			/* Previously stored serverside / buddy-supplied alias */
			if((servernick = purple_blist_node_get_string((PurpleBlistNode*)b, "servernick")))
				serv_got_alias(js->gc, jid, servernick);

			/* Alias from our roster retrieval */
			balias = purple_buddy_get_local_buddy_alias(b);
			if(alias && !purple_strequal(alias, balias))
				purple_serv_got_private_alias(js->gc, jid, alias);
			g_free(l->data);
			groups = g_slist_delete_link(groups, l);
		} else {
			/* This buddy isn't in the group on the server anymore */
			purple_debug_info("jabber", "jabber_roster_parse(): Removing %s "
			                  "from group '%s' on the local list\n",
			                  purple_buddy_get_name(b),
			                  purple_group_get_name(g));
			purple_blist_remove_buddy(b);
		}
	}

	if (groups) {
		char *tmp = roster_groups_join(groups);
		purple_debug_info("jabber", "jabber_roster_parse(): Adding %s to "
		                  "groups: %s\n", jid, tmp);
		g_free(tmp);
	}

	while(groups) {
		PurpleGroup *g = purple_find_group(groups->data);
		PurpleBuddy *b = purple_buddy_new(account, jid, alias);

		if(!g) {
			g = purple_group_new(groups->data);
			purple_blist_add_group(g, NULL);
		}

		purple_blist_add_buddy(b, NULL, g, NULL);
		purple_blist_alias_buddy(b, alias);

		g_free(groups->data);
		groups = g_slist_delete_link(groups, groups);
	}

	g_slist_free(buddies);
}
Ejemplo n.º 9
0
PurpleBuddy *tgp_blist_buddy_new  (struct tgl_state *TLS, tgl_peer_t *user) {
  PurpleBuddy *buddy = purple_buddy_new (tg_get_acc (TLS), tgp_blist_peer_get_purple_name (TLS, user->id), NULL);
  tgp_blist_buddy_set_id (buddy, user->id);
  return buddy;
}
Ejemplo n.º 10
0
static void pipe_handle_subscribe(struct purple_subscribe *subscribe) {
	PurpleAccount *account = NULL;
	extern_account_t *accounts = NULL;
	extern_user_t *users = NULL;
	int naccounts = 0, nusers = 0;
	int i, j;
	PurpleBuddy *buddy = NULL;

	int d = 0;

	const char *note;
	enum purple_publish_basic basic;
	enum purple_publish_activity activity;

	LM_DBG("calling find_accounts(\"%s\", &naccounts)\n", subscribe->from);
	accounts = find_accounts(subscribe->from, &naccounts);
	LM_DBG("found %d extra account(s) for <%s>", naccounts, subscribe->from);
	
	LM_DBG("calling find_users(\"%s\", &nusers)\n", subscribe->to);
	users = find_users(subscribe->to, &nusers);
	LM_DBG("found %d extra user(s) for <%s>", nusers, subscribe->to);

	for (i = 0; i < naccounts; i++) {
		LM_DBG("calling client_find_account(\"%s\")\n", accounts[i].username);
		account = client_find_account(&accounts[i]);
		//if ((account) && (purple_account_is_connected(account) || purple_account_is_connecting(account))) {
		if (account) {
			for (j = 0; j < nusers; j++) {
				if (!strcmp(accounts[i].protocol, users[j].protocol)) {
					LM_DBG("found matching protocol: %s\n", accounts[i].protocol);

					LM_DBG("subscribe expires : %d\n", subscribe->expires);
					if (subscribe->expires == 0)
						d = hashtable_dec_counter(users[j].username);
					else
						d = hashtable_inc_counter(users[j].username);
					
					LM_DBG("<%s> is now referenced %d times\n", users[j].username, d);
					if (d == 0) {
						LM_DBG("<%s> is no more referenced, removing presence...\n", users[j].username);
						if (purple_send_sip_publish(subscribe->to, users[j].username, PURPLE_BASIC_CLOSED, 0, NULL) < 0)
							LM_ERR("error sending presence for %s", subscribe->to);
						else
							LM_DBG("presence message sent successfully\n");
					}

					else {
	
						buddy = purple_find_buddy(account, users[j].username);
						if (buddy == NULL) {
							LM_DBG("<%s> not found in <%s> buddy list, adding\n", users[j].username, accounts[i].username);
							buddy = purple_buddy_new(account, users[j].username, users[j].username);
							//purple_blist_add_buddy(buddy, NULL, NULL, NULL);
							purple_account_add_buddy(account, buddy);
						}
						else {
							LM_DBG("<%s> found in <%s> buddy list, sending publish\n", users[j].username, accounts[i].username);
							PurplePresence *presence = purple_buddy_get_presence(buddy);
							PurpleStatus *status = purple_presence_get_active_status(presence);
							PurpleStatusType *type = purple_status_get_type(status);
							PurpleStatusPrimitive primitive = purple_status_type_get_primitive(type);
							note = purple_status_get_attr_string(status, "message");
							primitive_parse(primitive, &basic, &activity);

							if (purple_send_sip_publish(subscribe->to, users[j].username, basic, activity, note) < 0)
								LM_ERR("error sending presence for %s", subscribe->to);
							else
								LM_DBG("presence message sent successfully\n");
							
						}	
	
					}

					break;
				}
			}
		}
	}
	if (accounts)
		extern_account_free(accounts, naccounts);
	if (users)
		extern_user_free(users, nusers);
	
}
Ejemplo n.º 11
0
xmlnode * _h_elim_add_buddy ( const char *name ,
                              const char *id   ,
                              SEXP_VALUE *args ,
                              gpointer data    )
{
    ASSERT_ALISTP( args, id, name );

    elim_ping();
    
    int         loopc = 0;
    const char *aname = ALIST_VAL_STR( args, "account-name" );
    const char *proto = ALIST_VAL_STR( args, "im-protocol"  );
    gpointer    auid  = ALIST_VAL_PTR( args, "account-uid"  );

    PurpleAccount *acct = 
      auid ? find_acct_by_uid( auid ) : purple_accounts_find( aname, proto );

    if( !acct )
    {
        sexp_val_free( args );
        return response_error( ENXIO, id, name, "unknown account" );
    }

    const char *b_arg = ALIST_VAL_STRING( args, "bnode-name" );
    const char *bname = purple_normalize( acct, b_arg        );
    const char *gname = ALIST_VAL_STRING( args, "group"      );
    if( !gname || !*gname ) gname = "Buddies";

    PurpleGroup *group = purple_group_new( gname );
    PurpleBuddy *buddy = purple_buddy_new( acct, bname, b_arg );
    PurpleBuddy *clone = NULL;
    //fprintf( stderr, "add-buddy( b: %p, g: %p )\n", buddy, group );
    // remove other references to this buddy
    purple_blist_add_buddy  ( buddy, NULL, group, NULL );
    purple_account_add_buddy( acct , buddy );
    while( ( clone = (PurpleBuddy*)find_blist_node_clone( buddy ) ) )
    {
        if( loopc++ > 99   ) 
        {
            fprintf( stderr, "ARGH! clone reaping looped: %d\n", loopc );
            break;
        }
        if( clone == buddy ) 
        { 
            fprintf( stderr, "ARGH! %p not a clone of %p\n", buddy, clone );
            break;
        }
        fprintf( stderr, "(removing clone %p %ld (of buddy: %p)\n", 
                 clone, (long)clone, buddy );
        fprintf( stderr, "   name : %s\n", purple_buddy_get_name(clone) );
        fprintf( stderr, "   group: %s)\n", 
                 purple_group_get_name( purple_buddy_get_group(clone) ) );
        purple_blist_remove_buddy( clone );
    }

    xmlnode *rval = xnode_new( "alist" );
    AL_PTR( rval, "account-uid" , acct  );
    AL_PTR( rval, "bnode-uid"   , buddy );
    AL_PTR( rval, "group-uid"   , group );
    AL_STR( rval, "bnode-name"  , purple_buddy_get_name         ( buddy ) );
    AL_STR( rval, "bnode-alias" , purple_buddy_get_alias        ( buddy ) );
    AL_STR( rval, "account-name", purple_account_get_username   ( acct  ) );
    AL_STR( rval, "im-protocol" , purple_account_get_protocol_id( acct  ) );
    AL_STR( rval, "group-name"  , purple_group_get_name         ( group ) );

    sexp_val_free( args );
    return response_value( 0, id, name, rval );
}
Ejemplo n.º 12
0
static void
skypeweb_get_friend_list_cb(SkypeWebAccount *sa, JsonNode *node, gpointer user_data)
{
	JsonObject *obj;
	JsonArray *contacts;
	PurpleGroup *group = NULL;
	GSList *users_to_fetch = NULL;
	guint index, length;
	
	obj = json_node_get_object(node);
	contacts = json_object_get_array_member(obj, "contacts");
	length = json_array_get_length(contacts);
	
	for(index = 0; index < length; index++)
	{
		JsonObject *contact = json_array_get_object_element(contacts, index);
		const gchar *id = json_object_get_string_member(contact, "id");
		const gchar *display_name = json_object_get_string_member(contact, "display_name");
		const gchar *avatar_url = NULL;
		gboolean authorized = json_object_get_boolean_member(contact, "authorized");
		gboolean blocked = json_object_get_boolean_member(contact, "blocked");
		const gchar *type = json_object_get_string_member(contact, "type");
		
		JsonObject *name = json_object_get_object_member(contact, "name");
		const gchar *firstname = json_object_get_string_member(name, "first");
		const gchar *surname = NULL;
		PurpleBuddy *buddy;
		
		//TODO make this work for "pstn"
		if (!g_str_equal(type, "skype") && !g_str_equal(type, "msn"))
			continue;
		
		if (json_object_has_member(contact, "suggested") && json_object_get_boolean_member(contact, "suggested") && !authorized) {
			// suggested buddies wtf? some kind of advertising?
			continue;
		}
		
		buddy = purple_find_buddy(sa->account, id);
		if (!buddy)
		{
			if (!group)
			{
				group = purple_blist_find_group("Skype");
				if (!group)
				{
					group = purple_group_new("Skype");
					purple_blist_add_group(group, NULL);
				}
			}
			buddy = purple_buddy_new(sa->account, id, display_name);
			purple_blist_add_buddy(buddy, NULL, group, NULL);
		}
		
		if (json_object_has_member(name, "surname"))
			surname = json_object_get_string_member(name, "surname");

		// try to free the sbuddy here. no-op if it's not set before, otherwise prevents a leak.
		skypeweb_buddy_free(buddy);
		
		SkypeWebBuddy *sbuddy = g_new0(SkypeWebBuddy, 1);
		sbuddy->skypename = g_strdup(id);
		sbuddy->sa = sa;
		sbuddy->fullname = g_strconcat(firstname, (surname ? " " : NULL), surname, NULL);
		sbuddy->display_name = g_strdup(display_name);
		sbuddy->authorized = authorized;
		sbuddy->blocked = blocked;
		sbuddy->avatar_url = g_strdup(purple_buddy_icons_get_checksum_for_user(buddy));
		
		sbuddy->buddy = buddy;
		purple_buddy_set_protocol_data(buddy, sbuddy);
		
		purple_serv_got_alias(sa->pc, id, sbuddy->display_name);
		purple_blist_server_alias_buddy(buddy, sbuddy->fullname);
		
		if (json_object_has_member(contact, "avatar_url")) {
			avatar_url = json_object_get_string_member(contact, "avatar_url");
			if (avatar_url && *avatar_url && (!sbuddy->avatar_url || !g_str_equal(sbuddy->avatar_url, avatar_url))) {
				g_free(sbuddy->avatar_url);
				sbuddy->avatar_url = g_strdup(avatar_url);			
				skypeweb_get_icon(buddy);
			}
		}
		
		if (blocked == TRUE) {
			purple_privacy_deny_add(sa->account, id, TRUE);
		} else {
			users_to_fetch = g_slist_prepend(users_to_fetch, sbuddy->skypename);
		}
	}
	
	if (users_to_fetch)
	{
		//skypeweb_get_friend_profiles(sa, users_to_fetch);
		skypeweb_subscribe_to_contact_status(sa, users_to_fetch);
		g_slist_free(users_to_fetch);
	}
}
Ejemplo n.º 13
0
static gboolean ggp_roster_reply_list_read_buddy(PurpleConnection *gc,
	PurpleXmlNode *node, ggp_roster_content *content, GHashTable *remove_buddies)
{
	gchar *alias, *group_name = NULL;
	uin_t uin;
	gboolean succ = TRUE;
	PurpleXmlNode *group_list, *group_elem;
	PurpleBuddy *buddy = NULL;
	PurpleGroup *group = NULL;
	PurpleGroup *currentGroup;
	gboolean alias_changed;
	PurpleAccount *account = purple_connection_get_account(gc);

	succ &= ggp_xml_get_string(node, "ShowName", &alias);
	succ &= ggp_xml_get_uint(node, "GGNumber", &uin);

	group_list = purple_xmlnode_get_child(node, "Groups");
	succ &= (group_list != NULL);

	if (!succ) {
		g_free(alias);
		g_return_val_if_reached(FALSE);
	}

	g_hash_table_insert(content->contact_nodes, GINT_TO_POINTER(uin), node);

	/* check, if alias is set */
	if (strlen(alias) == 0 ||
		strcmp(alias, ggp_uin_to_str(uin)) == 0)
	{
		g_free(alias);
		alias = NULL;
	}

	/* getting (eventually creating) group */
	group_elem = purple_xmlnode_get_child(group_list, "GroupId");
	while (group_elem != NULL) {
		gchar *id;
		gboolean isbot;

		if (!ggp_xml_get_string(group_elem, NULL, &id))
			continue;
		isbot = (0 == g_strcmp0(id, content->bots_group_id));
		group_name = g_hash_table_lookup(content->group_names, id);
		g_free(id);

		/* we don't want to import bots;
		 * they are inserted to roster by default
		 */
		if (isbot) {
			g_free(alias);
			return TRUE;
		}

		if (group_name != NULL)
			break;

		group_elem = purple_xmlnode_get_next_twin(group_elem);
	}
	if (group_name) {
		group = purple_blist_find_group(group_name);
		if (!group) {
			group = purple_group_new(group_name);
			purple_blist_add_group(group, NULL);
		}
	}

	/* add buddy, if doesn't exists */
	buddy = purple_blist_find_buddy(account, ggp_uin_to_str(uin));
	g_hash_table_remove(remove_buddies, GINT_TO_POINTER(uin));
	if (!buddy) {
		purple_debug_info("gg", "ggp_roster_reply_list_read_buddy: "
			"adding %u (%s) to buddy list\n", uin, alias);
		buddy = purple_buddy_new(account, ggp_uin_to_str(uin), alias);
		purple_blist_add_buddy(buddy, NULL, group, NULL);
		ggp_roster_set_synchronized(gc, buddy, TRUE);

		g_free(alias);
		return TRUE;
	}

	/* buddy exists, but is not synchronized - local list has priority */
	if (!ggp_roster_is_synchronized(buddy)) {
		purple_debug_misc("gg", "ggp_roster_reply_list_read_buddy: "
			"ignoring not synchronized %u (%s)\n",
			uin, purple_buddy_get_name(buddy));
		g_free(alias);
		return TRUE;
	}

	currentGroup = ggp_purplew_buddy_get_group_only(buddy);
	alias_changed =
		(0 != g_strcmp0(alias, purple_buddy_get_alias_only(buddy)));

	if (currentGroup == group && !alias_changed) {
		g_free(alias);
		return TRUE;
	}

	purple_debug_misc("gg", "ggp_roster_reply_list_read_buddy: "
		"updating %u (%s) - alias=\"%s\"->\"%s\", group=%p->%p (%s)\n",
		uin, purple_buddy_get_name(buddy),
		purple_buddy_get_alias(buddy), alias,
		currentGroup, group, group_name);
	if (alias_changed)
		purple_buddy_set_local_alias(buddy, alias);
	if (currentGroup != group)
		purple_blist_add_buddy(buddy, NULL, group, NULL);

	g_free(alias);
	return TRUE;
}
Ejemplo n.º 14
0
static void
skypeweb_get_friend_list_cb(SkypeWebAccount *sa, JsonNode *node, gpointer user_data)
{
	JsonArray *friends;
	PurpleGroup *group = NULL;
	GSList *users_to_fetch = NULL;
	gint index, length;
	
	friends = json_node_get_array(node);
	length = json_array_get_length(friends);
	
	for(index = 0; index < length; index++)
	{
		JsonObject *friend = json_array_get_object_element(friends, index);
		const gchar *skypename = json_object_get_string_member(friend, "skypename");
		const gchar *fullname = json_object_get_string_member(friend, "fullname");
		const gchar *display_name = json_object_get_string_member(friend, "display_name");
		gboolean authorized = json_object_get_boolean_member(friend, "authorized");
		gboolean blocked = json_object_get_boolean_member(friend, "blocked");
		PurpleBuddy *buddy;
		
		buddy = purple_find_buddy(sa->account, skypename);
		if (!buddy)
		{
			if (!group)
			{
				group = purple_blist_find_group("Skype");
				if (!group)
				{
					group = purple_group_new("Skype");
					purple_blist_add_group(group, NULL);
				}
			}
			buddy = purple_buddy_new(sa->account, skypename, display_name);
			purple_blist_add_buddy(buddy, NULL, group, NULL);
		}
		
		SkypeWebBuddy *sbuddy = g_new0(SkypeWebBuddy, 1);
		sbuddy->skypename = g_strdup(skypename);
		sbuddy->sa = sa;
		sbuddy->fullname = g_strdup(fullname);
		sbuddy->display_name = g_strdup(display_name);
		sbuddy->authorized = authorized;
		sbuddy->blocked = blocked;
		
		sbuddy->buddy = buddy;
		purple_buddy_set_protocol_data(buddy, sbuddy);
		
		purple_serv_got_alias(sa->pc, skypename, sbuddy->display_name);
		purple_blist_server_alias_buddy(buddy, fullname);
		
		users_to_fetch = g_slist_prepend(users_to_fetch, sbuddy->skypename);
	}
	
	if (users_to_fetch)
	{
		skypeweb_get_friend_profiles(sa, users_to_fetch);
		skypeweb_subscribe_to_contact_status(sa, users_to_fetch);
		g_slist_free(users_to_fetch);
	}
}
Ejemplo n.º 15
0
//End VoxOx
static void add_purple_buddies_to_groups(JabberStream *js, const char *jid,
		const char *alias, GSList *groups)
{
	GSList *buddies, *g2, *l;
	gchar *my_bare_jid;
	GList *pool = NULL;

	buddies = purple_find_buddies(js->gc->account, jid);

	g2 = groups;

	if(!groups) {
		if(!buddies)
			g2 = g_slist_append(g2, g_strdup(_("Buddies")));
		else {
			g_slist_free(buddies);
			return;
		}
	}

	my_bare_jid = g_strdup_printf("%s@%s", js->user->node, js->user->domain);

	while(buddies) {
		PurpleBuddy *b = buddies->data;
		PurpleGroup *g = purple_buddy_get_group(b);

		buddies = g_slist_remove(buddies, b);

		if((l = g_slist_find_custom(g2, g->name, (GCompareFunc)strcmp))) {
			const char *servernick;

			/* Previously stored serverside / buddy-supplied alias */
			if((servernick = purple_blist_node_get_string((PurpleBlistNode*)b, "servernick")))
				serv_got_alias(js->gc, jid, servernick);

			/* Alias from our roster retrieval */
			if(alias && (!b->alias || strcmp(b->alias, alias)))
				purple_serv_got_private_alias(js->gc, jid, alias);
			g_free(l->data);
			g2 = g_slist_delete_link(g2, l);
		} else {
			pool = g_list_prepend(pool, b);
		}
	}

	while(g2) {
		PurpleGroup *g = purple_find_group(g2->data);
		PurpleBuddy *b = NULL;

		if (pool) {
			b = pool->data;
			pool = g_list_delete_link(pool, pool);
		} else {			
			b = purple_buddy_new(js->gc->account, jid, alias);
		}

		if(!g) {
			g = purple_group_new(g2->data);
			purple_blist_add_group(g, NULL);
		}

		purple_blist_add_buddy(b, NULL, g, NULL);
		purple_blist_alias_buddy(b, alias);

		/* If we just learned about ourself, then fake our status,
		 * because we won't be receiving a normal presence message
		 * about ourself. */
		if(!strcmp(b->name, my_bare_jid)) {
			PurplePresence *gpresence;
			PurpleStatus *status;

			gpresence = purple_account_get_presence(js->gc->account);
			status = purple_presence_get_active_status(gpresence);
			jabber_presence_fake_to_self(js, status);
		}

		g_free(g2->data);
		g2 = g_slist_delete_link(g2, g2);
	}

	while (pool) {
		PurpleBuddy *b = pool->data;
		purple_blist_remove_buddy(b);
		pool = g_list_delete_link(pool, pool);
	}

	g_free(my_bare_jid);
	g_slist_free(buddies);
}
Ejemplo n.º 16
0
void
fb_got_facepile(FacebookAccount *fba, const gchar *data, gsize data_len, gpointer user_data)
{
	gchar *group = user_data;
	JsonParser *parser;
	JsonObject *object, *payload, *user_obj;
	JsonArray *facepile;
	PurpleConversation *conv;
	PurpleConvChat *chat;
	gchar *uid;
	guint i;
	PurpleGroup *pgroup;
	
	purple_debug_info("facebook", "got facepile %s\n", data?data:"(null)");
	
	conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, group, fba->account);
	chat = PURPLE_CONV_CHAT(conv);
	
	parser = fb_get_parser(data, data_len);
	
	if (!parser)
	{
		purple_debug_warning("facebook",
			"could not fetch facepile for group %s\n", group);
		g_free(group);
		return;
	}
	
	object = fb_get_json_object(parser, NULL);
	payload = json_node_get_object(
		json_object_get_member(object, "payload"));
	facepile = json_node_get_array(
		json_object_get_member(payload, "facepile_click_info"));
	
	pgroup = purple_find_group(DEFAULT_GROUP_NAME);
	if (!pgroup)
	{
		pgroup = purple_group_new(DEFAULT_GROUP_NAME);
		purple_blist_add_group(pgroup, NULL);
	}

	purple_conv_chat_clear_users(chat);
	uid = g_strdup_printf("%" G_GINT64_FORMAT, fba->uid);
	purple_conv_chat_add_user(chat, uid, NULL, PURPLE_CBFLAGS_NONE, FALSE);
	if (!purple_find_buddy(fba->account, uid))
	{
		PurpleBuddy *buddy = purple_buddy_new(fba->account, uid, "You");
		purple_blist_node_set_flags((PurpleBlistNode *)buddy, PURPLE_BLIST_NODE_FLAG_NO_SAVE);
		purple_blist_add_buddy(buddy, NULL, pgroup, NULL);
	}
	g_free(uid);
	
	for (i = 0; i < json_array_get_length(facepile); i++)
	{
		user_obj = json_node_get_object(
			json_array_get_element(facepile, i));
		uid = g_strdup_printf("%" G_GINT64_FORMAT, (gint64)json_node_get_int(json_object_get_member(user_obj, "uid")));
		
		purple_conv_chat_add_user(PURPLE_CONV_CHAT(conv), uid, NULL, PURPLE_CBFLAGS_NONE, FALSE);
		
		if (!purple_find_buddy(fba->account, uid))
		{
			const char *alias = json_node_get_string(json_object_get_member(user_obj, "name"));
			PurpleBuddy *buddy = purple_buddy_new(fba->account, uid, alias);
			purple_blist_node_set_flags((PurpleBlistNode *)buddy, PURPLE_BLIST_NODE_FLAG_NO_SAVE);
			purple_blist_add_buddy(buddy, NULL, pgroup, NULL);
		}
		
		g_free(uid);
	}
	
	g_free(group);
}
Ejemplo n.º 17
0
GList *fb_get_buddies_friend_list (FacebookAccount *fba,
		const gchar *uid, JsonArray *friend_list_ids)
{
	GSList *buddies;
	GSList *cur;       
	GHashTable *cur_groups;
	int i;
	GList *final_buddies, *cur_buddy;
	PurpleGroup *fb_group;
	PurpleBuddy *buddy;

	final_buddies = NULL;
	buddies = purple_find_buddies(fba->account, uid);

	// If we're already in the buddy list, stop.  Ignore FB info because
	// it will be incorrect.
	if (atoll(uid) == fba->uid && buddies != NULL) {
		purple_debug_info("facebook",
			"already have buddies for self, not adding\n");
		for (cur = buddies; cur != NULL; cur = cur->next)
		{
			final_buddies = g_list_append(
				final_buddies, cur->data);
		}
		g_slist_free(buddies);
		return final_buddies;
	}
	
	//Do we want to ignore groups?
	if (!purple_account_get_bool(fba->account, "facebook_use_groups", TRUE))
	{
		if (buddies != NULL) {
			//Copy the slist into the list
			for (cur = buddies; cur != NULL; cur = cur->next)
			{
				final_buddies = g_list_append(
					final_buddies, cur->data);
			}
			g_slist_free(buddies);
			return final_buddies;
		} else {
			buddy = purple_buddy_new(fba->account, uid, NULL);
			fb_group = purple_find_group(DEFAULT_GROUP_NAME);
			if (fb_group == NULL)
			{
				fb_group = purple_group_new(DEFAULT_GROUP_NAME);
				purple_blist_add_group(fb_group, NULL);
			}
			purple_blist_add_buddy(buddy, NULL, fb_group, NULL);
			final_buddies = g_list_append(final_buddies, buddy);
			return final_buddies;
		}
	}
	
	// Determine what buddies exist and what groups they are in.
	cur_groups = g_hash_table_new_full(g_str_hash, g_str_equal,
		g_free, NULL);
	for (cur = buddies; cur != NULL; cur = cur->next)
	{
		const gchar *group_name;

		group_name = purple_group_get_name(purple_buddy_get_group(
					(PurpleBuddy *)cur->data));
		group_name = purple_normalize_nocase(NULL, group_name);
		
		g_hash_table_insert(cur_groups, g_strdup(group_name), cur->data);
	}
	g_slist_free(buddies);

	// Create/insert necessary buddies
	if (friend_list_ids) {
		for (i = 0; i < json_array_get_length(friend_list_ids); i++)
		{
			const gchar *friend_list_id;

			friend_list_id = json_node_get_string(
				json_array_get_element(friend_list_ids, i));

			buddy = add_buddy(fba, friend_list_id, uid, cur_groups);

			final_buddies = g_list_append(final_buddies, buddy);
		}
	} else {
		// No friend list data, so we use the default group.
		final_buddies = g_list_append(final_buddies,
			add_buddy(fba, "-1", uid, cur_groups));
	}

	// Figure out which groups/buddies are not represented.
	for (cur_buddy = final_buddies; cur_buddy != NULL;
	     cur_buddy = cur_buddy->next)
	{
		const gchar *group_name = purple_group_get_name(purple_buddy_get_group(
					(PurpleBuddy *)cur_buddy->data));
		g_hash_table_remove(cur_groups, purple_normalize_nocase(NULL, group_name));
	}

	// Delete remaining buddies to maintain sync state with server.
	g_hash_table_foreach(cur_groups, destroy_buddy, fba);

	// Cleanup!
	g_hash_table_destroy(cur_groups);

	return final_buddies;
}
Ejemplo n.º 18
0
/* void ggp_buddylist_load(PurpleConnection *gc, char *buddylist) {{{ */
void ggp_buddylist_load(PurpleConnection *gc, char *buddylist)
{
	PurpleBuddy *buddy;
	PurpleGroup *group;
	gchar **users_tbl;
	int i;
	char *utf8buddylist = ggp_convert_from_cp1250(buddylist);

	/* Don't limit the number of records in a buddylist. */
	users_tbl = g_strsplit(utf8buddylist, "\r\n", -1);

	for (i = 0; users_tbl[i] != NULL; i++) {
		gchar **data_tbl;
		gchar *name, *show, *g;

		if (!*users_tbl[i])
			continue;

		data_tbl = g_strsplit(users_tbl[i], ";", 8);
		if (g_strv_length(data_tbl) < 8) {
			purple_debug_warning("gg",
				"Something is wrong on line %d of the buddylist. Skipping.\n",
				i + 1);
			continue;
		}

		show = data_tbl[F_NICKNAME];
		name = data_tbl[F_UIN];
		if ('\0' == *name || !atol(name)) {
			purple_debug_warning("gg",
				"Identifier on line %d of the buddylist is not a number. Skipping.\n",
				i + 1);
			continue;
		}

		if ('\0' == *show) {
			show = name;
		}

		purple_debug_info("gg", "got buddy: name=%s; show=%s\n", name, show);

		if (purple_blist_find_buddy(purple_connection_get_account(gc), name)) {
			g_strfreev(data_tbl);
			continue;
		}

		g = g_strdup("Gadu-Gadu");

		if ('\0' != data_tbl[F_GROUP]) {
			/* XXX: Probably buddy should be added to all the groups. */
			/* Hard limit to at most 50 groups */
			gchar **group_tbl = g_strsplit(data_tbl[F_GROUP], ",", 50);
			if (g_strv_length(group_tbl) > 0) {
				g_free(g);
				g = g_strdup(group_tbl[0]);
			}
			g_strfreev(group_tbl);
		}

		buddy = purple_buddy_new(purple_connection_get_account(gc),
			name, strlen(show) ? show : NULL);

		if (!(group = purple_blist_find_group(g))) {
			group = purple_group_new(g);
			purple_blist_add_group(group, NULL);
		}

		purple_blist_add_buddy(buddy, NULL, group, NULL);
		g_free(g);

		g_strfreev(data_tbl);
	}
	g_strfreev(users_tbl);
	g_free(utf8buddylist);

	ggp_buddylist_send(gc);
}
Ejemplo n.º 19
0
static void parse_new_messages(PurpleConnection *pc, FacebookAccount *fba, JsonArray *messages)
{
	int i;
	PurpleBuddy *buddy;

	purple_debug_info("facebook", "parsing new messages\n");

	for (i = 0; i < json_array_get_length(messages); i++) {
		const gchar *type;
		gchar *from, *to;
		

		JsonObject *object = json_node_get_object(json_array_get_element(messages, i));
		type = json_node_get_string(json_object_get_member(object, "type"));

		from = g_strdup_printf("%" G_GINT64_FORMAT, (gint64)json_node_get_int(json_object_get_member(object, "from")));
		to = g_strdup_printf("%" G_GINT64_FORMAT, (gint64)json_node_get_int(json_object_get_member(object, "to")));
		
		/* Use the in-line buddy name if the buddy list hasn't been downloaded yet */
		buddy = purple_find_buddy(pc->account, from);
		if (buddy == NULL || buddy->server_alias == NULL || buddy->alias == NULL)
		{
			if (json_object_has_member(object, "from_name"))
			{
				const gchar *from_name = json_node_get_string(json_object_get_member(
					object, "from_name"));
				fb_blist_set_alias(fba, from, from_name);
			}
		}

		if (from && to && g_str_equal(type, "msg")) {
			JsonObject *messageObj = json_node_get_object(json_object_get_member(object, "msg"));
			parse_message(pc, fba, messageObj, from, to, PURPLE_CONV_TYPE_IM);
		} else if (from && g_str_equal(type, "typ")) {
			purple_debug_info("facebook", "handling typing notification\n");

			gint typing = json_node_get_int(json_object_get_member(object, "st"));
			if (typing == 0) {
				serv_got_typing(pc, from, 10, PURPLE_NOT_TYPING);
			} else {
				serv_got_typing(pc, from, 10, PURPLE_TYPING);
			}
		} else if (g_str_equal(type, "group_msg")) {
			PurpleConversation *conv = fb_find_chat(fba, to);
			
			if (conv != NULL)
			{			
				if (json_object_has_member(object, "to_name"))
				{
					const gchar *to_name = json_node_get_string(json_object_get_member(
						object, "to_name"));
					purple_conversation_set_title(conv, to_name);

					PurpleChat *chat = purple_blist_find_chat(fba->account, to);
					purple_blist_alias_chat(chat, to_name);
				}
				if (!purple_conv_chat_cb_find(PURPLE_CONV_CHAT(conv), from))
				{
					purple_conv_chat_add_user(PURPLE_CONV_CHAT(conv), from, NULL, PURPLE_CBFLAGS_NONE, FALSE);
				}
				if (!purple_find_buddy(fba->account, from))
				{
					const char *from_name = json_node_get_string(json_object_get_member(
						object, "from_name"));
					buddy = purple_buddy_new(fba->account, from, from_name);
					purple_blist_node_set_flags((PurpleBlistNode *)buddy, PURPLE_BLIST_NODE_FLAG_NO_SAVE);
					purple_blist_add_buddy(buddy, NULL, purple_find_group(DEFAULT_GROUP_NAME), NULL);
				}
			}

			JsonObject *messageObj = json_node_get_object(json_object_get_member(object, "msg"));
			parse_message(pc, fba, messageObj, from, to, PURPLE_CONV_TYPE_CHAT);
		}

		/*
		 * we've received something from a buddy, assume they're online
		 * only if it's not from ourselves
		 */
		if (from && fba->uid != atoll(from)) {
			purple_prpl_got_user_status(
				fba->account, from, 
				purple_primitive_get_id_from_type(PURPLE_STATUS_AVAILABLE), NULL);

		}
	
		g_free(from);
		g_free(to);

		fba->message_fetch_sequence++;
	}
}
Ejemplo n.º 20
0
void SpectrumRosterManager::handleSubscription(const Subscription &subscription) {
	std::string remote_user = purpleUsername(subscription.to().username());
	if (remote_user.empty()) {
		Log(m_user->jid(), "handleSubscription: Remote user is EMPTY!");
		return;
	}

	if (m_user->isConnected()) {
		PurpleBuddy *buddy = NULL;

		// Try to get PurpleBuddy from SpectrumBuddy at first, because SpectrumBuddy
		// uses normalized username (buddy->name could be "User", but remote_user is normalized
		// so it's "user" for example).
		AbstractSpectrumBuddy *s_buddy = getRosterItem(remote_user);
		if (s_buddy)
			buddy = s_buddy->getBuddy();
		else
			buddy = purple_find_buddy(m_user->account(), remote_user.c_str());

		if (subscription.subtype() == Subscription::Subscribed) {
			// Accept authorize request.
			if (hasAuthRequest(remote_user)) {
				Log(m_user->jid(), "subscribed presence for authRequest arrived => accepting the request");
				m_authRequests[remote_user]->authorize_cb(m_authRequests[remote_user]->user_data);
				removeAuthRequest(remote_user);
			}

			if (!isInRoster(remote_user, "both")) {
				if (buddy) {
					Log(m_user->jid(), "adding this user to local roster and sending presence");
					if (s_buddy == NULL) {
						// There is PurpleBuddy, but not SpectrumBuddy (that should not happen, but this
						// code doesn't break anything).
						addRosterItem(buddy);
						Transport::instance()->sql()->addBuddy(m_user->storageId(), remote_user, "both");
						storeBuddy(buddy);
					}
					else {
						// Update subscription.
						s_buddy->setSubscription("both");
						Transport::instance()->sql()->updateBuddySubscription(m_user->storageId(), remote_user, "both");
						storeBuddy(buddy);
					}
				} else {
					Log(m_user->jid(), "user is not in legacy network contact lists => nothing to be subscribed");
				}
			}

			// XMPP user is able to get the first status presence just after "subscribed" presence.
			if (s_buddy) {
				sendPresence(s_buddy);
			}
			return;
		}
		else if (subscription.subtype() == Subscription::Subscribe) {
			// User is in roster, so that's probably response for RIE.
			if (s_buddy) {
				Log(m_user->jid(), "subscribe presence; user is already in roster => sending subscribed");

				s_buddy->setSubscription("to");
				Tag *reply = new Tag("presence");
				reply->addAttribute( "to", subscription.from().bare() );
				reply->addAttribute( "from", subscription.to().bare() );
				reply->addAttribute( "type", "subscribe" );
				Transport::instance()->send( reply );

				reply = new Tag("presence");
				reply->addAttribute( "to", subscription.from().bare() );
				reply->addAttribute( "from", subscription.to().bare() );
				reply->addAttribute( "type", "subscribed" );
				Transport::instance()->send( reply );

				// Sometimes there is "subscribed" request for new user received before "subscribe",
				// so s_buddy could be already there, but purple_account_add_buddy has not been called.
				if (buddy) {
					Log(m_user->jid(), "Trying to purple_account_add_buddy just to be sure.");
					purple_account_add_buddy(m_user->account(), buddy);
				}
			}
			// User is not in roster, so that's probably new subscribe request.
			else {
				Log(m_user->jid(), "subscribe presence; user is not in roster => adding to legacy network");
				// Disable handling new-buddy event, because we're going to create new buddy by Spectrum, not
				// by libpurple (so we don't want to add it to RIE queue and send back to XMPP user).
				m_loadingFromDB = true;
				PurpleBuddy *buddy = purple_buddy_new(m_user->account(), remote_user.c_str(), remote_user.c_str());
#ifndef TESTS
				SpectrumBuddy *s_buddy = new SpectrumBuddy(-1, buddy);
				buddy->node.ui_data = (void *) s_buddy;
				s_buddy->setSubscription("to");
				if (usesJidEscaping(subscription.to().username()))
					s_buddy->setFlags(s_buddy->getFlags() | SPECTRUM_BUDDY_JID_ESCAPING);
				addRosterItem(s_buddy);
#endif
				// Add newly created buddy to legacy network roster.
				purple_blist_add_buddy(buddy, NULL, NULL ,NULL);
				purple_account_add_buddy(m_user->account(), buddy);
				m_loadingFromDB = false;
			}
			return;
		} else if (subscription.subtype() == Subscription::Unsubscribe || subscription.subtype() == Subscription::Unsubscribed) {
			if (subscription.subtype() == Subscription::Unsubscribed) {
				// Reject authorize request.
				if (hasAuthRequest(remote_user)) {
					Log(m_user->jid(), "unsubscribed presence for authRequest arrived => rejecting the request");
					m_authRequests[remote_user]->deny_cb(m_authRequests[remote_user]->user_data);
					removeAuthRequest(remote_user);
					return;
				}
			}

			// Buddy is in legacy network roster, so we can remove it.
			if (buddy) {
				Log(m_user->jid(), "unsubscribed presence => removing this contact from legacy network");
				// Remove buddy from database, if he's already there.
				if (s_buddy) {
					long id = s_buddy->getId();
					Transport::instance()->sql()->removeBuddy(m_user->storageId(), remote_user, id);
				}

				// Remove buddy from legacy network roster.
				purple_account_remove_buddy(m_user->account(), buddy, purple_buddy_get_group(buddy));
				purple_blist_remove_buddy(buddy);
			} else {
				// this buddy is not in legacy network roster, so there is nothing to remove...
			}

			removeFromLocalRoster(remote_user);

			// inform user about removing this buddy
			Tag *tag = new Tag("presence");
			tag->addAttribute("to", subscription.from().bare());
			tag->addAttribute("from", subscription.to().username() + "@" + Transport::instance()->jid() + "/bot");
			if(subscription.subtype() == Subscription::Unsubscribe) {
				tag->addAttribute( "type", "unsubscribe" );
			} else {
				tag->addAttribute( "type", "unsubscribed" );
			}
			Transport::instance()->send( tag );
			return;
		}
	}
	else {
		Log(subscription.from().full(), "Subscribe presence received, but is not connected to legacy network yet.");
	}
}
Ejemplo n.º 21
0
gboolean
GetContactList_cb(struct fetion_account_data *sip, struct sipmsg *msg,
		  struct transaction *tc)
{
	xmlnode *item, *group, *isc;
	const gchar *name_group, *group_id;
	PurpleBuddy *b;
	PurpleGroup *g = NULL;
	struct fetion_buddy *bs;
	struct group_attr *g_attr;
	gint len = msg->bodylen;

	purple_debug(PURPLE_DEBUG_MISC, "fetion",
		     "in process GetContactList response response: %d\n",
		     msg->response);
	switch (msg->response) {
	case 200:

		/*Convert the contact from XML to Purple Buddies */
		isc = xmlnode_from_str(msg->body, len);
		purple_debug_info("fetion:", "after xmlnode to str\n");
		group = xmlnode_get_child(isc, "contacts/buddy-lists");
		g_return_val_if_fail(group != NULL, FALSE);

		/* ToDo. Find for all groups */
		sip->GetContactFlag = 1;
		for ((group = xmlnode_get_child(group, "buddy-list")); group;
		     group = xmlnode_get_next_twin(group)) {
			purple_debug_info("fetion:", "buddy-list\n");
			name_group = xmlnode_get_attrib(group, "name");
			group_id = xmlnode_get_attrib(group, "id");
			g_return_val_if_fail(name_group != NULL, FALSE);
			purple_debug_info("fetion", "name_group->%s\n",
					  name_group);
			g = purple_find_group(name_group);
			if (!g) {
				g = purple_group_new(name_group);
			}
			g_attr = g_new0(struct group_attr, 1);
			g_attr->name = g_strdup(name_group);
			g_attr->id = g_strdup(group_id);
			g_hash_table_insert(sip->group, g_attr->id, g_attr);
			g_hash_table_insert(sip->group2id, g_attr->name,
					    g_attr);
		}

		group = xmlnode_get_child(isc, "contacts/buddies");
		g_return_val_if_fail(group != NULL, FALSE);

		for (item = xmlnode_get_child(group, "buddy"); item;
		     item = xmlnode_get_next_twin(item)) {
			const gchar *uri, *name;
			char *buddy_name;
			const gchar *g_id;
			uri = xmlnode_get_attrib(item, "uri");
			name = xmlnode_get_attrib(item, "local-name");
			g_id = xmlnode_get_attrib(item, "buddy-lists");

			buddy_name = g_strdup_printf("%s", uri);
			if ((g_id == NULL) || (*g_id == '\0')
			    || strlen(g_id) > 1) {
				g = purple_find_group("未分组");
				if (!g)
					g = purple_group_new("未分组");
			} else {
				g_attr = g_hash_table_lookup(sip->group, g_id);
				g_return_val_if_fail(g_attr != NULL, FALSE);
				g = purple_find_group(g_attr->name);

				if (!g)
					g = purple_group_new(g_attr->name);
			}

			b = purple_find_buddy(sip->account, buddy_name);
			if (!b) {
				b = purple_buddy_new(sip->account, buddy_name,
						     NULL);
			}
			g_free(buddy_name);

			purple_blist_add_buddy(b, NULL, g, NULL);
			if (name != NULL && *name != '\0')
				purple_blist_alias_buddy(b, name);
			bs = g_new0(struct fetion_buddy, 1);
			bs->name = g_strdup(b->name);
			g_hash_table_insert(sip->buddies, bs->name, bs);

			purple_prpl_got_user_status(sip->account, uri, "mobile",
						    NULL);

		}
		group = xmlnode_get_child(isc, "contacts/mobile-buddies");
		g_return_val_if_fail(group != NULL, FALSE);

		for (item = xmlnode_get_child(group, "mobile-buddy"); item;
		     item = xmlnode_get_next_twin(item)) {
			const gchar *uri, *name;
			gchar *buddy_name;
			const gchar *g_id;
			uri = xmlnode_get_attrib(item, "uri");
			name = xmlnode_get_attrib(item, "local-name");
			g_id = xmlnode_get_attrib(item, "buddy-lists");

			buddy_name = g_strdup_printf("%s", uri);
			if ((g_id == NULL) || (*g_id == '\0')
			    || strlen(g_id) > 1) {
				g = purple_find_group("未分组");
				if (!g)
					g = purple_group_new("未分组");
			} else {
				g_attr = g_hash_table_lookup(sip->group, g_id);
				//g_return_val_if_fail(g_attr!=NULL,FALSE);
				if (g_attr == NULL)
					continue;
				g = purple_find_group(g_attr->name);
				if (!g)
					g = purple_group_new(g_attr->name);
			}

			b = purple_find_buddy(sip->account, buddy_name);
			if (!b) {
				b = purple_buddy_new(sip->account, buddy_name,
						     uri);
			}
			g_free(buddy_name);

			purple_blist_add_buddy(b, NULL, g, NULL);
			if (name != NULL && *name != '\0')
				purple_blist_alias_buddy(b, name);
			else
				purple_blist_alias_buddy(b, uri);
			bs = g_new0(struct fetion_buddy, 1);
			bs->name = g_strdup(b->name);
			g_hash_table_insert(sip->buddies, bs->name, bs);
			purple_prpl_got_user_status(sip->account, uri, "mobile",
						    NULL);
		}

		fetion_subscribe_exp(sip, NULL);
		//Add youself

		b = purple_find_buddy(sip->account, sip->uri);
		if (!b) {
			b = purple_buddy_new(sip->account, sip->uri, NULL);
		}

		purple_blist_add_buddy(b, NULL, g, NULL);
		purple_blist_alias_buddy(b, "轰炸自己");
		bs = g_new0(struct fetion_buddy, 1);
		bs->name = g_strdup(b->name);
		g_hash_table_insert(sip->buddies, bs->name, bs);

		purple_prpl_got_user_status(sip->account, sip->uri, "mobile",
					    NULL);

		xmlnode_free(isc);

		break;
	default:
		GetContactList(sip);
		break;
	}

	return TRUE;
}
Ejemplo n.º 22
0
/**
 * If the buddy does not yet exist, then create it and add it to
 * our buddy list.  In either case we set the correct status for
 * the buddy.
 */
void
bonjour_buddy_add_to_purple(BonjourBuddy *bonjour_buddy)
{
	PurpleBuddy *buddy;
	PurpleGroup *group;
	PurpleAccount *account = bonjour_buddy->account;
	const char *status_id, *old_hash, *new_hash;

	/* Translate between the Bonjour status and the Purple status */
	if (bonjour_buddy->status != NULL && g_ascii_strcasecmp("dnd", bonjour_buddy->status) == 0)
		status_id = BONJOUR_STATUS_ID_AWAY;
	else
		status_id = BONJOUR_STATUS_ID_AVAILABLE;

	/*
	 * TODO: Figure out the idle time by getting the "away"
	 * field from the DNS SD.
	 */

	/* Make sure the Bonjour group exists in our buddy list */
	group = purple_find_group(BONJOUR_GROUP_NAME); /* Use the buddy's domain, instead? */
	if (group == NULL) {
		group = purple_group_new(BONJOUR_GROUP_NAME);
		purple_blist_add_group(group, NULL);
	}

	/* Make sure the buddy exists in our buddy list */
	buddy = purple_find_buddy(account, bonjour_buddy->name);

	if (buddy == NULL) {
		buddy = purple_buddy_new(account, bonjour_buddy->name, NULL);
		buddy->proto_data = bonjour_buddy;
		purple_blist_node_set_flags((PurpleBlistNode *)buddy, PURPLE_BLIST_NODE_FLAG_NO_SAVE);
		purple_blist_add_buddy(buddy, NULL, group, NULL);
	}

	/* Create the alias for the buddy using the first and the last name */
	if (bonjour_buddy->nick)
		serv_got_alias(purple_account_get_connection(account), buddy->name, bonjour_buddy->nick);
	else {
		gchar *alias = NULL;
		const char *first, *last;
		first = bonjour_buddy->first;
		last = bonjour_buddy->last;
		if ((first && *first) || (last && *last))
			alias = g_strdup_printf("%s%s%s",
						(first && *first ? first : ""),
						(first && *first && last && *last ? " " : ""),
						(last && *last ? last : ""));
		serv_got_alias(purple_account_get_connection(account), buddy->name, alias);
		g_free(alias);
	}

	/* Set the user's status */
	if (bonjour_buddy->msg != NULL)
		purple_prpl_got_user_status(account, buddy->name, status_id,
					    "message", bonjour_buddy->msg, NULL);
	else
		purple_prpl_got_user_status(account, buddy->name, status_id, NULL);

	purple_prpl_got_user_idle(account, buddy->name, FALSE, 0);

	/* TODO: Because we don't save Bonjour buddies in blist.xml,
	 * we will always have to look up the buddy icon at login time.
	 * I think we should figure out a way to do something about this. */

	/* Deal with the buddy icon */
	old_hash = purple_buddy_icons_get_checksum_for_user(buddy);
	new_hash = (bonjour_buddy->phsh && *(bonjour_buddy->phsh)) ? bonjour_buddy->phsh : NULL;
	if (new_hash && (!old_hash || strcmp(old_hash, new_hash) != 0)) {
		/* Look up the new icon data */
		/* TODO: Make sure the hash assigned to the retrieved buddy icon is the same
		 * as what we looked up. */
		bonjour_dns_sd_retrieve_buddy_icon(bonjour_buddy);
	} else if (!new_hash)
		purple_buddy_icons_set_for_user(account, buddy->name, NULL, 0, NULL);
}
Ejemplo n.º 23
0
static void
pb_got_everything(PushBulletAccount *pba, JsonNode *node, gpointer user_data)
{
	JsonObject *rootobj = json_node_get_object(node);
	JsonArray *devices = json_object_has_member(rootobj, "devices") ? json_object_get_array_member(rootobj, "devices") : NULL;
	JsonArray *pushes = json_object_has_member(rootobj, "pushes") ? json_object_get_array_member(rootobj, "pushes") : NULL;
	JsonArray *contacts = json_object_has_member(rootobj, "contacts") ? json_object_get_array_member(rootobj, "contacts") : NULL;
	JsonArray *chats = json_object_has_member(rootobj, "chats") ? json_object_get_array_member(rootobj, "chats") : NULL;
	JsonArray *texts = json_object_has_member(rootobj, "texts") ? json_object_get_array_member(rootobj, "texts") : NULL;
	gint i;
	guint len;
	PurpleGroup *pbgroup;
	
	pbgroup = purple_find_group("PushBullet");
	if (!pbgroup)
	{
		pbgroup = purple_group_new("PushBullet");
		purple_blist_add_group(pbgroup, NULL);
	}
	
	if (json_object_has_member(rootobj, "error")) {
		JsonObject *error = json_object_get_object_member(rootobj, "error");
		const gchar *type = json_object_get_string_member(error, "type");
		const gchar *message = json_object_get_string_member(error, "message");
		
		//TODO check type
		purple_connection_error_reason(pba->pc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, message);
		return;
	}
	
	if (devices != NULL) {
		for(i = 0, len = json_array_get_length(devices); i < len; i++) {
			JsonObject *device = json_array_get_object_element(devices, i);
			
			if (pba->main_sms_device == NULL && json_object_get_boolean_member(device, "has_sms")) {
				pba->main_sms_device = g_strdup(json_object_get_string_member(device, "iden"));
				purple_account_set_string(pba->account, "main_sms_device", pba->main_sms_device);
				
				pb_get_phonebook(pba, pba->main_sms_device);
				
				if (!pba->websocket) {
					pb_start_polling(pba);
				}
				
				break; //TODO handle more than one
			}
		}
	}
	
	if (pushes != NULL) {
		gint last_message_timestamp = purple_account_get_int(pba->account, "last_message_timestamp", 0);
		for(i = json_array_get_length(pushes); i > 0; i--) {
			JsonObject *push = json_array_get_object_element(pushes, i - 1);
			const gchar *type = json_object_get_string_member(push, "type");
			gdouble modified;
			time_t timestamp;
			gboolean dismissed;
			
			if (!type)
				continue;
			
			modified = json_object_get_double_member(push, "modified");
			timestamp = (time_t) modified;
			dismissed = json_object_get_boolean_member(push, "dismissed");
			
			if (timestamp <= last_message_timestamp || dismissed) {
				continue;
			}
			
			// {"active":true,"iden":"uffvytgsjApuAUIFRk","created":1.438895081423904e+09,"modified":1.438895081432786e+09,"type":"file","dismissed":false,"guid":"153b70f0-f7a6-4db9-a6f4-28b99fa416f1","direction":"self","sender_iden":"uffvytg","sender_email":"*****@*****.**","sender_email_normalized":"*****@*****.**","sender_name":"Eion Robb","receiver_iden":"uffvytg","receiver_email":"*****@*****.**","receiver_email_normalized":"*****@*****.**","target_device_iden":"uffvytgsjz7O3P0Jl6","source_device_iden":"uffvytgsjAoIRwhIL6","file_name":"IMG_20150807_084618.jpg","file_type":"image/jpeg","file_url":"https://dl.pushbulletusercontent.com/FHOZdyzfvnoYZY0DP6oK1rGKiJpWCPc0/IMG_20150807_084618.jpg","image_width":4128,"image_height":2322,"image_url":"https://lh3.googleusercontent.com/WY5TK7h3mzD32qMcnxtqt-4PrYcWW1uWDHnRW2x1oJK8mnYk2v4HbZrRjIQkiYdxMKQSdNI8GGPqfO6s6tEyuRVLzeA"}
			
			if (purple_strequal(type, "note") || purple_strequal(type, "link") || purple_strequal(type, "file")) {
				const gchar *from = json_object_get_string_member(push, "sender_email_normalized");
				const gchar *body = json_object_get_string_member(push, "body");
				const gchar *direction = json_object_get_string_member(push, "direction");
				gchar *body_html;
				
				if (from == NULL) {
					if (!json_object_has_member(push, "sender_name")) {
						purple_debug_error("pushbullet", "no sender name/email\n");
						continue;
					}
					from = json_object_get_string_member(push, "sender_name");
				}
				
				if (body && *body) {
					body_html = purple_strdup_withhtml(body);
				} else {
					const gchar *title = json_object_get_string_member(push, "title");
					if (title && *title) {
						body_html = purple_strdup_withhtml(title);
					} else {
						body_html = "Message";
					}
				}
				
				if (json_object_has_member(push, "url")) {
					gchar *body_with_link = g_strconcat("<a href=\"", json_object_get_string_member(push, "url"), "\">", body_html, "</a>", NULL);
					g_free(body_html);
					body_html = body_with_link;
					
				} else if (json_object_has_member(push, "image_url")) {
					const gchar *image_url = json_object_get_string_member(push, "image_url");
					PurpleConversation *conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, from, pba->account);
					
					if (conv == NULL)
					{
						conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, pba->account, from);
					}
					pb_download_image_to_conv(image_url, conv);
					
				} else if (json_object_has_member(push, "file_url")) {
					gchar *body_with_link;
					const gchar *file_name = json_object_get_string_member(push, "file_name");
					
					if (file_name && *file_name) {
						g_free(body_html);
						body_html = purple_strdup_withhtml(file_name);
					}
					
					body_with_link= g_strconcat("<a href=\"", json_object_get_string_member(push, "file_url"), "\">", json_object_get_string_member(push, "file_name"), "</a>", NULL);
					g_free(body_html);
					body_html = body_with_link;
				}
				
				if (direction[0] != 'o') {
					serv_got_im(pba->pc, from, body_html, PURPLE_MESSAGE_RECV, timestamp);
				} else {
					const gchar *guid = json_object_get_string_member(push, "guid");
					from = json_object_get_string_member(push, "receiver_email_normalized");
					
					if (!guid || !g_hash_table_remove(pba->sent_messages_hash, guid)) {
						PurpleConversation *conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, from, pba->account);
						if (conv == NULL)
						{
							conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, pba->account, from);
						}
						purple_conversation_write(conv, from, body_html, PURPLE_MESSAGE_SEND, timestamp);
					}
				}
				
				g_free(body_html);
			}
				
			purple_account_set_int(pba->account, "last_message_timestamp", MAX(purple_account_get_int(pba->account, "last_message_timestamp", 0), timestamp));
		}
	}
	
	if (contacts != NULL) {
		for(i = 0, len = json_array_get_length(contacts); i < len; i++) {
			JsonObject *contact = json_array_get_object_element(contacts, i);
			const gchar *email = json_object_get_string_member(contact, "email_normalized");
			const gchar *name = json_object_get_string_member(contact, "name");
			const gchar *image_url = json_object_get_string_member(contact, "image_url");
			
			PurpleBuddy *buddy = purple_find_buddy(pba->account, email);
			if (buddy == NULL)
			{
				buddy = purple_buddy_new(pba->account, email, name);
				purple_blist_add_buddy(buddy, NULL, pbgroup, NULL);
			}
			purple_prpl_got_user_status(pba->account, email, purple_primitive_get_id_from_type(PURPLE_STATUS_AVAILABLE), NULL);
		}
	}
	
	if (chats != NULL) {
		for(i = 0, len = json_array_get_length(chats); i < len; i++) {
			JsonObject *chat = json_array_get_object_element(chats, i);
			JsonObject *contact = json_object_get_object_member(chat, "with");
			const gchar *email = json_object_get_string_member(contact, "email_normalized");
			const gchar *name = json_object_get_string_member(contact, "name");
			const gchar *image_url = json_object_get_string_member(contact, "image_url");
			
			PurpleBuddy *buddy = purple_find_buddy(pba->account, email);
			if (buddy == NULL)
			{
				buddy = purple_buddy_new(pba->account, email, name);
				purple_blist_add_buddy(buddy, NULL, pbgroup, NULL);
			}
			purple_prpl_got_user_status(pba->account, email, purple_primitive_get_id_from_type(PURPLE_STATUS_AVAILABLE), NULL);
		}
	}
	
	if (texts != NULL) {
		for(i = 0, len = json_array_get_length(texts); i < len; i++) {
			JsonObject *text = json_array_get_object_element(texts, i);
		}
	}
}
Ejemplo n.º 24
0
void IMInvoker::send(void *userdata, const std::string event) {
	// we are in the thread that manages all of libpurple
	EventContext* ctx = (EventContext*)userdata;

	if (!ctx)
		return;

	if (!ctx->instance || !ctx->instance->_account) {
		ctx->instance->returnErrorExecution("No account available");
		delete(ctx);
		return;
	}

	if (iequals(ctx->sendReq.name, "im.send")) {
		std::string receiver;
		Event::getParam(ctx->sendReq.params, "receiver", receiver);

		Data data;
		Event::getParam(ctx->sendReq.params, "data", data);

#if LIBPURPLE_VERSION_MAJOR >= 3
		PurpleIMConversation* conv = purple_im_conversation_new(ctx->instance->_account, receiver.c_str());
		if (ctx->sendReq.content.length() > 0)
			purple_conversation_send(PURPLE_CONVERSATION(conv), ctx->sendReq.content.c_str());
#else
		PurpleConversation* conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, ctx->instance->_account, receiver.c_str());
		if (ctx->sendReq.content.length() > 0)
			purple_conv_im_send(purple_conversation_get_im_data(conv), ctx->sendReq.content.c_str());
#endif

#if 0
		if (data.binary) {
			PurpleConnection *gc = purple_account_get_connection(ctx->instance->_account);
			PurplePlugin *prpl;
			PurplePluginProtocolInfo *prpl_info;


			if (gc) {
				prpl = purple_connection_get_prpl(gc);
				prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);

//					if (prpl_info && prpl_info->new_xfer) {
//						PurpleXfer* xfer = (prpl_info->new_xfer)(purple_account_get_connection(ctx->instance->_account), receiver.c_str());
//						purple_xfer_set_local_filename(xfer, "/Users/sradomski/Documents/W3C Standards.pdf");
//						purple_xfer_set_filename(xfer, "asdfadsf.pdf");
//						purple_xfer_request(xfer);
//						purple_xfer_request_accepted(xfer, "/Users/sradomski/Documents/W3C Standards.pdf");
//					}

				//Set the filename
//					purple_xfer_set_local_filename(xfer, [[fileTransfer localFilename] UTF8String]);
//					purple_xfer_set_filename(xfer, [[[fileTransfer localFilename] lastPathComponent] UTF8String]);
//					xfer->ui_data
//					purple_xfer_request(xfer);

				serv_send_file(gc, "sradomski@localhost", "/Users/sradomski/Documents/W3C Standards.pdf");
//					if (prpl_info->send_file && (prpl_info->can_receive_file && prpl_info->can_receive_file(gc, receiver.c_str()))) {
//						prpl_info->send_file(gc, receiver.c_str(), "/Users/sradomski/Documents/W3C Standards.pdf");
//					}
//						prpl_info->send_raw(gc, data.binary->data, data.binary->size);
			}

		}
#endif
	} else if (iequals(ctx->sendReq.name, "im.buddy.add")) {
		std::string buddyName;
		Event::getParam(ctx->sendReq.params, "name", buddyName);

		std::string reqMsg;
		Event::getParam(ctx->sendReq.params, "msg", reqMsg);

		PurpleBuddy* buddy = purple_buddy_new(ctx->instance->_account, buddyName.c_str(), NULL);
		purple_blist_add_buddy(buddy, NULL, NULL, NULL);
#if LIBPURPLE_VERSION_MAJOR >= 3
		purple_account_add_buddy(ctx->instance->_account, buddy, reqMsg.c_str());
#else
		purple_account_add_buddy(ctx->instance->_account, buddy);
#endif

	} else if (iequals(ctx->sendReq.name, "im.buddy.remove")) {
		std::string buddyName;
		Event::getParam(ctx->sendReq.params, "name", buddyName);

#if LIBPURPLE_VERSION_MAJOR >= 3
		PurpleBuddy* buddy = purple_blist_find_buddy(ctx->instance->_account, buddyName.c_str());
		if (PURPLE_IS_BUDDY(buddy)) {
			purple_account_remove_buddy(ctx->instance->_account, buddy, purple_buddy_get_group(buddy));
			purple_blist_remove_buddy(buddy);
		}
#else
		PurpleBuddy* buddy = purple_find_buddy(ctx->instance->_account, buddyName.c_str());
		purple_account_remove_buddy(ctx->instance->_account, buddy, purple_buddy_get_group(buddy));
		purple_blist_remove_buddy(buddy);

#endif
	}

	delete(ctx);
}
Ejemplo n.º 25
0
xmlnode * _h_elim_remove_buddy ( const char *name ,
                                 const char *id   ,
                                 SEXP_VALUE *args ,
                                 gpointer data    )
{
    ASSERT_ALISTP( args, id, name );

    fprintf( stderr, "(elim-remove-buddy)\n" );

    elim_ping();
    
    const char    *aname = ALIST_VAL_STR( args, "account-name" );
    const char    *proto = ALIST_VAL_STR( args, "im-protocol"  );
    gpointer       auid  = ALIST_VAL_PTR( args, "account-uid"  );
    PurpleAccount *acct  = NULL;

    gpointer       b_uid = ALIST_VAL_PTR( args, "bnode-uid" );
    const char    *b_arg = NULL;
    const char    *bname = NULL;
    const char    *gname = NULL; 
    PurpleGroup   *group = NULL; 
    PurpleBuddy   *buddy = NULL;
    gboolean       gone  = FALSE;

    if( b_uid )
    {
        PurpleBlistNodeType type = PURPLE_BLIST_OTHER_NODE;
        PurpleBlistNode    *node = find_blist_node_by_uid( b_uid , TRUE );

        if( !node )
        {
            sexp_val_free( args );
            return response_error( EINVAL, id, name, "rogue buddy pointer" );
        }
        type = purple_blist_node_get_type( node );

        // ===========================================================
        // groups, contacts and chats can safely be removed here:
        // buddies should instead be noted for removal in the next
        // block of code as they require client<->server interaction:
        switch( type )
        {
          case PURPLE_BLIST_GROUP_NODE  :
            purple_blist_remove_group  ( (PurpleGroup   *)node );
            gone = TRUE;
            break;
          case PURPLE_BLIST_CONTACT_NODE:
            purple_blist_remove_contact( (PurpleContact *)node );
            gone = TRUE;
            break;
          case PURPLE_BLIST_CHAT_NODE   :
            FIND_ACCOUNT( args, id, name, acct, auid, aname, proto );
            BNODE_ACCOUNT_CHECK(chat,(PurpleChat *)node, acct, args, id, name);
            purple_blist_remove_chat   ( (PurpleChat    *)node );
            gone = TRUE;
            break;
          case PURPLE_BLIST_BUDDY_NODE  :
            buddy = (PurpleBuddy *)node;
            FIND_ACCOUNT( args, id, name, acct, auid, aname, proto );
            BNODE_ACCOUNT_CHECK( buddy, buddy, acct, args, id, name );
            b_arg = purple_buddy_get_name( buddy );
            bname = purple_normalize( acct, b_arg );
            break;
          default:
            sexp_val_free( args );
            return response_error( EINVAL, id, name, 
                                   "Unknown buddy list node type" );
        }

        if( gone )
        {
            xmlnode *rval = xnode_new( "alist" );
            if( acct )
            {
                AL_STR( rval, "account-name", aname );
                AL_STR( rval, "im-protocol" , proto );
                AL_PTR( rval, "account-uid" , acct  );
            }
            AL_PTR ( rval, "bnode-uid" , buddy );
            AL_ENUM( rval, "bnode-type", type  , ":blist-node-type" );

            sexp_val_free( args );
            return response_value( 0, id, name, rval );
        }
    }
    else
    {
        b_arg = ALIST_VAL_STRING( args, "bnode-name" );
        FIND_ACCOUNT( args, id, name, acct, auid, aname, proto );

        if( b_arg )
        {
            bname = purple_normalize( acct, b_arg   );
            gname = ALIST_VAL_STRING( args, "group" );
            group = ( gname && *gname ) ? purple_find_group( gname ) : NULL;
            buddy = ( group ?
                      purple_find_buddy_in_group( acct, bname, group ) :
                      purple_find_buddy         ( acct, bname        ) );
        }
    }

    if( !b_arg || !*b_arg )
    {
        sexp_val_free( args );
        return response_error( EINVAL, id, name, "buddy not specified" );
    }

    // buddy must be in our local list or libpurple won't remove it from the
    // server list ( determined empirically, confirmed by inspecting code ):
    if( !buddy )
    {
        buddy = purple_buddy_new( acct, bname, bname );
        purple_blist_add_buddy  ( buddy, NULL, NULL, NULL );
    }

    if( buddy )
    {
        // the order of the remove operations is important: it has to be
        // this way round, as noted above: account buddy removal won't 
        // happen if the buddy is not in the blist when we try:
        if( !group ) group = purple_buddy_get_group( buddy );
        // is this correct? what if we have more than one copy of said buddy?
        // potentially confusing. dunno what the right thing to do is here.
        purple_account_remove_buddy( acct, buddy, group );
        purple_blist_remove_buddy( buddy );
    }
    else 
    {
        sexp_val_free( args );
        return response_error( ENXIO, id, name, "no such buddy" );
    }
    
    xmlnode *rval = xnode_new( "alist" );
    AL_STR ( rval, "account-name", purple_account_get_username   ( acct ) );
    AL_STR ( rval, "im-protocol" , purple_account_get_protocol_id( acct ) );
    AL_PTR ( rval, "account-uid" , acct  );
    AL_PTR ( rval, "bnode-uid"   , buddy );
    AL_ENUM( rval, "bnode-type", PURPLE_BLIST_BUDDY_NODE, ":blist-node-type" );
    sexp_val_free( args );
    return response_value( 0, id, name, rval );
}
Ejemplo n.º 26
0
static void got_buddy_list_cb(FacebookAccount *fba, gchar *data,
                              gsize data_len, gpointer userdata)
{
    GSList *buddies_list;
    GSList *online_buddies_list = NULL;
    PurpleBuddy *buddy;
    FacebookBuddy *fbuddy;
    gchar *uid;
    gchar *name;
    gchar *status_text;
    gchar *status_time_text;
    gchar *buddy_icon_url;
    gboolean idle;
    guint32 error_number;

    gchar *search_start;
    gchar *search_tmp;
    gchar *tmp;
    gchar *largest_buddy_search_point = NULL;

    PurpleGroup *fb_group = NULL;

    gboolean current_buddy_online = FALSE;

    purple_debug_info("facebook", "parsing buddy list\n");
    purple_debug_misc("facebook", "buddy list\n%s\n", data);

    if (fba == NULL)
        return;

    if (data == NULL) {
        purple_connection_error_reason(fba->pc,
                                       PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
                                       _("Could not retrieve buddy list"));
        return;
    }

    /* Check if the facebook group already exists (fixes #13) */
    fb_group = purple_find_group("Facebook");

    /* if logged out, this comes up */
    /* for (;;);{"error":1357001,"errorSummary":"Not Logged In",
    	"errorDescription":"You must be logged in to do that.",
    	"payload":null,"bootload":[{"name":"js\/common.js.pkg.php",
    	"type":"js","src":"http:\/\/static.ak.fbcdn.net\/rsrc.php\/pkg\/59\
    	/98561\/js\/common.js.pkg.php"}]} */
    tmp = g_strstr_len(data, data_len, "\"error\":");
    if (tmp != NULL)
    {
        tmp += 9;
        tmp = g_strndup(tmp, strchr(tmp, ',')-tmp);
        error_number = atoi(tmp);
        g_free(tmp);
        if (error_number)
        {
            /* error :( */
            tmp = g_strstr_len(data, data_len, "\"errorDescription\":");
            tmp += 20;
            tmp = g_strndup(tmp, strchr(tmp, '"')-tmp);
            /* TODO: Use purple_connection_error_reason() */
            purple_connection_error(fba->pc, tmp);
            g_free(tmp);
            return;
        }
    }

    /* look for "userInfos":{ ... }, */
    search_start = strstr(data, "\"userInfos\":{");
    if (search_start == NULL)
        return;
    search_start += 13;

    while (*search_start != '}' && (search_start - data < data_len))
    {
        tmp = strchr(search_start, ':');
        uid = g_strndup(search_start+1, tmp-search_start-2);
        /* purple_debug_misc("facebook", "uid: %s\n", uid); */

        search_start += strlen(uid) + 2;

        search_tmp = strstr(search_start, "\"name\":") + 8;
        if (search_tmp > largest_buddy_search_point)
            largest_buddy_search_point = search_tmp;
        search_tmp = g_strndup(search_tmp, strchr(search_tmp, '"')-search_tmp);
        name = fb_convert_unicode(search_tmp);
        g_free(search_tmp);
        /* purple_debug_misc("facebook", "name: %s\n", name); */

        /* try updating the alias, just in case it was removed locally */
        serv_got_alias(fba->pc, uid, name);

        /* look for "uid":{"i":_____} */
        tmp = g_strdup_printf("\"%s\":{\"i\":", uid);
        search_tmp = g_strstr_len(data, data_len, tmp);
        if (search_tmp != NULL)
        {
            search_tmp += strlen(tmp);
            if (search_tmp > largest_buddy_search_point)
                largest_buddy_search_point = search_tmp;
            search_tmp = g_strndup(search_tmp, strchr(search_tmp, '}')-search_tmp);
            /* purple_debug_misc("facebook", "buddy idle: %s\n", search_tmp); */
            buddy = purple_find_buddy(fba->account, uid);
            idle = g_str_equal(search_tmp, "true");
            g_free(search_tmp);
            current_buddy_online = TRUE;
        } else {
            /* if we're here, the buddy's info has been sent, but they're not actually online */
            current_buddy_online = FALSE;
            idle = FALSE;
        }
        g_free(tmp);

        /* Set the buddy status text and time */
        search_tmp = strstr(search_start, "\"status\":");
        if (search_tmp != NULL && *(search_tmp + 9) == '"')
        {
            search_tmp += 10;
            if (search_tmp > largest_buddy_search_point)
                largest_buddy_search_point = strstr(search_tmp, ",\"statusTime");
            search_tmp = g_strndup(search_tmp, strstr(search_tmp, ",\"statusTime")-1-search_tmp);
            status_text = fb_convert_unicode(search_tmp);
            g_free(search_tmp);
        } else {
            status_text = NULL;
        }

        /* is this us? */
        if (atoi(uid) == fba->uid)
        {
            purple_connection_set_display_name(fba->pc, name);

            /* set our last known status so that we don't re-set it */
            if (status_text && !fba->last_status_message)
                fba->last_status_message = g_strdup(status_text);

            /* check that we don't want to show ourselves */
            if (purple_account_get_bool(fba->account, "facebook_hide_self", TRUE))
            {
                g_free(status_text);
                g_free(name);
                g_free(uid);

                /* Move pointer to the end of the buddy entry */
                search_start = strchr(largest_buddy_search_point, '}') + 1;
                while (*search_start == ',' && (search_start - data < data_len))
                    search_start++;
                /* go on to the next buddy */
                continue;
            } else {
                current_buddy_online = TRUE;
            }
        }

        /* Is this a new buddy? */
        buddy = purple_find_buddy(fba->account, uid);
        if (buddy == NULL)
        {
            buddy = purple_buddy_new(fba->account, uid, NULL);
            if (fb_group == NULL)
            {
                fb_group = purple_group_new("Facebook");
                purple_blist_add_group(fb_group, NULL);
            }
            purple_blist_add_buddy(buddy, NULL, fb_group, NULL);
        }
        serv_got_alias(fba->pc, uid, name);
        purple_presence_set_idle(purple_buddy_get_presence(buddy), idle, 0);

        /* Set the FacebookBuddy structure */
        if (buddy->proto_data == NULL)
        {
            fbuddy = g_new0(FacebookBuddy, 1);
            fbuddy->buddy = buddy;
            fbuddy->fba = fba;
            fbuddy->uid = atoi(uid);
            fbuddy->name = g_strdup(name);

            /* load the old buddy icon from the account settings */
            tmp = g_strdup_printf("buddy_icon_%d_cache", fbuddy->uid);
            fbuddy->thumb_url = g_strdup(purple_account_get_string(fba->account, tmp, ""));
            g_free(tmp);

            buddy->proto_data = fbuddy;
        } else {
            fbuddy = buddy->proto_data;
        }

        g_free(uid);
        g_free(name);

        if (status_text != NULL)
        {
            tmp = fb_strdup_withhtml(status_text);
            g_free(status_text);
            status_text = tmp;
            /* purple_debug_misc("facebook", "status: %s\n", status_text); */

            search_tmp = strstr(search_start, "\"statusTimeRel\":") + 17;
            if (search_tmp > largest_buddy_search_point)
                largest_buddy_search_point = strchr(search_tmp, '"');
            search_tmp = g_strndup(search_tmp, strchr(search_tmp, '"')-search_tmp);
            status_time_text = fb_convert_unicode(search_tmp);
            g_free(search_tmp);

            if (g_str_equal(status_time_text, "ull,"))
            {
                g_free(status_time_text);
                status_time_text = NULL;
            }
            g_free(fbuddy->status_rel_time);
            if (status_time_text != NULL)
            {
                fbuddy->status_rel_time = fb_strdup_withhtml(status_time_text);
                g_free(status_time_text);
                /* purple_debug_misc("facebook", "status time: %s\n", fbuddy->status_rel_time); */
            } else {
                fbuddy->status_rel_time = NULL;
            }

            /* if the buddy status has changed, update the contact list */
            if (fbuddy->status == NULL || !g_str_equal(fbuddy->status, status_text))
            {
                tmp = fbuddy->status;
                fbuddy->status = status_text;
                g_free(tmp);
                if (current_buddy_online)
                    purple_prpl_got_user_status(fba->account, buddy->name, purple_primitive_get_id_from_type(PURPLE_STATUS_AVAILABLE), NULL);
            } else {
                g_free(status_text);
            }
        } else {
            if (fbuddy->status != NULL)
            {
                g_free(fbuddy->status);
                fbuddy->status = NULL;
                if (current_buddy_online)
                {
                    /* update the status in the contact list */
                    purple_prpl_got_user_status(fba->account, buddy->name, purple_primitive_get_id_from_type(PURPLE_STATUS_AVAILABLE), NULL);
                }
            }
        }

        /* Set the buddy icon (if it hasn't changed) */
        search_tmp = strstr(search_start, "\"thumbSrc\":") + 12;
        if (search_tmp > largest_buddy_search_point)
            largest_buddy_search_point = search_tmp;
        buddy_icon_url = g_strndup(search_tmp, strchr(search_tmp, '"')-search_tmp);
        if (fbuddy->thumb_url == NULL || !g_str_equal(fbuddy->thumb_url, buddy_icon_url))
        {
            g_free(fbuddy->thumb_url);
            fbuddy->thumb_url = g_strdup(buddy_icon_url);

            /* Save the buddy icon so that they don't all need to be reloaded at startup */
            tmp = g_strdup_printf("buddy_icon_%d_cache", fbuddy->uid);
            purple_account_set_string(fba->account, tmp, buddy_icon_url);
            g_free(tmp);

            /* Turn the \/ into / */
            tmp = g_strcompress(buddy_icon_url);

            /* small icon at http://profile.ak.facebook.com/profile6/1845/74/q800753867_2878.jpg */
            /* bigger icon at http://profile.ak.facebook.com/profile6/1845/74/n800753867_2878.jpg */
            search_tmp = strstr(tmp, "/q");
            if (search_tmp)
                *(search_tmp + 1) = 'n';

            if (g_str_equal(tmp, "http://static.ak.fbcdn.net/pics/q_silhouette.gif"))
                /* User has no icon */
                purple_buddy_icons_set_for_user(fba->account,
                                                purple_buddy_get_name(buddy), NULL, 0, NULL);
            else
                /* Fetch their icon */
                fb_post_or_get(fba, FB_METHOD_GET, "profile.ak.facebook.com",
                               tmp + strlen("http://profile.ak.facebook.com"), NULL,
                               buddy_icon_cb, g_strdup(purple_buddy_get_name(buddy)),
                               FALSE);
            g_free(tmp);
        }
        g_free(buddy_icon_url);

        if (current_buddy_online)
        {
            /* Add buddy to the list of online buddies */
            online_buddies_list = g_slist_append(online_buddies_list, buddy);

            /* Update the display of the buddy in the buddy list and make the user online */
            if (!PURPLE_BUDDY_IS_ONLINE(buddy))
                purple_prpl_got_user_status(fba->account, buddy->name, purple_primitive_get_id_from_type(PURPLE_STATUS_AVAILABLE), NULL);
        }

        /* Move pointer after any user configurable data */
        search_start = search_tmp;
        /* Move pointer to the end of the buddy entry */
        search_start = strchr(largest_buddy_search_point, '}') + 1;
        while (*search_start == ',' && (search_start - data < data_len))
            search_start++;
    }

    buddies_list = purple_find_buddies(fba->account, NULL);
    if (buddies_list != NULL)
    {
        g_slist_foreach(buddies_list, (GFunc)set_buddies_offline, online_buddies_list);
        g_slist_free(buddies_list);
    }
    g_slist_free(online_buddies_list);
}