blur 1.8.6 → 2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -38,9 +38,9 @@ module Blur
38
38
  # Called when a line was received, the connection sends it to the network
39
39
  # delegate which then sends it to the client.
40
40
  def receive_line line
41
- command = Command.parse line
41
+ message = IRCParser::Message.parse line
42
42
 
43
- @network.got_command command
43
+ @network.got_message message
44
44
  end
45
45
 
46
46
  # Called when the SSL handshake was completed with the remote server,
@@ -1,140 +1,147 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module Blur
4
- # The +Script+ class is used for encapsulating dynamically loaded ruby scripts.
5
- #
6
- # The {Script#Script} method is then used to shape the DSL-language to make
7
- # writing Blur scripts a breeze.
8
- #
9
- # @todo add examples in the documentation
10
- # @see Script#Script
11
- class Script
12
- include Logging
13
- include Evaluable
14
- include DSL
15
-
16
- ExtensionNotFoundError = Class.new StandardError
17
- Emissions = [:connection_ready, :topic_change, :user_rename, :message,
18
- :private_message, :user_entered, :user_left, :user_quit,
19
- :user_kicked, :topic, :user_mode, :channel_mode,
20
- :channel_created, :channel_who_reply]
21
-
22
- # @return the path in which the script remains.
23
- attr_accessor :__path
24
- # Can be used inside the script to act with the client itself.
25
- # @return [Network::Client] the client delegate.
26
- attr_accessor :__client
27
- # @return [Array] a list of handled emissions.
28
- attr_accessor :__emissions
29
-
30
- # A list of extensions.
31
- @@__extensions = []
32
-
33
- # Find and evaluate script extensions.
34
- def self.load_extensions!
35
- root_path = File.dirname $0
36
-
37
- Dir.glob("#{root_path}/extensions/*.rb").each do |path|
38
- extension = Extension.new path
39
- extension.__client = self
40
- extension.extension_loaded if extension.respond_to? :extension_loaded
41
-
42
- @@__extensions << extension
4
+ module Commands
5
+ # This is a command look-up-table with an autoincrementing index.
6
+ class CommandLUT
7
+ attr_accessor :commands
8
+
9
+ def initialize
10
+ @index = -1
11
+ @commands = {}
12
+ end
13
+
14
+ # Inserts the command to the LUT.
15
+ #
16
+ # @returns the index.
17
+ def << command
18
+ @commands[command] = @index += 1
19
+ @index
43
20
  end
44
21
  end
45
22
 
46
- # "Unload" all script extensions.
47
- def self.unload_extensions!
48
- @@__extensions.clear
23
+ module ClassMethods
24
+ # Creates a new command.
25
+ #
26
+ # @example
27
+ # command! '!ping' do |user, channel, args|
28
+ # channel.say "#{user}: pong"
29
+ # end
30
+ def command! command, *args, &block
31
+ id = (command_lut << command)
32
+ define_method :"_command_#{id}", &block
33
+ end
49
34
  end
50
-
51
- # Check to see if the script has been evaluated.
52
- def evaluated?; @__evaluated end
53
-
54
- # Instantiates a script and evaluates the contents which remain in +path+.
55
- def initialize path
56
- @__path = path
57
- @__evaluated = false
58
- @__emissions = []
59
-
60
- if evaluate_source_file path
61
- cache.load if Cache.exists? @__name
62
-
63
- Emissions.each do |emission|
64
- @__emissions.push emission if respond_to? emission
65
- end
66
-
67
- __send__ :loaded if respond_to? :loaded
68
- __send__ :module_init if respond_to? :module_init
35
+
36
+ def self.included klass
37
+ class << klass
38
+ attr_accessor :command_lut
69
39
  end
40
+
41
+ klass.extend ClassMethods
42
+ klass.command_lut = CommandLUT.new
43
+ klass.register! message: -> (script, user, channel, line) {
44
+ command, args = line.split ' ', 2
45
+ return unless command
46
+
47
+ if id = klass.command_lut.commands[command.downcase]
48
+ script.__send__ :"_command_#{id}", user, channel, args
49
+ end
50
+ }
70
51
  end
