commit 6893cd3119ad2e73a79c3b0a0f1c279d05896223
parent 22af8f5c3a9f79f28cf2c56d9b244804a70ddcc7
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Sun, 14 Apr 2019 15:04:47 +0200
sfeed: add support for the first enclosure of an item
This is useful for example for podcasts (audio attachment), newsposts (usually
some image) or comic strips (link to page, image as enclosure).
thanks leot for the feedback!
Diffstat:
4 files changed, 25 insertions(+), 8 deletions(-)
diff --git a/sfeed.1 b/sfeed.1
@@ -1,4 +1,4 @@
-.Dd December 25, 2014
+.Dd April 14, 2019
.Dt SFEED 1
.Os
.Sh NAME
@@ -44,6 +44,8 @@ Content, can have plain-text or HTML code depending on the content-type field.
RSS item GUID or Atom id.
.It author
Item author.
+.It enclosure
+Item, first enclosure.
.El
.Sh SEE ALSO
.Xr sfeed_plain 1 ,
diff --git a/sfeed.5 b/sfeed.5
@@ -1,4 +1,4 @@
-.Dd April 10, 2016
+.Dd April 14, 2019
.Dt SFEED 5
.Os
.Sh NAME
@@ -39,6 +39,8 @@ Content, can have plain-text or HTML code depending on the content-type field.
RSS item GUID or Atom id.
.It author
Item author.
+.It enclosure
+Item, first enclosure.
.El
.Sh SEE ALSO
.Xr sfeed 1 ,
diff --git a/sfeed.c b/sfeed.c
@@ -48,6 +48,7 @@ enum TagId {
RSSTagGuid,
/* must be defined after GUID, because it can be a link (isPermaLink) */
RSSTagLink,
+ RSSTagEnclosure,
RSSTagAuthor, RSSTagDccreator,
/* Atom */
AtomTagUpdated, AtomTagPublished,
@@ -56,6 +57,7 @@ enum TagId {
AtomTagId,
AtomTagLink,
AtomTagLinkAlternate,
+ AtomTagLinkEnclosure,
AtomTagAuthor,
TagLast
};
@@ -73,7 +75,7 @@ typedef struct field {
enum {
FeedFieldTime = 0, FeedFieldTitle, FeedFieldLink, FeedFieldContent,
- FeedFieldId, FeedFieldAuthor, FeedFieldLast
+ FeedFieldId, FeedFieldAuthor, FeedFieldEnclosure, FeedFieldLast
};
typedef struct feedcontext {
@@ -122,6 +124,8 @@ static FeedTag rsstags[] = {
{ STRP("dc:creator"), RSSTagDccreator },
{ STRP("dc:date"), RSSTagDcdate },
{ STRP("description"), RSSTagDescription },
+ /* RSS: <enclosure url="" />, Atom has <link rel="enclosure" /> */
+ { STRP("enclosure"), RSSTagEnclosure },
{ STRP("guid"), RSSTagGuid },
{ STRP("link"), RSSTagLink },
{ STRP("media:description"), RSSTagMediaDescription },
@@ -156,6 +160,7 @@ static int fieldmap[TagLast] = {
[RSSTagContentEncoded] = FeedFieldContent,
[RSSTagGuid] = FeedFieldId,
[RSSTagLink] = FeedFieldLink,
+ [RSSTagEnclosure] = FeedFieldEnclosure,
[RSSTagAuthor] = FeedFieldAuthor,
[RSSTagDccreator] = FeedFieldAuthor,
/* Atom */
@@ -168,6 +173,7 @@ static int fieldmap[TagLast] = {
[AtomTagId] = FeedFieldId,
[AtomTagLink] = -1,
[AtomTagLinkAlternate] = FeedFieldLink,
+ [AtomTagLinkEnclosure] = FeedFieldEnclosure,
[AtomTagAuthor] = FeedFieldAuthor
};
@@ -593,6 +599,8 @@ printfields(void)
string_print_trimmed(&ctx.fields[FeedFieldId].str);
putchar(FieldSeparator);
string_print_trimmed(&ctx.fields[FeedFieldAuthor].str);
+ putchar(FieldSeparator);
+ string_print_uri(&ctx.fields[FeedFieldEnclosure].str);
putchar('\n');
}
@@ -620,10 +628,13 @@ xmlattr(XMLParser *p, const char *t, size_t tl, const char *n, size_t nl,
}
if (ctx.feedtype == FeedTypeRSS) {
- if (ctx.tagid == RSSTagGuid) {
- if (isattr(n, nl, STRP("ispermalink")) &&
- !isattr(v, vl, STRP("true")))
- rssidpermalink = 0;
+ if (ctx.tagid == RSSTagEnclosure &&
+ isattr(n, nl, STRP("url")) && ctx.field) {
+ string_append(ctx.field, v, vl);
+ } else if (ctx.tagid == RSSTagGuid &&
+ isattr(n, nl, STRP("ispermalink")) &&
+ !isattr(v, vl, STRP("true"))) {
+ rssidpermalink = 0;
}
} else if (ctx.feedtype == FeedTypeAtom) {
if (ISCONTENTTAG(ctx)) {
@@ -641,6 +652,8 @@ xmlattr(XMLParser *p, const char *t, size_t tl, const char *n, size_t nl,
"enclosure", "related", "self" or "via" */
if (!vl || isattr(v, vl, STRP("alternate")))
atomlinktype = AtomTagLinkAlternate;
+ else if (isattr(v, vl, STRP("enclosure")))
+ atomlinktype = AtomTagLinkEnclosure;
else
atomlinktype = TagUnknown;
} else if (ctx.tagid == AtomTagLink &&
diff --git a/util.h b/util.h
@@ -31,7 +31,7 @@ struct uri {
enum {
FieldUnixTimestamp = 0, FieldTitle, FieldLink, FieldContent,
- FieldContentType, FieldId, FieldAuthor, FieldLast
+ FieldContentType, FieldId, FieldAuthor, FieldEnclosure, FieldLast
};
int absuri(char *, size_t, const char *, const char *);