New upstream release; from the RELEASE-NOTES:
authorgregor herrmann <gregoa@debian.org>
Thu, 12 Mar 2009 15:55:34 +0000 (15:55 -0000)
committergregor herrmann <gregoa@debian.org>
Thu, 12 Mar 2009 15:55:34 +0000 (15:55 -0000)
"--action support, bti now can output data from the twitter
and identica servers".

ChangeLog
Makefile
RELEASE-NOTES
bti-bashcompletion
bti.c
bti.example
bti.xml
debian/changelog

index 2822668..e96b9ef 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,23 @@
+Summary of changes from v014 to v015
+============================================
+
+Amir Mohammad Saied (11):
+      Actions support for bti
+      libxml2 libs and cflags
+      action and values for bash completion
+      Added action option in example bti config file
+      User action
+      Replies action
+      Updating bashcompletion and example config file for new actions
+      logging more
+      Updating documents
+      Handling unknown actions
+      Fixing an assignment issue
+
+Greg Kroah-Hartman (2):
+      Change the formatting of --action output
+      fix readline mess when in --bash mode
+
 Summary of changes from v013 to v014
 ============================================
 
index d2c9031..994e5e3 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -16,7 +16,7 @@
 #
 #
 
-VERSION = 014
+VERSION = 015
 
 PROGRAM = bti
 
@@ -34,7 +34,8 @@ CC = $(CROSS_COMPILE)gcc
 LD = $(CROSS_COMPILE)gcc
 AR = $(CROSS_COMPILE)ar
 
-override CFLAGS        += -g -Wall -pipe -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -O2
+XML2_CFLAGS = `xml2-config --cflags`
+override CFLAGS        += -g -Wall -pipe -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -O2 $(XML2_CFLAGS)
 
 WARNINGS       = -Wstrict-prototypes -Wsign-compare -Wshadow \
                  -Wchar-subscripts -Wmissing-declarations -Wnested-externs \
@@ -60,13 +61,14 @@ export E Q
 # We need -lpthread for the pthread example
 #LIB_OBJS = -lcurl -lnsl -lssl -lcrypto
 LIB_OBJS = -lcurl -lnsl -lreadline
+LIB_XML2 = `xml2-config --libs`
 
 all:   $(PROGRAM) $(MAN_PAGES)
 
 # "Static Pattern Rule" to build all programs
 bti: %: $(HEADERS) $(GEN_HEADERS) $(CORE_OBJS)
        $(E) "  LD      " $@
-       $(Q) $(LD) $(LDFLAGS) $(CORE_OBJS) -o $@ $(LIB_OBJS)
+       $(Q) $(LD) $(LDFLAGS) $(CORE_OBJS) -o $@ $(LIB_OBJS) $(LIB_XML2)
 
 
 # build the objects
index b5c8fa6..533b88e 100644 (file)
@@ -1,3 +1,9 @@
+bti 015
+=============
+--action support, bti now can output data from the twitter
+and identica servers!  Thanks to Amir Saied for the work he put into this.
+minor bugfixes for bash mode, bah, readline is a pain at times.
+
 bti 014
 =============
 Fix reported readline bugs
index fa155bc..3b0f4d4 100644 (file)
@@ -5,15 +5,19 @@ _bti()
        cur="${COMP_WORDS[COMP_CWORD]}"
        prev="${COMP_WORDS[COMP_CWORD-1]}"
        if [[ "${cur}" == -* ]] ; then
