@@ -28,7 +28,7 @@ require "./invidious/helpers/*"
2828require " ./invidious/*"
2929
3030CONFIG = Config .from_yaml(File .read(" config/config.yml" ))
31- HMAC_KEY = CONFIG .hmac_key || Random ::Secure .random_bytes (32 )
31+ HMAC_KEY = CONFIG .hmac_key || Random ::Secure .hex (32 )
3232
3333config = CONFIG
3434logger = Invidious ::LogHandler .new
@@ -88,6 +88,7 @@ PG_DB = DB.open PG_URL
8888YT_URL = URI .parse(" https://www.youtube.com" )
8989REDDIT_URL = URI .parse(" https://www.reddit.com" )
9090LOGIN_URL = URI .parse(" https://accounts.google.com" )
91+ PUBSUB_URL = URI .parse(" https://pubsubhubbub.appspot.com" )
9192TEXTCAPTCHA_URL = URI .parse(" http://textcaptcha.com/omarroth@hotmail.com.json" )
9293CURRENT_COMMIT = ` git rev-list HEAD --max-count=1 --abbrev-commit` .strip
9394CURRENT_VERSION = ` git describe --tags $(git rev-list --tags --max-count=1)` .strip
@@ -115,6 +116,8 @@ refresh_channels(PG_DB, logger, config.channel_threads, config.full_refresh)
115116
116117refresh_feeds(PG_DB , logger, config.feed_threads)
117118
119+ subscribe_to_feeds(PG_DB , logger, HMAC_KEY , config)
120+
118121config.video_threads.times do |i |
119122 spawn do
120123 refresh_videos(PG_DB , logger)
@@ -2314,6 +2317,58 @@ get "/feed/playlist/:plid" do |env|
23142317 document
23152318end
23162319
2320+ # Add support for subscribing to channels via PubSubHubbub
2321+
2322+ get " /feed/webhook" do |env |
2323+ mode = env.params.query[" hub.mode" ]
2324+ topic = env.params.query[" hub.topic" ]
2325+ challenge = env.params.query[" hub.challenge" ]
2326+ lease_seconds = env.params.query[" hub.lease_seconds" ]
2327+ verify_token = env.params.query[" hub.verify_token" ]
2328+
2329+ time, signature = verify_token.split(" :" )
2330+
2331+ if Time .now.to_unix - time.to_i > 600
2332+ halt env, status_code: 400
2333+ end
2334+
2335+ if OpenSSL ::HMAC .hexdigest(:sha1 , HMAC_KEY , time) != signature
2336+ halt env, status_code: 400
2337+ end
2338+
2339+ ucid = HTTP ::Params .parse(URI .parse(topic).query.not_nil!)[" channel_id" ]
2340+ PG_DB .exec(" UPDATE channels SET subscribed = true WHERE ucid = $1" , ucid)
2341+
2342+ halt env, status_code: 200 , response: challenge
2343+ end
2344+
2345+ post " /feed/webhook" do |env |
2346+ body = env.request.body.not_nil!.gets_to_end
2347+ signature = env.request.headers[" X-Hub-Signature" ].lchop(" sha1=" )
2348+
2349+ if signature != OpenSSL ::HMAC .hexdigest(:sha1 , HMAC_KEY , body)
2350+ halt env, status_code: 200
2351+ end
2352+
2353+ rss = XML .parse_html(body)
2354+ rss.xpath_nodes(" //feed/entry" ).each do |entry |
2355+ id = entry.xpath_node(" videoid" ).not_nil!.content
2356+
2357+ video = get_video(id, PG_DB , proxies)
2358+ video = ChannelVideo .new(id, video.title, video.published, Time .now, video.ucid, video.author, video.length_seconds)
2359+
2360+ PG_DB .exec(" UPDATE users SET notifications = notifications || $1 \
2361+ WHERE updated < $2 AND $3 = ANY(subscriptions) AND $1 <> ALL(notifications)" , video.id, video.published, video.ucid)
2362+
2363+ video_array = video.to_a
2364+ args = arg_array(video_array)
2365+
2366+ PG_DB .exec(" INSERT INTO channel_videos VALUES (#{ args } ) \
2367+ ON CONFLICT (id) DO UPDATE SET title = $2, published = $3, \
2368+ updated = $4, ucid = $5, author = $6, length_seconds = $7" , video_array)
2369+ end
2370+ end
2371+
23172372# Channels
23182373
23192374# YouTube appears to let users set a "brand" URL that
0 commit comments