Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added the ability to see connectors that have been downloaded #1456

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/app/ElectronBootstrap.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ module.exports = class ElectronBootstrap {
];
this._directoryMap = {
'cache': this._configuration.applicationCacheDirectory,
'plugins': this._configuration.applicationUserPluginsDirectory
'plugins': this._configuration.applicationUserPluginsDirectory,
'root': this._configuration.applicationUserDataDirectory
hypoflex marked this conversation as resolved.
Show resolved Hide resolved
};
this._appIcon;
this._minimizeToTray = false; // only supported when tray is shown
Expand Down
42 changes: 36 additions & 6 deletions src/web/lib/hakuneko/frontend@classic-dark/connectors.html
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,34 @@
</template>
</div>
</div>
<div class="connectors">
Copy link
Contributor

@ronny1982 ronny1982 Apr 10, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All this duplicated code should not be added.
Just introduce a new checkbox or something to toggle between the full list of websites and the websites that have been downloaded. In the code behind, assign the corresponding list to the property which is bound to the dom-repeat template in the UI.

onClick(evt) {
    this.connectorList  = evt.value ? /* downloaded website list */ this.favoriteList : /* full website list */;
}

<div class="separator">
<i class="fas fa-times button clear" title="Reset all filters" on-click="clearFilters"></i>
<label>Favorites</label>
</div>
<div class="scroll">
<template is="dom-repeat" items="[[ favoriteList ]]" filter="[[ filterConnectors(connectorPattern, selectedTags) ]]">
<div class$="card [[ getConnectorClass(selectedConnector, item) ]]" title$="Click to show mangas from this website&#10;&#10;Label: [[ item.label ]]&#10;ID: [[ item.id ]]&#10;URL: [[ item.url ]]" on-click="selectConnector">
<img class="icon" src$="[[ item.icon ]]" onerror="this.src='/img/connectors/default';" />
<div class="description">
<div class="heading">
<div class="title">[[ item.label ]]</div>
<div class="control">
<i class$="fas fa-sign-in-alt link [[ getLoginClass(item.links) ]]" title="Click to open the login page" on-click="openLogin"></i>
<i class$="fas fa-coffee link [[ getDonationClass(item.links) ]]" title="Click to open the donation page" on-click="openDonation"></i>
<i class="fas fa-external-link-square-alt link active" title="Click to open the website in a new window&#10;This can be useful for various taks e.g.&#10;&#10;&#8226; Check / Investigate the website status&#10;&#8226; Bypass CloudFlare protection&#10;&#8226; Unlock a Captcha" on-click="openWebsite"></i>
</div>
</div>
<div>
<template is="dom-repeat" items="[[ item.tags ]]">
<span class="tag">[[ item ]]</span>
</template>
</div>
</div>
</div>
</template>
</div>
</div>
</div>
</div>
</template>
Expand Down Expand Up @@ -248,14 +276,16 @@
this.popupVisibility = false;
// list of all available connectors
this.connectorList = [];
this.favoriteList = [];
// load connectors
this.set( 'connectorList', Engine.Connectors );
this.set( 'favoriteList', Engine.Storage.downloadedConnectors );
this.tags = this.getAvailableTags();
this.selectedTags = [];
}

