Skip to content

Commit b4e176e

Browse files
committed
Added several features, including copying existing protected .desktop files into the .local folder for modification.
1 parent 9454645 commit b4e176e

File tree

5 files changed

+93
-28
lines changed

5 files changed

+93
-28
lines changed

.npmignore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
.gitignore
2+
.npmignore
3+
.github/
4+
node_modules/
5+
package-lock.json
6+
*.tgz
7+
*.tar
8+
*.zip

README.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ However, you are free to pass in whole slew of options:
1919
--help display help
2020
--view View file
2121
--edit Call your editor with the file
22-
--list List all desktop files
22+
--list <optional filter> List all desktop files
23+
--changelog Show the changelog
2324
2425
-d, --desktop <file> Desktop file to use
2526
-k, --keywords <keywords> Set keywords
@@ -31,6 +32,11 @@ However, you are free to pass in whole slew of options:
3132
--json <key> Set key/values from JSON
3233
```
3334

35+
#### Extra Features Usage
36+
`--list` has an optional filter, so you can do
37+
`desktopmenuitem --list .local` and it will only show `.desktop` files in a folder that has `.local` in it.
38+
39+
3440

3541
### Notes
3642
- [.desktop spec](https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html)
@@ -41,5 +47,3 @@ However, you are free to pass in whole slew of options:
4147
- Does not preserve any comments in an existing file
4248
- The underlying ini load/save module doesn't support this yet. I would be willing to switch for another no-dependency ini module. (PR would be welcome)
4349

44-
- Edits the original .desktop file, so you must have sudo rights if you are editing a .desktop file in a protected folder.
45-
- Technically, I believe it should create the "edited" menu item in your ~/.local... folder, this could easily be added, PR would be accepted.

changelog

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
0.0.1 - First version (unreleased)
2+
0.0.2 - First Released version
3+
0.0.3 - Added call desktop-update-database after modification to make sure mime cache is updated.
4+
0.0.4 - Added --changelog, filter to --list, automatically now save changed .desktop in the .local folder.

menuitem.js

Lines changed: 73 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ const pathsToCheck = [process.env.HOME+'/.local/share/applications/', '/usr/loca
2929
addPathsToCheck(process.env['XDG_DATA_DIRS']?.split(":") || []);
3030
addPathsToCheck(process.env['XDG_DATA_HOME']?.split(':') || []);
3131

32+
const isRoot = process.getuid() === 0 || process.getgid() === 0;
3233

3334
// noinspection SpellCheckingInspection
3435
console.log("\r\ndesktopmenuitem".blue,version.blue, "\r\n---------------------");
@@ -40,6 +41,8 @@ program.description('An application for creating or editing .desktop files');
4041
program.option("--view", "View .desktop file");
4142
program.option("--edit", "Call your editor with the .desktop file");
4243
program.option("--list", "List all .desktop files" );
44+
program.option("--changelog", "Display the changelog");
45+
program.option("--overwrite", "Over write the original file location, if root.")
4346
program.option("-d, --desktop <file>", "Desktop file to use");
4447
program.option("-k, --keywords <keywords>", "Set keywords");
4548
program.option("-m, --mime <type>", "Set mime type");
@@ -56,10 +59,30 @@ const options = program.opts();
5659

5760
// List Directories
5861
if (options.list) {
59-
pathsToCheck.forEach((val) => {
60-
listDirectory(val);
61-
console.log("");
62-
});
62+
if (program.args.length) {
63+
pathsToCheck.forEach((val) => {
64+
if (val.indexOf(program.args[0]) >= 0) {
65+
listDirectory(val);
66+
console.log("");
67+
}
68+
});
69+
} else {
70+
pathsToCheck.forEach((val) => {
71+
listDirectory(val);
72+
console.log("");
73+
});
74+
}
75+
process.exit(0);
76+
}
77+
78+
// Show the Changelog
79+
if (options.changelog) {
80+
let startPath = path.normalize(process.argv[1].replace(path.basename(process.argv[1]),'') + "../lib/node_modules/@master.technology/desktopmenuitem/changelog");
81+
if (fs.existsSync(startPath)) {
82+
console.log(fs.readFileSync(startPath).toString());
83+
} else {
84+
console.log("Missing changelog".red);
85+
}
6386
process.exit(0);
6487
}
6588

@@ -100,7 +123,7 @@ if (program.args.length && program.args[0].endsWith(".desktop")) {
100123
// Figure out the Application Name to show as the Menu
101124
if (options.name == null || options.name.length === 0) {
102125
if (program.args.length) {
103-
options.dynamicName = cleanName(path.basename(program.args[0], ".desktop"));
126+
options.dynamicName = properCase(cleanName(path.basename(program.args[0], ".desktop")));
104127
} else if (options.desktop != null && options.desktop.length) {
105128
options.dynamicName = path.basename(options.desktop, ".desktop");
106129
}
@@ -116,30 +139,30 @@ if (options.exec == null || options.exec.length === 0) {
116139
}
117140

118141
const info = loadFile(desktopFile);
119-
if (options.edit && !info._created) {
120-
spawnEditor(info._pathToDesktopFile);
121-
spawnUpdateDB(info._pathToDesktopFile.replace(path.basename(info._pathToDesktopFile), ''));
142+
if (options.edit && !info.__internal.created) {
143+
spawnEditor(info.__internal.pathWithDesktopFile);
144+
spawnUpdateDB(info.__internal.pathToDesktopFile);
122145
process.exit(0);
123146
}
124147

125148
// If they just want to view the file...
126149
if (options.view) {
150+
delete info.__internal;
127151
console.log(info);
128152
process.exit(0);
129153
}
130154

131-
if (configureDesktopEntry(info)) {
132-
// console.log(info);
133-
const fileName = info['_pathToDesktopFile'];
134-
delete info['_pathToDesktopFile'];
135-
delete info['_created'];
155+
if (configureDesktopEntry(info) || options.edit) {
156+
const fileName = info.__internal.pathWithDesktopFile;
157+
const pathToDesktopFile = info.__internal.pathToDesktopFile;
158+
delete info.__internal;
136159
fs.writeFileSync(fileName, ini.stringify(info));
137160
if (options.edit) {
138161
spawnEditor(fileName);
139162
} else {
140163
console.log("Saved:", fileName);
141164
}
142-
spawnUpdateDB(fileName.replace(path.basename(fileName), ''));
165+
spawnUpdateDB(pathToDesktopFile);
143166
} else {
144167
console.log("No Changes");
145168
}
@@ -153,7 +176,6 @@ if (configureDesktopEntry(info)) {
153176
* @param path
154177
*/
155178
function spawnUpdateDB(path) {
156-
console.log(path);
157179
const updater = ['/usr/bin/update-desktop-database'];
158180
for (let i=0;i<updater.length;i++) {
159181
if (fs.existsSync(updater[i])) {
@@ -259,7 +281,6 @@ function cleanName(name) {
259281
// Remove known app extensions
260282
let newName = name.replace(/\.appimage/gi,"");
261283

262-
263284
let offset=0;
264285
do {
265286
offset = findFirstOffset(newName, offset);
@@ -284,8 +305,7 @@ function cleanName(name) {
284305
}
285306
} while (offset !== -1);
286307

287-
// Upper case first letter
288-
return newName.substr(0,1).toUpperCase()+newName.substr(1);
308+
return newName;
289309
}
290310

291311
/**
@@ -336,18 +356,20 @@ function listDirectory(path) {
336356
/**
337357
* This finds and loads a .desktop file, or creates a new .desktop file
338358
* @param fileName
339-
* @returns {{"Desktop Entry": {Exec: string, Type: string, Keywords: string, Categories: string, Icon: string, Terminal: boolean, MimeType: string, Name: string}, _created: boolean, _pathToDesktopFile: string}|*}
359+
* @returns {object}
340360
*/
361+
341362
function loadFile(fileName) {
342363
//console.log("Searching for:", fileName.blue);
343364
for (let i=0;i<pathsToCheck.length;i++) {
365+
//console.log("Looking at", pathsToCheck[i] + fileName)
344366
if (fs.existsSync(pathsToCheck[i]+fileName)) {
345-
console.log("Loading:", (pathsToCheck[i]+ fileName).blue);
367+
console.log("Loading:", (pathsToCheck[i] + fileName).blue);
346368
return parseFile(pathsToCheck[i] + fileName);
347369
}
348370
}
349371

350-
console.log("Creating:", (pathsToCheck[0]+fileName).blue);
372+
console.log("Creating:", (pathsToCheck[0]+properCase(fileName)).blue);
351373
return {
352374
"Desktop Entry":
353375
{
@@ -360,8 +382,12 @@ function loadFile(fileName) {
360382
Icon: '',
361383
Exec: ''
362384
},
363-
_pathToDesktopFile: pathsToCheck[0] + fileName,
364-
_created: true
385+
__internal: {
386+
pathToDesktopFile: pathsToCheck[0],
387+
desktopFile: fileName,
388+
pathWithDesktopFile: pathsToCheck[0] + properCase(fileName),
389+
created: true
390+
}
365391
};
366392
}
367393

@@ -371,8 +397,21 @@ function loadFile(fileName) {
371397
* @returns {object}
372398
*/
373399
function parseFile(file) {
400+
let created = false;
374401
let data = ini.parse(fs.readFileSync(file, 'utf-8'));
375-
data._pathToDesktopFile = file;
402+
if (file.indexOf(pathsToCheck[0]) !== 0) {
403+
if (!options.overwrite || !isRoot) {
404+
file = pathsToCheck[0] + path.basename(file);
405+
console.log("Saving as:", file.blue);
406+
created = true;
407+
}
408+
}
409+
data.__internal = {
410+
pathWithDesktopFile: file,
411+
desktopFile: path.basename(file),
412+
pathToDesktopFile: file.replace(path.basename(file), ''),
413+
created: created
414+
};
376415
return data;
377416
}
378417

@@ -402,3 +441,13 @@ function pathNormalize(inPath) {
402441
return path.normalize(process.cwd() + "/" + tempFile);
403442
}
404443
}
444+
445+
/**
446+
* Proper-cases a word
447+
* @param str
448+
* @returns {string}
449+
*/
450+
function properCase(str)
451+
{
452+
return str.toLowerCase().replace(/^(.)|\s(.)/g, function($1) { return $1.toUpperCase(); });
453+
}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@master.technology/desktopmenuitem",
3-
"version": "0.0.3",
3+
"version": "0.0.4",
44
"main": "menuitem.js",
55
"bin": {
66
"desktopmenuitem": "menuitem.js"

0 commit comments

Comments
 (0)