comparison libpurple/protocols/qq/buddy_info.c @ 24150:119d85c40d75

2008.10.07 - ccpaging <ccpaging(at)gmail.com> * Update buddy icon
author SHiNE CsyFeK <csyfek@gmail.com>
date Wed, 22 Oct 2008 15:00:47 +0000
parents 818ab62006f5
children d3811bdb6b07
comparison
equal deleted inserted replaced
24149:818ab62006f5 24150:119d85c40d75
125 { QQ_FIELD_BASE, QQ_FIELD_STRING, "occupation", N_("Occupation"), NULL, 0 }, 125 { QQ_FIELD_BASE, QQ_FIELD_STRING, "occupation", N_("Occupation"), NULL, 0 },
126 { QQ_FIELD_CONTACT, QQ_FIELD_STRING, "homepage", N_("Homepage"), NULL, 0 }, 126 { QQ_FIELD_CONTACT, QQ_FIELD_STRING, "homepage", N_("Homepage"), NULL, 0 },
127 { QQ_FIELD_BASE, QQ_FIELD_BOOL, "auth", N_("Authorize adding"), NULL, 0 }, 127 { QQ_FIELD_BASE, QQ_FIELD_BOOL, "auth", N_("Authorize adding"), NULL, 0 },
128 { QQ_FIELD_UNUSED, QQ_FIELD_STRING, "unknow1", "Unknow1", NULL, 0 }, 128 { QQ_FIELD_UNUSED, QQ_FIELD_STRING, "unknow1", "Unknow1", NULL, 0 },
129 { QQ_FIELD_UNUSED, QQ_FIELD_STRING, "unknow2", "Unknow2", NULL, 0 }, 129 { QQ_FIELD_UNUSED, QQ_FIELD_STRING, "unknow2", "Unknow2", NULL, 0 },
130 { QQ_FIELD_UNUSED, QQ_FIELD_STRING, "face", "Face", NULL, 0 }, 130 { QQ_FIELD_BASE, QQ_FIELD_STRING, "face", "Face", NULL, 0 },
131 { QQ_FIELD_CONTACT, QQ_FIELD_STRING, "mobile", N_("Cellphone Number"), NULL, 0 }, 131 { QQ_FIELD_CONTACT, QQ_FIELD_STRING, "mobile", N_("Cellphone Number"), NULL, 0 },
132 { QQ_FIELD_UNUSED, QQ_FIELD_STRING, "mobile_type","Cellphone Type", NULL, 0 }, 132 { QQ_FIELD_UNUSED, QQ_FIELD_STRING, "mobile_type","Cellphone Type", NULL, 0 },
133 { QQ_FIELD_BASE, QQ_FIELD_MULTI, "intro", N_("Personal Introduction"), NULL, 0 }, 133 { QQ_FIELD_BASE, QQ_FIELD_MULTI, "intro", N_("Personal Introduction"), NULL, 0 },
134 { QQ_FIELD_ADDR, QQ_FIELD_STRING, "city", N_("City/Area"), NULL, 0 }, 134 { QQ_FIELD_ADDR, QQ_FIELD_STRING, "city", N_("City/Area"), NULL, 0 },
135 { QQ_FIELD_UNUSED, QQ_FIELD_STRING, "unknow3", "Unknow3", NULL, 0 }, 135 { QQ_FIELD_UNUSED, QQ_FIELD_STRING, "unknow3", "Unknow3", NULL, 0 },
476 476
477 qd->my_icon = 3 * (face_num - 1) + offset; 477 qd->my_icon = 3 * (face_num - 1) + offset;
478 qq_request_buddy_info(gc, qd->uid, 0, QQ_BUDDY_INFO_SET_ICON); 478 qq_request_buddy_info(gc, qd->uid, 0, QQ_BUDDY_INFO_SET_ICON);
479 } 479 }
480 480
481 static void buddy_local_icon_set(PurpleAccount *account, const gchar *who, const gchar *icon_num, const gchar *iconfile) 481 /* return the location of the buddy icon dir
482 { 482 * any application using libpurple but not installing the QQ buddy icons
483 gchar *data; 483 * under datadir needs to set the pref below, or buddy icons won't work */
484 gsize len; 484 static const char *get_icon_dir(void)
485 485 {
486 if (!g_file_get_contents(iconfile, &data, &len, NULL)) { 486 if (purple_prefs_exists("/plugins/prpl/qq/icon_dir"))
487 g_return_if_reached(); 487 return purple_prefs_get_string("/plugins/prpl/qq/icon_dir");
488 } else { 488 else
489 purple_buddy_icons_set_for_user(account, who, data, len, icon_num); 489 return NULL;
490 }
491 } 490 }
492 491
493 /* TODO: custom faces for QQ members and users with level >= 16 */ 492 /* TODO: custom faces for QQ members and users with level >= 16 */
494 void qq_set_buddy_icon(PurpleConnection *gc, PurpleStoredImage *img) 493 void qq_set_buddy_icon_old(PurpleConnection *gc, PurpleStoredImage *img)
495 { 494 {
496 gchar *icon; 495 gchar *icon;
497 gint icon_num; 496 gint icon_num;
498 gint icon_len; 497 gint icon_len;
499 PurpleAccount *account = purple_connection_get_account(gc); 498 PurpleAccount *account = purple_connection_get_account(gc);
500 const gchar *icon_path = purple_account_get_buddy_icon_path(account); 499 const gchar *icon_path = purple_account_get_buddy_icon_path(account);
501 const gchar *buddy_icon_dir = qq_buddy_icon_dir(); 500 const gchar *buddy_icon_dir = get_icon_dir();
502 gint prefix_len = strlen(QQ_ICON_PREFIX); 501 gint prefix_len = strlen(QQ_ICON_PREFIX);
503 gint suffix_len = strlen(QQ_ICON_SUFFIX); 502 gint suffix_len = strlen(QQ_ICON_SUFFIX);
504 gint dir_len = buddy_icon_dir ? strlen(buddy_icon_dir) : 0; 503 gint dir_len = buddy_icon_dir ? strlen(buddy_icon_dir) : 0;
505 gchar *errmsg = g_strdup_printf(_("Setting custom faces is not currently supported. Please choose an image from %s."), buddy_icon_dir ? buddy_icon_dir : "(null)"); 504 gchar *errmsg = g_strdup_printf(_("Setting custom faces is not currently supported. Please choose an image from %s."), buddy_icon_dir ? buddy_icon_dir : "(null)");
506 gboolean icon_global = purple_account_get_bool(gc->account, "use-global-buddyicon", TRUE); 505 gboolean icon_global = purple_account_get_bool(gc->account, "use-global-buddyicon", TRUE);
506
507 gchar *icon_file_content;
508 gsize icon_file_size;
507 509
508 if (!icon_path) 510 if (!icon_path)
509 icon_path = ""; 511 icon_path = "";
510 512
511 icon_len = strlen(icon_path) - dir_len - 1 - prefix_len - suffix_len; 513 icon_len = strlen(icon_path) - dir_len - 1 - prefix_len - suffix_len;
537 return; 539 return;
538 } 540 }
539 g_free(errmsg); 541 g_free(errmsg);
540 /* tell server my icon changed */ 542 /* tell server my icon changed */
541 request_set_buddy_icon(gc, icon_num); 543 request_set_buddy_icon(gc, icon_num);
544
542 /* display in blist */ 545 /* display in blist */
543 buddy_local_icon_set(account, account->username, icon, icon_path); 546 if (!g_file_get_contents(icon_path, &icon_file_content, &icon_file_size, NULL)) {
544 } 547 purple_debug_error("QQ", "Failed reading icon file %s\n", icon_path);
545 548 return;
546 549 }
547 static void buddy_local_icon_upate(PurpleAccount *account, const gchar *name, gint face) 550 purple_buddy_icons_set_for_user(account, account->username,
551 icon_file_content, icon_file_size, icon);
552 }
553
554 void qq_set_custom_icon(PurpleConnection *gc, PurpleStoredImage *img)
555 {
556 PurpleAccount *account = purple_connection_get_account(gc);
557 const gchar *icon_path = purple_account_get_buddy_icon_path(account);
558 gchar **segments;
559 gint index;
560
561 g_return_if_fail(icon_path != NULL);
562
563 /* Fixme:
564 * icon_path is always null
565 * purple_imgstore_get_filename is always new file
566 * QQ buddy may set custom icon if level is over 16 */
567 purple_debug_info("QQ", "Change my icon to %s\n", icon_path);
568 segments = g_strsplit_set(icon_path, G_DIR_SEPARATOR_S, 0);
569 for (index = 0; segments[index] != NULL; index++) {
570 purple_debug_info("QQ", "Split to %s\n", segments[index]);
571 }
572
573 g_strfreev(segments);
574 }
575
576 static void update_buddy_icon(PurpleAccount *account, const gchar *who, gint face)
548 { 577 {
549 PurpleBuddy *buddy; 578 PurpleBuddy *buddy;
550 gchar *icon_num_str = face_to_icon_str(face); 579 const gchar *icon_name_prev = NULL;
551 const gchar *old_icon_num = NULL; 580 gchar *icon_name;
552 581 const gchar *icon_dir;
553 if ((buddy = purple_find_buddy(account, name))) 582 gchar *icon_path;
554 old_icon_num = purple_buddy_icons_get_checksum_for_user(buddy); 583 gchar *icon_file_content;
555 584 gsize icon_file_size;
556 if ((old_icon_num == NULL || 585
557 strcmp(icon_num_str, old_icon_num)) && (qq_buddy_icon_dir() != NULL)) 586 purple_debug_info("QQ", "Update %s icon to %d\n", who, face);
558 { 587
559 gchar *icon_path; 588 icon_name = g_strdup_printf("%d", face);
560 589 if ((buddy = purple_find_buddy(account, who))) {
561 icon_path = g_strconcat(qq_buddy_icon_dir(), G_DIR_SEPARATOR_S, 590 icon_name_prev = purple_buddy_icons_get_checksum_for_user(buddy);
562 QQ_ICON_PREFIX, icon_num_str, 591 purple_debug_info("QQ", "Previous icon is %s\n", icon_name_prev);
563 QQ_ICON_SUFFIX, NULL); 592 }
564 593 if (icon_name_prev != NULL && !strcmp(icon_name, icon_name_prev)) {
565 buddy_local_icon_set(account, name, icon_num_str, icon_path); 594 purple_debug_info("QQ", "Icon is not changed\n");
566 g_free(icon_path); 595 g_free(icon_name);
567 } 596 return;
568 g_free(icon_num_str); 597 }
598 icon_dir = NULL;
599 if ( purple_prefs_exists("/plugins/prpl/qq/icon_dir") ) {
600 icon_dir = purple_prefs_get_string("/plugins/prpl/qq/icon_dir");
601 }
602 if ( icon_dir == NULL) {
603 purple_debug_info("QQ", "Icon dir is not defined in prefs '/plugins/prpl/qq/icon_dir'\n");
604 g_free(icon_name);
605 return;
606 }
607
608 icon_path = g_strconcat(icon_dir, G_DIR_SEPARATOR_S,
609 QQ_ICON_PREFIX, icon_name, QQ_ICON_SUFFIX, NULL);
610
611 if (!g_file_get_contents(icon_path, &icon_file_content, &icon_file_size, NULL)) {
612 purple_debug_error("QQ", "Failed reading icon file %s\n", icon_path);
613 } else {
614 purple_buddy_icons_set_for_user(account, who,
615 icon_file_content, icon_file_size, icon_name);
616 }
617 g_free(icon_name);
618 g_free(icon_path);
569 } 619 }
570 620
571 /* after getting info or modify myself, refresh the buddy list accordingly */ 621 /* after getting info or modify myself, refresh the buddy list accordingly */
572 static void qq_update_buddy_info(PurpleConnection *gc, gchar **segments) 622 static void update_buddy_info(PurpleConnection *gc, gchar **segments)
573 { 623 {
574 PurpleBuddy *buddy; 624 PurpleBuddy *buddy;
575 qq_data *qd; 625 qq_data *qd;
576 qq_buddy_data *bd; 626 qq_buddy_data *bd;
577 guint32 uid; 627 guint32 uid;
582 qd = (qq_data *) gc->proto_data; 632 qd = (qq_data *) gc->proto_data;
583 633
584 uid = strtol(segments[QQ_INFO_UID], NULL, 10); 634 uid = strtol(segments[QQ_INFO_UID], NULL, 10);
585 who = uid_to_purple_name(uid); 635 who = uid_to_purple_name(uid);
586 636
637 qq_filter_str(segments[QQ_INFO_NICK]);
587 alias_utf8 = qq_to_utf8(segments[QQ_INFO_NICK], QQ_CHARSET_DEFAULT); 638 alias_utf8 = qq_to_utf8(segments[QQ_INFO_NICK], QQ_CHARSET_DEFAULT);
588 if (uid == qd->uid) { /* it is me */ 639 if (uid == qd->uid) { /* it is me */
589 purple_debug_info("QQ", "Got my info\n"); 640 purple_debug_info("QQ", "Got my info\n");
590 qd->my_icon = strtol(segments[QQ_INFO_FACE], NULL, 10); 641 qd->my_icon = strtol(segments[QQ_INFO_FACE], NULL, 10);
591 if (alias_utf8 != NULL) { 642 if (alias_utf8 != NULL) {
595 buddy = qq_buddy_find_or_new(gc, uid); 646 buddy = qq_buddy_find_or_new(gc, uid);
596 } else { 647 } else {
597 buddy = purple_find_buddy(gc->account, who); 648 buddy = purple_find_buddy(gc->account, who);
598 } 649 }
599 650
600 if (buddy == NULL && buddy->proto_data == NULL) { 651 if (buddy == NULL || buddy->proto_data == NULL) {
601 g_free(who); 652 g_free(who);
602 g_free(alias_utf8); 653 g_free(alias_utf8);
603 return; 654 return;
604 } 655 }
605 656
614 bd->nickname = g_strdup(alias_utf8); 665 bd->nickname = g_strdup(alias_utf8);
615 } 666 }
616 bd->last_update = time(NULL); 667 bd->last_update = time(NULL);
617 668
618 purple_blist_server_alias_buddy(buddy, bd->nickname); 669 purple_blist_server_alias_buddy(buddy, bd->nickname);
619 buddy_local_icon_upate(gc->account, who, bd->face); 670
671 /* convert face num from packet (0-299) to local face (1-100) */
672 update_buddy_icon(gc->account, who, (bd->face / 3 + 1));
620 673
621 g_free(who); 674 g_free(who);
622 g_free(alias_utf8); 675 g_free(alias_utf8);
623 } 676 }
624 677
626 void qq_process_get_buddy_info(guint8 *data, gint data_len, guint32 action, PurpleConnection *gc) 679 void qq_process_get_buddy_info(guint8 *data, gint data_len, guint32 action, PurpleConnection *gc)
627 { 680 {
628 qq_data *qd; 681 qq_data *qd;
629 gchar **segments; 682 gchar **segments;
630 gint field_count; 683 gint field_count;
684 gchar *icon_name;
631 685
632 g_return_if_fail(data != NULL && data_len != 0); 686 g_return_if_fail(data != NULL && data_len != 0);
633 687
634 qd = (qq_data *) gc->proto_data; 688 qd = (qq_data *) gc->proto_data;
635 689
644 #ifdef DEBUG 698 #ifdef DEBUG
645 info_debug(segments); 699 info_debug(segments);
646 #endif 700 #endif
647 701
648 if (action == QQ_BUDDY_INFO_SET_ICON) { 702 if (action == QQ_BUDDY_INFO_SET_ICON) {
703 /* send new face to server */
649 if (strtol(segments[QQ_INFO_FACE], NULL, 10) != qd->my_icon) { 704 if (strtol(segments[QQ_INFO_FACE], NULL, 10) != qd->my_icon) {
650 gchar *icon = g_strdup_printf("%d", qd->my_icon); 705 icon_name = g_strdup_printf("%d", qd->my_icon);
651
652 g_free(segments[QQ_INFO_FACE]); 706 g_free(segments[QQ_INFO_FACE]);
653 segments[QQ_INFO_FACE] = icon; 707 segments[QQ_INFO_FACE] = icon_name;
654 708
655 request_modify_info(gc, segments); 709 request_modify_info(gc, segments);
656 qq_update_buddy_info(gc, segments);
657 } 710 }
658 g_strfreev(segments); 711 g_strfreev(segments);
659 return; 712 return;
660 } 713 }
661 714
662 qq_update_buddy_info(gc, segments); 715 update_buddy_info(gc, segments);
663 switch (action) { 716 switch (action) {
664 case QQ_BUDDY_INFO_DISPLAY: 717 case QQ_BUDDY_INFO_DISPLAY:
665 info_display_only(gc, segments); 718 info_display_only(gc, segments);
666 break; 719 break;
667 case QQ_BUDDY_INFO_SET_ICON: 720 case QQ_BUDDY_INFO_SET_ICON:
721 /* never reached */
668 break; 722 break;
669 case QQ_BUDDY_INFO_MODIFY_BASE: 723 case QQ_BUDDY_INFO_MODIFY_BASE:
670 info_modify_dialogue(gc, segments, QQ_FIELD_BASE); 724 info_modify_dialogue(gc, segments, QQ_FIELD_BASE);
671 break; 725 break;
672 case QQ_BUDDY_INFO_MODIFY_EXT: 726 case QQ_BUDDY_INFO_MODIFY_EXT: