Skip to content

Commit

Permalink
Added option to use favicons for browser bookmarks
Browse files Browse the repository at this point in the history
  • Loading branch information
oliverschwendener committed Oct 12, 2019
1 parent acdcf1a commit bd23b21
Show file tree
Hide file tree
Showing 12 changed files with 245 additions and 7 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,14 @@
"package:publish": "./node_modules/.bin/electron-builder --config electron-builder-config.yml --publish onTag"
},
"devDependencies": {
"@types/cheerio": "^0.22.13",
"@types/color": "^3.0.0",
"@types/jest": "^24.0.17",
"@types/mathjs": "^5.0.1",
"@types/node-powershell": "^3.1.0",
"@types/vue-color": "^2.4.2",
"axios": "^0.19.0",
"cheerio": "^1.0.0-rc.3",
"color": "^3.1.2",
"electron": "^5.0.9",
"electron-builder": "^21.2.0",
Expand Down
2 changes: 2 additions & 0 deletions src/common/config/browser-bookmarks-options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ import { Browser } from "../../main/plugins/browser-bookmarks-plugin/browser";
export interface BrowserBookmarksOptions {
isEnabled: boolean;
browser: Browser;
useFavicons: boolean;
}

export const defaultBrowserBookmarksOptions: BrowserBookmarksOptions = {
browser: Browser.GoogleChrome,
isEnabled: true,
useFavicons: false,
};
1 change: 1 addition & 0 deletions src/common/translation/english-translation-set.ts
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,7 @@ export const englishTranslationSet: TranslationSet = {
browserBookmarks: "Browser Bookmarks",
browserBookmarksDescription: "This plugin enables you to search your browser bookmarks.",
browserBookmarksBrowser: "Browser",
browserBookmarksUseFavicons: "Use favicons",
browserBookmark: "Bookmark",

cancel: "Cancel",
Expand Down
1 change: 1 addition & 0 deletions src/common/translation/german-translation-set.ts
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,7 @@ export const germanTranslationSet: TranslationSet = {
browserBookmarks: "Browser Lesezeichen",
browserBookmarksDescription: "Dieses Plugin erlaubt es dir die Lesezeichen deines Browser zu durchsuchen.",
browserBookmarksBrowser: "Browser",
browserBookmarksUseFavicons: "Favicons benutzen",
browserBookmark: "Lesezeichen",

cancel: "Abbrechen",
Expand Down
1 change: 1 addition & 0 deletions src/common/translation/translation-set.ts
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,7 @@ export interface TranslationSet {
browserBookmarks: string;
browserBookmarksBrowser: string;
browserBookmarksDescription: string;
browserBookmarksUseFavicons: string;
browserBookmark: string;

cancel: string;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { BrowserBookmark } from "./browser-bookmark";
import { Browser } from "./browser";
import { Icon } from "../../../common/icon/icon";

export interface BrowserBookmarkRepository {
browser: Browser;
defaultIcon: Icon;
getBrowserBookmarks(): Promise<BrowserBookmark[]>;
updateUseFaviconOption(useNativeIcons: boolean): void;
}
3 changes: 3 additions & 0 deletions src/main/plugins/browser-bookmarks-plugin/browser-bookmark.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import { Icon } from "../../../common/icon/icon";

export interface BrowserBookmark {
name: string;
url: string;
icon: Icon;
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { PluginType } from "../../plugin-type";
import { SearchResultItem } from "../../../common/search-result-item";
import { UserConfigOptions } from "../../../common/config/user-config-options";
import { TranslationSet } from "../../../common/translation/translation-set";
import { defaultBookmarkIcon } from "../../../common/icon/default-icons";
import { BrowserBookmark } from "./browser-bookmark";
import { BrowserBookmarksOptions } from "../../../common/config/browser-bookmarks-options";
import { BrowserBookmarkRepository } from "./browser-bookmark-repository";
Expand Down Expand Up @@ -63,7 +62,17 @@ export class BrowserBookmarksPlugin implements SearchPlugin {
public updateConfig(updatedConfig: UserConfigOptions, translationSet: TranslationSet): Promise<void> {
return new Promise((resolve, reject) => {
this.translations = translationSet;
if (updatedConfig.browserBookmarksOptions.browser !== this.config.browser) {

const browserChanged = updatedConfig.browserBookmarksOptions.browser !== this.config.browser;
const useFaviconsOptionChanged = updatedConfig.browserBookmarksOptions.useFavicons !== this.config.useFavicons;

if (useFaviconsOptionChanged) {
this.browserBookmarkRepositories.forEach((browserBookmarkRepository) => {
browserBookmarkRepository.updateUseFaviconOption(updatedConfig.browserBookmarksOptions.useFavicons);
});
}

if (useFaviconsOptionChanged || browserChanged) {
this.config = updatedConfig.browserBookmarksOptions;
this.refreshIndex()
.then(() => resolve())
Expand Down Expand Up @@ -97,7 +106,7 @@ export class BrowserBookmarksPlugin implements SearchPlugin {
: `${this.config.browser} ${this.translations.browserBookmark}`,
executionArgument: browserBookmark.url,
hideMainWindowAfterExecution: true,
icon: defaultBookmarkIcon,
icon: browserBookmark.icon,
name: browserBookmark.name || browserBookmark.url,
needsUserConfirmationBeforeExecution: false,
originPluginType: this.pluginType,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,24 @@ import { BrowserBookmark } from "./browser-bookmark";
import { FileHelpers } from "../../../common/helpers/file-helpers";
import { isValidUrl } from "../../../common/helpers/url-helpers";
import { Browser } from "./browser";
import axios from "axios";
import * as cheerio from "cheerio";
import { IconType } from "../../../common/icon/icon-type";
import { Icon } from "../../../common/icon/icon";

export class GoogleChromeBookmarkRepository implements BrowserBookmarkRepository {
public readonly browser = Browser.GoogleChrome;
public readonly defaultIcon: Icon = {
parameter: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48"><path fill="#4caf50" d="M44,24c0,11.044-8.956,20-20,20S4,35.044,4,24S12.956,4,24,4S44,12.956,44,24z"></path><path fill="#ffc107" d="M24,4v20l8,4l-8.843,16c0.317,0,0.526,0,0.843,0c11.053,0,20-8.947,20-20S35.053,4,24,4z"></path><path fill="#4caf50" d="M44,24c0,11.044-8.956,20-20,20S4,35.044,4,24S12.956,4,24,4S44,12.956,44,24z"></path><path fill="#ffc107" d="M24,4v20l8,4l-8.843,16c0.317,0,0.526,0,0.843,0c11.053,0,20-8.947,20-20S35.053,4,24,4z"></path><path fill="#f44336" d="M41.84,15H24v13l-3-1L7.16,13.26H7.14C10.68,7.69,16.91,4,24,4C31.8,4,38.55,8.48,41.84,15z"></path><path fill="#dd2c00" d="M7.158,13.264l8.843,14.862L21,27L7.158,13.264z"></path><path fill="#558b2f" d="M23.157,44l8.934-16.059L28,25L23.157,44z"></path><path fill="#f9a825" d="M41.865,15H24l-1.579,4.58L41.865,15z"></path><path fill="#fff" d="M33,24c0,4.969-4.031,9-9,9s-9-4.031-9-9s4.031-9,9-9S33,19.031,33,24z"></path><path fill="#2196f3" d="M31,24c0,3.867-3.133,7-7,7s-7-3.133-7-7s3.133-7,7-7S31,20.133,31,24z"></path></svg>`,
type: IconType.SVG,
};

private readonly bookmarkFilePath: string;
private useFavicons: boolean;

constructor(bookmarkFilePath: string) {
constructor(bookmarkFilePath: string, useFavicons: boolean) {
this.bookmarkFilePath = bookmarkFilePath;
this.useFavicons = useFavicons;
}

public getBrowserBookmarks(): Promise<BrowserBookmark[]> {
Expand All @@ -21,7 +32,11 @@ export class GoogleChromeBookmarkRepository implements BrowserBookmarkRepository
.then((data) => {
const jsonParsed = JSON.parse(data);
const bookmarks: BrowserBookmark[] = this.getBookmarksFromObject(jsonParsed.roots.bookmark_bar);
resolve(bookmarks);
this.getIcons(bookmarks)
.then((result) => {
resolve(result);
})
.catch((err) => reject(err));
})
.catch((err) => reject(`Can't read bookmarks file: ${err}`));
} else {
Expand All @@ -32,6 +47,10 @@ export class GoogleChromeBookmarkRepository implements BrowserBookmarkRepository
});
}

public updateUseFaviconOption(useFavicons: boolean) {
this.useFavicons = useFavicons;
}

private getBookmarksFromObject(data: any): any[] {
let result: any[] = [];

Expand All @@ -57,4 +76,65 @@ export class GoogleChromeBookmarkRepository implements BrowserBookmarkRepository

return result;
}

private getIcons(bookmarks: BrowserBookmark[]): Promise<BrowserBookmark[]> {
return new Promise((resolve, reject) => {
if (bookmarks.length === 0) {
resolve([]);
} else {
const promises = bookmarks.map((bookmark) => this.getIcon(bookmark));
Promise.all(promises)
.then((result) => {
resolve(result);
})
.catch((err) => reject(err));
}
});
}

private getIcon(bookmark: BrowserBookmark): Promise<BrowserBookmark> {
return new Promise((resolve) => {
const handleResult = (icon?: Icon) => {
if (icon) {
bookmark.icon = icon;
} else {
bookmark.icon = this.defaultIcon;
}
resolve(bookmark);
};

if (this.useFavicons) {
axios.get(bookmark.url)
.then((data) => {
const $ = cheerio.load(data.data);
const favicons = $(`link[rel="icon"]`).toArray();
if (favicons.length > 0) {
if (favicons[0].attribs && favicons[0].attribs.href) {
handleResult({
parameter: this.getFaviconUrl(favicons[0].attribs.href, bookmark),
type: IconType.URL,
});
} else {
handleResult();
}
} else {
handleResult();
}
})
.catch(() => handleResult());
} else {
handleResult();
}
});
}

private getFaviconUrl(faviconUrl: string, bookmark: BrowserBookmark): string {
if (!faviconUrl.startsWith("http://") &&
!faviconUrl.startsWith("https://") &&
!faviconUrl.startsWith("www.")) {
const slash = faviconUrl.startsWith("/") ? "" : "/";
faviconUrl = `http://${new URL(bookmark.url).host}${slash}${faviconUrl}`;
}
return faviconUrl;
}
}
2 changes: 1 addition & 1 deletion src/main/production/production-search-engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ export function getProductionSearchEngine(config: UserConfigOptions, translation
new BrowserBookmarksPlugin(
config.browserBookmarksOptions,
translationSet,
[new GoogleChromeBookmarkRepository(chromeBookmarksFilePath)],
[new GoogleChromeBookmarkRepository(chromeBookmarksFilePath, config.browserBookmarksOptions.useFavicons)],
urlExecutor,
),
];
Expand Down
12 changes: 12 additions & 0 deletions src/renderer/settings/browser-bookmark-settings-component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,18 @@ export const browserBookmarkSettingsComponent = Vue.extend({
</div>
</div>
<div class="settings__option">
<div class="settings__option-name">{{ translations.browserBookmarksUseFavicons }}</div>
<div class="settings__option-content">
<div class="field is-grouped is-grouped-right">
<div class="control">
<input id="useFaviconsToggle" type="checkbox" name="useFaviconsToggle" class="switch is-rounded is-success" checked="checked" v-model="config.browserBookmarksOptions.useFavicons" @change="updateConfig">
<label for="useFaviconsToggle"></label>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
Expand Down
Loading

0 comments on commit bd23b21

Please sign in to comment.