comparison pidgin-twitter.c @ 107:eb77d409c235

- do neither save nor cache icon image if pixbuf can not be obtained. - now icon size can be specified in prefs.xml. - tweaked configuration dialog.
author Yoshiki Yazawa <yaz@honeyplanet.jp>
date Tue, 15 Jul 2008 12:32:06 +0900
parents 084e1c6de8ca
children 01b6613a075a
comparison
equal deleted inserted replaced
106:a132905cece6 107:eb77d409c235
1379 1379
1380 twitter_debug("request %s's icon\n", user_name); 1380 twitter_debug("request %s's icon\n", user_name);
1381 } 1381 }
1382 } 1382 }
1383 1383
1384 static GdkPixbuf *
1385 make_scaled_pixbuf(const gchar *url_text, gsize len)
1386 {
1387 /* make pixbuf */
1388 GdkPixbufLoader *loader;
1389 GdkPixbuf *src = NULL, *dest = NULL;
1390 gint size;
1391
1392 g_return_val_if_fail(url_text != NULL, NULL);
1393 g_return_val_if_fail(len > 0, NULL);
1394
1395 loader = gdk_pixbuf_loader_new();
1396 gdk_pixbuf_loader_write(loader, (guchar *)url_text, len, NULL);
1397 gdk_pixbuf_loader_close(loader, NULL);
1398
1399 src = gdk_pixbuf_loader_get_pixbuf(loader);
1400 if(!src)
1401 return NULL;
1402
1403 size = purple_prefs_get_int(OPT_ICON_SIZE);
1404 if(size == 0)
1405 size = 48; /* twitter icon size */
1406
1407 dest = gdk_pixbuf_scale_simple(src, size, size, GDK_INTERP_HYPER);
1408 gdk_pixbuf_unref (src);
1409
1410 return dest;
1411 }
1412
1413
1384 static void 1414 static void
1385 got_icon_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data, 1415 got_icon_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data,
1386 const gchar *url_text, gsize len, const gchar *error_message) 1416 const gchar *url_text, gsize len, const gchar *error_message)
1387 { 1417 {
1388 got_icon_data *gotdata = (got_icon_data *)user_data; 1418 got_icon_data *gotdata = (got_icon_data *)user_data;
1390 gint service = gotdata->service; 1420 gint service = gotdata->service;
1391 1421
1392 gint icon_id; 1422 gint icon_id;
1393 icon_data *data = NULL; 1423 icon_data *data = NULL;
1394 GHashTable *hash = NULL; 1424 GHashTable *hash = NULL;
1425 GdkPixbuf *pixbuf = NULL;
1426 const gchar *dirname = NULL;
1395 1427
1396 twitter_debug("called: service = %d\n", service); 1428 twitter_debug("called: service = %d\n", service);
1397 1429
1398 switch(service) { 1430 switch(service) {
1399 case twitter_service: 1431 case twitter_service:
1416 if(!url_text) { 1448 if(!url_text) {
1417 twitter_debug("downloading %s's icon failed : %s\n", 1449 twitter_debug("downloading %s's icon failed : %s\n",
1418 user_name, error_message); 1450 user_name, error_message);
1419 if(data) 1451 if(data)
1420 data->requested = FALSE; 1452 data->requested = FALSE;
1421 g_free(gotdata->user_name); 1453 goto fin_got_icon_cb;
1422 g_free(gotdata);
1423 return; 1454 return;
1424 } 1455 }
1425 1456
1426 if(data) { 1457 if(data) {
1427 /* remove download request */ 1458 /* remove download request */
1430 1461
1431 /* return if user's icon had been downloaded */ 1462 /* return if user's icon had been downloaded */
1432 if(data->icon_id > 0) { 1463 if(data->icon_id > 0) {
1433 twitter_debug("%s's icon has already been downloaded\n", 1464 twitter_debug("%s's icon has already been downloaded\n",
1434 user_name); 1465 user_name);
1435 g_free(gotdata->user_name); 1466 goto fin_got_icon_cb;
1436 g_free(gotdata);
1437 return; 1467 return;
1438 } 1468 }
1439 } 1469 }
1440 1470
1441 /* make pixbuf */ 1471 pixbuf = make_scaled_pixbuf(url_text, len);
1442 GdkPixbufLoader *loader = gdk_pixbuf_loader_new(); 1472
1443 gdk_pixbuf_loader_write(loader, (guchar *)url_text, len, NULL); 1473 if(!pixbuf)
1444 gdk_pixbuf_loader_close(loader, NULL); 1474 goto fin_got_icon_cb;
1445 GdkPixbuf *src = gdk_pixbuf_loader_get_pixbuf(loader); 1475
1446 GdkPixbuf *dest = gdk_pixbuf_scale_simple(src, 48, 48,
1447 GDK_INTERP_HYPER);
1448 gdk_pixbuf_unref (src);
1449 icon_id = 1476 icon_id =
1450 purple_imgstore_add_with_id(dest, 1477 purple_imgstore_add_with_id(pixbuf,
1451 gdk_pixbuf_get_rowstride(dest) * 1478 gdk_pixbuf_get_rowstride(pixbuf) *
1452 gdk_pixbuf_get_height(dest), 1479 gdk_pixbuf_get_height(pixbuf),
1453 user_name); 1480 user_name);
1454 if(!data) { 1481 if(!data) {
1455 twitter_debug("allocate icon_data (shouldn't be called)\n"); 1482 twitter_debug("allocate icon_data (shouldn't be called)\n");
1456 data = g_new0(icon_data, 1); 1483 data = g_new0(icon_data, 1);
1457 } 1484 }
1459 data->icon_id = icon_id; 1486 data->icon_id = icon_id;
1460 1487
1461 if(hash) 1488 if(hash)
1462 g_hash_table_insert(hash, g_strdup(user_name), data); 1489 g_hash_table_insert(hash, g_strdup(user_name), data);
1463 1490
1464 const gchar *dirname = purple_prefs_get_string(OPT_ICON_DIR); 1491 dirname = purple_prefs_get_string(OPT_ICON_DIR);
1465 1492
1466 /* store retrieved image to a file in icon dir */ 1493 /* store retrieved image to a file in icon dir */
1467 if(ensure_path_exists(dirname)) { 1494 if(ensure_path_exists(dirname)) {
1468 gchar *filename = NULL; 1495 gchar *filename = NULL;
1469 gchar *path = NULL; 1496 gchar *path = NULL;
1470 // FILE *fp = NULL;
1471 1497
1472 switch(service) { 1498 switch(service) {
1473 case twitter_service: 1499 case twitter_service:
1474 filename = g_strdup_printf("%s_twitter.gif", user_name); 1500 filename = g_strdup_printf("%s_twitter.gif", user_name);
1475 break; 1501 break;
1493 twitter_debug("Downloading %s's icon has been complete.(icon_id = %d)\n", 1519 twitter_debug("Downloading %s's icon has been complete.(icon_id = %d)\n",
1494 user_name, icon_id); 1520 user_name, icon_id);
1495 1521
1496 /* Insert the icon to messages that had been received. */ 1522 /* Insert the icon to messages that had been received. */
1497 insert_requested_icon(user_name, service); 1523 insert_requested_icon(user_name, service);
1524
1525 fin_got_icon_cb:
1498 g_free(gotdata->user_name); 1526 g_free(gotdata->user_name);
1499 g_free(gotdata); 1527 g_free(gotdata);
1500 } 1528 }
1501 1529
1502 static void 1530 static void
1503 request_icon(const char *user_name, gint service) 1531 request_icon(const char *user_name, gint service)
1504 { 1532 {
1505 gchar *url = NULL; 1533 gchar *url = NULL;
1506 1534
1507 /* look local icon cache for the requested icon */ 1535 /* look local icon cache for the requested icon */
1508 gchar *filename = NULL;
1509 gchar *path = NULL; 1536 gchar *path = NULL;
1510 icon_data *data = NULL; 1537 icon_data *data = NULL;
1511 GHashTable *hash = NULL; 1538 GHashTable *hash = NULL;
1512 const gchar *suffix = NULL; 1539 const gchar *suffix = NULL;
1513 1540
1541 if(data->icon_id > 0) 1568 if(data->icon_id > 0)
1542 return; 1569 return;
1543 1570
1544 /* check if saved file exists */ 1571 /* check if saved file exists */
1545 if(suffix) { 1572 if(suffix) {
1573 gchar *filename = NULL;
1574
1546 filename = g_strdup_printf("%s_%s.gif", user_name, suffix); 1575 filename = g_strdup_printf("%s_%s.gif", user_name, suffix);
1547 path = g_build_filename( 1576 path = g_build_filename(
1548 purple_prefs_get_string(OPT_ICON_DIR), filename, NULL); 1577 purple_prefs_get_string(OPT_ICON_DIR), filename, NULL);
1549 1578
1550 if(!g_file_test(path, G_FILE_TEST_EXISTS)) { 1579 if(!g_file_test(path, G_FILE_TEST_EXISTS)) {
1551 g_free(path); 1580 g_free(path);
1552 filename = g_strdup_printf("%s_%s.png", user_name, suffix); 1581 filename = g_strdup_printf("%s_%s.png", user_name, suffix);
1553 path = g_build_filename( 1582 path = g_build_filename(
1554 purple_prefs_get_string(OPT_ICON_DIR), filename, NULL); 1583 purple_prefs_get_string(OPT_ICON_DIR), filename, NULL);
1555 } 1584 }
1585
1586 g_free(filename);
1556 } 1587 }
1557 1588
1558 twitter_debug("path = %s\n", path); 1589 twitter_debug("path = %s\n", path);
1559 1590
1560 /* build image from file, if file exists */ 1591 /* build image from file, if file exists */
1561 if(g_file_test(path, G_FILE_TEST_EXISTS)) { 1592 if(g_file_test(path, G_FILE_TEST_EXISTS)) {
1562 gchar *imgdata = NULL; 1593 gchar *imgdata = NULL;
1563 size_t len; 1594 size_t len;
1564 GError *err = NULL; 1595 GError *err = NULL;
1596 GdkPixbuf *pixbuf = NULL;
1565 1597
1566 if (!g_file_get_contents(path, &imgdata, &len, &err)) { 1598 if (!g_file_get_contents(path, &imgdata, &len, &err)) {
1567 twitter_debug("Error reading %s: %s\n", 1599 twitter_debug("Error reading %s: %s\n",
1568 path, err->message); 1600 path, err->message);
1569 g_error_free(err); 1601 g_error_free(err);
1570 } 1602 }
1571 1603
1572 /* make pixbuf */ 1604 pixbuf = make_scaled_pixbuf(imgdata, len);
1573 GdkPixbufLoader *loader = gdk_pixbuf_loader_new(); 1605
1574 gdk_pixbuf_loader_write(loader, (guchar *)imgdata, len, NULL); 1606 if(pixbuf) {
1575 gdk_pixbuf_loader_close(loader, NULL); 1607 data->icon_id =
1576 GdkPixbuf *src = gdk_pixbuf_loader_get_pixbuf(loader); 1608 purple_imgstore_add_with_id(pixbuf,
1577 GdkPixbuf *dest = gdk_pixbuf_scale_simple(src, 48, 48, 1609 gdk_pixbuf_get_rowstride(pixbuf) *
1578 GDK_INTERP_HYPER); 1610 gdk_pixbuf_get_height(pixbuf),
1579 gdk_pixbuf_unref (src); 1611 user_name);
1580 data->icon_id = 1612
1581 purple_imgstore_add_with_id(dest, 1613 twitter_debug("icon data has been loaded from file\n");
1582 gdk_pixbuf_get_rowstride(dest) * 1614 insert_requested_icon(user_name, service);
1583 gdk_pixbuf_get_height(dest), 1615 }
1584 user_name); 1616
1585
1586 g_free(filename);
1587 g_free(path); 1617 g_free(path);
1588
1589 twitter_debug("icon data has been loaded from file\n");
1590
1591 insert_requested_icon(user_name, service);
1592 return; 1618 return;
1593 } 1619 }
1594 1620
1595 /* Return if user's icon has been requested already. */ 1621 /* Return if user's icon has been requested already. */
1596 if(data->requested) 1622 if(data->requested)
1947 /* create gtk elements for the plugin preferences */ 1973 /* create gtk elements for the plugin preferences */
1948 PurplePluginPref *pref; 1974 PurplePluginPref *pref;
1949 PurplePluginPrefFrame *frame = purple_plugin_pref_frame_new(); 1975 PurplePluginPrefFrame *frame = purple_plugin_pref_frame_new();
1950 1976
1951 /************************/ 1977 /************************/
1952 /* translatione heading */ 1978 /* user config heading */
1979 /************************/
1980 pref = purple_plugin_pref_new_with_label("User Account");
1981 purple_plugin_pref_frame_add(frame, pref);
1982
1983 /* screenname configurations */
1984 pref = purple_plugin_pref_new_with_name_and_label(OPT_SCREEN_NAME,
1985 "Screen Name");
1986 purple_plugin_pref_frame_add(frame, pref);
1987
1988 pref = purple_plugin_pref_new_with_name_and_label(OPT_PASSWORD,
1989 "Password");
1990 purple_plugin_pref_set_masked(pref, TRUE);
1991
1992 purple_plugin_pref_frame_add(frame, pref);
1993
1994
1995 /************************/
1996 /* translation heading */
1953 /************************/ 1997 /************************/
1954 pref = purple_plugin_pref_new_with_label("Translation Configurations"); 1998 pref = purple_plugin_pref_new_with_label("Translation Configurations");
1955 purple_plugin_pref_frame_add(frame, pref); 1999 purple_plugin_pref_frame_add(frame, pref);
1956 2000
1957 /* translation settings */ 2001 /* translation settings */
1966 pref = purple_plugin_pref_new_with_name_and_label(OPT_TRANSLATE_CHANNEL, 2010 pref = purple_plugin_pref_new_with_name_and_label(OPT_TRANSLATE_CHANNEL,
1967 "Translate channel name to link (wassr only)"); 2011 "Translate channel name to link (wassr only)");
1968 purple_plugin_pref_frame_add(frame, pref); 2012 purple_plugin_pref_frame_add(frame, pref);
1969 2013
1970 2014
1971 /*************************/ 2015 /***********************/
1972 /* miscellaneous heading */ 2016 /* GUI config heading */
1973 /*************************/ 2017 /***********************/
1974 pref = purple_plugin_pref_new_with_label("Miscellaneous Configurations"); 2018 pref = purple_plugin_pref_new_with_label("GUI Configurations");
2019 purple_plugin_pref_frame_add(frame, pref);
2020
2021 /* show icon */
2022 pref = purple_plugin_pref_new_with_name_and_label(OPT_SHOW_ICON,
2023 "Show icons in conversation");
2024 purple_plugin_pref_frame_add(frame, pref);
2025
2026 #if 0
2027 /* icon size */
2028 pref = purple_plugin_pref_new_with_name_and_label(OPT_ICON_SIZE,
2029 "Icon size in pixel");
2030 purple_plugin_pref_set_bounds(pref, 16, 128);
2031 purple_plugin_pref_frame_add(frame, pref);
2032
2033 /* XXX should invalidate pixbufs in memory --yaz */
2034 #endif
2035
2036 /* show text counter */
2037 pref = purple_plugin_pref_new_with_name_and_label(OPT_COUNTER,
2038 "Show text counter widget");
2039 purple_plugin_pref_frame_add(frame, pref);
2040 purple_prefs_connect_callback(plugin, OPT_COUNTER,
2041 counter_prefs_cb, NULL);
2042
2043
2044 /****************************/
2045 /* advanced config heading */
2046 /****************************/
2047 pref = purple_plugin_pref_new_with_label("Advanced Configurations");
1975 purple_plugin_pref_frame_add(frame, pref); 2048 purple_plugin_pref_frame_add(frame, pref);
1976 2049
1977 /* escape pseudo command setting */ 2050 /* escape pseudo command setting */
1978 pref = purple_plugin_pref_new_with_name_and_label(OPT_ESCAPE_PSEUDO, 2051 pref = purple_plugin_pref_new_with_name_and_label(OPT_ESCAPE_PSEUDO,
1979 "Escape pseudo command string"); 2052 "Escape pseudo command string");
1980 purple_plugin_pref_frame_add(frame, pref); 2053 purple_plugin_pref_frame_add(frame, pref);
1981 2054
1982 /* show text counter */
1983 pref = purple_plugin_pref_new_with_name_and_label(OPT_COUNTER,
1984 "Show text counter");
1985 purple_plugin_pref_frame_add(frame, pref);
1986
1987 purple_prefs_connect_callback(plugin, OPT_COUNTER, counter_prefs_cb, NULL);
1988
1989 /* suppress oops message */ 2055 /* suppress oops message */
1990 pref = purple_plugin_pref_new_with_name_and_label(OPT_SUPPRESS_OOPS, 2056 pref = purple_plugin_pref_new_with_name_and_label(OPT_SUPPRESS_OOPS,
1991 "Suppress oops message"); 2057 "Suppress oops message");
1992 purple_plugin_pref_frame_add(frame, pref); 2058 purple_plugin_pref_frame_add(frame, pref);
1993 2059
1994 /* show icon */ 2060
1995 pref = purple_plugin_pref_new_with_name_and_label(OPT_SHOW_ICON, 2061 /* notification setting */
1996 "Show icon"); 2062 pref =
1997 purple_plugin_pref_frame_add(frame, pref); 2063 purple_plugin_pref_new_with_name_and_label(OPT_PREVENT_NOTIFICATION,
1998 2064 "Do not notify incoming message");
1999 2065 purple_plugin_pref_frame_add(frame, pref);
2000 /*****************/ 2066
2067 /******************/
2001 /* sound heading */ 2068 /* sound heading */
2002 /*****************/ 2069 /******************/
2003 pref = purple_plugin_pref_new_with_label("Sound Configurations"); 2070 pref = purple_plugin_pref_new_with_label("Sound Configurations");
2004 purple_plugin_pref_frame_add(frame, pref); 2071 purple_plugin_pref_frame_add(frame, pref);
2005 2072
2006 /* sound settings for recipient */ 2073 /* sound settings for recipient */
2007 pref = purple_plugin_pref_new_with_name_and_label(OPT_PLAYSOUND_RECIPIENT, 2074 pref = purple_plugin_pref_new_with_name_and_label(OPT_PLAYSOUND_RECIPIENT,
2058 purple_plugin_pref_add_choice(pref, "Chat Leave", GINT_TO_POINTER(6)); 2125 purple_plugin_pref_add_choice(pref, "Chat Leave", GINT_TO_POINTER(6));
2059 purple_plugin_pref_add_choice(pref, "Chat You Say", GINT_TO_POINTER(7)); 2126 purple_plugin_pref_add_choice(pref, "Chat You Say", GINT_TO_POINTER(7));
2060 purple_plugin_pref_add_choice(pref, "Chat Someone Say", GINT_TO_POINTER(8)); 2127 purple_plugin_pref_add_choice(pref, "Chat Someone Say", GINT_TO_POINTER(8));
2061 purple_plugin_pref_add_choice(pref, "Pounce Default", GINT_TO_POINTER(9)); 2128 purple_plugin_pref_add_choice(pref, "Pounce Default", GINT_TO_POINTER(9));
2062 purple_plugin_pref_add_choice(pref, "Chat Nick Said", GINT_TO_POINTER(10)); 2129 purple_plugin_pref_add_choice(pref, "Chat Nick Said", GINT_TO_POINTER(10));
2063 2130 purple_plugin_pref_frame_add(frame, pref);
2064 purple_plugin_pref_frame_add(frame, pref); 2131
2065 2132 /****************/
2066 /************************/ 2133 /* API heading */
2067 /* notification heading */ 2134 /****************/
2068 /************************/ 2135 pref = purple_plugin_pref_new_with_label("API Based Post Configuration");
2069 pref = purple_plugin_pref_new_with_label("Notification Configuration"); 2136 purple_plugin_pref_frame_add(frame, pref);
2070 purple_plugin_pref_frame_add(frame, pref); 2137
2071 2138 /* post configuration */
2072 /* notification setting */
2073 pref = purple_plugin_pref_new_with_name_and_label(OPT_PREVENT_NOTIFICATION,
2074 "Prevent notifications of incoming messages");
2075 purple_plugin_pref_frame_add(frame, pref);
2076
2077
2078 /* API based post */
2079
2080 pref = purple_plugin_pref_new_with_label("API Based Post");
2081 purple_plugin_pref_frame_add(frame, pref);
2082
2083 pref = purple_plugin_pref_new_with_name_and_label(OPT_API_BASE_POST, 2139 pref = purple_plugin_pref_new_with_name_and_label(OPT_API_BASE_POST,
2084 "Post Status with API"); 2140 "Post Status via API");
2085 purple_plugin_pref_frame_add(frame, pref); 2141 purple_plugin_pref_frame_add(frame, pref);
2086 2142
2087 pref = purple_plugin_pref_new_with_name_and_label(OPT_SCREEN_NAME,
2088 "Screen Name");
2089 purple_plugin_pref_frame_add(frame, pref);
2090
2091 pref = purple_plugin_pref_new_with_name_and_label(OPT_PASSWORD,
2092 "Password");
2093 purple_plugin_pref_set_masked(pref, TRUE);
2094
2095 purple_plugin_pref_frame_add(frame, pref);
2096 2143
2097 return frame; 2144 return frame;
2098 } 2145 }
2099 2146
2100 static PurplePluginUiInfo pref_info = { 2147 static PurplePluginUiInfo pref_info = {
2157 purple_prefs_add_bool(OPT_SHOW_ICON, TRUE); 2204 purple_prefs_add_bool(OPT_SHOW_ICON, TRUE);
2158 2205
2159 purple_prefs_add_bool(OPT_API_BASE_POST, FALSE); 2206 purple_prefs_add_bool(OPT_API_BASE_POST, FALSE);
2160 purple_prefs_add_string(OPT_SCREEN_NAME, EMPTY); 2207 purple_prefs_add_string(OPT_SCREEN_NAME, EMPTY);
2161 purple_prefs_add_string(OPT_PASSWORD, EMPTY); 2208 purple_prefs_add_string(OPT_PASSWORD, EMPTY);
2209
2210 purple_prefs_add_int(OPT_ICON_SIZE, 48);
2162 } 2211 }
2163 2212
2164 PURPLE_INIT_PLUGIN(pidgin_twitter, init_plugin, info) 2213 PURPLE_INIT_PLUGIN(pidgin_twitter, init_plugin, info)