Themabewertung:
  • 0 Bewertung(en) - 0 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
Nutzung von libpurple
#1
Hallo, Leute!

Ich versuche ein kleines C-Programm zu schreiben, das mir erlaubt ein ICQ-Nutzer online zu haben und mir (an meine private ICQ-Konto) Nachtrichten zu senden.

Nun, ich habe das nullclient.c kompiliert und es klappt. Der Testnutzer geht online und ich kann ihm was schreiben.
Was ich aber will ist, daß ER mir eine Meldung schickt.

Ich habe folgendes probiert:

Code:
pc=purple_conversation_new(PURPLE_CONV_TYPE_IM,account,"<meine ICQ-Nummer>");
purple_conversation_present(pc);
purple_conversation_set_logging(pc, FALSE);
purple_conv_im_send(PURPLE_CONV_IM(pc),"Hallo");

Aber leider geht es nicht. Es kommt gar kein Fehler, aber ich bekomme auch keine Meldung...

Was mache ich falsch? Ich finde leider keine Dokumentation für die Nutzung der libpurple in C...

Danke
Zitieren
#2
Die Dokumentation findest du unter [1].

[1] http://developer.pidgin.im/doxygen/dev2...._core.html
Welche Pidgin-Version setzt du ein?
Welches Betriebssystem?
Was sagt das Debug-Fenster?

[Bild: pidginbanner.png]
Zitieren
#3
(11.07.2012, 11:42)Freakazoid schrieb: Die Dokumentation findest du unter [1].

[1] http://developer.pidgin.im/doxygen/dev2...._core.html

Naja, hier sind nur die Funktionen gelistet, aber gar kein Beispiel, wie ich sie nutzen soll...

Gibt es auch so was?

Grüße
Luca
Zitieren
#4
Ich kenne nichts.

Da bleibt dir wohl nur der Pidgin- oder finch-Quellcode...

"purple_conversation_new()" gibt aber was gültiges zurück, oder?
Welche Pidgin-Version setzt du ein?
Welches Betriebssystem?
Was sagt das Debug-Fenster?

[Bild: pidginbanner.png]
Zitieren
#5
(11.07.2012, 12:33)Freakazoid schrieb: Ich kenne nichts.

Da bleibt dir wohl nur der Pidgin- oder finch-Quellcode...

"purple_conversation_new()" gibt aber was gültiges zurück, oder?

Ja! Ich kriege einen gültigen Zeiger zum PurpleConversation.

Grüße
Luca
Zitieren
#6
Ist dein Testprogramm geheim? Sonst kann es helfen, wenn du mal den kompletten Quellcode irgendwo hochlädst.
Welche Pidgin-Version setzt du ein?
Welches Betriebssystem?
Was sagt das Debug-Fenster?

[Bild: pidginbanner.png]
Zitieren
#7
(11.07.2012, 12:49)Freakazoid schrieb: Ist dein Testprogramm geheim? Sonst kann es helfen, wenn du mal den kompletten Quellcode irgendwo hochlädst.

Es ist überhaupt nicht geheim! Bisher ist es sogar wenig mehr als nullclient.c...

Hier ist es:
Code:
#include <account.h>
#include <conversation.h>
#include <core.h>
#include <debug.h>
#include <eventloop.h>
#include <ft.h>
#include <log.h>
#include <notify.h>
#include <prefs.h>
#include <prpl.h>
#include <pounce.h>
#include <savedstatuses.h>
#include <sound.h>
#include <status.h>
#include <util.h>
#include <whiteboard.h>

#include <glib.h>

#include <string.h>
#include <unistd.h>

#define CUSTOM_USER_DIRECTORY  "/dev/null"
#define CUSTOM_PLUGIN_PATH     "/dev/null"
#define PLUGIN_SAVE_PREF       "/dev/null"
#define UI_ID                  "TestICQ"

/**
* The following eventloop functions are used in both pidgin and purple-text. If your
* application uses glib mainloop, you can safely use this verbatim.
*/
#define PURPLE_GLIB_READ_COND  (G_IO_IN | G_IO_HUP | G_IO_ERR)
#define PURPLE_GLIB_WRITE_COND (G_IO_OUT | G_IO_HUP | G_IO_ERR | G_IO_NVAL)

typedef struct _PurpleGLibIOClosure {
    PurpleInputFunction function;
    guint result;
    gpointer data;
} PurpleGLibIOClosure;

static void purple_glib_io_destroy(gpointer data)
{
    g_free(data);
}

