tweetlr 0.1.17pre → 0.1.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/bin/tweetlr CHANGED
@@ -21,11 +21,14 @@ begin
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
22
 
23
23
  UPDATE_PERIOD = CONFIG['update_period']
24
-
24
+
25
25
  @tweetlr_config = {
26
- :tumblr_email => CONFIG['tumblr_username'],
27
- :tumblr_password => CONFIG['tumblr_password'],
28
- :group => CONFIG['group'],
26
+ :tumblr_blog_hostname => CONFIG['tumblr_blog_hostname'] || CONFIG['group'],
27
+ :tumblr_oauth_api_key => CONFIG['tumblr_oauth_api_key'],
28
+ :tumblr_oauth_api_secret => CONFIG['tumblr_oauth_api_secret'],
29
+ :tumblr_blog_hostname => CONFIG['tumblr_blog_hostname'],
30
+ :tumblr_oauth_access_token_key => CONFIG['tumblr_oauth_access_token_key'],
31
+ :tumblr_oauth_access_token_secret => CONFIG['tumblr_oauth_access_token_secret'],
29
32
  :whitelist => CONFIG['whitelist'],
30
33
  :shouts => CONFIG['shouts'],
31
34
  :since_id => CONFIG['start_at_tweet_id'] ,
@@ -46,7 +49,7 @@ end
46
49
  Daemons.run_proc('tweetlr', :dir_mode => :script, :dir => './', :backtrace => true, :log_output => true) do
47
50
  @log = Logger.new(STDOUT)
48
51
  @log.info "starting tweetlr daemon..."
49
- @log.info "creating a new tweetlr instance using this config: #{CONFIG.inspect}"
52
+ @log.info "creating a new tweetlr instance using this config: #{@tweetlr_config.inspect}"
50
53
  EventMachine::run do
51
54
  EventMachine::add_periodic_timer( UPDATE_PERIOD ) do
52
55
  response = Tweetlr.crawl(@tweetlr_config)
data/config/tweetlr.yml CHANGED
@@ -4,8 +4,11 @@ search_term: 'cat+dog+unicorn' #find tweets containing any of these terms
4
4
  start_at_tweet_id: 61847783463854082 # the tweet id to start searching at
5
5
  api_endpoint_twitter: 'http://search.twitter.com/search.json'
6
6
  api_endpoint_tumblr: 'http://www.tumblr.com'
7
- tumblr_username: YOUR_TUMBLR_EMAIL
8
- tumblr_password: YOUR_TUMBLR_PW
7
+ tumblr_oauth_api_key: YOUR APPS TUMBLR API TOKEN
8
+ tumblr_oauth_api_secret: YOUR APPS TUMBLR API SECRET
9
+ tumblr_oauth_access_token_key: YOUR BLOGS OAUTH ACCESS TOKEN KEY
10
+ tumblr_oauth_access_token_secret: YOUR BLOGS OAUTH ACCESS TOKEN SECRE
11
+ group: TUMBLR_GROUP_TO_POST_TO #e.g. mysubblog.tumblr.com
9
12
  embedly_key: '' #tweetlr uses http://embedly.com for link processing. a free plan containing an api key is available & recommended to use in order to ensure full support
10
13
  update_period: 300 #check for updates every 300 secs = 5 minutes
11
14
  shouts: 'says' # will be concatenated after the username, before the message: @mr_x says: awesome things on a photo!
@@ -32,7 +32,7 @@ module Combinators
32
32
  if !Processors::Twitter::retweet? message
33
33
  log.debug "tweet: #{tweet}"
34
34
  tumblr_post = {}
35
- tumblr_post[:group] = options[:group]
35
+ tumblr_post[:tumblr_blog_hostname] = options[:tumblr_blog_hostname] || options[:group]
36
36
  tumblr_post[:type] = 'photo'
37
37
  tumblr_post[:date] = tweet['created_at']
38
38
  tumblr_post[:source] = extract_image_url tweet, options[:embedly_key]
@@ -1,4 +1,5 @@
1
1
  require 'log_aware'
2
+ require 'oauth'
2
3
 
3
4
  module Processors
4
5
  #utilities for handling tumblr
@@ -11,38 +12,40 @@ module Processors
11
12
  end
12
13
  #post a tumblr photo entry.
13
14
  #
14
- #required arguments are :email, :password, :type, :date, :source, :caption, :state, :source
15
+ #required arguments are :tumblr_blog_hostname, :tumblr_blog_hostname, :tumblr_oauth_api_secret, :tumblr_oauth_access_token_secret, :source, :caption, :state
15
16
  #
16
- #optional arguments: :api_endpoint_tumblr, :tags, :group
17
+ #optional arguments: :tags, :type (default: 'photo')
17
18
  #
18
19
  def self.post(options={})
19
- tries = 3
20
- tags = options[:tags] || ''
21
- group = options[:group] || ''
22
- begin
23
- response = Curl::Easy.http_post("#{options[:api_endpoint_tumblr] || API_ENDPOINT_TUMBLR}/api/write",
24
- Curl::PostField.content('generator', GENERATOR),
25
- Curl::PostField.content('email', options[:email]),
26
- Curl::PostField.content('password', options[:password]),
27
- Curl::PostField.content('type', options[:type]),
28
- Curl::PostField.content('date', options[:date]),
29
- Curl::PostField.content('source', options[:source]),
30
- Curl::PostField.content('caption', options[:caption]),
31
- Curl::PostField.content('state', options[:state]),
32
- Curl::PostField.content('tags', tags),
33
- Curl::PostField.content('group', group)
34
- )
35
- rescue Curl::Err::CurlError => err
36
- log.error "Failure in Curl call: #{err}"
37
- tries -= 1
38
- sleep 3
39
- if tries > 0
40
- retry
41
- else
42
- response = nil
43
- end
44
- end
45
- response
20
+ base_hostname = options[:tumblr_blog_hostname] || options[:group]
21
+ tumblr_oauth_api_key= options[:tumblr_oauth_api_key]
22
+ tumblr_oauth_api_secret= options[:tumblr_oauth_api_secret]
23
+ access_token_key = options[:tumblr_oauth_access_token_key]
24
+ access_token_secret = options[:tumblr_oauth_access_token_secret]
25
+ type = options[:type] || 'photo'
26
+ tags = options[:tags] || ''
27
+
28
+ consumer = OAuth::Consumer.new(tumblr_oauth_api_key, tumblr_oauth_api_secret,
29
+ { :site => 'http://www.tumblr.com',
30
+ :request_token_path => '/oauth/request_token',
31
+ :authorize_path => '/oauth/authorize',
32
+ :access_token_path => '/oauth/access_token',
33
+ :http_method => :post } )
34
+
35
+ access_token = OAuth::AccessToken.new(consumer, access_token_key, access_token_secret)
36
+
37
+ post_response = access_token.post(
38
+ "http://api.tumblr.com/v2/blog/#{base_hostname}/post", {
39
+ :type => type,
40
+ :source => options[:source],
41
+ :caption => options[:caption],
42
+ :date => options[:date],
43
+ :tags => tags,
44
+ :state => options[:state],
45
+ :generator => GENERATOR
46
+ }
47
+ )
48
+ post_response
46
49
  end
47
50
  end
48
51
  end
data/lib/tweetlr.rb CHANGED
@@ -9,7 +9,7 @@ require 'uri'
9
9
 
10
10
  class Tweetlr
11
11
 
12
- VERSION = '0.1.17pre'
12
+ VERSION = '0.1.17'
13
13
 
14
14
  API_ENDPOINT_TWITTER = 'http://search.twitter.com/search.json'
15
15
  API_ENDPOINT_TUMBLR = 'http://www.tumblr.com'
@@ -53,6 +53,13 @@ class Tweetlr
53
53
  :result_type => config[:result_type] || TWITTER_RESULTS_TYPE,
54
54
  :api_endpoint_twitter => config[:api_endpoint_twitter] || API_ENDPOINT_TWITTER
55
55
  }
