Skip to content

Commit cbe05fa

Browse files
committed
~ adding support for more rss feed
1 parent 550a570 commit cbe05fa

File tree

6 files changed

+47
-30
lines changed

6 files changed

+47
-30
lines changed

manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"id": "rss-reader",
33
"name": "RSS Reader",
4-
"version": "1.0.1",
4+
"version": "1.0.2",
55
"minAppVersion": "0.12.17",
66
"description": "Read RSS Feeds from within obsidian",
77
"author": "Johannes Theiner",

package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "rss-reader",
3-
"version": "1.0.1",
3+
"version": "1.0.2",
44
"description": "Read RSS Feeds from inside obsidian",
55
"main": "main.js",
66
"scripts": {
@@ -46,7 +46,6 @@
4646
"svelte-preprocess": "^4.9.8",
4747
"ts-md5": "^1.2.10",
4848
"ts-node": "^10.4.0",
49-
"tslib": "^2.2.0",
5049
"tslint": "^6.1.3",
5150
"typescript": "^4.2.4"
5251
}

src/parser/rssParser.ts

Lines changed: 38 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ import {Md5} from "ts-md5";
44

55
/**
66
* parser for .rss files, build from scratch
7-
* because I could not find a parser that works on mobile and is up to date.
7+
* because I could not find a parser that
8+
* - works on mobile
9+
* - is up-to-date
10+
* - works for multiple different interpretations of the rss spec
811
*/
912