-               COMPREPLY=( $(compgen -W "-a -p -P -H -b -d -v -h --account \
-                       --password --proxy --host --bash --debug --version \
-                       --help" -- ${cur}) )
+               COMPREPLY=( $(compgen -W "-a -A -p -P -H -b -d -v -h
+                       --account --action --password --proxy --host --bash \
+                       --user --debug --version --help" -- ${cur}) )
        fi
 
        if [[ "${prev}" == "--host" ]] ; then
                COMPREPLY=( $(compgen -W "twitter identica" -- ${cur} ) )
        fi
 
+       if [[ "${prev}" == "--action" ]] ; then
+               COMPREPLY=( $(compgen -W "friends public update user replies" -- ${cur} ) )
+       fi
+
        return 0
 }
 
diff --git a/bti.c b/bti.c
index 2f3b35a..8f09356 100644 (file)
--- a/bti.c
+++ b/bti.c
@@ -28,6 +28,9 @@
 #include <sys/stat.h>
 #include <curl/curl.h>
 #include <readline/readline.h>
+#include <libxml/xmlmemory.h>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
 #include "bti_version.h"
 
 
@@ -47,6 +50,15 @@ enum host {
        HOST_IDENTICA = 1,
 };
 
+enum action {
+       ACTION_UPDATE = 0,
+       ACTION_FRIENDS = 1,
+       ACTION_USER = 2,
+       ACTION_REPLIES = 4,
+       ACTION_PUBLIC = 8,
+       ACTION_UNKNOWN = 16
+};
+
 struct session {
        char *password;
        char *account;
@@ -55,24 +67,30 @@ struct session {
        char *time;
        char *homedir;
        char *logfile;
+       char *user;
        int bash;
        enum host host;
+       enum action action;
 };
 
 struct bti_curl_buffer {
        char *data;
+       enum action action;
        int length;
 };
 
 static void display_help(void)
 {
-       fprintf(stdout, "bti - send tweet to twitter\n");
+       fprintf(stdout, "bti - send tweet to twitter or identi.ca\n");
        fprintf(stdout, "Version: " BTI_VERSION "\n");
        fprintf(stdout, "Usage:\n");
        fprintf(stdout, "  bti [options]\n");
        fprintf(stdout, "options are:\n");
        fprintf(stdout, "  --account accountname\n");
        fprintf(stdout, "  --password password\n");
+       fprintf(stdout, "  --action action\n");
+       fprintf(stdout, "    ('update', 'friends', 'public', 'replies' or 'user')\n");
+       fprintf(stdout, "  --user screenname\n");
        fprintf(stdout, "  --proxy PROXY:PORT\n");
        fprintf(stdout, "  --host HOST\n");
        fprintf(stdout, "  --logfile logfile\n");
@@ -107,10 +125,11 @@ static void session_free(struct session *session)
        free(session->proxy);
        free(session->time);
        free(session->homedir);
+       free(session->user);
        free(session);
 }
 
-static struct bti_curl_buffer *bti_curl_buffer_alloc(void)
+static struct bti_curl_buffer *bti_curl_buffer_alloc(enum action action)
 {
        struct bti_curl_buffer *buffer;
 
@@ -126,6 +145,7 @@ static struct bti_curl_buffer *bti_curl_buffer_alloc(void)
                return NULL;
        }
        buffer->length = 0;
+       buffer->action = action;
        return buffer;
 }
 
@@ -137,8 +157,17 @@ static void bti_curl_buffer_free(struct bti_curl_buffer *buffer)
        free(buffer);
 }
 
-static const char *twitter_url = "https://twitter.com/statuses/update.xml";
-static const char *identica_url = "http://identi.ca/api/statuses/update.xml";
+static const char *twitter_user_url    = "http://twitter.com/statuses/user_timeline/";
+static const char *twitter_update_url  = "https://twitter.com/statuses/update.xml";
+static const char *twitter_public_url  = "http://twitter.com/statuses/public_timeline.xml";
+static const char *twitter_friends_url = "https://twitter.com/statuses/friends_timeline.xml";
+static const char *twitter_replies_url = "http://twitter.com/statuses/replies.xml";
+
+static const char *identica_user_url    = "http://identi.ca/api/statuses/user_timeline/";
+static const char *identica_update_url  = "http://identi.ca/api/statuses/update.xml";
+static const char *identica_public_url  = "http://identi.ca/api/statuses/public_timeline.xml";
+static const char *identica_friends_url = "http://identi.ca/api/statuses/friends_timeline.xml";
+static const char *identica_replies_url = "http://identi.ca/api/statuses/replies.xml";
 
 static CURL *curl_init(void)
 {
@@ -155,6 +184,75 @@ static CURL *curl_init(void)
        return curl;
 }
 
