artaius 0.2.0 → 0.2.1

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/.gitignore CHANGED
@@ -1,2 +1,3 @@
1
- .rake_tasks~
1
+ *~
2
+ *.gem
2
3
  Gemfile.lock
data/README.md CHANGED
@@ -2,6 +2,7 @@
2
2
  ================
3
3
 
4
4
  * [https://github.com/kyrylo/artaius/][rkag]
5
+ * [Wiki][wiki]
5
6
 
6
7
  Description
7
8
  -----------
@@ -9,6 +10,11 @@ Description
9
10
  Artaius is a [King Arthur's Gold][kag] (KAG) IRC bot. Currently it's not
10
11
  suitable for a public use. Artaius dwells at #kag2d.ru@irc.quakenet.org.
11
12
 
13
+ Credits
14
+ -------
15
+
16
+ * Thanks to [dnmr][dnmr] for testing the bot
17
+
12
18
  License
13
19
  -------
14
20
 
@@ -17,3 +23,5 @@ The project uses Zlib License. See LICENSE file for more information.
17
23
  [logo]: http://img-fotki.yandex.ru/get/6210/98991937.9/0_7735e_6d44a25d_orig "Artaius logo"
18
24
  [rkag]: https://github.com/kyrylo/artaius/ "Home page"
19
25
  [kag]: http://kag2d.com/
26
+ [dnmr]: https://forum.kag2d.com/members/dnmr.23/
27
+ [wiki]: https://github.com/kyrylo/artaius/wiki
@@ -20,8 +20,9 @@ Gem::Specification.new do |s|
20
20
  s.add_runtime_dependency 'cinch', '~>2.0'
21
21
  s.add_runtime_dependency 'kag', '0.0.1'
22
22
  s.add_runtime_dependency 'r18n-desktop', '>=0.4.14'
23
- s.add_runtime_dependency 'sequel', '>=3.34.1'
24
- s.add_runtime_dependency 'sqlite3', '>=1.3.6'
23
+ s.add_runtime_dependency 'sequel', '>=3.34.1'
24
+ s.add_runtime_dependency 'sqlite3', '>=1.3.6'
25
+ s.add_runtime_dependency 'mechanize', '>=2.4'
25
26
 
26
27
  s.add_development_dependency 'rake'
27
28
  s.add_development_dependency 'minitest', '>=2.12.1'
@@ -38,3 +38,33 @@ archivarius:
38
38
  success: "Yay, registration complete! Enjoy KAG ;-)"
39
39
  m:
40
40
  reg: "reg"
41
+
42
+ scraper:
43
+ broken_link: "Uh oh! The link you just posted is broken."
44
+ title: "Title: %1"
45
+ h:
46
+ kag_forum: "KAG's forum: %1"
47
+
48
+ news_fetcher:
49
+ news: "News! %1 writes: \"%2\" → %3"
50
+ latest_news: "On %1 %2 wrote a post: \"%3\"."
51
+ read_post: "Read post: %1"
52
+ m:
53
+ news: "news"
54
+
55
+ informator:
56
+ kag_site: "https://www.kag2d.com/"
57
+ kag_wiki: "https://wiki.kag2d.com/"
58
+ kag_forum: "https://forum.kag2d.com/"
59
+ kag_manual: "https://kag2d.com/en/manual/"
60
+ kag_blog: "http://devlog.kag2d.com/"
61
+ kag_download: "https://kag2d.com/en/download/"
62
+ kag_bug_tracker: "https://bugs.kag2d.com/"
63
+ m:
64
+ site: "site"
65
+ wiki: "wiki"
66
+ forum: "forums"
67
+ manual: "manual"
68
+ blog: "blog"
69
+ download: "download"
70
+ bug_tracker: "bugs"
@@ -39,9 +39,39 @@ mixer:
39
39
  slots: "слоты"
40
40
 
41
41
  archivarius:
42
- exists: "%1, вы уже привязали свой аккаунт в КАГ-е к вашему логину в ИРЦ (%2)."
42
+ exists: "%1, вы уже привязали свой аккаунт в КАГ’е к вашему логину в ИРЦ (%2)."
43
43
  not_found: "Игрок %1 не существует. Опечатались?"
44
- authname_required: "Чтобы связать ваш аккаунт в КАГ-е и ИРЦ логин, вы должны авторизироваться на этом сервере или зарегистрировать свой ник."
45
- success: "Ура, регистрация завершена! Наслаждайтеь КАГ-ом ;-)"
44
+ authname_required: "Чтобы связать ваш аккаунт в КАГ’е и ИРЦ логин, вы должны авторизироваться на этом сервере или зарегистрировать свой ник."
45
+ success: "Ура, регистрация завершена! Наслаждайтеь КАГ’ом ;-)"
46
46
  m:
47
47
  reg: "регь"
48
+
49
+ scraper:
50
+ broken_link: "Опаньки! А вот эта ссылка не работает."
51
+ title: "Заголовок: %1"
52
+ h:
53
+ kag_forum: "Форум КАГ’а: %1"
54
+
55
+ news_fetcher:
56
+ news: "Новость! %1 пишет: \"%2\" → %3"
57
+ latest_news: "%1 %2 написал запись: \"%3\"."
58
+ read_post: "Читать запись: %1"
59
+ m:
60
+ news: "новости"
61
+
62
+ informator:
63
+ kag_site: "https://www.kag2d.com/"
64
+ kag_wiki: "https://wiki.kag2d.com/"
65
+ kag_forum: "https://forum.kag2d.com/"
66
+ kag_manual: "https://kag2d.com/en/manual/"
67
+ kag_blog: "http://devlog.kag2d.com/"
68
+ kag_download: "https://kag2d.com/en/download/"
69
+ kag_bug_tracker: "https://bugs.kag2d.com/"
70
+ m:
71
+ site: "сайт"
72
+ wiki: "вики"
73
+ forum: "форум"
74
+ manual: "справочник"
75
+ blog: "блог"
76
+ download: "скачать"
77
+ bug_tracker: "баги"
@@ -0,0 +1,25 @@
1
+ # Create initial schema for the table of news (tiles) from KAG development blog.
2
+ #
3
+ # +--------------+----------------------------+
4
+ # | Field | Description |
5
+ # +--------------+----------------------------+
6
+ # | id | News id number. |
7
+ # | title | News title. |
8
+ # | date | Date, when news were added.|
9
+ # | author | Author of the news. |
10
+ # | link | Link to post on the web. |
11
+ # +--------------+----------------------------+
12
+ #
13
+ Sequel.migration do
14
+ change do
15
+ create_table :news do
16
+ primary_key :id
17
+ String :title, :size => 255, :null => false
18
+ DateTime :date
19
+ String :author, :size => 32, :null => false
20
+ String :link, :null => false
21
+ DateTime :created_at
22
+ DateTime :updated_at
23
+ end
24
+ end
25
+ end
@@ -10,7 +10,13 @@ require_relative 'artaius/version'
10
10
 
11
11
  require_relative 'artaius/database'
12
12
  require_relative 'artaius/models/player'
13
+ require_relative 'artaius/models/news'
13
14
 
14
15
  require_relative 'artaius/plugins/identify'
15
16
  require_relative 'artaius/plugins/mixer'
16
17
  require_relative 'artaius/plugins/archivarius'
18
+ require_relative 'artaius/plugins/autovoicer'
19
+ require_relative 'artaius/plugins/autoopper'
20
+ require_relative 'artaius/plugins/scraper'
21
+ require_relative 'artaius/plugins/news_fetcher'
22
+ require_relative 'artaius/plugins/informator'
@@ -34,7 +34,12 @@ module Artaius
34
34
  c.plugins.plugins = [
35
35
  Artaius::Plugins::Identify,
36
36
  Artaius::Plugins::Mixer,
37
- Artaius::Plugins::Archivarius
37
+ Artaius::Plugins::Archivarius,
38
+ Artaius::Plugins::Autovoicer,
39
+ Artaius::Plugins::Autoopper,
40
+ Artaius::Plugins::Scraper,
41
+ Artaius::Plugins::NewsFetcher,
42
+ Artaius::Plugins::Informator
38
43
  ]
39
44
 
40
45
  # Set up plugins to be used.
@@ -0,0 +1,5 @@
1
+ module Artaius
2
+ class News < Sequel::Model(:news)
3
+ plugin :timestamps, :update_on_create => true
4
+ end
5
+ end
@@ -2,15 +2,5 @@ module Artaius
2
2
  # Internal: Represents KAG player.
3
3
  class Player < Sequel::Model(:players)
4
4
  plugin :timestamps, :update_on_create => true
5
-
6
- # Internal: Check database for given authname.
7
- #
8
- # irc_authname - The String, represents IRC authname of the player.
9
- #
10
- # Returns true if the given authname is in database or false otherwise.
11
- def self.exists?(irc_authname)
12
- filter(:irc_authname => irc_authname).select(:irc_authname).any?
13
- end
14
-
15
5
  end
16
6
  end
@@ -50,11 +50,13 @@ module Artaius
50
50
 
51
51
  protected
52
52
 
53
- # Internal: Ask database for whether the IRC authname is in it or not.
53
+ # Internal: Check database for given authname.
54
54
  #
55
- # Returns true, if the IRC authname is there of false otherwise.
55
+ # irc_authname - The String, represents IRC authname of the player.
56
+ #
57
+ # Returns true if the given authname is in database or false otherwise.
56
58
  def already_exists?(irc_authname)
57
- Player.exists?(irc_authname)
59
+ Player.filter(:irc_authname => irc_authname).select(:irc_authname).any?
58
60
  end
59
61
 
60
62
  end
@@ -0,0 +1,22 @@
1
+ module Artaius
2
+ module Plugins
3
+ class Autoopper
4
+ # Gives an op for everyone, who has a Guard role in King Arthur's Gold
5
+ # and registered.
6
+ include Cinch::Plugin
7
+
8
+ listen_to :join
9
+
10
+ def listen(m)
11
+ return if m.user.nick == bot.nick
12
+
13
+ m.channel.op(m.user) if guard?(m.user.authname)
14
+ end
15
+
16
+ def guard?(irc_authname)
17
+ Player.filter(:irc_authname => irc_authname).select_map(:role).first == 2
18
+ end
19
+
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+ module Artaius
2
+ module Plugins
3
+ # Gives a voice for everyone, who has a premium account in King Arthur's
4
+ # Gold and registered.
5
+ class Autovoicer
6
+ include Cinch::Plugin
7
+
8
+ listen_to :join
9
+
10
+ def listen(m)
11
+ return if m.user.nick == bot.nick
12
+
13
+ m.channel.voice(m.user) if premium?(m.user.authname)
14
+ end
15
+
16
+ def premium?(irc_authname)
17
+ Player.filter(:irc_authname => irc_authname).select_map(:premium).first
18
+ end
19
+
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,31 @@
1
+ module Artaius
2
+ module Plugins
3
+ # Provides useful links to KAG resources and maybe some other related
4
+ # information.
5
+ class Informator
6
+ include Cinch::Plugin
7
+
8
+ set react_on: :channel
9
+
10
+ methods = [:site, :wiki, :forum, :manual, :blog, :download, :bug_tracker]
11
+
12
+ methods.each do |method|
13
+ pattern = I18n.informator.m.send(method)
14
+ instance_eval <<-EVAL
15
+ match /#{pattern}$/,
16
+ method: :#{method},
17
+ use_suffix: false
18
+ EVAL
19
+ end
20
+
21
+ methods.each do |method|
22
+ class_eval <<-EVAL
23
+ def #{method}(m)
24
+ m.reply I18n.informator.kag_#{method}
25
+ end
26
+ EVAL
27
+ end
28
+
29
+ end
30
+ end
31
+ end
@@ -35,7 +35,6 @@ module Artaius
35
35
  # seconds).
36
36
  PENDING_DELAY = 300
37
37
 
38
-
39
38
  set react_on: :channel
40
39
 
41
40
  match /#{I18n.mixer.m.game}(\s([2-9]|[1-9][0-9]))?$/,
@@ -50,7 +49,7 @@ module Artaius
50
49
  #
51
50
  # Returns nothing.
52
51
  def start_game(m, limit)
53
- return if @game or !Player.exists?(m.user.authname)
52
+ return if @game or !already_exists?(m.user.authname)
54
53
 
55
54
  @limit = if limit && !limit.empty?
56
55
  limit.to_i
@@ -73,7 +72,7 @@ module Artaius
73
72
  #
74
73
  # Returns nothing.
75
74
  def add_player(m)
76
- return if !@game or !Player.exists?(m.user.authname)
75
+ return if !@game or !already_exists?(m.user.authname)
77
76
 
78
77
  unless @game.players.map(&:irc_authname).include?(m.user.authname)
79
78
  @game.players << create_gamer(m)
@@ -86,15 +85,16 @@ module Artaius
86
85
  m.reply I18n.mixer.players(show_players)
87
86
  m.reply I18n.mixer.need_players(need_players)
88
87
  end
89
-
90
88
  end
91
89
 
92
90
  @timer.stop if @timer
93
91
 
94
- @timer = Timer(PENDING_DELAY, :shots => 1) do
92
+ @timer ||= Timer(PENDING_DELAY, shots: 1, start_automatically: false) do
95
93
  @game = nil
96
94
  Channel(m.channel.name).send I18n.mixer.game_cancelled
97
95
  end
96
+
97
+ @timer.start
98
98
  end
99
99
 
100
100
  match /#{I18n.mixer.m.cancel}$/,
@@ -330,6 +330,15 @@ module Artaius
330
330
  )
331
331
  end
332
332
 
333
+ # Internal: Check database for given authname.
334
+ #
335
+ # irc_authname - The String, represents IRC authname of the player.
336
+ #
337
+ # Returns true if the given authname is in database or false otherwise.
338
+ def already_exists?(irc_authname)
339
+ Player.filter(:irc_authname => irc_authname).select(:irc_authname).any?
340
+ end
341
+
333
342
  end
334
343
  end
335
344
  end
@@ -0,0 +1,92 @@
1
+ require 'rss'
2
+ require 'open-uri'
3
+
4
+ module Artaius
5
+ module Plugins
6
+ class NewsFetcher
7
+ include Cinch::Plugin
8
+
9
+ # Internal: RSS address of KAG development blog.
10
+ KAGDEV_RSS = 'http://devlog.kag2d.com/rss'
11
+
12
+ # Internal: Time lapse between checking RSS feed for new posts.
13
+ CHECK_TIME_LAPSE = 1800
14
+
15
+ set react_on: :channel
16
+
17
+ timer CHECK_TIME_LAPSE,
18
+ method: :send_news
19
+
20
+ # Internal: Send latest news on channels.
21
+ #
22
+ # Returns nothing.
23
+ def send_news
24
+ feed = RSS::Parser.parse open(KAGDEV_RSS).read
25
+ last_post_title = feed.channel.item.title
26
+
27
+ # Check, whether the latest title of the post at KAG development
28
+ # blog is still the same, as it was, when the fetcher checked it last
29
+ # time.
30
+ return if unchanged?(last_post_title)
31
+
32
+ item = feed.channel.item
33
+
34
+ last_post_date = item.pubDate
35
+ last_post_author = item.dc_creator
36
+ last_post_link = item.link
37
+
38
+ News.create(
39
+ :title => last_post_title,
40
+ :date => last_post_date,
41
+ :author => last_post_author,
42
+ :link => last_post_link
43
+ )
44
+
45
+ real_author = reveal_author(last_post_author)
46
+ short_link = open("http://clck.ru/--?url=#{last_post_link}").read
47
+
48
+ Bot::CHANNELS.each do |chan|
49
+ Channel(chan).send I18n.news_fetcher.news(real_author, last_post_title, short_link)
50
+ end
51
+ rescue SocketError
52
+ nil
53
+ end
54
+
55
+ match /#{I18n.news_fetcher.m.news}$/,
56
+ method: :latest_news,
57
+ use_suffix: false
58
+
59
+ # Internal: Send on the channel information about the latest post at KAG
60
+ # development blog and give a link to it.
61
+ #
62
+ # Returns nothing.
63
+ def latest_news(m)
64
+ news = News.order(:date).last
65
+
66
+ author = reveal_author(news.author)
67
+ date = I18n.localize(news.date, :full)
68
+
69
+ m.reply I18n.news_fetcher.latest_news(date, author, news.title)
70
+ m.reply I18n.news_fetcher.read_post(news.link)
71
+ end
72
+
73
+ protected
74
+
75
+ def unchanged?(title)
76
+ last = News.select(:title).order(:date).last
77
+ last and last.title == title
78
+ end
79
+
80
+ # Internal: Transform aliases of a blog author to his/her real nickname.
81
+ #
82
+ # Returns the transformed String.
83
+ def reveal_author(nick)
84
+ case nick
85
+ when 'lddev' then 'MM'
86
+ when '1bardesign' then 'Geti'
87
+ end
88
+ end
89
+
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,43 @@
1
+ require 'mechanize'
2
+
3
+ module Artaius
4
+ module Plugins
5
+ # Scraps web pages, that have <title> attribute.
6
+ class Scraper
7
+ include Cinch::Plugin
8
+
9
+ listen_to :channel,
10
+ method: :scrap_links
11
+
12
+ def scrap_links(m)
13
+ unless @agent
14
+ @agent = Mechanize.new
15
+ @agent.user_agent_alias = 'Linux Firefox'
16
+ end
17
+
18
+ URI.extract(m.message, %w[http https]) do |link|
19
+ begin
20
+ page = @agent.get(link)
21
+ uri = URI.parse(link)
22
+ rescue Mechanize::ResponseCodeError
23
+ m.reply I18n.scraper.broken_link and next
24
+ end
25
+
26
+ title = page.title.gsub(/[\x00-\x1f]*/, "").gsub(/[ ]{2,}/, " ").strip rescue nil
27
+
28
+ if title
29
+ case uri.host
30
+ when 'forum.kag2d.com'
31
+ pattern = / \| Page \d{1,4} \| King Arthur's Gold Forum$/
32
+ title.sub!(pattern, '')
33
+ m.reply I18n.scraper.h.kag_forum(title)
34
+ else
35
+ m.reply I18n.scraper.title(title)
36
+ end
37
+ end
38
+ end
39
+ end
40
+
41
+ end
42
+ end
43
+ end
@@ -1,3 +1,3 @@
1
1
  module Artaius
2
- VERSION = '0.2.0'
2
+ VERSION = '0.2.1'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: artaius
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
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-10 00:00:00.000000000 Z
12
+ date: 2012-05-14 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: cinch
@@ -91,6 +91,22 @@ dependencies:
91
91
  - - ! '>='
92
92
  - !ruby/object:Gem::Version
93
93
  version: 1.3.6
94
+ - !ruby/object:Gem::Dependency
95
+ name: mechanize
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '2.4'
102
+ type: :runtime
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '2.4'
94
110
  - !ruby/object:Gem::Dependency
95
111
  name: rake
96
112
  requirement: !ruby/object:Gem::Requirement
@@ -160,13 +176,20 @@ files:
160
176
  - config/plugins/.gitignore
161
177
  - db/.gitignore
162
178
  - db/migrations/001_create_players.rb
179
+ - db/migrations/002_create_news_table.rb
163
180
  - lib/artaius.rb
164
181
  - lib/artaius/bot.rb
165
182
  - lib/artaius/database.rb
183
+ - lib/artaius/models/news.rb
166
184
  - lib/artaius/models/player.rb
167
185
  - lib/artaius/plugins/archivarius.rb
186
+ - lib/artaius/plugins/autoopper.rb
187
+ - lib/artaius/plugins/autovoicer.rb
168
188
  - lib/artaius/plugins/identify.rb
189
+ - lib/artaius/plugins/informator.rb
169
190
  - lib/artaius/plugins/mixer.rb
191
+ - lib/artaius/plugins/news_fetcher.rb
192
+ - lib/artaius/plugins/scraper.rb
170
193
  - lib/artaius/version.rb
171
194
  - spec/lib/artaius/bot_spec.rb
172
195
  - spec/lib/artaius/plugins/archivarius_spec.rb