Skip to content

btpd raw list/stats #8

Closed
queueRAM opened this Issue Jul 22, 2010 · 2 comments

1 participant

@queueRAM

Original Request

Fri, Feb 12, 2010 at 16:26

I've been fiddling with sort of a front-end to btcli for which I needed a bit more detail than I could get out of btcli's list or stat commands. Anyway, to make a long story short, I added some code to btcli to dump torrent data/stats in a format suitable for machine parsing. I implemented it as 'raw' list mode. It looks like this:

lithium:~ > btcli list -r

HASH[8]: b148c4beff54ae919bd5ac947e86395e7e39c532
NAME[8]: my_test_torrent2
DIR[8]: /data/user/cedric/inbox/bt/active/my_test_torrent2
STATE[8]: I
PEERS[8]: 0
BYTES_TOTAL[8]: 6026993900
BYTES_HAVE[8]: 0
BYTES_SENT[8]: 0
BYTES_DOWNLOADED[8]: 0
BYTES_UPLOADED[8]: 0
BPS_DOWN[8]: 0
BPS_UP[8]: 0
PIECES_TOTAL[8]: 12
PIECES_AVAIL[8]: 0
PIECES_HAVE[8]: 12

HASH[3]: ad164a08b74eb04cf5491a7c04f624bca6d8a3e3
NAME[3]: my_test_torrent_with_a_name_longer_than_40_characters
DIR[3]: /data/user/cedric/inbox/bt/active/my_test_torrent_with_a_name_longer_than_40_characters
STATE[3]: L
PEERS[3]: 23
BYTES_TOTAL[3]: 11559003430
BYTES_HAVE[3]: 2230887718
BYTES_SENT[3]: 2294546207
BYTES_DOWNLOADED[3]: 2236132081
BYTES_UPLOADED[3]: 2294546207
BPS_DOWN[3]: 0
BPS_UP[3]: 0
PIECES_TOTAL[3]: 2756
PIECES_AVAIL[3]: 534
PIECES_HAVE[3]: 532

I'm including my working version of the patch. It's not clean enough to be incorporated as-is, but it should give you the basic idea.

-Cedric

Patch

--- git/btpd/cli/list.c 2010-02-07 16:14:28.547914592 -0700
+++ work/cli/list.c 2010-02-08 00:42:35.851676000 -0700
@@ -6,7 +6,7 @@
     printf(
         "List torrents.\n"
         "\n"
-        "Usage: list [-a] [-i]\n"
+        "Usage: list [-a] [-i] [-r]\n"
         "       list torrent ...\n"
         "\n"
         "Arguments:\n"
@@ -21,15 +21,20 @@
         "-i\n"
         "\tList inactive torrents.\n"
         "\n"
+        "-r"
+        "\tDisplay raw data; suitable for machine parsing.\n\n"
         );
     exit(1);
 }
 
 struct item {
-    unsigned num;
-    char *name;
+    unsigned num, peers;
+    char *name, *dir;
+    char hash[SHAHEXSIZE];
     char st;
-    long long cgot, csize, totup;
+    long long content_got, content_size, tot_up, downloaded, uploaded,
+         rate_up, rate_down;
+    uint32_t torrent_pieces, pieces_have, pieces_seen;
     BTPDQ_ENTRY(item) entry;
 };
 
@@ -70,9 +75,23 @@
     else
         asprintf(&itm->name, "%.*s", (int)res[IPC_TVAL_NAME].v.str.l,
             res[IPC_TVAL_NAME].v.str.p);
-    itm->totup = res[IPC_TVAL_TOTUP].v.num;
-    itm->cgot = res[IPC_TVAL_CGOT].v.num;
-    itm->csize = res[IPC_TVAL_CSIZE].v.num;
+    if (res[IPC_TVAL_DIR].type == IPC_TYPE_ERR)
+        asprintf(&itm->dir, "%s", ipc_strerror(res[IPC_TVAL_DIR].v.num));
+    else
+        asprintf(&itm->dir, "%.*s", (int)res[IPC_TVAL_DIR].v.str.l,
+            res[IPC_TVAL_DIR].v.str.p);
+    bin2hex(res[IPC_TVAL_IHASH].v.str.p, itm->hash, 20);
+    itm->tot_up = res[IPC_TVAL_TOTUP].v.num;
+    itm->content_got = res[IPC_TVAL_CGOT].v.num;
+    itm->content_size = res[IPC_TVAL_CSIZE].v.num;
+    itm->downloaded = res[IPC_TVAL_SESSDWN].v.num;
+    itm->uploaded = res[IPC_TVAL_SESSUP].v.num;
+    itm->rate_down = res[IPC_TVAL_RATEDWN].v.num;
+    itm->rate_up = res[IPC_TVAL_RATEUP].v.num;
+    itm->torrent_pieces = res[IPC_TVAL_PCCOUNT].v.num;
+    itm->pieces_seen = res[IPC_TVAL_PCSEEN].v.num;
+    itm->pieces_have = res[IPC_TVAL_PCGOT].v.num;
+    itm->peers = res[IPC_TVAL_PCOUNT].v.num;
     itm_insert(itms, itm);
 }
 
@@ -82,9 +101,35 @@
     struct item *p;
     BTPDQ_FOREACH(p, &itms->hd, entry) {
         printf("%-40.40s %4u %c. ", p->name, p->num, p->st);
-        print_percent(p->cgot, p->csize);
-        print_size(p->csize);
-        print_ratio(p->totup, p->csize);
+        print_percent(p->content_got, p->content_size);
+        print_size(p->content_size);
+        print_ratio(p->tot_up, p->content_size);
+        printf("\n");
+    }
+}
+
+void
+print_items_raw(struct items* itms)
+{
+    struct item *p;
+    BTPDQ_FOREACH(p, &itms->hd, entry) {
+        printf("HASH[%u]: %20s\n", p->num, p->hash);
+        printf("NAME[%u]: %s\n", p->num, p->name);
+        printf("DIR[%u]: %s\n", p->num, p->dir);
+        printf("STATE[%u]: %c\n", p->num, p->st);
+        printf("PEERS[%u]: %u\n", p->num, p->peers);
+        printf("BYTES_TOTAL[%u]: %lld\n", p->num, p->content_size);
+        printf("BYTES_HAVE[%u]: %lld\n", p->num, p->content_got);
+        printf("BYTES_SENT[%u]: %lld\n",p->num, p->tot_up);
+        printf("BYTES_DOWNLOADED[%u]: %lld\n",p->num, p->downloaded);
+        printf("BYTES_UPLOADED[%u]: %lld\n",p->num, p->uploaded);
+        printf("BPS_DOWN[%u]: %lld\n",p->num, p->rate_down);
+        printf("BPS_UP[%u]: %lld\n",p->num, p->rate_up);
+        printf("PIECES_TOTAL[%u]: %u\n",p->num, p->torrent_pieces);
+        printf("PIECES_AVAIL[%u]: %u\n",p->num, p->pieces_seen);
+        printf("PIECES_HAVE[%u]: %u\n",p->num, p->pieces_have);
+//        printf("TR_GOOD[%u]: %u\n",p->num, p->tr_good);
+
         printf("\n");
     }
 }
@@ -97,14 +142,17 @@
 void
 cmd_list(int argc, char **argv)
 {
-    int ch, inactive = 0, active = 0;
+    int ch, inactive = 0, active = 0, rawformat = 0;
     enum ipc_err code;
     enum ipc_twc twc;
     enum ipc_tval keys[] = { IPC_TVAL_NUM, IPC_TVAL_STATE, IPC_TVAL_NAME,
-       IPC_TVAL_TOTUP, IPC_TVAL_CSIZE, IPC_TVAL_CGOT };
+       IPC_TVAL_TOTUP, IPC_TVAL_CSIZE, IPC_TVAL_CGOT, IPC_TVAL_PCOUNT,
+       IPC_TVAL_PCCOUNT, IPC_TVAL_PCSEEN, IPC_TVAL_PCGOT, IPC_TVAL_SESSUP,
+       IPC_TVAL_SESSDWN, IPC_TVAL_RATEUP, IPC_TVAL_RATEDWN, IPC_TVAL_IHASH,
+       IPC_TVAL_DIR };
     size_t nkeys = sizeof(keys) / sizeof(keys[0]);
     struct items itms;
-    while ((ch = getopt_long(argc, argv, "ai", list_opts, NULL)) != -1) {
+    while ((ch = getopt_long(argc, argv, "air", list_opts, NULL)) != -1) {
         switch (ch) {
         case 'a':
             active = 1;
@@ -112,6 +160,9 @@
         case 'i':
             inactive = 1;
             break;
+        case 'r':
+            rawformat = 1;
+            break;
         default:
             usage_list();
         }
@@ -120,7 +171,7 @@
     argv += optind;
 
     if (argc > 0) {
-        if (inactive || active)
+        if (inactive || active || rawformat)
             usage_list();
         itms.tps = malloc(argc * sizeof(*itms.tps));
         for (itms.ntps = 0; itms.ntps < argc; itms.ntps++) {
@@ -149,6 +200,11 @@
         code = btpd_tget(ipc, itms.tps, itms.ntps, keys, nkeys, list_cb, &itms);
     if (code != IPC_OK)
         diemsg("command failed (%s).\n", ipc_strerror(code));
-    printf("%-40.40s  NUM ST   HAVE    SIZE   RATIO\n", "NAME");
-    print_items(&itms);
+
+    if(rawformat) 
+   print_items_raw(&itms);
+    else {
+        printf("%-40.40s  NUM ST   HAVE    SIZE   RATIO\n", "NAME");
+   print_items(&itms);
+    }
 }

References

http://lists.stargirl.org/pipermail/btpd-users/2010-February/000581.html

@queueRAM

nicm July 14, 2010:

I like this and it looks good. I would omit the []s from the output and just show eg "HASH0:", []s make things more annoying to parse. Also I would use = instead of ": " so at least some of the output can be passed directly to the shell. This is just bikeshedding however.

@queueRAM

Added custom formats for list operation.

Added printf()-style '%' and '\' sequences for custom list formats.
Updated btcli manpage to reflect change and start -a.

Closed by 76c4947

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.