UNPKG

2ch

Version:

A JavaScript library for comfortable 2ch watching.

136 lines (121 loc) 4.34 kB
(function() { var EventEmitter2, Message, Thread, util, _, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; _ = require('lodash'); EventEmitter2 = require('eventemitter2').EventEmitter2; util = require('./util'); Message = require('./message'); module.exports = Thread = (function(_super) { __extends(Thread, _super); function Thread(bbs, number, title) { this.bbs = bbs; this.number = number; this.title = title != null ? title : ''; this.messages = []; this.lastModified = null; this.byteLength = 0; this.lastIndex = 0; this._ended = false; } Thread.prototype.isEnded = function() { return this._ended; }; Thread.prototype.toString = function() { var m, rawStrings; rawStrings = (function() { var _i, _len, _ref, _results; _ref = this.messages; _results = []; for (_i = 0, _len = _ref.length; _i < _len; _i++) { m = _ref[_i]; _results.push(m.rawString); } return _results; }).call(this); return rawStrings.join('\n') + '\n'; }; Thread.prototype.update = function(done, force) { var _this = this; if (force == null) { force = false; } return this.fetch(function(error, res) { if (error) { _this.emit('error', error); return typeof done === "function" ? done(error) : void 0; } switch (res.status) { case 200: case 206: return _this._updateOnSuccess(res, done); case 302: _this._ended = true; _this.emit('end', _this.title); return typeof done === "function" ? done(null, []) : void 0; case 304: if (_this.messages.length >= 1000) { _this._ended = true; _this.emit('end', _this.title); } return typeof done === "function" ? done(null, []) : void 0; case 416: _this.emit('reload', _this.title); return _this.update(done, true); default: error = new Error("Unknown Status: " + res.status); _this.emit('error', error); return typeof done === "function" ? done(error) : void 0; } }, force); }; Thread.prototype._updateOnSuccess = function(res, done) { var messages, newMessages, rawMessages, _this = this; this.lastModified = res.headers['last-modified']; if (res.status === 200) { this.byteLength = res.body.byteLength; this.messages = []; this.emit('begin', this.title); } else { this.byteLength += res.body.byteLength; } rawMessages = res.body.text.trim().split('\n'); messages = rawMessages.map(function(m, i) { return new Message(m, i + _this.messages.length + 1); }); this.messages = this.messages.concat(messages); newMessages = _.filter(this.messages, function(m) { return m.number > _this.lastIndex; }); this.lastIndex = this.messages.length; this.emit('update', newMessages); if (_.isEmpty(newMessages) && this.messages.length >= 1000) { this._ended = true; this.emit('end', this.title); } return typeof done === "function" ? done(null, newMessages) : void 0; }; Thread.prototype.fetch = function(done, force) { var req, url; if (force == null) { force = false; } url = this.bbs.getThreadUrl(this.number); req = util.requestGet(url); if (force) { req.set('Accept-Encoding', 'gzip'); } else { req.set('Accept-Encoding', this.lastModified != null ? 'identify' : 'gzip'); if (this.lastModified) { req.set('If-Modified-Since', this.lastModified); } if (this.byteLength > 0) { req.set('Range', "bytes=" + this.byteLength + "-"); } } return req.end(done); }; return Thread; })(EventEmitter2); }).call(this);