Changeset 9c8dbc7


Ignore:
Timestamp:
2015-11-23T17:49:09Z (9 years ago)
Author:
dequis <dx@…>
Branches:
master
Children:
ad9ac5d
Parents:
c34247d
Message:

hipchat: 'chat add hipchat "channel name"' now tries to guess the JID

It's basically prepending the organization id, appending the default MUC
host from the success packet, and generating a slug based on the name
for the middle part, which is replacing a few characters with
underscores and doing a unicode aware lowercasing.

Includes tests, which are useless other than validating the initial
implementation with the test vectors that i already tested manually.
Guaranteed to detect zero breakages in the future. Good test code.

Files:
4 edited

Legend:

Unmodified
Added
Removed
  • protocols/jabber/hipchat.c

    rc34247d r9c8dbc7  
    4242                *sep = '/';
    4343        }
     44
     45        jd->muc_host = g_strdup(xt_find_attr(node, "muc_host"));
    4446
    4547        /* Hipchat's auth doesn't expect a restart here */
     
    9294
    9395}
     96
     97/* Returns a newly allocated string that tries to match the "slug" part of the JID using an
     98 * approximation of the method used by the server. This might fail in some rare conditions
     99 * (old JIDs generated a different way, locale settings unicode, etc) */
     100char *hipchat_make_channel_slug(const char *name)
     101{
     102        char *lower;
     103        char *new = g_malloc(strlen(name) + 1);
     104        int i = 0;
     105
     106        do {
     107                if (*name == ' ') {
     108                        new[i++] = '_';
     109                } else if (*name && !strchr("\"&'/:<>@", *name)) {
     110                        new[i++] = *name;
     111                }
     112        } while (*(name++));
     113
     114        new[i] = '\0';
     115
     116        lower = g_utf8_strdown(new, -1);
     117        g_free(new);
     118
     119        return lower;
     120}
     121
     122char *hipchat_guess_channel_name(struct im_connection *ic, const char *name)
     123{
     124        struct jabber_data *jd = ic->proto_data;
     125        char *slug, *retval, *underscore;
     126       
     127        if (!(underscore = strchr(jd->username, '_')) || !jd->muc_host) {
     128                return NULL;
     129        }
     130
     131        slug = hipchat_make_channel_slug(name);
     132
     133        /* Get the organization ID from the username, before the underscore */
     134        *underscore = '\0';
     135
     136        retval = g_strdup_printf("%s_%s@%s", jd->username, slug, jd->muc_host);
     137
     138        *underscore = '_';
     139
     140        g_free(slug);
     141
     142        return retval;
     143}
  • protocols/jabber/jabber.c

    rc34247d r9c8dbc7  
    371371        g_free(jd->internal_jid);
    372372        g_free(jd->gmail_tid);
     373        g_free(jd->muc_host);
    373374        g_free(jd->username);
    374375        g_free(jd->me);
     
    533534        }
    534535
     536        if (jd->flags & JFLAG_HIPCHAT && jd->muc_host && !g_str_has_suffix(room, jd->muc_host)) {
     537                char *guessed_name = hipchat_guess_channel_name(ic, room);
     538                if (guessed_name) {
     539                        set_setstr(sets, "room", guessed_name);
     540                        g_free(guessed_name);
     541
     542                        /* call this same function again with the fixed name */
     543                        return jabber_chat_join_(ic, set_getstr(sets, "room"), nick, password, sets);
     544                }
     545        }
     546
    535547        if (strchr(room, '@') == NULL) {
    536548                imcb_error(ic, "%s is not a valid Jabber room name. Maybe you mean %s@conference.%s?",
     
    539551                imcb_error(ic, "Already present in chat `%s'", room);
    540552        } else {
     553                /* jabber_chat_join without the underscore is the conference.c one */
    541554                return jabber_chat_join(ic, room, final_nick, set_getstr(sets, "password"));
    542555        }
  • protocols/jabber/jabber.h

    rc34247d r9c8dbc7  
    113113        GSList *streamhosts;
    114114        int have_streamhosts;
     115
     116        char *muc_host;
    115117};
    116118
     
    358360xt_status jabber_parse_hipchat_profile(struct im_connection *ic, struct xt_node *node, struct xt_node *orig);
    359361xt_status hipchat_handle_success(struct im_connection *ic, struct xt_node *node);
     362char *hipchat_make_channel_slug(const char *name);
     363char *hipchat_guess_channel_name(struct im_connection *ic, const char *name);
    360364
    361365#endif
  • tests/check_jabber_util.c

    rc34247d r9c8dbc7  
    105105}
    106106
     107static void check_hipchat_slug(int l)
     108{
     109        int i;
     110
     111        const char *tests[] = {
     112                "test !\"#$%&\'()*+,-./0123456789:;<=>?@ABC", "test_!#$%\()*+,-.0123456789;=?abc",
     113                "test XYZ[\\]^_`abc", "test_xyz[\\]^_`abc",
     114                "test {|}~¡¢£¤¥¦§¨©ª«¬\xad®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆ", "test_{|}~¡¢£¤¥¦§¨©ª«¬\xad®¯°±²³´µ¶·¸¹º»¼½¾¿àáâãäåæ",
     115                "test IJ ij I ı I ı", "test_ij_ij_i_ı_i_ı",
     116                NULL,
     117        };
     118
     119        for (i = 0; tests[i]; i += 2) {
     120                char *new = hipchat_make_channel_slug(tests[i]);
     121                fail_unless(!strcmp(tests[i + 1], new));
     122                g_free(new);
     123        }
     124}
     125
    107126Suite *jabber_util_suite(void)
    108127{
     
    121140        tcase_add_test(tc_core, check_buddy_add);
    122141        tcase_add_test(tc_core, check_compareJID);
     142        tcase_add_test(tc_core, check_hipchat_slug);
    123143        return s;
    124144}
Note: See TracChangeset for help on using the changeset viewer.