yandex_speech_api 1.1.2

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,38 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+ module YandexSpeechApi
4
+ class Format
5
+
6
+ ##
7
+ # List of allowed formats
8
+ #
9
+ # @return [Array<String>]
10
+
11
+ def self.list
12
+ %i(mp3 wav opus)
13
+ end
14
+
15
+ # @return [Symbol]
16
+ # possible values: :mp3, :wav or :opus
17
+
18
+ attr_reader :type
19
+
20
+ def initialize(format)
21
+ @type = format.downcase.to_sym
22
+
23
+ raise FormatNotAllowed, format unless format_known? @type
24
+ end
25
+
26
+ private
27
+
28
+ def format_known?(format)
29
+ Format.list.include? format
30
+ end
31
+
32
+ ##
33
+ # Raised when unknown format has been selected.
34
+
35
+ class FormatNotAllowed < YandexSpeechError
36
+ def initialize(format); super "Format '#{format}' not allowed for usage. To see list of allowed formats use Format#list" end; end
37
+ end # class Format
38
+ end # module YandexSpeechApi
@@ -0,0 +1,52 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+ module YandexSpeechApi
4
+ module Helpers
5
+
6
+ ##
7
+ # From what OS we launched?
8
+ #
9
+ # @example #1
10
+ # recognize_operation_system # ==> :linux
11
+ #
12
+ # @example #2
13
+ # recognize_operation_system # ==> :unknown
14
+ #
15
+ # @return [Symbol]
16
+ # OS name
17
+
18
+ def self.recognize_operation_system
19
+ case RbConfig::CONFIG['host_os']
20
+ when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
21
+ :windows
22
+ when /darwin|mac os/
23
+ :mac_os
24
+ when /linux/
25
+ :linux
26
+ else
27
+ :unknown
28
+ end
29
+ end
30
+
31
+ ##
32
+ # Searches pathname for executable +cmd+.
33
+ #
34
+ # @return [Pathname, NilClass]
35
+ # Returns +Pathname+ if +cmd+ is present and executable.
36
+ # If search unsuccessful it returns +nil+.
37
+
38
+ def self.find_executable(cmd)
39
+ possible_extensions = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
40
+
41
+ ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
42
+ possible_extensions.each do |extension|
43
+ exe = Pathname.new(File.join(path, "#{cmd}#{extension}"))
44
+
45
+ return exe if exe.executable? && exe.file?
46
+ end
47
+ end
48
+
49
+ return nil # search unsuccessful
50
+ end
51
+ end # module Helpers
52
+ end # module YandexSpeechApi
@@ -0,0 +1,106 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+ module YandexSpeechApi
4
+ class Key
5
+ class << self
6
+
7
+ ##
8
+ # Sets global key.
9
+ #
10
+ # @param [Key, Symbol] new_key
11
+ #
12
+ # @exception InvalidGlobalKey
13
+ # raised when +new_key+ param have unexpected class.
14
+
15
+ def global_key=(new_key)
16
+ key_tmp = new_key.is_a?(Key) ? new_key : Key.new(new_key)
17
+ raise InvalidGlobalKey, key_tmp unless key_tmp.present?
18
+ @global_key = key_tmp
19
+ end
20
+
21
+ ##
22
+ # @return [TrueClass, FalseClass]
23
+ # True if global key set, otherwise returns false.
24
+
25
+ def global_key?
26
+ !!global_key
27
+ end
28
+
29
+ private
30
+
31
+ ##
32
+ # @return [Key, nil]
33
+
34
+ def global_key
35
+ @global_key
36
+ end
37
+ end # class << self
38
+
39
+ def initialize(key)
40
+ @instance_key = key
41
+ end
42
+
43
+ ##
44
+ # Returns an key.
45
+ #
46
+ # @exception KeyNotDefined
47
+ # raised if both +instance key+ and +global key_ are not present
48
+ #
49
+ # @return [Key]
50
+
51
+ def get
52
+ if present?
53
+ return instance_key
54
+ elsif default?
55
+ return default.get
56
+ else
57
+ raise KeyNotDefined
58
+ end
59
+ end
60
+
61
+ ##
62
+ # Key present?
63
+ #
64
+ # @return [TrueClass, FalseClass]
65
+ # returns +false+ if key is +:unknown+, otherwise - +true+.
66
+
67
+ def present?
68
+ !(instance_key == :unknown)
69
+ end
70
+
71
+ private
72
+
73
+ # @return [Symbol, String]
74
+ # possible values: :unknown or some string
75
+
76
+ attr_reader :instance_key
77
+
78
+ ##
79
+ # @return [TrueClass, FalseClass]
80
+ # @see Key#global_key?
81
+
82
+ def default?
83
+ Key.global_key?
84
+ end
85
+
86
+ ##
87
+ # @return [Key, nil]
88
+ # see Key#global_key
89
+
90
+ def default
91
+ Key.instance_variable_get :@global_key
92
+ end
93
+
94
+ ##
95
+ # Raised when user tries to call #say method without key.
96
+
97
+ class KeyNotDefined < YandexSpeechError
98
+ def initialize; super "WARNING! You initialized Speaker class without key! It means you can not use YandexSpeechApi service. You can get your key there: https://tech.yandex.ru/speechkit" end; end
99
+
100
+ ##
101
+ # Raised when global key going to be set with default values.
102
+
103
+ class InvalidGlobalKey < YandexSpeechError
104
+ def initialize(key); super "Global key '#{key}' can not been nil or :unknown" end; end
105
+ end # class Key
106
+ end # module YandexSpeechApi
@@ -0,0 +1,59 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+ module YandexSpeechApi
4
+ class Language # no-doc
5
+
6
+ ##
7
+ # List of allowed languages
8
+ #
9
+ # @return [Array<Classes>]
10
+
11
+ def self.allowed_languages
12
+ @cached_list ||= Array(codes.keys)
13
+ end
14
+
15
+ def self.codes # no-doc
16
+ {
17
+ english: 'en-US',
18
+ russian: 'ru‑RU',
19
+ turkey: 'tr-TR',
20
+ ukrain: 'uk-UK',
21
+ }
22
+ end
23
+
24
+ # @return [Symbol]
25
+
26
+ attr_reader :language
27
+
28
+ # @return [String]
29
+
30
+ def code
31
+ @code ||= Language.codes[@language]
32
+ end
33
+
34
+ ##
35
+ # Creates new object instance.
36
+ #
37
+ # @param [String] language
38
+ # Selected language.
39
+ #
40
+ # @exception UnknownLanguageError
41
+ # Raised when language is unknown
42
+ #
43
+ # @return [Language]
44
+
45
+ def initialize(language)
46
+ @language = language.downcase.to_sym
47
+
48
+ unless Language.allowed_languages.include? @language
49
+ raise UnknownLanguageError, @language
50
+ end
51
+ end
52
+
53
+ ##
54
+ # Raised when unknown language has been selected.
55
+
56
+ class UnknownLanguageError < YandexSpeechError
57
+ def initialize(lang); super "Unknown language selected: '#{lang}'. See Language#allowed_languages for list of allowed languages" end; end
58
+ end # class Language
59
+ end # module YandexSpeechApi
@@ -0,0 +1,33 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+ module YandexSpeechApi
4
+ module MP3_Player
5
+
6
+ ##
7
+ # Creates MP3 player instance. Depends from OS.
8
+ #
9
+ # @exception UnknownOsError
10
+ # raised when OS unknown.
11
+ #
12
+ # @return [Linux_MP3_Player, Mac_MP3_Player]
13
+
14
+ def self.init
15
+ @player ||=
16
+ case Helpers::recognize_operation_system
17
+ when :linux
18
+ Linux_MP3_Player.new
19
+ when :mac_os
20
+ Mac_MP3_Player.new
21
+ else
22
+ raise UnknownOs
23
+ end
24
+ end
25
+
26
+ ##
27
+ # Raised when MP3_Player#init can not recognize what operation system is
28
+ # used.
29
+
30
+ class UnknownOs < YandexSpeechError
31
+ def initialize; super "#{self.class}#recognize_operation_system cannot recognize your operation system!"; end; end
32
+ end # module Player
33
+ end # module YandexSpeechApi
@@ -0,0 +1,72 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+ module YandexSpeechApi
4
+ module MP3_Player
5
+ class Base # no-doc
6
+
7
+ ##
8
+ # Plays sound
9
+
10
+ def play(filename)
11
+ @filename = Pathname.new filename
12
+ validate_file_presence
13
+ validate_mp3_format
14
+ validate_requirements
15
+ play_mp3
16
+ end
17
+
18
+ private
19
+
20
+ attr_reader :filename # no-doc
21
+
22
+ ##
23
+ # no-doc
24
+
25
+ def validate_file_presence
26
+ raise FileNotFound, filename unless @filename.file?
27
+ end
28
+
29
+ ##
30
+ # Raises an exception if +filename+ without '.mp3' extension
31
+
32
+ def validate_mp3_format
33
+ unless File.extname(filename).casecmp('.mp3').zero?
34
+ raise UnknownExtension, filename
35
+ end
36
+ end
37
+
38
+ ##
39
+ # Play mp3
40
+ #
41
+ # @exception NotImplementedError
42
+ # raised if #play_mp3 was called, but not overridden in any MP3_Player child
43
+
44
+ def play_mp3
45
+ raise NotImplementedError, "Abstract class called"
46
+ end
47
+
48
+ ##
49
+ # Validates OS requirements. Abstract
50
+ #
51
+ # @exception NotImplementedError
52
+ # raised if #validate_requirements was called, but not overridden in any MP3_Player child
53
+
54
+ def validate_requirements
55
+ raise NotImplementedError, "Abstract class called"
56
+ end
57
+
58
+ ##
59
+ # Raised when +filename+ has wrong (not mp3) extension. Used to give
60
+ # minimal protection against files with unknown format.
61
+
62
+ class UnknownExtension < YandexSpeechError
63
+ def initialize(filename); super "Mp3 player can work only with files with '.mp3' extension. Please change extension for #{filename} if you sure that format is correct!'" end; end
64
+
65
+ ##
66
+ # Raised when file not found
67
+
68
+ class FileNotFound < YandexSpeechError
69
+ def initialize(file); super "File #{file} not found!" end; end
70
+ end # class Base
71
+ end # module MP3_Player
72
+ end # module YandexSpeechApi
@@ -0,0 +1,41 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+ module YandexSpeechApi
4
+ module MP3_Player
5
+ class Linux_MP3_Player < MP3_Player::Base # no-doc
6
+ private
7
+
8
+ # @return [String]
9
+ # Path to +mpg123+ application
10
+
11
+ attr_reader :path_to_executable
12
+
13
+ ##
14
+ # Check requirements.
15
+ #
16
+ # @exception ApplicationNotInstalled
17
+ # Raised if +mpg123+ not found.
18
+
19
+ def validate_requirements
20
+ @path_to_executable = Helpers::find_executable 'mpg123'
21
+
22
+ if path_to_executable.nil?
23
+ raise ApplicationNotInstalled , 'mpq123'
24
+ end
25
+ end
26
+
27
+ ##
28
+ # no-doc
29
+
30
+ def play_mp3
31
+ `#{path_to_executable} -q '#{filename}'`
32
+ end
33
+
34
+ ##
35
+ # Raised when necessary linux program not found.
36
+
37
+ class ApplicationNotInstalled < YandexSpeechError
38
+ def initialize(name); super "Program '#{name}' not found!" end; end
39
+ end # class Linux_MP3_Player
40
+ end # module MP3_Player
41
+ end # module YandexSpeechApi
@@ -0,0 +1,22 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+ module YandexSpeechApi
4
+ module MP3_Player
5
+ class Mac_MP3_Player < MP3_Player::Base
6
+
7
+ ##
8
+ # no-doc
9
+
10
+ def validate_requirements
11
+ nil
12
+ end
13
+
14
+ ##
15
+ # no-doc
16
+
17
+ def play_mp3
18
+ `afplay '#{filename}'`
19
+ end
20
+ end # class Mac_MP3_Player
21
+ end # module MP3_Player
22
+ end # module YandexSpeechApi
@@ -0,0 +1,30 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+ module YandexSpeechApi
4
+ # dependencies from core lib
5
+ require 'rbconfig'
6
+ require 'uri'
7
+ require 'net/http'
8
+
9
+ ##
10
+ # Core class for all exceptions that can be raised in YandexSpeechApi lib..
11
+
12
+ class YandexSpeechError < StandardError; end
13
+
14
+ # project structure
15
+
16
+ ##
17
+ # loads *.rb files in requested order
18
+
19
+ def self.load(**params)
20
+ params[:files].each do |f|
21
+ require File.join(__dir__, params[:folder].to_s, f)
22
+ end
23
+ end
24
+ private_class_method :load
25
+
26
+ load folder: 'mp3_player',
27
+ files: %w(base mac_mp3_player linux_mp3_player)
28
+
29
+ load files: %w(helpers mp3_player key language format voice emotion speed connection speaker)
30
+ end # module YandexSpeechApi