atig 0.3.6 → 0.3.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -21,9 +21,9 @@ HOW TO USE
21
21
 
22
22
  You type:
23
23
 
24
- $ cd atig
25
- $ ruby atig.rb -d
26
- I, [2010-04-05T07:22:07.861527 #62002] INFO -- : Host: localhost Port:16668
24
+ $ cd atig
25
+ $ bin/atig -d
26
+ I, [2010-04-05T07:22:07.861527 #62002] INFO -- : Host: localhost Port:16668
27
27
 
28
28
  and access localhost:16668 by Irc client.
29
29
 
@@ -1,6 +1,27 @@
1
1
  更新履歴
2
2
  ==============
3
3
 
4
+ v0.3.7(2013-01-27)
5
+ ------------------------------
6
+ http://github.com/mzp/atig/tree/v0.3.7
7
+
8
+ 機能追加
9
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10
+ - Twitter の Userstream に対応しました
11
+
12
+ バグ修正
13
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
14
+ - Ruby 2.0.0(r38955) で動かない問題を直しました
15
+ - github の API の変更によりバージョンチェックが動かない問題を直しました
16
+
17
+ v0.3.6(2012-05-14)
18
+ ------------------------------
19
+ http://github.com/mzp/atig/tree/v0.3.6
20
+
21
+ 機能変更
22
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
23
+ - Ruby 2.0.0 以降で iconv ライブラリが削除されることに伴う UTF7 サポートの終了
24
+
4
25
  v0.3.5(2012-05-07)
5
26
  ------------------------------
6
27
  http://github.com/mzp/atig/tree/v0.3.5
@@ -48,20 +48,20 @@ URL短縮関係
48
48
  発言中の長いURLを自動で短縮します。どの短縮URLサービスを用いて短縮する
49
49
  か、どの程度の長さのURLを短縮するか、などが設定できます。
50
50
 
51
- bitlify=\ ``size``
52
- ``size``\ 字以上のURLを http://bit.ly\ によって短縮します。
53
51
  bitlify
54
52
  |len|\ 字以上のURLを http://bit.ly\ によって短縮します。
55
- bitlify=\ ``api_key``:\ ``api_key``:\ ``size``
53
+ bitlify=\ ``size``
54
+ ``size``\ 字以上のURLを http://bit.ly\ によって短縮します。
55
+ bitlify=\ ``username``:\ ``api_key``
56
+ |len|\ 字以上のURLを http://bit.ly のAPIによって短縮します。
57
+ bitlify=\ ``username``:\ ``api_key``:\ ``size``
56
58
  ``size``\ 字以上のURLを http://bit.ly のAPIによって短縮します。
57
59
  APIを利用して短縮すると、ユーザページに短縮したURLが記録されたりします。
58
60
  詳しくは、 http://bit.ly のSign up for bit.lyを読んでください。
59
- bitlify=\ ``api_key``:\ ``api_key``
60
- |len|\ 字以上のURLを http://bit.ly のAPIによって短縮します。
61
- unuify= \ ``size``
62
- ``size`` 字以上のURLを http://u.nu によって短縮します。
63
61
  unuify
64
62
  |len| 字以上のURLを http://u.nu によって短縮します。
63
+ unuify= \ ``size``
64
+ ``size`` 字以上のURLを http://u.nu によって短縮します。
65
65
 
66
66
  .. |len| replace:: 20
67
67
 
@@ -7,3 +7,4 @@ require 'atig/agent/dm'
7
7
  require 'atig/agent/timeline'
8
8
  require 'atig/agent/clenup'
9
9
  require 'atig/agent/user_stream'
10
+ require 'atig/agent/noretweets'
@@ -7,6 +7,7 @@ module Atig
7
7
  include Util
8
8
 
9
9
  def initialize(context, api, db)
10
+ return if context.opts.stream
10
11
  @log = context.log
11
12
  @api = api
12
13
  @prev = nil
@@ -4,7 +4,10 @@ require 'atig/agent/agent'
4
4
  module Atig
5
5
  module Agent
6
6
  class Mention < Atig::Agent::Agent
7
- def initialize(context, api, db); super end
7
+ def initialize(context, api, db)
8
+ return if context.opts.stream
9
+ super
10
+ end
8
11
  def interval; 180 end
9
12
  def path; '/statuses/mentions' end
10
13
  def source; :mention end
@@ -0,0 +1,24 @@
1
+ # -*- mode:ruby; coding:utf-8 -*-
2
+
3
+ require 'atig/util'
4
+
5
+ module Atig
6
+ module Agent
7
+ class Noretweets
8
+ include Util
9
+
10
+ def initialize(context, api, db)
11
+ @opts = context.opts
12
+ @log = context.log
13
+ @db = db
14
+ log :info, "initialize"
15
+
16
+ api.repeat(3600){|t| update t }
17
+ end
18
+
19
+ def update(api)
20
+ @db.noretweets.clear.concat( api.get("friendships/no_retweet_ids") )
21
+ end
22
+ end
23
+ end
24
+ end
@@ -4,7 +4,10 @@ require 'atig/agent/agent'
4
4
  module Atig
5
5
  module Agent
6
6
  class Timeline < Atig::Agent::Agent
7
- def initialize(context, api, db); super end
7
+ def initialize(context, api, db)
8
+ return if context.opts.stream
9
+ super
10
+ end
8
11
  def interval; 30 end
9
12
  def path; '/statuses/home_timeline' end
10
13
  def source; :timeline end
@@ -18,10 +18,29 @@ module Atig
18
18
  @api.stream do|t|
19
19
  t.watch('user') do |status|
20
20
  # @log.debug status.inspect
21
- if status and status.user
21
+ next if status.retweeted_status and db.noretweets.include?(status.user.id)
22
+ if status.direct_message
23
+ dm = status.direct_message
24
+ db.dms.transaction do|d|
25
+ d.add :status => dm, :user => dm.sender
26
+ end
27
+ elsif status and status.user
22
28
  db.statuses.transaction do|d|
23
29
  d.add :status => status, :user => status.user, :source => :user_stream
24
30
  end
31
+ elsif status and status.event
32
+ case status.event
33
+ when 'list_member_added'
34
+ t.channel.notify "list member \00311added\017 : @#{status.target.screen_name} into #{status.target_object.full_name} [ http://twitter.com#{status.target_object.uri} ]"
35
+ when 'list_member_removed'
36
+ t.channel.notify "list member \00305removed\017 : @#{status.target.screen_name} from #{status.target_object.full_name} [ http://twitter.com#{status.target_object.uri} ]"
37
+ when 'follow'
38
+ t.channel.notify "#{status.source.screen_name} \00311follows\017 @#{status.target.screen_name}"
39
+ when 'favorite'
40
+ t.channel.notify "#{status.source.screen_name} \00311favorites\017 => @#{status.target_object.user.screen_name} : #{status.target_object.text}"
41
+ when 'unfavorite'
42
+ t.channel.notify "#{status.source.screen_name} \00305unfavorites\017 => @#{status.target_object.user.screen_name} : #{status.target_object.text}"
43
+ end
25
44
  end
26
45
  end
27
46
  end
@@ -13,7 +13,7 @@ module Atig
13
13
  module Db
14
14
  class Db
15
15
  include Util
16
- attr_reader :followings, :statuses, :dms, :lists
16
+ attr_reader :followings, :statuses, :dms, :lists, :noretweets
17
17
  attr_accessor :me
18
18
  Path = ::Dir.tmpdir
19
19
  VERSION = 4
@@ -26,6 +26,7 @@ module Atig
26
26
  @statuses = Statuses.new dir('status')
27
27
  @dms = Statuses.new dir('dm')
28
28
  @lists = Lists.new dir('lists.%s')
29
+ @noretweets = Array.new
29
30
 
30
31
  log :info, "initialize"
31
32
  end
@@ -9,6 +9,7 @@ Atig::Gateway::Session.agents = [
9
9
  Atig::Agent::Timeline,
10
10
  Atig::Agent::Cleanup,
11
11
  Atig::Agent::UserStream,
12
+ Atig::Agent::Noretweets,
12
13
  ]
13
14
 
14
15
  Atig::Gateway::Session.ifilters = [
@@ -96,7 +96,6 @@ END
96
96
  @channels.each{|_, ch| ch.topic entry }
97
97
  end
98
98
 
99
- protected
100
99
  def on_message(m)
101
100
  GC.start
102
101
  @on_message.call(m) if @on_message
@@ -138,7 +137,13 @@ END
138
137
  log :debug, "initialize Twitter"
139
138
  twitter = Twitter.new context, oauth.access
140
139
  search = SearchTwitter.new context
141
- stream = Stream.new context, @nick,@pass if @opts.stream
140
+ if @opts.stream
141
+ unless @channels.key?("##{@nick}")
142
+ ch = channel("##{@nick}")
143
+ ch.join_me
144
+ end
145
+ end
146
+ stream = Stream.new context, @channels["##{@nick}"], oauth.access if @opts.stream
142
147
  @api = Scheduler.new context, twitter, search, stream
143
148
 
144
149
  log :debug, "initialize filter"
@@ -169,34 +174,10 @@ END
169
174
  end
170
175
  end
171
176
 
172
- def run_new(klasses,*args)
173
- (klasses || []).map do|klass|
174
- if klass.respond_to?(:new)
175
- klass.new(*args)
176
- else
177
- klass
178
- end
179
- end
180
- end
181
-
182
177
  def on_disconnected
183
178
  (@thread_group.list - [Thread.current]).each {|t| t.kill }
184
179
  end
185
180
 
186
- CONFIG_FILE = File.expand_path("~/.atig/oauth")
187
- def save_config
188
- FileUtils.mkdir_p File.dirname(CONFIG_FILE)
189
- File.open(CONFIG_FILE, "w") {|io|
190
- YAML.dump(OAuth.dump,io)
191
- }
192
- FileUtils.chmod 0600, CONFIG_FILE
193
- end
194
-
195
- def load_config
196
- FileUtils.mkdir_p File.dirname(CONFIG_FILE)
197
- OAuth.load(YAML.load_file(CONFIG_FILE)) rescue nil
198
- end
199
-
200
181
  def on_privmsg(m)
201
182
  target, mesg = *m.params
202
183
  m.ctcps.each {|ctcp| on_ctcp(target, ctcp) } if m.ctcp?
@@ -314,6 +295,32 @@ END
314
295
  post server_name, RPL_ENDOFWHO, @nick, channel
315
296
  end
316
297
 
298
+ protected
299
+
300
+ def run_new(klasses,*args)
301
+ (klasses || []).map do|klass|
302
+ if klass.respond_to?(:new)
303
+ klass.new(*args)
304
+ else
305
+ klass
306
+ end
307
+ end
308
+ end
309
+
310
+ CONFIG_FILE = File.expand_path("~/.atig/oauth")
311
+ def save_config
312
+ FileUtils.mkdir_p File.dirname(CONFIG_FILE)
313
+ File.open(CONFIG_FILE, "w") {|io|
314
+ YAML.dump(OAuth.dump,io)
315
+ }
316
+ FileUtils.chmod 0600, CONFIG_FILE
317
+ end
318
+
319
+ def load_config
320
+ FileUtils.mkdir_p File.dirname(CONFIG_FILE)
321
+ OAuth.load(YAML.load_file(CONFIG_FILE)) rescue nil
322
+ end
323
+
317
324
  def available_user_modes
318
325
  "o"
319
326
  end
@@ -20,6 +20,7 @@ module Atig
20
20
  end
21
21
 
22
22
  attr_reader :access
23
+ attr_reader :oauth
23
24
  def initialize(context, nick)
24
25
  uri = URI(context.opts.api_base)
25
26
  site = "http://#{uri.host}"
@@ -30,7 +30,7 @@ module Atig
30
30
  end
31
31
 
32
32
  default_value :api_base, 'https://api.twitter.com/1/'
33
- default_value :stream_api_base, 'http://chirpstream.twitter.com/2b/'
33
+ default_value :stream_api_base, 'https://userstream.twitter.com/2/'
34
34
  default_value :search_api_base, 'http://search.twitter.com/'
35
35
 
36
36
  def initialize(table)
@@ -12,12 +12,14 @@ module Atig
12
12
  class Stream
13
13
  include Util
14
14
 
15
+ attr_reader :channel
16
+
15
17
  class APIFailed < StandardError; end
16
- def initialize(context, user, password)
18
+ def initialize(context, channel, access)
17
19
  @log = context.log
18
20
  @opts = context.opts
19
- @user = user
20
- @password = password
21
+ @channel = channel
22
+ @access = access
21
23
  end
22
24
 
23
25
  def watch(path, query={}, &f)
@@ -30,32 +32,31 @@ module Atig
30
32
 
31
33
  @log.debug [uri.to_s]
32
34
 
33
- Net::HTTP.start(uri.host, uri.port) do |http|
34
- request = Net::HTTP::Post.new uri.request_uri
35
- request.basic_auth @user, @password
36
-
37
- http.request(request) do |response|
38
- unless response.code == '200' then
39
- raise APIFailed,"#{response.code} #{response.message}"
40
- end
35
+ http = Net::HTTP.new(uri.host, uri.port)
36
+ http.use_ssl = true
37
+ request = Net::HTTP::Get.new(uri.request_uri)
38
+ request.oauth!(http, @access.consumer, @access)
39
+ http.request(request) do |response|
40
+ unless response.code == '200' then
41
+ raise APIFailed,"#{response.code} #{response.message}"
42
+ end
41
43
 
42
- begin
43
- buffer = ''
44
- response.read_body do |chunk|
45
- next if chunk.chomp.empty?
46
- buffer << chunk.to_s
44
+ begin
45
+ buffer = ''
46
+ response.read_body do |chunk|
47
+ next if chunk.chomp.empty?
48
+ buffer << chunk.to_s
47
49
 
48
- if buffer =~ /\A(.*)\n/ then
49
- text = $1
50
- unless text.strip.empty?
51
- f.call TwitterStruct.make(JSON.parse(text))
52
- end
53
- buffer = ''
50
+ if buffer =~ /\A(.*)\n/ then
51
+ text = $1
52
+ unless text.strip.empty?
53
+ f.call TwitterStruct.make(JSON.parse(text))
54
54
  end
55
+ buffer = ''
55
56
  end
56
- rescue => e
57
- raise APIFailed,e.to_s
58
57
  end
58
+ rescue => e
59
+ raise APIFailed,e.to_s
59
60
  end
60
61
  end
61
62
  end
@@ -3,10 +3,10 @@
3
3
  module Atig
4
4
  module UpdateChecker
5
5
  def commits
6
- uri = URI("http://github.com/api/v1/json/mzp/atig/commits/master")
6
+ uri = URI("https://api.github.com/repos/mzp/atig/commits")
7
7
  http = Atig::Http.new
8
8
  res = http.http(uri).request http.req(:get, uri)
9
- JSON.parse(res.body)['commits']
9
+ JSON.parse(res.body)
10
10
  end
11
11
 
12
12
  def server_version
@@ -29,18 +29,18 @@ module Atig
29
29
  []
30
30
  else
31
31
  cs = commits
32
- latest = cs.first['id'][/^[0-9a-z]{40}$/]
32
+ latest = cs.first['sha'][/^[0-9a-z]{40}$/]
33
33
  raise "github API changed?" unless latest
34
34
 
35
35
  if local_repos?(latest) then
36
36
  []
37
37
  else
38
- current = cs.map {|i| i['id'] }.index(server_version)
38
+ current = cs.map {|i| i['sha'] }.index(server_version)
39
39
  if current then
40
40
  cs[0...current]
41
41
  else
42
42
  cs
43
- end.map {|i| i['message'] }
43
+ end.map {|i| i['commit']['message'] }
44
44
  end
45
45
  end
46
46
  rescue Errno::ECONNREFUSED, Timeout::Error => e
@@ -1,3 +1,3 @@
1
1
  module Atig
2
- VERSION = "0.3.6"
2
+ VERSION = "0.3.7"
3
3
  end
@@ -9,7 +9,7 @@ describe Atig::UpdateChecker,'when use git version' do
9
9
  end
10
10
 
11
11
  def commit(c, mesg)
12
- {'id' => rev(c), 'message' => mesg}
12
+ {'sha' => rev(c), 'commit' => {'message' => mesg}}
13
13
  end
14
14
 
15
15
  before do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: atig
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.6
4
+ version: 0.3.7
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-05-14 00:00:00.000000000 Z
12
+ date: 2013-01-27 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: sqlite3
@@ -160,6 +160,7 @@ files:
160
160
  - lib/atig/agent/list.rb
161
161
  - lib/atig/agent/list_status.rb
162
162
  - lib/atig/agent/mention.rb
163
+ - lib/atig/agent/noretweets.rb
163
164
  - lib/atig/agent/other_list.rb
164
165
  - lib/atig/agent/own_list.rb
165
166
  - lib/atig/agent/stream_follow.rb
@@ -299,18 +300,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
299
300
  - - ! '>='
300
301
  - !ruby/object:Gem::Version
301
302
  version: '0'
302
- segments:
303
- - 0
304
- hash: 2969950395206530754
305
303
  required_rubygems_version: !ruby/object:Gem::Requirement
306
304
  none: false
307
305
  requirements:
308
306
  - - ! '>='
309
307
  - !ruby/object:Gem::Version
310
308
  version: '0'
311
- segments:
312
- - 0
313
- hash: 2969950395206530754
314
309
  requirements: []
315
310
  rubyforge_project:
316
311
  rubygems_version: 1.8.24
@@ -360,3 +355,4 @@ test_files:
360
355
  - spec/sized_hash_spec.rb
361
356
  - spec/spec_helper.rb
362
357
  - spec/update_checker_spec.rb
358
+ has_rdoc: