-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
101 lines (83 loc) · 3.51 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
const fs = require('fs');
const path = require('path');
const util = require('util');
const yaml = require('js-yaml')
const axios = require('axios');
const assert = require('assert');
const mkdirp = require('mkdirp');
const {MongoClient} = require('mongodb');
const {Repository, Signature} = require('nodegit');
const readFile = util.promisify(fs.readFile);
const writeFile = util.promisify(fs.writeFile);
const contestName = process.argv[2] || 'esolang';
const dirName = process.argv[3] || '01';
(async () => {
const usersData = yaml.safeLoad(await readFile('users.yml'));
const usersMap = new Map(Object.entries(usersData));
for (const [twitterName, githubName] of usersMap.entries()) {
if (githubName === null) {
usersMap.set(twitterName, {
name: twitterName,
email: `${twitterName}@twitter.com`,
});
} else {
usersMap.set(twitterName, {
name: githubName,
email: `${githubName}@users.noreply.github.com`,
});
}
}
const {data: githubLanguagesData} = await axios.get('https://raw.githubusercontent.com/github/linguist/master/lib/linguist/languages.yml');
const githubLanguages = yaml.safeLoad(githubLanguagesData);
const languagesData = yaml.safeLoad(await readFile('languages.yml'));
const client = await MongoClient.connect(`mongodb://localhost:27017/`);
const db = client.db('esolang-battle');
const contest = await db.collection('contests').findOne({id: contestName});
const users = await db.collection('users').find({}).toArray();
const languages = await db.collection('languages').find({}).toArray();
const submissions = await db.collection('submissions').find({
status: 'success',
contest: contest._id,
}).sort({createdAt: 1}).toArray();
client.close();
await new Promise((resolve, reject) => {
mkdirp(path.resolve(__dirname, 'esolang-battle-archive', dirName), (error) => {
if (error) {
reject(error);
} else {
resolve();
}
});
});
const repo = await Repository.open(path.resolve(__dirname, './esolang-battle-archive'));
for (const submission of submissions) {
const submissionLanguage = languages.find((language) => language._id.equals(submission.language))
assert(submissionLanguage);
const extension = (() => {
const slug = languagesData[submissionLanguage.slug] || submissionLanguage.slug;
if (slug.startsWith('.')) {
return slug;
}
const languageRegex = new RegExp(`^${slug}$`, 'i');
const key = Object.keys(githubLanguages).find((language) => (
language.match(languageRegex) || (language.aliases && language.aliases.any((alias) => alias.match(languageRegex)))
));
if (key) {
return githubLanguages[key].extensions[0];
}
return `.${slug}`;
})();
const filename = `${submissionLanguage.slug}${extension}`;
const pathname = path.join(__dirname, 'esolang-battle-archive', dirName, filename);
await writeFile(pathname, submission.code);
const submissionUser = users.find((user) => user._id.equals(submission.user))
const submissionUserId = submissionUser.email.match(/^(.+?)@/)[1];
const authorData = usersMap.get(submissionUserId);
assert(authorData, submissionUserId);
const author = Signature.create(authorData.name, authorData.email, submission.createdAt.getTime() / 1000, 540);
const committer = Signature.create(authorData.name, authorData.email, submission.createdAt.getTime() / 1000, 540);
const commitId = await repo.createCommitOnHead([`${dirName}/${filename}`], author, committer, `Update ${filename} (${submission.size || submission.code.length} bytes)`);
}
})().catch((error) => {
console.error(error);
});