static gboolean purple_glib_io_invoke(GIOChannel *source, GIOCondition condition, gpointer data)
{
    PurpleGLibIOClosure *closure = data;
    PurpleInputCondition purple_cond = 0;

    if (condition & PURPLE_GLIB_READ_COND)
        purple_cond |= PURPLE_INPUT_READ;
    if (condition & PURPLE_GLIB_WRITE_COND)
        purple_cond |= PURPLE_INPUT_WRITE;

    closure->function(closure->data, g_io_channel_unix_get_fd(source),
              purple_cond);

    return TRUE;
}

static guint glib_input_add(gint fd, PurpleInputCondition condition, PurpleInputFunction function,
                               gpointer data)
{
    PurpleGLibIOClosure *closure = g_new0(PurpleGLibIOClosure, 1);
    GIOChannel *channel;
    GIOCondition cond = 0;

    closure->function = function;
    closure->data = data;

    if (condition & PURPLE_INPUT_READ)
        cond |= PURPLE_GLIB_READ_COND;
    if (condition & PURPLE_INPUT_WRITE)
        cond |= PURPLE_GLIB_WRITE_COND;

    channel = g_io_channel_unix_new(fd);
    closure->result = g_io_add_watch_full(channel, G_PRIORITY_DEFAULT, cond,
                          purple_glib_io_invoke, closure, purple_glib_io_destroy);

    g_io_channel_unref(channel);
    return closure->result;
}

static PurpleEventLoopUiOps glib_eventloops =
{
    g_timeout_add,
    g_source_remove,
    glib_input_add,
    g_source_remove,
    NULL,
#if GLIB_CHECK_VERSION(2,14,0)
    g_timeout_add_seconds,
#else
    NULL,
#endif

    /* padding */
    NULL,
    NULL,
    NULL
};
/*** End of the eventloop functions. ***/

/*** Conversation uiops ***/
static void
null_write_conv(PurpleConversation *conv, const char *who, const char *alias,
            const char *message, PurpleMessageFlags flags, time_t mtime)
{
    const char *name;
    if (alias && *alias)
        name = alias;
    else if (who && *who)
        name = who;
    else
        name = NULL;

    printf("n(%s) %s %s: %s\n", purple_conversation_get_name(conv),
            purple_utf8_strftime("(%H:%M:%S)", localtime(&mtime)),
            name, message);

    if(strcmp(message, "test") == 0)
      purple_conv_im_send(PURPLE_CONV_IM(conv),"hi");
}

static PurpleConversationUiOps null_conv_uiops =
{
    NULL,                      /* create_conversation  */
    NULL,                      /* destroy_conversation */
    NULL,                      /* write_chat           */
    NULL,                      /* write_im             */
    null_write_conv,           /* write_conv           */
    NULL,                      /* chat_add_users       */
    NULL,                      /* chat_rename_user     */
    NULL,                      /* chat_remove_users    */
    NULL,                      /* chat_update_user     */
    NULL,                      /* present              */
    NULL,                      /* has_focus            */
    NULL,                      /* custom_smiley_add    */
    NULL,                      /* custom_smiley_write  */
    NULL,                      /* custom_smiley_close  */
    NULL,                      /* send_confirm         */
    NULL,
    NULL,
    NULL,
    NULL
};

static void
null_ui_init()
{
    /**
     * This should initialize the UI components for all the modules. Here we
     * just initialize the UI for conversations.
     */
    purple_conversations_set_ui_ops(&null_conv_uiops);
}

static PurpleCoreUiOps null_core_uiops =
{
    NULL,
    NULL,
    null_ui_init,
    NULL,

    /* padding */
    NULL,
    NULL,
    NULL,
    NULL
};

