Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

birdwatch

Package Overview
Dependencies
Maintainers
1
Versions
40
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

birdwatch - npm Package Compare versions

Comparing version 0.1.2 to 0.1.3

.travis.yml

3

index.js
'use strict';
var credentials = require('./configure/local_configure.js');
var EventEmitter = require('events').EventEmitter;

@@ -9,3 +8,2 @@ var objectAssign = require('object-assign');

/**

@@ -32,2 +30,3 @@ * Initialize a new Birdwatch

this.logReports = this.options.logReports || false;
this.useTestData = this.options.useTestData || false;
}

@@ -34,0 +33,0 @@

{
"name": "birdwatch",
"version": "0.1.2",
"version": "0.1.3",
"description": "Monitor and cache specific twitter feeds",
"main": "index.js",
"engines": {
"node": ">=0.10.0"
},
"scripts": {

@@ -34,2 +37,3 @@ "test": "mocha"

"each-async": "~1.1.1",
"fs-access": "^1.0.0",
"is-regexp": "~1.0.0",

@@ -36,0 +40,0 @@ "native-promise-only": "~0.8.0-a",

@@ -5,2 +5,4 @@ # Birdwatch :baby_chick::watch:

[![Build Status](https://travis-ci.org/radiovisual/birdwatch.svg?branch=master)](https://travis-ci.org/radiovisual/birdwatch)
Birdwatch will help you grab tweets from specific twitter accounts, and cache the tweets on-disk and in-memory on your server,

@@ -71,2 +73,9 @@ thus avoiding any request limits set by the Twitter API, and giving you more control over the data that is saved.

##### useTestData
Type: `boolean`<br>
Default: `false`
Use the test tweet data instead of making a network requests. Useful for testing/debugging.
# ![birdwatch](media/screenshot-v.0.0.1.png)

@@ -73,0 +82,0 @@

@@ -9,11 +9,2 @@ 'use strict';

/*
* TODO: Add more tests
*
* removes filtered tweets
* removes retweets when remove_retweets:true
* fails if filter_tags isn't valid regex
* tweets are sorted
*
* */

@@ -94,2 +85,55 @@ describe('Birdwatch', function() {

it('should fail when filter_tweets is not a valid regex', function(){
var birdwatch = new Birdwatch()
.feed('MichaelWuergler', {filter_tags: ''});
birdwatch.start(function(err){
assertEqual(err.message.slice(0,38) , "You must supply a regex to filter_tags");
});
});
/*
// Currently, we can't test filter_tags
// See: https://github.com/radiovisual/birdwatch/issues/4
it('should return only filtered tweets with option `filter_tags`', function(){
var birdwatch = new Birdwatch({useTestData:true})
.feed('Twitterer', {filter_tags:/#09/} );
birdwatch.start(function(err){});
return birdwatch.getCachedTweets().then(function(tweetdata){
assert(tweetdata.length === 1);
});
});
*/
/*
// Currently, we can't test remove_retweets
// See: https://github.com/radiovisual/birdwatch/issues/4
it('should remove retweets with option `remove_retweets`', function(){
var birdwatch = new Birdwatch({useTestData:true})
.feed('Twitterer', {remove_retweets:true} );
birdwatch.start(function(err){});
return birdwatch.getCachedTweets().then(function(tweetdata){
assert(tweetdata.length === 5);
});
});
*/
/*
// Currently, we can't test sorting
// See: https://github.com/radiovisual/birdwatch/issues/4
it('should sort the tweets', function(){
});
*/
});

@@ -96,0 +140,0 @@

'use strict';
var credentials = require('./configure/local_configure');
var test_tweets = require("./test/test_tweets.js");
var underscore = require('underscore');
var eachAsync = require('each-async');
var isRegexp = require('is-regexp');
var fsAccess = require('fs-access');
var report = require("./report");

@@ -12,13 +13,22 @@ var chalk = require('chalk');

/*
* The credentials file to use for Twitter API authentication.
* This will be dynamically set in setupCredentials()
*
* @type {object} - The json object from local_configure.js
*/
var credentials;
/*
* The Twit object used to access the Twitter API.
* This value will be dynamically assigned in setupCredentials()
*/
var twit;
// Polyfill Promise
require("native-promise-only");
// Setup the Twit object
var T = new Twit({
consumer_key: credentials.consumer_key,
consumer_secret: credentials.consumer_secret,
access_token: credentials.access_token,
access_token_secret: credentials.access_token_secret
});
/**

@@ -29,3 +39,3 @@ * Temporarily hold the data that is returned from the promises

* and on-disk caches. When the birdwatching cycle is over, this is emptied
* and waits for the next birdwatching cycle to begin.
* and waits for the next birdwatching cycle to begin.
* @type {Array}

@@ -43,5 +53,5 @@ */

