Add users table

This commit is contained in:
Omar Roth 2018-03-29 21:41:05 -05:00
parent 4a7fc4ea69
commit 6c4cfbe39d
6 changed files with 89 additions and 16 deletions

View File

@ -18,3 +18,12 @@ WITH (
TABLESPACE pg_default; TABLESPACE pg_default;
GRANT ALL ON TABLE public.channel_videos TO kemal; GRANT ALL ON TABLE public.channel_videos TO kemal;
-- Index: channel_videos_published_idx
-- DROP INDEX public.channel_videos_published_idx;
CREATE INDEX channel_videos_published_idx
ON public.channel_videos USING btree
(published)
TABLESPACE pg_default;

View File

@ -6,7 +6,8 @@ CREATE TABLE public.channels
( (
id text COLLATE pg_catalog."default" NOT NULL, id text COLLATE pg_catalog."default" NOT NULL,
author text COLLATE pg_catalog."default", author text COLLATE pg_catalog."default",
updated timestamp with time zone updated timestamp with time zone,
CONSTRAINT channels_id_key UNIQUE (id)
) )
WITH ( WITH (
OIDS = FALSE OIDS = FALSE
@ -14,3 +15,12 @@ WITH (
TABLESPACE pg_default; TABLESPACE pg_default;
GRANT ALL ON TABLE public.channels TO kemal; GRANT ALL ON TABLE public.channels TO kemal;
-- Index: channels_id_idx
-- DROP INDEX public.channels_id_idx;
CREATE INDEX channels_id_idx
ON public.channels USING btree
(id COLLATE pg_catalog."default")
TABLESPACE pg_default;

17
config/sql/users.sql Normal file
View File

@ -0,0 +1,17 @@
-- Table: public.users
-- DROP TABLE public.users;
CREATE TABLE public.users
(
id text COLLATE pg_catalog."default" NOT NULL,
updated timestamp with time zone,
notifications integer,
subscriptions text[] COLLATE pg_catalog."default"
)
WITH (
OIDS = FALSE
)
TABLESPACE pg_default;
GRANT ALL ON TABLE public.users TO kemal;

View File

@ -5,3 +5,4 @@ createuser kemal
psql invidious < config/sql/channels.sql psql invidious < config/sql/channels.sql
psql invidious < config/sql/videos.sql psql invidious < config/sql/videos.sql
psql invidious < config/sql/channel_videos.sql psql invidious < config/sql/channel_videos.sql
psql invidious < config/sql/users.sql

View File

@ -79,6 +79,15 @@ class ChannelVideo
}) })
end end
class User
add_mapping({
id: String,
updated: Time,
notifications: Int32,
subscriptions: Array(String),
})
end
class RedditSubmit class RedditSubmit
JSON.mapping({ JSON.mapping({
data: RedditSubmitData, data: RedditSubmitData,
@ -545,3 +554,40 @@ def fetch_channel(id, client, db)
return channel return channel
end end
def get_user(sid, client, headers, db)
if db.query_one?("SELECT EXISTS (SELECT true FROM users WHERE id = $1)", sid, as: Bool)
user = db.query_one("SELECT * FROM users WHERE id = $1", sid, as: User)
if Time.now - user.updated > 1.minutes
user = fetch_user(sid, client, headers)
user_array = user.to_a
args = arg_array(user_array)
db.exec("INSERT INTO users VALUES (#{args}) \
ON CONFLICT (id) DO UPDATE SET updated = $2, subscriptions = $4", user_array)
end
else
user = fetch_user(sid, client, headers)
args = arg_array(user.to_a)
db.exec("INSERT INTO users VALUES (#{args})", user.to_a)
end
return user
end
def fetch_user(sid, client, headers)
feed = client.get("/subscription_manager?action_takeout=1", headers).body
channels = [] of String
feed = XML.parse_html(feed)
feed.xpath_nodes("//opml/outline/outline").each do |channel|
id = channel["xmlurl"][-24..-1]
get_channel(id, client, PG_DB)
channels << id
end
user = User.new(sid, Time.now, 0, channels)
return user
end

View File

@ -567,29 +567,19 @@ get "/feed/subscriptions" do |env|
page = env.params.query["page"]?.try &.to_i page = env.params.query["page"]?.try &.to_i
page ||= 1 page ||= 1
client = get_client(youtube_pool)
headers = HTTP::Headers.new headers = HTTP::Headers.new
headers["Cookie"] = env.request.headers["Cookie"] headers["Cookie"] = env.request.headers["Cookie"]
feed = client.get("/subscription_manager?action_takeout=1", headers).body sid = env.request.cookies["SID"].value
channels = [] of String client = get_client(youtube_pool)
user = get_user(sid, client, headers, PG_DB)
feed = XML.parse_html(feed)
feed.xpath_nodes("//opml/outline/outline").each do |channel|
id = channel["xmlurl"][-24..-1]
get_channel(id, client, PG_DB)
channels << id
end
youtube_pool << client youtube_pool << client
time = Time.now args = arg_array(user.subscriptions)
args = arg_array(channels)
offset = (page - 1) * max_results offset = (page - 1) * max_results
videos = PG_DB.query_all("SELECT * FROM channel_videos WHERE ucid IN (#{args})\ videos = PG_DB.query_all("SELECT * FROM channel_videos WHERE ucid IN (#{args})\
ORDER BY published DESC LIMIT #{max_results} OFFSET #{offset}", channels, as: ChannelVideo) ORDER BY published DESC LIMIT #{max_results} OFFSET #{offset}", user.subscriptions, as: ChannelVideo)
templated "subscriptions" templated "subscriptions"
else else