smuxi_hooks 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d5e13abb87b2be4c8d8be22897e8b89ba0a3b363
4
+ data.tar.gz: 1f72953d20a1fa2b2a3043f14f21456784a44bb5
5
+ SHA512:
6
+ metadata.gz: 82eaac10c2e2bb499e170f48952f64e64fdab42b9c8477669f47415145e90568ea636adb5c18fdd43ef1da6661b29d6bc17d45635c5e6d85447a8eb134fe5376
7
+ data.tar.gz: 3ab9ff3a2f2154ffd2f28d284e72f5817e954f67f8446f317057681fb789595dd0c70034d1c26168f2f686d6bf7e32ef681a370e1ce35aa824ebc43bc7ec54aa
@@ -0,0 +1,12 @@
1
+ # Project metadata
2
+ nbproject
3
+ .idea
4
+
5
+ Gemfile.lock
6
+
7
+ doc/api
8
+ coverage
9
+ pkg
10
+ .yardoc
11
+ .rbx
12
+ *.rbc
@@ -0,0 +1,9 @@
1
+ --output-dir=doc/api
2
+ --embed-mixins
3
+ --protected
4
+ --no-private
5
+ --markup-provider=redcarpet
6
+ --markup=markdown
7
+ -
8
+ HISTORY.md
9
+ LICENSE.md
data/Gemfile ADDED
@@ -0,0 +1,23 @@
1
+ # encoding: UTF-8
2
+ =begin
3
+ Copyright GodObject Team <dev@godobject.net>, 2015
4
+
5
+ This file is part of Smuxi hooks API for Ruby.
6
+
7
+ Permission to use, copy, modify, and/or distribute this software for any
8
+ purpose with or without fee is hereby granted, provided that the above
9
+ copyright notice and this permission notice appear in all copies.
10
+
11
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
12
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
13
+ FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
14
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
16
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17
+ PERFORMANCE OF THIS SOFTWARE.
18
+ =end
19
+
20
+ source 'http://rubygems.org'
21
+
22
+ # Gem dependencies are specified in the .gemspec file
23
+ gemspec
@@ -0,0 +1,6 @@
1
+ 0.1.0 / 2015-01-17
2
+ ==================
3
+
4
+ * 1 major enhancement
5
+
6
+ * Birthday!
@@ -0,0 +1,15 @@
1
+ Copyright GodObject Team <dev@godobject.net>, 2015
2
+
3
+ Smuxi hooks API for Ruby is licensed under the following ISC-style license:
4
+
5
+ Permission to use, copy, modify, and/or distribute this software for any
6
+ purpose with or without fee is hereby granted, provided that the above
7
+ copyright notice and this permission notice appear in all copies.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
10
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
11
+ FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
12
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
14
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15
+ PERFORMANCE OF THIS SOFTWARE.
@@ -0,0 +1,226 @@
1
+ Smuxi hooks API for Ruby
2
+ ========================
3
+
4
+ [![Gem Version](https://badge.fury.io/rb/smuxi_hooks.png)](https://badge.fury.io/rb/smuxi_hooks)
5
+ [![Dependency Status](https://gemnasium.com/godobject/smuxi-hooks-ruby.png)](https://gemnasium.com/godobject/smuxi-hooks-ruby)
6
+ [![Code Climate](https://codeclimate.com/github/godobject/smuxi-hooks-ruby.png)](https://codeclimate.com/github/godobject/smuxi-hooks-ruby)
7
+
8
+ * [Documentation][docs]
9
+ * [Project][project]
10
+
11
+ [docs]: http://rdoc.info/github/godobject/smuxi-hooks-ruby/
12
+ [project]: https://github.com/godobject/smuxi-hooks-ruby/
13
+
14
+ Description
15
+ -----------
16
+
17
+ Plugin framework for the multi-protocol distributed chat client Smuxi.
18
+
19
+ Features / Problems
20
+ -------------------
21
+
22
+ This project tries to conform to:
23
+
24
+ * [Semantic Versioning (2.0.0)][semver]
25
+ * [Ruby Packaging Standard (0.5-draft)][rps]
26
+ * [Ruby Style Guide][style]
27
+ * [Gem Packaging: Best Practices][gem]
28
+
29
+ [semver]: http://semver.org/
30
+ [rps]: http://chneukirchen.github.com/rps/
31
+ [style]: https://github.com/bbatsov/ruby-style-guide
32
+ [gem]: http://weblog.rubyonrails.org/2009/9/1/gem-packaging-best-practices
33
+
34
+ Additional facts:
35
+
36
+ * Written purely in Ruby.
37
+ * Documented with YARD.
38
+ * Intended to be used with Ruby 1.9.3 or higher.
39
+ * Cryptographically signed git tags.
40
+
41
+ Shortcomings and problems:
42
+
43
+ * Currently, not all of the hooks that are available in Smuxi are supported.
44
+ * This library has NOT been tested extensively yet. With high probability
45
+ there are errors hidden in the code, these errors might even have
46
+ dangerous consequences for the security of your system. Please evaluate the
47
+ code thoroughly before using it on a production system.
48
+
49
+ If you have solved any of these feel free to submit your changes back.
50
+
51
+ Requirements
52
+ ------------
53
+
54
+ * Ruby 1.9.3 or higher
55
+
56
+ Installation
57
+ ------------
58
+
59
+ On *nix systems you may need to prefix the command with `sudo` to get root
60
+ privileges.
61
+
62
+ ### Gem
63
+
64
+ gem install smuxi_hooks
65
+
66
+ Usage
67
+ -----
68
+
69
+ This documentation defines the public interface of the software. Don't rely
70
+ on elements marked as private. Those should be hidden in the documentation
71
+ by default.
72
+
73
+ This is still experimental software, even the public interface may change
74
+ substantially in future releases.
75
+
76
+ ### Ruby interface
77
+
78
+ #### Loading
79
+
80
+ In most cases you want to load the code by using the following command:
81
+
82
+ ~~~~~ ruby
83
+ require 'smuxi_hooks'
84
+ ~~~~~
85
+
86
+ In a bundler Gemfile you should use the following:
87
+
88
+ ~~~~~ ruby
89
+ gem 'smuxi_hooks'
90
+ ~~~~~
91
+
92
+ #### Namespace
93
+
94
+ This project is contained within a namespace to avoid name collisions with
95
+ other code. If you do not want to specifiy the namespace explicitly you can
96
+ include it into the current scope by executing the following statement:
97
+
98
+ ~~~~~ ruby
99
+ include GodObject::SmuxiHooks
100
+ ~~~~~
101
+
102
+ #### Further information
103
+
104
+ See the `examples` directory for working plugin examples.
105
+
106
+ A custom plugin constists of only one file that can reside anywhere on the
107
+ filesystem where the Smuxi has access to it. Plugins could therefore easily
108
+ be published as separate gems.
109
+
110
+ Warning: Please make sure that Smuxi is not able to modify the plugin file.
111
+
112
+ To install a plugin on a Smuxi engine, you have to log into the user account,
113
+ the engine runs as:
114
+
115
+ sudo -u smuxi examples/chat_logger.rb install
116
+
117
+ Same goes for uninstalling:
118
+
119
+ sudo -u smuxi examples/chat_logger.rb uninstall
120
+
121
+ Hopefully I will find some time to write some more substantial documentation
122
+ soon.
123
+
124
+ Development
125
+ -----------
126
+
127
+ ### Bug reports and feature requests
128
+
129
+ Please use the [issue tracker][issues] on github.com to let me know about errors
130
+ or ideas for improvement of this software.
131
+
132
+ [issues]: https://github.com/godobject/smuxi-hooks-ruby/issues/
133
+
134
+ ### Source code
135
+
136
+ #### Distribution
137
+
138
+ This software is developed in the source code management system Git. There are
139
+ several synchronized mirror repositories available:
140
+
141
+ * [GitHub][github] (located in California, USA)
142
+
143
+ URL: https://github.com/godobject/smuxi-hooks-ruby.git
144
+
145
+ * [Gitorious][gitorious] (located in Norway)
146
+
147
+ URL: https://git.gitorious.org/smuxi-hooks-ruby/smuxi-hooks-ruby.git
148
+
149
+ * [BitBucket][bitbucket] (located in Colorado, USA)
150
+
151
+ URL: https://bitbucket.org/godobject/smuxi-hooks-ruby.git
152
+
153
+ * [Pikacode][pikacode] (located in France)
154
+
155
+ URL: https://pikacode.com/godobject/smuxi-hooks-ruby.git
156
+
157
+ [github]: https://github.com/godobject/smuxi-hooks-ruby/
158
+ [gitorious]: https://gitorious.org/smuxi-hooks-ruby/smuxi-hooks-ruby/
159
+ [bitbucket]: https://bitbucket.org/godobject/smuxi-hooks-ruby/
160
+ [pikacode]: https://pikacode.com/godobject/smuxi-hooks-ruby/
161
+
162
+ You can get the latest source code with the following command, while
163
+ exchanging the placeholder for one of the mirror URLs:
164
+
165
+ git clone MIRROR_URL
166
+
167
+ #### Tags and cryptographic verification
168
+
169
+ The final commit before each released gem version will be marked by a tag
170
+ named like the version with a prefixed lower-case "v", as required by Semantic
171
+ Versioning. Every tag will be signed by my [OpenPGP public key][openpgp] which
172
+ enables you to verify your copy of the code cryptographically.
173
+
174
+ [openpgp]: https://aef.name/crypto/aef-openpgp.asc
175
+
176
+ Add the key to your GnuPG keyring by the following command:
177
+
178
+ gpg --import aef-openpgp.asc
179
+
180
+ This command will tell you if your code is of integrity and authentic:
181
+
182
+ git tag -v [TAG NAME]
183
+
184
+ #### Building gems
185
+
186
+ To package your state of the source code into a gem package use the following
187
+ command:
188
+
189
+ rake build
190
+
191
+ The gem will be generated according to the .gemspec file in the project root
192
+ directory and will be placed into the pkg/ directory.
193
+
194
+ ### Contribution
195
+
196
+ Help on making this software better is always very appreciated. If you want
197
+ your changes to be included in the official release, please clone the project
198
+ on github.com, create a named branch to commit, push your changes into it and
199
+ send a pull request afterwards.
200
+
201
+ Please make sure to write tests for your changes so that no one else will break
202
+ them when changing other things. Also notice that an inclusion of your changes
203
+ cannot be guaranteed before reviewing them.
204
+
205
+ The following people were involved in development:
206
+
207
+ * Alexander E. Fischer <aef@godobject.net>
208
+
209
+ License
210
+ -------
211
+
212
+ Copyright GodObject Team <dev@godobject.net>, 2015
213
+
214
+ This file is part of Smuxi hooks API for Ruby.
215
+
216
+ Permission to use, copy, modify, and/or distribute this software for any
217
+ purpose with or without fee is hereby granted, provided that the above
218
+ copyright notice and this permission notice appear in all copies.
219
+
220
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
221
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
222
+ FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
223
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
224
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
225
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
226
+ PERFORMANCE OF THIS SOFTWARE.
@@ -0,0 +1,45 @@
1
+ # encoding: UTF-8
2
+ =begin
3
+ Copyright GodObject Team <dev@godobject.net>, 2015
4
+
5
+ This file is part of Smuxi hooks API for Ruby.
6
+
7
+ Permission to use, copy, modify, and/or distribute this software for any
8
+ purpose with or without fee is hereby granted, provided that the above
9
+ copyright notice and this permission notice appear in all copies.
10
+
11
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
12
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
13
+ FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
14
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
16
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17
+ PERFORMANCE OF THIS SOFTWARE.
18
+ =end
19
+
20
+ require 'bundler/gem_tasks'
21
+ require 'rake'
22
+ require 'pathname'
23
+ require 'yard'
24
+
25
+ YARD::Rake::YardocTask.new('doc')
26
+
27
+ desc "Removes temporary project files"
28
+ task :clean do
29
+ %w{doc/api coverage pkg .yardoc .rbx Gemfile.lock}.map{|name| Pathname.new(name) }.each do |path|
30
+ path.rmtree if path.exist?
31
+ end
32
+
33
+ Pathname.glob('*.gem').each &:delete
34
+ Pathname.glob('**/*.rbc').each &:delete
35
+ end
36
+
37
+ desc "Opens an interactive console with the project code loaded"
38
+ task :console do
39
+ Bundler.setup
40
+ require 'pry'
41
+ require 'smuxi_hooks'
42
+ Pry.start(GodObject::SmuxiHooks)
43
+ end
44
+
45
+ task default: :doc
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+ =begin
4
+ Copyright GodObject Team <dev@godobject.net>, 2015
5
+
6
+ This file is part of Smuxi hooks API for Ruby.
7
+
8
+ Permission to use, copy, modify, and/or distribute this software for any
9
+ purpose with or without fee is hereby granted, provided that the above
10
+ copyright notice and this permission notice appear in all copies.
11
+
12
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
13
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
14
+ FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
15
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
16
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
17
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
18
+ PERFORMANCE OF THIS SOFTWARE.
19
+ =end
20
+
21
+ require 'god_object/smuxi'
22
+
23
+ class ChatLogger < GodObject::Smuxi::Plugin
24
+
25
+ LOG_FILE = Pathname.new('/tmp/smuxi_message_log')
26
+
27
+ def message_received
28
+ LOG_FILE.open('a') do |io|
29
+ io.puts("#@sender: #@message (#@protocol_manager_network #@chat_name)")
30
+ end
31
+ end
32
+
33
+ alias message_sent message_received
34
+
35
+ end
36
+
37
+ ChatLogger.execute(__FILE__) if __FILE__ == $PROGRAM_NAME
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+ =begin
4
+ Copyright GodObject Team <dev@godobject.net>, 2015
5
+
6
+ This file is part of Smuxi hooks API for Ruby.
7
+
8
+ Permission to use, copy, modify, and/or distribute this software for any
9
+ purpose with or without fee is hereby granted, provided that the above
10
+ copyright notice and this permission notice appear in all copies.
11
+
12
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
13
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
14
+ FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
15
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
16
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
17
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
18
+ PERFORMANCE OF THIS SOFTWARE.
19
+ =end
20
+
21
+ require 'god_object/smuxi'
22
+
23
+ class KeywordCatcher < GodObject::Smuxi::Plugin
24
+
25
+ def message_sent
26
+ if @message.include?('keyword')
27
+ puts 'Keyword detected!'
28
+ end
29
+ end
30
+
31
+ end
32
+
33
+ KeywordCatcher.execute(__FILE__) if __FILE__ == $PROGRAM_NAME
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+ =begin
4
+ Copyright GodObject Team <dev@godobject.net>, 2015
5
+
6
+ This file is part of Smuxi hooks API for Ruby.
7
+
8
+ Permission to use, copy, modify, and/or distribute this software for any
9
+ purpose with or without fee is hereby granted, provided that the above
10
+ copyright notice and this permission notice appear in all copies.
11
+
12
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
13
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
14
+ FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
15
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
16
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
17
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
18
+ PERFORMANCE OF THIS SOFTWARE.
19
+ =end
20
+
21
+ require 'god_object/smuxi'
22
+
23
+ class Remember < GodObject::Smuxi::Plugin
24
+
25
+ MESSAGE_PATTERN = /remember: (?<data>.+)/
26
+ def message_sent
27
+ if result = MESSAGE_PATTERN.match(@message)
28
+ if state[:memory]
29
+ puts "Previous memory: #{state[:memory]}"
30
+ else
31
+ puts "No previous memory"
32
+ end
33
+
34
+ state[:memory] = result[:data]
35
+ end
36
+ end
37
+
38
+ end
39
+
40
+ Remember.execute(__FILE__) if __FILE__ == $PROGRAM_NAME
@@ -0,0 +1,39 @@
1
+ # encoding: UTF-8
2
+ =begin
3
+ Copyright GodObject Team <dev@godobject.net>, 2015
4
+
5
+ This file is part of Smuxi hooks API for Ruby.
6
+
7
+ Permission to use, copy, modify, and/or distribute this software for any
8
+ purpose with or without fee is hereby granted, provided that the above
9
+ copyright notice and this permission notice appear in all copies.
10
+
11
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
12
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
13
+ FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
14
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
16
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17
+ PERFORMANCE OF THIS SOFTWARE.
18
+ =end
19
+
20
+ # Namespace for projects of the GodObject team <dev@godobject.net>.
21
+ #
22
+ # If you want to be able to simply type Example instead of GodObject::Example
23
+ # to address classes in this namespace simply write the following before using
24
+ # the classes.
25
+ #
26
+ # @example Including the namespace
27
+ # include GodObject
28
+ # @see https://www.godobject.net/
29
+ module GodObject
30
+
31
+ # Namespace for components of the "smuxi_hooks" library
32
+ module SmuxiHooks
33
+
34
+ end
35
+
36
+ end
37
+
38
+ require 'god_object/smuxi_hooks/version'
39
+ require 'god_object/smuxi_hooks/plugin'
@@ -0,0 +1,359 @@
1
+ # encoding: UTF-8
2
+ =begin
3
+ Copyright GodObject Team <dev@godobject.net>, 2015
4
+
5
+ This file is part of Smuxi hooks API for Ruby.
6
+
7
+ Permission to use, copy, modify, and/or distribute this software for any
8
+ purpose with or without fee is hereby granted, provided that the above
9
+ copyright notice and this permission notice appear in all copies.
10
+
11
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
12
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
13
+ FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
14
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
16
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17
+ PERFORMANCE OF THIS SOFTWARE.
18
+ =end
19
+
20
+ require 'pathname'
21
+ require 'set'
22
+ require 'yaml'
23
+
24
+ module GodObject
25
+ module SmuxiHooks
26
+
27
+ # Base class that implements basic features of a Smuxi plugin.
28
+ #
29
+ # @note This class is supposed to be an abstract base class and is not
30
+ # meant to produce instances directly.
31
+ class Plugin
32
+
33
+ # @return [String] name of the base configuration directory
34
+ BASE_DIRECTORY_NAME = 'smuxi'
35
+
36
+ # @return [String] name of the sub-directory containing the hook handlers
37
+ HOOKS_DIRECTORY_NAME = 'hooks'
38
+
39
+ # @return [String] name of the sub-directory containing plugin state
40
+ STATE_DIRECTORY_NAME = 'hook-state'
41
+
42
+ # @return [String] name of the file in which the permanent state is held
43
+ STATE_FILE_NAME = 'state.yml'
44
+
45
+ # @return [{String => Symbol}] maps Smuxi hook names to named of the
46
+ # method supposed to handle that hook
47
+ HOOK_TABLE = {
48
+ 'engine/protocol-manager/on-connected' => :connected,
49
+ 'engine/protocol-manager/on-disconnected' => :disconnected,
50
+ 'engine/protocol-manager/on-message-received' => :message_received,
51
+ 'engine/protocol-manager/on-message-sent' => :message_sent,
52
+ 'engine/protocol-manager/on-presence-status-changed' => :presence_status_changed,
53
+ 'engine/session/on-group-chat-person-added' => :chat_person_added,
54
+ 'engine/session/on-group-chat-person-removed' => :chat_person_removed,
55
+ 'engine/session/on-group-chat-person-updated' => :chat_person_updated,
56
+ 'engine/session/on-event-message' => :event_message
57
+ }
58
+
59
+ # @return [{String => Symbol}] maps Smuxi environment variable names to
60
+ # instance variables which will inhert the value supplied by Smuxi
61
+ VARIABLE_TABLE = {
62
+ 'SMUXI_CHAT_ID' => :@chat_id,
63
+ 'SMUXI_CHAT_NAME' => :@chat_name,
64
+ 'SMUXI_CHAT_TYPE' => :@chat_type,
65
+ 'SMUXI_MSG' => :@message,
66
+ 'SMUXI_MSG_TYPE' => :@message_type,
67
+ 'SMUXI_MSG_TIMESTAMP_UNIX' => :@message_timestamp_unix,
68
+ 'SMUXI_MSG_TIMESTAMP_ISO_UTC' => :@message_timestamp_iso_utc,
69
+ 'SMUXI_MSG_TIMESTAMP_ISO_LOCAL' => :@message_timestamp_iso_local,
70
+ 'SMUXI_SENDER' => :@sender,
71
+ 'SMUXI_RECEIVER' => :@receiver,
72
+ 'SMUXI_PROTOCOL_MANAGER_TYPE' => :@protocol_manager_type,
73
+ 'SMUXI_PROTOCOL_MANAGER_PROTOCOL' => :@protocol_manager_protocol,
74
+ 'SMUXI_PROTOCOL_MANAGER_NETWORK' => :@protocol_manager_network,
75
+ 'SMUXI_PROTOCOL_MANAGER_HOST' => :@protocol_manager_host,
76
+ 'SMUXI_PROTOCOL_MANAGER_PORT' => :@protocol_manager_port,
77
+ 'SMUXI_PROTOCOL_MANAGER_ME_ID' => :@protocol_manager_me_id,
78
+ 'SMUXI_PROTOCOL_MANAGER_PRESENCE_STATUS' => :@protocol_manager_presence_status,
79
+ 'SMUXI_PRESENCE_STATUS_CHANGED_OLD_STATUS' => :@presence_status_old,
80
+ 'SMUXI_PRESENCE_STATUS_CHANGED_NEW_STATUS' => :@presence_status_new,
81
+ 'SMUXI_PRESENCE_STATUS_CHANGED_NEW_MESSAGE' => :@presence_status_new_message,
82
+ 'SMUXI_CMD' => :@command,
83
+ 'SMUXI_CMD_PARAMETER' => :@command_parameter,
84
+ 'SMUXI_CMD_CHARACTER' => :@command_character,
85
+ 'SMUXI_FRONTEND_VERSION' => :@frontend_version,
86
+ 'SMUXI_ENGINE_VERSION' => :@engine_version
87
+ }
88
+
89
+ class << self
90
+
91
+ # Decides whether to execute a plugin hook handler or plugin maintenance
92
+ # features.
93
+ #
94
+ # In case the first command line argument is `install` or `uninstall`,
95
+ # the plugin installation or uninstallation maintenance methods are
96
+ # executed.
97
+ #
98
+ # Otherwise, the plugin expects to be called as a hook handler by Smuxi.
99
+ #
100
+ # @param [String] executable_path path of the plugin executable file
101
+ # @param [{String => String}] environment the environment variables
102
+ # available to the plugin, defaults to the actual system environment
103
+ # @param [Array<String>] arguments list of command line arguments given
104
+ # to the plugin, defaults to the actual command line arguments
105
+ # @return [void]
106
+ def execute(executable_path, environment = ENV, arguments = ARGV)
107
+ case arguments.first
108
+ when 'install'
109
+ cli_install(executable_path)
110
+ when 'uninstall'
111
+ cli_uninstall(executable_path)
112
+ else
113
+ execute_hook(executable_path, environment)
114
+ end
115
+ end
116
+
117
+ # The name of the hook executed is detected through the name of the
118
+ # executable called. A plugin instance will be created and the hook
119
+ # name is then used to decide which instance method is called on that.
120
+ #
121
+ # @param [String] executable_path path of the plugin executable file
122
+ # @param [{String => String}] environment the environment variables
123
+ # available to the plugin, defaults to the actual system environment
124
+ # @return [void]
125
+ def execute_hook(executable_path, environment = ENV)
126
+ split_pattern = /\/#{BASE_DIRECTORY_NAME}\/#{HOOKS_DIRECTORY_NAME}\//
127
+ config_directory, relative_executable = executable_path.
128
+ split(split_pattern)
129
+
130
+ base_directory = Pathname.new(config_directory) +
131
+ BASE_DIRECTORY_NAME
132
+ relative_executable = Pathname.new(relative_executable)
133
+ script_name = relative_executable.basename.to_s
134
+ hook_name = relative_executable.dirname.to_s
135
+ state_directory = base_directory +
136
+ STATE_DIRECTORY_NAME +
137
+ hook_name +
138
+ script_name
139
+
140
+ state_file = state_directory + STATE_FILE_NAME
141
+
142
+ if state_file.exist?
143
+ state = YAML.load(state_file.read)
144
+ else
145
+ state = {}
146
+ end
147
+
148
+ instance = new(
149
+ environment: environment,
150
+ base_directory: base_directory,
151
+ script_name: script_name,
152
+ hook_name: hook_name,
153
+ state_directory: state_directory,
154
+ state: state
155
+ )
156
+
157
+ if method_name = HOOK_TABLE[hook_name]
158
+ instance.public_send(method_name)
159
+
160
+ state_file.open('w') do |io|
161
+ io.write(YAML.dump(instance.state))
162
+ end
163
+ else
164
+ raise "Hook `#{hook_name}` unsupported"
165
+ end
166
+ end
167
+
168
+ # Installs the plugin by placing symlinks to the plugin executable into
169
+ # Smuxi's hook handler paths.
170
+ #
171
+ # @note This method outputs to STDOUT and exits the program after it
172
+ # finishes.
173
+ #
174
+ # @param [String] executable_path path of the plugin executable file
175
+ # @return [void]
176
+ def cli_install(executable_path)
177
+ puts "Creating symlinks at the Smuxi plugin hook locations…"
178
+ puts
179
+
180
+ install(executable_path) do |hook_executable_file|
181
+ puts "Creating `#{hook_executable_file}`"
182
+ end
183
+
184
+ puts
185
+ puts "Plugin `#{name}` installed."
186
+
187
+ exit
188
+ end
189
+
190
+ # Uninstalls the plugin by removing symlinks to the plugin executable
191
+ # from Smuxi's hook handler paths.
192
+ #
193
+ # @note This method outputs to STDOUT and exits the program after it
194
+ # finishes.
195
+ #
196
+ # @param [String] executable_path path of the plugin executable file
197
+ # @return [void]
198
+ def cli_uninstall(executable_path)
199
+ puts "Trying to remove hook symlinks…"
200
+ puts
201
+
202
+ uninstall(executable_path) do |hook_executable_file|
203
+ puts "Removing `#{hook_executable_file}`"
204
+ end
205
+
206
+ puts
207
+ puts "Plugin `#{name}` uninstalled."
208
+
209
+ exit
210
+ end
211
+
212
+ # @return [Pathname] path to the base directory
213
+ def base_directory_guess
214
+ Pathname.new('~/.local/share').expand_path + BASE_DIRECTORY_NAME
215
+ end
216
+
217
+ # @return [Array<Symbol>] a list of the names of all hook handler
218
+ # instance methods implemented by this class
219
+ def used_hook_methods
220
+ instance_methods.to_set.intersection(HOOK_TABLE.values.to_set)
221
+ end
222
+
223
+ # @return [Array<String>] a list of the names of all hooks supported by
224
+ # this class
225
+ def used_hook_names
226
+ inverted_hook_table = HOOK_TABLE.invert
227
+
228
+ used_hook_methods.map do |method_name|
229
+ inverted_hook_table[method_name]
230
+ end
231
+ end
232
+
233
+ # @return [Array<String>] a list of the Smuxi hook paths this plugin
234
+ # needs to be linked in
235
+ # @param [Pathname] base_directory the Smuxi configuration directory.
236
+ # The hooks directory is expected to reside here
237
+ def used_hook_paths(base_directory = base_directory_guess)
238
+ hooks_directory = base_directory + HOOKS_DIRECTORY_NAME
239
+
240
+ used_hook_names.map do |hook_name|
241
+ hooks_directory + hook_name
242
+ end
243
+ end
244
+
245
+ # Installs the plugin by placing symlinks to the plugin executable into
246
+ # Smuxi's hook handler paths.
247
+ #
248
+ # @param [String] executable_path path of the plugin executable file
249
+ # @param [Pathname] base_directory the configuration directory for
250
+ # Smuxi. The hooks sub-directory is expected to reside here
251
+ # @return [void]
252
+ def install(executable_path, base_directory = base_directory_guess, &block)
253
+ executable_file = Pathname.new(executable_path).expand_path
254
+ executable_name = executable_file.basename.to_s
255
+
256
+ used_hook_paths(base_directory).each do |hook_path|
257
+ hook_path.mkpath
258
+ hook_executable_file = hook_path + executable_name
259
+ block.call(hook_executable_file) if block
260
+ hook_executable_file.unlink if hook_executable_file.symlink?
261
+ hook_executable_file.make_symlink(executable_file)
262
+ end
263
+ end
264
+
265
+ # Uninstalls the plugin by removing symlinks to the plugin executable
266
+ # from Smuxi's hook handler paths.
267
+ #
268
+ # @param [String] executable_path path of the plugin executable file
269
+ # @param [Pathname] base_directory the configuration directory for
270
+ # Smuxi. The hooks sub-directory is expected to reside here
271
+ # @yield [hook_executable
272
+ # @return [void]
273
+ def uninstall(executable_path, base_directory = base_directory_guess, &block)
274
+ executable_file = Pathname.new(executable_path).expand_path
275
+ executable_name = executable_file.basename.to_s
276
+
277
+ used_hook_paths(base_directory).each do |hook_path|
278
+ hook_executable_file = hook_path + executable_name
279
+ block.call(hook_executable_file) if block
280
+ hook_executable_file.unlink if hook_executable_file.symlink?
281
+ end
282
+ end
283
+
284
+ end
285
+
286
+ attr_reader :state
287
+
288
+ # Initializes the plugin.
289
+ #
290
+ # Known variables' values from the supplied environment will be transferred
291
+ # to the respective instance variables.
292
+ #
293
+ # @see VARIABLE_TABLE
294
+ #
295
+ # @param [Hash] options
296
+ # @option options [{String => String}] environment environment variables for the plugin execution
297
+ # @option options [Pathname] base_directory the configuration directory for
298
+ # Smuxi. The hooks and hook-state sub-directories are expected to reside
299
+ # here
300
+ # @option options [Pathname] state_directory the directory that Smuxi
301
+ # reserved for this plugin to store its state.
302
+ # @option options [String] hook_name name of the Smuxi hook that is executed
303
+ # @option options [String] script_name name of plugin hook executable, without path
304
+ def initialize(options = {})
305
+ @environment = options[:environment]
306
+ @base_directory = options[:base_directory]
307
+ @state_directory = options[:state_directory]
308
+ @state = options[:state]
309
+ @hook_name = options[:hook_name]
310
+ @script_name = options[:script_name]
311
+
312
+ VARIABLE_TABLE.each do |environment_variable, instance_variable|
313
+ instance_variable_set(instance_variable,
314
+ @environment[environment_variable])
315
+ end
316
+ end
317
+
318
+ # Calls a command in Smuxi
319
+ #
320
+ # @param [String] type the command type
321
+ # @param [Symbol, String] name the command name
322
+ # @param [String] data the argument data added to the command
323
+ # @return [void]
324
+ def command(type, name, data = nil)
325
+ command = "#{type} /#{name}"
326
+ command += " #{data}" if data
327
+
328
+ STDOUT.puts(command)
329
+ end
330
+
331
+ # Calls a session command in Smuxi
332
+ #
333
+ # @param [Symbol, String] name the command name
334
+ # @param [String] data the argument data added to the command
335
+ # @return [void]
336
+ def session_command(name, data = nil)
337
+ command('Session.Command', name, data)
338
+ end
339
+
340
+ # Calls a protocol manager command in Smuxi
341
+ #
342
+ # @param [Symbol, String] name the command name
343
+ # @param [String] data the argument data added to the command
344
+ # @return [void]
345
+ def protocol_manager_command(name, data = nil)
346
+ command('ProtocolManager.Command', name, data)
347
+ end
348
+
349
+ # Outputs a message to the Smuxi user
350
+ #
351
+ # @param [String] message the text message sent to the Smuxi user
352
+ def puts(message)
353
+ session_command(:echo, message)
354
+ end
355
+
356
+ end
357
+
358
+ end
359
+ end
@@ -0,0 +1,30 @@
1
+ # encoding: UTF-8
2
+ =begin
3
+ Copyright GodObject Team <dev@godobject.net>, 2015
4
+
5
+ This file is part of Smuxi hooks API for Ruby.
6
+
7
+ Permission to use, copy, modify, and/or distribute this software for any
8
+ purpose with or without fee is hereby granted, provided that the above
9
+ copyright notice and this permission notice appear in all copies.
10
+
11
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
12
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
13
+ FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
14
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
16
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17
+ PERFORMANCE OF THIS SOFTWARE.
18
+ =end
19
+
20
+ module GodObject
21
+ module SmuxiHooks
22
+
23
+ # The currently loaded version.
24
+ #
25
+ # Using Semantic Versioning (2.0.0) rules
26
+ # @see http://semver.org/
27
+ VERSION = '0.1.0'.freeze
28
+
29
+ end
30
+ end
@@ -0,0 +1,20 @@
1
+ # encoding: UTF-8
2
+ =begin
3
+ Copyright GodObject Team <dev@godobject.net>, 2015
4
+
5
+ This file is part of Smuxi hooks API for Ruby.
6
+
7
+ Permission to use, copy, modify, and/or distribute this software for any
8
+ purpose with or without fee is hereby granted, provided that the above
9
+ copyright notice and this permission notice appear in all copies.
10
+
11
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
12
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
13
+ FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
14
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
16
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17
+ PERFORMANCE OF THIS SOFTWARE.
18
+ =end
19
+
20
+ require 'god_object/smuxi_hooks'
@@ -0,0 +1,54 @@
1
+ # encoding: UTF-8
2
+ =begin
3
+ Copyright GodObject Team <dev@godobject.net>, 2015
4
+
5
+ This file is part of Smuxi hooks API for Ruby.
6
+
7
+ Permission to use, copy, modify, and/or distribute this software for any
8
+ purpose with or without fee is hereby granted, provided that the above
9
+ copyright notice and this permission notice appear in all copies.
10
+
11
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
12
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
13
+ FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
14
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
16
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17
+ PERFORMANCE OF THIS SOFTWARE.
18
+ =end
19
+
20
+ require File.expand_path('../lib/god_object/smuxi_hooks/version', __FILE__)
21
+
22
+ Gem::Specification.new do |gem|
23
+ gem.name = "smuxi_hooks"
24
+ gem.version = GodObject::SmuxiHooks::VERSION.dup
25
+ gem.authors = ["Alexander E. Fischer"]
26
+ gem.email = ["aef@godobject.net"]
27
+ gem.description = <<-DESCRIPTION
28
+ Plugin framework for the multi-protocol distributed chat client Smuxi.
29
+ DESCRIPTION
30
+ gem.summary = "Plugin framework for the multi-protocol distributed chat client Smuxi."
31
+ gem.homepage = "https://www.godobject.net/"
32
+ gem.license = "ISC"
33
+ gem.has_rdoc = "yard"
34
+ gem.extra_rdoc_files = ["HISTORY.md", "LICENSE.md"]
35
+ gem.rubyforge_project = nil
36
+
37
+ `git ls-files 2> /dev/null`
38
+
39
+ if $?.success?
40
+ gem.files = `git ls-files`.split($\)
41
+ else
42
+ gem.files = `ls -1`.split($\)
43
+ end
44
+
45
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
46
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
47
+ gem.require_paths = ["lib"]
48
+
49
+ gem.required_ruby_version = '>= 1.9.3'
50
+
51
+ gem.add_development_dependency('pry')
52
+ gem.add_development_dependency('yard')
53
+ gem.add_development_dependency('redcarpet')
54
+ end
metadata ADDED
@@ -0,0 +1,105 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: smuxi_hooks
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Alexander E. Fischer
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-01-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: pry
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: yard
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: redcarpet
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: |
56
+ Plugin framework for the multi-protocol distributed chat client Smuxi.
57
+ email:
58
+ - aef@godobject.net
59
+ executables: []
60
+ extensions: []
61
+ extra_rdoc_files:
62
+ - HISTORY.md
63
+ - LICENSE.md
64
+ files:
65
+ - ".gitignore"
66
+ - ".yardopts"
67
+ - Gemfile
68
+ - HISTORY.md
69
+ - LICENSE.md
70
+ - README.md
71
+ - Rakefile
72
+ - examples/chat_logger.rb
73
+ - examples/keyword_catcher.rb
74
+ - examples/remember.rb
75
+ - lib/god_object/smuxi_hooks.rb
76
+ - lib/god_object/smuxi_hooks/plugin.rb
77
+ - lib/god_object/smuxi_hooks/version.rb
78
+ - lib/smuxi_hooks.rb
79
+ - smuxi_hooks.gemspec
80
+ homepage: https://www.godobject.net/
81
+ licenses:
82
+ - ISC
83
+ metadata: {}
84
+ post_install_message:
85
+ rdoc_options: []
86
+ require_paths:
87
+ - lib
88
+ required_ruby_version: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: 1.9.3
93
+ required_rubygems_version: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ requirements: []
99
+ rubyforge_project:
100
+ rubygems_version: 2.4.3
101
+ signing_key:
102
+ specification_version: 4
103
+ summary: Plugin framework for the multi-protocol distributed chat client Smuxi.
104
+ test_files: []
105
+ has_rdoc: yard