diff --git a/common/store.js b/common/store.js
index c3780096..cdb8c961 100644
--- a/common/store.js
+++ b/common/store.js
@@ -5,8 +5,8 @@ import data from '../build/data.json';
const topics = {};
const all = [...data.incompatible, ...data.expo];
-all.forEach(repo => {
- repo.topics.forEach(topic => {
+all.forEach(project => {
+ project.github.topics.forEach(topic => {
if (!topics[topic]) {
topics[topic] = 1;
return;
diff --git a/components/List.js b/components/List.js
index 313f85af..6238aa74 100644
--- a/components/List.js
+++ b/components/List.js
@@ -186,22 +186,22 @@ export default class List extends React.PureComponent {
} else {
elements = this.props.data.map(item => {
return renderItem({
- name: item.name,
+ name: item.github.name,
column1: {
top: (
-
- {item.name}
+
+ {item.github.name}
),
- bottom: item.urls.homepage
- ?
+ bottom: item.github.urls.homepage
+ ?
homepage
: undefined,
},
column2: {
- top: item.description,
- bottom: item.topics.map(each =>
+ top: item.github.description,
+ bottom: item.github.topics.map(each =>
@@ -210,8 +210,8 @@ export default class List extends React.PureComponent {
),
},
column3: {
- top: getTimeSinceToday(item.stats.pushedAt),
- bottom: `${item.score}/100 — ${item.stats.stars} stars`,
+ top: getTimeSinceToday(item.github.stats.pushedAt),
+ bottom: `${item.score}/100 — ${item.github.stats.stars} stars`,
},
});
});
diff --git a/debug-github-repos.json b/debug-github-repos.json
index 62272c90..2d22ab59 100644
--- a/debug-github-repos.json
+++ b/debug-github-repos.json
@@ -1,10 +1,9 @@
-{
- "expo": [
- {"github": "https://github.com/expo/react-native-action-sheet", "pkg": "@expo/react-native-action-sheet"},
- "https://github.com/react-community/react-navigation",
- "https://github.com/gre/gl-react"
- ],
- "incompatible": [
- "https://github.com/PeelTechnologies/react-native-tcp"
- ]
-}
+[
+ {
+ "githubUrl": "https://github.com/react-community/react-navigation",
+ "expo": true
+ },
+ { "githubUrl": "https://github.com/gre/gl-react", "expo": true },
+ { "githubUrl": "https://github.com/n4kz/react-native-pages", "expo": true },
+ { "githubUrl": "https://github.com/airbnb/lottie-react-native", "expo": true }
+]
\ No newline at end of file
diff --git a/github-repos.json b/github-repos.json
index 02e1502b..ebe73b9c 100644
--- a/github-repos.json
+++ b/github-repos.json
@@ -1,42 +1,90 @@
-{
- "expo": [
- "https://github.com/react-community/react-navigation",
- "https://github.com/gre/gl-react",
- "https://github.com/n4kz/react-native-pages",
- "https://github.com/airbnb/lottie-react-native",
- "https://github.com/airbnb/react-native-maps",
- "https://github.com/oblador/react-native-animatable",
- "https://github.com/wix/react-native-calendars",
- "https://github.com/oblador/react-native-vector-icons",
- "https://github.com/idibidiart/react-native-responsive-grid",
- "https://github.com/24ark/react-native-step-indicator",
- "https://github.com/jacklam718/react-native-popup-dialog",
- "https://github.com/react-native-community/react-native-drawer-layout",
- "https://github.com/n4kz/react-native-material-textfield",
- "https://github.com/maxs15/react-native-modalbox",
- "https://github.com/react-native-community/react-native-modal",
- "https://github.com/react-native-training/react-native-elements",
- "https://github.com/FaridSafi/react-native-gifted-chat",
- "https://github.com/react-native-community/react-native-tab-view",
- "https://github.com/bgryszko/react-native-circular-slider",
- "https://github.com/archriss/react-native-snap-carousel",
- "https://github.com/mmazzarolo/react-native-modal-datetime-picker",
- "https://github.com/magicismight/react-native-root-siblings",
- {"github": "https://github.com/expo/react-native-action-sheet", "pkg": "@expo/react-native-action-sheet"}
- ],
- "incompatible": [
- "https://github.com/PeelTechnologies/react-native-tcp",
- "https://github.com/naoufal/react-native-speech",
- "https://github.com/EstebanFuentealba/react-native-share",
- "https://github.com/aakashns/react-native-dialogs",
- "https://github.com/oblador/react-native-keychain",
- "https://github.com/joeferraro/react-native-cookies",
- "https://github.com/doefler/react-native-social-share",
- "https://github.com/innoveit/react-native-ble-manager",
- "https://github.com/chirag04/react-native-mail",
- "https://github.com/cnjon/react-native-pdf-view",
- "https://github.com/kayla-tech/react-native-card-io",
- "https://github.com/Kerumen/react-native-awesome-card-io",
- "https://github.com/tolu360/react-native-google-places"
- ]
-}
+[
+ {
+ "githubUrl": "https://github.com/react-community/react-navigation",
+ "expo": true
+ },
+ { "githubUrl": "https://github.com/gre/gl-react", "expo": true },
+ { "githubUrl": "https://github.com/n4kz/react-native-pages", "expo": true },
+ { "githubUrl": "https://github.com/airbnb/lottie-react-native", "expo": true },
+ { "githubUrl": "https://github.com/airbnb/react-native-maps", "expo": true },
+ {
+ "githubUrl": "https://github.com/oblador/react-native-animatable",
+ "expo": true
+ },
+ { "githubUrl": "https://github.com/wix/react-native-calendars", "expo": true },
+ {
+ "githubUrl": "https://github.com/oblador/react-native-vector-icons",
+ "expo": true
+ },
+ {
+ "githubUrl": "https://github.com/idibidiart/react-native-responsive-grid",
+ "expo": true
+ },
+ {
+ "githubUrl": "https://github.com/24ark/react-native-step-indicator",
+ "expo": true
+ },
+ {
+ "githubUrl": "https://github.com/jacklam718/react-native-popup-dialog",
+ "expo": true
+ },
+ {
+ "githubUrl": "https://github.com/react-native-community/react-native-drawer-layout",
+ "expo": true
+ },
+ {
+ "githubUrl": "https://github.com/n4kz/react-native-material-textfield",
+ "expo": true
+ },
+ { "githubUrl": "https://github.com/maxs15/react-native-modalbox", "expo": true },
+ {
+ "githubUrl": "https://github.com/react-native-community/react-native-modal",
+ "expo": true
+ },
+ {
+ "githubUrl": "https://github.com/react-native-training/react-native-elements",
+ "expo": true
+ },
+ {
+ "githubUrl": "https://github.com/FaridSafi/react-native-gifted-chat",
+ "expo": true
+ },
+ {
+ "githubUrl": "https://github.com/react-native-community/react-native-tab-view",
+ "expo": true
+ },
+ {
+ "githubUrl": "https://github.com/bgryszko/react-native-circular-slider",
+ "expo": true
+ },
+ {
+ "githubUrl": "https://github.com/archriss/react-native-snap-carousel",
+ "expo": true
+ },
+ {
+ "githubUrl": "https://github.com/mmazzarolo/react-native-modal-datetime-picker",
+ "expo": true
+ },
+ {
+ "githubUrl": "https://github.com/magicismight/react-native-root-siblings",
+ "expo": true
+ },
+ {
+ "githubUrl": "https://github.com/expo/react-native-action-sheet",
+ "npmPkg": "@expo/react-native-action-sheet",
+ "expo": true
+ },
+ { "githubUrl": "https://github.com/PeelTechnologies/react-native-tcp" },
+ { "githubUrl": "https://github.com/naoufal/react-native-speech" },
+ { "githubUrl": "https://github.com/EstebanFuentealba/react-native-share" },
+ { "githubUrl": "https://github.com/aakashns/react-native-dialogs" },
+ { "githubUrl": "https://github.com/oblador/react-native-keychain" },
+ { "githubUrl": "https://github.com/joeferraro/react-native-cookies" },
+ { "githubUrl": "https://github.com/doefler/react-native-social-share" },
+ { "githubUrl": "https://github.com/innoveit/react-native-ble-manager" },
+ { "githubUrl": "https://github.com/chirag04/react-native-mail" },
+ { "githubUrl": "https://github.com/cnjon/react-native-pdf-view" },
+ { "githubUrl": "https://github.com/kayla-tech/react-native-card-io" },
+ { "githubUrl": "https://github.com/Kerumen/react-native-awesome-card-io" },
+ { "githubUrl": "https://github.com/tolu360/react-native-google-places" }
+]
diff --git a/package.json b/package.json
index 0fa0c4ae..554a851f 100644
--- a/package.json
+++ b/package.json
@@ -25,6 +25,7 @@
"express": "^4.14.0",
"isomorphic-fetch": "^2.2.1",
"jsonfile": "^3.0.0",
+ "lodash": "^4.17.4",
"next": "^2.1.1",
"next-redux-wrapper": "^1.0.0",
"next-routes": "^1.0.24",
diff --git a/scripts/build-and-score-data.js b/scripts/build-and-score-data.js
index 4f89f003..c9591d73 100644
--- a/scripts/build-and-score-data.js
+++ b/scripts/build-and-score-data.js
@@ -2,6 +2,7 @@ import 'isomorphic-fetch';
import path from 'path';
import fs from 'fs';
import jsonfile from 'jsonfile';
+import _ from 'lodash';
import fetchGithubData from './fetch-github-data';
import calculateScore from './calculate-score';
import fetchReadmeImages from './fetch-readme-images';
@@ -16,7 +17,7 @@ const USE_DEBUG_REPOS = false;
// Loads the Github API results from disk rather than hitting the API each time.
// The first run will hit the API if raw-github-results.json doesn't exist yet.
-const LOAD_GITHUB_RESULTS_FROM_DISK = false;
+const LOAD_GITHUB_RESULTS_FROM_DISK = true;
const GITHUB_RESULTS_PATH = path.join('scripts', 'raw-github-results.json');
const JSON_OPTIONS = {
@@ -25,37 +26,26 @@ const JSON_OPTIONS = {
const buildAndScoreData = async () => {
console.log('** Loading data from Github');
- let { expo, incompatible } = await loadRepositoryDataAsync();
+ let data = await loadRepositoryDataAsync();
console.log('\n** Scraping images from README');
- expo = await Promise.all(
- expo.map(repo => fetchReadmeImages(repo, repo.urls.repo))
- );
-
- incompatible = await Promise.all(
- incompatible.map(repo => fetchReadmeImages(repo, repo.urls.repo))
- );
+ data = await Promise.all(data.map(d => fetchReadmeImages(d, d.githubUrl)));
console.log('\n** Loading download stats from npm');
- expo = await Promise.all(expo.map(repo => fetchNpmData(repo, repo.pkg)));
-
- incompatible = await Promise.all(
- incompatible.map(repo => fetchNpmData(repo, repo.pkg))
+ data = await Promise.all(
+ data.map(d => fetchNpmData(d, d.npmPkg, d.githubUrl))
);
// Calculate score
console.log('\n** Calculating scores');
- expo = expo.map(calculateScore);
- incompatible = incompatible.map(calculateScore);
+ data = data.map(calculateScore);
- const jsonData = {
- expo,
- incompatible,
- };
+ const expo = _.filter(data, d => d.expo);
+ const incompatible = _.filter(data, d => !d.expo);
return jsonfile.writeFile(
path.resolve('build', 'data.json'),
- jsonData,
+ { expo, incompatible },
JSON_OPTIONS,
err => {
if (err) {
@@ -81,26 +71,17 @@ async function loadRepositoryDataAsync() {
result = jsonfile.readFileSync(GITHUB_RESULTS_PATH);
console.log('Loaded Github results from disk, skipped API calls');
} else {
- let expo = await Promise.all(data.expo.map(fetchGithubData));
- let incompatible = await Promise.all(
- data.incompatible.map(fetchGithubData)
- );
- result = { expo, incompatible };
+ result = await Promise.all(data.map(fetchGithubData));
if (LOAD_GITHUB_RESULTS_FROM_DISK) {
await new Promise((resolve, reject) => {
- jsonfile.writeFile(
- GITHUB_RESULTS_PATH,
- { expo, incompatible },
- JSON_OPTIONS,
- err => {
- if (err) {
- reject(err);
- } else {
- resolve();
- }
+ jsonfile.writeFile(GITHUB_RESULTS_PATH, result, JSON_OPTIONS, err => {
+ if (err) {
+ reject(err);
+ } else {
+ resolve();
}
- );
+ });
});
console.log('Saved Github results from disk');
}
diff --git a/scripts/calculate-score.js b/scripts/calculate-score.js
index f7a71f77..10f1cb8b 100644
--- a/scripts/calculate-score.js
+++ b/scripts/calculate-score.js
@@ -1,53 +1,55 @@
-const calculateScore = repo => {
- repo.score = 0;
+const calculateScore = data => {
+ let { github } = data;
+ let score = 0;
- const daysAgo = getDaysAgo(repo.stats.updatedAt);
+ const daysAgo = getDaysAgo(github.stats.updatedAt);
if (daysAgo <= 30) {
- repo.score += 15;
+ score += 15;
} else if (daysAgo <= 60) {
- repo.score += 10;
+ score += 10;
} else if (daysAgo <= 90) {
- repo.score += 5;
+ score += 5;
}
- if (repo.stats.hasIssues) {
- repo.score += 10;
+ if (github.stats.hasIssues) {
+ score += 10;
}
- if (repo.stats.hasWiki) {
- repo.score += 10;
+ if (github.stats.hasWiki) {
+ score += 10;
}
- if (repo.stats.hasPages) {
- repo.score += 5;
+ if (github.stats.hasPages) {
+ score += 5;
}
- if (repo.stats.hasDownloads) {
- repo.score += 10;
+ if (github.stats.hasDownloads) {
+ score += 10;
}
- if (repo.stats.hasTopics) {
- repo.score += 10;
+ if (github.stats.hasTopics) {
+ score += 10;
}
- if (repo.stats.watchers > 10) {
- repo.score += 5;
+ if (github.stats.watchers > 10) {
+ score += 5;
}
- if (repo.stats.forks > 5) {
- repo.score += 10;
+ if (github.stats.forks > 5) {
+ score += 10;
}
- if (repo.stats.stars >= 2500) {
- repo.score += 20;
- } else if (repo.stats.stars >= 500) {
- repo.score += 15;
- } else if (repo.stats.stars >= 100) {
- repo.score += 10;
+ if (github.stats.stars >= 2500) {
+ score += 20;
+ } else if (github.stats.stars >= 500) {
+ score += 15;
+ } else if (github.stats.stars >= 100) {
+ score += 10;
}
- return repo;
+ data.score = score;
+ return data;
};
const getDaysAgo = date => {
diff --git a/scripts/fetch-github-data.js b/scripts/fetch-github-data.js
index bdb17b1c..08b528ba 100644
--- a/scripts/fetch-github-data.js
+++ b/scripts/fetch-github-data.js
@@ -3,16 +3,8 @@ import { GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET } from '../secrets.json';
const API = 'https://api.github.com';
-const fetchGithubData = async urlOrObj => {
- let url, pkg;
- if (typeof urlOrObj === 'string') {
- url = urlOrObj;
- let parts = url.split('/');
- pkg = parts[parts.length - 1];
- } else {
- url = urlOrObj.github;
- pkg = urlOrObj.pkg;
- }
+const fetchGithubData = async data => {
+ let url = data.githubUrl;
const requestUrl = createRequestUrl(url);
const response = await fetch(requestUrl, {
@@ -22,10 +14,12 @@ const fetchGithubData = async urlOrObj => {
},
});
let json = await response.json();
-
let result = createRepoDataWithResponse(json);
- result.pkg = pkg;
- return result;
+
+ return {
+ ...data,
+ github: result,
+ };
};
const createRepoDataWithResponse = json => {
diff --git a/scripts/fetch-npm-data.js b/scripts/fetch-npm-data.js
index 557e2abf..888e7982 100644
--- a/scripts/fetch-npm-data.js
+++ b/scripts/fetch-npm-data.js
@@ -1,13 +1,19 @@
import 'isomorphic-fetch';
-const urlForPackage = pkgName => {
- return `https://api.npmjs.org/downloads/point/last-month/${pkgName}`;
+const urlForPackage = npmPkg => {
+ return `https://api.npmjs.org/downloads/point/last-month/${npmPkg}`;
};
-const fetchNpmData = async (data, pkgName) => {
+const fetchNpmData = async (data, npmPkg, githubUrl) => {
+ if (!npmPkg) {
+ let parts = githubUrl.split('/');
+ npmPkg = parts[parts.length - 1];
+ data.npmPkg = npmPkg;
+ }
+
try {
- console.log(urlForPackage(pkgName));
- let response = await fetch(urlForPackage(pkgName));
+ console.log(urlForPackage(npmPkg));
+ let response = await fetch(urlForPackage(npmPkg));
let downloadData = await response.json();
return {
diff --git a/yarn.lock b/yarn.lock
index 46a58c86..cf37740c 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1711,14 +1711,14 @@ domain-browser@^1.1.1:
version "1.1.7"
resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.1.7.tgz#867aa4b093faa05f1de08c06f4d7b21fdf8698bc"
-domelementtype@1, domelementtype@~1.1.1:
- version "1.1.3"
- resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.1.3.tgz#bd28773e2642881aec51544924299c5cd822185b"
-
-domelementtype@^1.3.0:
+domelementtype@1, domelementtype@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.0.tgz#b17aed82e8ab59e52dd9c19b1756e0fc187204c2"
+domelementtype@~1.1.1:
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.1.3.tgz#bd28773e2642881aec51544924299c5cd822185b"
+
domhandler@^2.3.0:
version "2.4.1"
resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.1.tgz#892e47000a99be55bbf3774ffea0561d8879c259"