Commit 7703481083decab4059e94f13a8c3f6bb6dafd27

Authored by Apichat.Tum
1 parent cf86e9a3
Exists in master

fix REST API

app/controllers/home.controller.js
... ... @@ -15,6 +15,17 @@ const lib = require('../lib')
15 15 const url = config.server.url
16 16 const port = config.server.port
17 17  
  18 +function responseJSON(code, description, data, status) {
  19 + return {
  20 + "code": code,
  21 + "description": description,
  22 + "result": {
  23 + "data": data,
  24 + "status": status
  25 + }
  26 + }
  27 +}
  28 +
18 29 function strToTime(date) {
19 30 var strDate = new Date(date)
20 31 return strDate.getTime()
... ... @@ -25,7 +36,7 @@ function ggToKendo(data) {
25 36 try {
26 37 for (var n = 0; n < data.items.length; n++) {
27 38 dataToArr.push({
28   - "TaskID": data.items[n].etag,
  39 + "TaskID": data.items[n].id,
29 40 "OwnerID": 2,
30 41 "Title": data.items[n].summary,
31 42 "Description": data.items[n].description,
... ... @@ -51,22 +62,27 @@ function home(req, res) {
51 62 }
52 63  
53 64 function index(req, res) {
  65 + console.log(req.body)
54 66 lib.getNewToken((err, authUrl) => {
55 67 if (err) {
56   - console.error(err.message)
  68 + console.error(err)
57 69 } else {
  70 + console.info(authUrl)
58 71 res.send(authUrl)
59 72 }
60 73 })
61 74 }
62 75  
63 76 function setToken(req, res) {
  77 + console.log(req.body)
64 78 var code = req.body.code
65 79 lib.setNewToken(code, (err, token) => {
66 80 if (err) {
  81 + console.error(err)
67 82 res.send(err)
68 83 res.end()
69 84 } else {
  85 + console.info(token)
70 86 res.send(token)
71 87 res.end()
72 88 }
... ... @@ -74,28 +90,40 @@ function setToken(req, res) {
74 90 }
75 91  
76 92 function events(req, res) {
  93 + // console.log(req.body)
77 94 lib.authorize((err, auth, authUrl) => {
78 95 if (err) {
  96 + console.error(err)
79 97 res.send(err)
80   - } else if (authUrl) {
81   - console.info(authUrl)
82   - res.send(authUrl)
83   - res.end()
84 98 } else {
85 99 lib.listEvents(auth, (err, response) => {
86 100 if (err) {
87   - res.send(err)
  101 + if (authUrl) {
  102 + console.info(authUrl)
  103 + res.json(responseJSON(res.code, "redirect to get auth code", authUrl, "redirect"))
  104 + res.end()
  105 + } else {
  106 + console.error(err)
  107 + res.json(responseJSON(res.code, "response error", err.message, "failed"))
  108 + res.end()
  109 + }
88 110 } else {
  111 + // console.info(response)
89 112 res.jsonp(ggToKendo(response))
  113 + res.end
90 114 }
91 115 })
92 116 }
93   -
94 117 })
95 118 }
96 119  
97   -function create(req, res) {
  120 +function eventCreate(req, res) {
  121 + console.log(req.body)
98 122 let payload = req.body
  123 + if (typeof payload.models == "string") {
  124 + payload.models = JSON.parse(req.body.models)
  125 + payload = payload.models[0]
  126 + }
99 127  
100 128 let summary = payload.summary
101 129 let description = payload.description
... ... @@ -119,13 +147,90 @@ function create(req, res) {
119 147 res.send(err)
120 148 } else {
121 149 res.send(result)
  150 + res.end()
122 151 }
123 152 })
124 153 })
125 154 }
126 155  
  156 +function oauth2callback(req, res) {
  157 + var code = req.query.code
  158 + lib.setNewToken(code, (err, token) => {
  159 + if (err) {
  160 + res.send(err)
  161 + res.end()
  162 + } else {
  163 + res.redirect('/home')
  164 + }
  165 + })
  166 +}
  167 +
  168 +function eventDelete(req, res) {
  169 + console.log(req.body)
  170 + let payload = req.body
  171 + if (typeof payload.models == "string") {
  172 + payload.models = JSON.parse(req.body.models)
  173 + payload = payload.models[0]
  174 + }
  175 + lib.authorize((err, auth) => {
  176 + let options = lib.deleteBuilder(payload)
  177 + if (err) {
  178 + console.error(err.message)
  179 + res.send(err)
  180 + } else {
  181 + console.info(auth)
  182 + options.auth = auth
  183 + }
  184 +
  185 + lib.deleteEvent(options, (err, result) => {
  186 + if (err) {
  187 + console.error(err.message)
  188 + res.send(err)
  189 + } else {
  190 + console.info(result)
  191 + res.send(result)
  192 + res.end()
  193 + }
  194 + })
  195 + })
  196 +}
  197 +
  198 +function eventUpdate(req, res) {
  199 + console.log(req.body)
  200 + let payload = req.body
  201 + if (typeof payload.models == "string") {
  202 + payload.models = JSON.parse(req.body.models)
  203 + payload = payload.models[0]
  204 + }
  205 + lib.authorize((err, auth) => {
  206 + let options = lib.updateBuilder(payload)
  207 + if (err) {
  208 + console.error(err.message)
  209 + res.send(err)
  210 + } else {
  211 + console.info(auth)
  212 + options.auth = auth
  213 + }
  214 +
  215 + lib.updateEvent(options, (err, result) => {
  216 + if (err) {
  217 + console.error(err)
  218 + res.send(err)
  219 + } else {
  220 + console.info(result)
  221 + res.send(result)
  222 + res.end()
  223 + }
  224 + })
  225 + })
  226 +}
  227 +
  228 +
127 229 module.exports.index = index
128 230 module.exports.events = events
129   -module.exports.create = create
  231 +module.exports.eventCreate = eventCreate
  232 +module.exports.eventUpdate = eventUpdate
  233 +module.exports.eventDelete = eventDelete
130 234 module.exports.home = home
131 235 module.exports.setToken = setToken
  236 +module.exports.oauth2callback = oauth2callback
... ...
app/lib/index.js
... ... @@ -7,7 +7,10 @@ const fs = require(&#39;fs&#39;);
7 7 const path = require('path');
8 8 const yamlConfig = require('node-yaml-config');
9 9 const config = yamlConfig.load(path.join(__dirname, '/../../config/config.yml'));
10   -const CALENDAR_ID = config.calendarID
  10 +const moment = require('moment')
  11 +const CALENDAR_ID = config.ggapi.calendarID
  12 +const REDIRECTURL = config.ggapi.redirectUrl
  13 +
11 14  
12 15 const SCOPES = ['https://www.googleapis.com/auth/calendar'];
13 16 const TOKEN_DIR = (process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE) + '/.credentials/';
... ... @@ -63,9 +66,9 @@ module.exports = {
63 66 let credentials = JSON.parse(content);
64 67 var clientSecret = credentials.installed.client_secret;
65 68 var clientId = credentials.installed.client_id;
66   - var redirectUrl = credentials.installed.redirect_uris[0];
  69 + var redirectUrl = credentials.installed.redirect_uris[1];
67 70 var auth = new googleAuth();
68   - var oauth2Client = new auth.OAuth2(clientId, clientSecret, redirectUrl);
  71 + var oauth2Client = new auth.OAuth2(clientId, clientSecret, REDIRECTURL);
69 72  
70 73 fs.readFile(TOKEN_PATH, (err, token) => {
71 74 if (err) {
... ... @@ -86,9 +89,9 @@ module.exports = {
86 89 let credentials = JSON.parse(content);
87 90 var clientSecret = credentials.installed.client_secret;
88 91 var clientId = credentials.installed.client_id;
89   - var redirectUrl = credentials.installed.redirect_uris[0];
  92 + var redirectUrl = credentials.installed.redirect_uris[1];
90 93 var auth = new googleAuth();
91   - var oauth2Client = new auth.OAuth2(clientId, clientSecret, redirectUrl);
  94 + var oauth2Client = new auth.OAuth2(clientId, clientSecret, REDIRECTURL);
92 95  
93 96 fs.readFile(TOKEN_PATH, (err, token) => {
94 97 if (err) {
... ... @@ -115,7 +118,6 @@ module.exports = {
115 118 calendar.events.list({
116 119 auth: auth,
117 120 calendarId: CALENDAR_ID || 'primary',
118   - timeMin: (new Date()).toISOString(),
119 121 maxResults: 50,
120 122 singleEvents: true,
121 123 orderBy: 'startTime'
... ... @@ -150,19 +152,82 @@ module.exports = {
150 152 });
151 153 },
152 154  
  155 + updateEvent: (options, callback) => {
  156 + calendar.events.update({
  157 + auth: options.auth,
  158 + calendarId: CALENDAR_ID || 'primary',
  159 + eventId: options.eventId
  160 + }, (err, response) => {
  161 + if (err) return callback(err);
  162 +
  163 + return callback(null, response);
  164 + });
  165 + },
  166 +
153 167 eventBuilder: (payload) => {
154 168 var buildPayload = {}
155 169 try {
156   - buildPayload.summary = payload.summary
157   - buildPayload.description = payload.description
  170 + buildPayload.summary = payload.Title
  171 + buildPayload.description = payload.Description
158 172 buildPayload.start = {
159   - dateTime: payload.startDate,
160   - timezone: hasTimezone(payload.startTimeZone)
  173 + dateTime: payload.Start,
  174 + timezone: hasTimezone(payload.StartTimezone)
  175 +
  176 + }
  177 + buildPayload.end = {
  178 + dateTime: payload.End,
  179 + timeZone: hasTimezone(payload.EndTimezone)
  180 + }
  181 + if (payload.email) {
  182 + buildPayload.attendees = [{ email: payload.email }]
  183 + }
  184 + if (payload.reminders) {
  185 + buildPayload.reminders = {
  186 + useDefault: false,
  187 + overrides: [
  188 + {
  189 + method: 'email',
  190 + minutes: 24 * 60
  191 + }
  192 + ]
  193 + }
  194 + }
  195 + if (payload.extendedProperties) {
  196 + buildPayload.extendedProperties = payload.extendedProperties
  197 + }
  198 + } catch (error) {
  199 + console.error(error.message)
  200 + } finally {
  201 + return buildPayload
  202 + }
  203 + },
161 204  
  205 + deleteBuilder: (payload) => {
  206 + var buildPayload = {}
  207 + try {
  208 + buildPayload.calendarId = CALENDAR_ID
  209 + buildPayload.eventId = payload.TaskID
  210 + } catch (error) {
  211 + console.error(error.message)
  212 + } finally {
  213 + return buildPayload
  214 + }
  215 + },
  216 +
  217 + updateBuilder: (payload) => {
  218 + var buildPayload = {}
  219 + try {
  220 + buildPayload.calendarId = CALENDAR_ID
  221 + buildPayload.eventId = payload.TaskID
  222 + buildPayload.summary = payload.Title
  223 + buildPayload.description = payload.Description
  224 + buildPayload.start = {
  225 + dateTime: moment(payload.Start).format("YYYY-MM-DDTHH:mm:ssZ"),
  226 + timeZone: hasTimezone(payload.StartTimezone)
162 227 }
163 228 buildPayload.end = {
164   - dateTime: payload.endDate,
165   - timeZone: hasTimezone(payload.endTimeZone)
  229 + dateTime: moment(payload.End).format("YYYY-MM-DDTHH:mm:ssZ"),
  230 + timeZone: hasTimezone(payload.EndTimezone)
166 231 }
167 232 if (payload.email) {
168 233 buildPayload.attendees = [{ email: payload.email }]
... ...
app/routes/home.routes.js
... ... @@ -7,7 +7,10 @@ router.get(&#39;/&#39;, home.index)
7 7 router.get('/home', home.home)
8 8  
9 9 router.get('/events', home.events)
10   -router.post('/events', home.create)
  10 +router.post('/events', home.eventCreate)
  11 +router.put('/events', home.eventUpdate)
  12 +router.delete('/events', home.eventDelete)
11 13 router.post('/setToken', home.setToken)
  14 +router.get('/oauth2callback', home.oauth2callback)
12 15  
13 16 module.exports = router
14 17 \ No newline at end of file
... ...
config/config.yml
... ... @@ -15,4 +15,6 @@ localhost:
15 15 pass:
16 16 timerecheck: '10000' #millisecond
17 17 apitimeout: 3000 #millisecond
18   - calendarID: 'rvmbg3kg7uqninf7n3au1ku4mc@group.calendar.google.com'
19 18 \ No newline at end of file
  19 + ggapi:
  20 + calendarID: 'rvmbg3kg7uqninf7n3au1ku4mc@group.calendar.google.com'
  21 + redirectUrl: 'http://localhost:3001/oauth2callback'
20 22 \ No newline at end of file
... ...
public/js/controllers/kendo.js
1 1 angular.module("KendoDemos", ["kendo.directives"])
2 2 .controller("MyCtrl", function ($scope, $http) {
  3 + $scope.update = function () {
  4 + console.log("update")
  5 + }
  6 +
  7 + $scope.create = function () {
  8 + console.log("create")
  9 + }
3 10 function getAuthURL() {
4 11 $http({
5 12 method: 'get',
6 13 url: '/events'
7 14 }).then(function successCallback(response) {
8   - window.open(response.data, '_blank')
9   - }, function errorCallback(response) {
10   - console.error(response)
11   - });
12   - }
13   - getAuthURL()
  15 + var res = response.data
  16 + if (res.result) {
  17 + if (res.result.status == "redirect") {
  18 + window.open(res.result.data, '_self')
  19 + }
  20 + } else {
  21 + console.info(response)
  22 + schedulerStart()
  23 + }
14 24  
15   - $scope.submitNewToken = function (valid) {
16   - $http({
17   - method: 'post',
18   - url: '/setToken',
19   - data: { "code": $scope.clientToken }
20   - }).then(function successCallback(response) {
21   - console.log(response.data)
22   - schedulerStart()
23 25 }, function errorCallback(response) {
24 26 console.error(response)
25 27 });
26 28 }
  29 + getAuthURL()
27 30  
28 31 function schedulerStart() {
29 32 $scope.schedulerOptions = {
... ... @@ -36,25 +39,29 @@ angular.module(&quot;KendoDemos&quot;, [&quot;kendo.directives&quot;])
36 39 "week",
37 40 "month",
38 41 ],
39   - timezone: "Etc/UTC",
  42 + timezone: "Asia/Bangkok",
40 43 dataSource: {
41 44 batch: true,
42 45 transport: {
43 46 read: {
44 47 url: "//localhost:3001/events",
45   - dataType: "jsonp"
  48 + dataType: "jsonp",
  49 + type: "GET"
46 50 },
47 51 update: {
48   - url: "//demos.telerik.com/kendo-ui/service/tasks/update",
49   - dataType: "jsonp"
  52 + url: "//localhost:3001/events",
  53 + dataType: "jsonp",
  54 + type: "PUT"
50 55 },
51 56 create: {
52   - url: "//demos.telerik.com/kendo-ui/service/tasks/create",
53   - dataType: "jsonp"
  57 + url: "//localhost:3001/events",
  58 + dataType: "jsonp",
  59 + type: "POST"
54 60 },
55 61 destroy: {
56   - url: "//demos.telerik.com/kendo-ui/service/tasks/destroy",
57   - dataType: "jsonp"
  62 + url: "//localhost:3001/events",
  63 + dataType: "jsonp",
  64 + type: "DELETE"
58 65 },
59 66 parameterMap: function (options, operation) {
60 67 if (operation !== "read" && options.models) {
... ... @@ -68,10 +75,10 @@ angular.module(&quot;KendoDemos&quot;, [&quot;kendo.directives&quot;])
68 75 fields: {
69 76 taskId: { from: "TaskID" },
70 77 title: { from: "Title", defaultValue: "No title", validation: { required: true } },
71   - start: { type: "date", from: "Start" },
72   - end: { type: "date", from: "End" },
73   - startTimezone: { from: "StartTimezone" },
74   - endTimezone: { from: "EndTimezone" },
  78 + start: { type: "datetime", from: "Start" },
  79 + end: { type: "datetime", from: "End" },
  80 + startTimezone: { from: "StartTimezone", defaultValue: "Asia/Bangkok" },
  81 + endTimezone: { from: "EndTimezone", defaultValue: "Asia/Bangkok" },
75 82 description: { from: "Description" },
76 83 recurrenceId: { from: "RecurrenceID" },
77 84 recurrenceRule: { from: "RecurrenceRule" },
... ... @@ -89,6 +96,7 @@ angular.module(&quot;KendoDemos&quot;, [&quot;kendo.directives&quot;])
89 96 ]
90 97 }
91 98 },
  99 + editable: true,
92 100 resources: [
93 101 {
94 102 field: "ownerId",
... ...
public/views/index.html
... ... @@ -7,7 +7,7 @@
7 7 <link href="../assets/content/shared/styles/examples-offline.css" rel="stylesheet">
8 8 <link href="../assets/styles/kendo.common.min.css" rel="stylesheet">
9 9 <link href="../assets/styles/kendo.rtl.min.css" rel="stylesheet">
10   - <link href="../assets/styles/kendo.flat.min.css" rel="stylesheet">
  10 + <link href="../assets/styles/kendo.bootstrap.min.css" rel="stylesheet">
11 11 <link href="../assets/styles/kendo.dataviz.min.css" rel="stylesheet">
12 12 <link href="../assets/styles/kendo.dataviz.flat.min.css" rel="stylesheet">
13 13 <script src="../assets/js/jquery.min.js"></script>
... ... @@ -27,22 +27,8 @@
27 27  
28 28 <body>
29 29  
30   - <a class="offline-button" href="../assets/offline/index.html">Back</a>
31   -
32 30 <div id="example" ng-app="KendoDemos">
33 31 <div ng-controller="MyCtrl">
34   - <form class="demo-section k-content wide" name="newTokenForm" ng-submit="submitNewToken(newTokenForm.$valid)">
35   - <ul class="fieldlist">
36   - <li>
37   - <h4>Put key here</h4>
38   - <input type="text" class="k-textbox " ng-model="clientToken" required />
39   - <input type="submit" class="k-button" name="btnSubmitKey" value="Submit">
40   - </li>
41   - </ul>
42   - </form>
43   -
44   - <hr>
45   -
46 32 <div kendo-scheduler k-options="schedulerOptions">
47 33 <span k-event-template class="custom-event">{{dataItem.title}}</span>
48 34 <div k-all-day-event-template class="custom-all-day-event">{{dataItem.title}}</div>
... ...