hibot 0.0.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.
- checksums.yaml +7 -0
- data/.gitignore +5 -0
- data/.rspec +3 -0
- data/Gemfile +8 -0
- data/README.md +51 -0
- data/Rakefile +6 -0
- data/bin/hibot +19 -0
- data/hibot.gemspec +26 -0
- data/lib/api/spotify.rb +45 -0
- data/lib/config.rb +0 -0
- data/lib/hibot.rb +41 -0
- data/lib/hibot/helpers/configuration.rb +26 -0
- data/lib/hibot/plugins/spotify.rb +20 -0
- data/spec/api/spotify_spec.rb +36 -0
- data/spec/foo +3 -0
- data/spec/helpers/configuration_spec.rb +57 -0
- data/spec/spec_helper.rb +13 -0
- metadata +134 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: da04f8159bb4a38fcec07a4b097f3686b07a79ad
|
4
|
+
data.tar.gz: ce6402a54c877a8eeeacd580b37cdd033123b246
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 35d390f87724f6090b3924ad00d99180f4143abe9089623b95a23ed0473c3eeded19ae400ca4a9b3573a02aff250793d0018d97df0b350f6da6919a2a5f621c1
|
7
|
+
data.tar.gz: 5375e81f645cfb8f2e3330c2007e7f59f6d52e8e8e6983c35e59c94c49a20a7d1095c3476069f949169f732813d615089645d35b948a6af313b7397c76c2692e
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
#Hibot
|
2
|
+
|
3
|
+
## Presentation
|
4
|
+
|
5
|
+
Hibot is a bot written in Ruby and based on the excellent [cinch gem](https://github.com/cinchrb/cinch). The gem is developped using the plugins principle. You can just load the needed plugins and so you don't have to configure and to enable all plugins.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Install the gem through rubygems. Use the basic command `gem install hibot`. Then you have to create a hibotrc yaml file that respects the following syntax :
|
10
|
+
|
11
|
+
```yaml
|
12
|
+
---
|
13
|
+
:general:
|
14
|
+
:server: your.server.irc
|
15
|
+
:channels:
|
16
|
+
- '#channel1'
|
17
|
+
- '#channel2'
|
18
|
+
- ...
|
19
|
+
:nick: your-bot-nick
|
20
|
+
:plugins.plugins:
|
21
|
+
- Hibot::Spotify
|
22
|
+
- ... # see the plugin list below to see which plugins are available
|
23
|
+
```
|
24
|
+
|
25
|
+
**NOTE : ** The default hibotrc location is in your $HOME directory. So if you don't want to override the default behavior, just create a hidden .hibotrc file in your $HOME.
|
26
|
+
|
27
|
+
Then, just run the hibot binary to launch the bot. If you changed to default hibotrc location, you can use the -c or --config flag to specify where is your config file.
|
28
|
+
|
29
|
+
## Plugins
|
30
|
+
|
31
|
+
At the moment, the following plugins are available :
|
32
|
+
|
33
|
+
To use a plugin, first you have to add it to the hibotrc file. Then configure the plugin if some extra configuration is needed. Here is the plugin list and the instructions per plugin :
|
34
|
+
|
35
|
+
1. Hibot::Spotify : allows you to parse Spotify uri when pasted in a channel or to search through Spotify's API some data.
|
36
|
+
|
37
|
+
To use this plugin, you have to create a spotify application. You can do it from [here](https://developer.spotify.com/my-applications). When it's done, copy you client ID and client Secret to the hibotrc file with that structure :
|
38
|
+
|
39
|
+
```yaml
|
40
|
+
---
|
41
|
+
# here comes the general configuration
|
42
|
+
:Hibot::Spotify:
|
43
|
+
:client_id: your_client_id
|
44
|
+
:client_secret: your_client_secret
|
45
|
+
```
|
46
|
+
|
47
|
+
## Contribute
|
48
|
+
1. Fork it
|
49
|
+
2. Dev it
|
50
|
+
3. Pull request it
|
51
|
+
4. Enjoy it
|
data/Rakefile
ADDED
data/bin/hibot
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "optparse"
|
4
|
+
require 'hibot'
|
5
|
+
|
6
|
+
|
7
|
+
opts = {
|
8
|
+
path: File.join(File.expand_path('~'), '.hibotrc')
|
9
|
+
}
|
10
|
+
|
11
|
+
OptionParser.new do |o|
|
12
|
+
o.banner = "USAGE: #{$0} [options]"
|
13
|
+
|
14
|
+
o.on("-c", "--config [CONFIG PATH]", "Set the location of the .hibotrc file") do |p|
|
15
|
+
opts[:path] = p
|
16
|
+
end
|
17
|
+
end.parse!
|
18
|
+
|
19
|
+
Hibot.launch(opts)
|
data/hibot.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = 'hibot'
|
5
|
+
s.version = '0.0.1'
|
6
|
+
s.date = '2015-04-16'
|
7
|
+
s.summary = "IRC bot supporting multiple services."
|
8
|
+
s.description = "IRC bot supporting multiple services like spotify, giphy and so on."
|
9
|
+
s.authors = ["Nicolas Collard"]
|
10
|
+
s.email = 'niko@hito.be'
|
11
|
+
s.files = ["lib/hibot.rb"]
|
12
|
+
s.homepage = 'https://github.com/Hito01/Hibot'
|
13
|
+
s.license = 'MIT'
|
14
|
+
|
15
|
+
s.add_dependency "cinch", "~> 2.2"
|
16
|
+
s.add_dependency "httparty", "~> 0.13"
|
17
|
+
s.add_dependency "rainbow", "~> 2.0"
|
18
|
+
|
19
|
+
s.add_development_dependency "bundler", "~> 1.9"
|
20
|
+
s.add_development_dependency "rake", "~> 10.4"
|
21
|
+
|
22
|
+
s.files = `git ls-files`.split($\)
|
23
|
+
s.test_files = s.files.grep(/^spec/)
|
24
|
+
|
25
|
+
s.executables << "hibot"
|
26
|
+
end
|
data/lib/api/spotify.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
module API
|
2
|
+
module Spotify
|
3
|
+
WS_URL = "https://api.spotify.com/v1"
|
4
|
+
PERMITTED_TYPES = %w{album artist track}
|
5
|
+
URI_REGEX = /spotify:([a-z]+):(\w+)/
|
6
|
+
|
7
|
+
def search(query)
|
8
|
+
# Check that parameters are correct or return the corresponding error
|
9
|
+
type, q = query.split(' ')
|
10
|
+
return "Invalid search request. You have to provide a valid type (artist, album or track) and then your query" if type.nil? || q.nil?
|
11
|
+
return "Bad request. Allowed types are album, artist and track." unless PERMITTED_TYPES.include?(type)
|
12
|
+
|
13
|
+
# Perform the search and return the result
|
14
|
+
result = ""
|
15
|
+
response = HTTParty.get("#{WS_URL}/search?type=#{type}&q=#{URI.encode(q)}")
|
16
|
+
if response["#{type}s"] && response["#{type}s"]['items'].count > 0
|
17
|
+
i = 1
|
18
|
+
response["#{type}s"]['items'].each do |item|
|
19
|
+
result += "#{i}. #{item['name']} --> #{item['uri']} --> #{item['external_urls']['spotify']}\n"
|
20
|
+
i += 1
|
21
|
+
break if i == 5
|
22
|
+
end
|
23
|
+
else
|
24
|
+
result = "Nothing found with that parameter."
|
25
|
+
end
|
26
|
+
result
|
27
|
+
end
|
28
|
+
|
29
|
+
def parse_uri(uri)
|
30
|
+
matcher = uri.match(URI_REGEX)
|
31
|
+
type = matcher[1]
|
32
|
+
spotify_id = matcher[2]
|
33
|
+
parsed_uri = nil
|
34
|
+
response = HTTParty.get("#{WS_URL}/#{type}s/#{spotify_id}?client_id=#{@@client_id}")
|
35
|
+
if response['name']
|
36
|
+
if response['artists']
|
37
|
+
parsed_uri = response['artists'][0]['name'] + " - " + response['name']
|
38
|
+
else
|
39
|
+
parsed_uri = response['name']
|
40
|
+
end
|
41
|
+
end
|
42
|
+
parsed_uri
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/config.rb
ADDED
File without changes
|
data/lib/hibot.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
# vendor gems
|
2
|
+
require 'cinch'
|
3
|
+
require 'httparty'
|
4
|
+
require 'rainbow'
|
5
|
+
|
6
|
+
# custom classes
|
7
|
+
require 'hibot/helpers/configuration'
|
8
|
+
require 'api/spotify'
|
9
|
+
require 'hibot/plugins/spotify'
|
10
|
+
|
11
|
+
|
12
|
+
module Hibot
|
13
|
+
extend Configuration
|
14
|
+
def self.launch(opts)
|
15
|
+
# Read the config file and get all the settings in the config hash
|
16
|
+
config = self.configure(opts)
|
17
|
+
bot = Cinch::Bot.new do
|
18
|
+
configure do |c|
|
19
|
+
# General bot settings such server, channels etc
|
20
|
+
config[:general].each {|opt, value|
|
21
|
+
c.send("#{opt}=".to_sym, value)
|
22
|
+
}
|
23
|
+
|
24
|
+
# Load plugins
|
25
|
+
c.plugins.plugins = []
|
26
|
+
config[:general]['plugins.plugins'.to_sym].each do |plugin|
|
27
|
+
c.plugins.plugins << Object.const_get(plugin)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Loop to configure each activated plugins
|
33
|
+
config[:general]['plugins.plugins'.to_sym].each do |plugin|
|
34
|
+
# Format the plugin name to call the appropriate configure method
|
35
|
+
plugin_name = plugin.split('::').join('_').downcase
|
36
|
+
self.send("configure_#{plugin_name}", config[plugin.to_sym])
|
37
|
+
end
|
38
|
+
|
39
|
+
bot.start
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module Configuration
|
4
|
+
def configure(opts)
|
5
|
+
unless config_file_exists?(opts[:path])
|
6
|
+
STDERR.puts Rainbow("Config file .hibotrc not found. Please ensure that it exists in your home directory or override the default location with the option corresponding.").red
|
7
|
+
exit 1
|
8
|
+
end
|
9
|
+
|
10
|
+
config = read_config_file(opts[:path])
|
11
|
+
end
|
12
|
+
|
13
|
+
def config_file_exists?(path)
|
14
|
+
File.exists?(path)
|
15
|
+
end
|
16
|
+
|
17
|
+
def read_config_file(path)
|
18
|
+
config = YAML.load_file(path)
|
19
|
+
end
|
20
|
+
|
21
|
+
def configure_hibot_spotify(opts)
|
22
|
+
opts.each {|opt, value|
|
23
|
+
API::Spotify.class_variable_set("@@#{opt}", value)
|
24
|
+
}
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Hibot
|
2
|
+
class Spotify
|
3
|
+
include Cinch::Plugin
|
4
|
+
include API::Spotify
|
5
|
+
|
6
|
+
match "search", method: :search
|
7
|
+
match API::Spotify::URI_REGEX, {method: :parse, use_prefix: false}
|
8
|
+
|
9
|
+
def search(m)
|
10
|
+
# Search on the message without !search and without any trailing spaces
|
11
|
+
result = search(m.message.gsub('!search', '').split)
|
12
|
+
m.reply result
|
13
|
+
end
|
14
|
+
|
15
|
+
def parse(m)
|
16
|
+
parsed_uri = parse_uri(m.message)
|
17
|
+
m.reply parsed_uri unless parsed_uri.nil?
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
RSpec.describe API::Spotify do
|
2
|
+
let(:obj) { Object.new.extend(described_class) }
|
3
|
+
|
4
|
+
before(:each) do
|
5
|
+
config = Hibot.configure({path: File.expand_path("../../hibotrc", __FILE__)})
|
6
|
+
Hibot.configure_hibot_spotify(config['Hibot::Spotify'.to_sym])
|
7
|
+
end
|
8
|
+
|
9
|
+
context "parse_uri method" do
|
10
|
+
it "should return a result if the uri matches with some results" do
|
11
|
+
expect(obj.parse_uri('spotify:track:0YQznyH9mJn6UTwWFHqy4b')).to eq('Nicolas Jaar - El Bandido')
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should return nil if the uri doesn't match with any results" do
|
15
|
+
expect(obj.parse_uri('spotify:track:xxxxxxxxxxxxxxxxxx')).to eq(nil)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context "search method" do
|
20
|
+
it "should return an error message if the number of arguments is not equal to 2" do
|
21
|
+
expect(obj.search('foo')).to eq('Invalid search request. You have to provide a valid type (artist, album or track) and then your query')
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should return an error message if the type is not in the permitted types list" do
|
25
|
+
expect(obj.search('foo query')).to eq('Bad request. Allowed types are album, artist and track.')
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should return a string saying not found if the query doesn't return any results" do
|
29
|
+
expect(obj.search('album foobartest')).to eq('Nothing found with that parameter.')
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should return a string with maximum 5 results if the query matches to something" do
|
33
|
+
expect(obj.search('track eminem')).to eq("1. 'Till I Collapse --> spotify:track:6yr8GiTHWvFfi4o6Q5ebdT --> https://open.spotify.com/track/6yr8GiTHWvFfi4o6Q5ebdT\n2. Lose Yourself - Soundtrack Version --> spotify:track:7w9bgPAmPTtrkt2v16QWvQ --> https://open.spotify.com/track/7w9bgPAmPTtrkt2v16QWvQ\n3. The Monster --> spotify:track:5U8hKxSaDXB8cVeLFQjvwx --> https://open.spotify.com/track/5U8hKxSaDXB8cVeLFQjvwx\n4. Mockingbird --> spotify:track:17baAghWcrewNOcc9dCewx --> https://open.spotify.com/track/17baAghWcrewNOcc9dCewx\n")
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/spec/foo
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
RSpec.describe Configuration do
|
2
|
+
let(:obj) { Object.new.extend(Configuration) }
|
3
|
+
let(:config_path) { File.expand_path("../../foo", __FILE__) }
|
4
|
+
let(:create_file) { FileUtils.touch(config_path) }
|
5
|
+
let(:delete_file) { FileUtils.remove_entry(config_path) }
|
6
|
+
|
7
|
+
describe "check if the .hibotrc file exists" do
|
8
|
+
it "should return false if it doesn't exist" do
|
9
|
+
begin delete_file; rescue;end
|
10
|
+
expect(obj.config_file_exists?(config_path)).to eq(false)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should return true if it exists" do
|
14
|
+
create_file
|
15
|
+
expect(obj.config_file_exists?(config_path)).to eq(true)
|
16
|
+
delete_file
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "parse the config file" do
|
21
|
+
before(:each) do create_file end
|
22
|
+
after(:each) do delete_file end
|
23
|
+
|
24
|
+
it "should return false if the file is empty" do
|
25
|
+
expect(obj.read_config_file(config_path)).to eq(false)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should return a hash with all the settings if file is not empty" do
|
29
|
+
File.open(config_path, 'w') {|f| f.write({foo: 'bar', hello: 'world'}.to_yaml)}
|
30
|
+
expect(obj.read_config_file(config_path)).to eq({foo: 'bar', hello: 'world'})
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "configure the gem" do
|
35
|
+
it "should exit if the path provided is not a valid config file" do
|
36
|
+
opts = {path: "/var/foo/bar"}
|
37
|
+
expect { obj.configure(opts) }.to raise_error(SystemExit)
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should return a hash with the settings contained in the config file" do
|
41
|
+
opts = {path: config_path}
|
42
|
+
File.open(config_path, 'w') {|f| f.write({foo: 'bar', hello: 'world'}.to_yaml)}
|
43
|
+
expect(obj.configure(opts)).to eq({foo: 'bar', hello: 'world'})
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "configure the spotify plugin" do
|
48
|
+
it "should create class variable for each options" do
|
49
|
+
opts = {foo: "bar", bar: "foo"}
|
50
|
+
obj.configure_hibot_spotify(opts)
|
51
|
+
expect(API::Spotify.class_variable_defined?(:@@foo)).to eq(true)
|
52
|
+
expect(API::Spotify.class_variable_get(:@@foo)).to eq('bar')
|
53
|
+
expect(API::Spotify.class_variable_defined?(:@@bar)).to eq(true)
|
54
|
+
expect(API::Spotify.class_variable_get(:@@bar)).to eq('foo')
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,134 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: hibot
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Nicolas Collard
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-04-16 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: cinch
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.2'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.2'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: httparty
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.13'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.13'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rainbow
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '2.0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '2.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: bundler
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.9'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ~>
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.9'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rake
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ~>
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '10.4'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ~>
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '10.4'
|
83
|
+
description: IRC bot supporting multiple services like spotify, giphy and so on.
|
84
|
+
email: niko@hito.be
|
85
|
+
executables:
|
86
|
+
- hibot
|
87
|
+
extensions: []
|
88
|
+
extra_rdoc_files: []
|
89
|
+
files:
|
90
|
+
- .gitignore
|
91
|
+
- .rspec
|
92
|
+
- Gemfile
|
93
|
+
- README.md
|
94
|
+
- Rakefile
|
95
|
+
- bin/hibot
|
96
|
+
- hibot.gemspec
|
97
|
+
- lib/api/spotify.rb
|
98
|
+
- lib/config.rb
|
99
|
+
- lib/hibot.rb
|
100
|
+
- lib/hibot/helpers/configuration.rb
|
101
|
+
- lib/hibot/plugins/spotify.rb
|
102
|
+
- spec/api/spotify_spec.rb
|
103
|
+
- spec/foo
|
104
|
+
- spec/helpers/configuration_spec.rb
|
105
|
+
- spec/spec_helper.rb
|
106
|
+
homepage: https://github.com/Hito01/Hibot
|
107
|
+
licenses:
|
108
|
+
- MIT
|
109
|
+
metadata: {}
|
110
|
+
post_install_message:
|
111
|
+
rdoc_options: []
|
112
|
+
require_paths:
|
113
|
+
- lib
|
114
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - '>='
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '0'
|
119
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
120
|
+
requirements:
|
121
|
+
- - '>='
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: '0'
|
124
|
+
requirements: []
|
125
|
+
rubyforge_project:
|
126
|
+
rubygems_version: 2.2.0
|
127
|
+
signing_key:
|
128
|
+
specification_version: 4
|
129
|
+
summary: IRC bot supporting multiple services.
|
130
|
+
test_files:
|
131
|
+
- spec/api/spotify_spec.rb
|
132
|
+
- spec/foo
|
133
|
+
- spec/helpers/configuration_spec.rb
|
134
|
+
- spec/spec_helper.rb
|