twitter_ebooks 2.2.6 → 2.2.7

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b50e63b5ee0a1fd5149d7ecd0157c10831433ecc
4
- data.tar.gz: e77e9ac3f6605dac9effe22f856a02b7e9f1df8a
3
+ metadata.gz: 69ac58617389d783dde49b9295bc12f00380ee2f
4
+ data.tar.gz: 6afd456d5eae6d74a8330240c40e427640255dda
5
5
  SHA512:
6
- metadata.gz: 1cf7e279e5f1c35b151f4af5296ea65de049bce7718502828381d9bbd9008898954b1093764eb7046f9e48a029d70629cea052e2747926a827ecd48b31b874e5
7
- data.tar.gz: 88ebd09ae226e30954fa287617c09775488536f897a9d025cdde1511da660df42d8c63fd760503a2766c680266c656a9f32c96488016951b4d79ceac0d48c096
6
+ metadata.gz: 4990cbbe8e4fa74bbf8b935598474d245de148464679b85a1908abe9612653849981f38343fb7f1706b241cc85ba166d45a89a8ee030d43878c91361f5d2dff4
7
+ data.tar.gz: 67bdec6974c5aea4bebf299045653b3f71cb3a69becd49b926c956bd22da546d01fc276334034c39175a9f329bf325535344a9e77f2036ab76085b95073c49a1
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- # Specify your gem's dependencies in libtcod.gemspec
3
+ # Specify your gem's dependencies in twitter_ebooks.gemspec
4
4
  gemspec
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # twitter\_ebooks 2.2.6
1
+ # twitter\_ebooks 2.2.7
2
2
 
