Removed app2png dependency

This commit is contained in:
Oliver Schwendener 2019-08-06 18:13:42 +02:00
parent 9920baf915
commit 286bed64d8
10 changed files with 113 additions and 93 deletions

View File

@ -42,7 +42,6 @@
"@types/lodash": "^4.14.130",
"@types/mathjs": "^5.0.1",
"@types/vue-color": "^2.4.2",
"app2png": "https://github.com/oliverschwendener/app2png",
"axios": "^0.18.0",
"electron": "^5.0.5",
"electron-builder": "^20.40.2",
@ -52,6 +51,7 @@
"jest": "^24.8.0",
"lodash": "^4.17.11",
"mathjs": "^5.10.3",
"simple-plist": "^1.0.0",
"ts-jest": "^24.0.2",
"ts-loader": "^6.0.1",
"tslint": "^5.16.0",

5
src/declarations.d.ts vendored Normal file
View File

@ -0,0 +1,5 @@
// Typescript type declarations
declare module "simple-plist" {
export function readFile(filePath: string, callback: (err: string, data: any) => void): void;
}

View File

@ -1,7 +1,5 @@
import { Application } from "./application";
import { join } from "path";
import { join, basename, extname } from "path";
import { createHash } from "crypto";
import { convert } from "app2png";
import { FileHelpers } from "../../../common/helpers/file-helpers";
import { ueliTempFolder } from "../../../common/helpers/ueli-helpers";
import { StringHelpers } from "../../../common/helpers/string-helpers";
@ -10,15 +8,15 @@ import { generateIcons, Icon } from "windows-system-icon";
export const applicationIconLocation = join(ueliTempFolder, "application-icons");
export const powershellScriptFilePath = join(ueliTempFolder, "generate-icons.ps1");
export function getApplicationIconFilePath(application: Application): string {
const hash = createHash("md5").update(`${application.filePath}`).digest("hex");
const fileName = `${StringHelpers.replaceWhitespace(application.name.toLowerCase(), "-")}-${hash}`;
export function getApplicationIconFilePath(applicationFilePath: string): string {
const hash = createHash("md5").update(`${applicationFilePath}`).digest("hex");
const fileName = `${StringHelpers.replaceWhitespace(basename(applicationFilePath).replace(extname(applicationFilePath), "").toLowerCase(), "-")}-${hash}`;
return `${join(applicationIconLocation, fileName)}.png`;
}
export function generateMacAppIcons(applications: Application[]): Promise<void> {
export function generateWindowsAppIcons(applicationFilePaths: string[]): Promise<void> {
return new Promise((resolve, reject) => {
if (applications.length === 0) {
if (applicationFilePaths.length === 0) {
resolve();
}
@ -28,34 +26,10 @@ export function generateMacAppIcons(applications: Application[]): Promise<void>
FileHelpers.createFolderSync(applicationIconLocation);
}
const promises = applications.map((application) => {
return convert(application.filePath, getApplicationIconFilePath(application));
});
Promise.all(promises)
.then(() => resolve())
.catch((err) => reject(err));
})
.catch((err) => reject(err));
});
}
export function generateWindowsAppIcons(applications: Application[]): Promise<void> {
return new Promise((resolve, reject) => {
if (applications.length === 0) {
resolve();
}
FileHelpers.fileExists(applicationIconLocation)
.then((fileExists) => {
if (!fileExists) {
FileHelpers.createFolderSync(applicationIconLocation);
}
const icons = applications.map((application): Icon => {
const icons = applicationFilePaths.map((applicationFilePath): Icon => {
return {
inputFilePath: application.filePath,
outputFilePath: getApplicationIconFilePath(application),
inputFilePath: applicationFilePath,
outputFilePath: getApplicationIconFilePath(applicationFilePath),
outputFormat: "Png",
};
});

View File

@ -1,18 +1,17 @@
import { Application } from "./application";
import { join } from "path";
import { applicationIconLocation } from "./application-icon-helpers";
import { FileHelpers } from "../../../common/helpers/file-helpers";
export class ApplicationIconService {
private readonly generateIcons: (applications: Application[]) => Promise<void>;
private readonly generateIcons: (applicationFilePaths: string[]) => Promise<void>;
constructor(generateIcons: (applications: Application[]) => Promise<void>) {
constructor(generateIcons: (applicationFilePaths: string[]) => Promise<void>) {
this.generateIcons = generateIcons;
}
public generateAppIcons(applications: Application[]): Promise<void> {
return new Promise((resolve, reject) => {
this.generateIcons(applications)
this.generateIcons(applications.map((app) => app.filePath))
.then(() => resolve())
.catch((err) => reject(err));
});
@ -22,7 +21,7 @@ export class ApplicationIconService {
return new Promise((resolve, reject) => {
FileHelpers.readFilesFromFolder(applicationIconLocation)
.then((files) => {
const deletionPromises = files.map((file) => FileHelpers.deleteFile(join(applicationIconLocation, file)));
const deletionPromises = files.map((file) => FileHelpers.deleteFile(file));
Promise.all(deletionPromises)
.then(() => resolve())
.catch((err) => reject(err));

View File

@ -52,7 +52,7 @@ export class FileApplicationRepository implements ApplicationRepository {
this.logger.error(err);
})
.finally(() => {
applications.forEach((application) => application.icon = getApplicationIconFilePath(application));
applications.forEach((application) => application.icon = getApplicationIconFilePath(application.filePath));
this.applications = applications;
resolve();
});

View File

@ -0,0 +1,72 @@
import { join } from "path";
import { FileHelpers } from "../../../common/helpers/file-helpers";
import * as plist from "simple-plist";
import { applicationIconLocation, getApplicationIconFilePath } from "./application-icon-helpers";
import { existsSync } from "fs";
import { executeCommand } from "../../executors/command-executor";
const defaultIcnsFilePath = "/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/GenericApplicationIcon.icns";
export function generateMacAppIcons(applicationFilePaths: string[]): Promise<void> {
return new Promise((resolve, reject) => {
if (applicationFilePaths.length === 0) {
resolve();
}
FileHelpers.fileExists(applicationIconLocation)
.then((fileExists) => {
if (!fileExists) {
FileHelpers.createFolderSync(applicationIconLocation);
}
Promise.all(applicationFilePaths.map((application) => generateMacAppIcon(application)))
.then(() => resolve())
.catch((err) => reject(err));
})
.catch((err) => reject(err));
});
}
function generateMacAppIcon(applicationFilePath: string): Promise<void> {
return new Promise((resolve, reject) => {
getPlistContent(applicationFilePath)
.then((data) => {
const icnsFilePath = getIcnsFilePath(applicationFilePath, data);
const outPngFilePath = getApplicationIconFilePath(applicationFilePath);
convertIcnsToPng(icnsFilePath, outPngFilePath)
.then(() => resolve())
.catch((err) => reject(err));
})
.catch((err) => reject(err));
});
}
function convertIcnsToPng(icnsFilePath: string, outFilePath: string): Promise<void> {
return executeCommand(`sips -s format png "${icnsFilePath}" --out "${outFilePath}"`);
}
function getIcnsFilePath(applicationFilePath: string, parsedPlistContent: any): string {
if (parsedPlistContent.CFBundleIconFile) {
if (!parsedPlistContent.CFBundleIconFile.endsWith(".icns")) {
parsedPlistContent.CFBundleIconFile += ".icns";
}
const icnsFilePath = join(applicationFilePath, "Contents", "Resources", parsedPlistContent.CFBundleIconFile);
return existsSync(icnsFilePath)
? icnsFilePath
: defaultIcnsFilePath;
} else {
return defaultIcnsFilePath;
}
}
function getPlistContent(applicationFilePath: string): Promise<any> {
return new Promise((resolve, reject) => {
plist.readFile(join(applicationFilePath, "Contents", "Info.plist"), (err: string, data: any) => {
if (err) {
reject(err);
} else {
resolve(data);
}
});
});
}

View File

@ -2,10 +2,10 @@ import { OperatingSystemSetting } from "./operating-system-setting";
import { OperatingSystemSettingRepository } from "./operating-system-setting-repository";
import { TranslationSet } from "../../../common/translation/translation-set";
import { FileHelpers } from "../../../common/helpers/file-helpers";
import { applicationIconLocation } from "../application-search-plugin/application-icon-helpers";
import { convert } from "app2png";
import { basename, join, extname } from "path";
import { getApplicationIconFilePath } from "../application-search-plugin/application-icon-helpers";
import { basename, extname } from "path";
import { IconType } from "../../../common/icon/icon-type";
import { generateMacAppIcons } from "../application-search-plugin/mac-os-app-icon-generator";
export class MacOsOperatingSystemSettingRepository implements OperatingSystemSettingRepository {
private readonly basePath = "/System/Library/PreferencePanes";
@ -14,8 +14,8 @@ export class MacOsOperatingSystemSettingRepository implements OperatingSystemSet
constructor() {
FileHelpers.readFilesFromFolder(this.basePath)
.then((filePaths) => {
Promise.all(filePaths.map((filePath) => this.buildOperatingSystemSetting(filePath)))
.then((results) => this.all = results)
generateMacAppIcons(filePaths)
.then(() => this.all = filePaths.map((filePath) => this.buildOperatingSystemSetting(filePath)))
.catch((err) => this.all = []);
})
.catch((err) => {
@ -29,20 +29,13 @@ export class MacOsOperatingSystemSettingRepository implements OperatingSystemSet
});
}
private buildOperatingSystemSetting(filePath: string): Promise<OperatingSystemSetting> {
return new Promise((resolve, reject) => {
const iconFilePath = join(applicationIconLocation, `${basename(filePath)}.png`);
convert(filePath, iconFilePath)
.then(() => {
resolve({
description: filePath,
executionArgument: filePath,
icon: { parameter: iconFilePath, type: IconType.URL },
name: basename(filePath).replace(extname(filePath), ""),
tags: [],
});
})
.catch((err) => reject(err));
});
private buildOperatingSystemSetting(filePath: string): OperatingSystemSetting {
return {
description: filePath,
executionArgument: filePath,
icon: { parameter: getApplicationIconFilePath(filePath), type: IconType.URL },
name: basename(filePath).replace(extname(filePath), ""),
tags: [],
};
}
}

View File

@ -2,7 +2,8 @@ import { ApplicationSearchPlugin } from "../plugins/application-search-plugin/ap
import { UserConfigOptions } from "../../common/config/user-config-options";
import { FileApplicationRepository } from "../plugins/application-search-plugin/file-application-repository";
import { ApplicationIconService } from "../plugins/application-search-plugin/application-icon-service";
import { generateMacAppIcons, generateWindowsAppIcons } from "../plugins/application-search-plugin/application-icon-helpers";
import { generateWindowsAppIcons } from "../plugins/application-search-plugin/application-icon-helpers";
import { generateMacAppIcons } from "../plugins/application-search-plugin/mac-os-app-icon-generator";
import { UeliCommandSearchPlugin } from "../plugins/ueli-command-search-plugin/ueli-command-search-plugin";
import { ShortcutsSearchPlugin } from "../plugins/shortcuts-search-plugin/shortcuts-search-plugin";
import { isWindows, isMacOs } from "../../common/helpers/operating-system-helpers";

View File

@ -49,5 +49,6 @@
},
"include": [
"./src/**/*.ts",
"./src/declarations.d.ts"
],
}

View File

@ -707,12 +707,6 @@ app-builder-lib@20.44.4, app-builder-lib@~20.44.4:
semver "^6.1.1"
temp-file "^3.3.3"
"app2png@https://github.com/oliverschwendener/app2png":
version "1.0.0"
resolved "https://github.com/oliverschwendener/app2png#6659dc041fa7dd36e8af0bd6de21e81915411f89"
dependencies:
simple-plist "^0.2.1"
aproba@^1.0.3, aproba@^1.1.1:
version "1.2.0"
resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a"
@ -894,11 +888,6 @@ balanced-match@^1.0.0:
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
base64-js@1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.1.2.tgz#d6400cac1c4c660976d90d07a04351d89395f5e8"
integrity sha1-1kAMrBxMZgl22Q0HoENR2JOV9eg=
base64-js@^1.0.2, base64-js@^1.2.3:
version "1.3.0"
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.0.tgz#cab1e6118f051095e58b5281aea8c1cd22bfc0e3"
@ -4781,15 +4770,6 @@ pkg-up@^3.0.1:
dependencies:
find-up "^3.0.0"
plist@2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/plist/-/plist-2.0.1.tgz#0a32ca9481b1c364e92e18dc55c876de9d01da8b"
integrity sha1-CjLKlIGxw2TpLhjcVch23p0B2os=
dependencies:
base64-js "1.1.2"
xmlbuilder "8.2.2"
xmldom "0.1.x"
plist@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/plist/-/plist-3.0.1.tgz#a9b931d17c304e8912ef0ba3bdd6182baf2e1f8c"
@ -5413,14 +5393,14 @@ signal-exit@^3.0.0, signal-exit@^3.0.2:
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=
simple-plist@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/simple-plist/-/simple-plist-0.2.1.tgz#71766db352326928cf3a807242ba762322636723"
integrity sha1-cXZts1IyaSjPOoByQrp2IyJjZyM=
simple-plist@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/simple-plist/-/simple-plist-1.0.0.tgz#bed3085633b22f371e111f45d159a1ccf94b81eb"
integrity sha512-043L2rO80LVF7zfZ+fqhsEkoJFvW8o59rt/l4ctx1TJWoTx7/jkiS1R5TatD15Z1oYnuLJytzE7gcnnBuIPL2g==
dependencies:
bplist-creator "0.0.7"
bplist-parser "0.1.1"
plist "2.0.1"
plist "^3.0.1"
simple-swizzle@^0.2.2:
version "0.2.2"
@ -6536,11 +6516,6 @@ xml-name-validator@^3.0.0:
resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a"
integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==
xmlbuilder@8.2.2:
version "8.2.2"
resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-8.2.2.tgz#69248673410b4ba42e1a6136551d2922335aa773"
integrity sha1-aSSGc0ELS6QuGmE2VR0pIjNap3M=
xmlbuilder@^9.0.7:
version "9.0.7"
resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d"