mirror of
https://github.com/iv-org/invidious.git
synced 2026-07-01 21:03:22 +05:30
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4d6f92f036 | |||
| c380ca72e7 | |||
| 241938538f | |||
| 86b2c4fb7a | |||
| dba5004daf | |||
| 98d69d87c7 |
@@ -65,7 +65,7 @@ jobs:
|
|||||||
crystal: ${{ matrix.crystal }}
|
crystal: ${{ matrix.crystal }}
|
||||||
|
|
||||||
- name: Cache Shards
|
- name: Cache Shards
|
||||||
uses: actions/cache@v6
|
uses: actions/cache@v5
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
./lib
|
./lib
|
||||||
@@ -137,7 +137,7 @@ jobs:
|
|||||||
crystal: latest
|
crystal: latest
|
||||||
|
|
||||||
- name: Cache Shards
|
- name: Cache Shards
|
||||||
uses: actions/cache@v6
|
uses: actions/cache@v5
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
./lib
|
./lib
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
Invidious is and has always been made by human first and foremost. However, things have changed recently with the rise of AI.
|
||||||
|
|
||||||
|
This document is going to explain everything that you need to know if you ever contribute in any way to Invidious using any kind of AI.
|
||||||
|
|
||||||
|
This document has been fully written, from scratch, by a Human.
|
||||||
|
|
||||||
|
|
||||||
|
# Motivation
|
||||||
|
|
||||||
|
Invidious is written in an obscure language: Crystal.
|
||||||
|
|
||||||
|
Because it is obscure the number of people knowing it is really low.
|
||||||
|
|
||||||
|
Invidious is the biggest Crystal project that exists, bigger than Crystal itself [(yes, seriously)](https://shards.info/).
|
||||||
|
|
||||||
|
The problem of being the biggest software in an obscure language is that you're often effectively the first project to encounter a problem and because it's an obscure language, not a lot of libraries exist to make it easier for you, meaning, you usually have to make everything you need yourself.
|
||||||
|
|
||||||
|
This makes it so working on Invidious far harder than working on most open source projects because you are effectively not benefiting and not using any external libraries for the vast majority of things. Almost any time you need anything, you have to make it yourself, which overcomplicates everything.
|
||||||
|
|
||||||
|
We are aware that some people wont like this change and we might even end up on one of the "bad people" list, but we try to be reasonable. We ask that you, please, do not fork the project out of spite because of this new policy - let's not split the thin list of people able to contribute even thinner. Contributions are welcome and highly preferred to anything made by AI.
|
||||||
|
|
||||||
|
This policy comes from a place of *need* not from a place of *choice*.
|
||||||
|
|
||||||
|
|
||||||
|
# Policy
|
||||||
|
|
||||||
|
|
||||||
|
Now that AIs exists and have become *reasonably good*, we will tolerate people using them with reasons and knowledge, as long those rules are respected:
|
||||||
|
|
||||||
|
|
||||||
|
- **Any one using AI to report bugs or submit code MUST properly disclose it, this includes mentioning the name of the EXACT model used and the tools used to interact with it.**
|
||||||
|
- The Human using AI MUST properly check the output manually in addition to any automated check that may exist or may have been created, **this includes BOTH codes AND bug reports**.
|
||||||
|
- Any code submitted by a Human, written even partially by AI, is the responsibility of this Human - If it's malicious, broken, destructive or anything bad, the Human is the sole responsible.
|
||||||
|
- Any new code touching any of the actual functions of Invidious MUST BE thoroughly tested by the Human MANUALLY.
|
||||||
|
- Team members using AIs are strongly encouraged to wait for the review of another Human before merging anything.
|
||||||
|
- At any point [Human-in-the-loop](https://en.wikipedia.org/wiki/Human-in-the-loop) applies.
|
||||||
+13
-15
@@ -205,6 +205,7 @@ https_only: false
|
|||||||
# path: /tmp/invidious.sock
|
# path: /tmp/invidious.sock
|
||||||
# permissions: 777
|
# permissions: 777
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
# Network (outbound)
|
# Network (outbound)
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
@@ -227,6 +228,7 @@ https_only: false
|
|||||||
##
|
##
|
||||||
#pool_size: 100
|
#pool_size: 100
|
||||||
|
|
||||||
|
|
||||||
##
|
##
|
||||||
## Additional cookies to be sent when requesting the youtube API.
|
## Additional cookies to be sent when requesting the youtube API.
|
||||||
##
|
##
|
||||||
@@ -261,6 +263,7 @@ https_only: false
|
|||||||
# host:
|
# host:
|
||||||
# port:
|
# port:
|
||||||
|
|
||||||
|
|
||||||
##
|
##
|
||||||
## Use Innertube's transcripts API instead of timedtext for closed captions
|
## Use Innertube's transcripts API instead of timedtext for closed captions
|
||||||
##
|
##
|
||||||
@@ -341,6 +344,7 @@ https_only: false
|
|||||||
##
|
##
|
||||||
#statistics_enabled: false
|
#statistics_enabled: false
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
# Users and accounts
|
# Users and accounts
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
@@ -452,25 +456,12 @@ full_refresh: false
|
|||||||
##
|
##
|
||||||
feed_threads: 1
|
feed_threads: 1
|
||||||
|
|
||||||
##
|
|
||||||
## Setting to disable easy to abuse API endpoints that can
|
|
||||||
## be spammed and therefore blocking your Invidious instance.
|
|
||||||
##
|
|
||||||
## Useful for public instance maintainers.
|
|
||||||
##
|
|
||||||
## Notes: The following API endpoints will be disabled:
|
|
||||||
## - /api/v1/videos
|
|
||||||
## - /api/v1/clips
|
|
||||||
## - /api/v1/transcripts
|
|
||||||
##
|
|
||||||
## Accepted values: true, false
|
|
||||||
## Default: false
|
|
||||||
##
|
|
||||||
disable_abusable_api: false
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|
||||||
## Options for the database cleaning job
|
## Options for the database cleaning job
|
||||||
clear_expired_items:
|
clear_expired_items:
|
||||||
|
|
||||||
## Enable/Disable job
|
## Enable/Disable job
|
||||||
##
|
##
|
||||||
## Accepted values: true, false
|
## Accepted values: true, false
|
||||||
@@ -480,6 +471,7 @@ jobs:
|
|||||||
|
|
||||||
## Options for the channels updater job
|
## Options for the channels updater job
|
||||||
refresh_channels:
|
refresh_channels:
|
||||||
|
|
||||||
## Enable/Disable job
|
## Enable/Disable job
|
||||||
##
|
##
|
||||||
## Accepted values: true, false
|
## Accepted values: true, false
|
||||||
@@ -489,6 +481,7 @@ jobs:
|
|||||||
|
|
||||||
## Options for the RSS feeds updater job
|
## Options for the RSS feeds updater job
|
||||||
refresh_feeds:
|
refresh_feeds:
|
||||||
|
|
||||||
## Enable/Disable job
|
## Enable/Disable job
|
||||||
##
|
##
|
||||||
## Accepted values: true, false
|
## Accepted values: true, false
|
||||||
@@ -496,6 +489,7 @@ jobs:
|
|||||||
##
|
##
|
||||||
enable: true
|
enable: true
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
# Miscellaneous
|
# Miscellaneous
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
@@ -694,6 +688,7 @@ default_user_preferences:
|
|||||||
##
|
##
|
||||||
#captions: ["", "", ""]
|
#captions: ["", "", ""]
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
# Interface
|
# Interface
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
@@ -795,6 +790,7 @@ default_user_preferences:
|
|||||||
##
|
##
|
||||||
#related_videos: true
|
#related_videos: true
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
# Video player behavior
|
# Video player behavior
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
@@ -858,6 +854,7 @@ default_user_preferences:
|
|||||||
##
|
##
|
||||||
#video_loop: false
|
#video_loop: false
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
# Video playback settings
|
# Video playback settings
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
@@ -969,6 +966,7 @@ default_user_preferences:
|
|||||||
##
|
##
|
||||||
#sort: published
|
#sort: published
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
# Miscellaneous
|
# Miscellaneous
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
|
|||||||
@@ -217,7 +217,6 @@ end
|
|||||||
Kemal.config.powered_by_header = false
|
Kemal.config.powered_by_header = false
|
||||||
add_handler FilteredCompressHandler.new
|
add_handler FilteredCompressHandler.new
|
||||||
add_handler APIHandler.new
|
add_handler APIHandler.new
|
||||||
add_handler DisableAbusableAPIHandler.new
|
|
||||||
add_handler AuthHandler.new
|
add_handler AuthHandler.new
|
||||||
add_handler DenyFrame.new
|
add_handler DenyFrame.new
|
||||||
|
|
||||||
|
|||||||
@@ -183,9 +183,6 @@ class Config
|
|||||||
# Playlist length limit
|
# Playlist length limit
|
||||||
property playlist_length_limit : Int32 = 500
|
property playlist_length_limit : Int32 = 500
|
||||||
|
|
||||||
# Disable easy to abuse API endpoints
|
|
||||||
property disable_abusable_api : Bool = false
|
|
||||||
|
|
||||||
def disabled?(option)
|
def disabled?(option)
|
||||||
case disabled = CONFIG.disable_proxy
|
case disabled = CONFIG.disable_proxy
|
||||||
when Bool
|
when Bool
|
||||||
|
|||||||
@@ -194,13 +194,13 @@ module Invidious::Database::PlaylistVideos
|
|||||||
PG_DB.exec(request, args: video_array)
|
PG_DB.exec(request, args: video_array)
|
||||||
end
|
end
|
||||||
|
|
||||||
def delete(index, plid : String)
|
def delete(index)
|
||||||
request = <<-SQL
|
request = <<-SQL
|
||||||
DELETE FROM playlist_videos *
|
DELETE FROM playlist_videos *
|
||||||
WHERE index = $1 AND plid = $2
|
WHERE index = $1
|
||||||
SQL
|
SQL
|
||||||
|
|
||||||
PG_DB.exec(request, index, plid)
|
PG_DB.exec(request, index)
|
||||||
end
|
end
|
||||||
|
|
||||||
def delete_by_playlist(plid : String)
|
def delete_by_playlist(plid : String)
|
||||||
|
|||||||
@@ -133,26 +133,6 @@ class APIHandler < Kemal::Handler
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class DisableAbusableAPIHandler < Kemal::Handler
|
|
||||||
{% for method in %w(GET HEAD) %}
|
|
||||||
# This endpoints make a video request to Invidious companion.
|
|
||||||
{% for endpoint in %w(videos clips transcripts) %}
|
|
||||||
only ["/api/v1/{{ endpoint.id }}/:id"], {{ method }}
|
|
||||||
{% end %}
|
|
||||||
{% end %}
|
|
||||||
|
|
||||||
def call(env)
|
|
||||||
return call_next env unless only_match?(env) && CONFIG.disable_abusable_api
|
|
||||||
|
|
||||||
env.response.content_type = "application/json"
|
|
||||||
env.response.status_code = 403
|
|
||||||
message = {"error" => "This API endpoint has been disabled by the administrator."}.to_json
|
|
||||||
env.response.print message
|
|
||||||
env.response.close
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class DenyFrame < Kemal::Handler
|
class DenyFrame < Kemal::Handler
|
||||||
exclude ["/embed/*"]
|
exclude ["/embed/*"]
|
||||||
|
|
||||||
|
|||||||
@@ -36,11 +36,6 @@ class Invidious::Jobs::RefreshChannelsJob < Invidious::Jobs::BaseJob
|
|||||||
|
|
||||||
LOGGER.trace("RefreshChannelsJob: #{id} fiber : Updating DB")
|
LOGGER.trace("RefreshChannelsJob: #{id} fiber : Updating DB")
|
||||||
Invidious::Database::Channels.update_author(id, channel.author)
|
Invidious::Database::Channels.update_author(id, channel.author)
|
||||||
|
|
||||||
if backoff > 2.minutes
|
|
||||||
backoff /= 2
|
|
||||||
LOGGER.debug("RefreshChannelsJob: #{id} fiber : decreasing backoff to #{backoff}s")
|
|
||||||
end
|
|
||||||
rescue ex
|
rescue ex
|
||||||
LOGGER.error("RefreshChannelsJob: #{id} : #{ex.message}")
|
LOGGER.error("RefreshChannelsJob: #{id} : #{ex.message}")
|
||||||
if ex.message == "Deleted or invalid channel"
|
if ex.message == "Deleted or invalid channel"
|
||||||
|
|||||||
@@ -364,7 +364,7 @@ module Invidious::Routes::API::V1::Authenticated
|
|||||||
return error_json(404, "Playlist does not contain index")
|
return error_json(404, "Playlist does not contain index")
|
||||||
end
|
end
|
||||||
|
|
||||||
Invidious::Database::PlaylistVideos.delete(index, plid)
|
Invidious::Database::PlaylistVideos.delete(index)
|
||||||
Invidious::Database::Playlists.update_video_removed(plid, index)
|
Invidious::Database::Playlists.update_video_removed(plid, index)
|
||||||
|
|
||||||
env.response.status_code = 204
|
env.response.status_code = 204
|
||||||
|
|||||||
@@ -357,12 +357,8 @@ module Invidious::Routes::Playlists
|
|||||||
Invidious::Database::PlaylistVideos.insert(playlist_video)
|
Invidious::Database::PlaylistVideos.insert(playlist_video)
|
||||||
Invidious::Database::Playlists.update_video_added(playlist_id, playlist_video.index)
|
Invidious::Database::Playlists.update_video_added(playlist_id, playlist_video.index)
|
||||||
when "remove_video"
|
when "remove_video"
|
||||||
index = env.params.query["set_video_id"].to_i64?
|
index = env.params.query["set_video_id"]
|
||||||
if index.nil? || !playlist.index.includes? index
|
Invidious::Database::PlaylistVideos.delete(index)
|
||||||
return error_json(404, "Playlist does not contain index")
|
|
||||||
end
|
|
||||||
|
|
||||||
Invidious::Database::PlaylistVideos.delete(index, playlist_id)
|
|
||||||
Invidious::Database::Playlists.update_video_removed(playlist_id, index)
|
Invidious::Database::Playlists.update_video_removed(playlist_id, index)
|
||||||
when "move_video_before"
|
when "move_video_before"
|
||||||
# TODO: Playlist stub
|
# TODO: Playlist stub
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ end
|
|||||||
|
|
||||||
def add_yt_headers(request)
|
def add_yt_headers(request)
|
||||||
request.headers.delete("User-Agent") if request.headers["User-Agent"] == "Crystal"
|
request.headers.delete("User-Agent") if request.headers["User-Agent"] == "Crystal"
|
||||||
request.headers["User-Agent"] ||= "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/149.0.0.0 Safari/537.36"
|
request.headers["User-Agent"] ||= "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36"
|
||||||
|
|
||||||
request.headers["Accept-Charset"] ||= "ISO-8859-1,utf-8;q=0.7,*;q=0.7"
|
request.headers["Accept-Charset"] ||= "ISO-8859-1,utf-8;q=0.7,*;q=0.7"
|
||||||
request.headers["Accept"] ||= "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
|
request.headers["Accept"] ||= "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
|
||||||
|
|||||||
Reference in New Issue
Block a user