1
1
mirror of https://github.com/neosubhamoy/neodlp.git synced 2026-03-22 12:35:49 +05:30

5 Commits

7 changed files with 84 additions and 62 deletions

View File

@@ -2,7 +2,7 @@
Type=Application Type=Application
Name=NeoDLP Name=NeoDLP
Comment=Modern video/audio downloader based on yt-dlp with browser integration. Comment=Modern feature-rich video/audio downloader based on yt-dlp.
Icon=com.neosubhamoy.neodlp Icon=com.neosubhamoy.neodlp
Exec=neodlp Exec=neodlp
Terminal=false Terminal=false

View File

@@ -2,7 +2,7 @@
<component type="desktop-application"> <component type="desktop-application">
<id>com.neosubhamoy.neodlp</id> <id>com.neosubhamoy.neodlp</id>
<name>NeoDLP</name> <name>NeoDLP</name>
<summary>Modern video/audio downloader based on yt-dlp with browser integration</summary> <summary>Modern feature-rich video/audio downloader based on yt-dlp</summary>
<developer id="com.neosubhamoy"> <developer id="com.neosubhamoy">
<name>Subhamoy Biswas</name> <name>Subhamoy Biswas</name>
</developer> </developer>
@@ -15,7 +15,7 @@
<p> <p>
NeoDLP is a cross-platform desktop application designed for downloading videos and audio from various online sources based on yt-dlp. NeoDLP is a cross-platform desktop application designed for downloading videos and audio from various online sources based on yt-dlp.
It offers modern user interface, lots of customization options and seamless browser integration. It offers modern user interface, lots of features and customization options.
</p> </p>
</description> </description>
<launchable type="desktop-id">com.neosubhamoy.neodlp.desktop</launchable> <launchable type="desktop-id">com.neosubhamoy.neodlp.desktop</launchable>
@@ -39,8 +39,8 @@
</screenshots> </screenshots>
<content_rating type="oars-1.1" /> <content_rating type="oars-1.1" />
<releases> <releases>
<release version="0.4.2" date="2026-03-03"> <release version="0.4.3" date="2026-03-05">
<url type="details">https://github.com/neosubhamoy/neodlp/releases/tag/v0.4.2</url> <url type="details">https://github.com/neosubhamoy/neodlp/releases/tag/v0.4.3</url>
</release> </release>
</releases> </releases>
</component> </component>

View File

@@ -119,6 +119,21 @@
"name": "deno", "name": "deno",
"cmd": "deno", "cmd": "deno",
"args": true "args": true
},
{
"name": "pkexec",
"cmd": "pkexec",
"args": true
},
{
"name": "powershell",
"cmd": "powershell",
"args": true
},
{
"name": "sh",
"cmd": "sh",
"args": true
} }
] ]
} }

View File