1013
export interface RssFeedContent {
@@ -44,58 +47,72 @@ export interface RssFeedItem {
4447
}
4548

4649
/**
50+
* return the node with the specified name
4751
* : to get namespaced element
4852
* . to get nested element
4953
* @param element
5054
* @param name
5155
*/
5256
function getElementByName(element: Element | Document, name: string): ChildNode {
5357
let value: ChildNode;
54-
if (typeof element.getElementsByTagName !== 'function') {
58+
if (typeof element.getElementsByTagName !== 'function' && typeof element.getElementsByTagNameNS !== 'function') {
59+
//the required methods do not exist on element, aborting
5560
return;
5661
}
5762

5863
if (name.contains(":")) {
5964
const [namespace, tag] = name.split(":");
6065
const namespaceUri = element.lookupNamespaceURI(namespace);
61-
if (element.getElementsByTagNameNS(namespaceUri, tag).length > 0) {
62-
value = element.getElementsByTagNameNS(namespaceUri, tag)[0].childNodes[0];
66+
const byNamespace = element.getElementsByTagNameNS(namespaceUri, tag);
67+
if (byNamespace.length > 0) {
68+
value = byNamespace[0].childNodes[0];
69+
} else {
70+
//there is no element in that namespace, probably because no namespace has been defined
71+
const tmp = element.getElementsByTagName(name);
72+
if (tmp.length > 0) {
73+
if (tmp[0].childNodes.length === 0) {
74+
value = tmp[0];
75+
} else {
76+
const node = tmp[0].childNodes[0];
77+
if (node !== undefined) {
78+
value = node;
79+
}
80+
}
81+
}
6382
}
6483

6584
} else if (name.contains(".")) {
6685
const [prefix, tag] = name.split(".");
6786
if (element.getElementsByTagName(prefix).length > 0) {
6887
const nodes = Array.from(element.getElementsByTagName(prefix)[0].childNodes);
69-
7088
nodes.forEach((node) => {
7189
if (node.nodeName == tag) {
7290
value = node;
7391
}
7492
});
7593
}
7694

77-
} else {
78-
if (element.getElementsByTagName(name).length > 0) {
79-
if (element.getElementsByTagName(name)[0].childNodes.length == 0) {
80-
value = element.getElementsByTagName(name)[0];
81-
} else {
82-
const node = element.getElementsByTagName(name)[0].childNodes[0];
83-
if (node !== undefined)
84-
value = node;
85-
}
95+
} else if (element.getElementsByTagName(name).length > 0) {
96+
if (element.getElementsByTagName(name)[0].childNodes.length == 0) {
97+
value = element.getElementsByTagName(name)[0];
98+
} else {
99+
const node = element.getElementsByTagName(name)[0].childNodes[0];
100+
if (node !== undefined)
101+
value = node;
86102
}
87103
}
88104
return value;
89105
}
90106

91107
/**
92108
* # to get attribute
109+
* Always returns the last found value for names
93110
* @param element
94111
* @param names possible names
95112
*/
96113
function getContent(element: Element | Document, names: string[]): string {
97114
let value: string;
98-
names.forEach((name) => {
115+
for (let name of names) {
99116
if (name.contains("#")) {
100117
const [elementName, attr] = name.split("#");
101118
const data = getElementByName(element, elementName);
@@ -108,21 +125,21 @@ function getContent(element: Element | Document, names: string[]): string {
108125
}
109126
}
110127
}
111-
}else {
128+
} else {
112129
const data = getElementByName(element, name);
113130
if (data) {
114131
//@ts-ignore
115132
if (data.nodeValue && data.nodeValue.length > 0) {
116133
value = data.nodeValue;
117134
}
118135
//@ts-ignore
119-
if (data.innerHTML && data.innerHTML.length > 0) {
136+
else if (data.innerHTML && data.innerHTML.length > 0) {
120137
//@ts-ignore
121138
value = data.innerHTML;
122139
}
123140
}
124141
}
125-
});
142+
}
126143
if (value === undefined) {
127144
return "";
128145
}
@@ -133,7 +150,7 @@ function buildItem(element: Element): RssFeedItem {
133150
return {
134151
title: getContent(element, ["title"]),
135152
description: getContent(element, ["content", "content:encoded", "itunes:summary", "description", "summary", "media:description"]),
136-
content: getContent(element, ["itunes:summary", "description", "summary", "media:description", "content", "content:encoded"]),
153+
content: getContent(element, ["itunes:summary", "description", "summary", "media:description", "content", "content:encoded", "ns0:encoded"]),
137154
category: getContent(element, ["category"]),
138155
link: getContent(element, ["link", "link#href"]),
139156
creator: getContent(element, ["creator", "dc:creator", "author", "author.name"]),
@@ -178,7 +195,7 @@ export async function getFeedItems(feed: RssFeed): Promise<RssFeedContent> {
178195
try {
179196
const rawData = await request({url: feed.url});
180197
data = new window.DOMParser().parseFromString(rawData, "text/xml");
181-
}catch (e) {
198+
} catch (e) {
182199
console.error(e);
183200
return Promise.resolve(undefined);
184201
}
@@ -200,14 +217,13 @@ export async function getFeedItems(feed: RssFeed): Promise<RssFeedContent> {
200217
item.language = language;
201218
item.hash = <string>new Md5().appendStr(item.title).appendStr(item.folder).appendStr(item.link).end();
202219

203-
if(!item.image && feed.url.contains("youtube.com/feeds")) {
220+
if (!item.image && feed.url.contains("youtube.com/feeds")) {
204221
item.image = "https://i3.ytimg.com/vi/" + item.id.split(":")[2] + "/hqdefault.jpg";
205222
}
206223

207224
items.push(item);
208225
}
209226
})
210-
211227
const image = getContent(data, ["image", "image.url", "icon"]);
212228

213229
const content: RssFeedContent = {

src/view/ItemView.svelte

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,14 +55,13 @@
5555
{/if}
5656
</span>
5757

58-
5958
<div class="rss-card-items">
60-
<div class="rss-item">
59+
<div class="rss-item-image">
6160
{#if item.image && !item.image.includes(".mp3")}
6261
<img src={item.image} width="250em" alt="Article">
6362
{/if}
6463
</div>
65-
<div class="rss-item">
64+
<div class="rss-item-text">
6665
{#if item.description}
6766
<MarkdownContent content={item.description}/>
6867
{/if}

styles.css

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,11 @@ input.is-invalid {
9595
padding-top: 10px;
9696
}
9797

98-
.rss-card-items .rss-item {
98+
.rss-card-items .rss-item-text {
9999
padding-left: 5px;
100100
text-overflow: ellipsis;
101+
overflow: hidden;
102+
max-height: 10em;
101103
}
102104

103105
.rss-item-title {

versions.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,6 @@
2020
"0.9.2": "0.13.14",
2121
"0.9.3": "0.12.17",
2222
"1.0.0": "0.12.17",
23-
"1.0.1": "0.12.17"
23+
"1.0.1": "0.12.17",
24+
"1.0.2": "0.12.17"
2425
}

0 commit comments

Comments
 (0)