/**
*
*
*/
getAvailableTags() {
let tags = this.connectorList.reduce( ( accumulator, connector ) => {
Expand Down Expand Up @@ -322,23 +352,23 @@
evt.cancelBubble = true;
evt.stopPropagation();
}

/**
*
*/
openWebsite(evt) {
let item = evt.model.item;
this._openLink(evt, item.url);
}

/**
*
*/
openLogin(evt) {
let links = evt.model.item.links;
this._openLink(evt, links ? links.login : undefined);
}

/**
*
*/
Expand All @@ -348,7 +378,7 @@
}

/**
*
*
*/
toggleTag( event ) {
event.model.item.selected = !event.model.item.selected;
Expand Down Expand Up @@ -402,7 +432,7 @@
}

/**
*
*
*/
clearFilters() {
this.tags.forEach( tag => tag.selected = false);
Expand Down
7 changes: 7 additions & 0 deletions src/web/mjs/HakuNeko.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import BookmarkImporter from './engine/BookmarkImporter.mjs';
import BookmarkManager from './engine/BookmarkManager.mjs';
import ChaptermarkManager from './engine/ChaptermarkManager.mjs';
import Connectors from './engine/Connectors.mjs';
import Favorites from './engine/Favorites.mjs';
import DownloadManager from './engine/DownloadManager.mjs';
//import HistoryWorker from './engine/HistoryWorker.mjs'
import Request from './engine/Request.mjs';
Expand All @@ -29,6 +30,7 @@ export default class HakuNeko {
this._settings = new Settings();
this._request = new Request(ipc, this._settings);
this._connectors = new Connectors(ipc);
this._favorites = new Favorites(ipc);
this._storage = new Storage();
this._bookmarkManager = new BookmarkManager(this._settings, new BookmarkImporter());
this._chaptermarkManager = new ChaptermarkManager(this._settings);
Expand All @@ -51,6 +53,7 @@ export default class HakuNeko {

async initialize() {
await this._connectors.initialize();
await this._favorites.initialize();
}

get Blacklist() {
Expand All @@ -69,6 +72,10 @@ export default class HakuNeko {
return this._connectors.list;
}

get Favorites() {
return this._connectors.favoriteList;
}

get DownloadManager() {
return this._downloadManager;
}
Expand Down
7 changes: 7 additions & 0 deletions src/web/mjs/engine/Connectors.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export default class Connectors {
constructor(ipc) {
ipc.listen('on-connector-protocol-handler', this._onConnectorProtocolHandler.bind(this));
this._list = [];
this._favList = [];
}

async _loadPlugins(uri) {
Expand All @@ -24,16 +25,22 @@ export default class Connectors {
];
let userPlugins = await this._loadPlugins('hakuneko://plugins/');
let internalPlugins = await this._loadPlugins('hakuneko://cache/mjs/connectors/');
let favoritePlugins = Storage.downloadedConnectors;

await this.register(systemPlugins);
await this.register(userPlugins);
await this.register(internalPlugins);
await this.register(favoritePlugins);
}

get list() {
return this._list;
}

get favoriteList() {
return this._favList;
}

async register(files) {
try {
for(let file of files) {
Expand Down
66 changes: 66 additions & 0 deletions src/web/mjs/engine/Favorites.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
export default class Favorites {

constructor(ipc) {
ipc.listen('on-connector-protocol-handler', this._onConnectorProtocolHandler.bind(this));
this._list = [];
}

async _loadPlugins(uri) {
try {
let response = await fetch(uri);
let data = await response.json();
let cc = data.filter(plugin => plugin.startsWith('hakuneko.mangas.'));
let connectorName = [];
cc.forEach(file => {
let name = file.substr(file.indexOf('.', 15)+1);
connectorName.push("hakuneko://cache/mjs/connectors/" + name + ".mjs");
});
return connectorName;
hypoflex marked this conversation as resolved.
Show resolved Hide resolved
} catch(error) {
//console.warn(error);
return [];
}
}

async initialize() {
let favoritePlugins = await this._loadPlugins('hakuneko://root/');
await this.register(favoritePlugins);
}

get list() {
return this._list;
}

async register(files) {
try {
for(let file of files) {
try {
let module = await import(file);
let connector = new module.default();
if(this._list.find(c => c.id === connector.id)) {
console.warn(`The connector "${connector.label}" with ID "${connector.id}" is already registered`);
} else {
this._list.push(connector);
}
} catch(error) {
console.warn(`Failed to load connector "${file}"`, error);
}
}
this._list.sort( ( a, b ) => {
return ( a.label.toLowerCase() < b.label.toLowerCase() ? -1 : 1 );
} );
} catch(error) {
console.warn(`Failed to load connector`, error);
}
}

async _onConnectorProtocolHandler(request) {
try {
let uri = new URL(request.url);
return this._list.find(connector => connector.id === uri.hostname).handleConnectorURI(uri);
} catch(error) {
console.error(error);
return undefined;
}
}
}
17 changes: 17 additions & 0 deletions src/web/mjs/engine/Storage.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export default class Storage {
this.fs = require( 'fs' );
this.path = require( 'path' );
this.config = this.path.join( electron.remote.app.getPath( 'userData' ), 'hakuneko.' );
this.root = electron.remote.app.getPath( 'userData');
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

couldn't use this.config since it contains hakuneko in the path. i don't like rewriting original paths or duplicating variable values, this needs to change

this.temp = this.path.join( require( 'os' ).tmpdir(), 'hakuneko' );
this._createDirectoryChain( this.temp );

Expand Down Expand Up @@ -911,4 +912,20 @@ export default class Storage {
} );
} );
}

get downloadedConnectors() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just return a list of connector IDs (string), makes further processing much simpler.

//since this is a async function, isn't hakuneko startup waiting for this to be ran first?
//seems like performance drain
let rootDirectoryEntries = this._readDirectoryEntries(this.root);
let arrayFiltered = [];
rootDirectoryEntries.then(function(arrayRaw){
arrayRaw = arrayRaw.filter(plugin => plugin.startsWith('hakuneko.mangas.'));
arrayRaw.forEach(file => {
arrayFiltered.push(file.substr(file.indexOf('.', 15)+1));
});
return arrayFiltered;
})


}
}