diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..a07bef28 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,52 @@ +FROM crystallang/crystal:1.12.2-alpine AS builder + +RUN apk add --no-cache sqlite-static yaml-static + +ARG release + +WORKDIR /invidious +COPY ./shard.yml ./shard.yml +COPY ./shard.lock ./shard.lock +RUN shards install --production + +COPY ./src/ ./src/ +# TODO: .git folder is required for building – this is destructive. +# See definition of CURRENT_BRANCH, CURRENT_COMMIT and CURRENT_VERSION. +COPY ./.git/ ./.git/ + +# Required for fetching player dependencies +COPY ./scripts/ ./scripts/ +COPY ./assets/ ./assets/ +COPY ./videojs-dependencies.yml ./videojs-dependencies.yml + +RUN crystal spec --warnings all \ + --link-flags "-lxml2 -llzma" +RUN --mount=type=cache,target=/root/.cache/crystal if [[ "${release}" == 1 ]] ; then \ + crystal build ./src/invidious.cr \ + --release \ + --static --warnings all \ + --link-flags "-lxml2 -llzma"; \ + else \ + crystal build ./src/invidious.cr \ + --static --warnings all \ + --link-flags "-lxml2 -llzma"; \ + fi + +FROM alpine:3.20 +RUN apk add --no-cache rsvg-convert ttf-opensans tini tzdata +WORKDIR /invidious +RUN addgroup -g 1000 -S invidious && \ + adduser -u 1000 -S invidious -G invidious +COPY --chown=invidious ./config/config.* ./config/ +RUN mv -n config/config.example.yml config/config.yml +RUN sed -i 's/host: \(127.0.0.1\|localhost\)/host: invidious-db/' config/config.yml +COPY ./config/sql/ ./config/sql/ +COPY ./locales/ ./locales/ +COPY --from=builder /invidious/assets ./assets/ +COPY --from=builder /invidious/invidious . +RUN chmod o+rX -R ./assets ./config ./locales + +EXPOSE 3000 +USER invidious +ENTRYPOINT ["/sbin/tini", "--"] +CMD [ "/invidious/invidious" ] diff --git a/deploy.sh b/deploy.sh new file mode 100755 index 00000000..0b40a8c5 --- /dev/null +++ b/deploy.sh @@ -0,0 +1,4 @@ +docker buildx build --platform=linux/x86_64 --tag=invidious . && docker tag invidious main.local:20000/invidious/invidious +docker push main.local:20000/invidious/invidious +docker rmi $(docker images main.local:20000/invidious/invidious -q) --force +echo "Finished." diff --git a/src/invidious/trending.cr b/src/invidious/trending.cr index 688d3bb3..4bb4fee1 100644 --- a/src/invidious/trending.cr +++ b/src/invidious/trending.cr @@ -44,20 +44,28 @@ end def fetch_subscription_related_videoids(env, region, locale) user = env.get("user").as(Invidious::User) - channel_videos, notifications = get_subscription_feed(user, 5, 1) + channel_videos, notifications = get_subscription_feed(user, 10, 1) videos = [] of SearchVideo - channel_videos.each do |video| - video = get_video(video.id) - related = video.related_videos + channel_videos.sample((channel_videos.size / 3).to_i).each do |channel_video| + next if channel_video.live_now || channel_video.premiere_timestamp || channel_video.length_seconds == 0 || channel_video.views == 0 + + video = get_video(channel_video.id) + next unless video.video_type == VideoType::Video + + related = video.related_videos.sample(10) # pick random related videos related.each do |related_video| - related_id = related_video["id"] + next unless id = related_video["id"]? + next unless related_video["view_count"]? && related_video["view_count"]? != 0 + next unless related_video["published"]? + next unless related_video["length_seconds"]? && related_video["length_seconds"]? != 0 + videos << SearchVideo.new({ title: related_video["title"], - id: related_video["id"], + id: id, author: related_video["author"], ucid: related_video["ucid"]? || "", - published: related_video["published"]?.try { |p| Time.parse_rfc3339(p) } || Time.utc, + published: (Time.parse_rfc3339(related_video["published"].to_s) rescue Time.utc), views: related_video["view_count"]?.try &.to_i64 || 0_i64, description_html: "", # not available length_seconds: related_video["length_seconds"]?.try &.to_i || 0,