tweetlr 0.1.4pre4 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
data/bin/tweetlr CHANGED
@@ -19,13 +19,21 @@ begin
19
19
  }.call
20
20
  CONFIG = YAML.load_file(config_file)
21
21
  CONFIG['start_at_tweet_id'] = start_at_tweet_id || CONFIG['start_at_tweet_id'] || CONFIG['twitter_timestamp'] #check the latter for backwards compability
22
- TERM = CONFIG['search_term']
23
- USER = CONFIG['tumblr_username']
24
- PW = CONFIG['tumblr_password']
25
- TIMESTAMP = CONFIG['start_at_tweet_id']
26
- UPDATE_PERIOD = CONFIG['update_period']
27
- LOGLEVEL = CONFIG['loglevel'] || Logger::INFO
28
- @tweetlr = Tweetlr.new(USER, PW, config_file, {:since_id => TIMESTAMP, :terms => TERM, :loglevel => LOGLEVEL})
22
+
23
+ UPDATE_PERIOD = CONFIG['update_period']
24
+
25
+ @tweetlr = Tweetlr.new(CONFIG['tumblr_username'], CONFIG['tumblr_password'], {
26
+ :whitelist => CONFIG['whitelist'],
27
+ :shouts => CONFIG['shouts'],
28
+ :since_id => CONFIG['start_at_tweet_id'] ,
29
+ :terms => CONFIG['search_term'],
30
+ :loglevel => CONFIG['loglevel'],
31
+ :update_period => UPDATE_PERIOD,
32
+ :api_endpoint_tumblr => CONFIG['api_endpoint_tumblr'],
33
+ :api_endpoint_twitter => CONFIG['api_endpoint_twitter'],
34
+ :results_per_page => CONFIG['results_per_page'],
35
+ :result_type => CONFIG['result_type']
36
+ })
29
37
  rescue SystemCallError
30
38
  $stderr.puts "Ooops - looks like there is no ./config/tweetlr.yml found. I'm affraid tweetlr won't work properly until you introduced that configuration file."
31
39
  exit(1)
data/lib/tweetlr.rb CHANGED
@@ -6,46 +6,40 @@ require 'json'
6
6
 
7
7
  class Tweetlr
8
8
 