static void
init_libpurple()
{
    /* Set a custom user directory (optional) */
    purple_util_set_user_dir(CUSTOM_USER_DIRECTORY);

    /* We do not want any debugging for now to keep the noise to a minimum. */
    purple_debug_set_enabled(FALSE);

    /* Set the core-uiops, which is used to
     *     - initialize the ui specific preferences.
     *     - initialize the debug ui.
     *     - initialize the ui components for all the modules.
     *     - uninitialize the ui components for all the modules when the core terminates.
     */
    purple_core_set_ui_ops(&null_core_uiops);

    /* Set the uiops for the eventloop. If your client is glib-based, you can safely
     * copy this verbatim. */
    purple_eventloop_set_ui_ops(&glib_eventloops);

    /* Set path to search for plugins. The core (libpurple) takes care of loading the
     * core-plugins, which includes the protocol-plugins. So it is not essential to add
     * any path here, but it might be desired, especially for ui-specific plugins. */
    purple_plugins_add_search_path(CUSTOM_PLUGIN_PATH);

    /* Now that all the essential stuff has been set, let's try to init the core. It's
     * necessary to provide a non-NULL name for the current ui to the core. This name
     * is used by stuff that depends on this ui, for example the ui-specific plugins. */
    if (!purple_core_init(UI_ID)) {
        /* Initializing the core failed. Terminate. */
        fprintf(stderr,
                "libpurple initialization failed. Dumping core.\n"
                "Please report this!\n");
        abort();
    }

    /* Create and load the buddylist. */
    purple_set_blist(purple_blist_new());
    purple_blist_load();

    /* Load the preferences. */
    purple_prefs_load();

    /* Load the desired plugins. The client should save the list of loaded plugins in
     * the preferences using purple_plugins_save_loaded(PLUGIN_SAVE_PREF) */
    purple_plugins_load_saved(PLUGIN_SAVE_PREF);

    /* Load the pounces. */
    purple_pounces_load();
}

static void
signed_on(PurpleConnection *gc, gpointer null)
{
    PurpleAccount *account = purple_connection_get_account(gc);
    /*while(!purple_account_is_connected(account)); */

    printf("Account connected: %s %s\n", account->username, account->protocol_id);

printf("A\n");
PurpleConversation *conv;
conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, "<my UID>");
if(conv != NULL)
  printf("OK\n");
printf("C\n");
purple_conversation_set_logging(conv, FALSE);
printf("D\n");
purple_conversation_autoset_title(conv);
printf("E\n");
purple_conv_im_send(PURPLE_CONV_IM(conv), "test");
printf("F\n");

    return;
}

static void
connect_to_signals_for_demonstration_purposes_only()
{
    static int handle;
    purple_signal_connect(purple_connections_get_handle(), "signed-on", &handle,
                PURPLE_CALLBACK(signed_on), NULL);
}

int main()
{
    char name[128];
    char password[255];
    GMainLoop *loop = g_main_loop_new(NULL, FALSE);
    PurpleAccount *account;
    PurpleSavedStatus *status;

    init_libpurple();

    printf("libpurple initialized.\n");

// Zum Test
strcpy(name, "<test UID>");
strcpy(password, "<password>");

    /* Create the account */
    account = purple_account_new(name, "prpl-icq");

    // Ansonsten nutzt libpurple die alte Adresse oscar.aol.com (und geht nicht!)
purple_account_set_string(account, "server", "login.icq.com");
purple_account_set_bool(account, "require_tls", FALSE);

    purple_account_set_password(account, password);

    /* It's necessary to enable the account first. */
    purple_account_set_enabled(account, UI_ID, TRUE);

    /* Now, to connect the account(s), create a status and activate it. */
    status = purple_savedstatus_new("ONLINE", PURPLE_STATUS_AVAILABLE);
    purple_savedstatus_activate(status);

    connect_to_signals_for_demonstration_purposes_only();

    g_main_loop_run(loop);

    return 0;
}
Zitieren
#8
Okay, bei mir funktioniert dein Programm.
Welche Pidgin-Version setzt du ein?
Welches Betriebssystem?
Was sagt das Debug-Fenster?

[Bild: pidginbanner.png]
Zitieren
#9
(11.07.2012, 14:16)Freakazoid schrieb: Okay, bei mir funktioniert dein Programm.

Also, geht online und schickt die Meldung sofort nach dem Login?!?

Dann ist vielleicht ein Bug in meiner libpurple-Version... Ich habe die 2.5.5 von der Ubuntu-Repositories (ich habe eine 8.04).
Was nutzt du?

Danke
Luca
Zitieren
#10
Ja, mein Empfänger bekommt die Nachricht sogar schon bevor er merkt, dass der Kontakt online gekommen ist.

Aber 2.5.5 ist schon extrem alt, das ist schon recht wahrscheinlich, dass ICQ in der Zwischenzeit Kleinigkeiten am Protokoll verändert hat.

Ich habe Version 2.10.4 aus dem Repository von http://pidgin.im/download/ubuntu/ , allerdings wird Hardy da nicht mehr unterstützt.
Welche Pidgin-Version setzt du ein?
Welches Betriebssystem?
Was sagt das Debug-Fenster?

[Bild: pidginbanner.png]
Zitieren


Gehe zu:


Benutzer, die gerade dieses Thema anschauen: 1 Gast/Gäste