mirror of
https://github.com/open-webui/open-webui.git
synced 2025-03-27 02:02:31 +01:00
enh: youtube watch param support
This commit is contained in:
parent
e7ae9a2107
commit
f099b277c8
@ -824,6 +824,32 @@ class PipelineMiddleware(BaseHTTPMiddleware):
|
||||
app.add_middleware(PipelineMiddleware)
|
||||
|
||||
|
||||
from urllib.parse import urlencode, parse_qs, urlparse
|
||||
|
||||
|
||||
class RedirectMiddleware(BaseHTTPMiddleware):
|
||||
async def dispatch(self, request: Request, call_next):
|
||||
# Check if the request is a GET request
|
||||
if request.method == "GET":
|
||||
path = request.url.path
|
||||
query_params = dict(parse_qs(urlparse(str(request.url)).query))
|
||||
|
||||
# Check for the specific watch path and the presence of 'v' parameter
|
||||
if path.endswith("/watch") and "v" in query_params:
|
||||
video_id = query_params["v"][0] # Extract the first 'v' parameter
|
||||
encoded_video_id = urlencode({"youtube": video_id})
|
||||
redirect_url = f"/?{encoded_video_id}"
|
||||
return RedirectResponse(url=redirect_url)
|
||||
|
||||
# Proceed with the normal flow of other requests
|
||||
response = await call_next(request)
|
||||
return response
|
||||
|
||||
|
||||
# Add the middleware to the app
|
||||
app.add_middleware(RedirectMiddleware)
|
||||
|
||||
|
||||
app.add_middleware(
|
||||
CORSMiddleware,
|
||||
allow_origins=CORS_ALLOW_ORIGIN,
|
||||
@ -2416,6 +2442,7 @@ async def healthcheck_with_db():
|
||||
app.mount("/static", StaticFiles(directory=STATIC_DIR), name="static")
|
||||
app.mount("/cache", StaticFiles(directory=CACHE_DIR), name="cache")
|
||||
|
||||
|
||||
if os.path.exists(FRONTEND_BUILD_DIR):
|
||||
mimetypes.add_type("text/javascript", ".js")
|
||||
app.mount(
|
||||
|
@ -53,7 +53,7 @@
|
||||
updateChatById
|
||||
} from '$lib/apis/chats';
|
||||
import { generateOpenAIChatCompletion } from '$lib/apis/openai';
|
||||
import { processWebSearch } from '$lib/apis/retrieval';
|
||||
import { processWeb, processWebSearch, processYoutubeVideo } from '$lib/apis/retrieval';
|
||||
import { createOpenAITextStream } from '$lib/apis/streaming';
|
||||
import { queryMemory } from '$lib/apis/memories';
|
||||
import { getAndUpdateUserLocation, getUserSettings } from '$lib/apis/users';
|
||||
@ -308,6 +308,74 @@
|
||||
$socket?.off('chat-events');
|
||||
});
|
||||
|
||||
// File upload functions
|
||||
|
||||
const uploadWeb = async (url) => {
|
||||
console.log(url);
|
||||
|
||||
const fileItem = {
|
||||
type: 'doc',
|
||||
name: url,
|
||||
collection_name: '',
|
||||
status: 'uploading',
|
||||
url: url,
|
||||
error: ''
|
||||
};
|
||||
|
||||
try {
|
||||
files = [...files, fileItem];
|
||||
const res = await processWeb(localStorage.token, '', url);
|
||||
|
||||
if (res) {
|
||||
fileItem.status = 'uploaded';
|
||||
fileItem.collection_name = res.collection_name;
|
||||
fileItem.file = {
|
||||
...res.file,
|
||||
...fileItem.file
|
||||
};
|
||||
|
||||
files = files;
|
||||
}
|
||||
} catch (e) {
|
||||
// Remove the failed doc from the files array
|
||||
files = files.filter((f) => f.name !== url);
|
||||
toast.error(JSON.stringify(e));
|
||||
}
|
||||
};
|
||||
|
||||
const uploadYoutubeTranscription = async (url) => {
|
||||
console.log(url);
|
||||
|
||||
const fileItem = {
|
||||
type: 'doc',
|
||||
name: url,
|
||||
collection_name: '',
|
||||
status: 'uploading',
|
||||
context: 'full',
|
||||
url: url,
|
||||
error: ''
|
||||
};
|
||||
|
||||
try {
|
||||
files = [...files, fileItem];
|
||||
const res = await processYoutubeVideo(localStorage.token, url);
|
||||
|
||||
if (res) {
|
||||
fileItem.status = 'uploaded';
|
||||
fileItem.collection_name = res.collection_name;
|
||||
fileItem.file = {
|
||||
...res.file,
|
||||
...fileItem.file
|
||||
};
|
||||
files = files;
|
||||
}
|
||||
} catch (e) {
|
||||
// Remove the failed doc from the files array
|
||||
files = files.filter((f) => f.name !== url);
|
||||
toast.error(e);
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////
|
||||
// Web functions
|
||||
//////////////////////////
|
||||
@ -348,6 +416,10 @@
|
||||
selectedModels = [''];
|
||||
}
|
||||
|
||||
if ($page.url.searchParams.get('youtube')) {
|
||||
uploadYoutubeTranscription(`https://www.youtube.com/watch?v=NqxUExCZJ5Y`);
|
||||
}
|
||||
|
||||
if ($page.url.searchParams.get('web-search') === 'true') {
|
||||
webSearchEnabled = true;
|
||||
}
|
||||
@ -366,6 +438,11 @@
|
||||
.filter((id) => id);
|
||||
}
|
||||
|
||||
if ($page.url.searchParams.get('call') === 'true') {
|
||||
showCallOverlay.set(true);
|
||||
showControls.set(true);
|
||||
}
|
||||
|
||||
if ($page.url.searchParams.get('q')) {
|
||||
prompt = $page.url.searchParams.get('q') ?? '';
|
||||
|
||||
@ -375,11 +452,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
if ($page.url.searchParams.get('call') === 'true') {
|
||||
showCallOverlay.set(true);
|
||||
showControls.set(true);
|
||||
}
|
||||
|
||||
selectedModels = selectedModels.map((modelId) =>
|
||||
$models.map((m) => m.id).includes(modelId) ? modelId : ''
|
||||
);
|
||||
@ -2060,6 +2132,15 @@
|
||||
transparentBackground={$settings?.backgroundImageUrl ?? false}
|
||||
{stopResponse}
|
||||
{createMessagePair}
|
||||
on:upload={async (e) => {
|
||||
const { type, data } = e.detail;
|
||||
|
||||
if (type === 'web') {
|
||||
await uploadWeb(data);
|
||||
} else if (type === 'youtube') {
|
||||
await uploadYoutubeTranscription(data);
|
||||
}
|
||||
}}
|
||||
on:submit={async (e) => {
|
||||
if (e.detail) {
|
||||
prompt = '';
|
||||
@ -2095,6 +2176,15 @@
|
||||
transparentBackground={$settings?.backgroundImageUrl ?? false}
|
||||
{stopResponse}
|
||||
{createMessagePair}
|
||||
on:upload={async (e) => {
|
||||
const { type, data } = e.detail;
|
||||
|
||||
if (type === 'web') {
|
||||
await uploadWeb(data);
|
||||
} else if (type === 'youtube') {
|
||||
await uploadYoutubeTranscription(data);
|
||||
}
|
||||
}}
|
||||
on:submit={async (e) => {
|
||||
if (e.detail) {
|
||||
prompt = '';
|
||||
|
@ -300,6 +300,9 @@
|
||||
bind:this={commandsElement}
|
||||
bind:prompt
|
||||
bind:files
|
||||
on:upload={(e) => {
|
||||
dispatch('upload', e.detail);
|
||||
}}
|
||||
on:select={(e) => {
|
||||
const data = e.detail;
|
||||
|
||||
|
@ -26,71 +26,6 @@
|
||||
|
||||
let command = '';
|
||||
$: command = (prompt?.trim() ?? '').split(' ')?.at(-1) ?? '';
|
||||
|
||||
const uploadWeb = async (url) => {
|
||||
console.log(url);
|
||||
|
||||
const fileItem = {
|
||||
type: 'doc',
|
||||
name: url,
|
||||
collection_name: '',
|
||||
status: 'uploading',
|
||||
url: url,
|
||||
error: ''
|
||||
};
|
||||
|
||||
try {
|
||||
files = [...files, fileItem];
|
||||
const res = await processWeb(localStorage.token, '', url);
|
||||
|
||||
if (res) {
|
||||
fileItem.status = 'uploaded';
|
||||
fileItem.collection_name = res.collection_name;
|
||||
fileItem.file = {
|
||||
...res.file,
|
||||
...fileItem.file
|
||||
};
|
||||
|
||||
files = files;
|
||||
}
|
||||
} catch (e) {
|
||||
// Remove the failed doc from the files array
|
||||
files = files.filter((f) => f.name !== url);
|
||||
toast.error(JSON.stringify(e));
|
||||
}
|
||||
};
|
||||
|
||||
const uploadYoutubeTranscription = async (url) => {
|
||||
console.log(url);
|
||||
|
||||
const fileItem = {
|
||||
type: 'doc',
|
||||
name: url,
|
||||
collection_name: '',
|
||||
status: 'uploading',
|
||||
url: url,
|
||||
error: ''
|
||||
};
|
||||
|
||||
try {
|
||||
files = [...files, fileItem];
|
||||
const res = await processYoutubeVideo(localStorage.token, url);
|
||||
|
||||
if (res) {
|
||||
fileItem.status = 'uploaded';
|
||||
fileItem.collection_name = res.collection_name;
|
||||
fileItem.file = {
|
||||
...res.file,
|
||||
...fileItem.file
|
||||
};
|
||||
files = files;
|
||||
}
|
||||
} catch (e) {
|
||||
// Remove the failed doc from the files array
|
||||
files = files.filter((f) => f.name !== url);
|
||||
toast.error(e);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
{#if ['/', '#', '@'].includes(command?.charAt(0))}
|
||||
@ -103,11 +38,17 @@
|
||||
{command}
|
||||
on:youtube={(e) => {
|
||||
console.log(e);
|
||||
uploadYoutubeTranscription(e.detail);
|
||||
dispatch('upload', {
|
||||
type: 'youtube',
|
||||
data: e.detail
|
||||
});
|
||||
}}
|
||||
on:url={(e) => {
|
||||
console.log(e);
|
||||
uploadWeb(e.detail);
|
||||
dispatch('upload', {
|
||||
type: 'web',
|
||||
data: e.detail
|
||||
});
|
||||
}}
|
||||
on:select={(e) => {
|
||||
console.log(e);
|
||||
|
@ -204,6 +204,9 @@
|
||||
{stopResponse}
|
||||
{createMessagePair}
|
||||
placeholder={$i18n.t('How can I help you today?')}
|
||||
on:upload={(e) => {
|
||||
dispatch('upload', e.detail);
|
||||
}}
|
||||
on:submit={(e) => {
|
||||
dispatch('submit', e.detail);
|
||||
}}
|
||||
|
22
src/routes/watch/+page.svelte
Normal file
22
src/routes/watch/+page.svelte
Normal file
@ -0,0 +1,22 @@
|
||||
<script>
|
||||
import { onMount } from 'svelte';
|
||||
import { goto } from '$app/navigation';
|
||||
|
||||
onMount(() => {
|
||||
// Get the current URL search parameters
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
|
||||
// Check if 'v' parameter exists
|
||||
if (params.has('v')) {
|
||||
// Get the value of 'v' parameter
|
||||
const videoId = params.get('v');
|
||||
|
||||
// Redirect to root with 'youtube' parameter
|
||||
|
||||
goto(`/?youtube=${encodeURIComponent(videoId)}`);
|
||||
} else {
|
||||
// Redirect to root if 'v' parameter doesn't exist
|
||||
goto('/');
|
||||
}
|
||||
});
|
||||
</script>
|
Loading…
x
Reference in New Issue
Block a user