comparison libpurple/plugins/log_reader.c @ 20453:69febfa6d307

propagate from branch 'im.pidgin.pidgin' (head d3e5a5add3f39caa08b46c83177328e51c2d961a) to branch 'im.pidgin.cpw.khc.msnp14' (head a8f6c999b039b4097aa70cd8d2597f3127615435)
author Carlos Silva <typ0@pidgin.im>
date Sat, 16 Jun 2007 04:00:32 +0000
parents c0cd4d84ba52
children 285779ebfe0b
comparison
equal deleted inserted replaced
20452:5c34a0a3c362 20453:69febfa6d307
1288 1288
1289 trillian_logger_finalize((PurpleLog *)last->data); 1289 trillian_logger_finalize((PurpleLog *)last->data);
1290 list = g_list_delete_link(list, last); 1290 list = g_list_delete_link(list, last);
1291 } 1291 }
1292 } 1292 }
1293 } else if (line[0] && line[1] && line [3] && 1293 } else if (line[0] && line[1] && line[2] &&
1294 purple_str_has_prefix(&line[3], "sion Start ")) { 1294 purple_str_has_prefix(&line[3], "sion Start ")) {
1295 1295 /* The conditional is to make sure we're not reading off
1296 * the end of the string. We don't want strlen(), as that'd
1297 * have to count the whole string needlessly.
1298 *
1299 * The odd check here is because a Session Start at the
1300 * beginning of the file can be overwritten with a UTF-8
1301 * byte order mark. Yes, it's weird.
1302 */
1296 char *their_nickname = line; 1303 char *their_nickname = line;
1297 char *timestamp; 1304 char *timestamp;
1298 1305
1299 if (data && !data->length) 1306 if (data && !data->length)
1300 data->length = last_line_offset - data->offset; 1307 data->length = last_line_offset - data->offset;
1423 FILE *file; 1430 FILE *file;
1424 PurpleBuddy *buddy; 1431 PurpleBuddy *buddy;
1425 char *escaped; 1432 char *escaped;
1426 GString *formatted; 1433 GString *formatted;
1427 char *c; 1434 char *c;
1428 char *line; 1435 const char *line;
1429 1436
1430 g_return_val_if_fail(log != NULL, g_strdup("")); 1437 g_return_val_if_fail(log != NULL, g_strdup(""));
1431 1438
1432 data = log->logger_data; 1439 data = log->logger_data;
1433 1440
1458 escaped = g_markup_escape_text(read, -1); 1465 escaped = g_markup_escape_text(read, -1);
1459 g_free(read); 1466 g_free(read);
1460 read = escaped; 1467 read = escaped;
1461 1468
1462 /* Apply formatting... */ 1469 /* Apply formatting... */
1463 formatted = g_string_new(""); 1470 formatted = g_string_sized_new(strlen(read));
1464 c = read; 1471 c = read;
1465 line = read; 1472 line = read;
1466 while (*c) 1473 while (c)
1467 { 1474 {
1468 if (*c == '\n') 1475 const char *link;
1476 const char *footer = NULL;
1477 GString *temp = NULL;
1478
1479 if ((c = strstr(c, "\n")))
1469 { 1480 {
1470 char *link_temp_line;
1471 char *link;
1472 char *timestamp;
1473 char *footer = NULL;
1474 *c = '\0'; 1481 *c = '\0';
1475 1482 c++;
1476 /* Convert links. 1483 }
1477 * 1484
1478 * The format is (Link: URL)URL 1485 /* Convert links.
1479 * So, I want to find each occurance of "(Link: " and replace that chunk with: 1486 *
1480 * <a href=" 1487 * The format is (Link: URL)URL
1481 * Then, replace the next ")" with: 1488 * So, I want to find each occurance of "(Link: " and replace that chunk with:
1482 * "> 1489 * <a href="
1483 * Then, replace the next " " (or add this if the end-of-line is reached) with: 1490 * Then, replace the next ")" with:
1484 * </a> 1491 * ">
1485 */ 1492 * Then, replace the next " " (or add this if the end-of-line is reached) with:
1486 link_temp_line = NULL; 1493 * </a>
1487 while ((link = g_strstr_len(line, strlen(line), "(Link: "))) { 1494 *
1488 GString *temp; 1495 * As implemented, this isn't perfect, but it should cover common cases.
1489 1496 */
1490 if (!*link) 1497 while (line && (link = strstr(line, "(Link: ")))
1491 continue; 1498 {
1492 1499 const char *tmp = link;
1493 *link = '\0'; 1500
1494 link++; 1501 link += 7;
1495 1502 if (*link)
1496 temp = g_string_new(line); 1503 {
1504 char *end_paren;
1505 char *space;
1506
1507 if (!(end_paren = strstr(link, ")")))
1508 {
1509 /* Something is not as we expect. Bail out. */
1510 break;
1511 }
1512
1513 if (!temp)
1514 temp = g_string_sized_new(c ? (c - 1 - line) : strlen(line));
1515
1516 g_string_append_len(temp, line, (tmp - line));
1517
1518 /* Start an <a> tag. */
1497 g_string_append(temp, "<a href=\""); 1519 g_string_append(temp, "<a href=\"");
1498 1520
1499 if (strlen(link) >= 6) { 1521 /* Append up to the ) */
1500 link += (sizeof("(Link: ") - 1); 1522 g_string_append_len(temp, link, end_paren - link);
1501 1523
1502 while (*link && *link != ')') { 1524 /* Finish the <a> tag. */
1503 g_string_append_c(temp, *link); 1525 g_string_append(temp, "\">");
1504 link++; 1526
1527 /* The \r is a bit of a hack to keep there from being a \r in
1528 * the link text, which may not matter. */
1529 if ((space = strstr(end_paren, " ")) || (space = strstr(end_paren, "\r")))
1530 {
1531 g_string_append_len(temp, end_paren + 1, space - end_paren - 1);
1532
1533 /* Close the <a> tag. */
1534 g_string_append(temp, "</a>");
1535
1536 space++;
1537 }
1538 else
1539 {
1540 /* There is no space before the end of the line. */
1541 g_string_append(temp, end_paren + 1);
1542 /* Close the <a> tag. */
1543 g_string_append(temp, "</a>");
1544 }
1545 line = space;
1546 }
1547 else
1548 {
1549 /* Something is not as we expect. Bail out. */
1550 break;
1551 }
1552 }
1553
1554 if (temp)
1555 {
1556 if (line)
1557 g_string_append(temp, line);
1558 line = temp->str;
1559 }
1560
1561 if (*line == '[') {
1562 const char *timestamp;
1563
1564 if ((timestamp = strstr(line, "]"))) {
1565 line++;
1566 /* TODO: Parse the timestamp and convert it to Purple's format. */
1567 g_string_append(formatted, "<font size=\"2\">(");
1568 g_string_append_len(formatted, line, (timestamp - line));
1569 g_string_append(formatted,")</font> ");
1570 line = timestamp + 1;
1571 if (line[0] && line[1])
1572 line++;
1573 }
1574
1575 if (purple_str_has_prefix(line, "*** ")) {
1576 line += (sizeof("*** ") - 1);
1577 g_string_append(formatted, "<b>");
1578 footer = "</b>";
1579 if (purple_str_has_prefix(line, "NOTE: This user is offline.")) {
1580 line = _("User is offline.");
1581 } else if (purple_str_has_prefix(line,
1582 "NOTE: Your status is currently set to ")) {
1583
1584 line += (sizeof("NOTE: ") - 1);
1585 } else if (purple_str_has_prefix(line, "Auto-response sent to ")) {
1586 g_string_append(formatted, _("Auto-response sent:"));
1587 while (*line && *line != ':')
1588 line++;
1589 if (*line)
1590 line++;
1591 g_string_append(formatted, "</b>");
1592 footer = NULL;
1593 } else if (strstr(line, " signed off ")) {
1594 if (buddy != NULL && buddy->alias)
1595 g_string_append_printf(formatted,
1596 _("%s has signed off."), buddy->alias);
1597 else
1598 g_string_append_printf(formatted,
1599 _("%s has signed off."), log->name);
1600 line = "";
1601 } else if (strstr(line, " signed on ")) {
1602 if (buddy != NULL && buddy->alias)
1603 g_string_append(formatted, buddy->alias);
1604 else
1605 g_string_append(formatted, log->name);
1606 line = " logged in.";
1607 } else if (purple_str_has_prefix(line,
1608 "One or more messages may have been undeliverable.")) {
1609
1610 g_string_append(formatted,
1611 "<span style=\"color: #ff0000;\">");
1612 g_string_append(formatted,
1613 _("One or more messages may have been "
1614 "undeliverable."));
1615 line = "";
1616 footer = "</span></b>";
1617 } else if (purple_str_has_prefix(line,
1618 "You have been disconnected.")) {
1619
1620 g_string_append(formatted,
1621 "<span style=\"color: #ff0000;\">");
1622 g_string_append(formatted,
1623 _("You were disconnected from the server."));
1624 line = "";
1625 footer = "</span></b>";
1626 } else if (purple_str_has_prefix(line,
1627 "You are currently disconnected.")) {
1628
1629 g_string_append(formatted,
1630 "<span style=\"color: #ff0000;\">");
1631 line = _("You are currently disconnected. Messages "
1632 "will not be received unless you are "
1633 "logged in.");
1634 footer = "</span></b>";
1635 } else if (purple_str_has_prefix(line,
1636 "Your previous message has not been sent.")) {
1637
1638 g_string_append(formatted,
1639 "<span style=\"color: #ff0000;\">");
1640
1641 if (purple_str_has_prefix(line,
1642 "Your previous message has not been sent. "
1643 "Reason: Maximum length exceeded.")) {
1644
1645 g_string_append(formatted,
1646 _("Message could not be sent because "
1647 "the maximum length was exceeded."));
1648 line = "";
1649 } else {
1650 g_string_append(formatted,
1651 _("Message could not be sent."));
1652 line += (sizeof(
1653 "Your previous message "
1654 "has not been sent. ") - 1);
1505 } 1655 }
1506 if (link) { 1656
1507 link++; 1657 footer = "</span></b>";
1508 1658 }
1509 g_string_append(temp, "\">"); 1659 } else if (purple_str_has_prefix(line, data->their_nickname)) {
1510 while (*link && *link != ' ') { 1660 if (buddy != NULL && buddy->alias) {
1511 g_string_append_c(temp, *link); 1661 line += strlen(data->their_nickname) + 2;
1512 link++; 1662 g_string_append_printf(formatted,
1513 } 1663 "<span style=\"color: #A82F2F;\">"
1514 g_string_append(temp, "</a>"); 1664 "<b>%s</b></span>: ", buddy->alias);
1515 } 1665 }
1516 1666 } else {
1517 g_string_append(temp, link); 1667 const char *line2 = strstr(line, ":");
1518 1668 if (line2) {
1519 /* Free the last round's line. */ 1669 const char *acct_name;
1520 if (link_temp_line) 1670 line2++;
1521 g_free(line); 1671 line = line2;
1522 1672 acct_name = purple_account_get_alias(log->account);
1523 line = temp->str; 1673 if (!acct_name)
1524 g_string_free(temp, FALSE); 1674 acct_name = purple_account_get_username(log->account);
1525 1675
1526 /* Save this memory location so we can free it later. */ 1676 g_string_append_printf(formatted,
1527 link_temp_line = line; 1677 "<span style=\"color: #16569E;\">"
1678 "<b>%s</b></span>:", acct_name);
1528 } 1679 }
1529 } 1680 }
1530 1681 }
1531 timestamp = ""; 1682
1532 if (*line == '[') { 1683 g_string_append(formatted, line);
1533 timestamp = line; 1684
1534 while (*timestamp && *timestamp != ']') 1685 line = c;
1535 timestamp++; 1686 if (temp)
1536 if (*timestamp == ']') { 1687 g_string_free(temp, TRUE);
1537 *timestamp = '\0'; 1688
1538 line++; 1689 if (footer)
1539 /* TODO: Parse the timestamp and convert it to Purple's format. */ 1690 g_string_append(formatted, footer);
1540 g_string_append_printf(formatted, 1691
1541 "<font size=\"2\">(%s)</font> ", line); 1692 g_string_append_c(formatted, '\n');
1542 line = timestamp;
1543 if (line[1] && line[2])
1544 line += 2;
1545 }
1546
1547 if (purple_str_has_prefix(line, "*** ")) {
1548 line += (sizeof("*** ") - 1);
1549 g_string_append(formatted, "<b>");
1550 footer = "</b>";
1551 if (purple_str_has_prefix(line, "NOTE: This user is offline.")) {
1552 line = _("User is offline.");
1553 } else if (purple_str_has_prefix(line,
1554 "NOTE: Your status is currently set to ")) {
1555
1556 line += (sizeof("NOTE: ") - 1);
1557 } else if (purple_str_has_prefix(line, "Auto-response sent to ")) {
1558 g_string_append(formatted, _("Auto-response sent:"));
1559 while (*line && *line != ':')
1560 line++;
1561 if (*line)
1562 line++;
1563 g_string_append(formatted, "</b>");
1564 footer = NULL;
1565 } else if (strstr(line, " signed off ")) {
1566 if (buddy != NULL && buddy->alias)
1567 g_string_append_printf(formatted,
1568 _("%s has signed off."), buddy->alias);
1569 else
1570 g_string_append_printf(formatted,
1571 _("%s has signed off."), log->name);
1572 line = "";
1573 } else if (strstr(line, " signed on ")) {
1574 if (buddy != NULL && buddy->alias)
1575 g_string_append(formatted, buddy->alias);
1576 else
1577 g_string_append(formatted, log->name);
1578 line = " logged in.";
1579 } else if (purple_str_has_prefix(line,
1580 "One or more messages may have been undeliverable.")) {
1581
1582 g_string_append(formatted,
1583 "<span style=\"color: #ff0000;\">");
1584 g_string_append(formatted,
1585 _("One or more messages may have been "
1586 "undeliverable."));
1587 line = "";
1588 footer = "</span></b>";
1589 } else if (purple_str_has_prefix(line,
1590 "You have been disconnected.")) {
1591
1592 g_string_append(formatted,
1593 "<span style=\"color: #ff0000;\">");
1594 g_string_append(formatted,
1595 _("You were disconnected from the server."));
1596 line = "";
1597 footer = "</span></b>";
1598 } else if (purple_str_has_prefix(line,
1599 "You are currently disconnected.")) {
1600
1601 g_string_append(formatted,
1602 "<span style=\"color: #ff0000;\">");
1603 line = _("You are currently disconnected. Messages "
1604 "will not be received unless you are "
1605 "logged in.");
1606 footer = "</span></b>";
1607 } else if (purple_str_has_prefix(line,
1608 "Your previous message has not been sent.")) {
1609
1610 g_string_append(formatted,
1611 "<span style=\"color: #ff0000;\">");
1612
1613 if (purple_str_has_prefix(line,
1614 "Your previous message has not been sent. "
1615 "Reason: Maximum length exceeded.")) {
1616
1617 g_string_append(formatted,
1618 _("Message could not be sent because "
1619 "the maximum length was exceeded."));
1620 line = "";
1621 } else {
1622 g_string_append(formatted,
1623 _("Message could not be sent."));
1624 line += (sizeof(
1625 "Your previous message "
1626 "has not been sent. ") - 1);
1627 }
1628
1629 footer = "</span></b>";
1630 }
1631 } else if (purple_str_has_prefix(line, data->their_nickname)) {
1632 if (buddy != NULL && buddy->alias) {
1633 line += strlen(data->their_nickname) + 2;
1634 g_string_append_printf(formatted,
1635 "<span style=\"color: #A82F2F;\">"
1636 "<b>%s</b></span>: ", buddy->alias);
1637 }
1638 } else {
1639 char *line2 = line;
1640 while (*line2 && *line2 != ':')
1641 line2++;
1642 if (*line2 == ':') {
1643 const char *acct_name;
1644 line2++;
1645 line = line2;
1646 acct_name = purple_account_get_alias(log->account);
1647 if (!acct_name)
1648 acct_name = purple_account_get_username(log->account);
1649
1650 g_string_append_printf(formatted,
1651 "<span style=\"color: #16569E;\">"
1652 "<b>%s</b></span>:", acct_name);
1653 }
1654 }
1655 }
1656
1657 g_string_append(formatted, line);
1658
1659 if (footer)
1660 g_string_append(formatted, footer);
1661
1662 g_string_append_c(formatted, '\n');
1663
1664 if (link_temp_line)
1665 g_free(link_temp_line);
1666
1667 c++;
1668 line = c;
1669 } else
1670 c++;
1671 } 1693 }
1672 1694
1673 g_free(read); 1695 g_free(read);
1674 read = formatted->str; 1696 /* XXX: TODO: Avoid this g_strchomp() */
1675 g_string_free(formatted, FALSE); 1697 return g_strchomp(g_string_free(formatted, FALSE));
1676
1677 return read;
1678 } 1698 }
1679 1699
1680 static int trillian_logger_size (PurpleLog *log) 1700 static int trillian_logger_size (PurpleLog *log)
1681 { 1701 {
1682 struct trillian_logger_data *data; 1702 struct trillian_logger_data *data;