1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
/* DreemGL is a collaboration between Teeming Society & Samsung Electronics, sponsored by Samsung and others. Copyright 2015-2016 Teeming Society. Licensed under the Apache License, Version 2.0 (the "License"); You may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.*/ /** * @class TwitterLib * Interface class between npm twitter and dreemgl * Requires the twitter npm modules: * 'npm install twitter'. */ define.class(function(exports){ var TwitterLib = exports // No credentials are stored in source. You must define them as an // environment variable Twitter = require('twitter') /** * @method constructor * Create a TwitterLib object with default parameters. The credentials * are read from environment variables, * TWITTER_CONSUMER_KEY * TWITTER_CONSUMER_SECRET * TWITTER_ACCESS_TOKEN_KEY * TWITTER_ACCESS_TOKEN_SECRET * * All four values are required to use the streaming interface. If you * do not specify the TWITTER_ACCESS_TOKEN_* for a search query, the * application rate-limits will apply. * * Install the twitter object via 'npm install twitter'. * You can access the twitter npm object using this.twitter */ this.atConstructor = function(view) { // Create the twitter object using environment creds //console.log('twitterlib') this.twitter = new Twitter({ consumer_key: process.env.TWITTER_CONSUMER_KEY, consumer_secret: process.env.TWITTER_CONSUMER_SECRET, access_token_key: process.env.TWITTER_ACCESS_TOKEN_KEY, access_token_secret: process.env.TWITTER_ACCESS_TOKEN_SECRET }) } // Search interface to retrieve images. You can call this routine multiple // times if you need more images, but you run the risk of hitting rate limits. // If 0 results are returned you should not continue searcing. // Multiple pages is not currently working. You can retrieve up to 100 // results per query. // // cb Callback method which is passed the returned tweets, as an array, // and the next maxid argument if you need additional tweets. // options is a hash of: // query The twitter query string // See: https://dev.twitter.com/rest/public/search // geocode Optional geocode location // nresults The number of results to return. Default = 25 // maxid (multi-page support). The maxid parameter. This is the // tweet.id_str-1 from the last tweet returned. this.search = function(options, cb) { // Parse the arguments options = options || {} var nresults = options.nresults || 25 var maxid = options.maxid || 25 var defaultquery='-RT&filter:images' var query = options.query || defaultquery var defaultgeocode='37.781157,-122.398720,4mi' var geocode = options.geocode || defaultgeocode if (nresults > 100) nresults = 100 var args = {q: query, geocode: geocode, result_type: 'recent', count: nresults, maxid: maxid} console.log('multi-page maxid', maxid) // Decrement the string id (64-bit) without using a bigint package // http://webapplog.com/decreasing-64-bit-tweet-id-in-javascript/ var decid = function(id) { var result=id var i=id.length-1 while (i>-1) { if (id[i]==="0") { result=result.substring(0,i)+"9"+result.substring(i+1) i-- } else { result=result.substring(0,i)+(parseInt(id[i],10)-1).toString()+result.substring(i+1) return result } } return result } // Retrieve a page of results this.twitter.get('search/tweets', args, function(error, tweets, response){ var result_tweets = [] // Check each tweet before adding it to the list. var lastid console.log(error, tweets) console.log('received', tweets.statuses.length, ' tweets') for (var i=0; i<tweets.statuses.length; i++) { var tweet = tweets.statuses[i] lastid = tweet.id_str var media = tweet.entities.media if (media && !tweet.possibly_sensitive) { result_tweets.push(tweet) } } // The next id is the lastid-1, but this is a 64-bit quantity // Instead of adding another npm module, do it manually if (lastid) { lastid = decid(lastid) } cb(result_tweets, lastid) }) } // Search interface. This returns an array of tweets, which will invoke // a callback method for each one. Same calling interface as streaming // If you don't specify a query, a default SF query is used // Watch out for rate limits this.oldsearch = function(cb, query) { // Test the twitter search interface var defaultquery='-RT&geocode:"37.781157,-122.398720,2mi"&filter:images' query = query || defaultquery this.twitter.get('search/tweets', {q: query, result_type: 'recent', count: 25}, function(error, tweets, response){ //console.log('tweets', tweets) for (var i=0; i<tweets.statuses.length; i++) { var tweet = tweets.statuses[i] var media = tweet.entities.media if (media && !tweet.possibly_sensitive) { // Take the first url var url = media[0].media_url console.log('twitter url', url) cb(url, tweet) } } }) } // Streaming interface. Returns the tweet to a callback method. // This is hardcoded to return images posted from San Francisco this.streaming = function(cb) { // Test the twitter streaming interface var locations = '-122.75,36.7,-121.75,37.9' var track = 'filter:images' this.twitter.stream('statuses/filter', {locations: locations, track: track}, function(stream) { stream.on('data', function(tweet) { // Only return tweets with images if (tweet.entities && tweet.entities.media && !tweet.possibly_sensitive) { // Return as an array to match search interface cb([tweet]) } }) stream.on('error', function(error) { //console.log('ERROR', error) }) }) } }) |