+void parse_statuses(xmlDocPtr doc, xmlNodePtr current)
+{
+       xmlChar *text = NULL;
+       xmlChar *user = NULL;
+       xmlNodePtr userinfo;
+
+       current = current->xmlChildrenNode;
+       while (current != NULL) {
+               if (current->type == XML_ELEMENT_NODE) {
+                       if (!xmlStrcmp(current->name, (const xmlChar *)"text"))
+                               text = xmlNodeListGetString(doc, current->xmlChildrenNode, 1);
+                       if (!xmlStrcmp(current->name, (const xmlChar *)"user")) {
+                               userinfo = current->xmlChildrenNode;
+                               while (userinfo != NULL) {
+                                       if ((!xmlStrcmp(userinfo->name, (const xmlChar *)"screen_name"))) {
+                                               if (user)
+                                                       xmlFree(user);
+                                               user = xmlNodeListGetString(doc, userinfo->xmlChildrenNode, 1);
+                                       }
+                                       userinfo = userinfo->next;
+                               }
+                       }
+                       if (user && text) {
+                               printf("[%s] %s\n", user, text);
+                               xmlFree(user);
+                               xmlFree(text);
+                               user = NULL;
+                               text = NULL;
+                       }
+               }
+               current = current->next;
+       }
+
+       return;
+}
+
+static void parse_timeline(char *document)
+{
+       xmlDocPtr doc;
+       xmlNodePtr current;
+       doc = xmlReadMemory(document, strlen(document), "timeline.xml", NULL, XML_PARSE_NOERROR);
+
+       if (doc == NULL)
+               return;
+
+       current = xmlDocGetRootElement(doc);
+       if (current == NULL) {
+               fprintf(stderr, "empty document\n");
+               xmlFreeDoc(doc);
+               return;
+       }
+
+       if (xmlStrcmp(current->name, (const xmlChar *) "statuses")) {
+               fprintf(stderr, "unexpected document type\n");
+               xmlFreeDoc(doc);
+               return;
+       }
+
+       current = current->xmlChildrenNode;
+       while (current != NULL) {
+               if ((!xmlStrcmp(current->name, (const xmlChar *)"status")))
+                       parse_statuses(doc, current);
+               current = current->next;
+       }
+       xmlFreeDoc(doc);
+
+       return;
+}
+
 size_t curl_callback(void *buffer, size_t size, size_t nmemb, void *userp)
 {
        struct bti_curl_buffer *curl_buf = userp;
@@ -174,16 +272,20 @@ size_t curl_callback(void *buffer, size_t size, size_t nmemb, void *userp)
        curl_buf->data = temp;
        memcpy(&curl_buf->data[curl_buf->length], (char *)buffer, buffer_size);
        curl_buf->length += buffer_size;
+       if (curl_buf->action)
+               parse_timeline(curl_buf->data);
 
        dbg("%s\n", curl_buf->data);
 
        return buffer_size;
 }
 
