mirror of
https://github.com/Hopiu/postal.js.git
synced 2026-03-17 06:30:23 +00:00
129 lines
No EOL
3.4 KiB
JavaScript
129 lines
No EOL
3.4 KiB
JavaScript
var query = require( 'querystring' ),
|
|
http = require( 'http' );
|
|
|
|
var client = http.createClient( 80, "search.twitter.com" );
|
|
|
|
var TwitterSearch = function ( refreshInterval ) {
|
|
this.events = {};
|
|
|
|
this.timeoutFn = undefined;
|
|
|
|
this.searchPath = "/search.json";
|
|
|
|
this.refreshInterval = refreshInterval || 5000;
|
|
|
|
this.searchRegistry = {};
|
|
|
|
this.tweetRegistry = {};
|
|
|
|
this.defaultSearch = {};
|
|
|
|
this.nextSearch = undefined;
|
|
};
|
|
|
|
TwitterSearch.prototype = {
|
|
search : function ( searchTerm ) {
|
|
clearTimeout( this.timeoutFn );
|
|
this.raiseEvent( "search.init", searchTerm );
|
|
this.defaultSearch = {
|
|
q : searchTerm,
|
|
result_type : "recent",
|
|
rpp : 100
|
|
};
|
|
this.nextSearch = undefined;
|
|
this.searchRegistry = {};
|
|
this.tweetRegistry = {};
|
|
this.runSearch();
|
|
},
|
|
on : function ( eventName, callback ) {
|
|
if ( !this.events[ eventName ] ) {
|
|
this.events[ eventName ] = [];
|
|
}
|
|
this.events[ eventName ].push( callback );
|
|
return function () {
|
|
this.events[ eventName ] = _.without( this.events[ eventName ], callback );
|
|
}.bind( this );
|
|
},
|
|
raiseEvent : function ( eventName, data ) {
|
|
if ( this.events[ eventName ] ) {
|
|
this.events[ eventName ].forEach( function ( callback ) {
|
|
callback( data );
|
|
} );
|
|
}
|
|
},
|
|
buildUrl : function () {
|
|
var srchQry;
|
|
if ( this.nextSearch ) {
|
|
srchQry = this.nextSearch;
|
|
}
|
|
else {
|
|
if ( !this.defaultSearch.since_id ) {
|
|
delete this.defaultSearch.since_id;
|
|
}
|
|
srchQry = "?" + query.stringify( this.defaultSearch );
|
|
}
|
|
return this.searchPath + srchQry;
|
|
},
|
|
|
|
runSearch : function () {
|
|
var url = this.buildUrl();
|
|
if ( !this.searchRegistry[url] ) {
|
|
this.searchRegistry[url] = true;
|
|
this.raiseEvent( "search.current", { url : url } );
|
|
var request = client.request( "GET", url, {"host" : "search.twitter.com"} );
|
|
request.addListener( "response", function ( response ) {
|
|
var body = "";
|
|
response.addListener( "data", function ( data ) {
|
|
body += data;
|
|
} );
|
|
|
|
response.addListener( "end", function () {
|
|
this.onSearched( JSON.parse( body ) );
|
|
}.bind( this ) );
|
|
this.timeoutFn = setTimeout( this.runSearch.bind( this ), this.refreshInterval );
|
|
}.bind( this ) );
|
|
request.end();
|
|
}
|
|
else {
|
|
this.raiseEvent( "search.nodata", { url : url } );
|
|
this.timeoutFn = setTimeout( this.runSearch.bind( this ), this.refreshInterval );
|
|
}
|
|
},
|
|
onSearched : function ( payload ) {
|
|
// sift out errors
|
|
if ( !payload.error ) {
|
|
if ( payload.results.length > 0 ) {
|
|
this.processTweets( payload.results );
|
|
}
|
|
// do we have a next page option? If so, let's use it
|
|
if ( payload.next_page ) {
|
|
this.nextSearch = payload.next_page;
|
|
}
|
|
if ( payload.max_id ) {
|
|
this.defaultSearch.since_id = payload.max_id;
|
|
}
|
|
}
|
|
else {
|
|
this.nextSearch = undefined;
|
|
}
|
|
},
|
|
processTweets : function ( tweets ) {
|
|
var newTweets = tweets.filter( function ( t ) {
|
|
return !this.tweetRegistry[t];
|
|
}, this );
|
|
newTweets.forEach( function ( tweet ) {
|
|
if ( !this.tweetRegistry[tweet.id] ) {
|
|
this.tweetRegistry[tweet.id] = true;
|
|
}
|
|
// deal with the images that consistently fail from twitter...
|
|
if ( tweet.profile_image_url === "http://twitter.com/images/default_profile_normal.png" ||
|
|
tweet.profile_image_url === "http://static.twitter.com/images/default_profile_normal.png" ) {
|
|
tweet.profile_image_url = "templates/images/default_profile_1_normal.png";
|
|
}
|
|
}, this );
|
|
this.raiseEvent( "newTweets", newTweets );
|
|
}
|
|
};
|
|
|
|
|
|
module.exports = TwitterSearch; |