@@ -1,8 +1,8 @@
{ {
"identifier": "com.neosubhamoy.neodlp", "identifier": "com.neosubhamoy.neodlp",
"build": { "build": {
"beforeDevCommand": "cargo build --manifest-path=./src-tauri/msghost/Cargo.toml && npm run dev", "beforeDevCommand": "npm run dev",
"beforeBuildCommand": "cargo build --release --manifest-path=./src-tauri/msghost/Cargo.toml && npm run build", "beforeBuildCommand": "npm run build",
"devUrl": "http://localhost:1420", "devUrl": "http://localhost:1420",
"frontendDist": "../dist" "frontendDist": "../dist"
}, },
@@ -38,11 +38,7 @@
], ],
"externalBin": [ "externalBin": [
"binaries/yt-dlp", "binaries/yt-dlp",
"binaries/ffmpeg", "binaries/deno"
"binaries/ffprobe",
"binaries/aria2c",
"binaries/deno",
"binaries/neodlp-pot"
], ],
"resources": { "resources": {
"resources/plugins/yt-dlp-plugins/": "yt-dlp-plugins/" "resources/plugins/yt-dlp-plugins/": "yt-dlp-plugins/"

View File

@@ -1403,6 +1403,8 @@ function AppPoTokenSettings() {
function AppNotificationSettings() { function AppNotificationSettings() {
const { saveSettingsKey } = useSettings(); const { saveSettingsKey } = useSettings();
const isFlatpak = useEnvironmentStore(state => state.isFlatpak);
const enableNotifications = useSettingsPageStatesStore(state => state.settings.enable_notifications); const enableNotifications = useSettingsPageStatesStore(state => state.settings.enable_notifications);
const updateNotification = useSettingsPageStatesStore(state => state.settings.update_notification); const updateNotification = useSettingsPageStatesStore(state => state.settings.update_notification);
const downloadCompletionNotification = useSettingsPageStatesStore(state => state.settings.download_completion_notification); const downloadCompletionNotification = useSettingsPageStatesStore(state => state.settings.download_completion_notification);
@@ -1416,6 +1418,7 @@ function AppNotificationSettings() {
<Switch <Switch
id="enable-notifications" id="enable-notifications"
checked={enableNotifications} checked={enableNotifications}
disabled={isFlatpak}
onCheckedChange={async (checked) => { onCheckedChange={async (checked) => {
if (checked) { if (checked) {
const granted = await isPermissionGranted(); const granted = await isPermissionGranted();
@@ -1441,7 +1444,7 @@ function AppNotificationSettings() {
id="update-notification" id="update-notification"
checked={updateNotification} checked={updateNotification}
onCheckedChange={(checked) => saveSettingsKey('update_notification', checked)} onCheckedChange={(checked) => saveSettingsKey('update_notification', checked)}
disabled={!enableNotifications} disabled={!enableNotifications || isFlatpak}
/> />
<Label htmlFor="update-notification">App Updates</Label> <Label htmlFor="update-notification">App Updates</Label>
</div> </div>
@@ -1450,7 +1453,7 @@ function AppNotificationSettings() {
id="download-completion-notification" id="download-completion-notification"
checked={downloadCompletionNotification} checked={downloadCompletionNotification}
onCheckedChange={(checked) => saveSettingsKey('download_completion_notification', checked)} onCheckedChange={(checked) => saveSettingsKey('download_completion_notification', checked)}
disabled={!enableNotifications} disabled={!enableNotifications || isFlatpak}
/> />
<Label htmlFor="download-completion-notification">Download Completion</Label> <Label htmlFor="download-completion-notification">Download Completion</Label>
</div> </div>
@@ -1813,7 +1816,7 @@ function AppInfoSettings() {
<TriangleAlert className="size-4 stroke-primary" /> <TriangleAlert className="size-4 stroke-primary" />
<AlertTitle className="text-sm">Flatpak Sandbox Detected!</AlertTitle> <AlertTitle className="text-sm">Flatpak Sandbox Detected!</AlertTitle>
<AlertDescription className="text-xs"> <AlertDescription className="text-xs">
It looks like you are running NeoDLP in a Flatpak sandbox. Some features like changing download folder, revealing completed downloads in explorer and automatic yt-dlp updates are not available in Flatpak due to sandbox restrictions. To use these features, please install the native build (DEB, RPM or AUR) of NeoDLP. It looks like you are running NeoDLP in a Flatpak sandbox. Some features like browser integration, desktop notifications, changing download folder, revealing completed downloads in explorer, automatic yt-dlp updates and auto-launch on startup are not available in Flatpak due to sandbox restrictions. To use these features, please install the native linux build (DEB, RPM or AUR) of NeoDLP.
</AlertDescription> </AlertDescription>
</Alert> </Alert>
) : isAppimage ? ( ) : isAppimage ? (
@@ -1821,7 +1824,7 @@ function AppInfoSettings() {
<TriangleAlert className="size-4 stroke-primary" /> <TriangleAlert className="size-4 stroke-primary" />
<AlertTitle className="text-sm">Appimage Environment Detected!</AlertTitle> <AlertTitle className="text-sm">Appimage Environment Detected!</AlertTitle>
<AlertDescription className="text-xs"> <AlertDescription className="text-xs">
Looks like you are using NeoDLP Appimage. NeoDLP's browser integration features are not available on Appimage environment due to it's limitations. To use NeoDLP's browser integration features please install the native build (DEB, RPM or AUR) of NeoDLP. Looks like you are using NeoDLP Appimage. NeoDLP's browser integration features are not available on Appimage environment due to it's limitations. To use NeoDLP's browser integration features please install the native linux build (DEB, RPM or AUR) of NeoDLP.
</AlertDescription> </AlertDescription>
</Alert> </Alert>
) : ( ) : (

View File

@@ -2,7 +2,7 @@ import { join, resourceDir, homeDir } from "@tauri-apps/api/path";
import * as fs from "@tauri-apps/plugin-fs"; import * as fs from "@tauri-apps/plugin-fs";
import { useKvPairs } from "@/helpers/use-kvpairs"; import { useKvPairs } from "@/helpers/use-kvpairs";
import { useSettingsPageStatesStore } from "@/services/store"; import { useSettingsPageStatesStore } from "@/services/store";
import { Command } from "@tauri-apps/plugin-shell"; // import { Command } from "@tauri-apps/plugin-shell";
import { invoke } from "@tauri-apps/api/core"; import { invoke } from "@tauri-apps/api/core";
interface FileMap { interface FileMap {
@@ -21,20 +21,20 @@ export function useLinuxRegisterer() {
const isFlatpak = await invoke<boolean>('is_flatpak'); const isFlatpak = await invoke<boolean>('is_flatpak');
const resourceDirPath = isFlatpak ? '/app/lib/neodlp' : await resourceDir(); const resourceDirPath = isFlatpak ? '/app/lib/neodlp' : await resourceDir();
const homeDirPath = await homeDir(); const homeDirPath = await homeDir();
const flatpakChromeManifestContent = { // const flatpakChromeManifestContent = {
name: "com.neosubhamoy.neodlp", // name: "com.neosubhamoy.neodlp",
description: "NeoDLP MsgHost", // description: "NeoDLP MsgHost",
path: `${homeDirPath}/.local/bin/neodlp-msghost`, // path: `${homeDirPath}/.local/bin/neodlp-msghost`,
type: "stdio", // type: "stdio",
allowed_origins: ["chrome-extension://mehopeailfjmiloiiohgicphlcgpompf/"] // allowed_origins: ["chrome-extension://mehopeailfjmiloiiohgicphlcgpompf/"]
}; // };
const flatpakFirefoxManifestContent = { // const flatpakFirefoxManifestContent = {
name: "com.neosubhamoy.neodlp", // name: "com.neosubhamoy.neodlp",
description: "NeoDLP MsgHost", // description: "NeoDLP MsgHost",
path: `${homeDirPath}/.local/bin/neodlp-msghost`, // path: `${homeDirPath}/.local/bin/neodlp-msghost`,
type: "stdio", // type: "stdio",
allowed_extensions: ["neodlp@neosubhamoy.com"] // allowed_extensions: ["neodlp@neosubhamoy.com"]
}; // };
const filesToCopy: FileMap[] = [ const filesToCopy: FileMap[] = [
{ source: 'yt-dlp-plugins/bgutil-ytdlp-pot-provider/yt_dlp_plugins/extractor/getpot_bgutil.py', destination: 'yt-dlp-plugins/bgutil-ytdlp-pot-provider/yt_dlp_plugins/extractor/getpot_bgutil.py', dir: 'yt-dlp-plugins/bgutil-ytdlp-pot-provider/yt_dlp_plugins/extractor/' }, { source: 'yt-dlp-plugins/bgutil-ytdlp-pot-provider/yt_dlp_plugins/extractor/getpot_bgutil.py', destination: 'yt-dlp-plugins/bgutil-ytdlp-pot-provider/yt_dlp_plugins/extractor/getpot_bgutil.py', dir: 'yt-dlp-plugins/bgutil-ytdlp-pot-provider/yt_dlp_plugins/extractor/' },
@@ -42,39 +42,42 @@ export function useLinuxRegisterer() {
{ source: 'yt-dlp-plugins/bgutil-ytdlp-pot-provider/yt_dlp_plugins/extractor/getpot_bgutil_http.py', destination: 'yt-dlp-plugins/bgutil-ytdlp-pot-provider/yt_dlp_plugins/extractor/getpot_bgutil_http.py', dir: 'yt-dlp-plugins/bgutil-ytdlp-pot-provider/yt_dlp_plugins/extractor/' }, { source: 'yt-dlp-plugins/bgutil-ytdlp-pot-provider/yt_dlp_plugins/extractor/getpot_bgutil_http.py', destination: 'yt-dlp-plugins/bgutil-ytdlp-pot-provider/yt_dlp_plugins/extractor/getpot_bgutil_http.py', dir: 'yt-dlp-plugins/bgutil-ytdlp-pot-provider/yt_dlp_plugins/extractor/' },
]; ];
const filesToCopyFlatpak: FileMap[] = [ // const filesToCopyFlatpak: FileMap[] = [
{ source: 'chrome.json', destination: '.config/google-chrome/NativeMessagingHosts/com.neosubhamoy.neodlp.json', dir: '.config/google-chrome/NativeMessagingHosts/', content: JSON.stringify(flatpakChromeManifestContent) }, // { source: 'chrome.json', destination: '.config/google-chrome/NativeMessagingHosts/com.neosubhamoy.neodlp.json', dir: '.config/google-chrome/NativeMessagingHosts/', content: JSON.stringify(flatpakChromeManifestContent) },
{ source: 'chrome.json', destination: '.config/chromium/NativeMessagingHosts/com.neosubhamoy.neodlp.json', dir: '.config/chromium/NativeMessagingHosts/', content: JSON.stringify(flatpakChromeManifestContent) }, // { source: 'chrome.json', destination: '.config/chromium/NativeMessagingHosts/com.neosubhamoy.neodlp.json', dir: '.config/chromium/NativeMessagingHosts/', content: JSON.stringify(flatpakChromeManifestContent) },
{ source: 'firefox.json', destination: '.mozilla/native-messaging-hosts/com.neosubhamoy.neodlp.json', dir: '.mozilla/native-messaging-hosts/', content: JSON.stringify(flatpakFirefoxManifestContent) }, // { source: 'firefox.json', destination: '.mozilla/native-messaging-hosts/com.neosubhamoy.neodlp.json', dir: '.mozilla/native-messaging-hosts/', content: JSON.stringify(flatpakFirefoxManifestContent) },
{ source: 'neodlp-msghost', destination: '.local/bin/neodlp-msghost', dir: '.local/bin/' }, // { source: 'neodlp-msghost', destination: '.local/bin/neodlp-msghost', dir: '.local/bin/' },
]; // ];
if (isFlatpak) { if (isFlatpak) {
for (const file of filesToCopyFlatpak) { // Skip registration and just return success in flatpak
const sourcePath = await join(resourceDirPath, file.source); console.log('Running in Flatpak, Skipping registration...');
const destinationPath = await join(homeDirPath, file.destination);
const escapedContent = file.content?.replace(/'/g, `'\\''`) || '';
const copyCommand = Command.create('sh', ['-c', `cp "${sourcePath}" "${destinationPath}"`]);
const writeCommand = Command.create('sh', ['-c', `printf '%s' '${escapedContent}' > "${destinationPath}"`]);
if (file.content) { // for (const file of filesToCopyFlatpak) {
const writeOutput = await writeCommand.execute(); // const sourcePath = await join(resourceDirPath, file.source);
if (writeOutput.code === 0) { // const destinationPath = await join(homeDirPath, file.destination);
console.log(`File ${file.destination} created successfully at ${destinationPath}`); // const escapedContent = file.content?.replace(/'/g, `'\\''`) || '';
} else { // const copyCommand = Command.create('sh', ['-c', `cp "${sourcePath}" "${destinationPath}"`]);
console.error(`Failed to create file ${file.destination} at ${destinationPath}:`, writeOutput.stderr); // const writeCommand = Command.create('sh', ['-c', `printf '%s' '${escapedContent}' > "${destinationPath}"`]);
return { success: false, message: 'Failed to register' };
} // if (file.content) {
} else { // const writeOutput = await writeCommand.execute();
const copyOutput = await copyCommand.execute(); // if (writeOutput.code === 0) {
if (copyOutput.code === 0) { // console.log(`File ${file.destination} created successfully at ${destinationPath}`);
console.log(`File ${file.source} copied successfully to ${destinationPath}`); // } else {
} else { // console.error(`Failed to create file ${file.destination} at ${destinationPath}:`, writeOutput.stderr);
console.error(`Failed to copy file ${file.source} to ${destinationPath}:`, copyOutput.stderr); // return { success: false, message: 'Failed to register' };
return { success: false, message: 'Failed to register' }; // }
} // } else {
} // const copyOutput = await copyCommand.execute();
} // if (copyOutput.code === 0) {
// console.log(`File ${file.source} copied successfully to ${destinationPath}`);
// } else {
// console.error(`Failed to copy file ${file.source} to ${destinationPath}:`, copyOutput.stderr);
// return { success: false, message: 'Failed to register' };
// }
// }
// }
} else { } else {
for (const file of filesToCopy) { for (const file of filesToCopy) {
const sourcePath = await join(resourceDirPath, file.source); const sourcePath = await join(resourceDirPath, file.source);

View File

@@ -17,7 +17,12 @@ export default function usePotServer() {
}; };
const startPotServer = async (port?: number) => { const startPotServer = async (port?: number) => {
const runCommand = Command.sidecar('binaries/neodlp-pot', [ const isFlatpak = await invoke<boolean>('is_flatpak');
const runCommand = isFlatpak
? Command.create('sh', [
'-c', `/app/bin/neodlp-pot server --port ${port ? port.toString() : potServerPort.toString()}`
])
: Command.sidecar('binaries/neodlp-pot', [
'server', 'server',
'--port', '--port',
port ? port.toString() : potServerPort.toString(), port ? port.toString() : potServerPort.toString(),