Skip to content
This repository has been archived by the owner on Sep 29, 2023. It is now read-only.

Commit

Permalink
Cleanup (#6)
Browse files Browse the repository at this point in the history
  • Loading branch information
ronjouch authored Feb 27, 2021
1 parent 16fcf8a commit 4719a7e
Show file tree
Hide file tree
Showing 19 changed files with 321 additions and 362 deletions.
25 changes: 0 additions & 25 deletions .editorconfig

This file was deleted.

1 change: 0 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,4 @@ jobs:
with:
node-version: ${{ matrix.node-version }}
- run: npm install
- run: npm run build
- run: npm test
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
# Node.js
lib
coverage
*.tgz

# Logs
logs
Expand Down Expand Up @@ -39,3 +40,7 @@ node_modules
*.iml
out
gen

# Test data
test/*.ico
test/*.png
4 changes: 1 addition & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@ This a Javascript implementation of http://stackoverflow.com/a/22007642/5076225.

## Installation

Only supported on Node.js >=v4.2 because of promise support.

If support is desired for earlier versions, a global promise polyfill is required.
Requires Node.js >= 10.

```bash
$ npm install --save page-icon
Expand Down
36 changes: 13 additions & 23 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,30 +1,25 @@
{
"name": "page-icon",
"version": "0.3.4",
"version": "0.4.0",
"engines": {
"node": ">= 10.0.0",
"npm": ">= 6.0.0"
},
"description": "Find the best icon for a web page",
"main": "lib/index.js",
"main": "src/index.js",
"scripts": {
"build": "babel src -d lib --source-maps",
"watch": "babel src -d lib --source-maps --watch",
"test": "npm run build && mkdir -p out && mocha --compilers js:babel-register",
"coverage": "istanbul cover _mocha -- --compilers js:babel-register",
"clean": "rm -rf out"
"test": "mocha"
},
"author": "Goh Jia Hao",
"license": "MIT",
"dependencies": {
"axios": "^0.21.0",
"cheerio": "^0.20.0",
"file-type": "^3.8.0",
"source-map-support": "^0.4.0"
"axios": "^0.21.1",
"cheerio": "^1.0.0-rc.5",
"file-type": "^16.2.0"
},
"devDependencies": {
"babel-cli": "^6.6.4",
"babel-preset-es2015": "^6.6.0",
"babel-register": "^6.6.0",
"chai": "^3.5.0",
"istanbul": "^0.4.2",
"mocha": "^2.4.5"
"chai": "^4.3.0",
"mocha": "^8.3.0"
},
"repository": {
"type": "git",
Expand All @@ -33,10 +28,5 @@
"bugs": {
"url": "https://github.com/nativefier/page-icon/issues"
},
"homepage": "https://github.com/nativefier/page-icon#readme",
"babel": {
"presets": [
"es2015"
]
}
"homepage": "https://github.com/nativefier/page-icon#readme"
}
50 changes: 50 additions & 0 deletions src/downloadIcon.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
const url = require('url');

const axios = require('axios').default;
const fileType = require('file-type');

/**
* @param {string} siteUrl
*/
function getSiteDomain(siteUrl) {
return url.parse(siteUrl).hostname;
}

/**
* @param {string} iconUrl
*/
async function downloadIcon(iconUrl) {
let iconResponse;
try {
iconResponse = await axios.get(iconUrl, {
responseType: 'arraybuffer',
//'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36'
});
} catch (error) {
if (error.response && error.response.status === 404) {
return null;
}
throw error;
}

const iconData = await iconResponse.data;
if (!iconData) {
return null;
}

const fileDetails = await fileType.fromBuffer(iconData);
if (!fileDetails) {
return null;
}

return {
source: iconUrl,
name: getSiteDomain(iconUrl),
data: iconData,
size: iconData.length,
ext: `.${fileDetails.ext}`, // add `.` to ext
mime: fileDetails.mime,
};
}

module.exports = downloadIcon;
12 changes: 12 additions & 0 deletions src/downloadIcons.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const downloadIcon = require('./downloadIcon');

function downloadIcons(iconUrls) {
const promises = iconUrls.map(downloadIcon);

return Promise.all(promises)
.then((iconPaths) => {
return iconPaths.filter(element => !!element);
});
}

module.exports = downloadIcons;
24 changes: 24 additions & 0 deletions src/findBestIcon.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
function sortIconsBySize(icons) {
return icons.sort((a, b) => {
if (a.size < b.size) {
return 1;
} else {
return -1;
}
});
}

function findBestIcon(icons, ext) {
const sorted = sortIconsBySize(icons);
if (ext) {
for (let icon of sorted) {
if (icon.ext === ext) {
return icon;
}
}
}

return sorted[0];
}

module.exports = findBestIcon;
57 changes: 57 additions & 0 deletions src/getIconLinks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
const url = require('url');

const cheerio = require('cheerio');

function hrefIsIcon(href) {
return /((icon.*\.(png|jpg))|(\w+\.ico))/.test(href);
}

function getDomainUrl(someUrl) {
const parsedUrl = url.parse(someUrl);
parsedUrl.pathname = null;
return parsedUrl.format();
}

function linkTagLinks($) {
const links = [];
$('link').each(function(index, element) {
const href = $(element).attr('href');
if (!hrefIsIcon(href)) {
return;
}
links.push(href);
});
return links;
}

function metaTagLinks($) {
const links = [];
$('meta').each((index, element) => {
const property = $(element).attr('property');
if (property !== 'og:image') {
return;
}

const graphImageUrl = $(element).attr('content');
links.push(graphImageUrl);
});

return links
}

function getIconLinks(rootUrl, dom) {
var $ = cheerio.load(dom);
let iconLinks = [];

iconLinks = iconLinks.concat(linkTagLinks($));
iconLinks = iconLinks.concat(metaTagLinks($));

iconLinks = iconLinks.map(iconLink => {
return url.resolve(rootUrl, iconLink);
});

iconLinks.push(url.resolve(getDomainUrl(rootUrl), 'apple-touch-icon.png'));
return iconLinks;
}

module.exports = getIconLinks;
15 changes: 15 additions & 0 deletions src/getPage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const axios = require('axios').default;

function getPage(pageUrl) {
return new Promise(function(resolve, reject) {
axios.get(pageUrl)
.then(function (response) {
resolve(response.data);
})
.catch(function (response) {
reject(response);
});
});
}

module.exports = getPage;
55 changes: 27 additions & 28 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,41 +1,40 @@
import 'source-map-support/register';

const url = require('url');
const getPage = require('./modules/getPage');
const getIconLinks = require('./modules/getIconLinks');
const downloadIcons = require('./modules/download/downloadIcons');
const findBestIcon = require('./modules/findBestIcon');

const downloadIcons = require('./downloadIcons');
const findBestIcon = require('./findBestIcon');
const getIconLinks = require('./getIconLinks');
const getPage = require('./getPage');

function isHttps(pageUrl) {
return url.parse(pageUrl).protocol === 'https:';
return url.parse(pageUrl).protocol === 'https:';
}

function makeHttps(pageUrl) {
const parsed = url.parse(pageUrl);
parsed.protocol = 'https:';
return url.format(parsed);
const parsed = url.parse(pageUrl);
parsed.protocol = 'https:';
return url.format(parsed);
}

function main(pageUrl, options={}) {

const bestWithPref = function(icons) {
return findBestIcon(icons, options.ext);
};

return getPage(pageUrl)
.then(function (dom) {
return getIconLinks(pageUrl, dom);
})
.then(downloadIcons)
.then(bestWithPref)
.then(result => {
if (result || isHttps(pageUrl)) {
return result;
}

const httpsUrl = makeHttps(pageUrl);
return main(httpsUrl, options);
});
const bestWithPref = function(icons) {
return findBestIcon(icons, options.ext);
};

return getPage(pageUrl)
.then(function (dom) {
return getIconLinks(pageUrl, dom);
})
.then(downloadIcons)
.then(bestWithPref)
.then(result => {
if (result || isHttps(pageUrl)) {
return result;
}

const httpsUrl = makeHttps(pageUrl);
return main(httpsUrl, options);
});
}

module.exports = main;
53 changes: 0 additions & 53 deletions src/modules/download/downloadIcon.js

This file was deleted.

Loading

0 comments on commit 4719a7e

Please sign in to comment.