56
+ tumblr_config = { :tumblr_oauth_access_token_key => config[:tumblr_oauth_access_token_key],
57
+ :tumblr_oauth_access_token_secret => config[:tumblr_oauth_access_token_secret],
58
+ :tumblr_oauth_api_key => config[:tumblr_oauth_api_key],
59
+ :tumblr_oauth_api_secret => config[:tumblr_oauth_api_secret],
60
+ :tumblr_blog_hostname => config[:tumblr_blog_hostname] || config[:group]
61
+ }
62
+
56
63
  twitter_config[:search_term] = URI::escape(twitter_config[:search_term]) if twitter_config[:search_term]
57
64
  log.info "starting tweetlr crawl..."
58
65
  response = {}
@@ -66,8 +73,8 @@ class Tweetlr
66
73
  log.warn "could not get image source: tweet: #{tweet} --- tumblr post: #{tumblr_post.inspect}"
67
74
  else
68
75
  log.debug "tumblr post: #{tumblr_post}"
69
- res = Processors::Tumblr.post tumblr_post.merge({:password => config[:tumblr_password], :email => config[:tumblr_email]})
70
- log.warn "tumblr response: #{res.header_str} #{res.body_str}" unless res.response_code == 201
76
+ res = Processors::Tumblr.post tumblr_post.merge(tumblr_config)
77
+ log.warn "tumblr response: #{res.header} #{res.body}" unless res.code == "201"
71
78
  end