71
-
72
- # Make it a DSL-way of writing a script.
73
- #
74
- # @example
75
- # Script :example do
76
- # def connection_ready network
77
- # #
78
- # end
79
- # end
80
- def Script name, options = {}, &block
81
- @__name = name
82
-
83
- extensions = options[:using] || options[:uses]
84
-
85
- # Automatically used extensions.
86
- if extensions
87
- extensions.each {|extension_name| using extension_name }
52
+ end
53
+
54
+ class SuperScript
55
+ class << self
56
+ attr_accessor :name, :authors, :version, :description, :events
57
+
58
+ # Sets the author.
59
+ #
60
+ # @example
61
+ # Author 'John Doe <john.doe@example.com>'
62
+ def Author *authors
63
+ @authors = authors
88
64
  end
89
65
 
90
- # Automatically included modules.
91
- if options[:includes]
92
- options[:includes].each{|module_name| self.extend module_name }
66
+ # Sets the description.
67
+ #
68
+ # @example
69
+ # Description 'This is an example script.'
70
+ def Description description
71
+ @description = description
72
+ end
73
+
74
+ # Sets the version.
75
+ #
76
+ # @example
77
+ # Version '1.0.0'
78
+ def Version version
79
+ @version = version
93
80
  end
94
-
95
- instance_eval &block
96
-
97
- true
98
- end
99
81
 
100
- # Add script extension and define a method with the same name as
101
- # the extension.
102
- def using *extension_names
103
- extension_names.each do |extension_name|
104
- if extension = @@__extensions.find{|ext| ext.__name.to_s == extension_name.to_s }
105
- extension.extension_used self if extension.respond_to? :extension_used
106
- self.metaclass.send :define_method, :"#{extension_name}" do
107
- return extension
82
+ # Registers events to certain functions.
83
+ #
84
+ # @example
85
+ # register! message: :on_message, connection_ready: :connected
86
+ def register! *args
87
+ args.each do |events|
88
+ case events
89
+ when Hash
90
+ events.each do |event, method_name|
91
+ register_event! event, method_name
92
+ end
93
+ when Array
94
+ register! *events
95
+ when Symbol
96
+ register_event! events
108
97
  end
109
- else
110
- raise ExtensionNotFoundError, "Extension not found: #{extension_name}"
111
98
  end
112
99
  end
113
- end
114
-
115
- # Unload the script and save the cache, if present.
116
- def unload!
117
- cache.save if @__cache
118
- __send__ :unloaded if respond_to? :unloaded
119
100
 
120
- @__cache = nil
121
- end
101
+ # Adds the given event +name+ and the name of the method to call once the
102
+ # event is emitted.
103
+ def register_event! name, method_name = name
104
+ (@events[name] ||= []) << method_name
105
+ end
122
106
 
123
- # Access another script with name +name+.
124
- #
125
- # @return [Script] the script with the name +name+, or nil.
126
- def script name
127
- @__client.scripts.find { |script| script.__name == name }
128
- end
129
-
130
- # Get the cache, if none, instantiate a new cache.
131
- def cache
132
- @__cache ||= Cache.new self
107
+ def to_s; inspect end
108
+ def inspect; %%#<SuperScript:0x#{self.object_id.to_s 16}>% end
109
+
110
+ alias :author :authors
111
+ alias :Authors :Author
133
112
  end
134
-
135
- # Convert it to a debug-friendly format.
113
+
114
+ # Called when when the superscript has been loaded and added to the list of
115
+ # superscripts.
116
+ def self.init; end
117
+
118
+ # Called right before the script is being removed from the list of
119
+ # superscripts.
120
+ def self.deinit; end
121
+
122
+ # Reference to the main client that holds the script.
123
+ attr_accessor :_client_ref
124
+
125
+ # Script-specific configuration that is read from the main configuration
126
+ # file.
127
+ attr_accessor :config
128
+
129
+ attr_accessor :cache
130
+
131
+ # Called right before the instance of the script is being removed.
132
+ def unloaded; end
133
+
134
+ # Gets the instantiated script with +name+.
135
+ def script name; _client_ref.scripts[name] end
136
+
137
+ # Gets a human-readable representation of the script.
136
138
  def inspect
