From c5cf1359762274a17fb139944405c02618996700 Mon Sep 17 00:00:00 2001 From: Mark Powers Date: Mon, 23 Nov 2020 20:21:59 -0600 Subject: Fix youtube feeds --- README.md | 8 +++--- cs.js | 80 ++++++++++++----------------------------------------------- index.js | 16 +++++++++++- instagram.js | 8 ++++++ manifest.json | 20 +++++++++------ options.html | 22 ++++++++++------ twitter.js | 10 ++++++++ youtube.js | 60 ++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 140 insertions(+), 84 deletions(-) create mode 100644 instagram.js create mode 100644 twitter.js create mode 100644 youtube.js diff --git a/README.md b/README.md index 7a92d3f..83c9cdc 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,5 @@ -This extension has a popup that will give you the option to select from feeds on a page natively (from the link tag in the head), or with RSS-bridge configured to your liking. +This extension has a popup that will give you the option to select from feeds on a page natively, or with RSS-bridge configured to your liking. It optionally integrates with tt-rss to include a 'subscribe' link. -This code is inspired and cloned somewhat from https://github.com/idealclover/Easy-to-RSS/. Icons are sourced from this repository as well. - -# TODO -- Add youtube rss +Supports twitter, instagram, and youtube RSS-Bridge. +This code is inspired and cloned somewhat from https://github.com/idealclover/Easy-to-RSS/. Icons are sourced from this repository as well. diff --git a/cs.js b/cs.js index b6b35c6..2bb7b12 100644 --- a/cs.js +++ b/cs.js @@ -41,84 +41,36 @@ function find_links_in_page() { return feeds } -function get_all_types(feed_url) { +function get_all_types(feed_url, note) { let feeds = []; formats.forEach(el => { - feeds.push({ - type: `rss-bridge: ${el}`, - url: feed_url + el - }); + if(note){ + feeds.push({ + type: `rss-bridge (${note}): ${el}`, + url: feed_url + el + }); + } else { + feeds.push({ + type: `rss-bridge: ${el}`, + url: feed_url + el + }); + } }) return feeds; } -async function get_insta(url) { - let insta_url = url + "?__a=1" - console.log("fetching") - let res = await fetch(insta_url); - let json = await res.json(); - let uid = json.graphql.user.id - let feed_url = `${base_url}/?action=display&bridge=Instagram&context=Username&u=${uid}&media_type=all&format=`; - return get_all_types(feed_url) -} - -function get_twitter(url) { - let pattern = /twitter.com\/(\w+).*/ - let match = url.match(pattern); - if (match) { - let twitter_handle = match[1] - let feed_url = `${base_url}/?action=display&bridge=Twitter&context=By+username&u=${twitter_handle}&format=` - return get_all_types(feed_url) - } - return [] -} - -async function get_youtube(url) { - // use link to channel if given a video url - let patternVideo = /youtube.com\/watch\?v=\w+/ - if (url.match(patternVideo)) { - url = document.querySelector("#channel-name a")["href"] - } - - let patternUser = /youtube.com\/user\/(\w+).*/ - let matchUser = url.match(patternUser) - - let patternChannel = /youtube.com\/channel\/(\w+).*/ - let matchChannel = url.match(patternChannel) - - let patternPlaylist = /youtube.com\/playlist\?list=(\w+)/ - let matchPlaylist = url.match(patternPlaylist) - - - if (matchUser) { - let user = matchUser[1]; - let feed_url = `${base_url}/?action=display&bridge=Youtube&context=By+username&u=${user}&duration_min=&duration_max=&format=` - return get_all_types(feed_url) - } else if (matchChannel) { - let channelId = matchChannel[1] - let feed_url = `${base_url}/?action=display&bridge=Youtube&context=By+channel+id&c=${channelId}&duration_min=&duration_max=&format=` - return get_all_types(feed_url) - } else if (matchPlaylist) { - let playlistId = matchPlaylist[1] - let native_url = `https://www.youtube.com/feeds/videos.xml?playlist_id=${playlistId}` - let feed_url = `${base_url}/?action=display&bridge=Youtube&context=By+playlist+Id&p=${playlistId}&duration_min=&duration_max=&format=` - let rb_feeds = get_all_types(feed_url) - return rb_feeds.concat([{ type: `native: Rss`, url: native_url }]) - } - return [] -} - async function get_feed_urls() { let settings = await browser.storage.sync.get("rb"); base_url = settings.rb; let all_feed_urls = [] let url = window.location.href; + let host = window.location.host; //url = url.toLowerCase() - if (url.includes("instagram")) { + if (host.includes("instagram")) { all_feed_urls = all_feed_urls.concat(await get_insta(url)) - } else if (url.includes("twitter")) { + } else if (host.includes("twitter")) { all_feed_urls = all_feed_urls.concat(get_twitter(url)) - } else if (url.includes("youtube")) { + } else if (host.includes("youtube")) { all_feed_urls = all_feed_urls.concat(await get_youtube(url)) } all_feed_urls = all_feed_urls.concat(find_links_in_page()) diff --git a/index.js b/index.js index 9ba390e..2138dd5 100644 --- a/index.js +++ b/index.js @@ -6,14 +6,28 @@ function subscribe_link(feed_url){ } window.onload = async function () { - let settings = await browser.storage.sync.get("tr"); + let settings = await browser.storage.sync.get(["tr", "rb"]); base_ttrss = settings.tr; + let base_rb = settings.rb; let feeds = document.getElementById('feeds'); feeds.innerText = "Loading..." browser.tabs.query({ active: true, currentWindow: true }, function (tabs) { browser.tabs.sendMessage(tabs[0].id, {}).then( function (feed_urls) { feeds.innerText = "" + if(!base_rb) { + let newSettingsLink = document.createElement("a") + newSettingsLink["href"] = "/options.html" + newSettingsLink.innerText = "RSS-bridge instance not set! Click here to open options."; + let newDiv = document.createElement('div'); + newDiv.append(newSettingsLink); + feeds.appendChild(newDiv); + + let newP = document.createElement('p') + newP.innerText = `Found ${feed_urls.length} feeds` + feeds.append(newP) + return; + } feed_urls.forEach(item => { let newLink = document.createElement('a'); diff --git a/instagram.js b/instagram.js new file mode 100644 index 0000000..56b3785 --- /dev/null +++ b/instagram.js @@ -0,0 +1,8 @@ +async function get_insta(url) { + let insta_url = url + "?__a=1" + let res = await fetch(insta_url); + let json = await res.json(); + let uid = json.graphql.user.id + let feed_url = `${base_url}/?action=display&bridge=Instagram&context=Username&u=${uid}&media_type=all&format=`; + return get_all_types(feed_url) +} \ No newline at end of file diff --git a/manifest.json b/manifest.json index e19b26a..7ed3af5 100644 --- a/manifest.json +++ b/manifest.json @@ -1,8 +1,8 @@ { - "description": "Subscribe to rss feeds with support for rss bridge", + "description": "Finds feeds or generates RSS-Bridge URLs for the current page. Optional integration with tt-rss.", "manifest_version": 2, - "name": "tt-rss_and_rss-bridge", - "version": "1.2", + "name": "RSS-Bridge helper", + "version": "1.0", "content_scripts": [ { "matches": [ @@ -10,13 +10,16 @@ "https://*/*" ], "js": [ + "youtube.js", + "twitter.js", + "instagram.js", "cs.js" ] } ], "browser_action": { "default_icon": "icon_default.png", - "default_title": "manage rss for this page", + "default_title": "See feeds for this page", "default_popup": "main.html" }, "permissions": [ @@ -30,8 +33,11 @@ }, "browser_specific_settings": { "gecko": { - "id": "ttrss_rb@marks.kitchen", - "strict_min_version": "42.0" + "id": "rss-bridge-helper@marks.kitchen", + "strict_min_version": "57.0" } + }, + "icons": { + "128": "icon_128.png" } -} \ No newline at end of file +} diff --git a/options.html b/options.html index 236357f..b248905 100644 --- a/options.html +++ b/options.html @@ -8,13 +8,21 @@
-
- -
-
- -
- + + + + + + + + + + + + +
+ +
diff --git a/twitter.js b/twitter.js new file mode 100644 index 0000000..1f21047 --- /dev/null +++ b/twitter.js @@ -0,0 +1,10 @@ +function get_twitter(url) { + let pattern = /twitter.com\/(\w+).*/ + let match = url.match(pattern); + if (match) { + let twitter_handle = match[1] + let feed_url = `${base_url}/?action=display&bridge=Twitter&context=By+username&u=${twitter_handle}&format=` + return get_all_types(feed_url) + } + return [] +} diff --git a/youtube.js b/youtube.js new file mode 100644 index 0000000..0f095e8 --- /dev/null +++ b/youtube.js @@ -0,0 +1,60 @@ +function get_native_playlist_feed(playlistId){ + return `https://www.youtube.com/feeds/videos.xml?playlist_id=${playlistId}` +} + +function get_native_channel_feed(channelId){ + return `https://www.youtube.com/feeds/videos.xml?channel_id=${channelId}` +} + +async function get_youtube(url) { + let patternVideo = /youtube.com\/watch\?v=\w+/ + let matchVideo = url.match(patternVideo) + + let patternUser = /youtube.com\/user\/(\w+).*/ + let matchUser = url.match(patternUser) + + let patternChannel = /youtube.com\/channel\/(\w+).*/ + let matchChannel = url.match(patternChannel) + + let patternPlaylist = /youtube.com\/playlist\?list=(\w+)/ + let matchPlaylist = url.match(patternPlaylist) + + if (matchVideo) { + let channel_url = document.querySelector("[role='main'] #channel-name a")["href"] + let matchChannel2 = channel_url.match(patternChannel) + let channelId = matchChannel2[1] + let feed_url = `${base_url}/?action=display&bridge=Youtube&context=By+channel+id&c=${channelId}&duration_min=&duration_max=&format=` + let native_url = get_native_channel_feed(channelId) + let feeds = get_all_types(feed_url, "channel").concat([{ type: `native (channel): Rss`, url: native_url }]) + + let patternListInVideo = /youtube.com\/watch\?v=\w+\&list=(\w+)/ + let matchListInVideo = url.match(patternListInVideo) + if(matchListInVideo){ + let playlistId = matchListInVideo[1] + let playlist_feed_url = `${base_url}/?action=display&bridge=Youtube&context=By+playlist+Id&p=${playlistId}&duration_min=&duration_max=&format=` + let native_url = get_native_playlist_feed(playlistId) + let rb_feeds = get_all_types(playlist_feed_url, "playlist") + feeds = feeds.concat(rb_feeds.concat([{ type: `native (playlist): Rss`, url: native_url }])) + } + + return feeds + } + if (matchUser) { + let user = matchUser[1]; + let feed_url = `${base_url}/?action=display&bridge=Youtube&context=By+username&u=${user}&duration_min=&duration_max=&format=` + return get_all_types(feed_url) + } + if (matchChannel) { + let channelId = matchChannel[1] + let feed_url = `${base_url}/?action=display&bridge=Youtube&context=By+channel+id&c=${channelId}&duration_min=&duration_max=&format=` + return get_all_types(feed_url) + } + if (matchPlaylist) { + let playlistId = matchPlaylist[1] + let native_url = get_native_playlist_feed(playlistId) + let feed_url = `${base_url}/?action=display&bridge=Youtube&context=By+playlist+Id&p=${playlistId}&duration_min=&duration_max=&format=` + let rb_feeds = get_all_types(feed_url) + return rb_feeds.concat([{ type: `native: Rss`, url: native_url }]) + } + return [] +} -- cgit v1.2.3