72
79
  end
73
80
  # store the highest tweet id
@@ -96,16 +96,17 @@ describe Combinators::TwitterTumblr do
96
96
  end
97
97
  end
98
98
  context "copes with different tumblelogs namely" do
99
- it "uses the main blog as default" do
99
+ it "uses a given blog via group option to post to" do
100
100
  stub_instagram
101
- tumblr_post = Combinators::TwitterTumblr.generate_photo_post_from_tweet @twitter_response, :whitelist => @whitelist
102
- tumblr_post[:group].should_not be
101
+ desired_group = 'mygroup.tumblr.com'
102
+ tumblr_post = Combinators::TwitterTumblr.generate_photo_post_from_tweet @twitter_response, {:whitelist => @whitelist, :group => desired_group}
103
+ tumblr_post[:tumblr_blog_hostname].should eq desired_group
103
104
  end
104
- it "uses a given sub-log (aka group)" do
105
+ it "uses a given blog via tumblr_blog_hostname to post to" do
105
106
  stub_instagram
106
107
  desired_group = 'mygroup.tumblr.com'
107
- tumblr_post = Combinators::TwitterTumblr.generate_photo_post_from_tweet @twitter_response, {:whitelist => @whitelist, :group => desired_group}
108
- tumblr_post[:group].should eq desired_group
108
+ tumblr_post = Combinators::TwitterTumblr.generate_photo_post_from_tweet @twitter_response, {:whitelist => @whitelist, :tumblr_blog_hostname => desired_group}
109
+ tumblr_post[:tumblr_blog_hostname].should eq desired_group
109
110
  end
110
111
  end
111
112
  end
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ describe Processors::Tumblr do
4
+ before :all do
5
+ config_file = File.join( Dir.pwd, 'config', 'tweetlr.yml')
6
+ config = YAML.load_file(config_file)
7
+ @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 #{@first_link} @ Augenarzt Dr. Lierow #{@second_link} #{@third_link}", "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"=>"<a href="http://instagr.am" rel="nofollow">instagram</a>"}
8
+ @tweetlr_config = {
9
+ :since_id => 0,
10
+ :search_term => 'moped',
11
+ :results_per_page => 100,
12
+ :result_type => 'recent',
13
+ :api_endpoint_twitter => Tweetlr::API_ENDPOINT_TWITTER,
14
+ :tumblr_oauth_api_key => config['tumblr_oauth_api_key'],
15
+ :tumblr_oauth_api_secret => config['tumblr_oauth_api_secret'],
16
+ :tumblr_blog_hostname => config['tumblr_blog_hostname'],
17
+ :tumblr_oauth_access_token_key => config['tumblr_oauth_access_token_key'],
18
+ :tumblr_oauth_access_token_secret => config['tumblr_oauth_access_token_secret']
19
+ }
20
+ end
21
+ it "posts to tumblr" do
22
+ stub_tumblr
23
+ stub_oauth
24
+ tumblr_post = Combinators::TwitterTumblr::generate_photo_post_from_tweet @twitter_response, @tweetlr_config
25
+ tumblr_post[:date] = Time.now.to_s
26
+ tumblr_post[:source] = 'http://distilleryimage6.instagram.com/db72627effde11e1b3f322000a1e8899_7.jpg'
27
+ response = Processors::Tumblr::post @tweetlr_config.merge(tumblr_post)
28
+ response.should be
29
+ response.code.should == "201"
30
+ end
31
+ end
data/spec/spec_helper.rb CHANGED
@@ -12,6 +12,10 @@ def check_pic_url_extraction(service)
12
12
  image_url.should =~ Processors::PhotoService::PIC_REGEXP
