2018-11-09 07:38:03 +05:30
require " crypto/bcrypt/password "
2019-07-08 00:30:42 +05:30
# Materialized views may not be defined using bound parameters (`$1` as used elsewhere)
2019-07-09 20:04:19 +05:30
MATERIALIZED_VIEW_SQL = - > ( email : String ) { " SELECT cv.* FROM channel_videos cv WHERE EXISTS (SELECT subscriptions FROM users u WHERE cv.ucid = ANY (u.subscriptions) AND u.email = E' #{ email . gsub ( { '\'' = > " \\ ' " , '\\' = > " \\ \\ " } ) } ') ORDER BY published DESC " }
2019-07-08 00:30:42 +05:30
2018-08-05 02:00:44 +05:30
def create_user ( sid , email , password )
password = Crypto :: Bcrypt :: Password . create ( password , cost : 10 )
token = Base64 . urlsafe_encode ( Random :: Secure . random_bytes ( 32 ) )
2022-02-04 08:39:07 +05:30
user = Invidious :: User . new ( {
2020-07-26 20:28:50 +05:30
updated : Time . utc ,
notifications : [ ] of String ,
subscriptions : [ ] of String ,
email : email ,
preferences : Preferences . new ( CONFIG . default_user_preferences . to_tuple ) ,
password : password . to_s ,
token : token ,
watched : [ ] of String ,
feed_needs_update : true ,
} )
2018-08-05 02:00:44 +05:30
2019-02-11 00:03:29 +05:30
return user , sid
2018-08-05 02:00:44 +05:30
end
2018-11-11 21:14:16 +05:30
2021-12-07 08:27:18 +05:30
def get_subscription_feed ( user , max_results = 40 , page = 1 )
2019-06-07 23:09:12 +05:30
limit = max_results . clamp ( 0 , MAX_ITEMS_PER_PAGE )
offset = ( page - 1 ) * limit
2021-12-03 07:59:52 +05:30
notifications = Invidious :: Database :: Users . select_notifications ( user )
2019-06-07 23:09:12 +05:30
view_name = " subscriptions_ #{ sha256 ( user . email ) } "
if user . preferences . notifications_only && ! notifications . empty?
# Only show notifications
2021-12-02 23:46:41 +05:30
notifications = Invidious :: Database :: ChannelVideos . select ( notifications )
2019-06-07 23:09:12 +05:30
videos = [ ] of ChannelVideo
2021-09-25 08:12:43 +05:30
notifications . sort_by! ( & . published ) . reverse!
2019-06-07 23:09:12 +05:30
case user . preferences . sort
when " alphabetically "
2021-09-25 08:12:43 +05:30
notifications . sort_by! ( & . title )
2019-06-07 23:09:12 +05:30
when " alphabetically - reverse "
2021-09-25 08:12:43 +05:30
notifications . sort_by! ( & . title ) . reverse!
2019-06-07 23:09:12 +05:30
when " channel name "
2021-09-25 08:12:43 +05:30
notifications . sort_by! ( & . author )
2019-06-07 23:09:12 +05:30
when " channel name - reverse "
2021-09-25 08:12:43 +05:30
notifications . sort_by! ( & . author ) . reverse!
2020-04-09 22:48:09 +05:30
else nil # Ignore
2019-06-07 23:09:12 +05:30
end
else
if user . preferences . latest_only
if user . preferences . unseen_only
# Show latest video from a channel that a user hasn't watched
# "unseen_only" isn't really correct here, more accurate would be "unwatched_only"
if user . watched . empty?
values = " '{}' "
else
values = " VALUES #{ user . watched . map { | id | %( ( ' #{ id } ' ) ) } . join ( " , " ) } "
end
2019-08-27 18:38:26 +05:30
videos = PG_DB . query_all ( " SELECT DISTINCT ON (ucid) * FROM #{ view_name } WHERE NOT id = ANY ( #{ values } ) ORDER BY ucid, published DESC " , as : ChannelVideo )
2019-06-07 23:09:12 +05:30
else
# Show latest video from each channel
2019-08-27 18:38:26 +05:30
videos = PG_DB . query_all ( " SELECT DISTINCT ON (ucid) * FROM #{ view_name } ORDER BY ucid, published DESC " , as : ChannelVideo )
2019-06-07 23:09:12 +05:30
end
2021-09-25 08:12:43 +05:30
videos . sort_by! ( & . published ) . reverse!
2019-06-07 23:09:12 +05:30
else
if user . preferences . unseen_only
# Only show unwatched
if user . watched . empty?
values = " '{}' "
else
values = " VALUES #{ user . watched . map { | id | %( ( ' #{ id } ' ) ) } . join ( " , " ) } "
end
2019-08-27 18:38:26 +05:30
videos = PG_DB . query_all ( " SELECT * FROM #{ view_name } WHERE NOT id = ANY ( #{ values } ) ORDER BY published DESC LIMIT $1 OFFSET $2 " , limit , offset , as : ChannelVideo )
2019-06-07 23:09:12 +05:30
else
# Sort subscriptions as normal
2019-08-27 18:38:26 +05:30
videos = PG_DB . query_all ( " SELECT * FROM #{ view_name } ORDER BY published DESC LIMIT $1 OFFSET $2 " , limit , offset , as : ChannelVideo )
2019-06-07 23:09:12 +05:30
end
end
case user . preferences . sort
when " published - reverse "
2021-09-25 08:12:43 +05:30
videos . sort_by! ( & . published )
2019-06-07 23:09:12 +05:30
when " alphabetically "
2021-09-25 08:12:43 +05:30
videos . sort_by! ( & . title )
2019-06-07 23:09:12 +05:30
when " alphabetically - reverse "
2021-09-25 08:12:43 +05:30
videos . sort_by! ( & . title ) . reverse!
2019-06-07 23:09:12 +05:30
when " channel name "
2021-09-25 08:12:43 +05:30
videos . sort_by! ( & . author )
2019-06-07 23:09:12 +05:30
when " channel name - reverse "
2021-09-25 08:12:43 +05:30
videos . sort_by! ( & . author ) . reverse!
2020-04-09 22:48:09 +05:30
else nil # Ignore
2019-06-07 23:09:12 +05:30
end
2021-12-03 07:59:52 +05:30
notifications = Invidious :: Database :: Users . select_notifications ( user )
2019-06-07 23:09:12 +05:30
notifications = videos . select { | v | notifications . includes? v . id }
videos = videos - notifications
end
return videos , notifications
end