Check if the video already exists in the playlist before inserting.
Uses the existing select_index() query. Returns 409 via the API and
silently redirects back on the web UI.
Applied to both the web route (playlist_ajax) and the API v1 route
(POST /api/v1/auth/playlists/:plid/videos).
When pages_enabled.search is false, instead of blocking search entirely,
the search bar now searches within the user's subscriptions and saved
playlists only. YouTube's search API is never called.
Changes:
- routes/search.cr: detect search_disabled, force subscription+playlist
search for logged-in users, 403 for anonymous users
- search/processors.cr: new subscriptions_and_playlists() method that
queries both the subscription materialized view and playlist_videos
table, merges and deduplicates results
- before_all.cr: let /search through to the route handler (APIs still
blocked), keep /hashtag/* blocked
- search_box.ecr: dynamic placeholder ("Search subscriptions & playlists")
- search_homepage.ecr: hint text when in subscription-only mode
- search.ecr: hide YouTube filters, show lock icon + notice, custom
empty-results message
- template.ecr: always show search bar (subscription search needs it)
- en-US.json: 6 new locale strings for subscription-only search UX
- Hide navbar search box when CONFIG.page_enabled?("search") is false
- Keep Invidious logo visible with proper width when search bar is hidden
- Hide search widget on search_homepage when search is disabled
- Block /results, /api/v1/search/suggestions in before_all guard
- Block /hashtag/* and /api/v1/hashtag/* when search is disabled
HTML checkboxes send no value when unchecked, so the fallback
"|| \"on\"" always re-enabled popular/trending/search on save.
Changed default to "off" to match the pattern used by captcha_enabled,
login_enabled, and other checkbox toggles in the same handler.
- Fix kemal_static_file_handler directory_listing to use Path types (Crystal API compat)
- Add missing search_page_disabled translation key to en-US.json
- Filter preferences default_home options based on pages_enabled config
- Add admin-only /debug_config route for verifying configuration state
When switching between Listen and Watching the timestamp in the url of
the listen of watch button is now updated automatically.
This means if you switch between listening and viewing you keep in sync
with time.
* Remove sort by rating and date in video search filters
Closes https://github.com/iv-org/invidious/issues/5626
* Remove check of protobug generation of rating and date sort filters in Invidious spec
thin_mode only took in account the query param because
env.get("preferences").as(Preferences).thin_mode returned a boolean and
not a string to be able to compare it with the string `"true"`
* doc: Update HTTP proxy configuration comments
Added information about proxy configuration for YouTube streams.
* Document supported proxy types in config.example.yml
Added note about supported proxy types in configuration.
Image responses contained the following unwanted headers that should not
be passed to the clients:
```
"Cross-Origin-Resource-Policy"
["cross-origin"]
"Cross-Origin-Opener-Policy-Report-Only"
["same-origin; report-to=\"youtube\""]
"Report-To"
["{\"group\":\"youtube\",\"max_age\":2592000,\"endpoints\":[{\"url\":\"https://csp.withgoogle.com/csp/report-to/youtube\"}]}"]
"Timing-Allow-Origin"
["*"]
```
* downgrade to 1.16.3
* Downgrade Alpine base image from 3.23 to 3.22
---------
Co-authored-by: Émilien (perso) <4016501+unixfox@users.noreply.github.com>
* Allow downloading via companion
* post request where not proxied for the download companion which made
it impossible to download with the companion enabled
* Re-apply Channel to Channels rename which was pulled in
* Update src/invidious/routes/companion.cr
* doc: better comments for each route
---------
Co-authored-by: Fijxu <fijxu@nadeko.net>
Co-authored-by: Émilien (perso) <4016501+unixfox@users.noreply.github.com>
* Replace deprecated `blocking` property of `Socket`
This replaces the deprecated argument `blocking` and uses
`Socket.set_blocking(fd, value)` instead.
Fixes a warning in the compiler
https://github.com/crystal-lang/crystal/pull/16033
* Upgrade to upstream
* chore: only Socket.set_blocking for > 1.18
---------
Co-authored-by: Emilien <4016501+unixfox@users.noreply.github.com>
Summing the sizes of each cached file every time is very inefficient.
Instead we can simply store the cache size in an constant and increase
it everytime a file is added into the cache.
Running `crystal spec` without a file argument essentially produces one
big program that combines every single spec file, their imports, and
the files that those imports themselves depend on. Most of the types
within this combined program will get ignored by the compiler due to a
lack of any calls to them from the spec files.
But for some types, partially the HTTP module ones, using them within
the spec files will suddenly make the compiler enable a bunch of
previously ignored code. And those code will suddenly require the
presence of additional types, constants, etc. This not only make it
annoying for getting the specs working but also makes it difficult to
isolate behaviors for testing.
The `static_assets_handler_spec.cr` causes this issue and so will be
marked as an isolated spec for now. In the future all of the tests
should be organized into independent groupings similar to how the
Crystal compiler splits their tests into std, compiler, primitives and
interpreter.
Overriding `#call` or patching out `serve_file_compressed` provides
only minimal benefits over the ease of maintenance granted by only
overriding what we need to for the caching behavior.
Kemal's subclass of the stdlib `HTTP::StaticFileHandler` is not as
maintained as its parent, and so misses out on many enhancements and bug
fixes from upstream, which unfortunately also includes the patches for
security vulnerabilities...
Though this isn't necessarily Kemal's fault since the bulk of the stdlib
handler's logic was done in a single big method, making any changes hard
to maintain. This was fixed in Crystal 1.17.0 where the handler
was refactored into many private methods, making it easier for an
inheriting type to implement custom behaviors while still leveraging
much of the pre-existing code.
Since we don't actually use any of the Kemal specific features added by
`Kemal::StaticFileHandler`, there really isn't a reason to not just
create a new handler based upon the stdlib implementation instead which
will address the problems mentioned above.
This PR implements a new handler which inherits from the stdlib variant
and overrides the helper methods added in Crystal 1.17.0 to add the
caching behavior with minimal code changes. Since this new handler
depends on the code in Crystal 1.17.0, it will only be applied on
versions greater than or equal to 1.17.0. On older versions we'll
fallback to the current monkey patched `Kemal::StaticFileHandler`