├── .github └── renovate.json ├── .gitignore ├── .snyk ├── Bgate-UI ├── .npmignore ├── .travis.yml ├── GruntFile.js ├── README.md ├── assets │ ├── screenshot-0.0.png │ └── screenshot-1.0.png ├── bin │ └── pm2-web.sh ├── certs │ ├── .npmignore │ └── generate_certificate.sh ├── common │ ├── HostData.js │ └── ProcessData.js ├── config.json ├── package.json ├── pm2-web.js ├── server │ ├── app.js │ ├── components │ │ ├── Configuration.js │ │ ├── PM2Listener.js │ │ ├── ServerHostList.js │ │ └── WebSocketResponder.js │ ├── public │ │ ├── css │ │ │ ├── bootstrap-responsive.css │ │ │ ├── bootstrap.css │ │ │ ├── font-awesome.min.css │ │ │ ├── reset.css │ │ │ ├── style.css │ │ │ └── style.less │ │ ├── font │ │ │ ├── FontAwesome.otf │ │ │ ├── fontawesome-webfont.eot │ │ │ ├── fontawesome-webfont.svg │ │ │ ├── fontawesome-webfont.ttf │ │ │ └── fontawesome-webfont.woff │ │ ├── img │ │ │ ├── _logo.png │ │ │ ├── favicon.png │ │ │ ├── glyphicons-halflings-white.png │ │ │ ├── glyphicons-halflings.png │ │ │ ├── logo.png │ │ │ ├── logo@2x.png │ │ │ ├── pw_maze_white.png │ │ │ └── satinweave.png │ │ └── js │ │ │ ├── monitor.js │ │ │ ├── partials │ │ │ ├── connecting.html │ │ │ └── host.html │ │ │ └── vendor │ │ │ ├── angular │ │ │ ├── angular-animate.js │ │ │ ├── angular-animate.min.js │ │ │ ├── angular-animate.min.js.map │ │ │ ├── angular-cookies.js │ │ │ ├── angular-cookies.min.js │ │ │ ├── angular-cookies.min.js.map │ │ │ ├── angular-csp.css │ │ │ ├── angular-loader.js │ │ │ ├── angular-loader.min.js │ │ │ ├── angular-loader.min.js.map │ │ │ ├── angular-mocks.js │ │ │ ├── angular-resource.js │ │ │ ├── angular-resource.min.js │ │ │ ├── angular-resource.min.js.map │ │ │ ├── angular-route.js │ │ │ ├── angular-route.min.js │ │ │ ├── angular-route.min.js.map │ │ │ ├── angular-sanitize.js │ │ │ ├── angular-sanitize.min.js │ │ │ ├── angular-sanitize.min.js.map │ │ │ ├── angular-scenario.js │ │ │ ├── angular-touch.js │ │ │ ├── angular-touch.min.js │ │ │ ├── angular-touch.min.js.map │ │ │ ├── angular.js │ │ │ ├── angular.min.js │ │ │ ├── angular.min.js.map │ │ │ ├── errors.json │ │ │ ├── i18n │ │ │ │ ├── angular-locale_af-na.js │ │ │ │ ├── angular-locale_af-za.js │ │ │ │ ├── angular-locale_af.js │ │ │ │ ├── angular-locale_am-et.js │ │ │ │ ├── angular-locale_am.js │ │ │ │ ├── angular-locale_ar-001.js │ │ │ │ ├── angular-locale_ar-ae.js │ │ │ │ ├── angular-locale_ar-bh.js │ │ │ │ ├── angular-locale_ar-dz.js │ │ │ │ ├── angular-locale_ar-eg.js │ │ │ │ ├── angular-locale_ar-iq.js │ │ │ │ ├── angular-locale_ar-jo.js │ │ │ │ ├── angular-locale_ar-kw.js │ │ │ │ ├── angular-locale_ar-lb.js │ │ │ │ ├── angular-locale_ar-ly.js │ │ │ │ ├── angular-locale_ar-ma.js │ │ │ │ ├── angular-locale_ar-om.js │ │ │ │ ├── angular-locale_ar-qa.js │ │ │ │ ├── angular-locale_ar-sa.js │ │ │ │ ├── angular-locale_ar-sd.js │ │ │ │ ├── angular-locale_ar-sy.js │ │ │ │ ├── angular-locale_ar-tn.js │ │ │ │ ├── angular-locale_ar-ye.js │ │ │ │ ├── angular-locale_ar.js │ │ │ │ ├── angular-locale_bg-bg.js │ │ │ │ ├── angular-locale_bg.js │ │ │ │ ├── angular-locale_bn-bd.js │ │ │ │ ├── angular-locale_bn-in.js │ │ │ │ ├── angular-locale_bn.js │ │ │ │ ├── angular-locale_ca-ad.js │ │ │ │ ├── angular-locale_ca-es.js │ │ │ │ ├── angular-locale_ca.js │ │ │ │ ├── angular-locale_cs-cz.js │ │ │ │ ├── angular-locale_cs.js │ │ │ │ ├── angular-locale_da-dk.js │ │ │ │ ├── angular-locale_da.js │ │ │ │ ├── angular-locale_de-at.js │ │ │ │ ├── angular-locale_de-be.js │ │ │ │ ├── angular-locale_de-ch.js │ │ │ │ ├── angular-locale_de-de.js │ │ │ │ ├── angular-locale_de-li.js │ │ │ │ ├── angular-locale_de-lu.js │ │ │ │ ├── angular-locale_de.js │ │ │ │ ├── angular-locale_el-cy.js │ │ │ │ ├── angular-locale_el-gr.js │ │ │ │ ├── angular-locale_el.js │ │ │ │ ├── angular-locale_en-as.js │ │ │ │ ├── angular-locale_en-au.js │ │ │ │ ├── angular-locale_en-bb.js │ │ │ │ ├── angular-locale_en-be.js │ │ │ │ ├── angular-locale_en-bm.js │ │ │ │ ├── angular-locale_en-bw.js │ │ │ │ ├── angular-locale_en-bz.js │ │ │ │ ├── angular-locale_en-ca.js │ │ │ │ ├── angular-locale_en-dsrt-us.js │ │ │ │ ├── angular-locale_en-dsrt.js │ │ │ │ ├── angular-locale_en-fm.js │ │ │ │ ├── angular-locale_en-gb.js │ │ │ │ ├── angular-locale_en-gu.js │ │ │ │ ├── angular-locale_en-gy.js │ │ │ │ ├── angular-locale_en-hk.js │ │ │ │ ├── angular-locale_en-ie.js │ │ │ │ ├── angular-locale_en-in.js │ │ │ │ ├── angular-locale_en-iso.js │ │ │ │ ├── angular-locale_en-jm.js │ │ │ │ ├── angular-locale_en-mh.js │ │ │ │ ├── angular-locale_en-mp.js │ │ │ │ ├── angular-locale_en-mt.js │ │ │ │ ├── angular-locale_en-mu.js │ │ │ │ ├── angular-locale_en-na.js │ │ │ │ ├── angular-locale_en-nz.js │ │ │ │ ├── angular-locale_en-ph.js │ │ │ │ ├── angular-locale_en-pk.js │ │ │ │ ├── angular-locale_en-pr.js │ │ │ │ ├── angular-locale_en-pw.js │ │ │ │ ├── angular-locale_en-sg.js │ │ │ │ ├── angular-locale_en-tc.js │ │ │ │ ├── angular-locale_en-tt.js │ │ │ │ ├── angular-locale_en-um.js │ │ │ │ ├── angular-locale_en-us.js │ │ │ │ ├── angular-locale_en-vg.js │ │ │ │ ├── angular-locale_en-vi.js │ │ │ │ ├── angular-locale_en-za.js │ │ │ │ ├── angular-locale_en-zw.js │ │ │ │ ├── angular-locale_en.js │ │ │ │ ├── angular-locale_es-419.js │ │ │ │ ├── angular-locale_es-ar.js │ │ │ │ ├── angular-locale_es-bo.js │ │ │ │ ├── angular-locale_es-cl.js │ │ │ │ ├── angular-locale_es-co.js │ │ │ │ ├── angular-locale_es-cr.js │ │ │ │ ├── angular-locale_es-do.js │ │ │ │ ├── angular-locale_es-ea.js │ │ │ │ ├── angular-locale_es-ec.js │ │ │ │ ├── angular-locale_es-es.js │ │ │ │ ├── angular-locale_es-gq.js │ │ │ │ ├── angular-locale_es-gt.js │ │ │ │ ├── angular-locale_es-hn.js │ │ │ │ ├── angular-locale_es-ic.js │ │ │ │ ├── angular-locale_es-mx.js │ │ │ │ ├── angular-locale_es-ni.js │ │ │ │ ├── angular-locale_es-pa.js │ │ │ │ ├── angular-locale_es-pe.js │ │ │ │ ├── angular-locale_es-pr.js │ │ │ │ ├── angular-locale_es-py.js │ │ │ │ ├── angular-locale_es-sv.js │ │ │ │ ├── angular-locale_es-us.js │ │ │ │ ├── angular-locale_es-uy.js │ │ │ │ ├── angular-locale_es-ve.js │ │ │ │ ├── angular-locale_es.js │ │ │ │ ├── angular-locale_et-ee.js │ │ │ │ ├── angular-locale_et.js │ │ │ │ ├── angular-locale_eu-es.js │ │ │ │ ├── angular-locale_eu.js │ │ │ │ ├── angular-locale_fa-af.js │ │ │ │ ├── angular-locale_fa-ir.js │ │ │ │ ├── angular-locale_fa.js │ │ │ │ ├── angular-locale_fi-fi.js │ │ │ │ ├── angular-locale_fi.js │ │ │ │ ├── angular-locale_fil-ph.js │ │ │ │ ├── angular-locale_fil.js │ │ │ │ ├── angular-locale_fr-be.js │ │ │ │ ├── angular-locale_fr-bf.js │ │ │ │ ├── angular-locale_fr-bi.js │ │ │ │ ├── angular-locale_fr-bj.js │ │ │ │ ├── angular-locale_fr-bl.js │ │ │ │ ├── angular-locale_fr-ca.js │ │ │ │ ├── angular-locale_fr-cd.js │ │ │ │ ├── angular-locale_fr-cf.js │ │ │ │ ├── angular-locale_fr-cg.js │ │ │ │ ├── angular-locale_fr-ch.js │ │ │ │ ├── angular-locale_fr-ci.js │ │ │ │ ├── angular-locale_fr-cm.js │ │ │ │ ├── angular-locale_fr-dj.js │ │ │ │ ├── angular-locale_fr-fr.js │ │ │ │ ├── angular-locale_fr-ga.js │ │ │ │ ├── angular-locale_fr-gf.js │ │ │ │ ├── angular-locale_fr-gn.js │ │ │ │ ├── angular-locale_fr-gp.js │ │ │ │ ├── angular-locale_fr-gq.js │ │ │ │ ├── angular-locale_fr-km.js │ │ │ │ ├── angular-locale_fr-lu.js │ │ │ │ ├── angular-locale_fr-mc.js │ │ │ │ ├── angular-locale_fr-mf.js │ │ │ │ ├── angular-locale_fr-mg.js │ │ │ │ ├── angular-locale_fr-ml.js │ │ │ │ ├── angular-locale_fr-mq.js │ │ │ │ ├── angular-locale_fr-ne.js │ │ │ │ ├── angular-locale_fr-re.js │ │ │ │ ├── angular-locale_fr-yt.js │ │ │ │ ├── angular-locale_fr.js │ │ │ │ ├── angular-locale_gl-es.js │ │ │ │ ├── angular-locale_gl.js │ │ │ │ ├── angular-locale_gsw-ch.js │ │ │ │ ├── angular-locale_gsw.js │ │ │ │ ├── angular-locale_gu-in.js │ │ │ │ ├── angular-locale_gu.js │ │ │ │ ├── angular-locale_he-il.js │ │ │ │ ├── angular-locale_he.js │ │ │ │ ├── angular-locale_hi-in.js │ │ │ │ ├── angular-locale_hi.js │ │ │ │ ├── angular-locale_hr-hr.js │ │ │ │ ├── angular-locale_hr.js │ │ │ │ ├── angular-locale_hu-hu.js │ │ │ │ ├── angular-locale_hu.js │ │ │ │ ├── angular-locale_id-id.js │ │ │ │ ├── angular-locale_id.js │ │ │ │ ├── angular-locale_in.js │ │ │ │ ├── angular-locale_is-is.js │ │ │ │ ├── angular-locale_is.js │ │ │ │ ├── angular-locale_it-it.js │ │ │ │ ├── angular-locale_it-sm.js │ │ │ │ ├── angular-locale_it.js │ │ │ │ ├── angular-locale_iw.js │ │ │ │ ├── angular-locale_ja-jp.js │ │ │ │ ├── angular-locale_ja.js │ │ │ │ ├── angular-locale_kn-in.js │ │ │ │ ├── angular-locale_kn.js │ │ │ │ ├── angular-locale_ko-kr.js │ │ │ │ ├── angular-locale_ko.js │ │ │ │ ├── angular-locale_ln-cd.js │ │ │ │ ├── angular-locale_ln.js │ │ │ │ ├── angular-locale_lt-lt.js │ │ │ │ ├── angular-locale_lt.js │ │ │ │ ├── angular-locale_lv-lv.js │ │ │ │ ├── angular-locale_lv.js │ │ │ │ ├── angular-locale_ml-in.js │ │ │ │ ├── angular-locale_ml.js │ │ │ │ ├── angular-locale_mr-in.js │ │ │ │ ├── angular-locale_mr.js │ │ │ │ ├── angular-locale_ms-my.js │ │ │ │ ├── angular-locale_ms.js │ │ │ │ ├── angular-locale_mt-mt.js │ │ │ │ ├── angular-locale_mt.js │ │ │ │ ├── angular-locale_nl-cw.js │ │ │ │ ├── angular-locale_nl-nl.js │ │ │ │ ├── angular-locale_nl-sx.js │ │ │ │ ├── angular-locale_nl.js │ │ │ │ ├── angular-locale_no.js │ │ │ │ ├── angular-locale_or-in.js │ │ │ │ ├── angular-locale_or.js │ │ │ │ ├── angular-locale_pl-pl.js │ │ │ │ ├── angular-locale_pl.js │ │ │ │ ├── angular-locale_pt-br.js │ │ │ │ ├── angular-locale_pt-pt.js │ │ │ │ ├── angular-locale_pt.js │ │ │ │ ├── angular-locale_ro-ro.js │ │ │ │ ├── angular-locale_ro.js │ │ │ │ ├── angular-locale_ru-ru.js │ │ │ │ ├── angular-locale_ru.js │ │ │ │ ├── angular-locale_sk-sk.js │ │ │ │ ├── angular-locale_sk.js │ │ │ │ ├── angular-locale_sl-si.js │ │ │ │ ├── angular-locale_sl.js │ │ │ │ ├── angular-locale_sq-al.js │ │ │ │ ├── angular-locale_sq.js │ │ │ │ ├── angular-locale_sr-cyrl-rs.js │ │ │ │ ├── angular-locale_sr-latn-rs.js │ │ │ │ ├── angular-locale_sr.js │ │ │ │ ├── angular-locale_sv-se.js │ │ │ │ ├── angular-locale_sv.js │ │ │ │ ├── angular-locale_sw-tz.js │ │ │ │ ├── angular-locale_sw.js │ │ │ │ ├── angular-locale_ta-in.js │ │ │ │ ├── angular-locale_ta.js │ │ │ │ ├── angular-locale_te-in.js │ │ │ │ ├── angular-locale_te.js │ │ │ │ ├── angular-locale_th-th.js │ │ │ │ ├── angular-locale_th.js │ │ │ │ ├── angular-locale_tl.js │ │ │ │ ├── angular-locale_tr-tr.js │ │ │ │ ├── angular-locale_tr.js │ │ │ │ ├── angular-locale_uk-ua.js │ │ │ │ ├── angular-locale_uk.js │ │ │ │ ├── angular-locale_ur-pk.js │ │ │ │ ├── angular-locale_ur.js │ │ │ │ ├── angular-locale_vi-vn.js │ │ │ │ ├── angular-locale_vi.js │ │ │ │ ├── angular-locale_zh-cn.js │ │ │ │ ├── angular-locale_zh-hans-cn.js │ │ │ │ ├── angular-locale_zh-hk.js │ │ │ │ ├── angular-locale_zh-tw.js │ │ │ │ ├── angular-locale_zh.js │ │ │ │ ├── angular-locale_zu-za.js │ │ │ │ └── angular-locale_zu.js │ │ │ ├── version.json │ │ │ └── version.txt │ │ │ ├── bootstrap │ │ │ ├── ui-bootstrap-0.7.0.js │ │ │ ├── ui-bootstrap-0.7.0.min.js │ │ │ ├── ui-bootstrap-tpls-0.7.0.js │ │ │ └── ui-bootstrap-tpls-0.7.0.min.js │ │ │ ├── highcharts-ng │ │ │ └── highcharts-ng.min.js │ │ │ ├── highcharts │ │ │ └── highcharts-all.js │ │ │ └── reconnecting-websocket │ │ │ └── reconnecting-websocket.min.js │ ├── routes │ │ └── Home.js │ └── views │ │ └── index.jade ├── test │ ├── fixtures │ │ ├── crashy.js │ │ ├── exceptional.js │ │ ├── jibberjabber.js │ │ └── talky.js │ ├── integration │ │ ├── hosts.js │ │ └── lib │ │ │ └── Harness.js │ └── unit │ │ ├── aggregator.js │ │ ├── common │ │ ├── HostDataTest.js │ │ └── ProcessDataTest.js │ │ ├── server │ │ └── components │ │ │ ├── ConfigurationTest.js │ │ │ ├── PM2ListenerTest.js │ │ │ ├── ServerHostListTest.js │ │ │ └── WebSocketResponderTest.js │ │ └── ui │ │ ├── components │ │ ├── ConfigTest.js │ │ ├── HostListTest.js │ │ └── WebSocketResponderTest.js │ │ ├── controllers │ │ ├── connectionTest.js │ │ ├── footerTest.js │ │ ├── hostListTest.js │ │ ├── processListTest.js │ │ └── systemTest.js │ │ └── filters │ │ ├── ansiToHtmlTest.js │ │ ├── decimalPlacesTest.js │ │ ├── humaniseTest.js │ │ └── memoryTest.js └── ui │ ├── components │ ├── Config.js │ ├── UIHostList.js │ └── WebSocketResponder.js │ ├── controllers │ ├── connection.js │ ├── footer.js │ ├── hostList.js │ ├── processList.js │ └── system.js │ ├── directives │ ├── resourceUsage.js │ └── scrollGlue.js │ ├── filters │ ├── ansiToHtml.js │ ├── decimalPlaces.js │ ├── humanise.js │ └── memory.js │ ├── index.js │ └── routes.js ├── README.md ├── TODO.txt ├── bgate_agent.txt ├── bgate_env.sh ├── config ├── bgate_var.js ├── config.js ├── db.js ├── global.js ├── mongo.js ├── mongodb.js └── routes.js ├── cronjob.js ├── cronjob ├── adzone-daily-tracker.js ├── banner-daily-tracker.js ├── internal-transaction-daily.js ├── internal-transaction-monthly.js ├── re-counter-banner-adzone.js ├── sync-banner-counter.js └── ubuntu │ ├── daily-endday.sh │ ├── daily-startday.sh │ ├── hourly.sh │ ├── minutely-15.sh │ ├── minutely.sh │ ├── monthly.sh │ └── weekly.sh ├── helper ├── BannerFilters.js ├── BgateAgent.js ├── Publisher.js ├── builder.js └── syncBannerCounter.js ├── lib └── openrtb │ ├── .npmignore │ ├── .travis.yml │ ├── LICENSE │ ├── README.md │ ├── index.js │ ├── lib │ ├── builderFactory.js │ ├── openrtb2_3 │ │ ├── app.js │ │ ├── banner.js │ │ ├── bid.js │ │ ├── bidRequest.js │ │ ├── bidResponse.js │ │ ├── device.js │ │ ├── imp.js │ │ ├── native.js │ │ ├── publisher.js │ │ ├── seatbid.js │ │ └── user.js │ └── rtbObject.js │ ├── package.json │ └── test │ ├── builderFactory.js │ ├── mocks │ └── mockResponse.js │ ├── openrtb2_3Tests.js │ └── rtbObjectTests.js ├── logs ├── .gitignore └── access │ └── access-2015-06-22.log ├── package.json ├── render ├── adbanner.js └── index.js ├── sample_db.mwb ├── server.js ├── setup_ubuntu_crontab.md ├── system ├── bannerRenderController.js ├── bidrequestController.js ├── bidsController.js ├── clickTrackerController.js ├── debugController.js ├── impTrackerController.js ├── manController.js ├── managerController.js ├── pingController.js ├── syncController.js ├── triggerController.js └── winNoticeController.js └── templates └── adbanner.jst /.github/renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "automerge": true, 3 | "extends": [ 4 | "config:base" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | logs/* 3 | -------------------------------------------------------------------------------- /.snyk: -------------------------------------------------------------------------------- 1 | # Snyk (https://snyk.io) policy file, patches or ignores known vulnerabilities. 2 | version: v1.7.0 3 | ignore: {} 4 | # patches apply the minimum changes required to fix a vulnerability 5 | patch: 6 | 'npm:ms:20170412': 7 | - mongoose > ms: 8 | patched: '2017-05-22T02:35:06.974Z' 9 | - morgan > debug > ms: 10 | patched: '2017-05-22T02:35:06.974Z' 11 | - compression > debug > ms: 12 | patched: '2017-05-22T02:35:06.974Z' 13 | - cookie-session > debug > ms: 14 | patched: '2017-05-22T02:35:06.974Z' 15 | - express-mysql-session > express-session > debug > ms: 16 | patched: '2017-05-22T02:35:06.974Z' 17 | - express-mysql-session > debug > ms: 18 | patched: '2017-05-22T02:35:06.974Z' 19 | - mongoose > mquery > debug > ms: 20 | patched: '2017-05-22T02:35:06.974Z' 21 | - express-mysql-session > mysql-connection-manager > debug > ms: 22 | patched: '2017-05-22T02:35:06.974Z' 23 | -------------------------------------------------------------------------------- /Bgate-UI/.npmignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | data 4 | .idea 5 | *.iml 6 | coverage 7 | *.log 8 | -------------------------------------------------------------------------------- /Bgate-UI/.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "0.10" 4 | script: npm run coveralls 5 | -------------------------------------------------------------------------------- /Bgate-UI/GruntFile.js: -------------------------------------------------------------------------------- 1 | module.exports = function(grunt) { 2 | grunt.initConfig({ 3 | 4 | browserify: { 5 | dist: { 6 | src: "ui/index.js", 7 | dest: "./server/public/js/monitor.js" 8 | } 9 | }, 10 | 11 | less: { 12 | development: { 13 | files: { 14 | "./server/public/css/style.css": "./server/public/css/style.less" 15 | } 16 | } 17 | }, 18 | 19 | watch: { 20 | scripts: { 21 | files: [ 22 | "./ui/**/*.js", 23 | "./common/**/*.js", 24 | "./server/public/css/*.less" 25 | ], 26 | tasks: ["browserify", "less"], 27 | options: { 28 | spawn: false 29 | } 30 | } 31 | } 32 | }); 33 | 34 | grunt.loadNpmTasks("grunt-browserify"); 35 | grunt.loadNpmTasks("grunt-contrib-watch"); 36 | grunt.loadNpmTasks('grunt-contrib-less'); 37 | 38 | 39 | // default task 40 | grunt.registerTask("default", ["browserify", "less", "watch"]); 41 | }; -------------------------------------------------------------------------------- /Bgate-UI/assets/screenshot-0.0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duyet/node-rtb-server/1089edd8eeac0d3027d4df2b0b2091fe6721241d/Bgate-UI/assets/screenshot-0.0.png -------------------------------------------------------------------------------- /Bgate-UI/assets/screenshot-1.0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duyet/node-rtb-server/1089edd8eeac0d3027d4df2b0b2091fe6721241d/Bgate-UI/assets/screenshot-1.0.png -------------------------------------------------------------------------------- /Bgate-UI/bin/pm2-web.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | require(__dirname + "/../pm2-web.js"); 4 | -------------------------------------------------------------------------------- /Bgate-UI/certs/.npmignore: -------------------------------------------------------------------------------- 1 | *.crt 2 | *.key 3 | *.csr 4 | -------------------------------------------------------------------------------- /Bgate-UI/certs/generate_certificate.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | DOMAIN=localhost 4 | COMPANY=pm2-web 5 | COUNTRY=UK 6 | CA_KEY=`LC_CTYPE=C tr -dc A-Za-z0-9_\!\@\#\$\%\^\&\*\(\)-+= < /dev/urandom | head -c 32 | xargs` 7 | CRT_KEY=`LC_CTYPE=C tr -dc A-Za-z0-9_\!\@\#\$\%\^\&\*\(\)-+= < /dev/urandom | head -c 32 | xargs` 8 | 9 | # Create the CA Key and Certificate for signing Client Certs 10 | echo Creating CA key 11 | openssl genrsa -des3 -out ca.key -passout pass:$CA_KEY 4096 12 | 13 | echo Creating CA certificate for "/CN=$DOMAIN/O=$COMPANY/C=$COUNTRY" 14 | openssl req -new -x509 -days 365 -key ca.key -out ca.crt -subj "/CN=$DOMAIN/O=$COMPANY/C=$COUNTRY" -passin pass:$CA_KEY 15 | 16 | # Create the Server Key, CSR, and Certificate 17 | echo Creating server key 18 | openssl genrsa -des3 -out server.key -passout pass:$CRT_KEY 1024 19 | 20 | echo Creating server certificate for "/CN=$DOMAIN/O=$COMPANY/C=$COUNTRY" 21 | openssl req -new -key server.key -out server.csr -subj "/CN=$DOMAIN/O=$COMPANY/C=$COUNTRY" -passin pass:$CRT_KEY 22 | 23 | # We're self signing our own server cert here. This is a no-no in production. 24 | echo Signing server certificate 25 | openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt -passin pass:$CA_KEY 26 | 27 | echo 28 | echo All done. Add the following to the \"www\" section of your config.json: 29 | echo 30 | echo '{' 31 | echo -e '\t"www": {' 32 | echo -e '\t\t...' 33 | echo -e '\t\t"ssl": {' 34 | echo -e '\t\t\t"enabled": true,' 35 | echo -e '\t\t\t"passphrase": "'$CRT_KEY'",' 36 | echo -e '\t\t\t"key": "'`pwd`'/server.key",' 37 | echo -e '\t\t\t"certificate": "'`pwd`'/server.crt"' 38 | echo -e '\t\t}' 39 | echo -e '\t}' 40 | echo -e '\t...' 41 | echo '}' 42 | -------------------------------------------------------------------------------- /Bgate-UI/common/HostData.js: -------------------------------------------------------------------------------- 1 | var ProcessData = require("./ProcessData"); 2 | 3 | var HostData = function(data, config) { 4 | Object.defineProperty(this, "_config", { 5 | enumerable: false, 6 | value: config 7 | }); 8 | 9 | this.name = data.name; 10 | this.inspector = data.inspector; 11 | this.pm2 = data.pm2, 12 | this.system = {}; 13 | this.processes = []; 14 | }; 15 | 16 | HostData.prototype.update = function(data) { 17 | this.lastUpdated = Date.now(); 18 | 19 | ["hostname", "cpu_count", "uptime", "time"].forEach(function(key) { 20 | this.system[key] = data.system[key] 21 | }.bind(this)); 22 | 23 | this.system.load = [ 24 | data.system.load[0], 25 | data.system.load[1], 26 | data.system.load[2] 27 | ]; 28 | this.system.memory = { 29 | free: data.system.memory.free, 30 | total: data.system.memory.total, 31 | used: data.system.memory.total - data.system.memory.free 32 | }; 33 | 34 | this._removeMissingProcesses(data.processes); 35 | 36 | data.processes.forEach(function(reportedProcess) { 37 | var existingProcess = this.findProcessById(reportedProcess.id); 38 | 39 | if(!existingProcess) { 40 | existingProcess = new ProcessData(this._config, reportedProcess); 41 | this.processes.push(existingProcess); 42 | } 43 | 44 | existingProcess.update(reportedProcess, data.system); 45 | }.bind(this)); 46 | }; 47 | 48 | HostData.prototype._removeMissingProcesses = function(reportedProcesses) { 49 | this.processes = this.processes.filter(function(existingProcess) { 50 | for(var i = 0; i < reportedProcesses.length; i++) { 51 | if(reportedProcesses[i].name == existingProcess.name) { 52 | return true; 53 | } 54 | } 55 | 56 | return false; 57 | }); 58 | }; 59 | 60 | HostData.prototype.findProcessById = function(id) { 61 | for(var i = 0; i < this.processes.length; i++) { 62 | if(this.processes[i].id == id) { 63 | return this.processes[i]; 64 | } 65 | } 66 | 67 | return null; 68 | } 69 | 70 | module.exports = HostData; -------------------------------------------------------------------------------- /Bgate-UI/pm2-web.js: -------------------------------------------------------------------------------- 1 | 2 | var PM2Web = require(__dirname + "/server/app"); 3 | 4 | var pm2web = new PM2Web({}); 5 | pm2web.start(); 6 | -------------------------------------------------------------------------------- /Bgate-UI/server/components/ServerHostList.js: -------------------------------------------------------------------------------- 1 | var HostData = require(__dirname + "/../../common/HostData"), 2 | Autowire = require("wantsit").Autowire; 3 | 4 | var ServerHostList = function() { 5 | this._pm2Listener = Autowire; 6 | this._config = Autowire; 7 | this._logger = Autowire; 8 | 9 | this._hostData = {}; 10 | } 11 | 12 | ServerHostList.prototype.afterPropertiesSet = function() { 13 | this._pm2Listener.on("systemData", this._onSystemData.bind(this)); 14 | this._pm2Listener.on("pm2:kill", function(data) { 15 | this._logger.info("HostList", data.name, "was killed"); 16 | delete this._hostData[data.name]; 17 | }.bind(this)); 18 | 19 | setInterval(this._hostPurge.bind(this), this._config.get("hostPurge:frequency")); 20 | }; 21 | 22 | ServerHostList.prototype._onSystemData = function(data) { 23 | if(!this._hostData[data.name]) { 24 | this._hostData[data.name] = new HostData(data, this._config); 25 | } 26 | 27 | this._hostData[data.name].update(data); 28 | }; 29 | 30 | ServerHostList.prototype._hostPurge = function() { 31 | var now = Date.now(); 32 | 33 | Object.keys(this._hostData).forEach(function(key) { 34 | if(now - this._hostData[key].lastUpdated > this._config.get("hostPurge:cutoff")) { 35 | this._logger.info("HostList", key, "has gone away"); 36 | delete this._hostData[key]; 37 | } 38 | }.bind(this)); 39 | }; 40 | 41 | ServerHostList.prototype.getHosts = function() { 42 | var output = []; 43 | 44 | Object.keys(this._hostData).forEach(function(key) { 45 | output.push(this._hostData[key]); 46 | }.bind(this)); 47 | 48 | return output; 49 | }; 50 | 51 | ServerHostList.prototype.addLog = function(host, pm2_id, type, data) { 52 | var host = this._hostData[host]; 53 | 54 | if(!host) { 55 | return; 56 | } 57 | 58 | var process = host.findProcessById(pm2_id); 59 | 60 | if(!process) { 61 | return; 62 | } 63 | 64 | process.log(type, data); 65 | } 66 | 67 | module.exports = ServerHostList; 68 | -------------------------------------------------------------------------------- /Bgate-UI/server/public/css/reset.css: -------------------------------------------------------------------------------- 1 | /* http://meyerweb.com/eric/tools/css/reset/ 2 | v2.0 | 20110126 3 | License: none (public domain) 4 | */ 5 | 6 | html, body, div, span, applet, object, iframe, 7 | h1, h2, h3, h4, h5, h6, p, blockquote, pre, 8 | a, abbr, acronym, address, big, cite, code, 9 | del, dfn, em, img, ins, kbd, q, s, samp, 10 | small, strike, strong, sub, sup, tt, var, 11 | b, u, i, center, 12 | dl, dt, dd, ol, ul, li, 13 | fieldset, form, label, legend, 14 | table, caption, tbody, tfoot, thead, tr, th, td, 15 | article, aside, canvas, details, embed, 16 | figure, figcaption, footer, header, hgroup, 17 | menu, nav, output, ruby, section, summary, 18 | time, mark, audio, video { 19 | margin: 0; 20 | padding: 0; 21 | border: 0; 22 | font-size: 100%; 23 | font: inherit; 24 | vertical-align: baseline; 25 | } 26 | /* HTML5 display-role reset for older browsers */ 27 | article, aside, details, figcaption, figure, 28 | footer, header, hgroup, menu, nav, section { 29 | display: block; 30 | } 31 | body { 32 | line-height: 1; 33 | } 34 | ol, ul { 35 | list-style: none; 36 | } 37 | blockquote, q { 38 | quotes: none; 39 | } 40 | blockquote:before, blockquote:after, 41 | q:before, q:after { 42 | content: ''; 43 | content: none; 44 | } 45 | table { 46 | border-collapse: collapse; 47 | border-spacing: 0; 48 | } -------------------------------------------------------------------------------- /Bgate-UI/server/public/font/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duyet/node-rtb-server/1089edd8eeac0d3027d4df2b0b2091fe6721241d/Bgate-UI/server/public/font/FontAwesome.otf -------------------------------------------------------------------------------- /Bgate-UI/server/public/font/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duyet/node-rtb-server/1089edd8eeac0d3027d4df2b0b2091fe6721241d/Bgate-UI/server/public/font/fontawesome-webfont.eot -------------------------------------------------------------------------------- /Bgate-UI/server/public/font/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duyet/node-rtb-server/1089edd8eeac0d3027d4df2b0b2091fe6721241d/Bgate-UI/server/public/font/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /Bgate-UI/server/public/font/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duyet/node-rtb-server/1089edd8eeac0d3027d4df2b0b2091fe6721241d/Bgate-UI/server/public/font/fontawesome-webfont.woff -------------------------------------------------------------------------------- /Bgate-UI/server/public/img/_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duyet/node-rtb-server/1089edd8eeac0d3027d4df2b0b2091fe6721241d/Bgate-UI/server/public/img/_logo.png -------------------------------------------------------------------------------- /Bgate-UI/server/public/img/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duyet/node-rtb-server/1089edd8eeac0d3027d4df2b0b2091fe6721241d/Bgate-UI/server/public/img/favicon.png -------------------------------------------------------------------------------- /Bgate-UI/server/public/img/glyphicons-halflings-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duyet/node-rtb-server/1089edd8eeac0d3027d4df2b0b2091fe6721241d/Bgate-UI/server/public/img/glyphicons-halflings-white.png -------------------------------------------------------------------------------- /Bgate-UI/server/public/img/glyphicons-halflings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duyet/node-rtb-server/1089edd8eeac0d3027d4df2b0b2091fe6721241d/Bgate-UI/server/public/img/glyphicons-halflings.png -------------------------------------------------------------------------------- /Bgate-UI/server/public/img/logo.png: -------------------------------------------------------------------------------- 1 | /home/ubuntu/bda_logo.png -------------------------------------------------------------------------------- /Bgate-UI/server/public/img/logo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duyet/node-rtb-server/1089edd8eeac0d3027d4df2b0b2091fe6721241d/Bgate-UI/server/public/img/logo@2x.png -------------------------------------------------------------------------------- /Bgate-UI/server/public/img/pw_maze_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duyet/node-rtb-server/1089edd8eeac0d3027d4df2b0b2091fe6721241d/Bgate-UI/server/public/img/pw_maze_white.png -------------------------------------------------------------------------------- /Bgate-UI/server/public/img/satinweave.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duyet/node-rtb-server/1089edd8eeac0d3027d4df2b0b2091fe6721241d/Bgate-UI/server/public/img/satinweave.png -------------------------------------------------------------------------------- /Bgate-UI/server/public/js/partials/connecting.html: -------------------------------------------------------------------------------- 1 |

PM2 Process Monitor

2 | {{alert.message}} -------------------------------------------------------------------------------- /Bgate-UI/server/public/js/vendor/angular/angular-cookies.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | AngularJS v1.2.3 3 | (c) 2010-2014 Google, Inc. http://angularjs.org 4 | License: MIT 5 | */ 6 | (function(p,f,n){'use strict';f.module("ngCookies",["ng"]).factory("$cookies",["$rootScope","$browser",function(d,b){var c={},g={},h,k=!1,l=f.copy,m=f.isUndefined;b.addPollFn(function(){var a=b.cookies();h!=a&&(h=a,l(a,g),l(a,c),k&&d.$apply())})();k=!0;d.$watch(function(){var a,e,d;for(a in g)m(c[a])&&b.cookies(a,n);for(a in c)(e=c[a],f.isString(e))?e!==g[a]&&(b.cookies(a,e),d=!0):f.isDefined(g[a])?c[a]=g[a]:delete c[a];if(d)for(a in e=b.cookies(),c)c[a]!==e[a]&&(m(e[a])?delete c[a]:c[a]=e[a])}); 7 | return c}]).factory("$cookieStore",["$cookies",function(d){return{get:function(b){return(b=d[b])?f.fromJson(b):b},put:function(b,c){d[b]=f.toJson(c)},remove:function(b){delete d[b]}}}])})(window,window.angular); 8 | //# sourceMappingURL=angular-cookies.min.js.map 9 | -------------------------------------------------------------------------------- /Bgate-UI/server/public/js/vendor/angular/angular-cookies.min.js.map: -------------------------------------------------------------------------------- 1 | { 2 | "version":3, 3 | "file":"angular-cookies.min.js", 4 | "lineCount":7, 5 | "mappings":"A;;;;;aAKC,SAAQ,CAACA,CAAD,CAASC,CAAT,CAAkBC,CAAlB,CAA6B,CAoBtCD,CAAAE,OAAA,CAAe,WAAf,CAA4B,CAAC,IAAD,CAA5B,CAAAC,QAAA,CA4BW,UA5BX,CA4BuB,CAAC,YAAD,CAAe,UAAf,CAA2B,QAAS,CAACC,CAAD,CAAaC,CAAb,CAAuB,CAAA,IACxEC,EAAU,EAD8D,CAExEC,EAAc,EAF0D,CAGxEC,CAHwE,CAIxEC,EAAU,CAAA,CAJ8D,CAKxEC,EAAOV,CAAAU,KALiE,CAMxEC,EAAcX,CAAAW,YAGlBN,EAAAO,UAAA,CAAmB,QAAQ,EAAG,CAC5B,IAAIC,EAAiBR,CAAAC,QAAA,EACjBE,EAAJ,EAA0BK,CAA1B,GACEL,CAGA,CAHqBK,CAGrB,CAFAH,CAAA,CAAKG,CAAL,CAAqBN,CAArB,CAEA,CADAG,CAAA,CAAKG,CAAL,CAAqBP,CAArB,CACA,CAAIG,CAAJ,EAAaL,CAAAU,OAAA,EAJf,CAF4B,CAA9B,CAAA,EAUAL,EAAA,CAAU,CAAA,CAKVL,EAAAW,OAAA,CASAC,QAAa,EAAG,CAAA,IACVC,CADU,CAEVC,CAFU,CAIVC,CAGJ,KAAKF,CAAL,GAAaV,EAAb,CACMI,CAAA,CAAYL,CAAA,CAAQW,CAAR,CAAZ,CAAJ,EACEZ,CAAAC,QAAA,CAAiBW,CAAjB,CAAuBhB,CAAvB,CAKJ,KAAIgB,CAAJ,GAAYX,EAAZ,CAEE,CADAY,CACK,CADGZ,CAAA,CAAQW,CAAR,CACH,CAAAjB,CAAAoB,SAAA,CAAiBF,CAAjB,CAAL,EAMWA,CANX,GAMqBX,CAAA,CAAYU,CAAZ,CANrB,GAOEZ,CAAAC,QAAA,CAAiBW,CAAjB,CAAuBC,CAAvB,CACA,CAAAC,CAAA,CAAU,CAAA,CARZ,EACMnB,CAAAqB,UAAA,CAAkBd,CAAA,CAAYU,CAAZ,CAAlB,CAAJ,CACEX,CAAA,CAAQW,CAAR,CADF,CACkBV,CAAA,CAAYU,CAAZ,CADlB,CAGE,OAAOX,CAAA,CAAQW,CAAR,CASb,IAAIE,CAAJ,CAIE,IAAKF,CAAL,GAFAK,EAEahB,CAFID,CAAAC,QAAA,EAEJA,CAAAA,CAAb,CACMA,CAAA,CAAQW,CAAR,CAAJ,GAAsBK,CAAA,CAAeL,CAAf,CAAtB,GAEMN,CAAA,CAAYW,CAAA,CAAeL,CAAf,CAAZ,CAAJ,CACE,OAAOX,CAAA,CAAQW,CAAR,CADT,CAGEX,CAAA,CAAQW,CAAR,CAHF,CAGkBK,CAAA,CAAeL,CAAf,CALpB,CAlCU,CAThB,CAEA;MAAOX,EA1BqE,CAA3D,CA5BvB,CAAAH,QAAA,CA4HW,cA5HX,CA4H2B,CAAC,UAAD,CAAa,QAAQ,CAACoB,CAAD,CAAW,CAErD,MAAO,KAYAC,QAAQ,CAACC,CAAD,CAAM,CAEjB,MAAO,CADHP,CACG,CADKK,CAAA,CAASE,CAAT,CACL,EAAQzB,CAAA0B,SAAA,CAAiBR,CAAjB,CAAR,CAAkCA,CAFxB,CAZd,KA4BAS,QAAQ,CAACF,CAAD,CAAMP,CAAN,CAAa,CACxBK,CAAA,CAASE,CAAT,CAAA,CAAgBzB,CAAA4B,OAAA,CAAeV,CAAf,CADQ,CA5BrB,QA0CGW,QAAQ,CAACJ,CAAD,CAAM,CACpB,OAAOF,CAAA,CAASE,CAAT,CADa,CA1CjB,CAF8C,CAAhC,CA5H3B,CApBsC,CAArC,CAAA,CAoME1B,MApMF,CAoMUA,MAAAC,QApMV;", 6 | "sources":["angular-cookies.js"], 7 | "names":["window","angular","undefined","module","factory","$rootScope","$browser","cookies","lastCookies","lastBrowserCookies","runEval","copy","isUndefined","addPollFn","currentCookies","$apply","$watch","push","name","value","updated","isString","isDefined","browserCookies","$cookies","get","key","fromJson","put","toJson","remove"] 8 | } 9 | -------------------------------------------------------------------------------- /Bgate-UI/server/public/js/vendor/angular/angular-csp.css: -------------------------------------------------------------------------------- 1 | /* Include this file in your html if you are using the CSP mode. */ 2 | 3 | @charset "UTF-8"; 4 | 5 | [ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], 6 | .ng-cloak, .x-ng-cloak, 7 | .ng-hide { 8 | display: none !important; 9 | } 10 | 11 | ng\:form { 12 | display: block; 13 | } 14 | 15 | /* The styles below ensure that the CSS transition will ALWAYS 16 | * animate and close. A nasty bug occurs with CSS transitions where 17 | * when the active class isn't set, or if the active class doesn't 18 | * contain any styles to transition to, then, if ngAnimate is used, 19 | * it will appear as if the webpage is broken due to the forever hanging 20 | * animations. The border-spacing (!ie) and zoom (ie) CSS properties are 21 | * used below since they trigger a transition without making the browser 22 | * animate anything and they're both highly underused CSS properties */ 23 | .ng-animate-start { border-spacing:1px 1px; -ms-zoom:1.0001; } 24 | .ng-animate-active { border-spacing:0px 0px; -ms-zoom:1; } 25 | -------------------------------------------------------------------------------- /Bgate-UI/server/public/js/vendor/angular/angular-loader.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | AngularJS v1.2.3 3 | (c) 2010-2014 Google, Inc. http://angularjs.org 4 | License: MIT 5 | */ 6 | (function(){'use strict';function d(a){return function(){var c=arguments[0],b,c="["+(a?a+":":"")+c+"] http://errors.angularjs.org/1.2.3/"+(a?a+"/":"")+c;for(b=1;bwith html"); 15 | }, 2000); -------------------------------------------------------------------------------- /Bgate-UI/test/fixtures/talky.js: -------------------------------------------------------------------------------- 1 | var util = require("util"); 2 | 3 | setInterval(function() { 4 | console.log("This is a console.log"); 5 | console.info("This is a console.info"); 6 | console.error("This is an console.error"); 7 | console.warn("This is an console.warn"); 8 | console.time("This is a console.time"); 9 | console.dir("This is a console.dir"); 10 | console.timeEnd("This is a console.time"); 11 | console.trace(); 12 | 13 | util.debug("This is a util.debug"); 14 | util.log("This is a util.log with html"); 15 | }, 2000); -------------------------------------------------------------------------------- /Bgate-UI/test/integration/hosts.js: -------------------------------------------------------------------------------- 1 | var Protractor = require("protractor"), 2 | Harness = require(__dirname + "/lib/Harness"), 3 | should = require("should"); 4 | 5 | var harness = new Harness(); 6 | 7 | module.exports = { 8 | 9 | "Should tell the user we are connecting": function(test) { 10 | harness.on("ready", function(ptor, pm2web) { 11 | ptor.get(pm2web.getAddress()).then(function() { 12 | ptor.findElement(Protractor.By.tagName("h1")).getText().then(function(text) { 13 | text.should.contain("PM2"); 14 | 15 | test.done(); 16 | }); 17 | /* 18 | ptor.findElement(Protractor.By.repeater("alert in alerts").row(0).column("{{alert.message}}")).getText().then(function(text) { 19 | text.should.contain("onnecting"); 20 | 21 | test.done(); 22 | });*/ 23 | }); 24 | }); 25 | } 26 | }; 27 | -------------------------------------------------------------------------------- /Bgate-UI/test/integration/lib/Harness.js: -------------------------------------------------------------------------------- 1 | var PM2Web = require(__dirname + "/../../../server/app"), 2 | Protractor = require("protractor"), 3 | EventEmitter = require("events").EventEmitter, 4 | util = require("util"), 5 | nodeunit = require("nodeunit"); 6 | 7 | // starts pm2-web, then configures Protractor and emits a "ready" event. 8 | var Harness = function() { 9 | EventEmitter.call(this); 10 | 11 | var pm2web; 12 | pm2web = new PM2Web({www: {port: 0}}); 13 | pm2web.on("start", function() { 14 | var driver = new Protractor.Builder(). 15 | withCapabilities(Protractor.Capabilities.phantomjs()). 16 | build(); 17 | 18 | this.emit("ready", Protractor.wrapDriver(driver), pm2web); 19 | }.bind(this)); 20 | pm2web.start(); 21 | 22 | nodeunit.on("done", function() { 23 | console.info("All tests done, shutting down"); 24 | 25 | pm2web.stop(); 26 | 27 | setTimeout(function() { 28 | // something in pm2-interface does not tear it's connections 29 | // down properly so be more forceful. 30 | process.exit(); 31 | }, 2000); 32 | }); 33 | } 34 | util.inherits(Harness, EventEmitter); 35 | 36 | module.exports = Harness; -------------------------------------------------------------------------------- /Bgate-UI/test/unit/aggregator.js: -------------------------------------------------------------------------------- 1 | var testsuite = require("testsuite"); 2 | 3 | module.exports = testsuite(__dirname); 4 | -------------------------------------------------------------------------------- /Bgate-UI/test/unit/common/HostDataTest.js: -------------------------------------------------------------------------------- 1 | var HostData = require(__dirname + "/../../../common/HostData"), 2 | sinon = require("sinon"), 3 | should = require("should"); 4 | 5 | module.exports = { 6 | setUp: function(done) { 7 | this._config = { 8 | get: sinon.stub() 9 | }; 10 | 11 | this._data = new HostData(this._config); 12 | 13 | done(); 14 | }, 15 | 16 | "Should remove missing processes": function(test) { 17 | this._data.processes.push({ 18 | name: "foo" 19 | }); 20 | this._data.processes.push({ 21 | name: "bar" 22 | }); 23 | 24 | this._data.processes.length.should.equal(2); 25 | 26 | this._data._removeMissingProcesses([{ 27 | name: "foo" 28 | }]); 29 | 30 | this._data.processes.length.should.equal(1); 31 | this._data.processes[0].name.should.equal("foo"); 32 | 33 | test.done(); 34 | }, 35 | 36 | "Should find process by id": function(test) { 37 | this._data.processes.push({ 38 | id: "foo" 39 | }); 40 | this._data.processes.push({ 41 | id: "bar" 42 | }); 43 | 44 | var returned = this._data.findProcessById("bar"); 45 | 46 | returned.id.should.equal("bar"); 47 | 48 | test.done(); 49 | }, 50 | 51 | "Should fail to find process by id": function(test) { 52 | this._data.processes.push({ 53 | id: "foo" 54 | }); 55 | this._data.processes.push({ 56 | id: "bar" 57 | }); 58 | 59 | var returned = this._data.findProcessById("baz"); 60 | 61 | test.ok(!returned); 62 | 63 | test.done(); 64 | } 65 | }; 66 | -------------------------------------------------------------------------------- /Bgate-UI/test/unit/ui/components/ConfigTest.js: -------------------------------------------------------------------------------- 1 | var Config = require(__dirname + "/../../../../ui/components/Config"), 2 | sinon = require("sinon"), 3 | should = require("should"); 4 | 5 | module.exports = { 6 | setUp: function(done) { 7 | this._webSocketResponder = { 8 | once: sinon.stub() 9 | }; 10 | 11 | this._config = new Config(this._webSocketResponder); 12 | 13 | done(); 14 | }, 15 | 16 | "Should return null before config has loaded": function(test) { 17 | var result = this._config.get("foo"); 18 | 19 | test.equal(result, null); 20 | 21 | test.done(); 22 | }, 23 | 24 | "Should survive being asked for null": function(test) { 25 | var callback = this._webSocketResponder.once.getCall(0).args[1]; 26 | callback({}); 27 | 28 | var result = this._config.get(); 29 | 30 | test.equal(result, null); 31 | 32 | test.done(); 33 | }, 34 | 35 | "Should return config key": function(test) { 36 | var callback = this._webSocketResponder.once.getCall(0).args[1]; 37 | callback({foo: "bar"}); 38 | 39 | var result = this._config.get("foo"); 40 | 41 | result.should.equal("bar"); 42 | 43 | test.done(); 44 | }, 45 | 46 | "Should return nested config key": function(test) { 47 | var callback = this._webSocketResponder.once.getCall(0).args[1]; 48 | callback({foo: {bar: "baz"}}); 49 | 50 | var result = this._config.get("foo:bar"); 51 | 52 | result.should.equal("baz"); 53 | 54 | test.done(); 55 | }, 56 | 57 | "Should survive invalid nested config key": function(test) { 58 | var callback = this._webSocketResponder.once.getCall(0).args[1]; 59 | callback({foo: {bar: "baz"}}); 60 | 61 | var result = this._config.get("foo:baz"); 62 | 63 | test.equal(result, null); 64 | 65 | test.done(); 66 | } 67 | }; 68 | -------------------------------------------------------------------------------- /Bgate-UI/test/unit/ui/controllers/footerTest.js: -------------------------------------------------------------------------------- 1 | var footer = require(__dirname + "/../../../../ui/controllers/footer"), 2 | should = require("should"); 3 | 4 | module.exports = { 5 | setUp: function(done) { 6 | this._controller = footer[footer.length - 1]; 7 | 8 | done(); 9 | }, 10 | 11 | "Should add version to scope": function(test) { 12 | var scope = {}; 13 | var window = { 14 | settings: { 15 | version: 10 16 | } 17 | }; 18 | 19 | this._controller(window, scope); 20 | 21 | scope.version.should.equal(window.settings.version); 22 | 23 | test.done(); 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /Bgate-UI/test/unit/ui/filters/ansiToHtmlTest.js: -------------------------------------------------------------------------------- 1 | var ansiToHtml = require(__dirname + "/../../../../ui/filters/ansiToHtml"), 2 | sinon = require("sinon"), 3 | should = require("should"); 4 | 5 | module.exports = { 6 | setUp: function(done) { 7 | this._ansiToHtml = ansiToHtml[ansiToHtml.length -1]({ 8 | trustAsHtml: function(text) { 9 | return text; 10 | } 11 | }); 12 | 13 | done(); 14 | }, 15 | 16 | "Should not allow HTML from logs through": function( test ) { 17 | this._ansiToHtml("

hello

").should.not.containEql("

hello

"); 18 | 19 | test.done(); 20 | }, 21 | 22 | "Should convert colours": function( test ) { 23 | this._ansiToHtml("info").should.equal("info"); 24 | 25 | test.done(); 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /Bgate-UI/test/unit/ui/filters/decimalPlacesTest.js: -------------------------------------------------------------------------------- 1 | var decimalPlaces = require(__dirname + "/../../../../ui/filters/decimalPlaces"), 2 | sinon = require("sinon"), 3 | should = require("should"); 4 | 5 | module.exports = { 6 | "Should format to two decimal places": function( test ) { 7 | decimalPlaces()(1.123, 2).length.should.equal(4); 8 | 9 | test.done(); 10 | }, 11 | 12 | "Should pad to two decimal places": function( test ) { 13 | decimalPlaces()(1, 2).length.should.equal(4); 14 | 15 | test.done(); 16 | }, 17 | 18 | "Should survive bad input": function( test ) { 19 | decimalPlaces()().should.equal(0); 20 | decimalPlaces()(undefined).should.equal(0); 21 | 22 | test.done(); 23 | } 24 | }; 25 | -------------------------------------------------------------------------------- /Bgate-UI/test/unit/ui/filters/humaniseTest.js: -------------------------------------------------------------------------------- 1 | var humanise = require(__dirname + "/../../../../ui/filters/humanise"), 2 | sinon = require("sinon"), 3 | should = require("should"); 4 | 5 | module.exports = { 6 | "Should humanise date": function( test ) { 7 | humanise()(new Date()).should.be.a.string; 8 | 9 | test.done(); 10 | } 11 | }; 12 | -------------------------------------------------------------------------------- /Bgate-UI/test/unit/ui/filters/memoryTest.js: -------------------------------------------------------------------------------- 1 | var memory = require(__dirname + "/../../../../ui/filters/memory"), 2 | sinon = require("sinon"), 3 | should = require("should"); 4 | 5 | module.exports = { 6 | "Should format bytes": function( test ) { 7 | memory()(10).should.equal("10 B"); 8 | 9 | test.done(); 10 | }, 11 | 12 | "Should format kilobytes": function( test ) { 13 | memory()(Math.pow(2, 10)).should.equal("1.00 KB"); 14 | 15 | test.done(); 16 | }, 17 | 18 | "Should format megabytes": function( test ) { 19 | memory()(Math.pow(2, 20)).should.equal("1.00 MB"); 20 | 21 | test.done(); 22 | }, 23 | 24 | "Should format gigabytes": function( test ) { 25 | memory()(Math.pow(2, 30)).should.equal("1.00 GB"); 26 | 27 | test.done(); 28 | }, 29 | 30 | "Should format terabytes": function( test ) { 31 | memory()(Math.pow(2, 40)).should.equal("1.00 TB"); 32 | 33 | test.done(); 34 | }, 35 | 36 | "Should format petabytes": function( test ) { 37 | memory()(Math.pow(2, 50)).should.equal("1.00 PB"); 38 | 39 | test.done(); 40 | }, 41 | 42 | "Should format exabytes": function( test ) { 43 | memory()(Math.pow(2, 60)).should.equal("1.00 EB"); 44 | 45 | test.done(); 46 | }, 47 | 48 | "Should survive bad input": function( test ) { 49 | memory()().should.equal("0 B"); 50 | memory()(undefined).should.equal("0 B"); 51 | 52 | test.done(); 53 | } 54 | }; 55 | -------------------------------------------------------------------------------- /Bgate-UI/ui/components/Config.js: -------------------------------------------------------------------------------- 1 | 2 | var Config = function(webSocketResponder) { 3 | webSocketResponder.once("config", function(data) { 4 | this._config = data 5 | }.bind(this)); 6 | }; 7 | 8 | Config.prototype.get = function(key) { 9 | if(!this._config || !key) { 10 | return null; 11 | } 12 | 13 | var value = this._config; 14 | 15 | key.split(":").forEach(function(property) { 16 | if(typeof(value[property]) != "undefined") { 17 | value = value[property]; 18 | } else { 19 | value = null; 20 | } 21 | }); 22 | 23 | return value; 24 | } 25 | 26 | module.exports = Config; 27 | -------------------------------------------------------------------------------- /Bgate-UI/ui/controllers/connection.js: -------------------------------------------------------------------------------- 1 | 2 | module.exports = ["$window", "$scope", "$location", "webSocketResponder", "hostList", function($window, $scope, $location, webSocketResponder, hostList) { 3 | if(!$window["WebSocket"]) { 4 | $scope.alerts = [{ 5 | type: "error", 6 | message: "Your browser does not support web sockets, please consider upgrading." 7 | }]; 8 | 9 | return; 10 | } 11 | 12 | webSocketResponder.on("connecting", function() { 13 | $scope.$apply(function() { 14 | $scope.alerts = [{ 15 | type: "info", 16 | message: "Connecting to " + webSocketResponder.url 17 | }]; 18 | }); 19 | }); 20 | webSocketResponder.on("open", function() { 21 | $scope.$apply(function() { 22 | $scope.alerts = [{ 23 | type: "success", 24 | message: "Waiting for hosts..." 25 | }]; 26 | }); 27 | }); 28 | webSocketResponder.on("closed", function() { 29 | hostList.empty(); 30 | 31 | $scope.$apply(function() { 32 | /*$scope.alerts = [{ 33 | type: "error", 34 | message: "Socket dropped connection" 35 | }];*/ 36 | 37 | $location.path("/"); 38 | }); 39 | }); 40 | webSocketResponder.on("error", function(event) { 41 | var message = ""; 42 | 43 | if(0 == event.target.readyState) { 44 | message = " - socket closed, attempting to reconnect"; 45 | } else if(2 == event.target.readyState) { 46 | message = " - socket closing"; 47 | } else if(3 == event.target.readyState) { 48 | message = " - socket closed"; 49 | } 50 | 51 | $scope.$apply(function() { 52 | $scope.alerts = [{ 53 | type: "error", 54 | message: "Socket error" + message 55 | }]; 56 | }); 57 | }); 58 | 59 | hostList.once("update", function(host) { 60 | $location.path("/hosts/" + host); 61 | }); 62 | }]; 63 | -------------------------------------------------------------------------------- /Bgate-UI/ui/controllers/footer.js: -------------------------------------------------------------------------------- 1 | 2 | module.exports = ["$window", "$scope", function($window, $scope) { 3 | $scope.version = $window.settings.version; 4 | }]; 5 | -------------------------------------------------------------------------------- /Bgate-UI/ui/controllers/hostList.js: -------------------------------------------------------------------------------- 1 | 2 | module.exports = ["$scope", "$routeParams", "$location", "hostList", function($scope, $routeParams, $location, hostList) { 3 | $scope.tabs = []; 4 | 5 | var updateScope = function() { 6 | $scope.tabs.length = 0; 7 | 8 | hostList.hosts().forEach(function(hostName) { 9 | $scope.tabs.push({ 10 | title: hostName, 11 | selected: $routeParams.host == hostName 12 | }) 13 | }); 14 | 15 | $scope.changeHost = function(hostName) { 16 | if(hostName == $routeParams.host) { 17 | return; 18 | } 19 | 20 | $scope.tabs.forEach(function(tab) { 21 | tab.selected = $routeParams.host == tab.hostName; 22 | }); 23 | 24 | $location.path("/hosts/" + hostName); 25 | } 26 | }; 27 | updateScope(); 28 | 29 | // redraw tabs when new host is found 30 | hostList.on("newHost", function() { 31 | updateScope(); 32 | }); 33 | }]; 34 | -------------------------------------------------------------------------------- /Bgate-UI/ui/controllers/processList.js: -------------------------------------------------------------------------------- 1 | 2 | module.exports = ["$scope", "$routeParams", "$location", "$window", "hostList", "webSocketResponder", function($scope, $routeParams, $location, $window, hostList, webSocketResponder) { 3 | $scope.showDetails = {}; 4 | 5 | var updateScope = function() { 6 | var hostData = hostList.find($routeParams.host); 7 | 8 | if(!hostData) { 9 | console.warn("Could not load host data for", $routeParams.host); 10 | 11 | return $location.path("/"); 12 | } 13 | 14 | $scope.hostData = hostData; 15 | $scope.processes = hostData.processes; 16 | $scope.debugEnabled = hostData.inspector ? true : false; 17 | 18 | $scope.toggleDetails = function(pm_id) { 19 | $scope.showDetails[pm_id] = !$scope.showDetails[pm_id]; 20 | }; 21 | 22 | $scope.start = function(pm_id, $event) { 23 | $event.stopPropagation(); 24 | 25 | webSocketResponder.startProcess(hostData.name, pm_id); 26 | }; 27 | $scope.stop = function(pm_id, $event) { 28 | $event.stopPropagation(); 29 | 30 | webSocketResponder.stopProcess(hostData.name, pm_id); 31 | }; 32 | $scope.restart = function(pm_id, $event) { 33 | $event.stopPropagation(); 34 | 35 | webSocketResponder.restartProcess(hostData.name, pm_id); 36 | }; 37 | $scope.reload = function(process, $event) { 38 | $event.stopPropagation(); 39 | 40 | process.reloading = true; 41 | 42 | webSocketResponder.reloadProcess(hostData.name, process.id); 43 | }; 44 | $scope.debug = function(process, $event) { 45 | $event.stopPropagation(); 46 | 47 | webSocketResponder.debugProcess(hostData.name, process.id); 48 | 49 | $window.open("http://" + hostData.name + ":" + hostData.inspector + "/debug?port=" + process.debugPort, hostData.name + "-" + process.id, "location=no,menubar=no,status=no,toolbar=no"); 50 | }; 51 | $scope.clearLogs = function(process) { 52 | process.logs.length = 0; 53 | } 54 | }; 55 | updateScope(); 56 | 57 | hostList.on("update", function(hostName) { 58 | // only update scope if the update was for our host 59 | if(hostName == $routeParams.host) { 60 | updateScope(); 61 | } 62 | }); 63 | }]; 64 | -------------------------------------------------------------------------------- /Bgate-UI/ui/controllers/system.js: -------------------------------------------------------------------------------- 1 | 2 | module.exports = ["$scope", "$routeParams", "$location", "$window", "config", "hostList", function($scope, $routeParams, $location, $window, config, hostList) { 3 | var updateScope = function() { 4 | var hostData = hostList.find($routeParams.host); 5 | 6 | if(!hostData) { 7 | return $location.path("/"); 8 | } 9 | 10 | $scope.hostData = hostData; 11 | }; 12 | updateScope(); 13 | 14 | hostList.on("update", function(hostName) { 15 | // only update scope if the update was for our host 16 | if(hostName == $routeParams.host) { 17 | updateScope(); 18 | } 19 | }); 20 | 21 | $scope.pm2WebVersion = $window.settings.version; 22 | $scope.pm2VersionRequired = config.get("requiredPm2Version"); 23 | }]; 24 | -------------------------------------------------------------------------------- /Bgate-UI/ui/directives/scrollGlue.js: -------------------------------------------------------------------------------- 1 | function fakeNgModel(initValue){ 2 | return { 3 | $setViewValue: function(value){ 4 | this.$viewValue = value; 5 | }, 6 | $viewValue: initValue 7 | }; 8 | }; 9 | 10 | module.exports = [function() { 11 | return { 12 | priority: 1, 13 | require: ['?ngModel'], 14 | restrict: 'A', 15 | link: function(scope, $el, attrs, ctrls){ 16 | var el = $el[0], 17 | ngModel = ctrls[0] || fakeNgModel(true); 18 | 19 | function scrollToBottom(){ 20 | el.scrollTop = el.scrollHeight; 21 | } 22 | 23 | function shouldActivateAutoScroll(){ 24 | // + 1 catches off by one errors in chrome 25 | return el.scrollTop + el.clientHeight + 1 >= el.scrollHeight; 26 | } 27 | 28 | scope.$watch(function(){ 29 | if(ngModel.$viewValue){ 30 | scrollToBottom(); 31 | } 32 | }); 33 | 34 | $el.bind('scroll', function(){ 35 | scope.$apply(ngModel.$setViewValue.bind(ngModel, shouldActivateAutoScroll())); 36 | }); 37 | } 38 | }; 39 | }]; 40 | -------------------------------------------------------------------------------- /Bgate-UI/ui/filters/ansiToHtml.js: -------------------------------------------------------------------------------- 1 | var ansiHTML = require("ansi-html"), 2 | Entities = require("html-entities").XmlEntities; 3 | 4 | var entities = new Entities(); 5 | 6 | module.exports = ["$sce", function($sce) { 7 | 8 | // don't force background color 9 | ansiHTML.tags.open[0] = ansiHTML.tags.open[0].replace("color:#000;", ""); 10 | 11 | return function(text) { 12 | var encoded = entities.encode(text); 13 | 14 | return $sce.trustAsHtml(ansiHTML(encoded)); 15 | } 16 | }]; 17 | -------------------------------------------------------------------------------- /Bgate-UI/ui/filters/decimalPlaces.js: -------------------------------------------------------------------------------- 1 | 2 | module.exports = function() { 3 | return function(number, decimalPlaces) { 4 | if(!number && number !== 0) { 5 | return 0; 6 | } 7 | 8 | return number.toFixed(decimalPlaces); 9 | } 10 | }; 11 | -------------------------------------------------------------------------------- /Bgate-UI/ui/filters/humanise.js: -------------------------------------------------------------------------------- 1 | var Moment = require("moment"); 2 | 3 | module.exports = function() { 4 | return function(date) { 5 | return Moment.duration(date, "seconds").humanize(); 6 | } 7 | }; 8 | -------------------------------------------------------------------------------- /Bgate-UI/ui/filters/memory.js: -------------------------------------------------------------------------------- 1 | 2 | module.exports = function() { 3 | var sizes = ["B", "KB", "MB", "GB", "TB", "PB", "EB"]; 4 | 5 | return function(bytes) { 6 | if(!bytes && bytes !== 0) { 7 | return "0 B"; 8 | } 9 | 10 | for(var i = sizes.length; i > 0; i--) { 11 | var step = Math.pow(1024, i); 12 | 13 | if (bytes >= step) { 14 | return (bytes / step).toFixed(2) + " " + sizes[i]; 15 | } 16 | } 17 | 18 | return bytes + " B"; 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /Bgate-UI/ui/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var WebSocketResponder = require("./components/WebSocketResponder"), 4 | HostList = require("./components/UIHostList"), 5 | Config = require("./components/Config"); 6 | 7 | var pm2Web = angular.module("pm2-web", [ 8 | "ngRoute", 9 | "ngSanitize", 10 | "ui.bootstrap", 11 | "highcharts-ng" 12 | ]); 13 | 14 | pm2Web.config(require("./routes")); 15 | pm2Web.factory("hostList", ["config", "webSocketResponder", function(config, webSocketResponder) { 16 | return new HostList(config, webSocketResponder); 17 | }]); 18 | pm2Web.factory("webSocketResponder", ["$window", "$rootScope", function($window, $rootScope) { 19 | return new WebSocketResponder($window.location, $rootScope); 20 | }]); 21 | pm2Web.factory("config", ["webSocketResponder", function(webSocketResponder) { 22 | return new Config(webSocketResponder); 23 | }]); 24 | 25 | // directives 26 | pm2Web.directive("resourceusage", require("./directives/resourceUsage")); 27 | pm2Web.directive("scrollglue", require("./directives/scrollGlue")); 28 | 29 | // filters 30 | pm2Web.filter("decimalPlaces", require("./filters/decimalPlaces")); 31 | pm2Web.filter("humanise", require("./filters/humanise")); 32 | pm2Web.filter("memory", require("./filters/memory")); 33 | pm2Web.filter("ansiToHtml", require("./filters/ansiToHtml")); 34 | 35 | // controllers 36 | pm2Web.controller("ConnectionController", require("./controllers/connection")); 37 | pm2Web.controller("SystemController", require("./controllers/system")); 38 | pm2Web.controller("ProcessListController", require("./controllers/processList")); 39 | pm2Web.controller("HostListController", require("./controllers/hostList")); 40 | pm2Web.controller("FooterController", require("./controllers/footer")); 41 | -------------------------------------------------------------------------------- /Bgate-UI/ui/routes.js: -------------------------------------------------------------------------------- 1 | 2 | module.exports = ["$routeProvider", 3 | function($routeProvider) { 4 | $routeProvider. 5 | when("/hosts/:host", { 6 | templateUrl: "/js/partials/host.html" 7 | }). 8 | otherwise({ 9 | templateUrl: "/js/partials/connecting.html", 10 | controller: "ConnectionController" 11 | }); 12 | } 13 | ]; 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RTB Server 2 | 3 | * Version: 0.0.1 4 | * Nodejs & NPM 5 | * Author: Van-Duyet Le (@duyet) 6 | * Copyright (c) 2015 7 | 8 | # Real-time Bidding 9 | 10 | *Real-time bidding (RTB)* is a means by which advertising inventory is bought and sold on a per-impression basis, via programmatic instantaneous auction, similar to financial markets. With real-time bidding, advertising buyers bid on an impression and, if the bid is won, the buyer’s ad is instantly displayed on the publisher’s site. Real-time bidding lets advertisers manage and optimize ads from multiple ad-networks by granting the user access to a multitude of different networks, allowing them to create and launch advertising campaigns, prioritize networks and allocate percentages of unsold inventory, known as backfill. 11 | 12 | # Installation 13 | 14 | * Require: Ubuntu 14.04 (RAM > 12GB) 15 | * Nodejs, NPM, PM2 16 | 17 | # Bidding Logs Server 18 | ![](http://i.imgur.com/jPVRbPb.png) 19 | 20 | # Setup environment varaibles and cronjob 21 | 22 | Run `./bgate_env.sh` to settup bgate ENV. 23 | Run `crontab -e` to setup crontab editor, append: 24 | 25 | BGATE_HOME=/home/ubuntu/bgate 26 | */1 * * * * $BGATE_HOME/cronjob/ubuntu/minutely.sh # every minute 27 | */15 * * * * $BGATE_HOME/cronjob/ubuntu/minutely-15.sh # every 10 minute 28 | 1 * * * * $BGATE_HOME/cronjob/ubuntu/hourly.sh # every hour 29 | 55 23 * * * $BGATE_HOME/cronjob/ubuntu/daily-endday.sh # 23h55 30 | 0 1 * * * $BGATE_HOME/cronjob/ubuntu/daily-startday.sh # 1h00 31 | 0 1 * * 7 $BGATE_HOME/cronjob/ubuntu/weekly.sh # 1h00 every sunday 32 | 55 23 28 * * $BGATE_HOME/cronjob/ubuntu/monthly.sh # every month (28/x/yyyy 23h55) 33 | 34 | -------------------------------------------------------------------------------- /TODO.txt: -------------------------------------------------------------------------------- 1 | Filter as modules. 2 | Bannker, Budget, ... sync from MySQL DB -------------------------------------------------------------------------------- /bgate_env.sh: -------------------------------------------------------------------------------- 1 | export BGATE_HOME=/home/ubuntu/bgate_server_nodejs -------------------------------------------------------------------------------- /config/bgate_var.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | requestCount: 0, 5 | requestId: [] 6 | } -------------------------------------------------------------------------------- /config/config.js: -------------------------------------------------------------------------------- 1 | 'use stricts'; 2 | 3 | // exports.mongo = require('./mongodb.js'); 4 | exports.global = require('./global.js'); 5 | 6 | var config = { 7 | host : 'sv5.lvduit.com', 8 | user : 'root', 9 | password : '', 10 | database : 'bgate_demo', 11 | charset : 'utf8' 12 | }; 13 | 14 | module.exports = { 15 | domain: 'http://ptnhttt.uit.edu.vn', 16 | port: process.env.PORT || 8899, 17 | 18 | db: config, 19 | 20 | debug: true, 21 | 22 | sessionSecret: 'LvDuit', 23 | sessionCollection: 'sessions', 24 | tmpDir: '/tmp', 25 | logDir: '/logs', 26 | 27 | trigger_token: '73a90acaae2b1ccc0e969709665bc62f', 28 | trigger_key: 'lvduit', 29 | 30 | routes : { 31 | // Manual for API REST 32 | man: '/man', 33 | 34 | bids: '/bids', 35 | rubicon_bids: '/rubicon_bids', 36 | 37 | imp_tracker: '/imp_tracker', 38 | click_tracker: '/click_tracker', 39 | banner_render: '/banner_render', 40 | banner_preview: '/banner_preview', 41 | banner_generate_preview_link: '/banner_generate_preview_link', 42 | ping: '/ping', 43 | bidrequest: '/bidrequest', 44 | win: '/win_notice', 45 | 46 | // Manager 47 | manager_agent: '/manager/agent', 48 | manager_banner: '/manager/banner', 49 | manager_publisher: '/manager/publisher', 50 | 51 | // Trigger refresh 52 | trigger_reset_agent: '/trigger/refresh/agent', 53 | trigger_reset_publisher: '/trigger/refresh/publisher', 54 | trigger_reset_all: '/trigger/refresh/all', 55 | 56 | // Sync 57 | sync_counter: '/sync/counter', 58 | sync_dailytracker: '/sync/dailytracker', 59 | sync_internaltransaction: '/sync/internaltransaction' 60 | }, 61 | 62 | bgate_ad_icon: '//3.bp.blogspot.com/-7aQF3mBOWPU/VY67czg2QmI/AAAAAAAACkk/FCBfavh1iI0/s1600/adxlogo-2.png', 63 | bgate_ad_icon_hover: '//3.bp.blogspot.com/-r87fGsSXmWA/VYfab3YV-0I/AAAAAAAACjs/hn-ylyS1Kzk/s1600/adxlogo-2-hover.png', 64 | bgate_ad_link: 'http://ads.bda.com.vn', 65 | 66 | // Bid type 67 | bid_type: { 68 | CPM: 1, 69 | CPC: 2 70 | }, 71 | 72 | // CPM to CPC rate 73 | cpm_to_cpc_rate: (10 / 1000), 74 | 75 | // Min balance to disable agent 76 | agentMinBalanceToDisable: 0.01, 77 | } 78 | 79 | -------------------------------------------------------------------------------- /config/db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var mysql = require('mysql'); 4 | var Promise = require('bluebird'); 5 | 6 | var config = require('./config').db; 7 | 8 | var knex = require('knex')({ 9 | client: 'mysql', 10 | connection: config 11 | }); 12 | 13 | console.info("INFO: ["+ new Date() +"] Connect to MySQL Server."); 14 | var bookshelf = require('bookshelf')(knex); 15 | 16 | module.exports.config = config; 17 | module.exports = bookshelf; -------------------------------------------------------------------------------- /config/global.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | port: 8899, 5 | bidsPath: 'bids', 6 | winPath: 'win', 7 | lossPath: 'loss' 8 | }; 9 | -------------------------------------------------------------------------------- /config/mongo.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var mysql = require('mysql'); 4 | var Promise = require('bluebird'); 5 | 6 | var config = { 7 | host : 'sv5.lvduit.com', 8 | user : 'root', 9 | password : '', 10 | database : 'bgate_demo', 11 | charset : 'utf8' 12 | }; 13 | 14 | var knex = require('knex')({ 15 | client: 'mysql', 16 | connection: config 17 | }); 18 | 19 | var bookshelf = require('bookshelf')(knex); 20 | 21 | module.exports.config = config; 22 | module.exports = bookshelf; -------------------------------------------------------------------------------- /config/mongodb.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var mongoConfig = { 4 | host: 'localhost', 5 | dbName: 'BGate-dev' 6 | }; 7 | 8 | var mongoose = require('mongoose'); 9 | var connectString = 'mongodb://'+ mongoConfig.host +'/' + mongoConfig.dbName; 10 | 11 | console.info("INFO: ["+ new Date() +"] Connect to MongoDB Server."); 12 | mongoose.connect(connectString, function(err) { 13 | if (err) { 14 | console.error("ERR: ["+ new Date() +"] Can not connect to MongoDB ("+ connectString +")"); 15 | } 16 | }); 17 | 18 | // =================================================== 19 | // DEFINE MONGO COLLECTION 20 | // =================================================== 21 | 22 | var ImpLog = mongoose.model('ImpLog', { impId: String, PublisherAdZoneID: Number, AdCampaignBannerID: Number, UserIP: String, Country: String, Price: Number, NetPrice: Number, created: Date }); 23 | var ClickLog = mongoose.model('ClickLog', { impId: String, PublisherAdZoneID: Number, AdCampaignBannerID: Number, TargetURL: String, UserIP: String, Country: String, Price: Number, NetPrice: Number, created: Date }); 24 | var BiddingMapLog = mongoose.model('BidddingMapLog', {impId: String, AdzoneMapBannerId: String, PublisherAdZoneID: Number, AdCampaignBannerID: Number, Price: Number, status: String, created: Date}) 25 | var AdvBanker = mongoose.model('AdvBanker', { UserID: Number, AdCampaignBannerID: Number, AdzoneMapBannerId: String, Price: Number, created: Date }); 26 | 27 | // =================================================== 28 | 29 | module.exports = { 30 | ImpLog: ImpLog, 31 | ClickLog: ClickLog, 32 | BiddingMapLog: BiddingMapLog, 33 | AdvBanker: AdvBanker 34 | }; -------------------------------------------------------------------------------- /cronjob.js: -------------------------------------------------------------------------------- 1 | var sys = require('sys') 2 | var exec = require('child_process').exec; 3 | var fs = require('fs'); 4 | 5 | var rootPath = __dirname; 6 | var logPath = __dirname + '/logs/cronjob.log'; 7 | 8 | console.log("Started cronjob server."); 9 | function puts(error, stdout, stderr) { 10 | // console.log('stdout: ' + stdout); 11 | console.log('stderr: ' + stderr); 12 | if (error !== null) console.log('exec error: ' + error); 13 | } 14 | 15 | var min = 1000 * 60; 16 | var hour = 1000 * 60 * 60; 17 | 18 | var syncBannerEvery = 5 * min; // 2 min 19 | var syncBanner = setInterval(function() { 20 | run(rootPath + "/cronjob/sync-banner-counter.js"); 21 | }, syncBannerEvery); 22 | 23 | var bannerDailyTrackerEvery = 5 * min; // 24 * hour; // 24 hour 24 | var bannerDailyTracker = setInterval(function() { 25 | run(rootPath + "/cronjob/banner-daily-tracker.js"); 26 | }, bannerDailyTrackerEvery); 27 | 28 | var adzoneDailyTrackerEvery = 5 * min; // 24 * hour; // 24 hour 29 | var adzoneDailyTracker = setInterval(function() { 30 | run(rootPath + "/cronjob/adzone-daily-tracker.js"); 31 | }, adzoneDailyTrackerEvery); 32 | 33 | var internalTransactionEvery = 1 * 24 * hour; // every days 34 | var internalTransaction = setInterval(function() { 35 | run(rootPath + "/cronjob/internal-transaction-daily.js"); 36 | }, internalTransactionEvery); 37 | 38 | var run = function(path) { 39 | var message = ("["+ new Date() +"]: Cronjob ", path); 40 | fs.appendFile(logPath, message + "\n", function (err) {}); 41 | console.log(message); 42 | 43 | exec("node "+ path, puts); 44 | } -------------------------------------------------------------------------------- /cronjob/re-counter-banner-adzone.js: -------------------------------------------------------------------------------- 1 | // Recounter Adzone and banner counter 2 | // By dedault, Banner (Impressions, Click, Outcome, ...) save base on 3 | // BGate Agent and sync to MySQL Database. Counter is saved to Mongo -------------------------------------------------------------------------------- /cronjob/sync-banner-counter.js: -------------------------------------------------------------------------------- 1 | var http = require('http'); 2 | var url = require('url'); 3 | var config = require('../config/config'); 4 | 5 | console.log("INFO: Start Cronjob sync"); 6 | 7 | var p = url.parse(config.domain); 8 | var options = { 9 | host: p.host, 10 | port: config.port, 11 | path: config.routes.sync_counter + '?s=' + config.trigger_token, 12 | method: 'GET' 13 | }; 14 | 15 | http.request(options, function(res) { 16 | console.log('STATUS: ' + res.statusCode); 17 | console.log('HEADERS: ' + JSON.stringify(res.headers)); 18 | res.setEncoding('utf8'); 19 | res.on('data', function (chunk) { 20 | console.log('BODY: ' + chunk); 21 | }); 22 | }).end(); -------------------------------------------------------------------------------- /cronjob/ubuntu/daily-endday.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | node $BGATE_HOME/cronjob/banner-adzone-daily-tracker.js >> $BGATE_HOME/logs/cronjob/daily-endday.log -------------------------------------------------------------------------------- /cronjob/ubuntu/daily-startday.sh: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duyet/node-rtb-server/1089edd8eeac0d3027d4df2b0b2091fe6721241d/cronjob/ubuntu/daily-startday.sh -------------------------------------------------------------------------------- /cronjob/ubuntu/hourly.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | node $BGATE_HOME/cronjob/sync-banner-counter.js > $BGATE_HOME/logs/cronjob/hourly.log -------------------------------------------------------------------------------- /cronjob/ubuntu/minutely-15.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | node $BGATE_HOME/cronjob/sync-banner-counter.js >> $BGATE_HOME/logs/cronjob/minutely.log -------------------------------------------------------------------------------- /cronjob/ubuntu/minutely.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | node $BGATE_HOME/cronjob/sync-banner-counter.js >> $BGATE_HOME/logs/cronjob/minutely.log -------------------------------------------------------------------------------- /cronjob/ubuntu/monthly.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | node $BGATE_HOME/cronjob/internal-transaction-monthly.js >> $BGATE_HOME/logs/cronjob/monthly.log -------------------------------------------------------------------------------- /cronjob/ubuntu/weekly.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | node $BGATE_HOME/cronjob/internal-transaction-monthly.js >> $BGATE_HOME/logs/cronjob/weekly.log -------------------------------------------------------------------------------- /helper/BannerFilters.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | -------------------------------------------------------------------------------- /helper/syncBannerCounter.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var config = require('../config/config'); 4 | var Model = require('../config/db').Model; 5 | var BGateAgent = require('./BgateAgent'); 6 | 7 | module.exports.sync = function() { 8 | if (!BGateAgent || !BGateAgent.agents) return false; 9 | 10 | for (var i = 0; i < BGateAgent.agents; i++) { 11 | var agent = BGateAgent.agents[i]; 12 | if (!agent.banner) return false; 13 | 14 | for (var j = 0; j < agent.banner; j++) { 15 | var banner = agent.banner[j]; 16 | 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /lib/openrtb/.npmignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # Directory for instrumented libs generated by jscoverage/JSCover 11 | lib-cov 12 | 13 | # Coverage directory used by tools like istanbul 14 | coverage 15 | 16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 17 | .grunt 18 | 19 | # node-waf configuration 20 | .lock-wscript 21 | 22 | # Compiled binary addons (http://nodejs.org/api/addons.html) 23 | build/Release 24 | 25 | # Dependency directory 26 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git 27 | node_modules 28 | -------------------------------------------------------------------------------- /lib/openrtb/.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "0.12" 4 | - "0.11" 5 | - "0.10" 6 | 7 | deploy: 8 | provider: npm 9 | email: "giorgosera@gmail.com" 10 | api_key: "Z2lvcmdvc2VyYTpHSU9pbXAxOTAz" 11 | on: 12 | branch: master 13 | tags: true -------------------------------------------------------------------------------- /lib/openrtb/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Avocarrot 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /lib/openrtb/index.js: -------------------------------------------------------------------------------- 1 | var BuilderFactory = require('./lib/builderFactory'); 2 | 3 | exports = module.exports = new BuilderFactory(); -------------------------------------------------------------------------------- /lib/openrtb/lib/builderFactory.js: -------------------------------------------------------------------------------- 1 | var BidRequestBuilder = require('./openrtb2_3/bidRequest').builder, 2 | BidResponseBuilder = require('./openrtb2_3/bidResponse').builder, 3 | SeatbidBuilder = require('./openrtb2_3/seatbid').builder, 4 | AppBuilder = require('./openrtb2_3/app').builder, 5 | DeviceBuilder = require('./openrtb2_3/device').builder, 6 | ImpBuilder = require('./openrtb2_3/imp').builder, 7 | NativeBuilder = require('./openrtb2_3/native').builder, 8 | BannerBuilder = require('./openrtb2_3/banner').builder, 9 | PublisherBuilder = require('./openrtb2_3/publisher').builder, 10 | UserBuilder = require('./openrtb2_3/user').builder, 11 | BidBuilder = require('./openrtb2_3/bid').builder; 12 | 13 | var BuilderFactory = function(){}; 14 | 15 | BuilderFactory.prototype.getBuilder = function(options){ 16 | options = options || {}; 17 | options.openRtbVersion = options.openRtbVersion || '2.3'; 18 | 19 | if (options.builderType === 'bidRequest') { 20 | return new BidRequestBuilder(); 21 | } else if (options.builderType === 'bidResponse'){ 22 | return new BidResponseBuilder(); 23 | } else if (options.builderType === 'app'){ 24 | return new AppBuilder(); 25 | } else if (options.builderType === 'device'){ 26 | return new DeviceBuilder(); 27 | } else if (options.builderType === 'imp'){ 28 | return new ImpBuilder(); 29 | } else if (options.builderType === 'native'){ 30 | return new NativeBuilder(); 31 | } else if (options.builderType === 'banner'){ 32 | return new BannerBuilder(); 33 | } else if (options.builderType === 'user'){ 34 | return new UserBuilder(); 35 | } else if (options.builderType === 'publisher'){ 36 | return new PublisherBuilder(); 37 | } else if (options.builderType === 'seatbid'){ 38 | return new SeatbidBuilder(); 39 | } else if (options.builderType === 'bid') { 40 | return new BidBuilder(); 41 | } else { 42 | throw new Error('Unsupported builder'); 43 | } 44 | }; 45 | 46 | module.exports = BuilderFactory; -------------------------------------------------------------------------------- /lib/openrtb/lib/openrtb2_3/app.js: -------------------------------------------------------------------------------- 1 | var RtbObject = require('../rtbObject'), 2 | PublisherBuilder = require('./publisher').builder; 3 | 4 | var App = function(storeurl, cat, id, name, publisher){ 5 | this.storeurl = storeurl; 6 | this.cat = cat; 7 | this.id = id; 8 | this.name = name; 9 | this.publisher = publisher; 10 | }; 11 | 12 | App.prototype = Object.create(RtbObject.prototype); 13 | 14 | var AppBuilder = function(){}; 15 | 16 | AppBuilder.prototype.storeurl = function(storeurl){ 17 | this._storeurl = storeurl; 18 | return this; 19 | }; 20 | 21 | AppBuilder.prototype.cat = function(cat){ 22 | this._cat = cat; 23 | return this; 24 | }; 25 | 26 | AppBuilder.prototype.id = function(id){ 27 | this._id = id; 28 | return this; 29 | }; 30 | 31 | AppBuilder.prototype.name = function(name){ 32 | this._name = name; 33 | return this; 34 | }; 35 | 36 | AppBuilder.prototype.publisher = function(publisher){ 37 | var builder = new PublisherBuilder(); 38 | this._publisher = builder 39 | .id(publisher.id) 40 | .name(publisher.name) 41 | .build(); 42 | return this; 43 | }; 44 | 45 | AppBuilder.prototype.build = function() { 46 | return new App(this._storeurl, this._cat, this._id, this._name, this._publisher).removeUndefined(); 47 | }; 48 | 49 | module.exports = { 50 | object: App, 51 | builder: AppBuilder 52 | }; -------------------------------------------------------------------------------- /lib/openrtb/lib/openrtb2_3/bidResponse.js: -------------------------------------------------------------------------------- 1 | var Promise = require('bluebird'), 2 | util = require('util'), 3 | RtbObject = require('../rtbObject'), 4 | SeatbidBuilder = require('./seatbid').builder; 5 | 6 | var BidResponse = function(timestamp, status, bidderName, seatbid){ 7 | this.timestamp = timestamp; 8 | this.status = status; 9 | this.bidderName = bidderName; 10 | this.seatbid = seatbid; 11 | }; 12 | 13 | BidResponse.prototype = Object.create(RtbObject.prototype); 14 | 15 | var BidResponseBuilder = function(){}; 16 | 17 | BidResponseBuilder.prototype.timestamp = function(timestamp){ 18 | this._timestamp = timestamp; 19 | return this; 20 | }; 21 | 22 | BidResponseBuilder.prototype.status = function(status){ 23 | this._status = status; 24 | return this; 25 | }; 26 | 27 | BidResponseBuilder.prototype.bidderName = function(bidderName){ 28 | this._bidderName = bidderName; 29 | return this; 30 | }; 31 | 32 | BidResponseBuilder.prototype.seatbid = function(seatbid){ 33 | this._seatbid = seatbid.map(function(sb){ 34 | var builder = new SeatbidBuilder(); 35 | return builder 36 | .bid(sb.bid) 37 | .build(); 38 | }); 39 | return this; 40 | }; 41 | 42 | BidResponseBuilder.prototype.build = function() { 43 | return new Promise(function (resolve, reject) { 44 | if (!this._status){ 45 | reject(new Error('BidResponse should have a status')); 46 | } else { 47 | Promise.map(this._seatbid, function(sb){ 48 | return sb; 49 | }).bind(this).then(function(_seatbid){ 50 | this._seatbid = _seatbid; 51 | resolve(new BidResponse( 52 | this._timestamp || new Date().toISOString(), 53 | this._status, 54 | this._bidderName, 55 | this._seatbid 56 | ).removeUndefined()); 57 | }).catch(function(err){ 58 | reject(err); 59 | }); 60 | } 61 | }.bind(this)); 62 | }; 63 | 64 | module.exports = { 65 | object: BidResponse, 66 | builder: BidResponseBuilder 67 | }; -------------------------------------------------------------------------------- /lib/openrtb/lib/openrtb2_3/imp.js: -------------------------------------------------------------------------------- 1 | var RtbObject = require('../rtbObject'), 2 | RtbObject = require('../rtbObject'), 3 | NativeBuilder = require('./native').builder, 4 | BannerBuilder = require('./banner').builder; 5 | 6 | var Imp = function(id, bidfloor, tagid, native, banner){ 7 | this.id = id; 8 | this.bidfloor = bidfloor; 9 | this.tagid = tagid; 10 | this.native = native; 11 | this.banner = banner; 12 | }; 13 | 14 | Imp.prototype = Object.create(RtbObject.prototype); 15 | 16 | var ImpBuilder = function(){}; 17 | 18 | ImpBuilder.prototype.id = function(id){ 19 | this._id = id; 20 | return this; 21 | }; 22 | 23 | ImpBuilder.prototype.bidfloor = function(bidfloor){ 24 | this._bidfloor = bidfloor; 25 | return this; 26 | }; 27 | 28 | ImpBuilder.prototype.tagid = function(tagid){ 29 | this._tagid = tagid; 30 | return this; 31 | }; 32 | 33 | ImpBuilder.prototype.native = function(native){ 34 | var builder = new NativeBuilder(); 35 | this._native = builder 36 | .request(native.request) 37 | .ver(native.ver) 38 | .api(native.api) 39 | .battr(native.battr) 40 | .ext(native.ext) 41 | .build(); 42 | return this; 43 | }; 44 | 45 | ImpBuilder.prototype.banner = function(banner){ 46 | var builder = new BannerBuilder(); 47 | this._banner = builder 48 | .w(banner.w) 49 | .h(banner.h) 50 | .wmax(banner.wmax) 51 | .hmax(banner.hmax) 52 | .wmin(banner.wmin) 53 | .hmin(banner.hmin) 54 | .id(banner.id) 55 | .btype(banner.btype) 56 | .battr(banner.battr) 57 | .pos(banner.pos) 58 | .mimes(banner.mimes) 59 | .topframe(banner.topframe) 60 | .expdir(banner.expdir) 61 | .api(banner.api) 62 | .ext(banner.ext) 63 | .build(); 64 | return this; 65 | }; 66 | 67 | ImpBuilder.prototype.build = function() { 68 | return new Imp(this._id, this._bidfloor, this._tagid, this._native, this._banner).removeUndefined(); 69 | }; 70 | 71 | module.exports = { 72 | object: Imp, 73 | builder: ImpBuilder 74 | }; -------------------------------------------------------------------------------- /lib/openrtb/lib/openrtb2_3/native.js: -------------------------------------------------------------------------------- 1 | var RtbObject = require('../rtbObject'); 2 | 3 | var Native = function(request, ver, api, battr, ext){ 4 | this.request = request; 5 | this.ver = ver; 6 | this.api = api; 7 | this.battr = battr; 8 | this.ext = ext; 9 | }; 10 | 11 | Native.prototype = Object.create(RtbObject.prototype); 12 | 13 | var NativeBuilder = function(){}; 14 | 15 | NativeBuilder.prototype.request = function(request){ 16 | this._request = request; 17 | return this; 18 | }; 19 | 20 | NativeBuilder.prototype.ver = function(ver){ 21 | this._ver = ver; 22 | return this; 23 | }; 24 | 25 | NativeBuilder.prototype.api = function(api){ 26 | this._api = api; 27 | return this; 28 | }; 29 | 30 | NativeBuilder.prototype.battr = function(battr){ 31 | this._battr = battr; 32 | return this; 33 | }; 34 | 35 | NativeBuilder.prototype.ext = function(ext){ 36 | this._ext = ext; 37 | return this; 38 | }; 39 | 40 | NativeBuilder.prototype.build = function() { 41 | if (!this._request){ 42 | throw new Error('Native should have request'); 43 | } else { 44 | return new Native(this._request, this._ver, this._api, this._battr, this._ext).removeUndefined(); 45 | } 46 | }; 47 | 48 | module.exports = { 49 | object: Native, 50 | builder: NativeBuilder 51 | }; -------------------------------------------------------------------------------- /lib/openrtb/lib/openrtb2_3/publisher.js: -------------------------------------------------------------------------------- 1 | var RtbObject = require('../rtbObject'); 2 | 3 | var Publisher = function(id, name){ 4 | this.id = id; 5 | this.name = name; 6 | }; 7 | 8 | Publisher.prototype = Object.create(RtbObject.prototype); 9 | 10 | var PublisherBuilder = function(){}; 11 | 12 | PublisherBuilder.prototype.id = function(id){ 13 | this._id = id; 14 | return this; 15 | }; 16 | 17 | PublisherBuilder.prototype.name = function(name){ 18 | this._name = name; 19 | return this; 20 | }; 21 | 22 | PublisherBuilder.prototype.build = function() { 23 | return new Publisher(this._id, this._name).removeUndefined(); 24 | }; 25 | 26 | module.exports = { 27 | object: Publisher, 28 | builder: PublisherBuilder 29 | }; -------------------------------------------------------------------------------- /lib/openrtb/lib/openrtb2_3/seatbid.js: -------------------------------------------------------------------------------- 1 | var Promise = require('bluebird'), 2 | RtbObject = require('../rtbObject'), 3 | BidBuilder = require('./bid').builder; 4 | 5 | var Seatbid = function(seat, bid, group, ext){ 6 | this.seat = seat; 7 | this.bid = bid; 8 | this.group = group; 9 | this.ext = ext; 10 | }; 11 | 12 | Seatbid.prototype = Object.create(RtbObject.prototype); 13 | 14 | var SeatbidBuilder = function(){}; 15 | 16 | SeatbidBuilder.prototype.seat = function(seat){ 17 | this._seat = seat; 18 | return this; 19 | }; 20 | 21 | SeatbidBuilder.prototype.bid = function(bid){ 22 | this._bid = bid.map(function(b){ 23 | var builder = new BidBuilder(); 24 | return builder 25 | .status(b.status) 26 | .nurl(b.nurl) 27 | .adm(b.adm) 28 | .adid(b.adid) 29 | .adomain(b.adomain) 30 | .id(b.id) 31 | .price(b.price) 32 | .cid(b.cid) 33 | .clearPrice(b.clearPrice) 34 | .crid(b.crid) 35 | .iurl(b.iurl) 36 | .impid(b.impid) 37 | .parseAdm(b.parseAdm || function(adm){ return adm; }) 38 | .ext(b.ext) 39 | .build(); 40 | }); 41 | return this; 42 | }; 43 | 44 | SeatbidBuilder.prototype.group = function(group){ 45 | this._group = group; 46 | return this; 47 | }; 48 | 49 | SeatbidBuilder.prototype.ext = function(ext){ 50 | this._ext = ext; 51 | return this; 52 | }; 53 | 54 | SeatbidBuilder.prototype.build = function() { 55 | return new Promise(function (resolve, reject) { 56 | Promise.map(this._bid, function(b){ 57 | return b; 58 | }).bind(this).then(function(_bid){ 59 | this._bid = _bid; 60 | resolve(new Seatbid(this._seat, this._bid, this._group, this._ext).removeUndefined()); 61 | }).catch(function(err){ 62 | reject(err); 63 | }); 64 | }.bind(this)); 65 | }; 66 | 67 | module.exports = { 68 | object: Seatbid, 69 | builder: SeatbidBuilder 70 | }; -------------------------------------------------------------------------------- /lib/openrtb/lib/openrtb2_3/user.js: -------------------------------------------------------------------------------- 1 | var RtbObject = require('../rtbObject'); 2 | 3 | var User = function(gender, id, yob){ 4 | this.gender = gender; 5 | this.id = id; 6 | this.yob = yob; 7 | }; 8 | 9 | User.prototype = Object.create(RtbObject.prototype); 10 | 11 | var UserBuilder = function(){}; 12 | 13 | UserBuilder.prototype.gender = function(gender){ 14 | this._gender = gender; 15 | return this; 16 | }; 17 | 18 | UserBuilder.prototype.id = function(id){ 19 | this._id = id; 20 | return this; 21 | }; 22 | 23 | UserBuilder.prototype.yob = function(yob){ 24 | this._yob = yob; 25 | return this; 26 | }; 27 | 28 | UserBuilder.prototype.build = function() { 29 | return new User(this._gender, this._id, this._yob).removeUndefined(); 30 | }; 31 | 32 | module.exports = { 33 | object: User, 34 | builder: UserBuilder 35 | }; -------------------------------------------------------------------------------- /lib/openrtb/lib/rtbObject.js: -------------------------------------------------------------------------------- 1 | var RtbObject = function(){}; 2 | 3 | RtbObject.prototype.stringify = function(){ 4 | return JSON.stringify(this); 5 | }; 6 | 7 | RtbObject.prototype.removeUndefined = function(){ 8 | for (var prop in this) { 9 | if (this.hasOwnProperty(prop) && typeof this[prop] === 'undefined') { 10 | delete this[prop]; 11 | } 12 | } 13 | return this; 14 | }; 15 | 16 | module.exports = RtbObject; -------------------------------------------------------------------------------- /lib/openrtb/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "openrtb", 3 | "version": "0.0.5", 4 | "description": "A Javascript library which builds and validates OpenRTB objects", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "mocha -R spec" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/Avocarrot/openrtb" 12 | }, 13 | "keywords": [ 14 | "openrtb", 15 | "real", 16 | "time", 17 | "bidding", 18 | "advertising" 19 | ], 20 | "author": { 21 | "name": "The Avocarrot Rockstar Team" 22 | }, 23 | "license": "MIT", 24 | "bugs": { 25 | "url": "https://github.com/Avocarrot/openrtb/issues" 26 | }, 27 | "homepage": "https://github.com/Avocarrot/openrtb", 28 | "dependencies": { 29 | "bluebird": "^3.0.0" 30 | }, 31 | "devDependencies": { 32 | "mocha": "10.4.0", 33 | "moment": "2.30.1", 34 | "should": "13.2.3", 35 | "timekeeper": "2.3.1" 36 | }, 37 | "gitHead": "1dff39612a8e36ba34dc2e0decc7f3e4a5184a06", 38 | "_id": "openrtb@0.0.5", 39 | "_shasum": "debaa21defb5310146029a78c6c19a943e7a740d", 40 | "_from": "openrtb@*", 41 | "_npmVersion": "1.4.28", 42 | "_npmUser": { 43 | "name": "giorgosera", 44 | "email": "giorgosera@gmail.com" 45 | }, 46 | "maintainers": [ 47 | { 48 | "name": "giorgosera", 49 | "email": "giorgosera@gmail.com" 50 | } 51 | ], 52 | "dist": { 53 | "shasum": "debaa21defb5310146029a78c6c19a943e7a740d", 54 | "tarball": "http://registry.npmjs.org/openrtb/-/openrtb-0.0.5.tgz" 55 | }, 56 | "directories": {}, 57 | "_resolved": "http://registry.npmjs.org/openrtb/-/openrtb-0.0.5.tgz" 58 | } 59 | -------------------------------------------------------------------------------- /lib/openrtb/test/mocks/mockResponse.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | seatbid:[ 3 | { 4 | bid: [ 5 | { 6 | adid: 1, 7 | id: '819582c3-96b2-401a-b60d-7ac3c117a513', 8 | impid: 'e317ae49-8cd1-47b0-b022-02a8830182ce', 9 | price: 1.05, 10 | nurl: 'http://trackwin.com/win?pid=784170&data=OuJifVtEK&price=${AUCTION_PRICE}', 11 | adm: '{"native":{"assets":[{"id":0,"title":{"text":"Test Campaign"}},{"id":1,"img":{"url":"http://cdn.exampleimage.com/a/100/100/2639042","w":100,"h":100}},{"id":2,"img":{"url":"http://cdn.exampleimage.com/a/50/50/2639042","w":50,"h":50}},{"id":3,"data":{"value":"This is an amazing offer..."}},{"id":5,"data":{"value":"Install"}}],"link":{"url":"http://trackclick.com/Click?data=soDvIjYdQMm3WBjoORcGaDvJGOzgMvUap7vAw2"},"imptrackers":["http://trackimp.com/Pixel/Impression/?bidPrice=${AUCTION_PRICE}&data=OuJifVtEKZqw3Hw7456F-etFgvhJpYOu0&type=img"]}}', 12 | cid: '9607', 13 | crid: '335224', 14 | iurl: 'http://cdn.testimage.net/1200x627.png', 15 | adomain: ["example.com"], 16 | parseAdm: function(adm) { 17 | return adm; 18 | }, 19 | ext: { 20 | bidderver: "1" 21 | } 22 | } 23 | ] 24 | } 25 | ] 26 | } -------------------------------------------------------------------------------- /lib/openrtb/test/rtbObjectTests.js: -------------------------------------------------------------------------------- 1 | var RtbObject = require('../lib/rtbObject'); 2 | 3 | describe("The RtbObject should", function() { 4 | var rtbObject; 5 | beforeEach(function(){ 6 | rtbObject = new RtbObject(); 7 | }); 8 | 9 | it("convert to JSON string", function() { 10 | rtbObject.prop1 = 'prop1'; 11 | rtbObject.prop2 = { 12 | nestedProp: 'nestedProp' 13 | }; 14 | rtbObject.prop3 = function(){ 15 | return 'prop3'; 16 | }; 17 | var stringified = rtbObject.stringify(); 18 | stringified.should.be.an.instanceOf(String); 19 | stringified.should.equal('{"prop1":"prop1","prop2":{"nestedProp":"nestedProp"}}'); 20 | }); 21 | 22 | it("removes undefined properties", function() { 23 | rtbObject.prop1 = 'prop1'; 24 | rtbObject.prop2 = undefined; 25 | var cleaned = rtbObject.removeUndefined(); 26 | cleaned.should.have.property('prop1', 'prop1'); 27 | cleaned.should.not.have.property('prop2'); 28 | }); 29 | 30 | 31 | }); 32 | -------------------------------------------------------------------------------- /logs/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bidding_server_nodejs", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "snyk-protect": "snyk protect", 9 | "prepublish": "npm run snyk-protect" 10 | }, 11 | "author": "", 12 | "license": "ISC", 13 | "dependencies": { 14 | "bcrypt": "^5.0.0", 15 | "bluebird": "^3.0.0", 16 | "body-parser": "^1.13.1", 17 | "bookshelf": "^1.0.0", 18 | "checkit": "^0.7.0", 19 | "compression": "^1.5.0", 20 | "connect-flash": "^0.1.1", 21 | "connect-multiparty": "^2.0.0", 22 | "consolidate": "^1.0.0", 23 | "cookie-parser": "^1.3.5", 24 | "cookie-session": "^2.0.0", 25 | "cors": "^2.7.1", 26 | "dot": "^1.0.3", 27 | "es6-promise": "^4.0.0", 28 | "express": "^4.12.4", 29 | "express-mysql-session": "^3.0.0", 30 | "express-session": "^1.11.3", 31 | "express-validator": "^7.0.0", 32 | "file-stream-rotator": "1.0.0", 33 | "glob": "^10.0.0", 34 | "helmet": "^7.0.0", 35 | "pug": "^3.0.1", 36 | "jsonschema": "^1.0.1", 37 | "knex": "^3.0.0", 38 | "lodash": "^4.0.0", 39 | "merge": "^2.1.1", 40 | "method-override": "^3.0.0", 41 | "moment": "^2.10.3", 42 | "mongoose": "^8.0.0", 43 | "morgan": "^1.6.0", 44 | "mysql": "^2.7.0", 45 | "openrtb": "3.6.1", 46 | "q": "^1.4.1", 47 | "redis": "^4.0.0", 48 | "string-hash": "^1.1.0", 49 | "uuid": "^10.0.0", 50 | "snyk": "^1.30.1" 51 | }, 52 | "snyk": true 53 | } 54 | -------------------------------------------------------------------------------- /render/adbanner.js: -------------------------------------------------------------------------------- 1 | (function(){function adbanner(it 2 | /**/) { 3 | var out='Bgate by ISLab
';return out; 4 | }var itself=adbanner, _encodeHTML=(function (doNotSkipEncoded) { 5 | var encodeHTMLRules = { "&": "&", "<": "<", ">": ">", '"': """, "'": "'", "/": "/" }, 6 | matchHTML = doNotSkipEncoded ? /[&<>"'\/]/g : /&(?!#?\w+;)|<|>|"|'|\//g; 7 | return function(code) { 8 | return code ? code.toString().replace(matchHTML, function(m) {return encodeHTMLRules[m] || m;}) : ""; 9 | }; 10 | }());if(typeof module!=='undefined' && module.exports) module.exports=itself;else if(typeof define==='function')define(function(){return itself;});else {_page.render=_page.render||{};_page.render['adbanner']=itself;}}()); -------------------------------------------------------------------------------- /render/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * BGate Bidding Server 3 | * 4 | * @version: 1.0.0 5 | * @author: Van-Duyet Le (ISLab) 6 | */ 7 | var path = require('path') 8 | , fs = require('fs'); 9 | 10 | function req(name) { 11 | var module = require("./" + name); 12 | delete exports[name]; 13 | return exports[name] = module; 14 | } 15 | 16 | fs.readdirSync(__dirname).forEach(function(file) { 17 | if ((file === 'index.js') || (file[0] === '_')) { return; } 18 | var ext = path.extname(file); 19 | var stats = fs.statSync(__dirname + '/' + file); 20 | if (stats.isFile() && !(ext in require.extensions)) { return; } 21 | var basename = path.basename(file, '.js'); 22 | exports.__defineGetter__(basename, function(){ return req(basename); }); 23 | }); -------------------------------------------------------------------------------- /sample_db.mwb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duyet/node-rtb-server/1089edd8eeac0d3027d4df2b0b2091fe6721241d/sample_db.mwb -------------------------------------------------------------------------------- /setup_ubuntu_crontab.md: -------------------------------------------------------------------------------- 1 | Run `./bgate_env.sh` to settup bgate ENV. 2 | Run `crontab -e` to setup crontab editor, append: 3 | 4 | ``` 5 | */1 * * * * $BGATE_HOME/cronjob/ubuntu/minutely.sh # every minute 6 | */15 * * * * $BGATE_HOME/cronjob/ubuntu/minutely-15.sh # every 10 minute 7 | * */1 * * * $BGATE_HOME/cronjob/ubuntu/hourly.sh # every hour 8 | 55 23 * * * $BGATE_HOME/cronjob/ubuntu/daily-endday.sh # 23h55 9 | 0 1 * * * $BGATE_HOME/cronjob/ubuntu/daily-startday.sh # 1h00 10 | 0 1 * * 7 $BGATE_HOME/cronjob/ubuntu/weekly.sh # 1h00 every sunday 11 | 55 23 28 * * $BGATE_HOME/cronjob/ubuntu/monthly.sh # every month (28/x/yyyy 23h55) 12 | ``` 13 | -------------------------------------------------------------------------------- /system/bidrequestController.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var moment = require('moment'); 4 | var openrtb = require('../lib/openrtb'); 5 | var builder = openrtb.getBuilder({builderType:'bidRequest'}); 6 | 7 | 8 | exports.generate = function(req, res) { 9 | builder 10 | .timestamp(moment.utc().format()) 11 | .id('1234') 12 | .at(2) 13 | .imp([ 14 | { 15 | "id":"1", 16 | "native":{ 17 | "request": { 18 | "ver": 1, 19 | "layout": 6, 20 | "assets": [ 21 | { "id": 0, "req": 1, "title": { "len": 25 } }, 22 | { "id": 1, "req": 1, "img": { "type": 3, "wmin": 100, "hmin": 100 } }, 23 | { "id": 3, "req": 0, "data": { "type": 2, "len": 90 } } 24 | ] 25 | } 26 | }, 27 | "tagid": "eb09ff2a287598302fd631493949169b0d17f815", 28 | "bidfloor": 1.3 29 | } 30 | ]) 31 | .app({ 32 | "id":"55", 33 | "name":"Test App", 34 | "cat":["IAB3-1"], 35 | "storeurl": "http://www.example.com", 36 | "publisher":{ 37 | "id": "6332" 38 | } 39 | }) 40 | .device({ 41 | "dnt":0, 42 | "ua":"Mozilla/5.0 (Linux; U; Android 4.0.3; ko-kr; LG-L160L Build/IML74K) AppleWebkit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", 43 | "ip":"76.174.49.222", 44 | "connectiontype":2, 45 | "devicetype":1, 46 | "didsha1": "bbc9ff2a287598302fd631693949169b0d17f215", 47 | "carrier": "o2", 48 | "make": "samsung GT-I9300", 49 | "model": "Android", 50 | "language": "en", 51 | "os": "Android", 52 | "osv": "5.1.1", 53 | "geo": { 54 | "country": "UK" 55 | } 56 | }) 57 | .user({ 58 | "id":"55816b39711f9b5acf3b90e313ed29e51665623f", 59 | "yob": 1987, 60 | "gender": "M" 61 | }) 62 | .ext({ 63 | 'extra': '1234' 64 | }) 65 | .build() 66 | .then(function(bidRequest){ 67 | res.send(bidRequest); 68 | }); 69 | }; -------------------------------------------------------------------------------- /system/debugController.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var BGateAgent = require('../helper/BgateAgent.js'); 4 | 5 | exports.main = function(req, res) { 6 | 7 | } 8 | 9 | exports.agent = function(req, res) { 10 | if (BGateAgent.agents) res.json(BGateAgent.agents); 11 | else res.json(); 12 | } 13 | 14 | exports.banner = function(req, res) { 15 | if (!BGateAgent.agents) return res.json([]); 16 | 17 | var listBanner = []; 18 | BGateAgent.agents.forEach(function(agent) { 19 | if (!agent || !agent.banner) return false; 20 | agent.banner.forEach(function(banner) { 21 | listBanner.push(banner); 22 | }); 23 | }); 24 | 25 | return res.json(listBanner); 26 | } 27 | -------------------------------------------------------------------------------- /system/manController.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var config = require('../config/config'); 4 | 5 | exports.index = function(req, res) { 6 | console.log("INFO: Open API Manual"); 7 | if (!req.query.s || req.query.s != config.trigger_key) 8 | return res.status(404).send("Hi, bye!"); 9 | 10 | var api = "BGate API List

"; 11 | for (var i in config.routes) { 12 | api += " " + config.routes[i] + "
\t\n"; 13 | } 14 | 15 | res.send(api); 16 | } -------------------------------------------------------------------------------- /system/managerController.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var config = require('../config/config'); 4 | var BGateAgent = require('../helper/BgateAgent'); 5 | var PublisherAgent = require('../helper/Publisher'); 6 | 7 | exports.agent = function(req, res) { 8 | console.log("REQ: ["+ new Date() +"] Fetch Agent info from REST API"); 9 | if (!req.query || !req.query.s || req.query.s != config.trigger_token || !BGateAgent) { 10 | return res.status(404).send("Not Found"); 11 | } 12 | 13 | var agents = []; 14 | for (var i = 0; i < BGateAgent.agents.length; i++) { 15 | var current = BGateAgent.agents[i]; 16 | //current.banner = current.banner.length; 17 | agents.push(current); 18 | } 19 | 20 | res.json(agents); 21 | }; 22 | 23 | exports.agent_all = function(req, res) { 24 | if (!req.query || !req.query.s || req.query.s != config.trigger_token || !BGateAgent) { 25 | return res.status(404).send("Not Found"); 26 | } 27 | 28 | res.json(BGateAgent.agents); 29 | }; 30 | 31 | exports.banner = function(req, res) { 32 | console.log("REQ: ["+ new Date() +"] Fetch Banner info from REST API"); 33 | if (!req.query || !req.query.s || req.query.s != config.trigger_token || !BGateAgent) { 34 | return res.status(404).send("Not Found"); 35 | } 36 | 37 | var banners = []; 38 | for (var i = 0; i < BGateAgent.agents.length; i++) { 39 | var current = BGateAgent.agents[i]; 40 | for (var j = 0; j < current.banner.length; j++) { 41 | var current_banner = current.banner[j]; 42 | banners.push({ 43 | user_id: current_banner.UserID, 44 | banner_id: current_banner.AdCampaignBannerPreviewID, 45 | banner_name: current_banner.Name, 46 | campain_id: current_banner.AdCampaignPreviewID, 47 | IABSize: current_banner.IABSize, 48 | BidAmount: current_banner.BidAmount, 49 | BidsCounter: current_banner.BidsCounter, 50 | ImpressionsCounter: current_banner.ImpressionsCounter, 51 | AdUrl: current_banner.AdUrl, 52 | }); 53 | } 54 | 55 | } 56 | 57 | res.json(banners); 58 | }; 59 | 60 | exports.publisher = function(req, res) { 61 | console.log("REQ: ["+ new Date() +"] Fetch Agent info from REST API"); 62 | if (!req.query || !req.query.s || req.query.s != config.trigger_token || !PublisherAgent) { 63 | return res.status(404).send("Not Found"); 64 | } 65 | 66 | res.json(PublisherAgent.data); 67 | }; -------------------------------------------------------------------------------- /system/pingController.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.pingme = function(req, res) { 4 | console.info("INFO: ["+ new Date() +"] Ping me"); 5 | res.end("pong"); 6 | }; -------------------------------------------------------------------------------- /templates/adbanner.jst: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | Bgate by ISLab 11 | 12 | 13 | 14 | 15 | 16 | 33 | 34 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 | 47 | 48 | 49 |
50 | 51 | 52 | --------------------------------------------------------------------------------