-static int send_tweet(struct session *session)
+static int send_request(struct session *session)
 {
        char user_password[500];
        char data[500];
+       /* is there usernames longer than 22 chars? */
+       char user_url[70];
        struct bti_curl_buffer *curl_buf;
        CURL *curl = NULL;
        CURLcode res;
@@ -194,42 +296,96 @@ static int send_tweet(struct session *session)
        if (!session)
                return -EINVAL;
 
-       curl_buf = bti_curl_buffer_alloc();
+       curl_buf = bti_curl_buffer_alloc(session->action);
        if (!curl_buf)
                return -ENOMEM;
 
-       snprintf(user_password, sizeof(user_password), "%s:%s",
-                session->account, session->password);
-       snprintf(data, sizeof(data), "status=\"%s\"", session->tweet);
-
        curl = curl_init();
        if (!curl)
                return -EINVAL;
 
-       curl_formadd(&formpost, &lastptr,
-                    CURLFORM_COPYNAME, "status",
-                    CURLFORM_COPYCONTENTS, session->tweet,
-                    CURLFORM_END);
+       switch (session->action) {
+       case ACTION_UPDATE:
+               snprintf(user_password, sizeof(user_password), "%s:%s",
+                        session->account, session->password);
+               snprintf(data, sizeof(data), "status=\"%s\"", session->tweet);
+               curl_formadd(&formpost, &lastptr,
+                            CURLFORM_COPYNAME, "status",
+                            CURLFORM_COPYCONTENTS, session->tweet,
+                            CURLFORM_END);
+
+               curl_formadd(&formpost, &lastptr,
+                            CURLFORM_COPYNAME, "source",
+                            CURLFORM_COPYCONTENTS, "bti",
+                            CURLFORM_END);
+
+               curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
+               slist = curl_slist_append(slist, "Expect:");
+               curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist);
+               switch (session->host) {
+               case HOST_TWITTER:
+                       curl_easy_setopt(curl, CURLOPT_URL, twitter_update_url);
+                       break;
+               case HOST_IDENTICA:
+                       curl_easy_setopt(curl, CURLOPT_URL, identica_update_url);
+                       break;
+               }
+               curl_easy_setopt(curl, CURLOPT_USERPWD, user_password);
 
-       curl_formadd(&formpost, &lastptr,
-                    CURLFORM_COPYNAME, "source",
-                    CURLFORM_COPYCONTENTS, "bti",
-                    CURLFORM_END);
+               break;
+       case ACTION_FRIENDS:
+               snprintf(user_password, sizeof(user_password), "%s:%s",
+                        session->account, session->password);
+               switch (session->host) {
+               case HOST_TWITTER:
+                       curl_easy_setopt(curl, CURLOPT_URL, twitter_friends_url);
+                       break;
+               case HOST_IDENTICA:
+                       curl_easy_setopt(curl, CURLOPT_URL, identica_friends_url);
+                       break;
+               }
+               curl_easy_setopt(curl, CURLOPT_USERPWD, user_password);
 
-       curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
+               break;
+       case ACTION_USER:
+               switch (session->host) {
+               case HOST_TWITTER:
+                       sprintf(user_url, "%s%s.xml", twitter_user_url, session->user);
+                       curl_easy_setopt(curl, CURLOPT_URL, user_url);
+                       break;
+               case HOST_IDENTICA:
+                       sprintf(user_url, "%s%s.xml", identica_user_url, session->user);
+                       curl_easy_setopt(curl, CURLOPT_URL, user_url);
+                       break;
+               }
 
-       switch (session->host) {
-       case HOST_TWITTER:
-               curl_easy_setopt(curl, CURLOPT_URL, twitter_url);
-               /*
-                * twitter doesn't like the "Expect: 100-continue" header
-                * anymore, so turn it off.
-                */
-               slist = curl_slist_append(slist, "Expect:");
-               curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist);
                break;
-       case HOST_IDENTICA:
-               curl_easy_setopt(curl, CURLOPT_URL, identica_url);
+       case ACTION_REPLIES:
+               snprintf(user_password, sizeof(user_password), "%s:%s",
+                        session->account, session->password);
+               switch (session->host) {
+               case HOST_TWITTER:
+                       curl_easy_setopt(curl, CURLOPT_URL, twitter_replies_url);
+                       break;
+               case HOST_IDENTICA:
+                       curl_easy_setopt(curl, CURLOPT_URL, identica_replies_url);
+                       break;
+               }
+               curl_easy_setopt(curl, CURLOPT_USERPWD, user_password);
+
+               break;
+       case ACTION_PUBLIC:
+               switch (session->host) {
+               case HOST_TWITTER:
+                       curl_easy_setopt(curl, CURLOPT_URL, twitter_public_url);
+                       break;
+               case HOST_IDENTICA:
+                       curl_easy_setopt(curl, CURLOPT_URL, identica_public_url);
+                       break;
+               }
+
+               break;
+       default:
                break;
        }
 