13
13
  end
14
14
 
15
+ def stub_oauth
16
+ OAuth::AccessToken.any_instance.stub(:post).and_return(Net::HTTPCreated.new("Created.", "201", nil))
17
+ end
18
+
15
19
  def stub_tumblr
16
20
  Curl::Easy.any_instance.stub(:response_code).and_return 201
17
21
  Curl::Easy.any_instance.stub(:header_str).and_return %|HTTP/1.1 201 Created
data/spec/tweetlr_spec.rb CHANGED
@@ -4,8 +4,6 @@ describe Tweetlr do
4
4
 
5
5
  config_file = File.join( Dir.pwd, 'config', 'tweetlr.yml')
6
6
  config = YAML.load_file(config_file)
7
- USER = config['tumblr_username']
8
- PW = config['tumblr_password']
9
7
  TIMESTAMP = config['twitter_timestamp']
10
8
  WHITELIST = config['whitelist']
11
9
 
@@ -15,9 +13,6 @@ describe Tweetlr do
15
13
  @third_link = "https://imageurl.com"
16
14
  @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 #{@first_link} @ Augenarzt Dr. Lierow #{@second_link} #{@third_link}", "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"=>"<a href="http://instagr.am" rel="nofollow">instagram</a>"}
17
15
  @tweetlr_config = {
18
- :tumblr_email => USER,
19
- :tumblr_pw => PW,
20
- :whitelist => WHITELIST,
21
16
  :since_id => 0,
22
17
  :search_term => 'moped',
23
18
  :results_per_page => 100,
@@ -25,19 +20,9 @@ describe Tweetlr do
25
20
  :api_endpoint_twitter => Tweetlr::API_ENDPOINT_TWITTER
26
21
  }
27
22
  end
28
- it "should post to tumblr" do
29
- stub_tumblr
30
- tumblr_post = Combinators::TwitterTumblr::generate_photo_post_from_tweet @twitter_response
31
- tumblr_post[:date] = Time.now.to_s
32
- response = Processors::Tumblr::post tumblr_post.merge({:email => USER, :password => PW})
33
- response.should be
34
- response.response_code.should be 201
35
- end
36
23
  it "crawls twitter and posts to tumblr" do
37
24
  stub_tumblr
38
25
  stub_twitter
39
26
  Tweetlr.crawl(@tweetlr_config)
40
27
  end
41
-
42
-
43
28
  end
data/tweetlr.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "tweetlr"
3
- s.version = "0.1.17pre"
3
+ s.version = "0.1.17"
4
4
  s.author = "Sven Kraeuter"
5
5
  s.email = "sven.kraeuter@gmail.com"
6
6
  s.homepage = "http://tweetlr.5v3n.com"
@@ -15,6 +15,7 @@ Gem::Specification.new do |s|
15
15
  s.add_dependency "curb"
16
16
  s.add_dependency "json"
17
17
  s.add_dependency "nokogiri"
18
+ s.add_dependency "oauth"
18
19
 
19
20
  s.add_development_dependency "rake"
20
21
  s.add_development_dependency "rspec"