137
- File.basename @__path
139
+ "#<Script(#{self.class.name.inspect}) " \
140
+ "@author=#{self.class.author.inspect} " \
141
+ "@version=#{self.class.version.inspect} " \
142
+ "@description=#{self.class.description.inspect}>"
138
143
  end
144
+
145
+ def to_s; inspect end
139
146
  end
140
147
  end
@@ -0,0 +1,43 @@
1
+ # encoding: utf-8
2
+
3
+ module Blur
4
+ class ScriptCache < Hash
5
+ def initialize script_name, path, hash
6
+ @script_name = script_name
7
+ @path = path
8
+ @hash = hash
9
+ end
10
+
11
+ # Gets a cache +value+ by its +key+.
12
+ def [] key; @hash[key] end
13
+
14
+ # Sets the cache +key+ to the provided +value+.
15
+ def []= key, value; @hash[key] = value end
16
+
17
+ # Saves the cache as a YAML file.
18
+ def save
19
+ directory = File.dirname @path
20
+
21
+ unless File.directory? directory
22
+ Dir.mkdir directory
23
+ end
24
+
25
+ File.open @path, ?w do |file|
26
+ YAML.dump @hash, file
27
+ end
28
+ end
29
+
30
+ # Loads the cache file for +script_name+ in +cache_dir+ if it exists.
31
+ def self.load script_name, cache_dir
32
+ cache_path = File.join cache_dir, "#{script_name}.yml"
33
+
34
+ if File.exists? cache_path
35
+ object = YAML.load_file cache_path
36
+
37
+ ScriptCache.new script_name, cache_path, object
38
+ else
39
+ ScriptCache.new script_name, cache_path, {}
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,105 @@
1
+ # encoding: utf-8
2
+
3
+ module Blur
4
+ # The +User+ class is used for encapsulating a user and its properties.
5
+ #
6
+ # The user owns a reference to its parent channel.
7
+ #
8
+ # Modes can be set for a user, but Blur is not
9
+ # {http://www.irc.org/tech_docs/005.html ISupport}-compliant yet.
10
+ #
11
+ # @todo make so that channels *and* users belongs to the network, and not
12
+ # like now where the user belongs to the channel, resulting in multiple
13
+ # user instances.
14
+ class User
15
+ # @return [String] the users nickname.
16
+ attr_accessor :nick
17
+ # @return [String] the users username.
18
+ attr_accessor :name
19
+ # @return [String] the users hostname.
20
+ attr_accessor :host
21
+ # @return [String] all the modes set on the user.
22
+ attr_accessor :modes
23
+ # @return [Network] a reference to the network.
24
+ attr_accessor :network
25
+ attr_accessor :channels
26
+
27
+ # Check to see if the user is an admin (+a)
28
+ def admin?; @modes.include? "a" end
29
+ # Check to see if the user has voice (+v)
30
+ def voice?; @modes.include? "v" end
31
+ # Check to see if the user is the owner (+q)
32
+ def owner?; @modes.include? "q" end
33
+ # Check to see if the user is an operator (+o)
34
+ def operator?; @modes.include? "o" end
35
+ # Check to see if the user is an half-operator (+h)
36
+ def half_operator?; @modes.include? "h" end
37
+
38
+ # Instantiate a user with a nickname.
39
+ def initialize nick, network = nil
40
+ @nick = nick
41
+ @modes = String.new
42
+ @channels = []
43
+ @network = network
44
+
45
+ if modes = prefix_to_mode(nick[0])
46
+ @nick = nick[1..-1]
47
+ @modes = modes
48
+ end
49
+ end
50
+
51
+ # Merge the users mode corresponding to the leading character (+ or -).
52
+ #
53
+ # @param [String] modes the modes to merge with.
54
+ def merge_modes modes
55
+ addition = true
56
+
57
+ modes.each_char do |char|
58
+ case char
59
+ when ?+
60
+ addition = true
61
+ when ?-
62
+ addition = false
63
+ else
64
+ addition ? @modes.concat(char) : @modes.delete!(char)
65
+ end
66
+ end
67
+ end
68
+
69
+ # Send a private message to the user.
70
+ #
71
+ # @param [String] message the message to send.
72
+ def say message
73
+ @network.say self, message
74
+ end
75
+
76
+ # Convert it to a debug-friendly format.
77
+ def inspect
78
+ %{#<#{self.class.name}:0x#{self.object_id.to_s 16} @nick=#{@nick.inspect}>}
79
+ end
80
+
81
+ # Called when YAML attempts to save the object, which happens when a
82
+ # scripts cache contains this user and the script is unloaded.
83
+ def to_yaml options = {}
84
+ @nick.to_yaml options
85
+ end
86
+
87
+ # Get the users nickname.
88
+ def to_s
89
+ @nick
90
+ end
91
+
92
+ private
93
+
94
+ # Translate a nickname-prefix to a mode character.
95
+ def prefix_to_mode prefix
96
+ case prefix
97
+ when '@' then 'o'
98
+ when '+' then 'v'
99
+ when '%' then 'h'
100
+ when '&' then 'a'
101
+ when '~' then 'q'
102
+ end
103
+ end
104
+ end
105
+ end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Blur
4
4
  # The current version of Blur.
5
- Version = "1.8.6"
5
+ Version = "2.1"
6
6
 
7
7
  # Get the current version.
8
8
  #
metadata CHANGED
@@ -1,71 +1,67 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: blur
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.8.6
4
+ version: '2.1'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mikkel Kroman
8
8
  autorequire:
9
- bindir: bin
9
+ bindir: executables
10
10
  cert_chain: []
11
- date: 2016-01-11 00:00:00.000000000 Z
11
+ date: 2017-09-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: majic
14
+ name: deep_merge
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0.4'
19
+ version: '1.1'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '0.4'
26
+ version: '1.1'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: eventmachine
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '1.0'
33
+ version: '1.2'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '1.0'
40
+ version: '1.2'
41
41
  description:
42
42
  email: mk@uplink.io
43
- executables: []
43
+ executables:
44
+ - blur
44
45
  extensions: []
45
46
  extra_rdoc_files: []
46
47
  files:
47
48
  - ".yardopts"
48
49
  - LICENSE
49
50
  - README.md
51
+ - executables/blur
50
52
  - library/blur.rb
53
+ - library/blur/callbacks.rb
54
+ - library/blur/channel.rb
51
55
  - library/blur/client.rb
52
- - library/blur/encryption.rb
53
- - library/blur/encryption/base64.rb
54
- - library/blur/encryption/fish.rb
55
56
  - library/blur/enhancements.rb
56
- - library/blur/evaluable.rb
57
- - library/blur/extension.rb
58
57
  - library/blur/handling.rb
58
+ - library/blur/logging.rb
59
59
  - library/blur/network.rb
60
- - library/blur/network/channel.rb
61
- - library/blur/network/command.rb
62
60
  - library/blur/network/connection.rb
63
61
  - library/blur/network/isupport.rb
64
- - library/blur/network/user.rb
65
62
  - library/blur/script.rb
66
- - library/blur/script/cache.rb
67
- - library/blur/script/commands.rb
68
- - library/blur/script/dsl.rb
63
+ - library/blur/script_cache.rb
64
+ - library/blur/user.rb
69
65
  - library/blur/version.rb
70
66
  homepage: https://github.com/mkroman/blur
71
67
  licenses:
@@ -87,7 +83,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
87
83
  version: '0'
88
84
  requirements: []
89
85
  rubyforge_project:
90
- rubygems_version: 2.2.0
86
+ rubygems_version: 2.6.13
91
87
  signing_key:
92
88
  specification_version: 4
93
89
  summary: An event-driven IRC-framework for Ruby.