smartdict-core 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. data/README.markdown +77 -0
  2. data/bin/smartdict +20 -0
  3. data/bin/smartdict-populator +50 -0
  4. data/config/default_config.yml +15 -0
  5. data/lib/smartdict/commands/abstract_command.rb +225 -0
  6. data/lib/smartdict/commands/has_format_list.rb +28 -0
  7. data/lib/smartdict/commands/help_command.rb +53 -0
  8. data/lib/smartdict/commands/list_command.rb +45 -0
  9. data/lib/smartdict/commands/translate_command.rb +35 -0
  10. data/lib/smartdict/commands.rb +10 -0
  11. data/lib/smartdict/core/command_manager.rb +27 -0
  12. data/lib/smartdict/core/driver_manager.rb +9 -0
  13. data/lib/smartdict/core/format_manager.rb +8 -0
  14. data/lib/smartdict/core/has_logger.rb +12 -0
  15. data/lib/smartdict/core/is_manager.rb +21 -0
  16. data/lib/smartdict/core/logger.rb +5 -0
  17. data/lib/smartdict/core/plugin_manager.rb +32 -0
  18. data/lib/smartdict/core.rb +12 -0
  19. data/lib/smartdict/drivers/abstract_driver.rb +61 -0
  20. data/lib/smartdict/drivers/google_translate_driver.rb +56 -0
  21. data/lib/smartdict/drivers.rb +6 -0
  22. data/lib/smartdict/errors.rb +11 -0
  23. data/lib/smartdict/formats/abstract_format.rb +21 -0
  24. data/lib/smartdict/formats/fb2_format.rb +40 -0
  25. data/lib/smartdict/formats/text_color_format.rb +52 -0
  26. data/lib/smartdict/formats/text_format.rb +9 -0
  27. data/lib/smartdict/formats.rb +8 -0
  28. data/lib/smartdict/list_builder.rb +51 -0
  29. data/lib/smartdict/models/driver.rb +14 -0
  30. data/lib/smartdict/models/language.rb +16 -0
  31. data/lib/smartdict/models/translated_word.rb +14 -0
  32. data/lib/smartdict/models/translation.rb +83 -0
  33. data/lib/smartdict/models/translation_query.rb +13 -0
  34. data/lib/smartdict/models/word.rb +13 -0
  35. data/lib/smartdict/models/word_class.rb +14 -0
  36. data/lib/smartdict/models.rb +11 -0
  37. data/lib/smartdict/plugin/initializer_context.rb +7 -0
  38. data/lib/smartdict/plugin.rb +9 -0
  39. data/lib/smartdict/runner.rb +5 -0
  40. data/lib/smartdict/storage/seeder.rb +32 -0
  41. data/lib/smartdict/storage/seeds/drivers.csv +2 -0
  42. data/lib/smartdict/storage/seeds/languages.csv +188 -0
  43. data/lib/smartdict/storage/seeds/word_classes.csv +10 -0
  44. data/lib/smartdict/storage.rb +44 -0
  45. data/lib/smartdict/translation.rb +19 -0
  46. data/lib/smartdict/translator.rb +38 -0
  47. data/lib/smartdict/version.rb +3 -0
  48. data/lib/smartdict-core.rb +1 -0
  49. data/lib/smartdict.rb +97 -0
  50. metadata +468 -0
data/README.markdown ADDED
@@ -0,0 +1,77 @@
1
+ # Smartdict
2
+
3
+ Simple dictionary.
4
+
5
+ ## Installation
6
+
7
+ ```
8
+ gem install smartdict
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ To get help just type:
14
+
15
+ ```
16
+ smartdict --help
17
+ ```
18
+
19
+ To get a help on specific command:
20
+
21
+ ```
22
+ smartdict help <COMMAND>
23
+ ```
24
+
25
+ ### Translate words:
26
+
27
+ To translate word `hallo` from German to Russian:
28
+
29
+ smartdict translate --from de --to ru hallo
30
+
31
+
32
+ ### List translated words:
33
+
34
+ If you want to take a look at words you've translated use `list` command.
35
+ You can specify date range and languages to filter words and
36
+ you can specify format for output.
37
+
38
+ To get more information see help:
39
+
40
+ ```
41
+ smartdict translate --help
42
+ ```
43
+
44
+ #### Example:
45
+
46
+ To see words translated today:
47
+
48
+ ```
49
+ smartdict list
50
+ ```
51
+
52
+ To save words translated since 13th of January 2012 from English to Russian in
53
+ [FictionBook](http://en.wikipedia.org/wiki/FictionBook) format to `words.fb2`
54
+ file.
55
+
56
+
57
+ ```
58
+ smartdict --since 2012-01-13 --from en --to ru --format fb2 > ./words.fb2
59
+ ```
60
+
61
+ ## How to configure?
62
+
63
+ See file `$HOME/.smartdict/configuration.yml`.
64
+
65
+ NOTE: currently not all options listed there have an effect.
66
+
67
+
68
+ ## Contributing to smartdict
69
+
70
+ * Make sure all tests pass.
71
+ * Send me a patch.
72
+
73
+ ## Copyright
74
+
75
+ Copyright (c) 2012 Potapov Sergey. The software is distributed under
76
+ [GNU GeneralPublic License version 2](http://www.gnu.org/licenses/gpl-2.0.txt).
77
+ See GPL-LICENSE.txt file for more details.
data/bin/smartdict ADDED
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
4
+ require 'rubygems'
5
+
6
+ require 'smartdict'
7
+ require 'smartdict/runner'
8
+
9
+ # TODO: remove before release
10
+ # require 'pry'
11
+
12
+ Smartdict.env = :user
13
+
14
+ args = ARGV.clone
15
+
16
+ Smartdict.load_plugins
17
+
18
+ # TODO :move Smartdict.run to Runner.run
19
+ Smartdict.run
20
+ Smartdict::Runner.run(args)
@@ -0,0 +1,50 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
4
+ require 'rubygems'
5
+
6
+ require 'smartdict'
7
+ require 'smartdict/runner'
8
+
9
+ Smartdict.env = :user
10
+
11
+ args = ARGV.clone
12
+
13
+ Smartdict.load_plugins
14
+
15
+ # TODO :mode Smartdict.run to Runner.run
16
+ Smartdict.run
17
+
18
+
19
+
20
+ def translate(word)
21
+ Smartdict::Translator.translate(word)
22
+ rescue Smartdict::TranslationNotFound
23
+ end
24
+
25
+ def translate_words(words, from_lang, to_lang)
26
+ words.each_with_index do |word, index|
27
+ translate word
28
+ if index % 10 == 0
29
+ print "#{index}/#{words.size} = %2.2f%" % [index.to_f/words.size * 100]
30
+ puts " #{from_lang.name} -> #{to_lang.name}"
31
+ end
32
+ end
33
+ end
34
+
35
+ from_lang = Smartdict::Models::Language.first(:code => 'en')
36
+ to_lang = Smartdict::Models::Language.first(:code => 'ru')
37
+
38
+
39
+ while(true)
40
+ Smartdict::Translator.from_lang_code = from_lang.code
41
+ Smartdict::Translator.to_lang_code = to_lang.code
42
+
43
+ words = Smartdict::Models::Word.all(:language_id => from_lang.id).map(&:name)
44
+ translate_words(words, from_lang, to_lang)
45
+
46
+ from_lang, to_lang = to_lang, from_lang
47
+ end
48
+
49
+
50
+
@@ -0,0 +1,15 @@
1
+ plugins:
2
+
3
+ store:
4
+ adapter: sqlite
5
+
6
+ default:
7
+ from_lang: en
8
+ to_lang: ru
9
+ format: text_color
10
+ langs:
11
+ - en
12
+ - ru
13
+ - de
14
+ - es
15
+ - fr
@@ -0,0 +1,225 @@
1
+ # Basic class for all command classes.
2
+ #
3
+ # == Usage:
4
+ # class Smartdict::Commands::HelloCommand < Smartdict::Commands::AbstractCommand
5
+ # # arguments and their default values
6
+ # arguments :name
7
+ # default :name => "world"
8
+ #
9
+ # # options and their default values.
10
+ # options :greating => "Hello",
11
+ # :today => lambda { Time.now.strftime("%A") }
12
+ #
13
+ # # Other helpful information about the command
14
+ # set_name "hello"
15
+ # set_summary "Summary for the hello command"
16
+ # set_description "Demonstrates how Command class works"
17
+ # set_syntax "#{prog_name} NAME [--greating GREATING] [--today DAY]"
18
+ # set_usage <<-USAGE
19
+ # #{prog_name}
20
+ # #{prog_name} Sergey
21
+ # #{prog_name} --today Friday
22
+ # USAGE
23
+ #
24
+ # # This method runs when command executes.
25
+ # def execute
26
+ # puts "#{@options[:greating]} #{@arguments[:name]}! Today is #{@options[:today]}."
27
+ # end
28
+ # end
29
+ #
30
+ # # == Output:
31
+ # # smartdict hello
32
+ # # Hello world! Today is Monday.
33
+ # #
34
+ # # smartdict hello Sergey
35
+ # # Hello Sergey! Today is Monday.
36
+ # #
37
+ # # smartdict hello Sergey --today Friday
38
+ # # Hello Sergey! Today is Friday.
39
+ class Smartdict::Commands::AbstractCommand
40
+ # Number of spaces for indent.
41
+ INDENT_SIZE = 2
42
+
43
+ # array with available arguments
44
+ class_attribute :known_arguments
45
+
46
+ # hash with default values for {known_arguments}.
47
+ class_attribute :default_argument_values
48
+
49
+ # hash with names of options and default values
50
+ class_attribute :known_options
51
+
52
+ # short summary message for a command
53
+ class_attribute :summary
54
+
55
+ # command description
56
+ class_attribute :description
57
+
58
+ # command name
59
+ class_attribute :name
60
+
61
+ # multi line text with syntax format
62
+ class_attribute :syntax
63
+
64
+ # multi line text with usage example
65
+ class_attribute :usage
66
+
67
+ # Runs command.
68
+ # @param [Array] args arguments passed from the command line
69
+ def self.run(args)
70
+ if ['--help', '-h'].include?(args.first)
71
+ puts help_message
72
+ else
73
+ self.new(args).execute
74
+ end
75
+ rescue Smartdict::Error => err
76
+ puts err.message
77
+ end
78
+
79
+ # Defines available arguments and their order.
80
+ def self.arguments(*argument_names)
81
+ self.known_arguments = argument_names
82
+ end
83
+
84
+ # Sets default values for arguments.
85
+ # @param [Hash] values
86
+ def self.default(values)
87
+ self.default_argument_values = values
88
+ end
89
+
90
+ # Defines available options with their default values.
91
+ # == Usage:
92
+ # options :to => "en",
93
+ # :from => lambda { Settings.current_language }
94
+ def self.options(options = {})
95
+ raise Smartdict::Error.new("options must be a hash") unless options.is_a? Hash
96
+ self.known_options = options
97
+ end
98
+
99
+ # Sets summary message for a command.
100
+ def self.set_summary(summary)
101
+ self.summary = summary
102
+ end
103
+
104
+ # Sets description message for a command.
105
+ def self.set_description(description)
106
+ self.description = description
107
+ end
108
+
109
+ # Defines name of a command.
110
+ def self.set_name(name)
111
+ self.name = name
112
+ end
113
+
114
+ # Sets syntax message.
115
+ # @param [String] syntax multi line text with number of syntax examples
116
+ def self.set_syntax(syntax)
117
+ self.syntax = syntax
118
+ end
119
+
120
+ # Sets usage examples
121
+ # @param [String] usage multi line text with number of usage examples.
122
+ def self.set_usage(usage)
123
+ self.usage = usage
124
+ end
125
+
126
+ # @return [String] program name. It's meant to be used in usage examples.
127
+ def self.prog_name
128
+ "smartdict #{name}"
129
+ end
130
+
131
+ # @return [String] help message for the command to be displayed.
132
+ def self.help_message
133
+ message = "#{description}\n\n"
134
+ message << "#{help_syntax_message}\n"
135
+ message << "#{help_usage_message}\n"
136
+ end
137
+
138
+ # @return [String] syntax part of the help message.
139
+ def self.help_syntax_message
140
+ result = " " * INDENT_SIZE + "Syntax:\n"
141
+ syntax.split("\n").map do |line|
142
+ result << " " * INDENT_SIZE * 2 + "#{line.strip}\n"
143
+ end
144
+ result
145
+ end
146
+
147
+ # @return [String] usage part of the help message.
148
+ def self.help_usage_message
149
+ result = " " * INDENT_SIZE + "Usage:\n"
150
+ usage.split("\n").map do |line|
151
+ result << " " * INDENT_SIZE * 2 + "#{line.strip}\n"
152
+ end
153
+ result
154
+ end
155
+
156
+ # Sets default values for class attributes.
157
+ def self.inherited(base)
158
+ base.known_arguments ||= []
159
+ base.default_argument_values ||= {}
160
+ base.known_options ||= {}
161
+ end
162
+
163
+
164
+
165
+ # @param [Array] args arguments passed from the command line
166
+ def initialize(args = [])
167
+ set_arguments_and_options!(args)
168
+ end
169
+
170
+ # Parses all passed arguments and initializes @arguments and @options variables.
171
+ # @param [Array] args arguments passed from the command line
172
+ def set_arguments_and_options!(args)
173
+ arguments, options = extract_arguments_and_options(args)
174
+ set_arguments!(arguments)
175
+ set_options!(options)
176
+ end
177
+
178
+ # Splits input args to arguments and options.
179
+ # Returns arguments as an array and options as a hash.
180
+ def extract_arguments_and_options(args)
181
+ arguments = []
182
+ options = {}
183
+ args = args.dup
184
+ while value = args.shift
185
+ if match = value.match(/^--(\w+)/)
186
+ options[match[1].to_sym] = args.shift
187
+ else
188
+ arguments << value
189
+ end
190
+ end
191
+ [arguments, options]
192
+ end
193
+
194
+ # Initializes @arguments variable.
195
+ # If no argument was passed then it uses default value.
196
+ def set_arguments!(arg_values)
197
+ @arguments = {}
198
+ known_arguments.each_with_index do |arg_name, index|
199
+ if value = arg_values[index]
200
+ @arguments[arg_name.to_sym] = value
201
+ elsif default_argument_values.has_key?(arg_name.to_sym)
202
+ @arguments[arg_name.to_sym] = default_argument_values[arg_name.to_sym]
203
+ else
204
+ raise Smartdict::Error.new("Argument `#{arg_name}` is not passed")
205
+ end
206
+ end
207
+ end
208
+
209
+ # Initializes @options variable.
210
+ # If no argument was passed then it uses default value.
211
+ def set_options!(options)
212
+ @options = {}
213
+ known_options.each do |opt_name, default_value|
214
+ value = options[opt_name]
215
+ unless value
216
+ value = case default_value
217
+ when Proc then default_value.call
218
+ else default_value
219
+ end
220
+ end
221
+ @options[opt_name] = value
222
+ end
223
+ end
224
+
225
+ end
@@ -0,0 +1,28 @@
1
+ # Extends {help_message} method to provide list of formats.
2
+ module Smartdict::Commands::HasFormatList
3
+ def self.included(base)
4
+ base.extend ClassMethods
5
+ base.class_eval do
6
+ class << self
7
+ alias_method_chain :help_message, :formats
8
+ end
9
+ end
10
+ end
11
+
12
+ module ClassMethods
13
+ def help_message_with_formats
14
+ formats = Smartdict::Core::FormatManager.all
15
+ width = formats.values.map{|f| f.name.size}.max
16
+ indent = Smartdict::Commands::AbstractCommand::INDENT_SIZE
17
+
18
+ message = " " * indent + "Formats:\n"
19
+ formats.each do |name, format|
20
+ message << " " * 2 * indent
21
+ message << name.ljust(width) + " "
22
+ message << "#{format.description}\n"
23
+ end
24
+
25
+ help_message_without_formats << message
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,53 @@
1
+ module Smartdict::Commands
2
+ class HelpCommand < AbstractCommand
3
+ include Smartdict::Core
4
+
5
+ arguments :command
6
+ default :command => nil
7
+
8
+ set_name "help"
9
+ set_summary "Show help message"
10
+ set_description "Smartdict is a dictionary designed to improve you knowledge of foreign languages."
11
+ set_syntax <<-SYNTAX
12
+ smartdict COMMAND [arguments...] [options...]
13
+ #{prog_name} COMMAND
14
+ smartdict --help
15
+ smartdict --version
16
+ SYNTAX
17
+
18
+ set_usage <<-SYNTAX
19
+ #{prog_name} translate
20
+ #{prog_name} list
21
+ SYNTAX
22
+
23
+ def execute
24
+ if cmd_name = @arguments[:command]
25
+ if cmd_class = CommandManager.find(cmd_name)
26
+ puts cmd_class.help_message
27
+ else
28
+ abort "Uknown command: #{cmd_name}"
29
+ end
30
+ else
31
+ puts help_message
32
+ end
33
+ end
34
+
35
+ def help_message
36
+ message = "#{description}\n\n"
37
+ message << "#{self.class.help_syntax_message}\n"
38
+ message << help_commands_message
39
+ end
40
+
41
+
42
+ def help_commands_message
43
+ width = CommandManager.all.keys.map(&:size).max
44
+ result = " " * INDENT_SIZE + "Commands:\n"
45
+ CommandManager.all.each do |command_name, command_class|
46
+ result << " " * 2 * INDENT_SIZE + "#{command_name.ljust(width)}"
47
+ result << " #{command_class.summary}\n"
48
+ end
49
+ result
50
+ end
51
+
52
+ end
53
+ end
@@ -0,0 +1,45 @@
1
+ module Smartdict::Commands
2
+ class ListCommand < AbstractCommand
3
+ include HasFormatList
4
+ include Smartdict::Models
5
+
6
+ set_name "list"
7
+ set_summary "Lists words you translated before"
8
+ set_description "Lists words you translated before in selected format(text_color by default)."
9
+ set_syntax <<-SYNTAX
10
+ #{prog_name} [--since DATE] [--till DATE] [--format FORMAT] [--from LANG] [--to LANG]
11
+ SYNTAX
12
+
13
+ set_usage <<-SYNTAX
14
+ #{prog_name}
15
+ #{prog_name} --since 2012-02-14 --till 2012-02-21
16
+ #{prog_name} --from de --to en --format text
17
+ SYNTAX
18
+
19
+ options :format => lambda { configatron.default.format },
20
+ :since => lambda { Date.today },
21
+ :till => lambda { Time.now },
22
+ :from => nil,
23
+ :to => nil,
24
+ :driver => nil
25
+
26
+ def execute
27
+ list_opts = {
28
+ :since => @options[:since],
29
+ :till => @options[:till],
30
+ :from_lang => @options[:from],
31
+ :to_lang => @options[:to],
32
+ :driver => @options[:driver]
33
+ }
34
+ translations = Smartdict::ListBuilder.build(list_opts)
35
+ puts format.format_list(translations)
36
+ end
37
+
38
+ def format
39
+ format = Smartdict::FormatManager.find(@options[:format])
40
+ raise Smartdict::Error.new("Wrong format: #{@options[:format]}") unless format
41
+ format
42
+ end
43
+
44
+ end
45
+ end
@@ -0,0 +1,35 @@
1
+ module Smartdict::Commands
2
+ class TranslateCommand < AbstractCommand
3
+ include HasFormatList
4
+
5
+ set_name "translate"
6
+ set_summary "Translate a word"
7
+ set_description "Translate a word"
8
+ set_syntax "#{prog_name} <WORD> [--from LANGUAGE] [--to LANGUAGE] [--format FORMAT]"
9
+ set_usage <<-USAGE
10
+ #{prog_name} hello
11
+ #{prog_name} again --from en --to ru
12
+ #{prog_name} again --format text
13
+ USAGE
14
+
15
+ arguments :word
16
+
17
+ options :from => lambda { configatron.default.from_lang },
18
+ :to => lambda { configatron.default.to_lang },
19
+ :format => lambda { configatron.default.format }
20
+
21
+ def execute
22
+ Smartdict::Translator.from_lang_code = @options[:from]
23
+ Smartdict::Translator.to_lang_code = @options[:to]
24
+ translation = Smartdict::Translator.translate(@arguments[:word])
25
+ puts format.format_translation(translation)
26
+ end
27
+
28
+ def format
29
+ format = Smartdict::FormatManager.find(@options[:format])
30
+ raise Smartdict::Error.new("Wrong format: #{@options[:format]}") unless format
31
+ format
32
+ end
33
+
34
+ end
35
+ end
@@ -0,0 +1,10 @@
1
+ module Smartdict::Commands
2
+ extend ActiveSupport::Autoload
3
+
4
+ autoload :AbstractCommand
5
+ autoload :HelpCommand
6
+ autoload :TranslateCommand
7
+ autoload :ListCommand
8
+
9
+ autoload :HasFormatList
10
+ end
@@ -0,0 +1,27 @@
1
+ class Smartdict::Core::CommandManager
2
+ include Smartdict::Core::IsManager
3
+ include Smartdict::Commands
4
+
5
+ register 'help' , HelpCommand
6
+ register 'translate', TranslateCommand
7
+ register 'list' , ListCommand
8
+
9
+
10
+ def self.run(args)
11
+ first_arg = args.shift
12
+ case first_arg
13
+ when nil, '-h', '--help', 'help'
14
+ run_command :help, args
15
+ else
16
+ run_command(first_arg, args)
17
+ end
18
+ end
19
+
20
+ def self.run_command(name, args = [])
21
+ if command = find(name)
22
+ command.run(args)
23
+ else
24
+ abort "Unknown command: #{name}"
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,9 @@
1
+ # Managers {Smartdict::Driver translation drivers}.
2
+ # Similar to {Smartdict::Core::CommandManager} it registers drivers
3
+ # and provides interfaces to find them by name.
4
+ class Smartdict::Core::DriverManager
5
+ include Smartdict::Core::IsManager
6
+ include Smartdict::Drivers
7
+
8
+ register 'google_translate', GoogleTranslateDriver
9
+ end
@@ -0,0 +1,8 @@
1
+ class Smartdict::Core::FormatManager
2
+ include Smartdict::Formats
3
+ include Smartdict::Core::IsManager
4
+
5
+ register "text" , TextFormat
6
+ register "text_color", TextColorFormat
7
+ register "fb2" , Fb2Format
8
+ end
@@ -0,0 +1,12 @@
1
+ module Smartdict::Core::HasLogger
2
+ def self.included(base)
3
+ base.extend Methods
4
+ base.send :include, Methods
5
+ end
6
+
7
+ module Methods
8
+ def logger
9
+ Smartdict::Core::Logger.root_logger
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,21 @@
1
+ module Smartdict::Core::IsManager
2
+ def self.included(receiver)
3
+ receiver.instance_variable_set("@entities", {})
4
+ receiver.extend ClassMethods
5
+ end
6
+
7
+ module ClassMethods
8
+ def register(name, klass)
9
+ raise Smartdict::Error.new("`#{name}` is already registered") if find(name)
10
+ @entities[name.to_s] = klass
11
+ end
12
+
13
+ def find(name)
14
+ @entities[name.to_s]
15
+ end
16
+
17
+ def all
18
+ @entities
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,5 @@
1
+ class Smartdict::Core::Logger < ::Logger
2
+ def self.root_logger
3
+ @logger ||= self.new(Smartdict.log_path)
4
+ end
5
+ end
@@ -0,0 +1,32 @@
1
+ class Smartdict::Core::PluginManager
2
+ include Smartdict::Core::IsManager
3
+
4
+ def self.load_plugins
5
+ require_plugins
6
+ run_initializers
7
+ end
8
+
9
+
10
+ private
11
+
12
+ def self.require_plugins
13
+ Dir["#{Smartdict.plugins_dir}/*"].each do |plugin_dir|
14
+ plugin_name = File.basename plugin_dir
15
+ require_plugin(plugin_name)
16
+ end
17
+ end
18
+
19
+ def self.require_plugin(plugin_name)
20
+ $LOAD_PATH << "#{Smartdict.plugins_dir}/#{plugin_name}/lib"
21
+ require plugin_name
22
+ rescue LoadError
23
+ log.error "Can't load plugin `#{plugin_name}` from directory #{Smartdict.plugins_dir}"
24
+ $LOAD_PATH.pop
25
+ end
26
+
27
+ def self.run_initializers
28
+ all.each do |name, data|
29
+ Smartdict::Plugin::InitializerContext.new.instance_eval &data[:block]
30
+ end
31
+ end
32
+ end