*/
var in_memory_cache = [];
/**

@@ -57,2 +67,4 @@ * Process the feeds by starting the promise chain.

var self = this;
// Let's go Birdwatching!

@@ -68,14 +80,16 @@ if(this.logReports){

var p = getTwitterData(screenname, bwoptions).then(function(tweetdata){
return filterTweets(tweetdata, screenname, feedoptions, bwoptions);
var p = self.setupCredentials(bwoptions).then(function(testmode){
return self.getTwitterData(screenname, bwoptions, testmode);
}).then(function(tweetdata){
return self.filterTweets(tweetdata, screenname, feedoptions, bwoptions);
}).then(function(){
return processCache(feeds);
return self.processCache(feeds);
}).then(function(processedCacheObjects){
return sortTweets(processedCacheObjects);
return self.sortTweets(processedCacheObjects);
}).then(function(sorteddataobjects){
saveToCache(sorteddataobjects, bwoptions);
self.saveToCache(sorteddataobjects, bwoptions);
});
p.catch(function(error){
report.logError(error, false);
p.catch(function(err){
report.logError(err, false);
});

@@ -98,3 +112,55 @@

/**
* Setup the credentials for the app.
*
* Do we have real credentials? Or are we testing?
* Travis CI and Mocha shouldn't need valid credentials to test with,
* so we use this promise to determine if we are in test mode or not.
* This promise will return `true` if we are in test mode
* (i.e, the local_configure is not set or we want to use the test_tweet data),
* and `false` if we in are in normal app mode.
* This function also sets var credentials when in normal app mode.
*
* @param {object} bwoptions - the birdwatch configuration options
* @returns {Promise}
*/
exports.setupCredentials = function(bwoptions){
return new Promise(function(resolve, reject){
if( bwoptions.useTestData ){
resolve(true);
} else {
fsAccess('./configure/local_configure.js', function(err){
if(err) {
resolve(true);
} else {
credentials = require("./configure/local_configure.js");
twit = new Twit({
consumer_key: credentials.consumer_key,
consumer_secret: credentials.consumer_secret,
access_token: credentials.access_token,
access_token_secret: credentials.access_token_secret
});
resolve(false);
}
});
}
});
};
/**
* Request twitter data from the Twitter API

@@ -104,6 +170,7 @@ *

* @param {Object} bwoptions - birdwatch configuration options
* @param {Boolean} testmode - are we in test mode? If yes, serve test tweet data
* @returns {Promise}
*/
function getTwitterData(screenname, bwoptions){
exports.getTwitterData = function(screenname, bwoptions, testmode){

@@ -116,12 +183,20 @@ if(bwoptions.logReports){

T.get("statuses/user_timeline", {screen_name: screenname, count:200, include_rts:true}, function(err, reply){
if (err){
reject(Error(err));
} else {
resolve(reply);
}
});
// Send test_tweets in testing environments
if(testmode){
resolve(test_tweets);
} else {
twit.get("statuses/user_timeline", {screen_name: screenname, count:200, include_rts:true}, function(err, reply){
if (err){
reject(err);
} else {
resolve(reply);
}
});
}
});
}
};

@@ -139,3 +214,3 @@

function filterTweets(tweetdata, screenname, feedoptions, bwoptions){
exports.filterTweets = function(tweetdata, screenname, feedoptions, bwoptions){

@@ -145,7 +220,8 @@ return new Promise(function (resolve, reject){

// return the unfiltered tweetdata if no filters are requested
if( !feedoptions.hasOwnProperty("filter_tags") ){
// and if no need to remove the retweets
if( !feedoptions.filter_tags && !feedoptions.remove_retweets){
returned_tweets.push(tweetdata);
resolve();
// otherwise, return the filtered tweets
// otherwise, let's filter the tweets
} else {

@@ -159,19 +235,15 @@

// is options.filter_tags a string or regex?
// is options.filter_tags a regex?
var isRegEx = isRegexp(feedoptions.filter_tags);
var search_tags;
if(!isRegEx){
if(feedoptions.filter_tags && !isRegEx){
reject(new Error(["You must supply a regex to filter_tags\nCheck your syntax on: "+feedoptions.filter_tags]));
}
var remove_retweets = feedoptions.remove_retweets;
for (var i in tweetdata){
var tweet = tweetdata[i];
var isRetweet = tweet.hasOwnProperty("retweeted_status");
var isRetweet = tweet.retweeted_status;
if(isRetweet && remove_retweets){
if(isRetweet && feedoptions.remove_retweets){
continue;

@@ -182,4 +254,6 @@ }

if(feedoptions.filter_tags.test(tweet.text)){
if(feedoptions.filter_tags && feedoptions.filter_tags.test(tweet.text)){
matches.push(tweet);
} else if (!feedoptions.filter_tags) {
matches.push(tweet);
}

@@ -194,4 +268,5 @@ }

}
};
/**

@@ -204,3 +279,3 @@ * Break the data objects out of the returned_tweets array

var processCache = function(feeds){
exports.processCache = function(feeds){

@@ -235,3 +310,3 @@ return new Promise(function(resolve, reject){

var sortTweets = function(tweetObjects, options){
exports.sortTweets = function(tweetObjects, options){

@@ -257,7 +332,9 @@ return new Promise(function(resolve, reject){

function saveToCache(dataToSave, bwoptions){
exports.saveToCache = function(dataToSave, bwoptions){
fs.writeFile('./cache/cached_tweets.json', JSON.stringify(dataToSave), function (err) {
in_memory_cache.push(JSON.stringify(dataToSave));
fs.writeFileSync('./cache/cached_tweets.json', JSON.stringify(dataToSave), {flag:'w'}, function (err) {
if (err) {
report.logError(["Error saving cached_tweets.json in processCache()", error]);
report.logError(["Error saving cached_tweets.json in saveToCache()", err]);
} else {

@@ -270,6 +347,5 @@

returned_tweets = [];
in_memory_cache.push(JSON.stringify(dataToSave));
}
});
}
};

@@ -309,2 +385,8 @@

// TODO: make the process wait until in_memory cache is available.
// This will allow the process to be properly tested.
// Otherwise the on-disk cache file is always served in the test scenarios,
// and we can't test sorting, and removing retweets, etc if this is the case
// See https://github.com/radiovisual/birdwatch/issues/4
// Maybe this will help: http://blog.mediumequalsmessage.com/promise-deferred-objects-in-javascript-pt2-practical-use
if (in_memory_cache.length > 0){

@@ -326,2 +408,3 @@

});
};

@@ -328,0 +411,0 @@

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc