From c5cf1359762274a17fb139944405c02618996700 Mon Sep 17 00:00:00 2001
From: Mark Powers <markppowers0@gmail.com>
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 @@
 
 <body>
     <form>
-        <div>
-            <label>rss-bridge instance<input type="text" id="rb"></label>
-        </div>
-        <div>
-            <label>tt-rss instance<input type="text" id="tr"></label>
-        </div>
-        <button type="submit">Save</button>
+        <table>
+        <tr>
+            <td><label for="rb">rss-bridge instance</label></td>
+            <td><input type="text" id="rb"></td>
+        </tr>
+        <tr>
+            <td><label for="tr">tt-rss instance</label></td>
+            <td><input type="text" id="tr"></td>
+        </tr>
+        <tr>
+            <td>
+                <button type="submit">Save</button>
+            </td>
+        </tr>
+        </table>
     </form>
     <script src="options.js"></script>
 </body>
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