syndi 0.1.0 → 0.1.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.
@@ -1,170 +0,0 @@
1
- # Copyright (c) 2013, Autumn Perrault, et al. All rights reserved.
2
- # This free software is distributed under the FreeBSD license (see LICENSE).
3
-
4
- require 'thread'
5
- require 'syndi/verbosity'
6
- require 'syndi/api/object'
7
-
8
- # Entering namespace: Syndi
9
- module Syndi
10
-
11
- # Entering namespace: API
12
- module API
13
-
14
- # A class which provides the the fundamental event system, upon which
15
- # much of the API is based, and which follows a simple model of broadcasting
16
- # and hooking onto such broadcasts.
17
- #
18
- # Plugin writers may be rather interested in {Syndi::DSL::Base}, since that
19
- # provides a simpler interface to Syndi's instances of this class.
20
- #
21
- # @api Syndi
22
- # @since 4.0.0
23
- # @author noxgirl
24
- #
25
- # @see Syndi::DSL::Base
26
- #
27
- # @!attribute [r] threads
28
- # @return [Array] An array of threads used by {#call}.
29
- class Events < Syndi::API::Object
30
-
31
- attr_reader :events, :threads
32
-
33
- # Create a new instance of Syndi::API::Events.
34
- def initialize
35
- @events = {}
36
- @threads = []
37
- end
38
-
39
- # Listen for (hook onto) an event.
40
- #
41
- # @param [Symbol] event The name of the event for which to listen.
42
- # @param [Integer] priority The priority of the event from 1-5, 1 being utmost priority.
43
- #
44
- # @yield [...] The arguments that will be yielded to the block vary by event.
45
- # Please consult with the {file:docs/Events.md events specification} for details by event.
46
- #
47
- # @return [Array(Symbol, Integer, String)] Identification data including a unique string. Keep
48
- # this if you need to destroy the hook later.
49
- #
50
- # @example
51
- # events.on :disconnect do |irc|
52
- # puts "I'm dying!"
53
- # end
54
- #
55
- # @see Syndi::DSL::Base#on
56
- # @see file:docs/Events.md
57
- def on(event, priority=3, &cb)
58
-
59
- # Priority must be in the range of 1-5.
60
- unless (1..5).include? priority
61
- return 0
62
- end
63
-
64
- # If the event does not exist, create it.
65
- @events[event] ||= {1 => {}, 2 => {}, 3 => {}, 4 => {}, 5 => {}}
66
-
67
- # Generate a unique pseudorandom ID for this hook.
68
- id = ''
69
- 10.times { id += get_rand_char }
70
- while @events[event][priority].has_key? id
71
- id = ''
72
- 10.times { id += get_rand_char }
73
- end
74
-
75
- # Create the hook in memory.
76
- @events[event][priority][id] = cb
77
-
78
- [event, priority, id]
79
-
80
- end
81
-
82
- # Broadcast an event and associated arguments.
83
- #
84
- # The arguments are globbed into an array from the list passed to the
85
- # method, so be sure to format your call correctly.
86
- #
87
- # If a hook returns +false+, all subsequent hook executions will be
88
- # forestalled from occurring.
89
- #
90
- # @param [Symbol] event The event being broadcasted.
91
- # @param [Array] args A list of arguments which should be passed to
92
- # the listeners. (splat)
93
- #
94
- # @example
95
- # events.call(:cow_moo, "the cows", "go moo", [1, 3, 5])
96
- #
97
- # @see Syndi::DSL::Base#emit
98
- def call(event, *args)
99
- # Check if any hooks exist for this event.
100
- if @events.include? event
101
-
102
- $m.verbose("A thread is spawning for an event broadcast (:#{event}).", VNOISY) do
103
- @threads << Thread.new(event) do |evnt|
104
-
105
- status = nil
106
-
107
- begin # catch exceptions
108
- # Iterate through the hooks.
109
- @events[evnt].each_key do |priority|
110
- @events[evnt][priority].each_value do |prc|
111
- status = prc.call(*args) unless status == false
112
- end # each hook
113
- end # each priority
114
- rescue => e
115
- $m.error "An exception occurred within the thread of :#{event}: #{e}", false, e.backtrace
116
- end # begin
117
-
118
- end # thread
119
- end # verbose
120
-
121
- end # whether this event exists
122
- end
123
-
124
- # Delete a hook or listener.
125
- #
126
- # @param [Array(Symbol, Integer, String)] id The identification data of the hook,
127
- # as provided by #on.
128
- #
129
- # @see Syndi::DSL::Base#undo_on
130
- def del(id)
131
- event, priority, hook = id
132
-
133
- if @events.has_key? event
134
- if @events[event][priority].has_key? hook
135
- @events[event][priority].delete(hook)
136
- end
137
- end
138
-
139
- tidy
140
- end
141
-
142
- # Terminate all active threads.
143
- def die
144
- @threads.each { |thr| thr.kill }
145
- end
146
-
147
- #######
148
- private
149
- #######
150
-
151
- # Tidy up.
152
- def tidy
153
- @events.each do |name, lists|
154
- empty = true
155
- empty = lists.each_value { |v| break false if not v.empty? }
156
- if empty
157
- # Drop the event.
158
- @events.delete name
159
- next
160
- end
161
- end
162
- end
163
-
164
- end # class Events
165
-
166
- end # module API
167
-
168
- end # module Syndi
169
-
170
- # vim: set ts=4 sts=2 sw=2 et:
@@ -1,155 +0,0 @@
1
- # Copyright (c) 2013, Autumn Perrault, et al. All rights reserved.
2
- # This free software is distributed under the FreeBSD license (see LICENSE).
3
-
4
- require 'ostruct'
5
- require 'libsyndi'
6
- require 'syndi/bot'
7
-
8
- module Syndi
9
-
10
- module API
11
-
12
- # A basic superclass for plugins.
13
- #
14
- # @api Syndi
15
- # @since 4.0.0
16
- # @author noxgirl
17
- # @author swarley
18
- #
19
- # @!attribute [r] name
20
- # @return [String] Name of the plugin.
21
- #
22
- # @!attribute [r] summary
23
- # @return [String] Summary of the plugin.
24
- #
25
- # @!attribute [r] version
26
- # @return [String] Version of the plugin.
27
- #
28
- # @!attribute [r] library
29
- # @return [String] The library upon which the plugin is based.
30
- #
31
- # @!attribute [r] author
32
- # @return [String] Author of the plugin.
33
- #
34
- # @!attribute [r] syndi
35
- # @return [String] Version of Syndi required by the plugin.
36
- class Plugin
37
-
38
- attr_reader :name, :summary, :version, :library, :author, :syndi
39
-
40
- # Configure the plugin.
41
- #
42
- # @yieldparam [OpenStruct] conf Configuration structure.
43
- #
44
- # - +conf.name+: Name of the plugin (String).
45
- # - +conf.summary+: Summary of the plugin (String).
46
- # - +conf.version+: Version of the plugin (String).
47
- # - +conf.library+: Library upon which the plugin is based. (String).
48
- # - +conf.author+: Author of the plugin (String).
49
- # - +conf.syndi+: Required version of Syndi (String). Should be in the format of
50
- # +'~> version'+ or +'>= version'+. +~>+ means at least +version+ but no later
51
- # than the minor version (e.g. +'~> 4.0'+ will allow +4.0.2+ but not +4.1.0+).
52
- # +>=+ means at at least +version+.
53
- #
54
- # Additionally, it should be noted that +conf.library+ should be either of the
55
- # core libraries, *or* 'multi' if it uses multiple libraries.
56
- #
57
- # @example
58
- # configure do |c|
59
- # c.name = 'MagicPlugin'
60
- # c.summary = 'A magical extension.'
61
- # c.version = '1.00'
62
- # c.library = 'irc'
63
- # c.author = 'noxgirl'
64
- # c.syndi = '~> 4.0'
65
- # end
66
- def configure
67
-
68
- # Prepare an open structure.
69
- conf = OpenStruct.new
70
-
71
- # Yield it to the configuration block.
72
- yield conf if block_given?
73
-
74
- # Check for sufficient configuration.
75
- [:name,:summary,:version,:library,:author,:syndi].each do |s|
76
- if conf.send(s).nil?
77
- raise PluginError, "Plugin #{self.inspect} provided insufficient configuration (#{s} is nil)."
78
- end
79
- end
80
-
81
- @name = conf.name
82
- @summary = conf.summary
83
- @version = conf.version
84
- @library = conf.library
85
- @author = conf.author
86
-
87
- # Check for compatibility.
88
- if conf.syndi =~ /^(~>\s*)((?:[\dabcr])(?:\.[\dabcr]))+$/ # ~>
89
-
90
- ver = $2
91
- if Gem::Version.new(ver.dup) >= Gem::Version.new(Syndi::VERSION.dup) # must be later than or equal to current
92
-
93
- # Split current version and plugin-demanded version by '.'.
94
- verarr = Syndi::VERSION.split(/\./)
95
- pverarr = ver.split(/\./)
96
-
97
- # Must be no later than the current minor version
98
- unless verarr[1] <= pverarr[1]
99
- raise PluginError, "Plugin #@name v#@version demands Syndi #{conf.syndi}; current version is #{Syndi::VERSION}. Incompatible! Aborting load!"
100
- end
101
-
102
- @syndi = conf.syndi
103
-
104
- else
105
- raise PluginError, "Plugin #@name v#@version demands Syndi #{conf.syndi}; current version is #{Syndi::VERSION}. Incompatible! Aborting load!"
106
- end # if ver >=
107
-
108
- elsif conf.syndi =~ /^(>=\s*)((?:[\dabcr])(?:\.[\dabcr]))+$/ # >=
109
-
110
- ver = $2
111
- unless ver >= Syndi::VERSION # must be later than or equal to current
112
- raise PluginError, "Plugin #@name v#@version demands Syndi #{conf.syndi}; current version is #{Syndi::VERSION}. Incompatible! Aborting load!"
113
- end
114
-
115
- @syndi = conf.syndi
116
-
117
- else
118
- raise PluginError, "Plugin #@name v#@version cannot be checked for compatibility. Aborting load!"
119
- end # compat check
120
-
121
- # If we've made it this far, it's sufficiently compatible with the API.
122
- # Now, we need to extend this plugin with our domain-specific language (DSL).
123
- self.extend Syndi::DSL::Base # this is the base
124
- case @library
125
-
126
- when 'irc'
127
- self.extend Syndi::DSL::IRC
128
- when 'multi'
129
- # the specifications for multilib DSL functionality are yet undecided
130
- else
131
- # If it's a library we don't comprehend, exception time, it is.
132
- raise PluginError, "Plugin #@name v#@version demands '#{@library}' library, which I do not understand. Aborting load!"
133
-
134
- end
135
-
136
- end # def configure
137
-
138
- #########
139
- protected
140
- #########
141
-
142
- # Inheritance event.
143
- #
144
- # @param [Class] subklass The subclass which has inherited {self}.
145
- def self.inherited(subklass)
146
- $m.debug("[plugin] Syndi::API::Plugin inherited by #{subklass}")
147
- end
148
-
149
- end # class Plugin
150
-
151
- end # module API
152
-
153
- end # module Syndi
154
-
155
- # vim: set ts=4 sts=2 sw=2 et:
@@ -1,23 +0,0 @@
1
- # Copyright (c) 2013, Autumn Perrault, et al. All rights reserved.
2
- # This free software is distributed under the FreeBSD license (see LICENSE).
3
-
4
- require 'thor'
5
- require 'psych'
6
-
7
- module Syndi
8
- module Configure
9
-
10
- # A command-line interface for making modifications to an existing Syndi
11
- # configuration file (which is in YAML).
12
- class CLI < Thor
13
-
14
-
15
-
16
-
17
- end
18
-
19
- end
20
- end
21
-
22
-
23
- # vim: set ts=4 sts=2 sw=2 et: