diff --git a/.gitignore b/.gitignore
index 4c244fbaa..4cb371265 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,6 +5,7 @@ build/*
drivers/npm/node_modules
drivers/npm/npm-debug.log
+package.json
node_modules/
npm-debug.log
diff --git a/.travis.yml b/.travis.yml
index 7e80fd13a..cb8bcca5a 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -10,7 +10,7 @@ install:
- sudo apt-get update -y
- sudo apt-get install -y curl zip sudo -y --force-yes
- sudo apt-get clean
- - npm install jsonlint jpm imagemin-cli -g
+ - npm install jsonlint jpm imagemin-cli svgo -g
- ln -s docker/node/package.json package.json && npm install
- mkdir phantomjs && curl -L https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-1.9.8-linux-x86_64.tar.bz2 | tar xvjC phantomjs && ln -s $WAPPALYZER_ROOT/phantomjs/phantomjs-*-linux-x86_64/bin/phantomjs bin/phantomjs
script: wappalyzer build
diff --git a/bin/wappalyzer-build b/bin/wappalyzer-build
index 5aedbf510..5c774b1ad 100755
--- a/bin/wappalyzer-build
+++ b/bin/wappalyzer-build
@@ -15,10 +15,14 @@ echo "Prettifying apps.json..."
jsonlint -ist $'\t' $WAPPALYZER_ROOT/src/apps.json
-echo "Compressing icons..."
+echo "Compressing PNG icons..."
imagemin $WAPPALYZER_ROOT/src/icons $WAPPALYZER_ROOT/src/icons -o 3
+echo "Compressing PNG icons..."
+
+svgo -f $WAPPALYZER_ROOT/src/icons $WAPPALYZER_ROOT/src/icons
+
wappalyzer links
# Npm Module
diff --git a/bin/wappalyzer-validate-icons b/bin/wappalyzer-validate-icons
index e840ec5fd..38a8cb2bf 100755
--- a/bin/wappalyzer-validate-icons
+++ b/bin/wappalyzer-validate-icons
@@ -6,23 +6,45 @@ var
fs = require('fs'),
fileType = require(modulesPath + 'file-type'),
readChunk = require(modulesPath + 'read-chunk')
+ isSvg = require(modulesPath + 'is-svg')
json = require(process.env.WAPPALYZER_ROOT + '/src/apps.json');
-for ( app in json.apps ) {
+for (app in json.apps) {
(function(app) {
- var path = process.env.WAPPALYZER_ROOT + '/src/icons/' + app + '.png';
-
+ var basePath = process.env.WAPPALYZER_ROOT + '/src/icons/';
+ var iconPath = json.apps[app].icon;
+ var path = basePath + iconPath;
+
+ var type;
+ if (path.substr(path.length - 4) === '.png') {
+ type = "PNG";
+ }
+ else if (path.substr(path.length - 4) === '.svg') {
+ type = "SVG";
+ }
+ else {
+ var err = new Error('Icon file extension specified for app "' + app + '" is not ".png" or ".svg": src/icons/' + iconPath);
+ throw err;
+ }
+
fs.exists(path, function(exists) {
- var buffer;
-
- if ( exists ) {
- buffer = fileType(readChunk.sync(path, 0, 262));
-
- if ( buffer.mime !== 'image/png' ) {
- throw new Error('Incorrect mimetype "' + buffer.mime + '": src/icons/' + app + '.png');
- }
+ if (exists) {
+ if (type === "PNG") {
+ var buffer = fileType(readChunk.sync(path, 0, 262));
+ if (buffer.mime !== 'image/png') {
+ var err = new Error('Incorrect mimetype "' + buffer.mime + '" when expected PNG for app "' + app + '": src/icons/' + iconPath);
+ throw err;
+ }
+ }
+ else if (type === "SVG") {
+ if (!isSvg(fs.readFileSync(path))) {
+ var err = new Error('Incorrect mimetype when expected SVG for app "' + app + '": src/icons/' + iconPath);
+ throw err;
+ }
+ }
} else {
- throw new Error('Missing file: src/icons/' + app + '.png');
+ var err = new Error('Missing file for app "' + app + '": src/icons/' + iconPath);
+ throw err;
}
});
}(app));
diff --git a/docker/Dockerfile b/docker/Dockerfile
index 627c8a774..857cf65a6 100644
--- a/docker/Dockerfile
+++ b/docker/Dockerfile
@@ -32,7 +32,7 @@ RUN su wappalyzer -c "mkdir $WAPPALYZER_NODE_PATH"
ADD node/package.json $WAPPALYZER_NODE_PATH/package.json
-RUN npm install jsonlint jpm imagemin-cli -g && su wappalyzer -c "cd $WAPPALYZER_NODE_PATH && npm install"
+RUN npm install jsonlint jpm imagemin-cli svgo -g && su wappalyzer -c "cd $WAPPALYZER_NODE_PATH && npm install"
# PhantomJS
diff --git a/docker/node/package.json b/docker/node/package.json
index dec35339d..e3174ad53 100644
--- a/docker/node/package.json
+++ b/docker/node/package.json
@@ -1,6 +1,7 @@
{
"devDependencies": {
- "file-type": "2.2.*",
+ "file-type": "3.1.*",
+ "is-svg": "1.1.*",
"read-chunk": "1.0.*"
}
}
diff --git a/schema.json b/schema.json
index e7256b144..8be26af2a 100644
--- a/schema.json
+++ b/schema.json
@@ -74,6 +74,10 @@
"website": {
"type": "string",
"required": true
+ },
+ "icon": {
+ "type": "string",
+ "required": true
}
}
}
diff --git a/src/apps.json b/src/apps.json
index 729f3a1b8..c3d3ef4c1 100755
--- a/src/apps.json
+++ b/src/apps.json
@@ -1,7867 +1,8676 @@
{
- "apps": {
- "1C-Bitrix": {
- "cats": [
- 1
- ],
- "headers": {
- "Set-Cookie": "BITRIX_",
- "X-Powered-CMS": "Bitrix Site Manager"
- },
- "html": "(?:]+components/bitrix|(?:src|href)=\"/bitrix/(?:js|templates))",
- "implies": "PHP",
- "script": "1c-bitrix",
- "website": "www.1c-bitrix.ru"
- },
- "1und1": {
- "cats": [
- 6
- ],
- "implies": "PHP",
- "url": "/shop/catalog/browse\\?sessid=",
- "website": "1und1.de"
- },
- "2z Project": {
- "cats": [
- 1
- ],
- "meta": {
- "generator": "2z project ([\\d.]+)\\;version:\\1"
- },
- "website": "2zproject-cms.ru"
- },
- "3DM": {
- "cats": [
- 19
- ],
- "html": "
3ware 3DM([\\d\\.]+)?\\;version:\\1",
- "implies": "3ware",
- "website": "www.3ware.com"
- },
- "3dCart": {
- "cats": [
- 1,
- 6
- ],
- "headers": {
- "Set-Cookie": "3dvisit",
- "X-Powered-By": "3DCART"
- },
- "script": "(?:twlh(?:track)?\\.asp|3d_upsell\\.js)",
- "website": "www.3dcart.com"
- },
- "3ware": {
- "cats": [
- 22
- ],
- "headers": {
- "Server": "3ware\\/?([\\d\\.]+)?\\;version:\\1"
- },
- "website": "www.3ware.com"
- },
- "AMPcms": {
- "cats": [
- 1
- ],
- "env": "^amp_js_init$",
- "headers": {
- "Set-Cookie": "^AMP=",
- "X-AMP-Version": "([\\d.]+)\\;version:\\1"
- },
- "implies": "PHP",
- "website": "www.ampcms.org"
- },
- "AOLserver": {
- "cats": [
- 22
- ],
- "headers": {
- "Server": "AOLserver/?([\\d.]+)?\\;version:\\1"
- },
- "website": "aolserver.com"
- },
- "AT Internet Analyzer": {
- "cats": [
- 10
- ],
- "env": "^xtsite$",
- "website": "atinternet.com/en"
- },
- "AT Internet XiTi": {
- "cats": [
- 10
- ],
- "env": "^Xt_",
- "script": "xiti\\.com/hit\\.xiti",
- "website": "atinternet.com/en"
- },
- "ATEN": {
- "cats": [
- 22
- ],
- "headers": {
- "Server": "ATEN HTTP Server(?:\\(?V?([\\d\\.]+)\\)?)?\\;version:\\1"
- },
- "website": "www.aten.com"
- },
- "ATG Web Commerce": {
- "cats": [
- 6
- ],
- "headers": {
- "X-ATG-Version": "(?:ATGPlatform/([\\d.]+))?\\;version:\\1"
- },
- "html": "<[^>]+_DARGS",
- "website": "oracle.com/us/products/applications/web-commerce/atg"
- },
- "AWStats": {
- "cats": [
- 10
- ],
- "implies": "Perl",
- "meta": {
- "generator": "AWStats ([\\d.]+(?: \\(build [\\d.]+\\))?)\\;version:\\1"
- },
- "website": "awstats.sourceforge.net"
- },
- "Accessible Portal": {
- "cats": [
- 1
- ],
- "implies": "PHP",
- "meta": {
- "generator": "Accessible Portal"
- },
- "website": "www.accessibleportal.com"
- },
- "AdInfinity": {
- "cats": [
- 36
- ],
- "script": "adinfinity\\.com\\.au",
- "website": "adinfinity.com.au"
- },
- "AdRiver": {
- "cats": [
- 36
- ],
- "env": "^adriver$",
- "html": "(?: