smuxi_hooks 0.1.0

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.
@@ -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