diff --git a/src/invidious.cr b/src/invidious.cr index 832b48829..ad63fcada 100644 --- a/src/invidious.cr +++ b/src/invidious.cr @@ -27,6 +27,8 @@ require "compress/zip" require "protodec/utils" require "./invidious/helpers/*" require "./invidious/*" +require "./invidious/routes/**" +require "./invidious/jobs/**" ENV_CONFIG_NAME = "INVIDIOUS_CONFIG" @@ -196,11 +198,11 @@ if config.statistics_enabled end end -popular_videos = [] of ChannelVideo -spawn do - pull_popular_videos(PG_DB) do |videos| - popular_videos = videos - end +Invidious::Jobs.register Invidious::Jobs::PullPopularVideosJob.new(PG_DB) +Invidious::Jobs.start_all + +def popular_videos + Invidious::Jobs::PullPopularVideosJob::POPULAR_VIDEOS.get end DECRYPT_FUNCTION = [] of {SigProc, Int32} @@ -350,44 +352,9 @@ before_all do |env| env.set "current_page", URI.encode_www_form(current_page) end -get "/" do |env| - preferences = env.get("preferences").as(Preferences) - locale = LOCALES[preferences.locale]? - user = env.get? "user" - - case preferences.default_home - when "" - templated "empty" - when "Popular" - templated "popular" - when "Trending" - env.redirect "/feed/trending" - when "Subscriptions" - if user - env.redirect "/feed/subscriptions" - else - templated "popular" - end - when "Playlists" - if user - env.redirect "/view_all_playlists" - else - templated "popular" - end - else - templated "empty" - end -end - -get "/privacy" do |env| - locale = LOCALES[env.get("preferences").as(Preferences).locale]? - templated "privacy" -end - -get "/licenses" do |env| - locale = LOCALES[env.get("preferences").as(Preferences).locale]? - rendered "licenses" -end +Invidious::Routing.get "/", Invidious::Routes::Home +Invidious::Routing.get "/privacy", Invidious::Routes::Privacy +Invidious::Routing.get "/licenses", Invidious::Routes::Licenses # Videos diff --git a/src/invidious/jobs.cr b/src/invidious/jobs.cr new file mode 100644 index 000000000..ec0cad641 --- /dev/null +++ b/src/invidious/jobs.cr @@ -0,0 +1,13 @@ +module Invidious::Jobs + JOBS = [] of BaseJob + + def self.register(job : BaseJob) + JOBS << job + end + + def self.start_all + JOBS.each do |job| + spawn { job.begin } + end + end +end diff --git a/src/invidious/jobs/base_job.cr b/src/invidious/jobs/base_job.cr new file mode 100644 index 000000000..47e758642 --- /dev/null +++ b/src/invidious/jobs/base_job.cr @@ -0,0 +1,3 @@ +abstract class Invidious::Jobs::BaseJob + abstract def begin +end diff --git a/src/invidious/jobs/pull_popular_videos_job.cr b/src/invidious/jobs/pull_popular_videos_job.cr new file mode 100644 index 000000000..7a8ab84ee --- /dev/null +++ b/src/invidious/jobs/pull_popular_videos_job.cr @@ -0,0 +1,27 @@ +class Invidious::Jobs::PullPopularVideosJob < Invidious::Jobs::BaseJob + QUERY = <<-SQL + SELECT DISTINCT ON (ucid) * + FROM channel_videos + WHERE ucid IN (SELECT channel FROM (SELECT UNNEST(subscriptions) AS channel FROM users) AS d + GROUP BY channel ORDER BY COUNT(channel) DESC LIMIT 40) + ORDER BY ucid, published DESC + SQL + POPULAR_VIDEOS = Atomic.new([] of ChannelVideo) + private getter db : DB::Database + + def initialize(@db) + end + + def begin + loop do + videos = db.query_all(QUERY, as: ChannelVideo) + .sort_by(&.published) + .reverse + + POPULAR_VIDEOS.set(videos) + + sleep 1.minute + Fiber.yield + end + end +end diff --git a/src/invidious/routes/base_route.cr b/src/invidious/routes/base_route.cr new file mode 100644 index 000000000..576c1746d --- /dev/null +++ b/src/invidious/routes/base_route.cr @@ -0,0 +1,8 @@ +abstract class Invidious::Routes::BaseRoute + private getter config : Config + + def initialize(@config) + end + + abstract def handle(env) +end diff --git a/src/invidious/routes/home.cr b/src/invidious/routes/home.cr new file mode 100644 index 000000000..9b1bf61b3 --- /dev/null +++ b/src/invidious/routes/home.cr @@ -0,0 +1,34 @@ +class Invidious::Routes::Home < Invidious::Routes::BaseRoute + def handle(env) + preferences = env.get("preferences").as(Preferences) + locale = LOCALES[preferences.locale]? + user = env.get? "user" + + case preferences.default_home + when "" + templated "empty" + when "Popular" + templated "popular" + when "Trending" + env.redirect "/feed/trending" + when "Subscriptions" + if user + env.redirect "/feed/subscriptions" + else + templated "popular" + end + when "Playlists" + if user + env.redirect "/view_all_playlists" + else + templated "popular" + end + else + templated "empty" + end + end + + private def popular_videos + Jobs::PullPopularVideosJob::POPULAR_VIDEOS.get + end +end diff --git a/src/invidious/routes/licenses.cr b/src/invidious/routes/licenses.cr new file mode 100644 index 000000000..38fde7bb4 --- /dev/null +++ b/src/invidious/routes/licenses.cr @@ -0,0 +1,6 @@ +class Invidious::Routes::Licenses < Invidious::Routes::BaseRoute + def handle(env) + locale = LOCALES[env.get("preferences").as(Preferences).locale]? + rendered "licenses" + end +end diff --git a/src/invidious/routes/privacy.cr b/src/invidious/routes/privacy.cr new file mode 100644 index 000000000..4565c94c5 --- /dev/null +++ b/src/invidious/routes/privacy.cr @@ -0,0 +1,6 @@ +class Invidious::Routes::Privacy < Invidious::Routes::BaseRoute + def handle(env) + locale = LOCALES[env.get("preferences").as(Preferences).locale]? + templated "privacy" + end +end diff --git a/src/invidious/routing.cr b/src/invidious/routing.cr new file mode 100644 index 000000000..a096db44a --- /dev/null +++ b/src/invidious/routing.cr @@ -0,0 +1,8 @@ +module Invidious::Routing + macro get(path, controller) + get {{ path }} do |env| + controller_instance = {{ controller }}.new(config) + controller_instance.handle(env) + end + end +end