{"action":"created","issue":{"url":"https://api.github.com/repos/zry656565/Hit-Kounter-LC/issues/4","repository_url":"https://api.github.com/repos/zry656565/Hit-Kounter-LC","labels_url":"https://api.github.com/repos/zry656565/Hit-Kounter-LC/issues/4/labels{/name}","comments_url":"https://api.github.com/repos/zry656565/Hit-Kounter-LC/issues/4/comments","events_url":"https://api.github.com/repos/zry656565/Hit-Kounter-LC/issues/4/events","html_url":"https://github.com/zry656565/Hit-Kounter-LC/issues/4","id":381957136,"node_id":"MDU6SXNzdWUzODE5NTcxMzY=","number":4,"title":"自己搭建后端云问题site总数不自增","user":{"login":"crazies","id":32092495,"node_id":"MDQ6VXNlcjMyMDkyNDk1","avatar_url":"https://avatars0.githubusercontent.com/u/32092495?v=4","gravatar_id":"","url":"https://api.github.com/users/crazies","html_url":"https://github.com/crazies","followers_url":"https://api.github.com/users/crazies/followers","following_url":"https://api.github.com/users/crazies/following{/other_user}","gists_url":"https://api.github.com/users/crazies/gists{/gist_id}","starred_url":"https://api.github.com/users/crazies/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/crazies/subscriptions","organizations_url":"https://api.github.com/users/crazies/orgs","repos_url":"https://api.github.com/users/crazies/repos","events_url":"https://api.github.com/users/crazies/events{/privacy}","received_events_url":"https://api.github.com/users/crazies/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":7,"created_at":"2018-11-18T12:49:49Z","updated_at":"2018-12-27T15:32:41Z","closed_at":null,"author_association":"NONE","body":"关于自己搭建后端云的问题，还希望讲解一下嘛，难道作者不希望我们自己自己管理自己的数据嘛。"},"comment":{"url":"https://api.github.com/repos/zry656565/Hit-Kounter-LC/issues/comments/450172986","html_url":"https://github.com/zry656565/Hit-Kounter-LC/issues/4#issuecomment-450172986","issue_url":"https://api.github.com/repos/zry656565/Hit-Kounter-LC/issues/4","id":450172986,"node_id":"MDEyOklzc3VlQ29tbWVudDQ1MDE3Mjk4Ng==","user":{"login":"zry656565","id":1888508,"node_id":"MDQ6VXNlcjE4ODg1MDg=","avatar_url":"https://avatars0.githubusercontent.com/u/1888508?v=4","gravatar_id":"","url":"https://api.github.com/users/zry656565","html_url":"https://github.com/zry656565","followers_url":"https://api.github.com/users/zry656565/followers","following_url":"https://api.github.com/users/zry656565/following{/other_user}","gists_url":"https://api.github.com/users/zry656565/gists{/gist_id}","starred_url":"https://api.github.com/users/zry656565/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zry656565/subscriptions","organizations_url":"https://api.github.com/users/zry656565/orgs","repos_url":"https://api.github.com/users/zry656565/repos","events_url":"https://api.github.com/users/zry656565/events{/privacy}","received_events_url":"https://api.github.com/users/zry656565/received_events","type":"User","site_admin":false},"created_at":"2018-12-27T15:32:41Z","updated_at":"2018-12-27T15:32:41Z","author_association":"OWNER","body":"@crazies @qssq 你好，抱歉这么晚回复。\r\n全站访问量统计是每天跑自动化脚本另外计算的，不在这个项目中。代码大概是下面这个样子，我过两天有时间就开源出来。\r\n\r\n```js\r\n'use strict';\r\n\r\nconst schedule = require('node-schedule');\r\nconst log4js = require('log4js');\r\nconst AV = require('leancloud-storage');\r\nconst Promise = require('bluebird');\r\nconst config = require('../lc-config.json');\r\nconst Site = AV.Object.extend('Site');\r\n\r\nconst ENV = 'prod'; // ['prod', 'staging']\r\nconst DEBUG = false;\r\n\r\n// configure log\r\nlet appenders;\r\nif (DEBUG) {\r\n  appenders = [{ type: 'console' }];\r\n} else {\r\n  appenders =[\r\n    {\r\n      type: 'file',\r\n      filename: 'log/site-views.log',\r\n      category: 'site-views'\r\n    }\r\n  ];\r\n}\r\nlog4js.configure({ appenders });\r\n\r\nconst logger = log4js.getLogger('site-views');\r\n\r\n// configure LeanCloud\r\nAV.init(config[ENV]);\r\nAV.Cloud.useMasterKey();\r\n\r\nif (DEBUG) {\r\n  refreshSiteViews();\r\n} else {\r\n  logger.setLevel('info');\r\n  logger.info('Schedule initialized.');\r\n  // 20:00 (UTC+0) / Amsterdam === 04:00 (UTC+8) / Beijing\r\n  let j = schedule.scheduleJob('0 20 * * *', refreshSiteViews);\r\n}\r\n\r\nfunction refreshSiteViews() {\r\n\r\n  // fetch all pages and calculate the sum.\r\n  let fullSites = {};\r\n  let pageQ = new AV.Query('Page');\r\n  logger.info('Begin to recalculate...');\r\n  logger.debug('Fetching and counting pages...');\r\n  pageQ.each(p => {\r\n    let domain = p.get('domain');\r\n    let count = p.get('count');\r\n    fullSites[domain] = fullSites[domain] || 0;\r\n    fullSites[domain] += count;\r\n  })\r\n  .then(() => {\r\n    // update site views\r\n    logger.debug('Updating site views...');\r\n    return new Promise((resolve, reject) => {\r\n      const newSites = Object.assign({}, fullSites);\r\n      const updateList = [];\r\n\r\n      // fetch all sites existed and update them\r\n      let siteQ = new AV.Query('Site');\r\n      siteQ.each(site => {\r\n        let domain = site.get('domain');\r\n        if (domain in fullSites && !(domain in newSites)) {\r\n          site.destroy().then(() => {\r\n            logger.info('Redundant data deleted: ' + domain);\r\n          }, err => reject('Fail to delete redundant data', err));\r\n        }\r\n        \r\n        if (site.get('count') !== fullSites[domain]) {\r\n          site.set('count', fullSites[domain] || 0);\r\n          updateList.push(site);\r\n        }\r\n        delete newSites[domain];\r\n      }).then(() => {\r\n        // post all nonexistent sites\r\n        const Site = AV.Object.extend('Site');\r\n        for (let domain of Object.keys(newSites)) {\r\n          let site = new Site();\r\n          site.set('domain', domain);\r\n          site.set('count', newSites[domain]);\r\n          updateList.push(site);\r\n        }\r\n        logger.info('Data of ' + updateList.length + ' site(s) needs to be updated.');\r\n        return AV.Object.saveAll(updateList);\r\n      }).then(() => {\r\n        logger.info('Update DONE.');\r\n        resolve('DONE');\r\n      }).catch((message, err) => reject(message, err));\r\n    });\r\n  })\r\n  .catch((message, err) => logger.error(message, err));\r\n}\r\n```"}}
{"actor":{"display_login":"zry656565"}}