mirror of
https://github.com/neosubhamoy/neodlp.git
synced 2025-12-19 01:32:57 +05:30
feat: added cookies support
This commit is contained in:
19
src/App.tsx
19
src/App.tsx
@@ -70,6 +70,10 @@ export default function App({ children }: { children: React.ReactNode }) {
|
||||
const EMBED_VIDEO_METADATA = useSettingsPageStatesStore(state => state.settings.embed_video_metadata);
|
||||
const EMBED_AUDIO_METADATA = useSettingsPageStatesStore(state => state.settings.embed_audio_metadata);
|
||||
const EMBED_AUDIO_THUMBNAIL = useSettingsPageStatesStore(state => state.settings.embed_audio_thumbnail);
|
||||
const USE_COOKIES = useSettingsPageStatesStore(state => state.settings.use_cookies);
|
||||
const IMPORT_COOKIES_FROM = useSettingsPageStatesStore(state => state.settings.import_cookies_from);
|
||||
const COOKIES_BROWSER = useSettingsPageStatesStore(state => state.settings.cookies_browser);
|
||||
const COOKIES_FILE = useSettingsPageStatesStore(state => state.settings.cookies_file);
|
||||
|
||||
const isErrored = useDownloaderPageStatesStore((state) => state.isErrored);
|
||||
const isErrorExpected = useDownloaderPageStatesStore((state) => state.isErrorExpected);
|
||||
@@ -112,6 +116,13 @@ export default function App({ children }: { children: React.ReactNode }) {
|
||||
if (STRICT_DOWNLOADABILITY_CHECK && !formatId) args.push('--check-all-formats');
|
||||
if (STRICT_DOWNLOADABILITY_CHECK && formatId) args.push('--check-formats');
|
||||
if (USE_PROXY && PROXY_URL) args.push('--proxy', PROXY_URL);
|
||||
if (USE_COOKIES) {
|
||||
if (IMPORT_COOKIES_FROM === 'browser' && COOKIES_BROWSER) {
|
||||
args.push('--cookies-from-browser', COOKIES_BROWSER);
|
||||
} else if (IMPORT_COOKIES_FROM === 'file' && COOKIES_FILE) {
|
||||
args.push('--cookies', COOKIES_FILE);
|
||||
}
|
||||
};
|
||||
const command = Command.sidecar('binaries/yt-dlp', args);
|
||||
|
||||
let jsonOutput = '';
|
||||
@@ -273,6 +284,14 @@ export default function App({ children }: { children: React.ReactNode }) {
|
||||
args.push('--limit-rate', `${RATE_LIMIT}`);
|
||||
}
|
||||
|
||||
if (USE_COOKIES) {
|
||||
if (IMPORT_COOKIES_FROM === 'browser' && COOKIES_BROWSER) {
|
||||
args.push('--cookies-from-browser', COOKIES_BROWSER);
|
||||
} else if (IMPORT_COOKIES_FROM === 'file' && COOKIES_FILE) {
|
||||
args.push('--cookies', COOKIES_FILE);
|
||||
}
|
||||
}
|
||||
|
||||
console.log('Starting download with args:', args);
|
||||
const command = Command.sidecar('binaries/yt-dlp', args);
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import { Switch } from "@/components/ui/switch";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { toast } from "sonner";
|
||||
import { ArrowDownToLine, ArrowRight, BrushCleaning, EthernetPort, ExternalLink, FileVideo, Folder, FolderOpen, Info, Loader2, LucideIcon, Monitor, Moon, Radio, RotateCcw, RotateCw, Sun, Terminal, WandSparkles, Wifi, Wrench } from "lucide-react";
|
||||
import { ArrowDownToLine, ArrowRight, BrushCleaning, Cookie, EthernetPort, ExternalLink, FileVideo, Folder, FolderOpen, Info, Loader2, LucideIcon, Monitor, Moon, Radio, RotateCcw, RotateCw, Sun, Terminal, WandSparkles, Wifi, Wrench } from "lucide-react";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { useEffect } from "react";
|
||||
import { useTheme } from "@/providers/themeProvider";
|
||||
@@ -95,6 +95,11 @@ export default function SettingsPage() {
|
||||
const embedVideoMetadata = useSettingsPageStatesStore(state => state.settings.embed_video_metadata);
|
||||
const embedAudioMetadata = useSettingsPageStatesStore(state => state.settings.embed_audio_metadata);
|
||||
const embedAudioThumbnail = useSettingsPageStatesStore(state => state.settings.embed_audio_thumbnail);
|
||||
const useCookies = useSettingsPageStatesStore(state => state.settings.use_cookies);
|
||||
const importCookiesFrom = useSettingsPageStatesStore(state => state.settings.import_cookies_from);
|
||||
const cookiesBrowser = useSettingsPageStatesStore(state => state.settings.cookies_browser);
|
||||
const cookiesFile = useSettingsPageStatesStore(state => state.settings.cookies_file);
|
||||
|
||||
const websocketPort = useSettingsPageStatesStore(state => state.settings.websocket_port);
|
||||
const isChangingWebSocketPort = useSettingsPageStatesStore(state => state.isChangingWebSocketPort);
|
||||
const setIsChangingWebSocketPort = useSettingsPageStatesStore(state => state.setIsChangingWebSocketPort);
|
||||
@@ -384,9 +389,14 @@ export default function SettingsPage() {
|
||||
value="network"
|
||||
className="data-[state=active]:bg-primary data-[state=active]:text-primary-foreground justify-start px-3 py-1.5 gap-2"
|
||||
><Wifi className="size-4" /> Network</TabsTrigger>
|
||||
<TabsTrigger
|
||||
key="cookies"
|
||||
value="cookies"
|
||||
className="data-[state=active]:bg-primary data-[state=active]:text-primary-foreground justify-start px-3 py-1.5 gap-2"
|
||||
><Cookie className="size-4" /> Cookies</TabsTrigger>
|
||||
</TabsList>
|
||||
<div className="min-h-full flex flex-col max-w-[55%] w-full border-l border-border pl-4">
|
||||
<TabsContent key="general" value="general" className="flex flex-col gap-4 min-h-[235px]">
|
||||
<TabsContent key="general" value="general" className="flex flex-col gap-4 min-h-[275px]">
|
||||
<div className="max-parallel-downloads">
|
||||
<h3 className="font-semibold">Max Parallel Downloads</h3>
|
||||
<p className="text-xs text-muted-foreground mb-3">Set maximum number of allowed parallel downloads</p>
|
||||
@@ -432,7 +442,7 @@ export default function SettingsPage() {
|
||||
<Label htmlFor="max-retries" className="text-xs text-muted-foreground">(Current: {maxRetries}) (Default: 5, Maximum: 100)</Label>
|
||||
</div>
|
||||
</TabsContent>
|
||||
<TabsContent key="appearance" value="appearance" className="flex flex-col gap-4 min-h-[235px]">
|
||||
<TabsContent key="appearance" value="appearance" className="flex flex-col gap-4 min-h-[275px]">
|
||||
<div className="app-theme">
|
||||
<h3 className="font-semibold">Theme</h3>
|
||||
<p className="text-xs text-muted-foreground mb-3">Choose app interface theme</p>
|
||||
@@ -455,7 +465,7 @@ export default function SettingsPage() {
|
||||
</div>
|
||||
</div>
|
||||
</TabsContent>
|
||||
<TabsContent key="folders" value="folders" className="flex flex-col gap-4 min-h-[235px]">
|
||||
<TabsContent key="folders" value="folders" className="flex flex-col gap-4 min-h-[275px]">
|
||||
<div className="download-dir">
|
||||
<h3 className="font-semibold">Download Folder</h3>
|
||||
<p className="text-xs text-muted-foreground mb-3">Set default download folder (directory)</p>
|
||||
@@ -515,7 +525,7 @@ export default function SettingsPage() {
|
||||
</div>
|
||||
</div>
|
||||
</TabsContent>
|
||||
<TabsContent key="formats" value="formats" className="flex flex-col gap-4 min-h-[235px]">
|
||||
<TabsContent key="formats" value="formats" className="flex flex-col gap-4 min-h-[275px]">
|
||||
<div className="video-format">
|
||||
<h3 className="font-semibold">Video Format</h3>
|
||||
<p className="text-xs text-muted-foreground mb-3">Choose in which format the final video file will be saved</p>
|
||||
@@ -580,7 +590,7 @@ export default function SettingsPage() {
|
||||
/>
|
||||
</div>
|
||||
</TabsContent>
|
||||
<TabsContent key="metadata" value="metadata" className="flex flex-col gap-4 min-h-[235px]">
|
||||
<TabsContent key="metadata" value="metadata" className="flex flex-col gap-4 min-h-[275px]">
|
||||
<div className="embed-video-metadata">
|
||||
<h3 className="font-semibold">Embed Metadata</h3>
|
||||
<p className="text-xs text-muted-foreground mb-3">Wheather to embed metadata in video/audio files (info, chapters)</p>
|
||||
@@ -611,7 +621,7 @@ export default function SettingsPage() {
|
||||
/>
|
||||
</div>
|
||||
</TabsContent>
|
||||
<TabsContent key="network" value="network" className="flex flex-col gap-4 min-h-[235px]">
|
||||
<TabsContent key="network" value="network" className="flex flex-col gap-4 min-h-[275px]">
|
||||
<div className="proxy">
|
||||
<h3 className="font-semibold">Proxy</h3>
|
||||
<p className="text-xs text-muted-foreground mb-3">Use proxy for downloads, Unblocks blocked sites in your region (download speed may affect, some sites may not work)</p>
|
||||
@@ -693,6 +703,93 @@ export default function SettingsPage() {
|
||||
</Form>
|
||||
</div>
|
||||
</TabsContent>
|
||||
<TabsContent key="cookies" value="cookies" className="flex flex-col gap-4 min-h-[275px]">
|
||||
<div className="cookies">
|
||||
<h3 className="font-semibold">Cookies</h3>
|
||||
<p className="text-xs text-muted-foreground mb-3">Use cookies to access exclusive/private (login-protected) contents from sites (use wisely, over-use can even block/ban your account)</p>
|
||||
<div className="flex items-center space-x-2 mb-4">
|
||||
<Switch
|
||||
id="use-cookies"
|
||||
checked={useCookies}
|
||||
onCheckedChange={(checked) => saveSettingsKey('use_cookies', checked)}
|
||||
/>
|
||||
<Label htmlFor="use-cookies">Use Cookies</Label>
|
||||
</div>
|
||||
<RadioGroup
|
||||
orientation="horizontal"
|
||||
className="flex items-center gap-4"
|
||||
value={importCookiesFrom}
|
||||
onValueChange={(value) => saveSettingsKey('import_cookies_from', value)}
|
||||
disabled={!useCookies}
|
||||
>
|
||||
<div className="flex items-center gap-3">
|
||||
<RadioGroupItem value="browser" id="cookies-browser" />
|
||||
<Label htmlFor="cookies-browser">Import from Browser</Label>
|
||||
</div>
|
||||
<div className="flex items-center gap-3">
|
||||
<RadioGroupItem value="file" id="cookies-file" />
|
||||
<Label htmlFor="cookies-file">Import from Text File</Label>
|
||||
</div>
|
||||
</RadioGroup>
|
||||
<div className="flex flex-col gap-2 mt-5 mb-2">
|
||||
<Label className="text-xs">Import Cookies from Browser</Label>
|
||||
<Select
|
||||
value={cookiesBrowser}
|
||||
onValueChange={(value) => saveSettingsKey('cookies_browser', value)}
|
||||
disabled={importCookiesFrom !== "browser" || !useCookies}
|
||||
>
|
||||
<SelectTrigger className="w-[230px] ring-0 focus:ring-0">
|
||||
<SelectValue placeholder="Select browser to import cookies" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectGroup>
|
||||
<SelectLabel>Browsers</SelectLabel>
|
||||
<SelectItem value="firefox">Firefox (Recommended)</SelectItem>
|
||||
<SelectItem value="chrome">Chrome</SelectItem>
|
||||
<SelectItem value="chromium">Chromium</SelectItem>
|
||||
<SelectItem value="safari">Safari</SelectItem>
|
||||
<SelectItem value="brave">Brave</SelectItem>
|
||||
<SelectItem value="edge">Edge</SelectItem>
|
||||
<SelectItem value="opera">Opera</SelectItem>
|
||||
<SelectItem value="vivaldi">Vivaldi</SelectItem>
|
||||
<SelectItem value="whale">Whale</SelectItem>
|
||||
</SelectGroup>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div className="flex flex-col gap-2 mt-3 mb-2">
|
||||
<Label className="text-xs">Import Cookies from Text File (Netscape format)</Label>
|
||||
<div className="flex items-center gap-4">
|
||||
<Input className="focus-visible:ring-0" type="text" placeholder="Select cookies text file" value={cookiesFile ?? ''} disabled={importCookiesFrom !== "file" || !useCookies} readOnly/>
|
||||
<Button
|
||||
variant="outline"
|
||||
disabled={importCookiesFrom !== "file" || !useCookies}
|
||||
onClick={async () => {
|
||||
try {
|
||||
const file = await open({
|
||||
multiple: false,
|
||||
directory: false,
|
||||
filters: [
|
||||
{ name: 'Text', extensions: ['txt'] },
|
||||
],
|
||||
});
|
||||
if (file && typeof file === 'string') {
|
||||
saveSettingsKey('cookies_file', file);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error selecting file:", error);
|
||||
toast.error("Failed to select file", {
|
||||
description: "An error occurred while trying to select the cookies text file. Please try again.",
|
||||
});
|
||||
}
|
||||
}}
|
||||
>
|
||||
<FolderOpen className="w-4 h-4" /> Browse
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</TabsContent>
|
||||
</div>
|
||||
</Tabs>
|
||||
</TabsContent>
|
||||
|
||||
@@ -141,6 +141,11 @@ export const useSettingsPageStatesStore = create<SettingsPageStatesStore>((set)
|
||||
embed_video_metadata: false,
|
||||
embed_audio_metadata: true,
|
||||
embed_audio_thumbnail: true,
|
||||
use_cookies: false,
|
||||
import_cookies_from: 'browser',
|
||||
cookies_browser: 'firefox',
|
||||
cookies_file: '',
|
||||
// extension settings
|
||||
websocket_port: 53511
|
||||
},
|
||||
isUsingDefaultSettings: true,
|
||||
@@ -185,6 +190,11 @@ export const useSettingsPageStatesStore = create<SettingsPageStatesStore>((set)
|
||||
embed_video_metadata: false,
|
||||
embed_audio_metadata: true,
|
||||
embed_audio_thumbnail: true,
|
||||
use_cookies: false,
|
||||
import_cookies_from: 'browser',
|
||||
cookies_browser: 'firefox',
|
||||
cookies_file: '',
|
||||
// extension settings
|
||||
websocket_port: 53511
|
||||
},
|
||||
isUsingDefaultSettings: true
|
||||
|
||||
@@ -22,6 +22,10 @@ export interface Settings {
|
||||
embed_video_metadata: boolean;
|
||||
embed_audio_metadata: boolean;
|
||||
embed_audio_thumbnail: boolean;
|
||||
use_cookies: boolean;
|
||||
import_cookies_from: string;
|
||||
cookies_browser: string;
|
||||
cookies_file: string;
|
||||
// extension settings
|
||||
websocket_port: number;
|
||||
}
|
||||
Reference in New Issue
Block a user