UNPKG

4.58 kBJavaScriptView Raw
1const fs = require('fs')
2const path = require('path')
3const async = require('async')
4const _ = require('underscore')
5const mk = require('mkdirp')
6const cfg = require('../lib/config')
7const cl = require('../lib/color')
8const log = console.log
9
10let 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 // looks like an long uri
46 let r = src.$api[k].$lcl.exec(t)
47 // log('long clue exec:', r)
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 // treat as short uri
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 // log('\n\ngetting info', ad, '\n\n')
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 // log('iter', source)
93 api.info(ad, info => {
94 if (info && info.version.length) {
95 res = info
96 res.source = source
97 // log('g info', info)
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 // log('searching', source)
145 let res = null
146 // log('searching', source)
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 // force update
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
206module.exports = src