@@ -238,7 +394,6 @@ static int send_tweet(struct session *session)
 
        if (debug)
                curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
-       curl_easy_setopt(curl, CURLOPT_USERPWD, user_password);
 
        dbg("user_password = %s\n", user_password);
        dbg("data = %s\n", data);
@@ -248,12 +403,13 @@ static int send_tweet(struct session *session)
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, curl_buf);
        res = curl_easy_perform(curl);
        if (res && !session->bash) {
-               fprintf(stderr, "error(%d) trying to send tweet\n", res);
+               fprintf(stderr, "error(%d) trying to perform operation\n", res);
                return -EINVAL;
        }
 
        curl_easy_cleanup(curl);
-       curl_formfree(formpost);
+       if (session->action == ACTION_UPDATE)
+               curl_formfree(formpost);
        bti_curl_buffer_free(curl_buf);
        return 0;
 }
@@ -268,6 +424,8 @@ static void parse_configfile(struct session *session)
        char *host = NULL;
        char *proxy = NULL;
        char *logfile = NULL;
+       char *action = NULL;
+       char *user = NULL;
        char *file;
 
        /* config file is ~/.bti  */
@@ -324,6 +482,16 @@ static void parse_configfile(struct session *session)
                        c += 8;
                        if (c[0] != '\0')
                                logfile = strdup(c);
+               } else if (!strncasecmp(c, "action", 6) &&
+                          (c[6] == '=')) {
+                       c += 7;
+                       if (c[0] != '\0')
+                               action = strdup(c);
+               } else if (!strncasecmp(c, "user", 4) &&
+                               (c[4] == '=')) {
+                       c += 5;
+                       if (c[0] != '\0')
+                               user = strdup(c);
                }
        } while (!feof(config_file));
 
@@ -345,6 +513,24 @@ static void parse_configfile(struct session *session)
        }
        if (logfile)
                session->logfile = logfile;
+       if (action) {
+               if (strcasecmp(action, "update") == 0)
+                       session->action = ACTION_UPDATE;
+               else if (strcasecmp(action, "friends") == 0)
+                       session->action = ACTION_FRIENDS;
+               else if (strcasecmp(action, "user") == 0)
+                       session->action = ACTION_USER;
+               else if (strcasecmp(action, "replies") == 0)
+                       session->action = ACTION_REPLIES;
+               else if (strcasecmp(action, "public") == 0)
+                       session->action = ACTION_PUBLIC;
+               else
+                       session->action = ACTION_UNKNOWN;
+               free(action);
+       }
+       if (user) {
+               session->user = user;
+       }
 
        /* Free buffer and close file.  */
        free(line);
@@ -381,16 +567,54 @@ static void log_session(struct session *session, int retval)
                break;
        }
 
-       if (retval)
-               fprintf(log_file, "%s: host=%s tweet failed\n",
+       switch (session->action) {
+       case ACTION_UPDATE:
+               if (retval)
+                       fprintf(log_file, "%s: host=%s tweet failed\n",
+                               session->time, host);
+               else
+                       fprintf(log_file, "%s: host=%s tweet=%s\n",
+                               session->time, host, session->tweet);
+               break;
+       case ACTION_FRIENDS:
+               fprintf(log_file, "%s: host=%s retrieving friends timeline\n",
+                       session->time, host);
+               break;
+       case ACTION_USER:
+               fprintf(log_file, "%s: host=%s retrieving %s's timeline\n",
+                       session->time, host, session->user);
+               break;
+       case ACTION_REPLIES:
+               fprintf(log_file, "%s: host=%s retrieving replies\n",
+                       session->time, host);
+               break;
+       case ACTION_PUBLIC:
+               fprintf(log_file, "%s: host=%s retrieving public timeline\n",
                        session->time, host);
-       else
-               fprintf(log_file, "%s: host=%s tweet=%s\n",
-                       session->time, host, session->tweet);
+               break;
+       default:
+               break;
+       }
 
        fclose(log_file);
 }
 
