cnpm / cnpmjs.org

@@ -20,7 +20,7 @@
Loading
20 20
  var noDep = this.query.nodeps === 'true';
21 21
  var syncUpstreamFirst = this.query.sync_upstream === 'true';
22 22
  var syncFromBackupFile = this.query.sync_from_backup === 'true';
23 -
  if (!config.sourceNpmRegistryIsCNpm) {
23 +
  if (!config.enableWebDataRemoteRegistry && !config.sourceNpmRegistryIsCNpm) {
24 24
    syncUpstreamFirst = false;
25 25
  }
26 26
  debug('sync %s with query: %j, syncUpstreamFirst: %s', name, this.query, syncUpstreamFirst);

@@ -207,6 +207,10 @@
Loading
207 207
  sourceNpmRegistry: 'https://registry.npmmirror.com',
208 208
  sourceNpmWeb: 'https://npmmirror.com',
209 209
210 +
  // set remote registry to show web page data
211 +
  enableWebDataRemoteRegistry: false,
212 +
  webDataRemoteRegistry: '',
213 +
210 214
  // upstream registry is base on cnpm/cnpmjs.org or not
211 215
  // if your upstream is official npm registry, please turn it off
212 216
  sourceNpmRegistryIsCNpm: true,

@@ -1,20 +1,5 @@
Loading
1 -
/**!
2 -
 * cnpmjs.org - controllers/web/show_sync.js
3 -
 *
4 -
 * Copyright(c) cnpmjs.org and other contributors.
5 -
 * MIT Licensed
6 -
 *
7 -
 * Authors:
8 -
 *  dead_horse <dead_horse@qq.com> (http://deadhorse.me)
9 -
 *  fengmk2 <fengmk2@gmail.com> (http://fengmk2.github.com)
10 -
 */
11 -
12 1
'use strict';
13 2
14 -
/**
15 -
 * Module dependencies.
16 -
 */
17 -
18 3
module.exports = function* showSync() {
19 4
  var name = this.params.name || this.params[0] || this.query.name;
20 5
  if (!name) {

@@ -218,18 +218,24 @@
Loading
218 218
};
219 219
220 220
SyncModuleWorker.prototype.syncUpstream = function* (name) {
221 -
  if (config.sourceNpmRegistry.indexOf('registry.npmjs.org') >= 0 ||
222 -
      config.sourceNpmRegistry.indexOf('registry.npmjs.com') >= 0 ||
223 -
      config.sourceNpmRegistry.indexOf('replicate.npmjs.com') >= 0) {
221 +
  var sourceNpmRegistry = config.sourceNpmRegistry;
222 +
  if (config.enableWebDataRemoteRegistry) {
223 +
    sourceNpmRegistry = config.webDataRemoteRegistry;
224 +
  }
225 +
226 +
  if (sourceNpmRegistry.indexOf('registry.npmjs.org') >= 0 ||
227 +
      sourceNpmRegistry.indexOf('registry.npmjs.com') >= 0 ||
228 +
      sourceNpmRegistry.indexOf('replicate.npmjs.com') >= 0) {
224 229
    this.log('----------------- upstream is npm registry: %s, ignore it -------------------',
225 -
      config.sourceNpmRegistry);
230 +
      sourceNpmRegistry);
226 231
    return;
227 232
  }
228 233
  var syncname = name;
229 234
  if (this.type === 'user') {
230 235
    syncname = this.type + ':' + syncname;
231 236
  }
232 -
  var url = config.sourceNpmRegistry + '/' + syncname + '/sync?sync_upstream=true';
237 +
238 +
  var url = sourceNpmRegistry + '/' + syncname + '/sync?sync_upstream=true';
233 239
  if (this.noDep) {
234 240
    url += '&nodeps=true';
235 241
  }
@@ -248,7 +254,7 @@
Loading
248 254
      url, r.status, r.data);
249 255
  }
250 256
251 -
  var logURL = config.sourceNpmRegistry + '/' + name + '/sync/log/' + r.data.logId;
257 +
  var logURL = sourceNpmRegistry + '/' + name + '/sync/log/' + r.data.logId;
252 258
  var offset = 0;
253 259
  this.log('----------------- Syncing upstream %s -------------------', logURL);
254 260

@@ -14,8 +14,12 @@
Loading
14 14
var packageService = require('../../../services/package');
15 15
var blocklistService = require('../../../services/blocklist');
16 16
var downloadTotalService = require('../../../services/download_total');
17 +
var showWithRemote = require('./showWithRemote');
17 18
18 19
module.exports = function* show(next) {
20 +
  if (config.enableWebDataRemoteRegistry) {
21 +
    return yield showWithRemote(this, next);
22 +
  }
19 23
  var params = this.params;
20 24
  // normal: {name: $name, version: $version}
21 25
  // scope: [$name, $version]

@@ -0,0 +1,97 @@
Loading
1 +
'use strict';
2 +
3 +
const debug = require('debug')('cnpmjs.org:controllers:web:package:showWithRemote');
4 +
const moment = require('moment');
5 +
const gravatar = require('gravatar');
6 +
const giturl = require('giturl');
7 +
const urllib = require('../../../common/urllib');
8 +
const config = require('../../../config');
9 +
const renderMarkdown = require('../../../common/markdown').render;
10 +
11 +
module.exports = function* showWithRemote(ctx, next) {
12 +
  const params = ctx.params;
13 +
  const fullname = params.name || params[0];
14 +
  const versionOrTag = params.version || params[1] || 'latest';
15 +
  debug('display %s with %j', fullname, params);
16 +
17 +
  const url = `${config.webDataRemoteRegistry}/${fullname}`;
18 +
  const result = yield urllib.request(url, {
19 +
    dataType: 'json',
20 +
    timeout: 20000,
21 +
    followRedirect: true,
22 +
    gzip: true,
23 +
  });
24 +
  if (result.status !== 200) {
25 +
    return yield next;
26 +
  }
27 +
  const manifest = result.data;
28 +
29 +
  const distTags = manifest['dist-tags'] || {};
30 +
  const realVersion = distTags[versionOrTag] || versionOrTag;
31 +
  const versionsMap = manifest.versions || {};
32 +
  const pkg = versionsMap[realVersion];
33 +
  if (!pkg) {
34 +
    return yield next;
35 +
  }
36 +
37 +
  const maintainers = manifest.maintainers;
38 +
  if (maintainers) {
39 +
    for (const maintainer of maintainers) {
40 +
      if (maintainer.email) {
41 +
        maintainer.gravatar = gravatar.url(maintainer.email, {s: '50', d: 'retro'}, true);
42 +
      }
43 +
    }
44 +
    pkg.maintainers = maintainers;
45 +
  }
46 +
47 +
  const timeMap = manifest.time || {};
48 +
  
49 +
  pkg.readme = manifest.readme || '';
50 +
  if (typeof pkg.readme !== 'string') {
51 +
    pkg.readme = 'readme is not string: ' + JSON.stringify(pkg.readme);
52 +
  } else {
53 +
    pkg.readme = renderMarkdown(pkg.readme);
54 +
  }
55 +
  
56 +
  pkg.fromNow = moment(new Date(timeMap[pkg.version])).fromNow();
57 +
  // [ {tag, version, fromNow} ]
58 +
  const tags = [];
59 +
  for (const tag in distTags) {
60 +
    const version = distTags[tag];
61 +
    const time = timeMap[version];
62 +
    if (time) {
63 +
      const fromNow = moment(new Date(time)).fromNow();
64 +
      tags.push({ tag, version, fromNow });
65 +
    }
66 +
  }
67 +
  pkg.tags = tags;
68 +
  // [ {version, deprecated, fromNow} ]
69 +
  const versions = [];
70 +
  for (const version in versionsMap) {
71 +
    const item = versionsMap[version];
72 +
    versions.push({
73 +
      version,
74 +
      deprecated: item.deprecated,
75 +
      fromNow: moment(new Date(timeMap[version])).fromNow(),
76 +
    });
77 +
  }
78 +
  pkg.versions = versions;
79 +
80 +
  pkg.registryUrl = '//' + config.registryHost + '/' + pkg.name;
81 +
  pkg.registryPackageUrl = '//' + config.registryHost + '/' + pkg.name + '/' + pkg.version;
82 +
83 +
  if (pkg.repository === 'undefined') {
84 +
    pkg.repository = null;
85 +
  }
86 +
  if (pkg.repository && pkg.repository.url) {
87 +
    if (!pkg.repository.weburl) {
88 +
      pkg.repository.weburl = /^https?:\/\//.test(pkg.repository.url) ? pkg.repository.url : (giturl.parse(pkg.repository.url) || pkg.repository.url);
89 +
    }
90 +
  }
91 +
92 +
  yield ctx.render('package', {
93 +
    title: 'Package - ' + manifest.name,
94 +
    package: pkg,
95 +
    download: null,
96 +
  });
97 +
};
Files Coverage
common 67.39%
controllers 84.70%
middleware 94.34%
models 89.96%
routes 100.00%
servers 90.91%
services 91.07%
sync 89.61%
config/index.js 76.47%
lib/common.js 88.46%
Project Totals (101 files) 86.94%
Sunburst
The inner-most circle is the entire project, moving away from the center are folders then, finally, a single file. The size and color of each slice is representing the number of statements and the coverage, respectively.
Icicle
The top section represents the entire project. Proceeding with folders and finally individual files. The size and color of each slice is representing the number of statements and the coverage, respectively.
Grid
Each block represents a single file in the project. The size and color of each block is represented by the number of statements and the coverage, respectively.
Loading