Skip to content

Commit f99f523

Browse files
committed
db module // incomplete, abandonned #13 #22 ghuser-io/ghuser.io#190
1 parent 0f5a0a6 commit f99f523

File tree

9 files changed

+109
-105
lines changed

9 files changed

+109
-105
lines changed

calculateContribsAndMeta.js

Lines changed: 8 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
const sleep = require('await-sleep');
1010

1111
const data = require('./impl/data');
12+
const db = require('./impl/db');
1213
const DbFile = require('./impl/dbFile');
1314
const scriptUtils = require('./impl/scriptUtils');
1415

@@ -18,31 +19,16 @@
1819
return;
1920

2021
async function calculateContribsAndMeta() {
21-
let spinner;
22-
23-
let spinnerText = 'Reading users from DB...';
24-
spinner = ora(spinnerText).start();
25-
const users = {};
2622
let numUsers = 0;
27-
for (const file of fs.readdirSync(data.users)) {
28-
await sleep(0); // make loop interruptible
23+
for await (const user of db.asyncNonRemovedUsers()) {
24+
++numUsers;
2925

30-
if (file.endsWith('.json')) {
31-
const user = new DbFile(path.join(data.users, file));
32-
if (!user.ghuser_deleted_because && !user.removed_from_github) {
33-
users[file] = user;
34-
++numUsers;
35-
spinner.text = `${spinnerText} [${numUsers}]`;
36-
37-
// Make sure the corresponding contrib file exists (not the case if it's a new user):
38-
(new DbFile(path.join(data.contribs, file))).write();
39-
}
40-
}
26+
// Make sure the corresponding contrib file exists (not the case if it's a new user):
27+
db.createUserContribList(user.login); //LA_TODO to be tested
4128
}
42-
spinner.succeed(`Found ${numUsers} users in DB`);
4329

44-
spinnerText = 'Reading contribution lists from DB...';
45-
spinner = ora(spinnerText).start();
30+
const spinnerText = 'Reading contribution lists from DB...';
31+
let spinner = ora(spinnerText).start();
4632
const contribs = {};
4733
for (const file of fs.readdirSync(data.contribs)) {
4834
await sleep(0); // make loop interruptible
@@ -79,7 +65,7 @@
7965

8066
const toBeDeleted = [];
8167
for (const contribList in contribs) {
82-
if (!users[contribList]) {
68+
if (!users[contribList]) { //LA_TODO I've removed this var
8369
toBeDeleted.push(contribList);
8470
}
8571
}

fetchOrgs.js

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
const path = require('path');
99

1010
const data = require('./impl/data');
11+
const db = require('./impl/db');
1112
const DbFile = require('./impl/dbFile');
1213
const github = require('./impl/github');
1314
const scriptUtils = require('./impl/scriptUtils');
@@ -18,36 +19,21 @@
1819
return;
1920

2021
async function fetchOrgs() {
21-
let spinner;
22-
2322
// In this file we store repo owners that we know aren't organizations. This avoids querying
2423
// them next time.
2524
const nonOrgs = new DbFile(data.nonOrgs);
2625
nonOrgs.non_orgs = nonOrgs.non_orgs || [];
2726

28-
const users = [];
29-
for (const file of fs.readdirSync(data.users)) {
30-
if (file.endsWith('.json')) {
31-
const user = new DbFile(path.join(data.users, file));
32-
if (!user.ghuser_deleted_because && !user.removed_from_github) {
33-
users.push(user);
34-
}
35-
}
36-
}
37-
3827
let userOrgs = new Set([]);
39-
for (const user of users) {
40-
userOrgs = new Set([...userOrgs, ...user.organizations]);
41-
}
42-
await fetchOrgs(userOrgs);
43-
4428
let contribOwners = new Set([]);
45-
for (const user of users) {
29+
for await (const user of db.asyncNonRemovedUsers()) { //LA_TODO to be tested
30+
userOrgs = new Set([...userOrgs, ...user.organizations]);
4631
contribOwners = new Set([
4732
...contribOwners,
4833
...(user.contribs && user.contribs.repos.map(repo => repo.split('/')[0]) || [])
4934
]);
5035
}
36+
await fetchOrgs(userOrgs);
5137
await fetchOrgs(contribOwners);
5238

5339
stripUnreferencedOrgs();
@@ -57,7 +43,7 @@
5743
async function fetchOrgs(owners) {
5844
owners:
5945
for (const owner of owners) {
60-
spinner = ora(`Fetching owner ${owner}...`).start();
46+
const spinner = ora(`Fetching owner ${owner}...`).start();
6147
const org = new DbFile(path.join(data.orgs, `${owner}.json`));
6248
if (org.avatar_url) {
6349
spinner.succeed(`Organization ${owner} is already known`);
@@ -67,7 +53,7 @@
6753
spinner.succeed(`${owner} is a user`);
6854
continue;
6955
}
70-
for (const user of users) {
56+
for (const user of users) { //LA_TODO I removed this var
7157
if (user.login === owner) {
7258
spinner.succeed(`${owner} is a user`);
7359
nonOrgs.non_orgs.push(owner);

fetchRepos.js

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
const sleep = require('await-sleep');
1111

1212
const data = require('./impl/data');
13+
const db = require('./impl/db');
1314
const DbFile = require('./impl/dbFile');
1415
const fetchJson = require('./impl/fetchJson');
1516

@@ -46,23 +47,9 @@ optional arguments:
4647
return;
4748

4849
async function fetchRepos(firsttime) {
49-
console.log('Reading users from DB...')
50-
const users = [];
51-
for (const file of fs.readdirSync(data.users)) {
52-
await sleep(0); // make loop interruptible
53-
54-
if (file.endsWith('.json')) {
55-
const user = new DbFile(path.join(data.users, file));
56-
if (!user.ghuser_deleted_because && !user.removed_from_github) {
57-
users.push(user);
58-
}
59-
}
60-
}
61-
console.log(`Found ${users.length} users in DB`);
62-
6350
console.log('Searching repos referenced by users...');
6451
const referencedRepos = new Set([]);
65-
for (const user of users) {
52+
for await (const user of db.asyncNonRemovedUsers()) { //LA_TODO to be tested
6653
for (const repo in (user.contribs && user.contribs.repos || [])) {
6754
await sleep(0); // make loop interruptible
6855

fetchUserDetailsAndContribs.js

Lines changed: 11 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
let path = require('path');
1111

1212
const data = require('./impl/data');
13+
const db = require('./impl/db');
1314
const DbFile = require('./impl/dbFile');
1415
const fetchJson = require('./impl/fetchJson');
1516
const github = require('./impl/github');
@@ -67,34 +68,21 @@ optional arguments:
6768
}
6869

6970
if (cli.input.length === 1) {
70-
await fetchUserDetailsAndContribs(`${cli.input[0].toLowerCase()}.json`);
71+
const userFilePath = path.join(data.users, `${cli.input[0].toLowerCase()}.json`);
72+
const user = new DbFile(userFilePath);
73+
await fetchUserDetailsAndContribs(user); //LA_TODO to be tested
7174
} else {
72-
for (const file of fs.readdirSync(data.users)) {
73-
if (file.endsWith('.json')) {
74-
await fetchUserDetailsAndContribs(file);
75-
}
75+
for await (const user of db.asyncNonRemovedUsers()) {
76+
await fetchUserDetailsAndContribs(user); //LA_TODO to be tested
7677
}
7778
}
7879

7980
return;
8081

81-
async function fetchUserDetailsAndContribs(userFileName) {
82-
let spinner;
83-
84-
const userFilePath = path.join(data.users, userFileName);
85-
const userFile = new DbFile(userFilePath);
82+
async function fetchUserDetailsAndContribs(userFile) {
8683
if (!userFile.login) {
8784
throw `${userFilePath} is malformed. Did you run ./addUser.js ?`;
8885
}
89-
if (userFile.ghuser_deleted_because) {
90-
console.log(`${userFile.login} has been deleted, skipping...`);
91-
return;
92-
}
93-
if (userFile.removed_from_github) {
94-
// For now ok, but maybe some day we'll have to deal with resurrected users.
95-
console.log(`${userFile.login} was removed from GitHub in the past, skipping...`);
96-
return;
97-
}
9886

9987
{
10088
const now = new Date;
@@ -117,7 +105,7 @@ optional arguments:
117105

118106
async function fetchDetails(userFile) {
119107
const ghUserUrl = `https://api.github.com/users/${userFile.login}`;
120-
spinner = ora(`Fetching ${ghUserUrl}...`).start();
108+
const spinner = ora(`Fetching ${ghUserUrl}...`).start();
121109
const ghDataJson = await github.fetchGHJson(
122110
ghUserUrl, spinner, [304, 404],
123111
userFile.contribs && userFile.contribs.fetched_at && new Date(userFile.contribs.fetched_at)
@@ -151,7 +139,7 @@ optional arguments:
151139

152140
async function fetchOrgs(userFile) {
153141
const orgsUrl = userFile.organizations_url;
154-
spinner = ora(`Fetching ${orgsUrl}...`).start();
142+
const spinner = ora(`Fetching ${orgsUrl}...`).start();
155143
const orgsDataJson = await github.fetchGHJson(orgsUrl, spinner);
156144
spinner.succeed(`Fetched ${orgsUrl}`);
157145

@@ -194,7 +182,7 @@ optional arguments:
194182
// fetchUserContribs() won't find forks as they are not considered to be contributions. But
195183
// the user might well have popular forks.
196184

197-
spinner = ora(`Fetching ${userFile.login}'s popular forks...`).start();
185+
const spinner = ora(`Fetching ${userFile.login}'s popular forks...`).start();
198186

199187
const perPage = 100;
200188
for (let page = 1; page <= 5; ++page) {
@@ -219,7 +207,7 @@ optional arguments:
219207

220208
async function fetchSettings(userFile) {
221209
const url = `https://raw.githubusercontent.com/${userFile.login}/ghuser.io.settings/master/ghuser.io.json`;
222-
spinner = ora(`Fetching ${userFile.login}'s settings...`).start();
210+
const spinner = ora(`Fetching ${userFile.login}'s settings...`).start();
223211

224212
const dataJson = await fetchJson(url, spinner, [404]);
225213
if (dataJson == 404) {

findUsersToRemove.js

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
const path = require('path');
99

1010
const data = require('./impl/data');
11+
const db = require('./impl/db');
1112
const DbFile = require('./impl/dbFile');
1213
const github = require('./impl/github');
1314
const scriptUtils = require('./impl/scriptUtils');
@@ -23,20 +24,16 @@
2324
// * aren't marked not to be deleted, and
2425
// * haven't starred the project.
2526

26-
let spinner;
2727
const now = new Date;
2828
const minAgeMonths = 1;
2929

3030
const users = [];
31-
for (const file of fs.readdirSync(data.users)) {
32-
if (file.endsWith('.json')) {
33-
const user = new DbFile(path.join(data.users, file));
34-
if (!user.ghuser_deleted_because && !user.ghuser_keep_because && !user.removed_from_github
35-
&& now - Date.parse(user.ghuser_created_at) > minAgeMonths * 30 * 24 * 60 * 60 * 1000) {
36-
users.push(user);
37-
}
31+
for await (const user of db.asyncNonRemovedUsers()) {
32+
if (!user.ghuser_keep_because
33+
&& now - Date.parse(user.ghuser_created_at) > minAgeMonths * 30 * 24 * 60 * 60 * 1000) {
34+
users.push(user);
3835
}
39-
}
36+
} //LA_TODO to be tested
4037

4138
const stargazers = await fetchStargazers('ghuser-io/ghuser.io');
4239
const toRemove = users.map(user => user.login).filter(user => stargazers.indexOf(user) === -1);
@@ -62,7 +59,7 @@ to make sure we're not wasting resources, I'd like to know if you'd like to keep
6259

6360
async function fetchStargazers(repo) {
6461
const ghUrl = `https://api.github.com/repos/${repo}/stargazers`;
65-
spinner = ora(`Fetching ${ghUrl}...`).start();
62+
const spinner = ora(`Fetching ${ghUrl}...`).start();
6663
const ghDataJson = await github.fetchGHJson(ghUrl, spinner);
6764
spinner.succeed(`Fetched ${ghUrl}`);
6865
return ghDataJson.map(stargazer => stargazer.login);

impl/data.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#!/usr/bin/env node
22
'use strict';
33

4+
//TODO all this should move inside db.js and this file should be removed.
5+
46
(() => {
57
const os = require('os');
68
const fs = require('fs');

impl/db.js

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#!/usr/bin/env node
2+
'use strict';
3+
4+
module.exports = {
5+
6+
// Async generator yielding an instance of DbFile for each user present in the database and not
7+
// marked as removed ghuser or GitHub.
8+
asyncNonRemovedUsers,
9+
10+
// Creates the list of all contribs of a user if it doesn't exist already. In other words, writes
11+
// an instance of DbFile on disk.
12+
// @param login Case insensitive.
13+
createUserContribList,
14+
};
15+
16+
17+
const fs = require('fs');
18+
const path = require('path');
19+
20+
const ora = require('ora');
21+
const sleep = require('await-sleep');
22+
23+
const data = require('./data');
24+
const DbFile = require('./dbFile'); //LA_TODO should be the only include of this file, i.e. move content here?
25+
26+
27+
async function* asyncNonRemovedUsers() {
28+
const spinnerText = 'Reading users from DB...';
29+
const spinner = ora(spinnerText).start();
30+
let numUsers = 0;
31+
32+
for (const file of fs.readdirSync(data.users)) {
33+
await sleep(0); // make loop interruptible
34+
35+
if (file.endsWith(DB_FILE_EXT)) {
36+
const pathToFile = path.join(data.users, file);
37+
const user = new DbFile(pathToFile);
38+
if (!user.ghuser_deleted_because && !user.removed_from_github) {
39+
++numUsers;
40+
spinner.text = `${spinnerText} [${numUsers}]`;
41+
42+
yield user;
43+
}
44+
}
45+
}
46+
47+
spinner.succeed(`Found ${numUsers} users in DB`);
48+
}
49+
50+
function createUserContribList(login) {
51+
if (!login) {
52+
throw 'login is mandatory';
53+
}
54+
(new DbFile(path.join(data.contribs, login.toLowerCase() + DB_FILE_EXT))).write();
55+
}
56+
57+
58+
const DB_FILE_EXT = '.json'; //TODO should be the only occurence of this string in the codebase

impl/dbFile.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@
2727
fs.writeFileSync(this._path(), JSON.stringify(this, null, 2) + '\n', 'utf-8');
2828
}
2929

30+
sizeBytes() {
31+
return fs.statSync(this._path()).size;
32+
}
33+
3034
deleteAllPropsBut(exceptions) {
3135
Object.keys(this).forEach(prop => {
3236
if (prop.startsWith('_') || prop in exceptions) {

0 commit comments

Comments
 (0)