+static char *get_string_from_stdin(void)
+{
+       char *temp;
+       char *string;
+
+       string = zalloc(1000);
+       if (!string)
+               return NULL;
+
+       if (!fgets(string, 999, stdin))
+               return NULL;
+       temp = strchr(string, '\n');
+       *temp = '\0';
+       return string;
+}
+
 int main(int argc, char *argv[], char *envp[])
 {
        static const struct option options[] = {
@@ -399,6 +623,8 @@ int main(int argc, char *argv[], char *envp[])
                { "password", 1, NULL, 'p' },
                { "host", 1, NULL, 'H' },
                { "proxy", 1, NULL, 'P' },
+               { "action", 1, NULL, 'A' },
+               { "user", 1, NULL, 'u' },
                { "logfile", 1, NULL, 'L' },
                { "help", 0, NULL, 'h' },
                { "bash", 0, NULL, 'b' },
@@ -444,7 +670,7 @@ int main(int argc, char *argv[], char *envp[])
        parse_configfile(session);
 
        while (1) {
-               option = getopt_long_only(argc, argv, "dqe:p:P:H:a:h",
+               option = getopt_long_only(argc, argv, "dqe:p:P:H:a:A:u:h",
                                          options, NULL);
                if (option == -1)
                        break;
@@ -470,6 +696,27 @@ int main(int argc, char *argv[], char *envp[])
                        session->proxy = strdup(optarg);
                        dbg("proxy = %s\n", session->proxy);
                        break;
+               case 'A':
+                       if (strcasecmp(optarg, "update") == 0)
+                               session->action = ACTION_UPDATE;
+                       else if (strcasecmp(optarg, "friends") == 0)
+                               session->action = ACTION_FRIENDS;
+                       else if (strcasecmp(optarg, "user") == 0)
+                               session->action = ACTION_USER;
+                       else if (strcasecmp(optarg, "replies") == 0)
+                               session->action = ACTION_REPLIES;
+                       else if (strcasecmp(optarg, "public") == 0)
+                               session->action = ACTION_PUBLIC;
+                       else
+                               session->action = ACTION_UNKNOWN;
+                       dbg("action = %d\n", session->action);
+                       break;
+               case 'u':
+                       if (session->user)
+                               free(session->user);
+                       session->user = strdup(optarg);
+                       dbg("user = %s\n", session->user);
+                       break;
                case 'L':
                        if (session->logfile)
                                free(session->logfile);
@@ -498,6 +745,12 @@ int main(int argc, char *argv[], char *envp[])
                }
        }
 
+       if (session->action == ACTION_UNKNOWN) {
+               fprintf(stderr, "Unknown action, valid actions are:\n");
+               fprintf(stderr, "'update', 'friends', 'public', 'replies' or 'user'.\n");
+               goto exit;
+       }
+
        if (!session->account) {
                fprintf(stdout, "Enter twitter account: ");
                session->account = readline(NULL);
@@ -508,44 +761,48 @@ int main(int argc, char *argv[], char *envp[])
                session->password = readline(NULL);
        }
 
-       if (session->bash)
-               tweet = readline(NULL);
-       else
-               tweet = readline("tweet: ");
-       if (!tweet || strlen(tweet) == 0) {
-               dbg("no tweet?\n");
-               return -1;
-       }
+       if (session->action == ACTION_UPDATE) {
+               if (session->bash)
+                       tweet = get_string_from_stdin();
+               else
+                       tweet = readline("tweet: ");
+               if (!tweet || strlen(tweet) == 0) {
+                       dbg("no tweet?\n");
+                       return -1;
+               }
 
-       session->tweet = zalloc(strlen(tweet) + 10);
+               session->tweet = zalloc(strlen(tweet) + 10);
+               if (session->bash)
+                       sprintf(session->tweet, "$ %s", tweet);
+               else
+                       sprintf(session->tweet, "%s", tweet);
+
+               free(tweet);
+               dbg("tweet = %s\n", session->tweet);
+       }
 
-       /* if --bash is specified, add the "PWD $ " to
-        * the start of the tweet. */
-       if (session->bash)
-               sprintf(session->tweet, "$ %s", tweet);
-       else
-               sprintf(session->tweet, "%s", tweet);
-       free(tweet);
+       if (!session->user)
+               session->user = strdup(session->account);
 
        dbg("account = %s\n", session->account);
        dbg("password = %s\n", session->password);
-       dbg("tweet = %s\n", session->tweet);
        dbg("host = %d\n", session->host);
+       dbg("action = %d\n", session->action);
 
        /* fork ourself so that the main shell can get on
         * with it's life as we try to connect and handle everything
         */
        if (session->bash) {
                child = fork();
-                       if (child) {
+               if (child) {
                        dbg("child is %d\n", child);
                        exit(0);
                }
        }
 
-       retval = send_tweet(session);
+       retval = send_request(session);
        if (retval && !session->bash)
-               fprintf(stderr, "tweet failed\n");
+               fprintf(stderr, "operation failed\n");
 
        log_session(session, retval);
 exit:
index bc97329..e4bbad8 100644 (file)
@@ -7,4 +7,6 @@ account=twitmaster
 password=icanhascheezburger
 host=identica
 logfile=.bti.log
+#action=update
+#user=gregkh
 #proxy=http://localhost:8080
diff --git a/bti.xml b/bti.xml
index 1b20586..d103228 100644 (file)
--- a/bti.xml
+++ b/bti.xml
@@ -28,6 +28,8 @@
           <command>bti</command>
           <arg><option>--account account</option></arg>
           <arg><option>--password password</option></arg>
+          <arg><option>--action action</option></arg>
+          <arg><option>--user screenname</option></arg>
           <arg><option>--host HOST_NAME</option></arg>
           <arg><option>--proxy PROXY:PORT</option></arg>
           <arg><option>--logfile LOGFILE</option></arg>
               </para>
             </listitem>
           </varlistentry>
+          <varlistentry>
+            <term><option>--action action</option></term>
+            <listitem>
+              <para>
+               Specify the action which you want to perform.  Valid options
+               are "update" to send a message, "friends" to see your friends
+               timeline, "public" to track public timeline, "replies" to see
+               replies to your messages and "user" to see a specific user's
+               timeline.
+              </para>
+            </listitem>
+          </varlistentry>
+         <varlistentry>
+            <term><option>--user screenname</option></term>
+            <listitem>
+              <para>
+               Specify the user you want to see his/her messages while the
+               action is "user".
+              </para>
+            </listitem>
+          </varlistentry>
           <varlistentry>
             <term><option>--host HOST_NAME</option></term>
             <listitem>
                </para>
              </listitem>
            </varlistentry>
+          <varlistentry>
+            <term><option>--action action</option></term>
+            <listitem>
+              <para>
+               Specify the action which you want to perform.  Valid options
+               are "update" to send a message, "friends" to see your friends
+               timeline, "public" to track public timeline, "replies" to see
+               replies to your messages and "user" to see a specific user's
+               timeline.
+              </para>
+            </listitem>
+           </varlistentry>
+          <varlistentry>
+            <term><option>--user screenname</option></term>
+            <listitem>
+              <para>
+               Specify the user you want to see his/her messages while the
+               action is "user".
+              </para>
+            </listitem>
+           </varlistentry>
            <varlistentry>
              <term><option>host</option></term>
              <listitem>
index 1992923..fd4b0bb 100644 (file)
@@ -1,3 +1,11 @@
+bti (015-1) UNRELEASED; urgency=low
+
+  * New upstream release; from the RELEASE-NOTES:
+    "--action support, bti now can output data from the twitter
+    and identica servers".
+
+ -- gregor herrmann <gregoa@debian.org>  Thu, 12 Mar 2009 16:50:10 +0100
+
 bti (014-1) unstable; urgency=low
 
   * New upstream release.