3
3
  Rewrite of my twitter\_ebooks code. While the original was solely a tweeting Markov generator, this framework helps you build any kind of interactive twitterbot which responds to mentions/DMs. See [ebooks\_example](https://github.com/mispy/ebooks_example) for an example of a full bot.
4
4
 
@@ -50,6 +50,7 @@ Ebooks::Bot.new("abby_ebooks") do |bot|
50
50
  # Tweet something every 24 hours
51
51
  # See https://github.com/jmettraux/rufus-scheduler
52
52
  # bot.tweet("hi")
53
+ # bot.pictweet("hi", "cuteselfie.jpg", ":possibly_sensitive => true")
53
54
  end
54
55
  end
55
56
  ```
@@ -43,16 +43,15 @@ module Ebooks
43
43
  config.oauth_token_secret = @oauth_token_secret
44
44
  end
45
45
 
46
- Twitter.configure do |config|
46
+ @twitter = Twitter::REST::Client.new do |config|
47
47
  config.consumer_key = @consumer_key
48
48
  config.consumer_secret = @consumer_secret
49
- config.oauth_token = @oauth_token
50
- config.oauth_token_secret = @oauth_token_secret
49
+ config.access_token = @access_token
50
+ config.access_token_secret = @access_token_secret
51
51
  end
52
52
 
53
53
  needs_stream = [@on_follow, @on_message, @on_mention, @on_timeline].any? {|e| !e.nil?}
54
54
 
55
- @twitter = Twitter::Client.new
56
55
  @stream = TweetStream::Client.new if needs_stream
57
56
  end
58
57
 
@@ -89,19 +88,19 @@ module Ebooks
89
88
  end
90
89
 
91
90
  @stream.userstream do |ev|
92
- next unless ev[:text] # If it's not a text-containing tweet, ignore it
93
- next if ev[:user][:screen_name] == @username # Ignore our own tweets
91
+ next unless ev.text # If it's not a text-containing tweet, ignore it
92
+ next if ev.user.screen_name == @username # Ignore our own tweets
94
93
 
95
94
  meta = {}
96
95
  mentions = ev.attrs[:entities][:user_mentions].map { |x| x[:screen_name] }
97
96
 
98
97
  reply_mentions = mentions.reject { |m| m.downcase == @username.downcase }
99
- reply_mentions = [ev[:user][:screen_name]] + reply_mentions
98
+ reply_mentions = [ev.user.screen_name] + reply_mentions
100
99
 
101
100
  meta[:reply_prefix] = reply_mentions.uniq.map { |m| '@'+m }.join(' ') + ' '
102
101
  meta[:limit] = 140 - meta[:reply_prefix].length
103
102
 
104
- mless = ev[:text]
103
+ mless = ev.text
105
104
  begin
106
105
  ev.attrs[:entities][:user_mentions].reverse.each do |entity|
107
106
  last = mless[entity[:indices][1]..-1]||''
@@ -109,7 +108,7 @@ module Ebooks
109
108
  end
110
109
  rescue Exception
111
110
  p ev.attrs[:entities][:user_mentions]
112
- p ev[:text]
111
+ p ev.text
113
112
  raise
114
113
  end
115
114
  meta[:mentionless] = mless
@@ -118,8 +117,8 @@ module Ebooks
118
117
  # - The tweet mentions list contains our username
119
118
  # - The tweet is not being retweeted by somebody else
120
119
  # - Or soft-retweeted by somebody else
121
- if mentions.map(&:downcase).include?(@username.downcase) && !ev[:retweeted_status] && !ev[:text].start_with?('RT ')
122
- log "Mention from @#{ev[:user][:screen_name]}: #{ev[:text]}"
120
+ if mentions.map(&:downcase).include?(@username.downcase) && !ev.retweeted_status && !ev.text.start_with?('RT ')
121
+ log "Mention from @#{ev.user.screen_name}: #{ev.text}"
123
122
  @on_mention.call(ev, meta) if @on_mention
124
123
  else
125
124
  @on_timeline.call(ev, meta) if @on_timeline
@@ -140,11 +139,11 @@ module Ebooks
140
139
  opts = opts.clone
141
140
 
142
141
  if ev.is_a? Twitter::DirectMessage
143
- log "Sending DM to @#{ev[:sender][:screen_name]}: #{text}"
144
- @twitter.direct_message_create(ev[:sender][:screen_name], text, opts)
142
+ log "Sending DM to @#{ev.sender.screen_name}: #{text}"
143
+ @twitter.direct_message_create(ev.sender.screen_name, text, opts)
145
144
  elsif ev.is_a? Twitter::Tweet
146
- log "Replying to @#{ev[:user][:screen_name]} with: #{text}"
147
- @twitter.update(text, in_reply_to_status_id: ev[:id])
145
+ log "Replying to @#{ev.user.screen_name} with: #{text}"
146
+ @twitter.update(text, in_reply_to_status_id: ev.id)
148
147
  else
149
148
  raise Exception("Don't know how to reply to a #{ev.class}")
150
149
  end
@@ -164,6 +163,12 @@ module Ebooks
164
163
  @twitter.update(*args)
165
164
  end
166
165
 
166
+ # could easily just be *args however the separation keeps it clean.
167
+ def pictweet(txt, pic, *args)
168
+ log "Tweeting #{txt.inspect} - #{pic} #{args}"
169
+ @twitter.update_with_media(txt, File.new(pic), *args)
170
+ end
171
+
167
172
  def on_startup(&b); @on_startup = b; end
168
173
  def on_follow(&b); @on_follow = b; end
169
174
  def on_mention(&b); @on_mention = b; end
@@ -18,14 +18,28 @@ module Ebooks
18
18
  Marshal.load(File.open(path, 'rb') { |f| f.read })
19
19
  end
20
20
 
21
+ def mass_tokenize(text)
22
+ sentences = NLP.sentences(text)
23
+ tokens = []
24
+
25
+ sentences.each do |s|
26
+ tokens << NLP.tokenize(s).reject do |t|
27
+ # Don't include usernames/urls as tokens
28
+ t.include?('@') || t.include?('http')
29
+ end
30
+ end
31
+
32
+ tokens
33
+ end
34
+
21
35
  def consume(path)
22
36
  content = File.read(path, :encoding => 'utf-8')
23
37
  @hash = Digest::MD5.hexdigest(content)
24
38
 
25
39
  if path.split('.')[-1] == "json"
26
40
  log "Reading json corpus from #{path}"
27
- lines = JSON.parse(content, symbolize_names: true).map do |tweet|
28
- tweet[:text]
41
+ lines = JSON.parse(content).map do |tweet|
42
+ tweet['text']
29
43
  end
30
44
  elsif path.split('.')[-1] == "csv"
31
45
  log "Reading CSV corpus from #{path}"
@@ -42,41 +56,28 @@ module Ebooks
42
56
 
43
57
  log "Removing commented lines and sorting mentions"
44
58
 
45
- keeping = []
59
+ statements = []
46
60
  mentions = []
47
61
  lines.each do |l|
48
62
  next if l.start_with?('#') # Remove commented lines
49
63
  next if l.include?('RT') || l.include?('MT') # Remove soft retweets
50
-
64
+
51
65
  if l.include?('@')
52
- mentions << l
66
+ statements << NLP.normalize(l)
53
67
  else
54
- keeping << l
68
+ mentions << NLP.normalize(l)
55
69
  end
56
70
  end
57
- text = NLP.normalize(keeping.join("\n")) # Normalize weird characters
58
- mention_text = NLP.normalize(mentions.join("\n"))
59
71
 
60
- log "Segmenting text into sentences"
72
+ text = statements.join("\n")
73
+ mention_text = mentions.join("\n")
61
74
 
62
- statements = NLP.sentences(text)
63
- mentions = NLP.sentences(mention_text)
75
+ lines = nil; statements = nil; mentions = nil # Allow garbage collection
64
76
 
65
- log "Tokenizing #{statements.length} statements and #{mentions.length} mentions"
66
- @sentences = []
67
- @mentions = []
77
+ log "Tokenizing #{text.count('\n')} statements and #{mention_text.count('\n')} mentions"
68
78
 
69
- statements.each do |s|
70
- @sentences << NLP.tokenize(s).reject do |t|
71
- t.include?('@') || t.include?('http')
72
- end
73
- end
74
-
75
- mentions.each do |s|
76
- @mentions << NLP.tokenize(s).reject do |t|
77
- t.include?('@') || t.include?('http')
78
- end
79
- end
79
+ @sentences = mass_tokenize(text)
80
+ @mentions = mass_tokenize(mention_text)
80
81
 
81
82
  log "Ranking keywords"
82
83
  @keywords = NLP.keywords(@sentences)
@@ -43,7 +43,7 @@ module Ebooks
43
43
  end
44
44
 
45
45
  ### Utility functions
46
-
46
+
47
47
  # We don't really want to deal with all this weird unicode punctuation
48
48
  def self.normalize(text)
49
49
  htmlentities.decode text.gsub('“', '"').gsub('”', '"').gsub('’', "'").gsub('…', '...')
@@ -1,3 +1,3 @@
1
1
  module Ebooks
2
- VERSION = "2.2.6"
2
+ VERSION = "2.2.7"
3
3
  end
@@ -1,5 +1,3 @@
1
- gem 'minitest'
2
-
3
1
  $debug = false
4
2
 
5
3
  def log(*args)
data/skeleton/bots.rb CHANGED
@@ -37,5 +37,6 @@ Ebooks::Bot.new("{{BOT_NAME}}") do |bot|
37
37
  # Tweet something every 24 hours
38
38
  # See https://github.com/jmettraux/rufus-scheduler
39
39
  # bot.tweet("hi")
40
+ # bot.pictweet("hi", "cuteselfie.jpg", ":possibly_sensitive => true")
40
41
  end
41
42
  end