stalkerr 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5e221a6891528b82fcb96f86fd755fc67849b574
4
- data.tar.gz: c3b563649487135c4c77e4ce77f3f3f3dee32205
3
+ metadata.gz: 37afbc1d1e7cc13a267357dbe454fdd58839856d
4
+ data.tar.gz: 3450f6d52f97e8eb53dbb75767f913ab6ee07a1e
5
5
  SHA512:
6
- metadata.gz: 80b0e80f8c158bb4081e9426a25d4381343f40b2bfd604318b73bccc7d10b23cefba63535744500632f21044b3a72e1270b971d8b53daaa03086ca8355dae1fa
7
- data.tar.gz: 13ae4d63529d31a4e98195f52b5813a6c8b798983ebd2f6561a9fa94fdbf88be2b765df34b88fe10b43701d464796e5c79aa5549bb7b8f95d93fa93bfc6a50ac
6
+ metadata.gz: 866a38efb3b596514926e829f04265896903cd7f12ec2bd9209935ab19a0633e990860e61b50884b74ea7f4c6755a1c2df4c553dcb1888205d32f68ec31ba21a
7
+ data.tar.gz: 94d131d97fd63d09e75d7e209b2ef70ea1b662bfa2a48f9e29c38f34efe0c53a9b7565fb0dded8c2db0a9668131dbd7acfda18bf8b9f1573c44296aaf5044d91
data/Gemfile CHANGED
@@ -3,4 +3,5 @@ source 'https://rubygems.org'
3
3
  gem 'net-irc'
4
4
  gem 'json'
5
5
  gem 'octokit'
6
+ gem 'qiita'
6
7
  gem 'string-irc'
data/README.md CHANGED
@@ -17,6 +17,7 @@ Usage
17
17
  ### Connecting to Stalkerr
18
18
 
19
19
  /join #github <username>:<password>
20
+ /join #qiita <username>:<password>
20
21
 
21
22
  Contributing
22
23
  ------------
@@ -30,7 +31,7 @@ Contributing
30
31
  Author
31
32
  ------
32
33
 
