]>
git.r.bdr.sh - rbdr/dasein/blob - lib/handlers/comments.js
3 const Joi
= require('joi');
4 const Pify
= require('pify');
5 const Redis
= require('redis');
6 const UUID
= require('uuid/v4');
10 internals
.kPostsPrefix
= 'posts';
11 internals
.kCommentsPrefix
= 'comments';
12 internals
.kMaxCommentSize
= 255;
14 internals
.kCommentsSchema
= Joi
.object().keys({
15 uuid: Joi
.string().required(),
16 content: Joi
.string().max(internals
.kMaxCommentSize
).required(),
17 timestamp: Joi
.number().integer().required(),
18 userId: Joi
.string().required(),
19 userName: Joi
.string().required(),
20 userImage: Joi
.string().required()
24 * Handles the HTTP requests for comment related operations
26 * @class CommentsHandler
27 * @param {Dasein.tConfiguration} config The configuration to
30 module
.exports
= internals
.CommentsHandler
= class CommentsHandler
{
33 this._ttl
= config
.ttl
;
34 this._redis
= Redis
.createClient(config
.redis
);
36 // Log an error if it happens.
37 this._redis
.on('error', (err
) => {
44 * Fetches all available comments
47 * @memberof CommentsHandler
49 * @return {generator} a koa compatible handler generator function
55 return function * (postId
) {
57 if (!this.state
.user
) {
58 return this.throw('Unauthorized', 401);
61 const scan
= Pify(self
._redis
.scan
.bind(self
._redis
));
62 const hgetall
= Pify(self
._redis
.hgetall
.bind(self
._redis
));
64 const commentsKey
= `${internals.kCommentsPrefix}:${postId}:*`;
67 let currentKeys
= null;
70 [nextCursor
, currentKeys
] = yield scan(nextCursor
|| 0, 'MATCH', commentsKey
);
71 keys
= keys
.concat(currentKeys
);
72 } while (nextCursor
> 0);
74 const comments
= yield keys
.map((key
) => hgetall(key
));
76 this.body
= comments
.sort((a
, b
) => a
.timestamp
- b
.timestamp
);
84 * @memberof CommentsHandler
86 * @return {generator} a koa compatible handler generator function
92 return function * (postId
) {
94 if (!this.state
.user
) {
95 return this.throw('Unauthorized', 401);
98 const hmset
= Pify(self
._redis
.hmset
.bind(self
._redis
));
99 const hgetall
= Pify(self
._redis
.hgetall
.bind(self
._redis
));
100 const expire
= Pify(self
._redis
.expire
.bind(self
._redis
));
103 const timestamp
= Date
.now();
104 const user
= this.state
.user
;
106 const postKey
= `${internals.kPostsPrefix}:${postId}`;
107 const commentKey
= `${internals.kCommentsPrefix}:${postId}:${uuid}`;
111 content: this.request
.body
.content
,
113 userId: user
.screen_name
,
115 userImage: user
.profile_image_url_https
118 yield self
._validate(comment
).catch((err
) => {
120 this.throw(err
.message
, 422);
123 yield hmset(commentKey
, comment
);
124 yield expire(commentKey
, self
._ttl
* 100); // this is me being lazy :(
125 // comments will last at most 100 bumps
126 // but will disappear eventually
127 yield expire(postKey
, self
._ttl
); // bumps the parent comment TTL
129 this.body
= yield hgetall(commentKey
);
133 // Validates the comment schema
137 const validate
= Pify(Joi
.validate
.bind(Joi
));
138 return validate(comment
, internals
.kCommentsSchema
);