metadata CHANGED
@@ -1,19 +1,19 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tweetlr
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.17pre
5
- prerelease: 6
4
+ version: 0.1.17
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: 2012-09-10 00:00:00.000000000 Z
12
+ date: 2012-09-16 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: daemons
16
- requirement: &2152750420 !ruby/object:Gem::Requirement
16
+ requirement: &2160430840 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *2152750420
24
+ version_requirements: *2160430840
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: eventmachine
27
- requirement: &2152749860 !ruby/object:Gem::Requirement
27
+ requirement: &2160430180 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *2152749860
35
+ version_requirements: *2160430180
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: curb
38
- requirement: &2152749440 !ruby/object:Gem::Requirement
38
+ requirement: &2160429480 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *2152749440
46
+ version_requirements: *2160429480
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: json
49
- requirement: &2152748880 !ruby/object:Gem::Requirement
49
+ requirement: &2160429020 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '0'
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *2152748880
57
+ version_requirements: *2160429020
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: nokogiri
60
- requirement: &2152748460 !ruby/object:Gem::Requirement
60
+ requirement: &2160428580 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,10 +65,21 @@ dependencies:
65
65
  version: '0'
66
66
  type: :runtime
67
67
  prerelease: false
68
- version_requirements: *2152748460
68
+ version_requirements: *2160428580
69
+ - !ruby/object:Gem::Dependency
70
+ name: oauth
71
+ requirement: &2160428140 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :runtime
78
+ prerelease: false
79
+ version_requirements: *2160428140
69
80
  - !ruby/object:Gem::Dependency
70
81
  name: rake
71
- requirement: &2152748040 !ruby/object:Gem::Requirement
82
+ requirement: &2160427720 !ruby/object:Gem::Requirement
72
83
  none: false
73
84
  requirements:
74
85
  - - ! '>='
@@ -76,10 +87,10 @@ dependencies:
76
87
  version: '0'
77
88
  type: :development
78
89
  prerelease: false
79
- version_requirements: *2152748040
90
+ version_requirements: *2160427720
80
91
  - !ruby/object:Gem::Dependency
81
92
  name: rspec
82
- requirement: &2152747620 !ruby/object:Gem::Requirement
93
+ requirement: &2160427240 !ruby/object:Gem::Requirement
83
94
  none: false
84
95
  requirements:
85
96
  - - ! '>='
@@ -87,10 +98,10 @@ dependencies:
87
98
  version: '0'
88
99
  type: :development
89
100
  prerelease: false
90
- version_requirements: *2152747620
101
+ version_requirements: *2160427240
91
102
  - !ruby/object:Gem::Dependency
92
103
  name: rdoc
93
- requirement: &2152747180 !ruby/object:Gem::Requirement
104
+ requirement: &2160426820 !ruby/object:Gem::Requirement
94
105
  none: false
95
106
  requirements:
96
107
  - - ! '>='
@@ -98,7 +109,7 @@ dependencies:
98
109
  version: '0'
99
110
  type: :development
100
111
  prerelease: false
101
- version_requirements: *2152747180
112
+ version_requirements: *2160426820
102
113
  description: tweetlr crawls twitter for a given term, extracts photos out of the collected
103
114
  tweets' short urls and posts the images to tumblr.
104
115
  email: sven.kraeuter@gmail.com
@@ -128,6 +139,7 @@ files:
128
139
  - lib/tweetlr.rb
129
140
  - spec/combinators/twitter_tumblr_combinator_spec.rb
130
141
  - spec/processors/photo_services_processor_spec.rb
142
+ - spec/processors/tumblr_processor_spec.rb
131
143
  - spec/processors/twitter_processor_spec.rb
132
144
  - spec/spec_helper.rb
133
145
  - spec/tweetlr_spec.rb
@@ -147,9 +159,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
147
159
  required_rubygems_version: !ruby/object:Gem::Requirement
148
160
  none: false
149
161
  requirements:
150
- - - ! '>'
162
+ - - ! '>='
151
163
  - !ruby/object:Gem::Version
152
- version: 1.3.1
164
+ version: '0'
153
165
  requirements: []
154
166
  rubyforge_project: tweetlr
155
167
  rubygems_version: 1.8.16
@@ -160,6 +172,7 @@ summary: tweetlr crawls twitter for a given term, extracts photos out of the col
160
172
  test_files:
161
173
  - spec/combinators/twitter_tumblr_combinator_spec.rb
162
174
  - spec/processors/photo_services_processor_spec.rb
175
+ - spec/processors/tumblr_processor_spec.rb
163
176
  - spec/processors/twitter_processor_spec.rb
164
177
  - spec/spec_helper.rb
165
178
  - spec/tweetlr_spec.rb