Compare commits
1 Commits
dev-cache
...
dev-stream
| Author | SHA1 | Date | |
|---|---|---|---|
| eb37df7c3e |
@@ -1,4 +1,5 @@
|
|||||||
import './bootstrap.js';
|
import './bootstrap.js';
|
||||||
|
import Hls from "./vendor/hls.js/hls.js.index.js";
|
||||||
/*
|
/*
|
||||||
* Welcome to your app's main JavaScript file!
|
* Welcome to your app's main JavaScript file!
|
||||||
*
|
*
|
||||||
@@ -18,3 +19,29 @@ var observer = new MutationObserver(function(mutations) {
|
|||||||
|
|
||||||
observer.observe(document, {attributes: false, childList: true, characterData: false, subtree:true});
|
observer.observe(document, {attributes: false, childList: true, characterData: false, subtree:true});
|
||||||
|
|
||||||
|
document.addEventListener("DOMContentLoaded", () => {
|
||||||
|
const videoUrl = "http://127.0.0.1:11470/hlsv2/2b76fe2ec12c83d264076fb859923c5d/master.m3u8?mediaURL=https%3A%2F%2Ftorrentio.strem.fun%2Frealdebrid%2FQYYBR7OSQ4VEFKWASDEZ2B4VO67KHUJY6IWOT7HHA7ATXO7QCYDQ%2F6bf1938db882f6fcbb0dafa6e7326230e7f4eae0%2Fnull%2F3%2FSurvivor.S48E01.1080p.HEVC.x265-MeGusta.mkv%26videoCodecs%3Dh264%26videoCodecs%3Dh265%26videoCodecs%3Dhevc%26videoCodecs%3Dvp9%26audioCodecs%3Daac%26audioCodecs%3Dmp3%26audioCodecs%3Dopus%26maxAudioChannels%3D2";
|
||||||
|
|
||||||
|
var video = document.getElementById('video');
|
||||||
|
if (Hls.isSupported()) {
|
||||||
|
var hls = new Hls({
|
||||||
|
debug: true,
|
||||||
|
});
|
||||||
|
hls.loadSource(videoUrl);
|
||||||
|
hls.attachMedia(video);
|
||||||
|
hls.on(Hls.Events.MEDIA_ATTACHED, function () {
|
||||||
|
video.muted = true;
|
||||||
|
video.play();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// hls.js is not supported on platforms that do not have Media Source Extensions (MSE) enabled.
|
||||||
|
// When the browser has built-in HLS support (check using `canPlayType`), we can provide an HLS manifest (i.e. .m3u8 URL) directly to the video element through the `src` property.
|
||||||
|
// This is using the built-in support of the plain video element, without using hls.js.
|
||||||
|
else if (video.canPlayType('application/vnd.apple.mpegurl')) {
|
||||||
|
video.src = videoUrl;
|
||||||
|
video.addEventListener('canplay', function () {
|
||||||
|
video.play();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -1,30 +0,0 @@
|
|||||||
import { Controller } from '@hotwired/stimulus';
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The following line makes this controller "lazy": it won't be downloaded until needed
|
|
||||||
* See https://symfony.com/bundles/StimulusBundle/current/index.html#lazy-stimulus-controllers
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* stimulusFetch: 'lazy' */
|
|
||||||
export default class extends Controller {
|
|
||||||
initialize() {}
|
|
||||||
|
|
||||||
connect() {}
|
|
||||||
|
|
||||||
disconnect() {}
|
|
||||||
|
|
||||||
async clearAll() {
|
|
||||||
let response = await fetch('/api/torrentio/cache', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
'Accept': 'application/json',
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
type: 'torrentio',
|
|
||||||
mediaType: 'tvshows',
|
|
||||||
})
|
|
||||||
});
|
|
||||||
response = await response.json()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -12,7 +12,6 @@ export default class extends Controller {
|
|||||||
filename: String,
|
filename: String,
|
||||||
mediaType: String,
|
mediaType: String,
|
||||||
imdbId: String,
|
imdbId: String,
|
||||||
episodeId: String
|
|
||||||
}
|
}
|
||||||
|
|
||||||
download() {
|
download() {
|
||||||
@@ -28,7 +27,6 @@ export default class extends Controller {
|
|||||||
filename: this.filenameValue,
|
filename: this.filenameValue,
|
||||||
mediaType: this.mediaTypeValue,
|
mediaType: this.mediaTypeValue,
|
||||||
imdbId: this.imdbIdValue,
|
imdbId: this.imdbIdValue,
|
||||||
episodeId: this.episodeIdValue
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.then(res => res.json())
|
.then(res => res.json())
|
||||||
|
|||||||
@@ -25,13 +25,6 @@
|
|||||||
.alert-warning {
|
.alert-warning {
|
||||||
@apply bg-yellow-500/70 hover:bg-yellow-600 border-yellow-400 text-black
|
@apply bg-yellow-500/70 hover:bg-yellow-600 border-yellow-400 text-black
|
||||||
}
|
}
|
||||||
|
|
||||||
.primary-btn {
|
|
||||||
@apply px-1 py-1 rounded-md bg-orange-500 self-end text-white w-16 ml-2 hover:bg-orange-600
|
|
||||||
}
|
|
||||||
.secondary-btn {
|
|
||||||
@apply px-1 py-1 rounded-md self-end w-16 hover:bg-stone-100
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Prevent scrolling while dialog is open */
|
/* Prevent scrolling while dialog is open */
|
||||||
|
|||||||
@@ -22,7 +22,6 @@
|
|||||||
"nihilarr/parse-torrent-name": "^0.0.1",
|
"nihilarr/parse-torrent-name": "^0.0.1",
|
||||||
"nyholm/psr7": "*",
|
"nyholm/psr7": "*",
|
||||||
"p3k/emoji-detector": "^1.2",
|
"p3k/emoji-detector": "^1.2",
|
||||||
"php-http/cache-plugin": "^2.0",
|
|
||||||
"php-tmdb/api": "^4.1",
|
"php-tmdb/api": "^4.1",
|
||||||
"predis/predis": "^2.4",
|
"predis/predis": "^2.4",
|
||||||
"runtime/frankenphp-symfony": "^0.2.0",
|
"runtime/frankenphp-symfony": "^0.2.0",
|
||||||
|
|||||||
370
composer.lock
generated
370
composer.lock
generated
@@ -4,7 +4,7 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "67e697578f7237f60726c0d93bfed001",
|
"content-hash": "3b0840f4e60d44d341c934f6ca153944",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "1tomany/rich-bundle",
|
"name": "1tomany/rich-bundle",
|
||||||
@@ -285,72 +285,6 @@
|
|||||||
},
|
},
|
||||||
"time": "2021-10-17T22:52:23+00:00"
|
"time": "2021-10-17T22:52:23+00:00"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "clue/stream-filter",
|
|
||||||
"version": "v1.7.0",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/clue/stream-filter.git",
|
|
||||||
"reference": "049509fef80032cb3f051595029ab75b49a3c2f7"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/clue/stream-filter/zipball/049509fef80032cb3f051595029ab75b49a3c2f7",
|
|
||||||
"reference": "049509fef80032cb3f051595029ab75b49a3c2f7",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"php": ">=5.3"
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36"
|
|
||||||
},
|
|
||||||
"type": "library",
|
|
||||||
"autoload": {
|
|
||||||
"files": [
|
|
||||||
"src/functions_include.php"
|
|
||||||
],
|
|
||||||
"psr-4": {
|
|
||||||
"Clue\\StreamFilter\\": "src/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"MIT"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Christian Lück",
|
|
||||||
"email": "christian@clue.engineering"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "A simple and modern approach to stream filtering in PHP",
|
|
||||||
"homepage": "https://github.com/clue/stream-filter",
|
|
||||||
"keywords": [
|
|
||||||
"bucket brigade",
|
|
||||||
"callback",
|
|
||||||
"filter",
|
|
||||||
"php_user_filter",
|
|
||||||
"stream",
|
|
||||||
"stream_filter_append",
|
|
||||||
"stream_filter_register"
|
|
||||||
],
|
|
||||||
"support": {
|
|
||||||
"issues": "https://github.com/clue/stream-filter/issues",
|
|
||||||
"source": "https://github.com/clue/stream-filter/tree/v1.7.0"
|
|
||||||
},
|
|
||||||
"funding": [
|
|
||||||
{
|
|
||||||
"url": "https://clue.engineering/support",
|
|
||||||
"type": "custom"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"url": "https://github.com/clue",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"time": "2023-12-20T15:40:13+00:00"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "composer/semver",
|
"name": "composer/semver",
|
||||||
"version": "3.4.3",
|
"version": "3.4.3",
|
||||||
@@ -2931,130 +2865,6 @@
|
|||||||
},
|
},
|
||||||
"time": "2024-02-19T18:29:05+00:00"
|
"time": "2024-02-19T18:29:05+00:00"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "php-http/cache-plugin",
|
|
||||||
"version": "2.0.1",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/php-http/cache-plugin.git",
|
|
||||||
"reference": "5c591e9e04602cec12307e3e1be3abefeb005e29"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/php-http/cache-plugin/zipball/5c591e9e04602cec12307e3e1be3abefeb005e29",
|
|
||||||
"reference": "5c591e9e04602cec12307e3e1be3abefeb005e29",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"php": "^7.1 || ^8.0",
|
|
||||||
"php-http/client-common": "^1.9 || ^2.0",
|
|
||||||
"psr/cache": "^1.0 || ^2.0 || ^3.0",
|
|
||||||
"psr/http-factory-implementation": "^1.0",
|
|
||||||
"symfony/options-resolver": "^2.6 || ^3.0 || ^4.0 || ^5.0 || ^6.0 || ^7.0"
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"nyholm/psr7": "^1.6.1",
|
|
||||||
"phpspec/phpspec": "^5.1 || ^6.0 || ^7.0"
|
|
||||||
},
|
|
||||||
"type": "library",
|
|
||||||
"autoload": {
|
|
||||||
"psr-4": {
|
|
||||||
"Http\\Client\\Common\\Plugin\\": "src/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"MIT"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Márk Sági-Kazár",
|
|
||||||
"email": "mark.sagikazar@gmail.com"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "PSR-6 Cache plugin for HTTPlug",
|
|
||||||
"homepage": "http://httplug.io",
|
|
||||||
"keywords": [
|
|
||||||
"cache",
|
|
||||||
"http",
|
|
||||||
"httplug",
|
|
||||||
"plugin"
|
|
||||||
],
|
|
||||||
"support": {
|
|
||||||
"issues": "https://github.com/php-http/cache-plugin/issues",
|
|
||||||
"source": "https://github.com/php-http/cache-plugin/tree/2.0.1"
|
|
||||||
},
|
|
||||||
"time": "2024-10-02T11:25:38+00:00"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "php-http/client-common",
|
|
||||||
"version": "2.7.2",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/php-http/client-common.git",
|
|
||||||
"reference": "0cfe9858ab9d3b213041b947c881d5b19ceeca46"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/php-http/client-common/zipball/0cfe9858ab9d3b213041b947c881d5b19ceeca46",
|
|
||||||
"reference": "0cfe9858ab9d3b213041b947c881d5b19ceeca46",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"php": "^7.1 || ^8.0",
|
|
||||||
"php-http/httplug": "^2.0",
|
|
||||||
"php-http/message": "^1.6",
|
|
||||||
"psr/http-client": "^1.0",
|
|
||||||
"psr/http-factory": "^1.0",
|
|
||||||
"psr/http-message": "^1.0 || ^2.0",
|
|
||||||
"symfony/options-resolver": "~4.0.15 || ~4.1.9 || ^4.2.1 || ^5.0 || ^6.0 || ^7.0",
|
|
||||||
"symfony/polyfill-php80": "^1.17"
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"doctrine/instantiator": "^1.1",
|
|
||||||
"guzzlehttp/psr7": "^1.4",
|
|
||||||
"nyholm/psr7": "^1.2",
|
|
||||||
"phpspec/phpspec": "^5.1 || ^6.3 || ^7.1",
|
|
||||||
"phpspec/prophecy": "^1.10.2",
|
|
||||||
"phpunit/phpunit": "^7.5.20 || ^8.5.33 || ^9.6.7"
|
|
||||||
},
|
|
||||||
"suggest": {
|
|
||||||
"ext-json": "To detect JSON responses with the ContentTypePlugin",
|
|
||||||
"ext-libxml": "To detect XML responses with the ContentTypePlugin",
|
|
||||||
"php-http/cache-plugin": "PSR-6 Cache plugin",
|
|
||||||
"php-http/logger-plugin": "PSR-3 Logger plugin",
|
|
||||||
"php-http/stopwatch-plugin": "Symfony Stopwatch plugin"
|
|
||||||
},
|
|
||||||
"type": "library",
|
|
||||||
"autoload": {
|
|
||||||
"psr-4": {
|
|
||||||
"Http\\Client\\Common\\": "src/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"MIT"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Márk Sági-Kazár",
|
|
||||||
"email": "mark.sagikazar@gmail.com"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "Common HTTP Client implementations and tools for HTTPlug",
|
|
||||||
"homepage": "http://httplug.io",
|
|
||||||
"keywords": [
|
|
||||||
"client",
|
|
||||||
"common",
|
|
||||||
"http",
|
|
||||||
"httplug"
|
|
||||||
],
|
|
||||||
"support": {
|
|
||||||
"issues": "https://github.com/php-http/client-common/issues",
|
|
||||||
"source": "https://github.com/php-http/client-common/tree/2.7.2"
|
|
||||||
},
|
|
||||||
"time": "2024-09-24T06:21:48+00:00"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "php-http/discovery",
|
"name": "php-http/discovery",
|
||||||
"version": "1.20.0",
|
"version": "1.20.0",
|
||||||
@@ -3134,184 +2944,6 @@
|
|||||||
},
|
},
|
||||||
"time": "2024-10-02T11:20:13+00:00"
|
"time": "2024-10-02T11:20:13+00:00"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "php-http/httplug",
|
|
||||||
"version": "2.4.1",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/php-http/httplug.git",
|
|
||||||
"reference": "5cad731844891a4c282f3f3e1b582c46839d22f4"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/php-http/httplug/zipball/5cad731844891a4c282f3f3e1b582c46839d22f4",
|
|
||||||
"reference": "5cad731844891a4c282f3f3e1b582c46839d22f4",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"php": "^7.1 || ^8.0",
|
|
||||||
"php-http/promise": "^1.1",
|
|
||||||
"psr/http-client": "^1.0",
|
|
||||||
"psr/http-message": "^1.0 || ^2.0"
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"friends-of-phpspec/phpspec-code-coverage": "^4.1 || ^5.0 || ^6.0",
|
|
||||||
"phpspec/phpspec": "^5.1 || ^6.0 || ^7.0"
|
|
||||||
},
|
|
||||||
"type": "library",
|
|
||||||
"autoload": {
|
|
||||||
"psr-4": {
|
|
||||||
"Http\\Client\\": "src/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"MIT"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Eric GELOEN",
|
|
||||||
"email": "geloen.eric@gmail.com"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Márk Sági-Kazár",
|
|
||||||
"email": "mark.sagikazar@gmail.com",
|
|
||||||
"homepage": "https://sagikazarmark.hu"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "HTTPlug, the HTTP client abstraction for PHP",
|
|
||||||
"homepage": "http://httplug.io",
|
|
||||||
"keywords": [
|
|
||||||
"client",
|
|
||||||
"http"
|
|
||||||
],
|
|
||||||
"support": {
|
|
||||||
"issues": "https://github.com/php-http/httplug/issues",
|
|
||||||
"source": "https://github.com/php-http/httplug/tree/2.4.1"
|
|
||||||
},
|
|
||||||
"time": "2024-09-23T11:39:58+00:00"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "php-http/message",
|
|
||||||
"version": "1.16.2",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/php-http/message.git",
|
|
||||||
"reference": "06dd5e8562f84e641bf929bfe699ee0f5ce8080a"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/php-http/message/zipball/06dd5e8562f84e641bf929bfe699ee0f5ce8080a",
|
|
||||||
"reference": "06dd5e8562f84e641bf929bfe699ee0f5ce8080a",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"clue/stream-filter": "^1.5",
|
|
||||||
"php": "^7.2 || ^8.0",
|
|
||||||
"psr/http-message": "^1.1 || ^2.0"
|
|
||||||
},
|
|
||||||
"provide": {
|
|
||||||
"php-http/message-factory-implementation": "1.0"
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"ergebnis/composer-normalize": "^2.6",
|
|
||||||
"ext-zlib": "*",
|
|
||||||
"guzzlehttp/psr7": "^1.0 || ^2.0",
|
|
||||||
"laminas/laminas-diactoros": "^2.0 || ^3.0",
|
|
||||||
"php-http/message-factory": "^1.0.2",
|
|
||||||
"phpspec/phpspec": "^5.1 || ^6.3 || ^7.1",
|
|
||||||
"slim/slim": "^3.0"
|
|
||||||
},
|
|
||||||
"suggest": {
|
|
||||||
"ext-zlib": "Used with compressor/decompressor streams",
|
|
||||||
"guzzlehttp/psr7": "Used with Guzzle PSR-7 Factories",
|
|
||||||
"laminas/laminas-diactoros": "Used with Diactoros Factories",
|
|
||||||
"slim/slim": "Used with Slim Framework PSR-7 implementation"
|
|
||||||
},
|
|
||||||
"type": "library",
|
|
||||||
"autoload": {
|
|
||||||
"files": [
|
|
||||||
"src/filters.php"
|
|
||||||
],
|
|
||||||
"psr-4": {
|
|
||||||
"Http\\Message\\": "src/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"MIT"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Márk Sági-Kazár",
|
|
||||||
"email": "mark.sagikazar@gmail.com"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "HTTP Message related tools",
|
|
||||||
"homepage": "http://php-http.org",
|
|
||||||
"keywords": [
|
|
||||||
"http",
|
|
||||||
"message",
|
|
||||||
"psr-7"
|
|
||||||
],
|
|
||||||
"support": {
|
|
||||||
"issues": "https://github.com/php-http/message/issues",
|
|
||||||
"source": "https://github.com/php-http/message/tree/1.16.2"
|
|
||||||
},
|
|
||||||
"time": "2024-10-02T11:34:13+00:00"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "php-http/promise",
|
|
||||||
"version": "1.3.1",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/php-http/promise.git",
|
|
||||||
"reference": "fc85b1fba37c169a69a07ef0d5a8075770cc1f83"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/php-http/promise/zipball/fc85b1fba37c169a69a07ef0d5a8075770cc1f83",
|
|
||||||
"reference": "fc85b1fba37c169a69a07ef0d5a8075770cc1f83",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"php": "^7.1 || ^8.0"
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"friends-of-phpspec/phpspec-code-coverage": "^4.3.2 || ^6.3",
|
|
||||||
"phpspec/phpspec": "^5.1.2 || ^6.2 || ^7.4"
|
|
||||||
},
|
|
||||||
"type": "library",
|
|
||||||
"autoload": {
|
|
||||||
"psr-4": {
|
|
||||||
"Http\\Promise\\": "src/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"MIT"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Joel Wurtz",
|
|
||||||
"email": "joel.wurtz@gmail.com"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Márk Sági-Kazár",
|
|
||||||
"email": "mark.sagikazar@gmail.com"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "Promise used for asynchronous HTTP requests",
|
|
||||||
"homepage": "http://httplug.io",
|
|
||||||
"keywords": [
|
|
||||||
"promise"
|
|
||||||
],
|
|
||||||
"support": {
|
|
||||||
"issues": "https://github.com/php-http/promise/issues",
|
|
||||||
"source": "https://github.com/php-http/promise/tree/1.3.1"
|
|
||||||
},
|
|
||||||
"time": "2024-03-15T13:55:21+00:00"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "php-tmdb/api",
|
"name": "php-tmdb/api",
|
||||||
"version": "4.1.3",
|
"version": "4.1.3",
|
||||||
|
|||||||
@@ -15,11 +15,5 @@ framework:
|
|||||||
#app: cache.adapter.apcu
|
#app: cache.adapter.apcu
|
||||||
|
|
||||||
# Namespaced pools use the above "app" backend by default
|
# Namespaced pools use the above "app" backend by default
|
||||||
pools:
|
#pools:
|
||||||
torrentio.cache:
|
#my.dedicated.cache: null
|
||||||
adapter: cache.app
|
|
||||||
tmdb.cache:
|
|
||||||
adapter: cache.app
|
|
||||||
default_lifetime: 2592000
|
|
||||||
page.cache:
|
|
||||||
adapter: cache.app
|
|
||||||
|
|||||||
@@ -29,12 +29,3 @@ controllersMonitor:
|
|||||||
type: attribute
|
type: attribute
|
||||||
defaults:
|
defaults:
|
||||||
schemes: ['https']
|
schemes: ['https']
|
||||||
|
|
||||||
controllersTorrentio:
|
|
||||||
resource:
|
|
||||||
path: ../src/Torrentio/Framework/Controller
|
|
||||||
namespace: App\Torrentio\Framework\Controller
|
|
||||||
type: attribute
|
|
||||||
defaults:
|
|
||||||
schemes: [ 'https' ]
|
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ DATABASE_URL="mysql://root:password@database:3306/app?serverVersion=10.6.19.2-Ma
|
|||||||
# Popular Movies and TV Shows section.
|
# Popular Movies and TV Shows section.
|
||||||
#TMDB_API=
|
#TMDB_API=
|
||||||
|
|
||||||
REAL_DEBRID_KEY=""
|
REAL_DEBRID_KEY="QYYBR7OSQ4VEFKWASDEZ2B4VO67KHUJY6IWOT7HHA7ATXO7QCYDQ"
|
||||||
TMDB_API=eyJhbGciOiJIUzI1NiJ9.eyJhdWQiOiI0ZTJjYjJhOGUzOGJhNjdiNjVhOGU1NGM0ZWI1MzhmOCIsIm5iZiI6MTczNzkyNjA0NC41NjQsInN1YiI6IjY3OTZhNTljYzdiMDFiNzJjNzIzZWM5YiIsInNjb3BlcyI6WyJhcGlfcmVhZCJdLCJ2ZXJzaW9uIjoxfQ.e8DbNe9qrSBC1y-ANRv-VWBAtls-ZS2r7aNCiI68mpw
|
TMDB_API=eyJhbGciOiJIUzI1NiJ9.eyJhdWQiOiI0ZTJjYjJhOGUzOGJhNjdiNjVhOGU1NGM0ZWI1MzhmOCIsIm5iZiI6MTczNzkyNjA0NC41NjQsInN1YiI6IjY3OTZhNTljYzdiMDFiNzJjNzIzZWM5YiIsInNjb3BlcyI6WyJhcGlfcmVhZCJdLCJ2ZXJzaW9uIjoxfQ.e8DbNe9qrSBC1y-ANRv-VWBAtls-ZS2r7aNCiI68mpw
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -11,13 +11,6 @@ services:
|
|||||||
- '8006:80'
|
- '8006:80'
|
||||||
env_file:
|
env_file:
|
||||||
- .env
|
- .env
|
||||||
volumes:
|
|
||||||
- /mnt/media/downloads/movies:/var/download/movies
|
|
||||||
- /mnt/media/downloads/tvshows:/var/download/tvshows
|
|
||||||
environment:
|
|
||||||
TZ: America/Chicago
|
|
||||||
MERCURE_PUBLISHER_JWT_KEY: '!ChangeThisMercureHubJWTSecretKey!'
|
|
||||||
MERCURE_SUBSCRIBER_JWT_KEY: '!ChangeThisMercureHubJWTSecretKey!'
|
|
||||||
depends_on:
|
depends_on:
|
||||||
database:
|
database:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
@@ -34,8 +27,6 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- /mnt/media/downloads/movies:/var/download/movies
|
- /mnt/media/downloads/movies:/var/download/movies
|
||||||
- /mnt/media/downloads/tvshows:/var/download/tvshows
|
- /mnt/media/downloads/tvshows:/var/download/tvshows
|
||||||
environment:
|
|
||||||
TZ: America/Chicago
|
|
||||||
command: -vvv
|
command: -vvv
|
||||||
env_file:
|
env_file:
|
||||||
- .env
|
- .env
|
||||||
@@ -52,17 +43,35 @@ services:
|
|||||||
scheduler:
|
scheduler:
|
||||||
image: code.caldwell.digital/home/torsearch-scheduler:latest
|
image: code.caldwell.digital/home/torsearch-scheduler:latest
|
||||||
volumes:
|
volumes:
|
||||||
- /mnt/media/downloads/movies:/var/download/movies
|
- ./downloads:/var/download
|
||||||
- /mnt/media/downloads/tvshows:/var/download/tvshows
|
|
||||||
env_file:
|
env_file:
|
||||||
- .env
|
- .env
|
||||||
environment:
|
|
||||||
TZ: America/Chicago
|
|
||||||
restart: always
|
restart: always
|
||||||
depends_on:
|
depends_on:
|
||||||
app:
|
app:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
|
|
||||||
|
# This container facilitates viewing the progress of downloads
|
||||||
|
# in realtime. It also handles sending alerts and notifications.
|
||||||
|
# The MERCURE_PUBLISHER_JWT key & MERCURE_SUBSCRIBER_JWT_KEY should
|
||||||
|
# match the MERCURE_JWT_SECRET environment variable.
|
||||||
|
mercure:
|
||||||
|
image: dunglas/mercure
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "3001:80"
|
||||||
|
environment:
|
||||||
|
SERVER_NAME: ':80'
|
||||||
|
MERCURE_PUBLISHER_JWT_KEY: '!ChangeThisMercureHubJWTSecretKey!'
|
||||||
|
MERCURE_SUBSCRIBER_JWT_KEY: '!ChangeThisMercureHubJWTSecretKey!'
|
||||||
|
MERCURE_EXTRA_DIRECTIVES: |
|
||||||
|
cors_origins *
|
||||||
|
anonymous
|
||||||
|
command: /usr/bin/caddy run --config /etc/caddy/dev.Caddyfile
|
||||||
|
volumes:
|
||||||
|
- mercure_data:/data
|
||||||
|
- mercure_config:/config
|
||||||
|
|
||||||
database:
|
database:
|
||||||
image: mariadb:10.11.2
|
image: mariadb:10.11.2
|
||||||
volumes:
|
volumes:
|
||||||
|
|||||||
@@ -40,4 +40,7 @@ return [
|
|||||||
'stimulus-use' => [
|
'stimulus-use' => [
|
||||||
'version' => '0.52.2',
|
'version' => '0.52.2',
|
||||||
],
|
],
|
||||||
|
'hls.js' => [
|
||||||
|
'version' => '1.6.5',
|
||||||
|
],
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -40,6 +40,8 @@ final class SearchController extends AbstractController
|
|||||||
): Response {
|
): Response {
|
||||||
$result = $this->getMediaInfoHandler->handle($input->toCommand());
|
$result = $this->getMediaInfoHandler->handle($input->toCommand());
|
||||||
|
|
||||||
|
// $this->warmDownloadOptionCache($result->media);
|
||||||
|
|
||||||
return $this->render('search/result.html.twig', [
|
return $this->render('search/result.html.twig', [
|
||||||
'results' => $result,
|
'results' => $result,
|
||||||
'filter' => [
|
'filter' => [
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ use Symfony\Component\HttpFoundation\Response;
|
|||||||
use Symfony\Component\Routing\Attribute\Route;
|
use Symfony\Component\Routing\Attribute\Route;
|
||||||
use Symfony\Contracts\Cache\CacheInterface;
|
use Symfony\Contracts\Cache\CacheInterface;
|
||||||
use Symfony\Contracts\Cache\ItemInterface;
|
use Symfony\Contracts\Cache\ItemInterface;
|
||||||
use Symfony\Contracts\Cache\TagAwareCacheInterface;
|
|
||||||
|
|
||||||
final class TorrentioController extends AbstractController
|
final class TorrentioController extends AbstractController
|
||||||
{
|
{
|
||||||
@@ -26,7 +25,7 @@ final class TorrentioController extends AbstractController
|
|||||||
) {}
|
) {}
|
||||||
|
|
||||||
#[Route('/torrentio/movies/{tmdbId}/{imdbId}', name: 'app_torrentio_movies')]
|
#[Route('/torrentio/movies/{tmdbId}/{imdbId}', name: 'app_torrentio_movies')]
|
||||||
public function movieOptions(GetMovieOptionsInput $input, TagAwareCacheInterface $pageCache): Response
|
public function movieOptions(GetMovieOptionsInput $input, CacheInterface $cache): Response
|
||||||
{
|
{
|
||||||
$cacheId = sprintf(
|
$cacheId = sprintf(
|
||||||
"page.torrentio.movies.%s.%s",
|
"page.torrentio.movies.%s.%s",
|
||||||
@@ -34,29 +33,17 @@ final class TorrentioController extends AbstractController
|
|||||||
$input->imdbId
|
$input->imdbId
|
||||||
);
|
);
|
||||||
|
|
||||||
try {
|
return $cache->get($cacheId, function (ItemInterface $item) use ($input) {
|
||||||
return $pageCache->get($cacheId, function (ItemInterface $item) use ($input) {
|
$item->expiresAt(Carbon::now()->addHour()->setMinute(0)->setSecond(0));
|
||||||
$item->expiresAt(Carbon::now()->addHour()->setMinute(0)->setSecond(0));
|
$results = $this->getMovieOptionsHandler->handle($input->toCommand());
|
||||||
$item->tag(['page', 'page.torrentio', 'page.torrentio.movies', "page.torrentio.movies.$input->tmdbId.$input->imdbId", 'torrentio', 'torrentio.movies', "torrentio.movies.$input->tmdbId.$input->imdbId"]);
|
return $this->render('torrentio/movies.html.twig', [
|
||||||
$results = $this->getMovieOptionsHandler->handle($input->toCommand());
|
'results' => $results,
|
||||||
return $this->render('torrentio/movies.html.twig', [
|
]);
|
||||||
'results' => $results,
|
});
|
||||||
]);
|
|
||||||
});
|
|
||||||
} catch (TorrentioRateLimitException $exception) {
|
|
||||||
$this->broadcaster->alert('Warning', 'Torrentio has rate limited your requests. Please wait a few minutes before trying again.', 'warning');
|
|
||||||
return $this->render('bare.html.twig',
|
|
||||||
[],
|
|
||||||
new Response('Too many requests',
|
|
||||||
Response::HTTP_TOO_MANY_REQUESTS,
|
|
||||||
['Retry-After' => 4000]
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[Route('/torrentio/tvshows/{tmdbId}/{imdbId}/{season?}/{episode?}', name: 'app_torrentio_tvshows')]
|
#[Route('/torrentio/tvshows/{tmdbId}/{imdbId}/{season?}/{episode?}', name: 'app_torrentio_tvshows')]
|
||||||
public function tvShowOptions(GetTvShowOptionsInput $input, TagAwareCacheInterface $pageCache): Response
|
public function tvShowOptions(GetTvShowOptionsInput $input, CacheInterface $cache): Response
|
||||||
{
|
{
|
||||||
$cacheId = sprintf(
|
$cacheId = sprintf(
|
||||||
"page.torrentio.tvshows.%s.%s.%s.%s",
|
"page.torrentio.tvshows.%s.%s.%s.%s",
|
||||||
@@ -67,9 +54,8 @@ final class TorrentioController extends AbstractController
|
|||||||
);
|
);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return $pageCache->get($cacheId, function (ItemInterface $item) use ($input) {
|
return $cache->get($cacheId, function (ItemInterface $item) use ($input) {
|
||||||
$item->expiresAt(Carbon::now()->addHour()->setMinute(0)->setSecond(0));
|
$item->expiresAt(Carbon::now()->addHour()->setMinute(0)->setSecond(0));
|
||||||
$item->tag(['page', 'page.torrentio', 'page.torrentio.tvshows', "page.torrentio.tvshows.$input->tmdbId.$input->imdbId", "page.torrentio.tvshows.$input->tmdbId.$input->imdbId.$input->season", "page.torrentio.tvshows.$input->tmdbId.$input->imdbId.$input->season.$input->episode", 'torrentio', 'torrentio.tvshows', "torrentio.tvshows.$input->tmdbId.$input->imdbId", "torrentio.tvshows.$input->tmdbId.$input->imdbId.$input->season", "torrentio.tvshows.$input->tmdbId.$input->imdbId.$input->season.$input->episode", $input->imdbId, $input->tmdbId]);
|
|
||||||
$results = $this->getTvShowOptionsHandler->handle($input->toCommand());
|
$results = $this->getTvShowOptionsHandler->handle($input->toCommand());
|
||||||
return $this->render('torrentio/tvshows.html.twig', [
|
return $this->render('torrentio/tvshows.html.twig', [
|
||||||
'results' => $results,
|
'results' => $results,
|
||||||
|
|||||||
@@ -26,9 +26,6 @@ class DownloadMediaInput implements InputInterface
|
|||||||
#[SourceRequest('imdbId')]
|
#[SourceRequest('imdbId')]
|
||||||
public string $imdbId,
|
public string $imdbId,
|
||||||
|
|
||||||
#[SourceRequest('episodeId', nullify: true)]
|
|
||||||
public ?string $episodeId = null,
|
|
||||||
|
|
||||||
public ?int $userId = null,
|
public ?int $userId = null,
|
||||||
|
|
||||||
public ?int $downloadId = null,
|
public ?int $downloadId = null,
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ use App\Download\Action\Input\PauseDownloadInput;
|
|||||||
use App\Download\Action\Input\ResumeDownloadInput;
|
use App\Download\Action\Input\ResumeDownloadInput;
|
||||||
use App\Download\Framework\Repository\DownloadRepository;
|
use App\Download\Framework\Repository\DownloadRepository;
|
||||||
use App\Util\Broadcaster;
|
use App\Util\Broadcaster;
|
||||||
use Nihilarr\PTN;
|
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Symfony\Component\Messenger\MessageBusInterface;
|
use Symfony\Component\Messenger\MessageBusInterface;
|
||||||
@@ -29,13 +28,6 @@ class ApiController extends AbstractController
|
|||||||
public function download(
|
public function download(
|
||||||
DownloadMediaInput $input,
|
DownloadMediaInput $input,
|
||||||
): Response {
|
): Response {
|
||||||
$ptn = (object) new Ptn()->parse($input->filename);
|
|
||||||
if ($input->mediaType === "tvshows" &&
|
|
||||||
!property_exists($ptn, 'episode') && !property_exists($ptn, 'season')
|
|
||||||
) {
|
|
||||||
$input->filename = $input->episodeId . '_' . $input->filename;
|
|
||||||
}
|
|
||||||
|
|
||||||
$download = $this->downloadRepository->insert(
|
$download = $this->downloadRepository->insert(
|
||||||
$this->getUser(),
|
$this->getUser(),
|
||||||
$input->url,
|
$input->url,
|
||||||
|
|||||||
@@ -2,13 +2,17 @@
|
|||||||
|
|
||||||
namespace App\Monitor\Framework\Controller;
|
namespace App\Monitor\Framework\Controller;
|
||||||
|
|
||||||
|
use App\Download\Action\Input\DeleteDownloadInput;
|
||||||
use App\Monitor\Action\Handler\AddMonitorHandler;
|
use App\Monitor\Action\Handler\AddMonitorHandler;
|
||||||
use App\Monitor\Action\Handler\DeleteMonitorHandler;
|
use App\Monitor\Action\Handler\DeleteMonitorHandler;
|
||||||
use App\Monitor\Action\Input\AddMonitorInput;
|
use App\Monitor\Action\Input\AddMonitorInput;
|
||||||
use App\Monitor\Action\Input\DeleteMonitorInput;
|
use App\Monitor\Action\Input\DeleteMonitorInput;
|
||||||
use App\Util\Broadcaster;
|
use App\Util\Broadcaster;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
|
use Symfony\Bundle\SecurityBundle\Security;
|
||||||
|
use Symfony\Component\DependencyInjection\Attribute\Autowire;
|
||||||
use Symfony\Component\Mercure\HubInterface;
|
use Symfony\Component\Mercure\HubInterface;
|
||||||
|
use Symfony\Component\Mercure\Update;
|
||||||
use Symfony\Component\Routing\Attribute\Route;
|
use Symfony\Component\Routing\Attribute\Route;
|
||||||
|
|
||||||
class ApiController extends AbstractController
|
class ApiController extends AbstractController
|
||||||
@@ -42,9 +46,19 @@ class ApiController extends AbstractController
|
|||||||
public function deleteMonitor(
|
public function deleteMonitor(
|
||||||
DeleteMonitorInput $input,
|
DeleteMonitorInput $input,
|
||||||
DeleteMonitorHandler $handler,
|
DeleteMonitorHandler $handler,
|
||||||
|
HubInterface $hub,
|
||||||
) {
|
) {
|
||||||
$response = $handler->handle($input->toCommand());
|
$response = $handler->handle($input->toCommand());
|
||||||
|
|
||||||
|
$hub->publish(new Update(
|
||||||
|
'alerts',
|
||||||
|
$this->renderer->render('broadcast/Alert.stream.html.twig', [
|
||||||
|
'alert_id' => uniqid(),
|
||||||
|
'title' => 'Success',
|
||||||
|
'message' => "New monitor added for {$response->monitor->getTitle()}",
|
||||||
|
])
|
||||||
|
));
|
||||||
|
|
||||||
return $this->json([
|
return $this->json([
|
||||||
'status' => 200,
|
'status' => 200,
|
||||||
'message' => $response
|
'message' => $response
|
||||||
|
|||||||
@@ -6,8 +6,6 @@ use Aimeos\Map;
|
|||||||
use App\Enum\MediaType;
|
use App\Enum\MediaType;
|
||||||
use App\ValueObject\ResultFactory;
|
use App\ValueObject\ResultFactory;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Psr\Cache\CacheItemPoolInterface;
|
|
||||||
use Symfony\Component\Cache\Adapter\RedisAdapter;
|
|
||||||
use Symfony\Component\DependencyInjection\Attribute\Autowire;
|
use Symfony\Component\DependencyInjection\Attribute\Autowire;
|
||||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||||
use Symfony\Contracts\Cache\CacheInterface;
|
use Symfony\Contracts\Cache\CacheInterface;
|
||||||
@@ -15,7 +13,6 @@ use Symfony\Contracts\Cache\ItemInterface;
|
|||||||
use Tmdb\Api\Find;
|
use Tmdb\Api\Find;
|
||||||
use Tmdb\Client;
|
use Tmdb\Client;
|
||||||
use Tmdb\Event\BeforeRequestEvent;
|
use Tmdb\Event\BeforeRequestEvent;
|
||||||
use Tmdb\Event\Listener\Psr6CachedRequestListener;
|
|
||||||
use Tmdb\Event\Listener\Request\AcceptJsonRequestListener;
|
use Tmdb\Event\Listener\Request\AcceptJsonRequestListener;
|
||||||
use Tmdb\Event\Listener\Request\ApiTokenRequestListener;
|
use Tmdb\Event\Listener\Request\ApiTokenRequestListener;
|
||||||
use Tmdb\Event\Listener\Request\ContentTypeJsonRequestListener;
|
use Tmdb\Event\Listener\Request\ContentTypeJsonRequestListener;
|
||||||
@@ -44,7 +41,7 @@ class Tmdb
|
|||||||
const POSTER_IMG_PATH = "https://image.tmdb.org/t/p/w500";
|
const POSTER_IMG_PATH = "https://image.tmdb.org/t/p/w500";
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private readonly CacheItemPoolInterface $tmdbCache,
|
private readonly CacheInterface $cache,
|
||||||
private readonly EventDispatcherInterface $eventDispatcher,
|
private readonly EventDispatcherInterface $eventDispatcher,
|
||||||
#[Autowire(env: 'TMDB_API')] string $apiKey,
|
#[Autowire(env: 'TMDB_API')] string $apiKey,
|
||||||
) {
|
) {
|
||||||
@@ -75,13 +72,7 @@ class Tmdb
|
|||||||
/**
|
/**
|
||||||
* Required event listeners and events to be registered with the PSR-14 Event Dispatcher.
|
* Required event listeners and events to be registered with the PSR-14 Event Dispatcher.
|
||||||
*/
|
*/
|
||||||
$requestListener = new Psr6CachedRequestListener(
|
$requestListener = new RequestListener($this->client->getHttpClient(), $this->eventDispatcher);
|
||||||
$this->client->getHttpClient(),
|
|
||||||
$this->eventDispatcher,
|
|
||||||
$tmdbCache,
|
|
||||||
$this->client->getHttpClient()->getPsr17StreamFactory(),
|
|
||||||
[]
|
|
||||||
);
|
|
||||||
$this->eventDispatcher->addListener(RequestEvent::class, $requestListener);
|
$this->eventDispatcher->addListener(RequestEvent::class, $requestListener);
|
||||||
|
|
||||||
$apiTokenListener = new ApiTokenRequestListener($this->client->getToken());
|
$apiTokenListener = new ApiTokenRequestListener($this->client->getToken());
|
||||||
@@ -325,7 +316,7 @@ class Tmdb
|
|||||||
|
|
||||||
public function getImdbId(string $tmdbId, $mediaType)
|
public function getImdbId(string $tmdbId, $mediaType)
|
||||||
{
|
{
|
||||||
$externalIds = $this->tmdbCache->get("tmdb.externalIds.{$tmdbId}",
|
$externalIds = $this->cache->get("tmdb.externalIds.{$tmdbId}",
|
||||||
function (ItemInterface $item) use ($tmdbId, $mediaType) {
|
function (ItemInterface $item) use ($tmdbId, $mediaType) {
|
||||||
switch (MediaType::tryFrom($mediaType)->value) {
|
switch (MediaType::tryFrom($mediaType)->value) {
|
||||||
case MediaType::Movie->value:
|
case MediaType::Movie->value:
|
||||||
@@ -346,7 +337,7 @@ class Tmdb
|
|||||||
|
|
||||||
public function getImages($tmdbId, $mediaType)
|
public function getImages($tmdbId, $mediaType)
|
||||||
{
|
{
|
||||||
return $this->tmdbCache->get("tmdb.images.{$tmdbId}",
|
return $this->cache->get("tmdb.images.{$tmdbId}",
|
||||||
function (ItemInterface $item) use ($tmdbId, $mediaType) {
|
function (ItemInterface $item) use ($tmdbId, $mediaType) {
|
||||||
switch (MediaType::tryFrom($mediaType)->value) {
|
switch (MediaType::tryFrom($mediaType)->value) {
|
||||||
case MediaType::Movie->value:
|
case MediaType::Movie->value:
|
||||||
|
|||||||
@@ -1,18 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Torrentio\Action\Command;
|
|
||||||
|
|
||||||
use OneToMany\RichBundle\Contract\CommandInterface;
|
|
||||||
|
|
||||||
class DeleteCacheCommand implements CommandInterface
|
|
||||||
{
|
|
||||||
public function __construct(
|
|
||||||
public ?string $type = null,
|
|
||||||
public ?string $mediaType = null,
|
|
||||||
public ?string $tmdbId = null,
|
|
||||||
public ?string $imdbId = null,
|
|
||||||
public ?int $season = null,
|
|
||||||
public ?int $episode = null,
|
|
||||||
public ?array $tags = null,
|
|
||||||
) {}
|
|
||||||
}
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Torrentio\Action\Handler;
|
|
||||||
|
|
||||||
use Aimeos\Map;
|
|
||||||
use App\Torrentio\Action\Command\DeleteCacheCommand;
|
|
||||||
use App\Torrentio\Action\Result\DeleteCacheResult;
|
|
||||||
use OneToMany\RichBundle\Contract\CommandInterface;
|
|
||||||
use OneToMany\RichBundle\Contract\HandlerInterface;
|
|
||||||
use OneToMany\RichBundle\Contract\ResultInterface;
|
|
||||||
use Symfony\Contracts\Cache\TagAwareCacheInterface;
|
|
||||||
|
|
||||||
/** @implements HandlerInterface<DeleteCacheCommand, DeleteCacheResult> */
|
|
||||||
class DeleteCacheHandler implements HandlerInterface
|
|
||||||
{
|
|
||||||
public function __construct(
|
|
||||||
private readonly TagAwareCacheInterface $torrentioCache
|
|
||||||
) {}
|
|
||||||
|
|
||||||
public function handle(CommandInterface $command): ResultInterface
|
|
||||||
{
|
|
||||||
$input = Map::from((array) $command)
|
|
||||||
->filter(fn ($value, $key) => null !== $value && "" !== $value)
|
|
||||||
;
|
|
||||||
|
|
||||||
$cacheKey = null;
|
|
||||||
if ($input->has('type')) {
|
|
||||||
$cacheKey = $input->get('type');
|
|
||||||
|
|
||||||
if ($input->has('mediaType')) {
|
|
||||||
$cacheKey .= ".".$input->get('mediaType');
|
|
||||||
|
|
||||||
if ($input->has('tmdbId')) {
|
|
||||||
$cacheKey .= ".".$input->get('tmdbId');
|
|
||||||
|
|
||||||
if ($input->has('imdbId')) {
|
|
||||||
$cacheKey .= ".".$input->get('imdbId');
|
|
||||||
|
|
||||||
if ($input->has('season')) {
|
|
||||||
$cacheKey .= ".".$input->get('season');
|
|
||||||
|
|
||||||
if ($input->has('episode')) {
|
|
||||||
$cacheKey .= ".".$input->get('episode');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($cacheKey !== null) {
|
|
||||||
$this->torrentioCache->invalidateTags([$cacheKey]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($input->has('tags')) {
|
|
||||||
$this->torrentioCache->invalidateTags($input->get('tags'));
|
|
||||||
}
|
|
||||||
|
|
||||||
return new DeleteCacheResult($input, $cacheKey, $command->tags);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Torrentio\Action\Input;
|
|
||||||
|
|
||||||
use App\Torrentio\Action\Command\DeleteCacheCommand;
|
|
||||||
use OneToMany\RichBundle\Attribute\SourceRequest;
|
|
||||||
use OneToMany\RichBundle\Contract\CommandInterface;
|
|
||||||
use OneToMany\RichBundle\Contract\InputInterface;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @implements DeleteCacheInput<DeleteCacheCommand>
|
|
||||||
*/
|
|
||||||
class DeleteCacheInput implements InputInterface
|
|
||||||
{
|
|
||||||
public function __construct(
|
|
||||||
#[SourceRequest('type', nullify: true)]
|
|
||||||
public ?string $type,
|
|
||||||
|
|
||||||
#[SourceRequest('mediaType', nullify: true)]
|
|
||||||
public ?string $mediaType,
|
|
||||||
|
|
||||||
#[SourceRequest('tmdbId', nullify: true)]
|
|
||||||
public ?string $tmdbId,
|
|
||||||
|
|
||||||
#[SourceRequest('imdbId', nullify: true)]
|
|
||||||
public ?string $imdbId,
|
|
||||||
|
|
||||||
#[SourceRequest('season', nullify: true)]
|
|
||||||
public ?int $season,
|
|
||||||
|
|
||||||
#[SourceRequest('episode', nullify: true)]
|
|
||||||
public ?int $episode,
|
|
||||||
|
|
||||||
#[SourceRequest('tags', nullify: true)]
|
|
||||||
public ?array $tags,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
public function toCommand(): CommandInterface
|
|
||||||
{
|
|
||||||
return new DeleteCacheCommand(
|
|
||||||
type: $this->type,
|
|
||||||
mediaType: $this->mediaType,
|
|
||||||
tmdbId: $this->tmdbId,
|
|
||||||
imdbId: $this->imdbId,
|
|
||||||
season: $this->season,
|
|
||||||
episode: $this->episode
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Torrentio\Action\Result;
|
|
||||||
|
|
||||||
use Aimeos\Map;
|
|
||||||
use OneToMany\RichBundle\Contract\ResultInterface;
|
|
||||||
|
|
||||||
class DeleteCacheResult implements ResultInterface
|
|
||||||
{
|
|
||||||
public function __construct(
|
|
||||||
public Map $result,
|
|
||||||
public ?string $cacheKey = null,
|
|
||||||
public ?array $tags = null,
|
|
||||||
) {}
|
|
||||||
}
|
|
||||||
@@ -10,8 +10,8 @@ use App\Torrentio\Exception\TorrentioRateLimitException;
|
|||||||
use GuzzleHttp\Client;
|
use GuzzleHttp\Client;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
use Symfony\Component\DependencyInjection\Attribute\Autowire;
|
use Symfony\Component\DependencyInjection\Attribute\Autowire;
|
||||||
|
use Symfony\Contracts\Cache\CacheInterface;
|
||||||
use Symfony\Contracts\Cache\ItemInterface;
|
use Symfony\Contracts\Cache\ItemInterface;
|
||||||
use Symfony\Contracts\Cache\TagAwareCacheInterface;
|
|
||||||
|
|
||||||
class Torrentio
|
class Torrentio
|
||||||
{
|
{
|
||||||
@@ -23,7 +23,7 @@ class Torrentio
|
|||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
#[Autowire(env: 'REAL_DEBRID_KEY')] private string $realDebridKey,
|
#[Autowire(env: 'REAL_DEBRID_KEY')] private string $realDebridKey,
|
||||||
private TagAwareCacheInterface $torrentioCache,
|
private CacheInterface $cache,
|
||||||
private LoggerInterface $logger,
|
private LoggerInterface $logger,
|
||||||
) {
|
) {
|
||||||
$this->searchUrl = str_replace('{realDebridKey}', $this->realDebridKey, $this->baseUrl);
|
$this->searchUrl = str_replace('{realDebridKey}', $this->realDebridKey, $this->baseUrl);
|
||||||
@@ -36,9 +36,8 @@ class Torrentio
|
|||||||
{
|
{
|
||||||
$cacheKey = "torrentio.{$imdbCode}";
|
$cacheKey = "torrentio.{$imdbCode}";
|
||||||
|
|
||||||
$results = $this->torrentioCache->get($cacheKey, function (ItemInterface $item) use ($imdbCode, $type) {
|
$results = $this->cache->get($cacheKey, function (ItemInterface $item) use ($imdbCode) {
|
||||||
$item->expiresAt(Carbon::now()->addHour()->setMinute(0)->setSecond(0));
|
$item->expiresAt(Carbon::now()->addHour()->setMinute(0)->setSecond(0));
|
||||||
$item->tag(['torrentio', $type, $imdbCode]);
|
|
||||||
try {
|
try {
|
||||||
$response = $this->client->get("$this->searchUrl/$imdbCode.json");
|
$response = $this->client->get("$this->searchUrl/$imdbCode.json");
|
||||||
return json_decode(
|
return json_decode(
|
||||||
@@ -62,9 +61,8 @@ class Torrentio
|
|||||||
public function fetchEpisodeResults(string $imdbId, int $season, int $episode): array
|
public function fetchEpisodeResults(string $imdbId, int $season, int $episode): array
|
||||||
{
|
{
|
||||||
$cacheKey = "torrentio.$imdbId.$season.$episode";
|
$cacheKey = "torrentio.$imdbId.$season.$episode";
|
||||||
$results = $this->torrentioCache->get($cacheKey, function (ItemInterface $item) use ($imdbId, $season, $episode) {
|
$results = $this->cache->get($cacheKey, function (ItemInterface $item) use ($imdbId, $season, $episode) {
|
||||||
$item->expiresAt(Carbon::now()->addHour()->setMinute(0)->setSecond(0));
|
$item->expiresAt(Carbon::now()->addHour()->setMinute(0)->setSecond(0));
|
||||||
$item->tag(['torrentio', 'tvshows', 'torrentio.tvshows', $imdbId, "torrentio.$imdbId", "$imdbId.$season", "torrentio.$imdbId.$season", "$imdbId.$season.$episode", "torrentio.$imdbId.$season.$episode"]);
|
|
||||||
try {
|
try {
|
||||||
$response = $this->client->get("$this->searchUrl/$imdbId:$season:$episode.json");
|
$response = $this->client->get("$this->searchUrl/$imdbId:$season:$episode.json");
|
||||||
return json_decode(
|
return json_decode(
|
||||||
|
|||||||
@@ -1,21 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Torrentio\Framework\Controller;
|
|
||||||
|
|
||||||
use App\Torrentio\Action\Handler\DeleteCacheHandler;
|
|
||||||
use App\Torrentio\Action\Input\DeleteCacheInput;
|
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
|
||||||
use Symfony\Component\Routing\Attribute\Route;
|
|
||||||
|
|
||||||
class ApiController extends AbstractController
|
|
||||||
{
|
|
||||||
#[Route('/api/torrentio/cache', name: 'api.torrentio.cache', methods: ['POST'])]
|
|
||||||
public function deleteCache(
|
|
||||||
DeleteCacheInput $deleteCacheInput,
|
|
||||||
DeleteCacheHandler $deleteCacheHandler,
|
|
||||||
): Response {
|
|
||||||
$result = $deleteCacheHandler->handle($deleteCacheInput->toCommand());
|
|
||||||
return $this->json($result, Response::HTTP_OK);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -4,10 +4,7 @@ namespace App\Twig\Extensions;
|
|||||||
|
|
||||||
use App\Monitor\Framework\Entity\Monitor;
|
use App\Monitor\Framework\Entity\Monitor;
|
||||||
use App\Monitor\Service\MediaFiles;
|
use App\Monitor\Service\MediaFiles;
|
||||||
use App\Torrentio\Action\Result\GetTvShowOptionsResult;
|
|
||||||
use App\Torrentio\Result\TorrentioResult;
|
|
||||||
use ChrisUllyott\FileSize;
|
use ChrisUllyott\FileSize;
|
||||||
use Tmdb\Model\Tv\Episode;
|
|
||||||
use Twig\Attribute\AsTwigFilter;
|
use Twig\Attribute\AsTwigFilter;
|
||||||
use Twig\Attribute\AsTwigFunction;
|
use Twig\Attribute\AsTwigFunction;
|
||||||
|
|
||||||
@@ -48,15 +45,4 @@ class UtilExtension
|
|||||||
$path
|
$path
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[AsTwigFilter('episode_id_from_results')]
|
|
||||||
public function episodeId($result): ?string
|
|
||||||
{
|
|
||||||
if (!$result instanceof GetTvShowOptionsResult) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return "S". str_pad($result->season, 2, "0", STR_PAD_LEFT) .
|
|
||||||
"E". str_pad($result->episode, 2, "0", STR_PAD_LEFT);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,16 +17,13 @@ use Psr\Log\LoggerInterface;
|
|||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
use Symfony\Bundle\SecurityBundle\Security;
|
use Symfony\Bundle\SecurityBundle\Security;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpFoundation\RequestStack;
|
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Symfony\Component\HttpKernel\KernelInterface;
|
use Symfony\Component\HttpKernel\KernelInterface;
|
||||||
use Symfony\Component\Routing\Attribute\Route;
|
use Symfony\Component\Routing\Attribute\Route;
|
||||||
|
|
||||||
class RegistrationController extends AbstractController
|
class RegistrationController extends AbstractController
|
||||||
{
|
{
|
||||||
public function __construct(private readonly RegisterUserHandler $registerUserHandler,
|
public function __construct(private readonly RegisterUserHandler $registerUserHandler)
|
||||||
private readonly RequestStack $requestStack
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,7 +71,6 @@ class RegistrationController extends AbstractController
|
|||||||
));
|
));
|
||||||
|
|
||||||
$security->login($user->user);
|
$security->login($user->user);
|
||||||
$this->requestStack->getCurrentRequest()->getSession()->set('mercure_alert_topic', 'alerts_' . uniqid());
|
|
||||||
|
|
||||||
return $this->redirectToRoute('app_index');
|
return $this->redirectToRoute('app_index');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,12 +19,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="col-span-5 h-screen overflow-y-scroll">
|
<div class="col-span-5 h-screen overflow-y-scroll">
|
||||||
<twig:Header />
|
<twig:Header />
|
||||||
<div class="px-4 mt-3 flex flex-row justify-between">
|
<h2 class="px-4 my-2 text-3xl font-bold text-gray-50">{% block h2 %}{% endblock %}</h2>
|
||||||
<h2 class="m-2 text-3xl font-bold text-gray-50">{% block h2 %}{% endblock %}</h2>
|
|
||||||
<div class="flex flex-row gap-1 align-end justify-end items-end">
|
|
||||||
{% block action_buttons %}{% endblock %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% block body %}{% endblock %}
|
{% block body %}{% endblock %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -9,12 +9,12 @@
|
|||||||
{% if show_cancel is defined or show_submit is defined %}
|
{% if show_cancel is defined or show_submit is defined %}
|
||||||
<div class="flex justify-end">
|
<div class="flex justify-end">
|
||||||
{% if show_cancel is defined %}
|
{% if show_cancel is defined %}
|
||||||
<button type="button" data-action="dialog#close" class="secondary-btn" autofocus>
|
<button type="button" data-action="dialog#close" class="px-1 py-1 rounded-md self-end w-16 hover:bg-stone-100" autofocus>
|
||||||
{{ cancel_text|default('Cancel') }}
|
{{ cancel_text|default('Cancel') }}
|
||||||
</button>
|
</button>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if show_submit is defined %}
|
{% if show_submit is defined %}
|
||||||
<button type="button" {{ submit_action|raw }} class="primary-btn" autofocus>
|
<button type="button" {{ submit_action|raw }} class="px-1 py-1 rounded-md bg-orange-500 self-end text-white w-16 ml-2 hover:bg-orange-600" autofocus>
|
||||||
{{ submit_text|default('Submit') }}
|
{{ submit_text|default('Submit') }}
|
||||||
</button>
|
</button>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@@ -22,5 +22,5 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</dialog>
|
</dialog>
|
||||||
|
|
||||||
<button type="button" data-action="dialog#open" class="{{ button_class|default('') }}">{{ button_text|raw }}</button>
|
<button type="button" data-action="dialog#open">{{ button_text|raw }}</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -9,6 +9,7 @@
|
|||||||
<twig:DownloadList type="active" :isWidget="false" :perPage="10"></twig:DownloadList>
|
<twig:DownloadList type="active" :isWidget="false" :perPage="10"></twig:DownloadList>
|
||||||
</twig:Card>
|
</twig:Card>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="p-4">
|
<div class="p-4">
|
||||||
<twig:Card title="Recent Downloads">
|
<twig:Card title="Recent Downloads">
|
||||||
<twig:DownloadList type="complete" :isWidget="false" :perPage="10"></twig:DownloadList>
|
<twig:DownloadList type="complete" :isWidget="false" :perPage="10"></twig:DownloadList>
|
||||||
|
|||||||
@@ -1,10 +1,16 @@
|
|||||||
{% extends 'base.html.twig' %}
|
{% extends 'base.html.twig' %}
|
||||||
|
|
||||||
{% block title %}Dashboard — Torsearch{% endblock %}
|
{% block title %}Dashboard — Torsearch{% endblock %}
|
||||||
{% block h2 %}Dashboard{% endblock %}
|
|
||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<div class="p-4 flex flex-col grow gap-4 z-30">
|
<div class="p-4 flex flex-col grow gap-4 z-30">
|
||||||
|
<h2 class="mb-2 text-3xl font-bold text-gray-50">Dashboard</h2>
|
||||||
|
<div class="flex flex-row gap-4">
|
||||||
|
<twig:Card title="Play Survivor" class="w-full">
|
||||||
|
<video width="352" height="198" controls>
|
||||||
|
</video>
|
||||||
|
</twig:Card>
|
||||||
|
</div>
|
||||||
<div class="flex flex-row gap-4">
|
<div class="flex flex-row gap-4">
|
||||||
<twig:Card title="Active Downloads" class="w-full">
|
<twig:Card title="Active Downloads" class="w-full">
|
||||||
<twig:DownloadList :type="'active'" />
|
<twig:DownloadList :type="'active'" />
|
||||||
|
|||||||
@@ -4,14 +4,22 @@
|
|||||||
{% block h2 %}Monitors{% endblock %}
|
{% block h2 %}Monitors{% endblock %}
|
||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<div class="p-4">
|
<div class="flex flex-row">
|
||||||
<twig:Card title="Active Monitors" class="w-full">
|
|
||||||
<twig:MonitorList :type="'active'" :isWidget="false" :perPage="10"></twig:MonitorList>
|
<div class="p-2 flex flex-col gap-4">
|
||||||
</twig:Card>
|
<twig:Card title="Active Monitors">
|
||||||
</div>
|
<twig:MonitorList :type="'active'" :isWidget="false" :perPage="10"></twig:MonitorList>
|
||||||
<div class="p-4">
|
</twig:Card>
|
||||||
<twig:Card title="Complete Monitors" class="w-full">
|
<twig:Card title="Complete Monitors">
|
||||||
<twig:MonitorList :type="'complete'" :isWidget="false" :perPage="10"></twig:MonitorList>
|
<twig:MonitorList :type="'complete'" :isWidget="false" :perPage="10"></twig:MonitorList>
|
||||||
</twig:Card>
|
</twig:Card>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="p-2">
|
||||||
|
<twig:Card title="Upcoming Episodes" >
|
||||||
|
<twig:UpcomingEpisodes />
|
||||||
|
</twig:Card>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@
|
|||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for result in results.results %}
|
{% for result in results.results %}
|
||||||
<tr class="bg-white border-b dark:bg-slate-700 dark:border-gray-600 border-gray-200" data-provider="{{ result.provider }}" data-languages="{{ result.languages|json_encode }}" {% if "tvshows" == results.media.mediaType %} data-season="{{ results.season }}"{% endif %}>
|
<tr class="bg-white border-b dark:bg-slate-700 dark:border-gray-600 border-gray-200" data-provider="{{ result.provider }}" data-languages="{{ result.languages|json_encode }}" {% if "tvshows" == results.media.mediaType %} data-season="{{ results.season }} {% endif %}">
|
||||||
<td id="size" class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-800 dark:text-gray-50">
|
<td id="size" class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-800 dark:text-gray-50">
|
||||||
{{ result.size }}
|
{{ result.size }}
|
||||||
</td>
|
</td>
|
||||||
@@ -60,8 +60,7 @@
|
|||||||
title: results.media.title,
|
title: results.media.title,
|
||||||
filename: result.filename,
|
filename: result.filename,
|
||||||
mediaType: results.media.mediaType,
|
mediaType: results.media.mediaType,
|
||||||
imdbId: results.media.imdbId,
|
imdbId: results.media.imdbId
|
||||||
episodeId: results|episode_id_from_results
|
|
||||||
}) }}
|
}) }}
|
||||||
{{ stimulus_action('download_button', 'download', 'click') }}
|
{{ stimulus_action('download_button', 'download', 'click') }}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -2,18 +2,6 @@
|
|||||||
{% block title %}Preferences{% endblock %}
|
{% block title %}Preferences{% endblock %}
|
||||||
{% block h2 %}Preferences{% endblock %}
|
{% block h2 %}Preferences{% endblock %}
|
||||||
|
|
||||||
{% block action_buttons %}
|
|
||||||
<div {{ stimulus_controller('clear_cache') }}>
|
|
||||||
<twig:Modal heading="Hold on a sec!" button_text="Clear Cache" cancel_text="Nope" submit_text="Yep" show_cancel show_submit
|
|
||||||
button_class="px-1.5 py-1 my-2 text-white text-sm bg-blue-950 hover:bg-black/80 border-2 border-blue-500/90 rounded-md inline-block"
|
|
||||||
submit_action="{{ stimulus_action('clear_cache', 'clearAll', 'click') }}"
|
|
||||||
>
|
|
||||||
This will clear the TMDB, Torrentio, and application cache. Clearing the cache is safe, but may lead to
|
|
||||||
slower page loads and rate limits by Torrentio. Would you like to proceed?
|
|
||||||
</twig:Modal>
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<div class="p-4 flex flex-row gap-2">
|
<div class="p-4 flex flex-row gap-2">
|
||||||
<twig:Card title="Media Preferences" class="w-full">
|
<twig:Card title="Media Preferences" class="w-full">
|
||||||
|
|||||||
Reference in New Issue
Block a user