Commit f6a4415af709ba3295700f510b7729b4e26d8fa7
0 parents
Exists in
master
start smart-rms-calendar
Showing
18 changed files
with
857 additions
and
0 deletions
Show diff stats
1 | +++ a/.eslintrc.js | ||
@@ -0,0 +1,19 @@ | @@ -0,0 +1,19 @@ | ||
1 | +module.exports = { | ||
2 | + "extends": ["standard"], | ||
3 | + "env": { | ||
4 | + "browser": 1 | ||
5 | + }, | ||
6 | + | ||
7 | + "globals": { | ||
8 | + "angular": 1 | ||
9 | + }, | ||
10 | + | ||
11 | + "rules": { | ||
12 | + "quotes": [2, "single"], | ||
13 | + "space-before-function-paren": 0, | ||
14 | + "eqeqeq": 0, | ||
15 | + "strict": 0, | ||
16 | + "indent": 0, | ||
17 | + "eol-last": 0 | ||
18 | + } | ||
19 | +}; | ||
0 | \ No newline at end of file | 20 | \ No newline at end of file |
1 | +++ a/.eslintrc.json | ||
@@ -0,0 +1,23 @@ | @@ -0,0 +1,23 @@ | ||
1 | +{ | ||
2 | + "env": { | ||
3 | + "browser": true, | ||
4 | + "commonjs": true, | ||
5 | + "es6": true, | ||
6 | + "node": true | ||
7 | + }, | ||
8 | + "parserOptions": { | ||
9 | + "ecmaFeatures": { | ||
10 | + "jsx": true | ||
11 | + }, | ||
12 | + "sourceType": "module" | ||
13 | + }, | ||
14 | + "rules": { | ||
15 | + "no-const-assign": "warn", | ||
16 | + "no-this-before-super": "warn", | ||
17 | + "no-undef": "warn", | ||
18 | + "no-unreachable": "warn", | ||
19 | + "no-unused-vars": "warn", | ||
20 | + "constructor-super": "warn", | ||
21 | + "valid-typeof": "warn" | ||
22 | + } | ||
23 | +} | ||
0 | \ No newline at end of file | 24 | \ No newline at end of file |
1 | +++ a/.gitignore | ||
@@ -0,0 +1,227 @@ | @@ -0,0 +1,227 @@ | ||
1 | + | ||
2 | +# Created by https://www.gitignore.io/api/bower,node,osx,windows,jetbrains | ||
3 | + | ||
4 | +### Bower ### | ||
5 | +bower_components | ||
6 | +.bower-cache | ||
7 | +.bower-registry | ||
8 | +.bower-tmp | ||
9 | + | ||
10 | + | ||
11 | +### Node ### | ||
12 | +# Logs | ||
13 | +logs | ||
14 | +*.log | ||
15 | +npm-debug.log* | ||
16 | + | ||
17 | +# Runtime data | ||
18 | +pids | ||
19 | +*.pid | ||
20 | +*.seed | ||
21 | + | ||
22 | +# Directory for instrumented libs generated by jscoverage/JSCover | ||
23 | +lib-cov | ||
24 | + | ||
25 | +# Coverage directory used by tools like istanbul | ||
26 | +coverage | ||
27 | + | ||
28 | +# nyc test coverage | ||
29 | +.nyc_output | ||
30 | + | ||
31 | +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) | ||
32 | +.grunt | ||
33 | + | ||
34 | +# node-waf configuration | ||
35 | +.lock-wscript | ||
36 | + | ||
37 | +# Compiled binary addons (http://nodejs.org/api/addons.html) | ||
38 | +build/Release | ||
39 | + | ||
40 | +# Dependency directories | ||
41 | +node_modules | ||
42 | +jspm_packages | ||
43 | + | ||
44 | +# Optional npm cache directory | ||
45 | +.npm | ||
46 | + | ||
47 | +# Optional REPL history | ||
48 | +.node_repl_history | ||
49 | + | ||
50 | + | ||
51 | +### OSX ### | ||
52 | +*.DS_Store | ||
53 | +.AppleDouble | ||
54 | +.LSOverride | ||
55 | + | ||
56 | +# Icon must end with two \r | ||
57 | +Icon | ||
58 | + | ||
59 | + | ||
60 | +# Thumbnails | ||
61 | +._* | ||
62 | + | ||
63 | +# Files that might appear in the root of a volume | ||
64 | +.DocumentRevisions-V100 | ||
65 | +.fseventsd | ||
66 | +.Spotlight-V100 | ||
67 | +.TemporaryItems | ||
68 | +.Trashes | ||
69 | +.VolumeIcon.icns | ||
70 | +.com.apple.timemachine.donotpresent | ||
71 | + | ||
72 | +# Directories potentially created on remote AFP share | ||
73 | +.AppleDB | ||
74 | +.AppleDesktop | ||
75 | +Network Trash Folder | ||
76 | +Temporary Items | ||
77 | +.apdisk | ||
78 | + | ||
79 | + | ||
80 | +### Windows ### | ||
81 | +# Windows image file caches | ||
82 | +Thumbs.db | ||
83 | +ehthumbs.db | ||
84 | + | ||
85 | +# Folder config file | ||
86 | +Desktop.ini | ||
87 | + | ||
88 | +# Recycle Bin used on file shares | ||
89 | +$RECYCLE.BIN/ | ||
90 | + | ||
91 | +# Windows Installer files | ||
92 | +*.cab | ||
93 | +*.msi | ||
94 | +*.msm | ||
95 | +*.msp | ||
96 | + | ||
97 | +# Windows shortcuts | ||
98 | +*.lnk | ||
99 | + | ||
100 | + | ||
101 | +### JetBrains ### | ||
102 | +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm | ||
103 | +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 | ||
104 | + | ||
105 | +# User-specific stuff: | ||
106 | +.idea/workspace.xml | ||
107 | +.idea/tasks.xml | ||
108 | +.idea/dictionaries | ||
109 | +.idea/vcs.xml | ||
110 | +.idea/jsLibraryMappings.xml | ||
111 | + | ||
112 | +# Sensitive or high-churn files: | ||
113 | +.idea/dataSources.ids | ||
114 | +.idea/dataSources.xml | ||
115 | +.idea/dataSources.local.xml | ||
116 | +.idea/sqlDataSources.xml | ||
117 | +.idea/dynamic.xml | ||
118 | +.idea/uiDesigner.xml | ||
119 | + | ||
120 | +# Gradle: | ||
121 | +.idea/gradle.xml | ||
122 | +.idea/libraries | ||
123 | + | ||
124 | +# Mongo Explorer plugin: | ||
125 | +.idea/mongoSettings.xml | ||
126 | + | ||
127 | +## File-based project format: | ||
128 | +*.iws | ||
129 | + | ||
130 | +## Plugin-specific files: | ||
131 | + | ||
132 | +# IntelliJ | ||
133 | +/out/ | ||
134 | + | ||
135 | +# mpeltonen/sbt-idea plugin | ||
136 | +.idea_modules/ | ||
137 | + | ||
138 | +# JIRA plugin | ||
139 | +atlassian-ide-plugin.xml | ||
140 | + | ||
141 | +# Crashlytics plugin (for Android Studio and IntelliJ) | ||
142 | +com_crashlytics_export_strings.xml | ||
143 | +crashlytics.properties | ||
144 | +crashlytics-build.properties | ||
145 | +fabric.properties | ||
146 | + | ||
147 | +### JetBrains Patch ### | ||
148 | +# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 | ||
149 | + | ||
150 | +# *.iml | ||
151 | +# modules.xml | ||
152 | +<<<<<<< HEAD | ||
153 | + | ||
154 | + | ||
155 | +### Eclipse ### | ||
156 | + | ||
157 | +.metadata | ||
158 | +bin/ | ||
159 | +tmp/ | ||
160 | +*.tmp | ||
161 | +*.bak | ||
162 | +*.swp | ||
163 | +*~.nib | ||
164 | +local.properties | ||
165 | +.settings/ | ||
166 | +.loadpath | ||
167 | +.recommenders | ||
168 | + | ||
169 | +# Eclipse Core | ||
170 | +.project | ||
171 | + | ||
172 | +# External tool builders | ||
173 | +.externalToolBuilders/ | ||
174 | + | ||
175 | +# Locally stored "Eclipse launch configurations" | ||
176 | +*.launch | ||
177 | + | ||
178 | +# PyDev specific (Python IDE for Eclipse) | ||
179 | +*.pydevproject | ||
180 | + | ||
181 | +# CDT-specific (C/C++ Development Tooling) | ||
182 | +.cproject | ||
183 | + | ||
184 | +# JDT-specific (Eclipse Java Development Tools) | ||
185 | +.classpath | ||
186 | + | ||
187 | +# Java annotation processor (APT) | ||
188 | +.factorypath | ||
189 | + | ||
190 | +# PDT-specific (PHP Development Tools) | ||
191 | +.buildpath | ||
192 | + | ||
193 | +# sbteclipse plugin | ||
194 | +.target | ||
195 | + | ||
196 | +# Tern plugin | ||
197 | +.tern-project | ||
198 | + | ||
199 | +# TeXlipse plugin | ||
200 | +.texlipse | ||
201 | + | ||
202 | +# STS (Spring Tool Suite) | ||
203 | +.springBeans | ||
204 | + | ||
205 | +# Code Recommenders | ||
206 | +.recommenders/ | ||
207 | + | ||
208 | + | ||
209 | +### Java ### | ||
210 | +*.class | ||
211 | + | ||
212 | +# Mobile Tools for Java (J2ME) | ||
213 | +.mtj.tmp/ | ||
214 | + | ||
215 | +# Package Files # | ||
216 | +## commented out to support storage of libs in git | ||
217 | +# *.jar | ||
218 | +# *.war | ||
219 | +# *.ear | ||
220 | + | ||
221 | +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml | ||
222 | +hs_err_pid* | ||
223 | +logs | ||
224 | + | ||
225 | +# logstatalarm # | ||
226 | +logstatalarm | ||
227 | +T16/Interface_Specification_SS7_Simulator_1.0_draft_J.docx |
1 | +++ a/.vscode/cSpell.json | ||
@@ -0,0 +1,26 @@ | @@ -0,0 +1,26 @@ | ||
1 | +// cSpell Settings | ||
2 | +{ | ||
3 | + // Version of the setting file. Always 0.1 | ||
4 | + "version": "0.1", | ||
5 | + // language - current active spelling language | ||
6 | + "language": "en", | ||
7 | + // words - list of words to be always considered correct | ||
8 | + "words": [ | ||
9 | + "ussd", | ||
10 | + "eventlog", | ||
11 | + "USSN", | ||
12 | + "PUSR", | ||
13 | + "GPRS", | ||
14 | + "isup", | ||
15 | + "toastr", | ||
16 | + "}", | ||
17 | + "lastname", | ||
18 | + "firstname" | ||
19 | + ], | ||
20 | + // flagWords - list of words to be always considered incorrect | ||
21 | + // This is useful for offensive words and common spelling errors. | ||
22 | + // For example "hte" should be "the" | ||
23 | + "flagWords": [ | ||
24 | + "hte" | ||
25 | + ] | ||
26 | +} | ||
0 | \ No newline at end of file | 27 | \ No newline at end of file |
1 | +++ a/.vscode/extensions.json | ||
@@ -0,0 +1,13 @@ | @@ -0,0 +1,13 @@ | ||
1 | +{ | ||
2 | + "recommendations": [ | ||
3 | + "christian-kohler.path-intellisense", | ||
4 | + "dbaeumer.vscode-eslint", | ||
5 | + "abusaidm.html-snippets", | ||
6 | + "be5invis.vscode-icontheme-nomo-dark", | ||
7 | + "alefragnani.Bookmarks", | ||
8 | + "donjayamanne.githistory", | ||
9 | + "karyfoundation.comment", | ||
10 | + "ms-vscode.typescript-javascript-grammar", | ||
11 | + "mkaufman.HTMLHint" | ||
12 | + ] | ||
13 | +} | ||
0 | \ No newline at end of file | 14 | \ No newline at end of file |
1 | +++ a/.vscode/launch.json | ||
@@ -0,0 +1,46 @@ | @@ -0,0 +1,46 @@ | ||
1 | +{ | ||
2 | + "version": "0.2.0", | ||
3 | + "configurations": [ | ||
4 | + { | ||
5 | + "name": "Launch", | ||
6 | + "type": "node", | ||
7 | + "request": "launch", | ||
8 | + "program": "${workspaceRoot}/server.js", | ||
9 | + "stopOnEntry": false, | ||
10 | + "args": [], | ||
11 | + "cwd": "${workspaceRoot}", | ||
12 | + "preLaunchTask": null, | ||
13 | + "runtimeExecutable": null, | ||
14 | + "runtimeArgs": [ | ||
15 | + "--nolazy" | ||
16 | + ], | ||
17 | + "env": { | ||
18 | + "NODE_ENV": "localhost" | ||
19 | + }, | ||
20 | + "console": "integratedTerminal", | ||
21 | + "sourceMaps": true, | ||
22 | + "outDir": null | ||
23 | + }, | ||
24 | + { | ||
25 | + "name": "Attach", | ||
26 | + "type": "node", | ||
27 | + "request": "attach", | ||
28 | + "port": 5858, | ||
29 | + "address": "localhost", | ||
30 | + "restart": false, | ||
31 | + "sourceMaps": false, | ||
32 | + "outDir": null, | ||
33 | + "localRoot": "${workspaceRoot}", | ||
34 | + "remoteRoot": null | ||
35 | + }, | ||
36 | + { | ||
37 | + "name": "Attach to Process", | ||
38 | + "type": "node", | ||
39 | + "request": "attach", | ||
40 | + "processId": "${command.PickProcess}", | ||
41 | + "port": 5858, | ||
42 | + "sourceMaps": false, | ||
43 | + "outDir": null | ||
44 | + } | ||
45 | + ] | ||
46 | +} | ||
0 | \ No newline at end of file | 47 | \ No newline at end of file |
1 | +++ a/.vscode/settings.json | ||
@@ -0,0 +1,17 @@ | @@ -0,0 +1,17 @@ | ||
1 | +// Place your settings in this file to overwrite default and user settings. | ||
2 | +{ | ||
3 | + "editor.tabSize": 4, | ||
4 | + "beautify.onSave": true, | ||
5 | + "editor.renderIndentGuides": true, | ||
6 | + "editor.wordWrap": false, | ||
7 | + "editor.detectIndentation": false, | ||
8 | + "editor.wrappingColumn": -1, | ||
9 | + "editor.cursorBlinking": "smooth", | ||
10 | + "editor.glyphMargin": true, | ||
11 | + "editor.formatOnType": true, | ||
12 | + "html.suggest.angular1": true, | ||
13 | + "html.suggest.html5": true, | ||
14 | + "editor.formatOnSave": true, | ||
15 | + "workbench.editor.showIcons": true, | ||
16 | + "eslint.enable": false | ||
17 | +} | ||
0 | \ No newline at end of file | 18 | \ No newline at end of file |
1 | +++ a/app/controllers/home.controller.js | ||
@@ -0,0 +1,73 @@ | @@ -0,0 +1,73 @@ | ||
1 | +'use strict' | ||
2 | + | ||
3 | +const console = process.console | ||
4 | +const yamlConfig = require('node-yaml-config') | ||
5 | +const path = require('path') | ||
6 | +const config = yamlConfig.load(path.join(__dirname, '/../../config/config.yml')) | ||
7 | + | ||
8 | +const lib = require('../lib') | ||
9 | + | ||
10 | +// lib.authorize() | ||
11 | +// lib.listEvents() | ||
12 | +// lib.createEvent() | ||
13 | + | ||
14 | +const url = config.server.url | ||
15 | +const port = config.server.port | ||
16 | +const urlto = config.server.urlto | ||
17 | +const portto = config.server.portto | ||
18 | + | ||
19 | +function index(req, res) { | ||
20 | + res.send({ | ||
21 | + message: 'Google Calendar API', | ||
22 | + endpoint: { | ||
23 | + listEvents: 'GET /events', | ||
24 | + createEvent: 'POST /events' | ||
25 | + } | ||
26 | + }) | ||
27 | +} | ||
28 | + | ||
29 | +function events(req, res) { | ||
30 | + lib.authorize((err, auth) => { | ||
31 | + if (err) { | ||
32 | + res.send(err) | ||
33 | + } | ||
34 | + lib.listEvents(auth, (err, response) => { | ||
35 | + if (err) { | ||
36 | + res.send(err) | ||
37 | + } else { | ||
38 | + res.send(response) | ||
39 | + } | ||
40 | + }) | ||
41 | + }) | ||
42 | +} | ||
43 | + | ||
44 | +function create(req, res) { | ||
45 | + let payload = req.body | ||
46 | + | ||
47 | + let summary = payload.summary | ||
48 | + let description = payload.description | ||
49 | + let email = payload.email | ||
50 | + let startDate = payload.startDate | ||
51 | + let endDate = payload.endDate | ||
52 | + | ||
53 | + lib.authorize((err, auth) => { | ||
54 | + if (err) { | ||
55 | + res.send(err) | ||
56 | + } | ||
57 | + | ||
58 | + // let options = lib.eventBuilder(payload) | ||
59 | + // options.auth = auth | ||
60 | + | ||
61 | + lib.createEvent(auth, payload, (err, result) => { | ||
62 | + if (err) { | ||
63 | + res.send(err) | ||
64 | + } else { | ||
65 | + res.send(result) | ||
66 | + } | ||
67 | + }) | ||
68 | + }) | ||
69 | +} | ||
70 | + | ||
71 | +module.exports.index = index | ||
72 | +module.exports.events = events | ||
73 | +module.exports.create = create |
1 | +++ a/app/lib/index.js | ||
@@ -0,0 +1,97 @@ | @@ -0,0 +1,97 @@ | ||
1 | +'use strict'; | ||
2 | + | ||
3 | +const google = require('googleapis'); | ||
4 | +const googleAuth = require('google-auth-library'); | ||
5 | +const calendar = google.calendar('v3'); | ||
6 | + | ||
7 | +const fs = require('fs'); | ||
8 | + | ||
9 | +const SCOPES = [process.env.SCOPES]; | ||
10 | +const TOKEN_DIR = (process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE) + '/.credentials/'; | ||
11 | +const TOKEN_PATH = TOKEN_DIR + 'calendar-nodejs-quickstart.json'; | ||
12 | + | ||
13 | +module.exports = { | ||
14 | + | ||
15 | + authorize: (callback) => { | ||
16 | + | ||
17 | + fs.readFile('client_secret.json', function processClientSecrets(err, content) { | ||
18 | + if (err) { | ||
19 | + console.log('Error loading client secret file: ' + err); | ||
20 | + return; | ||
21 | + } | ||
22 | + | ||
23 | + let credentials = JSON.parse(content); | ||
24 | + var clientSecret = credentials.installed.client_secret; | ||
25 | + var clientId = credentials.installed.client_id; | ||
26 | + var redirectUrl = credentials.installed.redirect_uris[0]; | ||
27 | + var auth = new googleAuth(); | ||
28 | + var oauth2Client = new auth.OAuth2(clientId, clientSecret, redirectUrl); | ||
29 | + | ||
30 | + // Check if we have previously stored a token. | ||
31 | + fs.readFile(TOKEN_PATH, function (err, token) { | ||
32 | + if (err) { | ||
33 | + return callback(err); | ||
34 | + } else { | ||
35 | + oauth2Client.credentials = JSON.parse(token); | ||
36 | + return callback(null, oauth2Client); | ||
37 | + } | ||
38 | + }); | ||
39 | + | ||
40 | + }); | ||
41 | + | ||
42 | + }, | ||
43 | + | ||
44 | + getNewToken: (oauth2Client, callback) => { | ||
45 | + var authUrl = oauth2Client.generateAuthUrl({ | ||
46 | + access_type: 'offline', | ||
47 | + scope: SCOPES | ||
48 | + }); | ||
49 | + console.log('Authorize this app by visiting this url: ', authUrl); | ||
50 | + var rl = readline.createInterface({ | ||
51 | + input: process.stdin, | ||
52 | + output: process.stdout | ||
53 | + }); | ||
54 | + rl.question('Enter the code from that page here: ', function (code) { | ||
55 | + rl.close(); | ||
56 | + oauth2Client.getToken(code, function (err, token) { | ||
57 | + if (err) { | ||
58 | + console.log('Error while trying to retrieve access token', err); | ||
59 | + return; | ||
60 | + } | ||
61 | + oauth2Client.credentials = token; | ||
62 | + storeToken(token); | ||
63 | + callback(oauth2Client); | ||
64 | + }); | ||
65 | + }); | ||
66 | + }, | ||
67 | + | ||
68 | + listEvents: (auth, callback) => { | ||
69 | + calendar.events.list({ | ||
70 | + auth: auth, | ||
71 | + calendarId: process.env.CALENDAR_ID, | ||
72 | + timeMin: (new Date()).toISOString(), | ||
73 | + maxResults: 50, | ||
74 | + singleEvents: true, | ||
75 | + orderBy: 'startTime' | ||
76 | + }, (err, response) => { | ||
77 | + if (err) { | ||
78 | + return callback(err); | ||
79 | + } | ||
80 | + return callback(null, response); | ||
81 | + }); | ||
82 | + }, | ||
83 | + | ||
84 | + createEvent: (auth, event, callback) => { | ||
85 | + | ||
86 | + calendar.events.insert({ | ||
87 | + auth: auth, | ||
88 | + calendarId: process.env.CALENDAR_ID, | ||
89 | + resource: event, | ||
90 | + }, (err, event) => { | ||
91 | + if (err) { | ||
92 | + return callback('There was an error contacting the Calendar service: ' + err); | ||
93 | + } | ||
94 | + return callback(null, event.htmlLink); | ||
95 | + }); | ||
96 | + } | ||
97 | +} | ||
0 | \ No newline at end of file | 98 | \ No newline at end of file |
1 | +++ a/app/routes/home.routes.js | ||
@@ -0,0 +1,10 @@ | @@ -0,0 +1,10 @@ | ||
1 | +// var console = process.console | ||
2 | +var express = require('express') | ||
3 | +var router = express.Router() | ||
4 | +var home = require('../controllers/home.controller') | ||
5 | + | ||
6 | +router.get('/', home.index) | ||
7 | +router.get('/events', home.events) | ||
8 | +router.post('/events', home.create) | ||
9 | + | ||
10 | +module.exports = router | ||
0 | \ No newline at end of file | 11 | \ No newline at end of file |
1 | +++ a/bower.json | ||
@@ -0,0 +1,36 @@ | @@ -0,0 +1,36 @@ | ||
1 | +{ | ||
2 | + "name": "ss7", | ||
3 | + "description": "", | ||
4 | + "main": "", | ||
5 | + "license": "MIT", | ||
6 | + "homepage": "", | ||
7 | + "private": true, | ||
8 | + "ignore": [ | ||
9 | + "**/.*", | ||
10 | + "node_modules", | ||
11 | + "bower_components", | ||
12 | + "test", | ||
13 | + "tests" | ||
14 | + ], | ||
15 | + "dependencies": { | ||
16 | + "angular-datatables": "^0.5.4", | ||
17 | + "yamljs": "^0.1.5", | ||
18 | + "sweetalert": "^1.1.3", | ||
19 | + "angular-ui-router": "^0.3.1", | ||
20 | + "ui-router-extras": "^0.1.2", | ||
21 | + "ng-slim-scroll": "^0.2.2", | ||
22 | + "angular-slimscroll": "^1.1.5", | ||
23 | + "angular-ladda": "^0.4.1", | ||
24 | + "toastr": "^2.1.3", | ||
25 | + "angular-toastr": "^2.1.1", | ||
26 | + "angular-animate": "^1.5.8", | ||
27 | + "angular-validation-match": "^1.9.0", | ||
28 | + "ngFitText": "^4.2.1", | ||
29 | + "angular-loading-bar": "^0.9.0", | ||
30 | + "animate.css": "^3.5.2", | ||
31 | + "ng-dialog": "^0.6.4" | ||
32 | + }, | ||
33 | + "resolutions": { | ||
34 | + "angular-ui-router": "^0.3.1" | ||
35 | + } | ||
36 | +} |
1 | +++ a/client_secret.json | ||
@@ -0,0 +1,14 @@ | @@ -0,0 +1,14 @@ | ||
1 | +{ | ||
2 | + "installed": { | ||
3 | + "client_id": "16634359544-7crvssfmpmtp0ng3jbipms65ccl9aol1.apps.googleusercontent.com", | ||
4 | + "project_id": "psyched-garage-146109", | ||
5 | + "auth_uri": "https://accounts.google.com/o/oauth2/auth", | ||
6 | + "token_uri": "https://accounts.google.com/o/oauth2/token", | ||
7 | + "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", | ||
8 | + "client_secret": "lpIa_7Wwbang6jTypMfCpOR6", | ||
9 | + "redirect_uris": [ | ||
10 | + "urn:ietf:wg:oauth:2.0:oob", | ||
11 | + "http://localhost" | ||
12 | + ] | ||
13 | + } | ||
14 | +} | ||
0 | \ No newline at end of file | 15 | \ No newline at end of file |
1 | +++ a/config/config.yml | ||
@@ -0,0 +1,18 @@ | @@ -0,0 +1,18 @@ | ||
1 | +##### deverlopment Config | ||
2 | +localhost: | ||
3 | + skipLogin: true | ||
4 | + debug: true | ||
5 | + server: | ||
6 | + url: 'localhost' | ||
7 | + urlto: 'localhost' | ||
8 | + port: 3001 | ||
9 | + portto: 4001 | ||
10 | + database: | ||
11 | + host: 'localhost' | ||
12 | + port: 27017 | ||
13 | + name: 'ss7' | ||
14 | + options: | ||
15 | + user: | ||
16 | + pass: | ||
17 | + timerecheck: '10000' #millisecond | ||
18 | + apitimeout: 3000 #millisecond | ||
0 | \ No newline at end of file | 19 | \ No newline at end of file |
1 | +++ a/jsconfig.json | ||
@@ -0,0 +1,16 @@ | @@ -0,0 +1,16 @@ | ||
1 | +{ | ||
2 | + // See https://go.microsoft.com/fwlink/?LinkId=759670 | ||
3 | + // for the documentation about the jsconfig.json format | ||
4 | + "compilerOptions": { | ||
5 | + "target": "es6", | ||
6 | + "module": "commonjs", | ||
7 | + "allowSyntheticDefaultImports": true | ||
8 | + }, | ||
9 | + "exclude": [ | ||
10 | + "node_modules", | ||
11 | + "bower_components", | ||
12 | + "jspm_packages", | ||
13 | + "tmp", | ||
14 | + "temp" | ||
15 | + ] | ||
16 | +} |
1 | +++ a/package.json | ||
@@ -0,0 +1,32 @@ | @@ -0,0 +1,32 @@ | ||
1 | +{ | ||
2 | + "name": "smart-rms-schedule", | ||
3 | + "version": "1.0.0", | ||
4 | + "dependencies": { | ||
5 | + "async": "^2.0.1", | ||
6 | + "bluebird": "^3.4.1", | ||
7 | + "body-parser": "~1.15.0", | ||
8 | + "busboy-body-parser": "0.0.10", | ||
9 | + "ejs": "^2.5.2", | ||
10 | + "express": "~4.13.0", | ||
11 | + "formidable": "^1.0.17", | ||
12 | + "google-auth-library": "^0.9.8", | ||
13 | + "googleapis": "^14.0.0", | ||
14 | + "indicative": "^2.1.0", | ||
15 | + "moment": "^2.14.1", | ||
16 | + "moment-timezone": "^0.5.5", | ||
17 | + "node-yaml-config": "0.0.4", | ||
18 | + "scribe-js": "^2.0.4", | ||
19 | + "unirest": "^0.5.0" | ||
20 | + }, | ||
21 | + "devDependencies": { | ||
22 | + "eslint": "^3.4.0", | ||
23 | + "eslint-config-angular": "^0.5.0", | ||
24 | + "eslint-config-defaults": "^9.0.0", | ||
25 | + "eslint-config-google": "^0.6.0", | ||
26 | + "eslint-config-standard": "^6.0.0", | ||
27 | + "eslint-plugin-angular": "^1.3.1", | ||
28 | + "eslint-plugin-promise": "^2.0.1", | ||
29 | + "eslint-plugin-standard": "^2.0.0", | ||
30 | + "gulp-ftp": "^1.1.0" | ||
31 | + } | ||
32 | +} |
1 | +++ a/public/views/index.html | ||
@@ -0,0 +1,14 @@ | @@ -0,0 +1,14 @@ | ||
1 | +<!DOCTYPE html> | ||
2 | +<html lang="en"> | ||
3 | + | ||
4 | +<head> | ||
5 | + <title>Smart RMS Schedule</title> | ||
6 | + <meta charset="UTF-8"> | ||
7 | + <meta name="viewport" content="width=device-width, initial-scale=1"> | ||
8 | +</head> | ||
9 | + | ||
10 | +<body> | ||
11 | + <h1>HELLO</h1> | ||
12 | +</body> | ||
13 | + | ||
14 | +</html> | ||
0 | \ No newline at end of file | 15 | \ No newline at end of file |
1 | +++ a/quickstart.js | ||
@@ -0,0 +1,131 @@ | @@ -0,0 +1,131 @@ | ||
1 | + | ||
2 | + | ||
3 | +var fs = require('fs'); | ||
4 | +var readline = require('readline'); | ||
5 | +var google = require('googleapis'); | ||
6 | +var googleAuth = require('google-auth-library'); | ||
7 | + | ||
8 | +// If modifying these scopes, delete your previously saved credentials | ||
9 | +// at ~/.credentials/calendar-nodejs-quickstart.json | ||
10 | +var SCOPES = ['https://www.googleapis.com/auth/calendar.readonly']; | ||
11 | +var TOKEN_DIR = (process.env.HOME || process.env.HOMEPATH || | ||
12 | + process.env.USERPROFILE) + '/.credentials/'; | ||
13 | +var TOKEN_PATH = TOKEN_DIR + 'calendar-nodejs-quickstart.json'; | ||
14 | + | ||
15 | +// Load client secrets from a local file. | ||
16 | +fs.readFile('client_secret.json', function processClientSecrets(err, content) { | ||
17 | + if (err) { | ||
18 | + console.log('Error loading client secret file: ' + err); | ||
19 | + return; | ||
20 | + } | ||
21 | + // Authorize a client with the loaded credentials, then call the | ||
22 | + // Google Calendar API. | ||
23 | + authorize(JSON.parse(content), listEvents); | ||
24 | +}); | ||
25 | + | ||
26 | +/** | ||
27 | + * Create an OAuth2 client with the given credentials, and then execute the | ||
28 | + * given callback function. | ||
29 | + * | ||
30 | + * @param {Object} credentials The authorization client credentials. | ||
31 | + * @param {function} callback The callback to call with the authorized client. | ||
32 | + */ | ||
33 | +function authorize(credentials, callback) { | ||
34 | + var clientSecret = credentials.installed.client_secret; | ||
35 | + var clientId = credentials.installed.client_id; | ||
36 | + var redirectUrl = credentials.installed.redirect_uris[0]; | ||
37 | + var auth = new googleAuth(); | ||
38 | + var oauth2Client = new auth.OAuth2(clientId, clientSecret, redirectUrl); | ||
39 | + | ||
40 | + // Check if we have previously stored a token. | ||
41 | + fs.readFile(TOKEN_PATH, function(err, token) { | ||
42 | + if (err) { | ||
43 | + getNewToken(oauth2Client, callback); | ||
44 | + } else { | ||
45 | + oauth2Client.credentials = JSON.parse(token); | ||
46 | + callback(oauth2Client); | ||
47 | + } | ||
48 | + }); | ||
49 | +} | ||
50 | + | ||
51 | +/** | ||
52 | + * Get and store new token after prompting for user authorization, and then | ||
53 | + * execute the given callback with the authorized OAuth2 client. | ||
54 | + * | ||
55 | + * @param {google.auth.OAuth2} oauth2Client The OAuth2 client to get token for. | ||
56 | + * @param {getEventsCallback} callback The callback to call with the authorized | ||
57 | + * client. | ||
58 | + */ | ||
59 | +function getNewToken(oauth2Client, callback) { | ||
60 | + var authUrl = oauth2Client.generateAuthUrl({ | ||
61 | + access_type: 'offline', | ||
62 | + scope: SCOPES | ||
63 | + }); | ||
64 | + console.log('Authorize this app by visiting this url: ', authUrl); | ||
65 | + var rl = readline.createInterface({ | ||
66 | + input: process.stdin, | ||
67 | + output: process.stdout | ||
68 | + }); | ||
69 | + rl.question('Enter the code from that page here: ', function(code) { | ||
70 | + rl.close(); | ||
71 | + oauth2Client.getToken(code, function(err, token) { | ||
72 | + if (err) { | ||
73 | + console.log('Error while trying to retrieve access token', err); | ||
74 | + return; | ||
75 | + } | ||
76 | + oauth2Client.credentials = token; | ||
77 | + storeToken(token); | ||
78 | + callback(oauth2Client); | ||
79 | + }); | ||
80 | + }); | ||
81 | +} | ||
82 | + | ||
83 | +/** | ||
84 | + * Store token to disk be used in later program executions. | ||
85 | + * | ||
86 | + * @param {Object} token The token to store to disk. | ||
87 | + */ | ||
88 | +function storeToken(token) { | ||
89 | + try { | ||
90 | + fs.mkdirSync(TOKEN_DIR); | ||
91 | + } catch (err) { | ||
92 | + if (err.code != 'EEXIST') { | ||
93 | + throw err; | ||
94 | + } | ||
95 | + } | ||
96 | + fs.writeFile(TOKEN_PATH, JSON.stringify(token)); | ||
97 | + console.log('Token stored to ' + TOKEN_PATH); | ||
98 | +} | ||
99 | + | ||
100 | +/** | ||
101 | + * Lists the next 10 events on the user's primary calendar. | ||
102 | + * | ||
103 | + * @param {google.auth.OAuth2} auth An authorized OAuth2 client. | ||
104 | + */ | ||
105 | +function listEvents(auth) { | ||
106 | + var calendar = google.calendar('v3'); | ||
107 | + calendar.events.list({ | ||
108 | + auth: auth, | ||
109 | + calendarId: 'primary', | ||
110 | + timeMin: (new Date()).toISOString(), | ||
111 | + maxResults: 10, | ||
112 | + singleEvents: true, | ||
113 | + orderBy: 'startTime' | ||
114 | + }, function(err, response) { | ||
115 | + if (err) { | ||
116 | + console.log('The API returned an error: ' + err); | ||
117 | + return; | ||
118 | + } | ||
119 | + var events = response.items; | ||
120 | + if (events.length == 0) { | ||
121 | + console.log('No upcoming events found.'); | ||
122 | + } else { | ||
123 | + console.log('Upcoming 10 events:'); | ||
124 | + for (var i = 0; i < events.length; i++) { | ||
125 | + var event = events[i]; | ||
126 | + var start = event.start.dateTime || event.start.date; | ||
127 | + console.log('%s - %s', start, event.summary); | ||
128 | + } | ||
129 | + } | ||
130 | + }); | ||
131 | +} | ||
0 | \ No newline at end of file | 132 | \ No newline at end of file |
1 | +++ a/server.js | ||
@@ -0,0 +1,45 @@ | @@ -0,0 +1,45 @@ | ||
1 | +var express = require('express') | ||
2 | +var bodyParser = require('body-parser') | ||
3 | +var yaml_config = require('node-yaml-config') | ||
4 | +var busboyBodyParser = require('busboy-body-parser') | ||
5 | +var scribe = require('scribe-js')() | ||
6 | +var Async = require('async') | ||
7 | + | ||
8 | +var console = process.console | ||
9 | +var app = express() | ||
10 | +var router = express.Router() | ||
11 | +var config = yaml_config.load(__dirname + '/config/config.yml') | ||
12 | + | ||
13 | +var url = config.server.url | ||
14 | +var port = config.server.port | ||
15 | + | ||
16 | +app.use(bodyParser.urlencoded({ | ||
17 | + extended: false | ||
18 | +})) | ||
19 | +app.use(bodyParser.json()) | ||
20 | +app.use(express.static('public')) | ||
21 | +app.use(express.static('bower_components')) | ||
22 | + | ||
23 | +var home = require('./app/routes/home.routes') | ||
24 | + | ||
25 | +app.set('views', './public/views') | ||
26 | +app.set('view engine', 'html') | ||
27 | +app.engine('html', require('ejs').renderFile) | ||
28 | + | ||
29 | +app.use(function (req, res, next) { | ||
30 | + res.header('Access-Control-Allow-Origin', '*') | ||
31 | + res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept') | ||
32 | + next() | ||
33 | +}) | ||
34 | + | ||
35 | +app.use('/', home) | ||
36 | + | ||
37 | +app.use(scribe.express.logger()) // Log each request | ||
38 | +app.use('/logs', scribe.webPanel()) | ||
39 | + | ||
40 | +app.use(busboyBodyParser()) | ||
41 | + | ||
42 | +app.listen(port) | ||
43 | +// console.log('Server is running at http://'+url+':'+port+''); | ||
44 | + | ||
45 | +console.tag('START').time().file().log('Server is running at http://' + url + ':' + port) | ||
0 | \ No newline at end of file | 46 | \ No newline at end of file |