9
- VERSION = '0.1.4pre3'
10
- GENERATOR = %{tweetlr - http://github.com/5v3n/tweetlr}
11
- USER_AGENT = %{Mozilla/5.0 (compatible; tweetlr/#{VERSION}; +http://github.com/5v3n/tweetlr/wiki)}
9
+ VERSION = '0.1.5'
10
+ GENERATOR = %{tweetlr - http://tweetlr.5v3n.com}
11
+ USER_AGENT = %{Mozilla/5.0 (compatible; tweetlr/#{VERSION}; +http://tweetlr.5v3n.com)}
12
12
  LOCATION_START_INDICATOR = 'Location: '
13
13
  LOCATION_STOP_INDICATOR = "\r\n"
14
14
 
15
- def initialize(email, password, config_file, args={:cookie => nil, :since_id=>nil, :results_per_page => nil, :terms=>nil, :loglevel=>Logger::INFO})
15
+ API_ENDPOINT_TWITTER = 'http://search.twitter.com/search.json'
16
+ API_ENDPOINT_TUMBLR = 'http://www.tumblr.com'
17
+ TWITTER_RESULTS_PER_PAGE = 100
18
+ TWITTER_RESULTS_TYPE = 'recent'
19
+ UPDATE_PERIOD = 600 #10 minutes
20
+
21
+ def initialize(email, password, args={:terms=>nil, :whitelist => nil, :shouts => nil, :since_id=>nil, :results_per_page => nil, :loglevel=>nil, :result_type => nil})
16
22
  @log = Logger.new(STDOUT)
17
- @log.level = args[:loglevel] if (Logger::DEBUG..Logger::UNKNOWN).to_a.index(args[:loglevel])
23
+ if (Logger::DEBUG..Logger::UNKNOWN).to_a.index(args[:loglevel])
24
+ @log.level = args[:loglevel]
25
+ else
26
+ @log.level = Logger::INFO
27
+ end
18
28
  @log.debug "log level set to #{@log.level}"
19
- config = YAML.load_file(config_file)
20
29
  @email = email
21
30
  @password = password
22
31
  @since_id = args[:since_id]
23
32
  @search_term = args[:terms]
24
33
  @cookie = args[:cookie]
25
- @results_per_page = args[:results_per_page] || config['results_per_page'] #TODO decide how to trade args vs config file
26
- @result_type = config['result_type']
27
- @api_endpoint_twitter = config['api_endpoint_twitter']
28
- @api_endpoint_tumblr = config['api_endpoint_tumblr']
29
- @whitelist = config['whitelist']
30
- @shouts = config['shouts']
34
+ @results_per_page = args[:results_per_page] || TWITTER_RESULTS_PER_PAGE
35
+ @result_type = args[:result_type] || TWITTER_RESULTS_TYPE
36
+ @api_endpoint_twitter = args[:api_endpoint_twitter] || API_ENDPOINT_TWITTER
37
+ @api_endpoint_tumblr = args[:api_endpoint_tumblr] || API_ENDPOINT_TUMBLR
38
+ @whitelist = args[:whitelist] || []
39
+ @shouts = args[:shouts]
40
+ @update_period = args[:update_period] || UPDATE_PERIOD
31
41
  @whitelist.each {|entry| entry.downcase!}
32
- @refresh_url = "#{@api_endpoint_twitter}?ors=#{@search_term}&since_id=#{@since_id}&rpp=#{@results_per_page}&result_type=#{@result_type}" if (@since_id && @search_term)
33
- if !@cookie
34
- response = Curl::Easy.http_post(
35
- "#{@api_endpoint_tumblr}/login",
36
- :body => {
37
- :email => @email,
38
- :password => @password
39
- }
40
- )
41
- @log.debug("initial login response header: #{response.header_str}") if response
42
- @cookie = response.headers['Set-Cookie']
43
- @log.debug("login cookie via new login: #{@cookie.inspect}")
44
- else
45
- @cookie = args[:cookie]
46
- @log.debug("login cookie via argument: #{@cookie.inspect}")
47
- end
48
-
42
+ @refresh_url = "#{@api_endpoint_twitter}?ors=#{@search_term}&since_id=#{@since_id}&rpp=#{@results_per_page}&result_type=#{@result_type}" if (@since_id && @search_term)
49
43
  end
50
44
  #post a tumblr photo entry. required arguments are :type, :date, :source, :caption, :state. optional argument: :tags
51
45
  def post_to_tumblr(options={})
@@ -117,9 +111,8 @@ class Tweetlr
117
111
  def lazy_search_twitter()
118
112
  @refresh_url = "#{@api_endpoint_twitter}#{@response['refresh_url']}" unless (@response.nil? || @response['refresh_url'].nil? || @response['refresh_url'].empty?)
119
113
  if @refresh_url
120
- #FIXME persist the refresh url - server restart would be a pain elsewise
121
114
  search_url = "#{@refresh_url}&result_type=#{@result_type}&rpp=#{@results_per_page}"
122
- @log.info "lazy search using '#{search_url}'" #workaround to get refresh url logged w/ the Daemons gem
115
+ @log.info "lazy search using '#{search_url}'"
123
116
  @response = http_get search_url
124
117
  else
125
118
  @log.debug "regular search using '#{@search_term}'"
data/spec/spec_helper.rb CHANGED
@@ -1,69 +1,49 @@
1
1
  #encoding: utf-8
2
2
  require "bundler"
3
- Bundler.require :default, :development
4
-
5
- module Curl
6
- class Easy
7
- attr_accessor :body_str, :header_str
8
- @@mocked_response = Curl::Easy.new
9
- def perform
10
- return @@mocked_response
11
- end
12
- def self.http_get(url)
13
- return @@mocked_response
14
- end
15
- def self.mock_body_str=(str)
16
- @@mock_body_str = str
17
- end
18
- def self.mock_header_str=(str)
19
- @@mock_header_str = str
20
- end
21
- def body_str
22
- @@mock_body_str
23
- end
24
- def header_str
25
- @@mock_header_str
26
- end
27
- end
28
- end
29
-
30
- def mock_reset
31
- Curl::Easy.mock_body_str = nil
32
- Curl::Easy.mock_header_str = nil
33
- end
3
+ Bundler.require :default, :development, :test
34
4
 
35
- def mock_bad_request
36
- Curl::Easy.mock_body_str = %|<html><title>400: Bad Request - Invalid URL format http://mopskopf</title><body>400: Bad Request - Invalid URL format http://mopskopf</body></html>|
5
+ def stub_twitter
6
+ Curl::Easy.any_instance.stub(:body_str).and_return %|{"results":[{"from_user_id_str":"220650275","profile_image_url":"http://a2.twimg.com/profile_images/668619338/9729_148876458070_505518070_2628895_7160219_n_normal.jpg","created_at":"Sat, 16 Jul 2011 23:20:01 +0000","from_user":"LoMuma","id_str":"92372947855093760","metadata":{"result_type":"recent"},"to_user_id":null,"text":"Need to stop procrastinating! 5 quizzes and personal responses due tomorrow... #fail","id":92372947855093760,"from_user_id":220650275,"geo":null,"iso_language_code":"en","to_user_id_str":null,"source":"&lt;a href=&quot;http://twitter.com/&quot;&gt;web&lt;/a&gt;"},{"from_user_id_str":"129718556","profile_image_url":"http://a2.twimg.com/profile_images/1428268221/twitter_normal.png","created_at":"Sat, 16 Jul 2011 23:20:01 +0000","from_user":"priiislopes","id_str":"92372947846692865","metadata":{"result_type":"recent"},"to_user_id":null,"text":"Esse jogo do Flu foi uma vergonha. Se ele fez o melhor dele no brasileiro semana passada, hj fez o pior de todos os tempos. #Fail","id":92372947846692865,"from_user_id":129718556,"geo":null,"iso_language_code":"pt","to_user_id_str":null,"source":"&lt;a href=&quot;http://twitter.com/&quot;&gt;web&lt;/a&gt;"},{"from_user_id_str":"259930166","profile_image_url":"http://a3.twimg.com/profile_images/1425221519/foto_normal.jpg","created_at":"Sat, 16 Jul 2011 23:20:00 +0000","from_user":"YamiiG4","id_str":"92372943132303360","metadata":{"result_type":"recent"},"to_user_id":null,"text":"vaya que eran 2 minutos..#FAIL!","id":92372943132303360,"from_user_id":259930166,"geo":null,"iso_language_code":"es","to_user_id_str":null,"source":"&lt;a href=&quot;http://www.tweetdeck.com&quot; rel=&quot;nofollow&quot;&gt;TweetDeck&lt;/a&gt;"},{"from_user_id_str":"321557905","profile_image_url":"http://a0.twimg.com/profile_images/1445672626/profile_normal.png","created_at":"Sat, 16 Jul 2011 23:20:00 +0000","from_user":"JasWafer_FFOE","id_str":"92372941379088384","metadata":{"result_type":"recent"},"to_user_id":null,"text":"RT @eye_OFBEHOLDER: RT @JasWafer_FFOE #Oomf said that he'll NEVER eat pussy! O.o --#FAIL","id":92372941379088384,"from_user_id":321557905,"geo":null,"iso_language_code":"en","to_user_id_str":null,"source":"&lt;a href=&quot;http://twidroyd.com&quot; rel=&quot;nofollow&quot;&gt;Twidroyd for Android&lt;/a&gt;"},{"from_user_id_str":"279395613","profile_image_url":"http://a0.twimg.com/profile_images/1334871419/lnnsquare_normal.jpg","created_at":"Sat, 16 Jul 2011 23:19:59 +0000","from_user":"LanguageNewsNet","id_str":"92372940640890881","metadata":{"result_type":"recent"},"to_user_id":null,"text":"Questioning the Inca Paradox: Did the civilization behind Machu Picchu really fail to develop a written la... http://tinyurl.com/5sfos23","id":92372940640890881,"from_user_id":279395613,"geo":null,"iso_language_code":"en","to_user_id_str":null,"source":"&lt;a href=&quot;http://twitterfeed.com&quot; rel=&quot;nofollow&quot;&gt;twitterfeed&lt;/a&gt;"}],"max_id":92372947855093760,"since_id":0,"refresh_url":"?since_id=92372947855093760&q=+fail","next_page":"?page=2&max_id=92372947855093760&rpp=5&q=+fail","results_per_page":5,"page":1,"completed_in":0.022152,"since_id_str":"0","max_id_str":"92372947855093760","query":"+fail"}|
7
+ Curl::Easy.any_instance.stub(:perform).and_return Curl::Easy.new
37
8
  end
38
9
 
39
- def mock_utf8_response
40
- Curl::Easy.mock_body_str = %|√∫ƒ® are inhabitnts of utf-8 wonderländ.|
10
+ def stub_instagram
11
+ Curl::Easy.any_instance.stub(:body_str).and_return %|{"provider_url": "http://instagram.com/", "title": "Curse you tweets. See what you have done to me?!!!", "url": "http://distillery.s3.amazonaws.com/media/2011/05/02/d25df62b9cec4a138967a3ad027d055b_7.jpg", "author_name": "loswhit", "height": 612, "width": 612, "version": "1.0", "author_url": "http://instagram.com/", "provider_name": "Instagram", "type": "photo"}|
12
+ Curl::Easy.any_instance.stub(:perform).and_return Curl::Easy.new
41
13
  end
42
14
 
43
- def mock_twitter
44
- Curl::Easy.mock_body_str = %|{"results":[{"from_user_id_str":"220650275","profile_image_url":"http://a2.twimg.com/profile_images/668619338/9729_148876458070_505518070_2628895_7160219_n_normal.jpg","created_at":"Sat, 16 Jul 2011 23:20:01 +0000","from_user":"LoMuma","id_str":"92372947855093760","metadata":{"result_type":"recent"},"to_user_id":null,"text":"Need to stop procrastinating! 5 quizzes and personal responses due tomorrow... #fail","id":92372947855093760,"from_user_id":220650275,"geo":null,"iso_language_code":"en","to_user_id_str":null,"source":"&lt;a href=&quot;http://twitter.com/&quot;&gt;web&lt;/a&gt;"},{"from_user_id_str":"129718556","profile_image_url":"http://a2.twimg.com/profile_images/1428268221/twitter_normal.png","created_at":"Sat, 16 Jul 2011 23:20:01 +0000","from_user":"priiislopes","id_str":"92372947846692865","metadata":{"result_type":"recent"},"to_user_id":null,"text":"Esse jogo do Flu foi uma vergonha. Se ele fez o melhor dele no brasileiro semana passada, hj fez o pior de todos os tempos. #Fail","id":92372947846692865,"from_user_id":129718556,"geo":null,"iso_language_code":"pt","to_user_id_str":null,"source":"&lt;a href=&quot;http://twitter.com/&quot;&gt;web&lt;/a&gt;"},{"from_user_id_str":"259930166","profile_image_url":"http://a3.twimg.com/profile_images/1425221519/foto_normal.jpg","created_at":"Sat, 16 Jul 2011 23:20:00 +0000","from_user":"YamiiG4","id_str":"92372943132303360","metadata":{"result_type":"recent"},"to_user_id":null,"text":"vaya que eran 2 minutos..#FAIL!","id":92372943132303360,"from_user_id":259930166,"geo":null,"iso_language_code":"es","to_user_id_str":null,"source":"&lt;a href=&quot;http://www.tweetdeck.com&quot; rel=&quot;nofollow&quot;&gt;TweetDeck&lt;/a&gt;"},{"from_user_id_str":"321557905","profile_image_url":"http://a0.twimg.com/profile_images/1445672626/profile_normal.png","created_at":"Sat, 16 Jul 2011 23:20:00 +0000","from_user":"JasWafer_FFOE","id_str":"92372941379088384","metadata":{"result_type":"recent"},"to_user_id":null,"text":"RT @eye_OFBEHOLDER: RT @JasWafer_FFOE #Oomf said that he'll NEVER eat pussy! O.o --#FAIL","id":92372941379088384,"from_user_id":321557905,"geo":null,"iso_language_code":"en","to_user_id_str":null,"source":"&lt;a href=&quot;http://twidroyd.com&quot; rel=&quot;nofollow&quot;&gt;Twidroyd for Android&lt;/a&gt;"},{"from_user_id_str":"279395613","profile_image_url":"http://a0.twimg.com/profile_images/1334871419/lnnsquare_normal.jpg","created_at":"Sat, 16 Jul 2011 23:19:59 +0000","from_user":"LanguageNewsNet","id_str":"92372940640890881","metadata":{"result_type":"recent"},"to_user_id":null,"text":"Questioning the Inca Paradox: Did the civilization behind Machu Picchu really fail to develop a written la... http://tinyurl.com/5sfos23","id":92372940640890881,"from_user_id":279395613,"geo":null,"iso_language_code":"en","to_user_id_str":null,"source":"&lt;a href=&quot;http://twitterfeed.com&quot; rel=&quot;nofollow&quot;&gt;twitterfeed&lt;/a&gt;"}],"max_id":92372947855093760,"since_id":0,"refresh_url":"?since_id=92372947855093760&q=+fail","next_page":"?page=2&max_id=92372947855093760&rpp=5&q=+fail","results_per_page":5,"page":1,"completed_in":0.022152,"since_id_str":"0","max_id_str":"92372947855093760","query":"+fail"}|
15
+ def stub_bad_request
16
+ Curl::Easy.any_instance.stub(:body_str).and_return %|<html><title>400: Bad Request - Invalid URL format http://mopskopf</title><body>400: Bad Request - Invalid URL format http://mopskopf</body></html>|
17
+ Curl::Easy.any_instance.stub(:perform).and_return Curl::Easy.new
45
18
  end
46
19
 
47
- def mock_instagram
48
- Curl::Easy.mock_body_str = %|{"provider_url": "http://instagram.com/", "title": "Curse you tweets. See what you have done to me?!!!", "url": "http://distillery.s3.amazonaws.com/media/2011/05/02/d25df62b9cec4a138967a3ad027d055b_7.jpg", "author_name": "loswhit", "height": 612, "width": 612, "version": "1.0", "author_url": "http://instagram.com/", "provider_name": "Instagram", "type": "photo"}|
20
+ def stub_utf8_response
21
+ Curl::Easy.any_instance.stub(:body_str).and_return %|√∫ƒ® are inhabitänts of utf-8 wonderländ.|
22
+ Curl::Easy.any_instance.stub(:perform).and_return Curl::Easy.new
49
23
  end
50
24
 
51
- def mock_yfrog
52
- Curl::Easy.mock_body_str = %|{"version":"1.0","provider_name":"yFrog","provider_url":"http:\/\/yfrog.com","thumbnail_url":"http:\/\/yfrog.com\/h4vlfp:small","width":1210,"height":894,"type":"image","url":"http:\/\/img616.yfrog.com\/img616\/16\/vlf.png"}|
25
+ def stub_yfrog
26
+ Curl::Easy.any_instance.stub(:body_str).and_return %|{"version":"1.0","provider_name":"yFrog","provider_url":"http:\/\/yfrog.com","thumbnail_url":"http:\/\/yfrog.com\/h4vlfp:small","width":1210,"height":894,"type":"image","url":"http:\/\/img616.yfrog.com\/img616\/16\/vlf.png"}|
27
+ Curl::Easy.any_instance.stub(:perform).and_return Curl::Easy.new
53
28
  end
54
29
 
55
- def mock_picplz
56
- Curl::Easy.mock_body_str = %|{"result":"ok","value":{"pics":[{"city":{"url":"/city/los-angeles-ca/","id":27,"name":"Los Angeles, CA"},"creator":{"username":"lakers","display_name":"Los Angeles Lakers","following_count":8,"follower_count":2364,"id":216541,"icon":{"url":"http://s1.ui1.picplzthumbs.com/usericons/c7/46/be/c746bee5eb6926e71f46176fddbd3fc16fc9b198_meds.jpg","width":75,"height":75}},"url":"/user/lakers/pic/6rlcc/","pic_files":{"640r":{"width":640,"img_url":"http://s1.i1.picplzthumbs.com/upload/img/7c/54/a0/7c54a0a10d3e97bef7ac570e14f461b1836e9168_wmeg.jpg","height":478},"100sh":{"width":100,"img_url":"http://s1.i1.picplzthumbs.com/upload/img/7c/54/a0/7c54a0a10d3e97bef7ac570e14f461b1836e9168_t200s.jpg","height":100},"320rh":{"width":320,"img_url":"http://s1.i1.picplzthumbs.com/upload/img/7c/54/a0/7c54a0a10d3e97bef7ac570e14f461b1836e9168_mmed.jpg","height":239}},"view_count":10873,"caption":"The playoff logo down on the floor.","comment_count":2,"like_count":24,"place":{"url":"/pics/staples-center-los-angeles-ca/","id":17357,"name":"STAPLES Center"},"date":1303059128,"id":1662796}]}}|
30
+ def stub_picplz
31
+ Curl::Easy.any_instance.stub(:body_str).and_return %|{"result":"ok","value":{"pics":[{"city":{"url":"/city/los-angeles-ca/","id":27,"name":"Los Angeles, CA"},"creator":{"username":"lakers","display_name":"Los Angeles Lakers","following_count":8,"follower_count":2364,"id":216541,"icon":{"url":"http://s1.ui1.picplzthumbs.com/usericons/c7/46/be/c746bee5eb6926e71f46176fddbd3fc16fc9b198_meds.jpg","width":75,"height":75}},"url":"/user/lakers/pic/6rlcc/","pic_files":{"640r":{"width":640,"img_url":"http://s1.i1.picplzthumbs.com/upload/img/7c/54/a0/7c54a0a10d3e97bef7ac570e14f461b1836e9168_wmeg.jpg","height":478},"100sh":{"width":100,"img_url":"http://s1.i1.picplzthumbs.com/upload/img/7c/54/a0/7c54a0a10d3e97bef7ac570e14f461b1836e9168_t200s.jpg","height":100},"320rh":{"width":320,"img_url":"http://s1.i1.picplzthumbs.com/upload/img/7c/54/a0/7c54a0a10d3e97bef7ac570e14f461b1836e9168_mmed.jpg","height":239}},"view_count":10873,"caption":"The playoff logo down on the floor.","comment_count":2,"like_count":24,"place":{"url":"/pics/staples-center-los-angeles-ca/","id":17357,"name":"STAPLES Center"},"date":1303059128,"id":1662796}]}}|
32
+ Curl::Easy.any_instance.stub(:perform).and_return Curl::Easy.new
57
33
  end
58
34
 
59
- def mock_lockerz
60
- Curl::Easy.mock_body_str = %|{"BigImageUrl":"http:\/\/c0013763.cdn1.cloudfiles.rackspacecloud.com\/x2_5f9fc67","CommentCount":1,"DetailsUrl":"http:\/\/api.plixi.com\/api\/tpapi.svc\/json\/photos\/100269159","GdAlias":"100269159","Id":100269159,"LargeImageUrl":"http:\/\/c0013763.cdn1.cloudfiles.rackspacecloud.com\/x2_5f9fc67","LikedVotes":0,"Location":{"Latitude":0,"Longitude":0},"MediumImageUrl":"http:\/\/c0013764.cdn1.cloudfiles.rackspacecloud.com\/x2_5f9fc67","Message":"Her name is Tofoi Al Nasr , she Reps the future of Qatar. @ the Doha Forum, technology is the new Revolution! ","MobileImageUrl":"http:\/\/c0013765.cdn1.cloudfiles.rackspacecloud.com\/x2_5f9fc67","Name":"x2_5f9fc67","SmallImageUrl":"http:\/\/c0013766.cdn1.cloudfiles.rackspacecloud.com\/x2_5f9fc67","ThumbnailUrl":"http:\/\/c0013767.cdn1.cloudfiles.rackspacecloud.com\/x2_5f9fc67","TinyAlias":"100269159","TwitterStatusId":67672440125394944,"UnLikedVotes":0,"UploadDate":1304969336,"UploadDateString":"2011-05-09T19:28:56Z","UserId":1067006,"Views":9319,"Vote":null}|
35
+ def stub_lockerz
36
+ Curl::Easy.any_instance.stub(:body_str).and_return %|{"BigImageUrl":"http:\/\/c0013763.cdn1.cloudfiles.rackspacecloud.com\/x2_5f9fc67","CommentCount":1,"DetailsUrl":"http:\/\/api.plixi.com\/api\/tpapi.svc\/json\/photos\/100269159","GdAlias":"100269159","Id":100269159,"LargeImageUrl":"http:\/\/c0013763.cdn1.cloudfiles.rackspacecloud.com\/x2_5f9fc67","LikedVotes":0,"Location":{"Latitude":0,"Longitude":0},"MediumImageUrl":"http:\/\/c0013764.cdn1.cloudfiles.rackspacecloud.com\/x2_5f9fc67","Message":"Her name is Tofoi Al Nasr , she Reps the future of Qatar. @ the Doha Forum, technology is the new Revolution! ","MobileImageUrl":"http:\/\/c0013765.cdn1.cloudfiles.rackspacecloud.com\/x2_5f9fc67","Name":"x2_5f9fc67","SmallImageUrl":"http:\/\/c0013766.cdn1.cloudfiles.rackspacecloud.com\/x2_5f9fc67","ThumbnailUrl":"http:\/\/c0013767.cdn1.cloudfiles.rackspacecloud.com\/x2_5f9fc67","TinyAlias":"100269159","TwitterStatusId":67672440125394944,"UnLikedVotes":0,"UploadDate":1304969336,"UploadDateString":"2011-05-09T19:28:56Z","UserId":1067006,"Views":9319,"Vote":null}|
37
+ Curl::Easy.any_instance.stub(:perform).and_return Curl::Easy.new
61
38
  end
62
39
 
63
40
  #follow redirect lookups
64
41
 
65
- def mock_imgly
66
- Curl::Easy.mock_header_str = %|HTTP/1.1 302 Found
42
+ def stub_imgly
43
+ curl = Curl::Easy.new
44
+ Curl::Easy.any_instance.stub(:perform).and_return curl
45
+ Curl::Easy.stub!(:http_get).and_return curl
46
+ Curl::Easy.any_instance.stub(:header_str).and_return %|HTTP/1.1 302 Found
67
47
  Content-Type: text/html; charset=utf-8
68
48
  Connection: keep-alive
69
49
  Status: 302
@@ -77,8 +57,9 @@ Server: nginx/1.0.0 + Phusion Passenger 3.0.7 (mod_rails/mod_rack)
77
57
  |
78
58
  end
79
59
 
80
- def mock_twitpic
81
- Curl::Easy.mock_header_str = %|HTTP/1.1 302 Moved Temporarily
60
+ def stub_twitpic
61
+ Curl::Easy.any_instance.stub(:perform).and_return Curl::Easy.new
62
+ Curl::Easy.any_instance.stub(:header_str).and_return %|HTTP/1.1 302 Moved Temporarily
82
63
  Server: nginx
83
64
  Date: Sun, 17 Jul 2011 01:03:43 GMT
84
65
  Content-Type: image/jpeg
@@ -94,8 +75,9 @@ Location: http://s3.amazonaws.com/twitpic/photos/full/249034281.jpg?AWSAccessKey
94
75
  |
95
76
  end
96
77
 
97
- def mock_tco
98
- Curl::Easy.mock_header_str = %|HTTP/1.1 301 Moved Permanently
78
+ def stub_tco
79
+ Curl::Easy.any_instance.stub(:perform).and_return Curl::Easy.new
80
+ Curl::Easy.any_instance.stub(:header_str).and_return %|HTTP/1.1 301 Moved Permanently
99
81
  Date: Sun, 17 Jul 2011 01:03:51 GMT
100
82
  Server: hi
101
83
  Location: http://yfrog.com/h0m3vpj
@@ -106,15 +88,17 @@ Connection: close
106
88
  Content-Type: text/html; charset=UTF-8
107
89
 
108
90
  |
109
- mock_yfrog
91
+ stub_yfrog
110
92
  end
111
93
 
112
94
  #embedly powered lookups
113
95
 
114
- def mock_foursquare
115
- Curl::Easy.mock_body_str = %|{"provider_url": "http://foursquare.com", "description": "See where your friends are, learn about the places they frequent, and unlock rewards as you travel. 8555 Fletcher PkwyLa Mesa, CA 91942(619) 589-0071", "title": "Matt S. checked in at Banbu Sushi Bar And Grill", "url": "https://playfoursquare.s3.amazonaws.com/pix/PNIBDBIPP5G2XGROCZXVCOHABOZP4MICHZVPJWZXZWAN3SEQ.jpg", "author_name": "Matt S.", "height": 345, "width": 460, "thumbnail_url": "https://playfoursquare.s3.amazonaws.com/pix/PNIBDBIPP5G2XGROCZXVCOHABOZP4MICHZVPJWZXZWAN3SEQ.jpg", "thumbnail_width": 460, "version": "1.0", "provider_name": "Foursquare", "type": "photo", "thumbnail_height": 345, "author_url": "https://foursquare.com/mjstraus"}|
96
+ def stub_foursquare
97
+ Curl::Easy.any_instance.stub(:body_str).and_return %|{"provider_url": "http://foursquare.com", "description": "See where your friends are, learn about the places they frequent, and unlock rewards as you travel. 8555 Fletcher PkwyLa Mesa, CA 91942(619) 589-0071", "title": "Matt S. checked in at Banbu Sushi Bar And Grill", "url": "https://playfoursquare.s3.amazonaws.com/pix/PNIBDBIPP5G2XGROCZXVCOHABOZP4MICHZVPJWZXZWAN3SEQ.jpg", "author_name": "Matt S.", "height": 345, "width": 460, "thumbnail_url": "https://playfoursquare.s3.amazonaws.com/pix/PNIBDBIPP5G2XGROCZXVCOHABOZP4MICHZVPJWZXZWAN3SEQ.jpg", "thumbnail_width": 460, "version": "1.0", "provider_name": "Foursquare", "type": "photo", "thumbnail_height": 345, "author_url": "https://foursquare.com/mjstraus"}|
98
+ Curl::Easy.any_instance.stub(:perform).and_return Curl::Easy.new
116
99
  end
117
100
 
118
- def mock_embedly
119
- Curl::Easy.mock_body_str = %|{"provider_url": "http://www.flickr.com/", "description": "Lady GaGa", "title": "Lady GaGa", "url": "http://farm6.static.flickr.com/5204/5319200155_c966f67dc3.jpg", "author_name": "mjcom18", "height": 468, "width": 307, "thumbnail_url": "http://farm6.static.flickr.com/5204/5319200155_c966f67dc3_t.jpg", "thumbnail_width": 66, "version": "1.0", "provider_name": "Flickr", "cache_age": 3600, "type": "photo", "thumbnail_height": 100, "author_url": "http://www.flickr.com/photos/57795463@N05/"}|
101
+ def stub_embedly
102
+ Curl::Easy.any_instance.stub(:body_str).and_return %|{"provider_url": "http://www.flickr.com/", "description": "Lady GaGa", "title": "Lady GaGa", "url": "http://farm6.static.flickr.com/5204/5319200155_c966f67dc3.jpg", "author_name": "mjcom18", "height": 468, "width": 307, "thumbnail_url": "http://farm6.static.flickr.com/5204/5319200155_c966f67dc3_t.jpg", "thumbnail_width": 66, "version": "1.0", "provider_name": "Flickr", "cache_age": 3600, "type": "photo", "thumbnail_height": 100, "author_url": "http://www.flickr.com/photos/57795463@N05/"}|
103
+ Curl::Easy.any_instance.stub(:perform).and_return Curl::Easy.new
120
104
  end
data/spec/tweetlr_spec.rb CHANGED
@@ -7,10 +7,10 @@ describe Tweetlr do
7
7
  USER = config['tumblr_username']
8
8
  PW = config['tumblr_password']
9
9
  TIMESTAMP = config['twitter_timestamp']
10
+ WHITELIST = config['whitelist']
10
11
 
11
12
  before :each do
12
13
  @credentials = {:email => USER, :password => PW}
13
- @cookie = "tmgioct=as3u4KJr9COyJA9j4nwr6ZAn"
14
14
  @searchterm = 'fail'
15
15
  @twitter_response = {"from_user_id_str"=>"1915714", "profile_image_url"=>"http://a0.twimg.com/profile_images/386000279/2_normal.jpg", "created_at"=>"Sun, 17 Apr 2011 16:48:42 +0000", "from_user"=>"whitey_Mc_whIteLIst", "id_str"=>"59659561224765440", "metadata"=>{"result_type"=>"recent"}, "to_user_id"=>nil, "text"=>"Rigaer #wirsounterwegs @ Augenarzt Dr. Lierow http://instagr.am/p/DzCWn/", "id"=>59659561224765440, "from_user_id"=>1915714, "geo"=>{"type"=>"Point", "coordinates"=>[52.5182, 13.454]}, "iso_language_code"=>"de", "place"=>{"id"=>"3078869807f9dd36", "type"=>"city", "full_name"=>"Berlin, Berlin"}, "to_user_id_str"=>nil, "source"=>"&lt;a href=&quot;http://instagr.am&quot; rel=&quot;nofollow&quot;&gt;instagram&lt;/a&gt;"}
16
16
  @non_whitelist_tweet = @twitter_response.merge 'from_user' => 'nonwhitelist user'
@@ -29,19 +29,17 @@ describe Tweetlr do
29
29
  }
30
30
  @pic_regexp = /(.*?)\.(jpg|jpeg|png|gif)$/i
31
31
  @config_file = File.join( Dir.pwd, 'config', 'tweetlr.yml')
32
- @tweetlr = Tweetlr.new(USER, PW, @config_file, {:results_per_page => 5, :since_id => TIMESTAMP, :terms => @searchterm, :loglevel => 4, :cookie => @cookie})
33
- mock_reset
32
+ @tweetlr = Tweetlr.new(USER, PW, {:whitelist => WHITELIST, :results_per_page => 5, :since_id => TIMESTAMP, :terms => @searchterm, :loglevel => 4, :cookie => @cookie})
34
33
  end
35
34
  # it "should post to tumblr" do
36
- # tweetlr = Tweetlr.new @credentials[:email], @credentials[:password], @cookie, nil, @searchterm, @config_file
37
- # tumblr_post = tweetlr.generate_tumblr_photo_post @twitter_response
35
+ # tumblr_post = @tweetlr.generate_tumblr_photo_post @twitter_response
38
36
  # tumblr_post[:date] = Time.now.to_s
39
- # response = tweetlr.post_to_tumblr tumblr_post
37
+ # response = @tweetlr.post_to_tumblr tumblr_post
40
38
  # response.should be
41
39
  # response.response_code.should be 201
42
40
  # end
43
41
  it "should search twitter for a given term" do
44
- mock_twitter
42
+ stub_twitter
45
43
  tweetlr = @tweetlr
46
44
  response = tweetlr.search_twitter
47
45
  tweets = response['results']
@@ -49,12 +47,12 @@ describe Tweetlr do
49
47
  tweets.should_not be_empty
50
48
  end
51
49
  it "should mark whitelist users' tweets as published" do
52
- mock_instagram
50
+ stub_instagram
53
51
  post = @tweetlr.generate_tumblr_photo_post @twitter_response
54
52
  post[:state].should == 'published'
55
53
  end
56
54
  it "should mark non whitelist users' tweets as drafts" do
57
- mock_instagram
55
+ stub_instagram
58
56
  post = @tweetlr.generate_tumblr_photo_post @non_whitelist_tweet
59
57
  post[:state].should == 'draft'
60
58
  end
@@ -69,18 +67,18 @@ describe Tweetlr do
69
67
  describe "image url processing" do
70
68
  it "should find a picture's url from the supported services" do
71
69
  @links.each do |key,value|
72
- send "mock_#{key}"
70
+ send "stub_#{key}"
73
71
  url = @tweetlr.find_image_url value
74
72
  url.should be, "service #{key} not working!"
75
73
  check_pic_url_extraction key if [:instagram,:picplz,:yfrog,:imgly,:foursquare,:not_listed].index key
76
74
  end
77
75
  end
78
76
  it "should not crash if embedly fallback won't find a link" do
79
- mock_bad_request
77
+ stub_bad_request
80
78
  url = @tweetlr.find_image_url "http://mopskopf"
81
79
  end
82
80
  it "should not crash with an encoding error when response is non-us-ascii" do
83
- mock_utf8_response
81
+ stub_utf8_response
84
82
  url = @tweetlr.find_image_url "http://api.instagram.com/oembed?url=http://instagr.am/p/Gx%E2%80%946/"
85
83
  end
86
84
  end
@@ -93,7 +91,7 @@ describe Tweetlr do
93
91
  link.should == @links[:instagram].chop
94
92
  end
95
93
  it "follows redirects" do
96
- mock_imgly
94
+ stub_imgly
97
95
  link = @tweetlr.link_url_redirect 'im mocked anyways'
98
96
  link.should == 'http://s3.amazonaws.com/imgly_production/899582/full.jpg'
99
97
  end
data/tweetlr.gemspec CHANGED
@@ -1,9 +1,9 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "tweetlr"
3
- s.version = "0.1.4pre4"
3
+ s.version = "0.1.5"
4
4
  s.author = "Sven Kraeuter"
5
- s.email = "mail@svenkraeuter.com"
6
- s.homepage = "http://github.com/5v3n/#{s.name}"
5
+ s.email = "sven.kraeuter@gmail.com"
6
+ s.homepage = "http://tweetlr.5v3n.com"
7
7
  s.summary = "tweetlr crawls twitter for a given term, extracts photos out of the collected tweets' short urls and posts the images to tumblr."
8
8
  s.description = s.summary
9
9
 
metadata CHANGED
@@ -1,20 +1,19 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tweetlr
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4pre4
5
- prerelease: 5
4
+ version: 0.1.5
5
+ prerelease:
6
6
  platform: ruby
7
7
  authors:
8
8
  - Sven Kraeuter
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-08-18 00:00:00.000000000 +02:00
13
- default_executable:
12
+ date: 2011-10-04 00:00:00.000000000Z
14
13
  dependencies:
15
14
  - !ruby/object:Gem::Dependency
16
15
  name: daemons
17
- requirement: &2157352460 !ruby/object:Gem::Requirement
16
+ requirement: &2153779740 !ruby/object:Gem::Requirement
18
17
  none: false
19
18
  requirements:
20
19
  - - ! '>='
@@ -22,10 +21,10 @@ dependencies:
22
21
  version: '0'
23
22
  type: :runtime
24
23
  prerelease: false
25
- version_requirements: *2157352460
24
+ version_requirements: *2153779740
26
25
  - !ruby/object:Gem::Dependency
27
26
  name: eventmachine
28
- requirement: &2157352040 !ruby/object:Gem::Requirement
27
+ requirement: &2153805660 !ruby/object:Gem::Requirement
29
28
  none: false
30
29
  requirements:
31
30
  - - ! '>='
@@ -33,10 +32,10 @@ dependencies:
33
32
  version: '0'
34
33
  type: :runtime
35
34
  prerelease: false
36
- version_requirements: *2157352040
35
+ version_requirements: *2153805660
37
36
  - !ruby/object:Gem::Dependency
38
37
  name: curb
39
- requirement: &2157351620 !ruby/object:Gem::Requirement
38
+ requirement: &2153805240 !ruby/object:Gem::Requirement
40
39
  none: false
41
40
  requirements:
42
41
  - - ! '>='
@@ -44,10 +43,10 @@ dependencies:
44
43
  version: '0'
45
44
  type: :runtime
46
45
  prerelease: false
47
- version_requirements: *2157351620
46
+ version_requirements: *2153805240
48
47
  - !ruby/object:Gem::Dependency
49
48
  name: json
50
- requirement: &2157351200 !ruby/object:Gem::Requirement
49
+ requirement: &2153804820 !ruby/object:Gem::Requirement
51
50
  none: false
52
51
  requirements:
53
52
  - - ! '>='
@@ -55,10 +54,10 @@ dependencies:
55
54
  version: '0'
56
55
  type: :runtime
57
56
  prerelease: false
58
- version_requirements: *2157351200
57
+ version_requirements: *2153804820
59
58
  - !ruby/object:Gem::Dependency
60
59
  name: rake
61
- requirement: &2157350700 !ruby/object:Gem::Requirement
60
+ requirement: &2153804320 !ruby/object:Gem::Requirement
62
61
  none: false
63
62
  requirements:
64
63
  - - ~>
@@ -66,10 +65,10 @@ dependencies:
66
65
  version: 0.8.7
67
66
  type: :development
68
67
  prerelease: false
69
- version_requirements: *2157350700
68
+ version_requirements: *2153804320
70
69
  - !ruby/object:Gem::Dependency
71
70
  name: rspec
72
- requirement: &2157350280 !ruby/object:Gem::Requirement
71
+ requirement: &2153803900 !ruby/object:Gem::Requirement
73
72
  none: false
74
73
  requirements:
75
74
  - - ! '>='
@@ -77,10 +76,10 @@ dependencies:
77
76
  version: '0'
78
77
  type: :development
79
78
  prerelease: false
80
- version_requirements: *2157350280
79
+ version_requirements: *2153803900
81
80
  - !ruby/object:Gem::Dependency
82
81
  name: rdoc
83
- requirement: &2157349820 !ruby/object:Gem::Requirement
82
+ requirement: &2153803440 !ruby/object:Gem::Requirement
84
83
  none: false
85
84
  requirements:
86
85
  - - ! '>='
@@ -88,10 +87,10 @@ dependencies:
88
87
  version: '0'
89
88
  type: :development
90
89
  prerelease: false
91
- version_requirements: *2157349820
90
+ version_requirements: *2153803440
92
91
  description: tweetlr crawls twitter for a given term, extracts photos out of the collected
93
92
  tweets' short urls and posts the images to tumblr.
94
- email: mail@svenkraeuter.com
93
+ email: sven.kraeuter@gmail.com
95
94
  executables:
96
95
  - tweetlr
97
96
  extensions: []
@@ -113,8 +112,7 @@ files:
113
112
  - spec/spec_helper.rb
114
113
  - spec/tweetlr_spec.rb
115
114
  - tweetlr.gemspec
116
- has_rdoc: true
117
- homepage: http://github.com/5v3n/tweetlr
115
+ homepage: http://tweetlr.5v3n.com
118
116
  licenses: []
119
117
  post_install_message:
120
118
  rdoc_options: []
@@ -129,12 +127,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
129
127
  required_rubygems_version: !ruby/object:Gem::Requirement
130
128
  none: false
131
129
  requirements:
132
- - - ! '>'
130
+ - - ! '>='
133
131
  - !ruby/object:Gem::Version
134
- version: 1.3.1
132
+ version: '0'
135
133
  requirements: []
136
134
  rubyforge_project: tweetlr
137
- rubygems_version: 1.6.2
135
+ rubygems_version: 1.8.10
138
136
  signing_key:
139
137
  specification_version: 3
140
138
  summary: tweetlr crawls twitter for a given term, extracts photos out of the collected