Skip to content

Commit 841c969

Browse files
committed
Refactor file paths to use path.join for cross-platform compatibility and improve error handling in directory creation. Enhance StremioService to check for Flatpak installation.
1 parent d40d50d commit 841c969

File tree

7 files changed

+121
-35
lines changed

7 files changed

+121
-35
lines changed

src/Main.ts

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import Properties from "./core/Properties";
77
import logger from "./utils/logger";
88
import StremioService from "./utils/StremioService";
99

10+
app.setName("stremio-enhanced");
11+
1012
let mainWindow: BrowserWindow | null;
1113

1214
app.commandLine.appendSwitch('use-angle', 'gl'); // Uses OpenGL for rendering. Having it on OpenGL enables the audio tracks menu in the video player
@@ -66,11 +68,25 @@ app.on("ready", async () => {
6668
logger.info("Running on Electron version: v" + process.versions.electron);
6769
logger.info("Running on Chromium version: v" + process.versions.chrome);
6870

71+
logger.info("User data path: " + app.getPath("userData"));
72+
logger.info("Themes path: " + Properties.themesPath);
73+
logger.info("Plugins path: " + Properties.pluginsPath);
74+
6975
try {
70-
if(!existsSync(`${process.env.APPDATA}\\stremio-enhanced`)) mkdirSync(`${process.env.APPDATA}\\stremio-enhanced`);
71-
if(!existsSync(Properties.themesPath)) mkdirSync(Properties.themesPath);
72-
if(!existsSync(Properties.pluginsPath)) mkdirSync(Properties.pluginsPath);
73-
}catch {}
76+
const basePath = Properties.enhancedPath;
77+
78+
if (!existsSync(basePath)) {
79+
mkdirSync(basePath, { recursive: true });
80+
}
81+
if (!existsSync(Properties.themesPath)) {
82+
mkdirSync(Properties.themesPath, { recursive: true });
83+
}
84+
if (!existsSync(Properties.pluginsPath)) {
85+
mkdirSync(Properties.pluginsPath, { recursive: true });
86+
}
87+
} catch (err) {
88+
logger.error("Failed to create necessary directories: " + err);
89+
}
7490

7591
if(!process.argv.includes("--no-stremio-service")) {
7692
const stremioServicePath = StremioService.checkExecutableExists();

src/Preload.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import DiscordPresence from "./utils/DiscordPresence";
1010
import { getAboutCategoryTemplate } from "./components/about-category/aboutCategory";
1111
import { getDefaultThemeTemplate } from "./components/default-theme/defaultTheme";
1212
import logger from "./utils/logger";
13+
import { join } from "path";
14+
import { pathToFileURL } from "url";
1315

1416
window.addEventListener("load", async () => {
1517
intializeUserSettings();
@@ -102,7 +104,7 @@ window.addEventListener("load", async () => {
102104

103105
// add themes to the settings
104106
themesList.forEach(theme => {
105-
let readMetaData = Helpers.extractMetadataFromFile(`${properties.themesPath}\\${theme}`);
107+
let readMetaData = Helpers.extractMetadataFromFile(join(properties.themesPath, theme));
106108

107109
if (readMetaData && Object.keys(readMetaData).length > 0) {
108110
if(readMetaData.name.toLowerCase() != "default") Settings.addItem("theme", theme, readMetaData);
@@ -112,7 +114,7 @@ window.addEventListener("load", async () => {
112114

113115
// add plugins to the settings
114116
pluginsList.forEach(plugin => {
115-
let readMetaData = Helpers.extractMetadataFromFile(`${properties.pluginsPath}\\${plugin}`);
117+
let readMetaData = Helpers.extractMetadataFromFile(join(properties.pluginsPath, plugin));
116118
if (readMetaData && Object.keys(readMetaData).length > 0) Settings.addItem("plugin", plugin, readMetaData);
117119
})
118120

@@ -140,14 +142,14 @@ function applyUserTheme() {
140142
if(localStorage.getItem("currentTheme") != null) {
141143
let currentTheme = localStorage.getItem("currentTheme");
142144

143-
if(currentTheme != "Default" && existsSync(`${properties.themesPath}\\${currentTheme}`)) {
145+
if(currentTheme != "Default" && existsSync(join(properties.themesPath, currentTheme))) {
144146
if(document.getElementById("activeTheme")) document.getElementById("activeTheme").remove();
147+
const themePath = join(properties.themesPath, currentTheme);
145148

146149
let themeElement = document.createElement('link');
147150
themeElement.setAttribute("id", "activeTheme");
148151
themeElement.setAttribute("rel", "stylesheet");
149-
themeElement.setAttribute("href", `${properties.themesPath}\\${currentTheme}`);
150-
152+
themeElement.setAttribute("href", pathToFileURL(themePath).toString());
151153
document.head.appendChild(themeElement);
152154
} else {
153155
localStorage.setItem("currentTheme", "Default");

src/components/apply-theme/apply-theme.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ function applyTheme(theme) {
1010
const themeElement = document.createElement("link");
1111
themeElement.id = "activeTheme";
1212
themeElement.rel = "stylesheet";
13-
themeElement.href = `{{ themesPath }}\\\\${theme}`;
13+
themeElement.href = `{{ themesPath }}/${theme}`;
1414

1515
document.head.appendChild(themeElement);
1616
}
Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import { readFileSync } from 'fs';
2+
import { pathToFileURL } from 'url';
23
import Properties from '../../core/Properties';
34

45
export function getApplyThemeTemplate() {
5-
let template = readFileSync(__dirname + '/apply-theme.js', 'utf8');
6+
const template = readFileSync(__dirname + '/apply-theme.js', 'utf8');
7+
const themeBaseURL = pathToFileURL(Properties.themesPath).toString();
68

7-
return template
8-
.replace("{{ themesPath }}", Properties.themesPath.replace(/\\/g, "\\\\"));
9-
}
9+
return template.replace("{{ themesPath }}", themeBaseURL);
10+
}

src/core/ModManager.ts

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,14 @@ import MetaData from "../interfaces/MetaData";
77
import { getLogger } from "../utils/logger";
88
import Properties from "./Properties";
99
import { getApplyThemeTemplate } from "../components/apply-theme/applyTheme";
10+
import { join } from "path";
1011

1112
class ModManager {
1213
private static logger = getLogger("ModManager");
1314

1415
public static loadPlugin(pluginName:string) {
1516
if(document.getElementById(pluginName)) return;
16-
let plugin = readFileSync(`${Properties.pluginsPath}\\${pluginName}`, "utf-8");
17+
let plugin = readFileSync(join(properties.pluginsPath, pluginName), "utf-8");
1718
let script = document.createElement("script");
1819
script.innerHTML = plugin
1920
script.id = pluginName
@@ -77,23 +78,44 @@ class ModManager {
7778
})
7879
}
7980

80-
8181
public static openThemesFolder() {
8282
helpers.waitForElm("#openthemesfolderBtn").then(() => {
83-
let button = document.getElementById("openthemesfolderBtn");
84-
button.addEventListener("click", () => {
85-
exec(`start "" "${Properties.themesPath}"`);
86-
})
87-
})
83+
const button = document.getElementById("openthemesfolderBtn");
84+
button?.addEventListener("click", () => {
85+
this.openFolder(Properties.themesPath);
86+
});
87+
});
8888
}
89-
89+
9090
public static openPluginsFolder() {
9191
helpers.waitForElm("#openpluginsfolderBtn").then(() => {
92-
let button = document.getElementById("openpluginsfolderBtn");
93-
button.addEventListener("click", () => {
94-
exec(`start "" "${Properties.pluginsPath}"`);
95-
})
96-
})
92+
const button = document.getElementById("openpluginsfolderBtn");
93+
button?.addEventListener("click", () => {
94+
this.openFolder(Properties.pluginsPath);
95+
});
96+
});
97+
}
98+
99+
private static openFolder(folderPath: string) {
100+
let command: string;
101+
102+
switch (process.platform) {
103+
case "win32":
104+
command = `start "" "${folderPath}"`;
105+
break;
106+
case "darwin":
107+
command = `open "${folderPath}"`;
108+
break;
109+
default:
110+
command = `xdg-open "${folderPath}"`;
111+
break;
112+
}
113+
114+
exec(command, (error) => {
115+
if (error) {
116+
console.error(`Failed to open folder: ${folderPath}`, error);
117+
}
118+
});
97119
}
98120

99121
public static scrollListener() {
@@ -165,8 +187,8 @@ class ModManager {
165187
if(itemFile.endsWith(".theme.css")) pluginOrTheme = "theme";
166188
else pluginOrTheme = "plugin";
167189

168-
let itemPath = `${pluginOrTheme == "theme" ? properties.themesPath : properties.pluginsPath}\\${itemFile}`;
169-
190+
const itemPath = join(pluginOrTheme === "theme" ? properties.themesPath : properties.pluginsPath, itemFile);
191+
170192
let installedItemMetaData:MetaData = helpers.extractMetadataFromFile(itemPath);
171193
if (installedItemMetaData && Object.keys(installedItemMetaData).length > 0) {
172194
let updateUrl = installedItemMetaData.updateUrl;

src/core/Properties.ts

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,19 @@
1+
import { homedir } from "os";
2+
import { join } from "path";
3+
14
class Properties {
25
public static themeLinkSelector: string = "head > link[rel=stylesheet]";
3-
public static themesPath = `${process.env.APPDATA}\\stremio-enhanced\\themes`;
4-
public static pluginsPath = `${process.env.APPDATA}\\stremio-enhanced\\plugins`;
6+
7+
private static baseDataPath: string = process.platform === "win32"
8+
? process.env.APPDATA || join(homedir(), "AppData", "Roaming")
9+
: process.platform === "darwin"
10+
? join(homedir(), "Library", "Application Support")
11+
: join(homedir(), ".config");
12+
13+
public static enhancedPath = join(Properties.baseDataPath, "stremio-enhanced");
14+
15+
public static themesPath = join(Properties.enhancedPath, "themes");
16+
public static pluginsPath = join(Properties.enhancedPath, "plugins");
517
}
618

7-
export default Properties;
19+
export default Properties;

src/utils/StremioService.ts

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -119,9 +119,42 @@ class StremioService {
119119
installationPath = join('/Applications', 'StremioService.app', 'Contents', 'MacOS', 'stremio-service');
120120
break;
121121
case 'linux':
122-
installationPath = existsSync('/usr/local/bin/stremio-service') ? '/usr/local/bin/stremio-service' :
123-
existsSync('/usr/bin/stremio-service') ? '/usr/bin/stremio-service' :
124-
join(process.env.HOME || '', 'bin', 'stremio-service');
122+
const standardPaths = [
123+
'/usr/local/bin/stremio-service',
124+
'/usr/bin/stremio-service',
125+
join(process.env.HOME || '', 'bin', 'stremio-service')
126+
];
127+
128+
for (const path of standardPaths) {
129+
if (existsSync(path)) {
130+
installationPath = path;
131+
break;
132+
}
133+
}
134+
135+
// If not found in standard paths, check for Flatpak installation
136+
if (!installationPath) {
137+
try {
138+
const execSync = require('child_process').execSync;
139+
const flatpakPath = execSync('which flatpak').toString().trim();
140+
141+
if (flatpakPath) {
142+
// Check if the Stremio Service Flatpak is installed
143+
const installed = execSync('flatpak list --app').toString();
144+
if (installed.includes('com.stremio.Service')) {
145+
const flatpakInstallPath = execSync('flatpak info --show-location com.stremio.Service')
146+
.toString().trim();
147+
148+
const flatpakExecutable = join(flatpakInstallPath, 'files', 'bin', 'stremio-service');
149+
if (existsSync(flatpakExecutable)) {
150+
installationPath = flatpakExecutable;
151+
}
152+
}
153+
}
154+
} catch (e) {
155+
this.logger.error("Flatpak check failed: " + e.message);
156+
}
157+
}
125158
break;
126159
default:
127160
this.logger.error('Unsupported operating system');

0 commit comments

Comments
 (0)