syndi 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: