mark as read: use the ID if the link is empty - sfeed_curses - sfeed curses UI (now part of sfeed, development is in sfeed)
 (HTM) git clone git://git.codemadness.org/sfeed_curses
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 015b434b8f0345665a9b6920f6dbbd361518904a
 (DIR) parent 95ef55218f09c78d2470581ec5640e5f05bca7b4
 (HTM) Author: Hiltjo Posthuma <hiltjo@codemadness.org>
       Date:   Sat, 20 Feb 2021 20:05:58 +0100
       
       mark as read: use the ID if the link is empty
       
       This allows to mark only textual content (without a link) as read/unread.
       
       The link is optional as specified in the Atom RFC 4287. The ID is mandatory.
       
       * the id element conveys a permanent, universally unique identifier for an
         entry or feed.
       * atom:feed elements MUST contain exactly one atom:id element.
       * atom:feed elements SHOULD contain one atom:link element.
       
       Document the "mark as read" behaviour in a bit more detail too.
       
       Suggested by feedback from Hadrien Lacour, thanks!
       
       Diffstat:
         M sfeed_curses.1                      |       8 +++++---
         M sfeed_curses.c                      |      15 ++++++++-------
       
       2 files changed, 13 insertions(+), 10 deletions(-)
       ---
 (DIR) diff --git a/sfeed_curses.1 b/sfeed_curses.1
       @@ -1,4 +1,4 @@
       -.Dd December 18, 2020
       +.Dd February 20, 2021
        .Dt SFEED_CURSES 1
        .Os
        .Sh NAME
       @@ -200,14 +200,16 @@ This URL is matched on the link field as specified in
        A program to mark items as read if
        .Ev SFEED_URL_FILE
        is also set, if unset the default program used is "sfeed_markread read".
       -The marked items are piped to the program.
       +The marked items are piped to the program line by line.
       +If the feed item has a link then this line is the link, otherwise it is the ID.
        The program is expected to merge items in a safe/transactional manner.
        The program should return the exit status 0 on success or non-zero on failure.
        .It Ev SFEED_MARK_UNREAD
        A program to mark items as unread if
        .Ev SFEED_URL_FILE
        is also set, if unset the default program used is "sfeed_markread unread".
       -The marked items are piped to the program.
       +The unmarked items are piped to the program line by line.
       +If the feed item has a link then this line is the link, otherwise it is the ID.
        The program is expected to merge items in a safe/transactional manner.
        The program should return the exit status 0 on success or non-zero on failure.
        .It Ev SFEED_LAZYLOAD
 (DIR) diff --git a/sfeed_curses.c b/sfeed_curses.c
       @@ -113,9 +113,10 @@ struct statusbar {
        /* /UI */
        
        struct item {
       -        char *link; /* separate link field (always loaded in case of urlfile) */
                char *fields[FieldLast];
                char *line; /* allocated split line */
       +        /* field to match new items, if link is set match on link, else on id */
       +        char *matchnew;
                time_t timestamp;
                int timeok;
                int isnew;
       @@ -1118,9 +1119,9 @@ linetoitem(char *line, struct item *item)
                parseline(line, fields);
                memcpy(item->fields, fields, sizeof(fields));
                if (urlfile)
       -                item->link = estrdup(fields[FieldLink]);
       +                item->matchnew = estrdup(fields[fields[FieldLink][0] ? FieldLink : FieldId]);
                else
       -                item->link = NULL;
       +                item->matchnew = NULL;
        
                parsedtime = 0;
                if (!strtotime(fields[FieldUnixTimestamp], &parsedtime)) {
       @@ -1141,7 +1142,7 @@ feed_items_free(struct items *items)
        
                for (i = 0; i < items->len; i++) {
                        free(items->items[i].line);
       -                free(items->items[i].link);
       +                free(items->items[i].matchnew);
                }
                free(items->items);
                items->items = NULL;
       @@ -1220,7 +1221,7 @@ updatenewitems(struct feed *f)
                        row = &(p->rows[i]); /* do not use pane_row_get */
                        item = (struct item *)row->data;
                        if (urlfile)
       -                        item->isnew = urls_isnew(item->link);
       +                        item->isnew = urls_isnew(item->matchnew);
                        else
                                item->isnew = (item->timeok && item->timestamp >= comparetime);
                        row->bold = item->isnew;
       @@ -1269,7 +1270,7 @@ feed_count(struct feed *f, FILE *fp)
                        parseline(line, fields);
        
                        if (urlfile) {
       -                        f->totalnew += urls_isnew(fields[FieldLink]);
       +                        f->totalnew += urls_isnew(fields[fields[FieldLink][0] ? FieldLink : FieldId]);
                        } else {
                                parsedtime = 0;
                                if (!strtotime(fields[FieldUnixTimestamp], &parsedtime))
       @@ -1695,7 +1696,7 @@ markread(struct pane *p, off_t from, off_t to, int isread)
                                row = &(p->rows[i]); /* use pane_row_get: no need for lazyload */
                                item = (struct item *)row->data;
                                if (item->isnew != isnew) {
       -                                fputs(item->link, fp);
       +                                fputs(item->matchnew, fp);
                                        putc('\n', fp);
                                }
                        }