33
- - [@linyows](https://github.com/linyows)
34
+ - [linyows](https://github.com/linyows)
34
35
 
35
36
  License
36
37
  -------
@@ -6,20 +6,24 @@ Dir["#{File.dirname(__FILE__)}/target/*.rb"].each { |p| require p }
6
6
 
7
7
  class Stalkerr::Session < Net::IRC::Server::Session
8
8
 
9
+ def server_name
10
+ 'Stalkerr'
11
+ end
12
+
13
+ def server_version
14
+ Stalkerr::VERSION
15
+ end
16
+
9
17
  def initialize(*args)
10
18
  super
11
19
  @debug = args.last.debug
12
- @channels = {}
20
+ @channels = @threads = @targets = {}
13
21
  Dir["#{File.dirname(__FILE__)}/target/*.rb"].each do |path|
14
22
  name = File.basename(path, '.rb')
15
23
  @channels.merge!(name.to_sym => "##{name}")
16
24
  end
17
25
  end
18
26
 
19
- def on_disconnected
20
- @retrieve_thread.kill rescue nil
21
- end
22
-
23
27
  def on_user(m)
24
28
  super
25
29
  @real, *@opts = @real.split(/\s+/)
@@ -36,23 +40,40 @@ class Stalkerr::Session < Net::IRC::Server::Session
36
40
 
37
41
  def on_join(m)
38
42
  super
43
+ create_worker(m.params)
44
+ end
39
45
 
40
- matched = m.params[1].match(/(.*?):(.*)/)
41
- channel = m.params[0]
46
+ def on_part(m)
47
+ super
48
+ kill @threads[m.params.first]
49
+ end
42
50
 
43
- if !@channels.value?(channel) || !matched
44
- @log.error "#{channel} not found."
51
+ def on_disconnected
52
+ super
53
+ kill_all
54
+ end
55
+
56
+ private
57
+
58
+ def create_worker(params)
59
+ channels = params[0].split(',')
60
+ keys = params[1].split(',')
61
+ channels.each_with_index.map { |v, i| [v, keys[i]] }.each do |channel, key|
62
+ guard auth_data(key).merge(channel: channel)
45
63
  end
64
+ end
46
65
 
47
- @class_name = "Stalkerr::Target::#{@channels.invert[channel].capitalize}"
48
- @username = matched[1]
49
- @password = matched[2]
50
- post @username, JOIN, channel
66
+ def auth_data(key)
67
+ id, pw = key.match(/(.*?):(.*)/).to_a.pop(2)
68
+ { username: id, password: pw }
69
+ end
51
70
 
52
- @retrieve_thread = Thread.start do
71
+ def guard(params)
72
+ post params[:username], JOIN, params[:channel]
73
+ @threads[params[:channel]] = Thread.start(target params) do |service|
53
74
  loop do
54
75
  begin
55
- target.stalking do |prefix, command, *params|
76
+ service.stalking do |prefix, command, *params|
56
77
  post(prefix, command, *params)
57
78
  end
58
79
  sleep Stalkerr::Const::FETCH_INTERVAL
@@ -65,9 +86,20 @@ class Stalkerr::Session < Net::IRC::Server::Session
65
86
  end
66
87
  end
67
88
 
68
- private
89
+ def target(params)
90
+ ch = params[:channel]
91
+ class_name = "Stalkerr::Target::#{@channels.invert[ch].capitalize}"
92
+ unless @targets[ch].is_a?(class_name.constantize)
93
+ @targets[ch] = class_name.constantize.new(params[:username], params[:password])
94
+ end
95
+ @targets[ch]
96
+ end
97
+
98
+ def kill(thread)
99
+ thread.kill if thread && thread.alive?
100
+ end
69
101
 
70
- def target
71
- @target ||= @class_name.constantize.new(@username, @password)
102
+ def kill_all
103
+ @threads.each { |channel, thread| thread.kill if thread.alive? } rescue nil
72
104
  end
73
105
  end
@@ -19,12 +19,15 @@ module Stalkerr::Target
19
19
  end
20
20
 
21
21
  def client
22
- @client ||= Octokit::Client.new(login: @username, password: @password)
22
+ if !@client || @client && !@client.authenticated?
23
+ @client = Octokit.new(login: @username, password: @password)
24
+ end
25
+ @client
23
26
  end
24
27
 
25
28
  def stalking(&post)
26
29
  @post = post
27
- client.received_events(@username).reverse_each { |event|
30
+ client.received_events(@username).sort_by(&:id).reverse_each { |event|
28
31
  if @last_event_id.nil?
29
32
  next if Time.now.utc - Stalkerr::Const::ROLLBACK_SEC >= Time.parse(event.created_at).utc
30
33
  else
@@ -97,10 +100,11 @@ module Stalkerr::Target
97
100
  none_repository = true
98
101
  status = "created repository"
99
102
  title = event.repo.name
103
+ title = "#{title}: #{obj.description}" if obj.description
100
104
  else
101
105
  status = "created #{obj.ref_type}:#{obj.ref}"
106
+ title = obj.description
102
107
  end
103
- title = obj.description
104
108
  link = "#{HOST}/#{event.repo.name}"
105
109
  when 'DeleteEvent'
106
110
  status = "deleted #{obj.ref_type}:#{obj.ref}"
@@ -180,6 +184,7 @@ module Stalkerr::Target
180
184
  end
181
185
 
182
186
  def split_for_comment(string)
187
+ return [] unless string.is_a? String
183
188
  string.split(/\r\n|\n/).map { |v| v unless v.eql? '' }.compact
184
189
  end
185
190
 
@@ -0,0 +1,114 @@
1
+ require 'time'
2
+ require 'net/irc'
3
+ require 'qiita'
4
+ require 'net/http'
5
+ require 'string-irc'
6
+ require 'stalkerr'
7
+
8
+ module Stalkerr::Target
9
+ class Qiita
10
+ include Net::IRC::Constants
11
+
12
+ HOST = 'http://qiita.com'
13
+ CHANNEL = '#qiita'
14
+ INTERVAL = 60 * 10
15
+
16
+ def initialize(username, password)
17
+ @username = username
18
+ @password = password
19
+ @last_fetched_at = nil
20
+ @marker = nil
21
+ end
22
+
23
+ def client
24
+ @client ||= ::Qiita.new(url_name: @username, password: @password)
25
+ end
26
+
27
+ def stalking(&post)
28
+ return if @last_fetched_at && Time.now.utc < @last_fetched_at + INTERVAL
29
+ @last_fetched_at = Time.now.utc
30
+
31
+ @post = post
32
+ stocked_items = posted_items = []
33
+ stocks = {}
34
+
35
+ followings = client.user_following_users(@username).map { |u| u.url_name }.compact
36
+ followings.each do |user|
37
+ begin
38
+ stocks[user] = client.user_stocks(user)
39
+ stocked_items = stocked_items + stocks[user]
40
+ rescue => e
41
+ nil
42
+ end
43
+ begin
44
+ posted_items = posted_items + client.user_items(user)
45
+ rescue => e
46
+ nil
47
+ end
48
+ end
49
+
50
+ tags = client.user_following_tags(@username).map { |t| t.url_name }.compact
51
+ new_items = tags.inject([]) { |arr, tag| arr + client.tag_items(encoder tag) }
52
+
53
+ items = (stocked_items + posted_items + new_items).uniq
54
+ items[0...30].sort_by(&:id).each do |obj|
55
+ next if @marker && @marker >= obj.id
56
+ type = 'new'
57
+ nick = obj.user.url_name
58
+ case
59
+ when stocked_items.include?(obj)
60
+ type = 'stock'
61
+ stocks.each { |user, items| nick = user and break if items.include?(obj) }
62
+ when posted_items.include?(obj)
63
+ type = 'post'
64
+ end
65
+ parse type, [nick, obj]
66
+ @marker = obj.id
67
+ end
68
+ end
69
+
70
+ def parse(type, data)
71
+ nick, obj = data
72
+ header = status = title = link = ''
73
+ body = []
74
+ notice_body = false
75
+
76
+ case type
77
+ when 'stock'
78
+ status = "stocked entry"
79
+ color = :pink
80
+ when 'post'
81
+ status = "posted entry"
82
+ color = :yellow
83
+ when 'new'
84
+ status = "new entry"
85
+ color = :aqua
86
+ notice_body = true
87
+ end
88
+ title = "#{obj.title}"
89
+ body = split_for_body obj.raw_body
90
+ link = obj.url
91
+
92
+ header = StringIrc.new(status).send(color)
93
+ header = "#{header} #{title}" unless title.eql? ''
94
+ header = "#{header} - #{StringIrc.new(link).blue}"
95
+
96
+ @post.call simple(nick), NOTICE, CHANNEL, header
97
+ mode = notice_body ? NOTICE : PRIVMSG
98
+ body.each { |b| @post.call simple(nick), mode, CHANNEL, b } unless body.eql? []
99
+ end
100
+
101
+ def split_for_body(string)
102
+ return [] unless string.is_a?(String)
103
+ string.split(/\r\n|\n/).map { |v| v unless v.eql? '' }.compact
104
+ end
105
+
106
+ def simple(string)
107
+ string.gsub('@github', '')
108
+ end
109
+
110
+ def encoder(string)
111
+ URI.encode(string).gsub('.', '%2e')
112
+ end
113
+ end
114
+ end
@@ -1,3 +1,3 @@
1
1
  module Stalkerr
2
- VERSION = "0.0.1"
2
+ VERSION = "0.1.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stalkerr
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - linyows
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-03-26 00:00:00.000000000 Z
11
+ date: 2013-03-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: net-irc
@@ -88,6 +88,7 @@ files:
88
88
  - lib/stalkerr/session.rb
89
89
  - lib/stalkerr/target.rb
90
90
  - lib/stalkerr/target/github.rb
91
+ - lib/stalkerr/target/qiita.rb
91
92
  - lib/stalkerr/version.rb
92
93
  - stalkerr.gemspec
93
94
  homepage: https://github.com/linyows/stalkerr