1 | const fs = require('fs')
|
2 | const path = require('path')
|
3 | const async = require('async')
|
4 | const _ = require('underscore')
|
5 | const mk = require('mkdirp')
|
6 | const cfg = require('../lib/config')
|
7 | const cl = require('../lib/color')
|
8 | const log = console.log
|
9 |
|
10 | let src = {
|
11 | $api: {
|
12 | curse: require('./curse'),
|
13 | mmoui: require('./mmoui'),
|
14 | tukui: require('./tukui'),
|
15 | github: require('./github'),
|
16 | git: require('./git')
|
17 | },
|
18 |
|
19 | $valid(ad) {
|
20 | if (ad.source && !src.$api[ad.source]) {
|
21 | log(`\nInvalid source: ${ad.source}, use one of below instead:`)
|
22 | log(
|
23 | _.keys(src.$api)
|
24 | .map(x => ` ${x}`)
|
25 | .join('\n')
|
26 | )
|
27 | return false
|
28 | }
|
29 |
|
30 | return true
|
31 | },
|
32 |
|
33 | parseName(name) {
|
34 | let t = name
|
35 | let d = {}
|
36 |
|
37 | if (name.match(/@/)) {
|
38 | t = name.split('@')
|
39 | d.version = t[1]
|
40 | t = t[0]
|
41 | }
|
42 |
|
43 | for (let k in src.$api) {
|
44 | if (t.match(/:\/\//)) {
|
45 |
|
46 | let r = src.$api[k].$lcl.exec(t)
|
47 |
|
48 |
|
49 | d.uri = t
|
50 | d.key = t
|
51 |
|
52 | if (r) {
|
53 | d.source = k
|
54 | d.key = r[r.length - 1]
|
55 | break
|
56 | }
|
57 | } else {
|
58 |
|
59 | let s = null
|
60 | let z = t.split(':')
|
61 | if (z.length > 1) s = z.shift()
|
62 | d.key = z[0]
|
63 |
|
64 | let f = src.$api[k].$fcl
|
65 | if (!s && f && d.key.search(f) >= 0) {
|
66 | d.source = k
|
67 | break
|
68 | } else if (s && src.$api[k].$scl.search(s) >= 0) {
|
69 | d.source = k
|
70 | break
|
71 | }
|
72 | }
|
73 | }
|
74 |
|
75 | d.anyway = cfg.anyway()
|
76 | return d
|
77 | },
|
78 |
|
79 | info(ad, done) {
|
80 |
|
81 | if (!src.$valid(ad)) return done()
|
82 |
|
83 | async.eachOfLimit(
|
84 | src.$api,
|
85 | 1,
|
86 | (api, source, cb) => {
|
87 | if (ad.source && source !== ad.source) return cb()
|
88 | if (!ad.source && source === 'github') return cb()
|
89 | if (!ad.uri && source === 'git') return cb()
|
90 |
|
91 | let res = null
|
92 |
|
93 | api.info(ad, info => {
|
94 | if (info && info.version.length) {
|
95 | res = info
|
96 | res.source = source
|
97 |
|
98 |
|
99 | if (source === 'git') {
|
100 | if (!ad.version) ad.version = 'master'
|
101 | ad.branch = ad.version
|
102 |
|
103 | let target = _.find(info.version, x => x.name === ad.branch)
|
104 | if (!target) {
|
105 | log(
|
106 | `\n${cl.i2(ad.branch)} is not a valid entry for ${cl.h(
|
107 | ad.uri
|
108 | )}`
|
109 | )
|
110 | log(
|
111 | 'Valid entries:',
|
112 | res.version
|
113 | .map(x => cl.i2(x.name))
|
114 | .slice(0, 10)
|
115 | .join(', '),
|
116 | '\n'
|
117 | )
|
118 | return done()
|
119 | } else {
|
120 | res.hash = target.hash
|
121 | }
|
122 | }
|
123 | done(res)
|
124 | cb(false)
|
125 | } else cb()
|
126 | })
|
127 | },
|
128 | () => {
|
129 | done()
|
130 | }
|
131 | )
|
132 | },
|
133 |
|
134 | search(ad, done) {
|
135 | if (!src.$valid(ad)) return done()
|
136 |
|
137 | async.eachOfLimit(
|
138 | src.$api,
|
139 | 1,
|
140 | (api, source, cb) => {
|
141 | if (!api.search) return cb()
|
142 | if (ad.source && source !== ad.source) return cb()
|
143 |
|
144 |
|
145 | let res = null
|
146 |
|
147 | api.search(ad, data => {
|
148 | if (data && data.length) {
|
149 | res = { source, data }
|
150 | done(res)
|
151 | cb(false)
|
152 | } else cb()
|
153 | })
|
154 | },
|
155 | () => {
|
156 | done()
|
157 | }
|
158 | )
|
159 | },
|
160 |
|
161 | summary(done) {
|
162 | let db = []
|
163 | src.$api.curse.summary(d => {
|
164 | db = db.concat(d)
|
165 | src.$api.mmoui.summary(d => {
|
166 | db = db.concat(d)
|
167 | done(db)
|
168 | })
|
169 | })
|
170 | },
|
171 |
|
172 | getDB(filter, done) {
|
173 | let p = cfg.getPath('db')
|
174 |
|
175 | if (!done) {
|
176 | done = filter
|
177 | filter = null
|
178 | }
|
179 |
|
180 | let _done = db => {
|
181 | done(filter ? _.filter(db, d => d && d.source === filter) : db)
|
182 | }
|
183 |
|
184 | if (
|
185 | !fs.existsSync(p) ||
|
186 | new Date() - fs.statSync(p).mtime > 24 * 3600 * 1000 ||
|
187 | !done
|
188 | ) {
|
189 | mk(path.dirname(p), err => {
|
190 | process.stdout.write(cl.i('\nUpdating database...'))
|
191 | src.summary(s => {
|
192 | fs.writeFileSync(p, JSON.stringify(s), 'utf-8')
|
193 | log(cl.i('done'))
|
194 | if (done) _done(s)
|
195 | })
|
196 | })
|
197 |
|
198 | return
|
199 | }
|
200 |
|
201 | _done(fs.existsSync(p) ? JSON.parse(fs.readFileSync(p, 'utf-8')) : null)
|
202 | return
|
203 | }
|
204 | }
|
205 |
|
206 | module.exports = src
|