]> git.r.bdr.sh - rbdr/dasein/blame_incremental - lib/handlers/posts.js
Merge branch 'release/1.0.0'
[rbdr/dasein] / lib / handlers / posts.js
... / ...
CommitLineData
1'use strict';
2
3const Joi = require('joi');
4const Pify = require('pify');
5const Redis = require('redis');
6const UUID = require('uuid/v4');
7
8const internals = {};
9
10internals.kPostsPrefix = 'posts';
11internals.kMaxPostSize = 255;
12
13internals.kPostsSchema = Joi.object().keys({
14 uuid: Joi.string().required(),
15 content: Joi.string().max(internals.kMaxPostSize).required(),
16 timestamp: Joi.number().integer().required(),
17 userId: Joi.string().required(),
18 userName: Joi.string().required(),
19 userImage: Joi.string().required()
20});
21
22/**
23 * Handles the HTTP requests for posts related operations
24 *
25 * @class PostsHandler
26 * @param {Dasein.tConfiguration} config The configuration to
27 * initialize.
28 */
29module.exports = internals.PostsHandler = class PostsHandler {
30 constructor(config) {
31
32 this._ttl = config.ttl;
33 this._redis = Redis.createClient(config.redis);
34
35 // Log an error if it happens.
36 this._redis.on('error', (err) => {
37
38 console.error(err);
39 });
40 }
41
42 /**
43 * Fetches all available posts
44 *
45 * @function findAll
46 * @memberof PostsHandler
47 * @instance
48 * @return {generator} a koa compatible handler generator function
49 */
50 findAll() {
51
52 const self = this;
53
54 return function * () {
55
56 if (!this.state.user) {
57 return this.throw('Unauthorized', 401);
58 }
59
60 const scan = Pify(self._redis.scan.bind(self._redis));
61 const hgetall = Pify(self._redis.hgetall.bind(self._redis));
62
63 let keys = [];
64 let nextCursor = 0;
65 let currentKeys = null;
66
67 do {
68 [nextCursor, currentKeys] = yield scan(nextCursor || 0, 'MATCH', `${internals.kPostsPrefix}:*`);
69 keys = keys.concat(currentKeys);
70 } while (nextCursor > 0);
71
72 const posts = yield keys.map((key) => hgetall(key));
73
74 this.body = posts.sort((a, b) => b.timestamp - a.timestamp);
75 };
76 }
77
78 /**
79 * Fetches a single post
80 *
81 * @function find
82 * @memberof PostsHandler
83 * @instance
84 * @return {generator} a koa compatible handler generator function
85 */
86 find() {
87
88 const self = this;
89
90 return function * (uuid) {
91
92 if (!this.state.user) {
93 return this.throw('Unauthorized', 401);
94 }
95
96 const hgetall = Pify(self._redis.hgetall.bind(self._redis));
97
98 const postKey = `${internals.kPostsPrefix}:${uuid}`;
99
100 const post = yield hgetall(postKey);
101
102 if (!post) {
103 this.throw('Post not found', 404);
104 }
105
106 this.body = post;
107 };
108 }
109
110 /**
111 * Creates a post
112 *
113 * @function create
114 * @memberof PostsHandler
115 * @instance
116 * @return {generator} a koa compatible handler generator function
117 */
118 create() {
119
120 const self = this;
121
122 return function * () {
123
124 if (!this.state.user) {
125 return this.throw('Unauthorized', 401);
126 }
127
128 const hmset = Pify(self._redis.hmset.bind(self._redis));
129 const hgetall = Pify(self._redis.hgetall.bind(self._redis));
130 const expire = Pify(self._redis.expire.bind(self._redis));
131
132 const uuid = UUID();
133 const timestamp = Date.now();
134 const user = this.state.user;
135
136 const postKey = `${internals.kPostsPrefix}:${uuid}`;
137
138 const post = {
139 uuid,
140 content: this.request.body.content,
141 timestamp,
142 userId: user.screen_name,
143 userName: user.name,
144 userImage: user.profile_image_url_https
145 };
146
147 yield self._validate(post).catch((err) => {
148
149 this.throw(err.message, 422);
150 });
151
152 yield hmset(postKey, post);
153 yield expire(postKey, self._ttl);
154
155 this.body = yield hgetall(postKey);
156 };
157 }
158
159 /**
160 * Deletes a post
161 *
162 * @function delete
163 * @memberof PostsHandler
164 * @instance
165 * @return {generator} a koa compatible handler generator function
166 */
167 delete() {
168
169 return function * () {};
170 }
171
172 // Validates the post schema
173
174 _validate(post) {
175
176 const validate = Pify(Joi.validate.bind(Joi));
177 return validate(post, internals.kPostsSchema);
178 }
179};